annotate vendor/github.com/russross/blackfriday/v2/block.go @ 82:1b27391363d1 draft

Add posthook examples Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Tue, 26 Mar 2024 02:14:25 +0000
parents 787b5ee0289d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
2 // Blackfriday Markdown Processor
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
3 // Available at http://github.com/russross/blackfriday
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
4 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
5 // Copyright © 2011 Russ Ross <russ@russross.com>.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6 // Distributed under the Simplified BSD License.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7 // See README.md for details.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 // Functions to parse block-level elements.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14 package blackfriday
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16 import (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17 "bytes"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 "html"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19 "regexp"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20 "strings"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21 "unicode"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24 const (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25 charEntity = "&(?:#x[a-f0-9]{1,8}|#[0-9]{1,8}|[a-z][a-z0-9]{1,31});"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 escapable = "[!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29 var (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 reBackslashOrAmp = regexp.MustCompile("[\\&]")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31 reEntityOrEscapedChar = regexp.MustCompile("(?i)\\\\" + escapable + "|" + charEntity)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 // Parse block-level data.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 // Note: this function and many that it calls assume that
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 // the input buffer ends with a newline.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37 func (p *Markdown) block(data []byte) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38 // this is called recursively: enforce a maximum depth
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 if p.nesting >= p.maxNesting {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42 p.nesting++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 // parse out one block-level construct at a time
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45 for len(data) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46 // prefixed heading:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48 // # Heading 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49 // ## Heading 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50 // ...
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51 // ###### Heading 6
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52 if p.isPrefixHeading(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 data = data[p.prefixHeading(data):]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57 // block of preformatted HTML:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 // <div>
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60 // ...
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 // </div>
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62 if data[0] == '<' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63 if i := p.html(data, true); i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64 data = data[i:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69 // title block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71 // % stuff
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 // % more stuff
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73 // % even more stuff
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74 if p.extensions&Titleblock != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 if data[0] == '%' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76 if i := p.titleBlock(data, true); i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77 data = data[i:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 // blank lines. note: returns the # of bytes to skip
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84 if i := p.isEmpty(data); i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85 data = data[i:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89 // indented code block:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
90 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
91 // func max(a, b int) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
92 // if a > b {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93 // return a
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94 // }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95 // return b
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96 // }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97 if p.codePrefix(data) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98 data = data[p.code(data):]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102 // fenced code block:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 // ``` go
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105 // func fact(n int) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 // if n <= 1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 // return n
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108 // }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109 // return n * fact(n-1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110 // }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111 // ```
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112 if p.extensions&FencedCode != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113 if i := p.fencedCodeBlock(data, true); i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114 data = data[i:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 // horizontal rule:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121 // ------
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 // or
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123 // ******
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 // or
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 // ______
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 if p.isHRule(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 p.addBlock(HorizontalRule, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 var i int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129 for i = 0; i < len(data) && data[i] != '\n'; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 data = data[i:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 // block quote:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137 // > A big quote I found somewhere
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138 // > on the web
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
139 if p.quotePrefix(data) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
140 data = data[p.quote(data):]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
141 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
142 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144 // table:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146 // Name | Age | Phone
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147 // ------|-----|---------
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
148 // Bob | 31 | 555-1234
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
149 // Alice | 27 | 555-4321
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
150 if p.extensions&Tables != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
151 if i := p.table(data); i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
152 data = data[i:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
153 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
154 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
155 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
156
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
157 // an itemized/unordered list:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
158 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
159 // * Item 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
160 // * Item 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
161 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
162 // also works with + or -
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
163 if p.uliPrefix(data) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
164 data = data[p.list(data, 0):]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
165 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
166 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
167
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
168 // a numbered/ordered list:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
169 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
170 // 1. Item 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
171 // 2. Item 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
172 if p.oliPrefix(data) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
173 data = data[p.list(data, ListTypeOrdered):]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
174 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
175 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
176
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
177 // definition lists:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
178 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
179 // Term 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
180 // : Definition a
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
181 // : Definition b
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
182 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
183 // Term 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
184 // : Definition c
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
185 if p.extensions&DefinitionLists != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
186 if p.dliPrefix(data) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
187 data = data[p.list(data, ListTypeDefinition):]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
188 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
189 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
190 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
191
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
192 // anything else must look like a normal paragraph
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
193 // note: this finds underlined headings, too
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
194 data = data[p.paragraph(data):]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
195 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
196
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
197 p.nesting--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
198 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
199
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
200 func (p *Markdown) addBlock(typ NodeType, content []byte) *Node {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
201 p.closeUnmatchedBlocks()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
202 container := p.addChild(typ, 0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
203 container.content = content
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
204 return container
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
205 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
206
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
207 func (p *Markdown) isPrefixHeading(data []byte) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
208 if data[0] != '#' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
209 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
210 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
211
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
212 if p.extensions&SpaceHeadings != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
213 level := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
214 for level < 6 && level < len(data) && data[level] == '#' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
215 level++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
216 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
217 if level == len(data) || data[level] != ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
218 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
219 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
220 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
221 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
222 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
223
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
224 func (p *Markdown) prefixHeading(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
225 level := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
226 for level < 6 && level < len(data) && data[level] == '#' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
227 level++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
228 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
229 i := skipChar(data, level, ' ')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
230 end := skipUntilChar(data, i, '\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
231 skip := end
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
232 id := ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
233 if p.extensions&HeadingIDs != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
234 j, k := 0, 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
235 // find start/end of heading id
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
236 for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
237 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
238 for k = j + 1; k < end && data[k] != '}'; k++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
239 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
240 // extract heading id iff found
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
241 if j < end && k < end {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
242 id = string(data[j+2 : k])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
243 end = j
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
244 skip = k + 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
245 for end > 0 && data[end-1] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
246 end--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
247 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
248 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
249 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
250 for end > 0 && data[end-1] == '#' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
251 if isBackslashEscaped(data, end-1) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
252 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
253 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
254 end--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
255 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
256 for end > 0 && data[end-1] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
257 end--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
258 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
259 if end > i {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
260 if id == "" && p.extensions&AutoHeadingIDs != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
261 id = SanitizedAnchorName(string(data[i:end]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
262 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
263 block := p.addBlock(Heading, data[i:end])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
264 block.HeadingID = id
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
265 block.Level = level
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
266 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
267 return skip
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
268 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
269
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
270 func (p *Markdown) isUnderlinedHeading(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
271 // test of level 1 heading
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
272 if data[0] == '=' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
273 i := skipChar(data, 1, '=')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
274 i = skipChar(data, i, ' ')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
275 if i < len(data) && data[i] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
276 return 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
277 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
278 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
279 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
280
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
281 // test of level 2 heading
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
282 if data[0] == '-' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
283 i := skipChar(data, 1, '-')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
284 i = skipChar(data, i, ' ')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
285 if i < len(data) && data[i] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
286 return 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
287 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
288 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
289 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
290
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
291 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
292 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
293
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
294 func (p *Markdown) titleBlock(data []byte, doRender bool) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
295 if data[0] != '%' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
296 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
297 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
298 splitData := bytes.Split(data, []byte("\n"))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
299 var i int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
300 for idx, b := range splitData {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
301 if !bytes.HasPrefix(b, []byte("%")) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
302 i = idx // - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
303 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
304 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
305 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
306
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
307 data = bytes.Join(splitData[0:i], []byte("\n"))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
308 consumed := len(data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
309 data = bytes.TrimPrefix(data, []byte("% "))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
310 data = bytes.Replace(data, []byte("\n% "), []byte("\n"), -1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
311 block := p.addBlock(Heading, data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
312 block.Level = 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
313 block.IsTitleblock = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
314
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
315 return consumed
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
316 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
317
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
318 func (p *Markdown) html(data []byte, doRender bool) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
319 var i, j int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
320
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
321 // identify the opening tag
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
322 if data[0] != '<' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
323 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
324 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
325 curtag, tagfound := p.htmlFindTag(data[1:])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
326
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
327 // handle special cases
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
328 if !tagfound {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
329 // check for an HTML comment
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
330 if size := p.htmlComment(data, doRender); size > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
331 return size
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
332 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
333
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
334 // check for an <hr> tag
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
335 if size := p.htmlHr(data, doRender); size > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
336 return size
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
337 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
338
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
339 // no special case recognized
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
340 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
341 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
342
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
343 // look for an unindented matching closing tag
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
344 // followed by a blank line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
345 found := false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
346 /*
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
347 closetag := []byte("\n</" + curtag + ">")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
348 j = len(curtag) + 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
349 for !found {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
350 // scan for a closing tag at the beginning of a line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
351 if skip := bytes.Index(data[j:], closetag); skip >= 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
352 j += skip + len(closetag)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
353 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
354 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
355 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
356
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
357 // see if it is the only thing on the line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
358 if skip := p.isEmpty(data[j:]); skip > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
359 // see if it is followed by a blank line/eof
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
360 j += skip
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
361 if j >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
362 found = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
363 i = j
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
364 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
365 if skip := p.isEmpty(data[j:]); skip > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
366 j += skip
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
367 found = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
368 i = j
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
369 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
370 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
371 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
372 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
373 */
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
374
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
375 // if not found, try a second pass looking for indented match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
376 // but not if tag is "ins" or "del" (following original Markdown.pl)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
377 if !found && curtag != "ins" && curtag != "del" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
378 i = 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
379 for i < len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
380 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
381 for i < len(data) && !(data[i-1] == '<' && data[i] == '/') {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
382 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
383 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
384
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
385 if i+2+len(curtag) >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
386 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
387 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
388
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
389 j = p.htmlFindEnd(curtag, data[i-1:])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
390
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
391 if j > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
392 i += j - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
393 found = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
394 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
395 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
396 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
397 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
398
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
399 if !found {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
400 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
401 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
402
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
403 // the end of the block has been found
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
404 if doRender {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
405 // trim newlines
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
406 end := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
407 for end > 0 && data[end-1] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
408 end--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
409 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
410 finalizeHTMLBlock(p.addBlock(HTMLBlock, data[:end]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
411 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
412
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
413 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
414 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
415
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
416 func finalizeHTMLBlock(block *Node) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
417 block.Literal = block.content
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
418 block.content = nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
419 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
420
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
421 // HTML comment, lax form
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
422 func (p *Markdown) htmlComment(data []byte, doRender bool) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
423 i := p.inlineHTMLComment(data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
424 // needs to end with a blank line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
425 if j := p.isEmpty(data[i:]); j > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
426 size := i + j
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
427 if doRender {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
428 // trim trailing newlines
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
429 end := size
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
430 for end > 0 && data[end-1] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
431 end--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
432 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
433 block := p.addBlock(HTMLBlock, data[:end])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
434 finalizeHTMLBlock(block)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
435 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
436 return size
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
437 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
438 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
439 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
440
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
441 // HR, which is the only self-closing block tag considered
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
442 func (p *Markdown) htmlHr(data []byte, doRender bool) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
443 if len(data) < 4 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
444 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
445 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
446 if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
447 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
448 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
449 if data[3] != ' ' && data[3] != '/' && data[3] != '>' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
450 // not an <hr> tag after all; at least not a valid one
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
451 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
452 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
453 i := 3
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
454 for i < len(data) && data[i] != '>' && data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
455 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
456 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
457 if i < len(data) && data[i] == '>' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
458 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
459 if j := p.isEmpty(data[i:]); j > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
460 size := i + j
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
461 if doRender {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
462 // trim newlines
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
463 end := size
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
464 for end > 0 && data[end-1] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
465 end--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
466 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
467 finalizeHTMLBlock(p.addBlock(HTMLBlock, data[:end]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
468 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
469 return size
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
470 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
471 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
472 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
473 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
474
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
475 func (p *Markdown) htmlFindTag(data []byte) (string, bool) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
476 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
477 for i < len(data) && isalnum(data[i]) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
478 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
479 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
480 key := string(data[:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
481 if _, ok := blockTags[key]; ok {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
482 return key, true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
483 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
484 return "", false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
485 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
486
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
487 func (p *Markdown) htmlFindEnd(tag string, data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
488 // assume data[0] == '<' && data[1] == '/' already tested
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
489 if tag == "hr" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
490 return 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
491 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
492 // check if tag is a match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
493 closetag := []byte("</" + tag + ">")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
494 if !bytes.HasPrefix(data, closetag) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
495 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
496 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
497 i := len(closetag)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
498
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
499 // check that the rest of the line is blank
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
500 skip := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
501 if skip = p.isEmpty(data[i:]); skip == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
502 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
503 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
504 i += skip
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
505 skip = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
506
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
507 if i >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
508 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
509 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
510
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
511 if p.extensions&LaxHTMLBlocks != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
512 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
513 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
514 if skip = p.isEmpty(data[i:]); skip == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
515 // following line must be blank
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
516 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
517 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
518
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
519 return i + skip
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
520 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
521
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
522 func (*Markdown) isEmpty(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
523 // it is okay to call isEmpty on an empty buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
524 if len(data) == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
525 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
526 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
527
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
528 var i int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
529 for i = 0; i < len(data) && data[i] != '\n'; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
530 if data[i] != ' ' && data[i] != '\t' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
531 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
532 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
533 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
534 if i < len(data) && data[i] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
535 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
536 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
537 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
538 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
539
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
540 func (*Markdown) isHRule(data []byte) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
541 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
542
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
543 // skip up to three spaces
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
544 for i < 3 && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
545 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
546 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
547
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
548 // look at the hrule char
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
549 if data[i] != '*' && data[i] != '-' && data[i] != '_' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
550 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
551 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
552 c := data[i]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
553
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
554 // the whole line must be the char or whitespace
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
555 n := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
556 for i < len(data) && data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
557 switch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
558 case data[i] == c:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
559 n++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
560 case data[i] != ' ':
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
561 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
562 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
563 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
564 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
565
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
566 return n >= 3
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
567 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
568
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
569 // isFenceLine checks if there's a fence line (e.g., ``` or ``` go) at the beginning of data,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
570 // and returns the end index if so, or 0 otherwise. It also returns the marker found.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
571 // If info is not nil, it gets set to the syntax specified in the fence line.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
572 func isFenceLine(data []byte, info *string, oldmarker string) (end int, marker string) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
573 i, size := 0, 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
574
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
575 // skip up to three spaces
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
576 for i < len(data) && i < 3 && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
577 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
578 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
579
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
580 // check for the marker characters: ~ or `
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
581 if i >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
582 return 0, ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
583 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
584 if data[i] != '~' && data[i] != '`' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
585 return 0, ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
586 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
587
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
588 c := data[i]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
589
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
590 // the whole line must be the same char or whitespace
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
591 for i < len(data) && data[i] == c {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
592 size++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
593 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
594 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
595
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
596 // the marker char must occur at least 3 times
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
597 if size < 3 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
598 return 0, ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
599 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
600 marker = string(data[i-size : i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
601
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
602 // if this is the end marker, it must match the beginning marker
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
603 if oldmarker != "" && marker != oldmarker {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
604 return 0, ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
605 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
606
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
607 // TODO(shurcooL): It's probably a good idea to simplify the 2 code paths here
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
608 // into one, always get the info string, and discard it if the caller doesn't care.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
609 if info != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
610 infoLength := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
611 i = skipChar(data, i, ' ')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
612
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
613 if i >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
614 if i == len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
615 return i, marker
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
616 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
617 return 0, ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
618 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
619
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
620 infoStart := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
621
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
622 if data[i] == '{' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
623 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
624 infoStart++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
625
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
626 for i < len(data) && data[i] != '}' && data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
627 infoLength++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
628 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
629 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
630
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
631 if i >= len(data) || data[i] != '}' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
632 return 0, ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
633 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
634
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
635 // strip all whitespace at the beginning and the end
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
636 // of the {} block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
637 for infoLength > 0 && isspace(data[infoStart]) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
638 infoStart++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
639 infoLength--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
640 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
641
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
642 for infoLength > 0 && isspace(data[infoStart+infoLength-1]) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
643 infoLength--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
644 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
645 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
646 i = skipChar(data, i, ' ')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
647 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
648 for i < len(data) && !isverticalspace(data[i]) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
649 infoLength++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
650 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
651 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
652 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
653
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
654 *info = strings.TrimSpace(string(data[infoStart : infoStart+infoLength]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
655 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
656
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
657 if i == len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
658 return i, marker
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
659 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
660 if i > len(data) || data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
661 return 0, ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
662 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
663 return i + 1, marker // Take newline into account.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
664 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
665
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
666 // fencedCodeBlock returns the end index if data contains a fenced code block at the beginning,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
667 // or 0 otherwise. It writes to out if doRender is true, otherwise it has no side effects.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
668 // If doRender is true, a final newline is mandatory to recognize the fenced code block.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
669 func (p *Markdown) fencedCodeBlock(data []byte, doRender bool) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
670 var info string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
671 beg, marker := isFenceLine(data, &info, "")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
672 if beg == 0 || beg >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
673 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
674 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
675 fenceLength := beg - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
676
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
677 var work bytes.Buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
678 work.Write([]byte(info))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
679 work.WriteByte('\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
680
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
681 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
682 // safe to assume beg < len(data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
683
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
684 // check for the end of the code block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
685 fenceEnd, _ := isFenceLine(data[beg:], nil, marker)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
686 if fenceEnd != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
687 beg += fenceEnd
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
688 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
689 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
690
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
691 // copy the current line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
692 end := skipUntilChar(data, beg, '\n') + 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
693
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
694 // did we reach the end of the buffer without a closing marker?
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
695 if end >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
696 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
697 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
698
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
699 // verbatim copy to the working buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
700 if doRender {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
701 work.Write(data[beg:end])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
702 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
703 beg = end
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
704 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
705
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
706 if doRender {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
707 block := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
708 block.IsFenced = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
709 block.FenceLength = fenceLength
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
710 finalizeCodeBlock(block)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
711 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
712
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
713 return beg
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
714 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
715
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
716 func unescapeChar(str []byte) []byte {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
717 if str[0] == '\\' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
718 return []byte{str[1]}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
719 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
720 return []byte(html.UnescapeString(string(str)))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
721 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
722
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
723 func unescapeString(str []byte) []byte {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
724 if reBackslashOrAmp.Match(str) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
725 return reEntityOrEscapedChar.ReplaceAllFunc(str, unescapeChar)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
726 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
727 return str
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
728 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
729
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
730 func finalizeCodeBlock(block *Node) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
731 if block.IsFenced {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
732 newlinePos := bytes.IndexByte(block.content, '\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
733 firstLine := block.content[:newlinePos]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
734 rest := block.content[newlinePos+1:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
735 block.Info = unescapeString(bytes.Trim(firstLine, "\n"))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
736 block.Literal = rest
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
737 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
738 block.Literal = block.content
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
739 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
740 block.content = nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
741 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
742
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
743 func (p *Markdown) table(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
744 table := p.addBlock(Table, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
745 i, columns := p.tableHeader(data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
746 if i == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
747 p.tip = table.Parent
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
748 table.Unlink()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
749 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
750 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
751
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
752 p.addBlock(TableBody, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
753
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
754 for i < len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
755 pipes, rowStart := 0, i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
756 for ; i < len(data) && data[i] != '\n'; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
757 if data[i] == '|' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
758 pipes++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
759 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
760 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
761
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
762 if pipes == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
763 i = rowStart
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
764 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
765 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
766
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
767 // include the newline in data sent to tableRow
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
768 if i < len(data) && data[i] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
769 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
770 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
771 p.tableRow(data[rowStart:i], columns, false)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
772 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
773
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
774 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
775 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
776
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
777 // check if the specified position is preceded by an odd number of backslashes
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
778 func isBackslashEscaped(data []byte, i int) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
779 backslashes := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
780 for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
781 backslashes++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
782 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
783 return backslashes&1 == 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
784 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
785
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
786 func (p *Markdown) tableHeader(data []byte) (size int, columns []CellAlignFlags) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
787 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
788 colCount := 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
789 for i = 0; i < len(data) && data[i] != '\n'; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
790 if data[i] == '|' && !isBackslashEscaped(data, i) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
791 colCount++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
792 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
793 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
794
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
795 // doesn't look like a table header
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
796 if colCount == 1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
797 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
798 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
799
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
800 // include the newline in the data sent to tableRow
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
801 j := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
802 if j < len(data) && data[j] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
803 j++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
804 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
805 header := data[:j]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
806
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
807 // column count ignores pipes at beginning or end of line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
808 if data[0] == '|' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
809 colCount--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
810 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
811 if i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
812 colCount--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
813 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
814
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
815 columns = make([]CellAlignFlags, colCount)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
816
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
817 // move on to the header underline
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
818 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
819 if i >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
820 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
821 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
822
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
823 if data[i] == '|' && !isBackslashEscaped(data, i) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
824 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
825 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
826 i = skipChar(data, i, ' ')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
827
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
828 // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
829 // and trailing | optional on last column
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
830 col := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
831 for i < len(data) && data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
832 dashes := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
833
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
834 if data[i] == ':' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
835 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
836 columns[col] |= TableAlignmentLeft
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
837 dashes++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
838 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
839 for i < len(data) && data[i] == '-' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
840 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
841 dashes++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
842 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
843 if i < len(data) && data[i] == ':' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
844 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
845 columns[col] |= TableAlignmentRight
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
846 dashes++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
847 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
848 for i < len(data) && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
849 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
850 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
851 if i == len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
852 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
853 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
854 // end of column test is messy
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
855 switch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
856 case dashes < 3:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
857 // not a valid column
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
858 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
859
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
860 case data[i] == '|' && !isBackslashEscaped(data, i):
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
861 // marker found, now skip past trailing whitespace
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
862 col++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
863 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
864 for i < len(data) && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
865 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
866 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
867
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
868 // trailing junk found after last column
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
869 if col >= colCount && i < len(data) && data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
870 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
871 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
872
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
873 case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
874 // something else found where marker was required
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
875 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
876
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
877 case data[i] == '\n':
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
878 // marker is optional for the last column
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
879 col++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
880
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
881 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
882 // trailing junk found after last column
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
883 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
884 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
885 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
886 if col != colCount {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
887 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
888 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
889
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
890 p.addBlock(TableHead, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
891 p.tableRow(header, columns, true)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
892 size = i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
893 if size < len(data) && data[size] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
894 size++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
895 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
896 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
897 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
898
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
899 func (p *Markdown) tableRow(data []byte, columns []CellAlignFlags, header bool) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
900 p.addBlock(TableRow, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
901 i, col := 0, 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
902
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
903 if data[i] == '|' && !isBackslashEscaped(data, i) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
904 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
905 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
906
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
907 for col = 0; col < len(columns) && i < len(data); col++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
908 for i < len(data) && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
909 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
910 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
911
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
912 cellStart := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
913
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
914 for i < len(data) && (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
915 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
916 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
917
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
918 cellEnd := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
919
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
920 // skip the end-of-cell marker, possibly taking us past end of buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
921 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
922
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
923 for cellEnd > cellStart && cellEnd-1 < len(data) && data[cellEnd-1] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
924 cellEnd--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
925 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
926
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
927 cell := p.addBlock(TableCell, data[cellStart:cellEnd])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
928 cell.IsHeader = header
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
929 cell.Align = columns[col]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
930 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
931
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
932 // pad it out with empty columns to get the right number
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
933 for ; col < len(columns); col++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
934 cell := p.addBlock(TableCell, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
935 cell.IsHeader = header
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
936 cell.Align = columns[col]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
937 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
938
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
939 // silently ignore rows with too many cells
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
940 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
941
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
942 // returns blockquote prefix length
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
943 func (p *Markdown) quotePrefix(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
944 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
945 for i < 3 && i < len(data) && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
946 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
947 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
948 if i < len(data) && data[i] == '>' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
949 if i+1 < len(data) && data[i+1] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
950 return i + 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
951 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
952 return i + 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
953 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
954 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
955 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
956
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
957 // blockquote ends with at least one blank line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
958 // followed by something without a blockquote prefix
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
959 func (p *Markdown) terminateBlockquote(data []byte, beg, end int) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
960 if p.isEmpty(data[beg:]) <= 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
961 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
962 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
963 if end >= len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
964 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
965 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
966 return p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
967 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
968
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
969 // parse a blockquote fragment
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
970 func (p *Markdown) quote(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
971 block := p.addBlock(BlockQuote, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
972 var raw bytes.Buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
973 beg, end := 0, 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
974 for beg < len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
975 end = beg
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
976 // Step over whole lines, collecting them. While doing that, check for
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
977 // fenced code and if one's found, incorporate it altogether,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
978 // irregardless of any contents inside it
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
979 for end < len(data) && data[end] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
980 if p.extensions&FencedCode != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
981 if i := p.fencedCodeBlock(data[end:], false); i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
982 // -1 to compensate for the extra end++ after the loop:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
983 end += i - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
984 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
985 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
986 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
987 end++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
988 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
989 if end < len(data) && data[end] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
990 end++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
991 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
992 if pre := p.quotePrefix(data[beg:]); pre > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
993 // skip the prefix
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
994 beg += pre
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
995 } else if p.terminateBlockquote(data, beg, end) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
996 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
997 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
998 // this line is part of the blockquote
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
999 raw.Write(data[beg:end])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1000 beg = end
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1001 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1002 p.block(raw.Bytes())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1003 p.finalize(block)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1004 return end
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1005 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1006
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1007 // returns prefix length for block code
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1008 func (p *Markdown) codePrefix(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1009 if len(data) >= 1 && data[0] == '\t' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1010 return 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1011 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1012 if len(data) >= 4 && data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1013 return 4
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1014 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1015 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1016 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1017
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1018 func (p *Markdown) code(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1019 var work bytes.Buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1020
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1021 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1022 for i < len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1023 beg := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1024 for i < len(data) && data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1025 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1026 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1027 if i < len(data) && data[i] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1028 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1029 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1030
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1031 blankline := p.isEmpty(data[beg:i]) > 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1032 if pre := p.codePrefix(data[beg:i]); pre > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1033 beg += pre
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1034 } else if !blankline {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1035 // non-empty, non-prefixed line breaks the pre
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1036 i = beg
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1037 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1038 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1039
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1040 // verbatim copy to the working buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1041 if blankline {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1042 work.WriteByte('\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1043 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1044 work.Write(data[beg:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1045 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1046 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1047
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1048 // trim all the \n off the end of work
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1049 workbytes := work.Bytes()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1050 eol := len(workbytes)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1051 for eol > 0 && workbytes[eol-1] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1052 eol--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1053 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1054 if eol != len(workbytes) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1055 work.Truncate(eol)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1056 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1057
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1058 work.WriteByte('\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1059
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1060 block := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1061 block.IsFenced = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1062 finalizeCodeBlock(block)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1063
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1064 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1065 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1066
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1067 // returns unordered list item prefix
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1068 func (p *Markdown) uliPrefix(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1069 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1070 // start with up to 3 spaces
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1071 for i < len(data) && i < 3 && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1072 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1073 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1074 if i >= len(data)-1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1075 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1076 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1077 // need one of {'*', '+', '-'} followed by a space or a tab
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1078 if (data[i] != '*' && data[i] != '+' && data[i] != '-') ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1079 (data[i+1] != ' ' && data[i+1] != '\t') {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1080 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1081 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1082 return i + 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1083 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1084
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1085 // returns ordered list item prefix
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1086 func (p *Markdown) oliPrefix(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1087 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1088
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1089 // start with up to 3 spaces
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1090 for i < 3 && i < len(data) && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1091 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1092 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1093
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1094 // count the digits
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1095 start := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1096 for i < len(data) && data[i] >= '0' && data[i] <= '9' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1097 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1098 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1099 if start == i || i >= len(data)-1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1100 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1101 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1102
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1103 // we need >= 1 digits followed by a dot and a space or a tab
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1104 if data[i] != '.' || !(data[i+1] == ' ' || data[i+1] == '\t') {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1105 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1106 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1107 return i + 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1108 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1109
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1110 // returns definition list item prefix
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1111 func (p *Markdown) dliPrefix(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1112 if len(data) < 2 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1113 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1114 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1115 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1116 // need a ':' followed by a space or a tab
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1117 if data[i] != ':' || !(data[i+1] == ' ' || data[i+1] == '\t') {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1118 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1119 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1120 for i < len(data) && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1121 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1122 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1123 return i + 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1124 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1125
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1126 // parse ordered or unordered list block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1127 func (p *Markdown) list(data []byte, flags ListType) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1128 i := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1129 flags |= ListItemBeginningOfList
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1130 block := p.addBlock(List, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1131 block.ListFlags = flags
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1132 block.Tight = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1133
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1134 for i < len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1135 skip := p.listItem(data[i:], &flags)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1136 if flags&ListItemContainsBlock != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1137 block.ListData.Tight = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1138 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1139 i += skip
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1140 if skip == 0 || flags&ListItemEndOfList != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1141 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1142 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1143 flags &= ^ListItemBeginningOfList
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1144 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1145
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1146 above := block.Parent
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1147 finalizeList(block)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1148 p.tip = above
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1149 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1150 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1151
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1152 // Returns true if the list item is not the same type as its parent list
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1153 func (p *Markdown) listTypeChanged(data []byte, flags *ListType) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1154 if p.dliPrefix(data) > 0 && *flags&ListTypeDefinition == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1155 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1156 } else if p.oliPrefix(data) > 0 && *flags&ListTypeOrdered == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1157 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1158 } else if p.uliPrefix(data) > 0 && (*flags&ListTypeOrdered != 0 || *flags&ListTypeDefinition != 0) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1159 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1160 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1161 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1162 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1163
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1164 // Returns true if block ends with a blank line, descending if needed
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1165 // into lists and sublists.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1166 func endsWithBlankLine(block *Node) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1167 // TODO: figure this out. Always false now.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1168 for block != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1169 //if block.lastLineBlank {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1170 //return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1171 //}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1172 t := block.Type
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1173 if t == List || t == Item {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1174 block = block.LastChild
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1175 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1176 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1177 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1178 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1179 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1180 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1181
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1182 func finalizeList(block *Node) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1183 block.open = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1184 item := block.FirstChild
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1185 for item != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1186 // check for non-final list item ending with blank line:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1187 if endsWithBlankLine(item) && item.Next != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1188 block.ListData.Tight = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1189 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1190 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1191 // recurse into children of list item, to see if there are spaces
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1192 // between any of them:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1193 subItem := item.FirstChild
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1194 for subItem != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1195 if endsWithBlankLine(subItem) && (item.Next != nil || subItem.Next != nil) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1196 block.ListData.Tight = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1197 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1198 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1199 subItem = subItem.Next
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1200 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1201 item = item.Next
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1202 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1203 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1204
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1205 // Parse a single list item.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1206 // Assumes initial prefix is already removed if this is a sublist.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1207 func (p *Markdown) listItem(data []byte, flags *ListType) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1208 // keep track of the indentation of the first line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1209 itemIndent := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1210 if data[0] == '\t' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1211 itemIndent += 4
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1212 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1213 for itemIndent < 3 && data[itemIndent] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1214 itemIndent++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1215 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1216 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1217
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1218 var bulletChar byte = '*'
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1219 i := p.uliPrefix(data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1220 if i == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1221 i = p.oliPrefix(data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1222 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1223 bulletChar = data[i-2]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1224 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1225 if i == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1226 i = p.dliPrefix(data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1227 // reset definition term flag
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1228 if i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1229 *flags &= ^ListTypeTerm
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1230 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1231 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1232 if i == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1233 // if in definition list, set term flag and continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1234 if *flags&ListTypeDefinition != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1235 *flags |= ListTypeTerm
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1236 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1237 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1238 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1239 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1240
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1241 // skip leading whitespace on first line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1242 for i < len(data) && data[i] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1243 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1244 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1245
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1246 // find the end of the line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1247 line := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1248 for i > 0 && i < len(data) && data[i-1] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1249 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1250 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1251
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1252 // get working buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1253 var raw bytes.Buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1254
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1255 // put the first line into the working buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1256 raw.Write(data[line:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1257 line = i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1258
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1259 // process the following lines
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1260 containsBlankLine := false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1261 sublist := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1262 codeBlockMarker := ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1263
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1264 gatherlines:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1265 for line < len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1266 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1267
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1268 // find the end of this line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1269 for i < len(data) && data[i-1] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1270 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1271 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1272
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1273 // if it is an empty line, guess that it is part of this item
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1274 // and move on to the next line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1275 if p.isEmpty(data[line:i]) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1276 containsBlankLine = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1277 line = i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1278 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1279 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1280
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1281 // calculate the indentation
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1282 indent := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1283 indentIndex := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1284 if data[line] == '\t' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1285 indentIndex++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1286 indent += 4
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1287 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1288 for indent < 4 && line+indent < i && data[line+indent] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1289 indent++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1290 indentIndex++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1291 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1292 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1293
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1294 chunk := data[line+indentIndex : i]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1295
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1296 if p.extensions&FencedCode != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1297 // determine if in or out of codeblock
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1298 // if in codeblock, ignore normal list processing
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1299 _, marker := isFenceLine(chunk, nil, codeBlockMarker)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1300 if marker != "" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1301 if codeBlockMarker == "" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1302 // start of codeblock
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1303 codeBlockMarker = marker
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1304 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1305 // end of codeblock.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1306 codeBlockMarker = ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1307 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1308 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1309 // we are in a codeblock, write line, and continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1310 if codeBlockMarker != "" || marker != "" {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1311 raw.Write(data[line+indentIndex : i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1312 line = i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1313 continue gatherlines
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1314 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1315 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1316
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1317 // evaluate how this line fits in
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1318 switch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1319 // is this a nested list item?
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1320 case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1321 p.oliPrefix(chunk) > 0 ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1322 p.dliPrefix(chunk) > 0:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1323
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1324 // to be a nested list, it must be indented more
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1325 // if not, it is either a different kind of list
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1326 // or the next item in the same list
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1327 if indent <= itemIndent {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1328 if p.listTypeChanged(chunk, flags) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1329 *flags |= ListItemEndOfList
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1330 } else if containsBlankLine {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1331 *flags |= ListItemContainsBlock
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1332 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1333
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1334 break gatherlines
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1335 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1336
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1337 if containsBlankLine {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1338 *flags |= ListItemContainsBlock
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1339 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1340
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1341 // is this the first item in the nested list?
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1342 if sublist == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1343 sublist = raw.Len()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1344 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1345
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1346 // is this a nested prefix heading?
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1347 case p.isPrefixHeading(chunk):
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1348 // if the heading is not indented, it is not nested in the list
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1349 // and thus ends the list
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1350 if containsBlankLine && indent < 4 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1351 *flags |= ListItemEndOfList
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1352 break gatherlines
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1353 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1354 *flags |= ListItemContainsBlock
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1355
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1356 // anything following an empty line is only part
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1357 // of this item if it is indented 4 spaces
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1358 // (regardless of the indentation of the beginning of the item)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1359 case containsBlankLine && indent < 4:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1360 if *flags&ListTypeDefinition != 0 && i < len(data)-1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1361 // is the next item still a part of this list?
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1362 next := i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1363 for next < len(data) && data[next] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1364 next++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1365 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1366 for next < len(data)-1 && data[next] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1367 next++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1368 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1369 if i < len(data)-1 && data[i] != ':' && data[next] != ':' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1370 *flags |= ListItemEndOfList
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1371 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1372 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1373 *flags |= ListItemEndOfList
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1374 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1375 break gatherlines
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1376
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1377 // a blank line means this should be parsed as a block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1378 case containsBlankLine:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1379 raw.WriteByte('\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1380 *flags |= ListItemContainsBlock
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1381 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1382
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1383 // if this line was preceded by one or more blanks,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1384 // re-introduce the blank into the buffer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1385 if containsBlankLine {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1386 containsBlankLine = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1387 raw.WriteByte('\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1388 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1389
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1390 // add the line into the working buffer without prefix
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1391 raw.Write(data[line+indentIndex : i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1392
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1393 line = i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1394 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1395
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1396 rawBytes := raw.Bytes()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1397
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1398 block := p.addBlock(Item, nil)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1399 block.ListFlags = *flags
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1400 block.Tight = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1401 block.BulletChar = bulletChar
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1402 block.Delimiter = '.' // Only '.' is possible in Markdown, but ')' will also be possible in CommonMark
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1403
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1404 // render the contents of the list item
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1405 if *flags&ListItemContainsBlock != 0 && *flags&ListTypeTerm == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1406 // intermediate render of block item, except for definition term
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1407 if sublist > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1408 p.block(rawBytes[:sublist])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1409 p.block(rawBytes[sublist:])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1410 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1411 p.block(rawBytes)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1412 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1413 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1414 // intermediate render of inline item
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1415 if sublist > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1416 child := p.addChild(Paragraph, 0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1417 child.content = rawBytes[:sublist]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1418 p.block(rawBytes[sublist:])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1419 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1420 child := p.addChild(Paragraph, 0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1421 child.content = rawBytes
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1422 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1423 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1424 return line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1425 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1426
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1427 // render a single paragraph that has already been parsed out
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1428 func (p *Markdown) renderParagraph(data []byte) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1429 if len(data) == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1430 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1431 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1432
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1433 // trim leading spaces
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1434 beg := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1435 for data[beg] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1436 beg++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1437 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1438
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1439 end := len(data)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1440 // trim trailing newline
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1441 if data[len(data)-1] == '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1442 end--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1443 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1444
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1445 // trim trailing spaces
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1446 for end > beg && data[end-1] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1447 end--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1448 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1449
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1450 p.addBlock(Paragraph, data[beg:end])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1451 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1452
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1453 func (p *Markdown) paragraph(data []byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1454 // prev: index of 1st char of previous line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1455 // line: index of 1st char of current line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1456 // i: index of cursor/end of current line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1457 var prev, line, i int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1458 tabSize := TabSizeDefault
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1459 if p.extensions&TabSizeEight != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1460 tabSize = TabSizeDouble
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1461 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1462 // keep going until we find something to mark the end of the paragraph
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1463 for i < len(data) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1464 // mark the beginning of the current line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1465 prev = line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1466 current := data[i:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1467 line = i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1468
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1469 // did we find a reference or a footnote? If so, end a paragraph
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1470 // preceding it and report that we have consumed up to the end of that
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1471 // reference:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1472 if refEnd := isReference(p, current, tabSize); refEnd > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1473 p.renderParagraph(data[:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1474 return i + refEnd
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1475 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1476
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1477 // did we find a blank line marking the end of the paragraph?
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1478 if n := p.isEmpty(current); n > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1479 // did this blank line followed by a definition list item?
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1480 if p.extensions&DefinitionLists != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1481 if i < len(data)-1 && data[i+1] == ':' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1482 return p.list(data[prev:], ListTypeDefinition)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1483 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1484 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1485
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1486 p.renderParagraph(data[:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1487 return i + n
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1488 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1489
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1490 // an underline under some text marks a heading, so our paragraph ended on prev line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1491 if i > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1492 if level := p.isUnderlinedHeading(current); level > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1493 // render the paragraph
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1494 p.renderParagraph(data[:prev])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1495
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1496 // ignore leading and trailing whitespace
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1497 eol := i - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1498 for prev < eol && data[prev] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1499 prev++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1500 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1501 for eol > prev && data[eol-1] == ' ' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1502 eol--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1503 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1504
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1505 id := ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1506 if p.extensions&AutoHeadingIDs != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1507 id = SanitizedAnchorName(string(data[prev:eol]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1508 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1509
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1510 block := p.addBlock(Heading, data[prev:eol])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1511 block.Level = level
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1512 block.HeadingID = id
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1513
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1514 // find the end of the underline
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1515 for i < len(data) && data[i] != '\n' {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1516 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1517 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1518 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1519 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1520 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1521
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1522 // if the next line starts a block of HTML, then the paragraph ends here
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1523 if p.extensions&LaxHTMLBlocks != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1524 if data[i] == '<' && p.html(current, false) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1525 // rewind to before the HTML block
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1526 p.renderParagraph(data[:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1527 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1528 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1529 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1530
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1531 // if there's a prefixed heading or a horizontal rule after this, paragraph is over
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1532 if p.isPrefixHeading(current) || p.isHRule(current) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1533 p.renderParagraph(data[:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1534 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1535 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1536
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1537 // if there's a fenced code block, paragraph is over
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1538 if p.extensions&FencedCode != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1539 if p.fencedCodeBlock(current, false) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1540 p.renderParagraph(data[:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1541 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1542 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1543 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1544
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1545 // if there's a definition list item, prev line is a definition term
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1546 if p.extensions&DefinitionLists != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1547 if p.dliPrefix(current) != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1548 ret := p.list(data[prev:], ListTypeDefinition)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1549 return ret
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1550 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1551 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1552
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1553 // if there's a list after this, paragraph is over
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1554 if p.extensions&NoEmptyLineBeforeBlock != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1555 if p.uliPrefix(current) != 0 ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1556 p.oliPrefix(current) != 0 ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1557 p.quotePrefix(current) != 0 ||
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1558 p.codePrefix(current) != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1559 p.renderParagraph(data[:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1560 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1561 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1562 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1563
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1564 // otherwise, scan to the beginning of the next line
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1565 nl := bytes.IndexByte(data[i:], '\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1566 if nl >= 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1567 i += nl + 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1568 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1569 i += len(data[i:])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1570 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1571 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1572
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1573 p.renderParagraph(data[:i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1574 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1575 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1576
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1577 func skipChar(data []byte, start int, char byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1578 i := start
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1579 for i < len(data) && data[i] == char {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1580 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1581 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1582 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1583 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1584
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1585 func skipUntilChar(text []byte, start int, char byte) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1586 i := start
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1587 for i < len(text) && text[i] != char {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1588 i++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1589 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1590 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1591 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1592
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1593 // SanitizedAnchorName returns a sanitized anchor name for the given text.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1594 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1595 // It implements the algorithm specified in the package comment.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1596 func SanitizedAnchorName(text string) string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1597 var anchorName []rune
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1598 futureDash := false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1599 for _, r := range text {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1600 switch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1601 case unicode.IsLetter(r) || unicode.IsNumber(r):
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1602 if futureDash && len(anchorName) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1603 anchorName = append(anchorName, '-')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1604 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1605 futureDash = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1606 anchorName = append(anchorName, unicode.ToLower(r))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1607 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1608 futureDash = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1609 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1610 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1611 return string(anchorName)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1612 }