home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / share / doc / diveintopython / examples / BaseHTMLProcessor.py < prev    next >
Encoding:
Python Source  |  2004-05-05  |  3.7 KB  |  94 lines

  1. """Base class for creating HTML processing modules
  2.  
  3. This class is designed to take HTML as input and spit out equivalent
  4. HTML as output.  By itself it's not very interesting; you use it by
  5. subclassing it and providing the methods you need to create your HTML
  6. transformation.
  7.  
  8. This program is part of "Dive Into Python", a free Python book for
  9. experienced programmers.  Visit http://diveintopython.org/ for the
  10. latest version.
  11. """
  12.  
  13. __author__ = "Mark Pilgrim (mark@diveintopython.org)"
  14. __version__ = "$Revision: 1.2 $"
  15. __date__ = "$Date: 2004/05/05 21:57:19 $"
  16. __copyright__ = "Copyright (c) 2001 Mark Pilgrim"
  17. __license__ = "Python"
  18.  
  19. from sgmllib import SGMLParser
  20. import htmlentitydefs
  21.  
  22. class BaseHTMLProcessor(SGMLParser):
  23.     def reset(self):
  24.         # extend (called by SGMLParser.__init__)
  25.         self.pieces = []
  26.         SGMLParser.reset(self)
  27.         
  28.     def unknown_starttag(self, tag, attrs):
  29.         # called for each start tag
  30.         # attrs is a list of (attr, value) tuples
  31.         # e.g. for <pre class="screen">, tag="pre", attrs=[("class", "screen")]
  32.         # Ideally we would like to reconstruct original tag and attributes, but
  33.         # we may end up quoting attribute values that weren't quoted in the source
  34.         # document, or we may change the type of quotes around the attribute value
  35.         # (single to double quotes).
  36.         # Note that improperly embedded non-HTML code (like client-side Javascript)
  37.         # may be parsed incorrectly by the ancestor, causing runtime script errors.
  38.         # All non-HTML code must be enclosed in HTML comment tags (<!-- code -->)
  39.         # to ensure that it will pass through this parser unaltered (in handle_comment).
  40.         strattrs = "".join([' %s="%s"' % (key, value) for key, value in attrs])
  41.         self.pieces.append("<%(tag)s%(strattrs)s>" % locals())
  42.         
  43.     def unknown_endtag(self, tag):
  44.         # called for each end tag, e.g. for </pre>, tag will be "pre"
  45.         # Reconstruct the original end tag.
  46.         self.pieces.append("</%(tag)s>" % locals())
  47.  
  48.     def handle_charref(self, ref):
  49.         # called for each character reference, e.g. for " ", ref will be "160"
  50.         # Reconstruct the original character reference.
  51.         self.pieces.append("&#%(ref)s;" % locals())
  52.         
  53.     def handle_entityref(self, ref):
  54.         # called for each entity reference, e.g. for "©", ref will be "copy"
  55.         # Reconstruct the original entity reference.
  56.         self.pieces.append("&%(ref)s" % locals())
  57.         # standard HTML entities are closed with a semicolon; other entities are not
  58.         if htmlentitydefs.entitydefs.has_key(ref):
  59.             self.pieces.append(";")
  60.  
  61.     def handle_data(self, text):
  62.         # called for each block of plain text, i.e. outside of any tag and
  63.         # not containing any character or entity references
  64.         # Store the original text verbatim.
  65.         self.pieces.append(text)
  66.         
  67.     def handle_comment(self, text):
  68.         # called for each HTML comment, e.g. <!-- insert Javascript code here -->
  69.         # Reconstruct the original comment.
  70.         # It is especially important that the source document enclose client-side
  71.         # code (like Javascript) within comments so it can pass through this
  72.         # processor undisturbed; see comments in unknown_starttag for details.
  73.         self.pieces.append("<!--%(text)s-->" % locals())
  74.         
  75.     def handle_pi(self, text):
  76.         # called for each processing instruction, e.g. <?instruction>
  77.         # Reconstruct original processing instruction.
  78.         self.pieces.append("<?%(text)s>" % locals())
  79.  
  80.     def handle_decl(self, text):
  81.         # called for the DOCTYPE, if present, e.g.
  82.         # <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  83.         #     "http://www.w3.org/TR/html4/loose.dtd">
  84.         # Reconstruct original DOCTYPE
  85.         self.pieces.append("<!%(text)s>" % locals())
  86.         
  87.     def output(self):
  88.         """Return processed HTML as a single string"""
  89.         return "".join(self.pieces)
  90.  
  91. if __name__ == "__main__":
  92.     for k, v in globals().items():
  93.         print k, "=", v
  94.