summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2015-12-12 23:30:45 +0100
committerRémi Verschelde <rverschelde@gmail.com>2015-12-12 23:30:45 +0100
commitaeb5ea59340f91ae445330c95429f903a8f20e8a (patch)
tree09e0e73b3faedfbbaed8823137a0935c56a61930 /doc
parentfb00cee33bd29969805572238815c0fb3d29ee45 (diff)
Move documentation python tools to doc/tools folder
Diffstat (limited to 'doc')
-rw-r--r--doc/make_doc.sh3
-rw-r--r--doc/tools/doc_merge.py208
-rw-r--r--doc/tools/locales/es/LC_MESSAGES/makedocs.mobin0 -> 2321 bytes
-rw-r--r--doc/tools/locales/es/LC_MESSAGES/makedocs.po142
-rw-r--r--doc/tools/main.css146
-rw-r--r--doc/tools/makedocs.pot108
-rw-r--r--doc/tools/makedocs.py382
-rw-r--r--doc/tools/makedoku.py511
-rw-r--r--doc/tools/makehtml.py717
-rw-r--r--doc/tools/makemd.py345
10 files changed, 2560 insertions, 2 deletions
diff --git a/doc/make_doc.sh b/doc/make_doc.sh
index a76f568bfc..5d0c1a9c2f 100644
--- a/doc/make_doc.sh
+++ b/doc/make_doc.sh
@@ -2,7 +2,6 @@
here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
godotHome=$(dirname "$here")
docTarget=${here}/html/class_list
-toolsRoot=${godotHome}/tools
throw() {
echo "$@" >&2
@@ -12,6 +11,6 @@ throw() {
[ -d "$docTarget" ] || mkdir -p "$docTarget" || throw "Could not create doc target $docTarget"
cd "$docTarget"
-python ${toolsRoot}/docdump/makehtml.py -multipage ${here}/base/classes.xml
+python ${here}/makehtml.py -multipage ${here}/base/classes.xml
cd "$here"
diff --git a/doc/tools/doc_merge.py b/doc/tools/doc_merge.py
new file mode 100644
index 0000000000..872f38ed87
--- /dev/null
+++ b/doc/tools/doc_merge.py
@@ -0,0 +1,208 @@
+import sys
+import xml.etree.ElementTree as ET
+
+
+tree = ET.parse(sys.argv[1])
+old_doc=tree.getroot()
+
+tree = ET.parse(sys.argv[2])
+new_doc=tree.getroot()
+
+f = file(sys.argv[3],"wb")
+tab=0
+
+old_classes={}
+
+def write_string(_f, text,newline=True):
+ for t in range(tab):
+ _f.write("\t")
+ _f.write(text)
+ if (newline):
+ _f.write("\n")
+
+def escape(ret):
+ ret=ret.replace("&","&amp;");
+ ret=ret.replace("<","&gt;");
+ ret=ret.replace(">","&lt;");
+ ret=ret.replace("'","&apos;");
+ ret=ret.replace("\"","&quot;");
+ return ret
+
+
+def inc_tab():
+ global tab
+ tab+=1
+
+def dec_tab():
+ global tab
+ tab-=1
+
+write_string(f,'<?xml version="1.0" encoding="UTF-8" ?>')
+write_string(f,'<doc version="'+new_doc.attrib["version"]+'">')
+
+def get_tag(node,name):
+ tag=""
+ if (name in node.attrib):
+ tag=' '+name+'="'+escape(node.attrib[name])+'" '
+ return tag
+
+def find_method_descr(old_class,name):
+
+ methods = old_class.find("methods")
+ if(methods!=None and len(list(methods))>0):
+ for m in list(methods):
+ if (m.attrib["name"]==name):
+ description=m.find("description")
+ if (description!=None and description.text.strip()!=""):
+ return description.text
+
+ return None
+
+def find_signal_descr(old_class,name):
+
+ signals = old_class.find("signals")
+ if(signals!=None and len(list(signals))>0):
+ for m in list(signals):
+ if (m.attrib["name"]==name):
+ description=m.find("description")
+ if (description!=None and description.text.strip()!=""):
+ return description.text
+
+ return None
+
+def find_constant_descr(old_class,name):
+
+ if (old_class==None):
+ return None
+ constants = old_class.find("constants")
+ if(constants!=None and len(list(constants))>0):
+ for m in list(constants):
+ if (m.attrib["name"]==name):
+ if (m.text.strip()!=""):
+ return m.text
+ return None
+
+def write_class(c):
+ class_name = c.attrib["name"]
+ print("Parsing Class: "+class_name)
+ if (class_name in old_classes):
+ old_class=old_classes[class_name]
+ else:
+ old_class=None
+
+
+ category=get_tag(c,"category")
+ inherits=get_tag(c,"inherits")
+ write_string(f,'<class name="'+class_name+'" '+category+inherits+'>')
+ inc_tab()
+
+ write_string(f,"<brief_description>")
+
+ if (old_class!=None):
+ old_brief_descr=old_class.find("brief_description")
+ if (old_brief_descr!=None):
+ write_string(f,escape(old_brief_descr.text.strip()))
+
+
+ write_string(f,"</brief_description>")
+
+ write_string(f,"<description>")
+ if (old_class!=None):
+ old_descr=old_class.find("description")
+ if (old_descr!=None):
+ write_string(f,escape(old_descr.text.strip()))
+
+ write_string(f,"</description>")
+
+ methods = c.find("methods")
+ if(methods!=None and len(list(methods))>0):
+
+ write_string(f,"<methods>")
+ inc_tab()
+
+ for m in list(methods):
+ qualifiers=get_tag(m,"qualifiers")
+
+ write_string(f,'<method name="'+escape(m.attrib["name"])+'" ' +qualifiers+'>')
+ inc_tab()
+
+ for a in list(m):
+ if (a.tag=="return"):
+ typ=get_tag(a,"type")
+ write_string(f,'<return'+typ+'>');
+ write_string(f,'</return>');
+ elif (a.tag=="argument"):
+
+ default=get_tag(a,"default")
+
+ write_string(f,'<argument index="'+a.attrib["index"]+'" name="'+escape(a.attrib["name"])+'" type="'+a.attrib["type"]+'"' +default+'>');
+ write_string(f,'</argument>');
+
+ write_string(f,'<description>');
+ if (old_class!=None):
+ old_method_descr=find_method_descr(old_class,m.attrib["name"])
+ if (old_method_descr):
+ write_string(f,escape(escape(old_method_descr.strip())))
+
+ write_string(f,'</description>');
+ dec_tab()
+ write_string(f,"</method>")
+ dec_tab()
+ write_string(f,"</methods>")
+
+ signals = c.find("signals")
+ if(signals!=None and len(list(signals))>0):
+
+ write_string(f,"<signals>")
+ inc_tab()
+
+ for m in list(signals):
+
+ write_string(f,'<signal name="'+escape(m.attrib["name"])+'">')
+ inc_tab()
+
+ for a in list(m):
+ if (a.tag=="argument"):
+
+ write_string(f,'<argument index="'+a.attrib["index"]+'" name="'+escape(a.attrib["name"])+'" type="'+a.attrib["type"]+'">');
+ write_string(f,'</argument>');
+
+ write_string(f,'<description>');
+ if (old_class!=None):
+ old_signal_descr=find_signal_descr(old_class,m.attrib["name"])
+ if (old_signal_descr):
+ write_string(f,escape(old_signal_descr.strip()))
+ write_string(f,'</description>');
+ dec_tab()
+ write_string(f,"</signal>")
+ dec_tab()
+ write_string(f,"</signals>")
+
+ constants = c.find("constants")
+ if(constants!=None and len(list(constants))>0):
+
+ write_string(f,"<constants>")
+ inc_tab()
+
+ for m in list(constants):
+
+ write_string(f,'<constant name="'+escape(m.attrib["name"])+'" value="'+m.attrib["value"]+'">')
+ old_constant_descr=find_constant_descr(old_class,m.attrib["name"])
+ if (old_constant_descr):
+ write_string(f,escape(old_constant_descr.strip()))
+ write_string(f,"</constant>")
+
+ dec_tab()
+ write_string(f,"</constants>")
+
+ dec_tab()
+ write_string(f,"</class>")
+
+for c in list(old_doc):
+ old_classes[c.attrib["name"]]=c
+
+for c in list(new_doc):
+ write_class(c)
+write_string(f,'</doc>\n')
+
+
diff --git a/doc/tools/locales/es/LC_MESSAGES/makedocs.mo b/doc/tools/locales/es/LC_MESSAGES/makedocs.mo
new file mode 100644
index 0000000000..8d7ea2689e
--- /dev/null
+++ b/doc/tools/locales/es/LC_MESSAGES/makedocs.mo
Binary files differ
diff --git a/doc/tools/locales/es/LC_MESSAGES/makedocs.po b/doc/tools/locales/es/LC_MESSAGES/makedocs.po
new file mode 100644
index 0000000000..82115dd897
--- /dev/null
+++ b/doc/tools/locales/es/LC_MESSAGES/makedocs.po
@@ -0,0 +1,142 @@
+# Translations template for PROJECT.
+# Copyright (C) 2015 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: makedocs\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2015-10-07 11:47-0600\n"
+"PO-Revision-Date: 2015-10-07 13:10-0600\n"
+"Last-Translator: Jorge Araya Navarro <elcorreo@deshackra.com>\n"
+"Language-Team: \n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Poedit 1.8.4\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: makedocs.py:74
+msgid ""
+"\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
+msgstr ""
+"\"<code>{gclass}</code>(Ir a la pagina de la clase {gclass})\":/"
+"class_{lkclass}"
+
+#: makedocs.py:76
+msgid ""
+"\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/"
+"class_{lkclass}#{lkmethod}"
+msgstr ""
+"\"<code>{gclass}.{method}</code>(Ir a la pagina {gclass}, sección "
+"{method})\":/class_{lkclass}#{lkmethod}"
+
+#: makedocs.py:79
+msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
+msgstr "\"<code>{method}</code>(Saltar al método {method})\":#{lkmethod}"
+
+#: makedocs.py:81
+msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
+msgstr " \"{rtype}(Ir a la pagina de la clase {rtype})\":/class_{link} "
+
+#: makedocs.py:82
+msgid ""
+"\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
+msgstr ""
+"\"*{funcname}*(Saltar a la descripción para el nodo {funcname})\":#{link} "
+"<b>(</b> "
+
+#: makedocs.py:87
+msgid "h4. Inherits: "
+msgstr "h4. Hereda de: "
+
+#: makedocs.py:232
+msgid "<doc>'s version attribute missing"
+msgstr "El atributo version de <doc> no existe"
+
+#: makedocs.py:246
+msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
+msgstr ""
+"|_. Índice de símbolo |_. Nombre de la clase |_. Índice de símbolo |_. "
+"Nombre de la clase |\n"
+
+#: makedocs.py:305
+msgid ""
+"h4. Category: {}\n"
+"\n"
+msgstr ""
+"h4. Categoría: {}\n"
+"\n"
+
+#: makedocs.py:310
+msgid ""
+"h2. Brief Description\n"
+"\n"
+msgstr ""
+"h2. Descripción breve\n"
+"\n"
+
+#: makedocs.py:312
+msgid ""
+"\"read more\":#more\n"
+"\n"
+msgstr ""
+"\"Leer más\":#more\n"
+"\n"
+
+#: makedocs.py:317
+msgid ""
+"\n"
+"h3. Member Functions\n"
+"\n"
+msgstr ""
+"\n"
+"h3. Funciones miembro\n"
+"\n"
+
+#: makedocs.py:323
+msgid ""
+"\n"
+"h3. Signals\n"
+"\n"
+msgstr ""
+"\n"
+"h3. Señales\n"
+"\n"
+
+#: makedocs.py:331
+msgid ""
+"\n"
+"h3. Numeric Constants\n"
+"\n"
+msgstr ""
+"\n"
+"h3. Constantes numéricas\n"
+"\n"
+
+#: makedocs.py:347
+msgid ""
+"\n"
+"h3(#more). Description\n"
+"\n"
+msgstr ""
+"\n"
+"h3(#more). Descripción\n"
+"\n"
+
+#: makedocs.py:351
+msgid "_Nothing here, yet..._\n"
+msgstr "_Aún nada por aquí..._\n"
+
+#: makedocs.py:355
+msgid ""
+"\n"
+"h3. Member Function Description\n"
+"\n"
+msgstr ""
+"\n"
+"h3. Descripción de las funciones miembro\n"
+"\n"
diff --git a/doc/tools/main.css b/doc/tools/main.css
new file mode 100644
index 0000000000..a76e6bbed8
--- /dev/null
+++ b/doc/tools/main.css
@@ -0,0 +1,146 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV, SPAN {
+ font-family: Arial, Geneva, Helvetica, sans-serif;
+}
+
+a {
+
+ text-decoration: none;
+
+}
+
+a:hover {
+
+ text-decoration: underline;
+}
+
+td.top_table {
+
+ padding: 5px;
+}
+
+div.method_doc {
+
+ padding-bottom: 30px;
+}
+
+div.method_description {
+ margin-left: 30px;
+}
+
+list.inh_class_list {
+ margin-left: 30px;
+
+}
+
+div.inh_class_list {
+ margin-left: 30px;
+
+}
+
+div.method_doc div.method {
+
+ font-size: 12pt;
+ font-weight: bold;
+}
+
+span.funcdecl {
+
+ color: #202060;
+}
+
+span.funcdef {
+
+ color: #202060;
+}
+
+
+span.qualifier {
+
+ font-weight: bold;
+}
+
+
+span.symbol {
+
+ /*font-weight: bold;*/
+ color: #471870;
+}
+
+
+span.datatype {
+
+ color: #6a1533;
+}
+
+tr.category_title {
+
+ background-color: #333333;
+}
+a.category_title {
+ font-weight: bold;
+ color: #FFFFFF;
+}
+
+div.method_list {
+
+ margin-left: 30px;
+}
+
+div.constant_list {
+
+ margin-left: 30px;
+}
+
+div.member_list {
+
+ margin-left: 30px;
+}
+
+div.description {
+
+ margin-left: 30px;
+}
+
+div.class_description {
+
+ margin-left: 30px;
+}
+
+div.method_list li div {
+
+ display: inline;
+}
+
+div.member_list li div.member {
+
+ display: inline;
+}
+
+div.constant_list li div.constant {
+
+ display: inline;
+}
+
+span.member_description {
+
+ font-style: italic;
+ color: grey;
+}
+
+span.constant_description {
+
+ font-style: italic;
+ color: grey;
+}
+
+span.identifier {
+
+ font-weight: bold;
+}
+
+
+table.class_table td {
+
+ vertical-align: top;
+}
+
diff --git a/doc/tools/makedocs.pot b/doc/tools/makedocs.pot
new file mode 100644
index 0000000000..be3220f686
--- /dev/null
+++ b/doc/tools/makedocs.pot
@@ -0,0 +1,108 @@
+# Translations template for PROJECT.
+# Copyright (C) 2015 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: makedocs 0.1\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2015-10-07 11:47-0600\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.0\n"
+"X-Generator: Poedit 1.8.4\n"
+
+#: makedocs.py:74
+msgid "\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
+msgstr ""
+
+#: makedocs.py:76
+msgid "\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/class_{lkclass}#{lkmethod}"
+msgstr ""
+
+#: makedocs.py:79
+msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
+msgstr ""
+
+#: makedocs.py:81
+msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
+msgstr ""
+
+#: makedocs.py:82
+msgid "\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
+msgstr ""
+
+#: makedocs.py:87
+msgid "h4. Inherits: "
+msgstr ""
+
+#: makedocs.py:232
+msgid "<doc>'s version attribute missing"
+msgstr ""
+
+#: makedocs.py:246
+msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
+msgstr ""
+
+#: makedocs.py:305
+msgid ""
+"h4. Category: {}\n"
+"\n"
+msgstr ""
+
+#: makedocs.py:310
+msgid ""
+"h2. Brief Description\n"
+"\n"
+msgstr ""
+
+#: makedocs.py:312
+msgid ""
+"\"read more\":#more\n"
+"\n"
+msgstr ""
+
+#: makedocs.py:317
+msgid ""
+"\n"
+"h3. Member Functions\n"
+"\n"
+msgstr ""
+
+#: makedocs.py:323
+msgid ""
+"\n"
+"h3. Signals\n"
+"\n"
+msgstr ""
+
+#: makedocs.py:331
+msgid ""
+"\n"
+"h3. Numeric Constants\n"
+"\n"
+msgstr ""
+
+#: makedocs.py:347
+msgid ""
+"\n"
+"h3(#more). Description\n"
+"\n"
+msgstr ""
+
+#: makedocs.py:351
+msgid "_Nothing here, yet..._\n"
+msgstr ""
+
+#: makedocs.py:355
+msgid ""
+"\n"
+"h3. Member Function Description\n"
+"\n"
+msgstr ""
diff --git a/doc/tools/makedocs.py b/doc/tools/makedocs.py
new file mode 100644
index 0000000000..be57891abc
--- /dev/null
+++ b/doc/tools/makedocs.py
@@ -0,0 +1,382 @@
+#!/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>
+#
+
+# IMPORTANT NOTICE:
+# If you are going to modify anything from this file, please be sure to follow
+# the Style Guide for Python Code or often called "PEP8". To do this
+# automagically just install autopep8:
+#
+# $ sudo pip3 install autopep8
+#
+# and run:
+#
+# $ autopep8 makedocs.py
+#
+# Before committing your changes. Also be sure to delete any trailing
+# whitespace you may left.
+#
+# TODO:
+# * Refactor code.
+# * Adapt this script for generating content in other markup formats like
+# DokuWiki, Markdown, etc.
+#
+# Also check other TODO entries in this script for more information on what is
+# left to do.
+import argparse
+import gettext
+import logging
+import re
+from itertools import zip_longest
+from os import path, listdir
+from xml.etree import ElementTree
+
+
+# add an option to change the verbosity
+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 langavailable():
+ """ Return a list of languages available for translation
+ """
+ filepath = path.join(
+ path.dirname(path.abspath(__file__)), "locales")
+ files = listdir(filepath)
+ choices = [x for x in files]
+ choices.insert(0, "none")
+ return choices
+
+
+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")
+parser.add_argument("--language", choices=langavailable(), default="none",
+ help=("Choose the language of translation"
+ " for the output files. Default is English (none). "
+ "Note: This is NOT for the documentation itself!"))
+# 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)
+
+_ = gettext.gettext
+if args.language != "none":
+ lang = gettext.translation(domain="makedocs",
+ localedir="locales",
+ languages=[args.language])
+ lang.install()
+
+ _ = lang.gettext
+
+# Strings
+C_LINK = _("\"<code>{gclass}</code>(Go to page of class"
+ " {gclass})\":/class_{lkclass}")
+MC_LINK = _("\"<code>{gclass}.{method}</code>(Go "
+ "to page {gclass}, section {method})\""
+ ":/class_{lkclass}#{lkmethod}")
+TM_JUMP = _("\"<code>{method}</code>(Jump to method"
+ " {method})\":#{lkmethod}")
+GTC_LINK = _(" \"{rtype}(Go to page of class {rtype})\":/class_{link} ")
+DFN_JUMP = _("\"*{funcname}*(Jump to description for"
+ " node {funcname})\":#{link} <b>(</b> ")
+M_ARG_DEFAULT = C_LINK + " {name}={default}"
+M_ARG = C_LINK + " {name}"
+
+OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n"
+
+
+def tb(string):
+ """ Return a byte representation of a string
+ """
+ return bytes(string, "UTF-8")
+
+
+def sortkey(c):
+ """ Symbols are first, letters second
+ """
+ if "_" == c.attrib["name"][0]:
+ return "A"
+ else:
+ return c.attrib["name"]
+
+
+def toOP(text):
+ """ Convert commands in text to Open Project commands
+ """
+ # TODO: Make this capture content between [command] ... [/command]
+ 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)
+ # Process other non-html commands
+ groups = re.finditer((r'\[method ((?P<class>[aA0-zZ9_]+)(?:\.))'
+ r'?(?P<method>[aA0-zZ9_]+)\]'), text)
+ for group in groups:
+ gd = group.groupdict()
+ if gd["class"]:
+ replacewith = (MC_LINK.format(gclass=gd["class"],
+ method=gd["method"],
+ lkclass=gd["class"].lower(),
+ lkmethod=gd["method"].lower()))
+ else:
+ # The method is located in the same wiki page
+ replacewith = (TM_JUMP.format(method=gd["method"],
+ lkmethod=gd["method"].lower()))
+
+ text = text.replace(group.group(0), replacewith, 1)
+ # Finally, [Classes] are around brackets, make them direct links
+ groups = re.finditer(r'\[(?P<class>[az0-AZ0_]+)\]', text)
+ for group in groups:
+ gd = group.groupdict()
+ replacewith = (C_LINK.
+ format(gclass=gd["class"],
+ lkclass=gd["class"].lower()))
+ text = text.replace(group.group(0), replacewith, 1)
+
+ return text + "\n\n"
+
+
+def mkfn(node, is_signal=False):
+ """ Return a string containing a unsorted item for a function
+ """
+ finalstr = ""
+ name = node.attrib["name"]
+ rtype = node.find("return")
+ if rtype:
+ rtype = rtype.attrib["type"]
+ else:
+ rtype = "void"
+ # write the return type and the function name first
+ finalstr += "* "
+ # return type
+ if not is_signal:
+ if rtype != "void":
+ finalstr += GTC_LINK.format(
+ rtype=rtype,
+ link=rtype.lower())
+ else:
+ finalstr += " void "
+
+ # function name
+ if not is_signal:
+ finalstr += DFN_JUMP.format(
+ funcname=name,
+ link=name.lower())
+ else:
+ # Signals have no description
+ finalstr += "*{funcname}* <b>(</b>".format(funcname=name)
+ # loop for the arguments of the function, if any
+ args = []
+ for arg in sorted(
+ node.iter(tag="argument"),
+ key=lambda a: int(a.attrib["index"])):
+
+ ntype = arg.attrib["type"]
+ nname = arg.attrib["name"]
+
+ if "default" in arg.attrib:
+ args.insert(-1, M_ARG_DEFAULT.format(
+ gclass=ntype,
+ lkclass=ntype.lower(),
+ name=nname,
+ default=arg.attrib["default"]))
+ else:
+ # No default value present
+ args.insert(-1, M_ARG.format(gclass=ntype,
+ lkclass=ntype.lower(), name=nname))
+ # join the arguments together
+ finalstr += ", ".join(args)
+ # and, close the function with a )
+ finalstr += " <b>)</b>"
+ # write the qualifier, if any
+ if "qualifiers" in node.attrib:
+ qualifier = node.attrib["qualifiers"]
+ finalstr += " " + qualifier
+
+ finalstr += "\n"
+
+ return finalstr
+
+# 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 = zip_longest(classes[:int(len(classes) / 2 + 1)],
+ classes[int(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(tb("|^.\n"))
+ fcl.write(tb(_("|_. Index symbol |_. Class name "
+ "|_. Index symbol |_. Class name |\n")))
+ fcl.write(tb("|-.\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(tb("| *{}* |".format(indexletterl.upper())))
+ else:
+ # empty cell
+ fcl.write(tb("| |"))
+ # write the class name column, left
+ fcl.write(tb(C_LINK.format(
+ gclass=gdclassl.attrib["name"],
+ lkclass=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(tb("| *{}* |".format(indexletterr.upper())))
+ else:
+ # empty cell
+ fcl.write(tb("| |"))
+ # We are dealing with an empty string
+ else:
+ # two empty cell
+ fcl.write(tb("| | |\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(tb(C_LINK.format(
+ gclass=gdclassl.attrib["name"],
+ lkclass=gdclassl.attrib["name"].lower()) + "|\n"))
+
+ # row written #
+ # now, let's write each class page for each class
+ for gdclass in [gdclassl, gdclassr]:
+ if not isinstance(gdclass, ElementTree.Element):
+ 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(tb("h1. {}\n\n".format(classname)))
+ # lay the attributes
+ if "inherits" in gdclass.attrib:
+ inh = gdclass.attrib["inherits"].strip()
+ clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
+ lkclass=inh.lower())))
+ if "category" in gdclass.attrib:
+ clsf.write(tb(_("h4. Category: {}\n\n").
+ format(gdclass.attrib["category"].strip())))
+ # lay child nodes
+ briefd = gdclass.find("brief_description")
+ if briefd.text.strip():
+ clsf.write(tb(_("h2. Brief Description\n\n")))
+ clsf.write(tb(toOP(briefd.text.strip()) +
+ _("\"read more\":#more\n\n")))
+
+ # Write the list of member functions of this class
+ methods = gdclass.find("methods")
+ if methods and len(methods) > 0:
+ clsf.write(tb(_("\nh3. Member Functions\n\n")))
+ for method in methods.iter(tag='method'):
+ clsf.write(tb(mkfn(method)))
+
+ signals = gdclass.find("signals")
+ if signals and len(signals) > 0:
+ clsf.write(tb(_("\nh3. Signals\n\n")))
+ for signal in signals.iter(tag='signal'):
+ clsf.write(tb(mkfn(signal, True)))
+ # TODO: <members> tag is necessary to process? it does not
+ # exists in class_list.xml file.
+
+ consts = gdclass.find("constants")
+ if consts and len(consts) > 0:
+ clsf.write(tb(_("\nh3. Numeric Constants\n\n")))
+ for const in sorted(consts, key=lambda k:
+ k.attrib["name"]):
+ if const.text.strip():
+ clsf.write(tb("* *{name}* = *{value}* - {desc}\n".
+ format(
+ name=const.attrib["name"],
+ value=const.attrib["value"],
+ desc=const.text.strip())))
+ else:
+ # Constant have no description
+ clsf.write(tb("* *{name}* = *{value}*\n".
+ format(
+ name=const.attrib["name"],
+ value=const.attrib["value"])))
+ descrip = gdclass.find("description")
+ clsf.write(tb(_("\nh3(#more). Description\n\n")))
+ if descrip.text:
+ clsf.write(tb(descrip.text.strip() + "\n"))
+ else:
+ clsf.write(tb(_("_Nothing here, yet..._\n")))
+
+ # and finally, the description for each method
+ if methods and len(methods) > 0:
+ clsf.write(tb(_("\nh3. Member Function Description\n\n")))
+ for method in methods.iter(tag='method'):
+ clsf.write(tb("h4(#{n}). {name}\n\n".format(
+ n=method.attrib["name"].lower(),
+ name=method.attrib["name"])))
+ clsf.write(tb(mkfn(method) + "\n"))
+ clsf.write(tb(toOP(method.find(
+ "description").text.strip())))
diff --git a/doc/tools/makedoku.py b/doc/tools/makedoku.py
new file mode 100644
index 0000000000..e8207715fe
--- /dev/null
+++ b/doc/tools/makedoku.py
@@ -0,0 +1,511 @@
+import sys
+import xml.etree.ElementTree as ET
+
+input_list = []
+
+
+for arg in sys.argv[1:]:
+ input_list.append(arg)
+
+if len(input_list) < 1:
+ print("usage: makedoku.py <class_list.xml>")
+ sys.exit(0)
+
+
+def validate_tag(elem,tag):
+ if (elem.tag != tag):
+ print("Tag mismatch, expected '"+tag+"', got "+elem.tag);
+ sys.exit(255)
+
+
+class_names=[]
+classes={}
+
+
+def make_class_list(class_list,columns):
+
+ f=open("class_list.txt","wb")
+ prev=0
+ col_max = len(class_list) / columns + 1
+ print("col max is ", col_max)
+ col_count = 0
+ row_count = 0
+ last_initial = ""
+ fit_columns=[]
+
+ for n in range(0,columns):
+ fit_columns+=[[]]
+
+ indexers=[]
+ last_initial=""
+
+ idx=0
+ for n in class_list:
+ col = idx/col_max
+ if (col>=columns):
+ col=columns-1
+ fit_columns[col]+=[n]
+ idx+=1
+ if (n[:1]!=last_initial):
+ indexers+=[n]
+ last_initial=n[:1]
+
+
+ row_max=0
+
+ for n in range(0,columns):
+ if (len(fit_columns[n])>row_max):
+ row_max=len(fit_columns[n])
+
+
+ for r in range(0,row_max):
+ s="|"
+ for c in range(0,columns):
+ if (r>=len(fit_columns[c])):
+ continue
+
+ classname = fit_columns[c][r]
+ initial=classname[0]
+ if (classname in indexers):
+ s+="**"+initial+"**|"
+ else:
+ s+=" |"
+
+ s+="[["+classname.lower()+"|"+classname+"]]|"
+
+ s+="\n"
+ f.write(s)
+
+
+def dokuize_text(txt):
+
+ return txt
+
+
+def dokuize_text(text):
+ pos=0
+ while(True):
+ pos = text.find("[",pos)
+ if (pos==-1):
+ break
+
+ endq_pos=text.find("]",pos+1)
+ if (endq_pos==-1):
+ break
+
+ pre_text=text[:pos]
+ post_text=text[endq_pos+1:]
+ tag_text=text[pos+1:endq_pos]
+
+ if (tag_text in class_names):
+ tag_text="[["+tag_text.lower()+"|"+tag_text+"]]"
+ else: #command
+ cmd=tag_text
+ space_pos=tag_text.find(" ")
+ if (cmd.find("html")==0):
+ cmd=tag_text[:space_pos]
+ param=tag_text[space_pos+1:]
+ tag_text="<"+param+">"
+ elif(cmd.find("method")==0):
+ cmd=tag_text[:space_pos]
+ param=tag_text[space_pos+1:]
+
+ if (param.find(".")!=-1):
+ class_param,method_param=param.split(".")
+ tag_text="[["+class_param.lower()+"#"+method_param+"|"+class_param+'.'+method_param+"]]"
+ else:
+ tag_text="[[#"+param+"|"+param+"]]"
+ elif (cmd.find("image=")==0):
+ tag_text="{{"+cmd[6:]+"}}"
+ elif (cmd.find("url=")==0):
+ tag_text="[["+cmd[4:]+"|"
+ elif (cmd=="/url"):
+ tag_text="]]>"
+ elif (cmd=="center"):
+ tag_text=""
+ elif (cmd=="/center"):
+ tag_text=""
+ elif (cmd=="br"):
+ tag_text="\\\\\n"
+ elif (cmd=="i" or cmd=="/i"):
+ tag_text="//"
+ elif (cmd=="b" or cmd=="/b"):
+ tag_text="**"
+ elif (cmd=="u" or cmd=="/u"):
+ tag_text="__"
+ else:
+ tag_text="["+tag_text+"]"
+
+
+ text=pre_text+tag_text+post_text
+ pos=len(pre_text)+len(tag_text)
+
+ #tnode = ET.SubElement(parent,"div")
+ #tnode.text=text
+ return text
+
+
+def make_type(t):
+ global class_names
+ if (t in class_names):
+ return "[["+t.lower()+"|"+t+"]]"
+ return t
+
+
+def make_method(f,name,m,declare,event=False):
+
+ s=" * "
+ ret_type="void"
+ args=list(m)
+ mdata={}
+ mdata["argidx"]=[]
+ for a in args:
+ if (a.tag=="return"):
+ idx=-1
+ elif (a.tag=="argument"):
+ idx=int(a.attrib["index"])
+ else:
+ continue
+
+ mdata["argidx"].append(idx)
+ mdata[idx]=a
+
+
+
+ if (not event):
+ if (-1 in mdata["argidx"]):
+ s+=make_type(mdata[-1].attrib["type"])
+ else:
+ s+="void"
+ s+=" "
+
+ if (declare):
+
+ #span.attrib["class"]="funcdecl"
+ #a=ET.SubElement(span,"a")
+ #a.attrib["name"]=name+"_"+m.attrib["name"]
+ #a.text=name+"::"+m.attrib["name"]
+ s+="**"+m.attrib["name"]+"**"
+ else:
+ s+="[[#"+m.attrib["name"]+"|"+m.attrib["name"]+"]]"
+
+ s+="**(**"
+ argfound=False
+ for a in mdata["argidx"]:
+ arg=mdata[a]
+ if (a<0):
+ continue
+ if (a>0):
+ s+=", "
+ else:
+ s+=" "
+
+ s+=make_type(arg.attrib["type"])
+ if ("name" in arg.attrib):
+ s+=" "+arg.attrib["name"]
+ else:
+ s+=" arg"+str(a)
+
+ if ("default" in arg.attrib):
+ s+="="+arg.attrib["default"]
+
+
+ argfound=True
+
+ if (argfound):
+ s+=" "
+ s+="**)**"
+
+ if ("qualifiers" in m.attrib):
+ s+=" "+m.attrib["qualifiers"]
+
+ f.write(s+"\n")
+
+
+def make_doku_class(node):
+
+ name = node.attrib["name"]
+
+ f=open(name.lower()+".txt","wb")
+
+ f.write("====== "+name+" ======\n")
+
+ if ("inherits" in node.attrib):
+ inh=node.attrib["inherits"].strip()
+ f.write("**Inherits:** [["+inh.lower()+"|"+inh+"]]\\\\\n")
+ if ("category" in node.attrib):
+ f.write("**Category:** "+node.attrib["category"].strip()+"\\\\\n")
+
+ briefd = node.find("brief_description")
+ if (briefd!=None):
+ f.write("===== Brief Description ======\n")
+ f.write( dokuize_text(briefd.text.strip())+"\n" )
+
+ methods = node.find("methods")
+
+ if(methods!=None and len(list(methods))>0):
+ f.write("===== Member Functions ======\n")
+ for m in list(methods):
+ make_method(f,node.attrib["name"],m,False)
+
+ events = node.find("signals")
+ if(events!=None and len(list(events))>0):
+ f.write("===== Signals ======\n")
+ for m in list(events):
+ make_method(f,node.attrib["name"],m,True,True)
+
+ members = node.find("members")
+
+ if(members!=None and len(list(members))>0):
+ f.write("===== Member Variables ======\n")
+
+ for c in list(members):
+ s = " * "
+ s+=make_type(c.attrib["type"])+" "
+ s+="**"+c.attrib["name"]+"**"
+ if (c.text.strip()!=""):
+ s+=" - "+c.text.strip()
+ f.write(s+"\n")
+
+
+
+ constants = node.find("constants")
+ if(constants!=None and len(list(constants))>0):
+ f.write("===== Numeric Constants ======\n")
+ for c in list(constants):
+ s = " * "
+ s+="**"+c.attrib["name"]+"**"
+ if ("value" in c.attrib):
+ s+=" = **"+c.attrib["value"]+"**"
+ if (c.text.strip()!=""):
+ s+=" - "+c.text.strip()
+ f.write(s+"\n")
+
+
+ descr=node.find("description")
+ if (descr!=None and descr.text.strip()!=""):
+ f.write("===== Description ======\n")
+ f.write(dokuize_text(descr.text.strip())+"\n")
+
+ methods = node.find("methods")
+
+ if(methods!=None and len(list(methods))>0):
+ f.write("===== Member Function Description ======\n")
+ for m in list(methods):
+
+ d=m.find("description")
+ if (d==None or d.text.strip()==""):
+ continue
+ f.write("== "+m.attrib["name"]+" ==\n")
+ make_method(f,node.attrib["name"],m,False)
+ f.write("\\\\\n")
+ f.write(dokuize_text(d.text.strip()))
+ f.write("\n")
+
+
+
+
+
+ """
+ div=ET.Element("div")
+ div.attrib["class"]="class";
+
+ a=ET.SubElement(div,"a")
+ a.attrib["name"]=node.attrib["name"]
+
+ h3=ET.SubElement(a,"h3")
+ h3.attrib["class"]="title class_title"
+ h3.text=node.attrib["name"]
+
+ briefd = node.find("brief_description")
+ if (briefd!=None):
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="description class_description"
+ div2.text=briefd.text
+
+ if ("inherits" in node.attrib):
+ ET.SubElement(div,"br")
+
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="inheritance";
+
+ span=ET.SubElement(div2,"span")
+ span.text="Inherits: "
+
+ make_type(node.attrib["inherits"],div2)
+
+ if ("category" in node.attrib):
+ ET.SubElement(div,"br")
+
+ div3=ET.SubElement(div,"div")
+ div3.attrib["class"]="category";
+
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="category"
+ span.text="Category: "
+
+ a = ET.SubElement(div3,"a")
+ a.attrib["class"]="category_ref"
+ a.text=node.attrib["category"]
+ catname=a.text
+ if (catname.rfind("/")!=-1):
+ catname=catname[catname.rfind("/"):]
+ catname="CATEGORY_"+catname
+
+ if (single_page):
+ a.attrib["href"]="#"+catname
+ else:
+ a.attrib["href"]="category.html#"+catname
+
+
+ methods = node.find("methods")
+
+ if(methods!=None and len(list(methods))>0):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Public Methods:"
+
+ method_table=ET.SubElement(div,"table")
+ method_table.attrib["class"]="method_list";
+
+ for m in list(methods):
+# li = ET.SubElement(div2, "li")
+ method_table.append( make_method_def(node.attrib["name"],m,False) )
+
+ events = node.find("signals")
+
+ if(events!=None and len(list(events))>0):
+ h4=ET.SubElement(div,"h4")
+ h4.text="Events:"
+
+ event_table=ET.SubElement(div,"table")
+ event_table.attrib["class"]="method_list";
+
+ for m in list(events):
+# li = ET.SubElement(div2, "li")
+ event_table.append( make_method_def(node.attrib["name"],m,False,True) )
+
+
+ members = node.find("members")
+ if(members!=None and len(list(members))>0):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Public Variables:"
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="member_list";
+
+ for c in list(members):
+
+ li = ET.SubElement(div2, "li")
+ div3=ET.SubElement(li,"div")
+ div3.attrib["class"]="member";
+ make_type(c.attrib["type"],div3)
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="identifier member_name"
+ span.text=" "+c.attrib["name"]+" "
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="member_description"
+ span.text=c.text
+
+
+ constants = node.find("constants")
+ if(constants!=None and len(list(constants))>0):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Constants:"
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="constant_list";
+
+ for c in list(constants):
+ li = ET.SubElement(div2, "li")
+ div3=ET.SubElement(li,"div")
+ div3.attrib["class"]="constant";
+
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="identifier constant_name"
+ span.text=c.attrib["name"]+" "
+ if ("value" in c.attrib):
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="symbol"
+ span.text="= "
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="constant_value"
+ span.text=c.attrib["value"]+" "
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="constant_description"
+ span.text=c.text
+
+# ET.SubElement(div,"br")
+
+
+ descr=node.find("description")
+ if (descr!=None and descr.text.strip()!=""):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Description:"
+
+ make_text_def(node.attrib["name"],div,descr.text)
+# div2=ET.SubElement(div,"div")
+# div2.attrib["class"]="description";
+# div2.text=descr.text
+
+
+
+ if(methods!=None or events!=None):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Method Documentation:"
+ iter_list = []
+ if (methods!=None):
+ iter_list+=list(methods)
+ if (events!=None):
+ iter_list+=list(events)
+
+ for m in iter_list:
+
+ descr=m.find("description")
+
+ if (descr==None or descr.text.strip()==""):
+ continue;
+
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="method_doc";
+
+
+ div2.append( make_method_def(node.attrib["name"],m,True) )
+ #anchor = ET.SubElement(div2, "a")
+ #anchor.attrib["name"] =
+ make_text_def(node.attrib["name"],div2,descr.text)
+ #div3=ET.SubElement(div2,"div")
+ #div3.attrib["class"]="description";
+ #div3.text=descr.text
+
+
+ return div
+"""
+for file in input_list:
+ tree = ET.parse(file)
+ doc=tree.getroot()
+
+ if ("version" not in doc.attrib):
+ print("Version missing from 'doc'")
+ 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
+
+
+class_names.sort()
+
+make_class_list(class_names,4)
+
+for cn in class_names:
+ c=classes[cn]
+ make_doku_class(c)
+
+
diff --git a/doc/tools/makehtml.py b/doc/tools/makehtml.py
new file mode 100644
index 0000000000..9b9c62f33b
--- /dev/null
+++ b/doc/tools/makehtml.py
@@ -0,0 +1,717 @@
+import sys
+import xml.etree.ElementTree as ET
+from xml.sax.saxutils import escape, unescape
+
+html_escape_table = {
+ '"': "&quot;",
+ "'": "&apos;"
+}
+
+html_unescape_table = {v:k for k, v in html_escape_table.items()}
+
+def html_escape(text):
+ return escape(text, html_escape_table)
+
+def html_unescape(text):
+ return unescape(text, html_unescape_table)
+
+input_list = []
+
+single_page=True
+
+for arg in sys.argv[1:]:
+ if arg[:1] == "-":
+ if arg[1:] == "multipage":
+ single_page = False
+ if arg[1:] == "singlepage":
+ single_page = True
+ else:
+ input_list.append(arg)
+
+if len(input_list) < 1:
+ print("usage: makehtml.py <class_list.xml>")
+ sys.exit(0)
+
+
+def validate_tag(elem,tag):
+ if (elem.tag != tag):
+ print("Tag mismatch, expected '"+tag+"', got "+elem.tag);
+ sys.exit(255)
+
+def make_html_bottom(body):
+ #make_html_top(body,True)
+ ET.SubElement(body,"hr")
+ copyright = ET.SubElement(body,"span")
+ copyright.text = "Copyright 2008-2010 Codenix SRL"
+
+def make_html_top(body,bottom=False):
+
+ if (bottom):
+ ET.SubElement(body,"hr")
+
+ table = ET.SubElement(body,"table")
+ table.attrib["class"]="top_table"
+ tr = ET.SubElement(table,"tr")
+ td = ET.SubElement(tr,"td")
+ td.attrib["class"]="top_table"
+
+ img = ET.SubElement(td,"image")
+ img.attrib["src"]="images/logo.png"
+ td = ET.SubElement(tr,"td")
+ td.attrib["class"]="top_table"
+ a = ET.SubElement(td,"a")
+ a.attrib["href"]="index.html"
+ a.text="Index"
+ td = ET.SubElement(tr,"td")
+ td.attrib["class"]="top_table"
+ a = ET.SubElement(td,"a")
+ a.attrib["href"]="alphabetical.html"
+ a.text="Classes"
+ td = ET.SubElement(tr,"td")
+ td.attrib["class"]="top_table"
+ a = ET.SubElement(td,"a")
+ a.attrib["href"]="category.html"
+ a.text="Categories"
+ td = ET.SubElement(tr,"td")
+ a = ET.SubElement(td,"a")
+ a.attrib["href"]="inheritance.html"
+ a.text="Inheritance"
+ if (not bottom):
+ ET.SubElement(body,"hr")
+
+
+
+
+def make_html_class_list(class_list,columns):
+
+ div=ET.Element("div")
+ div.attrib["class"]="ClassList";
+
+ h1=ET.SubElement(div,"h2")
+ h1.text="Alphabetical Class List"
+
+ table=ET.SubElement(div,"table")
+ table.attrib["class"]="class_table"
+ table.attrib["width"]="100%"
+ prev=0
+
+ col_max = len(class_list) / columns + 1
+ print("col max is ", col_max)
+ col_count = 0
+ row_count = 0
+ last_initial = ""
+ fit_columns=[]
+
+ for n in range(0,columns):
+ fit_columns+=[[]]
+
+ indexers=[]
+ last_initial=""
+
+ idx=0
+ for n in class_list:
+ col = int(idx/col_max)
+ if (col>=columns):
+ col=columns-1
+ fit_columns[col]+=[n]
+ idx+=1
+ if (n[:1]!=last_initial):
+ indexers+=[n]
+ last_initial=n[:1]
+
+ row_max=0
+
+ for n in range(0,columns):
+ if (len(fit_columns[n])>row_max):
+ row_max=len(fit_columns[n])
+
+
+ for r in range(0,row_max):
+ tr = ET.SubElement(table,"tr")
+ for c in range(0,columns):
+ tdi = ET.SubElement(tr,"td")
+ tdi.attrib["align"]="right"
+ td = ET.SubElement(tr,"td")
+ if (r>=len(fit_columns[c])):
+ continue
+
+ classname = fit_columns[c][r]
+ print(classname)
+ if (classname in indexers):
+
+ span = ET.SubElement(tdi, "span")
+ span.attrib["class"] = "class_index_letter"
+ span.text = classname[:1].upper()
+
+ if (single_page):
+ link="#"+classname
+ else:
+ link=classname+".html"
+
+ a=ET.SubElement(td,"a")
+ a.attrib["href"]=link
+ a.text=classname
+
+
+ if (not single_page):
+ cat_class_list=ET.Element("html")
+ csscc = ET.SubElement(cat_class_list, "link")
+ csscc.attrib["href"] = "main.css"
+ csscc.attrib["rel"] = "stylesheet"
+ csscc.attrib["type"] = "text/css"
+ bodycc = ET.SubElement(cat_class_list, "body")
+ make_html_top(bodycc)
+
+ cat_class_parent=bodycc
+ else:
+ cat_class_parent=div
+
+
+
+
+ h1=ET.SubElement(cat_class_parent,"h2")
+ h1.text="Class List By Category"
+
+ class_cat_table={}
+ class_cat_list=[]
+
+ for c in class_list:
+ clss = classes[c]
+ if ("category" in clss.attrib):
+ class_cat=clss.attrib["category"]
+ else:
+ class_cat="Core"
+ if (class_cat.find("/")!=-1):
+ class_cat=class_cat[class_cat.rfind("/")+1:]
+ if (not class_cat in class_cat_list):
+ class_cat_list.append(class_cat)
+ class_cat_table[class_cat]=[]
+ class_cat_table[class_cat].append(c)
+
+ class_cat_list.sort()
+
+ ct = ET.SubElement(cat_class_parent,"table")
+ for cl in class_cat_list:
+ l = class_cat_table[cl]
+ l.sort()
+ tr = ET.SubElement(ct,"tr")
+ tr.attrib["class"]="category_title"
+ td = ET.SubElement(ct,"td")
+ td.attrib["class"]="category_title"
+
+ a = ET.SubElement(td,"a")
+ a.attrib["class"]="category_title"
+ a.text=cl
+ a.attrib["name"]="CATEGORY_"+cl
+
+ td = ET.SubElement(ct,"td")
+ td.attrib["class"]="category_title"
+
+ for clt in l:
+ tr = ET.SubElement(ct,"tr")
+ td = ET.SubElement(ct,"td")
+ make_type(clt,td)
+ clss=classes[clt]
+ bd = clss.find("brief_description")
+ bdtext=""
+ if (bd!=None):
+ bdtext=bd.text
+ td = ET.SubElement(ct,"td")
+ td.text=bdtext
+
+ if (not single_page):
+ make_html_bottom(bodycc)
+ catet_out = ET.ElementTree(cat_class_list)
+ catet_out.write("category.html")
+
+
+ if (not single_page):
+ inh_class_list=ET.Element("html")
+ cssic = ET.SubElement(inh_class_list, "link")
+ cssic.attrib["href"] = "main.css"
+ cssic.attrib["rel"] = "stylesheet"
+ cssic.attrib["type"] = "text/css"
+ bodyic = ET.SubElement(inh_class_list, "body")
+ make_html_top(bodyic)
+ inh_class_parent=bodyic
+ else:
+ inh_class_parent=div
+
+
+
+
+ h1=ET.SubElement(inh_class_parent,"h2")
+ h1.text="Class List By Inheritance"
+
+ itemlist = ET.SubElement(inh_class_parent,"list")
+
+ class_inh_table={}
+
+ def add_class(clss):
+ if (clss.attrib["name"] in class_inh_table):
+ return #already added
+ parent_list=None
+
+ if ("inherits" in clss.attrib):
+ inhc = clss.attrib["inherits"]
+ if (not (inhc in class_inh_table)):
+ add_class(classes[inhc])
+
+ parent_list = class_inh_table[inhc].find("div")
+ if (parent_list == None):
+ parent_div = ET.SubElement(class_inh_table[inhc],"div")
+ parent_list = ET.SubElement(parent_div,"list")
+ parent_div.attrib["class"]="inh_class_list"
+ else:
+ parent_list = parent_list.find("list")
+
+
+ else:
+ parent_list=itemlist
+
+ item = ET.SubElement(parent_list,"li")
+# item.attrib["class"]="inh_class_list"
+ class_inh_table[clss.attrib["name"]]=item
+ make_type(clss.attrib["name"],item)
+
+
+ for c in class_list:
+ add_class(classes[c])
+
+ if (not single_page):
+ make_html_bottom(bodyic)
+ catet_out = ET.ElementTree(inh_class_list)
+ catet_out.write("inheritance.html")
+
+
+
+
+
+ #h1=ET.SubElement(div,"h2")
+ #h1.text="Class List By Inheritance"
+
+ return div
+
+
+def make_type(p_type,p_parent):
+ if (p_type=="RefPtr"):
+ p_type="Resource"
+
+ if (p_type in class_names):
+ a=ET.SubElement(p_parent,"a")
+ a.attrib["class"]="datatype_existing"
+ a.text=p_type+" "
+ if (single_page):
+ a.attrib["href"]="#"+p_type
+ else:
+ a.attrib["href"]=p_type+".html"
+ else:
+ span=ET.SubElement(p_parent,"span")
+ span.attrib["class"]="datatype"
+ span.text=p_type+" "
+
+
+
+def make_text_def(class_name,parent,text):
+ text = html_escape(text)
+ pos=0
+ while(True):
+ pos = text.find("[",pos)
+ if (pos==-1):
+ break
+
+ endq_pos=text.find("]",pos+1)
+ if (endq_pos==-1):
+ break
+
+ pre_text=text[:pos]
+ post_text=text[endq_pos+1:]
+ tag_text=text[pos+1:endq_pos]
+
+ if (tag_text in class_names):
+ if (single_page):
+ tag_text='<a href="#'+tag_text+'">'+tag_text+'</a>'
+ else:
+ tag_text='<a href="'+tag_text+'.html">'+tag_text+'</a>'
+ else: #command
+ cmd=tag_text
+ space_pos=tag_text.find(" ")
+ if (cmd.find("html")==0):
+ cmd=tag_text[:space_pos]
+ param=tag_text[space_pos+1:]
+ tag_text="<"+param+">"
+ elif(cmd.find("method")==0):
+ cmd=tag_text[:space_pos]
+ param=tag_text[space_pos+1:]
+
+ if (not single_page and param.find(".")!=-1):
+ class_param,method_param=param.split(".")
+ tag_text=tag_text='<a href="'+class_param+'.html#'+class_param+"_"+method_param+'">'+class_param+'.'+method_param+'()</a>'
+ else:
+ tag_text=tag_text='<a href="#'+class_name+"_"+param+'">'+class_name+'.'+param+'()</a>'
+ elif (cmd.find("image=")==0):
+ print("found image: "+cmd)
+ tag_text="<img src="+cmd[6:]+"/>"
+ elif (cmd.find("url=")==0):
+ tag_text="<a href="+cmd[4:]+">"
+ elif (cmd=="/url"):
+ tag_text="</a>"
+ elif (cmd=="center"):
+ tag_text="<div align=\"center\">"
+ elif (cmd=="/center"):
+ tag_text="</div>"
+ elif (cmd=="br"):
+ tag_text="<br/>"
+ elif (cmd=="i" or cmd=="/i" or cmd=="b" or cmd=="/b" or cmd=="u" or cmd=="/u"):
+ tag_text="<"+tag_text+">" #html direct mapping
+ else:
+ tag_text="["+tag_text+"]"
+
+
+ text=pre_text+tag_text+post_text
+ pos=len(pre_text)+len(tag_text)
+
+ #tnode = ET.SubElement(parent,"div")
+ #tnode.text=text
+ text="<div class=\"description\">"+text+"</div>"
+ try:
+ tnode=ET.XML(text)
+ parent.append(tnode)
+ except:
+ print("Error parsing description text: '"+text+"'")
+ sys.exit(255)
+
+
+ return tnode
+
+
+
+
+def make_method_def(name,m,declare,event=False):
+
+ mdata={}
+
+
+ if (not declare):
+ div=ET.Element("tr")
+ div.attrib["class"]="method"
+ ret_parent=ET.SubElement(div,"td")
+ ret_parent.attrib["align"]="right"
+ func_parent=ET.SubElement(div,"td")
+ else:
+ div=ET.Element("div")
+ div.attrib["class"]="method"
+ ret_parent=div
+ func_parent=div
+
+ mdata["argidx"]=[]
+ mdata["name"]=m.attrib["name"]
+ qualifiers=""
+ if ("qualifiers" in m.attrib):
+ qualifiers=m.attrib["qualifiers"]
+
+ args=list(m)
+ for a in args:
+ if (a.tag=="return"):
+ idx=-1
+ elif (a.tag=="argument"):
+ idx=int(a.attrib["index"])
+ else:
+ continue
+
+ mdata["argidx"].append(idx)
+ mdata[idx]=a
+
+ if (not event):
+ if (-1 in mdata["argidx"]):
+ make_type(mdata[-1].attrib["type"],ret_parent)
+ mdata["argidx"].remove(-1)
+ else:
+ make_type("void",ret_parent)
+
+ span=ET.SubElement(func_parent,"span")
+ if (declare):
+ span.attrib["class"]="funcdecl"
+ a=ET.SubElement(span,"a")
+ a.attrib["name"]=name+"_"+m.attrib["name"]
+ a.text=name+"::"+m.attrib["name"]
+ else:
+ span.attrib["class"]="identifier funcdef"
+ a=ET.SubElement(span,"a")
+ a.attrib["href"]="#"+name+"_"+m.attrib["name"]
+ a.text=m.attrib["name"]
+
+ span=ET.SubElement(func_parent,"span")
+ span.attrib["class"]="symbol"
+ span.text=" ("
+
+ for a in mdata["argidx"]:
+ arg=mdata[a]
+ if (a>0):
+ span=ET.SubElement(func_parent,"span")
+ span.text=", "
+ else:
+ span=ET.SubElement(func_parent,"span")
+ span.text=" "
+
+
+ make_type(arg.attrib["type"],func_parent)
+
+ span=ET.SubElement(func_parent,"span")
+ span.text=arg.attrib["name"]
+ if ("default" in arg.attrib):
+ span.text=span.text+"="+arg.attrib["default"]
+
+
+ span=ET.SubElement(func_parent,"span")
+ span.attrib["class"]="symbol"
+ if (len(mdata["argidx"])):
+ span.text=" )"
+ else:
+ span.text=")"
+
+ if (qualifiers):
+ span=ET.SubElement(func_parent,"span")
+ span.attrib["class"]="qualifier"
+ span.text=" "+qualifiers
+
+ return div
+
+
+def make_html_class(node):
+
+ div=ET.Element("div")
+ div.attrib["class"]="class";
+
+ a=ET.SubElement(div,"a")
+ a.attrib["name"]=node.attrib["name"]
+
+ h3=ET.SubElement(a,"h3")
+ h3.attrib["class"]="title class_title"
+ h3.text=node.attrib["name"]
+
+ briefd = node.find("brief_description")
+ if (briefd!=None):
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="description class_description"
+ div2.text=briefd.text
+
+ if ("inherits" in node.attrib):
+ ET.SubElement(div,"br")
+
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="inheritance";
+
+ span=ET.SubElement(div2,"span")
+ span.text="Inherits: "
+
+ make_type(node.attrib["inherits"],div2)
+
+ if ("category" in node.attrib):
+ ET.SubElement(div,"br")
+
+ div3=ET.SubElement(div,"div")
+ div3.attrib["class"]="category";
+
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="category"
+ span.text="Category: "
+
+ a = ET.SubElement(div3,"a")
+ a.attrib["class"]="category_ref"
+ a.text=node.attrib["category"]
+ catname=a.text
+ if (catname.rfind("/")!=-1):
+ catname=catname[catname.rfind("/"):]
+ catname="CATEGORY_"+catname
+
+ if (single_page):
+ a.attrib["href"]="#"+catname
+ else:
+ a.attrib["href"]="category.html#"+catname
+
+
+ methods = node.find("methods")
+
+ if(methods!=None and len(list(methods))>0):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Public Methods:"
+
+ method_table=ET.SubElement(div,"table")
+ method_table.attrib["class"]="method_list";
+
+ for m in list(methods):
+# li = ET.SubElement(div2, "li")
+ method_table.append( make_method_def(node.attrib["name"],m,False) )
+
+ events = node.find("signals")
+
+ if(events!=None and len(list(events))>0):
+ h4=ET.SubElement(div,"h4")
+ h4.text="Events:"
+
+ event_table=ET.SubElement(div,"table")
+ event_table.attrib["class"]="method_list";
+
+ for m in list(events):
+# li = ET.SubElement(div2, "li")
+ event_table.append( make_method_def(node.attrib["name"],m,False,True) )
+
+
+ members = node.find("members")
+ if(members!=None and len(list(members))>0):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Public Variables:"
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="member_list";
+
+ for c in list(members):
+
+ li = ET.SubElement(div2, "li")
+ div3=ET.SubElement(li,"div")
+ div3.attrib["class"]="member";
+ make_type(c.attrib["type"],div3)
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="identifier member_name"
+ span.text=" "+c.attrib["name"]+" "
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="member_description"
+ span.text=c.text
+
+
+ constants = node.find("constants")
+ if(constants!=None and len(list(constants))>0):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Constants:"
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="constant_list";
+
+ for c in list(constants):
+ li = ET.SubElement(div2, "li")
+ div3=ET.SubElement(li,"div")
+ div3.attrib["class"]="constant";
+
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="identifier constant_name"
+ span.text=c.attrib["name"]+" "
+ if ("value" in c.attrib):
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="symbol"
+ span.text="= "
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="constant_value"
+ span.text=c.attrib["value"]+" "
+ span=ET.SubElement(div3,"span")
+ span.attrib["class"]="constant_description"
+ span.text=c.text
+
+# ET.SubElement(div,"br")
+
+
+ descr=node.find("description")
+ if (descr!=None and descr.text.strip()!=""):
+ h4=ET.SubElement(div,"h4")
+ h4.text="Description:"
+
+ make_text_def(node.attrib["name"],div,descr.text)
+# div2=ET.SubElement(div,"div")
+# div2.attrib["class"]="description";
+# div2.text=descr.text
+
+
+
+ if(methods!=None or events!=None):
+
+ h4=ET.SubElement(div,"h4")
+ h4.text="Method Documentation:"
+ iter_list = []
+ if (methods!=None):
+ iter_list+=list(methods)
+ if (events!=None):
+ iter_list+=list(events)
+
+ for m in iter_list:
+
+ descr=m.find("description")
+
+ if (descr==None or descr.text.strip()==""):
+ continue;
+
+ div2=ET.SubElement(div,"div")
+ div2.attrib["class"]="method_doc";
+
+
+ div2.append( make_method_def(node.attrib["name"],m,True) )
+ #anchor = ET.SubElement(div2, "a")
+ #anchor.attrib["name"] =
+ make_text_def(node.attrib["name"],div2,descr.text)
+ #div3=ET.SubElement(div2,"div")
+ #div3.attrib["class"]="description";
+ #div3.text=descr.text
+
+
+ return div
+
+class_names=[]
+classes={}
+
+for file in input_list:
+ tree = ET.parse(file)
+ doc=tree.getroot()
+
+ if ("version" not in doc.attrib):
+ print("Version missing from 'doc'")
+ 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
+
+html = ET.Element("html")
+css = ET.SubElement(html, "link")
+css.attrib["href"] = "main.css"
+css.attrib["rel"] = "stylesheet"
+css.attrib["type"] = "text/css"
+
+body = ET.SubElement(html, "body")
+if (not single_page):
+ make_html_top(body)
+
+
+
+class_names.sort()
+
+body.append( make_html_class_list(class_names,5) )
+
+for cn in class_names:
+ c=classes[cn]
+ if (single_page):
+ body.append( make_html_class(c))
+ else:
+ html2 = ET.Element("html")
+ css = ET.SubElement(html2, "link")
+ css.attrib["href"] = "main.css"
+ css.attrib["rel"] = "stylesheet"
+ css.attrib["type"] = "text/css"
+ body2 = ET.SubElement(html2, "body" )
+ make_html_top(body2)
+ body2.append( make_html_class(c) );
+ make_html_bottom(body2)
+ et_out = ET.ElementTree(html2)
+ et_out.write(c.attrib["name"]+".html")
+
+
+et_out = ET.ElementTree(html)
+if (single_page):
+ et_out.write("singlepage.html")
+else:
+ make_html_bottom(body)
+ et_out.write("alphabetical.html")
+
diff --git a/doc/tools/makemd.py b/doc/tools/makemd.py
new file mode 100644
index 0000000000..f85d145d5e
--- /dev/null
+++ b/doc/tools/makemd.py
@@ -0,0 +1,345 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+import sys
+import xml.etree.ElementTree as ET
+
+input_list = []
+
+for arg in sys.argv[1:]:
+ input_list.append(arg)
+
+if len(input_list) < 1:
+ print 'usage: makedoku.py <class_list.xml>'
+ sys.exit(0)
+
+
+def validate_tag(elem, tag):
+ if elem.tag != tag:
+ print "Tag mismatch, expected '" + tag + "', got " + elem.tag
+ sys.exit(255)
+
+
+class_names = []
+classes = {}
+
+
+def make_class_list(class_list, columns):
+
+ f = open('class_list.md', 'wb')
+ prev = 0
+ col_max = len(class_list) / columns + 1
+ print ('col max is ', col_max)
+ col_count = 0
+ row_count = 0
+ last_initial = ''
+ fit_columns = []
+
+ for n in range(0, columns):
+ fit_columns += [[]]
+
+ indexers = []
+ last_initial = ''
+
+ idx = 0
+ for n in class_list:
+ col = idx / col_max
+ if col >= columns:
+ col = columns - 1
+ fit_columns[col] += [n]
+ idx += 1
+ if n[:1] != last_initial:
+ indexers += [n]
+ last_initial = n[:1]
+
+ row_max = 0
+ f.write("\n")
+
+ for n in range(0, columns):
+ if len(fit_columns[n]) > row_max:
+ row_max = len(fit_columns[n])
+
+ f.write("| ")
+ for n in range(0, columns):
+ f.write(" | |")
+
+ f.write("\n")
+ f.write("| ")
+ for n in range(0, columns):
+ f.write(" --- | ------- |")
+ f.write("\n")
+
+ for r in range(0, row_max):
+ s = '| '
+ for c in range(0, columns):
+ if r >= len(fit_columns[c]):
+ continue
+
+ classname = fit_columns[c][r]
+ initial = classname[0]
+ if classname in indexers:
+ s += '**' + initial + '** | '
+ else:
+ s += ' | '
+
+ s += '[' + classname + '](class_'+ classname.lower()+') | '
+
+ s += '\n'
+ f.write(s)
+
+
+def dokuize_text(txt):
+
+ return txt
+
+
+def dokuize_text(text):
+ pos = 0
+ while True:
+ pos = text.find('[', pos)
+ if pos == -1:
+ break
+
+ endq_pos = text.find(']', pos + 1)
+ if endq_pos == -1:
+ break
+
+ pre_text = text[:pos]
+ post_text = text[endq_pos + 1:]
+ tag_text = text[pos + 1:endq_pos]
+
+ if tag_text in class_names:
+ tag_text = make_type(tag_text)
+ else:
+
+ # command
+
+ cmd = tag_text
+ space_pos = tag_text.find(' ')
+ if cmd.find('html') == 0:
+ cmd = tag_text[:space_pos]
+ param = tag_text[space_pos + 1:]
+ tag_text = '<' + param + '>'
+ elif cmd.find('method') == 0:
+ cmd = tag_text[:space_pos]
+ param = tag_text[space_pos + 1:]
+
+ if param.find('.') != -1:
+ (class_param, method_param) = param.split('.')
+ tag_text = '['+class_param+'.'+method_param.replace("_","&#95;")+'](' + class_param.lower() + '#' \
+ + method_param + ')'
+ else:
+ tag_text = '[' + param.replace("_","&#95;") + '](#' + param + ')'
+ elif cmd.find('image=') == 0:
+ tag_text = '![](' + cmd[6:] + ')'
+ elif cmd.find('url=') == 0:
+ tag_text = '[' + cmd[4:] + ']('+cmd[4:]
+ elif cmd == '/url':
+ tag_text = ')'
+ elif cmd == 'center':
+ tag_text = ''
+ elif cmd == '/center':
+ tag_text = ''
+ elif cmd == 'br':
+ tag_text = '\n'
+ elif cmd == 'i' or cmd == '/i':
+ tag_text = '_'
+ elif cmd == 'b' or cmd == '/b':
+ tag_text = '**'
+ elif cmd == 'u' or cmd == '/u':
+ tag_text = '__'
+ else:
+ tag_text = '[' + tag_text + ']'
+
+ text = pre_text + tag_text + post_text
+ pos = len(pre_text) + len(tag_text)
+
+ # tnode = ET.SubElement(parent,"div")
+ # tnode.text=text
+
+ return text
+
+
+def make_type(t):
+ global class_names
+ if t in class_names:
+ return '[' + t + '](class_' + t.lower() + ')'
+ return t
+
+
+def make_method(
+ f,
+ name,
+ m,
+ declare,
+ event=False,
+ ):
+
+ s = ' * '
+ ret_type = 'void'
+ args = list(m)
+ mdata = {}
+ mdata['argidx'] = []
+ for a in args:
+ if a.tag == 'return':
+ idx = -1
+ elif a.tag == 'argument':
+ idx = int(a.attrib['index'])
+ else:
+ continue
+
+ mdata['argidx'].append(idx)
+ mdata[idx] = a
+
+ if not event:
+ if -1 in mdata['argidx']:
+ s += make_type(mdata[-1].attrib['type'])
+ else:
+ s += 'void'
+ s += ' '
+
+ if declare:
+
+ # span.attrib["class"]="funcdecl"
+ # a=ET.SubElement(span,"a")
+ # a.attrib["name"]=name+"_"+m.attrib["name"]
+ # a.text=name+"::"+m.attrib["name"]
+
+ s += ' **'+m.attrib['name'].replace("_","&#95;")+'** '
+ else:
+ s += ' **['+ m.attrib['name'].replace("_","&#95;")+'](#' + m.attrib['name'] + ')** '
+
+ s += ' **(**'
+ argfound = False
+ for a in mdata['argidx']:
+ arg = mdata[a]
+ if a < 0:
+ continue
+ if a > 0:
+ s += ', '
+ else:
+ s += ' '
+
+ s += make_type(arg.attrib['type'])
+ if 'name' in arg.attrib:
+ s += ' ' + arg.attrib['name']
+ else:
+ s += ' arg' + str(a)
+
+ if 'default' in arg.attrib:
+ s += '=' + arg.attrib['default']
+
+ argfound = True
+
+ if argfound:
+ s += ' '
+ s += ' **)**'
+
+ if 'qualifiers' in m.attrib:
+ s += ' ' + m.attrib['qualifiers']
+
+ f.write(s + '\n')
+
+
+def make_doku_class(node):
+
+ name = node.attrib['name']
+
+ f = open("class_"+name.lower() + '.md', 'wb')
+
+ f.write('# ' + name + ' \n')
+
+ if 'inherits' in node.attrib:
+ inh = node.attrib['inherits'].strip()
+ f.write('####**Inherits:** '+make_type(inh)+'\n')
+ if 'category' in node.attrib:
+ f.write('####**Category:** ' + node.attrib['category'].strip()
+ + '\n')
+
+ briefd = node.find('brief_description')
+ if briefd != None:
+ f.write('\n### Brief Description \n')
+ f.write(dokuize_text(briefd.text.strip()) + '\n')
+
+ methods = node.find('methods')
+
+ if methods != None and len(list(methods)) > 0:
+ f.write('\n### Member Functions \n')
+ for m in list(methods):
+ make_method(f, node.attrib['name'], m, False)
+
+ events = node.find('signals')
+ if events != None and len(list(events)) > 0:
+ f.write('\n### Signals \n')
+ for m in list(events):
+ make_method(f, node.attrib['name'], m, True, True)
+
+ members = node.find('members')
+
+ if members != None and len(list(members)) > 0:
+ f.write('\n### Member Variables \n')
+
+ for c in list(members):
+ s = ' * '
+ s += make_type(c.attrib['type']) + ' '
+ s += '**' + c.attrib['name'] + '**'
+ if c.text.strip() != '':
+ s += ' - ' + c.text.strip()
+ f.write(s + '\n')
+
+ constants = node.find('constants')
+ if constants != None and len(list(constants)) > 0:
+ f.write('\n### Numeric Constants \n')
+ for c in list(constants):
+ s = ' * '
+ s += '**' + c.attrib['name'] + '**'
+ if 'value' in c.attrib:
+ s += ' = **' + c.attrib['value'] + '**'
+ if c.text.strip() != '':
+ s += ' - ' + c.text.strip()
+ f.write(s + '\n')
+
+ descr = node.find('description')
+ if descr != None and descr.text.strip() != '':
+ f.write('\n### Description \n')
+ f.write(dokuize_text(descr.text.strip()) + '\n')
+
+ methods = node.find('methods')
+
+ if methods != None and len(list(methods)) > 0:
+ f.write('\n### Member Function Description \n')
+ for m in list(methods):
+
+ d = m.find('description')
+ if d == None or d.text.strip() == '':
+ continue
+ f.write('\n#### <a name="'+m.attrib['name']+'">' + m.attrib['name'] + '</a>\n')
+ make_method(f, node.attrib['name'], m, True)
+ f.write('\n')
+ f.write(dokuize_text(d.text.strip()))
+ f.write('\n')
+
+
+for file in input_list:
+ tree = ET.parse(file)
+ doc = tree.getroot()
+
+ if 'version' not in doc.attrib:
+ print "Version missing from 'doc'"
+ 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
+
+class_names.sort()
+
+make_class_list(class_names, 2)
+
+for cn in class_names:
+ c = classes[cn]
+ make_doku_class(c)
+