aboutsummaryrefslogtreecommitdiff
path: root/.ai/scripts/drill-to-anki.py
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-30 13:07:16 -0500
committerCraig Jennings <c@cjennings.net>2026-05-30 13:07:16 -0500
commit038d59b7e548d2323f43dcd92ba14cba876d840d (patch)
tree34f468689b3e4549918f1307d83ad8fda4eea7fa /.ai/scripts/drill-to-anki.py
parent23d87c187c950b047fd44ecb9c3d825b37712fc0 (diff)
downloadrulesets-038d59b7e548d2323f43dcd92ba14cba876d840d.tar.gz
rulesets-038d59b7e548d2323f43dcd92ba14cba876d840d.zip
feat(drill-to-anki): default to phone sync dir and basename deck name
Two default-behavior tweaks from real use. Output now defaults to ~/sync/phone/anki/ instead of ~/sync/org/drill/. The .apkg is a mobile-Anki artifact the phone picks up from its sync dir, while the org source stays in the project. Deck name now defaults to the raw input basename, case preserved. That drops the #+TITLE preference, which leaked tool-name jargon like "DeepSat org-drill flashcards" into the Anki deck list. The --deck and --output flags still override both. I dropped the now-unused title_from_org helper and added a test covering the two defaults. genanki is stubbed in the test since uv resolves it only at runtime.
Diffstat (limited to '.ai/scripts/drill-to-anki.py')
-rwxr-xr-x.ai/scripts/drill-to-anki.py38
1 files changed, 13 insertions, 25 deletions
diff --git a/.ai/scripts/drill-to-anki.py b/.ai/scripts/drill-to-anki.py
index 543ccd8..1050021 100755
--- a/.ai/scripts/drill-to-anki.py
+++ b/.ai/scripts/drill-to-anki.py
@@ -13,15 +13,13 @@ Parses org-drill structure:
text (sans :drill: tag). Back = entry body with newlines converted
to <br>.
-Deck name defaults to the org file's #+TITLE if present, otherwise the
-input basename. Deck and model IDs are derived from the deck name via
-stable hash so re-importing the same deck updates existing cards
-instead of duplicating them.
+Deck name defaults to the input basename, case preserved. Deck and model
+IDs are derived from the deck name via stable hash so re-importing the
+same deck updates existing cards instead of duplicating them.
-Output defaults to ~/sync/org/drill/<input-basename>.apkg (matches
-Craig's project convention where org source lives in the project and
-symlinks into ~/sync/org/drill/, with the .apkg writing directly into
-~/sync/org/drill/ as a build artifact).
+Output defaults to ~/sync/phone/anki/<input-basename>.apkg. The .apkg is
+a mobile-Anki artifact the phone picks up from its sync dir, so it lands
+there rather than next to the org source.
Usage:
drill-to-anki.py <input.org>
@@ -91,15 +89,6 @@ def escape_html(s: str) -> str:
)
-def title_from_org(org_text: str) -> str | None:
- """Return the #+TITLE: value if the org file declares one."""
- for line in org_text.splitlines()[:20]:
- m = re.match(r"^#\+TITLE:\s*(.+?)\s*$", line, re.IGNORECASE)
- if m:
- return m.group(1).strip()
- return None
-
-
def strip_org_metadata(body_lines: list[str]) -> list[str]:
"""Drop :PROPERTIES: drawers and SCHEDULED/DEADLINE/CLOSED planning lines.
@@ -185,13 +174,13 @@ def build(cards: list[tuple[str, str, str]], deck_name: str) -> genanki.Deck:
return deck
-def default_deck_name(input_path: Path, org_text: str) -> str:
- return title_from_org(org_text) or input_path.stem.replace("-", " ").title()
+def default_deck_name(input_path: Path) -> str:
+ return input_path.stem
def default_output_path(input_path: Path) -> Path:
- drill_dir = Path.home() / "sync" / "org" / "drill"
- return drill_dir / f"{input_path.stem}.apkg"
+ anki_dir = Path.home() / "sync" / "phone" / "anki"
+ return anki_dir / f"{input_path.stem}.apkg"
def main() -> int:
@@ -205,14 +194,13 @@ def main() -> int:
)
parser.add_argument(
"--deck",
- help="Deck name. Defaults to the org file's #+TITLE, or the "
- "input basename if no title is set.",
+ help="Deck name. Defaults to the input basename.",
)
parser.add_argument(
"--output",
type=Path,
help="Output .apkg path. Defaults to "
- "~/sync/org/drill/<input-basename>.apkg.",
+ "~/sync/phone/anki/<input-basename>.apkg.",
)
args = parser.parse_args()
@@ -222,7 +210,7 @@ def main() -> int:
return 1
org_text = input_path.read_text(encoding="utf-8")
- deck_name = args.deck or default_deck_name(input_path, org_text)
+ deck_name = args.deck or default_deck_name(input_path)
output_path: Path = (args.output or default_output_path(input_path)).expanduser().resolve()
output_path.parent.mkdir(parents=True, exist_ok=True)