File: Synopsis/Formatters/TOC.py
  1#
  2# Copyright (C) 2000 Stefan Seefeld
  3# Copyright (C) 2000 Stephen Davies
  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
  9"""Table of Contents classes"""
 10
 11from Synopsis import ASG
 12
 13import re
 14
 15class Linker:
 16   """Abstract class for linking declarations. This class has only one
 17   method, link(decl), which returns the link for the given declaration. This
 18   is dependant on the type of formatter used, and so a Linker derivative
 19   must be passed to the TOC upon creation."""
 20
 21   def link(decl): pass
 22
 23class TOC(ASG.Visitor):
 24   """Maintains a dictionary of all declarations which can be looked up
 25   to create cross references. Names are fully scoped."""
 26
 27   class Entry:
 28      """Struct for an entry in the table of contents.
 29      Vars: link, lang, type (all strings)
 30      Also: name (scoped)"""
 31
 32      def __init__(self, name, link, lang, type):
 33
 34         self.name = name
 35         self.link = link
 36         self.lang = lang
 37         self.type = type
 38
 39   def __init__(self, linker, verbose = False):
 40      """linker is an instance that implements the Linker interface and is
 41      used to generate the links from declarations."""
 42
 43      self.__toc = {}
 44      self.linker = linker
 45      self.verbose = verbose
 46
 47   def keys(self): return self.__toc.keys()
 48
 49   def lookup(self, name):
 50
 51      name = tuple(name)
 52      if self.__toc.has_key(name): return self.__toc[name]
 53      if self.verbose and len(name) > 1:
 54         print "Warning: TOC lookup of",name,"failed!"
 55      return None
 56
 57   def size(self): return len(self.__toc)
 58
 59   __getitem__ = lookup
 60
 61   def insert(self, entry):
 62      self.__toc[tuple(entry.name)] = entry
 63
 64   def store(self, file):
 65      """store the table of contents into a file, such that it can be used later when cross referencing"""
 66
 67      fout = open(file, 'w')
 68      nocomma = lambda str: str.replace("&","&").replace(",","&2c;")
 69      for name in self.__toc.keys():
 70         scopedname = nocomma('::'.join(name))
 71         lang = self.__toc[tuple(name)].lang
 72         link = nocomma(self.__toc[tuple(name)].link)
 73         fout.write(scopedname + "," + lang + "," + link + "\n")
 74
 75   def load(self, resource):
 76
 77      args = resource.split('|')
 78      file = args[0]
 79      if len(args) > 1: url = args[1]
 80      else: url = ""
 81      fin = open(file, 'r')
 82      line = fin.readline()
 83      recomma = lambda str: re.sub('&2c;', ',', str)
 84      while line:
 85         if line[-1] == '\n': line = line[:-1]
 86         scopedname, lang, link = line.split(',')
 87         scopedname, link = recomma(scopedname), recomma(link)
 88         param_index = scopedname.find('(')
 89         if param_index >= 0:
 90            name = scopedname[:param_index].split('::')
 91            name = name[:-1] + [name[-1]+scopedname[param_index:]]
 92         else:
 93            name = scopedname.split('::')
 94         if len(url): link = '/'.join([url, link])
 95         entry = TOC.Entry(name, link, lang, "decl")
 96         self.insert(entry)
 97         line = fin.readline()
 98
 99   def visit_declaration(self, decl):
100
101      file = decl.file
102      entry = TOC.Entry(decl.name, self.linker.link(decl),
103                        file and file.annotations['language'] or '', 'decl')
104      self.insert(entry)
105
106