mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
DOCX Output: When the input document contains paragraphs inside a block with a background color preserve the background color in the resulting paragraphs in the DOCX document. See #1683188 (Losing all bookmarks while converting azw3 files to docx)
This commit is contained in:
parent
3b7275d9e2
commit
d690bf2aa4
@ -135,7 +135,7 @@ class TextRun(object):
|
||||
|
||||
class Block(object):
|
||||
|
||||
def __init__(self, namespace, styles_manager, links_manager, html_block, style, is_table_cell=False, float_spec=None, is_list_item=False):
|
||||
def __init__(self, namespace, styles_manager, links_manager, html_block, style, is_table_cell=False, float_spec=None, is_list_item=False, parent_bg=None):
|
||||
self.namespace = namespace
|
||||
self.bookmarks = set()
|
||||
self.list_tag = (html_block, style) if is_list_item else None
|
||||
@ -148,7 +148,7 @@ class Block(object):
|
||||
if float_spec is not None:
|
||||
float_spec.blocks.append(self)
|
||||
self.html_style = style
|
||||
self.style = styles_manager.create_block_style(style, html_block, is_table_cell=is_table_cell)
|
||||
self.style = styles_manager.create_block_style(style, html_block, is_table_cell=is_table_cell, parent_bg=parent_bg)
|
||||
self.styles_manager, self.links_manager = styles_manager, links_manager
|
||||
self.keep_next = False
|
||||
self.runs = []
|
||||
@ -278,10 +278,19 @@ class Blocks(object):
|
||||
self.current_block = None
|
||||
|
||||
def start_new_block(self, html_block, style, is_table_cell=False, float_spec=None, is_list_item=False):
|
||||
parent_bg = None
|
||||
if html_block is not None:
|
||||
p = html_block.getparent()
|
||||
b = self.html_tag_start_blocks.get(p)
|
||||
if b is not None:
|
||||
ps = self.styles_manager.styles_for_html_blocks.get(p)
|
||||
if ps is not None and ps.background_color is not None:
|
||||
parent_bg = ps.background_color
|
||||
self.end_current_block()
|
||||
self.current_block = Block(
|
||||
self.namespace, self.styles_manager, self.links_manager, html_block, style,
|
||||
is_table_cell=is_table_cell, float_spec=float_spec, is_list_item=is_list_item)
|
||||
is_table_cell=is_table_cell, float_spec=float_spec, is_list_item=is_list_item,
|
||||
parent_bg=parent_bg)
|
||||
self.html_tag_start_blocks[html_block] = self.current_block
|
||||
self.open_html_blocks.add(html_block)
|
||||
return self.current_block
|
||||
|
@ -147,10 +147,13 @@ class DOCXStyle(object):
|
||||
def __init__(self, namespace):
|
||||
self.namespace = namespace
|
||||
self.w = lambda x: '{%s}%s' % (namespace.namespaces['w'], x)
|
||||
self._hash = hash(tuple(
|
||||
getattr(self, x) for x in self.ALL_PROPS))
|
||||
self.id = self.name = None
|
||||
self.next_style = None
|
||||
self.calculate_hash()
|
||||
|
||||
def calculate_hash(self):
|
||||
self._hash = hash(tuple(
|
||||
getattr(self, x) for x in self.ALL_PROPS))
|
||||
|
||||
def makeelement(self, parent, name, **attrs):
|
||||
return parent.makeelement(self.w(name), **{self.w(k):v for k, v in attrs.iteritems()})
|
||||
@ -180,6 +183,7 @@ class DOCXStyle(object):
|
||||
styles.append(style)
|
||||
return style
|
||||
|
||||
|
||||
LINE_STYLES = {
|
||||
'none' : 'none',
|
||||
'hidden': 'none',
|
||||
@ -481,7 +485,7 @@ class BlockStyle(DOCXStyle):
|
||||
[x%edge for edge in border_edges for x in border_props]
|
||||
)
|
||||
|
||||
def __init__(self, namespace, css, html_block, is_table_cell=False):
|
||||
def __init__(self, namespace, css, html_block, is_table_cell=False, parent_bg=None):
|
||||
read_css_block_borders(self, css)
|
||||
if is_table_cell:
|
||||
for edge in border_edges:
|
||||
@ -507,6 +511,8 @@ class BlockStyle(DOCXStyle):
|
||||
except (TypeError, ValueError):
|
||||
self.line_height = max(0, int(1.2 * css.fontSize * 20))
|
||||
self.background_color = None if is_table_cell else convert_color(css['background-color'])
|
||||
if not is_table_cell and self.background_color is None:
|
||||
self.background_color = parent_bg
|
||||
try:
|
||||
self.text_align = {'start':'left', 'left':'left', 'end':'right', 'right':'right', 'center':'center', 'justify':'both', 'centre':'center'}.get(
|
||||
css['text-align'].lower(), 'left')
|
||||
@ -623,6 +629,7 @@ class StylesManager(object):
|
||||
self.document_lang = lang_as_iso639_1(document_lang) or 'en'
|
||||
self.log = log
|
||||
self.block_styles, self.text_styles = {}, {}
|
||||
self.styles_for_html_blocks = {}
|
||||
|
||||
def create_text_style(self, css_style, is_parent_style=False):
|
||||
ans = TextStyle(self.namespace, css_style, is_parent_style=is_parent_style)
|
||||
@ -633,13 +640,14 @@ class StylesManager(object):
|
||||
ans = existing
|
||||
return ans
|
||||
|
||||
def create_block_style(self, css_style, html_block, is_table_cell=False):
|
||||
ans = BlockStyle(self.namespace, css_style, html_block, is_table_cell=is_table_cell)
|
||||
def create_block_style(self, css_style, html_block, is_table_cell=False, parent_bg=None):
|
||||
ans = BlockStyle(self.namespace, css_style, html_block, is_table_cell=is_table_cell, parent_bg=parent_bg)
|
||||
existing = self.block_styles.get(ans, None)
|
||||
if existing is None:
|
||||
self.block_styles[ans] = ans
|
||||
else:
|
||||
ans = existing
|
||||
self.styles_for_html_blocks[html_block] = ans
|
||||
return ans
|
||||
|
||||
def finalize(self, all_blocks):
|
||||
|
Loading…
x
Reference in New Issue
Block a user