# dirtreex A self-contained LaTeX package for rendering directory trees inside an optionally breakable, fully styleable frame. Built directly on TikZ and `zref` — no `tcolorbox` or classic `dirtree` underneath. ## Features - **Auto-tracked depth.** Nest `\dir`, `\file`, and `\archive` as deeply as you want; the package derives the depth from the nesting — no per-entry depth argument. - **Sharp or rounded elbows**, configurable per tree or per entry via a single `elbow radius` key (`0pt` = sharp, any positive length = rounded arc). - **Per-entry overrides** for icons, line colour, line width, line style, and elbow radius. - **Breakable frame.** The border, background fill, and every pending `│` column continue seamlessly across page boundaries. - **CJK-friendly.** Works out of the box with `ctex` + LuaLaTeX. - **Zero shell-escape, no external tools, no Python helpers.** --- ## Table of contents 1. [Requirements](#1-requirements) 2. [Installation](#2-installation) 3. [Quick start](#3-quick-start) 4. [Entries: `\dir`, `\file`, and `\archive`](#4-entries-dir-file-and-archive) 5. [Verbatim names: `\verbdir`, `\verbfile`, and `\verbarchive`](#5-verbatim-names-verbdir-verbfile-and-verbarchive) 6. [Environment options](#6-environment-options) - 6.1 [Top-level keys](#61-top-level-keys) - 6.2 [The `box` family](#62-the-box-family) - 6.3 [The `pagebreak` family](#63-the-pagebreak-family) - 6.4 [Per-entry overrides](#64-per-entry-overrides) 7. [Cross-page behaviour](#7-cross-page-behaviour) 8. [Example gallery](#8-example-gallery) 9. [Compilation](#9-compilation) 10. [Troubleshooting](#10-troubleshooting) 11. [Limitations](#11-limitations) 12. [Project files](#12-project-files) 13. [Contact](#13-contact) 14. [License](#14-license) --- ## 1. Requirements | Component | Notes | | :--- | :--- | | LuaLaTeX, pdfLaTeX or XeLaTeX | For CJK, use a suitable font setup, such as `ctex` with LuaLaTeX. | | e-TeX extensions (`\numexpr`, `\dimexpr`, `\ifcsname`) | Present in every modern TeX engine (pdfTeX, XeTeX, LuaTeX) and guaranteed by the package's format requirement (`LaTeX2e` `2020/10/01` or later). | | TikZ 3.x | The `backgrounds` library is loaded automatically. | | `xcolor` | Use colour names or expressions such as `blue!50!black`. Define HTML colours first, for example `\definecolor{accent}{HTML}{336699}`. | | `pgfkeys` | Option parsing. | | `zref-abspage` | Absolute page tracking; PGF positions distinguish standard two-column output. | | Document commands (LaTeX kernel) | `\NewDocumentEnvironment` / `\NewDocumentCommand`, plus the `v` (verbatim) argument type used by `\verbdir` / `\verbfile` / `\verbarchive`. | No `-shell-escape`, no external tools, no Python helper. --- ## 2. Installation 1. Copy `dirtreex.sty` into the same directory as your document, **or** install it under `texmf-local/tex/latex/dirtreex/` and run `mktexlsr` (TeX Live) / the MiKTeX equivalent. 2. In your preamble: ```latex \usepackage{dirtreex} ``` --- ## 3. Quick start The smallest possible document: ```latex \documentclass{article} \usepackage{dirtreex} \begin{document} \begin{dirtreex} \dir{project}{root}{ \dir{src}{source}{ \file{main.py}{entry point} \file{util.py}{helpers} } \file{README.md}{documentation} } \end{dirtreex} \end{document} ``` This produces a framed tree where each line is ` … ` joined with a dot-leader, directory names receive a trailing `/`, and the elbow connectors (`├`, `└`, `│`) are laid out automatically. --- ## 4. Entries: `\dir`, `\file`, and `\archive` ```latex \dir []{}{}{} \file []{}{} \archive[]{}{}{} ``` - **``** is typeset in `\ttfamily`. For `\dir`, a trailing `/` is appended automatically — write `src`, not `src/`. `\file` and `\archive` render the name as-is. - **``** is typeset in `\rmfamily` and joined to `` with a dot leader. Pass `{}` for no comment (the dot leader also disappears). - **``** is a run of further `\dir` / `\file` / `\archive` calls. `\file` has no children block. You do **not** supply the depth — the package tracks it from the nesting. - **``** are optional and described in §6.4. `\archive` is a container entry: it accepts a children block, so its contents indent and connect inside the tree, and its name is rendered as-is (no path separator appended). Use it for archive-like containers (`.tar.gz`, `.zip`, `.jar`, …) or for any container whose name should not carry a trailing `/`. Set `icon={...}` (§6.4) to choose an icon for an individual entry. For automatic formatting by entry type, override `\DirtreexFormatName` (§4.4) and dispatch on the entry's `t` slot. ### 4.1 Multi-line comments A comment may contain line breaks; the whole block is packed so its combined height stays rectangular, keeping the connector column straight: ```latex \file[line color=purple]{Makefile}{ build script\\ (multi-line comment, stays aligned) } ``` ### 4.2 Empty subtrees and empty comments Both are legal: ```latex \dir{empty-dir}{}{} % no comment, no children \dir{has-comment}{with comment}{} % comment but no children ``` ### 4.3 Multiple trees on one page Simply place several `dirtreex` environments back-to-back. Each environment has its own `zref` namespace, so their cross-page bookkeeping never collides. ### 4.4 Customising entry-name typesetting (`\DirtreexFormatName`) `\DirtreexFormatName` is a public hook that controls how each entry name is typeset. The default formatter prints the optional icon with a nonbreaking `0.5em` gap, then the stored name plus a trailing `/` for directories. An omitted or empty `icon={}` adds no prefix or gap. Override it with `\renewcommand` to inject icons, prefixes, or styling. The hook receives the 1-based entry index as `#1`, and `\DirtreexGetField{idx}{slot}` reads any stored field for that index: - `\DirtreexGetField{#1}{n}` — the entry name (the first mandatory argument of `\dir` / `\file` / `\archive`). - `\DirtreexGetField{#1}{t}` — `1` for directories, `0` for files, `2` for archives. - `\DirtreexGetField{#1}{i}` — the raw icon code, empty when omitted; the name field stays unchanged. A replacement hook controls the entire name, including icon rendering. Save and call the original formatter to retain its icon handling, gap, and directory slash when adding your own decoration. **Example — tag every directory with a `[DIR]` prefix while keeping the default formatter:** ```latex \let\OriginalDirtreexFormatName\DirtreexFormatName \renewcommand{\DirtreexFormatName}[1]{% \ifnum\DirtreexGetField{#1}{t}=1 [DIR]\fi \OriginalDirtreexFormatName{#1}% } ``` **Example — three-way icon dispatch on `t`:** ```latex \renewcommand{\DirtreexFormatName}[1]{% \ifcase\DirtreexGetField{#1}{t}% [F]\space\DirtreexGetField{#1}{n}% % t=0 file \or [D]\space\DirtreexGetField{#1}{n}/% % t=1 directory \or [A]\space\DirtreexGetField{#1}{n}% % t=2 archive \fi } ``` Swap the bracketed tags for icons from your icon package of choice (`\faFolder`, `\faFile`, `\faFileArchive`, …) to get the same dispatch with glyphs. **Constraints.** The replacement runs inside the row's name vbox under the body's font. It must respect the row's `\hsize` and leave the caller's `\strut` intact; anything that adds vertical material (for example a `\parbox` with its own depth) will pull the entry's connector out of alignment. **Stability.** `\DirtreexFormatName`'s single-argument convention and the `\DirtreexGetField` accessors for `n` (entry name), `t` (type flag), and `i` (icon code) are committed public surfaces — overrides built around them keep compiling across minor versions. Other slot keys exist internally but are not part of the public surface and may change. --- ## 5. Verbatim names: `\verbdir`, `\verbfile`, and `\verbarchive` `\dir`, `\file`, and `\archive` accept LaTeX-tokenised name arguments — paths containing `_`, `$`, `&`, `#`, `^`, `~`, `%`, or `\` need to be escaped (`\_`, `\$`, etc.) or wrapped in `\detokenize{}`. For paths where this is inconvenient, `dirtreex` provides three verbatim variants: ```latex \verbdir []||{}{} \verbfile []||{} \verbarchive[]||{}{} ``` Each verbatim variant pairs with the same-shape regular command: `\verbdir` mirrors `\dir` (children block, trailing `/`), `\verbfile` mirrors `\file` (no children), and `\verbarchive` mirrors `\archive` (children block, no trailing `/`). The path uses the LaTeX kernel's `v` (verbatim) argument type. It accepts two matching delimiters other than `%`, `\`, `#`, braces or a space, or a braced form such as `\verbfile{path.txt}{comment}`. ASCII letters retain their category; the usual special characters become literal characters, while spaces and tabs remain active tokens. Non-ASCII character categories depend on the engine: active in 8-bit engines, letter or other in Unicode engines. Comment and children retain full LaTeX catcodes — you can still write `$x^2$`, `\textbf{...}` and `\\` inside the comment, and nested `\dir` / `\file` / `\archive` / `\verbdir` / `\verbfile` / `\verbarchive` inside the children block work normally. ### 5.1 Example ```latex \begin{dirtreex} \verbdir|src/$ENV/data_v2|{environment-keyed data root}{% \verbfile|users_2026-01.parquet|{snapshot}% \verbfile|conf{prod}.yaml|{production config}% } \end{dirtreex} ``` ### 5.2 Restrictions - **The chosen delimiter cannot appear inside the path.** Pick one that doesn't collide: ```latex \verbfile|a/b|{...} % | as delimiter \verbfile+a|b+{...} % + as delimiter, | survives in the path \verbfile/a|b+c/{...} % / as delimiter, | and + survive ``` **Delimiter collisions corrupt SILENTLY.** Writing `\verbfile|foo|bar|{c}` makes the verbatim scanner take `|foo|` as the name and `b` as the comment, leaving `ar|{c}` as stray tokens — no error fires. Pick a delimiter that does not appear in any of your paths. - **The verbatim argument must be readable directly from source.** If you wrap `\verbfile|...|` inside another macro that captures its argument as a token list (e.g., a user-side `\NewDocumentCommand` with an `m` or `+m` argument), the path is tokenised at the wrapper's call site — before `\verbfile` can re-catcode it — and the verbatim semantics are lost. The children block of `\dir` and `\verbdir` does **not** suffer from this: it is a live TeX group, not a captured token list, so `\verbfile|...|` written inside `\dir{...}{...}{ ... }` works as expected. - **Encoding.** Under T1 / TU encoding (LuaLaTeX default, or pdfLaTeX with `\usepackage[T1]{fontenc}`), every cat-12 character renders as its literal glyph in monospace. If you target legacy OT1 encoding, the special characters `_` and `&` may require explicit `\char` mapping — pick an encoding that supports them. ### 5.3 Where verbatim names are useful - Paths with parameter substitutions (`$ENV`, `${VAR}`). - Windows paths (`C:\Users\foo`). - Configuration filenames (`conf{prod}.yaml`, `app_$STAGE.toml`). - Database identifiers (`schema$ext.table_v2`). - Log file patterns (`err_$.log`, `out_%Y-%m-%d.log`). --- ## 6. Environment options Options go inside `[...]` on `\begin{dirtreex}` and are parsed with `pgfkeys`. Spaces around `=` are allowed. ### 6.1 Top-level keys | Key | Default | Meaning | | :--- | :--- | :--- | | `fontsize` | `\small` | Size command applied to the tree body. Use any length-free size macro: `\tiny`, `\small`, `\normalsize`, …, `\Large`. | | `dotfill color` | inherited | Colour of the leader between an entry name and its comment. Accepts an `xcolor` expression; inherits the current text colour when omitted. | | `dotfill command` | `\dotfill` | TeX code that fills the gap before a comment. Use `\hrulefill` for a solid rule, `\hfill` for a blank gap, or a custom leader with `\hfill` stretch. | | `line color` | `black` | Default colour for connectors and cross-page extensions. Accepts any `xcolor` expression. | | `line width` | `0.4pt` | Default rule width for all connectors. | | `line style` | `solid` | Dash pattern for every connector segment styled by this entry. Accepts any TikZ line-style token — `solid`, `dashed`, `dotted`, `densely dashed`, `loosely dashed`, `densely dotted`, `loosely dotted`, `dash dot`, `dash dot dot`, … — or a comma-separated TikZ option list such as `dash pattern={on 3pt off 2pt},dash phase=1pt`. `solid` keeps the primitive `\vrule` fast path; any other value routes that segment through TikZ. Propagates to the entry's own elbow, the upper-half of its own-depth pass-through column, and (for the next sibling at each active depth) the lower-half pass-through and full pure-pass-through trunks, plus the matching cross-page extension rules. | | `elbow radius` | `0pt` | Elbow geometry. `0pt` (the default) gives sharp `└`/`├` right angles; any positive length gives rounded arcs of that radius. Clamped against `0.5\baselineskip` and the horizontal connector arm length for legibility. | | `box` | see §6.2 | Frame settings. | | `pagebreak` | see §6.3 | Page-break settings. | Enclose comma-separated `line style` options in braces. A macro may supply the list; conditional selection of key–value lists must finish before returning the selected keys. The stored keys are applied in normal TikZ order; per-entry styles retain capture-time expansion. The dotfill options apply to all nonempty comments in that environment. The leader's colour and any declarations in its command are local to the leader; names and comments retain their own formatting. Explicit `\\` continuations keep their right alignment, with a leader only before the first line. ```latex \begin{dirtreex}[dotfill color=blue!60!black, dotfill command=\hrulefill] \dir{project}{root}{ \file{main.py}{entry point} \file{LICENSE}{} } \end{dirtreex} ``` Custom leader commands are evaluated in the tree's font at rendering time. Use `\hfill` stretch to preserve comment alignment, and keep the leader within the normal text height. See the comment-leader section of `dirtreex_examples.tex` for a custom dashed pattern. ### 6.2 The `box` family Pass as a sub-list: `box = { … }`. | Subkey | Default | Meaning | | :--- | :--- | :--- | | `true` / `false` | `true` | Draw the frame at all. `box=false` leaves the tree bare. | | `corners` | `0pt` | Corner radius. A single value applies to all four corners; a four-value list is TL, TR, BR, BL. | | `border color` | `black` | | | `border width` | `0.4pt` | | | `background color` | `white` | Colour name or `xcolor` expression; define HTML colours first (see §1). | | `margin` | `6pt` | Padding between the border and the tree content. Single value = uniform; a four-value list is T, R, B, L (asymmetric padding is supported in both single and breakable output). | Example: ```latex \begin{dirtreex}[ box = { true, corners = 6pt, border color = purple, border width = 1pt, background color = purple!5, margin = {2pt, 20pt, 10pt, 4pt} } ] ``` ### 6.3 The `pagebreak` family | Subkey | Default | Meaning | | :--- | :--- | :--- | | `true` / `false` | `true` | Allow the frame to break across pages. When `false`, tall trees spill past the page; they are **not** truncated. | | `box break at` | `0pt` | Vertical gap between the frame's torn edge and the page boundary. Single value applies to both sides of every break; two values = `first-piece-bottom, next-piece-top`. | | `tree break at` | `1em` (`0pt` when `box=false`) | Same, but applied to the tree's extension rules rather than to the border itself. Useful when the frame should reach the page edge while the internal tree lines pull back. | ### 6.4 Per-entry overrides All six entry commands accept `icon={...}` to print inline TeX content before that entry's name using the default name formatter. Icons are specific to each entry: children and siblings start without an icon. The code is stored unexpanded and rendered in a local horizontal box, so ordinary font and colour declarations affect only the icon. A nonbreaking `0.5em` gap follows a nonempty icon; omitting the option or using `icon={}` adds no gap. ```latex \begin{dirtreex} \verbdir[icon={[D]}]|src_code|{sources}{ \verbfile[icon={\textcolor{blue}{[F]}}]|main_app.py|{entry point} \file{LICENSE}{} } \end{dirtreex} ``` Use a glyph command or a text-sized `\includegraphics` for an image icon. Keep its height and depth within the normal text row to preserve baseline and frame alignment; standard `\raisebox` can adjust its vertical position. The item-icon section in `dirtreex_examples.tex` shows images scaled to `0.9em` high and lowered by `0.15em`. Custom `\DirtreexFormatName` hooks control whether and how the icon is rendered (§4.4). Any `\dir`, `\file`, `\archive` (or their verbatim siblings `\verbdir` / `\verbfile` / `\verbarchive`) can take the same `line color`, `line width`, `line style`, and `elbow radius` keys. They override the environment-level defaults **for connector segments owned by that entry**: ```latex \dir[line color = blue]{src}{source}{ \file[line color = red, line width = 1.5pt]{old.py}{deprecated} \file[line color = green!60!black, elbow radius = 0pt]{new.py}{sharp} \archive{vendor.zip}{bundled}{ \file[line style = dashed]{numpy.py}{} \file[line style = dashed]{pandas.py}{} } } ``` Each entry owns its own `└`-shape. The vertical line continuing **down** from that entry's arm toward the next sibling carries the **next sibling's** colour — so two siblings with different colours share a column that changes colour at arm level (sharp) or at arc-top (rounded). --- ## 7. Cross-page behaviour When a tree needs splitting, `dirtreex` emits pieces on consecutive pages or standard LaTeX columns, accounting for current float reservations and rendered frame dimensions. Each piece contains a TikZ content node, with its frame and active `│` columns drawn around it. Bare trees use the same splitting machinery without a frame. The initial pass records absolute page numbers via `zref-abspage` and, in standard two-column mode, horizontal row origins via PGF. Later passes use these locations to distinguish a predecessor on the same piece from one across a page or column break. Recompile until the auxiliary files settle; the isolated regression cases settle within two passes, and the gallery with its table of contents within three. Concretely: - Every piece after the first starts with a `0.5\baselineskip` leader of empty space, so the first visible entry shows a `│` above its elbow matching the inter-sibling spacing used on a single page. - Bottom extensions of every active column continue down to the first piece's bottom edge. - Top extensions re-appear in the second (and any subsequent) piece, matching the column colours and widths the previous piece ended with. - The closing piece retains the configured content width. If first-piece fitting consumes the entire tree, it produces a complete tree without an empty trailing closing piece. --- ## 8. Example gallery The snippets below are self-contained: drop any of them into a document with `\usepackage{dirtreex}` and they compile. For more worked examples of the supported options, see `dirtreex_examples.tex` in the repository root. ### 8.1 Defaults ```latex \begin{dirtreex} \dir{project}{default settings}{ \file{a.txt}{file A} \file{b.txt}{file B} \dir{sub}{subdirectory}{ \file{c.txt}{file C} } } \end{dirtreex} ``` ### 8.2 Rounded elbows ```latex \begin{dirtreex}[elbow radius = 3pt] \dir{round3}{rounded 3pt}{ \file{a.txt}{} \dir{sub1}{subdir 1}{ \file{b.txt}{} \dir{sub2}{subdir 2}{\file{c.txt}{}} } \file{d.txt}{} } \end{dirtreex} ``` ### 8.3 Per-branch colours ```latex \begin{dirtreex}[ elbow radius = 3pt, box = { true, border color = black, background color = white, margin = 6pt }] \dir{project}{}{ \dir[line color = blue]{src}{blue: source code}{ \file[line color = red]{old.py}{red: deprecated} \file[line color = green!60!black]{new.py}{green: new} } \dir[line color = orange]{docs}{orange: documentation}{ \file{api.md}{} } \file[line color = purple]{Makefile}{purple} } \end{dirtreex} ``` ### 8.4 Thick lines ```latex \begin{dirtreex}[ line color = red!70!black, line width = 1pt, box = { true, border color = red!80!black, border width = 2pt, background color = red!5 }] \dir{bold}{thick-line test}{ \file{a.txt}{} \dir{sub}{}{\file{b.txt}{}} } \end{dirtreex} ``` ### 8.5 A tree that pages across ```latex \begin{dirtreex}[ elbow radius = 3pt, box = { true, border color = black, background color = white, margin = 6pt }] \dir{cross-page}{long tree}{ \dir[line color = red]{red-branch}{}{ \file{r1.txt}{} % ... add enough files to overflow } \dir[line color = blue]{blue-branch}{}{\file{b1.txt}{}} } \end{dirtreex} ``` The border, background, and all active `│` columns continue onto the next page; the first visible entry on that page shows a full `│` stem above its elbow. Colours are carried across the page break seamlessly. ### 8.6 Asymmetric margin ```latex \begin{dirtreex}[ box = {margin = {2pt, 20pt, 10pt, 4pt}, % T, R, B, L border color = teal, background color = teal!5}] \dir{root}{}{ \file{a}{} \file{b}{} } \end{dirtreex} ``` --- ## 9. Compilation ```bash lualatex -interaction=nonstopmode yourdoc.tex lualatex -interaction=nonstopmode yourdoc.tex # 2nd pass for zref ``` - The first pass records absolute pages and any required column positions. - Subsequent passes read those locations to choose connector anchors and cross-break extensions. For a fresh document, start with two passes and rerun if labels or the table of contents still change. The gallery requires three passes. A document with unchanged, settled auxiliary files generally needs only one. The package emits `Package dirtreex Warning: Rerun LaTeX...` at `\end{document}` when required page or column data is missing. This is a rerun request, not a complete auxiliary-stability check; also heed LaTeX's changed-label warnings or use `latexmk`. --- ## 10. Troubleshooting | Symptom | Likely cause | Fix | | :--- | :--- | :--- | | First entry on a continuation page has no `│` above its elbow | Only one compile pass has run so far | Run LaTeX again. The `Rerun LaTeX...` warning at `\end{document}` is already asking you to. | | Vertical columns stop halfway down the last piece | Same cause — `zref` has not seen the break yet | Run LaTeX again. | | CJK characters render as `□` or are missing | Missing glyphs or font setup | Use a suitable Unicode engine and fonts, for example LuaLaTeX with `ctex`. | | `! Package dirtreex Error: \dir used outside dirtreex environment` (same for `\file`, `\archive`, and their verbatim siblings) | A stray entry command that is not inside `\begin{dirtreex}…\end{dirtreex}` | Wrap the call in a `dirtreex` environment. | | `! Package dirtreex Error: parsefour expects 1 or 4 comma-separated values` (or `parsetwo expects 1 or 2 …`) | `corners`, `margin`, `box break at`, or `tree break at` given with the wrong arity | Pass either a single value or the full set (four for `corners`/`margin`, two for the break-at keys). Remember the enclosing braces: `margin = {2pt, 4pt, 6pt, 8pt}`, not `margin = 2pt, 4pt, 6pt, 8pt`. | | `Package dirtreex Warning: \dte@findanchor hit the recursion floor at entry N` (once per env) | The tree's first top-level entry has depth > 0, or an outer `\begingroup` shadowed `\dte@depth` and produced an inverted depth sequence | Ensure the env body starts with a depth-0 `\dir` / `\file` / `\archive` (or `\verbdir` / `\verbfile` / `\verbarchive`). The connector for the affected entry is snapped to a cross-page-stub variant as a graceful fallback, so the build still succeeds — the warning is purely diagnostic. | --- ## 11. Limitations - Nested directory/archive entries are supported; nested `dirtreex` environments and entry constructors invoked from rendering hooks are unsupported. Keep entry capture in the environment body. - Pagination assumes standard LaTeX page/column and float accounting. Arbitrary replacement output routines or balancing-column packages are not qualified. - Entry formatting runs once per entry, but picture hooks can run during rejected fitting trials. Keep their global or immediate side effects in mind; grouping cannot roll them back. - A row or frame padding too large for any column can still produce a finite overflow diagnostic. Repeated unconsumed deferral stops at the twentieth attempt; reduce recurring paragraph/header material or clear pending floats. - Extremely small `box.margin` combined with a very large `elbow radius` crowds the corner; the internal clamp (`connE ≤ 0.5\baselineskip`) keeps things legible but will not rescue pathological values. - No built-in numbering or hyperlinks. Use `icon={...}` (§6.4) for per-entry icons and the `\DirtreexFormatName` hook (§4.4) for custom name formatting; wrap the tree in a `minipage` if you need decoration around the whole frame. --- ## 12. Project files | Path | What it is | | :--- | :--- | | `dirtreex.sty` | The package — a single self-contained file. | | `dirtreex_examples.tex` | Worked examples covering the full feature surface. Compile with `lualatex dirtreex_examples.tex` three times to settle tree locations and the table of contents. | | `assets/` | PNG glyphs (`directory.png`, `python.png`, `zip_file.png`) used by the icon examples in `dirtreex_examples.tex`. | | `tests/` | Three-engine development tests on GitHub; see [test instructions](https://github.com/CloudCauldron/dirtreex/blob/main/tests/README.md) and [coverage](https://github.com/CloudCauldron/dirtreex/blob/main/tests/COVERAGE.md). | | `README.md` | This documentation. | | `LICENSE` | The LaTeX Project Public License 1.3c. | --- ## 13. Contact - **Maintainer:** CloudCauldron - **Email:** - **Repository / issues:** Bug reports, feature suggestions, and patches are welcome via either channel. --- ## 14. License Released under the [LaTeX Project Public License, version 1.3c](https://www.latex-project.org/lppl.txt) (`LPPL-1.3c`); see [`LICENSE`](LICENSE) for the full text. Maintenance status is `author-maintained`; the Current Maintainer is CloudCauldron (). --- ## 15. About the Development This project includes code generated with the assistance of AI tools. All such code has been reviewed and integrated by the maintainer.