Added support for FTL (#2080)

This adds support for FTL (Freemarker language).
This commit is contained in:
Michael Schmidt 2019-10-16 11:18:57 +02:00 committed by GitHub
parent fdb7de0d49
commit 2f3da7e8d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 740 additions and 3 deletions

File diff suppressed because one or more lines are too long

View File

@ -303,6 +303,11 @@
"title": "Fortran",
"owner": "Golmote"
},
"ftl": {
"title": "FreeMarker Template Language",
"require": "markup-templating",
"owner": "RunDevelopment"
},
"gcode": {
"title": "G-code",
"owner": "RunDevelopment"

97
components/prism-ftl.js Normal file
View File

@ -0,0 +1,97 @@
(function (Prism) {
// https://freemarker.apache.org/docs/dgui_template_exp.html
// FTL expression with 4 levels of nesting supported
var FTL_EXPR = /(?!<#--)[^()"']|\((?:<expr>)*\)|<#--[\s\S]*?-->|"(?:[^\\"]|\\.)*"|'(?:[^\\']|\\.)*'/.source;
for (var i = 0; i < 2; i++) {
FTL_EXPR = FTL_EXPR.replace(/<expr>/g, FTL_EXPR);
}
FTL_EXPR = FTL_EXPR.replace(/<expr>/g, '[^\s\S]');
var ftl = {
'comment': /<#--[\s\S]*?-->/,
'string': [
{
// raw string
pattern: /\br("|')(?:(?!\1)[^\\]|\\.)*\1/,
greedy: true
},
{
pattern: RegExp(/("|')(?:(?!\1|\$\{)[^\\]|\\.|\$\{(?:<expr>)*?\})*\1/.source.replace(/<expr>/g, FTL_EXPR)),
greedy: true,
inside: {
'interpolation': {
pattern: RegExp(/((?:^|[^\\])(?:\\\\)*)\$\{(?:<expr>)*?\}/.source.replace(/<expr>/g, FTL_EXPR)),
lookbehind: true,
inside: {
'interpolation-punctuation': {
pattern: /^\$\{|\}$/,
alias: 'punctuation'
},
rest: null
}
}
}
}
],
'keyword': /\b(?:as)\b/,
'boolean': /\b(?:true|false)\b/,
'builtin-function': {
pattern: /((?:^|[^?])\?\s*)\w+/,
lookbehind: true,
alias: 'function'
},
'function': /\w+(?=\s*\()/,
'number': /\d+(?:\.\d+)?/,
'operator': /\.\.[<*!]?|->|--|\+\+|&&|\|\||\?{1,2}|[-+*/%!=<>]=?|\b(?:gt|gte|lt|lte)\b/,
'punctuation': /[,;.:()[\]{}]/
};
ftl.string[1].inside.interpolation.inside.rest = ftl;
Prism.languages.ftl = {
'ftl-comment': {
// the pattern is shortened to be more efficient
pattern: /^<#--[\s\S]*/,
alias: 'comment'
},
'ftl-directive': {
pattern: /^<[\s\S]+>$/,
inside: {
'directive': {
pattern: /(^<\/?)[#@][a-z]\w*/i,
lookbehind: true,
alias: 'keyword'
},
'punctuation': /^<\/?|\/?>$/,
'content': {
pattern: /[\s\S]*\S[\s\S]*/,
alias: 'ftl',
inside: ftl
}
}
},
'ftl-interpolation': {
pattern: /^\$\{[\s\S]*\}$/,
inside: {
'punctuation': /^\$\{|\}$/,
'content': {
pattern: /[\s\S]*\S[\s\S]*/,
alias: 'ftl',
inside: ftl
}
}
}
};
Prism.hooks.add('before-tokenize', function (env) {
var pattern = RegExp(/<#--[\s\S]*?-->|<\/?[#@][a-zA-Z](?:<expr>)*?>|\$\{(?:<expr>)*?\}/.source.replace(/<expr>/g, FTL_EXPR), 'gi');
Prism.languages['markup-templating'].buildPlaceholders(env, 'ftl', pattern);
});
Prism.hooks.add('after-tokenize', function (env) {
Prism.languages['markup-templating'].tokenizePlaceholders(env, 'ftl');
});
}(Prism));

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

@ -0,0 +1 @@
!function(n){for(var a="(?!<#--)[^()\"']|\\((?:<expr>)*\\)|<#--[\\s\\S]*?--\x3e|\"(?:[^\\\\\"]|\\\\.)*\"|'(?:[^\\\\']|\\\\.)*'",e=0;e<2;e++)a=a.replace(/<expr>/g,a);a=a.replace(/<expr>/g,"[^sS]");var t={comment:/<#--[\s\S]*?-->/,string:[{pattern:/\br("|')(?:(?!\1)[^\\]|\\.)*\1/,greedy:!0},{pattern:RegExp("(\"|')(?:(?!\\1|\\$\\{)[^\\\\]|\\\\.|\\$\\{(?:<expr>)*?\\})*\\1".replace(/<expr>/g,a)),greedy:!0,inside:{interpolation:{pattern:RegExp("((?:^|[^\\\\])(?:\\\\\\\\)*)\\$\\{(?:<expr>)*?\\}".replace(/<expr>/g,a)),lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:null}}}}],keyword:/\b(?:as)\b/,boolean:/\b(?:true|false)\b/,"builtin-function":{pattern:/((?:^|[^?])\?\s*)\w+/,lookbehind:!0,alias:"function"},function:/\w+(?=\s*\()/,number:/\d+(?:\.\d+)?/,operator:/\.\.[<*!]?|->|--|\+\+|&&|\|\||\?{1,2}|[-+*/%!=<>]=?|\b(?:gt|gte|lt|lte)\b/,punctuation:/[,;.:()[\]{}]/};t.string[1].inside.interpolation.inside.rest=t,n.languages.ftl={"ftl-comment":{pattern:/^<#--[\s\S]*/,alias:"comment"},"ftl-directive":{pattern:/^<[\s\S]+>$/,inside:{directive:{pattern:/(^<\/?)[#@][a-z]\w*/i,lookbehind:!0,alias:"keyword"},punctuation:/^<\/?|\/?>$/,content:{pattern:/[\s\S]*\S[\s\S]*/,alias:"ftl",inside:t}}},"ftl-interpolation":{pattern:/^\$\{[\s\S]*\}$/,inside:{punctuation:/^\$\{|\}$/,content:{pattern:/[\s\S]*\S[\s\S]*/,alias:"ftl",inside:t}}}},n.hooks.add("before-tokenize",function(e){var t=RegExp("<#--[\\s\\S]*?--\x3e|<\\/?[#@][a-zA-Z](?:<expr>)*?>|\\$\\{(?:<expr>)*?\\}".replace(/<expr>/g,a),"gi");n.languages["markup-templating"].buildPlaceholders(e,"ftl",t)}),n.hooks.add("after-tokenize",function(e){n.languages["markup-templating"].tokenizePlaceholders(e,"ftl")})}(Prism);

21
examples/prism-ftl.html Normal file
View File

@ -0,0 +1,21 @@
<h2>Full example</h2>
<pre><code>&lt;html>
&lt;head>
&lt;title>Welcome!&lt;/title>
&lt;/head>
&lt;body>
&lt;h1>
Welcome ${user}&lt;#if user == "Big Joe">, our beloved leader&lt;/#if>!
&lt;/h1>
&lt;p>Our latest product:
&lt;a href="${latestProduct.url}">${latestProduct.name}&lt;/a>!
&lt;p>See what our happy customers have to say!&lt;/p>
&lt;ul>
&lt;#list userStories as story>
&lt;li>
&lt;p>${story.text?esc} - by &lt;span>${story.user.name}&lt;/span>
&lt;li>
&lt;/#list>
&lt;/ul>
&lt;/body>
&lt;/html></code></pre>

View File

@ -33,6 +33,7 @@
"fsharp": "clike",
"firestore-security-rules": "clike",
"flow": "javascript",
"ftl": "markup-templating",
"glsl": "clike",
"gml": "clike",
"go": "clike",

View File

@ -1 +1 @@
!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var c={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-templating",ejs:["javascript","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike","firestore-security-rules":"clike",flow:"javascript",glsl:"clike",gml:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike"],"js-extras":"javascript","js-templates":"javascript",jsonp:"json",json5:"json",kotlin:"clike",less:"css",lilypond:"scheme",markdown:"markup","markup-templating":"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:["clike","markup-templating"],phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],qore:"clike",jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sas:"sql",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",solidity:"clike",soy:"markup-templating",sparql:"turtle",swift:"clike",tap:"yaml",textile:"markup",tt2:["clike","markup-templating"],twig:"markup",typescript:"javascript","t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","visual-basic"],vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup",xquery:"markup"},l={html:"markup",xml:"markup",svg:"markup",mathml:"markup",js:"javascript",adoc:"asciidoc",shell:"bash",rbnf:"bnf",cs:"csharp",dotnet:"csharp",coffee:"coffeescript",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gamemakerlanguage:"gml",hs:"haskell",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",n4jsd:"n4js",objectpascal:"pascal",px:"pcaxis",py:"python",robot:"robot-framework",rb:"ruby",rq:"sparql",trig:"turtle",ts:"typescript",t4:"t4-cs",vb:"visual-basic",xeoracube:"xeora",yml:"yaml"},n={},e=document.getElementsByTagName("script"),a=e[e.length-1],t="components/",s=/\bplugins\/autoloader\/prism-autoloader\.(?:min\.)js$/i,i=/[\w-]+\.(?:min\.)js$/i;if(a.hasAttribute("data-autoloader-path"))t=a.getAttribute("data-autoloader-path").trim().replace(/\/?$/,"/");else{var r=a.src;s.test(r)?t=r.replace(s,"components/"):i.test(r)&&(t=r.replace(i,"components/"))}var p=Prism.plugins.autoloader={languages_path:t,use_minified:!0,loadLanguages:o};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&"none"!==e.language&&function(e,a){e in l&&(e=l[e]);var t=a.getAttribute("data-dependencies"),s=a.parentElement;!t&&s&&"pre"===s.tagName.toLowerCase()&&(t=s.getAttribute("data-dependencies")),o(t=t?t.split(/\s*,\s*/g):[],function(){m(e,function(){Prism.highlightElement(a)})})}(e.language,e.element)})}function o(e,a,t){"string"==typeof e&&(e=[e]);var s=e.length,i=0,r=!1;function c(){r||++i===s&&a&&a(e)}0!==s?e.forEach(function(e){m(e,c,function(){r||(r=!0,t&&t(e))})}):a&&setTimeout(a,0)}function m(a,t,s){var i=0<=a.indexOf("!");a=a.replace("!",""),a=l[a]||a;var e=function(){var e=n[a];if(e||(e=n[a]={callbacks:[]}),e.callbacks.push({success:t,error:s}),!i&&Prism.languages[a])u(a,"success");else if(!i&&e.error)u(a,"error");else if(i||!e.loading){e.loading=!0,function(e,a,t){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),a&&a()},s.onerror=function(){document.body.removeChild(s),t&&t()},document.body.appendChild(s)}(function(e){return p.languages_path+"prism-"+e+(p.use_minified?".min":"")+".js"}(a),function(){e.loading=!1,u(a,"success")},function(){e.loading=!1,e.error=!0,u(a,"error")})}},r=c[a];r&&r.length?o(r,e,s):e()}function u(e,a){if(n[e]){for(var t=n[e].callbacks,s=0,i=t.length;s<i;s++){var r=t[s][a];r&&setTimeout(r,0)}t.length=0}}}();
!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var c={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-templating",ejs:["javascript","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike","firestore-security-rules":"clike",flow:"javascript",ftl:"markup-templating",glsl:"clike",gml:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike"],"js-extras":"javascript","js-templates":"javascript",jsonp:"json",json5:"json",kotlin:"clike",less:"css",lilypond:"scheme",markdown:"markup","markup-templating":"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:["clike","markup-templating"],phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],qore:"clike",jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sas:"sql",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",solidity:"clike",soy:"markup-templating",sparql:"turtle",swift:"clike",tap:"yaml",textile:"markup",tt2:["clike","markup-templating"],twig:"markup",typescript:"javascript","t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","visual-basic"],vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup",xquery:"markup"},l={html:"markup",xml:"markup",svg:"markup",mathml:"markup",js:"javascript",adoc:"asciidoc",shell:"bash",rbnf:"bnf",cs:"csharp",dotnet:"csharp",coffee:"coffeescript",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gamemakerlanguage:"gml",hs:"haskell",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",n4jsd:"n4js",objectpascal:"pascal",px:"pcaxis",py:"python",robot:"robot-framework",rb:"ruby",rq:"sparql",trig:"turtle",ts:"typescript",t4:"t4-cs",vb:"visual-basic",xeoracube:"xeora",yml:"yaml"},n={},e=document.getElementsByTagName("script"),a=e[e.length-1],t="components/",s=/\bplugins\/autoloader\/prism-autoloader\.(?:min\.)js$/i,i=/[\w-]+\.(?:min\.)js$/i;if(a.hasAttribute("data-autoloader-path"))t=a.getAttribute("data-autoloader-path").trim().replace(/\/?$/,"/");else{var r=a.src;s.test(r)?t=r.replace(s,"components/"):i.test(r)&&(t=r.replace(i,"components/"))}var p=Prism.plugins.autoloader={languages_path:t,use_minified:!0,loadLanguages:o};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&"none"!==e.language&&function(e,a){e in l&&(e=l[e]);var t=a.getAttribute("data-dependencies"),s=a.parentElement;!t&&s&&"pre"===s.tagName.toLowerCase()&&(t=s.getAttribute("data-dependencies")),o(t=t?t.split(/\s*,\s*/g):[],function(){m(e,function(){Prism.highlightElement(a)})})}(e.language,e.element)})}function o(e,a,t){"string"==typeof e&&(e=[e]);var s=e.length,i=0,r=!1;function c(){r||++i===s&&a&&a(e)}0!==s?e.forEach(function(e){m(e,c,function(){r||(r=!0,t&&t(e))})}):a&&setTimeout(a,0)}function m(a,t,s){var i=0<=a.indexOf("!");a=a.replace("!",""),a=l[a]||a;var e=function(){var e=n[a];if(e||(e=n[a]={callbacks:[]}),e.callbacks.push({success:t,error:s}),!i&&Prism.languages[a])u(a,"success");else if(!i&&e.error)u(a,"error");else if(i||!e.loading){e.loading=!0,function(e,a,t){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),a&&a()},s.onerror=function(){document.body.removeChild(s),t&&t()},document.body.appendChild(s)}(function(e){return p.languages_path+"prism-"+e+(p.use_minified?".min":"")+".js"}(a),function(){e.loading=!1,u(a,"success")},function(){e.loading=!1,e.error=!0,u(a,"error")})}},r=c[a];r&&r.length?o(r,e,s):e()}function u(e,a){if(n[e]){for(var t=n[e].callbacks,s=0,i=t.length;s<i;s++){var r=t[s][a];r&&setTimeout(r,0)}t.length=0}}}();

