1
2
3
4
5
6
7
8
9 """
10 Predefined 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
27 import re
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 TEMPLATE = r"""
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 */
62 body { background: $body_bg; color: $body_fg; }
63 p { margin-top: 0.5em; margin-bottom: 0.5em; }
64 a:link { color: $body_link; }
65 a:visited { color: $body_visited_link; }
66 dt { font-weight: bold; }
67 h1 { font-size: +140%; font-style: italic;
68 font-weight: bold; }
69 h2 { font-size: +125%; font-style: italic;
70 font-weight: bold; }
71 h3 { font-size: +110%; font-style: italic;
72 font-weight: normal; }
73 code { font-size: 100%; }
74 /* N.B.: class, not pseudoclass */
75 a.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 */
88 h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; }
89 h2.epydoc { font-size: +130%; font-weight: bold; }
90 h3.epydoc { font-size: +115%; font-weight: bold;
91 margin-top: 0.2em; }
92 td h3.epydoc { font-size: +115%; font-weight: bold;
93 margin-bottom: 0; }
94 table.navbar { background: $navbar_bg; color: $navbar_fg;
95 border: $navbar_border; }
96 table.navbar table { color: $navbar_fg; }
97 th.navbar-select { background: $navbar_select_bg;
98 color: $navbar_select_fg; }
99 table.navbar a { text-decoration: none; }
100 table.navbar a:link { color: $navbar_link; }
101 table.navbar a:visited { color: $navbar_visited_link; }
102 span.breadcrumbs { font-size: 85%; font-weight: bold; }
103 span.options { font-size: 70%; }
104 span.codelink { font-size: 85%; }
105 td.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 */
115 td.table-header { background: $table_hdr_bg; color: $table_hdr_fg;
116 border: $table_border; }
117 td.table-header table { color: $table_hdr_fg; }
118 td.table-header table a:link { color: $table_hdr_link; }
119 td.table-header table a:visited { color: $table_hdr_visited_link; }
120 span.table-header { font-size: 120%; font-weight: bold; }
121 th.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 */
134 table.summary { border-collapse: collapse;
135 background: $table_bg; color: $table_fg;
136 border: $table_border;
137 margin-bottom: 0.5em; }
138 td.summary { border: $table_border; }
139 code.summary-type { font-size: 85%; }
140 table.summary a:link { color: $table_link; }
141 table.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 */
150 table.details { border-collapse: collapse;
151 background: $table_bg; color: $table_fg;
152 border: $table_border;
153 margin: .2em 0 0 0; }
154 table.details table { color: $table_fg; }
155 table.details a:link { color: $table_link; }
156 table.details a:visited { color: $table_visited_link; }
157
158 /* Fields */
159 dl.fields { margin-left: 2em; margin-top: 1em;
160 margin-bottom: 1em; }
161 dl.fields dd ul { margin-left: 0em; padding-left: 0em; }
162 dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; }
163 div.fields { margin-left: 2em; }
164 div.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 */
174 table.link-index { border-collapse: collapse;
175 background: $table_bg; color: $table_fg;
176 border: $table_border; }
177 td.link-index { border-width: 0px; }
178 table.link-index a:link { color: $table_link; }
179 table.link-index a:visited { color: $table_visited_link; }
180 span.index-where { font-size: 70%; }
181 table.metadata-index { border-collapse: collapse;
182 background: $table_bg; color: $table_fg;
183 border: $table_border;
184 margin: .2em 0 0 0; }
185 td.metadata-index { border-width: 1px; border-style: solid; }
186 table.metadata-index a:link { color: $table_link; }
187 table.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; }
199 table.summary a.summary-sig-name:link
200 { color: $summary_sig_name; font-weight: bold; }
201 table.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 */
208 ul.subclass-list { display: inline; margin: 0; padding: 0; }
209 ul.subclass-list li { display: inline; margin: 0; padding: 0; }
210
211 /* To render variables, classes etc. like functions */
212 table.summary .summary-name { color: $summary_sig_name; font-weight: bold;
213 font-family: monospace; }
214 table.summary
215 a.summary-name:link { color: $summary_sig_name; font-weight: bold;
216 font-family: monospace; }
217 table.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 */
234 pre.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 */
253 pre.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 */
261 h1.toc { text-align: center; font-size: 105%;
262 margin: 0; font-weight: bold;
263 padding: 0; }
264 h2.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 */
286 pre.py-doctest { padding: .5em; margin: 1em;
287 background: $doctest_bg; color: $doctest_fg;
288 border: $doctest_border; }
289 table pre.py-doctest { background: $doctest_in_table_bg;
290 color: $doctest_in_table_fg; }
291 pre.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; }
297 a.py-toggle { text-decoration: none; }
298 div.py-highlight-hdr { border-top: $pysrc_border;
299 border-bottom: $pysrc_border;
300 background: $pysrc_highlight_hdr_bg; }
301 div.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 */
328 img.graph-without-title { border: none; }
329 img.graph-with-title { border: $graph_border; }
330 span.graph-title { font-weight: bold; }
331 span.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 */
341 p.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 */
347 div.log-block { padding: 0; margin: .5em 0 .5em 0;
348 background: $log_bg; color: $log_fg;
349 border: $log_border; }
350 div.log-error { padding: .1em .3em .1em .3em; margin: 4px;
351 background: $log_error_bg; color: $log_error_fg;
352 border: $log_error_border; }
353 div.log-warning { padding: .1em .3em .1em .3em; margin: 4px;
354 background: $log_warn_bg; color: $log_warn_fg;
355 border: $log_warn_border; }
356 div.log-info { padding: .1em .3em .1em .3em; margin: 4px;
357 background: $log_info_bg; color: $log_info_fg;
358 border: $log_info_border; }
359 h2.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%; }
362 p.log { font-weight: bold; margin: .5em 0 .5em 0; }
363 tr.opt-changed { color: $opt_changed_fg; font-weight: bold; }
364 tr.opt-default { color: $opt_default_fg; }
365 pre.log { margin: 0; padding: 0; padding-left: 1em; }
366 """
367
368
369
370
371
372
373
374
375 _COLOR_RE = re.compile(r'#(..)(..)(..)')
376
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
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
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
401 body_bg = '#ffffff',
402 body_fg = '#000000',
403 body_link = '#0000ff',
404 body_visited_link = '#204080',
405
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
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
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
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
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
474 graph_border = '1px solid #000000',
475
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
497 body_bg = '#000070',
498 body_fg = '#ffffff',
499 body_link = '#ffffff',
500 body_visited_link = '#d0d0ff',
501
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
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
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
530 _GREEN = _COLOR_RE.sub(_darken_darks, _COLOR_RE.sub(r'#\1\3\2', _BLUE))
531
532
533 _BLACK = _COLOR_RE.sub(r'#\3\2\1', _COLOR_RE.sub(_rv, _WHITE))
534
535
536 _GRAYSCALE = _COLOR_RE.sub(r'#\2\2\2', _WHITE)
537
538
539
540
541
542 STYLESHEETS = {
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
550 }
551