comparison mercurial/templateutil.py @ 37327:ebf139cbd4a1

templater: abstract away from joinfmt Future patches will add a wrapper for a list of template mappings, which will implement a custom join() something like {join(mappings % template)}. The original join() function is broken down as follows: if hasattr(joinset, 'joinfmt'): # hybrid.join() where values must be a list or a dict joinitems((joinfmt(x) for x in values), sep) elif isinstance(joinset, templateutil.wrapped): # mappable.join() show() else: # a plain list, a generator, or a byte string; joinfmt was identity() joinset = templateutil.unwrapvalue(context, joinset) joinitems(pycompat.maybebytestr(joinset), joiner)
author Yuya Nishihara <yuya@tcha.org>
date Sat, 17 Mar 2018 22:06:31 +0900
parents 9cd88dd3bf64
children 676664592313
comparison
equal deleted inserted replaced
37326:9cd88dd3bf64 37327:ebf139cbd4a1
40 @abc.abstractmethod 40 @abc.abstractmethod
41 def itermaps(self, context): 41 def itermaps(self, context):
42 """Yield each template mapping""" 42 """Yield each template mapping"""
43 43
44 @abc.abstractmethod 44 @abc.abstractmethod
45 def join(self, context, mapping, sep):
46 """Join items with the separator; Returns a bytes or (possibly nested)
47 generator of bytes
48
49 A pre-configured template may be rendered per item if this container
50 holds unprintable items.
51 """
52
53 @abc.abstractmethod
45 def show(self, context, mapping): 54 def show(self, context, mapping):
46 """Return a bytes or (possibly nested) generator of bytes representing 55 """Return a bytes or (possibly nested) generator of bytes representing
47 the underlying object 56 the underlying object
48 57
49 A pre-configured template may be rendered if the underlying object is 58 A pre-configured template may be rendered if the underlying object is
84 def itermaps(self, context): 93 def itermaps(self, context):
85 makemap = self._makemap 94 makemap = self._makemap
86 for x in self._values: 95 for x in self._values:
87 yield makemap(x) 96 yield makemap(x)
88 97
98 def join(self, context, mapping, sep):
99 # TODO: switch gen to (context, mapping) API?
100 return joinitems((self.joinfmt(x) for x in self._values), sep)
101
89 def show(self, context, mapping): 102 def show(self, context, mapping):
90 # TODO: switch gen to (context, mapping) API? 103 # TODO: switch gen to (context, mapping) API?
91 gen = self._gen 104 gen = self._gen
92 if gen is None: 105 if gen is None:
93 return joinitems((self.joinfmt(x) for x in self._values), ' ') 106 return self.join(context, mapping, ' ')
94 if callable(gen): 107 if callable(gen):
95 return gen() 108 return gen()
96 return gen 109 return gen
97 110
98 def tovalue(self, context, mapping): 111 def tovalue(self, context, mapping):
134 def tomap(self): 147 def tomap(self):
135 return self._makemap(self._key) 148 return self._makemap(self._key)
136 149
137 def itermaps(self, context): 150 def itermaps(self, context):
138 yield self.tomap() 151 yield self.tomap()
152
153 def join(self, context, mapping, sep):
154 # TODO: just copies the old behavior where a value was a generator
155 # yielding one item, but reconsider about it. join() over a string
156 # has no consistent result because a string may be a bytes, or a
157 # generator yielding an item, or a generator yielding multiple items.
158 # Preserving all of the current behaviors wouldn't make any sense.
159 return self.show(context, mapping)
139 160
140 def show(self, context, mapping): 161 def show(self, context, mapping):
141 # TODO: switch gen to (context, mapping) API? 162 # TODO: switch gen to (context, mapping) API?
142 gen = self._gen 163 gen = self._gen
143 if gen is None: 164 if gen is None: