sphinx: parser_yaml.py: fix line numbers information

As reported by Donald, this code:

	rst_parser = RSTParser()
	rst_parser.parse('\n'.join(result), document)

breaks line parsing. As an alternative, I tested a variant of it:

	rst_parser.parse(result, document)

but still line number was not preserved. As Donald noted,
standard Parser classes don't have a direct mechanism to preserve
line numbers from ViewList().

So, instead, let's use a mechanism similar to what we do already at
kerneldoc.py: call the statemachine mechanism directly there.

I double-checked when states and statemachine were introduced:
both were back in 2002. I also tested doc build with docutils 0.16
and 0.21.2. It worked with both, so it seems to be stable enough
for our needs.

Reported-by: Donald Hunter <donald.hunter@gmail.com>
Closes: https://lore.kernel.org/linux-doc/m24ivk78ng.fsf@gmail.com/T/#u
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
Mauro Carvalho Chehab 2025-07-10 18:36:40 +02:00
parent d90555ef06
commit 47459937be
1 changed files with 14 additions and 7 deletions

View File

@ -11,7 +11,9 @@ import sys
from pprint import pformat from pprint import pformat
from docutils import statemachine
from docutils.parsers.rst import Parser as RSTParser from docutils.parsers.rst import Parser as RSTParser
from docutils.parsers.rst import states
from docutils.statemachine import ViewList from docutils.statemachine import ViewList
from sphinx.util import logging from sphinx.util import logging
@ -56,6 +58,8 @@ class YamlParser(Parser):
re_lineno = re.compile(r"\.\. LINENO ([0-9]+)$") re_lineno = re.compile(r"\.\. LINENO ([0-9]+)$")
tab_width = 8
def rst_parse(self, inputstring, document, msg): def rst_parse(self, inputstring, document, msg):
""" """
Receives a ReST content that was previously converted by the Receives a ReST content that was previously converted by the
@ -66,10 +70,18 @@ class YamlParser(Parser):
result = ViewList() result = ViewList()
self.statemachine = states.RSTStateMachine(state_classes=states.state_classes,
initial_state='Body',
debug=document.reporter.debug_flag)
try: try:
# Parse message with RSTParser # Parse message with RSTParser
lineoffset = 0; lineoffset = 0;
for line in msg.split('\n'):
lines = statemachine.string2lines(msg, self.tab_width,
convert_whitespace=True)
for line in lines:
match = self.re_lineno.match(line) match = self.re_lineno.match(line)
if match: if match:
lineoffset = int(match.group(1)) lineoffset = int(match.group(1))
@ -77,12 +89,7 @@ class YamlParser(Parser):
result.append(line, document.current_source, lineoffset) result.append(line, document.current_source, lineoffset)
# Fix backward compatibility with docutils < 0.17.1 self.statemachine.run(result, document)
if "tab_width" not in vars(document.settings):
document.settings.tab_width = 8
rst_parser = RSTParser()
rst_parser.parse('\n'.join(result), document)
except Exception as e: except Exception as e:
document.reporter.error("YAML parsing error: %s" % pformat(e)) document.reporter.error("YAML parsing error: %s" % pformat(e))