Mercurial > public > mercurial-scm > hg
comparison mercurial/formatter.py @ 29794:4891f3b93182
formatter: add function to convert dict to appropriate format
This will be used to process key-value pairs by formatter. The default
field names and format are derived from the {extras} template keyword.
Tests will be added later.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Mon, 15 Aug 2016 12:58:33 +0900 |
parents | 2f3f18ad55a2 |
children | 18bac830eef3 |
comparison
equal
deleted
inserted
replaced
29793:24991e7f775f | 29794:4891f3b93182 |
---|---|
48 self._item = {} | 48 self._item = {} |
49 @staticmethod | 49 @staticmethod |
50 def formatdate(date, fmt='%a %b %d %H:%M:%S %Y %1%2'): | 50 def formatdate(date, fmt='%a %b %d %H:%M:%S %Y %1%2'): |
51 '''convert date tuple to appropriate format''' | 51 '''convert date tuple to appropriate format''' |
52 return date | 52 return date |
53 @staticmethod | |
54 def formatdict(data, key='key', value='value', fmt='%s=%s', sep=' '): | |
55 '''convert dict or key-value pairs to appropriate dict format''' | |
56 # use plain dict instead of util.sortdict so that data can be | |
57 # serialized as a builtin dict in pickle output | |
58 return dict(data) | |
53 @staticmethod | 59 @staticmethod |
54 def formatlist(data, name, fmt='%s', sep=' '): | 60 def formatlist(data, name, fmt='%s', sep=' '): |
55 '''convert iterable to appropriate list format''' | 61 '''convert iterable to appropriate list format''' |
56 return list(data) | 62 return list(data) |
57 def data(self, **data): | 63 def data(self, **data): |
73 def end(self): | 79 def end(self): |
74 '''end output for the formatter''' | 80 '''end output for the formatter''' |
75 if self._item is not None: | 81 if self._item is not None: |
76 self._showitem() | 82 self._showitem() |
77 | 83 |
84 def _iteritems(data): | |
85 '''iterate key-value pairs in stable order''' | |
86 if isinstance(data, dict): | |
87 return sorted(data.iteritems()) | |
88 return data | |
89 | |
78 class plainformatter(baseformatter): | 90 class plainformatter(baseformatter): |
79 '''the default text output scheme''' | 91 '''the default text output scheme''' |
80 def __init__(self, ui, topic, opts): | 92 def __init__(self, ui, topic, opts): |
81 baseformatter.__init__(self, ui, topic, opts) | 93 baseformatter.__init__(self, ui, topic, opts) |
82 if ui.debugflag: | 94 if ui.debugflag: |
89 pass | 101 pass |
90 @staticmethod | 102 @staticmethod |
91 def formatdate(date, fmt='%a %b %d %H:%M:%S %Y %1%2'): | 103 def formatdate(date, fmt='%a %b %d %H:%M:%S %Y %1%2'): |
92 '''stringify date tuple in the given format''' | 104 '''stringify date tuple in the given format''' |
93 return util.datestr(date, fmt) | 105 return util.datestr(date, fmt) |
106 @staticmethod | |
107 def formatdict(data, key='key', value='value', fmt='%s=%s', sep=' '): | |
108 '''stringify key-value pairs separated by sep''' | |
109 return sep.join(fmt % (k, v) for k, v in _iteritems(data)) | |
94 @staticmethod | 110 @staticmethod |
95 def formatlist(data, name, fmt='%s', sep=' '): | 111 def formatlist(data, name, fmt='%s', sep=' '): |
96 '''stringify iterable separated by sep''' | 112 '''stringify iterable separated by sep''' |
97 return sep.join(fmt % e for e in data) | 113 return sep.join(fmt % e for e in data) |
98 def data(self, **data): | 114 def data(self, **data): |
127 def end(self): | 143 def end(self): |
128 baseformatter.end(self) | 144 baseformatter.end(self) |
129 self._ui.write(pickle.dumps(self._data)) | 145 self._ui.write(pickle.dumps(self._data)) |
130 | 146 |
131 def _jsonifyobj(v): | 147 def _jsonifyobj(v): |
132 if isinstance(v, (list, tuple)): | 148 if isinstance(v, dict): |
149 xs = ['"%s": %s' % (encoding.jsonescape(k), _jsonifyobj(u)) | |
150 for k, u in sorted(v.iteritems())] | |
151 return '{' + ', '.join(xs) + '}' | |
152 elif isinstance(v, (list, tuple)): | |
133 return '[' + ', '.join(_jsonifyobj(e) for e in v) + ']' | 153 return '[' + ', '.join(_jsonifyobj(e) for e in v) + ']' |
134 elif v is None: | 154 elif v is None: |
135 return 'null' | 155 return 'null' |
136 elif v is True: | 156 elif v is True: |
137 return 'true' | 157 return 'true' |
172 self._topic = topic | 192 self._topic = topic |
173 self._t = gettemplater(ui, topic, opts.get('template', '')) | 193 self._t = gettemplater(ui, topic, opts.get('template', '')) |
174 def _showitem(self): | 194 def _showitem(self): |
175 g = self._t(self._topic, ui=self._ui, **self._item) | 195 g = self._t(self._topic, ui=self._ui, **self._item) |
176 self._ui.write(templater.stringify(g)) | 196 self._ui.write(templater.stringify(g)) |
197 @staticmethod | |
198 def formatdict(data, key='key', value='value', fmt='%s=%s', sep=' '): | |
199 '''build object that can be evaluated as either plain string or dict''' | |
200 data = util.sortdict(_iteritems(data)) | |
201 def f(): | |
202 yield plainformatter.formatdict(data, key, value, fmt, sep) | |
203 return templatekw._hybrid(f(), data, lambda k: {key: k, value: data[k]}, | |
204 lambda d: fmt % (d[key], d[value])) | |
177 @staticmethod | 205 @staticmethod |
178 def formatlist(data, name, fmt='%s', sep=' '): | 206 def formatlist(data, name, fmt='%s', sep=' '): |
179 '''build object that can be evaluated as either plain string or list''' | 207 '''build object that can be evaluated as either plain string or list''' |
180 # name is mandatory argument for now, but it could be optional if | 208 # name is mandatory argument for now, but it could be optional if |
181 # we have default template keyword, e.g. {item} | 209 # we have default template keyword, e.g. {item} |