linting things
This commit is contained in:
181
app.py
181
app.py
@ -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}")
|
||||||
|
|
||||||
|
@ -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);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
``` -->
|
||||||
|
@ -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 -%}
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user