ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Zotero Better Notes Markdown Flavor 兼容性实战:让 Obsidian 扩展语法在同步中存活

Zotero Better Notes Markdown Flavor 兼容性实战:让 Obsidian 扩展语法在同步中存活 知识管理知识库AI 写作【免费下载链接】zotero-better-notesEverything about note management. All in Zotero.项目地址https://gitcode.com/gh_mirrors/zo/zotero-better-notes点击查看免费下载Better Notes 会把 Zotero 笔记与标准 Markdown 文件双向同步当你在 Obsidian、Logseq、Typora 等外部编辑器中使用 Wiki 链接、嵌入、Callout 等扩展 Markdown语法时同步回写可能让语法被转义如[[Page]]变成\[\[Page]]甚至丢失如任务列表。本篇结合官方兼容性文档 docs/markdown-flavor-compatibility.md 与仓库源码讲清哪些语法会原样存活、哪些会被改写、背后的转义机制以及如何用内置的[ExportMDFileContent]模板一行行写回你需要的 Flavor。为什么同步后语法前面会多出\Zotero 的每一条笔记都以HTML存储而不是 Markdown。Better Notes 写出.md文件时会把笔记 HTML 交给标准、符合规范的 Markdown 处理器remark 生态转成 Markdown。符合规范的处理器被要求转义一切可能被误认为 Markdown 语法的文本以保证文件往返round-trip时含义不变。扩展语法不属于规范因此在处理器眼里[[Page]]就是一个字面量[加[Page]它为了防止歧义会写成\[\[Page]]。这带来两个关键结论Better Notes 自身产生的格式永远是安全的加粗、斜体、编辑器里创建的链接、引用citations、图片、公式、表格、高亮、文字颜色都是笔记中的真实元素双向转换都干净利落。只影响你在外部文件里以纯文本方式敲入的扩展语法Zotero 侧没有对应元素它们以字面字符存储导出时自然被转义。这一点是有意为之且不会全局改变官方 issue #1337 的结论。作为替代Better Notes 提供了对导出 Markdown 做后处理的钩子——[ExportMDFileContent]模板本文后半部分全部围绕它展开。源码印证导出管线在哪里执行模板从源码结构看完整导出管线位于 note2mdnote2rehype在独立的 convert workersrc/extras/convertWorker/main.ts中把笔记 HTML 解析为 hast 树依次处理高亮节点、引用节点、笔记链接节点、图片节点复制附件图片到同步目录rehype2md把 hast 转成 Markdown 字符串随后执行[ExportMDFileContent]模板把mdContent与noteItem传入模板的返回值才最终写盘见 src/utils/convert.ts若开启 YAML 头再追加[ExportMDFileHeaderV2]生成的 front-matter。第 3 步使用的正是标准、规范合规的处理器转义行为由此而来见 remark2mdProcessorconst remark2mdProcessor unified() .use(remarkGfm) .use(remarkMath) .use(remarkStringify, { // mdast-util-to-markdown v2 changed the default to one; keep the // old output format so synced MD files do not change listItemIndent: tab, ... });也就是说转义不是 Better Notes 的bug而是remarkStringify这类规范字符串化器的固有职责——这也解释了为什么修复手段只能是导出后处理模板而不是改转换器本身。哪些语法存活哪些不存活以下清单基于官方文档对当前转换器的实测存活指.md文件中字符逐字不变Flavor示例导出note → md结果修复方式高亮text存活无需处理标签#tag、#a/b存活无需处理Obsidian 注释%%text%%存活无需处理图片尺寸后缀... \| 500存活无需处理行内/块级公式$x$、$$x$$存活无需处理Wiki 链接[[Page]]变为\[\[Page]]用下面的模板嵌入![[image.png]]变为!\[\[image.png]]用下面的模板Callout 标记 [!note]变为 \[!note]用下面的模板字面链接语法以纯文本输入的text变为\[text]\(url)用下面的模板任务列表/复选框- [ ] todo退化为普通列表- todo模板无法修复见任务列表关于高亮的一个重要区分Better Notes编辑器自带高亮器产生的高亮导出为span stylebackground-color:……/spanHTML。Obsidian 能正确渲染这种 HTML但它不是...语法若你希望导出成...见可选配方。而你在外部文件里手敲的...会原样保留。为什么图片尺寸后缀| 500能存活从源码看图片导出时把宽度编码进了alt文本processN2MRehypeImageNodes 中若有width属性则node.properties.alt ${alt} | ${width}反向导入时processM2NRehypeMetaImageNodes 会解析 alt 末尾的| 数字还原为宽度属性。因为这一后缀是转换器自己定义并消费的格式所以能无损往返而[[...]]这类外部生态语法没有对应的解析逻辑只能被当作普通文本转义。修复方案编辑[ExportMDFileContent]模板每次 Better Notes 写.md文件时都会对你的模板跑一遍结果。模板内有两个可用变量mdContent— 导出的 Markdown 字符串noteItem— 对应的 Zotero 笔记条目你return什么什么就被写盘。默认模板原样返回内容见 DEFAULT_TEMPLATES${{ return mdContent; }}$编辑入口Zotero 菜单 →Tools→Note Template Editor在列表中选择[ExportMDFileContent]替换其正文即可。模板编辑器为该模板注入的变量提示见 src/modules/template/editorWindow.ts全局类型声明见 scripts/types/templates.d.tsmdContent: string。系统模板名清单中它是受保护的内置名见 SYSTEM_TEMPLATE_NAMES。可直接粘贴保留 Obsidian 各 Flavor将下面模板粘贴进[ExportMDFileContent]。它会还原 Wiki 链接、嵌入、Callout 标记和手敲高亮的转义同时跳过代码块/行内代码绝不误伤代码示例并且是幂等的——每次同步含双向同步重复执行都安全${{ // Split off fenced code blocks and inline code so we never rewrite code. const parts mdContent.split(/([\s\S]*?|[^\n]*)/g); return parts .map((seg, i) { if (i % 2 1) return seg; // a code segment — leave untouched return seg // ![[embed]] must be handled before [[wikilink]] .replace(/!\\\[\\\[/g, ![[) .replace(/\\\[\\\[/g, [[) // highlight (only if it was escaped) .replace(/\\/g, ) // callout marker inside a blockquote: \[!note] - [!note] .replace(/(^|\n)(\s*\s*)\\\[!/g, $1$2[!); }) .join(); }}$实现要点逐条对照先用split(/(…|…)/g)把围栏代码块与行内代码切成奇偶交替的片段奇数下标段是代码、原样跳过因此代码里出现[[...]]也不会被改写![[...]]的还原规则必须放在[[...]]之前否则嵌入前缀!之后的\[\[会被 Wiki 链接规则抢先处理Callout 规则用(^|\n)(\s*\s*)锚定行首的引用符避免误伤普通文本中的\[!。只取你需要的规则如果只用部分 Flavor保留对应的.replace(...)行即可想保留的语法添加的行Wiki 链接[[Page]].replace(/\\\[\\\[/g, [[)嵌入![[file]].replace(/!\\\[\\\[/g, ![[)放在 Wiki 链接规则之前手敲高亮x.replace(/\\/g, )Callout 标记 [!x].replace(/(^|\n)(\s*\s*)\\\[!/g, $1$2[!)可选配方把 Better Notes 高亮转成...如果你用 Better Notes 编辑器做高亮、希望导出成 Obsidian 的...而不是 HTMLspan在上面的链式调用里追加这一行它只匹配高亮 span不影响彩色文字等其它 span.replace( /span stylebackground-color:[^]*([\s\S]*?)\/span/g, $1, )注意这是单向变换note → md。文件同步回 Zotero 后...仍是字面文本除非你再次在 Zotero 中用高亮器标一遍。双向同步的注意事项Wiki 链接、Callout、高亮、标签、注释配好上面模板后即可放心往返——它们在笔记中按字面文本存储下次导出时会被模板正确重写。嵌入![[file]]会被转成标准图片。导入侧的解析器会主动把 Obsidian 风格图片嵌入重写成标准语法见 md2remark 中的预处理str.replace(/!\[\[(.*)\]\]/g, (s) ![](${s.slice(3, -2)}))。因此![[image.png]]进 Zotero 后就变成了普通图片节点再导出只会得到![](image.png)模板能把\[\[还原成[[但无法恢复已经变成图片的嵌入。如果依赖![[...]]建议只改外部文件里的对应行不要让它在 Zotero 侧被消化。模板只在导出侧运行note → md。导入侧的转换函数 md2note 中不存在对应的内容模板调用——外部编辑器写进文件的任何内容回 Zotero 时都会原样接受除图片、引用等自带节点处理外。任务列表复选框为什么不可恢复- [ ] todo是 GitHub-Flavored-Markdown 特性转换器能解析管线挂载了remarkGfm见 src/extras/convert.ts但 Zotero 的笔记编辑器没有复选框元素从源码结构看导入时 mdast 中的任务列表项被转换为普通列表项勾选状态在到达导出之前就已丢失官方 issue #1406。所以这无法用导出模板修复——信息在更早的环节就没了。可行的替代方案把任务列表只保留在外部文件里不依赖 Zotero 侧重新渲染或者用能往返的纯文本/emoji 表达状态例如- ⬜ todo/- ✅ done。遇到新 Flavor 如何自行排查绝大多数扩展 Flavor 都遵循同一模式被转义的标点escaped punctuation。若本文未覆盖你使用的语法先在项目讨论区discussions提交一个最小 before/after 示例——你敲入的内容对比最终.md文件里的实际内容。由于导出走的是标准 Markdown 处理器拿到实际输出后通常只需在[ExportMDFileContent]里再加一条.replace(...)就能还原方法与上文 Obsidian 模板完全一致。写模板的完整语法${...}单行表达式、${{...}}$多行函数、变量作用域、Pragma 等见 Use Note Template其中内置模板表也将ExportMDFileContent的变量声明为noteItem, mdContent与本文所述一致。赞分享知识管理知识库AI 写作【免费下载链接】zotero-better-notesEverything about note management. All in Zotero.项目地址https://gitcode.com/gh_mirrors/zo/zotero-better-notes点击查看免费下载相关推荐Zotero-Better-Notes与Markdown双向同步无缝衔接Obsidian等编辑器Zotero Better Notes与Markdown双向同步无缝衔接Obsidian等编辑器 痛点与解决方案告别笔记孤岛 你是否经历过这样的困境在Zo知识管理知识库AI 写作Zotero-Better-Notes中的Markdown语法支持写作更高效Zotero Better Notes中的Markdown语法支持写作更高效 引言为什么Markdown支持对学术写作至关重要 在信息爆炸的时代研究人员和知识管理知识库AI 写作Zotero-Better-Notes跨设备同步实战指南让学术笔记无处不在Zotero Better Notes跨设备同步实战指南让学术笔记无处不在 您是否曾经遇到过这样的困扰在办公室电脑上精心整理的文献笔记回到家中的笔记本上却知识管理知识库AI 写作上一篇革命性视觉Transformer模型pit_b_distilled_224.in1k如何用74.8M参数实现ImageNet-1k高效分类下一篇vibe-server 完全指南基于 ggml.cpp 的本地转写引擎与 OpenAI 兼容 HTTP 服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表