#include "ATOOLS/Org/Settings_Writer.H" #include "ATOOLS/Org/Settings.H" #include "ATOOLS/Org/Run_Parameter.H" #include "ATOOLS/Org/Shell_Tools.H" #include using namespace ATOOLS; void Settings_Writer::WriteSettings(Settings& s) { // order output in rows of customised settings and uncustomised settings MyStrStream customised, uncustomised; for (const auto& keysetpair : s.m_usedvalues) { std::vector vals; const auto finalvals = keysetpair.second; assert(!finalvals.empty()); // put all values for the table rows in `vals`, if a value has multiple // entries, then these are separated by "-- AND --" vals.push_back(s.m_defaults[keysetpair.first]); const auto otherdefaultsit = s.m_otherscalardefaults.find(keysetpair.first); for (const auto& v : s.m_otherscalardefaults[keysetpair.first]) { vals.back().push_back({"-- AND --"}); vals.back().push_back({v}); } const auto iscustomised = !(finalvals.size() == 1 && (*finalvals.begin() == vals[0])); if (iscustomised) { vals.push_back(s.m_overrides[keysetpair.first]); Settings_Keys keys{ keysetpair.first }; for (auto it = s.m_yamlreaders.rbegin(); it != s.m_yamlreaders.rend(); ++it) vals.push_back((*it)->GetMatrix(keys)); if (!finalvals.empty()) { vals.push_back(*finalvals.begin()); for (auto it = ++finalvals.begin(); it != finalvals.end(); ++it) { vals.back().push_back({"-- AND --"}); std::copy(it->begin(), it->end(), std::back_inserter(vals.back())); } } } // write table body in the appropriate section MyStrStream& current = iscustomised ? customised : uncustomised; MyStrStream keystream; for (size_t i{ 0 }; i < keysetpair.first.size(); ++i) { keystream << keysetpair.first[i]; if (i + 1 < keysetpair.first.size()) keystream << ":"; } current << EncodeForMarkdown(keystream.str()); current << "| "; for (size_t i{ 0 }; i < vals.size(); ++i) { MyStrStream valstream; for (size_t j{ 0 }; j < vals[i].size(); ++j) { for (size_t k{ 0 }; k < vals[i][j].size(); ++k) { valstream << vals[i][j][k]; if (k + 1 < vals[i][j].size()) valstream << ", "; } if (j + 1 < vals[i].size()) valstream << "\n"; } current << EncodeForMarkdown(valstream.str()) << " | "; if (!iscustomised) break; } current << " |\n"; } const auto path = rpa->gen.Variable("SHERPA_RUN_PATH") + "/Settings_Report"; MakeDir(path, true); std::ofstream file(path + "/Settings_Report.md"); file << "---\n"; file << "title: Sherpa run-time settings\n"; file << "date: " << rpa->gen.Timer().TimeString(0) << "\n"; file << "...\n\n"; //file << "Sherpa run-time settings\n"; //file << "===================\n"; file << "Note that parameters that are never accessed by Sherpa during its" << " run will not be listed below. On the other hand, \"accessed\" does" << " not necessarily mean that the parameter had any effect on the" << " run.\n\n"; file << "In rare cases, an alternative default value is being used." << " These alternatives will be separated by \"`-- AND --`\" from the" << " standard default, which will always be listed on top.\n\n"; file << "Customised settings\n"; file << "-------------------\n"; file << "Note that parameters that can take on different values because they" << " are set within a list, for example `param: [{x: 1}, {x: 2}, ...]`," << " will not appear in the config-file or command-line columns. They" << " will be listed in the final-value column, with each different value" << " separated by an \"`-- AND --`\" line.\n\n"; file << "| parameter | default value | override by SHERPA"; const auto files = s.GetConfigFiles(); for (const auto& f : files) file << " | " << f; file << " | command line | final value |\n"; file << "|-|-|-"; for (int i {0}; i < files.size(); ++i) file << "|-"; file << "|-|-|\n"; file << customised.str(); file << "Settings kept at their default value\n"; file << "-------------------\n"; file << "| parameter | default value |\n"; file << "|-|-|\n"; file << uncustomised.str(); file.close(); std::ofstream cssfile(path + "/Style.css"); cssfile << "tr:nth-of-type(odd) {" << " background-color:#eef;" << "}"; cssfile << "th {" << " background-color:#fff;" << "}"; cssfile.close(); std::ofstream makefile(path + "/Makefile"); makefile << "Settings_Report.html: Settings_Report.md\n" << "\tpandoc -s -o Settings_Report.html -c Style.css" << " Settings_Report.md\n\n" << "clean:\n" << "\trm -f Settings_Report.html\n\n" << ".PHONY: clean"; makefile.close(); } std::string Settings_Writer::EncodeForMarkdown(const std::string &data) const { std::string buffer; buffer.reserve(data.size()); for(size_t pos = 0; pos != data.size(); ++pos) { switch(data[pos]) { case '\n': buffer.append("
"); break; case '|': case '_': case '*': case '$': case '\\': case '`': case '{': case '}': case '[': case ']': case '(': case ')': case '#': case '+': case '-': case '.': case '!': case '<': case '>': buffer.append("\\"); default: buffer.append(&data[pos], 1); break; } } return buffer; }