Markdown parser fork with extended syntax for personal use.
1use markdown::{
2 mdast::{Emphasis, List, ListItem, Node, Paragraph, Root, Text},
3 message, to_html, to_html_with_options, to_mdast,
4 unist::Position,
5 CompileOptions, Options, ParseOptions,
6};
7use pretty_assertions::assert_eq;
8
9#[test]
10fn gfm_task_list_item() -> Result<(), message::Message> {
11 assert_eq!(
12 to_html("* [x] y."),
13 "<ul>\n<li>[x] y.</li>\n</ul>",
14 "should ignore task list item checks by default"
15 );
16
17 assert_eq!(
18 to_html_with_options("* [x] y.", &Options::gfm())?,
19 "<ul>\n<li><input type=\"checkbox\" disabled=\"\" checked=\"\" /> y.</li>\n</ul>",
20 "should support task list item checks"
21 );
22
23 assert_eq!(
24 to_html_with_options("* [ ] z.", &Options::gfm())?,
25 "<ul>\n<li><input type=\"checkbox\" disabled=\"\" /> z.</li>\n</ul>",
26 "should support unchecked task list item checks"
27 );
28
29 assert_eq!(
30 to_html_with_options(
31 "* [x] y.",
32 &Options {
33 parse: ParseOptions::gfm(),
34 compile: CompileOptions {
35 gfm_task_list_item_checkable: true,
36 ..CompileOptions::gfm()
37 }
38 }
39 )?,
40 "<ul>\n<li><input type=\"checkbox\" checked=\"\" /> y.</li>\n</ul>",
41 "should support option for enabled (checkable) task list item checks"
42 );
43
44 assert_eq!(
45 to_html_with_options("*\n [x]", &Options::gfm())?,
46 "<ul>\n<li>[x]</li>\n</ul>",
47 "should not support laziness (1)"
48 );
49
50 assert_eq!(
51 to_html_with_options("*\n[x]", &Options::gfm())?,
52 "<ul>\n<li></li>\n</ul>\n<p>[x]</p>",
53 "should not support laziness (2)"
54 );
55
56 assert_eq!(
57 to_html_with_options(
58 &r###"
59* [ ] foo
60* [x] bar
61
62- [x] foo
63 - [ ] bar
64 - [x] baz
65- [ ] bim
66
67+ [ ] Unchecked?
68
69* [x] Checked?
70
71+ [y] What is this even?
72
73- [n]: #
74 [ ] After a definition
75
76+ [ ] In a setext heading
77 =======================
78
79* In the…
80
81 [ ] Second paragraph
82
83- [ ] With a tab
84
85+ [X] With an upper case `x`
86
87* [
88] In a lazy line
89
90- [ ] With two spaces
91
92+ [x] Two spaces indent
93
94* [x] Three spaces indent
95
96- [x] Four spaces indent
97
98+ [x] Five spaces indent
99
100[ ] here?
101
102* > [ ] here?
103
104- [ ]No space?
105
106Empty?
107
108+ [ ]
109
110Space after:
111
112+ [ ]␠
113
114* [ ]␠Text.
115
116Tab after:
117
118+ [ ]␉
119
120* [ ]␉Text.
121
122EOL after:
123
124+ [ ]
125
126* [ ]
127 Text.
128
129-
130 [ ] after blank?
131
132+ # [ ] ATX Heading
133
134> * [x] In a list in a block quote
135"###
136 .replace('␠', " ")
137 .replace('␉', "\t"),
138 &Options::gfm()
139 )?,
140 r#"<ul>
141<li><input type="checkbox" disabled="" /> foo</li>
142<li><input type="checkbox" disabled="" checked="" /> bar</li>
143</ul>
144<ul>
145<li><input type="checkbox" disabled="" checked="" /> foo
146<ul>
147<li><input type="checkbox" disabled="" /> bar</li>
148<li><input type="checkbox" disabled="" checked="" /> baz</li>
149</ul>
150</li>
151<li><input type="checkbox" disabled="" /> bim</li>
152</ul>
153<ul>
154<li><input type="checkbox" disabled="" /> Unchecked?</li>
155</ul>
156<ul>
157<li><input type="checkbox" disabled="" checked="" /> Checked?</li>
158</ul>
159<ul>
160<li>[y] What is this even?</li>
161</ul>
162<ul>
163<li><input type="checkbox" disabled="" /> After a definition</li>
164</ul>
165<ul>
166<li>
167<h1>[ ] In a setext heading</h1>
168</li>
169</ul>
170<ul>
171<li>
172<p>In the…</p>
173<p>[ ] Second paragraph</p>
174</li>
175</ul>
176<ul>
177<li><input type="checkbox" disabled="" /> With a tab</li>
178</ul>
179<ul>
180<li><input type="checkbox" disabled="" checked="" /> With an upper case <code>x</code></li>
181</ul>
182<ul>
183<li><input type="checkbox" disabled="" /> In a lazy line</li>
184</ul>
185<ul>
186<li>[ ] With two spaces</li>
187</ul>
188<ul>
189<li><input type="checkbox" disabled="" checked="" /> Two spaces indent</li>
190</ul>
191<ul>
192<li><input type="checkbox" disabled="" checked="" /> Three spaces indent</li>
193</ul>
194<ul>
195<li><input type="checkbox" disabled="" checked="" /> Four spaces indent</li>
196</ul>
197<ul>
198<li>
199<pre><code>[x] Five spaces indent
200</code></pre>
201</li>
202</ul>
203<p>[ ] here?</p>
204<ul>
205<li>
206<blockquote>
207<p>[ ] here?</p>
208</blockquote>
209</li>
210</ul>
211<ul>
212<li>[ ]No space?</li>
213</ul>
214<p>Empty?</p>
215<ul>
216<li>[ ]</li>
217</ul>
218<p>Space after:</p>
219<ul>
220<li>[ ]</li>
221</ul>
222<ul>
223<li><input type="checkbox" disabled="" /> Text.</li>
224</ul>
225<p>Tab after:</p>
226<ul>
227<li>[ ]</li>
228</ul>
229<ul>
230<li><input type="checkbox" disabled="" /> Text.</li>
231</ul>
232<p>EOL after:</p>
233<ul>
234<li>[ ]</li>
235</ul>
236<ul>
237<li><input type="checkbox" disabled="" />
238Text.</li>
239</ul>
240<ul>
241<li><input type="checkbox" disabled="" /> after blank?</li>
242</ul>
243<ul>
244<li>
245<h1>[ ] ATX Heading</h1>
246</li>
247</ul>
248<blockquote>
249<ul>
250<li><input type="checkbox" disabled="" checked="" /> In a list in a block quote</li>
251</ul>
252</blockquote>
253"#,
254 "should handle things like GitHub"
255 );
256
257 assert_eq!(
258 to_mdast("* [x] a\n* [ ] b\n* c", &ParseOptions::gfm())?,
259 Node::Root(Root {
260 children: vec![Node::List(List {
261 ordered: false,
262 spread: false,
263 start: None,
264 children: vec![
265 Node::ListItem(ListItem {
266 checked: Some(true),
267 spread: false,
268 children: vec![Node::Paragraph(Paragraph {
269 children: vec![Node::Text(Text {
270 value: "a".into(),
271 position: Some(Position::new(1, 7, 6, 1, 8, 7))
272 }),],
273 position: Some(Position::new(1, 7, 6, 1, 8, 7))
274 })],
275 position: Some(Position::new(1, 1, 0, 1, 8, 7))
276 }),
277 Node::ListItem(ListItem {
278 checked: Some(false),
279 spread: false,
280 children: vec![Node::Paragraph(Paragraph {
281 children: vec![Node::Text(Text {
282 value: "b".into(),
283 position: Some(Position::new(2, 7, 14, 2, 8, 15))
284 }),],
285 position: Some(Position::new(2, 7, 14, 2, 8, 15))
286 })],
287 position: Some(Position::new(2, 1, 8, 2, 8, 15))
288 }),
289 Node::ListItem(ListItem {
290 checked: None,
291 spread: false,
292 children: vec![Node::Paragraph(Paragraph {
293 children: vec![Node::Text(Text {
294 value: "c".into(),
295 position: Some(Position::new(3, 3, 18, 3, 4, 19))
296 }),],
297 position: Some(Position::new(3, 3, 18, 3, 4, 19))
298 })],
299 position: Some(Position::new(3, 1, 16, 3, 4, 19))
300 }),
301 ],
302 position: Some(Position::new(1, 1, 0, 3, 4, 19))
303 })],
304 position: Some(Position::new(1, 1, 0, 3, 4, 19))
305 }),
306 "should support task list items as `checked` fields on `ListItem`s in mdast"
307 );
308
309 assert_eq!(
310 to_mdast(
311 "* [x]\r\n a\n* [ ] b\n* [x]\t \r*c*",
312 &ParseOptions::gfm()
313 )?,
314 Node::Root(Root {
315 children: vec![Node::List(List {
316 ordered: false,
317 spread: false,
318 start: None,
319 children: vec![
320 Node::ListItem(ListItem {
321 checked: Some(true),
322 spread: false,
323 children: vec![Node::Paragraph(Paragraph {
324 children: vec![Node::Text(Text {
325 value: "a".into(),
326 position: Some(Position::new(2, 1, 7, 2, 4, 10))
327 }),],
328 position: Some(Position::new(2, 1, 7, 2, 4, 10))
329 })],
330 position: Some(Position::new(1, 1, 0, 2, 4, 10))
331 }),
332 Node::ListItem(ListItem {
333 checked: Some(false),
334 spread: false,
335 children: vec![Node::Paragraph(Paragraph {
336 children: vec![Node::Text(Text {
337 value: " b".into(),
338 position: Some(Position::new(3, 7, 17, 3, 10, 20))
339 }),],
340 position: Some(Position::new(3, 7, 17, 3, 10, 20))
341 })],
342 position: Some(Position::new(3, 1, 11, 3, 10, 20))
343 }),
344 Node::ListItem(ListItem {
345 checked: Some(true),
346 spread: false,
347 children: vec![Node::Paragraph(Paragraph {
348 children: vec![Node::Emphasis(Emphasis {
349 children: vec![Node::Text(Text {
350 value: "c".into(),
351 position: Some(Position::new(5, 2, 30, 5, 3, 31))
352 }),],
353 position: Some(Position::new(5, 1, 29, 5, 4, 32))
354 })],
355 position: Some(Position::new(5, 1, 29, 5, 4, 32))
356 })],
357 position: Some(Position::new(4, 1, 21, 5, 4, 32))
358 }),
359 ],
360 position: Some(Position::new(1, 1, 0, 5, 4, 32))
361 })],
362 position: Some(Position::new(1, 1, 0, 5, 4, 32))
363 }),
364 "should handle lots of whitespace after checkbox, and non-text"
365 );
366
367 Ok(())
368}