#!/usr/bin/env python3 ############################################################################ # # MODULE: build_class_graphical # AUTHOR(S): Vaclav Petras # PURPOSE: Build page with modules per family/class/category with images # COPYRIGHT: (C) 2015 by Vaclav Petras and 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. # ############################################################################# import sys import os import fnmatch # from build_html import * from build_html import ( default_year, header1_tmpl, grass_version, modclass_intro_tmpl, to_title, html_files, check_for_desc_override, get_desc, write_html_footer, replace_file, ) header_graphical_index_tmpl = """\
GRASS logo

Graphical index of GRASS GIS modules

""" def file_matches(filename, patterns): for pattern in patterns: if fnmatch.fnmatch(filename, pattern): return True return False def starts_with_module(string, module): # not solving: # module = module.replace('wxGUI.', 'g.gui.') # TODO: matches g.mapsets images for g.mapset and d.rast.num for d.rast if string.startswith(module.replace(".", "_")): return True if string.startswith(module.replace(".", "")): return True if string.startswith(module): return True return False def get_module_image(module, images): candidates = [] for image in images: if starts_with_module(image, module): candidates.append(image) if len(candidates) == 1: # matches g.mapsets images for g.mapset and d.rast.num for d.rast return candidates[0] if not candidates: return None for image in candidates: basename, unused = image.rsplit(".", 1) if basename == module.replace(".", "_"): return image if basename == module.replace(".", ""): return image if basename == module: return image return sorted(candidates, key=len)[0] def generate_page_for_category( short_family, module_family, imgs, year, skip_no_image=False ): filename = module_family + "_graphical.html" output = open(filename + ".tmp", "w") output.write( header1_tmpl.substitute( title="GRASS GIS %s Reference " "Manual: Graphical index" % grass_version ) ) output.write(header_graphical_index_tmpl) if module_family.lower() not in ["general", "postscript"]: if module_family == "raster3d": # covert keyword to nice form module_family = "3D raster" output.write( modclass_intro_tmpl.substitute( modclass=module_family, modclass_lower=module_family.lower() ) ) if module_family == "wxGUI": output.write("

wxGUI components:

") elif module_family == "guimodules": output.write("

g.gui.* modules:

") else: output.write("

{0} modules:

".format(to_title(module_family))) output.write('") write_html_footer(output, "index.html", year) output.close() replace_file(filename) # TODO: dependencies in makefile for this have to be fixed # TODO: there is a potential overlap with other scripts (-> refactoring) def main(): year = default_year html_dir = sys.argv[1] os.chdir(html_dir) img_extensions = ["png", "jpg", "gif"] img_patterns = ["*." + extension for extension in img_extensions] imgs = [] for filename in sorted(os.listdir(html_dir)): if file_matches(filename, img_patterns): imgs.append(filename) # using term family # category has its meaning in GRASS already # class has its meaning in Python, plus it is a synonym for category # TODO: what would be user friendly is unclear families = [ ("d", "display"), ("db", "database"), ("g", "general"), ("i", "imagery"), ("m", "miscellaneous"), ("ps", "postscript"), ("r", "raster"), ("r3", "raster3d"), ("t", "temporal"), ("v", "vector"), ("wxGUI", "wxGUI"), ("g.gui", "guimodules"), ] # partial compatibility with build_class.py # first arg is dist html dir but the 3 other are like first 3 there if len(sys.argv) > 2: short_family = sys.argv[2] module_family = sys.argv[3] if len(sys.argv) > 4: year = sys.argv[4] for short_family, module_family in families: generate_page_for_category( short_family, module_family, imgs, year=year, skip_no_image=False ) if __name__ == "__main__": main()