Skip to content

Commit

Permalink
enh(twig): update keywords list (#3415)
Browse files Browse the repository at this point in the history
* enh(twig): update keywords list
* chore(twig) major twig refatoring, add new functionality (Josh)

Co-authored-by: Josh Goebel <me@joshgoebel.com>
  • Loading branch information
MrYamous and joshgoebel committed Dec 7, 2021
1 parent b63b12d commit 5c8c876
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 52 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -2,6 +2,7 @@

Grammars:

- enh(twig) update keywords list (#3415) [Matthieu Lempereur][]
- fix(python) def, class keywords detected mid-identifier (#3381) [Josh Goebel][]
- fix(python) Fix recognition of numeric literals followed by keywords without whitespace (#2985) [Richard Gibson][]
- enh(swift) add SE-0290 unavailability condition (#3382) [Bradley Mackey][]
Expand Down Expand Up @@ -34,6 +35,7 @@ Themes:
[Björn Ebbinghaus]: https://github.com/MrEbbinghaus
[Josh Goebel]: https://github.com/joshgoebel
[Samia Ali]: https://github.com/samiaab1990
[Matthieu Lempereur]: https://github.com/MrYamous
[idleberg]: https://github.com/idleberg

## Version 11.3.1
Expand Down
219 changes: 180 additions & 39 deletions src/languages/twig.js
Expand Up @@ -8,67 +8,208 @@ 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",
"trim",
"u|0",
"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 cycle date dump 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 date date_modify default ' +
'escape filter first format inky_to_html inline_css join json_encode keys last ' +
'length lower map markdown merge nl2br number_format raw reduce replace ' +
'reverse round slice sort spaceless split striptags title 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",
relevance: 0,
contains: [
FUNCTIONS
{
match: /[A-Za-z_]+:?/,
keywords: FILTERS
},
]
};

var TAGS = 'apply autoescape block deprecated do embed extends filter flush for from ' +
'if import include macro sandbox set use verbatim with';
const tagNamed = (tagnames, {relevance}) => {
return {
beginScope: {
1: 'template-tag',
3: 'name'
},
relevance: relevance || 2,
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 TAG = tagNamed(TAG_NAMES, { relevance: 2 });
const CUSTOM_TAG = tagNamed([ CUSTOM_TAG_RE ], { relevance: 1 });

return {
name: 'Twig',
aliases: ['craftcms'],
aliases: [ 'craftcms' ],
case_insensitive: true,
subLanguage: 'xml',
contains: [
hljs.COMMENT(/\{#/, /#\}/),
TAG,
CUSTOM_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
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
@@ -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
@@ -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
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
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
@@ -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
@@ -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>
2 changes: 1 addition & 1 deletion tools/checkAutoDetect.js
Expand Up @@ -2,7 +2,7 @@
'use strict';

const fs = require('fs');
const hljs = require('../build.js');
const hljs = require('../build/lib/index.js');
const path = require('path');
const utility = require('../test/utility.js');
const Table = require('cli-table');
Expand Down

0 comments on commit 5c8c876

Please sign in to comment.