put images in their own lane
This commit is contained in:
		@@ -2,7 +2,7 @@ from .babycode_parser import Parser
 | 
			
		||||
from markupsafe import escape
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
BABYCODE_VERSION = 1
 | 
			
		||||
BABYCODE_VERSION = 2
 | 
			
		||||
 | 
			
		||||
NAMED_COLORS = [
 | 
			
		||||
    'black', 'silver', 'gray', 'white', 'maroon', 'red',
 | 
			
		||||
@@ -35,7 +35,19 @@ NAMED_COLORS = [
 | 
			
		||||
    'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen',
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
def tag_code(children, attr):
 | 
			
		||||
def is_tag(e, tag):
 | 
			
		||||
    if e is None:
 | 
			
		||||
        return False
 | 
			
		||||
    if isinstance(e, str):
 | 
			
		||||
        return False
 | 
			
		||||
    if e['type'] != 'bbcode':
 | 
			
		||||
        return False
 | 
			
		||||
    return e['name'] == tag
 | 
			
		||||
 | 
			
		||||
def is_text(e):
 | 
			
		||||
    return isinstance(e, str)
 | 
			
		||||
 | 
			
		||||
def tag_code(children, attr, surrounding):
 | 
			
		||||
    is_inline = children.find('\n') == -1
 | 
			
		||||
    if is_inline:
 | 
			
		||||
        return f"<code class=\"inline-code\">{children}</code>"
 | 
			
		||||
@@ -49,7 +61,7 @@ def tag_list(children):
 | 
			
		||||
    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):
 | 
			
		||||
def tag_color(children, attr, surrounding):
 | 
			
		||||
    hex_re = r"^#?([0-9a-f]{6}|[0-9a-f]{3})$"
 | 
			
		||||
    potential_color = attr.lower().strip()
 | 
			
		||||
 | 
			
		||||
@@ -63,31 +75,39 @@ 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):
 | 
			
		||||
def tag_spoiler(children, attr, surrounding):
 | 
			
		||||
    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'><div class='accordion-header'><button type='button' class='accordion-toggle'>+</button><span>{spoiler_name}</span></div>{content}</div>"""
 | 
			
		||||
    return container
 | 
			
		||||
 | 
			
		||||
def tag_image(children, attr, surrounding):
 | 
			
		||||
    img = f"<img class=\"post-image\" src=\"{attr}\" alt=\"{children}\">"
 | 
			
		||||
    if not is_tag(surrounding[0], 'img'):
 | 
			
		||||
        img = f"<div class=post-img-container>{img}"
 | 
			
		||||
    if not is_tag(surrounding[1], 'img'):
 | 
			
		||||
        img = f"{img}</div>"
 | 
			
		||||
    return img
 | 
			
		||||
 | 
			
		||||
