1 /**
2   * Description of global filters
3   *
4   * Copyright:
5   *     Copyright (c) 2018, Maxim Tyapkin.
6   * Authors:
7   *     Maxim Tyapkin
8   * License:
9   *     This software is licensed under the terms of the BSD 3-clause license.
10   *     The full terms of the license can be found in the LICENSE.md file.
11   */
12 
13 module djinja.algo.filters;
14 
15 private
16 {
17     import djinja.algo.wrapper;
18     import djinja.uninode;
19 }
20 
21 
22 Function[string] globalFilters()
23 {
24     return cast(immutable)
25         [
26             "default": wrapper!defaultVal,
27             "d":       wrapper!defaultVal,
28             "escape":  wrapper!escape,
29             "e":       wrapper!escape,
30             "upper":   wrapper!upper,
31             "sort":    wrapper!sort,
32             "keys":    wrapper!keys,
33         ];
34 }
35 
36 
37 UniNode defaultVal(UniNode value, UniNode default_value = UniNode(""), bool boolean = false)
38 {
39     if (value.kind == UniNode.Kind.nil)
40         return default_value;
41 
42     if (!boolean)
43         return value;
44 
45     value.toBoolType;
46     if (!value.get!bool)
47         return default_value;
48 
49     return value;
50 }
51 
52 
53 string escape(string s)
54 {
55     import std.array : appender;
56 
57     auto w = appender!string;
58     w.reserve(s.length);
59 
60     foreach (char ch; s)
61         switch (ch)
62         {
63             case '&':  w.put("&");  break;
64             case '\"': w.put("""); break;
65             case '\'': w.put("'"); break;
66             case '<':  w.put("&lt;");   break;
67             case '>':  w.put("&gt;");   break;
68             default:   w.put(ch);       break;
69         }
70 
71     return w.data;
72 }
73 
74 
75 string upper(string str)
76 {
77     import std.uni : toUpper;
78     return str.toUpper;
79 }
80 
81 
82 UniNode sort(UniNode value)
83 {
84     import std.algorithm : sort;
85 
86     switch (value.kind) with (UniNode.Kind)
87     {
88         case array:
89             auto arr = value.get!(UniNode[]);
90             sort!((a, b) => a.getAsString < b.getAsString)(arr);
91             return UniNode(arr);
92 
93         case object:
94             UniNode[] arr;
95             foreach (string key, val; value)
96                 arr ~= UniNode([UniNode(key), val]);
97             sort!"a[0].get!string < b[0].get!string"(arr);
98             return UniNode(arr);
99 
100         default:
101             return value;
102     }
103 }
104 
105 
106 UniNode keys(UniNode value)
107 {
108     if (value.kind != UniNode.Kind.object)
109         return UniNode(null);
110 
111     UniNode[] arr;
112     foreach (string key, val; value)
113         arr ~= UniNode(key);
114     return UniNode(arr);
115 }