mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-09 14:18:00 +08:00
[doc] Add parser for modules doc generation. (#2973)
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
|
||||
Boards
|
||||
======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
./*
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
Firmwares
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
./*
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
Modules
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
boards/index
|
||||
firmwares/index.rst
|
||||
targets/index.rst
|
||||
./*
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
Targets
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
./*
|
||||
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE module SYSTEM "module.dtd">
|
||||
|
||||
<module name="time_countdown" dir="time">
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
import sys
|
||||
sys.path.insert(0, "../../sw/tools/modules_doc")
|
||||
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
@@ -35,6 +37,7 @@ extensions = [
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinx.ext.githubpages',
|
||||
'modules_parser',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
|
||||
@@ -33,6 +33,7 @@ Contents:
|
||||
developer_guide/index_developer
|
||||
tutorials/index_tutorials
|
||||
support/index_support
|
||||
modules/index.rst
|
||||
|
||||
--------------
|
||||
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../../conf/modules/
|
||||
@@ -0,0 +1,157 @@
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.parsers import Parser
|
||||
from typing import Dict, Any, List
|
||||
from sphinx import addnodes, errors
|
||||
from sphinx.parsers import RSTParser
|
||||
from docutils import nodes
|
||||
from lxml import etree as ET
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
class Define:
|
||||
def __init__(self, xml: ET._Element):
|
||||
self.name = xml.attrib["name"]
|
||||
self.value = xml.get("value", "")
|
||||
self.description = xml.get("description", "")
|
||||
|
||||
|
||||
class Section:
|
||||
def __init__(self, xml: ET._Element):
|
||||
self.name = xml.attrib["name"]
|
||||
self.prefix = xml.attrib.get("prefix")
|
||||
self.defines = [Define(x) for x in xml.findall("define")]
|
||||
|
||||
|
||||
class ModuleParser:
|
||||
def __init__(self, inputstring):
|
||||
root = ET.fromstring(inputstring)
|
||||
self.name = root.attrib["name"] # name required
|
||||
# self.dir = root.attrib["dir"] # dir optional!!!
|
||||
edoc = root.find("doc") # doc required
|
||||
self.description = edoc.find("description").text # description required
|
||||
self.configures = [Define(xml) for xml in edoc.findall("configure")]
|
||||
self.defines = [Define(xml) for xml in edoc.findall("define")]
|
||||
self.sections = [Section(xml) for xml in edoc.findall("section")]
|
||||
self.depends = []
|
||||
self.conflicts = []
|
||||
self.provides = []
|
||||
edep = root.find("dep") # type: ET._Element
|
||||
if edep is not None:
|
||||
edepends = edep.find("depends") # type: ET._Element
|
||||
if edepends is not None:
|
||||
self.depends = edepends.text.split(",")
|
||||
eprovides = edep.find("provides")
|
||||
if eprovides is not None:
|
||||
self.provides = eprovides.text.split(",")
|
||||
econflicts = edep.find("conflicts")
|
||||
if econflicts is not None:
|
||||
self.conflicts = econflicts.text.split(",")
|
||||
|
||||
|
||||
class ModuleDoc(Parser):
|
||||
|
||||
supported = ("pprz_module", "xml")
|
||||
|
||||
def make_table_row(self, *args, colwidth=[]):
|
||||
row = nodes.row()
|
||||
for i, arg in enumerate(args):
|
||||
if len(colwidth) > i:
|
||||
entry = nodes.entry(morecols=colwidth[i]-1)
|
||||
else:
|
||||
entry = nodes.entry()
|
||||
entry += nodes.paragraph(text=arg)
|
||||
row += entry
|
||||
return row
|
||||
|
||||
def define_to_table(self, defines, title, section_row=None):
|
||||
t = nodes.table()
|
||||
t += nodes.title(text=title)
|
||||
tgroup = nodes.tgroup(cols=3)
|
||||
for _ in range(3):
|
||||
colspec = nodes.colspec(colwidth=1)
|
||||
tgroup.append(colspec)
|
||||
rows = []
|
||||
|
||||
header_row = self.make_table_row("Name", "Value", "Description")
|
||||
nt = nodes.thead()
|
||||
if section_row is not None:
|
||||
nt += section_row
|
||||
nt += header_row
|
||||
tgroup += nt
|
||||
|
||||
for define in defines:
|
||||
row = self.make_table_row(define.name, define.value, define.description)
|
||||
rows.append(row)
|
||||
tbody = nodes.tbody()
|
||||
tbody.extend(rows)
|
||||
tgroup += tbody
|
||||
t += tgroup
|
||||
return t
|
||||
|
||||
def make_section(self, title):
|
||||
section = nodes.section()
|
||||
section += nodes.title(text=title)
|
||||
section["ids"].append(title)
|
||||
return section
|
||||
|
||||
def make_list(self, args):
|
||||
dl = nodes.bullet_list()
|
||||
for arg in args:
|
||||
item = nodes.list_item()
|
||||
txt = nodes.Text(arg)
|
||||
item += txt
|
||||
dl += item
|
||||
return dl
|
||||
|
||||
def parse(self, inputstring: str, document: addnodes.document):
|
||||
self.setup_parse(inputstring, document)
|
||||
try:
|
||||
m = ModuleParser(inputstring)
|
||||
except:
|
||||
# print(document.source, document.current_source)
|
||||
print(document.reporter.warning("test"))
|
||||
# print(document.transformer)
|
||||
self.finish_parse()
|
||||
return
|
||||
pass
|
||||
|
||||
root = self.make_section(m.name)
|
||||
|
||||
# description
|
||||
root.append(nodes.paragraph(text=m.description))
|
||||
|
||||
if len(m.configures) > 0:
|
||||
root += self.define_to_table(m.configures, "Configures")
|
||||
if len(m.defines) > 0:
|
||||
header_row = self.make_table_row("Defines", colwidth=[3])
|
||||
root += self.define_to_table(m.defines, "Defines")
|
||||
if len(m.sections) > 0:
|
||||
for s in m.sections:
|
||||
header_row = self.make_table_row("{}".format(s.prefix), colwidth=[3])
|
||||
root += self.define_to_table(s.defines, "Section {}".format(s.name), header_row)
|
||||
if len(m.depends) > 0:
|
||||
ds = self.make_section("Depends")
|
||||
ds.append(self.make_list(m.depends))
|
||||
root.append(ds)
|
||||
if len(m.provides) > 0:
|
||||
ds = self.make_section("Provides")
|
||||
ds.append(self.make_list(m.provides))
|
||||
|
||||
root.append(ds)
|
||||
if len(m.conflicts) > 0:
|
||||
ds = self.make_section("Conflicts")
|
||||
ds.append(self.make_list(m.conflicts))
|
||||
root.append(ds)
|
||||
|
||||
if len(m.sections) > 0:
|
||||
ds = self.make_section("Sections")
|
||||
|
||||
root.append(ds)
|
||||
|
||||
document.append(root)
|
||||
self.finish_parse()
|
||||
|
||||
|
||||
def setup(app: "Sphinx") -> Dict[str, Any]:
|
||||
app.add_source_suffix(".xml", "pprz_module")
|
||||
app.add_source_parser(ModuleDoc)
|
||||
Reference in New Issue
Block a user