annotate mercurial/templater.py @ 25562:9452112c8eb0 stable

templater: evaluate arguments passed to diff() appropriately Before this patch, diff() crashed by passing non-string expression because it didn't evaluate arguments at all.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 13 Jun 2015 20:14:22 +0900
parents 7298da81f5a9
children a69983942fb4 5eccebe23942
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9842
diff changeset
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
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
8 from i18n import _
22633
92b54547ac5d util: introduce datapath for getting the location of supporting data files
Mads Kiilerich <madski@unity3d.com>
parents: 22434
diff changeset
9 import os, re
20519
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
10 import util, config, templatefilters, templatekw, parser, error
22304
5678b0e3608f templater: enable alias predicates to be used in "revset()" function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21960
diff changeset
11 import revset as revsetmod
17982
e06e9fd2d99f template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents: 17890
diff changeset
12 import types
18747
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
13 import minirst
13176
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 # template parsing
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
16
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
17 elements = {
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
18 "(": (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
19 ",": (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
20 "|": (5, None, ("|", 5)),
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
21 "%": (6, None, ("%", 6)),
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
22 ")": (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 "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
24 "string": (0, ("string",), None),
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
25 "rawstring": (0, ("rawstring",), None),
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
26 "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
27 }
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
28
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
29 def tokenizer(data):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
30 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
31 pos = start
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
32 while pos < end:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
33 c = program[pos]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
34 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
35 pass
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
36 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
37 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
38 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
39 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
40 if c == 'r':
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
41 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
42 c = program[pos]
17634
6b307730c9f0 templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents: 17633
diff changeset
43 decode = False
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
44 else:
17634
6b307730c9f0 templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents: 17633
diff changeset
45 decode = True
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
46 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
47 s = pos
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
48 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
49 d = program[pos]
17634
6b307730c9f0 templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents: 17633
diff changeset
50 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
51 pos += 2
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
52 continue
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
53 if d == c:
17634
6b307730c9f0 templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents: 17633
diff changeset
54 if not decode:
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
55 yield ('rawstring', program[s:pos], s)
17634
6b307730c9f0 templater: correctly deal with r"" strings
Matt Mackall <mpm@selenic.com>
parents: 17633
diff changeset
56 break
20066
64b4f0cd7336 templater: fix escaping in nested string literals (issue4102)
Matt Mackall <mpm@selenic.com>
parents: 19770
diff changeset
57 yield ('string', program[s:pos], s)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
58 break
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
59 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
60 else:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
61 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
62 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
63 s = pos
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
64 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
65 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
66 d = program[pos]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
67 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
68 break
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 sym = program[s:pos]
18893
74ea61318ea8 templater: back out 0615b22da148, it breaks schemes ({1})
Brendan Cully <brendan@kublai.com>
parents: 18889
diff changeset
71 yield ('symbol', sym, s)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
72 pos -= 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
73 elif c == '}':
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
74 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
75 break
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
76 else:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
77 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
78 pos += 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
79 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
80
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
81 def compiletemplate(tmpl, context, strtoken="string"):
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
82 parsed = []
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
83 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
84 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
85 while pos < stop:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
86 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
87 if n < 0:
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
88 parsed.append((strtoken, tmpl[pos:]))
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
89 break
24949
890845af1ac2 templater: strictly parse leading backslashes of '{' (issue4569) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 24948
diff changeset
90 bs = (n - pos) - len(tmpl[pos:n].rstrip('\\'))
890845af1ac2 templater: strictly parse leading backslashes of '{' (issue4569) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 24948
diff changeset
91 if strtoken == 'string' and bs % 2 == 1:
890845af1ac2 templater: strictly parse leading backslashes of '{' (issue4569) (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 24948
diff changeset
92 # escaped (e.g. '\{', '\\\{', but not '\\{' nor r'\{')
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
93 parsed.append((strtoken, (tmpl[pos:n - 1] + "{")))
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
94 pos = n + 1
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
95 continue
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
96 if n > pos:
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
97 parsed.append((strtoken, tmpl[pos:n]))
13176
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 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
100 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
101 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
102
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
103 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
104
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
105 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
106 t = exp[0]
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
107 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
108 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
109 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
110
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
111 # template evaluation
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
112
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
113 def getsymbol(exp):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
114 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
115 return exp[1]
21822
028a48105191 templater: add symbol to error
Ryan McElroy <rmcelroy@fb.com>
parents: 21821
diff changeset
116 raise error.ParseError(_("expected a symbol, got '%s'") % exp[0])
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
117
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
118 def getlist(x):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
119 if not x:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
120 return []
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
121 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
122 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
123 return [x]
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 getfilter(exp, context):
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
126 f = getsymbol(exp)
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
127 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
128 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
129 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
130
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
131 def gettemplate(exp, context):
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
132 if exp[0] == 'string' or exp[0] == 'rawstring':
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
133 return compiletemplate(exp[1], context, strtoken=exp[0])
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
134 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
135 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
136 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
137
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
138 def runstring(context, mapping, data):
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
139 return data.decode("string-escape")
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
140
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
141 def runrawstring(context, mapping, data):
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
142 return data
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
143
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
144 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
145 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
146 if v is None:
19770
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
147 v = context._defaults.get(key)
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
148 if v is None:
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
149 try:
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
150 v = context.process(key, mapping)
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
151 except TemplateNotFound:
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
152 v = ''
21798
f2c617ff2abc templater: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21540
diff changeset
153 if callable(v):
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
154 return v(**mapping)
17982
e06e9fd2d99f template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents: 17890
diff changeset
155 if isinstance(v, types.GeneratorType):
e06e9fd2d99f template engine: convert generator-based iterator to list-based iterator
Weiwen <weiwen@fb.com>
parents: 17890
diff changeset
156 v = list(v)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
157 return v
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
158
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
159 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
160 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
161 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
162 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
163
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
164 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
165 func, data, filt = data
24280
6c55e37ba5f2 templater: allow piping generator-type function output to filters
Yuya Nishihara <yuya@tcha.org>
parents: 24240
diff changeset
166 # func() may return string, generator of strings or arbitrary object such
6c55e37ba5f2 templater: allow piping generator-type function output to filters
Yuya Nishihara <yuya@tcha.org>
parents: 24240
diff changeset
167 # as date tuple, but filter does not want generator.
6c55e37ba5f2 templater: allow piping generator-type function output to filters
Yuya Nishihara <yuya@tcha.org>
parents: 24240
diff changeset
168 thing = func(context, mapping, data)
6c55e37ba5f2 templater: allow piping generator-type function output to filters
Yuya Nishihara <yuya@tcha.org>
parents: 24240
diff changeset
169 if isinstance(thing, types.GeneratorType):
6c55e37ba5f2 templater: allow piping generator-type function output to filters
Yuya Nishihara <yuya@tcha.org>
parents: 24240
diff changeset
170 thing = stringify(thing)
17383
099c778ceb33 templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents: 17334
diff changeset
171 try:
24280
6c55e37ba5f2 templater: allow piping generator-type function output to filters
Yuya Nishihara <yuya@tcha.org>
parents: 24240
diff changeset
172 return filt(thing)
17383
099c778ceb33 templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents: 17334
diff changeset
173 except (ValueError, AttributeError, TypeError):
099c778ceb33 templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents: 17334
diff changeset
174 if isinstance(data, tuple):
099c778ceb33 templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents: 17334
diff changeset
175 dt = data[1]
099c778ceb33 templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents: 17334
diff changeset
176 else:
099c778ceb33 templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents: 17334
diff changeset
177 dt = data
099c778ceb33 templater: abort when a template filter raises an exception (issue2987)
Neil Kodner <neilk@fb.com>
parents: 17334
diff changeset
178 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
179 "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
180
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
181 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
182 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
183 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
184 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
185
17632
523625e46760 templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents: 17631
diff changeset
186 def runtemplate(context, mapping, template):
523625e46760 templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents: 17631
diff changeset
187 for func, data in template:
523625e46760 templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents: 17631
diff changeset
188 yield func(context, mapping, data)
523625e46760 templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents: 17631
diff changeset
189
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
190 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
191 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
192 d = func(context, mapping, data)
21798
f2c617ff2abc templater: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21540
diff changeset
193 if callable(d):
17631
0b241d7a8c62 templating: make new-style templating features work with command line lists
Matt Mackall <mpm@selenic.com>
parents: 17383
diff changeset
194 d = d()
0b241d7a8c62 templating: make new-style templating features work with command line lists
Matt Mackall <mpm@selenic.com>
parents: 17383
diff changeset
195
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
196 lm = mapping.copy()
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
197
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
198 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
199 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
200 lm.update(i)
17991
d605a82cf189 hgweb: display diff for a changeset against any parents (issue2810)
Weiwen <weiwen@fb.com>
parents: 17982
diff changeset
201 lm['originalnode'] = mapping.get('node')
17632
523625e46760 templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents: 17631
diff changeset
202 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
203 else:
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
204 # 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
205 # 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
206 # 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
207 yield i
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
208
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
209 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
210 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
211 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
212 if n in funcs:
ab545a15d807 templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents: 14168
diff changeset
213 f = funcs[n]
ab545a15d807 templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents: 14168
diff changeset
214 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
215 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
216 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
217 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
218 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
219 return (runfilter, (args[0][0], args[0][1], f))
20857
6eb55310fcbc templater: raise error for unknown func
Sean Farley <sean.michael.farley@gmail.com>
parents: 20663
diff changeset
220 raise error.ParseError(_("unknown function '%s'") % n)
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
221
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
222 def date(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
223 """:date(date[, fmt]): Format a date. See :hg:`help dates` for formatting
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
224 strings."""
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
225 if not (1 <= len(args) <= 2):
23112
3226ed457928 i18n: add i18n comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22844
diff changeset
226 # i18n: "date" is a keyword
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
227 raise error.ParseError(_("date expects one or two arguments"))
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
228
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
229 date = args[0][0](context, mapping, args[0][1])
24903
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
230 fmt = None
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
231 if len(args) == 2:
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
232 fmt = stringify(args[1][0](context, mapping, args[1][1]))
24903
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
233 try:
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
234 if fmt is None:
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
235 return util.datestr(date)
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
236 else:
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
237 return util.datestr(date, fmt)
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
238 except (TypeError, ValueError):
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
239 # i18n: "date" is a keyword
09124cce913f templater: fix crash by passing invalid object to date() function
Yuya Nishihara <yuya@tcha.org>
parents: 24886
diff changeset
240 raise error.ParseError(_("date expects a date information"))
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
241
22434
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
242 def diff(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
243 """:diff([includepattern [, excludepattern]]): Show a diff, optionally
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
244 specifying files to include or exclude."""
22434
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
245 if len(args) > 2:
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
246 # i18n: "diff" is a keyword
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
247 raise error.ParseError(_("diff expects one, two or no arguments"))
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
248
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
249 def getpatterns(i):
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
250 if i < len(args):
25562
9452112c8eb0 templater: evaluate arguments passed to diff() appropriately
Yuya Nishihara <yuya@tcha.org>
parents: 25471
diff changeset
251 s = stringify(args[i][0](context, mapping, args[i][1])).strip()
22434
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
252 if s:
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
253 return [s]
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
254 return []
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
255
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
256 ctx = mapping['ctx']
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
257 chunks = ctx.diff(match=ctx.match([], getpatterns(0), getpatterns(1)))
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
258
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
259 return ''.join(chunks)
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
260
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
261 def fill(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
262 """:fill(text[, width[, initialident[, hangindent]]]): Fill many
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
263 paragraphs with optional indentation. See the "fill" filter."""
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
264 if not (1 <= len(args) <= 4):
23112
3226ed457928 i18n: add i18n comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22844
diff changeset
265 # i18n: "fill" is a keyword
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
266 raise error.ParseError(_("fill expects one to four arguments"))
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
267
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
268 text = stringify(args[0][0](context, mapping, args[0][1]))
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
269 width = 76
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
270 initindent = ''
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
271 hangindent = ''
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
272 if 2 <= len(args) <= 4:
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
273 try:
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
274 width = int(stringify(args[1][0](context, mapping, args[1][1])))
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
275 except ValueError:
23112
3226ed457928 i18n: add i18n comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22844
diff changeset
276 # i18n: "fill" is a keyword
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
277 raise error.ParseError(_("fill expects an integer width"))
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
278 try:
20661
7e627fe63e5e templater: avoid recursive evaluation of string literals completely
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20312
diff changeset
279 initindent = stringify(_evalifliteral(args[2], context, mapping))
7e627fe63e5e templater: avoid recursive evaluation of string literals completely
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20312
diff changeset
280 hangindent = stringify(_evalifliteral(args[3], context, mapping))
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
281 except IndexError:
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
282 pass
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
283
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
284 return templatefilters.fill(text, width, initindent, hangindent)
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
285
20370
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
286 def pad(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
287 """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
288 fill character."""
20370
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
289 if not (2 <= len(args) <= 4):
23112
3226ed457928 i18n: add i18n comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22844
diff changeset
290 # i18n: "pad" is a keyword
20370
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
291 raise error.ParseError(_("pad() expects two to four arguments"))
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
292
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
293 width = int(args[1][1])
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
294
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
295 text = stringify(args[0][0](context, mapping, args[0][1]))
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
296 if args[0][0] == runstring:
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
297 text = stringify(runtemplate(context, mapping,
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
298 compiletemplate(text, context)))
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
299
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
300 right = False
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
301 fillchar = ' '
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
302 if len(args) > 2:
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
303 fillchar = stringify(args[2][0](context, mapping, args[2][1]))
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
304 if len(args) > 3:
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
305 right = util.parsebool(args[3][1])
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
306
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
307 if right:
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
308 return text.rjust(width, fillchar)
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
309 else:
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
310 return text.ljust(width, fillchar)
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
311
18582
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
312 def get(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
313 """:get(dict, key): Get an attribute/key from an object. Some keywords
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
314 are complex types. This function allows you to obtain the value of an
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
315 attribute on these type."""
18582
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
316 if len(args) != 2:
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
317 # i18n: "get" is a keyword
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
318 raise error.ParseError(_("get() expects two arguments"))
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
319
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
320 dictarg = args[0][0](context, mapping, args[0][1])
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
321 if not util.safehasattr(dictarg, 'get'):
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
322 # i18n: "get" is a keyword
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
323 raise error.ParseError(_("get() expects a dict as first argument"))
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
324
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
325 key = args[1][0](context, mapping, args[1][1])
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
326 yield dictarg.get(key)
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
327
20067
3d8bfe2ecf6d templater: only recursively evaluate string literals as templates (issue4103)
Matt Mackall <mpm@selenic.com>
parents: 20066
diff changeset
328 def _evalifliteral(arg, context, mapping):
25471
7298da81f5a9 templater: do not preprocess template string in "if" expression (issue4714)
Yuya Nishihara <yuya@tcha.org>
parents: 24949
diff changeset
329 # get back to token tag to reinterpret string as template
7298da81f5a9 templater: do not preprocess template string in "if" expression (issue4714)
Yuya Nishihara <yuya@tcha.org>
parents: 24949
diff changeset
330 strtoken = {runstring: 'string', runrawstring: 'rawstring'}.get(arg[0])
7298da81f5a9 templater: do not preprocess template string in "if" expression (issue4714)
Yuya Nishihara <yuya@tcha.org>
parents: 24949
diff changeset
331 if strtoken:
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
332 yield runtemplate(context, mapping,
25471
7298da81f5a9 templater: do not preprocess template string in "if" expression (issue4714)
Yuya Nishihara <yuya@tcha.org>
parents: 24949
diff changeset
333 compiletemplate(arg[1], context, strtoken))
20067
3d8bfe2ecf6d templater: only recursively evaluate string literals as templates (issue4103)
Matt Mackall <mpm@selenic.com>
parents: 20066
diff changeset
334 else:
25471
7298da81f5a9 templater: do not preprocess template string in "if" expression (issue4714)
Yuya Nishihara <yuya@tcha.org>
parents: 24949
diff changeset
335 yield stringify(arg[0](context, mapping, arg[1]))
20067
3d8bfe2ecf6d templater: only recursively evaluate string literals as templates (issue4103)
Matt Mackall <mpm@selenic.com>
parents: 20066
diff changeset
336
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
337 def if_(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
338 """:if(expr, then[, else]): Conditionally execute based on the result of
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
339 an expression."""
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
340 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
341 # i18n: "if" is a keyword
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
342 raise error.ParseError(_("if expects two or three arguments"))
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
343
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
344 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
345 if test:
20067
3d8bfe2ecf6d templater: only recursively evaluate string literals as templates (issue4103)
Matt Mackall <mpm@selenic.com>
parents: 20066
diff changeset
346 yield _evalifliteral(args[1], context, mapping)
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
347 elif len(args) == 3:
20067
3d8bfe2ecf6d templater: only recursively evaluate string literals as templates (issue4103)
Matt Mackall <mpm@selenic.com>
parents: 20066
diff changeset
348 yield _evalifliteral(args[2], context, mapping)
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
349
20518
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
350 def ifcontains(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
351 """:ifcontains(search, thing, then[, else]): Conditionally execute based
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
352 on whether the item "search" is in "thing"."""
20518
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
353 if not (3 <= len(args) <= 4):
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
354 # i18n: "ifcontains" is a keyword
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
355 raise error.ParseError(_("ifcontains expects three or four arguments"))
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
356
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
357 item = stringify(args[0][0](context, mapping, args[0][1]))
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
358 items = args[1][0](context, mapping, args[1][1])
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
359
24240
bd504d90588d templater: implement _hybrid.__contains__ so that ifcontains can accept dict
Yuya Nishihara <yuya@tcha.org>
parents: 24114
diff changeset
360 if item in items:
20518
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
361 yield _evalifliteral(args[2], context, mapping)
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
362 elif len(args) == 4:
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
363 yield _evalifliteral(args[3], context, mapping)
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
364
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
365 def ifeq(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
366 """:ifeq(expr1, expr2, then[, else]): Conditionally execute based on
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
367 whether 2 items are equivalent."""
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
368 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
369 # i18n: "ifeq" is a keyword
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
370 raise error.ParseError(_("ifeq expects three or four arguments"))
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
371
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
372 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
373 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
374 if test == match:
20067
3d8bfe2ecf6d templater: only recursively evaluate string literals as templates (issue4103)
Matt Mackall <mpm@selenic.com>
parents: 20066
diff changeset
375 yield _evalifliteral(args[2], context, mapping)
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
376 elif len(args) == 4:
20067
3d8bfe2ecf6d templater: only recursively evaluate string literals as templates (issue4103)
Matt Mackall <mpm@selenic.com>
parents: 20066
diff changeset
377 yield _evalifliteral(args[3], context, mapping)
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
378
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
379 def join(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
380 """:join(list, sep): Join items in a list with a delimiter."""
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
381 if not (1 <= len(args) <= 2):
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
382 # i18n: "join" is a keyword
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
383 raise error.ParseError(_("join expects one or two arguments"))
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
384
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
385 joinset = args[0][0](context, mapping, args[0][1])
21798
f2c617ff2abc templater: restore use of callable() since it was readded in Python 3.2
Augie Fackler <raf@durin42.com>
parents: 21540
diff changeset
386 if callable(joinset):
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
387 jf = joinset.joinfmt
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
388 joinset = [jf(x) for x in joinset()]
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
389
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
390 joiner = " "
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
391 if len(args) > 1:
20662
a54c0d830499 templater: apply "stringify()" on sub expression to get string correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20661
diff changeset
392 joiner = stringify(args[1][0](context, mapping, args[1][1]))
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
393
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
394 first = True
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
395 for x in joinset:
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
396 if first:
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
397 first = False
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
398 else:
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
399 yield joiner
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
400 yield x
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
401
18289
9bfb53106328 templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents: 17991
diff changeset
402 def label(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
403 """:label(label, expr): Apply a label to generated content. Content with
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
404 a label applied can result in additional post-processing, such as
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
405 automatic colorization."""
18289
9bfb53106328 templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents: 17991
diff changeset
406 if len(args) != 2:
9bfb53106328 templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents: 17991
diff changeset
407 # i18n: "label" is a keyword
9bfb53106328 templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents: 17991
diff changeset
408 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
409
9bfb53106328 templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents: 17991
diff changeset
410 # ignore args[0] (the label string) since this is supposed to be a a no-op
20067
3d8bfe2ecf6d templater: only recursively evaluate string literals as templates (issue4103)
Matt Mackall <mpm@selenic.com>
parents: 20066
diff changeset
411 yield _evalifliteral(args[1], context, mapping)
18289
9bfb53106328 templater: add no-op template function 'label'
Sean Farley <sean.michael.farley@gmail.com>
parents: 17991
diff changeset
412
20519
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
413 def revset(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
414 """:revset(query[, formatargs...]): Execute a revision set query. See
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
415 :hg:`help revset`."""
20519
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
416 if not len(args) > 0:
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
417 # i18n: "revset" is a keyword
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
418 raise error.ParseError(_("revset expects one or more arguments"))
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
419
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
420 raw = args[0][1]
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
421 ctx = mapping['ctx']
24337
696ab1a24ae0 templater: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24306
diff changeset
422 repo = ctx.repo()
20519
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
423
22304
5678b0e3608f templater: enable alias predicates to be used in "revset()" function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21960
diff changeset
424 def query(expr):
5678b0e3608f templater: enable alias predicates to be used in "revset()" function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21960
diff changeset
425 m = revsetmod.match(repo.ui, expr)
24114
fafd9a1284cf revset: make match function initiate query from full set by default
Yuya Nishihara <yuya@tcha.org>
parents: 23167
diff changeset
426 return m(repo)
22304
5678b0e3608f templater: enable alias predicates to be used in "revset()" function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21960
diff changeset
427
20519
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
428 if len(args) > 1:
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
429 formatargs = list([a[0](context, mapping, a[1]) for a in args[1:]])
22304
5678b0e3608f templater: enable alias predicates to be used in "revset()" function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21960
diff changeset
430 revs = query(revsetmod.formatspec(raw, *formatargs))
20519
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
431 revs = list([str(r) for r in revs])
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
432 else:
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
433 revsetcache = mapping['cache'].setdefault("revsetcache", {})
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
434 if raw in revsetcache:
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
435 revs = revsetcache[raw]
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
436 else:
22304
5678b0e3608f templater: enable alias predicates to be used in "revset()" function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21960
diff changeset
437 revs = query(raw)
20519
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
438 revs = list([str(r) for r in revs])
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
439 revsetcache[raw] = revs
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
440
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
441 return templatekw.showlist("revision", revs, **mapping)
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
442
18747
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
443 def rstdoc(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
444 """:rstdoc(text, style): Format ReStructuredText."""
18747
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
445 if len(args) != 2:
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
446 # i18n: "rstdoc" is a keyword
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
447 raise error.ParseError(_("rstdoc expects two arguments"))
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
448
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
449 text = stringify(args[0][0](context, mapping, args[0][1]))
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
450 style = stringify(args[1][0](context, mapping, args[1][1]))
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
451
19079
1e433b5457fd hgweb: make help verbose again (issue3899)
Alexander Plavin <me@aplavin.ru>
parents: 19058
diff changeset
452 return minirst.format(text, style=style, keep=['verbose'])
18747
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
453
20369
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
454 def shortest(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
455 """:shortest(node, minlength=4): Obtain the shortest representation of
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
456 a node."""
20369
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
457 if not (1 <= len(args) <= 2):
23112
3226ed457928 i18n: add i18n comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22844
diff changeset
458 # i18n: "shortest" is a keyword
20369
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
459 raise error.ParseError(_("shortest() expects one or two arguments"))
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
460
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
461 node = stringify(args[0][0](context, mapping, args[0][1]))
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
462
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
463 minlength = 4
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
464 if len(args) > 1:
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
465 minlength = int(args[1][1])
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
466
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
467 cl = mapping['ctx']._repo.changelog
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
468 def isvalid(test):
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
469 try:
20371
6f3fb6a974e0 template: fix shortest(node) function in pure mercurial
Durham Goode <durham@fb.com>
parents: 20370
diff changeset
470 try:
6f3fb6a974e0 template: fix shortest(node) function in pure mercurial
Durham Goode <durham@fb.com>
parents: 20370
diff changeset
471 cl.index.partialmatch(test)
6f3fb6a974e0 template: fix shortest(node) function in pure mercurial
Durham Goode <durham@fb.com>
parents: 20370
diff changeset
472 except AttributeError:
6f3fb6a974e0 template: fix shortest(node) function in pure mercurial
Durham Goode <durham@fb.com>
parents: 20370
diff changeset
473 # Pure mercurial doesn't support partialmatch on the index.
6f3fb6a974e0 template: fix shortest(node) function in pure mercurial
Durham Goode <durham@fb.com>
parents: 20370
diff changeset
474 # Fallback to the slow way.
6f3fb6a974e0 template: fix shortest(node) function in pure mercurial
Durham Goode <durham@fb.com>
parents: 20370
diff changeset
475 if cl._partialmatch(test) is None:
6f3fb6a974e0 template: fix shortest(node) function in pure mercurial
Durham Goode <durham@fb.com>
parents: 20370
diff changeset
476 return False
6f3fb6a974e0 template: fix shortest(node) function in pure mercurial
Durham Goode <durham@fb.com>
parents: 20370
diff changeset
477
20369
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
478 try:
20539
aa021ece4506 templater: shorten pure integers
Sean Farley <sean.michael.farley@gmail.com>
parents: 20519
diff changeset
479 i = int(test)
aa021ece4506 templater: shorten pure integers
Sean Farley <sean.michael.farley@gmail.com>
parents: 20519
diff changeset
480 # if we are a pure int, then starting with zero will not be
aa021ece4506 templater: shorten pure integers
Sean Farley <sean.michael.farley@gmail.com>
parents: 20519
diff changeset
481 # confused as a rev; or, obviously, if the int is larger than
aa021ece4506 templater: shorten pure integers
Sean Farley <sean.michael.farley@gmail.com>
parents: 20519
diff changeset
482 # the value of the tip rev
aa021ece4506 templater: shorten pure integers
Sean Farley <sean.michael.farley@gmail.com>
parents: 20519
diff changeset
483 if test[0] == '0' or i > len(cl):
aa021ece4506 templater: shorten pure integers
Sean Farley <sean.michael.farley@gmail.com>
parents: 20519
diff changeset
484 return True
20369
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
485 return False
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
486 except ValueError:
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
487 return True
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
488 except error.RevlogError:
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
489 return False
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
490
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
491 shortest = node
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
492 startlength = max(6, minlength)
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
493 length = startlength
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
494 while True:
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
495 test = node[:length]
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
496 if isvalid(test):
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
497 shortest = test
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
498 if length == minlength or length > startlength:
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
499 return shortest
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
500 length -= 1
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
501 else:
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
502 length += 1
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
503 if len(shortest) <= length:
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
504 return shortest
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
505
19330
867b9957d895 templater: add strip function with chars as an extra argument
Alexander Plavin <me@aplavin.ru>
parents: 19228
diff changeset
506 def strip(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
507 """:strip(text[, chars]): Strip characters from a string."""
19330
867b9957d895 templater: add strip function with chars as an extra argument
Alexander Plavin <me@aplavin.ru>
parents: 19228
diff changeset
508 if not (1 <= len(args) <= 2):
23112
3226ed457928 i18n: add i18n comment to error messages of template functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22844
diff changeset
509 # i18n: "strip" is a keyword
19330
867b9957d895 templater: add strip function with chars as an extra argument
Alexander Plavin <me@aplavin.ru>
parents: 19228
diff changeset
510 raise error.ParseError(_("strip expects one or two arguments"))
867b9957d895 templater: add strip function with chars as an extra argument
Alexander Plavin <me@aplavin.ru>
parents: 19228
diff changeset
511
20662
a54c0d830499 templater: apply "stringify()" on sub expression to get string correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20661
diff changeset
512 text = stringify(args[0][0](context, mapping, args[0][1]))
19330
867b9957d895 templater: add strip function with chars as an extra argument
Alexander Plavin <me@aplavin.ru>
parents: 19228
diff changeset
513 if len(args) == 2:
20662
a54c0d830499 templater: apply "stringify()" on sub expression to get string correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20661
diff changeset
514 chars = stringify(args[1][0](context, mapping, args[1][1]))
19330
867b9957d895 templater: add strip function with chars as an extra argument
Alexander Plavin <me@aplavin.ru>
parents: 19228
diff changeset
515 return text.strip(chars)
867b9957d895 templater: add strip function with chars as an extra argument
Alexander Plavin <me@aplavin.ru>
parents: 19228
diff changeset
516 return text.strip()
867b9957d895 templater: add strip function with chars as an extra argument
Alexander Plavin <me@aplavin.ru>
parents: 19228
diff changeset
517
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
518 def sub(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
519 """:sub(pattern, replacement, expression): Perform text substitution
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
520 using regular expressions."""
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
521 if len(args) != 3:
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
522 # i18n: "sub" is a keyword
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
523 raise error.ParseError(_("sub expects three arguments"))
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
524
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
525 pat = stringify(args[0][0](context, mapping, args[0][1]))
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
526 rpl = stringify(args[1][0](context, mapping, args[1][1]))
20661
7e627fe63e5e templater: avoid recursive evaluation of string literals completely
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20312
diff changeset
527 src = stringify(_evalifliteral(args[2], context, mapping))
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
528 yield re.sub(pat, rpl, src)
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
529
21821
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
530 def startswith(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
531 """:startswith(pattern, text): Returns the value from the "text" argument
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
532 if it begins with the content from the "pattern" argument."""
21821
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
533 if len(args) != 2:
21960
2896d450fec4 templater: add i18n comments to error messages of newly added functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21846
diff changeset
534 # i18n: "startswith" is a keyword
21821
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
535 raise error.ParseError(_("startswith expects two arguments"))
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
536
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
537 patn = stringify(args[0][0](context, mapping, args[0][1]))
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
538 text = stringify(args[1][0](context, mapping, args[1][1]))
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
539 if text.startswith(patn):
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
540 return text
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
541 return ''
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
542
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
543
21846
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
544 def word(context, mapping, args):
24586
90e3f5d22dad templater: add consistent docstrings to functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24337
diff changeset
545 """:word(number, text[, separator]): Return the nth word from a string."""
21846
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
546 if not (2 <= len(args) <= 3):
21960
2896d450fec4 templater: add i18n comments to error messages of newly added functions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21846
diff changeset
547 # i18n: "word" is a keyword
21846
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
548 raise error.ParseError(_("word expects two or three arguments, got %d")
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
549 % len(args))
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
550
24886
10a13da8840d templater: fail more gracefully for blank strings to word
Ryan McElroy <rmcelroy@fb.com>
parents: 24601
diff changeset
551 try:
10a13da8840d templater: fail more gracefully for blank strings to word
Ryan McElroy <rmcelroy@fb.com>
parents: 24601
diff changeset
552 num = int(stringify(args[0][0](context, mapping, args[0][1])))
10a13da8840d templater: fail more gracefully for blank strings to word
Ryan McElroy <rmcelroy@fb.com>
parents: 24601
diff changeset
553 except ValueError:
10a13da8840d templater: fail more gracefully for blank strings to word
Ryan McElroy <rmcelroy@fb.com>
parents: 24601
diff changeset
554 # i18n: "word" is a keyword
10a13da8840d templater: fail more gracefully for blank strings to word
Ryan McElroy <rmcelroy@fb.com>
parents: 24601
diff changeset
555 raise error.ParseError(
10a13da8840d templater: fail more gracefully for blank strings to word
Ryan McElroy <rmcelroy@fb.com>
parents: 24601
diff changeset
556 _("Use strings like '3' for numbers passed to word function"))
21846
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
557 text = stringify(args[1][0](context, mapping, args[1][1]))
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
558 if len(args) == 3:
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
559 splitter = stringify(args[2][0](context, mapping, args[2][1]))
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
560 else:
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
561 splitter = None
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
562
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
563 tokens = text.split(splitter)
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
564 if num >= len(tokens):
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
565 return ''
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
566 else:
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
567 return tokens[num]
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
568
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
569 methods = {
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
570 "string": lambda e, c: (runstring, e[1]),
20663
5ab28a2e9962 templater: make strings in template expressions be "string-escape"-ed correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20662
diff changeset
571 "rawstring": lambda e, c: (runrawstring, e[1]),
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
572 "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
573 "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
574 # ".": buildmember,
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
575 "|": buildfilter,
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
576 "%": buildmap,
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
577 "func": buildfunc,
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
578 }
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
579
14925
ab545a15d807 templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents: 14168
diff changeset
580 funcs = {
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
581 "date": date,
22434
40ce05b50148 templater: add "diff" template function
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 22304
diff changeset
582 "diff": diff,
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
583 "fill": fill,
18582
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
584 "get": get,
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
585 "if": if_,
20518
1e43f15a647f template: add ifcontains template function
Durham Goode <durham@fb.com>
parents: 20371
diff changeset
586 "ifcontains": ifcontains,
17636
ce18dbcd91c8 templater: add if/ifeq conditionals
Matt Mackall <mpm@selenic.com>
parents: 17635
diff changeset
587 "ifeq": ifeq,
17633
312184f930b7 template: add join function
Matt Mackall <mpm@selenic.com>
parents: 17632
diff changeset
588 "join": join,
18582
ef78450c8df6 templater: add get() function to access dict element (e.g. extra)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 18289
diff changeset
589 "label": label,
20370
aa51392da507 template: add pad function for padding output
Durham Goode <durham@fb.com>
parents: 20369
diff changeset
590 "pad": pad,
20519
cda9d2b6beab template: add revset() template function
Durham Goode <durham@fb.com>
parents: 20518
diff changeset
591 "revset": revset,
18747
f5db3092790f hgweb: generate HTML documentation
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 18582
diff changeset
592 "rstdoc": rstdoc,
20369
9c6b86dd2ed2 template: add shortest(node) template function
Durham Goode <durham@fb.com>
parents: 20312
diff changeset
593 "shortest": shortest,
21821
4a445dc5abff templater: introduce startswith function
Ryan McElroy <rmcelroy@fb.com>
parents: 21798
diff changeset
594 "startswith": startswith,
19390
3af3a165db18 templater: sort functions alphabetically, as filters are
Alexander Plavin <me@aplavin.ru>
parents: 19330
diff changeset
595 "strip": strip,
17635
8804e3cb51bd templater: add sub() function
Matt Mackall <mpm@selenic.com>
parents: 17634
diff changeset
596 "sub": sub,
21846
8f23f8096606 templater: introduce word function
Ryan McElroy <rmcelroy@fb.com>
parents: 21822
diff changeset
597 "word": word,
14925
ab545a15d807 templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents: 14168
diff changeset
598 }
ab545a15d807 templater: use a global funcs table
Matt Mackall <mpm@selenic.com>
parents: 14168
diff changeset
599
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
600 # template engine
1901
c64bef3d7043 use safer string parser for template engine.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1900
diff changeset
601
8360
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
602 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
603
10850
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
604 def _flatten(thing):
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
605 '''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
606 if isinstance(thing, str):
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
607 yield thing
14944
e2c413bde8a5 globally: use safehasattr(x, '__iter__') instead of hasattr(x, '__iter__')
Augie Fackler <durin42@gmail.com>
parents: 14943
diff changeset
608 elif not util.safehasattr(thing, '__iter__'):
11305
d4cafcb63f77 cleanups: undefined variables
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10855
diff changeset
609 if thing is not None:
10852
0d50586a9d31 templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents: 10850
diff changeset
610 yield str(thing)
0d50586a9d31 templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents: 10850
diff changeset
611 else:
10850
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
612 for i in thing:
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
613 if isinstance(i, str):
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
614 yield i
14944
e2c413bde8a5 globally: use safehasattr(x, '__iter__') instead of hasattr(x, '__iter__')
Augie Fackler <durin42@gmail.com>
parents: 14943
diff changeset
615 elif not util.safehasattr(i, '__iter__'):
10852
0d50586a9d31 templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents: 10850
diff changeset
616 if i is not None:
0d50586a9d31 templater: raise nested functions
Matt Mackall <mpm@selenic.com>
parents: 10850
diff changeset
617 yield str(i)
10850
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
618 elif i is not None:
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
619 for j in _flatten(i):
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
620 yield j
a63391e26284 templater: use recursive flattening
Matt Mackall <mpm@selenic.com>
parents: 10849
diff changeset
621
1902
1cc5f25653a3 make parsestring work with strings that do not have quotes.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1901
diff changeset
622 def parsestring(s, quoted=True):
24948
db7463aa080f templater: do not process \-escapes at parsestring() (issue4290)
Yuya Nishihara <yuya@tcha.org>
parents: 24903
diff changeset
623 '''unwrap 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
624 if quoted:
3639
5c9a36210662 templater: simplify parsestring
Matt Mackall <mpm@selenic.com>
parents: 3638
diff changeset
625 if len(s) < 2 or s[0] != s[-1]:
5c9a36210662 templater: simplify parsestring
Matt Mackall <mpm@selenic.com>
parents: 3638
diff changeset
626 raise SyntaxError(_('unmatched quotes'))
24948
db7463aa080f templater: do not process \-escapes at parsestring() (issue4290)
Yuya Nishihara <yuya@tcha.org>
parents: 24903
diff changeset
627 return s[1:-1]
3632
231393b7316f templater: use str.decode in parse_string
Matt Mackall <mpm@selenic.com>
parents: 3462
diff changeset
628
24948
db7463aa080f templater: do not process \-escapes at parsestring() (issue4290)
Yuya Nishihara <yuya@tcha.org>
parents: 24903
diff changeset
629 return s
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
630
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
631 class engine(object):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
632 '''template expansion engine.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
633
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
634 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
635 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
636 is treated as name of template file.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
637
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
638 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
639 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
640 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
641 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
642
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
643 expansion also allows formatting and filtering.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
644
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
645 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
646 {key%format}.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
647
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
648 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
649 {key|filter1|filter2|...}.'''
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
650
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
651 def __init__(self, loader, filters={}, defaults={}):
10848
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
652 self._loader = loader
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
653 self._filters = filters
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
654 self._defaults = defaults
01346cea5485 templater: privatize class variables
Matt Mackall <mpm@selenic.com>
parents: 10847
diff changeset
655 self._cache = {}
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
656
13176
895f54a79c6e templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents: 13175
diff changeset
657 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
658 '''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
659 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
660 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
661 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
662
10853
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
663 def process(self, t, mapping):
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
664 '''Perform expansion. t is name of map element to expand.
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
665 mapping contains added elements for use during expansion. Is a
b6f6d9fd53d6 templater: drop raw method
Matt Mackall <mpm@selenic.com>
parents: 10852
diff changeset
666 generator.'''
17632
523625e46760 templater: factor out runtemplate method
Matt Mackall <mpm@selenic.com>
parents: 17631
diff changeset
667 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
668
8361
d8c5a7f25a40 templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8360
diff changeset
669 engines = {'default': engine}
d8c5a7f25a40 templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8360
diff changeset
670
19125
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
671 def stylelist():
22634
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
672 paths = templatepaths()
20312
268a5ab5c27b templater: selecting a style with no templates does not crash (issue4140)
Simon Heimberg <simohe@besonet.ch>
parents: 20067
diff changeset
673 if not paths:
268a5ab5c27b templater: selecting a style with no templates does not crash (issue4140)
Simon Heimberg <simohe@besonet.ch>
parents: 20067
diff changeset
674 return _('no templates found, try `hg debuginstall` for more info')
268a5ab5c27b templater: selecting a style with no templates does not crash (issue4140)
Simon Heimberg <simohe@besonet.ch>
parents: 20067
diff changeset
675 dirlist = os.listdir(paths[0])
19125
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
676 stylelist = []
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
677 for file in dirlist:
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
678 split = file.split(".")
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
679 if split[0] == "map-cmdline":
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
680 stylelist.append(split[1])
19127
d982edcfe7f0 templater: fix output instability from gsoc patches
Augie Fackler <raf@durin42.com>
parents: 19125
diff changeset
681 return ", ".join(sorted(stylelist))
19125
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
682
19770
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
683 class TemplateNotFound(util.Abort):
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
684 pass
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
685
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
686 class templater(object):
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
687
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
688 def __init__(self, mapfile, filters={}, defaults={}, cache={},
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
689 minchunk=1024, maxchunk=65536):
1909
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
690 '''set up template engine.
37b9f80a5fbb add doc comments to template code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1906
diff changeset
691 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
692 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
693 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
694 self.mapfile = mapfile or 'template'
1975
6e1a8ea5d717 Duplicate cache when creating templater.
Shun-ichi Goto <shunichi.goto@gmail.com>
parents: 1964
diff changeset
695 self.cache = cache.copy()
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
696 self.map = {}
24306
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24303
diff changeset
697 if mapfile:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24303
diff changeset
698 self.base = os.path.dirname(mapfile)
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24303
diff changeset
699 else:
6ddc86eedc3b style: kill ersatz if-else ternary operators
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 24303
diff changeset
700 self.base = ''
8360
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
701 self.filters = templatefilters.filters.copy()
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8312
diff changeset
702 self.filters.update(filters)
1964
778281d46bb2 fix template bug that made hgweb break.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1955
diff changeset
703 self.defaults = defaults
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
704 self.minchunk, self.maxchunk = minchunk, maxchunk
13187
e3b87fb34d00 templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents: 13176
diff changeset
705 self.ecache = {}
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
706
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
707 if not mapfile:
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
708 return
6337
d2713d902524 give better error message on non-existent mapfile (issue813)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
709 if not os.path.exists(mapfile):
19125
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
710 raise util.Abort(_("style '%s' not found") % mapfile,
6ba6e345961e templater: show the style list when I try to use a wrong one
Iulian Stana <julian.stana@gmail.com>
parents: 19079
diff changeset
711 hint=_("available styles: %s") % stylelist())
6337
d2713d902524 give better error message on non-existent mapfile (issue813)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5976
diff changeset
712
8194
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
713 conf = config.config()
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
714 conf.read(mapfile)
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
715
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
716 for key, val in conf[''].items():
17334
39c01f8e7b39 templater: handle a missing value correctly
Ross Lagerwall <rosslagerwall@gmail.com>
parents: 16686
diff changeset
717 if not val:
39c01f8e7b39 templater: handle a missing value correctly
Ross Lagerwall <rosslagerwall@gmail.com>
parents: 16686
diff changeset
718 raise SyntaxError(_('%s: missing value') % conf.source('', key))
8194
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
719 if val[0] in "'\"":
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
720 try:
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
721 self.cache[key] = parsestring(val)
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
722 except SyntaxError, inst:
63c47e4ac617 templater: use new config parser
Matt Mackall <mpm@selenic.com>
parents: 8015
diff changeset
723 raise SyntaxError('%s: %s' %
8198
cf9accffd0b3 config: getsource -> source
Matt Mackall <mpm@selenic.com>
parents: 8194
diff changeset
724 (conf.source('', key), inst.args[0]))
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
725 else:
8361
d8c5a7f25a40 templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8360
diff changeset
726 val = 'default', val
d8c5a7f25a40 templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8360
diff changeset
727 if ':' in val[1]:
d8c5a7f25a40 templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8360
diff changeset
728 val = val[1].split(':', 1)
d8c5a7f25a40 templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8360
diff changeset
729 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
730
1899
888d298ddb91 many small changes to templater.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1897
diff changeset
731 def __contains__(self, key):
3637
e7639888bb2f templater: simplify cache and remove filter argument in __call__
Matt Mackall <mpm@selenic.com>
parents: 3636
diff changeset
732 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
733
8218
e61cb2813d2a templater: separate template management and actual string processing
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8198
diff changeset
734 def load(self, t):
6783
6d824dc86907 templater: make a template a string-only iterator
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6434
diff changeset
735 '''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
736 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
737 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
738 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
739 except KeyError, inst:
19770
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
740 raise TemplateNotFound(_('"%s" not in template map') %
0361163efbaf templater: support using templates with non-standard names from map file
Alexander Plavin <alexander@plav.in>
parents: 19390
diff changeset
741 inst.args[0])
1905
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
742 except IOError, inst:
0c760737b996 improve template errors when something is wrong.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1904
diff changeset
743 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
744 (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
745 return self.cache[t]
1896
f8f818a04f5b move hgweb template code out to templater
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
746
10847
90f4367535a5 templater: map -> mapping
Matt Mackall <mpm@selenic.com>
parents: 10846
diff changeset
747 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
748 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
749 if ttype not in self.ecache:
e3b87fb34d00 templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents: 13176
diff changeset
750 self.ecache[ttype] = engines[ttype](self.load,
e3b87fb34d00 templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents: 13176
diff changeset
751 self.filters, self.defaults)
e3b87fb34d00 templater: clarify engine caching
Matt Mackall <mpm@selenic.com>
parents: 13176
diff changeset
752 proc = self.ecache[ttype]
8361
d8c5a7f25a40 templater: make the templating engine pluggable to some extent
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8360
diff changeset
753
10847
90f4367535a5 templater: map -> mapping
Matt Mackall <mpm@selenic.com>
parents: 10846
diff changeset
754 stream = proc.process(t, mapping)
7396
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
755 if self.minchunk:
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
756 stream = util.increasingchunks(stream, min=self.minchunk,
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
757 max=self.maxchunk)
526c40a74bd0 templater: return data in increasing chunk sizes
Brendan Cully <brendan@kublai.com>
parents: 7107
diff changeset
758 return stream
7434
cf7741aa1e96 kill some trailing spaces
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7396
diff changeset
759
22634
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
760 def templatepaths():
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
761 '''return locations used for template files.'''
22636
d844e220792a templater: don't search randomly for templates - trust util.datapath
Mads Kiilerich <madski@unity3d.com>
parents: 22635
diff changeset
762 pathsrel = ['templates']
22635
660861a6fad4 templater: inline global 'path' list in templatepaths
Mads Kiilerich <madski@unity3d.com>
parents: 22634
diff changeset
763 paths = [os.path.normpath(os.path.join(util.datapath, f))
660861a6fad4 templater: inline global 'path' list in templatepaths
Mads Kiilerich <madski@unity3d.com>
parents: 22634
diff changeset
764 for f in pathsrel]
660861a6fad4 templater: inline global 'path' list in templatepaths
Mads Kiilerich <madski@unity3d.com>
parents: 22634
diff changeset
765 return [p for p in paths if os.path.isdir(p)]
2189
e3eba577a0ae move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2001
diff changeset
766
22634
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
767 def templatepath(name):
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
768 '''return location of template file. returns None if not found.'''
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
769 for p in templatepaths():
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
770 f = os.path.join(p, name)
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
771 if os.path.exists(f):
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
772 return f
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
773 return None
2189
e3eba577a0ae move changeset_templater into templater module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2001
diff changeset
774
9842
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
775 def stylemap(styles, paths=None):
7966
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
776 """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
777
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
778 Searches mapfile in the following locations:
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
779 1. templatepath/style/map
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
780 2. templatepath/map-style
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
781 3. templatepath/map
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
782 """
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
783
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
784 if paths is None:
22634
e48a5d3996c2 templater: introduce templatepaths for getting paths searched for templates
Mads Kiilerich <madski@unity3d.com>
parents: 22633
diff changeset
785 paths = templatepaths()
7966
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
786 elif isinstance(paths, str):
8223
02145b700fe4 templater: fix little problem from stylemap() changes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8218
diff changeset
787 paths = [paths]
7966
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
788
9842
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
789 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
790 styles = [styles]
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
791
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
792 for style in styles:
24296
b73a22d1d9bf hgweb: prevent loading style map from directories other than specified paths
Yuya Nishihara <yuya@tcha.org>
parents: 23167
diff changeset
793 # only plain name is allowed to honor template paths
b73a22d1d9bf hgweb: prevent loading style map from directories other than specified paths
Yuya Nishihara <yuya@tcha.org>
parents: 23167
diff changeset
794 if (not style
b73a22d1d9bf hgweb: prevent loading style map from directories other than specified paths
Yuya Nishihara <yuya@tcha.org>
parents: 23167
diff changeset
795 or style in (os.curdir, os.pardir)
b73a22d1d9bf hgweb: prevent loading style map from directories other than specified paths
Yuya Nishihara <yuya@tcha.org>
parents: 23167
diff changeset
796 or os.sep in style
b73a22d1d9bf hgweb: prevent loading style map from directories other than specified paths
Yuya Nishihara <yuya@tcha.org>
parents: 23167
diff changeset
797 or os.altsep and os.altsep in style):
9842
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
798 continue
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
799 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
800 locations.append('map')
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
801
d3dbdca92458 hgweb: don't choke when an inexistent style is requested (issue1901)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9372
diff changeset
802 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
803 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
804 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
805 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
806 return style, mapfile
7966
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
807
aa983c3d94a9 templater: move stylemap function from hgweb to templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7434
diff changeset
808 raise RuntimeError("No hgweb templates found in %r" % paths)
24601
d80819f67d59 templater: tell hggettext to collect help of template functions
Yuya Nishihara <yuya@tcha.org>
parents: 24586
diff changeset
809
d80819f67d59 templater: tell hggettext to collect help of template functions
Yuya Nishihara <yuya@tcha.org>
parents: 24586
diff changeset
810 # tell hggettext to extract docstrings from these functions:
d80819f67d59 templater: tell hggettext to collect help of template functions
Yuya Nishihara <yuya@tcha.org>
parents: 24586
diff changeset
811 i18nfunctions = funcs.values()