mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
DOCX Output: Start work on table styling
This commit is contained in:
parent
1b4e2a8858
commit
cb69ee84ac
@ -7,12 +7,38 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
from calibre.ebooks.docx.names import makeelement
|
||||
from calibre.ebooks.docx.writer.utils import convert_color
|
||||
|
||||
def as_percent(x):
|
||||
if x and x.endswith('%'):
|
||||
try:
|
||||
return float(x.rstrip('%'))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def convert_width(tag_style):
|
||||
if tag_style is not None:
|
||||
w = tag_style._get('width')
|
||||
wp = as_percent(w)
|
||||
if w == 'auto':
|
||||
return ('auto', 0)
|
||||
elif wp is not None:
|
||||
return ('pct', int(wp * 50))
|
||||
else:
|
||||
try:
|
||||
return ('dxa', int(float(tag_style['width']) * 20))
|
||||
except Exception:
|
||||
pass
|
||||
return ('auto', 0)
|
||||
|
||||
class Cell(object):
|
||||
|
||||
def __init__(self, html_tag, tag_style):
|
||||
def __init__(self, row, html_tag, tag_style):
|
||||
self.row = row
|
||||
self.html_tag = html_tag
|
||||
self.items = []
|
||||
self.width = convert_width(tag_style)
|
||||
self.background_color = None if tag_style is None else convert_color(tag_style.backgroundColor)
|
||||
|
||||
def add_block(self, block):
|
||||
self.items.append(block)
|
||||
@ -23,18 +49,28 @@ class Cell(object):
|
||||
|
||||
def serialize(self, parent):
|
||||
tc = makeelement(parent, 'w:tc')
|
||||
tcPr = makeelement(tc, 'w:tcPr')
|
||||
makeelement(tcPr, 'w:tcW', w_type=self.width[0], w_w=str(self.width[1]))
|
||||
# For some reason, Word 2007 refuses to honor <w:shd> at the table or row
|
||||
# level, despite what the specs say, so we inherit and apply at the
|
||||
# cell level
|
||||
bc = self.background_color or self.row.background_color or self.row.table.background_color
|
||||
if bc:
|
||||
makeelement(tcPr, 'w:shd', w_val="clear", w_color="auto", w_fill=bc)
|
||||
for item in self.items:
|
||||
item.serialize(tc)
|
||||
|
||||
class Row(object):
|
||||
|
||||
def __init__(self, html_tag, tag_style=None):
|
||||
def __init__(self, table, html_tag, tag_style=None):
|
||||
self.table = table
|
||||
self.html_tag = html_tag
|
||||
self.cells = []
|
||||
self.current_cell = None
|
||||
self.background_color = None if tag_style is None else convert_color(tag_style.backgroundColor)
|
||||
|
||||
def start_new_cell(self, html_tag, tag_style):
|
||||
self.current_cell = Cell(html_tag, tag_style)
|
||||
self.current_cell = Cell(self, html_tag, tag_style)
|
||||
|
||||
def finish_tag(self, html_tag):
|
||||
if self.current_cell is not None:
|
||||
@ -50,6 +86,9 @@ class Row(object):
|
||||
|
||||
def serialize(self, parent):
|
||||
tr = makeelement(parent, 'w:tr')
|
||||
tblPrEx = makeelement(tr, 'w:tblPrEx')
|
||||
if len(tblPrEx) == 0:
|
||||
tr.remove(tblPrEx)
|
||||
for cell in self.cells:
|
||||
cell.serialize(tr)
|
||||
|
||||
@ -59,6 +98,13 @@ class Table(object):
|
||||
self.html_tag = html_tag
|
||||
self.rows = []
|
||||
self.current_row = None
|
||||
self.width = convert_width(tag_style)
|
||||
self.background_color = None if tag_style is None else convert_color(tag_style.backgroundColor)
|
||||
self.jc = None
|
||||
if tag_style is not None:
|
||||
ml, mr = tag_style._get('margin-left'), tag_style.get('margin-right')
|
||||
if ml == 'auto':
|
||||
self.jc = 'center' if mr == 'auto' else 'right'
|
||||
|
||||
def finish_tag(self, html_tag):
|
||||
if self.current_row is not None:
|
||||
@ -72,7 +118,7 @@ class Table(object):
|
||||
def start_new_row(self, html_tag, html_style):
|
||||
if self.current_row is not None:
|
||||
self.rows.append(self.current_row)
|
||||
self.current_row = Row(html_tag, html_style)
|
||||
self.current_row = Row(self, html_tag, html_style)
|
||||
|
||||
def start_new_cell(self, html_tag, html_style):
|
||||
if self.current_row is None:
|
||||
@ -91,6 +137,8 @@ class Table(object):
|
||||
return
|
||||
tbl = makeelement(parent, 'w:tbl')
|
||||
tblPr = makeelement(tbl, 'w:tblPr')
|
||||
tblPr
|
||||
makeelement(tblPr, 'w:tblW', w_type=self.width[0], w_w=str(self.width[1]))
|
||||
if self.jc is not None:
|
||||
makeelement(tblPr, 'w:jc', w_val=self.jc)
|
||||
for row in rows:
|
||||
row.serialize(tbl)
|
||||
|
Loading…
x
Reference in New Issue
Block a user