Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/format-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ jobs:
- uses: actions/checkout@v4
- name: Install clang-tidy and clang-format
run: sudo apt-get update && sudo apt-get install -y cmake clang
- name: Install Doxygen
run: sudo apt-get install -y doxygen
- name: Check if documentation is complete
run: doxygen Doxyfile
- name: Find C++ Packages, and then Format and Lint
run: |
for pkg in $(find . -name CMakeLists.txt -exec dirname {} \;); do
Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"iis.configDir": ""
}
4 changes: 2 additions & 2 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ WARN_IF_INCOMPLETE_DOC = YES
# WARN_IF_INCOMPLETE_DOC
# The default value is: NO.

WARN_NO_PARAMDOC = NO
WARN_NO_PARAMDOC = YES

# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, Doxygen will warn about
# undocumented enumeration values. If set to NO, Doxygen will accept
Expand Down Expand Up @@ -949,7 +949,7 @@ WARN_LAYOUT_FILE = YES
# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT.
# The default value is: NO.

WARN_AS_ERROR = NO
WARN_AS_ERROR = YES

# The WARN_FORMAT tag determines the format of the warning messages that Doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
Expand Down
39 changes: 34 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This template introduces a certain structure so that users and contributors can
└── usage/ # Examples and tutorials

All code is stored in `lib/` and organized into packages, either C++ or Python packages.\
All documentation, on the other hand, is stored in `docs/`. Documentation is a crucial aspect of this template. Using **Sphinx** with **Doxygen** via **Breathe**, code documentation is automated based on docstrings/comments and enriched with more info provided by the developers using **reStructuredText (reST)**. Together with GitHub Actions, this allows enforcement of consistent documentation practices across Python and C++ codebases. In this way:
All documentation, on the other hand, is stored in `docs/`. Documentation is a crucial aspect of this template. Using **Sphinx** with **Doxygen** via **Breathe**, code documentation is automated based on comments/docstrings and enriched with more info provided by the developers using **reStructuredText (reST)**. Together with GitHub Actions, this allows enforcement of consistent documentation practices across C++ and Python codebases. In this way:

* Documentation stays up-to-date with code changes.
* Documentation is organized and easily navigable.
Expand All @@ -28,9 +28,9 @@ All documentation, on the other hand, is stored in `docs/`. Documentation is a c
## Main Features

### Documentation Tools
- **Sphinx** — Primary tool for generating project documentation
- Supports both **reStructuredText (.rst)** and **Markdown (.md)** formats.
- **Sphinx** — Primary tool for generating project documentation
- Primarily uses reStructuredText, including its directives and extensions to produce documentation.
- Supports both **reStructuredText (.rst)** and **Markdown (.md)** formats.

- **Doxygen** — Specialized for C++ code documentation
- Produces **HTML output** for standalone C++ docs (found in `docs/doxygen/html`).
Expand All @@ -39,7 +39,7 @@ All documentation, on the other hand, is stored in `docs/`. Documentation is a c
### GitHub Actions
- **Formatting**: Automatic styling (ruff format for Python, clang-format for C++) before merging into main
- **Linting**: Automatic linting (ruff for Python, clang-tidy for C++) before merging into main
- **Documentation**: Automatic build and deployment to GitHub Pages after merging into main
- **Documentation**: Automatic build and deployment to GitHub Pages when updating main

