Synopsis - Synopsis/Formatters/Texinfo.py

File: Synopsis/Formatters/Texinfo.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 TexInfo formatter """
     10
     11from Synopsis.Processor import *
     12from Synopsis import ASG
     13from Synopsis.DocString import DocString
     14import sys, os, re
     15
     16
     17_tags = re.compile(r'@(?!(table|item|samp|end))')
     18def escape(text):
     19
     20   return _tags.sub('@@', text).replace('{', '@{').replace('}', '@}')
     21
     22
     23class MenuMaker(ASG.Visitor):
     24   """generate a texinfo menu for the declarations of a given scope"""
     25
     26   def __init__(self, scope, os):
     27
     28      self.scope = scope
     29      self.os = os
     30
     31   def write(self, text): self.os.write(text)
     32   def start(self): self.write('@menu\n')
     33   def end(self): self.write('@end menu\n')
     34   def visit_declaration(self, node):
     35
     36      name = escape(str(self.scope.prune(node.name)))
     37      self.write('* ' + name + '::\t' + node.type + '\n')
     38
     39   visit_group = visit_declaration
     40   visit_enum = visit_declaration
     41
     42class Formatter(Processor, ASG.Visitor):
     43   """The type visitors should generate names relative to the current scope.
     44   The generated references however are fully scoped names."""
     45
     46   def process(self, ir, **kwds):
     47
     48      self.set_parameters(kwds)
     49      if not self.output: raise MissingArgument('output')
     50      self.ir = self.merge_input(ir)
     51
     52      self.os = open(self.output, 'w+')
     53      self.scope = ()
     54      for d in self.ir.asg.declarations:
     55         d.accept(self)
     56
     57      return self.ir
     58
     59   def write(self, text): self.os.write(text)
     60
     61   def type_label(self): return escape(self.__type_label)
     62
     63   def decl_label(self, decl): return escape(decl[-1])
     64
     65   def format_type(self, type):
     66      "Returns a reference string for the given type object"
     67
     68      if type is None: return "(unknown)"
     69      type.accept(self)
     70      return self.type_label()
     71
     72   def format_comments(self, decl):
     73
     74      doc = decl.annotations.get('doc', DocString('', ''))
     75      # TODO: implement markup formatters for e.g. javadoc and rst
     76      self.write(escape(doc.text) + '\n')
     77
     78   #################### Type Visitor ###########################################
     79
     80   def visit_builtin_type_id(self, type):
     81
     82      self.__type_ref = str(type.name)
     83      self.__type_label = str(type.name)
     84
     85   def visit_unknown_type_id(self, type):
     86
     87      self.__type_ref = str(type.name)
     88      self.__type_label = str(self.scope.prune(type.name))
     89
     90   def visit_declared_type_id(self, type):
     91
     92      self.__type_label = str(self.scope.prune(type.name))
     93      self.__type_ref = str(type.name)
     94
     95   def visit_modifier_type_id(self, type):
     96
     97      type.alias.accept(self)
     98      self.__type_ref = ''.join(type.premod) + ' ' + self.__type_ref + ' ' + ''.join(type.postmod)
     99      self.__type_label = ''.join(type.premod) + ' ' + self.__type_label + ' ' + ''.join(type.postmod)
    100
    101   def visit_parametrized_type_id(self, type):
    102
    103      if type.template:
    104         type.template.accept(self)
    105         type_label = self.__type_label + '<'
    106      else: type_label = '(unknown)<'
    107      parameters_label = []
    108      for p in type.parameters:
    109         p.accept(self)
    110         parameters_label.append(self.__type_label)
    111      self.__type_label = type_label + ', '.join(parameters_label) + '>'
    112
    113   def visit_function_type_id(self, type):
    114
    115      # TODO: this needs to be implemented
    116      self.__type_ref = 'function_type'
    117      self.__type_label = 'function_type'
    118
    119   #################### ASG Visitor ############################################
    120
    121   def visit_declarator(self, node):
    122
    123      self.__declarator = node.name
    124      for i in node.sizes:
    125         self.__declarator[-1] = self.__declarator[-1] + '[%d]'%i
    126
    127   def visit_typedef(self, typedef):
    128
    129      #self.write('@node ' + self.decl_label(typedef.name) + '\n')
    130      self.write('@deftp ' + typedef.type + ' {' + self.format_type(typedef.alias) + '} {' + self.decl_label(typedef.name) + '}\n')
    131      self.format_comments(typedef)
    132      self.write('@end deftp\n')
    133
    134   def visit_variable(self, variable):
    135
    136      #self.write('@node ' + self.decl_label(variable.name) + '\n')
    137      self.write('@deftypevr {' + variable.type + '} {' + self.format_type(variable.vtype) + '} {' + self.decl_label(variable.name) + '}\n')
    138      #FIXME !: how can values be represented in texinfo ?
    139      self.format_comments(variable)
    140      self.write('@end deftypevr\n')
    141
    142   def visit_const(self, const):
    143
    144      print "sorry, <const> not implemented"
    145
    146   def visit_module(self, module):
    147
    148      #self.write('@node ' + self.decl_label(module.name) + '\n')
    149      self.write('@deftp ' + module.type + ' ' + self.decl_label(module.name) + '\n')
    150      self.format_comments(module)
    151      old_scope = self.scope
    152      self.scope = module.name
    153      #menu = MenuMaker(str(self.scope), self.os)
    154      #menu.start()
    155      #for declaration in module.declarations: declaration.accept(menu)
    156      #menu.end()
    157      for declaration in module.declarations: declaration.accept(self)
    158      self.scope = old_scope
    159      self.write('@end deftp\n')
    160
    161   def visit_class(self, class_):
    162
    163      #self.write('@node ' + self.decl_label(clas.name) + '\n')
    164      self.write('@deftp ' + class_.type + ' ' + self.decl_label(class_.name) + '\n')
    165      if len(class_.parents):
    166         self.write('parents:')
    167         first = 1
    168         for parent in class_.parents:
    169            if not first: self.write(', ')
    170            else: self.write(' ')
    171            parent.accept(self)
    172         self.write('\n')
    173      self.format_comments(class_)
    174      old_scope = self.scope
    175      self.scope = class_.name
    176      #menu = MenuMaker(str(self.scope), self.os)
    177      #menu.start()
    178      #for d in class_.declarations: d.accept(menu)
    179      #menu.end()
    180      for d in class_.declarations:
    181         d.accept(self)
    182      self.scope = old_scope
    183      self.write('@end deftp\n')
    184
    185   def visit_inheritance(self, inheritance):
    186
    187      self.write('parent class')
    188
    189   def visit_parameter(self, parameter):
    190
    191      parameter.type.accept(self)
    192      label = self.write('{' + self.type_label() + '}')
    193      label = self.write(' @var{' + parameter.name + '}')
    194
    195   def visit_function(self, function):
    196
    197      ret = function.return_type
    198      if ret:
    199         ret.accept(self)
    200         ret_label = '{' + self.type_label() + '}'
    201      else:
    202         ret_label = '{}'
    203      self.write('@deftypefn ' + function.type + ' ' + ret_label + ' ' + self.decl_label(function.real_name) + ' (')
    204      first = 1
    205      for parameter in function.parameters:
    206         if not first: self.write(', ')
    207         else: self.write(' ')
    208         parameter.accept(self)
    209         first = 0
    210      self.write(')\n')
    211      #    map(lambda e, this=self: this.entity("exceptionname", e), operation.exceptions)
    212      self.format_comments(function)
    213      self.write('@end deftypefn\n')
    214
    215   def visit_operation(self, operation):
    216
    217      ret = operation.return_type
    218      if ret:
    219         ret.accept(self)
    220         ret_label = '{' + self.type_label() + '}'
    221      else:
    222         ret_label = '{}'
    223      try:
    224         #self.write('@node ' + self.decl_label(operation.name) + '\n')
    225         self.write('@deftypeop ' + operation.type + ' ' + self.decl_label(self.scope) + ' ' + ret_label + ' ' + self.decl_label(operation.real_name) + ' (')
    226      except:
    227         print operation.real_name
    228         sys.exit(0)
    229      first = 1
    230      for parameter in operation.parameters:
    231         if not first: self.write(', ')
    232         else: self.write(' ')
    233         parameter.accept(self)
    234         first = 0
    235      self.write(')\n')
    236      #    map(lambda e, this=self: this.entity("exceptionname", e), operation.exceptions)
    237      self.format_comments(operation)
    238      self.write('@end deftypeop\n')
    239
    240   def visit_enumerator(self, enumerator):
    241
    242      self.write('@deftypevr {' + enumerator.type + '} {} {' + self.decl_label(enumerator.name) + '}')
    243      #FIXME !: how can values be represented in texinfo ?
    244      if enumerator.value: self.write('\n')
    245      else: self.write('\n')
    246      self.format_comments(enumerator)
    247      self.write('@end deftypevr\n')
    248
    249   def visit_enum(self, enum):
    250      #self.write('@node ' + self.decl_label(enum.name) + '\n')
    251      self.write('@deftp ' + enum.type + ' ' + self.decl_label(enum.name) + '\n')
    252      self.format_comments(enum)
    253      for enumerator in enum.enumerators:
    254         enumerator.accept(self)
    255      self.write('@end deftp\n')
    256

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