doc: Add autogenerated qubes.xml documentation
This commit is contained in:
parent
6df316378b
commit
42d8e67556
2
doc/.gitignore
vendored
2
doc/.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
|
_build
|
||||||
sandbox.rst
|
sandbox.rst
|
||||||
|
autoxml.rst
|
||||||
|
45
doc/Makefile
45
doc/Makefile
@ -14,6 +14,8 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|||||||
# the i18n builder cannot share the environment and doctrees with the others
|
# the i18n builder cannot share the environment and doctrees with the others
|
||||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||||
|
|
||||||
|
DEPEND = autoxml.rst
|
||||||
|
|
||||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@ -41,40 +43,40 @@ help:
|
|||||||
@echo " install to generate manpages and copy them to \$$(DESTDIR)/usr/share/man"
|
@echo " install to generate manpages and copy them to \$$(DESTDIR)/usr/share/man"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -rf $(BUILDDIR)/*
|
-rm -rf $(BUILDDIR)/* $(DEPEND)
|
||||||
|
|
||||||
html:
|
html: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||||
|
|
||||||
dirhtml:
|
dirhtml: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||||
|
|
||||||
singlehtml:
|
singlehtml: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||||
|
|
||||||
pickle:
|
pickle: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished; now you can process the pickle files."
|
@echo "Build finished; now you can process the pickle files."
|
||||||
|
|
||||||
json:
|
json: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished; now you can process the JSON files."
|
@echo "Build finished; now you can process the JSON files."
|
||||||
|
|
||||||
htmlhelp:
|
htmlhelp: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||||
|
|
||||||
qthelp:
|
qthelp: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||||
@ -83,7 +85,7 @@ qthelp:
|
|||||||
@echo "To view the help file:"
|
@echo "To view the help file:"
|
||||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/core-admin.qhc"
|
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/core-admin.qhc"
|
||||||
|
|
||||||
devhelp:
|
devhelp: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished."
|
@echo "Build finished."
|
||||||
@ -92,30 +94,30 @@ devhelp:
|
|||||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/core-admin"
|
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/core-admin"
|
||||||
@echo "# devhelp"
|
@echo "# devhelp"
|
||||||
|
|
||||||
epub:
|
epub: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||||
|
|
||||||
latex:
|
latex: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||||
"(use \`make latexpdf' here to do that automatically)."
|
"(use \`make latexpdf' here to do that automatically)."
|
||||||
|
|
||||||
latexpdf:
|
latexpdf: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
@echo "Running LaTeX files through pdflatex..."
|
@echo "Running LaTeX files through pdflatex..."
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||||
|
|
||||||
text:
|
text: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||||
|
|
||||||
man:
|
man: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||||
for file in $(BUILDDIR)/man/*.[12345678]; do \
|
for file in $(BUILDDIR)/man/*.[12345678]; do \
|
||||||
gzip -f $$file; \
|
gzip -f $$file; \
|
||||||
@ -123,41 +125,44 @@ man:
|
|||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||||
|
|
||||||
texinfo:
|
texinfo: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||||
"(use \`make info' here to do that automatically)."
|
"(use \`make info' here to do that automatically)."
|
||||||
|
|
||||||
info:
|
info: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||||
@echo "Running Texinfo files through makeinfo..."
|
@echo "Running Texinfo files through makeinfo..."
|
||||||
make -C $(BUILDDIR)/texinfo info
|
make -C $(BUILDDIR)/texinfo info
|
||||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||||
|
|
||||||
gettext:
|
gettext: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||||
|
|
||||||
changes:
|
changes: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||||
@echo
|
@echo
|
||||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||||
|
|
||||||
linkcheck:
|
linkcheck: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||||
@echo
|
@echo
|
||||||
@echo "Link check complete; look for any errors in the above output " \
|
@echo "Link check complete; look for any errors in the above output " \
|
||||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||||
|
|
||||||
doctest:
|
doctest: $(DEPEND)
|
||||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||||
@echo "Testing of doctests in the sources finished, look at the " \
|
@echo "Testing of doctests in the sources finished, look at the " \
|
||||||
"results in $(BUILDDIR)/doctest/output.txt."
|
"results in $(BUILDDIR)/doctest/output.txt."
|
||||||
|
|
||||||
|
|
||||||
|
autoxml.rst: ../relaxng/qubes.rng example.xml
|
||||||
|
../qubes/rngdoc.py $+ > $@
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: man
|
install: man
|
||||||
mkdir -p $(DESTDIR)/usr/share/man/man1
|
mkdir -p $(DESTDIR)/usr/share/man/man1
|
||||||
|
45
doc/example.xml
Normal file
45
doc/example.xml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<qubes version="3.0">
|
||||||
|
<properties>
|
||||||
|
<property name="default_netvm" ref="domain-1" />
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<labels>
|
||||||
|
<label id="label-1" color="#cc0000">red</label>
|
||||||
|
</labels>
|
||||||
|
|
||||||
|
<domains>
|
||||||
|
<domain class="QubesVM" id="domain-1">
|
||||||
|
<properties>
|
||||||
|
<property name="qid">1</property>
|
||||||
|
<property name="name">netvm</property>
|
||||||
|
<property name="label" ref="label-1" />
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<services>
|
||||||
|
<service enabled="false">meminfo-writer</service>
|
||||||
|
<service>qubes-firewall</service>
|
||||||
|
</services>
|
||||||
|
|
||||||
|
<devices class="pci">
|
||||||
|
<device>01:23.45</device>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
||||||
|
|
||||||
|
<domain class="QubesVM" id="domain-2">
|
||||||
|
<properties>
|
||||||
|
<property name="qid">2</property>
|
||||||
|
<property name="name">appvm</property>
|
||||||
|
<property name="label" ref="label-1" />
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<tags>
|
||||||
|
<tag name="userdef">qwe123</tag>
|
||||||
|
</tags>
|
||||||
|
</domain>
|
||||||
|
</domains>
|
||||||
|
</qubes>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
vim: ts=4 sw=4 et
|
||||||
|
-->
|
@ -35,6 +35,11 @@ Developer documentation
|
|||||||
qubes-tests
|
qubes-tests
|
||||||
qubes-dochelpers
|
qubes-dochelpers
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
autoxml
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
182
qubes/rngdoc.py
Executable file
182
qubes/rngdoc.py
Executable file
@ -0,0 +1,182 @@
|
|||||||
|
#!/usr/bin/python2 -O
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
import lxml.etree
|
||||||
|
|
||||||
|
class Element(object):
|
||||||
|
def __init__(self, schema, xml):
|
||||||
|
self.schema = schema
|
||||||
|
self.xml = xml
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def nsmap(self):
|
||||||
|
return self.schema.nsmap
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self.xml.get('name')
|
||||||
|
|
||||||
|
|
||||||
|
def get_description(self, xml=None, wrap=True):
|
||||||
|
if xml is None: xml = self.xml
|
||||||
|
|
||||||
|
xml = xml.xpath('./doc:description', namespaces=self.nsmap)
|
||||||
|
if not xml: return ''
|
||||||
|
xml = xml[0]
|
||||||
|
|
||||||
|
if wrap:
|
||||||
|
return ''.join(self.schema.wrapper.fill(p) + '\n\n'
|
||||||
|
for p in textwrap.dedent(xml.text.strip('\n')).split('\n\n'))
|
||||||
|
else:
|
||||||
|
return ' '.join(xml.text.strip().split())
|
||||||
|
|
||||||
|
|
||||||
|
def get_data_type(self, xml=None):
|
||||||
|
if xml is None: xml = self.xml
|
||||||
|
|
||||||
|
value = xml.xpath('./rng:value', namespaces=self.nsmap)
|
||||||
|
if value:
|
||||||
|
value = '``{}``'.format(value[0].text.strip())
|
||||||
|
else:
|
||||||
|
metavar = xml.xpath('./doc:metavar', namespaces=self.nsmap)
|
||||||
|
if metavar:
|
||||||
|
value = '``{}``'.format(metavar[0].text.strip())
|
||||||
|
else:
|
||||||
|
value = ''
|
||||||
|
|
||||||
|
xml = xml.xpath('./rng:data', namespaces=self.nsmap)
|
||||||
|
if not xml:
|
||||||
|
return ('', value)
|
||||||
|
|
||||||
|
xml = xml[0]
|
||||||
|
type_ = xml.get('type', '')
|
||||||
|
|
||||||
|
if not value:
|
||||||
|
pattern = xml.xpath('./rng:param[@name="pattern"]',
|
||||||
|
namespaces=self.nsmap)
|
||||||
|
if pattern:
|
||||||
|
value = '``{}``'.format(pattern[0].text.strip())
|
||||||
|
|
||||||
|
return type_, value
|
||||||
|
|
||||||
|
|
||||||
|
def get_attributes(self):
|
||||||
|
for xml in self.xml.xpath('''./rng:attribute |
|
||||||
|
./rng:optional/rng:attribute |
|
||||||
|
./rng:choice/rng:attribute''', namespaces=self.nsmap):
|
||||||
|
required = xml.getparent() == self.xml and 'yes' or 'no'
|
||||||
|
yield (xml, required)
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_ref(self, ref):
|
||||||
|
refs = self.xml.xpath('//rng:define[name="{}"]/rng:element'.format(ref['name']))
|
||||||
|
return refs[0] if refs else None
|
||||||
|
|
||||||
|
|
||||||
|
def get_child_elements(self):
|
||||||
|
for xml in self.xml.xpath('''./rng:element | ./rng:ref |
|
||||||
|
./rng:optional/rng:element | ./rng:optional/rng:ref |
|
||||||
|
./rng:zeroOrMore/rng:element | ./rng:zeroOrMore/rng:ref |
|
||||||
|
./rng:oneOrMore/rng:element | ./rng:oneOrMore/rng:ref''', namespaces=self.nsmap):
|
||||||
|
parent = xml.getparent()
|
||||||
|
qname = lxml.etree.QName(parent)
|
||||||
|
if parent == self.xml:
|
||||||
|
n = '1'
|
||||||
|
elif qname.localname == 'optional':
|
||||||
|
n = '?'
|
||||||
|
elif qname.localname == 'zeroOrMore':
|
||||||
|
n = '\\*'
|
||||||
|
elif qname.localname == 'oneOrMore':
|
||||||
|
n = '\\+'
|
||||||
|
else:
|
||||||
|
print(parent.tag)
|
||||||
|
|
||||||
|
if xml.tag == 'ref':
|
||||||
|
xml = self.resolve_ref(xml)
|
||||||
|
if xml is None: continue
|
||||||
|
|
||||||
|
yield (self.schema.elements[xml.get('name')], n)
|
||||||
|
|
||||||
|
|
||||||
|
def write_rst(self, stream):
|
||||||
|
stream.write('.. _qubesxml-element-{}:\n\n'.format(self.name))
|
||||||
|
stream.write(make_rst_section('Element: **{}**'.format(self.name), '-'))
|
||||||
|
stream.write(self.get_description())
|
||||||
|
|
||||||
|
attrtable = []
|
||||||
|
for attr, required in self.get_attributes():
|
||||||
|
type_, value = self.get_data_type(attr)
|
||||||
|
attrtable.append((
|
||||||
|
attr.get('name'),
|
||||||
|
required,
|
||||||
|
type_,
|
||||||
|
value,
|
||||||
|
self.get_description(attr, wrap=False)))
|
||||||
|
|
||||||
|
if attrtable:
|
||||||
|
stream.write(make_rst_section('Attributes', '^'))
|
||||||
|
write_rst_table(stream, attrtable,
|
||||||
|
('attribute', 'req.', 'type', 'value', 'description'))
|
||||||
|
|
||||||
|
childtable = [(':ref:`{0} <qubesxml-element-{0}>`'.format(child.xml.get('name')), n)
|
||||||
|
for child, n in self.get_child_elements()]
|
||||||
|
if childtable:
|
||||||
|
stream.write(make_rst_section('Child elements', '^'))
|
||||||
|
write_rst_table(stream, childtable, ('element', 'n'))
|
||||||
|
|
||||||
|
|
||||||
|
class Schema(object):
|
||||||
|
nsmap = {
|
||||||
|
'rng': 'http://relaxng.org/ns/structure/1.0',
|
||||||
|
'q': 'http://qubes-os.org/qubes/3',
|
||||||
|
'doc': 'http://qubes-os.org/qubes-doc/1'}
|
||||||
|
|
||||||
|
def __init__(self, xml):
|
||||||
|
self.xml = xml
|
||||||
|
|
||||||
|
self.wrapper = textwrap.TextWrapper(width=80,
|
||||||
|
break_long_words=False, break_on_hyphens=False)
|
||||||
|
|
||||||
|
self.elements = {}
|
||||||
|
for x in self.xml.xpath('//rng:element', namespaces=self.nsmap):
|
||||||
|
element = Element(self, x)
|
||||||
|
self.elements[element.name] = element
|
||||||
|
|
||||||
|
|
||||||
|
def make_rst_section(heading, c):
|
||||||
|
return '{}\n{}\n\n'.format(heading, c[0] * len(heading))
|
||||||
|
|
||||||
|
|
||||||
|
def write_rst_table(stream, it, heads):
|
||||||
|
stream.write('.. csv-table::\n')
|
||||||
|
stream.write(' :header: {}\n'.format(', '.join('"{}"'.format(c) for c in heads)))
|
||||||
|
stream.write(' :widths: {}\n\n'.format(', '.join('1' for c in heads)))
|
||||||
|
|
||||||
|
for row in it:
|
||||||
|
stream.write(' {}\n'.format(', '.join('"{}"'.format(i) for i in row)))
|
||||||
|
|
||||||
|
stream.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
def main(filename, example):
|
||||||
|
schema = Schema(lxml.etree.parse(open(filename, 'rb')))
|
||||||
|
|
||||||
|
sys.stdout.write(make_rst_section('Qubes XML specification', '='))
|
||||||
|
sys.stdout.write('This is the documentation of qubes.xml autogenerated from RelaxNG source.\n\n')
|
||||||
|
sys.stdout.write('Quick example, worth thousands lines of specification:\n\n')
|
||||||
|
sys.stdout.write('.. literalinclude:: {}\n :language: xml\n\n'.format(example))
|
||||||
|
|
||||||
|
for name in sorted(schema.elements):
|
||||||
|
schema.elements[name].write_rst(sys.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(*sys.argv[1:])
|
||||||
|
|
||||||
|
# vim: ts=4 sw=4 et
|
@ -320,4 +320,7 @@ class TC_30_VMCollection(qubes.tests.QubesTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TC_90_Qubes(qubes.tests.QubesTestCase):
|
class TC_90_Qubes(qubes.tests.QubesTestCase):
|
||||||
pass
|
def test_900_example_xml_in_doc(self):
|
||||||
|
self.assertXMLIsValid(
|
||||||
|
lxml.etree.parse(open('../../doc/example.xml', 'rb')),
|
||||||
|
'../../relaxng/qubes.rng')
|
||||||
|
@ -170,9 +170,6 @@ the parser will complain about missing combine= attribute on the second <start>.
|
|||||||
Whether service is enabled or disabled.
|
Whether service is enabled or disabled.
|
||||||
Default is ``true``.
|
Default is ``true``.
|
||||||
</doc:description>
|
</doc:description>
|
||||||
<doc:metavar>
|
|
||||||
true|false
|
|
||||||
</doc:metavar>
|
|
||||||
|
|
||||||
<data type="boolean" />
|
<data type="boolean" />
|
||||||
</attribute>
|
</attribute>
|
||||||
|
Loading…
Reference in New Issue
Block a user