#obsidian #markdown #export #note #front-matter #notes #vault

bin+lib c6o-obsidian-export

Rust 库和相关的 CLI 程序,用于将 Obsidian 保险库导出为常规 Markdown

1 个稳定版本

21.9.0 2021 年 9 月 23 日

#804 in 文本处理

MIT/Apache

84KB
1K SLoC

Obsidian 导出

Obsidian 导出是一个 CLI 程序和 Rust 库,用于将 Obsidian 保险库导出为常规 Markdown。

  • 递归导出 Obsidian Markdown 文件到 CommonMark
  • 支持 [[note]] 风格的引用以及 ![[note]] 文件包含。
  • 支持 gitignore 风格的排除模式(默认:.export-ignore)。
  • 当保险库位于 Git 仓库中时,自动排除 Git 忽略的文件。
  • 在所有主要平台上运行:Windows、Mac、Linux、BSDs。

请注意,obsidian-export 并非官方认可由 Obsidian 团队支持。它支持大部分但并非全部的 Obsidian Markdown 风格。

安装

预构建的二进制文件

为 Windows、Linux 和 Mac 操作系统提供针对 x86-64 处理器的二进制发布。它们作为在 .github/workflows/release.yml 中定义的发布工作流程的一部分使用 GitHub 运行者构建。

生成的二进制文件可以从 https://github.com/zoni/obsidian-export/releases 下载。

从源代码构建

当您的平台没有提供二进制发布,或者您不信任预构建的二进制文件时,可以通过以下步骤使用 obsidian-export 进行源代码编译,相对较为简单。这是通过 Rust 的官方包管理器 Cargo 完成的。

  1. https://rust-lang.net.cn/tools/install 安装 Rust 工具链
  2. 运行:cargo install obsidian-export

预期你在安装Rust工具链时正确配置了PATH变量,如https://rust-lang.net.cn/tools/install中“配置PATH环境变量”部分所述。

从早期版本升级

如果你下载了预构建的二进制文件,通过下载最新版本来替换旧版本以进行升级。

如果你从源代码构建,再次运行cargo install obsidian-export进行升级。

基本用法

obsidian-export 的主要界面是 obsidian-export CLI命令。作为文本界面,这必须在终端或Windows PowerShell中运行。

假设你熟悉命令行界面,并且如果你用cargo安装,你已正确设置了PATH。运行obsidian-export --version应该打印版本号而不是某些错误。

如果你下载了预构建的二进制文件,并且没有将其放在PATH引用的位置(例如,你将其放在Downloads中),则需要提供二进制的完整路径。

例如,在Mac/Linux上~/Downloads/obsidian-export --version或在Windows(PowerShell)上~\Downloads\obsidian-export --version

导出笔记

在其最基本的形式中,obsidian-export 只需要两个必填参数,源和目标

obsidian-export /path/to/my-obsidian-vault /path/to/exported-notes/

这将从 my-obsidian-vault 导出所有文件到 exported-notes,除了在 .export-ignore.gitignore 中列出的文件。

请注意,目标目录必须存在,因此你可能需要首先创建一个新的空目录。

如果你提供了一个已存在的目录,该目录下的文件可能会被覆盖。

也可以导出单个文件

# Export as some-note.md to /tmp/export/
obsidian-export my-obsidian-vault/some-note.md /tmp/export/
# Export as exported-note.md in /tmp/
obsidian-export my-obsidian-vault/some-note.md /tmp/exported-note.md

请注意,在此模式下,obsidian-export 将some-note.md视为你的库中存在的唯一文件,因此对其他笔记的引用将不会被解析。这是故意的。

如果你想要导出一个单个笔记同时解析库中其他区域的链接或嵌入,那么你应该指定库的根作为源,传递你想要导出的文件,使用--start-at,如下一节所述。

导出部分库

使用--start-at参数,你可以仅导出库的一部分。给定以下库结构