View File

@ -54,6 +54,7 @@
"erb": "ERB",
"fsharp": "F#",
"firestore-security-rules": "Firestore security rules",
"ftl": "FreeMarker Template Language",
"gcode": "G-code",
"gdscript": "GDScript",
"gedcom": "GEDCOM",

View File

@ -1 +1 @@
!function(){if("undefined"!=typeof self&&self.Prism&&self.document)if(Prism.plugins.toolbar){var r={html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",css:"CSS",clike:"C-like",js:"JavaScript",abap:"ABAP",abnf:"Augmented BackusNaur form",apacheconf:"Apache Configuration",apl:"APL",aql:"AQL",arff:"ARFF",asciidoc:"AsciiDoc",adoc:"AsciiDoc",asm6502:"6502 Assembly",aspnet:"ASP.NET (C#)",autohotkey:"AutoHotkey",autoit:"AutoIt",shell:"Bash",basic:"BASIC",bnf:"BackusNaur form",rbnf:"Routing BackusNaur form",csharp:"C#",cs:"C#",dotnet:"C#",cpp:"C++",cil:"CIL",coffee:"CoffeeScript",cmake:"CMake",csp:"Content-Security-Policy","css-extras":"CSS Extras",django:"Django/Jinja2",jinja2:"Django/Jinja2","dns-zone-file":"DNS zone file","dns-zone":"DNS zone file",dockerfile:"Docker",ebnf:"Extended BackusNaur form",ejs:"EJS",erb:"ERB",fsharp:"F#","firestore-security-rules":"Firestore security rules",gcode:"G-code",gdscript:"GDScript",gedcom:"GEDCOM",glsl:"GLSL",gml:"GameMaker Language",gamemakerlanguage:"GameMaker Language",graphql:"GraphQL",hs:"Haskell",hcl:"HCL",http:"HTTP",hpkp:"HTTP Public-Key-Pins",hsts:"HTTP Strict-Transport-Security",ichigojam:"IchigoJam",inform7:"Inform 7",javadoc:"JavaDoc",javadoclike:"JavaDoc-like",javastacktrace:"Java stack trace",jq:"JQ",jsdoc:"JSDoc","js-extras":"JS Extras","js-templates":"JS Templates",json:"JSON",jsonp:"JSONP",json5:"JSON5",latex:"LaTeX",tex:"TeX",context:"ConTeXt",lilypond:"LilyPond",ly:"LilyPond",emacs:"Lisp",elisp:"Lisp","emacs-lisp":"Lisp",lolcode:"LOLCODE",md:"Markdown","markup-templating":"Markup templating",matlab:"MATLAB",mel:"MEL",n1ql:"N1QL",n4js:"N4JS",n4jsd:"N4JS","nand2tetris-hdl":"Nand To Tetris HDL",nasm:"NASM",nginx:"nginx",nsis:"NSIS",objectivec:"Objective-C",ocaml:"OCaml",opencl:"OpenCL",parigp:"PARI/GP",objectpascal:"Object Pascal",pcaxis:"PC-Axis",px:"PC-Axis",php:"PHP",phpdoc:"PHPDoc","php-extras":"PHP Extras",plsql:"PL/SQL",powershell:"PowerShell",properties:".properties",protobuf:"Protocol Buffers",py:"Python",q:"Q (kdb+ database)",jsx:"React JSX",tsx:"React TSX",renpy:"Ren'py",rest:"reST (reStructuredText)","robot-framework":"Robot Framework",robot:"Robot Framework",rb:"Ruby",sas:"SAS",sass:"Sass (Sass)",scss:"Sass (Scss)","shell-session":"Shell session",solidity:"Solidity (Ethereum)",soy:"Soy (Closure Template)",sparql:"SPARQL",rq:"SPARQL","splunk-spl":"Splunk SPL",sql:"SQL",tap:"TAP",toml:"TOML",tt2:"Template Toolkit 2",trig:"TriG",ts:"TypeScript","t4-cs":"T4 Text Templates (C#)",t4:"T4 Text Templates (C#)","t4-vb":"T4 Text Templates (VB)","t4-templating":"T4 templating",vbnet:"VB.Net",vhdl:"VHDL",vim:"vim","visual-basic":"Visual Basic",vb:"Visual Basic",wasm:"WebAssembly",wiki:"Wiki markup",xeoracube:"XeoraCube",xojo:"Xojo (REALbasic)",xquery:"XQuery",yaml:"YAML",yml:"YAML"};Prism.plugins.toolbar.registerButton("show-language",function(e){var a=e.element.parentNode;if(a&&/pre/i.test(a.nodeName)){var s,t=a.getAttribute("data-language")||r[e.language]||((s=e.language)?(s.substring(0,1).toUpperCase()+s.substring(1)).replace(/s(?=cript)/,"S"):s);if(t){var o=document.createElement("span");return o.textContent=t,o}}})}else console.warn("Show Languages plugin loaded before Toolbar plugin.")}();
!function(){if("undefined"!=typeof self&&self.Prism&&self.document)if(Prism.plugins.toolbar){var r={html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",css:"CSS",clike:"C-like",js:"JavaScript",abap:"ABAP",abnf:"Augmented BackusNaur form",apacheconf:"Apache Configuration",apl:"APL",aql:"AQL",arff:"ARFF",asciidoc:"AsciiDoc",adoc:"AsciiDoc",asm6502:"6502 Assembly",aspnet:"ASP.NET (C#)",autohotkey:"AutoHotkey",autoit:"AutoIt",shell:"Bash",basic:"BASIC",bnf:"BackusNaur form",rbnf:"Routing BackusNaur form",csharp:"C#",cs:"C#",dotnet:"C#",cpp:"C++",cil:"CIL",coffee:"CoffeeScript",cmake:"CMake",csp:"Content-Security-Policy","css-extras":"CSS Extras",django:"Django/Jinja2",jinja2:"Django/Jinja2","dns-zone-file":"DNS zone file","dns-zone":"DNS zone file",dockerfile:"Docker",ebnf:"Extended BackusNaur form",ejs:"EJS",erb:"ERB",fsharp:"F#","firestore-security-rules":"Firestore security rules",ftl:"FreeMarker Template Language",gcode:"G-code",gdscript:"GDScript",gedcom:"GEDCOM",glsl:"GLSL",gml:"GameMaker Language",gamemakerlanguage:"GameMaker Language",graphql:"GraphQL",hs:"Haskell",hcl:"HCL",http:"HTTP",hpkp:"HTTP Public-Key-Pins",hsts:"HTTP Strict-Transport-Security",ichigojam:"IchigoJam",inform7:"Inform 7",javadoc:"JavaDoc",javadoclike:"JavaDoc-like",javastacktrace:"Java stack trace",jq:"JQ",jsdoc:"JSDoc","js-extras":"JS Extras","js-templates":"JS Templates",json:"JSON",jsonp:"JSONP",json5:"JSON5",latex:"LaTeX",tex:"TeX",context:"ConTeXt",lilypond:"LilyPond",ly:"LilyPond",emacs:"Lisp",elisp:"Lisp","emacs-lisp":"Lisp",lolcode:"LOLCODE",md:"Markdown","markup-templating":"Markup templating",matlab:"MATLAB",mel:"MEL",n1ql:"N1QL",n4js:"N4JS",n4jsd:"N4JS","nand2tetris-hdl":"Nand To Tetris HDL",nasm:"NASM",nginx:"nginx",nsis:"NSIS",objectivec:"Objective-C",ocaml:"OCaml",opencl:"OpenCL",parigp:"PARI/GP",objectpascal:"Object Pascal",pcaxis:"PC-Axis",px:"PC-Axis",php:"PHP",phpdoc:"PHPDoc","php-extras":"PHP Extras",plsql:"PL/SQL",powershell:"PowerShell",properties:".properties",protobuf:"Protocol Buffers",py:"Python",q:"Q (kdb+ database)",jsx:"React JSX",tsx:"React TSX",renpy:"Ren'py",rest:"reST (reStructuredText)","robot-framework":"Robot Framework",robot:"Robot Framework",rb:"Ruby",sas:"SAS",sass:"Sass (Sass)",scss:"Sass (Scss)","shell-session":"Shell session",solidity:"Solidity (Ethereum)",soy:"Soy (Closure Template)",sparql:"SPARQL",rq:"SPARQL","splunk-spl":"Splunk SPL",sql:"SQL",tap:"TAP",toml:"TOML",tt2:"Template Toolkit 2",trig:"TriG",ts:"TypeScript","t4-cs":"T4 Text Templates (C#)",t4:"T4 Text Templates (C#)","t4-vb":"T4 Text Templates (VB)","t4-templating":"T4 templating",vbnet:"VB.Net",vhdl:"VHDL",vim:"vim","visual-basic":"Visual Basic",vb:"Visual Basic",wasm:"WebAssembly",wiki:"Wiki markup",xeoracube:"XeoraCube",xojo:"Xojo (REALbasic)",xquery:"XQuery",yaml:"YAML",yml:"YAML"};Prism.plugins.toolbar.registerButton("show-language",function(e){var a=e.element.parentNode;if(a&&/pre/i.test(a.nodeName)){var s,t=a.getAttribute("data-language")||r[e.language]||((s=e.language)?(s.substring(0,1).toUpperCase()+s.substring(1)).replace(/s(?=cript)/,"S"):s);if(t){var o=document.createElement("span");return o.textContent=t,o}}})}else console.warn("Show Languages plugin loaded before Toolbar plugin.")}();

View File

@ -0,0 +1,24 @@
${true == !false}
----------------------------------------------------
[
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
["boolean", "true"],
["operator", "=="],
["operator", "!"],
["boolean", "false"]
]],
["punctuation", "}"]
]]
]]
]
----------------------------------------------------
Checks for booleans.

View File

@ -0,0 +1,78 @@
${testString?upper_case}
${testString?html}
${testString?upper_case?html}
${testSequence?size}
${testSequence?join(", ")}
----------------------------------------------------
[
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
"testString",
["operator", "?"],
["builtin-function", "upper_case"]
]],
["punctuation", "}"]
]]
]],
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
"testString",
["operator", "?"],
["builtin-function", "html"]
]],
["punctuation", "}"]
]]
]],
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
"testString",
["operator", "?"],
["builtin-function", "upper_case"],
["operator", "?"],
["builtin-function", "html"]
]],
["punctuation", "}"]
]]
]],
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
"testSequence",
["operator", "?"],
["builtin-function", "size"]
]],
["punctuation", "}"]
]]
]],
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
"testSequence",
["operator", "?"],
["builtin-function", "join"],
["punctuation", "("],
["string", [
"\", \""
]],
["punctuation", ")"]
]],
["punctuation", "}"]
]]
]]
]
----------------------------------------------------
Checks for builtin functions.

