Sphinx HTML构建器无法转义特殊字符

时间:2019-06-06 17:28:55

标签: python-sphinx

我会自动生成由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(&lt;)</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>

1 个答案:

答案 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 :ref: 角色时违反了少数语法规则之一。这不是 HTML 构建器问题,也不是 reST 解析器问题。第一个 < “小于号”字符定义 Link title 角色中 :ref: 的结尾和 label-name 的开头。这就是未定义标签是 ) <hyperlink-name2/ 而不仅仅是 hyperlink-name2/ 的原因。

如果您转义 <“小于号”字符:

| **Extends:**
|    ``private`` :ref:`heap(\<) <hyperlink-name2/>`

在文档树中,Sphinx 解析器已经将字符转换为 (&lt;)

<line><literal>private</literal>
    <reference internal="True" refid="hyperlink-name2">
        <inline classes="std std-ref">heap(&lt;)</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(&lt;)</span>
    </a>
</div>
<块引用>

我在 HTML 构建器的 Sphinx 文档中找不到针对此问题的任何解决方案。

没有,在 docutils configurationsSphinx configuration 中都没有。因为两者都没有解决格式错误的 reST 或 Sphinx 角色的配置。

<块引用>

修复原文中的问题不是一种选择(文本是必须编译干净的源代码;转义字符如 < there 会破坏其编译)。

您不必更改原始源代码。如果您要生成 XML -> XSLT -> reST,则最终的 reST/Sphinx 语法必须正确。因此,为 :ref: 角色重写 XSLT 或 XML(或在使用 Sphinx 生成之前对 reST 进行一些预处理)。