diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py
index 1a3344867f..9e712a102c 100644
--- a/src/calibre/devices/kobo/driver.py
+++ b/src/calibre/devices/kobo/driver.py
@@ -2347,7 +2347,10 @@ class KOBOTOUCH(KOBO):
return result
def _kepubify(self, path, name, mi) -> None:
+ from calibre.ebooks.conversion.config import load_defaults
from calibre.ebooks.oeb.polish.kepubify import kepubify_path, make_options
+ prefs = load_defaults('kepub_output')
+ prefer_justification = prefs.get('kepub_prefer_justification', False)
debug_print(f'Starting conversion of {mi.title} ({name}) to kepub')
opts = make_options(
extra_css=self.extra_css or '',
@@ -2359,6 +2362,7 @@ class KOBOTOUCH(KOBO):
hyphenation_limit_lines=self.get_pref('hyphenation_limit_lines'),
remove_at_page_rules=self.extra_css_options.get('has_atpage', False),
remove_widows_and_orphans=self.extra_css_options.get('has_widows_orphans', False),
+ prefer_justification=prefer_justification,
)
try:
kepubify_path(path, outpath=path, opts=opts, allow_overwrite=True)
diff --git a/src/calibre/ebooks/conversion/config.py b/src/calibre/ebooks/conversion/config.py
index 8fa27d3ebb..f2dccc5f22 100644
--- a/src/calibre/ebooks/conversion/config.py
+++ b/src/calibre/ebooks/conversion/config.py
@@ -282,7 +282,7 @@ OPTIONS = {
'preserve_cover_aspect_ratio', 'epub_flatten', 'epub_version', 'epub_max_image_size',),
'kepub': (
- 'dont_split_on_page_breaks', 'flow_size', 'kepub_max_image_size',
+ 'dont_split_on_page_breaks', 'flow_size', 'kepub_max_image_size', 'kepub_prefer_justification',
'kepub_affect_hyphenation', 'kepub_disable_hyphenation', 'kepub_hyphenation_min_chars',
'kepub_hyphenation_min_chars_before', 'kepub_hyphenation_min_chars_after', 'kepub_hyphenation_limit_lines',
),
diff --git a/src/calibre/ebooks/conversion/plugins/epub_output.py b/src/calibre/ebooks/conversion/plugins/epub_output.py
index a06ed43812..83a09ae46c 100644
--- a/src/calibre/ebooks/conversion/plugins/epub_output.py
+++ b/src/calibre/ebooks/conversion/plugins/epub_output.py
@@ -611,6 +611,16 @@ class KEPUBOutput(OutputFormatPlugin):
help=max_image_size_help
),
+ OptionRecommendation(name='kepub_prefer_justification', recommended_value=False,
+ help=_(
+ 'The KEPUB renderer on the Kobo has a bug when text justification is turned on.'
+ ' It will either not justify text properly or when highlighting there will be gaps'
+ ' between neighboring highlighted parts of text. By default, calibre generates'
+ ' KEPUB that avoid the highlighting gaps at the expense of worse text justification.'
+ ' This option reverses that tradeoff. Use this option if you use justification when'
+ ' reading on your Kobo device.'
+ )),
+
OptionRecommendation(name='kepub_affect_hyphenation', recommended_value=False,
help=_('Modify how hyphenation is performed for this book. Note that hyphenation'
' does not perform well for all languages, as it depends on the dictionaries'
@@ -653,6 +663,7 @@ class KEPUBOutput(OutputFormatPlugin):
hyphenation_min_chars_before=opts.kepub_hyphenation_min_chars_before,
hyphenation_min_chars_after=opts.kepub_hyphenation_min_chars_after,
hyphenation_limit_lines=opts.kepub_hyphenation_limit_lines,
+ prefer_justification=opts.kepub_prefer_justification,
)
kepubify_container(container, kopts)
container.commit()
diff --git a/src/calibre/ebooks/oeb/polish/kepubify.py b/src/calibre/ebooks/oeb/polish/kepubify.py
index 220caa4d65..8e201e8227 100644
--- a/src/calibre/ebooks/oeb/polish/kepubify.py
+++ b/src/calibre/ebooks/oeb/polish/kepubify.py
@@ -609,6 +609,7 @@ def make_options(
hyphenation_min_chars_before: int = 3,
hyphenation_min_chars_after: int = 3,
hyphenation_limit_lines: int = 2,
+ prefer_justification: bool = False,
remove_widows_and_orphans: bool | None = None,
remove_at_page_rules: bool | None = None,
@@ -652,7 +653,7 @@ h1, h2, h3, h4, h5, h6, td {{
'''
return Options(
extra_css=extra_css, hyphenation_css=hyphen_css, remove_widows_and_orphans=remove_widows_and_orphans,
- remove_at_page_rules=remove_at_page_rules)
+ remove_at_page_rules=remove_at_page_rules, prefer_justification=prefer_justification)
def profile():
diff --git a/src/calibre/gui2/convert/kepub_output.ui b/src/calibre/gui2/convert/kepub_output.ui
index d415c36c3b..30cf13007a 100644
--- a/src/calibre/gui2/convert/kepub_output.ui
+++ b/src/calibre/gui2/convert/kepub_output.ui
@@ -63,21 +63,21 @@
-
- -
+
-
Enable/disable &hyphenation for this book
- -
+
-
&Prevent all hyphenation
- -
+
-
Hyphenation: &minimum word length:
@@ -87,7 +87,7 @@
- -
+
-
Disabled
@@ -97,7 +97,7 @@
- -
+
-
Hyphenation: minimum characters &before:
@@ -107,14 +107,14 @@
- -
+
-
characters
- -
+
-
Hyphenation: minimum characters &after:
@@ -124,14 +124,14 @@
- -
+
-
characters
- -
+
-
Hyphenation: &limit lines:
@@ -141,14 +141,14 @@
- -
+
-
lines
- -
+
-
Qt::Vertical
@@ -161,6 +161,13 @@
+ -
+
+
+ Prefer improved text &justification to proper highlighting
+
+
+
diff --git a/src/pyj/book_list/conversion_widgets.pyj b/src/pyj/book_list/conversion_widgets.pyj
index 1577846d28..dfb608cc8c 100644
--- a/src/pyj/book_list/conversion_widgets.pyj
+++ b/src/pyj/book_list/conversion_widgets.pyj
@@ -558,6 +558,7 @@ def kepub_output(container):
g.appendChild(checkbox('dont_split_on_page_breaks', _('Do not &split on page breaks')))
g.appendChild(int_spin('flow_size', _('Split files &larger than:'), unit='KB', max=1000000, step=20))
g.appendChild(lineedit('kepub_max_image_size', _('Shrink &images larger than:')))
+ g.appendChild(lineedit('kepub_prefer_justification', _('Prefer improved text justification to proper highlighting')))
g.appendChild(checkbox('kepub_affect_hyphenation', _('Enable/disable &hyphenation for this book')))
g.appendChild(checkbox('kepub_disable_hyphenation', _('&Prevent all hyphenation')))
c = _('characters')