Some prose about the goals of the project, whatever.
Run this project like so:
PRETTY=1 python task_parser.py project.md
- a task @done
- another task @delay(2014-01-01)
- a child task
- another child task
| [ | |
| { | |
| "children": [], | |
| "name": "a task @done", | |
| "tags": { | |
| "done": null | |
| } | |
| }, | |
| { | |
| "children": [ | |
| { | |
| "children": [], | |
| "name": "a child task", | |
| "tags": {} | |
| }, | |
| { | |
| "children": [], | |
| "name": "another child task", | |
| "tags": {} | |
| } | |
| ], | |
| "name": "another task @delay(2014-01-01)", | |
| "tags": { | |
| "delay": "2014-01-01" | |
| } | |
| } | |
| ] |
| from itertools import chain | |
| import json | |
| import re | |
| import yaml | |
| task_re = re.compile(' +\+ .+') | |
| tag_re = re.compile('@(?P<tag>[\w\-_]+)(\((?P<value>.+?)\))?') | |
| def tasks_for_file(fname): | |
| with open(fname, 'r') as f: | |
| text = f.read() | |
| tasks = task_re.findall(text) | |
| sanitized = [ | |
| task.replace('+', '-', 1) + ':' | |
| for task in tasks | |
| ] | |
| tasks = yaml.safe_load('\n'.join(sanitized)) | |
| tasks = sanitize_tasks(tasks) | |
| return tasks | |
| def sanitize_tasks(tasks): | |
| for task in tasks: | |
| name = task.keys()[0] | |
| children = list(sanitize_tasks(task.values()[0] or [])) | |
| tags = { | |
| tag.groupdict()['tag']: tag.groupdict()['value'] | |
| for tag in tag_re.finditer(name) | |
| } | |
| yield { | |
| 'name': name, | |
| 'tags': tags, | |
| 'children': children, | |
| } | |
| def main(files, indent=2): | |
| tasks = chain.from_iterable( | |
| tasks_for_file(fname) | |
| for fname in files | |
| ) | |
| return json.dumps(list(tasks), indent=indent) | |
| if __name__ == '__main__': | |
| import os, sys | |
| sys.stdout.write(main( | |
| sys.argv[1:], | |
| 2 if os.environ.get('PRETTY', '0') == '1' else None | |
| ) + '\n') |