Created
July 1, 2024 05:40
-
-
Save cbednarski/8dcc0c90890613f2b74008dc264bd14f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package turbine | |
import ( | |
"bytes" | |
"io" | |
"regexp" | |
"strings" | |
"github.com/russross/blackfriday/v2" | |
) | |
var reParseHeadingID = regexp.MustCompile(`id="(.+)"`) | |
type AutoHeadingLinkRenderer struct { | |
Base blackfriday.Renderer | |
// LinkText will be inserted for the anchor's content. This is inserted | |
// verbatim so it could be a special character like # or an image tag. | |
LinkText string | |
// Outside will write the anchor outside the header tag. This can be useful | |
// to avoid mixing formatting. | |
Outside bool | |
// CSSClass will be added to the anchor tag (optional) | |
CSSClass string | |
} | |
func (r *AutoHeadingLinkRenderer) renderLink(id string) *bytes.Buffer { | |
s := strings.Builder{} | |
s.WriteString(`<a href="#`) | |
s.WriteString(id) | |
s.WriteString(`"`) | |
if r.CSSClass != "" { | |
s.WriteString(` class="`) | |
s.WriteString(r.CSSClass) | |
s.WriteString(`"`) | |
} | |
s.WriteString(">") | |
s.WriteString(r.LinkText) | |
s.WriteString("</a>") | |
buf := &bytes.Buffer{} | |
buf.WriteString(s.String()) | |
return buf | |
} | |
func (r *AutoHeadingLinkRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { | |
switch node.Type { | |
case blackfriday.Heading: | |
heading := &bytes.Buffer{} | |
// Render the node to a buffer so we can tamper with it | |
status := r.Base.RenderNode(heading, node, entering) | |
// entering is the opening tag, such as <h3 ... > | |
if entering { | |
id := reParseHeadingID.FindStringSubmatch(heading.String()) | |
if len(id) == 2 { | |
if r.Outside { | |
io.Copy(w, r.renderLink(id[1])) | |
} else { | |
heading.Write(r.renderLink(id[1]).Bytes()) | |
} | |
} | |
} | |
if _, err := io.Copy(w, heading); err != nil { | |
panic(err) | |
} | |
return status | |
default: | |
return r.Base.RenderNode(w, node, entering) | |
} | |
} | |
func (r *AutoHeadingLinkRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) { | |
r.Base.RenderHeader(w, ast) | |
} | |
func (r *AutoHeadingLinkRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) { | |
r.Base.RenderFooter(w, ast) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func Render(data []byte) []byte { | |
extensions := blackfriday.FencedCode | blackfriday.Strikethrough | blackfriday.AutoHeadingIDs | |
var renderer blackfriday.Renderer = blackfriday.NewHTMLRenderer(blackfriday.HTMLRendererParameters{}) | |
renderer = &AutoHeadingLinkRenderer{ | |
Base: renderer, | |
LinkText: "#", | |
Outside: true, | |
CSSClass: "heading-link", | |
} | |
return blackfriday.Run(data, blackfriday.WithExtensions(extensions), blackfriday.WithRenderer(renderer)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment