[PATCH v2 09/12] docs: sphinx: add a parser template for yaml files

Mauro Carvalho Chehab posted 12 patches 4 months ago
There is a newer version of this series
[PATCH v2 09/12] docs: sphinx: add a parser template for yaml files
Posted by Mauro Carvalho Chehab 4 months ago
Add a simple sphinx.Parser class meant to handle yaml files.

For now, it just replaces a yaml file by a simple ReST
code. I opted to do this way, as this patch can be used as
basis for new file format parsers. We may use this as an
example to parse other types of files.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 Documentation/sphinx/parser_yaml.py | 63 +++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)
 create mode 100755 Documentation/sphinx/parser_yaml.py

diff --git a/Documentation/sphinx/parser_yaml.py b/Documentation/sphinx/parser_yaml.py
new file mode 100755
index 000000000000..b3cde9cf7aac
--- /dev/null
+++ b/Documentation/sphinx/parser_yaml.py
@@ -0,0 +1,63 @@
+"""
+Sphinx extension for processing YAML files
+"""
+
+import os
+
+from docutils.parsers.rst import Parser as RSTParser
+from docutils.statemachine import ViewList
+
+from sphinx.util import logging
+from sphinx.parsers import Parser
+
+from pprint import pformat
+
+logger = logging.getLogger(__name__)
+
+class YamlParser(Parser):
+    """Custom parser for YAML files."""
+
+    supported = ('yaml', 'yml')
+
+    # Overrides docutils.parsers.Parser. See sphinx.parsers.RSTParser
+    def parse(self, inputstring, document):
+        """Parse YAML and generate a document tree."""
+
+        self.setup_parse(inputstring, document)
+
+        result = ViewList()
+
+        try:
+            # FIXME: Test logic to generate some ReST content
+            basename = os.path.basename(document.current_source)
+            title = os.path.splitext(basename)[0].replace('_', ' ').title()
+
+            msg = f"{title}\n"
+            msg += "=" * len(title) + "\n\n"
+            msg += "Something\n"
+
+            # Parse message with RSTParser
+            for i, line in enumerate(msg.split('\n')):
+                result.append(line, document.current_source, i)
+
+            rst_parser = RSTParser()
+            rst_parser.parse('\n'.join(result), document)
+
+        except Exception as e:
+            document.reporter.error("YAML parsing error: %s" % pformat(e))
+
+        self.finish_parse()
+
+def setup(app):
+    """Setup function for the Sphinx extension."""
+
+    # Add YAML parser
+    app.add_source_parser(YamlParser)
+    app.add_source_suffix('.yaml', 'yaml')
+    app.add_source_suffix('.yml', 'yaml')
+
+    return {
+        'version': '1.0',
+        'parallel_read_safe': True,
+        'parallel_write_safe': True,
+    }
-- 
2.49.0
Re: [PATCH v2 09/12] docs: sphinx: add a parser template for yaml files
Posted by Donald Hunter 3 months, 4 weeks ago
Mauro Carvalho Chehab <mchehab+huawei@kernel.org> writes:

> Add a simple sphinx.Parser class meant to handle yaml files.
>
> For now, it just replaces a yaml file by a simple ReST
> code. I opted to do this way, as this patch can be used as
> basis for new file format parsers. We may use this as an
> example to parse other types of files.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> ---
>  Documentation/sphinx/parser_yaml.py | 63 +++++++++++++++++++++++++++++
>  1 file changed, 63 insertions(+)
>  create mode 100755 Documentation/sphinx/parser_yaml.py

It's not a generic yaml parser so the file should be
netlink_doc_generator.py or something.

>
> diff --git a/Documentation/sphinx/parser_yaml.py b/Documentation/sphinx/parser_yaml.py
> new file mode 100755
> index 000000000000..b3cde9cf7aac
> --- /dev/null
> +++ b/Documentation/sphinx/parser_yaml.py
> @@ -0,0 +1,63 @@
> +"""
> +Sphinx extension for processing YAML files
> +"""
> +
> +import os
> +
> +from docutils.parsers.rst import Parser as RSTParser
> +from docutils.statemachine import ViewList
> +
> +from sphinx.util import logging
> +from sphinx.parsers import Parser
> +
> +from pprint import pformat
> +
> +logger = logging.getLogger(__name__)
> +
> +class YamlParser(Parser):
> +    """Custom parser for YAML files."""

