File: Synopsis/Formatters/HTML/Part.py 1
2
3
4
5
6
7
8
9"""ASG Formatting classes.
10
11This module contains classes for formatting parts of a scope view (class,
12module, etc with methods, variables etc. The actual formatting of the
13declarations is delegated to multiple strategies for each part of the view,
14and are defined in the FormatStrategy module.
15"""
16
17from Synopsis.Processor import Parametrized, Parameter
18from Synopsis import ASG
19from Fragment import Fragment
20import Tags
21from Tags import *
22
23class Part(Parametrized, ASG.Visitor):
24 """Base class for formatting a Part of a Scope View.
25
26 This class contains functionality for modularly formatting an ASG node and
27 its children for display. It is typically used to construct Heading,
28 Summary and Detail formatters. Strategy objects are added according to
29 configuration, and this base class then checks which format methods each
30 strategy implements. For each ASG declaration visited, the Part asks all
31 Strategies which implement the appropriate format method to generate
32 output for that declaration. The final writing of the formatted html is
33 delegated to the write_section_start, write_section_end, and write_section_item
34 methods, which must be implemented in a subclass.
35 """
36
37 fragments = Parameter([], "list of Fragments")
38
39 def register(self, view):
40
41 self.processor = view.processor
42 self.__view = view
43 self.__fragments = []
44 self.__id_holder = None
45
46 self.__formatdict = {'format_declaration':[],
47 'format_macro':[],
48 'format_forward':[],
49 'format_group':[],
50 'format_scope':[],
51 'format_module':[],
52 'format_meta_module':[],
53 'format_class':[],
54 'format_class_template':[],
55 'format_typedef':[],
56 'format_enum':[],
57 'format_variable':[],
58 'format_const':[],
59 'format_function':[],
60 'format_function_template':[],
61 'format_operation':[],
62 'format_operation_template':[]}
63
64 for fragment in self.fragments:
65 fragment.register(self)
66 for method in self.__formatdict.keys():
67 no_func = getattr(Fragment, method).im_func
68 method_obj = getattr(fragment, method)
69
70 if method_obj.im_func is not no_func:
71
72 self.__formatdict[method].append(method_obj)
73
74 def view(self): return self.__view
75 def filename(self): return self.__view.filename()
76 def os(self): return self.__view.os()
77 def scope(self): return self.__view.scope()
78 def write(self, text): self.os().write(text)
79
80
81 def type_ref(self): return self.__type_ref
82 def type_label(self): return self.__type_label
83 def declarator(self): return self.__declarator
84 def parameter(self): return self.__parameter
85
86 def reference(self, name, label=None, **keys):
87 """Returns a reference to the given name. The name is a scoped name,
88 and the optional label is an alternative name to use as the link text.
89 The name is looked up in the TOC so the link may not be local. The
90 optional keys are appended as attributes to the A tag."""
91
92 if not label: label = escape(str(self.scope().prune(name)))
93 entry = self.processor.toc[name]
94 if entry: return href(rel(self.filename(), entry.link), label, **keys)
95 else: return label or ''
96
97 def label(self, name, label=None):
98 """Create a label for the given name. The label is an anchor so it can
99 be referenced by other links. The name of the label is derived by
100 looking up the name in the TOC and using the link in the TOC entry.
101 The optional label is an alternative name to use as the displayed
102 name. If the name is not found in the TOC then the name is not
103 anchored and just label is returned (or name if no label is given).
104 """
105
106 if label is None: label = name
107
108 entry = self.processor.toc[name]
109 label = escape(str(self.scope().prune(label)))
110 if entry is None: return label
111 location = entry.link
112 index = location.find('#')
113 if index >= 0: location = location[index+1:]
114 return location and Tags.name(location, label) or label
115
116
117 def format_declaration(self, decl, method):
118 """Format decl using named method of each fragment. Each fragment
119 returns two strings - type and name. All the types are joined and all
120 the names are joined separately. The consolidated type and name
121 strings are then passed to write_section_item."""
122
123 type_name = [f(decl) for f in self.__formatdict[method]]
124 if type_name:
125 text = ' '.join(type_name).strip()
126 self.write_section_item(text)
127
128 def process(self, decl):
129 """Formats the given decl, creating the output for this Part of the
130 view. This method is implemented in various subclasses in different
131 ways, for example Summary and Detail iterate through the children of
132 'decl' section by section, whereas Heading only formats decl itself.
133 """
134
135 pass
136
137
138 def visit_declaration(self, decl): self.format_declaration(decl, 'format_declaration')
139 def visit_macro(self, decl): self.format_declaration(decl, 'format_macro')
140 def visit_forward(self, decl): self.format_declaration(decl, 'format_forward')
141 def visit_group(self, decl): self.format_declaration(decl, 'format_group')
142 def visit_scope(self, decl): self.format_declaration(decl, 'format_scope')
143 def visit_module(self, decl): self.format_declaration(decl, 'format_module')
144 def visit_meta_module(self, decl): self.format_declaration(decl, 'format_meta_module')
145 def visit_class(self, decl): self.format_declaration(decl, 'format_class')
146 def visit_class_template(self, decl): self.format_declaration(decl, 'format_class_template')
147 def visit_typedef(self, decl): self.format_declaration(decl, 'format_typedef')
148 def visit_enum(self, decl): self.format_declaration(decl, 'format_enum')
149 def visit_variable(self, decl): self.format_declaration(decl, 'format_variable')
150 def visit_const(self, decl): self.format_declaration(decl, 'format_const')
151 def visit_function(self, decl): self.format_declaration(decl, 'format_function')
152 def visit_function_template(self, decl): self.format_declaration(decl, 'format_function_template')
153 def visit_operation(self, decl): self.format_declaration(decl, 'format_operation')
154 def visit_operation_template(self, decl): self.format_declaration(decl, 'format_operation_template')
155
156
157
158 def format_type(self, typeObj, id_holder = None):
159 "Returns a reference string for the given type object"
160
161 if typeObj is None: return "(unknown)"
162 if id_holder:
163 save_id = self.__id_holder
164 self.__id_holder = id_holder
165 typeObj.accept(self)
166 if id_holder:
167 self.__id_holder = save_id
168 return self.__type_label
169
170 def visit_builtin_type_id(self, type):
171 "Sets the label to be a reference to the type's name"
172
173 self.__type_label = self.reference(type.name)
174
175 def visit_unknown_type_id(self, type):
176 "Sets the label to be a reference to the type's link"
177
178 self.__type_label = self.reference(type.link)
179
180 def visit_declared_type_id(self, type):
181 "Sets the label to be a reference to the type's name"
182
183 self.__type_label = self.reference(type.name)
184
185 def visit_dependent_type_id(self, type):
186 "Sets the label to be the type's name (which has no proper scope)"
187
188 self.__type_label = type.name[-1]
189
190 def visit_modifier_type_id(self, type):
191 "Adds modifiers to the formatted label of the modifier's alias"
192
193 alias = self.format_type(type.alias)
194 def amp(x):
195 if x == '&': return '&'
196 return x
197 pre = ''.join(['%s '%amp(x) for x in type.premod])
198 post = ''.join([amp(x) for x in type.postmod])
199 self.__type_label = "%s%s%s"%(pre,alias,post)
200
201 def visit_parametrized_type_id(self, type):
202 "Adds the parameters to the template name in angle brackets"
203
204 if type.template:
205 type_label = self.reference(type.template.name)
206 else:
207 type_label = "(unknown)"
208 parameters = [self.format_type(p) for p in type.parameters]
209 self.__type_label = "%s<%s>"%(type_label,', '.join(parameters))
210
211 def visit_template_id(self, type):
212 "Labs the template with the parameters"
213
214 self.__type_label = "template<%s>"%','.join(['typename %s'%self.format_type(p)
215 for p in type.parameters])
216
217 def visit_function_type_id(self, type):
218 "Labels the function type with return type, name and parameters"
219
220 ret = self.format_type(type.return_type)
221 params = map(self.format_type, type.parameters)
222 pre = ''.join(type.premod)
223 if self.__id_holder:
224 ident = self.__id_holder[0]
225 del self.__id_holder[0]
226 else:
227 ident = ''
228 self.__type_label = "%s(%s%s)(%s)"%(ret,pre,ident,', '.join(params))
229
230
231
232 def write_start(self):
233 "Abstract method to start the output, eg table headings"
234
235 self.write('<!-- this part was generated by ' + self.__class__.__name__ + ' -->\n')
236
237 def write_section_start(self, heading):
238 "Abstract method to start a section of declaration types"
239
240 pass
241
242 def write_section_end(self, heading):
243 "Abstract method to end a section of declaration types"
244
245 pass
246
247 def write_section_item(self, text):
248 "Abstract method to write the output of one formatted declaration"
249
250 pass
251
252 def write_end(self):
253 "Abstract method to end the output, eg close the table"
254
255 pass
256
Generated on Thu Apr 16 16:27:15 2009 by
synopsis (version devel)