Obsidian Excalidraw 画布构建器
生成能够被 Obsidian Excalidraw 插件正确打开的 .excalidraw.md 文件,支持手写 LaTeX 块、带绑定的箭头和主题匹配的颜色。
何时使用
- 在仓库中构建知识地图 / 决策树 / 公式板作为 Excalidraw 画布
- 将 Markdown 大纲或笔记转换为可视化画布
- 修复渲染为损坏图像、不可见文本、巨大公式或意外白色/深色背景的画布
- 使新画布与同一仓库中现有画布的视觉语言相匹配
请勿用于独立的 .excalidraw JSON(提供给 Web 应用),或用于渲染 PNG/SVG——如需区分,请参见 references/when-not-to-use.md。
黄金法则(来之不易的经验)
- LaTeX 不是文本。 公式是
type: "image"元素,其源码位于## Embedded Files部分,格式为<40-hex-id>: $$tex$$。没有匹配 Embedded Files 条目的图像元素将渲染为损坏图像。参见references/latex.md。 - 请勿在文本元素中手写
$$...$$——对于此插件,它会显示原始源码。插件只会渲染存在于 Embedded Files 中的公式。 - 场景主题并非权威。 插件会用应用级主题覆盖
appState.theme。因此画布颜色来自viewBackgroundColor,但浅色主题无论如何都会绘制为白色。参见references/theme-and-color.md。 - 在发明颜色之前,先复制同一仓库中现有画布的调色板。 使用
scripts/inspect_canvas.mjs解压一个,读取其描边颜色和字体系列,并复用它们。 - 统一的公式高度,基于长度的宽度。 固定的较大宽度会将短公式拉伸成巨无霸。参见
references/layout.md。 - 插件会重新保存为
compressed-json(LZString base64,约每 120 字符换行)。请从生成器脚本重新生成画布,而不是修补已保存的文件。读取它需要解压——scripts/inspect_canvas.mjs可以做到。 - 在声称成功之前先验证。 运行检查脚本,确认:公式数量等于图像数量,没有悬空绑定,主题/背景符合预期。
- “看起来不错”是可衡量的。 容器比例 ≤ 30%,≤ 4 种字体大小,公式高度方差为 0,重叠数为 0。
scripts/inspect_canvas.mjs现在会将这些打印为美学警告;将任何警告视为缺陷,而非偏好。参见references/design-metrics.md。 - 一次性写入,使用稳定的 ID,先删除。 元素 ID 必须源自内容(文本 / TeX / 标签的哈希),绝不能随机。并且在写入之前取消链接目标文件。如果不这样做,重新生成一个当前在 Obsidian 中打开的画布会将新元素合并到实时场景中:所有内容都会加倍,插件会将加倍的场景自动保存回磁盘。参见
references/troubleshooting.md→ “元素重复/三倍”。 - 交付前先渲染。
scripts/render_preview.mjs可无头光栅化文件(Node,无需浏览器)。查看 PNG——JSON 审计只能捕获结构,只有像素才能捕获“间距看起来不对”。LaTeX 在该预览中会显示为空白(MathJax 存在于 Obsidian 插件中,而不是渲染器中),因此在那里判断布局,从## Embedded Files判断公式正确性。 - 仅一层
$$。 数据模型中的 TeX 是裸的(A=\int…);分隔符仅在发出## Embedded Files行时添加。生成的文件中任何$$$都是双重包裹的错误,会渲染为字面意义的美元符号。
两种布局流派——绘图前选择一种
| 列网格 | 线为结构 | |
|---|---|---|
| 形状 | 列框 + 行分隔线 | 主干线 + 下垂线 + 自由浮动文本 |
| 容器比例 | 高(每列一个框) | 接近 0 |
| 可读性 | 类似查找表,严谨 | 类似黑板,轻量 |
| 最适合 | 许多同级别行,需要逐单元格检查 | 分支结构,或相互派生的列 |
| 失败模式 | “看起来像幻灯片模板” | 分支太多 -> 线条交叉 |
经验法则:兄弟列 -> 列网格;一列从另一列派生 -> 结构线。 这两种例子都存在于 design-metrics.md 中,内容相同(第十讲画布),因此您可以在选择前进行比较。
工作流程
- 读取目标仓库约定。 找到用户喜欢的现有
.excalidraw.md文件,运行node scripts/inspect_canvas.mjs <file>并记录:主题、viewBackgroundColor、主导描边颜色、fontFamily、roughness、典型字体大小。 - 将设计内容组织为列或行(参见
references/layout.md)——每个数量/步骤系列一列,每个公式一行,仅对实际相同的数量进行分组。根据上表选择布局流派(列网格或结构线)。 - 编写生成器脚本,以
scripts/gen_canvas.mjs为模型:编辑其CONFIG块(标题、列、行)并运行。不要手动编辑 30 kB 的 JSON。保留它附带的两个安全机制:内容派生 ID 和writeFileSync前的rmSync。 - 检查结果,使用
scripts/inspect_canvas.mjs,修复计数/颜色/绑定。同时确认文件中没有$$$,并且元素数量等于生成器打印的数量(若是其倍数,则说明发生了合并错误)。然后渲染它,使用scripts/render_preview.mjs并实际查看 PNG;在报告之前修复间距/重叠/短行问题。 - 报告用户在 Obsidian 中需要做什么(关闭并重新打开文件,或使用“解压当前 Excalidraw 文件”命令)——插件仅在文件重新打开时才会重新读取它。
参考地图
| 文件 | 内容 |
|---|---|
references/file-format.md | 精确的 .excalidraw.md 骨架、两种编码、节顺序、头部注释 |
references/element-schema.md | 每种元素类型所需的字段、绑定文本、箭头绑定、index 排序 |
references/latex.md | Embedded Files 协议、\color、大小调整、测试过的三种渲染变体、失败特征 |
references/theme-and-color.md | 画布为何以白色打开、matchThemeAlways、调色板提取、此仓库已建立的颜色 |
references/layout.md | 列/行几何、公式大小启发式、导致画布看起来未完成的原因 |
references/script-engine.md | 插件内的 JS 脚本引擎:脚本放哪、能干什么、ExcalidrawAutomate API、能不能做表格、与文件级生成的取舍 |
references/design-metrics.md | 量化美学:容器比例、字体级别数量、公式方差、空白、语义颜色;两种布局流派;如何在没有渲染器的情况下验证 |
references/troubleshooting.md | 迄今为止所有失败的症因-原因-修复表格 |
scripts/gen_canvas.mjs | 配置驱动的画布生成器(文本、LaTeX、矩形、水平线、箭头) |
scripts/inspect_canvas.mjs | 解压 + 审计:主题、计数、公式/图像匹配、绑定、字体、美学度量。--describe 打印紧凑的 ID/位置/标签/连接清单;--dump 打印原始场景 JSON |
scripts/render_preview.mjs | 通过 mcp-excalidraw-server render 进行无头 PNG 预览(无需浏览器)。LaTeX 渲染为空白——仅用于布局 |
evals/evals.json | 回归测试提示:每个实际发生的失败模式一个 |
examples/ea-table.md | 一个可运行的应用内脚本,用矩形+文本构建表格 |
编辑现有画布
- 解压它以了解当前状态(
inspect_canvas.mjs --dump <file>打印场景 JSON)。 - 优先从生成器脚本重新生成。如果用户有值得保留的手动编辑,请编写一个作用域转换(读取场景 -> 修改特定元素 -> 重新序列化为未压缩格式),而不是重写整个画布。
- 永远不要留下半迁移的画布:要么每个图像都有其公式,要么没有。
此仓库的默认大小和排版
- 正文文本
fontFamily: 6、roughness: 0、strokeWidth: 1。 - 标题 28–30 px,列标题 19–22 px,行标签 15–16 px,公式图像高度 50–52 px。
- 行间距 116–130 px;列宽 320–340 px;间距 28–40 px。
- 画布背景
#ffffff;墨水#1e1e1e;柔和#868e96;细线#e9ecef。