diff --git a/src/calibre/ebooks/oeb/iterator.py b/src/calibre/ebooks/oeb/iterator.py
index 03c09262d4..4910bf4e10 100644
--- a/src/calibre/ebooks/oeb/iterator.py
+++ b/src/calibre/ebooks/oeb/iterator.py
@@ -146,6 +146,9 @@ class EbookIterator(object):
self.opf = OPF(self.pathtoopf, os.path.dirname(self.pathtoopf))
+ self.language = self.opf.language
+ if self.language:
+ self.language = self.language.lower()
self.spine = [SpineItem(i.path) for i in self.opf.spine]
cover = self.opf.cover
diff --git a/src/calibre/gui2/convert/mobi_output.py b/src/calibre/gui2/convert/mobi_output.py
index f7d41957b2..611ef96e11 100644
--- a/src/calibre/gui2/convert/mobi_output.py
+++ b/src/calibre/gui2/convert/mobi_output.py
@@ -19,7 +19,7 @@ class PluginWidget(Widget, Ui_Form):
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
Widget.__init__(self, parent, 'mobi_output',
['prefer_author_sort', 'rescale_images', 'toc_title',
- 'dont_compress',]
+ 'dont_compress', 'no_inline_toc']
)
self.db, self.book_id = db, book_id
self.initialize_options(get_option, get_help, db, book_id)
diff --git a/src/calibre/gui2/viewer/config.ui b/src/calibre/gui2/viewer/config.ui
index 77532cdd6e..7b286f194c 100644
--- a/src/calibre/gui2/viewer/config.ui
+++ b/src/calibre/gui2/viewer/config.ui
@@ -144,7 +144,7 @@
- -
+
-
Remember last used &window size
@@ -174,9 +174,33 @@
+ -
+
+
+ H&yphenate (break line in the middle of large words)
+
+
+
+ -
+
+
+ The default language to use for hyphenation rules. If the book does not specify a language, this will be used.
+
+
+
+ -
+
+
+ Default &language for hyphenation:
+
+
+ hyphenate_default_lang
+
+
+
- -
+
-
&User stylesheet
@@ -226,8 +250,8 @@
accept()
- 248
- 254
+ 252
+ 569
157
@@ -242,8 +266,8 @@
reject()
- 316
- 260
+ 320
+ 569
286
@@ -251,5 +275,21 @@
+
+ hyphenate
+ toggled(bool)
+ hyphenate_default_lang
+ setEnabled(bool)
+
+
+ 83
+ 279
+
+
+ 349
+ 312
+
+
+
diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py
index 0c807a608a..8b7884d632 100644
--- a/src/calibre/gui2/viewer/documentview.py
+++ b/src/calibre/gui2/viewer/documentview.py
@@ -14,7 +14,7 @@ from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings
from calibre.utils.config import Config, StringConfig
from calibre.gui2.viewer.config_ui import Ui_Dialog
-from calibre.gui2.viewer.js import bookmarks, referencing
+from calibre.gui2.viewer.js import bookmarks, referencing, hyphenation
from calibre.ptempfile import PersistentTemporaryFile
from calibre.constants import iswindows
from calibre import prints
@@ -61,6 +61,9 @@ def config(defaults=None):
help=_('Set the user CSS stylesheet. This can be used to customize the look of all books.'))
c.add_opt('max_view_width', default=6000,
help=_('Maximum width of the viewer window, in pixels.'))
+ c.add_opt('hyphenate', default=False, help=_('Hyphenate text'))
+ c.add_opt('hyphenate_default_lang', default='en',
+ help=_('Default language for hyphenation rules'))
fonts = c.add_group('FONTS', _('Font options'))
fonts('serif_family', default='Times New Roman' if iswindows else 'Liberation Serif',
@@ -106,6 +109,15 @@ class ConfigDialog(QDialog, Ui_Dialog):
self.css.setPlainText(opts.user_css)
self.css.setToolTip(_('Set the user CSS stylesheet. This can be used to customize the look of all books.'))
self.max_view_width.setValue(opts.max_view_width)
+ from calibre.resources import hyphenate
+ for x in sorted(hyphenate['languages'].split(',')):
+ self.hyphenate_default_lang.addItem(x)
+ idx = self.hyphenate_default_lang.findText(opts.hyphenate_default_lang)
+ if idx == -1:
+ idx = self.hyphenate_default_lang.findText('en')
+ self.hyphenate_default_lang.setCurrentIndex(idx)
+ self.hyphenate.setChecked(opts.hyphenate)
+ self.hyphenate_default_lang.setEnabled(opts.hyphenate)
def accept(self, *args):
@@ -119,6 +131,9 @@ class ConfigDialog(QDialog, Ui_Dialog):
c.set('user_css', unicode(self.css.toPlainText()))
c.set('remember_window_size', self.opt_remember_window_size.isChecked())
c.set('max_view_width', int(self.max_view_width.value()))
+ c.set('hyphenate', self.hyphenate.isChecked())
+ c.set('hyphenate_default_lang',
+ self.hyphenate_default_lang.currentText())
return QDialog.accept(self, *args)
@@ -141,12 +156,14 @@ class Document(QWebPage):
if d.exec_() == QDialog.Accepted:
self.set_font_settings()
self.set_user_stylesheet()
+ self.misc_config()
self.triggerAction(QWebPage.Reload)
def __init__(self, *args):
QWebPage.__init__(self, *args)
self.setObjectName("py_bridge")
self.debug_javascript = False
+ self.current_language = None
#self.js_bridge = PythonJS(self.js_callback)
self.setLinkDelegationPolicy(self.DelegateAllLinks)
@@ -170,6 +187,7 @@ class Document(QWebPage):
# Miscellaneous
settings.setAttribute(QWebSettings.LinksIncludedInFocusChain, True)
self.set_user_stylesheet()
+ self.misc_config()
# Load jQuery
self.connect(self.mainFrame(), SIGNAL('javaScriptWindowObjectCleared()'),
@@ -182,18 +200,39 @@ class Document(QWebPage):
pt.close()
self.settings().setUserStyleSheetUrl(QUrl.fromLocalFile(pt.name))
+ def misc_config(self):
+ opts = config().parse()
+ self.hyphenate = opts.hyphenate
+ self.hyphenate_default_lang = opts.hyphenate_default_lang
+
def load_javascript_libraries(self):
self.mainFrame().addToJavaScriptWindowObject("py_bridge", self)
- from calibre.resources import jquery, jquery_scrollTo
+ from calibre.resources import jquery, jquery_scrollTo, hyphenate
self.javascript(jquery)
self.javascript(jquery_scrollTo)
self.javascript(bookmarks)
self.javascript(referencing)
+ self.javascript(hyphenation)
+ default_lang = self.hyphenate_default_lang
+ lang = self.current_language
+ if not lang:
+ lang = default_lang
+ lang = lang.lower()[:2]
+ if lang not in hyphenate['languages']:
+ lang = default_lang
+ self.loaded_lang = lang
+ self.javascript(hyphenate['Hyphenator.js'].decode('utf-8'))
+ self.javascript(hyphenate[lang+'.js'].decode('utf-8'))
@pyqtSignature("")
def animated_scroll_done(self):
self.emit(SIGNAL('animated_scroll_done()'))
+ @pyqtSignature("")
+ def init_hyphenate(self):
+ if self.hyphenate:
+ self.javascript('do_hyphenation("%s")'%self.loaded_lang)
+
@pyqtSignature("QString")
def debug(self, msg):
prints(msg)
@@ -401,6 +440,12 @@ class DocumentView(QWebView):
def content_size(self):
return self.document.width, self.document.height
+ @dynamic_property
+ def current_language(self):
+ def fget(self): return self.document.current_language
+ def fset(self, val): self.document.current_language = val
+ return property(fget=fget, fset=fset)
+
def search(self, text):
return self.findText(text)
diff --git a/src/calibre/gui2/viewer/js.py b/src/calibre/gui2/viewer/js.py
index 5e46bcdcfa..68768829bb 100644
--- a/src/calibre/gui2/viewer/js.py
+++ b/src/calibre/gui2/viewer/js.py
@@ -132,3 +132,25 @@ $(document.body).click(function(e) {
$(document).ready(enter_reference_mode);
'''
+
+hyphenation = '''
+function init_hyphenate() {
+ window.py_bridge.init_hyphenate();
+}
+
+document.addEventListener("DOMContentLoaded", init_hyphenate, false);
+
+function do_hyphenation(lang) {
+ Hyphenator.config(
+ {
+ 'minwordlength' : 6,
+ //'hyphenchar' : '|',
+ 'displaytogglebox' : false,
+ 'remoteloading' : false,
+ 'onerrorhandler' : function (e) {
+ window.py_bridge.debug(e);
+ }
+ });
+ Hyphenator.hyphenate(document.body, lang);
+}
+'''
diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py
index 0ed5312bf8..6fdeba8df7 100644
--- a/src/calibre/gui2/viewer/main.py
+++ b/src/calibre/gui2/viewer/main.py
@@ -563,6 +563,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.close_progress_indicator()
else:
self.metadata.show_opf(self.iterator.opf, os.path.splitext(pathtoebook)[1][1:])
+ self.view.current_language = self.iterator.language
title = self.iterator.opf.title
if not title:
title = os.path.splitext(os.path.basename(pathtoebook))[0]
diff --git a/upload.py b/upload.py
index 802aa8c93a..45dbac0bd6 100644
--- a/upload.py
+++ b/upload.py
@@ -186,12 +186,17 @@ class resources(OptionlessCommand):
def get_hyphenate(self):
sdir = os.path.join('src', 'calibre', 'gui2', 'viewer', 'hyphenate')
resources, max = {}, 0
+ languages = set([])
for f in glob.glob(os.path.join(sdir, 'patterns', '*.js')) + \
[os.path.join(sdir, 'Hyphenator.js')]:
f = os.path.abspath(f)
- resources[os.path.basename(f)] = self.get(f)
+ b = os.path.basename(f)
+ resources[b] = self.get(f)
+ if b != 'Hyphenator.js':
+ languages.add(b.split('.')[0])
mtime = os.stat(f).st_mtime
max = mtime if mtime > max else max
+ resources['languages'] = ','.join(languages)
return resources, max
def run(self):
@@ -205,7 +210,7 @@ class resources(OptionlessCommand):
static, smax = self.get_static_resources()
recipes, rmax = self.get_recipes()
hyphenate, hmax = self.get_hyphenate()
- amax = max(rmax, smax, hmax)
+ amax = max(rmax, smax, hmax, os.stat(__file__).st_mtime)
if newer([dest], RESOURCES.values()) or os.stat(dest).st_mtime < amax:
print 'Compiling resources...'
with open(dest, 'wb') as f: