1
0
mirror of https://codeberg.org/setop/elm-scripting synced 2025-11-08 21:49:57 +00:00
Files
elm-scripting/README.md
2025-10-15 13:00:58 +02:00

3.2 KiB

A tool to generate HTML code from Elm source in the terminal using QuickJS.

Requirements

  • depends only on elm compiler, quickjs cli and a posix shell
  • do not alter elm compiler
  • do not alter quickjs cli
  • do not patch elm compiler output
  • provide acceptable performances (500ms for a big script)

Design

QuickJS (Qjs) is a JavaScript runtime, similar to V8 or SpiderMonkey, but lighter and faster.

As any runtime, Qjs can interpret JavaScript code, but it is not a web browser. It has no concept of an HTML document.

To bridge this gap, we add a minimal DOM implementation.

Next, we concatenate this with the Elm JavaScript output and an app launcher snippet, then ask Qjs to interpret all of it.

Limitations

  • No event loop
  • Hence, no TEA; no update can be triggered
  • Hence, no Time, no Random, no Http
  • Nodes can only have one parent (this should always be the case)
  • Does not scale well : creating thousands of Nodes consumes a lot of RAM

Usage

  1. Clone this repository and navigate into your local copy
  2. Run elm init.
  3. Create src/Hello.elm with the following content:
module Hello exposing(main)

import Html exposing (text)

main = text "Hello World!"
  1. Run ./elmscript.sh src/Hello.elm

This produces the expected output:

Hello World!

passing input

Input content can be passed to the script via the standard input. The content is then passed to the Elm script as "flags". The script must then use Browser.element and implement init flags function.

Create src/Greet.elm with the following content:

module Greet exposing (main)

import Browser
import Html exposing (text)


main =
  Browser.element
    { init = \f -> (f, Cmd.none)
    , update = \m _ -> (m, Cmd.none)
    , view = \m -> text ("hello " ++ m)
    , subscriptions = always Sub.none
    }

Run ./elmscript.sh src/Greet.elm <<< 'Elm'

This produces the expected output: hello Elm.

I's even more natural when passing file :

  • run elm install elm-explorations/markdown
  • create src/MdRender.elm with the following content:
module MdRender exposing (main)

import Browser
import Html.Attributes exposing (class)
import Markdown

main =
  Browser.element
    { init = \s -> (s, Cmd.none)
    , update = \m c -> (m, Cmd.none)
    , view = \m -> Markdown.toHtml [class "content"] m
    , subscriptions = always Sub.none
    }

  • run ./elmscript.sh src/MdRender.elm < README.md > README.html

Performances

Acceptable for small scripts : 250ms on a modest x86_64 CPU and 64MB RAM for a 500 records into a table ; but is does not scale well as everything is loaded before processing ; no streaming contrary to the usual Unix way.

Generate 500k "li" loop took 17s and 900MB RAM.

Prior Work

There are more complete tools for generating static sites with Elm:

You should probably consider using one of them instead of this one. :)