home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Calibre / calibre-0.8.18.msi / file_262 / sgmllib.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-09-09  |  13.1 KB  |  525 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.7)
  3.  
  4. from warnings import warnpy3k
  5. warnpy3k('the sgmllib module has been removed in Python 3.0', stacklevel = 2)
  6. del warnpy3k
  7. import markupbase
  8. import re
  9. __all__ = [
  10.     'SGMLParser',
  11.     'SGMLParseError']
  12. interesting = re.compile('[&<]')
  13. incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|<([a-zA-Z][^<>]*|/([a-zA-Z][^<>]*)?|![^<>]*)?')
  14. entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
  15. charref = re.compile('&#([0-9]+)[^0-9]')
  16. starttagopen = re.compile('<[>a-zA-Z]')
  17. shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
  18. shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
  19. piclose = re.compile('>')
  20. endbracket = re.compile('[<>]')
  21. tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
  22. attrfind = re.compile('\\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\\s*=\\s*(\\\'[^\\\']*\\\'|"[^"]*"|[][\\-a-zA-Z0-9./,:;+*%?!&$\\(\\)_#=~\\\'"@]*))?')
  23.  
  24. class SGMLParseError(RuntimeError):
  25.     pass
  26.  
  27.  
  28. class SGMLParser(markupbase.ParserBase):
  29.     entity_or_charref = re.compile('&(?:([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+))(;?)')
  30.     
  31.     def __init__(self, verbose = 0):
  32.         self.verbose = verbose
  33.         self.reset()
  34.  
  35.     
  36.     def reset(self):
  37.         self._SGMLParser__starttag_text = None
  38.         self.rawdata = ''
  39.         self.stack = []
  40.         self.lasttag = '???'
  41.         self.nomoretags = 0
  42.         self.literal = 0
  43.         markupbase.ParserBase.reset(self)
  44.  
  45.     
  46.     def setnomoretags(self):
  47.         self.nomoretags = self.literal = 1
  48.  
  49.     
  50.     def setliteral(self, *args):
  51.         self.literal = 1
  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 SGMLParseError(message)
  65.  
  66.     
  67.     def goahead(self, end):
  68.         rawdata = self.rawdata
  69.         i = 0
  70.         n = len(rawdata)
  71.         while i < n:
  72.             if self.nomoretags:
  73.                 self.handle_data(rawdata[i:n])
  74.                 i = n
  75.                 break
  76.             match = interesting.search(rawdata, i)
  77.             if match:
  78.                 j = match.start()
  79.             else:
  80.                 j = n
  81.             if i < j:
  82.                 self.handle_data(rawdata[i:j])
  83.             i = j
  84.             if i == n:
  85.                 break
  86.             if rawdata[i] == '<':
  87.                 if starttagopen.match(rawdata, i):
  88.                     if self.literal:
  89.                         self.handle_data(rawdata[i])
  90.                         i = i + 1
  91.                         continue
  92.                     k = self.parse_starttag(i)
  93.                     if k < 0:
  94.                         break
  95.                     i = k
  96.                     continue
  97.                 if rawdata.startswith('</', i):
  98.                     k = self.parse_endtag(i)
  99.                     if k < 0:
  100.                         break
  101.                     i = k
  102.                     self.literal = 0
  103.                     continue
  104.                 if self.literal:
  105.                     if n > i + 1:
  106.                         self.handle_data('<')
  107.                         i = i + 1
  108.                         continue
  109.                     break
  110.                     continue
  111.                 if rawdata.startswith('<!--', i):
  112.                     k = self.parse_comment(i)
  113.                     if k < 0:
  114.                         break
  115.                     i = k
  116.                     continue
  117.                 if rawdata.startswith('<?', i):
  118.                     k = self.parse_pi(i)
  119.                     if k < 0:
  120.                         break
  121.                     i = i + k
  122.                     continue
  123.                 if rawdata.startswith('<!', i):
  124.                     k = self.parse_declaration(i)
  125.                     if k < 0:
  126.                         break
  127.                     i = k
  128.                     continue
  129.                 
  130.             elif rawdata[i] == '&':
  131.                 if self.literal:
  132.                     self.handle_data(rawdata[i])
  133.                     i = i + 1
  134.                     continue
  135.                 match = charref.match(rawdata, i)
  136.                 if match:
  137.                     name = match.group(1)
  138.                     self.handle_charref(name)
  139.                     i = match.end(0)
  140.                     if rawdata[i - 1] != ';':
  141.                         i = i - 1
  142.                         continue
  143.                         continue
  144.                 match = entityref.match(rawdata, i)
  145.                 if match:
  146.                     name = match.group(1)
  147.                     self.handle_entityref(name)
  148.                     i = match.end(0)
  149.                     if rawdata[i - 1] != ';':
  150.                         i = i - 1
  151.                         continue
  152.                         continue
  153.                     
  154.                 else:
  155.                     self.error('neither < nor & ??')
  156.             match = incomplete.match(rawdata, i)
  157.             if not match:
  158.                 self.handle_data(rawdata[i])
  159.                 i = i + 1
  160.                 continue
  161.             j = match.end(0)
  162.             if j == n:
  163.                 break
  164.             self.handle_data(rawdata[i:j])
  165.             i = j
  166.         if end and i < n:
  167.             self.handle_data(rawdata[i:n])
  168.             i = n
  169.         self.rawdata = rawdata[i:]
  170.  
  171.     _decl_otherchars = '='
  172.     
  173.     def parse_pi(self, i):
  174.         rawdata = self.rawdata
  175.         if rawdata[i:i + 2] != '<?':
  176.             self.error('unexpected call to parse_pi()')
  177.         match = piclose.search(rawdata, i + 2)
  178.         if not match:
  179.             return -1
  180.         j = None.start(0)
  181.         self.handle_pi(rawdata[i + 2:j])
  182.         j = match.end(0)
  183.         return j - i
  184.  
  185.     
  186.     def get_starttag_text(self):
  187.         return self._SGMLParser__starttag_text
  188.  
  189.     
  190.     def parse_starttag(self, i):
  191.         self._SGMLParser__starttag_text = None
  192.         start_pos = i
  193.         rawdata = self.rawdata
  194.         if shorttagopen.match(rawdata, i):
  195.             match = shorttag.match(rawdata, i)
  196.             if not match:
  197.                 return -1
  198.             (tag, data) = None.group(1, 2)
  199.             self._SGMLParser__starttag_text = '<%s/' % tag
  200.             tag = tag.lower()
  201.             k = match.end(0)
  202.             self.finish_shorttag(tag, data)
  203.             self._SGMLParser__starttag_text = rawdata[start_pos:match.end(1) + 1]
  204.             return k
  205.         match = None.search(rawdata, i + 1)
  206.         if not match:
  207.             return -1
  208.         j = None.start(0)
  209.         attrs = []
  210.         if rawdata[i:i + 2] == '<>':
  211.             k = j
  212.             tag = self.lasttag
  213.         else:
  214.             match = tagfind.match(rawdata, i + 1)
  215.             if not match:
  216.                 self.error('unexpected call to parse_starttag')
  217.             k = match.end(0)
  218.             tag = rawdata[i + 1:k].lower()
  219.             self.lasttag = tag
  220.         while k < j:
  221.             match = attrfind.match(rawdata, k)
  222.             if not match:
  223.                 break
  224.             (attrname, rest, attrvalue) = match.group(1, 2, 3)
  225.             if not rest:
  226.                 attrvalue = attrname
  227.             elif "'" == "'":
  228.                 pass
  229.             elif not "'" == "'" == attrvalue[-1:]:
  230.                 if '"' == '"':
  231.                     pass
  232.                 elif '"' == attrvalue[-1:]:
  233.                     attrvalue = attrvalue[1:-1]
  234.                 attrvalue = self.entity_or_charref.sub(self._convert_ref, attrvalue)
  235.                 attrs.append((attrname.lower(), attrvalue))
  236.                 k = match.end(0)
  237.             if rawdata[j] == '>':
  238.                 j = j + 1
  239.             self._SGMLParser__starttag_text = rawdata[start_pos:j]
  240.             self.finish_starttag(tag, attrs)
  241.             return j
  242.  
  243.     
  244.     def _convert_ref(self, match):
  245.         if match.group(2):
  246.             if not self.convert_charref(match.group(2)):
  247.                 pass
  248.             return '&#%s%s' % match.groups()[1:]
  249.         if None.group(3):
  250.             if not self.convert_entityref(match.group(1)):
  251.                 pass
  252.             return '&%s;' % match.group(1)
  253.         return None % match.group(1)
  254.  
  255.     
  256.     def parse_endtag(self, i):
  257.         rawdata = self.rawdata
  258.         match = endbracket.search(rawdata, i + 1)
  259.         if not match:
  260.             return -1
  261.         j = None.start(0)
  262.         tag = rawdata[i + 2:j].strip().lower()
  263.         if rawdata[j] == '>':
  264.             j = j + 1
  265.         self.finish_endtag(tag)
  266.         return j
  267.  
  268.     
  269.     def finish_shorttag(self, tag, data):
  270.         self.finish_starttag(tag, [])
  271.         self.handle_data(data)
  272.         self.finish_endtag(tag)
  273.  
  274.     
  275.     def finish_starttag(self, tag, attrs):
  276.         
  277.         try:
  278.             method = getattr(self, 'start_' + tag)
  279.         except AttributeError:
  280.             
  281.             try:
  282.                 method = getattr(self, 'do_' + tag)
  283.             except AttributeError:
  284.                 self.unknown_starttag(tag, attrs)
  285.                 return -1
  286.  
  287.             self.handle_starttag(tag, method, attrs)
  288.             return 0
  289.  
  290.         self.stack.append(tag)
  291.         self.handle_starttag(tag, method, attrs)
  292.         return 1
  293.  
  294.     
  295.     def finish_endtag(self, tag):
  296.         if not tag:
  297.             found = len(self.stack) - 1
  298.             if found < 0:
  299.                 self.unknown_endtag(tag)
  300.                 return None
  301.         if tag not in self.stack:
  302.             
  303.             try:
  304.                 method = getattr(self, 'end_' + tag)
  305.             except AttributeError:
  306.                 self.unknown_endtag(tag)
  307.  
  308.             self.report_unbalanced(tag)
  309.             return None
  310.         found = None(self.stack)
  311.         for i in range(found):
  312.             if self.stack[i] == tag:
  313.                 found = i
  314.                 continue
  315.         while len(self.stack) > found:
  316.             tag = self.stack[-1]
  317.             
  318.             try:
  319.                 method = getattr(self, 'end_' + tag)
  320.             except AttributeError:
  321.                 method = None
  322.  
  323.             if method:
  324.                 self.handle_endtag(tag, method)
  325.             else:
  326.                 self.unknown_endtag(tag)
  327.             del self.stack[-1]
  328.  
  329.     
  330.     def handle_starttag(self, tag, method, attrs):
  331.         method(attrs)
  332.  
  333.     
  334.     def handle_endtag(self, tag, method):
  335.         method()
  336.  
  337.     
  338.     def report_unbalanced(self, tag):
  339.         if self.verbose:
  340.             print '*** Unbalanced </' + tag + '>'
  341.             print '*** Stack:', self.stack
  342.  
  343.     
  344.     def convert_charref(self, name):
  345.         
  346.         try:
  347.             n = int(name)
  348.         except ValueError:
  349.             return None
  350.  
  351.         if n <= n:
  352.             pass
  353.         elif not n <= 127:
  354.             return None
  355.         return self.convert_codepoint(n)
  356.  
  357.     
  358.     def convert_codepoint(self, codepoint):
  359.         return chr(codepoint)
  360.  
  361.     
  362.     def handle_charref(self, name):
  363.         replacement = self.convert_charref(name)
  364.         if replacement is None:
  365.             self.unknown_charref(name)
  366.         else:
  367.             self.handle_data(replacement)
  368.  
  369.     entitydefs = {
  370.         'lt': '<',
  371.         'gt': '>',
  372.         'amp': '&',
  373.         'quot': '"',
  374.         'apos': "'" }
  375.     
  376.     def convert_entityref(self, name):
  377.         table = self.entitydefs
  378.         if name in table:
  379.             return table[name]
  380.         return None
  381.  
  382.     
  383.     def handle_entityref(self, name):
  384.         replacement = self.convert_entityref(name)
  385.         if replacement is None:
  386.             self.unknown_entityref(name)
  387.         else:
  388.             self.handle_data(replacement)
  389.  
  390.     
  391.     def handle_data(self, data):
  392.         pass
  393.  
  394.     
  395.     def handle_comment(self, data):
  396.         pass
  397.  
  398.     
  399.     def handle_decl(self, decl):
  400.         pass
  401.  
  402.     
  403.     def handle_pi(self, data):
  404.         pass
  405.  
  406.     
  407.     def unknown_starttag(self, tag, attrs):
  408.         pass
  409.  
  410.     
  411.     def unknown_endtag(self, tag):
  412.         pass
  413.  
  414.     
  415.     def unknown_charref(self, ref):
  416.         pass
  417.  
  418.     
  419.     def unknown_entityref(self, ref):
  420.         pass
  421.  
  422.  
  423.  
  424. class TestSGMLParser(SGMLParser):
  425.     
  426.     def __init__(self, verbose = 0):
  427.         self.testdata = ''
  428.         SGMLParser.__init__(self, verbose)
  429.  
  430.     
  431.     def handle_data(self, data):
  432.         self.testdata = self.testdata + data
  433.         if len(repr(self.testdata)) >= 70:
  434.             self.flush()
  435.  
  436.     
  437.     def flush(self):
  438.         data = self.testdata
  439.         if data:
  440.             self.testdata = ''
  441.             print 'data:', repr(data)
  442.  
  443.     
  444.     def handle_comment(self, data):
  445.         self.flush()
  446.         r = repr(data)
  447.         if len(r) > 68:
  448.             r = r[:32] + '...' + r[-32:]
  449.         print 'comment:', r
  450.  
  451.     
  452.     def unknown_starttag(self, tag, attrs):
  453.         self.flush()
  454.         if not attrs:
  455.             print 'start tag: <' + tag + '>'
  456.         else:
  457.             print 'start tag: <' + tag,
  458.             for name, value in attrs:
  459.                 print name + '=' + '"' + value + '"',
  460.             
  461.             print '>'
  462.  
  463.     
  464.     def unknown_endtag(self, tag):
  465.         self.flush()
  466.         print 'end tag: </' + tag + '>'
  467.  
  468.     
  469.     def unknown_entityref(self, ref):
  470.         self.flush()
  471.         print '*** unknown entity ref: &' + ref + ';'
  472.  
  473.     
  474.     def unknown_charref(self, ref):
  475.         self.flush()
  476.         print '*** unknown char ref: &#' + ref + ';'
  477.  
  478.     
  479.     def unknown_decl(self, data):
  480.         self.flush()
  481.         print '*** unknown decl: [' + data + ']'
  482.  
  483.     
  484.     def close(self):
  485.         SGMLParser.close(self)
  486.         self.flush()
  487.  
  488.  
  489.  
  490. def test(args = None):
  491.     import sys
  492.     if args is None:
  493.         args = sys.argv[1:]
  494.     if args and args[0] == '-s':
  495.         args = args[1:]
  496.         klass = SGMLParser
  497.     else:
  498.         klass = TestSGMLParser
  499.     if args:
  500.         file = args[0]
  501.     else:
  502.         file = 'test.html'
  503.     if file == '-':
  504.         f = sys.stdin
  505.     else:
  506.         
  507.         try:
  508.             f = open(file, 'r')
  509.         except IOError:
  510.             msg = None
  511.             print file, ':', msg
  512.             sys.exit(1)
  513.  
  514.     data = f.read()
  515.     if f is not sys.stdin:
  516.         f.close()
  517.     x = klass()
  518.     for c in data:
  519.         x.feed(c)
  520.     
  521.     x.close()
  522.  
  523. if __name__ == '__main__':
  524.     test()
  525.