annotate mercurial/templatefilters.py @ 39559:07b58266bce3

wireprotov2: implement commands as a generator of objects Previously, wire protocol version 2 inherited version 1's model of having separate types to represent the results of different wire protocol commands. As I implemented more powerful commands in future commits, I found I was using a common pattern of returning a special type to hold a generator. This meant the command function required a closure to do most of the work. That made logic flow more difficult to follow. I also noticed that many commands were effectively a sequence of objects to be CBOR encoded. I think it makes sense to define version 2 commands as generators. This way, commands can simply emit the data structures they wish to send to the client. This eliminates the need for a closure in command functions and removes encoding from the bodies of commands. As part of this commit, the handling of response objects has been moved into the serverreactor class. This puts the reactor in the driver's seat with regards to CBOR encoding and error handling. Having error handling in the function that emits frames is particularly important because exceptions in that function can lead to things getting in a bad state: I'm fairly certain that uncaught exceptions in the frame generator were causing deadlocks. I also introduced a dedicated error type for explicit error reporting in command handlers. This will be used in subsequent commits. There's still a bit of work to be done here, especially around formalizing the error handling "protocol." I've added yet another TODO to track this so we don't forget. Test output changed because we're using generators and no longer know we are at the end of the data until we hit the end of the generator. This means we can't emit the end-of-stream flag until we've exhausted the generator. Hence the introduction of 0-sized end-of-stream frames. Differential Revision: https://phab.mercurial-scm.org/D4472
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 05 Sep 2018 09:06:40 -0700
parents e7aa113b14f7
children e2697acd9381
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32740
ae0ebe93ac70 templatefilers: correct filename in header comment
Yuya Nishihara <yuya@tcha.org>
parents: 32128
diff changeset
1 # templatefilters.py - common template expansion filters
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8158
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9722
diff changeset
6 # GNU General Public License version 2 or any later version.
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
25983
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
8 from __future__ import absolute_import
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
9
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
10 import os
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
11 import re
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
12 import time
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
13
37229
05db42732fce templatefilters: handle TypeError by count()
Yuya Nishihara <yuya@tcha.org>
parents: 37227
diff changeset
14 from .i18n import _
25983
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
15 from . import (
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
16 encoding,
34837
4fdc4adbc838 templatefilters: defend against evil unicode strs in json filter
Augie Fackler <augie@google.com>
parents: 34695
diff changeset
17 error,
25983
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
18 node,
32126
e37fd5be0fed py3: alias long to int on Python 3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32039
diff changeset
19 pycompat,
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
20 registrar,
36920
6ff6e1d6b5b8 templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36831
diff changeset
21 templateutil,
34695
e178fcaa3933 python3: use our bytes-only version of cgi.escape everywhere
Augie Fackler <augie@google.com>
parents: 34131
diff changeset
22 url,
25983
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
23 util,
1245049da5f3 templatefilters: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25778
diff changeset
24 )
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
25 from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
26 dateutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
27 stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
28 )
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
29
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28693
diff changeset
30 urlerr = util.urlerr
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28693
diff changeset
31 urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28693
diff changeset
32
32126
e37fd5be0fed py3: alias long to int on Python 3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32039
diff changeset
33 if pycompat.ispy3:
e37fd5be0fed py3: alias long to int on Python 3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32039
diff changeset
34 long = int
e37fd5be0fed py3: alias long to int on Python 3
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32039
diff changeset
35
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
36 # filters are callables like:
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
37 # fn(obj)
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
38 # with:
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
39 # obj - object to be filtered (text, date, list and so on)
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
40 filters = {}
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
41
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
42 templatefilter = registrar.templatefilter(filters)
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
43
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
44 @templatefilter('addbreaks', intype=bytes)
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
45 def addbreaks(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
46 """Any text. Add an XHTML "<br />" tag before the end of
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
47 every line except the last.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
48 """
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
49 return text.replace('\n', '<br/>\n')
8360
acc202b71619 templater: provide the standard template filters by default
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8234
diff changeset
50
19736
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
51 agescales = [("year", 3600 * 24 * 365, 'Y'),
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
52 ("month", 3600 * 24 * 30, 'M'),
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
53 ("week", 3600 * 24 * 7, 'W'),
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
54 ("day", 3600 * 24, 'd'),
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
55 ("hour", 3600, 'h'),
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
56 ("minute", 60, 'm'),
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
57 ("second", 1, 's')]
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
58
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
59 @templatefilter('age', intype=templateutil.date)
19736
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
60 def age(date, abbrev=False):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
61 """Date. Returns a human-readable date/time difference between the
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
62 given date/time and the current date/time.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
63 """
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
64
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
65 def plural(t, c):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
66 if c == 1:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
67 return t
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68 return t + "s"
19736
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
69 def fmt(t, c, a):
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
70 if abbrev:
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
71 return "%d%s" % (c, a)
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72 return "%d %s" % (c, plural(t, c))
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
74 now = time.time()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 then = date[0]
13666
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
76 future = False
7682
9c8bbae02e9c templater: fix age filter to state the obvious on future timestamps
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6691
diff changeset
77 if then > now:
13666
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
78 future = True
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
79 delta = max(1, int(then - now))
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
80 if delta > agescales[0][1] * 30:
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
81 return 'in the distant future'
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
82 else:
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
83 delta = max(1, int(now - then))
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
84 if delta > agescales[0][1] * 2:
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36573
diff changeset
85 return dateutil.shortdate(date)
9722
4d9dea174b84 templater: readable dates older than 24 months revert to ISO8601 (issue1006)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9721
diff changeset
86
19736
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
87 for t, s, a in agescales:
9029
0001e49f1c11 compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents: 8697
diff changeset
88 n = delta // s
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
89 if n >= 2 or s == 1:
13666
c49cddce0a81 templates: provide granularity for future values for age filter
timeless <timeless@gmail.com>
parents: 13593
diff changeset
90 if future:
19736
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
91 return '%s from now' % fmt(t, n, a)
f08e542ce918 templatefilters: add short format for age formatting
David Soria Parra <dsp@experimentalworks.net>
parents: 19467
diff changeset
92 return '%s ago' % fmt(t, n, a)
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
93
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
94 @templatefilter('basename', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
95 def basename(path):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
96 """Any text. Treats the text as a path, and returns the last
35539
d1aae6d4efc5 templatefilters: fix doc of basename()
Yuya Nishihara <yuya@tcha.org>
parents: 34837
diff changeset
97 component of the path after splitting by the path separator.
d1aae6d4efc5 templatefilters: fix doc of basename()
Yuya Nishihara <yuya@tcha.org>
parents: 34837
diff changeset
98 For example, "foo/bar/baz" becomes "baz" and "foo/bar//" becomes "".
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
99 """
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
100 return os.path.basename(path)
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
101
38304
fabfbbf4dee2 templatefilters: rename commonprefix to commondir
Martin von Zweigbergk <martinvonz@google.com>
parents: 38300
diff changeset
102 @templatefilter('commondir')
fabfbbf4dee2 templatefilters: rename commonprefix to commondir
Martin von Zweigbergk <martinvonz@google.com>
parents: 38300
diff changeset
103 def commondir(filelist):
38201
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
104 """List of text. Treats each list item as file name with /
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
105 as path separator and returns the longest common directory
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
106 prefix shared by all list items.
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
107 Returns the empty string if no common prefix exists.
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
108
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
109 The list items are not normalized, i.e. "foo/../bar" is handled as
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
110 file "bar" in the directory "foo/..". Leading slashes are ignored.
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
111
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
112 For example, ["foo/bar/baz", "foo/baz/bar"] becomes "foo" and
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
113 ["foo/bar", "baz"] becomes "".
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
114 """
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
115 def common(a, b):
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
116 if len(a) > len(b):
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
117 a = b[:len(a)]
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
118 elif len(b) > len(a):
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
119 b = b[:len(a)]
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
120 if a == b:
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
121 return a
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38304
diff changeset
122 for i in pycompat.xrange(len(a)):
38201
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
123 if a[i] != b[i]:
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
124 return a[:i]
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
125 return a
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
126 try:
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
127 if not filelist:
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
128 return ""
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
129 dirlist = [f.lstrip('/').split('/')[:-1] for f in filelist]
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
130 if len(dirlist) == 1:
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
131 return '/'.join(dirlist[0])
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
132 a = min(dirlist)
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
133 b = max(dirlist)
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
134 # The common prefix of a and b is shared with all
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
135 # elements of the list since Python sorts lexicographical
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
136 # and [1, x] after [1].
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
137 return '/'.join(common(a, b))
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
138 except TypeError:
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
139 raise error.ParseError(_('argument is not a list of text'))
56dd15178190 templatefilters: add commonprefix
Joerg Sonnenberger <joerg@bec.de>
parents: 38024
diff changeset
140
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
141 @templatefilter('count')
22668
13e3f07d74a3 templater: add count template filter, plus tests
Anton Shestakov <engored@ya.ru>
parents: 21873
diff changeset
142 def count(i):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
143 """List or text. Returns the length as an integer."""
37229
05db42732fce templatefilters: handle TypeError by count()
Yuya Nishihara <yuya@tcha.org>
parents: 37227
diff changeset
144 try:
05db42732fce templatefilters: handle TypeError by count()
Yuya Nishihara <yuya@tcha.org>
parents: 37227
diff changeset
145 return len(i)
05db42732fce templatefilters: handle TypeError by count()
Yuya Nishihara <yuya@tcha.org>
parents: 37227
diff changeset
146 except TypeError:
05db42732fce templatefilters: handle TypeError by count()
Yuya Nishihara <yuya@tcha.org>
parents: 37227
diff changeset
147 raise error.ParseError(_('not countable'))
22668
13e3f07d74a3 templater: add count template filter, plus tests
Anton Shestakov <engored@ya.ru>
parents: 21873
diff changeset
148
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
149 @templatefilter('dirname', intype=bytes)
36246
9ee10b3284da templatefilters: add dirname() filter
Yuya Nishihara <yuya@tcha.org>
parents: 35751
diff changeset
150 def dirname(path):
9ee10b3284da templatefilters: add dirname() filter
Yuya Nishihara <yuya@tcha.org>
parents: 35751
diff changeset
151 """Any text. Treats the text as a path, and strips the last
9ee10b3284da templatefilters: add dirname() filter
Yuya Nishihara <yuya@tcha.org>
parents: 35751
diff changeset
152 component of the path after splitting by the path separator.
9ee10b3284da templatefilters: add dirname() filter
Yuya Nishihara <yuya@tcha.org>
parents: 35751
diff changeset
153 """
9ee10b3284da templatefilters: add dirname() filter
Yuya Nishihara <yuya@tcha.org>
parents: 35751
diff changeset
154 return os.path.dirname(path)
9ee10b3284da templatefilters: add dirname() filter
Yuya Nishihara <yuya@tcha.org>
parents: 35751
diff changeset
155
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
156 @templatefilter('domain', intype=bytes)
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
157 def domain(author):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
158 """Any text. Finds the first string that looks like an email
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
159 address, and extracts just the domain component. Example: ``User
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
160 <user@example.com>`` becomes ``example.com``.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
161 """
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
162 f = author.find('@')
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
163 if f == -1:
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
164 return ''
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
165 author = author[f + 1:]
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
166 f = author.find('>')
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
167 if f >= 0:
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
168 author = author[:f]
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
169 return author
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
170
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
171 @templatefilter('email', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
172 def email(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
173 """Any text. Extracts the first string that looks like an email
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
174 address. Example: ``User <user@example.com>`` becomes
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
175 ``user@example.com``.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
176 """
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
177 return stringutil.email(text)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
178
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
179 @templatefilter('escape', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
180 def escape(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
181 """Any text. Replaces the special XML/XHTML characters "&", "<"
17772
823a7d79ef82 hgweb: make the escape filter remove null characters (issue2567)
Siddharth Agarwal <sid0@fb.com>
parents: 17755
diff changeset
182 and ">" with XML entities, and filters out NUL characters.
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
183 """
34695
e178fcaa3933 python3: use our bytes-only version of cgi.escape everywhere
Augie Fackler <augie@google.com>
parents: 34131
diff changeset
184 return url.escape(text.replace('\0', ''), True)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
185
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
186 para_re = None
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
187 space_re = None
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
188
19872
681f7b9213a4 check-code: check for spaces around = for named parameters
Mads Kiilerich <madski@unity3d.com>
parents: 19736
diff changeset
189 def fill(text, width, initindent='', hangindent=''):
19228
889807c79384 templater: add indentation arguments to the fill function
Sean Farley <sean.michael.farley@gmail.com>
parents: 19227
diff changeset
190 '''fill many paragraphs with optional indentation.'''
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
191 global para_re, space_re
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
192 if para_re is None:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
193 para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
36498
b546181ae451 py3: make regexp literal bytes in templatefilters.py
Yuya Nishihara <yuya@tcha.org>
parents: 36497
diff changeset
194 space_re = re.compile(br' +')
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
195
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
196 def findparas():
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
197 start = 0
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
198 while True:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
199 m = para_re.search(text, start)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
200 if not m:
36497
b2e54b257832 templatefilters: use encoding.unifromlocal/unitolocal() for py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 36246
diff changeset
201 uctext = encoding.unifromlocal(text[start:])
11297
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
202 w = len(uctext)
d320e70442a5 replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 10787
diff changeset
203 while 0 < w and uctext[w - 1].isspace():
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
204 w -= 1
36497
b2e54b257832 templatefilters: use encoding.unifromlocal/unitolocal() for py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 36246
diff changeset
205 yield (encoding.unitolocal(uctext[:w]),
b2e54b257832 templatefilters: use encoding.unifromlocal/unitolocal() for py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 36246
diff changeset
206 encoding.unitolocal(uctext[w:]))
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
207 break
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
208 yield text[start:m.start(0)], m.group(1)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
209 start = m.end(1)
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
210
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
211 return "".join([stringutil.wrap(space_re.sub(' ',
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
212 stringutil.wrap(para, width)),
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
213 width, initindent, hangindent) + rest
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
214 for para, rest in findparas()])
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
216 @templatefilter('fill68', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
217 def fill68(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
218 """Any text. Wraps the text to fit in 68 columns."""
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
219 return fill(text, 68)
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
220
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
221 @templatefilter('fill76', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
222 def fill76(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
223 """Any text. Wraps the text to fit in 76 columns."""
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
224 return fill(text, 76)
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
225
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
226 @templatefilter('firstline', intype=bytes)
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
227 def firstline(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
228 """Any text. Returns the first line of text."""
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
229 try:
9136
31177742f54a for calls expecting bool args, pass bool instead of int
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9029
diff changeset
230 return text.splitlines(True)[0].rstrip('\r\n')
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
231 except IndexError:
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
232 return ''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
233
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
234 @templatefilter('hex', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
235 def hexfilter(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
236 """Any text. Convert a binary Mercurial node identifier into
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
237 its long hexadecimal representation.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
238 """
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
239 return node.hex(text)
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
240
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
241 @templatefilter('hgdate', intype=templateutil.date)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
242 def hgdate(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
243 """Date. Returns the date as a pair of numbers: "1157407993
38300
74b4a54002ec templatefilters: undeprecate hgdate
Yuya Nishihara <yuya@tcha.org>
parents: 38287
diff changeset
244 25200" (Unix timestamp, timezone offset).
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
245 """
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
246 return "%d %d" % text
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
247
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
248 @templatefilter('isodate', intype=templateutil.date)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
249 def isodate(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
250 """Date. Returns the date in ISO 8601 format: "2009-08-18 13:00
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
251 +0200".
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
252 """
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36573
diff changeset
253 return dateutil.datestr(text, '%Y-%m-%d %H:%M %1%2')
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
254
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
255 @templatefilter('isodatesec', intype=templateutil.date)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
256 def isodatesec(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
257 """Date. Returns the date in ISO 8601 format, including
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
258 seconds: "2009-08-18 13:00:13 +0200". See also the rfc3339date
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
259 filter.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
260 """
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36573
diff changeset
261 return dateutil.datestr(text, '%Y-%m-%d %H:%M:%S %1%2')
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
262
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
263 def indent(text, prefix):
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
264 '''indent each non-empty line of text after first with prefix.'''
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
265 lines = text.splitlines()
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
266 num_lines = len(lines)
9387
20ed9909dbd9 templatefilters: indent: do not compute text.endswith('\n') in each iteration
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9136
diff changeset
267 endswithnewline = text[-1:] == '\n'
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
268 def indenter():
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38304
diff changeset
269 for i in pycompat.xrange(num_lines):
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
270 l = lines[i]
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
271 if i and l.strip():
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
272 yield prefix
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
273 yield l
9387
20ed9909dbd9 templatefilters: indent: do not compute text.endswith('\n') in each iteration
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9136
diff changeset
274 if i < num_lines - 1 or endswithnewline:
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
275 yield '\n'
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
276 return "".join(indenter())
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
277
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
278 @templatefilter('json')
31782
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 31781
diff changeset
279 def json(obj, paranoid=True):
37948
a25513263075 templatefilters: document the json filter
Yuya Nishihara <yuya@tcha.org>
parents: 37230
diff changeset
280 """Any object. Serializes the object to a JSON formatted text."""
31780
8d9eafe01111 templatefilters: unroll handling of None/False/True
Yuya Nishihara <yuya@tcha.org>
parents: 31779
diff changeset
281 if obj is None:
8d9eafe01111 templatefilters: unroll handling of None/False/True
Yuya Nishihara <yuya@tcha.org>
parents: 31779
diff changeset
282 return 'null'
8d9eafe01111 templatefilters: unroll handling of None/False/True
Yuya Nishihara <yuya@tcha.org>
parents: 31779
diff changeset
283 elif obj is False:
8d9eafe01111 templatefilters: unroll handling of None/False/True
Yuya Nishihara <yuya@tcha.org>
parents: 31779
diff changeset
284 return 'false'
8d9eafe01111 templatefilters: unroll handling of None/False/True
Yuya Nishihara <yuya@tcha.org>
parents: 31779
diff changeset
285 elif obj is True:
8d9eafe01111 templatefilters: unroll handling of None/False/True
Yuya Nishihara <yuya@tcha.org>
parents: 31779
diff changeset
286 return 'true'
31728
35eb8f112c88 templatefilter: add support for 'long' to json()
Matt Harbison <matt_harbison@yahoo.com>
parents: 31451
diff changeset
287 elif isinstance(obj, (int, long, float)):
32127
964e7427a691 py3: use pycompat.bytestr() instead of str()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32126
diff changeset
288 return pycompat.bytestr(obj)
32128
c3342c177211 py3: replace str with bytes in isinstance()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32127
diff changeset
289 elif isinstance(obj, bytes):
31782
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 31781
diff changeset
290 return '"%s"' % encoding.jsonescape(obj, paranoid=paranoid)
38024
f5a1aa8c6987 json: reject unicode on py2 as well
Martin von Zweigbergk <martinvonz@google.com>
parents: 37948
diff changeset
291 elif isinstance(obj, type(u'')):
34837
4fdc4adbc838 templatefilters: defend against evil unicode strs in json filter
Augie Fackler <augie@google.com>
parents: 34695
diff changeset
292 raise error.ProgrammingError(
38024
f5a1aa8c6987 json: reject unicode on py2 as well
Martin von Zweigbergk <martinvonz@google.com>
parents: 37948
diff changeset
293 'Mercurial only does output with bytes: %r' % obj)
14967
376091a4ad23 templatefilters: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14944
diff changeset
294 elif util.safehasattr(obj, 'keys'):
32743
f924dd043974 json: pass formatting options recursively
Yuya Nishihara <yuya@tcha.org>
parents: 32742
diff changeset
295 out = ['"%s": %s' % (encoding.jsonescape(k, paranoid=paranoid),
f924dd043974 json: pass formatting options recursively
Yuya Nishihara <yuya@tcha.org>
parents: 32742
diff changeset
296 json(v, paranoid))
31781
47925b63be70 templatefilters: use list comprehension in json()
Yuya Nishihara <yuya@tcha.org>
parents: 31780
diff changeset
297 for k, v in sorted(obj.iteritems())]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
298 return '{' + ', '.join(out) + '}'
14944
e2c413bde8a5 globally: use safehasattr(x, '__iter__') instead of hasattr(x, '__iter__')
Augie Fackler <durin42@gmail.com>
parents: 14318
diff changeset
299 elif util.safehasattr(obj, '__iter__'):
32743
f924dd043974 json: pass formatting options recursively
Yuya Nishihara <yuya@tcha.org>
parents: 32742
diff changeset
300 out = [json(i, paranoid) for i in obj]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
301 return '[' + ', '.join(out) + ']'
37230
63144f33c8bb templatefilters: raise ProgrammingError if unencodable type passed to json()
Yuya Nishihara <yuya@tcha.org>
parents: 37229
diff changeset
302 raise error.ProgrammingError('cannot encode %r' % obj)
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6319
diff changeset
303
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
304 @templatefilter('lower', intype=bytes)
24566
6abce80e6cbf templatefilters: add "upper" and "lower" for case conversion
Yuya Nishihara <yuya@tcha.org>
parents: 23708
diff changeset
305 def lower(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
306 """Any text. Converts the text to lowercase."""
24566
6abce80e6cbf templatefilters: add "upper" and "lower" for case conversion
Yuya Nishihara <yuya@tcha.org>
parents: 23708
diff changeset
307 return encoding.lower(text)
6abce80e6cbf templatefilters: add "upper" and "lower" for case conversion
Yuya Nishihara <yuya@tcha.org>
parents: 23708
diff changeset
308
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
309 @templatefilter('nonempty', intype=bytes)
36552
a185b1af207c templatefilters: stop using str as a variable name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36498
diff changeset
310 def nonempty(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
311 """Any text. Returns '(none)' if the string is empty."""
36552
a185b1af207c templatefilters: stop using str as a variable name
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36498
diff changeset
312 return text or "(none)"
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
313
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
314 @templatefilter('obfuscate', intype=bytes)
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
315 def obfuscate(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
316 """Any text. Returns the input text rendered as a sequence of
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
317 XML entities.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
318 """
36563
9d71bd25554b templatefilters: convert arguments to sysstrs for unicode() ctor
Augie Fackler <augie@google.com>
parents: 36552
diff changeset
319 text = unicode(text, pycompat.sysstr(encoding.encoding), r'replace')
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
320 return ''.join(['&#%d;' % ord(c) for c in text])
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
321
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
322 @templatefilter('permissions', intype=bytes)
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
323 def permissions(flags):
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
324 if "l" in flags:
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
325 return "lrwxrwxrwx"
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
326 if "x" in flags:
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
327 return "-rwxr-xr-x"
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
328 return "-rw-r--r--"
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
329
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
330 @templatefilter('person', intype=bytes)
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
331 def person(author):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
332 """Any text. Returns the name before an email address,
16235
eb39bbda167b templates/filters: strip quotes from {author|person}
"Yann E. MORIN" <yann.morin.1998@free.fr>
parents: 15155
diff changeset
333 interpreting it as per RFC 5322.
eb39bbda167b templates/filters: strip quotes from {author|person}
"Yann E. MORIN" <yann.morin.1998@free.fr>
parents: 15155
diff changeset
334 """
37155
fb7140f1d09d stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents: 37084
diff changeset
335 return stringutil.person(author)
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
336
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
337 @templatefilter('revescape', intype=bytes)
25778
3a33412792f1 templates: introduce revescape filter for escaping symbolic revisions
Anton Shestakov <av6@dwimlabs.net>
parents: 25000
diff changeset
338 def revescape(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
339 """Any text. Escapes all "special" characters, except @.
25778
3a33412792f1 templates: introduce revescape filter for escaping symbolic revisions
Anton Shestakov <av6@dwimlabs.net>
parents: 25000
diff changeset
340 Forward slashes are escaped twice to prevent web servers from prematurely
3a33412792f1 templates: introduce revescape filter for escaping symbolic revisions
Anton Shestakov <av6@dwimlabs.net>
parents: 25000
diff changeset
341 unescaping them. For example, "@foo bar/baz" becomes "@foo%20bar%252Fbaz".
3a33412792f1 templates: introduce revescape filter for escaping symbolic revisions
Anton Shestakov <av6@dwimlabs.net>
parents: 25000
diff changeset
342 """
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28693
diff changeset
343 return urlreq.quote(text, safe='/@').replace('/', '%252F')
25778
3a33412792f1 templates: introduce revescape filter for escaping symbolic revisions
Anton Shestakov <av6@dwimlabs.net>
parents: 25000
diff changeset
344
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
345 @templatefilter('rfc3339date', intype=templateutil.date)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
346 def rfc3339date(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
347 """Date. Returns a date using the Internet date format
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
348 specified in RFC 3339: "2009-08-18T13:00:13+02:00".
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
349 """
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36573
diff changeset
350 return dateutil.datestr(text, "%Y-%m-%dT%H:%M:%S%1:%2")
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
351
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
352 @templatefilter('rfc822date', intype=templateutil.date)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
353 def rfc822date(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
354 """Date. Returns a date using the same format used in email
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
355 headers: "Tue, 18 Aug 2009 13:00:13 +0200".
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
356 """
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36573
diff changeset
357 return dateutil.datestr(text, "%a, %d %b %Y %H:%M:%S %1%2")
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
358
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
359 @templatefilter('short', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
360 def short(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
361 """Changeset hash. Returns the short form of a changeset hash,
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
362 i.e. a 12 hexadecimal digit string.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
363 """
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
364 return text[:12]
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
365
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
366 @templatefilter('shortbisect', intype=bytes)
36830
71f189941791 templatefilters: inline hbisect.shortlabel()
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
367 def shortbisect(label):
71f189941791 templatefilters: inline hbisect.shortlabel()
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
368 """Any text. Treats `label` as a bisection status, and
15155
f4a8d754cd0a templates: add 'bisect' keyword to return a cset's bisect status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14967
diff changeset
369 returns a single-character representing the status (G: good, B: bad,
f4a8d754cd0a templates: add 'bisect' keyword to return a cset's bisect status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14967
diff changeset
370 S: skipped, U: untested, I: ignored). Returns single space if `text`
f4a8d754cd0a templates: add 'bisect' keyword to return a cset's bisect status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14967
diff changeset
371 is not a valid bisection status.
f4a8d754cd0a templates: add 'bisect' keyword to return a cset's bisect status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14967
diff changeset
372 """
36830
71f189941791 templatefilters: inline hbisect.shortlabel()
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
373 if label:
36831
82af07e1ae16 py3: fix slicing of bisect label in templatefilters.shortbisect()
Yuya Nishihara <yuya@tcha.org>
parents: 36830
diff changeset
374 return label[0:1].upper()
36830
71f189941791 templatefilters: inline hbisect.shortlabel()
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
375 return ' '
15155
f4a8d754cd0a templates: add 'bisect' keyword to return a cset's bisect status
"Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
parents: 14967
diff changeset
376
37227
9bcf096a2da2 templatefilters: declare input type as date where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37223
diff changeset
377 @templatefilter('shortdate', intype=templateutil.date)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
378 def shortdate(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
379 """Date. Returns a date like "2006-09-18"."""
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36573
diff changeset
380 return dateutil.shortdate(text)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
381
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
382 @templatefilter('slashpath', intype=bytes)
35444
dad8a5071b0a templatefilters: add slashpath() to convert path separator to slash
Yuya Nishihara <yuya@tcha.org>
parents: 34837
diff changeset
383 def slashpath(path):
dad8a5071b0a templatefilters: add slashpath() to convert path separator to slash
Yuya Nishihara <yuya@tcha.org>
parents: 34837
diff changeset
384 """Any text. Replaces the native path separator with slash."""
dad8a5071b0a templatefilters: add slashpath() to convert path separator to slash
Yuya Nishihara <yuya@tcha.org>
parents: 34837
diff changeset
385 return util.pconvert(path)
dad8a5071b0a templatefilters: add slashpath() to convert path separator to slash
Yuya Nishihara <yuya@tcha.org>
parents: 34837
diff changeset
386
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
387 @templatefilter('splitlines', intype=bytes)
21820
cce404b0c918 templatefilter: add splitlines function
Ryan McElroy <rmcelroy@fb.com>
parents: 19886
diff changeset
388 def splitlines(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
389 """Any text. Split text into a list of lines."""
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
390 return templateutil.hybridlist(text.splitlines(), name='line')
21820
cce404b0c918 templatefilter: add splitlines function
Ryan McElroy <rmcelroy@fb.com>
parents: 19886
diff changeset
391
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
392 @templatefilter('stringescape', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
393 def stringescape(text):
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
394 return stringutil.escapestr(text)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
395
37222
54355c243042 templatefilters: allow declaration of input data type
Yuya Nishihara <yuya@tcha.org>
parents: 37155
diff changeset
396 @templatefilter('stringify', intype=bytes)
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
397 def stringify(thing):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
398 """Any type. Turns the value into text by converting values into
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
399 text and concatenating them.
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
400 """
37222
54355c243042 templatefilters: allow declaration of input data type
Yuya Nishihara <yuya@tcha.org>
parents: 37155
diff changeset
401 return thing # coerced by the intype
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
402
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
403 @templatefilter('stripdir', intype=bytes)
8158
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
404 def stripdir(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
405 """Treat the text as path and strip a directory level, if
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
406 possible. For example, "foo" and "foo/bar" becomes "foo".
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
407 """
8158
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
408 dir = os.path.dirname(text)
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
409 if dir == "":
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
410 return os.path.basename(text)
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
411 else:
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
412 return dir
1bef3656d9fe templatefilters: add new stripdir filter
Aleix Conchillo Flaque <aleix@member.fsf.org>
parents: 8014
diff changeset
413
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
414 @templatefilter('tabindent', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
415 def tabindent(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
416 """Any text. Returns the text, with every non-empty line
19467
1afe5d3939db template: fix tabindent docstring (issue2880)
Matt Mackall <mpm@selenic.com>
parents: 19228
diff changeset
417 except the first starting with a tab character.
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
418 """
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
419 return indent(text, '\t')
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
420
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
421 @templatefilter('upper', intype=bytes)
24566
6abce80e6cbf templatefilters: add "upper" and "lower" for case conversion
Yuya Nishihara <yuya@tcha.org>
parents: 23708
diff changeset
422 def upper(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
423 """Any text. Converts the text to uppercase."""
24566
6abce80e6cbf templatefilters: add "upper" and "lower" for case conversion
Yuya Nishihara <yuya@tcha.org>
parents: 23708
diff changeset
424 return encoding.upper(text)
6abce80e6cbf templatefilters: add "upper" and "lower" for case conversion
Yuya Nishihara <yuya@tcha.org>
parents: 23708
diff changeset
425
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
426 @templatefilter('urlescape', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
427 def urlescape(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
428 """Any text. Escapes all "special" characters. For example,
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
429 "foo bar" becomes "foo%20bar".
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
430 """
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28693
diff changeset
431 return urlreq.quote(text)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
432
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
433 @templatefilter('user', intype=bytes)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
434 def userfilter(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
435 """Any text. Returns a short representation of a user name or email
16360
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 16251
diff changeset
436 address."""
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
437 return stringutil.shortuser(text)
13590
1a752dcfe062 templatefilters: wrap all filters in dedicated functions
Patrick Mezard <pmezard@gmail.com>
parents: 13589
diff changeset
438
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
439 @templatefilter('emailuser', intype=bytes)
16360
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 16251
diff changeset
440 def emailuser(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
441 """Any text. Returns the user portion of an email address."""
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
442 return stringutil.emailuser(text)
16360
e5788269741a templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents: 16251
diff changeset
443
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
444 @templatefilter('utf8', intype=bytes)
28209
8ddf893560fa templatefilters: add "utf8" to get utf-8 bytes from local-encoding text
Yuya Nishihara <yuya@tcha.org>
parents: 28208
diff changeset
445 def utf8(text):
28693
11f623b5668f templatefilters: use templatefilter to mark a function as template filter
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28692
diff changeset
446 """Any text. Converts from the local character encoding to UTF-8."""
28209
8ddf893560fa templatefilters: add "utf8" to get utf-8 bytes from local-encoding text
Yuya Nishihara <yuya@tcha.org>
parents: 28208
diff changeset
447 return encoding.fromlocal(text)
8ddf893560fa templatefilters: add "utf8" to get utf-8 bytes from local-encoding text
Yuya Nishihara <yuya@tcha.org>
parents: 28208
diff changeset
448
37223
08e042f0a67c templatefilters: declare input type as bytes where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 37222
diff changeset
449 @templatefilter('xmlescape', intype=bytes)
13588
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
450 def xmlescape(text):
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
451 text = (text
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
452 .replace('&', '&amp;')
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
453 .replace('<', '&lt;')
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
454 .replace('>', '&gt;')
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
455 .replace('"', '&quot;')
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
456 .replace("'", '&#39;')) # &apos; invalid in HTML
b8b881f3f3a7 templatefilters: sort function definitions
Patrick Mezard <pmezard@gmail.com>
parents: 13587
diff changeset
457 return re.sub('[\x00-\x08\x0B\x0C\x0E-\x1F]', ' ', text)
8234
27dbe534397b templatefilters: add "nonempty" template filter
Rocco Rutte <pdmef@gmx.net>
parents: 8225
diff changeset
458
18627
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
459 def websub(text, websubtable):
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
460 """:websub: Any text. Only applies to hgweb. Applies the regular
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
461 expression replacements defined in the websub section.
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
462 """
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
463 if websubtable:
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
464 for regexp, format in websubtable:
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
465 text = regexp.sub(format, text)
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
466 return text
4e949b8e0930 hgweb: add websub template filter
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 17772
diff changeset
467
28692
6b3b958daf03 registrar: add templatefilter to mark a function as template filter (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28213
diff changeset
468 def loadfilter(ui, extname, registrarobj):
6b3b958daf03 registrar: add templatefilter to mark a function as template filter (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28213
diff changeset
469 """Load template filter from specified registrarobj
6b3b958daf03 registrar: add templatefilter to mark a function as template filter (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28213
diff changeset
470 """
6b3b958daf03 registrar: add templatefilter to mark a function as template filter (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28213
diff changeset
471 for name, func in registrarobj._table.iteritems():
6b3b958daf03 registrar: add templatefilter to mark a function as template filter (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28213
diff changeset
472 filters[name] = func
6b3b958daf03 registrar: add templatefilter to mark a function as template filter (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 28213
diff changeset
473
13591
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
474 # tell hggettext to extract docstrings from these functions:
264f292a0c6f templatefilters: move doc from templates.txt to docstrings
Patrick Mezard <pmezard@gmail.com>
parents: 13590
diff changeset
475 i18nfunctions = filters.values()