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