comparison mercurial/templatefilters.py @ 13588:b8b881f3f3a7

templatefilters: sort function definitions
author Patrick Mezard <pmezard@gmail.com>
date Sat, 12 Mar 2011 12:46:31 +0100
parents 9fb6850d5d97
children b0a4b05c25e2
comparison
equal deleted inserted replaced
13587:9fb6850d5d97 13588:b8b881f3f3a7
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 import cgi, re, os, time, urllib 8 import cgi, re, os, time, urllib
9 import encoding, node, util 9 import encoding, node, util
10 10
11 def stringify(thing): 11 def addbreaks(text):
12 '''turn nested template iterator into string.''' 12 '''replace raw newlines with xhtml line breaks.'''
13 if hasattr(thing, '__iter__') and not isinstance(thing, str): 13 return text.replace('\n', '<br/>\n')
14 return "".join([stringify(t) for t in thing if t is not None])
15 return str(thing)
16 14
17 agescales = [("year", 3600 * 24 * 365), 15 agescales = [("year", 3600 * 24 * 365),
18 ("month", 3600 * 24 * 30), 16 ("month", 3600 * 24 * 30),
19 ("week", 3600 * 24 * 7), 17 ("week", 3600 * 24 * 7),
20 ("day", 3600 * 24), 18 ("day", 3600 * 24),
43 41
44 for t, s in agescales: 42 for t, s in agescales:
45 n = delta // s 43 n = delta // s
46 if n >= 2 or s == 1: 44 if n >= 2 or s == 1:
47 return '%s ago' % fmt(t, n) 45 return '%s ago' % fmt(t, n)
46
47 def domain(author):
48 '''get domain of author, or empty string if none.'''
49 f = author.find('@')
50 if f == -1:
51 return ''
52 author = author[f + 1:]
53 f = author.find('>')
54 if f >= 0:
55 author = author[:f]
56 return author
48 57
49 para_re = None 58 para_re = None
50 space_re = None 59 space_re = None
51 60
52 def fill(text, width): 61 def fill(text, width):
79 try: 88 try:
80 return text.splitlines(True)[0].rstrip('\r\n') 89 return text.splitlines(True)[0].rstrip('\r\n')
81 except IndexError: 90 except IndexError:
82 return '' 91 return ''
83 92
84 def addbreaks(text):
85 '''replace raw newlines with xhtml line breaks.'''
86 return text.replace('\n', '<br/>\n')
87
88 def obfuscate(text):
89 text = unicode(text, encoding.encoding, 'replace')
90 return ''.join(['&#%d;' % ord(c) for c in text])
91
92 def domain(author):
93 '''get domain of author, or empty string if none.'''
94 f = author.find('@')
95 if f == -1:
96 return ''
97 author = author[f + 1:]
98 f = author.find('>')
99 if f >= 0:
100 author = author[:f]
101 return author
102
103 def person(author):
104 '''get name of author, or else username.'''
105 if not '@' in author:
106 return author
107 f = author.find('<')
108 if f == -1:
109 return util.shortuser(author)
110 return author[:f].rstrip()
111
112 def indent(text, prefix): 93 def indent(text, prefix):
113 '''indent each non-empty line of text after first with prefix.''' 94 '''indent each non-empty line of text after first with prefix.'''
114 lines = text.splitlines() 95 lines = text.splitlines()
115 num_lines = len(lines) 96 num_lines = len(lines)
116 endswithnewline = text[-1:] == '\n' 97 endswithnewline = text[-1:] == '\n'
121 yield prefix 102 yield prefix
122 yield l 103 yield l
123 if i < num_lines - 1 or endswithnewline: 104 if i < num_lines - 1 or endswithnewline:
124 yield '\n' 105 yield '\n'
125 return "".join(indenter()) 106 return "".join(indenter())
126
127 def permissions(flags):
128 if "l" in flags:
129 return "lrwxrwxrwx"
130 if "x" in flags:
131 return "-rwxr-xr-x"
132 return "-rw-r--r--"
133
134 def xmlescape(text):
135 text = (text
136 .replace('&', '&amp;')
137 .replace('<', '&lt;')
138 .replace('>', '&gt;')
139 .replace('"', '&quot;')
140 .replace("'", '&#39;')) # &apos; invalid in HTML
141 return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
142
143 def uescape(c):
144 if ord(c) < 0x80:
145 return c
146 else:
147 return '\\u%04x' % ord(c)
148
149 _escapes = [
150 ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
151 ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
152 ]
153
154 def jsonescape(s):
155 for k, v in _escapes:
156 s = s.replace(k, v)
157 return ''.join(uescape(c) for c in s)
158 107
159 def json(obj): 108 def json(obj):
160 if obj is None or obj is False or obj is True: 109 if obj is None or obj is False or obj is True:
161 return {None: 'null', False: 'false', True: 'true'}[obj] 110 return {None: 'null', False: 'false', True: 'true'}[obj]
162 elif isinstance(obj, int) or isinstance(obj, float): 111 elif isinstance(obj, int) or isinstance(obj, float):
178 out.append(json(i)) 127 out.append(json(i))
179 return '[' + ', '.join(out) + ']' 128 return '[' + ', '.join(out) + ']'
180 else: 129 else:
181 raise TypeError('cannot encode type %s' % obj.__class__.__name__) 130 raise TypeError('cannot encode type %s' % obj.__class__.__name__)
182 131
132 def uescape(c):
133 if ord(c) < 0x80:
134 return c
135 else:
136 return '\\u%04x' % ord(c)
137
138 _escapes = [
139 ('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'),
140 ('\r', '\\r'), ('\f', '\\f'), ('\b', '\\b'),
141 ]
142
143 def jsonescape(s):
144 for k, v in _escapes:
145 s = s.replace(k, v)
146 return ''.join(uescape(c) for c in s)
147
148 def nonempty(str):
149 return str or "(none)"
150
151 def obfuscate(text):
152 text = unicode(text, encoding.encoding, 'replace')
153 return ''.join(['&#%d;' % ord(c) for c in text])
154
155 def permissions(flags):
156 if "l" in flags:
157 return "lrwxrwxrwx"
158 if "x" in flags:
159 return "-rwxr-xr-x"
160 return "-rw-r--r--"
161
162 def person(author):
163 '''get name of author, or else username.'''
164 if not '@' in author:
165 return author
166 f = author.find('<')
167 if f == -1:
168 return util.shortuser(author)
169 return author[:f].rstrip()
170
171 def stringify(thing):
172 '''turn nested template iterator into string.'''
173 if hasattr(thing, '__iter__') and not isinstance(thing, str):
174 return "".join([stringify(t) for t in thing if t is not None])
175 return str(thing)
176
183 def stripdir(text): 177 def stripdir(text):
184 '''Treat the text as path and strip a directory level, if possible.''' 178 '''Treat the text as path and strip a directory level, if possible.'''
185 dir = os.path.dirname(text) 179 dir = os.path.dirname(text)
186 if dir == "": 180 if dir == "":
187 return os.path.basename(text) 181 return os.path.basename(text)
188 else: 182 else:
189 return dir 183 return dir
190 184
191 def nonempty(str): 185 def xmlescape(text):
192 return str or "(none)" 186 text = (text
187 .replace('&', '&amp;')
188 .replace('<', '&lt;')
189 .replace('>', '&gt;')
190 .replace('"', '&quot;')
191 .replace("'", '&#39;')) # &apos; invalid in HTML
192 return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
193 193
194 filters = { 194 filters = {
195 "addbreaks": addbreaks, 195 "addbreaks": addbreaks,
196 "age": age, 196 "age": age,
197 "basename": os.path.basename, 197 "basename": os.path.basename,