zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
tohtml.py
Go to the documentation of this file.
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 
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
def html_quote
Definition: tohtml.py:171
def html_quote0
Definition: tohtml.py:179
def print_html_field_list
Definition: tohtml.py:364
def dump_html_code
Definition: tohtml.py:183