DOCX Output: Support the <br> tag

This commit is contained in:
Kovid Goyal 2015-02-15 19:10:33 +05:30
parent 97281c4569
commit a30fb54406

View File

@ -41,11 +41,6 @@ class Stylizer(Sz):
return Style(element, self) return Style(element, self)
class LineBreak(object):
def __init__(self, clear='none'):
self.clear = clear
class TextRun(object): class TextRun(object):
ws_pat = None ws_pat = None
@ -67,22 +62,26 @@ class TextRun(object):
self.texts.append((text, preserve_whitespace)) self.texts.append((text, preserve_whitespace))
def add_break(self, clear='none'): def add_break(self, clear='none'):
self.texts.append(LineBreak(clear=clear)) self.texts.append((None, clear))
def serialize(self, p): def serialize(self, p):
r = p.makeelement('{%s}r' % namespaces['w']) r = p.makeelement('{%s}r' % namespaces['w'])
p.append(r) p.append(r)
for text, preserve_whitespace in self.texts: for text, preserve_whitespace in self.texts:
t = r.makeelement('{%s}t' % namespaces['w']) if text is None:
r.append(t) r.append(r.makeelement(w('br'), **{w('clear'):preserve_whitespace}))
t.text = text or '' else:
if preserve_whitespace: t = r.makeelement('{%s}t' % namespaces['w'])
t.set('{http://www.w3.org/XML/1998/namespace}space', 'preserve') r.append(t)
t.text = text or ''
if preserve_whitespace:
t.set('{http://www.w3.org/XML/1998/namespace}space', 'preserve')
class Block(object): class Block(object):
def __init__(self, html_block, style, is_first_block=False): def __init__(self, html_block, style, is_first_block=False):
self.html_block = html_block self.html_block = html_block
self.html_style = style
self.style = BlockStyle(style, html_block, is_first_block=is_first_block) self.style = BlockStyle(style, html_block, is_first_block=is_first_block)
self.runs = [] self.runs = []
@ -104,6 +103,14 @@ class Block(object):
else: else:
run.add_text(text, preserve_whitespace) run.add_text(text, preserve_whitespace)
def add_break(self, clear='none'):
if self.runs:
run = self.runs[-1]
else:
run = TextRun(TextStyle(self.html_style), self.html_block)
self.runs.append(run)
run.add_break(clear=clear)
def serialize(self, body): def serialize(self, body):
p = body.makeelement('{%s}p' % namespaces['w']) p = body.makeelement('{%s}p' % namespaces['w'])
body.append(p) body.append(p)
@ -147,10 +154,10 @@ class Convert(object):
for child in html_block.iterchildren(etree.Element): for child in html_block.iterchildren(etree.Element):
tag = barename(child.tag) tag = barename(child.tag)
style = stylizer.style(child) style = stylizer.style(child)
display = style.get('display', 'inline') display = style._get('display')
if tag == 'img': if tag == 'img':
return # TODO: Handle images pass # TODO: Handle images
if display == 'block': if display == 'block' and tag != 'br':
b = Block(child, style) b = Block(child, style)
self.blocks.append(b) self.blocks.append(b)
self.process_block(child, b, stylizer) self.process_block(child, b, stylizer)
@ -169,19 +176,23 @@ class Convert(object):
style = stylizer.style(html_child) style = stylizer.style(html_child)
if style.is_hidden: if style.is_hidden:
return return
if tag == 'img': if tag == 'br':
if html_child.tail or html_child is not html_child.getparent()[-1]:
docx_block.add_break(clear={'both':'all', 'left':'left', 'right':'right'}.get(style['clear'], 'none'))
elif tag == 'img':
return # TODO: Handle images return # TODO: Handle images
if html_child.text: else:
docx_block.add_text(html_child.text, style, html_parent=html_child) if html_child.text:
for child in html_child.iterchildren(etree.Element): docx_block.add_text(html_child.text, style, html_parent=html_child)
style = stylizer.style(child) for child in html_child.iterchildren(etree.Element):
display = style.get('display', 'inline') style = stylizer.style(child)
if display == 'block': display = style.get('display', 'inline')
b = Block(child, style) if display == 'block':
self.blocks.append(b) b = Block(child, style)
self.process_block(child, b, stylizer) self.blocks.append(b)
else: self.process_block(child, b, stylizer)
self.process_inline(child, self.blocks[-1], stylizer) else:
self.process_inline(child, self.blocks[-1], stylizer)
if html_child.tail: 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())