Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 177 additions & 39 deletions src/languages/twig.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,67 +8,205 @@ Category: template
*/

export default function(hljs) {
var PARAMS = {
className: 'params',
begin: '\\(', end: '\\)'
const regex = hljs.regex;
const FUNCTION_NAMES = [
"attribute",
"block",
"constant",
"country_timezones",
"cycle",
"date",
"dump",
"html_classes",
"include",
"max",
"min",
"parent",
"random",
"range",
"source",
"template_from_string"
];

const FILTERS = [
"abs",
"batch",
"capitalize",
"column",
"convert_encoding",
"country_name",
"currency_name",
"currency_symbol",
"data_uri",
"date",
"date_modify",
"default",
"escape",
"filter",
"first",
"format",
"format_currency",
"format_date",
"format_datetime",
"format_number",
"format_time",
"html_to_markdown",
"inky_to_html",
"inline_css",
"join",
"json_encode",
"keys",
"language_name",
"last",
"length",
"locale_name",
"lower",
"map",
"markdown",
"markdown_to_html",
"merge",
"nl2br",
"number_format",
"raw",
"reduce",
"replace",
"reverse",
"round",
"slice",
"slug",
"sort",
"spaceless",
"split",
"striptags",
"timezone_name",
"title",
"u|0",
"trim",
"upper",
"url_encode"
];

let TAG_NAMES = [
"apply",
"autoescape",
"block",
"cache",
"deprecated",
"do",
"embed",
"extends",
"filter",
"flush",
"for",
"from",
"if",
"import",
"include",
"macro",
"sandbox",
"set",
"use",
"verbatim",
"with"
];

TAG_NAMES = TAG_NAMES.concat(TAG_NAMES.map(t => `end${t}`));

const STRING = {
scope: 'string',
variants: [
{
begin: /'/,
end: /'/
},
{
begin: /"/,
end: /"/
},
]
};

var FUNCTION_NAMES = 'attribute block constant country_timezones cycle date dump html_classes include ' +
'max min parent random range source template_from_string';
const NUMBER = {
scope: "number",
match: /\d+/
};

var FUNCTIONS = {
beginKeywords: FUNCTION_NAMES,
keywords: {name: FUNCTION_NAMES},
relevance: 0,
const PARAMS = {
begin: /\(/,
end: /\)/,
excludeBegin: true,
excludeEnd: true,
contains: [
PARAMS
STRING,
NUMBER
]
};

var FILTER = {
begin: /\|[A-Za-z_]+:?/,
keywords:
'abs batch capitalize column convert_encoding country_name currency_name currency_symbol data_uri date date_modify default ' +
'escape filter first format format_currency format_date format_datetime format_number format_time html_to_markdown inky_to_html inline_css join json_encode keys language_name last ' +
'length locale_name lower map markdown markdown_to_html merge nl2br number_format raw reduce replace ' +
'reverse round slice slug sort spaceless split striptags timezone_name title u|0 trim upper url_encode',

const FUNCTIONS = {
beginKeywords: FUNCTION_NAMES.join(" "),
keywords: { name: FUNCTION_NAMES },
relevance: 0,
contains: [ PARAMS ]
};

const FILTER = {
match: /\|(?=[A-Za-z_]+:?)/,
beginScope: "punctuation",
contains: [
FUNCTIONS
{
match: /[A-Za-z_]+:?/,
keywords: FILTERS
},
]
};

var TAGS = 'apply autoescape block cache deprecated do embed extends filter flush for from ' +
'if import include macro sandbox set use verbatim with';
const tagNamed = (tagnames) => {
return {
beginScope: {
1: 'template-tag',
3: 'name'
},
endScope: 'template-tag',
begin: [
/\{%/,
/\s*/,
regex.either(...tagnames)
],
end: /%\}/,
keywords: "in",
contains: [
FILTER,
FUNCTIONS,
STRING,
NUMBER
]
};
};

TAGS = TAGS + ' ' + TAGS.split(' ').map(function(t){return 'end' + t}).join(' ');
const CUSTOM_TAG_RE = /[a-z_]+/;
const ALL_TAGS = [].concat(TAG_NAMES).concat(CUSTOM_TAG_RE);
const TAG = tagNamed(ALL_TAGS);

return {
name: 'Twig',
aliases: ['craftcms'],
aliases: [ 'craftcms' ],
case_insensitive: true,
subLanguage: 'xml',
contains: [
hljs.COMMENT(/\{#/, /#\}/),
TAG,
{
className: 'template-tag',
begin: /\{%/, end: /%\}/,
className: 'template-variable',
begin: /\{\{/,
end: /\}\}/,
contains: [
{
className: 'name',
begin: /\w+/,
keywords: TAGS,
starts: {
endsWithParent: true,
contains: [FILTER, FUNCTIONS],
relevance: 0
}
}
'self',
FILTER,
FUNCTIONS,
STRING,
NUMBER
]
},
{
className: 'template-variable',
begin: /\{\{/, end: /\}\}/,
contains: ['self', FILTER, FUNCTIONS]
}
]
};
Expand Down
2 changes: 1 addition & 1 deletion test/markup/clojure/globals_definition.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,4 @@ string&quot;</span>

<span class="hljs-comment">;; create a couple shapes and get their area</span>
(<span class="hljs-keyword">def</span> <span class="hljs-title">myCircle</span> (<span class="hljs-name">Circle.</span> <span class="hljs-number">10</span>))
(<span class="hljs-keyword">def</span> <span class="hljs-title">mySquare</span> (<span class="hljs-name">Square.</span> <span class="hljs-number">5</span> <span class="hljs-number">11</span>))
(<span class="hljs-keyword">def</span> <span class="hljs-title">mySquare</span> (<span class="hljs-name">Square.</span> <span class="hljs-number">5</span> <span class="hljs-number">11</span>))
2 changes: 1 addition & 1 deletion test/markup/clojure/symbols-numbers.expect.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(<span class="hljs-keyword">def</span> <span class="hljs-title">+x</span> [(<span class="hljs-name">a</span> <span class="hljs-number">1</span>) <span class="hljs-number">+2</span> <span class="hljs-number">-3.0</span> y-5])
(<span class="hljs-name">System/getProperty</span> <span class="hljs-string">&quot;java.vm.version&quot;</span>)
(<span class="hljs-name">.getEnclosingClass</span> java.util.Map$Entry)
(<span class="hljs-name">java.util.Map$Entry.</span> .getEnclosingClass)
(<span class="hljs-name">java.util.Map$Entry.</span> .getEnclosingClass)
2 changes: 1 addition & 1 deletion test/markup/fsharp/bang-keywords.expect.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<span class="hljs-keyword">let!</span> (result2 <span class="hljs-operator">:</span> <span class="hljs-type">byte</span>[]) <span class="hljs-operator">=</span> stream.AsyncRead(bufferSize)
<span class="hljs-keyword">let!</span> (result2 <span class="hljs-operator">:</span> <span class="hljs-type">byte</span>[]) <span class="hljs-operator">=</span> stream.AsyncRead(bufferSize)
2 changes: 1 addition & 1 deletion test/markup/fsharp/computation-expressions.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
<span class="hljs-keyword">return</span> result
}

<span class="hljs-keyword">let</span> result <span class="hljs-operator">=</span> work <span class="hljs-operator">|&gt;</span> Async.RunSynchronously
<span class="hljs-keyword">let</span> result <span class="hljs-operator">=</span> work <span class="hljs-operator">|&gt;</span> Async.RunSynchronously
2 changes: 1 addition & 1 deletion test/markup/fsharp/types.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,4 @@
<span class="hljs-operator">|</span> CaseK <span class="hljs-keyword">of</span> ``var with spaces``<span class="hljs-operator">:</span> <span class="hljs-type">string</span>
<span class="hljs-operator">|</span> CaseL <span class="hljs-keyword">of</span> ``var with spaces``<span class="hljs-operator">:</span> ``type with spaces``
<span class="hljs-operator">|</span> CaseM <span class="hljs-keyword">of</span> v1 <span class="hljs-operator">:</span> ``type with spaces``
<span class="hljs-operator">|</span> CaseN <span class="hljs-keyword">of</span> ``type with spaces``
<span class="hljs-operator">|</span> CaseN <span class="hljs-keyword">of</span> ``type with spaces``
2 changes: 1 addition & 1 deletion test/markup/twig/filter_with_underscore.expect.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<span class="hljs-template-variable">{{ &quot;string with spaces&quot;|<span class="hljs-keyword">url_encode</span> }}</span>
<span class="hljs-template-variable">{{ <span class="hljs-string">&quot;string with spaces&quot;</span><span class="hljs-punctuation">|</span><span class="hljs-keyword">url_encode</span> }}</span>
12 changes: 6 additions & 6 deletions test/markup/twig/template_tags.expect.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">if</span></span> posts|<span class="hljs-keyword">length</span> %}</span><span class="language-xml">
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">for</span></span> article in articles %}</span><span class="language-xml">
<span class="hljs-template-tag">{%</span> <span class="hljs-name">if</span> posts<span class="hljs-punctuation">|</span><span class="hljs-keyword">length</span> <span class="hljs-template-tag">%}</span><span class="language-xml">
</span><span class="hljs-template-tag">{%</span> <span class="hljs-name">for</span> article <span class="hljs-keyword">in</span> articles <span class="hljs-template-tag">%}</span><span class="language-xml">
<span class="hljs-symbol">&amp;lt;</span>div<span class="hljs-symbol">&amp;gt;</span>
</span><span class="hljs-template-variable">{{ article.title|<span class="hljs-keyword">upper</span>() }}</span><span class="language-xml">
</span><span class="hljs-template-variable">{{ article.title<span class="hljs-punctuation">|</span><span class="hljs-keyword">upper</span>() }}</span><span class="language-xml">

</span><span class="hljs-comment">{# outputs &#x27;WELCOME&#x27; #}</span><span class="language-xml">
<span class="hljs-symbol">&amp;lt;</span>/div<span class="hljs-symbol">&amp;gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> %}</span><span class="language-xml">
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span><span class="language-xml">
</span><span class="hljs-template-tag">{%</span> <span class="hljs-name">endfor</span> <span class="hljs-template-tag">%}</span><span class="language-xml">
</span><span class="hljs-template-tag">{%</span> <span class="hljs-name">endif</span> <span class="hljs-template-tag">%}</span><span class="language-xml">

</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">set</span></span> user = json_encode(user) %}</span><span class="language-xml">
</span><span class="hljs-template-tag">{%</span> <span class="hljs-name">set</span> user = json_encode(user) <span class="hljs-template-tag">%}</span><span class="language-xml">
</span>