import datetime import frontmatter import os import re import unicodedata input_dir = "content" def slugify(string): return re.sub( r"\W+", "", unicodedata.normalize("NFKD", string) .encode("ascii", "ignore") .decode("ascii") .lower(), ) def sortable_title(string): return re.sub(r"^the ", "", string, flags=re.IGNORECASE).lower() def parse_entry_data(entry_data): entry_data["date"] = datetime.datetime.fromisoformat(entry_data["date"] + "+00:00") if "description" in entry_data: entry_data["description"] = entry_data["description"].strip() if "links" in entry_data: for link in entry_data["links"]: link["title"] = link["title"].strip() if "description" in link: if link["description"].strip() != "": link["description"] = link["description"].strip() else: del link["description"] clean_link = dict((k, link[k]) for k in link) if "modified" in entry_data: entry_data["modified"] = datetime.datetime.fromisoformat( entry_data["modified"] + "+00:00" ) if "tags" in entry_data: entry_data["tags"] = [tag.strip() for tag in entry_data["tags"].split(",")] if "series" in entry_data: entry_data["series"] = entry_data["series"].strip() entry_data["title"] = entry_data["title"].strip() if os.path.isdir(f"{input_dir}/{entry_data['id']}"): entry_data["dir"] = f"{input_dir}/{entry_data['id']}" def _entries(): entries = {} for filename in os.listdir(input_dir): if filename.endswith(".md") or filename.endswith(".gmi"): entry_data = frontmatter.load(f"{input_dir}/{filename}") entry_data["id"], _ = map(slugify, os.path.splitext(filename)) if "date" in entry_data: parse_entry_data(entry_data) entries[entry_data["id"]] = entry_data entries = { id: entries[id] for id in sorted(entries.keys(), key=lambda entry: (entries[entry]["date"])) } return entries entries = _entries() def _series(): series = [] for entry_data in reversed(entries.values()): if "series" in entry_data and slugify(entry_data["series"]) not in map( slugify, series ): series += [entry_data["series"].strip()] return sorted(series, key=sortable_title) series = _series() def _tags(): tags = [] for entry_data in entries.values(): if "tags" in entry_data: tags += [ tag.strip() for tag in entry_data["tags"] if slugify(tag) not in map(slugify, tags) ] return sorted(tags, key=sortable_title) tags = _tags() years = sorted( set([datetime.datetime(entry["date"].year, 1, 1) for entry in entries.values()]) ) months = sorted( set( [ datetime.datetime(entry["date"].year, entry["date"].month, 1) for entry in entries.values() ] ) ) days = sorted( set( [ datetime.datetime( entry["date"].year, entry["date"].month, entry["date"].day ) for entry in entries.values() ] ) ) updated = sorted( [entry["date"] for entry in entries.values()] + [entry["modified"] for entry in entries.values() if "modified" in entry] )[-1]