Edit Book Function mode: Add builtin functions to change case of text, ignoring HTML tags in the matched text

This commit is contained in:
Kovid Goyal 2014-12-31 08:39:57 +05:30
parent 75406a22bb
commit 1410194a0d
3 changed files with 36 additions and 4 deletions

View File

@ -28,11 +28,12 @@ Automatically fixing the case of headings in the document
Here, we will leverage one of the builtin functions in the editor to
automatically change the case of all text inside heading tags to title case::
Find expression: <[Hh][1-6][^>]*>([^<>]+)</[hH][1-6]>
Find expression: <([Hh][1-6])[^>]*>.+?</\1>
For the function, simply choose the :guilabel:`Title-case text` builtin
For the function, simply choose the :guilabel:`Title-case text (ignore tags)` builtin
function. The will change titles that look like: ``<h1>some TITLE</h1>`` to
``<h1>Some Title</h1>``.
``<h1>Some Title</h1>``. It will work even if there are other HTML tags inside
the heading tags.
Your first custom function - smartening hyphens

View File

@ -198,3 +198,9 @@ def apply_func_to_match_groups(match, func=icu_upper, handle_entities=handle_ent
parts.append(match.string[pos:match.end()])
return ''.join(parts)
def apply_func_to_html_text(match, func=icu_upper, handle_entities=handle_entities):
''' Apply the specified function only to text between HTML tag definitions. '''
parts = re.split(r'(<[^>]+>)', match.group())
parts = (x if x.startswith('<') else func(x) for x in parts)
return ''.join(parts)

View File

@ -13,7 +13,7 @@ from PyQt5.Qt import (
pyqtSignal, QVBoxLayout, QHBoxLayout, QPlainTextEdit, QLabel, QFontMetrics,
QSize, Qt, QApplication, QIcon)
from calibre.ebooks.oeb.polish.utils import apply_func_to_match_groups
from calibre.ebooks.oeb.polish.utils import apply_func_to_match_groups, apply_func_to_html_text
from calibre.gui2 import error_dialog
from calibre.gui2.complete2 import EditWithComplete
from calibre.gui2.tweak_book import dictionaries
@ -319,6 +319,31 @@ def replace_swapcase(match, number, file_name, metadata, dictionaries, data, fun
changed.'''
return apply_func_to_match_groups(match, swapcase)
@builtin('Upper-case text (ignore tags)', upper, apply_func_to_html_text)
def replace_uppercase_ignore_tags(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
'''Make matched text upper case, ignoring the text inside tag definitions.'''
return apply_func_to_html_text(match, upper)
@builtin('Lower-case text (ignore tags)', lower, apply_func_to_html_text)
def replace_lowercase_ignore_tags(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
'''Make matched text lower case, ignoring the text inside tag definitions.'''
return apply_func_to_html_text(match, lower)
@builtin('Capitalize text (ignore tags)', capitalize, apply_func_to_html_text)
def replace_capitalize_ignore_tags(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
'''Capitalize matched text, ignoring the text inside tag definitions.'''
return apply_func_to_html_text(match, capitalize)
@builtin('Title-case text (ignore tags)', titlecase, apply_func_to_html_text)
def replace_titlecase_ignore_tags(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
'''Title-case matched text, ignoring the text inside tag definitions.'''
return apply_func_to_html_text(match, titlecase)
@builtin('Swap the case of text (ignore tags)', swapcase, apply_func_to_html_text)
def replace_swapcase_ignore_tags(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
'''Swap the case of the matched text, ignoring the text inside tag definitions.'''
return apply_func_to_html_text(match, swapcase)
if __name__ == '__main__':
app = QApplication([])
FunctionEditor().exec_()