mercurial/templater.py
author Vadim Gelfer <vadim.gelfer@gmail.com>
Tue, 14 Mar 2006 21:40:46 -0800
changeset 1951 696230e52e4d
parent 1914 a5bf0030df5f
child 1955 2f500a4b6e99
permissions -rw-r--r--
add HGRCPATH env var, list of places to look for hgrc files. if set, override default hgrc search path. if empty, only .hg/hgrc of current repo read. for each element, if directory, all entries in directory with end in ".rc" are added to path. else, element is added to path. big thing about this change is that user "~/.hgrc" and system hgrc not longer breaks tests. run-tests makes HGRCPATH empty now.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
     1
# templater.py - template expansion for output
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
     2
#
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
     3
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
     4
#
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
     5
# This software may be used and distributed according to the terms
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
     7
1900
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
     8
import re
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
     9
from demandload import demandload
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    10
from i18n import gettext as _
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    11
demandload(globals(), "cStringIO cgi os time urllib util")
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    12
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    13
esctable = {
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    14
    '\\': '\\',
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    15
    'r': '\r',
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    16
    't': '\t',
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    17
    'n': '\n',
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    18
    'v': '\v',
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    19
    }
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    20
1902
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    21
def parsestring(s, quoted=True):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    22
    '''parse a string using simple c-like syntax.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    23
    string must be in quotes if quoted is True.'''
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    24
    fp = cStringIO.StringIO()
1902
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    25
    if quoted:
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    26
        first = s[0]
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    27
        if len(s) < 2: raise SyntaxError(_('string too short'))
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    28
        if first not in "'\"": raise SyntaxError(_('invalid quote'))
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    29
        if s[-1] != first: raise SyntaxError(_('unmatched quotes'))
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    30
        s = s[1:-1]
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    31
    escape = False
1902
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    32
    for c in s:
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    33
        if escape:
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    34
            fp.write(esctable.get(c, c))
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    35
            escape = False
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    36
        elif c == '\\': escape = True
1902
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
    37
        elif quoted and c == first: raise SyntaxError(_('string ends early'))
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    38
        else: fp.write(c)
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    39
    if escape: raise SyntaxError(_('unterminated escape'))
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    40
    return fp.getvalue()
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    41
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    42
class templater(object):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    43
    '''template expansion engine.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    44
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    45
    template expansion works like this. a map file contains key=value
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    46
    pairs. if value is quoted, it is treated as string. otherwise, it
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    47
    is treated as name of template file.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    48
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    49
    templater is asked to expand a key in map. it looks up key, and
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    50
    looks for atrings like this: {foo}. it expands {foo} by looking up
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    51
    foo in map, and substituting it. expansion is recursive: it stops
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    52
    when there is no more {foo} to replace.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    53
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    54
    expansion also allows formatting and filtering.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    55
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    56
    format uses key to expand each item in list. syntax is
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    57
    {key%format}.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    58
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    59
    filter uses function to transform value. syntax is
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    60
    {key|filter1|filter2|...}.'''
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    61
1913
74cf2b2f43d4 fix some things people wanted to be cleaner.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1912
diff changeset
    62
    def __init__(self, mapfile, filters={}, cache={}):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    63
        '''set up template engine.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    64
        mapfile is name of file to read map definitions from.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    65
        filters is dict of functions. each transforms a value into another.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
    66
        defaults is dict of default map definitions.'''
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    67
        self.mapfile = mapfile or 'template'
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    68
        self.cache = {}
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    69
        self.map = {}
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    70
        self.base = (mapfile and os.path.dirname(mapfile)) or ''
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    71
        self.filters = filters
1913
74cf2b2f43d4 fix some things people wanted to be cleaner.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1912
diff changeset
    72
        self.defaults = {}
74cf2b2f43d4 fix some things people wanted to be cleaner.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1912
diff changeset
    73
        self.cache = cache
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    74
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    75
        if not mapfile:
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    76
            return
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    77
        i = 0
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    78
        for l in file(mapfile):
