如何为Sphinx的container指令传递自定义LaTeX环境的6个参数
如何在Sphinx中给自定义LaTeX环境传递多参数?
问题场景
我在conf.py的preamble中声明了一个接受6个参数的自定义LaTeX环境sphinxclasscustomizedrequirement,代码如下:
% REQUIREMENT STYLE/FORMAT \newenvironment{sphinxclasscustomizedrequirement}[6]{ \rule{15cm}{1pt}\\ \fontfamily{qcr}\selectfont \color{red} ARG1 = #1\\[1ex] \color{black} ARG2 = #2\\[1ex] ARG3 = #3\\[1ex] ARG4 = #4\\[1ex] ARG5 = #5\\[1ex] \rule{15cm}{1pt}\\, }{}
尝试用container指令包裹内容块时,无法为该环境指定6个参数,期望生成的LaTeX代码如下:
\begin{sphinxuseclass}{customizedrequirement}{123456}{LOREM}{IPSUM}{DOLOR}{SIT} \sphinxAtStartPar HELLO WORLD THIS IS A TEST \end{sphinxuseclass}
但模仿code-block的参数写法时:
.. container:: customizedrequirement :a: A :b: B :c: C :d: DEBUG HELLO WORLD THIS IS A TEST
生成的却是嵌套的sphinxuseclass环境,完全不符合需求:
\begin{sphinxuseclass}{customizedrequirement} \begin{sphinxuseclass}{a} \begin{sphinxuseclass}{a} \begin{sphinxuseclass}{b} \begin{sphinxuseclass}{b} \begin{sphinxuseclass}{c} \begin{sphinxuseclass}{c} \begin{sphinxuseclass}{d} \begin{sphinxuseclass}{debug} \sphinxAtStartPar HELLO WORLD THIS IS A TEST \end{sphinxuseclass} \end{sphinxuseclass} \end{sphinxuseclass} \end{sphinxuseclass} \end{sphinxuseclass} \end{sphinxuseclass} \end{sphinxuseclass} \end{sphinxuseclass} \end{sphinxuseclass}
解决方案
Sphinx的container指令本身不支持给对应LaTeX环境传递位置参数,它的选项会被解析为额外的CSS/LaTeX类,从而导致嵌套环境问题。以下是两种可行的解决方式:
方案1:自定义RST指令(推荐,兼顾多格式输出)
通过自定义Sphinx扩展指令,直接生成带参数的LaTeX环境调用:
- 在项目中创建扩展文件(如
custom_requirement.py),内容如下:
from docutils import nodes from docutils.parsers.rst import Directive, directives class RequirementDirective(Directive): required_arguments = 6 optional_arguments = 0 final_argument_whitespace = True has_content = True def run(self): args = self.arguments container_node = nodes.container() container_node['classes'].append('customizedrequirement') container_node['latex_args'] = args self.state.nested_parse(self.content, self.content_offset, container_node) return [container_node] def setup(app): app.add_directive('requirement', RequirementDirective) from sphinx.writers.latex import LaTeXTranslator original_visit_container = LaTeXTranslator.visit_container def new_visit_container(self, node): if 'customizedrequirement' in node.get('classes', []) and 'latex_args' in node: args = node['latex_args'] self.body.append(f'\\begin{{sphinxuseclass}}{{customizedrequirement}}') for arg in args: self.body.append(f'{{{arg}}}') self.body.append('\n') self.context.append('\\end{sphinxuseclass}\n') else: original_visit_container(self, node) LaTeXTranslator.visit_container = new_visit_container return { 'version': '0.1', 'parallel_read_safe': True, 'parallel_write_safe': True, }
- 在
conf.py中注册该扩展:
extensions = [ # 已有扩展... 'custom_requirement', ]
- 在RST文档中使用自定义指令:
.. requirement:: 123456 LOREM IPSUM DOLOR SIT AMET HELLO WORLD THIS IS A TEST
这样生成的LaTeX代码就会完全符合预期,同时还能兼容HTML等其他输出格式。
方案2:直接使用raw指令(快速但仅限LaTeX输出)
如果不需要兼顾其他输出格式,可以直接用raw指令插入原生LaTeX代码:
.. raw:: latex \begin{sphinxuseclass}{customizedrequirement}{123456}{LOREM}{IPSUM}{DOLOR}{SIT} HELLO WORLD THIS IS A TEST .. raw:: latex \end{sphinxuseclass}
这种方式简单直接,但仅对LaTeX输出生效,其他格式会忽略这些内容。
内容的提问来源于stack exchange,提问作者Arthur Attout
相关产品推荐
相关产品推荐

