UNPKG

4.35 kBJavaScriptView Raw
1/*
2Language: Twig
3Requires: xml.js
4Author: Luke Holder <lukemh@gmail.com>
5Description: Twig is a templating language for PHP
6Website: https://twig.symfony.com
7Category: template
8*/
9
10function twig(hljs) {
11 const regex = hljs.regex;
12 const FUNCTION_NAMES = [
13 "absolute_url",
14 "asset|0",
15 "asset_version",
16 "attribute",
17 "block",
18 "constant",
19 "controller|0",
20 "country_timezones",
21 "csrf_token",
22 "cycle",
23 "date",
24 "dump",
25 "expression",
26 "form|0",
27 "form_end",
28 "form_errors",
29 "form_help",
30 "form_label",
31 "form_rest",
32 "form_row",
33 "form_start",
34 "form_widget",
35 "html_classes",
36 "include",
37 "is_granted",
38 "logout_path",
39 "logout_url",
40 "max",
41 "min",
42 "parent",
43 "path|0",
44 "random",
45 "range",
46 "relative_path",
47 "render",
48 "render_esi",
49 "source",
50 "template_from_string",
51 "url|0"
52 ];
53
54 const FILTERS = [
55 "abs",
56 "abbr_class",
57 "abbr_method",
58 "batch",
59 "capitalize",
60 "column",
61 "convert_encoding",
62 "country_name",
63 "currency_name",
64 "currency_symbol",
65 "data_uri",
66 "date",
67 "date_modify",
68 "default",
69 "escape",
70 "file_excerpt",
71 "file_link",
72 "file_relative",
73 "filter",
74 "first",
75 "format",
76 "format_args",
77 "format_args_as_text",
78 "format_currency",
79 "format_date",
80 "format_datetime",
81 "format_file",
82 "format_file_from_text",
83 "format_number",
84 "format_time",
85 "html_to_markdown",
86 "humanize",
87 "inky_to_html",
88 "inline_css",
89 "join",
90 "json_encode",
91 "keys",
92 "language_name",
93 "last",
94 "length",
95 "locale_name",
96 "lower",
97 "map",
98 "markdown",
99 "markdown_to_html",
100 "merge",
101 "nl2br",
102 "number_format",
103 "raw",
104 "reduce",
105 "replace",
106 "reverse",
107 "round",
108 "slice",
109 "slug",
110 "sort",
111 "spaceless",
112 "split",
113 "striptags",
114 "timezone_name",
115 "title",
116 "trans",
117 "transchoice",
118 "trim",
119 "u|0",
120 "upper",
121 "url_encode",
122 "yaml_dump",
123 "yaml_encode"
124 ];
125
126 let TAG_NAMES = [
127 "apply",
128 "autoescape",
129 "block",
130 "cache",
131 "deprecated",
132 "do",
133 "embed",
134 "extends",
135 "filter",
136 "flush",
137 "for",
138 "form_theme",
139 "from",
140 "if",
141 "import",
142 "include",
143 "macro",
144 "sandbox",
145 "set",
146 "stopwatch",
147 "trans",
148 "trans_default_domain",
149 "transchoice",
150 "use",
151 "verbatim",
152 "with"
153 ];
154
155 TAG_NAMES = TAG_NAMES.concat(TAG_NAMES.map(t => `end${t}`));
156
157 const STRING = {
158 scope: 'string',
159 variants: [
160 {
161 begin: /'/,
162 end: /'/
163 },
164 {
165 begin: /"/,
166 end: /"/
167 },
168 ]
169 };
170
171 const NUMBER = {
172 scope: "number",
173 match: /\d+/
174 };
175
176 const PARAMS = {
177 begin: /\(/,
178 end: /\)/,
179 excludeBegin: true,
180 excludeEnd: true,
181 contains: [
182 STRING,
183 NUMBER
184 ]
185 };
186
187
188 const FUNCTIONS = {
189 beginKeywords: FUNCTION_NAMES.join(" "),
190 keywords: { name: FUNCTION_NAMES },
191 relevance: 0,
192 contains: [ PARAMS ]
193 };
194
195 const FILTER = {
196 match: /\|(?=[A-Za-z_]+:?)/,
197 beginScope: "punctuation",
198 relevance: 0,
199 contains: [
200 {
201 match: /[A-Za-z_]+:?/,
202 keywords: FILTERS
203 },
204 ]
205 };
206
207 const tagNamed = (tagnames, { relevance }) => {
208 return {
209 beginScope: {
210 1: 'template-tag',
211 3: 'name'
212 },
213 relevance: relevance || 2,
214 endScope: 'template-tag',
215 begin: [
216 /\{%/,
217 /\s*/,
218 regex.either(...tagnames)
219 ],
220 end: /%\}/,
221 keywords: "in",
222 contains: [
223 FILTER,
224 FUNCTIONS,
225 STRING,
226 NUMBER
227 ]
228 };
229 };
230
231 const CUSTOM_TAG_RE = /[a-z_]+/;
232 const TAG = tagNamed(TAG_NAMES, { relevance: 2 });
233 const CUSTOM_TAG = tagNamed([ CUSTOM_TAG_RE ], { relevance: 1 });
234
235 return {
236 name: 'Twig',
237 aliases: [ 'craftcms' ],
238 case_insensitive: true,
239 subLanguage: 'xml',
240 contains: [
241 hljs.COMMENT(/\{#/, /#\}/),
242 TAG,
243 CUSTOM_TAG,
244 {
245 className: 'template-variable',
246 begin: /\{\{/,
247 end: /\}\}/,
248 contains: [
249 'self',
250 FILTER,
251 FUNCTIONS,
252 STRING,
253 NUMBER
254 ]
255 }
256 ]
257 };
258}
259
260module.exports = twig;