Skip to content

Commit

Permalink
Edit book: Add a tool to transform HTML tags based on rules (Tools->T…
Browse files Browse the repository at this point in the history
…ransform HTML)
  • Loading branch information
kovidgoyal committed Nov 11, 2021
1 parent 23f3dbd commit 0e9b1c5
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 2 deletions.
20 changes: 19 additions & 1 deletion src/calibre/gui2/html_transform_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def text_from_rule(rule, parent):
text += '<br>' + ACTION_MAP[action['type']].short_text
if action.get('data'):
ad = elided_text(action['data'], font=parent.font(), width=200, pos='right')
text += f'<code>{prepare_string_for_xml(ad)}</code>'
text += f' <code>{prepare_string_for_xml(ad)}</code>'
except Exception:
import traceback
traceback.print_exc()
Expand Down Expand Up @@ -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))

# }}}


Expand Down
16 changes: 15 additions & 1 deletion src/calibre/gui2/tag_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,13 @@ def setup_ui(self):
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)
Expand All @@ -507,6 +513,9 @@ def setup_ui(self):
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
Expand All @@ -518,6 +527,11 @@ def rules(self, rules):
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([])
Expand Down
1 change: 1 addition & 0 deletions src/calibre/gui2/tweak_book/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
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)}
Expand Down
46 changes: 46 additions & 0 deletions src/calibre/gui2/tweak_book/boss.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@

_diff_dialogs = []
last_used_transform_rules = []
last_used_html_transform_rules = []


def get_container(*args, **kwargs):
Expand Down Expand Up @@ -626,6 +627,51 @@ def polish(self, action, name, parent=None):
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.')):
Expand Down
3 changes: 3 additions & 0 deletions src/calibre/gui2/tweak_book/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,8 @@ def treg(icon, text, target, sid, keys, description):
'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)'))
Expand Down Expand Up @@ -666,6 +668,7 @@ def create_menubar(self):
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)
Expand Down

0 comments on commit 0e9b1c5

Please sign in to comment.