mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
MOBI Output: Fix handling of white-space:pre-wrap
MOBI Output: Fix text marked with white-space:pre-wrap causing the Kindle to break lines at arbitrary points inside words. Fixes #1240235 [Private bug](https://bugs.launchpad.net/calibre/+bug/1240235)
This commit is contained in:
parent
c9a88a1a80
commit
f0e64e56a2
@ -75,6 +75,7 @@ class FormatState(object):
|
|||||||
self.strikethrough = False
|
self.strikethrough = False
|
||||||
self.underline = False
|
self.underline = False
|
||||||
self.preserve = False
|
self.preserve = False
|
||||||
|
self.pre_wrap = False
|
||||||
self.family = 'serif'
|
self.family = 'serif'
|
||||||
self.bgcolor = 'transparent'
|
self.bgcolor = 'transparent'
|
||||||
self.fgcolor = 'black'
|
self.fgcolor = 'black'
|
||||||
@ -88,6 +89,7 @@ class FormatState(object):
|
|||||||
and self.bold == other.bold \
|
and self.bold == other.bold \
|
||||||
and self.href == other.href \
|
and self.href == other.href \
|
||||||
and self.preserve == other.preserve \
|
and self.preserve == other.preserve \
|
||||||
|
and self.pre_wrap == other.pre_wrap \
|
||||||
and self.family == other.family \
|
and self.family == other.family \
|
||||||
and self.bgcolor == other.bgcolor \
|
and self.bgcolor == other.bgcolor \
|
||||||
and self.fgcolor == other.fgcolor \
|
and self.fgcolor == other.fgcolor \
|
||||||
@ -136,8 +138,14 @@ class MobiMLizer(object):
|
|||||||
return "%dpt" % int(round(ptsize))
|
return "%dpt" % int(round(ptsize))
|
||||||
return "%dem" % int(round(ptsize / embase))
|
return "%dem" % int(round(ptsize / embase))
|
||||||
|
|
||||||
def preize_text(self, text):
|
def preize_text(self, text, pre_wrap=False):
|
||||||
text = unicode(text).replace(u' ', u'\xa0')
|
text = unicode(text)
|
||||||
|
if pre_wrap:
|
||||||
|
# Replace n consecutive spaces with n-1 NBSP + space
|
||||||
|
text = re.sub(r' {2,}', lambda m:(u'\xa0'*(len(m.group())-1) + u' '), text)
|
||||||
|
else:
|
||||||
|
text = text.replace(u' ', u'\xa0')
|
||||||
|
|
||||||
text = text.replace('\r\n', '\n')
|
text = text.replace('\r\n', '\n')
|
||||||
text = text.replace('\r', '\n')
|
text = text.replace('\r', '\n')
|
||||||
lines = text.split('\n')
|
lines = text.split('\n')
|
||||||
@ -283,7 +291,7 @@ class MobiMLizer(object):
|
|||||||
bstate.inline = inline
|
bstate.inline = inline
|
||||||
bstate.istate = istate
|
bstate.istate = istate
|
||||||
inline = bstate.inline
|
inline = bstate.inline
|
||||||
content = self.preize_text(text) if istate.preserve else [text]
|
content = self.preize_text(text, pre_wrap=istate.pre_wrap) if istate.preserve or istate.pre_wrap else [text]
|
||||||
for item in content:
|
for item in content:
|
||||||
if isinstance(item, basestring):
|
if isinstance(item, basestring):
|
||||||
if len(inline) == 0:
|
if len(inline) == 0:
|
||||||
@ -377,7 +385,8 @@ class MobiMLizer(object):
|
|||||||
istate.italic = True if style['font-style'] == 'italic' else False
|
istate.italic = True if style['font-style'] == 'italic' else False
|
||||||
weight = style['font-weight']
|
weight = style['font-weight']
|
||||||
istate.bold = weight in ('bold', 'bolder') or asfloat(weight) > 400
|
istate.bold = weight in ('bold', 'bolder') or asfloat(weight) > 400
|
||||||
istate.preserve = (style['white-space'] in ('pre', 'pre-wrap'))
|
istate.preserve = style['white-space'] == 'pre'
|
||||||
|
istate.pre_wrap = style['white-space'] == 'pre-wrap'
|
||||||
istate.bgcolor = style['background-color']
|
istate.bgcolor = style['background-color']
|
||||||
istate.fgcolor = style['color']
|
istate.fgcolor = style['color']
|
||||||
istate.strikethrough = style.effective_text_decoration == 'line-through'
|
istate.strikethrough = style.effective_text_decoration == 'line-through'
|
||||||
@ -487,7 +496,7 @@ class MobiMLizer(object):
|
|||||||
elem.tail = u'\u201d' + t
|
elem.tail = u'\u201d' + t
|
||||||
text = None
|
text = None
|
||||||
if elem.text:
|
if elem.text:
|
||||||
if istate.preserve:
|
if istate.preserve or istate.pre_wrap:
|
||||||
text = elem.text
|
text = elem.text
|
||||||
elif (len(elem) > 0 and isspace(elem.text) and hasattr(elem[0].tag, 'rpartition') and
|
elif (len(elem) > 0 and isspace(elem.text) and hasattr(elem[0].tag, 'rpartition') and
|
||||||
elem[0].tag.rpartition('}')[-1] not in INLINE_TAGS):
|
elem[0].tag.rpartition('}')[-1] not in INLINE_TAGS):
|
||||||
@ -545,7 +554,7 @@ class MobiMLizer(object):
|
|||||||
self.mobimlize_elem(child, stylizer, bstate, istates)
|
self.mobimlize_elem(child, stylizer, bstate, istates)
|
||||||
tail = None
|
tail = None
|
||||||
if child.tail:
|
if child.tail:
|
||||||
if istate.preserve:
|
if istate.preserve or istate.pre_wrap:
|
||||||
tail = child.tail
|
tail = child.tail
|
||||||
elif bstate.para is None and isspace(child.tail):
|
elif bstate.para is None and isspace(child.tail):
|
||||||
tail = None
|
tail = None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user