我自动生成由Sphinx渲染为多种格式的reStructuredText文件,包括HTML。reStructuredText 文件有时包含 HTML 特殊字符,例如 HTML 构建器无法转义的<
,从而导致无效的 HTML 输出。这使我无法自动执行文档生成过程,迫使我手动修复输出文件。该问题的一个具体示例是:
<div class="line">
<code class="docutils literal notranslate">
<span class="pre">public</span>
</code>
<span class="xref std std-ref">heap(
</span>
</div>
它发生在heap(<)
文本片段上。输出当前必须手动固定为:
<div class="line">
<code class="docutils literal notranslate">
<span class="pre">public</span>
</code>
<a class="reference internal" href="heap_1.html#heap-1">
<span class="std std-ref">heap(<)</span>
</a>
</div>
我在 HTML 构建器的狮身人面像文档中找不到解决此问题的任何解决方案。有什么解决方法吗?修复原始文本中的问题不是一种选择(文本是源代码,必须编译干净;转义字符(如<
)会破坏其编译)。对应的 reStructuredText 文件片段为:
| **Extends:**
| ``public`` :ref:`heap(<) <heap/1>`
它是从 XML 文件片段自动生成的:
<extends>
<name><![CDATA[heap(<)]]></name>
<functor><![CDATA[heap/1]]></functor>
<scope>public</scope>
<file><![CDATA[heap_1]]></file>
</extends>
让我们从解决将要引用的超链接目标开始,以下示例使用:
超链接目标 - 重新结构化文本标记规范。
命名超链接目标由显式标记开头 ("..) ")、下划线、引用名称(无尾随下划线)、冒号、空格和链接块组成:
.. _hyperlink-name: link-block
接下来让我们看一下引用本身:
交叉引用语法 - 角色。
(...) 就像在 reST 直接超链接中一样:
:role:`title <target>`
将引用目标,但链接文本将是标题。(...
交叉引用任意位置 - 角色。
:裁判:
(...) 但您必须使用以下语法为链接指定显式标题:
:ref:`Link title <label-name>`
。
现在进入问题,以下 reST 以及前面提到的一对命名超链接目标:
.. _hyperlink-name:
.. _hyperlink-name2/:
| **Extends:**
| ``private`` :ref:`some title <hyperlink-name>`
| **Extends:**
| ``private`` :ref:`some title <hyperlink-name2/>`
提供以下 XML 文档树目标:
<target refid="hyperlink-name"></target>
<paragraph ids="hyperlink-name" names="hyperlink-name">
<target refid="hyperlink-name2"></target>
<paragraph ids="hyperlink-name2" names="hyperlink-name2/">
以及以下 XML 文档树引用:
<line><literal>private</literal>
<reference internal="True" refid="hyperlink-name">
<inline classes="std std-ref">some title</inline>
</reference>
</line>
<line><literal>private</literal>
<reference internal="True" refid="hyperlink-name2">
<inline classes="std std-ref">some title</inline>
</reference>
</line>
从这些生成以下 HTML:
<p id="hyperlink-name">
<p id="hyperlink-name2">
<div class="line">
<code class="docutils literal notranslate">
<span class="pre">private</span>
</code>
<a class="reference internal" href="#hyperlink-name">
<span class="std std-ref">some title</span>
</a>
</div>
<div class="line">
<code class="docutils literal notranslate">
<span class="pre">private</span>
</code>
<a class="reference internal" href="#hyperlink-name2">
<span class="std std-ref">some title</span>
</a>
</div>
到目前为止,只有对应于.. _hyperlink-name2/:
的refid
中的正斜杠已规范化。查看语法:ref:`Link title <label-name>`
这解决了label-name
的任何问题。
现在让我们尝试完整的示例:
| **Extends:**
| ``private`` :ref:`heap(<) <hyperlink-name2/>`
以上立即让狮身人面像发出警告:
C:\path_to_your_rest_file.rst:98: 警告: 未定义的标签: )
生成成功,1 条警告。
仔细看警告...!这就是为什么你的HTML被破坏了,因为你在编写狮身人面像:ref:
角色时违反了为数不多的语法规则之一。这不是 HTML 构建器问题,也不是 reST 解析器问题。第一个<
"小于号"字符定义:ref:
角色中Link title
的结束和label-name
的开始。这就是为什么未定义的标签) <hyperlink-name2/
而不仅仅是hyperlink-name2/
.
如果转义<
"小于号"字符:
| **Extends:**
| ``private`` :ref:`heap(<) <hyperlink-name2/>`
在文档树中,狮身人面像解析器已经将字符转换为(<)
。
<line><literal>private</literal>
<reference internal="True" refid="hyperlink-name2">
<inline classes="std std-ref">heap(<)</inline>
</reference>
</line>
同样在 HTML 构建器步骤之后:
<div class="line">
<code class="docutils literal notranslate">
<span class="pre">private</span>
</code>
<a class="reference internal" href="#hyperlink-name2">
<span class="std std-ref">heap(<)</span>
</a>
</div>
我在 HTML 构建器的狮身人面像文档中找不到解决此问题的任何解决方案。
没有任何,在文档配置中也没有,在狮身人面像配置中也没有。因为两者都没有解决格式错误的 reST 或狮身人面像角色的配置。
修复原始文本中的问题不是一种选择(文本是源代码,必须编译干净;转义字符,如<会破坏其编译)。>
您不必更改原始源代码。如果要生成XML -> XSLT -> reST
则最终的 reST/Sphinx 语法必须正确。因此,为:ref:
角色重写 XSLT 或 XML(或者在使用 Sphinx 生成之前对 reST 进行一些预处理)。