Mercurial > hg > mercurial-crew-with-dirclash
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])) |