File: Synopsis/Formatters/HTML/Views/NameIndex.py
  1#
  2# Copyright (C) 2000 Stephen Davies
  3# Copyright (C) 2000 Stefan Seefeld
  4# All rights reserved.
  5# Licensed to the public under the terms of the GNU LGPL (>= 2),
  6# see the file COPYING for details.
  7#
  8
  9from Synopsis import config
 10from Synopsis.Processor import Parameter
 11from Synopsis import ASG
 12from Synopsis.Formatters.HTML.View import View
 13from Synopsis.Formatters.HTML.Tags import *
 14import time
 15
 16class NameIndex(View):
 17    """Creates an index of all names on one view in alphabetical order."""
 18
 19    columns = Parameter(2, 'the number of columns for the listing')
 20
 21    def filename(self):
 22
 23        if self.main:
 24            return self.directory_layout.index()
 25        else:
 26            return self.directory_layout.special('NameIndex')
 27
 28    def title(self):
 29
 30        return 'Name Index'
 31
 32    def root(self):
 33
 34        return self.filename(), self.title()
 35
 36    def process(self):
 37
 38        self.start_file()
 39        self.write_navigation_bar()
 40        self.write(element('h1', 'Name Index'))
 41        self.write('<i>Hold the mouse over a link to see the scope of each name</i>\n')
 42
 43        dict = self.make_dictionary()
 44        keys = dict.keys()
 45        keys.sort()
 46        linker = lambda key: '<a href="#key%d">%s</a>'%(ord(key),key)
 47        self.write(div('nameindex-index', ''.join([linker(k) for k in keys])) + '\n')
 48        for key in keys:
 49            self.write('<a id="key%d">'%ord(key)+'</a>')
 50            self.write(element('h2', key) + '\n')
 51            self.write('<table summary="table of names">\n')
 52            self.write('<col width="*"/>'*self.columns + '\n')
 53            self.write('<tr>\n')
 54            items = dict[key]
 55            numitems = len(items)
 56            start = 0
 57            for column in range(self.columns):
 58                end = numitems * (column + 1) / self.columns
 59                self.write('<td valign="top">\n')
 60                for item in items[start:end]:
 61                    self._process_item(item)
 62                self.write('</td>\n')
 63                start = end
 64            self.write('</tr>\n</table>\n')
 65
 66        self.end_file()
 67
 68    def make_dictionary(self):
 69        """Returns a dictionary of items. The keys of the dictionary are the
 70        headings - the first letter of the name. The values are each a sorted
 71        list of items with that first letter."""
 72
 73        dict = {}
 74        def hasher(type):
 75            name = type.name
 76            try: key = name[-1][0]
 77            except:
 78                print 'name:',name, 'type:',repr(type), id(type)
 79                raise
 80            if key >= 'a' and key <= 'z': key = chr(ord(key) - 32)
 81            if dict.has_key(key): dict[key].append(type)
 82            else: dict[key] = [type]
 83        # Fill the dict
 84        [hasher(t) for t in self.processor.ir.asg.types.values()
 85         if isinstance(t, ASG.DeclaredTypeId) and
 86         not isinstance(t.declaration, ASG.Builtin)]
 87
 88        # Now sort the dict
 89        def name_cmp(a,b):
 90            a, b = a.name, b.name
 91            res = cmp(a[-1],b[-1])
 92            if res == 0: res = cmp(a,b)
 93            return res
 94        for items in dict.values():
 95            items.sort(name_cmp)
 96
 97        return dict
 98
 99    def _process_item(self, type):
100        """Process the given name for output"""
101
102        name = type.name
103        decl = type.declaration # non-declared types are filtered out
104        if isinstance(decl, ASG.Function):
105            realname = escape(decl.real_name[-1]) + '()'
106        else:
107            realname = escape(name[-1])
108        self.write('\n')
109        title = escape(str(name))
110        type = decl.type
111        name = self.reference(name, (), realname, title=title)+' '+type
112        self.write(div('nameindex-item', name))
113
114    def end_file(self):
115        """Overrides end_file to provide synopsis logo"""
116
117        self.write('\n')
118        now = time.strftime(r'%c', time.localtime(time.time()))
119        logo = img(src=rel(self.filename(), 'synopsis.png'), alt='logo')
120        logo = href('http://synopsis.fresco.org', logo + ' synopsis', target='_blank')
121        logo += ' (version %s)'%config.version
122        self.write(div('logo', 'Generated on ' + now + ' by \n<br/>\n' + logo))
123        View.end_file(self)
124