Ferromark / Rust
Customize Code Blocks in Rust
Use HtmlRenderHooks to replace output for selected AST nodes. The normal
render() path does not dispatch hooks; opt in with render_with_hooks().
For syntax highlighting, enable Ferromark's optional ferriki Cargo feature and
use FerrikiHighlightHooks with an initialized Ferriki highlighter. Ferromark
keeps the code-block wrappers, line numbers, and annotations. The optional
ferriki-remote feature enables release-pinned CDN assets. Build the
highlighter and preload required languages/themes before rendering. See the
native highlighting guide for the adapter contract.
use ferromark::{Allocator, HtmlRenderContext, HtmlRenderControl, HtmlRenderHooks,
HtmlRenderer, Parser};
use ferromark::ast::Node;
struct CodeRenderer;
impl HtmlRenderHooks for CodeRenderer {
fn render_node(&mut self, node: &Node<'_>, cx: &mut HtmlRenderContext<'_>)
-> HtmlRenderControl {
if let Node::CodeBlock(block) = node {
cx.write("<pre class=\"source\"><code>");
cx.write_escaped(&block.value);
cx.write("</code></pre>\n");
HtmlRenderControl::Handled
} else {
HtmlRenderControl::Default
}
}
}
let source = "```rust\nfn main() {}\n```";
let allocator = Allocator::for_source_len(source.len());
let document = Parser::new(&allocator, source).parse().unwrap();
let html = HtmlRenderer::new().render_with_hooks(&document, &mut CodeRenderer);
assert!(html.contains("class=\"source\""));
Return Default to use built-in output; return Handled after writing the entire
replacement. The hook sees fenced and indented code blocks. A highlighter adapter
can inspect the code, language, and metadata, then write its HTML here.
cx.write() inserts raw HTML, even when sanitization is enabled. Escape source
text with write_escaped, attributes with write_attribute_escaped, and URL
attributes with write_url_escaped. Validate URL schemes when supplying custom
URLs. Only insert highlighter output you trust. Theme colors from custom hooks
are escaped for HTML attributes, but their CSS values are not validated.
For code annotations, line numbers, and heading permalinks, inspect the existing
HtmlRendererOptions before writing a hook. Rendering and trust
explains the shared output boundary.
Compose highlighting and diagrams
Use HtmlRenderHooks::render_code_block for whole-block replacements and
highlight_code_block for highlighted line fragments. A tuple composes hooks;
all whole-block replacements run before highlighting. The code-only
render_with_code_hooks entry point preserves normal inline rendering.
The optional ferrigura feature implements these HTML and JSX contracts with
FerriguraHooks, just as the ferriki feature does with FerrikiHighlightHooks. The highlighting and diagrams guide
explains the available builds and links to the Rust adapter example.