PasWeave is an early-stage documentation generator designed primarily for
Free Pascal projects. It is written in Free Pascal and builds its source model
with FPC's reusable fcl-passrc parser libraries.
Documentation syntax:
///is PasWeave's own explicit documentation marker, not a special Free Pascal orfcl-passrcfeature. FPC reads it as an ordinary//comment; PasWeave gives the third slash its documentation meaning. Accordingly,--doc-comments=slashmeans consecutive///lines only. Ordinary//comments are never treated as API documentation.
The working parser-to-site pipeline includes:
- a
pasweave buildcommand for one Pascal unit or a directory of.pasand.ppunits, with opt-in recursive discovery and include/exclude filters; - interface parsing through
fcl-passrc; - compiler-aware parsing with repeatable unit paths, include paths, and conditional defines plus explicit normalized target OS and CPU settings;
- Lazarus
.lpiproject and.lpkpackage inputs with build-mode selection, imported compiler settings, and deterministic local-package discovery; - parser-independent project, unit, symbol, directive, and diagnostic models;
- source-backed association of enabled PasWeave
///, Pascal{ ... }, and Pascal(* ... *)documentation groups, with///as the safe default; - structural extraction of
@param,@returns,@raises,@deprecated,@see, and@since; - model-level authoring feedback with stable diagnostic codes for directive, project-local reference, route, and coverage defects;
- deterministic, human-readable UTF-8 JSON;
- a deterministic Markdown project index and one page per parsed unit;
- stable overload-aware anchors, internal dependency links, parent links, fenced Pascal declarations, directive sections, and visible undocumented API warnings;
- a responsive static HTML project index and one page per parsed unit;
- dependency-free, offline client-side search across every renderable API symbol;
- shared styling with light and dark colour schemes, safe Markdown-to-HTML conversion, and offline KaTeX rendering for marked inline and display mathematics;
- deterministic, linked Mermaid diagrams of project-local interface dependencies and semantically resolved class/interface relationships, each with independent accessible zoom, pan, reset, and linked text fallback;
- per-file error isolation, concise summaries, and meaningful exit codes.
The Markdown renderer consumes only PasWeave's model. FPC parser classes remain contained behind the adapter.
PasWeave targets Free Pascal and {$mode objfpc} first. Delphi-compatible
syntax is accepted only where it works naturally through FPC's parser.
PasWeave does not contain a Pascal parser of its own.
PasWeave is not a fork of PasDoc or FPDoc. It explores a Free Pascal-first workflow centred on Markdown, structured output and modern static documentation. We appreciate the substantial work those projects have contributed to the Pascal ecosystem.
Windows users can download the portable pasweave.exe from the
GitHub Releases page. It does
not use an installer, modify the registry, or require Free Pascal at runtime.
The executable contains the offline KaTeX and Mermaid assets needed by the
HTML renderer.
Place it anywhere and run:
.\pasweave.exe --version
.\pasweave.exe build path\to\project --output docsEach release also provides pasweave.exe.sha256 for integrity verification:
Get-FileHash .\pasweave.exe -Algorithm SHA256Early pre-release executables are not code-signed, so Windows may display a SmartScreen warning. Download only from the PasWeave release page and compare the SHA-256 value before running the executable.
Read the v0.4.0 release notes for the highlights, compatibility details, validation results, and known limitations. The complete project history is maintained in the changelog.
These requirements apply only when compiling PasWeave from source:
- Free Pascal 3.2.2 or newer
- the FPC
fcl-passrcandfcl-jsonpackages
The current adapter was inspected and tested specifically against FPC 3.2.2. See the parser integration notes for the exact APIs used and known uncertainties.
The first real-world run against all 45 source units in
mathlib-fp produced 2,338 symbols
with no parse errors, missing source positions, or duplicate stable IDs. See
the validation report for the tested revision,
determinism result, and its important comment-syntax finding.
With a POSIX-compatible make:
make
make test
Directly with FPC from the repository root:
mkdir -p build/bin build/tests build/units
fpc -Mobjfpc -Sh -Fusrc/cli -Fusrc/diagnostics -Fusrc/model -Fusrc/parser -Fusrc/render -Fusrc/validation -FUbuild/units -FEbuild/bin src/pasweave.lpr
fpc -Mobjfpc -Sh -Fusrc/cli -Fusrc/diagnostics -Fusrc/model -Fusrc/parser -Fusrc/render -Fusrc/validation -FUbuild/units -FEbuild/tests tests/test_pasweave.pas
On PowerShell, create the directories with:
New-Item -ItemType Directory -Force build/bin, build/tests, build/unitsRun the test executable from the repository root so it can find its fixture:
build/tests/test_pasweave
To build the standalone Windows release executable and perform its isolated smoke test:
.\scripts\build-portable-windows.ps1This writes only dist\pasweave.exe and its checksum as release artifacts;
there is no installer or ZIP package. See the
release procedure for the isolated smoke test, version-tag
rules, and public-release license gate.
build/bin/pasweave build tests/fixtures --output build/docs
For a small project whose public API is deliberately documented with
PasWeave /// comments, generate the
documented API example:
build/bin/pasweave build examples/documented-api --output build/documented-api --project-name "Documented API example"
Its HTML index reports 10 of 10 API symbols documented, providing an
immediate example of a fully populated DOCUMENTED column.
You can also browse the checked-in Markdown sample or clone the repository and open the HTML sample directly. The snapshot shows the actual project index and both generated unit pages.
For a more substantial equation-rich demonstration, see the runnable scientific API example. Its checked-in Markdown output and HTML output document 30 of 30 public API symbols with 16 display equations and 65 inline mathematical expressions.
For a nested source tree, enable recursive discovery explicitly and exclude trees that are not part of the public API:
pasweave build src --recursive --exclude=generated/** --exclude=tests --exclude=vendor/**
--include and --exclude are repeatable, case-insensitive globs relative to
the supplied source directory. * and ? match within one path segment;
** as a complete segment spans directories. Exclusions take precedence.
Without --recursive, directory input retains the original top-level-only
behavior. See source discovery for the complete
matching and safety contract.
To reproduce the interface selected by a configured FPC build, supply its source paths, defines, and target explicitly:
pasweave build src --recursive \
--unit-path=packages/core/src \
--include-path=include \
--define=USE_FAST_MATH \
--target-os=linux \
--target-cpu=aarch64
--unit-path, --include-path, and --define are repeatable. Paths are
searched in command-line order; the first match wins. Explicit targets replace
the host defaults and are normalized before fcl-passrc sees them. See
compiler-aware parsing for supported values,
precise precedence, diagnostics, and limitations.
Lazarus projects and packages can provide those settings directly. Point the
build command at an .lpi or .lpk; no Lazarus process is started:
pasweave build path/to/Application.lpi --build-mode=Release \
--package-path=path/to/local-packages --output build/docs
PasWeave imports project/package units, source and include paths, defines, and
target settings. Explicit command-line compiler options override imported
values; imported project/package settings override PasWeave defaults. The
default package scan is deterministic and prunes generated, vendor, example,
and test trees. Use repeatable --package-path values when a local package
intentionally lives in one of those trees. See the
Lazarus project and package guide for supported
XML elements and diagnostics.
To use authoring feedback as a CI gate, require a coverage percentage and promote warnings to failures explicitly:
pasweave build src --min-documentation-coverage=90 --fail-on=warning
The default is --fail-on=error, so new documentation warnings remain useful
without blocking local rendering. See authoring feedback and reference
integrity for stable codes and precise rules.
The command writes:
build/docs/
├── api-model.json
├── diagnostics.json
├── html/
│ ├── index.html
│ ├── assets/
│ │ ├── app.js
│ │ ├── diagram.js
│ │ ├── katex/
│ │ │ ├── fonts/
│ │ │ ├── katex.min.css
│ │ │ ├── katex.min.js
│ │ │ └── LICENSE
│ │ ├── math.js
│ │ ├── mermaid/
│ │ │ ├── mermaid.tiny.js
│ │ │ └── LICENSE
│ │ ├── search-index.js
│ │ └── site.css
│ └── units/
│ └── SimpleUnit.html
└── markdown/
├── index.md
└── units/
└── SimpleUnit.md
The command exits with 0 when no diagnostic meets the configured
--fail-on severity, 1 after usable output with a failing diagnostic,
2 for command-line or input errors, and 3 for an unexpected internal
failure. --fail-on=error is the default; --fail-on=warning also fails on
authoring feedback. --verbose adds diagnostic details without printing a
stack trace.
In api-model.json, class and interface symbols expose a
typeRelationships array. Each entry records kind (inherits or
implements), the typed-AST targetName, its source-like displayName, and a
stable targetSymbolId when the target resolves inside the documented
project. An empty target ID is an explicit unresolved result.
Routine symbols additionally expose parser-derived parameterNames and
hasReturnValue. Directive objects contain targetSymbolId for a resolved
project-local @see; an empty value is deliberately unresolved.
PasWeave deliberately defines /// as its explicit documentation marker.
fcl-passrc does not classify triple-slash comments as documentation: it
parses the declaration structure and supplies source positions, then PasWeave
reads the original source and associates enabled comments itself. In the CLI,
the style name slash therefore means exactly ///; it does not mean ordinary
// comments.
By default, place consecutive PasWeave /// lines immediately before an
interface declaration:
/// Returns the standard normal probability density.
///
/// $$
/// \phi(x) = \frac{1}{\sqrt{2\pi}}e^{-x^2/2}
/// $$
///
/// @param X Point at which the density is evaluated.
/// @returns The probability density at `X`.
function NormalPDF(const X: Double): Double;Ordinary Markdown and mathematical delimiters are retained in
markdownDocumentation. The original /// form is retained in
rawDocumentation, while recognised directives are also emitted as structured
objects.
Projects that deliberately use ordinary Pascal comments for API documentation can opt into one or both block forms:
--doc-comments value |
Source form treated as documentation |
|---|---|
slash |
Consecutive /// lines only; plain // is ignored |
brace |
Standalone { ... } comments |
paren |
Standalone (* ... *) comments |
all |
slash, brace, and paren together |
pasweave build src --doc-comments=slash
pasweave build src --doc-comments=brace
pasweave build src --doc-comments=paren
pasweave build src --doc-comments=slash,brace,paren
pasweave build src --doc-comments=all
The space-separated form, such as --doc-comments brace, is also accepted.
Enabled forms may be mixed in one standalone group and are merged in source
order:
/// Computes a scaled value.
{ @param X Input value. }
(* @returns The scaled result. *)
function Scale(const X: Double): Double;A group must directly precede its interface declaration. A blank line,
compiler directive, disabled comment form, or other source token ends the
association. Block groups must start on an otherwise blank source line, so a
trailing comment such as X: Double; { describes X } cannot drift onto the
next declaration. Compiler directives in {$...} and (*$...*) are never
documentation.
Opting into brace or paren is intentionally broad: section labels and
commented-out declarations can look exactly like ordinary documentation. Use
those modes only where the project's comment conventions make that trade-off
acceptable. The original delimiters are retained in rawDocumentation; the
combined bodies and supported structured directives are normalized into the
other model fields.
markdown/index.md contains project totals, documentation coverage, links to
every successfully parsed unit, and any build diagnostics. Each unit page
contains:
- source and interface-dependency information;
- linked public and protected types, routines, members, constants, and variables;
- stable explicit anchors that distinguish overloads;
- fenced
pascaldeclarations; - preserved Markdown and mathematical delimiters;
- parameter, return, raised-exception, deprecation, version, and see-also sections;
- a visible warning for every undocumented API symbol.
Private and strict-private symbols remain in api-model.json but are omitted
from the generated API pages.
Open html/index.html directly in a browser. The generated site requires no
web server or network connection; its KaTeX and Mermaid runtimes, styles,
fonts, and licenses are copied into the output. It contains:
- a responsive project overview and linked unit pages;
- the same stable symbol anchors and visibility filtering as Markdown;
- escaped Pascal declarations and safely rendered documentation prose;
- offline rendering of marked display and inline mathematics, with the original delimited source left readable when an expression is invalid;
- a linked Mermaid graph of project-local interface dependencies on the index, backed by an initially expanded textual list when diagrams are unavailable;
- a linked class/interface relationship graph generated from resolved model data, with generic and unresolved targets preserved in its text fallback;
- per-diagram controls for bounded zoom, directional pan, and reset, with keyboard shortcuts, mouse dragging, reduced-motion support, and independent view state;
- an offline search index covering names, qualified names, kinds, units, and documentation summaries;
- keyboard search focus with
/and dismissal with Escape; - build diagnostics and visible documentation-coverage totals.
Both generated indexes show the stable diagnostic code. The separate
diagnostics.json artifact carries the same model diagnostics for CI systems.
The HTML, stylesheet, JavaScript, and search index are deterministic UTF-8 files with LF line endings. See the HTML renderer notes for its offline-search, safety, and Markdown-subset contracts.
- mathematical rendering supports KaTeX's TeX subset rather than arbitrary LaTeX; invalid or unsupported expressions remain visible as source;
- the dependency-free Markdown-to-HTML conversion intentionally supports a focused subset rather than every Markdown extension;
- Lazarus package discovery requires local
.lpkfiles; external Lazarus/FPC packages must be made available through an explicit package path; - type relationship resolution is limited to the current unit and its interface dependencies; ancestors outside the documented source set remain explicitly unresolved, and implementation bodies are not analysed;
- ordinary block-comment modes cannot semantically distinguish API prose from section labels or commented-out code; they therefore remain explicit project opt-ins;
- configured unit paths resolve source
.pasand.ppfiles, not compiled.ppufiles, and do not recurse; - explicit OS and CPU values are validated independently, but PasWeave does not claim every possible pair is a real FPC code-generation target;
- no fixture coverage yet for every requested symbol kind or unusual FPC syntax.
PasWeave is released under the MIT License. Bundled third-party components retain their own licenses; see THIRD_PARTY_NOTICES.md.
The authoring-feedback milestone is complete in v0.4.0. See
ROADMAP.md for its acceptance evidence and the remaining
longer-term sequence.