Mercurial > hg
annotate mercurial/templater.py @ 13955:86b5cc1e8be8 stable
help config: explain that config files do not exist by default
Inspired by critique given on StackOverflow where a user writes:
I can have a good guess at what "%USERPROFILE%" might signify but
none of the files listed in the "hg help config" output exist after
running the installer. Previous experience would suggest that
missing files mean something somewhere has gone seriously wrong.
http://stackoverflow.com/questions/2329023/2351139#2351139
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Mon, 18 Apr 2011 13:57:22 +0200 |
parents | e3b87fb34d00 |
children | e798e430c5e5 |
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 _ |
10843
b91c1804008e
templater: directly parse templates, no regexes
Matt Mackall <mpm@selenic.com>
parents:
10339
diff
changeset
|
9 import sys, os |
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 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
11 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
12 # template parsing |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
13 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
14 elements = { |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
15 "(": (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
|
16 ",": (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
|
17 "|": (5, None, ("|", 5)), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
18 "%": (6, None, ("%", 6)), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
19 ")": (0, None, None), |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
20 "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
|
21 "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
|
22 "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
|
23 } |
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 def tokenizer(data): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
26 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
|
27 pos = start |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
28 while pos < end: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
29 c = program[pos] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
30 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
|
31 pass |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
32 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
|
33 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
|
34 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
|
35 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
|
36 if c == 'r': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
37 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
38 c = program[pos] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
39 decode = lambda x: x |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
40 else: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
41 decode = lambda x: x.decode('string-escape') |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
42 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
43 s = pos |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
44 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
|
45 d = program[pos] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
46 if d == '\\': # skip over escaped characters |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
47 pos += 2 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
48 continue |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
49 if d == c: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
50 yield ('string', decode(program[s:pos]), s) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
51 break |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
52 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
53 else: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
54 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
|
55 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
|
56 s = pos |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
57 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
58 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
|
59 d = program[pos] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
60 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
|
61 break |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
62 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
63 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
|
64 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
|
65 pos -= 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
66 elif c == '}': |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
67 pos += 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
68 break |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
69 else: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
70 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
|
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 data[2] = pos |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
73 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
|
74 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
75 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
|
76 parsed = [] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
77 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
|
78 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
|
79 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
80 while pos < stop: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
81 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
|
82 if n < 0: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
83 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
|
84 break |
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 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
|
86 # escaped |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
87 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
|
88 pos = n + 1 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
89 continue |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
90 if n > pos: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
91 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
|
92 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
93 pd = [tmpl, n + 1, stop] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
94 parsed.append(p.parse(pd)) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
95 pos = pd[2] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
96 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
97 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
|
98 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
99 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
|
100 t = exp[0] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
101 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
|
102 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
|
103 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
|
104 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
105 # template evaluation |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
106 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
107 def getsymbol(exp): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
108 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
|
109 return exp[1] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
110 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
|
111 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
112 def getlist(x): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
113 if not x: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
114 return [] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
115 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
|
116 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
|
117 return [x] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
118 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
119 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
|
120 f = getsymbol(exp) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
121 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
|
122 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
|
123 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
|
124 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
125 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
|
126 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
|
127 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
|
128 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
|
129 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
|
130 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
|
131 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
132 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
|
133 return data |
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 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
|
136 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
|
137 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
|
138 v = context._defaults.get(key, '') |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
139 if hasattr(v, '__call__'): |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
140 return v(**mapping) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
141 return v |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
142 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
143 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
|
144 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
|
145 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
|
146 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
|
147 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
148 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
|
149 func, data, filt = data |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
150 return filt(func(context, mapping, data)) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
151 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
152 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
|
153 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
|
154 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
|
155 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
|
156 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
157 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
|
158 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
|
159 d = func(context, mapping, data) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
160 lm = mapping.copy() |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
161 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
162 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
|
163 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
|
164 lm.update(i) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
165 for f, d in ctmpl: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
166 yield f(context, lm, d) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
167 else: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
168 # 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
|
169 # 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
|
170 # 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
|
171 yield i |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
172 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
173 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
|
174 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
|
175 args = [compileexp(x, context) for x in getlist(exp[2])] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
176 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
|
177 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
|
178 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
|
179 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
|
180 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
|
181 elif n in context._funcs: |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
182 f = context._funcs[n] |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
183 return (f, args) |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
184 |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
185 methods = { |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
186 "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
|
187 "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
|
188 "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
|
189 # ".": buildmember, |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
190 "|": buildfilter, |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
191 "%": buildmap, |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
192 "func": buildfunc, |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
193 } |
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 # template engine |
1901
c64bef3d7043
use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1900
diff
changeset
|
196 |
7107
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
197 path = ['templates', '../templates'] |
8360
acc202b71619
templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8312
diff
changeset
|
198 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
|
199 |
10850
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
200 def _flatten(thing): |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
201 '''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
|
202 if isinstance(thing, str): |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
203 yield thing |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
204 elif not hasattr(thing, '__iter__'): |
11305
d4cafcb63f77
cleanups: undefined variables
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10855
diff
changeset
|
205 if thing is not None: |
10852
0d50586a9d31
templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents:
10850
diff
changeset
|
206 yield str(thing) |
0d50586a9d31
templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents:
10850
diff
changeset
|
207 else: |
10850
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
208 for i in thing: |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
209 if isinstance(i, str): |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
210 yield i |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
211 elif not hasattr(i, '__iter__'): |
10852
0d50586a9d31
templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents:
10850
diff
changeset
|
212 if i is not None: |
0d50586a9d31
templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents:
10850
diff
changeset
|
213 yield str(i) |
10850
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
214 elif i is not None: |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
215 for j in _flatten(i): |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
216 yield j |
a63391e26284
templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents:
10849
diff
changeset
|
217 |
1902
1cc5f25653a3
make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1901
diff
changeset
|
218 def parsestring(s, quoted=True): |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
219 '''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
|
220 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
|
221 if quoted: |
3639
5c9a36210662
templater: simplify parsestring
Matt Mackall <mpm@selenic.com>
parents:
3638
diff
changeset
|
222 if len(s) < 2 or s[0] != s[-1]: |
5c9a36210662
templater: simplify parsestring
Matt Mackall <mpm@selenic.com>
parents:
3638
diff
changeset
|
223 raise SyntaxError(_('unmatched quotes')) |
5c9a36210662
templater: simplify parsestring
Matt Mackall <mpm@selenic.com>
parents:
3638
diff
changeset
|
224 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
|
225 |
231393b7316f
templater: use str.decode in parse_string
Matt Mackall <mpm@selenic.com>
parents:
3462
diff
changeset
|
226 return s.decode('string_escape') |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
227 |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
228 class engine(object): |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
229 '''template expansion engine. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
230 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
231 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
|
232 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
|
233 is treated as name of template file. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
234 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
235 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
|
236 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
|
237 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
|
238 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
|
239 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
240 expansion also allows formatting and filtering. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
241 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
242 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
|
243 {key%format}. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
244 |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
245 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
|
246 {key|filter1|filter2|...}.''' |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
247 |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
248 def __init__(self, loader, filters={}, defaults={}): |
10848
01346cea5485
templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents:
10847
diff
changeset
|
249 self._loader = loader |
01346cea5485
templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents:
10847
diff
changeset
|
250 self._filters = filters |
01346cea5485
templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents:
10847
diff
changeset
|
251 self._defaults = defaults |
01346cea5485
templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents:
10847
diff
changeset
|
252 self._cache = {} |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
253 |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
254 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
|
255 '''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
|
256 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
|
257 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
|
258 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
|
259 |
10853
b6f6d9fd53d6
templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents:
10852
diff
changeset
|
260 def process(self, t, mapping): |
b6f6d9fd53d6
templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents:
10852
diff
changeset
|
261 '''Perform expansion. t is name of map element to expand. |
b6f6d9fd53d6
templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents:
10852
diff
changeset
|
262 mapping contains added elements for use during expansion. Is a |
b6f6d9fd53d6
templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents:
10852
diff
changeset
|
263 generator.''' |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
264 return _flatten(func(self, mapping, data) for func, data in |
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
13175
diff
changeset
|
265 self._load(t)) |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
266 |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
267 engines = {'default': engine} |
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
268 |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
269 class templater(object): |
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
270 |
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
271 def __init__(self, mapfile, filters={}, defaults={}, cache={}, |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
272 minchunk=1024, maxchunk=65536): |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
273 '''set up template engine. |
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
274 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
|
275 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
|
276 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
|
277 self.mapfile = mapfile or 'template' |
1975
6e1a8ea5d717
Duplicate cache when creating templater.
Shun-ichi Goto <shunichi.goto@gmail.com>
parents:
1964
diff
changeset
|
278 self.cache = cache.copy() |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
279 self.map = {} |
1905
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
280 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
|
281 self.filters = templatefilters.filters.copy() |
acc202b71619
templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8312
diff
changeset
|
282 self.filters.update(filters) |
1964
778281d46bb2
fix template bug that made hgweb break.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1955
diff
changeset
|
283 self.defaults = defaults |
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
284 self.minchunk, self.maxchunk = minchunk, maxchunk |
13187
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
285 self.ecache = {} |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
286 |
1905
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
287 if not mapfile: |
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
288 return |
6337
d2713d902524
give better error message on non-existent mapfile (issue813)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5976
diff
changeset
|
289 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
|
290 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
|
291 |
8194
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
292 conf = config.config() |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
293 conf.read(mapfile) |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
294 |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
295 for key, val in conf[''].items(): |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
296 if val[0] in "'\"": |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
297 try: |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
298 self.cache[key] = parsestring(val) |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
299 except SyntaxError, inst: |
63c47e4ac617
templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents:
8015
diff
changeset
|
300 raise SyntaxError('%s: %s' % |
8198
cf9accffd0b3
config: getsource -> source
Matt Mackall <mpm@selenic.com>
parents:
8194
diff
changeset
|
301 (conf.source('', key), inst.args[0])) |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
302 else: |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
303 val = 'default', val |
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
304 if ':' in val[1]: |
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
305 val = val[1].split(':', 1) |
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
306 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
|
307 |
1899
888d298ddb91
many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1897
diff
changeset
|
308 def __contains__(self, key): |
3637
e7639888bb2f
templater: simplify cache and remove filter argument in __call__
Matt Mackall <mpm@selenic.com>
parents:
3636
diff
changeset
|
309 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
|
310 |
8218
e61cb2813d2a
templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8198
diff
changeset
|
311 def load(self, t): |
6783
6d824dc86907
templater: make a template a string-only iterator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
6434
diff
changeset
|
312 '''Get the template for the given template name. Use a local cache.''' |
5915
d0576d065993
Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents:
5269
diff
changeset
|
313 if not t in self.cache: |
1905
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
314 try: |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
315 self.cache[t] = open(self.map[t][1]).read() |
13175
09cde75e0613
templater: give slightly nicer error for unknown map entries
Matt Mackall <mpm@selenic.com>
parents:
13020
diff
changeset
|
316 except KeyError, inst: |
09cde75e0613
templater: give slightly nicer error for unknown map entries
Matt Mackall <mpm@selenic.com>
parents:
13020
diff
changeset
|
317 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
|
318 except IOError, inst: |
0c760737b996
improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1904
diff
changeset
|
319 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
|
320 (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
|
321 return self.cache[t] |
1896
f8f818a04f5b
move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff
changeset
|
322 |
10847 | 323 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
|
324 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
|
325 if ttype not in self.ecache: |
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
326 self.ecache[ttype] = engines[ttype](self.load, |
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
327 self.filters, self.defaults) |
e3b87fb34d00
templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents:
13176
diff
changeset
|
328 proc = self.ecache[ttype] |
8361
d8c5a7f25a40
templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8360
diff
changeset
|
329 |
10847 | 330 stream = proc.process(t, mapping) |
7396
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
331 if self.minchunk: |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
332 stream = util.increasingchunks(stream, min=self.minchunk, |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
333 max=self.maxchunk) |
526c40a74bd0
templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents:
7107
diff
changeset
|
334 return stream |
7434
cf7741aa1e96
kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7396
diff
changeset
|
335 |
1899
888d298ddb91
many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1897
diff
changeset
|
336 def templatepath(name=None): |
1909
37b9f80a5fbb
add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1906
diff
changeset
|
337 '''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
|
338 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
|
339 normpaths = [] |
2189
e3eba577a0ae
move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2001
diff
changeset
|
340 |
2001
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
341 # executable version (py2exe) doesn't support __file__ |
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
342 if hasattr(sys, 'frozen'): |
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
343 module = sys.executable |
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
344 else: |
a439b7b51530
Windows py2exe version didn't handle names given to templatepath() correctly
Lee Cantey <lcantey@gmail.com>
parents:
1987
diff
changeset
|
345 module = __file__ |
7107
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
346 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
|
347 if f.startswith('/'): |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
348 p = f |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
349 else: |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
350 fl = f.split('/') |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
351 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
|
352 if name: |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
353 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
|
354 if name and os.path.exists(p): |
1897
58b6784cf9f1
move hgweb.templatepath into templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1896
diff
changeset
|
355 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
|
356 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
|
357 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
|
358 |
125c8fedcbe0
Allow hgweb to search for templates in more than one path.
Brendan Cully <brendan@kublai.com>
parents:
6783
diff
changeset
|
359 return normpaths |
2189
e3eba577a0ae
move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
2001
diff
changeset
|
360 |
9842
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
361 def stylemap(styles, paths=None): |
7966
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
362 """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
|
363 |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
364 Searches mapfile in the following locations: |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
365 1. templatepath/style/map |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
366 2. templatepath/map-style |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
367 3. templatepath/map |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
368 """ |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
369 |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
370 if paths is None: |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
371 paths = templatepath() |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
372 elif isinstance(paths, str): |
8223
02145b700fe4
templater: fix little problem from stylemap() changes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
8218
diff
changeset
|
373 paths = [paths] |
7966
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
374 |
9842
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
375 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
|
376 styles = [styles] |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
377 |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
378 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
|
379 if not style: |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
380 continue |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
381 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
|
382 locations.append('map') |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
383 |
d3dbdca92458
hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9372
diff
changeset
|
384 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
|
385 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
|
386 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
|
387 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
|
388 return style, mapfile |
7966
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
389 |
aa983c3d94a9
templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
7434
diff
changeset
|
390 raise RuntimeError("No hgweb templates found in %r" % paths) |