mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement #2829 (Request for hyphenation)
This commit is contained in:
parent
ffb1d3d770
commit
ed92482019
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 &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&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 &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>&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>
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
'''
|
||||
|
@ -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]
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user