[docutils:bugs] #518 id_prefix removes footnote prefix from
Günter Milde via Docutils-develop <[email protected]> Tue, 24 Mar 2026 17:23:02 -0000
| Newsgroups | gmane.text.docutils.devel |
|---|---|
| Message-ID | </p/docutils/bugs/518/2b2c096fe1e067a365451db0ab3b610fa990c3bb.bugs@docutils.p.sourceforge.net> |
This is a multi-part message in MIME format.
--===============7151139055253967860==
Content-Type: multipart/related; boundary="===============0101529963511801710=="
This is a multi-part message in MIME format.
--===============0101529963511801710==
Content-Type: multipart/alternative; boundary="===============1166491128007995970=="
MIME-Version: 1.0
--===============1166491128007995970==
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Thank you for the report.
I'd classify the problem as a documentation issue rather than a bug.
The problem is the difference between an *reference name* and an *identifier* .
Identifiers are derived from reference names via the [identifier normalization](https://docutils.sourceforge.io/docs/ref/rst/directives.html#identifier-normalization). Due to identifier restriction in HTML4, a reference name consisting of only digits "vanishes completely" unless prefixed. (cf. https://sourceforge.net/p/docutils/feature-requests/66/).
This is why the reference-name "5" is replaced by the auto-generated ID "footnote-1" (with 1 just be a running number to disambiguate all "footnote" IDs). A similar problem happens to, e.g. section headings consiting of just a date.
However, prefixing the ID with "user-content" allows the "1" to be appended.
You may play with the attached test script.
Attachments:
- [ids.py](https://sourceforge.net/p/docutils/bugs/_discuss/thread/8a618f0801/b4e5/attachment/ids.py) (832 Bytes; text/x-python)
---
**[bugs:#518] id_prefix removes footnote prefix from **
**Status:** open
**Created:** Sun Mar 22, 2026 12:40 AM UTC by miketheman
**Last Updated:** Sun Mar 22, 2026 12:40 AM UTC
**Owner:** nobody
I was recently working on adding an `id_prefix` string to enable the behavior as described in https://docutils.sourceforge.io/docs/user/config.html#id-prefix
It works pretty consistently, however when I came across a footnote, it removed the `footnote-` prefix from the rendered ID, but not the associated `href` value, leaving the rendered links a little more confusing than before.
Here's a reproduction example:
```python
import sys
from difflib import unified_diff
from docutils.core import publish_parts
INPUT_RST_WITH_FOOTNOTES = """
Footnote reference, like [5]_.
Some Text
.. [5] A numerical footnote.
"""
def render_body(rst: str, settings: dict) -> str:
return publish_parts(rst, writer="html5", settings_overrides=settings)["body"]
settings = {"output_encoding": "unicode"}
basic = render_body(INPUT_RST_WITH_FOOTNOTES, settings)
settings["id_prefix"] = "user-content-"
prefixed = render_body(INPUT_RST_WITH_FOOTNOTES, settings)
sys.stdout.writelines(
unified_diff(
basic.splitlines(keepends=True),
prefixed.splitlines(keepends=True),
fromfile="basic.html",
tofile="prefixed.html",
)
)
```
Output with Docutils 0.22.4:
:::udiff
--- basic.html
+++ prefixed.html
@@ -1,8 +1,8 @@
-<p>Footnote reference, like <a class="brackets" href="#footnote-1" id="footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>5<span class="fn-bracket">]</span></a>.</p>
+<p>Footnote reference, like <a class="brackets" href="#user-content-5" id="user-content-footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>5<span class="fn-bracket">]</span></a>.</p>
<p>Some Text</p>
<aside class="footnote-list brackets">
-<aside class="footnote brackets" id="footnote-1" role="doc-footnote">
-<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#footnote-reference-1">5</a><span class="fn-bracket">]</span></span>
+<aside class="footnote brackets" id="user-content-5" role="doc-footnote">
+<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#user-content-footnote-reference-1">5</a><span class="fn-bracket">]</span></span>
<p>A numerical footnote.</p>
</aside>
</aside>
The things that are different:
- the footnote reference changes from `1` to `5` - which is more accurate than before - yay!
- the footnote id/href value loses it's `footnote-` prefix in the reference part, the backlinks have the prefix + `footnote-`
Both link and backlink work, it's more about the inconsistent naming of the `id` and associated `href` values, and ther output behavior not matching the expectation from the documentation.
Hope this makes sense!
---
Sent from sourceforge.net because [email protected] is subscribed to https://sourceforge.net/p/docutils/bugs/
To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/docutils/admin/bugs/options. Or, if this is a mailing list, you can unsubscribe from the mailing list.
--===============1166491128007995970==
MIME-Version: 1.0
Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: 7bit
<div class="markdown_content"><p>Thank you for the report.<br/>
I'd classify the problem as a documentation issue rather than a bug.</p>
<p>The problem is the difference between an <em>reference name</em> and an <em>identifier</em> .<br/>
Identifiers are derived from reference names via the <a href="https://docutils.sourceforge.io/docs/ref/rst/directives.html#identifier-normalization" rel="nofollow">identifier normalization</a>. Due to identifier restriction in HTML4, a reference name consisting of only digits "vanishes completely" unless prefixed. (cf. <a href="https://sourceforge.net/p/docutils/feature-requests/66/">https://sourceforge.net/p/docutils/feature-requests/66/</a>).</p>
<p>This is why the reference-name "5" is replaced by the auto-generated ID "footnote-1" (with 1 just be a running number to disambiguate all "footnote" IDs). A similar problem happens to, e.g. section headings consiting of just a date.<br/>
However, prefixing the ID with "user-content" allows the "1" to be appended.</p>
<p>You may play with the attached test script.</p>
<p>Attachments:</p>
<ul>
<li><a href="https://sourceforge.net/p/docutils/bugs/_discuss/thread/8a618f0801/b4e5/attachment/ids.py">ids.py</a> (832 Bytes; text/x-python)</li>
</ul>
<hr/>
<p>**<a class="alink" href="https://sourceforge.net/p/docutils/bugs/518/">[bugs:#518]</a> id_prefix removes footnote prefix from **</p>
<p><strong>Status:</strong> open<br/>
<strong>Created:</strong> Sun Mar 22, 2026 12:40 AM UTC by miketheman<br/>
<strong>Last Updated:</strong> Sun Mar 22, 2026 12:40 AM UTC<br/>
<strong>Owner:</strong> nobody</p>
<p>I was recently working on adding an <code>id_prefix</code> string to enable the behavior as described in <a href="https://docutils.sourceforge.io/docs/user/config.html#id-prefix" rel="nofollow">https://docutils.sourceforge.io/docs/user/config.html#id-prefix</a></p>
<p>It works pretty consistently, however when I came across a footnote, it removed the <code>footnote-</code> prefix from the rendered ID, but not the associated <code>href</code> value, leaving the rendered links a little more confusing than before.</p>
<p>Here's a reproduction example:</p>
<div class="codehilite"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">difflib</span><span class="w"> </span><span class="kn">import</span> <span class="n">unified_diff</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">docutils.core</span><span class="w"> </span><span class="kn">import</span> <span class="n">publish_parts</span>
<span class="n">INPUT_RST_WITH_FOOTNOTES</span> <span class="o">=</span> <span class="s2">"""</span>
<span class="s2">Footnote reference, like [5]_.</span>
<span class="s2">Some Text</span>
<span class="s2">.. [5] A numerical footnote.</span>
<span class="s2">"""</span>
<span class="k">def</span><span class="w"> </span><span class="nf">render_body</span><span class="p">(</span><span class="n">rst</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">settings</span><span class="p">:</span> <span class="nb">dict</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
<span class="k">return</span> <span class="n">publish_parts</span><span class="p">(</span><span class="n">rst</span><span class="p">,</span> <span class="n">writer</span><span class="o">=</span><span class="s2">"html5"</span><span class="p">,</span> <span class="n">settings_overrides</span><span class="o">=</span><span class="n">settings</span><span class="p">)[</span><span class="s2">"body"</span><span class="p">]</span>
<span class="n">settings</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"output_encoding"</span><span class="p">:</span> <span class="s2">"unicode"</span><span class="p">}</span>
<span class="n">basic</span> <span class="o">=</span> <span class="n">render_body</span><span class="p">(</span><span class="n">INPUT_RST_WITH_FOOTNOTES</span><span class="p">,</span> <span class="n">settings</span><span class="p">)</span>
<span class="n">settings</span><span class="p">[</span><span class="s2">"id_prefix"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"user-content-"</span>
<span class="n">prefixed</span> <span class="o">=</span> <span class="n">render_body</span><span class="p">(</span><span class="n">INPUT_RST_WITH_FOOTNOTES</span><span class="p">,</span> <span class="n">settings</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">writelines</span><span class="p">(</span>
<span class="n">unified_diff</span><span class="p">(</span>
<span class="n">basic</span><span class="o">.</span><span class="n">splitlines</span><span class="p">(</span><span class="n">keepends</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
<span class="n">prefixed</span><span class="o">.</span><span class="n">splitlines</span><span class="p">(</span><span class="n">keepends</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
<span class="n">fromfile</span><span class="o">=</span><span class="s2">"basic.html"</span><span class="p">,</span>
<span class="n">tofile</span><span class="o">=</span><span class="s2">"prefixed.html"</span><span class="p">,</span>
<span class="p">)</span>
<span class="p">)</span>
</code></pre></div>
<p>Output with Docutils 0.22.4:</p>
<div class="codehilite"><pre><span></span><code><span class="gd">--- basic.html</span>
<span class="gi">+++ prefixed.html</span>
<span class="gu">@@ -1,8 +1,8 @@</span>
<span class="gd">-<p>Footnote reference, like <a class="brackets" href="#footnote-1" id="footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>5<span class="fn-bracket">]</span></a>.</p></span>
<span class="gi">+<p>Footnote reference, like <a class="brackets" href="#user-content-5" id="user-content-footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>5<span class="fn-bracket">]</span></a>.</p></span>
<span class="w"> </span><p>Some Text</p>
<aside class="footnote-list brackets">
<span class="gd">-<aside class="footnote brackets" id="footnote-1" role="doc-footnote"></span>
<span class="gd">-<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#footnote-reference-1">5</a><span class="fn-bracket">]</span></span></span>
<span class="gi">+<aside class="footnote brackets" id="user-content-5" role="doc-footnote"></span>
<span class="gi">+<span class="label"><span class="fn-bracket">[</span><a role="doc-backlink" href="#user-content-footnote-reference-1">5</a><span class="fn-bracket">]</span></span></span>
<p>A numerical footnote.</p>
</aside>
</aside>
</code></pre></div>
<p>The things that are different:</p>
<ul>
<li>the footnote reference changes from <code>1</code> to <code>5</code> - which is more accurate than before - yay!</li>
<li>the footnote id/href value loses it's <code>footnote-</code> prefix in the reference part, the backlinks have the prefix + <code>footnote-</code></li>
</ul>
<p>Both link and backlink work, it's more about the inconsistent naming of the <code>id</code> and associated <code>href</code> values, and ther output behavior not matching the expectation from the documentation.</p>
<p>Hope this makes sense!</p>
<hr/>
<p>Sent from sourceforge.net because [email protected] is subscribed to <a href="https://sourceforge.net/p/docutils/bugs/">https://sourceforge.net/p/docutils/bugs/</a></p>
<p>To unsubscribe from further messages, a project admin can change settings at <a href="https://sourceforge.net/p/docutils/admin/bugs/options.">https://sourceforge.net/p/docutils/admin/bugs/options.</a> Or, if this is a mailing list, you can unsubscribe from the mailing list.</p></div>
--===============1166491128007995970==--
--===============0101529963511801710==--
--===============7151139055253967860==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
--===============7151139055253967860==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline