Mercurial > hg
annotate mercurial/templater.py @ 18365:4148414da120
obsolete: process markers in a stable order
Using set iteration order gave unstable debugsuccessorssets output with
PYTHONHASHSEED=random.
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Tue, 15 Jan 2013 02:59:13 +0100 |
parents | 9bfb53106328 |
children | ef78450c8df6 |
rev | line source |
---|---|
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 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8223
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
7 |
3891 | 8 from i18n import _ |
17635
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
9 import sys, os, re |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
10 import util, config, templatefilters, parser, error |
17982
e06e9fd2d99f
template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents:
17890
diff
changeset
|
11 import types |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
12 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
13 # template parsing |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
14 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
15 elements = { |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
16 "(": (20, ("group", 1, ")"), ("func", 1, ")")), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
17 ",": (2, None, ("list", 2)), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
18 "|": (5, None, ("|", 5)), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
19 "%": (6, None, ("%", 6)), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
20 ")": (0, None, None), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
21 "symbol": (0, ("symbol",), None), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
22 "string": (0, ("string",), None), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
23 "end": (0, None, None), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
24 } |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
25 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
26 def tokenizer(data): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
27 program, start, end = data |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
28 pos = start |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
29 while pos < end: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
30 c = program[pos] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
31 if c.isspace(): # skip inter-token whitespace |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
32 pass |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
33 elif c in "(,)%|": # handle simple operators |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
34 yield (c, None, pos) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
35 elif (c in '"\'' or c == 'r' and |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
36 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
37 if c == 'r': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
38 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
39 c = program[pos] |
17634
6b307730c9f0
templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents:
17633
diff
changeset
|
40 decode = False |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
41 else: |
17634
6b307730c9f0
templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents:
17633
diff
changeset
|
42 decode = True |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
43 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
44 s = pos |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
45 while pos < end: # find closing quote |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
46 d = program[pos] |
17634
6b307730c9f0
templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents:
17633
diff
changeset
|
47 if decode and d == '\\': # skip over escaped characters |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
48 pos += 2 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
49 continue |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
50 if d == c: |
17634
6b307730c9f0
templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents:
17633
diff
changeset
|
51 if not decode: |
6b307730c9f0
templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents:
17633
diff
changeset
|
52 yield ('string', program[s:pos].replace('\\', r'\\'), s) |
6b307730c9f0
templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents:
17633
diff
changeset
|
53 break |
6b307730c9f0
templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents:
17633
diff
changeset
|
54 yield ('string', program[s:pos].decode('string-escape'), s) |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
55 break |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
56 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
57 else: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
58 raise error.ParseError(_("unterminated string"), s) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
59 elif c.isalnum() or c in '_': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
60 s = pos |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
61 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
62 while pos < end: # find end of symbol |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
63 d = program[pos] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
64 if not (d.isalnum() or d == "_"): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
65 break |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
66 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
67 sym = program[s:pos] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
68 yield ('symbol', sym, s) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
69 pos -= 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
70 elif c == '}': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
71 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
72 break |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
73 else: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
74 raise error.ParseError(_("syntax error"), pos) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
75 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
76 yield ('end', None, pos) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
77 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
78 def compiletemplate(tmpl, context): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
79 parsed = [] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
80 pos, stop = 0, len(tmpl) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
81 p = parser.parser(tokenizer, elements) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
82 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
83 while pos < stop: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
84 n = tmpl.find('{', pos) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
85 if n < 0: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
86 parsed.append(("string", tmpl[pos:])) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
87 break |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
88 if n > 0 and tmpl[n - 1] == '\\': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
89 # escaped |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
90 parsed.append(("string", tmpl[pos:n - 1] + "{")) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
91 pos = n + 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
92 continue |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
93 if n > pos: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
94 parsed.append(("string", tmpl[pos:n])) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
95 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
96 pd = [tmpl, n + 1, stop] |
13665
e798e430c5e5
revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents:
13187
diff
changeset
|
97 parseres, pos = p.parse(pd) |
e798e430c5e5
revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents:
13187
diff
changeset
|
98 parsed.append(parseres) |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
99 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
100 return [compileexp(e, context) for e in parsed] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
101 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
102 def compileexp(exp, context): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
103 t = exp[0] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
104 if t in methods: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
105 return methods[t](exp, context) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
106 raise error.ParseError(_("unknown method '%s'") % t) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
107 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
108 # template evaluation |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
109 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
110 def getsymbol(exp): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
111 if exp[0] == 'symbol': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
112 return exp[1] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
113 raise error.ParseError(_("expected a symbol")) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
114 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
115 def getlist(x): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
116 if not x: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
117 return [] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
118 if x[0] == 'list': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
119 return getlist(x[1]) + [x[2]] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
120 return [x] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
121 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
122 def getfilter(exp, context): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
123 f = getsymbol(exp) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
124 if f not in context._filters: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
125 raise error.ParseError(_("unknown function '%s'") % f) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
126 return context._filters[f] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
127 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
128 def gettemplate(exp, context): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
129 if exp[0] == 'string': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
130 return compiletemplate(exp[1], context) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
131 if exp[0] == 'symbol': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
132 return context._load(exp[1]) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
133 raise error.ParseError(_("expected template specifier")) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
134 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
135 def runstring(context, mapping, data): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
136 return data |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
137 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
138 def runsymbol(context, mapping, key): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
139 v = mapping.get(key) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
140 if v is None: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
141 v = context._defaults.get(key, '') |
14943
d3bb825ddae3
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
Augie Fackler <durin42@gmail.com>
parents:
14941
diff
changeset
|
142 if util.safehasattr(v, '__call__'): |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
143 return v(**mapping) |
17982
e06e9fd2d99f
template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents:
17890
diff
changeset
|
144 if isinstance(v, types.GeneratorType): |
e06e9fd2d99f
template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents:
17890
diff
changeset
|
145 v = list(v) |
e06e9fd2d99f
template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents:
17890
diff
changeset
|
146 mapping[key] = v |
e06e9fd2d99f
template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents:
17890
diff
changeset
|
147 return v |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
148 return v |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
149 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
150 def buildfilter(exp, context): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
151 func, data = compileexp(exp[1], context) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
152 filt = getfilter(exp[2], context) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
153 return (runfilter, (func, data, filt)) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
154 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
155 def runfilter(context, mapping, data): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
156 func, data, filt = data |
17383
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
157 try: |
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
158 return filt(func(context, mapping, data)) |
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
159 except (ValueError, AttributeError, TypeError): |
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
160 if isinstance(data, tuple): |
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
161 dt = data[1] |
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
162 else: |
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
163 dt = data |
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
164 raise util.Abort(_("template filter '%s' is not compatible with " |
099c778ceb33
templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents:
17334
diff
changeset
|
165 "keyword '%s'") % (filt.func_name, dt)) |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
166 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
167 def buildmap(exp, context): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
168 func, data = compileexp(exp[1], context) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
169 ctmpl = gettemplate(exp[2], context) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
170 return (runmap, (func, data, ctmpl)) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
171 |
17632
523625e46760
templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents:
17631
diff
changeset
|
172 def runtemplate(context, mapping, template): |
523625e46760
templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents:
17631
diff
changeset
|
173 for func, data in template: |
523625e46760
templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents:
17631
diff
changeset
|
174 yield func(context, mapping, data) |
523625e46760
templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents:
17631
diff
changeset
|
175 |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
176 def runmap(context, mapping, data): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
177 func, data, ctmpl = data |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
178 d = func(context, mapping, data) |
17631
0b241d7a8c62
templating: make new-style templating features work with command line lists
Matt Mackall <mpm@selenic.com>
parents:
17383
diff
changeset
|
179 if util.safehasattr(d, '__call__'): |
0b241d7a8c62
templating: make new-style templating features work with command line lists
Matt Mackall <mpm@selenic.com>
parents:
17383
diff
changeset
|
180 d = d() |
0b241d7a8c62
templating: make new-style templating features work with command line lists
Matt Mackall <mpm@selenic.com>
parents:
17383
diff
changeset
|
181 |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
182 lm = mapping.copy() |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
183 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
184 for i in d: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
185 if isinstance(i, dict): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
186 lm.update(i) |
17991
d605a82cf189
hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents:
17982
diff
changeset
|
187 lm['originalnode'] = mapping.get('node') |
17632
523625e46760
templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents:
17631
diff
changeset
|
188 yield runtemplate(context, lm, ctmpl) |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
189 else: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
190 # v is not an iterable of dicts, this happen when 'key' |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
191 # has been fully expanded already and format is useless. |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
192 # If so, return the expanded value. |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
193 yield i |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
194 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
195 def buildfunc(exp, context): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
196 n = getsymbol(exp[1]) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
197 args = [compileexp(x, context) for x in getlist(exp[2])] |
14925
ab545a15d807
templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents:
14168
diff
changeset
|
198 if n in funcs: |
ab545a15d807
templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents:
14168
diff
changeset
|
199 f = funcs[n] |
ab545a15d807
templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents:
14168
diff
changeset
|
200 return (f, args) |
17637
02d2166ef5f1
templater: pull in functions defined in templatefilters
Matt Mackall <mpm@selenic.com>
parents:
17636
diff
changeset
|
201 if n in templatefilters.funcs: |
02d2166ef5f1
templater: pull in functions defined in templatefilters
Matt Mackall <mpm@selenic.com>
parents:
17636
diff
changeset
|
202 f = templatefilters.funcs[n] |
02d2166ef5f1
templater: pull in functions defined in templatefilters
Matt Mackall <mpm@selenic.com>
parents:
17636
diff
changeset
|
203 return (f, args) |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
204 if n in context._filters: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
205 if len(args) != 1: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
206 raise error.ParseError(_("filter %s expects one argument") % n) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
207 f = context._filters[n] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
208 return (runfilter, (args[0][0], args[0][1], f)) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
209 |
17633
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
210 def join(context, mapping, args): |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
211 if not (1 <= len(args) <= 2): |
17890
ca6850b9dd9e
i18n: add "i18n" comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17729
diff
changeset
|
212 # i18n: "join" is a keyword |
17633
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
213 raise error.ParseError(_("join expects one or two arguments")) |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
214 |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
215 joinset = args[0][0](context, mapping, args[0][1]) |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
216 if util.safehasattr(joinset, '__call__'): |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
217 joinset = [x.values()[0] for x in joinset()] |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
218 |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
219 joiner = " " |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
220 if len(args) > 1: |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
221 joiner = args[1][0](context, mapping, args[1][1]) |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
222 |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
223 first = True |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
224 for x in joinset: |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
225 if first: |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
226 first = False |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
227 else: |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
228 yield joiner |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
229 yield x |
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
230 |
17635
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
231 def sub(context, mapping, args): |
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
232 if len(args) != 3: |
17890
ca6850b9dd9e
i18n: add "i18n" comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17729
diff
changeset
|
233 # i18n: "sub" is a keyword |
17635
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
234 raise error.ParseError(_("sub expects three arguments")) |
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
235 |
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
236 pat = stringify(args[0][0](context, mapping, args[0][1])) |
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
237 rpl = stringify(args[1][0](context, mapping, args[1][1])) |
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
238 src = stringify(args[2][0](context, mapping, args[2][1])) |
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
239 yield re.sub(pat, rpl, src) |
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
240 |
17636
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
241 def if_(context, mapping, args): |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
242 if not (2 <= len(args) <= 3): |
17890
ca6850b9dd9e
i18n: add "i18n" comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17729
diff
changeset
|
243 # i18n: "if" is a keyword |
17636
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
244 raise error.ParseError(_("if expects two or three arguments")) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
245 |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
246 test = stringify(args[0][0](context, mapping, args[0][1])) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
247 if test: |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
248 t = stringify(args[1][0](context, mapping, args[1][1])) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
249 yield runtemplate(context, mapping, compiletemplate(t, context)) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
250 elif len(args) == 3: |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
251 t = stringify(args[2][0](context, mapping, args[2][1])) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
252 yield runtemplate(context, mapping, compiletemplate(t, context)) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
253 |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
254 def ifeq(context, mapping, args): |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
255 if not (3 <= len(args) <= 4): |
17890
ca6850b9dd9e
i18n: add "i18n" comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17729
diff
changeset
|
256 # i18n: "ifeq" is a keyword |
17636
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
257 raise error.ParseError(_("ifeq expects three or four arguments")) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
258 |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
259 test = stringify(args[0][0](context, mapping, args[0][1])) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
260 match = stringify(args[1][0](context, mapping, args[1][1])) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
261 if test == match: |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
262 t = stringify(args[2][0](context, mapping, args[2][1])) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
263 yield runtemplate(context, mapping, compiletemplate(t, context)) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
264 elif len(args) == 4: |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
265 t = stringify(args[3][0](context, mapping, args[3][1])) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
266 yield runtemplate(context, mapping, compiletemplate(t, context)) |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
267 |
18289
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
268 def label(context, mapping, args): |
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
269 if len(args) != 2: |
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
270 # i18n: "label" is a keyword |
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
271 raise error.ParseError(_("label expects two arguments")) |
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
272 |
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
273 # ignore args[0] (the label string) since this is supposed to be a a no-op |
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
274 t = stringify(args[1][0](context, mapping, args[1][1])) |
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
275 yield runtemplate(context, mapping, compiletemplate(t, context)) |
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
276 |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
277 methods = { |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
278 "string": lambda e, c: (runstring, e[1]), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
279 "symbol": lambda e, c: (runsymbol, e[1]), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
280 "group": lambda e, c: compileexp(e[1], c), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
281 # ".": buildmember, |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
282 "|": buildfilter, |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
283 "%": buildmap, |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
284 "func": buildfunc, |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
285 } |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
286 |
14925
ab545a15d807
templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents:
14168
diff
changeset
|
287 funcs = { |
17636
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
288 "if": if_, |
ce18dbcd91c8
templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents:
17635
diff
changeset
|
289 "ifeq": ifeq, |
17633
312184f930b7
template: add join function
Matt Mackall <mpm@selenic.com>
parents:
17632
diff
changeset
|
290 "join": join, |
17635
8804e3cb51bd
templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents:
17634
diff
changeset
|
291 "sub": sub, |
18289
9bfb53106328
templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents:
17991
diff
changeset
|
292 "label": label, |
14925
ab545a15d807
templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents:
14168
diff
changeset
|
293 } |
ab545a15d807
templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents:
14168
diff
changeset
|
294 |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
295 # template engine |
1901
c64bef3d7043
use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1900
diff
changeset
|
296 |
7107
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
297 path = ['templates', '../templates'] |
8360
acc202b71619
templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8312
diff
changeset
|
298 stringify = templatefilters.stringify |
7107
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
299 |
10850
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
300 def _flatten(thing): |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
301 '''yield a single stream from a possibly nested set of iterators''' |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
302 if isinstance(thing, str): |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
303 yield thing |
14944
e2c413bde8a5
globally: use safehasattr(x, '__iter__') instead of hasattr(x, '__iter__')
Augie Fackler <durin42@gmail.com>
parents:
14943
diff
changeset
|
304 elif not util.safehasattr(thing, '__iter__'): |
11305
d4cafcb63f77
cleanups: undefined variables
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10855
diff
changeset
|
305 if thing is not None: |
10852
0d50586a9d31
templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents:
10850
diff
changeset
|
306 yield str(thing) |
0d50586a9d31
templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents:
10850
diff
changeset
|
307 else: |
10850
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
308 for i in thing: |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
309 if isinstance(i, str): |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
310 yield i |
14944
e2c413bde8a5
globally: use safehasattr(x, '__iter__') instead of hasattr(x, '__iter__')
Augie Fackler <durin42@gmail.com>
parents:
14943
diff
changeset
|
311 elif not util.safehasattr(i, '__iter__'): |
10852
0d50586a9d31
templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents:
10850
diff
changeset
|
312 if i is not None: |
0d50586a9d31
templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents:
10850
diff
changeset
|
313 yield str(i) |
10850
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
314 elif i is not None: |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
315 for j in _flatten(i): |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
316 yield j |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
317 |
1902
1cc5f25653a3
make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1901
diff
changeset
|
318 def parsestring(s, quoted=True): |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
319 '''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
|
320 string must be in quotes if quoted is True.''' |
1902
1cc5f25653a3
make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1901
diff
changeset
|
321 if quoted: |
3639
5c9a36210662
templater: simplify parsestring
Matt Mackall <mpm@selenic.com>
parents:
3638
diff
changeset
|
322 if len(s) < 2 or s[0] != s[-1]: |
5c9a36210662
templater: simplify parsestring
Matt Mackall <mpm@selenic.com>
parents:
3638
diff
changeset
|
323 raise SyntaxError(_('unmatched quotes')) |
5c9a36210662
templater: simplify parsestring
Matt Mackall <mpm@selenic.com>
parents:
3638
diff
changeset
|
324 return s[1:-1].decode('string_escape') |
3632
231393b7316f
templater: use str.decode in parse_string
Matt Mackall <mpm@selenic.com>
parents:
3462
diff
changeset
|
325 |
231393b7316f
templater: use str.decode in parse_string
Matt Mackall <mpm@selenic.com>
parents:
3462
diff
changeset
|
326 return s.decode('string_escape') |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
327 |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
328 class engine(object): |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
329 '''template expansion engine. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
330 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
331 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
|
332 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
|
333 is treated as name of template file. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
334 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
335 templater is asked to expand a key in map. it looks up key, and |
4334
66a3fe30f9fc
minor typo fix in templater's docstring
TK Soh <teekaysoh@yahoo.com>
parents:
3904
diff
changeset
|
336 looks for strings like this: {foo}. it expands {foo} by looking up |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
337 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
|
338 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
|
339 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
340 expansion also allows formatting and filtering. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
341 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
342 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
|
343 {key%format}. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
344 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
345 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
|
346 {key|filter1|filter2|...}.''' |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
347 |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
348 def __init__(self, loader, filters={}, defaults={}): |
10848
01346cea5485
templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents:
10847
diff
changeset
|
349 self._loader = loader |
01346cea5485
templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents:
10847
diff
changeset
|
350 self._filters = filters |
01346cea5485
templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents:
10847
diff
changeset
|
351 self._defaults = defaults |
01346cea5485
templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents:
10847
diff
changeset
|
352 self._cache = {} |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
353 |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
354 def _load(self, t): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
355 '''load, parse, and cache a template''' |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
356 if t not in self._cache: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
357 self._cache[t] = compiletemplate(self._loader(t), self) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
358 return self._cache[t] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
359 |
10853
b6f6d9fd53d6
templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents:
10852
diff
changeset
|
360 def process(self, t, mapping): |
b6f6d9fd53d6
templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents:
10852
diff
changeset
|
361 '''Perform expansion. t is name of map element to expand. |
b6f6d9fd53d6
templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents:
10852
diff
changeset
|
362 mapping contains added elements for use during expansion. Is a |
b6f6d9fd53d6
templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents:
10852
diff
changeset
|
363 generator.''' |
17632
523625e46760
templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents:
17631
diff
changeset
|
364 return _flatten(runtemplate(self, mapping, self._load(t))) |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
365 |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
366 engines = {'default': engine} |
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
367 |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
368 class templater(object): |
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
369 |
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
370 def __init__(self, mapfile, filters={}, defaults={}, cache={}, |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
371 minchunk=1024, maxchunk=65536): |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
372 '''set up template engine. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
373 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
|
374 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
|
375 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
|
376 self.mapfile = mapfile or 'template' |
1975
6e1a8ea5d717
Duplicate cache when creating templater.
Shun-ichi Goto <shunichi.goto@gmail.com>
parents:
1964
diff
changeset
|
377 self.cache = cache.copy() |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
378 self.map = {} |
1905
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
379 self.base = (mapfile and os.path.dirname(mapfile)) or '' |
8360
acc202b71619
templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8312
diff
changeset
|
380 self.filters = templatefilters.filters.copy() |
acc202b71619
templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8312
diff
changeset
|
381 self.filters.update(filters) |
1964
778281d46bb2
fix template bug that made hgweb break.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1955
diff
changeset
|
382 self.defaults = defaults |
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
383 self.minchunk, self.maxchunk = minchunk, maxchunk |
13187
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
384 self.ecache = {} |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
385 |
1905
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
386 if not mapfile: |
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
387 return |
6337
d2713d902524
give better error message on non-existent mapfile (issue813)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5976
diff
changeset
|
388 if not os.path.exists(mapfile): |
d2713d902524
give better error message on non-existent mapfile (issue813)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5976
diff
changeset
|
389 raise util.Abort(_('style not found: %s') % mapfile) |
d2713d902524
give better error message on non-existent mapfile (issue813)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5976
diff
changeset
|
390 |
8194
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
391 conf = config.config() |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
392 conf.read(mapfile) |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
393 |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
394 for key, val in conf[''].items(): |
17334
39c01f8e7b39
templater: handle a missing value correctly
Ross Lagerwall <rosslagerwall@gmail.com>
parents:
16686
diff
changeset
|
395 if not val: |
39c01f8e7b39
templater: handle a missing value correctly
Ross Lagerwall <rosslagerwall@gmail.com>
parents:
16686
diff
changeset
|
396 raise SyntaxError(_('%s: missing value') % conf.source('', key)) |
8194
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
397 if val[0] in "'\"": |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
398 try: |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
399 self.cache[key] = parsestring(val) |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
400 except SyntaxError, inst: |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
401 raise SyntaxError('%s: %s' % |
8198
cf9accffd0b3
config: getsource -> source
Matt Mackall <mpm@selenic.com>
parents:
8194
diff
changeset
|
402 (conf.source('', key), inst.args[0])) |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
403 else: |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
404 val = 'default', val |
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
405 if ':' in val[1]: |
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
406 val = val[1].split(':', 1) |
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
407 self.map[key] = val[0], os.path.join(self.base, val[1]) |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
408 |
1899
888d298ddb91
many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1897
diff
changeset
|
409 def __contains__(self, key): |
3637
e7639888bb2f
templater: simplify cache and remove filter argument in __call__
Matt Mackall <mpm@selenic.com>
parents:
3636
diff
changeset
|
410 return key in self.cache or key in self.map |
1899
888d298ddb91
many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1897
diff
changeset
|
411 |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
412 def load(self, t): |
6783
6d824dc86907
templater: make a template a string-only iterator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6434
diff
changeset
|
413 '''Get the template for the given template name. Use a local cache.''' |
16686
67964cda8701
cleanup: "not x in y" -> "x not in y"
Brodie Rao <brodie@sf.io>
parents:
14944
diff
changeset
|
414 if t not in self.cache: |
1905
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
415 try: |
14168
135e244776f0
prevent transient leaks of file handle by using new helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
13665
diff
changeset
|
416 self.cache[t] = util.readfile(self.map[t][1]) |
13175
09cde75e0613
templater: give slightly nicer error for unknown map entries
Matt Mackall <mpm@selenic.com>
parents:
13020
diff
changeset
|
417 except KeyError, inst: |
09cde75e0613
templater: give slightly nicer error for unknown map entries
Matt Mackall <mpm@selenic.com>
parents:
13020
diff
changeset
|
418 raise util.Abort(_('"%s" not in template map') % inst.args[0]) |
1905
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
419 except IOError, inst: |
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
420 raise IOError(inst.args[0], _('template file %s: %s') % |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
421 (self.map[t][1], inst.args[1])) |
6783
6d824dc86907
templater: make a template a string-only iterator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6434
diff
changeset
|
422 return self.cache[t] |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
423 |
10847 | 424 def __call__(self, t, **mapping): |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
425 ttype = t in self.map and self.map[t][0] or 'default' |
13187
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
426 if ttype not in self.ecache: |
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
427 self.ecache[ttype] = engines[ttype](self.load, |
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
428 self.filters, self.defaults) |
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
429 proc = self.ecache[ttype] |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
430 |
10847 | 431 stream = proc.process(t, mapping) |
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
432 if self.minchunk: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
433 stream = util.increasingchunks(stream, min=self.minchunk, |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
434 max=self.maxchunk) |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
435 return stream |
7434
cf7741aa1e96
kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7396
diff
changeset
|
436 |
1899
888d298ddb91
many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1897
diff
changeset
|
437 def templatepath(name=None): |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
438 '''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
|
439 returns None if not found.''' |
7107
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
440 normpaths = [] |
2189
e3eba577a0ae
move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2001
diff
changeset
|
441 |
2001
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
442 # executable version (py2exe) doesn't support __file__ |
14941
4a28cb4df1f8
windows: check util.mainfrozen() instead of ad-hoc checks everywhere
Augie Fackler <durin42@gmail.com>
parents:
14925
diff
changeset
|
443 if util.mainfrozen(): |
2001
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
444 module = sys.executable |
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
445 else: |
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
446 module = __file__ |
7107
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
447 for f in path: |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
448 if f.startswith('/'): |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
449 p = f |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
450 else: |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
451 fl = f.split('/') |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
452 p = os.path.join(os.path.dirname(module), *fl) |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
453 if name: |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
454 p = os.path.join(p, name) |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
455 if name and os.path.exists(p): |
1897
58b6784cf9f1
move hgweb.templatepath into templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1896
diff
changeset
|
456 return os.path.normpath(p) |
7107
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
457 elif os.path.isdir(p): |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
458 normpaths.append(os.path.normpath(p)) |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
459 |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
460 return normpaths |
2189
e3eba577a0ae
move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2001
diff
changeset
|
461 |
9842
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
462 def stylemap(styles, paths=None): |
7966
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
463 """Return path to mapfile for a given style. |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
464 |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
465 Searches mapfile in the following locations: |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
466 1. templatepath/style/map |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
467 2. templatepath/map-style |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
468 3. templatepath/map |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
469 """ |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
470 |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
471 if paths is None: |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
472 paths = templatepath() |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
473 elif isinstance(paths, str): |
8223
02145b700fe4
templater: fix little problem from stylemap() changes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8218
diff
changeset
|
474 paths = [paths] |
7966
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
475 |
9842
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
476 if isinstance(styles, str): |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
477 styles = [styles] |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
478 |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
479 for style in styles: |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
480 if not style: |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
481 continue |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
482 locations = [os.path.join(style, 'map'), 'map-' + style] |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
483 locations.append('map') |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
484 |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
485 for path in paths: |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
486 for location in locations: |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
487 mapfile = os.path.join(path, location) |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
488 if os.path.isfile(mapfile): |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
489 return style, mapfile |
7966
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
490 |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
491 raise RuntimeError("No hgweb templates found in %r" % paths) |