Mercurial > hg
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 |
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 | 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('&', '&') |
434139080ed4
Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents:
6134
diff
changeset
|
137 .replace('<', '<') |
434139080ed4
Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents:
6134
diff
changeset
|
138 .replace('>', '>') |
434139080ed4
Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents:
6134
diff
changeset
|
139 .replace('"', '"') |
434139080ed4
Permit XML entities to be escaped in template output.
Jesse Glick <jesse.glick@sun.com>
parents:
6134
diff
changeset
|
140 .replace("'", ''')) # ' 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 } |