Mercurial > public > mercurial-scm > hg
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('&', '&') | |
137 .replace('<', '<') | |
138 .replace('>', '>') | |
139 .replace('"', '"') | |
140 .replace("'", ''')) # ' 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('&', '&') | |
188 .replace('<', '<') | |
189 .replace('>', '>') | |
190 .replace('"', '"') | |
191 .replace("'", ''')) # ' 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, |