Improve the formatting for RFC section anchors (#11809)

Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
Jakub Stasiak
2024-10-06 05:29:11 +02:00
committed by GitHub
parent 173838b534
commit e04d042f8f
4 changed files with 52 additions and 9 deletions

View File

@@ -64,6 +64,8 @@ Features added
* #11781: Add roles for referencing CVEs (:rst:role:`:cve: <cve>`)
and CWEs (:rst:role:`:cwe: <cwe>`).
Patch by Hugo van Kemenade.
* #11809: Improve the formatting for RFC section anchors.
Patch by Jakub Stasiak and Adam Turner.
Bugs fixed
----------

View File

@@ -332,7 +332,8 @@ class PEP(ReferenceRole):
class RFC(ReferenceRole):
def run(self) -> tuple[list[Node], list[system_message]]:
target_id = 'index-%s' % self.env.new_serialno('index')
entries = [('single', 'RFC; RFC %s' % self.target, target_id, '', None)]
formatted_target = _format_rfc_target(self.target)
entries = [('single', f'RFC; {formatted_target}', target_id, '', None)]
index = addnodes.index(entries=entries)
target = nodes.target('', '', ids=[target_id])
@@ -346,7 +347,7 @@ class RFC(ReferenceRole):
if self.has_explicit_title:
reference += nodes.strong(self.title, self.title)
else:
title = 'RFC ' + self.title
title = formatted_target
reference += nodes.strong(title, title)
except ValueError:
msg = self.inliner.reporter.error(
@@ -366,6 +367,24 @@ class RFC(ReferenceRole):
return base_url + self.inliner.rfc_url % int(ret[0])
def _format_rfc_target(target: str, /) -> str:
"""
Takes an RFC number with an optional anchor (like ``123#section-2.5.3``)
and attempts to produce a human-friendly title for it.
We have a set of known anchors that we format nicely,
everything else we leave alone.
"""
number, _, anchor = target.partition('#')
if anchor:
first, _, remaining = anchor.partition('-')
if first in {'appendix', 'page', 'section'}:
if remaining:
return f'RFC {number} {first.title()} {remaining}'
return f'RFC {number} {first.title()}'
return f'RFC {target}'
class GUILabel(SphinxRole):
amp_re = re.compile(r'(?<!&)&(?![&\s])')

View File

@@ -278,17 +278,17 @@ def get_verifier(verify, verify_re):
(
# rfc role with anchor
'verify',
':rfc:`2324#id1`',
':rfc:`2324#section-1`',
(
'<p><span class="target" id="index-0"></span><a class="rfc reference external" '
'href="https://datatracker.ietf.org/doc/html/rfc2324.html#id1">'
'<strong>RFC 2324#id1</strong></a></p>'
'href="https://datatracker.ietf.org/doc/html/rfc2324.html#section-1">'
'<strong>RFC 2324 Section 1</strong></a></p>'
),
(
'\\sphinxAtStartPar\n'
'\\index{RFC@\\spxentry{RFC}!RFC 2324\\#id1@\\spxentry{RFC 2324\\#id1}}'
'\\sphinxhref{https://datatracker.ietf.org/doc/html/rfc2324.html\\#id1}'
'{\\sphinxstylestrong{RFC 2324\\#id1}}'
'\\index{RFC@\\spxentry{RFC}!RFC 2324 Section 1@\\spxentry{RFC 2324 Section 1}}'
'\\sphinxhref{https://datatracker.ietf.org/doc/html/rfc2324.html\\#section-1}'
'{\\sphinxstylestrong{RFC 2324 Section 1}}'
),
),
(

View File

@@ -2,9 +2,10 @@
from unittest.mock import Mock
import pytest
from docutils import nodes
from sphinx.roles import EmphasizedLiteral
from sphinx.roles import EmphasizedLiteral, _format_rfc_target
from sphinx.testing.util import assert_node
@@ -113,3 +114,24 @@ def test_samp():
],
)
assert msg == []
@pytest.mark.parametrize(
('target', 'expected_output'),
[
('123', 'RFC 123'),
('123#', 'RFC 123#'),
('123#id1', 'RFC 123#id1'),
('123#section', 'RFC 123 Section'),
('123#section-1', 'RFC 123 Section 1'),
('123#section-2.5.3', 'RFC 123 Section 2.5.3'),
('123#page-13', 'RFC 123 Page 13'),
('123#appendix-B', 'RFC 123 Appendix B'),
# Section names are also present in some RFC anchors. Until we come up with a reliable way
# to reconstruct the section names from the corresponding anchors with the correct
# capitalization it's probably better to leave them alone.
('9076#name-risks-in-the-dns-data', 'RFC 9076#name-risks-in-the-dns-data'),
],
)
def test_format_rfc_target(target: str, expected_output: str) -> None:
assert _format_rfc_target(target) == expected_output