Skip to content
Ferromark

Ferromark / Shared reference

Add Highlighting and Mermaid Diagrams

Use Ferriki to highlight source code and Ferrigura to render Mermaid fences as static SVG. Ferromark supplies the code-block hooks; your application chooses the engines and their initialization.

Choose an integration

Your taskIntegrationAvailability
Node.js HTML highlightingtoHtmlWithHighlighter and @ferriki/corePublished; Node.js guide.
Rust HTML/JSX highlightingOptional ferriki feature and Rust hooksPublished; Rust code rendering.
Native plugin compositionCodeCompiler with factories linked into the addonRepository main and custom plugin bundles.
Rust Mermaid to SVGOptional ferrigura feature and Rust hooksRepository main; Mermaid guide.
Node.js Mermaid to SVGcreateDiagramCodeRenderer and @ferrigura/coreRepository main; waits for @ferrigura/core on npm.
Native Node.js MermaidCodeCompiler in a custom bundleCustom plugin bundles; excluded from the standard addon.

The published ferromark@3.6.0 facade does not export CodeCompiler, availableCodePlugins, or the new callback-composition helpers. Check your installed declarations before using those APIs. @ferrigura/core is not yet published on npm; until it is, the custom bundle is the installable Node.js Mermaid path.

Select native plugins once

The Native plugin bundles workflow builds an installable tarball for none, ferriki, ferrigura, or all. Download the artifact for your platform, extract it, and install its actual tarball filename:

npm install /path/to/ferromark-custom-bundle.tgz

This replaces the application's Ferromark installation with the selected custom build. The consuming application needs no Rust compiler or install script. The bundles are workflow artifacts with private custom versions, rather than registry releases.

With a bundle containing Ferrigura:

import { availableCodePlugins, CodeCompiler } from "ferromark";

console.log(availableCodePlugins()); // Includes the diagram factory in this build.
const compiler = new CodeCompiler({
  plugins: [
    {
      name: "ferrigura",
      options: { colorScheme: "auto", errorPolicy: "code", idPrefix: "guide" },
    },
  ],
});
const source = "```mermaid\nflowchart LR\nA[Markdown] --> B[SVG]\n```";

console.log(compiler.toHtml(source)); // Inline SVG inside the document HTML.
console.log(compiler.compile(source).body); // JSX source for the same diagram.

Reuse the compiler across documents. Add a ferriki entry when the bundle also contains that factory; initialize its languages, themes, and verified assets before rendering. Whole-block diagram replacements run before highlighting. new CodeCompiler() selects no plugins and initializes no engine assets.

The standard addon includes neither engine and reports [] from availableCodePlugins(). Use CodeCompiler with an explicit plugin list in an engine-enabled bundle; both engines follow the same opt-in build boundary.

Compose separately installed engines

The existing Node.js highlighter API calls an initialized engine through JavaScript. The source checkout adds composeCodeRenderers, createHighlighterCodeRenderer, createDiagramCodeRenderer, toHtmlWithCodeRenderer, and transformWithCodeRenderer for ordered synchronous callbacks. createDiagramCodeRenderer accepts any object with a synchronous render(text, options) method, such as a @ferrigura/core Renderer, so Ferromark does not pin the diagram package. A callback returns complete HTML, or declines with null or undefined. JSX callbacks must return JSX source instead of HTML.

Separately compiled native addons compose through these JavaScript APIs. Installing another npm package does not add factories to a Ferromark binary; native factories must be compiled with that addon. Rust applications compose hook implementations directly, without Node.js. See the code-block renderer contract.

Understand the current Mermaid boundary

The native integration recognizes parsed mermaid fences and emits SVG without a browser Mermaid runtime. By default, invalid or unsupported diagrams retain escaped code and a diagnostic with the fence's original UTF-8 byte range. Drain compiler.takeDiagnostics() or prepared.takeDiagnostics() after rendering. errorPolicy: "throw" selects strict failure instead.

SVG passes a dedicated policy before HTML emission or JSX conversion: scripts, event attributes, external resources, and foreignObject HTML are rejected. Embedded fonts and local fragment references remain available. Custom application callbacks, including createDiagramCodeRenderer, keep their own trusted-output contract.

IDs derive from the output namespace and original fence position. Repeated and prepared renders are identical; supply distinct idPrefix values when combining documents. Shared flowchart, sequence, state, class, and ER fixtures pin complete SVG bytes across Rust and installed Node consumers. Automatic light/dark CSS requires no JavaScript. See the Mermaid guide for options, examples, output constraints, and the engine version.