Jelajahi Sumber

Internationalization implemented

Specify which language you want the templates translate to with the
`--language` option and any choice language available. By default
English is used. When class_list.xml is translated to different language
than English this option will be useful to make the template language
match.
Jorge Araya Navarro 10 tahun lalu
induk
melakukan
68d005760b

TEMPAT SAMPAH
tools/docdump/locales/es/LC_MESSAGES/makedocs.mo


+ 142 - 0
tools/docdump/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 <[email protected]>\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"

+ 108 - 0
tools/docdump/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 ""

+ 76 - 52
tools/docdump/makedocs.py

@@ -25,37 +25,88 @@
 #  * Refactor code.
 #  * Refactor code.
 #  * Adapt this script for generating content in other markup formats like
 #  * Adapt this script for generating content in other markup formats like
 #    DokuWiki, Markdown, etc.
 #    DokuWiki, Markdown, etc.
-#  * Because people will translate class_list.xml, we should implement
-#    internalization.
 #
 #
 # Also check other TODO entries in this script for more information on what is
 # Also check other TODO entries in this script for more information on what is
 # left to do.
 # left to do.
+import gettext
 import argparse
 import argparse
 import logging
 import logging
 import re
 import re
 from itertools import zip_longest
 from itertools import zip_longest
 from os import path
 from os import path
+from os import listdir
 from xml.etree import ElementTree
 from xml.etree import ElementTree
 
 
 
 
 # add an option to change the verbosity
 # add an option to change the verbosity
 logging.basicConfig(level=logging.INFO)
 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":
+    logging.info("Language changed to: " + args.language)
+    lang = gettext.translation(domain="makedocs",
+                               localedir="locales",
+                               languages=[args.language])
+    lang.install()
+
+    _ = lang.gettext
+
 # Strings
 # 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> ")
+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_DEFAULT = C_LINK + " {name}={default}"
 M_ARG = C_LINK + " {name}"
 M_ARG = C_LINK + " {name}"
 
 
-OPENPROJ_INH = ("h4. Inherits: " + C_LINK + "\n\n")
+OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n"
 
 
 
 
 def tb(string):
 def tb(string):
@@ -64,13 +115,6 @@ def tb(string):
     return bytes(string, "UTF-8")
     return bytes(string, "UTF-8")
 
 
 
 
-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):
 def sortkey(c):
     """ Symbols are first, letters second
     """ Symbols are first, letters second
     """
     """
@@ -201,37 +245,17 @@ def mkfn(node, is_signal=False):
 
 
     return finalstr
     return finalstr
 
 
-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
 # Let's begin
 tree = ElementTree.parse(args.xmlfp)
 tree = ElementTree.parse(args.xmlfp)
 root = tree.getroot()
 root = tree.getroot()
 
 
 # Check version attribute exists in <doc>
 # Check version attribute exists in <doc>
 if "version" not in root.attrib:
 if "version" not in root.attrib:
-    logging.critical("<doc>'s version attribute missing")
+    logging.critical(_("<doc>'s version attribute missing"))
     exit(1)
     exit(1)
 
 
 version = root.attrib["version"]
 version = root.attrib["version"]
 classes = sorted(root, key=sortkey)
 classes = sorted(root, key=sortkey)
-logging.debug("Number of classes: {}".format(len(classes)))
-logging.debug("len(classes) / 2 + 1: {}".format(int(len(classes) / 2 + 1)))
 # first column is always longer, second column of classes should be shorter
 # first column is always longer, second column of classes should be shorter
 zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
 zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
                        classes[int(len(classes) / 2 + 1):],
                        classes[int(len(classes) / 2 + 1):],
@@ -241,8 +265,8 @@ zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
 with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
 with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
     # Write header of table
     # Write header of table
     fcl.write(tb("|^.\n"))
     fcl.write(tb("|^.\n"))
-    fcl.write(tb("|_. Index symbol |_. Class name "
-                 "|_. Index symbol |_. Class name |\n"))
+    fcl.write(tb(_("|_. Index symbol |_. Class name "
+                   "|_. Index symbol |_. Class name |\n")))
     fcl.write(tb("|-.\n"))
     fcl.write(tb("|-.\n"))
 
 
     indexletterl = ""
     indexletterl = ""
