Synopsis - Synopsis/Formatters/HTML/Views/FileDetails.py

File: Synopsis/Formatters/HTML/Views/FileDetails.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.Processor import Parameter
     10from Synopsis import ASG
     11from Synopsis.Formatters.HTML.View import View
     12from Synopsis.Formatters.HTML.Tags import *
     13from Source import *
     14import os
     15
     16class FileDetails(View):
     17   """A view that creates an index of files, and an index for each file.
     18   First the index of files is created, intended for the top-left frame.
     19   Second a view is created for each file, listing the major declarations for
     20   that file, eg: classes, global functions, namespaces, etc."""
     21
     22   def register(self, frame):
     23
     24      super(FileDetails, self).register(frame)
     25      self.__filename = ''
     26      self.__title = ''
     27      self.link_source = self.processor.has_view('Source') and self.processor.sxr_prefix
     28
     29
     30   def filename(self):
     31      """since FileTree generates a whole file hierarchy, this method returns the current filename,
     32      which may change over the lifetime of this object"""
     33
     34      return self.__filename
     35
     36   def title(self):
     37      """since FileTree generates a while file hierarchy, this method returns the current title,
     38      which may change over the lifetime of this object"""
     39
     40      return self.__title
     41
     42   def register_filenames(self):
     43      """Registers a view for each file indexed."""
     44
     45      for filename, file in self.processor.ir.files.items():
     46         if file.annotations['primary']:
     47            filename = self.directory_layout.file_details(filename)
     48            self.processor.register_filename(filename, self, file)
     49
     50   def process(self):
     51      """Creates a view for each known source file."""
     52
     53      for filename, file in self.processor.ir.files.items():
     54         if file.annotations['primary']:
     55            self.process_file(filename, file)
     56
     57   def process_file(self, filename, file):
     58      """Creates a view for the given file. The view is just an index,
     59      containing a list of declarations."""
     60
     61      # set up filename and title for the current view
     62      self.__filename = self.directory_layout.file_details(filename)
     63      # (get rid of ../'s in the filename)
     64      name = filename.split(os.sep)
     65      while len(name) and name[0] == '..': del name[0]
     66      self.__title = os.sep.join(name)+' Details'
     67
     68      self.start_file()
     69      self.write_navigation_bar()
     70      self.write(element('h1', os.sep.join(name)))
     71      if self.link_source:
     72         link = rel(self.filename(),
     73                    self.directory_layout.file_source(filename))
     74         self.write(div('', href(link, 'source code', target='content')) + '\n')
     75
     76      # Print list of includes
     77      try:
     78         # Only show files from the project
     79         includes = [i for i in file.includes if i.target.annotations['primary']]
     80         self.write('<h2 class="heading">Includes from this file:</h2>')
     81         if not includes:
     82            self.write('<p>No includes.</p>\n')
     83         else:
     84            self.write('<ul>\n')
     85            for include in includes:
     86               target_filename = include.target.name
     87               if include.is_next: idesc = 'include_next '
     88               else: idesc = 'include '
     89               if include.is_macro: idesc = idesc + 'from macro '
     90               link = rel(self.filename(), self.directory_layout.file_details(target_filename))
     91               self.write('<li>' + idesc + href(link, target_filename)+'</li>\n')
     92            self.write('</ul>\n')
     93      except:
     94         pass
     95
     96      self.write('<h2 class="heading">Declarations in this file:</h2>\n')
     97      # Sort items (by name)
     98      items = [(d.type, d.name, d) for d in file.declarations
     99               # We don't want to list (function, template) parameters, and neither 'this'.
    100               if type(d) is not ASG.Parameter and d.type not in ('this', 'parameter', 'local variable')]
    101      # ignore ASG.Builtin
    102      items = [i for i in items if not isinstance(i[2], ASG.Builtin)]
    103      items.sort()
    104      curr_scope = None
    105      curr_type = None
    106      for decl_type, name, decl in items:
    107         # Check scope and type to see if they've changed since the last
    108         # declaration, thereby forming sections of scope and type
    109         decl_scope = name[:-1]
    110         if decl_scope != curr_scope or decl_type != curr_type:
    111            if curr_scope is not None:
    112               self.write('\n</div>\n')
    113            curr_scope = decl_scope
    114            curr_type = decl_type
    115            if len(curr_type) and curr_type[-1] == 's': plural = 'es'
    116            else: plural = 's'
    117            if len(curr_scope):
    118               self.write('<div><h3>%s%s in %s</h3>\n'%(
    119                  curr_type.capitalize(), plural, escape(str(curr_scope))))
    120            else:
    121               self.write('<div><h3>%s%s</h3>\n'%(curr_type.capitalize(),plural))
    122
    123         # Format this declaration
    124         entry = self.processor.toc[name]
    125         label = escape(str(curr_scope.prune(name)))
    126         label = replace_spaces(label)
    127         if entry:
    128            link = rel(self.filename(), entry.link)
    129            item = href(link, label)
    130         else:
    131            item = label
    132         doc = div('doc', self.processor.documentation.summary(decl, self))
    133         self.write(div('item', item + '\n' + doc) + '\n')
    134
    135      # Close open div
    136      if curr_scope is not None:
    137         self.write('</div>\n')
    138      self.end_file()
    139

Generated on Thu Apr 16 16:27:16 2009 by
synopsis (version devel)