1package parser
2
3import (
4 "bytes"
5
6 "github.com/gomarkdown/markdown/ast"
7)
8
9// returns aisde prefix length
10func (p *Parser) asidePrefix(data []byte) int {
11 i := 0
12 n := len(data)
13 for i < 3 && i < n && data[i] == ' ' {
14 i++
15 }
16 if i+1 < n && data[i] == 'A' && data[i+1] == '>' {
17 if i+2 < n && data[i+2] == ' ' {
18 return i + 3
19 }
20 return i + 2
21 }
22 return 0
23}
24
25// aside ends with at least one blank line
26// followed by something without a aside prefix
27func (p *Parser) terminateAside(data []byte, beg, end int) bool {
28 if p.isEmpty(data[beg:]) <= 0 {
29 return false
30 }
31 if end >= len(data) {
32 return true
33 }
34 return p.asidePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0
35}
36
37// parse a aside fragment
38func (p *Parser) aside(data []byte) int {
39 var raw bytes.Buffer
40 beg, end := 0, 0
41 // identical to quote
42 for beg < len(data) {
43 end = beg
44 // Step over whole lines, collecting them. While doing that, check for
45 // fenced code and if one's found, incorporate it altogether,
46 // irregardless of any contents inside it
47 for end < len(data) && data[end] != '\n' {
48 if p.extensions&FencedCode != 0 {
49 if i := p.fencedCodeBlock(data[end:], false); i > 0 {
50 // -1 to compensate for the extra end++ after the loop:
51 end += i - 1
52 break
53 }
54 }
55 end++
56 }
57 end = skipCharN(data, end, '\n', 1)
58 if pre := p.asidePrefix(data[beg:]); pre > 0 {
59 // skip the prefix
60 beg += pre
61 } else if p.terminateAside(data, beg, end) {
62 break
63 }
64 // this line is part of the aside
65 raw.Write(data[beg:end])
66 beg = end
67 }
68
69 block := p.addBlock(&ast.Aside{})
70 p.block(raw.Bytes())
71 p.finalize(block)
72 return end
73}