##// END OF EJS Templates
add doc comments to template code.
Vadim Gelfer -
r1909:37b9f80a default
parent child Browse files
Show More
@@ -338,15 +338,20 b' def trimuser(ui, name, rev, revcache):'
338 338 return user
339 339
340 340 class changeset_templater(object):
341 '''use templater module to format changeset information.'''
342
341 343 def __init__(self, ui, repo, mapfile):
342 344 self.t = templater.templater(mapfile, templater.common_filters)
343 345 self.ui = ui
344 346 self.repo = repo
345 347
346 348 def use_template(self, t):
349 '''set template string to use'''
347 350 self.t.cache['template'] = t
348 351
349 352 def write(self, thing):
353 '''write expanded template.
354 uses in-order recursive traverse of iterators.'''
350 355 for t in thing:
351 356 if hasattr(t, '__iter__'):
352 357 self.write(t)
@@ -354,7 +359,7 b' class changeset_templater(object):'
354 359 self.ui.write(t)
355 360
356 361 def show(self, rev=0, changenode=None, brinfo=None):
357 """show a single changeset or file revision"""
362 '''show a single changeset or file revision'''
358 363 log = self.repo.changelog
359 364 if changenode is None:
360 365 changenode = log.node(rev)
@@ -364,6 +369,25 b' class changeset_templater(object):'
364 369 changes = log.read(changenode)
365 370
366 371 def showlist(name, values, plural=None, **args):
372 '''expand set of values.
373 name is name of key in template map.
374 values is list of strings or dicts.
375 plural is plural of name, if not simply name + 's'.
376
377 expansion works like this, given name 'foo'.
378
379 if values is empty, expand 'no_foos'.
380
381 if 'foo' not in template map, return values as a string,
382 joined by space.
383
384 expand 'start_foos'.
385
386 for each value, expand 'foo'. if 'last_foo' in template
387 map, expand it instead of 'foo' for last key.
388
389 expand 'end_foos'.
390 '''
367 391 if plural: names = plural
368 392 else: names = name + 's'
369 393 if not values:
@@ -371,13 +395,13 b' class changeset_templater(object):'
371 395 if noname in self.t:
372 396 yield self.t(noname, **args)
373 397 return
374 vargs = args.copy()
375 398 if name not in self.t:
376 399 yield ' '.join(values)
377 400 return
378 401 startname = 'start_' + names
379 402 if startname in self.t:
380 403 yield self.t(startname, **args)
404 vargs = args.copy()
381 405 def one(v, tag=name):
382 406 try:
383 407 vargs.update(v)
@@ -464,12 +488,14 b' class changeset_templater(object):'
464 488 raise util.Abort(_('%s: %s') % (self.t.mapfile, inst.args[0]))
465 489
466 490 class changeset_printer(object):
491 '''show changeset information when templating not requested.'''
492
467 493 def __init__(self, ui, repo):
468 494 self.ui = ui
469 495 self.repo = repo
470 496
471 497 def show(self, rev=0, changenode=None, brinfo=None):
472 """show a single changeset or file revision"""
498 '''show a single changeset or file revision'''
473 499 log = self.repo.changelog
474 500 if changenode is None:
475 501 changenode = log.node(rev)
@@ -530,6 +556,9 b' class changeset_printer(object):'
530 556 self.ui.status("\n")
531 557
532 558 def show_changeset(ui, repo, opts):
559 '''show one changeset. uses template or regular display. caller
560 can pass in 'map_file' and 'template' options in opts.'''
561
533 562 tmpl = opts.get('template')
534 563 if tmpl:
535 564 tmpl = templater.parsestring(tmpl, quoted=False)
@@ -1,3 +1,10 b''
1 # templater.py - template expansion for output
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 #
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
7
1 8 import re
2 9 from demandload import demandload
3 10 from i18n import gettext as _
@@ -12,6 +19,8 b' esctable = {'
12 19 }
13 20
14 21 def parsestring(s, quoted=True):
22 '''parse a string using simple c-like syntax.
23 string must be in quotes if quoted is True.'''
15 24 fp = cStringIO.StringIO()
16 25 if quoted:
17 26 first = s[0]
@@ -31,7 +40,30 b' def parsestring(s, quoted=True):'
31 40 return fp.getvalue()
32 41
33 42 class templater(object):
43 '''template expansion engine.
44
45 template expansion works like this. a map file contains key=value
46 pairs. if value is quoted, it is treated as string. otherwise, it
47 is treated as name of template file.
48
49 templater is asked to expand a key in map. it looks up key, and
50 looks for atrings like this: {foo}. it expands {foo} by looking up
51 foo in map, and substituting it. expansion is recursive: it stops
52 when there is no more {foo} to replace.
53
54 expansion also allows formatting and filtering.
55
56 format uses key to expand each item in list. syntax is
57 {key%format}.
58
59 filter uses function to transform value. syntax is
60 {key|filter1|filter2|...}.'''
61
34 62 def __init__(self, mapfile, filters={}, defaults={}):
63 '''set up template engine.
64 mapfile is name of file to read map definitions from.
65 filters is dict of functions. each transforms a value into another.
66 defaults is dict of default map definitions.'''
35 67 self.mapfile = mapfile or 'template'
36 68 self.cache = {}
37 69 self.map = {}
@@ -64,6 +96,9 b' class templater(object):'
64 96 return key in self.cache
65 97
66 98 def __call__(self, t, **map):
99 '''perform expansion.
100 t is name of map element to expand.
101 map is added elements to use during expansion.'''
67 102 m = self.defaults.copy()
68 103 m.update(map)
69 104 try:
@@ -127,7 +162,9 b' agescales = [("second", 1),'
127 162
128 163 agescales.reverse()
129 164
130 def age(x):
165 def age(date):
166 '''turn a (timestamp, tzoff) tuple into an age string.'''
167
131 168 def plural(t, c):
132 169 if c == 1:
133 170 return t
@@ -136,7 +173,7 b' def age(x):'
136 173 return "%d %s" % (c, plural(t, c))
137 174
138 175 now = time.time()
139 then = x[0]
176 then = date[0]
140 177 delta = max(1, int(now - then))
141 178
142 179 for t, s in agescales:
@@ -145,15 +182,18 b' def age(x):'
145 182 return fmt(t, n)
146 183
147 184 def isodate(date):
185 '''turn a (timestamp, tzoff) tuple into an iso 8631 date.'''
148 186 return util.datestr(date, format='%Y-%m-%d %H:%M')
149 187
150 188 def nl2br(text):
189 '''replace raw newlines with xhtml line breaks.'''
151 190 return text.replace('\n', '<br/>\n')
152 191
153 192 def obfuscate(text):
154 193 return ''.join(['&#%d;' % ord(c) for c in text])
155 194
156 195 def domain(author):
196 '''get domain of author, or empty string if none.'''
157 197 f = author.find('@')
158 198 if f == -1: return ''
159 199 author = author[f+1:]
@@ -162,6 +202,7 b' def domain(author):'
162 202 return author
163 203
164 204 def person(author):
205 '''get name of author, or else username.'''
165 206 f = author.find('<')
166 207 if f == -1: return util.shortuser(author)
167 208 return author[:f].rstrip()
@@ -185,6 +226,8 b' common_filters = {'
185 226 }
186 227
187 228 def templatepath(name=None):
229 '''return location of template file or directory (if no name).
230 returns None if not found.'''
188 231 for f in 'templates', '../templates':
189 232 fl = f.split('/')
190 233 if name: fl.append(name)
General Comments 0
You need to be logged in to leave comments. Login now