source: CMT/v1r18p20050901/doc/gendoc.py @ 668

Last change on this file since 668 was 83, checked in by arnault, 19 years ago

Add structure_strategy - see CL#278

  • Property svn:eol-style set to native
File size: 17.1 KB
Line 
1#-----------------------------------------------------------
2# Copyright Christian Arnault LAL-Orsay CNRS
3# arnault@lal.in2p3.fr
4# See the complete license in cmt_license.txt "http://www.cecill.info".
5#-----------------------------------------------------------
6
7import sys, os, string, getopt, types
8import xml.parsers.expat
9from datetime import date
10
11#------------------------------------------------------------
12# A Section holds
13#   an  id     of the form n.m.p
14#   a   title
15#   the level
16#
17class Section :
18  def __init__ (self, id, title, level) :
19    self.id = id
20    self.title = title
21    self.level = level
22  # end def
23
24  # Format the index entry for this section
25  def show_index_entry (self) :
26    tab = string.rjust ("", 4*self.level)
27    tab = tab.replace (" ", " ")
28    print '<tr>'
29    print '<td width="100">' + self.id + '</td>'
30    print '<td>' + tab + '<a href="#' + self.title + '">' + self.title + '</a></td>'
31    print '</tr>'
32  # end def
33
34#------------------------------------------------------------
35# A Book
36#  It holds the history of sections and the definitions of internal entities
37#
38class Book :
39  # Format one level of a section id as %2.2d
40  def format_id (self, id) :
41    r = repr (id)
42    if id < 10 :
43      r = '&nbsp;' + r
44    return r
45  # end def
46
47  # Format a complete section id, with all individual level ids
48  #  Currently the implementation is somewhat ugly. This is due
49  #  to the strange behaviour of the ideal form (using a for-loop
50  #  over the elements of self.level_ids). Once we can understand
51  #  the reason of this unexpected behaviour we can improve it.
52  def build_id (self) :
53    id = '<tt>'
54    n = len (self.level_ids)
55    if n >= 1 :
56      id += self.format_id (self.level_ids[0])
57    if n >= 2 :
58      id += '.' + self.format_id (self.level_ids[1])
59    if n >= 3 :
60      id += '.' + self.format_id (self.level_ids[2])
61    if n >= 4 :
62      id += '.' + self.format_id (self.level_ids[3])
63    id += '</tt>'
64    return id
65  # end def
66
67  # Create a new Section object
68  #  Register the history of sections (with level hierarchy)
69  def open_section (self, name) :
70    self.level_ids [self.level] += 1
71    i = self.level_ids [self.level]
72    id = self.build_id ()
73    self.sections.append (Section (id, name, self.level))
74    self.level += 1
75    self.level_ids.append (0)
76    return id
77  # end def
78
79  # Pop one level in the level hierarchy
80  def close_section (self) :
81    self.level_ids.pop ()
82    self.level -= 1
83  # end def
84
85  # Register the definition of an internal entity in the entity dictionary
86  def entity_decl (self, name, is_parameter, value, base, systemId, publicId, notation) :
87    if value :
88      self.entities['&' + name + ';'] = value
89  # end def
90
91  # Generic parser
92  def generic_parse (self, p, name) :
93    p.StartElementHandler = self.start_element
94    p.EndElementHandler = self.end_element
95    p.CharacterDataHandler = self.char_data
96    p.ExternalEntityRefHandler = self.external_entity
97    p.DefaultHandler = self.dummy
98    p.EntityDeclHandler = self.entity_decl
99    #file_name = os.path.join (sys.path[0], name)
100    f = open (name)
101    p.ParseFile (f)
102    f.close ()
103  # end def
104
105  # Top level parser
106  def parse (self, name) :
107    self.p = xml.parsers.expat.ParserCreate ()
108    self.generic_parse (self.p, name)
109  # end def
110
111  # Sub-parser for external entities
112  def external_entity (self, context, base, system_id, public_id):
113    #print "external entity " + repr(context) + " " + repr(system_id) + ' ' + sys.path[0]
114    ep = self.p.ExternalEntityParserCreate (context)
115    self.generic_parse (ep, system_id)
116  # end def
117
118  # Format a tabulation according to the stored tabulation level
119  def tab (self) :
120    return (string.rjust ("", self.tabulation))
121  # end def
122
123  # Flush the internal line buffer and display it using the tabulation
124  def purge (self) :
125    if self.line != '':
126      if self.in_code == 0 :
127        print self.tab () + self.line
128        self.line = ''
129  # end def
130
131
132  #----------------------------------------------------------
133  #
134  #  All XML element handlers
135  #
136  #----------------------------------------------------------
137
138
139  # any element : simply reproduce the element with its attributes
140  #  (ie assume it is a true HTML element)
141  def default_start (self, name, attrs) :
142    self.line += '<' + name
143    if len (attrs) > 0 :
144      i = len (attrs)
145      for k, v in attrs.items() :
146        self.line += ' ' + k + '="' + v + '"'
147        i -= 1
148        if i <= 0 : break
149    self.line += '>'
150    #####  self.purge ()
151    self.tabulation += 2
152  # end def
153
154
155  def default_end (self, name) :
156    self.tabulation -= 2
157    self.line += '</' + name + '>'
158    self.purge ()
159  # end def
160
161
162  # <book>
163  def book_start (self, attrs) :
164    self.name = attrs['name']
165    self.title = attrs['title']
166    self.version = attrs['version']
167    self.author = attrs['author']
168    print '<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> '
169    print '<html>'
170    print '<title>' + self.name + '</title>'
171    print '<head>'
172    print ' <style type="text/css">'
173    print '   body {font-face: Arial, Helvetica, Comic Sans MS, Times; color: #000000}'
174    ##print '   tt {color:#006600; font-weight: normal; background-color: #eeffee}'
175    print '   tt {color:#00AA00; font-weight: normal; background-color: #eeeeee}'
176    print '   pre {color:#FF0000; background-color: #eeeeee; border-style: solid; border-width: 1; border-color: black; padding: 4}'
177    print '   pre.cmt {font-family: courier; color:#00AA00; background-color: #eeeeee; border-style: solid; border-width: 1; border-color: black; padding: 4}'
178    print '   h2 {color:#0000FF}'
179    print '   h3 {color:#00AA00}'
180    print '   h4 {color:#997700}'
181    print '   a {color:#0000FF; background-color: LightGoldenRodYellow; text-decoration: none}'
182    print '   b {font-family: courier; color:#006600; font-weight: normal; %background-color: #eeffee}'
183    print '   td.rule {padding-top: 10}'
184    print ' </style>'
185    print '</head>'
186    print '<body bgcolor="#ffffff" link="#550088" alink="#007777" alink="#007777">'
187    ##print '<font face="Arial, Helvetica" color="#000000">'
188    ##print '<font face="Arial, Helvetica, Comic Sans MS, Times" color="#000000">'
189    print '<h1><center>' + self.name + '</center>'
190    print '<center>' + self.title + '</center></h1>'
191    print '<h2><center>Version ' + self.version + '</center>'
192    print '<center>' + self.author + '</center>'
193    print '<center><tt>' + attrs['email'] + '</tt></center></h2>'
194    self.line += '<center><i>Document revision date : ' + date.today().isoformat() + '</i></center>'
195    self.line += '<hr><h2>'
196    self.line += '<a href="#index">General index</a>'
197    self.line += '</h2>'
198    self.purge ()
199  # end def
200
201  def book_end (self) :
202    print '<hr><h1><A NAME="index"></A>Contents</h1>'
203    print '<blockquote>'
204    print '<table cols="2">'
205    for k in range (len (self.sections)) :
206      self.sections[k].show_index_entry ()
207    print '<tr><td colspan="2">&nbsp;</td></tr>'
208    print '<tr><td colspan="2"><h2>Images</h2></td></tr>'
209    for k in range (len (self.images)) :
210      print '<tr>'
211      print '<td width="100"><tt>' + repr(k+1) + '</tt></td>'
212      print '<td><a href="#' + self.images[k] + '">' + self.images[k] + '</a></td>'
213      print '</tr>'
214    print '</table>'
215    print '</blockquote>'
216    ##print '</font>'
217    print '<address>'
218    print '<i>' + self.author + '</i>'
219    print '</address>'
220    print '</body>'
221    print '</html>'
222  # end def
223
224
225  # <section>
226  def section_start (self, attrs) :
227    title = attrs['title']
228    title = title.replace ('>', '&gt;')
229    title = title.replace ('<', '&lt;')
230    id = self.open_section (title)
231    h_level = repr(self.level+1)
232    self.line += '<hr><h' + h_level + '>'
233    self.line += '<a name="' + title + '"></a>'
234    self.line += '<a href="#index">' + id + '</a> - ' + title
235    self.line += '</h' + h_level + '>'
236    self.purge ()
237    self.line = '<blockquote>'
238    self.purge ()
239  # end def
240
241  def section_end (self) :
242    self.purge ()
243    self.line = '</blockquote>'
244    self.purge ()
245    self.close_section ()
246  # end def
247
248
249  # <code>
250  def code_start (self, attrs) :
251    self.purge ()
252    self.in_code += 1
253    self.line = '<pre>'
254  # end def
255
256  def code_end (self) :
257    self.in_code -= 1
258    print self.line + '</pre>'
259    self.line = ''
260  # end def
261
262
263  # <cmtcode>
264  def cmtcode_start (self, attrs) :
265    self.purge ()
266    self.in_code += 1
267    self.line = '<pre class="cmt">'
268  # end def
269
270  def cmtcode_end (self) :
271    self.in_code -= 1
272    print self.line + '</pre>'
273    self.line = ''
274  # end def
275
276
277  # <syntax>
278  def syntax_start (self, attrs) :
279    print '<center>'
280    print '<table cols="3">'
281    print '<tr>'
282    if 'rule-width' in attrs :
283      print '<td width="' + attrs['rule-width'] + '"></td>'
284    else :
285      print '<td></td>'
286    if 'name' in attrs :
287      self.ruleref_prefix = 'kw' + attrs['name'] + '-'
288    else :
289      self.ruleref_prefix = 'kw-'
290    print '<td width="10"></td>'
291    print '<td></td>'
292    print '</tr>' 
293  # end def
294
295  def syntax_end (self) :
296    print '</table>'
297    print '</center>'
298  # end def
299
300
301  # <rule>
302  def rule_start (self, attrs) :
303    self.rule_name = attrs['name']
304    self.rule_started = 0
305  # end def
306
307  def rule_end (self) :
308    self.rule_name = ''
309    self.rule_started = 0
310  # end def
311
312
313  # <alt>
314  def alt_start (self, attrs) :
315    print '<tr>'
316    if self.rule_started == 0 :
317      self.rule_started = 1
318      print '<td class="rule"><font face="courier new, courier" COLOR="#770000"><i><a name="' + self.ruleref_prefix + self.rule_name + '"></a>' + self.rule_name + '</i></font></td>'
319      print '<td class="rule">:</td>'
320      print '<td class="rule">'
321    else :
322      print '<td></td>'
323      print '<td>|</td>'
324      print '<td>'
325  # end def
326     
327  def alt_end (self) :
328    print '</td>'
329    print '</tr>'
330  # end def
331
332
333  # <continuation>
334  def continuation_start (self, attrs) :
335    print '<tr>'
336    print '<td></td>'
337    print '<td></td>'
338    print '<td>&nbsp;&nbsp;&nbsp;'
339  # end def
340     
341  def continuation_end (self) :
342    print '</td>'
343    print '</tr>'
344  # end def
345
346
347  # <kwd>
348  def kwd_start (self, attrs) :
349    print '<font face="courier new, courier" COLOR="#FF0000">'
350    if 'name' in attrs :
351      name = attrs['name']
352    else :
353      name = self.rule_name
354    if 'value' in attrs :
355      name += '='
356      value = '<font face="courier new, courier" COLOR="#770000"><i>'
357      value += attrs['value']
358      value += '</i></font>'
359    else :
360      value = ''
361    print name + value
362  # end def
363
364  def kwd_end (self) :
365    print '</font>'
366  # end def
367
368
369
370  # <term>
371  def term_start (self, attrs) :
372    print '<font face="courier new, courier" COLOR="#770000"><i>'
373    print attrs['name']
374  # end def
375
376  def term_end (self) :
377    print '</i></font>'
378  # end def
379
380
381
382  # <ruleref>
383  def ruleref_start (self, attrs) :
384    print '<font face="courier new, courier" COLOR="#770000"><i>'
385    print '<a href="#' + self.ruleref_prefix + attrs['name'] + '">' + attrs['name'] + '</a>'
386  # end def
387
388  def ruleref_end (self) :
389    print '</i></font>'
390  # end def
391
392
393  # <option>
394  def option_start (self, attrs) :
395    print '[&nbsp;'
396  # end def
397
398  def option_end (self) :
399    print '&nbsp;]&nbsp;'
400  # end def
401
402
403  # <seq>
404  def seq_start (self, attrs) :
405    i=0
406  # end def
407
408  def seq_end (self) :
409    print '&nbsp;...&nbsp;'
410  # end def
411
412
413  # <optionseq>
414  def optionseq_start (self, attrs) :
415    print '[&nbsp;'
416  # end def
417
418  def optionseq_end (self) :
419    print '&nbsp;...&nbsp;'
420    print '&nbsp;]&nbsp;'
421  # end def
422
423
424
425  # <image>
426  def image_start (self, attrs) :
427    caption = attrs['caption']
428    self.images.append (caption)
429    n = len (self.images)
430    print '<center>'
431    print '<a name="' + caption + '"></a>'
432    print '<img src="' + attrs['src'] + '"/>'
433    print '</center>'
434    print '<center>'
435    print '<tt>' + repr(n) + '</tt> - <i>' + caption + '</i>'
436  # end def
437
438  def image_end (self) :
439    print '</center>'
440  # end def
441
442  def blockquote_start (self, attrs) :
443    print '<blockquote><hr>'
444  # end def
445
446  def blockquote_end (self) :
447    print '<hr></blockquote>'
448  # end def
449
450
451  # Basic element parsing handler
452  def start_element (self, name, attrs):
453    #print 'start_element: name=' + repr(name)
454    try :
455      if self.start_handlers.has_key (name) :
456        self.start_handlers [name] (attrs)
457      else :
458        self.default_start (name, attrs)
459    except TypeError:
460      print 'start_element: (error) name=' + repr(name)
461      self.default_start (name, attrs)
462  # end def
463
464  def end_element (self, name) :
465    #print 'end_element: name=' + repr(name)
466    try :
467      if self.end_handlers.has_key (name) :
468        self.end_handlers [name] ()
469      else :
470        self.default_end (name)
471    except TypeError:
472      #print 'end_element: (error) name=' + repr(name)
473      if name == u'cmt:book' :
474        self.book_end ()
475      else :
476        self.default_end (name)
477  # end def
478
479  # Unhandled elements will be trapped here
480  def dummy (self, data) :
481    if self.entities.has_key (data) :
482      self.char_data (self.entities[data])
483    #print "dummy:[" + repr (data) + "]" + repr (type(data))
484  # end def
485
486  # CDATA handling inside code sections
487  def code_char_data (self, data) :
488    if data == u'\n' :
489      self.line += data
490    else :
491      n = len (data)
492      #
493      if n > 0 :
494        if data == u'<':
495          self.line += '&lt;'
496        elif data == u'>' :
497          self.line += '&gt;'
498        else :
499          self.line += data
500  # end def
501
502  # CDATA handling outside code sections
503  def plain_char_data (self, data) :
504    if data == u'\n' :
505      self.purge ()
506    else :
507      n = len (string.strip (data))
508      #
509      if n > 0 :
510        if data == u'<':
511          self.line += '&lt;'
512        elif data == u'>' :
513          self.line += '&gt;'
514        else :
515  #        self.line += string.strip (data)
516          self.line += data
517  # end def
518
519  # CDATA handling
520  def char_data (self, data) :
521    #print '[' + repr(data) + ']' + repr (type (data)) + ' ' + repr(len (string.strip (data)))
522    if self.in_code > 0 :
523      self.code_char_data (data)
524    else :
525      self.plain_char_data (data)
526  # end def
527
528  def __init__ (self) :
529    self.line = ''
530    self.tabulation = 0
531    self.in_code = 0
532    self.sections = []
533    self.level_ids = [0]
534    self.level = 0
535    self.images = []
536    self.entities = {}
537    #
538    self.start_handlers = {}
539    self.start_handlers['cmt:code'] = self.code_start
540    self.start_handlers['cmt:cmtcode'] = self.cmtcode_start
541    self.start_handlers['cmt:section'] = self.section_start
542    self.start_handlers['cmt:book'] = self.book_start
543    self.start_handlers['cmt:syntax'] = self.syntax_start
544    self.start_handlers['cmt:rule'] = self.rule_start
545    self.start_handlers['cmt:alt'] = self.alt_start
546    self.start_handlers['cmt:continuation'] = self.continuation_start
547    self.start_handlers['cmt:kwd'] = self.kwd_start
548    self.start_handlers['cmt:term'] = self.term_start
549    self.start_handlers['cmt:ruleref'] = self.ruleref_start
550    self.start_handlers['cmt:option'] = self.option_start
551    self.start_handlers['cmt:seq'] = self.seq_start
552    self.start_handlers['cmt:optionseq'] = self.optionseq_start
553    self.start_handlers['cmt:image'] = self.image_start
554    self.start_handlers['cmt:blockquote'] = self.blockquote_start
555    #
556    self.end_handlers = {}
557    self.end_handlers['cmt:code'] = self.code_end
558    self.end_handlers['cmt:cmtcode'] = self.cmtcode_end
559    self.end_handlers['cmt:section'] = self.section_end
560    self.end_handlers['cmt:book'] = self.book_end
561    self.end_handlers['cmt:syntax'] = self.syntax_end
562    self.end_handlers['cmt:rule'] = self.rule_end
563    self.end_handlers['cmt:alt'] = self.alt_end
564    self.end_handlers['cmt:continuation'] = self.continuation_end
565    self.end_handlers['cmt:kwd'] = self.kwd_end
566    self.end_handlers['cmt:term'] = self.term_end
567    self.end_handlers['cmt:ruleref'] = self.ruleref_end
568    self.end_handlers['cmt:option'] = self.option_end
569    self.end_handlers['cmt:seq'] = self.seq_end
570    self.end_handlers['cmt:optionseq'] = self.optionseq_end
571    self.end_handlers['cmt:image'] = self.image_end
572    self.end_handlers['cmt:blockquote'] = self.blockquote_end
573  # end def
574
575
576
577#----------------------------------------------------------------------------------
578
579#----------------------------------------------------------------------------------
580#
581#  Various top level functions
582#
583#----------------------------------------------------------------------------------
584def usage() :
585  print 'Usage:'
586  print '  gendoc'
587  print 'Try "gendoc --help" for more information.'
588  sys.exit()
589# end def
590
591#----------------------------------------------------------------------------------
592def help() :
593  print "Generates the HTML documentation from Xml"
594# end def
595
596#----------------------------------------------------------------------------------
597def main() :
598  file_name = ''
599  options = []
600  for a in sys.argv[1:] :
601    if a[0] == '-' :
602      options = sys.argv[sys.argv.index(a):]
603      break
604    else :
605      file_name = a
606  try:
607    opts, args = getopt.getopt(options, 'h', ['help'])
608  except getopt.GetoptError:
609    usage()
610    sys.exit(2)
611  for o, a in opts:
612    if o in ('-h', '--help'):
613      help()
614      sys.exit()
615  book = Book ()
616  book.parse (file_name)
617# end def
618
619#---------------------------------------------------------------------
620#print '__name__ = ' + __name__
621if __name__ == "__main__":
622  main()
623# end def
624
Note: See TracBrowser for help on using the repository browser.