本页演示 Inkstone 自带的全部内容 shortcode。每一节都给出源码 markdown 与渲染结果,可以作为冒烟测试,也可以直接拷走当模板使用。

依赖外部 CDN 的 shortcode(mermaid、markmap、antv-g2 等),加载器只在该页真正用到时才注入——没用到的页面零 JS 成本。


Callout 与 Admonition

callout —— 简短的着色提示

五个严重程度,标题会按 i18n 自动取默认值。

{{< callout type="note" title="留意" >}}
这是一个 note 类型 callout,用来放偏题但相关的上下文。
{{< /callout >}}

留意

这是一个 note 类型 callout,用来放偏题但相关的上下文。
Tip callout(没显式给标题——用 i18n 默认值)。

先备份

做破坏性操作之前,先 git stash 一下。

admonition —— 可折叠的较长块

严重程度与 callout 相同,但可选折叠/展开,并自带图标。

{{< admonition type="tip" title="进阶提示" foldable=true >}}
长文本 callout 内容放在这里。当提示本身包含
多个段落或代码块时很有用。
{{< /admonition >}}
进阶提示
长文本 callout 内容放在这里。当提示本身包含多个段落或代码块时很有用。foldable=true 让读者读完之后可以收起。
迁移提示
Inkstone 0.x → 1.x 会对设计 token API 做破坏性变更。在你看完迁移指南之前,请把版本锁在 ~0

布局与组合

flex + flex-item —— flexbox 布局辅助

把子元素包进 flex 容器,可以控制方向、间距、对齐。

{{< flex justify-content="space-between" column-gap="24px" >}}
  {{< flex-item >}}**左**列内容。{{< /flex-item >}}
  {{< flex-item >}}**右**列内容。{{< /flex-item >}}
{{< /flex >}}
**左**列内容。适合用来做并排对比或"前/后"散文。
**右**列内容。这个 wrapper 接受标准的 flex 属性。

tab + tab-item —— 切换页内容

tab-item 必须使用 {{% %}} 这种 markdown 形态——否则内部的 ``` 围栏代码块不会被解析。label= 是 Tab 头文字。

{{</* 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 —— 可折叠披露

{{< details summary="点击展开" >}}
被折叠的内容写在这里。
{{< /details >}}
点击展开

被折叠的内容写在这里。适合用来放长附录、推导过程,或"如果你真想知道"的旁白。


代码与文本

highlight —— 带标题的语法高亮块

对 Chroma 的封装,加了一条可选的标题栏。

{{< highlight lang="python" title="fibonacci.py" >}}
def fib(n):
    return n if n < 2 else fib(n-1) + fib(n-2)
{{< /highlight >}}
fibonacci.py
def fib(n):
    return n if n < 2 else fib(n-1) + fib(n-2)

include —— 把另一个文件作为原始 HTML 内联

{{< include "snippets/hello.html" >}}

Hello from snippets/hello.html!

This file is loaded inline by the include shortcode.

include-code —— 把另一个文件作为代码块内联

{{< 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 —— 行内复制按钮

text= 是按钮上显示的文字,被复制到剪贴板的是 Inner 内容。

邮箱:{{< copy-to-clipboard text="复制" >}}user@example.com{{< /copy-to-clipboard >}}

邮箱: 复制

pseudocode —— 学术伪代码渲染

渲染 LaTeX 风格的算法伪代码。渲染器只在用到的页面才懒加载。

{{< 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 —— 把链接渲染为按钮样式

{{< button href="https://github.com/BerBai/inkstone" target="_blank" >}}在 GitHub 上查看{{< /button >}}
在 GitHub 上查看

pullquote —— 大字强调引言

{{< pullquote author="伊塔洛·卡尔维诺" >}}
经典是这样一种作品——它永远没有把要说的话说完。
{{< /pullquote >}}
经典是这样一种作品——它永远没有把要说的话说完。 — 伊塔洛·卡尔维诺

rating —— 通用星级评分

仅展示星级,最大刻度可配(默认 5),输入会四舍五入到最近 0.5,并 clamp 到 [0, max]aria-label 走 i18n,使用四舍五入后的值,保证视觉与读屏一致。

我的评价:{{< rating value="4.5" >}}(满分 5)

10 分制:{{< rating value="8" max="10" >}}

我的评价: (满分 5)

10 分制:


媒体

figure —— 带说明的图片

{{< figure src="/img/figure-demo.svg" alt="Demo image" caption="一张带说明文字与替代文本的图。" >}}
Demo image
一张带说明文字与替代文本的图。

image-compare —— 前后对比滑块

shortcode 接收 image-beforeimage-after(注意带前缀,是底层组件要求的属性名)。

{{< image-compare image-before="/img/compare-before.svg" image-after="/img/compare-after.svg" >}}

由 JSON 数据文件驱动。下面这份 fixture 在 static/data/smoke/gallery.json(用绝对路径,JSON 才能从任意页面 URL 拉到)。

{{< gallery data="/data/smoke/gallery.json" >}}

video —— 自托管的 MP4/WebM

{{< video mp4="https://example.com/demo.mp4" controls=true >}}

这里跳过实际渲染,因为 exampleSite/ 没有打包 MP4 fixture。完整参数列表见源码 layouts/shortcodes/video.html

youtube —— YouTube 嵌入

{{< youtube id="dQw4w9WgXcQ" >}}

bilibili —— B 站嵌入

{{< bilibili bvid="BV1xx411c7mD" >}}

跳过实际渲染,避免在 demo 构建过程中加载外部 iframe。shortcode 接受 bvid(推荐)或 aid

song —— 网易云音乐单曲播放器

{{< song id="447925558" >}}

跳过实际渲染(依赖 CDN)。shortcode 通过 id 接收网易云音乐的曲目 ID。

swiper —— JSON 驱动的轮播

{{< swiper data="data/smoke/swiper.json" >}}

exampleSite/ 没附带 fixture。schema 见 layouts/shortcodes/swiper.html


图表与数学

Mermaid 图表(通过 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 思维导图(通过 fenced codeblock)

```markmap
# Inkstone
## Layouts
- baseof
- single
- list
## Shortcodes
- callout
- admonition
- gallery
```

antv-g2 —— 声明式图表

{{< antv-g2 script="data/charts/sample.js" caption="一张示例图表" >}}

没附带脚本 fixture。这个 shortcode 通过 CDN 加载 @antv/g2,并跑你给的 resource 路径下的图表 spec。可以参考 static/data/smoke/ 的结构来准备自己的数据。

数学公式(MathJax v4)

行内:$E = mc^2$。

块级:

$$ \frac{\partial}{\partial t} \rho + \nabla \cdot (\rho \mathbf{v}) = 0 $$

MathJax CDN 只在带数学分隔符的页面注入——没数学公式的页面零成本。


外部嵌入

iframe —— 嵌入外部内容(带主题桥接)

主题会向已知 host(codepen.io、codesandbox.io、stackblitz.com、replit.com)传递 theme=light|dark 查询参数,让嵌入内容跟当前站点主题匹配。

{{< iframe src="https://codepen.io/team/codepen/embed/PNaGbb" ratio=0.6 >}}

跳过实际渲染,让本 demo 保持离线友好。桥接白名单在 data/iframe_theme_hosts.toml

douban-card —— 豆瓣书影音卡片

{{< douban-card type="book" id="1084336" >}}

需要访问豆瓣 API。shortcode 渲染一张回链豆瓣的卡片。

wechat-qr —— 微信公众号二维码气泡

{{< wechat-qr name="我的公众号" image="/img/wechat-qr.svg" >}}

悬停或聚焦下面这个元素,即可看到二维码气泡: Demo OA


小结

以上就是当前发行版下完整的 shortcode 目录。生产场景使用建议:

  • 永远给 figureimage-comparegalleryalt,照顾无障碍
  • 不要让视频自动播放,除非你嵌的是无声的循环片段——Inkstone 默认 autoplay=false
  • 懒加载的 shortcode(mermaid、markmap、antv-g2、mathjax、pseudocode、swiper、song)只在页面真正用到时才会请求 CDN 库

提 issue 或功能请求:github.com/BerBai/inkstone/issues