Synopsis - Synopsis/Formatters/BoostBook.py

File: Synopsis/Formatters/BoostBook.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"""a BoostBook formatter"""
     10
     11from Synopsis.Processor import Processor, Parameter
     12from Synopsis import ASG
     13
     14import sys, getopt, os, os.path
     15
     16class Formatter(Processor, ASG.Visitor):
     17   """
     18   The type visitors should generate names relative to the current scope.
     19   The generated references however are fully scoped names
     20   """
     21
     22   def process(self, ir, **kwds):
     23
     24      self.set_parameters(kwds)
     25      self.ir = self.merge_input(ir)
     26
     27      self.__os = open(self.output, 'w')
     28      self.__scope = ()
     29      self.__scopestack = []
     30      self.__indent = 0
     31      self.__type_label = ''
     32
     33      for d in ir.asg.declarations:
     34         d.accept(self)
     35
     36      self.__os.close()
     37
     38      return self.ir
     39
     40   def scope(self): return self.__scope
     41   def push_scope(self, newscope):
     42
     43      self.__scopestack.append(self.__scope)
     44      self.__scope = newscope
     45
     46   def pop_scope(self):
     47
     48      self.__scope = self.__scopestack[-1]
     49      del self.__scopestack[-1]
     50
     51   def write(self, text):
     52      """Write some text to the output stream, replacing \n's with \n's and
     53      indents."""
     54
     55      indent = ' ' * self.__indent
     56      self.__os.write(text.replace('\n', '\n'+indent))
     57
     58   def start_entity(self, __type, **__params):
     59      """Write the start of an entity, ending with a newline"""
     60
     61      param_text = ""
     62      if __params: param_text = " " + string.join(map(lambda p:'%s="%s"'%(p[0].lower(), p[1]), __params.items()))
     63      self.write("<" + __type + param_text + ">")
     64      self.__indent = self.__indent + 2
     65      self.write("\n")
     66
     67   def end_entity(self, type):
     68      """Write the end of an entity, starting with a newline"""
     69
     70      self.__indent = self.__indent - 2
     71      self.write("\n</" + type + ">")
     72
     73   def write_entity(self, __type, __body, **__params):
     74      """Write a single entity on one line (though body may contain
     75      newlines)"""
     76
     77      param_text = ""
     78      if __params: param_text = " " + string.join(map(lambda p:'%s="%s"'%(p[0].lower(), p[1]), __params.items()))
     79      self.write("<" + __type + param_text + ">")
     80      self.__indent = self.__indent + 2
     81      self.write(__body)
     82      self.__indent = self.__indent - 2
     83      self.write("</" + __type + ">")
     84
     85   def entity(self, __type, __body, **__params):
     86      """Return but do not write the text for an entity on one line"""
     87
     88      param_text = ""
     89      if __params: param_text = " " + string.join(map(lambda p:'%s="%s"'%(p[0].lower(), p[1]), __params.items()))
     90      return "<%s%s>%s</%s>"%(__type, param_text, __body, __type)
     91
     92   def reference(self, ref, label):
     93      """reference takes two strings, a reference (used to look up the symbol and generated the reference),
     94      and the label (used to actually write it)"""
     95
     96      location = self.__toc.lookup(ref)
     97      if location != "": return href("#" + location, label)
     98      else: return span("type", str(label))
     99
    100   def label(self, ref):
    101
    102      location = self.__toc.lookup(str(ref))
    103      ref = str(self.scope().prune(ref))
    104      if location != "": return name("\"" + location + "\"", ref)
    105      else: return ref
    106
    107   def type_label(self): return self.__type_label
    108   #################### Type Visitor ##########################################
    109
    110   def visit_builtin_type_id(self, type):
    111
    112      self.__type_ref = str(type.name)
    113      self.__type_label = str(type.name)
    114
    115   def visit_unknown_type_id(self, type):
    116
    117      self.__type_ref = str(type.name)
    118      self.__type_label = str(self.scope().prune(type.name))
    119
    120   def visit_declared_type_id(self, type):
    121
    122      self.__type_label = str(self.scope().prune(type.name))
    123      self.__type_ref = str(type.name)
    124
    125   def visit_modifier_type_id(self, type):
    126
    127      type.alias.accept(self)
    128      self.__type_ref = ''.join(type.premod) + ' ' + self.__type_ref + ' ' + ''.join(type.postmod)
    129      self.__type_label = ''.join(type.premod) + ' ' + self.__type_label + ' ' + ''.join(type.postmod)
    130
    131   def visit_parametrized_type_id(self, type):
    132
    133      type.template.accept(self)
    134      type_label = self.__type_label + "&lt;"
    135      parameters_label = []
    136      for p in type.parameters:
    137         p.accept(self)
    138         parameters_label.append(self.__type_label)
    139      self.__type_label = type_label + ', '.join(parameters_label) + '&gt;'
    140
    141   def format_type(self, type):
    142
    143      type.accept(self)
    144      return self.__type_label
    145
    146   def visit_function_type_id(self, type):
    147
    148      # TODO: this needs to be implemented
    149      self.__type_ref = 'function_type'
    150      self.__type_label = 'function_type'
    151
    152   def process_doc(self, doc):
    153
    154      text = doc.replace('\n\n', '</para><para>')
    155      self.write(self.entity("para", text)+'\n')
    156
    157   #################### ASG Visitor ###########################################
    158
    159   def visit_declarator(self, node):
    160      self.__declarator = node.name
    161      for i in node.sizes:
    162         self.__declarator[-1] = self.__declarator[-1] + '[%d]'%i
    163
    164   def visit_typedef(self, typedef):
    165
    166      self.start_entity("typedef", name=str(self.scope().prune(typedef.name)))
    167      self.write_entity("type", self.format_type(typedef.alias))
    168      self.end_entity("typedef")
    169
    170   def visit_variable(self, variable):
    171
    172      self.start_entity("fieldsynopsis")
    173      variable.vtype.accept(self)
    174      self.entity("type", self.type_label())
    175      self.entity("varname", variable.name[-1])
    176      self.end_entity("fieldsynopsis")
    177
    178   def visit_const(self, const):
    179
    180      print "sorry, <const> not implemented"
    181
    182   def visit_module(self, module):
    183
    184      self.start_entity("namespace", name=str(self.scope().prune(module.name)))
    185      self.write("\n")
    186      self.process_doc(module.annotations.get('doc', ''))
    187      self.push_scope(module.name)
    188      for declaration in module.declarations: declaration.accept(self)
    189      self.pop_scope()
    190      self.end_entity("namespace")
    191
    192   def visit_class(self, class_):
    193
    194      self.start_entity("class", name=str(self.scope().prune(class_.name)))
    195      # class_.type
    196      for p in class_.parents:
    197         p.accept(self)
    198      self.push_scope(class_.name)
    199      if class_.annotations.has_key('doc'):
    200         self.start_entity("purpose")
    201         self.process_doc(class_.annotations.get['doc'])
    202         self.end_entity("purpose")
    203      for d in class_.declarations:
    204         d.accept(self)
    205      self.pop_scope()
    206      self.end_entity("class")
    207
    208   def visit_inheritance(self, inheritance):
    209
    210      if len(inheritance.attributes()):
    211         self.start_entity("inherit", access=inheritance.attributes()[0])
    212      else:
    213         self.start_entity("inherit")
    214      self.write_entity("classname", self.format_type(inheritance.parent()))
    215      self.end_entity("inherit")
    216
    217   def visit_parameter(self, parameter):
    218
    219      self.start_entity("parameter", name=parameter.name)
    220      self.write_entity("param_type", self.format_type(parameter.type))
    221      #map(lambda m, this=self: this.write_entity("modifier", m), parameter.premodifier)
    222      #map(lambda m, this=self: this.write_entity("modifier", m), parameter.postmodifier)
    223      self.end_entity("parameter")
    224      self.write("\n")
    225
    226   def visit_function(self, function):
    227
    228      self.start_entity("function", name=str(self.scope().prune(function.real_name)))
    229      self.do_function(function)
    230      self.end_entity("function")
    231      self.write("\n")
    232
    233   def visit_operation(self, operation):
    234
    235      name = operation.name
    236      tag = None
    237      if len(name) > 1:
    238         if name[-1] == name[-2]:
    239            tag = "constructor"
    240            self.start_entity(tag)
    241         elif name[-1] == "~"+name[-2]:
    242            tag = "destructor"
    243            self.start_entity(tag)
    244      if tag is None:
    245         tag = "method"
    246         self.start_entity(tag, name=str(self.scope().prune(operation.real_name)))
    247      self.do_function(operation)
    248      self.end_entity(tag)
    249      self.write("\n")
    250
    251   def do_function(self, func):
    252      """Stuff common to functions and methods, contructors, destructors"""
    253
    254      for parameter in func.parameters: parameter.accept(self)
    255      if func.return_type:
    256         self.write_entity("type", self.format_type(func.return_type))
    257         self.write("\n")
    258      if func.annotations.has_key('doc'):
    259         self.start_entity("purpose")
    260         self.process_doc(func.annotations['doc'])
    261         self.end_entity("purpose")
    262         self.write("\n")
    263
    264      if func.exceptions:
    265         self.start_entity("throws")
    266         for ex in func.exceptions:
    267            self.write_entity("simpara", ex)
    268         self.end_entity("throws")
    269         self.write("\n")
    270
    271   def visit_enumerator(self, enumerator):
    272
    273      print "sorry, <enumerator> not implemented"
    274
    275   def visit_enum(self, enum):
    276
    277      print "sorry, <enum> not implemented"
    278
    279

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