This commit is contained in:
udf 2018-06-12 19:54:43 +02:00
commit ade16c6655
1 changed files with 19 additions and 17 deletions

View File

@ -57,7 +57,7 @@ PARSED_ENTITIES = (
MessageEntityBold, MessageEntityItalic, MessageEntityCode, MessageEntityBold, MessageEntityItalic, MessageEntityCode,
MessageEntityPre, MessageEntityTextUrl 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) # where the parse function takes the match and returns (text, entity)
MATCHERS = [ MATCHERS = [
(DEFAULT_URL_RE, parse_url_match), (DEFAULT_URL_RE, parse_url_match),
@ -72,16 +72,21 @@ MATCHERS = [
def parse(message, old_entities=None): def parse(message, old_entities=None):
entities = [] 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 i = 0
after = 0
message = _add_surrogate(message) message = _add_surrogate(message)
while i < len(message): while i < len(message):
# skip already existing entities if we're at one for after, e in enumerate(old_entities[after:], start=after):
if i in old_entities: # If the next entity is strictly to our right, we're done here
i += old_entities[i].length 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: for pattern, parser in MATCHERS:
match = pattern.match(message, pos=i) match = pattern.match(message, pos=i)
if match: if match:
@ -92,30 +97,27 @@ def parse(message, old_entities=None):
text, entity = parser(match) text, entity = parser(match)
# shift old entities after our current position (so they stay in place) # Shift old entities after our current position (so they stay in place)
shift = len(text) - len(message[match.start():match.end()]) shift = len(text) - len(match[0])
if shift: if shift:
old_entities = old_entities.values() for e in old_entities[after:]:
for entity in old_entities: e.offset += shift
if entity.offset >= i:
entity.offset += shift
old_entities = {e.offset: e for e in old_entities}
# replace whole match with text from parser # Replace whole match with text from parser
message = ''.join(( message = ''.join((
message[:match.start()], message[:match.start()],
text, text,
message[match.end():] message[match.end():]
)) ))
# append entity if we got one # Append entity if we got one
if entity: if entity:
entities.append(entity) entities.append(entity)
# skip past the match # Skip past the match
i += len(text) 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)) @borg.on(events.MessageEdited(outgoing=True))