diff --git a/stdplugins/markdown.py b/stdplugins/markdown.py index 976c936..bee0372 100644 --- a/stdplugins/markdown.py +++ b/stdplugins/markdown.py @@ -57,7 +57,7 @@ PARSED_ENTITIES = ( MessageEntityBold, MessageEntityItalic, MessageEntityCode, MessageEntityPre, MessageEntityTextUrl ) -# a matcher is a tuple of (regex pattern, parse function) +# A matcher is a tuple of (regex pattern, parse function) # where the parse function takes the match and returns (text, entity) MATCHERS = [ (DEFAULT_URL_RE, parse_url_match), @@ -72,16 +72,21 @@ MATCHERS = [ def parse(message, old_entities=None): entities = [] - old_entities = {e.offset: e for e in old_entities or []} + old_entities = sorted(old_entities or [], key=lambda e: e.offset) i = 0 + after = 0 message = _add_surrogate(message) while i < len(message): - # skip already existing entities if we're at one - if i in old_entities: - i += old_entities[i].length + for after, e in enumerate(old_entities[after:], start=after): + # If the next entity is strictly to our right, we're done here + if i < e.offset: + break + # Skip already existing entities if we're at one + if i == e.offset: + i += e.length - # find the first pattern that matches + # Find the first pattern that matches for pattern, parser in MATCHERS: match = pattern.match(message, pos=i) if match: @@ -92,30 +97,27 @@ def parse(message, old_entities=None): text, entity = parser(match) - # shift old entities after our current position (so they stay in place) - shift = len(text) - len(message[match.start():match.end()]) + # Shift old entities after our current position (so they stay in place) + shift = len(text) - len(match[0]) if shift: - old_entities = old_entities.values() - for entity in old_entities: - if entity.offset >= i: - entity.offset += shift - old_entities = {e.offset: e for e in old_entities} + for e in old_entities[after:]: + e.offset += shift - # replace whole match with text from parser + # Replace whole match with text from parser message = ''.join(( message[:match.start()], text, message[match.end():] )) - # append entity if we got one + # Append entity if we got one if entity: entities.append(entity) - # skip past the match + # Skip past the match i += len(text) - return _del_surrogate(message), entities + list(old_entities.values()) + return _del_surrogate(message), entities + old_entities @borg.on(events.MessageEdited(outgoing=True))