comparison mercurial/templater.py @ 2189:e3eba577a0ae

move changeset_templater into templater module.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Wed, 03 May 2006 10:25:28 -0700
parents a439b7b51530
children c2e43535d4d1
comparison
equal deleted inserted replaced
2188:62ae3d140185 2189:e3eba577a0ae
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 from node import *
11 demandload(globals(), "cStringIO cgi re sys os time urllib util textwrap") 12 demandload(globals(), "cStringIO cgi re sys os time urllib util textwrap")
12 13
13 esctable = { 14 esctable = {
14 '\\': '\\', 15 '\\': '\\',
15 'r': '\r', 16 'r': '\r',
207 while w > start and text[w-1].isspace(): w -= 1 208 while w > start and text[w-1].isspace(): w -= 1
208 yield text[start:w], text[w:] 209 yield text[start:w], text[w:]
209 break 210 break
210 yield text[start:m.start(0)], m.group(1) 211 yield text[start:m.start(0)], m.group(1)
211 start = m.end(1) 212 start = m.end(1)
212 213
213 fp = cStringIO.StringIO() 214 fp = cStringIO.StringIO()
214 for para, rest in findparas(): 215 for para, rest in findparas():
215 fp.write(space_re.sub(' ', textwrap.fill(para, width))) 216 fp.write(space_re.sub(' ', textwrap.fill(para, width)))
216 fp.write(rest) 217 fp.write(rest)
217 return fp.getvalue() 218 return fp.getvalue()
239 def email(author): 240 def email(author):
240 '''get email of author.''' 241 '''get email of author.'''
241 r = author.find('>') 242 r = author.find('>')
242 if r == -1: r = None 243 if r == -1: r = None
243 return author[author.find('<')+1:r] 244 return author[author.find('<')+1:r]
244 245
245 def person(author): 246 def person(author):
246 '''get name of author, or else username.''' 247 '''get name of author, or else username.'''
247 f = author.find('<') 248 f = author.find('<')
248 if f == -1: return util.shortuser(author) 249 if f == -1: return util.shortuser(author)
249 return author[:f].rstrip() 250 return author[:f].rstrip()
290 } 291 }
291 292
292 def templatepath(name=None): 293 def templatepath(name=None):
293 '''return location of template file or directory (if no name). 294 '''return location of template file or directory (if no name).
294 returns None if not found.''' 295 returns None if not found.'''
296
295 # executable version (py2exe) doesn't support __file__ 297 # executable version (py2exe) doesn't support __file__
296 if hasattr(sys, 'frozen'): 298 if hasattr(sys, 'frozen'):
297 module = sys.executable 299 module = sys.executable
298 else: 300 else:
299 module = __file__ 301 module = __file__
301 fl = f.split('/') 303 fl = f.split('/')
302 if name: fl.append(name) 304 if name: fl.append(name)
303 p = os.path.join(os.path.dirname(module), *fl) 305 p = os.path.join(os.path.dirname(module), *fl)
304 if (name and os.path.exists(p)) or os.path.isdir(p): 306 if (name and os.path.exists(p)) or os.path.isdir(p):
305 return os.path.normpath(p) 307 return os.path.normpath(p)
308
309 class changeset_templater(object):
310 '''format changeset information.'''
311
312 def __init__(self, ui, repo, mapfile, dest=None):
313 self.t = templater(mapfile, common_filters,
314 cache={'parent': '{rev}:{node|short} ',
315 'manifest': '{rev}:{node|short}'})
316 self.ui = ui
317 self.dest = dest
318 self.repo = repo
319
320 def use_template(self, t):
321 '''set template string to use'''
322 self.t.cache['changeset'] = t
323
324 def write(self, thing, header=False):
325 '''write expanded template.
326 uses in-order recursive traverse of iterators.'''
327 dest = self.dest or self.ui
328 for t in thing:
329 if hasattr(t, '__iter__'):
330 self.write(t, header=header)
331 elif header:
332 dest.write_header(t)
333 else:
334 dest.write(t)
335
336 def write_header(self, thing):
337 self.write(thing, header=True)
338
339 def show(self, rev=0, changenode=None, brinfo=None):
340 '''show a single changeset or file revision'''
341 log = self.repo.changelog
342 if changenode is None:
343 changenode = log.node(rev)
344 elif not rev:
345 rev = log.rev(changenode)
346
347 changes = log.read(changenode)
348
349 def showlist(name, values, plural=None, **args):
350 '''expand set of values.
351 name is name of key in template map.
352 values is list of strings or dicts.
353 plural is plural of name, if not simply name + 's'.
354
355 expansion works like this, given name 'foo'.
356
357 if values is empty, expand 'no_foos'.
358
359 if 'foo' not in template map, return values as a string,
360 joined by space.
361
362 expand 'start_foos'.
363
364 for each value, expand 'foo'. if 'last_foo' in template
365 map, expand it instead of 'foo' for last key.
366
367 expand 'end_foos'.
368 '''
369 if plural: names = plural
370 else: names = name + 's'
371 if not values:
372 noname = 'no_' + names
373 if noname in self.t:
374 yield self.t(noname, **args)
375 return
376 if name not in self.t:
377 if isinstance(values[0], str):
378 yield ' '.join(values)
379 else:
380 for v in values:
381 yield dict(v, **args)
382 return
383 startname = 'start_' + names
384 if startname in self.t:
385 yield self.t(startname, **args)
386 vargs = args.copy()
387 def one(v, tag=name):
388 try:
389 vargs.update(v)
390 except (AttributeError, ValueError):
391 try:
392 for a, b in v:
393 vargs[a] = b
394 except ValueError:
395 vargs[name] = v
396 return self.t(tag, **vargs)
397 lastname = 'last_' + name
398 if lastname in self.t:
399 last = values.pop()
400 else:
401 last = None
402 for v in values:
403 yield one(v)
404 if last is not None:
405 yield one(last, tag=lastname)
406 endname = 'end_' + names
407 if endname in self.t:
408 yield self.t(endname, **args)
409
410 if brinfo:
411 def showbranches(**args):
412 if changenode in brinfo:
413 for x in showlist('branch', brinfo[changenode],
414 plural='branches', **args):
415 yield x
416 else:
417 showbranches = ''
418
419 if self.ui.debugflag:
420 def showmanifest(**args):
421 args = args.copy()
422 args.update(dict(rev=self.repo.manifest.rev(changes[0]),
423 node=hex(changes[0])))
424 yield self.t('manifest', **args)
425 else:
426 showmanifest = ''
427
428 def showparents(**args):
429 parents = [[('rev', log.rev(p)), ('node', hex(p))]
430 for p in log.parents(changenode)
431 if self.ui.debugflag or p != nullid]
432 if (not self.ui.debugflag and len(parents) == 1 and
433 parents[0][0][1] == rev - 1):
434 return
435 for x in showlist('parent', parents, **args):
436 yield x
437
438 def showtags(**args):
439 for x in showlist('tag', self.repo.nodetags(changenode), **args):
440 yield x
441
442 if self.ui.debugflag:
443 files = self.repo.changes(log.parents(changenode)[0], changenode)
444 def showfiles(**args):
445 for x in showlist('file', files[0], **args): yield x
446 def showadds(**args):
447 for x in showlist('file_add', files[1], **args): yield x
448 def showdels(**args):
449 for x in showlist('file_del', files[2], **args): yield x
450 else:
451 def showfiles(**args):
452 for x in showlist('file', changes[3], **args): yield x
453 showadds = ''
454 showdels = ''
455
456 props = {
457 'author': changes[1],
458 'branches': showbranches,
459 'date': changes[2],
460 'desc': changes[4],
461 'file_adds': showadds,
462 'file_dels': showdels,
463 'files': showfiles,
464 'manifest': showmanifest,
465 'node': hex(changenode),
466 'parents': showparents,
467 'rev': rev,
468 'tags': showtags,
469 }
470
471 try:
472 if self.ui.debugflag and 'header_debug' in self.t:
473 key = 'header_debug'
474 elif self.ui.quiet and 'header_quiet' in self.t:
475 key = 'header_quiet'
476 elif self.ui.verbose and 'header_verbose' in self.t:
477 key = 'header_verbose'
478 elif 'header' in self.t:
479 key = 'header'
480 else:
481 key = ''
482 if key:
483 self.write_header(self.t(key, **props))
484 if self.ui.debugflag and 'changeset_debug' in self.t:
485 key = 'changeset_debug'
486 elif self.ui.quiet and 'changeset_quiet' in self.t:
487 key = 'changeset_quiet'
488 elif self.ui.verbose and 'changeset_verbose' in self.t:
489 key = 'changeset_verbose'
490 else:
491 key = 'changeset'
492 self.write(self.t(key, **props))
493 except KeyError, inst:
494 raise util.Abort(_("%s: no key named '%s'") % (self.t.mapfile,
495 inst.args[0]))
496 except SyntaxError, inst:
497 raise util.Abort(_('%s: %s') % (self.t.mapfile, inst.args[0]))