diff --git a/app/lib/babycode.py b/app/lib/babycode.py
index 91b6cda..33931e7 100644
--- a/app/lib/babycode.py
+++ b/app/lib/babycode.py
@@ -8,12 +8,15 @@ import re
BABYCODE_VERSION = 8
+
class BabycodeError(Exception):
pass
+
class BabycodeRenderError(BabycodeError):
pass
+
class UnknownASTElementError(BabycodeRenderError):
def __init__(self, element_type, element=None):
self.element_type = element_type
@@ -24,6 +27,7 @@ class UnknownASTElementError(BabycodeRenderError):
message += f' (element: {element})'
super().__init__(message)
+
class BabycodeRenderResult:
def __init__(self, result, mentions=[]):
self.result = result
@@ -232,9 +236,11 @@ NAMED_COLORS = [
'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen',
]
+
def make_emoji(name, code):
return f'
'
+
EMOJI = {
'angry': make_emoji('angry', 'angry'),
@@ -281,6 +287,7 @@ EMOJI = {
'wink': make_emoji('wink', 'wink'),
}
+
RSS_EMOJI = {
**EMOJI,
@@ -329,8 +336,10 @@ RSS_EMOJI = {
'wink': '😉',
}
+
TEXT_ONLY = ["code"]
+
def tag_code(children, attr):
is_inline = children.find('\n') == -1
if is_inline:
@@ -348,11 +357,13 @@ def tag_code(children, attr):
except PygmentsClassNotFound:
return unhighlighted
+
def tag_list(children):
list_body = re.sub(r" +\n", "
", children.strip())
list_body = re.sub(r"\n\n+", "\1", list_body)
return " ".join([f"
{x}" for x in list_body.split("\1") if x])
+
def tag_color(children, attr):
if not attr:
return f"[color]{children}[/color]"
@@ -370,16 +381,19 @@ def tag_color(children, attr):
# return just the way it was if we can't parse it
return f"[color={attr}]{children}[/color]"
+
def tag_spoiler(children, attr):
spoiler_name = attr if attr else "Spoiler"
content = f"{children}
"
container = f"""{content}
"""
return container
+
def tag_image(children, attr):
img = f"
"
return f"{img}
"
+
TAGS = {
"b": lambda children, attr: f"{children}",
"i": lambda children, attr: f"{children}",
@@ -403,6 +417,7 @@ TAGS = {
"spoiler": tag_spoiler,
}
+
def tag_code_rss(children, attr):
is_inline = children.find('\n') == -1
if is_inline:
@@ -419,6 +434,7 @@ def tag_url_rss(children, attr):
return f"{children}"
+
def tag_image_rss(children, attr):
if attr.startswith('/'):
from flask import current_app
@@ -427,6 +443,7 @@ def tag_image_rss(children, attr):
return f'
'
+
RSS_TAGS = {
**TAGS,
'img': tag_image_rss,
@@ -438,6 +455,7 @@ RSS_TAGS = {
'small': lambda children, attr: f'{children}'
}
+
VOID_TAGS = {
'lb': lambda attr: '[',
'rb': lambda attr: ']',
@@ -445,6 +463,7 @@ VOID_TAGS = {
'd': lambda attr: '-',
}
+
# [img] is considered block for the purposes of collapsing whitespace,
# despite being potentially inline (since the resulting
tag is inline, but creates a block container around itself and sibling images).
# [code] has a special case in is_inline().
@@ -452,6 +471,7 @@ INLINE_TAGS = {
'b', 'i', 's', 'u', 'color', 'big', 'small', 'url', 'lb', 'rb', 'at', 'd'
}
+
def is_tag(e, tag=None):
if e is None:
return False
@@ -465,9 +485,11 @@ def is_tag(e, tag=None):
return e['name'] == tag
+
def is_text(e):
return isinstance(e, str)
+
def is_inline(e):
if e is None:
return False # i think
@@ -483,24 +505,6 @@ def is_inline(e):
return e['type'] != 'rule'
-def make_mention(e, mentions):
- from ..models import Users
- from flask import url_for, current_app
- with current_app.test_request_context('/'):
- target_user = Users.find({'username': e['name'].lower()})
- if not target_user:
- return f"@{e['name']}"
-
- mention_data = {
- 'mention_text': f"@{e['name']}",
- 'mentioned_user_id': int(target_user.id),
- "start": e['start'],
- "end": e['end'],
- }
- if mention_data not in mentions:
- mentions.append(mention_data)
-
- return f"{'@' if not target_user.has_display_name() else ''}{target_user.get_readable_name()}"
def should_collapse(text, surrounding):
if not isinstance(text, str):