Skip to content

Commit

Permalink
Closes #46 : Add WithIDs option
Browse files Browse the repository at this point in the history
  • Loading branch information
yuin committed Dec 2, 2019
1 parent 6efe809 commit 68dcec6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
27 changes: 27 additions & 0 deletions extra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

. "github.com/yuin/goldmark"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/testutil"
)
Expand Down Expand Up @@ -57,3 +58,29 @@ func TestWindowsNewLine(t *testing.T) {
t.Errorf("\n%s\n---------\n%s", source, b2.String())
}
}

type myIDs struct {
}

func (s *myIDs) Generate(value, prefix []byte) []byte {
return []byte("my-id")
}

func (s *myIDs) Put(value []byte) {
}

func TestAutogeneratedIDs(t *testing.T) {
ctx := parser.NewContext(parser.WithIDs(&myIDs{}))
markdown := New(WithParserOptions(parser.WithAutoHeadingID()))
source := []byte("# Title1\n## Title2")
var b bytes.Buffer
err := markdown.Convert(source, &b, parser.WithContext(ctx))
if err != nil {
t.Error(err.Error())
}
if b.String() != `<h1 id="my-id">Title1</h1>
<h2 id="my-id">Title2</h2>
` {
t.Errorf("%s\n---------\n%s", source, b.String())
}
}
29 changes: 25 additions & 4 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (s *ids) Generate(value, prefix []byte) []byte {
v += 'a' - 'A'
}
result = append(result, v)
} else if util.IsSpace(v) {
} else if util.IsSpace(v) || v == '-' || v == '_' {
result = append(result, '-')
}
}
Expand All @@ -104,7 +104,7 @@ func (s *ids) Generate(value, prefix []byte) []byte {
return result
}
for i := 1; ; i++ {
newResult := fmt.Sprintf("%s%d", result, i)
newResult := fmt.Sprintf("%s-%d", result, i)
if _, ok := s.values[newResult]; !ok {
s.values[newResult] = true
return []byte(newResult)
Expand Down Expand Up @@ -198,6 +198,20 @@ type Context interface {
LastOpenedBlock() Block
}

// A ContextConfig struct is a data structure that holds configuration of the Context.
type ContextConfig struct {
IDs IDs
}

// An ContextOption is a functional option type for the Context.
type ContextOption func(*ContextConfig)

func WithIDs(ids IDs) ContextOption {
return func(c *ContextConfig) {
c.IDs = ids
}
}

type parseContext struct {
store []interface{}
ids IDs
Expand All @@ -210,11 +224,18 @@ type parseContext struct {
}

// NewContext returns a new Context.
func NewContext() Context {
func NewContext(options ...ContextOption) Context {
cfg := &ContextConfig{
IDs: newIDs(),
}
for _, option := range options {
option(cfg)
}

return &parseContext{
store: make([]interface{}, ContextKeyMax+1),
refs: map[string]Reference{},
ids: newIDs(),
ids: cfg.IDs,
blockOffset: -1,
blockIndent: -1,
delimiters: nil,
Expand Down

0 comments on commit 68dcec6

Please sign in to comment.