From a11a9ddffc4dcda6c5c912373f8ec6f7a0f63cca Mon Sep 17 00:00:00 2001 From: Alexander Meerhoff Date: Fri, 22 Sep 2017 16:55:48 +0200 Subject: [PATCH] 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] --- doc/Makefile | 2 +- doc/tools/makerst.py | 54 ++++++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 4914c657d2e..d68c66f8eb5 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,5 +1,5 @@ BASEDIR = $(CURDIR) -CLASSES = $(BASEDIR)/base/classes.xml +CLASSES = $(BASEDIR)/classes/ $(BASEDIR)/../modules/ OUTPUTDIR = $(BASEDIR)/_build TOOLSDIR = $(BASEDIR)/tools diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index 696e3c9c787..c4dff588b02 100644 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -3,15 +3,19 @@ import codecs import sys +import os import xml.etree.ElementTree as ET input_list = [] for arg in sys.argv[1:]: + if arg.endswith(os.sep): + arg = arg[:-1] input_list.append(arg) if len(input_list) < 1: - print 'usage: makerst.py ' + print 'usage: makerst.py and/or (order of arguments irrelevant)' + print 'example: makerst.py "../../modules/" "../classes" path_to/some_class.xml' sys.exit(0) @@ -34,7 +38,6 @@ def ul_string(str, ul): def make_class_list(class_list, columns): - f = codecs.open('class_list.rst', 'wb', 'utf-8') prev = 0 col_max = len(class_list) / columns + 1 @@ -102,7 +105,6 @@ def make_class_list(class_list, columns): def rstize_text(text, cclass): - # Linebreak + tabs in the XML should become two line breaks unless in a "codeblock" pos = 0 while True: @@ -250,9 +252,6 @@ def rstize_text(text, cclass): text = pre_text + tag_text + post_text pos = len(pre_text) + len(tag_text) - # tnode = ET.SubElement(parent,"div") - # tnode.text=text - return text @@ -272,7 +271,6 @@ def make_method( event=False, pp=None ): - if (declare or pp == None): t = '- ' else: @@ -340,7 +338,6 @@ def make_method( if 'qualifiers' in m.attrib: s += ' ' + m.attrib['qualifiers'] -# f.write(s) if (not declare): if (pp != None): pp.append((t, s)) @@ -355,24 +352,23 @@ def make_heading(title, underline): def make_rst_class(node): - name = node.attrib['name'] f = codecs.open("class_" + name.lower() + '.rst', 'wb', 'utf-8') # 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(".. 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//doc_classes.\n\n") f.write(".. _class_" + name + ":\n\n") f.write(make_heading(name, '=')) if 'inherits' in node.attrib: inh = node.attrib['inherits'].strip() -# whle inh in classes[cn] f.write('**Inherits:** ') first = True - while(inh in classes): + while (inh in classes): if (not first): f.write(" **<** ") else: @@ -436,10 +432,10 @@ def make_rst_class(node): f.write(sep) for s in ml: rt = s[0] - while(len(rt) < longest_s): + while (len(rt) < longest_s): rt += " " st = s[1] - while(len(st) < longest_t): + while (len(st) < longest_t): st += " " f.write("| " + rt + " | " + st + " |\n") f.write(sep) @@ -494,8 +490,6 @@ def make_rst_class(node): f.write(make_heading('Member Function Description', '-')) for m in list(methods): f.write(".. _class_" + name + "_" + m.attrib['name'] + ":\n\n") -# f.write(ul_string(m.attrib['name'],"^")) - #f.write('\n' + m.attrib['name'] + '\n------\n') make_method(f, node.attrib['name'], m, True, name) f.write('\n') d = m.find('description') @@ -506,7 +500,21 @@ def make_rst_class(node): 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) doc = tree.getroot() @@ -515,17 +523,15 @@ for file in input_list: sys.exit(255) version = doc.attrib['version'] - - for c in list(doc): - if c.attrib['name'] in class_names: - continue - class_names.append(c.attrib['name']) - classes[c.attrib['name']] = c + if doc.attrib['name'] in class_names: + continue + class_names.append(doc.attrib['name']) + classes[doc.attrib['name']] = doc class_names.sort() # 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: c = classes[cn]