Markdown parser fork with extended syntax for personal use.
1use markdown::{
2 mdast::{FootnoteDefinition, FootnoteReference, 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_footnote() -> Result<(), message::Message> {
11 assert_eq!(
12 to_html("A call.[^a]\n\n[^a]: whatevs"),
13 "<p>A call.<a href=\"whatevs\">^a</a></p>\n",
14 "should ignore footnotes by default"
15 );
16
17 assert_eq!(
18 to_html_with_options("A call.[^a]\n\n[^a]: whatevs", &Options::gfm())?,
19 "<p>A call.<sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>
20<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
21<ol>
22<li id=\"user-content-fn-a\">
23<p>whatevs <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
24</li>
25</ol>
26</section>
27",
28 "should support footnotes"
29 );
30
31 assert_eq!(
32 to_html_with_options(
33 "Noot.[^a]\n\n[^a]: dingen",
34 &Options {
35 parse: ParseOptions::gfm(),
36 compile: CompileOptions {
37 gfm_footnote_label: Some("Voetnoten".into()),
38 gfm_footnote_back_label: Some("Terug naar de inhoud".into()),
39 ..CompileOptions::gfm()
40 }
41 }
42 )?,
43 "<p>Noot.<sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>
44<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Voetnoten</h2>
45<ol>
46<li id=\"user-content-fn-a\">
47<p>dingen <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Terug naar de inhoud\" class=\"data-footnote-backref\">↩</a></p>
48</li>
49</ol>
50</section>
51",
52 "should support `options.gfm_footnote_label`, `options.gfm_footnote_back_label`"
53 );
54
55 assert_eq!(
56 to_html_with_options(
57 "[^a]\n\n[^a]: b",
58 &Options {
59 parse: ParseOptions::gfm(),
60 compile: CompileOptions {
61 gfm_footnote_label_tag_name: Some("h1".into()),
62 ..CompileOptions::gfm()
63 }
64 }
65 )?,
66 "<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>
67<section data-footnotes=\"\" class=\"footnotes\"><h1 id=\"footnote-label\" class=\"sr-only\">Footnotes</h1>
68<ol>
69<li id=\"user-content-fn-a\">
70<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
71</li>
72</ol>
73</section>
74",
75 "should support `options.gfm_footnote_label_tag_name`"
76 );
77
78 assert_eq!(
79 to_html_with_options(
80 "[^a]\n\n[^a]: b",
81 &Options {
82 parse: ParseOptions::gfm(),
83 compile: CompileOptions {
84 gfm_footnote_label_attributes: Some("class=\"footnote-heading\"".into()),
85 ..CompileOptions::gfm()
86 }
87 }
88 )?,
89 "<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>
90<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"footnote-heading\">Footnotes</h2>
91<ol>
92<li id=\"user-content-fn-a\">
93<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
94</li>
95</ol>
96</section>
97",
98 "should support `options.gfm_footnote_label_attributes`"
99 );
100
101 assert_eq!(
102 to_html_with_options(
103 "[^a]\n\n[^a]: b",
104 &Options {
105 parse: ParseOptions::gfm(),
106 compile: CompileOptions {
107 gfm_footnote_clobber_prefix: Some("".into()),
108 ..CompileOptions::gfm()
109 }
110 }
111 )?,
112 "<p><sup><a href=\"#fn-a\" id=\"fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>
113<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
114<ol>
115<li id=\"fn-a\">
116<p>b <a href=\"#fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
117</li>
118</ol>
119</section>
120",
121 "should support `options.gfm_footnote_clobber_prefix`"
122 );
123
124 assert_eq!(
125 to_html_with_options("A paragraph.\n\n[^a]: whatevs", &Options::gfm())?,
126 "<p>A paragraph.</p>\n",
127 "should ignore definitions w/o calls"
128 );
129
130 assert_eq!(
131 to_html_with_options("a[^b]", &Options::gfm())?,
132 "<p>a[^b]</p>",
133 "should ignore calls w/o definitions"
134 );
135
136 assert_eq!(
137 to_html_with_options("a[^b]\n\n[^b]: c\n[^b]: d", &Options::gfm())?,
138 "<p>a<sup><a href=\"#user-content-fn-b\" id=\"user-content-fnref-b\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>
139<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
140<ol>
141<li id=\"user-content-fn-b\">
142<p>c <a href=\"#user-content-fnref-b\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
143</li>
144</ol>
145</section>
146",
147 "should use the first of duplicate definitions"
148 );
149
150 assert_eq!(
151 to_html_with_options("a[^b], c[^b]\n\n[^b]: d", &Options::gfm())?,
152 "<p>a<sup><a href=\"#user-content-fn-b\" id=\"user-content-fnref-b\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>, c<sup><a href=\"#user-content-fn-b\" id=\"user-content-fnref-b-2\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>
153<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
154<ol>
155<li id=\"user-content-fn-b\">
156<p>d <a href=\"#user-content-fnref-b\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a> <a href=\"#user-content-fnref-b-2\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩<sup>2</sup></a></p>
157</li>
158</ol>
159</section>
160",
161 "should supports multiple calls to the same definition"
162 );
163
164 assert_eq!(
165 to_html_with_options("", &Options::gfm())?,
166 "<p>!<a href=\"b\">^a</a></p>",
167 "should not support images starting w/ `^` (but see it as a link?!, 1)"
168 );
169
170 assert_eq!(
171 to_html_with_options("![^a][b]\n\n[b]: c", &Options::gfm())?,
172 "<p>!<a href=\"c\">^a</a></p>\n",
173 "should not support images starting w/ `^` (but see it as a link?!, 2)"
174 );
175
176 assert_eq!(
177 to_html_with_options("[^]()", &Options::gfm())?,
178 "<p><a href=\"\">^</a></p>",
179 "should support an empty link with caret"
180 );
181
182 assert_eq!(
183 to_html_with_options("![^]()", &Options::gfm())?,
184 "<p>!<a href=\"\">^</a></p>",
185 "should support an empty image with caret (as link)"
186 );
187
188 // <https://github.com/github/cmark-gfm/issues/239>
189 assert_eq!(
190 to_html_with_options("Call.[^a\\+b].\n\n[^a\\+b]: y", &Options::gfm())?,
191 "<p>Call.<sup><a href=\"#user-content-fn-a%5C+b\" id=\"user-content-fnref-a%5C+b\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
192<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
193<ol>
194<li id=\"user-content-fn-a%5C+b\">
195<p>y <a href=\"#user-content-fnref-a%5C+b\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
196</li>
197</ol>
198</section>
199",
200 "should support a character escape in a call / definition"
201 );
202
203 assert_eq!(
204 to_html_with_options("Call.[^a©b].\n\n[^a©b]: y", &Options::gfm())?,
205 "<p>Call.<sup><a href=\"#user-content-fn-a&copy;b\" id=\"user-content-fnref-a&copy;b\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
206<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
207<ol>
208<li id=\"user-content-fn-a&copy;b\">
209<p>y <a href=\"#user-content-fnref-a&copy;b\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
210</li>
211</ol>
212</section>
213",
214 "should support a character reference in a call / definition"
215 );
216
217 // <https://github.com/github/cmark-gfm/issues/239>
218 // <https://github.com/github/cmark-gfm/issues/240>
219 assert_eq!(
220 to_html_with_options("Call.[^a\\]b].\n\n[^a\\]b]: y", &Options::gfm())?,
221 "<p>Call.<sup><a href=\"#user-content-fn-a%5C%5Db\" id=\"user-content-fnref-a%5C%5Db\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
222<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
223<ol>
224<li id=\"user-content-fn-a%5C%5Db\">
225<p>y <a href=\"#user-content-fnref-a%5C%5Db\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
226</li>
227</ol>
228</section>
229",
230 "should support a useful character escape in a call / definition"
231 );
232
233 assert_eq!(
234 to_html_with_options("Call.[^a[b].\n\n[^a[b]: y", &Options::gfm())?,
235 "<p>Call.<sup><a href=\"#user-content-fn-a&#91;b\" id=\"user-content-fnref-a&#91;b\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
236<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
237<ol>
238<li id=\"user-content-fn-a&#91;b\">
239<p>y <a href=\"#user-content-fnref-a&#91;b\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
240</li>
241</ol>
242</section>
243",
244 "should support a useful character reference in a call / definition"
245 );
246
247 assert_eq!(
248 to_html_with_options("Call.[^a\\+b].\n\n[^a+b]: y", &Options::gfm())?,
249 "<p>Call.[^a+b].</p>\n",
250 "should match calls to definitions on the source of the label, not on resolved escapes"
251 );
252
253 assert_eq!(
254 to_html_with_options("Call.[^a[b].\n\n[^a\\[b]: y", &Options::gfm())?,
255 "<p>Call.[^a[b].</p>\n",
256 "should match calls to definitions on the source of the label, not on resolved references"
257 );
258
259 assert_eq!(
260 to_html_with_options("[^1].\n\n[^1]: a\nb", &Options::gfm())?,
261 "<p><sup><a href=\"#user-content-fn-1\" id=\"user-content-fnref-1\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
262<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
263<ol>
264<li id=\"user-content-fn-1\">
265<p>a
266b <a href=\"#user-content-fnref-1\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
267</li>
268</ol>
269</section>
270",
271 "should support lazyness (1)"
272 );
273
274 assert_eq!(
275 to_html_with_options("[^1].\n\n> [^1]: a\nb", &Options::gfm())?,
276 "<p><sup><a href=\"#user-content-fn-1\" id=\"user-content-fnref-1\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
277<blockquote>
278</blockquote>
279<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
280<ol>
281<li id=\"user-content-fn-1\">
282<p>a
283b <a href=\"#user-content-fnref-1\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
284</li>
285</ol>
286</section>
287",
288 "should support lazyness (2)"
289 );
290
291 assert_eq!(
292 to_html_with_options("[^1].\n\n> [^1]: a\n> b", &Options::gfm())?,
293 "<p><sup><a href=\"#user-content-fn-1\" id=\"user-content-fnref-1\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
294<blockquote>
295</blockquote>
296<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
297<ol>
298<li id=\"user-content-fn-1\">
299<p>a
300b <a href=\"#user-content-fnref-1\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
301</li>
302</ol>
303</section>
304",
305 "should support lazyness (3)"
306 );
307
308 assert_eq!(
309 to_html_with_options("[^1].\n\n[^1]: a\n\n > b", &Options::gfm())?,
310 "<p><sup><a href=\"#user-content-fn-1\" id=\"user-content-fnref-1\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
311<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
312<ol>
313<li id=\"user-content-fn-1\">
314<p>a</p>
315<blockquote>
316<p>b</p>
317</blockquote>
318<a href=\"#user-content-fnref-1\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a>
319</li>
320</ol>
321</section>
322",
323 "should support lazyness (4)"
324 );
325
326 // 999 `x` characters.
327 let max = "x".repeat(999);
328
329 assert_eq!(
330 to_html_with_options(format!("Call.[^{}].\n\n[^{}]: y", max, max).as_str(), &Options::gfm())?,
331 format!("<p>Call.<sup><a href=\"#user-content-fn-{}\" id=\"user-content-fnref-{}\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup>.</p>
332<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
333<ol>
334<li id=\"user-content-fn-{}\">
335<p>y <a href=\"#user-content-fnref-{}\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
336</li>
337</ol>
338</section>
339", max, max, max, max),
340 "should support 999 characters in a call / definition"
341 );
342
343 assert_eq!(
344 to_html_with_options(
345 format!("Call.[^a{}].\n\n[^a{}]: y", max, max).as_str(),
346 &Options::gfm()
347 )?,
348 format!("<p>Call.[^a{}].</p>\n<p>[^a{}]: y</p>", max, max),
349 "should not support 1000 characters in a call / definition"
350 );
351
352 assert_eq!(
353 to_html_with_options(
354 "[^a]\n\n[^a]: b\n \n c",
355 &Options::gfm()
356 )?,
357 "<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"\" aria-describedby=\"footnote-label\">1</a></sup></p>
358<section data-footnotes=\"\" class=\"footnotes\"><h2 id=\"footnote-label\" class=\"sr-only\">Footnotes</h2>
359<ol>
360<li id=\"user-content-fn-a\">
361<p>b</p>
362<p>c <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to content\" class=\"data-footnote-backref\">↩</a></p>
363</li>
364</ol>
365</section>\n",
366 "should support blank lines in footnote definitions"
367 );
368
369 assert_eq!(
370 to_html_with_options(
371 r"a
372a\
373a![i][]
374a![^1]
375[^1]
376^1]
377
378[^1]: b
379
380[i]: c",
381 &Options::gfm()
382 )?,
383 r##"<p>a<img src="#" alt="i" />
384a!<a href="#">i</a>
385a<img src="c" alt="i" />
386a!<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup>
387<sup><a href="#user-content-fn-1" id="user-content-fnref-1-2" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup>
388^1]</p>
389<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
390<ol>
391<li id="user-content-fn-1">
392<p>b <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a> <a href="#user-content-fnref-1-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩<sup>2</sup></a></p>
393</li>
394</ol>
395</section>
396"##,
397 "should match bang/caret interplay like GitHub"
398 );
399
400 assert_eq!(
401 to_html_with_options("a![^1]", &Options::gfm())?,
402 "<p>a![^1]</p>",
403 "should match bang/caret interplay (undefined) like GitHub"
404 );
405
406 assert_eq!(
407 to_html_with_options(
408 r###"a![^1]
409
410[^1]: b
411"###,
412 &Options::gfm()
413 )?,
414 r##"<p>a!<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup></p>
415<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
416<ol>
417<li id="user-content-fn-1">
418<p>b <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
419</li>
420</ol>
421</section>
422"##,
423 "should match bang/caret like GitHub"
424 );
425
426 assert_eq!(
427 to_html_with_options(
428 r###"Calls may not be empty: [^].
429
430Calls cannot contain whitespace only: [^ ].
431
432Calls cannot contain whitespace at all: [^ ], [^ ], [^
433].
434
435Calls can contain other characters, such as numbers [^1234567890], or [^^]
436even another caret.
437
438[^]: empty
439
440[^ ]: space
441
442[^ ]: tab
443
444[^
445]: line feed
446
447[^1234567890]: numbers
448
449[^^]: caret
450"###,
451 &Options::gfm()
452 )?,
453 r##"<p>Calls may not be empty: <a href="empty">^</a>.</p>
454<p>Calls cannot contain whitespace only: <a href="empty">^ </a>.</p>
455<p>Calls cannot contain whitespace at all: <a href="empty">^ </a>, <a href="empty">^ </a>, <a href="empty">^
456</a>.</p>
457<p>Calls can contain other characters, such as numbers <sup><a href="#user-content-fn-1234567890" id="user-content-fnref-1234567890" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup>, or <sup><a href="#user-content-fn-%5E" id="user-content-fnref-%5E" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup>
458even another caret.</p>
459<p><a href="empty">^
460</a>: line feed</p>
461<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
462<ol>
463<li id="user-content-fn-1234567890">
464<p>numbers <a href="#user-content-fnref-1234567890" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
465</li>
466<li id="user-content-fn-%5E">
467<p>caret <a href="#user-content-fnref-%5E" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
468</li>
469</ol>
470</section>
471"##,
472 "should match calls like GitHub"
473 );
474
475 // Note:
476 // * GH does not support line ending in call.
477 // See: <https://github.com/github/cmark-gfm/issues/282>
478 // Here line endings don’t make text disappear.
479 assert_eq!(
480 to_html_with_options(
481 r###"[^a]: # b
482
483[^c d]: # e
484
485[^f g]: # h
486
487[^i
488j]: # k
489
490[^ l]: # l
491
492[^m ]: # m
493
494xxx[^a], [^c d], [^f g], [^i
495j], [^ l], [^m ]
496
497---
498
499Some calls.[^ w][^x ][^y][^z]
500
501[^w]: # w
502
503[^x]: # x
504
505[^ y]: # y
506
507[^x ]: # z
508"###,
509 &Options::gfm()
510 )?,
511 r##"<p>[^c d]: # e</p>
512<p>[^f g]: # h</p>
513<p>[^i
514j]: # k</p>
515<p>[^ l]: # l</p>
516<p>[^m ]: # m</p>
517<p>xxx<sup><a href="#user-content-fn-a" id="user-content-fnref-a" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup>, [^c d], [^f g], [^i
518j], [^ l], [^m ]</p>
519<hr />
520<p>Some calls.<sup><a href="#user-content-fn-w" id="user-content-fnref-w" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-x" id="user-content-fnref-x" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup>[^y][^z]</p>
521<p>[^ y]: # y</p>
522<p><sup><a href="#user-content-fn-x" id="user-content-fnref-x-2" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup>: # z</p>
523<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
524<ol>
525<li id="user-content-fn-a">
526<h1>b</h1>
527<a href="#user-content-fnref-a" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
528</li>
529<li id="user-content-fn-w">
530<h1>w</h1>
531<a href="#user-content-fnref-w" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
532</li>
533<li id="user-content-fn-x">
534<h1>x</h1>
535<a href="#user-content-fnref-x" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a> <a href="#user-content-fnref-x-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩<sup>2</sup></a>
536</li>
537</ol>
538</section>
539"##,
540 "should match whitespace in calls like GitHub (except for the bugs)"
541 );
542
543 assert_eq!(
544 to_html_with_options(
545 r###"[^*emphasis*]
546
547[^**strong**]
548
549[^`code`]
550
551[^www.example.com]
552
553[^https://example.com]
554
555[^://example.com]
556
557[^[link](#)]
558
559[^]
560
561[^*emphasis*]: a
562
563[^**strong**]: a
564
565[^`code`]: a
566
567[^www.example.com]: a
568
569[^https://example.com]: a
570
571[^://example.com]: a
572
573[^[link](#)]: a
574
575[^]: a
576"###,
577 &Options::gfm()
578 )?,
579 // Note:
580 // * GH does not support colons.
581 // See: <https://github.com/github/cmark-gfm/issues/250>
582 // Here identifiers that include colons *do* work (so they’re added below).
583 // * GH does not support footnote-like brackets around an image.
584 // See: <https://github.com/github/cmark-gfm/issues/275>
585 // Here images are fine.
586 r##"<p><sup><a href="#user-content-fn-*emphasis*" id="user-content-fnref-*emphasis*" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup></p>
587<p><sup><a href="#user-content-fn-**strong**" id="user-content-fnref-**strong**" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup></p>
588<p><sup><a href="#user-content-fn-%60code%60" id="user-content-fnref-%60code%60" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup></p>
589<p><sup><a href="#user-content-fn-www.example.com" id="user-content-fnref-www.example.com" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup></p>
590<p><sup><a href="#user-content-fn-https://example.com" id="user-content-fnref-https://example.com" data-footnote-ref="" aria-describedby="footnote-label">5</a></sup></p>
591<p><sup><a href="#user-content-fn-://example.com" id="user-content-fnref-://example.com" data-footnote-ref="" aria-describedby="footnote-label">6</a></sup></p>
592<p>[^<a href="#">link</a>]</p>
593<p>[^<img src="#" alt="image" />]</p>
594<p>[^<a href="#">link</a>]: a</p>
595<p>[^<img src="#" alt="image" />]: a</p>
596<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
597<ol>
598<li id="user-content-fn-*emphasis*">
599<p>a <a href="#user-content-fnref-*emphasis*" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
600</li>
601<li id="user-content-fn-**strong**">
602<p>a <a href="#user-content-fnref-**strong**" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
603</li>
604<li id="user-content-fn-%60code%60">
605<p>a <a href="#user-content-fnref-%60code%60" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
606</li>
607<li id="user-content-fn-www.example.com">
608<p>a <a href="#user-content-fnref-www.example.com" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
609</li>
610<li id="user-content-fn-https://example.com">
611<p>a <a href="#user-content-fnref-https://example.com" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
612</li>
613<li id="user-content-fn-://example.com">
614<p>a <a href="#user-content-fnref-://example.com" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
615</li>
616</ol>
617</section>
618"##,
619 "should match construct identifiers like GitHub (except for its bugs)"
620 );
621
622 assert_eq!(
623 to_html_with_options(
624 r###"Call[^1][^2][^3][^4]
625
626> [^1]: Defined in a block quote.
627>
628> More.
629[^2]: Directly after a block quote.
630
631* [^3]: Defined in a list item.
632
633 More.
634[^4]: Directly after a list item.
635"###,
636 &Options::gfm()
637 )?,
638 r##"<p>Call<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup></p>
639<blockquote>
640<p>More.</p>
641</blockquote>
642<ul>
643<li>
644<p>More.</p>
645</li>
646</ul>
647<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
648<ol>
649<li id="user-content-fn-1">
650<p>Defined in a block quote. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
651</li>
652<li id="user-content-fn-2">
653<p>Directly after a block quote. <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
654</li>
655<li id="user-content-fn-3">
656<p>Defined in a list item. <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
657</li>
658<li id="user-content-fn-4">
659<p>Directly after a list item. <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
660</li>
661</ol>
662</section>
663"##,
664 "should match containers like GitHub"
665 );
666
667 assert_eq!(
668 to_html_with_options(
669 r###"[^1][^2][^3][^4]
670
671[^1]: Paragraph
672…continuation
673
674# Heading
675
676[^2]: Paragraph
677…continuation
678
679 “code”, which is paragraphs…
680
681 …because of the indent!
682
683[^3]: Paragraph
684…continuation
685
686> block quote
687
688[^4]: Paragraph
689…continuation
690
691- list
692"###,
693 &Options::gfm()
694 )?,
695 r##"<p><sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup></p>
696<h1>Heading</h1>
697<blockquote>
698<p>block quote</p>
699</blockquote>
700<ul>
701<li>list</li>
702</ul>
703<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
704<ol>
705<li id="user-content-fn-1">
706<p>Paragraph
707…continuation <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
708</li>
709<li id="user-content-fn-2">
710<p>Paragraph
711…continuation</p>
712<p>“code”, which is paragraphs…</p>
713<p>…because of the indent! <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
714</li>
715<li id="user-content-fn-3">
716<p>Paragraph
717…continuation <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
718</li>
719<li id="user-content-fn-4">
720<p>Paragraph
721…continuation <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
722</li>
723</ol>
724</section>
725"##,
726 "should match continuation like GitHub"
727 );
728
729 assert_eq!(
730 to_html_with_options(
731 r###"Call[^1][^2][^3][^4][^5].
732
733[^1]:
734 ---
735
736[^2]:
737 Paragraph.
738
739[^3]:
740Lazy?
741
742[^4]:
743
744 Another blank.
745
746[^5]:
747
748Lazy!
749"###,
750 &Options::gfm()
751 )?,
752 r##"<p>Call<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup><sup><a href="#user-content-fn-5" id="user-content-fnref-5" data-footnote-ref="" aria-describedby="footnote-label">5</a></sup>.</p>
753<p>Lazy?</p>
754<p>Lazy!</p>
755<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
756<ol>
757<li id="user-content-fn-1">
758<hr />
759<a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
760</li>
761<li id="user-content-fn-2">
762<p>Paragraph. <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
763</li>
764<li id="user-content-fn-3">
765<a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
766</li>
767<li id="user-content-fn-4">
768<p>Another blank. <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
769</li>
770<li id="user-content-fn-5">
771<a href="#user-content-fnref-5" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
772</li>
773</ol>
774</section>
775"##,
776 "should match definitions initial blank like GitHub"
777 );
778
779 assert_eq!(
780 to_html_with_options(
781 r###"Note![^0][^1][^2][^3][^4][^5][^6][^7][^8][^9][^10]
782
783[^0]: alpha
784
785[^1]: bravo
786
787[^2]: charlie
788 indented delta
789
790[^3]: echo
791
792[^4]: foxtrot
793
794[^5]:> golf
795
796[^6]: > hotel
797
798[^7]: > india
799
800[^8]: # juliett
801
802[^9]: ---
803
804[^10]:- - - kilo
805"###,
806 &Options::gfm()
807 )?,
808 r##"<p>Note!<sup><a href="#user-content-fn-0" id="user-content-fnref-0" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">5</a></sup><sup><a href="#user-content-fn-5" id="user-content-fnref-5" data-footnote-ref="" aria-describedby="footnote-label">6</a></sup><sup><a href="#user-content-fn-6" id="user-content-fnref-6" data-footnote-ref="" aria-describedby="footnote-label">7</a></sup><sup><a href="#user-content-fn-7" id="user-content-fnref-7" data-footnote-ref="" aria-describedby="footnote-label">8</a></sup><sup><a href="#user-content-fn-8" id="user-content-fnref-8" data-footnote-ref="" aria-describedby="footnote-label">9</a></sup><sup><a href="#user-content-fn-9" id="user-content-fnref-9" data-footnote-ref="" aria-describedby="footnote-label">10</a></sup><sup><a href="#user-content-fn-10" id="user-content-fnref-10" data-footnote-ref="" aria-describedby="footnote-label">11</a></sup></p>
809<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
810<ol>
811<li id="user-content-fn-0">
812<p>alpha <a href="#user-content-fnref-0" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
813</li>
814<li id="user-content-fn-1">
815<p>bravo <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
816</li>
817<li id="user-content-fn-2">
818<p>charlie
819indented delta <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
820</li>
821<li id="user-content-fn-3">
822<p>echo <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
823</li>
824<li id="user-content-fn-4">
825<p>foxtrot <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
826</li>
827<li id="user-content-fn-5">
828<blockquote>
829<p>golf</p>
830</blockquote>
831<a href="#user-content-fnref-5" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
832</li>
833<li id="user-content-fn-6">
834<blockquote>
835<p>hotel</p>
836</blockquote>
837<a href="#user-content-fnref-6" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
838</li>
839<li id="user-content-fn-7">
840<blockquote>
841<p>india</p>
842</blockquote>
843<a href="#user-content-fnref-7" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
844</li>
845<li id="user-content-fn-8">
846<h1>juliett</h1>
847<a href="#user-content-fnref-8" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
848</li>
849<li id="user-content-fn-9">
850<hr />
851<a href="#user-content-fnref-9" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
852</li>
853<li id="user-content-fn-10">
854<ul>
855<li>
856<ul>
857<li>
858<ul>
859<li>kilo</li>
860</ul>
861</li>
862</ul>
863</li>
864</ul>
865<a href="#user-content-fnref-10" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
866</li>
867</ol>
868</section>
869"##,
870 "should match definitions like GitHub"
871 );
872
873 assert_eq!(
874 to_html_with_options(
875 r###"Call[^1][^1]
876
877[^1]: Recursion[^1][^1]
878"###,
879 &Options::gfm()
880 )?,
881 r##"<p>Call<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-1" id="user-content-fnref-1-2" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup></p>
882<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
883<ol>
884<li id="user-content-fn-1">
885<p>Recursion<sup><a href="#user-content-fn-1" id="user-content-fnref-1-3" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-1" id="user-content-fnref-1-4" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup> <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a> <a href="#user-content-fnref-1-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩<sup>2</sup></a> <a href="#user-content-fnref-1-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩<sup>3</sup></a> <a href="#user-content-fnref-1-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩<sup>4</sup></a></p>
886</li>
887</ol>
888</section>
889"##,
890 "should match duplicate calls and recursion like GitHub"
891 );
892
893 assert_eq!(
894 to_html_with_options(
895 r###"Call[^1]
896
897[^1]: a
898
899[^1]: b
900"###,
901 &Options::gfm()
902 )?,
903 r##"<p>Call<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup></p>
904<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
905<ol>
906<li id="user-content-fn-1">
907<p>a <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
908</li>
909</ol>
910</section>
911"##,
912 "should match duplicate definitions like GitHub"
913 );
914
915 // Note:
916 // * GH “supports” footnotes inside links.
917 // This breaks an HTML parser, as it is not allowed.
918 // See: <https://github.com/github/cmark-gfm/issues/275>
919 // CommonMark has mechanisms in place to prevent links in links.
920 // These mechanisms are in place here too.
921 assert_eq!(
922 to_html_with_options(
923 r###"*emphasis[^1]*
924
925**strong[^2]**
926
927`code[^3]`
928
929![image[^4]](#)
930
931[link[^5]](#)
932
933[^1]: a
934
935[^2]: b
936
937[^3]: c
938
939[^4]: d
940
941[^5]: e
942"###,
943 &Options::gfm()
944 )?,
945 r##"<p><em>emphasis<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup></em></p>
946<p><strong>strong<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup></strong></p>
947<p><code>code[^3]</code></p>
948<p><img src="#" alt="image" /></p>
949<p>[link<sup><a href="#user-content-fn-5" id="user-content-fnref-5" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup>](#)</p>
950<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
951<ol>
952<li id="user-content-fn-1">
953<p>a <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
954</li>
955<li id="user-content-fn-2">
956<p>b <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
957</li>
958<li id="user-content-fn-4">
959<p>d <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
960</li>
961<li id="user-content-fn-5">
962<p>e <a href="#user-content-fnref-5" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
963</li>
964</ol>
965</section>
966"##,
967 "should match footnotes in constructs like GitHub (without the bugs)"
968 );
969
970 assert_eq!(
971 to_html_with_options(
972 r###"What are these![^1], ![^2][], and ![this][^3].
973
974[^1]: a
975
976[^2]: b
977
978[^3]: c
979"###,
980 &Options::gfm()
981 )?,
982 r##"<p>What are these!<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup>, !<sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup>[], and ![this]<sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup>.</p>
983<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
984<ol>
985<li id="user-content-fn-1">
986<p>a <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
987</li>
988<li id="user-content-fn-2">
989<p>b <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
990</li>
991<li id="user-content-fn-3">
992<p>c <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
993</li>
994</ol>
995</section>
996"##,
997 "should match images/footnotes like GitHub"
998 );
999
1000 assert_eq!(
1001 to_html_with_options(
1002 r###"[^0][^1][^2][^3][^4][^5]
1003
1004[^0]: Paragraph
1005…continuation
1006[^1]: Another
1007[^2]: Paragraph
1008…continuation
1009# Heading
1010[^3]: Paragraph
1011…continuation
1012 “code”, which is paragraphs…
1013
1014 …because of the indent!
1015[^4]: Paragraph
1016…continuation
1017> block quote
1018[^5]: Paragraph
1019…continuation
1020* list
1021"###,
1022 &Options::gfm()
1023 )?,
1024 r##"<p><sup><a href="#user-content-fn-0" id="user-content-fnref-0" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">5</a></sup><sup><a href="#user-content-fn-5" id="user-content-fnref-5" data-footnote-ref="" aria-describedby="footnote-label">6</a></sup></p>
1025<h1>Heading</h1>
1026<blockquote>
1027<p>block quote</p>
1028</blockquote>
1029<ul>
1030<li>list</li>
1031</ul>
1032<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1033<ol>
1034<li id="user-content-fn-0">
1035<p>Paragraph
1036…continuation <a href="#user-content-fnref-0" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1037</li>
1038<li id="user-content-fn-1">
1039<p>Another <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1040</li>
1041<li id="user-content-fn-2">
1042<p>Paragraph
1043…continuation <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1044</li>
1045<li id="user-content-fn-3">
1046<p>Paragraph
1047…continuation
1048“code”, which is paragraphs…</p>
1049<p>…because of the indent! <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1050</li>
1051<li id="user-content-fn-4">
1052<p>Paragraph
1053…continuation <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1054</li>
1055<li id="user-content-fn-5">
1056<p>Paragraph
1057…continuation <a href="#user-content-fnref-5" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1058</li>
1059</ol>
1060</section>
1061"##,
1062 "should match interrupt like GitHub"
1063 );
1064
1065 assert_eq!(
1066 to_html_with_options(
1067 r###"What are these[^1], [^2][], and [this][^3].
1068
1069[^1]: a
1070
1071[^2]: b
1072
1073[^3]: c
1074"###,
1075 &Options::gfm()
1076 )?,
1077 r##"<p>What are these<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup>, <sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup>[], and [this]<sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup>.</p>
1078<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1079<ol>
1080<li id="user-content-fn-1">
1081<p>a <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1082</li>
1083<li id="user-content-fn-2">
1084<p>b <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1085</li>
1086<li id="user-content-fn-3">
1087<p>c <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1088</li>
1089</ol>
1090</section>
1091"##,
1092 "should match links/footnotes like GitHub"
1093 );
1094
1095 assert_eq!(
1096 to_html_with_options(
1097 r###"[^1][^2][^3][^4]
1098
1099[^1]: Paragraph
1100
1101
1102# Heading
1103
1104
1105[^2]: Paragraph
1106
1107
1108 “code”, which is paragraphs…
1109
1110
1111 …because of the indent!
1112
1113
1114[^3]: Paragraph
1115
1116
1117> block quote
1118
1119
1120[^4]: Paragraph
1121
1122
1123- list
1124"###,
1125 &Options::gfm()
1126 )?,
1127 r##"<p><sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup></p>
1128<h1>Heading</h1>
1129<blockquote>
1130<p>block quote</p>
1131</blockquote>
1132<ul>
1133<li>list</li>
1134</ul>
1135<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1136<ol>
1137<li id="user-content-fn-1">
1138<p>Paragraph <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1139</li>
1140<li id="user-content-fn-2">
1141<p>Paragraph</p>
1142<p>“code”, which is paragraphs…</p>
1143<p>…because of the indent! <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1144</li>
1145<li id="user-content-fn-3">
1146<p>Paragraph <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1147</li>
1148<li id="user-content-fn-4">
1149<p>Paragraph <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1150</li>
1151</ol>
1152</section>
1153"##,
1154 "should match many blank lines/no indent like GitHub"
1155 );
1156
1157 assert_eq!(
1158 to_html_with_options(
1159 r###"[^1][^2][^3][^4]
1160
1161[^1]: Paragraph
1162
1163
1164 # Heading
1165
1166
1167[^2]: Paragraph
1168
1169
1170 code
1171
1172
1173 more code
1174
1175
1176[^3]: Paragraph
1177
1178
1179 > block quote
1180
1181
1182[^4]: Paragraph
1183
1184
1185 - list
1186"###,
1187 &Options::gfm()
1188 )?,
1189 r##"<p><sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup></p>
1190<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1191<ol>
1192<li id="user-content-fn-1">
1193<p>Paragraph</p>
1194<h1>Heading</h1>
1195<a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1196</li>
1197<li id="user-content-fn-2">
1198<p>Paragraph</p>
1199<pre><code>code
1200
1201
1202more code
1203</code></pre>
1204<a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1205</li>
1206<li id="user-content-fn-3">
1207<p>Paragraph</p>
1208<blockquote>
1209<p>block quote</p>
1210</blockquote>
1211<a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1212</li>
1213<li id="user-content-fn-4">
1214<p>Paragraph</p>
1215<ul>
1216<li>list</li>
1217</ul>
1218<a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1219</li>
1220</ol>
1221</section>
1222"##,
1223 "should match many blank lines like GitHub"
1224 );
1225
1226 assert_eq!(
1227 to_html_with_options(
1228 r###"Note![^1][^2][^3][^4]
1229
1230- [^1]: Paragraph
1231
1232> [^2]: Paragraph
1233
1234[^3]: [^4]: Paragraph
1235"###,
1236 &Options::gfm()
1237 )?,
1238 r##"<p>Note!<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup></p>
1239<ul>
1240<li></li>
1241</ul>
1242<blockquote>
1243</blockquote>
1244<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1245<ol>
1246<li id="user-content-fn-1">
1247<p>Paragraph <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1248</li>
1249<li id="user-content-fn-2">
1250<p>Paragraph <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1251</li>
1252<li id="user-content-fn-3">
1253<a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1254</li>
1255<li id="user-content-fn-4">
1256<p>Paragraph <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1257</li>
1258</ol>
1259</section>
1260"##,
1261 "should match nest like GitHub"
1262 );
1263
1264 assert_eq!(
1265 to_html_with_options(
1266 r###"[^1][^2][^3][^4]
1267
1268[^1]: Paragraph
1269
1270# Heading
1271
1272[^2]: Paragraph
1273
1274 “code”, which is paragraphs…
1275
1276 …because of the indent!
1277
1278[^3]: Paragraph
1279
1280> block quote
1281
1282[^4]: Paragraph
1283
1284- list
1285"###,
1286 &Options::gfm()
1287 )?,
1288 r##"<p><sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup></p>
1289<h1>Heading</h1>
1290<blockquote>
1291<p>block quote</p>
1292</blockquote>
1293<ul>
1294<li>list</li>
1295</ul>
1296<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1297<ol>
1298<li id="user-content-fn-1">
1299<p>Paragraph <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1300</li>
1301<li id="user-content-fn-2">
1302<p>Paragraph</p>
1303<p>“code”, which is paragraphs…</p>
1304<p>…because of the indent! <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1305</li>
1306<li id="user-content-fn-3">
1307<p>Paragraph <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1308</li>
1309<li id="user-content-fn-4">
1310<p>Paragraph <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1311</li>
1312</ol>
1313</section>
1314"##,
1315 "should match normal blank lines/no indent like GitHub"
1316 );
1317
1318 assert_eq!(
1319 to_html_with_options(
1320 r###"[^1][^2][^3][^4]
1321
1322[^1]: Paragraph
1323
1324 # Heading
1325
1326[^2]: Paragraph
1327
1328 code
1329
1330 more code
1331
1332[^3]: Paragraph
1333
1334 > block quote
1335
1336[^4]: Paragraph
1337
1338 - list
1339"###,
1340 &Options::gfm()
1341 )?,
1342 r##"<p><sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup></p>
1343<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1344<ol>
1345<li id="user-content-fn-1">
1346<p>Paragraph</p>
1347<h1>Heading</h1>
1348<a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1349</li>
1350<li id="user-content-fn-2">
1351<p>Paragraph</p>
1352<pre><code>code
1353
1354more code
1355</code></pre>
1356<a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1357</li>
1358<li id="user-content-fn-3">
1359<p>Paragraph</p>
1360<blockquote>
1361<p>block quote</p>
1362</blockquote>
1363<a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1364</li>
1365<li id="user-content-fn-4">
1366<p>Paragraph</p>
1367<ul>
1368<li>list</li>
1369</ul>
1370<a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1371</li>
1372</ol>
1373</section>
1374"##,
1375 "should match normal blank lines like GitHub"
1376 );
1377
1378 assert_eq!(
1379 to_html_with_options(
1380 r###"Here is a footnote reference,[^1] and another.[^longnote]
1381
1382[^1]: Here is the footnote.
1383
1384[^longnote]: Here’s one with multiple blocks.
1385
1386 Subsequent paragraphs are indented to show that they
1387belong to the previous footnote.
1388
1389 { some.code }
1390
1391 The whole paragraph can be indented, or just the first
1392 line. In this way, multi-paragraph footnotes work like
1393 multi-paragraph list items.
1394
1395This paragraph won’t be part of the note, because it
1396isn’t indented.
1397"###,
1398 &Options::gfm()
1399 )?,
1400 r##"<p>Here is a footnote reference,<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup> and another.<sup><a href="#user-content-fn-longnote" id="user-content-fnref-longnote" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup></p>
1401<p>This paragraph won’t be part of the note, because it
1402isn’t indented.</p>
1403<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1404<ol>
1405<li id="user-content-fn-1">
1406<p>Here is the footnote. <a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1407</li>
1408<li id="user-content-fn-longnote">
1409<p>Here’s one with multiple blocks.</p>
1410<p>Subsequent paragraphs are indented to show that they
1411belong to the previous footnote.</p>
1412<pre><code>{ some.code }
1413</code></pre>
1414<p>The whole paragraph can be indented, or just the first
1415line. In this way, multi-paragraph footnotes work like
1416multi-paragraph list items. <a href="#user-content-fnref-longnote" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1417</li>
1418</ol>
1419</section>
1420"##,
1421 "should match pandoc like GitHub"
1422 );
1423
1424 assert_eq!(
1425 to_html_with_options(
1426 r###"Call[^1][^2][^3][^4][^5][^6][^7][^8][^9][^10][^11][^12].
1427
1428 [^1]: 5
1429
1430 [^2]: 4
1431
1432 [^3]: 3
1433
1434 [^4]: 2
1435
1436 [^5]: 1
1437
1438[^6]: 0
1439
1440***
1441
1442 [^7]: 3
1443
1444 5
1445
1446 [^8]: 3
1447
1448 4
1449
1450 [^9]: 3
1451
1452 3
1453
1454 [^10]: 2
1455
1456 5
1457
1458 [^11]: 2
1459
1460 4
1461
1462 [^12]: 2
1463
1464 3
1465"###,
1466 &Options::gfm()
1467 )?,
1468 r##"<p>Call[^1][^2]<sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-5" id="user-content-fnref-5" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-6" id="user-content-fnref-6" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup><sup><a href="#user-content-fn-7" id="user-content-fnref-7" data-footnote-ref="" aria-describedby="footnote-label">5</a></sup><sup><a href="#user-content-fn-8" id="user-content-fnref-8" data-footnote-ref="" aria-describedby="footnote-label">6</a></sup><sup><a href="#user-content-fn-9" id="user-content-fnref-9" data-footnote-ref="" aria-describedby="footnote-label">7</a></sup><sup><a href="#user-content-fn-10" id="user-content-fnref-10" data-footnote-ref="" aria-describedby="footnote-label">8</a></sup><sup><a href="#user-content-fn-11" id="user-content-fnref-11" data-footnote-ref="" aria-describedby="footnote-label">9</a></sup><sup><a href="#user-content-fn-12" id="user-content-fnref-12" data-footnote-ref="" aria-describedby="footnote-label">10</a></sup>.</p>
1469<pre><code> [^1]: 5
1470
1471[^2]: 4
1472</code></pre>
1473<hr />
1474<p>3</p>
1475<p>3</p>
1476<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1477<ol>
1478<li id="user-content-fn-3">
1479<p>3 <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1480</li>
1481<li id="user-content-fn-4">
1482<p>2 <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1483</li>
1484<li id="user-content-fn-5">
1485<p>1 <a href="#user-content-fnref-5" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1486</li>
1487<li id="user-content-fn-6">
1488<p>0 <a href="#user-content-fnref-6" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1489</li>
1490<li id="user-content-fn-7">
1491<p>3</p>
1492<p>5 <a href="#user-content-fnref-7" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1493</li>
1494<li id="user-content-fn-8">
1495<p>3</p>
1496<p>4 <a href="#user-content-fnref-8" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1497</li>
1498<li id="user-content-fn-9">
1499<p>3 <a href="#user-content-fnref-9" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1500</li>
1501<li id="user-content-fn-10">
1502<p>2</p>
1503<p>5 <a href="#user-content-fnref-10" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1504</li>
1505<li id="user-content-fn-11">
1506<p>2</p>
1507<p>4 <a href="#user-content-fnref-11" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1508</li>
1509<li id="user-content-fn-12">
1510<p>2 <a href="#user-content-fnref-12" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1511</li>
1512</ol>
1513</section>
1514"##,
1515 "should match prefix before like GitHub"
1516 );
1517
1518 assert_eq!(
1519 to_html_with_options(
1520 r###"Call[^1][^2][^3][^4][^5][^6][^7][^8][^9].
1521
1522[^1]: a
1523
1524 8
1525
1526[^2]: a
1527
1528 7
1529
1530[^3]: a
1531
1532 6
1533
1534[^4]: a
1535
1536 5
1537
1538[^5]: a
1539
1540 4
1541
1542[^6]: a
1543
1544 3
1545
1546[^7]: a
1547
1548 2
1549
1550[^8]: a
1551
1552 1
1553
1554[^9]: a
1555
15560
1557"###,
1558 &Options::gfm()
1559 )?,
1560 r##"<p>Call<sup><a href="#user-content-fn-1" id="user-content-fnref-1" data-footnote-ref="" aria-describedby="footnote-label">1</a></sup><sup><a href="#user-content-fn-2" id="user-content-fnref-2" data-footnote-ref="" aria-describedby="footnote-label">2</a></sup><sup><a href="#user-content-fn-3" id="user-content-fnref-3" data-footnote-ref="" aria-describedby="footnote-label">3</a></sup><sup><a href="#user-content-fn-4" id="user-content-fnref-4" data-footnote-ref="" aria-describedby="footnote-label">4</a></sup><sup><a href="#user-content-fn-5" id="user-content-fnref-5" data-footnote-ref="" aria-describedby="footnote-label">5</a></sup><sup><a href="#user-content-fn-6" id="user-content-fnref-6" data-footnote-ref="" aria-describedby="footnote-label">6</a></sup><sup><a href="#user-content-fn-7" id="user-content-fnref-7" data-footnote-ref="" aria-describedby="footnote-label">7</a></sup><sup><a href="#user-content-fn-8" id="user-content-fnref-8" data-footnote-ref="" aria-describedby="footnote-label">8</a></sup><sup><a href="#user-content-fn-9" id="user-content-fnref-9" data-footnote-ref="" aria-describedby="footnote-label">9</a></sup>.</p>
1561<p>3</p>
1562<p>2</p>
1563<p>1</p>
1564<p>0</p>
1565<section data-footnotes="" class="footnotes"><h2 id="footnote-label" class="sr-only">Footnotes</h2>
1566<ol>
1567<li id="user-content-fn-1">
1568<p>a</p>
1569<pre><code>8
1570</code></pre>
1571<a href="#user-content-fnref-1" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a>
1572</li>
1573<li id="user-content-fn-2">
1574<p>a</p>
1575<p>7 <a href="#user-content-fnref-2" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1576</li>
1577<li id="user-content-fn-3">
1578<p>a</p>
1579<p>6 <a href="#user-content-fnref-3" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1580</li>
1581<li id="user-content-fn-4">
1582<p>a</p>
1583<p>5 <a href="#user-content-fnref-4" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1584</li>
1585<li id="user-content-fn-5">
1586<p>a</p>
1587<p>4 <a href="#user-content-fnref-5" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1588</li>
1589<li id="user-content-fn-6">
1590<p>a <a href="#user-content-fnref-6" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1591</li>
1592<li id="user-content-fn-7">
1593<p>a <a href="#user-content-fnref-7" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1594</li>
1595<li id="user-content-fn-8">
1596<p>a <a href="#user-content-fnref-8" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1597</li>
1598<li id="user-content-fn-9">
1599<p>a <a href="#user-content-fnref-9" data-footnote-backref="" aria-label="Back to content" class="data-footnote-backref">↩</a></p>
1600</li>
1601</ol>
1602</section>
1603"##,
1604 "should match prefix like GitHub"
1605 );
1606
1607 assert_eq!(
1608 to_html_with_options(
1609 r###"Here is a short reference,[1], a collapsed one,[2][], and a full [one][3].
1610
1611[1]: a
1612
1613[2]: b
1614
1615[3]: c
1616"###,
1617 &Options::gfm()
1618 )?,
1619 r#"<p>Here is a short reference,<a href="a">1</a>, a collapsed one,<a href="b">2</a>, and a full <a href="c">one</a>.</p>
1620"#,
1621 "should match references and definitions like GitHub"
1622 );
1623
1624 assert_eq!(
1625 to_mdast("[^a]: b\n\tc\n\nd [^a] e.", &ParseOptions::gfm())?,
1626 Node::Root(Root {
1627 children: vec![
1628 Node::FootnoteDefinition(FootnoteDefinition {
1629 children: vec![Node::Paragraph(Paragraph {
1630 children: vec![Node::Text(Text {
1631 value: "b\nc".into(),
1632 position: Some(Position::new(1, 7, 6, 2, 6, 10))
1633 })],
1634 position: Some(Position::new(1, 7, 6, 2, 6, 10))
1635 })],
1636 identifier: "a".into(),
1637 label: Some("a".into()),
1638 position: Some(Position::new(1, 1, 0, 3, 1, 11))
1639 }),
1640 Node::Paragraph(Paragraph {
1641 children: vec![
1642 Node::Text(Text {
1643 value: "d ".into(),
1644 position: Some(Position::new(4, 1, 12, 4, 3, 14))
1645 }),
1646 Node::FootnoteReference(FootnoteReference {
1647 identifier: "a".into(),
1648 label: Some("a".into()),
1649 position: Some(Position::new(4, 3, 14, 4, 7, 18))
1650 }),
1651 Node::Text(Text {
1652 value: " e.".into(),
1653 position: Some(Position::new(4, 7, 18, 4, 10, 21))
1654 })
1655 ],
1656 position: Some(Position::new(4, 1, 12, 4, 10, 21))
1657 })
1658 ],
1659 position: Some(Position::new(1, 1, 0, 4, 10, 21))
1660 }),
1661 "should support GFM footnotes as `FootnoteDefinition`, `FootnoteReference`s in mdast"
1662 );
1663
1664 Ok(())
1665}