View File

@ -0,0 +1,117 @@
<#-- comment -->
<#assign x <#-- A comment --> = 123 <#-- A comment -->>
<#function f(x <#-- A comment -->, y <#-- A comment -->)>
<#return <#-- A comment --> 1 <#-- A comment -->>
</#function>
<#assign someHash = {
"foo": 123, <#-- A comment -->
"bar": x <#-- A comment --> + 1,
<#-- A comment -->
"baaz": f(1 <#-- A comment -->, 2 <#-- A comment -->)
} <#-- A comment -->>
----------------------------------------------------
[
["ftl", [
["ftl-comment", "<#-- comment -->"]
]],
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "#assign"],
["content", [
" x ",
["comment", "<#-- A comment -->"],
["operator", "="],
["number", "123"],
["comment", "<#-- A comment -->"]
]],
["punctuation", ">"]
]]
]],
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "#function"],
["content", [
["function", "f"],
["punctuation", "("],
"x ",
["comment", "<#-- A comment -->"],
["punctuation", ","],
" y ",
["comment", "<#-- A comment -->"],
["punctuation", ")"]
]],
["punctuation", ">"]
]]
]],
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "#return"],
["content", [
["comment", "<#-- A comment -->"],
["number", "1"],
["comment", "<#-- A comment -->"]
]],
["punctuation", ">"]
]]
]],
["ftl", [
["ftl-directive", [
["punctuation", "</"],
["directive", "#function"],
["punctuation", ">"]
]]
]],
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "#assign"],
["content", [
" someHash ",
["operator", "="],
["punctuation", "{"],
["string", [
"\"foo\""
]],
["punctuation", ":"],
["number", "123"],
["punctuation", ","],
["comment", "<#-- A comment -->"],
["string", [
"\"bar\""
]],
["punctuation", ":"],
" x ",
["comment", "<#-- A comment -->"],
["operator", "+"],
["number", "1"],
["punctuation", ","],
["comment", "<#-- A comment -->"],
["string", [
"\"baaz\""
]],
["punctuation", ":"],
["function", "f"],
["punctuation", "("],
["number", "1"],
["comment", "<#-- A comment -->"],
["punctuation", ","],
["number", "2"],
["comment", "<#-- A comment -->"],
["punctuation", ")"],
["punctuation", "}"],
["comment", "<#-- A comment -->"]
]],
["punctuation", ">"]
]]
]]
]
----------------------------------------------------
Checks for comments.

View File

@ -0,0 +1,84 @@
<#if a < b>
a is less than b
<#elseif (a > b)>
a is greater than b
<#else>
a is equal to by
</#if>
<@foo></@foo>
<@foo/>
----------------------------------------------------
[
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "#if"],
["content", [
" a ",
["operator", "<"],
" b"
]],
["punctuation", ">"]
]]
]],
"\r\n\ta is less than b\r\n",
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "#elseif"],
["content", [
["punctuation", "("],
"a ",
["operator", ">"],
" b",
["punctuation", ")"]
]],
["punctuation", ">"]
]]
]],
"\r\n\ta is greater than b\r\n",
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "#else"],
["punctuation", ">"]
]]
]],
"\r\n\ta is equal to by\r\n",
["ftl", [
["ftl-directive", [
["punctuation", "</"],
["directive", "#if"],
["punctuation", ">"]
]]
]],
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "@foo"],
["punctuation", ">"]
]]
]],
["ftl", [
["ftl-directive", [
["punctuation", "</"],
["directive", "@foo"],
["punctuation", ">"]
]]
]],
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "@foo"],
["punctuation", "/>"]
]]
]]
]
----------------------------------------------------
Checks for directive. This includes both predefined and user-defined ones.

View File

@ -0,0 +1,24 @@
${min(1,2)}
----------------------------------------------------
[
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
["function", "min"],
["punctuation", "("],
["number", "1"],
["punctuation", ","],
["number", "2"],
["punctuation", ")"]
]],
["punctuation", "}"]
]]
]]
]
----------------------------------------------------
Checks for functions.

