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
This commit is contained in:
Guido Flohr 2018-05-10 12:07:34 +03:00 committed by Golmote
parent fa328bb1c1
commit e063992b81
17 changed files with 565 additions and 5 deletions

File diff suppressed because one or more lines are too long

View File

@ -651,6 +651,11 @@
"require": "markup",
"owner": "Golmote"
},
"tt2": {
"title": "Template Toolkit 2",
"require": ["clike", "markup-templating"],
"owner": "gflohr"
},
"twig": {
"title": "Twig",
"require": "markup",

59
components/prism-tt2.js Normal file
View File

@ -0,0 +1,59 @@
(function(Prism) {
Prism.languages.tt2 = Prism.languages.extend('clike', {
comment: {
pattern: /#.*|\[%#[\s\S]*?%\]/,
lookbehind: true
},
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/,
punctuation: /[[\]{},()]/
});
delete Prism.languages.tt2['operator'];
delete Prism.languages.tt2['variable'];
Prism.languages.insertBefore('tt2', 'number', {
operator: /=[>=]?|!=?|<=?|>=?|&&|\|\|?|\b(?:and|or|not)\b/,
variable: {
pattern: /[a-z]\w*(?:\s*\.\s*(?:\d+|\$?[a-z]\w*))*/i
}
});
delete Prism.languages.tt2['delimiter'];
Prism.languages.insertBefore('tt2', 'keyword', {
'delimiter': {
pattern: /^(?:\[%|%%)-?|-?%]$/,
alias: 'punctuation'
}
});
Prism.languages.insertBefore('tt2', 'string', {
'single-quoted-string': {
pattern: /'[^\\']*(?:\\[\s\S][^\\']*)*'/,
greedy: true,
alias: 'string'
},
'double-quoted-string': {
pattern: /"[^\\"]*(?:\\[\s\S][^\\"]*)*"/,
greedy: true,
alias: 'string',
inside: {
variable: {
pattern: /\$(?:[a-z]\w*(?:\.(?:\d+|\$?[a-z]\w*))*)/i
}
}
}
});
// The different types of TT2 strings "replace" the C-like standard string
delete Prism.languages.tt2.string;
Prism.hooks.add('before-tokenize', function(env) {
var tt2Pattern = /\[%[\s\S]+?%\]/g;
Prism.languages['markup-templating'].buildPlaceholders(env, 'tt2', tt2Pattern);
});
Prism.hooks.add('after-tokenize', function(env) {
Prism.languages['markup-templating'].tokenizePlaceholders(env, 'tt2');
});
}(Prism));

1
components/prism-tt2.min.js vendored Normal file
View File

@ -0,0 +1 @@
!function(e){e.languages.tt2=e.languages.extend("clike",{comment:{pattern:/#.*|\[%#[\s\S]*?%\]/,lookbehind:!0},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/,punctuation:/[[\]{},()]/}),delete e.languages.tt2.operator,delete e.languages.tt2.variable,e.languages.insertBefore("tt2","number",{operator:/=[>=]?|!=?|<=?|>=?|&&|\|\|?|\b(?:and|or|not)\b/,variable:{pattern:/[a-z]\w*(?:\s*\.\s*(?:\d+|\$?[a-z]\w*))*/i}}),delete e.languages.tt2.delimiter,e.languages.insertBefore("tt2","keyword",{delimiter:{pattern:/^(?:\[%|%%)-?|-?%]$/,alias:"punctuation"}}),e.languages.insertBefore("tt2","string",{"single-quoted-string":{pattern:/'[^\\']*(?:\\[\s\S][^\\']*)*'/,greedy:!0,alias:"string"},"double-quoted-string":{pattern:/"[^\\"]*(?:\\[\s\S][^\\"]*)*"/,greedy:!0,alias:"string",inside:{variable:{pattern:/\$(?:[a-z]\w*(?:\.(?:\d+|\$?[a-z]\w*))*)/i}}}}),delete e.languages.tt2.string,e.hooks.add("before-tokenize",function(t){var a=/\[%[\s\S]+?%\]/g;e.languages["markup-templating"].buildPlaceholders(t,"tt2",a)}),e.hooks.add("after-tokenize",function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"tt2")})}(Prism);

61
examples/prism-tt2.html Normal file
View File

@ -0,0 +1,61 @@
<h2>Comments</h2>
<pre><code class="language-tt2">[%# this entire directive is ignored no
matter how many lines it wraps onto
%]
[% # this is a comment
theta = 20 # so is this
rho = 30 # &lt;aol&gt;me too!&lt;/aol&gt;
%]
</code></pre>
<h2>Variables</h2>
<pre><code class="language-tt2">[% text %]
[% article.title %]
[%= eat.whitespace.left %]
[% eat.whitespace.right =%]
[%= eat.whitespace.both =%]
[% object.method() %]</code></pre>
<h2>Conditionals and Loops</h2>
<pre><code class="language-tt2">[% IF foo = bar %]
this
[% ELSE %]
that
[% END %]
[% FOREACH post IN q.listPosts(lingua = "de") %]
&lt;a href="[% post.permalink %]"&gt;[% post.title | html %]&lt;/a&gt;
[% END %]</code></pre>
<h2>Multiple Directives</h2>
<pre><code class="language-tt2">[% IF title;
INCLUDE header;
ELSE;
INCLUDE other/header title="Some Other Title";
END
%]</code></pre>
<h2>Operators</h2>
<pre><code class="language-tt2">[% FOREACH post IN q.listPosts(lingua => 'de') %]
[% post.title | myfilter(foo = "bar") %]
[% END %]</code></pre>
<h2>Known Limitations</h2>
<ul>
<li><a href="http://template-toolkit.org/docs/manual/Syntax.html#section_Outline_Tags">
Outline tags</a> are not supported.</li>
<li>The arguments to
<a href="http://template-toolkit.org/docs/manual/Directives.html#section_TAGS">TAGS</a>
are usually misinterpreted</li>
<li>In TT2, you can use keywords as identifiers where this is
unambiguous. But these keywords will be highlighted as keywords, not
as variables here.</li>
<li>The
<a href="http://template-toolkit.org/docs/manual/Config.html#section_ANYCASE">ANYCASE</a>
option is not supported.</li>
<li>
Any number of backslashes in front of dollar signs inside of double quoted
strings are ignored since the behavior of Template Toolkit 2.26 seems to be
inconsistent.
</li>
</ul>

View File

@ -4,7 +4,7 @@
}
// The dependencies map is built automatically with gulp
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"}/*]*/;
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"}/*]*/;
var lang_data = {};

View File

@ -1 +1 @@
!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={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"},a={},c="none",t=document.getElementsByTagName("script");t=t[t.length-1];var r="components/";if(t.hasAttribute("data-autoloader-path")){var s=t.getAttribute("data-autoloader-path").trim();s.length>0&&!/^[a-z]+:\/\//i.test(t.src)&&(r=s.replace(/\/?$/,"/"))}else/[\w-]+\.js$/.test(t.src)&&(r=t.src.replace(/[\w-]+\.js$/,"components/"));var n=Prism.plugins.autoloader={languages_path:r,use_minified:!0},t=function(e,a,c){var t=document.createElement("script");t.src=e,t.async=!0,t.onload=function(){document.body.removeChild(t),a&&a()},t.onerror=function(){document.body.removeChild(t),c&&c()},document.body.appendChild(t)},i=function(e){return n.languages_path+"prism-"+e+(n.use_minified?".min":"")+".js"},l=function(e,c){var t=a[e];t||(t=a[e]={});var r=c.getAttribute("data-dependencies");!r&&c.parentNode&&"pre"===c.parentNode.tagName.toLowerCase()&&(r=c.parentNode.getAttribute("data-dependencies")),r=r?r.split(/\s*,\s*/g):[],o(r,function(){p(e,function(){Prism.highlightElement(c)})})},o=function(e,a,c){"string"==typeof e&&(e=[e]);var t=0,r=e.length,s=function(){r>t?p(e[t],function(){t++,s()},function(){c&&c(e[t])}):t===r&&a&&a(e)};s()},p=function(c,r,s){var n=function(){var e=!1;c.indexOf("!")>=0&&(e=!0,c=c.replace("!",""));var n=a[c];if(n||(n=a[c]={}),r&&(n.success_callbacks||(n.success_callbacks=[]),n.success_callbacks.push(r)),s&&(n.error_callbacks||(n.error_callbacks=[]),n.error_callbacks.push(s)),!e&&Prism.languages[c])u(c);else if(!e&&n.error)m(c);else if(e||!n.loading){n.loading=!0;var l=i(c);t(l,function(){n.loading=!1,u(c)},function(){n.loading=!1,n.error=!0,m(c)})}},l=e[c];l&&l.length?o(l,n):n()},u=function(e){a[e]&&a[e].success_callbacks&&a[e].success_callbacks.length&&a[e].success_callbacks.forEach(function(a){a(e)})},m=function(e){a[e]&&a[e].error_callbacks&&a[e].error_callbacks.length&&a[e].error_callbacks.forEach(function(a){a(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&e.language!==c&&l(e.language,e.element)})}}();
!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={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"},a={},c="none",t=document.getElementsByTagName("script");t=t[t.length-1];var r="components/";if(t.hasAttribute("data-autoloader-path")){var s=t.getAttribute("data-autoloader-path").trim();s.length>0&&!/^[a-z]+:\/\//i.test(t.src)&&(r=s.replace(/\/?$/,"/"))}else/[\w-]+\.js$/.test(t.src)&&(r=t.src.replace(/[\w-]+\.js$/,"components/"));var i=Prism.plugins.autoloader={languages_path:r,use_minified:!0},t=function(e,a,c){var t=document.createElement("script");t.src=e,t.async=!0,t.onload=function(){document.body.removeChild(t),a&&a()},t.onerror=function(){document.body.removeChild(t),c&&c()},document.body.appendChild(t)},n=function(e){return i.languages_path+"prism-"+e+(i.use_minified?".min":"")+".js"},l=function(e,c){var t=a[e];t||(t=a[e]={});var r=c.getAttribute("data-dependencies");!r&&c.parentNode&&"pre"===c.parentNode.tagName.toLowerCase()&&(r=c.parentNode.getAttribute("data-dependencies")),r=r?r.split(/\s*,\s*/g):[],o(r,function(){p(e,function(){Prism.highlightElement(c)})})},o=function(e,a,c){"string"==typeof e&&(e=[e]);var t=0,r=e.length,s=function(){r>t?p(e[t],function(){t++,s()},function(){c&&c(e[t])}):t===r&&a&&a(e)};s()},p=function(c,r,s){var i=function(){var e=!1;c.indexOf("!")>=0&&(e=!0,c=c.replace("!",""));var i=a[c];if(i||(i=a[c]={}),r&&(i.success_callbacks||(i.success_callbacks=[]),i.success_callbacks.push(r)),s&&(i.error_callbacks||(i.error_callbacks=[]),i.error_callbacks.push(s)),!e&&Prism.languages[c])u(c);else if(!e&&i.error)m(c);else if(e||!i.loading){i.loading=!0;var l=n(c);t(l,function(){i.loading=!1,u(c)},function(){i.loading=!1,i.error=!0,m(c)})}},l=e[c];l&&l.length?o(l,i):i()},u=function(e){a[e]&&a[e].success_callbacks&&a[e].success_callbacks.length&&a[e].success_callbacks.forEach(function(a){a(e)})},m=function(e){a[e]&&a[e].error_callbacks&&a[e].error_callbacks.length&&a[e].error_callbacks.forEach(function(a){a(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&e.language!==c&&l(e.language,e.element)})}}();

View File

@ -11,7 +11,7 @@ if (!Prism.plugins.toolbar) {
}
// The languages map is built automatically with gulp
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"}/*]*/;
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"}/*]*/;
Prism.plugins.toolbar.registerButton('show-language', function(env) {
var pre = env.element.parentNode;
if (!pre || !/pre/i.test(pre.nodeName)) {

View File

@ -1 +1 @@
!function(){if("undefined"!=typeof self&&self.Prism&&self.document){if(!Prism.plugins.toolbar)return console.warn("Show Languages plugin loaded before Toolbar plugin."),void 0;var e={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"};Prism.plugins.toolbar.registerButton("show-language",function(a){var t=a.element.parentNode;if(t&&/pre/i.test(t.nodeName)){var s=t.getAttribute("data-language")||e[a.language]||a.language&&a.language.substring(0,1).toUpperCase()+a.language.substring(1);if(s){var i=document.createElement("span");return i.textContent=s,i}}})}}();
!function(){if("undefined"!=typeof self&&self.Prism&&self.document){if(!Prism.plugins.toolbar)return console.warn("Show Languages plugin loaded before Toolbar plugin."),void 0;var e={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"};Prism.plugins.toolbar.registerButton("show-language",function(t){var a=t.element.parentNode;if(a&&/pre/i.test(a.nodeName)){var s=a.getAttribute("data-language")||e[t.language]||t.language&&t.language.substring(0,1).toUpperCase()+t.language.substring(1);if(s){var i=document.createElement("span");return i.textContent=s,i}}})}}();

View File

@ -0,0 +1,89 @@
<div>[% foo.bar.baz %]</div>
<div>[%- foo.bar.baz %]</div>
<div>[% foo.bar.baz -%]</div>
<div>[%- foo.bar.baz -%]</div>
----------------------------------------------------
[
["tag", [
["tag", [
["punctuation", "<"],
"div"
]],
["punctuation", ">"]
]],
["tt2", [
["delimiter", "[%"],
["variable", "foo.bar.baz"],
["delimiter", "%]"]
]],
["tag", [
["tag", [
["punctuation", "</"],
"div"
]],
["punctuation", ">"]
]],
["tag", [
["tag", [
["punctuation", "<"],
"div"
]],
["punctuation", ">"]
]],
["tt2", [
["delimiter", "[%-"],
["variable", "foo.bar.baz"],
["delimiter", "%]"]
]],
["tag", [
["tag", [
["punctuation", "</"],
"div"
]],
["punctuation", ">"]
]],
["tag", [
["tag", [
["punctuation", "<"],
"div"
]],
["punctuation", ">"]
]],
["tt2", [
["delimiter", "[%"],
["variable", "foo.bar.baz"],
["delimiter", "-%]"]
]],
["tag", [
["tag", [
["punctuation", "</"],
"div"
]],
["punctuation", ">"]
]],
["tag", [
["tag", [
["punctuation", "<"],
"div"
]],
["punctuation", ">"]
]],
["tt2", [
["delimiter", "[%-"],
["variable", "foo.bar.baz"],
["delimiter", "-%]"]
]],
["tag", [
["tag", [
["punctuation", "</"],
"div"
]],
["punctuation", ">"]
]]
]
----------------------------------------------------
Checks for Template Toolkit 2 inside Markup.

View File

@ -0,0 +1,36 @@
[%# this entire directive is ignored no
matter how many lines it wraps onto
%]
[% # this is a comment
theta = 20 # so is this
rho = 30 # <aol>me too!</aol>
%]
----------------------------------------------------
[
["tt2",
[
["comment", "[%# this entire directive is ignored no\r\n matter how many lines it wraps onto\r\n%]" ]
]
],
["tt2",
[
["delimiter", "[%"],
["comment", "# this is a comment" ],
["variable", "theta"],
["operator", "="],
["number", "20"],
["comment", "# so is this" ],
["variable", "rho"],
["operator", "="],
["number", "30"],
["comment", "# <aol>me too!</aol>"],
["delimiter", "%]"]
]
]
]
----------------------------------------------------
Checks for single-line and multi-line comments.

View File

@ -0,0 +1,18 @@
[%- %]
[% -%]
[%- -%]
[%
%]
----------------------------------------------------
[
["tt2", [["delimiter", "[%-"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["delimiter", "-%]"]]],
["tt2", [["delimiter", "[%-"], ["delimiter", "-%]"]]],
["tt2", [["delimiter", "[%"], ["delimiter", "%]"]]]
]
----------------------------------------------------
Checks for delimiters.

View File

@ -0,0 +1,130 @@
[% BLOCK header %]
[% CALL dbi.disconnect %]
[% CASE 23 %]
[% CATCH the.ball %]
[% CLEAR %]
[% DEBUG on %]
[% DEBUG off %]
[% DEFAULT answer = 42 %]
[% ELSE %]
[% ELSIF bar %]
[% END %]
[% FILTER html %]
[% FINAL breathe %]
[% FOREACH project IN time %]
[% GET foo %]
[% IF foo %]
[% IN %]
[% INCLUDE "$inc" %]
[% INSERT filename.html %]
[% LAST IF exhausted %]
[% MACRO header INCLUDE header %]
[% META title = 'Hello!' %]
[% NEXT IF client %]
[% PERL %]
[% PROCESS "functions.tt" %]
[% RAWPERL %]
[% RETURN %]
[% SET answer = 42 %]
[% STOP %]
[% SWITCH mday %]
[% TAGS [@ @] %]
[% THROW up %]
[% TRY %]
[% UNLESS fear %]
[% USE Plugin %]
[% WHILE my.guitar.gently.weeps %]
[% WRAPPER 'html5.html' %]
----------------------------------------------------
[
["tt2", [["delimiter", "[%"], ["keyword", "BLOCK"],
["variable", "header"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "CALL"],
["variable", "dbi.disconnect"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "CASE"],
["number", "23"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "CATCH"],
["variable", "the.ball"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "CLEAR"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "DEBUG"],
["variable", "on"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "DEBUG"],
["variable", "off"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "DEFAULT"],
["variable", "answer"], ["operator", "="], ["number", "42"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "ELSE"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "ELSIF"], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "END"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "FILTER"], ["variable", "html"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "FINAL"],
["variable", "breathe"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "FOREACH"],
["variable", "project"], ["keyword", "IN"], ["variable", "time"] ,
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "GET"],
["variable", "foo"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "IF"], ["variable", "foo"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "IN"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "INCLUDE"],
["double-quoted-string", ["\"", ["variable", "$inc"], "\""]],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "INSERT"],
["variable", "filename.html"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "LAST"],
["keyword", "IF"], ["variable", "exhausted"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "MACRO"], ["variable", "header"],
["keyword", "INCLUDE"], ["variable", "header"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "META"],
["variable", "title"], ["operator", "="], ["single-quoted-string", "'Hello!'"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "NEXT"],
["keyword", "IF"], ["variable", "client"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "PERL"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "PROCESS"],
["double-quoted-string", ["\"functions.tt\""]],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "RAWPERL"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "RETURN"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "SET"],
["variable", "answer"], ["operator", "="], ["number", "42"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "STOP"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "SWITCH"], ["variable", "mday"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "TAGS"],
["punctuation", "["], "@ @", ["punctuation", "]"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "THROW"],
["variable", "up"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "TRY"], ["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "UNLESS"], ["variable", "fear"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "USE"], ["variable", "Plugin"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "WHILE"],
["variable", "my.guitar.gently.weeps"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"], ["keyword", "WRAPPER"],
["single-quoted-string", "'html5.html'"],
["delimiter", "%]"]]]
]
----------------------------------------------------
Checks for keywords.

View File

@ -0,0 +1,69 @@
[% fat => comma %]
[% foo == bar %]
[% foo != bar %]
[% foo < bar %]
[% foo <= bar %]
[% foo > bar %]
[% foo >= bar %]
[% foo = bar %]
[% foo && bar %]
[% foo || bar %]
[% foo | bar %]
[% foo ! bar %]
[% penthouse and pavement %]
[% sooner or later %]
[% love not war %]
----------------------------------------------------
[
["tt2", [["delimiter", "[%"],
["variable", "fat"], ["operator", "=>"], ["variable", "comma"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "=="], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "!="], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "<"], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "<="], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", ">"], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", ">="], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "="], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "&&"], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "||"], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "|"], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "foo"], ["operator", "!"], ["variable", "bar"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "penthouse"], ["operator", "and"], ["variable", "pavement"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "sooner"], ["operator", "or"], ["variable", "later"],
["delimiter", "%]"]]],
["tt2", [["delimiter", "[%"],
["variable", "love"], ["operator", "not"], ["variable", "war"],
["delimiter", "%]"]]]
]
----------------------------------------------------
Checks for operators.

View File

@ -0,0 +1,21 @@
[% "Hello, $name!" %]
----------------------------------------------------
[
["tt2",
[
["delimiter", "[%"],
["double-quoted-string", [
"\"Hello, ",
["variable", "$name"],
"!\""]
],
["delimiter", "%]"]
]
]
]
----------------------------------------------------
Checks for interpolation inside strings.

View File

@ -0,0 +1,35 @@
[%
"https://example.com/"
" # not a comment"
"multi-line
string"
"escaped \"quotes\"\nwork\twell"
'https://example.com/'
' # not a comment'
'multi-line
string'
'escaped \'quotes\' work'
%]
----------------------------------------------------
[
["tt2",
[
["delimiter", "[%"],
["double-quoted-string", ["\"https://example.com/\""]],
["double-quoted-string", ["\" # not a comment\""]],
["double-quoted-string", ["\"multi-line\r\nstring\""]],
["double-quoted-string", ["\"escaped \\\"quotes\\\"\\nwork\\twell\""]],
["single-quoted-string", "'https://example.com/'"],
["single-quoted-string", "' # not a comment'"],
["single-quoted-string", "'multi-line\r\nstring'"],
["single-quoted-string", "'escaped \\'quotes\\' work'"],
["delimiter", "%]"]
]
]
]
----------------------------------------------------
Checks for strings.

View File

@ -0,0 +1,36 @@
[%
foo
foo.bar
foo.2
foo.1.bar.2.baz.3
foo.$index
foo
.
bar
world
hands
knots
%]
----------------------------------------------------
[
["tt2",
[
["delimiter", "[%"],
["variable", "foo"],
["variable", "foo.bar"],
["variable", "foo.2"],
["variable", "foo.1.bar.2.baz.3"],
["variable", "foo.$index"],
["variable", "foo\r\n\t\t.\r\n\t\t\tbar"],
["variable", "world"],
["variable", "hands"],
["variable", "knots"],
["delimiter", "%]"]
]
]
]
----------------------------------------------------
Checks for simple variables.