From 8bc65df29a4914156b6aef2ee21e9f0328906bc3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 15 Jun 2013 10:07:07 +0530 Subject: [PATCH] DOCX Input: Add support for contextual spacing DOCX Input: Add support for the Word setting "No space between paragraphs with the same style". Fixes #1191001 [docx conversion bug](https://bugs.launchpad.net/calibre/+bug/1191001) --- src/calibre/ebooks/docx/styles.py | 14 ++++++++++++++ src/calibre/ebooks/docx/to_html.py | 11 +++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/calibre/ebooks/docx/styles.py b/src/calibre/ebooks/docx/styles.py index 8e4d811803..3888496e5a 100644 --- a/src/calibre/ebooks/docx/styles.py +++ b/src/calibre/ebooks/docx/styles.py @@ -260,6 +260,7 @@ class Styles(object): for attr in ans.all_properties: if not (is_numbering and attr == 'text_indent'): # skip text-indent for lists setattr(ans, attr, self.para_val(parent_styles, direct_formatting, attr)) + ans.linked_style = direct_formatting.linked_style return ans def resolve_run(self, r): @@ -389,6 +390,19 @@ class Styles(object): else: ps.numbering = (ps.numbering[0], lvl) + def apply_contextual_spacing(self, paras): + last_para = None + for p in paras: + if last_para is not None: + ls = self.resolve_paragraph(last_para) + ps = self.resolve_paragraph(p) + if ls.linked_style is not None and ls.linked_style == ps.linked_style: + if ls.contextualSpacing: + ls.margin_bottom = 0 + if ps.contextualSpacing: + ps.margin_top = 0 + last_para = p + def register(self, css, prefix): h = hash(frozenset(css.iteritems())) ans, _ = self.classes.get(h, (None, None)) diff --git a/src/calibre/ebooks/docx/to_html.py b/src/calibre/ebooks/docx/to_html.py index ad26f91d46..bc8336d768 100644 --- a/src/calibre/ebooks/docx/to_html.py +++ b/src/calibre/ebooks/docx/to_html.py @@ -86,6 +86,7 @@ class Convert(object): self.framed_map = {} self.anchor_map = {} self.link_map = defaultdict(list) + paras = [] self.log.debug('Converting Word markup to HTML') self.read_page_properties(doc) @@ -94,6 +95,8 @@ class Convert(object): if wp.tag.endswith('}p'): p = self.convert_p(wp) self.body.append(p) + paras.append(wp) + self.styles.apply_contextual_spacing(paras) notes_header = None if self.footnotes.has_notes: @@ -107,12 +110,16 @@ class Convert(object): dl.append(DT('[', A('←' + text, href='#back_%s' % anchor, title=text), id=anchor)) dl[-1][0].tail = ']' dl.append(DD()) + paras = [] for wp in note: if wp.tag.endswith('}tbl'): self.tables.register(wp, self.styles) self.page_map[wp] = self.current_page - p = self.convert_p(wp) - dl[-1].append(p) + else: + p = self.convert_p(wp) + dl[-1].append(p) + paras.append(wp) + self.styles.apply_contextual_spacing(paras) self.resolve_links(relationships_by_id)