在 :ref:`title<label>` 的标题中转义“<”

Escaping a "<" in the title of :ref:`title<label>`

我正在自动生成由 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(&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>

让我们从解决将被引用的超链接目标开始,以下示例使用:

Hyperlink Targets - reStructuredText Markup Specification.

Named hyperlink targets consist of an explicit markup start (".. "), an underscore, the reference name (no trailing underscore), a colon, whitespace, and a link block:

.. _hyperlink-name: link-block

接下来让我们看看参考资料本身:

Cross-referencing syntax - Roles.

(...) like in reST direct hyperlinks: :role:`title <target>` will refer to target, but the link text will be title.

(...)

Cross-referencing arbitrary locations - Roles.

:ref:

(...) but you must give the link an explicit title, using this syntax: :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 doctree 参考资料:

<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>

到目前为止,只有 refid 中与 .. _hyperlink-name2/: 对应的正斜杠被规范化了。查看语法 :ref:`Link title <label-name>` 这解决了 label-name.

的任何问题

现在让我们试试完整的例子:

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

以上立即让Sphinx发出警告:

C:\path_to_your_rest_file.rst:98: WARNING: undefined label: ) <hyperlink-name2/

build succeeded, 1 warning.

仔细看警告...!这就是您的 HTML 被破坏的原因,因为您在编写 Sphinx :ref: 角色时违反了为数不多的语法规则之一。这不是 HTML 构建器问题,也不是 reST 解析器问题。第一个 <“小于号”字符定义 :ref: 角色中 Link title 的结尾和 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>

I cannot find in the Sphinx documentation for the HTML builder any solution for this problem.

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

Fixing the problem in the original text is not an option (the text is source code that must compile clean; escaping characters like < there would break its compilation).

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