Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extras: Some refactorings #20

Merged
merged 1 commit into from
May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
matrix:
go-version: [1.21.x, 1.22.x]
platform: [ubuntu-latest, macos-latest, windows-latest]
package: [passthrough]
package: [passthrough, extras]
runs-on: ${{ matrix.platform }}
defaults:
run:
Expand Down
84 changes: 84 additions & 0 deletions extras/ast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package extras

import (
"github.com/yuin/goldmark/ast"
)

type inlineTag struct {
TagKind ast.NodeKind
Char byte
Number int
Html string
WhitespaceAllowed bool
ParsePriority int
RenderPriority int
}

var superscriptTag = inlineTag{
TagKind: kindSuperscript,
Char: '^',
Number: 1,
Html: "sup",
WhitespaceAllowed: false,
ParsePriority: 600,
RenderPriority: 600,
}

var subscriptTag = inlineTag{
TagKind: kindSubscript,
Char: '~',
Number: 1,
Html: "sub",
WhitespaceAllowed: false,
ParsePriority: 602,
RenderPriority: 602,
}

var insertTag = inlineTag{
TagKind: kindInsert,
Char: '+',
Number: 2,
Html: "ins",
WhitespaceAllowed: true,
ParsePriority: 501,
RenderPriority: 501,
}

var markTag = inlineTag{
TagKind: kindMark,
Char: '=',
Number: 2,
Html: "mark",
WhitespaceAllowed: true,
ParsePriority: 550,
RenderPriority: 550,
}

type inlineTagNode struct {
ast.BaseInline

inlineTag
}

func newInlineTag(tag inlineTag) *inlineTagNode {
return &inlineTagNode{
BaseInline: ast.BaseInline{},

inlineTag: tag,
}
}

var (
kindSuperscript = ast.NewNodeKind("Superscript")
kindSubscript = ast.NewNodeKind("Subscript")
kindInsert = ast.NewNodeKind("Insert")
kindMark = ast.NewNodeKind("Mark")
)

func (n *inlineTagNode) Kind() ast.NodeKind {
return n.TagKind
}

func (n *inlineTagNode) Dump(source []byte, level int) {
ast.DumpHelper(n, source, level, nil, nil)
}
106 changes: 0 additions & 106 deletions extras/ast/inline.go

This file was deleted.

113 changes: 71 additions & 42 deletions extras/inline.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package extras

import (
"github.com/gohugoio/hugo-goldmark-extensions/extras/ast"
"github.com/yuin/goldmark"
gast "github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer"
"github.com/yuin/goldmark/renderer/html"
Expand All @@ -12,10 +11,10 @@ import (
)

type inlineTagDelimiterProcessor struct {
ast.InlineTag
inlineTag
}

func newInlineTagDelimiterProcessor(tag ast.InlineTag) parser.DelimiterProcessor {
func newInlineTagDelimiterProcessor(tag inlineTag) parser.DelimiterProcessor {
return &inlineTagDelimiterProcessor{tag}
}

Expand All @@ -27,16 +26,16 @@ func (p *inlineTagDelimiterProcessor) CanOpenCloser(opener, closer *parser.Delim
return opener.Char == closer.Char
}

func (p *inlineTagDelimiterProcessor) OnMatch(_ int) gast.Node {
return ast.NewInlineTag(p.InlineTag)
func (p *inlineTagDelimiterProcessor) OnMatch(_ int) ast.Node {
return newInlineTag(p.inlineTag)
}

type inlineTagParser struct {
ast.InlineTag
inlineTag
}

func newInlineTagParser(tag ast.InlineTag) parser.InlineParser {
return &inlineTagParser{InlineTag: tag}
func newInlineTagParser(tag inlineTag) parser.InlineParser {
return &inlineTagParser{inlineTag: tag}
}

// Trigger implements parser.InlineParser.
Expand All @@ -45,10 +44,10 @@ func (s *inlineTagParser) Trigger() []byte {
}

// Parse implements the parser.InlineParser for all types of InlineTags.
func (s *inlineTagParser) Parse(_ gast.Node, block text.Reader, pc parser.Context) gast.Node {
func (s *inlineTagParser) Parse(_ ast.Node, block text.Reader, pc parser.Context) ast.Node {
before := block.PrecendingCharacter()
line, segment := block.PeekLine()
node := parser.ScanDelimiter(line, before, s.Number, newInlineTagDelimiterProcessor(s.InlineTag))
node := parser.ScanDelimiter(line, before, s.Number, newInlineTagDelimiterProcessor(s.inlineTag))
if node == nil {
return nil
}
Expand Down Expand Up @@ -80,15 +79,15 @@ func hasSpace(line []byte) bool {

type inlineTagHTMLRenderer struct {
htmlTag string
tagType ast.InlineTagType
tagKind ast.NodeKind
html.Config
}

// newInlineTagHTMLRenderer returns a new NodeRenderer that renders InlineTagNode nodes to HTML.
func newInlineTagHTMLRenderer(tag ast.InlineTag, opts ...html.Option) renderer.NodeRenderer {
// newInlineTagHTMLRenderer returns a new NodeRenderer that renders InlineTaast.Node nodes to HTML.
func newInlineTagHTMLRenderer(tag inlineTag, opts ...html.Option) renderer.NodeRenderer {
r := &inlineTagHTMLRenderer{
htmlTag: tag.Html,
tagType: tag.TagType,
tagKind: tag.TagKind,
Config: html.NewConfig(),
}
for _, opt := range opts {
Expand All @@ -99,15 +98,16 @@ func newInlineTagHTMLRenderer(tag ast.InlineTag, opts ...html.Option) renderer.N

// RegisterFuncs registers rendering functions to the given NodeRendererFuncRegisterer.
func (r *inlineTagHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
reg.Register(ast.NewInlineTagNodeKind(r.tagType), r.renderInlineTag)
reg.Register(r.tagKind, r.renderInlineTag)
}

// inlineTagAttributeFilter is a global filter for attributes.
var inlineTagAttributeFilter = html.GlobalAttributeFilter

// renderInlineTag renders an inline tag.
func (r *inlineTagHTMLRenderer) renderInlineTag(
w util.BufWriter, _ []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
w util.BufWriter, _ []byte, n ast.Node, entering bool,
) (ast.WalkStatus, error) {
if entering {
_ = w.WriteByte('<')
_, _ = w.WriteString(r.htmlTag)
Expand All @@ -119,41 +119,70 @@ func (r *inlineTagHTMLRenderer) renderInlineTag(
_, _ = w.WriteString(r.htmlTag)
}
_ = w.WriteByte('>')
return gast.WalkContinue, nil
return ast.WalkContinue, nil
}

// inlineTag is an extension that adds inline tags to the Markdown parser and renderer.
type inlineTag struct {
ast.InlineTag
// inlineExtension is an extension that adds inline tags to the Markdown parser and renderer.
type inlineExtension struct {
conf Config
}

// InlineTagConfig is a configuration struct for the ExtraInlineTag extension.
// Config confitures the extras extension.
type Config struct {
ast.InlineTagType
Superscript SuperscriptConfig
Subscript SubscriptConfig
Insert InsertConfig
Mark MarkConfig
}

// SuperscriptConfig configures the superscript extension.
type SuperscriptConfig struct {
Enable bool
}

// SubscriptConfig configures the subscript extension.
type SubscriptConfig struct {
Enable bool
}

// InsertConfig configures the insert extension.
type InsertConfig struct {
Enable bool
}

// MarkConfig configures the mark extension.
type MarkConfig struct {
Enable bool
}

// New returns a new inline tag extension.

func New(config Config) goldmark.Extender {
var extension inlineTag

switch config.InlineTagType {
case ast.Superscript:
extension = inlineTag{ast.SuperscriptTag}
case ast.Subscript:
extension = inlineTag{ast.SubscriptTag}
case ast.Insert:
extension = inlineTag{ast.InsertTag}
case ast.Mark:
extension = inlineTag{ast.MarkTag}
return &inlineExtension{
conf: config,
}
return &extension
}

// Extend adds inline tags to the Markdown parser and renderer.
func (tag *inlineTag) Extend(md goldmark.Markdown) {
md.Parser().AddOptions(parser.WithInlineParsers(
util.Prioritized(newInlineTagParser(tag.InlineTag), tag.ParsePriority),
))
md.Renderer().AddOptions(renderer.WithNodeRenderers(
util.Prioritized(newInlineTagHTMLRenderer(tag.InlineTag), tag.RenderPriority),
))
func (tag *inlineExtension) Extend(md goldmark.Markdown) {
addTag := func(tag inlineTag) {
md.Parser().AddOptions(parser.WithInlineParsers(
util.Prioritized(newInlineTagParser(tag), tag.ParsePriority),
))
md.Renderer().AddOptions(renderer.WithNodeRenderers(
util.Prioritized(newInlineTagHTMLRenderer(tag), tag.RenderPriority),
))
}
if tag.conf.Superscript.Enable {
addTag(superscriptTag)
}
if tag.conf.Subscript.Enable {
addTag(subscriptTag)
}
if tag.conf.Insert.Enable {
addTag(insertTag)
}
if tag.conf.Mark.Enable {
addTag(markTag)
}
}
Loading