Mercurial > public > mercurial-scm > hg
comparison mercurial/templater.py @ 1987:04c17fc39c84
add changelog style to command line template.
to use, "hg log --style=changelog". makes different output with no
flags, -q, -v, --debug.
templater module has new template filters for this.
email - committer email address
fill68 - refill text to 68 colums
fill76 - refill text to 76 colums
tabindent - prefix every not empty line with tab
shortdate - iso 8631 date, no time zone
stringify - turn template iterator into string
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Tue, 21 Mar 2006 23:29:21 -0800 |
parents | 6e1a8ea5d717 |
children | a439b7b51530 |
comparison
equal
deleted
inserted
replaced
1985:c577689006fa | 1987:04c17fc39c84 |
---|---|
6 # of the GNU General Public License, incorporated herein by reference. | 6 # of the GNU General Public License, incorporated herein by reference. |
7 | 7 |
8 import re | 8 import re |
9 from demandload import demandload | 9 from demandload import demandload |
10 from i18n import gettext as _ | 10 from i18n import gettext as _ |
11 demandload(globals(), "cStringIO cgi sys os time urllib util") | 11 demandload(globals(), "cStringIO cgi re sys os time urllib util textwrap") |
12 | 12 |
13 esctable = { | 13 esctable = { |
14 '\\': '\\', | 14 '\\': '\\', |
15 'r': '\r', | 15 'r': '\r', |
16 't': '\t', | 16 't': '\t', |
179 for t, s in agescales: | 179 for t, s in agescales: |
180 n = delta / s | 180 n = delta / s |
181 if n >= 2 or s == 1: | 181 if n >= 2 or s == 1: |
182 return fmt(t, n) | 182 return fmt(t, n) |
183 | 183 |
184 def stringify(thing): | |
185 '''turn nested template iterator into string.''' | |
186 cs = cStringIO.StringIO() | |
187 def walk(things): | |
188 for t in things: | |
189 if hasattr(t, '__iter__'): | |
190 walk(t) | |
191 else: | |
192 cs.write(t) | |
193 walk(thing) | |
194 return cs.getvalue() | |
195 | |
196 para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M) | |
197 space_re = re.compile(r' +') | |
198 | |
199 def fill(text, width): | |
200 '''fill many paragraphs.''' | |
201 def findparas(): | |
202 start = 0 | |
203 while True: | |
204 m = para_re.search(text, start) | |
205 if not m: | |
206 w = len(text) | |
207 while w > start and text[w-1].isspace(): w -= 1 | |
208 yield text[start:w], text[w:] | |
209 break | |
210 yield text[start:m.start(0)], m.group(1) | |
211 start = m.end(1) | |
212 | |
213 fp = cStringIO.StringIO() | |
214 for para, rest in findparas(): | |
215 fp.write(space_re.sub(' ', textwrap.fill(para, width))) | |
216 fp.write(rest) | |
217 return fp.getvalue() | |
218 | |
184 def isodate(date): | 219 def isodate(date): |
185 '''turn a (timestamp, tzoff) tuple into an iso 8631 date.''' | 220 '''turn a (timestamp, tzoff) tuple into an iso 8631 date and time.''' |
186 return util.datestr(date, format='%Y-%m-%d %H:%M') | 221 return util.datestr(date, format='%Y-%m-%d %H:%M') |
187 | 222 |
188 def nl2br(text): | 223 def nl2br(text): |
189 '''replace raw newlines with xhtml line breaks.''' | 224 '''replace raw newlines with xhtml line breaks.''' |
190 return text.replace('\n', '<br/>\n') | 225 return text.replace('\n', '<br/>\n') |
199 author = author[f+1:] | 234 author = author[f+1:] |
200 f = author.find('>') | 235 f = author.find('>') |
201 if f >= 0: author = author[:f] | 236 if f >= 0: author = author[:f] |
202 return author | 237 return author |
203 | 238 |
239 def email(author): | |
240 '''get email of author.''' | |
241 r = author.find('>') | |
242 if r == -1: r = None | |
243 return author[author.find('<')+1:r] | |
244 | |
204 def person(author): | 245 def person(author): |
205 '''get name of author, or else username.''' | 246 '''get name of author, or else username.''' |
206 f = author.find('<') | 247 f = author.find('<') |
207 if f == -1: return util.shortuser(author) | 248 if f == -1: return util.shortuser(author) |
208 return author[:f].rstrip() | 249 return author[:f].rstrip() |
209 | 250 |
251 def shortdate(date): | |
252 '''turn (timestamp, tzoff) tuple into iso 8631 date.''' | |
253 return util.datestr(date, format='%Y-%m-%d', timezone=False) | |
254 | |
255 def indent(text, prefix): | |
256 '''indent each non-empty line of text after first with prefix.''' | |
257 fp = cStringIO.StringIO() | |
258 lines = text.splitlines() | |
259 num_lines = len(lines) | |
260 for i in xrange(num_lines): | |
261 l = lines[i] | |
262 if i and l.strip(): fp.write(prefix) | |
263 fp.write(l) | |
264 if i < num_lines - 1 or text.endswith('\n'): | |
265 fp.write('\n') | |
266 return fp.getvalue() | |
267 | |
210 common_filters = { | 268 common_filters = { |
211 "addbreaks": nl2br, | 269 "addbreaks": nl2br, |
212 "age": age, | 270 "age": age, |
213 "date": lambda x: util.datestr(x), | 271 "date": lambda x: util.datestr(x), |
214 "domain": domain, | 272 "domain": domain, |
273 "email": email, | |
215 "escape": lambda x: cgi.escape(x, True), | 274 "escape": lambda x: cgi.escape(x, True), |
275 "fill68": lambda x: fill(x, width=68), | |
276 "fill76": lambda x: fill(x, width=76), | |
216 "firstline": lambda x: x.splitlines(1)[0].rstrip('\r\n'), | 277 "firstline": lambda x: x.splitlines(1)[0].rstrip('\r\n'), |
278 "tabindent": lambda x: indent(x, '\t'), | |
217 "isodate": isodate, | 279 "isodate": isodate, |
218 "obfuscate": obfuscate, | 280 "obfuscate": obfuscate, |
219 "permissions": lambda x: x and "-rwxr-xr-x" or "-rw-r--r--", | 281 "permissions": lambda x: x and "-rwxr-xr-x" or "-rw-r--r--", |
220 "person": person, | 282 "person": person, |
221 "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"), | 283 "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"), |
222 "short": lambda x: x[:12], | 284 "short": lambda x: x[:12], |
285 "shortdate": shortdate, | |
286 "stringify": stringify, | |
223 "strip": lambda x: x.strip(), | 287 "strip": lambda x: x.strip(), |
224 "urlescape": lambda x: urllib.quote(x), | 288 "urlescape": lambda x: urllib.quote(x), |
225 "user": lambda x: util.shortuser(x), | 289 "user": lambda x: util.shortuser(x), |
226 } | 290 } |
227 | 291 |