1# 2# formatter.py 3# 4# Convert parsed content blocks to a structured document (library file). 5# 6# Copyright 2002-2018 by 7# David Turner. 8# 9# This file is part of the FreeType project, and may only be used, 10# modified, and distributed under the terms of the FreeType project 11# license, LICENSE.TXT. By continuing to use, modify, or distribute 12# this file you indicate that you have read the license and 13# understand and accept it fully. 14 15# 16# This is the base Formatter class. Its purpose is to convert a content 17# processor's data into specific documents (i.e., table of contents, global 18# index, and individual API reference indices). 19# 20# You need to sub-class it to output anything sensible. For example, the 21# file `tohtml.py' contains the definition of the `HtmlFormatter' sub-class 22# to output HTML. 23# 24 25 26from sources import * 27from content import * 28from utils import * 29 30 31################################################################ 32## 33## FORMATTER CLASS 34## 35class Formatter: 36 37 def __init__( self, processor ): 38 self.processor = processor 39 self.identifiers = {} 40 self.chapters = processor.chapters 41 self.sections = processor.sections.values() 42 self.block_index = [] 43 44 # store all blocks in a dictionary 45 self.blocks = [] 46 for section in self.sections: 47 for block in section.blocks.values(): 48 self.add_identifier( block.name, block ) 49 50 # add enumeration values to the index, since this is useful 51 for markup in block.markups: 52 if markup.tag == 'values': 53 for field in markup.fields: 54 self.add_identifier( field.name, block ) 55 56 self.block_index = self.identifiers.keys() 57 self.block_index.sort( key = index_key ) 58 59 # also add section names to dictionary (without making them appear 60 # in the index) 61 for section in self.sections: 62 self.add_identifier( section.name, section ) 63 64 def add_identifier( self, name, block ): 65 if name in self.identifiers: 66 # duplicate name! 67 sys.stderr.write( "WARNING: duplicate definition for" 68 + " '" + name + "' " 69 + "in " + block.location() + ", " 70 + "previous definition in " 71 + self.identifiers[name].location() 72 + "\n" ) 73 else: 74 self.identifiers[name] = block 75 76 # 77 # formatting the table of contents 78 # 79 def toc_enter( self ): 80 pass 81 82 def toc_chapter_enter( self, chapter ): 83 pass 84 85 def toc_section_enter( self, section ): 86 pass 87 88 def toc_section_exit( self, section ): 89 pass 90 91 def toc_chapter_exit( self, chapter ): 92 pass 93 94 def toc_index( self, index_filename ): 95 pass 96 97 def toc_exit( self ): 98 pass 99 100 def toc_dump( self, toc_filename = None, index_filename = None ): 101 output = None 102 if toc_filename: 103 output = open_output( toc_filename ) 104 105 self.toc_enter() 106 107 for chap in self.processor.chapters: 108 109 self.toc_chapter_enter( chap ) 110 111 for section in chap.sections: 112 self.toc_section_enter( section ) 113 self.toc_section_exit( section ) 114 115 self.toc_chapter_exit( chap ) 116 117 self.toc_index( index_filename ) 118 119 self.toc_exit() 120 121 if output: 122 close_output( output ) 123 124 # 125 # formatting the index 126 # 127 def index_enter( self ): 128 pass 129 130 def index_name_enter( self, name ): 131 pass 132 133 def index_name_exit( self, name ): 134 pass 135 136 def index_exit( self ): 137 pass 138 139 def index_dump( self, index_filename = None ): 140 output = None 141 if index_filename: 142 output = open_output( index_filename ) 143 144 self.index_enter() 145 146 for name in self.block_index: 147 self.index_name_enter( name ) 148 self.index_name_exit( name ) 149 150 self.index_exit() 151 152 if output: 153 close_output( output ) 154 155 # 156 # formatting a section 157 # 158 def section_enter( self, section ): 159 pass 160 161 def block_enter( self, block ): 162 pass 163 164 def markup_enter( self, markup, block = None ): 165 pass 166 167 def field_enter( self, field, markup = None, block = None ): 168 pass 169 170 def field_exit( self, field, markup = None, block = None ): 171 pass 172 173 def markup_exit( self, markup, block = None ): 174 pass 175 176 def block_exit( self, block ): 177 pass 178 179 def section_exit( self, section ): 180 pass 181 182 def section_dump( self, section, section_filename = None ): 183 output = None 184 if section_filename: 185 output = open_output( section_filename ) 186 187 self.section_enter( section ) 188 189 for name in section.block_names: 190 skip_entry = 0 191 try: 192 block = self.identifiers[name] 193 # `block_names' can contain field names also, 194 # which we filter out 195 for markup in block.markups: 196 if markup.tag == 'values': 197 for field in markup.fields: 198 if field.name == name: 199 skip_entry = 1 200 except: 201 skip_entry = 1 # this happens e.g. for `/empty/' entries 202 203 if skip_entry: 204 continue 205 206 self.block_enter( block ) 207 208 for markup in block.markups[1:]: # always ignore first markup! 209 self.markup_enter( markup, block ) 210 211 for field in markup.fields: 212 self.field_enter( field, markup, block ) 213 self.field_exit( field, markup, block ) 214 215 self.markup_exit( markup, block ) 216 217 self.block_exit( block ) 218 219 self.section_exit( section ) 220 221 if output: 222 close_output( output ) 223 224 def section_dump_all( self ): 225 for section in self.sections: 226 self.section_dump( section ) 227 228# eof 229