The class is only intended to be a netlink doc generator so I sugget
calling it NetlinkDocGenerator

> +
> +    supported = ('yaml', 'yml')

I don't think we need to support the .yml extension.

> +
> +    # Overrides docutils.parsers.Parser. See sphinx.parsers.RSTParser
> +    def parse(self, inputstring, document):
> +        """Parse YAML and generate a document tree."""
> +
> +        self.setup_parse(inputstring, document)
> +
> +        result = ViewList()
> +
> +        try:
> +            # FIXME: Test logic to generate some ReST content
> +            basename = os.path.basename(document.current_source)
> +            title = os.path.splitext(basename)[0].replace('_', ' ').title()
> +
> +            msg = f"{title}\n"
> +            msg += "=" * len(title) + "\n\n"
> +            msg += "Something\n"
> +
> +            # Parse message with RSTParser
> +            for i, line in enumerate(msg.split('\n')):
> +                result.append(line, document.current_source, i)
> +
> +            rst_parser = RSTParser()
> +            rst_parser.parse('\n'.join(result), document)
> +
> +        except Exception as e:
> +            document.reporter.error("YAML parsing error: %s" % pformat(e))
> +
> +        self.finish_parse()
> +
> +def setup(app):
> +    """Setup function for the Sphinx extension."""
> +
> +    # Add YAML parser
> +    app.add_source_parser(YamlParser)
> +    app.add_source_suffix('.yaml', 'yaml')
> +    app.add_source_suffix('.yml', 'yaml')

No need to support the .yml extension.

> +
> +    return {
> +        'version': '1.0',
> +        'parallel_read_safe': True,
> +        'parallel_write_safe': True,
> +    }
Re: [PATCH v2 09/12] docs: sphinx: add a parser template for yaml files
Posted by Mauro Carvalho Chehab 3 months, 4 weeks ago
Em Fri, 13 Jun 2025 12:29:34 +0100
Donald Hunter <donald.hunter@gmail.com> escreveu:

> Mauro Carvalho Chehab <mchehab+huawei@kernel.org> writes:
> 
> > Add a simple sphinx.Parser class meant to handle yaml files.
> >
> > For now, it just replaces a yaml file by a simple ReST
> > code. I opted to do this way, as this patch can be used as
> > basis for new file format parsers. We may use this as an
> > example to parse other types of files.
> >
> > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> > ---
> >  Documentation/sphinx/parser_yaml.py | 63 +++++++++++++++++++++++++++++
> >  1 file changed, 63 insertions(+)
> >  create mode 100755 Documentation/sphinx/parser_yaml.py  
> 
> It's not a generic yaml parser so the file should be
> netlink_doc_generator.py or something.

There's no way I'm aware of to have two yaml parsers. So, assuming that
some other subsystem would also use yaml (*), the same parser will need to
handle yaml files from different parts.

That's why I opted to have a generic name here. Besides that, there's
nothing there which is specific to Netlink, as the actual parser is
implemented inside a class on a separate file.

(*) as I said, media is considering using yaml for sensors. Nothing yet
    materialized, as we just had our summit last month. Yet, as DT also
    uses yaml, so I won't doubt that other subsystems may end using it
    as well.

> > diff --git a/Documentation/sphinx/parser_yaml.py b/Documentation/sphinx/parser_yaml.py
> > new file mode 100755
> > index 000000000000..b3cde9cf7aac
> > --- /dev/null
> > +++ b/Documentation/sphinx/parser_yaml.py
> > @@ -0,0 +1,63 @@
> > +"""
> > +Sphinx extension for processing YAML files
> > +"""
> > +
> > +import os
> > +
> > +from docutils.parsers.rst import Parser as RSTParser
> > +from docutils.statemachine import ViewList
> > +
> > +from sphinx.util import logging
> > +from sphinx.parsers import Parser
> > +
> > +from pprint import pformat
> > +
> > +logger = logging.getLogger(__name__)
> > +
> > +class YamlParser(Parser):
> > +    """Custom parser for YAML files."""  
> 
> The class is only intended to be a netlink doc generator so I sugget
> calling it NetlinkDocGenerator

