makerst.py: Support split classes XML and use folders and/or single files as input

The new syntax is (from `doc/`): `tools/makerst.py classes/ ../modules/`.
Also adapted `make rst` target accordingly.

[ci skip]
This commit is contained in:
Alexander Meerhoff 2017-09-22 16:55:48 +02:00 committed by Rémi Verschelde
parent a42fbfc426
commit a11a9ddffc
2 changed files with 31 additions and 25 deletions

View file

@ -1,5 +1,5 @@
BASEDIR = $(CURDIR) BASEDIR = $(CURDIR)
CLASSES = $(BASEDIR)/base/classes.xml CLASSES = $(BASEDIR)/classes/ $(BASEDIR)/../modules/
OUTPUTDIR = $(BASEDIR)/_build OUTPUTDIR = $(BASEDIR)/_build
TOOLSDIR = $(BASEDIR)/tools TOOLSDIR = $(BASEDIR)/tools

View file

@ -3,15 +3,19 @@
import codecs import codecs
import sys import sys
import os
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
input_list = [] input_list = []
for arg in sys.argv[1:]: for arg in sys.argv[1:]:
if arg.endswith(os.sep):
arg = arg[:-1]
input_list.append(arg) input_list.append(arg)
if len(input_list) < 1: if len(input_list) < 1:
print 'usage: makerst.py <classes.xml>' print 'usage: makerst.py <path to folders> and/or <path to .xml files> (order of arguments irrelevant)'
print 'example: makerst.py "../../modules/" "../classes" path_to/some_class.xml'
sys.exit(0) sys.exit(0)
@ -34,7 +38,6 @@ def ul_string(str, ul):
def make_class_list(class_list, columns): def make_class_list(class_list, columns):
f = codecs.open('class_list.rst', 'wb', 'utf-8') f = codecs.open('class_list.rst', 'wb', 'utf-8')
prev = 0 prev = 0
col_max = len(class_list) / columns + 1 col_max = len(class_list) / columns + 1
@ -102,7 +105,6 @@ def make_class_list(class_list, columns):
def rstize_text(text, cclass): def rstize_text(text, cclass):
# Linebreak + tabs in the XML should become two line breaks unless in a "codeblock" # Linebreak + tabs in the XML should become two line breaks unless in a "codeblock"
pos = 0 pos = 0
while True: while True:
@ -250,9 +252,6 @@ def rstize_text(text, cclass):
text = pre_text + tag_text + post_text text = pre_text + tag_text + post_text
pos = len(pre_text) + len(tag_text) pos = len(pre_text) + len(tag_text)
# tnode = ET.SubElement(parent,"div")
# tnode.text=text
return text return text
@ -272,7 +271,6 @@ def make_method(
event=False, event=False,
pp=None pp=None
): ):
if (declare or pp == None): if (declare or pp == None):
t = '- ' t = '- '
else: else:
@ -340,7 +338,6 @@ def make_method(
if 'qualifiers' in m.attrib: if 'qualifiers' in m.attrib:
s += ' ' + m.attrib['qualifiers'] s += ' ' + m.attrib['qualifiers']
# f.write(s)
if (not declare): if (not declare):
if (pp != None): if (pp != None):
pp.append((t, s)) pp.append((t, s))
@ -355,24 +352,23 @@ def make_heading(title, underline):
def make_rst_class(node): def make_rst_class(node):
name = node.attrib['name'] name = node.attrib['name']
f = codecs.open("class_" + name.lower() + '.rst', 'wb', 'utf-8') f = codecs.open("class_" + name.lower() + '.rst', 'wb', 'utf-8')
# Warn contributors not to edit this file directly # Warn contributors not to edit this file directly
f.write(".. Generated automatically by doc/tools/makerst.py in Godot's source tree.\n") f.write(".. Generated automatically by doc/tools/makerst.py in Godot's source tree.\n")
f.write(".. DO NOT EDIT THIS FILE, but the doc/base/classes.xml source instead.\n\n") f.write(".. DO NOT EDIT THIS FILE, but the " + name + ".xml source instead.\n")
f.write(".. The source is found in doc/classes or modules/<name>/doc_classes.\n\n")
f.write(".. _class_" + name + ":\n\n") f.write(".. _class_" + name + ":\n\n")
f.write(make_heading(name, '=')) f.write(make_heading(name, '='))
if 'inherits' in node.attrib: if 'inherits' in node.attrib:
inh = node.attrib['inherits'].strip() inh = node.attrib['inherits'].strip()
# whle inh in classes[cn]
f.write('**Inherits:** ') f.write('**Inherits:** ')
first = True first = True
while(inh in classes): while (inh in classes):
if (not first): if (not first):
f.write(" **<** ") f.write(" **<** ")
else: else:
@ -436,10 +432,10 @@ def make_rst_class(node):
f.write(sep) f.write(sep)
for s in ml: for s in ml:
rt = s[0] rt = s[0]
while(len(rt) < longest_s): while (len(rt) < longest_s):
rt += " " rt += " "
st = s[1] st = s[1]
while(len(st) < longest_t): while (len(st) < longest_t):
st += " " st += " "
f.write("| " + rt + " | " + st + " |\n") f.write("| " + rt + " | " + st + " |\n")
f.write(sep) f.write(sep)
@ -494,8 +490,6 @@ def make_rst_class(node):
f.write(make_heading('Member Function Description', '-')) f.write(make_heading('Member Function Description', '-'))
for m in list(methods): for m in list(methods):
f.write(".. _class_" + name + "_" + m.attrib['name'] + ":\n\n") f.write(".. _class_" + name + "_" + m.attrib['name'] + ":\n\n")
# f.write(ul_string(m.attrib['name'],"^"))
#f.write('\n<a name="'+m.attrib['name']+'">' + m.attrib['name'] + '</a>\n------\n')
make_method(f, node.attrib['name'], m, True, name) make_method(f, node.attrib['name'], m, True, name)
f.write('\n') f.write('\n')
d = m.find('description') d = m.find('description')
@ -506,7 +500,21 @@ def make_rst_class(node):
f.write('\n') f.write('\n')
for file in input_list: file_list = []
for path in input_list:
if os.path.basename(path) == 'modules':
for subdir, dirs, _ in os.walk(path):
if 'doc_classes' in dirs:
doc_dir = os.path.join(subdir, 'doc_classes')
class_file_name = [f for f in os.listdir(doc_dir) if f.endswith('.xml')][0]
file_list.append(os.path.join(doc_dir, class_file_name))
elif not os.path.isfile(path):
file_list += [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.xml')]
elif os.path.isfile(path) and path.endswith('.xml'):
file_list.append(path)
for file in file_list:
tree = ET.parse(file) tree = ET.parse(file)
doc = tree.getroot() doc = tree.getroot()
@ -515,17 +523,15 @@ for file in input_list:
sys.exit(255) sys.exit(255)
version = doc.attrib['version'] version = doc.attrib['version']
if doc.attrib['name'] in class_names:
for c in list(doc): continue
if c.attrib['name'] in class_names: class_names.append(doc.attrib['name'])
continue classes[doc.attrib['name']] = doc
class_names.append(c.attrib['name'])
classes[c.attrib['name']] = c
class_names.sort() class_names.sort()
# Don't make class list for Sphinx, :toctree: handles it # Don't make class list for Sphinx, :toctree: handles it
#make_class_list(class_names, 2) # make_class_list(class_names, 2)
for cn in class_names: for cn in class_names:
c = classes[cn] c = classes[cn]