home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1067 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  8.8 KB  |  280 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 re
  8. from calibre.ebooks.oeb.base import XHTML, XHTML_NS, barename, namespace
  9. from calibre.ebooks.oeb.stylizer import Stylizer
  10. from calibre.ebooks.pdb.ereader import image_name
  11. from calibre.ebooks.pml import unipmlcode
  12. TAG_MAP = {
  13.     'b': 'B',
  14.     'strong': 'B',
  15.     'i': 'i',
  16.     'small': 'k',
  17.     'sub': 'Sb',
  18.     'sup': 'Sp',
  19.     'big': 'l',
  20.     'del': 'o',
  21.     'h1': 'x',
  22.     'h2': 'X0',
  23.     'h3': 'X1',
  24.     'h4': 'X2',
  25.     'h5': 'X3',
  26.     'h6': 'X4',
  27.     '!--': 'v' }
  28. STYLES = [
  29.     ('font-weight', {
  30.         'bold': 'B',
  31.         'bolder': 'B' }),
  32.     ('font-style', {
  33.         'italic': 'i' }),
  34.     ('text-decoration', {
  35.         'underline': 'u' }),
  36.     ('text-align', {
  37.         'right': 'r',
  38.         'center': 'c' })]
  39. BLOCK_TAGS = [
  40.     'p',
  41.     'div']
  42. BLOCK_STYLES = [
  43.     'block']
  44. LINK_TAGS = [
  45.     'a']
  46. IMAGE_TAGS = [
  47.     'img']
  48. SEPARATE_TAGS = [
  49.     'h1',
  50.     'h2',
  51.     'h3',
  52.     'h4',
  53.     'h5',
  54.     'h6',
  55.     'p',
  56.     'div',
  57.     'li',
  58.     'tr']
  59.  
  60. class PMLMLizer(object):
  61.     
  62.     def __init__(self, log):
  63.         self.log = log
  64.         self.image_hrefs = { }
  65.         self.link_hrefs = { }
  66.  
  67.     
  68.     def extract_content(self, oeb_book, opts):
  69.         self.log.info('Converting XHTML to PML markup...')
  70.         self.oeb_book = oeb_book
  71.         self.opts = opts
  72.         self.toc = { }
  73.         for item in oeb_book.toc:
  74.             (href, mid, id) = item.href.partition('#')
  75.             self.get_anchor_id(href, id)
  76.             if not self.toc.get(href, None):
  77.                 self.toc[href] = { }
  78.             
  79.             self.toc[href][id] = item.title
  80.         
  81.         return self.pmlmlize_spine()
  82.  
  83.     
  84.     def pmlmlize_spine(self):
  85.         self.image_hrefs = { }
  86.         self.link_hrefs = { }
  87.         output = [
  88.             u'']
  89.         output.append(self.get_cover_page())
  90.         output.append(self.get_text())
  91.         output = ''.join(output)
  92.         output = self.clean_text(output)
  93.         return output
  94.  
  95.     
  96.     def get_cover_page(self):
  97.         output = u''
  98.         if 'cover' in self.oeb_book.guide:
  99.             output += '\\m="cover.png"\n'
  100.             self.image_hrefs[self.oeb_book.guide['cover'].href] = 'cover.png'
  101.         
  102.         if 'titlepage' in self.oeb_book.guide:
  103.             self.log.debug('Generating title page...')
  104.             href = self.oeb_book.guide['titlepage'].href
  105.             item = self.oeb_book.manifest.hrefs[href]
  106.             if item.spine_position is None:
  107.                 stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts, self.opts.output_profile)
  108.                 output += ''.join(self.dump_text(item.data.find(XHTML('body')), stylizer, item))
  109.             
  110.         
  111.         return output
  112.  
  113.     
  114.     def get_text(self):
  115.         text = [
  116.             u'']
  117.         for item in self.oeb_book.spine:
  118.             self.log.debug('Converting %s to PML markup...' % item.href)
  119.             stylizer = Stylizer(item.data, item.href, self.oeb_book, self.opts, self.opts.output_profile)
  120.             text.append(self.add_page_anchor(item))
  121.             text += self.dump_text(item.data.find(XHTML('body')), stylizer, item)
  122.         
  123.         return ''.join(text)
  124.  
  125.     
  126.     def add_page_anchor(self, page):
  127.         return self.get_anchor(page, '')
  128.  
  129.     
  130.     def get_anchor_id(self, href, aid):
  131.         aid = '%s#%s' % (href, aid)
  132.         if aid not in self.link_hrefs.keys():
  133.             self.link_hrefs[aid] = 'calibre_link-%s' % len(self.link_hrefs.keys())
  134.         
  135.         aid = self.link_hrefs[aid]
  136.         return aid
  137.  
  138.     
  139.     def get_anchor(self, page, aid):
  140.         aid = self.get_anchor_id(page.href, aid)
  141.         return u'\\Q="%s"' % aid
  142.  
  143.     
  144.     def remove_newlines(self, text):
  145.         text = text.replace('\r\n', ' ')
  146.         text = text.replace('\n', ' ')
  147.         text = text.replace('\r', ' ')
  148.         return text
  149.  
  150.     
  151.     def clean_text(self, text):
  152.         text = re.sub('\\\\p\\s*\\\\p', '', text)
  153.         anchors = set(re.findall('(?<=\\\\Q=").+?(?=")', text))
  154.         links = set(re.findall('(?<=\\\\q="#).+?(?=")', text))
  155.         for unused in anchors.difference(links):
  156.             text = text.replace('\\Q="%s"' % unused, '')
  157.         
  158.         text = text.replace(u'├é', '')
  159.         text = text.replace(u'┬á', ' ')
  160.         text = re.sub('[^\x00-\x7f]', (lambda x: unipmlcode(x.group())), text)
  161.         text = re.sub('(?m)^[ ]+', '', text)
  162.         text = re.sub('(?m)[ ]+$', '', text)
  163.         text = re.sub('[ ]{2,}', ' ', text)
  164.         text = re.sub('\n[ ]+\n', '\n\n', text)
  165.         if self.opts.remove_paragraph_spacing:
  166.             text = re.sub('\n{2,}', '\n', text)
  167.             text = re.sub('(?imu)^(?P<text>.+)$', (lambda mo: if re.search('\\\\[XxCm]', mo.group('text')):
  168. mo.group('text')'    %s' % mo.group('text')), text)
  169.         else:
  170.             text = re.sub('\n{3,}', '\n\n', text)
  171.         return text
  172.  
  173.     
  174.     def dump_text(self, elem, stylizer, page, tag_stack = []):
  175.         if not isinstance(elem.tag, basestring) or namespace(elem.tag) != XHTML_NS:
  176.             return []
  177.         text = []
  178.         tags = []
  179.         style = stylizer.style(elem)
  180.         if style['display'] in ('none', 'oeb-page-head', 'oeb-page-foot') or style['visibility'] == 'hidden':
  181.             return []
  182.         tag = barename(elem.tag)
  183.         if tag in IMAGE_TAGS:
  184.             if elem.attrib.get('src', None):
  185.                 if page.abshref(elem.attrib['src']) not in self.image_hrefs.keys():
  186.                     if len(self.image_hrefs.keys()) == 0:
  187.                         self.image_hrefs[page.abshref(elem.attrib['src'])] = 'cover.png'
  188.                     else:
  189.                         self.image_hrefs[page.abshref(elem.attrib['src'])] = image_name('%s.png' % len(self.image_hrefs.keys()), self.image_hrefs.keys()).strip('\x00')
  190.                 
  191.                 text.append('\\m="%s"' % self.image_hrefs[page.abshref(elem.attrib['src'])])
  192.             
  193.         
  194.         if tag == 'hr':
  195.             w = '\\w'
  196.             width = elem.get('width')
  197.             if width:
  198.                 w += '="%s%%"' % width
  199.             else:
  200.                 w += '="50%"'
  201.             text.append(w)
  202.         
  203.         toc_name = elem.attrib.get('name', None)
  204.         toc_id = elem.attrib.get('id', None)
  205.         if (toc_id or toc_name) and tag not in ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'):
  206.             toc_page = page.href
  207.             if self.toc.get(toc_page, None):
  208.                 for toc_x in (toc_name, toc_id):
  209.                     toc_title = self.toc[toc_page].get(toc_x, None)
  210.                     if toc_title:
  211.                         text.append('\\C0="%s"' % toc_title)
  212.                         continue
  213.                 
  214.             
  215.         
  216.         pml_tag = TAG_MAP.get(tag, None)
  217.         if pml_tag and pml_tag not in tag_stack + tags:
  218.             text.append('\\%s' % pml_tag)
  219.             tags.append(pml_tag)
  220.         
  221.         if tag in LINK_TAGS and 'q' not in tag_stack + tags:
  222.             href = elem.get('href')
  223.             if href:
  224.                 href = page.abshref(href)
  225.                 if '://' not in href:
  226.                     if '#' not in href:
  227.                         href += '#'
  228.                     
  229.                     if href not in self.link_hrefs.keys():
  230.                         self.link_hrefs[href] = 'calibre_link-%s' % len(self.link_hrefs.keys())
  231.                     
  232.                     href = '#%s' % self.link_hrefs[href]
  233.                 
  234.                 text.append('\\q="%s"' % href)
  235.                 tags.append('q')
  236.             
  237.         
  238.         id_name = elem.get('id')
  239.         name_name = elem.get('name')
  240.         for name_x in (id_name, name_name):
  241.             if name_x:
  242.                 text.append(self.get_anchor(page, name_x))
  243.                 continue
  244.         
  245.         for s in STYLES:
  246.             style_tag = s[1].get(style[s[0]], None)
  247.             if style_tag and style_tag not in tag_stack + tags:
  248.                 text.append('\\%s' % style_tag)
  249.                 tags.append(style_tag)
  250.                 continue
  251.         
  252.         if hasattr(elem, 'text') and elem.text:
  253.             text.append(self.remove_newlines(elem.text))
  254.         
  255.         for item in elem:
  256.             text += self.dump_text(item, stylizer, page, tag_stack + tags)
  257.         
  258.         tags.reverse()
  259.         text += self.close_tags(tags)
  260.         if tag in SEPARATE_TAGS:
  261.             text.append('\n\n')
  262.         
  263.         if hasattr(elem, 'tail') and elem.tail:
  264.             text.append(self.remove_newlines(elem.tail))
  265.         
  266.         return text
  267.  
  268.     
  269.     def close_tags(self, tags):
  270.         text = []
  271.         for tag in tags:
  272.             if tag == 'block':
  273.                 text.append('\n\n')
  274.                 continue
  275.             text.append('\\%s' % tag)
  276.         
  277.         return text
  278.  
  279.  
  280.