Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to render any arbitrary HTML tag instead of erroring? #51

Open
devinjameson opened this issue Jul 31, 2020 · 2 comments
Open

Comments

@devinjameson
Copy link

devinjameson commented Jul 31, 2020

Something like this?

html =
    Markdown.Html.oneOf
        [ Markdown.Html.tag "i"
            (\renderedChildren ->
                italicsView renderedChildren
            )
        , Markdown.Html.tag "b"
            (\renderedChildren ->
                boldView renderedChildren
            )
        , Markdown.Html.tag anything_else
            (\renderedChildren ->
                someView renderedChildren
            )
@houseofmercy-github
Copy link

I'm also trying to find a way to improve the user experience for this but am encountering some difficulties
importing the types I need to define a catch-all variation of Markdown.Html.tag which would just render
the unsupported tag in red. I'm new to Elm so I left this question in r/Elm


Hello. I'm new to Elm.

I'm trying to see if I can improve this Ellie https://ellie-app.com/d7R3b9FsHfCa1
which makes use of https://github.com/dillonkearns/elm-markdown to render some custom html.

The example works but it's a little fragile. For example if I add a tag like <p/>
to the input area the you see nothing but

Problem with the given value:
<p>
Expecting attribute "photo".

Clearly "photo" is isn't relevent for a <p> - the error seems to be coming from
the last custom renderer in the list given to the oneOf function here:

renderer : Markdown.Renderer.Renderer (Element Msg)
renderer =
    { elmUiRenderer
        | html =
            Markdown.Html.oneOf
                [ Markdown.Html.tag "bio"
                    (\name photoUrl twitter github dribbble renderedChildren ->
                        bioView renderedChildren name photoUrl twitter github dribbble
                    )
                    |> Markdown.Html.withAttribute "name"
                    |> Markdown.Html.withAttribute "photo"
                    |> Markdown.Html.withOptionalAttribute "twitter"
                    |> Markdown.Html.withOptionalAttribute "github"
                    |> Markdown.Html.withOptionalAttribute "dribbble"
                ]
    }

I'm trying to add a generic catch-all renderer to this list which will convert unrecognized
tags like <p> to red text so that the remaining parts of the document which are ok don't
entirely vanish and the user has a better idea of what they need to do along the lines
Jim Carlson does in his L1 markup demonstration https://www.youtube.com/watch?v=gqeqtZeDp18&t=120s

I thought I would get started by trying make my own version of "Markdown.Html.tag"
https://github.com/dillonkearns/elm-markdown/blob/master/src/Markdown/Html.elm#L178
and improving on it. I tried adding

-- Based on https://github.com/dillonkearns/elm-markdown/blob/master/src/Markdown/Html.elm#L178
mytag : String -> view -> Renderer view
mytag expectedTag a =
    Markdown.HtmlRenderer.HtmlRenderer
        (\tagName attributes children ->
            if tagName == expectedTag then
                Ok a

            else
                Err ("Expected " ++ expectedTag ++ " but was " ++ tagName)
        )

but that didn't work because 'Renderer' and 'Markdown.HtmlRenderer.HtmlRenderer' weren't defined
and I can't quite seem to figure out how to import what I need to define them and I'm starting to
suspect I won't be able to the way the module exports are setup. Markdown/Html.elm does

import Markdown.HtmlRenderer

but when I try adding that to my Ellie I get the error

You are trying to import a `Markdown.HtmlRenderer` module:

11| import Markdown.HtmlRenderer
           ^^^^^^^^^^^^^^^^^^^^^
I checked the "dependencies" and "source-directories" listed in your elm.json,
but I cannot find it! 

I assumed that if Markdown/Html.elm can import Markdown.HtmlRenderer then my Ellie should be
able to as well but things aren't so simple it seems and there must be some rules I'm missing.

So my question(s) for anyone here is:

  • Is there a way I can import the types I need into the Ellie to define the "mytag" function there?
  • Is there a way I could define this function in my own code modifying elm-markdown?

Any and all advice is appreciated. Thanks,

@dillonkearns
Copy link
Owner

@houseofmercy-github Markdown.HtmlRenderer isn't exposed in the public module (see the list of exposed modules in the package at https://package.elm-lang.org/packages/dillonkearns/elm-markdown/latest/).

elm-markdown currently only exposes the API you see in Markdown.Html for defining HTML rendering behavior and how to parse HTML tags.

I do think it would make sense to allow for some way to handle HTML parsing errors (either a different default and/or an API for customizing how to handle it), which I touched on a little bit here: #99 (reply in thread).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants