Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Formatter/HTML/NameIndex.py
    1| # $Id: NameIndex.py,v 1.10 2002/11/01 07:21:15 chalky Exp $
    2| #
    3| # This file is a part of Synopsis.
    4| # Copyright (C) 2000, 2001 Stephen Davies
    5| # Copyright (C) 2000, 2001 Stefan Seefeld
    6| #
    7| # Synopsis is free software; you can redistribute it and/or modify it
    8| # under the terms of the GNU General Public License as published by
    9| # the Free Software Foundation; either version 2 of the License, or
   10| # (at your option) any later version.
   11| #
   12| # This program is distributed in the hope that it will be useful,
   13| # but WITHOUT ANY WARRANTY; without even the implied warranty of
   14| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15| # General Public License for more details.
   16| #
   17| # You should have received a copy of the GNU General Public License
   18| # along with this program; if not, write to the Free Software
   19| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   20| # 02111-1307, USA.
   21| #
   22| # $Log: NameIndex.py,v $
   23| # Revision 1.10  2002/11/01 07:21:15  chalky
   24| # More HTML formatting fixes eg: ampersands and stuff
   25| #
   26| # Revision 1.9  2002/11/01 03:39:21  chalky
   27| # Cleaning up HTML after using 'htmltidy'
   28| #
   29| # Revision 1.8  2002/07/04 06:43:18  chalky
   30| # Improved support for absolute references - pages known their full path.
   31| #
   32| # Revision 1.7  2002/03/14 00:19:47  chalky
   33| # Added demo of template specializations, and fixed HTML formatter to deal with
   34| # angle brackets in class names :)
   35| #
   36| # Revision 1.6  2001/07/10 14:41:22  chalky
   37| # Make treeformatter config nicer
   38| #
   39| # Revision 1.5  2001/07/05 05:39:58  stefan
   40| # advanced a lot in the refactoring of the HTML module.
   41| # Page now is a truely polymorphic (abstract) class. Some derived classes
   42| # implement the 'filename()' method as a constant, some return a variable
   43| # dependent on what the current scope is...
   44| #
   45| # Revision 1.4  2001/07/05 02:08:35  uid20151
   46| # Changed the registration of pages to be part of a two-phase construction
   47| #
   48| # Revision 1.3  2001/06/28 07:22:18  stefan
   49| # more refactoring/cleanup in the HTML formatter
   50| #
   51| # Revision 1.2  2001/06/26 04:32:16  stefan
   52| # A whole slew of changes mostly to fix the HTML formatter's output generation,
   53| # i.e. to make the output more robust towards changes in the layout of files.
   54| #
   55| # the rpm script now works, i.e. it generates source and binary packages.
   56| #
   57| # Revision 1.1  2001/02/13 02:54:15  chalky
   58| # Added Name Index page
   59| #
   60| #
   61| 
   62| import os
   63| from Synopsis.Core import AST, Type
   64| from Synopsis.Formatter.HTML import core, Tags, Page
   65| from Tags import *
   66| from core import config
   67| 
   68| class NameIndex (Page.Page):
   69|     """Creates an index of all names on one page in alphabetical order"""
   70|     def __init__(self, manager):
   71|         Page.Page.__init__(self, manager)
   72| 
   73|     def filename(self): return config.files.nameOfSpecial('NameIndex')
   74|     def title(self): return 'Synopsis - Name Index'
   75| 
   76|     def register(self):
   77|         self.manager.addRootPage(self.filename(), 'Name Index', 'main', 1)
   78| 
   79|     def process(self, start):
   80|         """Creates the page. It is created as a list of tables, one for each
   81|         letter. The tables have a number of columns, which is 2 by default.
   82|         _processItem is called for each item in the dictionary."""
   83|         self.start_file()
   84|         self.write(self.manager.formatHeader(self.filename()))
   85|         self.write(entity('h1', "Name Index"))
   86|         self.write('<i>Hold the mouse over a link to see the scope of each name</i>')
   87| 
   88|         dict = self._makeDict()
   89|         keys = dict.keys()
   90|         keys.sort()
   91|         columns = 2 # TODO set from config
   92|         linker = lambda key: '<a href="#%s">%s</a>'%(ord(key),key)
   93|         self.write(div('nameindex-index', string.join(map(linker, keys))))
   94|         for key in keys:
   95|             self.write('<a name="%s">'%ord(key)+'</a>')
   96|             self.write(entity('h2', key))
   97|             self.write('<table border=0 width="100%" summary="table of names">')
   98|             self.write('<col width="*">'*columns)
   99|             self.write('<tr>')
  100|             items = dict[key]
  101|             numitems = len(items)
  102|             start = 0
  103|             for column in range(columns):
  104|                end = numitems * (column+1) / columns
  105|                self.write('<td valign=top>')
  106|                for item in items[start:end]:
  107|                    self._processItem(item)
  108|                self.write('</td>')
  109|                start = end
  110|             self.write('</tr></table>')
  111|         
  112|         self.end_file()
  113| 
  114|     def _makeDict(self):
  115|         """Returns a dictionary of items. The keys of the dictionary are the
  116|         headings - the first letter of the name. The values are each a sorted
  117|         list of items with that first letter."""
  118|         decl_filter = lambda type: isinstance(type, Type.Declared)
  119|         def name_cmp(a,b):
  120|             a, b = a.name(), b.name()
  121|             res = cmp(a[-1],b[-1])
  122|             if res == 0: res = cmp(a,b)
  123|             return res
  124|         dict = {}
  125|         def hasher(type, dict=dict):
  126|             name = type.name()
  127|             try: key = name[-1][0]
  128|            except:
  129|                print 'name:',name, 'type:',repr(type)
  130|         raise
  131|             if key >= 'a' and key <= 'z': key = chr(ord(key) - 32)
  132|             if dict.has_key(key): dict[key].append(type)
  133|             else: dict[key] = [type]
  134|         # Fill the dict
  135|         map(hasher, filter(decl_filter, config.types.values()))
  136|         # Now sort the dict
  137|         for items in dict.values():
  138|             items.sort(name_cmp)
  139|         return dict
  140| 
  141|     def _processItem(self, type):
  142|         """Process the given name for output"""
  143|         name = type.name()
  144|         decl = type.declaration() # non-declared types are filtered out
  145|         if isinstance(decl, AST.Function):
  146|             realname = anglebrackets(decl.realname()[-1]) + '()'
  147|         else:
  148|             realname = anglebrackets(name[-1])
  149|         self.write('\n')
  150|         title = anglebrackets(string.join(name, '::'))
  151|         type = decl.type()
  152|         name = self.reference(name, (), realname, title=title)+' '+type
  153|         self.write(div('nameindex-item', name))
  154| 
  155| htmlPageClass = NameIndex