diff options
Diffstat (limited to 'tools/docdump/makedocs.py')
-rw-r--r-- | tools/docdump/makedocs.py | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/tools/docdump/makedocs.py b/tools/docdump/makedocs.py new file mode 100644 index 0000000000..d11515e94a --- /dev/null +++ b/tools/docdump/makedocs.py @@ -0,0 +1,184 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +# +# makedocs.py: Generate documentation for Open Project Wiki +# +# Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. +# +# Contributor: Jorge Araya Navarro <elcorreo@deshackra.com> +# + +import re +import argparse +import logging +from os import path +from itertools import izip_longest +from xml.etree import ElementTree + +logging.basicConfig(level=logging.INFO) + + +def getxmlfloc(): + """ Returns the supposed location of the XML file + """ + filepath = path.dirname(path.abspath(__file__)) + return path.join(filepath, "class_list.xml") + + +def sortkey(c): + """ Symbols are first, letters second + """ + if "_" == c.attrib["name"][0]: + return True + else: + return c.attrib["name"] + + +def toOP(text): + """ Convert commands in text to Open Project commands + """ + # We are going to do something very complicated with all HTML commands + # sadly, some commands are embedded inside other commands, so some steps + # are needed before converting some commands to Textile markup + groups = re.finditer((r'\[html (?P<command>/?\w+/?)(\]| |=)?(\]| |=)?(?P<a' + 'rg>\w+)?(\]| |=)?(?P<value>"[^"]+")?/?\]'), text) + alignstr = "" + for group in groups: + gd = group.groupdict() + if gd["command"] == "br/": + text = text.replace(group.group(0), "\n\n", 1) + elif gd["command"] == "div": + if gd["value"] == '"center"': + alignstr = "{display:block; margin-left:auto; margin-right:auto;}" + elif gd["value"] == '"left"': + alignstr = "<" + elif gd["value"] == '"right"': + alignstr = ">" + text = text.replace(group.group(0), "\n\n", 1) + elif gd["command"] == "/div": + alignstr = "" + text = text.replace(group.group(0), "\n\n", 1) + elif gd["command"] == "img": + text = text.replace(group.group(0), "!{align}{src}!".format( + align=alignstr, src=gd["value"].strip('"')), 1) + elif gd["command"] == "b" or gd["command"] == "/b": + text = text.replace(group.group(0), "*", 1) + elif gd["command"] == "i" or gd["command"] == "/i": + text = text.replace(group.group(0), "_", 1) + elif gd["command"] == "u" or gd["command"] == "/u": + text = text.replace(group.group(0), "+", 1) + # TODO: Process other non-html commands + return text + "\n\n" + +desc = "Generates documentation from a XML file to different markup languages" + +parser = argparse.ArgumentParser(description=desc) +parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(), + help="Input XML file, default: {}".format(getxmlfloc())) +parser.add_argument("--output-dir", dest="outputdir", required=True, + help="Output directory for generated files") +# TODO: add an option for outputting different markup formats + +args = parser.parse_args() +# Let's check if the file and output directory exists +if not path.isfile(args.xmlfp): + logging.critical("File not found: {}".format(args.xmlfp)) + exit(1) +elif not path.isdir(args.outputdir): + logging.critical("Path does not exist: {}".format(args.outputdir)) + exit(1) + +# Let's begin +tree = ElementTree.parse(args.xmlfp) +root = tree.getroot() + +# Check version attribute exists in <doc> +if "version" not in root.attrib: + logging.critical("<doc>'s version attribute missing") + exit(1) + +version = root.attrib["version"] +classes = sorted(root, key=sortkey) +# first column is always longer, second column of classes should be shorter +zclasses = izip_longest(classes[:len(classes) / 2 + 1], + classes[len(classes) / 2 + 1:], + fillvalue="") + +# We write the class_list file and also each class file at once +with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: + # Write header of table + fcl.write("|^.\n") + fcl.write("|_. Index symbol |_. Class name " + "|_. Index symbol |_. Class name |\n") + fcl.write("|-.\n") + + indexletterl = "" + indexletterr = "" + for gdclassl, gdclassr in zclasses: + # write a row # + # write the index symbol column, left + if indexletterl != gdclassl.attrib["name"][0]: + indexletterl = gdclassl.attrib["name"][0] + fcl.write("| *{}* |".format(indexletterl.upper())) + else: + # empty cell + fcl.write("| |") + # write the class name column, left + fcl.write("\"{name}({title})\":/class_{link}".format( + name=gdclassl.attrib["name"], + title="Go to page of class " + gdclassl.attrib["name"], + link="class_" + gdclassl.attrib["name"].lower())) + + # write the index symbol column, right + if isinstance(gdclassr, ElementTree.Element): + if indexletterr != gdclassr.attrib["name"][0]: + indexletterr = gdclassr.attrib["name"][0] + fcl.write("| *{}* |".format(indexletterr.upper())) + else: + # empty cell + fcl.write("| |") + # We are dealing with an empty string + else: + # two empty cell + fcl.write("| | |\n") + # We won't get the name of the class since there is no ElementTree + # object for the right side of the tuple, so we iterate the next + # tuple instead + continue + + # write the class name column (if any), right + fcl.write("\"{name}({title})\":/{link} |\n".format( + name=gdclassr.attrib["name"], + title="Go to page of class " + gdclassr.attrib["name"], + link=gdclassr.attrib["name"].lower())) + + # row written # + # now, let's write each class page for each class + for gdclass in [gdclassl, gdclassr]: + if not isinstance(ElementTree.Element, gdclass): + continue + + classname = gdclass.attrib["name"] + with open(path.join(args.outputdir, "{}.txt".format( + classname.lower())), "wb") as clsf: + # First level header with the name of the class + clsf.write("h1. {}\n".format(classname)) + # lay the attributes + if "inherits" in gdclass.attrib: + inh = gdclass.attrib["inherits"].strip() + clsf.write( + "*Inherits:* \"{name}({title})\":/class_{link}\n". + format( + name=classname, + title="Go to page of class " + classname, + link=classname.lower())) + if "category" in gdclass.attrib: + clsf.write("*Category:* {}". + format(gdclass.attrib["category"].strip())) + # lay child nodes + for gdchild in gdclass.iter(): + if gdchild.tag == "brief_description": + clsf.write("h2. Brief Description\n") + clsf.write(toOP(gdchild.text.strip())) + # convert commands in text |