news 2026/9/14 5:00:47

Example Obsidian Links

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Example Obsidian Links

Example Obsidian Links

【免费下载链接】harperOffline, privacy-first grammar checker. Fast, open-source, Rust-powered项目地址: https://gitcode.com/GitHub_Trending/har/harper

Below, you will find a number of example links that Obsidian is able to process.

These should be treated as normal Markdown links. The things inside the square brackets are visible and should be checked by Harper.

[[Three lws of motion]] Three las of motion

Wikilinks allow you to replace the visible text with a pipe (|) operator. The text to the left of the operator should be ignored.

[[lnk tget|Link Text]]

这份文件同时承担了三个角色,逐层拆解如下: 1. **它本身是一篇被检查的文档**。文件中故意埋入了拼写错误:`lws`(应为 *laws*)、`las`(应为 *laws*)、`lnk tget`(应为 *link target*),用来验证哪些位置的错误会被 Harper 捕获。 2. **它定义了 Wiki 链接的语义契约**,原文档中给出了两条明确规则: - “These should be treated as normal Markdown links. The things inside the square brackets are visible and should be checked by Harper.”——双括号里的文字**对 Harper 可见**,应当参与拼写与语法检查; - “The text to the left of the operator should be ignored.”——当使用竖线 `|` 运算符时(`[[target|display]]`),竖线**左侧**的目标笔记名应当被**忽略**,只有右侧的显示文本参与检查。 3. **它作为回归测试的输入**,与 [run_tests.rs](https://link.gitcode.com/i/457147c577a081dc2c28cf4b99dbe250) 中的宏绑定,断言 lint 总数。 值得注意的设计是:同一个目标笔记“Three laws of motion”分别以 Wiki 链接 `[[Three lws of motion]]` 和标准 Markdown 链接 `Three las of motion` 两种形式出现。这直接验证了原文档中“treated as normal Markdown links”的契约——两种链接形式必须得到相同的检查待遇,任何一侧的差异都会改变预期 lint 数量并让测试失败。 ## 测试断言:预期恰好 2 个 lint 在 [run_tests.rs](https://link.gitcode.com/i/457147c577a081dc2c28cf4b99dbe250#L74) 中,该文件通过 `create_test!` 宏注册: ```rust create_test!(obsidian_links.md, 2, Dialect::American);

这个断言精确编码了上述语义契约。create_test!宏(定义于 run_tests.rs)的工作原理是:

  1. include_str!./test_sources/obsidian_links.md编译期嵌入二进制;
  2. 调用Document::new_markdown_default(&source, &dict)以默认 Markdown 解析器 和FstDictionary::curated()受审词典构建文档;
  3. LintGroup::new_curated(dict, Dialect::American)执行美式英语全套 linter,断言lints.len() == 2
  4. 额外校验每个 token 的 span 都指向真实存在的字符(token.span.try_get_content(...).is_some()),防止解析器产出越界的 token 区间。

预期 2 个 lint 的来源是:[[Three lws of motion]]中的lws(拼写错误)和[Three las of motion]链接文本中的las(拼写错误)——两处都是可见文本。而[[lnk tget|Link Text]]中竖线左侧的lnk tget虽然也是拼写错误,但按规则应被解析器剥离,因此不产生 lint;右侧的Link Text拼写正确,同样不产生 lint。如果解析器误把隐藏目标也拿去检查,lint 数会变成 4,测试即失败。Document::new_markdown_default的入口实现在 document.rs,它只是MarkdownOptions::default()配置的薄封装,即 Wiki 链接处理无需任何额外开关,默认行为即生效。

解析器实现:两个 Wiki 链接处理函数

上述语义契约在 harper-core/src/parsers/markdown.rs 中由两个函数落地。在Parser::parse主流程的末尾(markdown.rs),解析完成、标点/HTML 等事件处理结束后,会依序执行:

Self::remove_hidden_wikilink_tokens(&mut tokens); Self::remove_wikilink_brackets(&mut tokens);

1. remove_hidden_wikilink_tokens:剥离竖线左侧的隐藏目标

该函数(markdown.rs)处理形如[[Target text|Display Text]]的链接,函数文档注释也直接引用了这个语法示例:

[[Target text|Display Text]]

其算法分三步:

  1. 定位所有竖线:遍历tokens.iter_pipe_indices()找出每个|token 的下标;
  2. 向前回溯找[[:从竖线前第 2 个 token 开始逐个回退,直到找到相邻的两个开方括号,或遇到换行、越界(cursor == 0)为止;
  3. 向后前瞻找]]:从竖线后 1 位开始逐个前进,找到相邻的两个闭方括号,或遇到换行为止。

只有当[[]]都在同一行内找到时,才执行删除:移除open_bracket_idx..=pipe_idx区间(即[[、隐藏目标的所有 token 和竖线本身),再额外移除close_bracket_idxclose_bracket_idx + 1(即]]的两个括号)——注意它保留了]]与竖线之间的显示文本Display Text)以及[[到竖线之前区间之外的内容。批量删除通过 vec_ext.rs 中定义的remove_indices(&mut VecDeque<usize>)一次完成,保证 span 位置的一致性。

对应到测试文件,[[lnk tget|Link Text]]经此函数处理后,lnktget及其前后括号均被剔除,剩余可见 token 为LinkText

2. remove_wikilink_brackets:去除无竖线链接的括号

对不含竖线的普通 Wiki 链接(如[[Three lws of motion]]),由 remove_wikilink_brackets 处理。它用单游标线性扫描:遇到相邻的[[时记录起点下标;之后若在同一行内遇到相邻的]],就把开括号的两个 token 和闭括号的两个 token 都加入删除队列,并将起点复位。关键在于只删括号、不删内容——链接内部的Threelwsofmotion等 token 原样保留,于是lws依然会被拼写检查器捕获,这正是测试中 2 个 lint 的其中之一。

两个函数都以换行作为扫描边界:Wiki 链接跨行时不会配对成功,括号会被当作普通标点保留。这与 Obsidian 的 Wiki 链接不可跨行的实际语义一致。

边界情况:解析器单元测试覆盖的极端输入

markdown.rs 的tests模块针对 Wiki 链接专门编写了若干极端输入测试,它们与 obsidian_links.md 的文档级测试形成互补:

测试用例输入断言结果
normal_wikilink[[Wikilink]]只剩一个TokenKind::Word(_),四个括号全部被剥离
hidden_wikilink_text[[this is hidden\|this is not]]只剩 3 个Word+ 2 个Spacethis is not),左侧 3 词连同括号、竖线全部消失
empty_wikilink_text[[\|]]token 列表为空——目标与显示文本均缺失时整段剥离
improper_wikilink_textthis is shown\|this is also shown]][[开头时不触发剥离:所有 token(含\|]])原样保留为词、空格、Punctuation::PipePunctuation::CloseSquare
hang[[#\|]]:A]只要求不挂死(历史回归问题),不做断言

其中improper_wikilink_text特别值得注意:它证实剥离逻辑依赖完整的双开括号,孤立的竖线加孤立的]]会被当作普通标点处理,不会误删正文内容。hang用例则记录了[[#|]]:A]这类畸形输入曾经导致解析器卡住的问题,如今仅作为不崩溃的冒烟检查。

解析流程定位:Wiki 链接处理在管线中的位置

从源码结构看,整条 Markdown 解析管线为:

  1. Markdown::parse(markdown.rs)先用pulldown_cmarkOptions::all()减去ENABLE_SMART_PUNCTUATION的方式做 CommonMark 词法分析,并借助build_byte_to_char_map把字节偏移换算为 Harper 内部的字符偏移;
  2. 事件循环中,代码块、行内数学、HTML 等被整体标记为TokenKind::Unlintable;普通Text事件则委托PlainEnglish解析器切分为Word/Space/Punctuation等细粒度 token;链接文本默认参与检查(可通过MarkdownOptions.ignore_link_title关闭);
  3. 事件循环结束后,依次运行remove_hidden_wikilink_tokensremove_wikilink_brackets完成 Wiki 链接的“去壳”处理;
  4. 最后Document的构造阶段还会执行apply_fixups(见 document.rs):合并多余空格与换行、压缩缩写点、配对引号等,为 linter 准备规整的 token 序列。

也就是说,Wiki 链接的处理发生在词法分析的最后阶段,且以“物理删除 token”而非“标记为不可检查”的方式实现——被隐藏的文本根本不会进入 linter 的视野,因此既不会产生误报,也不会被任何 lint 规则(包括拼写检查)触碰。

复现与验证:如何运行这一测试

该测试是harper-core集成测试套件的一部分,在仓库根目录可用 Cargo 定向运行:

cargo test -p harper-core --test run_tests lints_obsidian_links_md_correctly

生成的测试函数名为lints_obsidian_links_md_correctly(由宏内paste::paste!lints_ + 文件名 + _correctly拼接而来)。运行时会通过dbg!打印实际检出的 lint 列表,与预期的 2 个拼写类 lint 对照即可确认 Wiki 链接语义是否符合 obsidian_links.md 开头声明的规则。解析器层面的细粒度行为则可单独验证:

cargo test -p harper-core --lib parsers::markdown::tests

【免费下载链接】harperOffline, privacy-first grammar checker. Fast, open-source, Rust-powered项目地址: https://gitcode.com/GitHub_Trending/har/harper

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 4:57:38

BMA2x2 三轴加速度计 Linux 驱动开发:从寄存器到设备树全解析

简介&#xff1a;BMA2x2驱动源码包面向嵌入式开发者&#xff0c;适用于智能手环、手机外设、工业监测等需采集运动数据的物联网场景&#xff0c;解决从底层寄存器初始化、数据读写到联合调试的完整开发问题。压缩包内共4个文件&#xff0c;包含2个C源文件、1个头文件和1个Markd…

作者头像 李华
网站建设 2026/9/14 4:56:07

Lithe-IDEA:轻量级Spring Boot专用IDE开源实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 4:55:41

开源机械爪控制系统OpenClaw设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 4:52:00

Python车牌识别实战:从YOLO检测到字符切分与参数调优

简介&#xff1a;这是一套基于Python开发的车牌识别参考项目源码包&#xff0c;面向图像处理、模式识别领域的开发者与学习者&#xff0c;适用于课程设计、毕业设计、算法验证或实际项目二次开发场景。项目采用PyQt5构建友好交互界面&#xff0c;借助OpenCV完成车牌图像预处理、…

作者头像 李华
网站建设 2026/9/14 4:51:25

爱心公益网站HTML5模板改造与优化实战指南

简介&#xff1a;一款基于HTML5与CSS3的爱心公益网站模板&#xff0c;面向非营利组织、慈善机构及有公益建站需求的个人开发者&#xff0c;提供了可直接定制上线的响应式页面框架&#xff0c;适合展示公益项目、发布志愿活动或承载捐赠入口。包体为zip压缩包&#xff0c;共35个…

作者头像 李华
网站建设 2026/9/14 4:48:25

FPGA创新设计竞赛实战指南:从IO约束到系统协同

1. 这不是一场普通竞赛&#xff1a;FPGA创新设计赛道到底在考什么&#xff1f;FPGA创新设计赛道&#xff0c;光看名字容易误以为是“学生交个Verilog代码、调通个LED流水灯就能拿奖”的轻量级活动。但实际接触过近三年赛题的带队老师都清楚——这已经是国内高校电子类、信息类、…

作者头像 李华