mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Handle anchors within tables.
This commit is contained in:
parent
4f9f0f853a
commit
9b8e737920
@ -220,9 +220,6 @@ class HTMLConverter(object):
|
|||||||
self.unindented_style = book.create_text_style(parindent=0)
|
self.unindented_style = book.create_text_style(parindent=0)
|
||||||
|
|
||||||
|
|
||||||
# Set by table processing code so that any <a name> within the table
|
|
||||||
# point to the previous element
|
|
||||||
self.anchor_to_previous = None
|
|
||||||
self.in_table = False
|
self.in_table = False
|
||||||
# List processing
|
# List processing
|
||||||
self.list_level = 0
|
self.list_level = 0
|
||||||
@ -1213,51 +1210,43 @@ class HTMLConverter(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def process_anchor(self, tag, tag_css, tag_pseudo_css):
|
def process_anchor(self, tag, tag_css, tag_pseudo_css):
|
||||||
key = 'name' if tag.has_key('name') else 'id'
|
if not self.in_table: # Anchors in tables are handled separately
|
||||||
name = tag[key].replace('#', '')
|
key = 'name' if tag.has_key('name') else 'id'
|
||||||
if self.anchor_to_previous:
|
name = tag[key].replace('#', '')
|
||||||
|
previous = self.current_block
|
||||||
self.process_children(tag, tag_css, tag_pseudo_css)
|
self.process_children(tag, tag_css, tag_pseudo_css)
|
||||||
for c in self.anchor_to_previous.contents:
|
target = None
|
||||||
if isinstance(c, (TextBlock, ImageBlock)):
|
|
||||||
self.targets[self.target_prefix+tag[key]] = c
|
if self.current_block == previous:
|
||||||
return
|
self.current_block.must_append = True
|
||||||
tb = self.book.create_text_block()
|
target = self.current_block
|
||||||
tb.Paragraph(" ")
|
else:
|
||||||
self.anchor_to_previous.append(tb)
|
found = False
|
||||||
self.targets[self.target_prefix+name] = tb
|
for item in self.current_page.contents:
|
||||||
return
|
if item == previous:
|
||||||
previous = self.current_block
|
found = True
|
||||||
self.process_children(tag, tag_css, tag_pseudo_css)
|
continue
|
||||||
target = None
|
if found:
|
||||||
|
target = item
|
||||||
if self.current_block == previous:
|
break
|
||||||
self.current_block.must_append = True
|
if target and not isinstance(target, (TextBlock, ImageBlock)):
|
||||||
target = self.current_block
|
if isinstance(target, RuledLine):
|
||||||
|
target = self.book.create_text_block(textStyle=self.current_block.textStyle,
|
||||||
|
blockStyle=self.current_block.blockStyle)
|
||||||
|
target.Paragraph(' ')
|
||||||
|
self.current_page.append(target)
|
||||||
|
else:
|
||||||
|
target = BlockSpace()
|
||||||
|
self.current_page.append(target)
|
||||||
|
if target == None:
|
||||||
|
if self.current_block.has_text():
|
||||||
|
target = self.current_block
|
||||||
|
else:
|
||||||
|
target = BlockSpace()
|
||||||
|
self.current_page.append(target)
|
||||||
|
self.targets[self.target_prefix+name] = target
|
||||||
else:
|
else:
|
||||||
found = False
|
self.process_children(tag, tag_css, tag_pseudo_css)
|
||||||
for item in self.current_page.contents:
|
|
||||||
if item == previous:
|
|
||||||
found = True
|
|
||||||
continue
|
|
||||||
if found:
|
|
||||||
target = item
|
|
||||||
break
|
|
||||||
if target and not isinstance(target, (TextBlock, ImageBlock)):
|
|
||||||
if isinstance(target, RuledLine):
|
|
||||||
target = self.book.create_text_block(textStyle=self.current_block.textStyle,
|
|
||||||
blockStyle=self.current_block.blockStyle)
|
|
||||||
target.Paragraph(' ')
|
|
||||||
self.current_page.append(target)
|
|
||||||
else:
|
|
||||||
target = BlockSpace()
|
|
||||||
self.current_page.append(target)
|
|
||||||
if target == None:
|
|
||||||
if self.current_block.has_text():
|
|
||||||
target = self.current_block
|
|
||||||
else:
|
|
||||||
target = BlockSpace()
|
|
||||||
self.current_page.append(target)
|
|
||||||
self.targets[self.target_prefix+name] = target
|
|
||||||
|
|
||||||
def parse_tag(self, tag, parent_css):
|
def parse_tag(self, tag, parent_css):
|
||||||
try:
|
try:
|
||||||
@ -1540,12 +1529,14 @@ class HTMLConverter(object):
|
|||||||
table = Table(self, tag, tag_css, rowpad=rowpad, colpad=10)
|
table = Table(self, tag, tag_css, rowpad=rowpad, colpad=10)
|
||||||
canvases = []
|
canvases = []
|
||||||
ps = self.current_page.pageStyle.attrs
|
ps = self.current_page.pageStyle.attrs
|
||||||
for block, xpos, ypos, delta in table.blocks(int(ps['textwidth']), int(ps['textheight'])):
|
for block, xpos, ypos, delta, targets in table.blocks(int(ps['textwidth']), int(ps['textheight'])):
|
||||||
if not block:
|
if not block:
|
||||||
if ypos > int(ps['textheight']):
|
if ypos > int(ps['textheight']):
|
||||||
raise Exception, 'Table has cell that is too large'
|
raise Exception, 'Table has cell that is too large'
|
||||||
canvases.append(Canvas(int(self.current_page.pageStyle.attrs['textwidth']), ypos+rowpad,
|
canvases.append(Canvas(int(self.current_page.pageStyle.attrs['textwidth']), ypos+rowpad,
|
||||||
blockrule='block-fixed'))
|
blockrule='block-fixed'))
|
||||||
|
for name in targets:
|
||||||
|
self.targets[self.target_prefix+name] = canvases[-1]
|
||||||
else:
|
else:
|
||||||
canvases[-1].put_object(block, xpos + int(delta/2.), ypos)
|
canvases[-1].put_object(block, xpos + int(delta/2.), ypos)
|
||||||
|
|
||||||
|
@ -221,9 +221,15 @@ class Row(object):
|
|||||||
self.cells = []
|
self.cells = []
|
||||||
self.colpad = colpad
|
self.colpad = colpad
|
||||||
cells = row.findAll(re.compile('td|th', re.IGNORECASE))
|
cells = row.findAll(re.compile('td|th', re.IGNORECASE))
|
||||||
|
self.targets = []
|
||||||
for cell in cells:
|
for cell in cells:
|
||||||
ccss = conv.tag_css(cell, css)[0]
|
ccss = conv.tag_css(cell, css)[0]
|
||||||
self.cells.append(Cell(conv, cell, ccss))
|
self.cells.append(Cell(conv, cell, ccss))
|
||||||
|
for a in row.findAll('a'):
|
||||||
|
name = a['name'] if a.has_key('name') else a['id'] if a.has_key('id') else None
|
||||||
|
if name is not None:
|
||||||
|
self.targets.append(name.replace('#', ''))
|
||||||
|
|
||||||
|
|
||||||
def number_of_cells(self):
|
def number_of_cells(self):
|
||||||
'''Number of cells in this row. Respects colspan'''
|
'''Number of cells in this row. Respects colspan'''
|
||||||
@ -284,14 +290,11 @@ class Table(object):
|
|||||||
self.rowpad = rowpad
|
self.rowpad = rowpad
|
||||||
self.colpad = colpad
|
self.colpad = colpad
|
||||||
rows = table.findAll('tr')
|
rows = table.findAll('tr')
|
||||||
conv.anchor_to_previous = conv.current_page
|
|
||||||
conv.in_table = True
|
conv.in_table = True
|
||||||
for row in rows:
|
for row in rows:
|
||||||
rcss = conv.tag_css(row, css)[0]
|
rcss = conv.tag_css(row, css)[0]
|
||||||
self.rows.append(Row(conv, row, rcss, colpad))
|
self.rows.append(Row(conv, row, rcss, colpad))
|
||||||
conv.in_table = False
|
conv.in_table = False
|
||||||
conv.anchor_to_previous = None
|
|
||||||
|
|
||||||
|
|
||||||
def number_of_columns(self):
|
def number_of_columns(self):
|
||||||
max = 0
|
max = 0
|
||||||
@ -373,7 +376,7 @@ class Table(object):
|
|||||||
if delta < 0:
|
if delta < 0:
|
||||||
delta = 0
|
delta = 0
|
||||||
for r in range(len(cellmatrix)):
|
for r in range(len(cellmatrix)):
|
||||||
yield None, 0, heights[r], 0
|
yield None, 0, heights[r], 0, self.rows[r].targets
|
||||||
for c in range(len(cellmatrix[r])):
|
for c in range(len(cellmatrix[r])):
|
||||||
cell = cellmatrix[r][c]
|
cell = cellmatrix[r][c]
|
||||||
if not cell:
|
if not cell:
|
||||||
@ -386,7 +389,7 @@ class Table(object):
|
|||||||
blockheight=cell.text_block_size(tb, width)[1],
|
blockheight=cell.text_block_size(tb, width)[1],
|
||||||
blockrule='horz-fixed')
|
blockrule='horz-fixed')
|
||||||
|
|
||||||
yield tb, xpos[c], sypos, delta
|
yield tb, xpos[c], sypos, delta, None
|
||||||
sypos += tb.blockStyle.attrs['blockheight']
|
sypos += tb.blockStyle.attrs['blockheight']
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user