From ae10633c5835ca2061162441d9809222b7b54d32 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 20 May 2018 11:57:08 +0530 Subject: [PATCH] DOCX Output: Fix
 tags not being converted correctly.
 Fixes #1772219 [fail to keep the original program code format while
 converting](https://bugs.launchpad.net/calibre/+bug/1772219)

---
 src/calibre/ebooks/docx/writer/from_html.py |  8 ++++----
 src/calibre/ebooks/docx/writer/styles.py    | 18 +++++++++++++-----
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/src/calibre/ebooks/docx/writer/from_html.py b/src/calibre/ebooks/docx/writer/from_html.py
index b7039b5f2b..0d509efef7 100644
--- a/src/calibre/ebooks/docx/writer/from_html.py
+++ b/src/calibre/ebooks/docx/writer/from_html.py
@@ -168,19 +168,19 @@ class Block(object):
                 next_block.list_tag = self.list_tag
 
     def add_text(self, text, style, ignore_leading_whitespace=False, html_parent=None, is_parent_style=False, bookmark=None, link=None, lang=None):
-        ts = self.styles_manager.create_text_style(style, is_parent_style=is_parent_style)
         ws = style['white-space']
+        preserve_whitespace = ws in {'pre', 'pre-wrap'}
+        ts = self.styles_manager.create_text_style(style, is_parent_style=is_parent_style)
         if self.runs and ts == self.runs[-1].style and link == self.runs[-1].link and lang == self.runs[-1].lang:
             run = self.runs[-1]
         else:
             run = TextRun(self.namespace, ts, self.html_block if html_parent is None else html_parent, lang=lang)
             self.runs.append(run)
-        preserve_whitespace = ws in {'pre', 'pre-wrap'}
         if ignore_leading_whitespace and not preserve_whitespace:
             text = text.lstrip()
-        if ws == 'pre-line':
+        if preserve_whitespace or ws == 'pre-line':
             for text in text.splitlines():
-                run.add_text(text, False, bookmark=bookmark, link=link)
+                run.add_text(text, preserve_whitespace, bookmark=bookmark, link=link)
                 bookmark = None
                 run.add_break()
         else:
diff --git a/src/calibre/ebooks/docx/writer/styles.py b/src/calibre/ebooks/docx/writer/styles.py
index 396c87b8f4..9c532cdb2f 100644
--- a/src/calibre/ebooks/docx/writer/styles.py
+++ b/src/calibre/ebooks/docx/writer/styles.py
@@ -479,10 +479,10 @@ def read_css_block_borders(self, css, store_css_style=False):
 class BlockStyle(DOCXStyle):
 
     ALL_PROPS = tuple(
-        'text_align css_text_indent text_indent line_height background_color'.split() +
-        ['margin_' + edge for edge in border_edges] +
-        ['css_margin_' + edge for edge in border_edges] +
-        [x%edge for edge in border_edges for x in border_props]
+        'text_align css_text_indent text_indent line_height background_color'.split(
+        ) + ['margin_' + edge for edge in border_edges
+        ] + ['css_margin_' + edge for edge in border_edges
+        ] + [x%edge for edge in border_edges for x in border_props]
     )
 
     def __init__(self, namespace, css, html_block, is_table_cell=False, parent_bg=None):
@@ -514,8 +514,16 @@ class BlockStyle(DOCXStyle):
             if not is_table_cell and self.background_color is None:
                 self.background_color = parent_bg
             try:
+                ws = css['white-space'].lower()
+                preserve_whitespace = ws in {'pre', 'pre-wrap'}
+            except Exception:
+                preserve_whitespace = False
+            try:
+                aval = css['text-align'].lower()
+                if preserve_whitespace:
+                    aval = 'start'
                 self.text_align = {'start':'left', 'left':'left', 'end':'right', 'right':'right', 'center':'center', 'justify':'both', 'centre':'center'}.get(
-                    css['text-align'].lower(), 'left')
+                    aval, 'left')
             except AttributeError:
                 self.text_align = 'left'