File: Synopsis/Formatters/Texinfo.py 1
2
3
4
5
6
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
76 self.write(escape(doc.text) + '\n')
77
78
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
116 self.__type_ref = 'function_type'
117 self.__type_label = 'function_type'
118
119
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
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
137 self.write('@deftypevr {' + variable.type + '} {' + self.format_type(variable.vtype) + '} {' + self.decl_label(variable.name) + '}\n')
138
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
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
154
155
156
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
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
177
178
179
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
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
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
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
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
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)