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

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL 3'
  5. __copyright__ = '2009, John Schember <john@nachtimwald.com>'
  6. __docformat__ = 'restructuredtext en'
  7. import os
  8. import re
  9.  
  10. try:
  11.     from PIL import Image
  12.     Image
  13. except ImportError:
  14.     import Image
  15.  
  16. import cStringIO
  17. from lxml import etree
  18. from calibre.ebooks.oeb.base import XHTML, XHTML_NS, barename, namespace, OEB_RASTER_IMAGES
  19. from calibre.ebooks.oeb.stylizer import Stylizer
  20. from calibre.ebooks.metadata import authors_to_string
  21. from calibre.utils.filenames import ascii_text
  22. TAGS = {
  23.     'b': '\\b',
  24.     'del': '\\deleted',
  25.     'h1': '\\b \\par \\pard \\hyphpar',
  26.     'h2': '\\b \\par \\pard \\hyphpar',
  27.     'h3': '\\b \\par \\pard \\hyphpar',
  28.     'h4': '\\b \\par \\pard \\hyphpar',
  29.     'h5': '\\b \\par \\pard \\hyphpar',
  30.     'h6': '\\b \\par \\pard \\hyphpar',
  31.     'li': '\\par \\pard \\hyphpar \t',
  32.     'p': '\\par \\pard \\hyphpar \t',
  33.     'sub': '\\sub',
  34.     'sup': '\\super',
  35.     'u': '\\ul' }
  36. SINGLE_TAGS = {
  37.     'br': '\n{\\line }\n',
  38.     'div': '\n{\\line }\n' }
  39. SINGLE_TAGS_END = {
  40.     'div': '\n{\\line }\n' }
  41. STYLES = [
  42.     ('display', {
  43.         'block': '\\par \\pard \\hyphpar' }),
  44.     ('font-weight', {
  45.         'bold': '\\b',
  46.         'bolder': '\\b' }),
  47.     ('font-style', {
  48.         'italic': '\\i' }),
  49.     ('text-align', {
  50.         'center': '\\qc',
  51.         'left': '\\ql',
  52.         'right': '\\qr' }),
  53.     ('text-decoration', {
  54.         'line-through': '\\strike',
  55.         'underline': '\\ul' })]
  56. BLOCK_TAGS = [
  57.     'p',
  58.     'h1',
  59.     'h2',
  60.     'h3',
  61.     'h4',
  62.     'h5',
  63.     'h6',
  64.     'li']
  65. BLOCK_STYLES = [
  66.     'block']
  67.  
  68. def txt2rtf(text):
  69.     if not isinstance(text, unicode):
  70.         return text
  71.     buf = cStringIO.StringIO()
  72.     for x in text:
  73.         val = ord(x)
  74.         if val <= 127:
  75.             buf.write(x)
  76.             continue
  77.         isinstance(text, unicode)
  78.         repl = ascii_text(x)
  79.         c = '\\uc{2}\\u{0:d}{1}'.format(val, repl, len(repl))
  80.         buf.write(c)
  81.     
  82.     return buf.getvalue()
  83.  
  84.  
  85. class RTFMLizer(object):
  86.     
  87.     def __init__(self, log):
  88.         self.log = log
  89.  
  90.     
  91.     def extract_content(self, oeb_book, opts):
  92.         self.log.info('Converting XHTML to RTF markup...')
  93.         self.oeb_book = oeb_book
  94.         self.opts = opts
  95.         return self.mlize_spine()
  96.  
  97.     
  98.     def mlize_spine(self):
  99.         output = self.header()
  100.         if 'titlepage' in self.oeb_book.guide:
  101.             href = self.oeb_book.guide['titlepage'].href
  102.             item = self.oeb_book.manifest.hrefs[href]
  103.             if item.spine_position is None:
  104.                 stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts, self.opts.output_profile)
  105.                 output += self.dump_text(item.data.find(XHTML('body')), stylizer)
  106.                 output += '{\\page } '
  107.             
  108.         
  109.         for item in self.oeb_book.spine:
  110.             self.log.debug('Converting %s to RTF markup...' % item.href)
  111.             content = unicode(etree.tostring(item.data, encoding = unicode))
  112.             content = self.remove_newlines(content)
  113.             content = etree.fromstring(content)
  114.             stylizer = Stylizer(content, item.href, self.oeb_book, self.opts, self.opts.output_profile)
  115.             output += self.dump_text(content.find(XHTML('body')), stylizer)
  116.         
  117.         output += self.footer()
  118.         output = self.insert_images(output)
  119.         output = self.clean_text(output)
  120.         return output
  121.  
  122.     
  123.     def remove_newlines(self, text):
  124.         self.log.debug('\tRemove newlines for processing...')
  125.         text = text.replace('\r\n', ' ')
  126.         text = text.replace('\n', ' ')
  127.         text = text.replace('\r', ' ')
  128.         return text
  129.  
  130.     
  131.     def header(self):
  132.         return authors_to_string % ([], []([ x.value for x in self.oeb_book.metadata.creator ]))
  133.  
  134.     
  135.     def footer(self):
  136.         return ' }'
  137.  
  138.     
  139.     def insert_images(self, text):
  140.         for item in self.oeb_book.manifest:
  141.             if item.media_type in OEB_RASTER_IMAGES:
  142.                 src = os.path.basename(item.href)
  143.                 (data, width, height) = self.image_to_hexstring(item.data)
  144.                 text = text.replace('SPECIAL_IMAGE-%s-REPLACE_ME' % src, '\n\n{\\*\\shppict{\\pict\\picw%i\\pich%i\\jpegblip \n%s\n}}\n\n' % (width, height, data))
  145.                 continue
  146.         
  147.         return text
  148.  
  149.     
  150.     def image_to_hexstring(self, data):
  151.         im = Image.open(cStringIO.StringIO(data))
  152.         data = cStringIO.StringIO()
  153.         im.convert('RGB').save(data, 'JPEG')
  154.         data = data.getvalue()
  155.         raw_hex = ''
  156.         for char in data:
  157.             raw_hex += hex(ord(char)).replace('0x', '').rjust(2, '0')
  158.         
  159.         hex_string = ''
  160.         col = 1
  161.         for char in raw_hex:
  162.             if col == 129:
  163.                 hex_string += '\n'
  164.                 col = 1
  165.             
  166.             col += 1
  167.             hex_string += char
  168.         
  169.         return (hex_string, im.size[0], im.size[1])
  170.  
  171.     
  172.     def clean_text(self, text):
  173.         text = re.sub('(?m)^[ ]+', '', text)
  174.         text = re.sub('(?m)[ ]+$', '', text)
  175.         text = re.sub('%s{3,}' % os.linesep, '%s%s' % (os.linesep, os.linesep), text)
  176.         text = re.sub('[ ]{2,}', ' ', text)
  177.         text = re.sub('(\\{\\\\line \\}\\s*){3,}', '{\\\\line }{\\\\line }', text)
  178.         text = text.replace(u'┬á', ' ')
  179.         text = text.replace('\n\r', '\n')
  180.         return text
  181.  
  182.     
  183.     def dump_text(self, elem, stylizer, tag_stack = []):
  184.         if not isinstance(elem.tag, basestring) or namespace(elem.tag) != XHTML_NS:
  185.             return u''
  186.         text = u''
  187.         style = stylizer.style(elem)
  188.         if style['display'] in ('none', 'oeb-page-head', 'oeb-page-foot') or style['visibility'] == 'hidden':
  189.             return u''
  190.         tag = barename(elem.tag)
  191.         tag_count = 0
  192.         single_tag = SINGLE_TAGS.get(tag, None)
  193.         if single_tag:
  194.             text += single_tag
  195.         
  196.         rtf_tag = TAGS.get(tag, None)
  197.         if rtf_tag and rtf_tag not in tag_stack:
  198.             tag_count += 1
  199.             text += '{%s\n' % rtf_tag
  200.             tag_stack.append(rtf_tag)
  201.         
  202.         for s in STYLES:
  203.             style_tag = s[1].get(style[s[0]], None)
  204.             if style_tag and style_tag not in tag_stack:
  205.                 tag_count += 1
  206.                 text += '{%s\n' % style_tag
  207.                 tag_stack.append(style_tag)
  208.                 continue
  209.         
  210.         if hasattr(elem, 'text') and elem.text != None and elem.text.strip() != '':
  211.             text += txt2rtf(elem.text)
  212.         
  213.         for item in elem:
  214.             text += self.dump_text(item, stylizer, tag_stack)
  215.         
  216.         for i in range(0, tag_count):
  217.             end_tag = tag_stack.pop()
  218.             if end_tag != 'block':
  219.                 text += u'}'
  220.                 continue
  221.         
  222.         single_tag_end = SINGLE_TAGS_END.get(tag, None)
  223.         if single_tag_end:
  224.             text += single_tag_end
  225.         
  226.         if hasattr(elem, 'tail') and elem.tail != None and elem.tail.strip() != '':
  227.             if 'block' in tag_stack:
  228.                 text += '%s ' % txt2rtf(elem.tail)
  229.             else:
  230.                 text += '{\\par \\pard \\hyphpar %s}' % txt2rtf(elem.tail)
  231.         
  232.         return text
  233.  
  234.  
  235.