diff --git a/setup/installer/__init__.py b/setup/installer/__init__.py index d0a6cd6fa3..8374f93e38 100644 --- a/setup/installer/__init__.py +++ b/setup/installer/__init__.py @@ -48,7 +48,7 @@ class Push(Command): threads = [] for host in ( r'Owner@winxp:/cygdrive/c/Documents\ and\ Settings/Owner/calibre', - 'kovid@leopard_test:calibre', + 'kovid@ox:calibre', r'kovid@win7:/cygdrive/c/Users/kovid/calibre', ): rcmd = BASE_RSYNC + EXCLUDES + ['.', host] diff --git a/src/calibre/ebooks/oeb/display/__init__.py b/src/calibre/ebooks/oeb/display/__init__.py new file mode 100644 index 0000000000..dd9615356c --- /dev/null +++ b/src/calibre/ebooks/oeb/display/__init__.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2012, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + + + diff --git a/src/calibre/ebooks/oeb/display/webview.py b/src/calibre/ebooks/oeb/display/webview.py new file mode 100644 index 0000000000..efcfe0346c --- /dev/null +++ b/src/calibre/ebooks/oeb/display/webview.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2012, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +import re + +from calibre import guess_type + +class EntityDeclarationProcessor(object): # {{{ + + def __init__(self, html): + self.declared_entities = {} + for match in re.finditer(r']+)>', html): + tokens = match.group(1).split() + if len(tokens) > 1: + self.declared_entities[tokens[0].strip()] = tokens[1].strip().replace('"', '') + self.processed_html = html + for key, val in self.declared_entities.iteritems(): + self.processed_html = self.processed_html.replace('&%s;'%key, val) +# }}} + +def self_closing_sub(match): + tag = match.group(1) + if tag.lower().strip() == 'br': + return match.group() + return '<%s %s>'%(match.group(1), match.group(2), match.group(1)) + +def load_html(path, view, codec='utf-8', mime_type=None, + pre_load_callback=lambda x:None): + from PyQt4.Qt import QUrl, QByteArray + if mime_type is None: + mime_type = guess_type(path)[0] + with open(path, 'rb') as f: + html = f.read().decode(codec, 'replace') + + html = EntityDeclarationProcessor(html).processed_html + has_svg = re.search(r'<[:a-zA-Z]*svg', html) is not None + if 'xhtml' in mime_type: + self_closing_pat = re.compile(r'<([a-z1-6]+)\s+([^>]+)/>', + re.IGNORECASE) + html = self_closing_pat.sub(self_closing_sub, html) + + html = re.sub(ur'<\s*title\s*/\s*>', u'', html, flags=re.IGNORECASE) + loading_url = QUrl.fromLocalFile(path) + pre_load_callback(loading_url) + + if has_svg: + view.setContent(QByteArray(html.encode(codec)), mime_type, + loading_url) + else: + view.setHtml(html, loading_url) + + + diff --git a/src/calibre/ebooks/pdf/writer.py b/src/calibre/ebooks/pdf/writer.py index 2c2e6a2f0e..fa2f5ebcfa 100644 --- a/src/calibre/ebooks/pdf/writer.py +++ b/src/calibre/ebooks/pdf/writer.py @@ -18,10 +18,11 @@ from calibre.ebooks.pdf.pageoptions import unit, paper_size, \ from calibre.ebooks.metadata import authors_to_string from calibre.ptempfile import PersistentTemporaryFile from calibre import __appname__, __version__, fit_image +from calibre.ebooks.oeb.display.webview import load_html from PyQt4 import QtCore -from PyQt4.Qt import QUrl, QEventLoop, QObject, \ - QPrinter, QMetaObject, QSizeF, Qt, QPainter, QPixmap +from PyQt4.Qt import (QEventLoop, QObject, + QPrinter, QMetaObject, QSizeF, Qt, QPainter, QPixmap) from PyQt4.QtWebKit import QWebView from pyPdf import PdfFileWriter, PdfFileReader @@ -70,7 +71,7 @@ def get_pdf_printer(opts, for_comic=False): opts.margin_right, opts.margin_bottom, QPrinter.Point) printer.setOrientation(orientation(opts.orientation)) printer.setOutputFormat(QPrinter.PdfFormat) - printer.setFullPage(True) + printer.setFullPage(for_comic) return printer def get_printer_page_size(opts, for_comic=False): @@ -156,8 +157,7 @@ class PDFWriter(QObject): # {{{ self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1))) self.logger.debug('Processing %s...' % item) - - self.view.load(QUrl.fromLocalFile(item)) + load_html(item, self.view) def _render_html(self, ok): if ok: @@ -171,6 +171,10 @@ class PDFWriter(QObject): # {{{ # previously set on the printer. if isosx: printer.setOutputFormat(QPrinter.NativeFormat) + self.view.page().mainFrame().evaluateJavaScript(''' + document.body.style.backgroundColor = "white"; + + ''') self.view.print_(printer) printer.abort() else: diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index b03de237c1..4992510dc4 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -4,14 +4,14 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' # Imports {{{ -import os, math, re, glob, sys, zipfile +import os, math, glob, sys, zipfile from base64 import b64encode from functools import partial from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, QPainter, QPalette, QBrush, QFontDatabase, QDialog, QColor, QPoint, QImage, QRegion, QVariant, QIcon, - QFont, pyqtSignature, QAction, QByteArray, QMenu, + QFont, pyqtSignature, QAction, QMenu, pyqtSignal, QSwipeGesture, QApplication) from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings @@ -21,10 +21,11 @@ from calibre.gui2.viewer.config_ui import Ui_Dialog from calibre.gui2.viewer.flip import SlideFlip from calibre.gui2.shortcuts import Shortcuts, ShortcutConfig from calibre.constants import iswindows -from calibre import prints, guess_type +from calibre import prints from calibre.gui2.viewer.keys import SHORTCUTS from calibre.gui2.viewer.javascript import JavaScriptLoader from calibre.gui2.viewer.position import PagePosition +from calibre.ebooks.oeb.display.webview import load_html # }}} @@ -474,19 +475,6 @@ class Document(QWebPage): # {{{ # }}} -class EntityDeclarationProcessor(object): # {{{ - - def __init__(self, html): - self.declared_entities = {} - for match in re.finditer(r']+)>', html): - tokens = match.group(1).split() - if len(tokens) > 1: - self.declared_entities[tokens[0].strip()] = tokens[1].strip().replace('"', '') - self.processed_html = html - for key, val in self.declared_entities.iteritems(): - self.processed_html = self.processed_html.replace('&%s;'%key, val) -# }}} - class DocumentView(QWebView): # {{{ magnification_changed = pyqtSignal(object) @@ -497,8 +485,6 @@ class DocumentView(QWebView): # {{{ self.is_auto_repeat_event = False self.debug_javascript = debug_javascript self.shortcuts = Shortcuts(SHORTCUTS, 'shortcuts/viewer') - self.self_closing_pat = re.compile(r'<([a-z1-6]+)\s+([^>]+)/>', - re.IGNORECASE) self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self._size_hint = QSize(510, 680) self.initial_pos = 0.0 @@ -689,31 +675,16 @@ class DocumentView(QWebView): # {{{ def path(self): return os.path.abspath(unicode(self.url().toLocalFile())) - def self_closing_sub(self, match): - tag = match.group(1) - if tag.lower().strip() == 'br': - return match.group() - return '<%s %s>'%(match.group(1), match.group(2), match.group(1)) - def load_path(self, path, pos=0.0): self.initial_pos = pos - mt = getattr(path, 'mime_type', None) - if mt is None: - mt = guess_type(path)[0] - html = open(path, 'rb').read().decode(path.encoding, 'replace') - html = EntityDeclarationProcessor(html).processed_html - has_svg = re.search(r'<[:a-zA-Z]*svg', html) is not None - if 'xhtml' in mt: - html = self.self_closing_pat.sub(self.self_closing_sub, html) - if self.manager is not None: - self.manager.load_started() - self.loading_url = QUrl.fromLocalFile(path) - html = re.sub(ur'<\s*title\s*/\s*>', u'', html, flags=re.IGNORECASE) - if has_svg: - self.setContent(QByteArray(html.encode(path.encoding)), mt, QUrl.fromLocalFile(path)) - else: - self.setHtml(html, self.loading_url) + def callback(lu): + self.loading_url = lu + if self.manager is not None: + self.manager.load_started() + + load_html(path, self, codec=path.encoding, mime_type=getattr(path, + 'mime_type', None), pre_load_callback=callback) self.turn_off_internal_scrollbars() def initialize_scrollbar(self):