trbldoc
A really awful documentation generator.
Trbldoc scans source files for comments, extracts them as content chunks, passes each chunk through a renderer, groups the results by namespace, and assembles an HTML site.
Dependencies
| Tool | Purpose |
|---|---|
Any POSIX shell (ash, dash, sh, bash, ...) |
Runtime |
awk, sed (with -E), grep, find, mktemp, xargs |
Standard Unix tools |
That's it. Really. Runs under busybox systems, no GNU required!
Installation
Drop trbldoc.sh into your $PATH and mark it executable:
sudo cp trbldoc.sh /usr/local/bin/trbldoc
sudo chmod +x /usr/local/bin/trbldoc
Usage
trbldoc [-s <source1> -s <source2> ...] [-o <dest>] [-l <layout>] [-f ext;start;end] [-R prefix=script;opts] [-C] [source ...]
-s <source>- Add a folder or file to scan. Repeatable.-o <dest>- Output directory (default:.trblcache/built).-l <layout>- Use an alternativemain.layouttemplate file instead of the built-in default.-f ext;start;end- Register a custom file extension with AWK-regex delimiters.-R prefix=script;opts- Set a resolver used for@prefix/...reference tags.-C- Force a clean rebuild — wipes cached chunks and timestamps before scanning.
Environment variables
trbldoc allows you to use some environment variables to provide more information
while rendering.
| Variable | Description |
|---|---|
TRBLDOC_SRC_REPO |
Repository URL substituted for {{ src_repo }} in doc comments. Falls back to git remote get-url origin if not provided. |
TRBLDOC_MD |
Override the Markdown renderer used for .md files and @exec md chunks. Defaults to md2html --github --fpermissive-autolinks --ftables. |
TRBLDOC_RST |
Override the ReStructured Text renderer used for .rst files and @exec rst chunks. Defaults to %(body)s. |
TRBLDOC_JOBS |
Number of parallel jobs used for extraction and rendering. Defaults to the detected processor count. |
Quick start
Scan the src/ folder and write output to docs/
trbldoc -s src -o docs
Include the source repository URL in generated pages
TRBLDOC_SRC_REPO=https://github.com/you/repo trbldoc -s src -o docs
Writing doc comments
A doc comment is a block comment whose opening tag is followed on the same
line by the renderer command to use for that chunk. trbldoc includes the
following markup format -> html mapping:
| alias | program |
|---|---|
md |
md2html |
rst |
docutils |
C / C++ / SQL
/* md
# My Function
Does something useful.
*/
Lua
--[[ md
## Overview
Brief description here.
]]
Python
'''md
## Helper
Processes the input.
'''
trbldoc lets you call arbitrary bash(!) from source code comments.
Some users may be alarmed, or believe this is a security vulnerability.
The reality at the time of publishing is that it is almost all
software documentation is generated on computers controlled by
the same person or people that wrote the source code, and published on the internet.
If you can trust someone to write some code that's running on your machine,
you can probably trust them to run more code to generate documentation.
If you are interested in letting third parties generate documentation
without reading the code, or you want to generate documentation from untrusted input,
trbldoc is not right for your project.
With that said, allowing people to generate arbitrary html to explain their code can be extremely powerful:
--[[ cat
<pre class="mermaid">
---
title: querying a resource
---
sequenceDiagram
participant db@{"type": "database"}
participant host
actor client
client ->> host : GET /resource/123
host ->> db : select * from resources where id = 123
db ->> host : 0 rows
host ->> client : 404 - File not Found
</pre>
]]
In addition, you can add new kinds of comment blocks, here's how you would add comment blocks for Nim
$ trbldoc -s src -f 'nim;#[;#]'
If you wanted to cite the Nim standard library in your comments like
#[ md
This function uses @nim/ropes under the hood...
#]
You need a way to turn ropes into the nim link, https://nim-lang.org/docs/ropes.html.
You might chose to use sed:
$ trbldoc -s src -f 'nim;#[;#]' -R 'nim=sed;-e s|^|https://nim-lang.org/docs/|g -e s|$|.html|g'
As your prefix to link resolution gets more complex, you may chose to use a
simple bash program to generate links. You may also chose to call trbldoc
from a bash script or makefile.
Markdown (.md)
The whole file is treated as a single chunk and rendered with md.
Single-line comments (/* ... */, --[[ ]], ''' ''') on one line are
intentionally ignored, trbldoc only extracts multiline blocks.
Comment blocks that do not specify a program on it's first line are likewise ignored.
In-chunk directives
Directives are lines inside a doc comment that control how the chunk is processed. They are stripped before rendering.
| Directive | Effect |
|---|---|
@name <name/space> |
Group this chunk under <namespace> using slash-separated paths (e.g. lua/string). Defaults to the relative source file path. Use slashes (/) as the separator. |
@priority <number> |
Controls chunk ordering when rendering pages. Higher values are rendered first. Falls back to alphabetical @name ordering. |
@exec <program> |
Override the program used to turn text into html for this chunk. |
@file <path>:<line> |
Override the displayed source file attribution. Useful if the file seen by trbldoc has been built from some other source file. |
@ref <name> |
Publish this chunk under a custom reference name for cross-linking. (e.g. if you want to shorten a long name like @interface/composites/menus/dropdown to just @ui/dropdown) |
Template variables
The following {{ }} markers are expanded in chunk bodies before the renderer
runs (or, for toc, in a post-render pass):
| Variable | Expands to |
|---|---|
{{ src_repo }} |
Source repository URL (TRBLDOC_SRC_REPO env var or git remote get-url origin). |
{{ ref_string }} |
HTML link for this chunk's @ref value, resolved from the built-in references map. |
{{ toc }} |
Navigation list (nav.partial content) - substituted after all chunks are rendered. |
@prefix/path/to/resolve |
Create a link to another document in this or another project. |
The default page layout (main.layout) also supports:
| Variable | Expands to |
|---|---|
{{ title }} |
page title in <title>. |
{{ breadcrumb }} |
heading text for the current page. |
{{ nav }} |
navigation list. |
{{ yield }} |
rendered page body. |
Example:
/* md
@name http/api/public/connect
@ref db/connect
Establishes a database connection.
*/
Pipeline overview
trbldoc has several steps, in each step multiple actions are done in parallel,
as your xargs allows.
- Finds all source files under the input folders whose extension has
a registered comment form (
c,h,cpp,hpp,lua,py,sql,md,dot, plus any-fadditions). - Run each file through an AWK program that emits chunk files
into
.trblcache/chunks/. - For each chunk, strip directives, run the renderer, and append
output to
.trblcache/namespace/<namespace>/index.html. - Write
main.layout,nav.partial,global.meta, and CSS into.trblcache/namespace/. - Apply the layout/template tokens to each namespace page and
write the final site to
-o <dest>(default.trblcache/built).
Chunk files in .trblcache/chunks/ and last-processed timestamps in
.trblcache/last_processed/ persist between runs. Only source files that have
changed since the last run are re-extracted. Use -C to force a full rebuild.
Rendered output (index.html, nav.partial, etc.) are always regenerated from
all chunks on every run. See docs/trblcache
for why they have to be.
Tests
The test suite uses bats-core ≥ 1.5.
npm install -g bats # or: brew install bats-core
bats tests/unit tests/integration
Tests are organised as:
tests/unit/extraction.batsAWK comment extraction per languagetests/unit/directives.batsdirective parsing and strippingtests/unit/template_vars.batstemplate variable pattern matchingtests/integration/pipeline.batsend-to-end pipeline assertionstests/integration/cli.batsCLI option parsing
Repository layout
trbldoc.sh Main pipeline script
ref_resolvers/lua.sh Reference Lua API prefix resolver
tests/
helpers/ Shared test helpers, stubs, AWK program builders
common.bash Common test helpers
profiler.bash Helpers for profileing
fixtures/ Small files used as test inputs
unit/ Unit tests
integration/ Integration tests
