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,
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))