koder aka kdanilov | cff7b2e | 2015-04-18 20:48:15 +0300 | [diff] [blame] | 1 | __doc__ = "functions for make pretty yaml files" |
| 2 | __all__ = ['dumps'] |
| 3 | |
| 4 | |
koder aka kdanilov | f4b82c2 | 2015-04-11 13:35:25 +0300 | [diff] [blame] | 5 | def 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 | |
| 22 | def is_simple(val): |
| 23 | simple_type = isinstance(val, (str, unicode, int, long, bool, float)) |
| 24 | return simple_type or val is None |
| 25 | |
| 26 | |
| 27 | def all_nums(vals): |
| 28 | return all(isinstance(val, (int, float, long)) for val in vals) |
| 29 | |
| 30 | |
| 31 | def 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): |
| 44 | one_line = "[{}]".format(", ".join(map(dumps_simple, data))) |
| 45 | else: |
| 46 | one_line = "[{}]".format(",".join(map(dumps_simple, data))) |
| 47 | 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 | |
| 67 | if len(val_res) == 1 and len(key_str + val_res[0]) < width: |
| 68 | res.append(key_str + val_res[0]) |
| 69 | else: |
| 70 | res.append(key_str) |
| 71 | res.extend(tab + i for i in val_res) |
| 72 | else: |
| 73 | raise ValueError("Can't pack {0!r}".format(data)) |
| 74 | |
| 75 | return res |
| 76 | |
| 77 | |
| 78 | def dumps(data, tab_sz=4, width=120, min_width=40): |
| 79 | return "\n".join(dumpv(data, tab_sz, width, min_width)) |