mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
FB2 Input: Implement handling of stylesheets and style attributes on <p> tags. Fixes #7219 (FB2 → EPUB without styles)
This commit is contained in:
parent
7603f5b51c
commit
58863d0880
@ -30,23 +30,40 @@
|
||||
<title>
|
||||
<xsl:value-of select="fb:description/fb:title-info/fb:book-title"/>
|
||||
</title>
|
||||
<style type="text/x-oeb1-css">
|
||||
A { color : #0002CC }
|
||||
A:HOVER { color : #BF0000 }
|
||||
BODY { background-color : #FEFEFE; color : #000000; font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; text-align : justify }
|
||||
H1{ font-size : 160%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Black; background-color : #E7E7E7; margin-left : 0px; page-break-before : always; }
|
||||
H2{ font-size : 130%; font-style : normal; font-weight : bold; text-align : left; background-color : #EEEEEE; border : 1px solid Gray; page-break-before : always; }
|
||||
H3{ font-size : 110%; font-style : normal; font-weight : bold; text-align : left; background-color : #F1F1F1; border : 1px solid Silver;}
|
||||
H4{ font-size : 100%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
|
||||
H5{ font-size : 100%; font-style : italic; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
|
||||
H6{ font-size : 100%; font-style : italic; font-weight : normal; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
|
||||
SMALL{ font-size : 80% }
|
||||
BLOCKQUOTE{ margin-left :4em; margin-top:1em; margin-right:0.2em;}
|
||||
HR{ color : Black }
|
||||
DIV{font-family : "Times New Roman", Times, serif; text-align : justify}
|
||||
UL{margin-left: 0}
|
||||
.epigraph{width:50%; margin-left : 35%;}
|
||||
<style type="text/css">
|
||||
a { color : #0002CC }
|
||||
|
||||
a:hover { color : #BF0000 }
|
||||
|
||||
body { background-color : #FEFEFE; color : #000000; font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; text-align : justify }
|
||||
|
||||
h1{ font-size : 160%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Black; background-color : #E7E7E7; margin-left : 0px; page-break-before : always; }
|
||||
|
||||
h2{ font-size : 130%; font-style : normal; font-weight : bold; text-align : left; background-color : #EEEEEE; border : 1px solid Gray; page-break-before : always; }
|
||||
|
||||
h3{ font-size : 110%; font-style : normal; font-weight : bold; text-align : left; background-color : #F1F1F1; border : 1px solid Silver;}
|
||||
|
||||
h4{ font-size : 100%; font-style : normal; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
|
||||
|
||||
h5{ font-size : 100%; font-style : italic; font-weight : bold; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
|
||||
|
||||
h6{ font-size : 100%; font-style : italic; font-weight : normal; text-align : left; border : 1px solid Gray; background-color : #F4F4F4;}
|
||||
|
||||
small { font-size : 80% }
|
||||
|
||||
blockquote { margin-left :4em; margin-top:1em; margin-right:0.2em;}
|
||||
|
||||
hr { color : Black }
|
||||
|
||||
div {font-family : "Times New Roman", Times, serif; text-align : justify}
|
||||
|
||||
ul {margin-left: 0}
|
||||
|
||||
.epigraph{width:50%; margin-left : 35%;}
|
||||
|
||||
div.paragraph { text-align: justify; text-indent: 2em; }
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="inline-styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<xsl:for-each select="fb:description/fb:title-info/fb:annotation">
|
||||
@ -136,12 +153,13 @@
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:if test="$section_has_title = 'None'">
|
||||
<a name="TOC_{generate-id()}" />
|
||||
<xsl:if test="@id">
|
||||
<xsl:element name="a">
|
||||
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
|
||||
</xsl:element>
|
||||
</xsl:if>
|
||||
<div id="TOC_{generate-id()}">
|
||||
<xsl:if test="@id">
|
||||
<xsl:element name="a">
|
||||
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
|
||||
</xsl:element>
|
||||
</xsl:if>
|
||||
</div>
|
||||
</xsl:if>
|
||||
<xsl:apply-templates>
|
||||
<xsl:with-param name="section_toc_id" select="$section_has_title" />
|
||||
@ -207,11 +225,18 @@
|
||||
</xsl:template>
|
||||
<!-- p -->
|
||||
<xsl:template match="fb:p">
|
||||
<div align="justify"><xsl:if test="@id">
|
||||
<xsl:element name="div">
|
||||
<xsl:attribute name="class">paragraph</xsl:attribute>
|
||||
<xsl:if test="@id">
|
||||
<xsl:element name="a">
|
||||
<xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
|
||||
</xsl:element>
|
||||
</xsl:if>    <xsl:apply-templates/></div>
|
||||
</xsl:if>
|
||||
<xsl:if test="@style">
|
||||
<xsl:attribute name="style"><xsl:value-of select="@style"/></xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
<!-- strong -->
|
||||
<xsl:template match="fb:strong">
|
||||
|
@ -40,7 +40,7 @@ class FB2Input(InputFormatPlugin):
|
||||
accelerators):
|
||||
from calibre.ebooks.metadata.opf2 import OPFCreator
|
||||
from calibre.ebooks.metadata.meta import get_metadata
|
||||
from calibre.ebooks.oeb.base import XLINK_NS
|
||||
from calibre.ebooks.oeb.base import XLINK_NS, XHTML_NS
|
||||
NAMESPACES = {'f':FB2NS, 'l':XLINK_NS}
|
||||
log.debug('Parsing XML...')
|
||||
raw = stream.read()
|
||||
@ -48,6 +48,23 @@ class FB2Input(InputFormatPlugin):
|
||||
doc = etree.fromstring(raw.replace('\0', ''))
|
||||
except etree.XMLSyntaxError:
|
||||
doc = etree.fromstring(raw.replace('& ', '&'))
|
||||
stylesheets = doc.xpath('//*[local-name() = "stylesheet" and @type="text/css"]')
|
||||
css = ''
|
||||
for s in stylesheets:
|
||||
css += etree.tostring(s, encoding=unicode, method='text',
|
||||
with_tail=False) + '\n\n'
|
||||
if css:
|
||||
import cssutils, logging
|
||||
parser = cssutils.CSSParser(fetcher=None,
|
||||
log=logging.getLogger('calibre.css'))
|
||||
|
||||
XHTML_CSS_NAMESPACE = '@namespace "%s";\n' % XHTML_NS
|
||||
text = XHTML_CSS_NAMESPACE + css
|
||||
log.debug('Parsing stylesheet...')
|
||||
stylesheet = parser.parseString(text)
|
||||
stylesheet.namespaces['h'] = XHTML_NS
|
||||
css = unicode(stylesheet.cssText).replace('h|style', 'h|span')
|
||||
css = re.sub(r'name\s*=\s*', 'class=', css)
|
||||
self.extract_embedded_content(doc)
|
||||
log.debug('Converting XML to HTML...')
|
||||
ss = open(P('templates/fb2.xsl'), 'rb').read()
|
||||
@ -63,7 +80,9 @@ class FB2Input(InputFormatPlugin):
|
||||
for img in result.xpath('//img[@src]'):
|
||||
src = img.get('src')
|
||||
img.set('src', self.binary_map.get(src, src))
|
||||
open('index.xhtml', 'wb').write(transform.tostring(result))
|
||||
index = transform.tostring(result)
|
||||
open('index.xhtml', 'wb').write(index)
|
||||
open('inline-styles.css', 'wb').write(css)
|
||||
stream.seek(0)
|
||||
mi = get_metadata(stream, 'fb2')
|
||||
if not mi.title:
|
||||
|
Loading…
x
Reference in New Issue
Block a user