Skip to content

Instantly share code, notes, and snippets.

@bbelderbos
Last active August 20, 2022 07:30
Show Gist options
  • Save bbelderbos/0bce5326a2ffa82baee56a147d13ee51 to your computer and use it in GitHub Desktop.
Save bbelderbos/0bce5326a2ffa82baee56a147d13ee51 to your computer and use it in GitHub Desktop.
"""Script to create an index file from my Zettelkasten notes (md files)"""
from collections import defaultdict
import os
from pathlib import Path
import re
from typing import NamedTuple
INDEX_NAME = "index.md"
NOTE_FILENAME_REGEX = re.compile(r"^\d.*\.md")
TAG_REGEX = re.compile(r"#\S+")
HEADER = """# Bob's Zettelkasten index
Idea from [this post](https://www.edwinwenink.xyz/posts/42-vim_notetaking/).
This file gets generated by [this script](index.py).
"""
class Note(NamedTuple):
title: str
filename: str
def group_notes_by_tag(
directory: Path = Path.cwd()
) -> defaultdict[str, list[Note]]:
notes_grouped_by_tags = defaultdict(list)
filenames = os.listdir(directory)
for filename in filenames:
if not NOTE_FILENAME_REGEX.match(filename):
continue
note_content = Path(filename).read_text()
title = note_content.splitlines()[0].strip("# ")
tag_lines = "\n".join(
line for line in note_content.splitlines()
if line.startswith("#")
)
tags = re.findall(TAG_REGEX, tag_lines)
for tag in tags:
tag = tag.lstrip("#").title()
notes_grouped_by_tags[tag].append(
Note(title=title, filename=filename)
)
return notes_grouped_by_tags
def create_index(tag_index_tree: defaultdict[str, list[Note]]) -> None:
output = [HEADER]
for tag, notes in sorted(tag_index_tree.items()):
tag = tag.lower().capitalize()
output.append(f"## {tag}\n\n")
for note in notes:
title = note.title.capitalize()
output.append(f"- [{title}]({note.filename})\n")
output.append("\n\n")
with open(INDEX_NAME, "w") as f:
f.write("".join(output))
if __name__ == "__main__":
tag_index_tree = group_notes_by_tag()
create_index(tag_index_tree)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment