77 lines
2.3 KiB
Python
77 lines
2.3 KiB
Python
import random, functools, os
|
|
from html import escape
|
|
|
|
_rand_n = lambda: functools.reduce(lambda x, y: (x<<8)+y,os.urandom(4))
|
|
|
|
ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"
|
|
USED_IDS = set()
|
|
def rand_id():
|
|
n = _rand_n()
|
|
id = ""
|
|
while n>0:
|
|
n, index = divmod(n,len(ALPHABET))
|
|
id = ALPHABET[index]+id
|
|
if id in USED_IDS: return rand_id()
|
|
return id
|
|
|
|
def gem2html(content,link_callback=lambda url, text: (url, text)):
|
|
lines = content.splitlines()
|
|
out = "<body>\n"
|
|
pre = False
|
|
pre_alt = False
|
|
for line in lines:
|
|
if pre:
|
|
if line[:3]=="```":
|
|
pre=False
|
|
out+="</pre>\n"
|
|
if pre_alt:
|
|
out+="</figure>\n"
|
|
pre_alt=False
|
|
else:
|
|
out+=escape(line)+"\n"
|
|
else:
|
|
if line[:3]=="```":
|
|
if len(line)>3:
|
|
cap_id = rand_id()
|
|
out+="<figure role='img' aria-captionedby='{0}'><figcaption id='{0}' style='clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px;'>{1}</figcaption>\n".format(cap_id,escape(line[3:]))
|
|
pre_alt = True
|
|
pre = True
|
|
out+="<pre>\n"
|
|
elif line.startswith("#"):
|
|
if line[:3]=="###":
|
|
out+="<h3>{}</h3>".format(escape(line[3:].strip()))
|
|
elif line[:2]=="##":
|
|
out+="<h2>{}</h2>".format(escape(line[2:].strip()))
|
|
elif line[:1]=="#":
|
|
out+="<h1>{}</h1>".format(escape(line[1:].strip()))
|
|
elif line.startswith("* "):
|
|
out += "<ul>\n<li>{}</li>\n</ul>\n".format(escape(line[1:].strip()))
|
|
# combine consecutive unordered list items into one unordered list
|
|
out = out.replace("</ul>\n<ul>\n","")
|
|
elif line.startswith("=>"):
|
|
parts = line.split(None,2)
|
|
try:
|
|
url, text = parts[1:]
|
|
except ValueError:
|
|
try:
|
|
url=parts[1]
|
|
text=parts[1]
|
|
except:
|
|
# no link content at all
|
|
# just put a literal => in there
|
|
out+="<p></p>".format(escape(parts[0]))
|
|
continue
|
|
# now comes the fun part, use the link callback to mutilate these
|
|
url, text = link_callback(url, text)
|
|
# and now render
|
|
out+="<p><a href='{}'>{}</a></p>".format(escape(url),escape(text))
|
|
elif line.startswith(">"):
|
|
out+="<blockquote><p>{}</p></blockquote>".format(escape(line))
|
|
else: # any other line is a text line
|
|
if line:
|
|
out+="<p>{}</p>".format(escape(line))
|
|
else:
|
|
out+="<p><br></p>"
|
|
out+="</body>"
|
|
return out
|