diff --git a/src/calibre/gui2/html_transform_rules.py b/src/calibre/gui2/html_transform_rules.py
index df5cac89f1..89e5b1a9d8 100644
--- a/src/calibre/gui2/html_transform_rules.py
+++ b/src/calibre/gui2/html_transform_rules.py
@@ -293,7 +293,7 @@ class RuleItem(RuleItemBase): # {{{
text += '
' + ACTION_MAP[action['type']].short_text
if action.get('data'):
ad = elided_text(action['data'], font=parent.font(), width=200, pos='right')
- text += f'{prepare_string_for_xml(ad)}
'
+ text += f' {prepare_string_for_xml(ad)}
'
except Exception:
import traceback
traceback.print_exc()
@@ -336,6 +336,24 @@ class RulesDialog(RulesDialogBase): # {{{
PREFS_OBJECT_NAME = 'html-transform-rules'
RulesClass = Rules
TesterClass = Tester
+
+ def extra_bottom_widget(self):
+ self.scope_cb = cb = QComboBox()
+ cb.addItem(_('Current HTML file'), 'current')
+ cb.addItem(_('All HTML files'), 'all')
+ cb.addItem(_('Open HTML files'), 'open')
+ cb.addItem(_('Selected HTML files'), 'selected')
+ return cb
+
+ @property
+ def transform_scope(self):
+ return self.scope_cb.currentData()
+
+ @transform_scope.setter
+ def transform_scope(self, val):
+ idx = self.scope_cb.findData(val)
+ self.scope_cb.setCurrentIndex(max(0, idx))
+
# }}}
diff --git a/src/calibre/gui2/tag_mapper.py b/src/calibre/gui2/tag_mapper.py
index 452419bb75..47d649e3ae 100644
--- a/src/calibre/gui2/tag_mapper.py
+++ b/src/calibre/gui2/tag_mapper.py
@@ -495,7 +495,13 @@ class RulesDialog(Dialog, SaveLoadMixin):
self.l = l = QVBoxLayout(self)
self.edit_widget = w = self.RulesClass(self)
l.addWidget(w)
- l.addWidget(self.bb)
+ ebw = self.extra_bottom_widget()
+ if ebw is None:
+ l.addWidget(self.bb)
+ else:
+ self.h = h = QHBoxLayout()
+ l.addLayout(h)
+ h.addWidget(ebw), h.addStretch(10), h.addWidget(self.bb)
self.save_button = b = self.bb.addButton(_('&Save'), QDialogButtonBox.ButtonRole.ActionRole)
b.setToolTip(_('Save this ruleset for later re-use'))
b.clicked.connect(self.save_ruleset)
@@ -507,6 +513,9 @@ class RulesDialog(Dialog, SaveLoadMixin):
self.test_button = b = self.bb.addButton(_('&Test rules'), QDialogButtonBox.ButtonRole.ActionRole)
b.clicked.connect(self.test_rules)
+ def extra_bottom_widget(self):
+ pass
+
@property
def rules(self):
return self.edit_widget.rules
@@ -518,6 +527,11 @@ class RulesDialog(Dialog, SaveLoadMixin):
def test_rules(self):
self.TesterClass(self.rules, self).exec_()
+ def sizeHint(self):
+ ans = super().sizeHint()
+ ans.setWidth(ans.width() + 100)
+ return ans
+
if __name__ == '__main__':
app = Application([])
diff --git a/src/calibre/gui2/tweak_book/__init__.py b/src/calibre/gui2/tweak_book/__init__.py
index e9f833c3d8..aff8506ecc 100644
--- a/src/calibre/gui2/tweak_book/__init__.py
+++ b/src/calibre/gui2/tweak_book/__init__.py
@@ -85,6 +85,7 @@ d['file_list_shows_full_pathname'] = False
d['auto_link_stylesheets'] = True
d['check_external_link_anchors'] = True
d['remove_ncx'] = True
+d['html_transform_scope'] = 'current'
del d
ucase_map = {l:string.ascii_uppercase[i] for i, l in enumerate(string.ascii_lowercase)}
diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py
index a2633402a1..1f2e5c1646 100644
--- a/src/calibre/gui2/tweak_book/boss.py
+++ b/src/calibre/gui2/tweak_book/boss.py
@@ -74,6 +74,7 @@ from polyglot.urllib import urlparse
_diff_dialogs = []
last_used_transform_rules = []
+last_used_html_transform_rules = []
def get_container(*args, **kwargs):
@@ -626,6 +627,51 @@ class Boss(QObject):
self.rewind_savepoint()
show_report(changed, self.current_metadata.title, report, parent or self.gui, self.show_current_diff)
+ def transform_html(self):
+ global last_used_html_transform_rules
+ if not self.ensure_book(_('You must first open a book in order to transform styles.')):
+ return
+ from calibre.gui2.html_transform_rules import RulesDialog
+ from calibre.ebooks.html_transform_rules import transform_container
+ d = RulesDialog(self.gui)
+ d.rules = last_used_html_transform_rules
+ d.transform_scope = scope = tprefs['html_transform_scope']
+ ret = d.exec_()
+ last_used_html_transform_rules = d.rules
+ tprefs.set('html_transform_scope', d.transform_scope)
+ if ret != QDialog.DialogCode.Accepted:
+ return
+
+ cc = current_container()
+ names = ()
+ if scope == 'current':
+ if not self.currently_editing or cc.mime_map.get(self.currently_editing) not in OEB_DOCS:
+ return error_dialog(self.gui, _('No HTML file'), _('Not currently editing an HTML file'), show=True)
+ names = (self.currently_editing,)
+ elif scope == 'open':
+ names = tuple(name for name in editors if cc.mime_map.get(name) in OEB_DOCS)
+ if not names:
+ return error_dialog(self.gui, _('No HTML files'), _('Not currently editing any HTML files'), show=True)
+ elif scope == 'selected':
+ names = tuple(name for name in self.gui.file_list.file_list.selected_names if cc.mime_map.get(name) in OEB_DOCS)
+ if not names:
+ return error_dialog(self.gui, _('No HTML files'), _('No HTML files are currently selected in the File browser'), show=True)
+ with BusyCursor():
+ self.add_savepoint(_('Before HTML transformation'))
+ try:
+ changed = transform_container(cc, last_used_html_transform_rules, names)
+ except:
+ self.rewind_savepoint()
+ raise
+ if changed:
+ self.apply_container_update_to_gui()
+ if not changed:
+ self.rewind_savepoint()
+ info_dialog(self.gui, _('No changes'), _(
+ 'No HTML was changed.'), show=True)
+ return
+ self.show_current_diff()
+
def transform_styles(self):
global last_used_transform_rules
if not self.ensure_book(_('You must first open a book in order to transform styles.')):
diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py
index 3b266a2da8..bbc27f0200 100644
--- a/src/calibre/gui2/tweak_book/ui.py
+++ b/src/calibre/gui2/tweak_book/ui.py
@@ -500,6 +500,8 @@ class Main(MainWindow):
'Compress images losslessly'))
self.action_transform_styles = treg('wizard.png', _('Transform &styles'), self.boss.transform_styles, 'transform-styles', (), _(
'Transform styles used in the book'))
+ self.action_transform_html = treg('wizard.png', _('Transform &HTML'), self.boss.transform_html, 'transform-html', (), _(
+ 'Transform HTML used in the book'))
self.action_get_ext_resources = treg('download-metadata.png', _('Download external &resources'),
self.boss.get_external_resources, 'get-external-resources', (), _(
'Download external resources in the book (images/stylesheets/etc/ that are not included in the book)'))
@@ -666,6 +668,7 @@ class Main(MainWindow):
e.addAction(self.action_smarten_punctuation)
e.addAction(self.action_remove_unused_css)
e.addAction(self.action_transform_styles)
+ e.addAction(self.action_transform_html)
e.addAction(self.action_fix_html_all)
e.addAction(self.action_pretty_all)
e.addAction(self.action_rationalize_folders)