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