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}