Pure functions use Managoat.Docs runs at compile time to turn the
authoring dialect of a manual into plain markdown. Split out because a
module cannot call its own functions from its own body, and so the
transforms can be tested directly.
Covers exactly the dialect a manual may use (see the Managoat.Docs
moduledoc): snippet includes, admonitions, and relative .md links. The
syntax is inherited from the MkDocs Material site Fountain's pages were
published as until they moved in-app; this is not, and never was, a
general MkDocs renderer.
Every function that produces a served path takes the manual's mount
("/docs" for a manual served at /docs), because the only place that
path is known is the host's use line.
Summary
Types
One search-index entry: the page and the h2-h6 headings on it.
{title, file} for a page, {section_title, [{title, file}]} for a section.
One compiled page: its nav title and its preprocessed markdown.
Functions
Reads a nav file and every page it names into the shape use Managoat.Docs
stores: the parsed nav, the slug => page map, and the search index over
the rendered headings. Runs in the host module's body at compile time; the
host declares every path here as an @external_resource.
Pulls {id, text} for every <h2>–<h6> out of a page's rendered
HTML, in document order. The input is Managoat.Docs.Markdown.to_trusted_html/1
output, not markdown. <h1> is skipped; every page has exactly one, and it
duplicates the nav title a search result already shows next to it.
Flattens a nav (sections one level deep) to {title, file} pairs in order.
Parses the nav: block of a nav.yml into the shape use Managoat.Docs
serves: {title, file} for a page and {section_title, [{title, file}, ...]}
for a section, in document order.
With mount "/docs": "" → "/docs", "setup" → "/docs/setup".
Snippets, then admonitions, then link rewriting. file is the page's path
relative to the docs directory (links resolve against its directory),
root is where snippet includes are read from, and mount: is the path
the manual is served at (default "/docs").
"index.md" → "", "integrations/index.md" → "integrations", else the rootname.
Types
Functions
@spec compile(String.t(), String.t(), String.t(), String.t()) :: %{ nav: [nav_entry()], pages: %{required(String.t()) => page()}, search_index: [index_entry()] }
Reads a nav file and every page it names into the shape use Managoat.Docs
stores: the parsed nav, the slug => page map, and the search index over
the rendered headings. Runs in the host module's body at compile time; the
host declares every path here as an @external_resource.
Pulls {id, text} for every <h2>–<h6> out of a page's rendered
HTML, in document order. The input is Managoat.Docs.Markdown.to_trusted_html/1
output, not markdown. <h1> is skipped; every page has exactly one, and it
duplicates the nav title a search result already shows next to it.
Reads the id comrak already assigned rather than re-deriving one from the
heading text. Slugging headings a second time is a known trap: the MkDocs
build Fountain's pages came from and comrak's header_id_prefix
extension picked different ids for duplicate headings on the same page
(-1 vs _1), and a search result is only useful if its anchor is the one
the page actually renders. The anchor guardrail leans on the same rendered
output, for the same reason.
Flattens a nav (sections one level deep) to {title, file} pairs in order.
With mount "/docs": "" → "/docs", "setup" → "/docs/setup".
Snippets, then admonitions, then link rewriting. file is the page's path
relative to the docs directory (links resolve against its directory),
root is where snippet includes are read from, and mount: is the path
the manual is served at (default "/docs").
"index.md" → "", "integrations/index.md" → "integrations", else the rootname.