Commits: 4
Gitignore .swp files
index 9114974..0c19f1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
=/elm-stuff
=/**/.DS_Store
+*.swpBegin reconstructing the 'fpart' presentation as an Elm program
We can render markdown and html elements
Next todo: scaling images to fit on slide
index 988c3a5..67b87e4 100644
--- a/elm.json
+++ b/elm.json
@@ -10,6 +10,8 @@
= "elm/core": "1.0.0",
= "elm/html": "1.0.0",
= "elm/svg": "1.0.1",
+ "elm-community/list-extra": "8.1.0",
+ "elm-explorations/markdown": "1.0.0",
= "ianmackenzie/elm-geometry": "1.2.1",
= "ianmackenzie/elm-geometry-svg": "1.0.2",
= "mdgriffith/elm-ui": "1.1.0"new file mode 100644
index 0000000..88cb6e2
--- /dev/null
+++ b/src/Main.elm
@@ -0,0 +1,400 @@
+module Main exposing (main)
+
+import Dict
+import Element
+import Html exposing (Html)
+import Html.Attributes as Html
+import Presentation exposing (Slide, markdown)
+
+
+currentSlide =
+ 5
+
+
+main =
+ let
+ slide =
+ slides
+ |> Dict.get currentSlide
+
+ notFound =
+ Element.text "404: Slide not found"
+ in
+ Element.layout [ Element.width Element.fill, Element.height Element.fill ] <|
+ Element.row
+ [ Element.centerX, Element.centerY ]
+ [ slide
+ |> Maybe.map (Element.column [])
+ |> Maybe.withDefault notFound
+ ]
+
+
+slides =
+ Dict.fromList <|
+ List.indexedMap Tuple.pair <|
+ [ markdown """
+ # FP-Art!
+ ## A functional programming workshop
+ ### for non-programmers
+ """
+ , markdown """
+ # Stuff
+ """
+ ]
+ :: [ markdown """
+ ## Setup
+ """
+ , markdown """
+ # Stuff
+ """
+ ]
+ :: [ markdown """
+ > This setup instructions are based on an assumption that you are using a Mac.
+ >
+ > If you are using Linux or BSD, then you probably know how to install stuff.
+ >
+ > If you are using anything else, then... well, good luck.
+ >
+ > The rest of the instructions should work with any platform.
+
+ """ ]
+ :: [ markdown """
+
+ We will need:
+
+ - a text editor (I use [Atom][])
+ - and [Elm programming language][]
+
+ [Atom]: https://atom.io/
+ [Elm programming language]: https://elm-lang.org/
+
+ """
+ ]
+ :: [ markdown """
+
+ We will use the terminal a little bit.
+
+ # :fa-terminal:
+
+ Don't be scared. It's easy :)
+
+ <!-- slide data-background-image="images/mac-launchpad-terminal.png" data-background-size="cover" data-background-position="top center"-->
+
+ > <p style="color: white">In Launchpad find a program called <code>terminal</code> and start it.</p>
+
+ """
+ ]
+ :: [ markdown """
+ You should see a window like this
+ """
+ , Element.el [ Element.height Element.fill, Element.width Element.fill ] <| Element.html <| Html.img [ Html.class "plain", Html.alt "Mac Terminal app window", Html.src "../assets/mac-terminal-window.png" ] []
+ , markdown """
+ Here is some more markdown.
+ """
+ ]
+ :: [ markdown """
+
+Now we are going to install few things.
+
+- Homebrew (to install other things)
+- Elm programming language
+- Atom editor
+
+"""
+ ]
+ :: [ markdown """
+
+### Install Homebrew
+
+Follow instructions on the [Homebrew website](https://brew.sh/) by typing the following in the terminal (you probably want to copy and paste it):
+
+```sh
+/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+```
+
+<small>
+Make sure that the command is exactly like the one above, including the `/` character at the beginning, the quotes and parentheses.
+
+It will ask you to confirm several actions and ask for your password. It may take few minutes to finish, so get your coffee
+</small>
+
+:fa-coffee:
+
+Once it's done you should see a command prompt like that:
+
+```
+~ your-name$
+```
+
+
+"""
+ ]
+ :: [ markdown """
+
+### Install the Elm programming language
+
+<small>Once we have Homebrew installed, we can use it to install the language.</small>
+
+Type the following in the terminal.
+
+```sh
+brew install node elm
+```
+
+and check if it works by typing:
+
+```
+elm repl
+```
+
+"""
+ ]
+ :: [ markdown """
+
+Note that the command line changes. You should see something like that
+
+```
+---- Elm 0.19.0 ----------------------------------------------------------------
+Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
+--------------------------------------------------------------------------------
+>
+```
+
+It's the Elm REPL
+
+<small>Read - Evaluate - Print Loop</small>
+
+*[REPL]: Read - Evaluate - Print Loop.
+
+"""
+ ]
+ :: [ markdown """
+
+Inside the REPL type
+
+```
+2 + 2
+```
+
+And expect to see
+
+```
+---- Elm 0.19.0 ----------------------------------------------------------------
+Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
+--------------------------------------------------------------------------------
+> 2 + 2
+4 : number
+>
+```
+
+Easy, huh?
+
+"""
+ ]
+ :: [ markdown """
+
+We will learn more about REPL later. For now type `:exit` to close it.
+
+The command line should look like before again.
+
+"""
+ ]
+ :: [ markdown """
+
+### Install Atom text editor
+
+Computer programs are represented as text, so the text editor is the most fundamental tool of a programmer. There is a lot of good text editors, but to get you started, we will use [Atom] here.
+
+"""
+ ]
+ :: [ markdown """
+
+Type following in the terminal:
+
+```
+brew cask install atom
+```
+
+And start it with:
+
+```sh
+atom
+```
+
+"""
+ ]
+ :: [ markdown """
+
+One last thing we need is Elm support for Atom editor. You can install it by typing in the terminal:
+
+```
+apm install language-elm
+```
+
+<small>APM is the Atom Package Manager, but don't pay much attention to it. We won't be using it again.</small>
+
+"""
+ ]
+ :: [ markdown """
+
+**We are all set!**
+
+:smile:
+
+"""
+ ]
+ :: [ markdown """
+
+
+# First program!
+
+"""
+ ]
+ :: [ markdown """
+
+As mentioned before, programs are represented as text (called *the source code*).
+
+The source code is stored in files
+
+:fa-file:
+
+and files are organized in directories
+
+:fa-folder:
+
+"""
+ ]
+ :: [ markdown """
+
+So the first step is to create a directory for our new program. Let's call it `fpart`.
+
+In the terminal type
+
+```sh
+mkdir fpart/
+```
+
+and then
+
+```
+cd fpart/
+```
+
+<small>This creates a new directory and makes it the current one. Again, don't worry about the details.</small>
+
+"""
+ ]
+ :: [ markdown """
+
+To easily create a new program, we can type
+
+```
+elm init
+```
+
+"""
+ ]
+ :: [ markdown """
+
+Then to create a file with source code, type
+
+```
+atom src/Main.elm
+```
+
+<small>This command should open a new Atom window with empty text file.</small>
+
+"""
+ ]
+ :: [ markdown """
+
+### `main.elm`
+
+```elm
+module Main exposing (main)
+
+import Html
+
+
+main =
+ Html.text "Hello, Tree!"
+```
+
+<small>Type the above in the editor and save the file</small>
+
+"""
+ ]
+ :: [ markdown """
+
+To see the program running type following in the terminal
+
+```sh
+elm reactor
+```
+
+<small>This command starts the Elm reactor, which will let you run your program in the web browser. Note that it won't give you the command line back - it will run as long as you don't stop it.</small>
+
+"""
+ ]
+ :: [ markdown """
+
+# Voila!
+
+<small>Open following address in the web browser</small>
+
+http://localhost:8000/src/Main.elm
+
+<small>Note that the same address was printed by Elm reactor</small>
+
+"""
+ ]
+ :: [ markdown """
+
+# Let's make a dot!
+# :fa-circle:
+
+"""
+ ]
+ :: [ markdown """
+
+We are going to use a technology called SVG
+
+<small>Scalable Vector Graphics</small>
+
+
+*[SVG]: Scalable Vector Graphics
+
+"""
+ ]
+ :: [ markdown """
+
+Let's install an Elm package to help us work with SVG.
+
+Stop the Reactor running in terminal by pressing
+
+`CTRL-C`
+
+and type the following
+
+```
+elm install elm/svg
+```
+
+Then start the reactor again
+
+```
+elm reactor
+```
+
+<small>you can press up arrow :fa-arrow-up: on the keyboard to get to previous commands</small>
+
+"""
+ ]
+ :: [ markdown """
+
+<iframe id="cartesian" data-src="./CartesianCoordinates.html" class="stretch">
+</iframe>
+
+"""
+ ]
+ :: []new file mode 100644
index 0000000..c017bb5
--- /dev/null
+++ b/src/Presentation.elm
@@ -0,0 +1,41 @@
+module Presentation exposing (Slide, markdown)
+
+import Element exposing (Element)
+import List.Extra as List
+import Markdown
+
+
+type alias Slide msg =
+ List (Element msg)
+
+
+markdown : String -> Element msg
+markdown string =
+ let
+ dedentedString =
+ string
+ |> String.lines
+ |> List.map dedent
+ |> String.join "\n"
+
+ dedent line =
+ line
+ |> String.toList
+ |> List.indexedMap Tuple.pair
+ |> List.dropWhile (\( index, character ) -> index < indentation && character == ' ')
+ |> List.map Tuple.second
+ |> String.fromList
+
+ indentation =
+ string
+ |> String.lines
+ |> List.filter (\line -> String.trim line /= "")
+ |> List.head
+ |> Maybe.withDefault ""
+ |> String.toList
+ |> List.findIndex ((/=) ' ')
+ |> Maybe.withDefault 0
+ in
+ Markdown.toHtml [] dedentedString
+ |> Element.html
+ |> Element.el [ Element.centerX ]Evolve program to Browser.sandobx, center text on slides
index 88cb6e2..50a8c46 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,45 +1,71 @@
=module Main exposing (main)
=
+import Browser
=import Dict
=import Element
+import Element.Font as Font
=import Html exposing (Html)
=import Html.Attributes as Html
=import Presentation exposing (Slide, markdown)
=
=
-currentSlide =
- 5
+main =
+ Browser.sandbox
+ { init = init
+ , view = view
+ , update = update
+ }
=
=
-main =
- let
- slide =
- slides
- |> Dict.get currentSlide
-
- notFound =
- Element.text "404: Slide not found"
- in
- Element.layout [ Element.width Element.fill, Element.height Element.fill ] <|
+type alias Model =
+ { currentSlide : Int
+ }
+
+
+type Msg
+ = Next
+ | Previous
+
+
+init : Model
+init =
+ { currentSlide = 0 }
+
+
+view : Model -> Html Msg
+view model =
+ Element.layout
+ [ Element.width Element.fill
+ , Element.height Element.fill
+ ]
+ <|
= Element.row
- [ Element.centerX, Element.centerY ]
- [ slide
+ [ Element.centerX, Element.centerY, Font.center ]
+ [ slides
+ |> Dict.get model.currentSlide
= |> Maybe.map (Element.column [])
- |> Maybe.withDefault notFound
+ |> Maybe.withDefault (Element.text "404: Slide not found")
= ]
=
=
+update : Msg -> Model -> Model
+update msg model =
+ case msg of
+ Next ->
+ { model | currentSlide = model.currentSlide + 1 }
+
+ Previous ->
+ { model | currentSlide = model.currentSlide - 1 }
+
+
=slides =
= Dict.fromList <|
= List.indexedMap Tuple.pair <|
= [ markdown """
- # FP-Art!
- ## A functional programming workshop
- ### for non-programmers
- """
- , markdown """
- # Stuff
- """
+ # FP-Art!
+ ## A functional programming workshop
+ ### for non-programmers
+ """
= ]
= :: [ markdown """
= ## SetupImplement keyboard navigation
index 67b87e4..d17943a 100644
--- a/elm.json
+++ b/elm.json
@@ -9,6 +9,7 @@
= "elm/browser": "1.0.0",
= "elm/core": "1.0.0",
= "elm/html": "1.0.0",
+ "elm/json": "1.0.0",
= "elm/svg": "1.0.1",
= "elm-community/list-extra": "8.1.0",
= "elm-explorations/markdown": "1.0.0",
@@ -17,7 +18,6 @@
= "mdgriffith/elm-ui": "1.1.0"
= },
= "indirect": {
- "elm/json": "1.0.0",
= "elm/time": "1.0.0",
= "elm/url": "1.0.0",
= "elm/virtual-dom": "1.0.2",index 50a8c46..0e51aaa 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,22 +1,29 @@
=module Main exposing (main)
=
-import Browser
+import Browser exposing (Document)
+import Browser.Events
=import Dict
=import Element
=import Element.Font as Font
=import Html exposing (Html)
=import Html.Attributes as Html
+import Json.Decode as Decode exposing (Decoder)
=import Presentation exposing (Slide, markdown)
=
=
=main =
- Browser.sandbox
+ Browser.document
= { init = init
= , view = view
= , update = update
+ , subscriptions = subscriptions
= }
=
=
+type alias Flags =
+ ()
+
+
=type alias Model =
= { currentSlide : Int
= }
@@ -27,35 +34,72 @@ type Msg
= | Previous
=
=
-init : Model
-init =
- { currentSlide = 0 }
+init : Flags -> ( Model, Cmd Msg )
+init flags =
+ ( { currentSlide = 0 }
+ , Cmd.none
+ )
=
=
-view : Model -> Html Msg
+view : Model -> Document Msg
=view model =
- Element.layout
- [ Element.width Element.fill
- , Element.height Element.fill
- ]
- <|
- Element.row
- [ Element.centerX, Element.centerY, Font.center ]
- [ slides
- |> Dict.get model.currentSlide
- |> Maybe.map (Element.column [])
- |> Maybe.withDefault (Element.text "404: Slide not found")
+ { title = "FP-Art!"
+ , body =
+ [ Element.layout
+ [ Element.width Element.fill
+ , Element.height Element.fill
= ]
+ <|
+ Element.column
+ [ Element.centerX, Element.centerY, Font.center ]
+ [ slides
+ |> Dict.get model.currentSlide
+ |> Maybe.map (Element.column [ Element.height Element.fill ])
+ |> Maybe.withDefault (Element.text "404: Slide not found")
+ ]
+ ]
+ }
=
=
-update : Msg -> Model -> Model
+update : Msg -> Model -> ( Model, Cmd Msg )
=update msg model =
= case msg of
= Next ->
- { model | currentSlide = model.currentSlide + 1 }
+ ( { model
+ | currentSlide =
+ min (Dict.size slides - 1) (model.currentSlide + 1)
+ }
+ , Cmd.none
+ )
=
= Previous ->
- { model | currentSlide = model.currentSlide - 1 }
+ ( { model
+ | currentSlide =
+ max 0 (model.currentSlide - 1)
+ }
+ , Cmd.none
+ )
+
+
+subscriptions model =
+ let
+ handleKeyPress : Decoder Msg
+ handleKeyPress =
+ Decode.field "key" Decode.string
+ |> Decode.andThen
+ (\key ->
+ case Debug.log "Key" key of
+ "ArrowLeft" ->
+ Decode.succeed Previous
+
+ "ArrowRight" ->
+ Decode.succeed Next
+
+ _ ->
+ Decode.fail "Unsupported key"
+ )
+ in
+ Browser.Events.onKeyPress handleKeyPress
=
=
=slides =