#
# epydoc -- HTML output generator
# Edward Loper
#
# Created [01/30/01 05:18 PM]
# $Id: html.py 1674 2008-01-29 06:03:36Z edloper $
#

"""
The HTML output generator for epydoc.  The main interface provided by
this module is the L{HTMLWriter} class.

@todo: Add a cache to L{HTMLWriter.url()}?
"""
__docformat__ = 'epytext en'

import re, os, sys, codecs, sre_constants, pprint, base64
import urllib
import __builtin__
from epydoc.apidoc import *
import epydoc.docstringparser
import time, epydoc, epydoc.markup, epydoc.markup.epytext
from epydoc.docwriter.html_colorize import PythonSourceColorizer
from epydoc.docwriter import html_colorize
from epydoc.docwriter.html_css import STYLESHEETS
from epydoc.docwriter.html_help import HTML_HELP
from epydoc.docwriter.dotgraph import *
from epydoc import log
from epydoc.util import plaintext_to_html, is_src_filename
from epydoc.compat import * # Backwards compatibility

######################################################################
## Template Compiler
######################################################################
# The compile_template() method defined in this section is used to
# define several of HTMLWriter's methods.

def compile_template(docstring, template_string,
                     output_function='out', debug=epydoc.DEBUG):
    """
    Given a template string containing inline python source code,
    return a python function that will fill in the template, and
    output the result.  The signature for this function is taken from
    the first line of C{docstring}.  Output is generated by making
    repeated calls to the output function with the given name (which
    is typically one of the function's parameters).

    The templating language used by this function passes through all
    text as-is, with three exceptions:

      - If every line in the template string is indented by at least
        M{x} spaces, then the first M{x} spaces are stripped from each
        line.

      - Any line that begins with '>>>' (with no indentation)
        should contain python code, and will be inserted as-is into
        the template-filling function.  If the line begins a control
        block (such as 'if' or 'for'), then the control block will
        be closed by the first '>>>'-marked line whose indentation is
        less than or equal to the line's own indentation (including
        lines that only contain comments.)

      - In any other line, any expression between two '$' signs will
        be evaluated and inserted into the line (using C{str()} to
        convert the result to a string).

    Here is a simple example:

        >>> TEMPLATE = '''
        ... <book>
        ...   <title>$book.title$</title>
        ...   <pages>$book.count_pages()$</pages>
        ... >>> for chapter in book.chapters:
        ...     <chaptername>$chapter.name$</chaptername>
        ... >>> #endfor
        ... </book>
        >>> write_book = compile_template('write_book(out, book)', TEMPLATE)

    @newfield acknowledgements: Acknowledgements
    @acknowledgements: The syntax used by C{compile_template} is
    loosely based on Cheetah.
    """
    # Extract signature from the docstring:
    signature = docstring.lstrip().split('\n',1)[0].strip()
    func_name = signature.split('(',1)[0].strip()

    # Regexp to search for inline substitutions:
    INLINE = re.compile(r'\$([^\$]+)\$')
    # Regexp to search for python statements in the template:
    COMMAND = re.compile(r'(^>>>.*)\n?', re.MULTILINE)

    # Strip indentation from the template.
    template_string = strip_indent(template_string)

    # If we're debugging, then we'll store the generated function,
    # so we can print it along with any tracebacks that depend on it.
    if debug:
        signature = re.sub(r'\)\s*$', ', __debug=__debug)', signature)

    # Funciton declaration line
    pysrc_lines = ['def %s:' % signature]
    indents = [-1]

    if debug:
        pysrc_lines.append('    try:')
        indents.append(-1)

    commands = COMMAND.split(template_string.strip()+'\n')
    for i, command in enumerate(commands):
        if command == '': continue

        # String literal segment:
        if i%2 == 0:
            pieces = INLINE.split(command)
            for j, piece in enumerate(pieces):
                if j%2 == 0:
                    # String piece
                    pysrc_lines.append('    '*len(indents)+
                                 '%s(%r)' % (output_function, piece))
                else:
                    # Variable piece
                    pysrc_lines.append('    '*len(indents)+
                                 '%s(unicode(%s))' % (output_function, piece))

        # Python command:
        else:
            srcline = command[3:].lstrip()
            # Update indentation
            indent = len(command)-len(srcline)
            while indent <= indents[-1]: indents.pop()
            # Add on the line.
            srcline = srcline.rstrip()
            pysrc_lines.append('    '*len(indents)+srcline)
            if srcline.endswith(':'):
                indents.append(indent)
        
    if debug:
        pysrc_lines.append('    except Exception,e:')
        pysrc_lines.append('        pysrc, func_name = __debug ')
        pysrc_lines.append('        lineno = sys.exc_info()[2].tb_lineno')
        pysrc_lines.append('        print ("Exception in template %s() on "')
        pysrc_lines.append('               "line %d:" % (func_name, lineno))')
        pysrc_lines.append('        print pysrc[lineno-1]')
        pysrc_lines.append('        raise')
        
    pysrc = '\n'.join(pysrc_lines)+'\n'
    #log.debug(pysrc)
    if debug: localdict = {'__debug': (pysrc_lines, func_name)}
    else: localdict = {}
    try: exec pysrc in globals(), localdict
    except SyntaxError:
        log.error('Error in script:\n' + pysrc + '\n')
        raise
    template_func = localdict[func_name]
    template_func.__doc__ = docstring
    return template_func
    
def strip_indent(s):
    """
    Given a multiline string C{s}, find the minimum indentation for
    all non-blank lines, and return a new string formed by stripping
    that amount of indentation from all lines in C{s}.
    """
    # Strip indentation from the template.
    minindent = sys.maxint
    lines = s.split('\n')
    for line in lines:
        stripline = line.lstrip()
        if stripline:
            minindent = min(minindent, len(line)-len(stripline))
    return '\n'.join([l[minindent:] for l in lines])

######################################################################
## HTML Writer
######################################################################

class HTMLWriter:
    #////////////////////////////////////////////////////////////
    # Table of Contents
    #////////////////////////////////////////////////////////////
    #
    # 1. Interface Methods
    #
    # 2. Page Generation -- write complete web page files
    #   2.1. Module Pages
    #   2.2. Class Pages
    #   2.3. Trees Page
    #   2.4. Indices Page
    #   2.5. Help Page
    #   2.6. Frames-based table of contents pages
    #   2.7. Homepage (index.html)
    #   2.8. CSS Stylesheet
    #   2.9. Javascript file
    #   2.10. Graphs
    #   2.11. Images
    #
    # 3. Page Element Generation -- write pieces of a web page file
    #   3.1. Page Header
    #   3.2. Page Footer
    #   3.3. Navigation Bar
    #   3.4. Breadcrumbs
    #   3.5. Summary Tables
    #
    # 4. Helper functions

    def __init__(self, docindex, **kwargs):
        """
        Construct a new HTML writer, using the given documentation
        index.
        
        @param docindex: The documentation index.
        
        @type prj_name: C{string}
        @keyword prj_name: The name of the project.  Defaults to
              none.
        @type prj_url: C{string}
        @keyword prj_url: The target for the project hopeage link on
              the navigation bar.  If C{prj_url} is not specified,
              then no hyperlink is created.
        @type prj_link: C{string}
        @keyword prj_link: The label for the project link on the
              navigation bar.  This link can contain arbitrary HTML
              code (e.g. images).  By default, a label is constructed
              from C{prj_name}.
        @type top_page: C{string}
        @keyword top_page: The top page for the documentation.  This
              is the default page shown main frame, when frames are
              enabled.  C{top} can be a URL, the name of a
              module, the name of a class, or one of the special
              strings C{"trees.html"}, C{"indices.html"}, or
              C{"help.html"}.  By default, the top-level package or
              module is used, if there is one; otherwise, C{"trees"}
              is used.
        @type css: C{string}
        @keyword css: The CSS stylesheet file.  If C{css} is a file
              name, then the specified file's conents will be used.
              Otherwise, if C{css} is the name of a CSS stylesheet in
              L{epydoc.docwriter.html_css}, then that stylesheet will
              be used.  Otherwise, an error is reported.  If no stylesheet 
              is specified, then the default stylesheet is used.
        @type help_file: C{string}
        @keyword help_file: The name of the help file.  If no help file is
              specified, then the default help file will be used.
        @type show_private: C{boolean}
        @keyword show_private: Whether to create documentation for
            private objects.  By default, private objects are documented.
        @type show_frames: C{boolean})
        @keyword show_frames: Whether to create a frames-based table of
              contents.  By default, it is produced.
        @type show_imports: C{boolean}
        @keyword show_imports: Whether or not to display lists of
              imported functions and classes.  By default, they are
              not shown.
        @type variable_maxlines: C{int}
        @keyword variable_maxlines: The maximum number of lines that
              should be displayed for the value of a variable in the
              variable details section.  By default, 8 lines are
              displayed.
        @type variable_linelength: C{int}
        @keyword variable_linelength: The maximum line length used for
              displaying the values of variables in the variable
              details sections.  If a line is longer than this length,
              then it will be wrapped to the next line.  The default
              line length is 70 characters.
        @type variable_summary_linelength: C{int}
        @keyword variable_summary_linelength: The maximum line length
              used for displaying the values of variables in the summary
              section.  If a line is longer than this length, then it
              will be truncated.  The default is 40 characters.
        @type variable_tooltip_linelength: C{int}
        @keyword variable_tooltip_linelength: The maximum line length
              used for tooltips for the values of variables.  If a
              line is longer than this length, then it will be
              truncated.  The default is 600 characters.
        @type property_function_linelength: C{int}
        @keyword property_function_linelength: The maximum line length
              used to dispaly property functions (C{fget}, C{fset}, and
              C{fdel}) that contain something other than a function
              object.  The default length is 40 characters.
        @type inheritance: C{string}
        @keyword inheritance: How inherited objects should be displayed.
              If C{inheritance='grouped'}, then inherited objects are
              gathered into groups; if C{inheritance='listed'}, then
              inherited objects are listed in a short list at the
              end of their group; if C{inheritance='included'}, then
              inherited objects are mixed in with non-inherited
              objects.  The default is 'grouped'.
        @type include_source_code: C{boolean}
        @keyword include_source_code: If true, then generate colorized
              source code files for each python module.
        @type include_log: C{boolean}
        @keyword include_log: If true, the the footer will include an
              href to the page 'epydoc-log.html'.
        @type src_code_tab_width: C{int}
        @keyword src_code_tab_width: Number of spaces to replace each tab
            with in source code listings.
        """
        self.docindex = docindex

        # Process keyword arguments.
        self._show_private = kwargs.get('show_private', 1)
        """Should private docs be included?"""
        
        self._prj_name = kwargs.get('prj_name', None)
        """The project's name (for the project link in the navbar)"""
        
        self._prj_url = kwargs.get('prj_url', None)
        """URL for the project link in the navbar"""
        
        self._prj_link = kwargs.get('prj_link', None)
        """HTML code for the project link in the navbar"""
        
        self._top_page = kwargs.get('top_page', None)
        """The 'main' page"""

        self._css = kwargs.get('css')
        """CSS stylesheet to use"""
        
        self._helpfile = kwargs.get('help_file', None)
        """Filename of file to extract help contents from"""
        
        self._frames_index = kwargs.get('show_frames', 1)
        """Should a frames index be created?"""
        
        self._show_imports = kwargs.get('show_imports', False)
        """Should imports be listed?"""
        
        self._propfunc_linelen = kwargs.get('property_function_linelength', 40)
        """[XXX] Not used!"""
        
        self._variable_maxlines = kwargs.get('variable_maxlines', 8)
        """Max lines for variable values"""
        
        self._variable_linelen = kwargs.get('variable_linelength', 70)
        """Max line length for variable values"""
        
        self._variable_summary_linelen = \
                         kwargs.get('variable_summary_linelength', 65)
        """Max length for variable value summaries"""
        
        self._variable_tooltip_linelen = \
                         kwargs.get('variable_tooltip_linelength', 600)
        """Max length for variable tooltips"""
        
        self._inheritance = kwargs.get('inheritance', 'listed')
        """How should inheritance be displayed?  'listed', 'included',
        or 'grouped'"""

        self._incl_sourcecode = kwargs.get('include_source_code', True)
        """Should pages be generated for source code of modules?"""

        self._mark_docstrings = kwargs.get('mark_docstrings', False)
        """Wrap <span class='docstring'>...</span> around docstrings?"""

        self._graph_types = kwargs.get('graphs', ()) or ()
        """Graphs that we should include in our output."""

        self._include_log = kwargs.get('include_log', False)
        """Are we generating an HTML log page?"""

        self._src_code_tab_width = kwargs.get('src_code_tab_width', 8)
        """Number of spaces to replace each tab with in source code
        listings."""
        
        self._callgraph_cache = {}
        """Map the callgraph L{uid<DotGraph.uid>} to their HTML
        representation."""

        self._redundant_details = kwargs.get('redundant_details', False)
        """If true, then include objects in the details list even if all
        info about them is already provided by the summary table."""

        # For use with select_variables():
        if self._show_private:
            self._public_filter = None
        else:
            self._public_filter = True
        
        # Make sure inheritance has a sane value.
        if self._inheritance not in ('listed', 'included', 'grouped'):
            raise ValueError, 'Bad value for inheritance'

        # Create the project homepage link, if it was not specified.
        if (self._prj_name or self._prj_url) and not self._prj_link:
            self._prj_link = plaintext_to_html(self._prj_name or
                                               'Project Homepage')

        # Add a hyperlink to _prj_url, if _prj_link doesn't already
        # contain any hyperlinks.
        if (self._prj_link and self._prj_url and
            not re.search(r'<a[^>]*\shref', self._prj_link)):
            self._prj_link = ('<a class="navbar" target="_top" href="'+
                              self._prj_url+'">'+self._prj_link+'</a>')

        # Precompute lists & sets of APIDoc objects that we're
        # interested in.
        self.valdocs = valdocs = sorted(docindex.reachable_valdocs(
            imports=False, packages=False, bases=False, submodules=False, 
            subclasses=False, private=self._show_private))
        self.module_list = [d for d in valdocs if isinstance(d, ModuleDoc)]
        """The list of L{ModuleDoc}s for the documented modules."""
        self.module_set = set(self.module_list)
        """The set of L{ModuleDoc}s for the documented modules."""
        self.class_list = [d for d in valdocs if isinstance(d, ClassDoc)]
        """The list of L{ClassDoc}s for the documented classes."""
        self.class_set = set(self.class_list)
        """The set of L{ClassDoc}s for the documented classes."""
        self.routine_list = [d for d in valdocs if isinstance(d, RoutineDoc)]
        """The list of L{RoutineDoc}s for the documented routines."""
        self.indexed_docs = []
        """The list of L{APIDoc}s for variables and values that should
        be included in the index."""

        # URL for 'trees' page
        if self.module_list: self._trees_url = 'module-tree.html'
        else: self._trees_url = 'class-tree.html'

        # Construct the value for self.indexed_docs.
        self.indexed_docs += [d for d in valdocs
                              if not isinstance(d, GenericValueDoc)]
        for doc in valdocs:
            if isinstance(doc, NamespaceDoc):
                # add any vars with generic values; but don't include
                # inherited vars.
                self.indexed_docs += [d for d in doc.variables.values() if
                                      isinstance(d.value, GenericValueDoc)
                                      and d.container == doc]
        self.indexed_docs.sort()

        # Figure out the url for the top page.
        self._top_page_url = self._find_top_page(self._top_page)

        # Decide whether or not to split the identifier index.
        self._split_ident_index = (len(self.indexed_docs) >=
                                   self.SPLIT_IDENT_INDEX_SIZE)
        
        # Figure out how many output files there will be (for progress
        # reporting).
        self.modules_with_sourcecode = set()
        for doc in self.module_list:
            if isinstance(doc, ModuleDoc) and is_src_filename(doc.filename):
                self.modules_with_sourcecode.add(doc)
        self._num_files = (len(self.class_list) + len(self.module_list) +
                           10 + len(self.METADATA_INDICES))
        if self._frames_index:
            self._num_files += len(self.module_list) + 3

        if self._incl_sourcecode:
            self._num_files += len(self.modules_with_sourcecode)
        if self._split_ident_index:
            self._num_files += len(self.LETTERS)
            
    def _find_top_page(self, pagename):
        """
        Find the top page for the API documentation.  This page is
        used as the default page shown in the main frame, when frames
        are used.  When frames are not used, this page is copied to 
        C{index.html}.

        @param pagename: The name of the page, as specified by the
            keyword argument C{top} to the constructor.
        @type pagename: C{string}
        @return: The URL of the top page.
        @rtype: C{string}
        """
        # If a page name was specified, then we need to figure out
        # what it points to.
        if pagename:
            # If it's a URL, then use it directly.
            if pagename.lower().startswith('http:'):
                return pagename

            # If it's an object, then use that object's page.
            try:
                doc = self.docindex.get_valdoc(pagename)
                return self.url(doc)
            except:
                pass

            # Otherwise, give up.
            log.warning('Could not find top page %r; using %s '
                        'instead' % (pagename, self._trees_url))
            return self._trees_url

        # If no page name was specified, then try to choose one
        # automatically.
        else:
            root = [val_doc for val_doc in self.docindex.root
                    if isinstance(val_doc, (ClassDoc, ModuleDoc))]
            if len(root) == 0:
                # No docs??  Try the trees page.
                return self._trees_url
            elif len(root) == 1:
                # One item in the root; use that.
                return self.url(root[0]) 
            else:
                # Multiple root items; if they're all in one package,
                # then use that.  Otherwise, use self._trees_url
                root = sorted(root, key=lambda v:len(v.canonical_name))
                top = root[0]
                for doc in root[1:]:
                    if not top.canonical_name.dominates(doc.canonical_name):
                        return self._trees_url
                else:
                    return self.url(top)
    
    #////////////////////////////////////////////////////////////
    #{ 1. Interface Methods
    #////////////////////////////////////////////////////////////

    def write(self, directory=None):
        """
        Write the documentation to the given directory.

        @type directory: C{string}
        @param directory: The directory to which output should be
            written.  If no directory is specified, output will be
            written to the current directory.  If the directory does
            not exist, it will be created.
        @rtype: C{None}
        @raise OSError: If C{directory} cannot be created.
        @raise OSError: If any file cannot be created or written to.
        """
        # For progress reporting:
        self._files_written = 0.
        
        # Set the default values for ValueDoc formatted representations.
        orig_valdoc_defaults = (ValueDoc.SUMMARY_REPR_LINELEN,
                                ValueDoc.REPR_LINELEN,
                                ValueDoc.REPR_MAXLINES)
        ValueDoc.SUMMARY_REPR_LINELEN = self._variable_summary_linelen
        ValueDoc.REPR_LINELEN = self._variable_linelen
        ValueDoc.REPR_MAXLINES = self._variable_maxlines

        # Use an image for the crarr symbol.
        from epydoc.markup.epytext import ParsedEpytextDocstring
        orig_crarr_html = ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr']
        ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr'] = (
            r'<span class="variable-linewrap">'
            r'<img src="crarr.png" alt="\" /></span>')

        # Keep track of failed xrefs, and report them at the end.
        self._failed_xrefs = {}

        # Create destination directories, if necessary
        if not directory: directory = os.curdir
        self._mkdir(directory)
        self._directory = directory

        # Write the CSS file.
        self._files_written += 1
        log.progress(self._files_written/self._num_files, 'epydoc.css')
        self.write_css(directory, self._css)

        # Write the Javascript file.
        self._files_written += 1
        log.progress(self._files_written/self._num_files, 'epydoc.js')
        self.write_javascript(directory)

        # Write images
        self.write_images(directory)

        # Build the indices.
        indices = {'ident': self.build_identifier_index(),
                   'term': self.build_term_index()}
        for (name, label, label2) in self.METADATA_INDICES:
            indices[name] = self.build_metadata_index(name)

        # Write the identifier index.  If requested, split it into
        # separate pages for each letter.
        ident_by_letter = self._group_by_letter(indices['ident'])
        if not self._split_ident_index:
            self._write(self.write_link_index, directory,
                        'identifier-index.html', indices,
                        'Identifier Index', 'identifier-index.html',
                        ident_by_letter)
        else:
            # Write a page for each section.
            for letter in self.LETTERS:
                filename = 'identifier-index-%s.html' % letter
                self._write(self.write_link_index, directory, filename,
                            indices, 'Identifier Index', filename,
                            ident_by_letter, [letter],
                            'identifier-index-%s.html')
            # Use the first non-empty section as the main index page.
            for letter in self.LETTERS:
                if letter in ident_by_letter:
                    filename = 'identifier-index.html'
                    self._write(self.write_link_index, directory, filename,
                                indices, 'Identifier Index', filename,
                                ident_by_letter, [letter], 
                                'identifier-index-%s.html')
                    break

        # Write the term index.
        if indices['term']:
            term_by_letter = self._group_by_letter(indices['term'])
            self._write(self.write_link_index, directory, 'term-index.html',
                        indices, 'Term Definition Index',
                        'term-index.html', term_by_letter)
        else:
            self._files_written += 1 # (skipped)

        # Write the metadata indices.
        for (name, label, label2) in self.METADATA_INDICES:
            if indices[name]:
                self._write(self.write_metadata_index, directory,
                            '%s-index.html' % name, indices, name,
                            label, label2)
            else:
                self._files_written += 1 # (skipped)

        # Write the trees file (package & class hierarchies)
        if self.module_list:
            self._write(self.write_module_tree, directory, 'module-tree.html')
        else:
            self._files_written += 1 # (skipped)
        if self.class_list:
            self._write(self.write_class_tree, directory, 'class-tree.html')
        else:
            self._files_written += 1 # (skipped)
        
        # Write the help file.
        self._write(self.write_help, directory,'help.html')
        
        # Write the frames-based table of contents.
        if self._frames_index:
            self._write(self.write_frames_index, directory, 'frames.html')
            self._write(self.write_toc, directory, 'toc.html')
            self._write(self.write_project_toc, directory, 'toc-everything.html')
            for doc in self.module_list:
                filename = 'toc-%s' % urllib.unquote(self.url(doc))
                self._write(self.write_module_toc, directory, filename, doc)

        # Write the object documentation.
        for doc in self.module_list:
            filename = urllib.unquote(self.url(doc))
            self._write(self.write_module, directory, filename, doc)
        for doc in self.class_list:
            filename = urllib.unquote(self.url(doc))
            self._write(self.write_class, directory, filename, doc)

        # Write source code files.
        if self._incl_sourcecode:
            # Build a map from short names to APIDocs, used when
            # linking names in the source code.
            name_to_docs = {}
            for api_doc in self.indexed_docs:
                if (api_doc.canonical_name is not None and
                    self.url(api_doc) is not None):
                    name = api_doc.canonical_name[-1]
                    name_to_docs.setdefault(name, []).append(api_doc)
            # Sort each entry of the name_to_docs list.
            for doc_list in name_to_docs.values():
                doc_list.sort()
            # Write the source code for each module.
            for doc in self.modules_with_sourcecode:
                filename = urllib.unquote(self.pysrc_url(doc))
                self._write(self.write_sourcecode, directory, filename, doc,
                            name_to_docs)

        # Write the auto-redirect page.
        self._write(self.write_redirect_page, directory, 'redirect.html')

        # Write the mapping object name -> URL
        self._write(self.write_api_list, directory, 'api-objects.txt')
        
        # Write the index.html files.
        # (this must be done last, since it might copy another file)
        self._files_written += 1
        log.progress(self._files_written/self._num_files, 'index.html')
        self.write_homepage(directory)

        # Don't report references to builtins as missing
        for k in self._failed_xrefs.keys(): # have a copy of keys
            if hasattr(__builtin__, k):
                del self._failed_xrefs[k]

        # Report any failed crossreferences
        if self._failed_xrefs:
            estr = 'Failed identifier crossreference targets:\n'
            failed_identifiers = self._failed_xrefs.keys()
            failed_identifiers.sort()
            for identifier in failed_identifiers:
                names = self._failed_xrefs[identifier].keys()
                names.sort()
                estr += '- %s' % identifier
                estr += '\n'
                for name in names:
                    estr += '      (from %s)\n' % name
            log.docstring_warning(estr)

        # [xx] testing:
        if self._num_files != int(self._files_written):
            log.debug("Expected to write %d files, but actually "
                      "wrote %d files" %
                      (self._num_files, int(self._files_written)))

        # Restore defaults that we changed.
        (ValueDoc.SUMMARY_REPR_LINELEN, ValueDoc.REPR_LINELEN,
         ValueDoc.REPR_MAXLINES) = orig_valdoc_defaults
        ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr'] = orig_crarr_html

    def _write(self, write_func, directory, filename, *args):
        # Display our progress.
        self._files_written += 1
        log.progress(self._files_written/self._num_files, filename)
        
        path = os.path.join(directory, filename)
        f = codecs.open(path, 'w', 'ascii', errors='xmlcharrefreplace')
        write_func(f.write, *args)
        f.close()

    def _mkdir(self, directory):
        """
        If the given directory does not exist, then attempt to create it.
        @rtype: C{None}
        """
        if not os.path.isdir(directory):
            if os.path.exists(directory):
                raise OSError('%r is not a directory' % directory)
            os.mkdir(directory)
        
    #////////////////////////////////////////////////////////////
    #{ 2.1. Module Pages
    #////////////////////////////////////////////////////////////

    def write_module(self, out, doc):
        """
        Write an HTML page containing the API documentation for the
        given module to C{out}.
        
        @param doc: A L{ModuleDoc} containing the API documentation
        for the module that should be described.
        """
        longname = doc.canonical_name
        shortname = doc.canonical_name[-1]

        # Write the page header (incl. navigation bar & breadcrumbs)
        self.write_header(out, str(longname))
        self.write_navbar(out, doc)
        self.write_breadcrumbs(out, doc, self.url(doc))

        # Write the name of the module we're describing.
        if doc.is_package is True: typ = 'Package'
        else: typ = 'Module'
        if longname[0].startswith('script-'):
            shortname = str(longname)[7:]
            typ = 'Script'
        out('<!-- ==================== %s ' % typ.upper() +
            'DESCRIPTION ==================== -->\n')
        out('<h1 class="epydoc">%s %s</h1>' % (typ, shortname))
        out('<p class="nomargin-top">%s</p>\n' % self.pysrc_link(doc))
        
        # If the module has a description, then list it.
        if doc.descr not in (None, UNKNOWN):
            out(self.descr(doc, 2)+'\n\n')

        # Write any standarad metadata (todo, author, etc.)
        if doc.metadata is not UNKNOWN and doc.metadata:
            out('<hr />\n')
        self.write_standard_fields(out, doc)

        # If it's a package, then list the modules it contains.
        if doc.is_package is True:
            self.write_module_list(out, doc)

        # Write summary tables describing the variables that the
        # module defines.
        self.write_summary_table(out, "Classes", doc, "class")
        self.write_summary_table(out, "Functions", doc, "function")
        self.write_summary_table(out, "Variables", doc, "other")

        # Write a list of all imported objects.
        if self._show_imports:
            self.write_imports(out, doc)

        # Write detailed descriptions of functions & variables defined
        # in this module.
        self.write_details_list(out, "Function Details", doc, "function")
        self.write_details_list(out, "Variables Details", doc, "other")

        # Write the page footer (including navigation bar)
        self.write_navbar(out, doc)
        self.write_footer(out)

    #////////////////////////////////////////////////////////////
    #{ 2.??. Source Code Pages
    #////////////////////////////////////////////////////////////

    def write_sourcecode(self, out, doc, name_to_docs):
        #t0 = time.time()
        
        filename = doc.filename
        name = str(doc.canonical_name)
        
        # Header
        self.write_header(out, name)
        self.write_navbar(out, doc)
        self.write_breadcrumbs(out, doc, self.pysrc_url(doc))

        # Source code listing
        out('<h1 class="epydoc">Source Code for %s</h1>\n' %
            self.href(doc, label='%s %s' % (self.doc_kind(doc), name)))
        out('<pre class="py-src">\n')
        out(PythonSourceColorizer(filename, name, self.docindex,
                                  self.url, name_to_docs,
                                  self._src_code_tab_width).colorize())
        out('</pre>\n<br />\n')

        # Footer
        self.write_navbar(out, doc)
        self.write_footer(out)
        
        #log.debug('[%6.2f sec] Wrote pysrc for %s' %
        #          (time.time()-t0, name))

    #////////////////////////////////////////////////////////////
    #{ 2.2. Class Pages
    #////////////////////////////////////////////////////////////

    def write_class(self, out, doc):
        """
        Write an HTML page containing the API documentation for the
        given class to C{out}.
        
        @param doc: A L{ClassDoc} containing the API documentation
        for the class that should be described.
        """
        longname = doc.canonical_name
        shortname = doc.canonical_name[-1]

        # Write the page header (incl. navigation bar & breadcrumbs)
        self.write_header(out, str(longname))
        self.write_navbar(out, doc)
        self.write_breadcrumbs(out, doc, self.url(doc))

        # Write the name of the class we're describing.
        if doc.is_type(): typ = 'Type'
        elif doc.is_exception(): typ = 'Exception'
        else: typ = 'Class'
        out('<!-- ==================== %s ' % typ.upper() +
            'DESCRIPTION ==================== -->\n')
        out('<h1 class="epydoc">%s %s</h1>' % (typ, shortname))
        out('<p class="nomargin-top">%s</p>\n' % self.pysrc_link(doc))

        if ((doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0) or
            (doc.subclasses not in (UNKNOWN,None) and len(doc.subclasses)>0)):
            # Display bases graphically, if requested.
            if 'umlclasstree' in self._graph_types:
                self.write_class_tree_graph(out, doc, uml_class_tree_graph)
            elif 'classtree' in self._graph_types:
                self.write_class_tree_graph(out, doc, class_tree_graph)
                
            # Otherwise, use ascii-art.
            else:
                # Write the base class tree.
                if doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0:
                    out('<pre class="base-tree">\n%s</pre>\n\n' %
                        self.base_tree(doc))

                # Write the known subclasses
                if (doc.subclasses not in (UNKNOWN, None) and
                    len(doc.subclasses) > 0):
                    out('<dl><dt>Known Subclasses:</dt>\n<dd>\n    ')
                    out('  <ul class="subclass-list">\n')
                    for i, subclass in enumerate(doc.subclasses):
                        href = self.href(subclass, context=doc)
                        if self._val_is_public(subclass): css = ''
                        else: css = ' class="private"'
                        if i > 0: href = ', '+href
                        out('<li%s>%s</li>' % (css, href))
                    out('  </ul>\n')
                    out('</dd></dl>\n\n')

            out('<hr />\n')
        
        # If the class has a description, then list it.
        if doc.descr not in (None, UNKNOWN):
            out(self.descr(doc, 2)+'\n\n')

        # Write any standarad metadata (todo, author, etc.)
        if doc.metadata is not UNKNOWN and doc.metadata:
            out('<hr />\n')
        self.write_standard_fields(out, doc)

        # Write summary tables describing the variables that the
        # class defines.
        self.write_summary_table(out, "Nested Classes", doc, "class")
        self.write_summary_table(out, "Instance Methods", doc,
                                 "instancemethod")
        self.write_summary_table(out, "Class Methods", doc, "classmethod")
        self.write_summary_table(out, "Static Methods", doc, "staticmethod")
        self.write_summary_table(out, "Class Variables", doc,
                                 "classvariable")
        self.write_summary_table(out, "Instance Variables", doc,
                                 "instancevariable")
        self.write_summary_table(out, "Properties", doc, "property")

        # Write a list of all imported objects.
        if self._show_imports:
            self.write_imports(out, doc)

        # Write detailed descriptions of functions & variables defined
        # in this class.
        # [xx] why group methods into one section but split vars into two?
        # seems like we should either group in both cases or split in both
        # cases.
        self.write_details_list(out, "Method Details", doc, "method")
        self.write_details_list(out, "Class Variable Details", doc,
                                "classvariable")
        self.write_details_list(out, "Instance Variable Details", doc,
                                "instancevariable")
        self.write_details_list(out, "Property Details", doc, "property")

        # Write the page footer (including navigation bar)
        self.write_navbar(out, doc)
        self.write_footer(out)

    def write_class_tree_graph(self, out, doc, graphmaker):
        """
        Write HTML code for a class tree graph of C{doc} (a classdoc),
        using C{graphmaker} to draw the actual graph.  C{graphmaker}
        should be L{class_tree_graph()}, or L{uml_class_tree_graph()},
        or any other function with a compatible signature.

        If the given class has any private sublcasses (including
        recursive subclasses), then two graph images will be generated
        -- one to display when private values are shown, and the other
        to display when private values are hidden.
        """
        linker = _HTMLDocstringLinker(self, doc)
        private_subcls = self._private_subclasses(doc)
        if private_subcls:
            out('<center>\n'
                '  <div class="private">%s</div>\n'
                '  <div class="public" style="display:none">%s</div>\n'
                '</center>\n' %
                (self.render_graph(graphmaker(doc, linker, doc)),
                 self.render_graph(graphmaker(doc, linker, doc,
                                              exclude=private_subcls))))
        else:
            out('<center>\n%s\n</center>\n' %
                self.render_graph(graphmaker(doc, linker, doc)))

    #////////////////////////////////////////////////////////////
    #{ 2.3. Trees pages
    #////////////////////////////////////////////////////////////

    def write_module_tree(self, out):
        # Header material
        self.write_treepage_header(out, 'Module Hierarchy', 'module-tree.html')
        out('<h1 class="epydoc">Module Hierarchy</h1>\n')

        # Write entries for all top-level modules/packages.
        out('<ul class="nomargin-top">\n')
        for doc in self.module_list:
            if (doc.package in (None, UNKNOWN) or
                doc.package not in self.module_set):
                self.write_module_tree_item(out, doc)
        out('</ul>\n')

        # Footer material
        self.write_navbar(out, 'trees')
        self.write_footer(out)

    def write_class_tree(self, out):
        """
        Write HTML code for a nested list showing the base/subclass
        relationships between all documented classes.  Each element of
        the top-level list is a class with no (documented) bases; and
        under each class is listed all of its subclasses.  Note that
        in the case of multiple inheritance, a class may appear
        multiple times.  
        
        @todo: For multiple inheritance, don't repeat subclasses the
            second time a class is mentioned; instead, link to the
            first mention.
        """
        # [XX] backref for multiple inheritance?
        # Header material
        self.write_treepage_header(out, 'Class Hierarchy', 'class-tree.html')
        out('<h1 class="epydoc">Class Hierarchy</h1>\n')

        # Build a set containing all classes that we should list.
        # This includes everything in class_list, plus any of those
        # class' bases, but not undocumented subclasses.
        class_set = self.class_set.copy()
        for doc in self.class_list:
            if doc.bases != UNKNOWN:
                for base in doc.bases:
                    if base not in class_set:
                        if isinstance(base, ClassDoc):
                            class_set.update(base.mro())
                        else:
                            # [XX] need to deal with this -- how?
                            pass
                            #class_set.add(base)
 
        out('<ul class="nomargin-top">\n')
        for doc in sorted(class_set, key=lambda c:c.canonical_name[-1]):
            if doc.bases != UNKNOWN and len(doc.bases)==0:
                self.write_class_tree_item(out, doc, class_set)
        out('</ul>\n')
        
        # Footer material
        self.write_navbar(out, 'trees')
        self.write_footer(out)

    def write_treepage_header(self, out, title, url):
        # Header material.
        self.write_header(out, title)
        self.write_navbar(out, 'trees')
        self.write_breadcrumbs(out, 'trees', url)
        if self.class_list and self.module_list:
            out('<center><b>\n')
            out(' [ <a href="module-tree.html">Module Hierarchy</a>\n')
            out(' | <a href="class-tree.html">Class Hierarchy</a> ]\n')
            out('</b></center><br />\n')


    #////////////////////////////////////////////////////////////
    #{ 2.4. Index pages
    #////////////////////////////////////////////////////////////

    SPLIT_IDENT_INDEX_SIZE = 3000
    """If the identifier index has more than this number of entries,
    then it will be split into separate pages, one for each
    alphabetical section."""

    LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'
    """The alphabetical sections that are used for link index pages."""
    
    def write_link_index(self, out, indices, title, url, index_by_section,
                         sections=LETTERS, section_url='#%s'):
        
        # Header
        self.write_indexpage_header(out, indices, title, url)

        # Index title & links to alphabetical sections.
        out('<table border="0" width="100%">\n'
            '<tr valign="bottom"><td>\n')
        out('<h1 class="epydoc">%s</h1>\n</td><td>\n[\n' % title)
        for sec in self.LETTERS:
            if sec in index_by_section:
                out(' <a href="%s">%s</a>\n' % (section_url % sec, sec))
            else:
                out('  %s\n' % sec)
        out(']\n')
        out('</td></table>\n')

        # Alphabetical sections.
        sections = [s for s in sections if s in index_by_section]
        if sections:
            out('<table border="0" width="100%">\n')
            for section in sorted(sections):
                out('<tr valign="top"><td valign="top" width="1%">')
                out('<h2 class="epydoc"><a name="%s">%s</a></h2></td>\n' %
                    (section, section))
                out('<td valign="top">\n')
                self.write_index_section(out, index_by_section[section], True)
                out('</td></tr>\n')
            out('</table>\n<br />')

        # Footer material.
        out('<br />')
        self.write_navbar(out, 'indices')
        self.write_footer(out)
                
        
    def write_metadata_index(self, out, indices, field, title, typ):
        """
        Write an HTML page containing a metadata index.
        """
        index = indices[field]
        
        # Header material.
        self.write_indexpage_header(out, indices, title,
                                    '%s-index.html' % field)

        # Page title.
        out('<h1 class="epydoc"><a name="%s">%s</a></h1>\n<br />\n' %
            (field, title))

        # Index (one section per arg)
        for arg in sorted(index):
            # Write a section title.
            if arg is not None:
                if len([1 for (doc, descrs) in index[arg] if
                        not self._doc_or_ancestor_is_private(doc)]) == 0:
                    out('<div class="private">')
                else:
                    out('<div>')
                self.write_table_header(out, 'metadata-index', arg)
                out('</table>')
            # List every descr for this arg.
            for (doc, descrs) in index[arg]:
                if self._doc_or_ancestor_is_private(doc):
                    out('<div class="private">\n')
                else:
                    out('<div>\n')
                out('<table width="100%" class="metadata-index" '
                    'bgcolor="#e0e0e0"><tr><td class="metadata-index">')
                out('<b>%s in %s</b>' %
                    (typ, self.href(doc, label=doc.canonical_name)))
                out('    <ul class="nomargin">\n')
                for descr in descrs:
                    out('      <li>%s</li>\n' %
                        self.docstring_to_html(descr,doc,4))
                out('    </ul>\n')
                out('</table></div>\n')

        # Footer material.
        out('<br />')
        self.write_navbar(out, 'indices')
        self.write_footer(out)

    def write_indexpage_header(self, out, indices, title, url):
        """
        A helper for the index page generation functions, which
        generates a header that can be used to navigate between the
        different indices.
        """
        self.write_header(out, title)
        self.write_navbar(out, 'indices')
        self.write_breadcrumbs(out, 'indices', url)

        if (indices['term'] or
            [1 for (name,l,l2) in self.METADATA_INDICES if indices[name]]):
            out('<center><b>[\n')
            out(' <a href="identifier-index.html">Identifiers</a>\n')
            if indices['term']:
                out('| <a href="term-index.html">Term Definitions</a>\n')
            for (name, label, label2) in self.METADATA_INDICES:
                if indices[name]:
                    out('| <a href="%s-index.html">%s</a>\n' %
                        (name, label2))
            out(']</b></center><br />\n')

    def write_index_section(self, out, items, add_blankline=False):
        out('<table class="link-index" width="100%" border="1">\n')
        num_rows = (len(items)+2)/3
        for row in range(num_rows):
            out('<tr>\n')
            for col in range(3):
                out('<td width="33%" class="link-index">')
                i = col*num_rows+row
                if i < len(items):
                    name, url, container = items[col*num_rows+row]
                    out('<a href="%s">%s</a>' % (url, name))
                    if container is not None:
                        out('<br />\n')
                        if isinstance(container, ModuleDoc):
                            label = container.canonical_name
                        else:
                            label = container.canonical_name[-1]
                        out('<span class="index-where">(in&nbsp;%s)'
                            '</span>' % self.href(container, label))
                else:
                    out('&nbsp;')
                out('</td>\n')
            out('</tr>\n')
            if add_blankline and num_rows == 1:
                blank_cell = '<td class="link-index">&nbsp;</td>'
                out('<tr>'+3*blank_cell+'</tr>\n')
        out('</table>\n')

    #////////////////////////////////////////////////////////////
    #{ 2.5. Help Page
    #////////////////////////////////////////////////////////////

    def write_help(self, out):
        """
        Write an HTML help file to the given stream.  If
        C{self._helpfile} contains a help file, then use it;
        otherwise, use the default helpfile from
        L{epydoc.docwriter.html_help}.
        """
        # todo: optionally parse .rst etc help files?
        
        # Get the contents of the help file.
        if self._helpfile:
            if os.path.exists(self._helpfile):
                try: help = open(self._helpfile).read()
                except: raise IOError("Can't open help file: %r" %
                                      self._helpfile)
            else:
                raise IOError("Can't find help file: %r" % self._helpfile)
        else:
            if self._prj_name: thisprj = self._prj_name
            else: thisprj = 'this project'
            help = HTML_HELP % {'this_project':thisprj}

        # Insert the help contents into a webpage.
        self.write_header(out, 'Help')
        self.write_navbar(out, 'help')
        self.write_breadcrumbs(out, 'help', 'help.html')
        out(help)
        self.write_navbar(out, 'help')
        self.write_footer(out)

    #////////////////////////////////////////////////////////////
    #{ 2.6. Frames-based Table of Contents
    #////////////////////////////////////////////////////////////
    
    write_frames_index = compile_template(
        """
        write_frames_index(self, out)

        Write the frames index file for the frames-based table of
        contents to the given streams.
        """,
        # /------------------------- Template -------------------------\
        '''
        <?xml version="1.0" encoding="iso-8859-1"?>
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
                  "DTD/xhtml1-frameset.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
          <title> $self._prj_name or "API Documentation"$ </title>
        </head>
        <frameset cols="20%,80%">
          <frameset rows="30%,70%">
            <frame src="toc.html" name="moduleListFrame"
                   id="moduleListFrame" />
            <frame src="toc-everything.html" name="moduleFrame"
                   id="moduleFrame" />
          </frameset>
          <frame src="$self._top_page_url$" name="mainFrame" id="mainFrame" />
        </frameset>
        </html>
        ''')
        # \------------------------------------------------------------/
    
    write_toc = compile_template(
        """
        write_toc(self, out)
        """,
        # /------------------------- Template -------------------------\
        '''
        >>> self.write_header(out, "Table of Contents")
        <h1 class="toc">Table&nbsp;of&nbsp;Contents</h1>
        <hr />
          <a target="moduleFrame" href="toc-everything.html">Everything</a>
          <br />
        >>> self.write_toc_section(out, "Modules", self.module_list)
        <hr />
        >>> if self._show_private:
          $self.PRIVATE_LINK$
        >>> #endif
        >>> self.write_footer(out, short=True)
        ''')
        # \------------------------------------------------------------/

    def write_toc_section(self, out, name, docs, fullname=True):
        if not docs: return

        # Assign names to each item, and sort by name.
        if fullname:
            docs = [(str(d.canonical_name), d) for d in docs]
        else:
            docs = [(str(d.canonical_name[-1]), d) for d in docs]
        docs.sort()

        out('  <h2 class="toc">%s</h2>\n' % name)
        for label, doc in docs:
            doc_url = self.url(doc)
            toc_url = 'toc-%s' % doc_url
            is_private = self._doc_or_ancestor_is_private(doc)
            if is_private:
                if not self._show_private: continue
                out('  <div class="private">\n')
                
            if isinstance(doc, ModuleDoc):
                out('    <a target="moduleFrame" href="%s"\n'
                    '     onclick="setFrame(\'%s\',\'%s\');"'
                    '     >%s</a><br />' % (toc_url, toc_url, doc_url, label))
            else:
                out('    <a target="mainFrame" href="%s"\n'
                    '     >%s</a><br />' % (doc_url, label))
            if is_private:
                out('  </div>\n')

    def write_project_toc(self, out):
        self.write_header(out, "Everything")
        out('<h1 class="toc">Everything</h1>\n')
        out('<hr />\n')

        # List the classes.
        self.write_toc_section(out, "All Classes", self.class_list)

        # List the functions.
        funcs = [d for d in self.routine_list 
                 if not isinstance(self.docindex.container(d), 
                                   (ClassDoc, types.NoneType))]
        self.write_toc_section(out, "All Functions", funcs)

        # List the variables.
        vars = []
        for doc in self.module_list:
            vars += doc.select_variables(value_type='other',
                                         imported=False,
                                         public=self._public_filter)
        self.write_toc_section(out, "All Variables", vars)

        # Footer material.
        out('<hr />\n')
        if self._show_private:
            out(self.PRIVATE_LINK+'\n')
        self.write_footer(out, short=True)

    def write_module_toc(self, out, doc):
        """
        Write an HTML page containing the table of contents page for
        the given module to the given streams.  This page lists the
        modules, classes, exceptions, functions, and variables defined
        by the module.
        """
        name = doc.canonical_name[-1]
        self.write_header(out, name)
        out('<h1 class="toc">Module %s</h1>\n' % name)
        out('<hr />\n')


        # List the classes.
        classes = doc.select_variables(value_type='class', imported=False,
                                       public=self._public_filter)
        self.write_toc_section(out, "Classes", classes, fullname=False)

        # List the functions.
        funcs = doc.select_variables(value_type='function', imported=False,
                                     public=self._public_filter)
        self.write_toc_section(out, "Functions", funcs, fullname=False)

        # List the variables.
        variables = doc.select_variables(value_type='other', imported=False,
                                         public=self._public_filter)
        self.write_toc_section(out, "Variables", variables, fullname=False)
        
        # Footer material.
        out('<hr />\n')
        if self._show_private:
            out(self.PRIVATE_LINK+'\n')
        self.write_footer(out, short=True)

    #////////////////////////////////////////////////////////////
    #{ 2.7. Project homepage (index.html)
    #////////////////////////////////////////////////////////////

    def write_homepage(self, directory):
        """
        Write an C{index.html} file in the given directory.  The
        contents of this file are copied or linked from an existing
        page, so this method must be called after all pages have been
        written.  The page used is determined by L{_frames_index} and
        L{_top_page}:
            - If L{_frames_index} is true, then C{frames.html} is
              copied.
            - Otherwise, the page specified by L{_top_page} is
              copied.
        """
        filename = os.path.join(directory, 'index.html')
        if self._frames_index: top = 'frames.html'
        else: top = self._top_page_url

        # Copy the non-frames index file from top, if it's internal.
        if top[:5] != 'http:' and '/' not in top:
            try:
                # Read top into `s`.
                topfile = os.path.join(directory, top)
                s = open(topfile, 'r').read()

                # Write the output file.
                open(filename, 'w').write(s)
                return
            except:
                log.error('Warning: error copying index; '
                          'using a redirect page')

        # Use a redirect if top is external, or if we faild to copy.
        name = self._prj_name or 'this project'
        f = open(filename, 'w')
        self.write_redirect_index(f.write, top, name)
        f.close()

    write_redirect_index = compile_template(
        """
        write_redirect_index(self, out, top, name)
        """,
        # /------------------------- Template -------------------------\
        '''
        <?xml version="1.0" encoding="iso-8859-1"?>
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                  "DTD/xhtml1-strict.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
          <title> Redirect </title>
          <meta http-equiv="refresh" content="1;url=$top$" />
          <link rel="stylesheet" href="epydoc.css" type="text/css"></link>
        </head>
        <body>
          <p>Redirecting to the API documentation for
            <a href="$top$">$self._prj_name or "this project"$</a>...</p>
        </body>
        </html>
        ''')
        # \------------------------------------------------------------/

    #////////////////////////////////////////////////////////////
    #{ 2.8. Stylesheet (epydoc.css)
    #////////////////////////////////////////////////////////////

    def write_css(self, directory, cssname):
        """
        Write the CSS stylesheet in the given directory.  If
        C{cssname} contains a stylesheet file or name (from
        L{epydoc.docwriter.html_css}), then use that stylesheet;
        otherwise, use the default stylesheet.

        @rtype: C{None}
        """
        filename = os.path.join(directory, 'epydoc.css')
        
        # Get the contents for the stylesheet file.
        if cssname is None:
            css = STYLESHEETS['default'][0]
        else:
            if os.path.exists(cssname):
                try: css = open(cssname).read()
                except: raise IOError("Can't open CSS file: %r" % cssname)
            elif cssname in STYLESHEETS:
                css = STYLESHEETS[cssname][0]
            else:
                raise IOError("Can't find CSS file: %r" % cssname)

        # Write the stylesheet.
        cssfile = open(filename, 'w')
        cssfile.write(css)
        cssfile.close()

    #////////////////////////////////////////////////////////////
    #{ 2.9. Javascript (epydoc.js)
    #////////////////////////////////////////////////////////////

    def write_javascript(self, directory):
        jsfile = open(os.path.join(directory, 'epydoc.js'), 'w')
        print >> jsfile, self.TOGGLE_PRIVATE_JS
        print >> jsfile, self.SHOW_PRIVATE_JS
        print >> jsfile, self.GET_COOKIE_JS
        print >> jsfile, self.SET_FRAME_JS
        print >> jsfile, self.HIDE_PRIVATE_JS
        print >> jsfile, self.TOGGLE_CALLGRAPH_JS
        print >> jsfile, html_colorize.PYSRC_JAVASCRIPTS
        print >> jsfile, self.GET_ANCHOR_JS
        print >> jsfile, self.REDIRECT_URL_JS
        jsfile.close()

    #: A javascript that is used to show or hide the API documentation
    #: for private objects.  In order for this to work correctly, all
    #: documentation for private objects should be enclosed in 
    #: C{<div class="private">...</div>} elements.
    TOGGLE_PRIVATE_JS = '''
      function toggle_private() {
        // Search for any private/public links on this page.  Store
        // their old text in "cmd," so we will know what action to
        // take; and change their text to the opposite action.
        var cmd = "?";
        var elts = document.getElementsByTagName("a");
        for(var i=0; i<elts.length; i++) {
          if (elts[i].className == "privatelink") {
            cmd = elts[i].innerHTML;
            elts[i].innerHTML = ((cmd && cmd.substr(0,4)=="show")?
                                    "hide&nbsp;private":"show&nbsp;private");
          }
        }
        // Update all DIVs containing private objects.
        var elts = document.getElementsByTagName("div");
        for(var i=0; i<elts.length; i++) {
          if (elts[i].className == "private") {
            elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?"none":"block");
          }
          else if (elts[i].className == "public") {
            elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?"block":"none");
          }
        }
        // Update all table rows containing private objects.  Note, we
        // use "" instead of "block" becaue IE & firefox disagree on what
        // this should be (block vs table-row), and "" just gives the
        // default for both browsers.
        var elts = document.getElementsByTagName("tr");
        for(var i=0; i<elts.length; i++) {
          if (elts[i].className == "private") {
            elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?"none":"");
          }
        }
        // Update all list items containing private objects.
        var elts = document.getElementsByTagName("li");
        for(var i=0; i<elts.length; i++) {
          if (elts[i].className == "private") {
            elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?
                                        "none":"");
          }
        }
        // Update all list items containing private objects.
        var elts = document.getElementsByTagName("ul");
        for(var i=0; i<elts.length; i++) {
          if (elts[i].className == "private") {
            elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?"none":"block");
          }
        }
        // Set a cookie to remember the current option.
        document.cookie = "EpydocPrivate="+cmd;
      }
      '''.strip()

    #: A javascript that is used to read the value of a cookie.  This
    #: is used to remember whether private variables should be shown or
    #: hidden.
    GET_COOKIE_JS = '''
      function getCookie(name) {
        var dc = document.cookie;
        var prefix = name + "=";
        var begin = dc.indexOf("; " + prefix);
        if (begin == -1) {
          begin = dc.indexOf(prefix);
          if (begin != 0) return null;
        } else
        { begin += 2; }
        var end = document.cookie.indexOf(";", begin);
        if (end == -1)
        { end = dc.length; }
        return unescape(dc.substring(begin + prefix.length, end));
      }
      '''.strip()

    #: A javascript that is used to set the contents of two frames at
    #: once.  This is used by the project table-of-contents frame to
    #: set both the module table-of-contents frame and the main frame
    #: when the user clicks on a module.
    SET_FRAME_JS = '''
      function setFrame(url1, url2) {
          parent.frames[1].location.href = url1;
          parent.frames[2].location.href = url2;
      }
    '''.strip()

    #: A javascript that is used to hide private variables, unless
    #: either: (a) the cookie says not to; or (b) we appear to be
    #: linking to a private variable.
    HIDE_PRIVATE_JS = '''
      function checkCookie() {
        var cmd=getCookie("EpydocPrivate");
        if (cmd && cmd.substr(0,4)!="show" && location.href.indexOf("#_") < 0)
            toggle_private();
      }
    '''.strip()

    TOGGLE_CALLGRAPH_JS = '''
      function toggleCallGraph(id) {
        var elt = document.getElementById(id);
        if (elt.style.display == "none")
            elt.style.display = "block";
        else
            elt.style.display = "none";
      }
    '''.strip()

    SHOW_PRIVATE_JS = '''
      function show_private() {
        var elts = document.getElementsByTagName("a");
        for(var i=0; i<elts.length; i++) {
          if (elts[i].className == "privatelink") {
            cmd = elts[i].innerHTML;
            if (cmd && cmd.substr(0,4)=="show")
                toggle_private();
          }
        }
      }
    '''.strip()

    GET_ANCHOR_JS = '''
      function get_anchor() {
          var href = location.href;
          var start = href.indexOf("#")+1;
          if ((start != 0) && (start != href.length))
              return href.substring(start, href.length);
      }
    '''.strip()

    #: A javascript that is used to implement the auto-redirect page.
    #: When the user visits <redirect.html#dotted.name>, they will
    #: automatically get redirected to the page for the object with
    #: the given fully-qualified dotted name.  E.g., for epydoc,
    #: <redirect.html#epydoc.apidoc.UNKNOWN> redirects the user to
    #: <epydoc.apidoc-module.html#UNKNOWN>.
    REDIRECT_URL_JS = '''
      function redirect_url(dottedName) {
          // Scan through each element of the "pages" list, and check
          // if "name" matches with any of them.
          for (var i=0; i<pages.length; i++) {

              // Each page has the form "<pagename>-m" or "<pagename>-c";
              // extract the <pagename> portion & compare it to dottedName.
              var pagename = pages[i].substring(0, pages[i].length-2);
              if (pagename == dottedName.substring(0,pagename.length)) {

                  // We\'ve found a page that matches `dottedName`;
                  // construct its URL, using leftover `dottedName`
                  // content to form an anchor.
                  var pagetype = pages[i].charAt(pages[i].length-1);
                  var url = pagename + ((pagetype=="m")?"-module.html":
                                                        "-class.html");
                  if (dottedName.length > pagename.length)
                      url += "#" + dottedName.substring(pagename.length+1,
                                                        dottedName.length);
                  return url;
              }
          }
      }
    '''.strip()
          

    #////////////////////////////////////////////////////////////
    #{ 2.10. Graphs
    #////////////////////////////////////////////////////////////

    def render_graph(self, graph):
        if graph is None: return ''
        graph.caption = graph.title = None
        image_url = '%s.gif' % graph.uid
        image_file = os.path.join(self._directory, image_url)
        return graph.to_html(image_file, image_url)
    
    RE_CALLGRAPH_ID = re.compile(r"""["'](.+-div)['"]""")
    
    def render_callgraph(self, callgraph, token=""):
        """Render the HTML chunk of a callgraph.

        If C{callgraph} is a string, use the L{_callgraph_cache} to return
        a pre-rendered HTML chunk. This mostly avoids to run C{dot} twice for
        the same callgraph. Else, run the graph and store its HTML output in
        the cache.

        @param callgraph: The graph to render or its L{uid<DotGraph.uid>}.
        @type callgraph: L{DotGraph} or C{str}
        @param token: A string that can be used to make the C{<div>} id
            unambiguous, if the callgraph is used more than once in a page.
        @type token: C{str}
        @return: The HTML representation of the graph.
        @rtype: C{str}
        """
        if callgraph is None: return ""
        
        if isinstance(callgraph, basestring):
            uid = callgraph
            rv = self._callgraph_cache.get(callgraph, "")

        else:
            uid = callgraph.uid
            graph_html = self.render_graph(callgraph)
            if graph_html == '':
                rv = ""
            else:
                rv = ('<div style="display:none" id="%%s-div"><center>\n'
                      '<table border="0" cellpadding="0" cellspacing="0">\n'
                      '  <tr><td>%s</td></tr>\n'
                      '  <tr><th>Call Graph</th></tr>\n'
                      '</table><br />\n</center></div>\n' % graph_html)

            # Store in the cache the complete HTML chunk without the
            # div id, which may be made unambiguous by the token
            self._callgraph_cache[uid] = rv

        # Mangle with the graph
        if rv: rv = rv % (uid + token)
        return rv

    def callgraph_link(self, callgraph, token=""):
        """Render the HTML chunk of a callgraph link.

        The link can toggles the visibility of the callgraph rendered using
        L{render_callgraph} with matching parameters.

        @param callgraph: The graph to render or its L{uid<DotGraph.uid>}.
        @type callgraph: L{DotGraph} or C{str}
        @param token: A string that can be used to make the C{<div>} id
            unambiguous, if the callgraph is used more than once in a page.
        @type token: C{str}
        @return: The HTML representation of the graph link.
        @rtype: C{str}
        """
        # Use class=codelink, to match style w/ the source code link.
        if callgraph is None: return ''

        if isinstance(callgraph, basestring):
            uid = callgraph
        else:
            uid = callgraph.uid

        return ('<br /><span class="codelink"><a href="javascript:void(0);" '
                'onclick="toggleCallGraph(\'%s-div\');return false;">'
                'call&nbsp;graph</a></span>&nbsp;' % (uid + token))

    #////////////////////////////////////////////////////////////
    #{ 2.11. Images
    #////////////////////////////////////////////////////////////

    IMAGES = {'crarr.png': # Carriage-return arrow, used for LINEWRAP.
              'iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAMAAABlokWQAAAALHRFWHRD'
              'cmVhdGlvbiBUaW1lAFR1\nZSAyMiBBdWcgMjAwNiAwMDo0MzoxMCAtMD'
              'UwMGAMEFgAAAAHdElNRQfWCBYFASkQ033WAAAACXBI\nWXMAAB7CAAAe'
              'wgFu0HU+AAAABGdBTUEAALGPC/xhBQAAAEVQTFRF////zcOw18/AgGY0'
              'c1cg4dvQ\ninJEYEAAYkME3NXI6eTcloFYe2Asr5+AbE4Uh29A9fPwqp'
              'l4ZEUI8O3onopk0Ma0lH5U1nfFdgAA\nAAF0Uk5TAEDm2GYAAABNSURB'
              'VHjaY2BAAbzsvDAmK5oIlxgfioiwCAe7KJKIgKAQOzsLLwTwA0VY\n+d'
              'iRAT8T0AxuIIMHqoaXCWIPGzsHJ6orGJiYWRjQASOcBQAocgMSPKMTIg'
              'AAAABJRU5ErkJggg==\n',
              }

    def write_images(self, directory):
        for (name, data) in self.IMAGES.items():
            f = open(os.path.join(directory, name), 'wb')
            f.write(base64.decodestring(data))
            f.close()

    #////////////////////////////////////////////////////////////
    #{ 3.1. Page Header
    #////////////////////////////////////////////////////////////

    write_header = compile_template(
        """
        write_header(self, out, title)

        Generate HTML code for the standard page header, and write it
        to C{out}.  C{title} is a string containing the page title.
        It should be appropriately escaped/encoded.
        """,
        # /------------------------- Template -------------------------\
        '''
        <?xml version="1.0" encoding="ascii"?>
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                  "DTD/xhtml1-transitional.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
          <title>$title$</title>
          <link rel="stylesheet" href="epydoc.css" type="text/css" />
          <script type="text/javascript" src="epydoc.js"></script>
        </head>
        
        <body bgcolor="white" text="black" link="blue" vlink="#204080"
              alink="#204080">
        ''')
        # \------------------------------------------------------------/

    #////////////////////////////////////////////////////////////
    #{ 3.2. Page Footer
    #////////////////////////////////////////////////////////////

    write_footer = compile_template(
        """
        write_footer(self, out, short=False)

        Generate HTML code for the standard page footer, and write it
        to C{out}.
        """,
        # /------------------------- Template -------------------------\
        '''
        >>> if not short:
        <table border="0" cellpadding="0" cellspacing="0" width="100%%">
          <tr>
            <td align="left" class="footer">
        >>>   if self._include_log:
            <a href="epydoc-log.html">Generated by Epydoc
            $epydoc.__version__$ on $time.asctime()$</a>
        >>>   else:
            Generated by Epydoc $epydoc.__version__$ on $time.asctime()$
        >>>   #endif
            </td>
            <td align="right" class="footer">
              <a target="mainFrame" href="http://epydoc.sourceforge.net"
                >http://epydoc.sourceforge.net</a>
            </td>
          </tr>
        </table>
        >>> #endif

        <script type="text/javascript">
          <!--
          // Private objects are initially displayed (because if
          // javascript is turned off then we want them to be
          // visible); but by default, we want to hide them.  So hide
          // them unless we have a cookie that says to show them.
          checkCookie();
          // -->
        </script>
        </body>
        </html>
        ''')
        # \------------------------------------------------------------/

    #////////////////////////////////////////////////////////////
    #{ 3.3. Navigation Bar
    #////////////////////////////////////////////////////////////

    write_navbar = compile_template(
        """
        write_navbar(self, out, context)

        Generate HTML code for the navigation bar, and write it to
        C{out}.  The navigation bar typically looks like::

             [ Home Trees Index Help             Project ]

        @param context: A value indicating what page we're generating
        a navigation bar for.  If we're generating an API
        documentation page for an object, then C{context} is a
        L{ValueDoc} containing the documentation for that object;
        otherwise, C{context} is a string name for the page.  The
        following string names are recognized: C{'tree'}, C{'index'},
        and C{'help'}.
        """,
        # /------------------------- Template -------------------------\
        '''
        <!-- ==================== NAVIGATION BAR ==================== -->
        <table class="navbar" border="0" width="100%" cellpadding="0"
               bgcolor="#a0c0ff" cellspacing="0">
          <tr valign="middle">
        >>> if self._top_page_url not in (self._trees_url, "identifier-index.html", "help.html"):
          <!-- Home link -->
        >>>   if (isinstance(context, ValueDoc) and
        >>>       self._top_page_url == self.url(context.canonical_name)):
              <th bgcolor="#70b0f0" class="navbar-select"
                  >&nbsp;&nbsp;&nbsp;Home&nbsp;&nbsp;&nbsp;</th>
        >>>   else:
              <th>&nbsp;&nbsp;&nbsp;<a
                href="$self._top_page_url$">Home</a>&nbsp;&nbsp;&nbsp;</th>
        >>> #endif
        
          <!-- Tree link -->
        >>> if context == "trees":
              <th bgcolor="#70b0f0" class="navbar-select"
                  >&nbsp;&nbsp;&nbsp;Trees&nbsp;&nbsp;&nbsp;</th>
        >>> else:
              <th>&nbsp;&nbsp;&nbsp;<a
                href="$self._trees_url$">Trees</a>&nbsp;&nbsp;&nbsp;</th>
        >>> #endif
        
          <!-- Index link -->
        >>> if context == "indices":
              <th bgcolor="#70b0f0" class="navbar-select"
                  >&nbsp;&nbsp;&nbsp;Indices&nbsp;&nbsp;&nbsp;</th>
        >>> else:
              <th>&nbsp;&nbsp;&nbsp;<a
                href="identifier-index.html">Indices</a>&nbsp;&nbsp;&nbsp;</th>
        >>> #endif
        
          <!-- Help link -->
        >>> if context == "help":
              <th bgcolor="#70b0f0" class="navbar-select"
                  >&nbsp;&nbsp;&nbsp;Help&nbsp;&nbsp;&nbsp;</th>
        >>> else:
              <th>&nbsp;&nbsp;&nbsp;<a
                href="help.html">Help</a>&nbsp;&nbsp;&nbsp;</th>
        >>> #endif
        
        >>> if self._prj_link:
          <!-- Project homepage -->
              <th class="navbar" align="right" width="100%">
                <table border="0" cellpadding="0" cellspacing="0">
                  <tr><th class="navbar" align="center"
                    >$self._prj_link.strip()$</th>
                  </tr></table></th>
        >>> else:
              <th class="navbar" width="100%"></th>
        >>> #endif
          </tr>
        </table>
        ''')
        # \------------------------------------------------------------/

    #////////////////////////////////////////////////////////////
    #{ 3.4. Breadcrumbs
    #////////////////////////////////////////////////////////////

    write_breadcrumbs = compile_template(
        """
        write_breadcrumbs(self, out, context, context_url)

        Generate HTML for the breadcrumbs line, and write it to
        C{out}.  The breadcrumbs line is an invisible table with a
        list of pointers to the current object's ancestors on the
        left; and the show/hide private selector and the
        frames/noframes selector on the right.

        @param context: The API documentation for the object whose
        breadcrumbs we should generate.
        @type context: L{ValueDoc}
        """,
        # /------------------------- Template -------------------------\
        '''
        <table width="100%" cellpadding="0" cellspacing="0">
          <tr valign="top">
        >>> if isinstance(context, APIDoc):
            <td width="100%">
              <span class="breadcrumbs">
        >>>   crumbs = self.breadcrumbs(context)
        >>>   for crumb in crumbs[:-1]:
                $crumb$ ::
        >>>   #endfor
                $crumbs[-1]$
              </span>
            </td>
        >>> else:
            <td width="100%">&nbsp;</td>
        >>> #endif
            <td>
              <table cellpadding="0" cellspacing="0">
                <!-- hide/show private -->
        >>> if self._show_private:
                <tr><td align="right">$self.PRIVATE_LINK$</td></tr>
        >>> #endif
        >>> if self._frames_index:
                <tr><td align="right"><span class="options"
                    >[<a href="frames.html" target="_top">frames</a
                    >]&nbsp;|&nbsp;<a href="$context_url$"
                    target="_top">no&nbsp;frames</a>]</span></td></tr>
        >>> #endif
              </table>
            </td>
          </tr>
        </table>
        ''')
        # \------------------------------------------------------------/

    def breadcrumbs(self, doc):
        crumbs = [self._crumb(doc)]

        # Generate the crumbs for uid's ancestors.
        while True:
            container = self.docindex.container(doc)
            assert doc != container, 'object is its own container?'
            if container is None:
                if doc.canonical_name is UNKNOWN:
                    return ['??']+crumbs
                elif isinstance(doc, ModuleDoc):
                    return ['Package&nbsp;%s' % ident
                            for ident in doc.canonical_name[:-1]]+crumbs
                else:
                    return list(doc.canonical_name)+crumbs
            else:
                label = self._crumb(container)
                name = container.canonical_name
                crumbs.insert(0, self.href(container, label)) # [xx] code=0??
                doc = container
        
    def _crumb(self, doc):
        if (len(doc.canonical_name)==1 and
            doc.canonical_name[0].startswith('script-')):
            return 'Script&nbsp;%s' % doc.canonical_name[0][7:]
        return '%s&nbsp;%s' % (self.doc_kind(doc), doc.canonical_name[-1])

    #////////////////////////////////////////////////////////////
    #{ 3.5. Summary Tables
    #////////////////////////////////////////////////////////////

    def write_summary_table(self, out, heading, doc, value_type):
        """
        Generate HTML code for a summary table, and write it to
        C{out}.  A summary table is a table that includes a one-row
        description for each variable (of a given type) in a module
        or class.

        @param heading: The heading for the summary table; typically,
            this indicates what kind of value the table describes
            (e.g., functions or classes).
        @param doc: A L{ValueDoc} object containing the API
            documentation for the module or class whose variables
            we should summarize.
        @param value_type: A string indicating what type of value
            should be listed in this summary table.  This value
            is passed on to C{doc}'s C{select_variables()} method.
        """
        # inh_var_groups is a dictionary used to hold "inheritance
        # pseudo-groups", which are created when inheritance is
        # 'grouped'.  It maps each base to a list of vars inherited
        # from that base.
        grouped_inh_vars = {}

        # Divide all public variables of the given type into groups.
        groups = [(plaintext_to_html(group_name),
                   doc.select_variables(group=group_name, imported=False,
                                        value_type=value_type,
                                        public=self._public_filter))
                  for group_name in doc.group_names()]
                
        # Discard any empty groups; and return if they're all empty.
        groups = [(g,vars) for (g,vars) in groups if vars]
        if not groups: return

        # Write a header
        self.write_table_header(out, "summary", heading)

        # Write a section for each group.
        for name, var_docs in groups:
            self.write_summary_group(out, doc, name,
                                     var_docs, grouped_inh_vars)

        # Write a section for each inheritance pseudo-group (used if
        # inheritance=='grouped')
        if grouped_inh_vars:
            for base in doc.mro():
                if base in grouped_inh_vars:
                    hdr = 'Inherited from %s' % self.href(base, context=doc)
                    tr_class = ''
                    if len([v for v in grouped_inh_vars[base]
                            if v.is_public]) == 0:
                        tr_class = ' class="private"'
                    self.write_group_header(out, hdr, tr_class)
                    for var_doc in grouped_inh_vars[base]:
                        self.write_summary_line(out, var_doc, doc)

        # Write a footer for the table.
        out(self.TABLE_FOOTER)

    def write_summary_group(self, out, doc, name, var_docs, grouped_inh_vars):
        # Split up the var_docs list, according to the way each var
        # should be displayed:
        #   - listed_inh_vars -- for listed inherited variables.
        #   - grouped_inh_vars -- for grouped inherited variables.
        #   - normal_vars -- for all other variables.
        listed_inh_vars = {}
        normal_vars = []
        for var_doc in var_docs:
            if var_doc.container != doc:
                base = var_doc.container
                if not isinstance(base, ClassDoc):
                    # This *should* never happen:
                    log.warning("%s's container is not a class!" % var_doc)
                    normal_vars.append(var_doc)
                elif (base not in self.class_set or
                    self._inheritance == 'listed'):
                    listed_inh_vars.setdefault(base,[]).append(var_doc)
                elif self._inheritance == 'grouped':
                    grouped_inh_vars.setdefault(base,[]).append(var_doc)
                else:
                    normal_vars.append(var_doc)
            else:
                normal_vars.append(var_doc)
            
        # Write a header for the group.
        if name != '':
            tr_class = ''
            if len([v for v in var_docs if v.is_public]) == 0:
                tr_class = ' class="private"'
            self.write_group_header(out, name, tr_class)

        # Write a line for each normal var:
        for var_doc in normal_vars:
            self.write_summary_line(out, var_doc, doc)
        # Write a subsection for inherited vars:
        if listed_inh_vars:
            self.write_inheritance_list(out, doc, listed_inh_vars)

    def write_inheritance_list(self, out, doc, listed_inh_vars):
        out('  <tr>\n    <td colspan="2" class="summary">\n')
        for base in doc.mro():
            if base not in listed_inh_vars: continue
            public_vars = [v for v in listed_inh_vars[base]
                           if v.is_public]
            private_vars = [v for v in listed_inh_vars[base]
                            if not v.is_public]
            if public_vars:
                out('    <p class="indent-wrapped-lines">'
                    '<b>Inherited from <code>%s</code></b>:\n' %
                    self.href(base, context=doc))
                self.write_var_list(out, public_vars)
                out('      </p>\n')
            if private_vars and self._show_private:
                out('    <div class="private">')
                out('    <p class="indent-wrapped-lines">'
                    '<b>Inherited from <code>%s</code></b> (private):\n' %
                    self.href(base, context=doc))
                self.write_var_list(out, private_vars)
                out('      </p></div>\n')
        out('    </td>\n  </tr>\n')
    
    def write_var_list(self, out, vardocs):
        out('      ')
        out(',\n      '.join(['<code>%s</code>' % self.href(v,v.name)
                              for v in vardocs])+'\n')

    def write_summary_line(self, out, var_doc, container):
        """
        Generate HTML code for a single line of a summary table, and
        write it to C{out}.  See L{write_summary_table} for more
        information.
        
        @param var_doc: The API documentation for the variable that
            should be described by this line of the summary table.
        @param container: The API documentation for the class or
            module whose summary table we're writing.
        """
        pysrc_link = None
        callgraph = None

        # If it's a private variable, then mark its <tr>.
        if var_doc.is_public: tr_class = ''
        else: tr_class = ' class="private"'

        # Decide an anchor or a link is to be generated.
        link_name = self._redundant_details or var_doc.is_detailed()
        anchor = not link_name

        # Construct the HTML code for the type (cell 1) & description
        # (cell 2).
        if isinstance(var_doc.value, RoutineDoc):
            typ = self.return_type(var_doc, indent=6)
            description = self.function_signature(var_doc, is_summary=True,
                link_name=link_name, anchor=anchor)
            pysrc_link = self.pysrc_link(var_doc.value)

            # Perpare the call-graph, if requested
            if 'callgraph' in self._graph_types:
                linker = _HTMLDocstringLinker(self, var_doc.value)
                callgraph = call_graph([var_doc.value], self.docindex,
                                       linker, var_doc, add_callers=True, 
                                       add_callees=True)
                if callgraph and callgraph.nodes:
                    var_doc.value.callgraph_uid = callgraph.uid
                else:
                    callgraph = None
        else:
            typ = self.type_descr(var_doc, indent=6)
            description = self.summary_name(var_doc,
                link_name=link_name, anchor=anchor)
            if isinstance(var_doc.value, GenericValueDoc):
                # The summary max length has been chosen setting
                # L{ValueDoc.SUMMARY_REPR_LINELEN} in the constructor
                max_len=self._variable_summary_linelen-3-len(var_doc.name)
                val_repr = var_doc.value.summary_pyval_repr(max_len)
                tooltip = self.variable_tooltip(var_doc)
                description += (' = <code%s>%s</code>' %
                                (tooltip, val_repr.to_html(None)))

        # Add the summary to the description (if there is one).
        summary = self.summary(var_doc, indent=6)
        if summary: description += '<br />\n      %s' % summary
        
        # If it's inherited, then add a note to the description.
        if var_doc.container != container and self._inheritance=="included":
            description += ("\n      <em>(Inherited from " +
                        self.href(var_doc.container) + ")</em>")

        # Write the summary line.
        self._write_summary_line(out, typ, description, tr_class, pysrc_link,
                                 callgraph)

    _write_summary_line = compile_template(
        "_write_summary_line(self, out, typ, description, tr_class, "
                            "pysrc_link, callgraph)",
        # /------------------------- Template -------------------------\
        '''
          <tr$tr_class$>
            <td width="15%" align="right" valign="top" class="summary">
              <span class="summary-type">$typ or "&nbsp;"$</span>
            </td><td class="summary">
        >>> if pysrc_link is not None or callgraph is not None:
              <table width="100%" cellpadding="0" cellspacing="0" border="0">
                <tr>
                  <td>$description$</td>
                  <td align="right" valign="top">
                    $pysrc_link$
                    $self.callgraph_link(callgraph, token='-summary')$
                  </td>
                </tr>
              </table>
              $self.render_callgraph(callgraph, token='-summary')$
        >>> #endif
        >>> if pysrc_link is None and callgraph is None:
                $description$
        >>> #endif
            </td>
          </tr>
        ''')
        # \------------------------------------------------------------/

    #////////////////////////////////////////////////////////////
    #{ 3.6. Details Lists
    #////////////////////////////////////////////////////////////

    def write_details_list(self, out, heading, doc, value_type):
        # Get a list of the VarDocs we should describe.
        if self._redundant_details:
            detailed = None
        else:
            detailed = True
        if isinstance(doc, ClassDoc):
            var_docs = doc.select_variables(value_type=value_type,
                                            imported=False, inherited=False,
                                            public=self._public_filter,
                                            detailed=detailed)
        else:
            var_docs = doc.select_variables(value_type=value_type,
                                            imported=False,
                                            public=self._public_filter,
                                            detailed=detailed)
        if not var_docs: return

        # Write a header
        self.write_table_header(out, "details", heading)
        out(self.TABLE_FOOTER)

        for var_doc in var_docs:
            self.write_details_entry(out, var_doc)

        out('<br />\n')

    def write_details_entry(self, out, var_doc):
        descr = self.descr(var_doc, indent=2) or ''
        if var_doc.is_public: div_class = ''
        else: div_class = ' class="private"'

        # Functions
        if isinstance(var_doc.value, RoutineDoc):
            rtype = self.return_type(var_doc, indent=10)
            rdescr = self.return_descr(var_doc, indent=10)
            arg_descrs = []
            args = set()
            # Find the description for each arg.  (Leave them in the
            # same order that they're listed in the docstring.)
            for (arg_names, arg_descr) in var_doc.value.arg_descrs:
                args.update(arg_names)
                lhs = ', '.join([self.arg_name_to_html(var_doc.value, n)
                                 for n in arg_names])
                rhs = self.docstring_to_html(arg_descr, var_doc.value, 10)
                arg_descrs.append( (lhs, rhs) )
            # Check for arguments for which we have @type but not @param;
            # and add them to the arg_descrs list.
            for arg in var_doc.value.arg_types:
                if arg not in args:
                    argname = self.arg_name_to_html(var_doc.value, arg)
                    arg_descrs.append( (argname,'') )

            self.write_function_details_entry(out, var_doc, descr,
                                              var_doc.value.callgraph_uid,
                                              rtype, rdescr, arg_descrs,
                                              div_class)

        # Properties
        elif isinstance(var_doc.value, PropertyDoc):
            prop_doc = var_doc.value
            accessors = [ (name,
                           self.property_accessor_to_html(val_doc, prop_doc),
                           self.summary(val_doc))
                         for (name, val_doc) in
                            [('Get', prop_doc.fget), ('Set', prop_doc.fset),
                             ('Delete', prop_doc.fdel)]
                            if val_doc not in (None, UNKNOWN)
                            and val_doc.pyval is not None ]

            self.write_property_details_entry(out, var_doc, descr,
                                              accessors, div_class)
        
        # Variables
        else:
            self.write_variable_details_entry(out, var_doc, descr, div_class)

    def labelled_list_item(self, lhs, rhs):
        # If the RHS starts with a paragraph, then move the
        # paragraph-start tag to the beginning of the lhs instead (so
        # there won't be a line break after the '-').
        m = re.match(r'^<p( [^>]+)?>', rhs)
        if m:
            lhs = m.group() + lhs
            rhs = rhs[m.end():]

        if rhs:
            return '<li>%s - %s</li>' % (lhs, rhs)
        else:
            return '<li>%s</li>' % (lhs,)

    def property_accessor_to_html(self, val_doc, context=None):
        if val_doc not in (None, UNKNOWN):
            if isinstance(val_doc, RoutineDoc):
                return self.function_signature(val_doc, is_summary=True,
                                               link_name=True, context=context)
            elif isinstance(val_doc, GenericValueDoc):
                return self.pprint_value(val_doc)
            else:
                return self.href(val_doc, context=context)
        else:
            return '??'
        
    def arg_name_to_html(self, func_doc, arg_name):
        """
        A helper function used to format an argument name, for use in
        the argument description list under a routine's details entry.
        This just wraps strong & code tags around the arg name; and if
        the arg name is associated with a type, then adds it
        parenthetically after the name.
        """
        s = '<strong class="pname"><code>%s</code></strong>' % arg_name
        if arg_name in func_doc.arg_types:
            typ = func_doc.arg_types[arg_name]
            typ_html = self.docstring_to_html(typ, func_doc, 10)
            s += " (%s)" % typ_html
        return s

    write_function_details_entry = compile_template(
        '''
        write_function_details_entry(self, out, var_doc, descr, callgraph, \
                                     rtype, rdescr, arg_descrs, div_class)
        ''',
        # /------------------------- Template -------------------------\
        '''
        >>> func_doc = var_doc.value
        <a name="$var_doc.name$"></a>
        <div$div_class$>
        >>> self.write_table_header(out, "details")
        <tr><td>
          <table width="100%" cellpadding="0" cellspacing="0" border="0">
          <tr valign="top"><td>
          <h3 class="epydoc">$self.function_signature(var_doc)$
        >>> if var_doc.name in self.SPECIAL_METHODS:
            <br /><em class="fname">($self.SPECIAL_METHODS[var_doc.name]$)</em>
        >>> #endif
        >>> if isinstance(func_doc, ClassMethodDoc):
            <br /><em class="fname">Class Method</em>
        >>> #endif
        >>> if isinstance(func_doc, StaticMethodDoc):
            <br /><em class="fname">Static Method</em>
        >>> #endif
          </h3>
          </td><td align="right" valign="top"
            >$self.pysrc_link(func_doc)$&nbsp;
            $self.callgraph_link(callgraph)$</td>
          </tr></table>
          $self.render_callgraph(callgraph)$
          $descr$
          <dl class="fields">
        >>> # === parameters ===
        >>> if arg_descrs:
            <dt>Parameters:</dt>
            <dd><ul class="nomargin-top">
        >>>   for lhs, rhs in arg_descrs:
                $self.labelled_list_item(lhs, rhs)$
        >>>   #endfor
            </ul></dd>
        >>> #endif
        >>> # === return type ===
        >>> if rdescr and rtype:
            <dt>Returns: $rtype$</dt>
                <dd>$rdescr$</dd>
        >>> elif rdescr:
            <dt>Returns:</dt>
                <dd>$rdescr$</dd>
        >>> elif rtype:
            <dt>Returns: $rtype$</dt>
        >>> #endif
        >>> # === decorators ===
        >>> if func_doc.decorators not in (None, UNKNOWN):
        >>>   # (staticmethod & classmethod are already shown, above)
        >>>   decos = filter(lambda deco:
        >>>     not ((deco=="staticmethod" and
        >>>            isinstance(func_doc, StaticMethodDoc)) or
        >>>          (deco=="classmethod" and
        >>>           isinstance(func_doc, ClassMethodDoc))),
        >>>     func_doc.decorators)
        >>> else:
        >>>   decos = None
        >>> #endif
        >>> if decos:
            <dt>Decorators:</dt>
            <dd><ul class="nomargin-top">
        >>>   for deco in decos:
                <li><code>@$deco$</code></li>
        >>>   #endfor
            </ul></dd>
        >>> #endif
        >>> # === exceptions ===
        >>> if func_doc.exception_descrs not in (None, UNKNOWN, (), []):
            <dt>Raises:</dt>
            <dd><ul class="nomargin-top">
        >>>   for name, descr in func_doc.exception_descrs:
        >>>     exc_name = self.docindex.find(name, func_doc)
        >>>     if exc_name is not None:
        >>>       name = self.href(exc_name, label=str(name))
        >>>     #endif
                $self.labelled_list_item(
                    "<code><strong class=\'fraise\'>" +
                    str(name) + "</strong></code>",
                    self.docstring_to_html(descr, func_doc, 8))$
        >>>   #endfor
            </ul></dd>
        >>> #endif
        >>> # === overrides ===
        >>> if var_doc.overrides not in (None, UNKNOWN):
            <dt>Overrides:
        >>>   # Avoid passing GenericValueDoc to href()
        >>>   if isinstance(var_doc.overrides.value, RoutineDoc):
                $self.href(var_doc.overrides.value, context=var_doc)$
        >>>   else:
        >>>     # In this case, a less interesting label is generated.
                $self.href(var_doc.overrides, context=var_doc)$
        >>>   #endif
        >>>   if (func_doc.docstring in (None, UNKNOWN) and
        >>>       var_doc.overrides.value.docstring not in (None, UNKNOWN)):
                <dd><em class="note">(inherited documentation)</em></dd>
        >>>   #endif
            </dt>
        >>> #endif
          </dl>
        >>> # === metadata ===
        >>> self.write_standard_fields(out, func_doc)
        </td></tr></table>
        </div>
        ''')
        # \------------------------------------------------------------/

    # Names for the __special__ methods.
    SPECIAL_METHODS ={
    '__init__': 'Constructor',
    '__del__': 'Destructor',
    '__add__': 'Addition operator',
    '__sub__': 'Subtraction operator',
    '__and__': 'And operator',
    '__or__': 'Or operator',
    '__xor__': 'Exclusive-Or operator',
    '__repr__': 'Representation operator',
    '__call__': 'Call operator',
    '__getattr__': 'Qualification operator',
    '__getitem__': 'Indexing operator',
    '__setitem__': 'Index assignment operator',
    '__delitem__': 'Index deletion operator',
    '__delslice__': 'Slice deletion operator',
    '__setslice__': 'Slice assignment operator',
    '__getslice__': 'Slicling operator',
    '__len__': 'Length operator',
    '__cmp__': 'Comparison operator',
    '__eq__': 'Equality operator',
    '__in__': 'Containership operator',
    '__gt__': 'Greater-than operator',
    '__lt__': 'Less-than operator',
    '__ge__': 'Greater-than-or-equals operator',
    '__le__': 'Less-than-or-equals operator',
    '__radd__': 'Right-side addition operator',
    '__hash__': 'Hashing function',
    '__contains__': 'In operator',
    '__nonzero__': 'Boolean test operator',
    '__str__': 'Informal representation operator',
    }

    write_property_details_entry = compile_template(
        '''
        write_property_details_entry(self, out, var_doc, descr, \
                                     accessors, div_class)
        ''',
        # /------------------------- Template -------------------------\
        '''
        >>> prop_doc = var_doc.value
        <a name="$var_doc.name$"></a>
        <div$div_class$>
        >>> self.write_table_header(out, "details")
        <tr><td>
          <h3 class="epydoc">$var_doc.name$</h3>
          $descr$
          <dl class="fields">
        >>> for (name, val, summary) in accessors:
            <dt>$name$ Method:</dt>
            <dd class="value">$val$
        >>>     if summary:
                - $summary$
        >>>     #endif
            </dd>
        >>> #endfor
        >>> if prop_doc.type_descr not in (None, UNKNOWN):
            <dt>Type:</dt>
              <dd>$self.type_descr(var_doc, indent=6)$</dd>
        >>> #endif
          </dl>
        >>> self.write_standard_fields(out, prop_doc)
        </td></tr></table>
        </div>
        ''')
        # \------------------------------------------------------------/
        
    write_variable_details_entry = compile_template(
        '''
        write_variable_details_entry(self, out, var_doc, descr, div_class)
        ''',
        # /------------------------- Template -------------------------\
        '''
        <a name="$var_doc.name$"></a>
        <div$div_class$>
        >>> self.write_table_header(out, "details")
        <tr><td>
          <h3 class="epydoc">$var_doc.name$</h3>
          $descr$
          <dl class="fields">
        >>> if var_doc.type_descr not in (None, UNKNOWN):
            <dt>Type:</dt>
              <dd>$self.type_descr(var_doc, indent=6)$</dd>
        >>> #endif
          </dl>
        >>> self.write_standard_fields(out, var_doc)
        >>> if var_doc.value is not UNKNOWN:
          <dl class="fields">
            <dt>Value:</dt>
              <dd>$self.pprint_value(var_doc.value)$</dd>
          </dl>
        >>> #endif
        </td></tr></table>
        </div>
        ''')
        # \------------------------------------------------------------/

    def variable_tooltip(self, var_doc):
        if var_doc.value in (None, UNKNOWN):
            return ''
        s = var_doc.value.pyval_repr().to_plaintext(None)
        if len(s) > self._variable_tooltip_linelen:
            s = s[:self._variable_tooltip_linelen-3]+'...'
        return ' title="%s"' % plaintext_to_html(s)

    def pprint_value(self, val_doc):
        if val_doc is UNKNOWN:
            return '??'
        elif isinstance(val_doc, GenericValueDoc):
            return ('<table><tr><td><pre class="variable">\n' +
                    val_doc.pyval_repr().to_html(None) +
                    '\n</pre></td></tr></table>\n')
        else:
            return self.href(val_doc)

    #////////////////////////////////////////////////////////////
    #{ Base Tree
    #////////////////////////////////////////////////////////////

    def base_tree(self, doc, width=None, postfix='', context=None):
        """
        @return: The HTML code for a class's base tree.  The tree is
            drawn 'upside-down' and right justified, to allow for
            multiple inheritance.
        @rtype: C{string}
        """
        if context is None:
            context = doc.defining_module
        if width == None: width = self.find_tree_width(doc, context)
        if isinstance(doc, ClassDoc) and doc.bases != UNKNOWN:
            bases = doc.bases
        else:
            bases = []
        
        if postfix == '':
            # [XX] use var name instead of canonical name?
            s = (' '*(width-2) + '<strong class="uidshort">'+
                   self.contextual_label(doc, context)+'</strong>\n')
        else: s = ''
        for i in range(len(bases)-1, -1, -1):
            base = bases[i]
            label = self.contextual_label(base, context)
            s = (' '*(width-4-len(label)) + self.href(base, label)
                   +' --+'+postfix+'\n' + 
                   ' '*(width-4) +
                   '   |'+postfix+'\n' +
                   s)
            if i != 0:
                s = (self.base_tree(base, width-4, '   |'+postfix, context)+s)
            else:
                s = (self.base_tree(base, width-4, '    '+postfix, context)+s)
        return s

    def find_tree_width(self, doc, context):
        """
        Helper function for L{base_tree}.
        @return: The width of a base tree, when drawn
            right-justified.  This is used by L{base_tree} to
            determine how far to indent lines of the base tree.
        @rtype: C{int}
        """
        if not isinstance(doc, ClassDoc): return 2
        if doc.bases == UNKNOWN: return 2
        width = 2
        for base in doc.bases:
            width = max(width, len(self.contextual_label(base, context))+4,
                        self.find_tree_width(base, context)+4)
        return width

    def contextual_label(self, doc, context):
        """
        Return the label for C{doc} to be shown in C{context}.
        """
        if doc.canonical_name is None:
            if doc.parse_repr is not None:
                return doc.parse_repr
            else:
                return '??'
        else:
            if context is UNKNOWN:
                return str(doc.canonical_name)
            else:
                context_name = context.canonical_name
                return str(doc.canonical_name.contextualize(context_name))
        
    #////////////////////////////////////////////////////////////
    #{ Function Signatures
    #////////////////////////////////////////////////////////////

    def function_signature(self, api_doc, is_summary=False, 
                           link_name=False, anchor=False, context=None):
        """Render a function signature in HTML.

        @param api_doc: The object whose name is to be rendered. If a
            C{VariableDoc}, its C{value} should be a C{RoutineDoc}
        @type api_doc: L{VariableDoc} or L{RoutineDoc}
        @param is_summary: True if the fuction is to be rendered in the summary.
        type css_class: C{bool}
        @param link_name: If True, the name is a link to the object anchor.
        @type link_name: C{bool}
        @param anchor: If True, the name is the object anchor.
        @type anchor: C{bool}
        @param context: If set, represent the function name from this context.
            Only useful when C{api_doc} is a L{RoutineDoc}.
        @type context: L{DottedName}

        @return: The HTML code for the object.
        @rtype: C{str}
        """
        if is_summary: css_class = 'summary-sig'
        else: css_class = 'sig'
        
        # [XX] clean this up!
        if isinstance(api_doc, VariableDoc):
            func_doc = api_doc.value
            # This should never happen, but just in case:
            if api_doc.value in (None, UNKNOWN):
                return (('<span class="%s"><span class="%s-name">%s'+
                         '</span>(...)</span>') %
                        (css_class, css_class, api_doc.name))
            # Get the function's name.
            name = self.summary_name(api_doc, css_class=css_class+'-name',
                                     link_name=link_name, anchor=anchor)
        else:
            func_doc = api_doc
            name = self.href(api_doc, css_class=css_class+'-name',
                             context=context)

        if func_doc.posargs == UNKNOWN:
            args = ['...']
        else:
            args = [self.func_arg(n, d, css_class) for (n, d)
                    in zip(func_doc.posargs, func_doc.posarg_defaults)]
        if func_doc.vararg not in (None, UNKNOWN):
            if func_doc.vararg == '...':
                args.append('<span class="%s-arg">...</span>' % css_class)
            else:
                args.append('<span class="%s-arg">*%s</span>' %
                            (css_class, func_doc.vararg))
        if func_doc.kwarg not in (None, UNKNOWN):
            args.append('<span class="%s-arg">**%s</span>' %
                        (css_class, func_doc.kwarg))

        return ('<span class="%s">%s(%s)</span>' %
                (css_class, name, ',\n        '.join(args)))

    def summary_name(self, api_doc, css_class='summary-name',
                     link_name=False, anchor=False):
        """Render an object name in HTML.

        @param api_doc: The object whose name is to be rendered
        @type api_doc: L{APIDoc}
        @param css_class: The CSS class to assign to the rendered name
        type css_class: C{str}
        @param link_name: If True, the name is a link to the object anchor.
        @type link_name: C{bool}
        @param anchor: If True, the name is the object anchor.
        @type anchor: C{bool}

        @return: The HTML code for the object.
        @rtype: C{str}
        """
        if anchor:
            rv = '<a name="%s"></a>' % api_doc.name
        else:
            rv = ''

        if link_name:
            rv += self.href(api_doc, css_class=css_class)
        else:
            rv += '<span class="%s">%s</span>' % (css_class, api_doc.name)

        return rv

    # [xx] tuple args???
    def func_arg(self, name, default, css_class):
        name = self._arg_name(name)
        s = '<span class="%s-arg">%s</span>' % (css_class, name)
        if default is not None:
            s += ('=<span class="%s-default">%s</span>' %
                    (css_class, default.summary_pyval_repr().to_html(None)))
        return s

    def _arg_name(self, arg):
        if isinstance(arg, basestring):
            return arg
        elif len(arg) == 1:
            return '(%s,)' % self._arg_name(arg[0])
        else:
            return '(%s)' % (', '.join([self._arg_name(a) for a in arg]))


    

    #////////////////////////////////////////////////////////////
    #{ Import Lists
    #////////////////////////////////////////////////////////////
        
    def write_imports(self, out, doc):
        assert isinstance(doc, NamespaceDoc)
        imports = doc.select_variables(imported=True,
                                       public=self._public_filter)
        if not imports: return

        out('<p class="indent-wrapped-lines">')
        out('<b>Imports:</b>\n  ')
        out(',\n  '.join([self._import(v, doc) for v in imports]))
        out('\n</p><br />\n')

    def _import(self, var_doc, context):
        if var_doc.imported_from not in (None, UNKNOWN):
            return self.href(var_doc.imported_from,
                             var_doc.name, context=context,
                             tooltip='%s' % var_doc.imported_from)
        elif (var_doc.value not in (None, UNKNOWN) and not
              isinstance(var_doc.value, GenericValueDoc)):
            return self.href(var_doc.value,
                             var_doc.name, context=context,
                             tooltip='%s' % var_doc.value.canonical_name)
        else:
            return plaintext_to_html(var_doc.name)
            
    #////////////////////////////////////////////////////////////
    #{ Function Attributes
    #////////////////////////////////////////////////////////////
        
    #////////////////////////////////////////////////////////////
    #{ Module Trees
    #////////////////////////////////////////////////////////////

    def write_module_list(self, out, doc):
        if len(doc.submodules) == 0: return
        self.write_table_header(out, "summary", "Submodules")

        for group_name in doc.group_names():
            if not doc.submodule_groups[group_name]: continue
            if group_name:
                self.write_group_header(out, group_name)
            out('  <tr><td class="summary">\n'
                '  <ul class="nomargin">\n')
            for submodule in doc.submodule_groups[group_name]:
                self.write_module_tree_item(out, submodule, package=doc)
            out('  </ul></td></tr>\n')
                
        out(self.TABLE_FOOTER+'\n<br />\n')

    def write_module_tree_item(self, out, doc, package=None):
        # If it's a private variable, then mark its <li>.
        var = package and package.variables.get(doc.canonical_name[-1])
        priv = ((var is not None and var.is_public is False) or
                (var is None and doc.canonical_name[-1].startswith('_')))
        out('    <li%s> <strong class="uidlink">%s</strong>'
            % (priv and ' class="private"' or '', self.href(doc)))
        if doc.summary not in (None, UNKNOWN):
            out(': <em class="summary">'+
                self.description(doc.summary, doc, 8)+'</em>')
        if doc.submodules != UNKNOWN and doc.submodules:
            if priv: out('\n    <ul class="private">\n')
            else: out('\n    <ul>\n')
            for submodule in doc.submodules:
                self.write_module_tree_item(out, submodule, package=doc)
            out('    </ul>\n')
        out('    </li>\n')

    #////////////////////////////////////////////////////////////
    #{ Class trees
    #////////////////////////////////////////////////////////////

    write_class_tree_item = compile_template(
        '''
        write_class_tree_item(self, out, doc, class_set)
        ''',
        # /------------------------- Template -------------------------\
        '''
        >>> if doc.summary in (None, UNKNOWN):
            <li> <strong class="uidlink">$self.href(doc)$</strong>
        >>> else:
            <li> <strong class="uidlink">$self.href(doc)$</strong>:
              <em class="summary">$self.description(doc.summary, doc, 8)$</em>
        >>> # endif
        >>> if doc.subclasses:
            <ul>
        >>>   for subclass in sorted(set(doc.subclasses), key=lambda c:c.canonical_name[-1]):
        >>>     if subclass in class_set:
        >>>       self.write_class_tree_item(out, subclass, class_set)
        >>>     #endif
        >>>   #endfor
            </ul>
        >>> #endif
            </li>
        ''')
        # \------------------------------------------------------------/
    
    #////////////////////////////////////////////////////////////
    #{ Standard Fields
    #////////////////////////////////////////////////////////////

    def write_standard_fields(self, out, doc):
        """
        Write HTML code containing descriptions of any standard markup
        fields that are defined by the given L{APIDoc} object (such as
        C{@author} and C{@todo} fields).

        @param doc: The L{APIDoc} object containing the API documentation
            for the object whose standard markup fields should be
            described.
        """
        fields = []
        field_values = {}
        
        for (field, arg, descr) in doc.metadata:
            if field not in field_values:
                fields.append(field)
            if field.takes_arg:
                subfields = field_values.setdefault(field,{})
                subfields.setdefault(arg,[]).append(descr)
            else:
                field_values.setdefault(field,[]).append(descr)

        if not fields: return

        out('<div class="fields">')
        for field in fields:
            if field.takes_arg:
                for arg, descrs in field_values[field].items():
                    self.write_standard_field(out, doc, field, descrs, arg)
                                              
            else:
                self.write_standard_field(out, doc, field, field_values[field])

        out('</div>')

    write_standard_field = compile_template(
        """
        write_standard_field(self, out, doc, field, descrs, arg='')
        
        """,
        # /------------------------- Template -------------------------\
        '''
        >>> if arg: arglabel = " (%s)" % arg
        >>> else: arglabel = ""
        >>>   if len(descrs) == 1:
              <p><strong>$field.singular+arglabel$:</strong>
                $self.description(descrs[0], doc, 8)$
              </p>
        >>>   elif field.short:
              <dl><dt>$field.plural+arglabel$:</dt>
                <dd>
        >>>     for descr in descrs[:-1]:
                  $self.description(descr, doc, 10)$,
        >>>     # end for
                  $self.description(descrs[-1], doc, 10)$
                </dd>
              </dl>
        >>>   else:
              <strong>$field.plural+arglabel$:</strong>
              <ul class="nomargin-top">
        >>>     for descr in descrs:
                <li>
                $self.description(descr, doc, 8)$
                </li>
        >>>     # end for
              </ul>
        >>>   # end else
        >>> # end for
        ''')
        # \------------------------------------------------------------/

    #////////////////////////////////////////////////////////////
    #{ Index generation
    #////////////////////////////////////////////////////////////

    #: A list of metadata indices that should be generated.  Each
    #: entry in this list is a tuple C{(tag, label, short_label)},
    #: where C{tag} is the cannonical tag of a metadata field;
    #: C{label} is a label for the index page; and C{short_label}
    #: is a shorter label, used in the index selector.
    METADATA_INDICES = [('bug', 'Bug List', 'Bugs'),
                        ('todo', 'To Do List', 'To Do'),
                        ('change', 'Change Log', 'Changes'),
                        ('deprecated', 'Deprecation List', 'Deprecations'),
                        ('since', 'Introductions List', 'Introductions'),
                        ]
    
    def build_identifier_index(self):
        items = []
        for doc in self.indexed_docs:
            name = plaintext_to_html(doc.canonical_name[-1])
            if isinstance(doc, RoutineDoc): name += '()'
            url = self.url(doc)
            if not url: continue
            container = self.docindex.container(doc)
            items.append( (name, url, container) )
        return sorted(items, key=lambda v:v[0].lower())

    def _group_by_letter(self, items):
        """Preserves sort order of the input."""
        index = {}
        for item in items:
            first_letter = item[0][0].upper()
            if not ("A" <= first_letter <= "Z"):
                first_letter = '_'
            index.setdefault(first_letter, []).append(item)
        return index
    
    def build_term_index(self):
        items = []
        for doc in self.indexed_docs:
            url = self.url(doc)
            items += self._terms_from_docstring(url, doc, doc.descr)
            for (field, arg, descr) in doc.metadata:
                items += self._terms_from_docstring(url, doc, descr)
                if hasattr(doc, 'type_descr'):
                    items += self._terms_from_docstring(url, doc,
                                                        doc.type_descr)
                if hasattr(doc, 'return_descr'):
                    items += self._terms_from_docstring(url, doc,
                                                        doc.return_descr)
                if hasattr(doc, 'return_type'):
                    items += self._terms_from_docstring(url, doc,
                                                        doc.return_type)
        return sorted(items, key=lambda v:v[0].lower())

    def _terms_from_docstring(self, base_url, container, parsed_docstring):
        if parsed_docstring in (None, UNKNOWN): return []
        terms = []
        # Strip any existing anchor off:
        base_url = re.sub('#.*', '', '%s' % (base_url,))
        for term in parsed_docstring.index_terms():
            anchor = self._term_index_to_anchor(term)
            url = '%s#%s' % (base_url, anchor)
            terms.append( (term.to_plaintext(None), url, container) )
        return terms

    def build_metadata_index(self, field_name):
        # Build the index.
        index = {}
        for doc in self.indexed_docs:
            if (not self._show_private and
                self._doc_or_ancestor_is_private(doc)):
                continue
            descrs = {}
            if doc.metadata is not UNKNOWN:
                for (field, arg, descr) in doc.metadata:
                    if field.tags[0] == field_name:
                        descrs.setdefault(arg, []).append(descr)
            for (arg, descr_list) in descrs.iteritems():
                index.setdefault(arg, []).append( (doc, descr_list) )
        return index

    def _term_index_to_anchor(self, term):
        """
        Given the name of an inline index item, construct a URI anchor.
        These anchors are used to create links from the index page to each
        index item.
        """
        # Include "-" so we don't accidentally collide with the name
        # of a python identifier.
        s = re.sub(r'\s\s+', '-', term.to_plaintext(None))
        return "index-"+re.sub("[^a-zA-Z0-9]", "_", s)

    #////////////////////////////////////////////////////////////
    #{ Redirect page
    #////////////////////////////////////////////////////////////

    def write_redirect_page(self, out):
        """
        Build the auto-redirect page, which translates dotted names to
        URLs using javascript.  When the user visits
        <redirect.html#dotted.name>, they will automatically get
        redirected to the page for the object with the given
        fully-qualified dotted name.  E.g., for epydoc,
        <redirect.html#epydoc.apidoc.UNKNOWN> redirects the user to
        <epydoc.apidoc-module.html#UNKNOWN>.
        """
        # Construct a list of all the module & class pages that we're
        # documenting.  The redirect_url javascript will scan through
        # this list, looking for a page name that matches the
        # requested dotted name.
        pages = (['%s-m' % val_doc.canonical_name
                  for val_doc in self.module_list] +
                 ['%s-c' % val_doc.canonical_name
                  for val_doc in self.class_list])
        # Sort the pages from longest to shortest.  This ensures that
        # we find e.g. "x.y.z" in the list before "x.y".
        pages = sorted(pages, key=lambda p:-len(p))

        # Write the redirect page.
        self._write_redirect_page(out, pages)

    _write_redirect_page = compile_template(
        '''
        _write_redirect_page(self, out, pages)
        ''',
        # /------------------------- Template -------------------------\
        '''
        <html><head><title>Epydoc Redirect Page</title>
        <meta http-equiv="cache-control" content="no-cache" />
        <meta http-equiv="expires" content="0" />
        <meta http-equiv="pragma" content="no-cache" />
          <script type="text/javascript" src="epydoc.js"></script>
        </head>
        <body>
        <script type="text/javascript">
        <!--
        var pages = $"[%s]" % ", ".join(['"%s"' % v for v in pages])$;
        var dottedName = get_anchor();
        if (dottedName) {
            var target = redirect_url(dottedName);
            if (target) window.location.replace(target);
        }
        // -->
        </script>

        <h3>Epydoc Auto-redirect page</h3>
        
        <p>When javascript is enabled, this page will redirect URLs of
        the form <tt>redirect.html#<i>dotted.name</i></tt> to the
        documentation for the object with the given fully-qualified
        dotted name.</p>
        <p><a id="message"> &nbsp; </a></p>
        
        <script type="text/javascript">
        <!--
        if (dottedName) {
            var msg = document.getElementById("message");
            msg.innerHTML = "No documentation found for <tt>"+
                            dottedName+"</tt>";
        }
        // -->
        </script>

        </body>
        </html>
        ''')
        # \------------------------------------------------------------/

    #////////////////////////////////////////////////////////////
    #{ URLs list
    #////////////////////////////////////////////////////////////

    def write_api_list(self, out):
        """
        Write a list of mapping name->url for all the documented objects.
        """
        # Construct a list of all the module & class pages that we're
        # documenting.  The redirect_url javascript will scan through
        # this list, looking for a page name that matches the
        # requested dotted name.
        skip = (ModuleDoc, ClassDoc, type(UNKNOWN))
        for val_doc in self.module_list:
            self.write_url_record(out, val_doc)
            for var in val_doc.variables.itervalues():
                if not isinstance(var.value, skip):
                    self.write_url_record(out, var)

        for val_doc in self.class_list:
            self.write_url_record(out, val_doc)
            for var in val_doc.variables.itervalues():
                self.write_url_record(out, var)

    def write_url_record(self, out, obj):
        url = self.url(obj)
        if url is not None:
            out("%s\t%s\n" % (obj.canonical_name, url))

    #////////////////////////////////////////////////////////////
    #{ Helper functions
    #////////////////////////////////////////////////////////////

    def _val_is_public(self, valdoc):
        """Make a best-guess as to whether the given class is public."""
        container = self.docindex.container(valdoc)
        if isinstance(container, NamespaceDoc):
            for vardoc in container.variables.values():
                if vardoc in (UNKNOWN, None): continue
                if vardoc.value is valdoc:
                    return vardoc.is_public
        return True

    # [XX] Is it worth-while to pull the anchor tricks that I do here?
    # Or should I just live with the fact that show/hide private moves
    # stuff around?
    write_table_header = compile_template(
        '''
        write_table_header(self, out, css_class, heading=None, \
                           private_link=True, colspan=2)
        ''',
        # /------------------------- Template -------------------------\
        '''
        >>> if heading is not None:
        >>>     anchor = "section-%s" % re.sub("\W", "", heading)
        <!-- ==================== $heading.upper()$ ==================== -->
        <a name="$anchor$"></a>
        >>> #endif
        <table class="$css_class$" border="1" cellpadding="3"
               cellspacing="0" width="100%" bgcolor="white">
        >>> if heading is not None:
        <tr bgcolor="#70b0f0" class="table-header">
        >>>     if private_link and self._show_private:
          <td colspan="$colspan$" class="table-header">
            <table border="0" cellpadding="0" cellspacing="0" width="100%">
              <tr valign="top">
                <td align="left"><span class="table-header">$heading$</span></td>
                <td align="right" valign="top"
                 ><span class="options">[<a href="#$anchor$"
                 class="privatelink" onclick="toggle_private();"
                 >hide private</a>]</span></td>
              </tr>
            </table>
          </td>
        >>>     else:
          <td align="left" colspan="2" class="table-header">
            <span class="table-header">$heading$</span></td>
        >>>     #endif
        </tr>
        >>> #endif
        ''')
        # \------------------------------------------------------------/

    TABLE_FOOTER = '</table>\n'

    PRIVATE_LINK = '''
    <span class="options">[<a href="javascript:void(0);" class="privatelink"
    onclick="toggle_private();">hide&nbsp;private</a>]</span>
    '''.strip()

    write_group_header = compile_template(
        '''
        write_group_header(self, out, group, tr_class='')
        ''',
        # /------------------------- Template -------------------------\
        '''
        <tr bgcolor="#e8f0f8" $tr_class$>
          <th colspan="2" class="group-header"
            >&nbsp;&nbsp;&nbsp;&nbsp;$group$</th></tr>
        ''')
        # \------------------------------------------------------------/

    _url_cache = {}
    def url(self, obj):
        """
        Return the URL for the given object, which can be a
        C{VariableDoc}, a C{ValueDoc}, or a C{DottedName}.
        """
        cached_url = self._url_cache.get(id(obj))
        if cached_url is not None:
            return cached_url
        else:
            url = self._url_cache[id(obj)] = self._url(obj)
            return url

    def _url(self, obj):
        """
        Internal helper for L{url}.
        """
        # Module: <canonical_name>-module.html
        if isinstance(obj, ModuleDoc):
            if obj not in self.module_set: return None
            return urllib.quote('%s'%obj.canonical_name) + '-module.html'
        # Class: <canonical_name>-class.html
        elif isinstance(obj, ClassDoc):
            if obj not in self.class_set: return None
            return urllib.quote('%s'%obj.canonical_name) + '-class.html'
        # Variable
        elif isinstance(obj, VariableDoc):
            val_doc = obj.value
            if isinstance(val_doc, (ModuleDoc, ClassDoc)):
                return self.url(val_doc)
            elif obj.container in (None, UNKNOWN):
                if val_doc in (None, UNKNOWN): return None
                return self.url(val_doc)
            elif obj.is_imported == True:
                if obj.imported_from is not UNKNOWN:
                    return self.url(obj.imported_from)
                else:
                    return None
            else:
                container_url = self.url(obj.container)
                if container_url is None: return None
                return '%s#%s' % (container_url, urllib.quote('%s'%obj.name))
        # Value (other than module or class)
        elif isinstance(obj, ValueDoc):
            container = self.docindex.container(obj)
            if container is None:
                return None # We couldn't find it!
            else:
                container_url = self.url(container)
                if container_url is None: return None
                anchor = urllib.quote('%s'%obj.canonical_name[-1])
                return '%s#%s' % (container_url, anchor)
        # Dotted name: look up the corresponding APIDoc
        elif isinstance(obj, DottedName):
            val_doc = self.docindex.get_valdoc(obj)
            if val_doc is None: return None
            return self.url(val_doc)
        # Special pages:
        elif obj == 'indices':
            return 'identifier-index.html'
        elif obj == 'help':
            return 'help.html'
        elif obj == 'trees':
            return self._trees_url
        else:
            raise ValueError, "Don't know what to do with %r" % obj

    def pysrc_link(self, api_doc):
        if not self._incl_sourcecode:
            return ''
        url = self.pysrc_url(api_doc)
        if url is not None: 
            return ('<span class="codelink"><a href="%s">source&nbsp;'
                    'code</a></span>' % url)
        else:
            return ''
    
    def pysrc_url(self, api_doc):
        if isinstance(api_doc, VariableDoc):
            if api_doc.value not in (None, UNKNOWN):
                return pysrc_url(api_doc.value)
            else:
                return None
        elif isinstance(api_doc, ModuleDoc):
            if api_doc in self.modules_with_sourcecode:
                return ('%s-pysrc.html' %
                       urllib.quote('%s' % api_doc.canonical_name))
            else:
                return None
        else:
            module = api_doc.defining_module
            if module == UNKNOWN: return None
            module_pysrc_url = self.pysrc_url(module)
            if module_pysrc_url is None: return None
            module_name = module.canonical_name
            if not module_name.dominates(api_doc.canonical_name, True):
                log.debug('%r is in %r but name does not dominate' %
                          (api_doc, module))
                return module_pysrc_url
            mname_len = len(module.canonical_name)
            anchor = '%s' % api_doc.canonical_name[mname_len:]
            return '%s#%s' % (module_pysrc_url, urllib.quote(anchor))
        
        # We didn't find it:
        return None

    # [xx] add code to automatically do <code> wrapping or the like?
    def href(self, target, label=None, css_class=None, context=None,
             tooltip=None):
        """
        Return the HTML code for an HREF link to the given target
        (which can be a C{VariableDoc}, a C{ValueDoc}, or a
        C{DottedName}.
        If a C{NamespaceDoc} C{context} is specified, the target label is
        contextualized to it.
        """
        assert isinstance(target, (APIDoc, DottedName))

        # Pick a label, if none was given.
        if label is None:
            if isinstance(target, VariableDoc):
                label = target.name
            elif (isinstance(target, ValueDoc) and
                  target.canonical_name is not UNKNOWN):
                label = target.canonical_name
            elif isinstance(target, DottedName):
                label = target
            elif isinstance(target, GenericValueDoc):
                raise ValueError("href() should not be called with "
                                 "GenericValueDoc objects (perhaps you "
                                 "meant to use the containing variable?)")
            else:
                raise ValueError("Unable to find a label for %r" % target)
                
            if context is not None and isinstance(label, DottedName):
                label = label.contextualize(context.canonical_name.container())
                
            label = plaintext_to_html(str(label))
            
            # Munge names for scripts & unreachable values
            if label.startswith('script-'):
                label = label[7:] + ' (script)'
            if label.startswith('??'):
                label = '<i>unreachable</i>' + label[2:]
                label = re.sub(r'-\d+$', '', label)

        # Get the url for the target.
        url = self.url(target)
        if url is None:
            if tooltip: return '<span title="%s">%s</span>' % (tooltip, label)
            else: return label

        # Construct a string for the class attribute.
        if css_class is None:
            css = ''
        else:
            css = ' class="%s"' % css_class

        onclick = ''
        if ((isinstance(target, VariableDoc) and not target.is_public) or
            (isinstance(target, ValueDoc) and
             not isinstance(target, GenericValueDoc) and
             not self._val_is_public(target))):
            onclick = ' onclick="show_private();"'

        if tooltip:
            tooltip = ' title="%s"' % tooltip
        else:
            tooltip = ''

        return '<a href="%s"%s%s%s>%s</a>' % (url, css, onclick, tooltip, label)

    def _attr_to_html(self, attr, api_doc, indent):
        if api_doc in (None, UNKNOWN):
            return ''
        pds = getattr(api_doc, attr, None) # pds = ParsedDocstring.
        if pds not in (None, UNKNOWN):
            return self.docstring_to_html(pds, api_doc, indent)
        elif isinstance(api_doc, VariableDoc):
            return self._attr_to_html(attr, api_doc.value, indent)
        
    def summary(self, api_doc, indent=0):
        return self._attr_to_html('summary', api_doc, indent)
        
    def descr(self, api_doc, indent=0):
        return self._attr_to_html('descr', api_doc, indent)

    def type_descr(self, api_doc, indent=0):
        return self._attr_to_html('type_descr', api_doc, indent)

    def return_type(self, api_doc, indent=0):
        return self._attr_to_html('return_type', api_doc, indent)

    def return_descr(self, api_doc, indent=0):
        return self._attr_to_html('return_descr', api_doc, indent)

    def docstring_to_html(self, parsed_docstring, where=None, indent=0):
        if parsed_docstring in (None, UNKNOWN): return ''
        linker = _HTMLDocstringLinker(self, where)
        s = parsed_docstring.to_html(linker, indent=indent,
                                     directory=self._directory,
                                     docindex=self.docindex,
                                     context=where).strip()
        if self._mark_docstrings:
            s = '<span class="docstring">%s</span><!--end docstring-->' % s
        return s

    def description(self, parsed_docstring, where=None, indent=0):
        assert isinstance(where, (APIDoc, type(None)))
        if parsed_docstring in (None, UNKNOWN): return ''
        linker = _HTMLDocstringLinker(self, where)
        descr = parsed_docstring.to_html(linker, indent=indent,
                                         directory=self._directory,
                                         docindex=self.docindex,
                                         context=where).strip()
        if descr == '': return '&nbsp;'
        return descr

    # [xx] Should this be defined by the APIDoc classes themselves??
    def doc_kind(self, doc):
        if isinstance(doc, ModuleDoc) and doc.is_package == True:
            return 'Package'
        elif (isinstance(doc, ModuleDoc) and
              doc.canonical_name[0].startswith('script')):
            return 'Script'
        elif isinstance(doc, ModuleDoc):
            return 'Module'
        elif isinstance(doc, ClassDoc):
            return 'Class'
        elif isinstance(doc, ClassMethodDoc):
            return 'Class Method'
        elif isinstance(doc, StaticMethodDoc):
            return 'Static Method'
        elif isinstance(doc, RoutineDoc):
            if isinstance(self.docindex.container(doc), ClassDoc):
                return 'Method'
            else:
                return 'Function'
        else:
            return 'Variable'
        
    def _doc_or_ancestor_is_private(self, api_doc):
        name = api_doc.canonical_name
        for i in range(len(name), 0, -1):
            # Is it (or an ancestor) a private var?
            var_doc = self.docindex.get_vardoc(name[:i])
            if var_doc is not None and var_doc.is_public == False:
                return True
            # Is it (or an ancestor) a private module?
            val_doc = self.docindex.get_valdoc(name[:i])
            if (val_doc is not None and isinstance(val_doc, ModuleDoc) and
                val_doc.canonical_name[-1].startswith('_')):
                return True
        return False

    def _private_subclasses(self, class_doc):
        """Return a list of all subclasses of the given class that are
        private, as determined by L{_val_is_private}.  Recursive
        subclasses are included in this list."""
        queue = [class_doc]
        private = set()
        for cls in queue:
            if (isinstance(cls, ClassDoc) and
                cls.subclasses not in (None, UNKNOWN)):
                queue.extend(cls.subclasses)
                private.update([c for c in cls.subclasses if
                                not self._val_is_public(c)])
        return private
                
class _HTMLDocstringLinker(epydoc.markup.DocstringLinker):
    def __init__(self, htmlwriter, container):
        self.htmlwriter = htmlwriter
        self.docindex = htmlwriter.docindex
        self.container = container
        
    def translate_indexterm(self, indexterm):
        key = self.htmlwriter._term_index_to_anchor(indexterm)
        return ('<a name="%s"></a><i class="indexterm">%s</i>' %
                (key, indexterm.to_html(self)))
    
    def translate_identifier_xref(self, identifier, label=None):
        # Pick a label for this xref.
        if label is None: label = plaintext_to_html(identifier)

        # Find the APIDoc for it (if it's available).
        doc = self.docindex.find(identifier, self.container)

        # If we didn't find a target, then try checking in the contexts
        # of the ancestor classes. 
        if doc is None and isinstance(self.container, RoutineDoc):
            container = self.docindex.get_vardoc(
                self.container.canonical_name)
            while (doc is None and container not in (None, UNKNOWN)
                   and container.overrides not in (None, UNKNOWN)):
                container = container.overrides
                doc = self.docindex.find(identifier, container)
                
        # Translate it into HTML.
        if doc is None:
            self._failed_xref(identifier)
            return '<code class="link">%s</code>' % label
        else:
            return self.htmlwriter.href(doc, label, 'link')

    # [xx] Should this be added to the DocstringLinker interface???
    # Currently, this is *only* used by dotgraph.
    def url_for(self, identifier):
        if isinstance(identifier, (basestring, DottedName)):
            doc = self.docindex.find(identifier, self.container)
            if doc:
                return self.htmlwriter.url(doc)
            else:
                return None
            
        elif isinstance(identifier, APIDoc):
            return self.htmlwriter.url(identifier)
            doc = identifier
            
        else:
            raise TypeError('Expected string or APIDoc')

    def _failed_xref(self, identifier):
        """Add an identifier to the htmlwriter's failed crossreference
        list."""
        # Don't count it as a failed xref if it's a parameter of the
        # current function.
        if (isinstance(self.container, RoutineDoc) and
            identifier in self.container.all_args()):
            return
        
        failed_xrefs = self.htmlwriter._failed_xrefs
        context = self.container.canonical_name
        failed_xrefs.setdefault(identifier,{})[context] = 1
