Skip to content

Markdown migration: .md files, standard task-list syntax#10

Merged
TroyHernandez merged 5 commits into
mainfrom
markdown-migration
Apr 27, 2026
Merged

Markdown migration: .md files, standard task-list syntax#10
TroyHernandez merged 5 commits into
mainfrom
markdown-migration

Conversation

@TroyHernandez
Copy link
Copy Markdown
Contributor

Summary

hacer files are now standard markdown:

  • Extension: .txt.md
  • Syntax: [X] - text- [X] text (standard markdown task list)
  • Status set: - [ ], - [/], - [x], - [!] (Obsidian renders all four; GitHub renders the standard two)
  • Recurring * marker: dropped from the writer entirely. recurring.txt is the source of truth.
  • Section headers in Daily: # Monday## Monday (proper hierarchy under H1)
  • The #####... separator line: removed
  • First line stays H1 (# todo_yymmdd_daily.md)

Backwards-compat reads: the dual-format parser still understands pre-0.2.0 files ([X] - text in .txt), so existing repos keep working until you run the migration.

migrate_to_markdown() does the one-shot conversion of cfg$live_dir. Per Troy: archive is left alone ("I'm not too concerned with old todo lists right now. when I become concerned enough to investigate, we dial in the defaults."). The function surfaces a warning listing any tasks that carried the legacy * marker so you can copy those paths into recurring.txt.

Phases

  1. Dual-format parser.parse_task_line() helper recognizes both formats; parse_todo, roll_day, next_day, tasks() all use it. Section headers extend to ^#+\s+.
  2. Markdown writer.df_to_lines() emits - [X] name. build_todo_txt_lines emits ## Section H2 headers and drops the #####... separator.
  3. .md extension default + test sweep.build_names_for emits .md. .resolve_period_paths prefers .md, falls back to lowercase then capitalized .txt. Listings accept (md|txt). render_markdown cfg flag, build_markdown_lines, write_markdown all removed (canonical IS markdown now). All test fixtures and assertions updated.
  4. migrate_to_markdown() — new exported function. Walks live_dir only, reads via dual-format parser, writes .md with new syntax, removes .txt source, surfaces * recurring tasks as a warning.
  5. Test sweep — bundled into Phase 3.
  6. Docs — README rewritten with new format examples and a "Migrating from pre-0.2.0" section. CLAUDE.md updates the modules list and Task File Format section.

Test plan

  • 26 new tests in test_migrate.R: format conversion, * warning surface, empty-repo no-op, preview leaves disk untouched, all four cadences migrate together
  • All existing tests updated for the new format and .md filenames; test_lowercase_compat verifies legacy capitalized .txt reads still work
  • All 192 tests pass
  • Smoke test on a hypothetical legacy repo: migrate_to_markdown() correctly rewrites and warns about *Email/*Exercise
  • Version bumped to 0.2.0 — first format change, semver-warrants minor bump

Add internal .parse_task_line() helper that recognizes both
markdown task-list format ("- [X] text") and the legacy
"[X] - text" format. parse_todo, roll_day, next_day, and
tasks() all dispatch through it now, and the section-header
regex extends to "^#+\\s+" so "## Monday" headers parse the
same as "# Monday".

The `*` recurring marker is still parsed (for backwards-compat
reads of legacy hand-edited files) even though Phase 2's writer
will stop emitting it.

No write-side changes yet. All 165 existing tests pass against
both formats.
.df_to_lines now emits standard markdown task list syntax
("- [X] name") and drops the `*` recurring marker entirely;
recurring.txt is the source of truth for recurring items.

build_todo_txt_lines uses "## Section" (H2) for day-section
headers in Daily and drops the "######..." separator line. The
first-line "# basename" stays as the H1.

165 tests still pass — Phase 1's dual-format parser reads both
old fixtures and new writer output.
New writes always emit .md:
- .build_names_for emits "todo_yymmdd_<period>.md"
- .resolve_period_paths prefers .md, falls back to legacy
  lowercase .txt then capitalized ToDo_*.txt — old repos still
  work
- tasks() and roll_day() list_files patterns accept (md|txt)
- run_monday's render_markdown branch removed (canonical IS
  markdown now); render_html stays
- build_markdown_lines and write_markdown deleted (redundant
  with the new canonical writer)
- config.R and instantiate.R defaults switch to .md and drop
  render_markdown

Test sweep:
- All output-file expectations updated to .md
- Format-related regexes rewritten to extract status from
  "[X]" inside any task line, format-agnostic
- New helper status_in() in test_blocked, status_of() in
  test_fix_parents
- test_recurring section-header greps updated to "## Foo"
- test_lowercase_compat verifies legacy capitalized .txt
  reads still work and writes still produce .md

166 tests pass.
New exported function that walks cfg$live_dir for legacy .txt
todo files, rewrites each as .md in the markdown task-list
syntax, and removes the .txt source after a successful write.

Surfaces a warning listing any tasks that carried the legacy
`*` recurring marker so the user can copy those paths into
recurring.txt — the new writer drops `*` entirely, so without
the manifest entry they stop recurring.

Archive files are not touched. Per Troy: "I'm not too
concerned with old todo lists right now. when I become
concerned enough to investigate, we dial in the defaults."

Supports preview = TRUE; in preview mode, lists the would-be
created .md files plus a separate "would also remove" line for
each .txt source. The preview struct stays unchanged
(file_removed isn't a hacer_preview field).

26 new tests in test_migrate.R: format conversion, * warning
surface, empty-repo no-op, preview leaves disk untouched, all
four cadences migrate together.

Bump version to 0.2.0 — file format change.
README rewritten for the markdown task-list format:

- Folder layout uses .md filenames
- Editing rules show standard markdown task list with the [/]
  and [!] custom states called out as non-standard
- "Migrating from pre-0.2.0" section explains
  migrate_to_markdown() with preview-then-commit flow
- Examples updated throughout (.txt -> .md, [X] - text -> - [X] text)
- recurring.txt section reframes the workflow ("recurring lives
  in the manifest, not as inline `*` markers")
- Coverage of preview mode adds migrate_to_markdown to the list
- .gitignore tip drops `*.md` since .md is now canonical
- Troubleshooting adds a mixed-extension hint

CLAUDE.md updates:
- Modules list adds R/recurring.R and R/migrate.R, calls out
  the dual-format .parse_task_line() helper in R/parse.R
- Preview mode list adds migrate_to_markdown
- Task File Format section rewritten as markdown, notes the
  parser still reads pre-0.2.0 files
@TroyHernandez TroyHernandez merged commit 57b6e48 into main Apr 27, 2026
0 of 4 checks passed
@TroyHernandez TroyHernandez deleted the markdown-migration branch April 27, 2026 23:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant