From cd888703b868e62b5528f5a7e37ab659164e1809 Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Thu, 4 May 2023 10:06:13 +0200 Subject: [PATCH 1/2] add HTML entity highlighter --- src/calibre/gui2/markdown_editor.py | 2 +- .../gui2/markdown_syntax_highlighter.py | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/markdown_editor.py b/src/calibre/gui2/markdown_editor.py index 37bcd43a30..6d946c746c 100644 --- a/src/calibre/gui2/markdown_editor.py +++ b/src/calibre/gui2/markdown_editor.py @@ -183,7 +183,7 @@ if __name__ == '__main__': w.setWindowFlag(Qt.WindowType.Dialog) w.show() w.markdown = '''\ -test *italic* **bold** ***bold-italic*** `code` [link](https://calibre-ebook.com) span +normal& *italic&* **bold&** ***bold-italic*** `code` [link](https://calibre-ebook.com) span > Blockquotes diff --git a/src/calibre/gui2/markdown_syntax_highlighter.py b/src/calibre/gui2/markdown_syntax_highlighter.py index c481773647..2220c840d0 100644 --- a/src/calibre/gui2/markdown_syntax_highlighter.py +++ b/src/calibre/gui2/markdown_syntax_highlighter.py @@ -32,7 +32,8 @@ class MarkdownHighlighter(QSyntaxHighlighter): 'CodeSpan': re.compile(r'(?`+).+?(?P=delim)'), 'HeaderLine': re.compile(r'(?u)^(-|=)+\s*$'), 'HR': re.compile(r'(?u)^(\s*(\*|-|_)\s*){3,}$'), - 'Html': re.compile(r'(?u)') + 'Html': re.compile(r'(?u)'), + 'Entity': re.compile(r'&([A-z]{2,7}|#\d{1,7}|#x[\dA-Fa-f]{1,6});'), } key_theme_maps = { @@ -55,6 +56,7 @@ class MarkdownHighlighter(QSyntaxHighlighter): 'CodeSpan': "codespan", 'HR': "line", 'Html': "html", + 'Entity': "entity", } light_theme = { @@ -70,7 +72,8 @@ class MarkdownHighlighter(QSyntaxHighlighter): "codespan": {"color":"#ff5800", "font-weight":"normal", "font-style":"normal"}, "codeblock": {"color":"#ff5800", "font-weight":"normal", "font-style":"normal"}, "line": {"color":"#2aa198", "font-weight":"normal", "font-style":"normal"}, - "html": {"color":"#c000c0", "font-weight":"normal", "font-style":"normal"} + "html": {"color":"#c000c0", "font-weight":"normal", "font-style":"normal"}, + "entity": {"color":"#006496", "font-weight":"normal", "font-style":"normal"}, } dark_theme = { @@ -86,7 +89,8 @@ class MarkdownHighlighter(QSyntaxHighlighter): "codespan": {"color":"#90ee90", "font-weight":"normal", "font-style":"normal"}, "codeblock": {"color":"#ff9900", "font-weight":"normal", "font-style":"normal"}, "line": {"color":"#2aa198", "font-weight":"normal", "font-style":"normal"}, - "html": {"color":"#F653A6", "font-weight":"normal", "font-style":"normal"} + "html": {"color":"#f653a6", "font-weight":"normal", "font-style":"normal"}, + "entity": {"color":"#ff82ac", "font-weight":"normal", "font-style":"normal"}, } def __init__(self, parent): @@ -141,6 +145,8 @@ class MarkdownHighlighter(QSyntaxHighlighter): self.highlightImage(text, cursor, bf) + self.highlightEntity(text, cursor, bf) + self.highlightCodeSpan(text, cursor, bf) self.highlightCodeBlock(text, cursor, bf) @@ -295,6 +301,13 @@ class MarkdownHighlighter(QSyntaxHighlighter): found = True return found + def highlightEntity(self, text, cursor, bf): + found = False + for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Entity'],text): + self.setFormat(self.offset+ mo.start(), mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['Entity']) + found = True + return found + def highlightHtml(self, text): for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Html'], text): self.setFormat(mo.start(), mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['Html']) From c451efbd4257103417ebf5c6f4aa71f65e45009e Mon Sep 17 00:00:00 2001 From: un-pogaz <46523284+un-pogaz@users.noreply.github.com> Date: Thu, 4 May 2023 10:58:39 +0200 Subject: [PATCH 2/2] apply local bold/italic to Entity --- .../gui2/markdown_syntax_highlighter.py | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/markdown_syntax_highlighter.py b/src/calibre/gui2/markdown_syntax_highlighter.py index 2220c840d0..693f43d6b9 100644 --- a/src/calibre/gui2/markdown_syntax_highlighter.py +++ b/src/calibre/gui2/markdown_syntax_highlighter.py @@ -73,7 +73,7 @@ class MarkdownHighlighter(QSyntaxHighlighter): "codeblock": {"color":"#ff5800", "font-weight":"normal", "font-style":"normal"}, "line": {"color":"#2aa198", "font-weight":"normal", "font-style":"normal"}, "html": {"color":"#c000c0", "font-weight":"normal", "font-style":"normal"}, - "entity": {"color":"#006496", "font-weight":"normal", "font-style":"normal"}, + "entity": {"color":"#006496"}, } dark_theme = { @@ -90,7 +90,7 @@ class MarkdownHighlighter(QSyntaxHighlighter): "codeblock": {"color":"#ff9900", "font-weight":"normal", "font-style":"normal"}, "line": {"color":"#2aa198", "font-weight":"normal", "font-style":"normal"}, "html": {"color":"#f653a6", "font-weight":"normal", "font-style":"normal"}, - "entity": {"color":"#ff82ac", "font-weight":"normal", "font-style":"normal"}, + "entity": {"color":"#ff82ac"}, } def __init__(self, parent): @@ -102,6 +102,16 @@ class MarkdownHighlighter(QSyntaxHighlighter): self.theme = theme self.MARKDOWN_KWS_FORMAT = {} + for k in ['Bold', 'Italic','BoldItalic']: + # generate dynamically keys and theme for EntityBold, EntityItalic, EntityBoldItalic + t = self.key_theme_maps[k] + newtheme = theme['entity'].copy() + newtheme.update(theme[t]) + newthemekey = 'entity'+t + newmapkey = 'Entity'+k + theme[newthemekey] = newtheme + self.key_theme_maps[newmapkey] = newthemekey + for k,t in self.key_theme_maps.items(): subtheme = theme[t] format = QTextCharFormat() @@ -304,7 +314,18 @@ class MarkdownHighlighter(QSyntaxHighlighter): def highlightEntity(self, text, cursor, bf): found = False for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Entity'],text): - self.setFormat(self.offset+ mo.start(), mo.end() - mo.start(), self.MARKDOWN_KWS_FORMAT['Entity']) + charformat = self.format(self.offset+ mo.start()) + charbold = charformat.fontWeight() == QFont.Weight.Bold + charitalic = charformat.fontItalic() + if charbold and charitalic: + format = self.MARKDOWN_KWS_FORMAT['EntityBoldItalic'] + elif charbold and not charitalic: + format = self.MARKDOWN_KWS_FORMAT['EntityBold'] + elif not charbold and charitalic: + format = self.MARKDOWN_KWS_FORMAT['EntityItalic'] + else: + format = self.MARKDOWN_KWS_FORMAT['Entity'] + self.setFormat(self.offset+ mo.start(), mo.end() - mo.start(), format) found = True return found