TAGS = {
 | 
			
		||||
    "b": lambda children, attr: f"<strong>{children}</strong>",
 | 
			
		||||
    "i": lambda children, attr: f"<em>{children}</em>",
 | 
			
		||||
    "s": lambda children, attr: f"<del>{children}</del>",
 | 
			
		||||
    "u": lambda children, attr: f"<u>{children}</u>",
 | 
			
		||||
    "b": lambda children, attr, _: f"<strong>{children}</strong>",
 | 
			
		||||
    "i": lambda children, attr, _: f"<em>{children}</em>",
 | 
			
		||||
    "s": lambda children, attr, _: f"<del>{children}</del>",
 | 
			
		||||
    "u": lambda children, attr, _: f"<u>{children}</u>",
 | 
			
		||||
 | 
			
		||||
    "img": lambda children, attr: f"<div class=\"post-img-container\"><img class=\"block-img\" src=\"{attr}\" alt=\"{children}\"></div>",
 | 
			
		||||
    "url": lambda children, attr: f"<a href={attr}>{children}</a>",
 | 
			
		||||
    "quote": lambda children, attr: f"<blockquote>{children}</blockquote>",
 | 
			
		||||
    "img": tag_image,
 | 
			
		||||
    "url": lambda children, attr, _: f"<a href={attr}>{children}</a>",
 | 
			
		||||
    "quote": lambda children, attr, _: f"<blockquote>{children}</blockquote>",
 | 
			
		||||
    "code": tag_code,
 | 
			
		||||
    "ul": lambda children, attr: f"<ul>{tag_list(children)}</ul>",
 | 
			
		||||
    "ol": lambda children, attr: f"<ol>{tag_list(children)}</ol>",
 | 
			
		||||
    "ul": lambda children, attr, _: f"<ul>{tag_list(children)}</ul>",
 | 
			
		||||
    "ol": lambda children, attr, _: f"<ol>{tag_list(children)}</ol>",
 | 
			
		||||
 | 
			
		||||
    "big": lambda children, attr: f"<span style='font-size: 2rem;'>{children}</span>",
 | 
			
		||||
    "small": lambda children, attr: f"<span style='font-size: 0.75rem;'>{children}</span>",
 | 
			
		||||
    "big": lambda children, attr, _: f"<span style='font-size: 2rem;'>{children}</span>",
 | 
			
		||||
    "small": lambda children, attr, _: f"<span style='font-size: 0.75rem;'>{children}</span>",
 | 
			
		||||
    "color": tag_color,
 | 
			
		||||
 | 
			
		||||
    "center": lambda children, attr: f"<div style='text-align: center;'>{children}</div>",
 | 
			
		||||
    "right": lambda children, attr: f"<div style='text-align: right;'>{children}</div>",
 | 
			
		||||
    "center": lambda children, attr, _: f"<div style='text-align: center;'>{children}</div>",
 | 
			
		||||
    "right": lambda children, attr, _: f"<div style='text-align: right;'>{children}</div>",
 | 
			
		||||
 | 
			
		||||
    "spoiler": tag_spoiler,
 | 
			
		||||
}
 | 
			
		||||
@@ -156,9 +176,8 @@ def babycode_to_html(s):
 | 
			
		||||
    parser.valid_emotes = EMOJI.keys()
 | 
			
		||||
 | 
			
		||||
    elements = parser.parse()
 | 
			
		||||
    # print(elements)
 | 
			
		||||
    out = ""
 | 
			
		||||
    def fold(element, nobr):
 | 
			
		||||
    def fold(element, nobr, surrounding):
 | 
			
		||||
        if isinstance(element, str):
 | 
			
		||||
            if nobr:
 | 
			
		||||
                return element
 | 
			
		||||
@@ -167,10 +186,16 @@ def babycode_to_html(s):
 | 
			
		||||
        match element['type']:
 | 
			
		||||
            case "bbcode":
 | 
			
		||||
                c = ""
 | 
			
		||||
                for child in element['children']:
 | 
			
		||||
                for i in range(len(element['children'])):
 | 
			
		||||
                    child = element['children'][i]
 | 
			
		||||
                    _surrounding = (
 | 
			
		||||
                        element['children'][i - 1] if i-1 >= 0 else None,
 | 
			
		||||
                        element['children'][i + 1] if i+1 < len(element['children']) else None
 | 
			
		||||
                        )
 | 
			
		||||
                    _nobr = element['name'] == "code" or element['name'] == "ul" or element['name'] == "ol"
 | 
			
		||||
                    c = c + fold(child, _nobr)
 | 
			
		||||
                res = TAGS[element['name']](c, element['attr'])
 | 
			
		||||
                    c = c + fold(child, _nobr, _surrounding)
 | 
			
		||||
 | 
			
		||||
                res = TAGS[element['name']](c, element['attr'], surrounding)
 | 
			
		||||
                return res
 | 
			
		||||
            case "link":
 | 
			
		||||
                return f"<a href=\"{element['url']}\">{element['url']}</a>"
 | 
			
		||||
@@ -178,6 +203,13 @@ def babycode_to_html(s):
 | 
			
		||||
                return EMOJI[element['name']]
 | 
			
		||||
            case "rule":
 | 
			
		||||
                return "<hr>"
 | 
			
		||||
    for e in elements:
 | 
			
		||||
        out = out + fold(e, False)
 | 
			
		||||
    # for e in elements:
 | 
			
		||||
    #     out = out + fold(e, False)
 | 
			
		||||
    for i in range(len(elements)):
 | 
			
		||||
        e = elements[i]
 | 
			
		||||
        surrounding = (
 | 
			
		||||
            elements[i - 1] if i-1 >= 0 else None,
 | 
			
		||||
            elements[i + 1] if i+1 < len(elements) else None
 | 
			
		||||
            )
 | 
			
		||||
        out = out + fold(e, False, surrounding)
 | 
			
		||||
    return out
 | 
			
		||||
 
 | 
			
		||||
