From 298b6646695ab3a715f779edd3a09e6aef12e52b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 2 Jun 2016 17:36:44 +0530 Subject: [PATCH] Implement text search for HTML files --- .../gui2/tweak_book/editor/smarts/html.py | 63 ++++++++++++++++++- src/calibre/gui2/tweak_book/editor/text.py | 1 + src/calibre/gui2/tweak_book/text_search.py | 32 +++++++++- 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/tweak_book/editor/smarts/html.py b/src/calibre/gui2/tweak_book/editor/smarts/html.py index 63be2a8cb8..b81ff37c30 100644 --- a/src/calibre/gui2/tweak_book/editor/smarts/html.py +++ b/src/calibre/gui2/tweak_book/editor/smarts/html.py @@ -10,7 +10,7 @@ import sys, re from operator import itemgetter from cssutils import parseStyle -from PyQt5.Qt import QTextEdit, Qt +from PyQt5.Qt import QTextEdit, Qt, QTextCursor from calibre import prepare_string_for_xml, xml_entity_to_unicode from calibre.ebooks.oeb.polish.container import OEB_DOCS @@ -672,9 +672,62 @@ class Smarts(NullSmarts): return 'complete_names', (names_type, doc_name, c.root), query + def find_text(self, pat, cursor): + from calibre.gui2.tweak_book.text_search import find_text_in_chunks + chunks = [] + c = QTextCursor(cursor) + c.setPosition(0) + in_text = True + block = c.block() + + cstart = min(cursor.position(), cursor.anchor()) + cend = max(cursor.position(), cursor.anchor()) + + def append(text, start): + after = start + len(text) + if start <= cend and cstart < after: + extra = after - (cend + 1) + if extra > 0: + text = text[:-extra] + extra = cstart - start + if extra > 0: + text = text[extra:] + chunks.append((text, start + max(extra, 0))) + + while block.isValid() and block.position() <= cend and block.position() + block.length() > cstart: + boundaries = sorted(block.userData().tags, key=get_offset) + if not boundaries: + # Add the whole line + if in_text: + text = block.text() + if text: + append(text, block.position()) + else: + start = block.position() + c.setPosition(start) + for b in boundaries: + if in_text: + c.setPosition(start + b.offset, c.KeepAnchor) + if c.hasSelection(): + append(c.selectedText(), c.anchor()) + in_text = not b.is_start + c.setPosition(start + b.offset + 1) + if in_text: + # Add remaining text in block + c.setPosition(block.position() + boundaries[-1].offset + 1) + c.movePosition(c.EndOfBlock, c.KeepAnchor) + if c.hasSelection(): + append(c.selectedText(), c.anchor()) + block = block.next() + s, e = find_text_in_chunks(pat, chunks) + return s != -1 and e != -1, s, e + if __name__ == '__main__': # {{{ from calibre.gui2.tweak_book.editor.widget import launch_editor - launch_editor('''\ + if sys.argv[-1].endswith('.html'): + raw = lopen(sys.argv[-1], 'rb').read().decode('utf-8') + else: + raw = '''\