mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
DOCX Output: Proper handling of inheritance for border/padding CSS properties
This commit is contained in:
parent
bf152707b3
commit
8d7a936cec
@ -98,8 +98,8 @@ class Block(object):
|
||||
self.keep_next = False
|
||||
self.runs = []
|
||||
|
||||
def add_text(self, text, style, ignore_leading_whitespace=False, html_parent=None):
|
||||
ts = self.styles_manager.create_text_style(style)
|
||||
def add_text(self, text, style, ignore_leading_whitespace=False, html_parent=None, is_parent_style=False):
|
||||
ts = self.styles_manager.create_text_style(style, is_parent_style=is_parent_style)
|
||||
ws = style['white-space']
|
||||
if self.runs and ts == self.runs[-1].style:
|
||||
run = self.runs[-1]
|
||||
@ -178,7 +178,7 @@ class Convert(object):
|
||||
if block_style.is_hidden:
|
||||
return
|
||||
if html_block.text:
|
||||
docx_block.add_text(html_block.text, block_style, ignore_leading_whitespace=True)
|
||||
docx_block.add_text(html_block.text, block_style, ignore_leading_whitespace=True, is_parent_style=True)
|
||||
|
||||
for child in html_block.iterchildren(etree.Element):
|
||||
tag = barename(child.tag)
|
||||
@ -198,7 +198,7 @@ class Convert(object):
|
||||
if b is not self.blocks[-1]:
|
||||
b = Block(self.styles_manager, html_block, block_style)
|
||||
self.blocks.append(b)
|
||||
b.add_text(html_block.tail, stylizer.style(html_block.getparent()))
|
||||
b.add_text(html_block.tail, stylizer.style(html_block.getparent()), is_parent_style=True)
|
||||
if block_style['page-break-after'] == 'avoid':
|
||||
self.blocks[-1].keep_next = True
|
||||
|
||||
@ -226,7 +226,7 @@ class Convert(object):
|
||||
self.process_inline(child, self.blocks[-1], stylizer)
|
||||
|
||||
if html_child.tail:
|
||||
self.blocks[-1].add_text(html_child.tail, stylizer.style(html_child.getparent()), html_parent=html_child.getparent())
|
||||
self.blocks[-1].add_text(html_child.tail, stylizer.style(html_child.getparent()), html_parent=html_child.getparent(), is_parent_style=True)
|
||||
|
||||
def write(self):
|
||||
dn = {k:v for k, v in namespaces.iteritems() if k in {'w', 'r', 'm', 've', 'o', 'wp', 'w10', 'wne'}}
|
||||
|
@ -123,7 +123,7 @@ class TextStyle(DOCXStyle):
|
||||
x%edge for edge in border_edges for x in border_props)
|
||||
TYPE = 'character'
|
||||
|
||||
def __init__(self, css):
|
||||
def __init__(self, css, is_parent_style=False):
|
||||
self.font_family = css_font_family_to_docx(css['font-family'])
|
||||
try:
|
||||
self.font_size = max(0, int(float(css['font-size']) * 2)) # stylizer normalizes all font sizes into pts
|
||||
@ -134,7 +134,7 @@ class TextStyle(DOCXStyle):
|
||||
self.bold = fw.lower() in {'bold', 'bolder'} or int_or_zero(fw) >= 700
|
||||
self.italic = css['font-style'].lower() in {'italic', 'oblique'}
|
||||
self.color = convert_color(css['color'])
|
||||
self.background_color = convert_color(css.backgroundColor)
|
||||
self.background_color = None if is_parent_style else convert_color(css.backgroundColor)
|
||||
td = set((css.effective_text_decoration or '').split())
|
||||
self.underline = 'underline' in td
|
||||
self.dstrike = 'line-through' in td and 'overline' in td
|
||||
@ -149,12 +149,18 @@ class TextStyle(DOCXStyle):
|
||||
self.spacing = None
|
||||
self.vertical_align = css['vertical-align']
|
||||
for edge in border_edges:
|
||||
# In DOCX padding can only be a positive integer
|
||||
setattr(self, 'padding_' + edge, max(0, int(css['padding-' + edge])))
|
||||
val = min(96, max(2, int({'thin':0.2, 'medium':1, 'thick':2}.get(css['border-%s-width' % edge], 0) * 8)))
|
||||
setattr(self, 'border_%s_width' % edge, val)
|
||||
setattr(self, 'border_%s_color' % edge, convert_color(css['border-%s-color' % edge]))
|
||||
setattr(self, 'border_%s_style' % edge, LINE_STYLES.get(css['border-%s-style' % edge].lower(), 'none'))
|
||||
if is_parent_style:
|
||||
setattr(self, 'padding_' + edge, 0)
|
||||
setattr(self, 'border_%s_width' % edge, 0)
|
||||
setattr(self, 'border_%s_color' % edge, None)
|
||||
setattr(self, 'border_%s_style' % edge, 'none')
|
||||
else:
|
||||
# In DOCX padding can only be a positive integer
|
||||
setattr(self, 'padding_' + edge, max(0, int(css['padding-' + edge])))
|
||||
val = min(96, max(2, int({'thin':0.2, 'medium':1, 'thick':2}.get(css['border-%s-width' % edge], 0) * 8)))
|
||||
setattr(self, 'border_%s_width' % edge, val)
|
||||
setattr(self, 'border_%s_color' % edge, convert_color(css['border-%s-color' % edge]))
|
||||
setattr(self, 'border_%s_style' % edge, LINE_STYLES.get(css['border-%s-style' % edge].lower(), 'none'))
|
||||
|
||||
DOCXStyle.__init__(self)
|
||||
|
||||
@ -331,8 +337,8 @@ class StylesManager(object):
|
||||
def __init__(self):
|
||||
self.block_styles, self.text_styles = {}, {}
|
||||
|
||||
def create_text_style(self, css_style):
|
||||
ans = TextStyle(css_style)
|
||||
def create_text_style(self, css_style, is_parent_style=False):
|
||||
ans = TextStyle(css_style, is_parent_style=is_parent_style)
|
||||
existing = self.text_styles.get(ans, None)
|
||||
if existing is None:
|
||||
self.text_styles[ans] = ans
|
||||
|
Loading…
x
Reference in New Issue
Block a user