Skip to content

Instantly share code, notes, and snippets.

@soupi
Last active April 26, 2016 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soupi/eed3243e4f40995442ff to your computer and use it in GitHub Desktop.
Save soupi/eed3243e4f40995442ff to your computer and use it in GitHub Desktop.
demonstration of a simple EDSL to create a slideshow in Elm
import Html
import Html.Attributes as Html
import List
import Signal
import Keyboard
main =
Signal.map (render << .current) (mkSlides slides)
slides =
[ slide "Hello World" <| halign worldList
, slide "Second slide" <| halign <| List.reverse worldList
]
worldList =
[ image "http://deziretours.com/world-tours/images/world-glob.jpg"
, ulist
[ valign
[ text "Hello"
, text "World"
]
]
]
type alias State =
{ back : Slides
, current : Slide
, next : Slides
}
mkSlides slides =
let (s, ss) =
case slides of
s::ss -> (s, ss)
[] -> (empty, [])
in
Signal.foldp
moveSlide
{back = [], current = s, next = ss}
Keyboard.arrows
moveSlide : { x : Int, y : Int } -> State -> State
moveSlide {x} state =
let
updateNext state =
case state.next of
(n::ns) ->
{ back = state.current :: state.back
, current = n
, next = ns
}
[] ->
state
updateBack state =
case state.back of
(b::bs) ->
{ back = bs
, current = b
, next = state.current :: state.next
}
[] ->
state
in
case x of
-1 -> updateBack state
1 -> updateNext state
_ -> state
-----------------
-- Slides EDSL
-----------------
type alias Slides
= List Slide
type Slide
= Slide Element
type Element
= Empty
| Title String
| Text String
| Image String
| VAlign (List Element)
| HAlign (List Element)
| UList (List Element)
empty : Slide
empty = Slide Empty
slide : String -> Element -> Slide
slide ttl el = Slide (valign [title ttl, el])
title : String -> Element
title str = halign [valign [text ""], Title str, valign [text ""]]
text : String -> Element
text = Text
image : String -> Element
image = Image
valign : List Element -> Element
valign = VAlign
halign : List Element -> Element
halign = HAlign
ulist : List Element -> Element
ulist = UList
render : Slide -> Html.Html
render (Slide el) =
Html.div [Html.style ["width" => "100%"]] [renderE el]
renderE : Element -> Html.Html
renderE element =
case element of
Empty ->
Html.div [] []
Title tl ->
span [Html.h2 [Html.style ["text-align" => "center"]] [Html.text tl]]
Text str ->
span [Html.p [Html.style ["margin" => "auto"]] [Html.text str]]
Image url ->
span [Html.img [Html.src url] []]
VAlign els ->
Html.span [Html.style ["width" => "100%", "margin" => "auto"]] (applyRest block <| List.map renderE els)
HAlign els ->
Html.span [flexStyle] (List.map renderE els)
UList els ->
span [Html.ul [] (List.map ((\x -> Html.li [] [x]) << renderE) els)]
(=>) : a -> b -> (a, b)
(=>) x y = (x, y)
marwidStyle =
Html.style
[ "display" => "inline-block"
, "margin" => "auto"
]
flexStyle =
Html.style
[ "display" => "flex"
, "flex-flow" => "row wrap"
]
span x =
Html.span [marwidStyle] x
block x =
Html.span [Html.style ["display" => "block"]] [x]
applyRest f xs =
case xs of
(x::xs) -> x :: List.map f xs
_ -> xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment