Skip to content

Commit

Permalink
Add Elm (elm-lang.org) support (#1174)
Browse files Browse the repository at this point in the history
* Add Elm (elm-lang.org) support

* Simplify patterns and fix a few things inherited from haskell

* Add example and minified file

* Clean up comment pattern, drop redundant groups, tabs for indents
  • Loading branch information
zwilias authored and Golmote committed Jan 16, 2018
1 parent bf9a314 commit d6da70e
Show file tree
Hide file tree
Showing 14 changed files with 373 additions and 0 deletions.
4 changes: 4 additions & 0 deletions components.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ var components = {
"title": "Elixir",
"owner": "Golmote"
},
"elm": {
"title": "Elm",
"owner": "zwilias"
},
"erlang": {
"title": "Erlang",
"owner": "Golmote"
Expand Down
44 changes: 44 additions & 0 deletions components/prism-elm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
Prism.languages.elm = {
comment: /--.*|{-[\s\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\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: /^\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/,
// 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 | 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.
// 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]\w*\.)*[a-z]\w*\b/,
constant: /\b(?:[A-Z]\w*\.)*[A-Z]\w*\b/,
punctuation: /[{}[\]|(),.:]/
};
1 change: 1 addition & 0 deletions components/prism-elm.min.js

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

94 changes: 94 additions & 0 deletions examples/prism-elm.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<h1>Elm</h1>
<p>To user this language, use the class "language-elm".</p>

<h2>Comments</h2>
<pre><code>-- Single line comment
{- Multi-line
comment -}</code></pre>

<h2>Strings and characters</h2>
<pre><code>'a'
'\n'
'\x03'
"foo \" bar"
"""
"multiline strings" are also
supported!
"""</code></pre>

<h2>Full example</h2>
<pre><code>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" ] []
]
</code></pre>
25 changes: 25 additions & 0 deletions tests/languages/elm/builtin_feature.test
Original file line number Diff line number Diff line change
@@ -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.
19 changes: 19 additions & 0 deletions tests/languages/elm/char_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'a'
'\''
'\n'
'\23'
'\xFE'

----------------------------------------------------

[
["char", "'a'"],
["char", "'\\''"],
["char", "'\\n'"],
["char", "'\\23'"],
["char", "'\\xFE'"]
]

----------------------------------------------------

Checks for chars.
14 changes: 14 additions & 0 deletions tests/languages/elm/comment_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- foo
{- foo
bar -}

----------------------------------------------------

[
["comment", "-- foo"],
["comment", "{- foo\r\nbar -}"]
]

----------------------------------------------------

Checks for single-line and multi-line comments.
15 changes: 15 additions & 0 deletions tests/languages/elm/constant_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Foo
Foo.Bar
Baz.Foobar_42

----------------------------------------------------

[
["constant", "Foo"],
["constant", "Foo.Bar"],
["constant", "Baz.Foobar_42"]
]

----------------------------------------------------

Checks for constants.
15 changes: 15 additions & 0 deletions tests/languages/elm/hvariable_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
foo
Foo.bar
Baz.foobar_42

----------------------------------------------------

[
["hvariable", "foo"],
["hvariable", "Foo.bar"],
["hvariable", "Baz.foobar_42"]
]

----------------------------------------------------

Checks for hvariables.
48 changes: 48 additions & 0 deletions tests/languages/elm/import_statement_feature.test
Original file line number Diff line number Diff line change
@@ -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.
19 changes: 19 additions & 0 deletions tests/languages/elm/keyword_feature.test
Original file line number Diff line number Diff line change
@@ -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.
21 changes: 21 additions & 0 deletions tests/languages/elm/number_feature.test
Original file line number Diff line number Diff line change
@@ -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.
33 changes: 33 additions & 0 deletions tests/languages/elm/operator_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
..
reverse . sort
+ - * /
^ ^^ **
&& ||
< <= == /=
>= > |
++ : !!
<- ->
= :: =>
>> >>= >@>
~ ! @

----------------------------------------------------

[
["operator", ".."],
["hvariable", "reverse"], ["operator", " . "], ["hvariable", "sort"],
["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.
21 changes: 21 additions & 0 deletions tests/languages/elm/string_feature.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
""
"regular string"
"fo\"o"
"""foo
bar"""
"""foo -- comment
bar"""

----------------------------------------------------

[
["string", "\"\""],
["string", "\"regular string\""],
["string", "\"fo\\\"o\""],
["string", "\"\"\"foo\r\n bar\"\"\""],
["string", "\"\"\"foo -- comment\r\n bar\"\"\""]
]

----------------------------------------------------

Checks for strings.

0 comments on commit d6da70e

Please sign in to comment.