goldmark-hashtag is an extension for the goldmark Markdown parser
that adds support for tagging documents with #hashtags.
Demo: A web-based demonstration of the extension is available at https://abhinav.github.io/goldmark-hashtag/demo/.
go get go.abhg.dev/goldmark/hashtag@latestTo use goldmark-hashtag, import the hashtag package.
import "go.abhg.dev/goldmark/hashtag"Then include the hashtag.Extender in the list of extensions you build your
goldmark.Markdown with.
goldmark.New(
goldmark.WithExtensions(
&hashtag.Extender{},
),
// ...
).Convert(src, out)This alone has little effect
besides adding <span class="hashtag">...</span>
around hashtags in your Markdown document.
You must supply a hashtag.Resolver to render hashtags as links.
Supply a hashtag.Resolver to the hashtag.Extender
to render hashtags as links:
goldmark.New(
goldmark.WithExtensions(
&hashtag.Extender{
Resolver: hashtagResolver,
},
),
// ...
).Convert(src, out)Hashtags must always begin with a "#". The characters that follow that depend on the variant you have chosen. goldmark-hashtag supports the following variants:
- Default: Hashtags must begin with a letter, and may contain letters,
numbers and any of the following symbols:
/_-. goldmark-hashtag uses this variant if you do not specify one. - Obsidian: Hashtags can begin with and contain letters, numbers, emoji, and
any of the following symbols:
/_-, but must not contain only numbers.
You can specify the variant by setting the Variant property of the
hashtag.Extender.
&hashtag.Extender{
// ...
Variant: hashtag.ObsidianVariant,
}To collect all hashtags from a Markdown document, use Goldmark's ast.Walk
function after parsing the document.
For example, the following will populate the hashtags map with all hashtags
found in the document.
markdown := goldmark.New(
goldmark.WithExtensions(
&hashtag.Extender{
Resolver: hashtagResolver,
},
),
// ...
)
// Parse the Markdown document.
doc := markdown.Parser().Parse(text.NewReader(src))
// List the tags.
hashtags := make(map[string]struct{})
ast.Walk(doc, func(node ast.Node, enter bool) (ast.WalkStatus, error) {
if n, ok := node.(*hashtag.Node); ok && enter {
hashtags[string(n.Tag)] = struct{}{}
}
return ast.WalkContinue, nil
})