JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 36
  • Score
    100M100P100Q54866F
  • License MIT

A tiny precompiler that takes an Elm program with embedded HTML and desugars the HTML into elm-html syntax

Package Exports

  • elmx

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (elmx) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

elmx

elmx is to Elm what React's JSX is to Javascript. That is, Elmx is a tiny precompiler that takes an Elm program with embedded HTML and desugars the HTML into elm-html syntax.

Atom integration

apm install language-elmx

If you also have the Elm Atom packages installed you will get additional functionality in your .elmx files:

  • If you have language-elm, you will get auto-complete.
  • If you have linter-elm-make, you will get .elmx to .elm compilation.

See language-elmx for more details.

Emacs integration

Sorry but currently there is no Emacs integration for elmx. You could check the Gulp integration example for an alternative workflow that runs elmx independently of your editor.

On the flip side, if you are an Emacs fan then probably you are a hacker as well and could help with the integration. If you are up for it, check the TextMate grammar file for elmx. Also maybe you can hack (ehm, I mean compose) the existing linter and auto-complete Elm plugins like I did for the language-elm Atom package.

If you want to contribute with this or any other elmx integration let me know in an issue and I'll put the link here.

Gulp integration

This integration uses Gulp to monitor changes in .elmx files and pipes the file contents through the elmx parser to produce .elm files.

See the full integration example in: Gulp integration example

Library installation

npm install --save-dev elmx

Then:

var elmxParser = require('elmx');

var elmSource = elmxParser(elmxSource);

Syntax

In the same spirit of JSX, elmx syntax allows HTML tags embedded in the Elm code and uses { and } to interpolate Elm code into the HTML.

For example:

import Html
import Html.Attributes

main : Html
main = <span>Hello, elmx!</span>

Translates to:

import Html
import Html.Attributes

main : Html
main = Html.span [] [Html.text "Hello, elmx!"]

Note that for elmx to work you need to import both Html and Html.Attributes.

Attributes can be specified with:

showError : Html
showError = <span class="error">Oops!</span>

Or:

showError : String -> Html
showError errorClass = <span class={errorClass}>Oops!</span>

Elm expressions can be interpolated into HTML with:

addBorder : Html -> Html
addBorder s = <div class="border">{s}</div>

Unlike JSX, elmx requires a few extensions to accommodate for Elm's types, namely:

  • {=text}, where text : String (only required for element interpolation)
  • {:list}, where list : [Html]

Elm strings can be interpolated with:

showMessage : String -> Html
showMessage s = <span>{=s}</span>

(note the = in {=s})

Elm lists can be interpolated with:

makeList : [Html] -> Html
makeList lis = <ul>{:lis}</ul>

(note the : in {:lis})

All together:

import Html
import Html.Attributes
import List exposing (map)

main : Html.Html
main =
  let
    title = <h1>Hello</h1>
    name = "Homer"
    lis = map (\s -> <li>{=s}</li>) [ "Bart", "List", "Maggie" ]
  in
    <div class="container">
      {title}
      {=name} is the father or:
      <ul>{:lis}</ul>
    </div>

Considerations, cool stuff, limitations and workarounds

  • No runtime dependencies: elmx just takes Elm code embedded with HTML and produces vanilla elm-html code. This means that, other than suboptimal indentation (see below), once compiled into Elm, your original .elmx should look just like normal Elm code written in pure Elm.

  • Symmetric code generation: a major goal of elmx is to generate the Elm code preserving the line numbers of the original .elmx file. This makes finding and fixing issues in your .elmx very easy since the line numbers reported by the Elm compiler match the line numbers in your .elmx.

  • Non-compliant Elm indentation: because of the symmetric code generation, the Elm code produced does not comply with the Elm syntax guide.

  • Easy to opt-out: since almost every Elm program is a valid elmx program, you can mix-and-match elmx code with traditional elm-html code. Even more, if at any point you decide that you want to stop using elmx, you can always take the generated .elm files, fix the indentation and you are good to go.

  • Non-recursive interpolation: currently Elm code interpolated between { and } is not recursive (i.e. is a regular grammar not a CFG). This means that you cannot include curly brackets inside curly brackets. For example:

    -- BROKEN CODE
    <ul>{:map (\s -> <li>{=s}</li>) items}</ul>

    Note that the interpolated code includes curly brackets and this is not supported. Fortunately this limitation is trivial to overcome with a let binding:

    let
      lis = map (\s -> <li>{=s}</li>) items
    in
      <ul>{:lis}</ul>
  • Required whitespace around <: since elmx tries to parse HTML tags, valid Elm expressions that look like HTML tags will probably confuse the elmx parser. For this reason is best to include some whitespace around your < operators.