Code and math
Everything on this page renders at build time — no script is needed to show the highlighting, math, or callouts below.
Syntax highlighting
Fences are highlighted by language, and the first code block of a site looks exactly like the last one — the highlighter settles each grammar as it loads, so a build cannot produce two different colourings for two identical blocks.
import { build } from "@iyulab/canopy";
const bundle = await build({
documents: [
{ path: "index.md", content: "# Home\n\nSee [[notes/idea]]." },
],
});
def pages(tree: dict) -> list[str]:
return sorted(p for p in tree if p.endswith(".md"))
{ "title": "Product Help", "sections": [{ "path": "guide" }] }
A fence naming a language nothing can resolve renders as plain text — the same background as every other code block, just without coloring — rather than failing:
this still renders
Math
Written between dollars, rendered to HTML with the fonts bundled into the site, so it needs no network:
Inline as well: a site of documents resolves its links in one pass, not .
Callouts
NOTE
A note carries context the surrounding prose would interrupt.
WARNING
A warning is what a reader will wish they had read.
TIP
Callout syntax is the same one GitHub renders, so a document reads correctly both in the repository and on the published site.
Long enough for a contents list
The list at the top of this page was not written by hand. Every page with at least two headings
gets one, built from the same heading ids that [[page#heading]] links target — so a contents
entry and a cross-page link can never disagree about where a section is.
A third-level heading
Nested one level in the contents list, matching its depth here.
Another one
And that is the whole page.