Implement #2829 (Request for hyphenation)

This commit is contained in:
Kovid Goyal 2009-07-14 18:12:29 -06:00
parent ffb1d3d770
commit ed92482019
7 changed files with 127 additions and 11 deletions

View File

@ -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

View File

@ -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)

View File

@ -144,7 +144,7 @@
</item>
</widget>
</item>
<item row="4" column="0" colspan="2">
<item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="opt_remember_window_size">
<property name="text">
<string>Remember last used &amp;window size</string>
@ -174,9 +174,33 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="hyphenate">
<property name="text">
<string>H&amp;yphenate (break line in the middle of large words)</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="hyphenate_default_lang">
<property name="toolTip">
<string>The default language to use for hyphenation rules. If the book does not specify a language, this will be used.</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Default &amp;language for hyphenation:</string>
</property>
<property name="buddy">
<cstring>hyphenate_default_lang</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>&amp;User stylesheet</string>
@ -226,8 +250,8 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
<x>252</x>
<y>569</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
@ -242,8 +266,8 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
<x>320</x>
<y>569</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
@ -251,5 +275,21 @@
</hint>
</hints>
</connection>
<connection>
<sender>hyphenate</sender>
<signal>toggled(bool)</signal>
<receiver>hyphenate_default_lang</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>83</x>
<y>279</y>
</hint>
<hint type="destinationlabel">
<x>349</x>
<y>312</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -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)

View File

@ -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);
}
'''

View File

@ -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]

View File

@ -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: