Fix typo and remove unnecessary conversion

This commit is contained in:
Zhizhen He 2022-06-09 11:38:52 +08:00
parent 8c219a7562
commit 2698d6168d
31 changed files with 1672 additions and 1692 deletions

View file

@ -65,6 +65,7 @@ Import packages:
```go ```go
import ( import (
"bytes" "bytes"
"github.com/yuin/goldmark" "github.com/yuin/goldmark"
) )
``` ```
@ -106,6 +107,7 @@ Custom parser and renderer
```go ```go
import ( import (
"bytes" "bytes"
"github.com/yuin/goldmark" "github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/parser"

View file

@ -97,17 +97,17 @@ type Node interface {
SortChildren(comparator func(n1, n2 Node) int) SortChildren(comparator func(n1, n2 Node) int)
// ReplaceChild replace a node v1 with a node insertee. // ReplaceChild replace a node v1 with a node insertee.
// If v1 is not children of this node, ReplaceChild append a insetee to the // If v1 is not children of this node, ReplaceChild append an insetee to the
// tail of the children. // tail of the children.
ReplaceChild(self, v1, insertee Node) ReplaceChild(self, v1, insertee Node)
// InsertBefore inserts a node insertee before a node v1. // InsertBefore inserts a node insertee before a node v1.
// If v1 is not children of this node, InsertBefore append a insetee to the // If v1 is not children of this node, InsertBefore append an insetee to the
// tail of the children. // tail of the children.
InsertBefore(self, v1, insertee Node) InsertBefore(self, v1, insertee Node)
// InsertAfterinserts a node insertee after a node v1. // InsertAfter inserts a node insertee after a node v1.
// If v1 is not children of this node, InsertBefore append a insetee to the // If v1 is not children of this node, InsertBefore append an insetee to the
// tail of the children. // tail of the children.
InsertAfter(self, v1, insertee Node) InsertAfter(self, v1, insertee Node)
@ -118,7 +118,7 @@ type Node interface {
// Dump dumps an AST tree structure to stdout. // Dump dumps an AST tree structure to stdout.
// This function completely aimed for debugging. // This function completely aimed for debugging.
// level is a indent level. Implementer should indent informations with // level is an indent level. Implementer should indent information with
// 2 * level spaces. // 2 * level spaces.
Dump(source []byte, level int) Dump(source []byte, level int)
@ -169,7 +169,7 @@ type Node interface {
RemoveAttributes() RemoveAttributes()
} }
// A BaseNode struct implements the Node interface partialliy. // A BaseNode struct implements the Node interface partially.
type BaseNode struct { type BaseNode struct {
firstChild Node firstChild Node
lastChild Node lastChild Node
@ -468,7 +468,7 @@ const (
// WalkStop indicates no more walking needed. // WalkStop indicates no more walking needed.
WalkStop WalkStatus = iota + 1 WalkStop WalkStatus = iota + 1
// WalkSkipChildren indicates that Walk wont walk on children of current // WalkSkipChildren indicates that Walk won't walk on children of current
// node. // node.
WalkSkipChildren WalkSkipChildren
@ -482,7 +482,7 @@ const (
// If Walker returns error, Walk function immediately stop walking. // If Walker returns error, Walk function immediately stop walking.
type Walker func(n Node, entering bool) (WalkStatus, error) type Walker func(n Node, entering bool) (WalkStatus, error)
// Walk walks a AST tree by the depth first search algorithm. // Walk walks an AST tree by the depth first search algorithm.
func Walk(n Node, walker Walker) error { func Walk(n Node, walker Walker) error {
_, err := walkHelper(n, walker) _, err := walkHelper(n, walker)
return err return err

View file

@ -7,7 +7,7 @@ import (
textm "github.com/yuin/goldmark/text" textm "github.com/yuin/goldmark/text"
) )
// A BaseBlock struct implements the Node interface partialliy. // A BaseBlock struct implements the Node interface partially.
type BaseBlock struct { type BaseBlock struct {
BaseNode BaseNode
blankPreviousLines bool blankPreviousLines bool
@ -265,7 +265,7 @@ type FencedCodeBlock struct {
language []byte language []byte
} }
// Language returns an language in an info string. // Language returns a language in an info string.
// Language returns nil if this node does not have an info string. // Language returns nil if this node does not have an info string.
func (n *FencedCodeBlock) Language(source []byte) []byte { func (n *FencedCodeBlock) Language(source []byte) []byte {
if n.language == nil && n.Info != nil { if n.language == nil && n.Info != nil {

View file

@ -8,7 +8,7 @@ import (
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )
// A BaseInline struct implements the Node interface partialliy. // A BaseInline struct implements the Node interface partially.
type BaseInline struct { type BaseInline struct {
BaseNode BaseNode
} }
@ -378,9 +378,10 @@ type Link struct {
// Dump implements Node.Dump. // Dump implements Node.Dump.
func (n *Link) Dump(source []byte, level int) { func (n *Link) Dump(source []byte, level int) {
m := map[string]string{} m := map[string]string{
m["Destination"] = string(n.Destination) "Destination": string(n.Destination),
m["Title"] = string(n.Title) "Title": string(n.Title),
}
DumpHelper(n, source, level, m, nil) DumpHelper(n, source, level, m, nil)
} }
@ -409,9 +410,10 @@ type Image struct {
// Dump implements Node.Dump. // Dump implements Node.Dump.
func (n *Image) Dump(source []byte, level int) { func (n *Image) Dump(source []byte, level int) {
m := map[string]string{} m := map[string]string{
m["Destination"] = string(n.Destination) "Destination": string(n.Destination),
m["Title"] = string(n.Title) "Title": string(n.Title),
}
DumpHelper(n, source, level, m, nil) DumpHelper(n, source, level, m, nil)
} }
@ -522,13 +524,14 @@ func (n *RawHTML) Inline() {}
// Dump implements Node.Dump. // Dump implements Node.Dump.
func (n *RawHTML) Dump(source []byte, level int) { func (n *RawHTML) Dump(source []byte, level int) {
m := map[string]string{} var t []string
t := []string{}
for i := 0; i < n.Segments.Len(); i++ { for i := 0; i < n.Segments.Len(); i++ {
segment := n.Segments.At(i) segment := n.Segments.At(i)
t = append(t, string(segment.Value(source))) t = append(t, string(segment.Value(source)))
} }
m["RawText"] = strings.Join(t, "") m := map[string]string{
"RawText": strings.Join(t, ""),
}
DumpHelper(n, source, level, m, nil) DumpHelper(n, source, level, m, nil)
} }

View file

@ -28,7 +28,7 @@ func TestSpec(t *testing.T) {
if err := json.Unmarshal(bs, &testCases); err != nil { if err := json.Unmarshal(bs, &testCases); err != nil {
panic(err) panic(err)
} }
cases := []testutil.MarkdownTestCase{} var cases []testutil.MarkdownTestCase
nos := testutil.ParseCliCaseArg() nos := testutil.ParseCliCaseArg()
for _, c := range testCases { for _, c := range testCases {
shouldAdd := len(nos) == 0 shouldAdd := len(nos) == 0

View file

@ -1,13 +1,14 @@
// Package goldmark implements functions to convert markdown text to a desired format. // Package goldmark implements functions to convert Markdown text to a desired format.
package goldmark package goldmark
import ( import (
"io"
"github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer" "github.com/yuin/goldmark/renderer"
"github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/text" "github.com/yuin/goldmark/text"
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
"io"
) )
// DefaultParser returns a new Parser that is configured by default values. // DefaultParser returns a new Parser that is configured by default values.
@ -44,7 +45,7 @@ type Markdown interface {
// SetParser sets a Parser to this object. // SetParser sets a Parser to this object.
SetParser(parser.Parser) SetParser(parser.Parser)
// Parser returns a Renderer that will be used for conversion. // Renderer returns a Renderer that will be used for conversion.
Renderer() renderer.Renderer Renderer() renderer.Renderer
// SetRenderer sets a Renderer to this object. // SetRenderer sets a Renderer to this object.

View file

@ -170,7 +170,7 @@ func parseAttributeValue(reader text.Reader) (interface{}, bool) {
func parseAttributeArray(reader text.Reader) ([]interface{}, bool) { func parseAttributeArray(reader text.Reader) ([]interface{}, bool) {
reader.Advance(1) // skip [ reader.Advance(1) // skip [
ret := []interface{}{} var ret []interface{}
for i := 0; ; i++ { for i := 0; ; i++ {
c := reader.Peek() c := reader.Peek()
comma := false comma := false
@ -243,11 +243,10 @@ func parseAttributeString(reader text.Reader) ([]byte, bool) {
func scanAttributeDecimal(reader text.Reader, w io.ByteWriter) { func scanAttributeDecimal(reader text.Reader, w io.ByteWriter) {
for { for {
c := reader.Peek() c := reader.Peek()
if util.IsNumeric(c) { if !util.IsNumeric(c) {
w.WriteByte(c)
} else {
return return
} }
w.WriteByte(c)
reader.Advance(1) reader.Advance(1)
} }
} }

View file

@ -6,8 +6,7 @@ import (
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )
type autoLinkParser struct { type autoLinkParser struct{}
}
var defaultAutoLinkParser = &autoLinkParser{} var defaultAutoLinkParser = &autoLinkParser{}

View file

@ -6,13 +6,11 @@ import (
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )
type blockquoteParser struct { type blockquoteParser struct{}
}
var defaultBlockquoteParser = &blockquoteParser{} var defaultBlockquoteParser = &blockquoteParser{}
// NewBlockquoteParser returns a new BlockParser that // NewBlockquoteParser returns a new BlockParser that parses blockquotes.
// parses blockquotes.
func NewBlockquoteParser() BlockParser { func NewBlockquoteParser() BlockParser {
return defaultBlockquoteParser return defaultBlockquoteParser
} }

View file

@ -6,14 +6,12 @@ import (
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )
type codeBlockParser struct { type codeBlockParser struct{}
}
// CodeBlockParser is a BlockParser implementation that parses indented code blocks. // CodeBlockParser is a BlockParser implementation that parses indented code blocks.
var defaultCodeBlockParser = &codeBlockParser{} var defaultCodeBlockParser = &codeBlockParser{}
// NewCodeBlockParser returns a new BlockParser that // NewCodeBlockParser returns a new BlockParser that parses code blocks.
// parses code blocks.
func NewCodeBlockParser() BlockParser { func NewCodeBlockParser() BlockParser {
return defaultCodeBlockParser return defaultCodeBlockParser
} }

View file

@ -5,8 +5,7 @@ import (
"github.com/yuin/goldmark/text" "github.com/yuin/goldmark/text"
) )
type codeSpanParser struct { type codeSpanParser struct{}
}
var defaultCodeSpanParser = &codeSpanParser{} var defaultCodeSpanParser = &codeSpanParser{}

View file

@ -9,8 +9,7 @@ import (
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )
// A DelimiterProcessor interface provides a set of functions about // A DelimiterProcessor interface provides a set of functions about Delimiter nodes.
// Delimiter nodes.
type DelimiterProcessor interface { type DelimiterProcessor interface {
// IsDelimiter returns true if given character is a delimiter, otherwise false. // IsDelimiter returns true if given character is a delimiter, otherwise false.
IsDelimiter(byte) bool IsDelimiter(byte) bool
@ -82,9 +81,9 @@ func (d *Delimiter) ConsumeCharacters(n int) {
d.Segment = d.Segment.WithStop(d.Segment.Start + d.Length) d.Segment = d.Segment.WithStop(d.Segment.Start + d.Length)
} }
// CalcComsumption calculates how many characters should be used for opening // CalcConsumption calculates how many characters should be used for opening
// a new span correspond to given closer. // a new span correspond to given closer.
func (d *Delimiter) CalcComsumption(closer *Delimiter) int { func (d *Delimiter) CalcConsumption(closer *Delimiter) int {
if (d.CanClose || closer.CanOpen) && (d.OriginalLength+closer.OriginalLength)%3 == 0 && closer.OriginalLength%3 != 0 { if (d.CanClose || closer.CanOpen) && (d.OriginalLength+closer.OriginalLength)%3 == 0 && closer.OriginalLength%3 != 0 {
return 0 return 0
} }
@ -150,7 +149,7 @@ func ScanDelimiter(line []byte, before rune, min int, processor DelimiterProcess
} }
// ProcessDelimiters processes the delimiter list in the context. // ProcessDelimiters processes the delimiter list in the context.
// Processing will be stop when reaching the bottom. // Processing will stop when reaching the bottom.
// //
// If you implement an inline parser that can have other inline nodes as // If you implement an inline parser that can have other inline nodes as
// children, you should call this function when nesting span has closed. // children, you should call this function when nesting span has closed.
@ -188,7 +187,7 @@ func ProcessDelimiters(bottom ast.Node, pc Context) {
for opener = closer.PreviousDelimiter; opener != nil && opener != bottom; opener = opener.PreviousDelimiter { for opener = closer.PreviousDelimiter; opener != nil && opener != bottom; opener = opener.PreviousDelimiter {
if opener.CanOpen && opener.Processor.CanOpenCloser(opener, closer) { if opener.CanOpen && opener.Processor.CanOpenCloser(opener, closer) {
maybeOpener = true maybeOpener = true
consume = opener.CalcComsumption(closer) consume = opener.CalcConsumption(closer)
if consume > 0 { if consume > 0 {
found = true found = true
break break

View file

@ -5,8 +5,7 @@ import (
"github.com/yuin/goldmark/text" "github.com/yuin/goldmark/text"
) )
type emphasisDelimiterProcessor struct { type emphasisDelimiterProcessor struct{}
}
func (p *emphasisDelimiterProcessor) IsDelimiter(b byte) bool { func (p *emphasisDelimiterProcessor) IsDelimiter(b byte) bool {
return b == '*' || b == '_' return b == '*' || b == '_'
@ -22,8 +21,7 @@ func (p *emphasisDelimiterProcessor) OnMatch(consumes int) ast.Node {
var defaultEmphasisDelimiterProcessor = &emphasisDelimiterProcessor{} var defaultEmphasisDelimiterProcessor = &emphasisDelimiterProcessor{}
type emphasisParser struct { type emphasisParser struct{}
}
var defaultEmphasisParser = &emphasisParser{} var defaultEmphasisParser = &emphasisParser{}

View file

@ -8,13 +8,11 @@ import (
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )
type fencedCodeBlockParser struct { type fencedCodeBlockParser struct{}
}
var defaultFencedCodeBlockParser = &fencedCodeBlockParser{} var defaultFencedCodeBlockParser = &fencedCodeBlockParser{}
// NewFencedCodeBlockParser returns a new BlockParser that // NewFencedCodeBlockParser returns a new BlockParser that parses fenced code blocks.
// parses fenced code blocks.
func NewFencedCodeBlockParser() BlockParser { func NewFencedCodeBlockParser() BlockParser {
return defaultFencedCodeBlockParser return defaultFencedCodeBlockParser
} }

View file

@ -100,8 +100,7 @@ type htmlBlockParser struct {
var defaultHTMLBlockParser = &htmlBlockParser{} var defaultHTMLBlockParser = &htmlBlockParser{}
// NewHTMLBlockParser return a new BlockParser that can parse html // NewHTMLBlockParser return a new BlockParser that can parse html blocks.
// blocks.
func NewHTMLBlockParser() BlockParser { func NewHTMLBlockParser() BlockParser {
return defaultHTMLBlockParser return defaultHTMLBlockParser
} }

View file

@ -105,8 +105,7 @@ func removeLinkLabelState(pc Context, d *linkLabelState) {
d.Last = nil d.Last = nil
} }
type linkParser struct { type linkParser struct{}
}
var defaultLinkParser = &linkParser{} var defaultLinkParser = &linkParser{}
@ -244,7 +243,7 @@ func (s *linkParser) processLinkLabel(parent ast.Node, link *ast.Link, last *lin
} }
} }
var linkFindClosureOptions text.FindClosureOptions = text.FindClosureOptions{ var linkFindClosureOptions = text.FindClosureOptions{
Nesting: false, Nesting: false,
Newline: true, Newline: true,
Advance: true, Advance: true,

View file

@ -16,7 +16,7 @@ var LinkReferenceParagraphTransformer = &linkReferenceParagraphTransformer{}
func (p *linkReferenceParagraphTransformer) Transform(node *ast.Paragraph, reader text.Reader, pc Context) { func (p *linkReferenceParagraphTransformer) Transform(node *ast.Paragraph, reader text.Reader, pc Context) {
lines := node.Lines() lines := node.Lines()
block := text.NewBlockReader(reader.Source(), lines) block := text.NewBlockReader(reader.Source(), lines)
removes := [][2]int{} var removes [][2]int
for { for {
start, end := parseLinkReferenceDefinition(block, pc) start, end := parseLinkReferenceDefinition(block, pc)
if start > -1 { if start > -1 {

View file

@ -109,13 +109,11 @@ func lastOffset(node ast.Node) int {
return 0 return 0
} }
type listParser struct { type listParser struct{}
}
var defaultListParser = &listParser{} var defaultListParser = &listParser{}
// NewListParser returns a new BlockParser that // NewListParser returns a new BlockParser that parses lists.
// parses lists.
// This parser must take precedence over the ListItemParser. // This parser must take precedence over the ListItemParser.
func NewListParser() BlockParser { func NewListParser() BlockParser {
return defaultListParser return defaultListParser
@ -147,7 +145,7 @@ func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.
if typ == orderedList && start != 1 { if typ == orderedList && start != 1 {
return nil, NoChildren return nil, NoChildren
} }
//an empty list item cannot interrupt a paragraph: // an empty list item cannot interrupt a paragraph:
if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) { if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) {
return nil, NoChildren return nil, NoChildren
} }

View file

@ -6,13 +6,11 @@ import (
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )
type listItemParser struct { type listItemParser struct{}
}
var defaultListItemParser = &listItemParser{} var defaultListItemParser = &listItemParser{}
// NewListItemParser returns a new BlockParser that // NewListItemParser returns a new BlockParser that parses list items.
// parses list items.
func NewListItemParser() BlockParser { func NewListItemParser() BlockParser {
return defaultListItemParser return defaultListItemParser
} }

View file

@ -10,8 +10,7 @@ type paragraphParser struct {
var defaultParagraphParser = &paragraphParser{} var defaultParagraphParser = &paragraphParser{}
// NewParagraphParser returns a new BlockParser that // NewParagraphParser returns a new BlockParser that parses paragraphs.
// parses paragraphs.
func NewParagraphParser() BlockParser { func NewParagraphParser() BlockParser {
return defaultParagraphParser return defaultParagraphParser
} }

View file

@ -75,7 +75,7 @@ func newIDs() IDs {
func (s *ids) Generate(value []byte, kind ast.NodeKind) []byte { func (s *ids) Generate(value []byte, kind ast.NodeKind) []byte {
value = util.TrimLeftSpace(value) value = util.TrimLeftSpace(value)
value = util.TrimRightSpace(value) value = util.TrimRightSpace(value)
result := []byte{} var result []byte
for i := 0; i < len(value); { for i := 0; i < len(value); {
v := value[i] v := value[i]
l := util.UTF8Len(v) l := util.UTF8Len(v)
@ -162,7 +162,7 @@ type Context interface {
// BlockOffset returns -1 if current line is blank. // BlockOffset returns -1 if current line is blank.
BlockOffset() int BlockOffset() int
// BlockOffset sets a first non-space character position on current line. // SetBlockOffset sets a first non-space character position on current line.
// This value is valid only for BlockParser.Open. // This value is valid only for BlockParser.Open.
SetBlockOffset(int) SetBlockOffset(int)
@ -171,7 +171,7 @@ type Context interface {
// BlockIndent returns -1 if current line is blank. // BlockIndent returns -1 if current line is blank.
BlockIndent() int BlockIndent() int
// BlockIndent sets an indent width on current line. // SetBlockIndent sets an indent width on current line.
// This value is valid only for BlockParser.Open. // This value is valid only for BlockParser.Open.
SetBlockIndent(int) SetBlockIndent(int)
@ -370,7 +370,7 @@ func (p *parseContext) References() []Reference {
} }
func (p *parseContext) String() string { func (p *parseContext) String() string {
refs := []string{} var refs []string
for _, r := range p.refs { for _, r := range p.refs {
refs = append(refs, r.String()) refs = append(refs, r.String())
} }
@ -451,11 +451,10 @@ type Option interface {
// OptionName is a name of parser options. // OptionName is a name of parser options.
type OptionName string type OptionName string
// Attribute is an option name that spacify attributes of elements. // Attribute is an option name that specifies attributes of elements.
const optAttribute OptionName = "Attribute" const optAttribute OptionName = "Attribute"
type withAttribute struct { type withAttribute struct{}
}
func (o *withAttribute) SetParserOption(c *Config) { func (o *withAttribute) SetParserOption(c *Config) {
c.Options[optAttribute] = true c.Options[optAttribute] = true
@ -471,7 +470,7 @@ type Parser interface {
// Parse parses the given Markdown text into AST nodes. // Parse parses the given Markdown text into AST nodes.
Parse(reader text.Reader, opts ...ParseOption) ast.Node Parse(reader text.Reader, opts ...ParseOption) ast.Node
// AddOption adds the given option to this parser. // AddOptions adds the given option to this parser.
AddOptions(...Option) AddOptions(...Option)
} }
@ -499,7 +498,7 @@ type BlockParser interface {
// //
// If Open has not been able to parse the current line, Open should returns // If Open has not been able to parse the current line, Open should returns
// (nil, NoChildren). If Open has been able to parse the current line, Open // (nil, NoChildren). If Open has been able to parse the current line, Open
// should returns a new Block node and returns HasChildren or NoChildren. // should return a new Block node and returns HasChildren or NoChildren.
Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State)
// Continue parses the current line and returns a result of parsing. // Continue parses the current line and returns a result of parsing.
@ -509,9 +508,8 @@ type BlockParser interface {
// a reader position by consumed byte length. // a reader position by consumed byte length.
// //
// If Continue has not been able to parse the current line, Continue should // If Continue has not been able to parse the current line, Continue should
// returns Close. If Continue has been able to parse the current line, // return Close. If Continue has been able to parse the current line,
// Continue should returns (Continue | NoChildren) or // Continue should return (Continue | NoChildren) or (Continue | HasChildren)
// (Continue | HasChildren)
Continue(node ast.Node, reader text.Reader, pc Context) State Continue(node ast.Node, reader text.Reader, pc Context) State
// Close will be called when the parser returns Close. // Close will be called when the parser returns Close.
@ -535,7 +533,7 @@ type InlineParser interface {
// a head of line // a head of line
Trigger() []byte Trigger() []byte
// Parse parse the given block into an inline node. // Parse parses the given block into an inline node.
// //
// Parse can parse beyond the current line. // Parse can parse beyond the current line.
// If Parse has been able to parse the current line, it must advance a reader // If Parse has been able to parse the current line, it must advance a reader
@ -907,7 +905,7 @@ const (
) )
func (p *parser) openBlocks(parent ast.Node, blankLine bool, reader text.Reader, pc Context) blockOpenResult { func (p *parser) openBlocks(parent ast.Node, blankLine bool, reader text.Reader, pc Context) blockOpenResult {
result := blockOpenResult(noBlocksOpened) result := noBlocksOpened
continuable := false continuable := false
lastBlock := pc.LastOpenedBlock() lastBlock := pc.LastOpenedBlock()
if lastBlock.Node != nil { if lastBlock.Node != nil {

View file

@ -14,8 +14,7 @@ type rawHTMLParser struct {
var defaultRawHTMLParser = &rawHTMLParser{} var defaultRawHTMLParser = &rawHTMLParser{}
// NewRawHTMLParser return a new InlineParser that can parse // NewRawHTMLParser return a new InlineParser that can parse inline htmls
// inline htmls
func NewRawHTMLParser() InlineParser { func NewRawHTMLParser() InlineParser {
return defaultRawHTMLParser return defaultRawHTMLParser
} }
@ -153,9 +152,8 @@ func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Read
if l == eline { if l == eline {
block.Advance(end - start) block.Advance(end - start)
break break
} else {
block.AdvanceLine()
} }
block.AdvanceLine()
} }
return node return node
} }

View file

@ -6,15 +6,13 @@ import (
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )
type thematicBreakPraser struct { type thematicBreakParser struct{}
}
var defaultThematicBreakPraser = &thematicBreakPraser{} var defaultThematicBreakParser = &thematicBreakParser{}
// NewThematicBreakParser returns a new BlockParser that // NewThematicBreakParser returns a new BlockParser that parses thematic breaks.
// parses thematic breaks.
func NewThematicBreakParser() BlockParser { func NewThematicBreakParser() BlockParser {
return defaultThematicBreakPraser return defaultThematicBreakParser
} }
func isThematicBreak(line []byte, offset int) bool { func isThematicBreak(line []byte, offset int) bool {
@ -45,11 +43,11 @@ func isThematicBreak(line []byte, offset int) bool {
return count > 2 return count > 2
} }
func (b *thematicBreakPraser) Trigger() []byte { func (b *thematicBreakParser) Trigger() []byte {
return []byte{'-', '*', '_'} return []byte{'-', '*', '_'}
} }
func (b *thematicBreakPraser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { func (b *thematicBreakParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) {
line, segment := reader.PeekLine() line, segment := reader.PeekLine()
if isThematicBreak(line, reader.LineOffset()) { if isThematicBreak(line, reader.LineOffset()) {
reader.Advance(segment.Len() - 1) reader.Advance(segment.Len() - 1)
@ -58,18 +56,18 @@ func (b *thematicBreakPraser) Open(parent ast.Node, reader text.Reader, pc Conte
return nil, NoChildren return nil, NoChildren
} }
func (b *thematicBreakPraser) Continue(node ast.Node, reader text.Reader, pc Context) State { func (b *thematicBreakParser) Continue(node ast.Node, reader text.Reader, pc Context) State {
return Close return Close
} }
func (b *thematicBreakPraser) Close(node ast.Node, reader text.Reader, pc Context) { func (b *thematicBreakParser) Close(node ast.Node, reader text.Reader, pc Context) {
// nothing to do // nothing to do
} }
func (b *thematicBreakPraser) CanInterruptParagraph() bool { func (b *thematicBreakParser) CanInterruptParagraph() bool {
return true return true
} }
func (b *thematicBreakPraser) CanAcceptIndentedLine() bool { func (b *thematicBreakParser) CanAcceptIndentedLine() bool {
return false return false
} }

View file

@ -97,8 +97,7 @@ func WithHardWraps() interface {
// XHTML is an option name used in WithXHTML. // XHTML is an option name used in WithXHTML.
const optXHTML renderer.OptionName = "XHTML" const optXHTML renderer.OptionName = "XHTML"
type withXHTML struct { type withXHTML struct{}
}
func (o *withXHTML) SetConfig(c *renderer.Config) { func (o *withXHTML) SetConfig(c *renderer.Config) {
c.Options[optXHTML] = true c.Options[optXHTML] = true
@ -683,8 +682,7 @@ type Writer interface {
var replacementCharacter = []byte("\ufffd") var replacementCharacter = []byte("\ufffd")
type defaultWriter struct { type defaultWriter struct{}
}
func escapeRune(writer util.BufWriter, r rune) { func escapeRune(writer util.BufWriter, r rune) {
if r < 256 { if r < 256 {

View file

@ -74,7 +74,7 @@ type NodeRendererFunc func(writer util.BufWriter, source []byte, n ast.Node, ent
// A NodeRenderer interface offers NodeRendererFuncs. // A NodeRenderer interface offers NodeRendererFuncs.
type NodeRenderer interface { type NodeRenderer interface {
// RendererFuncs registers NodeRendererFuncs to given NodeRendererFuncRegisterer. // RegisterFuncs registers NodeRendererFuncs to given NodeRendererFuncRegisterer.
RegisterFuncs(NodeRendererFuncRegisterer) RegisterFuncs(NodeRendererFuncRegisterer)
} }

View file

@ -65,11 +65,11 @@ type MarkdownTestCaseOptions struct {
const attributeSeparator = "//- - - - - - - - -//" const attributeSeparator = "//- - - - - - - - -//"
const caseSeparator = "//= = = = = = = = = = = = = = = = = = = = = = = =//" const caseSeparator = "//= = = = = = = = = = = = = = = = = = = = = = = =//"
var optionsRegexp *regexp.Regexp = regexp.MustCompile(`(?i)\s*options:(.*)`) var optionsRegexp = regexp.MustCompile(`(?i)\s*options:(.*)`)
// ParseCliCaseArg parses -case command line args. // ParseCliCaseArg parses -case command line args.
func ParseCliCaseArg() []int { func ParseCliCaseArg() []int {
ret := []int{} var ret []int
for _, a := range os.Args { for _, a := range os.Args {
if strings.HasPrefix(a, "case=") { if strings.HasPrefix(a, "case=") {
parts := strings.Split(a, "=") parts := strings.Split(a, "=")
@ -100,7 +100,7 @@ func DoTestCaseFile(m goldmark.Markdown, filename string, t TestingT, no ...int)
Markdown: "", Markdown: "",
Expected: "", Expected: "",
} }
cases := []MarkdownTestCase{} var cases []MarkdownTestCase
line := 0 line := 0
for scanner.Scan() { for scanner.Scan() {
line++ line++
@ -135,7 +135,7 @@ func DoTestCaseFile(m goldmark.Markdown, filename string, t TestingT, no ...int)
if scanner.Text() != attributeSeparator { if scanner.Text() != attributeSeparator {
panic(fmt.Sprintf("%s: invalid separator '%s' at line %d", filename, scanner.Text(), line)) panic(fmt.Sprintf("%s: invalid separator '%s' at line %d", filename, scanner.Text(), line))
} }
buf := []string{} var buf []string
for scanner.Scan() { for scanner.Scan() {
line++ line++
text := scanner.Text() text := scanner.Text()
@ -290,7 +290,7 @@ func simpleDiffAux(v1lines, v2lines [][]byte) []diff {
overlap = newOverlap overlap = newOverlap
} }
if length == 0 { if length == 0 {
diffs := []diff{} var diffs []diff
if len(v1lines) != 0 { if len(v1lines) != 0 {
diffs = append(diffs, diff{diffRemoved, v1lines}) diffs = append(diffs, diff{diffRemoved, v1lines})
} }
@ -377,7 +377,7 @@ func applyEscapeSequence(b []byte) []byte {
} }
case 'u', 'U': case 'u', 'U':
if len(b) > i+2 { if len(b) > i+2 {
num := []byte{} var num []byte
for j := i + 2; j < len(b); j++ { for j := i + 2; j < len(b); j++ {
if util.IsHexDecimal(b[j]) { if util.IsHexDecimal(b[j]) {
num = append(num, b[j]) num = append(num, b[j])

View file

@ -61,14 +61,14 @@ type Reader interface {
// If it reaches EOF, returns false. // If it reaches EOF, returns false.
SkipSpaces() (Segment, int, bool) SkipSpaces() (Segment, int, bool)
// SkipSpaces skips blank lines and returns a non-blank line. // SkipBlankLines skips blank lines and returns a non-blank line.
// If it reaches EOF, returns false. // If it reaches EOF, returns false.
SkipBlankLines() (Segment, int, bool) SkipBlankLines() (Segment, int, bool)
// Match performs regular expression matching to current line. // Match performs regular expression matching to current line.
Match(reg *regexp.Regexp) bool Match(reg *regexp.Regexp) bool
// Match performs regular expression searching to current line. // FindSubMatch performs regular expression searching to current line.
FindSubMatch(reg *regexp.Regexp) [][]byte FindSubMatch(reg *regexp.Regexp) [][]byte
// FindClosure finds corresponding closure. // FindClosure finds corresponding closure.
@ -94,6 +94,7 @@ type FindClosureOptions struct {
Advance bool Advance bool
} }
// reader implements io.RuneReader interface
type reader struct { type reader struct {
source []byte source []byte
sourceLength int sourceLength int
@ -153,7 +154,6 @@ func (r *reader) PeekLine() ([]byte, Segment) {
return nil, r.pos return nil, r.pos
} }
// io.RuneReader interface
func (r *reader) ReadRune() (rune, int, error) { func (r *reader) ReadRune() (rune, int, error) {
return readRuneReader(r) return readRuneReader(r)
} }
@ -276,6 +276,7 @@ type BlockReader interface {
Reset(segment *Segments) Reset(segment *Segments)
} }
// blockReader implements io.RuneReader interface
type blockReader struct { type blockReader struct {
source []byte source []byte
segments *Segments segments *Segments
@ -353,21 +354,20 @@ func (r *blockReader) Value(seg Segment) []byte {
return ret return ret
} }
// io.RuneReader interface
func (r *blockReader) ReadRune() (rune, int, error) { func (r *blockReader) ReadRune() (rune, int, error) {
return readRuneReader(r) return readRuneReader(r)
} }
func (r *blockReader) PrecendingCharacter() rune { func (r *blockReader) PrecendingCharacter() rune {
if r.pos.Padding != 0 { if r.pos.Padding != 0 {
return rune(' ') return ' '
} }
if r.segments.Len() < 1 { if r.segments.Len() < 1 {
return rune('\n') return '\n'
} }
firstSegment := r.segments.At(0) firstSegment := r.segments.At(0)
if r.line == 0 && r.pos.Start <= firstSegment.Start { if r.line == 0 && r.pos.Start <= firstSegment.Start {
return rune('\n') return '\n'
} }
l := len(r.source) l := len(r.source)
i := r.pos.Start - 1 i := r.pos.Start - 1
@ -377,7 +377,7 @@ func (r *blockReader) PrecendingCharacter() rune {
} }
} }
if i < 0 || i >= l { if i < 0 || i >= l {
return rune('\n') return '\n'
} }
rn, _ := utf8.DecodeRune(r.source[i:]) rn, _ := utf8.DecodeRune(r.source[i:])
return rn return rn
@ -549,7 +549,7 @@ func findSubMatchReader(r Reader, reg *regexp.Regexp) [][]byte {
i += size i += size
runes = append(runes, r) runes = append(runes, r)
} }
result := [][]byte{} var result [][]byte
for i := 0; i < len(match); i += 2 { for i := 0; i < len(match); i += 2 {
result = append(result, []byte(string(runes[match[i]:match[i+1]]))) result = append(result, []byte(string(runes[match[i]:match[i+1]])))
} }

View file

@ -2,6 +2,7 @@ package text
import ( import (
"bytes" "bytes"
"github.com/yuin/goldmark/util" "github.com/yuin/goldmark/util"
) )

View file

@ -1,6 +1,6 @@
package util package util
// An HTML5Entity struct represents HTML5 entitites. // An HTML5Entity struct represents HTML5 entities.
type HTML5Entity struct { type HTML5Entity struct {
Name string Name string
CodePoints []int CodePoints []int

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@ import (
) )
// A CopyOnWriteBuffer is a byte buffer that copies buffer when // A CopyOnWriteBuffer is a byte buffer that copies buffer when
// it need to be changed. // it needs to be changed.
type CopyOnWriteBuffer struct { type CopyOnWriteBuffer struct {
buffer []byte buffer []byte
copied bool copied bool