gomarkdown / markdown

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

How to extend inline markdown parsing? #291

Closed kensanata closed 11 months ago

kensanata commented 11 months ago

I'd be interested in parsing [[links]] and #hashtags but don't know where to start.

My naïve approach would be something like the following for hashtags (untested, since it doesn't compile). I'm pretty new to Go so I'm guessing the reason this fails is because I have no access to Parser.inlineCallback. I think the best solution would be to add something to Options that would allow passing a additional values for inlineCallback?

func hashtag(p *parser.Parser, data []byte, offset int) (int, ast.Node) {
    data = data[offset:]
    i := 0
    n := len(data)
    for i < n && !parser.IsSpace(data[i]) {
        i++
    }
    if i == 0 {
        return 0, nil
    }
    link := &ast.Link{
        Destination: append([]byte("/search?q=%23"), data[1:i]...),
        Title: data[0:i],
    }
    return i + 1, link
}

// renderHtml renders the Page.Body to HTML and sets Page.Html.
func (p *Page) renderHtml() {
    parser := parser.New()
    parser.inlineCallback['#'] = hashtag
    maybeUnsafeHTML := markdown.ToHTML(p.Body, parser, nil)
    p.Html = sanitizeBytes(maybeUnsafeHTML)
    p.Language = language(p.plainText())
}
kensanata commented 11 months ago

I've forked a version of the markdown library and made the following change: 302893f99160ba6fd0c3f58edd6e2611d6a7dd3a

This seems to do what I want. In my wiki, I was able to add the extension to the parser, and test it successfully: 4c4156c44e7a0e43c4ca671e9361243dc8065822

kjk commented 11 months ago

I've added Parser.RegisterInline() which should give you a way to register hashtag without forking the library.

kensanata commented 11 months ago

Thanks, works as intended!

kensanata commented 11 months ago

If you're interested, I can try and write extract the two uses I have for this for your examples directory?

kjk commented 11 months ago

Yes, that would be great.