linting things

This commit is contained in:
vitrinekast
2025-04-13 10:24:24 +02:00
parent 9b8474efb9
commit 2bd968cfba
5 changed files with 116 additions and 135 deletions

181
app.py
View File

@ -1,23 +1,19 @@
import subprocess
import os
from pathlib import Path
import shutil
import csv import csv
import os
import re import re
from datetime import datetime import shutil
import subprocess
from jinja2 import Environment, PackageLoader, select_autoescape
import frontmatter
from slugify import slugify
import pypandoc
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from datetime import datetime
from pathlib import Path
import frontmatter
import pypandoc
from jinja2 import Environment, PackageLoader, select_autoescape
from slugify import slugify
# TODO make newsletter URL's absolute to klank.school # TODO make newsletter URL's absolute to klank.school
env = Environment( env = Environment(loader=PackageLoader("src"), autoescape=select_autoescape())
loader=PackageLoader("src"),
autoescape=select_autoescape()
)
CONTENT_D = os.path.abspath("src/content") CONTENT_D = os.path.abspath("src/content")
OUTPUT_D = "dist" OUTPUT_D = "dist"
@ -27,13 +23,6 @@ documents = {}
now = datetime.now() now = datetime.now()
word_count = 0 word_count = 0
# Utils
def getParam(params, index):
return params[index] if len(params) > index else False
# jinja filter that can list documents # jinja filter that can list documents
def listDocuments(params): def listDocuments(params):
param = params.split(" ") param = params.split(" ")
@ -42,57 +31,47 @@ def listDocuments(params):
return html return html
# jinja filter to make a slug out of a stirng
def slugify_filter(value):
return slugify(value)
# Source: https://github.com/gandreadis/markdown-word-count # Source: https://github.com/gandreadis/markdown-word-count
def count_words_in_markdown(text): def count_words_in_markdown(text):
# Comments # Comments
text = re.sub(r'<!--(.*?)-->', '', text, flags=re.MULTILINE) text = re.sub(r"<!--(.*?)-->", "", text, flags=re.MULTILINE)
# Tabs to spaces # Tabs to spaces
text = text.replace('\t', ' ') text = text.replace("\t", " ")
# More than 1 space to 4 spaces # More than 1 space to 4 spaces
text = re.sub(r'[ ]{2,}', ' ', text) text = re.sub(r"[ ]{2,}", " ", text)
# Footnotes # Footnotes
text = re.sub(r'^\[[^]]*\][^(].*', '', text, flags=re.MULTILINE) text = re.sub(r"^\[[^]]*\][^(].*", "", text, flags=re.MULTILINE)
# Indented blocks of code # Indented blocks of code
text = re.sub(r'^( {4,}[^-*]).*', '', text, flags=re.MULTILINE) text = re.sub(r"^( {4,}[^-*]).*", "", text, flags=re.MULTILINE)
# Replace newlines with spaces for uniform handling # Replace newlines with spaces for uniform handling
text = text.replace('\n', ' ') text = text.replace("\n", " ")
# Custom header IDs # Custom header IDs
text = re.sub(r'{#.*}', '', text) text = re.sub(r"{#.*}", "", text)
# Remove images # Remove images
text = re.sub(r'!\[[^\]]*\]\([^)]*\)', '', text) text = re.sub(r"!\[[^\]]*\]\([^)]*\)", "", text)
# Remove HTML tags # Remove HTML tags
text = re.sub(r'</?[^>]*>', '', text) text = re.sub(r"</?[^>]*>", "", text)
# Remove special characters # Remove special characters
text = re.sub(r'[#*`~\-^=<>+|/:]', '', text) text = re.sub(r"[#*`~\-^=<>+|/:]", "", text)
# Remove footnote references # Remove footnote references
text = re.sub(r'\[[0-9]*\]', '', text) text = re.sub(r"\[[0-9]*\]", "", text)
# Remove enumerations # Remove enumerations
text = re.sub(r'[0-9#]*\.', '', text) text = re.sub(r"[0-9#]*\.", "", text)
return len(text.split()) return len(text.split())
# jinja filter for date formatting # jinja filter for date formatting
def prettydate(value, format="%d/%m/%Y"):
def prettydate(value, format='%d/%m/%Y'):
return datetime.fromtimestamp(int(value)).strftime(format) return datetime.fromtimestamp(int(value)).strftime(format)
# jinja filter to replace shortcodes in HTML # jinja filter to replace shortcodes in HTML
def shortcode_filter(value): def shortcode_filter(value):
shortcode_callbacks = { shortcode_callbacks = {"show": listDocuments}
"show": listDocuments
}
def shortcode_replacer(match): def shortcode_replacer(match):
@ -109,15 +88,15 @@ def shortcode_filter(value):
env.filters["shortcode"] = shortcode_filter env.filters["shortcode"] = shortcode_filter
env.filters["slugify"] = slugify_filter env.filters["slugify"] = slugify
env.filters["prettydate"] = prettydate env.filters["prettydate"] = prettydate
# translate a single file into HTML # translate a single file into HTML
def render_single_file(path, dist, name=False):
def render_single_file(page, path, dist, name=False):
name = Path(path).stem name = Path(path).stem
template = env.select_template([f"{name}.jinja", "post.jinja"]) template = env.select_template([f"{name}.jinja", "post.jinja"])
page = get_page_data(path)
html = template.render(documents=documents, page=page, name=name) html = template.render(documents=documents, page=page, name=name)
if not os.path.exists(dist): if not os.path.exists(dist):
@ -141,34 +120,20 @@ def get_existing_page(path, slug):
if folder == "content": if folder == "content":
return False return False
for doc in documents[folder]: return [item for item in documents[folder] if item.get("slug") == slug]
if doc:
if doc["slug"] == slug:
return doc
return False return False
# build a slug including the folder
def get_slug(path, folder, filename):
if folder == "content":
return slugify(filename)
else:
return slugify(f"{folder}/{filename}")
# compile markdown into cited HTML # compile markdown into cited HTML
def get_page_data(path): def get_page_data(path):
global word_count global word_count
filename = Path(path).stem filename = Path(path).stem
folder = Path(path).parent.name folder = Path(path).parent.name
slug = get_slug(path, folder, filename) slug = slugify(filename) if folder == "content" else slugify(f"{folder}/{filename}")
prerendered = get_existing_page(path, slug)
if prerendered: if prerendered := get_existing_page(path, slug):
return prerendered return prerendered
page = frontmatter.load(path) page = frontmatter.load(path)
@ -177,19 +142,18 @@ def get_page_data(path):
page["folder"] = folder page["folder"] = folder
if "start_datetime" in page: if "start_datetime" in page:
page["has_passed"] = datetime.fromtimestamp( page["has_passed"] = datetime.fromtimestamp(page["start_datetime"]) < now
page["start_datetime"]) < now
content = page.content content = page.content
if "`include" in page.content: if ".include" in page.content:
print("doing an include!")
content = pypandoc.convert_text( content = pypandoc.convert_text(
page.content, page.content,
to='md', to="md",
format='md', format="md",
extra_args=[ extra_args=["--lua-filter=include-files.lua"],
"--lua-filter=include-files.lua" )
])
page.body = pypandoc.convert_text( page.body = pypandoc.convert_text(
content, content,
@ -199,13 +163,13 @@ def get_page_data(path):
"--citeproc", "--citeproc",
"--bibliography=library.bib", "--bibliography=library.bib",
"--csl=harvard-cite-them-right.csl", "--csl=harvard-cite-them-right.csl",
]) ],
)
return page return page
# Do stuff to the circuit's pcb # Do stuff to the circuit's pcb
def save_circuit_svg(filepath, outpath, name): def save_circuit_svg(filepath, outpath, name):
tree = ET.parse(filepath) tree = ET.parse(filepath)
@ -232,8 +196,7 @@ def render_posts(path, output_path=OUTPUT_D):
file_path = Path(path) / filename file_path = Path(path) / filename
if file_path.suffix == ".md": if file_path.suffix == ".md":
render_single_file(get_page_data(file_path), render_single_file(file_path, f"{output_path}/{name}")
file_path, f"{output_path}/{name}")
elif file_path.is_dir(): elif file_path.is_dir():
render_posts(file_path, f"{output_path}/{name}") render_posts(file_path, f"{output_path}/{name}")
elif file_path.suffix == ".svg": elif file_path.suffix == ".svg":
@ -242,16 +205,18 @@ def render_posts(path, output_path=OUTPUT_D):
os.makedirs(f"{output_path}/{name}", exist_ok=True) os.makedirs(f"{output_path}/{name}", exist_ok=True)
shutil.copyfile(file_path, f"{output_path}/{name}/{filename}") shutil.copyfile(file_path, f"{output_path}/{name}/{filename}")
# Pre-load before compiling # Pre-load before compiling
def preload_documents(): def preload_documents():
global documents global documents
version = subprocess.check_output( version = (
["git", "rev-list", "--count", "HEAD"]).decode("utf-8").strip() subprocess.check_output(["git", "rev-list", "--count", "HEAD"])
.decode("utf-8")
.strip()
)
documents["meta"] = {"now": now.strftime("%d %B %Y"), "version": version} documents["meta"] = {"now": now.strftime("%d %B %Y - %H:%M:%S"), "version": version}
for subdir in os.listdir(CONTENT_D): for subdir in os.listdir(CONTENT_D):
path = os.path.join(CONTENT_D, subdir) path = os.path.join(CONTENT_D, subdir)
@ -265,20 +230,14 @@ def preload_documents():
if filename.endswith(".md"): if filename.endswith(".md"):
documents[name].append(get_page_data(cpath)) documents[name].append(get_page_data(cpath))
elif os.path.isdir(cpath): elif os.path.isdir(cpath):
documents[name].append(get_page_data( documents[name].append(
os.path.join(cpath, "index.md"))) get_page_data(os.path.join(cpath, "index.md"))
)
elif Path(path).suffix == '.md': elif Path(path).suffix == ".md":
documents[Path(path).stem] = get_page_data(path) documents[Path(path).stem] = get_page_data(path)
def copy_assets():
if os.path.exists(OUT_ASSETS):
shutil.rmtree(OUT_ASSETS)
shutil.copytree(SRC_ASSETS, OUT_ASSETS)
def get_inventory(): def get_inventory():
global documents global documents
@ -291,28 +250,17 @@ def get_inventory():
def get_wordcount(): def get_wordcount():
global word_count global word_count
word_count += count_words_in_markdown(documents['thesis'].body) word_count += count_words_in_markdown(documents["thesis"].body)
for c in documents['chapters']: for section in ["chapters", "components", "recipes"]:
if c['filename'] != 'index': for c in documents[section]:
count = count_words_in_markdown(c.body) if section == "recipes" or c["filename"] != "index":
print(f"{c['filename']}: has {count} words")
word_count += count
for c in documents['components']:
if c['filename'] != 'index':
count = count_words_in_markdown(c.body)
print(f"{c['filename']}: has {count} words")
word_count += count
for c in documents['recipes']:
print(c['filename'])
count = count_words_in_markdown(c.body) count = count_words_in_markdown(c.body)
print(f"{c['filename']}: has {count} words") print(f"{c['filename']}: has {count} words")
word_count += count word_count += count
print(f"word count: { word_count} ") print(f"word count: { word_count} ")
documents['meta']["count"] = word_count documents["meta"]["count"] = word_count
def main(): def main():
@ -327,13 +275,16 @@ def main():
if os.path.isdir(path): if os.path.isdir(path):
print("Compile: an entire directory", Path(path).name) print("Compile: an entire directory", Path(path).name)
render_posts(path) render_posts(path)
elif Path(path).suffix == '.md': elif Path(path).suffix == ".md":
print("Compile: single page", Path(path).name) print("Compile: single page", Path(path).name)
render_single_file(get_page_data(path), path, OUTPUT_D) render_single_file(path, OUTPUT_D)
elif Path(path).suffix in [".csv"]: elif Path(path).suffix in [".csv"]:
print("Compile: not compiling ", Path(path).name) print("Compile: not compiling ", Path(path).name)
copy_assets() if os.path.exists(OUT_ASSETS):
shutil.rmtree(OUT_ASSETS)
shutil.copytree(SRC_ASSETS, OUT_ASSETS)
print(f"total words: {word_count}") print(f"total words: {word_count}")

