gen2space/src/MParser.elm
2022-03-25 07:22:48 -07:00

128 lines
3.6 KiB
Elm

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)