Skip to content

Commit

Permalink
Support for Template Toolkit 2 (#1418)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
gflohr authored and Golmote committed May 10, 2018
1 parent fa328bb commit e063992
Show file tree
Hide file tree
Showing 17 changed files with 565 additions and 5 deletions.
2 changes: 1 addition & 1 deletion components.js

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,11 @@
"require": "markup",
"owner": "Golmote"
},
"tt2": {
"title": "Template Toolkit 2",
"require": ["clike", "markup-templating"],
"owner": "gflohr"
},
"twig": {
"title": "Twig",
"require": "markup",
Expand Down
59 changes: 59 additions & 0 deletions components/prism-tt2.js
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions components/prism-tt2.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions examples/prism-tt2.html
Original file line number Diff line number Diff line change
@@ -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>
2 changes: 1 addition & 1 deletion plugins/autoloader/prism-autoloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {};

Expand Down
2 changes: 1 addition & 1 deletion plugins/autoloader/prism-autoloader.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/show-language/prism-show-language.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
Loading

0 comments on commit e063992

Please sign in to comment.