Last updated on Edit this page

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.
pdf Build the site and print its PDF documents.
describe Format a diagnostic as path:line: severity CODE: message.

Build a project

Pudu
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.
A build with custom options
/// 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:

Pudu
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.

A page transform
/// 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.

A post-processor that adds a file
/// 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:

Pudu
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.