#include "lib/core/globals.h" #include "lib/config/proto.h" #include "lib/config/flags.h" #include "fmt/format.h" extern const std::map formats; static const ConfigProto& findConfig(std::string name) { return *formats.at(name); } static void addExample(std::vector& examples, bool write, std::string name, ConfigProto config, const OptionProto* format) { std::string r; if (format) config.MergeFrom(format->config()); if (write && config.has_encoder()) r += fmt::format("fluxengine write"); else if (!write && config.has_decoder()) r += fmt::format("fluxengine read"); else return; r += fmt::format(" {}", name); if (format) r += fmt::format(" --{}", format->name()); std::string filename = write ? config.image_reader().filename() : config.image_writer().filename(); if (filename.empty()) filename = fmt::format("{}.img", name); if (write) r += fmt::format(" -d drive:0 -i {}", filename); else r += fmt::format(" -s drive:0 -o {}", filename); examples.push_back(r); } int main(int argc, const char* argv[]) { auto config = findConfig(argv[1]); fmt::print("{}\n====\n", argv[1]); fmt::print("## {}\n", config.comment()); fmt::print( "\n\n"); const auto& documentation = config.documentation(); auto it = documentation.begin(); if (it != documentation.end()) { fmt::print("{}\n", *it++); if (!config.is_extension()) { fmt::print("## Options\n\n"); const OptionGroupProto* formatGroup = nullptr; if (!config.option().empty() || !config.option_group().empty()) { for (const auto& option_group : config.option_group()) { auto groupName = option_group.comment(); if (groupName == "$formats") { groupName = "Format variants"; formatGroup = &option_group; } fmt::print(" - {}:\n", groupName); for (const auto& option : option_group.option()) fmt::print(" - `{}`: {}\n", option.name(), option.comment()); } for (const auto& option : config.option()) fmt::print( " - `{}`: {}\n", option.name(), option.comment()); } else fmt::print("(no options)\n"); fmt::print("\n"); fmt::print("## Examples\n\n"); std::vector examples; if (formatGroup) { for (const auto& option : formatGroup->option()) addExample(examples, false, argv[1], config, &option); } else addExample(examples, false, argv[1], config, nullptr); if (!examples.empty()) { fmt::print("To read:\n\n"); for (const std::string& e : examples) fmt::print(" - `{}`\n", e); fmt::print("\n"); } examples.clear(); if (formatGroup) { for (const auto& option : formatGroup->option()) addExample(examples, true, argv[1], config, &option); } else addExample(examples, true, argv[1], config, nullptr); if (!examples.empty()) { fmt::print("To write:\n\n"); for (const std::string& e : examples) fmt::print(" - `{}`\n", e); fmt::print("\n"); } } while (it != documentation.end()) fmt::print("{}\n", *it++); } else fmt::print("(This format has no documentation. Please file a bug.)\n"); return 0; }