docs: sphinx/automarkup: add cross-references for ABI

Now that all ABI files are handled together, we can add a feature
at automarkup for it to generate cross-references for ABI symbols.

The cross-reference logic can produce references for all existing
files, except for README (as this is not parsed).

For symbols, they need to be an exact match of what it is
described at the docs, which is not always true due to wildcards.

If symbols at /sys /proc and /config are identical, a cross-reference
will be used.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Link: https://lore.kernel.org/r/0b97a51b68b1c20127ad4a6a55658557fe0848d0.1739182025.git.mchehab+huawei@kernel.org
This commit is contained in:
Mauro Carvalho Chehab 2025-02-10 11:18:11 +01:00 committed by Jonathan Corbet
parent 4bb2dbd757
commit c940816968
2 changed files with 56 additions and 0 deletions

View file

@ -11,6 +11,8 @@ from sphinx.errors import NoUri
import re
from itertools import chain
from kernel_abi import kernel_abi
#
# Python 2 lacks re.ASCII...
#
@ -48,6 +50,8 @@ RE_typedef = re.compile(r'\b(typedef)\s+([a-zA-Z_]\w+)', flags=ascii_p3)
# an optional extension
#
RE_doc = re.compile(r'(\bDocumentation/)?((\.\./)*[\w\-/]+)\.(rst|txt)')
RE_abi_file = re.compile(r'(\bDocumentation/ABI/[\w\-/]+)')
RE_abi_symbol = re.compile(r'(\b/(sys|config|proc)/[\w\-/]+)')
RE_namespace = re.compile(r'^\s*..\s*c:namespace::\s*(\S+)\s*$')
@ -84,10 +88,14 @@ def markup_refs(docname, app, node):
# Associate each regex with the function that will markup its matches
#
markup_func_sphinx2 = {RE_doc: markup_doc_ref,
RE_abi_file: markup_abi_ref,
RE_abi_symbol: markup_abi_ref,
RE_function: markup_c_ref,
RE_generic_type: markup_c_ref}
markup_func_sphinx3 = {RE_doc: markup_doc_ref,
RE_abi_file: markup_abi_ref,
RE_abi_symbol: markup_abi_ref,
RE_function: markup_func_ref_sphinx3,
RE_struct: markup_c_ref,
RE_union: markup_c_ref,
@ -270,6 +278,43 @@ def markup_doc_ref(docname, app, match):
else:
return nodes.Text(match.group(0))
#
# Try to replace a documentation reference of the form Documentation/ABI/...
# with a cross reference to that page
#
def markup_abi_ref(docname, app, match):
stddom = app.env.domains['std']
#
# Go through the dance of getting an xref out of the std domain
#
fname = match.group(1)
target = kernel_abi.xref(fname)
# Kernel ABI doesn't describe such file or symbol
if not target:
return nodes.Text(match.group(0))
pxref = addnodes.pending_xref('', refdomain = 'std', reftype = 'ref',
reftarget = target, modname = None,
classname = None, refexplicit = False)
#
# XXX The Latex builder will throw NoUri exceptions here,
# work around that by ignoring them.
#
try:
xref = stddom.resolve_xref(app.env, docname, app.builder, 'ref',
target, pxref, None)
except NoUri:
xref = None
#
# Return the xref if we got it; otherwise just return the plain text.
#
if xref:
return xref
else:
return nodes.Text(match.group(0))
def get_c_namespace(app, docname):
source = app.env.doc2path(docname)
with open(source) as f:

View file

@ -391,6 +391,17 @@ class AbiParser:
return desc + "\n\n"
def xref(self, fname):
"""
Converts a Documentation/ABI + basename into a ReST cross-reference
"""
xref = self.file_refs.get(fname)
if not xref:
return None
else:
return xref
def desc_rst(self, desc):
"""Enrich ReST output by creating cross-references"""