Linkify typed usernames/id in markdown
This commit is contained in:
parent
728c47f159
commit
f858e505a6
|
@ -3,6 +3,8 @@
|
||||||
"""HTML and Markdown processing tools."""
|
"""HTML and Markdown processing tools."""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
from typing import Dict, Optional
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
import html_sanitizer.sanitizer as sanitizer
|
import html_sanitizer.sanitizer as sanitizer
|
||||||
import mistune
|
import mistune
|
||||||
|
@ -162,13 +164,33 @@ class HTMLProcessor:
|
||||||
|
|
||||||
|
|
||||||
def from_markdown(
|
def from_markdown(
|
||||||
self, text: str, inline: bool = False, outgoing: bool = False,
|
self,
|
||||||
|
text: str,
|
||||||
|
inline: bool = False,
|
||||||
|
outgoing: bool = False,
|
||||||
|
mentionable_users: Optional[Dict[str, str]] = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Return filtered HTML from Markdown text."""
|
"""Return filtered HTML from Markdown text."""
|
||||||
|
|
||||||
|
if mentionable_users:
|
||||||
|
text = self.markdown_linkify_users(text, mentionable_users)
|
||||||
|
|
||||||
return self.filter(self._markdown_to_html(text), inline, outgoing)
|
return self.filter(self._markdown_to_html(text), inline, outgoing)
|
||||||
|
|
||||||
|
|
||||||
|
def markdown_linkify_users(self, text: str, users: Dict[str, str]) -> str:
|
||||||
|
print(text)
|
||||||
|
|
||||||
|
for user_id, username in users.items():
|
||||||
|
repl = rf"\1[{user_id}](https://matrix.to/#/{quote(user_id)})\2"
|
||||||
|
text = re.sub(rf"(^|\W){user_id}($|\W)", repl, text)
|
||||||
|
|
||||||
|
repl = rf"\1[{username}](https://matrix.to/#/{quote(user_id)})\2"
|
||||||
|
text = re.sub(rf"(^|\W){username}($|\W)", repl, text)
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
def filter(
|
def filter(
|
||||||
self, html: str, inline: bool = False, outgoing: bool = False,
|
self, html: str, inline: bool = False, outgoing: bool = False,
|
||||||
) -> str:
|
) -> str:
|
||||||
|
|
|
@ -308,6 +308,15 @@ class MatrixClient(nio.AsyncClient):
|
||||||
async def send_text(self, room_id: str, text: str) -> None:
|
async def send_text(self, room_id: str, text: str) -> None:
|
||||||
"""Send a markdown `m.text` or `m.notice` (with `/me`) message ."""
|
"""Send a markdown `m.text` or `m.notice` (with `/me`) message ."""
|
||||||
|
|
||||||
|
from_md = partial(
|
||||||
|
HTML.from_markdown,
|
||||||
|
mentionable_users={
|
||||||
|
user_id: member.display_name or user_id
|
||||||
|
for user_id, member in
|
||||||
|
self.models[self.user_id, room_id, "members"].items()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
escape = False
|
escape = False
|
||||||
if text.startswith("//") or text.startswith(r"\/"):
|
if text.startswith("//") or text.startswith(r"\/"):
|
||||||
escape = True
|
escape = True
|
||||||
|
@ -317,13 +326,13 @@ class MatrixClient(nio.AsyncClient):
|
||||||
event_type = nio.RoomMessageEmote
|
event_type = nio.RoomMessageEmote
|
||||||
text = text[len("/me "): ]
|
text = text[len("/me "): ]
|
||||||
content = {"body": text, "msgtype": "m.emote"}
|
content = {"body": text, "msgtype": "m.emote"}
|
||||||
to_html = HTML.from_markdown(text, inline=True, outgoing=True)
|
to_html = from_md(text, inline=True, outgoing=True)
|
||||||
echo_body = HTML.from_markdown(text, inline=True)
|
echo_body = from_md(text, inline=True)
|
||||||
else:
|
else:
|
||||||
event_type = nio.RoomMessageText
|
event_type = nio.RoomMessageText
|
||||||
content = {"body": text, "msgtype": "m.text"}
|
content = {"body": text, "msgtype": "m.text"}
|
||||||
to_html = HTML.from_markdown(text, outgoing=True)
|
to_html = from_md(text, outgoing=True)
|
||||||
echo_body = HTML.from_markdown(text)
|
echo_body = from_md(text)
|
||||||
|
|
||||||
if to_html not in (html.escape(text), f"<p>{html.escape(text)}</p>"):
|
if to_html not in (html.escape(text), f"<p>{html.escape(text)}</p>"):
|
||||||
content["format"] = "org.matrix.custom.html"
|
content["format"] = "org.matrix.custom.html"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user