@@ -300,25 +324,25 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
                     clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
                     clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
                                                       lkclass=inh.lower())))
                                                       lkclass=inh.lower())))
                 if "category" in gdclass.attrib:
                 if "category" in gdclass.attrib:
-                    clsf.write(tb("h4. Category: {}\n\n".
+                    clsf.write(tb(_("h4. Category: {}\n\n").
                                   format(gdclass.attrib["category"].strip())))
                                   format(gdclass.attrib["category"].strip())))
                 # lay child nodes
                 # lay child nodes
                 briefd = gdclass.find("brief_description")
                 briefd = gdclass.find("brief_description")
                 if briefd.text.strip():
                 if briefd.text.strip():
-                    clsf.write(b"h2. Brief Description\n\n")
+                    clsf.write(tb(_("h2. Brief Description\n\n")))
                     clsf.write(tb(toOP(briefd.text.strip()) +
                     clsf.write(tb(toOP(briefd.text.strip()) +
-                                  "\"read more\":#more\n\n"))
+                                  _("\"read more\":#more\n\n")))
 
 
                 # Write the list of member functions of this class
                 # Write the list of member functions of this class
                 methods = gdclass.find("methods")
                 methods = gdclass.find("methods")
                 if methods and len(methods) > 0:
                 if methods and len(methods) > 0:
-                    clsf.write(b"\nh3. Member Functions\n\n")
+                    clsf.write(tb(_("\nh3. Member Functions\n\n")))
                     for method in methods.iter(tag='method'):
                     for method in methods.iter(tag='method'):
                         clsf.write(tb(mkfn(method)))
                         clsf.write(tb(mkfn(method)))
 
 
                 signals = gdclass.find("signals")
                 signals = gdclass.find("signals")
                 if signals and len(signals) > 0:
                 if signals and len(signals) > 0:
-                    clsf.write(b"\nh3. Signals\n\n")
+                    clsf.write(tb(_("\nh3. Signals\n\n")))
                     for signal in signals.iter(tag='signal'):
                     for signal in signals.iter(tag='signal'):
                         clsf.write(tb(mkfn(signal, True)))
                         clsf.write(tb(mkfn(signal, True)))
                 # TODO: <members> tag is necessary to process? it does not
                 # TODO: <members> tag is necessary to process? it does not
@@ -326,7 +350,7 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
 
 
                 consts = gdclass.find("constants")
                 consts = gdclass.find("constants")
                 if consts and len(consts) > 0:
                 if consts and len(consts) > 0:
-                    clsf.write(b"\nh3. Numeric Constants\n\n")
+                    clsf.write(tb(_("\nh3. Numeric Constants\n\n")))
                     for const in sorted(consts, key=lambda k:
                     for const in sorted(consts, key=lambda k:
                                         k.attrib["name"]):
                                         k.attrib["name"]):
                         if const.text.strip():
                         if const.text.strip():
@@ -342,15 +366,15 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
                                               name=const.attrib["name"],
                                               name=const.attrib["name"],
                                               value=const.attrib["value"])))
                                               value=const.attrib["value"])))
                 descrip = gdclass.find("description")
                 descrip = gdclass.find("description")
-                clsf.write(b"\nh3(#more). Description\n\n")
+                clsf.write(tb(_("\nh3(#more). Description\n\n")))
                 if descrip.text:
                 if descrip.text:
                     clsf.write(tb(descrip.text.strip() + "\n"))
                     clsf.write(tb(descrip.text.strip() + "\n"))
                 else:
                 else:
-                    clsf.write(b"_Nothing here, yet..._\n")
+                    clsf.write(tb(_("_Nothing here, yet..._\n")))
 
 
                 # and finally, the description for each method
                 # and finally, the description for each method
                 if methods and len(methods) > 0:
                 if methods and len(methods) > 0:
-                    clsf.write(b"\nh3. Member Function Description\n\n")
+                    clsf.write(tb(_("\nh3. Member Function Description\n\n")))
                     for method in methods.iter(tag='method'):
                     for method in methods.iter(tag='method'):
                         clsf.write(tb("h4(#{n}). {name}\n\n".format(
                         clsf.write(tb("h4(#{n}). {name}\n\n".format(
                             n=method.attrib["name"].lower(),
                             n=method.attrib["name"].lower(),