mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix #86 and add support for % width values in <td> elements.
This commit is contained in:
parent
0ade1a3e64
commit
5ecdb79f5c
1
setup.py
1
setup.py
@ -285,7 +285,6 @@ setup(
|
||||
'gui_scripts' : [ 'prs500-gui = libprs500.gui.main:main']
|
||||
},
|
||||
zip_safe = True,
|
||||
install_requires = ['sqlalchemy >= 0.3.7'],
|
||||
description =
|
||||
"""
|
||||
Ebook management application.
|
||||
|
@ -33,7 +33,7 @@ You may have to adjust the GROUP and the location of the rules file to
|
||||
suit your distribution.
|
||||
"""
|
||||
|
||||
__version__ = "0.3.37"
|
||||
__version__ = "0.3.38"
|
||||
__docformat__ = "epytext"
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
|
||||
|
@ -856,7 +856,6 @@ class HTMLConverter(object):
|
||||
pass
|
||||
elif tagname == 'a' and self.max_link_levels >= 0:
|
||||
if tag.has_key('name'):
|
||||
print tag, self.anchor_to_previous
|
||||
if self.anchor_to_previous:
|
||||
self.process_children(tag, tag_css)
|
||||
for c in self.anchor_to_previous.contents:
|
||||
|
@ -73,23 +73,36 @@ def tokens(tb):
|
||||
|
||||
class Cell(object):
|
||||
|
||||
def __init__(self, conv, cell, css):
|
||||
def __init__(self, conv, tag, css):
|
||||
self.conv = conv
|
||||
self.cell = cell
|
||||
self.tag = tag
|
||||
self.css = css
|
||||
self.text_blocks = []
|
||||
self.pwidth = -1.
|
||||
if tag.has_key('width') and '%' in tag['width']:
|
||||
try:
|
||||
self.pwidth = float(tag['width'].replace('%', ''))
|
||||
except ValueError:
|
||||
pass
|
||||
if css.has_key('width') and '%' in css['width']:
|
||||
try:
|
||||
self.pwidth = float(css['width'].replace('%', ''))
|
||||
except ValueError:
|
||||
pass
|
||||
if self.pwidth > 100:
|
||||
self.pwidth = -1
|
||||
self.rowspan = self.colspan = 1
|
||||
try:
|
||||
self.colspan = int(cell['colspan']) if cell.has_key('colspan') else 1
|
||||
self.rowspan = int(cell['rowspan']) if cell.has_key('rowspan') else 1
|
||||
self.colspan = int(tag['colspan']) if tag.has_key('colspan') else 1
|
||||
self.rowspan = int(tag['rowspan']) if tag.has_key('rowspan') else 1
|
||||
except:
|
||||
if conv.verbose:
|
||||
print >>sys.stderr, "Error reading row/colspan for ", cell
|
||||
print >>sys.stderr, "Error reading row/colspan for ", tag
|
||||
|
||||
pp = conv.current_page
|
||||
conv.book.allow_new_page = False
|
||||
conv.current_page = conv.book.create_page()
|
||||
conv.parse_tag(cell, css)
|
||||
conv.parse_tag(tag, css)
|
||||
conv.end_current_block()
|
||||
for item in conv.current_page.contents:
|
||||
if isinstance(item, TextBlock):
|
||||
@ -121,6 +134,31 @@ class Cell(object):
|
||||
pts = int(pts)
|
||||
return ceil((float(self.conv.profile.dpi)/72)*(pts/10.))
|
||||
|
||||
def minimum_width(self):
|
||||
return max([self.minimum_tb_width(tb) for tb in self.text_blocks])
|
||||
|
||||
def minimum_tb_width(self, tb):
|
||||
ts = tb.textStyle.attrs
|
||||
default_font = get_font(ts['fontfacename'], self.pts_to_pixels(ts['fontsize']))
|
||||
parindent = self.pts_to_pixels(ts['parindent'])
|
||||
|
||||
for token, attrs in tokens(tb):
|
||||
font = default_font
|
||||
if isinstance(token, int): # Handle para and line breaks
|
||||
continue
|
||||
if isinstance(token, Plot):
|
||||
return self.pts_to_pixels(token.xsize)
|
||||
ff = attrs.get('fontfacename', ts['fontfacename'])
|
||||
fs = attrs.get('fontsize', ts['fontsize'])
|
||||
if (ff, fs) != (ts['fontfacename'], ts['fontsize']):
|
||||
font = get_font(ff, self.pts_to_pixels(fs))
|
||||
if not token.strip():
|
||||
continue
|
||||
word = token.split()
|
||||
word = word[0] if word else ""
|
||||
width, height = font.getsize(word)
|
||||
return parindent + width + 2
|
||||
|
||||
def text_block_size(self, tb, maxwidth=sys.maxint, debug=False):
|
||||
ts = tb.textStyle.attrs
|
||||
default_font = get_font(ts['fontfacename'], self.pts_to_pixels(ts['fontsize']))
|
||||
@ -195,7 +233,7 @@ class Row(object):
|
||||
return 0
|
||||
return max(heights)
|
||||
|
||||
def preferred_width(self, col):
|
||||
def cell_from_index(self, col):
|
||||
i = -1
|
||||
cell = None
|
||||
for cell in self.cells:
|
||||
@ -205,10 +243,26 @@ class Row(object):
|
||||
i += 1
|
||||
if i == col:
|
||||
break
|
||||
return cell
|
||||
|
||||
def minimum_width(self, col):
|
||||
cell = self.cell_from_index(col)
|
||||
if not cell:
|
||||
return 0
|
||||
return cell.minimum_width()
|
||||
|
||||
def preferred_width(self, col):
|
||||
cell = self.cell_from_index(col)
|
||||
if not cell:
|
||||
return 0
|
||||
return 0 if cell.colspan > 1 else cell.preferred_width()
|
||||
|
||||
def width_percent(self, col):
|
||||
cell = self.cell_from_index(col)
|
||||
if not cell:
|
||||
return -1
|
||||
return -1 if cell.colspan > 1 else cell.pwidth
|
||||
|
||||
def cell_iterator(self):
|
||||
for c in self.cells:
|
||||
yield c
|
||||
@ -244,6 +298,12 @@ class Table(object):
|
||||
widths = self.get_widths(maxwidth)
|
||||
return sum([row.height(widths) + self.rowpad for row in self.rows]) - self.rowpad
|
||||
|
||||
def minimum_width(self, col):
|
||||
return max([row.minimum_width(col) for row in self.rows])
|
||||
|
||||
def width_percent(self, col):
|
||||
return max([row.width_percent(col) for row in self.rows])
|
||||
|
||||
def get_widths(self, maxwidth):
|
||||
'''
|
||||
Return widths of columns + sefl.colpad
|
||||
@ -258,9 +318,24 @@ class Table(object):
|
||||
except IndexError:
|
||||
continue
|
||||
widths[c] = max(cellwidths)
|
||||
adjustable_columns, psum = [], 0.
|
||||
for i in xrange(len(widths)):
|
||||
wp = self.width_percent(i)
|
||||
if wp >= 0.:
|
||||
psum += wp
|
||||
if psum > 100:
|
||||
adjustable_columns.append(i)
|
||||
else:
|
||||
widths[i] = (wp/100.) * (maxwidth - (cols-1)*self.colpad)
|
||||
else:
|
||||
adjustable_columns.append(i)
|
||||
|
||||
itercount = 0
|
||||
min_widths = [self.minimum_width(i) for i in xrange(cols)]
|
||||
while sum(widths) > maxwidth-((len(widths)-1)*self.colpad) and itercount < 100:
|
||||
widths = [ceil((95./100.)*w) for w in widths]
|
||||
for i in adjustable_columns:
|
||||
widths[i] = ceil((95./100.)*widths[i]) if \
|
||||
ceil((95./100.)*widths[i]) >= min_widths[i] else widths[i]
|
||||
itercount += 1
|
||||
return [i+self.colpad for i in widths]
|
||||
|
||||
|
22
src/libprs500/library/sqlnotes
Normal file
22
src/libprs500/library/sqlnotes
Normal file
@ -0,0 +1,22 @@
|
||||
SQLITE notes
|
||||
1) Versioning
|
||||
pragma user_version
|
||||
returns the 0 for a new database
|
||||
pragma user_version=1 sets the user version
|
||||
|
||||
2) Periodic vacuum;
|
||||
On exit? Config option?
|
||||
|
||||
3) unique indices on the tables
|
||||
|
||||
4) Foreign key triggers
|
||||
http://www.sqlite.org/cvstrac/wiki?p=ForeignKeyTriggers
|
||||
|
||||
5) Optimization
|
||||
http://www.sqlite.org/cvstrac/wiki?p=PerformanceTuning
|
||||
|
||||
6) Autoincreemnt to guarantee each logical book has a forever unique id
|
||||
|
||||
7) Add NOT NULL and default constraints
|
||||
|
||||
8) COLLATE NOCASE llok at Ch. 7 for non english
|
Loading…
x
Reference in New Issue
Block a user