Markdown parser fork with extended syntax for personal use.
1use markdown::{
2 mdast::{AlignKind, InlineCode, Node, Root, Table, TableCell, TableRow, Text},
3 message, to_html, to_html_with_options, to_mdast,
4 unist::Position,
5 CompileOptions, Constructs, Options, ParseOptions,
6};
7use pretty_assertions::assert_eq;
8
9#[test]
10fn gfm_table() -> Result<(), message::Message> {
11 assert_eq!(
12 to_html("| a |\n| - |\n| b |"),
13 "<p>| a |\n| - |\n| b |</p>",
14 "should ignore tables by default"
15 );
16
17 assert_eq!(
18 to_html_with_options("| a |\n| - |\n| b |", &Options::gfm())?,
19 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n</tbody>\n</table>",
20 "should support tables"
21 );
22
23 assert_eq!(
24 to_html_with_options("| a |", &Options::gfm())?,
25 "<p>| a |</p>",
26 "should not support a table w/ the head row ending in an eof (1)"
27 );
28
29 assert_eq!(
30 to_html_with_options("| a", &Options::gfm())?,
31 "<p>| a</p>",
32 "should not support a table w/ the head row ending in an eof (2)"
33 );
34
35 assert_eq!(
36 to_html_with_options("a |", &Options::gfm())?,
37 "<p>a |</p>",
38 "should not support a table w/ the head row ending in an eof (3)"
39 );
40
41 assert_eq!(
42 to_html_with_options("| a |\n| - |", &Options::gfm())?,
43 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>",
44 "should support a table w/ a delimiter row ending in an eof (1)"
45 );
46
47 assert_eq!(
48 to_html_with_options("| a\n| -", &Options::gfm())?,
49 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>",
50 "should support a table w/ a delimiter row ending in an eof (2)"
51 );
52
53 assert_eq!(
54 to_html_with_options("| a |\n| - |\n| b |", &Options::gfm())?,
55 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n</tbody>\n</table>",
56 "should support a table w/ a body row ending in an eof (1)"
57 );
58
59 assert_eq!(
60 to_html_with_options("| a\n| -\n| b", &Options::gfm())?,
61 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n</tbody>\n</table>",
62 "should support a table w/ a body row ending in an eof (2)"
63 );
64
65 assert_eq!(
66 to_html_with_options("a|b\n-|-\nc|d", &Options::gfm())?,
67 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>c</td>\n<td>d</td>\n</tr>\n</tbody>\n</table>",
68 "should support a table w/ a body row ending in an eof (3)"
69 );
70
71 assert_eq!(
72 to_html_with_options("| a \n| -\t\n| b | ", &Options::gfm())?,
73 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n</tbody>\n</table>",
74 "should support rows w/ trailing whitespace (1)"
75 );
76
77 assert_eq!(
78 to_html_with_options("| a | \n| - |", &Options::gfm())?,
79 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>",
80 "should support rows w/ trailing whitespace (2)"
81 );
82
83 assert_eq!(
84 to_html_with_options("| a |\n| - | ", &Options::gfm())?,
85 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>",
86 "should support rows w/ trailing whitespace (3)"
87 );
88
89 assert_eq!(
90 to_html_with_options("| a |\n| - |\n| b | ", &Options::gfm())?,
91 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n</tbody>\n</table>",
92 "should support rows w/ trailing whitespace (4)"
93 );
94
95 assert_eq!(
96 to_html_with_options("||a|\n|-|-|", &Options::gfm())?,
97 "<table>\n<thead>\n<tr>\n<th></th>\n<th>a</th>\n</tr>\n</thead>\n</table>",
98 "should support empty first header cells"
99 );
100
101 assert_eq!(
102 to_html_with_options("|a||\n|-|-|", &Options::gfm())?,
103 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th></th>\n</tr>\n</thead>\n</table>",
104 "should support empty last header cells"
105 );
106
107 assert_eq!(
108 to_html_with_options("a||b\n-|-|-", &Options::gfm())?,
109 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th></th>\n<th>b</th>\n</tr>\n</thead>\n</table>",
110 "should support empty header cells"
111 );
112
113 assert_eq!(
114 to_html_with_options("|a|b|\n|-|-|\n||c|", &Options::gfm())?,
115 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td></td>\n<td>c</td>\n</tr>\n</tbody>\n</table>",
116 "should support empty first body cells"
117 );
118
119 assert_eq!(
120 to_html_with_options("|a|b|\n|-|-|\n|c||", &Options::gfm())?,
121 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>c</td>\n<td></td>\n</tr>\n</tbody>\n</table>",
122 "should support empty last body cells"
123 );
124
125 assert_eq!(
126 to_html_with_options("a|b|c\n-|-|-\nd||e", &Options::gfm())?,
127 "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>d</td>\n<td></td>\n<td>e</td>\n</tr>\n</tbody>\n</table>",
128 "should support empty body cells"
129 );
130
131 assert_eq!(
132 to_html_with_options(":\n|-|\n|a|\n\nb\n|-|\n|c|\n\n|\n|-|\n|d|\n\n|\n|-|\n|e|\n\n|:\n|-|\n|f|\n\n||\n|-|\n|g|\n\n| |\n|-|\n|h|\n", &Options::gfm())?,
133 "<table>\n<thead>\n<tr>\n<th>:</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>a</td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>c</td>\n</tr>\n</tbody>\n</table>\n<p>|\n|-|\n|d|</p>\n<p>|\n|-|\n|e|</p>\n<table>\n<thead>\n<tr>\n<th>:</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>f</td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>g</td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
134 "should need any character other than a single pipe in the header row"
135 );
136
137 assert_eq!(
138 to_html_with_options("a\n|-\n\nb\n||\n\nc\n|-|\n\nd\n|:|\n\ne\n| |\n\nf\n| -|\n\ng\n|- |\n", &Options::gfm())?,
139 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<p>b\n||</p>\n<table>\n<thead>\n<tr>\n<th>c</th>\n</tr>\n</thead>\n</table>\n<p>d\n|:|</p>\n<p>e\n| |</p>\n<table>\n<thead>\n<tr>\n<th>f</th>\n</tr>\n</thead>\n</table>\n<table>\n<thead>\n<tr>\n<th>g</th>\n</tr>\n</thead>\n</table>\n",
140 "should need a dash in the delimimter row"
141 );
142
143 assert_eq!(
144 to_html_with_options("|\n|", &Options::gfm())?,
145 "<p>|\n|</p>",
146 "should need something"
147 );
148
149 assert_eq!(
150 to_html_with_options("| a |\n| - |\n- b", &Options::gfm())?,
151 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<ul>\n<li>b</li>\n</ul>",
152 "should support a list after a table"
153 );
154
155 assert_eq!(
156 to_html_with_options("> | a |\n| - |", &Options::gfm())?,
157 "<blockquote>\n<p>| a |\n| - |</p>\n</blockquote>",
158 "should not support a lazy delimiter row (1)"
159 );
160
161 assert_eq!(
162 to_html_with_options("> a\n> | b |\n| - |", &Options::gfm())?,
163 "<blockquote>\n<p>a\n| b |\n| - |</p>\n</blockquote>",
164 "should not support a lazy delimiter row (2)"
165 );
166
167 assert_eq!(
168 to_html_with_options("| a |\n> | - |", &Options::gfm())?,
169 "<p>| a |</p>\n<blockquote>\n<p>| - |</p>\n</blockquote>",
170 "should not support a piercing delimiter row"
171 );
172
173 assert_eq!(
174 to_html_with_options("> a\n> | b |\n|-", &Options::gfm())?,
175 "<blockquote>\n<p>a\n| b |\n|-</p>\n</blockquote>",
176 "should not support a lazy body row (2)"
177 );
178
179 assert_eq!(
180 to_html_with_options("> | a |\n> | - |\n| b |", &Options::gfm())?,
181 "<blockquote>\n<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n</blockquote>\n<p>| b |</p>",
182 "should not support a lazy body row (1)"
183 );
184
185 assert_eq!(
186 to_html_with_options("> a\n> | b |\n> | - |\n| c |", &Options::gfm())?,
187 "<blockquote>\n<p>a</p>\n<table>\n<thead>\n<tr>\n<th>b</th>\n</tr>\n</thead>\n</table>\n</blockquote>\n<p>| c |</p>",
188 "should not support a lazy body row (2)"
189 );
190
191 assert_eq!(
192 to_html_with_options("> | A |\n> | - |\n> | 1 |\n| 2 |", &Options::gfm())?,
193 "<blockquote>\n<table>\n<thead>\n<tr>\n<th>A</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n</tr>\n</tbody>\n</table>\n</blockquote>\n<p>| 2 |</p>",
194 "should not support a lazy body row (3)"
195 );
196
197 assert_eq!(
198 to_html_with_options(" - d\n - e", &Options::gfm())?,
199 to_html(" - d\n - e"),
200 "should not change how lists and lazyness work"
201 );
202
203 assert_eq!(
204 to_html_with_options("| a |\n | - |", &Options::gfm())?,
205 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>",
206 "should form a table if the delimiter row is indented w/ 3 spaces"
207 );
208
209 assert_eq!(
210 to_html_with_options("| a |\n | - |", &Options::gfm())?,
211 "<p>| a |\n| - |</p>",
212 "should not form a table if the delimiter row is indented w/ 4 spaces"
213 );
214
215 assert_eq!(
216 to_html_with_options("| a |\n | - |", &Options {
217 parse: ParseOptions {
218 constructs: Constructs {
219 code_indented: false,
220 ..Constructs::gfm()
221 },
222 ..ParseOptions::gfm()
223 },
224 ..Options::gfm()
225 })?,
226 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>",
227 "should form a table if the delimiter row is indented w/ 4 spaces and indented code is turned off"
228 );
229
230 assert_eq!(
231 to_html_with_options("| a |\n| - |\n> block quote?", &Options::gfm())?,
232 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<blockquote>\n<p>block quote?</p>\n</blockquote>",
233 "should be interrupted by a block quote"
234 );
235
236 assert_eq!(
237 to_html_with_options("| a |\n| - |\n>", &Options::gfm())?,
238 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<blockquote>\n</blockquote>",
239 "should be interrupted by a block quote (empty)"
240 );
241
242 assert_eq!(
243 to_html_with_options("| a |\n| - |\n- list?", &Options::gfm())?,
244 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<ul>\n<li>list?</li>\n</ul>",
245 "should be interrupted by a list"
246 );
247
248 assert_eq!(
249 to_html_with_options("| a |\n| - |\n-", &Options::gfm())?,
250 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<ul>\n<li></li>\n</ul>",
251 "should be interrupted by a list (empty)"
252 );
253
254 assert_eq!(
255 to_html_with_options(
256 "| a |\n| - |\n<!-- HTML? -->",
257 &Options {
258 compile: CompileOptions {
259 allow_dangerous_html: true,
260 allow_dangerous_protocol: true,
261 ..CompileOptions::gfm()
262 },
263 ..Options::gfm()
264 }
265 )?,
266 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<!-- HTML? -->",
267 "should be interrupted by HTML (flow)"
268 );
269
270 assert_eq!(
271 to_html_with_options("| a |\n| - |\n\tcode?", &Options {
272 compile: CompileOptions {
273 allow_dangerous_html: true,
274 allow_dangerous_protocol: true,
275 ..CompileOptions::gfm()
276 },
277 ..Options::gfm()
278 })?,
279 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<pre><code>code?\n</code></pre>",
280 "should be interrupted by code (indented)"
281 );
282
283 assert_eq!(
284 to_html_with_options("| a |\n| - |\n```js\ncode?", &Options {
285 compile: CompileOptions {
286 allow_dangerous_html: true,
287 allow_dangerous_protocol: true,
288 ..CompileOptions::gfm()
289 },
290 ..Options::gfm()
291 })?,
292 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<pre><code class=\"language-js\">code?\n</code></pre>\n",
293 "should be interrupted by code (fenced)"
294 );
295
296 assert_eq!(
297 to_html_with_options(
298 "| a |\n| - |\n***",
299 &Options {
300 compile: CompileOptions {
301 allow_dangerous_html: true,
302 allow_dangerous_protocol: true,
303 ..CompileOptions::gfm()
304 },
305 ..Options::gfm()
306 }
307 )?,
308 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<hr />",
309 "should be interrupted by a thematic break"
310 );
311
312 assert_eq!(
313 to_html_with_options("| a |\n| - |\n# heading?", &Options::gfm())?,
314 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<h1>heading?</h1>",
315 "should be interrupted by a heading (ATX)"
316 );
317
318 assert_eq!(
319 to_html_with_options("| a |\n| - |\nheading\n=", &Options::gfm())?,
320 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>heading</td>\n</tr>\n<tr>\n<td>=</td>\n</tr>\n</tbody>\n</table>",
321 "should *not* be interrupted by a heading (setext)"
322 );
323
324 assert_eq!(
325 to_html_with_options("| a |\n| - |\nheading\n---", &Options::gfm())?,
326 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>heading</td>\n</tr>\n</tbody>\n</table>\n<hr />",
327 "should *not* be interrupted by a heading (setext), but interrupt if the underline is also a thematic break"
328 );
329
330 assert_eq!(
331 to_html_with_options("| a |\n| - |\nheading\n-", &Options::gfm())?,
332 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>heading</td>\n</tr>\n</tbody>\n</table>\n<ul>\n<li></li>\n</ul>",
333 "should *not* be interrupted by a heading (setext), but interrupt if the underline is also an empty list item bullet"
334 );
335
336 assert_eq!(
337 to_html_with_options("a\nb\n-:", &Options::gfm())?,
338 "<p>a</p>\n<table>\n<thead>\n<tr>\n<th align=\"right\">b</th>\n</tr>\n</thead>\n</table>",
339 "should support a single head row"
340 );
341
342 assert_eq!(
343 to_html_with_options("> | a |\n> | - |", &Options::gfm())?,
344 "<blockquote>\n<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n</blockquote>",
345 "should support a table in a container"
346 );
347
348 assert_eq!(
349 to_html_with_options("> | a |\n| - |", &Options::gfm())?,
350 "<blockquote>\n<p>| a |\n| - |</p>\n</blockquote>",
351 "should not support a lazy delimiter row if the head row is in a container"
352 );
353
354 assert_eq!(
355 to_html_with_options("| a |\n> | - |", &Options::gfm())?,
356 "<p>| a |</p>\n<blockquote>\n<p>| - |</p>\n</blockquote>",
357 "should not support a “piercing” container for the delimiter row, if the head row was not in that container"
358 );
359
360 assert_eq!(
361 to_html_with_options("> | a |\n> | - |\n| c |", &Options::gfm())?,
362 "<blockquote>\n<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n</blockquote>\n<p>| c |</p>",
363 "should not support a lazy body row if the head row and delimiter row are in a container"
364 );
365
366 assert_eq!(
367 to_html_with_options("> | a |\n| - |\n> | c |", &Options::gfm())?,
368 "<blockquote>\n<p>| a |\n| - |\n| c |</p>\n</blockquote>",
369 "should not support a lazy delimiter row if the head row and a further body row are in a container"
370 );
371
372 assert_eq!(
373 to_html_with_options("[\na\n:-\n]: b", &Options::gfm())?,
374 "<p>[</p>\n<table>\n<thead>\n<tr>\n<th align=\"left\">a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">]: b</td>\n</tr>\n</tbody>\n</table>",
375 "should prefer GFM tables over definitions"
376 );
377
378 assert_eq!(
379 to_html_with_options(" | a |\n\t| - |\n | b |", &Options {
380 parse: ParseOptions {
381 constructs: Constructs {
382 code_indented: false,
383 ..Constructs::gfm()
384 },
385 ..ParseOptions::gfm()
386 },
387 ..Options::gfm()
388 })?,
389 "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n</tbody>\n</table>",
390 "should support indented rows if code (indented) is off"
391 );
392
393 assert_eq!(
394 to_html_with_options(
395 r###"# Align
396
397## An empty initial cell
398
399| | a|c|
400|--|:----:|:---|
401|a|b|c|
402|a|b|c|
403
404## Missing alignment characters
405
406| a | b | c |
407| |---|---|
408| d | e | f |
409
410* * *
411
412| a | b | c |
413|---|---| |
414| d | e | f |
415
416## Incorrect characters
417
418| a | b | c |
419|---|-*-|---|
420| d | e | f |
421
422## Two alignments
423
424|a|
425|::|
426
427|a|
428|:-:|
429
430## Two at the start or end
431
432|a|
433|::-|
434
435|a|
436|-::|
437
438## In the middle
439
440|a|
441|-:-|
442
443## A space in the middle
444
445|a|
446|- -|
447
448## No pipe
449
450a
451:-:
452
453a
454:-
455
456a
457-:
458
459## A single colon
460
461|a|
462|:|
463
464a
465:
466
467## Alignment on empty cells
468
469| a | b | c | d | e |
470| - | - | :- | -: | :-: |
471| f |
472"###,
473 &Options::gfm()
474 )?,
475 r#"<h1>Align</h1>
476<h2>An empty initial cell</h2>
477<table>
478<thead>
479<tr>
480<th></th>
481<th align="center">a</th>
482<th align="left">c</th>
483</tr>
484</thead>
485<tbody>
486<tr>
487<td>a</td>
488<td align="center">b</td>
489<td align="left">c</td>
490</tr>
491<tr>
492<td>a</td>
493<td align="center">b</td>
494<td align="left">c</td>
495</tr>
496</tbody>
497</table>
498<h2>Missing alignment characters</h2>
499<p>| a | b | c |
500| |---|---|
501| d | e | f |</p>
502<hr />
503<p>| a | b | c |
504|---|---| |
505| d | e | f |</p>
506<h2>Incorrect characters</h2>
507<p>| a | b | c |
508|---|-*-|---|
509| d | e | f |</p>
510<h2>Two alignments</h2>
511<p>|a|
512|::|</p>
513<table>
514<thead>
515<tr>
516<th align="center">a</th>
517</tr>
518</thead>
519</table>
520<h2>Two at the start or end</h2>
521<p>|a|
522|::-|</p>
523<p>|a|
524|-::|</p>
525<h2>In the middle</h2>
526<p>|a|
527|-:-|</p>
528<h2>A space in the middle</h2>
529<p>|a|
530|- -|</p>
531<h2>No pipe</h2>
532<table>
533<thead>
534<tr>
535<th align="center">a</th>
536</tr>
537</thead>
538</table>
539<table>
540<thead>
541<tr>
542<th align="left">a</th>
543</tr>
544</thead>
545</table>
546<table>
547<thead>
548<tr>
549<th align="right">a</th>
550</tr>
551</thead>
552</table>
553<h2>A single colon</h2>
554<p>|a|
555|:|</p>
556<p>a
557:</p>
558<h2>Alignment on empty cells</h2>
559<table>
560<thead>
561<tr>
562<th>a</th>
563<th>b</th>
564<th align="left">c</th>
565<th align="right">d</th>
566<th align="center">e</th>
567</tr>
568</thead>
569<tbody>
570<tr>
571<td>f</td>
572<td></td>
573<td align="left"></td>
574<td align="right"></td>
575<td align="center"></td>
576</tr>
577</tbody>
578</table>
579"#,
580 "should match alignment like GitHub"
581 );
582
583 assert_eq!(
584 to_html_with_options(
585 r###"# Tables
586
587| a | b | c |
588| - | - | - |
589| d | e | f |
590
591## No body
592
593| a | b | c |
594| - | - | - |
595
596## One column
597
598| a |
599| - |
600| b |
601"###,
602 &Options::gfm()
603 )?,
604 r###"<h1>Tables</h1>
605<table>
606<thead>
607<tr>
608<th>a</th>
609<th>b</th>
610<th>c</th>
611</tr>
612</thead>
613<tbody>
614<tr>
615<td>d</td>
616<td>e</td>
617<td>f</td>
618</tr>
619</tbody>
620</table>
621<h2>No body</h2>
622<table>
623<thead>
624<tr>
625<th>a</th>
626<th>b</th>
627<th>c</th>
628</tr>
629</thead>
630</table>
631<h2>One column</h2>
632<table>
633<thead>
634<tr>
635<th>a</th>
636</tr>
637</thead>
638<tbody>
639<tr>
640<td>b</td>
641</tr>
642</tbody>
643</table>
644"###,
645 "should match basic like GitHub"
646 );
647
648 assert_eq!(
649 to_html_with_options(
650 r###"# Tables in things
651
652## In lists
653
654* Unordered:
655
656 | A | B |
657 | - | - |
658 | 1 | 2 |
659
6601. Ordered:
661
662 | A | B |
663 | - | - |
664 | 1 | 2 |
665
666* Lazy?
667 | A | B |
668 | - | - |
669 | 1 | 2 |
670 | 3 | 4 |
671 | 5 | 6 |
672| 7 | 8 |
673
674## In block quotes
675
676> W/ space:
677> | A | B |
678> | - | - |
679> | 1 | 2 |
680
681>W/o space:
682>| A | B |
683>| - | - |
684>| 1 | 2 |
685
686> Lazy?
687> | A | B |
688> | - | - |
689> | 1 | 2 |
690>| 3 | 4 |
691| 5 | 6 |
692
693### List interrupting delimiters
694
695a |
696- |
697
698a
699-|
700
701a
702|-
703"###,
704 &Options::gfm()
705 )?,
706 r###"<h1>Tables in things</h1>
707<h2>In lists</h2>
708<ul>
709<li>
710<p>Unordered:</p>
711<table>
712<thead>
713<tr>
714<th>A</th>
715<th>B</th>
716</tr>
717</thead>
718<tbody>
719<tr>
720<td>1</td>
721<td>2</td>
722</tr>
723</tbody>
724</table>
725</li>
726</ul>
727<ol>
728<li>
729<p>Ordered:</p>
730<table>
731<thead>
732<tr>
733<th>A</th>
734<th>B</th>
735</tr>
736</thead>
737<tbody>
738<tr>
739<td>1</td>
740<td>2</td>
741</tr>
742</tbody>
743</table>
744</li>
745</ol>
746<ul>
747<li>Lazy?
748<table>
749<thead>
750<tr>
751<th>A</th>
752<th>B</th>
753</tr>
754</thead>
755</table>
756</li>
757</ul>
758<p>| 1 | 2 |
759| 3 | 4 |
760| 5 | 6 |
761| 7 | 8 |</p>
762<h2>In block quotes</h2>
763<blockquote>
764<p>W/ space:</p>
765<table>
766<thead>
767<tr>
768<th>A</th>
769<th>B</th>
770</tr>
771</thead>
772<tbody>
773<tr>
774<td>1</td>
775<td>2</td>
776</tr>
777</tbody>
778</table>
779</blockquote>
780<blockquote>
781<p>W/o space:</p>
782<table>
783<thead>
784<tr>
785<th>A</th>
786<th>B</th>
787</tr>
788</thead>
789<tbody>
790<tr>
791<td>1</td>
792<td>2</td>
793</tr>
794</tbody>
795</table>
796</blockquote>
797<blockquote>
798<p>Lazy?</p>
799<table>
800<thead>
801<tr>
802<th>A</th>
803<th>B</th>
804</tr>
805</thead>
806<tbody>
807<tr>
808<td>1</td>
809<td>2</td>
810</tr>
811<tr>
812<td>3</td>
813<td>4</td>
814</tr>
815</tbody>
816</table>
817</blockquote>
818<p>| 5 | 6 |</p>
819<h3>List interrupting delimiters</h3>
820<p>a |</p>
821<ul>
822<li>|</li>
823</ul>
824<table>
825<thead>
826<tr>
827<th>a</th>
828</tr>
829</thead>
830</table>
831<table>
832<thead>
833<tr>
834<th>a</th>
835</tr>
836</thead>
837</table>
838"###,
839 "should match containers like GitHub"
840 );
841
842 assert_eq!(
843 to_html_with_options(
844 r###"| a |
845| - |
846| - |
847| 1 |
848"###,
849 &Options::gfm()
850 )?,
851 r###"<table>
852<thead>
853<tr>
854<th>a</th>
855</tr>
856</thead>
857<tbody>
858<tr>
859<td>-</td>
860</tr>
861<tr>
862<td>1</td>
863</tr>
864</tbody>
865</table>
866"###,
867 "should match a double delimiter row like GitHub"
868 );
869
870 assert_eq!(
871 to_html_with_options(
872 r"# Examples from GFM
873
874## A
875
876| foo | bar |
877| --- | --- |
878| baz | bim |
879
880## B
881
882| abc | defghi |
883:-: | -----------:
884bar | baz
885
886## C
887
888| f\|oo |
889| ------ |
890| b `\|` az |
891| b **\|** im |
892
893## D
894
895| abc | def |
896| --- | --- |
897| bar | baz |
898> bar
899
900## E
901
902| abc | def |
903| --- | --- |
904| bar | baz |
905bar
906
907bar
908
909## F
910
911| abc | def |
912| --- |
913| bar |
914
915## G
916
917| abc | def |
918| --- | --- |
919| bar |
920| bar | baz | boo |
921
922## H
923
924| abc | def |
925| --- | --- |
926",
927 &Options::gfm()
928 )?,
929 r#"<h1>Examples from GFM</h1>
930<h2>A</h2>
931<table>
932<thead>
933<tr>
934<th>foo</th>
935<th>bar</th>
936</tr>
937</thead>
938<tbody>
939<tr>
940<td>baz</td>
941<td>bim</td>
942</tr>
943</tbody>
944</table>
945<h2>B</h2>
946<table>
947<thead>
948<tr>
949<th align="center">abc</th>
950<th align="right">defghi</th>
951</tr>
952</thead>
953<tbody>
954<tr>
955<td align="center">bar</td>
956<td align="right">baz</td>
957</tr>
958</tbody>
959</table>
960<h2>C</h2>
961<table>
962<thead>
963<tr>
964<th>f|oo</th>
965</tr>
966</thead>
967<tbody>
968<tr>
969<td>b <code>|</code> az</td>
970</tr>
971<tr>
972<td>b <strong>|</strong> im</td>
973</tr>
974</tbody>
975</table>
976<h2>D</h2>
977<table>
978<thead>
979<tr>
980<th>abc</th>
981<th>def</th>
982</tr>
983</thead>
984<tbody>
985<tr>
986<td>bar</td>
987<td>baz</td>
988</tr>
989</tbody>
990</table>
991<blockquote>
992<p>bar</p>
993</blockquote>
994<h2>E</h2>
995<table>
996<thead>
997<tr>
998<th>abc</th>
999<th>def</th>
1000</tr>
1001</thead>
1002<tbody>
1003<tr>
1004<td>bar</td>
1005<td>baz</td>
1006</tr>
1007<tr>
1008<td>bar</td>
1009<td></td>
1010</tr>
1011</tbody>
1012</table>
1013<p>bar</p>
1014<h2>F</h2>
1015<p>| abc | def |
1016| --- |
1017| bar |</p>
1018<h2>G</h2>
1019<table>
1020<thead>
1021<tr>
1022<th>abc</th>
1023<th>def</th>
1024</tr>
1025</thead>
1026<tbody>
1027<tr>
1028<td>bar</td>
1029<td></td>
1030</tr>
1031<tr>
1032<td>bar</td>
1033<td>baz</td>
1034</tr>
1035</tbody>
1036</table>
1037<h2>H</h2>
1038<table>
1039<thead>
1040<tr>
1041<th>abc</th>
1042<th>def</th>
1043</tr>
1044</thead>
1045</table>
1046"#,
1047 "should match examples from the GFM spec like GitHub"
1048 );
1049
1050 assert_eq!(
1051 to_html_with_options(
1052 r"# Grave accents
1053
1054## Grave accent in cell
1055
1056| A | B |
1057|--------------|---|
1058| <kbd>`</kbd> | C |
1059
1060## Escaped grave accent in “inline code” in cell
1061
1062| A |
1063|-----|
1064| `\` |
1065
1066## “Empty” inline code
1067
1068| 1 | 2 | 3 |
1069|---|------|----|
1070| a | `` | |
1071| b | `` | `` |
1072| c | ` | ` |
1073| d | `|` |
1074| e | `\|` | |
1075| f | \| | |
1076
1077## Escaped pipes in code in cells
1078
1079| `\|\\` |
1080| --- |
1081| `\|\\` |
1082
1083`\|\\`
1084",
1085 &Options {
1086 compile: CompileOptions {
1087 allow_dangerous_html: true,
1088 allow_dangerous_protocol: true,
1089 ..CompileOptions::gfm()
1090 },
1091 ..Options::gfm()
1092 }
1093 )?,
1094 r"<h1>Grave accents</h1>
1095<h2>Grave accent in cell</h2>
1096<table>
1097<thead>
1098<tr>
1099<th>A</th>
1100<th>B</th>
1101</tr>
1102</thead>
1103<tbody>
1104<tr>
1105<td><kbd>`</kbd></td>
1106<td>C</td>
1107</tr>
1108</tbody>
1109</table>
1110<h2>Escaped grave accent in “inline code” in cell</h2>
1111<table>
1112<thead>
1113<tr>
1114<th>A</th>
1115</tr>
1116</thead>
1117<tbody>
1118<tr>
1119<td><code>\</code></td>
1120</tr>
1121</tbody>
1122</table>
1123<h2>“Empty” inline code</h2>
1124<table>
1125<thead>
1126<tr>
1127<th>1</th>
1128<th>2</th>
1129<th>3</th>
1130</tr>
1131</thead>
1132<tbody>
1133<tr>
1134<td>a</td>
1135<td>``</td>
1136<td></td>
1137</tr>
1138<tr>
1139<td>b</td>
1140<td>``</td>
1141<td>``</td>
1142</tr>
1143<tr>
1144<td>c</td>
1145<td>`</td>
1146<td>`</td>
1147</tr>
1148<tr>
1149<td>d</td>
1150<td>`</td>
1151<td>`</td>
1152</tr>
1153<tr>
1154<td>e</td>
1155<td><code>|</code></td>
1156<td></td>
1157</tr>
1158<tr>
1159<td>f</td>
1160<td>|</td>
1161<td></td>
1162</tr>
1163</tbody>
1164</table>
1165<h2>Escaped pipes in code in cells</h2>
1166<table>
1167<thead>
1168<tr>
1169<th><code>|\\</code></th>
1170</tr>
1171</thead>
1172<tbody>
1173<tr>
1174<td><code>|\\</code></td>
1175</tr>
1176</tbody>
1177</table>
1178<p><code>\|\\</code></p>
1179",
1180 "should match grave accent like GitHub"
1181 );
1182
1183 assert_eq!(
1184 to_html_with_options(
1185 r###"# Code
1186
1187## Indented delimiter row
1188
1189a
1190 |-
1191
1192a
1193 |-
1194
1195## Indented body
1196
1197| a |
1198 | - |
1199 | C |
1200 | D |
1201 | E |
1202"###,
1203 &Options::gfm()
1204 )?,
1205 r###"<h1>Code</h1>
1206<h2>Indented delimiter row</h2>
1207<table>
1208<thead>
1209<tr>
1210<th>a</th>
1211</tr>
1212</thead>
1213</table>
1214<p>a
1215|-</p>
1216<h2>Indented body</h2>
1217<table>
1218<thead>
1219<tr>
1220<th>a</th>
1221</tr>
1222</thead>
1223<tbody>
1224<tr>
1225<td>C</td>
1226</tr>
1227<tr>
1228<td>D</td>
1229</tr>
1230</tbody>
1231</table>
1232<pre><code>| E |
1233</code></pre>
1234"###,
1235 "should match indent like GitHub"
1236 );
1237
1238 assert_eq!(
1239 to_html_with_options(
1240 r###"## Blank line
1241
1242a
1243:-
1244b
1245
1246c
1247
1248## Block quote
1249
1250a
1251:-
1252b
1253> c
1254
1255## Code (fenced)
1256
1257a
1258:-
1259b
1260```
1261c
1262```
1263
1264## Code (indented)
1265
1266a
1267:-
1268b
1269 c
1270
1271## Definition
1272
1273a
1274:-
1275b
1276[c]: d
1277
1278## Heading (atx)
1279
1280a
1281:-
1282b
1283# c
1284
1285
1286## Heading (setext) (rank 1)
1287
1288a
1289:-
1290b
1291==
1292c
1293
1294## Heading (setext) (rank 2)
1295
1296a
1297:-
1298b
1299--
1300c
1301
1302## HTML (flow, kind 1: raw)
1303
1304a
1305:-
1306b
1307<pre>
1308 a
1309</pre>
1310
1311## HTML (flow, kind 2: comment)
1312
1313a
1314:-
1315b
1316<!-- c -->
1317
1318## HTML (flow, kind 3: instruction)
1319
1320a
1321:-
1322b
1323<? c ?>
1324
1325## HTML (flow, kind 4: declaration)
1326
1327a
1328:-
1329b
1330<!C>
1331
1332## HTML (flow, kind 5: cdata)
1333
1334a
1335:-
1336b
1337<![CDATA[c]]>
1338
1339## HTML (flow, kind 6: basic)
1340
1341a
1342:-
1343b
1344<div>
1345
1346## HTML (flow, kind 7: complete)
1347
1348a
1349:-
1350b
1351<x>
1352
1353## List (ordered, 1)
1354
1355a
1356:-
1357b
13581. c
1359
1360## List (ordered, other)
1361
1362a
1363:-
1364b
13652. c
1366
1367## List (unordered)
1368
1369a
1370:-
1371b
1372* c
1373
1374## List (unordered, blank)
1375
1376a
1377:-
1378b
1379*
1380c
1381
1382## List (unordered, blank start)
1383
1384a
1385:-
1386b
1387*
1388 c
1389
1390## Thematic break
1391
1392a
1393:-
1394b
1395***
1396"###,
1397 &Options {
1398 compile: CompileOptions {
1399 allow_dangerous_html: true,
1400 allow_dangerous_protocol: true,
1401 ..CompileOptions::gfm()
1402 },
1403 ..Options::gfm()
1404 }
1405 )?,
1406 r#"<h2>Blank line</h2>
1407<table>
1408<thead>
1409<tr>
1410<th align="left">a</th>
1411</tr>
1412</thead>
1413<tbody>
1414<tr>
1415<td align="left">b</td>
1416</tr>
1417</tbody>
1418</table>
1419<p>c</p>
1420<h2>Block quote</h2>
1421<table>
1422<thead>
1423<tr>
1424<th align="left">a</th>
1425</tr>
1426</thead>
1427<tbody>
1428<tr>
1429<td align="left">b</td>
1430</tr>
1431</tbody>
1432</table>
1433<blockquote>
1434<p>c</p>
1435</blockquote>
1436<h2>Code (fenced)</h2>
1437<table>
1438<thead>
1439<tr>
1440<th align="left">a</th>
1441</tr>
1442</thead>
1443<tbody>
1444<tr>
1445<td align="left">b</td>
1446</tr>
1447</tbody>
1448</table>
1449<pre><code>c
1450</code></pre>
1451<h2>Code (indented)</h2>
1452<table>
1453<thead>
1454<tr>
1455<th align="left">a</th>
1456</tr>
1457</thead>
1458<tbody>
1459<tr>
1460<td align="left">b</td>
1461</tr>
1462</tbody>
1463</table>
1464<pre><code>c
1465</code></pre>
1466<h2>Definition</h2>
1467<table>
1468<thead>
1469<tr>
1470<th align="left">a</th>
1471</tr>
1472</thead>
1473<tbody>
1474<tr>
1475<td align="left">b</td>
1476</tr>
1477<tr>
1478<td align="left">[c]: d</td>
1479</tr>
1480</tbody>
1481</table>
1482<h2>Heading (atx)</h2>
1483<table>
1484<thead>
1485<tr>
1486<th align="left">a</th>
1487</tr>
1488</thead>
1489<tbody>
1490<tr>
1491<td align="left">b</td>
1492</tr>
1493</tbody>
1494</table>
1495<h1>c</h1>
1496<h2>Heading (setext) (rank 1)</h2>
1497<table>
1498<thead>
1499<tr>
1500<th align="left">a</th>
1501</tr>
1502</thead>
1503<tbody>
1504<tr>
1505<td align="left">b</td>
1506</tr>
1507<tr>
1508<td align="left">==</td>
1509</tr>
1510<tr>
1511<td align="left">c</td>
1512</tr>
1513</tbody>
1514</table>
1515<h2>Heading (setext) (rank 2)</h2>
1516<table>
1517<thead>
1518<tr>
1519<th align="left">a</th>
1520</tr>
1521</thead>
1522<tbody>
1523<tr>
1524<td align="left">b</td>
1525</tr>
1526<tr>
1527<td align="left">--</td>
1528</tr>
1529<tr>
1530<td align="left">c</td>
1531</tr>
1532</tbody>
1533</table>
1534<h2>HTML (flow, kind 1: raw)</h2>
1535<table>
1536<thead>
1537<tr>
1538<th align="left">a</th>
1539</tr>
1540</thead>
1541<tbody>
1542<tr>
1543<td align="left">b</td>
1544</tr>
1545</tbody>
1546</table>
1547<pre>
1548 a
1549</pre>
1550<h2>HTML (flow, kind 2: comment)</h2>
1551<table>
1552<thead>
1553<tr>
1554<th align="left">a</th>
1555</tr>
1556</thead>
1557<tbody>
1558<tr>
1559<td align="left">b</td>
1560</tr>
1561</tbody>
1562</table>
1563<!-- c -->
1564<h2>HTML (flow, kind 3: instruction)</h2>
1565<table>
1566<thead>
1567<tr>
1568<th align="left">a</th>
1569</tr>
1570</thead>
1571<tbody>
1572<tr>
1573<td align="left">b</td>
1574</tr>
1575</tbody>
1576</table>
1577<? c ?>
1578<h2>HTML (flow, kind 4: declaration)</h2>
1579<table>
1580<thead>
1581<tr>
1582<th align="left">a</th>
1583</tr>
1584</thead>
1585<tbody>
1586<tr>
1587<td align="left">b</td>
1588</tr>
1589</tbody>
1590</table>
1591<!C>
1592<h2>HTML (flow, kind 5: cdata)</h2>
1593<table>
1594<thead>
1595<tr>
1596<th align="left">a</th>
1597</tr>
1598</thead>
1599<tbody>
1600<tr>
1601<td align="left">b</td>
1602</tr>
1603</tbody>
1604</table>
1605<![CDATA[c]]>
1606<h2>HTML (flow, kind 6: basic)</h2>
1607<table>
1608<thead>
1609<tr>
1610<th align="left">a</th>
1611</tr>
1612</thead>
1613<tbody>
1614<tr>
1615<td align="left">b</td>
1616</tr>
1617</tbody>
1618</table>
1619<div>
1620<h2>HTML (flow, kind 7: complete)</h2>
1621<table>
1622<thead>
1623<tr>
1624<th align="left">a</th>
1625</tr>
1626</thead>
1627<tbody>
1628<tr>
1629<td align="left">b</td>
1630</tr>
1631</tbody>
1632</table>
1633<x>
1634<h2>List (ordered, 1)</h2>
1635<table>
1636<thead>
1637<tr>
1638<th align="left">a</th>
1639</tr>
1640</thead>
1641<tbody>
1642<tr>
1643<td align="left">b</td>
1644</tr>
1645</tbody>
1646</table>
1647<ol>
1648<li>c</li>
1649</ol>
1650<h2>List (ordered, other)</h2>
1651<table>
1652<thead>
1653<tr>
1654<th align="left">a</th>
1655</tr>
1656</thead>
1657<tbody>
1658<tr>
1659<td align="left">b</td>
1660</tr>
1661</tbody>
1662</table>
1663<ol start="2">
1664<li>c</li>
1665</ol>
1666<h2>List (unordered)</h2>
1667<table>
1668<thead>
1669<tr>
1670<th align="left">a</th>
1671</tr>
1672</thead>
1673<tbody>
1674<tr>
1675<td align="left">b</td>
1676</tr>
1677</tbody>
1678</table>
1679<ul>
1680<li>c</li>
1681</ul>
1682<h2>List (unordered, blank)</h2>
1683<table>
1684<thead>
1685<tr>
1686<th align="left">a</th>
1687</tr>
1688</thead>
1689<tbody>
1690<tr>
1691<td align="left">b</td>
1692</tr>
1693</tbody>
1694</table>
1695<ul>
1696<li></li>
1697</ul>
1698<p>c</p>
1699<h2>List (unordered, blank start)</h2>
1700<table>
1701<thead>
1702<tr>
1703<th align="left">a</th>
1704</tr>
1705</thead>
1706<tbody>
1707<tr>
1708<td align="left">b</td>
1709</tr>
1710</tbody>
1711</table>
1712<ul>
1713<li>c</li>
1714</ul>
1715<h2>Thematic break</h2>
1716<table>
1717<thead>
1718<tr>
1719<th align="left">a</th>
1720</tr>
1721</thead>
1722<tbody>
1723<tr>
1724<td align="left">b</td>
1725</tr>
1726</tbody>
1727</table>
1728<hr />
1729"#,
1730 "should match interrupt like GitHub"
1731 );
1732
1733 assert_eq!(
1734 to_html_with_options(
1735 r###"# Loose
1736
1737## Loose
1738
1739Header 1 | Header 2
1740-------- | --------
1741Cell 1 | Cell 2
1742Cell 3 | Cell 4
1743
1744## One “column”, loose
1745
1746a
1747-
1748b
1749
1750## No pipe in first row
1751
1752a
1753| - |
1754"###,
1755 &Options::gfm()
1756 )?,
1757 r###"<h1>Loose</h1>
1758<h2>Loose</h2>
1759<table>
1760<thead>
1761<tr>
1762<th>Header 1</th>
1763<th>Header 2</th>
1764</tr>
1765</thead>
1766<tbody>
1767<tr>
1768<td>Cell 1</td>
1769<td>Cell 2</td>
1770</tr>
1771<tr>
1772<td>Cell 3</td>
1773<td>Cell 4</td>
1774</tr>
1775</tbody>
1776</table>
1777<h2>One “column”, loose</h2>
1778<h2>a</h2>
1779<p>b</p>
1780<h2>No pipe in first row</h2>
1781<table>
1782<thead>
1783<tr>
1784<th>a</th>
1785</tr>
1786</thead>
1787</table>
1788"###,
1789 "should match loose tables like GitHub"
1790 );
1791
1792 assert_eq!(
1793 to_html_with_options(
1794 r"# Some more escapes
1795
1796| Head |
1797| ------------- |
1798| A | Alpha |
1799| B \| Bravo |
1800| C \\| Charlie |
1801| D \\\| Delta |
1802| E \\\\| Echo |
1803
1804Note: GH has a bug where in case C and E, the escaped escape is treated as a
1805normal escape: <https://github.com/github/cmark-gfm/issues/277>.
1806",
1807 &Options::gfm()
1808 )?,
1809 r#"<h1>Some more escapes</h1>
1810<table>
1811<thead>
1812<tr>
1813<th>Head</th>
1814</tr>
1815</thead>
1816<tbody>
1817<tr>
1818<td>A</td>
1819</tr>
1820<tr>
1821<td>B | Bravo</td>
1822</tr>
1823<tr>
1824<td>C \</td>
1825</tr>
1826<tr>
1827<td>D \| Delta</td>
1828</tr>
1829<tr>
1830<td>E \\</td>
1831</tr>
1832</tbody>
1833</table>
1834<p>Note: GH has a bug where in case C and E, the escaped escape is treated as a
1835normal escape: <a href="https://github.com/github/cmark-gfm/issues/277">https://github.com/github/cmark-gfm/issues/277</a>.</p>
1836"#,
1837 "should match loose escapes like GitHub"
1838 );
1839
1840 assert_eq!(
1841 to_mdast(
1842 "| none | left | right | center |\n| - | :- | -: | :-: |\n| a |\n| b | c | d | e | f |",
1843 &ParseOptions::gfm()
1844 )?,
1845 Node::Root(Root {
1846 children: vec![Node::Table(Table {
1847 align: vec![
1848 AlignKind::None,
1849 AlignKind::Left,
1850 AlignKind::Right,
1851 AlignKind::Center
1852 ],
1853 children: vec![
1854 Node::TableRow(TableRow {
1855 children: vec![
1856 Node::TableCell(TableCell {
1857 children: vec![Node::Text(Text {
1858 value: "none".into(),
1859 position: Some(Position::new(1, 3, 2, 1, 7, 6))
1860 }),],
1861 position: Some(Position::new(1, 1, 0, 1, 8, 7))
1862 }),
1863 Node::TableCell(TableCell {
1864 children: vec![Node::Text(Text {
1865 value: "left".into(),
1866 position: Some(Position::new(1, 10, 9, 1, 14, 13))
1867 }),],
1868 position: Some(Position::new(1, 8, 7, 1, 15, 14))
1869 }),
1870 Node::TableCell(TableCell {
1871 children: vec![Node::Text(Text {
1872 value: "right".into(),
1873 position: Some(Position::new(1, 17, 16, 1, 22, 21))
1874 }),],
1875 position: Some(Position::new(1, 15, 14, 1, 23, 22))
1876 }),
1877 Node::TableCell(TableCell {
1878 children: vec![Node::Text(Text {
1879 value: "center".into(),
1880 position: Some(Position::new(1, 25, 24, 1, 31, 30))
1881 }),],
1882 position: Some(Position::new(1, 23, 22, 1, 33, 32))
1883 }),
1884 ],
1885 position: Some(Position::new(1, 1, 0, 1, 33, 32))
1886 }),
1887 Node::TableRow(TableRow {
1888 children: vec![Node::TableCell(TableCell {
1889 children: vec![Node::Text(Text {
1890 value: "a".into(),
1891 position: Some(Position::new(3, 3, 57, 3, 4, 58))
1892 }),],
1893 position: Some(Position::new(3, 1, 55, 3, 6, 60))
1894 }),],
1895 position: Some(Position::new(3, 1, 55, 3, 6, 60))
1896 }),
1897 Node::TableRow(TableRow {
1898 children: vec![
1899 Node::TableCell(TableCell {
1900 children: vec![Node::Text(Text {
1901 value: "b".into(),
1902 position: Some(Position::new(4, 3, 63, 4, 4, 64))
1903 }),],
1904 position: Some(Position::new(4, 1, 61, 4, 5, 65))
1905 }),
1906 Node::TableCell(TableCell {
1907 children: vec![Node::Text(Text {
1908 value: "c".into(),
1909 position: Some(Position::new(4, 7, 67, 4, 8, 68))
1910 }),],
1911 position: Some(Position::new(4, 5, 65, 4, 9, 69))
1912 }),
1913 Node::TableCell(TableCell {
1914 children: vec![Node::Text(Text {
1915 value: "d".into(),
1916 position: Some(Position::new(4, 11, 71, 4, 12, 72))
1917 }),],
1918 position: Some(Position::new(4, 9, 69, 4, 13, 73))
1919 }),
1920 Node::TableCell(TableCell {
1921 children: vec![Node::Text(Text {
1922 value: "e".into(),
1923 position: Some(Position::new(4, 15, 75, 4, 16, 76))
1924 }),],
1925 position: Some(Position::new(4, 13, 73, 4, 17, 77))
1926 }),
1927 Node::TableCell(TableCell {
1928 children: vec![Node::Text(Text {
1929 value: "f".into(),
1930 position: Some(Position::new(4, 19, 79, 4, 20, 80))
1931 }),],
1932 position: Some(Position::new(4, 17, 77, 4, 22, 82))
1933 }),
1934 ],
1935 position: Some(Position::new(4, 1, 61, 4, 22, 82))
1936 }),
1937 ],
1938 position: Some(Position::new(1, 1, 0, 4, 22, 82))
1939 })],
1940 position: Some(Position::new(1, 1, 0, 4, 22, 82))
1941 }),
1942 "should support GFM tables as `Table`, `TableRow`, `TableCell`s in mdast"
1943 );
1944
1945 assert_eq!(
1946 to_mdast("| `a\\|b` |\n| - |", &ParseOptions::gfm())?,
1947 Node::Root(Root {
1948 children: vec![Node::Table(Table {
1949 align: vec![AlignKind::None,],
1950 children: vec![Node::TableRow(TableRow {
1951 children: vec![Node::TableCell(TableCell {
1952 children: vec![Node::InlineCode(InlineCode {
1953 value: "a|b".into(),
1954 position: Some(Position::new(1, 3, 2, 1, 9, 8))
1955 }),],
1956 position: Some(Position::new(1, 1, 0, 1, 11, 10))
1957 }),],
1958 position: Some(Position::new(1, 1, 0, 1, 11, 10))
1959 }),],
1960 position: Some(Position::new(1, 1, 0, 2, 6, 16))
1961 })],
1962 position: Some(Position::new(1, 1, 0, 2, 6, 16))
1963 }),
1964 "should support weird pipe escapes in code in tables"
1965 );
1966
1967 Ok(())
1968}