From 1bedcff167774a21dfcdb6252bb9a78d529bc399 Mon Sep 17 00:00:00 2001 From: ilias Date: Thu, 17 Aug 2017 12:44:58 +0200 Subject: [PATCH 1/4] Add Elm (elm-lang.org) support --- components.js | 4 ++ components/prism-elm.js | 35 ++++++++++++++ components/prism-elm.min.js | 1 + tests/languages/elm/builtin_feature.test | 25 ++++++++++ tests/languages/elm/char_feature.test | 17 +++++++ tests/languages/elm/comment_feature.test | 14 ++++++ tests/languages/elm/constant_feature.test | 15 ++++++ tests/languages/elm/hvariable_feature.test | 15 ++++++ .../elm/import_statement_feature.test | 48 +++++++++++++++++++ tests/languages/elm/keyword_feature.test | 19 ++++++++ tests/languages/elm/number_feature.test | 21 ++++++++ tests/languages/elm/operator_feature.test | 37 ++++++++++++++ tests/languages/elm/string_feature.test | 19 ++++++++ 13 files changed, 270 insertions(+) create mode 100644 components/prism-elm.js create mode 100644 components/prism-elm.min.js create mode 100644 tests/languages/elm/builtin_feature.test create mode 100644 tests/languages/elm/char_feature.test create mode 100644 tests/languages/elm/comment_feature.test create mode 100644 tests/languages/elm/constant_feature.test create mode 100644 tests/languages/elm/hvariable_feature.test create mode 100644 tests/languages/elm/import_statement_feature.test create mode 100644 tests/languages/elm/keyword_feature.test create mode 100644 tests/languages/elm/number_feature.test create mode 100644 tests/languages/elm/operator_feature.test create mode 100644 tests/languages/elm/string_feature.test diff --git a/components.js b/components.js index c66247dd95..1b0b710d4f 100644 --- a/components.js +++ b/components.js @@ -188,6 +188,10 @@ var components = { "title": "Elixir", "owner": "Golmote" }, + "elm": { + "title": "Elm", + "owner": "zwilias" + }, "erlang": { "title": "Erlang", "owner": "Golmote" diff --git a/components/prism-elm.js b/components/prism-elm.js new file mode 100644 index 0000000000..1550bf591e --- /dev/null +++ b/components/prism-elm.js @@ -0,0 +1,35 @@ +Prism.languages.elm = { + comment: { + pattern: /(^|[^-!#$%*+=?&@|~.:<>^\\\/])(--[^-!#$%*+=?&@|~.:<>^\\\/].*|{-[\s\S]*?-})/m, + lookbehind: true + }, + char: /'([^\\']|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+))'/, + string: { + pattern: /"([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+)|\\\s+\\)*"/, + greedy: true + }, + import_statement: { + // The imported or hidden names are not included in this import + // statement. This is because we want to highlight those exactly like + // we do for the names in the program. + pattern: /(\r?\n|\r|^)\s*import\s+([A-Z][_a-zA-Z0-9]*)(\.[A-Z][_a-zA-Z0-9]*)*(\s+as\s+([A-Z][_a-zA-Z0-9]*)(\.[A-Z][_a-zA-Z0-9]*)*)?(\s+exposing\s+)?/m, + inside: { + keyword: /\b(import|as|exposing)\b/ + } + }, + keyword: /\b(alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/, + // These are builtin variables only. Constructors are highlighted later as a constant. + builtin: /\b(abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/, + // decimal integers and floating point numbers | octal integers | hexadecimal integers + number: /\b(\d+(\.\d+)?(e[+-]?\d+)?|0x[0-9a-f]+)\b/i, + // Most of this is needed because of the meaning of a single '.'. + // If it stands alone freely, it is the function composition. + // It may also be a separator between a module name and an identifier => no + // operator. If it comes together with other special characters it is an + // operator too. + operator: /\s\.\s|[-!#$%*+=?&@|~.:<>^\\\/]*\.[-!#$%*+=?&@|~.:<>^\\\/]+|[-!#$%*+=?&@|~.:<>^\\\/]+\.[-!#$%*+=?&@|~.:<>^\\\/]*|[-!#$%*+=?&@|~:<>^\\\/]+|`([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*`/, + // In Elm, nearly everything is a variable, do not highlight these. + hvariable: /\b([A-Z][_a-zA-Z0-9]*\.)*[_a-z][_a-zA-Z0-9]*\b/, + constant: /\b([A-Z][_a-zA-Z0-9]*\.)*[A-Z][_a-zA-Z0-9]*\b/, + punctuation: /[{}[\];(),.:]/ +}; diff --git a/components/prism-elm.min.js b/components/prism-elm.min.js new file mode 100644 index 0000000000..c9355830bf --- /dev/null +++ b/components/prism-elm.min.js @@ -0,0 +1 @@ +Prism.languages.elm={comment:{pattern:/(^|[^-!#$%*+=?&@|~.:<>^\\\/])(--[^-!#$%*+=?&@|~.:<>^\\\/].*|{-[\s\S]*?-})/m,lookbehind:!0},"char":/'([^\\']|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,string:{pattern:/"([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+)|\\\s+\\)*"/,greedy:!0},import_statement:{pattern:/(\r?\n|\r|^)\s*import\s+([A-Z][_a-zA-Z0-9]*)(\.[A-Z][_a-zA-Z0-9]*)*(\s+as\s+([A-Z][_a-zA-Z0-9]*)(\.[A-Z][_a-zA-Z0-9]*)*)?(\s+exposing\s+)?/m,inside:{keyword:/\b(import|as|exposing)\b/}},keyword:/\b(alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/,builtin:/\b(abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/,number:/\b(\d+(\.\d+)?(e[+-]?\d+)?|0x[0-9a-f]+)\b/i,operator:/\s\.\s|[-!#$%*+=?&@|~.:<>^\\\/]*\.[-!#$%*+=?&@|~.:<>^\\\/]+|[-!#$%*+=?&@|~.:<>^\\\/]+\.[-!#$%*+=?&@|~.:<>^\\\/]*|[-!#$%*+=?&@|~:<>^\\\/]+|`([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*`/,hvariable:/\b([A-Z][_a-zA-Z0-9]*\.)*[_a-z][_a-zA-Z0-9]*\b/,constant:/\b([A-Z][_a-zA-Z0-9]*\.)*[A-Z][_a-zA-Z0-9]*\b/,punctuation:/[{}[\];(),.:]/}; \ No newline at end of file diff --git a/tests/languages/elm/builtin_feature.test b/tests/languages/elm/builtin_feature.test new file mode 100644 index 0000000000..da96c1dd6c --- /dev/null +++ b/tests/languages/elm/builtin_feature.test @@ -0,0 +1,25 @@ +abs acos always asin atan atan2 +ceiling clamp compare cos curry +degrees e flip floor fromPolar +identity isInfinite isNaN +logBase max min negate never +not pi radians rem round sin +sqrt tan toFloat toPolar toString +truncate turns uncurry xor + +---------------------------------------------------- + +[ + ["builtin", "abs"], ["builtin", "acos"], ["builtin", "always"], ["builtin", "asin"], ["builtin", "atan"], ["builtin", "atan2"], + ["builtin", "ceiling"], ["builtin", "clamp"], ["builtin", "compare"], ["builtin", "cos"], ["builtin", "curry"], + ["builtin", "degrees"], ["builtin", "e"], ["builtin", "flip"], ["builtin", "floor"], ["builtin", "fromPolar"], + ["builtin", "identity"], ["builtin", "isInfinite"], ["builtin", "isNaN"], + ["builtin", "logBase"], ["builtin", "max"], ["builtin", "min"], ["builtin", "negate"], ["builtin", "never"], + ["builtin", "not"], ["builtin", "pi"], ["builtin", "radians"], ["builtin", "rem"], ["builtin", "round"], ["builtin", "sin"], + ["builtin", "sqrt"], ["builtin", "tan"], ["builtin", "toFloat"], ["builtin", "toPolar"], ["builtin", "toString"], + ["builtin", "truncate"], ["builtin", "turns"], ["builtin", "uncurry"], ["builtin", "xor"] +] + +---------------------------------------------------- + +Checks for all builtin. diff --git a/tests/languages/elm/char_feature.test b/tests/languages/elm/char_feature.test new file mode 100644 index 0000000000..e4dedc444a --- /dev/null +++ b/tests/languages/elm/char_feature.test @@ -0,0 +1,17 @@ +'a' +'\n' +'\23' +'\xFE' + +---------------------------------------------------- + +[ + ["char", "'a'"], + ["char", "'\\n'"], + ["char", "'\\23'"], + ["char", "'\\xFE'"] +] + +---------------------------------------------------- + +Checks for chars. \ No newline at end of file diff --git a/tests/languages/elm/comment_feature.test b/tests/languages/elm/comment_feature.test new file mode 100644 index 0000000000..d8c8cdda20 --- /dev/null +++ b/tests/languages/elm/comment_feature.test @@ -0,0 +1,14 @@ +-- foo +{- foo +bar -} + +---------------------------------------------------- + +[ + ["comment", "-- foo"], + ["comment", "{- foo\r\nbar -}"] +] + +---------------------------------------------------- + +Checks for single-line and multi-line comments. \ No newline at end of file diff --git a/tests/languages/elm/constant_feature.test b/tests/languages/elm/constant_feature.test new file mode 100644 index 0000000000..06f25f10e5 --- /dev/null +++ b/tests/languages/elm/constant_feature.test @@ -0,0 +1,15 @@ +Foo +Foo.Bar +Baz.Foobar_42 + +---------------------------------------------------- + +[ + ["constant", "Foo"], + ["constant", "Foo.Bar"], + ["constant", "Baz.Foobar_42"] +] + +---------------------------------------------------- + +Checks for constants. \ No newline at end of file diff --git a/tests/languages/elm/hvariable_feature.test b/tests/languages/elm/hvariable_feature.test new file mode 100644 index 0000000000..defa3ba74d --- /dev/null +++ b/tests/languages/elm/hvariable_feature.test @@ -0,0 +1,15 @@ +foo +Foo.bar +Baz.foobar_42 + +---------------------------------------------------- + +[ + ["hvariable", "foo"], + ["hvariable", "Foo.bar"], + ["hvariable", "Baz.foobar_42"] +] + +---------------------------------------------------- + +Checks for hvariables. \ No newline at end of file diff --git a/tests/languages/elm/import_statement_feature.test b/tests/languages/elm/import_statement_feature.test new file mode 100644 index 0000000000..c2940362dc --- /dev/null +++ b/tests/languages/elm/import_statement_feature.test @@ -0,0 +1,48 @@ +import Foo +import Foo_42.Bar as Foobar +import Foo.Bar as Foo.Baz +import List exposing (map) +import Json.Decode as Json exposing (Decoder) + +---------------------------------------------------- + +[ + ["import_statement", [ + ["keyword", "import"], + " Foo" + ]], + ["import_statement", [ + ["keyword", "import"], + " Foo_42.Bar ", + ["keyword", "as"], + " Foobar" + ]], + ["import_statement", [ + ["keyword", "import"], + " Foo.Bar ", + ["keyword", "as"], + " Foo.Baz" + ]], + ["import_statement", [ + ["keyword", "import"], + " List ", + ["keyword", "exposing"] + ]], + ["punctuation", "("], + ["hvariable", "map"], + ["punctuation", ")"], + ["import_statement", [ + ["keyword", "import"], + " Json.Decode ", + ["keyword", "as"], + " Json ", + ["keyword", "exposing"] + ]], + ["punctuation", "("], + ["constant", "Decoder"], + ["punctuation", ")"] +] + +---------------------------------------------------- + +Checks for import statement. diff --git a/tests/languages/elm/keyword_feature.test b/tests/languages/elm/keyword_feature.test new file mode 100644 index 0000000000..6f1132a4ec --- /dev/null +++ b/tests/languages/elm/keyword_feature.test @@ -0,0 +1,19 @@ +alias as case else +exposing if in +infixl infixr let +module of then +type + +---------------------------------------------------- + +[ + ["keyword", "alias"], ["keyword", "as"], ["keyword", "case"], ["keyword", "else"], + ["keyword", "exposing"], ["keyword", "if"], ["keyword", "in"], + ["keyword", "infixl"], ["keyword", "infixr"], ["keyword", "let"], + ["keyword", "module"], ["keyword", "of"], ["keyword", "then"], + ["keyword", "type"] +] + +---------------------------------------------------- + +Checks for all keywords. diff --git a/tests/languages/elm/number_feature.test b/tests/languages/elm/number_feature.test new file mode 100644 index 0000000000..c27dae9a62 --- /dev/null +++ b/tests/languages/elm/number_feature.test @@ -0,0 +1,21 @@ +42 +3.14159 +2E3 +1.2e-4 +0.9e+1 +0xBadFace + +---------------------------------------------------- + +[ + ["number", "42"], + ["number", "3.14159"], + ["number", "2E3"], + ["number", "1.2e-4"], + ["number", "0.9e+1"], + ["number", "0xBadFace"] +] + +---------------------------------------------------- + +Checks for decimal and hexadecimal numbers. diff --git a/tests/languages/elm/operator_feature.test b/tests/languages/elm/operator_feature.test new file mode 100644 index 0000000000..43a86e59f8 --- /dev/null +++ b/tests/languages/elm/operator_feature.test @@ -0,0 +1,37 @@ +.. +reverse . sort +`foo` +`Foo.bar` ++ - * / +^ ^^ ** +&& || +< <= == /= +>= > \ | +++ : !! +\\ <- -> += :: => +>> >>= >@> +~ ! @ + +---------------------------------------------------- + +[ + ["operator", ".."], + ["hvariable", "reverse"], ["operator", " . "], ["hvariable", "sort"], + ["operator", "`foo`"], + ["operator", "`Foo.bar`"], + ["operator", "+"], ["operator", "-"], ["operator", "*"], ["operator", "/"], + ["operator", "^"], ["operator", "^^"], ["operator", "**"], + ["operator", "&&"], ["operator", "||"], + ["operator", "<"], ["operator", "<="], ["operator", "=="], ["operator", "/="], + ["operator", ">="], ["operator", ">"], ["operator", "\\"], ["operator", "|"], + ["operator", "++"], ["operator", ":"], ["operator", "!!"], + ["operator", "\\\\"], ["operator", "<-"], ["operator", "->"], + ["operator", "="], ["operator", "::"], ["operator", "=>"], + ["operator", ">>"], ["operator", ">>="], ["operator", ">@>"], + ["operator", "~"], ["operator", "!"], ["operator", "@"] +] + +---------------------------------------------------- + +Checks for operators. diff --git a/tests/languages/elm/string_feature.test b/tests/languages/elm/string_feature.test new file mode 100644 index 0000000000..49c2cfbf23 --- /dev/null +++ b/tests/languages/elm/string_feature.test @@ -0,0 +1,19 @@ +"" +"fo\"o" +"foo \ + \ bar" +"foo -- comment \ + \ bar" + +---------------------------------------------------- + +[ + ["string", "\"\""], + ["string", "\"fo\\\"o\""], + ["string", "\"foo \\\r\n \\ bar\""], + ["string", "\"foo -- comment \\\r\n \\ bar\""] +] + +---------------------------------------------------- + +Checks for strings. \ No newline at end of file From 17904473f88ac0f4e50bf05b7f4493a594749513 Mon Sep 17 00:00:00 2001 From: ilias Date: Mon, 25 Dec 2017 00:11:14 +0100 Subject: [PATCH 2/4] Simplify patterns and fix a few things inherited from haskell --- components/prism-elm.js | 30 ++++++++++++++++------- tests/languages/elm/char_feature.test | 2 ++ tests/languages/elm/operator_feature.test | 12 +++------ tests/languages/elm/string_feature.test | 14 ++++++----- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/components/prism-elm.js b/components/prism-elm.js index 1550bf591e..d6f4eac5c8 100644 --- a/components/prism-elm.js +++ b/components/prism-elm.js @@ -3,16 +3,26 @@ Prism.languages.elm = { pattern: /(^|[^-!#$%*+=?&@|~.:<>^\\\/])(--[^-!#$%*+=?&@|~.:<>^\\\/].*|{-[\s\S]*?-})/m, lookbehind: true }, - char: /'([^\\']|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+))'/, - string: { - pattern: /"([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+)|\\\s+\\)*"/, + char: { + pattern: /'([^\\'\r\n]|\\([abfnrtv\\']|\d+|x[0-9a-fA-F]+))'/, greedy: true }, + string: [ + { + // Multiline strings are wrapped in triple ". Quotes may appear unescaped. + pattern: /"""((.|\s)*?(?="""))"""/, + greedy: true + }, + { + pattern: /"([^\\"\r\n]|\\([abfnrtv\\"]|\d+|x[0-9a-fA-F]+))*"/, + greedy: true + } + ], import_statement: { // The imported or hidden names are not included in this import // statement. This is because we want to highlight those exactly like // we do for the names in the program. - pattern: /(\r?\n|\r|^)\s*import\s+([A-Z][_a-zA-Z0-9]*)(\.[A-Z][_a-zA-Z0-9]*)*(\s+as\s+([A-Z][_a-zA-Z0-9]*)(\.[A-Z][_a-zA-Z0-9]*)*)?(\s+exposing\s+)?/m, + pattern: /^\s*import\s+[A-Z]\w*(\.[A-Z]\w*)*(\s+as\s+([A-Z]\w*)(\.[A-Z]\w*)*)?(\s+exposing\s+)?/m, inside: { keyword: /\b(import|as|exposing)\b/ } @@ -20,16 +30,18 @@ Prism.languages.elm = { keyword: /\b(alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/, // These are builtin variables only. Constructors are highlighted later as a constant. builtin: /\b(abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/, - // decimal integers and floating point numbers | octal integers | hexadecimal integers + // decimal integers and floating point numbers | hexadecimal integers number: /\b(\d+(\.\d+)?(e[+-]?\d+)?|0x[0-9a-f]+)\b/i, // Most of this is needed because of the meaning of a single '.'. // If it stands alone freely, it is the function composition. // It may also be a separator between a module name and an identifier => no // operator. If it comes together with other special characters it is an // operator too. - operator: /\s\.\s|[-!#$%*+=?&@|~.:<>^\\\/]*\.[-!#$%*+=?&@|~.:<>^\\\/]+|[-!#$%*+=?&@|~.:<>^\\\/]+\.[-!#$%*+=?&@|~.:<>^\\\/]*|[-!#$%*+=?&@|~:<>^\\\/]+|`([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*`/, + // Valid operator characters in 0.18: +-/*=.$<>:&|^?%#@~! + // Ref: https://groups.google.com/forum/#!msg/elm-dev/0AHSnDdkSkQ/E0SVU70JEQAJ + operator: /\s\.\s|[+\-/*=.$<>:&|^?%#@~!]{2,}|[+\-/*=$<>:&|^?%#@~!]/, // In Elm, nearly everything is a variable, do not highlight these. - hvariable: /\b([A-Z][_a-zA-Z0-9]*\.)*[_a-z][_a-zA-Z0-9]*\b/, - constant: /\b([A-Z][_a-zA-Z0-9]*\.)*[A-Z][_a-zA-Z0-9]*\b/, - punctuation: /[{}[\];(),.:]/ + hvariable: /\b([A-Z]\w*\.)*[a-z]\w*\b/, + constant: /\b([A-Z]\w*\.)*[A-Z]\w*\b/, + punctuation: /[{}[\]|(),.:]/ }; diff --git a/tests/languages/elm/char_feature.test b/tests/languages/elm/char_feature.test index e4dedc444a..c6d2bcbb84 100644 --- a/tests/languages/elm/char_feature.test +++ b/tests/languages/elm/char_feature.test @@ -1,4 +1,5 @@ 'a' +'\'' '\n' '\23' '\xFE' @@ -7,6 +8,7 @@ [ ["char", "'a'"], + ["char", "'\\''"], ["char", "'\\n'"], ["char", "'\\23'"], ["char", "'\\xFE'"] diff --git a/tests/languages/elm/operator_feature.test b/tests/languages/elm/operator_feature.test index 43a86e59f8..ce120ec62a 100644 --- a/tests/languages/elm/operator_feature.test +++ b/tests/languages/elm/operator_feature.test @@ -1,14 +1,12 @@ .. reverse . sort -`foo` -`Foo.bar` + - * / ^ ^^ ** && || < <= == /= ->= > \ | +>= > | ++ : !! -\\ <- -> +<- -> = :: => >> >>= >@> ~ ! @ @@ -18,15 +16,13 @@ reverse . sort [ ["operator", ".."], ["hvariable", "reverse"], ["operator", " . "], ["hvariable", "sort"], - ["operator", "`foo`"], - ["operator", "`Foo.bar`"], ["operator", "+"], ["operator", "-"], ["operator", "*"], ["operator", "/"], ["operator", "^"], ["operator", "^^"], ["operator", "**"], ["operator", "&&"], ["operator", "||"], ["operator", "<"], ["operator", "<="], ["operator", "=="], ["operator", "/="], - ["operator", ">="], ["operator", ">"], ["operator", "\\"], ["operator", "|"], + ["operator", ">="], ["operator", ">"], ["operator", "|"], ["operator", "++"], ["operator", ":"], ["operator", "!!"], - ["operator", "\\\\"], ["operator", "<-"], ["operator", "->"], + ["operator", "<-"], ["operator", "->"], ["operator", "="], ["operator", "::"], ["operator", "=>"], ["operator", ">>"], ["operator", ">>="], ["operator", ">@>"], ["operator", "~"], ["operator", "!"], ["operator", "@"] diff --git a/tests/languages/elm/string_feature.test b/tests/languages/elm/string_feature.test index 49c2cfbf23..365c8c764c 100644 --- a/tests/languages/elm/string_feature.test +++ b/tests/languages/elm/string_feature.test @@ -1,17 +1,19 @@ "" +"regular string" "fo\"o" -"foo \ - \ bar" -"foo -- comment \ - \ bar" +"""foo + bar""" +"""foo -- comment + bar""" ---------------------------------------------------- [ ["string", "\"\""], + ["string", "\"regular string\""], ["string", "\"fo\\\"o\""], - ["string", "\"foo \\\r\n \\ bar\""], - ["string", "\"foo -- comment \\\r\n \\ bar\""] + ["string", "\"\"\"foo\r\n bar\"\"\""], + ["string", "\"\"\"foo -- comment\r\n bar\"\"\""] ] ---------------------------------------------------- From 4aa8fedb97a01af4763824f59c11e2bcd6ef5ca3 Mon Sep 17 00:00:00 2001 From: ilias Date: Mon, 25 Dec 2017 00:40:00 +0100 Subject: [PATCH 3/4] Add example and minified file --- components/prism-elm.min.js | 2 +- examples/prism-elm.html | 94 +++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 examples/prism-elm.html diff --git a/components/prism-elm.min.js b/components/prism-elm.min.js index c9355830bf..891e28737f 100644 --- a/components/prism-elm.min.js +++ b/components/prism-elm.min.js @@ -1 +1 @@ -Prism.languages.elm={comment:{pattern:/(^|[^-!#$%*+=?&@|~.:<>^\\\/])(--[^-!#$%*+=?&@|~.:<>^\\\/].*|{-[\s\S]*?-})/m,lookbehind:!0},"char":/'([^\\']|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,string:{pattern:/"([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+)|\\\s+\\)*"/,greedy:!0},import_statement:{pattern:/(\r?\n|\r|^)\s*import\s+([A-Z][_a-zA-Z0-9]*)(\.[A-Z][_a-zA-Z0-9]*)*(\s+as\s+([A-Z][_a-zA-Z0-9]*)(\.[A-Z][_a-zA-Z0-9]*)*)?(\s+exposing\s+)?/m,inside:{keyword:/\b(import|as|exposing)\b/}},keyword:/\b(alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/,builtin:/\b(abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/,number:/\b(\d+(\.\d+)?(e[+-]?\d+)?|0x[0-9a-f]+)\b/i,operator:/\s\.\s|[-!#$%*+=?&@|~.:<>^\\\/]*\.[-!#$%*+=?&@|~.:<>^\\\/]+|[-!#$%*+=?&@|~.:<>^\\\/]+\.[-!#$%*+=?&@|~.:<>^\\\/]*|[-!#$%*+=?&@|~:<>^\\\/]+|`([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*`/,hvariable:/\b([A-Z][_a-zA-Z0-9]*\.)*[_a-z][_a-zA-Z0-9]*\b/,constant:/\b([A-Z][_a-zA-Z0-9]*\.)*[A-Z][_a-zA-Z0-9]*\b/,punctuation:/[{}[\];(),.:]/}; \ No newline at end of file +Prism.languages.elm={comment:{pattern:/(^|[^-!#$%*+=?&@|~.:<>^\\\/])(--[^-!#$%*+=?&@|~.:<>^\\\/].*|{-[\s\S]*?-})/m,lookbehind:!0},"char":{pattern:/'([^\\'\r\n]|\\([abfnrtv\\']|\d+|x[0-9a-fA-F]+))'/,greedy:!0},string:[{pattern:/"""((.|\s)*?(?="""))"""/,greedy:!0},{pattern:/"([^\\"\r\n]|\\([abfnrtv\\"]|\d+|x[0-9a-fA-F]+))*"/,greedy:!0}],import_statement:{pattern:/^\s*import\s+[A-Z]\w*(\.[A-Z]\w*)*(\s+as\s+([A-Z]\w*)(\.[A-Z]\w*)*)?(\s+exposing\s+)?/m,inside:{keyword:/\b(import|as|exposing)\b/}},keyword:/\b(alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/,builtin:/\b(abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/,number:/\b(\d+(\.\d+)?(e[+-]?\d+)?|0x[0-9a-f]+)\b/i,operator:/\s\.\s|[+\-\/*=.$<>:&|^?%#@~!]{2,}|[+\-\/*=$<>:&|^?%#@~!]/,hvariable:/\b([A-Z]\w*\.)*[a-z]\w*\b/,constant:/\b([A-Z]\w*\.)*[A-Z]\w*\b/,punctuation:/[{}[\]|(),.:]/}; \ No newline at end of file diff --git a/examples/prism-elm.html b/examples/prism-elm.html new file mode 100644 index 0000000000..d5f14f0270 --- /dev/null +++ b/examples/prism-elm.html @@ -0,0 +1,94 @@ +

Elm

+

To user this language, use the class "language-elm".

+ +

Comments

+
-- Single line comment
+{- Multi-line
+comment -}
+ +

Strings and characters

+
'a'
+'\n'
+'\x03'
+"foo \" bar"
+"""
+"multiline strings" are also
+supported!
+"""
+ +

Full example

+
module Main exposing (..)
+
+import Html exposing (Html)
+import Svg exposing (..)
+import Svg.Attributes exposing (..)
+import Time exposing (Time, second)
+
+
+main =
+    Html.program
+        { init = init
+        , view = view
+        , update = update
+        , subscriptions = subscriptions
+        }
+
+
+
+-- MODEL
+
+
+type alias Model =
+    Time
+
+
+init : ( Model, Cmd Msg )
+init =
+    ( 0, Cmd.none )
+
+
+
+-- UPDATE
+
+
+type Msg
+    = Tick Time
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case msg of
+        Tick newTime ->
+            ( newTime, Cmd.none )
+
+
+
+-- SUBSCRIPTIONS
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+    Time.every second (\time -> Tick time)
+
+
+
+-- VIEW
+
+
+view : Model -> Html Msg
+view model =
+    let
+        angle =
+            turns (Time.inMinutes model)
+
+        handX =
+            toString (50 + 40 * cos angle)
+
+        handY =
+            toString (50 + 40 * sin angle)
+    in
+    svg [ viewBox "0 0 100 100", width "300px" ]
+        [ circle [ cx "50", cy "50", r "45", fill "#0B79CE" ] []
+        , line [ x1 "50", y1 "50", x2 handX, y2 handY, stroke "#023963" ] []
+        ]
+
From b3e3b6b961b843485a6858912e673cbdd7d5695c Mon Sep 17 00:00:00 2001 From: ilias Date: Sat, 13 Jan 2018 15:54:34 +0100 Subject: [PATCH 4/4] Clean up comment pattern, drop redundant groups, tabs for indents --- components/prism-elm.js | 25 +++++++++++-------------- components/prism-elm.min.js | 2 +- tests/languages/elm/char_feature.test | 2 +- tests/languages/elm/string_feature.test | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/components/prism-elm.js b/components/prism-elm.js index d6f4eac5c8..3a0d6a9b34 100644 --- a/components/prism-elm.js +++ b/components/prism-elm.js @@ -1,20 +1,17 @@ Prism.languages.elm = { - comment: { - pattern: /(^|[^-!#$%*+=?&@|~.:<>^\\\/])(--[^-!#$%*+=?&@|~.:<>^\\\/].*|{-[\s\S]*?-})/m, - lookbehind: true - }, + comment: /--.*|{-[\s\S]*?-}/, char: { - pattern: /'([^\\'\r\n]|\\([abfnrtv\\']|\d+|x[0-9a-fA-F]+))'/, + pattern: /'(?:[^\\'\r\n]|\\(?:[abfnrtv\\']|\d+|x[0-9a-fA-F]+))'/, greedy: true }, string: [ { // Multiline strings are wrapped in triple ". Quotes may appear unescaped. - pattern: /"""((.|\s)*?(?="""))"""/, + pattern: /"""[\s\S]*?"""/, greedy: true }, { - pattern: /"([^\\"\r\n]|\\([abfnrtv\\"]|\d+|x[0-9a-fA-F]+))*"/, + pattern: /"(?:[^\\"\r\n]|\\(?:[abfnrtv\\"]|\d+|x[0-9a-fA-F]+))*"/, greedy: true } ], @@ -22,16 +19,16 @@ Prism.languages.elm = { // The imported or hidden names are not included in this import // statement. This is because we want to highlight those exactly like // we do for the names in the program. - pattern: /^\s*import\s+[A-Z]\w*(\.[A-Z]\w*)*(\s+as\s+([A-Z]\w*)(\.[A-Z]\w*)*)?(\s+exposing\s+)?/m, + pattern: /^\s*import\s+[A-Z]\w*(?:\.[A-Z]\w*)*(?:\s+as\s+([A-Z]\w*)(?:\.[A-Z]\w*)*)?(?:\s+exposing\s+)?/m, inside: { - keyword: /\b(import|as|exposing)\b/ + keyword: /\b(?:import|as|exposing)\b/ } }, - keyword: /\b(alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/, + keyword: /\b(?:alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/, // These are builtin variables only. Constructors are highlighted later as a constant. - builtin: /\b(abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/, + builtin: /\b(?:abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/, // decimal integers and floating point numbers | hexadecimal integers - number: /\b(\d+(\.\d+)?(e[+-]?\d+)?|0x[0-9a-f]+)\b/i, + number: /\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0x[0-9a-f]+)\b/i, // Most of this is needed because of the meaning of a single '.'. // If it stands alone freely, it is the function composition. // It may also be a separator between a module name and an identifier => no @@ -41,7 +38,7 @@ Prism.languages.elm = { // Ref: https://groups.google.com/forum/#!msg/elm-dev/0AHSnDdkSkQ/E0SVU70JEQAJ operator: /\s\.\s|[+\-/*=.$<>:&|^?%#@~!]{2,}|[+\-/*=$<>:&|^?%#@~!]/, // In Elm, nearly everything is a variable, do not highlight these. - hvariable: /\b([A-Z]\w*\.)*[a-z]\w*\b/, - constant: /\b([A-Z]\w*\.)*[A-Z]\w*\b/, + hvariable: /\b(?:[A-Z]\w*\.)*[a-z]\w*\b/, + constant: /\b(?:[A-Z]\w*\.)*[A-Z]\w*\b/, punctuation: /[{}[\]|(),.:]/ }; diff --git a/components/prism-elm.min.js b/components/prism-elm.min.js index 891e28737f..e8544da640 100644 --- a/components/prism-elm.min.js +++ b/components/prism-elm.min.js @@ -1 +1 @@ -Prism.languages.elm={comment:{pattern:/(^|[^-!#$%*+=?&@|~.:<>^\\\/])(--[^-!#$%*+=?&@|~.:<>^\\\/].*|{-[\s\S]*?-})/m,lookbehind:!0},"char":{pattern:/'([^\\'\r\n]|\\([abfnrtv\\']|\d+|x[0-9a-fA-F]+))'/,greedy:!0},string:[{pattern:/"""((.|\s)*?(?="""))"""/,greedy:!0},{pattern:/"([^\\"\r\n]|\\([abfnrtv\\"]|\d+|x[0-9a-fA-F]+))*"/,greedy:!0}],import_statement:{pattern:/^\s*import\s+[A-Z]\w*(\.[A-Z]\w*)*(\s+as\s+([A-Z]\w*)(\.[A-Z]\w*)*)?(\s+exposing\s+)?/m,inside:{keyword:/\b(import|as|exposing)\b/}},keyword:/\b(alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/,builtin:/\b(abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/,number:/\b(\d+(\.\d+)?(e[+-]?\d+)?|0x[0-9a-f]+)\b/i,operator:/\s\.\s|[+\-\/*=.$<>:&|^?%#@~!]{2,}|[+\-\/*=$<>:&|^?%#@~!]/,hvariable:/\b([A-Z]\w*\.)*[a-z]\w*\b/,constant:/\b([A-Z]\w*\.)*[A-Z]\w*\b/,punctuation:/[{}[\]|(),.:]/}; \ No newline at end of file +Prism.languages.elm={comment:/--.*|{-[\s\S]*?-}/,"char":{pattern:/'(?:[^\\'\r\n]|\\(?:[abfnrtv\\']|\d+|x[0-9a-fA-F]+))'/,greedy:!0},string:[{pattern:/"""[\s\S]*?"""/,greedy:!0},{pattern:/"(?:[^\\"\r\n]|\\(?:[abfnrtv\\"]|\d+|x[0-9a-fA-F]+))*"/,greedy:!0}],import_statement:{pattern:/^\s*import\s+[A-Z]\w*(?:\.[A-Z]\w*)*(?:\s+as\s+([A-Z]\w*)(?:\.[A-Z]\w*)*)?(?:\s+exposing\s+)?/m,inside:{keyword:/\b(?:import|as|exposing)\b/}},keyword:/\b(?:alias|as|case|else|exposing|if|in|infixl|infixr|let|module|of|then|type)\b/,builtin:/\b(?:abs|acos|always|asin|atan|atan2|ceiling|clamp|compare|cos|curry|degrees|e|flip|floor|fromPolar|identity|isInfinite|isNaN|logBase|max|min|negate|never|not|pi|radians|rem|round|sin|sqrt|tan|toFloat|toPolar|toString|truncate|turns|uncurry|xor)\b/,number:/\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0x[0-9a-f]+)\b/i,operator:/\s\.\s|[+\-\/*=.$<>:&|^?%#@~!]{2,}|[+\-\/*=$<>:&|^?%#@~!]/,hvariable:/\b(?:[A-Z]\w*\.)*[a-z]\w*\b/,constant:/\b(?:[A-Z]\w*\.)*[A-Z]\w*\b/,punctuation:/[{}[\]|(),.:]/}; \ No newline at end of file diff --git a/tests/languages/elm/char_feature.test b/tests/languages/elm/char_feature.test index c6d2bcbb84..c4d33fcd2a 100644 --- a/tests/languages/elm/char_feature.test +++ b/tests/languages/elm/char_feature.test @@ -8,7 +8,7 @@ [ ["char", "'a'"], - ["char", "'\\''"], + ["char", "'\\''"], ["char", "'\\n'"], ["char", "'\\23'"], ["char", "'\\xFE'"] diff --git a/tests/languages/elm/string_feature.test b/tests/languages/elm/string_feature.test index 365c8c764c..6b5ea8ddd9 100644 --- a/tests/languages/elm/string_feature.test +++ b/tests/languages/elm/string_feature.test @@ -10,7 +10,7 @@ [ ["string", "\"\""], - ["string", "\"regular string\""], + ["string", "\"regular string\""], ["string", "\"fo\\\"o\""], ["string", "\"\"\"foo\r\n bar\"\"\""], ["string", "\"\"\"foo -- comment\r\n bar\"\"\""]