feat: 支持 Obsidian 风格 callout,并把脚注文案中文化
Callout
- 接入 satteri-callouts(HAST 插件),用 Obsidian 语法:
> [!tip] 标题
> 内容
> [!warning]- 默认折叠
类型名大小写不敏感,支持嵌套、可折叠、标题内联 Markdown。
- 样式没有用它自带的主题 CSS(Obsidian 原版是高饱和蓝/青/紫,还靠
mix-blend-mode 叠底色,在暖纸底上会发脏),改为新建 src/styles/callouts.css,
复用主题已有的 --admonitions-color-* token,与 .admonition(免责声明块)
统一成「3px 左边框 + 彩色标题、无底色」。
- 类型映射:tip/hint→tip,note/info/todo/abstract/summary/tldr→note,
important/example→important,warning/attention/question/help/faq→warning,
caution→caution,success/check/done→(新增的)success,
danger/error/failure/fail/missing/bug→destructive,quote/cite→muted-foreground。
- global.css 补一个 --admonitions-color-success(浅色 oklch(0.62 0.16 150) /
深色 oklch(0.7 0.18 150)),与 tip(180)/note(250)/important(310) 同明度彩度。
脚注中文化
features.gfm.footnotes 设 label「脚注」、backLabel「返回第 {reference} 条」、
backContent「↑」,替换默认的 Footnotes / Back to reference。
正文
- 周末愉快.md:`::: tip 下周计划`(冒号后有空格,从来不是合法指令,
一直渲染成普通段落)改成 `> [!tip] 下周计划`,任务列表一并加 `>` 前缀。
- 关于价值感和归属感的思考.md 的 `> [!tip] Tip` 本来就合法,一行未改,
现在自动变成真 callout。
顺带修
autolink-headings 不再给脚注区那个 sr-only 的「脚注」标题加 # 锚点。
验证
- 两处 callout 均正确渲染;callout 内的图片仍带 data-lightbox-src
(说明 imageLightbox 与 satteriCallouts 的执行顺序没问题)。
- 临时加了一篇带脚注和折叠 callout 的文章验证:脚注文案、返回链接、
折叠态 <details>/<summary> 结构都正确,验证后已删除。
- 整页对比基线:37/41 一致,4 处差异中 2 处是本次有意的 callout 生效,
另 2 处是已知的智能标点引号方向(Sätteri 的结果更正确)。
- pnpm build 41 页 + pagefind 通过。
This commit is contained in:
@@ -17,13 +17,10 @@ draft: false
|
||||
其实现在看来,一个有趣的网站固然重要,但是毕竟是一个内容输出的平台,没有足够多的原创内容支持,也只能是一个测试站。
|
||||
另外要想清楚一点,持续的创作和更新其实才是最难的工作。
|
||||
|
||||
::: tip 下周计划
|
||||
|
||||
- [ ] 阅读累计4小时
|
||||
- [ ] 汇总整理近期拍摄的照片
|
||||
- [ ] 写一篇原创文章
|
||||
|
||||
:::
|
||||
> [!tip] 下周计划
|
||||
> - [ ] 阅读累计4小时
|
||||
> - [ ] 汇总整理近期拍摄的照片
|
||||
> - [ ] 写一篇原创文章
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,15 @@ export const autolinkHeadings = defineHastPlugin({
|
||||
if (typeof id !== "string" || id.length === 0) return
|
||||
if (hasAnchor(node)) return
|
||||
|
||||
// 脚注区那个视觉隐藏的 "脚注" 标题不需要 # 锚点
|
||||
let parent = ctx.parent(node)
|
||||
while (parent) {
|
||||
if (parent.type === "element" && parent.properties?.["data-footnotes"] !== undefined) {
|
||||
return
|
||||
}
|
||||
parent = ctx.parent(parent)
|
||||
}
|
||||
|
||||
ctx.appendChild(node, {
|
||||
type: "element",
|
||||
tagName: "a",
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Obsidian 风格 callout 的样式(DOM 由 satteri-callouts 生成)。
|
||||
*
|
||||
* 刻意**不引入** satteri-callouts 自带的主题 CSS:它那套是 Obsidian 原版配色
|
||||
* (蓝/青/紫高饱和色),而且靠 mix-blend-mode 叠底色 —— 在「暖纸底 + 朱红」这套
|
||||
* 配色上会发灰发脏。这里改为复用主题已有的 --admonitions-color-* token,
|
||||
* 与 .admonition(免责声明块)保持同一种视觉语言:3px 左边框 + 彩色标题、无底色。
|
||||
*
|
||||
* 用法(frontmatter 里写):
|
||||
* > [!tip] 标题
|
||||
* > 内容
|
||||
*
|
||||
* > [!warning]- 默认折叠的
|
||||
* > 展开后才看到
|
||||
*/
|
||||
|
||||
.callout {
|
||||
/* 未指定类型时的兜底色 */
|
||||
--callout-accent: var(--admonitions-color-note);
|
||||
|
||||
border-left: 3px solid var(--callout-accent);
|
||||
background: transparent;
|
||||
padding: 0.75rem 1rem;
|
||||
margin: 1.25rem 0;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
/* ---------- 类型 → 主题配色 ---------- */
|
||||
|
||||
[data-callout="tip"],
|
||||
[data-callout="hint"] {
|
||||
--callout-accent: var(--admonitions-color-tip);
|
||||
}
|
||||
|
||||
[data-callout="note"],
|
||||
[data-callout="info"],
|
||||
[data-callout="todo"],
|
||||
[data-callout="abstract"],
|
||||
[data-callout="summary"],
|
||||
[data-callout="tldr"] {
|
||||
--callout-accent: var(--admonitions-color-note);
|
||||
}
|
||||
|
||||
[data-callout="important"],
|
||||
[data-callout="example"] {
|
||||
--callout-accent: var(--admonitions-color-important);
|
||||
}
|
||||
|
||||
[data-callout="warning"],
|
||||
[data-callout="attention"],
|
||||
[data-callout="question"],
|
||||
[data-callout="help"],
|
||||
[data-callout="faq"] {
|
||||
--callout-accent: var(--admonitions-color-warning);
|
||||
}
|
||||
|
||||
[data-callout="caution"] {
|
||||
--callout-accent: var(--admonitions-color-caution);
|
||||
}
|
||||
|
||||
[data-callout="success"],
|
||||
[data-callout="check"],
|
||||
[data-callout="done"] {
|
||||
--callout-accent: var(--admonitions-color-success);
|
||||
}
|
||||
|
||||
[data-callout="danger"],
|
||||
[data-callout="error"],
|
||||
[data-callout="failure"],
|
||||
[data-callout="fail"],
|
||||
[data-callout="missing"],
|
||||
[data-callout="bug"] {
|
||||
--callout-accent: var(--destructive);
|
||||
}
|
||||
|
||||
[data-callout="quote"],
|
||||
[data-callout="cite"] {
|
||||
--callout-accent: var(--muted-foreground);
|
||||
}
|
||||
|
||||
/* ---------- 标题 ---------- */
|
||||
|
||||
.callout-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.375rem;
|
||||
|
||||
color: var(--callout-accent);
|
||||
font-weight: 600;
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.callout-title-icon {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.callout-title-icon svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.callout-title-text {
|
||||
color: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/* 折叠版用的是 <summary>,去掉浏览器默认的三角标记 */
|
||||
.callout-title::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.callout-title::marker {
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* ---------- 内容 ---------- */
|
||||
|
||||
/* prose 给段落 1.25rem 的上下边距,在 callout 里太松,收紧一点 */
|
||||
.callout-content p {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.callout-content > :first-child {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.callout-content > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* ---------- 折叠态 ---------- */
|
||||
|
||||
.callout[data-collapsible="true"] .callout-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.callout[data-collapsible="true"] .callout-fold-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
|
||||
.callout-fold-icon svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.callout[data-collapsible="true"] > .callout-title .callout-fold-icon svg {
|
||||
transform: rotate(-90deg);
|
||||
transition: transform 150ms ease-in-out;
|
||||
}
|
||||
|
||||
.callout[data-collapsible="true"][open] > .callout-title .callout-fold-icon svg {
|
||||
transform: none;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
@import "./transition.css";
|
||||
@import "tailwindcss/index.css";
|
||||
@import "tw-animate-css";
|
||||
@import "./callouts.css";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
@@ -88,6 +89,7 @@
|
||||
--admonitions-color-important: oklch(0.62 0.16 310);
|
||||
--admonitions-color-warning: oklch(0.7 0.18 70);
|
||||
--admonitions-color-caution: oklch(0.62 0.2 var(--primary-hue, 25));
|
||||
--admonitions-color-success: oklch(0.62 0.16 150);
|
||||
/* Code block colors - light mode */
|
||||
/* 暖色阴槽 #f2ece1。原来是 0.97/0.003 的中性灰白,在暖纸底(#f8f3e9)上
|
||||
就是一块冷白补丁,很跳。现在带上同样的暖色相。
|
||||
@@ -149,6 +151,7 @@
|
||||
--admonitions-color-important: oklch(0.7 0.18 310);
|
||||
--admonitions-color-warning: oklch(0.75 0.2 70);
|
||||
--admonitions-color-caution: oklch(0.7 0.22 var(--primary-hue, 25));
|
||||
--admonitions-color-success: oklch(0.7 0.18 150);
|
||||
/* Code block colors - dark mode */
|
||||
--codeblock-bg: oklch(0.20 0.015 250);
|
||||
--codeblock-topbar-bg: oklch(0.24 0.015 250);
|
||||
|
||||
Reference in New Issue
Block a user