1914
a5bf0030df5f make --style=compact look for map-cmdline.compact.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1913
diff changeset
    79
            l = l.strip()
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
    80
            i += 1
1914
a5bf0030df5f make --style=compact look for map-cmdline.compact.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1913
diff changeset
    81
            if not l or l[0] in '#;': continue
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    82
            m = re.match(r'([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$', l)
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    83
            if m:
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    84
                key, val = m.groups()
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    85
                if val[0] in "'\"":
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    86
                    try:
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    87
                        self.cache[key] = parsestring(val)
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    88
                    except SyntaxError, inst:
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    89
                        raise SyntaxError('%s:%s: %s' %
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    90
                                          (mapfile, i, inst.args[0]))
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    91
                else:
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    92
                    self.map[key] = os.path.join(self.base, val)
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    93
            else:
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
    94
                raise SyntaxError(_("%s:%s: parse error") % (mapfile, i))
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    95
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    96
    def __contains__(self, key):
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    97
        return key in self.cache
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
    98
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    99
    def __call__(self, t, **map):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   100
        '''perform expansion.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   101
        t is name of map element to expand.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   102
        map is added elements to use during expansion.'''
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   103
        m = self.defaults.copy()
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   104
        m.update(map)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   105
        try:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   106
            tmpl = self.cache[t]
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   107
        except KeyError:
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   108
            try:
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   109
                tmpl = self.cache[t] = file(self.map[t]).read()
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   110
            except IOError, inst:
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   111
                raise IOError(inst.args[0], _('template file %s: %s') %
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   112
                              (self.map[t], inst.args[1]))
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   113
        return self.template(tmpl, self.filters, **m)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   114
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   115
    template_re = re.compile(r"[#{]([a-zA-Z_][a-zA-Z0-9_]*)"
1900
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   116
                             r"((%[a-zA-Z_][a-zA-Z0-9_]*)*)"
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   117
                             r"((\|[a-zA-Z_][a-zA-Z0-9_]*)*)[#}]")
1900
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   118
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   119
    def template(self, tmpl, filters={}, **map):
1900
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   120
        lm = map.copy()
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   121
        while tmpl:
1900
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   122
            m = self.template_re.search(tmpl)
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   123
            if m:
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   124
                start, end = m.span(0)
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   125
                s, e = tmpl[start], tmpl[end - 1]
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   126
                key = m.group(1)
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   127
                if ((s == '#' and e != '#') or (s == '{' and e != '}')):
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   128
                    raise SyntaxError(_("'%s'/'%s' mismatch expanding '%s'") %
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   129
                                      (s, e, key))
1900
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   130
                if start:
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   131
                    yield tmpl[:start]
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   132
                v = map.get(key, "")
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   133
                v = callable(v) and v(**map) or v
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   134
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   135
                format = m.group(2)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   136
                fl = m.group(4)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   137
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   138
                if format:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   139
                    q = v.__iter__
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   140
                    for i in q():
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   141
                        lm.update(i)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   142
                        yield self(format[1:], **lm)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   143
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   144
                    v = ""
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   145
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   146
                elif fl:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   147
                    for f in fl.split("|")[1:]:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   148
                        v = filters[f](v)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   149
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   150
                yield v
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   151
                tmpl = tmpl[end:]
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   152
            else:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   153
                yield tmpl
