source: nagslang/yamlish.py@ 102:fd9c4db5ddfe

Last change on this file since 102:fd9c4db5ddfe was 102:fd9c4db5ddfe, checked in by Stefano Rivera <stefano@…>, 8 years ago

Rename to yamlish

File size: 2.8 KB
Line 
1'''
2Serializer and dumper for a simple, YAMLish format (actually a YAML subset).
3The top level object is a dict.
4lists and dicts can contain lists, dicts, and strings.
5'''
6
7import re
8
9
10def dump(data, file_object):
11 file_object.write('\n'.join(_dump(data, 0)))
12
13
14def _dump(obj, indent):
15 if isinstance(obj, list):
16 for item in obj:
17 yield '%s- %s' % (' ' * indent,
18 '\n'.join(_dump(item, indent + 2)).strip())
19 elif isinstance(obj, dict):
20 for k, v in obj.iteritems():
21 if isinstance(v, basestring):
22 yield '%s%s: %s' % (' ' * indent, k, v)
23 else:
24 extra = 0 if isinstance(v, list) else 2
25 yield '%s%s:\n%s' % (' ' * indent, k,
26 '\n'.join(_dump(v, indent + extra)))
27 elif isinstance(obj, basestring):
28 yield '%s%s' % (' ' * indent, obj)
29
30
31spaces_re = re.compile(r'^(\s*)(.*)')
32list_re = re.compile(r'^(-\s+)(.*)')
33dict_re = re.compile(r'^([^-:]+):\s?(.*)')
34
35
36def load(file_object):
37 # Stack of (indent level, container object)
38 stack = [(0, {})]
39 indent = lambda: stack[-1][0]
40 obj = lambda: stack[-1][1]
41
42 # When a dict's value is a nested block, remember the key
43 parent_key = None
44
45 for line in file_object:
46 spaces, line = spaces_re.match(line).groups()
47
48 while len(spaces) < indent():
49 stack.pop()
50
51 lm = list_re.match(line)
52 dm = dict_re.match(line)
53 if len(spaces) == indent():
54 if lm:
55 assert isinstance(obj(), list) or parent_key
56 if isinstance(obj(), dict) and parent_key:
57 # Starting a list in a dict
58 stack.append((indent(), []))
59 stack[-2][1][parent_key] = obj()
60 parent_key = None
61 elif dm and isinstance(obj(), list):
62 # Left an embedded list
63 stack.pop()
64
65 if len(spaces) > indent():
66 # Nested dict
67 assert dm
68 assert parent_key
69 stack.append((len(spaces), {}))
70 stack[-2][1][parent_key] = obj()
71 parent_key = None
72
73 while lm and lm.group(2).startswith('- '):
74 # Nested lists
75 prefix, line = lm.groups()
76 stack.append((indent() + len(prefix), []))
77 stack[-2][1].append(obj())
78 lm = list_re.match(line)
79
80 if lm:
81 prefix, line = lm.groups()
82 dm = dict_re.match(line)
83 if dm:
84 stack.append((indent() + len(prefix), {}))
85 stack[-2][1].append(obj())
86 else:
87 obj().append(line)
88
89 if dm:
90 key, value = dm.groups()
91 if value:
92 obj()[key] = value
93 else:
94 parent_key = key
95
96 return stack[0][1]
Note: See TracBrowser for help on using the repository browser.