comparison mercurial/formatter.py @ 32967:13eebc189ff3

formatter: add support for docheader and docfooter templates templatepartsmap() is a minimal copy of changeset_templater.__init__(). I tried to factor out a common function, but it was unnecessarily complicated.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 22 Apr 2017 21:46:14 +0900
parents 12a0794fa2e3
children 5100ce217dfa
comparison
equal deleted inserted replaced
32966:12a0794fa2e3 32967:13eebc189ff3
348 baseformatter.__init__(self, ui, topic, opts, _templateconverter) 348 baseformatter.__init__(self, ui, topic, opts, _templateconverter)
349 self._out = out 349 self._out = out
350 spec = lookuptemplate(ui, topic, opts.get('template', '')) 350 spec = lookuptemplate(ui, topic, opts.get('template', ''))
351 self._tref = spec.ref 351 self._tref = spec.ref
352 self._t = loadtemplater(ui, spec, cache=templatekw.defaulttempl) 352 self._t = loadtemplater(ui, spec, cache=templatekw.defaulttempl)
353 self._parts = templatepartsmap(spec, self._t,
354 ['docheader', 'docfooter'])
353 self._counter = itertools.count() 355 self._counter = itertools.count()
354 self._cache = {} # for templatekw/funcs to store reusable data 356 self._cache = {} # for templatekw/funcs to store reusable data
357 self._renderitem('docheader', {})
358
355 def context(self, **ctxs): 359 def context(self, **ctxs):
356 '''insert context objects to be used to render template keywords''' 360 '''insert context objects to be used to render template keywords'''
357 ctxs = pycompat.byteskwargs(ctxs) 361 ctxs = pycompat.byteskwargs(ctxs)
358 assert all(k == 'ctx' for k in ctxs) 362 assert all(k == 'ctx' for k in ctxs)
359 self._item.update(ctxs) 363 self._item.update(ctxs)
361 def _showitem(self): 365 def _showitem(self):
362 item = self._item.copy() 366 item = self._item.copy()
363 item['index'] = next(self._counter) 367 item['index'] = next(self._counter)
364 self._renderitem(self._tref, item) 368 self._renderitem(self._tref, item)
365 369
366 def _renderitem(self, ref, item): 370 def _renderitem(self, part, item):
371 if part not in self._parts:
372 return
373 ref = self._parts[part]
374
367 # TODO: add support for filectx. probably each template keyword or 375 # TODO: add support for filectx. probably each template keyword or
368 # function will have to declare dependent resources. e.g. 376 # function will have to declare dependent resources. e.g.
369 # @templatekeyword(..., requires=('ctx',)) 377 # @templatekeyword(..., requires=('ctx',))
370 props = {} 378 props = {}
371 if 'ctx' in item: 379 if 'ctx' in item:
379 props['revcache'] = {} 387 props['revcache'] = {}
380 props = pycompat.strkwargs(props) 388 props = pycompat.strkwargs(props)
381 g = self._t(ref, ui=self._ui, cache=self._cache, **props) 389 g = self._t(ref, ui=self._ui, cache=self._cache, **props)
382 self._out.write(templater.stringify(g)) 390 self._out.write(templater.stringify(g))
383 391
392 def end(self):
393 baseformatter.end(self)
394 self._renderitem('docfooter', {})
395
384 templatespec = collections.namedtuple(r'templatespec', 396 templatespec = collections.namedtuple(r'templatespec',
385 r'ref tmpl mapfile') 397 r'ref tmpl mapfile')
386 398
387 def lookuptemplate(ui, topic, tmpl): 399 def lookuptemplate(ui, topic, tmpl):
388 """Find the template matching the given -T/--template spec 'tmpl' 400 """Find the template matching the given -T/--template spec 'tmpl'
431 tmpl = f.read() 443 tmpl = f.read()
432 return templatespec('', tmpl, None) 444 return templatespec('', tmpl, None)
433 445
434 # constant string? 446 # constant string?
435 return templatespec('', tmpl, None) 447 return templatespec('', tmpl, None)
448
449 def templatepartsmap(spec, t, partnames):
450 """Create a mapping of {part: ref}"""
451 partsmap = {spec.ref: spec.ref} # initial ref must exist in t
452 if spec.mapfile:
453 partsmap.update((p, p) for p in partnames if p in t)
454 return partsmap
436 455
437 def loadtemplater(ui, spec, cache=None): 456 def loadtemplater(ui, spec, cache=None):
438 """Create a templater from either a literal template or loading from 457 """Create a templater from either a literal template or loading from
439 a map file""" 458 a map file"""
440 assert not (spec.tmpl and spec.mapfile) 459 assert not (spec.tmpl and spec.mapfile)