From d27b70dc48bde9f1df9b6cb0302aac89b4c0abe3 Mon Sep 17 00:00:00 2001 From: Golmote Date: Sat, 11 Nov 2017 23:42:44 +0100 Subject: [PATCH] Add support for Flow Fix #1216 --- components.js | 5 +++ components/prism-flow.js | 34 ++++++++++++++++ components/prism-flow.min.js | 1 + examples/prism-flow.html | 21 ++++++++++ plugins/autoloader/prism-autoloader.js | 2 +- plugins/autoloader/prism-autoloader.min.js | 2 +- .../flow/flow-punctuation_feature.test | 12 ++++++ .../flow/function-variable_feature.test | 20 ++++++++++ tests/languages/flow/keyword_feature.test | 39 +++++++++++++++++++ tests/languages/flow/type_feature.test | 31 +++++++++++++++ 10 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 components/prism-flow.js create mode 100644 components/prism-flow.min.js create mode 100644 examples/prism-flow.html create mode 100644 tests/languages/flow/flow-punctuation_feature.test create mode 100644 tests/languages/flow/function-variable_feature.test create mode 100644 tests/languages/flow/keyword_feature.test create mode 100644 tests/languages/flow/type_feature.test diff --git a/components.js b/components.js index 4b934ad4f7..48ab6dca46 100644 --- a/components.js +++ b/components.js @@ -202,6 +202,11 @@ var components = { "require": "clike", "owner": "simonreynolds7" }, + "flow": { + "title": "Flow", + "require": "javascript", + "owner": "Golmote" + }, "fortran": { "title": "Fortran", "owner": "Golmote" diff --git a/components/prism-flow.js b/components/prism-flow.js new file mode 100644 index 0000000000..7e42ed3c8b --- /dev/null +++ b/components/prism-flow.js @@ -0,0 +1,34 @@ +(function (Prism) { + Prism.languages.flow = Prism.languages.extend('javascript', {}); + + Prism.languages.insertBefore('flow', 'keyword', { + 'type': [ + { + pattern: /\b(?:[Nn]umber|[Ss]tring|[Bb]oolean|Function|any|mixed|null|void)\b/, + alias: 'tag' + } + ] + }); + Prism.languages.flow['function-variable'].pattern = /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)\s*=>))/i; + + Prism.languages.insertBefore('flow', 'operator', { + 'flow-punctuation': { + pattern: /\{\||\|\}/, + alias: 'punctuation' + } + }); + + if (Prism.util.type(Prism.languages.flow.keyword) !== 'Array') { + Prism.languages.flow.keyword = [Prism.languages.flow.keyword]; + } + Prism.languages.flow.keyword.unshift( + { + pattern: /(^|[^$]\b)(?:type|opaque|declare|Class)\b(?!\$)/, + lookbehind: true + }, + { + pattern: /(^|[^$]\B)\$(?:await|Diff|Exact|Keys|ObjMap|PropertyType|Shape|Record|Supertype|Subtype|Enum)\b(?!\$)/, + lookbehind: true + } + ); +}(Prism)); \ No newline at end of file diff --git a/components/prism-flow.min.js b/components/prism-flow.min.js new file mode 100644 index 0000000000..b966631088 --- /dev/null +++ b/components/prism-flow.min.js @@ -0,0 +1 @@ +!function(a){a.languages.flow=a.languages.extend("javascript",{}),a.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Nn]umber|[Ss]tring|[Bb]oolean|Function|any|mixed|null|void)\b/,alias:"tag"}]}),a.languages.flow["function-variable"].pattern=/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)\s*=>))/i,a.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),"Array"!==a.util.type(a.languages.flow.keyword)&&(a.languages.flow.keyword=[a.languages.flow.keyword]),a.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:type|opaque|declare|Class)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:await|Diff|Exact|Keys|ObjMap|PropertyType|Shape|Record|Supertype|Subtype|Enum)\b(?!\$)/,lookbehind:!0})}(Prism); \ No newline at end of file diff --git a/examples/prism-flow.html b/examples/prism-flow.html new file mode 100644 index 0000000000..2742d214e4 --- /dev/null +++ b/examples/prism-flow.html @@ -0,0 +1,21 @@ +

Flow

+

To use this language, use the class "language-flow".

+ +

Primitive types

+
function method(x: number, y: string, z: boolean) {}
+function stringifyBasicValue(value: string | number) {}
+function add(one: any, two: any): number {
+  return one + two;
+}
+
+const bar: number = 2;
+var barVar: number = 2;
+let barLet: number = 2;
+let isOneOf: number | boolean | string = foo;
+ +

Keywords

+
type UnionAlias = 1 | 2 | 3;
+opaque type ID = string;
+declare opaque type PositiveNumber: number;
+type Country = $Keys<typeof countries>;
+type RequiredProps = $Diff<Props, DefaultProps>;
\ No newline at end of file diff --git a/plugins/autoloader/prism-autoloader.js b/plugins/autoloader/prism-autoloader.js index 0a21d3d564..41f405d550 100644 --- a/plugins/autoloader/prism-autoloader.js +++ b/plugins/autoloader/prism-autoloader.js @@ -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","bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","django":"markup","fsharp":"clike","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup","haxe":"clike","java":"clike","jolie":"clike","kotlin":"clike","less":"css","markdown":"markup","n4js":"javascript","nginx":"clike","objectivec":"c","opencl":"cpp","parser":"markup","php":"clike","php-extras":"php","processing":"clike","protobuf":"clike","pug":"javascript","qore":"clike","jsx":["markup","javascript"],"reason":"clike","ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","vbnet":"basic","wiki":"markup"}/*]*/; + var lang_dependencies = /*languages_placeholder[*/{"javascript":"clike","actionscript":"javascript","arduino":"cpp","aspnet":"markup","bison":"c","c":"clike","csharp":"clike","cpp":"c","coffeescript":"javascript","crystal":"ruby","css-extras":"css","d":"clike","dart":"clike","django":"markup","fsharp":"clike","flow":"javascript","glsl":"clike","go":"clike","groovy":"clike","haml":"ruby","handlebars":"markup","haxe":"clike","java":"clike","jolie":"clike","kotlin":"clike","less":"css","markdown":"markup","n4js":"javascript","nginx":"clike","objectivec":"c","opencl":"cpp","parser":"markup","php":"clike","php-extras":"php","processing":"clike","protobuf":"clike","pug":"javascript","qore":"clike","jsx":["markup","javascript"],"reason":"clike","ruby":"clike","sass":"css","scss":"css","scala":"java","smarty":"markup","swift":"clike","textile":"markup","twig":"markup","typescript":"javascript","vbnet":"basic","wiki":"markup"}/*]*/; var lang_data = {}; diff --git a/plugins/autoloader/prism-autoloader.min.js b/plugins/autoloader/prism-autoloader.min.js index 2ce34e2b2e..bc8ce703cd 100644 --- a/plugins/autoloader/prism-autoloader.min.js +++ b/plugins/autoloader/prism-autoloader.min.js @@ -1 +1 @@ -!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={javascript:"clike",actionscript:"javascript",arduino:"cpp",aspnet:"markup",bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup",fsharp:"clike",glsl:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup",haxe:"clike",java:"clike",jolie:"clike",kotlin:"clike",less:"css",markdown:"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:"clike","php-extras":"php",processing:"clike",protobuf:"clike",pug:"javascript",qore:"clike",jsx:["markup","javascript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java",smarty:"markup",swift:"clike",textile:"markup",twig:"markup",typescript:"javascript",vbnet:"basic",wiki:"markup"},c={},a="none",s=Prism.plugins.autoloader={languages_path:"components/",use_minified:!0},n=function(e,c,a){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),c&&c()},s.onerror=function(){document.body.removeChild(s),a&&a()},document.body.appendChild(s)},r=function(e){return s.languages_path+"prism-"+e+(s.use_minified?".min":"")+".js"},i=function(e,a){var s=c[e];s||(s=c[e]={});var n=a.getAttribute("data-dependencies");!n&&a.parentNode&&"pre"===a.parentNode.tagName.toLowerCase()&&(n=a.parentNode.getAttribute("data-dependencies")),n=n?n.split(/\s*,\s*/g):[],t(n,function(){l(e,function(){Prism.highlightElement(a)})})},t=function(e,c,a){"string"==typeof e&&(e=[e]);var s=0,n=e.length,r=function(){n>s?l(e[s],function(){s++,r()},function(){a&&a(e[s])}):s===n&&c&&c(e)};r()},l=function(a,s,i){var l=function(){var e=!1;a.indexOf("!")>=0&&(e=!0,a=a.replace("!",""));var t=c[a];if(t||(t=c[a]={}),s&&(t.success_callbacks||(t.success_callbacks=[]),t.success_callbacks.push(s)),i&&(t.error_callbacks||(t.error_callbacks=[]),t.error_callbacks.push(i)),!e&&Prism.languages[a])o(a);else if(!e&&t.error)u(a);else if(e||!t.loading){t.loading=!0;var l=r(a);n(l,function(){t.loading=!1,o(a)},function(){t.loading=!1,t.error=!0,u(a)})}},p=e[a];p&&p.length?t(p,l):l()},o=function(e){c[e]&&c[e].success_callbacks&&c[e].success_callbacks.length&&c[e].success_callbacks.forEach(function(c){c(e)})},u=function(e){c[e]&&c[e].error_callbacks&&c[e].error_callbacks.length&&c[e].error_callbacks.forEach(function(c){c(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&e.language!==a&&i(e.language,e.element)})}}(); \ No newline at end of file +!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var e={javascript:"clike",actionscript:"javascript",arduino:"cpp",aspnet:"markup",bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup",fsharp:"clike",flow:"javascript",glsl:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup",haxe:"clike",java:"clike",jolie:"clike",kotlin:"clike",less:"css",markdown:"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:"clike","php-extras":"php",processing:"clike",protobuf:"clike",pug:"javascript",qore:"clike",jsx:["markup","javascript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java",smarty:"markup",swift:"clike",textile:"markup",twig:"markup",typescript:"javascript",vbnet:"basic",wiki:"markup"},c={},a="none",s=Prism.plugins.autoloader={languages_path:"components/",use_minified:!0},n=function(e,c,a){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),c&&c()},s.onerror=function(){document.body.removeChild(s),a&&a()},document.body.appendChild(s)},r=function(e){return s.languages_path+"prism-"+e+(s.use_minified?".min":"")+".js"},i=function(e,a){var s=c[e];s||(s=c[e]={});var n=a.getAttribute("data-dependencies");!n&&a.parentNode&&"pre"===a.parentNode.tagName.toLowerCase()&&(n=a.parentNode.getAttribute("data-dependencies")),n=n?n.split(/\s*,\s*/g):[],t(n,function(){l(e,function(){Prism.highlightElement(a)})})},t=function(e,c,a){"string"==typeof e&&(e=[e]);var s=0,n=e.length,r=function(){n>s?l(e[s],function(){s++,r()},function(){a&&a(e[s])}):s===n&&c&&c(e)};r()},l=function(a,s,i){var l=function(){var e=!1;a.indexOf("!")>=0&&(e=!0,a=a.replace("!",""));var t=c[a];if(t||(t=c[a]={}),s&&(t.success_callbacks||(t.success_callbacks=[]),t.success_callbacks.push(s)),i&&(t.error_callbacks||(t.error_callbacks=[]),t.error_callbacks.push(i)),!e&&Prism.languages[a])o(a);else if(!e&&t.error)u(a);else if(e||!t.loading){t.loading=!0;var l=r(a);n(l,function(){t.loading=!1,o(a)},function(){t.loading=!1,t.error=!0,u(a)})}},p=e[a];p&&p.length?t(p,l):l()},o=function(e){c[e]&&c[e].success_callbacks&&c[e].success_callbacks.length&&c[e].success_callbacks.forEach(function(c){c(e)})},u=function(e){c[e]&&c[e].error_callbacks&&c[e].error_callbacks.length&&c[e].error_callbacks.forEach(function(c){c(e)})};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&e.language!==a&&i(e.language,e.element)})}}(); \ No newline at end of file diff --git a/tests/languages/flow/flow-punctuation_feature.test b/tests/languages/flow/flow-punctuation_feature.test new file mode 100644 index 0000000000..ba0c900515 --- /dev/null +++ b/tests/languages/flow/flow-punctuation_feature.test @@ -0,0 +1,12 @@ +{| foo : string |} + +---------------------------------------------------- + +[ + ["flow-punctuation", "{|"], " foo ", ["punctuation", ":"], + ["type", "string"], ["flow-punctuation", "|}"] +] + +---------------------------------------------------- + +Checks for Flow specific punctuation. \ No newline at end of file diff --git a/tests/languages/flow/function-variable_feature.test b/tests/languages/flow/function-variable_feature.test new file mode 100644 index 0000000000..cda25c97bf --- /dev/null +++ b/tests/languages/flow/function-variable_feature.test @@ -0,0 +1,20 @@ +foo = (a: number) : number => {} +bar = () : string => {} + +---------------------------------------------------- + +[ + ["function-variable", "foo"], ["operator", "="], + ["punctuation", "("], "a", ["punctuation", ":"], + ["type", "number"], ["punctuation", ")"], + ["punctuation", ":"], ["type", "number"], + ["operator", "=>"], ["punctuation", "{"], ["punctuation", "}"], + ["function-variable", "bar"], ["operator", "="], + ["punctuation", "("], ["punctuation", ")"], + ["punctuation", ":"], ["type", "string"], + ["operator", "=>"], ["punctuation", "{"], ["punctuation", "}"] +] + +---------------------------------------------------- + +Checks for function variables containing types. \ No newline at end of file diff --git a/tests/languages/flow/keyword_feature.test b/tests/languages/flow/keyword_feature.test new file mode 100644 index 0000000000..fc1ca2accb --- /dev/null +++ b/tests/languages/flow/keyword_feature.test @@ -0,0 +1,39 @@ +type +opaque +declare +Class +$await +$Diff +$Exact +$Keys +$ObjMap +$PropertyType +$Shape +$Record +$Supertype +$Subtype +$Enum + +---------------------------------------------------- + +[ + ["keyword", "type"], + ["keyword", "opaque"], + ["keyword", "declare"], + ["keyword", "Class"], + ["keyword", "$await"], + ["keyword", "$Diff"], + ["keyword", "$Exact"], + ["keyword", "$Keys"], + ["keyword", "$ObjMap"], + ["keyword", "$PropertyType"], + ["keyword", "$Shape"], + ["keyword", "$Record"], + ["keyword", "$Supertype"], + ["keyword", "$Subtype"], + ["keyword", "$Enum"] +] + +---------------------------------------------------- + +Checks for keywords. \ No newline at end of file diff --git a/tests/languages/flow/type_feature.test b/tests/languages/flow/type_feature.test new file mode 100644 index 0000000000..53827c351a --- /dev/null +++ b/tests/languages/flow/type_feature.test @@ -0,0 +1,31 @@ +Number +number +String +string +Boolean +boolean +Function +any +mixed +null +void + +---------------------------------------------------- + +[ + ["type", "Number"], + ["type", "number"], + ["type", "String"], + ["type", "string"], + ["type", "Boolean"], + ["type", "boolean"], + ["type", "Function"], + ["type", "any"], + ["type", "mixed"], + ["type", "null"], + ["type", "void"] +] + +---------------------------------------------------- + +Checks for types. \ No newline at end of file