@@ -126,8 +126,8 @@
 | 
			
		||||
        <code class="inline-code">[img=https://forum.poto.cafe/avatars/default.webp]the Python logo with a cowboy hat[/img]</code>
 | 
			
		||||
        {{ '[img=/static/avatars/default.webp]the Python logo with a cowboy hat[/img]' | babycode | safe }}
 | 
			
		||||
        </p>
 | 
			
		||||
        <p>Text inside the tag becomes the alt text. The attribute is the image URL.</p>
 | 
			
		||||
        <p>Images will always break up a paragraph and will get scaled down to a maximum of 400px. The text inside the tag will become the image's alt text.</p>
 | 
			
		||||
        <p>Text inside the tag becomes the alt text. The attribute is the image URL. The text inside the tag will become the image's alt text.</p>
 | 
			
		||||
        <p>Images will always break up a paragraph and will get scaled down to a maximum of 400px. However, if there is no space between consecutive <code class="inline-code">[img]</code> tags,  </p>
 | 
			
		||||
        <p>Multiple images attached to a post can be clicked to open a dialog to view them.</p>
 | 
			
		||||
      </section>
 | 
			
		||||
      <section class="babycode-guide-section">
 | 
			
		||||
 
 | 
			
		||||
@@ -142,8 +142,22 @@ document.addEventListener("DOMContentLoaded", () => {
 | 
			
		||||
  //lightboxes
 | 
			
		||||
  lightboxObj = constructLightbox();
 | 
			
		||||
  document.body.appendChild(lightboxObj.dialog);
 | 
			
		||||
  const postImages = document.querySelectorAll(".post-inner img.block-img");
 | 
			
		||||
 | 
			
		||||
  function setImageMaxSize(img) {
 | 
			
		||||
    const { maxWidth: origMaxWidth } = getComputedStyle(img);
 | 
			
		||||
    if (img.naturalWidth >= parseInt(origMaxWidth)) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    img.style.maxWidth = img.naturalWidth + "px";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const postImages = document.querySelectorAll(".post-inner img.post-image");
 | 
			
		||||
  postImages.forEach(postImage => {
 | 
			
		||||
    if (postImage.complete) {
 | 
			
		||||
      setImageMaxSize(postImage);
 | 
			
		||||
    } else {
 | 
			
		||||
      postImage.addEventListener("load", () => setImageMaxSize(postImage));
 | 
			
		||||
    }
 | 
			
		||||
    const belongingTo = postImage.closest(".post-inner");
 | 
			
		||||
    const images = lightboxImages.get(belongingTo) ?? [];
 | 
			
		||||
    images.push({
 | 
			
		||||
 
 | 
			
		||||
@@ -511,10 +511,21 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.block-img {
 | 
			
		||||
.post-img-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  gap: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.post-image {
 | 
			
		||||
  object-fit: contain;
 | 
			
		||||
  max-width: 400px;
 | 
			
		||||
  max-height: 400px;
 | 
			
		||||
  max-width: 300px;
 | 
			
		||||
  max-height: 300px;
 | 
			
		||||
  min-width: 200px;
 | 
			
		||||
  min-height: 200px;
 | 
			
		||||
  flex: 1 1 0%;
 | 
			
		||||
  width: auto;
 | 
			
		||||
  height: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.thread-info-container {
 | 
			
		||||
 
 | 
			
		||||
@@ -512,10 +512,21 @@ input[type="text"], input[type="password"], textarea, select {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.block-img {
 | 
			
		||||
.post-img-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  gap: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.post-image {
 | 
			
		||||
  object-fit: contain;
 | 
			
		||||
  max-width: 400px;
 | 
			
		||||
  max-height: 400px;
 | 
			
		||||
  min-width: 200px;
 | 
			
		||||
  min-height: 200px;
 | 
			
		||||
  flex: 1 1 0%;
 | 
			
		||||
  width: auto;
 | 
			
		||||
  height: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.thread-info-container {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user