Shortcodes Reference
Live demo of every content shortcode shipped with Inkstone.
This page demonstrates every content shortcode that ships with Inkstone. Each section shows the source markdown and the rendered result. Use it as both a smoke test and a copy-paste reference.
For shortcodes that depend on external CDN libraries (mermaid, markmap, antv-g2, etc.), the loaders only inject when the page actually uses them — pages without the shortcode pay zero JS cost.
Callouts & Admonitions
callout — short colored note
Five severity levels with i18n-aware default titles.
{{< callout type="note" title="Heads up" >}}
This is a note callout. Use it for tangential context.
{{< /callout >}}
Heads up
This is a note callout. Use it for tangential context.Backup first
Always rungit stash before destructive operations.admonition — foldable longer block
Same severities as callout but with optional fold/unfold and an icon.
{{< admonition type="tip" title="Pro tip" foldable=true >}}
Long-form callout content goes here. Useful when the
note itself contains multiple paragraphs or code blocks.
{{< /admonition >}}
Pro tip
foldable=true lets readers collapse it after reading.~0 until you’ve reviewed the migration guide.Layout & Composition
flex + flex-item — flexbox layout helper
Wrap children in a flex container with control over direction, gap, and alignment.
{{< flex justify-content="space-between" column-gap="24px" >}}
{{< flex-item >}}**Left** column content.{{< /flex-item >}}
{{< flex-item >}}**Right** column content.{{< /flex-item >}}
{{< /flex >}}
tab + tab-item — tabbed content
The tab-item shortcode uses the {{% %}} markdown form so fenced code blocks inside it render correctly. The label= attribute sets the tab header.
{{</* tab */>}}
{{%/* tab-item label="Python" %}}
```python
print("hello")
```
{{% /tab-item %}}
{{% tab-item label="JavaScript" %}}
```javascript
console.log("hello");
```
{{% /tab-item %}}
{{< /tab >}}
print("hello")
console.log("hello");
details — collapsible disclosure
{{< details summary="Click to expand" >}}
Hidden content goes here.
{{< /details >}}
Click to expand
Hidden content goes here. Use it for long appendices, derivations, or “if you really want to know” sidebars.
Code & Text
highlight — syntax-highlighted block with title
A wrapper around Chroma that adds an optional title bar.
{{< highlight lang="python" title="fibonacci.py" >}}
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
{{< /highlight >}}
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)include — inline another file (raw HTML)
{{< include "snippets/hello.html" >}}
Hello from snippets/hello.html!
This file is loaded inline by the include shortcode.
include-code — inline another file as a code block
{{< include-code file="snippets/hello.py" language="python" >}}
def hello(name: str = "world") -> str:
"""Greet someone. Inlined by the `include-code` shortcode."""
return f"Hello, {name}!"
if __name__ == "__main__":
print(hello("Inkstone"))
copy-to-clipboard — inline copy button
The text= parameter is the button label; the inner content is what gets copied to the clipboard.
Email: {{< copy-to-clipboard text="Copy" >}}user@example.com{{< /copy-to-clipboard >}}
Email: Copy
pseudocode — academic pseudocode rendering
Renders LaTeX-style algorithm pseudocode. Lazy-loads the renderer only on pages that use it.
{{< pseudocode >}}
\begin{algorithm}
\caption{Binary Search}
\begin{algorithmic}
\REQUIRE sorted array $A$, target $t$
\STATE $\ell \gets 0$, $r \gets |A| - 1$
\WHILE{$\ell \leq r$}
\STATE $m \gets \lfloor (\ell + r) / 2 \rfloor$
\IF{$A[m] = t$} \RETURN $m$ \ENDIF
\IF{$A[m] < t$} \STATE $\ell \gets m + 1$
\ELSE \STATE $r \gets m - 1$
\ENDIF
\ENDWHILE
\RETURN $-1$
\end{algorithmic}
\end{algorithm}
{{< /pseudocode >}}
\begin{algorithm}
\caption{Binary Search}
\begin{algorithmic}
\REQUIRE sorted array $A$, target $t$
\STATE $\ell \gets 0$, $r \gets |A| - 1$
\WHILE{$\ell \leq r$}
\STATE $m \gets \lfloor (\ell + r) / 2 \rfloor$
\IF{$A[m] = t$} \RETURN $m$ \ENDIF
\IF{$A[m] < t$} \STATE $\ell \gets m + 1$
\ELSE \STATE $r \gets m - 1$
\ENDIF
\ENDWHILE
\RETURN $-1$
\end{algorithmic}
\end{algorithm}
button — styled link as button
{{< button href="https://github.com/BerBai/inkstone" target="_blank" >}}View on GitHub{{< /button >}}
pullquote — large emphasized quote
{{< pullquote author="Italo Calvino" >}}
A classic is a book that has never finished saying what it has to say.
{{< /pullquote >}}
A classic is a book that has never finished saying what it has to say. — Italo Calvino
rating — generic star rating
Display-only stars over a configurable max (default 5). Any input is rounded to the nearest 0.5 and clamped to [0, max]. The aria-label is i18n-driven and uses the rounded value so visual and screen-reader output stay in sync.
My take: {{< rating value="4.5" >}} (out of 5)
On a 10-point scale: {{< rating value="8" max="10" >}}
My take: (out of 5)
On a 10-point scale:
Media
figure — captioned image
{{< figure src="/img/figure-demo.svg" alt="Demo image" caption="A captioned figure with alt text." >}}
image-compare — before/after slider
The shortcode takes image-before and image-after (note the prefix — required by the underlying viewer).
{{< image-compare image-before="/img/compare-before.svg" image-after="/img/compare-after.svg" >}}
gallery — justified grid + lightbox
Driven by a JSON data file. The fixture below lives at static/data/smoke/gallery.json (use an absolute path so the JS fetch resolves correctly from any page URL).
{{< gallery data="/data/smoke/gallery.json" >}}
video — self-hosted MP4/WebM
{{< video mp4="https://example.com/demo.mp4" controls=true >}}
Skipped here because
exampleSite/ships with no MP4 fixture. See the source code atlayouts/shortcodes/video.htmlfor the full parameter list.
youtube — YouTube embed
{{< youtube id="dQw4w9WgXcQ" >}}
bilibili — Bilibili embed
{{< bilibili bvid="BV1xx411c7mD" >}}
Live render skipped to avoid loading external iframes during the demo build. The shortcode accepts
bvid(preferred) oraid.
song — NetEase Music single-track player
{{< song id="447925558" >}}
Live render skipped (CDN dependency). The shortcode accepts NetEase track IDs via
id.
swiper — JSON-driven carousel
{{< swiper data="data/smoke/swiper.json" >}}
No fixture shipped in
exampleSite/. Seelayouts/shortcodes/swiper.htmlfor the schema.
Diagrams & Math
Mermaid diagrams (via fenced codeblock)
```mermaid
flowchart LR
A[hugo build] --> B{has tag?}
B -->|yes| C[use latest tag]
B -->|no| D[use latest commit]
C --> E[deploy preview]
D --> E
```
flowchart LR
A[hugo build] --> B{has tag?}
B -->|yes| C[use latest tag]
B -->|no| D[use latest commit]
C --> E[deploy preview]
D --> E
Markmap mind maps (via fenced codeblock)
```markmap
# Inkstone
## Layouts
- baseof
- single
- list
## Shortcodes
- callout
- admonition
- gallery
```
antv-g2 — declarative chart
{{< antv-g2 script="data/charts/sample.js" caption="A sample chart" >}}
No script fixture shipped. The shortcode loads
@antv/g2from CDN and runs your chart spec from the given resource path. Seestatic/data/smoke/patterns to provide your own.
Math (MathJax v4)
Inline: $E = mc^2$.
Block:
$$ \frac{\partial}{\partial t} \rho + \nabla \cdot (\rho \mathbf{v}) = 0 $$
The MathJax CDN is only injected on pages that contain math delimiters — pages without math pay zero cost.
External & Embeds
iframe — embed external content with theme bridge
The theme passes a theme=light|dark query param to known hosts (codepen.io, codesandbox.io, stackblitz.com, replit.com), so embedded content matches the site’s current theme.
{{< iframe src="https://codepen.io/team/codepen/embed/PNaGbb" ratio=0.6 >}}
Live render skipped to keep this demo offline-friendly. The bridge whitelist lives at
data/iframe_theme_hosts.toml.
douban-card — Douban book/movie card
{{< douban-card type="book" id="1084336" >}}
Requires Douban API access. The shortcode renders a card linking back to Douban.
wechat-qr — WeChat OA QR popover
{{< wechat-qr name="My OA" image="/img/wechat-qr.svg" >}}
Hover or focus this element to see a QR code popover: Demo OA
Summary
That’s the full shortcode catalog as of the current release. For production usage:
- Always pass
altonfigure,image-compare, andgalleryfor a11y - Don’t autoplay video unless you’re embedding a silent looping clip — Inkstone defaults
autoplay=false - Lazy-loaded shortcodes (mermaid, markmap, antv-g2, mathjax, pseudocode, swiper, song) only fetch their CDN libs when the shortcode is actually present on the page
Issues or feature requests: github.com/BerBai/inkstone/issues .