├── elm-bot-lines ├── build.sh ├── elm-package.json ├── index.html ├── Main.elm └── Grid.elm ├── elm-drag-objects ├── Notes.md ├── elm-package.json ├── LICENSE ├── Child.elm └── Parent.elm ├── .gitignore ├── elm-modular-view-style ├── web │ ├── panton │ │ ├── Panton-BlackCaps.otf │ │ ├── Panton-LightCaps.otf │ │ ├── Panton-BlackitalicCaps.otf │ │ ├── Panton-LightitalicCaps.otf │ │ └── EULA Free Font License Ver. 2.0.pdf │ └── electrolize │ │ ├── Electrolize-Regular.ttf │ │ └── OFL.txt ├── src │ ├── Style.elm │ ├── Widget.elm │ ├── Main.elm │ ├── Widget │ │ └── View.elm │ ├── Parent.elm │ └── Parent │ │ └── View.elm ├── README.md ├── elm-package.json └── AllInOne.elm ├── README.md ├── elm-markdown ├── TODO.md ├── elm-package.json ├── Main.elm └── index.html ├── elm-ai ├── elm-package.json └── Ai.elm ├── elm-scroll-divs ├── elm-package.json └── Main.elm ├── grand-subs ├── elm-package.json └── Main.elm └── LICENSE /elm-bot-lines/build.sh: -------------------------------------------------------------------------------- 1 | 2 | elm make Main.elm --output main.js 3 | -------------------------------------------------------------------------------- /elm-drag-objects/Notes.md: -------------------------------------------------------------------------------- 1 | ## Use time.every to animating delete 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | elm-stuff 2 | node_modules 3 | 4 | #swap files 5 | *~ 6 | *.swp 7 | *.swo 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /elm-modular-view-style/web/panton/Panton-BlackCaps.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanceras/elm-examples/HEAD/elm-modular-view-style/web/panton/Panton-BlackCaps.otf -------------------------------------------------------------------------------- /elm-modular-view-style/web/panton/Panton-LightCaps.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanceras/elm-examples/HEAD/elm-modular-view-style/web/panton/Panton-LightCaps.otf -------------------------------------------------------------------------------- /elm-modular-view-style/web/panton/Panton-BlackitalicCaps.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanceras/elm-examples/HEAD/elm-modular-view-style/web/panton/Panton-BlackitalicCaps.otf -------------------------------------------------------------------------------- /elm-modular-view-style/web/panton/Panton-LightitalicCaps.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanceras/elm-examples/HEAD/elm-modular-view-style/web/panton/Panton-LightitalicCaps.otf -------------------------------------------------------------------------------- /elm-modular-view-style/web/electrolize/Electrolize-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanceras/elm-examples/HEAD/elm-modular-view-style/web/electrolize/Electrolize-Regular.ttf -------------------------------------------------------------------------------- /elm-modular-view-style/web/panton/EULA Free Font License Ver. 2.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanceras/elm-examples/HEAD/elm-modular-view-style/web/panton/EULA Free Font License Ver. 2.0.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## This are list of my example code using elm-lang. 2 | 3 | AsciiToSVG is now moved into a different project https://github.com/ivanceras/svgbob 4 | 5 | It is being heavily rewritten for optimizing the generated SVG. 6 | 7 | -------------------------------------------------------------------------------- /elm-markdown/TODO.md: -------------------------------------------------------------------------------- 1 | ## Markdown live editor 2 | https://github.com/jbt/markdown-editor 3 | 4 | https://stackedit.io/ 5 | https://stackedit.io/editor 6 | 7 | ## Plugins 8 | 9 | http://flowchart.js.org/ 10 | 11 | ## Sideby side markdown 12 | https://markdown-it.github.io/ 13 | -------------------------------------------------------------------------------- /elm-modular-view-style/src/Style.elm: -------------------------------------------------------------------------------- 1 | module Style exposing (..) 2 | 3 | import Html.Attributes exposing (style) 4 | import Css exposing (..) 5 | 6 | styles = 7 | Css.asPairs >> style 8 | 9 | 10 | truste_header = 11 | styles [ border3 (px 1) solid (rgb 10 10 255)] 12 | -------------------------------------------------------------------------------- /elm-modular-view-style/README.md: -------------------------------------------------------------------------------- 1 | # Building 2 | 3 | ``` 4 | 5 | elm make src/Main.elm 6 | 7 | ``` 8 | 9 | then open index.html 10 | 11 | 12 | ## Notes: 13 | 14 | There is already an elm library for DOM scrolling 15 | http://package.elm-lang.org/packages/elm-lang/dom/1.1.0/Dom-Scroll 16 | -------------------------------------------------------------------------------- /elm-modular-view-style/src/Widget.elm: -------------------------------------------------------------------------------- 1 | module Widget exposing (..) 2 | 3 | type Msg 4 | = DoSomething 5 | 6 | 7 | type alias Model = 8 | { name: String 9 | , description: String 10 | } 11 | 12 | create: Model 13 | create = 14 | { name = "Statistics" 15 | , description = "Hello" 16 | } 17 | -------------------------------------------------------------------------------- /elm-markdown/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "." 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "4.0.5 <= v < 5.0.0" 12 | }, 13 | "elm-version": "0.17.0 <= v < 0.18.0" 14 | } -------------------------------------------------------------------------------- /elm-modular-view-style/src/Main.elm: -------------------------------------------------------------------------------- 1 | module Main exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.App as App 5 | import Html.Events exposing (..) 6 | import Html.Attributes 7 | 8 | import Parent.View 9 | 10 | 11 | import Parent 12 | 13 | 14 | 15 | main = 16 | App.program { 17 | init = Parent.init 18 | , view = Parent.View.view 19 | , update = Parent.update 20 | , subscriptions = Parent.subscriptions 21 | } 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /elm-ai/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "." 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "4.0.5 <= v < 5.0.0", 12 | "elm-lang/html": "1.1.0 <= v < 2.0.0" 13 | }, 14 | "elm-version": "0.17.0 <= v < 0.18.0" 15 | } -------------------------------------------------------------------------------- /elm-scroll-divs/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "." 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "4.0.5 <= v < 5.0.0", 12 | "elm-lang/html": "1.1.0 <= v < 2.0.0" 13 | }, 14 | "elm-version": "0.17.1 <= v < 0.18.0" 15 | } 16 | -------------------------------------------------------------------------------- /elm-modular-view-style/src/Widget/View.elm: -------------------------------------------------------------------------------- 1 | 2 | module Widget.View exposing (view) 3 | 4 | import Html exposing (..) 5 | import Html.Events exposing (..) 6 | import Html.Attributes exposing (style) 7 | 8 | import Css exposing (..) 9 | import Style exposing (styles) 10 | import Widget 11 | import Color 12 | 13 | 14 | 15 | 16 | 17 | view: Widget.Model -> Html Widget.Msg 18 | view model = 19 | div [ styles [border3 (px 1) solid (hex "cf9")]] 20 | [ 21 | Html.text "This is a child widget" 22 | ] 23 | -------------------------------------------------------------------------------- /elm-markdown/Main.elm: -------------------------------------------------------------------------------- 1 | type Block 2 | = Header (List Span) Int 3 | | Para (List Span) 4 | | Blockquote List Block 5 | | CodeBlock String 6 | | UnorderedList List ListItem 7 | | Raw String 8 | | Hr 9 | 10 | 11 | type ListItem 12 | = Simple List Span 13 | | Paragraph List Block 14 | 15 | 16 | type Span 17 | = Break 18 | | Text String 19 | | Code String 20 | | Link String String (Maybe String) 21 | | Image String String (Maybe String) 22 | | Emphasis List Span 23 | | String List Span 24 | 25 | 26 | -------------------------------------------------------------------------------- /grand-subs/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "." 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "4.0.5 <= v < 5.0.0", 12 | "elm-lang/html": "1.1.0 <= v < 2.0.0", 13 | "elm-lang/mouse": "1.0.0 <= v < 2.0.0" 14 | }, 15 | "elm-version": "0.17.0 <= v < 0.18.0" 16 | } -------------------------------------------------------------------------------- /elm-bot-lines/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "." 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "4.0.5 <= v < 5.0.0", 12 | "elm-lang/html": "1.1.0 <= v < 2.0.0", 13 | "elm-lang/svg": "1.1.1 <= v < 2.0.0" 14 | }, 15 | "elm-version": "0.17.1 <= v < 0.18.0" 16 | } 17 | -------------------------------------------------------------------------------- /elm-drag-objects/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "." 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "4.0.5 <= v < 5.0.0", 12 | "elm-lang/html": "1.1.0 <= v < 2.0.0", 13 | "elm-lang/mouse": "1.0.0 <= v < 2.0.0" 14 | }, 15 | "elm-version": "0.17.1 <= v < 0.18.0" 16 | } 17 | -------------------------------------------------------------------------------- /elm-modular-view-style/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "src" 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-lang/core": "4.0.5 <= v < 5.0.0", 12 | "elm-lang/html": "1.1.0 <= v < 2.0.0", 13 | "jystic/elm-font-awesome": "2.0.0 <= v < 3.0.0", 14 | "rtfeldman/elm-css": "5.0.0 <= v < 6.0.0" 15 | }, 16 | "elm-version": "0.17.1 <= v < 0.18.0" 17 | } 18 | -------------------------------------------------------------------------------- /elm-modular-view-style/AllInOne.elm: -------------------------------------------------------------------------------- 1 | 2 | import Html exposing (..) 3 | import Html.App exposing (..) 4 | import Html.Events exposing (..) 5 | import Html.Attributes 6 | 7 | import Css exposing (..) 8 | 9 | 10 | main = 11 | beginnerProgram { model = 0, view = view, update = update } 12 | 13 | styles = 14 | Css.asPairs >> Html.Attributes.style 15 | 16 | 17 | view model = 18 | div [] 19 | [ button [ onClick Decrement ] [ Html.text "-" ] 20 | , div [] [ Html.text (toString model) ] 21 | , button [ onClick Increment ] [ Html.text "+" ] 22 | , div [ styles [ 23 | width (px 100) 24 | ,height (px 100) 25 | ,backgroundColor (rgb 100 10 10) 26 | ,color (rgb 200 10 100) 27 | ] ] 28 | [ Html.text "Whee!" ] 29 | ] 30 | 31 | 32 | type Msg = Increment | Decrement 33 | 34 | 35 | update msg model = 36 | case msg of 37 | Increment -> 38 | model + 1 39 | 40 | Decrement -> 41 | model - 1 42 | -------------------------------------------------------------------------------- /elm-drag-objects/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /elm-modular-view-style/src/Parent.elm: -------------------------------------------------------------------------------- 1 | module Parent exposing(..) 2 | 3 | import Html exposing (..) 4 | import Html.App as App 5 | import Html.Events exposing (..) 6 | import Html.Attributes 7 | 8 | import Css exposing (..) 9 | 10 | 11 | import Widget 12 | 13 | 14 | type Msg 15 | = Increment 16 | | Decrement 17 | | UpdateWidget Widget.Msg 18 | 19 | type alias Model = 20 | { id: Int 21 | , message: String 22 | , widget: Widget.Model 23 | } 24 | 25 | 26 | create: Model 27 | create= 28 | {id = 0 29 | ,message = "Hello" 30 | ,widget = Widget.create 31 | } 32 | 33 | update: Msg -> Model -> (Model, Cmd Msg) 34 | update msg model = 35 | case msg of 36 | Increment -> 37 | ({model | id = model.id + 1} 38 | , Cmd.none) 39 | 40 | Decrement -> 41 | ({model | id = model.id- 1} 42 | , Cmd.none) 43 | 44 | UpdateWidget widgetMsg -> 45 | (model 46 | , Cmd.none) 47 | 48 | 49 | init: (Model, Cmd Msg) 50 | init = 51 | (create 52 | ,Cmd.batch[ 53 | ]) 54 | 55 | 56 | subscriptions: Model -> Sub Msg 57 | subscriptions model = 58 | Sub.batch [] 59 | -------------------------------------------------------------------------------- /elm-modular-view-style/src/Parent/View.elm: -------------------------------------------------------------------------------- 1 | module Parent.View exposing (view) 2 | 3 | import Html exposing (..) 4 | import Html.App as App 5 | import Html.Events exposing (..) 6 | import Html.Attributes exposing (style) 7 | import Css exposing (..) 8 | 9 | import Style exposing (styles,truste_header) 10 | import Parent exposing (..) 11 | import Widget.View 12 | import FontAwesome exposing (..) 13 | import Color 14 | 15 | 16 | view: Parent.Model -> Html Parent.Msg 17 | 18 | 19 | 20 | view model = 21 | div [] 22 | [ button [ onClick Decrement ] [ Html.text "-" ] 23 | , if model.id > 5 then div [] [ Html.text (toString model) ] 24 | else Html.text "No id for you!..." 25 | , button [ onClick Increment ] [ Html.text "+" ] 26 | , div [ styles [ 27 | width (px 100) 28 | ,height (px 100) 29 | ,backgroundColor (rgb 100 10 10) 30 | ,color (rgb 200 10 100) 31 | ] 32 | ,style [("color", "#cf9")] 33 | ,truste_header 34 | ] 35 | [ Html.text "PARENT WIDGET" ] 36 | , android (Color.rgb 30 30 30) 50 37 | , check (Color.rgb 0 255 0) 80 38 | , calendar (Color.rgb 0 100 0) 16 39 | , App.map UpdateWidget (Widget.View.view model.widget) 40 | ] 41 | 42 | 43 | -------------------------------------------------------------------------------- /elm-scroll-divs/Main.elm: -------------------------------------------------------------------------------- 1 | 2 | import Html exposing (..) 3 | import Html.App as App exposing (..) 4 | import Html.Events exposing (..) 5 | import Html.Attributes exposing (..) 6 | import Json.Decode as Json exposing ((:=)) 7 | 8 | 9 | main = 10 | beginnerProgram { model = 0, view = view, update = update } 11 | 12 | 13 | view model = 14 | div [] 15 | [ button [ onClick Decrement ] [ text "-" ] 16 | , div [] [ text (toString model) ] 17 | , button [ onClick Increment ] [ text "+" ] 18 | ,div [class "container" 19 | ,style [("background-color", "#eee") 20 | ,("width", "500px") 21 | ,("height", "500px") 22 | ,("overflow", "auto") 23 | ] 24 | ,onScroll Scrolled 25 | ] 26 | [ div [class "widget" 27 | ,style [("background-color", "#cf9") 28 | ,("width", "1200px") 29 | ,("height", "700px") 30 | ] 31 | ] 32 | [text "Scrollers"] 33 | ] 34 | ] 35 | 36 | 37 | type Msg 38 | = Increment 39 | | Decrement 40 | | Scrolled Scroll 41 | 42 | 43 | update msg model = 44 | case msg of 45 | Increment -> 46 | model + 1 47 | 48 | Decrement -> 49 | model - 1 50 | 51 | Scrolled scroll -> 52 | Debug.log ("scrolled "++(toString msg)) 53 | model 54 | 55 | 56 | type alias Scroll = 57 | {left: Int 58 | ,top: Int 59 | } 60 | 61 | scrollDecoder: Json.Decoder Scroll 62 | scrollDecoder = 63 | Json.object2 Scroll 64 | ("scrollTop" := Json.int) 65 | ("scrollLeft" := Json.int) 66 | 67 | 68 | 69 | targetScroll : Json.Decoder Scroll 70 | targetScroll = 71 | Json.at ["target"] scrollDecoder 72 | 73 | onScroll : (Scroll -> msg) -> Attribute msg 74 | onScroll tagger = 75 | on "scroll" (Json.map tagger targetScroll) 76 | -------------------------------------------------------------------------------- /elm-drag-objects/Child.elm: -------------------------------------------------------------------------------- 1 | module Child exposing (..) 2 | 3 | import Html exposing (..) 4 | import Html.App as App 5 | import Html.Attributes exposing (..) 6 | import Html.Events exposing (on) 7 | import Json.Decode as Json exposing ((:=)) 8 | import Mouse exposing (Position) 9 | 10 | 11 | 12 | 13 | -- MODEL 14 | 15 | 16 | type alias Model = 17 | { position : Position 18 | , drag : Maybe Drag 19 | , id : Int 20 | } 21 | 22 | 23 | type alias Drag = 24 | { start : Position 25 | , current : Position 26 | } 27 | 28 | 29 | init :Int -> Position -> Model 30 | init id position = 31 | ( Model position Nothing id) 32 | 33 | 34 | 35 | -- UPDATE 36 | 37 | 38 | type Msg 39 | = DragStart Position 40 | | DragAt Position 41 | | DragEnd Position 42 | 43 | type OutMsg = 44 | ChildListened Int 45 | | ChildStopListened Int 46 | 47 | update : Msg -> Model -> ( Model, Maybe OutMsg ) 48 | update msg model = 49 | Debug.log ("Received "++(toString msg)++" in "++(toString model.id)) 50 | ( updateHelp msg model) 51 | 52 | 53 | updateHelp : Msg -> Model -> (Model, Maybe OutMsg) 54 | updateHelp msg ({position, drag, id} as model) = 55 | case msg of 56 | DragStart xy -> 57 | (Model position (Just (Drag xy xy)) id 58 | , Just (ChildListened id) 59 | ) 60 | 61 | DragAt xy -> 62 | (Model position (Maybe.map (\{start} -> Drag start xy) drag) id 63 | , Nothing 64 | ) 65 | 66 | DragEnd _ -> 67 | (Model (getPosition model) Nothing id 68 | , Just (ChildStopListened id) 69 | ) 70 | 71 | 72 | 73 | 74 | 75 | -- VIEW 76 | 77 | 78 | (=>) = (,) 79 | 80 | 81 | view : Model -> Html Msg 82 | view model = 83 | let 84 | realPosition = 85 | getPosition model 86 | in 87 | div 88 | [ onMouseDown 89 | , style 90 | [ "background-color" => "#3C8D2F" 91 | , "cursor" => "move" 92 | 93 | , "width" => "100px" 94 | , "height" => "100px" 95 | , "border-radius" => "4px" 96 | , "position" => "absolute" 97 | , "left" => px realPosition.x 98 | , "top" => px realPosition.y 99 | 100 | , "color" => "white" 101 | , "display" => "flex" 102 | , "align-items" => "center" 103 | , "justify-content" => "center" 104 | ] 105 | ] 106 | [ text "Drag Me!" 107 | ] 108 | 109 | 110 | px : Int -> String 111 | px number = 112 | toString number ++ "px" 113 | 114 | 115 | getPosition : Model -> Position 116 | getPosition {position, drag} = 117 | case drag of 118 | Nothing -> 119 | position 120 | 121 | Just {start,current} -> 122 | Position 123 | (position.x + current.x - start.x) 124 | (position.y + current.y - start.y) 125 | 126 | 127 | onMouseDown : Attribute Msg 128 | onMouseDown = 129 | on "mousedown" (Json.map DragStart Mouse.position) 130 | -------------------------------------------------------------------------------- /elm-bot-lines/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Ascii to SVG 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 23 | 24 | 25 |
26 |
27 |
28 |
29 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /grand-subs/Main.elm: -------------------------------------------------------------------------------- 1 | import Html exposing (..) 2 | import Html.App as App 3 | import Html.Attributes exposing (..) 4 | import Html.Events exposing (on) 5 | import Json.Decode as Json exposing ((:=)) 6 | import Mouse exposing (Position) 7 | 8 | 9 | 10 | main = 11 | App.program 12 | { init = init 13 | , view = view 14 | , update = update 15 | , subscriptions = subscriptions 16 | } 17 | 18 | 19 | -- MODEL 20 | type alias Model = 21 | { childmodel : ChildModel } 22 | 23 | type alias ChildModel = 24 | { position : Position 25 | , drag : Maybe Drag 26 | } 27 | 28 | 29 | type alias Drag = 30 | { start : Position 31 | , current : Position 32 | } 33 | 34 | 35 | init : ( Model, Cmd Msg ) 36 | init = 37 | ( Model <| ChildModel (Position 200 200) Nothing, Cmd.none ) 38 | 39 | 40 | 41 | -- UPDATE 42 | 43 | 44 | type ChildMsg 45 | = DragStart Position 46 | | DragAt Position 47 | | DragEnd Position 48 | 49 | type Msg 50 | = ChildMsg ChildMsg 51 | 52 | update : Msg -> Model -> (Model, Cmd Msg) 53 | update msg model = 54 | case msg of 55 | ChildMsg msg -> 56 | let (childmodel, childmsg) = childupdate msg model.childmodel 57 | in 58 | (Model childmodel, Cmd.map ChildMsg childmsg) 59 | 60 | childupdate : ChildMsg -> ChildModel -> ( ChildModel, Cmd ChildMsg ) 61 | childupdate msg model = 62 | ( updateHelp msg model, Cmd.none ) 63 | 64 | 65 | updateHelp : ChildMsg -> ChildModel -> ChildModel 66 | updateHelp msg ({position, drag} as model) = 67 | case msg of 68 | DragStart xy -> 69 | ChildModel position (Just (Drag xy xy)) 70 | 71 | DragAt xy -> 72 | ChildModel position (Maybe.map (\{start} -> Drag start xy) drag) 73 | 74 | DragEnd _ -> 75 | ChildModel (getPosition model) Nothing 76 | 77 | 78 | 79 | -- SUBSCRIPTIONS 80 | 81 | 82 | childsubs : ChildModel -> Sub ChildMsg 83 | childsubs model = 84 | case model.drag of 85 | Nothing -> 86 | Sub.none 87 | 88 | Just _ -> 89 | Sub.batch [ Mouse.moves DragAt, Mouse.ups DragEnd ] 90 | 91 | subscriptions : Model -> Sub Msg 92 | subscriptions model = 93 | Sub.map ChildMsg (childsubs model.childmodel) 94 | 95 | -- VIEW 96 | 97 | 98 | (=>) = (,) 99 | 100 | view : Model -> Html Msg 101 | view model = 102 | App.map ChildMsg (childview model.childmodel) 103 | 104 | childview : ChildModel -> Html ChildMsg 105 | childview model = 106 | let 107 | realPosition = 108 | getPosition model 109 | in 110 | div 111 | [ onMouseDown 112 | , style 113 | [ "background-color" => "#3C8D2F" 114 | , "cursor" => "move" 115 | 116 | , "width" => "100px" 117 | , "height" => "100px" 118 | , "border-radius" => "4px" 119 | , "position" => "absolute" 120 | , "left" => px realPosition.x 121 | , "top" => px realPosition.y 122 | 123 | , "color" => "white" 124 | , "display" => "flex" 125 | , "align-items" => "center" 126 | , "justify-content" => "center" 127 | ] 128 | ] 129 | [ text "Drag Me!" 130 | ] 131 | 132 | 133 | px : Int -> String 134 | px number = 135 | toString number ++ "px" 136 | 137 | 138 | getPosition : ChildModel -> Position 139 | getPosition {position, drag} = 140 | case drag of 141 | Nothing -> 142 | position 143 | 144 | Just {start,current} -> 145 | Position 146 | (position.x + current.x - start.x) 147 | (position.y + current.y - start.y) 148 | 149 | 150 | onMouseDown : Attribute ChildMsg 151 | onMouseDown = 152 | on "mousedown" (Json.map DragStart Mouse.position) 153 | -------------------------------------------------------------------------------- /elm-drag-objects/Parent.elm: -------------------------------------------------------------------------------- 1 | 2 | import Html exposing (..) 3 | import Html.App as App 4 | import Html.Attributes exposing (..) 5 | import Html.Events exposing (on) 6 | import Json.Decode as Json exposing ((:=)) 7 | import Mouse exposing (Position) 8 | import Child 9 | 10 | 11 | main = 12 | App.program 13 | { init = init 14 | , view = view 15 | , update = update 16 | , subscriptions = subscriptions 17 | } 18 | 19 | 20 | -- MODEL 21 | 22 | 23 | type alias Model = 24 | { child : List Child.Model 25 | , listened: Maybe Int 26 | } 27 | 28 | 29 | type alias Drag = 30 | { start : Position 31 | , current : Position 32 | } 33 | 34 | 35 | init : ( Model, Cmd Msg ) 36 | init = 37 | ( Model 38 | [Child.init 0 (Position 200 200) 39 | ,Child.init 1 (Position 300 300) 40 | ] 41 | Nothing 42 | 43 | , Cmd.none ) 44 | 45 | 46 | 47 | -- UPDATE 48 | 49 | 50 | type Msg 51 | = UpdateChild Int Child.Msg 52 | | DragAt Position 53 | | DragEnd Position 54 | 55 | 56 | update : Msg -> Model -> ( Model, Cmd Msg ) 57 | update msg model = 58 | case msg of 59 | UpdateChild childId childMsg -> 60 | updateThenHandleChildMsg childMsg childId model 61 | 62 | DragAt position -> 63 | case model.listened of 64 | Just id -> 65 | updateThenHandleChildMsg (Child.DragAt position) id model 66 | Nothing -> 67 | (model, Cmd.none) 68 | 69 | DragEnd position -> 70 | case model.listened of 71 | Just id -> 72 | updateThenHandleChildMsg (Child.DragEnd position) id model 73 | Nothing -> 74 | (model, Cmd.none) 75 | 76 | updateThenHandleChildMsg: Child.Msg -> Int -> Model -> (Model, Cmd Msg) 77 | updateThenHandleChildMsg childMsg childId model = 78 | updateChild childMsg childId model 79 | |> handleChildOutMsg 80 | 81 | handleChildOutMsg: (Model, Maybe Child.OutMsg) -> (Model, Cmd Msg) 82 | handleChildOutMsg (model, outmsg) = 83 | case outmsg of 84 | Just outmsg -> 85 | case outmsg of 86 | Child.ChildListened id -> 87 | ({model | listened = Just id} 88 | , Cmd.none) 89 | 90 | Child.ChildStopListened id -> 91 | ({model | listened = Nothing } 92 | , Cmd.none) 93 | 94 | Nothing -> 95 | (model, Cmd.none) 96 | 97 | 98 | updateChild: Child.Msg -> Int -> Model -> (Model, Maybe Child.OutMsg) 99 | updateChild childMsg childId model = 100 | let children = 101 | List.map( 102 | \child -> 103 | if child.id == childId then 104 | Child.update childMsg child 105 | else 106 | (child, Nothing) 107 | ) model.child 108 | 109 | (child, outmsgs) = List.unzip children 110 | in 111 | ({model | child = child 112 | } 113 | , 114 | (List.filterMap ( 115 | \o -> o 116 | ) outmsgs 117 | |> List.head 118 | ) 119 | ) 120 | 121 | 122 | -- SUBSCRIPTIONS 123 | 124 | 125 | subscriptions : Model -> Sub Msg 126 | subscriptions model = 127 | case model.listened of 128 | Just id -> 129 | Sub.batch [ Mouse.moves DragAt, Mouse.ups DragEnd ] 130 | Nothing -> 131 | Sub.none 132 | 133 | 134 | 135 | -- VIEW 136 | 137 | 138 | (=>) = (,) 139 | 140 | 141 | view : Model -> Html Msg 142 | view model = 143 | div [] 144 | <| List.map 145 | (\ child -> 146 | App.map (UpdateChild child.id) (Child.view child) 147 | ) model.child 148 | 149 | 150 | -------------------------------------------------------------------------------- /elm-modular-view-style/web/electrolize/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011, Cyreal (www.cyreal.org), 2 | with Reserved Font Name "Electrolize". 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /elm-ai/Ai.elm: -------------------------------------------------------------------------------- 1 | import Html exposing (text,div) 2 | import Time exposing (Time) 3 | 4 | type Word = Sky | Is | Blue | Atmosphere | Ozone 5 | | I | Have | Magic 6 | | Skies | Are | Atmospheres 7 | | Yes | Ok | Good | Great | Exactly | True' 8 | | No | Not | Nope | Bad | Isn't 9 | 10 | 11 | wordEquivalent = 12 | [(Sky,"sky") 13 | ,(Is,"is") 14 | ,(Blue,"blue") 15 | ,(Atmosphere, "atmosphere") 16 | ,(Ozone,"ozone") 17 | ,(I,"i") 18 | ,(Have,"have") 19 | ,(Magic,"magic") 20 | ,(Skies,"skies") 21 | ,(Are,"are") 22 | ,(Atmospheres, "atmospheres") 23 | ,(Yes,"yes") 24 | ,(Ok,"ok") 25 | ,(Good,"good") 26 | ,(Great, "great") 27 | ] 28 | 29 | toWord: Word -> Maybe String 30 | toWord x = 31 | List.filterMap ( 32 | \(w, e) -> 33 | if w == x then 34 | Just e 35 | else 36 | Nothing 37 | )wordEquivalent 38 | |> List.head 39 | 40 | inTruth words = 41 | let len = List.length words 42 | in 43 | List.any (\e -> e == words) truthdb 44 | 45 | truthdb = 46 | [ 47 | [Sky,Is,Blue] 48 | ,[Sky,Is,Atmosphere] 49 | ] 50 | 51 | 52 | synonym: List (Word, List Word) 53 | synonym = 54 | [(Sky, 55 | [Atmosphere,Ozone] -- TODO: 2 words that can substitude 1 (Sky -> Ozone Layer) 56 | ) 57 | ,(Atmosphere, [Sky]) 58 | ] 59 | 60 | 61 | otherWord: Word -> Maybe (List Word) 62 | otherWord x = 63 | List.filterMap( 64 | \(w,s) -> 65 | if (w == x) then 66 | Just s 67 | else 68 | Nothing 69 | ) synonym 70 | |> List.head 71 | 72 | 73 | truth x y z = 74 | inTruth [x,y,z] 75 | 76 | canBeTrue x y z = 77 | case otherWord x of 78 | Just otherWord' -> 79 | List.any ( 80 | \x' -> 81 | inTruth [x', y, z] 82 | ) otherWord' 83 | Nothing -> 84 | False 85 | 86 | 87 | 88 | plural = 89 | [(Sky,Skies) 90 | ,(Is,Are) 91 | ,(Atmosphere,Atmospheres) 92 | ] 93 | 94 | pluralOf x = 95 | List.filterMap( 96 | \ (s,p)-> 97 | if s == x then 98 | Just p 99 | else 100 | Nothing 101 | )plural 102 | |> List.head 103 | 104 | pluralOfWithGuess: Word -> Maybe String 105 | pluralOfWithGuess x = 106 | case pluralOf x of 107 | Just x' -> 108 | toWord x' 109 | Nothing -> 110 | case toWord x of 111 | Just wordX -> 112 | Just (wordX ++ "s") 113 | 114 | Nothing -> 115 | Just "anything(s)" 116 | 117 | singularOf x = 118 | List.filterMap( 119 | \ (s,p)-> 120 | if p == x then 121 | Just s 122 | else 123 | Nothing 124 | )plural 125 | 126 | spoken: List (User, List Word, Time) 127 | spoken = 128 | [ 129 | (User41532, [Sky,Is,Blue],231231.122) 130 | ,(User41532, [Atmosphere,Is,Blue], 12838912.77) 131 | ,(MrRubeck812, [I, Have, Magic], 23142002.89) 132 | ] 133 | 134 | positiveWords = 135 | [Yes, Good, Ok, True', Great, Exactly] 136 | 137 | negativeWords = 138 | [No, Not, Nope, Isn't, Bad] 139 | 140 | type User = User41532 | MrRubeck812 141 | 142 | main = 143 | div [] 144 | [ 145 | showDiv "thruth sky is blue?" ( truth Sky Is Blue) 146 | ,showDiv "thruth atmoshere is blue?" (truth Atmosphere Is Blue) 147 | ,showDiv "inTruth [Atmosphere,Is,Blue]?" (inTruth [Atmosphere, Is, Blue]) 148 | ,showDiv "canBeTrue [Atmosphere,Is,Blue]?" (canBeTrue Atmosphere Is Blue) 149 | ,showDiv "otherWord Sky?" (otherWord Sky) 150 | ,showDiv "otherWord Atmosphere?" (otherWord Atmosphere) 151 | ,showDiv "canBeTrue [Atmosphere,Is,Sky]?" (canBeTrue Atmosphere Is Sky) 152 | ,showDiv "plural of Sky?" (pluralOf Sky) 153 | ,showDiv "plural of Ozone?" (pluralOfWithGuess Ozone) 154 | ] 155 | 156 | showDiv question answer = 157 | div [] 158 | [text question 159 | ,text (toString answer) 160 | ] 161 | 162 | {--| 163 | a very simple AI concept. 164 | 165 | addWord = rewrite the whole program then see if it compiles 166 | 167 | addRule = add a function to the program, must be a valid elm function 168 | 169 | addTruth List = add truths into the program automatically add workds that has not been encountered before 170 | the order of words in truths is sensitive 171 | 172 | addSynonyms List 173 | 174 | how to add more truths that is longer than 2 arguments 175 | 176 | truth a 177 | truth2 a b 178 | truth3 a b c 179 | truth4 a b c d 180 | truth5 a b c d 181 | truth6 a b c d e 182 | 183 | --} 184 | -------------------------------------------------------------------------------- /elm-bot-lines/Main.elm: -------------------------------------------------------------------------------- 1 | port module Main exposing (..) 2 | import Html exposing (text,pre,div,button,textarea) 3 | import Html.Attributes exposing (class, style,contenteditable,id) 4 | import Html.Events exposing (onClick,on) 5 | import String 6 | import Grid 7 | import Html.App as App 8 | import Json.Decode exposing (string) 9 | import Regex 10 | 11 | 12 | {-- code which detects lines and connections 13 | also algorithmn to connect these lines 14 | --} 15 | 16 | type alias Model = 17 | {grid: Grid.Model 18 | } 19 | 20 | type Msg = Input String | Convert 21 | 22 | 23 | init: (Model, Cmd Msg) 24 | init = 25 | ({grid = Grid.init arg 26 | } 27 | ,Cmd.batch[ 28 | setAsciiText arg 29 | ] 30 | ) 31 | 32 | textContentDecoder = 33 | Json.Decode.at ["target", "textContent"] string 34 | 35 | 36 | 37 | view model = 38 | div [style 39 | [("display", "flex") 40 | ] 41 | ] 42 | [ 43 | div[] 44 | [button [onClick Convert 45 | ] 46 | [text "Convert >>"] 47 | ] 48 | ,div 49 | [style [("width", "500px") 50 | ,("height", "100%") 51 | ,("overflow", "auto") 52 | ] 53 | ] 54 | [Grid.getSvg model.grid 55 | ] 56 | ] 57 | 58 | {-- 59 | div [] 60 | [ 61 | button [ 62 | style [("padding","10px") 63 | ,("margin-left","500px") 64 | ] 65 | ,onClick Convert 66 | ] 67 | [text "Convert >>"] 68 | ,div [style [("display", "flex")]] 69 | [pre 70 | [style 71 | [("font-size", "15.4px") 72 | ,("font-family","monospace") 73 | ,("word-wrap","nowrap") 74 | ,("overflow", "auto") 75 | ,("border", "1px solid #ddd") 76 | ,("min-height", "500px") 77 | ,("min-width", "500px") 78 | ] 79 | ,contenteditable True 80 | ,id "ascii_text" 81 | ,on "input" (Json.Decode.map Input textContentDecoder) 82 | ] 83 | [text arg] 84 | ,div [style [("padding-left", "10px")]] 85 | [Grid.getSvg model.grid 86 | ] 87 | ] 88 | ] 89 | --} 90 | 91 | 92 | update msg model = 93 | case msg of 94 | Convert -> 95 | (model, getAsciiText () ) 96 | Input asciiText -> 97 | ({model | grid = Grid.init asciiText} 98 | ,Cmd.none 99 | ) 100 | 101 | main = 102 | App.program 103 | {init = init 104 | ,view = view 105 | ,update = update 106 | ,subscriptions = subscriptions 107 | } 108 | 109 | subscriptions: Model -> Sub Msg 110 | subscriptions model = 111 | Sub.batch [receiveAsciiText Input] 112 | 113 | port getAsciiText: () -> Cmd msg 114 | 115 | port setAsciiText: String -> Cmd msg 116 | 117 | port receiveAsciiText: (String -> msg) -> Sub msg 118 | 119 | 120 | 121 | 122 | arg = 123 | """ 124 | 125 | +------+ +-----+ +-----+ +-----+ 126 | | | | | | | | | 127 | | Foo +-->| Bar +---+ Baz |<--+ Moo | 128 | | | | | | | | | 129 | +------+ +-----+ +--+--+ +-----+ 130 | ^ | 131 | | V 132 | .-------------+-----------------------. 133 | | Hello here and there and everywhere | 134 | '-------------------------------------' 135 | 136 | 137 | ____________ 138 | .--------------. \\ \\ 139 | / a == b \\ \\ \\ __________ 140 | ( && ) ) process ) \\ \\ 141 | \\ 'string' ne '' / / / / process / 142 | '--------------' /___________/ /_________/ 143 | 144 | User code ^ ^ OS code 145 | \\ / 146 | \\ .--' 147 | \\ / 148 | User code <--- Mode ----> OS code 149 | / \\ 150 | .--' \\___ 151 | / \\ 152 | v v 153 | User code OS code 154 | 155 | .---. .---. .---. .---. .---. .---. 156 | OS API '---' '---' '---' '---' '---' '---' 157 | | | | | | | 158 | v v | v | v 159 | .------------. | .-----------. | .-----. 160 | | Filesystem | | | Scheduler | | | MMU | 161 | '------------' | '-----------' | '-----' 162 | | | | | 163 | v | | v 164 | .----. | | .---------. 165 | | IO |<----' | | Network | 166 | '----' | '---------' 167 | | | | 168 | v v v 169 | .---------------------------------------. 170 | | HAL | 171 | '---------------------------------------' 172 | 173 | 174 | ____[] 175 | | ___ | 176 | || || device 177 | ||___|| loads 178 | | ooo |----------------------------------------------------------. 179 | | ooo | | | | 180 | | ooo | | | | 181 | '_____' | | | 182 | | | | 183 | v v v 184 | .-------------------. .---------------------------. .-------------------. 185 | | Loadable module C | | Loadable module A | | Loadable module B | 186 | '-------------------' |---------------------------| | (instrumented) | 187 | | | .-----. | '-------------------' 188 | '------------+-------->| A.o | | | 189 | calls | '-----' | | 190 | | .------------------. | | 191 | | / A.instrumented.o /<---+-------------' 192 | | '------------------' | calls 193 | '---------------------------' 194 | 195 | 196 | .--> Base::Class::Derived_A 197 | / 198 | .----> Base::Class::Derived_B 199 | Something -------. / \\ 200 | \\ / \\---> Base::Class::Derived 201 | Something::else \\ / \\ 202 | \\ \\ / '--> Base::Class::Derived 203 | \\ \\ / 204 | \\ \\ .-----------> Base::Class::Derived_C 205 | \\ \\ / 206 | '------ Base::Class 207 | / \\ \\ \\ 208 | ' \\ \\ \\ 209 | | \\ \\ \\ 210 | . \\ \\ '--- The::Latest 211 | /| \\ \\ \\ 212 | With::Some::fantasy ' \\ \\ '---- The::Latest::Greatest 213 | /| \\ \\ 214 | More::Stuff ' \\ '- I::Am::Running::Out::Of::Ideas 215 | /| \\ 216 | More::Stuff ' \\ 217 | / '--- Last::One 218 | More::Stuff 219 | 220 | Safety 221 | ^ 222 | | *Rust 223 | | *Java 224 | | *Python 225 | | *C++ 226 | +-----------------------------> Control 227 | 228 | 229 | 230 | 231 | 232 | TODO: 233 | 234 | 235 | 236 | | \\/ 237 | -+- /\\ 238 | | 239 | 240 | | | | | 241 | +-- --+ +-- --+ +-- --+ 242 | | | | | 243 | 244 | | | | | 245 | .- -. .- -. ._ _. 246 | | | 247 | 248 | .- -. .-. 249 | '- -' | | | | 250 | '-' 251 | 252 | \\ | / | 253 | . ' ' . 254 | | / | \\ 255 | 256 | \\ 257 | / 258 | 259 | / 260 | \\ 261 | 262 | 263 | / \\ 264 | '-- --' 265 | / \\ 266 | 267 | / \\ 268 | --' '-- 269 | / \\ 270 | 271 | \\ / 272 | --.-- --.-- --.-- --.-- 273 | / \\ 274 | 275 | 276 | | | 277 | . . 278 | /| |\\ 279 | 280 | | 281 | . 282 | / \\ 283 | 284 | \\|/ 285 | . 286 | /|\\ 287 | 288 | 289 | \\|/ 290 | --.-- 291 | /|\\ 292 | 293 | \\|/ 294 | --+-- 295 | /|\\ 296 | 297 | |/ \\| 298 | . . 299 | | | 300 | 301 | 302 | -. -. 303 | / \\ 304 | 305 | .- .- 306 | / \\ 307 | 308 | 309 | / / \\ \\ 310 | '- '_ _' -' 311 | 312 | 313 | .-. 314 | ( ) 315 | '-' 316 | 317 | .. 318 | ( ) 319 | '' 320 | 321 | 322 | .------. 323 | ( ) 324 | '------' 325 | 326 | ________ 327 | / / 328 | / / 329 | /_______/ 330 | 331 | 332 | ________ 333 | \\ \\ 334 | \\ \\ 335 | \\_______\\ 336 | 337 | ________ 338 | |________| 339 | 340 | 341 | ________ 342 | | | 343 | |________| 344 | 345 | .-. 346 | '-' 347 | 348 | ________ 349 | \\_______\\ 350 | 351 | /\\ 352 | / \\ 353 | /____\\ 354 | 355 | /\\ 356 | / \\ 357 | / \\ 358 | '------' 359 | 360 | ___ 361 | / \\ 362 | \\___/ 363 | 364 | ______ 365 | / \\ 366 | / \\ 367 | \\ / 368 | \\______/ 369 | 370 | 371 | +---------+ 372 | | | +--------------+ 373 | | NFS |--+ | | 374 | | | | +-->| CacheFS | 375 | +---------+ | +----------+ | | /dev/hda5 | 376 | | | | | +--------------+ 377 | +---------+ +-->| | | 378 | | | | |--+ 379 | | AFS |----->| FS-Cache | 380 | | | | |--+ 381 | +---------+ +-->| | | 382 | | | | | +--------------+ 383 | +---------+ | +----------+ | | | 384 | | | | +-->| CacheFiles | 385 | | ISOFS |--+ | /var/cache | 386 | | | +--------------+ 387 | +---------+ 388 | """ 389 | 390 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2016 Jovansonlee B. Cesar 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /elm-bot-lines/Grid.elm: -------------------------------------------------------------------------------- 1 | module Grid exposing (..) 2 | import String 3 | import Svg exposing (Svg,svg,path,line,marker,defs) 4 | import Svg.Attributes exposing ( 5 | x,y,x1,y1,x2,y2,height, 6 | width,d,markerHeight, 7 | markerWidth,orient,markerEnd, 8 | markerUnits,refX,refY,viewBox,id, 9 | stroke,strokeWidth,fill,strokeLinecap, 10 | strokeLinejoin 11 | ) 12 | import Char 13 | import Color 14 | import Array exposing (Array) 15 | 16 | type alias Model = 17 | {rows: Int 18 | ,columns: Int 19 | ,lines: Array (Array Char) 20 | } 21 | 22 | fontSize = 14.0 23 | lineWidth = 1.0 24 | textWidth = 8.0 25 | textHeight = 16.0 26 | arcRadius = textWidth / 2 27 | color = Color.rgb 0 0 0 28 | 29 | type Position 30 | = TopRightCorner 31 | | TopLeftCorner 32 | | BottomRightCorner 33 | | BottomLeftCorner 34 | | BottomLeftLowHorizontal 35 | | BottomRightLowHorizontal 36 | | BottomLeftSlantedTopLeft 37 | | BottomLeftSlantedTopRight 38 | | BottomLeftSlantedBottomRight 39 | | BottomLeftSlantedTopRightLowHorizontal 40 | | BottomRightSlantedTopRight 41 | | BottomRightSlantedTopLeftLowHorizontal 42 | | BottomRightSlantedTopLeft 43 | | BottomRightSlantedBottomLeft 44 | | TopLeftSlantedBottomLeft 45 | | TopLeftSlantedBottomRight 46 | | TopRightSlantedBottomRight 47 | | TopRightSlantedBottomLeft 48 | | TopRightSlantedTopLeft 49 | | SlantedRightJunctionRight 50 | | SlantedLeftJunctionLeft 51 | | SlantedRightJunctionLeft 52 | | SlantedLeftJunctionRight 53 | | VerticalTopDownJunctionBottomLeft 54 | | VerticalTopDownJunctionBottomRight 55 | | TopLeftSlantedTopRight 56 | | VerticalTopDownJunctionTopRight 57 | | VerticalTopDownJunctionTopLeft 58 | | TopLeftBigCurve 59 | | TopRightBigCurve 60 | | BottomLeftBigCurve 61 | | BottomRightBigCurve 62 | 63 | type Element 64 | = Intersection Type -- also corner 65 | | Horizontal 66 | | LowHorizontal 67 | | LowHorizontalExtendLeft 68 | | LowHorizontalExtendVerticalLeft 69 | | LowHorizontalExtendRight 70 | | LowHorizontalExtendVerticalRight 71 | | LowHorizontalExtendVerticalBottomLeft 72 | | LowHorizontalExtendVerticalBottomRight 73 | | Vertical 74 | | RoundCorner Position 75 | | ArrowEast 76 | | ArrowSouth 77 | | ArrowSouthWest 78 | | ArrowSouthEast 79 | | ArrowNorth 80 | | ArrowNorthWest 81 | | ArrowNorthEast 82 | | ArrowWest 83 | | SlantRight 84 | | SlantLeft 85 | | OpenCurve 86 | | CloseCurve 87 | | BigOpenCurve 88 | | BigCloseCurve 89 | | Text Char 90 | 91 | {-- intersection types 92 | --} 93 | type Type 94 | = Cross 95 | | HorJunctionTop 96 | | HorJunctionBot 97 | | VertJunctionLeft 98 | | VertJunctionRight 99 | | TopLeft 100 | | TopRight 101 | | BottomLeft 102 | | BottomRight 103 | 104 | vertical = ['|'] 105 | verticalDashed = [':'] 106 | horizontal = ['-'] 107 | horizontalDouble = ['='] 108 | lowHorizontal = ['_'] 109 | intersections = ['+'] 110 | roundCorners = ['.','\''] 111 | arrowRight = ['>'] 112 | arrowDown = ['V','v'] 113 | arrowLeft = ['<'] 114 | arrowUp = ['^','î'] 115 | slantRight = ['/'] 116 | slantLeft = ['\\'] 117 | openCurve = ['('] 118 | closeCurve = [')'] 119 | 120 | isOpenCurve char = 121 | List.member char openCurve 122 | 123 | --close parenthesis 124 | isCloseCurve char = 125 | List.member char closeCurve 126 | 127 | isVertical char = 128 | List.member char vertical 129 | 130 | isAlphaNumeric char = 131 | Char.isDigit char || Char.isUpper char || Char.isLower char 132 | 133 | isHorizontal char = 134 | List.member char horizontal 135 | 136 | isLowHorizontal char = 137 | List.member char lowHorizontal 138 | 139 | isIntersection char = 140 | List.member char intersections 141 | 142 | isLine char = 143 | isVertical char || isHorizontal char || isLowHorizontal char 144 | 145 | isRoundCorner char = 146 | List.member char roundCorners 147 | 148 | isArrowRight char = 149 | List.member char arrowRight 150 | 151 | isArrowLeft char = 152 | List.member char arrowLeft 153 | 154 | isArrowDown char = 155 | List.member char arrowDown 156 | 157 | isArrowUp char = 158 | List.member char arrowUp 159 | 160 | isSlantRight char = 161 | List.member char slantRight 162 | 163 | isSlantLeft char = 164 | List.member char slantLeft 165 | 166 | 167 | leftOf x y model = 168 | get (x-1) y model 169 | 170 | rightOf x y model = 171 | get (x+1) y model 172 | 173 | topOf x y model = 174 | get x (y-1) model 175 | 176 | bottomOf x y model = 177 | get x (y+1) model 178 | 179 | topLeftOf x y model = 180 | get (x-1) (y-1) model 181 | 182 | topRightOf x y model = 183 | get (x+1) (y-1) model 184 | 185 | bottomLeftOf x y model = 186 | get (x-1) (y+1) model 187 | 188 | bottomRightOf x y model = 189 | get (x+1) (y+1) model 190 | 191 | 192 | isNeighbor neighbor check = 193 | case neighbor of 194 | Just neighbor -> 195 | check neighbor 196 | Nothing -> 197 | False 198 | 199 | 200 | getElement: Int -> Int -> Model -> Maybe Element 201 | getElement x y model = 202 | let 203 | char = get x y model 204 | top = topOf x y model 205 | bottom = bottomOf x y model 206 | left = leftOf x y model 207 | right = rightOf x y model 208 | topLeft = topLeftOf x y model 209 | topRight = topRightOf x y model 210 | bottomLeft = bottomLeftOf x y model 211 | bottomRight = bottomRightOf x y model 212 | 213 | in 214 | case char of 215 | Just char -> 216 | if isVertical char 217 | && not (isNeighbor left isAlphaNumeric) 218 | && not (isNeighbor right isAlphaNumeric) then 219 | Just Vertical 220 | else if isHorizontal char 221 | && not (isNeighbor left isAlphaNumeric) 222 | && not (isNeighbor right isAlphaNumeric) then 223 | Just Horizontal 224 | else if isLowHorizontal char 225 | && isNeighbor left isSlantRight then 226 | Just LowHorizontalExtendLeft 227 | else if isLowHorizontal char 228 | && isNeighbor left isVertical then 229 | Just LowHorizontalExtendVerticalLeft 230 | else if isLowHorizontal char 231 | && isNeighbor right isSlantLeft then 232 | Just LowHorizontalExtendRight 233 | else if isLowHorizontal char 234 | && isNeighbor right isVertical then 235 | Just LowHorizontalExtendVerticalRight 236 | else if isLowHorizontal char 237 | && isNeighbor bottomLeft isVertical then 238 | Just LowHorizontalExtendVerticalBottomLeft 239 | else if isLowHorizontal char 240 | && isNeighbor bottomRight isVertical then 241 | Just LowHorizontalExtendVerticalBottomRight 242 | else if isLowHorizontal char 243 | && not (isNeighbor left isAlphaNumeric) 244 | && not (isNeighbor right isAlphaNumeric) then 245 | Just LowHorizontal 246 | else if isIntersection char then 247 | let 248 | isVerticalJunctionLeft = 249 | isNeighbor top isVertical 250 | && isNeighbor(bottomOf x y model) isVertical 251 | && isNeighbor(leftOf x y model) isHorizontal 252 | 253 | isVerticalJunctionRight = 254 | isNeighbor top isVertical 255 | && isNeighbor bottom isVertical 256 | && isNeighbor right isHorizontal 257 | 258 | isHorizontalJunctionTop = 259 | isNeighbor left isHorizontal 260 | && isNeighbor right isHorizontal 261 | && isNeighbor top isVertical 262 | 263 | isHorizontalJunctionBot = 264 | isNeighbor left isHorizontal 265 | && isNeighbor right isHorizontal 266 | && isNeighbor bottom isVertical 267 | 268 | isTopLeftIntersection = 269 | isNeighbor bottom isVertical && isNeighbor right isHorizontal 270 | 271 | isTopRightIntersection = 272 | isNeighbor bottom isVertical && isNeighbor left isHorizontal 273 | 274 | isBottomRightIntersection = 275 | isNeighbor top isVertical && isNeighbor left isHorizontal 276 | 277 | isBottomLeftIntersection = 278 | isNeighbor top isVertical && isNeighbor right isHorizontal 279 | 280 | isCrossIntersection = 281 | isNeighbor top isVertical 282 | && isNeighbor bottom isVertical 283 | && isNeighbor left isHorizontal 284 | && isNeighbor right isHorizontal 285 | 286 | in 287 | if isCrossIntersection then 288 | Just (Intersection Cross) 289 | else if isVerticalJunctionLeft then 290 | Just (Intersection VertJunctionLeft) 291 | else if isVerticalJunctionRight then 292 | Just (Intersection VertJunctionRight) 293 | else if isHorizontalJunctionTop then 294 | Just (Intersection HorJunctionTop) 295 | else if isHorizontalJunctionBot then 296 | Just (Intersection HorJunctionBot) 297 | else if isTopRightIntersection then 298 | Just (Intersection TopRight) 299 | else if isTopLeftIntersection then 300 | Just (Intersection TopLeft) 301 | else if isBottomRightIntersection then 302 | Just (Intersection BottomRight) 303 | else if isBottomLeftIntersection then 304 | Just (Intersection BottomLeft) 305 | else 306 | Nothing 307 | else if isRoundCorner char then 308 | if isNeighbor topRight isSlantRight 309 | && isNeighbor bottomLeft isSlantRight 310 | && isNeighbor right isHorizontal then 311 | Just (RoundCorner SlantedRightJunctionRight) 312 | else if isNeighbor top isVertical 313 | && isNeighbor bottom isVertical 314 | && isNeighbor topLeft isSlantLeft then 315 | Just (RoundCorner VerticalTopDownJunctionTopLeft) 316 | else if isNeighbor topLeft isSlantLeft 317 | && isNeighbor bottomRight isSlantLeft 318 | && isNeighbor left isHorizontal then 319 | Just (RoundCorner SlantedLeftJunctionLeft) 320 | else if isNeighbor topRight isSlantRight 321 | && isNeighbor bottomLeft isSlantRight 322 | && isNeighbor left isHorizontal then 323 | Just (RoundCorner SlantedRightJunctionLeft) 324 | else if isNeighbor topLeft isSlantLeft 325 | && isNeighbor bottomRight isSlantLeft 326 | && isNeighbor right isHorizontal then 327 | Just (RoundCorner SlantedLeftJunctionRight) 328 | else if isNeighbor top isVertical 329 | && isNeighbor bottom isVertical 330 | && isNeighbor bottomLeft isSlantRight then 331 | Just (RoundCorner VerticalTopDownJunctionBottomLeft) 332 | else if isNeighbor top isVertical 333 | && isNeighbor bottom isVertical 334 | && isNeighbor bottomRight isSlantLeft then 335 | Just (RoundCorner VerticalTopDownJunctionBottomRight) 336 | else if isNeighbor top isVertical 337 | && isNeighbor bottom isVertical 338 | && isNeighbor topRight isSlantRight then 339 | Just (RoundCorner VerticalTopDownJunctionTopRight) 340 | else if isNeighbor bottom isVertical 341 | && isNeighbor right isHorizontal then 342 | Just (RoundCorner TopLeftCorner) 343 | else if isNeighbor bottom isVertical 344 | && isNeighbor left isHorizontal then 345 | Just (RoundCorner TopRightCorner) 346 | else if isNeighbor bottom isVertical 347 | && isNeighbor topRight isSlantRight then 348 | Just (RoundCorner TopLeftSlantedTopRight) 349 | else if isNeighbor right isHorizontal 350 | && isNeighbor bottomLeft isOpenCurve then 351 | Just (RoundCorner TopLeftBigCurve) 352 | else if isNeighbor right isRoundCorner 353 | && isNeighbor bottomLeft isOpenCurve then 354 | Just (RoundCorner TopLeftBigCurve) 355 | else if isNeighbor left isHorizontal 356 | && isNeighbor bottomRight isCloseCurve then 357 | Just (RoundCorner TopRightBigCurve) 358 | else if isNeighbor left isRoundCorner 359 | && isNeighbor bottomRight isCloseCurve then 360 | Just (RoundCorner TopRightBigCurve) 361 | else if isNeighbor right isHorizontal 362 | && isNeighbor topLeft isOpenCurve then 363 | Just (RoundCorner BottomLeftBigCurve) 364 | else if isNeighbor left isHorizontal 365 | && isNeighbor topRight isCloseCurve then 366 | Just (RoundCorner BottomRightBigCurve) 367 | else if isNeighbor right isRoundCorner 368 | && isNeighbor topLeft isOpenCurve then 369 | Just (RoundCorner BottomLeftBigCurve) 370 | else if isNeighbor left isRoundCorner 371 | && isNeighbor topRight isCloseCurve then 372 | Just (RoundCorner BottomRightBigCurve) 373 | else if isNeighbor top isVertical 374 | && isNeighbor right isHorizontal then 375 | Just (RoundCorner BottomLeftCorner) 376 | else if isNeighbor top isVertical 377 | && isNeighbor right isLowHorizontal then 378 | Just (RoundCorner BottomLeftLowHorizontal) 379 | else if isNeighbor top isVertical 380 | && isNeighbor left isLowHorizontal then 381 | Just (RoundCorner BottomRightLowHorizontal) 382 | else if isNeighbor right isHorizontal 383 | && isNeighbor topLeft isSlantLeft then 384 | Just (RoundCorner BottomLeftSlantedTopLeft) 385 | else if isNeighbor right isHorizontal 386 | && isNeighbor topRight isSlantRight then 387 | Just (RoundCorner BottomLeftSlantedTopRight) 388 | else if isNeighbor top isVertical 389 | && isNeighbor bottomRight isSlantLeft then 390 | Just (RoundCorner BottomLeftSlantedBottomRight) 391 | else if isNeighbor left isHorizontal 392 | && isNeighbor topRight isSlantRight then 393 | Just (RoundCorner BottomRightSlantedTopRight) 394 | else if isNeighbor right isLowHorizontal 395 | && isNeighbor topRight isSlantRight then 396 | Just (RoundCorner BottomLeftSlantedTopRightLowHorizontal) 397 | else if isNeighbor left isLowHorizontal 398 | && isNeighbor topLeft isSlantLeft then 399 | Just (RoundCorner BottomRightSlantedTopLeftLowHorizontal) 400 | else if isNeighbor left isHorizontal 401 | && isNeighbor topLeft isSlantLeft then 402 | Just (RoundCorner BottomRightSlantedTopLeft) 403 | else if isNeighbor top isVertical 404 | && isNeighbor bottomLeft isSlantRight then 405 | Just (RoundCorner BottomRightSlantedBottomLeft) 406 | else if isNeighbor top isVertical 407 | && isNeighbor left isHorizontal then 408 | Just (RoundCorner BottomRightCorner) 409 | else if isNeighbor right isHorizontal 410 | && isNeighbor bottom isRoundCorner then 411 | Just (RoundCorner TopLeftCorner) 412 | else if isNeighbor left isHorizontal 413 | && isNeighbor bottom isRoundCorner then 414 | Just (RoundCorner TopRightCorner) 415 | else if isNeighbor left isHorizontal 416 | && isNeighbor top isRoundCorner then 417 | Just (RoundCorner BottomRightCorner) 418 | else if isNeighbor right isHorizontal 419 | && isNeighbor top isRoundCorner then 420 | Just (RoundCorner BottomLeftCorner) 421 | else if isNeighbor right isHorizontal 422 | && isNeighbor bottomLeft isSlantRight then 423 | Just (RoundCorner TopLeftSlantedBottomLeft) 424 | else if isNeighbor right isHorizontal 425 | && isNeighbor bottomRight isSlantLeft then 426 | Just (RoundCorner TopLeftSlantedBottomRight) 427 | else if isNeighbor left isHorizontal 428 | && isNeighbor bottomRight isSlantLeft then 429 | Just (RoundCorner TopRightSlantedBottomRight) 430 | else if isNeighbor left isHorizontal 431 | && isNeighbor bottomLeft isSlantRight then 432 | Just (RoundCorner TopRightSlantedBottomLeft) 433 | else if isNeighbor bottom isVertical 434 | && isNeighbor topLeft isSlantLeft then 435 | Just (RoundCorner TopRightSlantedTopLeft) 436 | else 437 | Just (Text char) 438 | else if isArrowRight char then 439 | Just ArrowEast 440 | else if isArrowDown char then 441 | if isNeighbor top isVertical then 442 | Just ArrowSouth 443 | else if isNeighbor topRight isSlantRight then 444 | Just ArrowSouthWest 445 | else if isNeighbor topLeft isSlantLeft then 446 | Just ArrowSouthEast 447 | else 448 | Just <| Text char 449 | 450 | else if isArrowLeft char then 451 | Just ArrowWest 452 | else if isArrowUp char then 453 | if isNeighbor bottom isVertical then 454 | Just ArrowNorth 455 | else if isNeighbor bottomLeft isSlantRight then 456 | Just ArrowNorthWest 457 | else if isNeighbor bottomRight isSlantLeft then 458 | Just ArrowNorthEast 459 | else 460 | Just <| Text char 461 | else if isSlantRight char then 462 | Just SlantRight 463 | else if isSlantLeft char then 464 | Just SlantLeft 465 | else if isOpenCurve char then 466 | if isNeighbor topRight isSlantRight 467 | && isNeighbor bottomRight isSlantLeft then 468 | Just OpenCurve 469 | else if isNeighbor topRight isRoundCorner 470 | && isNeighbor bottomRight isRoundCorner then 471 | Just BigOpenCurve 472 | else 473 | Just <| Text char 474 | else if isCloseCurve char 475 | && isNeighbor topLeft isRoundCorner 476 | && isNeighbor bottomLeft isRoundCorner then 477 | Just BigCloseCurve 478 | else if isCloseCurve char 479 | && isNeighbor topLeft isSlantLeft 480 | && isNeighbor bottomLeft isSlantRight then 481 | Just CloseCurve 482 | else if char /= ' ' then 483 | Just <| Text char 484 | else 485 | Nothing 486 | Nothing -> 487 | Nothing 488 | 489 | 490 | drawArc: Float -> Float -> Float -> Float -> Float -> Svg a 491 | drawArc startX startY endX endY radius = 492 | let 493 | rx = radius 494 | ry = radius 495 | paths = 496 | ["M", toString startX, toString startY 497 | ,"A", toString rx, toString ry, "0" ,"0", "0" 498 | ,toString endX, toString endY 499 | ] |> String.join " " 500 | in 501 | path [d paths, stroke "black", strokeWidth <| toString lineWidth, fill "transparent"] [] 502 | 503 | arrowMarker: Svg a 504 | arrowMarker = 505 | marker [id "triangle" 506 | ,viewBox "0 0 14 14" 507 | ,refX "0" 508 | ,refY "5" 509 | ,markerUnits "strokeWidth" 510 | ,markerWidth "10" 511 | ,markerHeight "10" 512 | ,orient "auto" 513 | ] 514 | [path [d "M 0 0 L 10 5 L 0 10 z"] 515 | [] 516 | ] 517 | 518 | getSvg model = 519 | let 520 | gwidth = toString <| (measureX model.columns) + 10 521 | gheight = toString <| (measureY model.rows) + 10 522 | in 523 | svg [height gheight, width gwidth] 524 | (defs [] 525 | [arrowMarker] 526 | ::drawPaths model 527 | ) 528 | 529 | --TODO: optimize here to indexedMap only the lines and chars 530 | --TODO: modularized parts in order to easily fit and match 531 | drawPaths: Model -> List (Svg a) 532 | drawPaths model = 533 | Array.indexedMap 534 | (\r line -> 535 | Array.indexedMap 536 | (\ c char-> 537 | drawElement c r model 538 | ) line 539 | |> Array.toList 540 | ) model.lines 541 | |> Array.toList 542 | |> List.concat 543 | |> List.concat 544 | 545 | drawElement: Int -> Int -> Model -> List (Svg a) 546 | drawElement x y model = 547 | let 548 | element = 549 | getElement x y model 550 | in 551 | case element of 552 | Just element -> 553 | case element of 554 | Horizontal -> 555 | [drawHorizontalLine x y model] 556 | 557 | LowHorizontal -> 558 | [drawLowHorizontalLine x y model] 559 | 560 | LowHorizontalExtendLeft -> 561 | [drawLowHorizontalExtendLeft x y model] 562 | 563 | LowHorizontalExtendVerticalLeft -> 564 | [drawLowHorizontalExtendVerticalLeft x y model] 565 | 566 | LowHorizontalExtendRight -> 567 | [drawLowHorizontalExtendRight x y model] 568 | 569 | LowHorizontalExtendVerticalRight -> 570 | [drawLowHorizontalExtendVerticalRight x y model] 571 | 572 | LowHorizontalExtendVerticalBottomLeft -> 573 | [drawLowHorizontalExtendVerticalBottomLeft x y model] 574 | 575 | LowHorizontalExtendVerticalBottomRight -> 576 | [drawLowHorizontalExtendVerticalBottomRight x y model] 577 | 578 | Vertical -> 579 | [drawVerticalLine x y model] 580 | 581 | Intersection itype-> 582 | (drawIntersection x y itype model) 583 | 584 | RoundCorner pos -> 585 | (drawRoundCorner x y pos model) 586 | 587 | ArrowEast -> 588 | [drawArrowRight x y model] 589 | 590 | ArrowSouth -> 591 | [drawArrowDown x y model] 592 | 593 | ArrowSouthWest -> 594 | [drawArrowSouthWest x y model] 595 | 596 | ArrowSouthEast -> 597 | [drawArrowSouthEast x y model] 598 | 599 | ArrowNorth -> 600 | [drawArrowUp x y model] 601 | 602 | ArrowNorthWest -> 603 | [drawArrowNorthWest x y model] 604 | 605 | ArrowNorthEast -> 606 | [drawArrowNorthEast x y model] 607 | 608 | ArrowWest -> 609 | [drawArrowLeft x y model] 610 | 611 | SlantRight -> 612 | [drawSlantRightLine x y model] 613 | 614 | SlantLeft -> 615 | [drawSlantLeftLine x y model] 616 | 617 | OpenCurve -> 618 | drawOpenCurve x y model 619 | 620 | CloseCurve -> 621 | drawCloseCurve x y model 622 | 623 | BigOpenCurve -> 624 | drawBigOpenCurve x y model 625 | 626 | BigCloseCurve -> 627 | drawBigCloseCurve x y model 628 | 629 | Text char -> 630 | [drawText x y char] 631 | 632 | Nothing -> 633 | [] 634 | 635 | drawHorizontalLine: Int -> Int -> Model -> Svg a 636 | drawHorizontalLine x y model = 637 | let 638 | startX = measureX x 639 | endX = startX + textWidth 640 | startY = measureY y + textHeight / 2 641 | endY = startY 642 | in 643 | drawLine startX startY endX endY color 644 | 645 | 646 | drawLowHorizontalLine: Int -> Int -> Model -> Svg a 647 | drawLowHorizontalLine x y model = 648 | let 649 | startX = measureX x 650 | endX = startX + textWidth 651 | startY = measureY y + textHeight 652 | endY = startY 653 | in 654 | drawLine startX startY endX endY color 655 | 656 | drawLowHorizontalExtendLeft: Int -> Int -> Model -> Svg a 657 | drawLowHorizontalExtendLeft x y model = 658 | let 659 | startX = measureX x - textWidth 660 | endX = measureX x + textWidth 661 | startY = measureY y + textHeight 662 | endY = startY 663 | in 664 | drawLine startX startY endX endY color 665 | 666 | drawLowHorizontalExtendVerticalLeft: Int -> Int -> Model -> Svg a 667 | drawLowHorizontalExtendVerticalLeft x y model = 668 | let 669 | startX = measureX x - textWidth / 2 670 | endX = measureX x + textWidth 671 | startY = measureY y + textHeight 672 | endY = startY 673 | in 674 | drawLine startX startY endX endY color 675 | 676 | drawLowHorizontalExtendVerticalBottomLeft: Int -> Int -> Model -> Svg a 677 | drawLowHorizontalExtendVerticalBottomLeft x y model = 678 | let 679 | startX = measureX x - textWidth / 2 680 | endX = measureX x + textWidth 681 | startY = measureY y + textHeight 682 | endY = startY 683 | in 684 | drawLine startX startY endX endY color 685 | 686 | drawLowHorizontalExtendVerticalBottomRight: Int -> Int -> Model -> Svg a 687 | drawLowHorizontalExtendVerticalBottomRight x y model = 688 | let 689 | startX = measureX x 690 | endX = measureX x + textWidth + textWidth / 2 691 | startY = measureY y + textHeight 692 | endY = startY 693 | in 694 | drawLine startX startY endX endY color 695 | 696 | drawLowHorizontalExtendRight: Int -> Int -> Model -> Svg a 697 | drawLowHorizontalExtendRight x y model = 698 | let 699 | startX = measureX x 700 | endX = measureX x + textWidth * 2 701 | startY = measureY y + textHeight 702 | endY = startY 703 | in 704 | drawLine startX startY endX endY color 705 | 706 | drawLowHorizontalExtendVerticalRight: Int -> Int -> Model -> Svg a 707 | drawLowHorizontalExtendVerticalRight x y model = 708 | let 709 | startX = measureX x 710 | endX = measureX x + textWidth + textWidth / 2 711 | startY = measureY y + textHeight 712 | endY = startY 713 | in 714 | drawLine startX startY endX endY color 715 | 716 | drawVerticalLine: Int -> Int -> Model -> Svg a 717 | drawVerticalLine x y model = 718 | let 719 | startX = measureX x + textWidth / 2 720 | endX = startX 721 | startY = measureY y 722 | endY = startY + textHeight 723 | in 724 | drawLine startX startY endX endY color 725 | 726 | 727 | drawSlantRightLine: Int -> Int -> Model -> Svg a 728 | drawSlantRightLine x y model = 729 | let 730 | startX = measureX x 731 | endX = startX + textWidth 732 | startY = measureY y + textHeight 733 | endY = measureY y 734 | in 735 | drawLine startX startY endX endY color 736 | 737 | 738 | drawSlantLeftLine: Int -> Int -> Model -> Svg a 739 | drawSlantLeftLine x y model = 740 | let 741 | startX = measureX x 742 | endX = startX + textWidth 743 | startY = measureY y 744 | endY = measureY y + textHeight 745 | in 746 | drawLine startX startY endX endY color 747 | 748 | drawOpenCurve: Int -> Int -> Model -> List (Svg a) 749 | drawOpenCurve x y model = 750 | let 751 | startX = measureX x + textWidth 752 | startY = measureY y 753 | endX = measureX x + textWidth 754 | endY = measureY y + textHeight 755 | in 756 | [drawArc startX startY endX endY (arcRadius * 4) 757 | ] 758 | 759 | drawBigOpenCurve: Int -> Int -> Model -> List (Svg a) 760 | drawBigOpenCurve x y model = 761 | let 762 | startX = measureX x + textWidth / 2 763 | startY = measureY y 764 | endX = measureX x + textWidth / 2 765 | endY = measureY y + textHeight 766 | in 767 | [drawArc startX startY endX endY (arcRadius * 4) 768 | ] 769 | 770 | drawBigCloseCurve: Int -> Int -> Model -> List (Svg a) 771 | drawBigCloseCurve x y model = 772 | let 773 | startX = measureX x + textWidth / 2 774 | startY = measureY y + textHeight 775 | endX = measureX x + textWidth / 2 776 | endY = measureY y 777 | in 778 | [drawArc startX startY endX endY (arcRadius * 4) 779 | ] 780 | 781 | drawCloseCurve: Int -> Int -> Model -> List (Svg a) 782 | drawCloseCurve x y model = 783 | let 784 | startX = measureX x 785 | startY = measureY y + textHeight 786 | endX = measureX x 787 | endY = measureY y 788 | radius = textHeight 789 | in 790 | [drawArc startX startY endX endY radius 791 | ] 792 | 793 | drawRoundCorner: Int -> Int -> Position -> Model -> List (Svg a) 794 | drawRoundCorner x y pos model = 795 | case pos of 796 | TopLeftCorner -> 797 | drawRoundTopLeftCorner x y 798 | TopRightCorner -> 799 | drawRoundTopRightCorner x y 800 | BottomLeftCorner -> 801 | drawRoundBottomLeftCorner x y 802 | BottomRightCorner -> 803 | drawRoundBottomRightCorner x y 804 | TopLeftSlantedBottomLeft -> 805 | drawRoundTopLeftSlantedBottomLeftCorner x y 806 | TopLeftSlantedBottomRight -> 807 | drawRoundTopLeftSlantedBottomRightCorner x y 808 | TopRightSlantedBottomRight -> 809 | drawRoundTopRightSlantedBottomRight x y 810 | TopRightSlantedBottomLeft -> 811 | drawRoundTopRightSlantedBottomLeft x y 812 | TopRightSlantedTopLeft -> 813 | drawRoundTopRightSlantedTopLeft x y 814 | VerticalTopDownJunctionTopLeft -> 815 | drawVerticalTopDownJunctionTopLeft x y 816 | SlantedRightJunctionRight -> 817 | drawRoundSlantedRightJunctionRight x y 818 | SlantedLeftJunctionLeft -> 819 | drawRoundSlantedLeftJunctionLeft x y 820 | SlantedRightJunctionLeft -> 821 | drawRoundSlantedRightJunctionLeft x y 822 | SlantedLeftJunctionRight -> 823 | drawRoundSlantedLeftJunctionRight x y 824 | BottomLeftLowHorizontal -> 825 | drawRoundBottomLeftLowHorizontalCorner x y 826 | BottomRightLowHorizontal -> 827 | drawRoundBottomRightLowHorizontalCorner x y 828 | BottomLeftSlantedTopLeft -> 829 | drawRoundBottomLeftSlantedTopLeftCorner x y 830 | BottomLeftSlantedTopRight -> 831 | drawRoundBottomLeftSlantedTopRightCorner x y 832 | BottomLeftSlantedBottomRight -> 833 | drawRoundBottomLeftSlantedBottomRightCorner x y 834 | BottomLeftSlantedTopRightLowHorizontal -> 835 | drawRoundBottomLeftSlantedTopRightLowHorizontal x y 836 | BottomRightSlantedTopRight -> 837 | drawRoundBottomRightSlantedTopRightCorner x y 838 | BottomRightSlantedTopLeftLowHorizontal -> 839 | drawRoundBottomRightSlantedTopLeftLowHorizontal x y 840 | BottomRightSlantedTopLeft -> 841 | drawRoundBottomRightSlantedTopLeftCorner x y 842 | BottomRightSlantedBottomLeft -> 843 | drawRoundBottomRightSlantedBottomLeft x y 844 | VerticalTopDownJunctionBottomLeft -> 845 | drawVerticalTopDownJunctionBottomLeft x y 846 | VerticalTopDownJunctionBottomRight -> 847 | drawVerticalTopDownJunctionBottomRight x y 848 | TopLeftSlantedTopRight -> 849 | drawRoundTopLeftSlantedTopRightCorner x y 850 | VerticalTopDownJunctionTopRight -> 851 | drawVerticalTopDownJunctionTopRight x y 852 | TopLeftBigCurve -> 853 | drawTopLeftBigCurve x y 854 | TopRightBigCurve -> 855 | drawTopRightBigCurve x y 856 | BottomLeftBigCurve -> 857 | drawBottomLeftBigCurve x y 858 | BottomRightBigCurve -> 859 | drawBottomRightBigCurve x y 860 | 861 | drawRoundTopLeftCorner x y = 862 | let 863 | startX = measureX x + textWidth 864 | startY = measureY y + textHeight / 2 865 | endX = measureX x + textWidth / 2 --circular arc 866 | endY = measureY y + textHeight / 2 + textWidth / 2 --then the rest is line 867 | in 868 | [drawArc startX startY endX endY arcRadius 869 | ,drawLine endX endY endX (measureY y + textHeight) color 870 | ] 871 | 872 | drawTopLeftBigCurve x y = 873 | let 874 | startX = measureX x + textWidth 875 | startY = measureY y + textHeight / 2 876 | endX = measureX x - textWidth / 2 877 | endY = measureY y + textHeight 878 | in 879 | [drawArc startX startY endX endY (arcRadius * 4)] 880 | 881 | drawBottomLeftBigCurve x y = 882 | let 883 | startX = measureX x - textWidth / 2 884 | startY = measureY y 885 | endX = measureX x + textWidth 886 | endY = measureY y + textHeight / 2 887 | in 888 | [drawArc startX startY endX endY (arcRadius * 4)] 889 | 890 | drawBottomRightBigCurve x y = 891 | let 892 | startX = measureX x 893 | startY = measureY y + textHeight / 2 894 | endX = measureX x + textWidth + textWidth / 2 895 | endY = measureY y 896 | in 897 | [drawArc startX startY endX endY (arcRadius * 4)] 898 | 899 | 900 | drawTopRightBigCurve x y = 901 | let 902 | startX = measureX x + textWidth + textWidth / 2 903 | startY = measureY y + textHeight 904 | endX = measureX x 905 | endY = measureY y + textHeight / 2 906 | in 907 | [drawArc startX startY endX endY (arcRadius * 4)] 908 | 909 | drawRoundTopLeftSlantedTopRightCorner x y = 910 | let 911 | lstartX = measureX x + textWidth 912 | lstartY = measureY y 913 | lendX = measureX x + textWidth * 3 / 4 914 | lendY = measureY y + textHeight * 1 / 4 915 | l2startX = measureX x + textWidth / 2 916 | l2startY = measureY y + textHeight 917 | l2endX = measureX x + textWidth / 2 918 | l2endY = measureY y + textHeight * 3 / 4 919 | in 920 | [drawArc lendX lendY l2endX l2endY (arcRadius * 4) 921 | ,drawLine lstartX lstartY lendX lendY color 922 | ,drawLine l2startX l2startY l2endX l2endY color 923 | ] 924 | 925 | 926 | drawVerticalTopDownJunctionTopRight x y = 927 | let 928 | lstartX = measureX x + textWidth 929 | lstartY = measureY y 930 | lendX = measureX x + textWidth * 3 / 4 931 | lendY = measureY y + textHeight * 1 / 4 932 | l2startX = measureX x + textWidth / 2 933 | l2startY = measureY y + textHeight 934 | l2endX = measureX x + textWidth / 2 935 | l2endY = measureY y + textHeight * 3 / 4 936 | l3startX = measureX x + textWidth / 2 937 | l3startY = measureY y 938 | l3endX = measureX x + textWidth / 2 939 | l3endY = measureY y + textHeight 940 | in 941 | [drawArc lendX lendY l2endX l2endY (arcRadius * 4) 942 | ,drawLine lstartX lstartY lendX lendY color 943 | ,drawLine l2startX l2startY l2endX l2endY color 944 | ,drawLine l3startX l3startY l3endX l3endY color 945 | ] 946 | 947 | drawRoundTopRightSlantedBottomRight x y = 948 | let 949 | startX = measureX x 950 | startY = measureY y + textHeight / 2 951 | lstartX = measureX x + textWidth 952 | lstartY = measureY y + textHeight 953 | lendX = measureX x + textWidth * 3 /4 954 | lendY = measureY y + textHeight * 3 /4 955 | in 956 | [drawArc lendX lendY startX startY (arcRadius * 2) 957 | ,drawLine lstartX lstartY lendX lendY color 958 | ] 959 | 960 | drawRoundTopRightSlantedBottomLeft x y = 961 | let 962 | startX = measureX x 963 | startY = measureY y + textHeight / 2 964 | lstartX = measureX x 965 | lstartY = measureY y + textHeight 966 | lendX = measureX x + textWidth * 1 / 4 967 | lendY = measureY y + textHeight * 3 / 4 968 | in 969 | [drawArc lendX lendY startX startY (arcRadius * 3 / 4) 970 | ,drawLine lstartX lstartY lendX lendY color 971 | ] 972 | 973 | drawRoundTopRightSlantedTopLeft x y = 974 | let 975 | lstartX = measureX x + textWidth / 2 976 | lstartY = measureY y + textHeight 977 | lendX = measureX x + textWidth / 2 978 | lendY = measureY y + textHeight * 3 / 4 979 | l2startX = measureX x 980 | l2startY = measureY y 981 | l2endX = measureX x + textWidth * 1 /4 982 | l2endY = measureY y + textHeight * 1 /4 983 | in 984 | [drawArc lendX lendY l2endX l2endY (arcRadius * 4) 985 | ,drawLine lstartX lstartY lendX lendY color 986 | ,drawLine l2startX l2startY l2endX l2endY color 987 | ] 988 | 989 | drawVerticalTopDownJunctionTopLeft x y = 990 | let 991 | lstartX = measureX x + textWidth / 2 992 | lstartY = measureY y + textHeight 993 | lendX = measureX x + textWidth / 2 994 | lendY = measureY y + textHeight * 3 / 4 995 | l2startX = measureX x 996 | l2startY = measureY y 997 | l2endX = measureX x + textWidth * 1 /4 998 | l2endY = measureY y + textHeight * 1 /4 999 | l3startX = measureX x + textWidth / 2 1000 | l3startY = measureY y 1001 | l3endX = measureX x + textWidth / 2 1002 | l3endY = measureY y + textHeight 1003 | in 1004 | [drawArc lendX lendY l2endX l2endY (arcRadius * 4) 1005 | ,drawLine lstartX lstartY lendX lendY color 1006 | ,drawLine l2startX l2startY l2endX l2endY color 1007 | ,drawLine l3startX l3startY l3endX l3endY color 1008 | ] 1009 | 1010 | drawRoundTopLeftSlantedBottomLeftCorner x y = 1011 | let 1012 | startX = measureX x + textWidth 1013 | startY = measureY y + textHeight / 2 1014 | lstartX = measureX x 1015 | lstartY = measureY y + textHeight 1016 | lendX = measureX x + textWidth * 1 /4 1017 | lendY = measureY y + textHeight * 3 /4 1018 | in 1019 | [drawArc startX startY lendX lendY (arcRadius * 2) 1020 | ,drawLine lstartX lstartY lendX lendY color 1021 | ] 1022 | 1023 | drawRoundTopLeftSlantedBottomRightCorner x y = 1024 | let 1025 | startX = measureX x + textWidth 1026 | startY = measureY y + textHeight / 2 1027 | lstartX = measureX x + textWidth 1028 | lstartY = measureY y + textHeight 1029 | lendX = measureX x + textWidth * 3 /4 1030 | lendY = measureY y + textHeight * 3 /4 1031 | in 1032 | [drawArc startX startY lendX lendY (arcRadius * 3 / 4) 1033 | ,drawLine lstartX lstartY lendX lendY color 1034 | ] 1035 | 1036 | drawRoundBottomLeftSlantedTopLeftCorner x y = 1037 | let 1038 | startX = measureX x + textWidth 1039 | startY = measureY y + textHeight / 2 1040 | lstartX = measureX x 1041 | lstartY = measureY y 1042 | lendX = measureX x + textWidth * 1 /4 1043 | lendY = measureY y + textHeight * 1 /4 1044 | in 1045 | [drawArc lendX lendY startX startY (arcRadius * 2) 1046 | ,drawLine lstartX lstartY lendX lendY color 1047 | ] 1048 | 1049 | drawRoundBottomLeftSlantedTopRightCorner x y = 1050 | let 1051 | startX = measureX x + textWidth 1052 | startY = measureY y + textHeight / 2 1053 | lstartX = measureX x + textWidth 1054 | lstartY = measureY y 1055 | lendX = measureX x + textWidth * 3 /4 1056 | lendY = measureY y + textHeight * 1 /4 1057 | in 1058 | [drawArc lendX lendY startX startY (arcRadius * 3 / 4) 1059 | ,drawLine lstartX lstartY lendX lendY color 1060 | ] 1061 | 1062 | drawRoundBottomLeftSlantedBottomRightCorner x y = 1063 | let 1064 | lstartX = measureX x + textWidth / 2 1065 | lstartY = measureY y 1066 | lendX = measureX x + textWidth / 2 1067 | lendY = measureY y + textHeight * 1 /4 1068 | l2startX = measureX x + textWidth 1069 | l2startY = measureY y + textHeight 1070 | l2endX = measureX x + textWidth * 3 / 4 1071 | l2endY = measureY y + textHeight * 3 / 4 1072 | in 1073 | [drawArc lendX lendY l2endX l2endY (arcRadius * 4) 1074 | ,drawLine lstartX lstartY lendX lendY color 1075 | ,drawLine l2startX l2startY l2endX l2endY color 1076 | ] 1077 | 1078 | drawRoundBottomLeftSlantedTopRightLowHorizontal x y = 1079 | let 1080 | startX = measureX x + textWidth 1081 | startY = measureY y + textHeight 1082 | lstartX = measureX x + textWidth 1083 | lstartY = measureY y 1084 | lendX = measureX x + textWidth / 2 1085 | lendY = measureY y + textHeight / 2 1086 | in 1087 | [drawArc lendX lendY startX startY (arcRadius * 1.5) 1088 | ,drawLine lstartX lstartY lendX lendY color 1089 | ] 1090 | 1091 | drawRoundBottomRightSlantedTopLeftLowHorizontal x y = 1092 | let 1093 | startX = measureX x 1094 | startY = measureY y + textHeight 1095 | lstartX = measureX x 1096 | lstartY = measureY y 1097 | lendX = measureX x + textWidth / 2 1098 | lendY = measureY y + textHeight / 2 1099 | in 1100 | [drawArc startX startY lendX lendY (arcRadius * 1.5) 1101 | ,drawLine lstartX lstartY lendX lendY color 1102 | ] 1103 | 1104 | drawRoundSlantedRightJunctionRight x y = 1105 | let 1106 | startX = measureX x + textWidth 1107 | startY = measureY y + textHeight / 2 1108 | endX = measureX x + textWidth * 1 /4 1109 | endY = measureY y + textHeight * 3 /4 1110 | lstartX = measureX x + textWidth 1111 | lstartY = measureY y 1112 | lendX = measureX x 1113 | lendY = measureY y + textHeight 1114 | in 1115 | [drawArc startX startY endX endY (arcRadius * 2) 1116 | ,drawLine lstartX lstartY lendX lendY color 1117 | ] 1118 | 1119 | 1120 | drawRoundSlantedRightJunctionLeft x y = 1121 | let 1122 | startX = measureX x 1123 | startY = measureY y + textHeight / 2 1124 | endX = measureX x + textWidth * 3 / 4 1125 | endY = measureY y + textHeight * 1 / 4 1126 | lstartX = measureX x + textWidth 1127 | lstartY = measureY y 1128 | lendX = measureX x 1129 | lendY = measureY y + textHeight 1130 | in 1131 | [drawArc startX startY endX endY (arcRadius * 2) 1132 | ,drawLine lstartX lstartY lendX lendY color 1133 | ] 1134 | 1135 | drawRoundSlantedLeftJunctionLeft x y = 1136 | let 1137 | startX = measureX x + textWidth * 3 / 4 1138 | startY = measureY y + textHeight * 3 / 4 1139 | endX = measureX x 1140 | endY = measureY y + textHeight / 2 1141 | lstartX = measureX x 1142 | lstartY = measureY y 1143 | lendX = measureX x + textWidth 1144 | lendY = measureY y + textHeight 1145 | in 1146 | [drawArc startX startY endX endY (arcRadius * 2) 1147 | ,drawLine lstartX lstartY lendX lendY color 1148 | ] 1149 | 1150 | drawRoundSlantedLeftJunctionRight x y = 1151 | let 1152 | startX = measureX x + textWidth * 1 /4 1153 | startY = measureY y + textHeight * 1 / 4 1154 | endX = measureX x + textWidth 1155 | endY = measureY y + textHeight / 2 1156 | lstartX = measureX x 1157 | lstartY = measureY y 1158 | lendX = measureX x + textWidth 1159 | lendY = measureY y + textHeight 1160 | in 1161 | [drawArc startX startY endX endY (arcRadius * 2) 1162 | ,drawLine lstartX lstartY lendX lendY color 1163 | ] 1164 | 1165 | drawRoundBottomRightSlantedTopRightCorner x y = 1166 | let 1167 | startX = measureX x 1168 | startY = measureY y + textHeight / 2 1169 | lstartX = measureX x + textWidth 1170 | lstartY = measureY y 1171 | lendX = measureX x + textWidth * 3 /4 1172 | lendY = measureY y + textHeight * 1 /4 1173 | in 1174 | [drawArc startX startY lendX lendY (arcRadius * 2) 1175 | ,drawLine lstartX lstartY lendX lendY color 1176 | ] 1177 | 1178 | drawRoundBottomRightSlantedTopLeftCorner x y = 1179 | let 1180 | startX = measureX x 1181 | startY = measureY y + textHeight / 2 1182 | lstartX = measureX x 1183 | lstartY = measureY y 1184 | lendX = measureX x + textWidth * 1 / 4 1185 | lendY = measureY y + textHeight * 1 / 4 1186 | in 1187 | [drawArc startX startY lendX lendY (arcRadius * 3 / 4) 1188 | ,drawLine lstartX lstartY lendX lendY color 1189 | ] 1190 | 1191 | drawRoundBottomRightSlantedBottomLeft x y = 1192 | let 1193 | lstartX = measureX x + textWidth / 2 1194 | lstartY = measureY y 1195 | lendX = measureX x + textWidth / 2 1196 | lendY = measureY y + textHeight * 1 / 4 1197 | l2startX = measureX x 1198 | l2startY = measureY y + textHeight 1199 | l2endX = measureX x + textWidth * 1 / 4 1200 | l2endY = measureY y + textHeight * 3 / 4 1201 | in 1202 | [drawArc l2endX l2endY lendX lendY (arcRadius * 4) 1203 | ,drawLine lstartX lstartY lendX lendY color 1204 | ,drawLine l2startX l2startY l2endX l2endY color 1205 | ] 1206 | 1207 | drawVerticalTopDownJunctionBottomLeft x y = 1208 | 1209 | let 1210 | lstartX = measureX x + textWidth / 2 1211 | lstartY = measureY y 1212 | lendX = measureX x + textWidth / 2 1213 | lendY = measureY y + textHeight * 1 / 4 1214 | l2startX = measureX x 1215 | l2startY = measureY y + textHeight 1216 | l2endX = measureX x + textWidth * 1 / 4 1217 | l2endY = measureY y + textHeight * 3 / 4 1218 | l3startX = measureX x + textWidth / 2 1219 | l3startY = measureY y 1220 | l3endX = measureX x + textWidth / 2 1221 | l3endY = measureY y + textHeight 1222 | in 1223 | [drawArc l2endX l2endY lendX lendY (arcRadius * 4) 1224 | ,drawLine lstartX lstartY lendX lendY color 1225 | ,drawLine l2startX l2startY l2endX l2endY color 1226 | ,drawLine l3startX l3startY l3endX l3endY color 1227 | ] 1228 | 1229 | drawVerticalTopDownJunctionBottomRight x y = 1230 | let 1231 | lstartX = measureX x + textWidth / 2 1232 | lstartY = measureY y 1233 | lendX = measureX x + textWidth / 2 1234 | lendY = measureY y + textHeight * 1 /4 1235 | l2startX = measureX x + textWidth 1236 | l2startY = measureY y + textHeight 1237 | l2endX = measureX x + textWidth * 3 / 4 1238 | l2endY = measureY y + textHeight * 3 / 4 1239 | l3startX = measureX x + textWidth / 2 1240 | l3startY = measureY y 1241 | l3endX = measureX x + textWidth / 2 1242 | l3endY = measureY y + textHeight 1243 | in 1244 | [drawArc lendX lendY l2endX l2endY (arcRadius * 4) 1245 | ,drawLine lstartX lstartY lendX lendY color 1246 | ,drawLine l2startX l2startY l2endX l2endY color 1247 | ,drawLine l3startX l3startY l3endX l3endY color 1248 | ] 1249 | 1250 | drawRoundBottomLeftCorner x y = 1251 | let 1252 | startX = measureX x + textWidth / 2 1253 | startY = measureY y + textHeight/2 - textWidth / 2 1254 | endX = measureX x + textWidth 1255 | endY = measureY y + textHeight / 2 1256 | in 1257 | [drawArc startX startY endX endY arcRadius 1258 | ,drawLine startX startY startX (measureY y) color 1259 | ] 1260 | 1261 | drawRoundBottomLeftLowHorizontalCorner x y = 1262 | let 1263 | startX = measureX x + textWidth / 2 1264 | startY = measureY y + textHeight - textWidth / 2 1265 | endX = measureX x + textWidth 1266 | endY = measureY y + textHeight 1267 | in 1268 | [drawArc startX startY endX endY arcRadius 1269 | ,drawLine startX startY startX (measureY y) color 1270 | ] 1271 | 1272 | 1273 | drawRoundBottomRightLowHorizontalCorner x y = 1274 | let 1275 | startX = measureX x 1276 | startY = measureY y + textHeight 1277 | endX = measureX x + textWidth / 2 1278 | endY = measureY y + textHeight - textWidth / 2 1279 | in 1280 | [drawArc startX startY endX endY arcRadius 1281 | ,drawLine endX endY endX (measureY y) color 1282 | ] 1283 | 1284 | drawRoundTopRightCorner x y = 1285 | let 1286 | startX = measureX x + textWidth / 2 1287 | startY = measureY y + textWidth / 2 + textHeight / 2 1288 | endX = measureX x 1289 | endY = measureY y + textHeight / 2 1290 | in 1291 | [drawArc startX startY endX endY arcRadius 1292 | ,drawLine startX startY startX (measureY y + textHeight) color 1293 | ] 1294 | 1295 | drawRoundBottomRightCorner x y = 1296 | let 1297 | startX = measureX x 1298 | startY = measureY y + textHeight / 2 1299 | endX = measureX x + textWidth / 2 1300 | endY = measureY y + textHeight / 2 - textWidth / 2 1301 | in 1302 | [drawArc startX startY endX endY arcRadius 1303 | ,drawLine endX endY endX (measureY y) color 1304 | ] 1305 | 1306 | 1307 | drawIntersection: Int -> Int -> Type -> Model -> List (Svg a) 1308 | drawIntersection x y itype model = 1309 | let 1310 | --vertical line 1311 | v1startX = measureX x + textWidth / 2 1312 | v1endX = v1startX 1313 | v1startY = measureY y 1314 | v1endY = measureY y + textHeight / 2 1315 | 1316 | -- v line part 2 1317 | v2startX = measureX x + textWidth / 2 1318 | v2endX = v2startX 1319 | v2startY = measureY y + textHeight / 2 1320 | v2endY = measureY y + textHeight 1321 | 1322 | --horizontal line 1323 | h1startX = measureX x 1324 | h1endX = measureX x + textWidth / 2 1325 | h1startY = measureY y + textHeight / 2 1326 | h1endY = h1startY 1327 | 1328 | --h line part 2 1329 | h2startX = measureX x + textWidth / 2 1330 | h2endX = h2startX + textWidth 1331 | h2startY = measureY y + textHeight / 2 1332 | h2endY = h2startY 1333 | 1334 | v1Line = drawLine v1startX v1startY v1endX v1endY color 1335 | v2Line = drawLine v2startX v2startY v2endX v2endY color 1336 | h1Line = drawLine h1startX h1startY h1endX h1endY color 1337 | h2Line = drawLine h2startX h2startY h2endX h2endY color 1338 | 1339 | in 1340 | case itype of 1341 | VertJunctionLeft -> 1342 | [v1Line, v2Line, h1Line] 1343 | VertJunctionRight -> 1344 | [v1Line, v2Line, h2Line] 1345 | HorJunctionTop -> 1346 | [h1Line, h2Line, v1Line] 1347 | HorJunctionBot -> 1348 | [h1Line, h2Line, v2Line] 1349 | TopLeft -> 1350 | [h2Line, v2Line] 1351 | TopRight -> 1352 | [h1Line, v2Line] 1353 | BottomLeft -> 1354 | [v1Line, h2Line] 1355 | BottomRight -> 1356 | [v1Line, h1Line] 1357 | Cross -> 1358 | [v1Line, v2Line, h1Line, h2Line] 1359 | 1360 | 1361 | drawArrowRight x y model = 1362 | let 1363 | startX = measureX x 1364 | endX = startX + textWidth / 2 1365 | startY = measureY y + textHeight / 2 1366 | endY = startY 1367 | {red,green,blue,alpha} = Color.toRgb color 1368 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1369 | in 1370 | line 1371 | [x1 <| toString startX 1372 | ,x2 <| toString endX 1373 | ,y1 <| toString startY 1374 | ,y2 <| toString endY 1375 | ,Svg.Attributes.style ("stroke: "++colorText++";stroke-width:"++toString lineWidth) 1376 | ,markerEnd "url(#triangle)" 1377 | ] 1378 | [] 1379 | 1380 | 1381 | drawArrowLeft x y model = 1382 | let 1383 | startX = measureX x + textWidth 1384 | endX = measureX x + textWidth / 2 1385 | startY = measureY y + textHeight / 2 1386 | endY = startY 1387 | {red,green,blue,alpha} = Color.toRgb color 1388 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1389 | in 1390 | line 1391 | [x1 <| toString startX 1392 | ,x2 <| toString endX 1393 | ,y1 <| toString startY 1394 | ,y2 <| toString endY 1395 | ,Svg.Attributes.style ("stroke: "++colorText++";stroke-width:"++toString lineWidth) 1396 | ,markerEnd "url(#triangle)" 1397 | ] 1398 | [] 1399 | 1400 | 1401 | 1402 | drawArrowDown x y model = 1403 | let 1404 | startX = measureX x + textWidth / 2 1405 | endX = startX 1406 | startY = measureY y 1407 | endY = startY + textHeight 1408 | {red,green,blue,alpha} = Color.toRgb color 1409 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1410 | in 1411 | line 1412 | [x1 <| toString startX 1413 | ,x2 <| toString endX 1414 | ,y1 <| toString startY 1415 | ,y2 <| toString endY 1416 | ,Svg.Attributes.style ("stroke: "++colorText++";stroke-width:"++toString lineWidth) 1417 | ,markerEnd "url(#triangle)" 1418 | ] 1419 | [] 1420 | 1421 | drawArrowSouthWest x y model = 1422 | let 1423 | startX = measureX x + textWidth 1424 | startY = measureY y 1425 | endX = startX - textWidth / 2 1426 | endY = startY + textHeight / 2 1427 | {red,green,blue,alpha} = Color.toRgb color 1428 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1429 | in 1430 | line 1431 | [x1 <| toString startX 1432 | ,x2 <| toString endX 1433 | ,y1 <| toString startY 1434 | ,y2 <| toString endY 1435 | ,Svg.Attributes.style ("stroke: "++colorText++";stroke-width:"++toString lineWidth) 1436 | ,markerEnd "url(#triangle)" 1437 | ] 1438 | [] 1439 | 1440 | drawArrowSouthEast x y model = 1441 | let 1442 | startX = measureX x 1443 | startY = measureY y 1444 | endX = startX + textWidth / 2 1445 | endY = startY + textHeight / 2 1446 | {red,green,blue,alpha} = Color.toRgb color 1447 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1448 | in 1449 | line 1450 | [x1 <| toString startX 1451 | ,x2 <| toString endX 1452 | ,y1 <| toString startY 1453 | ,y2 <| toString endY 1454 | ,Svg.Attributes.style ("stroke: "++colorText++";stroke-width:"++toString lineWidth) 1455 | ,markerEnd "url(#triangle)" 1456 | ] 1457 | [] 1458 | 1459 | drawArrowUp x y model = 1460 | let 1461 | startX = measureX x + textWidth / 2 1462 | endX = startX 1463 | startY = measureY y + textHeight 1464 | endY = measureY y 1465 | {red,green,blue,alpha} = Color.toRgb color 1466 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1467 | in 1468 | line 1469 | [x1 <| toString startX 1470 | ,x2 <| toString endX 1471 | ,y1 <| toString startY 1472 | ,y2 <| toString endY 1473 | ,Svg.Attributes.style ("stroke: "++colorText++";stroke-width:"++toString lineWidth) 1474 | ,markerEnd "url(#triangle)" 1475 | ] 1476 | [] 1477 | 1478 | drawArrowNorthWest x y model = 1479 | let 1480 | startX = measureX x 1481 | startY = measureY y + textHeight 1482 | endX = startX + textWidth / 2 1483 | endY = measureY y + textHeight / 2 1484 | {red,green,blue,alpha} = Color.toRgb color 1485 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1486 | in 1487 | line 1488 | [x1 <| toString startX 1489 | ,x2 <| toString endX 1490 | ,y1 <| toString startY 1491 | ,y2 <| toString endY 1492 | ,Svg.Attributes.style ("stroke: "++colorText++";stroke-width:"++toString lineWidth) 1493 | ,markerEnd "url(#triangle)" 1494 | ] 1495 | [] 1496 | 1497 | drawArrowNorthEast x y model = 1498 | let 1499 | startX = measureX x + textWidth 1500 | startY = measureY y + textHeight 1501 | endX = measureX x + textWidth / 2 1502 | endY = measureY y + textHeight / 2 1503 | {red,green,blue,alpha} = Color.toRgb color 1504 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1505 | in 1506 | line 1507 | [x1 <| toString startX 1508 | ,x2 <| toString endX 1509 | ,y1 <| toString startY 1510 | ,y2 <| toString endY 1511 | ,Svg.Attributes.style ("stroke: "++colorText++";stroke-width:"++toString lineWidth) 1512 | ,markerEnd "url(#triangle)" 1513 | ] 1514 | [] 1515 | 1516 | 1517 | drawLine startX startY endX endY color = 1518 | let 1519 | {red,green,blue,alpha} = Color.toRgb color 1520 | colorText = "rgb("++(toString red)++","++(toString green)++","++(toString blue)++")" 1521 | in 1522 | line 1523 | [x1 <| toString startX 1524 | ,x2 <| toString endX 1525 | ,y1 <| toString startY 1526 | ,y2 <| toString endY 1527 | ,stroke colorText 1528 | ,strokeWidth <| toString lineWidth 1529 | ,strokeLinecap "round" 1530 | ,strokeLinejoin "mitter" 1531 | ] 1532 | [] 1533 | 1534 | 1535 | drawText: Int -> Int -> Char -> Svg a 1536 | drawText x' y' char = 1537 | let x'' = measureX x' - textWidth / 4 1538 | y'' = measureY y' + textHeight * 3 / 4 1539 | in 1540 | Svg.text' 1541 | [x <| toString x'' 1542 | ,y <| toString y'' 1543 | ,Svg.Attributes.style ("font-size:"++toString fontSize++"px;font-family:monospace") 1544 | ] 1545 | [Svg.text <| String.fromChar char] 1546 | 1547 | 1548 | measureX: Int -> Float 1549 | measureX x = 1550 | toFloat x * textWidth 1551 | 1552 | measureY: Int -> Float 1553 | measureY y = 1554 | toFloat y * textHeight 1555 | 1556 | get: Int -> Int -> Model -> Maybe Char 1557 | get x y model = 1558 | let 1559 | row = y 1560 | 1561 | line: Maybe (Array Char) 1562 | line = Array.get y model.lines 1563 | 1564 | char: Maybe Char 1565 | char = 1566 | case line of 1567 | Just l -> 1568 | Array.get x l 1569 | Nothing -> 1570 | Nothing 1571 | in 1572 | char 1573 | 1574 | 1575 | init: String -> Model 1576 | init str = 1577 | let 1578 | lines = String.lines str 1579 | max = 1580 | List.map 1581 | (\line -> 1582 | String.length line 1583 | )lines 1584 | |> List.maximum 1585 | lineArr = Array.fromList lines 1586 | lineChar = 1587 | Array.map ( 1588 | \line -> 1589 | (String.toList <| String.trimRight line) 1590 | |> Array.fromList 1591 | ) lineArr 1592 | in 1593 | {rows = Array.length lineChar 1594 | ,columns = Maybe.withDefault 0 max 1595 | ,lines = lineChar 1596 | } 1597 | -------------------------------------------------------------------------------- /elm-markdown/index.html: -------------------------------------------------------------------------------- 1 | 2 | Main --------------------------------------------------------------------------------