OSDN Git Service

ffmpeg release 0.5 (http://www.ffmpeg.org/changelog.html)
[handbrake-jp/handbrake-jp-git.git] / doc / xml2wiki.py
1 import io
2 import re
3 import sys
4 import time
5 import xml.parsers.expat
6
7 from optparse import OptionParser
8
9 ###############################################################################
10
11 writer = None
12
13 ###############################################################################
14
15 class StreamEntry:
16     def __init__( self, object, isElement ):
17         self.object    = object
18         self.isElement = isElement
19
20 ###############################################################################
21
22 class Element:
23     def __init__( self, parent, text=True, strip=True, delimBegin=None, delimEnd=None, newline=0 ):
24         self._parent     = parent
25         self._text       = text
26         self._strip      = strip
27         self._delimBegin = delimBegin
28         self._delimEnd   = delimEnd
29         self._newline    = newline
30         self._stream     = []
31
32     def _addElement( self, child ):
33         self._stream.append( StreamEntry( child, True ))
34
35     def _addText( self, text ):
36         if self._text:
37             self._stream.append( StreamEntry( text, False ))
38
39     def _write( self, file ):
40         if self._delimBegin:
41             file.write( self._delimBegin )
42         for entry in self._stream:
43             if entry.isElement:
44                 entry.object.write( file )
45             else:
46                 file.write( str(entry.object) )
47         if self._delimEnd:
48             file.write( self._delimEnd )
49
50     def write( self, file ):
51         if self._newline > writer.newlineCount:
52             file.write( '\n' * (self._newline - writer.newlineCount))
53         self._write( file )
54
55 ###############################################################################
56
57 class Document( Element ):
58     def __init__( self ):
59         Element.__init__( self, None )
60         self._stack        = [ self ]
61         self._pending      = self
62         self._summary      = None
63         self._debugIndent  = ''
64         self._chapterLevel = 0
65         self._sectionLevel = 0
66         self._dividerCount = 0
67         self._majorHeading = Element( self, delimBegin='= ', delimEnd=' =\n\n' )
68
69     def _pop( self ):
70         self._stack.pop()
71         self._pending = self._stack[-1]
72         return self._pending
73
74     def _pushChild( self, child, add=True ):
75         if add:
76             self._pending._addElement( child );
77         self._stack.append( child )
78         self._pending = child
79         return self._pending
80
81     def _chapterBegin( self ):
82         self._chapterLevel = self._chapterLevel + 1
83
84     def _chapterEnd( self ):
85         self._chapterLevel = self._chapterLevel - 1
86
87     def _sectionBegin( self ):
88         self._sectionLevel = self._sectionLevel + 1
89
90     def _sectionEnd( self ):
91         self._sectionLevel = self._sectionLevel - 1
92
93     def _write( self, file ):
94         if options.date:
95             file.write( "\n\n  ===== `[`generated by xml2wiki on %s`]` =====" % (time.strftime( '%c' ) ))
96         Element._write( self, file )
97         file.write( '\n' )
98
99     def handleElementBegin( self, name, attrs ):
100         self._debugIndent = '    ' * (len(self._stack) - 1)
101         if options.verbose:
102             print( '%sBEGIN %s %s' % (self._debugIndent, name, attrs))
103
104         e = None
105         shouldAdd = True
106
107         if name == 'anchor':
108             global anchor
109             anchor = attrs['name']
110         elif name == 'b':
111             e = Element( self._pending, delimBegin="'''", delimEnd="'''" )
112         elif name == 'chapter':
113             self._chapterBegin()
114         elif name == 'code':
115             e = Element( self._pending, delimBegin='{{{{', delimEnd='}}}' )
116         elif name == 'command':
117             e = Element( self._pending, delimBegin='{{{', delimEnd='}}}' )
118         elif name == 'enumerate':
119             e = EnumerateElement( self._pending )
120         elif name == 'example':
121             e = CodeElement( self._pending )
122         elif name == 'file':
123             e = Element( self._pending, delimBegin='{{{', delimEnd='}}}' )
124         elif name == 'i':
125             e = Element( self._pending, delimBegin="''", delimEnd="''" )
126         elif name == 'itemize':
127             e = ItemizeElement( self._pending )
128         elif name == 'item':
129             e = ItemElement( self._pending )
130         elif name == 'majorheading':
131             e = self._majorHeading
132             shouldAdd = False
133         elif name == 'para':
134             e = ParagraphElement( self._pending )
135         elif name == 'quotation':
136             e = IndentedElement( self._pending )
137         elif name == 'samp':
138             e = Element( self._pending, delimBegin='{{{', delimEnd='}}}' )
139         elif name == 'section' or name == 'subsection':
140             self._sectionBegin()
141         #elif name == 'table':
142         #    e = Element( self._pending, newline=1, delimBegin='<table border="1" cellpadding="4">', delimEnd='</table>', strip=True )
143         elif name == 'tableitem':
144             e = TableItemElement( self._pending )
145         elif name == 'tableterm':
146             e = Element( self._pending, delimBegin=' ', delimEnd='::\n' )
147         elif name == 'title':
148             e = HeadingElement( self._pending, self._chapterLevel + self._sectionLevel )
149         elif name == 'unnumbered' or name == 'unnumberedsec':
150             self._chapterBegin()
151         elif name == 'uref':
152             e = UrefInline( self._pending )
153         elif name == 'urefdesc':
154             e = UrefDescInline( self._pending )
155         elif name == 'urefurl':
156             e = UrefUrlInline( self._pending )
157         elif name == 'xref':
158             e = XrefInline( self._pending )
159         elif name == 'xrefnodename':
160             e = XrefNodenameInline( self._pending )
161
162         if not e:
163             self._pushChild( UnknownElement( self._pending ) )
164             if options.verbose > 2:
165                 print( 'UNKNOWN:', name )
166         else:
167             self._pushChild( e, add=shouldAdd )
168
169     def handleElementEnd( self, name ):
170         if name == 'chapter':
171             self._chapterEnd()
172         elif name == 'section' or name == 'subsection':
173             self._sectionEnd()
174         elif name == 'unnumbered' or name == 'unnumberedsec':
175             self._sectionEnd()
176
177         self._pop()
178         self._debugIndent = '    ' * (len(self._stack) - 1)
179         if options.verbose:
180             print( '%sEND %s' % (self._debugIndent, name))
181
182     def handleCharacterData( self, data ):
183         if options.verbose > 1:
184             print( '%s[%s]' % (self._debugIndent, data.strip()))
185         self._pending._addText( data )
186
187 ###############################################################################
188
189 class UnknownElement( Element ):
190     def __init__( self, parent ):
191         Element.__init__( self, parent, text=False )
192
193 ###############################################################################
194
195 class PragmaElement( Element ):
196     def __init__( self, parent, keyword ):
197         Element.__init__( self, parent, delimBegin=('#' + keyword + ' ') )
198
199 ###############################################################################
200
201 class BlockElement( Element ):
202     def __init__( self, parent ):
203         Element.__init__( self, parent, newline=2, text=False )
204
205 ###############################################################################
206
207 class CodeElement( Element ):
208     def __init__( self, parent ):
209         Element.__init__( self, parent, newline=2, delimBegin='{{{\n', delimEnd='\n}}}\n' )
210
211 ###############################################################################
212
213 class HeadingElement( Element ):
214     def __init__( self, parent, level ):
215         Element.__init__( self, parent, newline=2 )
216         global anchor
217         self._anchor = anchor
218
219         self._level = level
220         self._delimBegin = ('=' * level) + ' '
221         self._delimEnd   =  ' %s #%s\n' % (('=' * level), self._anchor)
222         #self._delimEnd   =  ' ' + ('=' * level) + ' #%s\n' % (self._anchor)
223
224         # insert divider for level 1 headers
225         if level == 1:
226             if options.toc or doc._dividerCount:
227                 self._delimBegin = '----\n%s' % (self._delimBegin)
228             doc._dividerCount = doc._dividerCount + 1
229
230         toc.append( self )
231
232 ###############################################################################
233
234 class IndentedElement( BlockElement ):
235     def _write( self, file ):
236         writer.increase()
237         Element._write( self, file )
238         writer.decrease()
239
240 ###############################################################################
241
242 class EnumerateElement( IndentedElement ):
243     pass
244
245 ###############################################################################
246
247 class ItemizeElement( IndentedElement ):
248     pass
249
250 ###############################################################################
251
252 class ItemElement( BlockElement ):
253     def __init__( self, parent ):
254         BlockElement.__init__( self, parent )
255         self._newline = 1
256         if isinstance( parent, TableItemElement ):
257             self._newline    = 0
258             #self._delimBegin = '<td>'
259             #self._delimEnd   = '</td>'
260             self._delimBegin = '    '
261             self._delimEnd   = '\n'
262
263 ###############################################################################
264
265 class ParagraphElement( Element ):
266     def __init__( self, parent ):
267         Element.__init__( self, parent, newline=2 )
268         if isinstance( parent, ItemElement ):
269             if isinstance( parent._parent, TableItemElement ):
270                 self._newline = 0
271             elif isinstance( parent._parent, EnumerateElement ):
272                 self._newline    = 1
273                 self._delimBegin = '# '
274             else:
275                 self._newline    = 1
276                 self._delimBegin = '* '
277
278 ###############################################################################
279
280 class TableItemElement( Element ):
281     def __init__( self, parent ):
282         Element.__init__( self, parent, newline=1, text=False )
283         #self._delimBegin = '<tr>'
284         #self._delimEnd   = '</tr>'
285
286 ###############################################################################
287
288 class UrefInline( Element ):
289     def __init__( self, parent ):
290         Element.__init__( self, parent, text=False, delimBegin='[', delimEnd=']' )
291
292 ###############################################################################
293
294 class UrefDescInline( Element ):
295     def __init__( self, parent ):
296         Element.__init__( self, parent, delimBegin=' ' )
297
298 ###############################################################################
299
300 class UrefUrlInline( Element ):
301     def __init__( self, parent ):
302         Element.__init__( self, parent )
303
304 ###############################################################################
305
306 class XrefInline( Element ):
307     def __init__( self, parent ):
308         Element.__init__( self, parent, text=False )
309
310 ###############################################################################
311
312 class XrefNodenameInline( Element ):
313     def __init__( self, parent ):
314         Element.__init__( self, parent )
315
316     def _write( self, file ):
317         buffer = io.StringIO()
318         Element._write( self, buffer )
319         name = str( buffer.getvalue() )
320         anchor = re.sub( ' ', '_', name )
321         file.write( '[#%s %s]' % (anchor, name) )
322
323 ###############################################################################
324
325 class IndentedWriter:
326     def __init__( self, size, file ):
327         self._chunk   = ' ' * size
328         self._file    = file
329         self._level   = 0
330         self._indent  = ''
331         self._pending = False
332
333         self.newlineCount = 0
334
335     def decrease( self ):
336         self._level  = self._level - 1
337         self._indent = self._chunk * self._level
338
339     def increase( self ):
340         self._level  = self._level + 1
341         self._indent = self._chunk * self._level
342
343     def write( self, data ):
344         for b in data:
345             if self._pending:
346                 self._pending = False
347                 self._file.write( self._indent )
348             if b == '\n':
349                 self.newlineCount = self.newlineCount + 1
350                 self._pending = True
351             else:
352                 self.newlineCount = 0
353             self._file.write( b )
354
355 ###############################################################################
356
357 parser = OptionParser( 'Usage: %prog [OPTIONS] xml' )
358 parser.add_option( '-d', '--date', action='store_true', default=False, help='generate date-stamp under title' )
359 parser.add_option( '-t', '--toc', action='store_true', default=False, help='generate table of contents' )
360 parser.add_option( '-v', '--verbose', action='count', default=False, help='increase verbosity' )
361
362 (options, args) = parser.parse_args()
363
364 if( len(args) != 1 ):
365     parser.error( 'incorrect number of arguments' )
366
367 ###############################################################################
368
369 doc = Document()
370 xml = xml.parsers.expat.ParserCreate()
371
372 xml.StartElementHandler  = doc.handleElementBegin
373 xml.EndElementHandler    = doc.handleElementEnd
374 xml.CharacterDataHandler = doc.handleCharacterData
375
376 anchor = None
377 toc = []
378 with open( args[0], 'rb' ) as fin:
379     xml.ParseFile( fin )
380
381 writer = IndentedWriter( 4, sys.stdout )
382
383 doc._majorHeading.write( writer )
384 if options.toc:
385     for e in toc:
386         writer.write( '%s* [#%s %s]\n' % ('  ' * e._level,e._anchor,e._stream[0].object) )
387 doc.write( writer )