##// END OF EJS Templates
templater: wrap result of '%' operation so it never looks like a thunk...
Yuya Nishihara -
r37517:75c13343 default
parent child Browse files
Show More
@@ -48,6 +48,10 b' mappable'
48 mappinggenerator, mappinglist
48 mappinggenerator, mappinglist
49 represents mappings (i.e. a list of dicts), which may have default
49 represents mappings (i.e. a list of dicts), which may have default
50 output format.
50 output format.
51
52 mappedgenerator
53 a lazily-evaluated list of byte strings, which is e.g. a result of %
54 operation.
51 """
55 """
52
56
53 from __future__ import absolute_import, print_function
57 from __future__ import absolute_import, print_function
@@ -227,6 +227,33 b' class mappinglist(_mappingsequence):'
227 def itermaps(self, context):
227 def itermaps(self, context):
228 return iter(self._mappings)
228 return iter(self._mappings)
229
229
230 class mappedgenerator(wrapped):
231 """Wrapper for generator of strings which acts as a list
232
233 The function ``make(context, *args)`` should return a generator of
234 byte strings, or a generator of (possibly nested) generators of byte
235 strings (i.e. a generator for a list of byte strings.)
236 """
237
238 def __init__(self, make, args=()):
239 self._make = make
240 self._args = args
241
242 def _gen(self, context):
243 return self._make(context, *self._args)
244
245 def itermaps(self, context):
246 raise error.ParseError(_('list of strings is not mappable'))
247
248 def join(self, context, mapping, sep):
249 return joinitems(self._gen(context), sep)
250
251 def show(self, context, mapping):
252 return self.join(context, mapping, '')
253
254 def tovalue(self, context, mapping):
255 return [stringify(context, mapping, x) for x in self._gen(context)]
256
230 def hybriddict(data, key='key', value='value', fmt=None, gen=None):
257 def hybriddict(data, key='key', value='value', fmt=None, gen=None):
231 """Wrap data to support both dict-like and string-like operations"""
258 """Wrap data to support both dict-like and string-like operations"""
232 prefmt = pycompat.identity
259 prefmt = pycompat.identity
@@ -589,18 +616,23 b' def _iteroverlaymaps(context, origmappin'
589 lm['index'] = i
616 lm['index'] = i
590 yield lm
617 yield lm
591
618
619 def _applymap(context, mapping, diter, targ):
620 for lm in _iteroverlaymaps(context, mapping, diter):
621 yield evalrawexp(context, lm, targ)
622
592 def runmap(context, mapping, data):
623 def runmap(context, mapping, data):
593 darg, targ = data
624 darg, targ = data
594 d = evalrawexp(context, mapping, darg)
625 d = evalrawexp(context, mapping, darg)
595 # TODO: a generator should be rejected because it is a thunk of lazy
626 # TODO: a generator should be rejected because it is a thunk of lazy
596 # string, but we can't because hgweb abuses generator as a keyword
627 # string, but we can't because hgweb abuses generator as a keyword
597 # that returns a list of dicts.
628 # that returns a list of dicts.
629 # TODO: drop _checkeditermaps() and pass 'd' to mappedgenerator so it
630 # can be restarted.
598 if isinstance(d, wrapped):
631 if isinstance(d, wrapped):
599 diter = d.itermaps(context)
632 diter = d.itermaps(context)
600 else:
633 else:
601 diter = _checkeditermaps(darg, d)
634 diter = _checkeditermaps(darg, d)
602 for lm in _iteroverlaymaps(context, mapping, diter):
635 return mappedgenerator(_applymap, args=(mapping, diter, targ))
603 yield evalrawexp(context, lm, targ)
604
636
605 def runmember(context, mapping, data):
637 def runmember(context, mapping, data):
606 darg, memb = data
638 darg, memb = data
@@ -3217,7 +3217,7 b' Test new-style inline templating:'
3217 hg: parse error: None is not iterable of mappings
3217 hg: parse error: None is not iterable of mappings
3218 [255]
3218 [255]
3219 $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}'
3219 $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}'
3220 hg: parse error: <generator *> is not iterable of mappings (glob)
3220 hg: parse error: list of strings is not mappable
3221 [255]
3221 [255]
3222
3222
3223 Test new-style inline templating of non-list/dict type:
3223 Test new-style inline templating of non-list/dict type:
@@ -3255,6 +3255,13 b' Test min/max of integers'
3255 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3255 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3256 10
3256 10
3257
3257
3258 Test min/max over map operation:
3259
3260 $ hg log -R latesttag -r3 -T '{min(tags % "{tag}")}\n'
3261 at3
3262 $ hg log -R latesttag -r3 -T '{max(tags % "{tag}")}\n'
3263 t3
3264
3258 Test min/max of if() result
3265 Test min/max of if() result
3259
3266
3260 $ cd latesttag
3267 $ cd latesttag
@@ -3842,6 +3849,11 b' Test json filter applied to hybrid objec'
3842 $ hg log -r0 -T '{extras|json}\n'
3849 $ hg log -r0 -T '{extras|json}\n'
3843 {"branch": "default"}
3850 {"branch": "default"}
3844
3851
3852 Test json filter applied to map result:
3853
3854 $ hg log -r0 -T '{json(extras % "{key}")}\n'
3855 ["branch"]
3856
3845 Test localdate(date, tz) function:
3857 Test localdate(date, tz) function:
3846
3858
3847 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
3859 $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n'
General Comments 0
You need to be logged in to leave comments. Login now