pablo-abc / svelte-markdown

Markdown parser to svelte components
MIT License
359 stars 50 forks source link

Raw html in markdown is not translated properly #31

Closed boczpeter closed 2 years ago

boczpeter commented 2 years ago

Hi @pablo-abc,

My md text contains raw html, like: <time datetime="19:20">19:20</time> It is not left as-is in the output, but this: <time datetime="19:20"></time>19:20 It doesn't work for simple tags, like <span>label</span> either; it gets converted to <span></span>label

I tested it on Marked Demo page and couldn't reproduce the problem.

Using latest versions on Svelte, not SvelteKit.

pablo-abc commented 2 years ago

I've been scratching my head with this for a while. The reason this is happening is two things:

const tokens = [
    {
        type:"paragraph",
        raw:"<time datetime=\"19:20\">19:20</time>",
        text:"<time datetime=\"19:20\">19:20</time>",
        tokens: [
            {
                type:"html", raw:"<time datetime=\"19:20\">",
                inLink:false,
                inRawBlock:false,
                text:"<time datetime=\"19:20\">"
            },
            {
                type:"text",
                raw:"19:20",
                text:"19:20"
            },
            {
                type:"html",
                raw:"</time>",
                inLink:false,
                inRawBlock:false,
                text:"</time>"
            }
        ]
    }
]
{@html "<time datetime=\"19:20\">"}19:20{@html "</time>"}

But Svelte does not allow you to start an html tag in a {@html } block and finish it in another. So when svelte-markdown tries to render this, it fails as you saw previously.


The quickest solution is to treat a whole paragraph as HTML if there's at least one html element within its children. The drawback of this is that you won't be able to mix HTML and markdown in the same paragraph. So you wouldn't be able to write something like this at all:

The **time** is: <time datetime="19:20">19:20</time>

This seems like an acceptable compromise compared to just having broken HTML. I'll do this as a fix for now and add a note in the README explaining that paragraphs can either be HTML or Markdown, but not a mix of both.

boczpeter commented 2 years ago

Hi Thanks for the thorough explanation. I agree this compromise is better than the previous broken implementation.

pablo-abc commented 2 years ago

@boczpeter I haven't actually managed to merge this yet, but I found a workaround. You can "force" SvelteMarkdown to render the whole paragraph as HTML by wrapping it whole in <p></p> (or any HTML element tbh). E.g.

# Example

This will be _rendered_ as **markdown**.

<p>This will be <em>rendered</em> as <strong>HTML</strong></p>
boczpeter commented 2 years ago

Yes, it's exactly what I did in my documents.