diff options
Diffstat (limited to 'syntax_highlight/chat_syntax_highlighter.py')
-rw-r--r-- | syntax_highlight/chat_syntax_highlighter.py | 108 |
1 files changed, 58 insertions, 50 deletions
diff --git a/syntax_highlight/chat_syntax_highlighter.py b/syntax_highlight/chat_syntax_highlighter.py index c18cc18..338dd62 100644 --- a/syntax_highlight/chat_syntax_highlighter.py +++ b/syntax_highlight/chat_syntax_highlighter.py @@ -8,12 +8,22 @@ from syntax_highlight.gtkformatter import GTKFormatter from syntax_highlight.types import MatchType from syntax_highlight.types import LineBreakOptions from syntax_highlight.types import CodeMarkerOptions +from syntax_highlight.types import PLUGIN_INTERNAL_NONE_LEXER_ID log = logging.getLogger('gajim.p.syntax_highlight') class ChatSyntaxHighlighter: - def hide_code_markup(self, buf, start, end): + def __init__(self, plugin_config, highlighter_config, textview): + self.textview = textview + self._plugin_config = plugin_config + self._highlighter_config = highlighter_config + + def update_config(self, plugin_config): + self._plugin_config = plugin_config + + @staticmethod + def _hide_code_markup(buf, start, end): tag = buf.get_tag_table().lookup('hide_code_markup') if tag is None: tag = Gtk.TextTag.new('hide_code_markup') @@ -22,17 +32,16 @@ class ChatSyntaxHighlighter: buf.apply_tag_by_name('hide_code_markup', start, end) - def check_line_break(self, is_multiline): - line_break = self.config.get_line_break_action() - + def _check_line_break(self, is_multiline): + line_break = self._plugin_config['line_break'].value return (line_break == LineBreakOptions.ALWAYS) \ or (is_multiline and line_break == LineBreakOptions.MULTILINE) - def format_code(self, buf, s_tag, s_code, e_tag, e_code, language): - style = self.config.get_style_name() - if self.config.get_code_marker_setting() == CodeMarkerOptions.HIDE: - self.hide_code_markup(buf, s_tag, s_code) - self.hide_code_markup(buf, e_code, e_tag) + def _format_code(self, buf, s_tag, s_code, e_tag, e_code, language): + style = self._plugin_config['style'] + if self._plugin_config['code_marker'] == CodeMarkerOptions.HIDE: + self._hide_code_markup(buf, s_tag, s_code) + self._hide_code_markup(buf, e_code, e_tag) else: comment_tag = GTKFormatter.create_tag_for_token( pygments.token.Comment, @@ -49,24 +58,25 @@ class ChatSyntaxHighlighter: lexer = None if language is None: - lexer = self.config.get_default_lexer() + lexer = self._highlighter_config.get_default_lexer() log.info('No Language specified. ' 'Falling back to default lexer: %s.', - self.config.get_default_lexer_name()) + self._highlighter_config.get_default_lexer_name()) else: log.debug('Using lexer for %s.', str(language)) - lexer = self.config.get_lexer_with_fallback(language) + lexer = self._highlighter_config.get_lexer_with_fallback(language) if lexer is None: iterator = buf.get_iter_at_mark(start_mark) buf.insert(iterator, '\n') - elif not self.config.is_internal_none_lexer(lexer): + elif lexer != PLUGIN_INTERNAL_NONE_LEXER_ID: tokens = pygments.lex(code, lexer) formatter = GTKFormatter(style=style, start_mark=start_mark) pygments.format(tokens, formatter, buf) - def find_multiline_matches(self, text): + @staticmethod + def _find_multiline_matches(text): start = None matches = [] # Less strict, allow prefixed whitespaces: @@ -84,7 +94,8 @@ class ChatSyntaxHighlighter: continue return matches - def find_inline_matches(self, text): + @staticmethod + def _find_inline_matches(text): """ Inline code is highlighted if the start marker is precedded by a start of line, a whitespace character or either of the other span markers @@ -95,18 +106,19 @@ class ChatSyntaxHighlighter: re.finditer(r'(?:^|\s|\*|~|_)(`((?!`).+?)`)(?:\s|\*|~|_|$)', text)] - def merge_match_groups(self, real_text, inline_matches, multiline_matches): + @staticmethod + def _merge_match_groups(real_text, inline_matches, multiline_matches): it_inline = iter(inline_matches) it_multi = iter(multiline_matches) length = len(real_text) # Just to get cleaner code below... - def get_next(iterator): + def _get_next(iterator): return next(iterator, (length, length, '')) # In order to simplify the process, we use the 'length' here. - cur_inline = get_next(it_inline) - cur_multi = get_next(it_multi) + cur_inline = _get_next(it_inline) + cur_multi = _get_next(it_multi) pos = 0 @@ -142,18 +154,18 @@ class ChatSyntaxHighlighter: # Also, forward the other one, if regions overlap or we took over... if selected[2] == MatchType.INLINE: if cur_multi[0] < cur_inline[1]: - cur_multi = get_next(it_multi) - cur_inline = get_next(it_inline) + cur_multi = _get_next(it_multi) + cur_inline = _get_next(it_inline) elif selected[2] == MatchType.MULTILINE: if cur_inline[0] < cur_multi[1]: - cur_inline = get_next(it_inline) - cur_multi = get_next(it_multi) + cur_inline = _get_next(it_inline) + cur_multi = _get_next(it_multi) return parts def process_text(self, real_text, other_tags, _graphics, iter_, - _additional): - def fix_newline(char, marker_len_no_newline, force=False): + _additional): + def _fix_newline(char, marker_len_no_newline, force=False): fixed = (marker_len_no_newline, '') if char == '\n': fixed = (marker_len_no_newline + 1, '') @@ -164,8 +176,8 @@ class ChatSyntaxHighlighter: buf = self.textview.tv.get_buffer() # First, try to find inline or multiline code snippets - inline_matches = self.find_inline_matches(real_text) - multiline_matches = self.find_multiline_matches(real_text) + inline_matches = self._find_inline_matches(real_text) + multiline_matches = self._find_multiline_matches(real_text) if not inline_matches and not multiline_matches: log.debug('Stopping early, since there is no code block in it...') @@ -177,10 +189,10 @@ class ChatSyntaxHighlighter: start_mark = buf.create_mark('SHP_start', iterator, True) end_mark = buf.create_mark('SHP_end', iterator, False) - insert_newline_for_multiline = self.check_line_break(True) - insert_newline_for_inline = self.check_line_break(False) + insert_newline_for_multiline = self._check_line_break(True) + insert_newline_for_inline = self._check_line_break(False) - split_text = self.merge_match_groups( + split_text = self._merge_match_groups( real_text, inline_matches, multiline_matches) buf.begin_user_action() @@ -204,20 +216,20 @@ class ChatSyntaxHighlighter: language_len = 0 if language is None else len(language) # We account the language word width for the front marker - front = fix_newline( + front = _fix_newline( text_to_insert[0], 3 + language_len, insert_newline_for_multiline) - back = fix_newline( + back = _fix_newline( text_to_insert[-1], 3, insert_newline_for_multiline and not end_of_message) else: - front = fix_newline( + front = _fix_newline( text_to_insert[0], 1, insert_newline_for_inline) - back = fix_newline( + back = _fix_newline( text_to_insert[-1], 1, insert_newline_for_inline and not end_of_message) @@ -226,8 +238,9 @@ class ChatSyntaxHighlighter: text_to_insert = ''.join([front[1], text_to_insert, back[1]]) # Insertion invalidates iterator, let's use our start mark... - self.insert_and_format_code(buf, text_to_insert, language, - marker_widths, start_mark, end_mark, other_tags) + self._insert_and_format_code( + buf, text_to_insert, language, marker_widths, start_mark, + end_mark, other_tags) iterator = buf.get_iter_at_mark(end_mark) # The current end of the buffer's contents is the start for the @@ -244,14 +257,13 @@ class ChatSyntaxHighlighter: # print_special_text method is resetting the plugin_modified variable... self.textview.plugin_modified = True - def insert_and_format_code(self, buf, insert_text, language, marker, - start_mark, end_mark, other_tags=None): + def _insert_and_format_code(self, buf, insert_text, language, marker, + start_mark, end_mark, other_tags=None): start_iter = buf.get_iter_at_mark(start_mark) if other_tags: - buf.insert_with_tags_by_name(start_iter, insert_text, - *other_tags) + buf.insert_with_tags_by_name(start_iter, insert_text, *other_tags) else: buf.insert(start_iter, insert_text) @@ -264,20 +276,16 @@ class ChatSyntaxHighlighter: log.debug('full text between tags: %s.', tag_start.get_text(tag_end)) - self.format_code(buf, tag_start, s_code, tag_end, e_code, language) + self._format_code(buf, tag_start, s_code, tag_end, e_code, language) self.textview.plugin_modified = True # Set general code block format tag = Gtk.TextTag.new() - if self.config.is_bgcolor_override_enabled(): - tag.set_property('background', self.config.get_bgcolor()) - tag.set_property('paragraph-background', self.config.get_bgcolor()) - tag.set_property('font', self.config.get_font()) + bg_color = self._plugin_config['bgcolor'] + if self._plugin_config['bgcolor_override']: + tag.set_property('background', bg_color) + tag.set_property('paragraph-background', bg_color) + tag.set_property('font', self._plugin_config['font']) buf.get_tag_table().add(tag) buf.apply_tag(tag, tag_start, tag_end) - - def __init__(self, config, textview): - self.last_end_mark = None - self.config = config - self.textview = textview |