239 lines
6.8 KiB
Python
Executable File
239 lines
6.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
import yaml
|
|
from jinja2 import Template, FileSystemLoader, Environment
|
|
import jinja2
|
|
import os
|
|
import shutil
|
|
import xml
|
|
import xml.etree.ElementTree as ET
|
|
import html
|
|
import datetime
|
|
import numpy as np
|
|
from pathlib import Path
|
|
|
|
DOMAIN = "https://www.weissmann.pm"
|
|
|
|
|
|
def Se(parent, tag, **kwargs):
|
|
# mod = {k.replace("_", "-"): v for k, v in kwargs.items() if v is not None}
|
|
|
|
mod = {}
|
|
for k, v in kwargs.items():
|
|
if v is not None:
|
|
if isinstance(v, (int, float)):
|
|
v = str(v)
|
|
mod[k.replace("_", "-")] = v
|
|
|
|
return ET.SubElement(parent, tag, **mod)
|
|
|
|
|
|
def add_site(urlset, url, lastmod):
|
|
el = ET.SubElement(urlset, "url")
|
|
ET.SubElement(el, "loc").text = html.escape(DOMAIN + url)
|
|
ET.SubElement(el, "lastmod").text = datetime.datetime.utcfromtimestamp(
|
|
lastmod
|
|
).strftime("%Y-%m-%d")
|
|
|
|
|
|
def remove_prefix(str, prefix):
|
|
assert str.startswith(prefix)
|
|
return str[len(prefix) :]
|
|
|
|
|
|
def remove_suffix(str, prefix):
|
|
assert str.endswith(prefix)
|
|
return str[: len(str) - len(prefix)]
|
|
|
|
|
|
def read_conf_md(name):
|
|
url = "/" + name + "/"
|
|
|
|
content = (Path("content") / (name + ".md")).read_text()
|
|
secs = content.split("---")
|
|
yaml_conf = secs[1]
|
|
conf = yaml.safe_load(yaml_conf)
|
|
return {
|
|
"url": url,
|
|
"abstract": conf["abstract"],
|
|
"title": conf["title"],
|
|
}
|
|
|
|
|
|
def read_conf_mds(names):
|
|
return [read_conf_md(name) for name in names]
|
|
|
|
|
|
def gen_index():
|
|
programming_articles = ["julialang", "bugfix-newsflash-color", "test-surface-code-quality", "fail-early", "http-301-is-not-404"]
|
|
german_politics_articles = ["framing-manual"]
|
|
|
|
programming_articles = read_conf_mds(programming_articles)
|
|
german_politics_articles = read_conf_mds(german_politics_articles)
|
|
|
|
templateLoader = FileSystemLoader(searchpath="./")
|
|
templateEnv = Environment(loader=templateLoader, undefined=jinja2.StrictUndefined)
|
|
template = templateEnv.get_template("index.html")
|
|
|
|
out = template.render(
|
|
programming_articles=programming_articles,
|
|
german_politics_articles=german_politics_articles,
|
|
)
|
|
with open("build/index.html", "w") as outfile:
|
|
outfile.write(out)
|
|
|
|
|
|
def gen_sitemap():
|
|
# todo_: build sitemap from build directory
|
|
urlset = ET.Element(
|
|
"urlset",
|
|
**{
|
|
"xmlns": "http://www.sitemaps.org/schemas/sitemap/0.9",
|
|
"xmlns:xhtml": "http://www.w3.org/1999/xhtml",
|
|
},
|
|
)
|
|
add_site(urlset, "/", os.path.getmtime("index.html"))
|
|
for root, subdirs, files in os.walk("content"):
|
|
for file in files:
|
|
if not file.endswith(".md"):
|
|
continue
|
|
url = (
|
|
remove_suffix(remove_prefix(root, "content") + "/" + file, ".md") + "/"
|
|
)
|
|
add_site(urlset, url, os.path.getmtime(root + "/" + file))
|
|
with open("build/sitemap.xml", "wb") as outfile:
|
|
outfile.write(ET.tostring(urlset, encoding="utf8"))
|
|
|
|
|
|
def polyline(svg, posar):
|
|
pointstr = " ".join(map(lambda el: str(el[0]) + "," + str(el[1]), posar))
|
|
|
|
Se(
|
|
svg,
|
|
"polyline",
|
|
points=pointstr,
|
|
fill="none",
|
|
stroke="currentColor",
|
|
)
|
|
|
|
|
|
def arrow(svg, pos1, pos2):
|
|
pos1 = np.array(pos1)
|
|
pos2 = np.array(pos2)
|
|
|
|
direction = (pos2 - pos1) / np.linalg.norm(pos2 - pos1)
|
|
perp = np.array([direction[1], -direction[0]])
|
|
|
|
end1 = pos1 + direction * 5
|
|
end2 = pos2 - direction * 5
|
|
|
|
x1, y1 = end1
|
|
x2, y2 = end2
|
|
|
|
polyline(svg, [end1, end2])
|
|
polyline(
|
|
svg,
|
|
[end2 - direction * 10 + perp * 5, end2, end2 - direction * 10 - perp * 5],
|
|
)
|
|
|
|
|
|
def gen_svg1():
|
|
stepdist = 80
|
|
boxwidth = 100
|
|
boxheight = 20
|
|
middle = 125
|
|
fontsize = 14
|
|
abortstep = 4
|
|
yoffset = boxheight / 2 + 1
|
|
|
|
for imgnum in range(1, 3):
|
|
svg = ET.Element(
|
|
"svg",
|
|
version="1.1",
|
|
width="400",
|
|
height=str(yoffset + stepdist * 5 + boxheight / 2 + 1),
|
|
xmlns="http://www.w3.org/2000/svg",
|
|
**{"xmlns:xlink": "http://www.w3.org/1999/xlink"},
|
|
)
|
|
Se(
|
|
svg, "style"
|
|
).text = "@media(prefers-color-scheme:light){svg{fill:#000000;color:#000000;background-color:#FFFFFF;}}@media(prefers-color-scheme:dark){svg{fill:#FFFFFF;color:#FFFFFF;background-color:#000000;}}"
|
|
|
|
for i in range(6):
|
|
if imgnum > 1 and i == 1:
|
|
partcolor = "red"
|
|
else:
|
|
partcolor = None
|
|
if imgnum > 1 and i > 1:
|
|
cmdcolor = "red"
|
|
else:
|
|
cmdcolor = None
|
|
if i != 0 and (i <= abortstep or imgnum == 1):
|
|
arrow(
|
|
svg,
|
|
(middle, yoffset + stepdist * (i - 1) + boxheight / 2),
|
|
(middle, yoffset + stepdist * i - boxheight / 2),
|
|
)
|
|
Se(
|
|
svg,
|
|
"text",
|
|
x=middle + 5,
|
|
y=yoffset + stepdist * (i - 1 / 2) + fontsize / 3,
|
|
fill=cmdcolor,
|
|
font_size=fontsize,
|
|
text_anchor="left",
|
|
).text = "Command " + str(i)
|
|
Se(
|
|
svg,
|
|
"text",
|
|
x=middle,
|
|
y=yoffset + stepdist * i + fontsize / 3,
|
|
fill=partcolor,
|
|
font_size=fontsize,
|
|
text_anchor="middle",
|
|
).text = "Part " + str(i)
|
|
Se(
|
|
svg,
|
|
"rect",
|
|
x=middle - boxwidth / 2,
|
|
y=yoffset + stepdist * i - boxheight / 2,
|
|
width=boxwidth,
|
|
height=boxheight,
|
|
fill="none",
|
|
stroke="currentColor",
|
|
)
|
|
if imgnum == 2:
|
|
abortdist = 60
|
|
arrow(
|
|
svg,
|
|
(middle + boxwidth / 2, yoffset + stepdist * abortstep),
|
|
(middle + boxwidth / 2 + abortdist, yoffset + stepdist * abortstep),
|
|
)
|
|
Se(
|
|
svg,
|
|
"rect",
|
|
x=middle + boxwidth / 2 + abortdist,
|
|
y=yoffset + stepdist * abortstep - boxheight / 2,
|
|
width=boxwidth,
|
|
height=boxheight,
|
|
fill="none",
|
|
stroke="currentColor",
|
|
)
|
|
Se(
|
|
svg,
|
|
"text",
|
|
x=middle + boxwidth + abortdist,
|
|
y=yoffset + stepdist * abortstep + fontsize / 3,
|
|
font_size=fontsize,
|
|
text_anchor="middle",
|
|
).text = "abort"
|
|
|
|
with open(
|
|
"build/fail-early/code-chain-" + str(imgnum) + ".svg", "wb"
|
|
) as outfile:
|
|
outfile.write(ET.tostring(svg, encoding="utf8"))
|
|
|
|
|
|
gen_index()
|
|
gen_sitemap()
|
|
gen_svg1()
|