module MParser exposing (ezmd) import Element exposing (..) import Element.Background import Element.Border import Element.Font as Font import Html.Attributes import Markdown.Html import Markdown.Parser import SiteComponents exposing (..) ezmd input = case markdownView input of Ok rendered -> Element.column [ Element.spacing 30 ] rendered Err errors -> Element.text errors markdownView : String -> Result String (List (Element msg)) markdownView markdown = markdown |> Markdown.Parser.parse |> Result.mapError (\error -> error |> List.map Markdown.Parser.deadEndToString |> String.join "\n") |> Result.andThen (Markdown.Parser.render renderer) renderer : Markdown.Parser.Renderer (Element msg) renderer = { heading = heading , raw = Element.paragraph [ Element.spacing 15 ] , thematicBreak = Element.none , plain = Element.text , bold = \content -> Element.row [ Font.bold ] [ Element.text content ] , italic = \content -> Element.row [ Font.italic ] [ Element.text content ] , code = code , link = \{ destination } body -> (if List.member (String.left 1 destination) [ "#", "/" ] then Element.link else Element.newTabLink ) [ Element.htmlAttribute (Html.Attributes.style "display" "inline-flex") ] { url = destination , label = Element.paragraph [ Font.color basedGreen, Font.underline ] body } |> Ok , image = \image body -> Element.image [ Element.width (Element.maximum 700 Element.fill) ] { src = image.src, description = body } |> Ok , list = \items -> Element.column [ Element.spacing 15 ] (items |> List.map (\itemBlocks -> Element.row [ Element.spacing 5 ] [ Element.el [ Element.alignTop ] (Element.text "•") , itemBlocks ] ) ) , codeBlock = codeBlock , html = Markdown.Html.oneOf [] } rawTextToId rawText = rawText |> String.toLower |> String.replace " " "-" heading : { level : Int, rawText : String, children : List (Element msg) } -> Element msg heading { level, rawText, children } = let fontSize = case level of 1 -> 36 2 -> 24 _ -> 20 in paragraph [ Element.htmlAttribute (Html.Attributes.attribute "name" (rawTextToId rawText)) , Element.htmlAttribute (Html.Attributes.id (rawTextToId rawText)) , width fill , height shrink , padding 10 , greenLines , Font.size fontSize ] children code : String -> Element msg code snippet = Element.el [ Element.Background.color (Element.rgba 0 0 0 0.04) , scrollbars , Element.Border.rounded 2 , Element.paddingXY 5 3 ] (Element.text snippet) codeBlock : { body : String, language : Maybe String } -> Element msg codeBlock details = Element.el [ Element.Background.color (Element.rgba 0 0 0 0.03) , scrollbars , Element.htmlAttribute (Html.Attributes.style "white-space" "pre") , Element.padding 20 , Element.width Element.fill ] (Element.text details.body)