## Before Using This Template
If you haven't done so already, check the following:
Expand All @@ -53,16 +53,45 @@ Do you think that's not enough? If not, then checking the following is highly re
- [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html)
- [Doxygen Documenting Code Guide](https://www.doxygen.nl/manual/docblocks.html)
- [Clang-Tidy](https://clang.llvm.org/extra/clang-tidy/index.html) and [Clang-Format](https://clang.llvm.org/docs/ClangFormat.html)
- [Ruff](https://docs.astral.sh/ruff/)
- [Ruff Formatter](https://docs.astral.sh/ruff/formatter/) and [Ruff Linter](https://docs.astral.sh/ruff/linter/)

## To Produce Documentation Locally:
Assuming you are in the root directory of this project and have a Python envioment to work with:
1. Install Python dependencies:
```bash
pip install -r requirements-docs.txt
```
2. Install Doxygen from [here](https://www.doxygen.nl/download.html).
3. Build your documentation
```bash
doxygen Doxyfile # If there are any C++ packages
sphinx-build -b html docs build/html
```

## Maintaining Your Code
When using this template, repository-level rulesets are NOT copied into the new repository. Project owners must configure these protections themselves in the repository settings.

Why protect main?
- Prevents direct pushes and accidental changes to main.
- Ensures CI (formatting, linting, testing, etc) runs and passes before code is merged.
- Keeps main stable for releases and documentation builds.

Template's Linting / formatting behavior
- The template’s GitHub Actions jobs for formatting and linting are intended to run on pull requests.
- Only merge into main after the required status checks pass on the PR.

Recommended minimal branch-protection rule (GitHub: Settings → Branches → Add branch ruleset) on the main branch:
- Restrict deletions
- Require a pull request before merging
- Require review from Code Owners
- Require conversation resolution before merging
- Require status checks to pass (select cpp-format-lint and python-format-lint)
- Require branches to be up to date before merging
- Do not require status checks on creation
- Block force pushes
- Optionally enable: include administrators, require linear history

At minimum, create a rule that enforces updates to main only via pull requests with passing status checks.

## License
This template is licensed under the terms in `LICENSE`.
59 changes: 31 additions & 28 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ All of our documentation is stored and handled in `docs/`. The directory tree be
├─ example.md # Example of using a feature or some features from a package
└─ ...

Each directory contains an `index.rst` file, which serves as an entry point. In each index file, we can reference index files from subdirectories. In this way, it is possible to create pages and subpages in order to make a structured and organized documentation web page. The main `index.rst` is located in the source directory of the documentation setup. We can also use Markdown within reStructuredText. This allows some specific documentation intended for display on GitHub to be included in the main documentation. `conf.py` is the central configuration file that defines how the documentation is built and styled. It sets project details, enables extensions, chooses the theme, and controls paths and output formats. Essentially, it's the settings file that tells **Sphinx** what to include and how to present it.
Each directory contains an `index.rst` file (**reStructuredText (reSET)** file), which serves as an entry point. In each index file, we can reference index files from subdirectories. In this way, it is possible to create pages and subpages in order to make a structured and organized documentation web page. The main `index.rst` is located in the source directory of the documentation setup. We can also use Markdown within reStructuredText. This allows some specific documentation intended for display on GitHub to be included in the main documentation. `conf.py` is the central configuration file that defines how the documentation is built and styled. It sets project details, enables extensions, chooses the theme, and controls paths and output formats. Essentially, it's the settings file that tells **Sphinx** what to include and how to present it.

### Main Entry Point

Expand All @@ -44,10 +44,10 @@ This is the landing section of the project with an overview. A good overview bri

Here, an overall architecture is presented. If this project delivers a certain solution, this section should explain what this solution entails. Diagrams (generated by Mermaid) are used to visually explain the architecture. This section contains the following:

* A diagram with an explanation of the overall architecture and the high-level components.
* Info about how these components interact.
* (Recommended Optional) Additional diagrams with detailed explanations of the components.
* (Optional) A list of constraints and trade-offs.
* A diagram with an explanation of the overall architecture and the high-level components
* Info about how these components interact
* (Recommended Optional) Additional diagrams with detailed explanations of the components
* (Optional) A list of constraints and trade-offs

Example Mermaid snippet (in an `.rst` or `.md` doc):
```mermaid
Expand All @@ -58,15 +58,14 @@ graph LR
```

Note that each component should have its own documentation page(s) describing its role, responsibility, use, configuration, and diagrams where useful. More details can be added if necessary.
Here’s your original text with **only grammatical corrections**, keeping all content intact:


### Code Documentation
----------------------
Code documentation primarily depends on docstrings/comments written in the code. For you as a developer, if you are writing code in:
Code documentation primarily depends on comments/docstrings written in the code. For you as a developer, if you are writing code in:

- **C++**: Use Doxygen-style comments (check Doxygen's Documenting the Code Guide); **Doxygen** produces XML-based documentation, which is used by **Breathe** to integrate into **Sphinx**. **Breathe**-specific directives are used (e.g., `doxygenclass`) to achieve this integration.
- **Python**: Use NumPy-style docstrings (check numpydoc's Style Guide). **Sphinx** extensions (e.g., `automodule`) are used to pull documentation from docstrings.
- **C++**: Use Doxygen-style comments (check [Doxygen Documenting Code Guide](https://www.doxygen.nl/manual/docblocks.html)); **Doxygen** produces XML-based documentation, which is used by **Breathe** to integrate into **Sphinx**. **Breathe**-specific directives are used (e.g., `doxygenclass`) to achieve this integration.
- **Python**: Use NumPy-style docstrings (check [NumPy Style Guide](https://numpydoc.readthedocs.io/en/latest/format.html)). **Sphinx** extensions (e.g., `automodule`) are used to pull documentation from docstrings.

A C++ example from `math_utils.hpp`:

Expand Down Expand Up @@ -98,9 +97,22 @@ def square(x):
return x * x
```

**Sphinx** uses **reStructuredText (reST)** as its markup language to generate structured documentation. Therefore, our documentation should technically be stored in `.rst` files. In these files, we declare the **directives** and **extensions**.
**Sphinx** uses **reStructuredText (reST)** as its markup language to generate structured documentation. Therefore, our documentation should technically be defined in `.rst` files. In these files, we declare the **directives** and **extensions**.

Directives are special instructions in reST that tell **Sphinx** how to include and format content. An extension is a Python module that provides additional features for **Sphinx** projects. For example, to use **Sphinx** on Python code, the `autodoc` extension is often used to automatically pull in docstrings from the source code:
Directives are special instructions in reST that tell **Sphinx** how to include and format content. An extension is a Python module that provides additional features for **Sphinx** projects.

For example, to use **Sphinx** on C++ code, `autodoc` cannot be used, since it is made for Python. But we can use **Breathe**’s set of directives. They may not be as powerful as `autodoc`, but are still useful in our use case.

```rst
Math Utilities
--------------

.. doxygenclass:: math_utils::Calculator
:project: cpp_pkg
:members:
```

To use **Sphinx** on Python code, the `autodoc` extension is often used to automatically pull in docstrings from the source code:

```rst
.. automodule:: py_pkg.math_utils
Expand All @@ -111,16 +123,7 @@ Directives are special instructions in reST that tell **Sphinx** how to include

This directive tells **Sphinx** to document the `math_utils` module, including all its members—even those without docstrings—and to show class inheritance.

To use **Sphinx** on C++ code, `autodoc` cannot be used, since it is made for Python. But we can use **Breathe**’s set of directives. They may not be as powerful as `autodoc`, but are still useful in our use case.

```rst
Math Utilities
--------------

.. doxygenclass:: math_utils::Calculator
:project: cpp_pkg
:members:
```

All this is nice, but writing docstrings/comments alone and using directives and extensions is not sufficient for proper documentation. While some of them are powerful in automatically extracting and displaying documentation from source code, they work best when combined with additional narrative content written in reStructuredText. Writing introductions, explanations, usage examples, and conceptual overviews alongside directives and extensions helps provide context, guide the reader, and make the documentation more accessible and educational. This blend of auto-generated and hand-written content results in a more complete and user-friendly documentation experience. Here is an example of how you can enrich the documentation:

Expand All @@ -146,20 +149,20 @@ Remember that the file structure in documentation is package-based, i.e., each p
In order to quickly start working with the project and provide value for users, a set of examples must be provided. Each example should ideally include an explanation of a use case, a demonstration, and output explanation. The examples should highlight the main features of your solution and explain the usage in a user-friendly way. This may also provide some guidance on how to develop a user-friendly solution.

## Documentation Workflow
1. Document your code using the appropriate style (NumPy for Python, Doxygen for C++).
2. Create a reST file in `/docs/documentation/` with the package name you want to document.

- **For a Python package**:
**Sphinx** can access your Python packages. Therefore, there is no need for any additional configuration.
1. Document your code using the appropriate style (Doxygen for C++, NumPy for Python).
2. Create a reST file in `/docs/code/` with the package name you want to document. (The current template has two code documentation subdirectories, one for C++ packages, the other for Python packages)

- **For a C++ package**:
Since **Sphinx** relies on **Doxygen** to get the documentation, it is required to specify the files and/or directories that contain documented source files in **Doxyfile**. Find the key `INPUT`in **Doxyfile**, and add the appropriate paths.

3. Add any necessary directives, extensions, and content enrichments. See an example here: [cpp_pkg.rst](/docs/code/cpp_pkgs/cpp_pkg.rst)
4. (Optional) Build docs locally and check them in `/build/html` before pushing:
- **For a Python package**:
**Sphinx** can access your Python packages based on the paths you specify in `conf.py`.

3. Add any necessary directives, extensions, and content enrichments. See an example here: [cpp_pkg.rst](/docs/code/cpp_pkgs/cpp_pkg.rst).
4. (Recommended optional) Build docs locally and check them in `/build/html` before pushing:
```bash
doxygen Doxyfile # If there are any C++ packages
sphinx-build -b html docs build/html
```
5. Push changes – GitHub Actions will automatically:
- Build and deploy documentation when successfully merging into main
- Build and deploy documentation when successfully merging into main.
40 changes: 0 additions & 40 deletions docs/doxygen/html/doxygen_crawl.html
Original file line number Diff line number Diff line change
@@ -1,40 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<title>Validator / crawler helper</title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.14.0"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
</head>
<body>
<a href="annotated.html"/>
<a href="classes.html"/>
<a href="classmath__utils_1_1_calculator-members.html"/>
<a href="classmath__utils_1_1_calculator.html"/>
<a href="classmath__utils_1_1_calculator.html#a1ac410555bdef0e7d1d6856eb65a8623"/>
<a href="classmath__utils_1_1_calculator.html#a4761e091532dd7b2b3aa5b05d462e745"/>
<a href="classmath__utils_1_1_calculator.html#a9d94459903e96e34ed80b3267e55da27"/>
<a href="classmath__utils_1_1_calculator.html#abc237c0b76a0bcb0361bfe201b728465"/>
<a href="classstring__utils_1_1_formatter-members.html"/>
<a href="classstring__utils_1_1_formatter.html"/>
<a href="classstring__utils_1_1_formatter.html#a72c83ffa1f6f2564f47f70137d215d56"/>
<a href="dir_5994212e0c7b0ba1796e56179c2444a2.html"/>
<a href="dir_93e8756b682c3e239c9cbf8e72d3aa62.html"/>
<a href="dir_97aefd0d527b934f1d99a682da8fe6a9.html"/>
<a href="dir_abbbdf32378d28d1c3aa8a91b3abe1c0.html"/>
<a href="doxygen_crawl.html"/>
<a href="files.html"/>
<a href="functions.html"/>
<a href="functions_func.html"/>
<a href="index.html"/>
<a href="math__utils_8hpp.html"/>
<a href="math__utils_8hpp.html#a5a6ea77164a9ce3c89c66f186228bf08"/>
<a href="math__utils_8hpp.html#ab77ed9bc6a5263c1912751341b1d96f9"/>
<a href="math__utils_8hpp_source.html"/>
<a href="string__utils_8hpp.html"/>
<a href="string__utils_8hpp.html#a5156a6427c72b2e7ab96d986f346d9db"/>
<a href="string__utils_8hpp.html#a846b06166c7acbde7cf9e2a457f628e3"/>
<a href="string__utils_8hpp_source.html"/>
</body>
</html>
Loading