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