1#
2# epydoc.css: default epydoc CSS stylesheets
3# Edward Loper
4#
5# Created [01/30/01 05:18 PM]
6# $Id: html_css.py 1634 2007-09-24 15:58:38Z dvarrazzo $
7#
8
9"""
10Predefined CSS stylesheets for the HTML outputter (L{epydoc.docwriter.html}).
11
12@type STYLESHEETS: C{dictionary} from C{string} to C{(string, string)}
13@var STYLESHEETS: A dictionary mapping from stylesheet names to CSS
14    stylesheets and descriptions.  A single stylesheet may have
15    multiple names.  Currently, the following stylesheets are defined:
16      - C{default}: The default stylesheet (synonym for C{white}).
17      - C{white}: Black on white, with blue highlights (similar to
18        javadoc).
19      - C{blue}: Black on steel blue.
20      - C{green}: Black on green.
21      - C{black}: White on black, with blue highlights
22      - C{grayscale}: Grayscale black on white.
23      - C{none}: An empty stylesheet.
24"""
25__docformat__ = 'epytext en'
26
27import re
28
29############################################################
30## Basic stylesheets
31############################################################
32
33# [xx] Should I do something like:
34#
35#    @import url(html4css1.css);
36#
37# But then where do I get that css file from?  Hm.
38# Also, in principle I'm mangling classes, but it looks like I'm
39# failing.
40#
41
42# Black on white, with blue highlights.  This is similar to how
43# javadoc looks.
44TEMPLATE = """
45
46/* Epydoc CSS Stylesheet
47 *
48 * This stylesheet can be used to customize the appearance of epydoc's
49 * HTML output.
50 *
51 */
52
53/* Default Colors & Styles
54 *   - Set the default foreground & background color with 'body'; and
55 *     link colors with 'a:link' and 'a:visited'.
56 *   - Use bold for decision list terms.
57 *   - The heading styles defined here are used for headings *within*
58 *     docstring descriptions.  All headings used by epydoc itself use
59 *     either class='epydoc' or class='toc' (CSS styles for both
60 *     defined below).
61 */
62body                        { background: $body_bg; color: $body_fg; }
63p                           { margin-top: 0.5em; margin-bottom: 0.5em; }
64a:link                      { color: $body_link; }
65a:visited                   { color: $body_visited_link; }
66dt                          { font-weight: bold; }
67h1                          { font-size: +140%; font-style: italic;
68                              font-weight: bold; }
69h2                          { font-size: +125%; font-style: italic;
70                              font-weight: bold; }
71h3                          { font-size: +110%; font-style: italic;
72                              font-weight: normal; }
73code                        { font-size: 100%; }
74/* N.B.: class, not pseudoclass */
75a.link                      { font-family: monospace; }
76
77/* Page Header & Footer
78 *   - The standard page header consists of a navigation bar (with
79 *     pointers to standard pages such as 'home' and 'trees'); a
80 *     breadcrumbs list, which can be used to navigate to containing
81 *     classes or modules; options links, to show/hide private
82 *     variables and to show/hide frames; and a page title (using
83 *     <h1>).  The page title may be followed by a link to the
84 *     corresponding source code (using 'span.codelink').
85 *   - The footer consists of a navigation bar, a timestamp, and a
86 *     pointer to epydoc's homepage.
87 */
88h1.epydoc                   { margin: 0; font-size: +140%; font-weight: bold; }
89h2.epydoc                   { font-size: +130%; font-weight: bold; }
90h3.epydoc                   { font-size: +115%; font-weight: bold;
91                              margin-top: 0.2em; }
92td h3.epydoc                { font-size: +115%; font-weight: bold;
93                              margin-bottom: 0; }
94table.navbar                { background: $navbar_bg; color: $navbar_fg;
95                              border: $navbar_border; }
96table.navbar table          { color: $navbar_fg; }
97th.navbar-select            { background: $navbar_select_bg;
98                              color: $navbar_select_fg; }
99table.navbar a              { text-decoration: none; }
100table.navbar a:link         { color: $navbar_link; }
101table.navbar a:visited      { color: $navbar_visited_link; }
102span.breadcrumbs            { font-size: 85%; font-weight: bold; }
103span.options                { font-size: 70%; }
104span.codelink               { font-size: 85%; }
105td.footer                   { font-size: 85%; }
106
107/* Table Headers
108 *   - Each summary table and details section begins with a 'header'
109 *     row.  This row contains a section title (marked by
110 *     'span.table-header') as well as a show/hide private link
111 *     (marked by 'span.options', defined above).
112 *   - Summary tables that contain user-defined groups mark those
113 *     groups using 'group header' rows.
114 */
115td.table-header             { background: $table_hdr_bg; color: $table_hdr_fg;
116                              border: $table_border; }
117td.table-header table       { color: $table_hdr_fg; }
118td.table-header table a:link      { color: $table_hdr_link; }
119td.table-header table a:visited   { color: $table_hdr_visited_link; }
120span.table-header           { font-size: 120%; font-weight: bold; }
121th.group-header             { background: $group_hdr_bg; color: $group_hdr_fg;
122                              text-align: left; font-style: italic;
123                              font-size: 115%;
124                              border: $table_border; }
125
126/* Summary Tables (functions, variables, etc)
127 *   - Each object is described by a single row of the table with
128 *     two cells.  The left cell gives the object's type, and is
129 *     marked with 'code.summary-type'.  The right cell gives the
130 *     object's name and a summary description.
131 *   - CSS styles for the table's header and group headers are
132 *     defined above, under 'Table Headers'
133 */
134table.summary               { border-collapse: collapse;
135                              background: $table_bg; color: $table_fg;
136                              border: $table_border;
137                              margin-bottom: 0.5em; }
138td.summary                  { border: $table_border; }
139code.summary-type           { font-size: 85%; }
140table.summary a:link        { color: $table_link; }
141table.summary a:visited     { color: $table_visited_link; }
142
143
144/* Details Tables (functions, variables, etc)
145 *   - Each object is described in its own div.
146 *   - A single-row summary table w/ table-header is used as
147 *     a header for each details section (CSS style for table-header
148 *     is defined above, under 'Table Headers').
149 */
150table.details               { border-collapse: collapse;
151                              background: $table_bg; color: $table_fg;
152                              border: $table_border;
153                              margin: .2em 0 0 0; }
154table.details table         { color: $table_fg; }
155table.details a:link        { color: $table_link; }
156table.details a:visited     { color: $table_visited_link; }
157
158/* Fields */
159dl.fields                   { margin-left: 2em; margin-top: 1em;
160                              margin-bottom: 1em; }
161dl.fields dd ul             { margin-left: 0em; padding-left: 0em; }
162dl.fields dd ul li ul       { margin-left: 2em; padding-left: 0em; }
163div.fields                  { margin-left: 2em; }
164div.fields p                { margin-bottom: 0.5em; }
165
166/* Index tables (identifier index, term index, etc)
167 *   - link-index is used for indices containing lists of links
168 *     (namely, the identifier index & term index).
169 *   - index-where is used in link indices for the text indicating
170 *     the container/source for each link.
171 *   - metadata-index is used for indices containing metadata
172 *     extracted from fields (namely, the bug index & todo index).
173 */
174table.link-index            { border-collapse: collapse;
175                              background: $table_bg; color: $table_fg;
176                              border: $table_border; }
177td.link-index               { border-width: 0px; }
178table.link-index a:link     { color: $table_link; }
179table.link-index a:visited  { color: $table_visited_link; }
180span.index-where            { font-size: 70%; }
181table.metadata-index        { border-collapse: collapse;
182                              background: $table_bg; color: $table_fg;
183                              border: $table_border;
184                              margin: .2em 0 0 0; }
185td.metadata-index           { border-width: 1px; border-style: solid; }
186table.metadata-index a:link { color: $table_link; }
187table.metadata-index a:visited  { color: $table_visited_link; }
188
189/* Function signatures
190 *   - sig* is used for the signature in the details section.
191 *   - .summary-sig* is used for the signature in the summary
192 *     table, and when listing property accessor functions.
193 * */
194.sig-name                   { color: $sig_name; }
195.sig-arg                    { color: $sig_arg; }
196.sig-default                { color: $sig_default; }
197.summary-sig                { font-family: monospace; }
198.summary-sig-name           { color: $summary_sig_name; font-weight: bold; }
199table.summary a.summary-sig-name:link
200                            { color: $summary_sig_name; font-weight: bold; }
201table.summary a.summary-sig-name:visited
202                            { color: $summary_sig_name; font-weight: bold; }
203.summary-sig-arg            { color: $summary_sig_arg; }
204.summary-sig-default        { color: $summary_sig_default; }
205
206/* Subclass list
207 */
208ul.subclass-list { display: inline; }
209ul.subclass-list li { display: inline; }
210
211/* To render variables, classes etc. like functions */
212table.summary .summary-name { color: $summary_sig_name; font-weight: bold;
213                              font-family: monospace; }
214table.summary
215     a.summary-name:link    { color: $summary_sig_name; font-weight: bold;
216                              font-family: monospace; }
217table.summary
218    a.summary-name:visited  { color: $summary_sig_name; font-weight: bold;
219                              font-family: monospace; }
220
221/* Variable values
222 *   - In the 'variable details' sections, each varaible's value is
223 *     listed in a 'pre.variable' box.  The width of this box is
224 *     restricted to 80 chars; if the value's repr is longer than
225 *     this it will be wrapped, using a backslash marked with
226 *     class 'variable-linewrap'.  If the value's repr is longer
227 *     than 3 lines, the rest will be ellided; and an ellipsis
228 *     marker ('...' marked with 'variable-ellipsis') will be used.
229 *   - If the value is a string, its quote marks will be marked
230 *     with 'variable-quote'.
231 *   - If the variable is a regexp, it is syntax-highlighted using
232 *     the re* CSS classes.
233 */
234pre.variable                { padding: .5em; margin: 0;
235                              background: $variable_bg; color: $variable_fg;
236                              border: $variable_border; }
237.variable-linewrap          { color: $variable_linewrap; font-weight: bold; }
238.variable-ellipsis          { color: $variable_ellipsis; font-weight: bold; }
239.variable-quote             { color: $variable_quote; font-weight: bold; }
240.variable-group             { color: $variable_group; font-weight: bold; }
241.variable-op                { color: $variable_op; font-weight: bold; }
242.variable-string            { color: $variable_string; }
243.variable-unknown           { color: $variable_unknown; font-weight: bold; }
244.re                         { color: $re; }
245.re-char                    { color: $re_char; }
246.re-op                      { color: $re_op; }
247.re-group                   { color: $re_group; }
248.re-ref                     { color: $re_ref; }
249
250/* Base tree
251 *   - Used by class pages to display the base class hierarchy.
252 */
253pre.base-tree               { font-size: 80%; margin: 0; }
254
255/* Frames-based table of contents headers
256 *   - Consists of two frames: one for selecting modules; and
257 *     the other listing the contents of the selected module.
258 *   - h1.toc is used for each frame's heading
259 *   - h2.toc is used for subheadings within each frame.
260 */
261h1.toc                      { text-align: center; font-size: 105%;
262                              margin: 0; font-weight: bold;
263                              padding: 0; }
264h2.toc                      { font-size: 100%; font-weight: bold;
265                              margin: 0.5em 0 0 -0.3em; }
266
267/* Syntax Highlighting for Source Code
268 *   - doctest examples are displayed in a 'pre.py-doctest' block.
269 *     If the example is in a details table entry, then it will use
270 *     the colors specified by the 'table pre.py-doctest' line.
271 *   - Source code listings are displayed in a 'pre.py-src' block.
272 *     Each line is marked with 'span.py-line' (used to draw a line
273 *     down the left margin, separating the code from the line
274 *     numbers).  Line numbers are displayed with 'span.py-lineno'.
275 *     The expand/collapse block toggle button is displayed with
276 *     'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not
277 *     modify the font size of the text.)
278 *   - If a source code page is opened with an anchor, then the
279 *     corresponding code block will be highlighted.  The code
280 *     block's header is highlighted with 'py-highlight-hdr'; and
281 *     the code block's body is highlighted with 'py-highlight'.
282 *   - The remaining py-* classes are used to perform syntax
283 *     highlighting (py-string for string literals, py-name for names,
284 *     etc.)
285 */
286pre.py-doctest              { padding: .5em; margin: 1em;
287                              background: $doctest_bg; color: $doctest_fg;
288                              border: $doctest_border; }
289table pre.py-doctest        { background: $doctest_in_table_bg;
290                              color: $doctest_in_table_fg; }
291pre.py-src                  { border: $pysrc_border;
292                              background: $pysrc_bg; color: $pysrc_fg; }
293.py-line                    { border-left: $pysrc_sep_border;
294                              margin-left: .2em; padding-left: .4em; }
295.py-lineno                  { font-style: italic; font-size: 90%;
296                              padding-left: .5em; }
297a.py-toggle                 { text-decoration: none; }
298div.py-highlight-hdr        { border-top: $pysrc_border;
299                              border-bottom: $pysrc_border;
300                              background: $pysrc_highlight_hdr_bg; }
301div.py-highlight            { border-bottom: $pysrc_border;
302                              background: $pysrc_highlight_bg; }
303.py-prompt                  { color: $py_prompt; font-weight: bold;}
304.py-more                    { color: $py_more; font-weight: bold;}
305.py-string                  { color: $py_string; }
306.py-comment                 { color: $py_comment; }
307.py-keyword                 { color: $py_keyword; }
308.py-output                  { color: $py_output; }
309.py-name                    { color: $py_name; }
310.py-name:link               { color: $py_name !important; }
311.py-name:visited            { color: $py_name !important; }
312.py-number                  { color: $py_number; }
313.py-defname                 { color: $py_def_name; font-weight: bold; }
314.py-def-name                { color: $py_def_name; font-weight: bold; }
315.py-base-class              { color: $py_base_class; }
316.py-param                   { color: $py_param; }
317.py-docstring               { color: $py_docstring; }
318.py-decorator               { color: $py_decorator; }
319/* Use this if you don't want links to names underlined: */
320/*a.py-name                   { text-decoration: none; }*/
321
322/* Graphs & Diagrams
323 *   - These CSS styles are used for graphs & diagrams generated using
324 *     Graphviz dot.  'img.graph-without-title' is used for bare
325 *     diagrams (to remove the border created by making the image
326 *     clickable).
327 */
328img.graph-without-title     { border: none; }
329img.graph-with-title        { border: $graph_border; }
330span.graph-title            { font-weight: bold; }
331span.graph-caption          { }
332
333/* General-purpose classes
334 *   - 'p.indent-wrapped-lines' defines a paragraph whose first line
335 *     is not indented, but whose subsequent lines are.
336 *   - The 'nomargin-top' class is used to remove the top margin (e.g.
337 *     from lists).  The 'nomargin' class is used to remove both the
338 *     top and bottom margin (but not the left or right margin --
339 *     for lists, that would cause the bullets to disappear.)
340 */
341p.indent-wrapped-lines      { padding: 0 0 0 7em; text-indent: -7em;
342                              margin: 0; }
343.nomargin-top               { margin-top: 0; }
344.nomargin                   { margin-top: 0; margin-bottom: 0; }
345
346/* HTML Log */
347div.log-block               { padding: 0; margin: .5em 0 .5em 0;
348                              background: $log_bg; color: $log_fg;
349                              border: $log_border; }
350div.log-error               { padding: .1em .3em .1em .3em; margin: 4px;
351                              background: $log_error_bg; color: $log_error_fg;
352                              border: $log_error_border; }
353div.log-warning             { padding: .1em .3em .1em .3em; margin: 4px;
354                              background: $log_warn_bg; color: $log_warn_fg;
355                              border: $log_warn_border; }
356div.log-info               { padding: .1em .3em .1em .3em; margin: 4px;
357                              background: $log_info_bg; color: $log_info_fg;
358                              border: $log_info_border; }
359h2.log-hdr                  { background: $log_hdr_bg; color: $log_hdr_fg;
360                              margin: 0; padding: 0em 0.5em 0em 0.5em;
361                              border-bottom: $log_border; font-size: 110%; }
362p.log                       { font-weight: bold; margin: .5em 0 .5em 0; }
363tr.opt-changed              { color: $opt_changed_fg; font-weight: bold; }
364tr.opt-default              { color: $opt_default_fg; }
365pre.log                     { margin: 0; padding: 0; padding-left: 1em; }
366"""
367
368############################################################
369## Derived stylesheets
370############################################################
371# Use some simple manipulations to produce a wide variety of color
372# schemes.  In particular, use th _COLOR_RE regular expression to
373# search for colors, and to transform them in various ways.
374
375_COLOR_RE = re.compile(r'#(..)(..)(..)')
376
377def _set_colors(template, *dicts):
378    colors = dicts[0].copy()
379    for d in dicts[1:]: colors.update(d)
380    return re.sub(r'\$(\w+)', lambda m:colors[m.group(1)], template)
381
382def _rv(match):
383    """
384    Given a regexp match for a color, return the reverse-video version
385    of that color.
386
387    @param match: A regular expression match.
388    @type match: C{Match}
389    @return: The reverse-video color.
390    @rtype: C{string}
391    """
392    rgb = [int(grp, 16) for grp in match.groups()]
393    return '#' + ''.join(['%02x' % (255-c) for c in rgb])
394
395def _darken_darks(match):
396    rgb = [int(grp, 16) for grp in match.groups()]
397    return '#' + ''.join(['%02x' % (((c/255.)**2) * 255) for c in rgb])
398
399_WHITE_COLORS = dict(
400    # Defaults:
401    body_bg                 =  '#ffffff',
402    body_fg                 =  '#000000',
403    body_link               =  '#0000ff',
404    body_visited_link       =  '#204080',
405    # Navigation bar:
406    navbar_bg               =  '#a0c0ff',
407    navbar_fg               =  '#000000',
408    navbar_border           =  '2px groove #c0d0d0',
409    navbar_select_bg        =  '#70b0ff',
410    navbar_select_fg        =  '#000000',
411    navbar_link             =  '#0000ff',
412    navbar_visited_link     =  '#204080',
413    # Tables (summary tables, details tables, indices):
414    table_bg                =  '#e8f0f8',
415    table_fg                =  '#000000',
416    table_link              =  '#0000ff',
417    table_visited_link      =  '#204080',
418    table_border            =  '1px solid #608090',
419    table_hdr_bg            =  '#70b0ff',
420    table_hdr_fg            =  '#000000',
421    table_hdr_link          =  '#0000ff',
422    table_hdr_visited_link  =  '#204080',
423    group_hdr_bg            =  '#c0e0f8',
424    group_hdr_fg            =  '#000000',
425    # Function signatures:
426    sig_name                =  '#006080',
427    sig_arg                 =  '#008060',
428    sig_default             =  '#602000',
429    summary_sig_name        =  '#006080',
430    summary_sig_arg         =  '#006040',
431    summary_sig_default     =  '#501800',
432    # Variable values:
433    variable_bg             =  '#dce4ec',
434    variable_fg             =  '#000000',
435    variable_border         =  '1px solid #708890',
436    variable_linewrap       =  '#604000',
437    variable_ellipsis       =  '#604000',
438    variable_quote          =  '#604000',
439    variable_group          =  '#008000',
440    variable_string         =  '#006030',
441    variable_op             =  '#604000',
442    variable_unknown        =  '#a00000',
443    re                      =  '#000000',
444    re_char                 =  '#006030',
445    re_op                   =  '#600000',
446    re_group                =  '#003060',
447    re_ref                  =  '#404040',
448    # Python source code:
449    doctest_bg              =  '#e8f0f8',
450    doctest_fg              =  '#000000',
451    doctest_border          =  '1px solid #708890',
452    doctest_in_table_bg     =  '#dce4ec',
453    doctest_in_table_fg     =  '#000000',
454    pysrc_border            =  '2px solid #000000',
455    pysrc_sep_border        =  '2px solid #000000',
456    pysrc_bg                =  '#f0f0f0',
457    pysrc_fg                =  '#000000',
458    pysrc_highlight_hdr_bg  =  '#d8e8e8',
459    pysrc_highlight_bg      =  '#d0e0e0',
460    py_prompt               =  '#005050',
461    py_more                 =  '#005050',
462    py_string               =  '#006030',
463    py_comment              =  '#003060',
464    py_keyword              =  '#600000',
465    py_output               =  '#404040',
466    py_name                 =  '#000050',
467    py_number               =  '#005000',
468    py_def_name             =  '#000060',
469    py_base_class           =  '#000060',
470    py_param                =  '#000060',
471    py_docstring            =  '#006030',
472    py_decorator            =  '#804020',
473    # Graphs
474    graph_border            =  '1px solid #000000',
475    # Log block
476    log_bg                  =  '#e8f0f8',
477    log_fg                  =  '#000000',
478    log_border              =  '1px solid #000000',
479    log_hdr_bg              =  '#70b0ff',
480    log_hdr_fg              =  '#000000',
481    log_error_bg            =  '#ffb0b0',
482    log_error_fg            =  '#000000',
483    log_error_border        =  '1px solid #000000',
484    log_warn_bg             =  '#ffffb0',
485    log_warn_fg             =  '#000000',
486    log_warn_border         =  '1px solid #000000',
487    log_info_bg             =  '#b0ffb0',
488    log_info_fg             =  '#000000',
489    log_info_border         =  '1px solid #000000',
490    opt_changed_fg          =  '#000000',
491    opt_default_fg          =  '#606060',
492    )
493
494_BLUE_COLORS = _WHITE_COLORS.copy()
495_BLUE_COLORS.update(dict(
496    # Body: white text on a dark blue background
497    body_bg                 =  '#000070',
498    body_fg                 =  '#ffffff',
499    body_link               =  '#ffffff',
500    body_visited_link       =  '#d0d0ff',
501    # Tables: cyan headers, black on white bodies
502    table_bg                =   '#ffffff',
503    table_fg                =  '#000000',
504    table_hdr_bg            =  '#70b0ff',
505    table_hdr_fg            =  '#000000',
506    table_hdr_link          =  '#000000',
507    table_hdr_visited_link  =  '#000000',
508    table_border            =  '1px solid #000000',
509    # Navigation bar: blue w/ cyan selection
510    navbar_bg               =  '#0000ff',
511    navbar_fg               =  '#ffffff',
512    navbar_link             =  '#ffffff',
513    navbar_visited_link     =  '#ffffff',
514    navbar_select_bg        =   '#70b0ff',
515    navbar_select_fg        =   '#000000',
516    navbar_border           =  '1px solid #70b0ff',
517    # Variable values & doctest blocks: cyan
518    variable_bg             =   '#c0e0f8',
519    variable_fg             =  '#000000',
520    doctest_bg              =   '#c0e0f8',
521    doctest_fg              =  '#000000',
522    doctest_in_table_bg     =   '#c0e0f8',
523    doctest_in_table_fg     =  '#000000',
524    ))
525
526_WHITE = _set_colors(TEMPLATE, _WHITE_COLORS)
527_BLUE = _set_colors(TEMPLATE, _BLUE_COLORS)
528
529    # Black-on-green
530_GREEN = _COLOR_RE.sub(_darken_darks, _COLOR_RE.sub(r'#\1\3\2', _BLUE))
531
532# White-on-black, with blue highlights.
533_BLACK = _COLOR_RE.sub(r'#\3\2\1', _COLOR_RE.sub(_rv, _WHITE))
534
535# Grayscale
536_GRAYSCALE = _COLOR_RE.sub(r'#\2\2\2', _WHITE)
537
538############################################################
539## Stylesheet table
540############################################################
541
542STYLESHEETS = {
543    'white': (_WHITE, "Black on white, with blue highlights"),
544    'blue': (_BLUE, "Black on steel blue"),
545    'green': (_GREEN, "Black on green"),
546    'black': (_BLACK, "White on black, with blue highlights"),
547    'grayscale': (_GRAYSCALE, "Grayscale black on white"),
548    'default': (_WHITE, "Default stylesheet (=white)"),
549#    'none': (_LAYOUT, "A base stylesheet (no color modifications)"),
550    }
551