Initialize Tizen 2.3
[framework/graphics/freetype.git] / src / tools / docmaker / tohtml.py
1 #  ToHTML (c) 2002, 2003, 2005, 2006, 2007, 2008
2 #    David Turner <david@freetype.org>
3
4 from sources import *
5 from content import *
6 from formatter import *
7
8 import time
9
10
11 # The following defines the HTML header used by all generated pages.
12 html_header_1 = """\
13 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
14 "http://www.w3.org/TR/html4/loose.dtd">
15 <html>
16 <head>
17 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
18 <title>\
19 """
20
21 html_header_2 = """\
22  API Reference</title>
23 <style type="text/css">
24   body { font-family: Verdana, Geneva, Arial, Helvetica, serif;
25          color: #000000;
26          background: #FFFFFF; }
27
28   p { text-align: justify; }
29   h1 { text-align: center; }
30   li { text-align: justify; }
31   td { padding: 0 0.5em 0 0.5em; }
32   td.left { padding: 0 0.5em 0 0.5em;
33             text-align: left; }
34
35   a:link { color: #0000EF; }
36   a:visited { color: #51188E; }
37   a:hover { color: #FF0000; }
38
39   span.keyword { font-family: monospace;
40                  text-align: left;
41                  white-space: pre;
42                  color: darkblue; }
43
44   pre.colored { color: blue; }
45
46   ul.empty { list-style-type: none; }
47 </style>
48 </head>
49 <body>
50 """
51
52 html_header_3 = """
53 <table align=center><tr><td><font size=-1>[<a href="\
54 """
55
56 html_header_3i = """
57 <table align=center><tr><td width="100%"></td>
58 <td><font size=-1>[<a href="\
59 """
60
61 html_header_4 = """\
62 ">Index</a>]</font></td>
63 <td width="100%"></td>
64 <td><font size=-1>[<a href="\
65 """
66
67 html_header_5 = """\
68 ">TOC</a>]</font></td></tr></table>
69 <center><h1>\
70 """
71
72 html_header_5t = """\
73 ">Index</a>]</font></td>
74 <td width="100%"></td></tr></table>
75 <center><h1>\
76 """
77
78 html_header_6 = """\
79  API Reference</h1></center>
80 """
81
82
83 # The HTML footer used by all generated pages.
84 html_footer = """\
85 </body>
86 </html>\
87 """
88
89 # The header and footer used for each section.
90 section_title_header = "<center><h1>"
91 section_title_footer = "</h1></center>"
92
93 # The header and footer used for code segments.
94 code_header = '<pre class="colored">'
95 code_footer = '</pre>'
96
97 # Paragraph header and footer.
98 para_header = "<p>"
99 para_footer = "</p>"
100
101 # Block header and footer.
102 block_header        = '<table align=center width="75%"><tr><td>'
103 block_footer_start  = """\
104 </td></tr></table>
105 <hr width="75%">
106 <table align=center width="75%"><tr><td><font size=-2>[<a href="\
107 """
108 block_footer_middle = """\
109 ">Index</a>]</font></td>
110 <td width="100%"></td>
111 <td><font size=-2>[<a href="\
112 """
113 block_footer_end    = """\
114 ">TOC</a>]</font></td></tr></table>
115 """
116
117 # Description header/footer.
118 description_header = '<table align=center width="87%"><tr><td>'
119 description_footer = "</td></tr></table><br>"
120
121 # Marker header/inter/footer combination.
122 marker_header = '<table align=center width="87%" cellpadding=5><tr bgcolor="#EEEEFF"><td><em><b>'
123 marker_inter  = "</b></em></td></tr><tr><td>"
124 marker_footer = "</td></tr></table>"
125
126 # Header location header/footer.
127 header_location_header = '<table align=center width="87%"><tr><td>'
128 header_location_footer = "</td></tr></table><br>"
129
130 # Source code extracts header/footer.
131 source_header = '<table align=center width="87%"><tr bgcolor="#D6E8FF"><td><pre>\n'
132 source_footer = "\n</pre></table><br>"
133
134 # Chapter header/inter/footer.
135 chapter_header = '<br><table align=center width="75%"><tr><td><h2>'
136 chapter_inter  = '</h2><ul class="empty"><li>'
137 chapter_footer = '</li></ul></td></tr></table>'
138
139 # Index footer.
140 index_footer_start = """\
141 <hr>
142 <table><tr><td width="100%"></td>
143 <td><font size=-2>[<a href="\
144 """
145 index_footer_end = """\
146 ">TOC</a>]</font></td></tr></table>
147 """
148
149 # TOC footer.
150 toc_footer_start = """\
151 <hr>
152 <table><tr><td><font size=-2>[<a href="\
153 """
154 toc_footer_end = """\
155 ">Index</a>]</font></td>
156 <td width="100%"></td>
157 </tr></table>
158 """
159
160
161 # source language keyword coloration/styling
162 keyword_prefix = '<span class="keyword">'
163 keyword_suffix = '</span>'
164
165 section_synopsis_header = '<h2>Synopsis</h2>'
166 section_synopsis_footer = ''
167
168
169 # Translate a single line of source to HTML.  This will convert
170 # a "<" into "&lt.", ">" into "&gt.", etc.
171 def  html_quote( line ):
172     result = string.replace( line, "&", "&amp;" )
173     result = string.replace( result, "<", "&lt;" )
174     result = string.replace( result, ">", "&gt;" )
175     return result
176
177
178 # same as 'html_quote', but ignores left and right brackets
179 def  html_quote0( line ):
180     return string.replace( line, "&", "&amp;" )
181
182
183 def  dump_html_code( lines, prefix = "" ):
184     # clean the last empty lines
185     l = len( self.lines )
186     while l > 0 and string.strip( self.lines[l - 1] ) == "":
187         l = l - 1
188
189     # The code footer should be directly appended to the last code
190     # line to avoid an additional blank line.
191     print prefix + code_header,
192     for line in self.lines[0 : l + 1]:
193         print '\n' + prefix + html_quote( line ),
194     print prefix + code_footer,
195
196
197
198 class  HtmlFormatter( Formatter ):
199
200     def  __init__( self, processor, project_title, file_prefix ):
201         Formatter.__init__( self, processor )
202
203         global html_header_1, html_header_2, html_header_3
204         global html_header_4, html_header_5, html_footer
205
206         if file_prefix:
207             file_prefix = file_prefix + "-"
208         else:
209             file_prefix = ""
210
211         self.headers           = processor.headers
212         self.project_title     = project_title
213         self.file_prefix       = file_prefix
214         self.html_header       = html_header_1 + project_title +              \
215                                  html_header_2 +                              \
216                                  html_header_3 + file_prefix + "index.html" + \
217                                  html_header_4 + file_prefix + "toc.html" +   \
218                                  html_header_5 + project_title +              \
219                                  html_header_6
220
221         self.html_index_header = html_header_1 + project_title +             \
222                                  html_header_2 +                             \
223                                  html_header_3i + file_prefix + "toc.html" + \
224                                  html_header_5 + project_title +             \
225                                  html_header_6
226
227         self.html_toc_header   = html_header_1 + project_title +              \
228                                  html_header_2 +                              \
229                                  html_header_3 + file_prefix + "index.html" + \
230                                  html_header_5t + project_title +             \
231                                  html_header_6
232
233         self.html_footer       = "<center><font size=""-2"">generated on " +     \
234                                  time.asctime( time.localtime( time.time() ) ) + \
235                                  "</font></center>" + html_footer
236
237         self.columns = 3
238
239     def  make_section_url( self, section ):
240         return self.file_prefix + section.name + ".html"
241
242     def  make_block_url( self, block ):
243         return self.make_section_url( block.section ) + "#" + block.name
244
245     def  make_html_words( self, words ):
246         """ convert a series of simple words into some HTML text """
247         line = ""
248         if words:
249             line = html_quote( words[0] )
250             for w in words[1:]:
251                 line = line + " " + html_quote( w )
252
253         return line
254
255     def  make_html_word( self, word ):
256         """analyze a simple word to detect cross-references and styling"""
257         # look for cross-references
258         m = re_crossref.match( word )
259         if m:
260             try:
261                 name = m.group( 1 )
262                 rest = m.group( 2 )
263                 block = self.identifiers[name]
264                 url   = self.make_block_url( block )
265                 return '<a href="' + url + '">' + name + '</a>' + rest
266             except:
267                 # we detected a cross-reference to an unknown item
268                 sys.stderr.write( \
269                    "WARNING: undefined cross reference '" + name + "'.\n" )
270                 return '?' + name + '?' + rest
271
272         # look for italics and bolds
273         m = re_italic.match( word )
274         if m:
275             name = m.group( 1 )
276             rest = m.group( 3 )
277             return '<i>' + name + '</i>' + rest
278
279         m = re_bold.match( word )
280         if m:
281             name = m.group( 1 )
282             rest = m.group( 3 )
283             return '<b>' + name + '</b>' + rest
284
285         return html_quote( word )
286
287     def  make_html_para( self, words ):
288         """ convert words of a paragraph into tagged HTML text, handle xrefs """
289         line = ""
290         if words:
291             line = self.make_html_word( words[0] )
292             for word in words[1:]:
293                 line = line + " " + self.make_html_word( word )
294             # convert `...' quotations into real left and right single quotes
295             line = re.sub( r"(^|\W)`(.*?)'(\W|$)",  \
296                            r'\1&lsquo;\2&rsquo;\3', \
297                            line )
298             # convert tilde into non-breakable space
299             line = string.replace( line, "~", "&nbsp;" )
300
301         return para_header + line + para_footer
302
303     def  make_html_code( self, lines ):
304         """ convert a code sequence to HTML """
305         line = code_header + '\n'
306         for l in lines:
307             line = line + html_quote( l ) + '\n'
308
309         return line + code_footer
310
311     def  make_html_items( self, items ):
312         """ convert a field's content into some valid HTML """
313         lines = []
314         for item in items:
315             if item.lines:
316                 lines.append( self.make_html_code( item.lines ) )
317             else:
318                 lines.append( self.make_html_para( item.words ) )
319
320         return string.join( lines, '\n' )
321
322     def  print_html_items( self, items ):
323         print self.make_html_items( items )
324
325     def  print_html_field( self, field ):
326         if field.name:
327             print "<table><tr valign=top><td><b>" + field.name + "</b></td><td>"
328
329         print self.make_html_items( field.items )
330
331         if field.name:
332             print "</td></tr></table>"
333
334     def  html_source_quote( self, line, block_name = None ):
335         result = ""
336         while line:
337             m = re_source_crossref.match( line )
338             if m:
339                 name   = m.group( 2 )
340                 prefix = html_quote( m.group( 1 ) )
341                 length = len( m.group( 0 ) )
342
343                 if name == block_name:
344                     # this is the current block name, if any
345                     result = result + prefix + '<b>' + name + '</b>'
346                 elif re_source_keywords.match( name ):
347                     # this is a C keyword
348                     result = result + prefix + keyword_prefix + name + keyword_suffix
349                 elif self.identifiers.has_key( name ):
350                     # this is a known identifier
351                     block = self.identifiers[name]
352                     result = result + prefix + '<a href="' + \
353                              self.make_block_url( block ) + '">' + name + '</a>'
354                 else:
355                     result = result + html_quote( line[:length] )
356
357                 line = line[length:]
358             else:
359                 result = result + html_quote( line )
360                 line   = []
361
362         return result
363
364     def  print_html_field_list( self, fields ):
365         print "<p></p>"
366         print "<table cellpadding=3 border=0>"
367         for field in fields:
368             if len( field.name ) > 22:
369               print "<tr valign=top><td colspan=0><b>" + field.name + "</b></td></tr>"
370               print "<tr valign=top><td></td><td>"
371             else:
372               print "<tr valign=top><td><b>" + field.name + "</b></td><td>"
373
374             self.print_html_items( field.items )
375             print "</td></tr>"
376         print "</table>"
377
378     def  print_html_markup( self, markup ):
379         table_fields = []
380         for field in markup.fields:
381             if field.name:
382                 # we begin a new series of field or value definitions, we
383                 # will record them in the 'table_fields' list before outputting
384                 # all of them as a single table
385                 #
386                 table_fields.append( field )
387             else:
388                 if table_fields:
389                     self.print_html_field_list( table_fields )
390                     table_fields = []
391
392                 self.print_html_items( field.items )
393
394         if table_fields:
395             self.print_html_field_list( table_fields )
396
397     #
398     #  Formatting the index
399     #
400     def  index_enter( self ):
401         print self.html_index_header
402         self.index_items = {}
403
404     def  index_name_enter( self, name ):
405         block = self.identifiers[name]
406         url   = self.make_block_url( block )
407         self.index_items[name] = url
408
409     def  index_exit( self ):
410         # block_index already contains the sorted list of index names
411         count = len( self.block_index )
412         rows  = ( count + self.columns - 1 ) / self.columns
413
414         print "<table align=center border=0 cellpadding=0 cellspacing=0>"
415         for r in range( rows ):
416             line = "<tr>"
417             for c in range( self.columns ):
418                 i = r + c * rows
419                 if i < count:
420                     bname = self.block_index[r + c * rows]
421                     url   = self.index_items[bname]
422                     line = line + '<td><a href="' + url + '">' + bname + '</a></td>'
423                 else:
424                     line = line + '<td></td>'
425             line = line + "</tr>"
426             print line
427
428         print "</table>"
429
430         print index_footer_start +            \
431               self.file_prefix + "toc.html" + \
432               index_footer_end
433
434         print self.html_footer
435
436         self.index_items = {}
437
438     def  index_dump( self, index_filename = None ):
439         if index_filename == None:
440             index_filename = self.file_prefix + "index.html"
441
442         Formatter.index_dump( self, index_filename )
443
444     #
445     #  Formatting the table of content
446     #
447     def  toc_enter( self ):
448         print self.html_toc_header
449         print "<center><h1>Table of Contents</h1></center>"
450
451     def  toc_chapter_enter( self, chapter ):
452         print  chapter_header + string.join( chapter.title ) + chapter_inter
453         print "<table cellpadding=5>"
454
455     def  toc_section_enter( self, section ):
456         print '<tr valign=top><td class="left">'
457         print '<a href="' + self.make_section_url( section ) + '">' + \
458                section.title + '</a></td><td>'
459
460         print self.make_html_para( section.abstract )
461
462     def  toc_section_exit( self, section ):
463         print "</td></tr>"
464
465     def  toc_chapter_exit( self, chapter ):
466         print "</table>"
467         print chapter_footer
468
469     def  toc_index( self, index_filename ):
470         print chapter_header +                                      \
471               '<a href="' + index_filename + '">Global Index</a>' + \
472               chapter_inter + chapter_footer
473
474     def  toc_exit( self ):
475         print toc_footer_start +                \
476               self.file_prefix + "index.html" + \
477               toc_footer_end
478
479         print self.html_footer
480
481     def  toc_dump( self, toc_filename = None, index_filename = None ):
482         if toc_filename == None:
483             toc_filename = self.file_prefix + "toc.html"
484
485         if index_filename == None:
486             index_filename = self.file_prefix + "index.html"
487
488         Formatter.toc_dump( self, toc_filename, index_filename )
489
490     #
491     #  Formatting sections
492     #
493     def  section_enter( self, section ):
494         print self.html_header
495
496         print section_title_header
497         print section.title
498         print section_title_footer
499
500         maxwidth = 0
501         for b in section.blocks.values():
502             if len( b.name ) > maxwidth:
503                 maxwidth = len( b.name )
504
505         width = 70  # XXX magic number
506         if maxwidth <> 0:
507             # print section synopsis
508             print section_synopsis_header
509             print "<table align=center cellspacing=5 cellpadding=0 border=0>"
510
511             columns = width / maxwidth
512             if columns < 1:
513                 columns = 1
514
515             count = len( section.block_names )
516             rows  = ( count + columns - 1 ) / columns
517
518             for r in range( rows ):
519                 line = "<tr>"
520                 for c in range( columns ):
521                     i = r + c * rows
522                     line = line + '<td></td><td>'
523                     if i < count:
524                         name = section.block_names[i]
525                         line = line + '<a href="#' + name + '">' + name + '</a>'
526
527                     line = line + '</td>'
528                 line = line + "</tr>"
529                 print line
530
531             print "</table><br><br>"
532             print section_synopsis_footer
533
534         print description_header
535         print self.make_html_items( section.description )
536         print description_footer
537
538     def  block_enter( self, block ):
539         print block_header
540
541         # place html anchor if needed
542         if block.name:
543             print '<h4><a name="' + block.name + '">' + block.name + '</a></h4>'
544
545         # dump the block C source lines now
546         if block.code:
547             header = ''
548             for f in self.headers.keys():
549                 if block.source.filename.find( f ) >= 0:
550                     header = self.headers[f] + ' (' + f + ')'
551                     break;
552                 
553 #           if not header:
554 #               sys.stderr.write( \
555 #                 'WARNING: No header macro for ' + block.source.filename + '.\n' )
556
557             if header:
558                 print header_location_header
559                 print 'Defined in ' + header + '.'
560                 print header_location_footer
561
562             print source_header
563             for l in block.code:
564                 print self.html_source_quote( l, block.name )
565             print source_footer
566
567     def  markup_enter( self, markup, block ):
568         if markup.tag == "description":
569             print description_header
570         else:
571             print marker_header + markup.tag + marker_inter
572
573         self.print_html_markup( markup )
574
575     def  markup_exit( self, markup, block ):
576         if markup.tag == "description":
577             print description_footer
578         else:
579             print marker_footer
580
581     def  block_exit( self, block ):
582         print block_footer_start + self.file_prefix + "index.html" + \
583               block_footer_middle + self.file_prefix + "toc.html" +  \
584               block_footer_end
585
586     def  section_exit( self, section ):
587         print html_footer
588
589     def  section_dump_all( self ):
590         for section in self.sections:
591             self.section_dump( section, self.file_prefix + section.name + '.html' )
592
593 # eof