Synopsis - Cross-Reference
File: Synopsis/Formatters/BoostBook.py1# 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 BoostBook formatter""" 10 11from Synopsis.Processor import Processor, Parameter 12from Synopsis import ASG 13 14import sys, getopt, os, os.path 15 16class Formatter(Processor, ASG.Visitor): 17 """ 18 The type visitors should generate names relative to the current scope. 19 The generated references however are fully scoped names 20 """ 21 22 def process(self, ir, **kwds): 23 24 self.set_parameters(kwds) 25 self.ir = self.merge_input(ir) 26 27 self.__os = open(self.output, 'w') 28 self.__scope = () 29 self.__scopestack = [] 30 self.__indent = 0 31 self.__type_label = '' 32 33 for d in ir.asg.declarations: 34 d.accept(self) 35 36 self.__os.close() 37 38 return self.ir 39 40 def scope(self): return self.__scope 41 def push_scope(self, newscope): 42 43 self.__scopestack.append(self.__scope) 44 self.__scope = newscope 45 46 def pop_scope(self): 47 48 self.__scope = self.__scopestack[-1] 49 del self.__scopestack[-1] 50 51 def write(self, text): 52 """Write some text to the output stream, replacing \n's with \n's and 53 indents.""" 54 55 indent = ' ' * self.__indent 56 self.__os.write(text.replace('\n', '\n'+indent)) 57 58 def start_entity(self, __type, **__params): 59 """Write the start of an entity, ending with a newline""" 60 61 param_text = "" 62 if __params: param_text = " " + string.join(map(lambda p:'%s="%s"'%(p[0].lower(), p[1]), __params.items())) 63 self.write("<" + __type + param_text + ">") 64 self.__indent = self.__indent + 2 65 self.write("\n") 66 67 def end_entity(self, type): 68 """Write the end of an entity, starting with a newline""" 69 70 self.__indent = self.__indent - 2 71 self.write("\n</" + type + ">") 72 73 def write_entity(self, __type, __body, **__params): 74 """Write a single entity on one line (though body may contain 75 newlines)""" 76 77 param_text = "" 78 if __params: param_text = " " + string.join(map(lambda p:'%s="%s"'%(p[0].lower(), p[1]), __params.items())) 79 self.write("<" + __type + param_text + ">") 80 self.__indent = self.__indent + 2 81 self.write(__body) 82 self.__indent = self.__indent - 2 83 self.write("</" + __type + ">") 84 85 def entity(self, __type, __body, **__params): 86 """Return but do not write the text for an entity on one line""" 87 88 param_text = "" 89 if __params: param_text = " " + string.join(map(lambda p:'%s="%s"'%(p[0].lower(), p[1]), __params.items())) 90 return "<%s%s>%s</%s>"%(__type, param_text, __body, __type) 91 92 def reference(self, ref, label): 93 """reference takes two strings, a reference (used to look up the symbol and generated the reference), 94 and the label (used to actually write it)""" 95 96 location = self.__toc.lookup(ref) 97 if location != "": return href("#" + location, label) 98 else: return span("type", str(label)) 99 100 def label(self, ref): 101 102 location = self.__toc.lookup(str(ref)) 103 ref = str(self.scope().prune(ref)) 104 if location != "": return name("\"" + location + "\"", ref) 105 else: return ref 106 107 def type_label(self): return self.__type_label 108 #################### Type Visitor ########################################## 109 110 def visit_builtin_type_id(self, type): 111 112 self.__type_ref = str(type.name) 113 self.__type_label = str(type.name) 114 115 def visit_unknown_type_id(self, type): 116 117 self.__type_ref = str(type.name) 118 self.__type_label = str(self.scope().prune(type.name)) 119 120 def visit_declared_type_id(self, type): 121 122 self.__type_label = str(self.scope().prune(type.name)) 123 self.__type_ref = str(type.name) 124 125 def visit_modifier_type_id(self, type): 126 127 type.alias.accept(self) 128 self.__type_ref = ''.join(type.premod) + ' ' + self.__type_ref + ' ' + ''.join(type.postmod) 129 self.__type_label = ''.join(type.premod) + ' ' + self.__type_label + ' ' + ''.join(type.postmod) 130 131 def visit_parametrized_type_id(self, type): 132 133 type.template.accept(self) 134 type_label = self.__type_label + "<" 135 parameters_label = [] 136 for p in type.parameters: 137 p.accept(self) 138 parameters_label.append(self.__type_label) 139 self.__type_label = type_label + ', '.join(parameters_label) + '>' 140 141 def format_type(self, type): 142 143 type.accept(self) 144 return self.__type_label 145 146 def visit_function_type_id(self, type): 147 148 # TODO: this needs to be implemented 149 self.__type_ref = 'function_type' 150 self.__type_label = 'function_type' 151 152 def process_doc(self, doc): 153 154 text = doc.replace('\n\n', '</para><para>') 155 self.write(self.entity("para", text)+'\n') 156 157 #################### ASG Visitor ########################################### 158 159 def visit_declarator(self, node): 160 self.__declarator = node.name 161 for i in node.sizes: 162 self.__declarator[-1] = self.__declarator[-1] + '[%d]'%i 163 164 def visit_typedef(self, typedef): 165 166 self.start_entity("typedef", name=str(self.scope().prune(typedef.name))) 167 self.write_entity("type", self.format_type(typedef.alias)) 168 self.end_entity("typedef") 169 170 def visit_variable(self, variable): 171 172 self.start_entity("fieldsynopsis") 173 variable.vtype.accept(self) 174 self.entity("type", self.type_label()) 175 self.entity("varname", variable.name[-1]) 176 self.end_entity("fieldsynopsis") 177 178 def visit_const(self, const): 179 180 print "sorry, <const> not implemented" 181 182 def visit_module(self, module): 183 184 self.start_entity("namespace", name=str(self.scope().prune(module.name))) 185 self.write("\n") 186 self.process_doc(module.annotations.get('doc', '')) 187 self.push_scope(module.name) 188 for declaration in module.declarations: declaration.accept(self) 189 self.pop_scope() 190 self.end_entity("namespace") 191 192 def visit_class(self, class_): 193 194 self.start_entity("class", name=str(self.scope().prune(class_.name))) 195 # class_.type 196 for p in class_.parents: 197 p.accept(self) 198 self.push_scope(class_.name) 199 if class_.annotations.has_key('doc'): 200 self.start_entity("purpose") 201 self.process_doc(class_.annotations.get['doc']) 202 self.end_entity("purpose") 203 for d in class_.declarations: 204 d.accept(self) 205 self.pop_scope() 206 self.end_entity("class") 207 208 def visit_inheritance(self, inheritance): 209 210 if len(inheritance.attributes()): 211 self.start_entity("inherit", access=inheritance.attributes()[0]) 212 else: 213 self.start_entity("inherit") 214 self.write_entity("classname", self.format_type(inheritance.parent())) 215 self.end_entity("inherit") 216 217 def visit_parameter(self, parameter): 218 219 self.start_entity("parameter", name=parameter.name) 220 self.write_entity("param_type", self.format_type(parameter.type)) 221 #map(lambda m, this=self: this.write_entity("modifier", m), parameter.premodifier) 222 #map(lambda m, this=self: this.write_entity("modifier", m), parameter.postmodifier) 223 self.end_entity("parameter") 224 self.write("\n") 225 226 def visit_function(self, function): 227 228 self.start_entity("function", name=str(self.scope().prune(function.real_name))) 229 self.do_function(function) 230 self.end_entity("function") 231 self.write("\n") 232 233 def visit_operation(self, operation): 234 235 name = operation.name 236 tag = None 237 if len(name) > 1: 238 if name[-1] == name[-2]: 239 tag = "constructor" 240 self.start_entity(tag) 241 elif name[-1] == "~"+name[-2]: 242 tag = "destructor" 243 self.start_entity(tag) 244 if tag is None: 245 tag = "method" 246 self.start_entity(tag, name=str(self.scope().prune(operation.real_name))) 247 self.do_function(operation) 248 self.end_entity(tag) 249 self.write("\n") 250 251 def do_function(self, func): 252 """Stuff common to functions and methods, contructors, destructors""" 253 254 for parameter in func.parameters: parameter.accept(self) 255 if func.return_type: 256 self.write_entity("type", self.format_type(func.return_type)) 257 self.write("\n") 258 if func.annotations.has_key('doc'): 259 self.start_entity("purpose") 260 self.process_doc(func.annotations['doc']) 261 self.end_entity("purpose") 262 self.write("\n") 263 264 if func.exceptions: 265 self.start_entity("throws") 266 for ex in func.exceptions: 267 self.write_entity("simpara", ex) 268 self.end_entity("throws") 269 self.write("\n") 270 271 def visit_enumerator(self, enumerator): 272 273 print "sorry, <enumerator> not implemented" 274 275 def visit_enum(self, enum): 276 277 print "sorry, <enum> not implemented" 278 279
Generated on Tue May 13 02:39:10 2008 by
synopsis (version 0.10)
synopsis (version 0.10)