#! /usr/bin/env python
#  -*- Python -*-

"""usage: %(program)s [options] file...

Supported options:

    --address addr
    -a addr         Set the address text to include at the end of the generated
                    HTML; this should be used for contact information.
    --columns cols
    -c cols         Set the number of columns each index section should be
                    displayed in.  The default is 1.
    --help
    -h              Display this help message.
    --letters
    -l              Split the output into sections by letter.
    --output file
    -o file         Write output to 'file' instead of standard out.
    --iconserver is Use 'is' as the directory containing icons for the
                    navigation bar.  The default is 'icons'.
    --title str     Set the page title to 'str'.  The default is 'Global
                    Module Index'.
    --uplink url    Set the upward link URL.  The default is './'.
    --uptitle str   Set the upward link title.  The default is 'Python
                    Documentation Index'.
"""
import os
import re
import sys

from xml.sax.saxutils import quoteattr

import buildindex
import support


class IndexOptions(support.Options):
    aesop_type = "links"

    def __init__(self):
        support.Options.__init__(self)
        self.add_args("l", ["letters"])
        self.letters = 0

    def handle_option(self, opt, val):
        if opt in ("-l", "--letters"):
            self.letters = 1

    def usage(self):
        program = os.path.basename(sys.argv[0])
        print __doc__ % {"program": program}

    links = [
        ('author', 'acks.html',  'Acknowledgements'),
        ('help',   'about.html', 'About the Python Documentation'),
        ]

    def get_header(self):
        header = support.Options.get_header(self)
        s = ''
        for rel, href, title in self.links:
            s += '<link rel="%s" href="%s"' % (rel, href)
            if title:
                s += ' title=' + quoteattr(title)
            s += '>\n  '
        return header.replace("<link ", s + "<link ", 1)


class Node(buildindex.Node):
    def __init__(self, link, str, seqno, platinfo):
        self.annotation = platinfo or None
        if str[0][-5:] == "</tt>":
            str = str[:-5]
        self.modname = str
        buildindex.Node.__init__(self, link, self.modname, seqno)
        if platinfo:
            s = '<tt class="module">%s</tt> %s' \
                % (self.modname, self.annotation)
        else:
            s = '<tt class="module">%s</tt>' % str
        self.text = [s]

    def __str__(self):
        if self.annotation:
            return '<tt class="module">%s</tt> %s' \
                   % (self.modname, self.annotation)
        else:
            return '<tt class="module">%s</tt>' % self.modname

_rx = re.compile(
    "<dt><a href=['\"](module-.*\.html)(?:#l2h-\d+)?['\"]>"
    "<tt class=['\"]module['\"]>([a-zA-Z_][a-zA-Z0-9_.]*)</tt>\s*(<em>"
    "\(<span class=['\"]platform['\"]>.*</span>\)</em>)?</a>")

def main():
    options = IndexOptions()
    options.variables["title"] = "Global Module Index"
    options.parse(sys.argv[1:])
    args = options.args
    if not args:
        args = ["-"]
    #
    # Collect the input data:
    #
    nodes = []
    has_plat_flag = 0
    for ifn in args:
        if ifn == "-":
            ifp = sys.stdin
            dirname = ''
        else:
            ifp = open(ifn)
            dirname = os.path.dirname(ifn)
        while 1:
            line = ifp.readline()
            if not line:
                break
            m = _rx.match(line)
            if m:
                # This line specifies a module!
                basename, modname, platinfo = m.group(1, 2, 3)
                has_plat_flag = has_plat_flag or platinfo
                linkfile = os.path.join(dirname, basename)
                nodes.append(Node('<a href="%s">' % linkfile, modname,
                                  len(nodes), platinfo))
        ifp.close()
    #
    # Generate all output:
    #
    num_nodes = len(nodes)
    # Here's the HTML generation:
    parts = [options.get_header(),
             buildindex.process_nodes(nodes, options.columns, options.letters),
             options.get_footer(),
             ]
    if has_plat_flag:
        parts.insert(1, PLAT_DISCUSS)
    html = ''.join(parts)
    program = os.path.basename(sys.argv[0])
    fp = options.get_output_file()
    fp.write(html.rstrip() + "\n")
    if options.outputfile == "-":
        sys.stderr.write("%s: %d index nodes\n" % (program, num_nodes))
    else:
        print
        print "%s: %d index nodes" % (program, num_nodes)


PLAT_DISCUSS = """
<p> Some module names are followed by an annotation indicating what
platform they are available on.</p>

"""


if __name__ == "__main__":
    main()
