subtask_text = """
# Work
- (A) Finish report @office
- Write introduction
- Add charts
- Email client
"""
sections = parse_markdown_todos(subtask_text)
sections[1].todos[1]Todo: (A) Finish report @office
In addition to flat Todo.txt files, TodoFiles.jl can parse markdown files where #-headings define sections and - list items are todo entries:
Each list item is parsed using the same Todo.txt rules as parse_todo.
Indented - items under a top-level todo are parsed as subtasks:
Todo: (A) Finish report @office
When iterating a MarkdownTodoFile, subtasks are flattened alongside their parents:
4
4-element Vector{Todo}:
Todo: (A) Finish report @office
Todo: Write introduction
Todo: Add charts
Todo: Email client
When writing back to markdown, subtasks are indented with 4 spaces:
Tasks can have associated notes, written as blockquote lines (> ...) beneath the task. Notes are stored in the notes field as a single string (lines joined by \n):
notes_text = """
# Work
- (A) Finish report @office +ClientProject due:2024-02-01
> Need to include Q4 numbers from the finance team.
> Ask Sarah for the updated spreadsheet.
- Get Q4 data from finance
- Write executive summary
- Email client @office +ClientProject
> They prefer to be contacted after 2pm EST.
"""
sections = parse_markdown_todos(notes_text)
sections[1].todos[1].notes"Need to include Q4 numbers from the finance team.\nAsk Sarah for the updated spreadsheet."
Subtasks can also have notes:
"From the finance team."
Notes roundtrip through write and parse:
# Work
- (A) Finish report @office +ClientProject due:2024-02-01
> Need to include Q4 numbers from the finance team.
> Ask Sarah for the updated spreadsheet.
- Get Q4 data from finance
- Write executive summary
- Email client @office +ClientProject
> They prefer to be contacted after 2pm EST.
Tasks without notes have an empty string and are written without any blockquote lines (fully backward-compatible).
parse_markdown_todos returns a vector of TodoSections, each with a heading, level, and todos:
2-element Vector{TodoSection}:
TodoSection("Work", 2 tasks)
TodoSection("Personal", 2 tasks)
2-element Vector{Todo}:
Todo: (A) Finish report @office +ClientProject
Todo: Email client @office
Todos appearing before any heading are placed in a section with heading="" and level=0:
write_markdown_todos serializes sections back to markdown with blank lines between sections:
MarkdownTodoFile is the section-aware counterpart to TodoFile. It reads a markdown file, provides iteration over all todos (flattened across sections), and can write back to disk:
4-element Vector{Todo}:
Todo: (A) Finish report @office +ClientProject
Todo: Email client @office
Todo: Buy groceries @store +Errands
Todo: (B) Call Mom @phone +Family due:2024-02-01
Write back to disk with write_todos:
All existing views work with MarkdownTodoFile – todos are flattened automatically:
| Done | Priority | Description | Tags | Created | Completed |
|---|---|---|---|---|---|
| A | Finish report | @office+ClientProject | |||
| Email client | @office | ||||
| Buy groceries | @store+Errands | ||||
| B | Call Mom | @phone+Familydue:2024-02-01 |
KanbanView supports :section as a group_by option, which groups todos by their markdown heading:
The html_view convenience function also accepts MarkdownTodoFile: