Skip to content

Commit

Permalink
catch if base plugin is not registered
Browse files Browse the repository at this point in the history
  • Loading branch information
JohannesKaufmann committed Nov 4, 2024
1 parent c37ad42 commit 847f2d7
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 4 deletions.
12 changes: 9 additions & 3 deletions converter/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"errors"
"io"
"slices"
"strings"

"golang.org/x/net/html"
Expand Down Expand Up @@ -40,7 +41,8 @@ func (conv *Converter) getError() error {
return conv.err
}

var errNoRenderHandlers = errors.New("no render handlers are registered. did you forget to register the commonmark plugin?")
var errNoRenderHandlers = errors.New(`no render handlers are registered. did you forget to register the "commonmark" and "base" plugins?`)
var errBasePluginMissing = errors.New(`you registered the "commonmark" plugin but the "base" plugin is also required`)

// ConvertNode converts a `*html.Node` to a markdown byte slice.
//
Expand All @@ -65,11 +67,15 @@ func (conv *Converter) ConvertNode(doc *html.Node, opts ...convertOptionFunc) ([
// If there are no render handlers registered this is
// usually a user error - since people want the Commonmark Plugin in 99% of cases.
if len(conv.getRenderHandlers()) == 0 {
// TODO: Add Name() to the interface & check for the presence of *both* the Base & Commonmark Plugin
// TODO: What if just the base plugin is registered?
return nil, errNoRenderHandlers
}

containsCommonmark := slices.Contains(conv.registeredPlugins, "commonmark")
containsBase := slices.Contains(conv.registeredPlugins, "base")
if containsCommonmark && !containsBase {
return nil, errBasePluginMissing
}

// - - - - - - - - - - - - - - - - - - - //

state := newGlobalState()
Expand Down
19 changes: 18 additions & 1 deletion converter/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/JohannesKaufmann/dom"
"github.com/JohannesKaufmann/html-to-markdown/v2/converter"
"github.com/JohannesKaufmann/html-to-markdown/v2/plugin/base"
"github.com/JohannesKaufmann/html-to-markdown/v2/plugin/commonmark"
"golang.org/x/net/html"
)

Expand Down Expand Up @@ -61,7 +62,7 @@ func TestConvertString_ErrNoRenderHandlers(t *testing.T) {
if err == nil {
t.Fatal("expected an error")
}
if err.Error() != "no render handlers are registered. did you forget to register the commonmark plugin?" {
if err.Error() != `no render handlers are registered. did you forget to register the "commonmark" and "base" plugins?` {
t.Fatal("expected a different error but got", err)
}

Expand All @@ -78,6 +79,22 @@ func TestConvertString_ErrNoRenderHandlers(t *testing.T) {
}
}

func TestConvertString_ErrBasePluginMissing(t *testing.T) {
conv := converter.NewConverter(
converter.WithPlugins(
commonmark.NewCommonmarkPlugin(),
),
)

_, err := conv.ConvertString("<strong>bold text</strong>")
if err == nil {
t.Fatal("expected an error")
}
if err.Error() != `you registered the "commonmark" plugin but the "base" plugin is also required` {
t.Fatal("expected a different error but got", err)
}
}

func TestWithEscapeMode(t *testing.T) {
mockRenderer := func(ctx converter.Context, w converter.Writer, n *html.Node) converter.RenderStatus {
return converter.RenderTryNext
Expand Down
2 changes: 2 additions & 0 deletions converter/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ type Converter struct {

err error

registeredPlugins []string

preRenderHandlers prioritizedSlice[HandlePreRenderFunc]
renderHandlers prioritizedSlice[HandleRenderFunc]
postRenderHandlers prioritizedSlice[HandlePostRenderFunc]
Expand Down
11 changes: 11 additions & 0 deletions converter/plugin.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package converter

import "errors"

// Plugin can be used to extends functionality beyond what
// is offered by commonmark.
type Plugin interface {
// The public name of the plugin, e.g. "strikethrough"
Name() string

// Init is called to initialize the plugin. It can be used to
// *validate* the arguments and *register* the rules.
Init(conv *Converter) error
Expand All @@ -12,6 +17,12 @@ type Plugin interface {
func WithPlugins(plugins ...Plugin) converterOption {
return func(c *Converter) error {
for _, plugin := range plugins {
pluginName := plugin.Name()
if pluginName == "" {
return errors.New("the plugin has no name")
}
c.registeredPlugins = append(c.registeredPlugins, pluginName)

err := plugin.Init(c)
if err != nil {
return err
Expand Down
3 changes: 3 additions & 0 deletions plugin/base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ func NewBasePlugin() converter.Plugin {
return &base
}

func (s *base) Name() string {
return "base"
}
func (b *base) Init(conv *converter.Converter) error {
conv.Register.TagType("#comment", converter.TagTypeRemove, converter.PriorityStandard)
conv.Register.TagType("head", converter.TagTypeRemove, converter.PriorityStandard)
Expand Down
3 changes: 3 additions & 0 deletions plugin/commonmark/commonmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ func NewCommonmarkPlugin(opts ...OptionFunc) converter.Plugin {
return &cm
}

func (s *commonmark) Name() string {
return "commonmark"
}
func (cm *commonmark) Init(conv *converter.Converter) error {
if err := validateConfig(&cm.config); err != nil {
return err
Expand Down
3 changes: 3 additions & 0 deletions plugin/strikethrough/strikethrough.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ func NewStrikethroughPlugin(opts ...option) converter.Plugin {
return plugin
}

func (s *strikethroughPlugin) Name() string {
return "strikethrough"
}
func (s *strikethroughPlugin) Init(conv *converter.Converter) error {
conv.Register.PreRenderer(s.handlePreRender, converter.PriorityStandard)

Expand Down

0 comments on commit 847f2d7

Please sign in to comment.