View File

@ -0,0 +1,69 @@
<a href="${link}">${text}</a>
${ "{}foo${bar}" }
----------------------------------------------------
[
["tag", [
["tag", [
["punctuation", "<"],
"a"
]],
["attr-name", [
"href"
]],
["attr-value", [
["punctuation", "="],
["punctuation", "\""],
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
"link"
]],
["punctuation", "}"]
]]
]],
["punctuation", "\""]
]],
["punctuation", ">"]
]],
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
"text"
]],
["punctuation", "}"]
]]
]],
["tag", [
["tag", [
["punctuation", "</"],
"a"
]],
["punctuation", ">"]
]],
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
["string", [
"\"{}foo",
["interpolation", [
["interpolation-punctuation", "${"],
"bar",
["interpolation-punctuation", "}"]
]],
"\""
]]
]],
["punctuation", "}"]
]]
]]
]
----------------------------------------------------
Checks for template interpolation.

View File

@ -0,0 +1,29 @@
${
0
08
0.2
1233.42234
}
----------------------------------------------------
[
["ftl", [
["ftl-interpolation", [
["punctuation", "${"],
["content", [
["number", "0"],
["number", "08"],
["number", "0.2"],
["number", "1233.42234"]
]],
["punctuation", "}"]
]]
]]
]
----------------------------------------------------
Checks for numbers.

