Authoring Rich Content

This how-to guide provides copy-ready recipes for authoring documentation pages in Supa Maven Skin using standard Markdown (.md), embedded HTML, and Velocity-preprocessed Markdown (.md.vm).


Choosing Markdown (.md) vs. Velocity Templates (.md.vm)

Doxia 2.0 supports two ways to author Markdown pages in src/site/markdown/:

File Extension Processing Pipeline Best For
page.md CommonMark → HTML + Furo DOM transforms Fast, clean prose using :bi-...: icon shortcodes, > [!NOTE] admonitions, .supa-tabs, .supa-accordion, and embedded Bootstrap 6 HTML.
page.md.vm Apache Velocity → CommonMark → HTML + Furo DOM transforms Pages that need live Maven POM variables (${project.version}, ${project.groupId}, ${project.properties.getProperty("...")}) or Velocity helper macros (#bi, #bsAlert, #bsBadge, #bsCard, #bsCardGridStart, #bsGuideCard, #bsCardGridEnd).

Rules for .md.vm Files and Embedded HTML

  1. Global Skin Macros in .md.vm: Supa Maven Skin automatically registers its Velocity helper macros (#bi, #bsAlert, #bsBadge, #bsCard, #bsCardGridStart, #bsGuideCard, #bsCardGridEnd) globally via site-macros.vm so they can be called directly in .md.vm pages.
  2. Escaping ## Headings in .md.vm: Because ## denotes a single-line comment in Apache Velocity, wrap level-2+ Markdown heading hashes in Velocity's unparsed block syntax (#[[##]]# Section Heading or #[[###]]# Subsection) inside .md.vm files so Velocity passes ## / ### through to the Markdown parser.
  3. Keeping Multi-Line HTML Blocks Contiguous: In CommonMark (Doxia 2.0), a blank line inside a raw HTML <div>...</div> block ends the HTML block early. Keep multi-line HTML component wrappers free of internal empty lines (use &#10; if you need a blank line inside an HTML <pre><code> block).

Using Velocity Helper Macros (#bsBadge, #bsCard, & #bsGuideCard)

In .md.vm pages, #bsBadge( $theme $variant $text ), #bsCard( $title $subtitle $body $footer ), and #bsCardGridStart / #bsGuideCard / #bsCardGridEnd generate isolated .not-prose Bootstrap 6 components that can interpolate Maven properties:

v0.2.0 Stable API JDK 21+
Supa Maven Skin
io.github.mepcotterell:supa-maven-skin

Zero-config Sphinx Furo aesthetics powered by Bootstrap 6.

#bsBadge( "primary" "" "v${project.version}" )
#bsBadge( "success" "subtle" "Stable API" )
#bsBadge( "info" "outline" "JDK 21+" )

#bsCard(
  "${project.name}"
  "${project.groupId}:${project.artifactId}"
  "Zero-config Sphinx Furo aesthetics powered by Bootstrap 6."
  "MIT License"
)

#bsCardGridStart( "" )
#bsGuideCard( "col-12 md:col-6" "rocket-takeoff" "primary" "getting-started.html" "Quickstart Tutorial" "Tutorial" "Step-by-step guide to configuring <code>pom.xml</code> and <code>site.xml</code>." )
#bsCardGridEnd()

Writing Admonitions and Alerts

Admonitions

Supa Maven Skin supports all 12 Sphinx Furo admonition types across 6 semantic categories, each rendered with a Bootstrap Icons glyph (<i class="bi bi-... supa-admonition-icon" aria-hidden="true"></i>), tinted header bar, and colored left accent border. Any text after the [!...] marker on the first line becomes a custom title, and nested blockquotes (> > [!WARNING]) are automatically transformed into nested admonitions. Inline Markdown such as code spans and emphasis works in custom titles too.

Select a category below to preview the rendered admonitions and copy their Markdown syntax:

[!NOTE] Renders with bi-info-circle and the Info palette tokens. Adapts across all 6 WCAG 2.2 AA & AAA color schemes.

[!SEEALSO] Renders with bi-arrow-up-right-circle for cross-references ([!SEE-ALSO] is also supported). See the Kitchen Sink for all 12 types on one page.

> [!NOTE]
> Renders with `bi-info-circle` and the **Info** palette tokens.

> [!SEEALSO]
> Cross-reference related sections or external docs (`[!SEE-ALSO]` also works).

[!TIP] Custom Admonition Title Renders with bi-lightbulb. Provide text immediately after [!TIP] on the first line to override the default heading.

[!HINT] Renders with bi-question-circle and the Success / Tip palette tokens for gentle guidance or troubleshooting hints.

> [!TIP] Custom Admonition Title
> Provide text immediately after `[!TIP]` on the first line to override the default heading.

> [!HINT]
> Gentle guidance or troubleshooting hints (`bi-question-circle`).

[!IMPORTANT] Renders with bi-fire and the Important / Accent palette tokens to highlight key requirements.

[!ADMONITION] Custom Admonition Heading Renders with bi-card-text — equivalent to Sphinx's generic .. admonition:: Title directive.

> [!IMPORTANT]
> Highlights essential requirements or prerequisites (`bi-fire`).

> [!ADMONITION] Custom Admonition Heading
> Equivalent to Sphinx's generic `.. admonition:: Title` directive (`bi-card-text`).

[!WARNING] Renders with bi-exclamation-triangle and the Warning palette tokens for configuration pitfalls or breaking changes.

[!CAUTION] Renders with bi-lightning-charge and the Warning palette tokens when advising extra care.

> [!WARNING]
> Warns readers about potential configuration pitfalls (`bi-exclamation-triangle`).

> [!CAUTION]
> Advises caution before changing sensitive parameters (`bi-lightning-charge`).

[!ATTENTION] Renders with bi-exclamation-diamond and the Danger / Error palette tokens.

[!DANGER] Renders with bi-lightning-charge-fill for destructive actions or data-loss risks.

[!ERROR] Renders with bi-x-octagon to document failure modes or error states.

> [!ATTENTION]
> Demands immediate attention before proceeding (`bi-exclamation-diamond`).

> [!DANGER]
> Alerts readers to destructive actions or data-loss risks (`bi-lightning-charge-fill`).

> [!ERROR]
> Documents known error states or failure modes (`bi-x-octagon`).

[!TODO] Renders with bi-check2-square and neutral Todo tokens for tracking upcoming tasks.

> [!TODO]
> Renders with `bi-check2-square` for tracking upcoming tasks.

Bootstrap 6 Semantic Alerts

When you need a Bootstrap 6 .alert banner (supporting all 8 .theme-* colors and optional dismiss buttons), you can use the GFM blockquote shorthand, raw HTML, or the #bsAlert Velocity macro:

[!ALERT:primary dismissible] Release Ready Use [!ALERT:theme dismissible] in Markdown or #bsAlert in Velocity.

> [!ALERT:primary dismissible] Release Ready
> Use `[!ALERT:theme dismissible]` in Markdown or `#bsAlert` in Velocity.
#bsAlert( "primary" "Release Ready" "Use #bsAlert in Velocity templates." true )
<div class="alert theme-primary not-prose" role="alert">
  <div class="flex-grow-1">
    <div class="alert-heading fw-semibold mb-1">Release Ready</div>
    <div>Standard Bootstrap 6 alert markup.</div>
  </div>
  <button type="button" class="btn-close ms-auto" data-bs-dismiss="alert" aria-label="Close"></button>
</div>

Adding Bootstrap Icons

Supa Maven Skin bundles 2,000+ Bootstrap Icons offline (bootstrap-icons.woff2). You can insert icons using Markdown shortcodes, the #bi Velocity macro, or HTML <i> tags.

:bi-rocket-takeoff text-primary fs-5: Launch :bi-check-circle-fill text-success fs-5: Verified :bi-exclamation-triangle-fill text-warning fs-5: Warning :bi-github fs-5: GitHub

1. Markdown Shortcode

Write :bi-<icon-name>: anywhere in prose, table cells, headings, or lists. You can optionally append space-separated utility classes (such as text-primary, text-success, fs-5, me-1) before the closing colon:

- :bi-rocket-takeoff: Basic decorative icon
- :bi-check-circle-fill text-success fs-5: Icon with color and font-size utilities
- :bi-github me-1: Icon with right margin inside a link

[!NOTE] Code Block Safety Shortcodes inside inline `code` and <pre><code> blocks are automatically ignored and left untouched as literal text.

2. Velocity Macro

In .md.vm pages, use #bi( $name $extraClasses $ariaLabel ):

## Decorative icon (renders aria-hidden="true")
#bi( "rocket-takeoff" "" "" ) Launch

## Icon + extra CSS utility classes (renders aria-hidden="true")
#bi( "check-circle-fill" "text-success fs-5" "" ) Verified

## Semantic accessible icon (renders role="img" aria-label="Accessible")
#bi( "universal-access-circle" "text-info fs-5" "Accessible" ) WCAG 2.2 AAA

3. Raw HTML

<i class="bi bi-rocket-takeoff text-primary fs-5" aria-hidden="true"></i> Launch

Styling Code Blocks

Supa Maven Skin bundles Highlight.js offline for 18+ JVM, web, and configuration languages (java, kotlin, groovy, xml, html, velocity/vm, typescript/ts, javascript/js, json, yaml/yml, properties, sql, bash/sh/shell, python/py, css, scss, markdown/md, diff, and plaintext/text) and attaches a one-click Copy to clipboard button to every <pre> block.

File Header Bars & Line Numbers

To add a file-path header bar (.supa-code-header) or line numbers (.has-line-numbers) to a code block, use an HTML <pre> block with data-title="..." (or title="...") on <code> and class="line-numbers" on <pre>:

package io.example;

public final class Greeter {
  public static String greet(String name) {
    return "Hello, " + name + "!";
  }
}
<pre class="line-numbers"><code class="language-java" data-title="src/main/java/io/example/Greeter.java">package io.example;

public final class Greeter {
  public static String greet(String name) {
    return "Hello, " + name + "!";
  }
}</code></pre>

Unified Diffs

Use a standard ```diff fenced code block to highlight additions (+) and removals (-) with palette-aware semantic colors:

```diff
 <skin>
-  <groupId>org.apache.maven.skins</groupId>
-  <artifactId>maven-fluido-skin</artifactId>
+  <groupId>io.github.mepcotterell</groupId>
+  <artifactId>supa-maven-skin</artifactId>
 </skin>
```

Creating Synchronized Content Tabs

Wrap child <div title="Tab Label"> panels inside <div class="supa-tabs" title="group-key"> to create ARIA-compliant tablists.

  • Synchronization: Every .supa-tabs container sharing the same title (or data-tab-group) attribute automatically synchronizes across the page and persists the user's preferred tab in localStorage (supa-tab-sync).
  • Keyboard Navigation: Supports ArrowLeft, ArrowRight, Home, and End keys out of the box.
<dependency>
  <groupId>io.github.mepcotterell</groupId>
  <artifactId>supa-maven-skin</artifactId>
  <version>0.2.0</version>
</dependency>
<skin>
  <groupId>io.github.mepcotterell</groupId>
  <artifactId>supa-maven-skin</artifactId>
  <version>0.2.0</version>
</skin>
<div class="supa-tabs" title="build-tool-demo">
  <div title="Maven (pom.xml)">
    <pre><code class="language-xml">&lt;dependency&gt;
  &lt;groupId&gt;io.github.mepcotterell&lt;/groupId&gt;
  &lt;artifactId&gt;supa-maven-skin&lt;/artifactId&gt;
  &lt;version&gt;0.2.0&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
  </div>
  <div title="Site Descriptor (site.xml)">
    <pre><code class="language-xml">&lt;skin&gt;
  &lt;groupId&gt;io.github.mepcotterell&lt;/groupId&gt;
  &lt;artifactId&gt;supa-maven-skin&lt;/artifactId&gt;
  &lt;version&gt;0.2.0&lt;/version&gt;
&lt;/skin&gt;</code></pre>
  </div>
</div>

Building Accordions and Steppers

Declarative Accordions (.supa-accordion)

Wrap <div title="Section Heading"> items inside <div class="supa-accordion">. Add class="open" to any item that should be expanded initially:

Set <colorScheme>modus</colorScheme> inside <custom><supaSkin> in your src/site/site.xml.

Yes. Bootstrap 6 CSS/JS, Bootstrap Icons fonts, and Highlight.js are all bundled directly inside the skin JAR.

<div class="supa-accordion">
  <div title="How do I set a default color scheme?" class="open">
    <p>Set <code>&lt;colorScheme&gt;modus&lt;/colorScheme&gt;</code> inside <code>&lt;custom&gt;&lt;supaSkin&gt;</code> in your <code>src/site/site.xml</code>.</p>
  </div>
  <div title="Does Supa Maven Skin work offline?">
    <p>Yes. Bootstrap 6 CSS/JS, Bootstrap Icons fonts, and Highlight.js are all bundled directly inside the skin JAR.</p>
  </div>
</div>

Declarative Steppers (ol.supa-stepper)

Use <ol class="supa-stepper" title="2"> where title specifies the 1-based active step index (all steps up to that number are styled as active/completed):

  1. Configure pom.xml
  2. Author Markdown
  3. Deploy Site
<ol class="supa-stepper" title="2">
  <li>Configure pom.xml</li>
  <li>Author Markdown</li>
  <li>Deploy Site</li>
</ol>

Rendering Mermaid Diagrams and KaTeX Math

When <mermaid>auto</mermaid> and <katex>auto</katex> are enabled in site.xml (the default), Supa Maven Skin inspects each page at load time and only fetches Mermaid or KaTeX when diagrams or math expressions are present on that page. The default builds come from jsDelivr, pinned to exact versions and verified with Subresource Integrity; to serve them from your own site instead, follow Self-Hosting Mermaid & KaTeX.

Mermaid Diagrams

Use a standard fenced ```mermaid code block. The diagram automatically re-renders when the user toggles between Light and Dark themes:

```mermaid
flowchart LR
    A["src/site/markdown/*.md"] --> B["Doxia 2.0"]
    B --> C["Supa Maven Skin (site.vm)"]
    C --> D["Responsive HTML5 Site"]
```

KaTeX Mathematical Notation

Write inline math between single $...$ delimiters (such as $O(n \log n)$) and display equations between $$...$$ delimiters:

Inline complexity $O(n \log n)$ or display block:

$$
\hat{y} = \sigma\left( \sum_{i=1}^{d} w_i x_i + b \right)
$$

Self-Hosting Mermaid & KaTeX

Serve both libraries from your own site when you cannot depend on jsDelivr, for example on an intranet or under a strict Content Security Policy.

  1. Copy the classic builds into src/site/resources/vendor/, keeping KaTeX's dist/ layout so the stylesheet finds fonts/ and the loader finds ../katex.min.js:

    mkdir -p src/site/resources/vendor/mermaid src/site/resources/vendor/katex
    curl -fsSL -o src/site/resources/vendor/mermaid/mermaid.min.js \
      https://cdn.jsdelivr.net/npm/mermaid@11.17.2/dist/mermaid.min.js
    npm pack katex@0.16.47 --pack-destination /tmp && tar -xzf /tmp/katex-0.16.47.tgz -C /tmp
    cp -R /tmp/package/dist/katex.min.js /tmp/package/dist/katex.min.css \
      /tmp/package/dist/fonts /tmp/package/dist/contrib src/site/resources/vendor/katex/
    
  2. Point the overrides at root-relative paths (or absolute https:// URLs):

    <supaSkin>
      <mermaidCdnUrl>/my-project/vendor/mermaid/mermaid.min.js</mermaidCdnUrl>
      <katexCssCdnUrl>/my-project/vendor/katex/katex.min.css</katexCssCdnUrl>
      <katexJsCdnUrl>/my-project/vendor/katex/contrib/auto-render.min.js</katexJsCdnUrl>
    </supaSkin>
    

    Replace /my-project/ with the path your site is deployed under (/ for a site at the domain root).

[!WARNING] Avoid document-relative values such as vendor/mermaid/mermaid.min.js. Classic <script src> and <link href> URLs resolve against the current page, so they break on pages in subdirectories (for example, pages from src/site/markdown/guides/*.md). .mjs URLs loaded with import() resolve against js/supa-maven-skin.min.js instead and must start with ./, ../, or /. Root-relative and absolute URLs resolve the same way in all three cases.

Self-hosted URLs load without Subresource Integrity, because the skin only knows the hashes of its pinned defaults. The Configuration Reference lists every loading option, and Content Security Policy lists the origins to allow when you keep the jsDelivr defaults.

Documentation channels

Group project, version, and API links in a named navigation landmark. The native version disclosure works without JavaScript:

<nav class="supa-documentation-channels" aria-label="Documentation channels">
<a href="index.html" aria-current="page">Project home</a>
<a href="https://example.org/versions/">All versions</a>
<a href="api/index.html">API Reference</a>
<details class="documentation-version-picker">
<summary>Version: Current release</summary>
<ul>
<li><a href="dev/index.html">Development</a></li>
<li><a href="release/index.html">Current release</a></li>
</ul>
</details>
</nav>

Replace destinations and labels with your own. Set aria-current="page" only on a link to the current page. The skin does not discover versions or rewrite links. The component works inside or outside article prose, inherits all six palettes and light, dark, or automatic polarity, and is hidden when printed. On phones, the version list expands in the page flow; long labels wrap.

The existing .documentation-channels class is an equivalent alias. When adopting this in a site such as the tracer, remove the old channel and version-picker rules from consumer CSS (including dependencies.css). Keep unrelated dependency-table styles. Later consumer CSS can otherwise override the skin's layout and colors.