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

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
  6. import math
  7. import sys
  8. import re
  9. from calibre.ebooks.lrf.fonts import get_font
  10. from calibre.ebooks.lrf.pylrs.pylrs import TextBlock, Text, CR, Span, CharButton, Plot, Paragraph, LrsTextTag
  11.  
  12. def ceil(num):
  13.     return int(math.ceil(num))
  14.  
  15.  
  16. def print_xml(elem):
  17.     ElementWriter = ElementWriter
  18.     import calibre.ebooks.lrf.pylrs.pylrs
  19.     elem = elem.toElement('utf8')
  20.     ew = ElementWriter(elem, sourceEncoding = 'utf8')
  21.     ew.write(sys.stdout)
  22.     print 
  23.  
  24.  
  25. def cattrs(base, extra):
  26.     new = base.copy()
  27.     new.update(extra)
  28.     return new
  29.  
  30.  
  31. def tokens(tb):
  32.     
  33.     def process_element(x, attrs):
  34.         if isinstance(x, CR):
  35.             yield (2, None)
  36.         elif isinstance(x, Text):
  37.             yield (x.text, cattrs(attrs, { }))
  38.         elif isinstance(x, basestring):
  39.             yield (x, cattrs(attrs, { }))
  40.         elif isinstance(x, (CharButton, LrsTextTag)):
  41.             if x.contents:
  42.                 if hasattr(x.contents[0], 'text'):
  43.                     yield (x.contents[0].text, cattrs(attrs, { }))
  44.                 elif hasattr(x.contents[0], 'attrs'):
  45.                     for z in process_element(x.contents[0], x.contents[0].attrs):
  46.                         yield z
  47.                     
  48.                 
  49.             
  50.         elif isinstance(x, Plot):
  51.             yield (x, None)
  52.         elif isinstance(x, Span):
  53.             attrs = cattrs(attrs, x.attrs)
  54.             for y in x.contents:
  55.                 for z in process_element(y, attrs):
  56.                     yield z
  57.                 
  58.             
  59.         
  60.  
  61.     for i in tb.contents:
  62.         if isinstance(i, CR):
  63.             yield (1, None)
  64.             (None,)
  65.             continue
  66.         if isinstance(i, Paragraph):
  67.             for j in i.contents:
  68.                 attrs = { }
  69.                 if hasattr(j, 'attrs'):
  70.                     attrs = j.attrs
  71.                 
  72.                 for k in process_element(j, attrs):
  73.                     yield k
  74.                 
  75.             
  76.     
  77.  
  78.  
  79. class Cell(object):
  80.     
  81.     def __init__(self, conv, tag, css):
  82.         self.conv = conv
  83.         self.tag = tag
  84.         self.css = css
  85.         self.text_blocks = []
  86.         self.pwidth = -1
  87.         if tag.has_key('width') and '%' in tag['width']:
  88.             
  89.             try:
  90.                 self.pwidth = float(tag['width'].replace('%', ''))
  91.             except ValueError:
  92.                 pass
  93.             except:
  94.                 None<EXCEPTION MATCH>ValueError
  95.             
  96.  
  97.         None<EXCEPTION MATCH>ValueError
  98.         if css.has_key('width') and '%' in css['width']:
  99.             
  100.             try:
  101.                 self.pwidth = float(css['width'].replace('%', ''))
  102.             except ValueError:
  103.                 pass
  104.             except:
  105.                 None<EXCEPTION MATCH>ValueError
  106.             
  107.  
  108.         None<EXCEPTION MATCH>ValueError
  109.         if self.pwidth > 100:
  110.             self.pwidth = -1
  111.         
  112.         self.rowspan = self.colspan = 1
  113.         
  114.         try:
  115.             self.colspan = None if tag.has_key('colspan') else 1
  116.             self.rowspan = None if tag.has_key('rowspan') else 1
  117.         except:
  118.             pass
  119.  
  120.         pp = conv.current_page
  121.         conv.book.allow_new_page = False
  122.         conv.current_page = conv.book.create_page()
  123.         conv.parse_tag(tag, css)
  124.         conv.end_current_block()
  125.         for item in conv.current_page.contents:
  126.             if isinstance(item, TextBlock):
  127.                 self.text_blocks.append(item)
  128.                 continue
  129.         
  130.         conv.current_page = pp
  131.         conv.book.allow_new_page = True
  132.         if not self.text_blocks:
  133.             tb = conv.book.create_text_block()
  134.             tb.Paragraph(' ')
  135.             self.text_blocks.append(tb)
  136.         
  137.         for tb in self.text_blocks:
  138.             tb.parent = None
  139.             tb.objId = 0
  140.             tb.blockStyle = conv.book.create_block_style()
  141.             ts = conv.book.create_text_style(**tb.textStyle.attrs)
  142.             ts.attrs['parindent'] = 0
  143.             tb.textStyle = ts
  144.             if ts.attrs['align'] == 'foot':
  145.                 if isinstance(tb.contents[-1], Paragraph):
  146.                     tb.contents[-1].append(' ')
  147.                 
  148.             isinstance(tb.contents[-1], Paragraph)
  149.         
  150.  
  151.     
  152.     def pts_to_pixels(self, pts):
  153.         pts = int(pts)
  154.         return ceil((float(self.conv.profile.dpi) / 72) * (pts / 10))
  155.  
  156.     
  157.     def minimum_width(self):
  158.         return []([ self.minimum_tb_width(tb) for tb in self.text_blocks ])
  159.  
  160.     
  161.     def minimum_tb_width(self, tb):
  162.         ts = tb.textStyle.attrs
  163.         default_font = get_font(ts['fontfacename'], self.pts_to_pixels(ts['fontsize']))
  164.         parindent = self.pts_to_pixels(ts['parindent'])
  165.         mwidth = 0
  166.         for token, attrs in tokens(tb):
  167.             font = default_font
  168.             if isinstance(token, int):
  169.                 continue
  170.             
  171.             if isinstance(token, Plot):
  172.                 return self.pts_to_pixels(token.xsize)
  173.             ff = attrs.get('fontfacename', ts['fontfacename'])
  174.             fs = attrs.get('fontsize', ts['fontsize'])
  175.             if (ff, fs) != (ts['fontfacename'], ts['fontsize']):
  176.                 font = get_font(ff, self.pts_to_pixels(fs))
  177.             
  178.             if not token.strip():
  179.                 continue
  180.             
  181.             word = token.split()
  182.             word = None if word else ''
  183.             width = font.getsize(word)[0]
  184.             if width > mwidth:
  185.                 mwidth = width
  186.                 continue
  187.         
  188.         return parindent + mwidth + 2
  189.  
  190.     
  191.     def text_block_size(self, tb, maxwidth = sys.maxint, debug = False):
  192.         ts = tb.textStyle.attrs
  193.         default_font = get_font(ts['fontfacename'], self.pts_to_pixels(ts['fontsize']))
  194.         parindent = self.pts_to_pixels(ts['parindent'])
  195.         (top, bottom, left, right) = (0, 0, parindent, parindent)
  196.         
  197.         def add_word(width, height, left, right, top, bottom, ls, ws):
  198.             if left + width > maxwidth:
  199.                 left = width + ws
  200.                 top += ls
  201.                 bottom = None if top + ls > bottom else bottom
  202.             else:
  203.                 left += width + ws
  204.                 right = None if left > right else right
  205.                 bottom = None if top + ls > bottom else bottom
  206.             return (left, right, top, bottom)
  207.  
  208.         for token, attrs in tokens(tb):
  209.             if attrs == None:
  210.                 attrs = { }
  211.             
  212.             font = default_font
  213.             ls = self.pts_to_pixels(attrs.get('baselineskip', ts['baselineskip'])) + self.pts_to_pixels(attrs.get('linespace', ts['linespace']))
  214.             ws = self.pts_to_pixels(attrs.get('wordspace', ts['wordspace']))
  215.             if isinstance(token, int):
  216.                 if top != bottom:
  217.                     top = bottom
  218.                 else:
  219.                     top += ls
  220.                     bottom += ls
  221.                 left = None if int == 1 else 0
  222.                 continue
  223.             
  224.             if isinstance(token, Plot):
  225.                 width = self.pts_to_pixels(token.xsize)
  226.                 height = self.pts_to_pixels(token.ysize)
  227.                 (left, right, top, bottom) = add_word(width, height, left, right, top, bottom, height, ws)
  228.                 continue
  229.             
  230.             ff = attrs.get('fontfacename', ts['fontfacename'])
  231.             fs = attrs.get('fontsize', ts['fontsize'])
  232.             if (ff, fs) != (ts['fontfacename'], ts['fontsize']):
  233.                 font = get_font(ff, self.pts_to_pixels(fs))
  234.             
  235.             for word in token.split():
  236.                 (width, height) = font.getsize(word)
  237.                 (left, right, top, bottom) = add_word(width, height, left, right, top, bottom, ls, ws)
  238.             
  239.         
  240.         return (right + 3 + max(parindent, 10), bottom)
  241.  
  242.     
  243.     def text_block_preferred_width(self, tb, debug = False):
  244.         return self.text_block_size(tb, sys.maxint, debug = debug)[0]
  245.  
  246.     
  247.     def preferred_width(self, debug = False):
  248.         return []([]([ self.text_block_preferred_width(i, debug = debug) for i in self.text_blocks ]))
  249.  
  250.     
  251.     def height(self, width):
  252.         return []([ self.text_block_size(i, width)[1] for i in self.text_blocks ])
  253.  
  254.  
  255.  
  256. class Row(object):
  257.     
  258.     def __init__(self, conv, row, css, colpad):
  259.         self.cells = []
  260.         self.colpad = colpad
  261.         cells = row.findAll(re.compile('td|th', re.IGNORECASE))
  262.         self.targets = []
  263.         for cell in cells:
  264.             ccss = conv.tag_css(cell, css)[0]
  265.             self.cells.append(Cell(conv, cell, ccss))
  266.         
  267.         for a in row.findAll(id = True) + row.findAll(name = True):
  268.             if a.has_key('name'):
  269.                 pass
  270.             elif a.has_key('id'):
  271.                 pass
  272.             
  273.             name = None
  274.             if name is not None:
  275.                 self.targets.append(name.replace('#', ''))
  276.                 continue
  277.         
  278.  
  279.     
  280.     def number_of_cells(self):
  281.         ans = 0
  282.         for cell in self.cells:
  283.             ans += cell.colspan
  284.         
  285.         return ans
  286.  
  287.     
  288.     def height(self, widths):
  289.         i = 0
  290.         heights = []
  291.         for cell in self.cells:
  292.             width = sum(widths[i:i + cell.colspan])
  293.             heights.append(cell.height(width))
  294.             i += cell.colspan
  295.         
  296.         if not heights:
  297.             return 0
  298.         return max(heights)
  299.  
  300.     
  301.     def cell_from_index(self, col):
  302.         i = -1
  303.         cell = None
  304.         for cell in self.cells:
  305.             for k in range(0, cell.colspan):
  306.                 if i == col:
  307.                     break
  308.                 
  309.                 i += 1
  310.             
  311.             if i == col:
  312.                 break
  313.                 continue
  314.         
  315.         return cell
  316.  
  317.     
  318.     def minimum_width(self, col):
  319.         cell = self.cell_from_index(col)
  320.         if not cell:
  321.             return 0
  322.         return cell.minimum_width()
  323.  
  324.     
  325.     def preferred_width(self, col):
  326.         cell = self.cell_from_index(col)
  327.         if not cell:
  328.             return 0
  329.         if cell.colspan > 1:
  330.             return 0
  331.         return cell.preferred_width()
  332.  
  333.     
  334.     def width_percent(self, col):
  335.         cell = self.cell_from_index(col)
  336.         if not cell:
  337.             return -1
  338.         if cell.colspan > 1:
  339.             return -1
  340.         return cell.pwidth
  341.  
  342.     
  343.     def cell_iterator(self):
  344.         for c in self.cells:
  345.             yield c
  346.         
  347.  
  348.  
  349.  
  350. class Table(object):
  351.     
  352.     def __init__(self, conv, table, css, rowpad = 10, colpad = 10):
  353.         self.rows = []
  354.         self.conv = conv
  355.         self.rowpad = rowpad
  356.         self.colpad = colpad
  357.         rows = table.findAll('tr')
  358.         conv.in_table = True
  359.         for row in rows:
  360.             rcss = conv.tag_css(row, css)[0]
  361.             self.rows.append(Row(conv, row, rcss, colpad))
  362.         
  363.         conv.in_table = False
  364.  
  365.     
  366.     def number_of_columns(self):
  367.         max = 0
  368.         for row in self.rows:
  369.             max = None if row.number_of_cells() > max else max
  370.         
  371.         return max
  372.  
  373.     
  374.     def number_or_rows(self):
  375.         return len(self.rows)
  376.  
  377.     
  378.     def height(self, maxwidth):
  379.         widths = self.get_widths(maxwidth)
  380.         return []([ row.height(widths) + self.rowpad for row in self.rows ]) - self.rowpad
  381.  
  382.     
  383.     def minimum_width(self, col):
  384.         return []([ row.minimum_width(col) for row in self.rows ])
  385.  
  386.     
  387.     def width_percent(self, col):
  388.         return []([ row.width_percent(col) for row in self.rows ])
  389.  
  390.     
  391.     def get_widths(self, maxwidth):
  392.         rows = self.number_or_rows()
  393.         cols = self.number_of_columns()
  394.         widths = range(cols)
  395.         for c in range(cols):
  396.             cellwidths = [ 0 for i in range(rows) ]
  397.             for r in range(rows):
  398.                 
  399.                 try:
  400.                     cellwidths[r] = self.rows[r].preferred_width(c)
  401.                 continue
  402.                 except IndexError:
  403.                     []
  404.                     []
  405.                     []
  406.                     continue
  407.                     continue
  408.                 
  409.  
  410.             
  411.             widths[c] = max(cellwidths)
  412.         
  413.         min_widths = [ self.minimum_width(i) + 10 for i in xrange(cols) ]
  414.         for i in xrange(len(widths)):
  415.             wp = self.width_percent(i)
  416.             if wp >= 0:
  417.                 widths[i] = max(min_widths[i], ceil((wp / 100) * (maxwidth - (cols - 1) * self.colpad)))
  418.                 continue
  419.             []
  420.         
  421.         itercount = 0
  422.         while sum(widths) > maxwidth - (len(widths) - 1) * self.colpad and itercount < 100:
  423.             for i in range(cols):
  424.                 widths[i] = [] if ceil((95 / 100) * widths[i]) >= min_widths[i] else widths[i]
  425.             
  426.             itercount += 1
  427.             continue
  428.             []<EXCEPTION MATCH>IndexError
  429.         return [ i + self.colpad for i in widths ]
  430.  
  431.     
  432.     def blocks(self, maxwidth, maxheight):
  433.         rows = self.number_or_rows()
  434.         cols = self.number_of_columns()
  435.         cellmatrix = [ [ None for c in range(cols) ] for r in range(rows) ]
  436.         rowpos = [ 0 for i in range(rows) ]
  437.         for r in range(rows):
  438.             nc = self.rows[r].cell_iterator()
  439.             
  440.             try:
  441.                 while True:
  442.                     cell = nc.next()
  443.                     cellmatrix[r][rowpos[r]] = cell
  444.                     rowpos[r] += cell.colspan
  445.                     for k in range(1, cell.rowspan):
  446.                         
  447.                         try:
  448.                             rowpos[r + k] += 1
  449.                         continue
  450.                         except IndexError:
  451.                             []
  452.                             []
  453.                             []
  454.                             break
  455.                             continue
  456.                             []
  457.                         
  458.  
  459.                     
  460.                     continue
  461.                     []<EXCEPTION MATCH>IndexError
  462.             continue
  463.             except StopIteration:
  464.                 []
  465.                 []
  466.                 []
  467.                 continue
  468.                 continue
  469.                 []
  470.             
  471.  
  472.         
  473.         widths = self.get_widths(maxwidth)
  474.         heights = [ row.height(widths) for row in self.rows ]
  475.         xpos = [ sum(widths[:i]) for i in range(cols) ]
  476.         delta = maxwidth - sum(widths)
  477.         for r in range(len(cellmatrix)):
  478.             yield (None, 0, heights[r], 0, self.rows[r].targets)
  479.             [] if delta < 0 else []
  480.             for c in range(len(cellmatrix[r])):
  481.                 cell = cellmatrix[r][c]
  482.                 width = sum(widths[c:c + cell.colspan]) - self.colpad * cell.colspan
  483.                 sypos = 0
  484.                 for tb in cell.text_blocks:
  485.                     tb.blockStyle = self.conv.book.create_block_style(blockwidth = width, blockheight = cell.text_block_size(tb, width)[1], blockrule = 'horz-fixed')
  486.                     yield (tb, xpos[c], sypos, delta, None)
  487.                     [] if not cell else []<EXCEPTION MATCH>StopIteration
  488.                     sypos += tb.blockStyle.attrs['blockheight']
  489.                 
  490.             
  491.         
  492.  
  493.  
  494.