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:
Kovid Goyal 2017-05-04 13:47:46 +05:30
parent 3b7275d9e2
commit d690bf2aa4
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 25 additions and 8 deletions

View File

@ -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

View File

@ -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):