Awesome
goldmark-anchor
goldmark-anchor is an extension for the goldmark Markdown parser that adds support for anchors next to all headers.
Demo: A web-based demonstration of the extension is available at https://abhinav.github.io/goldmark-anchor/demo/.
Installation
go get go.abhg.dev/goldmark/anchor@latest
Usage
To use goldmark-anchor, import the anchor
package.
import "go.abhg.dev/goldmark/anchor"
Then include the anchor.Extender
in the list of extensions
when constructing your goldmark.Markdown
.
goldmark.New(
goldmark.WithParserOptions(
parser.WithAutoHeadingID(), // read note
),
goldmark.WithExtensions(
// ...
&anchor.Extender{},
),
).Convert(src, out)
This will begin adding '¶' anchors next to all headers in your Markdown files.
NOTE: The example above adds the
parser.WithAutoHeadingID
option. Without this, or a custom implementation ofparser.IDs
, Goldmark will not addid
attributes to headers. If a header does not have anid
, then goldmark-anchor will not generate an anchor for it.
Changing anchor text
Change the anchor text by setting the Texter
field
of the Extender
to an anchor.Text
value.
&anchor.Extender{
Texter: anchor.Text("#"),
}
Dynamic anchor text
You can dynamically calculate anchor text
by supplying a custom implementation of Texter
to the Extender
.
For example, the following Texter
repeats '#' matching the header level,
providing anchors similar to Markdown #
-style headers.
type customTexter struct{}
func (*customTexter) AnchorText(h *anchor.HeaderInfo) []byte {
return bytes.Repeat([]byte{'#'}, h.Level)
}
// Elsewhere:
&anchor.Extender{
Texter: &customTexter{},
}
Skipping headers
To skip headers, supply a custom Texter
that returns an empty output
for the AnchorText
method.
The following Texter
will not render anchors for level 1 headers.
type customTexter struct{}
func (*customTexter) AnchorText(h *anchor.HeaderInfo) []byte {
if h.Level == 1 {
return nil
}
return []byte("#")
}
Changing anchor attributes
Change the anchor attributes by setting the Attributer
field
of the Extender
.
&anchor.Extender{
Attributer: anchor.Attributes{
"class": "permalink",
},
}
By default, goldmark-anchor will add class="anchor"
to all anchors.
Set Attributer
to anchor.Attributes{}
to disable this.
&anchor.Extender{
Attributer: anchor.Attributes{},
}
Changing anchor positioning
Anchors can appear either at the start of the header before the header text, or at the end after the header text.
<!-- Before -->
<h1><a href="#">#</a> Foo</h1>
<!-- After -->
<h1>Foo <a href="#">¶</a></h1>
You can choose the placement by setting the Position
field of Extender
.
&anchor.Extender{
Position: anchor.Before, // or anchor.After
}
By default, goldmark-anchor will place anchors after the header text.
FAQ
Why are no anchors being generated?
By default, Goldmark does not generate IDs for headings. Since goldmark-anchor generates anchors only for headings with IDs, this can result in no anchors being generated
You must enable heading ID generation using one of the following methods:
- set the
parser.WithAutoHeadingID
option - supply your own
parser.IDs
implementation
Alternatively, if your document specifies heading attributes manually,
enable the parser.WithHeadingAttribute
option and manually specify
heading IDs next to each heading.
License
This software is made available under the BSD3 license.