Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Formatter/HTML/XRefPages.py
    1| # $Id: XRefPages.py,v 1.9 2002/12/09 04:00:59 chalky Exp $
    2| #
    3| # This file is a part of Synopsis.
    4| # Copyright (C) 2002 Stephen Davies
    5| #
    6| # Synopsis is free software; you can redistribute it and/or modify it
    7| # under the terms of the GNU General Public License as published by
    8| # the Free Software Foundation; either version 2 of the License, or
    9| # (at your option) any later version.
   10| #
   11| # This program is distributed in the hope that it will be useful,
   12| # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14| # General Public License for more details.
   15| #
   16| # You should have received a copy of the GNU General Public License
   17| # along with this program; if not, write to the Free Software
   18| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   19| # 02111-1307, USA.
   20| #
   21| # $Log: XRefPages.py,v $
   22| # Revision 1.9  2002/12/09 04:00:59  chalky
   23| # Added multiple file support to parsers, changed AST datastructure to handle
   24| # new information, added a demo to demo/C++. AST Declarations now have a
   25| # reference to a SourceFile (which includes a filename) instead of a filename.
   26| #
   27| # Revision 1.8  2002/11/13 01:01:49  chalky
   28| # Improvements to links when using the Nested file layout
   29| #
   30| # Revision 1.7  2002/11/11 15:19:34  chalky
   31| # More fixes to get demo/C++ sxr working without frames
   32| #
   33| # Revision 1.6  2002/11/02 06:37:37  chalky
   34| # Allow non-frames output, some refactoring of page layout, new modules.
   35| #
   36| # Revision 1.5  2002/11/01 03:39:21  chalky
   37| # Cleaning up HTML after using 'htmltidy'
   38| #
   39| # Revision 1.4  2002/10/29 15:00:16  chalky
   40| # Don't show fully scoped name for child declarations
   41| #
   42| # Revision 1.3  2002/10/29 12:43:56  chalky
   43| # Added flexible TOC support to link to things other than ScopePages
   44| #
   45| # Revision 1.2  2002/10/29 01:35:58  chalky
   46| # Add descriptive comment and link to docs for scope in xref pages
   47| #
   48| # Revision 1.1  2002/10/28 17:39:36  chalky
   49| # Cross referencing support
   50| #
   51| 
   52| # System modules
   53| import os
   54| 
   55| # Synopsis modules
   56| from Synopsis.Core import AST, Type, Util
   57| 
   58| # Formatter modules
   59| from Synopsis.Formatter import TOC
   60| 
   61| # HTML modules
   62| import Page
   63| from core import config
   64| from Tags import *
   65| 
   66| class XRefLinker (TOC.Linker):
   67|     def __init__(self, xref):
   68|         self.xref = xref
   69|     def link(self, name):
   70|         return file
   71| 
   72| class XRefPages (Page.Page):
   73|     """A module for creating pages full of xref infos"""
   74|     def __init__(self, manager):
   75|         Page.Page.__init__(self, manager)
   76|         self.xref = config.xref
   77|         self.__filename = None
   78|         self.__title = None
   79|         self.__toc = None
   80|         self.__link_to_scopepages = 0
   81|         if hasattr(config.obj, 'XRefPages'):
   82|             if hasattr(config.obj.XRefPages, 'xref_file'):
   83|                self.xref.load(config.obj.XRefPages.xref_file)
   84|             if hasattr(config.obj.XRefPages, 'link_to_scopepages'):
   85|                self.__link_to_scopepages = config.obj.XRefPages.link_to_scopepages
   86| 
   87|     def get_toc(self, start):
   88|         """Returns the toc for XRefPages"""
   89|         if self.__toc: return self.__toc
   90|         self.__toc = TOC.TableOfContents(None)
   91|         # Add an entry for every xref
   92|         for name in self.xref.get_all_names():
   93|             page = self.xref.get_page_for(name)
   94|             file = config.files.nameOfSpecial('xref%d'%page)
   95|             file = file + '#' + Util.quote(string.join(name,'::'))
   96|             self.__toc.insert(TOC.TocEntry(name, file, 'C++', 'xref'))
   97|         return self.__toc
   98| 
   99|     def filename(self):
  100|         """Returns the current filename,
  101|         which may change over the lifetime of this object"""
  102|         return self.__filename
  103|     def title(self):
  104|         """Returns the current title,
  105|         which may change over the lifetime of this object"""
  106|         return self.__title
  107| 
  108|     def process(self, start):
  109|         """Creates a page for every bunch of xref infos"""
  110|         page_info = self.xref.get_page_info()
  111|         if not page_info: return
  112|         for i in range(len(page_info)):
  113|             self.__filename = config.files.nameOfSpecial('xref%d'%i)
  114|             self.__title = 'Cross Reference page #%d'%i
  115| 
  116|             self.start_file()
  117|             self.write(self.manager.formatHeader(self.filename()))
  118|             self.write(entity('h1', self.__title))
  119|             self.write('<hr>')
  120|             for name in page_info[i]:
  121|                self.process_name(name)
  122|             self.end_file()
  123| 
  124|     def register_filenames(self, start):
  125|         """Registers each page"""
  126|         page_info = self.xref.get_page_info()
  127|         if not page_info: return
  128|         for i in range(len(page_info)):
  129|             filename = config.files.nameOfSpecial('xref%d'%i)
  130|             self.manager.register_filename(filename, self, i)
  131|     
  132|     def process_link(self, file, line, scope):
  133|         """Outputs the info for one link"""
  134|         # Make a link to the highlighted source
  135|         realfile = os.path.join(config.base_dir, file)
  136|         file_link = config.files.nameOfFileSource(realfile)
  137|         file_link = file_link + "#%d"%line
  138|         # Try and make a descriptive
  139|         desc = ''
  140|         if config.types.has_key(scope):
  141|             type = config.types[scope]
  142|             if isinstance(type, Type.Declared):
  143|                desc = ' ' + type.declaration().type()
  144|         # Try and find a link to the scope
  145|         scope_text = string.join(scope, '::')
  146|         entry = config.toc[scope]
  147|         if entry:
  148|             scope_text = href(entry.link, scope_text)
  149|         # Output list element
  150|         self.write('<li><a href="%s">%s:%s</a>: in%s %s</li>\n'%(
  151|             file_link, file, line, desc, scope_text))
  152|     
  153|     def describe_decl(self, decl):
  154|         """Returns a description of the declaration. Detects constructors and
  155|         destructors"""
  156|         name = decl.name()
  157|         if isinstance(decl, AST.Function) and len(name) > 1:
  158|             real = decl.realname()[-1]
  159|             if name[-2] == real:
  160|                return 'Constructor '
  161|             elif real[0] == '~' and name[-2] == real[1:]:
  162|                return 'Destructor '
  163|         return decl.type().capitalize() + ' '
  164| 
  165|     def process_name(self, name):
  166|         """Outputs the info for a given name"""
  167| 
  168|         target_data = self.xref.get_info(name)
  169|         if not target_data: return
  170| 
  171|         jname = string.join(name, '::')
  172|         self.write(entity('a', '', name=Util.quote(jname)))
  173|         desc = ''
  174|         decl = None
  175|         if config.types.has_key(name):
  176|             type = config.types[name]
  177|             if isinstance(type, Type.Declared):
  178|                decl = type.declaration()
  179|                desc = self.describe_decl(decl)
  180|         self.write(entity('h2', desc + jname) + '<ul>\n')
  181|         
  182|         if self.__link_to_scopepages:
  183|             if config.types.has_key(name):
  184|                type = config.types[name]
  185|                if isinstance(type, Type.Declared):
  186|                    link = config.files.link(type.declaration())
  187|                    self.write('<li>'+href(rel(self.__filename, link), 'Documentation')+'</li>')
  188|         if target_data[0]:
  189|             self.write('<li>Defined at:<ul>\n')
  190|             for file, line, scope in target_data[0]:
  191|                self.process_link(file, line, scope)
  192|             self.write('</ul></li>\n')
  193|         if target_data[1]:
  194|             self.write('<li>Called from:<ul>\n')
  195|             for file, line, scope in target_data[1]:
  196|                self.process_link(file, line, scope)
  197|             self.write('</ul></li>\n')
  198|         if target_data[2]:
  199|             self.write('<li>Referenced from:<ul>\n')
  200|             for file, line, scope in target_data[2]:
  201|                self.process_link(file, line, scope)
  202|             self.write('</ul></li>\n')
  203|         if isinstance(decl, AST.Scope):
  204|             self.write('<li>Declarations:<ul>\n')
  205|             for child in decl.declarations():
  206|                file, line = child.file().filename(), child.line()
  207|                realfile = os.path.join(config.base_dir, file)
  208|                file_link = config.files.nameOfFileSource(realfile)
  209|                file_link = '%s#%d'%(file_link,line)
  210|                file_href = '<a href="%s">%s:%s</a>: '%(file_link,file,line)
  211|                cname = child.name()
  212|                entry = config.toc[cname]
  213|                type = self.describe_decl(child)
  214|                if entry:
  215|                    link = href(entry.link, Util.ccolonName(cname, name))
  216|                    self.write(entity('li', file_href + type + link))
  217|         else:
  218|                    self.write(entity('li', file_href + type + Util.ccolonName(cname, name)))
  219|             self.write('</ul></li>\n')
  220|         self.write('</ul><hr>\n')
  221| 
  222| htmlPageClass = XRefPages