1# -*- coding: utf-8 -*-
2"""Built-in template filters used with the ``|`` operator."""
3import math
4import random
5import re
6import warnings
7from collections import namedtuple
8from itertools import chain
9from itertools import groupby
10
11from markupsafe import escape
12from markupsafe import Markup
13from markupsafe import soft_unicode
14
15from ._compat import abc
16from ._compat import imap
17from ._compat import iteritems
18from ._compat import string_types
19from ._compat import text_type
20from .exceptions import FilterArgumentError
21from .runtime import Undefined
22from .utils import htmlsafe_json_dumps
23from .utils import pformat
24from .utils import unicode_urlencode
25from .utils import urlize
26
27_word_re = re.compile(r"\w+", re.UNICODE)
28_word_beginning_split_re = re.compile(r"([-\s\(\{\[\<]+)", re.UNICODE)
29
30
31def contextfilter(f):
32    """Decorator for marking context dependent filters. The current
33    :class:`Context` will be passed as first argument.
34    """
35    f.contextfilter = True
36    return f
37
38
39def evalcontextfilter(f):
40    """Decorator for marking eval-context dependent filters.  An eval
41    context object is passed as first argument.  For more information
42    about the eval context, see :ref:`eval-context`.
43
44    .. versionadded:: 2.4
45    """
46    f.evalcontextfilter = True
47    return f
48
49
50def environmentfilter(f):
51    """Decorator for marking environment dependent filters.  The current
52    :class:`Environment` is passed to the filter as first argument.
53    """
54    f.environmentfilter = True
55    return f
56
57
58def ignore_case(value):
59    """For use as a postprocessor for :func:`make_attrgetter`. Converts strings
60    to lowercase and returns other types as-is."""
61    return value.lower() if isinstance(value, string_types) else value
62
63
64def make_attrgetter(environment, attribute, postprocess=None, default=None):
65    """Returns a callable that looks up the given attribute from a
66    passed object with the rules of the environment.  Dots are allowed
67    to access attributes of attributes.  Integer parts in paths are
68    looked up as integers.
69    """
70    attribute = _prepare_attribute_parts(attribute)
71
72    def attrgetter(item):
73        for part in attribute:
74            item = environment.getitem(item, part)
75
76            if default and isinstance(item, Undefined):
77                item = default
78
79        if postprocess is not None:
80            item = postprocess(item)
81
82        return item
83
84    return attrgetter
85
86
87def make_multi_attrgetter(environment, attribute, postprocess=None):
88    """Returns a callable that looks up the given comma separated
89    attributes from a passed object with the rules of the environment.
90    Dots are allowed to access attributes of each attribute.  Integer
91    parts in paths are looked up as integers.
92
93    The value returned by the returned callable is a list of extracted
94    attribute values.
95
96    Examples of attribute: "attr1,attr2", "attr1.inner1.0,attr2.inner2.0", etc.
97    """
98    attribute_parts = (
99        attribute.split(",") if isinstance(attribute, string_types) else [attribute]
100    )
101    attribute = [
102        _prepare_attribute_parts(attribute_part) for attribute_part in attribute_parts
103    ]
104
105    def attrgetter(item):
106        items = [None] * len(attribute)
107        for i, attribute_part in enumerate(attribute):
108            item_i = item
109            for part in attribute_part:
110                item_i = environment.getitem(item_i, part)
111
112            if postprocess is not None:
113                item_i = postprocess(item_i)
114
115            items[i] = item_i
116        return items
117
118    return attrgetter
119
120
121def _prepare_attribute_parts(attr):
122    if attr is None:
123        return []
124    elif isinstance(attr, string_types):
125        return [int(x) if x.isdigit() else x for x in attr.split(".")]
126    else:
127        return [attr]
128
129
130def do_forceescape(value):
131    """Enforce HTML escaping.  This will probably double escape variables."""
132    if hasattr(value, "__html__"):
133        value = value.__html__()
134    return escape(text_type(value))
135
136
137def do_urlencode(value):
138    """Quote data for use in a URL path or query using UTF-8.
139
140    Basic wrapper around :func:`urllib.parse.quote` when given a
141    string, or :func:`urllib.parse.urlencode` for a dict or iterable.
142
143    :param value: Data to quote. A string will be quoted directly. A
144        dict or iterable of ``(key, value)`` pairs will be joined as a
145        query string.
146
147    When given a string, "/" is not quoted. HTTP servers treat "/" and
148    "%2F" equivalently in paths. If you need quoted slashes, use the
149    ``|replace("/", "%2F")`` filter.
150
151    .. versionadded:: 2.7
152    """
153    if isinstance(value, string_types) or not isinstance(value, abc.Iterable):
154        return unicode_urlencode(value)
155
156    if isinstance(value, dict):
157        items = iteritems(value)
158    else:
159        items = iter(value)
160
161    return u"&".join(
162        "%s=%s" % (unicode_urlencode(k, for_qs=True), unicode_urlencode(v, for_qs=True))
163        for k, v in items
164    )
165
166
167@evalcontextfilter
168def do_replace(eval_ctx, s, old, new, count=None):
169    """Return a copy of the value with all occurrences of a substring
170    replaced with a new one. The first argument is the substring
171    that should be replaced, the second is the replacement string.
172    If the optional third argument ``count`` is given, only the first
173    ``count`` occurrences are replaced:
174
175    .. sourcecode:: jinja
176
177        {{ "Hello World"|replace("Hello", "Goodbye") }}
178            -> Goodbye World
179
180        {{ "aaaaargh"|replace("a", "d'oh, ", 2) }}
181            -> d'oh, d'oh, aaargh
182    """
183    if count is None:
184        count = -1
185    if not eval_ctx.autoescape:
186        return text_type(s).replace(text_type(old), text_type(new), count)
187    if (
188        hasattr(old, "__html__")
189        or hasattr(new, "__html__")
190        and not hasattr(s, "__html__")
191    ):
192        s = escape(s)
193    else:
194        s = soft_unicode(s)
195    return s.replace(soft_unicode(old), soft_unicode(new), count)
196
197
198def do_upper(s):
199    """Convert a value to uppercase."""
200    return soft_unicode(s).upper()
201
202
203def do_lower(s):
204    """Convert a value to lowercase."""
205    return soft_unicode(s).lower()
206
207
208@evalcontextfilter
209def do_xmlattr(_eval_ctx, d, autospace=True):
210    """Create an SGML/XML attribute string based on the items in a dict.
211    All values that are neither `none` nor `undefined` are automatically
212    escaped:
213
214    .. sourcecode:: html+jinja
215
216        <ul{{ {'class': 'my_list', 'missing': none,
217                'id': 'list-%d'|format(variable)}|xmlattr }}>
218        ...
219        </ul>
220
221    Results in something like this:
222
223    .. sourcecode:: html
224
225        <ul class="my_list" id="list-42">
226        ...
227        </ul>
228
229    As you can see it automatically prepends a space in front of the item
230    if the filter returned something unless the second parameter is false.
231    """
232    rv = u" ".join(
233        u'%s="%s"' % (escape(key), escape(value))
234        for key, value in iteritems(d)
235        if value is not None and not isinstance(value, Undefined)
236    )
237    if autospace and rv:
238        rv = u" " + rv
239    if _eval_ctx.autoescape:
240        rv = Markup(rv)
241    return rv
242
243
244def do_capitalize(s):
245    """Capitalize a value. The first character will be uppercase, all others
246    lowercase.
247    """
248    return soft_unicode(s).capitalize()
249
250
251def do_title(s):
252    """Return a titlecased version of the value. I.e. words will start with
253    uppercase letters, all remaining characters are lowercase.
254    """
255    return "".join(
256        [
257            item[0].upper() + item[1:].lower()
258            for item in _word_beginning_split_re.split(soft_unicode(s))
259            if item
260        ]
261    )
262
263
264def do_dictsort(value, case_sensitive=False, by="key", reverse=False):
265    """Sort a dict and yield (key, value) pairs. Because python dicts are
266    unsorted you may want to use this function to order them by either
267    key or value:
268
269    .. sourcecode:: jinja
270
271        {% for item in mydict|dictsort %}
272            sort the dict by key, case insensitive
273
274        {% for item in mydict|dictsort(reverse=true) %}
275            sort the dict by key, case insensitive, reverse order
276
277        {% for item in mydict|dictsort(true) %}
278            sort the dict by key, case sensitive
279
280        {% for item in mydict|dictsort(false, 'value') %}
281            sort the dict by value, case insensitive
282    """
283    if by == "key":
284        pos = 0
285    elif by == "value":
286        pos = 1
287    else:
288        raise FilterArgumentError('You can only sort by either "key" or "value"')
289
290    def sort_func(item):
291        value = item[pos]
292
293        if not case_sensitive:
294            value = ignore_case(value)
295
296        return value
297
298    return sorted(value.items(), key=sort_func, reverse=reverse)
299
300
301@environmentfilter
302def do_sort(environment, value, reverse=False, case_sensitive=False, attribute=None):
303    """Sort an iterable using Python's :func:`sorted`.
304
305    .. sourcecode:: jinja
306
307        {% for city in cities|sort %}
308            ...
309        {% endfor %}
310
311    :param reverse: Sort descending instead of ascending.
312    :param case_sensitive: When sorting strings, sort upper and lower
313        case separately.
314    :param attribute: When sorting objects or dicts, an attribute or
315        key to sort by. Can use dot notation like ``"address.city"``.
316        Can be a list of attributes like ``"age,name"``.
317
318    The sort is stable, it does not change the relative order of
319    elements that compare equal. This makes it is possible to chain
320    sorts on different attributes and ordering.
321
322    .. sourcecode:: jinja
323
324        {% for user in users|sort(attribute="name")
325            |sort(reverse=true, attribute="age") %}
326            ...
327        {% endfor %}
328
329    As a shortcut to chaining when the direction is the same for all
330    attributes, pass a comma separate list of attributes.
331
332    .. sourcecode:: jinja
333
334        {% for user users|sort(attribute="age,name") %}
335            ...
336        {% endfor %}
337
338    .. versionchanged:: 2.11.0
339        The ``attribute`` parameter can be a comma separated list of
340        attributes, e.g. ``"age,name"``.
341
342    .. versionchanged:: 2.6
343       The ``attribute`` parameter was added.
344    """
345    key_func = make_multi_attrgetter(
346        environment, attribute, postprocess=ignore_case if not case_sensitive else None
347    )
348    return sorted(value, key=key_func, reverse=reverse)
349
350
351@environmentfilter
352def do_unique(environment, value, case_sensitive=False, attribute=None):
353    """Returns a list of unique items from the given iterable.
354
355    .. sourcecode:: jinja
356
357        {{ ['foo', 'bar', 'foobar', 'FooBar']|unique|list }}
358            -> ['foo', 'bar', 'foobar']
359
360    The unique items are yielded in the same order as their first occurrence in
361    the iterable passed to the filter.
362
363    :param case_sensitive: Treat upper and lower case strings as distinct.
364    :param attribute: Filter objects with unique values for this attribute.
365    """
366    getter = make_attrgetter(
367        environment, attribute, postprocess=ignore_case if not case_sensitive else None
368    )
369    seen = set()
370
371    for item in value:
372        key = getter(item)
373
374        if key not in seen:
375            seen.add(key)
376            yield item
377
378
379def _min_or_max(environment, value, func, case_sensitive, attribute):
380    it = iter(value)
381
382    try:
383        first = next(it)
384    except StopIteration:
385        return environment.undefined("No aggregated item, sequence was empty.")
386
387    key_func = make_attrgetter(
388        environment, attribute, postprocess=ignore_case if not case_sensitive else None
389    )
390    return func(chain([first], it), key=key_func)
391
392
393@environmentfilter
394def do_min(environment, value, case_sensitive=False, attribute=None):
395    """Return the smallest item from the sequence.
396
397    .. sourcecode:: jinja
398
399        {{ [1, 2, 3]|min }}
400            -> 1
401
402    :param case_sensitive: Treat upper and lower case strings as distinct.
403    :param attribute: Get the object with the min value of this attribute.
404    """
405    return _min_or_max(environment, value, min, case_sensitive, attribute)
406
407
408@environmentfilter
409def do_max(environment, value, case_sensitive=False, attribute=None):
410    """Return the largest item from the sequence.
411
412    .. sourcecode:: jinja
413
414        {{ [1, 2, 3]|max }}
415            -> 3
416
417    :param case_sensitive: Treat upper and lower case strings as distinct.
418    :param attribute: Get the object with the max value of this attribute.
419    """
420    return _min_or_max(environment, value, max, case_sensitive, attribute)
421
422
423def do_default(value, default_value=u"", boolean=False):
424    """If the value is undefined it will return the passed default value,
425    otherwise the value of the variable:
426
427    .. sourcecode:: jinja
428
429        {{ my_variable|default('my_variable is not defined') }}
430
431    This will output the value of ``my_variable`` if the variable was
432    defined, otherwise ``'my_variable is not defined'``. If you want
433    to use default with variables that evaluate to false you have to
434    set the second parameter to `true`:
435
436    .. sourcecode:: jinja
437
438        {{ ''|default('the string was empty', true) }}
439
440    .. versionchanged:: 2.11
441       It's now possible to configure the :class:`~jinja2.Environment` with
442       :class:`~jinja2.ChainableUndefined` to make the `default` filter work
443       on nested elements and attributes that may contain undefined values
444       in the chain without getting an :exc:`~jinja2.UndefinedError`.
445    """
446    if isinstance(value, Undefined) or (boolean and not value):
447        return default_value
448    return value
449
450
451@evalcontextfilter
452def do_join(eval_ctx, value, d=u"", attribute=None):
453    """Return a string which is the concatenation of the strings in the
454    sequence. The separator between elements is an empty string per
455    default, you can define it with the optional parameter:
456
457    .. sourcecode:: jinja
458
459        {{ [1, 2, 3]|join('|') }}
460            -> 1|2|3
461
462        {{ [1, 2, 3]|join }}
463            -> 123
464
465    It is also possible to join certain attributes of an object:
466
467    .. sourcecode:: jinja
468
469        {{ users|join(', ', attribute='username') }}
470
471    .. versionadded:: 2.6
472       The `attribute` parameter was added.
473    """
474    if attribute is not None:
475        value = imap(make_attrgetter(eval_ctx.environment, attribute), value)
476
477    # no automatic escaping?  joining is a lot easier then
478    if not eval_ctx.autoescape:
479        return text_type(d).join(imap(text_type, value))
480
481    # if the delimiter doesn't have an html representation we check
482    # if any of the items has.  If yes we do a coercion to Markup
483    if not hasattr(d, "__html__"):
484        value = list(value)
485        do_escape = False
486        for idx, item in enumerate(value):
487            if hasattr(item, "__html__"):
488                do_escape = True
489            else:
490                value[idx] = text_type(item)
491        if do_escape:
492            d = escape(d)
493        else:
494            d = text_type(d)
495        return d.join(value)
496
497    # no html involved, to normal joining
498    return soft_unicode(d).join(imap(soft_unicode, value))
499
500
501def do_center(value, width=80):
502    """Centers the value in a field of a given width."""
503    return text_type(value).center(width)
504
505
506@environmentfilter
507def do_first(environment, seq):
508    """Return the first item of a sequence."""
509    try:
510        return next(iter(seq))
511    except StopIteration:
512        return environment.undefined("No first item, sequence was empty.")
513
514
515@environmentfilter
516def do_last(environment, seq):
517    """
518    Return the last item of a sequence.
519
520    Note: Does not work with generators. You may want to explicitly
521    convert it to a list:
522
523    .. sourcecode:: jinja
524
525        {{ data | selectattr('name', '==', 'Jinja') | list | last }}
526    """
527    try:
528        return next(iter(reversed(seq)))
529    except StopIteration:
530        return environment.undefined("No last item, sequence was empty.")
531
532
533@contextfilter
534def do_random(context, seq):
535    """Return a random item from the sequence."""
536    try:
537        return random.choice(seq)
538    except IndexError:
539        return context.environment.undefined("No random item, sequence was empty.")
540
541
542def do_filesizeformat(value, binary=False):
543    """Format the value like a 'human-readable' file size (i.e. 13 kB,
544    4.1 MB, 102 Bytes, etc).  Per default decimal prefixes are used (Mega,
545    Giga, etc.), if the second parameter is set to `True` the binary
546    prefixes are used (Mebi, Gibi).
547    """
548    bytes = float(value)
549    base = binary and 1024 or 1000
550    prefixes = [
551        (binary and "KiB" or "kB"),
552        (binary and "MiB" or "MB"),
553        (binary and "GiB" or "GB"),
554        (binary and "TiB" or "TB"),
555        (binary and "PiB" or "PB"),
556        (binary and "EiB" or "EB"),
557        (binary and "ZiB" or "ZB"),
558        (binary and "YiB" or "YB"),
559    ]
560    if bytes == 1:
561        return "1 Byte"
562    elif bytes < base:
563        return "%d Bytes" % bytes
564    else:
565        for i, prefix in enumerate(prefixes):
566            unit = base ** (i + 2)
567            if bytes < unit:
568                return "%.1f %s" % ((base * bytes / unit), prefix)
569        return "%.1f %s" % ((base * bytes / unit), prefix)
570
571
572def do_pprint(value, verbose=False):
573    """Pretty print a variable. Useful for debugging.
574
575    With Jinja 1.2 onwards you can pass it a parameter.  If this parameter
576    is truthy the output will be more verbose (this requires `pretty`)
577    """
578    return pformat(value, verbose=verbose)
579
580
581@evalcontextfilter
582def do_urlize(
583    eval_ctx, value, trim_url_limit=None, nofollow=False, target=None, rel=None
584):
585    """Converts URLs in plain text into clickable links.
586
587    If you pass the filter an additional integer it will shorten the urls
588    to that number. Also a third argument exists that makes the urls
589    "nofollow":
590
591    .. sourcecode:: jinja
592
593        {{ mytext|urlize(40, true) }}
594            links are shortened to 40 chars and defined with rel="nofollow"
595
596    If *target* is specified, the ``target`` attribute will be added to the
597    ``<a>`` tag:
598
599    .. sourcecode:: jinja
600
601       {{ mytext|urlize(40, target='_blank') }}
602
603    .. versionchanged:: 2.8+
604       The *target* parameter was added.
605    """
606    policies = eval_ctx.environment.policies
607    rel = set((rel or "").split() or [])
608    if nofollow:
609        rel.add("nofollow")
610    rel.update((policies["urlize.rel"] or "").split())
611    if target is None:
612        target = policies["urlize.target"]
613    rel = " ".join(sorted(rel)) or None
614    rv = urlize(value, trim_url_limit, rel=rel, target=target)
615    if eval_ctx.autoescape:
616        rv = Markup(rv)
617    return rv
618
619
620def do_indent(s, width=4, first=False, blank=False, indentfirst=None):
621    """Return a copy of the string with each line indented by 4 spaces. The
622    first line and blank lines are not indented by default.
623
624    :param width: Number of spaces to indent by.
625    :param first: Don't skip indenting the first line.
626    :param blank: Don't skip indenting empty lines.
627
628    .. versionchanged:: 2.10
629        Blank lines are not indented by default.
630
631        Rename the ``indentfirst`` argument to ``first``.
632    """
633    if indentfirst is not None:
634        warnings.warn(
635            "The 'indentfirst' argument is renamed to 'first' and will"
636            " be removed in version 3.0.",
637            DeprecationWarning,
638            stacklevel=2,
639        )
640        first = indentfirst
641
642    indention = u" " * width
643    newline = u"\n"
644
645    if isinstance(s, Markup):
646        indention = Markup(indention)
647        newline = Markup(newline)
648
649    s += newline  # this quirk is necessary for splitlines method
650
651    if blank:
652        rv = (newline + indention).join(s.splitlines())
653    else:
654        lines = s.splitlines()
655        rv = lines.pop(0)
656
657        if lines:
658            rv += newline + newline.join(
659                indention + line if line else line for line in lines
660            )
661
662    if first:
663        rv = indention + rv
664
665    return rv
666
667
668@environmentfilter
669def do_truncate(env, s, length=255, killwords=False, end="...", leeway=None):
670    """Return a truncated copy of the string. The length is specified
671    with the first parameter which defaults to ``255``. If the second
672    parameter is ``true`` the filter will cut the text at length. Otherwise
673    it will discard the last word. If the text was in fact
674    truncated it will append an ellipsis sign (``"..."``). If you want a
675    different ellipsis sign than ``"..."`` you can specify it using the
676    third parameter. Strings that only exceed the length by the tolerance
677    margin given in the fourth parameter will not be truncated.
678
679    .. sourcecode:: jinja
680
681        {{ "foo bar baz qux"|truncate(9) }}
682            -> "foo..."
683        {{ "foo bar baz qux"|truncate(9, True) }}
684            -> "foo ba..."
685        {{ "foo bar baz qux"|truncate(11) }}
686            -> "foo bar baz qux"
687        {{ "foo bar baz qux"|truncate(11, False, '...', 0) }}
688            -> "foo bar..."
689
690    The default leeway on newer Jinja versions is 5 and was 0 before but
691    can be reconfigured globally.
692    """
693    if leeway is None:
694        leeway = env.policies["truncate.leeway"]
695    assert length >= len(end), "expected length >= %s, got %s" % (len(end), length)
696    assert leeway >= 0, "expected leeway >= 0, got %s" % leeway
697    if len(s) <= length + leeway:
698        return s
699    if killwords:
700        return s[: length - len(end)] + end
701    result = s[: length - len(end)].rsplit(" ", 1)[0]
702    return result + end
703
704
705@environmentfilter
706def do_wordwrap(
707    environment,
708    s,
709    width=79,
710    break_long_words=True,
711    wrapstring=None,
712    break_on_hyphens=True,
713):
714    """Wrap a string to the given width. Existing newlines are treated
715    as paragraphs to be wrapped separately.
716
717    :param s: Original text to wrap.
718    :param width: Maximum length of wrapped lines.
719    :param break_long_words: If a word is longer than ``width``, break
720        it across lines.
721    :param break_on_hyphens: If a word contains hyphens, it may be split
722        across lines.
723    :param wrapstring: String to join each wrapped line. Defaults to
724        :attr:`Environment.newline_sequence`.
725
726    .. versionchanged:: 2.11
727        Existing newlines are treated as paragraphs wrapped separately.
728
729    .. versionchanged:: 2.11
730        Added the ``break_on_hyphens`` parameter.
731
732    .. versionchanged:: 2.7
733        Added the ``wrapstring`` parameter.
734    """
735
736    import textwrap
737
738    if not wrapstring:
739        wrapstring = environment.newline_sequence
740
741    # textwrap.wrap doesn't consider existing newlines when wrapping.
742    # If the string has a newline before width, wrap will still insert
743    # a newline at width, resulting in a short line. Instead, split and
744    # wrap each paragraph individually.
745    return wrapstring.join(
746        [
747            wrapstring.join(
748                textwrap.wrap(
749                    line,
750                    width=width,
751                    expand_tabs=False,
752                    replace_whitespace=False,
753                    break_long_words=break_long_words,
754                    break_on_hyphens=break_on_hyphens,
755                )
756            )
757            for line in s.splitlines()
758        ]
759    )
760
761
762def do_wordcount(s):
763    """Count the words in that string."""
764    return len(_word_re.findall(soft_unicode(s)))
765
766
767def do_int(value, default=0, base=10):
768    """Convert the value into an integer. If the
769    conversion doesn't work it will return ``0``. You can
770    override this default using the first parameter. You
771    can also override the default base (10) in the second
772    parameter, which handles input with prefixes such as
773    0b, 0o and 0x for bases 2, 8 and 16 respectively.
774    The base is ignored for decimal numbers and non-string values.
775    """
776    try:
777        if isinstance(value, string_types):
778            return int(value, base)
779        return int(value)
780    except (TypeError, ValueError):
781        # this quirk is necessary so that "42.23"|int gives 42.
782        try:
783            return int(float(value))
784        except (TypeError, ValueError):
785            return default
786
787
788def do_float(value, default=0.0):
789    """Convert the value into a floating point number. If the
790    conversion doesn't work it will return ``0.0``. You can
791    override this default using the first parameter.
792    """
793    try:
794        return float(value)
795    except (TypeError, ValueError):
796        return default
797
798
799def do_format(value, *args, **kwargs):
800    """Apply the given values to a `printf-style`_ format string, like
801    ``string % values``.
802
803    .. sourcecode:: jinja
804
805        {{ "%s, %s!"|format(greeting, name) }}
806        Hello, World!
807
808    In most cases it should be more convenient and efficient to use the
809    ``%`` operator or :meth:`str.format`.
810
811    .. code-block:: text
812
813        {{ "%s, %s!" % (greeting, name) }}
814        {{ "{}, {}!".format(greeting, name) }}
815
816    .. _printf-style: https://docs.python.org/library/stdtypes.html
817        #printf-style-string-formatting
818    """
819    if args and kwargs:
820        raise FilterArgumentError(
821            "can't handle positional and keyword arguments at the same time"
822        )
823    return soft_unicode(value) % (kwargs or args)
824
825
826def do_trim(value, chars=None):
827    """Strip leading and trailing characters, by default whitespace."""
828    return soft_unicode(value).strip(chars)
829
830
831def do_striptags(value):
832    """Strip SGML/XML tags and replace adjacent whitespace by one space."""
833    if hasattr(value, "__html__"):
834        value = value.__html__()
835    return Markup(text_type(value)).striptags()
836
837
838def do_slice(value, slices, fill_with=None):
839    """Slice an iterator and return a list of lists containing
840    those items. Useful if you want to create a div containing
841    three ul tags that represent columns:
842
843    .. sourcecode:: html+jinja
844
845        <div class="columnwrapper">
846          {%- for column in items|slice(3) %}
847            <ul class="column-{{ loop.index }}">
848            {%- for item in column %}
849              <li>{{ item }}</li>
850            {%- endfor %}
851            </ul>
852          {%- endfor %}
853        </div>
854
855    If you pass it a second argument it's used to fill missing
856    values on the last iteration.
857    """
858    seq = list(value)
859    length = len(seq)
860    items_per_slice = length // slices
861    slices_with_extra = length % slices
862    offset = 0
863    for slice_number in range(slices):
864        start = offset + slice_number * items_per_slice
865        if slice_number < slices_with_extra:
866            offset += 1
867        end = offset + (slice_number + 1) * items_per_slice
868        tmp = seq[start:end]
869        if fill_with is not None and slice_number >= slices_with_extra:
870            tmp.append(fill_with)
871        yield tmp
872
873
874def do_batch(value, linecount, fill_with=None):
875    """
876    A filter that batches items. It works pretty much like `slice`
877    just the other way round. It returns a list of lists with the
878    given number of items. If you provide a second parameter this
879    is used to fill up missing items. See this example:
880
881    .. sourcecode:: html+jinja
882
883        <table>
884        {%- for row in items|batch(3, '&nbsp;') %}
885          <tr>
886          {%- for column in row %}
887            <td>{{ column }}</td>
888          {%- endfor %}
889          </tr>
890        {%- endfor %}
891        </table>
892    """
893    tmp = []
894    for item in value:
895        if len(tmp) == linecount:
896            yield tmp
897            tmp = []
898        tmp.append(item)
899    if tmp:
900        if fill_with is not None and len(tmp) < linecount:
901            tmp += [fill_with] * (linecount - len(tmp))
902        yield tmp
903
904
905def do_round(value, precision=0, method="common"):
906    """Round the number to a given precision. The first
907    parameter specifies the precision (default is ``0``), the
908    second the rounding method:
909
910    - ``'common'`` rounds either up or down
911    - ``'ceil'`` always rounds up
912    - ``'floor'`` always rounds down
913
914    If you don't specify a method ``'common'`` is used.
915
916    .. sourcecode:: jinja
917
918        {{ 42.55|round }}
919            -> 43.0
920        {{ 42.55|round(1, 'floor') }}
921            -> 42.5
922
923    Note that even if rounded to 0 precision, a float is returned.  If
924    you need a real integer, pipe it through `int`:
925
926    .. sourcecode:: jinja
927
928        {{ 42.55|round|int }}
929            -> 43
930    """
931    if method not in {"common", "ceil", "floor"}:
932        raise FilterArgumentError("method must be common, ceil or floor")
933    if method == "common":
934        return round(value, precision)
935    func = getattr(math, method)
936    return func(value * (10 ** precision)) / (10 ** precision)
937
938
939# Use a regular tuple repr here.  This is what we did in the past and we
940# really want to hide this custom type as much as possible.  In particular
941# we do not want to accidentally expose an auto generated repr in case
942# people start to print this out in comments or something similar for
943# debugging.
944_GroupTuple = namedtuple("_GroupTuple", ["grouper", "list"])
945_GroupTuple.__repr__ = tuple.__repr__
946_GroupTuple.__str__ = tuple.__str__
947
948
949@environmentfilter
950def do_groupby(environment, value, attribute):
951    """Group a sequence of objects by an attribute using Python's
952    :func:`itertools.groupby`. The attribute can use dot notation for
953    nested access, like ``"address.city"``. Unlike Python's ``groupby``,
954    the values are sorted first so only one group is returned for each
955    unique value.
956
957    For example, a list of ``User`` objects with a ``city`` attribute
958    can be rendered in groups. In this example, ``grouper`` refers to
959    the ``city`` value of the group.
960
961    .. sourcecode:: html+jinja
962
963        <ul>{% for city, items in users|groupby("city") %}
964          <li>{{ city }}
965            <ul>{% for user in items %}
966              <li>{{ user.name }}
967            {% endfor %}</ul>
968          </li>
969        {% endfor %}</ul>
970
971    ``groupby`` yields namedtuples of ``(grouper, list)``, which
972    can be used instead of the tuple unpacking above. ``grouper`` is the
973    value of the attribute, and ``list`` is the items with that value.
974
975    .. sourcecode:: html+jinja
976
977        <ul>{% for group in users|groupby("city") %}
978          <li>{{ group.grouper }}: {{ group.list|join(", ") }}
979        {% endfor %}</ul>
980
981    .. versionchanged:: 2.6
982        The attribute supports dot notation for nested access.
983    """
984    expr = make_attrgetter(environment, attribute)
985    return [
986        _GroupTuple(key, list(values))
987        for key, values in groupby(sorted(value, key=expr), expr)
988    ]
989
990
991@environmentfilter
992def do_sum(environment, iterable, attribute=None, start=0):
993    """Returns the sum of a sequence of numbers plus the value of parameter
994    'start' (which defaults to 0).  When the sequence is empty it returns
995    start.
996
997    It is also possible to sum up only certain attributes:
998
999    .. sourcecode:: jinja
1000
1001        Total: {{ items|sum(attribute='price') }}
1002
1003    .. versionchanged:: 2.6
1004       The `attribute` parameter was added to allow suming up over
1005       attributes.  Also the `start` parameter was moved on to the right.
1006    """
1007    if attribute is not None:
1008        iterable = imap(make_attrgetter(environment, attribute), iterable)
1009    return sum(iterable, start)
1010
1011
1012def do_list(value):
1013    """Convert the value into a list.  If it was a string the returned list
1014    will be a list of characters.
1015    """
1016    return list(value)
1017
1018
1019def do_mark_safe(value):
1020    """Mark the value as safe which means that in an environment with automatic
1021    escaping enabled this variable will not be escaped.
1022    """
1023    return Markup(value)
1024
1025
1026def do_mark_unsafe(value):
1027    """Mark a value as unsafe.  This is the reverse operation for :func:`safe`."""
1028    return text_type(value)
1029
1030
1031def do_reverse(value):
1032    """Reverse the object or return an iterator that iterates over it the other
1033    way round.
1034    """
1035    if isinstance(value, string_types):
1036        return value[::-1]
1037    try:
1038        return reversed(value)
1039    except TypeError:
1040        try:
1041            rv = list(value)
1042            rv.reverse()
1043            return rv
1044        except TypeError:
1045            raise FilterArgumentError("argument must be iterable")
1046
1047
1048@environmentfilter
1049def do_attr(environment, obj, name):
1050    """Get an attribute of an object.  ``foo|attr("bar")`` works like
1051    ``foo.bar`` just that always an attribute is returned and items are not
1052    looked up.
1053
1054    See :ref:`Notes on subscriptions <notes-on-subscriptions>` for more details.
1055    """
1056    try:
1057        name = str(name)
1058    except UnicodeError:
1059        pass
1060    else:
1061        try:
1062            value = getattr(obj, name)
1063        except AttributeError:
1064            pass
1065        else:
1066            if environment.sandboxed and not environment.is_safe_attribute(
1067                obj, name, value
1068            ):
1069                return environment.unsafe_undefined(obj, name)
1070            return value
1071    return environment.undefined(obj=obj, name=name)
1072
1073
1074@contextfilter
1075def do_map(*args, **kwargs):
1076    """Applies a filter on a sequence of objects or looks up an attribute.
1077    This is useful when dealing with lists of objects but you are really
1078    only interested in a certain value of it.
1079
1080    The basic usage is mapping on an attribute.  Imagine you have a list
1081    of users but you are only interested in a list of usernames:
1082
1083    .. sourcecode:: jinja
1084
1085        Users on this page: {{ users|map(attribute='username')|join(', ') }}
1086
1087    You can specify a ``default`` value to use if an object in the list
1088    does not have the given attribute.
1089
1090    .. sourcecode:: jinja
1091
1092        {{ users|map(attribute="username", default="Anonymous")|join(", ") }}
1093
1094    Alternatively you can let it invoke a filter by passing the name of the
1095    filter and the arguments afterwards.  A good example would be applying a
1096    text conversion filter on a sequence:
1097
1098    .. sourcecode:: jinja
1099
1100        Users on this page: {{ titles|map('lower')|join(', ') }}
1101
1102    Similar to a generator comprehension such as:
1103
1104    .. code-block:: python
1105
1106        (u.username for u in users)
1107        (u.username or "Anonymous" for u in users)
1108        (do_lower(x) for x in titles)
1109
1110    .. versionchanged:: 2.11.0
1111        Added the ``default`` parameter.
1112
1113    .. versionadded:: 2.7
1114    """
1115    seq, func = prepare_map(args, kwargs)
1116    if seq:
1117        for item in seq:
1118            yield func(item)
1119
1120
1121@contextfilter
1122def do_select(*args, **kwargs):
1123    """Filters a sequence of objects by applying a test to each object,
1124    and only selecting the objects with the test succeeding.
1125
1126    If no test is specified, each object will be evaluated as a boolean.
1127
1128    Example usage:
1129
1130    .. sourcecode:: jinja
1131
1132        {{ numbers|select("odd") }}
1133        {{ numbers|select("odd") }}
1134        {{ numbers|select("divisibleby", 3) }}
1135        {{ numbers|select("lessthan", 42) }}
1136        {{ strings|select("equalto", "mystring") }}
1137
1138    Similar to a generator comprehension such as:
1139
1140    .. code-block:: python
1141
1142        (n for n in numbers if test_odd(n))
1143        (n for n in numbers if test_divisibleby(n, 3))
1144
1145    .. versionadded:: 2.7
1146    """
1147    return select_or_reject(args, kwargs, lambda x: x, False)
1148
1149
1150@contextfilter
1151def do_reject(*args, **kwargs):
1152    """Filters a sequence of objects by applying a test to each object,
1153    and rejecting the objects with the test succeeding.
1154
1155    If no test is specified, each object will be evaluated as a boolean.
1156
1157    Example usage:
1158
1159    .. sourcecode:: jinja
1160
1161        {{ numbers|reject("odd") }}
1162
1163    Similar to a generator comprehension such as:
1164
1165    .. code-block:: python
1166
1167        (n for n in numbers if not test_odd(n))
1168
1169    .. versionadded:: 2.7
1170    """
1171    return select_or_reject(args, kwargs, lambda x: not x, False)
1172
1173
1174@contextfilter
1175def do_selectattr(*args, **kwargs):
1176    """Filters a sequence of objects by applying a test to the specified
1177    attribute of each object, and only selecting the objects with the
1178    test succeeding.
1179
1180    If no test is specified, the attribute's value will be evaluated as
1181    a boolean.
1182
1183    Example usage:
1184
1185    .. sourcecode:: jinja
1186
1187        {{ users|selectattr("is_active") }}
1188        {{ users|selectattr("email", "none") }}
1189
1190    Similar to a generator comprehension such as:
1191
1192    .. code-block:: python
1193
1194        (u for user in users if user.is_active)
1195        (u for user in users if test_none(user.email))
1196
1197    .. versionadded:: 2.7
1198    """
1199    return select_or_reject(args, kwargs, lambda x: x, True)
1200
1201
1202@contextfilter
1203def do_rejectattr(*args, **kwargs):
1204    """Filters a sequence of objects by applying a test to the specified
1205    attribute of each object, and rejecting the objects with the test
1206    succeeding.
1207
1208    If no test is specified, the attribute's value will be evaluated as
1209    a boolean.
1210
1211    .. sourcecode:: jinja
1212
1213        {{ users|rejectattr("is_active") }}
1214        {{ users|rejectattr("email", "none") }}
1215
1216    Similar to a generator comprehension such as:
1217
1218    .. code-block:: python
1219
1220        (u for user in users if not user.is_active)
1221        (u for user in users if not test_none(user.email))
1222
1223    .. versionadded:: 2.7
1224    """
1225    return select_or_reject(args, kwargs, lambda x: not x, True)
1226
1227
1228@evalcontextfilter
1229def do_tojson(eval_ctx, value, indent=None):
1230    """Dumps a structure to JSON so that it's safe to use in ``<script>``
1231    tags.  It accepts the same arguments and returns a JSON string.  Note that
1232    this is available in templates through the ``|tojson`` filter which will
1233    also mark the result as safe.  Due to how this function escapes certain
1234    characters this is safe even if used outside of ``<script>`` tags.
1235
1236    The following characters are escaped in strings:
1237
1238    -   ``<``
1239    -   ``>``
1240    -   ``&``
1241    -   ``'``
1242
1243    This makes it safe to embed such strings in any place in HTML with the
1244    notable exception of double quoted attributes.  In that case single
1245    quote your attributes or HTML escape it in addition.
1246
1247    The indent parameter can be used to enable pretty printing.  Set it to
1248    the number of spaces that the structures should be indented with.
1249
1250    Note that this filter is for use in HTML contexts only.
1251
1252    .. versionadded:: 2.9
1253    """
1254    policies = eval_ctx.environment.policies
1255    dumper = policies["json.dumps_function"]
1256    options = policies["json.dumps_kwargs"]
1257    if indent is not None:
1258        options = dict(options)
1259        options["indent"] = indent
1260    return htmlsafe_json_dumps(value, dumper=dumper, **options)
1261
1262
1263def prepare_map(args, kwargs):
1264    context = args[0]
1265    seq = args[1]
1266    default = None
1267
1268    if len(args) == 2 and "attribute" in kwargs:
1269        attribute = kwargs.pop("attribute")
1270        default = kwargs.pop("default", None)
1271        if kwargs:
1272            raise FilterArgumentError(
1273                "Unexpected keyword argument %r" % next(iter(kwargs))
1274            )
1275        func = make_attrgetter(context.environment, attribute, default=default)
1276    else:
1277        try:
1278            name = args[2]
1279            args = args[3:]
1280        except LookupError:
1281            raise FilterArgumentError("map requires a filter argument")
1282
1283        def func(item):
1284            return context.environment.call_filter(
1285                name, item, args, kwargs, context=context
1286            )
1287
1288    return seq, func
1289
1290
1291def prepare_select_or_reject(args, kwargs, modfunc, lookup_attr):
1292    context = args[0]
1293    seq = args[1]
1294    if lookup_attr:
1295        try:
1296            attr = args[2]
1297        except LookupError:
1298            raise FilterArgumentError("Missing parameter for attribute name")
1299        transfunc = make_attrgetter(context.environment, attr)
1300        off = 1
1301    else:
1302        off = 0
1303
1304        def transfunc(x):
1305            return x
1306
1307    try:
1308        name = args[2 + off]
1309        args = args[3 + off :]
1310
1311        def func(item):
1312            return context.environment.call_test(name, item, args, kwargs)
1313
1314    except LookupError:
1315        func = bool
1316
1317    return seq, lambda item: modfunc(func(transfunc(item)))
1318
1319
1320def select_or_reject(args, kwargs, modfunc, lookup_attr):
1321    seq, func = prepare_select_or_reject(args, kwargs, modfunc, lookup_attr)
1322    if seq:
1323        for item in seq:
1324            if func(item):
1325                yield item
1326
1327
1328FILTERS = {
1329    "abs": abs,
1330    "attr": do_attr,
1331    "batch": do_batch,
1332    "capitalize": do_capitalize,
1333    "center": do_center,
1334    "count": len,
1335    "d": do_default,
1336    "default": do_default,
1337    "dictsort": do_dictsort,
1338    "e": escape,
1339    "escape": escape,
1340    "filesizeformat": do_filesizeformat,
1341    "first": do_first,
1342    "float": do_float,
1343    "forceescape": do_forceescape,
1344    "format": do_format,
1345    "groupby": do_groupby,
1346    "indent": do_indent,
1347    "int": do_int,
1348    "join": do_join,
1349    "last": do_last,
1350    "length": len,
1351    "list": do_list,
1352    "lower": do_lower,
1353    "map": do_map,
1354    "min": do_min,
1355    "max": do_max,
1356    "pprint": do_pprint,
1357    "random": do_random,
1358    "reject": do_reject,
1359    "rejectattr": do_rejectattr,
1360    "replace": do_replace,
1361    "reverse": do_reverse,
1362    "round": do_round,
1363    "safe": do_mark_safe,
1364    "select": do_select,
1365    "selectattr": do_selectattr,
1366    "slice": do_slice,
1367    "sort": do_sort,
1368    "string": soft_unicode,
1369    "striptags": do_striptags,
1370    "sum": do_sum,
1371    "title": do_title,
1372    "trim": do_trim,
1373    "truncate": do_truncate,
1374    "unique": do_unique,
1375    "upper": do_upper,
1376    "urlencode": do_urlencode,
1377    "urlize": do_urlize,
1378    "wordcount": do_wordcount,
1379    "wordwrap": do_wordwrap,
1380    "xmlattr": do_xmlattr,
1381    "tojson": do_tojson,
1382}
1383