Skip to content

Commit e063992

Browse files
gflohrGolmote
authored andcommitted
Support for Template Toolkit 2 (#1418)
* support for Template Toolkit 2 * optimized quoted string regexes * optimized double-quoted string regex * fully qualified tt2 plug-in names don't work Also use \w. * do not use empty character class See #1107. * put keyword tests in alphabetical order * ordered tt2 keywords alphabetically * removed redundant operator rule for tt2 * removed possibly existing old rules before inserti * indentation * allow backslash in front of lf in tt2 strings * indentation * avoid backtracking * escape xml special characters * indent with tab instead of spaces * greedy is no longer needed for variables Also use \w instead of explicit character class. * re-generated with gulp
1 parent fa328bb commit e063992

17 files changed

+565
-5
lines changed

components.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,11 @@
651651
"require": "markup",
652652
"owner": "Golmote"
653653
},
654+
"tt2": {
655+
"title": "Template Toolkit 2",
656+
"require": ["clike", "markup-templating"],
657+
"owner": "gflohr"
658+
},
654659
"twig": {
655660
"title": "Twig",
656661
"require": "markup",

components/prism-tt2.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
(function(Prism) {
2+
3+
Prism.languages.tt2 = Prism.languages.extend('clike', {
4+
comment: {
5+
pattern: /#.*|\[%#[\s\S]*?%\]/,
6+
lookbehind: true
7+
},
8+
keyword: /\b(?:BLOCK|CALL|CASE|CATCH|CLEAR|DEBUG|DEFAULT|ELSE|ELSIF|END|FILTER|FINAL|FOREACH|GET|IF|IN|INCLUDE|INSERT|LAST|MACRO|META|NEXT|PERL|PROCESS|RAWPERL|RETURN|SET|STOP|TAGS|THROW|TRY|SWITCH|UNLESS|USE|WHILE|WRAPPER)\b/,
9+
punctuation: /[[\]{},()]/
10+
});
11+
12+
delete Prism.languages.tt2['operator'];
13+
delete Prism.languages.tt2['variable'];
14+
Prism.languages.insertBefore('tt2', 'number', {
15+
operator: /=[>=]?|!=?|<=?|>=?|&&|\|\|?|\b(?:and|or|not)\b/,
16+
variable: {
17+
pattern: /[a-z]\w*(?:\s*\.\s*(?:\d+|\$?[a-z]\w*))*/i
18+
}
19+
});
20+
21+
delete Prism.languages.tt2['delimiter'];
22+
Prism.languages.insertBefore('tt2', 'keyword', {
23+
'delimiter': {
24+
pattern: /^(?:\[%|%%)-?|-?%]$/,
25+
alias: 'punctuation'
26+
}
27+
});
28+
29+
Prism.languages.insertBefore('tt2', 'string', {
30+
'single-quoted-string': {
31+
pattern: /'[^\\']*(?:\\[\s\S][^\\']*)*'/,
32+
greedy: true,
33+
alias: 'string'
34+
},
35+
'double-quoted-string': {
36+
pattern: /"[^\\"]*(?:\\[\s\S][^\\"]*)*"/,
37+
greedy: true,
38+
alias: 'string',
39+
inside: {
40+
variable: {
41+
pattern: /\$(?:[a-z]\w*(?:\.(?:\d+|\$?[a-z]\w*))*)/i
42+
}
43+
}
44+
}
45+
});
46+
47+
// The different types of TT2 strings "replace" the C-like standard string
48+
delete Prism.languages.tt2.string;
49+
50+
Prism.hooks.add('before-tokenize', function(env) {
51+
var tt2Pattern = /\[%[\s\S]+?%\]/g;
52+
Prism.languages['markup-templating'].buildPlaceholders(env, 'tt2', tt2Pattern);
53+
});
54+
55+
Prism.hooks.add('after-tokenize', function(env) {
56+
Prism.languages['markup-templating'].tokenizePlaceholders(env, 'tt2');
57+
});
58+
59+
}(Prism));

components/prism-tt2.min.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/prism-tt2.html

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<h2>Comments</h2>
2+
<pre><code class="language-tt2">[%# this entire directive is ignored no
3+
matter how many lines it wraps onto
4+
%]
5+
[% # this is a comment
6+
theta = 20 # so is this
7+
rho = 30 # &lt;aol&gt;me too!&lt;/aol&gt;
8+
%]
9+
</code></pre>
10+
11+
<h2>Variables</h2>
12+
<pre><code class="language-tt2">[% text %]
13+
[% article.title %]
14+
[%= eat.whitespace.left %]
15+
[% eat.whitespace.right =%]
16+
[%= eat.whitespace.both =%]
17+
[% object.method() %]</code></pre>
18+
19+
20+
<h2>Conditionals and Loops</h2>
21+
<pre><code class="language-tt2">[% IF foo = bar %]
22+
this
23+
[% ELSE %]
24+
that
25+
[% END %]
26+
[% FOREACH post IN q.listPosts(lingua = "de") %]
27+
&lt;a href="[% post.permalink %]"&gt;[% post.title | html %]&lt;/a&gt;
28+
[% END %]</code></pre>
29+
30+
<h2>Multiple Directives</h2>
31+
<pre><code class="language-tt2">[% IF title;
32+
INCLUDE header;
33+
ELSE;
34+
INCLUDE other/header title="Some Other Title";
35+
END
36+
%]</code></pre>
37+
38+
<h2>Operators</h2>
39+
<pre><code class="language-tt2">[% FOREACH post IN q.listPosts(lingua => 'de') %]
40+
[% post.title | myfilter(foo = "bar") %]
41+
[% END %]</code></pre>
42+
43+
<h2>Known Limitations</h2>
44+
<ul>
45+
<li><a href="http://template-toolkit.org/docs/manual/Syntax.html#section_Outline_Tags">
46+
Outline tags</a> are not supported.</li>
47+
<li>The arguments to
48+
<a href="http://template-toolkit.org/docs/manual/Directives.html#section_TAGS">TAGS</a>
49+
are usually misinterpreted</li>
50+
<li>In TT2, you can use keywords as identifiers where this is
51+
unambiguous. But these keywords will be highlighted as keywords, not
52+
as variables here.</li>
53+
<li>The
54+
<a href="http://template-toolkit.org/docs/manual/Config.html#section_ANYCASE">ANYCASE</a>
55+
option is not supported.</li>
56+
<li>
57+
Any number of backslashes in front of dollar signs inside of double quoted
58+
strings are ignored since the behavior of Template Toolkit 2.26 seems to be
59+
inconsistent.
60+
</li>
61+
</ul>

plugins/autoloader/prism-autoloader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
}
55

66
// The dependencies map is built automatically with gulp
7-
var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","arduino":"cpp","aspnet":["markup","csharp"],"bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","django":"markup","erb":["ruby","markup-templating"],"fsharp":"clike","flow":"javascript","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup-templating","haxe":"clike","java":"clike","jolie":"clike","kotlin":"clike","less":"css","markdown":"markup","markup-templating":"markup","n4js":"javascript","nginx":"clike","objectivec":"c","opencl":"cpp","parser":"markup","php":["clike","markup-templating"],"php-extras":"php","plsql":"sql","processing":"clike","protobuf":"clike","pug":"javascript","qore":"clike","jsx":["markup","javascript"],"tsx":["jsx","typescript"],"reason":"clike","ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup-templating","soy":"markup-templating","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","vbnet":"basic","velocity":"markup","wiki":"markup","xeora":"markup"}/*]*/;
7+
var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","arduino":"cpp","aspnet":["markup","csharp"],"bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","django":"markup","erb":["ruby","markup-templating"],"fsharp":"clike","flow":"javascript","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup-templating","haxe":"clike","java":"clike","jolie":"clike","kotlin":"clike","less":"css","markdown":"markup","markup-templating":"markup","n4js":"javascript","nginx":"clike","objectivec":"c","opencl":"cpp","parser":"markup","php":["clike","markup-templating"],"php-extras":"php","plsql":"sql","processing":"clike","protobuf":"clike","pug":"javascript","qore":"clike","jsx":["markup","javascript"],"tsx":["jsx","typescript"],"reason":"clike","ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup-templating","soy":"markup-templating","swift":"clike","textile":"markup","tt2":["clike","markup-templating"],"twig":"markup","typescript":"javascript","vbnet":"basic","velocity":"markup","wiki":"markup","xeora":"markup"}/*]*/;
88

99
var lang_data = {};
1010

plugins/autoloader/prism-autoloader.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/show-language/prism-show-language.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ if (!Prism.plugins.toolbar) {
1111
}
1212

1313
// The languages map is built automatically with gulp
14-
var Languages = /*languages_placeholder[*/{"html":"HTML","xml":"XML","svg":"SVG","mathml":"MathML","css":"CSS","clike":"C-like","javascript":"JavaScript","abap":"ABAP","actionscript":"ActionScript","apacheconf":"Apache Configuration","apl":"APL","applescript":"AppleScript","arff":"ARFF","asciidoc":"AsciiDoc","asm6502":"6502 Assembly","aspnet":"ASP.NET (C#)","autohotkey":"AutoHotkey","autoit":"AutoIt","basic":"BASIC","csharp":"C#","cpp":"C++","coffeescript":"CoffeeScript","csp":"Content-Security-Policy","css-extras":"CSS Extras","django":"Django/Jinja2","erb":"ERB","fsharp":"F#","gedcom":"GEDCOM","glsl":"GLSL","graphql":"GraphQL","http":"HTTP","hpkp":"HTTP Public-Key-Pins","hsts":"HTTP Strict-Transport-Security","ichigojam":"IchigoJam","inform7":"Inform 7","json":"JSON","latex":"LaTeX","livescript":"LiveScript","lolcode":"LOLCODE","markup-templating":"Markup templating","matlab":"MATLAB","mel":"MEL","n4js":"N4JS","nasm":"NASM","nginx":"nginx","nsis":"NSIS","objectivec":"Objective-C","ocaml":"OCaml","opencl":"OpenCL","parigp":"PARI/GP","php":"PHP","php-extras":"PHP Extras","plsql":"PL/SQL","powershell":"PowerShell","properties":".properties","protobuf":"Protocol Buffers","q":"Q (kdb+ database)","jsx":"React JSX","tsx":"React TSX","renpy":"Ren'py","rest":"reST (reStructuredText)","sas":"SAS","sass":"Sass (Sass)","scss":"Sass (Scss)","sql":"SQL","soy":"Soy (Closure Template)","typescript":"TypeScript","vbnet":"VB.Net","vhdl":"VHDL","vim":"vim","visual-basic":"Visual Basic","wasm":"WebAssembly","wiki":"Wiki markup","xojo":"Xojo (REALbasic)","yaml":"YAML"}/*]*/;
14+
var Languages = /*languages_placeholder[*/{"html":"HTML","xml":"XML","svg":"SVG","mathml":"MathML","css":"CSS","clike":"C-like","javascript":"JavaScript","abap":"ABAP","actionscript":"ActionScript","apacheconf":"Apache Configuration","apl":"APL","applescript":"AppleScript","arff":"ARFF","asciidoc":"AsciiDoc","asm6502":"6502 Assembly","aspnet":"ASP.NET (C#)","autohotkey":"AutoHotkey","autoit":"AutoIt","basic":"BASIC","csharp":"C#","cpp":"C++","coffeescript":"CoffeeScript","csp":"Content-Security-Policy","css-extras":"CSS Extras","django":"Django/Jinja2","erb":"ERB","fsharp":"F#","gedcom":"GEDCOM","glsl":"GLSL","graphql":"GraphQL","http":"HTTP","hpkp":"HTTP Public-Key-Pins","hsts":"HTTP Strict-Transport-Security","ichigojam":"IchigoJam","inform7":"Inform 7","json":"JSON","latex":"LaTeX","livescript":"LiveScript","lolcode":"LOLCODE","markup-templating":"Markup templating","matlab":"MATLAB","mel":"MEL","n4js":"N4JS","nasm":"NASM","nginx":"nginx","nsis":"NSIS","objectivec":"Objective-C","ocaml":"OCaml","opencl":"OpenCL","parigp":"PARI/GP","php":"PHP","php-extras":"PHP Extras","plsql":"PL/SQL","powershell":"PowerShell","properties":".properties","protobuf":"Protocol Buffers","q":"Q (kdb+ database)","jsx":"React JSX","tsx":"React TSX","renpy":"Ren'py","rest":"reST (reStructuredText)","sas":"SAS","sass":"Sass (Sass)","scss":"Sass (Scss)","sql":"SQL","soy":"Soy (Closure Template)","tt2":"Template Toolkit 2","typescript":"TypeScript","vbnet":"VB.Net","vhdl":"VHDL","vim":"vim","visual-basic":"Visual Basic","wasm":"WebAssembly","wiki":"Wiki markup","xojo":"Xojo (REALbasic)","yaml":"YAML"}/*]*/;
1515
Prism.plugins.toolbar.registerButton('show-language', function(env) {
1616
var pre = env.element.parentNode;
1717
if (!pre || !/pre/i.test(pre.nodeName)) {

0 commit comments

Comments
 (0)