#!/usr/bin/env python # # @file generate-pkg-stylesheet.py # @brief Create a stylesheet for libSBML package extensions # @author Michael Hucka # # Usage: # generate-pkg-stylesheet.py PACKAGE-SRC-DIR > libsbml-package-stylesheet.css # # where # PACKAGE-SRC-DIR = the path to the libSBML src/sbml/packages directory # # This program looks in the root of the libSBML source directory for package # plug-ins that are distributed with libSBML (i.e., for accepted SBML Level 3 # packages) and generates a CSS stylesheet for both the Doxygen-based and # Javadoc-based API documentation. To do the desired styling for the Javadoc # documentation, this program has to know the object classes that are defined # by each libSBML package plug-in. Since this may change over time, it # is better to look in the source directory for the current class definitions # than to hard code them in a CSS file or this file. That is the motivation # for this program. # # */ import os, sys, re from os.path import join sys.path.append('../../../src/bindings/swig') sys.path.append('../../src/bindings/swig') from libsbmlutils import find_classes color_table = [ # Name, red, green, blue ['comp', '220', '220', '220'], ['fbc', '190', '230', '215'], ['layout', '250', '230', '170'], ['qual', '160', '185', '235'], ['multi', '120', '120', '120'], ['groups', '242', '169', '135'], ['arrays', '0', '150', '132'], ['distrib', '243', '250', '134'], ['spatial', '223', '170', '20'], ['render', '77', '168', '170'], ] header_template = '''/** * WARNING -- THIS FILE IS AUTO-GENERATED -- DO NOT EDIT THIS FILE * * @file libsbml-package-stylesheet.css * @brief Stylesheet used by libSBML for L3 package plug-in docs. * @author libSBML Team * * This file is generated by generate-pkg-stylesheet.py in the libSBML * documentation source directory. DO NOT EDIT THIS FILE DIRECTLY * BECAUSE YOUR CHANGES WILL BE LOST WHEN THE FILE IS REGENERATED. * * This file is part of libSBML. Please visit http://sbml.org for more * information about SBML, and the latest version of libSBML. */ ''' pkg_separator_template = ''' /* Styling for package '{}' used in libSBML Javadoc output */ ''' pkg_style_template = '''.pkg-color-{0} {{ border: 1px solid rgb({1}, {2}, {3}); background-color: rgba({1}, {2}, {3}, 0.35); }} ''' group_page_ref_template = '''{ font-family: "Noto Sans", Verdana, Helvetica, Arial, Sans, sans-serif !important; font-weight: normal; font-size: 12px; } ''' safari_bugfix_template = '''{ display: inline-block; margin-left: 0px; } ''' before_template = '''{{ content: "\\25cf"; color: rgb({1}, {2}, {3}); margin-right: 0.25em; }} ''' after_template = '''{{ content: "{0}"; display: inline-block; font-family: "Noto Sans", Verdana, Helvetica, Arial, Sans, sans-serif; font-size: 80%; font-style: italic; font-weight: normal; line-height: 100%; text-align: center; color: #000 !important; background-color: rgba({1}, {2}, {3}, 0.35); border: 1px solid rgb({1}, {2}, {3}); border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; margin-left: 1em; padding: 1px 3px; min-width: 40px; width: 40px; }} ''' def main(args): if len(args) != 2: print ("Must be given one argument: the path to the package source dir") sys.exit(1) src_dir = args[1] # First, write out an informative file header. print (header_template) # Next, write out the .pkg-color-x CSS classes: for entry in color_table: print (pkg_style_template.format(entry[0], entry[1], entry[2], entry[3])) # Next, write rules for general references to the summary pages for packages. print ('/* Styles for references to the package summary pages. */\n') for entry in color_table: print ('p a.el[href="group__{}.html"]'.format(entry[0])) print (group_page_ref_template) # Next, read the source dir to find out the L3 packages available, and # extract the names of the libSBML object classes in each package. known_pkgs = [entry[0] for entry in color_table] top_root, top_level_dirs, top_level_files = os.walk(src_dir).next() found_pkgs = [pkg for pkg in known_pkgs if pkg in top_level_dirs] # Now generate CSS styling that uses attribute selectors specialized to # our Javadoc output. These styles are ignored by our Doxygen output # (because the CSS code doesn't match anything there), so technically we # could split this into a separate file for Javadoc-only styling, but # it's easier to write all our package CSS code into one file. for pkg in found_pkgs: print (pkg_separator_template.format(pkg)) color = next(entry for entry in color_table if entry[0] == pkg) classes = find_classes(os.path.join(src_dir, pkg), enums_too = False) last = classes[-1] # There is a spectacularly obscure bug in Safari that necessitates # first writing CSS rules that use the same attribute selectors we # use later, but without using pseudo elements. Here, we output a # benign bit of CSS that doesn't change anything. See # http://stackoverflow.com/a/8988418/743730 for c in classes: # This next format works for Javadoc version 1.6: print ('.FrameItemFont a[href$="{}.html"],'.format(c)) # This next format works for Javadoc versions after version 1.6: comma = (',' if c != last else '') print ('.indexContainer a[href$="{}.html"]{}'.format(c, comma)) print (safari_bugfix_template) # With that out of the way, we can write the real CSS. for c in classes: # This next format works for Javadoc version 1.6: print ('.FrameItemFont a[href$="{}.html"]:before,'.format(c)) # This next format works for Javadoc versions after version 1.6: comma = (',' if c != last else '') print ('.indexContainer a[href$="{}.html"]:before{}'.format(c, comma)) print (before_template.format(pkg, color[1], color[2], color[3])) for c in classes: # This next format works for Javadoc version 1.6: print ('.FrameItemFont a[href$="{}.html"]:after,'.format(c)) # This next format works for Javadoc versions after version 1.6: comma = (',' if c != last else '') print ('.indexContainer a[href$="{}.html"]:after{}'.format(c, comma)) print (after_template.format(pkg, color[1], color[2], color[3])) # A final bit of styling for Doxygen output. print ('/* Styles for page headings and "Level 3 Extensions" section. */\n') for entry in color_table: print ('.title .ingroups a[href="group__{}.html"]:after,'.format(entry[0])) print ('#navrow2 ul.tablist li a[href="group__{}.html"]:after,'.format(entry[0])) print ('.contents ul li a[href="group__{}.html"]:after'.format(entry[0])) print (after_template.format(entry[0], entry[1], entry[2], entry[3])) if __name__ == '__main__': main(sys.argv)