See above.

> > +
> > +    supported = ('yaml', 'yml')  
> 
> I don't think we need to support the .yml extension.

Ok, will drop "yml".

> > +
> > +    # Overrides docutils.parsers.Parser. See sphinx.parsers.RSTParser
> > +    def parse(self, inputstring, document):
> > +        """Parse YAML and generate a document tree."""
> > +
> > +        self.setup_parse(inputstring, document)
> > +
> > +        result = ViewList()
> > +
> > +        try:
> > +            # FIXME: Test logic to generate some ReST content
> > +            basename = os.path.basename(document.current_source)
> > +            title = os.path.splitext(basename)[0].replace('_', ' ').title()
> > +
> > +            msg = f"{title}\n"
> > +            msg += "=" * len(title) + "\n\n"
> > +            msg += "Something\n"
> > +
> > +            # Parse message with RSTParser
> > +            for i, line in enumerate(msg.split('\n')):
> > +                result.append(line, document.current_source, i)
> > +
> > +            rst_parser = RSTParser()
> > +            rst_parser.parse('\n'.join(result), document)
> > +
> > +        except Exception as e:
> > +            document.reporter.error("YAML parsing error: %s" % pformat(e))
> > +
> > +        self.finish_parse()
> > +
> > +def setup(app):
> > +    """Setup function for the Sphinx extension."""
> > +
> > +    # Add YAML parser
> > +    app.add_source_parser(YamlParser)
> > +    app.add_source_suffix('.yaml', 'yaml')
> > +    app.add_source_suffix('.yml', 'yaml')  
> 
> No need to support the .yml extension.

Ok.

> > +
> > +    return {
> > +        'version': '1.0',
> > +        'parallel_read_safe': True,
> > +        'parallel_write_safe': True,
> > +    }  

Thanks,
Mauro
Re: [PATCH v2 09/12] docs: sphinx: add a parser template for yaml files
Posted by Mauro Carvalho Chehab 3 months, 4 weeks ago
Em Fri, 13 Jun 2025 14:26:44 +0200
Mauro Carvalho Chehab <mchehab+huawei@kernel.org> escreveu:

> > > +
> > > +    supported = ('yaml', 'yml')    
> > 
> > I don't think we need to support the .yml extension.  
> 
> Ok, will drop "yml".

"supported" is not just extensions. It is a list of aliases for the
supported standard (*), like:

    supported = ('rst', 'restructuredtext', 'rest', 'restx', 'rtxt', 'rstx')
    """Aliases this parser supports."""

    (*) see: https://www.sphinx-doc.org/en/master/_modules/docutils/parsers/rst.html

Anyway, I tried with:

	supported = ('yaml')    

but it crashed with:

	sphinx.errors.SphinxError: Source parser for yaml not registered

On my tests, if "supported" set has just one element, it crashes.

On this specific case, this, for instance, works:

    supported = ('yaml', 'foobar')

Anyway, not worth spending too much time on it, as it could be
a bug or a feature at either docutils or sphinx. As we want it to
work with existing versions, I'll keep it as:

	supported = ('yaml', 'yml')    

at the next version.

> > > +def setup(app):
> > > +    """Setup function for the Sphinx extension."""
> > > +
> > > +    # Add YAML parser
> > > +    app.add_source_parser(YamlParser)
> > > +    app.add_source_suffix('.yaml', 'yaml')
> > > +    app.add_source_suffix('.yml', 'yaml')    
> > 
> > No need to support the .yml extension.  

Dropping .yml works here. So, here I'll keep just:

    # Add YAML parser
    app.add_source_parser(YamlParser)
    app.add_source_suffix('.yaml', 'yaml')

Regards,
Mauro