跳转到内容
关系图谱

markdown-it-obsidian-callouts:Obsidian Callouts 语法完全指南

2,672 字 10 分钟

属性 1
series
VaultKit 包指南

Callouts 是 Obsidian 里最常用的排版元素——一个 > [!tip] 就能把提示、警告、示例从正文里凸显出来。但把笔记发布上网时,通用 Markdown 渲染器只会把它当成普通引用块。@vaultkit/markdown-it-obsidian-callouts 在任何 markdown-it ≥ 14 环境里补齐这块拼图:对齐 Obsidian 官方规范的完整实现,折叠形态直接产出原生 <details>,零客户端 JS。

本文是「VaultKit 包指南」系列第二篇,一份面向写作者的教程:13 种标准类型、14 个别名逐一实活演示(你看到的每个 callout 都是本站构建时真实渲染的),再到折叠、嵌套、自定义类型注册与 DOM/CSS 契约。

为什么需要它

markdown-it 生态里的 callout 插件不少,这个包的差异点在于「对齐 Obsidian,且为静态站点做减法」:

  • 语法逐项对齐 Obsidian 官方帮助页:别名全集、折叠正负号、大小写不敏感、未知类型回退,Obsidian 里怎么写,发布出来行为一致;
  • DOM/CSS 契约也跟随 Obsidian.callout[data-callout] + --callout-color 变量,你在 Obsidian 里攒的自定义颜色 snippet 心智可以直接迁移;
  • 零客户端开销:图标(Obsidian 同款 lucide 集)构建期内联 SVG,折叠用原生 <details> 实现,不发一行 JS;
  • 宿主无关:样式选择器不带任何宿主前缀,VitePress 之外的 markdown-it 环境同样可用。

安装

sh
pnpm add -D @vaultkit/markdown-it-obsidian-callouts

如果你用的是 @vaultkit/vitepress-theme-vault 主题,本插件开箱即带markdown.callouts 缺省开启,样式已引入),下面的接入步骤可以整段跳过。

快速上手

任意 markdown-it 环境:

ts
import { obsidianCallouts } from '@vaultkit/markdown-it-obsidian-callouts'
import MarkdownIt from 'markdown-it'

const md = new MarkdownIt().use(obsidianCallouts)

VitePress 环境要多做两件事——停用同形语法的内置 GFM alerts,并引入样式:

ts
// .vitepress/config.ts
import { obsidianCallouts } from '@vaultkit/markdown-it-obsidian-callouts'
import { defineConfig } from 'vitepress'

export default defineConfig({
  markdown: {
    gfmAlerts: false, // 内置 GFM alerts 与 callout 语法同形,必须停用其一
    config(md) {
      md.use(obsidianCallouts)
    },
  },
})
ts
// .vitepress/theme/index.ts
import '@vaultkit/markdown-it-obsidian-callouts/styles/index.css'

基础语法

在引用块首行写 [!类型],可选跟一个自定义标题;后续行是正文,支持任意块级内容:

md
> [!tip] 可选的自定义标题
> 正文是普通 Markdown,列表、代码块、嵌套引用都可以。
可选的自定义标题

正文是普通 Markdown,列表、代码块、嵌套引用都可以。

省略标题时,缺省标题为类型名首字母大写;省略正文(仅标题行)也合法:

md
> [!tip] 只有标题、没有正文的 callout 同样合法
只有标题、没有正文的 callout 同样合法

13 种标准类型

每种类型有专属的 lucide 图标与色系(色板保持 Obsidian 色相,但明暗分态调至 WCAG AA 对比度)。逐一演示:

md
> [!note]
> note——蓝色 + 铅笔图标,最常规的补充说明。

> [!abstract]
> abstract——青色 + 清单图标,摘要与概括。

> [!info]
> info——蓝色 + 信息图标,背景信息。

> [!todo]
> todo——蓝色 + 对勾圆圈,待办容器。

> [!tip]
> tip——青色 + 火焰图标,小技巧。

> [!success]
> success——绿色 + 对勾,操作成功。

> [!question]
> question——橙色 + 问号圆圈,疑问与解答。

> [!warning]
> warning——橙色 + 警示三角,注意事项。

> [!failure]
> failure——红色 + 叉号,失败记录。

> [!danger]
> danger——红色 + 闪电,危险操作。

> [!bug]
> bug——红色 + 虫子图标,缺陷记录。

> [!example]
> example——紫色 + 列表图标,示例演示。

> [!quote]
> quote——灰色 + 引号,引用他人。
Note

note——蓝色 + 铅笔图标,最常规的补充说明。

Abstract

abstract——青色 + 清单图标,摘要与概括。

Info

info——蓝色 + 信息图标,背景信息。

Todo

todo——蓝色 + 对勾圆圈,待办容器。

Tip

tip——青色 + 火焰图标,小技巧。

Success

success——绿色 + 对勾,操作成功。

Question

question——橙色 + 问号圆圈,疑问与解答。

Warning

warning——橙色 + 警示三角,注意事项。

Failure

failure——红色 + 叉号,失败记录。

Danger

danger——红色 + 闪电,危险操作。

Bug

bug——红色 + 虫子图标,缺陷记录。

Example

example——紫色 + 列表图标,示例演示。

Quote

quote——灰色 + 引号,引用他人。

14 个别名

Obsidian 为常用类型准备了别名,与规范类型同色同图标,只有缺省标题不同(显示别名本身的首字母大写形式)。插件以 CALLOUT_ALIASES 常量导出全集,共 14 个,逐一演示:

md
> [!summary]
> `summary` → abstract

> [!tldr]
> `tldr` → abstract

> [!hint]
> `hint` → tip

> [!important]
> `important` → tip

> [!check]
> `check` → success

> [!done]
> `done` → success

> [!help]
> `help` → question

> [!faq]
> `faq` → question

> [!caution]
> `caution` → warning

> [!attention]
> `attention` → warning

> [!fail]
> `fail` → failure

> [!missing]
> `missing` → failure

> [!error]
> `error` → danger

> [!cite]
> `cite` → quote
Summary

summary → abstract

Tldr

tldr → abstract

Hint

hint → tip

Important

important → tip

Check

check → success

Done

done → success

Help

help → question

Faq

faq → question

Caution

caution → warning

Attention

attention → warning

Fail

fail → failure

Missing

missing → failure

Error

error → danger

Cite

cite → quote

速查表(规范类型 → 别名 → 图标):

规范类型别名lucide 图标
notepencil
abstractsummary tldrclipboard-list
infoinfo
todocircle-check
tiphint importantflame
successcheck donecheck
questionhelp faqcircle-help
warningcaution attentiontriangle-alert
failurefail missingx
dangererrorzap
bugbug
examplelist
quotecitequote

折叠:[!type]-[!type]+

类型标记后紧跟 -+,callout 渲染为原生 <details>——- 默认收起、+ 默认展开,点标题即可切换,零 JS:

md
> [!faq]- 这条默认是收起的,点我展开
> 折叠形态是原生 `<details>` + `<summary>`,键盘可操作,无需 JavaScript。右侧箭头随展开态旋转 90°。

> [!faq]+ 这条默认是展开的,点我收起
> 适合「默认给读者看,但允许收起」的补充内容。
这条默认是收起的,点我展开

折叠形态是原生 <details> + <summary>,键盘可操作,无需 JavaScript。右侧箭头随展开态旋转 90°。

这条默认是展开的,点我收起

适合「默认给读者看,但允许收起」的补充内容。

自定义标题

标题支持行内 Markdown——粗体、行内代码,甚至 wikilink:

md
> [!tip] 标题里可以有 **粗体**`行内代码` 与 [[Minimal Theme|双链]]
> 标题内的行内元素继承标题色,不会被宿主主题的链接色打花。
标题里可以有 粗体行内代码双链

标题内的行内元素继承标题色,不会被宿主主题的链接色打花。

大小写不敏感

类型标识大小写不敏感,[!NOTE][!Note][!note] 完全等价:

md
> [!NOTE] 大写 NOTE 与小写 note 等价
> 从 GitHub README 粘贴过来的大写写法无需修改。
大写 NOTE 与小写 note 等价

从 GitHub README 粘贴过来的大写写法无需修改。

未知类型回退

未注册的类型不会报错,而是回退 note 样式(Obsidian 行为),缺省标题显示原类型名:

md
> [!spoiler]
> `spoiler` 未注册,样式回退 note 蓝,`data-callout` 属性仍保留原值 `spoiler`——想给它专属颜色补一条 CSS 即可(见下文契约一节)。
Spoiler

spoiler 未注册,样式回退 note 蓝,data-callout 属性仍保留原值 spoiler——想给它专属颜色补一条 CSS 即可(见下文契约一节)。

嵌套

callout 可以多层嵌套,插件从内向外转换,嵌套层自动收紧间距:

