我会自动生成由Sphinx渲染为多种格式(包括HTML)的reStructuredText文件。 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>
我在Sphinx文档中找不到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>
答案 0 :(得分:1)
让我们首先解决将引用的超链接目标,以下示例使用:
<块引用>Hyperlink Targets - 重构文本标记规范。
命名超链接目标由显式标记开始(“..”)、下划线、引用名称(无尾随下划线)、冒号、空格和链接块组成: >
.. _hyperlink-name: link-block
接下来让我们看看引用本身:
<块引用>Cross-referencing syntax - 角色。
(...) 就像在 reST 直接超链接中一样::role:`title <target>`
将引用目标,但链接文本将是标题。
(...)
Cross-referencing arbitrary locations - 角色。
:ref:
(...) 但您必须使用以下语法为链接指定明确的标题::ref:`Link title <label-name>`
。
现在问题来了,下面是前面提到的一对命名超链接目标:
.. _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/>`
以上立即让 Sphinx 发出警告:
<块引用>C:\path_to_your_rest_file.rst:98: 警告:未定义标签:) 构建成功,1 次警告。 仔细看警告...!这就是您的 HTML 被破坏的原因,因为您在编写 Sphinx 如果您转义 在文档树中,Sphinx 解析器已经将字符转换为 也在 HTML 构建器步骤之后: 我在 HTML 构建器的 Sphinx 文档中找不到针对此问题的任何解决方案。 没有,在 docutils configurations 和 Sphinx configuration 中都没有。因为两者都没有解决格式错误的 reST 或 Sphinx 角色的配置。 修复原文中的问题不是一种选择(文本是必须编译干净的源代码;转义字符如 < there 会破坏其编译)。 您不必更改原始源代码。如果您要生成 :ref:
角色时违反了少数语法规则之一。这不是 HTML 构建器问题,也不是 reST 解析器问题。第一个 <
“小于号”字符定义 Link title
角色中 :ref:
的结尾和 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>
<块引用>
<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>
XML -> XSLT -> reST
,则最终的 reST/Sphinx 语法必须正确。因此,为 :ref:
角色重写 XSLT 或 XML(或在使用 Sphinx 生成之前对 reST 进行一些预处理)。