markdown-it 嵌套链接引用标签解析原理与性能基准样本解析(block-ref-nested)
开发工具CLI【免费下载链接】markdown-itMarkdown parser, done right. 100% CommonMark support, extensions, syntax plugins high speed项目地址https://gitcode.com/gh_mirrors/ma/markdown-it点击查看免费下载导读本文围绕 markdown-it 官方基准套件中的 benchmark/samples/block-ref-nested.md 样本文件展开深入剖析 markdown-it 如何处理链接引用定义标签中的嵌套方括号这一边界场景当标签内包含多对[/]如[[[[foo]]]]: bar或内嵌强调符如[*[foo]*]: bar时解析器如何判定合法标签、如何归一化标签、以及这些行为如何被 CommonMark 规范与源码规则共同约束。读完本文你将掌握 markdown-it 引用标签解析的完整判定链从块级reference规则到行内parseLinkLabel辅助函数、再到normalizeReference归一化并能亲手运行基准命令复现该样本的解析与性能表现。一、样本文件在基准套件中的定位1.1 基准样本目录的构成benchmark/samples/目录存放着 markdown-it 性能基准benchmark与性能剖析profile所用的全部输入样本每个样本都对应一个独立的 Markdown 解析场景block-ref-flat.md普通扁平引用定义含长标签、多行目标地址、超长嵌套括号等边界输入block-ref-list.md50 条连续引用定义的列表式批量解析场景block-ref-nested.md本文主角嵌套方括号与嵌套强调符的引用定义样本同目录下还有block-bq-*、block-list-*、inline-em-*、inline-links-*等系列样本覆盖块级与行内语法的典型压力场景。1.2 样本如何被基准框架消费benchmark/benchmark.mjs 会扫描./samples目录下所有文件将每个文件读入内存并统计字节数然后为每个样本构造一个 tinybench 基准实例依次运行当前目录中所有实现见./implementationscommonmark-reference官方 CommonMark 参考实现current以html: true, linkify: true, typographer: true全开模式渲染的 markdown-it 当前版本见 benchmark/implementations/current/index.mjscurrent-commonmark以commonmark预设渲染的 markdown-it并替换掉默认的链接归一化函数以获得更诚实的对比见 benchmark/implementations/current-commonmark/index.mjsmarkedmarked 库。运行命令如下# 运行全部样本 node benchmark/benchmark.mjs # 只运行与正则匹配的样本例如只测 block-ref-nested node benchmark/benchmark.mjs block-ref-nested选中样本后框架会输出样本字节数并逐个实现输出ops/sec ±RME%形式的吞吐率。也就是说block-ref-nested.md不仅是语法边界测试更是衡量解析器在嵌套引用标签这类容易导致回溯爆炸的输入上的速度基准。二、样本内容逐段拆解block-ref-nested.md的完整内容共 17 行可划分为两大场景组中间用空行隔开。2.1 场景组一嵌套方括号的引用定义第 19 行[[[[[[[foo]]]]]]] [[[[[[[foo]]]]]]]: bar [[[[[[foo]]]]]]: bar [[[[[foo]]]]]: bar [[[[foo]]]]: bar [[[foo]]]: bar [[foo]]: bar [foo]: bar第 1 行[[[[[[[foo]]]]]]]是一个独立的段落内部是 7 层嵌套的[foo]包裹。由于它后面没有跟随:目标地址它不是引用定义同时它也不是行内链接语法因此整行被当作普通文本段落渲染。第 39 行是从 7 层嵌套递减到 1 层的引用定义序列[[[[[[[foo]]]]]]]: bar、[[[[[[foo]]]]]]: bar…… 直到最朴素的[foo]: bar。这里的核心问题是一个标签内部出现多对[和]时哪一对才是标签真正的括号对答案是最外层那一对——块级reference规则只要求从行首字符[0x5B开始扫描并在第一个未被内层括号遮蔽的]0x5D处闭合同时要求闭合后紧跟:0x3A才会被当作引用定义。因此[[[[[[[foo]]]]]]]: bar会被解析为标签 [[[[[[foo]]]]]]、目标地址 bar的引用定义而不会因内层括号而报错。2.2 场景组二嵌套强调符的引用定义第 1117 行[*[*[*[*[foo]*]*]*]*] [*[*[*[*[foo]*]*]*]*]: bar [*[*[*[foo]*]*]*]: bar [*[*[foo]*]*]: bar [*[foo]*]: bar [foo]: bar第 11 行[*[*[*[*[foo]*]*]*]*]是含 4 层*强调嵌套的独立段落同样因缺少:而不构成引用定义。第 1317 行是从 4 层强调嵌套递减到 0 层的引用定义序列。这一场景验证的是引用标签的括号匹配与行内强调符*无关。标签扫描只关心方括号的配平*只是标签文本的普通字符它们不会被当作强调定界符参与块级判定。2.3 两个场景组的共同意义两个场景组都呈现出递减嵌套的结构这并非偶然合法性验证验证任意深度嵌套方括号或强调符下引用定义仍能被识别且[foo]: bar这一最终定义在两种写法下都保持一致性能与回溯压力嵌套越深块级规则与后续行内规则需要跳过的字符越多是测试解析器线性退化而非指数爆炸的关键输入——这正是该样本被放进基准目录的原因。三、源码级解析原理块级 reference 规则3.1 入口与前置检查引用定义的解析由块级规则 src/rules_block/reference.ts 完成它在 src/parser_block.ts 中以[reference, r_reference]注册位于table、code、fence、blockquote、hr、list之后、paragraph之前。规则开头的关键判定// 缩进超过 3 个空格 - 视为代码块不解析引用 if (state.sCount[startLine] - state.blkIndent 4) { return false } // 行首必须是 [ if (state.src.charCodeAt(pos) ! 0x5B/* [ */) { return false }也就是说引用定义必须顶格或缩进不超过 3 个空格且以[开头。block-ref-nested.md中所有定义行都满足该条件。3.2 标签扫描第一个能闭合的]随后是标签扫描主循环for (pos 1; pos max; pos) { const ch str.charCodeAt(pos) if (ch 0x5B /* [ */) { return false // 遇到未配平的 [ - 直接判定非法 } else if (ch 0x5D /* ] */) { labelEnd pos // 遇到 ] - 记录闭合位置并跳出 break } else if (ch 0x0A /* \n */) { // 换行尝试把下一行并入多行标签 / 多行目标地址 ... } else if (ch 0x5C /* \ */) { // 反斜杠转义跳过下一个字符 ... } }这里存在一个看似矛盾的行为循环里遇到[就 return false但样本里明明有[[[[[[[foo]]]]]]]这样的多括号输入。关键在于外层调用只把第一个[之后的内容交给这个循环——外层[已经被消耗循环从pos 1开始扫描剩余部分一旦剩余部分中再出现裸[说明这是一个嵌套未闭合的结构本规则立即放弃最终该行会落入paragraph规则。而对于[[[[foo]]]]: bar这种每层括号都成对的输入扫描到第一个]时labelEnd就被记录下来随后检查labelEnd 1处是否为:if (labelEnd 0 || str.charCodeAt(labelEnd 1) ! 0x3A/* : */) { return false }以[[[foo]]]: bar为例外层[被消耗后剩余字符串是[[foo]]]: bar扫描遇到第一个]对应内层闭合即停止labelEnd 1处是:判定成立标签文本为[[foo]]。这印证了第一节的结论嵌套引用定义的标签取最外层括号对内的全部内容含内层括号本身。3.3 目标地址、标题与多行支持标签之后规则按[label]: destination title的语法继续解析参考 src/rules_block/reference.ts跳过标签与目标地址之间的空白调用state.md.helpers.parseLinkDestination(str, pos, max)解析目标地址并通过state.md.normalizeLink与state.md.validateLink做归一化与安全校验如javascript:等危险协议会被拒绝解析可选标题parseLinkTitle若标题后还有非空白垃圾则回滚到仅目标地址的形态上述步骤全部支持换行续行通过getNextLine将后续行并入样本block-ref-flat.md中的多行目标地址、多行标题正是该机制的用例。3.4 标签归一化与写入环境解析成功的标签会先经normalizeReference归一化见 src/common/utils.tsstr str.trim().replace(/\s/g, ) // 去首尾空白、折叠连续空白为单个空格 return str.toLowerCase().toUpperCase() // 先小写再大写完成 Unicode 大小写折叠其中先toLowerCase()再toUpperCase()是有讲究的单用toLowerCase()无法正确归一化约 125 个码点单用toUpperCase()无法归一化 6 个特例İ、ϴ、ẞ、Ω、K、Å两者串联可实现等价于 Unicode case folding 的效果。最终结果统一为大写并作为对象键存入state.env.references一方面保证[FOO]与[foo]视为同一引用另一方面避免与Object.prototype成员尤其是__proto__冲突。随后向 token 流写入reference_definitiontokenhidden: true、携带map与meta.label并把state.line推进到定义结束行state.env.references[label] { title, href } const token state.push(reference_definition, , 0) token.map [startLine, nextLine] token.hidden true state.line nextLine3.5 行内规则如何消费这些定义当正文中出现[[[[[[[foo]]]]]]]这样的行内嵌套引用时行内规则 src/rules_inline/link.ts 负责将其解析为引用链接reference link。其关键路径使用 src/helpers/parse_link_label.ts 中的parseLinkLabel找到标签结束位置。该函数维护一个level计数器遇到[则level遇到]则level--只有当level归零时才认定标签闭合——这正是行内侧括号配平的正式实现若[label]后紧跟(优先尝试内联链接失败如缺少闭合)则回退为引用链接引用链接模式下从state.env.references中按归一化后的标签查找{ href, title }命中则生成link_open/link_closetoken含href、title属性与meta.label未命中则回退为纯文本。3.6 定义 token 的默认剥离默认情况下reference_definitiontoken 会在核心链路的 src/rules_core/strip_references.ts 中被移除保证向后兼容——即定义不渲染任何输出仅把 href/title 留在env.references中。若插件需要看到这些定义的位置可关闭该规则md.core.ruler.disable(strip_references)该行为在 test/markdown-it/misc.test.mjs 中有对应测试默认剥离时reference_definition过滤结果为空数组禁用规则后能拿到带map: [0, 1]与meta.label: FOO的定义 token。四、嵌套引用在 CommonMark 规范测试中的印证CommonMark 规范测试文件 test/fixtures/commonmark/good.txt 中包含与嵌套引用直接对应的用例. [[[foo]]] [[[foo]]]: /url . p[[[foo]]]/p p[[[foo]]]: /url/p .期望输出表明正文中的[[[foo]]]保持为普通文本不构成链接而[[[foo]]]: /url被识别为引用定义但同样不渲染任何 HTML定义本身不可见。同一文件的src line: 8240用例还验证了[foo][ref[bar]]这类标签内含未配平括号的输入不会被误判为引用链接。这些用例从规范层面确认了block-ref-nested.md样本所覆盖的行为正是 CommonMark 的既定语义。五、参考系样本block-ref-flat 与 block-ref-list为了让读者理解block-ref-nested在基准套件中的独特性这里简要对照同目录的另外两个引用相关样本详见 benchmark/samples/README.mdblock-ref-flat.md测试标签形态的多样性——普通短标签、超长标签含大量o、空格填充的长标签、...尖括号目标地址、单引号标题、多行目标地址与标题以及[[[[[...]]]]]: q这种永不引用、不应拖慢解析的超深嵌套输入专门用来暴露回溯陷阱block-ref-list.md50 条[item N]: N定义的批量解析测试大量定义连续出现时的吞吐。三者分别从嵌套深度标签/目标多样性批量数量三个维度压测引用解析而block-ref-nested的核心价值在于验证方括号与强调符嵌套下解析复杂度不失控。六、运行与验证如何亲手复现6.1 环境准备仓库为纯 TypeScript 源码结构入口 src/index.ts基准脚本直接通过src/index.ts导入当前实现无需预构建即可运行commonmark-reference与marked依赖benchmark/extra/下的独立依赖包见 benchmark/extra/package.json。# 在仓库根目录安装根依赖与 benchmark/extra 的依赖 npm install cd benchmark/extra npm install6.2 只跑嵌套引用样本cd benchmark/extra cd ../.. # 回到仓库根目录后执行 node benchmark/benchmark.mjs block-ref-nested预期输出大致形如Selected samples: (1 of 27) block-ref-nested Sample: block-ref-nested.md (217 bytes) commonmark-reference x ... ops/sec ±...% current x ... ops/sec ±...% current-commonmark x ... ops/sec ±...% marked x ... ops/sec ±...%具体数值取决于运行机器current-commonmark因绕过了默认链接归一化的开销通常吞吐更高。6.3 对照全量基准与 CPU 剖析# 跑全部 27 个样本 node benchmark/benchmark.mjs # 用 spec.txt约 110 KB做 CPU 剖析预热 20 轮渲染 node benchmark/profile.mjsprofile.mjs见 benchmark/profile.mjs以html: true、关闭 linkify 与 typographer 的配置渲染 test/fixtures/commonmark/spec.txt 共 20 次适合搭配node --prof或--cpu-prof定位热路径。6.4 用 Node 直接观察解析行为不依赖基准框架直接解析样本观察 token 流import markdownit from ./src/index.ts import fs from node:fs const md markdownit() const src fs.readFileSync(./benchmark/samples/block-ref-nested.md, utf8) // 默认reference_definition 被剥离只输出段落 token console.log(md.parse(src, {}).map(t t.type)) // 保留定义 token观察 label 归一化结果 md.core.ruler.disable(strip_references) console.log(md.parse(src, {}).filter(t t.type reference_definition) .map(t t.meta.label)) // 引用生效验证定义一个嵌套标签然后在正文引用它 const md2 markdownit() console.log(md2.render([[[foo]]]: /url\n\n[ [[foo]] ](go)))其中meta.label输出应为全部大写的归一化结果如[[[[[[FOO]]]]]]印证第三节的归一化规则。七、要点小结嵌套引用定义的判定块级reference规则从行首[开始在第一个可闭合的]处截断标签并要求其后续紧跟:标签文本保留全部内层括号。这一定义行为在 src/rules_block/reference.ts 中逐行可查。行内消费parseLinkLabel以括号计数level实现真正的嵌套配平link规则据此从env.references中查表生成链接 tokensrc/rules_inline/link.ts、src/helpers/parse_link_label.ts。归一化normalizeReference先toLowerCase()再toUpperCase()实现 Unicode 大小写折叠保证[FOO]与[foo]等价同时规避Object.prototype冲突src/common/utils.ts。规范一致性[[[foo]]]正文保持纯文本、[[[foo]]]: /url仅登记定义与 test/fixtures/commonmark/good.txt 中的规范用例完全一致。基准价值block-ref-nested.md是嵌套深度压力样本用于验证解析器在最坏形态输入下保持线性性能配合 benchmark/benchmark.mjs 可在几分钟内复现current、current-commonmark、commonmark-reference、marked四路实现的吞吐对比。赞分享开发工具CLI【免费下载链接】markdown-itMarkdown parser, done right. 100% CommonMark support, extensions, syntax plugins high speed项目地址https://gitcode.com/gh_mirrors/ma/markdown-it点击查看免费下载相关推荐markdown-it 链接引用定义解析与基准样本剖析从 block-ref-list.md 看引用语法与性能设计markdown it 链接引用定义解析与基准样本剖析从 block ref list.md 看引用语法与性能设计 benchmark/samples/blo开发工具CLImarkdown-it 嵌套强调Nested Emphasis解析原理与基准测试指南markdown it 嵌套强调Nested Emphasis解析原理与基准测试指南 导读 本文以仓库基准样本 benchmark/samples/inli开发工具CLImarkdown-it 深层嵌套列表基准样本剖析block-list-nested.md 的用例设计与列表解析原理markdown it 深层嵌套列表基准样本剖析block list nested.md 的用例设计与列表解析原理 导读 本文以 benchmark/sam开发工具CLI上一篇如何免费解锁WeMod专业版Wand-Enhancer完整指南与使用教程下一篇Wand-Enhancer终极WeMod免费增强方案完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

