Markdown Features
Every feature and config surface zfb's Markdown pipeline provides, including Core pipeline behavior and opt-in features.
zfb's Markdown pipeline is layered. A set of Core features runs in the engine's main markdown pipeline/config surface, giving you heading anchors, server-side syntax highlighting, CJK-friendly handling, and more. Some Core rows are always on; others are top-level or markdown.* config knobs implemented in the core pipeline. The table below aims to document every Core and Opt-in surface's default and config key, but it is hand-maintained rather than generated from the config schema, so it can lag behind newly landed constructs — check the linked feature page or the config type it mirrors for the current behavior.
This page is the map. Each feature has its own page with a usage example, config key, and ordering notes.
Dependency graph
zfb-content — Core features live here; always compiled in
└─ zfb-md-extras — Opt-in features; compiled in but gated at runtime
└─ zfb-md-ast — Shared AST types (MdastNode, HastNode, visitors)The zfb-md-ast crate defines the MdastVisitor and HastVisitor traits and the shared node types. Both Core and Opt-in features implement these traits.
Tier convention
Core — implemented in
zfb-contentor the top-level markdown config surface. Core does not always mean "unconfigurable"; check the config key and default in the table.Opt-in — inactive unless enabled in config. Most opt-in feature entries live under
markdown.features.*, butstripMdExtandmarkdown.hardBreaksare opt-in top-level options.
Each feature page shows a Core or Opt-in badge near its title.
Config shape
import { defineConfig } from "zfb/config";
export default defineConfig({
stripMdExt: true,
markdown: {
hardBreaks: true,
features: {
mermaid: true,
directives: {
note: "Note",
tip: "Tip",
},
},
},
});Boolean shorthand is not universal. It works only for rows whose value shape includes boolean. Object-only rows, such as codeEnrichment, tocExport, imageDimensions, linkValidation, transclude, and headingIds, require an object. Unknown keys are rejected at config load time.
Feature map
| Feature | Tier | Config key | Value shape | Default / gating |
|---|---|---|---|---|
| GFM constructs | Core | markdown.gfm | boolean | { strikethrough?: boolean; table?: boolean; autolinkLiteral?: boolean; taskListItem?: boolean; footnoteDefinition?: boolean } | Absent → conservative default (strikethrough/table/autolinkLiteral on, other two off). true/false shorthand toggles all five. |
| CJK-friendly emphasis | Core | markdown.cjkFriendly | boolean | true; set false to opt out. |
| Heading links | Core | markdown.features.headingIds | { strategy?: "flat" | "hierarchical" } | Plugin always on; default strategy is "flat". |
| Code block title | Core | none | n/a | Always on. |
| External links | Core | markdown.externalLinks | { target?: string; rel?: string[] } | Off unless supplied. |
| Resolve links | Core | resolveMarkdownLinks | { enabled?: boolean; docsDir?: string; dirs?: { dir: string; routePrefix: string }[]; onBrokenLinks?: "warn" | "error" | "ignore" } | Off unless enabled: true. |
| Strip .md extension | Opt-in | stripMdExt | boolean | false; when true, strips .md/.mdx and appends /. |
| Hard breaks | Opt-in | markdown.hardBreaks | boolean | false; when true, soft line breaks become <br>. |
| Syntax highlighting | Core | codeHighlight | { theme?: string; themesDir?: string; themeLight?: string; themeDark?: string; mode?: "inline" | "class"; classPrefix?: string; roleClasses?: Partial<Record<CodeHighlightRole, string>>; defaultStylesheet?: boolean } | On with the default syntect theme (mode: "inline"); mode: "class" emits semantic role classes instead — see the linked page for the full shape. |
| Directives registry | Core primitive | markdown.features.directives or Rust API | Record<string, DirectiveSpec> | Registry visitor runs only when supplied; zero default names. |
| Directives | Opt-in | markdown.features.directives | Record<string, string | { component: string; kind?: "container" | "leaf" | "text"; titleFromLabel?: boolean }> | Off when absent; {} wires an empty registry. |
| Mermaid diagrams | Opt-in | markdown.features.mermaid | boolean | {} | Off when absent or false; marks blocks as <div class="mermaid">. |
| Heading-marker TOC | Opt-in | markdown.features.headingMarkerToc | boolean | { heading?: string; maxDepth?: number } | Off when absent or false. |
| GitHub alerts | Opt-in | markdown.features.githubAlerts | boolean | {} | Off when absent or false. |
| Reading time | Opt-in | markdown.features.readingTime | boolean | { wpm?: number } | Off when absent or false; emits export const readingTimeMinutes. |
| Code-block enrichment | Opt-in | markdown.features.codeEnrichment | { diffMarkers?: boolean; lineHighlight?: boolean; wordHighlight?: boolean } | Off when absent; object form enables it, with all subfeatures on by default. |
| Code tabs | Opt-in | markdown.features.codeTabs | boolean | {} | Off when absent or false. |
| Ruby annotation | Opt-in | markdown.features.ruby | boolean | {} | Off when absent or false. |
| TOC export | Opt-in | markdown.features.tocExport | { maxDepth?: number } | Off when absent; default maxDepth is 3. |
| Image dimensions | Opt-in | markdown.features.imageDimensions | { skipRemote?: boolean } | Off when absent; skipRemote defaults to true. |
| Link validation | Opt-in | markdown.features.linkValidation | { failOnBroken?: boolean } | Off when absent; warns by default, errors with failOnBroken: true. |
| Transclusion | Opt-in | markdown.features.transclude | { maxDepth?: number } | Off when absent; default maxDepth is 5. |
See also
Design Philosophy — the three-consumer threshold for promoting a recipe to an Opt-in feature.
Extending the Markdown Pipeline — write a Rust visitor and wire it into the engine.
Custom Directives — register new directive names without writing Rust.
Recipe: Enlargeable Images — userland replacement for the removed
imageEnlargebuilt-in, using theimgcomponent override.Recipe: Admonitions — register
:::note,:::tip, etc. viadirectiveswith component stubs and CSS hooks.