File: Synopsis/Formatters/DocBook/Syntax.py
  1#
  2# Copyright (C) 2007 Stefan Seefeld
  3# All rights reserved.
  4# Licensed to the public under the terms of the GNU LGPL (>= 2),
  5# see the file COPYING for details.
  6#
  7
  8from Synopsis import ASG
  9
 10def escape(text):
 11
 12    for p in [('&', '&amp;'), ('"', '&quot;'), ('<', '&lt;'), ('>', '&gt;'),]:
 13        text = text.replace(*p)
 14    return text
 15
 16class Syntax(ASG.Visitor):
 17    """Even though DocBook provides markup for some programming artifacts,
 18    it is incomplete, and the XSL stylesheets are buggy, resulting in
 19    incorrect syntax. Thus, we use the 'synopsis' element, and attempt to
 20    reproduce the original syntax with language-specific subclasses."""
 21
 22    def __init__(self, output):
 23
 24        self.output = output
 25
 26    def finish(self): pass
 27
 28    def typeid(self, type):
 29
 30        self._typeid = ''
 31        type.accept(self)
 32        return self._typeid
 33
 34
 35class PythonSyntax(Syntax):
 36
 37    def visit_function(self, node):
 38        text = escape(str(node.return_type))
 39        text += '%s(%s)\n'%(escape(node.real_name[-1]),
 40                            ', '.join([self.visit_parameter(p)
 41                                       for p in node.parameters]))
 42        self.output.write(text)
 43
 44    def visit_parameter(self, parameter):
 45        text = str(parameter.name)
 46        if parameter.value:
 47            text += ' = %s'%escape(parameter.value)
 48        return text
 49
 50    def visit_variable(self, variable):
 51        variable.vtype.accept(self)
 52        self.output.write(variable.name[-1])
 53
 54    def visit_const(self, const):
 55        const.ctype.accept(self)
 56        self.output.write(const.name[-1])
 57
 58
 59class PythonSummarySyntax(PythonSyntax):
 60    """Generate DocBook Synopsis for Python declarations."""
 61
 62    def __init__(self, output):
 63        super(PythonSummarySyntax, self).__init__(output)
 64        self.output.write('<synopsis>')
 65
 66    def finish(self):
 67        self.output.write('</synopsis>\n')
 68
 69    def visit_group(self, node):
 70        for d in node.declarations:
 71            d.accept(self)
 72    def visit_module(self, module):
 73        self.output.write('%s %s\n'%(module.type, module.name[-1]))
 74
 75    def visit_class(self, class_):
 76        self.output.write('class %s\n'%escape(class_.name[-1]))
 77
 78    def visit_inheritance(self, node): pass
 79
 80
 81class PythonDetailSyntax(PythonSyntax):
 82    """Generate DocBook Synopsis for Python declarations."""
 83
 84    def __init__(self, output):
 85        super(PythonDetailSyntax, self).__init__(output)
 86        self.output.write('<synopsis>')
 87
 88    def finish(self):
 89        self.output.write('</synopsis>\n')
 90
 91    def visit_group(self, node):
 92        for d in node.declarations:
 93            d.accept(self)
 94    def visit_module(self, module):
 95        self.output.write('%s %s\n'%(module.type, module.name[-1]))
 96
 97    def visit_class(self, class_):
 98        self.output.write('class %s\n'%escape(class_.name[-1]))
 99
