File xml_parser.py¶
File List > mkdoxy > xml_parser.py
Go to the documentation of this file
from xml.etree.ElementTree import Element as Element
from mkdoxy.cache import Cache
from mkdoxy.markdown import (
Br,
Code,
Md,
MdBlockQuote,
MdBold,
MdCodeBlock,
MdHeader,
MdImage,
MdItalic,
MdLink,
MdList,
MdParagraph,
MdRenderer,
MdTable,
MdTableCell,
MdTableRow,
Text,
)
from mkdoxy.utils import lookahead
# https://www.doxygen.nl/manual/commands.html
SIMPLE_SECTIONS = {
"see": "See also:",
"note": "Note:",
"bug": "Bug:",
"warning": "Warning:",
"return": "Returns:",
"returns": "Returns:",
"param": "Parameters:",
"templateparam": "Template parameters:",
"retval": "Return value:",
"author": "Author:",
"authors": "Authors:",
"since": "Since:",
"pre": "Precondition:",
"remark": "Remark:",
"copyright": "Copyright:",
"post": "Postcondition:",
"rcs": "Rcs:",
"attention": "Attention:",
"invariant": "Invariant:",
"exception": "Exception:",
"date": "Date:",
"version": "Version:",
"par": "\r\n",
}
class XmlParser:
def __init__(self, cache: Cache, debug: bool = False):
self.cachecache = cache
self.debugdebug = debug
def anchor(self, name: str) -> str:
return f'<a name="{name}"></a>'
def paras_as_str(self, p: Element, italic: bool = False, plain: bool = False) -> str:
if plain:
return self.plain_as_strplain_as_str(p)
renderer = MdRenderer()
for m in self.parasparas(p, italic=italic):
m.render(renderer, "")
return renderer.output
def reference_as_str(self, p: Element) -> str:
renderer = MdRenderer()
refid = p.get("refid")
if refid is None:
return p.text
m = MdLink([MdBold([Text(p.text)])], refid)
m.render(renderer, "")
return renderer.output
def programlisting_as_str(self, p: Element) -> str:
renderer = MdRenderer()
for m in self.programlistingprogramlisting(p):
m.render(renderer, "")
return renderer.output
def plain_as_str(self, p: Element) -> str:
return " ".join(self.plainplain(p)).strip()
def plain(self, p: Element) -> [str]:
ret = []
if p is None:
return ret
if p.text:
ret.append(p.text.strip())
for item in list(p):
ret.extend(self.plainplain(item))
if p.tail:
ret.append(p.tail.strip())
return ret
def programlisting(self, p: Element) -> [Md]:
ret = []
# programlisting
if p.tag == "programlisting":
code = MdCodeBlock([])
for codeline in p.findall("codeline"):
line = ""
for highlight in codeline.findall("highlight"):
if highlight.text is not None:
line += highlight.text
for c in list(highlight):
if c.tag == "sp":
line += " "
if c.text:
line += c.text
if c.tail:
line += c.tail
code.append(line)
ret.extend((Text("\n"), code))
return ret
def paras(self, p: Element, italic: bool = False) -> [Md]:
ret = []
if p is None:
return ret
if p.text:
if italic:
ret.extend((MdItalic([Text(p.text.strip())]), Text(" ")))
else:
ret.append(Text(p.text))
for item in list(p):
# para
if item.tag == "para":
ret.extend((MdParagraph(self.parasparas(item)), Text("\n")))
elif item.tag == "image":
url = item.get("name")
ret.append(MdImage(url))
elif item.tag == "computeroutput":
text = []
if item.text:
text.append(item.text)
for i in list(item):
text.extend(self.plainplain(i))
ret.append(Code(" ".join(text)))
elif item.tag == "programlisting":
ret.extend(self.programlistingprogramlisting(item))
elif item.tag == "table":
t = MdTable()
for row in item.findall("row"):
r = MdTableRow([])
for cell in row.findall("entry"):
for para in cell.findall("para"):
r.append(MdTableCell(self.parasparas(para)))
t.append(r)
ret.append(t)
elif item.tag == "blockquote":
b = MdBlockQuote([])
for para in item.findall("para"):
b.extend(self.parasparas(para))
ret.append(b)
elif item.tag == "heading":
ret.append(MdHeader(int(item.get("level")), self.parasparas(item)))
elif item.tag in ["orderedlist", "itemizedlist"]:
lst = MdList([])
for listitem in item.findall("listitem"):
i = MdParagraph([])
for para in listitem.findall("para"):
i.extend(self.parasparas(para))
lst.append(i)
ret.append(lst)
elif item.tag == "ref":
refid = item.get("refid")
try:
ref = self.cachecache.get(refid)
if italic:
if item.text:
ret.append(MdLink([MdItalic([MdBold([Text(item.text)])])], ref.url))
else:
ret.append(
MdLink(
[MdItalic([MdBold([Text(ref.get_full_name())])])],
ref.url,
)
)
elif item.text:
ret.append(MdLink([MdBold([Text(item.text)])], ref.url))
else:
ret.append(MdLink([MdBold([Text(ref.get_full_name())])], ref.url))
except Exception:
if item.text:
ret.append(Text(item.text))
elif item.tag == "sect1":
title = item.find("title").text
ret.append(MdHeader(2, [Text(title)]))
ret.extend(self.parasparas(item))
elif item.tag == "sect2":
title = item.find("title").text
ret.append(MdHeader(3, [Text(title)]))
ret.extend(self.parasparas(item))
elif item.tag == "sect3":
title = item.find("title").text
ret.append(MdHeader(4, [Text(title)]))
ret.extend(self.parasparas(item))
elif item.tag == "sect4":
title = item.find("title").text
ret.append(MdHeader(5, [Text(title)]))
ret.extend(self.parasparas(item))
elif item.tag == "sect5":
title = item.find("title").text
ret.append(MdHeader(6, [Text(title)]))
ret.extend(self.parasparas(item))
elif item.tag == "variablelist":
varlistentry = item.find("varlistentry")
ret.append(MdHeader(4, self.parasparas(varlistentry.find("term"))))
varlistentry.find("term")
for listitem in item.findall("listitem"):
ret.extend(MdParagraph(self.parasparas(para)) for para in listitem.findall("para"))
elif item.tag == "parameterlist":
parameteritems = item.findall("parameteritem")
lst = MdList([])
for parameteritem in parameteritems:
name = parameteritem.find("parameternamelist").find("parametername")
description = parameteritem.find("parameterdescription").findall("para")
par = MdParagraph([])
if name is not None and len(name) > 0:
par.extend(self.parasparas(name))
else:
par.append(Code(name.text))
par.append(Text(" "))
for ip in description:
par.extend(self.parasparas(ip))
lst.append(par)
ret.extend((Br(), MdBold([Text(SIMPLE_SECTIONS[item.get("kind")])]), Br(), lst))
elif item.tag == "simplesect":
kind = item.get("kind")
ret.extend((Br(), MdBold([Text(SIMPLE_SECTIONS[kind])])))
if kind != "see":
ret.append(Br())
else:
ret.append(Text(" "))
for sp, has_more in lookahead(item.findall("para")):
ret.extend(self.parasparas(sp))
if kind == "see":
if has_more:
ret.append(Text(", "))
else:
ret.append(Br())
elif item.tag == "xrefsect":
xreftitle = item.find("xreftitle")
xrefdescription = item.find("xrefdescription")
kind = xreftitle.text.lower()
ret.extend((Br(), MdBold(self.parasparas(xreftitle)), Br()))
for sp in xrefdescription.findall("para"):
ret.extend(self.parasparas(sp))
ret.append(Br())
elif item.tag == "ulink":
ret.append(MdLink(self.parasparas(item), item.get("url")))
elif item.tag == "bold":
ret.append(MdBold(self.parasparas(item)))
elif item.tag == "emphasis":
ret.append(MdItalic(self.parasparas(item)))
if item.tail:
if italic:
ret.extend((Text(" "), MdItalic([Text(item.tail.strip())])))
else:
ret.append(Text(item.tail))
return ret