On 18/02/2024 11:08, Vegard Nossum wrote:
I think the "bug" here is really that Sphinx generated LaTeX code that doesn't build -- and that it didn't warn about the problem in other modes (maybe it does in newer versions, or maybe we overlooked the warnings?). If we'd had those warnings then we could have stopped those constructs from entering the documentation sources to start with.
With the attached patch I get: $ make htmldocs SPHINXDIRS=filesystems/xfs make[3]: Nothing to be done for 'html'. Using alabaster theme source directory: filesystems/xfsWARNING: xfs-online-fsck-design.rst:2096: heading "Case Study: Sorting xfarrays" has nesting level 7; consider restructuring
Maybe we can do the same for itemize lists. I didn't check what impact this potentially has on running time. Also only tested with Sphinx 4.3.2. Thoughts? Vegard
diff --git a/Documentation/conf.py b/Documentation/conf.py index 5830b01c5642..1cfcea4e487d 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -55,7 +55,8 @@ needs_sphinx = '2.4.4' extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'kfigure', 'sphinx.ext.ifconfig', 'automarkup', 'maintainers_include', 'sphinx.ext.autosectionlabel', - 'kernel_abi', 'kernel_feat', 'translations'] + 'kernel_abi', 'kernel_feat', 'translations', + 'kvalidate'] if major >= 3: if (major > 3) or (minor > 0 or patch >= 2): diff --git a/Documentation/sphinx/kvalidate.py b/Documentation/sphinx/kvalidate.py new file mode 100644 index 000000000000..3302e936db77 --- /dev/null +++ b/Documentation/sphinx/kvalidate.py @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright © 2024, Oracle and/or its affiliates. +# Author: Vegard Nossum <vegard.nossum@xxxxxxxxxx> +# +# Validate doc tree against kernel-specific rules. +# + +import os + +import docutils +from sphinx.util import logging + +logger = logging.getLogger('kerneldoc') + +max_heading_levels = 5 + +def process_doctree(app, doctree): + env = app.env + srcdir = env.srcdir + + for node in doctree.traverse(docutils.nodes.title): + heading_level = 0 + + ancestor = node.parent + while ancestor is not None: + if isinstance(ancestor, docutils.nodes.section): + heading_level = heading_level + 1 + + ancestor = ancestor.parent + + if heading_level > max_heading_levels: + logger.warning("%s:%u: heading \"%s\" has nesting level %u; consider restructuring", + os.path.relpath(node.source, srcdir), node.line, node.astext(), heading_level + 1) + +def setup(app): + app.connect('doctree-read', process_doctree) + + return { + 'parallel_read_safe': True, + 'parallel_write_safe': True, + }