Show More
@@ -316,16 +316,16 b' def join(context, mapping, args):' | |||||
316 | # i18n: "join" is a keyword |
|
316 | # i18n: "join" is a keyword | |
317 | raise error.ParseError(_("join expects one or two arguments")) |
|
317 | raise error.ParseError(_("join expects one or two arguments")) | |
318 |
|
318 | |||
319 | # TODO: perhaps this should be evalfuncarg(), but it can't because hgweb |
|
|||
320 | # abuses generator as a keyword that returns a list of dicts. |
|
|||
321 | joinset = evalrawexp(context, mapping, args[0]) |
|
319 | joinset = evalrawexp(context, mapping, args[0]) | |
322 | joinset = templateutil.unwrapvalue(context, mapping, joinset) |
|
|||
323 | joinfmt = getattr(joinset, 'joinfmt', pycompat.identity) |
|
|||
324 | joiner = " " |
|
320 | joiner = " " | |
325 | if len(args) > 1: |
|
321 | if len(args) > 1: | |
326 | joiner = evalstring(context, mapping, args[1]) |
|
322 | joiner = evalstring(context, mapping, args[1]) | |
327 | itemiter = (joinfmt(x) for x in pycompat.maybebytestr(joinset)) |
|
323 | if isinstance(joinset, templateutil.wrapped): | |
328 | return templateutil.joinitems(itemiter, joiner) |
|
324 | return joinset.join(context, mapping, joiner) | |
|
325 | # TODO: perhaps a generator should be stringify()-ed here, but we can't | |||
|
326 | # because hgweb abuses it as a keyword that returns a list of dicts. | |||
|
327 | joinset = templateutil.unwrapvalue(context, mapping, joinset) | |||
|
328 | return templateutil.joinitems(pycompat.maybebytestr(joinset), joiner) | |||
329 |
|
329 | |||
330 | @templatefunc('label(label, expr)') |
|
330 | @templatefunc('label(label, expr)') | |
331 | def label(context, mapping, args): |
|
331 | def label(context, mapping, args): |
@@ -42,6 +42,15 b' class wrapped(object):' | |||||
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 | |
@@ -86,11 +95,15 b' class hybrid(wrapped):' | |||||
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 | |
@@ -137,6 +150,14 b' class mappable(wrapped):' | |||||
137 | def itermaps(self, context): |
|
150 | def itermaps(self, context): | |
138 | yield self.tomap() |
|
151 | yield self.tomap() | |
139 |
|
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) | |||
|
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 |
General Comments 0
You need to be logged in to leave comments.
Login now