[Synopsis-changes] Synopsis/Synopsis/Synopsis/Formatters/HTML/Fragments ClassHierarchyGraph.py,NONE,1.1 ClassHierarchySimple.py,NONE,1.1 DeclarationFormatter.py,NONE,1.1 Default.py,NONE,1.1 DetailCommenter.py,NONE,1.1 DetailFormatter.py,NONE,1.1 HeadingFormatter.py,NONE,1.1 InheritanceFormatter.py,NONE,1.1 SourceLinker.py,NONE,1.1 SummaryCommenter.py,NONE,1.1 SummaryFormatter.py,NONE,1.1 XRefLinker.py,NONE,1.1 __init__.py,NONE,1.1

Stefan Seefeld stefan at synopsis.fresco.org
Fri Dec 5 22:31:55 UTC 2003


Update of /cvs/synopsis/Synopsis/Synopsis/Formatters/HTML/Fragments
In directory frida:/tmp/cvs-serv31759/Synopsis/Formatters/HTML/Fragments

Added Files:
	ClassHierarchyGraph.py ClassHierarchySimple.py 
	DeclarationFormatter.py Default.py DetailCommenter.py 
	DetailFormatter.py HeadingFormatter.py InheritanceFormatter.py 
	SourceLinker.py SummaryCommenter.py SummaryFormatter.py 
	XRefLinker.py __init__.py 
Log Message:
rename and refactor FormatStrategy -> Fragment

--- NEW FILE: ClassHierarchyGraph.py ---
# $Id: ClassHierarchyGraph.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis import AST, Type
from ClassHierarchySimple import ClassHierarchySimple
import os, string

class ClassHierarchyGraph(ClassHierarchySimple):
   """Prints a graphical hierarchy for classes, using the Dot formatter.
   
   @see Formatters.Dot
   """
   def format_class(self, clas):
      try:
         import tempfile
         from Synopsis.Formatters import Dot
      except:
         print "HierarchyGraph: Dot not found"
         return ""
      super = self.processor.class_tree.superclasses(clas.name())
      sub = self.processor.class_tree.subclasses(clas.name())
      if len(super) == 0 and len(sub) == 0:
         # Skip classes with a boring graph
         return ''
      #label = self.processor.files.scoped_special('inheritance', clas.name())
      label = self.formatter.filename()[:-5] + '-inheritance.html'
      tmp = os.path.join(self.processor.output, label)
      ast = AST.AST({}, [clas], self.processor.ast.types())
      dot = Dot.Formatter()
      dot.toc = self.processor.toc
      dot.process(ast,
                  output=tmp,
                  format='html',
                  base_url=self.formatter.filename(),
                  type='single',
                  title=label)
      text = ''
      input = open(tmp, "r+")
      line = input.readline()
      while line:
         text = text + line
         line = input.readline()
      input.close()
      os.unlink(tmp)
      return text


--- NEW FILE: ClassHierarchySimple.py ---
# $Id: ClassHierarchySimple.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis.Formatters.HTML.Tags import *
from Synopsis.Formatters.HTML.Fragment import Fragment

class ClassHierarchySimple(Fragment):
   "Prints a simple text hierarchy for classes"

   def format_inheritance(self, inheritance):

      return '%s %s'%(self.format_modifiers(inheritance.attributes()),
                      self.format_type(inheritance.parent()))

   def format_class(self, clas):

      # Print out a list of the parents
      super = sub = ''
      if clas.parents():
         parents = map(self.format_inheritance, clas.parents())
         super = string.join(parents, ", ")
         super = div('superclasses', "Superclasses: "+super)

      # Print subclasses
      subs = self.processor.classTree.subclasses(clas.name())
      if subs:
         refs = map(self.reference, subs)
         sub = string.join(refs, ", ")
         sub = div('subclasses', "Known subclasses: "+sub) 
	
      return super + sub

--- NEW FILE: DeclarationFormatter.py ---
# $Id: DeclarationFormatter.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis import AST, Type, Util
from Synopsis.Formatters.HTML.Fragment import Fragment
from Synopsis.Formatters.HTML.Tags import *

import string

class DeclarationFormatter(Fragment):
   """Base class for SummaryFormatter and DetailFormatter.
    
   The two classes SummaryFormatter and DetailFormatter are actually
   very similar in operation, and so most of their methods are defined here.
   Both of them print out the definition of the declarations, including type,
   parameters, etc. Some things such as exception specifications are only
   printed out in the detailed version.
   """
   col_sep = '<td class="summ-info">'
   row_sep = '</tr><tr><td class="summ-info">'
   whole_row = '<td class="summ-start" colspan="2">'

   def format_parameters(self, parameters):
      "Returns formatted string for the given parameter list"

      return string.join(map(self.format_parameter, parameters), ", ")

   def format_declaration(self, decl):
      """The default is to return no type and just the declarations name for
      the name"""

      return self.col_sep + self.label(decl.name())

   def format_forward(self, decl): return self.format_declaration(decl)
   def format_group(self, decl):

      return self.col_sep + ''

   def format_scope(self, decl):
      """Scopes have their own pages, so return a reference to it"""

      name = decl.name()
      link = rel(self.formatter.filename(),
                 self.processor.file_layout.scope(name))
      return self.col_sep + href(link, anglebrackets(name[-1]))

   def format_module(self, decl): return self.format_scope(decl)
   def format_meta_module(self, decl): return self.format_module(decl)
   def format_class(self, decl): return self.format_scope(decl)

   def format_typedef(self, decl):
      "(typedef type, typedef name)"

      type = self.format_type(decl.alias())
      return type + self.col_sep +  self.label(decl.name())

   def format_enumerator(self, decl):
      """This is only called by formatEnum"""

      self.format_declaration(decl)

   def format_enum(self, decl):
      "(enum name, list of enumerator names)"

      type = self.label(decl.name())
      name = map(lambda enumor:enumor.name()[-1], decl.enumerators())
      name = string.join(name, ', ')
      return type + self.col_sep + name

   def format_variable(self, decl):

      # TODO: deal with sizes
      type = self.format_type(decl.vtype())
      return type + self.col_sep + self.label(decl.name())

   def format_const(self, decl):
      "(const type, const name = const value)"

      type = self.format_type(decl.ctype())
      name = self.label(decl.name()) + " = " + decl.value()
      return type + self.col_sep + name

   def format_function(self, decl):
      "(return type, func + params + exceptions)"

      premod = self.format_modifiers(decl.premodifier())
      type = self.format_type(decl.returnType())
      name = self.label(decl.name(), decl.realname())
      # Special C++ functions  TODO: maybe move to a separate AST formatter...
      if decl.language() == 'C++' and len(decl.realname())>1:
         if decl.realname()[-1] == decl.realname()[-2]: type = '<i>constructor</i>'
         elif decl.realname()[-1] == "~"+decl.realname()[-2]: type = '<i>destructor</i>'
         elif decl.realname()[-1] == "(conversion)":
            name = "(%s)"%type
      params = self.format_parameters(decl.parameters())
      postmod = self.format_modifiers(decl.postmodifier())
      raises = self.format_exceptions(decl)
      type = '%s %s'%(premod,type)
      # Prevent linebreaks on shorter lines
      if len(type) < 60:
         type = replace_spaces(type)
      if decl.type() == "attribute": name = '%s %s %s'%(name, postmod, raises)
      else: name = '%s(%s) %s %s'%(name, params, postmod, raises)
      if decl.template():
         templ = 'template &lt;%s&gt;'%(self.format_parameters(decl.template().parameters()),)
         templ = div('template', templ)
         return self.whole_row + templ + self.row_sep + type + self.col_sep + name
      return type + self.col_sep + name

   # Default operation is same as function, and quickest way is to assign:
   def format_operation(self, decl): return self.format_function(decl)

   def format_parameter(self, parameter):
      """Returns one string for the given parameter"""

      str = []
      keyword = lambda m,span=span: span("keyword", m)
      # Premodifiers
      str.extend(map(keyword, parameter.premodifier()))
      # Param Type
      id_holder = [parameter.identifier()]
      typestr = self.format_type(parameter.type(), id_holder)
      if typestr: str.append(typestr)
      # Postmodifiers
      str.extend(map(keyword, parameter.postmodifier()))
      # Param identifier
      if id_holder and len(parameter.identifier()) != 0:
         str.append(span("variable", parameter.identifier()))
      # Param value
      if len(parameter.value()) != 0:
         str.append(" = " + span("value", parameter.value()))
      return string.join(str)


--- NEW FILE: Default.py ---
# $Id: Default.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis.Formatters.HTML.Fragment import Fragment

class Default(Fragment):
   """A base AST strategy that calls format_declaration for all types"""

   # All these use the same method:
   def format_forward(self, decl): return self.format_declaration(decl)
   def format_group(self, decl): return self.format_declaration(decl)
   def format_scope(self, decl): return self.format_declaration(decl)
   def format_module(self, decl): return self.format_declaration(decl)
   def format_meta_module(self, decl): return self.format_declaration(decl)
   def format_class(self, decl): return self.format_declaration(decl)
   def format_typedef(self, decl): return self.format_declaration(decl)
   def format_enum(self, decl): return self.format_declaration(decl)
   def format_variable(self, decl): return self.format_declaration(decl)
   def format_const(self, decl): return self.format_declaration(decl)
   def format_function(self, decl): return self.format_declaration(decl)
   def format_operation(self, decl): return self.format_declaration(decl)

--- NEW FILE: DetailCommenter.py ---
# $Id: DetailCommenter.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis.Formatters.HTML.Tags import *
from Default import Default

class DetailCommenter(Default):
   """Adds summary comments to all declarations"""

   def format_declaration(self, decl):

      text = self.processor.comments.format(self.page, decl)
      if text: return desc(text)
      return ''


--- NEW FILE: DetailFormatter.py ---
# $Id: DetailFormatter.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from DeclarationFormatter import DeclarationFormatter
from Synopsis.Formatters.HTML.Tags import *

class DetailFormatter(DeclarationFormatter):
   """Provide detail-specific Declaration formatting."""

   col_sep = ' '
   row_sep = '<br>'
   whole_row = ''

   def format_exceptions(self, oper):
      """Prints out the full exception spec"""

      if len(oper.exceptions()):
         raises = span("keyword", "raises")
         exceptions = []
         for exception in oper.exceptions():
            exceptions.append(self.reference(exception.name()))
         exceptions = span("raises", string.join(exceptions, ", "))
         return '%s (%s)'%(raises, exceptions)
      return ''

   def format_enum(self, enum):

      name = span("keyword", "enum ") + self.label(enum.name())
      start = '<div class="enum">'
      enumors = string.join(map(self.format_enumerator, enum.enumerators()))
      end = "</div>"
      return '%s%s%s%s'%(name, start, enumors, end)

   def format_enumerator(self, enumerator):

      text = self.label(enumerator.name())
      if len(enumerator.value()):
         value = " = " + span("value", enumerator.value())
      else: value = ''
      comments = self.processor.comments.format(self.page, enumerator)
      return '<div class="enumerator">%s%s%s</div>'%(text,value,comments)


--- NEW FILE: HeadingFormatter.py ---
# $Id: HeadingFormatter.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis import AST, Type
from Synopsis.Formatters.HTML.Fragment import Fragment
from Synopsis.Formatters.HTML.Tags import *
import string

