mercurial/templater.py
changeset 38354 e637dc0b3b1f
parent 38353 48289eafb37d
child 38355 d4fae9a0ab1f
equal deleted inserted replaced
38353:48289eafb37d 38354:e637dc0b3b1f
   595     {key%format}.
   595     {key%format}.
   596 
   596 
   597     filter uses function to transform value. syntax is
   597     filter uses function to transform value. syntax is
   598     {key|filter1|filter2|...}.'''
   598     {key|filter1|filter2|...}.'''
   599 
   599 
   600     def __init__(self, loader, filters=None, defaults=None, resources=None,
   600     def __init__(self, loader, filters=None, defaults=None, resources=None):
   601                  aliases=()):
       
   602         self._loader = loader
   601         self._loader = loader
   603         if filters is None:
   602         if filters is None:
   604             filters = {}
   603             filters = {}
   605         self._filters = filters
   604         self._filters = filters
   606         self._funcs = templatefuncs.funcs  # make this a parameter if needed
   605         self._funcs = templatefuncs.funcs  # make this a parameter if needed
   608             defaults = {}
   607             defaults = {}
   609         if resources is None:
   608         if resources is None:
   610             resources = nullresourcemapper()
   609             resources = nullresourcemapper()
   611         self._defaults = defaults
   610         self._defaults = defaults
   612         self._resources = resources
   611         self._resources = resources
   613         self._aliasmap = _aliasrules.buildmap(aliases)
       
   614         self._cache = {}  # key: (func, data)
   612         self._cache = {}  # key: (func, data)
   615         self._tmplcache = {}  # literal template: (func, data)
   613         self._tmplcache = {}  # literal template: (func, data)
   616 
   614 
   617     def overlaymap(self, origmapping, newmapping):
   615     def overlaymap(self, origmapping, newmapping):
   618         """Create combined mapping from the original mapping and partial
   616         """Create combined mapping from the original mapping and partial
   663         return v
   661         return v
   664 
   662 
   665     def _load(self, t):
   663     def _load(self, t):
   666         '''load, parse, and cache a template'''
   664         '''load, parse, and cache a template'''
   667         if t not in self._cache:
   665         if t not in self._cache:
   668             x = parse(self._loader(t))
   666             x = self._loader(t)
   669             if self._aliasmap:
       
   670                 x = _aliasrules.expand(self._aliasmap, x)
       
   671             # put poison to cut recursion while compiling 't'
   667             # put poison to cut recursion while compiling 't'
   672             self._cache[t] = (_runrecursivesymbol, t)
   668             self._cache[t] = (_runrecursivesymbol, t)
   673             try:
   669             try:
   674                 self._cache[t] = compileexp(x, self, methods)
   670                 self._cache[t] = compileexp(x, self, methods)
   675             except: # re-raises
   671             except: # re-raises
   806         self._map = {}
   802         self._map = {}
   807         self._filters = templatefilters.filters.copy()
   803         self._filters = templatefilters.filters.copy()
   808         self._filters.update(filters)
   804         self._filters.update(filters)
   809         self.defaults = defaults
   805         self.defaults = defaults
   810         self._resources = resources
   806         self._resources = resources
   811         self._aliases = aliases
   807         self._aliasmap = _aliasrules.buildmap(aliases)
   812         self._minchunk, self._maxchunk = minchunk, maxchunk
   808         self._minchunk, self._maxchunk = minchunk, maxchunk
   813 
   809 
   814     @classmethod
   810     @classmethod
   815     def frommapfile(cls, mapfile, filters=None, defaults=None, resources=None,
   811     def frommapfile(cls, mapfile, filters=None, defaults=None, resources=None,
   816                     cache=None, minchunk=1024, maxchunk=65536):
   812                     cache=None, minchunk=1024, maxchunk=65536):
   817         """Create templater from the specified map file"""
   813         """Create templater from the specified map file"""
   818         t = cls(filters, defaults, resources, cache, [], minchunk, maxchunk)
   814         t = cls(filters, defaults, resources, cache, [], minchunk, maxchunk)
   819         cache, tmap, aliases = _readmapfile(mapfile)
   815         cache, tmap, aliases = _readmapfile(mapfile)
   820         t.cache.update(cache)
   816         t.cache.update(cache)
   821         t._map = tmap
   817         t._map = tmap
   822         t._aliases = aliases
   818         t._aliasmap = _aliasrules.buildmap(aliases)
   823         return t
   819         return t
   824 
   820 
   825     def __contains__(self, key):
   821     def __contains__(self, key):
   826         return key in self.cache or key in self._map
   822         return key in self.cache or key in self._map
   827 
   823 
   828     def load(self, t):
   824     def load(self, t):
   829         '''Get the template for the given template name. Use a local cache.'''
   825         """Get parsed tree for the given template name. Use a local cache."""
   830         if t not in self.cache:
   826         if t not in self.cache:
   831             try:
   827             try:
   832                 self.cache[t] = util.readfile(self._map[t])
   828                 self.cache[t] = util.readfile(self._map[t])
   833             except KeyError as inst:
   829             except KeyError as inst:
   834                 raise templateutil.TemplateNotFound(
   830                 raise templateutil.TemplateNotFound(
   836             except IOError as inst:
   832             except IOError as inst:
   837                 reason = (_('template file %s: %s')
   833                 reason = (_('template file %s: %s')
   838                           % (self._map[t],
   834                           % (self._map[t],
   839                              stringutil.forcebytestr(inst.args[1])))
   835                              stringutil.forcebytestr(inst.args[1])))
   840                 raise IOError(inst.args[0], encoding.strfromlocal(reason))
   836                 raise IOError(inst.args[0], encoding.strfromlocal(reason))
   841         return self.cache[t]
   837         return self._parse(self.cache[t])
       
   838 
       
   839     def _parse(self, tmpl):
       
   840         x = parse(tmpl)
       
   841         if self._aliasmap:
       
   842             x = _aliasrules.expand(self._aliasmap, x)
       
   843         return x
   842 
   844 
   843     def renderdefault(self, mapping):
   845     def renderdefault(self, mapping):
   844         """Render the default unnamed template and return result as string"""
   846         """Render the default unnamed template and return result as string"""
   845         return self.render('', mapping)
   847         return self.render('', mapping)
   846 
   848 
   849         return b''.join(self.generate(t, mapping))
   851         return b''.join(self.generate(t, mapping))
   850 
   852 
   851     def generate(self, t, mapping):
   853     def generate(self, t, mapping):
   852         """Return a generator that renders the specified named template and
   854         """Return a generator that renders the specified named template and
   853         yields chunks"""
   855         yields chunks"""
   854         proc = engine(self.load, self._filters, self.defaults, self._resources,
   856         proc = engine(self.load, self._filters, self.defaults, self._resources)
   855                       self._aliases)
       
   856         stream = proc.process(t, mapping)
   857         stream = proc.process(t, mapping)
   857         if self._minchunk:
   858         if self._minchunk:
   858             stream = util.increasingchunks(stream, min=self._minchunk,
   859             stream = util.increasingchunks(stream, min=self._minchunk,
   859                                            max=self._maxchunk)
   860                                            max=self._maxchunk)
   860         return stream
   861         return stream