gomarkdown / markdown

markdown parser and HTML renderer for Go
Other
1.36k stars 171 forks source link

Question about list with tight option enabled #298

Closed Lord-Y closed 8 months ago

Lord-Y commented 8 months ago

Hello there,

I'm trying to skip paragraph into a list of items with this sample code:

func list(w io.Writer, x *ast.List, entering bool) {
    if entering {
        io.WriteString(w, `<ul class="list-inside list-disc marker:text-emerald-500">`)
    } else {
        io.WriteString(w, "</ul>")
    }
}

func renderHook(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
    if ls, ok := node.(*ast.List); ok {
        ls.Tight = true
        list(w, ls, entering)
        return ast.GoToNext, true
    }
    return ast.GoToNext, false
}

func customizedRender() *html.Renderer {
    htmlFlags := html.CommonFlags | html.HrefTargetBlank
    opts := html.RendererOptions{
        RenderNodeHook: renderHook,
        Flags:          htmlFlags,
    }
    return html.NewRenderer(opts)
}

func mdToHTML(md []byte) []byte {
    // create markdown parser with extensions
    extensions := parser.CommonExtensions | parser.NoEmptyLineBeforeBlock
    p := parser.NewWithExtensions(extensions)
    doc := p.Parse(md)

    // create HTML renderer with extensions
    renderer := customizedRender()

    return markdown.Render(doc, renderer)
}

The source is like:

Asterisks loose:
* asterisk 1
* asterisk 2
* asterisk 3

and the result is:

<p>Asterisks loose:</p>
<ul>
<li><p>asterisk 1</p></li>
<li><p>asterisk 2</p></li>
<li><p>asterisk 3</p></li>
</ul>

instead of:

<p>Asterisks loose:</p>
<ul>
<li>asterisk 1</li>
<li>asterisk 2</li>
<li>asterisk 3</li>
</ul>

What do I miss? Thx.

PS: Sorry to open an issue as Discussions is not enabled here.

kjk commented 8 months ago

Please create and link to a fully runnable example e.g. on https://onlinetool.io/goplayground/

Also provide more context about what you expect and why.

Just looking at the code:

Lord-Y commented 8 months ago

@kjk Here is the example: https://onlinetool.io/goplayground/#avoxF4PMHIf This is what I expect:

<p class="my-4">Asterisks loose:</p>
<ul class="list-inside list-disc marker:text-emerald-500">
<li>asterisk 1</li>
<li>asterisk 2</li>
<li>asterisk 3</li>
</ul>
kjk commented 8 months ago

The problem is in your paragraph() renderer.

See https://github.com/gomarkdown/markdown/blob/master/html/renderer.go#L596C2-L606C2

There's logic to skip <p> inside in <li> in SkipParagraphTags() function.

You must do:

func paragraph(w io.Writer, x *ast.Paragraph, entering bool) {
    if html.SkipParagraphTags(x) {
        return
    }
    if entering {
        io.WriteString(w, `<p class="my-4">`)
    } else {
        io.WriteString(w, "</p>")
    }
}

See fixed example: https://onlinetool.io/goplayground/#C8hhoeyINje

Lord-Y commented 8 months ago

Thx for the help 💯 .