class HeadingFormatter(Fragment):
   """Formats the top of a page - it is passed only the Declaration that the
   page is for (a Module or Class)."""

   def format_name(self, scoped_name):
      """Formats a reference to each parent scope"""

      scope, text = [], []
      for name in scoped_name[:-1]:
         scope.append(name)
         text.append(self.reference(scope))
      text.append(anglebrackets(scoped_name[-1]))
      return string.join(text, "::\n") + '\n'

   def format_name_in_namespace(self, scoped_name):
      """Formats a reference to each parent scope, starting at the first
      non-module scope"""

      types = self.processor.ast.types()

      scope, text = [], []
      for name in scoped_name[:-1]:
         scope.append(name)
         if types.has_key(scope):
            ns_type = types[scope]
            if isinstance(ns_type, Type.Declared):
               decl = ns_type.declaration()
               if isinstance(decl, AST.Module):
                  # Skip modules (including namespaces)
                  continue
         text.append(self.reference(scope))
      text.append(anglebrackets(scoped_name[-1]))
      return string.join(text, "::\n") + '\n'

   def format_namespace_of_name(self, scoped_name):
      "Formats a reference to each parent scope and this one"

      types = self.processor.ast.types()

      scope, text = [], []
      last_decl = None
      for name in scoped_name:
         scope.append(name)
         if types.has_key(scope):
            ns_type = types[scope]
            if isinstance(ns_type, Type.Declared):
               decl = ns_type.declaration()
               if isinstance(decl, AST.Module):
                  # Only do modules and namespaces
                  text.append(self.reference(scope))
                  last_decl = decl
                  continue
         break
      return last_decl, string.join(text, "::") + '\n'

   def format_module(self, module):
      """Formats the module by linking to each parent scope in the name"""

      # Module details are only printed at the top of their page
      if not module.name():
         type, name = "Global", "Namespace"
      else:
         type = string.capitalize(module.type())
         name = self.format_name(module.name())
      name = entity('h1', "%s %s"%(type, name))
      return name

   def format_meta_module(self, module):
      """Calls formatModule"""

      return self.format_module(module)

   def format_class(self, clas):
      """Formats the class by linking to each parent scope in the name"""

      # Calculate the namespace string
      decl, namespace = self.format_namespace_of_name(clas.name())
      if decl:
         namespace = '%s %s'%(decl.type(), namespace)
         namespace = div('class-namespace', namespace)
      else:
         namespace = ''

      # Calculate template string
      templ = clas.template()
      if templ:
         params = templ.parameters()
         params = string.join(map(self.format_parameter, params), ', ')
         templ = div('class-template', "template &lt;%s&gt;"%params)
      else:
         templ = ''

      # Calculate class name string
      type = clas.type()
      name = self.format_name_in_namespace(clas.name())
      name = div('class-name', "%s %s"%(type, name))

      # Calculate file-related string
      file_name = rel(self.processor.output, clas.file().filename())
      # Try the file index page first
      file_link = self.processor.file_layout.file_index(clas.file().filename())
      if self.processor.filename_info(file_link):
         file_ref = href(rel(self.formatter.filename(), file_link), file_name, target="index")
      else:
         # Try source file next
         file_link = self.processor.file_layout.file_source(clas.file().filename())
         if self.processor.filename_info(file_link):
            file_ref = href(rel(self.formatter.filename(), file_link), file_name)
         else:
            file_ref = file_name
      files = "Files: "+file_ref + "<br>"

      return '%s%s%s%s'%(namespace, templ, name, files)

   def format_parameter(self, parameter):
      """Returns one string for the given parameter"""

      str = []
      keyword = lambda m,span=span: span("keyword", m)
      # Premodifiers
      str.extend(map(keyword, parameter.premodifier()))
      # Param Type
      typestr = self.format_type(parameter.type())
      if typestr: str.append(typestr)
      # Postmodifiers
      str.extend(map(keyword, parameter.postmodifier()))
      # Param identifier
      if len(parameter.identifier()) != 0:
         str.append(span("variable", parameter.identifier()))
      # Param value
      if len(parameter.value()) != 0:
         str.append(" = " + span("value", parameter.value()))
      return string.join(str)

