blob: ff1f3bc3c5baf887af1b47a7ce16f97ed9a81da7 [file] [log] [blame]
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +03001__doc__ = "functions for make pretty yaml files"
2__all__ = ['dumps']
3
4
koder aka kdanilovf4b82c22015-04-11 13:35:25 +03005def dumps_simple(val):
6 bad_symbols = set(" \r\t\n,':")
7
8 if isinstance(val, basestring):
9 if len(bad_symbols & set(val)) != 0:
10 return repr(val)
11 return val
12 elif val is True:
13 return 'true'
14 elif val is False:
15 return 'false'
16 elif val is None:
17 return 'null'
18
19 return str(val)
20
21
22def is_simple(val):
23 simple_type = isinstance(val, (str, unicode, int, long, bool, float))
24 return simple_type or val is None
25
26
27def all_nums(vals):
28 return all(isinstance(val, (int, float, long)) for val in vals)
29
30
31def dumpv(data, tab_sz=4, width=120, min_width=40):
32 tab = ' ' * tab_sz
33
34 if width < min_width:
35 width = min_width
36
37 res = []
38 if is_simple(data):
39 return [dumps_simple(data)]
40
41 if isinstance(data, (list, tuple)):
42 if all(map(is_simple, data)):
43 if all_nums(data):
koder aka kdanilova047e1b2015-04-21 23:16:59 +030044 one_line = "[{0}]".format(", ".join(map(dumps_simple, data)))
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030045 else:
koder aka kdanilova047e1b2015-04-21 23:16:59 +030046 one_line = "[{0}]".format(",".join(map(dumps_simple, data)))
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030047 else:
48 one_line = None
49
50 if one_line is None or len(one_line) > width:
51 pref = "-" + ' ' * (tab_sz - 1)
52
53 for val in data:
54 items = dumpv(val, tab_sz, width - tab_sz, min_width)
55 items = [pref + items[0]] + \
56 [tab + item for item in items[1:]]
57 res.extend(items)
58 else:
59 res.append(one_line)
60 elif isinstance(data, dict):
61 assert all(map(is_simple, data.keys()))
62
63 for k, v in data.items():
64 key_str = dumps_simple(k) + ": "
65 val_res = dumpv(v, tab_sz, width - tab_sz, min_width)
66
koder aka kdanilov7e0f7cf2015-05-01 17:24:35 +030067 if len(val_res) == 1 and \
68 len(key_str + val_res[0]) < width and \
69 not isinstance(v, dict):
koder aka kdanilovf4b82c22015-04-11 13:35:25 +030070 res.append(key_str + val_res[0])
71 else:
72 res.append(key_str)
73 res.extend(tab + i for i in val_res)
74 else:
75 raise ValueError("Can't pack {0!r}".format(data))
76
77 return res
78
79
80def dumps(data, tab_sz=4, width=120, min_width=40):
81 return "\n".join(dumpv(data, tab_sz, width, min_width))