diff --git a/src/calibre/ebooks/rtf/xsl.py b/resources/templates/rtf.xsl similarity index 71% rename from src/calibre/ebooks/rtf/xsl.py rename to resources/templates/rtf.xsl index be58683958..7d633a0038 100644 --- a/src/calibre/ebooks/rtf/xsl.py +++ b/resources/templates/rtf.xsl @@ -1,27 +1,10 @@ -######################################################################### -# # -# # -# copyright 2002 Paul Henry Tremblay # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # -# General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program; if not, write to the Free Software # -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA # -# 02111-1307 USA # -# # -# # -######################################################################### - -xhtml = '''\ @@ -147,7 +130,7 @@ xhtml = '''\ generator - http://rtf2xml.sourceforge.net/ + http://calibre-ebook.com @@ -233,9 +216,7 @@ xhtml = '''\ span.italic-bold{font-style:italic;font-weight:bold} span.italic-underline{font-style:italic;text-decoration:underline} span.bold-underline{font-weight:bold;text-decoration:underline} - - - + @@ -287,52 +268,6 @@ xhtml = '''\ - - - - - - - - - - - span. - - { - - font-style:italic; - - - font-style:normal; - - - font-weight:bold; - - - font-weight:normal; - - - text-decoration:underline; - - - text-decoration:none; - - - text-decoration:line-through; - - - text-decoration:none; - - - font-size: - - pt; - - } - - - @@ -345,45 +280,7 @@ xhtml = '''\ - - - italic - - - no-italic - - - bold - - - bold - - - no-bold - - - - - underline - - - no-underline - - - - - italic-bold - - - italic-underline - - - bold-underline - - - - - + @@ -539,4 +436,3 @@ xhtml = '''\ -''' diff --git a/src/calibre/ebooks/rtf/input.py b/src/calibre/ebooks/rtf/input.py index 51e6862e7b..e1c1fd4a22 100644 --- a/src/calibre/ebooks/rtf/input.py +++ b/src/calibre/ebooks/rtf/input.py @@ -2,12 +2,48 @@ from __future__ import with_statement __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -import os, glob, re +import os, glob, re, textwrap from lxml import etree from calibre.customize.conversion import InputFormatPlugin +class InlineClass(etree.XSLTExtension): + + FMTS = ('italics', 'bold', 'underlined', 'strike-through', 'small-caps') + + def __init__(self, log): + etree.XSLTExtension.__init__(self) + self.log = log + self.font_sizes = [] + self.colors = [] + + def execute(self, context, self_node, input_node, output_parent): + classes = [] + for x in self.FMTS: + cls = x if input_node.get(x, None) == 'true' else 'no-'+x + classes.append(cls) + none = True + for x in self.FMTS: + if 'no-'+x not in classes: + none = False + break + if none: + classes = ['none'] + fs = input_node.get('font-size', False) + if fs: + if fs not in self.font_sizes: + self.font_sizes.append(fs) + classes.append('fs%d'%self.font_sizes.index(fs)) + fc = input_node.get('font-color', False) + if fc: + if fc not in self.colors: + self.colors.append(fc) + classes.append('col%d'%self.colors.index(fc)) + + output_parent.text = ' '.join(classes) + + class RTFInput(InputFormatPlugin): name = 'RTF Input' @@ -21,15 +57,15 @@ class RTFInput(InputFormatPlugin): parser = ParseRtf( in_file = stream, out_file = ofile, - # Convert symbol fonts to unicode equivelents. Default + # Convert symbol fonts to unicode equivalents. Default # is 1 convert_symbol = 1, - # Convert Zapf fonts to unicode equivelents. Default + # Convert Zapf fonts to unicode equivalents. Default # is 1. convert_zapf = 1, - # Convert Wingding fonts to unicode equivelents. + # Convert Wingding fonts to unicode equivalents. # Default is 1. convert_wingdings = 1, @@ -94,9 +130,41 @@ class RTFInput(InputFormatPlugin): #open(name+'.hex', 'wb').write(enc) return imap + def write_inline_css(self, ic): + font_size_classes = ['span.fs%d { font-size: %spt }'%(i, x) for i, x in + enumerate(ic.font_sizes)] + color_classes = ['span.col%d { color: %s }'%(i, x) for i, x in + enumerate(ic.colors)] + css = textwrap.dedent(''' + span.none { + text-decoration: none; font-weight: normal; + font-style: normal; font-variant: normal + } + + span.italics { font-style: italic } + span.no-italics { font-style: normal } + + span.bold { font-weight: bold } + span.no-bold { font-weight: normal } + + span.small-caps { font-variant: small-caps } + span.no-small-caps { font-variant: normal } + + span.underlined { text-decoration: underline } + span.no-underlined { text-decoration: none } + + span.strike-through { text-decoration: line-through } + span.no-strike-through { text-decoration: none } + + ''') + css += '\n'+'\n'.join(font_size_classes) + css += '\n' +'\n'.join(color_classes) + with open('styles.css', 'ab') as f: + f.write(css) + + def convert(self, stream, options, file_ext, log, accelerators): - from calibre.ebooks.rtf.xsl import xhtml from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.metadata.opf2 import OPFCreator from calibre.ebooks.rtf2xml.ParseRtf import RtfInvalidCodeException @@ -124,15 +192,18 @@ class RTFInput(InputFormatPlugin): if name is not None: pict.set('num', name) self.log('Converting XML to HTML...') - styledoc = etree.fromstring(xhtml) + inline_class = InlineClass(self.log) + styledoc = etree.fromstring(P('templates/rtf.xsl', data=True)) - transform = etree.XSLT(styledoc) + extensions = { ('calibre', 'inline-class') : inline_class } + transform = etree.XSLT(styledoc, extensions=extensions) result = transform(doc) html = 'index.xhtml' with open(html, 'wb') as f: res = transform.tostring(result) res = res[:100].replace('xmlns:html', 'xmlns') + res[100:] f.write(res) + self.write_inline_css(inline_class) stream.seek(0) mi = get_metadata(stream, 'rtf') if not mi.title: