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']
|
'gui_scripts' : [ 'prs500-gui = libprs500.gui.main:main']
|
||||||
},
|
},
|
||||||
zip_safe = True,
|
zip_safe = True,
|
||||||
install_requires = ['sqlalchemy >= 0.3.7'],
|
|
||||||
description =
|
description =
|
||||||
"""
|
"""
|
||||||
Ebook management application.
|
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.
|
suit your distribution.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "0.3.37"
|
__version__ = "0.3.38"
|
||||||
__docformat__ = "epytext"
|
__docformat__ = "epytext"
|
||||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||||
|
|
||||||
|
@ -856,7 +856,6 @@ class HTMLConverter(object):
|
|||||||
pass
|
pass
|
||||||
elif tagname == 'a' and self.max_link_levels >= 0:
|
elif tagname == 'a' and self.max_link_levels >= 0:
|
||||||
if tag.has_key('name'):
|
if tag.has_key('name'):
|
||||||
print tag, self.anchor_to_previous
|
|
||||||
if self.anchor_to_previous:
|
if self.anchor_to_previous:
|
||||||
self.process_children(tag, tag_css)
|
self.process_children(tag, tag_css)
|
||||||
for c in self.anchor_to_previous.contents:
|
for c in self.anchor_to_previous.contents:
|
||||||
|
@ -73,23 +73,36 @@ def tokens(tb):
|
|||||||
|
|
||||||
class Cell(object):
|
class Cell(object):
|
||||||
|
|
||||||
def __init__(self, conv, cell, css):
|
def __init__(self, conv, tag, css):
|
||||||
self.conv = conv
|
self.conv = conv
|
||||||
self.cell = cell
|
self.tag = tag
|
||||||
self.css = css
|
self.css = css
|
||||||
self.text_blocks = []
|
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
|
self.rowspan = self.colspan = 1
|
||||||
try:
|
try:
|
||||||
self.colspan = int(cell['colspan']) if cell.has_key('colspan') else 1
|
self.colspan = int(tag['colspan']) if tag.has_key('colspan') else 1
|
||||||
self.rowspan = int(cell['rowspan']) if cell.has_key('rowspan') else 1
|
self.rowspan = int(tag['rowspan']) if tag.has_key('rowspan') else 1
|
||||||
except:
|
except:
|
||||||
if conv.verbose:
|
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
|
pp = conv.current_page
|
||||||
conv.book.allow_new_page = False
|
conv.book.allow_new_page = False
|
||||||
conv.current_page = conv.book.create_page()
|
conv.current_page = conv.book.create_page()
|
||||||
conv.parse_tag(cell, css)
|
conv.parse_tag(tag, css)
|
||||||
conv.end_current_block()
|
conv.end_current_block()
|
||||||
for item in conv.current_page.contents:
|
for item in conv.current_page.contents:
|
||||||
if isinstance(item, TextBlock):
|
if isinstance(item, TextBlock):
|
||||||
@ -121,6 +134,31 @@ class Cell(object):
|
|||||||
pts = int(pts)
|
pts = int(pts)
|
||||||
return ceil((float(self.conv.profile.dpi)/72)*(pts/10.))
|
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):
|
def text_block_size(self, tb, maxwidth=sys.maxint, debug=False):
|
||||||
ts = tb.textStyle.attrs
|
ts = tb.textStyle.attrs
|
||||||
default_font = get_font(ts['fontfacename'], self.pts_to_pixels(ts['fontsize']))
|
default_font = get_font(ts['fontfacename'], self.pts_to_pixels(ts['fontsize']))
|
||||||
@ -195,7 +233,7 @@ class Row(object):
|
|||||||
return 0
|
return 0
|
||||||
return max(heights)
|
return max(heights)
|
||||||
|
|
||||||
def preferred_width(self, col):
|
def cell_from_index(self, col):
|
||||||
i = -1
|
i = -1
|
||||||
cell = None
|
cell = None
|
||||||
for cell in self.cells:
|
for cell in self.cells:
|
||||||
@ -205,10 +243,26 @@ class Row(object):
|
|||||||
i += 1
|
i += 1
|
||||||
if i == col:
|
if i == col:
|
||||||
break
|
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:
|
if not cell:
|
||||||
return 0
|
return 0
|
||||||
return 0 if cell.colspan > 1 else cell.preferred_width()
|
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):
|
def cell_iterator(self):
|
||||||
for c in self.cells:
|
for c in self.cells:
|
||||||
yield c
|
yield c
|
||||||
@ -244,6 +298,12 @@ class Table(object):
|
|||||||
widths = self.get_widths(maxwidth)
|
widths = self.get_widths(maxwidth)
|
||||||
return sum([row.height(widths) + self.rowpad for row in self.rows]) - self.rowpad
|
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):
|
def get_widths(self, maxwidth):
|
||||||
'''
|
'''
|
||||||
Return widths of columns + sefl.colpad
|
Return widths of columns + sefl.colpad
|
||||||
@ -258,9 +318,24 @@ class Table(object):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
continue
|
continue
|
||||||
widths[c] = max(cellwidths)
|
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
|
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:
|
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
|
itercount += 1
|
||||||
return [i+self.colpad for i in widths]
|
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