home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_598 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  9.9 KB  |  316 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import markupbase
  5. import re
  6. interesting_normal = re.compile('[&<]')
  7. interesting_cdata = re.compile('<(/|\\Z)')
  8. incomplete = re.compile('&[a-zA-Z#]')
  9. entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
  10. charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]')
  11. starttagopen = re.compile('<[a-zA-Z]')
  12. piclose = re.compile('>')
  13. commentclose = re.compile('--\\s*>')
  14. tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*')
  15. attrfind = re.compile('\\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\\s*=\\s*(\\\'[^\\\']*\\\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\\(\\)_#=~@]*))?')
  16. locatestarttagend = re.compile('\n  <[a-zA-Z][-.a-zA-Z0-9:_]*          # tag name\n  (?:\\s+                             # whitespace before attribute name\n    (?:[a-zA-Z_][-.:a-zA-Z0-9_]*     # attribute name\n      (?:\\s*=\\s*                     # value indicator\n        (?:\'[^\']*\'                   # LITA-enclosed value\n          |\\"[^\\"]*\\"                # LIT-enclosed value\n          |[^\'\\">\\s]+                # bare value\n         )\n       )?\n     )\n   )*\n  \\s*                                # trailing whitespace\n', re.VERBOSE)
  17. endendtag = re.compile('>')
  18. endtagfind = re.compile('</\\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\\s*>')
  19.  
  20. class HTMLParseError(Exception):
  21.     
  22.     def __init__(self, msg, position = (None, None)):
  23.         self.msg = msg
  24.         self.lineno = position[0]
  25.         self.offset = position[1]
  26.  
  27.     
  28.     def __str__(self):
  29.         result = self.msg
  30.         if self.lineno is not None:
  31.             result = result + ', at line %d' % self.lineno
  32.         
  33.         if self.offset is not None:
  34.             result = result + ', column %d' % (self.offset + 1)
  35.         
  36.         return result
  37.  
  38.  
  39.  
  40. class HTMLParser(markupbase.ParserBase):
  41.     CDATA_CONTENT_ELEMENTS = ('script', 'style')
  42.     
  43.     def __init__(self):
  44.         self.reset()
  45.  
  46.     
  47.     def reset(self):
  48.         self.rawdata = ''
  49.         self.lasttag = '???'
  50.         self.interesting = interesting_normal
  51.         markupbase.ParserBase.reset(self)
  52.  
  53.     
  54.     def feed(self, data):
  55.         self.rawdata = self.rawdata + data
  56.         self.goahead(0)
  57.  
  58.     
  59.     def close(self):
  60.         self.goahead(1)
  61.  
  62.     
  63.     def error(self, message):
  64.         raise HTMLParseError(message, self.getpos())
  65.  
  66.     __starttag_text = None
  67.     
  68.     def get_starttag_text(self):
  69.         return self._HTMLParser__starttag_text
  70.  
  71.     
  72.     def set_cdata_mode(self):
  73.         self.interesting = interesting_cdata
  74.  
  75.     
  76.     def clear_cdata_mode(self):
  77.         self.interesting = interesting_normal
  78.  
  79.     
  80.     def goahead(self, end):
  81.         rawdata = self.rawdata
  82.         i = 0
  83.         n = len(rawdata)
  84.         while i < n:
  85.             match = self.interesting.search(rawdata, i)
  86.             if match:
  87.                 j = match.start()
  88.             else:
  89.                 j = n
  90.             if i < j:
  91.                 self.handle_data(rawdata[i:j])
  92.             
  93.             i = self.updatepos(i, j)
  94.             if i == n:
  95.                 break
  96.             
  97.             startswith = rawdata.startswith
  98.             if startswith('<', i):
  99.                 if starttagopen.match(rawdata, i):
  100.                     k = self.parse_starttag(i)
  101.                 elif startswith('</', i):
  102.                     k = self.parse_endtag(i)
  103.                 elif startswith('<!--', i):
  104.                     k = self.parse_comment(i)
  105.                 elif startswith('<?', i):
  106.                     k = self.parse_pi(i)
  107.                 elif startswith('<!', i):
  108.                     k = self.parse_declaration(i)
  109.                 elif i + 1 < n:
  110.                     self.handle_data('<')
  111.                     k = i + 1
  112.                 else:
  113.                     break
  114.                 if k < 0:
  115.                     if end:
  116.                         self.error('EOF in middle of construct')
  117.                     
  118.                     break
  119.                 
  120.                 i = self.updatepos(i, k)
  121.                 continue
  122.             if startswith('&#', i):
  123.                 match = charref.match(rawdata, i)
  124.                 if match:
  125.                     name = match.group()[2:-1]
  126.                     self.handle_charref(name)
  127.                     k = match.end()
  128.                     if not startswith(';', k - 1):
  129.                         k = k - 1
  130.                     
  131.                     i = self.updatepos(i, k)
  132.                     continue
  133.                 else:
  134.                     break
  135.             match
  136.             if startswith('&', i):
  137.                 match = entityref.match(rawdata, i)
  138.                 if match:
  139.                     name = match.group(1)
  140.                     self.handle_entityref(name)
  141.                     k = match.end()
  142.                     if not startswith(';', k - 1):
  143.                         k = k - 1
  144.                     
  145.                     i = self.updatepos(i, k)
  146.                     continue
  147.                 
  148.                 match = incomplete.match(rawdata, i)
  149.                 if match:
  150.                     if end and match.group() == rawdata[i:]:
  151.                         self.error('EOF in middle of entity or char ref')
  152.                     
  153.                     break
  154.                 elif i + 1 < n:
  155.                     self.handle_data('&')
  156.                     i = self.updatepos(i, i + 1)
  157.                 else:
  158.                     break
  159.             match
  160.         if end and i < n:
  161.             self.handle_data(rawdata[i:n])
  162.             i = self.updatepos(i, n)
  163.         
  164.         self.rawdata = rawdata[i:]
  165.  
  166.     
  167.     def parse_pi(self, i):
  168.         rawdata = self.rawdata
  169.         match = piclose.search(rawdata, i + 2)
  170.         if not match:
  171.             return -1
  172.         j = match.start()
  173.         self.handle_pi(rawdata[i + 2:j])
  174.         j = match.end()
  175.         return j
  176.  
  177.     
  178.     def parse_starttag(self, i):
  179.         self._HTMLParser__starttag_text = None
  180.         endpos = self.check_for_whole_start_tag(i)
  181.         if endpos < 0:
  182.             return endpos
  183.         rawdata = self.rawdata
  184.         self._HTMLParser__starttag_text = rawdata[i:endpos]
  185.         attrs = []
  186.         match = tagfind.match(rawdata, i + 1)
  187.         k = match.end()
  188.         while k < endpos:
  189.             m = attrfind.match(rawdata, k)
  190.             (attrname, rest, attrvalue) = m.group(1, 2, 3)
  191.             if not rest:
  192.                 attrvalue = None
  193.             elif "'" == "'":
  194.                 pass
  195.             elif not "'" == attrvalue[-1:]:
  196.                 if '"' == '"':
  197.                     pass
  198.                 elif '"' == attrvalue[-1:]:
  199.                     attrvalue = attrvalue[1:-1]
  200.                     attrvalue = self.unescape(attrvalue)
  201.                 
  202.             attrs.append((attrname.lower(), attrvalue))
  203.             k = m.end()
  204.             continue
  205.             attrvalue[:1]
  206.         end = rawdata[k:endpos].strip()
  207.         if end not in ('>', '/>'):
  208.             (lineno, offset) = self.getpos()
  209.             if '\n' in self._HTMLParser__starttag_text:
  210.                 lineno = lineno + self._HTMLParser__starttag_text.count('\n')
  211.                 offset = len(self._HTMLParser__starttag_text) - self._HTMLParser__starttag_text.rfind('\n')
  212.             else:
  213.                 offset = offset + len(self._HTMLParser__starttag_text)
  214.             self.error('junk characters in start tag: %r' % (rawdata[k:endpos][:20],))
  215.         
  216.         if end.endswith('/>'):
  217.             self.handle_startendtag(tag, attrs)
  218.         else:
  219.             self.handle_starttag(tag, attrs)
  220.             if tag in self.CDATA_CONTENT_ELEMENTS:
  221.                 self.set_cdata_mode()
  222.             
  223.         return endpos
  224.  
  225.     
  226.     def check_for_whole_start_tag(self, i):
  227.         rawdata = self.rawdata
  228.         m = locatestarttagend.match(rawdata, i)
  229.         raise AssertionError('we should not get here!')
  230.  
  231.     
  232.     def parse_endtag(self, i):
  233.         rawdata = self.rawdata
  234.         match = endendtag.search(rawdata, i + 1)
  235.         if not match:
  236.             return -1
  237.         j = match.end()
  238.         match = endtagfind.match(rawdata, i)
  239.         if not match:
  240.             self.error('bad end tag: %r' % (rawdata[i:j],))
  241.         
  242.         tag = match.group(1)
  243.         self.handle_endtag(tag.lower())
  244.         self.clear_cdata_mode()
  245.         return j
  246.  
  247.     
  248.     def handle_startendtag(self, tag, attrs):
  249.         self.handle_starttag(tag, attrs)
  250.         self.handle_endtag(tag)
  251.  
  252.     
  253.     def handle_starttag(self, tag, attrs):
  254.         pass
  255.  
  256.     
  257.     def handle_endtag(self, tag):
  258.         pass
  259.  
  260.     
  261.     def handle_charref(self, name):
  262.         pass
  263.  
  264.     
  265.     def handle_entityref(self, name):
  266.         pass
  267.  
  268.     
  269.     def handle_data(self, data):
  270.         pass
  271.  
  272.     
  273.     def handle_comment(self, data):
  274.         pass
  275.  
  276.     
  277.     def handle_decl(self, decl):
  278.         pass
  279.  
  280.     
  281.     def handle_pi(self, data):
  282.         pass
  283.  
  284.     
  285.     def unknown_decl(self, data):
  286.         self.error('unknown declaration: %r' % (data,))
  287.  
  288.     entitydefs = None
  289.     
  290.     def unescape(self, s):
  291.         if '&' not in s:
  292.             return s
  293.         
  294.         def replaceEntities(s):
  295.             s = s.groups()[0]
  296.             if s[0] == '#':
  297.                 s = s[1:]
  298.                 if s[0] in ('x', 'X'):
  299.                     c = int(s[1:], 16)
  300.                 else:
  301.                     c = int(s)
  302.                 return unichr(c)
  303.             import htmlentitydefs
  304.             
  305.             try:
  306.                 return self.entitydefs[s]
  307.             except KeyError:
  308.                 None if HTMLParser.entitydefs is None else s[0] == '#'
  309.                 None if HTMLParser.entitydefs is None else s[0] == '#'
  310.                 return '&' + s + ';'
  311.  
  312.  
  313.         return re.sub('&(#?[xX]?(?:[0-9a-fA-F]+|\\w{1,8}));', replaceEntities, s)
  314.  
  315.  
  316.