View File

@ -0,0 +1,77 @@
<@foo (
+ - * / %
+= -= *= /= %=
++ --
== != >= <= > <
gt gte lt lte
! && ||
? ??
->
.. ..* ..< ..!
)/>
----------------------------------------------------
[
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "@foo"],
["content", [
["punctuation", "("],
["operator", "+"],
["operator", "-"],
["operator", "*"],
["operator", "/"],
["operator", "%"],
["operator", "+="],
["operator", "-="],
["operator", "*="],
["operator", "/="],
["operator", "%="],
["operator", "++"],
["operator", "--"],
["operator", "=="],
["operator", "!="],
["operator", ">="],
["operator", "<="],
["operator", ">"],
["operator", "<"],
["operator", "gt"],
["operator", "gte"],
["operator", "lt"],
["operator", "lte"],
["operator", "!"],
["operator", "&&"],
["operator", "||"],
["operator", "?"],
["operator", "??"],
["operator", "->"],
["operator", ".."],
["operator", "..*"],
["operator", "..<"],
["operator", "..!"],
["punctuation", ")"]
]],
["punctuation", "/>"]
]]
]]
]
----------------------------------------------------
Checks for operators.

View File

@ -0,0 +1,37 @@
<@foo
() [] {}
, ; . :
/>
----------------------------------------------------
[
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "@foo"],
["content", [
["punctuation", "("],
["punctuation", ")"],
["punctuation", "["],
["punctuation", "]"],
["punctuation", "{"],
["punctuation", "}"],
["punctuation", ","],
["punctuation", ";"],
["punctuation", "."],
["punctuation", ":"]
]],
["punctuation", "/>"]
]]
]]
]
----------------------------------------------------
Checks for punctuation.

View File

@ -0,0 +1,72 @@
<@foo (
"foo'\"'
\"\\"
'foo\'
'
r"foo${bar}"
r'foo${bar}'
"foo${bar}"
'foo${bar + "foo}" + '}'}'
)/>
----------------------------------------------------
[
["ftl", [
["ftl-directive", [
["punctuation", "<"],
["directive", "@foo"],
["content", [
["punctuation", "("],
["string", [
"\"foo'\\\"'\r\n\\\"\\\\\""
]],
["string", [
"'foo\\'\r\n'"
]],
["string", "r\"foo${bar}\""],
["string", "r'foo${bar}'"],
["string", [
"\"foo",
["interpolation", [
["interpolation-punctuation", "${"],
"bar",
["interpolation-punctuation", "}"]
]],
"\""
]],
["string", [
"'foo",
["interpolation", [
["interpolation-punctuation", "${"],
"bar ",
["operator", "+"],
["string", [
"\"foo}\""
]],
["operator", "+"],
["string", [
"'}'"
]],
["interpolation-punctuation", "}"]
]],
"'"
]],
["punctuation", ")"]
]],
["punctuation", "/>"]
]]
]]
]
----------------------------------------------------
Checks for strings, raw string, and string with interpolations.