Commit Graph
2 Commits
Author SHA1 Message Date
TimeCrackbot f4a49ef94c 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 通过。
2026-09-17 18:01:44 +08:00
TimeCrackbot 26e873b9f6 refactor: Markdown 管线迁移到 Sätteri(Phase 1 + Phase 2)
把 markdown.processor 从 unified() 换成 Astro 7 的默认管线 satteri(),
并把原来 12 个 remark/rehype 插件逐一移植到 Sätteri 的 MDAST/HAST 插件模型。

内置能力直接替代(零代码)
- remark-math      → features.math
- remark-directive → 未启用(见下)
- rehype-slug      → satteriHeadingIdsPlugin()

新增 src/plugins/satteri/(6 个插件,约 200 行)
- reading-time.mjs    after 钩子写 ctx.data.astro.frontmatter.minutes/words
- excerpt.mjs         取第一段写 frontmatter.excerpt
- shift-headings.mjs  工厂按 fileURL 判断,只对 posts 下的文章生效
- sectionize.mjs      remark-sectionize 的等价实现(递归分组 + data.hName)
- autolink-headings.mjs  标题锚点,输出与 rehype-autolink-headings 逐字一致
- image-lightbox.mjs  上一版 rehype 图片灯箱的 HAST 版

删除(已迁移或本就无效)
- remark-reading-time / remark-excerpt / remark-shift-headings /
  remark-directive-rehype / rehype-component-admonition /
  rehype-image-lightbox —— 共 6 个旧插件文件
- 未启用 features.directive:内容里的 `::: tip`(冒号后有空格)和
  `> [!tip] Tip` 在迁移前后都渲染成普通段落/引用,属于死语法;
  保持现状以免升级顺手把它激活。

行为对齐
- smartPunctuation: { dashes: false } —— Astro 的 unified 管线会把直引号
  排成弯引号但不转换 ---,Sätteri 默认会转,显式关掉 dashes 才能逐字一致。

验证(与 unified() 构建逐页对比,41 页)
- 正文 HTML 完全一致 35 页;把 HTML 实体和表格对齐写法归一化后,
  只剩 3 页有差异:1 页是 KaTeX 尚未迁移(见下),2 页是中文/emoji 旁的
  引号方向(Sätteri 的结果更正确)。
- meta description 仍由 excerpt 正确生成;阅读时长与基线一致。
- astro check:1 error / 0 warnings,与迁移前完全相同(原有 footer.astro 报错)。
- pnpm build 41 页通过;dev server 正常。

尚未迁移
- KaTeX:Sätteri 的 math 只负责解析,不渲染。数学公式目前落成
  <code class="language-math">,是可见的回归,Phase 3 处理。
- package.json 里 remark-*/rehype-* 依赖暂未清理,等 Phase 3 确定后再收。
2026-09-17 17:38:37 +08:00