ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Sphinx literalinclude 与 code-block 行号控制:linenos、lineno-start 与 lineno-match 完全指南

Sphinx literalinclude 与 code-block 行号控制:linenos、lineno-start 与 lineno-match 完全指南 文档开发工具【免费下载链接】sphinxThe Sphinx documentation generator项目地址https://gitcode.com/gh_mirrors/sp/sphinx点击查看免费下载Sphinx 内置的literalinclude与code-block指令支持对代码块进行行号渲染本文基于仓库中的测试文档 tests/roots/test-directive-code/linenos.rst 与核心实现 sphinx/directives/code.py系统讲解linenos、lineno-start、lineno-match三个选项的语义、组合规则与底层实现并延伸至highlight指令的linenothreshold自动阈值机制。读完本文你将能在自己的 Sphinx 文档中精确控制代码块行号的显示起点、对齐方式与触发条件。一、关联文档与功能定位linenos.rst是 Sphinx 测试套件中专门用于验证「带行号的 literal 包含」场景的测试源文件由 tests/roots/test-directive-code/index.rst 通过toctree的:glob:收集。它虽然以测试根文件形式存在但其内容本身就是一份可运行的最小示例集四种典型的行号配置组合覆盖了普通启用、自定义起始行、行号对齐以及空文件边界。这些功能由sphinx.directives.code模块实现并通过 sphinx/directives/code.py 底部的setup()函数注册为highlight、code-block别名sourcecode与literalinclude三个指令。行号相关的测试断言则位于 tests/test_directives/test_directive_code.py 的test_literal_include_linenos与test_linenothreshold中。二、四个核心示例逐行解读linenos.rst原文共包含四个literalinclude实例分别演示了不同的行号控制方式.. literalinclude:: literal.inc :language: python :linenos: .. literalinclude:: literal.inc :language: python :lineno-start: 200 .. literalinclude:: literal.inc :language: python :lines: 5-9 :lineno-match: .. literalinclude:: empty.inc :lineno-match:其中被包含的 tests/roots/test-directive-code/literal.inc 是一段 13 行的 Python 源码含注释、类定义、Unicode 字符串tests/roots/test-directive-code/empty.inc 则是只有空行的文件。2.1:linenos:启用行号第一个实例仅使用:linenos:标志。按源码实现只要检测到该选项Sphinx 就会在生成的literal_block节点上设置linenos: Trueif ( linenos in self.options or lineno-start in self.options or lineno-match in self.options ): retnode[linenos] True对应的测试断言tests/test_directives/test_directive_code.py 第 411 行起验证输出 HTML 中行号以span classlinenos 1/span的形式出现即从第 1 行开始、默认以右侧对齐显示。2.2:lineno-start: 200自定义起始行号第二个实例通过:lineno-start: 200把行号起点改为 200。这在拼接代码片段例如从某个较大的源文件中截取片段希望行号与源文件一致时非常实用。实现层面LiteralIncludeReader在构造时读取该选项并作为默认起始值self.lineno_start self.options.get(lineno-start, 1)最终在run()中把reader.lineno_start写入高亮参数extra_args[linenostart]交给 Pygments 渲染。测试断言验证输出包含span classlinenos200/span即渲染出的首个行号是 200。2.3:lineno-match:行号与源文件精确对齐第三个实例同时使用:lines: 5-9与:lineno-match:。其语义是被截取/过滤后的片段其行号仍与原始文件保持一致。例如只包含原文件第 59 行时展示的行号就是 5、6、7、8、9而不是重新从 1 开始。从源码看lines_filter()在同时出现两个选项时会先把行号起点加上第一个选中行if lineno-match in self.options: first linelist[0] if all(first i n for i, n in enumerate(linelist)): self.lineno_start linelist[0] else: msg __(Cannot use lineno-match with a disjoint set of lines) raise ValueError(msg)这里有一个重要的约束lineno-match要求所选行是连续的即5,6,7,8,9这种如果写成0,3,5之类的非连续集合会直接抛出Cannot use lineno-match with a disjoint set of lines错误。对应的单元测试见 tests/test_directives/test_directive_code.py 中test_LiteralIncludeReader_lines_and_lineno_match*系列。同理lineno-match与start-after/start-at/pyobject组合时也会自动修正起点例如pyobject_filter()中定位到对象定义后self.lineno_start startstart_filter()中命中标记行后self.lineno_start lineno 1start-after模式。这样无论是按对象、按注释标记还是按行号范围截取行号都能与源文件对得上。2.4:lineno-match:与空文件边界安全第四个实例对空文件 tests/roots/test-directive-code/empty.inc 使用lineno-match。此时文件中没有内容可供对齐LiteralIncludeReader的过滤管道依次执行后得到 0 行文本lineno_start保持默认值 1Sphinx 输出一个空的行号代码块而不会报错。这一用例证明了lineno-match在边界条件下的容错性。三、code-block指令中的行号选项行号控制并非literalinclude专属。同文件 tests/roots/test-directive-code/index.rst 给出了code-block的用法.. code-block:: ruby :linenos: def ruby? false endCodeBlock指令的选项表sphinx/directives/code.py支持linenosflag与lineno-startint。需要注意linenos与lineno-start任一生效都会开启行号if linenos in self.options or lineno-start in self.options: literal[linenos] Truelineno-start会通过extra_args[linenostart]传给 Pygments但code-block没有lineno-match选项因为其内容直接写在文档中不涉及「与源文件行号对齐」的场景。四、highlight指令与linenothreshold自动阈值行号除了手动开启Sphinx 还支持按代码块长度自动决定是否显示行号。测试文件 tests/roots/test-directive-code/linenothreshold.rst 展示了完整用法.. highlight:: python :linenothreshold: 5 .. code-block:: class Foo: pass class Bar: def baz(): pass .. code-block:: # comment value True其语义是当代码块行数达到或超过linenothreshold时自动显示行号否则不显示。上述示例中第一段有 6 行≥5会显示行号第二段仅 2 行不显示行号。实现上Highlight指令sphinx/directives/code.py解析该选项并把它记录到当前文档的高亮设置中linenothreshold self.options.get(linenothreshold, sys.maxsize)默认值取sys.maxsize意味着不设置时所有代码块都不因阈值自动获得行号即行为与code-block无linenos时一致。该阈值不仅作用于后续code-block同样作用于不带语言参数的literalinclude如linenothreshold.rst中对literal.inc与literal-short.inc的包含前者超过阈值显示行号、后者不足阈值不显示。test_linenothresholdtests/test_directives/test_directive_code.py 第 578 行起分别对两种code-block与两种literalinclude做了断言验证阈值判定在两条路径上行为一致。五、选项组合规则与常见错误结合 sphinx/directives/code.py 中LiteralIncludeReader.INVALID_OPTIONS_PAIR与各过滤器的实现整理出与行号相关的组合约束选项组合行为lineno-matchlineno-start非法报Cannot use both lineno-match and lineno-start optionslineno-matchappend/prepend非法追加/前置内容会破坏行号对齐lineno-matchdiff非法diff 输出为补丁文本无原始行号语义lineno-matchlines连续区间合法行号从区间首行延续lineno-matchlines非连续集合报Cannot use lineno-match with a disjoint set of lineslineno-matchstart-after/start-at/pyobject合法自动把起点调整到命中行difflineno-start非法这些规则在LiteralIncludeReader.__init__中被逐一校验任何冲突都会在构建期以警告warning形式呈现run()中的异常统一由document.reporter.warning捕获而不是静默产生错误输出。六、行号渲染的底层输出LiteralInclude.run()最终把linenos标记写入nodes.literal_block并把linenostart写入highlight_args。HTML 构建器交给 Pygments 渲染后输出结构为带linenos类名的span元素span classlinenos 1/spanspan classc1# Literally included file.../span行号1前面的空格是 Pygments 对个位数行号的右对齐填充lineno-start: 200时则输出span classlinenos200/span。测试文件 tests/test_directives/test_directive_code.py 的test_literal_include_linenos直接以这些片段作为断言可作为理解输出细节的参考。七、实践建议片段引用保持真实行号从大型源文件截取片段时优先使用:lines:或:start-after:/:end-before:搭配:lineno-match:让读者能回溯源文件定位但务必保证所选行连续。长代码自动加行号在全文档统一使用.. highlight:: python\n :linenothreshold: N设置阈值短片段保持干净、长片段自动带行号兼顾可读性与定位便利。避免冲突选项不要同时使用lineno-match与lineno-start也不要对prepend/append/diff修饰的片段使用lineno-match否则构建期会产生警告。先跑通测试用例仓库中 tests/roots/test-directive-code/linenos.rst 与 tests/roots/test-directive-code/linenothreshold.rst 本身就是最小可复现示例可直接在本地 Sphinx 项目中运行sphinx-build验证上述行为再迁移到自己的文档中。赞分享文档开发工具【免费下载链接】sphinxThe Sphinx documentation generator项目地址https://gitcode.com/gh_mirrors/sp/sphinx点击查看免费下载相关推荐5分钟上手Rufus免费制作Windows 11启动盘的完整指南5分钟上手Rufus免费制作Windows 11启动盘的完整指南 你装过 Windows 11 吗老电脑没有 TPM 2.0 芯片官方安装工具直接拒绝。R文档开发工具Sphinx 代码指令实战code-block 与 literalinclude 的语法高亮、行号与源码级实现解析Sphinx 代码指令实战code block 与 literalinclude 的语法高亮、行号与源码级实现解析 本篇指南以 Sphinx 官方测试根目录文档开发工具Sphinx 代码行号阈值linenothreshold实战指南自动为长代码块与 literalinclude 添加行号Sphinx 代码行号阈值linenothreshold实战指南自动为长代码块与 literalinclude 添加行号 本指南以 Sphinx 文档生成文档开发工具上一篇告别混乱日志Ink打造专业CLI应用的日志系统完整指南下一篇如何用15分钟快速部署AzerothCore魔兽世界开源服务器完整容器化指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表