1 # ToHTML (c) 2002, 2003, 2005, 2006, 2007, 2008
2 # David Turner <david@freetype.org>
6 from formatter
import *
11 # The following defines the HTML header used by all generated pages.
13 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
14 "http://www.w3.org/TR/html4/loose.dtd">
17 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
23 <style type="text/css">
24 body { font-family: Verdana, Geneva, Arial, Helvetica, serif;
26 background: #FFFFFF; }
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;
35 a:link { color: #0000EF; }
36 a:visited { color: #51188E; }
37 a:hover { color: #FF0000; }
39 span.keyword { font-family: monospace;
44 pre.colored { color: blue; }
46 ul.empty { list-style-type: none; }
53 <table align=center><tr><td><font size=-1>[<a href="\
57 <table align=center><tr><td width="100%"></td>
58 <td><font size=-1>[<a href="\
62 ">Index</a>]</font></td>
63 <td width="100%"></td>
64 <td><font size=-1>[<a href="\
68 ">TOC</a>]</font></td></tr></table>
73 ">Index</a>]</font></td>
74 <td width="100%"></td></tr></table>
79 API Reference</h1></center>
83 # The HTML footer used by all generated pages.
89 # The header and footer used for each section.
90 section_title_header
= "<center><h1>"
91 section_title_footer
= "</h1></center>"
93 # The header and footer used for code segments.
94 code_header
= '<pre class="colored">'
95 code_footer
= '</pre>'
97 # Paragraph header and footer.
101 # Block header and footer.
102 block_header
= '<table align=center width="75%"><tr><td>'
103 block_footer_start
= """\
106 <table align=center width="75%"><tr><td><font size=-2>[<a href="\
108 block_footer_middle
= """\
109 ">Index</a>]</font></td>
110 <td width="100%"></td>
111 <td><font size=-2>[<a href="\
113 block_footer_end
= """\
114 ">TOC</a>]</font></td></tr></table>
117 # Description header/footer.
118 description_header
= '<table align=center width="87%"><tr><td>'
119 description_footer
= "</td></tr></table><br>"
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>"
126 # Header location header/footer.
127 header_location_header
= '<table align=center width="87%"><tr><td>'
128 header_location_footer
= "</td></tr></table><br>"
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>"
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>'
140 index_footer_start
= """\
142 <table><tr><td width="100%"></td>
143 <td><font size=-2>[<a href="\
145 index_footer_end
= """\
146 ">TOC</a>]</font></td></tr></table>
150 toc_footer_start
= """\
152 <table><tr><td><font size=-2>[<a href="\
154 toc_footer_end
= """\
155 ">Index</a>]</font></td>
156 <td width="100%"></td>
161 # source language keyword coloration/styling
162 keyword_prefix
= '<span class="keyword">'
163 keyword_suffix
= '</span>'
165 section_synopsis_header
= '<h2>Synopsis</h2>'
166 section_synopsis_footer
= ''
169 # Translate a single line of source to HTML. This will convert
170 # a "<" into "<.", ">" into ">.", etc.
171 def html_quote( line
):
172 result
= string
.replace( line
, "&", "&" )
173 result
= string
.replace( result
, "<", "<" )
174 result
= string
.replace( result
, ">", ">" )
178 # same as 'html_quote', but ignores left and right brackets
179 def html_quote0( line
):
180 return string
.replace( line
, "&", "&" )
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] ) == "":
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
,
198 class HtmlFormatter( Formatter
):
200 def __init__( self
, processor
, project_title
, file_prefix
):
201 Formatter
.__init
__( self
, processor
)
203 global html_header_1
, html_header_2
, html_header_3
204 global html_header_4
, html_header_5
, html_footer
207 file_prefix
= file_prefix
+ "-"
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
+ \
216 html_header_3
+ file_prefix
+ "index.html" + \
217 html_header_4
+ file_prefix
+ "toc.html" + \
218 html_header_5
+ project_title
+ \
221 self
.html_index_header
= html_header_1
+ project_title
+ \
223 html_header_3i
+ file_prefix
+ "toc.html" + \
224 html_header_5
+ project_title
+ \
227 self
.html_toc_header
= html_header_1
+ project_title
+ \
229 html_header_3
+ file_prefix
+ "index.html" + \
230 html_header_5t
+ project_title
+ \
233 self
.html_footer
= "<center><font size=""-2"">generated on " + \
234 time
.asctime( time
.localtime( time
.time() ) ) + \
235 "</font></center>" + html_footer
239 def make_section_url( self
, section
):
240 return self
.file_prefix
+ section
.name
+ ".html"
242 def make_block_url( self
, block
):
243 return self
.make_section_url( block
.section
) + "#" + block
.name
245 def make_html_words( self
, words
):
246 """ convert a series of simple words into some HTML text """
249 line
= html_quote( words
[0] )
251 line
= line
+ " " + html_quote( w
)
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
)
263 block
= self
.identifiers
[name
]
264 url
= self
.make_block_url( block
)
265 return '<a href="' + url
+ '">' + name
+ '</a>' + rest
267 # we detected a cross-reference to an unknown item
269 "WARNING: undefined cross reference '" + name
+ "'.\n" )
270 return '?' + name
+ '?' + rest
272 # look for italics and bolds
273 m
= re_italic
.match( word
)
277 return '<i>' + name
+ '</i>' + rest
279 m
= re_bold
.match( word
)
283 return '<b>' + name
+ '</b>' + rest
285 return html_quote( word
)
287 def make_html_para( self
, words
):
288 """ convert words of a paragraph into tagged HTML text, handle xrefs """
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‘\2’\3', \
298 # convert tilde into non-breakable space
299 line
= string
.replace( line
, "~", " " )
301 return para_header
+ line
+ para_footer
303 def make_html_code( self
, lines
):
304 """ convert a code sequence to HTML """
305 line
= code_header
+ '\n'
307 line
= line
+ html_quote( l
) + '\n'
309 return line
+ code_footer
311 def make_html_items( self
, items
):
312 """ convert a field's content into some valid HTML """
316 lines
.append( self
.make_html_code( item
.lines
) )
318 lines
.append( self
.make_html_para( item
.words
) )
320 return string
.join( lines
, '\n' )
322 def print_html_items( self
, items
):
323 print self
.make_html_items( items
)
325 def print_html_field( self
, field
):
327 print "<table><tr valign=top><td><b>" + field
.name
+ "</b></td><td>"
329 print self
.make_html_items( field
.items
)
332 print "</td></tr></table>"
334 def html_source_quote( self
, line
, block_name
= None ):
337 m
= re_source_crossref
.match( line
)
340 prefix
= html_quote( m
.group( 1 ) )
341 length
= len( m
.group( 0 ) )
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>'
355 result
= result
+ html_quote( line
[:length
] )
359 result
= result
+ html_quote( line
)
364 def print_html_field_list( self
, fields
):
366 print "<table cellpadding=3 border=0>"
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>"
372 print "<tr valign=top><td><b>" + field
.name
+ "</b></td><td>"
374 self
.print_html_items( field
.items
)
378 def print_html_markup( self
, markup
):
380 for field
in markup
.fields
:
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
386 table_fields
.append( field
)
389 self
.print_html_field_list( table_fields
)
392 self
.print_html_items( field
.items
)
395 self
.print_html_field_list( table_fields
)
398 # Formatting the index
400 def index_enter( self
):
401 print self
.html_index_header
402 self
.index_items
= {}
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
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
414 print "<table align=center border=0 cellpadding=0 cellspacing=0>"
415 for r
in range( rows
):
417 for c
in range( self
.columns
):
420 bname
= self
.block_index
[r
+ c
* rows
]
421 url
= self
.index_items
[bname
]
422 line
= line
+ '<td><a href="' + url
+ '">' + bname
+ '</a></td>'
424 line
= line
+ '<td></td>'
425 line
= line
+ "</tr>"
430 print index_footer_start
+ \
431 self
.file_prefix
+ "toc.html" + \
434 print self
.html_footer
436 self
.index_items
= {}
438 def index_dump( self
, index_filename
= None ):
439 if index_filename
== None:
440 index_filename
= self
.file_prefix
+ "index.html"
442 Formatter
.index_dump( self
, index_filename
)
445 # Formatting the table of content
447 def toc_enter( self
):
448 print self
.html_toc_header
449 print "<center><h1>Table of Contents</h1></center>"
451 def toc_chapter_enter( self
, chapter
):
452 print chapter_header
+ string
.join( chapter
.title
) + chapter_inter
453 print "<table cellpadding=5>"
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>'
460 print self
.make_html_para( section
.abstract
)
462 def toc_section_exit( self
, section
):
465 def toc_chapter_exit( self
, chapter
):
469 def toc_index( self
, index_filename
):
470 print chapter_header
+ \
471 '<a href="' + index_filename
+ '">Global Index</a>' + \
472 chapter_inter
+ chapter_footer
474 def toc_exit( self
):
475 print toc_footer_start
+ \
476 self
.file_prefix
+ "index.html" + \
479 print self
.html_footer
481 def toc_dump( self
, toc_filename
= None, index_filename
= None ):
482 if toc_filename
== None:
483 toc_filename
= self
.file_prefix
+ "toc.html"
485 if index_filename
== None:
486 index_filename
= self
.file_prefix
+ "index.html"
488 Formatter
.toc_dump( self
, toc_filename
, index_filename
)
491 # Formatting sections
493 def section_enter( self
, section
):
494 print self
.html_header
496 print section_title_header
498 print section_title_footer
501 for b
in section
.blocks
.values():
502 if len( b
.name
) > maxwidth
:
503 maxwidth
= len( b
.name
)
505 width
= 70 # XXX magic number
507 # print section synopsis
508 print section_synopsis_header
509 print "<table align=center cellspacing=5 cellpadding=0 border=0>"
511 columns
= width
/ maxwidth
515 count
= len( section
.block_names
)
516 rows
= ( count
+ columns
- 1 ) / columns
518 for r
in range( rows
):
520 for c
in range( columns
):
522 line
= line
+ '<td></td><td>'
524 name
= section
.block_names
[i
]
525 line
= line
+ '<a href="#' + name
+ '">' + name
+ '</a>'
527 line
= line
+ '</td>'
528 line
= line
+ "</tr>"
531 print "</table><br><br>"
532 print section_synopsis_footer
534 print description_header
535 print self
.make_html_items( section
.description
)
536 print description_footer
538 def block_enter( self
, block
):
541 # place html anchor if needed
543 print '<h4><a name="' + block
.name
+ '">' + block
.name
+ '</a></h4>'
545 # dump the block C source lines now
548 for f
in self
.headers
.keys():
549 if block
.source
.filename
.find( f
) >= 0:
550 header
= self
.headers
[f
] + ' (' + f
+ ')'
554 # sys.stderr.write( \
555 # 'WARNING: No header macro for ' + block.source.filename + '.\n' )
558 print header_location_header
559 print 'Defined in ' + header
+ '.'
560 print header_location_footer
564 print self
.html_source_quote( l
, block
.name
)
567 def markup_enter( self
, markup
, block
):
568 if markup
.tag
== "description":
569 print description_header
571 print marker_header
+ markup
.tag
+ marker_inter
573 self
.print_html_markup( markup
)
575 def markup_exit( self
, markup
, block
):
576 if markup
.tag
== "description":
577 print description_footer
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" + \
586 def section_exit( self
, section
):
589 def section_dump_all( self
):
590 for section
in self
.sections
:
591 self
.section_dump( section
, self
.file_prefix
+ section
.name
+ '.html' )