Closes #46 : Add WithIDs option

This commit is contained in:
yuin 2019-12-02 14:38:28 +09:00
parent 6efe809cde
commit 68dcec6ac4
2 changed files with 52 additions and 4 deletions

View file

@ -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"
)
@ -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())
}
}

View file

@ -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, '-')
}
}
@ -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)
@ -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
@ -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,