Fix bug that escaped space not working with Linkfy extension

This commit is contained in:
yuin 2022-09-25 19:39:48 +09:00
parent 1dd67d5750
commit ae42b9179f
3 changed files with 43 additions and 1 deletions

View file

@ -2,6 +2,7 @@ package extension
import ( import (
"github.com/yuin/goldmark" "github.com/yuin/goldmark"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/renderer/html"
) )
@ -45,5 +46,6 @@ func (e *cjk) Extend(m goldmark.Markdown) {
} }
if e.EscapedSpace { if e.EscapedSpace {
m.Renderer().AddOptions(html.WithWriter(html.NewWriter(html.WithEscapedSpace()))) m.Renderer().AddOptions(html.WithWriter(html.NewWriter(html.WithEscapedSpace())))
m.Parser().AddOptions(parser.WithEscapedSpace())
} }
} }

View file

@ -56,6 +56,31 @@ func TestEscapedSpace(t *testing.T) {
}, },
t, t,
) )
// ' ' triggers Linkify extension inline parser.
// Escaped spaces should not trigger the inline parser.
markdown = goldmark.New(goldmark.WithRendererOptions(
html.WithXHTML(),
html.WithUnsafe(),
),
goldmark.WithExtensions(
NewCJK(WithEscapedSpace()),
Linkify,
),
)
no = 4
testutil.DoTestCase(
markdown,
testutil.MarkdownTestCase{
No: no,
Description: "Escaped space and linkfy extension",
Markdown: "太郎は\\ **「こんにちわ」**\\ と言った\nんです",
Expected: "<p>太郎は<strong>「こんにちわ」</strong>と言った\nんです</p>",
},
t,
)
} }
func TestEastAsianLineBreaks(t *testing.T) { func TestEastAsianLineBreaks(t *testing.T) {

View file

@ -430,6 +430,7 @@ type Config struct {
InlineParsers util.PrioritizedSlice /*<InlineParser>*/ InlineParsers util.PrioritizedSlice /*<InlineParser>*/
ParagraphTransformers util.PrioritizedSlice /*<ParagraphTransformer>*/ ParagraphTransformers util.PrioritizedSlice /*<ParagraphTransformer>*/
ASTTransformers util.PrioritizedSlice /*<ASTTransformer>*/ ASTTransformers util.PrioritizedSlice /*<ASTTransformer>*/
EscapedSpace bool
} }
// NewConfig returns a new Config. // NewConfig returns a new Config.
@ -635,6 +636,7 @@ type parser struct {
closeBlockers []CloseBlocker closeBlockers []CloseBlocker
paragraphTransformers []ParagraphTransformer paragraphTransformers []ParagraphTransformer
astTransformers []ASTTransformer astTransformers []ASTTransformer
escapedSpace bool
config *Config config *Config
initSync sync.Once initSync sync.Once
} }
@ -695,6 +697,18 @@ func WithASTTransformers(ps ...util.PrioritizedValue) Option {
return &withASTTransformers{ps} return &withASTTransformers{ps}
} }
type withEscapedSpace struct {
}
func (o *withEscapedSpace) SetParserOption(c *Config) {
c.EscapedSpace = true
}
// WithEscapedSpace is a functional option indicates that a '\' escaped half-space(0x20) should not trigger parsers.
func WithEscapedSpace() Option {
return &withEscapedSpace{}
}
type withOption struct { type withOption struct {
name OptionName name OptionName
value interface{} value interface{}
@ -846,6 +860,7 @@ func (p *parser) Parse(reader text.Reader, opts ...ParseOption) ast.Node {
for _, v := range p.config.ASTTransformers { for _, v := range p.config.ASTTransformers {
p.addASTTransformer(v, p.config.Options) p.addASTTransformer(v, p.config.Options)
} }
p.escapedSpace = p.config.EscapedSpace
p.config = nil p.config = nil
}) })
c := &ParseConfig{} c := &ParseConfig{}
@ -1165,7 +1180,7 @@ func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context)
} }
isSpace := util.IsSpace(c) isSpace := util.IsSpace(c)
isPunct := util.IsPunct(c) isPunct := util.IsPunct(c)
if (isPunct && !escaped) || isSpace || i == 0 { if (isPunct && !escaped) || isSpace && !(escaped && p.escapedSpace) || i == 0 {
parserChar := c parserChar := c
if isSpace || (i == 0 && !isPunct) { if isSpace || (i == 0 && !isPunct) {
parserChar = ' ' parserChar = ' '