my-obsidian-vault 
├── Notes/
├── Books/
└── People/

这将仅将Books目录中的笔记导出到exported-notes

obsidian-export my-obsidian-vault --start-at my-obsidian-vault/Books exported-notes

在此模式下,所有在源(第一个参数)下的笔记都被视为库的一部分,因此对这些文件的任何引用都将保持完整,即使它们不是导出笔记的一部分。

字符编码

目前,假设所有笔记文本以及文件名都使用UTF-8字符编码。所有文本和文件处理都执行有损转换为Unicode字符串

使用非UTF8编码可能导致文本替换错误和无法找到链接笔记等问题。尽管未来可能会有所改变,但短期内没有计划更改此行为。

高级用法

前导内容

默认情况下,前导内容将“原样”复制。

一些静态网站生成器对前导内容比较挑剔,并要求其存在。有些生成器在Markdown文件没有前导内容但以列表项或水平线开头时会遇到问题。在这些情况下,可以使用--frontmatter=always来插入一个空的前导内容条目。

要完全从导出的笔记中删除任何前导内容,请使用--frontmatter=never

忽略文件

默认情况下,隐藏文件、在.export-ignore中列出的模式以及git忽略的任何文件(如果您的保险库是git仓库的一部分)将不包括在导出中。

如果需要,可以使用--hidden--ignore-file--no-git来调整这些选项。(有关更多信息,请参阅--help)。

链接到忽略笔记的笔记将被取消链接(它们只包含链接文本)。忽略笔记的嵌入将被完全跳过。

忽略文件语法

.export-ignore文件的语法与gitignore文件的语法相同。以下是一个示例

# Ignore the directory private that is located at the top of the export tree
/private
# Ignore any file or directory called `test`
test
# Ignore any PDF file
*.pdf
# ..but include special.pdf
!special.pdf

有关更全面的文档和示例,请参阅gitignore手册页。

递归嵌入

当两个笔记相互嵌入时,可能会出现“递归嵌入”。例如,当Note A.md包含![[Note B]]Note B.md也包含![[Note A]]时,就会发生这种情况。

默认情况下,这将触发一个错误并显示导致递归的笔记链。

可以通过指定--no-recursive-embeds来更改此行为。使用此模式,如果在处理原始笔记时遇到第二次遇到的笔记,则插入到笔记的链接,而不是再次嵌入它,以打破循环。

Hugo静态网站生成器不支持文件相对链接。相反,它期望您使用refrelref简码来链接到其他页面。

因此,使用obsidian-export导出的笔记不能直接使用,因为Hugo无法正确解析这些链接。

Markdown Render Hooks(仅支持默认的goldmark渲染器)允许您绕过此问题,使导出的笔记在完成一些一次性设置工作后与Hugo一起使用。

创建文件layouts/_default/_markup/render-link.html,内容如下

{{- $url := urls.Parse .Destination -}}
{{- $scheme := $url.Scheme -}}

<a href="
  {{- if eq $scheme "" -}}
    {{- if strings.HasSuffix $url.Path ".md" -}}
      {{- relref .Page .Destination | safeURL -}}
    {{- else -}}
      {{- .Destination | safeURL -}}
    {{- end -}}
  {{- else -}}
    {{- .Destination | safeURL -}}
  {{- end -}}"
  {{- with .Title }} title="{{ . | safeHTML }}"{{- end -}}>
  {{- .Text | safeHTML -}}
</a>

{{- /* whitespace stripped here to avoid trailing newline in rendered result caused by file EOL */ -}}

以及用于图片的layouts/_default/_markup/render-image.html

{{- $url := urls.Parse .Destination -}}
{{- $scheme := $url.Scheme -}}

<img src="
  {{- if eq $scheme "" -}}
    {{- if strings.HasSuffix $url.Path ".md" -}}
      {{- relref .Page .Destination | safeURL -}}
    {{- else -}}
      {{- printf "/%s%s" .Page.File.Dir .Destination | safeURL -}}
    {{- end -}}
  {{- else -}}
    {{- .Destination | safeURL -}}
  {{- end -}}"
  {{- with .Title }} title="{{ . | safeHTML }}"{{- end -}}
  {{- with .Text }} alt="{{ . | safeHTML }}"
  {{- end -}}
/>

{{- /* whitespace stripped here to avoid trailing newline in rendered result caused by file EOL */ -}}

配置了这些钩子后,现在链接到笔记以及文件附件应该可以正确工作。

注意:如果您使用的是带有自己的渲染钩子的主题,可能需要进行一些额外的工作,或者自定义上述片段,以避免与主题的钩子冲突。

库使用

所有由 obsidian-export CLI 命令暴露的功能,也可以通过 obsidian_export crate 以 Rust 库的形式访问。

要开始使用,请访问 obsidian_exportobsidian_export::Exporter 库的文档。

许可证

Obsidian-export 同时使用 Apache 2.0MIT 许可证。

除非您明确声明,否则根据 Apache-2.0 许可证的定义,您有意提交给本项目的任何贡献都应按上述方式双重许可,不附加任何额外的条款或条件。

变更日志

v21.9.0 (2021-09-12)

此版本切换到 日历版本控制方案。有关此决定的详细信息,请参阅 switching obsidian-export to CalVer

新增

  • 支持在嵌入式笔记上运行后处理器。[Nick Groenen]

    这引入了对在另一个笔记中嵌入的笔记结果上运行的 postprocessor 的支持。这与现有的 postprocessor(保持不变)不同,后者在所有嵌入处理并合并到最终笔记后才运行。

    这些“嵌入后处理器”可以通过新的 Exporter::add_embed_postprocessor 方法设置。

  • 添加 start_at 选项以导出部分库。[Nick Groenen]

    这引入了新的 CLI 参数 --start-at 和相应的 start_at() 方法,允许仅导出库中的给定子目录。

    有关何时以及如何使用此功能的详细信息,请参阅更新的 README 文件。

其他

  • 不要为 bin 目标构建文档。[Nick Groenen]

    库包含涵盖 CLI 和库使用的文档,没有为二进制目标单独的文档。

  • 将后处理器测试移动到自己的文件以提高清晰度。[Nick Groenen]

  • 更新间接依赖。[Nick Groenen]

  • 将 serde_yaml 从 0.8.19 更新到 0.8.20。[dependabot[bot]]

    serde_yaml 从 0.8.19 更新到 0.8.20。


    updated-dependencies

    • 依赖名称:serde_yaml 依赖类型:直接 生产类型:更新:semver-patch ...
  • 不要借用立即解引用的引用。[Nick Groenen]

    这被最近引入的 clippy 规则捕获

  • 将 serde_yaml 从 0.8.17 更新到 0.8.19。[dependabot[bot]]

    serde_yaml 从 0.8.17 更新到 0.8.19。


    updated-dependencies

    • 依赖名称:serde_yaml 依赖类型:直接 生产类型:更新:semver-patch ...
  • 更新依赖项。[Nick Groenen]

  • 修复 4 个新的 clippy 检查。[Nick Groenen]

  • 将 regex 从 1.4.6 更新到 1.5.3。[dependabot[bot]]

    regex 从 1.4.6 更新到 1.5.3。

  • 将 pretty_assertions 从 0.7.1 更新到 0.7.2。[dependabot[bot]]

    pretty_assertions 从 0.7.1 更新到 0.7.2。

  • 将 regex 从 1.4.5 更新到 1.4.6。[dependabot[bot]]

    regex 从 1.4.5 更新到 1.4.6。

v0.7.0 (2021-04-11)

新增

  • 支持后处理。[Nick Groenen]

    在将转换后的笔记写入磁盘之前,添加对 Markdown 的后处理支持。

    当使用 Obsidian 导出作为 Rust 库时,可以使用后处理器执行以下操作:

    1. 修改笔记的 Context,例如更改目标文件名或更新其元数据。
    2. 通过修改 MarkdownEvents 来更改笔记的内容。
    3. 防止后续的处理器运行或导致整个笔记被跳过。如果可以识别出通用用例,未来版本的 Obsidian 导出可能会自带用于命令行工具用户的内置处理器。

    例如,未来版本可能包括使笔记更适合 Hugo 静态网站生成器的功能。此功能将作为可以通过命令行标志启用的后处理器来实现。

修复

  • 也在文件名中对 ? 进行百分比编码。[Nick Groenen]

    最近的一次 Obsidian 更新扩展了文件名中允许的字符列表,现在包括 ?。在像 Hugo 这样的静态网站生成器中,这需要百分比编码以生成正确的链接。[Nick Groenen]

其他

v0.6.0 (2021-02-15)

新增

  • 添加 --version 标志。[Nick Groenen]

变更

  • 不要在 WalkOptions 中 Box FilterFn。[Nick Groenen]

    之前,在 WalkOptions 结构体上的 filter_fn 看起来是这样的

    pub filter_fn: Option<Box<&'static FilterFn>>,
    

    这种装箱是不必要的,已经改为

    pub filter_fn: Option<&'static FilterFn>,
    

    这只会影响那些在其他 Rust 程序中将 obsidian-export 作为库的用户,而不是 CLI 的用户。

    对于这些库用户,他们不再需要提供包装在 Box 中的 FilterFn

修复

  • 识别以下划线开头的笔记。[Nick Groenen]

    由于假设底层的 Markdown 解析器(pulldown_cmark)会在 [[]] 之间发出一个单独的事件,因此带有下划线的笔记在 Obsidian 中会失败识别 [[_WikiLinks]]

    现在,笔记解析器已经重写,使用了一个更可靠的状态机,可以正确识别这个边缘情况(以及可能的一些其他情况)。

  • 支持自引用。[Joshua Coles]

    这确保了在同一笔记内链接到标题([[#Heading]])可以正确解析。

其他

  • 避免在 GitHub 发布标题中重复“发布”。[Nick Groenen]

  • 为带有下划线的文件添加失败的测试用例。[Nick Groenen]

  • 为 ObsidianNoteReference 的显示添加单元测试。[Nick Groenen]

  • 为 ObsidianNoteReference::from_str 添加一些单元测试。[Nick Groenen]

  • 也在拉取请求上运行测试。[Nick Groenen]

  • 应用 rust 1.50.0 的 clippy 建议。[Nick Groenen]

  • 修复与当前文件引用相关的无限递归错误。[Joshua Coles]

  • 为自引用添加测试。[Joshua Coles]

    请注意,由于目前没有支持块引用,生成的链接没有地方可去,但是它指向了一个合理的 ID。

  • 将 tempfile 从 3.1.0 升级到 3.2.0。[dependabot[bot]]

    tempfile 从 3.1.0 升级到 3.2.0。[dependabot[bot]]

  • 将 eyre 从 0.6.3 升级到 0.6.5。[dependabot[bot]]

    eyre 从 0.6.3 升级到 0.6.5。[dependabot[bot]]

  • 将 regex 从 1.4.2 升级到 1.4.3。[dependabot[bot]]

    regex 从 1.4.2 升级到 1.4.3。

v0.5.1 (2021-01-10)

修复

  • 在用小写引用时找到大写的笔记。 [Nick Groenen]

    此提交修复了一个错误,当笔记包含大写字母(例如 Note.md)但使用小写引用时(例如 [[note]]),该笔记将无法找到。

v0.5.0 (2021-01-05)

新增

  • 添加 --no-recursive-embeds 以打破无限递归循环。 [Nick Groenen]

    当两个笔记相互嵌入时,可能会出现“递归嵌入”。例如,当Note A.md包含![[Note B]]Note B.md也包含![[Note A]]时,就会发生这种情况。

    默认情况下,这将触发一个错误并显示导致递归的笔记链。

    使用新的 --no-recursive-embeds,如果在处理原始笔记时遇到第二次笔记,将插入笔记的链接而不是再次嵌入,以打破循环。

    另请参阅:https://github.com/zoni/obsidian-export/issues/1

  • 在 CLI 上使遍历选项可配置。 [Nick Groenen]

    默认情况下,隐藏文件、在 .export-ignore 中列出的模式以及任何由 git 忽略的文件都将从导出中排除。此行为已通过新的标志 --hidden--ignore-file--no-git 在 CLI 上进行配置。

  • 支持引用标题的链接。 [Nick Groenen]

    以前,引用标题的链接([[note#heading]])将仅链接到文件名,而不会在链接目标中包含锚点。现在,此类引用将包括适当的 #anchor 属性。

    请注意,原始 Markdown 规范以及更近期的 CommonMark 标准都没有指定如何为给定标题构造锚点。

    各种 Markdown 渲染实现之间也有一些差异。

    Obsidian-export 使用 slug crate 生成锚点,应该与大多数实现兼容,但您的实际使用情况可能会有所不同。

    (例如,GitHub 在标题以笑脸结束时会将一个尾随的 - 留在锚点上。slug 库以及因此 obsidian-export 将避免此类悬挂破折号)。

  • 支持引用标题的嵌入。 [Nick Groenen]

    以前,部分嵌入(![[note#heading]])总是将整个文件包含到源笔记中。现在,此类嵌入将仅包含引用标题(以及任何子标题)的内容。

    目前不支持链接和嵌入任意块。 [Nick Groenen]

变更

  • 将警告信息打印到 stderr 而不是 stdout。 [Nick Groenen]

    在遇到损坏的链接/引用时发出的警告信息现在将打印到 stderr 而不是 stdout。

其他

  • 在 WalkOptions 调试显示中包含 filter_fn 字段。 [Nick Groenen]

v0.4.0 (2020-12-23)

修复

  • 修复嵌入式笔记中的相对链接。 [Nick Groenen]

    嵌入式笔记中的链接将指向相对于笔记所在文件系统位置的本地资源。

    当不同目录中的笔记嵌入此类笔记时,这些链接将指向无效的位置。

    现在这些链接是相对于顶层笔记计算的,这确保了这些链接将指向正确的路径。

其他

  • 为所有公共类型和函数添加简短的库文档。 [Nick Groenen]

v0.3.0 (2020-12-21)

新增

  • 当达到递归限制时报告文件树。 [Nick Groenen]

    此代码重构了上下文,以维护一个链表中所有已处理的文件的列表。当返回RecursionLimitExceeded时,此信息用于向CLI用户打印更有用的错误信息。

变更

  • 在多行警告周围添加额外的空格。[Nick Groenen]

    这使在打印了多次警告之后更容易区分错误。

其他

  • 设置gitchangelog。[Nick Groenen]

    此版本添加了变更日志(CHANGES.md),它是使用gitchangelog自动生成的。

v0.2.0(2020-12-13)

  • 允许在WalkOptions中传递自定义过滤函数。[Nick Groenen]

  • 从crate根重新导出vault_contents和WalkOptions作为pub。[Nick Groenen]

  • 也对README.md运行mdbook钩子。[Nick Groenen]

  • 更新安装说明。[Nick Groenen]

    由于crate已发布,安装不再需要git仓库URL。

  • 添加MdBook生成脚本和precommit钩子。[Nick Groenen]

  • 添加更可靠的非ASCII测试用例。[Nick Groenen]

  • 创建FUNDING.yml。[Nick Groenen]

v0.1.0(2020-11-28)

  • 公开发布。[Nick Groenen]

依赖项

~9–19MB
~248K SLoC