1#!/usr/bin/env python 2# 3# @file generate-pkg-stylesheet.py 4# @brief Create a stylesheet for libSBML package extensions 5# @author Michael Hucka 6# 7# Usage: 8# generate-pkg-stylesheet.py PACKAGE-SRC-DIR > libsbml-package-stylesheet.css 9# 10# where 11# PACKAGE-SRC-DIR = the path to the libSBML src/sbml/packages directory 12# 13# This program looks in the root of the libSBML source directory for package 14# plug-ins that are distributed with libSBML (i.e., for accepted SBML Level 3 15# packages) and generates a CSS stylesheet for both the Doxygen-based and 16# Javadoc-based API documentation. To do the desired styling for the Javadoc 17# documentation, this program has to know the object classes that are defined 18# by each libSBML package plug-in. Since this may change over time, it 19# is better to look in the source directory for the current class definitions 20# than to hard code them in a CSS file or this file. That is the motivation 21# for this program. 22# 23# <!-------------------------------------------------------------------------- 24# This file is part of libSBML. Please visit http://sbml.org for more 25# information about SBML, and the latest version of libSBML. 26# 27# Copyright (C) 2013-2018 jointly by the following organizations: 28# 1. California Institute of Technology, Pasadena, CA, USA 29# 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK 30# 3. University of Heidelberg, Heidelberg, Germany 31# 32# Copyright (C) 2009-2013 jointly by the following organizations: 33# 1. California Institute of Technology, Pasadena, CA, USA 34# 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK 35# 36# Copyright (C) 2006-2008 by the California Institute of Technology, 37# Pasadena, CA, USA 38# 39# Copyright (C) 2002-2005 jointly by the following organizations: 40# 1. California Institute of Technology, Pasadena, CA, USA 41# 2. Japan Science and Technology Agency, Japan 42# 43# This library is free software; you can redistribute it and/or modify it 44# under the terms of the GNU Lesser General Public License as published by 45# the Free Software Foundation. A copy of the license agreement is provided 46# in the file named "LICENSE.txt" included with this software distribution 47# and also available online as http://sbml.org/software/libsbml/license.html 48# ---------------------------------------------------------------------- -->*/ 49 50import os, sys, re 51from os.path import join 52sys.path.append('../../../src/bindings/swig') 53sys.path.append('../../src/bindings/swig') 54from libsbmlutils import find_classes 55 56 57color_table = [ 58 # Name, red, green, blue 59 ['comp', '220', '220', '220'], 60 ['fbc', '190', '230', '215'], 61 ['layout', '250', '230', '170'], 62 ['qual', '160', '185', '235'], 63 ['multi', '120', '120', '120'], 64 ['groups', '242', '169', '135'], 65 ['arrays', '0', '150', '132'], 66 ['distrib', '243', '250', '134'], 67 ['spatial', '223', '170', '20'], 68 ['render', '77', '168', '170'], 69] 70 71 72header_template = '''/** 73 * WARNING -- THIS FILE IS AUTO-GENERATED -- DO NOT EDIT THIS FILE 74 * 75 * @file libsbml-package-stylesheet.css 76 * @brief Stylesheet used by libSBML for L3 package plug-in docs. 77 * @author libSBML Team <libsbml-team@googlegroups.com> 78 * 79 * This file is generated by generate-pkg-stylesheet.py in the libSBML 80 * documentation source directory. DO NOT EDIT THIS FILE DIRECTLY 81 * BECAUSE YOUR CHANGES WILL BE LOST WHEN THE FILE IS REGENERATED. 82 * 83 * This file is part of libSBML. Please visit http://sbml.org for more 84 * information about SBML, and the latest version of libSBML. 85 */ 86''' 87 88 89pkg_separator_template = ''' 90/* Styling for package '{}' used in libSBML Javadoc output */ 91''' 92 93 94pkg_style_template = '''.pkg-color-{0} 95{{ 96 border: 1px solid rgb({1}, {2}, {3}); 97 background-color: rgba({1}, {2}, {3}, 0.35); 98}} 99''' 100 101 102group_page_ref_template = '''{ 103 font-family: "Noto Sans", Verdana, Helvetica, Arial, Sans, sans-serif !important; 104 font-weight: normal; 105 font-size: 12px; 106} 107''' 108 109 110safari_bugfix_template = '''{ 111 display: inline-block; 112 margin-left: 0px; 113} 114''' 115 116 117before_template = '''{{ 118 content: "\\25cf"; 119 color: rgb({1}, {2}, {3}); 120 margin-right: 0.25em; 121}} 122''' 123 124 125after_template = '''{{ 126 content: "{0}"; 127 display: inline-block; 128 font-family: "Noto Sans", Verdana, Helvetica, Arial, Sans, sans-serif; 129 font-size: 80%; 130 font-style: italic; 131 font-weight: normal; 132 line-height: 100%; 133 text-align: center; 134 color: #000 !important; 135 background-color: rgba({1}, {2}, {3}, 0.35); 136 border: 1px solid rgb({1}, {2}, {3}); 137 border-radius: 5px; 138 -moz-border-radius: 5px; 139 -webkit-border-radius: 5px; 140 margin-left: 1em; 141 padding: 1px 3px; 142 min-width: 40px; 143 width: 40px; 144}} 145''' 146 147 148def main(args): 149 if len(args) != 2: 150 print ("Must be given one argument: the path to the package source dir") 151 sys.exit(1) 152 153 src_dir = args[1] 154 155 # First, write out an informative file header. 156 print (header_template) 157 158 # Next, write out the .pkg-color-x CSS classes: 159 for entry in color_table: 160 print (pkg_style_template.format(entry[0], entry[1], entry[2], entry[3])) 161 162 # Next, write rules for general references to the summary pages for packages. 163 print ('/* Styles for references to the package summary pages. */\n') 164 for entry in color_table: 165 print ('p a.el[href="group__{}.html"]'.format(entry[0])) 166 print (group_page_ref_template) 167 168 # Next, read the source dir to find out the L3 packages available, and 169 # extract the names of the libSBML object classes in each package. 170 known_pkgs = [entry[0] for entry in color_table] 171 top_root, top_level_dirs, top_level_files = os.walk(src_dir).next() 172 found_pkgs = [pkg for pkg in known_pkgs if pkg in top_level_dirs] 173 174 # Now generate CSS styling that uses attribute selectors specialized to 175 # our Javadoc output. These styles are ignored by our Doxygen output 176 # (because the CSS code doesn't match anything there), so technically we 177 # could split this into a separate file for Javadoc-only styling, but 178 # it's easier to write all our package CSS code into one file. 179 for pkg in found_pkgs: 180 print (pkg_separator_template.format(pkg)) 181 182 color = next(entry for entry in color_table if entry[0] == pkg) 183 classes = find_classes(os.path.join(src_dir, pkg), enums_too = False) 184 last = classes[-1] 185 186 # There is a spectacularly obscure bug in Safari that necessitates 187 # first writing CSS rules that use the same attribute selectors we 188 # use later, but without using pseudo elements. Here, we output a 189 # benign bit of CSS that doesn't change anything. See 190 # http://stackoverflow.com/a/8988418/743730 191 for c in classes: 192 # This next format works for Javadoc version 1.6: 193 print ('.FrameItemFont a[href$="{}.html"],'.format(c)) 194 # This next format works for Javadoc versions after version 1.6: 195 comma = (',' if c != last else '') 196 print ('.indexContainer a[href$="{}.html"]{}'.format(c, comma)) 197 print (safari_bugfix_template) 198 199 # With that out of the way, we can write the real CSS. 200 for c in classes: 201 # This next format works for Javadoc version 1.6: 202 print ('.FrameItemFont a[href$="{}.html"]:before,'.format(c)) 203 # This next format works for Javadoc versions after version 1.6: 204 comma = (',' if c != last else '') 205 print ('.indexContainer a[href$="{}.html"]:before{}'.format(c, comma)) 206 print (before_template.format(pkg, color[1], color[2], color[3])) 207 208 for c in classes: 209 # This next format works for Javadoc version 1.6: 210 print ('.FrameItemFont a[href$="{}.html"]:after,'.format(c)) 211 # This next format works for Javadoc versions after version 1.6: 212 comma = (',' if c != last else '') 213 print ('.indexContainer a[href$="{}.html"]:after{}'.format(c, comma)) 214 print (after_template.format(pkg, color[1], color[2], color[3])) 215 216 # A final bit of styling for Doxygen output. 217 print ('/* Styles for page headings and "Level 3 Extensions" section. */\n') 218 for entry in color_table: 219 print ('.title .ingroups a[href="group__{}.html"]:after,'.format(entry[0])) 220 print ('#navrow2 ul.tablist li a[href="group__{}.html"]:after,'.format(entry[0])) 221 print ('.contents ul li a[href="group__{}.html"]:after'.format(entry[0])) 222 print (after_template.format(entry[0], entry[1], entry[2], entry[3])) 223 224 225 226if __name__ == '__main__': 227 main(sys.argv) 228