mirror of
https://github.com/yuin/goldmark
synced 2025-03-04 23:04:52 +00:00
Closes #46 : Add WithIDs option
This commit is contained in:
parent
6efe809cde
commit
68dcec6ac4
2 changed files with 52 additions and 4 deletions
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue