diff --git a/.github/workflows/demo.yaml b/.github/workflows/demo.yaml index 03ad961d..1f48e569 100644 --- a/.github/workflows/demo.yaml +++ b/.github/workflows/demo.yaml @@ -1,4 +1,4 @@ -name: demo +name: CPP-ARGON Demo on: push: branches: diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml index 36bcd6a4..098a6283 100644 --- a/.github/workflows/documentation.yaml +++ b/.github/workflows/documentation.yaml @@ -1,4 +1,4 @@ -name: documentation +name: Documentation on: pull_request: @@ -40,7 +40,7 @@ jobs: continue-on-error: false run: | doxygen Doxyfile - python3 scripts/postprocess_doxyhtml.py ./documentation + python3 scripts/postprocess_doxyhtml.py ./documentation --img-rules docs/style/img_style_rules.json - name: Validate output run: test -d documentation && test -f documentation/index.html @@ -84,7 +84,7 @@ jobs: continue-on-error: false run: | doxygen Doxyfile - python3 scripts/postprocess_doxyhtml.py ./documentation + python3 scripts/postprocess_doxyhtml.py ./documentation --img-rules docs/style/img_style_rules.json - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v4 diff --git a/.github/workflows/format.yaml b/.github/workflows/format.yaml index f8a84fef..c6f319ba 100644 --- a/.github/workflows/format.yaml +++ b/.github/workflows/format.yaml @@ -1,4 +1,4 @@ -name: format +name: Code Formatting on: push: branches: diff --git a/.github/workflows/license.yaml b/.github/workflows/license.yaml index b82682e4..011b3004 100644 --- a/.github/workflows/license.yaml +++ b/.github/workflows/license.yaml @@ -1,4 +1,4 @@ -name: license +name: License on: push: branches: diff --git a/.gitmodules b/.gitmodules index b9cf135d..fcf0b52f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,5 +2,5 @@ path = cpp-argon-demo url = https://github.com/SpectraL519/cpp-argon-demo.git [submodule "doxygen-awesome-css"] - path = doxygen-awesome-css + path = docs/style/doxygen-awesome-css url = https://github.com/SpectraL519/doxygen-awesome-css.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 196029d4..7ce9fb3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ else() endif() project(cpp-argon - VERSION 4.0.0 + VERSION 4.0.1 DESCRIPTION "Command-line argument parser for C++20" HOMEPAGE_URL "https://github.com/SpectraL519/cpp-argon" LANGUAGES CXX diff --git a/Doxyfile b/Doxyfile index 7e2bfcd7..7cc5afd3 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = CPP-ARGON # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.0.0 +PROJECT_NUMBER = 4.0.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -190,7 +190,7 @@ FULL_PATH_NAMES = YES # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = . # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -1004,7 +1004,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = format .gitignore .clang-format test/doctest.h +EXCLUDE = .gitignore .clang-format .clangd tests/external/doctest.h scripts/ docs/style/ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -1315,7 +1315,7 @@ HTML_STYLESHEET = # documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = doxygen-awesome-css/doxygen-awesome.css doxygen-ext-stylesheet.css +HTML_EXTRA_STYLESHEET = docs/style/doxygen-awesome-css/doxygen-awesome.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note diff --git a/MODULE.bazel b/MODULE.bazel index f8f82ee4..8570bbe2 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,4 +1,4 @@ module( name = "cpp-argon", - version = "4.0.0", + version = "4.0.1", ) diff --git a/README.md b/README.md index 86d3f57a..eedde6d3 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@
-[![format](https://github.com/SpectraL519/cpp-argon/actions/workflows/format.yaml/badge.svg)](https://github.com/SpectraL519/cpp-argon/actions/workflows/format) -[![demo](https://github.com/SpectraL519/cpp-argon/actions/workflows/demo.yaml/badge.svg)](https://github.com/SpectraL519/cpp-argon/actions/workflows/demo) -[![documentation](https://github.com/SpectraL519/cpp-argon/actions/workflows/documentation.yaml/badge.svg)](https://github.com/SpectraL519/cpp-argon/actions/workflows/documentation) -[![changelog](https://img.shields.io/badge/changelog-blue.svg?logo=github)](https://github.com/SpectraL519/cpp-argon/releases) +[![Code Formatting](https://github.com/SpectraL519/cpp-argon/actions/workflows/format.yaml/badge.svg)](https://github.com/SpectraL519/cpp-argon/actions/workflows/format) +[![CPP-ARGON Demo](https://github.com/SpectraL519/cpp-argon/actions/workflows/demo.yaml/badge.svg)](https://github.com/SpectraL519/cpp-argon/actions/workflows/demo) +[![Documentation](https://github.com/SpectraL519/cpp-argon/actions/workflows/documentation.yaml/badge.svg)](https://github.com/SpectraL519/cpp-argon/actions/workflows/documentation) +[![Changelog](https://img.shields.io/badge/changelog-blue.svg?logo=github)](https://github.com/SpectraL519/cpp-argon/releases)
diff --git a/docs/style/doxygen-awesome-css b/docs/style/doxygen-awesome-css new file mode 160000 index 00000000..e12d72ef --- /dev/null +++ b/docs/style/doxygen-awesome-css @@ -0,0 +1 @@ +Subproject commit e12d72efe0f4c43de9a7f1f0f3c184dc0107f98b diff --git a/docs/style/img_style_rules.json b/docs/style/img_style_rules.json new file mode 100644 index 00000000..e710cad1 --- /dev/null +++ b/docs/style/img_style_rules.json @@ -0,0 +1,6 @@ +[ + { + "alt": "CPP-ARGON", + "style": "display: block; margin: 1.5em auto;" + } +] diff --git a/docs/tutorial.md b/docs/tutorial.md index 31fcc029..c33532e0 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -12,19 +12,20 @@ - [Boolean Flags](#boolean-flags) - [Argument Parameters](#argument-parameters) - [Common Parameters](#common-parameters) - - [help](#1-help---the-arguments-description-which-will-be-printed-when-printing-the-parser-class-instance) - the text shown in the help message to describe an argument - - [hidden](#2-hidden---if-this-option-is-set-for-an-argument-then-it-will-not-be-included-in-the-program-description) - hides the argument from the generated program description and help output - - [required](#3-required---if-this-option-is-set-for-an-argument-and-its-value-is-not-passed-in-the-command-line-an-exception-will-be-thrown) - marks the argument as mandatory; not using it will cause an error - - [suppress arg checks](#4-suppress_arg_checks---using-a-suppressing-argument-results-in-suppressing-requirement-checks-for-other-arguments) - if a suppressing argument is used, other requirement validation will be skipped for other arguments - - [nargs](#5-nargs---sets-the-allowed-number-of-values-to-be-parsed-for-an-argument) - defines how many values an argument can or must accept - - [greedy](#6-greedy---if-this-option-is-set-the-argument-will-consume-all-command-line-values-until-its-upper-nargs-bound-is-reached) - makes the argument consume all following values until its limit is reached - - [choices](#7-choices---a-list-of-valid-argument-values) - restricts the valid inputs to a predefined set of values - - [value actions](#8-value-actions---functions-that-are-called-after-parsing-an-arguments-value) - allows you to run custom code after the argument’s value is parsed - - [default values](#9-default_values---a-list-of-values-which-will-be-used-if-no-values-for-an-argument-have-been-parsed) - specifies fallback values to use if none are provided + - [Help - The argument's description which will be printed when printing the parser class instance.](#help---the-arguments-description-which-will-be-printed-when-printing-the-parser-class-instance) + - [Hidden - If this option is set for an argument, then it will not be included in the program description.](#hidden---if-this-option-is-set-for-an-argument-then-it-will-not-be-included-in-the-program-description) + - [Required - If this option is set for an argument and it's value is not passed in the command-line, an exception will be thrown.](#required---if-this-option-is-set-for-an-argument-and-its-value-is-not-passed-in-the-command-line-an-exception-will-be-thrown) + - [Argument Checks Suppression - Using a suppressing argument results in suppressing requirement checks for other arguments.](#argument-checks-suppression---using-a-suppressing-argument-results-in-suppressing-requirement-checks-for-other-arguments) + - [Number of Arguments - Sets the allowed number of values to be parsed for an argument.](#number-of-arguments---sets-the-allowed-number-of-values-to-be-parsed-for-an-argument) + - [Greedy Parsing - If this option is set, the argument will consume ALL command-line values until it's upper nargs bound is reached.](#greedy-parsing---if-this-option-is-set-the-argument-will-consume-all-command-line-values-until-its-upper-nargs-bound-is-reached) + - [Choices - A list of valid argument values.](#choices---a-list-of-valid-argument-values) + - [Value Actions - Functions that are called after parsing an argument's value.](#value-actions---functions-that-are-called-after-parsing-an-arguments-value) + - [Default Values - A list of values which will be used if no values for an argument have been parsed](#default-values---a-list-of-values-which-will-be-used-if-no-values-for-an-argument-have-been-parsed) - [Parameters Specific for Optional Arguments](#parameters-specific-for-optional-arguments) - - [on-flag actions](#1-on-flag-actions---functions-that-are-called-immediately-after-parsing-an-arguments-flag) - executes custom code immediately when the argument’s flag is present - - [implicit values](#2-implicit_values---a-list-of-values-which-will-be-set-for-an-argument-if-only-its-flag-but-no-values-are-parsed-from-the-command-line) - automatically assigns a value if an argument flag is used without an explicit value + - [On-flag Actions - Functions that are called immediately after parsing an argument's flag.](#on-flag-actions---functions-that-are-called-immediately-after-parsing-an-arguments-flag) + - [Implicit Values - A list of values which will be set for an argument if only its flag but no values are parsed from the command-line.](#implicit-values---a-list-of-values-which-will-be-set-for-an-argument-if-only-its-flag-but-no-values-are-parsed-from-the-command-line) - [Predefined Parameter Values](#predefined-parameter-values) + - [Actions](#actions) - [Default Arguments](#default-arguments) - [Argument Groups](#argument-groups) - [Creating New Groups](#creating-new-groups) @@ -34,6 +35,10 @@ - [Suppressing Argument Group Checks](#suppressing-argument-group-checks) - [Parsing Arguments](#parsing-arguments) - [Basic Argument Parsing Rules](#basic-argument-parsing-rules) + - [1. Optional arguments are parsed only with a flag](#1-optional-arguments-are-parsed-only-with-a-flag) + - [2. Positional arguments are parsed in the order of definition](#2-positional-arguments-are-parsed-in-the-order-of-definition) + - [3. Positional arguments consume free values](#3-positional-arguments-consume-free-values) + - [4. Unknown Argument Flag Handling](#4-unknown-argument-flag-handling) - [Compound Arguments](#compound-arguments) - [Parsing Known Arguments](#parsing-known-arguments) - [Retrieving Argument Values](#retrieving-argument-values) @@ -42,6 +47,7 @@ - [Using Multiple Subparsers](#using-multiple-subparsers) - [Parsing Arguments with Subparsers](#parsing-arguments-with-subparsers) - [Tracking Parser State](#tracking-parser-state) + - [Example: Inspecting Parsing States](#example-inspecting-parsing-states) - [Examples](#examples) - [Common Utility](#common-utility) @@ -256,7 +262,6 @@ parser.add_optional_argument("disable_another_option", "dao") .nargs(0) .help("disables option: another option"); */ - ```
@@ -269,7 +274,7 @@ parser.add_optional_argument("disable_another_option", "dao") Parameters which can be specified for both positional and optional arguments include: -#### 1. `help` - The argument's description which will be printed when printing the parser class instance. +#### Help - The argument's description which will be printed when printing the parser class instance. ```cpp parser.add_positional_argument("number", "n") @@ -278,7 +283,7 @@ parser.add_positional_argument("number", "n")
-#### 2. `hidden` - If this option is set for an argument, then it will not be included in the program description. +#### Hidden - If this option is set for an argument, then it will not be included in the program description. By default all arguments are visible, but this can be modified using the `hidden(bool)` setter as follows: @@ -309,7 +314,7 @@ Optional arguments:
-#### 3. `required` - If this option is set for an argument and it's value is not passed in the command-line, an exception will be thrown. +#### Required - If this option is set for an argument and it's value is not passed in the command-line, an exception will be thrown. > [!IMPORTANT] > @@ -376,7 +381,7 @@ Command Result
-#### 4. `suppress_arg_checks` - Using a suppressing argument results in suppressing requirement checks for other arguments. +#### Argument Checks Suppression - Using a suppressing argument results in suppressing requirement checks for other arguments. If an argument is defined with the `suppress_arg_checks` option enabled and such argument is explicitly used in the command-line, then requirement validation will be suppressed/skipped for other arguments. This includes validating whether: - a required argument has been parsed @@ -417,7 +422,7 @@ os << data << std::endl;
-#### 5. `nargs` - Sets the allowed number of values to be parsed for an argument. +#### Number of Arguments - Sets the allowed number of values to be parsed for an argument. The `nargs` parameter can be set as: @@ -458,7 +463,7 @@ The `nargs` parameter can be set as:
-#### 6. `greedy` - If this option is set, the argument will consume ALL command-line values until it's upper nargs bound is reached. +#### Greedy Parsing - If this option is set, the argument will consume ALL command-line values until it's upper nargs bound is reached. > [!NOTE] > @@ -499,7 +504,7 @@ Notice that even though the `-v` and `--type` command-line arguments have flag p
-#### 7. `choices` - A list of valid argument values. +#### Choices - A list of valid argument values. ```cpp parser.add_optional_argument("method", "m").choices('a', 'b', 'c'); @@ -516,7 +521,7 @@ parser.add_optional_argument("method", "m").choices('a', 'b', 'c');
-#### 8. value actions - Functions that are called after parsing an argument's value. +#### Value Actions - Functions that are called after parsing an argument's value. Actions are represented as functions, which take the argument's value as an argument. The available action types are: - `observe` actions | `void(const value_type&)` - applied to the parsed value. No value is returned - this action type is used to perform some logic on the parsed value without modifying it. @@ -561,7 +566,7 @@ Actions are represented as functions, which take the argument's value as an argu
-#### 9. `default_values` - A list of values which will be used if no values for an argument have been parsed +#### Default Values - A list of values which will be used if no values for an argument have been parsed > [!WARNING] > @@ -624,7 +629,7 @@ Command Result Apart from the common parameters listed above, for optional arguments you can also specify the following parameters: -#### 1. on-flag actions - Functions that are called immediately after parsing an argument's flag. +#### On-flag Actions - Functions that are called immediately after parsing an argument's flag. ```cpp void print_debug_info() noexcept { @@ -644,7 +649,7 @@ Here the `print_debug_info` function will be called right after parsing the `--d
-#### 2. `implicit_values` - A list of values which will be set for an argument if only its flag but no values are parsed from the command-line. +#### Implicit Values - A list of values which will be set for an argument if only its flag but no values are parsed from the command-line. ```cpp // example @@ -1607,8 +1612,8 @@ The following table lists the projects provided in the `cpp-argon-demo` submodul | [Numbers Converter](https://github.com/SpectraL519/cpp-argon-demo/tree/master/numbers_converter/) | Converts numbers between different bases.
**Demonstrates:** The usage of argument parameters such as *nargs*, *choices*, and *default values*. | | [Verbosity](https://github.com/SpectraL519/cpp-argon-demo/tree/master/verbosity/) | Prints messages with varying levels of verbosity.
**Demonstrates:** The usage of `none_type` arguments and compound argument flags. | | [Logging Mode](https://github.com/SpectraL519/cpp-argon-demo/tree/master/logging_mode/) | Logs a message depending on the selected logging mode (`quiet`, `normal`, `verbose`).
**Demonstrates:** The usage of custom argument value types (like enums). | -| [Message Logger](https://github.com/SpectraL519/cpp-argon-demo/arg_parsertree/master/message_logger/) | Outputs a message to a file, console, or not at all.
**Demonstrates:** The usage of argument groups. | -| [AP-GIT](https://github.com/SpectraL519/cpp-argon-demo/tree/master/ap_git/) | A minimal Git CLI clone with subcommands (`init`, `add`, `commit`, `status`, `push`).
**Demonstrates:** The usage of subparsers for multi-command CLIs and complex argument configurations. | +| [Message Logger](https://github.com/SpectraL519/cpp-argon-demo/tree/master/message_logger/) | Outputs a message to a file, console, or not at all.
**Demonstrates:** The usage of argument groups. | +| [ARGON-GIT](https://github.com/SpectraL519/cpp-argon-demo/tree/master/argon_git/) | A minimal Git CLI clone with subcommands (`init`, `add`, `commit`, `status`, `push`).
**Demonstrates:** The usage of subparsers for multi-command CLIs and complex argument configurations. |

diff --git a/doxygen-awesome-css b/doxygen-awesome-css deleted file mode 160000 index 170ba433..00000000 --- a/doxygen-awesome-css +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 170ba433cdca0611d08c134dbac1e140f4ebb1c4 diff --git a/doxygen-ext-stylesheet.css b/doxygen-ext-stylesheet.css deleted file mode 100644 index cbcb0c85..00000000 --- a/doxygen-ext-stylesheet.css +++ /dev/null @@ -1,42 +0,0 @@ -@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"); - -.fa { - vertical-align: middle; - transition: transform 0.2s; -} -.fa:hover { - transform: scale(1.2); -} - -/* Reduce padding around the title area */ -#titlearea { - padding: 0.2em 0 !important; -} -#titlearea table { - margin: 0 !important; -} - -/* Reduce projectrow cell padding */ -#projectrow td { - padding: 0.2em 0.6em !important; - vertical-align: middle !important; -} - -/* Constrain logo height */ -#projectlogo img { - max-height: 90px; - width: auto; - display: block; -} - -/* Tighten project name & brief spacing */ -#projectname { - font-size: 1.6em; - line-height: 1.1em; - margin: 0 !important; -} -#projectbrief { - font-size: 0.9em; - line-height: 1.1em; - margin: 0 !important; -} diff --git a/include/argon/argument_parser.hpp b/include/argon/argument_parser.hpp index 6c1c90ff..c1548d4c 100644 --- a/include/argon/argument_parser.hpp +++ b/include/argon/argument_parser.hpp @@ -148,7 +148,7 @@ void add_default_argument(const default_argument, argument_parser&) noexcept; * This class provides methods to define positional and optional arguments, set parser options, * and parse the command-line input. * - * Example usage: + * ## Basic Usage: * @code{.cpp} * #include * @@ -175,7 +175,6 @@ void add_default_argument(const default_argument, argument_parser&) noexcept; * * return 0; * } - * @endcode */ class argument_parser { public: @@ -700,7 +699,6 @@ class argument_parser { * - For top-level parsers, this is the same as the parser's name. * - For subparsers, the name is prefixed with its parent parser names. * - * @example * Top-level parser: `git` * Subparser: `git submodule` * Nested subparser : `git submodule init` diff --git a/scripts/postprocess_doxyhtml.py b/scripts/postprocess_doxyhtml.py index a8eef7d8..cdea2d8b 100644 --- a/scripts/postprocess_doxyhtml.py +++ b/scripts/postprocess_doxyhtml.py @@ -1,17 +1,11 @@ import argparse import re +import json from pathlib import Path +from typing import Optional from bs4 import BeautifulSoup -IMAGE_STYLE_RULES = [ - { - "alt": "CPP-ARGON", - "style": "display: block; margin: 1.5em auto;" - } -] - - def encode_md_link(path_str: str) -> str: """ Encode a Markdown filepath according to Doxygen's rules: @@ -95,7 +89,9 @@ def remove_mainpage_title(content: str, filename: str) -> str: return str(soup) -def process_images(content: str, html_path: Path) -> str: +ImgRules = list[dict] + +def process_images(content: str, html_path: Path, rules: ImgRules) -> str: soup = BeautifulSoup(content, 'html.parser') for img in soup.find_all('img'): @@ -111,31 +107,39 @@ def process_images(content: str, html_path: Path) -> str: img['src'] = filename # Align the file path alt = img.get('alt', '') - for rule in IMAGE_STYLE_RULES: # Apply image style rules + for rule in rules: # Apply image style rules if ("filaneme" in rule and filename == rule["filename"]) or ("alt" in rule and alt == rule["alt"]): img['style'] = f"{img.get('style', '')}; {rule.get('style', '')}".strip('; ') return str(soup) -def process_file(f: Path): +def process_file(f: Path, img_rules: Optional[ImgRules] = None): content = f.read_text(encoding='utf-8') content = process_md_refs(content) content = process_gfm(content) content = process_heading_code_blocks(content) content = remove_mainpage_title(content, f.name) - content = process_images(content, f) + if img_rules: + content = process_images(content, f, img_rules) + f.write_text(content, encoding='utf-8') def main(): parser = argparse.ArgumentParser(description='Postprocess Doxygen HTML files to fix links.') parser.add_argument('directory', type=Path, help='Root directory of generated HTML files') + parser.add_argument('--img-rules', type=Path, help='Path to JSON file with image style rules') args = parser.parse_args() + img_rules = None + if args.img_rules: + with args.img_rules.open(encoding='utf-8') as f: + img_rules = json.load(f) + for f in args.directory.rglob('*.html'): - process_file(f) + process_file(f, img_rules) if __name__ == '__main__':