Synopsis - Cross-Reference
File: Synopsis/Formatters/HTML/Part.py1# 2# Copyright (C) 2000 Stephen Davies 3# Copyright (C) 2000 Stefan Seefeld 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"""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 # need both because otherwise 'Tags.name' would be ambiguous 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 # Lists of format methods for each ASG type 46 self.__formatdict = {'format_declaration':[], 47 'format_forward':[], 48 'format_group':[], 49 'format_scope':[], 50 'format_module':[], 51 'format_meta_module':[], 52 'format_class':[], 53 'format_class_template':[], 54 'format_typedef':[], 55 'format_enum':[], 56 'format_variable':[], 57 'format_const':[], 58 'format_function':[], 59 'format_function_template':[], 60 'format_operation':[], 61 'format_operation_template':[]} 62 63 for fragment in self.fragments: 64 fragment.register(self) 65 for method in self.__formatdict.keys(): 66 no_func = getattr(Fragment, method).im_func 67 method_obj = getattr(fragment, method) 68 # If it was overridden in fragment 69 if method_obj.im_func is not no_func: 70 # Add to the dictionary 71 self.__formatdict[method].append(method_obj) 72 73 def view(self): return self.__view 74 def filename(self): return self.__view.filename() 75 def os(self): return self.__view.os() 76 def scope(self): return self.__view.scope() 77 def write(self, text): self.os().write(text) 78 79 # Access to generated values 80 def type_ref(self): return self.__type_ref 81 def type_label(self): return self.__type_label 82 def declarator(self): return self.__declarator 83 def parameter(self): return self.__parameter 84 85 def reference(self, name, label=None, **keys): 86 """Returns a reference to the given name. The name is a scoped name, 87 and the optional label is an alternative name to use as the link text. 88 The name is looked up in the TOC so the link may not be local. The 89 optional keys are appended as attributes to the A tag.""" 90 91 if not label: label = escape(str(self.scope().prune(name))) 92 entry = self.processor.toc[name] 93 if entry: return href(rel(self.filename(), entry.link), label, **keys) 94 else: return label or '' 95 96 def label(self, name, label=None): 97 """Create a label for the given name. The label is an anchor so it can 98 be referenced by other links. The name of the label is derived by 99 looking up the name in the TOC and using the link in the TOC entry. 100 The optional label is an alternative name to use as the displayed 101 name. If the name is not found in the TOC then the name is not 102 anchored and just label is returned (or name if no label is given). 103 """ 104 105 if label is None: label = name 106 # some labels are templates with <>'s 107 entry = self.processor.toc[name] 108 label = escape(str(self.scope().prune(label))) 109 if entry is None: return label 110 location = entry.link 111 index = location.find('#') 112 if index >= 0: location = location[index+1:] 113 return location and Tags.name(location, label) or label 114 115 116 def format_declaration(self, decl, method): 117 """Format decl using named method of each fragment. Each fragment 118 returns two strings - type and name. All the types are joined and all 119 the names are joined separately. The consolidated type and name 120 strings are then passed to write_section_item.""" 121 122 type_name = [f(decl) for f in self.__formatdict[method]] 123 if type_name: 124 text = ' '.join(type_name).strip() 125 self.write_section_item(text) 126 127 def process(self, decl): 128 """Formats the given decl, creating the output for this Part of the 129 view. This method is implemented in various subclasses in different 130 ways, for example Summary and Detail iterate through the children of 131 'decl' section by section, whereas Heading only formats decl itself. 132 """ 133 134 pass 135 136 #################### ASG Visitor ############################################ 137 def visit_declaration(self, decl): self.format_declaration(decl, 'format_declaration') 138 def visit_forward(self, decl): self.format_declaration(decl, 'format_forward') 139 def visit_group(self, decl): self.format_declaration(decl, 'format_group') 140 def visit_scope(self, decl): self.format_declaration(decl, 'format_scope') 141 def visit_module(self, decl): self.format_declaration(decl, 'format_module') 142 def visit_meta_module(self, decl): self.format_declaration(decl, 'format_meta_module') 143 def visit_class(self, decl): self.format_declaration(decl, 'format_class') 144 def visit_class_template(self, decl): self.format_declaration(decl, 'format_class_template') 145 def visit_typedef(self, decl): self.format_declaration(decl, 'format_typedef') 146 def visit_enum(self, decl): self.format_declaration(decl, 'format_enum') 147 def visit_variable(self, decl): self.format_declaration(decl, 'format_variable') 148 def visit_const(self, decl): self.format_declaration(decl, 'format_const') 149 def visit_function(self, decl): self.format_declaration(decl, 'format_function') 150 def visit_function_template(self, decl): self.format_declaration(decl, 'format_function_template') 151 def visit_operation(self, decl): self.format_declaration(decl, 'format_operation') 152 def visit_operation_template(self, decl): self.format_declaration(decl, 'format_operation_template') 153 154 155 #################### Type Formatter/Visitor ################################# 156 def format_type(self, typeObj, id_holder = None): 157 "Returns a reference string for the given type object" 158 159 if typeObj is None: return "(unknown)" 160 if id_holder: 161 save_id = self.__id_holder 162 self.__id_holder = id_holder 163 typeObj.accept(self) 164 if id_holder: 165 self.__id_holder = save_id 166 return self.__type_label 167 168 def visit_builtin_type_id(self, type): 169 "Sets the label to be a reference to the type's name" 170 171 self.__type_label = self.reference(type.name) 172 173 def visit_unknown_type_id(self, type): 174 "Sets the label to be a reference to the type's link" 175 176 self.__type_label = self.reference(type.link) 177 178 def visit_declared_type_id(self, type): 179 "Sets the label to be a reference to the type's name" 180 181 self.__type_label = self.reference(type.name) 182 183 def visit_dependent_type_id(self, type): 184 "Sets the label to be the type's name (which has no proper scope)" 185 186 self.__type_label = type.name[-1] 187 188 def visit_modifier_type_id(self, type): 189 "Adds modifiers to the formatted label of the modifier's alias" 190 191 alias = self.format_type(type.alias) 192 def amp(x): 193 if x == '&': return '&' 194 return x 195 pre = ''.join(['%s '%amp(x) for x in type.premod]) 196 post = ''.join([amp(x) for x in type.postmod]) 197 self.__type_label = "%s%s%s"%(pre,alias,post) 198 199 def visit_parametrized_type_id(self, type): 200 "Adds the parameters to the template name in angle brackets" 201 202 if type.template: 203 type_label = self.reference(type.template.name) 204 else: 205 type_label = "(unknown)" 206 parameters = [self.format_type(p) for p in type.parameters] 207 self.__type_label = "%s<%s>"%(type_label,', '.join(parameters)) 208 209 def visit_template_id(self, type): 210 "Labs the template with the parameters" 211 212 self.__type_label = "template<%s>"%','.join(['typename %s'%self.format_type(p) 213 for p in type.parameters]) 214 215 def visit_function_type_id(self, type): 216 "Labels the function type with return type, name and parameters" 217 218 ret = self.format_type(type.return_type) 219 params = map(self.format_type, type.parameters) 220 pre = ''.join(type.premod) 221 if self.__id_holder: 222 ident = self.__id_holder[0] 223 del self.__id_holder[0] 224 else: 225 ident = '' 226 self.__type_label = "%s(%s%s)(%s)"%(ret,pre,ident,', '.join(params)) 227 228 229 # These are overridden in {Summary,Detail}Formatter 230 def write_start(self): 231 "Abstract method to start the output, eg table headings" 232 233 self.write('<!-- this part was generated by ' + self.__class__.__name__ + ' -->\n') 234 235 def write_section_start(self, heading): 236 "Abstract method to start a section of declaration types" 237 238 pass 239 240 def write_section_end(self, heading): 241 "Abstract method to end a section of declaration types" 242 243 pass 244 245 def write_section_item(self, text): 246 "Abstract method to write the output of one formatted declaration" 247 248 pass 249 250 def write_end(self): 251 "Abstract method to end the output, eg close the table" 252 253 pass 254
Generated on Tue May 13 02:39:41 2008 by
synopsis (version 0.10)
synopsis (version 0.10)