mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -04:00
MOBI Output: Conversion of super/sub scripts now handles nested tags. Fixes #7264 (Superscripts may not be correctly converted from HTML/epub/odt to MOBI)
This commit is contained in:
parent
c1dc4ad09d
commit
7603f5b51c
@ -27,6 +27,8 @@ TABLE_TAGS = set(['table', 'tr', 'td', 'th', 'caption'])
|
|||||||
SPECIAL_TAGS = set(['hr', 'br'])
|
SPECIAL_TAGS = set(['hr', 'br'])
|
||||||
CONTENT_TAGS = set(['img', 'hr', 'br'])
|
CONTENT_TAGS = set(['img', 'hr', 'br'])
|
||||||
|
|
||||||
|
NOT_VTAGS = HEADER_TAGS | NESTABLE_TAGS | TABLE_TAGS | SPECIAL_TAGS | \
|
||||||
|
CONTENT_TAGS
|
||||||
PAGE_BREAKS = set(['always', 'left', 'right'])
|
PAGE_BREAKS = set(['always', 'left', 'right'])
|
||||||
|
|
||||||
COLLAPSE = re.compile(r'[ \t\r\n\v]+')
|
COLLAPSE = re.compile(r'[ \t\r\n\v]+')
|
||||||
@ -57,8 +59,6 @@ class FormatState(object):
|
|||||||
self.indent = 0.
|
self.indent = 0.
|
||||||
self.fsize = 3
|
self.fsize = 3
|
||||||
self.ids = set()
|
self.ids = set()
|
||||||
self.valign = 'baseline'
|
|
||||||
self.nest = False
|
|
||||||
self.italic = False
|
self.italic = False
|
||||||
self.bold = False
|
self.bold = False
|
||||||
self.strikethrough = False
|
self.strikethrough = False
|
||||||
@ -76,7 +76,6 @@ class FormatState(object):
|
|||||||
and self.italic == other.italic \
|
and self.italic == other.italic \
|
||||||
and self.bold == other.bold \
|
and self.bold == other.bold \
|
||||||
and self.href == other.href \
|
and self.href == other.href \
|
||||||
and self.valign == other.valign \
|
|
||||||
and self.preserve == other.preserve \
|
and self.preserve == other.preserve \
|
||||||
and self.family == other.family \
|
and self.family == other.family \
|
||||||
and self.bgcolor == other.bgcolor \
|
and self.bgcolor == other.bgcolor \
|
||||||
@ -224,7 +223,6 @@ class MobiMLizer(object):
|
|||||||
return
|
return
|
||||||
if not pstate or istate != pstate:
|
if not pstate or istate != pstate:
|
||||||
inline = para
|
inline = para
|
||||||
valign = istate.valign
|
|
||||||
fsize = istate.fsize
|
fsize = istate.fsize
|
||||||
href = istate.href
|
href = istate.href
|
||||||
if not href:
|
if not href:
|
||||||
@ -234,19 +232,8 @@ class MobiMLizer(object):
|
|||||||
else:
|
else:
|
||||||
inline = etree.SubElement(inline, XHTML('a'), href=href)
|
inline = etree.SubElement(inline, XHTML('a'), href=href)
|
||||||
bstate.anchor = inline
|
bstate.anchor = inline
|
||||||
if valign == 'super':
|
|
||||||
parent = inline
|
if fsize != 3:
|
||||||
if istate.nest and bstate.inline is not None:
|
|
||||||
parent = bstate.inline
|
|
||||||
istate.nest = False
|
|
||||||
inline = etree.SubElement(parent, XHTML('sup'))
|
|
||||||
elif valign == 'sub':
|
|
||||||
parent = inline
|
|
||||||
if istate.nest and bstate.inline is not None:
|
|
||||||
parent = bstate.inline
|
|
||||||
istate.nest = False
|
|
||||||
inline = etree.SubElement(parent, XHTML('sub'))
|
|
||||||
elif fsize != 3:
|
|
||||||
inline = etree.SubElement(inline, XHTML('font'),
|
inline = etree.SubElement(inline, XHTML('font'),
|
||||||
size=str(fsize))
|
size=str(fsize))
|
||||||
if istate.family == 'monospace':
|
if istate.family == 'monospace':
|
||||||
@ -279,7 +266,8 @@ class MobiMLizer(object):
|
|||||||
else:
|
else:
|
||||||
inline.append(item)
|
inline.append(item)
|
||||||
|
|
||||||
def mobimlize_elem(self, elem, stylizer, bstate, istates):
|
def mobimlize_elem(self, elem, stylizer, bstate, istates,
|
||||||
|
ignore_valign=False):
|
||||||
if not isinstance(elem.tag, basestring) \
|
if not isinstance(elem.tag, basestring) \
|
||||||
or namespace(elem.tag) != XHTML_NS:
|
or namespace(elem.tag) != XHTML_NS:
|
||||||
return
|
return
|
||||||
@ -351,15 +339,6 @@ class MobiMLizer(object):
|
|||||||
istate.family = 'sans-serif'
|
istate.family = 'sans-serif'
|
||||||
else:
|
else:
|
||||||
istate.family = 'serif'
|
istate.family = 'serif'
|
||||||
valign = style['vertical-align']
|
|
||||||
if valign in ('super', 'text-top') or asfloat(valign) > 0:
|
|
||||||
istate.nest = istate.valign in ('sub', 'super')
|
|
||||||
istate.valign = 'super'
|
|
||||||
elif valign == 'sub' or asfloat(valign) < 0:
|
|
||||||
istate.nest = istate.valign in ('sub', 'super')
|
|
||||||
istate.valign = 'sub'
|
|
||||||
else:
|
|
||||||
istate.valign = 'baseline'
|
|
||||||
if 'id' in elem.attrib:
|
if 'id' in elem.attrib:
|
||||||
istate.ids.add(elem.attrib['id'])
|
istate.ids.add(elem.attrib['id'])
|
||||||
if 'name' in elem.attrib:
|
if 'name' in elem.attrib:
|
||||||
@ -407,6 +386,30 @@ class MobiMLizer(object):
|
|||||||
text = None
|
text = None
|
||||||
else:
|
else:
|
||||||
text = COLLAPSE.sub(' ', elem.text)
|
text = COLLAPSE.sub(' ', elem.text)
|
||||||
|
valign = style['vertical-align']
|
||||||
|
not_baseline = valign in ('super', 'sub', 'text-top',
|
||||||
|
'text-bottom')
|
||||||
|
vtag = 'sup' if valign in ('super', 'text-top') else 'sub'
|
||||||
|
if not_baseline and not ignore_valign and tag not in NOT_VTAGS and not isblock:
|
||||||
|
nroot = etree.Element(XHTML('html'), nsmap=MOBI_NSMAP)
|
||||||
|
vbstate = BlockState(etree.SubElement(nroot, XHTML('body')))
|
||||||
|
vbstate.para = etree.SubElement(vbstate.body, XHTML('p'))
|
||||||
|
self.mobimlize_elem(elem, stylizer, vbstate, istates,
|
||||||
|
ignore_valign=True)
|
||||||
|
if len(istates) > 0:
|
||||||
|
istates.pop()
|
||||||
|
if len(istates) == 0:
|
||||||
|
istates.append(FormatState())
|
||||||
|
at_start = bstate.para is None
|
||||||
|
if at_start:
|
||||||
|
self.mobimlize_content('span', '', bstate, istates)
|
||||||
|
parent = bstate.para if bstate.inline is None else bstate.inline
|
||||||
|
if parent is not None:
|
||||||
|
vtag = etree.SubElement(parent, XHTML(vtag))
|
||||||
|
for child in vbstate.para:
|
||||||
|
vtag.append(child)
|
||||||
|
return
|
||||||
|
|
||||||
if text or tag in CONTENT_TAGS or tag in NESTABLE_TAGS:
|
if text or tag in CONTENT_TAGS or tag in NESTABLE_TAGS:
|
||||||
self.mobimlize_content(tag, text, bstate, istates)
|
self.mobimlize_content(tag, text, bstate, istates)
|
||||||
for child in elem:
|
for child in elem:
|
||||||
@ -421,6 +424,8 @@ class MobiMLizer(object):
|
|||||||
tail = COLLAPSE.sub(' ', child.tail)
|
tail = COLLAPSE.sub(' ', child.tail)
|
||||||
if tail:
|
if tail:
|
||||||
self.mobimlize_content(tag, tail, bstate, istates)
|
self.mobimlize_content(tag, tail, bstate, istates)
|
||||||
|
|
||||||
|
|
||||||
if bstate.content and style['page-break-after'] in PAGE_BREAKS:
|
if bstate.content and style['page-break-after'] in PAGE_BREAKS:
|
||||||
bstate.pbreak = True
|
bstate.pbreak = True
|
||||||
if isblock:
|
if isblock:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user