--- NEW FILE: InheritanceFormatter.py ---
# $Id: InheritanceFormatter.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis.Formatters.HTML.Tags import *
from Default import Default
from Synopsis import Util

class InheritanceFormatter(Default):
   """Prints just the name of each declaration, with a link to its doc"""

   def format_declaration(self, decl, label=None):

      if not label: label = decl.name()[-1]
      fullname = Util.ccolonName(decl.name(), self.formatter.scope())
      title = decl.type() + " " + anglebrackets(fullname)
      return self.reference(decl.name(), label=label, title=title) + ' '

   def format_function(self, decl):

      return self.format_declaration(decl, label=decl.realname()[-1])

   def format_operation(self, decl): return self.format_function(decl)

--- NEW FILE: SourceLinker.py ---
# $Id: SourceLinker.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis.Formatters.HTML.Tags import *
from Default import Default

class SourceLinker(Default):
   """Adds a link to the decl on the file page to all declarations"""

   def format_declaration(self, decl):

      if not decl.file(): return ''
      filename = self.processor.file_layout.file_source(decl.file().filename())
      line = decl.line()
      link = filename + "#%d" % line
      return href(rel(self.formatter.filename(), link), "[Source]")

--- NEW FILE: SummaryCommenter.py ---
# $Id: SummaryCommenter.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis.Formatters.HTML.Tags import *
from Default import Default

class SummaryCommenter(Default):
   """Adds summary comments to all declarations"""

   def format_declaration(self, decl):
      summary = self.processor.comments.format_summary(self.page, decl)
      if summary:
         return '<br>'+span('summary', summary)
      return ''

   def format_group(self, decl):
      """Override for group to use the div version of commenting, and no
      <br> before"""

      summary = self.processor.comments.format(self.page, decl)
      if summary:
         return desc(summary)
      return ''
    

--- NEW FILE: SummaryFormatter.py ---
# $Id: SummaryFormatter.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from DeclarationFormatter import DeclarationFormatter

class SummaryFormatter(DeclarationFormatter):
   """Derives from BaseStrategy to provide summary-specific methods.
   Currently the only one is format_exceptions"""

   def format_exceptions(self, oper):
      """Returns a reference to the detail if there are any exceptions."""
      if len(oper.exceptions()):
         return self.reference(oper.name(), " raises")
      return ''

--- NEW FILE: XRefLinker.py ---
# $Id: XRefLinker.py,v 1.1 2003/12/05 22:31:53 stefan Exp $
#
# Copyright (C) 2000 Stephen Davies
# Copyright (C) 2000 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis.Formatters.HTML.Tags import *
from Default import Default
from Synopsis import Util

class XRefLinker(Default):
   """Adds an xref link to all declarations"""

   def register(self, formatter):

      Default.register(self, formatter)
      self.xref = self.processor.xref

   def format_declaration(self, decl):

      info = self.xref.get_info(decl.name())
      if not info:
         return ''
      page = self.xref.get_page_for(decl.name())
      filename = self.processor.file_layout.special('xref%d'%page)
      filename = filename + "#" + Util.quote(string.join(decl.name(), '::'))
      return href(rel(self.formatter.filename(), filename), "[xref]")


--- NEW FILE: __init__.py ---
from ClassHierarchySimple import ClassHierarchySimple
from ClassHierarchyGraph import ClassHierarchyGraph
from InheritanceFormatter import InheritanceFormatter
from HeadingFormatter import HeadingFormatter
from DetailFormatter import DetailFormatter
from SummaryFormatter import SummaryFormatter
from SummaryCommenter import SummaryCommenter
from DetailCommenter import DetailCommenter
from SourceLinker import SourceLinker
from XRefLinker import XRefLinker






More information about the Synopsis-changes mailing list