clean up newlines in babycode.py

This commit is contained in:
2025-12-14 08:40:38 +03:00
parent d7a90745f6
commit 36e17c6677

View File

@@ -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' <img class=emoji src="/static/emoji/{name}.png" alt="{name}" title=":{code}:">'
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", "<br>", children.strip())
list_body = re.sub(r"\n\n+", "\1", list_body)
return " ".join([f"<li>{x}</li>" 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"<div class='accordion-content post-accordion-content hidden'>{children}</div>"
container = f"""<div class='accordion hidden' data-receive='toggleAccordion'><div class='accordion-header'><button type='button' class='accordion-toggle' data-send='toggleAccordion'>+</button><span>{spoiler_name}</span></div>{content}</div>"""
return container
def tag_image(children, attr):
img = f"<img class=\"post-image\" src=\"{attr}\" alt=\"{children}\">"
return f"<div class=post-img-container>{img}</div>"
TAGS = {
"b": lambda children, attr: f"<strong>{children}</strong>",
"i": lambda children, attr: f"<em>{children}</em>",
@@ -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"<a href={attr}>{children}</a>"
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'<img src="{attr}" alt={children} />'
RSS_TAGS = {
**TAGS,
'img': tag_image_rss,
@@ -438,6 +455,7 @@ RSS_TAGS = {
'small': lambda children, attr: f'<small>{children}</small>'
}
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 <img> 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"<a class='mention{' display' if target_user.has_display_name() else ''}' href='{url_for('users.page', username=target_user.username)}' title='@{target_user.username}' data-init='highlightMentions' data-username='{target_user.username}'>{'@' if not target_user.has_display_name() else ''}{target_user.get_readable_name()}</a>"
def should_collapse(text, surrounding):
if not isinstance(text, str):