Fix #2595 (Lost scene-breaks (<br/> tags) in epub book)

This commit is contained in:
Kovid Goyal 2009-07-06 11:07:27 -06:00
parent 68afc75c4d
commit befdf2208d

View File

@ -17,6 +17,34 @@ from calibre.customize.conversion import OptionRecommendation
from lxml import etree from lxml import etree
block_level_tags = (
'address',
'body',
'blockquote',
'center',
'dir',
'div',
'dl',
'fieldset',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'hr',
'isindex',
'menu',
'noframes',
'noscript',
'ol',
'p',
'pre',
'table',
'ul',
)
class EPUBOutput(OutputFormatPlugin): class EPUBOutput(OutputFormatPlugin):
@ -217,39 +245,41 @@ class EPUBOutput(OutputFormatPlugin):
Perform various markup transforms to get the output to render correctly Perform various markup transforms to get the output to render correctly
in the quirky ADE. in the quirky ADE.
''' '''
from calibre.ebooks.oeb.base import XPNSMAP, XHTML, OEB_STYLES from calibre.ebooks.oeb.base import XPath, XHTML, OEB_STYLES, barename
from lxml.etree import XPath as _XPath
from functools import partial
XPath = partial(_XPath, namespaces=XPNSMAP)
for x in self.oeb.spine: for x in self.oeb.spine:
root = x.data root = x.data
body = XPath('//h:body')(root) body = XPath('//h:body')(root)
if body: if body:
body = body[0] body = body[0]
# Replace <br> that are children of <body> as ADE doesn't handle them # Replace <br> that are children of <body> as ADE doesn't handle them
if hasattr(body, 'xpath'): if hasattr(body, 'xpath'):
for br in XPath('./h:br')(body): for br in XPath('./h:br')(body):
if br.getparent() is None: if br.getparent() is None:
continue continue
try: try:
sibling = br.itersiblings().next() prior = br.itersiblings(preceding=True).next()
priortag = barename(prior.tag)
priortext = prior.tail
except: except:
sibling = None priortag = 'body'
priortext = body.text
if priortext:
priortext = priortext.strip()
br.tag = XHTML('p') br.tag = XHTML('p')
br.text = u'\u00a0' br.text = u'\u00a0'
if (br.tail and br.tail.strip()) or sibling is None or \
getattr(sibling, 'tag', '') != XHTML('br'):
style = br.get('style', '').split(';') style = br.get('style', '').split(';')
style = filter(None, map(lambda x: x.strip(), style)) style = filter(None, map(lambda x: x.strip(), style))
style.append('margin: 0pt; border:0pt; height:0pt') style.append('margin:0pt; border:0pt')
br.set('style', '; '.join(style)) # If the prior tag is a block (including a <br> we replaced)
# then this <br> replacement should have a 1-line height.
# Otherwise it should have no height.
if not priortext and priortag in block_level_tags:
style.append('height:1em')
else: else:
sibling.getparent().remove(sibling) style.append('height:0pt')
if sibling.tail: br.set('style', '; '.join(style))
if not br.tail:
br.tail = ''
br.tail += sibling.tail
for tag in XPath('//h:embed')(root): for tag in XPath('//h:embed')(root):
tag.getparent().remove(tag) tag.getparent().remove(tag)