blockquote.go

 1package parser
 2
 3import (
 4	"github.com/yuin/goldmark/ast"
 5	"github.com/yuin/goldmark/text"
 6	"github.com/yuin/goldmark/util"
 7)
 8
 9type blockquoteParser struct {
10}
11
12var defaultBlockquoteParser = &blockquoteParser{}
13
14// NewBlockquoteParser returns a new BlockParser that
15// parses blockquotes.
16func NewBlockquoteParser() BlockParser {
17	return defaultBlockquoteParser
18}
19
20func (b *blockquoteParser) process(reader text.Reader) bool {
21	line, _ := reader.PeekLine()
22	w, pos := util.IndentWidth(line, reader.LineOffset())
23	if w > 3 || pos >= len(line) || line[pos] != '>' {
24		return false
25	}
26	pos++
27	if pos >= len(line) || line[pos] == '\n' {
28		reader.Advance(pos)
29		return true
30	}
31	reader.Advance(pos)
32	if line[pos] == ' ' || line[pos] == '\t' {
33		padding := 0
34		if line[pos] == '\t' {
35			padding = util.TabWidth(reader.LineOffset()) - 1
36		}
37		reader.AdvanceAndSetPadding(1, padding)
38	}
39	return true
40}
41
42func (b *blockquoteParser) Trigger() []byte {
43	return []byte{'>'}
44}
45
46func (b *blockquoteParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) {
47	if b.process(reader) {
48		return ast.NewBlockquote(), HasChildren
49	}
50	return nil, NoChildren
51}
52
53func (b *blockquoteParser) Continue(node ast.Node, reader text.Reader, pc Context) State {
54	if b.process(reader) {
55		return Continue | HasChildren
56	}
57	return Close
58}
59
60func (b *blockquoteParser) Close(node ast.Node, reader text.Reader, pc Context) {
61	// nothing to do
62}
63
64func (b *blockquoteParser) CanInterruptParagraph() bool {
65	return true
66}
67
68func (b *blockquoteParser) CanAcceptIndentedLine() bool {
69	return false
70}