mercurial/formatter.py
changeset 32949 13eebc189ff3
parent 32948 12a0794fa2e3
child 32950 5100ce217dfa
equal deleted inserted replaced
32948:12a0794fa2e3 32949: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)