Skip to content

Commit

Permalink
refactor: consistent structure
Browse files Browse the repository at this point in the history
1. Extension
2. NodeKind
3. Parse/Transform
4. HTML Renderer
  • Loading branch information
13rac1 committed Dec 20, 2020
1 parent 9eb1067 commit 9e06d63
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 55 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# goldmark-wikilink

goldmark-embed is an extension for the [goldmark][goldmark] library that extends
goldmark-wikilink is an extension for the [goldmark][goldmark] library that extends
Markdown to support `[[title]]` [Wikilink][help-link] style links with a new AST
type and HTML Renderer.

Expand Down
115 changes: 62 additions & 53 deletions wikilink.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,66 @@ import (
"github.com/yuin/goldmark/util"
)

type wlExtension struct{}

// Option is a functional option type for this extension.
type Option func(*wlExtension)

// New returns a new Wikilink extension.
func New(opts ...Option) goldmark.Extender {
e := &wlExtension{}
for _, opt := range opts {
opt(e)
}
return e
}

// Extend adds a wikilink parser to a Goldmark parser
func (wl *wlExtension) Extend(m goldmark.Markdown) {
m.Parser().AddOptions(
parser.WithInlineParsers(
util.Prioritized(NewParser(), 102),
),
)
m.Renderer().AddOptions(
renderer.WithNodeRenderers(
util.Prioritized(NewHTMLRenderer(), 500),
),
)
}

// Wikilink struct represents a Wikilink of the Markdown text.
type Wikilink struct {
ast.Link
}

// KindWikilink is a NodeKind of the Wikilink node.
var KindWikilink = ast.NewNodeKind("Wikilink")

// Kind implements Node.Kind.
func (n *Wikilink) Kind() ast.NodeKind {
return KindWikilink
}

// NewWikilink returns a new Wikilink node.
func NewWikilink(l *ast.Link) *Wikilink {
c := &Wikilink{
Link: *l,
}
c.Destination = l.Destination // AKA Target
c.Title = l.Title

return c
}

// FilenameNormalizer is a plugin which takes link text and converts the text given to
// a filename which can be linked to in the final format of your file.
type FilenameNormalizer interface {
Normalize(linkText string) string
}

// wikilinksParser keeps track of the plugins used for processing wikilinks.
type wikilinksParser struct {
// Parser keeps track of the plugins used for processing wikilinks.
type Parser struct {
normalizer FilenameNormalizer
}

Expand All @@ -31,27 +83,26 @@ func (t *linkNormalizer) Normalize(linkText string) string {
return url.PathEscape(linkText) + ".html"
}

var defaultWikilinksParser = &wikilinksParser{
normalizer: &linkNormalizer{},
}

// NewParser gives you back a parser that you can use to process wikilinks.
func NewParser() *wikilinksParser {
return defaultWikilinksParser
func NewParser() *Parser {
return &Parser{
normalizer: &linkNormalizer{},
}
}

// WithNormalizer is the fluent interface for replacing the default normalizer plugin.
func (p *wikilinksParser) WithNormalizer(fn FilenameNormalizer) *wikilinksParser {
func (p *Parser) WithNormalizer(fn FilenameNormalizer) *Parser {
p.normalizer = fn
return p
}

// Trigger looks for the [[ beginning of wikilinks.
func (p *wikilinksParser) Trigger() []byte {
func (p *Parser) Trigger() []byte {
return []byte{'[', '['}
}

func (p *wikilinksParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node {
// Parse implements the parser.Parser interface for Wikilinks in markdown
func (p *Parser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node {
line, segment := block.PeekLine()
// Must specifically confirm the second '['.
if line[1] != '[' {
Expand Down Expand Up @@ -94,48 +145,6 @@ func (p *wikilinksParser) Parse(parent ast.Node, block text.Reader, pc parser.Co
return wl
}

type wlExtension struct {
}

// Extension is the default extension instance.
var Extension = &wlExtension{}

// Extend adds a wikilink parser to a Goldmark parser
func (wl *wlExtension) Extend(m goldmark.Markdown) {
m.Parser().AddOptions(
parser.WithInlineParsers(util.Prioritized(defaultWikilinksParser, 102)),
)
m.Renderer().AddOptions(
renderer.WithNodeRenderers(
util.Prioritized(NewHTMLRenderer(), 500),
),
)
}

// Wikilink struct represents a Wikilink of the Markdown text.
type Wikilink struct {
ast.Link
}

// KindWikilink is a NodeKind of the Wikilink node.
var KindWikilink = ast.NewNodeKind("Wikilink")

// Kind implements Node.Kind.
func (n *Wikilink) Kind() ast.NodeKind {
return KindWikilink
}

// NewWikilink returns a new Wikilink node.
func NewWikilink(l *ast.Link) *Wikilink {
c := &Wikilink{
Link: *l,
}
c.Destination = l.Destination // AKA Target
c.Title = l.Title

return c
}

// HTMLRenderer struct is a renderer.NodeRenderer implementation for the extension.
type HTMLRenderer struct{}

Expand Down
2 changes: 1 addition & 1 deletion wikilink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestWikilink(t *testing.T) {
html.WithUnsafe(),
),
goldmark.WithExtensions(
wikilink.Extension,
wikilink.New(),
),
)

Expand Down

0 comments on commit 9e06d63

Please sign in to comment.