DocAnvil

Components

DocAnvil provides built-in components rendered via fenced directives. These are processed before Markdown rendering, so you can use Markdown inside them.

Directive Syntax

Components use a fenced block syntax with triple colons:

<div class="name">
<p>Content goes here. <strong>Markdown</strong> is supported.</p>
</div>

The opening fence is ::: followed by the component name and optional attributes in curly braces. The closing fence is ::: on its own line.

Attributes

Attributes are specified inside {...} after the component name:

Syntax Result
key="value" Named attribute
.classname Adds a CSS class
#idname Sets the element ID

Multiple attributes can be combined: :::note{title="Important" .custom-class #my-note}

Note

Display informational callouts with a blue/indigo theme.

Note

This is a note with the default title.

Custom Title

Notes accept a title attribute. The default title is "Note".

Raw syntax:

<div class="admonition note">
<p class="admonition-title">Custom Title</p>
<p>Your content here. Supports <strong>Markdown</strong>.</p>
</div>

Warning

Display cautionary messages with an orange theme.

Warning

This is a warning with the default title.

Danger Zone

Warnings accept a title attribute. The default title is "Warning".

Raw syntax:

<div class="admonition warning">
<p class="admonition-title">Danger Zone</p>
<p>Your warning content here.</p>
</div>

Lozenge

Display a quick visual status with a lozenge.

Syntax is as follow: :::lozenge{type="default",text="Default"}

Syntax Result
Default Default
Warning Warning
In Progress In Progress
Error Error
Success Success

Tabs

Group content into switchable tabs. Each tab is defined with a nested :::tab directive. The outer ::::tabs uses four colons so the inner :::tab closings (three colons) don't end the container prematurely:

console.log("Hello!");
print("Hello!")
fn main() {
    println!("Hello!");
}

Raw syntax:

<div class="tabs">
<div class="tab-headers">
  <button class="tab-header active" data-tab="0">JavaScript</button>
  <button class="tab-header" data-tab="1">Python</button>
</div>
<div class="tab-content active" data-tab="0">
<p>Content for the JavaScript tab.</p>
</div>
<div class="tab-content" data-tab="1">
<p>Content for the Python tab.</p>
</div>
</div>

If no title is provided, tabs are labeled "Tab 1", "Tab 2", etc.

Code Group

A specialized tab component for comparing code blocks across languages. Each fenced code block becomes a tab, with the language name as the tab label:

fn greet(name: &str) {
    println!("Hello, {name}!");
}
def greet(name):
    print(f"Hello, {name}!")
function greet(name) {
  console.log(`Hello, ${name}!`);
}

Raw syntax:

<div class="code-group">
<div class="tab-headers">
  <button class="tab-header active" data-tab="0">rust</button>
  <button class="tab-header" data-tab="1">python</button>
</div>
<div class="tab-content active" data-tab="0"><pre><code class="language-rust">fn greet(name: &amp;str) {
    println!("Hello, {name}!");
}</code></pre></div>
<div class="tab-content" data-tab="1"><pre><code class="language-python">def greet(name):
    print(f"Hello, {name}!")</code></pre></div>
</div>

Mermaid Diagrams

Render diagrams and charts using Mermaid.js. The content inside a :::mermaid block is passed directly to Mermaid — it is not processed as Markdown.

graph TD
    A[Write Markdown] --> B[Run docanvil build]
    B --> C[Static HTML site]
    C --> D[Deploy anywhere]

Raw syntax:

<pre class="mermaid">graph TD
    A[Write Markdown] --> B[Run docanvil build]
    B --> C[Static HTML site]
    C --> D[Deploy anywhere]</pre>

Mermaid supports many diagram types including flowcharts, sequence diagrams, class diagrams, state diagrams, Gantt charts, and more. See the Mermaid documentation for the full syntax reference.

Configuration

Mermaid is enabled by default. Disable it by setting enabled = false under [charts] in docanvil.toml. When disabled, :::mermaid blocks render as preformatted text. See Configuration for details.

Nesting Directives

When nesting directives, use more colons on the outer fence to distinguish it from inner closings. The ::::tabs (four colons) and :::tab (three colons) pattern is the primary example of this:

<div class="tabs">
<div class="tab-headers">
  <button class="tab-header active" data-tab="0">First</button>
  <button class="tab-header" data-tab="1">Second</button>
</div>
<div class="tab-content active" data-tab="0">
<p>Content here.</p>
</div>
<div class="tab-content" data-tab="1">
<p>Content here.</p>
</div>
</div>

The outer directive uses 4 colons (::::) while the inner ones use 3 (:::). The closing fence must match the exact number of colons used in the opening fence.

Unknown Directives

If you use a directive name that doesn't match a built-in component, the content is wrapped in a <div> with the directive name as the class:

<div class="custom-block">
<p>This becomes a <code><div class="custom-block extra"></code>.</p>
</div>

This lets you create custom styled blocks using your own CSS.

Summary

Component Directive Key Attribute Default
Note :::note title "Note"
Warning :::warning title "Warning"
Tabs ::::tabs + :::tab title (on tab) "Tab 1", "Tab 2", ...
Code Group :::code-group (none) Language name from code fence
Mermaid :::mermaid (none) Renders diagram via Mermaid.js

Note

Components are processed before Markdown rendering. This means you can use bold, italic, links, code, and other Markdown formatting inside any component.