diff --git a/src/backend/html_markdown.py b/src/backend/html_markdown.py
index 8db07257..18cbf301 100644
--- a/src/backend/html_markdown.py
+++ b/src/backend/html_markdown.py
@@ -130,6 +130,16 @@ class HTMLProcessor:
extra_newlines_regex = re.compile(r"\n(\n*)")
+ user_id_mention_regex = re.compile(
+ r"(?=^|\W)@.+?:[a-zA-Z\d.-:]*[a-zA-Z\d]",
+ )
+ room_id_mention_regex = re.compile(
+ r"(?=^|\W)!.+?:[a-zA-Z\d.-:]*[a-zA-Z\d]",
+ )
+ room_alias_mention_regex = re.compile(
+ r"(?=^|\W)#.+?:[a-zA-Z\d.-:]*[a-zA-Z\d]",
+ )
+
def __init__(self) -> None:
self._sanitizers = {
@@ -168,25 +178,33 @@ class HTMLProcessor:
text: str,
inline: bool = False,
outgoing: bool = False,
- mentionable_users: Optional[Dict[str, str]] = None,
+ mentionable_users: Optional[Dict[str, str]] = None, # {id: name}
) -> str:
"""Return filtered HTML from Markdown text."""
- if mentionable_users:
- text = self.markdown_linkify_users(text, mentionable_users)
-
+ text = self.markdown_linkify_users_rooms(text, mentionable_users)
return self.filter(self._markdown_to_html(text), inline, outgoing)
- def markdown_linkify_users(self, text: str, users: Dict[str, str]) -> str:
- print(text)
+ def markdown_linkify_users_rooms(
+ self, text: str, usernames: Optional[Dict[str, str]] = None,
+ ) -> str:
+ """Turn usernames, user ID, room alias, room ID into matrix.to URL."""
- 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)
+ def repl_func(m) -> str:
+ return rf"[{m.group(0)}](https://matrix.to/#/{quote(m.group(0))})"
- repl = rf"\1[{username}](https://matrix.to/#/{quote(user_id)})\2"
- text = re.sub(rf"(^|\W){username}($|\W)", repl, text)
+ text = self.user_id_mention_regex.sub(repl_func, text)
+ text = self.room_id_mention_regex.sub(repl_func, text)
+ text = self.room_alias_mention_regex.sub(repl_func, text)
+
+ for user_id, username in (usernames or {}).items():
+ text = re.sub(
+ rf"(?