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') |