README file from
GithubTheme Plume
在 Obsidian 阅读视图中渲染 VuePress Theme Plume 的 Markdown 容器语法(::: file-tree、::: tabs、::: steps 等)。
项目来源
本仓库是将 vuepress-theme-plume 的 Markdown 增强能力迁移到 Obsidian 的独立插件,并非上游官方仓库。解析、渲染与样式对齐过程中大量使用了 AI 辅助开发工具(如 Cursor)。
- 仅覆盖 Plume 的 Markdown 容器与阅读视图渲染,不包含 VuePress 站点主题、导航、博客、搜索等。
- 上游主题为 MIT;本仓库同样 MIT,并保留上游版权声明,详见 NOTICE。
功能概览
:::自定义容器:文件树、代码树、选项卡、步骤、提示框、卡片、时间线等(见下表)。- 容器内正文交给 Obsidian 自带 Markdown 引擎渲染,不内置 markdown-it。
- 代码块信息串中的
title="..."会显示为 Plume 风格标题栏(src/pipeline/code-fence-titles.ts)。 - 行内
`badge:tip:文本`徽章(不支持 HTML<Badge>,阅读视图会剥离未知标签)。 - 编辑时 软刷新 Plume 块;命令面板可强制整页重建预览。
- 文件树 / 代码树支持
colored/simple图标模式(simple不加载离线 Iconify SVG)。
组件示例稿:examples/plume-components.md — 每种容器的初版写法,可在 Obsidian 阅读视图中打开对照。
在线预览(GitHub Pages):https://eason596.github.io/obsidian-theme-plume/ — 由 npm run build:demo 将示例稿渲染为静态 HTML(见下方 发布预览站)。
安装
社区插件(推荐)
- 在 Obsidian 中打开 设置 → 社区插件 → 浏览,搜索 Theme Plume。
- 安装并启用插件。
若尚未出现在社区目录,可先用下方手动安装或 BRAT 从 GitHub 安装。
提交社区插件(维护者):登录 community.obsidian.md → Plugins → New plugin → 填写 https://github.com/Eason596/obsidian-theme-plume。首次提交前需已有与 manifest.json 中 version 一致的 GitHub Release(含 main.js、manifest.json、styles.css)。
手动安装(开发构建)
git clone https://github.com/Eason596/obsidian-theme-plume.git
cd obsidian-theme-plume
npm install
npm run build
将以下文件复制到库内插件目录:
<vault>/.obsidian/plugins/theme-plume/
manifest.json
main.js
styles.css
main.js 由 npm run build 生成,未提交到 Git。
在 设置 → 社区插件 中启用 Theme Plume。
升级提示:插件 ID 现为
theme-plume。若曾安装obsidian-plume或vuepress-file-tree,请删除旧插件目录后再安装,避免重复加载。
网络使用说明
本插件默认可离线使用大部分功能。以下能力仅在启用时访问网络(无服务端遥测、无账号要求):
| 功能 | 远程服务 | 何时触发 |
|---|---|---|
::: repo-card |
GitHub / Gitee REST API | 渲染含仓库 URL 的 repo-card 块 |
文件树 / 代码树 colored 图标 |
Iconify API | 离线包未覆盖的 Iconify 图标 ID |
卡片 icon= 外链图片 |
用户指定的图片 URL | 渲染含 http(s) 图标的卡片 |
可在设置中将 Default file-tree icon mode 设为 simple,并避免使用 repo-card,即可在无网络环境下使用核心容器语法。
支持的语法
与 Plume 文档 大体一致;下表对应当前 src/parser.ts / src/render.ts 已实现的块类型。
| 类别 | 语法 | 说明 |
|---|---|---|
| 文件树 | ::: file-tree |
也支持 Obsidian 围栏代码块 ```file-tree / filetree / file_tree |
| 代码树 | ::: code-tree |
单文件或虚拟目录树 + 代码高亮 |
| 目录嵌入 | @[code-tree](path) |
从库内目录读取文本文件生成代码树;路径支持 /、./、../、@source/ |
| 选项卡 | ::: tabs / ::: code-tabs |
面板以 @tab / @tab:active 分隔;可用 ::: tabs#id 或 id="..." |
| 步骤 | ::: steps 或 :::: steps |
正文为 1. / 2. 编号列表;Obsidian 内用自定义 <ol> 渲染,避免列表内 ::: 被破坏 |
| 提示 | ::: note / info / tip / warning / caution / details |
可选自定义标题 |
| 卡片 | ::: card / card-grid / card-masonry |
icon= 为 Obsidian Lucide 名或图片 URL;不支持 twemoji: |
| 折叠 | ::: collapse |
列表项为面板;支持 accordion、expand |
| 外链卡片 | ::: repo-card / link-card / image-card |
repo-card 会请求 GitHub / Gitee API(需网络) |
| 布局 | ::: field / field-group / flex / window / chat |
|
| 时间线 | ::: timeline |
支持 horizontal、card、placement、line 等属性 |
| 行内徽章 | `badge:tip:文本` |
类型与文本用 : 或 ` |
| 代码标题 | ```ts title="app.ts" |
在围栏 info 中写 title="..." |
嵌套容器(如 Card → Collapse → code-tabs)在首段渲染时会递归解析内层块。
完整可运行示例见 examples/plume-components.md(每种组件一节,便于在库内打开验收)。
片段预览
::: tabs#demo
@tab 安装
```bash
npm install
```
@tab:active 配置
::: tip
保存后切换阅读视图即可预览。
:::
:::
@[code-tree](./src)
```ts title="main.ts"
export default class ObsidianPlumePlugin extends Plugin {}
```
架构(v1.0)
| 模块 | 职责 |
|---|---|
main.ts |
插件入口、设置页、命令、解析缓存、@[code-tree] 目录扫描 |
src/parser.ts |
纯函数解析 ::: 容器、collapse 列表、@[code-tree] 嵌入 |
src/render.ts |
各容器 DOM 渲染;经 registerBlockRenderer 分发 |
src/render/pipeline.ts |
占位符 + 递归 renderInnerMarkdown |
src/render/blocks/collapse.ts |
Collapse 面板(合法 <summary>、懒加载正文) |
src/render/tabbed-container.ts |
tabs / code-tabs 共用导航与面板 |
src/render/tab-store.ts |
Tab 持久化与跨实例同步 |
src/render/code-fence.ts |
代码块标题栏 DOM |
src/render/inline.ts |
容器内行内 / 短语级 Markdown |
src/markdown/plume-markdown.ts |
MarkdownRenderer + MarkdownRenderChild 生命周期 |
src/pipeline/preview-pipeline.ts |
与 Obsidian 分段后处理器协调(首段渲染、吸收内部段) |
src/pipeline/preview-sync.ts |
未保存缓冲区、脏标记、滚动位置 |
src/pipeline/code-fence-titles.ts |
代码块 title 签名增量修补 |
src/generated/* |
离线 Iconify / VuePress 文件图标映射(npm run generate:icons) |
核心原则:不重复实现 markdown-it;顶层块在渲染前替换为 HTML 占位符,再填充组件并递归渲染内文。
设置
设置 → Theme Plume:
| 选项 | 默认值 | 说明 |
|---|---|---|
| Default file-tree icon mode | colored |
::: file-tree 未指定 icon= 时使用;simple 不加载彩色离线 SVG |
| Remember tab selection | 开启 | ::: tabs#id / ::: code-tabs#id 选中项写入 localStorage |
| Lazy collapse bodies | 开启 | 折叠面板首次展开前不渲染正文 |
| Lazy tab panels | 开启 | 仅渲染当前选项卡;当前 tab 在块显示前渲染完成 |
| Debug render errors | 关闭 | 块渲染失败时在预览中显示简短提示 |
编辑后预览采用 软刷新(只重绘 Plume 块,不整页 rerender),减轻跳动。异常时可用命令 Theme Plume: Force Refresh Current Preview 做完整重建。
命令面板
| 命令 | 作用 |
|---|---|
| Theme Plume: Force Refresh Current Preview | 对当前笔记强制整页重建阅读视图 |
| Theme Plume: Self Check | 显示版本、图标模式、预览窗数量等自检信息 |
开发
npm install
npm run check # TypeScript
npm test # Vitest(src/parser.test.ts)
npm run test:legacy # 旧版脚本测试
npm run dev # 监听构建 + 生成图标
npm run build # 类型检查 + 图标生成 + 生产构建 main.js
npm run build:demo # 生成 docs/index.html(GitHub Pages 预览)
build / dev 会自动执行 npm run generate:icons(依赖 @iconify-json/*)。
测试说明
src/parser.test.ts 中部分用例读取上级目录的 plume-complex-test.md(多仓库工作区中的综合验收稿)。若单独克隆本仓库后 npm test 报找不到该文件,可将综合测试 Markdown 放到 obsidian-theme-plume/../plume-complex-test.md,或仅运行不依赖该 fixture 的用例。
人工验收推荐使用本仓库内的 examples/plume-components.md。
与 VuePress / Plume 的差异
| 能力 | Theme Plume | VuePress Plume |
|---|---|---|
| 站点主题、导航、博客、搜索 | 否 | 是 |
| Markdown 容器与样式 | 是(子集) | 完整 |
| Mermaid / ECharts / 嵌入沙箱 | 未内置 | 支持;可配合 Obsidian 其他插件 |
repo-card |
需联网拉取仓库元数据 | 类似 |
@[code-tree] |
读取当前库内文本文件;跳过图片、音视频、Office、PDF 等 | 构建时读磁盘 |
| 阅读视图分段 | 跨段块由 preview-pipeline 首段渲染并吸收后续段(plume-section-absorbed) |
无此限制 |
<Badge> HTML |
不支持 | 支持 |
| 实时预览 + 深嵌套 | 极端场景可能与纯 VuePress 有细微差异 | — |
发布预览站(GitHub Pages)
将 examples/plume-components.md 预渲染为静态页面,发布到 GitHub Pages。
本地生成
npm install
npm run build:demo
构建成功时终端会打印 Wrote .../docs/index.html。用浏览器直接打开该文件即可本地预览(file:// 路径)。
若进程以 JavaScript heap out of memory 退出,说明 @[code-tree] 嵌入了过大目录;示例已改为 ../src,构建脚本也会跳过 main.js、offlineIconData.ts 等大文件。
输出目录 docs/:
| 文件 | 说明 |
|---|---|
index.html |
生成的预览页(不要手改,改示例后重新 build) |
styles.css |
从插件根目录复制 |
demo-base.css |
页面布局与 Obsidian 风格 CSS 变量 |
demo-client.js |
选项卡切换等静态页交互 |
首次在 GitHub 开启 Pages
- 推送代码到
main(含.github/workflows/pages.yml)。 - 打开仓库 Settings → Pages。
- Build and deployment → Source 选 GitHub Actions(不要选 “Deploy from branch”)。
- 推送触发 workflow,或到 Actions 手动运行 Deploy GitHub Pages。
- 几分钟后访问:https://eason596.github.io/obsidian-theme-plume/
之后每次改 examples/plume-components.md 或样式,推送到 main 会自动重建;也可本地 npm run build:demo 后把 docs/index.html 一并提交。
预览站用
marked渲染普通 Markdown,与 Obsidian 阅读视图在细节上可能略有差异;Plume 容器样式与 Obsidian 真环境更接近。选项卡、文件树/代码树、折叠手风琴、瀑布流等交互由docs/demo-client.js在浏览器中启用(静态 HTML 本身不含事件监听)。
发布新版本
维护者推送 semver 标签后,GitHub Actions 会自动构建并创建 Release(附件含 main.js、manifest.json、styles.css):
# 1. 更新 manifest.json 与 package.json 中的 version
# 2. 提交并推送
git push origin main
# 3. 打标签并推送(标签须与 manifest version 一致)
git tag 1.0.1
git push origin 1.0.1
发布到 GitHub
已安装 GitHub CLI 并登录后:
scripts\publish-github.cmd