commit ead4b01edccef8d4bb6de9a74da4dbaac7349d64 Author: Tyler Starr Date: Thu Jul 11 22:08:32 2024 -0700 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..74f6ade --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# z.py +> Gotta go fast! -Bowser + +A zippy note taking implementation that fits my needs. Principles are: + + 1. Should be pure python and only rely on standard libraries + 2. Loosly based on the excellent Denote package for Emacs + 3. CLI first with potential to integrate with (n)vim + 4. Primarily for Markdown files, but can name other files + 5. Notes viewable and editable with Obsidian + +Notes: + - Z.py assumes you want to operate in the current folder where the command + is run. Folders are indicated by creating a `.z` file. diff --git a/create.py b/create.py new file mode 100644 index 0000000..c5614fd --- /dev/null +++ b/create.py @@ -0,0 +1,55 @@ +from argparse import ArgumentTypeError +from template import apply_template +from pathlib import Path +from typing import List +import datetime +import re + +# Format: --__<tag1>_<tag2>.<ext> +def normalize_name(name: str, tags: str, time: datetime.date | None = None, ext: str ="md"): + if "-" in name or "_" in name: + raise ArgumentTypeError("Title cannot have '-' or '_'") + if "-" in name or "_" in tags: + raise ArgumentTypeError("Note cannot have '-' or '_'") + + # timestamp + if time: + f = time.strftime("%Y%m%dT%H%M%S") + else: + f = datetime.datetime.now().strftime("%Y%m%dT%H%M%S") + + # title + f += "--" + f += re.sub(r" ", "-", name).strip() + + # tags + f += "__" + for tag in tags.split(","): + tag = tag.strip() + tag = re.sub(r" ", "-", tag) + f += tag + "_" + f = f[:-1] + + # ext + if ext[0] == ".": + f += ext + else: + f += "." + ext + return f + +def create_file(name: str, silo: str, template: str = "default.md"): + if silo: + Path(silo).mkdir(exist_ok=True) + if silo[-1] != '/': + silo += '/' + content = apply_template(Path.home().joinpath('.config/z/templates'), template) + with open(silo + name, 'w') as f: + f.write(content) + return + +def main(args): + file = normalize_name(args.name, args.tags) + create_file(file, args.silo) + +if __name__ == "__main__": + main(None) diff --git a/template.py b/template.py new file mode 100644 index 0000000..d114e84 --- /dev/null +++ b/template.py @@ -0,0 +1,17 @@ +import template_funcs as tf +from pathlib import Path +from typing import List +import re + +def read_file(p: Path, n: str): + f_path = p.joinpath(n) + with open(f_path, "r") as f: + return f.read() + return -1 + +def split_template(s: str) -> (List[str], str): + return re.findall(r"{([^}]+)}", s), re.sub(r"{([^}]+)}", "{}", s) + +def apply_template(path: Path, name: str): + fns, s = split_template(read_file(path, name)) + return s.format(*[eval("tf." + fn)() for fn in fns]) diff --git a/template_funcs.py b/template_funcs.py new file mode 100644 index 0000000..72be20e --- /dev/null +++ b/template_funcs.py @@ -0,0 +1,16 @@ +from datetime import datetime + +def date(): + return datetime.now().strftime("%Y%m%d") + +def time(): + return datetime.now().strftime("%Y%m%dT%H%M%S") + +def title(): + return "TODO" + +def silo(): + return "TODO" + +def tags(): + return "TODO" diff --git a/templates/default.md b/templates/default.md new file mode 100644 index 0000000..02f0453 --- /dev/null +++ b/templates/default.md @@ -0,0 +1,10 @@ +--- +title: {title} +silo: {silo} +tags: {tags} +date: {time} +--- + +# {title} + +- diff --git a/z.py b/z.py new file mode 100644 index 0000000..da9128a --- /dev/null +++ b/z.py @@ -0,0 +1,28 @@ +from pathlib import Path +import argparse +import create +import sys + +folder = "dude2" + +def init_parser(): + parser = argparse.ArgumentParser(prog="z.py", description="top level prog") + sub_parsers = parser.add_subparsers(help="subcommand help") + create_parser = sub_parsers.add_parser("create", help="create note") + create_parser.set_defaults(func=create.main) + create_parser.add_argument("name", help="name of note to create") + create_parser.add_argument("-t", "--tags", nargs="?", default="", const="", help="comma seperated list of tags for note") + create_parser.add_argument("-s", "--silo", nargs="?", default="", const="", help="Optionally create note in silo") + return parser + +def main(): + z_file = Path("./.z") + if not z_file.is_file(): + raise Exception("You aren't in a z.py folder. Re-run in a z.py folder") + + parser = init_parser() + args = parser.parse_args() + args.func(args) + +if __name__ == "__main__": + sys.exit(main())