文档开发工具【免费下载链接】sphinxThe Sphinx documentation generator项目地址https://gitcode.com/gh_mirrors/sp/sphinx点击查看免费下载本篇指南以 Sphinx 官方扩展开发文档 doc/extdev/appapi.rst 为骨架系统讲解 Sphinx 应用对象Sphinx的公开 API扩展的加载机制、三十余个注册方法builder、配置项、指令、角色、域、节点、变换、HTML 资产等、事件发射与运行时信息并结合当前仓库源码sphinx/application.py、sphinx/registry.py、sphinx/events.py 等深入印证每个 API 的底层实现。读完本文你将能够独立编写一个结构完整、兼容并行构建、可发布复用的 Sphinx 扩展并懂得如何通过Sphinx对象精确控制文档构建的每个阶段。扩展的本质一个带setup()的 Python 模块每个 Sphinx 扩展本质上就是一个 Python 模块其中至少包含一个setup函数。构建初始化时Sphinx 会以应用对象app即sphinx.application.Sphinx的实例作为唯一参数调用该函数# my_extension.py def setup(app): # 在这里注册指令、角色、事件、配置项…… pass用户在项目的conf.py中通过extensions配置值启用扩展例如extensions [my_extension]。sphinx-build启动后Sphinx 会依次导入每个列出的模块并执行yourmodule.setup(app)——这一点在 doc/extdev/index.rst 中有明确说明同时conf.py自身也可以被当作一个扩展只要其中定义了setup()函数Sphinx 就会像对待普通扩展一样调用它对应 sphinx/application.py 中的if self.config.setup:分支。从源码结构看扩展加载的完整调用链是Sphinx.__init__先依次加载内置扩展builtin_extensions元组如sphinx.addnodes、sphinx.builders.html、sphinx.domains.python等见 sphinx/application.py再加载用户配置的扩展每个扩展通过Sphinx.setup_extension(extname)委托给SphinxComponentRegistry.load_extension()sphinx/registry.py完成导入与setup(app)调用扩展的setup()返回值是可选的元数据字典其中version、parallel_read_safe、parallel_write_safe会被封装进Extension对象sphinx/extension.py供后续版本校验与并行构建判断使用。def setup(app): app.add_directive(my-directive, MyDirective) return { version: 1.0.0, parallel_read_safe: True, parallel_write_safe: True, }官方扩展的完整范例集中在 sphinx/ext 目录下如todo.py、viewcode.py、autosectionlabel.py等它们都是用 Application API 写扩展的最佳参照。扩展注册 APIsetup 阶段的核心方法以下方法通常在扩展的setup()函数中被调用。它们几乎都在 sphinx/application.py 中定义多数只是将注册动作转发给SphinxComponentRegistry或 docutils 注册表。所有这些方法在出错时都会抛出ExtensionError异常见 sphinx/errors.py该异常会携带原始异常与模块名便于定位是哪个扩展出了问题。依赖加载与版本检查app.setup_extension(extname)sphinx/application.py以模块名加载另一个扩展用于你的扩展依赖他人扩展提供的功能重复调用是空操作load_extension会先检查extname in app.extensions。app.require_sphinx(version)sphinx/application.py检查运行中的 Sphinx 版本version形如2.5或(2, 5)若当前版本过旧抛出VersionRequirementError。注意当前仓库的 Sphinx 版本为 9.1.1sphinx/init.py。事件系统注册与注销app.connect(event, callback, priority500)sphinx/application.py为事件注册回调返回可用于注销的监听器 ID。回调按priority升序执行3.0 起支持优先级。app.disconnect(listener_id)sphinx/application.py按 ID 注销回调。app.add_event(name)sphinx/application.py注册自定义事件名之后才能发射它事件名重复会抛ExtensionError见 sphinx/events.py。事件的实际管理由EventManager承担内置核心事件清单定义在core_events字典中sphinx/events.py包括config-inited、builder-inited、source-read、doctree-read、doctree-resolved、env-updated、build-finished、missing-reference等。各事件的回调参数说明详见 doc/extdev/event_callbacks.rst。def source_read_handler(app, docname, source): print(f正在读取文档: {docname}) def setup(app): app.connect(source-read, source_read_handler, priority500)Builder 与翻译器app.add_builder(builder_cls, overrideFalse)sphinx/application.py注册新的 builder 类以支持新的输出格式或对已解析文档的新操作overrideTrue可强制覆盖同名 builder。app.set_translator(name, translator_class, overrideFalse)sphinx/application.py注册或替换 docutils 翻译器类常与add_node配合为自定义节点提供特定输出格式的渲染逻辑。配置值注册add_config_valueapp.add_config_value(name, default, rebuild, types(), description)sphinx/application.py是扩展声明自身配置项的必经之路不注册的值 Sphinx 无法识别也就不会写入app.config。四个关键参数参数说明name配置项名称建议以扩展名作为前缀如html_logo、epub_titledefault默认值若为可调用对象则会被以 config 对象为参数调用以得到默认值0.4 起支持可用于默认值依赖其他配置项的场景rebuild重建条件env表示改动需重建整个环境重新解析文档html表示需完整重建 HTML 输出表示无需特殊重建。从 sphinx/config.py 的_ConfigRebuild类型定义看还支持epub、gettext、applehelp、devhelptypes合法类型可传单个类型、类型列表或ENUM候选集合1.4 起支持description配置项的简短说明7.4 起新增app.add_config_value(todo_include_todos, False, html, typesbool) app.add_config_value(my_theme_variant, light, html, ENUM(light, dark))types校验由Config内部的_Opt对象执行内置配置项的默认值与合法类型全部声明在Config.config_values字典中sphinx/config.py例如language: _Opt(en, env, frozenset((str,)))可对照查看合法类型与 rebuild 值的真实用法。节点与枚举节点app.add_node(node, overrideFalse, **kwargs)sphinx/application.py注册 docutils 节点类并通过关键字参数为各输出格式提供(visit, depart)访客函数关键字可取html、latex、text、man、texinfo等。若depart为None表示visit会抛docutils.nodes.SkipNode来跳过离开处理。未提供访客函数的格式遇到该节点时无法翻译。class math(docutils.nodes.Element): ... def visit_math_html(self, node): self.body.append(self.starttag(node, math)) def depart_math_html(self, node): self.body.append(/math) app.add_node(math, html(visit_math_html, depart_math_html))app.add_enumerable_node(node, figtype, title_getterNone, overrideFalse, **kwargs)sphinx/application.py把节点注册为可自动编号的 numfig 目标用户可通过numref角色引用。系统内置figure、table、code-block三种figtype各有独立编号序列也支持传入新 figtype 定义新的编号序列title_getter返回节点标题字符串默认从caption或title子节点查找。指令与角色app.add_directive(name, cls, overrideFalse)sphinx/application.py注册 docutils 指令类docutils.parsers.rst.Directive子类。from docutils.parsers.rst import Directive, directives class MyDirective(Directive): has_content True required_arguments 1 optional_arguments 0 final_argument_whitespace True option_spec { class: directives.class_option, name: directives.unchanged, } def run(self): pass def setup(app): app.add_directive(my-directive, MyDirective)app.add_role(name, role, overrideFalse)sphinx/application.py注册 docutils 角色函数。app.add_generic_role(name, nodeclass, overrideFalse)sphinx/application.py注册一个只把内容包进指定节点的通用角色源码中通过docutils.parsers.rst.roles.GenericRole(name, nodeclass)实现0.6 起支持。域Domain相关域是 Sphinx 对同一类型对象的指令、角色、索引、交叉引用关系的整体封装深入原理见 doc/extdev/domainapi.rstapp.add_domain(domain_cls, overrideFalse)sphinx/application.py注册域类sphinx.domains.Domain子类如py、c、cpp域。app.add_directive_to_domain(domain, name, cls, overrideFalse)sphinx/application.py向指定域添加指令等价于域的局部add_directive。app.add_role_to_domain(domain, name, role, overrideFalse)sphinx/application.py向指定域添加角色。app.add_index_to_domain(domain, index_cls)sphinx/application.py向指定域注册自定义索引类sphinx.domains.Index子类。app.add_object_type(directivename, rolename, indextemplate, parse_nodeNone, ref_nodeclassNone, objname, doc_field_types(), overrideFalse)sphinx/application.py便捷方法一步创建文档化指令 交叉引用角色 索引项。indextemplate必须恰好含一个%s占位符引用节点默认为字面量等宽样式可通过ref_nodeclass如docutils.nodes.emphasis改变也可使用sphinx.addnodes.literal_emphasis、literal_strong获得按字面处理但不带等宽样式的效果。# 注册后即可使用 .. rst:directive:: 与 :rst:dir:... app.add_object_type(directive, dir, pair: %s; directive)app.add_crossref_type(directivename, rolename, indextemplate, ref_nodeclassNone, objname, overrideFalse)sphinx/application.py与add_object_type类似但生成的指令必须为空且不产生输出仅用于建立可交叉引用的语义目标。app.add_crossref_type(topic, topic, single: %s, docutils.nodes.emphasis)变换Transformapp.add_transform(transform_cls)sphinx/application.py注册 docutils 变换类在 Sphinx 解析完 reST 文档后应用。变换的priority数值决定了执行阶段源码给出了完整的优先级区间分类表优先级Sphinx 中的主要用途0–99修正 docutils 产生的非法节点、翻译文档树100–299准备工作300–399早期处理400–699主要处理700–799后处理文本与引用的最后修改时机800–899收集引用与被引用节点、域处理900–999收尾与清理app.add_post_transform(transform_cls)sphinx/application.py注册在 Sphinx写出文档之前应用的变换与add_transform的阶段不同。HTML 资产JS、CSS 与静态目录app.add_js_file(filename, priority500, loading_methodNone, **kwargs)sphinx/application.py注册要包含进 HTML 输出的 JavaScript 文件。filename必须是相对静态路径、带协议完整 URI或None配合body关键字生成内联script。loading_method可取async或defer4.4 起支持其余关键字会作为script标签属性。优先级约定200 为内置 JS 默认值、500 为扩展默认值、800 为html_js_files配置的默认值。在html-page-context事件中调用可为特定页面添加 JS。app.add_js_file(example.js) # script src_static/example.js/script app.add_js_file(example.js, loading_methodasync) app.add_js_file(None, bodyvar myVariable foo;)app.add_css_file(filename, priority500, **kwargs)sphinx/application.py注册样式表优先级约定与 JS 相同200/500/800关键字会作为link标签属性例如mediaprint、relalternate stylesheet、title...。app.add_static_dir(path)sphinx/application.py注册静态目录构建 HTML 时其内容会复制到输出_static目录保留子目录结构。复制顺序为扩展静态目录在主题静态文件之后、用户html_static_path配置之前9.1 起新增的方法。from pathlib import Path def setup(app): app.add_static_dir(Path(__file__).parent / static) app.add_js_file(js/my_extension.js) app.add_css_file(css/my_extension.css)LaTeX、语法高亮与 autodocapp.add_latex_package(packagename, optionsNone, after_hyperrefFalse)sphinx/application.py让 LaTeX 输出的源文件中\usepackage引入指定包after_hyperrefTrue时在hyperref之后加载。app.add_latex_package(mypackage, foo,bar)对应\usepackage[foo,bar]{mypackage}。app.add_lexer(alias, lexer_cls)sphinx/application.py为代码块语言别名注册 Pygments lexer 类2.1 起只接受 lexer 类4.0 移除了实例支持写入sphinx.highlighting.lexer_classes。app.add_autodocumenter(cls, overrideFalse)sphinx/application.py为 autodoc 扩展注册新的文档器类必须是sphinx.ext.autodoc.Documenter子类同时自动注册对应的auto*指令。app.add_autodoc_attrgetter(typ, getter)sphinx/application.py为特定类型注册 autodoc 专用的取属性函数接口与内置getattr兼容autodoc 获取该类型实例的属性时会改用它。搜索语言、源文件解析与环境收集app.add_search_language(cls)sphinx/application.py注册sphinx.search.SearchLanguage子类以支持 HTML 全文搜索索引的新语言类须有lang属性。app.add_source_suffix(suffix, filetype, overrideFalse)sphinx/application.py注册源文件后缀及其解析的文件类型效果等同source_suffix配置用户配置可覆盖扩展设置。app.add_source_parser(parser_cls, overrideFalse)sphinx/application.py注册解析器类1.8 起废弃了suffix参数后缀请改用add_source_suffix。app.add_env_collector(collector_cls)sphinx/application.py注册环境收集器类EnvironmentCollector子类收集器是 Sphinx 1.6 引入的在构建环境中缓存与合并数据的机制详见 doc/extdev/collectorapi.rst。主题、数学渲染与消息目录app.add_html_theme(name, theme_path)sphinx/application.py注册 HTML 主题theme_path是主题目录的完整路径。app.add_html_math_renderer(name, inline_renderersNone, block_renderersNone)sphinx/application.py注册 HTML 数学渲染器分别为行内数学节点nodes.math与块级数学节点nodes.math_block提供访客函数。app.add_message_catalog(catalog, locale_dir)sphinx/application.py注册 gettext 消息目录使扩展自身的文案可参与文档翻译。并行构建与资产策略app.is_parallel_allowed(typ)sphinx/application.py检查并行处理是否被允许typ只能是read或write。它遍历所有已加载扩展读取parallel_read_safe/parallel_write_safe元数据未声明则警告并保守地回退到串行声明为不安全同样回退串行。这提醒扩展作者务必在setup()返回的元数据中显式声明并行安全性。app.set_html_assets_policy(policy)sphinx/application.py设置 HTML 资产包含策略always表示所有页面都包含per_page表示只在用到的页面包含非法值抛ValueError4.1 起支持。发射事件优先使用事件管理器虽然Sphinx类也提供emit与emit_firstresult但扩展开发者应优先直接使用事件管理器对象app.events即EventManager.emit与EventManager.emit_firstresult二者行为与Sphinx上的同名方法完全一致doc/extdev/appapi.rst 中的attention提示及 sphinx/application.py 的委托实现。events.emit(event, *args, allowed_exceptions())sphinx/events.py发射事件并把参数传给所有回调返回所有回调返回值的列表。回调按 priority 升序执行allowed_exceptions用于放行某些希望继续传播的异常3.1 起支持。若某个回调抛出其他异常会被包装成ExtensionError并附上模块名——除非启用 pdb 调试模式直接重抛。events.emit_firstresult(event, *args, allowed_exceptions())sphinx/events.py与emit相同但返回第一个非None的回调结果0.5 起支持适用于missing-reference这类谁先给出答案就用谁的场景。def setup(app): # 注册自定义事件注意不要发射 Sphinx 核心事件 app.add_event(my-ext-processed) def my_handler(app, docname): ... def setup(app): app.connect(my-ext-processed, my_handler) # 在扩展的其他代码中发射 # app.events.emit(my-ext-processed, docname)注意emit的 docstring 明确要求扩展中不要发射 Sphinx 核心事件自定义事件请先通过add_event注册。Sphinx 运行时信息属性Sphinx应用对象还以属性形式暴露构建过程的运行时信息属性含义app.project当前目标项目sphinx.project.Project实例封装源目录与source_suffix映射在 sphinx/application.py 创建app.srcdir源文档目录app.confdir包含conf.py的目录若未提供 confdir则回退为srcdir见 sphinx/application.pyapp.doctreedir存放 pickled doctree构建环境缓存的目录app.outdir存放构建产物的目录app.fresh_env_used本次构建是否创建了全新环境True/False环境尚未初始化时为None属性实现见 sphinx/application.py检查 Sphinx 版本version_info为了让扩展适配 Sphinx 的 API 演进可以在运行时读取sphinx.version_infoimport sphinx if sphinx.version_info (9, 0): # 兼容旧 API 的代码路径 ...version_info是五元组(major, minor, micro, releaselevel, serial)例如当前仓库中sphinx.__init__.py定义为(9, 1, 1, beta, 0)sphinx/init.py即 Sphinx 9.1.1。与之配合的还有sphinx.__version__字符串形式。更严格的声明方式是app.require_sphinx()或在conf.py中设置needs_sphinx。Config 对象与 ENUMsphinx.config.Config是配置文件的抽象sphinx/config.py它把全部配置项暴露为属性可通过app.config与env.config访问例如app.config.language。内置配置项的默认值、rebuild 条件、合法类型集中在Config.config_values字典中是了解注册一个配置项后会发生什么的权威参照。ENUM类用于声明配置值必须是以下候选之一sphinx/config.py其match()方法同时支持单个值或序列app.add_config_value( my_ext_level, info, rebuildenv, typesENUM(debug, info, warning, error), )模板桥TemplateBridgeTemplateBridgesphinx/application.py定义了模板桥接口——负责给定模板名与上下文渲染模板的类用于接入第三方模板引擎init(builder, themeNone, dirsNone)由 builder 调用以初始化模板系统theme为sphinx.theming.Theme对象或None后者时dirs为固定模板目录列表。可查看builder.config.templates_path。newest_template_mtime()返回最新变更模板文件的 mtime供 builder 判断输出是否因模板变更而过期默认实现返回0。render(template, context)按文件名渲染模板并写入输出context为 Python 字典。render_string(template, context)按字符串渲染模板并返回结果字符串。默认实现均抛NotImplementedError子类必须实现除newest_template_mtime有合理默认值外。主题系统本身即基于模板机制可参考 sphinx/themes 与 doc/usage/theming.rst。异常体系sphinx.errors扩展 API 相关异常全部定义在 sphinx/errors.py 中统一以SphinxError为基类。它携带category属性如Sphinx errorSphinx 捕获后会以category: message的形式中止构建并展示给用户建议扩展的自定义错误也继承SphinxError而非SphinxError的异常会被视为意外错误向用户展示部分 traceback完整 traceback 保存到临时文件。异常类用途categorySphinxError所有友好异常的基类Sphinx errorSphinxWarning警告被当作错误时Warning, treated as errorApplicationError应用初始化错误Application errorExtensionError扩展相关错误构造时可选携带orig_exc与modnamecategory会显示模块名Extension error (modname)ConfigError配置错误Configuration errorThemeError主题错误Theme errorVersionRequirementErrorSphinx 版本不满足要求Sphinx version error例如require_sphinx版本过旧、needs_sphinx配置高于当前版本、needs_extensions中扩展版本不足sphinx/extension.py都会抛出VersionRequirementError。实战一个完整的最小扩展骨架综合以上 API一个结构完整、可放入sphinx/ext/参照的扩展骨架如下# my_extension.py from docutils import nodes from docutils.parsers.rst import Directive from sphinx.errors import SphinxError from sphinx.util.docutils import SphinxDirective class MyError(SphinxError): category My extension error class MyDirective(SphinxDirective): has_content True def run(self): node nodes.paragraph(textHello from my extension) return [node] def visit_my_node(self, node): self.body.append(self.starttag(node, div, CLASSmy-node)) def depart_my_node(self, node): self.body.append(/div) def on_build_finished(app, exception): if exception is None: print(my extension: build finished successfully) def setup(app): # 依赖与其他扩展 app.setup_extension(sphinx.ext.todo) app.require_sphinx(7.0) # 指令 / 角色 / 节点 app.add_directive(my-directive, MyDirective) app.add_generic_role(my-node, nodes.emphasis) app.add_node(nodes.emphasis, html(visit_my_node, depart_my_node)) # 配置项建议加扩展名前缀 app.add_config_value(my_ext_enabled, True, env, typesbool) # 自定义事件与回调 app.add_event(my-ext-ready) app.connect(build-finished, on_build_finished) # HTML 资产 app.add_js_file(js/my_extension.js) app.add_css_file(css/my_extension.css) app.add_static_dir(static) # 元数据版本与并行安全声明 return { version: 1.0.0, parallel_read_safe: True, parallel_write_safe: True, }把该模块加入conf.py的extensions列表后sphinx-build即会在初始化阶段导入并调用setup(app)。想系统学习如何用这些 API 编写指令与角色可继续阅读 doc/extdev/markupapi.rst想了解每个事件回调的精确签名参见 doc/extdev/event_callbacks.rst。赞分享文档开发工具【免费下载链接】sphinxThe Sphinx documentation generator项目地址https://gitcode.com/gh_mirrors/sp/sphinx点击查看免费下载相关推荐RenderDoc qrenderdoc 模块 UI 扩展 API 完全指南ExtensionManager、MiniQtHelper 与扩展注册机制RenderDoc qrenderdoc 模块 UI 扩展 API 完全指南ExtensionManager、MiniQtHelper 与扩展注册机制 导读开发工具调试器图形学GPUqutebrowser 扩展 API 完全指南从命令注册、钩子机制到 Tab 与请求拦截的开发者手册qutebrowser 扩展 API 完全指南从命令注册、钩子机制到 Tab 与请求拦截的开发者手册 qutebrowser 是一个基于 Python 与 Q桌面应用Egg 框架扩展机制全解从 Application 到 Helper 的五大扩展点实战指南Egg 框架扩展机制全解从 Application 到 Helper 的五大扩展点实战指南 导读 Egg 框架基于 Koa 之上提供了一套约定优先Conve后端Web框架上一篇aitextgen完整指南10个技巧掌握GPT-2文本生成与训练下一篇无 Root 获得 ADB 级 Shell 权限Shizuku 生态中 rish 可执行文件的安装、语法与自动化实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?