思源笔记 v3.1.22 版本技术详解:行级标记开关、编辑体验与开发者 API 改进
思源笔记 v3.1.22 版本技术详解行级标记开关、编辑体验与开发者 API 改进【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan本篇文章基于思源笔记SiYuanv3.1.22 的官方繁体中文更新日志app/changelogs/v3.1.x/v3.1.22/v3.1.22_zh_CHT.md逐一解析该版本的改进细节并结合仓库源码说明其底层实现。读完本文你将了解如何关闭foo行级标记语法、理解虚拟引用粘贴与退出聚焦定位的改进原理、掌握数据库日期字段相对过滤与 S3 同步的配置要点并能利用新增的nodeElement参数扩展插件斜杠菜单回调。一、版本概览一次面向细节的「打磨」更新v3.1.22 延续思源笔记「小版本持续打磨」的节奏官方将其概述为「此版本改进了一些细节」。从变更记录看本版本共包含10 项功能改进与1 项面向开发者的 API 变更覆盖范围包括编辑体验行级标记语法开关、虚拟引用内容粘贴、文本外观设置、本地文件链接粘贴界面交互停靠面板弹出、退出聚焦定位、块自定义属性搜索预览区域定位兼容性与数据Firefox 浏览器兼容性、数据库日期字段相对过滤、S3 提供商兼容性开发者 APIprotyleSlash.callback新增nodeElement参数。这些改进虽「小」却都落在编辑器的日常使用高频路径上下文将逐项结合源码深入分析。二、核心新功能支持停用foo行级标记语法本版本最重要的新增能力是允许用户在设置中关闭 Markdown 行级标记inline mark语法。在此之前文字是思源内置的「标记/高亮」行级语法其解析由思源的 Markdown 引擎 Lute 负责且默认开启现在用户可以按需关闭避免在粘贴或输入含符号的文本例如代码片段、等式时被意外解析。2.1 设置入口与配置项在「设置 → 编辑器 → Markdown 行级语法」分组中新增了「行级标记」开关。对应的前端 UI 构建位于 app/src/config/tabs/editorTab.ts该分组registerEditorMarkdownInlineGroup中共有 7 个开关本次新增的是最后一个group.switch(editor.markdown.inlineMark, { title: window.siyuan.languages.editorMarkdownInlineMark, desc: window.siyuan.languages.editorMarkdownInlineMarkTip, });该配置项的完整类型定义位于 app/src/types/config.d.tsIMarkdown接口将行级语法配置统一收敛在editor.markdown下interface IMarkdown { inlineAsterisk: boolean; // *斜体* 星号语法 inlineUnderscore: boolean; // _斜体_ 下划线语法 inlineSup: boolean; // ^上标^ inlineSub: boolean; // ~下标~ inlineTag: boolean; // #标签# inlineMath: boolean; // $行内公式$ inlineStrikethrough: boolean; // ~~删除线~~ inlineMark: boolean; // 行级标记 }2.2 前端与内核的双重解析开关关闭开关后前后端两个层面的 Lute 实例都会同步关闭该语法前端渲染在 app/src/protyle/render/setLute.ts 中编辑器初始化 Lute 时会逐一读取这些配置lute.SetGFMStrikethrough(window.siyuan.config.editor.markdown.inlineStrikethrough); lute.SetMark(window.siyuan.config.editor.markdown.inlineMark);内核解析在 kernel/util/lute.go 中MarkdownSettings定义了运行时默认值InlineMark默认开启true随后通过ret.SetMark(MarkdownSettings.InlineMark)应用到内核 Lute 实例保证导入、导出与索引等内核侧操作与前端行为一致。由此可以看出标记的「开关」并不是简单的 CSS 隐藏而是从前端编辑器到内核解析器全链路禁用了该语法因此关闭后文档中的foo会按普通文本对待不会再被解析为高亮标记。提示foo与思源的行内公式$...$、标签#...#等同属「Markdown 行级语法」分组如需更精细地控制解析行为可一并调整该分组下的其他开关。三、编辑体验改进3.1 改进虚拟引用内容粘贴虚拟引用virtual block ref是思源中不依赖 ID 的引用方式粘贴其内容时如果正文中包含 Markdown 特殊字符可能会被 Lute 二次解析而产生与源内容不一致的结果。本版本对此进行了改进。相关实现位于 app/src/protyle/util/paste.ts。该文件采用了一个值得注意的设计——Lute 单例临界区// 临界区Lute 已是所有编辑器共享的单例此处临时把 inline-syntax 标志置 true 再恢复。 enableLuteMarkdownSyntax(protyle); const content protyle.lute.BlockDOM2EscapeMarkerContent(protyle.lute.Md2BlockDOM(textPlain)); restoreLuteMarkdownSyntax(protyle);其中enableLuteMarkdownSyntax会临时开启全部行级语法restoreLuteMarkdownSyntax再按用户配置恢复。源码注释特别强调enable/transform/restore必须保持同步执行中间不得插入await否则并发编辑器的转换调用如实时输入的SpinBlockDOM会读到被改写的标志而产生错误输出。这正是本版本「改进虚拟引用内容粘贴」所涉及的底层机制——它保证了粘贴内容先以完整语法解析、再按用户配置还原从而避免粘贴结果与源内容不一致。3.2 改进退出聚焦定位「退出聚焦」是指从聚焦focus模式返回文档视图时光标/选中块的定位问题。此前在退出聚焦后若目标块处于折叠状态或位于被隐藏元素中定位可能失败或跳转错误。在 app/src/menus/protyle.ts 中可以看到对这类问题的既有处理逻辑if (options.focusId) { let focusElement options.protyle.wysiwyg.element.querySelector([data-node-id${options.focusId}]); if (!focusElement) { const unfoldResponse await fetchSyncPost(/api/block/getUnfoldedParentID, {id: options.focusId}); options.focusId unfoldResponse.data.parentID; focusElement ...; } if (focusElement) { // 退出聚焦后块在折叠中 https://github.com/siyuan-note/siyuan/issues/10746 let showElement focusElement; while (showElement.getBoundingClientRect().height 0) { showElement showElement.parentElement; } ... focusBlock(showElement); } }从代码可以看出退出聚焦后的定位逻辑会先按块 ID 查找目标元素若不存在则通过/api/block/getUnfoldedParentID回溯到已展开的父块随后向上遍历跳过所有高度为 0 的折叠父级最终定位到可见块。v3.1.22 在此基础上进一步改进了定位的稳定性和准确性使退出聚焦后视图能可靠回到正确位置。3.3 改进文本外观设置「文本外观设置」指编辑器中对字体、字号、行高等外观相关配置的即时生效能力。本版本改进了该设置的更新路径确保修改后能立即反映到编辑区。该功能与外观运行时配置相关前端配置逻辑位于 app/src/config/tabs/appearanceRuntime.ts 与 app/src/config/render/render.ts 等文件中涉及的配置项包括appearance下的字体与排版参数读者可结合「设置 → 外观」面板实际体验。3.4 改进本地文件链接粘贴当从系统文件管理器复制本地文件路径并在编辑器内粘贴时思源需要将其转换为符合其资产asset管理规范的内链格式。本版本改进了该转换流程使本地文件链接的粘贴结果更符合预期、路径处理更健壮。相关粘贴处理逻辑位于 app/src/protyle/util/paste.ts 中的本地文件读取与资产处理分支readLocalFile等函数。四、界面与兼容性改进4.1 改进停靠面板弹出停靠dock面板是思源左右侧边栏的统称包含文件树、大纲、反向链接等面板。「改进停靠面板弹出」主要针对面板展开时的定位、层级与交互细节进行优化使面板弹出行为更平滑。停靠面板的布局与弹出逻辑集中在 app/src/layout/dock/ 目录下其中 app/src/layout/dock/index.ts 负责面板的注册与组织app/src/layout/dock/Backlink.ts、app/src/layout/dock/Outline.ts 等文件实现了各具体面板。4.2 改进 Firefox 浏览器兼容性思源在桌面端基于 Electron在 Web 端则需要在各主流浏览器中运行。本版本修复了 Firefox 下若干兼容性问题例如部分样式或事件处理在 Firefox 中的差异表现提升了 Web 版在 Firefox 中的可用性。此类兼容性修复通常涉及 app/src/protyle/util/compatibility.ts 等兼容性适配文件读者可在 Firefox 中打开思源 Web 版实际验证。4.3 改进块自定义属性搜索预览区域定位「块自定义属性」允许用户为块附加键值对属性并可在搜索中按属性检索。本版本改进了属性搜索结果在预览区域中的定位行为使命中结果在预览面板中能被准确定位与高亮显示。搜索结果的高亮与定位逻辑与搜索模块相关可参考 app/src/search/ 目录下的实现。五、数据与同步改进5.1 改进数据库日期字段相对过滤思源数据库属性视图的日期字段支持「相对过滤」即按「当前时间 ± 偏移」进行动态过滤例如「近 7 天」「前 30 天」。本版本改进了相对过滤在「介于between」条件下的判断逻辑。前端实现位于 app/src/protyle/render/av/filter.ts该文件中的genInlineDateHTML函数负责生成日期类型的内联筛选控件支持绝对/相对切换以及「Is between 结束日期」的组合代码注释表明日期类型切换绝对/相对、日期方向切换当前/前/后等状态变化会触发筛选条件的保存。结合本版本改进相对过滤在 between 区间下的计算边界更加准确。5.2 某些 S3 提供商不可用S3 协议对象存储如 MinIO、Cloudflare R2、Backblaze B2 等是思源「云端同步」的三种可选提供商之一另两种为思源内置云与 WebDAV。不同 S3 提供商在端点Endpoint、路径风格Path Style、TLS 校验等方面的实现存在差异部分提供商此前无法正常同步本版本对此进行了兼容性修复。S3 同步配置的结构体定义位于 kernel/conf/sync.gotype S3 struct { Endpoint string json:endpoint // 服务端点 AccessKey string json:accessKey // Access Key SecretKey string json:secretKey // Secret Key Bucket string json:bucket // 存储空间 Region string json:region // 存储区域 PathStyle bool json:pathStyle // 是否使用路径风格 SkipTlsVerify bool json:skipTlsVerify // 是否跳过 TLS 验证 Timeout int json:timeout // 超时时间单位秒 ConcurrentReqs int json:concurrentReqs // 并发请求数 }其中PathStyle路径风格与SkipTlsVerify跳过 TLS 校验是影响不同提供商兼容性的两个关键字段部分兼容 S3 的私有服务要求使用http://host/bucket/key的路径风格访问而云厂商默认使用https://bucket.host/key的虚拟主机风格自建端点若使用自签名证书则需要SkipTlsVerify。值得注意的是思源在初始化默认配置时已将这两项预设为开启状态kernel/model/conf.goConf.Sync.S3 conf.S3{PathStyle: true, SkipTlsVerify: true}并在同步仓库提交时随配置一并传递kernel/model/repository.go。S3 提供商的配置与导入导出通过 API 完成对应路由在 kernel/api/router.go 中注册POST /api/sync/setSyncProviderS3—— 设置 S3 同步提供商含管理员角色校验参见 kernel/api/sync.goPOST /api/sync/exportSyncProviderS3/POST /api/sync/importSyncProviderS3—— 导出/导入 S3 提供商配置包。实操建议若使用自建 S3 或小众兼容服务时同步失败可优先检查 Endpoint 地址是否含路径前缀、PathStyle是否符合服务商要求、证书是否可信必要时开启「跳过 TLS 校验」。六、开发者 APIprotyleSlash.callback新增nodeElement参数本版本面向插件开发者提供了一项 API 变更protyleSlash.callback回调新增nodeElement参数。插件通过plugin.protyleSlash注册自定义斜杠菜单项其类型定义位于 app/src/plugin/index.tspublic protyleSlash: { filter: string[], html: string, id: string, callback: (protyle: import(../protyle).Protyle, nodeElement: HTMLElement) void }[] [];可见callback的签名已从单个protyle参数扩展为(protyle, nodeElement)两个参数。nodeElement是触发斜杠菜单时所操作的 DOM 节点元素它由斜杠菜单的触发流程传入——在 app/src/protyle/hint/index.ts 中当用户选择plugin__xxx类型的斜杠菜单项时} else if (value.startsWith(plugin)) { protyle.app.plugins.find((plugin) { const ids value.split(Constants.ZWSP); if (ids[1] plugin.name) { plugin.protyleSlash.find((slash) { if (slash.id ids[2]) { slash.callback(protyle.getInstance(), nodeElement); return true; } }); return true; } }); return; }对插件开发者的影响此前回调只能拿到protyle实例需要自行通过选区或 DOM 查询定位当前操作节点现在可以直接使用nodeElement参数简化了「在光标处插入内容 / 替换文本」类插件的实现。旧插件若回调仍声明为单参数在 TypeScript 下并不会报错JS 允许少传参但将无法使用该新参数建议升级签名以充分利用新能力。七、下载与升级v3.1.22 属于思源笔记 3.1.x 稳定分支的维护版本可通过官方提供的桌面端Windows / macOS / Linux与移动端安装包进行升级。升级前建议备份工作空间默认目录包含data数据目录见 docs/WORKSPACE.zh-CN.md关注版本间的数据格式兼容性思源会为数据格式变更提供自动迁移插件用户升级前确认所用插件是否依赖protyleSlash.callback的旧签名。本版本的完整变更记录可在 app/changelogs/v3.1.x/v3.1.22/v3.1.22_zh_CHT.md繁体中文、app/changelogs/v3.1.x/v3.1.22/v3.1.22_zh_CN.md简体中文与 app/changelogs/v3.1.x/v3.1.22/v3.1.22.md英文中查看。总结v3.1.22 是一个典型的「细节打磨」版本但其中的每一项改进都直接作用于日常编辑路径行级标记语法开关让 Markdown 解析行为可控前端 setLute.ts 与内核 lute.go 双重生效虚拟引用粘贴通过 Lute 单例临界区保证解析一致性S3 同步通过PathStyle、SkipTlsVerify等字段提升了不同提供商的兼容性protyleSlash.callback的nodeElement参数则为插件开发提供了更便捷的节点访问能力。对于使用思源进行日常记录、或基于其开发插件的用户而言理解这些改进背后的实现细节将有助于更精准地使用和扩展这个开源知识工作空间。【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考