【问题标题】:Escaping a "<" in the title of :ref:`title<label>`在 :ref:`title<label>` 的标题中转义一个“<”
【发布时间】:2019-06-06 17:28:55
【问题描述】:

我正在自动生成 reStructuredText 文件,这些文件由 Sphinx 呈现为多种格式,包括 HTML。 reStructuredText 文件有时包含 HTML 特殊字符,例如 HTML 构建器无法转义的 &amp;lt;,从而导致无效的 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(&lt;) 文本片段上。当前必须手动将输出固定为:

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

我在 HTML 构建器的 Sphinx 文档中找不到任何解决此问题的方法。有什么解决方法吗?修复原文中的问题不是一种选择(文本是必须编译干净的源代码;像&amp;lt; 这样的转义字符会破坏其编译)。对应的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>

【问题讨论】:

  • literal blockscode blocks 是否适用于您的方案?
  • @StevePiercy 否。在上面的示例中,我有一个名为 hep(&lt;) 的参数对象。指向对象文档的链接将对象名称作为链接的文本。但是 HTML 构建器在 &amp;lt; 字符上卡住了。
  • 您能否粘贴一个您从中生成 HTML 的 reST 样本?看起来您在上面的两个代码示例中只粘贴了make html 的输出。每当我尝试段落、内联文字、文字块或代码块语法时,&amp;lt; 总是被 HTML 编码为 &amp;lt; 并正确显示。
  • 如何在 ReST 标记中转义 &amp;lt; 字符?像这样:heap(\&lt;).
  • @mzjn .rst 文件是自动生成的。预处理所有生成的内容以转义仅用于 HTML 输出的特殊字符的计算成本很高(这里的上下文是为编程语言 Logtalk 的所有 API 生成文档)。这种转义不应该是 HTML 构建器本身的任务吗?

标签: html xml python-sphinx documentation-generation cross-reference


【解决方案1】:

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

Hyperlink Targets - reStructuredText 标记规范。

命名超链接目标由显式标记开始(“..”)、下划线、引用名称(无尾随下划线)、冒号、空格和链接块组成:

.. _hyperlink-name: link-block

接下来让我们看看引用本身:

Cross-referencing syntax - 角色。

(...) 就像在 reST 直接超链接中一样::role:`title &lt;target&gt;` 将引用目标,但链接文本将是标题。

(...)

Cross-referencing arbitrary locations - 角色。

:ref:

(...) 但您必须为链接指定一个明确的标题,使用以下语法::ref:`Link title &lt;label-name&gt;`

现在问题是,下面的 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 &lt;label-name&gt;` 的语法,这解决了label-name 的任何问题。

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

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

以上立即让Sphinx发出警告:

C:\path_to_your_rest_file.rst:98: 警告:未定义标签:)

构建成功,1 个警告。

仔细查看警告...!这就是您的 HTML 被破坏的原因,因为您在编写 Sphinx :ref: 角色时违反了为数不多的语法规则之一。这不是 HTML 构建器问题,也不是 reST 解析器问题。第一个&lt;“小于号”字符定义:ref: 角色中Link title 的结尾和label-name 的开头。这就是为什么未定义的标签是) &lt;hyperlink-name2/ 而不仅仅是hyperlink-name2/

如果您转义 &lt;“小于号”字符:

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

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

<line><literal>private</literal>
    <reference internal="True" refid="hyperlink-name2">
        <inline classes="std std-ref">heap(&lt;)</inline>
    </reference>
</line>

同样在 HTML builder 步骤之后:

<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 角色的配置。

修复原文中的问题不是一种选择(文本是必须编译干净的源代码;转义字符如

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

【讨论】:

  • 建议的解决方案是我在 2019 年实施的解决方案:github.com/LogtalkDotOrg/logtalk3/commit/… 如您所言,这 不是 HTML 构建器错误,尽管 &lt; 不是reST 中的特殊字符,在外部参照角色的特殊情况下是特殊字符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
相关资源
最近更新 更多