home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_1461 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  13.7 KB  |  563 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __version__ = '2.39'
  5. __author__ = 'Aaron Swartz (me@aaronsw.com)'
  6. __copyright__ = '(C) 2004-2008 Aaron Swartz. GNU GPL 3.'
  7. __contributors__ = [
  8.     "Martin 'Joey' Schulze",
  9.     'Ricardo Reyes',
  10.     'Kevin Jay North']
  11. if not hasattr(__builtins__, 'True'):
  12.     (True, False) = (1, 0)
  13.  
  14. import re
  15. import sys
  16. import urllib
  17. import htmlentitydefs
  18. import codecs
  19. import StringIO
  20. import types
  21. import sgmllib
  22. import urlparse
  23. sgmllib.charref = re.compile('&#([xX]?[0-9a-fA-F]+)[^0-9a-fA-F]')
  24.  
  25. try:
  26.     from textwrap import wrap
  27. except:
  28.     pass
  29.  
  30. UNICODE_SNOB = 0
  31. LINKS_EACH_PARAGRAPH = 0
  32. BODY_WIDTH = 78
  33. SKIP_INTERNAL_LINKS = False
  34.  
  35. def name2cp(k):
  36.     if k == 'apos':
  37.         return ord("'")
  38.     if hasattr(htmlentitydefs, 'name2codepoint'):
  39.         return htmlentitydefs.name2codepoint[k]
  40.     k = htmlentitydefs.entitydefs[k]
  41.     if k.startswith('&#') and k.endswith(';'):
  42.         return int(k[2:-1])
  43.     return ord(codecs.latin_1_decode(k)[0])
  44.  
  45. unifiable = {
  46.     'rsquo': "'",
  47.     'lsquo': "'",
  48.     'rdquo': '"',
  49.     'ldquo': '"',
  50.     'copy': '(C)',
  51.     'mdash': '--',
  52.     'nbsp': ' ',
  53.     'rarr': '->',
  54.     'larr': '<-',
  55.     'middot': '*',
  56.     'ndash': '-',
  57.     'oelig': 'oe',
  58.     'aelig': 'ae',
  59.     'agrave': 'a',
  60.     'aacute': 'a',
  61.     'acirc': 'a',
  62.     'atilde': 'a',
  63.     'auml': 'a',
  64.     'aring': 'a',
  65.     'egrave': 'e',
  66.     'eacute': 'e',
  67.     'ecirc': 'e',
  68.     'euml': 'e',
  69.     'igrave': 'i',
  70.     'iacute': 'i',
  71.     'icirc': 'i',
  72.     'iuml': 'i',
  73.     'ograve': 'o',
  74.     'oacute': 'o',
  75.     'ocirc': 'o',
  76.     'otilde': 'o',
  77.     'ouml': 'o',
  78.     'ugrave': 'u',
  79.     'uacute': 'u',
  80.     'ucirc': 'u',
  81.     'uuml': 'u' }
  82. unifiable_n = { }
  83. for k in unifiable.keys():
  84.     unifiable_n[name2cp(k)] = unifiable[k]
  85.  
  86.  
  87. def charref(name):
  88.     if name[0] in ('x', 'X'):
  89.         c = int(name[1:], 16)
  90.     else:
  91.         c = int(name)
  92.     if not UNICODE_SNOB and c in unifiable_n.keys():
  93.         return unifiable_n[c]
  94.     return unichr(c)
  95.  
  96.  
  97. def entityref(c):
  98.     if not UNICODE_SNOB and c in unifiable.keys():
  99.         return unifiable[c]
  100.     
  101.     try:
  102.         name2cp(c)
  103.     except KeyError:
  104.         c in unifiable.keys()
  105.         c in unifiable.keys()
  106.         return '&' + c
  107.  
  108.     return unichr(name2cp(c))
  109.  
  110.  
  111. def replaceEntities(s):
  112.     s = s.group(1)
  113.     if s[0] == '#':
  114.         return charref(s[1:])
  115.     return entityref(s)
  116.  
  117. r_unescape = re.compile('&(#?[xX]?(?:[0-9a-fA-F]+|\\w{1,8}));')
  118.  
  119. def unescape(s):
  120.     return r_unescape.sub(replaceEntities, s)
  121.  
  122.  
  123. def fixattrs(attrs):
  124.     if not attrs:
  125.         return attrs
  126.     newattrs = []
  127.     for attr in attrs:
  128.         newattrs.append((attr[0], unescape(attr[1])))
  129.     
  130.     return newattrs
  131.  
  132.  
  133. def onlywhite(line):
  134.     for c in line:
  135.         if c is not ' ' and c is not '  ':
  136.             return c is ' '
  137.     
  138.     return line
  139.  
  140.  
  141. def optwrap(text):
  142.     if not BODY_WIDTH:
  143.         return text
  144.     result = ''
  145.     newlines = 0
  146.     for para in text.split('\n'):
  147.         if len(para) > 0:
  148.             if para[0] is not ' ' and para[0] is not '-' and para[0] is not '*':
  149.                 for line in wrap(para, BODY_WIDTH):
  150.                     result += line + '\n'
  151.                 
  152.                 result += '\n'
  153.                 newlines = 2
  154.             elif not onlywhite(para):
  155.                 result += para + '\n'
  156.                 newlines = 1
  157.             
  158.         para[0] is not '*'
  159.         if newlines < 2:
  160.             result += '\n'
  161.             newlines += 1
  162.             continue
  163.         BODY_WIDTH
  164.     
  165.     return result
  166.  
  167.  
  168. def hn(tag):
  169.     if tag[0] == 'h' and len(tag) == 2:
  170.         
  171.         try:
  172.             n = int(tag[1])
  173.             if n in range(1, 10):
  174.                 return n
  175.         except ValueError:
  176.             return 0
  177.         
  178.  
  179.     None<EXCEPTION MATCH>ValueError
  180.  
  181.  
  182. class _html2text(sgmllib.SGMLParser):
  183.     
  184.     def __init__(self, out = None, baseurl = ''):
  185.         sgmllib.SGMLParser.__init__(self)
  186.         if out is None:
  187.             self.out = self.outtextf
  188.         else:
  189.             self.out = out
  190.         self.outtext = u''
  191.         self.quiet = 0
  192.         self.p_p = 0
  193.         self.outcount = 0
  194.         self.start = 1
  195.         self.space = 0
  196.         self.a = []
  197.         self.astack = []
  198.         self.acount = 0
  199.         self.list = []
  200.         self.blockquote = 0
  201.         self.pre = 0
  202.         self.startpre = 0
  203.         self.lastWasNL = 0
  204.         self.abbr_title = None
  205.         self.abbr_data = None
  206.         self.abbr_list = { }
  207.         self.baseurl = baseurl
  208.  
  209.     
  210.     def outtextf(self, s):
  211.         self.outtext += s
  212.  
  213.     
  214.     def close(self):
  215.         sgmllib.SGMLParser.close(self)
  216.         self.pbr()
  217.         self.o('', 0, 'end')
  218.         return self.outtext
  219.  
  220.     
  221.     def handle_charref(self, c):
  222.         self.o(charref(c))
  223.  
  224.     
  225.     def handle_entityref(self, c):
  226.         self.o(entityref(c))
  227.  
  228.     
  229.     def unknown_starttag(self, tag, attrs):
  230.         self.handle_tag(tag, attrs, 1)
  231.  
  232.     
  233.     def unknown_endtag(self, tag):
  234.         self.handle_tag(tag, None, 0)
  235.  
  236.     
  237.     def previousIndex(self, attrs):
  238.         if not attrs.has_key('href'):
  239.             return None
  240.         i = -1
  241.         for a in self.a:
  242.             i += 1
  243.             match = 0
  244.             if a.has_key('href') and a['href'] == attrs['href']:
  245.                 if a.has_key('title') or attrs.has_key('title'):
  246.                     if a.has_key('title') and attrs.has_key('title') and a['title'] == attrs['title']:
  247.                         match = True
  248.                     
  249.                 else:
  250.                     match = True
  251.             
  252.             if match:
  253.                 return i
  254.         
  255.  
  256.     
  257.     def handle_tag(self, tag, attrs, start):
  258.         attrs = fixattrs(attrs)
  259.         if hn(tag):
  260.             self.p()
  261.             if start:
  262.                 self.o(hn(tag) * '#' + ' ')
  263.             
  264.         
  265.         if tag in ('p', 'div'):
  266.             self.p()
  267.         
  268.         if tag == 'br' and start:
  269.             self.o('  \n')
  270.         
  271.         if tag == 'hr' and start:
  272.             self.p()
  273.             self.o('* * *')
  274.             self.p()
  275.         
  276.         if tag in ('head', 'style', 'script'):
  277.             if start:
  278.                 self.quiet += 1
  279.             else:
  280.                 self.quiet -= 1
  281.         
  282.         if tag in ('body',):
  283.             self.quiet = 0
  284.         
  285.         if tag == 'blockquote':
  286.             if start:
  287.                 self.p()
  288.                 self.o('> ', 0, 1)
  289.                 self.start = 1
  290.                 self.blockquote += 1
  291.             else:
  292.                 self.blockquote -= 1
  293.                 self.p()
  294.         
  295.         if tag in ('em', 'i', 'u'):
  296.             self.o('_')
  297.         
  298.         if tag in ('strong', 'b'):
  299.             self.o('**')
  300.         
  301.         if tag == 'code' and not (self.pre):
  302.             self.o('`')
  303.         
  304.         if tag == 'abbr':
  305.             if start:
  306.                 attrsD = { }
  307.                 for x, y in attrs:
  308.                     attrsD[x] = y
  309.                 
  310.                 attrs = attrsD
  311.                 self.abbr_title = None
  312.                 self.abbr_data = ''
  313.                 if attrs.has_key('title'):
  314.                     self.abbr_title = attrs['title']
  315.                 
  316.             elif self.abbr_title != None:
  317.                 self.abbr_list[self.abbr_data] = self.abbr_title
  318.                 self.abbr_title = None
  319.             
  320.             self.abbr_data = ''
  321.         
  322.         if tag == 'a':
  323.             if start:
  324.                 attrsD = { }
  325.                 for x, y in attrs:
  326.                     attrsD[x] = y
  327.                 
  328.                 attrs = attrsD
  329.                 if attrs.has_key('href'):
  330.                     if SKIP_INTERNAL_LINKS:
  331.                         pass
  332.                 None if not attrs['href'].startswith('#') else not attrs['href'].startswith('#')
  333.                 self.astack.append(None)
  334.             elif self.astack:
  335.                 a = self.astack.pop()
  336.                 if a:
  337.                     i = self.previousIndex(a)
  338.                     self.o('][' + `a['count']` + ']')
  339.                 
  340.             
  341.         
  342.         if tag == 'img' and start:
  343.             attrsD = { }
  344.             for x, y in attrs:
  345.                 attrsD[x] = y
  346.             
  347.             attrs = attrsD
  348.             if attrs.has_key('src'):
  349.                 attrs['href'] = attrs['src']
  350.                 alt = attrs.get('alt', '')
  351.                 i = self.previousIndex(attrs)
  352.                 self.o('![')
  353.                 self.o(alt)
  354.                 self.o('][' + `attrs['count']` + ']')
  355.             
  356.         
  357.         if tag == 'dl' and start:
  358.             self.p()
  359.         
  360.         if tag == 'dt' and not start:
  361.             self.pbr()
  362.         
  363.         if tag == 'dd' and start:
  364.             self.o('    ')
  365.         
  366.         if tag == 'dd' and not start:
  367.             self.pbr()
  368.         
  369.         if tag in ('ol', 'ul'):
  370.             if start:
  371.                 self.list.append({
  372.                     'name': tag,
  373.                     'num': 0 })
  374.             elif self.list:
  375.                 self.list.pop()
  376.             
  377.             self.p()
  378.         
  379.         if tag == 'li':
  380.             if start:
  381.                 self.pbr()
  382.                 if self.list:
  383.                     li = self.list[-1]
  384.                 else:
  385.                     li = {
  386.                         'name': 'ul',
  387.                         'num': 0 }
  388.                 self.o('  ' * len(self.list))
  389.                 if li['name'] == 'ul':
  390.                     self.o('* ')
  391.                 elif li['name'] == 'ol':
  392.                     li['num'] += 1
  393.                     self.o(`li['num']` + '. ')
  394.                 
  395.                 self.start = 1
  396.             else:
  397.                 self.pbr()
  398.         
  399.         if tag in ('table', 'tr') and start:
  400.             self.p()
  401.         
  402.         if tag == 'td':
  403.             self.pbr()
  404.         
  405.         if tag == 'pre':
  406.             if start:
  407.                 self.startpre = 1
  408.                 self.pre = 1
  409.             else:
  410.                 self.pre = 0
  411.             self.p()
  412.         
  413.  
  414.     
  415.     def pbr(self):
  416.         if self.p_p == 0:
  417.             self.p_p = 1
  418.         
  419.  
  420.     
  421.     def p(self):
  422.         self.p_p = 2
  423.  
  424.     
  425.     def o(self, data, puredata = 0, force = 0):
  426.         if self.abbr_data is not None:
  427.             self.abbr_data += data
  428.         
  429.         if not self.quiet:
  430.             if puredata and not (self.pre):
  431.                 data = re.sub('\\s+', ' ', data)
  432.                 if data and data[0] == ' ':
  433.                     self.space = 1
  434.                     data = data[1:]
  435.                 
  436.             
  437.             if not data and not force:
  438.                 return None
  439.             if self.startpre:
  440.                 self.startpre = 0
  441.             
  442.             bq = '>' * self.blockquote
  443.             if force and data:
  444.                 pass
  445.             if not (data[0] == '>') and self.blockquote:
  446.                 bq += ' '
  447.             
  448.             if self.pre:
  449.                 bq += '    '
  450.                 data = data.replace('\n', '\n' + bq)
  451.             
  452.             if self.start:
  453.                 self.space = 0
  454.                 self.p_p = 0
  455.                 self.start = 0
  456.             
  457.             if force == 'end':
  458.                 self.p_p = 0
  459.                 self.out('\n')
  460.                 self.space = 0
  461.             
  462.             if self.p_p:
  463.                 self.out(('\n' + bq) * self.p_p)
  464.                 self.space = 0
  465.             
  466.             if self.space:
  467.                 if not self.lastWasNL:
  468.                     self.out(' ')
  469.                 
  470.                 self.space = 0
  471.             
  472.             if self.a:
  473.                 if self.p_p == 2 or LINKS_EACH_PARAGRAPH or force == 'end':
  474.                     if force == 'end':
  475.                         self.out('\n')
  476.                     
  477.                     newa = []
  478.                     for link in self.a:
  479.                         if self.outcount > link['outcount']:
  480.                             self.out('   [' + `link['count']` + ']: ' + urlparse.urljoin(self.baseurl, link['href']))
  481.                             if link.has_key('title'):
  482.                                 self.out(' (' + link['title'] + ')')
  483.                             
  484.                             self.out('\n')
  485.                             continue
  486.                         newa.append(link)
  487.                     
  488.                     if self.a != newa:
  489.                         self.out('\n')
  490.                     
  491.                     self.a = newa
  492.                 
  493.             if self.abbr_list and force == 'end':
  494.                 for abbr, definition in self.abbr_list.items():
  495.                     self.out('  *[' + abbr + ']: ' + definition + '\n')
  496.                 
  497.             
  498.             self.p_p = 0
  499.             self.out(data)
  500.             if data:
  501.                 pass
  502.             self.lastWasNL = data[-1] == '\n'
  503.             self.outcount += 1
  504.         
  505.  
  506.     
  507.     def handle_data(self, data):
  508.         if '\\/script>' in data:
  509.             self.quiet -= 1
  510.         
  511.         self.o(data, 1)
  512.  
  513.     
  514.     def unknown_decl(self, data):
  515.         pass
  516.  
  517.  
  518.  
  519. def wrapwrite(text):
  520.     sys.stdout.write(text.encode('utf8'))
  521.  
  522.  
  523. def html2text_file(html, out = wrapwrite, baseurl = ''):
  524.     h = _html2text(out, baseurl)
  525.     h.feed(html)
  526.     h.feed('')
  527.     return h.close()
  528.  
  529.  
  530. def html2text(html, baseurl = ''):
  531.     return optwrap(html2text_file(html, None, baseurl))
  532.  
  533. if __name__ == '__main__':
  534.     baseurl = ''
  535.     if sys.argv[1:]:
  536.         arg = sys.argv[1]
  537.         if arg.startswith('http://') or arg.startswith('https://'):
  538.             baseurl = arg
  539.             j = urllib.urlopen(baseurl)
  540.             
  541.             try:
  542.                 from feedparser import _getCharacterEncoding as enc
  543.             except ImportError:
  544.                 
  545.                 enc = lambda x, y: ('utf-8', 1)
  546.  
  547.             text = j.read()
  548.             encoding = enc(j.headers, text)[0]
  549.             if encoding == 'us-ascii':
  550.                 encoding = 'utf-8'
  551.             
  552.             data = text.decode(encoding)
  553.         else:
  554.             encoding = 'utf8'
  555.             if len(sys.argv) > 2:
  556.                 encoding = sys.argv[2]
  557.             
  558.             data = open(arg, 'r').read().decode(encoding)
  559.     else:
  560.         data = sys.stdin.read().decode('utf8')
  561.     wrapwrite(html2text(data, baseurl))
  562.  
  563.