View File

@ -1,12 +1,12 @@
const dialog = document.querySelector("dialog"); const dialog = document.querySelector("dialog");
const closeDialog = (e) => { const closeDialog = (e) => {
e.stopPropagation(); e.stopPropagation();
console.log("close") console.log("close")
dialog.close(); dialog.close();
document.body.removeEventListener("click", closeDialog); document.body.removeEventListener("click", closeDialog);
} }
const showLightbox = (e) => { const showLightbox = (e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -18,7 +18,5 @@ const showLightbox = (e) => {
document.body.addEventListener("click", closeDialog, false); document.body.addEventListener("click", closeDialog, false);
} }
document.querySelectorAll("article img").forEach((img) => { document.querySelectorAll("article img").forEach((img) => {
console.log(img);
img.addEventListener("click", showLightbox); img.addEventListener("click", showLightbox);
}) })

View File

@ -6,3 +6,30 @@ layout: index
description: This is the description of the about us page description: This is the description of the about us page
--- ---
<span template-type="intro"></span> <span template-type="intro"></span>
<!-- ``` {.include}
src/content/chapters/-1-intro.md
src/content/chapters/0-gather.md
src/content/chapters/1-dismantling.md
src/content/chapters/2-component-salvaging.md
src/content/components/1_capacitor.md
src/content/components/chips.md
src/content/components/inputs.md
src/content/components/outputs.md
src/content/components/pcb.md
src/content/components/0_resistor.md
src/content/components/transistor.md
src/content/chapters/3-recipes.md
src/content/recipes/Kick/index.md
src/content/recipes/PCB-keyboard/index.md
src/content/recipes/SingleTransistorOsc/index.md
src/content/recipes/power-supply/index.md
src/content/chapters/4-reflection.md
src/content/chapters/5-bib.md
``` -->

View File

@ -107,7 +107,7 @@
</script> </script>
{% block title %} {% block title %}
{%- if page['title'] -%} {%- if page['title'] -%}
<title>{{ page['title'] }} {{documents['meta']['version']}}</title> <title>{{ page['title'] }} {%- if documents['meta'] -%}{{documents['meta']['version']}}{%- endif -%}</title>
{%- else -%} {%- else -%}
<title>I dont have a title</title> <title>I dont have a title</title>
{%- endif -%} {%- endif -%}

View File

@ -9,14 +9,19 @@
{% block content %} {% block content %}
<section template-type="front" jinja="thesis.jinja"> <section template-type="front" jinja="thesis.jinja">
<section class="meta"> <section class="meta">
{% if documents["meta"] %}
<span data-generated-date>{{documents["meta"]["now"]}}</span> <span data-generated-date>{{documents["meta"]["now"]}}</span>
{% endif %}
<span data-publication-title>{{page['title']}}</span> <span data-publication-title>{{page['title']}}</span>
</section> </section>
<header> <header>
<h2>A field guide to</h2> <h2>A field guide to</h2>
<h1>Salvaging Sound Devices</h1> <h1>Salvaging Sound Devices</h1>
{% if documents["meta"] %}
<p>Version {{documents['meta']['version']}} | {{documents['meta']['count']}} words</p> <p>Version {{documents['meta']['version']}} | {{documents['meta']['count']}} words</p>
<p>{{documents["meta"]["now"]}}</p> <p>{{documents["meta"]["now"]}}</p>
{% endif %}
</header> </header>
</section> </section>