AIO Sandbox MCP 集成实战:通过单一端点聚合浏览器、文件、终端与文档服务的 Agent 工具接入指南

AIO Sandbox MCP 集成实战:通过单一端点聚合浏览器、文件、终端与文档服务的 Agent 工具接入指南

AI Agent后端MCP 服务浏览器控制Agent 评测 【免费下载链接】sandbox All-in-One Sandbox for AI Agents that combines Browser, Shell, File, MCP and VSCode Server in a single Docker container. 项目地址: https://gitcode.com/gh_mirrors/sandbox103/sandbox…

2026/10/12 17:54:48 阅读更多 →
flask-admin 辅助模块(flask_admin.helpers)源码级解析:视图上下文、表单校验与 Jinja2 渲染工具

flask-admin 辅助模块(flask_admin.helpers)源码级解析:视图上下文、表单校验与 Jinja2 渲染工具

后端 【免费下载链接】flask-admin Simple and extensible administrative interface framework for Flask 项目地址: https://gitcode.com/gh_mirrors/fl/flask-admin 点击查看 免费下载 本文围绕 Flask Admin 项目(Simple and extensible administrat…

2026/10/11 10:59:15 阅读更多 →
express-validator 入门实战:用 Express 中间件完成请求参数校验与错误报告

express-validator 入门实战:用 Express 中间件完成请求参数校验与错误报告