1900
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   154
                break
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   155
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   156
agescales = [("second", 1),
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   157
             ("minute", 60),
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   158
             ("hour", 3600),
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   159
             ("day", 3600 * 24),
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   160
             ("week", 3600 * 24 * 7),
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   161
             ("month", 3600 * 24 * 30),
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   162
             ("year", 3600 * 24 * 365)]
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   163
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   164
agescales.reverse()
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   165
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   166
def age(date):
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   167
    '''turn a (timestamp, tzoff) tuple into an age string.'''
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   168
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   169
    def plural(t, c):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   170
        if c == 1:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   171
            return t
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   172
        return t + "s"
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   173
    def fmt(t, c):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   174
        return "%d %s" % (c, plural(t, c))
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   175
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   176
    now = time.time()
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   177
    then = date[0]
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   178
    delta = max(1, int(now - then))
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   179
1900
f2815605186e move repeated work out of inner loops.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1899
diff changeset
   180
    for t, s in agescales:
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   181
        n = delta / s
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   182
        if n >= 2 or s == 1:
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   183
            return fmt(t, n)
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   184
1906
9dec2479622d add iso date template filter.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1905
diff changeset
   185
def isodate(date):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   186
    '''turn a (timestamp, tzoff) tuple into an iso 8631 date.'''
1906
9dec2479622d add iso date template filter.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1905
diff changeset
   187
    return util.datestr(date, format='%Y-%m-%d %H:%M')
9dec2479622d add iso date template filter.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1905
diff changeset
   188
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   189
def nl2br(text):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   190
    '''replace raw newlines with xhtml line breaks.'''
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   191
    return text.replace('\n', '<br/>\n')
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   192
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   193
def obfuscate(text):
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   194
    return ''.join(['&#%d;' % ord(c) for c in text])
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   195
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   196
def domain(author):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   197
    '''get domain of author, or empty string if none.'''
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   198
    f = author.find('@')
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   199
    if f == -1: return ''
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   200
    author = author[f+1:]
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   201
    f = author.find('>')
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   202
    if f >= 0: author = author[:f]
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   203
    return author
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   204
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   205
def person(author):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   206
    '''get name of author, or else username.'''
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   207
    f = author.find('<')
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   208
    if f == -1: return util.shortuser(author)
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   209
    return author[:f].rstrip()
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   210
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   211
common_filters = {
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   212
    "addbreaks": nl2br,
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   213
    "age": age,
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   214
    "date": lambda x: util.datestr(x),
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
   215
    "domain": domain,
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   216
    "escape": lambda x: cgi.escape(x, True),
1912
b288b4bb8448 hide some functions behind lambdas, so demandload is useful.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1909
diff changeset
   217
    "firstline": lambda x: x.splitlines(1)[0].rstrip('\r\n'),
1906
9dec2479622d add iso date template filter.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1905
diff changeset
   218
    "isodate": isodate,
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   219
    "obfuscate": obfuscate,
1912
b288b4bb8448 hide some functions behind lambdas, so demandload is useful.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1909
diff changeset
   220
    "permissions": lambda x: x and "-rwxr-xr-x" or "-rw-r--r--",
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   221
    "person": person,
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   222
    "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"),
1912
b288b4bb8448 hide some functions behind lambdas, so demandload is useful.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1909
diff changeset
   223
    "short": lambda x: x[:12],
1904
a7e416bf3c1d improve templating.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1902
diff changeset
   224
    "strip": lambda x: x.strip(),
1912
b288b4bb8448 hide some functions behind lambdas, so demandload is useful.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1909
diff changeset
   225
    "urlescape": lambda x: urllib.quote(x),
b288b4bb8448 hide some functions behind lambdas, so demandload is useful.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1909
diff changeset
   226
    "user": lambda x: util.shortuser(x),
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   227
    }
1897
58b6784cf9f1 move hgweb.templatepath into templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1896
diff changeset
   228
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   229
def templatepath(name=None):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   230
    '''return location of template file or directory (if no name).
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
   231
    returns None if not found.'''
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   232
    for f in 'templates', '../templates':
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   233
        fl = f.split('/')
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   234
        if name: fl.append(name)
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   235
        p = os.path.join(os.path.dirname(__file__), *fl)
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
   236
        if (name and os.path.exists(p)) or os.path.isdir(p):
1897
58b6784cf9f1 move hgweb.templatepath into templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1896
diff changeset
   237
            return os.path.normpath(p)