annotate mercurial/templatefilters.py @ 13955:86b5cc1e8be8 stable

help config: explain that config files do not exist by default Inspired by critique given on StackOverflow where a user writes: I can have a good guess at what "%USERPROFILE%" might signify but none of the files listed in the "hg help config" output exist after running the installer. Previous experience would suggest that missing files mean something somewhere has gone seriously wrong. http://stackoverflow.com/questions/2329023/2351139#2351139
author Martin Geisler <mg@lazybytes.net>
date Mon, 18 Apr 2011 13:57:22 +0200
parents 48a4acd1ccf1
children 57150dc5a9c7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # template-filters.py - common template expansion filters
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8158
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: 9722
diff changeset
6 # GNU General Public License version 2 or any later version.
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
8 import cgi, re, os, time, urllib
12371
48a4acd1ccf1 templater: add hex filter.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11891
diff changeset
9 import encoding, node, util
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
10
8360
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
11 def stringify(thing):
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
12 '''turn nested template iterator into string.'''
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
13 if hasattr(thing, '__iter__') and not isinstance(thing, str):
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
14 return "".join([stringify(t) for t in thing if t is not None])
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
15 return str(thing)
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
16
10601
b98b6a7363ae templatefilters: store the agescales in reverseorder directly
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
17 agescales = [("year", 3600 * 24 * 365),
b98b6a7363ae templatefilters: store the agescales in reverseorder directly
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
18 ("month", 3600 * 24 * 30),
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
19 ("week", 3600 * 24 * 7),
10601
b98b6a7363ae templatefilters: store the agescales in reverseorder directly
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
20 ("day", 3600 * 24),
b98b6a7363ae templatefilters: store the agescales in reverseorder directly
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
21 ("hour", 3600),
b98b6a7363ae templatefilters: store the agescales in reverseorder directly
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
22 ("minute", 60),
10787
5974123d0339 templatefilters: fix check-code warning
Matt Mackall <mpm@selenic.com>
parents: 10601
diff changeset
23 ("second", 1)]
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
24
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
25 def age(date):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
26 '''turn a (timestamp, tzoff) tuple into an age string.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
28 def plural(t, c):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
29 if c == 1:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
30 return t
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
31 return t + "s"
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
32 def fmt(t, c):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
33 return "%d %s" % (c, plural(t, c))
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
34
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
35 now = time.time()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
36 then = date[0]
7682
9c8bbae02e9c templater: fix age filter to state the obvious on future timestamps
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6691
diff changeset
37 if then > now:
9c8bbae02e9c templater: fix age filter to state the obvious on future timestamps
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6691
diff changeset
38 return 'in the future'
9c8bbae02e9c templater: fix age filter to state the obvious on future timestamps
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6691
diff changeset
39
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
40 delta = max(1, int(now - then))
9722
4d9dea174b84 templater: readable dates older than 24 months revert to ISO8601 (issue1006)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9721
diff changeset
41 if delta > agescales[0][1] * 2:
4d9dea174b84 templater: readable dates older than 24 months revert to ISO8601 (issue1006)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9721
diff changeset
42 return util.shortdate(date)
4d9dea174b84 templater: readable dates older than 24 months revert to ISO8601 (issue1006)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9721
diff changeset
43
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
44 for t, s in agescales:
9029
0001e49f1c11 compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents: 8697
diff changeset
45 n = delta // s
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
46 if n >= 2 or s == 1:
9721
1d75c683ada1 templater: put 'ago' inside the age template filter
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9387
diff changeset
47 return '%s ago' % fmt(t, n)
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
48
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
49 para_re = None
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
50 space_re = None
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
51
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
52 def fill(text, width):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 '''fill many paragraphs.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
54 global para_re, space_re
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
55 if para_re is None:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
56 para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
57 space_re = re.compile(r' +')
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
58
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
59 def findparas():
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
60 start = 0
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
61 while True:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
62 m = para_re.search(text, start)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
63 if not m:
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
64 uctext = unicode(text[start:], encoding.encoding)
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
65 w = len(uctext)
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
66 while 0 < w and uctext[w - 1].isspace():
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
67 w -= 1
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
68 yield (uctext[:w].encode(encoding.encoding),
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
69 uctext[w:].encode(encoding.encoding))
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
70 break
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71 yield text[start:m.start(0)], m.group(1)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72 start = m.end(1)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
74 return "".join([space_re.sub(' ', util.wrap(para, width=width)) + rest
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 for para, rest in findparas()])
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
76
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77 def firstline(text):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78 '''return the first line of text'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
79 try:
9136
31177742f54a for calls expecting bool args, pass bool instead of int
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9029
diff changeset
80 return text.splitlines(True)[0].rstrip('\r\n')
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
81 except IndexError:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
82 return ''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
84 def nl2br(text):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
85 '''replace raw newlines with xhtml line breaks.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
86 return text.replace('\n', '<br/>\n')
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
88 def obfuscate(text):
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7682
diff changeset
89 text = unicode(text, encoding.encoding, 'replace')
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 return ''.join(['&#%d;' % ord(c) for c in text])
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
91
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 def domain(author):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
93 '''get domain of author, or empty string if none.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
94 f = author.find('@')
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
95 if f == -1:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
96 return ''
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
97 author = author[f + 1:]
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
98 f = author.find('>')
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
99 if f >= 0:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
100 author = author[:f]
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
101 return author
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
102
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 def person(author):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
104 '''get name of author, or else username.'''
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
105 if not '@' in author:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
106 return author
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
107 f = author.find('<')
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
108 if f == -1:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
109 return util.shortuser(author)
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
110 return author[:f].rstrip()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
111
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
112 def indent(text, prefix):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
113 '''indent each non-empty line of text after first with prefix.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
114 lines = text.splitlines()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
115 num_lines = len(lines)
9387
20ed9909dbd9 templatefilters: indent: do not compute text.endswith('\n') in each iteration
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9136
diff changeset
116 endswithnewline = text[-1:] == '\n'
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117 def indenter():
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
118 for i in xrange(num_lines):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119 l = lines[i]
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
120 if i and l.strip():
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
121 yield prefix
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
122 yield l
9387
20ed9909dbd9 templatefilters: indent: do not compute text.endswith('\n') in each iteration
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9136
diff changeset
123 if i < num_lines - 1 or endswithnewline:
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
124 yield '\n'
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
125 return "".join(indenter())
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
126
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
127 def permissions(flags):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
128 if "l" in flags:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
129 return "lrwxrwxrwx"
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
130 if "x" in flags:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
131 return "-rwxr-xr-x"
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
132 return "-rw-r--r--"
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
133
6174
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
134 def xmlescape(text):
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
135 text = (text
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
136 .replace('&', '&amp;')
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
137 .replace('<', '&lt;')
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
138 .replace('>', '&gt;')
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
139 .replace('"', '&quot;')
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
140 .replace("'", '&#39;')) # &apos; invalid in HTML
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
141 return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
142
11891
0bedf3a2062a templatefilters: unnest uescape()
Patrick Mezard <pmezard@gmail.com>
parents: 11890
diff changeset
143 def uescape(c):
0bedf3a2062a templatefilters: unnest uescape()
Patrick Mezard <pmezard@gmail.com>
parents: 11890
diff changeset
144 if ord(c) < 0x80:
0bedf3a2062a templatefilters: unnest uescape()
Patrick Mezard <pmezard@gmail.com>
parents: 11890
diff changeset
145 return c
0bedf3a2062a templatefilters: unnest uescape()
Patrick Mezard <pmezard@gmail.com>
parents: 11890
diff changeset
146 else:
0bedf3a2062a templatefilters: unnest uescape()
Patrick Mezard <pmezard@gmail.com>
parents: 11890
diff changeset
147 return '\\u%04x' % ord(c)
0bedf3a2062a templatefilters: unnest uescape()
Patrick Mezard <pmezard@gmail.com>
parents: 11890
diff changeset
148
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
149 _escapes = [
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
150 ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
151 ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
152 ]
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
153
8014
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
154 def jsonescape(s):
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
155 for k, v in _escapes:
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
156 s = s.replace(k, v)
11890
9dac951d0185 templatefilters: use \uxxxx style escape for JSON string
Yuya Nishihara <yuya@tcha.org>
parents: 11765
diff changeset
157 return ''.join(uescape(c) for c in s)
8014
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
158
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
159 def json(obj):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
160 if obj is None or obj is False or obj is True:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
161 return {None: 'null', False: 'false', True: 'true'}[obj]
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
162 elif isinstance(obj, int) or isinstance(obj, float):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
163 return str(obj)
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
164 elif isinstance(obj, str):
11765
aff419e260f9 templatefilters: make json filter handle multibyte characters correctly
Yuya Nishihara <yuya@tcha.org>
parents: 11297
diff changeset
165 u = unicode(obj, encoding.encoding, 'replace')
11890
9dac951d0185 templatefilters: use \uxxxx style escape for JSON string
Yuya Nishihara <yuya@tcha.org>
parents: 11765
diff changeset
166 return '"%s"' % jsonescape(u)
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
167 elif isinstance(obj, unicode):
11890
9dac951d0185 templatefilters: use \uxxxx style escape for JSON string
Yuya Nishihara <yuya@tcha.org>
parents: 11765
diff changeset
168 return '"%s"' % jsonescape(obj)
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
169 elif hasattr(obj, 'keys'):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
170 out = []
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
171 for k, v in obj.iteritems():
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
172 s = '%s: %s' % (json(k), json(v))
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
173 out.append(s)
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
174 return '{' + ', '.join(out) + '}'
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
175 elif hasattr(obj, '__iter__'):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
176 out = []
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
177 for i in obj:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
178 out.append(json(i))
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
179 return '[' + ', '.join(out) + ']'
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
180 else:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
181 raise TypeError('cannot encode type %s' % obj.__class__.__name__)
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
182
8158
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
183 def stripdir(text):
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
184 '''Treat the text as path and strip a directory level, if possible.'''
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
185 dir = os.path.dirname(text)
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
186 if dir == "":
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
187 return os.path.basename(text)
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
188 else:
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
189 return dir
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
190
8234
27dbe534397b templatefilters: add "nonempty" template filter
Rocco Rutte <pdmef@gmx.net>
parents: 8225
diff changeset
191 def nonempty(str):
8389
4b798b100c32 indentation cleanup
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8360
diff changeset
192 return str or "(none)"
8234
27dbe534397b templatefilters: add "nonempty" template filter
Rocco Rutte <pdmef@gmx.net>
parents: 8225
diff changeset
193
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
194 filters = {
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
195 "addbreaks": nl2br,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
196 "basename": os.path.basename,
8158
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
197 "stripdir": stripdir,
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
198 "age": age,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
199 "date": lambda x: util.datestr(x),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
200 "domain": domain,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
201 "email": util.email,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
202 "escape": lambda x: cgi.escape(x, True),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
203 "fill68": lambda x: fill(x, width=68),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
204 "fill76": lambda x: fill(x, width=76),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
205 "firstline": firstline,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
206 "tabindent": lambda x: indent(x, '\t'),
6229
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6174
diff changeset
207 "hgdate": lambda x: "%d %d" % x,
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6174
diff changeset
208 "isodate": lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2'),
6319
8999d1249171 Add an {isodatesec} template, to show seconds too.
Giorgos Keramidas <keramida@ceid.upatras.gr>
parents: 6229
diff changeset
209 "isodatesec": lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2'),
8014
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
210 "json": json,
6a77ba181bc6 templatefilters: split out jsonescape() function
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7948
diff changeset
211 "jsonescape": jsonescape,
8591
08c93b07f5ad templatefilters: add filter to convert date to local date (issue1674)
Henrik Stuart <hg@hstuart.dk>
parents: 8390
diff changeset
212 "localdate": lambda x: (x[0], util.makedate()[1]),
8234
27dbe534397b templatefilters: add "nonempty" template filter
Rocco Rutte <pdmef@gmx.net>
parents: 8225
diff changeset
213 "nonempty": nonempty,
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
214 "obfuscate": obfuscate,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215 "permissions": permissions,
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
216 "person": person,
6229
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6174
diff changeset
217 "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2"),
c3182eeb70ea dates: improve timezone handling
Matt Mackall <mpm@selenic.com>
parents: 6174
diff changeset
218 "rfc3339date": lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2"),
12371
48a4acd1ccf1 templater: add hex filter.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11891
diff changeset
219 "hex": node.hex,
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
220 "short": lambda x: x[:12],
6134
7b937b26adf7 Make annotae/grep print short dates with -q/--quiet.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5976
diff changeset
221 "shortdate": util.shortdate,
8360
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
222 "stringify": stringify,
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
223 "strip": lambda x: x.strip(),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
224 "urlescape": lambda x: urllib.quote(x),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
225 "user": lambda x: util.shortuser(x),
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
226 "stringescape": lambda x: x.encode('string_escape'),
6174
434139080ed4 Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents: 6134
diff changeset
227 "xmlescape": xmlescape,
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
228 }