123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- """
- @package tools.build_modules_xml
- @brief Builds XML metadata of GRASS modules. Runs only during compilation.
- (C) 2013 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- @author Vaclav Petras <wenzeslaus gmail.com>
- @author Anna Petrasova <kratochanna gmail.com>
- """
- from __future__ import print_function
- import sys
- import grass.script.core as gcore
- import grass.script.task as gtask
- def escapeXML(text):
- """This is a duplicate of function in core/toolboxes.
- >>> escapeXML('<>&')
- '&lt;>&'
- """
- return text.replace("<", "<").replace("&", "&").replace(">", ">")
- def do_doctest_gettext_workaround():
- """This is a duplicate of function in core/toolboxes."""
- def new_displayhook(string):
- """A replacement for default `sys.displayhook`"""
- if string is not None:
- sys.stdout.write("%r\n" % (string,))
- def new_translator(string):
- """A fake gettext underscore function."""
- return string
- sys.displayhook = new_displayhook
- sys.__displayhook__ = new_displayhook
- import __builtin__
- __builtin__._ = new_translator
- def parse_modules(fd):
- """Writes metadata to xml file."""
- # TODO: what about ms windows? does gtask handle this?
- mlist = list(gcore.get_commands()[0])
- indent = 4
- for m in sorted(mlist):
- # TODO: get rid of g.mapsets_picker.py
- if m == "g.mapsets_picker.py" or m == "g.parser":
- continue
- desc, keyw = get_module_metadata(m)
- fd.write('%s<module-item name="%s">\n' % (" " * indent, m))
- indent += 4
- fd.write("%s<module>%s</module>\n" % (" " * indent, m))
- fd.write("%s<description>%s</description>\n" % (" " * indent, escapeXML(desc)))
- fd.write(
- "%s<keywords>%s</keywords>\n" % (" " * indent, escapeXML(",".join(keyw)))
- )
- indent -= 4
- fd.write("%s</module-item>\n" % (" " * indent))
- def get_module_metadata(name):
- """
- >>> get_module_metadata('g.region')
- ('Manages the boundary definitions for the geographic region.', ['general', 'settings'])
- >>> get_module_metadata('m.proj')
- ('Converts coordinates from one projection to another (cs2cs frontend).', ['miscellaneous', 'projection'])
- """
- try:
- task = gtask.parse_interface(name)
- except:
- sys.stderr.write(
- "Cannot parse interface for module %s. Empty strings"
- " will be placed instead of description and keywords."
- "\n" % name
- )
- return "", ""
- return task.get_description(full=True), task.get_keywords()
- def header(fd):
- fd.write('<?xml version="1.0" encoding="UTF-8"?>\n')
- fd.write('<!DOCTYPE module-items SYSTEM "module_items.dtd">\n')
- fd.write("<!--This file is automatically generated using %s-->\n" % sys.argv[0])
- # g.version -r is crashing, commenting this block for now
- # vInfo = gcore.version()
- # fd.write('<!--version="%s" revision="%s" date="%s"-->\n' % \
- # (vInfo['version'].split('.')[0],
- # vInfo['revision'],
- # datetime.now()))
- fd.write("<module-items>\n")
- def footer(fd):
- fd.write("</module-items>\n")
- def doc_test():
- """Tests the module using doctest
- :return: a number of failed tests
- """
- import doctest
- do_doctest_gettext_workaround()
- return doctest.testmod().failed
- def module_test():
- grass_commands = gcore.get_commands()[0]
- if "g.region" not in grass_commands:
- print("No g.region")
- return 1
- if "m.proj" not in grass_commands:
- print("No m.proj")
- return 1
- if "t.rast.univar" not in grass_commands:
- print("No t.rast.univar")
- return 1
- print(get_module_metadata("g.region"))
- print(get_module_metadata("m.proj"))
- print(get_module_metadata("t.rast.univar"))
- def main():
- fh = sys.stdout
- header(fh)
- parse_modules(fh)
- footer(fh)
- return 0
- if __name__ == "__main__":
- if len(sys.argv) > 1:
- if sys.argv[1] == "doctest":
- sys.exit(doc_test())
- elif sys.argv[1] == "test":
- sys.exit(module_test())
- else:
- gcore.fatal("Unrecognized parameter.")
- sys.exit(main())
|