From c813ede85100c9ff8a4a6ef47fad4f970116985e Mon Sep 17 00:00:00 2001 From: Holger Frey Date: Mon, 29 Jun 2026 12:57:00 +0200 Subject: [PATCH] added function to create travel checklist pdfs --- pyproject.toml | 2 +- work_helpers/mkd2pdf.py | 89 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 work_helpers/mkd2pdf.py diff --git a/pyproject.toml b/pyproject.toml index c3b9ac7..a68a549 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ travel_final_payment = "work_helpers.travels:final_payment" xls2changelog = "work_helpers.excel2changelog:cli" xls2markdown = "work_helpers.excel2markdown:cli" xls2pylist = "work_helpers.excel2pylist:cli" - +mkd_to_pdf = "work_helpers.mkd2pdf:convert" [tool.ruff] diff --git a/work_helpers/mkd2pdf.py b/work_helpers/mkd2pdf.py new file mode 100644 index 0000000..ef6cc18 --- /dev/null +++ b/work_helpers/mkd2pdf.py @@ -0,0 +1,89 @@ +import click +import pathlib +import tempfile +import subprocess + +OSIDIAN_SEPARATOR ="---\n" + + +def get_destination() -> pathlib.Path(): + scratch = pathlib.Path("/", "mnt", "c", "Users", "Holgi", "Desktop", "Scratch") + if scratch.is_dir(): + return scratch + return pathlib.Path(".") + +def split_header(text:str) -> (str, str): + (left, sep, right) = text.strip().partition(OSIDIAN_SEPARATOR) + if sep != OSIDIAN_SEPARATOR: + return ("", left) + (left, sep, right) = right.strip().partition(OSIDIAN_SEPARATOR) + if sep != OSIDIAN_SEPARATOR: + return ("", left) + return (left.strip(), right.strip()) + + +def _parse_date(iso_date): + try: + (year, month, day) = iso_date.split("-") + return f"{day}.{month}.{year}" + except ValueError: + return iso_date + +def _parse_traveller(name): + translation_table = str.maketrans("", "", "[@/]") + return name.translate(translation_table) + +def parse_header(text:str) -> dict[str, str]: + FIELD_PARSERS = { + "traveller": _parse_traveller, + "end": _parse_date, + "start": _parse_date, + } + result = {} + for line in text.strip().splitlines(): + key, sep, value = line.strip().partition(":") + if sep: + parser_func = FIELD_PARSERS.get(key.lower(), lambda x: x) + result[key.lower()] = parser_func(value.strip()) + return {k: v.replace('"', "").strip() for k, v in result.items()} + +def fill_fields(body, fields): + for key, value in fields.items(): + search = f"`= this.{key}`" + body = body.replace(search, value) + return body + + +def convert_file(markdown) -> str: + path = pathlib.Path(markdown) + content = path.read_text() + header, body = split_header(content) + + fields = parse_header(header) + text = fill_fields(body, fields) + with tempfile.TemporaryDirectory() as tmp_name: + tempdir = pathlib.Path(tmp_name) + markdown = pathlib.Path(tempdir) / "obsidian.md" + markdown.write_text(text) + + typist = pathlib.Path(tempdir) / "obsidian.typ" + cmd = ["pandoc", f"{markdown}", "--to", "typst", "-o", f"{typist}"] + subprocess.run(cmd) + + output = get_destination() / f"Checkliste {path.stem}.pdf" + cmd = ["typst", "compile", f"{typist}", f"{output}"] + subprocess.run(cmd) + + moved = get_destination() / f"Checkliste {path.name}" + subprocess.run(["mv", f"{path}", moved]) + return f"{output}" + + +@click.command() +@click.argument( + "markdowns", nargs=-1, type=click.Path(exists=True, file_okay=True, dir_okay=False) +) +def convert(markdowns): + for name in markdowns: + path = convert_file(name) + print(path) \ No newline at end of file