From ce3d5b955658f8a6f87fe66c0c14b203798fd439 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Thu, 25 Sep 2025 15:52:28 +0800 Subject: [PATCH] feat: finish basic of manual in clap --- src/CMakeLists.txt | 10 ++++----- src/yycc/carton/clap/manual.cpp | 37 ++++++++++++++++++++++++++----- src/yycc/carton/clap/manual.hpp | 6 ++--- src/yycc/carton/clap/option.cpp | 24 +++++++++----------- src/yycc/carton/clap/summary.cpp | 8 ++++++- src/yycc/carton/clap/summary.hpp | 4 +++- src/yycc/carton/clap/variable.cpp | 4 ++-- src/yycc/patch/format.hpp | 1 + src/yycc/patch/stream.hpp | 2 ++ 9 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 492a4f2..d2aba0d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,11 +31,11 @@ PRIVATE yycc/carton/tabulate.cpp yycc/carton/ironpad.cpp yycc/carton/csconsole.cpp - #yycc/carton/clap/option.cpp - #yycc/carton/clap/variable.cpp - #yycc/carton/clap/summary.cpp - #yycc/carton/clap/application.cpp - #yycc/carton/clap/manual.cpp + yycc/carton/clap/option.cpp + yycc/carton/clap/variable.cpp + yycc/carton/clap/summary.cpp + yycc/carton/clap/application.cpp + yycc/carton/clap/manual.cpp ) target_sources(YYCCommonplace PUBLIC diff --git a/src/yycc/carton/clap/manual.cpp b/src/yycc/carton/clap/manual.cpp index c04b544..98addce 100644 --- a/src/yycc/carton/clap/manual.cpp +++ b/src/yycc/carton/clap/manual.cpp @@ -1,16 +1,18 @@ #include "manual.hpp" #include "../termcolor.hpp" #include "../../patch/stream.hpp" +#include "../../patch/format.hpp" #include "../../string/op.hpp" #define CLAP ::yycc::carton::clap #define TABULATE ::yycc::carton::tabulate #define TERMCOLOR ::yycc::carton::termcolor +#define FORMAT ::yycc::patch::format #define OP ::yycc::carton::op using namespace ::yycc::patch::stream; -namespace yycc::carton::clap::manual::Manual { +namespace yycc::carton::clap::manual { #pragma region Manual Translation @@ -27,6 +29,8 @@ namespace yycc::carton::clap::manual::Manual { using Application = CLAP::application::Application; using Tabulate = TABULATE::Tabulate; + static constexpr char8_t INDENT[] = u8" "; + Manual::Manual(const Application &app, ManualTr &&trctx) : trctx(std::move(trctx)), app(app), opt_printer(3), var_printer(2) { this->setup_table(); this->fill_opt_table(); @@ -38,11 +42,11 @@ namespace yycc::carton::clap::manual::Manual { void Manual::setup_table() { this->opt_printer.show_header(false); this->opt_printer.show_bar(false); - this->opt_printer.set_prefix(u8" "); + this->opt_printer.set_prefix(INDENT); this->var_printer.show_header(false); this->var_printer.show_bar(false); - this->var_printer.set_prefix(u8" "); + this->var_printer.set_prefix(INDENT); } void Manual::fill_opt_table() { @@ -57,13 +61,34 @@ namespace yycc::carton::clap::manual::Manual { void Manual::print_version(std::ostream &dst) const { const auto &summary = this->app.get_summary(); - dst << std::format + TERMCOLOR::cprintln(summary.get_name(), TERMCOLOR::Color::Yellow, TERMCOLOR::Color::Default, TERMCOLOR::Attribute::Default, dst); + dst << summary.get_name() << std::endl; + dst << FORMAT::format(trctx.author_and_version, summary.get_author(), summary.get_version()) << std::endl; dst << summary.get_description() << std::endl; dst << std::endl; } - void Manual::print_help(std::ostream &dst) const {} + void Manual::print_help(std::ostream &dst) const { + this->print_version(); + + TERMCOLOR::cprintln(trctx.usage_title, TERMCOLOR::Color::Yellow, TERMCOLOR::Color::Default, TERMCOLOR::Attribute::Default, dst); + dst << INDENT << FORMAT::format(trctx.usage_body, app.get_summary().get_bin_name()) << std::endl; + + const auto &variables = app.get_variables(); + if (!variables.empty()) { + TERMCOLOR::cprintln(trctx.avail_var, TERMCOLOR::Color::Yellow, TERMCOLOR::Color::Default, TERMCOLOR::Attribute::Default, dst); + this->var_printer.print(dst); + dst << std::endl; + } + + const auto &options = app.get_options(); + if (!options.empty()) { + TERMCOLOR::cprintln(trctx.avail_opt, TERMCOLOR::Color::Yellow, TERMCOLOR::Color::Default, TERMCOLOR::Attribute::Default, dst); + this->opt_printer.print(dst); + dst << std::endl; + } + } #pragma endregion -} // namespace yycc::carton::clap::manual::Manual +} // namespace yycc::carton::clap::manual diff --git a/src/yycc/carton/clap/manual.hpp b/src/yycc/carton/clap/manual.hpp index 8ce2751..416d18d 100644 --- a/src/yycc/carton/clap/manual.hpp +++ b/src/yycc/carton/clap/manual.hpp @@ -7,7 +7,7 @@ #define NS_YYCC_CLAP ::yycc::carton::clap #define NS_YYCC_TABULATE ::yycc::carton::tabulate -namespace yycc::carton::clap::manual::Manual { +namespace yycc::carton::clap::manual { struct ManualTr { public: @@ -20,7 +20,7 @@ namespace yycc::carton::clap::manual::Manual { std::u8string usage_title, usage_body; std::u8string avail_opt, avail_var; }; - + class Manual { public: Manual(const NS_YYCC_CLAP::application::Application& app, ManualTr&& trctx = ManualTr()); @@ -43,7 +43,7 @@ namespace yycc::carton::clap::manual::Manual { NS_YYCC_TABULATE::Tabulate var_printer; }; -} +} // namespace yycc::carton::clap::manual #undef NS_YYCC_TABULATE #undef NS_YYCC_CLAP diff --git a/src/yycc/carton/clap/option.cpp b/src/yycc/carton/clap/option.cpp index 74f8df6..2638ecd 100644 --- a/src/yycc/carton/clap/option.cpp +++ b/src/yycc/carton/clap/option.cpp @@ -1,11 +1,9 @@ #include "option.hpp" -#include "../../string/op.hpp" #include "../../patch/format.hpp" #include -#include #define TYPES ::yycc::carton::clap::types -#define OP ::yycc::string::op +#define FORMAT ::yycc::patch::format namespace yycc::carton::clap::option { @@ -23,13 +21,13 @@ namespace yycc::carton::clap::option { if (short_name.has_value()) { const auto& short_name_value = short_name.value(); if (!legal_short_name(short_name_value)) { - throw std::logic_error(std::format("invalid short name {}", short_name_value)); + throw std::logic_error(FORMAT::format("invalid short name {}", short_name_value)); } } if (long_name.has_value()) { const auto& long_name_value = long_name.value(); if (!legal_long_name(long_name_value)) { - throw std::logic_error(std::format("invalid long name {}", long_name_value)); + throw std::logic_error(FORMAT::format("invalid long name {}", long_name_value)); } } } @@ -55,13 +53,13 @@ namespace yycc::carton::clap::option { std::u8string Option::to_showcase_name() const { if (short_name.has_value()) { if (long_name.has_value()) { - return OP::printf(u8"%s%s %s%s", TYPES::DASH, short_name.value().c_str(), TYPES::DOUBLE_DASH, long_name.value().c_str()); + return FORMAT::format(u8"{}{} {}{}", TYPES::DASH, short_name.value(), TYPES::DOUBLE_DASH, long_name.value()); } else { - return OP::printf(u8"%s%s", TYPES::DASH, short_name.value().c_str()); + return FORMAT::format(u8"{}{}", TYPES::DASH, short_name.value()); } } else { if (long_name.has_value()) { - return OP::printf(u8"%s%s", TYPES::DOUBLE_DASH, long_name.value().c_str()); + return FORMAT::format(u8"{}{}", TYPES::DOUBLE_DASH, long_name.value()); } else { throw std::runtime_error("both long name and short name are empty"); } @@ -70,7 +68,7 @@ namespace yycc::carton::clap::option { std::u8string Option::to_showcase_value() const { if (value_hint.has_value()) { - return OP::printf(u8"<%s>", value_hint.value().c_str()); + return FORMAT::format(u8"<{}>", value_hint.value()); } else { return {}; } @@ -119,11 +117,11 @@ namespace yycc::carton::clap::option { std::u8string short_name_value(short_name.value()); if (this->long_names.contains(short_name_value)) { throw std::logic_error( - std::format("short name {} is duplicated with same long name", short_name_value)); + FORMAT::format("short name {} is duplicated with same long name", short_name_value)); } auto [_, ok] = this->short_names.try_emplace(short_name_value, token); if (!ok) { - throw std::logic_error(std::format("duplicate short name {}", short_name_value)); + throw std::logic_error(FORMAT::format("duplicate short name {}", short_name_value)); } } const auto& long_name = opt.get_long_name(); @@ -131,11 +129,11 @@ namespace yycc::carton::clap::option { std::u8string long_name_value(long_name.value()); if (this->short_names.contains(long_name_value)) { throw std::logic_error( - std::format("long name {} is duplicated with same short name", long_name_value)); + FORMAT::format("long name {} is duplicated with same short name", long_name_value)); } auto [_, ok] = this->long_names.try_emplace(long_name_value, token); if (!ok) { - throw std::logic_error(std::format("duplicate long name {}", long_name_value)); + throw std::logic_error(FORMAT::format("duplicate long name {}", long_name_value)); } } diff --git a/src/yycc/carton/clap/summary.cpp b/src/yycc/carton/clap/summary.cpp index 69d9567..5365a1a 100644 --- a/src/yycc/carton/clap/summary.cpp +++ b/src/yycc/carton/clap/summary.cpp @@ -3,9 +3,11 @@ namespace yycc::carton::clap::summary { Summary::Summary(const std::u8string_view &name, + const std::u8string_view &bin_name, const std::u8string_view &author, const std::u8string_view &version, - const std::u8string_view &description) : name(name), author(author), version(version), description(description) {} + const std::u8string_view &description) : + name(name), bin_name(bin_name), author(author), version(version), description(description) {} Summary::~Summary() {} @@ -13,6 +15,10 @@ namespace yycc::carton::clap::summary { return this->name; } + std::u8string_view Summary::get_bin_name() const { + return this->bin_name; + } + std::u8string_view Summary::get_author() const { return this->author; } diff --git a/src/yycc/carton/clap/summary.hpp b/src/yycc/carton/clap/summary.hpp index 5de2a0c..6bfdc29 100644 --- a/src/yycc/carton/clap/summary.hpp +++ b/src/yycc/carton/clap/summary.hpp @@ -8,6 +8,7 @@ namespace yycc::carton::clap::summary { class Summary { public: Summary(const std::u8string_view& name, + const std::u8string_view& bin_name, const std::u8string_view& author, const std::u8string_view& version, const std::u8string_view& description); @@ -16,12 +17,13 @@ namespace yycc::carton::clap::summary { public: std::u8string_view get_name() const; + std::u8string_view get_bin_name() const; std::u8string_view get_author() const; std::u8string_view get_version() const; std::u8string_view get_description() const; private: - std::u8string name, author, version, description; + std::u8string name, bin_name, author, version, description; }; } diff --git a/src/yycc/carton/clap/variable.cpp b/src/yycc/carton/clap/variable.cpp index 346f0b2..8459294 100644 --- a/src/yycc/carton/clap/variable.cpp +++ b/src/yycc/carton/clap/variable.cpp @@ -1,9 +1,9 @@ #include "variable.hpp" #include "../../patch/format.hpp" #include -#include #define TYPES ::yycc::carton::clap::types +#define FORMAT ::yycc::patch::format namespace yycc::carton::clap::variable { @@ -55,7 +55,7 @@ namespace yycc::carton::clap::variable { std::u8string name(var.get_name()); auto [_, ok] = this->names.try_emplace(name, token); if (!ok) { - throw std::logic_error(std::format("duplicated variable name {}", name)); + throw std::logic_error(FORMAT::format("duplicated variable name {}", name)); } this->variables.emplace_back(RegisteredVariable(token, std::move(var))); diff --git a/src/yycc/patch/format.hpp b/src/yycc/patch/format.hpp index a2394d7..c7d7b21 100644 --- a/src/yycc/patch/format.hpp +++ b/src/yycc/patch/format.hpp @@ -20,6 +20,7 @@ namespace yycc::patch::format { // TODO: order all use of std::format redirect to this function. + // TODO: all use of OP::printf should also switch to this function if possible. template std::string format(std::format_string fmt, Args&&... args) { diff --git a/src/yycc/patch/stream.hpp b/src/yycc/patch/stream.hpp index 4bcb281..159ce14 100644 --- a/src/yycc/patch/stream.hpp +++ b/src/yycc/patch/stream.hpp @@ -10,6 +10,8 @@ */ namespace yycc::patch::stream { + // TODO: replace all old way of outputing utf8 string with this new way. + std::ostream& operator<<(std::ostream& os, const std::u8string_view& u8str); std::ostream& operator<<(std::ostream& os, const char8_t* u8str); std::ostream& operator<<(std::ostream& os, char8_t u8chr);