# # epydoc.css: default epydoc CSS stylesheets # Edward Loper # # Created [01/30/01 05:18 PM] # $Id: html_css.py 1634 2007-09-24 15:58:38Z dvarrazzo $ # """ Predefined CSS stylesheets for the HTML outputter (L{epydoc.docwriter.html}). @type STYLESHEETS: C{dictionary} from C{string} to C{(string, string)} @var STYLESHEETS: A dictionary mapping from stylesheet names to CSS stylesheets and descriptions. A single stylesheet may have multiple names. Currently, the following stylesheets are defined: - C{default}: The default stylesheet (synonym for C{white}). - C{white}: Black on white, with blue highlights (similar to javadoc). - C{blue}: Black on steel blue. - C{green}: Black on green. - C{black}: White on black, with blue highlights - C{grayscale}: Grayscale black on white. - C{none}: An empty stylesheet. """ __docformat__ = 'epytext en' import re ############################################################ ## Basic stylesheets ############################################################ # [xx] Should I do something like: # # @import url(html4css1.css); # # But then where do I get that css file from? Hm. # Also, in principle I'm mangling classes, but it looks like I'm # failing. # # Black on white, with blue highlights. This is similar to how # javadoc looks. TEMPLATE = """ /* Epydoc CSS Stylesheet * * This stylesheet can be used to customize the appearance of epydoc's * HTML output. * */ /* Default Colors & Styles * - Set the default foreground & background color with 'body'; and * link colors with 'a:link' and 'a:visited'. * - Use bold for decision list terms. * - The heading styles defined here are used for headings *within* * docstring descriptions. All headings used by epydoc itself use * either class='epydoc' or class='toc' (CSS styles for both * defined below). */ body { background: $body_bg; color: $body_fg; } p { margin-top: 0.5em; margin-bottom: 0.5em; } a:link { color: $body_link; } a:visited { color: $body_visited_link; } dt { font-weight: bold; } h1 { font-size: +140%; font-style: italic; font-weight: bold; } h2 { font-size: +125%; font-style: italic; font-weight: bold; } h3 { font-size: +110%; font-style: italic; font-weight: normal; } code { font-size: 100%; } /* N.B.: class, not pseudoclass */ a.link { font-family: monospace; } /* Page Header & Footer * - The standard page header consists of a navigation bar (with * pointers to standard pages such as 'home' and 'trees'); a * breadcrumbs list, which can be used to navigate to containing * classes or modules; options links, to show/hide private * variables and to show/hide frames; and a page title (using *

). The page title may be followed by a link to the * corresponding source code (using 'span.codelink'). * - The footer consists of a navigation bar, a timestamp, and a * pointer to epydoc's homepage. */ h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } h2.epydoc { font-size: +130%; font-weight: bold; } h3.epydoc { font-size: +115%; font-weight: bold; margin-top: 0.2em; } td h3.epydoc { font-size: +115%; font-weight: bold; margin-bottom: 0; } table.navbar { background: $navbar_bg; color: $navbar_fg; border: $navbar_border; } table.navbar table { color: $navbar_fg; } th.navbar-select { background: $navbar_select_bg; color: $navbar_select_fg; } table.navbar a { text-decoration: none; } table.navbar a:link { color: $navbar_link; } table.navbar a:visited { color: $navbar_visited_link; } span.breadcrumbs { font-size: 85%; font-weight: bold; } span.options { font-size: 70%; } span.codelink { font-size: 85%; } td.footer { font-size: 85%; } /* Table Headers * - Each summary table and details section begins with a 'header' * row. This row contains a section title (marked by * 'span.table-header') as well as a show/hide private link * (marked by 'span.options', defined above). * - Summary tables that contain user-defined groups mark those * groups using 'group header' rows. */ td.table-header { background: $table_hdr_bg; color: $table_hdr_fg; border: $table_border; } td.table-header table { color: $table_hdr_fg; } td.table-header table a:link { color: $table_hdr_link; } td.table-header table a:visited { color: $table_hdr_visited_link; } span.table-header { font-size: 120%; font-weight: bold; } th.group-header { background: $group_hdr_bg; color: $group_hdr_fg; text-align: left; font-style: italic; font-size: 115%; border: $table_border; } /* Summary Tables (functions, variables, etc) * - Each object is described by a single row of the table with * two cells. The left cell gives the object's type, and is * marked with 'code.summary-type'. The right cell gives the * object's name and a summary description. * - CSS styles for the table's header and group headers are * defined above, under 'Table Headers' */ table.summary { border-collapse: collapse; background: $table_bg; color: $table_fg; border: $table_border; margin-bottom: 0.5em; } td.summary { border: $table_border; } code.summary-type { font-size: 85%; } table.summary a:link { color: $table_link; } table.summary a:visited { color: $table_visited_link; } /* Details Tables (functions, variables, etc) * - Each object is described in its own div. * - A single-row summary table w/ table-header is used as * a header for each details section (CSS style for table-header * is defined above, under 'Table Headers'). */ table.details { border-collapse: collapse; background: $table_bg; color: $table_fg; border: $table_border; margin: .2em 0 0 0; } table.details table { color: $table_fg; } table.details a:link { color: $table_link; } table.details a:visited { color: $table_visited_link; } /* Fields */ dl.fields { margin-left: 2em; margin-top: 1em; margin-bottom: 1em; } dl.fields dd ul { margin-left: 0em; padding-left: 0em; } dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } div.fields { margin-left: 2em; } div.fields p { margin-bottom: 0.5em; } /* Index tables (identifier index, term index, etc) * - link-index is used for indices containing lists of links * (namely, the identifier index & term index). * - index-where is used in link indices for the text indicating * the container/source for each link. * - metadata-index is used for indices containing metadata * extracted from fields (namely, the bug index & todo index). */ table.link-index { border-collapse: collapse; background: $table_bg; color: $table_fg; border: $table_border; } td.link-index { border-width: 0px; } table.link-index a:link { color: $table_link; } table.link-index a:visited { color: $table_visited_link; } span.index-where { font-size: 70%; } table.metadata-index { border-collapse: collapse; background: $table_bg; color: $table_fg; border: $table_border; margin: .2em 0 0 0; } td.metadata-index { border-width: 1px; border-style: solid; } table.metadata-index a:link { color: $table_link; } table.metadata-index a:visited { color: $table_visited_link; } /* Function signatures * - sig* is used for the signature in the details section. * - .summary-sig* is used for the signature in the summary * table, and when listing property accessor functions. * */ .sig-name { color: $sig_name; } .sig-arg { color: $sig_arg; } .sig-default { color: $sig_default; } .summary-sig { font-family: monospace; } .summary-sig-name { color: $summary_sig_name; font-weight: bold; } table.summary a.summary-sig-name:link { color: $summary_sig_name; font-weight: bold; } table.summary a.summary-sig-name:visited { color: $summary_sig_name; font-weight: bold; } .summary-sig-arg { color: $summary_sig_arg; } .summary-sig-default { color: $summary_sig_default; } /* Subclass list */ ul.subclass-list { display: inline; } ul.subclass-list li { display: inline; } /* To render variables, classes etc. like functions */ table.summary .summary-name { color: $summary_sig_name; font-weight: bold; font-family: monospace; } table.summary a.summary-name:link { color: $summary_sig_name; font-weight: bold; font-family: monospace; } table.summary a.summary-name:visited { color: $summary_sig_name; font-weight: bold; font-family: monospace; } /* Variable values * - In the 'variable details' sections, each varaible's value is * listed in a 'pre.variable' box. The width of this box is * restricted to 80 chars; if the value's repr is longer than * this it will be wrapped, using a backslash marked with * class 'variable-linewrap'. If the value's repr is longer * than 3 lines, the rest will be ellided; and an ellipsis * marker ('...' marked with 'variable-ellipsis') will be used. * - If the value is a string, its quote marks will be marked * with 'variable-quote'. * - If the variable is a regexp, it is syntax-highlighted using * the re* CSS classes. */ pre.variable { padding: .5em; margin: 0; background: $variable_bg; color: $variable_fg; border: $variable_border; } .variable-linewrap { color: $variable_linewrap; font-weight: bold; } .variable-ellipsis { color: $variable_ellipsis; font-weight: bold; } .variable-quote { color: $variable_quote; font-weight: bold; } .variable-group { color: $variable_group; font-weight: bold; } .variable-op { color: $variable_op; font-weight: bold; } .variable-string { color: $variable_string; } .variable-unknown { color: $variable_unknown; font-weight: bold; } .re { color: $re; } .re-char { color: $re_char; } .re-op { color: $re_op; } .re-group { color: $re_group; } .re-ref { color: $re_ref; } /* Base tree * - Used by class pages to display the base class hierarchy. */ pre.base-tree { font-size: 80%; margin: 0; } /* Frames-based table of contents headers * - Consists of two frames: one for selecting modules; and * the other listing the contents of the selected module. * - h1.toc is used for each frame's heading * - h2.toc is used for subheadings within each frame. */ h1.toc { text-align: center; font-size: 105%; margin: 0; font-weight: bold; padding: 0; } h2.toc { font-size: 100%; font-weight: bold; margin: 0.5em 0 0 -0.3em; } /* Syntax Highlighting for Source Code * - doctest examples are displayed in a 'pre.py-doctest' block. * If the example is in a details table entry, then it will use * the colors specified by the 'table pre.py-doctest' line. * - Source code listings are displayed in a 'pre.py-src' block. * Each line is marked with 'span.py-line' (used to draw a line * down the left margin, separating the code from the line * numbers). Line numbers are displayed with 'span.py-lineno'. * The expand/collapse block toggle button is displayed with * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not * modify the font size of the text.) * - If a source code page is opened with an anchor, then the * corresponding code block will be highlighted. The code * block's header is highlighted with 'py-highlight-hdr'; and * the code block's body is highlighted with 'py-highlight'. * - The remaining py-* classes are used to perform syntax * highlighting (py-string for string literals, py-name for names, * etc.) */ pre.py-doctest { padding: .5em; margin: 1em; background: $doctest_bg; color: $doctest_fg; border: $doctest_border; } table pre.py-doctest { background: $doctest_in_table_bg; color: $doctest_in_table_fg; } pre.py-src { border: $pysrc_border; background: $pysrc_bg; color: $pysrc_fg; } .py-line { border-left: $pysrc_sep_border; margin-left: .2em; padding-left: .4em; } .py-lineno { font-style: italic; font-size: 90%; padding-left: .5em; } a.py-toggle { text-decoration: none; } div.py-highlight-hdr { border-top: $pysrc_border; border-bottom: $pysrc_border; background: $pysrc_highlight_hdr_bg; } div.py-highlight { border-bottom: $pysrc_border; background: $pysrc_highlight_bg; } .py-prompt { color: $py_prompt; font-weight: bold;} .py-more { color: $py_more; font-weight: bold;} .py-string { color: $py_string; } .py-comment { color: $py_comment; } .py-keyword { color: $py_keyword; } .py-output { color: $py_output; } .py-name { color: $py_name; } .py-name:link { color: $py_name !important; } .py-name:visited { color: $py_name !important; } .py-number { color: $py_number; } .py-defname { color: $py_def_name; font-weight: bold; } .py-def-name { color: $py_def_name; font-weight: bold; } .py-base-class { color: $py_base_class; } .py-param { color: $py_param; } .py-docstring { color: $py_docstring; } .py-decorator { color: $py_decorator; } /* Use this if you don't want links to names underlined: */ /*a.py-name { text-decoration: none; }*/ /* Graphs & Diagrams * - These CSS styles are used for graphs & diagrams generated using * Graphviz dot. 'img.graph-without-title' is used for bare * diagrams (to remove the border created by making the image * clickable). */ img.graph-without-title { border: none; } img.graph-with-title { border: $graph_border; } span.graph-title { font-weight: bold; } span.graph-caption { } /* General-purpose classes * - 'p.indent-wrapped-lines' defines a paragraph whose first line * is not indented, but whose subsequent lines are. * - The 'nomargin-top' class is used to remove the top margin (e.g. * from lists). The 'nomargin' class is used to remove both the * top and bottom margin (but not the left or right margin -- * for lists, that would cause the bullets to disappear.) */ p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; margin: 0; } .nomargin-top { margin-top: 0; } .nomargin { margin-top: 0; margin-bottom: 0; } /* HTML Log */ div.log-block { padding: 0; margin: .5em 0 .5em 0; background: $log_bg; color: $log_fg; border: $log_border; } div.log-error { padding: .1em .3em .1em .3em; margin: 4px; background: $log_error_bg; color: $log_error_fg; border: $log_error_border; } div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; background: $log_warn_bg; color: $log_warn_fg; border: $log_warn_border; } div.log-info { padding: .1em .3em .1em .3em; margin: 4px; background: $log_info_bg; color: $log_info_fg; border: $log_info_border; } h2.log-hdr { background: $log_hdr_bg; color: $log_hdr_fg; margin: 0; padding: 0em 0.5em 0em 0.5em; border-bottom: $log_border; font-size: 110%; } p.log { font-weight: bold; margin: .5em 0 .5em 0; } tr.opt-changed { color: $opt_changed_fg; font-weight: bold; } tr.opt-default { color: $opt_default_fg; } pre.log { margin: 0; padding: 0; padding-left: 1em; } """ ############################################################ ## Derived stylesheets ############################################################ # Use some simple manipulations to produce a wide variety of color # schemes. In particular, use th _COLOR_RE regular expression to # search for colors, and to transform them in various ways. _COLOR_RE = re.compile(r'#(..)(..)(..)') def _set_colors(template, *dicts): colors = dicts[0].copy() for d in dicts[1:]: colors.update(d) return re.sub(r'\$(\w+)', lambda m:colors[m.group(1)], template) def _rv(match): """ Given a regexp match for a color, return the reverse-video version of that color. @param match: A regular expression match. @type match: C{Match} @return: The reverse-video color. @rtype: C{string} """ rgb = [int(grp, 16) for grp in match.groups()] return '#' + ''.join(['%02x' % (255-c) for c in rgb]) def _darken_darks(match): rgb = [int(grp, 16) for grp in match.groups()] return '#' + ''.join(['%02x' % (((c/255.)**2) * 255) for c in rgb]) _WHITE_COLORS = dict( # Defaults: body_bg = '#ffffff', body_fg = '#000000', body_link = '#0000ff', body_visited_link = '#204080', # Navigation bar: navbar_bg = '#a0c0ff', navbar_fg = '#000000', navbar_border = '2px groove #c0d0d0', navbar_select_bg = '#70b0ff', navbar_select_fg = '#000000', navbar_link = '#0000ff', navbar_visited_link = '#204080', # Tables (summary tables, details tables, indices): table_bg = '#e8f0f8', table_fg = '#000000', table_link = '#0000ff', table_visited_link = '#204080', table_border = '1px solid #608090', table_hdr_bg = '#70b0ff', table_hdr_fg = '#000000', table_hdr_link = '#0000ff', table_hdr_visited_link = '#204080', group_hdr_bg = '#c0e0f8', group_hdr_fg = '#000000', # Function signatures: sig_name = '#006080', sig_arg = '#008060', sig_default = '#602000', summary_sig_name = '#006080', summary_sig_arg = '#006040', summary_sig_default = '#501800', # Variable values: variable_bg = '#dce4ec', variable_fg = '#000000', variable_border = '1px solid #708890', variable_linewrap = '#604000', variable_ellipsis = '#604000', variable_quote = '#604000', variable_group = '#008000', variable_string = '#006030', variable_op = '#604000', variable_unknown = '#a00000', re = '#000000', re_char = '#006030', re_op = '#600000', re_group = '#003060', re_ref = '#404040', # Python source code: doctest_bg = '#e8f0f8', doctest_fg = '#000000', doctest_border = '1px solid #708890', doctest_in_table_bg = '#dce4ec', doctest_in_table_fg = '#000000', pysrc_border = '2px solid #000000', pysrc_sep_border = '2px solid #000000', pysrc_bg = '#f0f0f0', pysrc_fg = '#000000', pysrc_highlight_hdr_bg = '#d8e8e8', pysrc_highlight_bg = '#d0e0e0', py_prompt = '#005050', py_more = '#005050', py_string = '#006030', py_comment = '#003060', py_keyword = '#600000', py_output = '#404040', py_name = '#000050', py_number = '#005000', py_def_name = '#000060', py_base_class = '#000060', py_param = '#000060', py_docstring = '#006030', py_decorator = '#804020', # Graphs graph_border = '1px solid #000000', # Log block log_bg = '#e8f0f8', log_fg = '#000000', log_border = '1px solid #000000', log_hdr_bg = '#70b0ff', log_hdr_fg = '#000000', log_error_bg = '#ffb0b0', log_error_fg = '#000000', log_error_border = '1px solid #000000', log_warn_bg = '#ffffb0', log_warn_fg = '#000000', log_warn_border = '1px solid #000000', log_info_bg = '#b0ffb0', log_info_fg = '#000000', log_info_border = '1px solid #000000', opt_changed_fg = '#000000', opt_default_fg = '#606060', ) _BLUE_COLORS = _WHITE_COLORS.copy() _BLUE_COLORS.update(dict( # Body: white text on a dark blue background body_bg = '#000070', body_fg = '#ffffff', body_link = '#ffffff', body_visited_link = '#d0d0ff', # Tables: cyan headers, black on white bodies table_bg = '#ffffff', table_fg = '#000000', table_hdr_bg = '#70b0ff', table_hdr_fg = '#000000', table_hdr_link = '#000000', table_hdr_visited_link = '#000000', table_border = '1px solid #000000', # Navigation bar: blue w/ cyan selection navbar_bg = '#0000ff', navbar_fg = '#ffffff', navbar_link = '#ffffff', navbar_visited_link = '#ffffff', navbar_select_bg = '#70b0ff', navbar_select_fg = '#000000', navbar_border = '1px solid #70b0ff', # Variable values & doctest blocks: cyan variable_bg = '#c0e0f8', variable_fg = '#000000', doctest_bg = '#c0e0f8', doctest_fg = '#000000', doctest_in_table_bg = '#c0e0f8', doctest_in_table_fg = '#000000', )) _WHITE = _set_colors(TEMPLATE, _WHITE_COLORS) _BLUE = _set_colors(TEMPLATE, _BLUE_COLORS) # Black-on-green _GREEN = _COLOR_RE.sub(_darken_darks, _COLOR_RE.sub(r'#\1\3\2', _BLUE)) # White-on-black, with blue highlights. _BLACK = _COLOR_RE.sub(r'#\3\2\1', _COLOR_RE.sub(_rv, _WHITE)) # Grayscale _GRAYSCALE = _COLOR_RE.sub(r'#\2\2\2', _WHITE) ############################################################ ## Stylesheet table ############################################################ STYLESHEETS = { 'white': (_WHITE, "Black on white, with blue highlights"), 'blue': (_BLUE, "Black on steel blue"), 'green': (_GREEN, "Black on green"), 'black': (_BLACK, "White on black, with blue highlights"), 'grayscale': (_GRAYSCALE, "Grayscale black on white"), 'default': (_WHITE, "Default stylesheet (=white)"), # 'none': (_LAYOUT, "A base stylesheet (no color modifications)"), }