Commit 8abc2a12 authored by Jonathan Corbet's avatar Jonathan Corbet

Merge branch 'automarkup' into docs-next

Bring in (finally) automatic markup of function() so we need not load up
our docs with ugly c:func: annotations.
parents 49872a1c d9d7c0c4
...@@ -34,7 +34,8 @@ needs_sphinx = '1.3' ...@@ -34,7 +34,8 @@ needs_sphinx = '1.3'
# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain', 'kfigure', 'sphinx.ext.ifconfig'] extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain',
'kfigure', 'sphinx.ext.ifconfig', 'automarkup']
# The name of the math extension changed on Sphinx 1.4 # The name of the math extension changed on Sphinx 1.4
if (major == 1 and minor > 3) or (major > 1): if (major == 1 and minor > 3) or (major > 1):
......
This diff is collapsed.
...@@ -241,11 +241,14 @@ The C domain of the kernel-doc has some additional features. E.g. you can ...@@ -241,11 +241,14 @@ The C domain of the kernel-doc has some additional features. E.g. you can
The func-name (e.g. ioctl) remains in the output but the ref-name changed from The func-name (e.g. ioctl) remains in the output but the ref-name changed from
``ioctl`` to ``VIDIOC_LOG_STATUS``. The index entry for this function is also ``ioctl`` to ``VIDIOC_LOG_STATUS``. The index entry for this function is also
changed to ``VIDIOC_LOG_STATUS`` and the function can now referenced by: changed to ``VIDIOC_LOG_STATUS``.
.. code-block:: rst Please note that there is no need to use ``c:func:`` to generate cross
references to function documentation. Due to some Sphinx extension magic,
:c:func:`VIDIOC_LOG_STATUS` the documentation build system will automatically turn a reference to
``function()`` into a cross reference if an index entry for the given
function name exists. If you see ``c:func:`` use in a kernel document,
please feel free to remove it.
list tables list tables
......
# SPDX-License-Identifier: GPL-2.0
# Copyright 2019 Jonathan Corbet <corbet@lwn.net>
#
# Apply kernel-specific tweaks after the initial document processing
# has been done.
#
from docutils import nodes
from sphinx import addnodes
import re
#
# Regex nastiness. Of course.
# Try to identify "function()" that's not already marked up some
# other way. Sphinx doesn't like a lot of stuff right after a
# :c:func: block (i.e. ":c:func:`mmap()`s" flakes out), so the last
# bit tries to restrict matches to things that won't create trouble.
#
RE_function = re.compile(r'([\w_][\w\d_]+\(\))')
#
# Many places in the docs refer to common system calls. It is
# pointless to try to cross-reference them and, as has been known
# to happen, somebody defining a function by these names can lead
# to the creation of incorrect and confusing cross references. So
# just don't even try with these names.
#
Skipfuncs = [ 'open', 'close', 'read', 'write', 'fcntl', 'mmap'
'select', 'poll', 'fork', 'execve', 'clone', 'ioctl']
#
# Find all occurrences of function() and try to replace them with
# appropriate cross references.
#
def markup_funcs(docname, app, node):
cdom = app.env.domains['c']
t = node.astext()
done = 0
repl = [ ]
for m in RE_function.finditer(t):
#
# Include any text prior to function() as a normal text node.
#
if m.start() > done:
repl.append(nodes.Text(t[done:m.start()]))
#
# Go through the dance of getting an xref out of the C domain
#
target = m.group(1)[:-2]
target_text = nodes.Text(target + '()')
xref = None
if target not in Skipfuncs:
lit_text = nodes.literal(classes=['xref', 'c', 'c-func'])
lit_text += target_text
pxref = addnodes.pending_xref('', refdomain = 'c',
reftype = 'function',
reftarget = target, modname = None,
classname = None)
xref = cdom.resolve_xref(app.env, docname, app.builder,
'function', target, pxref, lit_text)
#
# Toss the xref into the list if we got it; otherwise just put
# the function text.
#
if xref:
repl.append(xref)
else:
repl.append(target_text)
done = m.end()
if done < len(t):
repl.append(nodes.Text(t[done:]))
return repl
def auto_markup(app, doctree, name):
#
# This loop could eventually be improved on. Someday maybe we
# want a proper tree traversal with a lot of awareness of which
# kinds of nodes to prune. But this works well for now.
#
# The nodes.literal test catches ``literal text``, its purpose is to
# avoid adding cross-references to functions that have been explicitly
# marked with cc:func:.
#
for para in doctree.traverse(nodes.paragraph):
for node in para.traverse(nodes.Text):
if not isinstance(node.parent, nodes.literal):
node.parent.replace(node, markup_funcs(name, app, node))
def setup(app):
app.connect('doctree-resolved', auto_markup)
return {
'parallel_read_safe': True,
'parallel_write_safe': True,
}
...@@ -249,7 +249,7 @@ my @highlights_rst = ( ...@@ -249,7 +249,7 @@ my @highlights_rst = (
[$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"], [$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"],
[$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"], [$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"],
[$type_fp_param, "**\$1\\\\(\\\\)**"], [$type_fp_param, "**\$1\\\\(\\\\)**"],
[$type_func, "\\:c\\:func\\:`\$1()`"], [$type_func, "\$1()"],
[$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"], [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"],
[$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"], [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"],
[$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"], [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment