Skip to content

Commit 449a901

Browse files
committed
refactor HTML and Markdown parsers
1 parent fd29eef commit 449a901

10 files changed

Lines changed: 1433 additions & 693 deletions

File tree

pyrogram/parser/combined.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from __future__ import annotations
2+
3+
from typing import List, Optional
4+
5+
import pyrogram
6+
from pyrogram.types.messages_and_media.message_entity import MessageEntity
7+
8+
from .rendering import make_entity_list
9+
from .html import HTML
10+
from .markdown import Markdown
11+
from .types import ParseResult
12+
from .utils import add_surrogates
13+
14+
15+
class CombinedParser:
16+
def __init__(self, client: Optional["pyrogram.Client"]) -> None:
17+
self.client = client
18+
self.html = HTML(client)
19+
self.markdown = Markdown(client)
20+
21+
async def parse(self, text: str) -> ParseResult:
22+
html_result = await self.html.parse(text)
23+
source = html_result["message"]
24+
html_entities = list(html_result["entities"] or [])
25+
26+
markdown_result = await self.markdown.parse(source)
27+
message = markdown_result["message"]
28+
markdown_entities = list(markdown_result["entities"] or [])
29+
30+
if html_entities:
31+
mapping = self._build_subsequence_map(add_surrogates(source), add_surrogates(message))
32+
html_entities = [self._remap_entity(entity, mapping) for entity in html_entities]
33+
34+
entities = [*markdown_entities, *html_entities]
35+
entities.sort(key=lambda entity: (entity.offset, entity.length))
36+
37+
return {
38+
"message": message,
39+
"entities": make_entity_list(entities)
40+
}
41+
42+
@staticmethod
43+
def _build_subsequence_map(source: str, plain: str) -> List[int]:
44+
mapping: List[int] = [0] * (len(source) + 1)
45+
plain_index = 0
46+
47+
for source_index, char in enumerate(source):
48+
mapping[source_index] = plain_index
49+
50+
if plain_index < len(plain) and char == plain[plain_index]:
51+
plain_index += 1
52+
53+
mapping[source_index + 1] = plain_index
54+
55+
return mapping
56+
57+
@staticmethod
58+
def _remap_entity(entity: MessageEntity, mapping: List[int]) -> MessageEntity:
59+
start = mapping[entity.offset]
60+
end = mapping[entity.offset + entity.length]
61+
62+
return MessageEntity(
63+
type=entity.type,
64+
offset=start,
65+
length=end - start,
66+
url=entity.url,
67+
user=entity.user,
68+
language=entity.language,
69+
custom_emoji_id=entity.custom_emoji_id,
70+
expandable=entity.expandable,
71+
unix_time=entity.unix_time,
72+
date_time_format=entity.date_time_format
73+
)

0 commit comments

Comments
 (0)