Library usage
Everything the command line does is available to Pudu programs. Call the package directly to build sites from a larger tool, add pages or files during a build, or check a project in tests.
Entry points
| Function | Use it to |
|---|---|
| run | Run the command line with a list of arguments and get its exit status. |
| build | Load a project from its configuration file, build it, and publish it incrementally. |
| load | Load a project into a Input without building it. |
| plan | Build a validated Plan from loaded input, without touching the file system. |
| metadata | Write API metadata files for the configured sources. |
| Build the site and print its PDF documents. | |
| describe | Format a diagnostic as path:line: severity CODE: message. |
Build a project
export fn build(configFile: Str, chosen: &Options, extending: &Build.Extensions) -> Result[Docgen.Report, Array[Docgen.Diagnostic]]
build reads the configuration, loads every file the project uses, builds the site, and publishes it. On success it returns a Report listing the files written, unchanged, and removed, with any warnings. On failure it returns every diagnostic, and nothing is written.
Options layers command-line choices over the configuration. Start from options, which changes nothing, and set the fields you need:
| Field | Type | Effect |
|---|---|---|
output |
Str |
Output folder instead of the configured one. |
metadata |
Array[(Str, Docgen.Meta)] |
Global metadata merged over the configuration. |
xref |
Array[Str] |
More cross-reference maps. |
templates |
Array[Str] |
More template folders. |
warningsAsErrors |
Bool |
Fail on any warning. |
dryRun |
Bool |
Validate and plan without writing. |
disableGitFeatures |
Bool |
Skip git dates and edit links. |
force |
Bool |
Rewrite every output file. |
exportRawModel, exportViewModel |
Bool |
Write page models beside the pages. |
/// Builds the project and prints every diagnostic; answers 0 on success and 1 on failure.
fn main() -> Int {
let extending = Build.Extensions{pages: [reviewed], artifacts: [robots]}
let chosen = Docset.Options{..Docset.options(), output: "_preview", warningsAsErrors: true}
match Docset.build("docs/docgen.json", &chosen, &extending) {
case Ok(report) => {
for problem in report.diagnostics { let _said = Io.writeLine(Docgen.describe(&problem)) }
let _summary = Io.writeLine("written " + show(report.written.length()) + ", unchanged " + show(report.unchanged.length()) + ", removed " + show(report.removed.length()))
0
}
case Err(problems) => {
for problem in problems { let _said = Io.writeErrorLine(Docgen.describe(&problem)) }
1
}
}
}
Extend a build
Extensions holds two lists of functions that run during a build:
export type Extensions = { pages: Array[fn(Docgen.Page) -> Docgen.Page], artifacts: Array[fn(Array[Docgen.Artifact]) -> Array[Docgen.Artifact]] }
| Field | Runs | Receives |
|---|---|---|
pages |
After every page is rendered, before navigation, fragment checks, and layout. | One Page at a time: its path, source, kind, title, uid, body HTML, headings, links, and metadata. |
artifacts |
After the whole site is rendered, before output paths are validated. | Every output file as a Artifact with its path and text. |
Use extensions when you need none.
Page transforms
A page transform returns the page it is given, changed or not. The kind of a page is article, rest, api-page, catalog, redirect, or not-found for content, and api-module, api-type, or api-member for generated Pudu reference pages. A transform can use it to target one family of pages; the layout also exposes it as a kind-<kind> class on the page body.
/// Adds a review notice to the end of every article.
fn reviewed(page: Docgen.Page) -> Docgen.Page {
if page.kind != "article" { return page }
Docgen.Page{..page, body: page.body + "<p class=\"review-note\">Reviewed for release 0.1.</p>\n"}
}
Changes made by a page transform are validated with the rest of the site: a fragment link to a heading the transform removed is still reported.
Post-processors
A post-processor receives every output file and returns the files to publish. It can add, remove, or rewrite files; the result is checked for portable, unique paths before anything is written.
/// Adds a robots.txt that points crawlers at the sitemap.
fn robots(artifacts: Array[Docgen.Artifact]) -> Array[Docgen.Artifact] {
let text = "User-agent: *\nAllow: /\nSitemap: https://docs.example.com/sitemap.xml\n"
artifacts.push(Docgen.Artifact{path: "robots.txt", content: text})
}
Build without writing
plan is a pure function: given loaded input, it returns the complete Plan of files and resources, or every error. Tests can use it to check a documentation project without an output folder:
match Docset.load("docs/docgen.json", &Docset.options()) {
case Ok(loaded) => match Build.plan(&loaded.input, &Build.extensions()) {
case Ok(plan) => plan.diagnostics.isEmpty()
case Err(_problems) => false
}
case Err(_problems) => false
}
Diagnostics
Every failure is a Diagnostic with a stable code, a Severity, the file, the line, and a message. failed tells whether a list holds an error. The codes are listed in the diagnostics reference.