Show More
@@ -17,6 +17,7 b' from . import (' | |||||
17 | error, |
|
17 | error, | |
18 | minirst, |
|
18 | minirst, | |
19 | parser, |
|
19 | parser, | |
|
20 | registrar, | |||
20 | revset as revsetmod, |
|
21 | revset as revsetmod, | |
21 | templatefilters, |
|
22 | templatefilters, | |
22 | templatekw, |
|
23 | templatekw, | |
@@ -393,8 +394,14 b' def buildfunc(exp, context):' | |||||
393 | return (runfilter, (args[0], f)) |
|
394 | return (runfilter, (args[0], f)) | |
394 | raise error.ParseError(_("unknown function '%s'") % n) |
|
395 | raise error.ParseError(_("unknown function '%s'") % n) | |
395 |
|
396 | |||
|
397 | # dict of template built-in functions | |||
|
398 | funcs = {} | |||
|
399 | ||||
|
400 | templatefunc = registrar.templatefunc(funcs) | |||
|
401 | ||||
|
402 | @templatefunc('date(date[, fmt])') | |||
396 | def date(context, mapping, args): |
|
403 | def date(context, mapping, args): | |
397 |
""" |
|
404 | """Format a date. See :hg:`help dates` for formatting | |
398 | strings. The default is a Unix date format, including the timezone: |
|
405 | strings. The default is a Unix date format, including the timezone: | |
399 | "Mon Sep 04 15:13:13 2006 0700".""" |
|
406 | "Mon Sep 04 15:13:13 2006 0700".""" | |
400 | if not (1 <= len(args) <= 2): |
|
407 | if not (1 <= len(args) <= 2): | |
@@ -414,8 +421,9 b' def date(context, mapping, args):' | |||||
414 | # i18n: "date" is a keyword |
|
421 | # i18n: "date" is a keyword | |
415 | raise error.ParseError(_("date expects a date information")) |
|
422 | raise error.ParseError(_("date expects a date information")) | |
416 |
|
423 | |||
|
424 | @templatefunc('diff([includepattern [, excludepattern]])') | |||
417 | def diff(context, mapping, args): |
|
425 | def diff(context, mapping, args): | |
418 | """:diff([includepattern [, excludepattern]]): Show a diff, optionally |
|
426 | """Show a diff, optionally | |
419 | specifying files to include or exclude.""" |
|
427 | specifying files to include or exclude.""" | |
420 | if len(args) > 2: |
|
428 | if len(args) > 2: | |
421 | # i18n: "diff" is a keyword |
|
429 | # i18n: "diff" is a keyword | |
@@ -433,8 +441,9 b' def diff(context, mapping, args):' | |||||
433 |
|
441 | |||
434 | return ''.join(chunks) |
|
442 | return ''.join(chunks) | |
435 |
|
443 | |||
|
444 | @templatefunc('fill(text[, width[, initialident[, hangindent]]])') | |||
436 | def fill(context, mapping, args): |
|
445 | def fill(context, mapping, args): | |
437 | """:fill(text[, width[, initialident[, hangindent]]]): Fill many |
|
446 | """Fill many | |
438 | paragraphs with optional indentation. See the "fill" filter.""" |
|
447 | paragraphs with optional indentation. See the "fill" filter.""" | |
439 | if not (1 <= len(args) <= 4): |
|
448 | if not (1 <= len(args) <= 4): | |
440 | # i18n: "fill" is a keyword |
|
449 | # i18n: "fill" is a keyword | |
@@ -456,8 +465,9 b' def fill(context, mapping, args):' | |||||
456 |
|
465 | |||
457 | return templatefilters.fill(text, width, initindent, hangindent) |
|
466 | return templatefilters.fill(text, width, initindent, hangindent) | |
458 |
|
467 | |||
|
468 | @templatefunc('pad(text, width[, fillchar=\' \'[, right=False]])') | |||
459 | def pad(context, mapping, args): |
|
469 | def pad(context, mapping, args): | |
460 | """:pad(text, width[, fillchar=' '[, right=False]]): Pad text with a |
|
470 | """Pad text with a | |
461 | fill character.""" |
|
471 | fill character.""" | |
462 | if not (2 <= len(args) <= 4): |
|
472 | if not (2 <= len(args) <= 4): | |
463 | # i18n: "pad" is a keyword |
|
473 | # i18n: "pad" is a keyword | |
@@ -481,8 +491,9 b' def pad(context, mapping, args):' | |||||
481 | else: |
|
491 | else: | |
482 | return text.ljust(width, fillchar) |
|
492 | return text.ljust(width, fillchar) | |
483 |
|
493 | |||
|
494 | @templatefunc('indent(text, indentchars[, firstline])') | |||
484 | def indent(context, mapping, args): |
|
495 | def indent(context, mapping, args): | |
485 |
""" |
|
496 | """Indents all non-empty lines | |
486 | with the characters given in the indentchars string. An optional |
|
497 | with the characters given in the indentchars string. An optional | |
487 | third parameter will override the indent for the first line only |
|
498 | third parameter will override the indent for the first line only | |
488 | if present.""" |
|
499 | if present.""" | |
@@ -501,8 +512,9 b' def indent(context, mapping, args):' | |||||
501 | # the indent function doesn't indent the first line, so we do it here |
|
512 | # the indent function doesn't indent the first line, so we do it here | |
502 | return templatefilters.indent(firstline + text, indent) |
|
513 | return templatefilters.indent(firstline + text, indent) | |
503 |
|
514 | |||
|
515 | @templatefunc('get(dict, key)') | |||
504 | def get(context, mapping, args): |
|
516 | def get(context, mapping, args): | |
505 |
""" |
|
517 | """Get an attribute/key from an object. Some keywords | |
506 | are complex types. This function allows you to obtain the value of an |
|
518 | are complex types. This function allows you to obtain the value of an | |
507 | attribute on these types.""" |
|
519 | attribute on these types.""" | |
508 | if len(args) != 2: |
|
520 | if len(args) != 2: | |
@@ -517,8 +529,9 b' def get(context, mapping, args):' | |||||
517 | key = evalfuncarg(context, mapping, args[1]) |
|
529 | key = evalfuncarg(context, mapping, args[1]) | |
518 | return dictarg.get(key) |
|
530 | return dictarg.get(key) | |
519 |
|
531 | |||
|
532 | @templatefunc('if(expr, then[, else])') | |||
520 | def if_(context, mapping, args): |
|
533 | def if_(context, mapping, args): | |
521 |
""" |
|
534 | """Conditionally execute based on the result of | |
522 | an expression.""" |
|
535 | an expression.""" | |
523 | if not (2 <= len(args) <= 3): |
|
536 | if not (2 <= len(args) <= 3): | |
524 | # i18n: "if" is a keyword |
|
537 | # i18n: "if" is a keyword | |
@@ -530,8 +543,9 b' def if_(context, mapping, args):' | |||||
530 | elif len(args) == 3: |
|
543 | elif len(args) == 3: | |
531 | yield args[2][0](context, mapping, args[2][1]) |
|
544 | yield args[2][0](context, mapping, args[2][1]) | |
532 |
|
545 | |||
|
546 | @templatefunc('ifcontains(search, thing, then[, else])') | |||
533 | def ifcontains(context, mapping, args): |
|
547 | def ifcontains(context, mapping, args): | |
534 |
""" |
|
548 | """Conditionally execute based | |
535 | on whether the item "search" is in "thing".""" |
|
549 | on whether the item "search" is in "thing".""" | |
536 | if not (3 <= len(args) <= 4): |
|
550 | if not (3 <= len(args) <= 4): | |
537 | # i18n: "ifcontains" is a keyword |
|
551 | # i18n: "ifcontains" is a keyword | |
@@ -545,8 +559,9 b' def ifcontains(context, mapping, args):' | |||||
545 | elif len(args) == 4: |
|
559 | elif len(args) == 4: | |
546 | yield args[3][0](context, mapping, args[3][1]) |
|
560 | yield args[3][0](context, mapping, args[3][1]) | |
547 |
|
561 | |||
|
562 | @templatefunc('ifeq(expr1, expr2, then[, else])') | |||
548 | def ifeq(context, mapping, args): |
|
563 | def ifeq(context, mapping, args): | |
549 |
""" |
|
564 | """Conditionally execute based on | |
550 | whether 2 items are equivalent.""" |
|
565 | whether 2 items are equivalent.""" | |
551 | if not (3 <= len(args) <= 4): |
|
566 | if not (3 <= len(args) <= 4): | |
552 | # i18n: "ifeq" is a keyword |
|
567 | # i18n: "ifeq" is a keyword | |
@@ -559,8 +574,9 b' def ifeq(context, mapping, args):' | |||||
559 | elif len(args) == 4: |
|
574 | elif len(args) == 4: | |
560 | yield args[3][0](context, mapping, args[3][1]) |
|
575 | yield args[3][0](context, mapping, args[3][1]) | |
561 |
|
576 | |||
|
577 | @templatefunc('join(list, sep)') | |||
562 | def join(context, mapping, args): |
|
578 | def join(context, mapping, args): | |
563 |
""" |
|
579 | """Join items in a list with a delimiter.""" | |
564 | if not (1 <= len(args) <= 2): |
|
580 | if not (1 <= len(args) <= 2): | |
565 | # i18n: "join" is a keyword |
|
581 | # i18n: "join" is a keyword | |
566 | raise error.ParseError(_("join expects one or two arguments")) |
|
582 | raise error.ParseError(_("join expects one or two arguments")) | |
@@ -582,8 +598,9 b' def join(context, mapping, args):' | |||||
582 | yield joiner |
|
598 | yield joiner | |
583 | yield x |
|
599 | yield x | |
584 |
|
600 | |||
|
601 | @templatefunc('label(label, expr)') | |||
585 | def label(context, mapping, args): |
|
602 | def label(context, mapping, args): | |
586 |
""" |
|
603 | """Apply a label to generated content. Content with | |
587 | a label applied can result in additional post-processing, such as |
|
604 | a label applied can result in additional post-processing, such as | |
588 | automatic colorization.""" |
|
605 | automatic colorization.""" | |
589 | if len(args) != 2: |
|
606 | if len(args) != 2: | |
@@ -598,8 +615,9 b' def label(context, mapping, args):' | |||||
598 |
|
615 | |||
599 | return ui.label(thing, label) |
|
616 | return ui.label(thing, label) | |
600 |
|
617 | |||
|
618 | @templatefunc('latesttag([pattern])') | |||
601 | def latesttag(context, mapping, args): |
|
619 | def latesttag(context, mapping, args): | |
602 |
""" |
|
620 | """The global tags matching the given pattern on the | |
603 | most recent globally tagged ancestor of this changeset.""" |
|
621 | most recent globally tagged ancestor of this changeset.""" | |
604 | if len(args) > 1: |
|
622 | if len(args) > 1: | |
605 | # i18n: "latesttag" is a keyword |
|
623 | # i18n: "latesttag" is a keyword | |
@@ -611,8 +629,9 b' def latesttag(context, mapping, args):' | |||||
611 |
|
629 | |||
612 | return templatekw.showlatesttags(pattern, **mapping) |
|
630 | return templatekw.showlatesttags(pattern, **mapping) | |
613 |
|
631 | |||
|
632 | @templatefunc('localdate(date[, tz])') | |||
614 | def localdate(context, mapping, args): |
|
633 | def localdate(context, mapping, args): | |
615 |
""" |
|
634 | """Converts a date to the specified timezone. | |
616 | The default is local date.""" |
|
635 | The default is local date.""" | |
617 | if not (1 <= len(args) <= 2): |
|
636 | if not (1 <= len(args) <= 2): | |
618 | # i18n: "localdate" is a keyword |
|
637 | # i18n: "localdate" is a keyword | |
@@ -639,8 +658,9 b' def localdate(context, mapping, args):' | |||||
639 | tzoffset = util.makedate()[1] |
|
658 | tzoffset = util.makedate()[1] | |
640 | return (date[0], tzoffset) |
|
659 | return (date[0], tzoffset) | |
641 |
|
660 | |||
|
661 | @templatefunc('revset(query[, formatargs...])') | |||
642 | def revset(context, mapping, args): |
|
662 | def revset(context, mapping, args): | |
643 |
""" |
|
663 | """Execute a revision set query. See | |
644 | :hg:`help revset`.""" |
|
664 | :hg:`help revset`.""" | |
645 | if not len(args) > 0: |
|
665 | if not len(args) > 0: | |
646 | # i18n: "revset" is a keyword |
|
666 | # i18n: "revset" is a keyword | |
@@ -669,8 +689,9 b' def revset(context, mapping, args):' | |||||
669 |
|
689 | |||
670 | return templatekw.showrevslist("revision", revs, **mapping) |
|
690 | return templatekw.showrevslist("revision", revs, **mapping) | |
671 |
|
691 | |||
|
692 | @templatefunc('rstdoc(text, style)') | |||
672 | def rstdoc(context, mapping, args): |
|
693 | def rstdoc(context, mapping, args): | |
673 |
""" |
|
694 | """Format ReStructuredText.""" | |
674 | if len(args) != 2: |
|
695 | if len(args) != 2: | |
675 | # i18n: "rstdoc" is a keyword |
|
696 | # i18n: "rstdoc" is a keyword | |
676 | raise error.ParseError(_("rstdoc expects two arguments")) |
|
697 | raise error.ParseError(_("rstdoc expects two arguments")) | |
@@ -680,8 +701,9 b' def rstdoc(context, mapping, args):' | |||||
680 |
|
701 | |||
681 | return minirst.format(text, style=style, keep=['verbose']) |
|
702 | return minirst.format(text, style=style, keep=['verbose']) | |
682 |
|
703 | |||
|
704 | @templatefunc('shortest(node, minlength=4)') | |||
683 | def shortest(context, mapping, args): |
|
705 | def shortest(context, mapping, args): | |
684 |
""" |
|
706 | """Obtain the shortest representation of | |
685 | a node.""" |
|
707 | a node.""" | |
686 | if not (1 <= len(args) <= 2): |
|
708 | if not (1 <= len(args) <= 2): | |
687 | # i18n: "shortest" is a keyword |
|
709 | # i18n: "shortest" is a keyword | |
@@ -734,8 +756,9 b' def shortest(context, mapping, args):' | |||||
734 | if len(shortest) <= length: |
|
756 | if len(shortest) <= length: | |
735 | return shortest |
|
757 | return shortest | |
736 |
|
758 | |||
|
759 | @templatefunc('strip(text[, chars])') | |||
737 | def strip(context, mapping, args): |
|
760 | def strip(context, mapping, args): | |
738 |
""" |
|
761 | """Strip characters from a string. By default, | |
739 | strips all leading and trailing whitespace.""" |
|
762 | strips all leading and trailing whitespace.""" | |
740 | if not (1 <= len(args) <= 2): |
|
763 | if not (1 <= len(args) <= 2): | |
741 | # i18n: "strip" is a keyword |
|
764 | # i18n: "strip" is a keyword | |
@@ -747,8 +770,9 b' def strip(context, mapping, args):' | |||||
747 | return text.strip(chars) |
|
770 | return text.strip(chars) | |
748 | return text.strip() |
|
771 | return text.strip() | |
749 |
|
772 | |||
|
773 | @templatefunc('sub(pattern, replacement, expression)') | |||
750 | def sub(context, mapping, args): |
|
774 | def sub(context, mapping, args): | |
751 |
""" |
|
775 | """Perform text substitution | |
752 | using regular expressions.""" |
|
776 | using regular expressions.""" | |
753 | if len(args) != 3: |
|
777 | if len(args) != 3: | |
754 | # i18n: "sub" is a keyword |
|
778 | # i18n: "sub" is a keyword | |
@@ -768,8 +792,9 b' def sub(context, mapping, args):' | |||||
768 | # i18n: "sub" is a keyword |
|
792 | # i18n: "sub" is a keyword | |
769 | raise error.ParseError(_("sub got an invalid replacement: %s") % rpl) |
|
793 | raise error.ParseError(_("sub got an invalid replacement: %s") % rpl) | |
770 |
|
794 | |||
|
795 | @templatefunc('startswith(pattern, text)') | |||
771 | def startswith(context, mapping, args): |
|
796 | def startswith(context, mapping, args): | |
772 |
""" |
|
797 | """Returns the value from the "text" argument | |
773 | if it begins with the content from the "pattern" argument.""" |
|
798 | if it begins with the content from the "pattern" argument.""" | |
774 | if len(args) != 2: |
|
799 | if len(args) != 2: | |
775 | # i18n: "startswith" is a keyword |
|
800 | # i18n: "startswith" is a keyword | |
@@ -781,9 +806,9 b' def startswith(context, mapping, args):' | |||||
781 | return text |
|
806 | return text | |
782 | return '' |
|
807 | return '' | |
783 |
|
808 | |||
784 |
|
809 | @templatefunc('word(number, text[, separator])') | ||
785 | def word(context, mapping, args): |
|
810 | def word(context, mapping, args): | |
786 |
""" |
|
811 | """Return the nth word from a string.""" | |
787 | if not (2 <= len(args) <= 3): |
|
812 | if not (2 <= len(args) <= 3): | |
788 | # i18n: "word" is a keyword |
|
813 | # i18n: "word" is a keyword | |
789 | raise error.ParseError(_("word expects two or three arguments, got %d") |
|
814 | raise error.ParseError(_("word expects two or three arguments, got %d") | |
@@ -821,29 +846,6 b' exprmethods = {' | |||||
821 | methods = exprmethods.copy() |
|
846 | methods = exprmethods.copy() | |
822 | methods["integer"] = exprmethods["symbol"] # '{1}' as variable |
|
847 | methods["integer"] = exprmethods["symbol"] # '{1}' as variable | |
823 |
|
848 | |||
824 | funcs = { |
|
|||
825 | "date": date, |
|
|||
826 | "diff": diff, |
|
|||
827 | "fill": fill, |
|
|||
828 | "get": get, |
|
|||
829 | "if": if_, |
|
|||
830 | "ifcontains": ifcontains, |
|
|||
831 | "ifeq": ifeq, |
|
|||
832 | "indent": indent, |
|
|||
833 | "join": join, |
|
|||
834 | "label": label, |
|
|||
835 | "latesttag": latesttag, |
|
|||
836 | "localdate": localdate, |
|
|||
837 | "pad": pad, |
|
|||
838 | "revset": revset, |
|
|||
839 | "rstdoc": rstdoc, |
|
|||
840 | "shortest": shortest, |
|
|||
841 | "startswith": startswith, |
|
|||
842 | "strip": strip, |
|
|||
843 | "sub": sub, |
|
|||
844 | "word": word, |
|
|||
845 | } |
|
|||
846 |
|
||||
847 | # template engine |
|
849 | # template engine | |
848 |
|
850 | |||
849 | stringify = templatefilters.stringify |
|
851 | stringify = templatefilters.stringify |
General Comments 0
You need to be logged in to leave comments.
Login now