后端 【免费下载链接】express-validator An express.js middleware for validator.js. 项目地址: https://gitcode.com/gh_mirrors/ex/express-validator 点击查看 免费下载 express-validator 是一组面向 Express 的中间件集合,它在 validator.js 提供…

2026/10/11 15:04:45 阅读更多 →

最新新闻

Tesseract OCR中文识别实战:安装、调优与避坑指南

Tesseract OCR中文识别实战:安装、调优与避坑指南

简介:Tesseract OCR 安装包与中文语言包面向需要在本地完成图片文字识别的开发者、测试人员及自动化办公用户,尤其适合用 Python 调用 OCR 引擎处理中文文档、票据或截图的人群。压缩包共 723 个文件,约 36.01MB,以 C 源码&#x…

2026/10/12 17:54:23 阅读更多 →
深入解构Claude Code - 第 8 篇 · 数据放哪、钱怎么算:用 TaoToken 统一 Key 看清 JSONL 会话与用量账本

深入解构Claude Code - 第 8 篇 · 数据放哪、钱怎么算:用 TaoToken 统一 Key 看清 JSONL 会话与用量账本

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

2026/10/12 17:54:23 阅读更多 →
ResNet特征提取+SVM分类:乳腺癌病理图像检测实战

ResNet特征提取+SVM分类:乳腺癌病理图像检测实战

