| 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): | 
| koder aka kdanilov | a047e1b | 2015-04-21 23:16:59 +0300 | [diff] [blame] | 44 |                 one_line = "[{0}]".format(", ".join(map(dumps_simple, data))) | 
| koder aka kdanilov | f4b82c2 | 2015-04-11 13:35:25 +0300 | [diff] [blame] | 45 |             else: | 
| koder aka kdanilov | a047e1b | 2015-04-21 23:16:59 +0300 | [diff] [blame] | 46 |                 one_line = "[{0}]".format(",".join(map(dumps_simple, data))) | 
| koder aka kdanilov | f4b82c2 | 2015-04-11 13:35:25 +0300 | [diff] [blame] | 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 |  | 
| koder aka kdanilov | 7e0f7cf | 2015-05-01 17:24:35 +0300 | [diff] [blame] | 67 |             if len(val_res) == 1 and \ | 
 | 68 |                len(key_str + val_res[0]) < width and \ | 
 | 69 |                not isinstance(v, dict): | 
| koder aka kdanilov | f4b82c2 | 2015-04-11 13:35:25 +0300 | [diff] [blame] | 70 |                 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 |  | 
 | 80 | def dumps(data, tab_sz=4, width=120, min_width=40): | 
 | 81 |     return "\n".join(dumpv(data, tab_sz, width, min_width)) |