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(''.join([linker(k) for k in keys]),
 48                       class_='nameindex-index') + '\n')
 49        for key in keys:
 50            self.write('<a id="key%d">'%ord(key)+'</a>')
 51            self.write(element('h2', key) + '\n')
 52            self.write('<table summary="table of names">\n')
 53            self.write('<col width="*"/>'*self.columns + '\n')
 54            self.write('<tr>\n')
 55            items = dict[key]
 56            numitems = len(items)
 57            start = 0
 58            for column in range(self.columns):
 59                end = numitems * (column + 1) / self.columns
 60                self.write('<td valign="top">\n')
 61                for item in items[start:end]:
 62                    self._process_item(item)
 63                self.write('</td>\n')
 64                start = end
 65            self.write('</tr>\n</table>\n')
 66
 67        self.end_file()
 68
 69    def make_dictionary(self):
 70        """Returns a dictionary of items. The keys of the dictionary are the
 71        headings - the first letter of the name. The values are each a sorted
 72        list of items with that first letter."""
 73
 74        dict = {}
 75        def hasher(type):
 76            name = type.name
 77            try: key = name[-1][0]
 78            except:
 79                print 'name:',name, 'type:',repr(type), id(type)
 80                raise
 81            if key >= 'a' and key <= 'z': key = chr(ord(key) - 32)
 82            if dict.has_key(key): dict[key].append(type)
 83            else: dict[key] = [type]
 84        # Fill the dict
 85        [hasher(t) for t in self.processor.ir.asg.types.values()
 86         if isinstance(t, ASG.DeclaredTypeId) and
 87         not isinstance(t.declaration, ASG.Builtin)]
 88
 89        # Now sort the dict
 90        def name_cmp(a,b):
 91            a, b = a.name, b.name
 92            res = cmp(a[-1],b[-1])
 93            if res == 0: res = cmp(a,b)
 94            return res
 95        for items in dict.values():
 96            items.sort(name_cmp)
 97
 98        return dict
 99
100    def _process_item(self, type):
101        """Process the given name for output"""
102
103        name = type.name
104        decl = type.declaration # non-declared types are filtered out
105        if isinstance(decl, ASG.Function):
106            realname = escape(decl.real_name[-1]) + '()'
107        else:
108            realname = escape(name[-1])
109        self.write('\n')
110        title = escape(str(name))
111        type = decl.type
112        # The name index should not list function or template parameters
113        # or local variables. There are just too many of them...
114        # typenames are not referring to actual (declared) types,
115        # so aren't meaningful here either.
116        if type not in ['parameter', 'local variable', 'typename']:
117            name = self.reference(name, (), realname, title=title)+' '+type
118            self.write(div(name, class_='nameindex-item'))
119
120    def end_file(self):
121        """Overrides end_file to provide synopsis logo"""
122
123        self.write('\n')
124        now = time.strftime(r'%c', time.localtime(time.time()))
125        logo = img(src=rel(self.filename(), 'synopsis.png'), alt='logo')
126        logo = href('http://synopsis.fresco.org', logo + ' synopsis', target='_blank')
127        logo += ' (version %s)'%config.version
128        self.write(div('Generated on ' + now + ' by \n<br/>\n' + logo, class_='logo'))
129        View.end_file(self)
130