简介:这份资源面向医学影像分析与深度学习入门者,提供一套将ResNet深度残差网络与SVM支持向量机结合的乳腺癌检测完整方案,可用于辅助诊断、课程设计或算法复现练习。压缩包共25个文件,约7.1MB,包含Python脚本、模型权…

2026/10/12 17:54:23 阅读更多 →
2026年七款AI编程工具横评:TaoToken统一Key接入Cursor与Windsurf实测

2026年七款AI编程工具横评:TaoToken统一Key接入Cursor与Windsurf实测

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

2026/10/12 17:54:22 阅读更多 →
Unity 鼠标图标更换实战:用 TaoToken 统一管理 Cursor 资源与 Script 配置

Unity 鼠标图标更换实战:用 TaoToken 统一管理 Cursor 资源与 Script 配置

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

2026/10/12 17:54:22 阅读更多 →
DeepSeek AI接入企业微信:从API到聊天机器人的完整实现指南

DeepSeek AI接入企业微信:从API到聊天机器人的完整实现指南

简介:这是一套将DeepSeek大模型接入微信聊天的完整工程实现,适合具备基础Python技能、希望为个人微信账号提供智能对话能力的开发者。项目从模型加载、消息收发到前端交互均有配套代码,支持文本对话、Web界面操作,并附带文档上传与…

2026/10/12 17:53:21 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/11 14:36:54 阅读更多 →