mirror of
https://github.com/yuin/goldmark
synced 2025-03-04 23:04:52 +00:00
Fix bug that escaped space not working with Linkfy extension
This commit is contained in:
parent
1dd67d5750
commit
ae42b9179f
3 changed files with 43 additions and 1 deletions
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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 = ' '
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue