Yank Note 的 Hashtag 标签语法:从规则解析到全文检索实战

发布时间:2026/9/17 19:59:37
Yank Note 的 Hashtag 标签语法:从规则解析到全文检索实战 Yank Note 的 Hashtag 标签语法从规则解析到全文检索实战【免费下载链接】ynA highly extensible Markdown editor featuring version control, AI Copilot, document annotations, mind maps, document encryption, executable code snippets, chart embedding, HTML applets, plugins, and macro replacement. Its integrated sidebar terminal makes working with AI faster and more convenient.项目地址: https://gitcode.com/GitHub_Trending/yn/ynHashtag哈希标签是 Yank Note 内置的一项 Markdown 扩展语法允许在文档中用#标签形式标记关键词并在预览中以高亮形式展示、点击即可全局检索所有引用该标签的文件。本文以仓库中的语法测试文档 test/md/hashtags.md 为主体结合 markdown-hashtags 插件 的源码实现完整讲解标签语法规则、解析边界、渲染交互、索引检索与配置开关读完即可在自己的笔记中熟练使用标签体系并理解其底层工作方式。一、语法规则速览Yank Note 的 Hashtag 语法与主流笔记软件的标签语法一致核心形式就是#加标签名。以下规则均来自 test/md/hashtags.md 的测试用例。1. 基础标签在行首或空白之后直接书写#加标签名即可#YankNote #Markdown #Test2. 特殊字符支持标签名中可以包含-、_、/三种特殊字符用于表达层级或复合标签#my-tag #my_tag #tag/subtag其中/可用于构建子标签结构如#tag/subtag-与_用于连接多个单词。3. 中文标签标签名支持中文以及中英混排#笔记 #测试标签 #Yank笔记中文标签意味着可以在不切换输入法的情况下用中文关键词组织笔记。4. 行内上下文使用标签可以出现在段落中间也可以在一段文字中同时使用多个标签This is a paragraph with a #hashtag in the middle. Multiple tags: #tag1 #tag2 #tag35. 列表中使用标签可以嵌套在无序列表项内- #feature1 First feature - #feature2 Second feature - #bug Fix for a bug二、解析边界什么情况不会被识别为标签测试文档 test/md/hashtags.md 的 Notes 部分明确列出了四条边界规则前置字符限制#前面必须是空白字符空格、换行、制表符或位于行首否则不解析为标签字符集限制标签名仅允许字母a-z、A-Z、数字、中文、_、/、-紧贴文本的#不是标签如C#这类紧跟在普通字符后面的#不会被当作标签典型反例This is C# language#前是空格但紧贴C不会生成标签——因为#的前一个字符是字母而非空白。换句话说判定标签的关键在#的左侧上下文而非右侧。以C#为例#前一个字符是C字母不满足前置空白条件因此整个C#被视为普通文本。这让文档中涉及C#、Node#等编程语言名称的段落不会产生误匹配。三、源码级解析标签规则是怎么实现的Hashtag 的解析并不在 Markdown 通用解析器中而是由独立的 markdown-hashtags 插件 注入 markdown-it 内联规则完成。1. 核心正则与字符集插件核心规则定义在 lib.ts 中export const RE_MATCH /(#[a-zA-Z\u4e00-\u9fff][\da-zA-Z\u4e00-\u9fff_/-]*)/对这条正则逐段拆解片段含义#标签起始符[a-zA-Z\u4e00-\u9fff]首字符只能是英文字母或 CJK 汉字\u4e00-\u9fff覆盖常用中文字符区[\da-zA-Z\u4e00-\u9fff_/-]*后续字符可为数字、字母、汉字、_、/、-出现零次或多次值得注意的两点首字符不能是数字#123不会被识别为标签测试 lib.ts 测试用例 中明确验证了#123返回false。这避免了与文档中常见的编号、行号等歧义中文字符集用 Unicode 区间表示因此无需特殊配置即可原生支持中文标签这也是中文标签能在测试文档中生效的底层原因。2. 前置字符检查解析函数hashTags在匹配正则之前先对#的前一个字符做判断见 lib.tsif (start 0) { const prevChar state.src.charCodeAt(start - 1) if (prevChar ! 0x20 prevChar ! 0x0a prevChar ! 0x09) { return false } }其中0x20是空格、0x0a是换行、0x09是制表符。只有当前一字符是这三种空白之一或#位于行首时start 0才继续匹配标签正则。这正是“C#不是标签”这一规则的代码实现。3. Token 生成校验通过后解析器会向 token 流中压入一个hash_tag类型的 tokenconst token state.push(hash_tag, span, 0) token.markup # token.content tagisTagToken工具函数则用于在后续流程中快速判断某个 token 是否为标签 token见 lib.ts它被索引器直接复用。四、渲染效果与交互高亮标签、点击检索1. 预览渲染插件为 markdown-it 注册了hash_tag的渲染规则见 index.ts将标签渲染为带data-hashtag属性的span元素md.renderer.rules.hash_tag (tokens, idx) { const token tokens[idx] const tag token.content return ctx.lib.vue.h(span, { class: ctx.args.DOM_CLASS_NAME.HASH_TAG, [ctx.args.DOM_ATTR_NAME.DATA_HASHTAG]: tag, }, tag) }对应的 CSS 样式见 index.ts 的addStyles部分会给标签一个浅紫色圆角底色rgb(159 167 214 / 34%)使其在预览中一眼可辨同时保持cursor: pointer表明其可点击性。样式类名hash-tag定义于 support/args.ts。2. 点击标签快速打开检索预览区中的标签是可交互的。插件注册了VIEW_ELEMENT_CLICK钩子见 index.ts当点击的元素是带hash-tag类的SPAN时读取其data-hashtag属性调用workbench.show-quick-open动作以{ query: tag , tab: file }参数打开快速打开面板直接用该标签作为关键词检索文件。也就是说在预览中点击任意标签即可瞬间列出当前仓库中所有包含该标签的文档实现了“标签即入口”的笔记检索体验。3. 编辑器语法高亮插件还通过tapMarkdownMonarchLanguage为编辑器Monaco注入标签的高亮规则见 index.ts在行首或空白之后出现的#tag会被标记为metatag词法类型编辑源码时标签同样一目了然。五、标签索引与按标签检索文件标签不只是预览层的视觉标记Yank Note 会在后台索引阶段把标签提取出来纳入全局文件搜索体系。1. 索引 Worker 中的标签提取插件通过ctx.indexer.importScriptsToWorker将 worker-indexer.ts 注入索引 Worker。索引器在解析文档 token 流时凡是isTagToken命中的 token其内容都会被收集进该文件的tags数组见 indexer-worker.ts 中的convert函数最终随索引项一并存储if (isTagToken(token)) { const tag token.content if (tag) { tags.push(tag) } }2. Front Matter 中的 tags 字段除了正文中的#标签索引器同样读取文档 Front Matter 中的tags字段字符串或字符串数组均可并在提取时自动为每个标签补上#前缀见 indexer-worker.tsconst tagsFromAttributes typeof env.attributes?.tags string ? [env.attributes?.tags] : Array.isArray(env.attributes?.tags) ? env.attributes?.tags : [] const tags tagsFromAttributes .filter(tag typeof tag string tag.trim()) .map(tag # tag.trim())因此既可以在正文中书写标签也可以在文档头部用 Front Matter 声明标签两种方式都会进入同一套检索体系。3. 快速打开面板的 tags 标签页QuickOpen.vue 提供了files、tags等多个标签页其中tags标签页专门用于按标签浏览文件当搜索结果附带标签过滤条件searchPartial.tags时filterFiles会结合标签与关键词做联合过滤。这意味着你可以输入#标签关键字快速收敛到某个主题下的所有相关文档。六、配置项render.md-hash-tagsHashtag 功能可以通过设置项render.md-hash-tags开启或关闭。1. 默认值与 Schema设置项定义于 setting-schema.ts属于render分组、布尔类型复选框render.md-hash-tags: { defaultValue: true, // 默认开启 type: boolean, format: checkbox, group: render, required: true, }类型声明见 types.ts。四种语言的设置面板文案如下见 zh-CN.ts 及 en/ru/zh-TW 对应文件语言文案简体中文启用哈希标签 - #tagEnglishEnable Hash Tags - #tag繁体中文啟用哈希標籤 - #tagРусскийВключить хештеги - #тег2. 关闭后的行为链关闭该选项后影响是全局且一致的渲染侧markdown 服务在构建解析器时依据该设置决定是否启用hash-tags规则见 services/markdown.ts标签不再渲染为高亮 span索引侧插件监听SETTING_CHANGED钩子一旦render.md-hash-tags变更即调用ctx.indexer.rebuildCurrentRepo()重建当前仓库索引见 index.tsWorker 侧索引 Worker 在WORKER_INDEXER_BEFORE_START_WATCH钩子中读取该设置并据此enable/disable对应规则见 worker-indexer.ts从而决定是否从正文中提取标签。从源码结构看render.md-hash-tags是控制整个 Hashtag 链路渲染、高亮、索引、检索的唯一总开关默认开启、开箱即用。七、测试验证规则与行为都有用例兜底仓库为 Hashtag 功能配备了完整的单元测试可以作为理解规则细节的权威参考lib.ts 测试验证了RE_MATCH能匹配#tag、#中文/a_1等合法形式#tag-name/rest会生成 content 为#tag-name/rest的hash_tagtoken空白后与换行后的标签可识别且 silent 模式下不产 tokenword#tag嵌入单词中、#123首字符为数字、普通文本均返回falseworker-indexer.ts 测试验证设置开启时调用enable([hash-tags])、关闭时调用disable([hash-tags])且设置读取使用默认值trueplugin-entry-zero.ts 测试验证插件注册hash-tags规则、渲染器产出带data-hashtag的 span以及render.md-hash-tags变更时触发rebuildCurrentRepo。这些用例与 test/md/hashtags.md 中描述的边界规则一一对应共同构成了 Hashtag 功能“文档定义规则、代码实现规则、测试守护规则”的完整闭环。八、实践建议结合语法规则与源码行为可以给出几条在 Yank Note 中使用标签体系的实操建议组织层级标签利用/构建层级如#项目/后端、#项目/前端配合_、-连接多词标签形成统一命名规范中文标签中文标签开箱即用适合以母语关键词组织知识库且首字符必须是汉字或字母#123这类纯数字标签不可用避免误匹配由于#前置必须为空白书写C#、F#等编程语言名不会产生标签若确实想创建紧贴文本的标签请在前面补一个空格配合 Front Matter文档头部声明tags字段字符串或数组与正文#标签等效适合为正文中不便于插入标签的文档补充元数据点击即检索在预览中直接点击标签即可触发快速打开检索是日常整理与回看笔记时最高效的入口一键开关若某个仓库不需要标签体系可在设置中关闭render.md-hash-tags索引会随之重建无需手动清理旧标签。【免费下载链接】ynA highly extensible Markdown editor featuring version control, AI Copilot, document annotations, mind maps, document encryption, executable code snippets, chart embedding, HTML applets, plugins, and macro replacement. Its integrated sidebar terminal makes working with AI faster and more convenient.项目地址: https://gitcode.com/GitHub_Trending/yn/yn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考