diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e3c28f8c8..b64b38978 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: - name: 'Build environment' run: | cmake --build ${{ env.CEPGEN_PATH }} - cmake --build ${{ env.CEPGEN_PATH }} -- cepgenDocGenerator + cmake --build ${{ env.CEPGEN_PATH }} -- cepgenDescribeModules - name: 'Compress environment' run: tar -cvf environment.tar /Package diff --git a/CepGen/Generator.h b/CepGen/Generator.h index 690319e2e..f1fdf3385 100644 --- a/CepGen/Generator.h +++ b/CepGen/Generator.h @@ -41,7 +41,6 @@ namespace cepgen { /// \param[in] safe_mode Drop libraries initialisation? void initialise(bool safe_mode = false); void printHeader(); ///< Dump this program's header into the standard output stream - void dumpModules(); ///< List the modules registered in RTE database /// Core generator object allowing for process definition, cross section computation, and event generation /// \author Laurent Forthomme diff --git a/CepGen/Modules/DocumentationGeneratorFactory.h b/CepGen/Modules/DocumentationGeneratorFactory.h new file mode 100644 index 000000000..11e354bd0 --- /dev/null +++ b/CepGen/Modules/DocumentationGeneratorFactory.h @@ -0,0 +1,45 @@ +/* + * CepGen: a central exclusive processes event generator + * Copyright (C) 2024 Laurent Forthomme + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CepGen_Modules_DocumentationGeneratorFactory_h +#define CepGen_Modules_DocumentationGeneratorFactory_h + +#include "CepGen/Modules/ModuleFactory.h" + +/// Add a documentation generator to the list of handled modules +#define REGISTER_DOCUMENTATION_GENERATOR(name, obj) \ + namespace cepgen { \ + struct BUILDERNM(obj) { \ + BUILDERNM(obj)() { DocumentationGeneratorFactory::get().registerModule(name); } \ + }; \ + static const BUILDERNM(obj) gDogGen##obj; \ + } \ + static_assert(true, "") + +namespace cepgen { + namespace utils { + class DocumentationGenerator; + } + /// A documentation generator factory + DEFINE_FACTORY(std::string, + DocumentationGeneratorFactory, + utils::DocumentationGenerator, + "Documentation generator factory"); +} // namespace cepgen + +#endif diff --git a/CepGen/Modules/ListModules.cpp b/CepGen/Modules/ListModules.cpp deleted file mode 100644 index 23b231478..000000000 --- a/CepGen/Modules/ListModules.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * CepGen: a central exclusive processes event generator - * Copyright (C) 2020-2024 Laurent Forthomme - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "CepGen/Generator.h" -#include "CepGen/Utils/Message.h" -#include "CepGen/Utils/String.h" - -// list of factories listed -#include "CepGen/Modules/AnalyticIntegratorFactory.h" -#include "CepGen/Modules/CardsHandlerFactory.h" -#include "CepGen/Modules/CouplingFactory.h" -#include "CepGen/Modules/DerivatorFactory.h" -#include "CepGen/Modules/DrawerFactory.h" -#include "CepGen/Modules/EventExporterFactory.h" -#include "CepGen/Modules/EventImporterFactory.h" -#include "CepGen/Modules/EventModifierFactory.h" -#include "CepGen/Modules/FormFactorsFactory.h" -#include "CepGen/Modules/FunctionalFactory.h" -#include "CepGen/Modules/GeneratorWorkerFactory.h" -#include "CepGen/Modules/IntegratorFactory.h" -#include "CepGen/Modules/PartonFluxFactory.h" -#include "CepGen/Modules/PhaseSpaceGeneratorFactory.h" -#include "CepGen/Modules/ProcessFactory.h" -#include "CepGen/Modules/RandomGeneratorFactory.h" -#include "CepGen/Modules/StructureFunctionsFactory.h" - -namespace cepgen { - void dumpModules() { - CG_LOG.log([](auto& info) { - const std::string sep_mid(80, '-'); - info << "List of modules registered in the runtime database:"; - auto list_modules = [&info, &sep_mid](const auto& fact, const std::string& name) { - info << "\n" << sep_mid << "\n" << utils::boldify(name); - if (fact.empty()) - info << "\n>>> " << utils::colourise("none found", utils::Colour::red) << " <<<"; - for (const auto& mod : fact.modules()) - info << "\n> " << utils::colourise(mod, utils::Colour::green, utils::Modifier::bold) << ": " - << fact.describe(mod) << (fact.describeParameters(mod).empty() ? " (*)" : ""); - }; - auto list_int_modules = [&info, &sep_mid](const auto& fact, - const std::string& name, - std::function translator = nullptr) { - info << "\n" << sep_mid << "\n" << utils::boldify(name); - if (!translator) - translator = [](int val) -> std::string { return std::to_string(val); }; - if (fact.empty()) - info << "\n>>> " << utils::colourise("none found", utils::Colour::red) << " <<<"; - for (const auto& mod : fact.modules()) - info << "\n> " << utils::colourise(translator(mod), utils::Colour::green, utils::Modifier::bold) << ": " - << fact.describe(mod) << (fact.describeParameters(mod).empty() ? " (*)" : ""); - }; - - list_modules(ProcessFactory::get(), "Physics processes"); - list_modules(PhaseSpaceGeneratorFactory::get(), "Phase space mapping generators"); - list_modules(KTFluxFactory::get(), "kt-factorised fluxes modellings"); - list_modules(CollinearFluxFactory::get(), "Collinear parton fluxes modellings"); - list_modules(FormFactorsFactory::get(), "Beam form factors modellings"); - list_int_modules(SigmaRatiosFactory::get(), "Cross section ratios modellings"); - list_int_modules(StructureFunctionsFactory::get(), "Structure functions modellings", [](int mod) { - std::ostringstream os; - os << std::setw(3) << mod << "|" << StructureFunctionsFactory::get().describe(mod); - return os.str(); - }); - list_modules(AlphaEMFactory::get(), "alpha(EM) evolution algorithms"); - list_modules(AlphaSFactory::get(), "alpha(s) evolution algorithms"); - list_modules(EventImporterFactory::get(), "Event import modules"); - list_modules(GeneratorWorkerFactory::get(), "Event generation modules"); - list_modules(EventModifierFactory::get(), "Event modification modules"); - list_modules(EventExporterFactory::get(), "Export modules"); - list_modules(FunctionalFactory::get(), "Functional evaluators"); - list_modules(CardsHandlerFactory::get(), "Steering cards parsers"); - list_modules(IntegratorFactory::get(), "Integration algorithms"); - list_modules(AnalyticIntegratorFactory::get(), "Analytic integration algorithms"); - list_modules(DerivatorFactory::get(), "Derivation algorithm"); - list_modules(RandomGeneratorFactory::get(), "Random number generator engines"); - list_modules(DrawerFactory::get(), "Drawer utilities"); - }); - } -} // namespace cepgen diff --git a/CepGen/Modules/ModuleFactoryImpl.h b/CepGen/Modules/ModuleFactoryImpl.h index d13758237..a00136ecb 100644 --- a/CepGen/Modules/ModuleFactoryImpl.h +++ b/CepGen/Modules/ModuleFactoryImpl.h @@ -33,6 +33,7 @@ #include "CepGen/StructureFunctions/Parameterisation.h" #include "CepGen/StructureFunctions/SigmaRatio.h" #include "CepGen/Utils/Derivator.h" +#include "CepGen/Utils/DocumentationGenerator.h" #include "CepGen/Utils/Drawer.h" #include "CepGen/Utils/Functional.h" #include "CepGen/Utils/RandomGenerator.h" @@ -42,6 +43,7 @@ namespace cepgen { template class ModuleFactory; template class ModuleFactory; template class ModuleFactory; + template class ModuleFactory; template class ModuleFactory; template class ModuleFactory; template class ModuleFactory; diff --git a/CepGen/Utils/DocumentationGenerator.cpp b/CepGen/Utils/DocumentationGenerator.cpp new file mode 100644 index 000000000..c7c5fbf69 --- /dev/null +++ b/CepGen/Utils/DocumentationGenerator.cpp @@ -0,0 +1,89 @@ +/* + * CepGen: a central exclusive processes event generator + * Copyright (C) 2024 Laurent Forthomme + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CepGen/Utils/DocumentationGenerator.h" +#include "CepGen/Utils/String.h" + +// list of factories documented +#include "CepGen/Modules/CardsHandlerFactory.h" +#include "CepGen/Modules/CouplingFactory.h" +#include "CepGen/Modules/DrawerFactory.h" +#include "CepGen/Modules/EventExporterFactory.h" +#include "CepGen/Modules/EventImporterFactory.h" +#include "CepGen/Modules/EventModifierFactory.h" +#include "CepGen/Modules/FormFactorsFactory.h" +#include "CepGen/Modules/FunctionalFactory.h" +#include "CepGen/Modules/GeneratorWorkerFactory.h" +#include "CepGen/Modules/IntegratorFactory.h" +#include "CepGen/Modules/PartonFluxFactory.h" +#include "CepGen/Modules/PhaseSpaceGeneratorFactory.h" +#include "CepGen/Modules/ProcessFactory.h" +#include "CepGen/Modules/RandomGeneratorFactory.h" +#include "CepGen/Modules/StructureFunctionsFactory.h" + +namespace cepgen { + namespace utils { + DocumentationGenerator::DocumentationGenerator(const ParametersList& params) : NamedModule(params) {} + + void DocumentationGenerator::initialise() { + const auto categories = steer >("categories"), + mod_names = steer >("modules"); + const auto add_category = [&categories, &mod_names, this](const std::string& name, + const std::string& title, + const std::string& description, + auto& factory) -> void { + if (!categories.empty() && !contains(categories, name)) + return; + category_t cat; + cat.name = name; + cat.title = title; + cat.description = description; + for (const auto& mod : factory.modules()) + if (mod_names.empty() || contains(mod_names, utils::toString(mod))) + cat.modules[utils::toString(mod)] = factory.describeParameters(mod); + categories_.emplace_back(std::make_pair(name, cat)); + }; + add_category("proc", "Processes", "", cepgen::ProcessFactory::get()); + add_category("cards", "Cards handler", "", cepgen::CardsHandlerFactory::get()); + add_category("formfac", "Form factors", "", cepgen::FormFactorsFactory::get()); + add_category("strfun", "Structure functions", "", cepgen::StructureFunctionsFactory::get()); + add_category("sigrat", + "Longitudinal/transverse cross section ratio parameterisations", + "", + cepgen::SigmaRatiosFactory::get()); + add_category("psmap", "Phase space mapper", "", cepgen::PhaseSpaceGeneratorFactory::get()); + add_category("collflux", "Collinear parton flux modelling", "", cepgen::CollinearFluxFactory::get()); + add_category("ktflux", "KT-factorised parton flux modelling", "", cepgen::KTFluxFactory::get()); + add_category("alphaem", "Electromagnetic coupling evolution", "", cepgen::AlphaEMFactory::get()); + add_category("alphas", "Strong coupling evolution", "", cepgen::AlphaSFactory::get()); + add_category("integr", "Integrator algorithms", "", cepgen::IntegratorFactory::get()); + add_category("func", "Functional parsers", "", cepgen::FunctionalFactory::get()); + add_category("rndgen", "Random number generators", "", cepgen::RandomGeneratorFactory::get()); + add_category("drawer", "Drawing tools", "", cepgen::DrawerFactory::get()); + add_category("evtgen", "Event generation algorithms", "", cepgen::GeneratorWorkerFactory::get()); + add_category("evtimp", "Event import algorithms", "", cepgen::EventImporterFactory::get()); + add_category("evtmod", "Event modification algorithms", "", cepgen::EventModifierFactory::get()); + add_category("evtout", "Event export modules", "", cepgen::EventExporterFactory::get()); + } + + ParametersDescription DocumentationGenerator::description() { + auto desc = ParametersDescription(); + return desc; + } + } // namespace utils +} // namespace cepgen diff --git a/CepGen/Utils/DocumentationGenerator.h b/CepGen/Utils/DocumentationGenerator.h new file mode 100644 index 000000000..429e254c6 --- /dev/null +++ b/CepGen/Utils/DocumentationGenerator.h @@ -0,0 +1,49 @@ +/* + * CepGen: a central exclusive processes event generator + * Copyright (C) 2024 Laurent Forthomme + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CepGen_Utils_DocumentationGenerator_h +#define CepGen_Utils_DocumentationGenerator_h + +#include "CepGen/Modules/ModuleFactory.h" + +namespace cepgen { + namespace utils { + /// Documentation generator object + /// \author Laurent Forthomme + /// \date Mar 2024 + class DocumentationGenerator : public NamedModule { + public: + explicit DocumentationGenerator(const ParametersList&); + virtual ~DocumentationGenerator() = default; + + static ParametersDescription description(); + + virtual void initialise(); + virtual std::string describe() = 0; + + protected: + struct category_t { + std::string name, title, description; + std::map modules{}; + }; + std::vector > categories_; + }; + } // namespace utils +} // namespace cepgen + +#endif diff --git a/CepGen/Utils/TextDocumentationGenerator.cpp b/CepGen/Utils/TextDocumentationGenerator.cpp new file mode 100644 index 000000000..b50e7cc82 --- /dev/null +++ b/CepGen/Utils/TextDocumentationGenerator.cpp @@ -0,0 +1,73 @@ +/* + * CepGen: a central exclusive processes event generator + * Copyright (C) 2021-2024 Laurent Forthomme + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CepGen/Modules/DocumentationGeneratorFactory.h" +#include "CepGen/Utils/DocumentationGenerator.h" +#include "CepGen/Utils/String.h" + +namespace cepgen { + namespace utils { + /// Text documentation generator object + /// \author Laurent Forthomme + /// \date Nov 2021 + class TextDocumentationGenerator final : public DocumentationGenerator { + public: + explicit TextDocumentationGenerator(const ParametersList& params) + : DocumentationGenerator(params), dump_params_(steer("dumpParameters")) {} + + static ParametersDescription description() { + auto desc = DocumentationGenerator::description(); + desc.setDescription("Bare text documentation generator"); + desc.add("light", false).setDescription("lightweight module description (without parameters)"); + desc.add("dumpParameters", false) + .setDescription("dump the parameters list along with their parameters description?"); + return desc; + } + + std::string describe() override { + std::ostringstream os; + const auto separator = std::string(80, '-'); + const auto light = steer("light"); + for (const auto& cat : categories_) { + if (cat.second.modules.empty()) + continue; + os << colourise("\n" + separator + "\n" + cat.second.title, Colour::green, Modifier::bold); + if (!light) + os << "\n"; + for (const auto& mod : cat.second.modules) { + if (light) { + os << "\n> " << colourise(mod.first, Colour::cyan, Modifier::underline | Modifier::bold) << ": " + << mod.second.description() << (mod.second.empty() ? " (*)" : ""); + } else { + os << "\n" << mod.second.describe(); + if (dump_params_) + os << "\n\tParametersList object:\n\t\t" << mod.second.parameters(); + os << "\n"; + } + } + } + return os.str(); + } + + private: + const bool dump_params_; + }; + } // namespace utils +} // namespace cepgen +using cepgen::utils::TextDocumentationGenerator; +REGISTER_DOCUMENTATION_GENERATOR("text", TextDocumentationGenerator); diff --git a/CepGenAddOns/CTMLWrapper/CMakeLists.txt b/CepGenAddOns/CTMLWrapper/CMakeLists.txt index 1263d9ed9..75bfc37c2 100644 --- a/CepGenAddOns/CTMLWrapper/CMakeLists.txt +++ b/CepGenAddOns/CTMLWrapper/CMakeLists.txt @@ -11,5 +11,4 @@ endif() cepgen_build(CepGenCTML SOURCES *.cpp EXT_HEADERS ${CTML_INCLUDE} - UTILS utils/*.cc INSTALL_COMPONENT doc) diff --git a/CepGenAddOns/CTMLWrapper/CTMLDocumentationGenerator.cpp b/CepGenAddOns/CTMLWrapper/CTMLDocumentationGenerator.cpp new file mode 100644 index 000000000..75b8d23fa --- /dev/null +++ b/CepGenAddOns/CTMLWrapper/CTMLDocumentationGenerator.cpp @@ -0,0 +1,160 @@ +/* + * CepGen: a central exclusive processes event generator + * Copyright (C) 2022-2024 Laurent Forthomme + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "CepGen/Core/Exception.h" +#include "CepGen/Modules/DocumentationGeneratorFactory.h" +#include "CepGen/Utils/DocumentationGenerator.h" +#include "CepGen/Utils/String.h" +#include "CepGen/Version.h" + +using namespace cepgen; +/// CTML documentation generator object +/// \author Laurent Forthomme +/// \date Apr 2022 +class CTMLDocumentationGenerator final : public cepgen::utils::DocumentationGenerator { +public: + explicit CTMLDocumentationGenerator(const ParametersList& params) + : DocumentationGenerator(params), + page_title_(steer("pageTitle")), + bare_(steer("bare")), + show_git_(steer("showGit")), + container_(CTML::Node("div.container-fluid")) { + doc_.AppendNodeToHead(CTML::Node("title", "CepGen v" + version::tag + " modules documentation")); + if (!bare_ && steer("useBS")) { + doc_.AppendNodeToHead( + CTML::Node("link") + .SetAttribute("rel", "stylesheet") + .SetAttribute("href", "https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css") + .SetAttribute("integrity", "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T") + .SetAttribute("crossorigin", "anonymous")); + doc_.AppendNodeToHead(CTML::Node("meta") + .SetAttribute("name", "viewport") + .SetAttribute("content", "width=device-width, initial-scale=1")); + } + if (!page_title_.empty()) + container_.AppendChild(CTML::Node("h1", page_title_)); + auto header = CTML::Node("div").AppendText("CepGen version ").AppendChild(CTML::Node("mark", version::tag)); + if (show_git_) + header.AppendChild(CTML::Node("br").UseClosingTag(false)) + .AppendText("Git hash/branch: ") + .AppendChild(CTML::Node("code", version::extended)); + header.AppendChild(CTML::Node("br").UseClosingTag(false)) + .AppendText("Documentation last generated on " + utils::timeAs("%B %d, %Y")); + container_.AppendChild(header); + } + + static ParametersDescription description() { + auto desc = DocumentationGenerator::description(); + desc.setDescription("CTML HTML document generator helper"); + desc.add("output", "index.html").setDescription("output path for the generated HTML file"); + desc.add("pageTitle", "Modules documentation").setDescription("documentation page upper level title"); + desc.add("useBS", true).setDescription("use the Bootstrap CDN to prettify this output?"); + desc.add("showGit", false).setDescription("print out the git hash/branch in the output?"); + desc.add("bare", false).setDescription("generate a bare version (without // attributes)"); + return desc; + } + + void initialise() override { + DocumentationGenerator::initialise(); + for (const auto& cat : categories_) { + container_.AppendChild(CTML::Node("a").SetAttribute("name", cat.first)) + .AppendChild(CTML::Node("h2", cat.second.title)); + CTML::Node mods("p"); + for (const auto& mod : cat.second.modules) + mods.AppendChild(CTML::Node("a").SetAttribute("name", utils::toString(cat.first) + mod.first)) + .AppendChild(CTML::Node("span").AppendChild(moduleDescription(mod.second))); + container_.AppendChild(mods); + } + } + std::string describe() override { + doc_.AppendNodeToBody(container_); + std::ostringstream out; + if (bare_) + out << container_.ToString(); + else + out << doc_.ToString(); + return out.str(); + } + +private: + inline static CTML::Node moduleDescription(const ParametersDescription& desc) { + CTML::Node out("div.module"); + if (desc.empty()) + return out; + CTML::Node mod_summary(CTML::Node("summary").AppendChild(CTML::Node("b", desc.parameters().getNameString()))); + CTML::Node mod_details("details"); + const auto desc_type = desc.type(); + if (desc_type == ParametersDescription::Type::ParametersVector) { + } else if (desc_type == ParametersDescription::Type::Value) { + } else { + mod_summary.AppendText(" " + desc.description()); + } + mod_details.AppendChild(mod_summary); + try { + CTML::Node items("ul"); + for (const auto& key : desc.parameters().keys(false)) { + const auto& subdesc = desc.get(key); + const auto subdesc_type = subdesc.type(); + CTML::Node item("li.key"); + item.AppendChild(CTML::Node("u.key", key)); + if (subdesc_type == ParametersDescription::Type::Value) { + if (!subdesc.description().empty()) + item.AppendChild(CTML::Node("i", " " + subdesc.description())); + if (!desc.parameters().getString(key).empty()) + item.AppendText(" ").AppendChild( + CTML::Node("span.text-muted") + .AppendText("(default value: ") + .AppendChild(CTML::Node("code", desc.parameters().getString(key, false))) + .AppendText(")")); + } else if (subdesc_type == ParametersDescription::Type::ParametersVector) { + item.AppendText(" vector of parameters"); + if (!subdesc.description().empty()) + item.AppendText(" defining a ").AppendChild(CTML::Node("i", subdesc.description())); + item.AppendChild(moduleDescription(subdesc)); + const auto& vparams = desc.parameters().get >(key); + if (!vparams.empty()) { + CTML::Node itparams("ol"); + for (const auto& it : vparams) + itparams.AppendChild(CTML::Node("li").AppendChild(moduleDescription(ParametersDescription(it)))); + item.AppendChild(CTML::Node("details") + .AppendChild(CTML::Node("summary").AppendChild(CTML::Node("b", "Default content"))) + .AppendChild(CTML::Node("p").AppendChild(itparams))); + } + } else + item.AppendChild(CTML::Node("i", " " + subdesc.description())).AppendChild(moduleDescription(subdesc)); + items.AppendChild(item); + } + if (!items.GetChildren().empty()) + mod_details.AppendChild(CTML::Node("p").AppendText("List of parameters:").AppendChild(items)); + out.AppendChild(mod_details); + } catch (const Exception& exc) { + exc.dump(); + } + return out; + } + + const std::string page_title_; + const bool bare_, show_git_; + CTML::Document doc_; + CTML::Node container_; +}; +REGISTER_DOCUMENTATION_GENERATOR("ctml", CTMLDocumentationGenerator); diff --git a/CepGenAddOns/CTMLWrapper/DocumentationGenerator.cpp b/CepGenAddOns/CTMLWrapper/DocumentationGenerator.cpp deleted file mode 100644 index 2ee4bfaf1..000000000 --- a/CepGenAddOns/CTMLWrapper/DocumentationGenerator.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * CepGen: a central exclusive processes event generator - * Copyright (C) 2022-2024 Laurent Forthomme - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "CepGen/Core/Exception.h" -#include "CepGen/Utils/String.h" -#include "CepGen/Version.h" -#include "CepGenAddOns/CTMLWrapper/DocumentationGenerator.h" - -namespace cepgen { - namespace utils { - DocumentationGenerator::DocumentationGenerator(const ParametersList& params) - : SteeredObject(params), - output_filename_(steer("output")), - page_title_(steer("pageTitle")), - bare_(steer("bare")), - show_git_(steer("showGit")), - container_(CTML::Node("div.container-fluid")) { - doc_.AppendNodeToHead(CTML::Node("title", "CepGen v" + version::tag + " modules documentation")); - if (!bare_ && steer("useBS")) { - doc_.AppendNodeToHead( - CTML::Node("link") - .SetAttribute("rel", "stylesheet") - .SetAttribute("href", "https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css") - .SetAttribute("integrity", "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T") - .SetAttribute("crossorigin", "anonymous")); - doc_.AppendNodeToHead(CTML::Node("meta") - .SetAttribute("name", "viewport") - .SetAttribute("content", "width=device-width, initial-scale=1")); - } - if (!page_title_.empty()) - container_.AppendChild(CTML::Node("h1", page_title_)); - auto header = CTML::Node("div").AppendText("CepGen version ").AppendChild(CTML::Node("mark", version::tag)); - if (show_git_) - header.AppendChild(CTML::Node("br").UseClosingTag(false)) - .AppendText("Git hash/branch: ") - .AppendChild(CTML::Node("code", version::extended)); - header.AppendChild(CTML::Node("br").UseClosingTag(false)) - .AppendText("Documentation last generated on " + timeAs("%B %d, %Y")); - container_.AppendChild(header); - } - - DocumentationGenerator::~DocumentationGenerator() { - doc_.AppendNodeToBody(container_); - std::ostream* out{nullptr}; - if (!output_filename_.empty()) - out = new std::ofstream(output_filename_); - else - out = &std::cout; - if (bare_) - (*out) << container_.ToString(); - else - (*out) << doc_.ToString(); - if (!output_filename_.empty()) { - delete out; - CG_INFO("DocumentationGenerator") << "Documentation written in \"" << output_filename_ << "\"."; - } - } - - CTML::Node DocumentationGenerator::moduleDescription(const ParametersDescription& desc) { - CTML::Node out("div.module"); - if (desc.empty()) - return out; - CTML::Node mod_summary(CTML::Node("summary").AppendChild(CTML::Node("b", desc.parameters().getNameString()))); - CTML::Node mod_details("details"); - const auto desc_type = desc.type(); - if (desc_type == ParametersDescription::Type::ParametersVector) { - } else if (desc_type == ParametersDescription::Type::Value) { - } else { - mod_summary.AppendText(" " + desc.description()); - } - mod_details.AppendChild(mod_summary); - try { - CTML::Node items("ul"); - for (const auto& key : desc.parameters().keys(false)) { - const auto& subdesc = desc.get(key); - const auto subdesc_type = subdesc.type(); - CTML::Node item("li.key"); - item.AppendChild(CTML::Node("u.key", key)); - if (subdesc_type == ParametersDescription::Type::Value) { - if (!subdesc.description().empty()) - item.AppendChild(CTML::Node("i", " " + subdesc.description())); - if (!desc.parameters().getString(key).empty()) - item.AppendText(" ").AppendChild( - CTML::Node("span.text-muted") - .AppendText("(default value: ") - .AppendChild(CTML::Node("code", desc.parameters().getString(key, false))) - .AppendText(")")); - } else if (subdesc_type == ParametersDescription::Type::ParametersVector) { - item.AppendText(" vector of parameters"); - if (!subdesc.description().empty()) - item.AppendText(" defining a ").AppendChild(CTML::Node("i", subdesc.description())); - item.AppendChild(moduleDescription(subdesc)); - const auto& vparams = desc.parameters().get >(key); - if (!vparams.empty()) { - CTML::Node itparams("ol"); - for (const auto& it : vparams) - itparams.AppendChild(CTML::Node("li").AppendChild(moduleDescription(ParametersDescription(it)))); - item.AppendChild(CTML::Node("details") - .AppendChild(CTML::Node("summary").AppendChild(CTML::Node("b", "Default content"))) - .AppendChild(CTML::Node("p").AppendChild(itparams))); - } - } else - item.AppendChild(CTML::Node("i", " " + subdesc.description())).AppendChild(moduleDescription(subdesc)); - items.AppendChild(item); - } - if (!items.GetChildren().empty()) - mod_details.AppendChild(CTML::Node("p").AppendText("List of parameters:").AppendChild(items)); - out.AppendChild(mod_details); - } catch (const Exception& exc) { - exc.dump(); - } - return out; - } - - ParametersDescription DocumentationGenerator::description() { - auto desc = ParametersDescription(); - desc.setDescription("CTML HTML document generator helper"); - desc.add("output", "index.html").setDescription("output path for the generated HTML file"); - desc.add("pageTitle", "Modules documentation") - .setDescription("documentation page upper level title"); - desc.add("useBS", true).setDescription("use the Bootstrap CDN to prettify this output?"); - desc.add("showGit", false).setDescription("print out the git hash/branch in the output?"); - desc.add("bare", false).setDescription("generate a bare version (without // attributes)"); - return desc; - } - } // namespace utils -} // namespace cepgen diff --git a/CepGenAddOns/CTMLWrapper/DocumentationGenerator.h b/CepGenAddOns/CTMLWrapper/DocumentationGenerator.h deleted file mode 100644 index e9802db7f..000000000 --- a/CepGenAddOns/CTMLWrapper/DocumentationGenerator.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * CepGen: a central exclusive processes event generator - * Copyright (C) 2022-2024 Laurent Forthomme - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef CepGenAddOns_CTMLWrapper_DocumentationGenerator_h -#define CepGenAddOns_CTMLWrapper_DocumentationGenerator_h - -#include - -#include "CepGen/Modules/ModuleFactory.h" - -namespace cepgen { - namespace utils { - /** - * \brief CTML documentation generator object - * \author Laurent Forthomme - * \date Apr 2022 - */ - class DocumentationGenerator final : public SteeredObject { - public: - explicit DocumentationGenerator(const ParametersList&); - ~DocumentationGenerator(); - - static ParametersDescription description(); - - template - inline DocumentationGenerator& document(const std::string& type, - const std::string& title, - const ModuleFactory& factory) { - container_.AppendChild(CTML::Node("a").SetAttribute("name", type)).AppendChild(CTML::Node("h2", title)); - CTML::Node mods("p"); - for (const auto& mod : factory.modules()) { - std::ostringstream os; - os << type << "-" << mod; - mods.AppendChild(CTML::Node("a").SetAttribute("name", os.str())) - .AppendChild(CTML::Node("span").AppendChild(moduleDescription(factory.describeParameters(mod)))); - } - container_.AppendChild(mods); - return *this; - } - - private: - static CTML::Node moduleDescription(const ParametersDescription&); - - const std::string output_filename_, page_title_; - const bool bare_, show_git_; - CTML::Document doc_; - CTML::Node container_; - }; - } // namespace utils -} // namespace cepgen - -#endif diff --git a/CepGenAddOns/CTMLWrapper/utils/cepgenDocGenerator.cc b/CepGenAddOns/CTMLWrapper/utils/cepgenDocGenerator.cc deleted file mode 100644 index b246f2114..000000000 --- a/CepGenAddOns/CTMLWrapper/utils/cepgenDocGenerator.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* - * CepGen: a central exclusive processes event generator - * Copyright (C) 2022 Laurent Forthomme - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "CepGen/Generator.h" -#include "CepGen/Utils/ArgumentsParser.h" -#include "CepGenAddOns/CTMLWrapper/DocumentationGenerator.h" - -// list of factories documented -#include "CepGen/Modules/CouplingFactory.h" -#include "CepGen/Modules/DrawerFactory.h" -#include "CepGen/Modules/EventExporterFactory.h" -#include "CepGen/Modules/EventImporterFactory.h" -#include "CepGen/Modules/EventModifierFactory.h" -#include "CepGen/Modules/FormFactorsFactory.h" -#include "CepGen/Modules/FunctionalFactory.h" -#include "CepGen/Modules/GeneratorWorkerFactory.h" -#include "CepGen/Modules/IntegratorFactory.h" -#include "CepGen/Modules/PartonFluxFactory.h" -#include "CepGen/Modules/PhaseSpaceGeneratorFactory.h" -#include "CepGen/Modules/ProcessFactory.h" -#include "CepGen/Modules/RandomGeneratorFactory.h" -#include "CepGen/Modules/StructureFunctionsFactory.h" - -namespace cepgen { - namespace utils {} -} // namespace cepgen - -int main(int argc, char* argv[]) { - std::string output_file; - bool use_bs, show_title, show_git, bare; - cepgen::ArgumentsParser(argc, argv) - .addOptionalArgument("output,o", "output HTML file", &output_file, "index.html") - .addOptionalArgument("bootstrap,b", "use Bootstrap CDN to prettify the output?", &use_bs, true) - .addOptionalArgument("show-title,t", "show the page title?", &show_title, true) - .addOptionalArgument("show-git,g", "show the git hash/branch?", &show_git, false) - .addOptionalArgument("bare,e", "generate a bare version (without document tags) of the output?", &bare, false) - .parse(); - - cepgen::initialise(); - auto gen_params = cepgen::ParametersList() - .set("output", output_file) - .set("useBS", use_bs) - .set("showGit", show_git) - .set("bare", bare); - if (!show_title) - gen_params.set("pageTitle", ""); - cepgen::utils::DocumentationGenerator gen{gen_params}; - - gen.document("proc", "Processes", cepgen::ProcessFactory::get()) - //.document("cards", "Cards handler", cepgen::CardsHandlerFactory::get()) - .document("formfac", "Form factors", cepgen::FormFactorsFactory::get()) - .document("strfun", "Structure functions", cepgen::StructureFunctionsFactory::get()) - .document( - "sigrat", "Longitudinal/transverse cross section ratio parameterisations", cepgen::SigmaRatiosFactory::get()) - .document("psmap", "Phase space mapper", cepgen::PhaseSpaceGeneratorFactory::get()) - .document("collflux", "Collinear parton flux modelling", cepgen::CollinearFluxFactory::get()) - .document("ktflux", "KT-factorised parton flux modelling", cepgen::KTFluxFactory::get()) - .document("alphaem", "Electromagnetic coupling evolution", cepgen::AlphaEMFactory::get()) - .document("alphas", "Strong coupling evolution", cepgen::AlphaSFactory::get()) - .document("integr", "Integrator algorithms", cepgen::IntegratorFactory::get()) - .document("func", "Functional parsers", cepgen::FunctionalFactory::get()) - .document("rndgen", "Random number generators", cepgen::RandomGeneratorFactory::get()) - .document("drawer", "Drawing tools", cepgen::DrawerFactory::get()) - .document("evtgen", "Event generation algorithms", cepgen::GeneratorWorkerFactory::get()) - .document("evtimp", "Event import algorithms", cepgen::EventImporterFactory::get()) - .document("evtmod", "Event modification algorithms", cepgen::EventModifierFactory::get()) - .document("evtout", "Event export modules", cepgen::EventExporterFactory::get()); - - return 0; -} diff --git a/CepGenAddOns/PythonWrapper/PythonConfigWriter.cpp b/CepGenAddOns/PythonWrapper/PythonConfigWriter.cpp index 2d1062096..9216df364 100644 --- a/CepGenAddOns/PythonWrapper/PythonConfigWriter.cpp +++ b/CepGenAddOns/PythonWrapper/PythonConfigWriter.cpp @@ -80,10 +80,10 @@ namespace cepgen { PythonConfigWriter& PythonConfigWriter::operator<<(const ParametersDescription& pdesc) { CG_DEBUG("PythonConfigWriter") << "Adding a parameters description object:\n" << pdesc; std::function write = - [&](const ParametersDescription& pdesc, const std::string& key, size_t offset) -> std::string { + [&](const ParametersDescription& pdesc, const std::string& key, size_t offset_num) -> std::string { // write a generic parameters description object std::stringstream os; - const std::string off(offset * 4, ' '); + const auto off = offset(offset_num); os << off; if (!key.empty()) os << key << " = "; @@ -112,16 +112,19 @@ namespace cepgen { switch (daugh.type()) { case ParametersDescription::Type::Module: case ParametersDescription::Type::Parameters: - os << write(pdesc.get(key), key, offset + 1); + os << write(pdesc.get(key), key, offset_num + 1); break; case ParametersDescription::Type::ParametersVector: { std::string sep2; for (const auto& it : params.get >(key)) os << sep2 << write(ParametersDescription(it), "", 0), sep2 = ", "; } break; - case ParametersDescription::Type::Value: - os << off << std::string(4, ' ') << key << " = " << repr(params, key); - break; + case ParametersDescription::Type::Value: { + if (params.has(key)) + os << off << write(ParametersDescription(params.get(key)), key, offset_num + 1); + else + os << off << offset(1) << key << " = " << repr(params, key); + } break; } sep = ","; } diff --git a/CepGenAddOns/PythonWrapper/PythonConfigWriter.h b/CepGenAddOns/PythonWrapper/PythonConfigWriter.h index cc61b166b..27215913f 100644 --- a/CepGenAddOns/PythonWrapper/PythonConfigWriter.h +++ b/CepGenAddOns/PythonWrapper/PythonConfigWriter.h @@ -34,7 +34,9 @@ namespace cepgen { PythonConfigWriter& operator<<(const ParametersDescription&); private: + inline std::string offset(size_t num) { return std::string(num * tab_len_, ' '); } ///< Compute a char-offset mutable std::ofstream file_; + const size_t tab_len_{4}; }; } // namespace python } // namespace cepgen diff --git a/CepGenAddOns/PythonWrapper/PythonDocumentationGenerator.cpp b/CepGenAddOns/PythonWrapper/PythonDocumentationGenerator.cpp new file mode 100644 index 000000000..f872f9b39 --- /dev/null +++ b/CepGenAddOns/PythonWrapper/PythonDocumentationGenerator.cpp @@ -0,0 +1,51 @@ +/* + * CepGen: a central exclusive processes event generator + * Copyright (C) 2024 Laurent Forthomme + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "CepGen/Modules/DocumentationGeneratorFactory.h" +#include "CepGen/Utils/DocumentationGenerator.h" +#include "CepGenAddOns/PythonWrapper/PythonConfigWriter.h" + +using namespace cepgen; + +/// Python modules documentation generator +/// \author Laurent Forthomme +/// \date Mar 2024 +class PythonDocumentationGenerator final : public cepgen::utils::DocumentationGenerator { +public: + explicit PythonDocumentationGenerator(const ParametersList& params) : DocumentationGenerator(params) {} + + static ParametersDescription description() { + auto desc = DocumentationGenerator::description(); + desc.setDescription("Python modules documentation generator"); + desc.add("filename", "output.py").setDescription("Python output filename"); + return desc; + } + + std::string describe() override { + python::PythonConfigWriter writer(steer("filename")); + const auto separator = std::string(80, '='); + for (const auto& cat : categories_) { + if (cat.second.modules.empty()) + continue; + for (const auto& mod : cat.second.modules) + writer << mod.second; + } + return ""; + } +}; +REGISTER_DOCUMENTATION_GENERATOR("python", PythonDocumentationGenerator); diff --git a/src/cepgen.cc b/src/cepgen.cc index 54a8852f3..03c43303c 100644 --- a/src/cepgen.cc +++ b/src/cepgen.cc @@ -22,9 +22,11 @@ #include "CepGen/EventFilter/EventExporter.h" #include "CepGen/Generator.h" #include "CepGen/Modules/CardsHandlerFactory.h" +#include "CepGen/Modules/DocumentationGeneratorFactory.h" #include "CepGen/Modules/EventExporterFactory.h" #include "CepGen/Utils/AbortHandler.h" #include "CepGen/Utils/ArgumentsParser.h" +#include "CepGen/Utils/DocumentationGenerator.h" using namespace std; @@ -48,39 +50,36 @@ int main(int argc, char* argv[]) { .addOptionalArgument("safe-mode,s", "safe mode", &safe_mode, false) .parse(); - cepgen::Generator gen(safe_mode); - - //--- first start by defining the generator object - for (const auto& lib : addons) + cepgen::Generator gen(safe_mode); // first start by defining the generator object + for (const auto& lib : addons) // loading of additional plugins into the runtime environment manager try { cepgen::loadLibrary(lib); } catch (const cepgen::Exception& e) { e.dump(); } - //--- if modules listing is requested - if (list_mods) { - cepgen::dumpModules(); + if (list_mods) { // modules listing is requested ; dump and exit + auto doc_dump = + cepgen::DocumentationGeneratorFactory::get().build("text", cepgen::ParametersList().set("light", true)); + doc_dump->initialise(); + CG_LOG << doc_dump->describe(); return 0; } - //--- no steering card nor additional flags found - if (input_card.empty() && parser.extra_config().empty()) { + if (input_card.empty() && parser.extra_config().empty()) { // no steering card nor additional flags found CG_WARNING("main") << "Neither input card nor configuration word provided!\n\n " << parser.help_message(); return 0; } - //--- parse the steering card if (!input_card.empty()) - gen.parseRunParameters(input_card); - //--- parse the additional flags - if (!parser.extra_config().empty()) { + gen.parseRunParameters(input_card); // parse the steering card + if (!parser.extra_config().empty()) { // parse any additional flags auto args_handler = cepgen::CardsHandlerFactory::get().build(".cmd"); args_handler->setRunParameters(&gen.runParameters()); args_handler->parseCommands(parser.extra_config()); gen.setRunParameters(args_handler->runParameters()); } - cepgen::utils::AbortHandler(); + cepgen::utils::AbortHandler(); // allow C-c to be triggered during a run try { auto& params = gen.runParameters(); @@ -91,14 +90,12 @@ int main(int argc, char* argv[]) { for (const auto& output : outputs) gen.runParameters().addEventExporter(cepgen::EventExporterFactory::get().build(output)); - //--- list all parameters - CG_LOG << gen.runParameters(); + CG_LOG << gen.runParameters(); // user-friendly printout of all run parameters - //--- let there be a cross-section... - gen.computeXsection(); + gen.computeXsection(); //--- let there be a cross-section... if (params.generation().enabled()) - //--- events generation starts here + // events generation happens here // (one may use a callback function) gen.generate(0); } catch (const cepgen::utils::RunAbortedException&) { diff --git a/src/utils/cepgenDescribeModules.cc b/src/utils/cepgenDescribeModules.cc index 3bb407195..13bd02bda 100644 --- a/src/utils/cepgenDescribeModules.cc +++ b/src/utils/cepgenDescribeModules.cc @@ -1,6 +1,6 @@ /* * CepGen: a central exclusive processes event generator - * Copyright (C) 2021-2024 Laurent Forthomme + * Copyright (C) 2022-2024 Laurent Forthomme * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,140 +16,39 @@ * along with this program. If not, see . */ -#include "CepGen/Core/Exception.h" +#include + #include "CepGen/Generator.h" +#include "CepGen/Modules/DocumentationGeneratorFactory.h" #include "CepGen/Utils/ArgumentsParser.h" -#include "CepGen/Utils/String.h" - -// list of factories described -#include "CepGen/Modules/AnalyticIntegratorFactory.h" -#include "CepGen/Modules/CardsHandlerFactory.h" -#include "CepGen/Modules/CouplingFactory.h" -#include "CepGen/Modules/DerivatorFactory.h" -#include "CepGen/Modules/DrawerFactory.h" -#include "CepGen/Modules/EventExporterFactory.h" -#include "CepGen/Modules/EventImporterFactory.h" -#include "CepGen/Modules/EventModifierFactory.h" -#include "CepGen/Modules/FormFactorsFactory.h" -#include "CepGen/Modules/FunctionalFactory.h" -#include "CepGen/Modules/GeneratorWorkerFactory.h" -#include "CepGen/Modules/IntegratorFactory.h" -#include "CepGen/Modules/PartonFluxFactory.h" -#include "CepGen/Modules/PhaseSpaceGeneratorFactory.h" -#include "CepGen/Modules/ProcessFactory.h" -#include "CepGen/Modules/RandomGeneratorFactory.h" -#include "CepGen/Modules/StructureFunctionsFactory.h" +#include "CepGen/Utils/DocumentationGenerator.h" +#include "CepGen/Utils/Message.h" using namespace std; -#define LOOP_FACTORY(desc, obj) \ - { \ - if (all) \ - os << "\n" \ - << cepgen::utils::colourise(string(80, '=') + "\n" + string(desc) + " modules" + "\n" + string(80, '='), \ - cepgen::utils::Colour::green, \ - cepgen::utils::Modifier::bold) \ - << "\n"; \ - for (const auto& mod_name : obj::get().modules()) { \ - if (all) \ - os << describe_one(desc, false, obj::get().describeParameters(mod_name)); \ - else \ - for (const auto& mod : modules) \ - if (mod == mod_name) \ - os << describe_one(desc, true, obj::get().describeParameters(mod_name)); \ - } \ - } \ - static_assert(true, "") -#define LOOP_FACTORY_INT(desc, obj) \ - if (all) { \ - os << "\n" \ - << cepgen::utils::colourise(string(80, '=') + "\n" + string(desc) + " modules" + "\n" + string(80, '='), \ - cepgen::utils::Colour::green, \ - cepgen::utils::Modifier::bold) \ - << "\n"; \ - for (const auto& mod_name : obj::get().modules()) { \ - if (all) \ - os << describe_one(desc, false, obj::get().describeParameters(mod_name)); \ - else \ - for (const auto& mod : modules) \ - if (cepgen::utils::isInt(mod) && stod(mod) == mod_name) \ - os << describe_one(desc, true, obj::get().describeParameters(mod_name)); \ - } \ - } \ - static_assert(true, "") - -/** Listing module for CepGen - * \author Laurent Forthomme - */ int main(int argc, char* argv[]) { - bool list_mods, safe_mode, dump_params, all; - vector addons, modules; - - cepgen::ArgumentsParser parser(argc, argv); - parser.addOptionalArgument("list-modules,l", "list all runtime modules", &list_mods, false) - .addOptionalArgument("modules,m", "list of runtime modules to be described", &modules) - .addOptionalArgument("add-ons,e", "external runtime plugin", &addons) - .addOptionalArgument("safe-mode,s", "safe mode", &safe_mode, false) - .addOptionalArgument("dump-params,p", "dump the ParametersList object", &dump_params, false) - .addOptionalArgument("all,a", "dump all modules descriptions", &all, false) + string doc_generator, output_file; + vector categories, modules_names; + cepgen::ArgumentsParser(argc, argv) + .addOptionalArgument("documentation-generator,D", "type of documentation", &doc_generator, "text") + .addOptionalArgument("output,o", "output file", &output_file, "") + .addOptionalArgument("categories,C", "categories to document", &categories, vector{}) + .addOptionalArgument("modules,m", "module names to document", &modules_names, vector{}) .parse(); - //--- first start by defining the generator object - try { - for (const auto& lib : addons) - cepgen::loadLibrary(lib); - cepgen::Generator gen(safe_mode); - } catch (const cepgen::Exception& e) { - e.dump(); - } - - //--- if modules listing is requested - if (list_mods) { - cepgen::dumpModules(); - return 0; - } - if (all or !modules.empty()) { - auto describe_one = - [&dump_params](const string& type, bool dump_mod_name, const cepgen::ParametersDescription& desc) -> string { - ostringstream os; - os << "\n"; - if (dump_mod_name) - os << cepgen::utils::colourise( - type, cepgen::utils::Colour::none, cepgen::utils::Modifier::underline | cepgen::utils::Modifier::bold) - << " module:\n\n"; - os << desc.describe(); - if (dump_params) - os << "\n\tParametersList object:\n\t\t" << desc.parameters(); - os << "\n"; - return os.str(); - }; - - ostringstream os; - LOOP_FACTORY("Cards steering", cepgen::CardsHandlerFactory); - // event management - LOOP_FACTORY("Process", cepgen::ProcessFactory); - LOOP_FACTORY("Event import", cepgen::EventImporterFactory); - LOOP_FACTORY("Event generation", cepgen::GeneratorWorkerFactory); - LOOP_FACTORY("Event modification", cepgen::EventModifierFactory); - LOOP_FACTORY("Event export", cepgen::EventExporterFactory); - // physics evaluators - LOOP_FACTORY("Phase space mapper", cepgen::PhaseSpaceGeneratorFactory); - LOOP_FACTORY("Collinear parton flux modelling", cepgen::CollinearFluxFactory); - LOOP_FACTORY("KT-factorised parton flux modelling", cepgen::KTFluxFactory); - LOOP_FACTORY("Beam form factors modelling", cepgen::FormFactorsFactory); - LOOP_FACTORY_INT("Structure functions modelling", cepgen::StructureFunctionsFactory); - LOOP_FACTORY_INT("Cross sections ratio modelling", cepgen::SigmaRatiosFactory); - LOOP_FACTORY("alpha(EM)", cepgen::AlphaEMFactory); - LOOP_FACTORY("alpha(S)", cepgen::AlphaSFactory); - // utilities - LOOP_FACTORY("Functional evaluator", cepgen::FunctionalFactory); - LOOP_FACTORY("Integrator", cepgen::IntegratorFactory); - LOOP_FACTORY("Analytic integrator", cepgen::AnalyticIntegratorFactory); - LOOP_FACTORY("Derivator", cepgen::DerivatorFactory); - LOOP_FACTORY("Random generator", cepgen::RandomGeneratorFactory); - LOOP_FACTORY("Drawer", cepgen::DrawerFactory); - CG_LOG << os.str(); - return 0; + cepgen::initialise(); + auto gen = cepgen::DocumentationGeneratorFactory::get().build( + doc_generator, cepgen::ParametersList().set("categories", categories).set("modules", modules_names)); + gen->initialise(); + const auto documentation = gen->describe(); + + if (output_file.empty()) + CG_LOG << documentation; + else { + ofstream of(output_file); + of << documentation; + of.close(); + CG_INFO("main") << "Documentation written in '" << output_file << "'."; } return 0;