diff --git a/randogoth.com/content/20261025_orvanitag-v2.md b/randogoth.com/content/20261025_orvanitag-v2.md new file mode 100644 index 0000000..ad00b37 --- /dev/null +++ b/randogoth.com/content/20261025_orvanitag-v2.md @@ -0,0 +1,34 @@ +Title: otag 2: Plain-Text Tags for Your Files +Date: 2026-10-25 14:00 +Category: MINIMAL +Slug: orvanitag-v2 +Summary: A todo.txt style file tagger written in one week of June 2023 and then left alone, now back as version 2 with its YAML replaced by plain-text .otag files and nine plugins that write tags into the files themselves. +Tags: python, orvanitag, todo.txt + +In June 2023 I spent one week writing a file tagger and then didn't touch it again for over three years. It is called *Orvani Tagger*, after עוֹרְבָנִי, the Hebrew name for the Eurasian jay, and the idea was simple: tag files the way *todo.txt* tags tasks. A `+project`, an `@context`, some `#tags` and a free note, typed on one line, searchable from the shell. + +The 2023 version kept those tags in a `.context.yaml` in every folder, with a `.index.yaml` cache next to it and a configurable schema on top. + +## One Line per File + +Version 2 throws the YAML out. Each folder now has a plain `.otag` file, and every line in it is written in exactly the syntax you type on the command line: + +``` +Boombap Loop.wav --- +album @drums #boombap #lofi +song.mp3 --- +album @drums #lofi #snare first take +stems/ --- @archive +``` + +You can open it in any editor, grep it, diff it, and it travels with the folder when you copy, sync or zip it. A line without the ` --- ` separator stops `otag` with an error naming the file and the line, so a typo of mine can't quietly eat the rest of the folder. The configurable schema is gone too. + +## Tags That Live in the File + +The part that grew most is the plugins, from five to nine. `scan` reads tags that are already embedded in files and `write` puts them back, each in the place its format already has for it: the comment tag of an *MP3* or *FLAC*, the keywords field of a PDF, the description of an *ODT* or *DOCX*, a COM segment in a JPEG, an iTXt chunk in a PNG, the archive comment of a ZIP, a pax header in a tar, a `` in an EPUB, an `otag:` comment line at the top of a Python or Rust file. *TagSpaces* sidecars are read and written as well, so the two tools can share a folder. In every case the file's own data stays untouched, and another tool's comment (like the commit id `git archive` stores in a ZIP) is never overwritten. + +The rest is housekeeping I had been putting off since 2023: `setup.py` and `requirements.txt` replaced by a `pyproject.toml` and `uv`, a committed `build/` directory deleted, the CLI rebuilt on argparse with one handler per command, a real test suite, and the licence moved from MIT to Apache-2.0. There is also a `SKILL.md`, so a coding agent can tag and search files with it without me explaining the syntax every time. + +It's not on PyPI yet. For now it lives in the repository below. + +## Repository + +[orvanitag](https://code.randogoth.com/randogoth/orvanitag)