md
> [!question] 外层:callout 能嵌套吗?
> > [!success] 中层:能。
> > > [!example] 内层:多层也没问题。
外层:callout 能嵌套吗?
中层:能。
内层:多层也没问题。

正文的块级能力不止于此——列表、任务清单、代码块都可以放进 callout,体例演示见 Callout 语法测试

icons 选项:注册自定义类型

插件唯一的选项是 icons(类型 Record<string, string>),与内置 CALLOUT_ICONS 浅合并,两个用途:

  1. 覆盖内置图标{ tip: 'lightbulb' } 把 tip 的火焰换成灯泡;
  2. 注册新类型:新增键会同时把该键注册为合法类型——不再回退 note 样式。
ts
md.use(obsidianCallouts, {
  icons: { idea: 'lightbulb' }, // 值是 lucide 图标名
})

新类型的颜色需要自行补一条 CSS(值是 R, G, B 数值三元组,明暗两态分开给):

css
.callout[data-callout='idea'] {
  --callout-color: 178, 106, 0;
}

.dark .callout[data-callout='idea'] {
  --callout-color: 250, 173, 20;
}

所有图标在插件注册时预渲染——图标名写错在构建期即抛错(@iconify-json/lucide 中不存在图标:xxx),而非渲染期静默缺图。别名与图标映射同时以 CALLOUT_ALIASES / CALLOUT_ICONS 常量导出,可编程消费。

与 Obsidian 的 DOM/CSS 契约

插件产出的结构与 Obsidian 官方约定一致:

html
<div class="callout" data-callout="tip">
  <div class="callout-title">
    <span class="callout-icon"><svg></svg></span>
    <span class="callout-title-inner">标题</span>
  </div>
  <div class="callout-content">正文</div>
</div>

关键契约点:

  • data-callout 保留原始类型名(含别名与未知类型),样式经属性选择器命中——这正是 Obsidian 自定义颜色 snippet 的工作方式,.callout[data-callout='x'] { --callout-color: R, G, B } 一行迁移;
  • --callout-colorR, G, B 数值三元组:标题文字用 rgb(var(--callout-color)),底色用 rgba(var(--callout-color), 0.1),一个变量派生两种用途;
  • 基础 .callout 缺省即 note 蓝,所以未知类型「自动」回退 note 样式,不需要任何 JS 判断;
  • 暗色态跟随宿主 .dark(VitePress / Nuxt UI 同轨约定),色板明暗分别调色,标题对比度实测 ≥ 4.5:1(Obsidian 原版单一色板在 10% 透明底上普遍不达标);
  • 折叠形态根元素换成 <details class="callout is-foldable">,标题换成 <summary>

与 GFM alerts 的关系

GitHub 的 alerts 语法(> [!NOTE] 等五种)与 Obsidian callouts 同形。在 VitePress 宿主里必须设置 markdown.gfmAlerts: false 停用内置实现,保持全站语法单轨——否则两套规则会争抢同一段落。

停用后 GFM 五种写法照常可用,由本插件统一渲染,语义按 Obsidian 归位:NOTE / TIP / WARNING 是规范类型,IMPORTANT 是 tip 的别名、CAUTION 是 warning 的别名。从 GitHub README 迁移的文档零改动。

高级与边界

  • SSR / SSG 友好:转换发生在 markdown-it core ruler 阶段(构建期),产物是纯 HTML + CSS,没有水合、没有闪烁;
  • 无障碍:图标 SVG 带 aria-hidden="true" 不进读屏;折叠用原生 <summary>,键盘与读屏语义免费获得;
  • 样式不随插件自动注入:需在主题入口单独引入 @vaultkit/markdown-it-obsidian-callouts/styles/index.css(或完全自写——DOM 契约稳定);
  • 类型标识的字符集:匹配 [\w-]+,即字母、数字、下划线、连字符;
  • 标题的解析边界:标记后同一行是标题,首个换行之后进正文;整段只有标记行时正文为空。

常见问题

写了 callout 但渲染成了普通引用块?

检查标记行格式:[!type] 必须在引用块首行行首,类型后要么接空格 + 标题,要么直接换行。[!type] 前有多余字符不会触发转换。

VitePress 里 callout 渲染了两层样式?

忘了设 markdown.gfmAlerts: false——内置 GFM alerts 与本插件同时命中了同一段落。

自定义类型没有颜色?

icons 只注册图标与合法性,颜色走 CSS:补一条 .callout[data-callout='你的类型'] { --callout-color: R, G, B }(暗色态再补一条 .dark 前缀的)。

相关链接