This is the multi-page printable view of this section. .
Components
- 1: Code blocks and Code Groups
- 2: Badge
- 3: Kbd
- 4: Fields and Field
- 5: FileTree
- 6: Gallery
- 7: Image Zoom
- 8: Shortcodes
- 9: Diagrams and formulae
- 10: Apache ECharts
- 11: Infographics with AntV
OINK’s components fall into two groups: the writing primitives you use every day, and the larger components you need for specific situations. Complete multi-page publishing workflows live under Scenario components.
They all follow one contract: semantic HTML, no JavaScript for the non-interactive ones, a defined presentation in print and Markdown output, and a failed build rather than silent degradation when a parameter is invalid.
Everyday writing
| Component | Purpose | Needs JS |
|---|---|---|
| Code blocks and groups | Filenames, copy, collapse, synchronized tabs | On pages with code |
| Badge | Status labels such as Beta or Deprecated | No |
| Kbd | Keyboard shortcuts | No |
| Fields | Configuration, parameter, and response descriptions | No |
| FileTree | Directory structures | No |
Media
| Component | Purpose | Needs JS |
|---|---|---|
| Gallery | A grid of related images | Reuses the zoom runtime |
| Image zoom | Enlarging screenshots and diagrams | Per page when enabled |
Layout and structure
| Component | Purpose |
|---|---|
| Tabs, cards, steps, and more | Tabbed panes, cards, steps, disclosures, carousels |
Diagrams and visualization
| Component | Purpose | Runtime |
|---|---|---|
| Diagrams and formulae | Mermaid, KaTeX, Markmap, PlantUML | Per page |
| ECharts | Interactive data charts | Per page |
| Infographic | Process and information graphics | Per page |
Scenario workflows
| Scenario | Coordinated capabilities |
|---|---|
| Sequential reading | Pager order, head relations, local mathematics |
| Releases and downloads | Facts, checksums, rolling and pinned channels |
| Landing pages | Full-width shell, local data, 21 reusable sections |
| Book publishing | Numbered media, xrefs, indexes, whole-Book print |
These scenarios compose several primitives with navigation, data, and output rules. Their pages are the authoritative adoption guides; do not infer a scenario contract from one shortcode example alone.
Shared contract
- Standard shortcode notation
{{</* … */>}}. - Nested names (
filetree/folder,gallery/image,field) are valid only inside their parent. - An invalid parameter fails the build with its source position; strict failure beats silent degradation.
- Only Fields descriptions accept Markdown; every other public string parameter is plain text.
- A page that does not use a component never receives its runtime.
1 - Code blocks and Code Groups
OINK enhances Hugo’s ordinary fenced code blocks without replacing Chroma or requiring a browser highlighter. The server emits the complete code and shell; small page-scoped scripts only enable Copy, visual collapse, and tab state.
Enhanced fences
Add metadata in Hugo’s fence attribute list. A fence without attributes still
receives the same responsive shell and its normal Copy default. filename adds
a visible header; title is its compatible alias, and setting both is a build
error. With neither, OINK uses a compact overlay instead of an empty title row.
Authoring
Live result
Rendered result
This block combines a filename, inline line numbers, a stable root ID, line
links, and highlighted source lines. Line numbers begin at 12, while hl_lines
still addresses the source lines inside the fence:
Shell parameters
| Attribute | Values | Behavior |
|---|---|---|
filename |
string | Visible filename and accessible group name |
title |
string | Alias for filename on an ordinary fence |
copy |
all, command, false, or true |
Copy policy; true is shorthand for all |
wrap |
true or false |
Visually wrap long lines without changing text |
collapse |
positive integer | Initial maximum number of visible source lines |
label |
string | Accessible label when no filename is suitable |
id |
string | Stable public block ID and line-anchor prefix |
Hugo generic class, safe data-*, aria-*, and global attributes remain on
the .td-code root. Names beginning with data-td-code and data-language are
reserved. OINK rejects event-handler and inline-style attributes. Use label to
override a filename-derived accessible name; a generic aria-label together
with label or filename is a build error.
Hugo options
The render hook continues to pass these options to Hugo:
lineNos,lineNoStart, andanchorLineNos;hl_lines;tabWidthandstyle.
Class-based Chroma markup remains inside .highlight and .chroma, so existing
token-level overrides keep working. The new stable outer element is .td-code;
sites using direct-child selectors such as .td-content > .highlight should
update those selectors.
The visible language label normalizes the common bash, sh, and shell lexer
aliases to BASH. The original lexer value is still passed to Chroma and
retained in data-language.
Diffs deliberately use Chroma’s standard diff lexer rather than a custom
transformer:
Authoring
Rendered result
Copy semantics
Ordinary source defaults to copy="all". console and shell-session default
to copy="command": only lines carrying Chroma prompt tokens are copied, and
prompt/output tokens are excluded. Use copy="all" when a complete transcript
is intentional. command on another language is a build error.
Copy preserves indentation, internal blank lines, and Unicode, removes line
numbers, trims only trailing newline characters, and appends exactly one final
newline. A session lexer that emits no prompt token reports a localized failure
and copies nothing. Set params.disable_click2copy_chroma: true to hard-disable
Copy for the entire site.
Copy is shown as a compact icon without adjacent text. Its localized label is still exposed to assistive technology and as a hover tooltip; success and failure also change the icon and update the live status message.
For a multi-line terminal command, include the continuation prompt (normally
>) on every continued transcript line. Chroma classifies an unprompted line as
output, so copy="command" deliberately excludes it.
The Copy action on this live session copies the two commands, not the prompts or output:
Authoring
Rendered result
Wrapping and collapse
wrap=true changes presentation only; copied source is untouched. It is
incompatible with Chroma’s table line-number layout because separately wrapped
gutter and source cells would drift. Use inline line numbers or disable wrap.
OINK fails the build instead of silently misaligning them.
collapse=N is progressive enhancement. The server always emits all source; the
browser clips only after it can measure the Nth real Chroma line. Without
JavaScript, in assistive technology, and in print, the listing remains complete.
Reduced-motion preferences disable the height animation.
The first example wraps a long value without altering copied text:
Authoring
Rendered result
The second emits all lines on the server but initially shows six in a browser:
Authoring
Rendered result
Stable IDs and line links
Set a page-unique explicit id when publishing line-number links. IDs cannot
contain ASCII whitespace or control characters and cannot collide with another
code component’s generated viewport, tab, panel, title, or line-anchor ID. OINK
reports any such collision as a build error:
Authoring
Rendered result
OINK derives unique line-anchor prefixes from that ID. Generated IDs are safe inside a page but depend on the block ordinal and are not a permalink contract; inserting an earlier fence can change them.
Code Groups
Use code-group when examples are alternatives rather than independent tabs:
Authoring
Rendered result
code-tab contains raw code, not Markdown. OINK removes the framing newline and
closing-shortcode indentation while preserving all source whitespace inside.
Because a Markdown formatter can otherwise reflow that raw body, put
<!-- prettier-ignore --> immediately before each live code-group when using
Prettier, as in the examples below.
Group and tab parameters
Every group requires a page-unique lower-case id. Optional sync, persist,
label, copy, wrap, and collapse values apply to the group; the last
three are inherited defaults. persist defaults to true.
Every child requires a plain-text title and stable lower-case value. lang
defaults to text; selected, copy, wrap, collapse, and the Hugo
highlight options can override group defaults. A group cannot be empty, repeat a
value, or contain more than one selected=true child. Filenames are omitted
inside groups because the tab itself identifies the example.
Selection, sync, and persistence
A selected panel has the public hash #<group-id>-<value>, for example
#install-client-pnpm. Initial selection priority is URL hash, saved value,
selected=true, then the first child.
Groups sharing sync select the same value when that value exists in each
group; a peer missing it stays unchanged. A user selection updates the hash with
replaceState and saves the value when persistence is enabled. Visiting a
shared hash activates the requested examples without overwriting the reader’s
saved preference. persist=false disables storage, not in-page synchronization.
Live synchronized groups
The rendered install group above and the run group below share the same sync
key. Choose a package manager in either group and the other follows. The first
group’s npm, pnpm, and
yarn panels also have shareable hashes.
Authoring
Rendered result
Output and compatibility
Print hides controls and tab rows, expands every listing, and places each group title before its code. Markdown output turns every grouped or legacy tab into a readable titled fence and chooses a longer delimiter when source contains backticks. Feeds and other non-interactive outputs use stacked examples. Pages without applicable code or tabs do not load their runtimes.
Existing tabpane source and its td-tp-persist:* browser keys remain
compatible. Prism remains a legacy alternative and does not receive Enhanced
Code Blocks or Code Groups. Specialized mermaid, math, chem, markmap,
and plantuml hooks continue using their own renderers.
2 - Badge
Use Badge to place a short status beside a feature, option, or release name. The author chooses a semantic tone; Oink maps it to theme tokens that retain contrast in light and dark modes.
When to use
Badge works well for lifecycle states such as Beta, New, Experimental, and Deprecated. Keep the text explicit: color supplements the label and never replaces it. Use ordinary prose or an alert when the status needs explanation, instructions, or a deadline.
Quick start
Source
Rendered result
Neutral Info Supported Beta Deprecated v0.3
The final badge is a link. The others are static inline labels.
Parameters
Badge parameters
-
text,string, required A nonempty string shown to the reader.
-
tone,enum, default:neutral One of
neutral,info,success,warning, ordanger.-
link,URL A validated internal, relative, HTTP(S), or
mailto:destination. When set, the Badge becomes a link.-
outline,boolean, default:true Set to
falseto select the filled treatment.
Pass booleans without quotes. For example, use outline=false, not
outline="false". Unknown parameters and invalid tone or link values stop the
Hugo build and report the source position.
Semantics and fallback
A static badge renders as a span; a linked badge renders as an a. Oink does
not make it a live status region, so adding a badge does not create unexpected
screen-reader announcements. Its visible text remains present in every output:
Markdown uses emphasized text (and preserves the link), while print and RSS use
static inline content. Badge loads no JavaScript.
Deliberate limits
Badge does not accept arbitrary colors, CSS classes, styles, or event handlers.
Version one also has no icon parameter. Use a concise textual label now;
content icons can receive a separate public API after their naming, licensing,
accessibility, and Markdown fallback contracts are settled.
3 - Kbd
Use Kbd to distinguish literal keys and shortcuts from surrounding prose. It renders semantic HTML, remains readable in Markdown and print, and needs no JavaScript.
When to use
Use Kbd for keys the reader should press, including multi-key shortcuts. Use inline code for commands, option names, or text the reader should type; those are not physical or virtual keys.
Quick start
Source
Rendered result
Press Ctrl with K to open search. Use ⌘ with Shift with P to open the command palette, or press Alt with Enter to apply an action.
Interface
Kbd accepts one or more nonempty positional strings:
It has no named parameters. Quotes are required because every key must be a string. Missing keys, blank strings, named arguments, or non-string values stop the build with the source position.
Use the label printed on the relevant platform when the distinction matters. For cross-platform instructions, name the platform in prose instead of placing alternatives inside one key sequence.
Semantics and fallback
HTML contains one nested kbd element per key. Visual plus signs are hidden
from assistive technology; a localized word separates the keys for screen
readers. Markdown, print, and RSS use an unambiguous sequence such as
Ctrl + K. The instruction remains complete when CSS or JavaScript is absent.
Deliberate limits
Kbd represents simultaneous key sequences only. It does not model menus, gesture input, key remapping, platform detection, or an interactive shortcut recorder. Explain sequential actions in prose: “press Escape, then Enter.”
4 - Fields and Field
Use fields with field children to document named values and their metadata.
The component favors a responsive definition list over a wide fixed table, so
long names and descriptions remain usable on narrow screens.
When to use
Fields works for configuration keys, command or API parameters, object properties, and response members. Use a regular Markdown table when readers must compare many rows across the same columns. Use prose when the entries are steps rather than definitions.
Quick start
Source
Rendered result
Search configuration
-
offlineSearch,boolean, required , default:true Builds a local search index and command palette.
-
offlineSearchMaxResults,integer, default:10 Limits the number of visible results while retaining keyboard navigation.
-
searchPlaceholder,string, default:"" Sets optional placeholder text. The empty-string default remains visible.
-
theme.components.media.previewMaximumWidthInCharacters,string, default:auto This deliberately long field name demonstrates wrapping without widening the page.
Descriptions accept Markdown, including links, emphasis, inline code, and lists. Keep each description self-contained because Markdown output presents each one beneath its metadata.
Fields parameters
fields parameters
-
label,string A nonempty visible label associated with the complete definition list.
The container must have at least one direct field child. Text or another
shortcode directly inside fields stops the build.
Field parameters
field parameters
-
name,string, required A nonempty string identifying the field.
-
type,string A nonempty type label such as
boolean,string[], orduration.-
required,boolean, default:false When true, adds the literal
requiredmarker. The marker is untranslated API vocabulary.-
default,scalar A string, boolean, integer, or floating-point value.
false,0, and""are preserved.
Every field also requires a nonempty body. It must be a direct child of
fields. Parameter names and types are validated at build time, and unknown
parameters are errors.
Semantics and fallback
HTML uses dl, dt, and dd. Each entry stacks a header row — the field name
followed by its type, required, and default markers — above the
description, and hairline dividers separate entries. The required and
default labels stay in English in every locale. The optional label names the
definition list for assistive technology. Markdown emits an indented bullet list
with code-formatted names, types, and defaults; print and RSS retain every
definition. No JavaScript is loaded.
Deliberate limits
Version one does not implement kind, deprecated, since, location, or
per-field links. It also does not parse TypeScript or an API schema inside Hugo.
An external generator may emit these shortcodes later, keeping compiler and
schema runtimes outside the theme while preserving this output contract.
5 - FileTree
Use FileTree to explain the part of a repository or directory layout that matters to the reader. Folders use native disclosure controls in interactive HTML; every output retains the complete nested structure.
When to use
FileTree works best for curated structures in setup guides, architecture overviews, and contribution instructions. Use a code block for literal command output that should be copied verbatim. Describe generated or highly dynamic trees in prose instead of committing a large snapshot that will quickly drift.
Quick start
Source
Rendered result
Repository structure
-
content
- _index.md
-
docs
- operations-and-troubleshooting
- configuration.md
-
blog
- release.md
- hugo.yml
The blog folder starts closed. Activate its summary with a pointer, Enter, or
Space to reveal the child file; this behavior comes from the native details
element rather than a custom script.
Root parameters
filetree parameters
-
label,string A nonempty visible label associated with the root list.
The root accepts only direct filetree/folder and filetree/file children. Add
at least one meaningful entry rather than publishing an empty tree.
Folder and file parameters
filetree/folder parameters
-
name,string, required A nonempty visible directory name.
-
open,boolean, default:false Controls the initial interactive HTML state.
filetree/file parameters
-
name,string, required A nonempty visible file name.
-
link,URL A validated internal, relative, HTTP(S), or
mailto:destination.
A folder can contain folders and files recursively. A file cannot contain children. Unknown parameters, text between children, or a child outside an allowed parent stops the build with its source position.
Semantics and fallback
The structure is a nested ul. Interactive folders add native details and
summary; Oink deliberately does not declare role="tree", because that ARIA
widget would require a complete arrow-key navigation model. Print and RSS expand
all folders. Markdown becomes a nested list with linked file names where
applicable. No JavaScript is loaded.
Deliberate limits
FileTree is author-controlled and never reads a local directory during a Hugo build. This keeps builds safe and reproducible. Version one also has no public badge or icon parameters for entries; the built-in folder and file glyphs are presentational theme details, not content APIs.
6 - Gallery
Gallery groups related images in a responsive grid. It is static-first: images, alternative text, and captions remain available without JavaScript. When Image Zoom is enabled, Gallery reuses the same dialog instead of loading another lightbox.
When to use
Use Gallery to compare a small set of screenshots, states, or related visual examples. Use a single image when sequence and comparison do not matter. Use Carousel when the content intentionally needs slide navigation and hiding noncurrent items is acceptable.
Quick start
Source
Rendered result
OINK screenshots and layout examples
-
A global image resource with known intrinsic dimensions. -
A deliberately long caption demonstrates wrapping on desktop and mobile without covering an adjacent image or widening the document. -
The responsive grid reduces its effective column count on a narrow viewport.
This page enables Image Zoom. Activate any image to inspect it in the shared dialog. With JavaScript disabled, the same three figures remain visible in the same reading order.
Gallery parameters
gallery parameters
-
columns,integer, default:2 An unquoted value from
1through4; this is the desktop maximum.-
label,string A nonempty visible label associated with the gallery list.
The container requires at least one direct gallery/image child and accepts no
ordinary body text. Small viewports reduce the effective column count without
changing the requested desktop maximum.
Image parameters
gallery/image parameters
-
src,image URL, required A validated page, global, static, or remote image URL.
-
alt,string, required Meaningful nonempty plain text describing the image.
-
caption,string Nonempty plain text shown below the image.
Gallery records intrinsic width and height for local Hugo resources when available and adds lazy loading. It accepts a remote source URL but never downloads that image during the Hugo build, so remote dimensions remain unknown. Captions do not render Markdown; keep them concise and move rich explanation into nearby prose.
Semantics and fallback
HTML uses a labeled ul of figure, img, and optional figcaption elements.
Each image retains its own alternative text; the gallery label names the
collection. Markdown emits ordinary images followed by italic captions. Print
and RSS render sequential static figures. Gallery has no private JavaScript
runtime: it only marks its images for Image Zoom when that page-level feature is
enabled.
Deliberate limits
Gallery does not crop images to a forced aspect ratio, reorder them by breakpoint, hide overflow, or provide slide navigation. It has no Gallery-specific lightbox. These constraints preserve document order and keep the fallback complete.
7 - Image Zoom
Image Zoom progressively enhances eligible content images with one native dialog. It is useful for screenshots and architecture diagrams whose details may be hard to read at the document width. The original image remains complete when JavaScript or dialog support is unavailable.
When to use
Enable zoom when a reader benefits from seeing the source image at a larger size. Prefer a purpose-built crop or a clearer diagram when enlargement does not solve the readability problem. Decorative icons, logos embedded in prose, and linked thumbnails should retain their existing behavior.
Enable the feature
Image Zoom is disabled by default. Enable it for the whole site in Hugo configuration:
A page can override the site value in its front matter with the same structure. Use a real boolean:
Oink only includes the JavaScript runtime and dialog on an enabled page that has an eligible image. Enabling the switch alone adds no runtime to a text-only page.
Quick start
Source
Ordinary standalone Markdown images are eligible. The named imgproc form is
useful when Oink should generate a smaller preview but open the original:
Rendered result
Activate the image with a pointer, Enter, or Space. Close the dialog with Escape, the visible close button, or the backdrop.
The document displays a processed preview. Image Zoom opens the original resource, and closing the dialog restores focus to this trigger.
An image inside a link is deliberately skipped and remains a link:
Eligible images
Oink enhances a meaningful image when all of these conditions hold:
- The image is standalone in a paragraph or figure, or Gallery marks it explicitly.
- It has a nonempty
altvalue and usable source. - It is not inside a link, button, or element marked
data-no-zoom. - It is not marked
aria-hidden="true",role="presentation", orrole="none".
Inline images among text and empty-alt decorative images are skipped. Authors
can add data-no-zoom to an image or ancestor in trusted HTML when an otherwise
eligible image should not open.
Named imgproc parameters
Named imgproc parameters
-
src,resource path, required An exact page or global image resource.
-
command,enum, required One of
Fit,Resize,Fill, orCrop.-
options,string, required Nonempty Hugo image-processing options, such as
640x320.-
alt,string Meaningful alternative text. It is required for content images and omitted only with
decorative=true.-
decorative,boolean, default:false When true,
altmust be absent and Image Zoom is suppressed.
The optional shortcode body is a Markdown caption. The historical three-value
positional imgproc form remains compatible, but new content should use the
named form so alternative text is enforced at build time.
Interaction and fallback
Progressive enhancement wraps an eligible image in a real button with
aria-haspopup="dialog". The native dialog moves focus to its close button,
supports Escape, copies the image’s alternative text and direct caption, and
restores focus after closing. Without JavaScript or HTMLDialogElement, the
image and caption remain ordinary static content. Markdown, print, and RSS do
not include dialog controls.
Deliberate limits
Version one does not implement dragging, panning, wheel zoom, editing, or previous and next image navigation. It also never downloads a remote image at build time. Use Gallery to group related images while reusing this same dialog.
8 - Shortcodes
Shortcodes add behavior that ordinary Markdown cannot express. OINK retains the core Docsy components and adds locally served charts, terminal recordings, infographics, carousels, cards, and disclosure widgets. Browser runtimes load only on pages that use them.
Prefer Markdown for headings, prose, lists, links, tables, and images. A shortcode becomes part of the content API: changing its name or parameters can break every page that calls it.
Shortcode delimiters
Hugo supports two forms:
{{< name >}}uses standard delimiters and passes inner content as-is;{{% name %}}uses Markdown delimiters and renders inner Markdown in the surrounding content context.
Use the form documented for the component. Nesting, indentation, and blank lines
matter, especially inside lists and blockquotes. In examples, the /* ... */
escape prevents Hugo from executing the displayed shortcode.
blocks/* shortcodes
Block shortcodes compose full-width landing pages. Their color argument uses
OINK/Bootstrap semantic colors or a project-defined block style. Their height
argument accepts the values documented for each block.
blocks/cover
Creates a hero from the page bundle image matching *background* and optional
*logo*:
image_anchor and logo_anchor control image cropping; byline attributes the
image. Heights are auto, min, med, max, or full. Essential hero text
must remain readable without the background.
blocks/lead
Creates a prominent introductory band:
The height accepts auto, min, med, max, or full.
blocks/section
Creates a general landing-page band:
type selects the container treatment; height uses the block height values.
Keep heading levels consistent with the page outline.
blocks/feature
Creates one feature cell, normally inside a section:
The icon is decorative; title and link text must carry the meaning.
blocks/link-down
Adds a link from one block to the next. It must be nested inside a block. Set an
explicit id when the generated target must remain stable.
Below-navbar layout correction
Blocks that begin directly below fixed navigation use
td-below-navbar/td-anchor-no-extra-offset to compensate for navbar height.
Reuse these classes rather than adding arbitrary top margins; verify direct
fragment navigation after changing navbar dimensions.
Helper shortcodes
alert
The legacy alert shortcode remains available:
color maps to a Bootstrap alert suffix. New content should generally use the
Markdown alert syntax described in
Adding Content.
Alerts, indentation, and examples
Keep the opening and closing shortcode aligned with their surrounding list or blockquote. Leave a blank line around block Markdown. If an example must show a shortcode literally, escape its delimiters rather than wrapping an active call in another component.
pageinfo
Renders an informational panel around Markdown:
Use a semantic alert for warnings; pageinfo is intended for contextual page
information.
imgproc
Processes an image from the current page bundle:
Commands are Fit, Resize, Fill, and Crop. The third argument follows
Hugo image-processing syntax. The inner text becomes a caption, and a resource
params.byline is appended when present. Always provide useful alternative or
adjacent text.
swaggerui
Embeds the locally vendored Swagger UI runtime:
Use a same-origin specification for offline and CSP-safe deployments. A remote
src is an explicit network dependency and can expose reader metadata to that
host. Only one Swagger UI instance should be placed on a page with the current
compatibility shortcode.
redoc
Embeds the locally vendored Redoc runtime:
The first argument is a page-relative, site-relative, or explicit HTTP specification. The optional second argument contains Redoc element options. Treat specification content as reviewed input and test large schemas on mobile.
iframe
Embeds another page:
Set a descriptive name, a unique id, a fallback sub message, and the
narrowest viable sandbox. The defaults support width and automatic-height
behavior, but cross-origin documents cannot always be measured. An iframe is a
security and privacy boundary, not a general layout tool.
OINK content components
The following components are additions carried by OINK. Each runtime is pinned
in VENDOR.json and loaded on demand from the same origin.
details
Creates an accessible disclosure:
closed defaults to true. Use a concise summary and do not hide mandatory
instructions inside a closed disclosure.
steps
steps presents a sequence with automatically generated numbers and a visual
guide line. Write ordinary Markdown headings and content inside the shortcode;
do not type the numbers yourself.
Create the content
Write one direct child heading for each step, followed by any Markdown content that belongs to it.
Check the sequence
Move, add, or remove whole steps. The displayed numbers update automatically.
Publish the result
Verify the sequence on narrow screens and in both color themes.
Use Markdown shortcode delimiters so Hugo renders the inner content:
Every direct child heading from h2 through h6 becomes a step. Add
class="no-step-marker" when a direct child heading is a subsection of the
current step. Keep the same heading level for peer steps, preserve a logical
page outline, and avoid nesting one steps block inside another.
asciinema
Plays an asciinema .cast recording:
The window title uses title when supplied and otherwise displays file. Other
important parameters include theme, autoplay, loop, preload, speed,
startAt, poster, cols, rows, idleTimeLimit, pauseOnMarkers,
markers, and fit (width, height, both, or none). Local recordings
can come from Hugo assets or a site-relative URL. Avoid autoplay, remove secrets
from terminal history, and provide nearby text for essential steps.
echarts
Apache ECharts is a full visualization system rather than a one-paragraph shortcode. Its advanced guide documents the wrapper, structured options, themes, responsive behavior, accessibility, and trusted callback boundary:
The shortcode body accepts a JSON or YAML options object. Use height, theme,
and full only as described in the dedicated guide.
infographic
AntV Infographic has its own advanced guide because template choice, DSL structure, themes, visual semantics, and accessibility need more than an inline example:
The shortcode body contains the Infographic DSL. Use height and full as
documented there, and keep an equivalent textual explanation beside every
essential visualization.
doc-cards and nav-cards
Both containers accept cols from 1 through 4. Their child cards accept
title, link, image, alt, icon, desc, accent, and badge:
doc-card/doc-cards share the rendering contract and suit editorial content;
nav-card/nav-cards signal navigation. Description tokens such as {version}
resolve from site parameters. Card images are lazy-loaded; supply meaningful
alt text unless the image is decorative.
doc-carousel
Places doc-card elements in a keyboard-scrollable carousel:
label names the region for assistive technology. Previous/next buttons are
localized. Do not place information only in an off-screen card; the track must
remain usable without script.
param
Prints a page parameter, falling back through Hugo’s Page.Param rules to site
configuration:
A missing parameter fails the build. Use param for scalar display values, not
for injecting unreviewed HTML. The internal _param compatibility shortcode
also performs numbered placeholder replacement for legacy content.
Tabbed panes
Tabs group equivalent representations, such as YAML/TOML/JSON configuration. They must not hide sequential steps or unrelated choices.
Selection persistence is local to the browser. persist accepts header,
lang, or disabled. The deprecated persistLang should not be used in new
content.
Shortcode details
text=true renders inner content as prose rather than highlighted code.
right=true aligns tabs to the end. langEqualsHeader=true derives language
identifiers from headers. Pane defaults can be overridden per tab.
tabpane
The parent validates boolean and persistence parameters, builds unique IDs, and ensures a selected tab. Use one disabled header tab only when it adds a useful group label.
tab
tab must be inside tabpane. It accepts header, selected, lang,
highlight, text, right, and disabled. Only one tab should be selected.
Translate reader-facing headers, but keep language identifiers stable.
Code Groups
Use code-group/code-tab for code-only alternatives that need stable public
hashes, synchronized values, and exact Copy behavior. Unlike legacy tabpane,
each child has a required machine value, and non-interactive outputs expand
every example. Read Code blocks and Code Groups
for the complete parameter and persistence contract.
Card panes
The legacy cardpane/card pair lays out Bootstrap-style cards. New navigation
surfaces should prefer OINK content cards, but existing Docsy content can keep
the compatibility component.
Shortcode card: textual content
header, title, subtitle, and footer accept rendered text. Keep equal
cards concise and avoid using cards as a replacement for headings.
Shortcode card: programming code
Set code=true and optionally lang/highlight:
Card groups
Adjacent cards in cardpane form a responsive group. Test unequal text length,
mobile stacking, code overflow, and both language variants.
Include external files
The readfile shortcode reads a repository file at build time and either
renders it as Markdown or highlights it as code. The path is relative to the
current content file unless it begins with /.
Reuse documentation
Included Markdown is not an independent published page and is exempt from the page-pair audit. If shared prose is reader-facing, create and select language-specific include files deliberately; Hugo cannot translate an include.
Installation
Keep reusable fragments under an includes/ directory near their callers.
Document ownership and avoid deep include chains: readers and reviewers should
be able to locate the source quickly.
Include code files
code=true highlights the file with lang. Never include secrets, generated
credentials, or untrusted paths.
Error reporting
A missing file fails the build. draft=true replaces that failure with a
visible draft warning, which is suitable only during authoring and must not
reach a release build.
Conditional text
conditional-text selects content using params.buildCondition:
include-if and exclude-if accept condition lists. A condition cannot appear
in both. Use the feature for genuinely different published variants, not for
language selection; multilingual content belongs in translated page files.
9 - Diagrams and formulae
OINK supports KaTeX, Mermaid, Markmap, PlantUML, and Diagrams.net. KaTeX, Mermaid, and Markmap use build-time or same-origin resources shipped with the theme. PlantUML and the Diagrams.net editor require an explicitly configured service endpoint; they do not silently default to a public service.
LaTeX support with KaTeX
KaTeX renders TeX mathematics for the web. Hugo’s embedded KaTeX support can render formulae at build time, so readers do not need a remote math service.
Inline formulae
Inline formulae use the passthrough delimiter pairs configured in Goldmark. Keep surrounding spaces and punctuation outside the formula when possible.
Formulae in display mode
Use a math code block for a formula on its own line:
Activating KaTeX support
math and chem code blocks use theme render hooks automatically. For inline
and delimiter-based formulae, enable Goldmark’s passthrough extension and set
the delimiter pairs appropriate for the site. The included oink.pgsty.com
config shows square-bracket, double-dollar, and parenthesis pairs.
Enable the passthrough extension
The relevant YAML structure is:
Fill the arrays with Hugo’s documented delimiter pairs. Choose pairs that do not conflict with the site’s prose or code and apply the setting consistently in every build environment.
Add the passthrough render hook
For delimiter-based math, create layouts/_markup/render-passthrough.html in
the site:
The hook can be scoped to a content type or section by placing it under the corresponding layout directory. A scoped hook avoids treating unrelated content as mathematical passthrough.
Chemical equations and physical units
Hugo’s embedded KaTeX supports the mhchem extension. Use chem code blocks
for chemical equations. The same extension supports physical units. See the
mhchem manual for its equation and unit syntax.
Diagrams with Mermaid
Mermaid turns a text definition into a diagram in the browser. Use a
mermaid code block:
flowchart LR Source --> Hugo --> Static
The theme detects the block, publishes its pinned local Mermaid runtime, and loads it once on that page. Pages without Mermaid do not load the runtime.
Site-wide Mermaid settings live under params.mermaid:
Per-diagram front matter can override supported Mermaid settings. Keep diagram text readable in source, test both color modes, and provide surrounding prose for information that must remain accessible when a diagram cannot render.
UML diagrams with PlantUML
PlantUML supports sequence, use-case, class, state, and other UML-oriented
diagrams. A plantuml block contains the source:
PlantUML requires a renderer endpoint. Enable it only with an approved local or explicit remote service:
The endpoint receives encoded diagram source from the browser. Review its confidentiality, availability, CSP, and offline implications. For an air-gapped site, use an internal endpoint or commit pre-rendered images; do not point the default configuration at a public demo server.
Mind-map support with Markmap
Markmap converts a Markdown outline into an interactive mind map:
# Local-first
## Build
- Hugo Extended
## Browser
- Local scripts
- Local fonts
Enable the feature globally when desired:
The runtime is pinned and served locally. Keep the underlying outline useful and avoid relying on pointer-only interactions.
Diagrams with Diagrams.net
Diagrams.net (draw.io) can export SVG and PNG files that retain an
embedded copy of their editable diagram. OINK can detect those images and show
an Edit action when an editor endpoint is explicitly configured.
Export with Include a copy of my diagram enabled. The page can display the exported image offline, but opening the editor requires the configured service. Saving in the editor downloads an updated file to the browser; it does not write directly to the documentation repository.
Treat a public Diagrams.net endpoint as an online integration. If editing must
stay inside an organization, deploy an approved self-hosted editor and set
drawio_server to it.
Resource and authoring checklist
- Use text-based diagrams when reviewable diffs are valuable.
- Provide alt text or adjacent prose for essential meaning.
- Test light, dark, mobile, print, and reduced-motion behavior.
- Keep local runtimes pinned in
VENDOR.jsonand load them only when used. - Never include secrets in diagram source sent to a service endpoint.
- Use pre-rendered output when an online renderer is unacceptable.
- Verify all asset and endpoint URLs under a subpath
baseURL.
10 - Apache ECharts
The echarts shortcode renders an Apache ECharts options object with the
versioned runtime bundled by Oink. Hugo parses JSON or YAML at build time,
serializes the result into the page, and loads ECharts only on pages that use
the component.
Use ECharts for quantitative charts whose axes, encodings, tooltips, or series need more control than a diagram or table provides. Keep a nearby textual summary so the conclusion does not depend on color, pointer interaction, or JavaScript.
Quick start
The example shows 12 draft pages, nine pages in review, and four pages ready to publish.
How Oink loads a chart
The shortcode creates a unique chart container and stores the parsed options in
an application/json element. The page includes the local ECharts runtime and
Oink initializer once, even when it contains several charts.
If theme is not set, Oink initializes the chart for the current site color
mode and redraws it when the reader changes modes. A ResizeObserver resizes
the chart with its container. Setting an explicit ECharts theme opts out of
automatic site-theme switching for that chart.
Shortcode parameters
| Parameter | Default | Behavior |
|---|---|---|
height |
400px |
Accepts a nonnegative number with px, rem, em, vh, vw, or % |
theme |
unset | Uses a named ECharts theme; when unset, follows the site’s light or dark color mode |
full |
false |
Set to true to remove Oink’s normal content-width clamp |
Invalid height values fail the Hugo build. The shortcode body must decode to an ECharts options object; malformed JSON or YAML also fails at build time instead of creating a blank chart silently.
Choose a guide
scatter plots, legends, and visual encodings.
- Callbacks and trusted code: explains formatter functions, data-dependent
styles, the
$fn:namebridge, and its security boundary.
Start with declarative JSON or YAML. Add JavaScript callbacks only when the ECharts option cannot be expressed as data.
Authoring checklist
- State the chart’s conclusion and data scope in prose.
- Label axes, units, series, and time ranges explicitly.
- Do not use color as the only way to distinguish important values.
- Keep legends and tooltips readable in both site color modes.
- Test the chart at narrow widths and with long translated labels.
- Prefer a shared
datasetwhen several series use the same records. - Record the data source and observation date for nonillustrative data.
- Avoid animation when it does not help comprehension, and respect reduced motion for custom effects.
Further reference
OINK documents its wrapper and delivery behavior; the full options schema
belongs to Apache ECharts. Use the
ECharts concepts handbook,
dataset guide, and
option reference for chart-specific
settings. The theme’s VENDOR.json records the exact runtime version and
license shipped by a release.
11 - Infographics with AntV
The infographic shortcode renders the AntV Infographic DSL with the versioned
runtime bundled by Oink. Use it for processes, timelines, cycles, funnels,
roadmaps, and compact visual summaries where a statistical chart would be too
literal.
The DSL is serialized as data, not inserted as arbitrary HTML or executable code. The browser runtime turns it into SVG and loads only on pages that use the shortcode.
Quick start
The same three steps appear below. Drafting creates the first version, review checks facts and language, and publication builds and verifies the site.
Syntax anatomy
An infographic normally contains:
infographic TEMPLATE, which selects a built-in AntV template;- a
datablock with an optionaltitleanddesc; - an
itemslist withlabel,desc, optionalvalue, and optional nestedchildrenfields; - an optional
themeblock for a built-in theme or explicit colors.
Indentation defines structure. Keep labels short, use descriptions for context, and choose a template whose visual relationship matches the prose. A decorative sequence is not a substitute for an actual hierarchy or comparison.
Shortcode parameters
| Parameter | Default | Behavior |
|---|---|---|
height |
auto |
Accepts auto or a nonnegative number with px, rem, em, vh, vw, or % |
full |
false |
Set to true to remove Oink’s normal content-width clamp |
Invalid height values and an empty DSL body fail the Hugo build. DSL schema or template errors are reported by the browser runtime in the infographic container.
AntV themes belong to the DSL rather than the shortcode parameters. They do not automatically follow Oink’s site color mode, so verify foreground, background, and surrounding-page contrast in both modes.
Choose a guide
- Processes, timelines, and cycles: demonstrates three common ways to explain a sequence.
- Layouts, funnels, and themes: demonstrates grids, narrowing stages, template selection, and a built-in hand-drawn theme.
The AntV package contains many templates. Start with the smallest visual form that clarifies the relationship, not the most decorative form available.
Authoring and accessibility
- Summarize the same conclusion in ordinary text before or after the graphic.
- Keep the reading order meaningful and labels concise.
- Do not use color or shape as the only carrier of status.
- Check long translated labels, narrow screens, printing, and both site color modes.
- Avoid remote image or icon identifiers in a local-first page unless their network and license boundary has been reviewed explicitly.
- Record the source and date when values are not illustrative.
SVG improves visual fidelity, but it does not guarantee that every template exposes the same semantic structure as native headings, lists, and tables. Essential instructions must remain available in adjacent prose.
Further reference
OINK documents its shortcode and delivery boundary. For the full DSL, template
gallery, and theme model, use the
AntV Infographic documentation,
gallery, and
source repository. The Oink theme’s
VENDOR.json records the exact bundled version, checksum, and MIT license file.
