clean up newlines in babycode.py
This commit is contained in:
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user