100    def visit_inheritance(self, node): pass
101
102
103class CxxSyntax(Syntax):
104
105    def visit_function(self, node):
106
107        text = node.return_type and self.typeid(node.return_type) or ''
108        text += ' %s(%s);\n'%(escape(node.real_name[-1]),
109                              ', '.join([self.visit_parameter(p)
110                                         for p in node.parameters]))
111        self.output.write(text)
112
113    def visit_parameter(self, parameter):
114
115        text = escape(str(parameter.type))
116        if parameter.name:
117            text += ' %s'%parameter.name
118        if parameter.value:
119            text += ' = %s'%escape(parameter.value)
120        return text
121
122    def visit_typedef(self, node):
123
124        self.output.write('typedef %s %s;\n'%(self.typeid(node.alias), node.name[-1]))
125
126    def visit_variable(self, variable):
127        self.output.write('%s %s;\n'%(self.typeid(variable.vtype), variable.name[-1]))
128
129    def visit_const(self, const):
130        self.output.write('%s %s;\n'%(self.typeid(const.ctype), const.name[-1]))
131
132    def visit_builtin_type_id(self, type): self._typeid = type.name[-1]
133    def visit_unknown_type_id(self, type): self._typeid = escape(str(type.name))
134    def visit_declared_type_id(self, type): self._typeid = escape(str(type.name))
135    def visit_modifier_type_id(self, type):
136
137        self._typeid = '%s %s %s'%(escape(' '.join(type.premod)),
138                                   self.typeid(type.alias),
139                                   escape(' '.join(type.postmod)))
140    def visit_array_type_id(self, type):
141
142        self._typeid = '%s%s'%(escape(str(type.name)), ''.join(['[%s]'%s for s in type.sizes]))
143
144    def visit_template_id(self, type): self._typeid = escape(str(type.name))
145
146    def visit_parametrized_type_id(self, type):
147
148        self._typeid = '%s&lt;%s&gt;'%(self.typeid(type.template),
149                                       ', '.join([self.typeid(p) for p in type.parameters]))
150
151    def visit_function_type_id(self, type):
152
153        self._typeid = '%s(%s)'%(self.typeid(type.return_type),
154                                 ', '.join([self.typeid(p) for p in type.parameters]))
155
156    def visit_dependent_type_id(self, type): self._typeid = type.name[-1]
157
158
159class CxxSummarySyntax(CxxSyntax):
160    """Generate DocBook Synopsis for C++ declarations."""
161
162    def __init__(self, output):
163        super(CxxSummarySyntax, self).__init__(output)
164        self.output.write('<synopsis>')
165
166    def finish(self):
167        self.output.write('</synopsis>\n')
168
169    def visit_macro(self, macro):
170        self.output.write(macro.name[-1])
171        if macro.parameters:
172            self.output.write('(%)'%(', '.join([p for p in macro.parameters])))
173        self.output.write('\n')
174
175    def visit_forward(self, node): pass
176    def visit_group(self, node):
177        for d in node.declarations:
178            d.accept(self)
179    def visit_module(self, module):
180        self.output.write('%s %s;\n'%(module.type, module.name[-1]))
181
182    def visit_class(self, class_):
183        self.output.write('%s %s;\n'%(class_.type, escape(class_.name[-1])))
184
185    def visit_class_template(self, class_): self.visit_class(class_)
186
187    def visit_enumerator(self, node):
188        if node.value:
189            return '%s=%s'%(node.name[-1], escape(node.value))
190        else:
191            return node.name[-1]
192
193    def visit_enum(self, node):
194        self.output.write('%s %s { '%(node.type, node.name[-1]))
195        self.output.write(', '.join([self.visit_enumerator(e)
196                                     for e in node.enumerators
197                                     if isinstance(e, ASG.Enumerator)]))
198        self.output.write('};\n')
199
200    def visit_inheritance(self, node): pass
201
202
203class CxxDetailSyntax(CxxSyntax):
204    """Generate DocBook Synopsis for C++ declarations."""
205
206    def __init__(self, output):
207        super(CxxDetailSyntax, self).__init__(output)
208        self.output.write('<synopsis>')
209
210    def finish(self):
211        self.output.write('</synopsis>\n')
212
213    def visit_macro(self, macro):
214        self.output.write(macro.name[-1])
215        if macro.parameters:
216            self.output.write('(%s)'%(', '.join([p for p in macro.parameters])))
217        self.output.write('\n')
218
219    def visit_forward(self, node): pass
220    def visit_group(self, node):
221        for d in node.declarations:
222            d.accept(self)
223    def visit_module(self, module):
224        self.output.write('%s %s;\n'%(module.type, module.name[-1]))
225
226    def visit_class(self, class_):
227        self.output.write('%s %s;\n'%(class_.type, escape(class_.name[-1])))
228
229    def visit_class_template(self, node): pass
230
231    def visit_enumerator(self, node):
232        if node.value:
233            return '%s=%s'%(node.name[-1], escape(node.value))
234        else:
235            return node.name[-1]
236
237    def visit_enum(self, node):
238        self.output.write('%s %s { '%(node.type, node.name[-1]))
239        self.output.write(', '.join([self.visit_enumerator(e)
240                                     for e in node.enumerators
241                                     if isinstance(e, ASG.Enumerator)]))
242        self.output.write('};\n')
243
244    def visit_inheritance(self, node): pass
245
246