Markdown parser fork with extended syntax for personal use.
1use markdown::{message, to_html_with_options, CompileOptions, Constructs, Options, ParseOptions};
2use pretty_assertions::assert_eq;
3
4#[test]
5fn wikilinks() -> Result<(), message::Message> {
6 let backlinks = Options {
7 compile: CompileOptions {
8 ..Default::default()
9 },
10 parse: ParseOptions {
11 constructs: Constructs {
12 wikilink: true,
13 ..Default::default()
14 },
15 ..Default::default()
16 },
17 };
18
19 assert_eq!(
20 to_html_with_options("[[backlink]]()", &backlinks).unwrap(),
21 "<p><strong>backlink</strong>()</p>",
22 "should support backlinks"
23 );
24
25 Ok(())
26}
27
28#[test]
29fn wikilink_retrocompat() -> Result<(), message::Message> {
30 let danger = Options {
31 parse: ParseOptions {
32 constructs: Constructs {
33 wikilink: true,
34 ..Default::default()
35 },
36 ..Default::default()
37 },
38 compile: CompileOptions {
39 allow_dangerous_html: true,
40 allow_dangerous_protocol: true,
41 ..Default::default()
42 },
43 ..Default::default()
44 };
45
46 assert_eq!(
47 to_html_with_options("[link](/uri \"title\")", &danger)?,
48 "<p><a href=\"/uri\" title=\"title\">link</a></p>",
49 "should support links"
50 );
51
52 assert_eq!(
53 to_html_with_options("[link](/uri)", &danger)?,
54 "<p><a href=\"/uri\">link</a></p>",
55 "should support links w/o title"
56 );
57
58 assert_eq!(
59 to_html_with_options("[link]()", &danger)?,
60 "<p><a href=\"\">link</a></p>",
61 "should support links w/o destination"
62 );
63
64 assert_eq!(
65 to_html_with_options("[link](<>)", &danger)?,
66 "<p><a href=\"\">link</a></p>",
67 "should support links w/ empty enclosed destination"
68 );
69
70 assert_eq!(
71 to_html_with_options("[link](/my uri)", &danger)?,
72 "<p>[link](/my uri)</p>",
73 "should not support links w/ spaces in destination"
74 );
75
76 assert_eq!(
77 to_html_with_options("[link](</my uri>)", &danger)?,
78 "<p><a href=\"/my%20uri\">link</a></p>",
79 "should support links w/ spaces in enclosed destination"
80 );
81
82 assert_eq!(
83 to_html_with_options("[link](foo\nbar)", &danger)?,
84 "<p>[link](foo\nbar)</p>",
85 "should not support links w/ line endings in destination"
86 );
87
88 assert_eq!(
89 to_html_with_options("[link](<foo\nbar>)", &danger)?,
90 "<p>[link](<foo\nbar>)</p>",
91 "should not support links w/ line endings in enclosed destination"
92 );
93
94 assert_eq!(
95 to_html_with_options("[a](<b)c>)", &danger)?,
96 "<p><a href=\"b)c\">a</a></p>",
97 "should support links w/ closing parens in destination"
98 );
99
100 assert_eq!(
101 to_html_with_options("[link](<foo\\>)", &danger)?,
102 "<p>[link](<foo>)</p>",
103 "should not support links w/ enclosed destinations w/o end"
104 );
105
106 assert_eq!(
107 to_html_with_options("[a](<b)c\n[a](<b)c>\n[a](<b>c)", &danger)?,
108 "<p>[a](<b)c\n[a](<b)c>\n[a](<b>c)</p>",
109 "should not support links w/ unmatched enclosed destinations"
110 );
111
112 assert_eq!(
113 to_html_with_options("[link](\\(foo\\))", &danger)?,
114 "<p><a href=\"(foo)\">link</a></p>",
115 "should support links w/ destinations w/ escaped parens"
116 );
117
118 assert_eq!(
119 to_html_with_options("[link](foo(and(bar)))", &danger)?,
120 "<p><a href=\"foo(and(bar))\">link</a></p>",
121 "should support links w/ destinations w/ balanced parens"
122 );
123
124 assert_eq!(
125 to_html_with_options("[link](foo\\(and\\(bar\\))", &danger)?,
126 "<p><a href=\"foo(and(bar)\">link</a></p>",
127 "should support links w/ destinations w/ escaped parens"
128 );
129
130 assert_eq!(
131 to_html_with_options("[link](<foo(and(bar)>)", &danger)?,
132 "<p><a href=\"foo(and(bar)\">link</a></p>",
133 "should support links w/ enclosed destinations w/ parens"
134 );
135
136 assert_eq!(
137 to_html_with_options("[link](foo\\)\\:)", &danger)?,
138 "<p><a href=\"foo):\">link</a></p>",
139 "should support links w/ escapes in destinations"
140 );
141
142 assert_eq!(
143 to_html_with_options("[link](#fragment)", &danger)?,
144 "<p><a href=\"#fragment\">link</a></p>",
145 "should support links w/ destinations to fragments"
146 );
147
148 assert_eq!(
149 to_html_with_options("[link](http://example.com#fragment)", &danger)?,
150 "<p><a href=\"http://example.com#fragment\">link</a></p>",
151 "should support links w/ destinations to URLs w/ fragments"
152 );
153
154 assert_eq!(
155 to_html_with_options("[link](http://example.com?foo=3#frag)", &danger)?,
156 "<p><a href=\"http://example.com?foo=3#frag\">link</a></p>",
157 "should support links w/ destinations to URLs w/ search and fragments"
158 );
159
160 assert_eq!(
161 to_html_with_options("[link](foo\\bar)", &danger)?,
162 "<p><a href=\"foo%5Cbar\">link</a></p>",
163 "should not support non-punctuation character escapes in links"
164 );
165
166 assert_eq!(
167 to_html_with_options("[link](foo%20bä)", &danger)?,
168 "<p><a href=\"foo%20b%C3%A4\">link</a></p>",
169 "should support character references in links"
170 );
171
172 assert_eq!(
173 to_html_with_options("[link](\"title\")", &danger)?,
174 "<p><a href=\"%22title%22\">link</a></p>",
175 "should not support links w/ only a title"
176 );
177
178 assert_eq!(
179 to_html_with_options("[link](/url \"title\")", &danger)?,
180 "<p><a href=\"/url\" title=\"title\">link</a></p>",
181 "should support titles w/ double quotes"
182 );
183
184 assert_eq!(
185 to_html_with_options("[link](/url 'title')", &danger)?,
186 "<p><a href=\"/url\" title=\"title\">link</a></p>",
187 "should support titles w/ single quotes"
188 );
189
190 assert_eq!(
191 to_html_with_options("[link](/url (title))", &danger)?,
192 "<p><a href=\"/url\" title=\"title\">link</a></p>",
193 "should support titles w/ parens"
194 );
195
196 assert_eq!(
197 to_html_with_options("[link](/url \"title \\\""\")", &danger)?,
198 "<p><a href=\"/url\" title=\"title ""\">link</a></p>",
199 "should support character references and escapes in titles"
200 );
201
202 assert_eq!(
203 to_html_with_options("[link](/url \"title\")", &danger)?,
204 "<p><a href=\"/url%C2%A0%22title%22\">link</a></p>",
205 "should not support unicode whitespace between destination and title"
206 );
207
208 assert_eq!(
209 to_html_with_options("[link](/url \"title \"and\" title\")", &danger)?,
210 "<p>[link](/url "title "and" title")</p>",
211 "should not support nested balanced quotes in title"
212 );
213
214 assert_eq!(
215 to_html_with_options("[link](/url 'title \"and\" title')", &danger)?,
216 "<p><a href=\"/url\" title=\"title "and" title\">link</a></p>",
217 "should support the other quotes in titles"
218 );
219
220 assert_eq!(
221 to_html_with_options("[link]( /uri\n \"title\" )", &danger)?,
222 "<p><a href=\"/uri\" title=\"title\">link</a></p>",
223 "should support whitespace around destination and title (1)"
224 );
225
226 assert_eq!(
227 to_html_with_options("[link](\t\n/uri \"title\")", &danger)?,
228 "<p><a href=\"/uri\" title=\"title\">link</a></p>",
229 "should support whitespace around destination and title (2)"
230 );
231
232 assert_eq!(
233 to_html_with_options("[link](/uri \"title\"\t\n)", &danger)?,
234 "<p><a href=\"/uri\" title=\"title\">link</a></p>",
235 "should support whitespace around destination and title (3)"
236 );
237
238 assert_eq!(
239 to_html_with_options("[link] (/uri)", &danger)?,
240 "<p>[link] (/uri)</p>",
241 "should not support whitespace between label and resource"
242 );
243
244 assert_eq!(
245 to_html_with_options("[link [foo [bar]]](/uri)", &danger)?,
246 "<p><a href=\"/uri\">link [foo [bar]]</a></p>",
247 "should support balanced brackets"
248 );
249
250 assert_eq!(
251 to_html_with_options("[link] bar](/uri)", &danger)?,
252 "<p>[link] bar](/uri)</p>",
253 "should not support unbalanced brackets (1)"
254 );
255
256 assert_eq!(
257 to_html_with_options("[link [bar](/uri)", &danger)?,
258 "<p>[link <a href=\"/uri\">bar</a></p>",
259 "should not support unbalanced brackets (2)"
260 );
261
262 assert_eq!(
263 to_html_with_options("[link \\[bar](/uri)", &danger)?,
264 "<p><a href=\"/uri\">link [bar</a></p>",
265 "should support characer escapes"
266 );
267
268 assert_eq!(
269 to_html_with_options("[link *foo **bar** `#`*](/uri)", &danger)?,
270 "<p><a href=\"/uri\">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>",
271 "should support content"
272 );
273
274 assert_eq!(
275 to_html_with_options("[](/uri)", &danger)?,
276 "<p><a href=\"/uri\"><img src=\"moon.jpg\" alt=\"moon\" /></a></p>",
277 "should support an image as content"
278 );
279
280 assert_eq!(
281 to_html_with_options("[foo [bar](/uri)](/uri)", &danger)?,
282 "<p>[foo <a href=\"/uri\">bar</a>](/uri)</p>",
283 "should not support links in links (1)"
284 );
285
286 assert_eq!(
287 to_html_with_options("[foo *[bar [baz](/uri)](/uri)*](/uri)", &danger)?,
288 "<p>[foo <em>[bar <a href=\"/uri\">baz</a>](/uri)</em>](/uri)</p>",
289 "should not support links in links (2)"
290 );
291
292 assert_eq!(
293 to_html_with_options("](uri2)](uri3)", &danger)?,
294 "<p><img src=\"uri3\" alt=\"[foo](uri2)\" /></p>",
295 "should not support links in links (3)"
296 );
297
298 assert_eq!(
299 to_html_with_options("*[foo*](/uri)", &danger)?,
300 "<p>*<a href=\"/uri\">foo*</a></p>",
301 "should prefer links over emphasis (1)"
302 );
303
304 assert_eq!(
305 to_html_with_options("[foo *bar](baz*)", &danger)?,
306 "<p><a href=\"baz*\">foo *bar</a></p>",
307 "should prefer links over emphasis (2)"
308 );
309
310 assert_eq!(
311 to_html_with_options("[foo <bar attr=\"](baz)\">", &danger)?,
312 "<p>[foo <bar attr=\"](baz)\"></p>",
313 "should prefer HTML over links"
314 );
315
316 assert_eq!(
317 to_html_with_options("[foo`](/uri)`", &danger)?,
318 "<p>[foo<code>](/uri)</code></p>",
319 "should prefer code over links"
320 );
321
322 assert_eq!(
323 to_html_with_options("[foo<http://example.com/?search=](uri)>", &danger)?,
324 "<p>[foo<a href=\"http://example.com/?search=%5D(uri)\">http://example.com/?search=](uri)</a></p>",
325 "should prefer autolinks over links"
326 );
327
328 assert_eq!(
329 to_html_with_options("[foo<http://example.com/?search=](uri)>", &danger)?,
330 "<p>[foo<a href=\"http://example.com/?search=%5D(uri)\">http://example.com/?search=](uri)</a></p>",
331 "should prefer autolinks over links"
332 );
333
334 // Extra
335 assert_eq!(
336 to_html_with_options("[]()", &danger)?,
337 "<p><a href=\"\"></a></p>",
338 "should support an empty link"
339 );
340
341 // See: <https://github.com/commonmark/commonmark.js/issues/192>
342 assert_eq!(
343 to_html_with_options("[](<> \"\")", &danger)?,
344 "<p><a href=\"\"></a></p>",
345 "should ignore an empty title"
346 );
347
348 assert_eq!(
349 to_html_with_options("[a](<b>\"c\")", &danger)?,
350 "<p>[a](<b>"c")</p>",
351 "should require whitespace between enclosed destination and title"
352 );
353
354 assert_eq!(
355 to_html_with_options("[](<", &danger)?,
356 "<p>[](<</p>",
357 "should not support an unclosed enclosed destination"
358 );
359
360 assert_eq!(
361 to_html_with_options("[](", &danger)?,
362 "<p>[](</p>",
363 "should not support an unclosed destination"
364 );
365
366 assert_eq!(
367 to_html_with_options("[](\\<)", &danger)?,
368 "<p><a href=\"%3C\"></a></p>",
369 "should support unenclosed link destination starting w/ escapes"
370 );
371
372 assert_eq!(
373 to_html_with_options("[](<\\<>)", &danger)?,
374 "<p><a href=\"%3C\"></a></p>",
375 "should support enclosed link destination starting w/ escapes"
376 );
377
378 assert_eq!(
379 to_html_with_options("[](\\", &danger)?,
380 "<p>[](\\</p>",
381 "should not support unenclosed link destination starting w/ an incorrect escape"
382 );
383
384 assert_eq!(
385 to_html_with_options("[](<\\", &danger)?,
386 "<p>[](<\\</p>",
387 "should not support enclosed link destination starting w/ an incorrect escape"
388 );
389
390 assert_eq!(
391 to_html_with_options("[](a \"", &danger)?,
392 "<p>[](a "</p>",
393 "should not support an eof in a link title (1)"
394 );
395
396 assert_eq!(
397 to_html_with_options("[](a '", &danger)?,
398 "<p>[](a '</p>",
399 "should not support an eof in a link title (2)"
400 );
401
402 assert_eq!(
403 to_html_with_options("[](a (", &danger)?,
404 "<p>[](a (</p>",
405 "should not support an eof in a link title (3)"
406 );
407
408 assert_eq!(
409 to_html_with_options("[](a \"\\", &danger)?,
410 "<p>[](a "\\</p>",
411 "should not support an eof in a link title escape (1)"
412 );
413
414 assert_eq!(
415 to_html_with_options("[](a '\\", &danger)?,
416 "<p>[](a '\\</p>",
417 "should not support an eof in a link title escape (2)"
418 );
419
420 assert_eq!(
421 to_html_with_options("[](a (\\", &danger)?,
422 "<p>[](a (\\</p>",
423 "should not support an eof in a link title escape (3)"
424 );
425
426 assert_eq!(
427 to_html_with_options("[](a \"\\\"\")", &danger)?,
428 "<p><a href=\"a\" title=\""\"></a></p>",
429 "should support a character escape to start a link title (1)"
430 );
431
432 assert_eq!(
433 to_html_with_options("[](a '\\'')", &danger)?,
434 "<p><a href=\"a\" title=\"\'\"></a></p>",
435 "should support a character escape to start a link title (2)"
436 );
437
438 assert_eq!(
439 to_html_with_options("[](a (\\)))", &danger)?,
440 "<p><a href=\"a\" title=\")\"></a></p>",
441 "should support a character escape to start a link title (3)"
442 );
443
444 assert_eq!(
445 to_html_with_options(
446 "[&©&](example.com/&©& \"&©&\")",
447 &danger
448 )?,
449 "<p><a href=\"example.com/&%C2%A9&\" title=\"&©&\">&©&</a></p>",
450 "should support character references in links"
451 );
452
453 assert_eq!(
454 to_html_with_options("[a](1())", &danger)?,
455 "<p><a href=\"1()\">a</a></p>",
456 "should support 1 set of parens"
457 );
458
459 assert_eq!(
460 to_html_with_options("[a](1(2()))", &danger)?,
461 "<p><a href=\"1(2())\">a</a></p>",
462 "should support 2 sets of parens"
463 );
464
465 assert_eq!(
466 to_html_with_options(
467 "[a](1(2(3(4(5(6(7(8(9(10(11(12(13(14(15(16(17(18(19(20(21(22(23(24(25(26(27(28(29(30(31(32()))))))))))))))))))))))))))))))))", &danger)?,
468 "<p><a href=\"1(2(3(4(5(6(7(8(9(10(11(12(13(14(15(16(17(18(19(20(21(22(23(24(25(26(27(28(29(30(31(32())))))))))))))))))))))))))))))))\">a</a></p>",
469 "should support 32 sets of parens"
470 );
471
472 assert_eq!(
473 to_html_with_options(
474 "[a](1(2(3(4(5(6(7(8(9(10(11(12(13(14(15(16(17(18(19(20(21(22(23(24(25(26(27(28(29(30(31(32(33())))))))))))))))))))))))))))))))))", &danger)?,
475 "<p>[a](1(2(3(4(5(6(7(8(9(10(11(12(13(14(15(16(17(18(19(20(21(22(23(24(25(26(27(28(29(30(31(32(33())))))))))))))))))))))))))))))))))</p>",
476 "should not support 33 or more sets of parens"
477 );
478
479 assert_eq!(
480 to_html_with_options("[a](b \"\n c\")", &danger)?,
481 "<p><a href=\"b\" title=\"\nc\">a</a></p>",
482 "should support an eol at the start of a title"
483 );
484
485 assert_eq!(
486 to_html_with_options("[a](b( \"c\")", &danger)?,
487 "<p>[a](b( "c")</p>",
488 "should not support whitespace when unbalanced in a raw destination"
489 );
490
491 assert_eq!(
492 to_html_with_options("[a](\0)", &danger)?,
493 "<p><a href=\"%EF%BF%BD\">a</a></p>",
494 "should support a single NUL character as a link resource"
495 );
496
497 Ok(())
498}