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