from collections import OrderedDict, deque, namedtuple import shlex Meta = namedtuple('Meta', ['sects', 'meta']) def _merge(l): return ''.join(l).strip() def _next(l): sect = deque() while l and not l[0].strip().startswith('$'): sect.append(l.popleft()) if not l: return (('TRAIL', _merge(sect)), l) name = l.popleft().strip()[1:] sect = _merge(sect) return ((name, sect), l) def parse(s): l = deque(s.splitlines(True)) meta = dict() sects = OrderedDict() while l and l[0].strip().startswith('$'): s = shlex.split(l[0][1:]) meta[s[0]] = s[1:] l.popleft() while l: s, l = _next(l) sects[s[0]] = s[1] return Meta(sects, meta)