Handle anchors within tables.

This commit is contained in:
Kovid Goyal 2007-10-26 18:06:51 +00:00
parent 4f9f0f853a
commit 9b8e737920
2 changed files with 48 additions and 54 deletions

View File

@ -220,9 +220,6 @@ class HTMLConverter(object):
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
# List processing
self.list_level = 0
@ -1213,51 +1210,43 @@ class HTMLConverter(object):
return False
def process_anchor(self, tag, tag_css, tag_pseudo_css):
key = 'name' if tag.has_key('name') else 'id'
name = tag[key].replace('#', '')
if self.anchor_to_previous:
if not self.in_table: # Anchors in tables are handled separately
key = 'name' if tag.has_key('name') else 'id'
name = tag[key].replace('#', '')
previous = self.current_block
self.process_children(tag, tag_css, tag_pseudo_css)
for c in self.anchor_to_previous.contents:
if isinstance(c, (TextBlock, ImageBlock)):
self.targets[self.target_prefix+tag[key]] = c
return
tb = self.book.create_text_block()
tb.Paragraph(" ")
self.anchor_to_previous.append(tb)
self.targets[self.target_prefix+name] = tb
return
previous = self.current_block
self.process_children(tag, tag_css, tag_pseudo_css)
target = None
if self.current_block == previous:
self.current_block.must_append = True
target = self.current_block
target = None
if self.current_block == previous:
self.current_block.must_append = True
target = self.current_block
else:
found = False
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
else:
found = False
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
self.process_children(tag, tag_css, tag_pseudo_css)
def parse_tag(self, tag, parent_css):
try:
@ -1540,12 +1529,14 @@ class HTMLConverter(object):
table = Table(self, tag, tag_css, rowpad=rowpad, colpad=10)
canvases = []
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 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,
blockrule='block-fixed'))
for name in targets:
self.targets[self.target_prefix+name] = canvases[-1]
else:
canvases[-1].put_object(block, xpos + int(delta/2.), ypos)

View File

@ -221,9 +221,15 @@ class Row(object):
self.cells = []
self.colpad = colpad
cells = row.findAll(re.compile('td|th', re.IGNORECASE))
self.targets = []
for cell in cells:
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):
'''Number of cells in this row. Respects colspan'''
@ -284,14 +290,11 @@ class Table(object):
self.rowpad = rowpad
self.colpad = colpad
rows = table.findAll('tr')
conv.anchor_to_previous = conv.current_page
conv.in_table = True
for row in rows:
rcss = conv.tag_css(row, css)[0]
self.rows.append(Row(conv, row, rcss, colpad))
conv.in_table = False
conv.anchor_to_previous = None
def number_of_columns(self):
max = 0
@ -373,7 +376,7 @@ class Table(object):
if delta < 0:
delta = 0
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])):
cell = cellmatrix[r][c]
if not cell:
@ -386,7 +389,7 @@ class Table(object):
blockheight=cell.text_block_size(tb, width)[1],
blockrule='horz-fixed')
yield tb, xpos[c], sypos, delta
yield tb, xpos[c], sypos, delta, None
sypos += tb.blockStyle.attrs['blockheight']