# # formatter.py # # Convert parsed content blocks to a structured document (library file). # # Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, # modified, and distributed under the terms of the FreeType project # license, LICENSE.TXT. By continuing to use, modify, or distribute # this file you indicate that you have read the license and # understand and accept it fully. # # This is the base Formatter class. Its purpose is to convert a content # processor's data into specific documents (i.e., table of contents, global # index, and individual API reference indices). # # You need to sub-class it to output anything sensible. For example, the # file `tohtml.py' contains the definition of the `HtmlFormatter' sub-class # to output HTML. # from sources import * from content import * from utils import * ################################################################ ## ## FORMATTER CLASS ## class Formatter: def __init__( self, processor ): self.processor = processor self.identifiers = {} self.chapters = processor.chapters self.sections = processor.sections.values() self.block_index = [] # store all blocks in a dictionary self.blocks = [] for section in self.sections: for block in section.blocks.values(): self.add_identifier( block.name, block ) # add enumeration values to the index, since this is useful for markup in block.markups: if markup.tag == 'values': for field in markup.fields: self.add_identifier( field.name, block ) self.block_index = list(self.identifiers.keys()) self.block_index.sort( key = index_key ) # also add section names to dictionary (without making them appear # in the index) for section in self.sections: self.add_identifier( section.name, section ) def add_identifier( self, name, block ): if name in self.identifiers: # duplicate name! sys.stderr.write( "WARNING: duplicate definition for" + " '" + name + "' " + "in " + block.location() + ", " + "previous definition in " + self.identifiers[name].location() + "\n" ) else: self.identifiers[name] = block # # formatting the table of contents # def toc_enter( self ): pass def toc_chapter_enter( self, chapter ): pass def toc_section_enter( self, section ): pass def toc_section_exit( self, section ): pass def toc_chapter_exit( self, chapter ): pass def toc_index( self, index_filename ): pass def toc_exit( self ): pass def toc_dump( self, toc_filename = None, index_filename = None ): output = None if toc_filename: output = open_output( toc_filename ) self.toc_enter() for chap in self.processor.chapters: self.toc_chapter_enter( chap ) for section in chap.sections: self.toc_section_enter( section ) self.toc_section_exit( section ) self.toc_chapter_exit( chap ) self.toc_index( index_filename ) self.toc_exit() if output: close_output( output ) # # formatting the index # def index_enter( self ): pass def index_name_enter( self, name ): pass def index_name_exit( self, name ): pass def index_exit( self ): pass def index_dump( self, index_filename = None ): output = None if index_filename: output = open_output( index_filename ) self.index_enter() for name in self.block_index: self.index_name_enter( name ) self.index_name_exit( name ) self.index_exit() if output: close_output( output ) # # formatting a section # def section_enter( self, section ): pass def block_enter( self, block ): pass def markup_enter( self, markup, block = None ): pass def field_enter( self, field, markup = None, block = None ): pass def field_exit( self, field, markup = None, block = None ): pass def markup_exit( self, markup, block = None ): pass def block_exit( self, block ): pass def section_exit( self, section ): pass def section_dump( self, section, section_filename = None ): output = None if section_filename: output = open_output( section_filename ) self.section_enter( section ) for name in section.block_names: skip_entry = 0 try: block = self.identifiers[name] # `block_names' can contain field names also, # which we filter out for markup in block.markups: if markup.tag == 'values': for field in markup.fields: if field.name == name: skip_entry = 1 except: skip_entry = 1 # this happens e.g. for `/empty/' entries if skip_entry: continue self.block_enter( block ) for markup in block.markups[1:]: # always ignore first markup! self.markup_enter( markup, block ) for field in markup.fields: self.field_enter( field, markup, block ) self.field_exit( field, markup, block ) self.markup_exit( markup, block ) self.block_exit( block ) self.section_exit( section ) if output: close_output( output ) def section_dump_all( self ): for section in self.sections: self.section_dump( section ) # eof