markdown-it / markdown-it-container

Fenced container plugin for markdown-it markdown parser
MIT License
496 stars 74 forks source link

An rendering bug when using <p> tag. #22

Closed ulivz closed 6 years ago

ulivz commented 6 years ago

My options is like this:

md.use(...cssHelpersPlugin(md))

/* cssHelpersPlugin's source code: */

const RE = /^(tip|warning|danger)$/

export default md => ([
  containerPlugiin,
  'css-helper',
  {
    validate (params) {
      console.log(params)
      return params.trim().match(RE)
    },

    render(tokens, idx) {
      const [, helperType] = tokens[idx].info.trim().match(RE) || []
      if (tokens[idx].nesting === 1) {
        return `<p class="${helperType}">\n` // opening tag
      }
      return '</p>\n' // closing tag
    }
  }
])

Whose render result will be:

<p class="warning"></p>
<p><em>here be dragons</em></p>
<p></p>

The expected result should be like this instead.

<p class="warning">
     <em>here be dragons</em>
<p>
puzrin commented 6 years ago

I'm sure it works as expected :). Can't understand idea of you code. Could you provide full executable sample? I'll try to help then.

ulivz commented 6 years ago

@puzrin Oh, sorry, I made a standalone test here: https://codepan.net/gist/0d29a35d61822f769c73351582a65b99

And it looks good, maybe there exists some problem at my project, just close this issue, thank you.

puzrin commented 6 years ago

No problem, just note that "container" is for block elements inside. So, it's not good idea to use <p>, because it's for inline elements only. Expect something like <div>, <aside> etc. May be you need something different - another tag (not <p>) or another plugin (i don't know your requirements).

Feel free to ask more questions.

ulivz commented 6 years ago

Thank you very much, I finally found out that it's bug of Vue which cannot render the nested <p> elements correctly.

https://github.com/vuejs/vue/issues/7939

emmm, so I still have another question, why the rendering content would be embedded in a <p> element by default?

My test input:

::: warning
*here be warning*
:::

And I found two token paragraph_open and paragraph_close was mixed in:

image


image

puzrin commented 6 years ago

Probably, you misunderstood "markdown spirit" :). No inline content allowed wihout <p> wrapper (except lists, special case). Since it's impossible to create universal parser, it's expected that you follow "markdown spirit" when use this one. So, if you try to make something "unusual", everything become bad :)

Let's inspect your example:

::: warning
*here be warning*
:::

If you type inner:

*here be warning*

you should get:

<p><b>here be warning</b></p>

Then, after adding container wrapper, you should get:

<container opening>
<p><b>here be warning</b></p> <---- inner content, as usual markdown
</container closing>

That's exactly what container is created for. If you try to use it in another way, you will fall in troubles. If you just wish custom wrapper for unparsed plain text, then "fenced block" will be more suitable.

ulivz commented 6 years ago

Thank you for your detailed explanation. It's my misunderstanding. I also found out in the specification:

https://www.w3.org/TR/html401/struct/text.html#h-9.3.1

The P element represents a paragraph. It cannot contain block-level elements (including P itself).

Studied it! Thank you!

douglasg14b commented 4 years ago

This seems like a common problem with this library, why not add a configuration option to just exclude the paragraph tag?