Compare commits
1126 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e3527b7d2 | ||
|
|
d56e080fd7 | ||
|
|
d807255e13 | ||
|
|
029da6c99b | ||
|
|
b59c9e8925 | ||
|
|
22662b248d | ||
|
|
9d51ab176c | ||
|
|
584378967d | ||
|
|
f553bdd4c7 | ||
|
|
16d77b7bb8 | ||
|
|
d267cbe173 | ||
|
|
f54944962f | ||
|
|
5a54af1235 | ||
|
|
4567d86c15 | ||
|
|
2b6dde9415 | ||
|
|
ea8d9b608a | ||
|
|
1469cc8fdb | ||
|
|
daf2171366 | ||
|
|
63a9f2406b | ||
|
|
fd100d1796 | ||
|
|
2c5a51d89b | ||
|
|
28db7fbd6b | ||
|
|
56470a72a8 | ||
|
|
6b163a50c3 | ||
|
|
c0ee97a803 | ||
|
|
63ce549ea2 | ||
|
|
0faf0ef430 | ||
|
|
cdd4b40469 | ||
|
|
54d85ebac6 | ||
|
|
64875c3dd9 | ||
|
|
4c92fe5a3b | ||
|
|
27f625f15b | ||
|
|
aca085703e | ||
|
|
8aa0948b20 | ||
|
|
8ce6f4d9ad | ||
|
|
3a47a5115a | ||
|
|
a8737e8481 | ||
|
|
f56b8e6ba7 | ||
|
|
0a0040450f | ||
|
|
fb12be5ab0 | ||
|
|
2277596e2e | ||
|
|
a10f6f6b8c | ||
|
|
203cfd6508 | ||
|
|
5fefcbb5b3 | ||
|
|
7ad7b55c48 | ||
|
|
e9ea103e32 | ||
|
|
c680910828 | ||
|
|
4526d886c8 | ||
|
|
397de86e2f | ||
|
|
f985750b82 | ||
|
|
00c175a79c | ||
|
|
6204095261 | ||
|
|
63fddf4511 | ||
|
|
c964659085 | ||
|
|
eabfe74e92 | ||
|
|
bd1dcd952c | ||
|
|
54e2514778 | ||
|
|
4b7a4d21de | ||
|
|
6b1399ba23 | ||
|
|
07467d6c30 | ||
|
|
2f9588498c | ||
|
|
80ed85e2a8 | ||
|
|
b2306db388 | ||
|
|
8db238797b | ||
|
|
780e16a9c9 | ||
|
|
8fdc0d59d7 | ||
|
|
f1cd0cb1b8 | ||
|
|
a724783e3f | ||
|
|
1c862a1e07 | ||
|
|
35d3160ad2 | ||
|
|
e0a2f9e52d | ||
|
|
c9ba236dbc | ||
|
|
0c9b5dddc9 | ||
|
|
bd2bb98631 | ||
|
|
da0ba34165 | ||
|
|
51c5bec315 | ||
|
|
13bdab4570 | ||
|
|
6b9433c7d8 | ||
|
|
eedbb494fc | ||
|
|
9d36a74312 | ||
|
|
4009c89321 | ||
|
|
6b433d9352 | ||
|
|
f6e6001d94 | ||
|
|
1474b7b29a | ||
|
|
61b29b6d41 | ||
|
|
6684c8257c | ||
|
|
247cd92926 | ||
|
|
404a94f284 | ||
|
|
1cc8a40473 | ||
|
|
dc4968d5ab | ||
|
|
b2b36038ff | ||
|
|
4a57035aec | ||
|
|
1752178631 | ||
|
|
39c05f34d1 | ||
|
|
640196a18f | ||
|
|
4f9119fc96 | ||
|
|
5eb600afc3 | ||
|
|
64ebff4012 | ||
|
|
9e5d30cd4c | ||
|
|
4324caaaea | ||
|
|
46c2d49243 | ||
|
|
80b1cf6020 | ||
|
|
264f7f2132 | ||
|
|
80ec8da7d3 | ||
|
|
1e2399669d | ||
|
|
ab53969f06 | ||
|
|
168217b4e0 | ||
|
|
a3ce1903c1 | ||
|
|
db1021a979 | ||
|
|
cbd00a45af | ||
|
|
fef4719e41 | ||
|
|
ae25a8f12c | ||
|
|
bb5403c795 | ||
|
|
325fb7158e | ||
|
|
67416e4b45 | ||
|
|
8b48accb7e | ||
|
|
bb42ee42ca | ||
|
|
d17660fe5d | ||
|
|
19e409ceca | ||
|
|
59df6d1a2e | ||
|
|
763ed32212 | ||
|
|
8aa522c4bf | ||
|
|
9031be96f8 | ||
|
|
4bc2e847d5 | ||
|
|
80d4e6f344 | ||
|
|
b6e38a0a96 | ||
|
|
1d79ad8436 | ||
|
|
383b197490 | ||
|
|
7aeee0681f | ||
|
|
e017adae84 | ||
|
|
7035aed74a | ||
|
|
21b6a3869a | ||
|
|
aa92e59b2c | ||
|
|
5f87e56651 | ||
|
|
9934c0033a | ||
|
|
5d1da2deac | ||
|
|
4e424c43fb | ||
|
|
3030b72f78 | ||
|
|
d1784676b2 | ||
|
|
47e49f0a4f | ||
|
|
0bfc456509 | ||
|
|
8e14997bc1 | ||
|
|
a8ec3c1a48 | ||
|
|
f6f617a746 | ||
|
|
3d65b9f6b6 | ||
|
|
5f7d93be52 | ||
|
|
3ec787687c | ||
|
|
9fbe5eb21d | ||
|
|
e523dfd7f4 | ||
|
|
412500158c | ||
|
|
fc942b4d01 | ||
|
|
d1d64842ca | ||
|
|
930eee383f | ||
|
|
87c45db46b | ||
|
|
fb4abdfae3 | ||
|
|
7ab34d5cef | ||
|
|
b576b08332 | ||
|
|
9c43b802bd | ||
|
|
7dda864e4a | ||
|
|
b3953dbe23 | ||
|
|
453e8239d2 | ||
|
|
8e8b95c3bb | ||
|
|
35b64052d6 | ||
|
|
ef495da097 | ||
|
|
a6b9c9a41e | ||
|
|
5bb2d92180 | ||
|
|
929ec36c76 | ||
|
|
8e17d9c94e | ||
|
|
a11cd8c28c | ||
|
|
68d2a20d20 | ||
|
|
e3531413e1 | ||
|
|
ef534224f8 | ||
|
|
2f3e1451b8 | ||
|
|
a34e257d2c | ||
|
|
9d83631cfe | ||
|
|
61b3ffde91 | ||
|
|
bebdf0179e | ||
|
|
ab5e8ae9e2 | ||
|
|
c8da430134 | ||
|
|
0e8c312fda | ||
|
|
4814e9cea5 | ||
|
|
068a6e7af5 | ||
|
|
e4f2892a23 | ||
|
|
c2cfb05d8d | ||
|
|
813647ca10 | ||
|
|
83357dc929 | ||
|
|
420aa79a48 | ||
|
|
24be820827 | ||
|
|
694a764f96 | ||
|
|
bb1da73da2 | ||
|
|
e6b591c035 | ||
|
|
5a19cdfebb | ||
|
|
34e439f494 | ||
|
|
b0602a7bb0 | ||
|
|
d7558f0442 | ||
|
|
eac0ab3cca | ||
|
|
147cd48a8d | ||
|
|
1b44256fc0 | ||
|
|
db2856daf7 | ||
|
|
9beb0c1613 | ||
|
|
ef343158b7 | ||
|
|
de5526877d | ||
|
|
b00d75607b | ||
|
|
8c37a1bef5 | ||
|
|
7a9405ec9e | ||
|
|
6506e4594c | ||
|
|
7b20299d2b | ||
|
|
55eaadce67 | ||
|
|
87269d88b9 | ||
|
|
fb8162f5d7 | ||
|
|
a04aa8a4de | ||
|
|
352443d9cd | ||
|
|
cd798b8d95 | ||
|
|
c5b260f708 | ||
|
|
2583463ea2 | ||
|
|
777ac71bd1 | ||
|
|
810ae49cc7 | ||
|
|
225e308438 | ||
|
|
05dd543d16 | ||
|
|
c711201b34 | ||
|
|
47b3ac5d99 | ||
|
|
49aa856f52 | ||
|
|
5e15575929 | ||
|
|
c9fc608598 | ||
|
|
6ba3c3d683 | ||
|
|
d15edb79fa | ||
|
|
fa3b67342d | ||
|
|
033f156b2b | ||
|
|
f3db5e882e | ||
|
|
c9365f3551 | ||
|
|
9ecb5b9950 | ||
|
|
95fb53cbc9 | ||
|
|
9d82088e03 | ||
|
|
340b75b557 | ||
|
|
751c79fce4 | ||
|
|
4dc8cc3977 | ||
|
|
a1891e2984 | ||
|
|
ff0637993c | ||
|
|
8b64ce456f | ||
|
|
a781ae1e5b | ||
|
|
2e5007241d | ||
|
|
cf6d98b7f8 | ||
|
|
0b79389b14 | ||
|
|
111d3d3362 | ||
|
|
ac6ceb23e8 | ||
|
|
d31fa47cd1 | ||
|
|
d7f6a94f12 | ||
|
|
dbdd752b73 | ||
|
|
ccb7e8edfa | ||
|
|
db25c1db43 | ||
|
|
5db90ede4b | ||
|
|
fef1ad3563 | ||
|
|
e9302d93bd | ||
|
|
4704c49fbf | ||
|
|
aca70e5c9a | ||
|
|
da5eff075d | ||
|
|
971207e942 | ||
|
|
4c2b46e0fc | ||
|
|
68d12d0212 | ||
|
|
fa1c117011 | ||
|
|
6b1c5bc816 | ||
|
|
e2cafc6b3d | ||
|
|
aff7604b4b | ||
|
|
68530aa4e0 | ||
|
|
bfc1152b8a | ||
|
|
37af8f8ecb | ||
|
|
6792bffb5e | ||
|
|
976855a4c3 | ||
|
|
acf2ba9502 | ||
|
|
cadbc67825 | ||
|
|
0d86a93200 | ||
|
|
f78b5c83cd | ||
|
|
fb942f9810 | ||
|
|
25a227fffd | ||
|
|
2be8cd4aa7 | ||
|
|
569b80befe | ||
|
|
0b8b14490e | ||
|
|
c59fd5c651 | ||
|
|
4893e2b177 | ||
|
|
b30b219237 | ||
|
|
d6c627aa88 | ||
|
|
a26f4298a4 | ||
|
|
d5b80f6a7b | ||
|
|
98d747c839 | ||
|
|
7dd9321a97 | ||
|
|
c22d681c20 | ||
|
|
ffe7f56bc2 | ||
|
|
16c0b6a3fa | ||
|
|
db867dee48 | ||
|
|
d35b1b82ea | ||
|
|
8b829a2dea | ||
|
|
0234d60d74 | ||
|
|
cd18087e29 | ||
|
|
30f670bf5f | ||
|
|
c73785372b | ||
|
|
147698daab | ||
|
|
2b07e9a5b9 | ||
|
|
4f7ef61303 | ||
|
|
831a529338 | ||
|
|
4f5e9cd334 | ||
|
|
cb0b3a6292 | ||
|
|
4390ff289e | ||
|
|
be53e778be | ||
|
|
0eab0a3107 | ||
|
|
8fa47427ac | ||
|
|
bca544575b | ||
|
|
0017dbffc4 | ||
|
|
569efa357a | ||
|
|
7e9df72173 | ||
|
|
b2fcb1cc37 | ||
|
|
8758ba460f | ||
|
|
477a290538 | ||
|
|
0fc112a6b8 | ||
|
|
b7aea44502 | ||
|
|
0545faa9af | ||
|
|
ea67a295b2 | ||
|
|
d53128d56d | ||
|
|
ba192ce065 | ||
|
|
42462d71ac | ||
|
|
6e0363aa91 | ||
|
|
e9be3725d6 | ||
|
|
38f4332de1 | ||
|
|
bcc123d240 | ||
|
|
144e8ad156 | ||
|
|
55a7eae4d4 | ||
|
|
d96862378d | ||
|
|
8acf5a548e | ||
|
|
222a99c7e4 | ||
|
|
ac4a75bdf9 | ||
|
|
fc2e1ab896 | ||
|
|
ef7f20482e | ||
|
|
fc50e2e2e7 | ||
|
|
4d513acf6b | ||
|
|
32b1ee7eaa | ||
|
|
3e2a498ae7 | ||
|
|
e0ac9b7ddf | ||
|
|
bbf10a7ad0 | ||
|
|
62a0992e5e | ||
|
|
b2e49d174e | ||
|
|
5e218721e7 | ||
|
|
c64cd53ac3 | ||
|
|
920ab6cb60 | ||
|
|
3ef1d735d5 | ||
|
|
47c6c49f5c | ||
|
|
a19f78342f | ||
|
|
edb4c6c3cb | ||
|
|
4b6d7c78f5 | ||
|
|
0386cfd617 | ||
|
|
5c52a7249d | ||
|
|
14fb550704 | ||
|
|
741d09a4e8 | ||
|
|
34d9fa2bcc | ||
|
|
8ee50a265d | ||
|
|
eb002db3c7 | ||
|
|
a15203a061 | ||
|
|
b0a2f19ed7 | ||
|
|
a9d78e04a1 | ||
|
|
a8b6e2c2e4 | ||
|
|
665f5f5e51 | ||
|
|
86a72c3582 | ||
|
|
784b999d6c | ||
|
|
be3a893d3d | ||
|
|
2679c84788 | ||
|
|
3d005d6444 | ||
|
|
09593ff3da | ||
|
|
f0269fc61f | ||
|
|
2d97628cfd | ||
|
|
ee97d32ef0 | ||
|
|
9ca5cdcb31 | ||
|
|
5f453fbe92 | ||
|
|
8300a9cca2 | ||
|
|
f7d763230d | ||
|
|
cce1b99edc | ||
|
|
2dca2119fa | ||
|
|
faf0a20816 | ||
|
|
68196c1ce6 | ||
|
|
fdf125d05d | ||
|
|
46133715ab | ||
|
|
ae726b3796 | ||
|
|
4151ac2287 | ||
|
|
305f722899 | ||
|
|
abc8aa25b7 | ||
|
|
e6bb83ecdf | ||
|
|
e6ea8ad274 | ||
|
|
1f3cf5962f | ||
|
|
83b3427805 | ||
|
|
3ff3f1ccb9 | ||
|
|
5d91f0e26f | ||
|
|
9af462e412 | ||
|
|
e1ba52da20 | ||
|
|
70ee97d5c7 | ||
|
|
da916a1700 | ||
|
|
5548246703 | ||
|
|
097fc5c4e0 | ||
|
|
168ad39ff6 | ||
|
|
54e065aabe | ||
|
|
98d58797d9 | ||
|
|
2f0dd2a6a7 | ||
|
|
247209870e | ||
|
|
ef5b958267 | ||
|
|
7d61df2c0c | ||
|
|
51f9da1974 | ||
|
|
9321628b9c | ||
|
|
525e2c7fb8 | ||
|
|
1f9b70636f | ||
|
|
d4f43f826f | ||
|
|
62788b1101 | ||
|
|
c3c4d37b82 | ||
|
|
333bf04274 | ||
|
|
dab4b7176d | ||
|
|
25ec56e1be | ||
|
|
3455fd12da | ||
|
|
ae5d47a0ed | ||
|
|
1ff721d512 | ||
|
|
2c130504e2 | ||
|
|
6405b16692 | ||
|
|
2e1912a23d | ||
|
|
71c680388c | ||
|
|
3f50b3fd0b | ||
|
|
99b250b4c9 | ||
|
|
655bf13df0 | ||
|
|
d2c89a3a06 | ||
|
|
754d11fd44 | ||
|
|
1252e49ba4 | ||
|
|
d18487ae53 | ||
|
|
f401d5082e | ||
|
|
dd6418d108 | ||
|
|
7875e4bce9 | ||
|
|
2e1b1a1fdc | ||
|
|
fa2b157c1a | ||
|
|
e4e6406546 | ||
|
|
1cff10270a | ||
|
|
87023184cb | ||
|
|
aecdf2192e | ||
|
|
0a36382126 | ||
|
|
0057b368ec | ||
|
|
3033284096 | ||
|
|
9b1b791b18 | ||
|
|
2b7d205701 | ||
|
|
89b28659b1 | ||
|
|
446b1bcc0d | ||
|
|
ec7a4a6902 | ||
|
|
07a77142f4 | ||
|
|
3606f234b8 | ||
|
|
616eed62bd | ||
|
|
99f55e9ddc | ||
|
|
f8ab1cccc5 | ||
|
|
f24067cd16 | ||
|
|
9af96ba2b4 | ||
|
|
c99f7dd96a | ||
|
|
bf28cbd33f | ||
|
|
2040e23545 | ||
|
|
2761e36b6b | ||
|
|
891334134c | ||
|
|
0987fab6f2 | ||
|
|
ed5eea5e27 | ||
|
|
f73cbe4e76 | ||
|
|
aefad219cf | ||
|
|
76c3e88c58 | ||
|
|
afe4308e91 | ||
|
|
606556b692 | ||
|
|
253be5c362 | ||
|
|
33037d1034 | ||
|
|
f16ee828db | ||
|
|
a76305f39b | ||
|
|
f52a41e167 | ||
|
|
4d172bf905 | ||
|
|
890b2cda2a | ||
|
|
c818670919 | ||
|
|
a78a0b7016 | ||
|
|
6a0c9aeb47 | ||
|
|
b1cfcf2431 | ||
|
|
b411522a23 | ||
|
|
1d2977d47b | ||
|
|
ee8c87c357 | ||
|
|
25959174d5 | ||
|
|
033ddaf6a8 | ||
|
|
f3f7584c39 | ||
|
|
d00ca4acc1 | ||
|
|
d9663ef2e6 | ||
|
|
3106a49d02 | ||
|
|
a47a6890e7 | ||
|
|
7d21f8b003 | ||
|
|
15f6205adc | ||
|
|
e6dd2cf3d4 | ||
|
|
ea6592b773 | ||
|
|
5cd20efe3e | ||
|
|
31c7ba5862 | ||
|
|
0272840a62 | ||
|
|
8886b48634 | ||
|
|
64cd8ec262 | ||
|
|
a1e19912a9 | ||
|
|
ca51967fb1 | ||
|
|
bb3a4f372c | ||
|
|
1d6a464c5d | ||
|
|
0fe5c17a93 | ||
|
|
f879d55b4a | ||
|
|
6d3a3584ac | ||
|
|
ea13b33f1a | ||
|
|
9b2ec2e2e5 | ||
|
|
d8dffc28b4 | ||
|
|
0735042599 | ||
|
|
d1f99cdb69 | ||
|
|
d0a2ae2b50 | ||
|
|
dd4d1b349f | ||
|
|
e33281b8ae | ||
|
|
50d42560da | ||
|
|
a1e96d717b | ||
|
|
56278657fd | ||
|
|
b7202084d2 | ||
|
|
88052168d0 | ||
|
|
27cb88773a | ||
|
|
fe3d5b0ccf | ||
|
|
86759e44e1 | ||
|
|
dd60990d3d | ||
|
|
a3a9496c6f | ||
|
|
d09013ba14 | ||
|
|
9499660f83 | ||
|
|
df24ab9846 | ||
|
|
40a8cd09b6 | ||
|
|
b556f06d31 | ||
|
|
54e61d3b91 | ||
|
|
221afcc4d3 | ||
|
|
f1fc64af42 | ||
|
|
b39614f10c | ||
|
|
5bda352f7a | ||
|
|
4f08094de0 | ||
|
|
13a733a061 | ||
|
|
d010a4f21e | ||
|
|
a353c59e26 | ||
|
|
01c8aedced | ||
|
|
01d8842ac1 | ||
|
|
69a2261562 | ||
|
|
09905db72a | ||
|
|
754409c8fa | ||
|
|
cd67a3049a | ||
|
|
277aef341a | ||
|
|
9a5ef61bd1 | ||
|
|
ed6c59dd07 | ||
|
|
4deeac538a | ||
|
|
b05161d20e | ||
|
|
d02adf1bf3 | ||
|
|
f767b649e6 | ||
|
|
bdec15d943 | ||
|
|
fe4ac6643a | ||
|
|
eb72bc6d4f | ||
|
|
f484366612 | ||
|
|
bb5e45b939 | ||
|
|
2b41e47170 | ||
|
|
3c16852219 | ||
|
|
744417c7a2 | ||
|
|
4039e11e08 | ||
|
|
3c73a2d05a | ||
|
|
1ef247b093 | ||
|
|
d45d8873f5 | ||
|
|
396a03567c | ||
|
|
6a98e204a5 | ||
|
|
210a6612c7 | ||
|
|
27c35b3b09 | ||
|
|
ac1db841d5 | ||
|
|
09f29615c1 | ||
|
|
05e5a3f2bb | ||
|
|
6d238de69e | ||
|
|
5b88dbb90a | ||
|
|
fbd822cef7 | ||
|
|
0e22a120f1 | ||
|
|
590f3d0b1b | ||
|
|
23766d84fa | ||
|
|
14e9e618a2 | ||
|
|
f523cb243b | ||
|
|
1064818b49 | ||
|
|
befd1ca846 | ||
|
|
65c671d014 | ||
|
|
25bc0b8bf6 | ||
|
|
343a2a17e1 | ||
|
|
5100ed0b68 | ||
|
|
95dd2c148c | ||
|
|
354db6b306 | ||
|
|
50313a36dc | ||
|
|
77d5dcb6dd | ||
|
|
1c88fb65c8 | ||
|
|
db9660d090 | ||
|
|
39ab066e2d | ||
|
|
47f395dad7 | ||
|
|
04e195cdb2 | ||
|
|
3b3872ffe3 | ||
|
|
c7cda0df45 | ||
|
|
7651e75bfa | ||
|
|
ea99cd6115 | ||
|
|
3af4f33b5d | ||
|
|
41e8d5e5fc | ||
|
|
5a73c2bf2b | ||
|
|
f542fd0a88 | ||
|
|
5a6300823c | ||
|
|
6dcef438c4 | ||
|
|
40206c4d76 | ||
|
|
24ecfc93f3 | ||
|
|
8eb52c50ec | ||
|
|
9965597256 | ||
|
|
987580e71e | ||
|
|
bba3ef04ee | ||
|
|
d8a594a151 | ||
|
|
60c64b67c7 | ||
|
|
7f0b39a44a | ||
|
|
57784cedc6 | ||
|
|
80b918e6f5 | ||
|
|
64883152c9 | ||
|
|
20bd561062 | ||
|
|
035ce17386 | ||
|
|
bc4dbd1b35 | ||
|
|
1d8266b86d | ||
|
|
b5293b907f | ||
|
|
a11676ed7e | ||
|
|
18e9486c95 | ||
|
|
ef452c292c | ||
|
|
325495a367 | ||
|
|
d854b0b941 | ||
|
|
ca38da576e | ||
|
|
b15b05015e | ||
|
|
5266ae965b | ||
|
|
42b201d8c2 | ||
|
|
d232e847dd | ||
|
|
1b5d9d46fc | ||
|
|
6b1b5165ca | ||
|
|
7719ef503f | ||
|
|
f01b5281fd | ||
|
|
3e4e6d6627 | ||
|
|
16ffc052a3 | ||
|
|
22853d9782 | ||
|
|
8164c1fa8d | ||
|
|
8a42f74a6c | ||
|
|
19a5a07763 | ||
|
|
dd68351235 | ||
|
|
c346e55a46 | ||
|
|
ffdfd427ce | ||
|
|
edbf832e0a | ||
|
|
7887cf7348 | ||
|
|
e6432038b5 | ||
|
|
f8df3c80e1 | ||
|
|
664c824f8b | ||
|
|
95cbf0e6d2 | ||
|
|
b2a542b43e | ||
|
|
f1b736f918 | ||
|
|
282da043b7 | ||
|
|
4519d3820a | ||
|
|
37325f1bdc | ||
|
|
1bbe20dca1 | ||
|
|
b237d70298 | ||
|
|
632f400a74 | ||
|
|
a302db679c | ||
|
|
653972847c | ||
|
|
832f86cf5f | ||
|
|
103434eb9b | ||
|
|
f9dd201563 | ||
|
|
9b9243a61f | ||
|
|
91dbfce18e | ||
|
|
57692a557b | ||
|
|
02bd8149ac | ||
|
|
0920001f45 | ||
|
|
cde939f79c | ||
|
|
f932b3c87a | ||
|
|
b2a7baa079 | ||
|
|
1c37c996dc | ||
|
|
da99af68c6 | ||
|
|
03858dc5c8 | ||
|
|
ebedc6829d | ||
|
|
28322c3645 | ||
|
|
c3395e6779 | ||
|
|
cc47d33c7d | ||
|
|
fedbe2adc5 | ||
|
|
8efc082d1d | ||
|
|
6c2702f9fd | ||
|
|
4824f460c0 | ||
|
|
46fc840c35 | ||
|
|
ce3078dcf2 | ||
|
|
b8255a87cf | ||
|
|
4f6ad47c6a | ||
|
|
d6d6f9c5c1 | ||
|
|
92b06f0954 | ||
|
|
ecd625d40b | ||
|
|
7e81747662 | ||
|
|
cffe5b2f4b | ||
|
|
c349ead32c | ||
|
|
07e6a13378 | ||
|
|
1b54bb157c | ||
|
|
e23fae26c8 | ||
|
|
2501c6aaf6 | ||
|
|
e390a870cc | ||
|
|
e4892fc86d | ||
|
|
dfc67021ee | ||
|
|
25db2774c3 | ||
|
|
22271db431 | ||
|
|
446764873d | ||
|
|
bdb5119806 | ||
|
|
f3bb06531e | ||
|
|
9a74f3708e | ||
|
|
57033311dc | ||
|
|
bda2f8c9ad | ||
|
|
0d5d3ddb2a | ||
|
|
3f8e50031b | ||
|
|
949d5c0c25 | ||
|
|
31e163f9f7 | ||
|
|
b1440ab788 | ||
|
|
6e55d84f01 | ||
|
|
595dbb9af4 | ||
|
|
d1576fd2ee | ||
|
|
1fe05639c9 | ||
|
|
8afff09b3e | ||
|
|
694747471a | ||
|
|
dfcd5cddfa | ||
|
|
a99b7f4572 | ||
|
|
7d7598db54 | ||
|
|
8767a1d8ed | ||
|
|
16c0829d9e | ||
|
|
fc5d832432 | ||
|
|
7292acc27a | ||
|
|
d05bc1572d | ||
|
|
5aa138425f | ||
|
|
c56041811b | ||
|
|
790bff3baf | ||
|
|
571e04fe28 | ||
|
|
c847996146 | ||
|
|
2782d3b4c3 | ||
|
|
582a76f8f0 | ||
|
|
030d676497 | ||
|
|
0794213eef | ||
|
|
427dc849f7 | ||
|
|
e598047964 | ||
|
|
15546732dd | ||
|
|
7bd238852d | ||
|
|
0f406039a0 | ||
|
|
1cd9cdfca0 | ||
|
|
812c4fabe6 | ||
|
|
85f8f59786 | ||
|
|
b0839f114c | ||
|
|
431fecb1c6 | ||
|
|
7620b2b760 | ||
|
|
ad18514824 | ||
|
|
c68a488717 | ||
|
|
e2f0f00831 | ||
|
|
fea2ca5adf | ||
|
|
f77bd0b36d | ||
|
|
20243a79a0 | ||
|
|
a097247272 | ||
|
|
f3cb0712ca | ||
|
|
eedfc3cd9c | ||
|
|
5f4b049ce0 | ||
|
|
20edf26c40 | ||
|
|
4192a00e20 | ||
|
|
4346c52ef0 | ||
|
|
42683e043d | ||
|
|
96c469018e | ||
|
|
f64ac47841 | ||
|
|
c29b7d2942 | ||
|
|
0f7e3b8c52 | ||
|
|
6dff16a612 | ||
|
|
8e15c8bc6a | ||
|
|
558db1fd70 | ||
|
|
796b143316 | ||
|
|
3402805ebb | ||
|
|
c3600c2ba5 | ||
|
|
4ba98f594a | ||
|
|
544a64e5c9 | ||
|
|
f17320702a | ||
|
|
d883694ac4 | ||
|
|
42fba26ea2 | ||
|
|
595dacf213 | ||
|
|
75adfa3fe8 | ||
|
|
0bb8139450 | ||
|
|
60784901b2 | ||
|
|
5020fdd3b1 | ||
|
|
bd4ea56d2a | ||
|
|
fbc8a4116c | ||
|
|
9af318d334 | ||
|
|
88e561c3ae | ||
|
|
1ca82eb058 | ||
|
|
66007c6bbf | ||
|
|
14d4286fd7 | ||
|
|
58b1a48f5b | ||
|
|
5e1eaf8590 | ||
|
|
c946295d96 | ||
|
|
97cbf11f8b | ||
|
|
8d4394e7c6 | ||
|
|
fbdb8cf063 | ||
|
|
964538ec79 | ||
|
|
9a30883e2a | ||
|
|
6408705f82 | ||
|
|
523582e588 | ||
|
|
aaff022e7c | ||
|
|
37eb6aa529 | ||
|
|
9b7356b05e | ||
|
|
33d3bc1330 | ||
|
|
07a2980d5b | ||
|
|
2d8872f2a1 | ||
|
|
16a9bbc84e | ||
|
|
0e5338a709 | ||
|
|
9139e0142b | ||
|
|
9a38312df0 | ||
|
|
d808dcf6f8 | ||
|
|
d5985fc94c | ||
|
|
994687d5ae | ||
|
|
2f4e958ab2 | ||
|
|
26beaa81da | ||
|
|
de5ed11963 | ||
|
|
b557d51276 | ||
|
|
27a8345943 | ||
|
|
131163ff9a | ||
|
|
241f674b99 | ||
|
|
194edee243 | ||
|
|
0995fa0cec | ||
|
|
6717be5210 | ||
|
|
e15745f346 | ||
|
|
a513b0c587 | ||
|
|
72adb963e8 | ||
|
|
aac7df6b87 | ||
|
|
4cf4bfb58f | ||
|
|
59630aec8e | ||
|
|
70c4f6deda | ||
|
|
e2b3f812cb | ||
|
|
fc8adc70e0 | ||
|
|
72c2c06fcb | ||
|
|
7174e32b7a | ||
|
|
600219529c | ||
|
|
d7fd04d14c | ||
|
|
2147e434f7 | ||
|
|
7bd00d115f | ||
|
|
80ef9d2799 | ||
|
|
d6a705d76c | ||
|
|
42472085a6 | ||
|
|
3897e875ee | ||
|
|
c63392657d | ||
|
|
34579b51a1 | ||
|
|
1bb35c5fc1 | ||
|
|
0c408951b8 | ||
|
|
218a094f0d | ||
|
|
3cc405b05b | ||
|
|
d58db530bb | ||
|
|
3628dc3b17 | ||
|
|
89ff42805d | ||
|
|
48866a2609 | ||
|
|
9cc5856c1c | ||
|
|
a4bb174a77 | ||
|
|
82987fa879 | ||
|
|
2df2ff17c5 | ||
|
|
4e4825cb3f | ||
|
|
ed2371beae | ||
|
|
2c2898769e | ||
|
|
001a99ab77 | ||
|
|
9233ec220c | ||
|
|
bb30dc21c5 | ||
|
|
c761fa2243 | ||
|
|
9d172ffcc1 | ||
|
|
1863e22328 | ||
|
|
c591d1950f | ||
|
|
339fcc9152 | ||
|
|
3a54f06540 | ||
|
|
3f305a25a8 | ||
|
|
5a210223b6 | ||
|
|
a7786d934d | ||
|
|
cb3c1f1505 | ||
|
|
50b33b8512 | ||
|
|
80790b5038 | ||
|
|
311c28ae60 | ||
|
|
9906a0554f | ||
|
|
7e92f1881d | ||
|
|
41911806a0 | ||
|
|
610f1519b0 | ||
|
|
29aa56b4f1 | ||
|
|
5004ecedb7 | ||
|
|
ba06a796dc | ||
|
|
b1d6f34976 | ||
|
|
28f4236a57 | ||
|
|
0739a82735 | ||
|
|
3ac9f2e788 | ||
|
|
d9607cc687 | ||
|
|
f0573ef9e2 | ||
|
|
017a3bd7e2 | ||
|
|
d6f9a1055c | ||
|
|
2612e9d565 | ||
|
|
1076d7af10 | ||
|
|
850cecfa6c | ||
|
|
bfdb03bd78 | ||
|
|
56b6e329d5 | ||
|
|
006e384d1a | ||
|
|
9cd9b683a5 | ||
|
|
e01e2c3d2b | ||
|
|
97ce0da564 | ||
|
|
26c5ce59b5 | ||
|
|
d2d94ecf39 | ||
|
|
0ec82bb81d | ||
|
|
ad9e941cb0 | ||
|
|
27dab6ca6d | ||
|
|
762196f03b | ||
|
|
26a565fa45 | ||
|
|
4369db1a43 | ||
|
|
d83f1f87cc | ||
|
|
14027f4be3 | ||
|
|
8bcfb53607 | ||
|
|
700bb21e03 | ||
|
|
1bc9d9083c | ||
|
|
1d7bb021a7 | ||
|
|
3305a74b06 | ||
|
|
6312bc0515 | ||
|
|
b595383281 | ||
|
|
bf85964543 | ||
|
|
d5b020b784 | ||
|
|
8ab0467e78 | ||
|
|
74fe3be7c7 | ||
|
|
b47ae8d9ba | ||
|
|
a926e1a326 | ||
|
|
6048406f52 | ||
|
|
1edf14c742 | ||
|
|
d4bb7c0a51 | ||
|
|
ba4e463517 | ||
|
|
2d0dae4ebb | ||
|
|
1a9d923c44 | ||
|
|
013ec0bf80 | ||
|
|
f82e874cb7 | ||
|
|
976fc569fa | ||
|
|
5aab21f0bf | ||
|
|
1df8344576 | ||
|
|
9eb84cf95e | ||
|
|
47d45b5577 | ||
|
|
ebcc286df0 | ||
|
|
f11d8037ac | ||
|
|
f668b3fe38 | ||
|
|
5ca4e31332 | ||
|
|
a8fbe79e30 | ||
|
|
bdb09b9820 | ||
|
|
79348ebea8 | ||
|
|
b366c1a5e3 | ||
|
|
a5e53b014f | ||
|
|
c2f21e21c8 | ||
|
|
81b8dce7a8 | ||
|
|
e6223f86d8 | ||
|
|
2054c16662 | ||
|
|
95641e562f | ||
|
|
e4953931c7 | ||
|
|
93b5b7a091 | ||
|
|
4f52e893ee | ||
|
|
23ede077a1 | ||
|
|
d5e6f17683 | ||
|
|
4d5980a485 | ||
|
|
19dd902519 | ||
|
|
f046a46275 | ||
|
|
25e9eafa8b | ||
|
|
f4ff981008 | ||
|
|
a1b48aff89 | ||
|
|
0aa34caa82 | ||
|
|
98ce9b1a06 | ||
|
|
ab157b21ea | ||
|
|
53c72d3031 | ||
|
|
165e2f97d0 | ||
|
|
6c577059ad | ||
|
|
0ea4dc769b | ||
|
|
a9b626e810 | ||
|
|
b90d6f9769 | ||
|
|
f0ea008c46 | ||
|
|
c43d5ccd63 | ||
|
|
d6d7b398e4 | ||
|
|
e1032e5094 | ||
|
|
a32ac298c5 | ||
|
|
2e6ab670cb | ||
|
|
72b7fce48c | ||
|
|
fa281f1ca1 | ||
|
|
1b92311aeb | ||
|
|
a593212f03 | ||
|
|
c4ec928953 | ||
|
|
e7df7fabeb | ||
|
|
1c187f2d81 | ||
|
|
da66cf90c3 | ||
|
|
0e8bd7407f | ||
|
|
d70f14addb | ||
|
|
e7b9eea3a5 | ||
|
|
97af9d822d | ||
|
|
cf7a09ab76 | ||
|
|
e755627421 | ||
|
|
f9be64a988 | ||
|
|
d65431e6cc | ||
|
|
86fb962fdb | ||
|
|
d003837b27 | ||
|
|
fd813e3c5a | ||
|
|
a3691c4423 | ||
|
|
9506f22025 | ||
|
|
06ae907949 | ||
|
|
555523b2af | ||
|
|
3b9772f772 | ||
|
|
891c80f48c | ||
|
|
105b09e1ec | ||
|
|
9fe7596a23 | ||
|
|
82af7cadc5 | ||
|
|
800c81bb9a | ||
|
|
5653a4f7ee | ||
|
|
4f14ffe63b | ||
|
|
d57acefe56 | ||
|
|
fb61e5a8da | ||
|
|
264516bfdb | ||
|
|
6d8f8996d5 | ||
|
|
ba8557d3bf | ||
|
|
d18fd0b957 | ||
|
|
fba96774f4 | ||
|
|
0b2764ea62 | ||
|
|
64d81ed47b | ||
|
|
9a9742888b | ||
|
|
5400b30a90 | ||
|
|
673f4a4beb | ||
|
|
05a27649aa | ||
|
|
26c6b12dea | ||
|
|
9a18ca222f | ||
|
|
354f31b870 | ||
|
|
c6c2f58ec0 | ||
|
|
4a146f00f6 | ||
|
|
2c10ac59d3 | ||
|
|
9a98fb9453 | ||
|
|
b20b111385 | ||
|
|
6ac2429e2a | ||
|
|
9d52732f18 | ||
|
|
1c7f843a4c | ||
|
|
fdaf301bd6 | ||
|
|
5a9f2f3afe | ||
|
|
6a1b30761a | ||
|
|
8f8b08fad6 | ||
|
|
312b63a4c8 | ||
|
|
1598b538ab | ||
|
|
16ce46a741 | ||
|
|
4456598228 | ||
|
|
2a937c63b9 | ||
|
|
191bc940c7 | ||
|
|
05673758e3 | ||
|
|
cff2b9a8ca | ||
|
|
586095a475 | ||
|
|
eae2082a1e | ||
|
|
4576548df3 | ||
|
|
266e0c8bfd | ||
|
|
f5c07dbab5 | ||
|
|
c8a28a1ad7 | ||
|
|
72cc454314 | ||
|
|
7fe2c1f939 | ||
|
|
087e7a68b6 | ||
|
|
abeabf15a1 | ||
|
|
f9bfcaab7b | ||
|
|
afa0182f02 | ||
|
|
b83de5934d | ||
|
|
c294d3bfb4 | ||
|
|
a7cdb2351a | ||
|
|
46ef21a3ed | ||
|
|
18c8d0178c | ||
|
|
ebc79dafbd | ||
|
|
a1d2467643 | ||
|
|
8220f0fa56 | ||
|
|
ec385acc7f | ||
|
|
04c1cc62d4 | ||
|
|
abdbd65f60 | ||
|
|
1f32a060da | ||
|
|
699d80c150 | ||
|
|
56bcac7600 | ||
|
|
cab3365104 | ||
|
|
3821bd00fe | ||
|
|
62701fd0f1 | ||
|
|
1be5e60506 | ||
|
|
c9f1512358 | ||
|
|
8f23aed6af | ||
|
|
6a62ae9c69 | ||
|
|
2c3de5688b | ||
|
|
f3c08b4ec4 | ||
|
|
69e3baafe5 | ||
|
|
5844ccc395 | ||
|
|
be9c6fa54b | ||
|
|
d14f277c7b | ||
|
|
593bf08b92 | ||
|
|
85f631f868 | ||
|
|
5ad964bcb6 | ||
|
|
137a404bdc | ||
|
|
5204ec758a | ||
|
|
6f4fb69c62 | ||
|
|
0a1b37c965 | ||
|
|
90bdafb05a | ||
|
|
8cc668ae6d | ||
|
|
1787dc4590 | ||
|
|
0a9cc8fcd7 | ||
|
|
10c06daf5d | ||
|
|
a262e42980 | ||
|
|
4cd3d045d1 | ||
|
|
92357576b1 | ||
|
|
d45f67f8c2 | ||
|
|
2571cdffee | ||
|
|
c31cb6da27 | ||
|
|
5503929d15 | ||
|
|
ca32dda1fe | ||
|
|
12111e0b63 | ||
|
|
bdd46c0fc0 | ||
|
|
daf4c8fe86 | ||
|
|
bd2c2aff9c | ||
|
|
921f75e1f3 | ||
|
|
44a3b85f0b | ||
|
|
f9e827395b | ||
|
|
64a9a80774 | ||
|
|
e10594391d | ||
|
|
60eb03a221 | ||
|
|
c0a0f10af0 | ||
|
|
56e1ed0e25 | ||
|
|
a9f33cbca6 | ||
|
|
6f1d39e1bb | ||
|
|
838f7c5598 | ||
|
|
0f54cc5927 | ||
|
|
12745f70cf | ||
|
|
442737767f | ||
|
|
61ac46e467 | ||
|
|
85550580d5 | ||
|
|
ed69ac5fe0 | ||
|
|
0aec5a5783 | ||
|
|
c1885fe31b | ||
|
|
c2270a2b3a | ||
|
|
3e60515bb3 | ||
|
|
8550c13688 | ||
|
|
3aa65694aa | ||
|
|
52403687db | ||
|
|
3e83409cf4 | ||
|
|
9b051955bd | ||
|
|
35c8126add | ||
|
|
67e1c8ce7f | ||
|
|
6e5fbda8e5 | ||
|
|
90e7ccd80a | ||
|
|
c09b3eedd2 | ||
|
|
9441e8a04b | ||
|
|
301dc70ab4 |
37
.editorconfig
Normal file
@@ -0,0 +1,37 @@
|
||||
# EditorConfig is awesome:http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# All Files
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Solution Files
|
||||
[*.sln]
|
||||
indent_style = tab
|
||||
|
||||
# XML Project Files
|
||||
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
|
||||
indent_size = 2
|
||||
|
||||
# Configuration Files
|
||||
[*.{json,xml,yml,config,props,targets,nuspec,resx,ruleset}]
|
||||
indent_size = 2
|
||||
|
||||
# Markdown Files
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
# Web Files
|
||||
[*.{htm,html,js,ts,css,scss,less}]
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
|
||||
# Bash Files
|
||||
[*.sh]
|
||||
end_of_line = lf
|
||||
3
.gitattributes
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
* text=auto
|
||||
*.cs text=auto diff=csharp
|
||||
*.sln text=auto eol=crlf
|
||||
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [xoofx]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
64
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
name: ci
|
||||
|
||||
env:
|
||||
PROJECT_NAME: Markdig
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'img/**'
|
||||
- 'changelog.md'
|
||||
- 'readme.md'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install .NET 6.0
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
|
||||
- name: Build (Release)
|
||||
run: dotnet build src -c Release
|
||||
|
||||
- name: SpecFileGen
|
||||
run: dotnet src/SpecFileGen/bin/Release/net6.0/SpecFileGen.dll
|
||||
|
||||
- name: Test (Release)
|
||||
run: dotnet test src -c Release
|
||||
|
||||
- name: Build & Test (Debug)
|
||||
run: dotnet test src -c Debug
|
||||
|
||||
- name: Coverlet
|
||||
run: dotnet test src -c Release -f net6.0 /p:Include=\"[${{env.PROJECT_NAME}}]*\" /p:CollectCoverage=true /p:CoverletOutputFormat=lcov
|
||||
|
||||
- name: Coveralls Upload
|
||||
uses: coverallsapp/github-action@1.1.3
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path-to-lcov: src/${{env.PROJECT_NAME}}.Tests/coverage.info
|
||||
|
||||
- name: Pack
|
||||
run: dotnet pack src -c Release
|
||||
|
||||
- name: Pack Signed
|
||||
run: dotnet pack -c Release src/${{env.PROJECT_NAME}}.Signed/${{env.PROJECT_NAME}}.Signed.csproj
|
||||
|
||||
- name: Publish
|
||||
if: github.event_name == 'push'
|
||||
run: |
|
||||
if ( "${{github.ref}}" -match "^refs/tags/[0-9]+\.[0-9]+\.[0-9]+$" ) {
|
||||
dotnet nuget push src\${{env.PROJECT_NAME}}\bin\Release\*.nupkg -s nuget.org -k ${{secrets.NUGET_TOKEN}}
|
||||
dotnet nuget push src\${{env.PROJECT_NAME}}.Signed\bin\Release\*.nupkg -s nuget.org -k ${{secrets.NUGET_TOKEN}}
|
||||
} else {
|
||||
echo "publish is only enabled by tagging with a release tag"
|
||||
}
|
||||
27
.gitignore
vendored
@@ -6,6 +6,8 @@
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
@@ -136,7 +138,7 @@ publish/
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
@@ -214,3 +216,26 @@ FakesAssemblies/
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Common IntelliJ Platform excludes
|
||||
|
||||
# User specific
|
||||
**/.idea/**/workspace.xml
|
||||
**/.idea/**/tasks.xml
|
||||
**/.idea/shelf/*
|
||||
**/.idea/dictionaries
|
||||
**/.idea/httpRequests/
|
||||
|
||||
# Sensitive or high-churn files
|
||||
**/.idea/**/dataSources/
|
||||
**/.idea/**/dataSources.ids
|
||||
**/.idea/**/dataSources.xml
|
||||
**/.idea/**/dataSources.local.xml
|
||||
**/.idea/**/sqlDataSources.xml
|
||||
**/.idea/**/dynamic.xml
|
||||
|
||||
# Rider
|
||||
# Rider auto-generates .iml files, and contentModel.xml
|
||||
**/.idea/**/*.iml
|
||||
**/.idea/**/contentModel.xml
|
||||
**/.idea/**/modules.xml
|
||||
|
||||
259
changelog.md
Normal file
@@ -0,0 +1,259 @@
|
||||
# Changelog
|
||||
|
||||
## 0.27.0 (23 Jan 2022)
|
||||
- Fix link reference definition parse bug with title and CRLF ([PR #590](https://github.com/lunet-io/markdig/pull/590))
|
||||
- Move tests to net6.0 ([PR #560](https://github.com/lunet-io/markdig/pull/560))
|
||||
|
||||
## 0.26.0 (27 Aug 2021)
|
||||
- Fix rendering diff between line endings ([PR #560](https://github.com/lunet-io/markdig/pull/560))
|
||||
- Make Mathematics extension respect EnableHtml* options ([PR #570](https://github.com/lunet-io/markdig/pull/570))
|
||||
|
||||
## 0.25.0 (10 June 2021)
|
||||
- Fix regression when parsing link reference definitions (#543)
|
||||
- Make digits in JiraKey's posible ([PR #548](https://github.com/lunet-io/markdig/pull/548))
|
||||
|
||||
## 0.24.0 (20 Mar 2021)
|
||||
- Add support for roundtrip Markdown ([PR #481](https://github.com/lunet-io/markdig/pull/481))
|
||||
- Introduction of nullability ([PR #522](https://github.com/lunet-io/markdig/pull/522) [PR #524](https://github.com/lunet-io/markdig/pull/524) [PR #525](https://github.com/lunet-io/markdig/pull/525) [PR #526](https://github.com/lunet-io/markdig/pull/526) [PR #527](https://github.com/lunet-io/markdig/pull/527))
|
||||
- Various internal cleanup and small performance improvements ([PR #521](https://github.com/lunet-io/markdig/pull/521) [PR #524](https://github.com/lunet-io/markdig/pull/524) [PR #525](https://github.com/lunet-io/markdig/pull/525) [PR #529](https://github.com/lunet-io/markdig/pull/529) [PR #531](https://github.com/lunet-io/markdig/pull/531) [PR #532](https://github.com/lunet-io/markdig/pull/532))
|
||||
|
||||
## 0.23.0 (16 Jan 2021)
|
||||
- Add depth limits to avoid pathological-case parsing times/StackOverflows (#500)
|
||||
- Breaking change: rename AutolineInlineParser to AutolinkInlineParser
|
||||
|
||||
## 0.22.1 (2 Dec 2020)
|
||||
- Update logo for NuGet package
|
||||
|
||||
## 0.22.0 (05 Oct 2020)
|
||||
- Fix Setext headings in block quotes.
|
||||
- Fix tel: treated as autolink ([PR #478](https://github.com/lunet-io/markdig/pull/478))
|
||||
- Make Inline.FirstParentOfType public ([PR #474](https://github.com/lunet-io/markdig/pull/474))
|
||||
- Fix `&` to be parsed as a punctuation while it was detected as a html entity in certain cases ([PR #471](https://github.com/lunet-io/markdig/pull/471))
|
||||
- Add ParentBlock property to ContainerInline ([PR #468](https://github.com/lunet-io/markdig/pull/468))
|
||||
|
||||
## 0.21.1 (17 Aug 2020)
|
||||
- Fix Markdig.Signed on GitHub Actions
|
||||
|
||||
## 0.21.0 (17 Aug 2020)
|
||||
- Restore support for .NET 4.5 (#)
|
||||
- Add IReadonlyList interface to ContainerBlock to unify and simplify enumeration (#425)
|
||||
- Fix relative uri detection to be cross-platform compatible (#430)
|
||||
- Escape URLs scheme (#431)
|
||||
- Fix media links (#435)
|
||||
- Fix parsing math blocks with no leading or trailing whitespace (#452)
|
||||
- Add support for autolink `tel:` uri (#453)
|
||||
- Fallback to non-punycode encoding for invalid IDN urls (#449)
|
||||
- Pipe Tables: Normalize using header column count (#455)
|
||||
- Expose IndentCount of FencedCodeBlock (#464)
|
||||
|
||||
## 0.20.0 (18 Apr 2020)
|
||||
- Markdig is now compatible only with `NETStandard 2.0`, `NETStandard 2.1`, `NETCoreApp 2.1` and `NETCoreApp 3.1`.
|
||||
- Many performance improvements from [PR #416](https://github.com/lunet-io/markdig/pull/416)
|
||||
[PR #417](https://github.com/lunet-io/markdig/pull/417)
|
||||
[PR #418](https://github.com/lunet-io/markdig/pull/418)
|
||||
[PR #421](https://github.com/lunet-io/markdig/pull/421)
|
||||
[PR #422](https://github.com/lunet-io/markdig/pull/422)
|
||||
[PR #410](https://github.com/lunet-io/markdig/pull/410)
|
||||
|
||||
## 0.18.3 (8 Mar 2020)
|
||||
- Publish NuGet Symbol packages
|
||||
|
||||
## 0.18.2 (8 Mar 2020)
|
||||
- Optimize LineReader.ReadLine in [PR #393](https://github.com/lunet-io/markdig/pull/393)
|
||||
- Use HashSet<T> instead of Dictionary<TKey, TValue> in CharacterMap<T> in [PR #394](https://github.com/lunet-io/markdig/pull/394)
|
||||
- Use BitVector128 in CharacterMap<T> in [PR #396](https://github.com/lunet-io/markdig/pull/396)
|
||||
- Optimizations in StringLineGroup in [PR #399](https://github.com/lunet-io/markdig/pull/399)
|
||||
- Fixed a bug in HeadingRenderer in [PR #402](https://github.com/lunet-io/markdig/pull/402)
|
||||
- Fixes issue #303 in [PR #404](https://github.com/lunet-io/markdig/pull/404)
|
||||
- Make output of HtmlTableRenderer XML wellformed in [PR #406](https://github.com/lunet-io/markdig/pull/406)
|
||||
|
||||
## 0.18.1 (21 Jan 2020)
|
||||
- Re-allow emojis and smileys customization, that was broken in [PR #308](https://github.com/lunet-io/markdig/pull/308) ([PR #386](https://github.com/lunet-io/markdig/pull/386))
|
||||
- Add `IHostProvider` for medialink customization (#337), support protocol-less url (#135) ([(PR #341)](https://github.com/lunet-io/markdig/pull/341))
|
||||
- Add missing Descendants<T> overload ([(PR #387)](https://github.com/lunet-io/markdig/pull/387))
|
||||
|
||||
## 0.18.0 (24 Oct 2019)
|
||||
- Ignore backslashes in GFM AutoLinks ([(PR #357)](https://github.com/lunet-io/markdig/pull/357))
|
||||
- Fix SmartyPants quote matching ([(PR #360)](https://github.com/lunet-io/markdig/pull/360))
|
||||
- Fix generic attributes with values of length 1 ([(PR #361)](https://github.com/lunet-io/markdig/pull/361))
|
||||
- Fix link text balanced bracket matching ([(PR #375)](https://github.com/lunet-io/markdig/pull/375))
|
||||
- Improve overall performance and substantially reduce allocations ([(PR #377)](https://github.com/lunet-io/markdig/pull/377))
|
||||
|
||||
## 0.17.1 (04 July 2019)
|
||||
- Fix regression when escaping HTML characters ([(PR #340)](https://github.com/lunet-io/markdig/pull/340))
|
||||
- Update Emoji Dictionary ([(PR #346)](https://github.com/lunet-io/markdig/pull/346))
|
||||
|
||||
## 0.17.0 (10 May 2019)
|
||||
- Update to latest CommonMark specs 0.29 ([(PR #327)](https://github.com/lunet-io/markdig/pull/327))
|
||||
- Add `AutoLinkOptions` with `OpenInNewWindow`, `UseHttpsForWWWLinks` ([(PR #327)](https://github.com/lunet-io/markdig/pull/327))
|
||||
- Add `DisableHeadings` extension method to `MarkdownPipelineBuilder` ([(PR #327)](https://github.com/lunet-io/markdig/pull/327))
|
||||
- Drop support for netstandard1.1 and Portable Class Libraries ([(PR #319)](https://github.com/lunet-io/markdig/pull/319))
|
||||
- Allow non-ASCII characters in url domain names ([(PR #319)](https://github.com/lunet-io/markdig/pull/319))
|
||||
- Add better support for youtu.be link ([(PR #336)](https://github.com/lunet-io/markdig/pull/336))
|
||||
- Fix backsticks in Markdown.Normalize ([(PR #334)](https://github.com/lunet-io/markdig/pull/334))
|
||||
|
||||
## 0.16.0 (25 Feb 2019)
|
||||
- Improve performance of emoji-abbreviation parser ([(PR #305)](https://github.com/lunet-io/markdig/pull/305))
|
||||
- Change output for math extension to use a rendering more compatible with existing Math JS libraries ([(PR #311)](https://github.com/lunet-io/markdig/pull/311))
|
||||
- Improve emphasis parser to allow to match more than 2 characters ([(PR #301)](https://github.com/lunet-io/markdig/pull/301))
|
||||
- Output attached attributes to a `<tr>` from a table row ([(PR #300)](https://github.com/lunet-io/markdig/pull/300))
|
||||
- Improve MarkdownObject.Descendants() search ([(PR #288)](https://github.com/lunet-io/markdig/pull/288))
|
||||
- Allow to pass a `MarkdownParserContext` ([(PR #285)](https://github.com/lunet-io/markdig/pull/285))
|
||||
|
||||
## 0.15.7 (11 Jan 2019)
|
||||
- Add configurable leading count for ATX headers ([(PR #282)](https://github.com/lunet-io/markdig/pull/282))
|
||||
- Render XML well-formed boolean attribute ([(PR #281)](https://github.com/lunet-io/markdig/pull/281))
|
||||
|
||||
## 0.15.6 (28 Dec 2018)
|
||||
- Fix potential hang when parsing LinkReferenceDefinition #278
|
||||
- Fix parsing of an invalid html entity (#277)
|
||||
- Fix IndexOutOfRangeException while parsing fenced code block with a single trailing space (#276)
|
||||
- Add tests for checking that ArgumentOutOfRangeException doesn't occur on invalid input md string (#275)
|
||||
|
||||
## 0.15.5 (11 Dec 2018)
|
||||
- Empty image alt text for link reference definitions ([(PR #254)](https://github.com/lunet-io/markdig/pull/254))
|
||||
- Fix AutoLink Match links without slash after domain ([(PR #260)](https://github.com/lunet-io/markdig/pull/260))
|
||||
- Make AutoLink ValidPreviousCharacters configurable ([(PR #264)](https://github.com/lunet-io/markdig/pull/264))
|
||||
- Ensuring line breaks when renderer does not have html enabled ([(PR #270)](https://github.com/lunet-io/markdig/pull/270))
|
||||
|
||||
## 0.15.4 (07 Oct 2018)
|
||||
- Add autolink domain GFM validation ([(PR #253)](https://github.com/lunet-io/markdig/pull/253))
|
||||
|
||||
## 0.15.3 (15 Sep 2018)
|
||||
- Add support for RTL ([(PR #239)](https://github.com/lunet-io/markdig/pull/239))
|
||||
- Add MarkdownDocument.LineCount ([(PR #241)](https://github.com/lunet-io/markdig/pull/241))
|
||||
- Fix source positions for link definitions ([(PR #243)](https://github.com/lunet-io/markdig/pull/243))
|
||||
- Add ListItemBlock.Order ([(PR #244)](https://github.com/lunet-io/markdig/pull/244))
|
||||
- Add MarkdownDocument.LineStartIndexes ([(PR #247)](https://github.com/lunet-io/markdig/pull/247))
|
||||
|
||||
## 0.15.2 (21 Aug 2018)
|
||||
- Fix footnotes parsing when they are defined after a container that has been closed in the meantime (#223)
|
||||
|
||||
## 0.15.1 (10 July 2018)
|
||||
- Add support for `netstandard2.0`
|
||||
- Make AutoIdentifierExtension thread safe
|
||||
|
||||
## 0.15.0 (4 Apr 2018)
|
||||
- Add `ConfigureNewLine` extension method to `MarkdownPipelineBuilder` ([(PR #214)](https://github.com/lunet-io/markdig/pull/214))
|
||||
- Add alternative `Use` extension method to `MarkdownPipelineBuilder` that receives an object instance ([(PR #213)](https://github.com/lunet-io/markdig/pull/213))
|
||||
- Added class attribute to media link extension ([(PR #203)](https://github.com/lunet-io/markdig/pull/203))
|
||||
- Optional link rewriter func for HtmlRenderer #143 ([(PR #201)](https://github.com/lunet-io/markdig/pull/201))
|
||||
- Upgrade NUnit3TestAdapter from 3.2 to 3.9 to address Resharper test runner problems ([(PR #199)](https://github.com/lunet-io/markdig/pull/199))
|
||||
- HTML renderer supports converting relative URLs on links and images to absolute #143 ([(PR #197)](https://github.com/lunet-io/markdig/pull/197))
|
||||
|
||||
## 0.14.9 (15 Jan 2018)
|
||||
- AutoLinkParser should to remove mailto: in outputted text ([(PR #195)](https://github.com/lunet-io/markdig/pull/195))
|
||||
- Add support for `music.yandex.ru` and `ok.ru` for MediaLinks extension ([(PR #193)](https://github.com/lunet-io/markdig/pull/193))
|
||||
## 0.14.8 (05 Dec 2017)
|
||||
- Fix potential StackOverflow exception when processing deep nested `|` delimiters (#179)
|
||||
## 0.14.7 (25 Nov 2017)
|
||||
- Fix autolink attached attributes not being displayed properly (#175)
|
||||
## 0.14.6 (21 Nov 2017)
|
||||
- Fix yaml frontmatter issue when ending with a empty line (#170)
|
||||
## 0.14.5 (18 Nov 2017)
|
||||
- Fix changelog link from nuget package
|
||||
## 0.14.4 (18 Nov 2017)
|
||||
- Add changelog.md
|
||||
- Fix bug when a thematic break is inside a fenced code block inside a pending list (#164)
|
||||
- Add support for GFM autolinks (#165, #169)
|
||||
- Better handle YAML frontmatter in case the opening `---` is never actually closed (#160)
|
||||
- Fix link conflict between a link to an image definition and heading auto-identifiers (#159)
|
||||
## 0.14.3
|
||||
- Make EmojiExtension.EnableSmiley public
|
||||
## 0.14.2
|
||||
- Fix issue with emphasis preceded/followed by an HTML entity (#157)
|
||||
- Add support for link reference definitions for Normalize renderer (#155)
|
||||
- Add option to disable smiley parsing in EmojiAndSmiley extension
|
||||
## 0.14.1
|
||||
- Fix crash in Markdown.Normalize to handle HtmlBlock correctly
|
||||
- Add better handling of bullet character for lists in Markdown.Normalize
|
||||
## 0.14.0
|
||||
- Add Markdown.ToPlainText, Add option HtmlRenderer.EnableHtmlForBlock.
|
||||
- Add Markdown.Normalize, to allow to normalize a markdown document. Add NormalizeRenderer, to render a MarkdownDocument back to markdown.
|
||||
## 0.13.4
|
||||
- Add support for single table header row without a table body rows (#141)
|
||||
- ADd support for `nomnoml` diagrams
|
||||
## 0.13.3
|
||||
- Add support for Pandoc YAML frontmatter (#138)
|
||||
## 0.13.2
|
||||
- Add support for UAP10.0 (#137)
|
||||
## 0.13.1
|
||||
- Fix indenting issue after a double digit list block using a tab (#134)
|
||||
## 0.13.0
|
||||
- Update to latest CommonMark specs 0.28
|
||||
## 0.12.3
|
||||
- Fix issue with HTML blocks for heading h2,h3,h4,h5,h6 that were not correctly identified as HTML blocks as per CommonMark spec
|
||||
## 0.12.2
|
||||
- Fix issue with generic attributes used just before a pipe table (issue #121)
|
||||
## 0.12.1
|
||||
- Fix issue with media links extension when a URL to video is used, an unexpected closing `</iframe>` was inserted (issue #119)
|
||||
## 0.12.0
|
||||
- Add new extension JiraLink support (thanks to @clarkd)
|
||||
- Fix issue in html attributes not parsing correctly properties (thanks to @meziantou)
|
||||
- Fix issues detected by an automatic static code analysis tool
|
||||
## 0.11.0
|
||||
- Fix issue with math extension and $$ block parsing not handling correctly beginning of a $$ as a inline math instead (issue #107)
|
||||
- Fix issue with custom attributes for emphasis
|
||||
- Add support for new special custom arrows emoji (`->` `<-` `<->` `<=` `=>` `<==>`)
|
||||
## 0.10.7
|
||||
- Fix issue when an url ends by a dot `.`
|
||||
## 0.10.6
|
||||
- Fix emphasis with HTML entities
|
||||
## 0.10.5
|
||||
- Several minor fixes
|
||||
## 0.10.4
|
||||
- Fix issue with autolinks
|
||||
- Normalize number of columns for tables
|
||||
## 0.10.3
|
||||
- Fix issue with pipetables shifting a cell to a new column (issue #73)
|
||||
## 0.10.2
|
||||
- Fix exception when trying to urlize an url with an unicode character outside the supported range by NormD (issue #75)
|
||||
## 0.10.1
|
||||
- Update to latest CommonMark specs
|
||||
- Fix source span for LinkReferenceDefinition
|
||||
## 0.10.0
|
||||
- Breaking change of the IMarkdownExtension to allow to receive the MarkdownPipeline for the renderers setup
|
||||
## 0.9.1
|
||||
- Fix regression bug with conflicts between autolink extension and html inline/regular links
|
||||
## 0.9.0
|
||||
- Add new Autolink extension
|
||||
## 0.8.5
|
||||
- Allow to force table column alignment to left
|
||||
## 0.8.4
|
||||
- Fix issue when calculating the span of an indented code block within a list. Make sure to include first whitespace on the line
|
||||
## 0.8.3
|
||||
- fix NullReferenceException with Gridtables extension when a single `+` is entered on a line
|
||||
## 0.8.2
|
||||
- fix potential cast exception with Abbreviation extension and empty literals
|
||||
## 0.8.1
|
||||
- new extension to disable URI escaping for non-US-ASCII characters to workaround a bug in Edge/IE
|
||||
- Fix an issue with abbreviations with left/right multiple non-punctuation/space characters
|
||||
## 0.8.0
|
||||
- Update to latest CommonMark specs
|
||||
- Fix empty literal
|
||||
- Add YAML frontmatter extension
|
||||
## 0.7.5
|
||||
- several bug fixes (pipe tables, disable HTML, special attributes, inline maths, abbreviations...)
|
||||
- add support for rowspan in grid tables
|
||||
## 0.7.4
|
||||
- Fix bug with strong emphasis starting at the beginning of a line
|
||||
## 0.7.3
|
||||
- Fix threading issue with pipeline
|
||||
## 0.7.2
|
||||
- Fix rendering of table colspan with non english locale
|
||||
- Fix grid table colspan parsing
|
||||
- Add nofollow extension for links
|
||||
## 0.7.1
|
||||
- Fix issue in smarty pants which could lead to an InvalidCastException
|
||||
- Update parsers to latest CommonMark specs
|
||||
## 0.7.0
|
||||
- Update to latest NETStandard.Library 1.6.0
|
||||
- Fix issue with digits in auto-identifier extension
|
||||
- Fix incorrect start of span calculated for code indented blocks
|
||||
## 0.6.2
|
||||
- Handle latest CommonMark specs for corner cases for emphasis (See https://talk.commonmark.org/t/emphasis-strong-emphasis-corner-cases/2123/1 )
|
||||
## 0.6.1:
|
||||
- Fix issue with autoidentifier extension overriding manual HTML attributes id on headings
|
||||
## 0.6.0
|
||||
- Fix conflicts between PipeTables and SmartyPants extensions
|
||||
- Add SelfPipeline extension
|
||||
|
Before Width: | Height: | Size: 4.3 KiB |
@@ -1,131 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="192"
|
||||
height="192"
|
||||
viewBox="0 0 192 192"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="markdig.svg"
|
||||
inkscape:export-filename="C:\Code\lunet-io\markdig\markdig.png"
|
||||
inkscape:export-xdpi="93.400002"
|
||||
inkscape:export-ydpi="93.400002">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4.4374889"
|
||||
inkscape:cx="174.14769"
|
||||
inkscape:cy="93.189838"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1377"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
units="px" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline"
|
||||
transform="translate(0,-860.36216)">
|
||||
<path
|
||||
style="fill:#000000"
|
||||
d="M 75.009766 60.486328 L 34.648438 122.74414 C 33.793918 123.59769 37.647081 134.96384 37.052734 136.09766 L 4.0234375 177.69727 C 2.4142291 180.39677 3.2900484 182.21846 4.8730469 183.84766 C 5.9214414 184.93636 6.6591287 186.06887 8.3828125 185.67188 C 9.0750612 185.50987 10.104893 185.27338 10.875 184.76758 L 52.806641 151.81445 C 53.912466 151.23195 64.44071 154.77813 65.289062 153.92383 L 126.45312 111.46875 L 75.009766 60.486328 z M 89.632812 84.769531 L 103.77539 98.912109 L 79.027344 123.66016 L 86.238281 130.87109 L 48.621094 139.92383 L 57.435547 102.30859 L 64.884766 109.51758 L 89.632812 84.769531 z "
|
||||
transform="translate(0,860.36216)"
|
||||
id="path4140" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 111.18463,862.06984 c -1.98231,0 -3.96282,0.78454 -5.54759,2.38445 L 88.200894,881.94537 75.123368,868.82653 c -3.169466,-3.18017 -7.92567,-3.18017 -11.095213,0 -3.169466,3.18017 -3.169466,7.95108 0,11.13109 l 13.077526,13.11885 -11.095212,10.73223 82.031621,81.49227 11.09525,-11.13109 13.87084,13.51554 c 1.57915,1.59105 3.56724,2.38445 5.54759,2.38445 1.98231,0 3.96285,-0.78453 5.54762,-2.38445 3.16947,-3.18017 3.16947,-7.95111 0,-11.13109 l -13.87083,-13.11884 17.43611,-17.09442 c 1.17983,-1.59105 1.98231,-3.5788 1.98231,-5.96329 0,-1.98351 -0.79863,-3.97554 -2.37816,-5.56446 l -70.54053,-70.35856 c -1.57914,-1.59105 -3.56724,-2.38446 -5.54758,-2.38446 z m 15.86949,20.75826 9.50139,9.5291 -4.04453,23.11372 23.04691,-4.05619 9.50138,9.5291 -36.8437,36.95052 -9.50135,-9.5291 21.13082,-21.19197 -23.04672,4.05619 4.04453,-23.11396 -21.131009,21.19198 -9.501383,-9.5291 36.843662,-36.95048 z"
|
||||
id="path4142"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
id="rect4168"
|
||||
mask="url(#a)"
|
||||
ry="0"
|
||||
height="0"
|
||||
width="0"
|
||||
x="141.51523"
|
||||
y="364.10403" />
|
||||
<rect
|
||||
id="rect4184"
|
||||
mask="url(#a)"
|
||||
ry="0"
|
||||
height="0"
|
||||
width="0"
|
||||
x="96.108383"
|
||||
y="352.01443" />
|
||||
<rect
|
||||
id="rect4200"
|
||||
mask="url(#a)"
|
||||
ry="2.1886277"
|
||||
height="0.14590852"
|
||||
width="0.17464182"
|
||||
x="87.014519"
|
||||
y="276.38696" />
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot4797"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
transform="matrix(0.1746417,0,0,0.1459084,499.69318,366.39614)"><flowRegion
|
||||
id="flowRegion4799"><rect
|
||||
id="rect4801"
|
||||
width="972.27185"
|
||||
height="618.71844"
|
||||
x="959.01355"
|
||||
y="-976.15039" /></flowRegion><flowPara
|
||||
id="flowPara4803" /></flowRoot> <g
|
||||
id="g4833"
|
||||
transform="matrix(0.09510056,0,0,0.09061765,496.09965,368.83934)">
|
||||
<rect
|
||||
id="rect4823"
|
||||
height="1"
|
||||
width="1"
|
||||
x="0"
|
||||
y="0"
|
||||
style="fill:#ffffff" />
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4886"
|
||||
d="m 111.18463,862.06984 c -1.98231,0 -3.96282,0.78454 -5.54759,2.38445 L 88.200894,881.94537 75.123368,868.82653 c -3.169466,-3.18017 -7.92567,-3.18017 -11.095213,0 -3.169466,3.18017 -3.169466,7.95108 0,11.13109 l 13.077526,13.11885 -11.095212,10.73223 82.031621,81.49227 11.09525,-11.13109 13.87084,13.51554 c 1.57915,1.59105 3.56724,2.38445 5.54759,2.38445 1.98231,0 3.96285,-0.78453 5.54762,-2.38445 3.16947,-3.18017 3.16947,-7.95111 0,-11.13109 l -13.87083,-13.11884 17.43611,-17.09442 c 1.17983,-1.59105 1.98231,-3.5788 1.98231,-5.96329 0,-1.98351 -0.79863,-3.97554 -2.37816,-5.56446 l -70.54053,-70.35856 c -1.57914,-1.59105 -3.56724,-2.38446 -5.54758,-2.38446 z m 15.86949,20.75826 9.50139,9.5291 -4.04453,23.11372 23.04691,-4.05619 9.50138,9.5291 -36.8437,36.95052 -9.50135,-9.5291 21.13082,-21.19197 -23.04672,4.05619 4.04453,-23.11396 -21.131009,21.19198 -9.501383,-9.5291 36.843662,-36.95048 z"
|
||||
style="fill:#000000;fill-opacity:1" />
|
||||
<g
|
||||
transform="translate(234.63786,787.55486)"
|
||||
id="g4170" />
|
||||
<path
|
||||
id="path4225"
|
||||
transform="translate(0,860.36216)"
|
||||
d="M 75.009766 60.486328 L 34.648438 122.74414 C 33.793918 123.59769 37.647081 134.96384 37.052734 136.09766 L 4.0234375 177.69727 C 2.4142291 180.39677 3.2900484 182.21846 4.8730469 183.84766 C 5.9214414 184.93636 6.6591287 186.06887 8.3828125 185.67188 C 9.0750612 185.50987 10.104893 185.27338 10.875 184.76758 L 52.806641 151.81445 C 53.912466 151.23195 64.44071 154.77813 65.289062 153.92383 L 126.45312 111.46875 L 75.009766 60.486328 z M 89.632812 84.769531 L 103.77539 98.912109 L 79.027344 123.66016 L 86.238281 130.87109 L 48.621094 139.92383 L 57.435547 102.30859 L 64.884766 109.51758 L 89.632812 84.769531 z "
|
||||
style="fill:#000000" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
BIN
img/BenchmarkCPU.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
img/BenchmarkMemory.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
img/markdig.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
129
img/markdig.svg
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="192"
|
||||
height="192"
|
||||
viewBox="0 0 192 192"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="markdig.svg"
|
||||
inkscape:export-filename="C:\code\lunet\markdig\img\markdig.png"
|
||||
inkscape:export-xdpi="256"
|
||||
inkscape:export-ydpi="256">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="6.275557"
|
||||
inkscape:cx="81.620292"
|
||||
inkscape:cy="119.68434"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2066"
|
||||
inkscape:window-x="-11"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
units="px" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
style="display:inline"
|
||||
transform="translate(0,-860.36216)">
|
||||
<path
|
||||
style="fill:#006680;fill-opacity:1;stroke-width:1.09204066"
|
||||
d="m 34.5307,873.24547 c -1.506145,1.5557 -2.414834,3.72567 -2.403331,6.22497 l 0.04173,27.41047 -19.903814,-0.0324 c -4.824408,-0.009 -8.4381391,3.7242 -8.4300642,8.70738 0.00817,4.98312 3.6330369,8.72727 8.4573232,8.73554 l 19.903821,0.0324 -0.275791,17.12991 124.244306,-0.42328 -0.0273,-17.44297 20.80798,-0.27883 c 2.4087,0.009 4.52205,-0.92824 6.02671,-2.48239 1.50614,-1.55569 2.41486,-3.72569 2.40336,-6.225 -0.009,-4.98311 -3.63306,-8.7273 -8.45733,-8.73554 l -20.50656,0.59015 0.25961,-27.09914 c -0.31244,-2.17456 -1.213,-4.36429 -3.02472,-6.23561 -1.50705,-1.55665 -3.62738,-2.49321 -6.03475,-2.50058 l -107.054134,0.14282 c -2.408688,-0.009 -4.522059,0.92823 -6.026707,2.48237 z m 27.829505,3.83665 14.459233,0.0217 14.488635,21.31347 14.429017,-21.27019 14.45922,0.0217 0.0811,57.91281 -14.4592,-0.0217 -0.0464,-33.21443 -14.428869,21.27005 -14.488819,-21.31366 0.04632,33.21458 -14.459226,-0.0218 -0.08116,-57.91275 z"
|
||||
id="path4142"
|
||||
inkscape:connector-curvature="0" />
|
||||
<rect
|
||||
id="rect4168"
|
||||
mask="url(#a)"
|
||||
ry="0"
|
||||
height="0"
|
||||
width="0"
|
||||
x="141.51523"
|
||||
y="364.10403" />
|
||||
<rect
|
||||
id="rect4184"
|
||||
mask="url(#a)"
|
||||
ry="0"
|
||||
height="0"
|
||||
width="0"
|
||||
x="96.108383"
|
||||
y="352.01443" />
|
||||
<rect
|
||||
id="rect4200"
|
||||
mask="url(#a)"
|
||||
ry="2.1886277"
|
||||
height="0.14590852"
|
||||
width="0.17464182"
|
||||
x="87.014519"
|
||||
y="276.38696" />
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot4797"
|
||||
style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
transform="matrix(0.1746417,0,0,0.1459084,499.69318,366.39614)"><flowRegion
|
||||
id="flowRegion4799"><rect
|
||||
id="rect4801"
|
||||
width="972.27185"
|
||||
height="618.71844"
|
||||
x="959.01355"
|
||||
y="-976.15039" /></flowRegion><flowPara
|
||||
id="flowPara4803"
|
||||
style="font-size:40px;line-height:1.25"> </flowPara></flowRoot> <g
|
||||
id="g4833"
|
||||
transform="matrix(0.09510056,0,0,0.09061765,496.09965,368.83934)">
|
||||
<rect
|
||||
id="rect4823"
|
||||
height="1"
|
||||
width="1"
|
||||
x="0"
|
||||
y="0"
|
||||
style="fill:#ffffff" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(234.63786,787.55486)"
|
||||
id="g4170" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path826"
|
||||
d="m 45.058494,943.54749 20.013843,88.87081 c -8.87e-4,1.4793 13.909884,7.9857 28.77803,7.9868 14.868153,0 27.732473,-6.0454 27.727033,-7.5199 l 17.1004,-89.73688 z m 35.561125,8.36596 h 25.853221 l 10e-6,42.86491 h 13.18189 l -26.108514,40.41734 -26.324515,-40.20925 13.397908,-0.20809 z"
|
||||
style="fill:#ff6600;stroke-width:1.2582258" />
|
||||
<path
|
||||
style="fill:#c83737;stroke-width:1.2582258"
|
||||
d="m 45.058494,943.54749 20.013843,88.87081 c -8.87e-4,1.4793 13.909884,7.9857 28.77803,7.9868 14.868153,0 27.732473,-6.0454 27.727033,-7.5199 l 17.1004,-89.73688 z m 35.561125,8.36596 h 25.853221 l 10e-6,42.86491 h 13.18189 l -26.108514,40.41734 -26.324515,-40.20925 13.397908,-0.20809 z"
|
||||
id="path828"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
BIN
img/markdig128.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
img/markdig64.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2016, Alexandre Mutel
|
||||
Copyright (c) 2018-2019, Alexandre Mutel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification
|
||||
|
||||
188
readme.md
@@ -1,55 +1,83 @@
|
||||
# Markdig [](https://ci.appveyor.com/project/xoofx/markdig) [](https://www.nuget.org/packages/Markdig/)
|
||||
# Markdig [](https://github.com/lunet-io/markdig/actions) [](https://coveralls.io/github/xoofx/markdig?branch=master) [](https://www.nuget.org/packages/Markdig/) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FRGHXBTP442JL)
|
||||
|
||||
<img align="right" width="128px" height="128px" src="images/markdig.png">
|
||||
<img align="right" width="160px" height="160px" src="img/markdig.png">
|
||||
|
||||
Markdig is a fast, powerfull, [CommonMark](http://commonmark.org/) compliant, extensible Markdown processor for .NET.
|
||||
Markdig is a fast, powerful, [CommonMark](http://commonmark.org/) compliant, extensible Markdown processor for .NET.
|
||||
|
||||
> NOTE: The repository is under construction. There will be a dedicated website and proper documentation at some point!
|
||||
|
||||
You can **try Markdig online** and compare it to other implems on [babelmark3](http://babelmark.github.io/)
|
||||
You can **try Markdig online** and compare it to other implementations on [babelmark3](https://babelmark.github.io/?text=Hello+**Markdig**!)
|
||||
|
||||
## Features
|
||||
|
||||
- **Very fast parser** (no-regexp), very lightweight in terms of GC pressure. See benchmarks
|
||||
- **Abstract Syntax Tree**
|
||||
- **Very fast parser and html renderer** (no-regexp), very lightweight in terms of GC pressure. See benchmarks
|
||||
- **Abstract Syntax Tree** with precise source code location for syntax tree, useful when building a Markdown editor.
|
||||
- Checkout [MarkdownEditor for Visual Studio](https://visualstudiogallery.msdn.microsoft.com/eaab33c3-437b-4918-8354-872dfe5d1bfe) powered by Markdig!
|
||||
- Converter to **HTML**
|
||||
- Passing more than **600+ tests** from the latest [CommonMark specs](http://spec.commonmark.org/)
|
||||
- Passing more than **600+ tests** from the latest [CommonMark specs (0.29)](http://spec.commonmark.org/)
|
||||
- Includes all the core elements of CommonMark:
|
||||
- including GFM fenced code blocks.
|
||||
- including **GFM fenced code blocks**.
|
||||
- **Extensible** architecture
|
||||
- Even the core Markdown/CommonMark parsing is pluggable, so it allows to disable builtin Markdown/Commonmark parsing (e.g [Disable HTML parsing](https://github.com/lunet-io/markdig/blob/7964bd0160d4c18e4155127a4c863d61ebd8944a/src/Markdig/MarkdownExtensions.cs#L306)) or change behaviour (e.g change matching `#` of a headers with `@`)
|
||||
- Built-in with **18+ extensions**, including:
|
||||
- [**Roundtrip support**](./src/Markdig/Roundtrip.md): Parses trivia (whitespace, newlines and other characters) to support lossless parse ⭢ render roundtrip. This enables changing markdown documents without introducing undesired trivia changes.
|
||||
- Built-in with **20+ extensions**, including:
|
||||
- 2 kind of tables:
|
||||
- **Pipe tables** (inspired from Github tables and [PanDoc - Pipe Tables](http://pandoc.org/README.html#extension-pipe_tables))
|
||||
- **Grid tables** (inspired from [Pandoc - Grid Tables](http://pandoc.org/README.html#extension-grid_tables))
|
||||
- **Extra emphasis** (inspired from [Pandoc - Emphasis](http://pandoc.org/README.html#strikeout) and [Markdown-it](https://markdown-it.github.io/))
|
||||
- [**Pipe tables**](src/Markdig.Tests/Specs/PipeTableSpecs.md) (inspired from GitHub tables and [PanDoc - Pipe Tables](http://pandoc.org/README.html#extension-pipe_tables))
|
||||
- [**Grid tables**](src/Markdig.Tests/Specs/GridTableSpecs.md) (inspired from [Pandoc - Grid Tables](http://pandoc.org/README.html#extension-grid_tables))
|
||||
- [**Extra emphasis**](src/Markdig.Tests/Specs/EmphasisExtraSpecs.md) (inspired from [Pandoc - Emphasis](http://pandoc.org/README.html#strikeout) and [Markdown-it](https://markdown-it.github.io/))
|
||||
- strike through `~~`,
|
||||
- Subscript `~`
|
||||
- Superscript `^`
|
||||
- Inserted `++`
|
||||
- Marked `==`
|
||||
- **Special attributes** or attached HTML attributes (inspired from [PHP Markdown Extra - Special Attributes](https://michelf.ca/projects/php-markdown/extra/#spe-attr))
|
||||
- **Definition lists** (inspired from [PHP Markdown Extra - Definitions Lists](https://michelf.ca/projects/php-markdown/extra/#def-list))
|
||||
- **Footnotes** (inspired from [PHP Markdown Extra - Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes))
|
||||
- **Auto-identifiers** for headings (similar to [Pandoc - Auto Identifiers](http://pandoc.org/README.html#extension-auto_identifiers))
|
||||
- **Extra bullet lists**, supporting alpha bullet `a.` `b.` and roman bullet (`i`, `ii`...etc.)
|
||||
- **Media support** for media url (youtube, vimeo, mp4...etc.) (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/embedded-audio-and-video/441))
|
||||
- **Abbreviations** (inspired from [PHP Markdown Extra - Abbreviations](https://michelf.ca/projects/php-markdown/extra/#abbr))
|
||||
- **Citation** text by enclosing `""...""` (inspired by this [CommonMark discussion ](https://talk.commonmark.org/t/referencing-creative-works-with-cite/892))
|
||||
- **Custom containers** similar to fenced code block `:::` for generating a proper `<div>...</div>` instead (inspired by this [CommonMark discussion ](https://talk.commonmark.org/t/custom-container-for-block-and-inline/2051))
|
||||
- **Figures** (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/image-tag-should-expand-to-figure-when-used-with-title/265/5))
|
||||
- **Footers** (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/syntax-for-footer/2070))
|
||||
- **Mathematics**/Latex extension by enclosing `$$` for block and `$` for inline math (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/mathematics-extension/457/31))
|
||||
- **Soft lines as hard lines**
|
||||
- **Emoji** support (inspired from [Markdown-it](https://markdown-it.github.io/))
|
||||
- **SmartyPants** (inspired from [Daring Fireball - SmartyPants](https://daringfireball.net/projects/smartypants/))
|
||||
- **Bootstrap** class (to output bootstrap class)
|
||||
- Compatible with .NET 3.5, 4.0+ and .NET Core (`netstandard1.1+`)
|
||||
- [**Special attributes**](src/Markdig.Tests/Specs/GenericAttributesSpecs.md) or attached HTML attributes (inspired from [PHP Markdown Extra - Special Attributes](https://michelf.ca/projects/php-markdown/extra/#spe-attr))
|
||||
- [**Definition lists**](src/Markdig.Tests/Specs/DefinitionListSpecs.md) (inspired from [PHP Markdown Extra - Definitions Lists](https://michelf.ca/projects/php-markdown/extra/#def-list))
|
||||
- [**Footnotes**](src/Markdig.Tests/Specs/FootnotesSpecs.md) (inspired from [PHP Markdown Extra - Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes))
|
||||
- [**Auto-identifiers**](src/Markdig.Tests/Specs/AutoIdentifierSpecs.md) for headings (similar to [Pandoc - Auto Identifiers](http://pandoc.org/README.html#extension-auto_identifiers))
|
||||
- [**Auto-links**](src/Markdig.Tests/Specs/AutoLinks.md) generates links if a text starts with `http://` or `https://` or `ftp://` or `mailto:` or `www.xxx.yyy`
|
||||
- [**Task Lists**](src/Markdig.Tests/Specs/TaskListSpecs.md) inspired from [Github Task lists](https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments).
|
||||
- [**Extra bullet lists**](src/Markdig.Tests/Specs/ListExtraSpecs.md), supporting alpha bullet `a.` `b.` and roman bullet (`i`, `ii`...etc.)
|
||||
- [**Media support**](src/Markdig.Tests/Specs/MediaSpecs.md) for media url (youtube, vimeo, mp4...etc.) (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/embedded-audio-and-video/441))
|
||||
- [**Abbreviations**](src/Markdig.Tests/Specs/AbbreviationSpecs.md) (inspired from [PHP Markdown Extra - Abbreviations](https://michelf.ca/projects/php-markdown/extra/#abbr))
|
||||
- [**Citation**](src/Markdig.Tests/Specs/FigureFooterAndCiteSpecs.md) text by enclosing `""...""` (inspired by this [CommonMark discussion ](https://talk.commonmark.org/t/referencing-creative-works-with-cite/892))
|
||||
- [**Custom containers**](src/Markdig.Tests/Specs/CustomContainerSpecs.md) similar to fenced code block `:::` for generating a proper `<div>...</div>` instead (inspired by this [CommonMark discussion ](https://talk.commonmark.org/t/custom-container-for-block-and-inline/2051))
|
||||
- [**Figures**](src/Markdig.Tests/Specs/FigureFooterAndCiteSpecs.md) (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/image-tag-should-expand-to-figure-when-used-with-title/265/5))
|
||||
- [**Footers**](src/Markdig.Tests/Specs/FigureFooterAndCiteSpecs.md) (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/syntax-for-footer/2070))
|
||||
- [**Mathematics**](src/Markdig.Tests/Specs/MathSpecs.md)/Latex extension by enclosing `$$` for block and `$` for inline math (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/mathematics-extension/457/31))
|
||||
- [**Soft lines as hard lines**](src/Markdig.Tests/Specs/HardlineBreakSpecs.md)
|
||||
- [**Emoji**](src/Markdig.Tests/Specs/EmojiSpecs.md) support (inspired from [Markdown-it](https://markdown-it.github.io/))
|
||||
- [**SmartyPants**](src/Markdig.Tests/Specs/SmartyPantsSpecs.md) (inspired from [Daring Fireball - SmartyPants](https://daringfireball.net/projects/smartypants/))
|
||||
- [**Bootstrap**](src/Markdig.Tests/Specs/BootstrapSpecs.md) class (to output bootstrap class)
|
||||
- [**Diagrams**](src/Markdig.Tests/Specs/DiagramsSpecs.md) extension whenever a fenced code block contains a special keyword, it will be converted to a div block with the content as-is (currently, supports [`mermaid`](https://knsv.github.io/mermaid/) and [`nomnoml`](https://github.com/skanaar/nomnoml) diagrams)
|
||||
- [**YAML Front Matter**](src/Markdig.Tests/Specs/YamlSpecs.md) to parse without evaluating the front matter and to discard it from the HTML output (typically used for previewing without the front matter in MarkdownEditor)
|
||||
- [**JIRA links**](src/Markdig.Tests/Specs/JiraLinks.md) to automatically generate links for JIRA project references (Thanks to @clarkd: https://github.com/clarkd/MarkdigJiraLinker)
|
||||
- Starting with Markdig version `0.20.0+`, Markdig is compatible only with `NETStandard 2.0`, `NETStandard 2.1`, `NETCoreApp 2.1` and `NETCoreApp 3.1`.
|
||||
|
||||
If you are looking for support for an old .NET Framework 3.5 or 4.0, you can download Markdig `0.18.3`.
|
||||
|
||||
### Third Party Extensions
|
||||
|
||||
- [**WPF/XAML Markdown Renderer**: `markdig.wpf`](https://github.com/Kryptos-FR/markdig.wpf)
|
||||
- [**WPF/XAML Markdown Renderer**: `Neo.Markdig.Xaml`](https://github.com/neolithos/NeoMarkdigXaml)
|
||||
- [**Syntax highlighting**: `Markdig.SyntaxHighlighting`](https://github.com/RichardSlater/Markdig.SyntaxHighlighting)
|
||||
- [**Syntax highlighting using ColorCode-Universal**: `Markdown.ColorCode`](https://github.com/wbaldoumas/markdown-colorcode)
|
||||
- [**Syntax highlighting using Prism.js**: `WebStoating.Markdig.Prism`](https://github.com/ilich/Markdig.Prism)
|
||||
- [**Embedded C# scripting**: `Markdig.Extensions.ScriptCs`](https://github.com/macaba/Markdig.Extensions.ScriptCs)
|
||||
|
||||
## Documentation
|
||||
|
||||
> The repository is under construction. There will be a dedicated website and proper documentation at some point!
|
||||
|
||||
While there is not yet a dedicated documentation, you can find from the [specs documentation](src/Markdig.Tests/Specs/readme.md) how to use these extensions.
|
||||
|
||||
In the meantime, you can have a "behind the scene" article about Markdig in my blog post ["Implementing a Markdown Engine for .NET"](http://xoofx.com/blog/2016/06/13/implementing-a-markdown-processor-for-dotnet/)
|
||||
|
||||
## Download
|
||||
|
||||
Markdig is available as a NuGet package: [](https://www.nuget.org/packages/Markdig/)
|
||||
|
||||
Also [Markdig.Signed](https://www.nuget.org/packages/Markdig.Signed/) NuGet package provides signed assemblies.
|
||||
|
||||
## Usage
|
||||
|
||||
The main entry point for the API is the `Markdig.Markdown` class:
|
||||
@@ -61,7 +89,7 @@ var result = Markdown.ToHtml("This is a text with some *emphasis*");
|
||||
Console.WriteLine(result); // prints: <p>This is a text with some <em>emphasis</em></p>
|
||||
```
|
||||
|
||||
In order to activate most of all advanced extensions (except Emoji, SoftLine as HarLine and SmartyPants)
|
||||
In order to activate most of all advanced extensions (except Emoji, SoftLine as HardLine, Bootstrap, YAML Front Matter, JiraLinks and SmartyPants)
|
||||
|
||||
```csharp
|
||||
// Configure the pipeline with all advanced extensions active
|
||||
@@ -69,8 +97,14 @@ var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
|
||||
var result = Markdown.ToHtml("This is a text with some *emphasis*", pipeline);
|
||||
```
|
||||
|
||||
[Try it online!](https://dotnetfiddle.net/GoZXyI)
|
||||
|
||||
You can have a look at the [MarkdownExtensions](https://github.com/lunet-io/markdig/blob/master/src/Markdig/MarkdownExtensions.cs) that describes all actionable extensions (by modifying the MarkdownPipeline)
|
||||
|
||||
## Build
|
||||
|
||||
In order to build Markdig, you need to install [.NET Core RTM](https://www.microsoft.com/net/core)
|
||||
|
||||
## License
|
||||
|
||||
This software is released under the [BSD-Clause 2 license](https://github.com/lunet-io/markdig/blob/master/license.txt).
|
||||
@@ -80,24 +114,40 @@ This software is released under the [BSD-Clause 2 license](https://github.com/lu
|
||||
|
||||
This is an early preview of the benchmarking against various implementations:
|
||||
|
||||
- Markdig: itself
|
||||
- CommonMarkCpp: [cmark](https://github.com/jgm/cmark), Reference C implementation of CommonMark, no support for extensions
|
||||
- [CommonMark.NET](https://github.com/Knagis/CommonMark.NET): CommonMark implementation for .NET, no support for extensions, port of cmark
|
||||
- [CommonMarkNet (devel)](https://github.com/AMDL/CommonMark.NET/tree/pipe-tables): An evolution of CommonMark.NET, supports extensions, not released yet
|
||||
- [MarkdownDeep](https://github.com/toptensoftware/markdowndeep) another .NET implementation
|
||||
- [MarkdownSharp](https://github.com/Kiri-rin/markdownsharp): Open source C# implementation of Markdown processor, as featured on Stack Overflow, regexp based.
|
||||
- [Moonshine](https://github.com/brandonc/moonshine): popular C Markdown processor
|
||||
**C implementations**:
|
||||
|
||||
Markdig is roughly x100 times faster than MarkdownSharp and extremelly competitive to other implems (that are not feature wise comparable)
|
||||
- [cmark](https://github.com/jgm/cmark) (version: 0.25.0): Reference C implementation of CommonMark, no support for extensions
|
||||
- [Moonshine](https://github.com/brandonc/moonshine) (version: : popular C Markdown processor
|
||||
|
||||
Performance in x86:
|
||||
**.NET implementations**:
|
||||
|
||||
- [Markdig](https://github.com/lunet-io/markdig) (version: 0.5.x): itself
|
||||
- [CommonMark.NET(master)](https://github.com/Knagis/CommonMark.NET) (version: 0.11.0): CommonMark implementation for .NET, no support for extensions, port of cmark
|
||||
- [CommonMark.NET(pipe_tables)](https://github.com/AMDL/CommonMark.NET/tree/pipe-tables): An evolution of CommonMark.NET, supports extensions, not released yet
|
||||
- [MarkdownDeep](https://github.com/toptensoftware/markdowndeep) (version: 1.5.0): another .NET implementation
|
||||
- [MarkdownSharp](https://github.com/Kiri-rin/markdownsharp) (version: 1.13.0): Open source C# implementation of Markdown processor, as featured on Stack Overflow, regexp based.
|
||||
- [Marked.NET](https://github.com/T-Alex/MarkedNet) (version: 1.0.5) port of original [marked.js](https://github.com/chjj/marked) project
|
||||
- [Microsoft.DocAsCode.MarkdownLite](https://github.com/dotnet/docfx/tree/dev/src/Microsoft.DocAsCode.MarkdownLite) (version: 2.0.1) used by the [docfx](https://github.com/dotnet/docfx) project
|
||||
|
||||
### Analysis of the results:
|
||||
|
||||
- Markdig is roughly **x100 times faster than MarkdownSharp**, **30x times faster than docfx**
|
||||
- **Among the best in CPU**, Extremely competitive and often faster than other implementations (not feature wise equivalent)
|
||||
- **15% to 30% less allocations** and GC pressure
|
||||
|
||||
Because Marked.NET, MarkdownSharp and DocAsCode.MarkdownLite are way too slow, they are not included in the following charts:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
### Performance for x86:
|
||||
|
||||
```
|
||||
// * Summary *
|
||||
|
||||
BenchmarkDotNet-Dev=v0.9.6.0+
|
||||
BenchmarkDotNet-Dev=v0.9.7.0+
|
||||
OS=Microsoft Windows NT 6.2.9200.0
|
||||
Processor=Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, ProcessorCount=8
|
||||
Processor=Intel(R) Core(TM) i7-4770 CPU 3.40GHz, ProcessorCount=8
|
||||
Frequency=3319351 ticks, Resolution=301.2637 ns, Timer=TSC
|
||||
HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE
|
||||
JitModules=clrjit-v4.6.1080.0
|
||||
@@ -105,26 +155,22 @@ JitModules=clrjit-v4.6.1080.0
|
||||
Type=Program Mode=SingleRun LaunchCount=2
|
||||
WarmupCount=2 TargetCount=10
|
||||
|
||||
Method | Median | StdDev | Gen 0 | Gen 1 | Gen 2 | Bytes Allocated/Op |
|
||||
--------------------- |---------- |---------- |------- |------ |------- |------------------- |
|
||||
TestMarkdig | 5.4870 ms | 0.0158 ms | 193.00 | 12.00 | 84.00 | 1,425,192.72 |
|
||||
TestCommonMarkCpp | 4.0134 ms | 0.1008 ms | - | - | 180.00 | 454,859.74 |
|
||||
TestCommonMarkNet | 4.6139 ms | 0.0581 ms | 193.00 | 12.00 | 84.00 | 1,406,367.27 |
|
||||
TestCommonMarkNetNew | 5.5327 ms | 0.0461 ms | 193.00 | 96.00 | 84.00 | 1,738,465.42 |
|
||||
TestMarkdownDeep | 7.5910 ms | 0.1006 ms | 205.00 | 96.00 | 84.00 | 1,758,383.79 |
|
||||
TestMoonshine | 5.8843 ms | 0.1758 ms | - | - | 215.00 | 565,000.73 |
|
||||
|
||||
// * Diagnostic Output - MemoryDiagnoser *
|
||||
|
||||
|
||||
// ***** BenchmarkRunner: End *****
|
||||
Method | Median | StdDev |Scaled | Gen 0 | Gen 1| Gen 2|Bytes Allocated/Op |
|
||||
--------------------------- |------------ |---------- |------ | ------ |------|---------|------------------ |
|
||||
Markdig | 5.5316 ms | 0.0372 ms | 0.71 | 56.00| 21.00| 49.00| 1,285,917.31 |
|
||||
CommonMark.NET(master) | 4.7035 ms | 0.0422 ms | 0.60 | 113.00| 7.00| 49.00| 1,502,404.60 |
|
||||
CommonMark.NET(pipe_tables) | 5.6164 ms | 0.0298 ms | 0.72 | 111.00| 56.00| 49.00| 1,863,128.13 |
|
||||
MarkdownDeep | 7.8193 ms | 0.0334 ms | 1.00 | 120.00| 56.00| 49.00| 1,884,854.85 |
|
||||
cmark | 4.2698 ms | 0.1526 ms | 0.55 | -| -| -| NA |
|
||||
Moonshine | 6.0929 ms | 0.1053 ms | 1.28 | -| -| -| NA |
|
||||
Marked.NET | 207.3169 ms | 5.2628 ms | 26.51 | 0.00| 0.00| 0.00| 303,125,228.65 |
|
||||
MarkdownSharp | 675.0185 ms | 2.8447 ms | 86.32 | 40.00| 27.00| 41.00| 2,413,394.17 |
|
||||
Microsoft DocfxMarkdownLite | 166.3357 ms | 0.4529 ms | 21.27 |4,452.00|948.00|11,167.00| 180,218,359.60 |
|
||||
```
|
||||
|
||||
Performance for x64:
|
||||
### Performance for x64:
|
||||
|
||||
```
|
||||
// * Summary *
|
||||
|
||||
BenchmarkDotNet-Dev=v0.9.6.0+
|
||||
OS=Microsoft Windows NT 6.2.9200.0
|
||||
Processor=Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, ProcessorCount=8
|
||||
@@ -137,25 +183,29 @@ WarmupCount=2 TargetCount=10
|
||||
|
||||
Method | Median | StdDev | Gen 0 | Gen 1 | Gen 2 | Bytes Allocated/Op |
|
||||
--------------------- |---------- |---------- |------- |------- |------ |------------------- |
|
||||
TestMarkdig | 5.9539 ms | 0.0495 ms | 157.00 | 96.00 | 84.00 | 1,767,834.52 |
|
||||
TestCommonMarkNet | 4.3158 ms | 0.0161 ms | 157.00 | 96.00 | 84.00 | 1,747,432.06 |
|
||||
TestCommonMarkNetNew | 5.3421 ms | 0.0435 ms | 229.00 | 168.00 | 84.00 | 2,323,922.97 |
|
||||
TestMarkdownDeep | 7.4750 ms | 0.0281 ms | 318.00 | 186.00 | 84.00 | 2,576,728.69 |
|
||||
|
||||
// * Diagnostic Output - MemoryDiagnoser *
|
||||
|
||||
|
||||
// ***** BenchmarkRunner: End *****
|
||||
TestMarkdig | 5.5276 ms | 0.0402 ms | 109.00 | 96.00 | 84.00 | 1,537,027.66 |
|
||||
TestCommonMarkNet | 4.4661 ms | 0.1190 ms | 157.00 | 96.00 | 84.00 | 1,747,432.06 |
|
||||
TestCommonMarkNetNew | 5.3151 ms | 0.0815 ms | 229.00 | 168.00 | 84.00 | 2,323,922.97 |
|
||||
TestMarkdownDeep | 7.4076 ms | 0.0617 ms | 318.00 | 186.00 | 84.00 | 2,576,728.69 |
|
||||
```
|
||||
|
||||
## Donate
|
||||
|
||||
If you are using this library and find it useful for your project, please consider a donation for it!
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FRGHXBTP442JL)
|
||||
|
||||
## Credits
|
||||
|
||||
Thanks to the fantastic work done by [John Mac Farlane](http://johnmacfarlane.net/) for the CommonMark specs and all the people involved in making Markdown a better standard!
|
||||
|
||||
This project would not have been possible without this huge foundation.
|
||||
|
||||
Thanks also to the project [BenchmarkDotNet](https://github.com/PerfDotNet/BenchmarkDotNet) that makes benchmarking so easy to setup!
|
||||
Thanks also to the project [BenchmarkDotNet](https://github.com/PerfDotNet/BenchmarkDotNet) that makes benchmarking so easy to setup!
|
||||
|
||||
Some decoding part (e.g HTML [EntityHelper.cs](https://github.com/lunet-io/markdig/blob/master/src/Markdig/Helpers/EntityHelper.cs)) have been re-used from [CommonMark.NET](https://github.com/Knagis/CommonMark.NET)
|
||||
|
||||
Thanks to the work done by @clarkd on the JIRA Link extension (https://github.com/clarkd/MarkdigJiraLinker), now included with this project!
|
||||
## Author
|
||||
|
||||
Alexandre MUTEL aka [xoofx](http://xoofx.com)
|
||||
|
||||
@@ -1,43 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{6A19F040-BC7C-4283-873A-177B5324F1ED}</ProjectGuid>
|
||||
<TargetFrameworks>net471</TargetFrameworks>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Markdig.Benchmarks</RootNamespace>
|
||||
<AssemblyName>Markdig.Benchmarks</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
<CopyNuGetImplementations>true</CopyNuGetImplementations>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="spec.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CommonMarkNew, Version=0.1.0.0, Culture=neutral, PublicKeyToken=001ef8810438905d, processorArchitecture=MSIL">
|
||||
<HintPath>lib\CommonMarkNew.dll</HintPath>
|
||||
@@ -45,31 +15,12 @@
|
||||
<Aliases>newcmark</Aliases>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Build" />
|
||||
<Reference Include="Microsoft.Build.Framework" />
|
||||
<Reference Include="Microsoft.Build.Utilities.v4.0" />
|
||||
<Reference Include="MoonShine">
|
||||
<HintPath>lib\MoonShine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MarkdownDeep">
|
||||
<HintPath>lib\MarkdownDeep.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CommonMarkLib.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TestMatchPerf.cs" />
|
||||
<Compile Include="TestStringPerf.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="cmark.dll">
|
||||
@@ -83,21 +34,16 @@
|
||||
<Content Include="spec.md">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="app.config" />
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Markdig">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Markdig\Bin\$(Configuration)\net40\Markdig.dll</HintPath>
|
||||
</Reference>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
|
||||
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.1" />
|
||||
<PackageReference Include="CommonMark.NET" Version="0.15.1" />
|
||||
<PackageReference Include="MarkdownSharp" Version="2.0.5" />
|
||||
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="2.0.226801" />
|
||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.74" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Markdig\Markdig.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(NuGetPackageRoot)' == ''">
|
||||
<NuGetPackageRoot>$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
</PropertyGroup>
|
||||
<ImportGroup>
|
||||
<Import Project="$(NuGetPackageRoot)\Microsoft.Diagnostics.Tracing.TraceEvent\1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets" Condition="Exists('$(NuGetPackageRoot)\Microsoft.Diagnostics.Tracing.TraceEvent\1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -5,14 +5,9 @@ extern alias newcmark;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Diagnostics;
|
||||
using BenchmarkDotNet.Diagnostics.Windows;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Running;
|
||||
using newcmark::CommonMark.Extension;
|
||||
using Markdig;
|
||||
|
||||
|
||||
@@ -55,7 +50,7 @@ namespace Testamina.Markdig.Benchmarks
|
||||
//CommonMark.CommonMarkConverter.Parse(reader);
|
||||
//reader.Dispose();
|
||||
//var writer = new StringWriter();
|
||||
global::CommonMark.CommonMarkConverter.Convert(text);
|
||||
CommonMark.CommonMarkConverter.Convert(text);
|
||||
//writer.Flush();
|
||||
//writer.ToString();
|
||||
}
|
||||
@@ -131,7 +126,7 @@ namespace Testamina.Markdig.Benchmarks
|
||||
var config = ManualConfig.Create(DefaultConfig.Instance);
|
||||
//var gcDiagnoser = new MemoryDiagnoser();
|
||||
//config.Add(new Job { Mode = Mode.SingleRun, LaunchCount = 2, WarmupCount = 2, IterationTime = 1024, TargetCount = 10 });
|
||||
config.Add(new Job { Mode = Mode.Throughput, LaunchCount = 2, WarmupCount = 2, TargetCount = 10 });
|
||||
//config.Add(new Job { Mode = Mode.Throughput, LaunchCount = 2, WarmupCount = 2, TargetCount = 10 });
|
||||
//config.Add(gcDiagnoser);
|
||||
|
||||
//var config = DefaultConfig.Instance;
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Testamina.Markdig.Benchmarks")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Testamina.Markdig.Benchmarks")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("6a19f040-bc7c-4283-873a-177b5324f1ed")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"profiles": {
|
||||
"CLASSIC": {
|
||||
"executablePath": "Testamina.Markdig.Benchmarks.dll",
|
||||
"workingDirectory": "..\\..\\artifacts\\bin\\Testamina.Markdig.Benchmarks\\Debug\\net45"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,10 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// This file is licensed under the BSD-Clause 2 license.
|
||||
// See the license.txt file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Markdig.Helpers;
|
||||
|
||||
namespace Testamina.Markdig.Benchmarks
|
||||
{
|
||||
@@ -52,7 +48,7 @@ namespace Testamina.Markdig.Benchmarks
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public class TestMatchPerf
|
||||
{
|
||||
private readonly TextMatchHelper matcher;
|
||||
@@ -82,4 +78,5 @@ namespace Testamina.Markdig.Benchmarks
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/></startup></configuration>
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"runtimes": {
|
||||
"win-x86": {},
|
||||
"win-x64": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net451": {
|
||||
"compilationOptions": {
|
||||
"define": [
|
||||
"CLASSIC"
|
||||
]
|
||||
},
|
||||
"frameworkAssemblies": {
|
||||
"Microsoft.Build": "4.0.0.0",
|
||||
"Microsoft.Build.Framework": "4.0.0.0",
|
||||
"Microsoft.Build.Utilities.v4.0": "4.0.0.0",
|
||||
"System.Management": "4.0.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"BenchmarkDotNet": "0.9.6",
|
||||
"BenchmarkDotNet.Diagnostics.Windows": "0.9.6",
|
||||
"CommonMark.NET": "0.11.0",
|
||||
"MarkdownSharp": "1.13.0.0",
|
||||
"Microsoft.Diagnostics.Runtime": "0.8.31-beta",
|
||||
"Microsoft.Diagnostics.Tracing.TraceEvent": "1.0.41.0"
|
||||
}
|
||||
}
|
||||
@@ -5397,7 +5397,7 @@ foo
|
||||
## Entity and numeric character references
|
||||
|
||||
All valid HTML entity references and numeric character
|
||||
references, except those occuring in code blocks and code spans,
|
||||
references, except those occurring in code blocks and code spans,
|
||||
are recognized as such and treated as equivalent to the
|
||||
corresponding Unicode characters. Conforming CommonMark parsers
|
||||
need not store information about whether a particular character
|
||||
|
||||
13
src/Markdig.Signed/Markdig.Signed.csproj
Normal file
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<PackageId>Markdig.Signed</PackageId>
|
||||
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Markdig\**\*.cs" Exclude="..\Markdig\obj\**;..\Markdig\bin\**">
|
||||
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="..\Markdig\Markdig.targets" />
|
||||
</Project>
|
||||
BIN
src/Markdig.Signed/key.snk
Normal file
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
BIN
src/Markdig.Tests/ArgumentOutOfRangeException.md
Normal file
@@ -1,107 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{A0C5CB5F-5568-40AB-B945-D6D2664D51B0}</ProjectGuid>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Markdig.Tests</RootNamespace>
|
||||
<AssemblyName>Markdig.Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<CopyNuGetImplementations>true</CopyNuGetImplementations>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
<IsPackable>false</IsPackable>
|
||||
<StartupObject>Markdig.Tests.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Markdig">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Markdig\Bin\$(Configuration)\net40\Markdig.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<PackageReference Include="coverlet.msbuild" Version="3.1.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Specs\Specs.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Specs.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="TestHtmlHelper.cs" />
|
||||
<Compile Include="TestLinkHelper.cs" />
|
||||
<Compile Include="TestStringSliceList.cs" />
|
||||
<Compile Include="TestPlayParser.cs" />
|
||||
<Compile Include="TextAssert.cs" />
|
||||
<Compile Include="TestParser.cs" />
|
||||
<ProjectReference Include="..\Markdig\Markdig.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="project.json" />
|
||||
<None Include="Specs\AutoIdentifierSpecs.md" />
|
||||
<None Include="Specs\AbbreviationSpecs.md" />
|
||||
<None Include="Specs\FigureFooterAndCiteSpecs.md" />
|
||||
<None Include="Specs\ListExtraSpecs.md" />
|
||||
<None Include="Specs\GenericAttributesSpecs.md" />
|
||||
<None Include="Specs\CustomContainerSpecs.md" />
|
||||
<None Include="Specs\DefinitionListSpecs.md" />
|
||||
<None Include="Specs\EmojiSpecs.md" />
|
||||
<None Include="Specs\FootnotesSpecs.md" />
|
||||
<None Include="Specs\GridTableSpecs.md" />
|
||||
<None Include="Specs\HardlineBreakSpecs.md" />
|
||||
<None Include="Specs\BootstrapSpecs.md" />
|
||||
<None Include="Specs\SmartyPantsSpecs.md" />
|
||||
<None Include="Specs\MediaSpecs.md" />
|
||||
<None Include="Specs\MathSpecs.md" />
|
||||
<None Include="Specs\PipeTableSpecs.md" />
|
||||
<None Include="Specs\EmphasisExtraSpecs.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Specs\Specs.tt">
|
||||
<Generator>TextTemplatingFileGenerator</Generator>
|
||||
<LastGenOutput>Specs.cs</LastGenOutput>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
|
||||
</Project>
|
||||
288
src/Markdig.Tests/MiscTests.cs
Normal file
@@ -0,0 +1,288 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Markdig.Extensions.AutoLinks;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests
|
||||
{
|
||||
public class MiscTests
|
||||
{
|
||||
[Test]
|
||||
public void LinkWithInvalidNonAsciiDomainNameIsIgnored()
|
||||
{
|
||||
// Url from https://github.com/lunet-io/markdig/issues/438
|
||||
_ = Markdown.ToHtml("[minulém díle](http://V%20minulém%20díle%20jsme%20nainstalovali%20SQL%20Server,%20který%20je%20nutný%20pro%20běh%20Configuration%20Manageru.%20Dnes%20nás%20čeká%20instalace%20WSUS,%20což%20je%20produkt,%20jež%20je%20možné%20používat%20i%20jako%20samostatnou%20funkci%20ve%20Windows%20Serveru,%20který%20se%20stará%20o%20stažení%20a%20instalaci%20aktualizací%20z%20Microsoft%20Update%20na%20klientské%20počítače.%20Stejně%20jako%20v%20předchozích%20dílech,%20tak%20i%20v%20tomto%20si%20ukážeme%20obě%20varianty%20instalace%20–%20a%20to%20jak%20instalaci%20z%20PowerShellu,%20tak%20instalaci%20pomocí%20GUI.) ");
|
||||
|
||||
// Valid IDN
|
||||
TestParser.TestSpec("[foo](http://ünicode.com)", "<p><a href=\"http://xn--nicode-2ya.com\">foo</a></p>");
|
||||
TestParser.TestSpec("[foo](http://ünicode.ünicode.com)", "<p><a href=\"http://xn--nicode-2ya.xn--nicode-2ya.com\">foo</a></p>");
|
||||
|
||||
// Invalid IDN
|
||||
TestParser.TestSpec("[foo](http://ünicode..com)", "<p><a href=\"http://%C3%BCnicode..com\">foo</a></p>");
|
||||
}
|
||||
|
||||
[TestCase("link [foo [bar]]")] // https://spec.commonmark.org/0.29/#example-508
|
||||
[TestCase("link [foo][bar]")]
|
||||
[TestCase("link [][foo][bar][]")]
|
||||
[TestCase("link [][foo][bar][[]]")]
|
||||
[TestCase("link [foo] [bar]")]
|
||||
[TestCase("link [[foo] [] [bar] [[abc]def]]")]
|
||||
[TestCase("[]")]
|
||||
[TestCase("[ ]")]
|
||||
[TestCase("[bar][]")]
|
||||
[TestCase("[bar][ foo]")]
|
||||
[TestCase("[bar][foo ][]")]
|
||||
[TestCase("[bar][fo[ ]o ][][]")]
|
||||
[TestCase("[a]b[c[d[e]f]g]h")]
|
||||
[TestCase("a[b[c[d]e]f[g]h]i foo [j]k[l[m]n]o")]
|
||||
[TestCase("a[b[c[d]e]f[g]h]i[] [][foo][bar][] foo [j]k[l[m]n]o")]
|
||||
[TestCase("a[b[c[d]e]f[g]h]i foo [j]k[l[m]n]o[][]")]
|
||||
public void LinkTextMayContainBalancedBrackets(string linkText)
|
||||
{
|
||||
string markdown = $"[{linkText}](/uri)";
|
||||
string expected = $@"<p><a href=""/uri"">{linkText}</a></p>";
|
||||
|
||||
TestParser.TestSpec(markdown, expected);
|
||||
|
||||
// Make the link text unbalanced
|
||||
foreach (var bracketIndex in linkText
|
||||
.Select((c, i) => new Tuple<char, int>(c, i))
|
||||
.Where(t => t.Item1 == '[' || t.Item1 == ']')
|
||||
.Select(t => t.Item2))
|
||||
{
|
||||
string brokenLinkText = linkText.Remove(bracketIndex, 1);
|
||||
|
||||
markdown = $"[{brokenLinkText}](/uri)";
|
||||
expected = $@"<p><a href=""/uri"">{brokenLinkText}</a></p>";
|
||||
|
||||
string actual = Markdown.ToHtml(markdown);
|
||||
Assert.AreNotEqual(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[TestCase('[', 9 * 1024, true, false)]
|
||||
[TestCase('[', 11 * 1024, true, true)]
|
||||
[TestCase('[', 100, false, false)]
|
||||
[TestCase('[', 150, false, true)]
|
||||
[TestCase('>', 100, true, false)]
|
||||
[TestCase('>', 150, true, true)]
|
||||
public void GuardsAgainstHighlyNestedNodes(char c, int count, bool parseOnly, bool shouldThrow)
|
||||
{
|
||||
var markdown = new string(c, count);
|
||||
TestDelegate test = parseOnly ? () => Markdown.Parse(markdown) : () => Markdown.ToHtml(markdown);
|
||||
|
||||
if (shouldThrow)
|
||||
{
|
||||
Exception e = Assert.Throws<ArgumentException>(test);
|
||||
Assert.True(e.Message.Contains("depth limit"));
|
||||
}
|
||||
else
|
||||
{
|
||||
test();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsIssue356Corrected()
|
||||
{
|
||||
string input = @"https://foo.bar/path/\#m4mv5W0GYKZpGvfA.97";
|
||||
string expected = @"<p><a href=""https://foo.bar/path/%5C#m4mv5W0GYKZpGvfA.97"">https://foo.bar/path/\#m4mv5W0GYKZpGvfA.97</a></p>";
|
||||
|
||||
TestParser.TestSpec($"<{input}>", expected);
|
||||
TestParser.TestSpec(input, expected, "autolinks|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsIssue365Corrected()
|
||||
{
|
||||
// The scheme must be escaped too...
|
||||
string input = "";
|
||||
string expected = "<p><img src=\"%22onclick=%22alert&#40;%27click%27&#41;%22://\" alt=\"image\" /></p>";
|
||||
|
||||
TestParser.TestSpec(input, expected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAltTextIsCorrectlyEscaped()
|
||||
{
|
||||
TestParser.TestSpec(
|
||||
@"",
|
||||
@"<p><img src=""girl.png"" alt=""This is image alt text with quotation ' and double quotation "hello" world"" /></p>");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestChangelogPRLinksMatchDescription()
|
||||
{
|
||||
string solutionFolder = Path.GetFullPath(Path.Combine(TestParser.TestsDirectory, "../.."));
|
||||
string changelogPath = Path.Combine(solutionFolder, "changelog.md");
|
||||
string changelog = File.ReadAllText(changelogPath);
|
||||
var matches = Regex.Matches(changelog, @"\(\[\(PR #(\d+)\)\]\(.*?pull\/(\d+)\)\)");
|
||||
Assert.Greater(matches.Count, 0);
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
Assert.True(int.TryParse(match.Groups[1].Value, out int textNr));
|
||||
Assert.True(int.TryParse(match.Groups[2].Value, out int linkNr));
|
||||
Assert.AreEqual(textNr, linkNr);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFixHang()
|
||||
{
|
||||
var input = File.ReadAllText(Path.Combine(TestParser.TestsDirectory, "hang.md"));
|
||||
_ = Markdown.ToHtml(input);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInvalidHtmlEntity()
|
||||
{
|
||||
var input = "9&ddr;&*&ddr;&de<64><65>__";
|
||||
TestParser.TestSpec(input, "<p>9&ddr;&*&ddr;&de<64><65>__</p>");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInvalidCharacterHandling()
|
||||
{
|
||||
var input = File.ReadAllText(Path.Combine(TestParser.TestsDirectory, "ArgumentOutOfRangeException.md"));
|
||||
_ = Markdown.ToHtml(input);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInvalidCodeEscape()
|
||||
{
|
||||
var input = "```**Header** ";
|
||||
_ = Markdown.ToHtml(input);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEmphasisAndHtmlEntity()
|
||||
{
|
||||
var markdownText = "*Unlimited-Fun®*®";
|
||||
TestParser.TestSpec(markdownText, "<p><em>Unlimited-Fun®</em>®</p>");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestThematicInsideCodeBlockInsideList()
|
||||
{
|
||||
var input = @"1. In the :
|
||||
|
||||
```
|
||||
Id DisplayName Description
|
||||
-- ----------- -----------
|
||||
62375ab9-6b52-47ed-826b-58e47e0e304b Group.Unified ...
|
||||
```";
|
||||
TestParser.TestSpec(input, @"<ol>
|
||||
<li><p>In the :</p>
|
||||
<pre><code>Id DisplayName Description
|
||||
-- ----------- -----------
|
||||
62375ab9-6b52-47ed-826b-58e47e0e304b Group.Unified ...
|
||||
</code></pre></li>
|
||||
</ol>");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VisualizeMathExpressions()
|
||||
{
|
||||
string math = @"Math expressions
|
||||
|
||||
$\frac{n!}{k!(n-k)!} = \binom{n}{k}$
|
||||
|
||||
$$\frac{n!}{k!(n-k)!} = \binom{n}{k}$$
|
||||
|
||||
$$
|
||||
\frac{n!}{k!(n-k)!} = \binom{n}{k}
|
||||
$$
|
||||
|
||||
<div class=""math"">
|
||||
\begin{align}
|
||||
\sqrt{37} & = \sqrt{\frac{73^2-1}{12^2}} \\
|
||||
& = \sqrt{\frac{73^2}{12^2}\cdot\frac{73^2-1}{73^2}} \\
|
||||
& = \sqrt{\frac{73^2}{12^2}}\sqrt{\frac{73^2-1}{73^2}} \\
|
||||
& = \frac{73}{12}\sqrt{1 - \frac{1}{73^2}} \\
|
||||
& \approx \frac{73}{12}\left(1 - \frac{1}{2\cdot73^2}\right)
|
||||
\end{align}
|
||||
</div>
|
||||
";
|
||||
Console.WriteLine("Math Expressions:\n");
|
||||
|
||||
var pl = new MarkdownPipelineBuilder().UseMathematics().Build(); // UseEmphasisExtras(EmphasisExtraOptions.Subscript).Build()
|
||||
|
||||
|
||||
var html = Markdown.ToHtml(math, pl);
|
||||
Console.WriteLine(html);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InlineMathExpression()
|
||||
{
|
||||
string math = @"Math expressions
|
||||
|
||||
$\frac{n!}{k!(n-k)!} = \binom{n}{k}$
|
||||
";
|
||||
var pl = new MarkdownPipelineBuilder().UseMathematics().Build(); // UseEmphasisExtras(EmphasisExtraOptions.Subscript).Build()
|
||||
|
||||
var html = Markdown.ToHtml(math, pl);
|
||||
Console.WriteLine(html);
|
||||
|
||||
Assert.IsTrue(html.Contains("<p><span class=\"math\">\\("), "Leading bracket missing");
|
||||
Assert.IsTrue(html.Contains("\\)</span></p>"), "Trailing bracket missing");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BlockMathExpression()
|
||||
{
|
||||
string math = @"Math expressions
|
||||
|
||||
$$
|
||||
\frac{n!}{k!(n-k)!} = \binom{n}{k}
|
||||
$$
|
||||
";
|
||||
var pl = new MarkdownPipelineBuilder().UseMathematics().Build(); // UseEmphasisExtras(EmphasisExtraOptions.Subscript).Build()
|
||||
|
||||
var html = Markdown.ToHtml(math, pl);
|
||||
Console.WriteLine(html);
|
||||
|
||||
Assert.IsTrue(html.Contains("<div class=\"math\">\n\\["), "Leading bracket missing");
|
||||
Assert.IsTrue(html.Contains("\\]</div>"), "Trailing bracket missing");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanDisableParsingHeadings()
|
||||
{
|
||||
var noHeadingsPipeline = new MarkdownPipelineBuilder().DisableHeadings().Build();
|
||||
|
||||
TestParser.TestSpec("Foo\n===", "<h1>Foo</h1>");
|
||||
TestParser.TestSpec("Foo\n===", "<p>Foo\n===</p>", noHeadingsPipeline);
|
||||
|
||||
TestParser.TestSpec("# Heading 1", "<h1>Heading 1</h1>");
|
||||
TestParser.TestSpec("# Heading 1", "<p># Heading 1</p>", noHeadingsPipeline);
|
||||
|
||||
// Does not also disable link reference definitions
|
||||
TestParser.TestSpec("[Foo]\n\n[Foo]: bar", "<p><a href=\"bar\">Foo</a></p>");
|
||||
TestParser.TestSpec("[Foo]\n\n[Foo]: bar", "<p><a href=\"bar\">Foo</a></p>", noHeadingsPipeline);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanOpenAutoLinksInNewWindow()
|
||||
{
|
||||
var pipeline = new MarkdownPipelineBuilder().UseAutoLinks().Build();
|
||||
var newWindowPipeline = new MarkdownPipelineBuilder().UseAutoLinks(new AutoLinkOptions() { OpenInNewWindow = true }).Build();
|
||||
|
||||
TestParser.TestSpec("www.foo.bar", "<p><a href=\"http://www.foo.bar\">www.foo.bar</a></p>", pipeline);
|
||||
TestParser.TestSpec("www.foo.bar", "<p><a href=\"http://www.foo.bar\" target=\"_blank\">www.foo.bar</a></p>", newWindowPipeline);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanUseHttpsPrefixForWWWAutoLinks()
|
||||
{
|
||||
var pipeline = new MarkdownPipelineBuilder().UseAutoLinks().Build();
|
||||
var httpsPipeline = new MarkdownPipelineBuilder().UseAutoLinks(new AutoLinkOptions() { UseHttpsForWWWLinks = true }).Build();
|
||||
|
||||
TestParser.TestSpec("www.foo.bar", "<p><a href=\"http://www.foo.bar\">www.foo.bar</a></p>", pipeline);
|
||||
TestParser.TestSpec("www.foo.bar", "<p><a href=\"https://www.foo.bar\">www.foo.bar</a></p>", httpsPipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
92
src/Markdig.Tests/NormalizeSpecs/Headings.generated.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
|
||||
// --------------------------------
|
||||
// Headings
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.Normalize.Headings
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestHeadings
|
||||
{
|
||||
// # Headings
|
||||
[Test]
|
||||
public void Headings_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Headings
|
||||
//
|
||||
// The following Markdown:
|
||||
// # Heading 1
|
||||
//
|
||||
// ## Heading 2
|
||||
//
|
||||
// ### Heading 3
|
||||
//
|
||||
// #### Heading 4
|
||||
//
|
||||
// ##### Heading 5
|
||||
//
|
||||
// ###### Heading 6
|
||||
//
|
||||
// Should be rendered as:
|
||||
// # Heading 1
|
||||
//
|
||||
// ## Heading 2
|
||||
//
|
||||
// ### Heading 3
|
||||
//
|
||||
// #### Heading 4
|
||||
//
|
||||
// ##### Heading 5
|
||||
//
|
||||
// ###### Heading 6
|
||||
|
||||
Console.WriteLine("Example 1\nSection Headings\n");
|
||||
TestNormalize.TestSpec("# Heading 1\n\n## Heading 2\n\n### Heading 3\n\n#### Heading 4\n\n##### Heading 5\n\n###### Heading 6", "# Heading 1\n\n## Heading 2\n\n### Heading 3\n\n#### Heading 4\n\n##### Heading 5\n\n###### Heading 6", "");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Headings_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Headings
|
||||
//
|
||||
// The following Markdown:
|
||||
// ###### Heading
|
||||
//
|
||||
// Text after two newlines
|
||||
//
|
||||
// Should be rendered as:
|
||||
// ###### Heading
|
||||
//
|
||||
// Text after two newlines
|
||||
|
||||
Console.WriteLine("Example 2\nSection Headings\n");
|
||||
TestNormalize.TestSpec("###### Heading\n\nText after two newlines", "###### Heading\n\nText after two newlines", "");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Headings_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Headings
|
||||
//
|
||||
// The following Markdown:
|
||||
// Heading
|
||||
// =======
|
||||
//
|
||||
// Text after two newlines 1
|
||||
//
|
||||
// Should be rendered as:
|
||||
// # Heading
|
||||
//
|
||||
// Text after two newlines 1
|
||||
|
||||
Console.WriteLine("Example 3\nSection Headings\n");
|
||||
TestNormalize.TestSpec("Heading\n=======\n\nText after two newlines 1", "# Heading\n\nText after two newlines 1", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
48
src/Markdig.Tests/NormalizeSpecs/Headings.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Headings
|
||||
|
||||
```````````````````````````````` example
|
||||
# Heading 1
|
||||
|
||||
## Heading 2
|
||||
|
||||
### Heading 3
|
||||
|
||||
#### Heading 4
|
||||
|
||||
##### Heading 5
|
||||
|
||||
###### Heading 6
|
||||
.
|
||||
# Heading 1
|
||||
|
||||
## Heading 2
|
||||
|
||||
### Heading 3
|
||||
|
||||
#### Heading 4
|
||||
|
||||
##### Heading 5
|
||||
|
||||
###### Heading 6
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
###### Heading
|
||||
|
||||
Text after two newlines
|
||||
.
|
||||
###### Heading
|
||||
|
||||
Text after two newlines
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
Heading
|
||||
=======
|
||||
|
||||
Text after two newlines 1
|
||||
.
|
||||
# Heading
|
||||
|
||||
Text after two newlines 1
|
||||
````````````````````````````````
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
// --------------------------------
|
||||
// Sample
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.PlainText.Sample
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSamplePlainTextSpec
|
||||
{
|
||||
// # Sample plain text spec
|
||||
//
|
||||
// Emphasis and anchors are stripped. A newline is ensured.
|
||||
[Test]
|
||||
public void SamplePlainTextSpec_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Sample plain text spec
|
||||
//
|
||||
// The following Markdown:
|
||||
// *Hello*, [world](http://example.com)!
|
||||
//
|
||||
// Should be rendered as:
|
||||
// Hello, world!
|
||||
//
|
||||
|
||||
Console.WriteLine("Example 1\nSection Sample plain text spec\n");
|
||||
TestPlainText.TestSpec("*Hello*, [world](http://example.com)!", "Hello, world!\n", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/Markdig.Tests/PlainTextSpecs/SamplePlainText.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Sample plain text spec
|
||||
|
||||
Emphasis and anchors are stripped. A newline is ensured.
|
||||
|
||||
```````````````````````````````` example
|
||||
*Hello*, [world](http://example.com)!
|
||||
.
|
||||
Hello, world!
|
||||
|
||||
````````````````````````````````
|
||||
@@ -1,14 +1,19 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// This file is licensed under the BSD-Clause 2 license.
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// This file is licensed under the BSD-Clause 2 license.
|
||||
// See the license.txt file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Markdig.Tests
|
||||
{
|
||||
public class Program
|
||||
class Program
|
||||
{
|
||||
public static void Main()
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
new TestPlayParser().TestSimple();
|
||||
Console.WriteLine("Run NUnit tests runner with this");
|
||||
// Uncomment the following line to debug a specific tests more easily
|
||||
//var tests = new Specs.CommonMarkV_0_29.TestLeafBlocksSetextHeadings();
|
||||
//tests.LeafBlocksSetextHeadings_Example063();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Textamin.Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Textamin.Tests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a0c5cb5f-5568-40ab-b945-d6d2664d51b0")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
15266
src/Markdig.Tests/RoundtripSpecs/CommonMark.generated.cs
Normal file
9710
src/Markdig.Tests/RoundtripSpecs/CommonMark.md
Normal file
@@ -0,0 +1,23 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestAutoLinkInline
|
||||
{
|
||||
[TestCase("<http://a>")]
|
||||
[TestCase(" <http://a>")]
|
||||
[TestCase("<http://a> ")]
|
||||
[TestCase(" <http://a> ")]
|
||||
[TestCase("<example@example.com>")]
|
||||
[TestCase(" <example@example.com>")]
|
||||
[TestCase("<example@example.com> ")]
|
||||
[TestCase(" <example@example.com> ")]
|
||||
[TestCase("p http://a p")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBackslashEscapeInline
|
||||
{
|
||||
[TestCase(@"\!")]
|
||||
[TestCase(@"\""")]
|
||||
[TestCase(@"\#")]
|
||||
[TestCase(@"\$")]
|
||||
[TestCase(@"\&")]
|
||||
[TestCase(@"\'")]
|
||||
[TestCase(@"\(")]
|
||||
[TestCase(@"\)")]
|
||||
[TestCase(@"\*")]
|
||||
[TestCase(@"\+")]
|
||||
[TestCase(@"\,")]
|
||||
[TestCase(@"\-")]
|
||||
[TestCase(@"\.")]
|
||||
[TestCase(@"\/")]
|
||||
[TestCase(@"\:")]
|
||||
[TestCase(@"\;")]
|
||||
[TestCase(@"\<")]
|
||||
[TestCase(@"\=")]
|
||||
[TestCase(@"\>")]
|
||||
[TestCase(@"\?")]
|
||||
[TestCase(@"\@")]
|
||||
[TestCase(@"\[")]
|
||||
[TestCase(@"\\")]
|
||||
[TestCase(@"\]")]
|
||||
[TestCase(@"\^")]
|
||||
[TestCase(@"\_")]
|
||||
[TestCase(@"\`")]
|
||||
[TestCase(@"\{")]
|
||||
[TestCase(@"\|")]
|
||||
[TestCase(@"\}")]
|
||||
[TestCase(@"\~")]
|
||||
|
||||
// below test breaks visual studio
|
||||
//[TestCase(@"\!\""\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase(@"# \#\#h1")]
|
||||
[TestCase(@"# \#\#h1\#")]
|
||||
public void TestHeading(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase(@"`\``")]
|
||||
[TestCase(@"` \``")]
|
||||
[TestCase(@"`\` `")]
|
||||
[TestCase(@"` \` `")]
|
||||
[TestCase(@" ` \` `")]
|
||||
[TestCase(@"` \` ` ")]
|
||||
[TestCase(@" ` \` ` ")]
|
||||
public void TestCodeSpanInline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
77
src/Markdig.Tests/RoundtripSpecs/Inlines/TestCodeInline.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCodeInline
|
||||
{
|
||||
[TestCase("``")]
|
||||
[TestCase(" ``")]
|
||||
[TestCase("`` ")]
|
||||
[TestCase(" `` ")]
|
||||
|
||||
[TestCase("`c`")]
|
||||
[TestCase(" `c`")]
|
||||
[TestCase("`c` ")]
|
||||
[TestCase(" `c` ")]
|
||||
|
||||
[TestCase("` c`")]
|
||||
[TestCase(" ` c`")]
|
||||
[TestCase("` c` ")]
|
||||
[TestCase(" ` c` ")]
|
||||
|
||||
[TestCase("`c `")]
|
||||
[TestCase(" `c `")]
|
||||
[TestCase("`c ` ")]
|
||||
[TestCase(" `c ` ")]
|
||||
|
||||
[TestCase("`c``")] // 1, 2
|
||||
[TestCase("``c`")] // 2, 1
|
||||
[TestCase("``c``")] // 2, 2
|
||||
|
||||
[TestCase("```c``")] // 2, 3
|
||||
[TestCase("``c```")] // 3, 2
|
||||
[TestCase("```c```")] // 3, 3
|
||||
|
||||
[TestCase("```c````")] // 3, 4
|
||||
[TestCase("````c```")] // 4, 3
|
||||
[TestCase("````c````")] // 4, 4
|
||||
|
||||
[TestCase("```a``` p")]
|
||||
[TestCase("```a`b`c```")]
|
||||
[TestCase("```a``` p\n```a``` p")]
|
||||
|
||||
[TestCase("` a `")]
|
||||
[TestCase(" ` a `")]
|
||||
[TestCase("` a ` ")]
|
||||
[TestCase(" ` a ` ")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("p `a` p")]
|
||||
[TestCase("p ``a`` p")]
|
||||
[TestCase("p ```a``` p")]
|
||||
[TestCase("p\n\n```a``` p")]
|
||||
public void TestParagraph(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("`\na\n`")]
|
||||
[TestCase("`\na\r`")]
|
||||
[TestCase("`\na\r\n`")]
|
||||
[TestCase("`\ra\r`")]
|
||||
[TestCase("`\ra\n`")]
|
||||
[TestCase("`\ra\r\n`")]
|
||||
[TestCase("`\r\na\n`")]
|
||||
[TestCase("`\r\na\r`")]
|
||||
[TestCase("`\r\na\r\n`")]
|
||||
public void Test_Newlines(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
132
src/Markdig.Tests/RoundtripSpecs/Inlines/TestEmphasisInline.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestEmphasisInline
|
||||
{
|
||||
[TestCase("_t_")]
|
||||
[TestCase("_t_t")]
|
||||
[TestCase("t_t_")]
|
||||
[TestCase("_t t_")]
|
||||
[TestCase("_t\tt_")]
|
||||
[TestCase("*t*")]
|
||||
[TestCase("t*t*")]
|
||||
[TestCase("*t*t")]
|
||||
[TestCase("*t t*")]
|
||||
[TestCase("*t\tt*")]
|
||||
|
||||
[TestCase(" _t_")]
|
||||
[TestCase(" _t_t")]
|
||||
[TestCase(" t_t_")]
|
||||
[TestCase(" _t t_")]
|
||||
[TestCase(" _t\tt_")]
|
||||
[TestCase(" *t*")]
|
||||
[TestCase(" t*t*")]
|
||||
[TestCase(" *t*t")]
|
||||
[TestCase(" *t t*")]
|
||||
[TestCase(" *t\tt*")]
|
||||
|
||||
[TestCase("_t_")]
|
||||
[TestCase("_t_t ")]
|
||||
[TestCase("t_t_ ")]
|
||||
[TestCase("_t t_ ")]
|
||||
[TestCase("_t\tt_ ")]
|
||||
[TestCase("*t* ")]
|
||||
[TestCase("t*t* ")]
|
||||
[TestCase("*t*t ")]
|
||||
[TestCase("*t t* ")]
|
||||
[TestCase("*t\tt* ")]
|
||||
|
||||
[TestCase(" _t_")]
|
||||
[TestCase(" _t_t ")]
|
||||
[TestCase(" t_t_ ")]
|
||||
[TestCase(" _t t_ ")]
|
||||
[TestCase(" _t\tt_ ")]
|
||||
[TestCase(" *t* ")]
|
||||
[TestCase(" t*t* ")]
|
||||
[TestCase(" *t*t ")]
|
||||
[TestCase(" *t t* ")]
|
||||
[TestCase(" *t\tt* ")]
|
||||
|
||||
[TestCase("_t_\t")]
|
||||
[TestCase("_t_t\t")]
|
||||
[TestCase("t_t_\t")]
|
||||
[TestCase("_t t_\t")]
|
||||
[TestCase("_t\tt_\t")]
|
||||
[TestCase("*t*\t")]
|
||||
[TestCase("t*t*\t")]
|
||||
[TestCase("*t*t\t")]
|
||||
[TestCase("*t t*\t")]
|
||||
[TestCase("*t\tt*\t")]
|
||||
public void Test_Emphasis(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("__t__")]
|
||||
[TestCase("__t__t")]
|
||||
[TestCase("t__t__")]
|
||||
[TestCase("__t t__")]
|
||||
[TestCase("__t\tt__")]
|
||||
[TestCase("**t**")]
|
||||
[TestCase("**t**t")]
|
||||
[TestCase("t**t**")]
|
||||
[TestCase("**t\tt**")]
|
||||
|
||||
[TestCase(" __t__")]
|
||||
[TestCase(" __t__t")]
|
||||
[TestCase(" t__t__")]
|
||||
[TestCase(" __t t__")]
|
||||
[TestCase(" __t\tt__")]
|
||||
[TestCase(" **t**")]
|
||||
[TestCase(" **t**t")]
|
||||
[TestCase(" t**t**")]
|
||||
[TestCase(" **t\tt**")]
|
||||
|
||||
[TestCase("__t__ ")]
|
||||
[TestCase("__t__t ")]
|
||||
[TestCase("t__t__ ")]
|
||||
[TestCase("__t t__ ")]
|
||||
[TestCase("__t\tt__ ")]
|
||||
[TestCase("**t** ")]
|
||||
[TestCase("**t**t ")]
|
||||
[TestCase("t**t** ")]
|
||||
[TestCase("**t\tt** ")]
|
||||
|
||||
[TestCase(" __t__ ")]
|
||||
[TestCase(" __t__t ")]
|
||||
[TestCase(" t__t__ ")]
|
||||
[TestCase(" __t t__ ")]
|
||||
[TestCase(" __t\tt__ ")]
|
||||
[TestCase(" **t** ")]
|
||||
[TestCase(" **t** t")]
|
||||
[TestCase(" t**t** ")]
|
||||
[TestCase(" **t\tt** ")]
|
||||
|
||||
[TestCase("__t__\t")]
|
||||
[TestCase("__t__t\t")]
|
||||
[TestCase("t__t__\t ")]
|
||||
[TestCase("__t t__\t ")]
|
||||
[TestCase("__t\tt__\t ")]
|
||||
[TestCase("**t**\t ")]
|
||||
[TestCase("**t**t\t ")]
|
||||
[TestCase("t**t**\t ")]
|
||||
[TestCase("**t\tt**\t ")]
|
||||
|
||||
[TestCase(" __t__\t ")]
|
||||
[TestCase(" __t__t\t ")]
|
||||
[TestCase(" t__t__\t ")]
|
||||
[TestCase(" __t t__\t ")]
|
||||
[TestCase(" __t\tt__\t ")]
|
||||
[TestCase(" **t**\t ")]
|
||||
[TestCase(" **t**\t t")]
|
||||
[TestCase(" t**t**\t ")]
|
||||
[TestCase(" **t\tt**\t ")]
|
||||
public void Test_StrongEmphasis(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <seealso cref="https://spec.commonmark.org/0.29/#entity-and-numeric-character-references"/>
|
||||
[TestFixture]
|
||||
public class TestHtmlEntityInline
|
||||
{
|
||||
[TestCase(">")]
|
||||
[TestCase("<")]
|
||||
[TestCase(" ")]
|
||||
[TestCase("♥")]
|
||||
[TestCase("*")]
|
||||
[TestCase("�")]
|
||||
[TestCase("Ӓ")]
|
||||
[TestCase("ಫ")]
|
||||
|
||||
[TestCase(" >")]
|
||||
[TestCase(" <")]
|
||||
[TestCase(" ")]
|
||||
[TestCase(" ♥")]
|
||||
[TestCase(" *")]
|
||||
[TestCase(" �")]
|
||||
[TestCase(" Ӓ")]
|
||||
[TestCase(" ಫ")]
|
||||
|
||||
[TestCase("> ")]
|
||||
[TestCase("< ")]
|
||||
[TestCase(" ")]
|
||||
[TestCase("♥ ")]
|
||||
[TestCase("* ")]
|
||||
[TestCase("� ")]
|
||||
[TestCase("Ӓ ")]
|
||||
[TestCase("ಫ ")]
|
||||
|
||||
[TestCase(" > ")]
|
||||
[TestCase(" < ")]
|
||||
[TestCase(" ")]
|
||||
[TestCase(" ♥ ")]
|
||||
[TestCase(" * ")]
|
||||
[TestCase(" � ")]
|
||||
[TestCase(" Ӓ ")]
|
||||
[TestCase(" ಫ ")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/Markdig.Tests/RoundtripSpecs/Inlines/TestHtmlInline.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestHtmlInline
|
||||
{
|
||||
[TestCase("<em>f</em>")]
|
||||
[TestCase("<em> f</em>")]
|
||||
[TestCase("<em>f </em>")]
|
||||
[TestCase("<em> f </em>")]
|
||||
[TestCase("<b>p</b>")]
|
||||
[TestCase("<b></b>")]
|
||||
[TestCase("<b> </b>")]
|
||||
[TestCase("<b> </b>")]
|
||||
[TestCase("<b> </b>")]
|
||||
[TestCase("<b>\t</b>")]
|
||||
[TestCase("<b> \t</b>")]
|
||||
[TestCase("<b>\t </b>")]
|
||||
[TestCase("<b> \t </b>")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/Markdig.Tests/RoundtripSpecs/Inlines/TestImageInline.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestImageInline
|
||||
{
|
||||
[TestCase("")]
|
||||
[TestCase(" ")]
|
||||
[TestCase(" ")]
|
||||
[TestCase("  ")]
|
||||
[TestCase(" ")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("paragraph ")]
|
||||
public void TestParagraph(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLineBreakInline
|
||||
{
|
||||
[TestCase("p\n")]
|
||||
[TestCase("p\r\n")]
|
||||
[TestCase("p\r")]
|
||||
[TestCase("[]() ![]() `` ` ` ` ` ![]() ![]()")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
229
src/Markdig.Tests/RoundtripSpecs/Inlines/TestLinkInline.cs
Normal file
@@ -0,0 +1,229 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLinkInline
|
||||
{
|
||||
[TestCase("[a]")] // TODO: this is not a link but a paragraph
|
||||
[TestCase("[a]()")]
|
||||
|
||||
[TestCase("[](b)")]
|
||||
[TestCase(" [](b)")]
|
||||
[TestCase("[](b) ")]
|
||||
[TestCase(" [](b) ")]
|
||||
|
||||
[TestCase("[a](b)")]
|
||||
[TestCase(" [a](b)")]
|
||||
[TestCase("[a](b) ")]
|
||||
[TestCase(" [a](b) ")]
|
||||
|
||||
[TestCase("[ a](b)")]
|
||||
[TestCase(" [ a](b)")]
|
||||
[TestCase("[ a](b) ")]
|
||||
[TestCase(" [ a](b) ")]
|
||||
|
||||
[TestCase("[a ](b)")]
|
||||
[TestCase(" [a ](b)")]
|
||||
[TestCase("[a ](b) ")]
|
||||
[TestCase(" [a ](b) ")]
|
||||
|
||||
[TestCase("[ a ](b)")]
|
||||
[TestCase(" [ a ](b)")]
|
||||
[TestCase("[ a ](b) ")]
|
||||
[TestCase(" [ a ](b) ")]
|
||||
|
||||
// below cases are required for a full roundtrip but not have low prio for impl
|
||||
[TestCase("[]( b)")]
|
||||
[TestCase(" []( b)")]
|
||||
[TestCase("[]( b) ")]
|
||||
[TestCase(" []( b) ")]
|
||||
|
||||
[TestCase("[a]( b)")]
|
||||
[TestCase(" [a]( b)")]
|
||||
[TestCase("[a]( b) ")]
|
||||
[TestCase(" [a]( b) ")]
|
||||
|
||||
[TestCase("[ a]( b)")]
|
||||
[TestCase(" [ a]( b)")]
|
||||
[TestCase("[ a]( b) ")]
|
||||
[TestCase(" [ a]( b) ")]
|
||||
|
||||
[TestCase("[a ]( b)")]
|
||||
[TestCase(" [a ]( b)")]
|
||||
[TestCase("[a ]( b) ")]
|
||||
[TestCase(" [a ]( b) ")]
|
||||
|
||||
[TestCase("[ a ]( b)")]
|
||||
[TestCase(" [ a ]( b)")]
|
||||
[TestCase("[ a ]( b) ")]
|
||||
[TestCase(" [ a ]( b) ")]
|
||||
|
||||
[TestCase("[](b )")]
|
||||
[TestCase(" [](b )")]
|
||||
[TestCase("[](b ) ")]
|
||||
[TestCase(" [](b ) ")]
|
||||
|
||||
[TestCase("[a](b )")]
|
||||
[TestCase(" [a](b )")]
|
||||
[TestCase("[a](b ) ")]
|
||||
[TestCase(" [a](b ) ")]
|
||||
|
||||
[TestCase("[ a](b )")]
|
||||
[TestCase(" [ a](b )")]
|
||||
[TestCase("[ a](b ) ")]
|
||||
[TestCase(" [ a](b ) ")]
|
||||
|
||||
[TestCase("[a ](b )")]
|
||||
[TestCase(" [a ](b )")]
|
||||
[TestCase("[a ](b ) ")]
|
||||
[TestCase(" [a ](b ) ")]
|
||||
|
||||
[TestCase("[ a ](b )")]
|
||||
[TestCase(" [ a ](b )")]
|
||||
[TestCase("[ a ](b ) ")]
|
||||
[TestCase(" [ a ](b ) ")]
|
||||
|
||||
[TestCase("[]( b )")]
|
||||
[TestCase(" []( b )")]
|
||||
[TestCase("[]( b ) ")]
|
||||
[TestCase(" []( b ) ")]
|
||||
|
||||
[TestCase("[a]( b )")]
|
||||
[TestCase(" [a]( b )")]
|
||||
[TestCase("[a]( b ) ")]
|
||||
[TestCase(" [a]( b ) ")]
|
||||
|
||||
[TestCase("[ a]( b )")]
|
||||
[TestCase(" [ a]( b )")]
|
||||
[TestCase("[ a]( b ) ")]
|
||||
[TestCase(" [ a]( b ) ")]
|
||||
|
||||
[TestCase("[a ]( b )")]
|
||||
[TestCase(" [a ]( b )")]
|
||||
[TestCase("[a ]( b ) ")]
|
||||
[TestCase(" [a ]( b ) ")]
|
||||
|
||||
[TestCase("[ a ]( b )")]
|
||||
[TestCase(" [ a ]( b )")]
|
||||
[TestCase("[ a ]( b ) ")]
|
||||
[TestCase(" [ a ]( b ) ")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[a](b \"t\") ")]
|
||||
[TestCase("[a](b \" t\") ")]
|
||||
[TestCase("[a](b \"t \") ")]
|
||||
[TestCase("[a](b \" t \") ")]
|
||||
|
||||
[TestCase("[a](b \"t\") ")]
|
||||
[TestCase("[a](b \" t\") ")]
|
||||
[TestCase("[a](b \"t \") ")]
|
||||
[TestCase("[a](b \" t \") ")]
|
||||
|
||||
[TestCase("[a](b \"t\" ) ")]
|
||||
[TestCase("[a](b \" t\" ) ")]
|
||||
[TestCase("[a](b \"t \" ) ")]
|
||||
[TestCase("[a](b \" t \" ) ")]
|
||||
|
||||
[TestCase("[a](b \"t\" ) ")]
|
||||
[TestCase("[a](b \" t\" ) ")]
|
||||
[TestCase("[a](b \"t \" ) ")]
|
||||
[TestCase("[a](b \" t \" ) ")]
|
||||
|
||||
[TestCase("[a](b 't') ")]
|
||||
[TestCase("[a](b ' t') ")]
|
||||
[TestCase("[a](b 't ') ")]
|
||||
[TestCase("[a](b ' t ') ")]
|
||||
|
||||
[TestCase("[a](b 't') ")]
|
||||
[TestCase("[a](b ' t') ")]
|
||||
[TestCase("[a](b 't ') ")]
|
||||
[TestCase("[a](b ' t ') ")]
|
||||
|
||||
[TestCase("[a](b 't' ) ")]
|
||||
[TestCase("[a](b ' t' ) ")]
|
||||
[TestCase("[a](b 't ' ) ")]
|
||||
[TestCase("[a](b ' t ' ) ")]
|
||||
|
||||
[TestCase("[a](b 't' ) ")]
|
||||
[TestCase("[a](b ' t' ) ")]
|
||||
[TestCase("[a](b 't ' ) ")]
|
||||
[TestCase("[a](b ' t ' ) ")]
|
||||
|
||||
[TestCase("[a](b (t)) ")]
|
||||
[TestCase("[a](b ( t)) ")]
|
||||
[TestCase("[a](b (t )) ")]
|
||||
[TestCase("[a](b ( t )) ")]
|
||||
|
||||
[TestCase("[a](b (t)) ")]
|
||||
[TestCase("[a](b ( t)) ")]
|
||||
[TestCase("[a](b (t )) ")]
|
||||
[TestCase("[a](b ( t )) ")]
|
||||
|
||||
[TestCase("[a](b (t) ) ")]
|
||||
[TestCase("[a](b ( t) ) ")]
|
||||
[TestCase("[a](b (t ) ) ")]
|
||||
[TestCase("[a](b ( t ) ) ")]
|
||||
|
||||
[TestCase("[a](b (t) ) ")]
|
||||
[TestCase("[a](b ( t) ) ")]
|
||||
[TestCase("[a](b (t ) ) ")]
|
||||
[TestCase("[a](b ( t ) ) ")]
|
||||
public void Test_Title(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[a](<>)")]
|
||||
[TestCase("[a]( <>)")]
|
||||
[TestCase("[a](<> )")]
|
||||
[TestCase("[a]( <> )")]
|
||||
|
||||
[TestCase("[a](< >)")]
|
||||
[TestCase("[a]( < >)")]
|
||||
[TestCase("[a](< > )")]
|
||||
[TestCase("[a]( < > )")]
|
||||
|
||||
[TestCase("[a](<b>)")]
|
||||
[TestCase("[a](<b >)")]
|
||||
[TestCase("[a](< b>)")]
|
||||
[TestCase("[a](< b >)")]
|
||||
|
||||
[TestCase("[a](<b b>)")]
|
||||
[TestCase("[a](<b b >)")]
|
||||
[TestCase("[a](< b b >)")]
|
||||
public void Test_PointyBrackets(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[*a*][a]")]
|
||||
[TestCase("[a][b]")]
|
||||
[TestCase("[a][]")]
|
||||
[TestCase("[a]")]
|
||||
public void Test_Inlines(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
// | [ a ]( b " t " ) |
|
||||
[TestCase(" [ a ]( b \" t \" ) ")]
|
||||
[TestCase("\v[\va\v](\vb\v\"\vt\v\"\v)\v")]
|
||||
[TestCase("\f[\fa\f](\fb\f\"\ft\f\"\f)\f")]
|
||||
[TestCase("\t[\ta\t](\tb\t\"\tt\t\"\t)\t")]
|
||||
public void Test_UncommonWhitespace(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[x]: https://example.com\r\n")]
|
||||
public void Test_LinkReferenceDefinitionWithCarriageReturnLineFeed(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Markdig.Renderers.Roundtrip;
|
||||
using Markdig.Syntax;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs.Inlines
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestNullCharacterInline
|
||||
{
|
||||
[TestCase("\0", "\uFFFD")]
|
||||
[TestCase("\0p", "\uFFFDp")]
|
||||
[TestCase("p\0", "p\uFFFD")]
|
||||
[TestCase("p\0p", "p\uFFFDp")]
|
||||
[TestCase("p\0\0p", "p\uFFFD\uFFFDp")] // I promise you, this was not intentional
|
||||
public void Test(string value, string expected)
|
||||
{
|
||||
RoundTrip(value, expected);
|
||||
}
|
||||
|
||||
// this method is copied intentionally to ensure all other tests
|
||||
// do not unintentionally use the expected parameter
|
||||
private static void RoundTrip(string markdown, string expected)
|
||||
{
|
||||
var pipelineBuilder = new MarkdownPipelineBuilder();
|
||||
pipelineBuilder.EnableTrackTrivia();
|
||||
MarkdownPipeline pipeline = pipelineBuilder.Build();
|
||||
MarkdownDocument markdownDocument = Markdown.Parse(markdown, pipeline);
|
||||
var sw = new StringWriter();
|
||||
var rr = new RoundtripRenderer(sw);
|
||||
|
||||
rr.Write(markdownDocument);
|
||||
|
||||
Assert.AreEqual(expected, sw.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/Markdig.Tests/RoundtripSpecs/TestAtxHeading.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestAtxHeading
|
||||
{
|
||||
[TestCase("# h")]
|
||||
[TestCase("# h ")]
|
||||
[TestCase("# h\n#h")]
|
||||
[TestCase("# h\n #h")]
|
||||
[TestCase("# h\n # h")]
|
||||
[TestCase("# h\n # h ")]
|
||||
[TestCase(" # h \n # h ")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("\n# h\n\np")]
|
||||
[TestCase("\n# h\n\np\n")]
|
||||
[TestCase("\n# h\n\np\n\n")]
|
||||
[TestCase("\n\n# h\n\np\n\n")]
|
||||
[TestCase("\n\n# h\np\n\n")]
|
||||
[TestCase("\n\n# h\np\n\n")]
|
||||
public void TestParagraph(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("\n# h")]
|
||||
[TestCase("\n# h\n")]
|
||||
[TestCase("\n# h\r")]
|
||||
[TestCase("\n# h\r\n")]
|
||||
|
||||
[TestCase("\r# h")]
|
||||
[TestCase("\r# h\n")]
|
||||
[TestCase("\r# h\r")]
|
||||
[TestCase("\r# h\r\n")]
|
||||
|
||||
[TestCase("\r\n# h")]
|
||||
[TestCase("\r\n# h\n")]
|
||||
[TestCase("\r\n# h\r")]
|
||||
[TestCase("\r\n# h\r\n")]
|
||||
|
||||
[TestCase("# h\n\n ")]
|
||||
[TestCase("# h\n\n ")]
|
||||
[TestCase("# h\n\n ")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
src/Markdig.Tests/RoundtripSpecs/TestExample.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Markdig.Helpers;
|
||||
using Markdig.Renderers.Roundtrip;
|
||||
using Markdig.Syntax;
|
||||
using Markdig.Syntax.Inlines;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExample
|
||||
{
|
||||
[Test]
|
||||
public void Test()
|
||||
{
|
||||
var markdown = $@"
|
||||
# Test document
|
||||
This document contains an unordered list. It uses tabs to indent. This test demonstrates
|
||||
a method of making the input markdown uniform without altering any other markdown in the
|
||||
resulting output file.
|
||||
|
||||
- item1
|
||||
|
||||
>look, ma:
|
||||
> my space is not normalized!
|
||||
";
|
||||
MarkdownDocument markdownDocument = Markdown.Parse(markdown, trackTrivia: true);
|
||||
var listBlock = markdownDocument[2] as ListBlock;
|
||||
var listItem = listBlock[0] as ListItemBlock;
|
||||
var paragraph = listItem[0] as ParagraphBlock;
|
||||
var containerInline = new ContainerInline();
|
||||
containerInline.AppendChild(new LiteralInline(" my own text!"));
|
||||
containerInline.AppendChild(new LineBreakInline { NewLine = NewLine.CarriageReturnLineFeed });
|
||||
paragraph.Inline = containerInline;
|
||||
|
||||
var sw = new StringWriter();
|
||||
var rr = new RoundtripRenderer(sw);
|
||||
rr.Write(markdownDocument);
|
||||
var outputMarkdown = sw.ToString();
|
||||
var expected = $@"
|
||||
# Test document
|
||||
This document contains an unordered list. It uses tabs to indent. This test demonstrates
|
||||
a method of making the input markdown uniform without altering any other markdown in the
|
||||
resulting output file.
|
||||
|
||||
- my own text!
|
||||
|
||||
>look, ma:
|
||||
> my space is not normalized!
|
||||
";
|
||||
|
||||
expected = expected.Replace("\r\n", "\n").Replace("\r", "\n");
|
||||
outputMarkdown = outputMarkdown.Replace("\r\n", "\n").Replace("\r", "\n");
|
||||
|
||||
Assert.AreEqual(expected, outputMarkdown);
|
||||
}
|
||||
}
|
||||
}
|
||||
107
src/Markdig.Tests/RoundtripSpecs/TestFencedCodeBlock.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestFencedCodeBlock
|
||||
{
|
||||
[TestCase("```\nc\n```")]
|
||||
[TestCase("```\nc\n```\n")]
|
||||
[TestCase("\n```\nc\n```")]
|
||||
[TestCase("\n\n```\nc\n```")]
|
||||
[TestCase("```\nc\n```\n")]
|
||||
[TestCase("```\nc\n```\n\n")]
|
||||
[TestCase("\n```\nc\n```\n")]
|
||||
[TestCase("\n```\nc\n```\n\n")]
|
||||
[TestCase("\n\n```\nc\n```\n")]
|
||||
[TestCase("\n\n```\nc\n```\n\n")]
|
||||
|
||||
[TestCase(" ```\nc\n````")]
|
||||
[TestCase("```\nc\n````")]
|
||||
[TestCase("p\n\n```\nc\n```")]
|
||||
|
||||
[TestCase("```\n c\n```")]
|
||||
[TestCase("```\nc \n```")]
|
||||
[TestCase("```\n c \n```")]
|
||||
|
||||
[TestCase(" ``` \n c \n ``` ")]
|
||||
[TestCase("\t```\t\n\tc\t\n\t```\t")]
|
||||
[TestCase("\v```\v\n\vc\v\n\v```\v")]
|
||||
[TestCase("\f```\f\n\fc\f\n\f```\f")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("~~~ aa ``` ~~~\nfoo\n~~~")]
|
||||
[TestCase("~~~ aa ``` ~~~\nfoo\n~~~ ")]
|
||||
public void TestTilde(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("```\n c \n```")]
|
||||
[TestCase("```\n c \r```")]
|
||||
[TestCase("```\n c \r\n```")]
|
||||
[TestCase("```\r c \n```")]
|
||||
[TestCase("```\r c \r```")]
|
||||
[TestCase("```\r c \r\n```")]
|
||||
[TestCase("```\r\n c \n```")]
|
||||
[TestCase("```\r\n c \r```")]
|
||||
[TestCase("```\r\n c \r\n```")]
|
||||
|
||||
[TestCase("```\n c \n```\n")]
|
||||
[TestCase("```\n c \r```\n")]
|
||||
[TestCase("```\n c \r\n```\n")]
|
||||
[TestCase("```\r c \n```\n")]
|
||||
[TestCase("```\r c \r```\n")]
|
||||
[TestCase("```\r c \r\n```\n")]
|
||||
[TestCase("```\r\n c \n```\n")]
|
||||
[TestCase("```\r\n c \r```\n")]
|
||||
[TestCase("```\r\n c \r\n```\n")]
|
||||
|
||||
[TestCase("```\n c \n```\r")]
|
||||
[TestCase("```\n c \r```\r")]
|
||||
[TestCase("```\n c \r\n```\r")]
|
||||
[TestCase("```\r c \n```\r")]
|
||||
[TestCase("```\r c \r```\r")]
|
||||
[TestCase("```\r c \r\n```\r")]
|
||||
[TestCase("```\r\n c \n```\r")]
|
||||
[TestCase("```\r\n c \r```\r")]
|
||||
[TestCase("```\r\n c \r\n```\r")]
|
||||
|
||||
[TestCase("```\n c \n```\r\n")]
|
||||
[TestCase("```\n c \r```\r\n")]
|
||||
[TestCase("```\n c \r\n```\r\n")]
|
||||
[TestCase("```\r c \n```\r\n")]
|
||||
[TestCase("```\r c \r```\r\n")]
|
||||
[TestCase("```\r c \r\n```\r\n")]
|
||||
[TestCase("```\r\n c \n```\r\n")]
|
||||
[TestCase("```\r\n c \r```\r\n")]
|
||||
[TestCase("```\r\n c \r\n```\r\n")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("```i a\n```")]
|
||||
[TestCase("```i a a2\n```")]
|
||||
[TestCase("```i a a2 a3\n```")]
|
||||
[TestCase("```i a a2 a3 a4\n```")]
|
||||
|
||||
[TestCase("```i\ta\n```")]
|
||||
[TestCase("```i\ta a2\n```")]
|
||||
[TestCase("```i\ta a2 a3\n```")]
|
||||
[TestCase("```i\ta a2 a3 a4\n```")]
|
||||
|
||||
[TestCase("```i\ta \n```")]
|
||||
[TestCase("```i\ta a2 \n```")]
|
||||
[TestCase("```i\ta a2 a3 \n```")]
|
||||
[TestCase("```i\ta a2 a3 a4 \n```")]
|
||||
public void TestInfoArguments(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
src/Markdig.Tests/RoundtripSpecs/TestHtmlBlock.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestHtmlBlock
|
||||
{
|
||||
[TestCase("<br>")]
|
||||
[TestCase("<br>\n")]
|
||||
[TestCase("<br>\n\n")]
|
||||
[TestCase("<div></div>\n\n# h")]
|
||||
[TestCase("p\n\n<div></div>\n")]
|
||||
[TestCase("<div></div>\n\n# h")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
86
src/Markdig.Tests/RoundtripSpecs/TestIndentedCodeBlock.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestIndentedCodeBlock
|
||||
{
|
||||
// A codeblock is indented with 4 spaces. After the 4th space, whitespace is interpreted as content.
|
||||
// l = line
|
||||
[TestCase(" l")]
|
||||
[TestCase(" l")]
|
||||
[TestCase("\tl")]
|
||||
[TestCase("\t\tl")]
|
||||
[TestCase("\tl1\n l1")]
|
||||
|
||||
[TestCase("\n l")]
|
||||
[TestCase("\n\n l")]
|
||||
[TestCase("\n l\n")]
|
||||
[TestCase("\n l\n\n")]
|
||||
[TestCase("\n\n l\n")]
|
||||
[TestCase("\n\n l\n\n")]
|
||||
|
||||
[TestCase(" l\n l")]
|
||||
[TestCase(" l\n l\n l")]
|
||||
|
||||
|
||||
// two newlines are needed for indented codeblock start after paragraph
|
||||
[TestCase("p\n\n l")]
|
||||
[TestCase("p\n\n l\n")]
|
||||
[TestCase("p\n\n l\n\n")]
|
||||
|
||||
[TestCase("p\n\n l\n l")]
|
||||
[TestCase("p\n\n l\n l")]
|
||||
|
||||
[TestCase(" l\n\np\n\n l")]
|
||||
[TestCase(" l l\n\np\n\n l l")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase(" l\n")]
|
||||
[TestCase(" l\r")]
|
||||
[TestCase(" l\r\n")]
|
||||
|
||||
[TestCase(" l\n l")]
|
||||
[TestCase(" l\n l\n")]
|
||||
[TestCase(" l\n l\r")]
|
||||
[TestCase(" l\n l\r\n")]
|
||||
|
||||
[TestCase(" l\r l")]
|
||||
[TestCase(" l\r l\n")]
|
||||
[TestCase(" l\r l\r")]
|
||||
[TestCase(" l\r l\r\n")]
|
||||
|
||||
[TestCase(" l\r\n l")]
|
||||
[TestCase(" l\r\n l\n")]
|
||||
[TestCase(" l\r\n l\r")]
|
||||
[TestCase(" l\r\n l\r\n")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase(" l\n\n l\n")]
|
||||
[TestCase(" l\n\n\n l\n")]
|
||||
public void TestNewlinesInBetweenResultInOneCodeBlock(string value)
|
||||
{
|
||||
var pipelineBuilder = new MarkdownPipelineBuilder();
|
||||
pipelineBuilder.EnableTrackTrivia();
|
||||
MarkdownPipeline pipeline = pipelineBuilder.Build();
|
||||
var markdownDocument = Markdown.Parse(value, pipeline);
|
||||
|
||||
Assert.AreEqual(1, markdownDocument.Count);
|
||||
}
|
||||
|
||||
[TestCase(" l\n\np")]
|
||||
[TestCase(" l\n\n\np")]
|
||||
[TestCase(" l\n\n\n\np")]
|
||||
public void TestParagraph(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
214
src/Markdig.Tests/RoundtripSpecs/TestLinkReferenceDefinition.cs
Normal file
@@ -0,0 +1,214 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLinkReferenceDefinition
|
||||
{
|
||||
[TestCase(@"[a]: /r")]
|
||||
[TestCase(@" [a]: /r")]
|
||||
[TestCase(@" [a]: /r")]
|
||||
[TestCase(@" [a]: /r")]
|
||||
|
||||
[TestCase(@"[a]: /r")]
|
||||
[TestCase(@" [a]: /r")]
|
||||
[TestCase(@" [a]: /r")]
|
||||
[TestCase(@" [a]: /r")]
|
||||
|
||||
[TestCase(@"[a]: /r ")]
|
||||
[TestCase(@" [a]: /r ")]
|
||||
[TestCase(@" [a]: /r ")]
|
||||
[TestCase(@" [a]: /r ")]
|
||||
|
||||
[TestCase(@"[a]: /r ""l""")]
|
||||
[TestCase(@"[a]: /r ""l""")]
|
||||
[TestCase(@"[a]: /r ""l""")]
|
||||
[TestCase(@"[a]: /r ""l"" ")]
|
||||
[TestCase(@"[a]: /r ""l""")]
|
||||
[TestCase(@"[a]: /r ""l"" ")]
|
||||
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l"" ")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l"" ")]
|
||||
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l"" ")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l"" ")]
|
||||
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l"" ")]
|
||||
[TestCase(@" [a]: /r ""l""")]
|
||||
[TestCase(@" [a]: /r ""l"" ")]
|
||||
|
||||
[TestCase("[a]:\t/r")]
|
||||
[TestCase("[a]:\t/r\t")]
|
||||
[TestCase("[a]:\t/r\t\"l\"")]
|
||||
[TestCase("[a]:\t/r\t\"l\"\t")]
|
||||
|
||||
[TestCase("[a]: \t/r")]
|
||||
[TestCase("[a]: \t/r\t")]
|
||||
[TestCase("[a]: \t/r\t\"l\"")]
|
||||
[TestCase("[a]: \t/r\t\"l\"\t")]
|
||||
|
||||
[TestCase("[a]:\t /r")]
|
||||
[TestCase("[a]:\t /r\t")]
|
||||
[TestCase("[a]:\t /r\t\"l\"")]
|
||||
[TestCase("[a]:\t /r\t\"l\"\t")]
|
||||
|
||||
[TestCase("[a]: \t /r")]
|
||||
[TestCase("[a]: \t /r\t")]
|
||||
[TestCase("[a]: \t /r\t\"l\"")]
|
||||
[TestCase("[a]: \t /r\t\"l\"\t")]
|
||||
|
||||
[TestCase("[a]:\t/r \t")]
|
||||
[TestCase("[a]:\t/r \t\"l\"")]
|
||||
[TestCase("[a]:\t/r \t\"l\"\t")]
|
||||
|
||||
[TestCase("[a]: \t/r")]
|
||||
[TestCase("[a]: \t/r \t")]
|
||||
[TestCase("[a]: \t/r \t\"l\"")]
|
||||
[TestCase("[a]: \t/r \t\"l\"\t")]
|
||||
|
||||
[TestCase("[a]:\t /r")]
|
||||
[TestCase("[a]:\t /r \t")]
|
||||
[TestCase("[a]:\t /r \t\"l\"")]
|
||||
[TestCase("[a]:\t /r \t\"l\"\t")]
|
||||
|
||||
[TestCase("[a]: \t /r")]
|
||||
[TestCase("[a]: \t /r \t")]
|
||||
[TestCase("[a]: \t /r \t\"l\"")]
|
||||
[TestCase("[a]: \t /r \t\"l\"\t")]
|
||||
|
||||
[TestCase("[a]:\t/r\t ")]
|
||||
[TestCase("[a]:\t/r\t \"l\"")]
|
||||
[TestCase("[a]:\t/r\t \"l\"\t")]
|
||||
|
||||
[TestCase("[a]: \t/r")]
|
||||
[TestCase("[a]: \t/r\t ")]
|
||||
[TestCase("[a]: \t/r\t \"l\"")]
|
||||
[TestCase("[a]: \t/r\t \"l\"\t")]
|
||||
|
||||
[TestCase("[a]:\t /r")]
|
||||
[TestCase("[a]:\t /r\t ")]
|
||||
[TestCase("[a]:\t /r\t \"l\"")]
|
||||
[TestCase("[a]:\t /r\t \"l\"\t")]
|
||||
|
||||
[TestCase("[a]: \t /r")]
|
||||
[TestCase("[a]: \t /r\t ")]
|
||||
[TestCase("[a]: \t /r\t \"l\"")]
|
||||
[TestCase("[a]: \t /r\t \"l\"\t")]
|
||||
|
||||
[TestCase("[a]:\t/r \t ")]
|
||||
[TestCase("[a]:\t/r \t \"l\"")]
|
||||
[TestCase("[a]:\t/r \t \"l\"\t")]
|
||||
|
||||
[TestCase("[a]: \t/r")]
|
||||
[TestCase("[a]: \t/r \t ")]
|
||||
[TestCase("[a]: \t/r \t \"l\"")]
|
||||
[TestCase("[a]: \t/r \t \"l\"\t")]
|
||||
|
||||
[TestCase("[a]:\t /r")]
|
||||
[TestCase("[a]:\t /r \t ")]
|
||||
[TestCase("[a]:\t /r \t \"l\"")]
|
||||
[TestCase("[a]:\t /r \t \"l\"\t")]
|
||||
|
||||
[TestCase("[a]: \t /r")]
|
||||
[TestCase("[a]: \t /r \t ")]
|
||||
[TestCase("[a]: \t /r \t \"l\"")]
|
||||
[TestCase("[a]: \t /r \t \"l\"\t")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[a]: /r\n[b]: /r\n")]
|
||||
[TestCase("[a]: /r\n[b]: /r\n[c] /r\n")]
|
||||
public void TestMultiple(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[a]:\f/r\f\"l\"")]
|
||||
[TestCase("[a]:\v/r\v\"l\"")]
|
||||
public void TestUncommonWhitespace(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[a]:\n/r\n\"t\"")]
|
||||
[TestCase("[a]:\n/r\r\"t\"")]
|
||||
[TestCase("[a]:\n/r\r\n\"t\"")]
|
||||
|
||||
[TestCase("[a]:\r/r\n\"t\"")]
|
||||
[TestCase("[a]:\r/r\r\"t\"")]
|
||||
[TestCase("[a]:\r/r\r\n\"t\"")]
|
||||
|
||||
[TestCase("[a]:\r\n/r\n\"t\"")]
|
||||
[TestCase("[a]:\r\n/r\r\"t\"")]
|
||||
[TestCase("[a]:\r\n/r\r\n\"t\"")]
|
||||
|
||||
[TestCase("[a]:\n/r\n\"t\nt\"")]
|
||||
[TestCase("[a]:\n/r\n\"t\rt\"")]
|
||||
[TestCase("[a]:\n/r\n\"t\r\nt\"")]
|
||||
|
||||
[TestCase("[a]:\r\n /r\t \n \t \"t\r\nt\" ")]
|
||||
[TestCase("[a]:\n/r\n\n[a],")]
|
||||
[TestCase("[a]: /r\n[b]: /r\n\n[a],")]
|
||||
public void TestNewlines(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[ a]: /r")]
|
||||
[TestCase("[a ]: /r")]
|
||||
[TestCase("[ a ]: /r")]
|
||||
[TestCase("[ a]: /r")]
|
||||
[TestCase("[ a ]: /r")]
|
||||
[TestCase("[a ]: /r")]
|
||||
[TestCase("[ a ]: /r")]
|
||||
[TestCase("[ a ]: /r")]
|
||||
[TestCase("[a a]: /r")]
|
||||
[TestCase("[a\va]: /r")]
|
||||
[TestCase("[a\fa]: /r")]
|
||||
[TestCase("[a\ta]: /r")]
|
||||
[TestCase("[\va]: /r")]
|
||||
[TestCase("[\fa]: /r")]
|
||||
[TestCase("[\ta]: /r")]
|
||||
[TestCase(@"[\]]: /r")]
|
||||
public void TestLabel(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[a]: /r ()")]
|
||||
[TestCase("[a]: /r (t)")]
|
||||
[TestCase("[a]: /r ( t)")]
|
||||
[TestCase("[a]: /r (t )")]
|
||||
[TestCase("[a]: /r ( t )")]
|
||||
|
||||
[TestCase("[a]: /r ''")]
|
||||
[TestCase("[a]: /r 't'")]
|
||||
[TestCase("[a]: /r ' t'")]
|
||||
[TestCase("[a]: /r 't '")]
|
||||
[TestCase("[a]: /r ' t '")]
|
||||
public void Test_Title(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("[a]: /r\n===\n[a]")]
|
||||
public void TestSetextHeader(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/Markdig.Tests/RoundtripSpecs/TestNoBlocksFoundBlock.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestNoBlocksFoundBlock
|
||||
{
|
||||
[TestCase("\r")]
|
||||
[TestCase("\n")]
|
||||
[TestCase("\r\n")]
|
||||
[TestCase("\t")]
|
||||
[TestCase("\v")]
|
||||
[TestCase("\f")]
|
||||
[TestCase(" ")]
|
||||
[TestCase(" ")]
|
||||
[TestCase(" ")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
191
src/Markdig.Tests/RoundtripSpecs/TestOrderedList.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestOrderedList
|
||||
{
|
||||
[TestCase("1. i")]
|
||||
[TestCase("1. i")]
|
||||
[TestCase("1. i ")]
|
||||
[TestCase("1. i ")]
|
||||
[TestCase("1. i ")]
|
||||
|
||||
[TestCase(" 1. i")]
|
||||
[TestCase(" 1. i")]
|
||||
[TestCase(" 1. i ")]
|
||||
[TestCase(" 1. i ")]
|
||||
[TestCase(" 1. i ")]
|
||||
|
||||
[TestCase(" 1. i")]
|
||||
[TestCase(" 1. i")]
|
||||
[TestCase(" 1. i ")]
|
||||
[TestCase(" 1. i ")]
|
||||
[TestCase(" 1. i ")]
|
||||
|
||||
[TestCase(" 1. i")]
|
||||
[TestCase(" 1. i")]
|
||||
[TestCase(" 1. i ")]
|
||||
[TestCase(" 1. i ")]
|
||||
[TestCase(" 1. i ")]
|
||||
|
||||
[TestCase("1. i\n")]
|
||||
[TestCase("1. i\n")]
|
||||
[TestCase("1. i \n")]
|
||||
[TestCase("1. i \n")]
|
||||
[TestCase("1. i \n")]
|
||||
|
||||
[TestCase(" 1. i\n")]
|
||||
[TestCase(" 1. i\n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
|
||||
[TestCase(" 1. i\n")]
|
||||
[TestCase(" 1. i\n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
|
||||
[TestCase(" 1. i\n")]
|
||||
[TestCase(" 1. i\n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
[TestCase(" 1. i \n")]
|
||||
|
||||
[TestCase("1. i\n2. j")]
|
||||
[TestCase("1. i\n2. j")]
|
||||
[TestCase("1. i \n2. j")]
|
||||
[TestCase("1. i \n2. j")]
|
||||
[TestCase("1. i \n2. j")]
|
||||
|
||||
[TestCase(" 1. i\n2. j")]
|
||||
[TestCase(" 1. i\n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
|
||||
[TestCase(" 1. i\n2. j")]
|
||||
[TestCase(" 1. i\n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
|
||||
[TestCase(" 1. i\n2. j")]
|
||||
[TestCase(" 1. i\n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
[TestCase(" 1. i \n2. j")]
|
||||
|
||||
[TestCase("1. i\n2. j\n")]
|
||||
[TestCase("1. i\n2. j\n")]
|
||||
[TestCase("1. i \n2. j\n")]
|
||||
[TestCase("1. i \n2. j\n")]
|
||||
[TestCase("1. i \n2. j\n")]
|
||||
|
||||
[TestCase(" 1. i\n2. j\n")]
|
||||
[TestCase(" 1. i\n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
|
||||
[TestCase(" 1. i\n2. j\n")]
|
||||
[TestCase(" 1. i\n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
|
||||
[TestCase(" 1. i\n2. j\n")]
|
||||
[TestCase(" 1. i\n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
[TestCase(" 1. i \n2. j\n")]
|
||||
|
||||
[TestCase("1. i\n2. j\n3. k")]
|
||||
[TestCase("1. i\n2. j\n3. k\n")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("10. i")]
|
||||
[TestCase("11. i")]
|
||||
[TestCase("10. i\n12. i")]
|
||||
[TestCase("2. i\n3. i")]
|
||||
public void Test_MoreThenOneStart(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
|
||||
[TestCase("\n1. i")]
|
||||
[TestCase("\r1. i")]
|
||||
[TestCase("\r\n1. i")]
|
||||
|
||||
[TestCase("\n1. i\n")]
|
||||
[TestCase("\r1. i\n")]
|
||||
[TestCase("\r\n1. i\n")]
|
||||
|
||||
[TestCase("\n1. i\r")]
|
||||
[TestCase("\r1. i\r")]
|
||||
[TestCase("\r\n1. i\r")]
|
||||
|
||||
[TestCase("\n1. i\r\n")]
|
||||
[TestCase("\r1. i\r\n")]
|
||||
[TestCase("\r\n1. i\r\n")]
|
||||
|
||||
[TestCase("1. i\n2. i")]
|
||||
[TestCase("\n1. i\n2. i")]
|
||||
[TestCase("\r1. i\n2. i")]
|
||||
[TestCase("\r\n1. i\n2. i")]
|
||||
|
||||
[TestCase("1. i\r2. i")]
|
||||
[TestCase("\n1. i\r2. i")]
|
||||
[TestCase("\r1. i\r2. i")]
|
||||
[TestCase("\r\n1. i\r2. i")]
|
||||
|
||||
[TestCase("1. i\r\n2. i")]
|
||||
[TestCase("\n1. i\r\n2. i")]
|
||||
[TestCase("\r1. i\r\n2. i")]
|
||||
[TestCase("\r\n1. i\r\n2. i")]
|
||||
|
||||
[TestCase("1. i\n2. i\n")]
|
||||
[TestCase("\n1. i\n2. i\n")]
|
||||
[TestCase("\r1. i\n2. i\n")]
|
||||
[TestCase("\r\n1. i\n2. i\n")]
|
||||
|
||||
[TestCase("1. i\r2. i\r")]
|
||||
[TestCase("\n1. i\r2. i\r")]
|
||||
[TestCase("\r1. i\r2. i\r")]
|
||||
[TestCase("\r\n1. i\r2. i\r")]
|
||||
|
||||
[TestCase("1. i\r\n2. i\r\n")]
|
||||
[TestCase("\n1. i\r\n2. i\r\n")]
|
||||
[TestCase("\r1. i\r\n2. i\r\n")]
|
||||
[TestCase("\r\n1. i\r\n2. i\r\n")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("1. i\n 1. i")]
|
||||
[TestCase("1. i\n 1. i\n")]
|
||||
[TestCase("1. i\n 1. i\n 2. i")]
|
||||
[TestCase("1. i\n 2. i\n 3. i")]
|
||||
|
||||
[TestCase("1. i\n\t1. i")]
|
||||
[TestCase("1. i\n\t1. i\n2. i")]
|
||||
public void TestMultipleLevels(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("1. c")]
|
||||
[TestCase("1. c")]
|
||||
public void Test_IndentedCodeBlock(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
247
src/Markdig.Tests/RoundtripSpecs/TestParagraph.cs
Normal file
@@ -0,0 +1,247 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestParagraph
|
||||
{
|
||||
[TestCase("p")]
|
||||
[TestCase(" p")]
|
||||
[TestCase("p ")]
|
||||
[TestCase(" p ")]
|
||||
|
||||
[TestCase("p\np")]
|
||||
[TestCase(" p\np")]
|
||||
[TestCase("p \np")]
|
||||
[TestCase(" p \np")]
|
||||
|
||||
[TestCase("p\n p")]
|
||||
[TestCase(" p\n p")]
|
||||
[TestCase("p \n p")]
|
||||
[TestCase(" p \n p")]
|
||||
|
||||
[TestCase("p\np ")]
|
||||
[TestCase(" p\np ")]
|
||||
[TestCase("p \np ")]
|
||||
[TestCase(" p \np ")]
|
||||
|
||||
[TestCase("p\n\n p ")]
|
||||
[TestCase(" p\n\n p ")]
|
||||
[TestCase("p \n\n p ")]
|
||||
[TestCase(" p \n\n p ")]
|
||||
|
||||
[TestCase("p\n\np")]
|
||||
[TestCase(" p\n\np")]
|
||||
[TestCase("p \n\np")]
|
||||
[TestCase(" p \n\np")]
|
||||
|
||||
[TestCase("p\n\n p")]
|
||||
[TestCase(" p\n\n p")]
|
||||
[TestCase("p \n\n p")]
|
||||
[TestCase(" p \n\n p")]
|
||||
|
||||
[TestCase("p\n\np ")]
|
||||
[TestCase(" p\n\np ")]
|
||||
[TestCase("p \n\np ")]
|
||||
[TestCase(" p \n\np ")]
|
||||
|
||||
[TestCase("p\n\n p ")]
|
||||
[TestCase(" p\n\n p ")]
|
||||
[TestCase("p \n\n p ")]
|
||||
[TestCase(" p \n\n p ")]
|
||||
|
||||
[TestCase("\np")]
|
||||
[TestCase("\n p")]
|
||||
[TestCase("\np ")]
|
||||
[TestCase("\n p ")]
|
||||
|
||||
[TestCase("\np\np")]
|
||||
[TestCase("\n p\np")]
|
||||
[TestCase("\np \np")]
|
||||
[TestCase("\n p \np")]
|
||||
|
||||
[TestCase("\np\n p")]
|
||||
[TestCase("\n p\n p")]
|
||||
[TestCase("\np \n p")]
|
||||
[TestCase("\n p \n p")]
|
||||
|
||||
[TestCase("\np\np ")]
|
||||
[TestCase("\n p\np ")]
|
||||
[TestCase("\np \np ")]
|
||||
[TestCase("\n p \np ")]
|
||||
|
||||
[TestCase("\np\n\n p ")]
|
||||
[TestCase("\n p\n\n p ")]
|
||||
[TestCase("\np \n\n p ")]
|
||||
[TestCase("\n p \n\n p ")]
|
||||
|
||||
[TestCase("\np\n\np")]
|
||||
[TestCase("\n p\n\np")]
|
||||
[TestCase("\np \n\np")]
|
||||
[TestCase("\n p \n\np")]
|
||||
|
||||
[TestCase("\np\n\n p")]
|
||||
[TestCase("\n p\n\n p")]
|
||||
[TestCase("\np \n\n p")]
|
||||
[TestCase("\n p \n\n p")]
|
||||
|
||||
[TestCase("\np\n\np ")]
|
||||
[TestCase("\n p\n\np ")]
|
||||
[TestCase("\np \n\np ")]
|
||||
[TestCase("\n p \n\np ")]
|
||||
|
||||
[TestCase("\np\n\n p ")]
|
||||
[TestCase("\n p\n\n p ")]
|
||||
[TestCase("\np \n\n p ")]
|
||||
[TestCase("\n p \n\n p ")]
|
||||
|
||||
[TestCase("p p")]
|
||||
[TestCase("p\tp")]
|
||||
[TestCase("p \tp")]
|
||||
[TestCase("p \t p")]
|
||||
[TestCase("p \tp")]
|
||||
|
||||
// special cases
|
||||
[TestCase(" p \n\n\n\n p \n\n")]
|
||||
[TestCase("\n\np")]
|
||||
[TestCase("p\n")]
|
||||
[TestCase("p\n\n")]
|
||||
[TestCase("p\np\n p")]
|
||||
[TestCase("p\np\n p\n p")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
|
||||
[TestCase("\n")]
|
||||
[TestCase("\r\n")]
|
||||
[TestCase("\r")]
|
||||
|
||||
[TestCase("p\n")]
|
||||
[TestCase("p\r")]
|
||||
[TestCase("p\r\n")]
|
||||
|
||||
[TestCase("p\np")]
|
||||
[TestCase("p\rp")]
|
||||
[TestCase("p\r\np")]
|
||||
|
||||
[TestCase("p\np\n")]
|
||||
[TestCase("p\rp\n")]
|
||||
[TestCase("p\r\np\n")]
|
||||
|
||||
[TestCase("p\np\r")]
|
||||
[TestCase("p\rp\r")]
|
||||
[TestCase("p\r\np\r")]
|
||||
|
||||
[TestCase("p\np\r\n")]
|
||||
[TestCase("p\rp\r\n")]
|
||||
[TestCase("p\r\np\r\n")]
|
||||
|
||||
[TestCase("\np\n")]
|
||||
[TestCase("\np\r")]
|
||||
[TestCase("\np\r\n")]
|
||||
|
||||
[TestCase("\np\np")]
|
||||
[TestCase("\np\rp")]
|
||||
[TestCase("\np\r\np")]
|
||||
|
||||
[TestCase("\np\np\n")]
|
||||
[TestCase("\np\rp\n")]
|
||||
[TestCase("\np\r\np\n")]
|
||||
|
||||
[TestCase("\np\np\r")]
|
||||
[TestCase("\np\rp\r")]
|
||||
[TestCase("\np\r\np\r")]
|
||||
|
||||
[TestCase("\np\np\r\n")]
|
||||
[TestCase("\np\rp\r\n")]
|
||||
[TestCase("\np\r\np\r\n")]
|
||||
|
||||
[TestCase("\rp\n")]
|
||||
[TestCase("\rp\r")]
|
||||
[TestCase("\rp\r\n")]
|
||||
|
||||
[TestCase("\rp\np")]
|
||||
[TestCase("\rp\rp")]
|
||||
[TestCase("\rp\r\np")]
|
||||
|
||||
[TestCase("\rp\np\n")]
|
||||
[TestCase("\rp\rp\n")]
|
||||
[TestCase("\rp\r\np\n")]
|
||||
|
||||
[TestCase("\rp\np\r")]
|
||||
[TestCase("\rp\rp\r")]
|
||||
[TestCase("\rp\r\np\r")]
|
||||
|
||||
[TestCase("\rp\np\r\n")]
|
||||
[TestCase("\rp\rp\r\n")]
|
||||
[TestCase("\rp\r\np\r\n")]
|
||||
|
||||
[TestCase("\r\np\n")]
|
||||
[TestCase("\r\np\r")]
|
||||
[TestCase("\r\np\r\n")]
|
||||
|
||||
[TestCase("\r\np\np")]
|
||||
[TestCase("\r\np\rp")]
|
||||
[TestCase("\r\np\r\np")]
|
||||
|
||||
[TestCase("\r\np\np\n")]
|
||||
[TestCase("\r\np\rp\n")]
|
||||
[TestCase("\r\np\r\np\n")]
|
||||
|
||||
[TestCase("\r\np\np\r")]
|
||||
[TestCase("\r\np\rp\r")]
|
||||
[TestCase("\r\np\r\np\r")]
|
||||
|
||||
[TestCase("\r\np\np\r\n")]
|
||||
[TestCase("\r\np\rp\r\n")]
|
||||
[TestCase("\r\np\r\np\r\n")]
|
||||
|
||||
[TestCase("p\n")]
|
||||
[TestCase("p\n\n")]
|
||||
[TestCase("p\n\n\n")]
|
||||
[TestCase("p\n\n\n\n")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase(" \n")]
|
||||
[TestCase(" \r")]
|
||||
[TestCase(" \r\n")]
|
||||
|
||||
[TestCase(" \np")]
|
||||
[TestCase(" \rp")]
|
||||
[TestCase(" \r\np")]
|
||||
|
||||
[TestCase(" \np")]
|
||||
[TestCase(" \rp")]
|
||||
[TestCase(" \r\np")]
|
||||
|
||||
[TestCase(" \np")]
|
||||
[TestCase(" \rp")]
|
||||
[TestCase(" \r\np")]
|
||||
|
||||
[TestCase(" \n ")]
|
||||
[TestCase(" \r ")]
|
||||
[TestCase(" \r\n ")]
|
||||
|
||||
[TestCase(" \np ")]
|
||||
[TestCase(" \rp ")]
|
||||
[TestCase(" \r\np ")]
|
||||
|
||||
[TestCase(" \np ")]
|
||||
[TestCase(" \rp ")]
|
||||
[TestCase(" \r\np ")]
|
||||
|
||||
[TestCase(" \np ")]
|
||||
[TestCase(" \rp ")]
|
||||
[TestCase(" \r\np ")]
|
||||
public void Test_WhitespaceWithNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
286
src/Markdig.Tests/RoundtripSpecs/TestQuoteBlock.cs
Normal file
@@ -0,0 +1,286 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestQuoteBlock
|
||||
{
|
||||
[TestCase(">q")]
|
||||
[TestCase(" >q")]
|
||||
[TestCase(" >q")]
|
||||
[TestCase(" >q")]
|
||||
[TestCase("> q")]
|
||||
[TestCase(" > q")]
|
||||
[TestCase(" > q")]
|
||||
[TestCase(" > q")]
|
||||
[TestCase("> q")]
|
||||
[TestCase(" > q")]
|
||||
[TestCase(" > q")]
|
||||
[TestCase(" > q")]
|
||||
|
||||
[TestCase(">q\n>q")]
|
||||
[TestCase(">q\n >q")]
|
||||
[TestCase(">q\n >q")]
|
||||
[TestCase(">q\n >q")]
|
||||
[TestCase(">q\n> q")]
|
||||
[TestCase(">q\n > q")]
|
||||
[TestCase(">q\n > q")]
|
||||
[TestCase(">q\n > q")]
|
||||
[TestCase(">q\n> q")]
|
||||
[TestCase(">q\n > q")]
|
||||
[TestCase(">q\n > q")]
|
||||
[TestCase(">q\n > q")]
|
||||
|
||||
[TestCase(" >q\n>q")]
|
||||
[TestCase(" >q\n >q")]
|
||||
[TestCase(" >q\n >q")]
|
||||
[TestCase(" >q\n >q")]
|
||||
[TestCase(" >q\n> q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n> q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
|
||||
[TestCase(" >q\n>q")]
|
||||
[TestCase(" >q\n >q")]
|
||||
[TestCase(" >q\n >q")]
|
||||
[TestCase(" >q\n >q")]
|
||||
[TestCase(" >q\n> q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n> q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
[TestCase(" >q\n > q")]
|
||||
|
||||
[TestCase("> q\n>q")]
|
||||
[TestCase("> q\n >q")]
|
||||
[TestCase("> q\n >q")]
|
||||
[TestCase("> q\n >q")]
|
||||
[TestCase("> q\n> q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n> q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n > q")]
|
||||
|
||||
[TestCase(" > q\n>q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
|
||||
[TestCase(" > q\n>q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
|
||||
[TestCase(" > q\n>q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
|
||||
[TestCase("> q\n>q")]
|
||||
[TestCase("> q\n >q")]
|
||||
[TestCase("> q\n >q")]
|
||||
[TestCase("> q\n >q")]
|
||||
[TestCase("> q\n> q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n> q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n > q")]
|
||||
[TestCase("> q\n > q")]
|
||||
|
||||
[TestCase(" > q\n>q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
|
||||
[TestCase(" > q\n>q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
|
||||
[TestCase(" > q\n>q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n >q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n> q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
[TestCase(" > q\n > q")]
|
||||
|
||||
[TestCase(">q\n>q\n>q")]
|
||||
[TestCase(">q\n>\n>q")]
|
||||
[TestCase(">q\np\n>q")]
|
||||
[TestCase(">q\n>\n>\n>q")]
|
||||
[TestCase(">q\n>\n>\n>\n>q")]
|
||||
[TestCase(">q\n>\n>q\n>\n>q")]
|
||||
[TestCase("p\n\n> **q**\n>p\n")]
|
||||
|
||||
[TestCase("> q\np\n> q")] // lazy
|
||||
[TestCase("> q\n> q\np")] // lazy
|
||||
|
||||
[TestCase(">>q")]
|
||||
[TestCase(" > > q")]
|
||||
|
||||
[TestCase("> **q**\n>p\n")]
|
||||
[TestCase("> **q**")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("> q")] // 5
|
||||
[TestCase("> q")] // 6
|
||||
[TestCase(" > q")] //5
|
||||
[TestCase(" > q")] //6
|
||||
[TestCase(" > \tq")]
|
||||
[TestCase("> q\n> q")] // 5, 5
|
||||
[TestCase("> q\n> q")] // 5, 6
|
||||
[TestCase("> q\n> q")] // 6, 5
|
||||
[TestCase("> q\n> q")] // 6, 6
|
||||
[TestCase("> q\n\n> 5")] // 5, 5
|
||||
public void TestIndentedCodeBlock(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("\n> q")]
|
||||
[TestCase("\n> q\n")]
|
||||
[TestCase("\n> q\n\n")]
|
||||
[TestCase("> q\n\np")]
|
||||
[TestCase("p\n\n> q\n\n# h")]
|
||||
|
||||
//https://github.com/lunet-io/markdig/issues/480
|
||||
//[TestCase(">\np")]
|
||||
//[TestCase(">**b**\n>\n>p\n>\np\n")]
|
||||
public void TestParagraph(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("> q\n\n# h\n")]
|
||||
public void TestAtxHeader(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase(">- i")]
|
||||
[TestCase("> - i")]
|
||||
[TestCase(">- i\n>- i")]
|
||||
[TestCase(">- >p")]
|
||||
[TestCase("> - >p")]
|
||||
[TestCase(">- i1\n>- i2\n")]
|
||||
[TestCase("> **p** p\n>- i1\n>- i2\n")]
|
||||
public void TestUnorderedList(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("> *q*\n>p\n")]
|
||||
[TestCase("> *q*")]
|
||||
public void TestEmphasis(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("> **q**\n>p\n")]
|
||||
[TestCase("> **q**")]
|
||||
public void TestStrongEmphasis(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase(">p\n")]
|
||||
[TestCase(">p\r")]
|
||||
[TestCase(">p\r\n")]
|
||||
|
||||
[TestCase(">p\n>p")]
|
||||
[TestCase(">p\r>p")]
|
||||
[TestCase(">p\r\n>p")]
|
||||
|
||||
[TestCase(">p\n>p\n")]
|
||||
[TestCase(">p\r>p\n")]
|
||||
[TestCase(">p\r\n>p\n")]
|
||||
|
||||
[TestCase(">p\n>p\r")]
|
||||
[TestCase(">p\r>p\r")]
|
||||
[TestCase(">p\r\n>p\r")]
|
||||
|
||||
[TestCase(">p\n>p\r\n")]
|
||||
[TestCase(">p\r>p\r\n")]
|
||||
[TestCase(">p\r\n>p\r\n")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase(">\n>q")]
|
||||
[TestCase(">\n>\n>q")]
|
||||
[TestCase(">q\n>\n>q")]
|
||||
[TestCase(">q\n>\n>\n>q")]
|
||||
[TestCase(">q\n> \n>q")]
|
||||
[TestCase(">q\n> \n>q")]
|
||||
[TestCase(">q\n> \n>q")]
|
||||
[TestCase(">q\n>\t\n>q")]
|
||||
[TestCase(">q\n>\v\n>q")]
|
||||
[TestCase(">q\n>\f\n>q")]
|
||||
public void TestEmptyLines(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/Markdig.Tests/RoundtripSpecs/TestSetextHeading.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSetextHeading
|
||||
{
|
||||
[TestCase("h1\n===")] //3
|
||||
[TestCase("h1\n ===")] //3
|
||||
[TestCase("h1\n ===")] //3
|
||||
[TestCase("h1\n ===")] //3
|
||||
[TestCase("h1\n=== ")] //3
|
||||
[TestCase("h1 \n===")] //3
|
||||
[TestCase("h1\\\n===")] //3
|
||||
[TestCase("h1\n === ")] //3
|
||||
[TestCase("h1\nh1 l2\n===")] //3
|
||||
[TestCase("h1\n====")] // 4
|
||||
[TestCase("h1\n ====")] // 4
|
||||
[TestCase("h1\n==== ")] // 4
|
||||
[TestCase("h1\n ==== ")] // 4
|
||||
[TestCase("h1\n===\nh1\n===")] //3
|
||||
[TestCase("\\>h1\n===")] //3
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("h1\r===")]
|
||||
[TestCase("h1\n===")]
|
||||
[TestCase("h1\r\n===")]
|
||||
|
||||
[TestCase("h1\r===\r")]
|
||||
[TestCase("h1\n===\r")]
|
||||
[TestCase("h1\r\n===\r")]
|
||||
|
||||
[TestCase("h1\r===\n")]
|
||||
[TestCase("h1\n===\n")]
|
||||
[TestCase("h1\r\n===\n")]
|
||||
|
||||
[TestCase("h1\r===\r\n")]
|
||||
[TestCase("h1\n===\r\n")]
|
||||
[TestCase("h1\r\n===\r\n")]
|
||||
|
||||
[TestCase("h1\n===\n\n\nh2---\n\n")]
|
||||
[TestCase("h1\r===\r\r\rh2---\r\r")]
|
||||
[TestCase("h1\r\n===\r\n\r\n\r\nh2---\r\n\r\n")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/Markdig.Tests/RoundtripSpecs/TestThematicBreak.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestThematicBreak
|
||||
{
|
||||
[TestCase("---")]
|
||||
[TestCase(" ---")]
|
||||
[TestCase(" ---")]
|
||||
[TestCase(" ---")]
|
||||
[TestCase("--- ")]
|
||||
[TestCase(" --- ")]
|
||||
[TestCase(" --- ")]
|
||||
[TestCase(" --- ")]
|
||||
[TestCase("- - -")]
|
||||
[TestCase(" - - -")]
|
||||
[TestCase(" - - - ")]
|
||||
[TestCase("-- -")]
|
||||
[TestCase("---\n")]
|
||||
[TestCase("---\n\n")]
|
||||
[TestCase("---\np")]
|
||||
[TestCase("---\n\np")]
|
||||
[TestCase("---\n# h")]
|
||||
[TestCase("p\n\n---")]
|
||||
// Note: "p\n---" is parsed as setext heading
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("\n---")]
|
||||
[TestCase("\r---")]
|
||||
[TestCase("\r\n---")]
|
||||
|
||||
[TestCase("\n---\n")]
|
||||
[TestCase("\r---\n")]
|
||||
[TestCase("\r\n---\n")]
|
||||
|
||||
[TestCase("\n---\r")]
|
||||
[TestCase("\r---\r")]
|
||||
[TestCase("\r\n---\r")]
|
||||
|
||||
[TestCase("\n---\r\n")]
|
||||
[TestCase("\r---\r\n")]
|
||||
[TestCase("\r\n---\r\n")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
183
src/Markdig.Tests/RoundtripSpecs/TestUnorderedList.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
using NUnit.Framework;
|
||||
using static Markdig.Tests.TestRoundtrip;
|
||||
|
||||
namespace Markdig.Tests.RoundtripSpecs
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestUnorderedList
|
||||
{
|
||||
// i = item
|
||||
[TestCase("- i1")]
|
||||
[TestCase("- i1 ")]
|
||||
[TestCase("- i1\n")]
|
||||
[TestCase("- i1\n\n")]
|
||||
[TestCase("- i1\n- i2")]
|
||||
[TestCase("- i1\n - i2")]
|
||||
[TestCase("- i1\n - i1.1\n - i1.2")]
|
||||
[TestCase("- i1 \n- i2 \n")]
|
||||
[TestCase("- i1 \n- i2 \n")]
|
||||
[TestCase(" - i1")]
|
||||
[TestCase(" - i1")]
|
||||
[TestCase(" - i1")]
|
||||
[TestCase("- i1\n\n- i1")]
|
||||
[TestCase("- i1\n\n\n- i1")]
|
||||
[TestCase("- i1\n - i1.1\n - i1.1.1\n")]
|
||||
|
||||
[TestCase("-\ti1")]
|
||||
[TestCase("-\ti1\n-\ti2")]
|
||||
[TestCase("-\ti1\n- i2\n-\ti3")]
|
||||
public void Test(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("- > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase("- > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase("- > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase("- > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q")]
|
||||
[TestCase(" - > q1\n - > q2")]
|
||||
public void TestBlockQuote(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("- i1\n\np\n")] // TODO: listblock should render newline, apparently last paragraph of last listitem dont have newline
|
||||
[TestCase("- i1\n\n\np\n")]
|
||||
[TestCase("- i1\n\np")]
|
||||
[TestCase("- i1\n\np\n")]
|
||||
public void TestParagraph(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("- i1\n\n---\n")]
|
||||
[TestCase("- i1\n\n\n---\n")]
|
||||
public void TestThematicBreak(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("- c")] // 5
|
||||
[TestCase("- c\n c")] // 5, 6
|
||||
[TestCase(" - c\n c")] // 5, 6
|
||||
[TestCase(" - c\n c")] // 5, 7
|
||||
[TestCase("- c\n c")] // 6, 6
|
||||
[TestCase(" - c\n c")] // 6, 6
|
||||
[TestCase(" - c\n c")] // 6, 7
|
||||
public void TestIndentedCodeBlock(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("- ```a```")]
|
||||
[TestCase("- ```\n a\n```")]
|
||||
[TestCase("- i1\n - i1.1\n ```\n c\n ```")]
|
||||
[TestCase("- i1\n - i1.1\n ```\nc\n```")]
|
||||
[TestCase("- i1\n - i1.1\n ```\nc\n```\n")]
|
||||
public void TestFencedCodeBlock(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
|
||||
[TestCase("\n- i")]
|
||||
[TestCase("\r- i")]
|
||||
[TestCase("\r\n- i")]
|
||||
|
||||
[TestCase("\n- i\n")]
|
||||
[TestCase("\r- i\n")]
|
||||
[TestCase("\r\n- i\n")]
|
||||
|
||||
[TestCase("\n- i\r")]
|
||||
[TestCase("\r- i\r")]
|
||||
[TestCase("\r\n- i\r")]
|
||||
|
||||
[TestCase("\n- i\r\n")]
|
||||
[TestCase("\r- i\r\n")]
|
||||
[TestCase("\r\n- i\r\n")]
|
||||
|
||||
[TestCase("- i\n- j")]
|
||||
[TestCase("- i\r- j")]
|
||||
[TestCase("- i\r\n- j")]
|
||||
|
||||
[TestCase("\n- i\n- j")]
|
||||
[TestCase("\n- i\r- j")]
|
||||
[TestCase("\n- i\r\n- j")]
|
||||
|
||||
[TestCase("\r- i\n- j")]
|
||||
[TestCase("\r- i\r- j")]
|
||||
[TestCase("\r- i\r\n- j")]
|
||||
|
||||
[TestCase("\r\n- i\n- j")]
|
||||
[TestCase("\r\n- i\r- j")]
|
||||
[TestCase("\r\n- i\r\n- j")]
|
||||
|
||||
[TestCase("- i\n- j\n")]
|
||||
[TestCase("- i\r- j\n")]
|
||||
[TestCase("- i\r\n- j\n")]
|
||||
|
||||
[TestCase("\n- i\n- j\n")]
|
||||
[TestCase("\n- i\r- j\n")]
|
||||
[TestCase("\n- i\r\n- j\n")]
|
||||
|
||||
[TestCase("\r- i\n- j\n")]
|
||||
[TestCase("\r- i\r- j\n")]
|
||||
[TestCase("\r- i\r\n- j\n")]
|
||||
|
||||
[TestCase("\r\n- i\n- j\n")]
|
||||
[TestCase("\r\n- i\r- j\n")]
|
||||
[TestCase("\r\n- i\r\n- j\n")]
|
||||
|
||||
[TestCase("- i\n- j\r")]
|
||||
[TestCase("- i\r- j\r")]
|
||||
[TestCase("- i\r\n- j\r")]
|
||||
|
||||
[TestCase("\n- i\n- j\r")]
|
||||
[TestCase("\n- i\r- j\r")]
|
||||
[TestCase("\n- i\r\n- j\r")]
|
||||
|
||||
[TestCase("\r- i\n- j\r")]
|
||||
[TestCase("\r- i\r- j\r")]
|
||||
[TestCase("\r- i\r\n- j\r")]
|
||||
|
||||
[TestCase("\r\n- i\n- j\r")]
|
||||
[TestCase("\r\n- i\r- j\r")]
|
||||
[TestCase("\r\n- i\r\n- j\r")]
|
||||
|
||||
[TestCase("- i\n- j\r\n")]
|
||||
[TestCase("- i\r- j\r\n")]
|
||||
[TestCase("- i\r\n- j\r\n")]
|
||||
|
||||
[TestCase("\n- i\n- j\r\n")]
|
||||
[TestCase("\n- i\r- j\r\n")]
|
||||
[TestCase("\n- i\r\n- j\r\n")]
|
||||
|
||||
[TestCase("\r- i\n- j\r\n")]
|
||||
[TestCase("\r- i\r- j\r\n")]
|
||||
[TestCase("\r- i\r\n- j\r\n")]
|
||||
|
||||
[TestCase("\r\n- i\n- j\r\n")]
|
||||
[TestCase("\r\n- i\r- j\r\n")]
|
||||
[TestCase("\r\n- i\r\n- j\r\n")]
|
||||
|
||||
[TestCase("- i\n")]
|
||||
[TestCase("- i\n\n")]
|
||||
[TestCase("- i\n\n\n")]
|
||||
[TestCase("- i\n\n\n\n")]
|
||||
public void TestNewline(string value)
|
||||
{
|
||||
RoundTrip(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
235
src/Markdig.Tests/Specs/AbbreviationSpecs.generated.cs
Normal file
@@ -0,0 +1,235 @@
|
||||
|
||||
// --------------------------------
|
||||
// Abbreviations
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.Abbreviations
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsAbbreviation
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Abbreviation
|
||||
//
|
||||
// Abbreviation can be declared by using the `*[Abbreviation Label]: Abbreviation description`
|
||||
//
|
||||
// Abbreviation definition will be removed from the original document. Any Abbreviation label found in literals will be replaced by the abbreviation description:
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[HTML]: Hypertext Markup Language
|
||||
//
|
||||
// Later in a text we are using HTML and it becomes an abbr tag HTML
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Later in a text we are using <abbr title="Hypertext Markup Language">HTML</abbr> and it becomes an abbr tag <abbr title="Hypertext Markup Language">HTML</abbr></p>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[HTML]: Hypertext Markup Language\n\nLater in a text we are using HTML and it becomes an abbr tag HTML", "<p>Later in a text we are using <abbr title=\"Hypertext Markup Language\">HTML</abbr> and it becomes an abbr tag <abbr title=\"Hypertext Markup Language\">HTML</abbr></p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// An abbreviation definition can be indented at most 3 spaces
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[HTML]: Hypertext Markup Language
|
||||
// *[This]: is not an abbreviation
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <pre><code>*[This]: is not an abbreviation
|
||||
// </code></pre>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[HTML]: Hypertext Markup Language\n *[This]: is not an abbreviation", "<pre><code>*[This]: is not an abbreviation\n</code></pre>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// An abbreviation may contain spaces:
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[SUPER HTML]: Super Hypertext Markup Language
|
||||
//
|
||||
// This is a SUPER HTML document
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <abbr title="Super Hypertext Markup Language">SUPER HTML</abbr> document</p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[SUPER HTML]: Super Hypertext Markup Language\n\nThis is a SUPER HTML document ", "<p>This is a <abbr title=\"Super Hypertext Markup Language\">SUPER HTML</abbr> document</p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// Abbreviation may contain any unicode characters:
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[😃 HTML]: Hypertext Markup Language
|
||||
//
|
||||
// This is a 😃 HTML document
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <abbr title="Hypertext Markup Language">😃 HTML</abbr> document</p>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[😃 HTML]: Hypertext Markup Language\n\nThis is a 😃 HTML document ", "<p>This is a <abbr title=\"Hypertext Markup Language\">😃 HTML</abbr> document</p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// Abbreviations may be similar:
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[1A]: First
|
||||
// *[1A1]: Second
|
||||
// *[1A2]: Third
|
||||
//
|
||||
// We can abbreviate 1A, 1A1 and 1A2!
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>We can abbreviate <abbr title="First">1A</abbr>, <abbr title="Second">1A1</abbr> and <abbr title="Third">1A2</abbr>!</p>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[1A]: First\n*[1A1]: Second\n*[1A2]: Third\n\nWe can abbreviate 1A, 1A1 and 1A2!", "<p>We can abbreviate <abbr title=\"First\">1A</abbr>, <abbr title=\"Second\">1A1</abbr> and <abbr title=\"Third\">1A2</abbr>!</p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// Abbreviations should match whole word only:
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[1A]: First
|
||||
//
|
||||
// We should not abbreviate 1.1A or 11A!
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>We should not abbreviate 1.1A or 11A!</p>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[1A]: First\n\nWe should not abbreviate 1.1A or 11A!", "<p>We should not abbreviate 1.1A or 11A!</p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// Abbreviations should match whole word only, even if the word is the entire content:
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[1A]: First
|
||||
//
|
||||
// 1.1A
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>1.1A</p>
|
||||
|
||||
Console.WriteLine("Example 7\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[1A]: First\n\n1.1A", "<p>1.1A</p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// Abbreviations should match whole word only, even if there is another glossary term:
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[SCO]: First
|
||||
// *[SCOM]: Second
|
||||
//
|
||||
// SCOM
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><abbr title="Second">SCOM</abbr></p>
|
||||
|
||||
Console.WriteLine("Example 8\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[SCO]: First\n*[SCOM]: Second\n\nSCOM", "<p><abbr title=\"Second\">SCOM</abbr></p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// Abbreviations should only match when surrounded by whitespace:
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example009()
|
||||
{
|
||||
// Example 9
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[PR]: Pull Request
|
||||
//
|
||||
// PRAA
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>PRAA</p>
|
||||
|
||||
Console.WriteLine("Example 9\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[PR]: Pull Request\n\nPRAA", "<p>PRAA</p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// Single character abbreviations should be matched
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example010()
|
||||
{
|
||||
// Example 10
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[A]: Foo
|
||||
//
|
||||
// A
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><abbr title="Foo">A</abbr></p>
|
||||
|
||||
Console.WriteLine("Example 10\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[A]: Foo\n\nA", "<p><abbr title=\"Foo\">A</abbr></p>", "abbreviations|advanced");
|
||||
}
|
||||
|
||||
// The longest matching abbreviation should be used
|
||||
[Test]
|
||||
public void ExtensionsAbbreviation_Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions / Abbreviation
|
||||
//
|
||||
// The following Markdown:
|
||||
// *[Foo]: foo
|
||||
// *[Foo Bar]: foobar
|
||||
//
|
||||
// Foo B
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><abbr title="foo">Foo</abbr> B</p>
|
||||
|
||||
Console.WriteLine("Example 11\nSection Extensions / Abbreviation\n");
|
||||
TestParser.TestSpec("*[Foo]: foo\n*[Foo Bar]: foobar\n\nFoo B", "<p><abbr title=\"foo\">Foo</abbr> B</p>", "abbreviations|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,3 +45,77 @@ This is a 😃 HTML document
|
||||
.
|
||||
<p>This is a <abbr title="Hypertext Markup Language">😃 HTML</abbr> document</p>
|
||||
````````````````````````````````
|
||||
|
||||
Abbreviations may be similar:
|
||||
|
||||
```````````````````````````````` example
|
||||
*[1A]: First
|
||||
*[1A1]: Second
|
||||
*[1A2]: Third
|
||||
|
||||
We can abbreviate 1A, 1A1 and 1A2!
|
||||
.
|
||||
<p>We can abbreviate <abbr title="First">1A</abbr>, <abbr title="Second">1A1</abbr> and <abbr title="Third">1A2</abbr>!</p>
|
||||
````````````````````````````````
|
||||
|
||||
Abbreviations should match whole word only:
|
||||
|
||||
```````````````````````````````` example
|
||||
*[1A]: First
|
||||
|
||||
We should not abbreviate 1.1A or 11A!
|
||||
.
|
||||
<p>We should not abbreviate 1.1A or 11A!</p>
|
||||
````````````````````````````````
|
||||
|
||||
Abbreviations should match whole word only, even if the word is the entire content:
|
||||
|
||||
```````````````````````````````` example
|
||||
*[1A]: First
|
||||
|
||||
1.1A
|
||||
.
|
||||
<p>1.1A</p>
|
||||
````````````````````````````````
|
||||
|
||||
Abbreviations should match whole word only, even if there is another glossary term:
|
||||
|
||||
```````````````````````````````` example
|
||||
*[SCO]: First
|
||||
*[SCOM]: Second
|
||||
|
||||
SCOM
|
||||
.
|
||||
<p><abbr title="Second">SCOM</abbr></p>
|
||||
````````````````````````````````
|
||||
|
||||
Abbreviations should only match when surrounded by whitespace:
|
||||
|
||||
```````````````````````````````` example
|
||||
*[PR]: Pull Request
|
||||
|
||||
PRAA
|
||||
.
|
||||
<p>PRAA</p>
|
||||
````````````````````````````````
|
||||
|
||||
Single character abbreviations should be matched
|
||||
|
||||
```````````````````````````````` example
|
||||
*[A]: Foo
|
||||
|
||||
A
|
||||
.
|
||||
<p><abbr title="Foo">A</abbr></p>
|
||||
````````````````````````````````
|
||||
|
||||
The longest matching abbreviation should be used
|
||||
|
||||
```````````````````````````````` example
|
||||
*[Foo]: foo
|
||||
*[Foo Bar]: foobar
|
||||
|
||||
Foo B
|
||||
.
|
||||
<p><abbr title="foo">Foo</abbr> B</p>
|
||||
````````````````````````````````
|
||||
223
src/Markdig.Tests/Specs/AutoIdentifierSpecs.generated.cs
Normal file
@@ -0,0 +1,223 @@
|
||||
|
||||
// --------------------------------
|
||||
// Auto Identifiers
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.AutoIdentifiers
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsHeadingAutoIdentifiers
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the auto identifier extension
|
||||
//
|
||||
// ## Heading Auto Identifiers
|
||||
//
|
||||
// Allows to automatically creates an identifier for a heading:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// # This is a heading
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="this-is-a-heading">This is a heading</h1>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("# This is a heading", "<h1 id=\"this-is-a-heading\">This is a heading</h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// Only punctuation `-`, `_` and `.` is kept, all other non letter characters are discarded.
|
||||
// Consecutive same character `-`, `_` or `.` are rendered into a single one
|
||||
// Characters `-`, `_` and `.` at the end of the string are also discarded.
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// # This - is a &@! heading _ with . and ! -
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="this-is-a-heading_with.and">This - is a &@! heading _ with . and ! -</h1>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("# This - is a &@! heading _ with . and ! -", "<h1 id=\"this-is-a-heading_with.and\">This - is a &@! heading _ with . and ! -</h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// Formatting (emphasis) are also discarded:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// # This is a *heading*
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="this-is-a-heading">This is a <em>heading</em></h1>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("# This is a *heading*", "<h1 id=\"this-is-a-heading\">This is a <em>heading</em></h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// Links are also removed:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// # This is a [heading](/url)
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="this-is-a-heading">This is a <a href="/url">heading</a></h1>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("# This is a [heading](/url)", "<h1 id=\"this-is-a-heading\">This is a <a href=\"/url\">heading</a></h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// If multiple heading have the same text, -1, -2...-n will be postfix to the header id.
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// # This is a heading
|
||||
// # This is a heading
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="this-is-a-heading">This is a heading</h1>
|
||||
// <h1 id="this-is-a-heading-1">This is a heading</h1>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("# This is a heading\n# This is a heading", "<h1 id=\"this-is-a-heading\">This is a heading</h1>\n<h1 id=\"this-is-a-heading-1\">This is a heading</h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// The heading Id will start on the first letter character of the heading, all previous characters will be discarded:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// # 1.0 This is a heading
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="this-is-a-heading">1.0 This is a heading</h1>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("# 1.0 This is a heading", "<h1 id=\"this-is-a-heading\">1.0 This is a heading</h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// If the heading is all stripped by the previous rules, the id `section` will be used instead:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// # 1.0 & ^ % *
|
||||
// # 1.0 & ^ % *
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="section">1.0 & ^ % *</h1>
|
||||
// <h1 id="section-1">1.0 & ^ % *</h1>
|
||||
|
||||
Console.WriteLine("Example 7\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("# 1.0 & ^ % *\n# 1.0 & ^ % *", "<h1 id=\"section\">1.0 & ^ % *</h1>\n<h1 id=\"section-1\">1.0 & ^ % *</h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// When the options "AutoLink" is setup, it is possible to link to an existing heading by using the
|
||||
// exact same Label text as the heading:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// # This is a heading
|
||||
// [This is a heading]
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="this-is-a-heading">This is a heading</h1>
|
||||
// <p><a href="#this-is-a-heading">This is a heading</a></p>
|
||||
|
||||
Console.WriteLine("Example 8\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("# This is a heading\n[This is a heading]", "<h1 id=\"this-is-a-heading\">This is a heading</h1>\n<p><a href=\"#this-is-a-heading\">This is a heading</a></p>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// Links before the heading are also working:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example009()
|
||||
{
|
||||
// Example 9
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// [This is a heading]
|
||||
// # This is a heading
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="#this-is-a-heading">This is a heading</a></p>
|
||||
// <h1 id="this-is-a-heading">This is a heading</h1>
|
||||
|
||||
Console.WriteLine("Example 9\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("[This is a heading]\n# This is a heading", "<p><a href=\"#this-is-a-heading\">This is a heading</a></p>\n<h1 id=\"this-is-a-heading\">This is a heading</h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// The text of the link can be changed:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example010()
|
||||
{
|
||||
// Example 10
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// [With a new text][This is a heading]
|
||||
// # This is a heading
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="#this-is-a-heading">With a new text</a></p>
|
||||
// <h1 id="this-is-a-heading">This is a heading</h1>
|
||||
|
||||
Console.WriteLine("Example 10\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("[With a new text][This is a heading]\n# This is a heading", "<p><a href=\"#this-is-a-heading\">With a new text</a></p>\n<h1 id=\"this-is-a-heading\">This is a heading</h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
|
||||
// An autoidentifier should not conflict with an existing link:
|
||||
[Test]
|
||||
public void ExtensionsHeadingAutoIdentifiers_Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions / Heading Auto Identifiers
|
||||
//
|
||||
// The following Markdown:
|
||||
// ![scenario image][scenario]
|
||||
// ## Scenario
|
||||
// [scenario]: ./scenario.png
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><img src="./scenario.png" alt="scenario image" /></p>
|
||||
// <h2 id="scenario">Scenario</h2>
|
||||
|
||||
Console.WriteLine("Example 11\nSection Extensions / Heading Auto Identifiers\n");
|
||||
TestParser.TestSpec("![scenario image][scenario]\n## Scenario\n[scenario]: ./scenario.png", "<p><img src=\"./scenario.png\" alt=\"scenario image\" /></p>\n<h2 id=\"scenario\">Scenario</h2>", "autoidentifiers|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ Allows to automatically creates an identifier for a heading:
|
||||
<h1 id="this-is-a-heading">This is a heading</h1>
|
||||
````````````````````````````````
|
||||
|
||||
Only punctuation `-`, `_` and `.` is kept, all over non letter characters are discarded.
|
||||
Only punctuation `-`, `_` and `.` is kept, all other non letter characters are discarded.
|
||||
Consecutive same character `-`, `_` or `.` are rendered into a single one
|
||||
Characters `-`, `_` and `.` at the end of the string are also discarded.
|
||||
|
||||
@@ -96,3 +96,14 @@ The text of the link can be changed:
|
||||
<p><a href="#this-is-a-heading">With a new text</a></p>
|
||||
<h1 id="this-is-a-heading">This is a heading</h1>
|
||||
````````````````````````````````
|
||||
|
||||
An autoidentifier should not conflict with an existing link:
|
||||
|
||||
```````````````````````````````` example
|
||||
![scenario image][scenario]
|
||||
## Scenario
|
||||
[scenario]: ./scenario.png
|
||||
.
|
||||
<p><img src="./scenario.png" alt="scenario image" /></p>
|
||||
<h2 id="scenario">Scenario</h2>
|
||||
````````````````````````````````
|
||||
|
||||
562
src/Markdig.Tests/Specs/AutoLinks.generated.cs
Normal file
@@ -0,0 +1,562 @@
|
||||
|
||||
// --------------------------------
|
||||
// Auto Links
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.AutoLinks
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsAutoLinks
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## AutoLinks
|
||||
//
|
||||
// Autolinks will format as a HTML link any string that starts by:
|
||||
//
|
||||
// - `http://` or `https://`
|
||||
// - `ftp://`
|
||||
// - `mailto:`
|
||||
// - `tel:`
|
||||
// - `www.`
|
||||
[Test]
|
||||
public void ExtensionsAutoLinks_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / AutoLinks
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a http://www.google.com URL and https://www.google.com
|
||||
// This is a ftp://test.com
|
||||
// And a mailto:email@toto.com
|
||||
// And a tel:+1555123456
|
||||
// And a plain www.google.com
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <a href="http://www.google.com">http://www.google.com</a> URL and <a href="https://www.google.com">https://www.google.com</a>
|
||||
// This is a <a href="ftp://test.com">ftp://test.com</a>
|
||||
// And a <a href="mailto:email@toto.com">email@toto.com</a>
|
||||
// And a <a href="tel:+1555123456">+1555123456</a>
|
||||
// And a plain <a href="http://www.google.com">www.google.com</a></p>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / AutoLinks\n");
|
||||
TestParser.TestSpec("This is a http://www.google.com URL and https://www.google.com\nThis is a ftp://test.com\nAnd a mailto:email@toto.com\nAnd a tel:+1555123456\nAnd a plain www.google.com", "<p>This is a <a href=\"http://www.google.com\">http://www.google.com</a> URL and <a href=\"https://www.google.com\">https://www.google.com</a>\nThis is a <a href=\"ftp://test.com\">ftp://test.com</a>\nAnd a <a href=\"mailto:email@toto.com\">email@toto.com</a>\nAnd a <a href=\"tel:+1555123456\">+1555123456</a>\nAnd a plain <a href=\"http://www.google.com\">www.google.com</a></p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// But incomplete links will not be matched:
|
||||
[Test]
|
||||
public void ExtensionsAutoLinks_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / AutoLinks
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not a http:/www.google.com URL and https:/www.google.com
|
||||
// This is not a ftp:/test.com
|
||||
// And not a mailto:emailtoto.com
|
||||
// And not a plain www. or a www.x
|
||||
// And not a tel:
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not a http:/www.google.com URL and https:/www.google.com
|
||||
// This is not a ftp:/test.com
|
||||
// And not a mailto:emailtoto.com
|
||||
// And not a plain www. or a www.x
|
||||
// And not a tel:</p>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / AutoLinks\n");
|
||||
TestParser.TestSpec("This is not a http:/www.google.com URL and https:/www.google.com\nThis is not a ftp:/test.com\nAnd not a mailto:emailtoto.com\nAnd not a plain www. or a www.x \nAnd not a tel:", "<p>This is not a http:/www.google.com URL and https:/www.google.com\nThis is not a ftp:/test.com\nAnd not a mailto:emailtoto.com\nAnd not a plain www. or a www.x\nAnd not a tel:</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// Previous character must be a punctuation or a valid space (tab, space, new line):
|
||||
[Test]
|
||||
public void ExtensionsAutoLinks_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / AutoLinks
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not a nhttp://www.google.com URL but this is (https://www.google.com)
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not a nhttp://www.google.com URL but this is (<a href="https://www.google.com">https://www.google.com</a>)</p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / AutoLinks\n");
|
||||
TestParser.TestSpec("This is not a nhttp://www.google.com URL but this is (https://www.google.com)", "<p>This is not a nhttp://www.google.com URL but this is (<a href=\"https://www.google.com\">https://www.google.com</a>)</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// An autolink should not interfere with an `<a>` HTML inline:
|
||||
[Test]
|
||||
public void ExtensionsAutoLinks_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / AutoLinks
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is an HTML <a href="http://www.google.com">http://www.google.com</a> link
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / AutoLinks\n");
|
||||
TestParser.TestSpec("This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link", "<p>This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// or even within emphasis:
|
||||
[Test]
|
||||
public void ExtensionsAutoLinks_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / AutoLinks
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is an HTML <a href="http://www.google.com"> **http://www.google.com** </a> link
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is an HTML <a href="http://www.google.com"> <strong>http://www.google.com</strong> </a> link</p>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / AutoLinks\n");
|
||||
TestParser.TestSpec("This is an HTML <a href=\"http://www.google.com\"> **http://www.google.com** </a> link", "<p>This is an HTML <a href=\"http://www.google.com\"> <strong>http://www.google.com</strong> </a> link</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// An autolink should not interfere with a markdown link:
|
||||
[Test]
|
||||
public void ExtensionsAutoLinks_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / AutoLinks
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is an HTML [http://www.google.com](http://www.google.com) link
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / AutoLinks\n");
|
||||
TestParser.TestSpec("This is an HTML [http://www.google.com](http://www.google.com) link", "<p>This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// A link embraced by pending emphasis should let the emphasis takes precedence if characters are placed at the end of the matched link:
|
||||
[Test]
|
||||
public void ExtensionsAutoLinks_Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Extensions / AutoLinks
|
||||
//
|
||||
// The following Markdown:
|
||||
// Check **http://www.a.com** or __http://www.b.com__
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Check <strong><a href="http://www.a.com">http://www.a.com</a></strong> or <strong><a href="http://www.b.com">http://www.b.com</a></strong></p>
|
||||
|
||||
Console.WriteLine("Example 7\nSection Extensions / AutoLinks\n");
|
||||
TestParser.TestSpec("Check **http://www.a.com** or __http://www.b.com__", "<p>Check <strong><a href=\"http://www.a.com\">http://www.a.com</a></strong> or <strong><a href=\"http://www.b.com\">http://www.b.com</a></strong></p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// It is not mentioned by the spec, but empty emails won't be matched (only a subset of [RFC2368](https://tools.ietf.org/html/rfc2368) is supported by auto links):
|
||||
[Test]
|
||||
public void ExtensionsAutoLinks_Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Extensions / AutoLinks
|
||||
//
|
||||
// The following Markdown:
|
||||
// mailto:email@test.com is okay, but mailto:@test.com is not
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="mailto:email@test.com">email@test.com</a> is okay, but mailto:@test.com is not</p>
|
||||
|
||||
Console.WriteLine("Example 8\nSection Extensions / AutoLinks\n");
|
||||
TestParser.TestSpec("mailto:email@test.com is okay, but mailto:@test.com is not", "<p><a href=\"mailto:email@test.com\">email@test.com</a> is okay, but mailto:@test.com is not</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsAutoLinksGFMSupport
|
||||
{
|
||||
// ### GFM Support
|
||||
//
|
||||
// Extract from [GFM Autolinks extensions specs](https://github.github.com/gfm/#autolinks-extension-)
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksGFMSupport_Example009()
|
||||
{
|
||||
// Example 9
|
||||
// Section: Extensions / AutoLinks / GFM Support
|
||||
//
|
||||
// The following Markdown:
|
||||
// www.commonmark.org
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www.commonmark.org">www.commonmark.org</a></p>
|
||||
|
||||
Console.WriteLine("Example 9\nSection Extensions / AutoLinks / GFM Support\n");
|
||||
TestParser.TestSpec("www.commonmark.org", "<p><a href=\"http://www.commonmark.org\">www.commonmark.org</a></p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksGFMSupport_Example010()
|
||||
{
|
||||
// Example 10
|
||||
// Section: Extensions / AutoLinks / GFM Support
|
||||
//
|
||||
// The following Markdown:
|
||||
// Visit www.commonmark.org/help for more information.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Visit <a href="http://www.commonmark.org/help">www.commonmark.org/help</a> for more information.</p>
|
||||
|
||||
Console.WriteLine("Example 10\nSection Extensions / AutoLinks / GFM Support\n");
|
||||
TestParser.TestSpec("Visit www.commonmark.org/help for more information.", "<p>Visit <a href=\"http://www.commonmark.org/help\">www.commonmark.org/help</a> for more information.</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksGFMSupport_Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions / AutoLinks / GFM Support
|
||||
//
|
||||
// The following Markdown:
|
||||
// Visit www.commonmark.org.
|
||||
//
|
||||
// Visit www.commonmark.org/a.b.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Visit <a href="http://www.commonmark.org">www.commonmark.org</a>.</p>
|
||||
// <p>Visit <a href="http://www.commonmark.org/a.b">www.commonmark.org/a.b</a>.</p>
|
||||
|
||||
Console.WriteLine("Example 11\nSection Extensions / AutoLinks / GFM Support\n");
|
||||
TestParser.TestSpec("Visit www.commonmark.org.\n\nVisit www.commonmark.org/a.b.", "<p>Visit <a href=\"http://www.commonmark.org\">www.commonmark.org</a>.</p>\n<p>Visit <a href=\"http://www.commonmark.org/a.b\">www.commonmark.org/a.b</a>.</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksGFMSupport_Example012()
|
||||
{
|
||||
// Example 12
|
||||
// Section: Extensions / AutoLinks / GFM Support
|
||||
//
|
||||
// The following Markdown:
|
||||
// www.google.com/search?q=Markup+(business)
|
||||
//
|
||||
// (www.google.com/search?q=Markup+(business))
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a></p>
|
||||
// <p>(<a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a>)</p>
|
||||
|
||||
Console.WriteLine("Example 12\nSection Extensions / AutoLinks / GFM Support\n");
|
||||
TestParser.TestSpec("www.google.com/search?q=Markup+(business)\n\n(www.google.com/search?q=Markup+(business))", "<p><a href=\"http://www.google.com/search?q=Markup+(business)\">www.google.com/search?q=Markup+(business)</a></p>\n<p>(<a href=\"http://www.google.com/search?q=Markup+(business)\">www.google.com/search?q=Markup+(business)</a>)</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksGFMSupport_Example013()
|
||||
{
|
||||
// Example 13
|
||||
// Section: Extensions / AutoLinks / GFM Support
|
||||
//
|
||||
// The following Markdown:
|
||||
// www.google.com/search?q=commonmark&hl=en
|
||||
//
|
||||
// www.google.com/search?q=commonmark&hl;
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www.google.com/search?q=commonmark&hl=en">www.google.com/search?q=commonmark&hl=en</a></p>
|
||||
// <p><a href="http://www.google.com/search?q=commonmark">www.google.com/search?q=commonmark</a>&hl;</p>
|
||||
|
||||
Console.WriteLine("Example 13\nSection Extensions / AutoLinks / GFM Support\n");
|
||||
TestParser.TestSpec("www.google.com/search?q=commonmark&hl=en\n\nwww.google.com/search?q=commonmark&hl;", "<p><a href=\"http://www.google.com/search?q=commonmark&hl=en\">www.google.com/search?q=commonmark&hl=en</a></p>\n<p><a href=\"http://www.google.com/search?q=commonmark\">www.google.com/search?q=commonmark</a>&hl;</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksGFMSupport_Example014()
|
||||
{
|
||||
// Example 14
|
||||
// Section: Extensions / AutoLinks / GFM Support
|
||||
//
|
||||
// The following Markdown:
|
||||
// www.commonmark.org/he<lp
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www.commonmark.org/he">www.commonmark.org/he</a><lp</p>
|
||||
|
||||
Console.WriteLine("Example 14\nSection Extensions / AutoLinks / GFM Support\n");
|
||||
TestParser.TestSpec("www.commonmark.org/he<lp", "<p><a href=\"http://www.commonmark.org/he\">www.commonmark.org/he</a><lp</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksGFMSupport_Example015()
|
||||
{
|
||||
// Example 15
|
||||
// Section: Extensions / AutoLinks / GFM Support
|
||||
//
|
||||
// The following Markdown:
|
||||
// http://commonmark.org
|
||||
//
|
||||
// (Visit https://encrypted.google.com/search?q=Markup+(business))
|
||||
//
|
||||
// Anonymous FTP is available at ftp://foo.bar.baz.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://commonmark.org">http://commonmark.org</a></p>
|
||||
// <p>(Visit <a href="https://encrypted.google.com/search?q=Markup+(business)">https://encrypted.google.com/search?q=Markup+(business)</a>)</p>
|
||||
// <p>Anonymous FTP is available at <a href="ftp://foo.bar.baz">ftp://foo.bar.baz</a>.</p>
|
||||
|
||||
Console.WriteLine("Example 15\nSection Extensions / AutoLinks / GFM Support\n");
|
||||
TestParser.TestSpec("http://commonmark.org\n\n(Visit https://encrypted.google.com/search?q=Markup+(business))\n\nAnonymous FTP is available at ftp://foo.bar.baz.", "<p><a href=\"http://commonmark.org\">http://commonmark.org</a></p>\n<p>(Visit <a href=\"https://encrypted.google.com/search?q=Markup+(business)\">https://encrypted.google.com/search?q=Markup+(business)</a>)</p>\n<p>Anonymous FTP is available at <a href=\"ftp://foo.bar.baz\">ftp://foo.bar.baz</a>.</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsAutoLinksValidDomainTests
|
||||
{
|
||||
// ### Valid Domain Tests
|
||||
//
|
||||
// Domain names that have empty segments won't be matched
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksValidDomainTests_Example016()
|
||||
{
|
||||
// Example 16
|
||||
// Section: Extensions / AutoLinks / Valid Domain Tests
|
||||
//
|
||||
// The following Markdown:
|
||||
// www..
|
||||
// www..com
|
||||
// http://test.
|
||||
// http://.test
|
||||
// http://.
|
||||
// http://..
|
||||
// ftp://test.
|
||||
// ftp://.test
|
||||
// mailto:email@test.
|
||||
// mailto:email@.test
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>www..
|
||||
// www..com
|
||||
// http://test.
|
||||
// http://.test
|
||||
// http://.
|
||||
// http://..
|
||||
// ftp://test.
|
||||
// ftp://.test
|
||||
// mailto:email@test.
|
||||
// mailto:email@.test</p>
|
||||
|
||||
Console.WriteLine("Example 16\nSection Extensions / AutoLinks / Valid Domain Tests\n");
|
||||
TestParser.TestSpec("www..\nwww..com\nhttp://test.\nhttp://.test\nhttp://.\nhttp://..\nftp://test.\nftp://.test\nmailto:email@test.\nmailto:email@.test", "<p>www..\nwww..com\nhttp://test.\nhttp://.test\nhttp://.\nhttp://..\nftp://test.\nftp://.test\nmailto:email@test.\nmailto:email@.test</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// Domain names with too few segments won't be matched
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksValidDomainTests_Example017()
|
||||
{
|
||||
// Example 17
|
||||
// Section: Extensions / AutoLinks / Valid Domain Tests
|
||||
//
|
||||
// The following Markdown:
|
||||
// www
|
||||
// www.com
|
||||
// http://test
|
||||
// ftp://test
|
||||
// mailto:email@test
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>www
|
||||
// www.com
|
||||
// http://test
|
||||
// ftp://test
|
||||
// mailto:email@test</p>
|
||||
|
||||
Console.WriteLine("Example 17\nSection Extensions / AutoLinks / Valid Domain Tests\n");
|
||||
TestParser.TestSpec("www\nwww.com\nhttp://test\nftp://test\nmailto:email@test", "<p>www\nwww.com\nhttp://test\nftp://test\nmailto:email@test</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// Domain names that contain an underscores in the last two segments won't be matched
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksValidDomainTests_Example018()
|
||||
{
|
||||
// Example 18
|
||||
// Section: Extensions / AutoLinks / Valid Domain Tests
|
||||
//
|
||||
// The following Markdown:
|
||||
// www._test.foo.bar is okay, but www._test.foo is not
|
||||
//
|
||||
// http://te_st.foo.bar is okay, as is http://test.foo_.bar.foo
|
||||
//
|
||||
// But http://te_st.foo, http://test.foo_.bar and http://test._foo are not
|
||||
//
|
||||
// ftp://test_.foo.bar is okay, but ftp://test.fo_o is not
|
||||
//
|
||||
// mailto:email@_test.foo.bar is okay, but mailto:email@_test.foo is not
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www._test.foo.bar">www._test.foo.bar</a> is okay, but www._test.foo is not</p>
|
||||
// <p><a href="http://te_st.foo.bar">http://te_st.foo.bar</a> is okay, as is <a href="http://test.foo_.bar.foo">http://test.foo_.bar.foo</a></p>
|
||||
// <p>But http://te_st.foo, http://test.foo_.bar and http://test._foo are not</p>
|
||||
// <p><a href="ftp://test_.foo.bar">ftp://test_.foo.bar</a> is okay, but ftp://test.fo_o is not</p>
|
||||
// <p><a href="mailto:email@_test.foo.bar">email@_test.foo.bar</a> is okay, but mailto:email@_test.foo is not</p>
|
||||
|
||||
Console.WriteLine("Example 18\nSection Extensions / AutoLinks / Valid Domain Tests\n");
|
||||
TestParser.TestSpec("www._test.foo.bar is okay, but www._test.foo is not\n\nhttp://te_st.foo.bar is okay, as is http://test.foo_.bar.foo\n\nBut http://te_st.foo, http://test.foo_.bar and http://test._foo are not\n\nftp://test_.foo.bar is okay, but ftp://test.fo_o is not\n\nmailto:email@_test.foo.bar is okay, but mailto:email@_test.foo is not", "<p><a href=\"http://www._test.foo.bar\">www._test.foo.bar</a> is okay, but www._test.foo is not</p>\n<p><a href=\"http://te_st.foo.bar\">http://te_st.foo.bar</a> is okay, as is <a href=\"http://test.foo_.bar.foo\">http://test.foo_.bar.foo</a></p>\n<p>But http://te_st.foo, http://test.foo_.bar and http://test._foo are not</p>\n<p><a href=\"ftp://test_.foo.bar\">ftp://test_.foo.bar</a> is okay, but ftp://test.fo_o is not</p>\n<p><a href=\"mailto:email@_test.foo.bar\">email@_test.foo.bar</a> is okay, but mailto:email@_test.foo is not</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// Domain names that contain invalid characters (not AlphaNumberic, -, _ or .) won't be matched
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksValidDomainTests_Example019()
|
||||
{
|
||||
// Example 19
|
||||
// Section: Extensions / AutoLinks / Valid Domain Tests
|
||||
//
|
||||
// The following Markdown:
|
||||
// https://[your-domain]/api
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>https://[your-domain]/api</p>
|
||||
|
||||
Console.WriteLine("Example 19\nSection Extensions / AutoLinks / Valid Domain Tests\n");
|
||||
TestParser.TestSpec("https://[your-domain]/api", "<p>https://[your-domain]/api</p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// Domain names followed by ?, : or # instead of / are matched
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksValidDomainTests_Example020()
|
||||
{
|
||||
// Example 20
|
||||
// Section: Extensions / AutoLinks / Valid Domain Tests
|
||||
//
|
||||
// The following Markdown:
|
||||
// https://github.com?
|
||||
//
|
||||
// https://github.com?a
|
||||
//
|
||||
// https://github.com#a
|
||||
//
|
||||
// https://github.com:
|
||||
//
|
||||
// https://github.com:443
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="https://github.com">https://github.com</a>?</p>
|
||||
// <p><a href="https://github.com?a">https://github.com?a</a></p>
|
||||
// <p><a href="https://github.com#a">https://github.com#a</a></p>
|
||||
// <p><a href="https://github.com">https://github.com</a>:</p>
|
||||
// <p><a href="https://github.com:443">https://github.com:443</a></p>
|
||||
|
||||
Console.WriteLine("Example 20\nSection Extensions / AutoLinks / Valid Domain Tests\n");
|
||||
TestParser.TestSpec("https://github.com?\n\nhttps://github.com?a\n\nhttps://github.com#a\n\nhttps://github.com:\n\nhttps://github.com:443", "<p><a href=\"https://github.com\">https://github.com</a>?</p>\n<p><a href=\"https://github.com?a\">https://github.com?a</a></p>\n<p><a href=\"https://github.com#a\">https://github.com#a</a></p>\n<p><a href=\"https://github.com\">https://github.com</a>:</p>\n<p><a href=\"https://github.com:443\">https://github.com:443</a></p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsAutoLinksUnicodeSupport
|
||||
{
|
||||
// ### Unicode support
|
||||
//
|
||||
// Links with unicode characters in the path / query / fragment are matched and url encoded
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksUnicodeSupport_Example021()
|
||||
{
|
||||
// Example 21
|
||||
// Section: Extensions / AutoLinks / Unicode support
|
||||
//
|
||||
// The following Markdown:
|
||||
// http://abc.net/☃
|
||||
//
|
||||
// http://abc.net?☃
|
||||
//
|
||||
// http://abc.net#☃
|
||||
//
|
||||
// http://abc.net/foo#☃
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://abc.net/%E2%98%83">http://abc.net/☃</a></p>
|
||||
// <p><a href="http://abc.net?%E2%98%83">http://abc.net?☃</a></p>
|
||||
// <p><a href="http://abc.net#%E2%98%83">http://abc.net#☃</a></p>
|
||||
// <p><a href="http://abc.net/foo#%E2%98%83">http://abc.net/foo#☃</a></p>
|
||||
|
||||
Console.WriteLine("Example 21\nSection Extensions / AutoLinks / Unicode support\n");
|
||||
TestParser.TestSpec("http://abc.net/☃\n\nhttp://abc.net?☃\n\nhttp://abc.net#☃\n\nhttp://abc.net/foo#☃", "<p><a href=\"http://abc.net/%E2%98%83\">http://abc.net/☃</a></p>\n<p><a href=\"http://abc.net?%E2%98%83\">http://abc.net?☃</a></p>\n<p><a href=\"http://abc.net#%E2%98%83\">http://abc.net#☃</a></p>\n<p><a href=\"http://abc.net/foo#%E2%98%83\">http://abc.net/foo#☃</a></p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// Unicode characters in the FQDN are matched and IDNA encoded
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksUnicodeSupport_Example022()
|
||||
{
|
||||
// Example 22
|
||||
// Section: Extensions / AutoLinks / Unicode support
|
||||
//
|
||||
// The following Markdown:
|
||||
// http://☃.net?☃
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://xn--n3h.net?%E2%98%83">http://☃.net?☃</a></p>
|
||||
|
||||
Console.WriteLine("Example 22\nSection Extensions / AutoLinks / Unicode support\n");
|
||||
TestParser.TestSpec("http://☃.net?☃", "<p><a href=\"http://xn--n3h.net?%E2%98%83\">http://☃.net?☃</a></p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// Same goes for regular autolinks
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksUnicodeSupport_Example023()
|
||||
{
|
||||
// Example 23
|
||||
// Section: Extensions / AutoLinks / Unicode support
|
||||
//
|
||||
// The following Markdown:
|
||||
// <http://abc.net/☃>
|
||||
//
|
||||
// <http://abc.net?☃>
|
||||
//
|
||||
// <http://abc.net#☃>
|
||||
//
|
||||
// <http://abc.net/foo#☃>
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://abc.net/%E2%98%83">http://abc.net/☃</a></p>
|
||||
// <p><a href="http://abc.net?%E2%98%83">http://abc.net?☃</a></p>
|
||||
// <p><a href="http://abc.net#%E2%98%83">http://abc.net#☃</a></p>
|
||||
// <p><a href="http://abc.net/foo#%E2%98%83">http://abc.net/foo#☃</a></p>
|
||||
|
||||
Console.WriteLine("Example 23\nSection Extensions / AutoLinks / Unicode support\n");
|
||||
TestParser.TestSpec("<http://abc.net/☃>\n\n<http://abc.net?☃>\n\n<http://abc.net#☃>\n\n<http://abc.net/foo#☃>", "<p><a href=\"http://abc.net/%E2%98%83\">http://abc.net/☃</a></p>\n<p><a href=\"http://abc.net?%E2%98%83\">http://abc.net?☃</a></p>\n<p><a href=\"http://abc.net#%E2%98%83\">http://abc.net#☃</a></p>\n<p><a href=\"http://abc.net/foo#%E2%98%83\">http://abc.net/foo#☃</a></p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksUnicodeSupport_Example024()
|
||||
{
|
||||
// Example 24
|
||||
// Section: Extensions / AutoLinks / Unicode support
|
||||
//
|
||||
// The following Markdown:
|
||||
// <http://☃.net?☃>
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://xn--n3h.net?%E2%98%83">http://☃.net?☃</a></p>
|
||||
|
||||
Console.WriteLine("Example 24\nSection Extensions / AutoLinks / Unicode support\n");
|
||||
TestParser.TestSpec("<http://☃.net?☃>", "<p><a href=\"http://xn--n3h.net?%E2%98%83\">http://☃.net?☃</a></p>", "autolinks|advanced");
|
||||
}
|
||||
|
||||
// It also complies with CommonMark's vision of priority.
|
||||
// This will therefore be seen as an autolink and not as code inline.
|
||||
[Test]
|
||||
public void ExtensionsAutoLinksUnicodeSupport_Example025()
|
||||
{
|
||||
// Example 25
|
||||
// Section: Extensions / AutoLinks / Unicode support
|
||||
//
|
||||
// The following Markdown:
|
||||
// <http://foö.bar.`baz>`
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://xn--fo-gka.bar.%60baz">http://foö.bar.`baz</a>`</p>
|
||||
|
||||
Console.WriteLine("Example 25\nSection Extensions / AutoLinks / Unicode support\n");
|
||||
TestParser.TestSpec("<http://foö.bar.`baz>`", "<p><a href=\"http://xn--fo-gka.bar.%60baz\">http://foö.bar.`baz</a>`</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
306
src/Markdig.Tests/Specs/AutoLinks.md
Normal file
@@ -0,0 +1,306 @@
|
||||
# Extensions
|
||||
|
||||
This section describes the different extensions supported:
|
||||
|
||||
## AutoLinks
|
||||
|
||||
Autolinks will format as a HTML link any string that starts by:
|
||||
|
||||
- `http://` or `https://`
|
||||
- `ftp://`
|
||||
- `mailto:`
|
||||
- `tel:`
|
||||
- `www.`
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a http://www.google.com URL and https://www.google.com
|
||||
This is a ftp://test.com
|
||||
And a mailto:email@toto.com
|
||||
And a tel:+1555123456
|
||||
And a plain www.google.com
|
||||
.
|
||||
<p>This is a <a href="http://www.google.com">http://www.google.com</a> URL and <a href="https://www.google.com">https://www.google.com</a>
|
||||
This is a <a href="ftp://test.com">ftp://test.com</a>
|
||||
And a <a href="mailto:email@toto.com">email@toto.com</a>
|
||||
And a <a href="tel:+1555123456">+1555123456</a>
|
||||
And a plain <a href="http://www.google.com">www.google.com</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
But incomplete links will not be matched:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not a http:/www.google.com URL and https:/www.google.com
|
||||
This is not a ftp:/test.com
|
||||
And not a mailto:emailtoto.com
|
||||
And not a plain www. or a www.x
|
||||
And not a tel:
|
||||
.
|
||||
<p>This is not a http:/www.google.com URL and https:/www.google.com
|
||||
This is not a ftp:/test.com
|
||||
And not a mailto:emailtoto.com
|
||||
And not a plain www. or a www.x
|
||||
And not a tel:</p>
|
||||
````````````````````````````````
|
||||
|
||||
Previous character must be a punctuation or a valid space (tab, space, new line):
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not a nhttp://www.google.com URL but this is (https://www.google.com)
|
||||
.
|
||||
<p>This is not a nhttp://www.google.com URL but this is (<a href="https://www.google.com">https://www.google.com</a>)</p>
|
||||
````````````````````````````````
|
||||
|
||||
An autolink should not interfere with an `<a>` HTML inline:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is an HTML <a href="http://www.google.com">http://www.google.com</a> link
|
||||
.
|
||||
<p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
|
||||
````````````````````````````````
|
||||
or even within emphasis:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is an HTML <a href="http://www.google.com"> **http://www.google.com** </a> link
|
||||
.
|
||||
<p>This is an HTML <a href="http://www.google.com"> <strong>http://www.google.com</strong> </a> link</p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
An autolink should not interfere with a markdown link:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is an HTML [http://www.google.com](http://www.google.com) link
|
||||
.
|
||||
<p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
|
||||
````````````````````````````````
|
||||
|
||||
A link embraced by pending emphasis should let the emphasis takes precedence if characters are placed at the end of the matched link:
|
||||
|
||||
```````````````````````````````` example
|
||||
Check **http://www.a.com** or __http://www.b.com__
|
||||
.
|
||||
<p>Check <strong><a href="http://www.a.com">http://www.a.com</a></strong> or <strong><a href="http://www.b.com">http://www.b.com</a></strong></p>
|
||||
````````````````````````````````
|
||||
|
||||
It is not mentioned by the spec, but empty emails won't be matched (only a subset of [RFC2368](https://tools.ietf.org/html/rfc2368) is supported by auto links):
|
||||
|
||||
```````````````````````````````` example
|
||||
mailto:email@test.com is okay, but mailto:@test.com is not
|
||||
.
|
||||
<p><a href="mailto:email@test.com">email@test.com</a> is okay, but mailto:@test.com is not</p>
|
||||
````````````````````````````````
|
||||
|
||||
### GFM Support
|
||||
|
||||
Extract from [GFM Autolinks extensions specs](https://github.github.com/gfm/#autolinks-extension-)
|
||||
|
||||
```````````````````````````````` example
|
||||
www.commonmark.org
|
||||
.
|
||||
<p><a href="http://www.commonmark.org">www.commonmark.org</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
Visit www.commonmark.org/help for more information.
|
||||
.
|
||||
<p>Visit <a href="http://www.commonmark.org/help">www.commonmark.org/help</a> for more information.</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
Visit www.commonmark.org.
|
||||
|
||||
Visit www.commonmark.org/a.b.
|
||||
.
|
||||
<p>Visit <a href="http://www.commonmark.org">www.commonmark.org</a>.</p>
|
||||
<p>Visit <a href="http://www.commonmark.org/a.b">www.commonmark.org/a.b</a>.</p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
www.google.com/search?q=Markup+(business)
|
||||
|
||||
(www.google.com/search?q=Markup+(business))
|
||||
.
|
||||
<p><a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a></p>
|
||||
<p>(<a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a>)</p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
www.google.com/search?q=commonmark&hl=en
|
||||
|
||||
www.google.com/search?q=commonmark&hl;
|
||||
.
|
||||
<p><a href="http://www.google.com/search?q=commonmark&hl=en">www.google.com/search?q=commonmark&hl=en</a></p>
|
||||
<p><a href="http://www.google.com/search?q=commonmark">www.google.com/search?q=commonmark</a>&hl;</p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
www.commonmark.org/he<lp
|
||||
.
|
||||
<p><a href="http://www.commonmark.org/he">www.commonmark.org/he</a><lp</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
http://commonmark.org
|
||||
|
||||
(Visit https://encrypted.google.com/search?q=Markup+(business))
|
||||
|
||||
Anonymous FTP is available at ftp://foo.bar.baz.
|
||||
.
|
||||
<p><a href="http://commonmark.org">http://commonmark.org</a></p>
|
||||
<p>(Visit <a href="https://encrypted.google.com/search?q=Markup+(business)">https://encrypted.google.com/search?q=Markup+(business)</a>)</p>
|
||||
<p>Anonymous FTP is available at <a href="ftp://foo.bar.baz">ftp://foo.bar.baz</a>.</p>
|
||||
````````````````````````````````
|
||||
|
||||
### Valid Domain Tests
|
||||
|
||||
Domain names that have empty segments won't be matched
|
||||
|
||||
```````````````````````````````` example
|
||||
www..
|
||||
www..com
|
||||
http://test.
|
||||
http://.test
|
||||
http://.
|
||||
http://..
|
||||
ftp://test.
|
||||
ftp://.test
|
||||
mailto:email@test.
|
||||
mailto:email@.test
|
||||
.
|
||||
<p>www..
|
||||
www..com
|
||||
http://test.
|
||||
http://.test
|
||||
http://.
|
||||
http://..
|
||||
ftp://test.
|
||||
ftp://.test
|
||||
mailto:email@test.
|
||||
mailto:email@.test</p>
|
||||
````````````````````````````````
|
||||
|
||||
Domain names with too few segments won't be matched
|
||||
|
||||
```````````````````````````````` example
|
||||
www
|
||||
www.com
|
||||
http://test
|
||||
ftp://test
|
||||
mailto:email@test
|
||||
.
|
||||
<p>www
|
||||
www.com
|
||||
http://test
|
||||
ftp://test
|
||||
mailto:email@test</p>
|
||||
````````````````````````````````
|
||||
|
||||
Domain names that contain an underscores in the last two segments won't be matched
|
||||
|
||||
```````````````````````````````` example
|
||||
www._test.foo.bar is okay, but www._test.foo is not
|
||||
|
||||
http://te_st.foo.bar is okay, as is http://test.foo_.bar.foo
|
||||
|
||||
But http://te_st.foo, http://test.foo_.bar and http://test._foo are not
|
||||
|
||||
ftp://test_.foo.bar is okay, but ftp://test.fo_o is not
|
||||
|
||||
mailto:email@_test.foo.bar is okay, but mailto:email@_test.foo is not
|
||||
.
|
||||
<p><a href="http://www._test.foo.bar">www._test.foo.bar</a> is okay, but www._test.foo is not</p>
|
||||
<p><a href="http://te_st.foo.bar">http://te_st.foo.bar</a> is okay, as is <a href="http://test.foo_.bar.foo">http://test.foo_.bar.foo</a></p>
|
||||
<p>But http://te_st.foo, http://test.foo_.bar and http://test._foo are not</p>
|
||||
<p><a href="ftp://test_.foo.bar">ftp://test_.foo.bar</a> is okay, but ftp://test.fo_o is not</p>
|
||||
<p><a href="mailto:email@_test.foo.bar">email@_test.foo.bar</a> is okay, but mailto:email@_test.foo is not</p>
|
||||
````````````````````````````````
|
||||
|
||||
Domain names that contain invalid characters (not AlphaNumberic, -, _ or .) won't be matched
|
||||
|
||||
```````````````````````````````` example
|
||||
https://[your-domain]/api
|
||||
.
|
||||
<p>https://[your-domain]/api</p>
|
||||
````````````````````````````````
|
||||
|
||||
Domain names followed by ?, : or # instead of / are matched
|
||||
|
||||
```````````````````````````````` example
|
||||
https://github.com?
|
||||
|
||||
https://github.com?a
|
||||
|
||||
https://github.com#a
|
||||
|
||||
https://github.com:
|
||||
|
||||
https://github.com:443
|
||||
.
|
||||
<p><a href="https://github.com">https://github.com</a>?</p>
|
||||
<p><a href="https://github.com?a">https://github.com?a</a></p>
|
||||
<p><a href="https://github.com#a">https://github.com#a</a></p>
|
||||
<p><a href="https://github.com">https://github.com</a>:</p>
|
||||
<p><a href="https://github.com:443">https://github.com:443</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
### Unicode support
|
||||
|
||||
Links with unicode characters in the path / query / fragment are matched and url encoded
|
||||
|
||||
```````````````````````````````` example
|
||||
http://abc.net/☃
|
||||
|
||||
http://abc.net?☃
|
||||
|
||||
http://abc.net#☃
|
||||
|
||||
http://abc.net/foo#☃
|
||||
.
|
||||
<p><a href="http://abc.net/%E2%98%83">http://abc.net/☃</a></p>
|
||||
<p><a href="http://abc.net?%E2%98%83">http://abc.net?☃</a></p>
|
||||
<p><a href="http://abc.net#%E2%98%83">http://abc.net#☃</a></p>
|
||||
<p><a href="http://abc.net/foo#%E2%98%83">http://abc.net/foo#☃</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
Unicode characters in the FQDN are matched and IDNA encoded
|
||||
|
||||
```````````````````````````````` example
|
||||
http://☃.net?☃
|
||||
.
|
||||
<p><a href="http://xn--n3h.net?%E2%98%83">http://☃.net?☃</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
Same goes for regular autolinks
|
||||
|
||||
```````````````````````````````` example
|
||||
<http://abc.net/☃>
|
||||
|
||||
<http://abc.net?☃>
|
||||
|
||||
<http://abc.net#☃>
|
||||
|
||||
<http://abc.net/foo#☃>
|
||||
.
|
||||
<p><a href="http://abc.net/%E2%98%83">http://abc.net/☃</a></p>
|
||||
<p><a href="http://abc.net?%E2%98%83">http://abc.net?☃</a></p>
|
||||
<p><a href="http://abc.net#%E2%98%83">http://abc.net#☃</a></p>
|
||||
<p><a href="http://abc.net/foo#%E2%98%83">http://abc.net/foo#☃</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
<http://☃.net?☃>
|
||||
.
|
||||
<p><a href="http://xn--n3h.net?%E2%98%83">http://☃.net?☃</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
It also complies with CommonMark's vision of priority.
|
||||
This will therefore be seen as an autolink and not as code inline.
|
||||
|
||||
```````````````````````````````` example
|
||||
<http://foö.bar.`baz>`
|
||||
.
|
||||
<p><a href="http://xn--fo-gka.bar.%60baz">http://foö.bar.`baz</a>`</p>
|
||||
````````````````````````````````
|
||||
110
src/Markdig.Tests/Specs/BootstrapSpecs.generated.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
// --------------------------------
|
||||
// Bootstrap
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.Bootstrap
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsBootstrap
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// Adds support for outputting bootstrap ready tags:
|
||||
//
|
||||
// ## Bootstrap
|
||||
//
|
||||
// Adds bootstrap `.table` class to `<table>`:
|
||||
[Test]
|
||||
public void ExtensionsBootstrap_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Bootstrap
|
||||
//
|
||||
// The following Markdown:
|
||||
// Name | Value
|
||||
// -----| -----
|
||||
// Abc | 16
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table class="table">
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>Name</th>
|
||||
// <th>Value</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>Abc</td>
|
||||
// <td>16</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Bootstrap\n");
|
||||
TestParser.TestSpec("Name | Value\n-----| -----\nAbc | 16", "<table class=\"table\">\n<thead>\n<tr>\n<th>Name</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Abc</td>\n<td>16</td>\n</tr>\n</tbody>\n</table>", "bootstrap+pipetables+figures+attributes");
|
||||
}
|
||||
|
||||
// Adds bootstrap `.blockquote` class to `<blockquote>`:
|
||||
[Test]
|
||||
public void ExtensionsBootstrap_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Bootstrap
|
||||
//
|
||||
// The following Markdown:
|
||||
// > This is a blockquote
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <blockquote class="blockquote">
|
||||
// <p>This is a blockquote</p>
|
||||
// </blockquote>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Bootstrap\n");
|
||||
TestParser.TestSpec("> This is a blockquote", "<blockquote class=\"blockquote\">\n<p>This is a blockquote</p>\n</blockquote>", "bootstrap+pipetables+figures+attributes");
|
||||
}
|
||||
|
||||
// Adds bootstrap `.figure` class to `<figure>` and `.figure-caption` to `<figcaption>`
|
||||
[Test]
|
||||
public void ExtensionsBootstrap_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Bootstrap
|
||||
//
|
||||
// The following Markdown:
|
||||
// ^^^
|
||||
// This is a text in a caption
|
||||
// ^^^ This is the caption
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <figure class="figure">
|
||||
// <p>This is a text in a caption</p>
|
||||
// <figcaption class="figure-caption">This is the caption</figcaption>
|
||||
// </figure>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Bootstrap\n");
|
||||
TestParser.TestSpec("^^^\nThis is a text in a caption\n^^^ This is the caption", "<figure class=\"figure\">\n<p>This is a text in a caption</p>\n<figcaption class=\"figure-caption\">This is the caption</figcaption>\n</figure>", "bootstrap+pipetables+figures+attributes");
|
||||
}
|
||||
|
||||
// Adds the `.img-fluid` class to all image links `<img>`
|
||||
[Test]
|
||||
public void ExtensionsBootstrap_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Bootstrap
|
||||
//
|
||||
// The following Markdown:
|
||||
// 
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><img src="/url" class="img-fluid" alt="Image Link" /></p>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Bootstrap\n");
|
||||
TestParser.TestSpec("", "<p><img src=\"/url\" class=\"img-fluid\" alt=\"Image Link\" /></p>", "bootstrap+pipetables+figures+attributes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# Extensions
|
||||
|
||||
Adds support for outputing bootstrap ready tags:
|
||||
Adds support for outputting bootstrap ready tags:
|
||||
|
||||
## Bootstrap
|
||||
|
||||
|
||||
15289
src/Markdig.Tests/Specs/CommonMark.generated.cs
Normal file
9724
src/Markdig.Tests/Specs/CommonMark.md
Normal file
210
src/Markdig.Tests/Specs/CustomContainerSpecs.generated.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
|
||||
// --------------------------------
|
||||
// Custom Containers
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.CustomContainers
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsCustomContainer
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Custom Container
|
||||
//
|
||||
// A custom container is similar to a fenced code block, but it is using the character `:` to declare a block (with at least 3 characters), and instead of generating a `<pre><code>...</code></pre>` it will generate a `<div>...</div>` block.
|
||||
[Test]
|
||||
public void ExtensionsCustomContainer_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// :::spoiler
|
||||
// This is a *spoiler*
|
||||
// :::
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <div class="spoiler"><p>This is a <em>spoiler</em></p>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Custom Container\n");
|
||||
TestParser.TestSpec(":::spoiler\nThis is a *spoiler*\n:::", "<div class=\"spoiler\"><p>This is a <em>spoiler</em></p>\n</div>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
|
||||
// The text following the opened custom container is optional:
|
||||
[Test]
|
||||
public void ExtensionsCustomContainer_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// :::
|
||||
// This is a regular div
|
||||
// :::
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <div><p>This is a regular div</p>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Custom Container\n");
|
||||
TestParser.TestSpec(":::\nThis is a regular div\n:::", "<div><p>This is a regular div</p>\n</div>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
|
||||
// Like for fenced code block, you can use more than 3 `:` characters as long as the closing has the same number of characters:
|
||||
[Test]
|
||||
public void ExtensionsCustomContainer_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// ::::::::::::spoiler
|
||||
// This is a spoiler
|
||||
// ::::::::::::
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <div class="spoiler"><p>This is a spoiler</p>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Custom Container\n");
|
||||
TestParser.TestSpec("::::::::::::spoiler\nThis is a spoiler\n::::::::::::", "<div class=\"spoiler\"><p>This is a spoiler</p>\n</div>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
|
||||
// Like for fenced code block, a custom container can span over multiple empty lines in a list block:
|
||||
[Test]
|
||||
public void ExtensionsCustomContainer_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// - This is a list
|
||||
// :::spoiler
|
||||
// This is a spoiler
|
||||
// - item1
|
||||
// - item2
|
||||
// :::
|
||||
// - A second item in the list
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ul>
|
||||
// <li>This is a list
|
||||
// <div class="spoiler">This is a spoiler
|
||||
// <ul>
|
||||
// <li>item1</li>
|
||||
// <li>item2</li>
|
||||
// </ul>
|
||||
// </div>
|
||||
// </li>
|
||||
// <li>A second item in the list</li>
|
||||
// </ul>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Custom Container\n");
|
||||
TestParser.TestSpec("- This is a list\n :::spoiler\n This is a spoiler\n - item1\n - item2\n :::\n- A second item in the list", "<ul>\n<li>This is a list\n<div class=\"spoiler\">This is a spoiler\n<ul>\n<li>item1</li>\n<li>item2</li>\n</ul>\n</div>\n</li>\n<li>A second item in the list</li>\n</ul>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
|
||||
// Attributes extension is also supported for Custom Container, as long as the Attributes extension is activated after the CustomContainer extension (`.UseCustomContainer().UseAttributes()`)
|
||||
[Test]
|
||||
public void ExtensionsCustomContainer_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// :::spoiler {#myspoiler myprop=yes}
|
||||
// This is a spoiler
|
||||
// :::
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <div id="myspoiler" class="spoiler" myprop="yes"><p>This is a spoiler</p>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / Custom Container\n");
|
||||
TestParser.TestSpec(":::spoiler {#myspoiler myprop=yes}\nThis is a spoiler\n:::", "<div id=\"myspoiler\" class=\"spoiler\" myprop=\"yes\"><p>This is a spoiler</p>\n</div>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
|
||||
// The content of a custom container can contain any blocks:
|
||||
[Test]
|
||||
public void ExtensionsCustomContainer_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// :::mycontainer
|
||||
// <p>This is a raw spoiler</p>
|
||||
// :::
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <div class="mycontainer"><p>This is a raw spoiler</p>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / Custom Container\n");
|
||||
TestParser.TestSpec(":::mycontainer\n<p>This is a raw spoiler</p>\n:::", "<div class=\"mycontainer\"><p>This is a raw spoiler</p>\n</div>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsInlineCustomContainer
|
||||
{
|
||||
// ## Inline Custom Container
|
||||
//
|
||||
// A custom container can also be used within an inline container (e.g: paragraph, heading...) by enclosing a text by a new emphasis `::`
|
||||
[Test]
|
||||
public void ExtensionsInlineCustomContainer_Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Extensions / Inline Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a text ::with special emphasis::
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a text <span>with special emphasis</span></p>
|
||||
|
||||
Console.WriteLine("Example 7\nSection Extensions / Inline Custom Container \n");
|
||||
TestParser.TestSpec("This is a text ::with special emphasis::", "<p>This is a text <span>with special emphasis</span></p>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
|
||||
// Any other emphasis inline can be used within this emphasis inline container:
|
||||
[Test]
|
||||
public void ExtensionsInlineCustomContainer_Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Extensions / Inline Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a text ::with special *emphasis*::
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a text <span>with special <em>emphasis</em></span></p>
|
||||
|
||||
Console.WriteLine("Example 8\nSection Extensions / Inline Custom Container \n");
|
||||
TestParser.TestSpec("This is a text ::with special *emphasis*::", "<p>This is a text <span>with special <em>emphasis</em></span></p>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
|
||||
// Attributes can be attached to a inline custom container:
|
||||
[Test]
|
||||
public void ExtensionsInlineCustomContainer_Example009()
|
||||
{
|
||||
// Example 9
|
||||
// Section: Extensions / Inline Custom Container
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a text ::with special emphasis::{#myId .myemphasis}
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a text <span id="myId" class="myemphasis">with special emphasis</span></p>
|
||||
|
||||
Console.WriteLine("Example 9\nSection Extensions / Inline Custom Container \n");
|
||||
TestParser.TestSpec("This is a text ::with special emphasis::{#myId .myemphasis}", "<p>This is a text <span id=\"myId\" class=\"myemphasis\">with special emphasis</span></p>", "customcontainers+attributes|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ This section describes the different extensions supported:
|
||||
|
||||
## Custom Container
|
||||
|
||||
A custom container is similar to a fenced code block, but it is using the character `:` to declare a block (with at least 3 characters), and instead of generating a `<pre><code>...</code></pre>` it will generate a `<div>...</dib>` block.
|
||||
A custom container is similar to a fenced code block, but it is using the character `:` to declare a block (with at least 3 characters), and instead of generating a `<pre><code>...</code></pre>` it will generate a `<div>...</div>` block.
|
||||
|
||||
```````````````````````````````` example
|
||||
:::spoiler
|
||||
@@ -109,4 +109,4 @@ Attributes can be attached to a inline custom container:
|
||||
This is a text ::with special emphasis::{#myId .myemphasis}
|
||||
.
|
||||
<p>This is a text <span id="myId" class="myemphasis">with special emphasis</span></p>
|
||||
````````````````````````````````
|
||||
````````````````````````````````
|
||||
|
||||
201
src/Markdig.Tests/Specs/DefinitionListSpecs.generated.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
|
||||
// --------------------------------
|
||||
// Definition Lists
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.DefinitionLists
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsDefinitionLists
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Definition lists
|
||||
//
|
||||
// A custom container is similar to a fenced code block, but it is using the character `:` to declare a block (with at least 3 characters), and instead of generating a `<pre><code>...</code></pre>` it will generate a `<div>...</div>` block.
|
||||
[Test]
|
||||
public void ExtensionsDefinitionLists_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Definition lists
|
||||
//
|
||||
// The following Markdown:
|
||||
//
|
||||
// Term 1
|
||||
// : This is a definition item
|
||||
// With a paragraph
|
||||
// > This is a block quote
|
||||
//
|
||||
// - This is a list
|
||||
// - with an item2
|
||||
//
|
||||
// ```java
|
||||
// Test
|
||||
//
|
||||
//
|
||||
// ```
|
||||
//
|
||||
// And a last line
|
||||
// : This ia another definition item
|
||||
//
|
||||
// Term2
|
||||
// Term3 *with some inline*
|
||||
// : This is another definition for term2
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <dl>
|
||||
// <dt>Term 1</dt>
|
||||
// <dd><p>This is a definition item
|
||||
// With a paragraph</p>
|
||||
// <blockquote>
|
||||
// <p>This is a block quote</p>
|
||||
// </blockquote>
|
||||
// <ul>
|
||||
// <li>This is a list</li>
|
||||
// <li>with an item2</li>
|
||||
// </ul>
|
||||
// <pre><code class="language-java">Test
|
||||
//
|
||||
//
|
||||
// </code></pre>
|
||||
// <p>And a last line</p>
|
||||
// </dd>
|
||||
// <dd>This ia another definition item</dd>
|
||||
// <dt>Term2</dt>
|
||||
// <dt>Term3 <em>with some inline</em></dt>
|
||||
// <dd>This is another definition for term2</dd>
|
||||
// </dl>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Definition lists\n");
|
||||
TestParser.TestSpec("\nTerm 1\n: This is a definition item\n With a paragraph\n > This is a block quote\n\n - This is a list\n - with an item2\n\n ```java\n Test\n\n\n ```\n\n And a last line\n: This ia another definition item\n\nTerm2\nTerm3 *with some inline*\n: This is another definition for term2", "<dl>\n<dt>Term 1</dt>\n<dd><p>This is a definition item\nWith a paragraph</p>\n<blockquote>\n<p>This is a block quote</p>\n</blockquote>\n<ul>\n<li>This is a list</li>\n<li>with an item2</li>\n</ul>\n<pre><code class=\"language-java\">Test\n\n\n</code></pre>\n<p>And a last line</p>\n</dd>\n<dd>This ia another definition item</dd>\n<dt>Term2</dt>\n<dt>Term3 <em>with some inline</em></dt>\n<dd>This is another definition for term2</dd>\n</dl>", "definitionlists+attributes|advanced");
|
||||
}
|
||||
|
||||
// A definition term can be followed at most by one blank line. Lazy continuations are supported for definitions:
|
||||
[Test]
|
||||
public void ExtensionsDefinitionLists_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Definition lists
|
||||
//
|
||||
// The following Markdown:
|
||||
// Term 1
|
||||
//
|
||||
// : Definition
|
||||
// with lazy continuation.
|
||||
//
|
||||
// Second paragraph of the definition.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <dl>
|
||||
// <dt>Term 1</dt>
|
||||
// <dd><p>Definition
|
||||
// with lazy continuation.</p>
|
||||
// <p>Second paragraph of the definition.</p>
|
||||
// </dd>
|
||||
// </dl>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Definition lists\n");
|
||||
TestParser.TestSpec("Term 1\n\n: Definition\nwith lazy continuation.\n\n Second paragraph of the definition.", "<dl>\n<dt>Term 1</dt>\n<dd><p>Definition\nwith lazy continuation.</p>\n<p>Second paragraph of the definition.</p>\n</dd>\n</dl>", "definitionlists+attributes|advanced");
|
||||
}
|
||||
|
||||
// The definition must be indented to 4 characters including the `:`.
|
||||
[Test]
|
||||
public void ExtensionsDefinitionLists_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Definition lists
|
||||
//
|
||||
// The following Markdown:
|
||||
// Term 1
|
||||
// : Invalid with less than 3 characters
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Term 1
|
||||
// : Invalid with less than 3 characters</p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Definition lists\n");
|
||||
TestParser.TestSpec("Term 1\n: Invalid with less than 3 characters", "<p>Term 1\n: Invalid with less than 3 characters</p>", "definitionlists+attributes|advanced");
|
||||
}
|
||||
|
||||
// The `:` can be indented up to 3 spaces:
|
||||
[Test]
|
||||
public void ExtensionsDefinitionLists_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Definition lists
|
||||
//
|
||||
// The following Markdown:
|
||||
// Term 1
|
||||
// : Valid even if `:` starts at most 3 spaces
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <dl>
|
||||
// <dt>Term 1</dt>
|
||||
// <dd>Valid even if <code>:</code> starts at most 3 spaces</dd>
|
||||
// </dl>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Definition lists\n");
|
||||
TestParser.TestSpec("Term 1\n : Valid even if `:` starts at most 3 spaces", "<dl>\n<dt>Term 1</dt>\n<dd>Valid even if <code>:</code> starts at most 3 spaces</dd>\n</dl>", "definitionlists+attributes|advanced");
|
||||
}
|
||||
|
||||
// But more than 3 spaces before `:` will trigger an indented code block:
|
||||
[Test]
|
||||
public void ExtensionsDefinitionLists_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / Definition lists
|
||||
//
|
||||
// The following Markdown:
|
||||
// Term 1
|
||||
//
|
||||
// : Not valid
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Term 1</p>
|
||||
// <pre><code>: Not valid
|
||||
// </code></pre>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / Definition lists\n");
|
||||
TestParser.TestSpec("Term 1\n\n : Not valid", "<p>Term 1</p>\n<pre><code>: Not valid\n</code></pre>", "definitionlists+attributes|advanced");
|
||||
}
|
||||
|
||||
// Definition lists can be nested inside list items
|
||||
[Test]
|
||||
public void ExtensionsDefinitionLists_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / Definition lists
|
||||
//
|
||||
// The following Markdown:
|
||||
// 1. First
|
||||
//
|
||||
// 2. Second
|
||||
//
|
||||
// Term 1
|
||||
// : Definition
|
||||
//
|
||||
// Term 2
|
||||
// : Second Definition
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol>
|
||||
// <li><p>First</p></li>
|
||||
// <li><p>Second</p>
|
||||
// <dl>
|
||||
// <dt>Term 1</dt>
|
||||
// <dd>Definition</dd>
|
||||
// <dt>Term 2</dt>
|
||||
// <dd>Second Definition</dd>
|
||||
// </dl></li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / Definition lists\n");
|
||||
TestParser.TestSpec("1. First\n \n2. Second\n \n Term 1\n : Definition\n \n Term 2\n : Second Definition", "<ol>\n<li><p>First</p></li>\n<li><p>Second</p>\n<dl>\n<dt>Term 1</dt>\n<dd>Definition</dd>\n<dt>Term 2</dt>\n<dd>Second Definition</dd>\n</dl></li>\n</ol>", "definitionlists+attributes|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ This section describes the different extensions supported:
|
||||
|
||||
## Definition lists
|
||||
|
||||
A custom container is similar to a fenced code block, but it is using the character `:` to declare a block (with at least 3 characters), and instead of generating a `<pre><code>...</code></pre>` it will generate a `<div>...</dib>` block.
|
||||
A custom container is similar to a fenced code block, but it is using the character `:` to declare a block (with at least 3 characters), and instead of generating a `<pre><code>...</code></pre>` it will generate a `<div>...</div>` block.
|
||||
|
||||
```````````````````````````````` example
|
||||
|
||||
@@ -105,3 +105,28 @@ Term 1
|
||||
<pre><code>: Not valid
|
||||
</code></pre>
|
||||
````````````````````````````````
|
||||
|
||||
Definition lists can be nested inside list items
|
||||
|
||||
```````````````````````````````` example
|
||||
1. First
|
||||
|
||||
2. Second
|
||||
|
||||
Term 1
|
||||
: Definition
|
||||
|
||||
Term 2
|
||||
: Second Definition
|
||||
.
|
||||
<ol>
|
||||
<li><p>First</p></li>
|
||||
<li><p>Second</p>
|
||||
<dl>
|
||||
<dt>Term 1</dt>
|
||||
<dd>Definition</dd>
|
||||
<dt>Term 2</dt>
|
||||
<dd>Second Definition</dd>
|
||||
</dl></li>
|
||||
</ol>
|
||||
````````````````````````````````
|
||||
|
||||
93
src/Markdig.Tests/Specs/DiagramsSpecs.generated.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
|
||||
// --------------------------------
|
||||
// Diagrams
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.Diagrams
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsMermaidDiagrams
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// Adds support for diagrams extension:
|
||||
//
|
||||
// ## Mermaid diagrams
|
||||
//
|
||||
// Using a fenced code block with the `mermaid` language info will output a `<div class='mermaid'>` instead of a `pre/code` block:
|
||||
[Test]
|
||||
public void ExtensionsMermaidDiagrams_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Mermaid diagrams
|
||||
//
|
||||
// The following Markdown:
|
||||
// ```mermaid
|
||||
// graph TD;
|
||||
// A-->B;
|
||||
// A-->C;
|
||||
// B-->D;
|
||||
// C-->D;
|
||||
// ```
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <div class="mermaid">graph TD;
|
||||
// A-->B;
|
||||
// A-->C;
|
||||
// B-->D;
|
||||
// C-->D;
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Mermaid diagrams\n");
|
||||
TestParser.TestSpec("```mermaid\ngraph TD;\n A-->B;\n A-->C;\n B-->D;\n C-->D;\n```", "<div class=\"mermaid\">graph TD;\n A-->B;\n A-->C;\n B-->D;\n C-->D;\n</div>", "diagrams|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsNomnomlDiagrams
|
||||
{
|
||||
// ## nomnoml diagrams
|
||||
//
|
||||
// Using a fenced code block with the `nomnoml` language info will output a `<div class='nomnoml'>` instead of a `pre/code` block:
|
||||
[Test]
|
||||
public void ExtensionsNomnomlDiagrams_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / nomnoml diagrams
|
||||
//
|
||||
// The following Markdown:
|
||||
// ```nomnoml
|
||||
// [example|
|
||||
// propertyA: Int
|
||||
// propertyB: string
|
||||
// |
|
||||
// methodA()
|
||||
// methodB()
|
||||
// |
|
||||
// [subA]--[subB]
|
||||
// [subA]-:>[sub C]
|
||||
// ]
|
||||
// ```
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <div class="nomnoml">[example|
|
||||
// propertyA: Int
|
||||
// propertyB: string
|
||||
// |
|
||||
// methodA()
|
||||
// methodB()
|
||||
// |
|
||||
// [subA]--[subB]
|
||||
// [subA]-:>[sub C]
|
||||
// ]
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / nomnoml diagrams\n");
|
||||
TestParser.TestSpec("```nomnoml\n[example|\n propertyA: Int\n propertyB: string\n|\n methodA()\n methodB()\n|\n [subA]--[subB]\n [subA]-:>[sub C]\n]\n```", "<div class=\"nomnoml\">[example|\n propertyA: Int\n propertyB: string\n|\n methodA()\n methodB()\n|\n [subA]--[subB]\n [subA]-:>[sub C]\n]\n</div>", "diagrams|advanced");
|
||||
}
|
||||
// TODO: Add other text diagram languages
|
||||
}
|
||||
}
|
||||
57
src/Markdig.Tests/Specs/DiagramsSpecs.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Extensions
|
||||
|
||||
Adds support for diagrams extension:
|
||||
|
||||
## Mermaid diagrams
|
||||
|
||||
Using a fenced code block with the `mermaid` language info will output a `<div class='mermaid'>` instead of a `pre/code` block:
|
||||
|
||||
```````````````````````````````` example
|
||||
```mermaid
|
||||
graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
```
|
||||
.
|
||||
<div class="mermaid">graph TD;
|
||||
A-->B;
|
||||
A-->C;
|
||||
B-->D;
|
||||
C-->D;
|
||||
</div>
|
||||
````````````````````````````````
|
||||
|
||||
## nomnoml diagrams
|
||||
|
||||
Using a fenced code block with the `nomnoml` language info will output a `<div class='nomnoml'>` instead of a `pre/code` block:
|
||||
|
||||
```````````````````````````````` example
|
||||
```nomnoml
|
||||
[example|
|
||||
propertyA: Int
|
||||
propertyB: string
|
||||
|
|
||||
methodA()
|
||||
methodB()
|
||||
|
|
||||
[subA]--[subB]
|
||||
[subA]-:>[sub C]
|
||||
]
|
||||
```
|
||||
.
|
||||
<div class="nomnoml">[example|
|
||||
propertyA: Int
|
||||
propertyB: string
|
||||
|
|
||||
methodA()
|
||||
methodB()
|
||||
|
|
||||
[subA]--[subB]
|
||||
[subA]-:>[sub C]
|
||||
]
|
||||
</div>
|
||||
````````````````````````````````
|
||||
|
||||
TODO: Add other text diagram languages
|
||||
90
src/Markdig.Tests/Specs/EmojiSpecs.generated.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
// --------------------------------
|
||||
// Emoji
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.Emoji
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsEmoji
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Emoji
|
||||
//
|
||||
// Emoji shortcodes and smileys can be converted to their respective unicode characters:
|
||||
[Test]
|
||||
public void ExtensionsEmoji_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Emoji
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a test with a :) and a :angry: smiley
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a test with a 😃 and a 😠 smiley</p>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Emoji\n");
|
||||
TestParser.TestSpec("This is a test with a :) and a :angry: smiley", "<p>This is a test with a 😃 and a 😠 smiley</p>", "emojis|advanced+emojis");
|
||||
}
|
||||
|
||||
// An emoji needs to be preceded by a space:
|
||||
[Test]
|
||||
public void ExtensionsEmoji_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Emoji
|
||||
//
|
||||
// The following Markdown:
|
||||
// These are not:) an emoji with a:) x:angry:x
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>These are not:) an emoji with a:) x:angry:x</p>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Emoji\n");
|
||||
TestParser.TestSpec("These are not:) an emoji with a:) x:angry:x", "<p>These are not:) an emoji with a:) x:angry:x</p>", "emojis|advanced+emojis");
|
||||
}
|
||||
|
||||
// Emojis can be followed by close punctuation (or any other characters):
|
||||
[Test]
|
||||
public void ExtensionsEmoji_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Emoji
|
||||
//
|
||||
// The following Markdown:
|
||||
// We all need :), it makes us :muscle:. (and :ok_hand:).
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>We all need 😃, it makes us 💪. (and 👌).</p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Emoji\n");
|
||||
TestParser.TestSpec("We all need :), it makes us :muscle:. (and :ok_hand:).", "<p>We all need 😃, it makes us 💪. (and 👌).</p>", "emojis|advanced+emojis");
|
||||
}
|
||||
|
||||
// Sentences can end with emojis:
|
||||
[Test]
|
||||
public void ExtensionsEmoji_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Emoji
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a sentence :ok_hand:
|
||||
// and keeps going to the next line :)
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a sentence 👌
|
||||
// and keeps going to the next line 😃</p>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Emoji\n");
|
||||
TestParser.TestSpec("This is a sentence :ok_hand:\nand keeps going to the next line :)", "<p>This is a sentence 👌\nand keeps going to the next line 😃</p>", "emojis|advanced+emojis");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,36 @@ This section describes the different extensions supported:
|
||||
|
||||
## Emoji
|
||||
|
||||
Emoji and smiley can be converted to their respective unicode characters:
|
||||
Emoji shortcodes and smileys can be converted to their respective unicode characters:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a test with a :) and a :angry: smiley
|
||||
.
|
||||
<p>This is a test with a 😃 and a 😠 smiley</p>
|
||||
````````````````````````````````
|
||||
|
||||
An emoji needs to be preceded by a space:
|
||||
|
||||
```````````````````````````````` example
|
||||
These are not:) an emoji with a:) x:angry:x
|
||||
.
|
||||
<p>These are not:) an emoji with a:) x:angry:x</p>
|
||||
````````````````````````````````
|
||||
|
||||
Emojis can be followed by close punctuation (or any other characters):
|
||||
|
||||
```````````````````````````````` example
|
||||
We all need :), it makes us :muscle:. (and :ok_hand:).
|
||||
.
|
||||
<p>We all need 😃, it makes us 💪. (and 👌).</p>
|
||||
````````````````````````````````
|
||||
|
||||
Sentences can end with emojis:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a sentence :ok_hand:
|
||||
and keeps going to the next line :)
|
||||
.
|
||||
<p>This is a sentence 👌
|
||||
and keeps going to the next line 😃</p>
|
||||
````````````````````````````````
|
||||
|
||||
151
src/Markdig.Tests/Specs/EmphasisExtraSpecs.generated.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
// --------------------------------
|
||||
// Emphasis Extra
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.EmphasisExtra
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsStrikethrough
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// The following additional emphasis are supported:
|
||||
//
|
||||
// ## Strikethrough
|
||||
//
|
||||
// Allows to strikethrough a span of text by surrounding it by `~~`. The semantic used for the generated HTML is the tag `<del>`.
|
||||
[Test]
|
||||
public void ExtensionsStrikethrough_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Strikethrough
|
||||
//
|
||||
// The following Markdown:
|
||||
// The following text ~~is deleted~~
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>The following text <del>is deleted</del></p>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Strikethrough\n");
|
||||
TestParser.TestSpec("The following text ~~is deleted~~", "<p>The following text <del>is deleted</del></p>", "emphasisextras|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsSuperscriptAndSubscript
|
||||
{
|
||||
// ## Superscript and Subscript
|
||||
//
|
||||
// Superscripts can be written by surrounding a text by ^ characters; subscripts can be written by surrounding the subscripted text by ~ characters
|
||||
[Test]
|
||||
public void ExtensionsSuperscriptAndSubscript_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Superscript and Subscript
|
||||
//
|
||||
// The following Markdown:
|
||||
// H~2~O is a liquid. 2^10^ is 1024
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>H<sub>2</sub>O is a liquid. 2<sup>10</sup> is 1024</p>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Superscript and Subscript\n");
|
||||
TestParser.TestSpec("H~2~O is a liquid. 2^10^ is 1024", "<p>H<sub>2</sub>O is a liquid. 2<sup>10</sup> is 1024</p>", "emphasisextras|advanced");
|
||||
}
|
||||
|
||||
// Certain punctuation characters are exempted from the rule forbidding them within inline delimiters
|
||||
[Test]
|
||||
public void ExtensionsSuperscriptAndSubscript_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Superscript and Subscript
|
||||
//
|
||||
// The following Markdown:
|
||||
// One quintillionth can be expressed as 10^-18^
|
||||
//
|
||||
// Daggers^†^ and double-daggers^‡^ can be used to denote notes.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>One quintillionth can be expressed as 10<sup>-18</sup></p>
|
||||
// <p>Daggers<sup>†</sup> and double-daggers<sup>‡</sup> can be used to denote notes.</p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Superscript and Subscript\n");
|
||||
TestParser.TestSpec("One quintillionth can be expressed as 10^-18^\n\nDaggers^†^ and double-daggers^‡^ can be used to denote notes.", "<p>One quintillionth can be expressed as 10<sup>-18</sup></p>\n<p>Daggers<sup>†</sup> and double-daggers<sup>‡</sup> can be used to denote notes.</p>", "emphasisextras|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsInserted
|
||||
{
|
||||
// ## Inserted
|
||||
//
|
||||
// Inserted text can be used to specify that a text has been added to a document. The semantic used for the generated HTML is the tag `<ins>`.
|
||||
[Test]
|
||||
public void ExtensionsInserted_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Inserted
|
||||
//
|
||||
// The following Markdown:
|
||||
// ++Inserted text++
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><ins>Inserted text</ins></p>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Inserted\n");
|
||||
TestParser.TestSpec("++Inserted text++", "<p><ins>Inserted text</ins></p>", "emphasisextras|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsMarked
|
||||
{
|
||||
// ## Marked
|
||||
//
|
||||
// Marked text can be used to specify that a text has been marked in a document. The semantic used for the generated HTML is the tag `<mark>`.
|
||||
[Test]
|
||||
public void ExtensionsMarked_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / Marked
|
||||
//
|
||||
// The following Markdown:
|
||||
// ==Marked text==
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><mark>Marked text</mark></p>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / Marked\n");
|
||||
TestParser.TestSpec("==Marked text==", "<p><mark>Marked text</mark></p>", "emphasisextras|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsEmphasisOnHtmlEntities
|
||||
{
|
||||
// ## Emphasis on Html Entities
|
||||
[Test]
|
||||
public void ExtensionsEmphasisOnHtmlEntities_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / Emphasis on Html Entities
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is text MyBrand ^®^ and MyTrademark ^™^
|
||||
// This is text MyBrand^®^ and MyTrademark^™^
|
||||
// This is text MyBrand~®~ and MyCopyright^©^
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is text MyBrand <sup>®</sup> and MyTrademark <sup>TM</sup>
|
||||
// This is text MyBrand<sup>®</sup> and MyTrademark<sup>TM</sup>
|
||||
// This is text MyBrand<sub>®</sub> and MyCopyright<sup>©</sup></p>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / Emphasis on Html Entities\n");
|
||||
TestParser.TestSpec("This is text MyBrand ^®^ and MyTrademark ^™^\nThis is text MyBrand^®^ and MyTrademark^™^\nThis is text MyBrand~®~ and MyCopyright^©^", "<p>This is text MyBrand <sup>®</sup> and MyTrademark <sup>TM</sup>\nThis is text MyBrand<sup>®</sup> and MyTrademark<sup>TM</sup>\nThis is text MyBrand<sub>®</sub> and MyCopyright<sup>©</sup></p>", "emphasisextras|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,17 @@ H~2~O is a liquid. 2^10^ is 1024
|
||||
.
|
||||
<p>H<sub>2</sub>O is a liquid. 2<sup>10</sup> is 1024</p>
|
||||
````````````````````````````````
|
||||
|
||||
Certain punctuation characters are exempted from the rule forbidding them within inline delimiters
|
||||
|
||||
```````````````````````````````` example
|
||||
One quintillionth can be expressed as 10^-18^
|
||||
|
||||
Daggers^†^ and double-daggers^‡^ can be used to denote notes.
|
||||
.
|
||||
<p>One quintillionth can be expressed as 10<sup>-18</sup></p>
|
||||
<p>Daggers<sup>†</sup> and double-daggers<sup>‡</sup> can be used to denote notes.</p>
|
||||
````````````````````````````````
|
||||
|
||||
## Inserted
|
||||
|
||||
@@ -41,3 +52,16 @@ Marked text can be used to specify that a text has been marked in a document. T
|
||||
.
|
||||
<p><mark>Marked text</mark></p>
|
||||
````````````````````````````````
|
||||
## Emphasis on Html Entities
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
This is text MyBrand ^®^ and MyTrademark ^™^
|
||||
This is text MyBrand^®^ and MyTrademark^™^
|
||||
This is text MyBrand~®~ and MyCopyright^©^
|
||||
.
|
||||
<p>This is text MyBrand <sup>®</sup> and MyTrademark <sup>TM</sup>
|
||||
This is text MyBrand<sup>®</sup> and MyTrademark<sup>TM</sup>
|
||||
This is text MyBrand<sub>®</sub> and MyCopyright<sup>©</sup></p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
|
||||
// --------------------------------
|
||||
// Figures, Footers and Cites
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.FiguresFootersAndCites
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsFigures
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// The following the figure extension:
|
||||
//
|
||||
// ## Figures
|
||||
//
|
||||
// A figure can be defined by using a pattern equivalent to a fenced code block but with the character `^`
|
||||
[Test]
|
||||
public void ExtensionsFigures_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Figures
|
||||
//
|
||||
// The following Markdown:
|
||||
// ^^^
|
||||
// This is a figure
|
||||
// ^^^ This is a *caption*
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <figure>
|
||||
// <p>This is a figure</p>
|
||||
// <figcaption>This is a <em>caption</em></figcaption>
|
||||
// </figure>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Figures\n");
|
||||
TestParser.TestSpec("^^^\nThis is a figure\n^^^ This is a *caption*", "<figure>\n<p>This is a figure</p>\n<figcaption>This is a <em>caption</em></figcaption>\n</figure>", "figures+footers+citations|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsFooters
|
||||
{
|
||||
// ## Footers
|
||||
//
|
||||
// A footer equivalent to a block quote parsing but starts with double character ^^
|
||||
[Test]
|
||||
public void ExtensionsFooters_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Footers
|
||||
//
|
||||
// The following Markdown:
|
||||
// ^^ This is a footer
|
||||
// ^^ multi-line
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <footer>This is a footer
|
||||
// multi-line</footer>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Footers\n");
|
||||
TestParser.TestSpec("^^ This is a footer\n^^ multi-line", "<footer>This is a footer\nmulti-line</footer>", "figures+footers+citations|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsCite
|
||||
{
|
||||
// ## Cite
|
||||
//
|
||||
// A cite is working like an emphasis but using the double character ""
|
||||
[Test]
|
||||
public void ExtensionsCite_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Cite
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a ""citation of someone""
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <cite>citation of someone</cite></p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Cite\n");
|
||||
TestParser.TestSpec("This is a \"\"citation of someone\"\"", "<p>This is a <cite>citation of someone</cite></p>", "figures+footers+citations|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
192
src/Markdig.Tests/Specs/FootnotesSpecs.generated.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
|
||||
// --------------------------------
|
||||
// Footnotes
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.Footnotes
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsFootnotes
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Footnotes
|
||||
//
|
||||
// Allows footnotes using the following syntax (taken from pandoc example):
|
||||
[Test]
|
||||
public void ExtensionsFootnotes_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Footnotes
|
||||
//
|
||||
// The following Markdown:
|
||||
// Here is a footnote reference,[^1] and another.[^longnote]
|
||||
//
|
||||
// This is another reference to [^1]
|
||||
//
|
||||
// [^1]: Here is the footnote.
|
||||
//
|
||||
// And another reference to [^longnote]
|
||||
//
|
||||
// [^longnote]: Here's one with multiple blocks.
|
||||
//
|
||||
// Subsequent paragraphs are indented to show that they
|
||||
// belong to the previous footnote.
|
||||
//
|
||||
// > This is a block quote
|
||||
// > Inside a footnote
|
||||
//
|
||||
// { some.code }
|
||||
//
|
||||
// The whole paragraph can be indented, or just the first
|
||||
// line. In this way, multi-paragraph footnotes work like
|
||||
// multi-paragraph list items.
|
||||
//
|
||||
// This paragraph won't be part of the note, because it
|
||||
// isn't indented.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Here is a footnote reference,<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a> and another.<a id="fnref:3" href="#fn:2" class="footnote-ref"><sup>2</sup></a></p>
|
||||
// <p>This is another reference to <a id="fnref:2" href="#fn:1" class="footnote-ref"><sup>1</sup></a></p>
|
||||
// <p>And another reference to <a id="fnref:4" href="#fn:2" class="footnote-ref"><sup>2</sup></a></p>
|
||||
// <p>This paragraph won't be part of the note, because it
|
||||
// isn't indented.</p>
|
||||
// <div class="footnotes">
|
||||
// <hr />
|
||||
// <ol>
|
||||
// <li id="fn:1">
|
||||
// <p>Here is the footnote.<a href="#fnref:1" class="footnote-back-ref">↩</a><a href="#fnref:2" class="footnote-back-ref">↩</a></p>
|
||||
// </li>
|
||||
// <li id="fn:2">
|
||||
// <p>Here's one with multiple blocks.</p>
|
||||
// <p>Subsequent paragraphs are indented to show that they
|
||||
// belong to the previous footnote.</p>
|
||||
// <blockquote>
|
||||
// <p>This is a block quote
|
||||
// Inside a footnote</p>
|
||||
// </blockquote>
|
||||
// <pre><code>{ some.code }
|
||||
// </code></pre>
|
||||
// <p>The whole paragraph can be indented, or just the first
|
||||
// line. In this way, multi-paragraph footnotes work like
|
||||
// multi-paragraph list items.<a href="#fnref:3" class="footnote-back-ref">↩</a><a href="#fnref:4" class="footnote-back-ref">↩</a></p>
|
||||
// </li>
|
||||
// </ol>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Footnotes\n");
|
||||
TestParser.TestSpec("Here is a footnote reference,[^1] and another.[^longnote]\n\nThis is another reference to [^1]\n\n[^1]: Here is the footnote.\n\nAnd another reference to [^longnote]\n\n[^longnote]: Here's one with multiple blocks.\n\n Subsequent paragraphs are indented to show that they\nbelong to the previous footnote.\n\n > This is a block quote\n > Inside a footnote\n\n { some.code }\n\n The whole paragraph can be indented, or just the first\n line. In this way, multi-paragraph footnotes work like\n multi-paragraph list items.\n\nThis paragraph won't be part of the note, because it\nisn't indented.", "<p>Here is a footnote reference,<a id=\"fnref:1\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a> and another.<a id=\"fnref:3\" href=\"#fn:2\" class=\"footnote-ref\"><sup>2</sup></a></p>\n<p>This is another reference to <a id=\"fnref:2\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a></p>\n<p>And another reference to <a id=\"fnref:4\" href=\"#fn:2\" class=\"footnote-ref\"><sup>2</sup></a></p>\n<p>This paragraph won't be part of the note, because it\nisn't indented.</p>\n<div class=\"footnotes\">\n<hr />\n<ol>\n<li id=\"fn:1\">\n<p>Here is the footnote.<a href=\"#fnref:1\" class=\"footnote-back-ref\">↩</a><a href=\"#fnref:2\" class=\"footnote-back-ref\">↩</a></p>\n</li>\n<li id=\"fn:2\">\n<p>Here's one with multiple blocks.</p>\n<p>Subsequent paragraphs are indented to show that they\nbelong to the previous footnote.</p>\n<blockquote>\n<p>This is a block quote\nInside a footnote</p>\n</blockquote>\n<pre><code>{ some.code }\n</code></pre>\n<p>The whole paragraph can be indented, or just the first\nline. In this way, multi-paragraph footnotes work like\nmulti-paragraph list items.<a href=\"#fnref:3\" class=\"footnote-back-ref\">↩</a><a href=\"#fnref:4\" class=\"footnote-back-ref\">↩</a></p>\n</li>\n</ol>\n</div>", "footnotes|advanced");
|
||||
}
|
||||
|
||||
// Check with multiple consecutive footnotes:
|
||||
[Test]
|
||||
public void ExtensionsFootnotes_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Footnotes
|
||||
//
|
||||
// The following Markdown:
|
||||
// Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].
|
||||
//
|
||||
// [^1]: Footnote 1 text
|
||||
//
|
||||
// [^2]: Footnote 2 text
|
||||
//
|
||||
// a
|
||||
//
|
||||
// [^3]: Footnote 3 text
|
||||
//
|
||||
// [^4]: Footnote 4 text
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Here is a footnote<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. And another one<a id="fnref:2" href="#fn:2" class="footnote-ref"><sup>2</sup></a>. And a third one<a id="fnref:3" href="#fn:3" class="footnote-ref"><sup>3</sup></a>. And a fourth<a id="fnref:4" href="#fn:4" class="footnote-ref"><sup>4</sup></a>.</p>
|
||||
// <p>a</p>
|
||||
// <div class="footnotes">
|
||||
// <hr />
|
||||
// <ol>
|
||||
// <li id="fn:1">
|
||||
// <p>Footnote 1 text<a href="#fnref:1" class="footnote-back-ref">↩</a></p></li>
|
||||
// <li id="fn:2">
|
||||
// <p>Footnote 2 text<a href="#fnref:2" class="footnote-back-ref">↩</a></p></li>
|
||||
// <li id="fn:3">
|
||||
// <p>Footnote 3 text<a href="#fnref:3" class="footnote-back-ref">↩</a></p></li>
|
||||
// <li id="fn:4">
|
||||
// <p>Footnote 4 text<a href="#fnref:4" class="footnote-back-ref">↩</a></p></li>
|
||||
// </ol>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Footnotes\n");
|
||||
TestParser.TestSpec("Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].\n\n[^1]: Footnote 1 text\n\n[^2]: Footnote 2 text\n\na\n\n[^3]: Footnote 3 text\n\n[^4]: Footnote 4 text", "<p>Here is a footnote<a id=\"fnref:1\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a>. And another one<a id=\"fnref:2\" href=\"#fn:2\" class=\"footnote-ref\"><sup>2</sup></a>. And a third one<a id=\"fnref:3\" href=\"#fn:3\" class=\"footnote-ref\"><sup>3</sup></a>. And a fourth<a id=\"fnref:4\" href=\"#fn:4\" class=\"footnote-ref\"><sup>4</sup></a>.</p>\n<p>a</p>\n<div class=\"footnotes\">\n<hr />\n<ol>\n<li id=\"fn:1\">\n<p>Footnote 1 text<a href=\"#fnref:1\" class=\"footnote-back-ref\">↩</a></p></li>\n<li id=\"fn:2\">\n<p>Footnote 2 text<a href=\"#fnref:2\" class=\"footnote-back-ref\">↩</a></p></li>\n<li id=\"fn:3\">\n<p>Footnote 3 text<a href=\"#fnref:3\" class=\"footnote-back-ref\">↩</a></p></li>\n<li id=\"fn:4\">\n<p>Footnote 4 text<a href=\"#fnref:4\" class=\"footnote-back-ref\">↩</a></p></li>\n</ol>\n</div>", "footnotes|advanced");
|
||||
}
|
||||
|
||||
// Another test with consecutive footnotes without a blank line separator:
|
||||
[Test]
|
||||
public void ExtensionsFootnotes_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Footnotes
|
||||
//
|
||||
// The following Markdown:
|
||||
// Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].
|
||||
//
|
||||
// [^1]: Footnote 1 text
|
||||
// [^2]: Footnote 2 text
|
||||
// [^3]: Footnote 3 text
|
||||
// [^4]: Footnote 4 text
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Here is a footnote<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. And another one<a id="fnref:2" href="#fn:2" class="footnote-ref"><sup>2</sup></a>. And a third one<a id="fnref:3" href="#fn:3" class="footnote-ref"><sup>3</sup></a>. And a fourth<a id="fnref:4" href="#fn:4" class="footnote-ref"><sup>4</sup></a>.</p>
|
||||
// <div class="footnotes">
|
||||
// <hr />
|
||||
// <ol>
|
||||
// <li id="fn:1">
|
||||
// <p>Footnote 1 text<a href="#fnref:1" class="footnote-back-ref">↩</a></p></li>
|
||||
// <li id="fn:2">
|
||||
// <p>Footnote 2 text<a href="#fnref:2" class="footnote-back-ref">↩</a></p></li>
|
||||
// <li id="fn:3">
|
||||
// <p>Footnote 3 text<a href="#fnref:3" class="footnote-back-ref">↩</a></p></li>
|
||||
// <li id="fn:4">
|
||||
// <p>Footnote 4 text<a href="#fnref:4" class="footnote-back-ref">↩</a></p></li>
|
||||
// </ol>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Footnotes\n");
|
||||
TestParser.TestSpec("Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].\n\n[^1]: Footnote 1 text\n[^2]: Footnote 2 text\n[^3]: Footnote 3 text\n[^4]: Footnote 4 text", "<p>Here is a footnote<a id=\"fnref:1\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a>. And another one<a id=\"fnref:2\" href=\"#fn:2\" class=\"footnote-ref\"><sup>2</sup></a>. And a third one<a id=\"fnref:3\" href=\"#fn:3\" class=\"footnote-ref\"><sup>3</sup></a>. And a fourth<a id=\"fnref:4\" href=\"#fn:4\" class=\"footnote-ref\"><sup>4</sup></a>.</p>\n<div class=\"footnotes\">\n<hr />\n<ol>\n<li id=\"fn:1\">\n<p>Footnote 1 text<a href=\"#fnref:1\" class=\"footnote-back-ref\">↩</a></p></li>\n<li id=\"fn:2\">\n<p>Footnote 2 text<a href=\"#fnref:2\" class=\"footnote-back-ref\">↩</a></p></li>\n<li id=\"fn:3\">\n<p>Footnote 3 text<a href=\"#fnref:3\" class=\"footnote-back-ref\">↩</a></p></li>\n<li id=\"fn:4\">\n<p>Footnote 4 text<a href=\"#fnref:4\" class=\"footnote-back-ref\">↩</a></p></li>\n</ol>\n</div>", "footnotes|advanced");
|
||||
}
|
||||
|
||||
// A footnote link inside a list should work as well:
|
||||
[Test]
|
||||
public void ExtensionsFootnotes_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Footnotes
|
||||
//
|
||||
// The following Markdown:
|
||||
// - abc
|
||||
// - def[^1]
|
||||
//
|
||||
// [^1]: Here is the footnote.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ul>
|
||||
// <li>abc</li>
|
||||
// <li>def<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a></li>
|
||||
// </ul>
|
||||
// <div class="footnotes">
|
||||
// <hr />
|
||||
// <ol>
|
||||
// <li id="fn:1">
|
||||
// <p>Here is the footnote.<a href="#fnref:1" class="footnote-back-ref">↩</a></p></li>
|
||||
// </ol>
|
||||
// </div>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Footnotes\n");
|
||||
TestParser.TestSpec("- abc\n- def[^1]\n\n[^1]: Here is the footnote.", "<ul>\n<li>abc</li>\n<li>def<a id=\"fnref:1\" href=\"#fn:1\" class=\"footnote-ref\"><sup>1</sup></a></li>\n</ul>\n<div class=\"footnotes\">\n<hr />\n<ol>\n<li id=\"fn:1\">\n<p>Here is the footnote.<a href=\"#fnref:1\" class=\"footnote-back-ref\">↩</a></p></li>\n</ol>\n</div>", "footnotes|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This section describes the different extensions supported:
|
||||
|
||||
## Footontes
|
||||
## Footnotes
|
||||
|
||||
Allows footnotes using the following syntax (taken from pandoc example):
|
||||
|
||||
@@ -61,3 +61,81 @@ multi-paragraph list items.<a href="#fnref:3" class="footnote-back-ref">↩<
|
||||
</div>
|
||||
````````````````````````````````
|
||||
|
||||
Check with multiple consecutive footnotes:
|
||||
|
||||
```````````````````````````````` example
|
||||
Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].
|
||||
|
||||
[^1]: Footnote 1 text
|
||||
|
||||
[^2]: Footnote 2 text
|
||||
|
||||
a
|
||||
|
||||
[^3]: Footnote 3 text
|
||||
|
||||
[^4]: Footnote 4 text
|
||||
.
|
||||
<p>Here is a footnote<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. And another one<a id="fnref:2" href="#fn:2" class="footnote-ref"><sup>2</sup></a>. And a third one<a id="fnref:3" href="#fn:3" class="footnote-ref"><sup>3</sup></a>. And a fourth<a id="fnref:4" href="#fn:4" class="footnote-ref"><sup>4</sup></a>.</p>
|
||||
<p>a</p>
|
||||
<div class="footnotes">
|
||||
<hr />
|
||||
<ol>
|
||||
<li id="fn:1">
|
||||
<p>Footnote 1 text<a href="#fnref:1" class="footnote-back-ref">↩</a></p></li>
|
||||
<li id="fn:2">
|
||||
<p>Footnote 2 text<a href="#fnref:2" class="footnote-back-ref">↩</a></p></li>
|
||||
<li id="fn:3">
|
||||
<p>Footnote 3 text<a href="#fnref:3" class="footnote-back-ref">↩</a></p></li>
|
||||
<li id="fn:4">
|
||||
<p>Footnote 4 text<a href="#fnref:4" class="footnote-back-ref">↩</a></p></li>
|
||||
</ol>
|
||||
</div>
|
||||
````````````````````````````````
|
||||
|
||||
Another test with consecutive footnotes without a blank line separator:
|
||||
|
||||
```````````````````````````````` example
|
||||
Here is a footnote[^1]. And another one[^2]. And a third one[^3]. And a fourth[^4].
|
||||
|
||||
[^1]: Footnote 1 text
|
||||
[^2]: Footnote 2 text
|
||||
[^3]: Footnote 3 text
|
||||
[^4]: Footnote 4 text
|
||||
.
|
||||
<p>Here is a footnote<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a>. And another one<a id="fnref:2" href="#fn:2" class="footnote-ref"><sup>2</sup></a>. And a third one<a id="fnref:3" href="#fn:3" class="footnote-ref"><sup>3</sup></a>. And a fourth<a id="fnref:4" href="#fn:4" class="footnote-ref"><sup>4</sup></a>.</p>
|
||||
<div class="footnotes">
|
||||
<hr />
|
||||
<ol>
|
||||
<li id="fn:1">
|
||||
<p>Footnote 1 text<a href="#fnref:1" class="footnote-back-ref">↩</a></p></li>
|
||||
<li id="fn:2">
|
||||
<p>Footnote 2 text<a href="#fnref:2" class="footnote-back-ref">↩</a></p></li>
|
||||
<li id="fn:3">
|
||||
<p>Footnote 3 text<a href="#fnref:3" class="footnote-back-ref">↩</a></p></li>
|
||||
<li id="fn:4">
|
||||
<p>Footnote 4 text<a href="#fnref:4" class="footnote-back-ref">↩</a></p></li>
|
||||
</ol>
|
||||
</div>
|
||||
````````````````````````````````
|
||||
|
||||
A footnote link inside a list should work as well:
|
||||
|
||||
```````````````````````````````` example
|
||||
- abc
|
||||
- def[^1]
|
||||
|
||||
[^1]: Here is the footnote.
|
||||
.
|
||||
<ul>
|
||||
<li>abc</li>
|
||||
<li>def<a id="fnref:1" href="#fn:1" class="footnote-ref"><sup>1</sup></a></li>
|
||||
</ul>
|
||||
<div class="footnotes">
|
||||
<hr />
|
||||
<ol>
|
||||
<li id="fn:1">
|
||||
<p>Here is the footnote.<a href="#fnref:1" class="footnote-back-ref">↩</a></p></li>
|
||||
</ol>
|
||||
</div>
|
||||
````````````````````````````````
|
||||
|
||||
105
src/Markdig.Tests/Specs/GenericAttributesSpecs.generated.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
// --------------------------------
|
||||
// Generic Attributes
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.GenericAttributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsGenericAttributes
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Generic Attributes
|
||||
//
|
||||
// Attributes can be attached to:
|
||||
// - The previous inline element if the previous element is not a literal
|
||||
// - The next block if the current block is a paragraph and the attributes is the only inline present in the paragraph
|
||||
// - Or the current block
|
||||
//
|
||||
// Attributes can be of 3 kinds:
|
||||
//
|
||||
// - An id element, starting by `#` that will be used to set the `id` property of the HTML element
|
||||
// - A class element, starting by `.` that will be appended to the CSS class property of the HTML element
|
||||
// - a `name=value` or `name="value"` that will be appended as an attribute of the HTML element
|
||||
//
|
||||
// The following shows that attributes is attached to the current block or the previous inline:
|
||||
[Test]
|
||||
public void ExtensionsGenericAttributes_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Generic Attributes
|
||||
//
|
||||
// The following Markdown:
|
||||
// # This is a heading with an an attribute{#heading-link}
|
||||
//
|
||||
// # This is a heading # {#heading-link2}
|
||||
//
|
||||
// [This is a link](http://google.com){#a-link .myclass data-lang=fr data-value="This is a value"}
|
||||
//
|
||||
// This is a heading{#heading-link2}
|
||||
// -----------------
|
||||
//
|
||||
// This is a paragraph with an attached attributes {#myparagraph attached-bool-property attached-bool-property2}
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="heading-link">This is a heading with an an attribute</h1>
|
||||
// <h1 id="heading-link2">This is a heading</h1>
|
||||
// <p><a href="http://google.com" id="a-link" class="myclass" data-lang="fr" data-value="This is a value">This is a link</a></p>
|
||||
// <h2 id="heading-link2">This is a heading</h2>
|
||||
// <p id="myparagraph" attached-bool-property="" attached-bool-property2="">This is a paragraph with an attached attributes </p>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Generic Attributes\n");
|
||||
TestParser.TestSpec("# This is a heading with an an attribute{#heading-link}\n\n# This is a heading # {#heading-link2}\n\n[This is a link](http://google.com){#a-link .myclass data-lang=fr data-value=\"This is a value\"}\n\nThis is a heading{#heading-link2}\n-----------------\n\nThis is a paragraph with an attached attributes {#myparagraph attached-bool-property attached-bool-property2}", "<h1 id=\"heading-link\">This is a heading with an an attribute</h1>\n<h1 id=\"heading-link2\">This is a heading</h1>\n<p><a href=\"http://google.com\" id=\"a-link\" class=\"myclass\" data-lang=\"fr\" data-value=\"This is a value\">This is a link</a></p>\n<h2 id=\"heading-link2\">This is a heading</h2>\n<p id=\"myparagraph\" attached-bool-property=\"\" attached-bool-property2=\"\">This is a paragraph with an attached attributes </p>", "attributes|advanced");
|
||||
}
|
||||
|
||||
// The following shows that attributes can be attached to the next block if they are used inside a single line just preceding the block (and preceded by a blank line or beginning of a block container):
|
||||
[Test]
|
||||
public void ExtensionsGenericAttributes_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Generic Attributes
|
||||
//
|
||||
// The following Markdown:
|
||||
// {#fenced-id .fenced-class}
|
||||
// ~~~
|
||||
// This is a fenced with attached attributes
|
||||
// ~~~
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <pre><code id="fenced-id" class="fenced-class">This is a fenced with attached attributes
|
||||
// </code></pre>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Generic Attributes\n");
|
||||
TestParser.TestSpec("{#fenced-id .fenced-class}\n~~~\nThis is a fenced with attached attributes\n~~~ ", "<pre><code id=\"fenced-id\" class=\"fenced-class\">This is a fenced with attached attributes\n</code></pre>", "attributes|advanced");
|
||||
}
|
||||
|
||||
// Attribute values can be one character long
|
||||
[Test]
|
||||
public void ExtensionsGenericAttributes_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Generic Attributes
|
||||
//
|
||||
// The following Markdown:
|
||||
// [Foo](url){data-x=1}
|
||||
//
|
||||
// [Foo](url){data-x='1'}
|
||||
//
|
||||
// [Foo](url){data-x=11}
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="url" data-x="1">Foo</a></p>
|
||||
// <p><a href="url" data-x="1">Foo</a></p>
|
||||
// <p><a href="url" data-x="11">Foo</a></p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Generic Attributes\n");
|
||||
TestParser.TestSpec("[Foo](url){data-x=1}\n\n[Foo](url){data-x='1'}\n\n[Foo](url){data-x=11}", "<p><a href=\"url\" data-x=\"1\">Foo</a></p>\n<p><a href=\"url\" data-x=\"1\">Foo</a></p>\n<p><a href=\"url\" data-x=\"11\">Foo</a></p>", "attributes|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,13 +27,13 @@ The following shows that attributes is attached to the current block or the prev
|
||||
This is a heading{#heading-link2}
|
||||
-----------------
|
||||
|
||||
This is a paragraph with an attached attributes {#myparagraph attached-bool-property}
|
||||
This is a paragraph with an attached attributes {#myparagraph attached-bool-property attached-bool-property2}
|
||||
.
|
||||
<h1 id="heading-link">This is a heading with an an attribute</h1>
|
||||
<h1 id="heading-link2">This is a heading</h1>
|
||||
<p><a href="http://google.com" id="a-link" class="myclass" data-lang="fr" data-value="This is a value">This is a link</a></p>
|
||||
<h2 id="heading-link2">This is a heading</h2>
|
||||
<p id="myparagraph" attached-bool-property>This is a paragraph with an attached attributes </p>
|
||||
<p id="myparagraph" attached-bool-property="" attached-bool-property2="">This is a paragraph with an attached attributes </p>
|
||||
````````````````````````````````
|
||||
|
||||
The following shows that attributes can be attached to the next block if they are used inside a single line just preceding the block (and preceded by a blank line or beginning of a block container):
|
||||
@@ -47,3 +47,17 @@ This is a fenced with attached attributes
|
||||
<pre><code id="fenced-id" class="fenced-class">This is a fenced with attached attributes
|
||||
</code></pre>
|
||||
````````````````````````````````
|
||||
|
||||
Attribute values can be one character long
|
||||
|
||||
```````````````````````````````` example
|
||||
[Foo](url){data-x=1}
|
||||
|
||||
[Foo](url){data-x='1'}
|
||||
|
||||
[Foo](url){data-x=11}
|
||||
.
|
||||
<p><a href="url" data-x="1">Foo</a></p>
|
||||
<p><a href="url" data-x="1">Foo</a></p>
|
||||
<p><a href="url" data-x="11">Foo</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
233
src/Markdig.Tests/Specs/GlobalizationSpecs.generated.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
|
||||
// --------------------------------
|
||||
// Globalization
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.Globalization
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsGlobalization
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Globalization
|
||||
// Adds support for RTL content by adding `dir="rtl"` and `align="right` attributes to the appropriate html elements. Left to right text is not affected by this extension.
|
||||
//
|
||||
// Whether a markdown block is marked as RTL or not is determined by the [first strong character](https://en.wikipedia.org/wiki/Bi-directional_text#Strong_characters) of the block.
|
||||
//
|
||||
// **Note**: You might need to add `<meta charset="UTF-8">` to the head of the html file to be able to see the result correctly.
|
||||
//
|
||||
// Headings and block quotes:
|
||||
[Test]
|
||||
public void ExtensionsGlobalization_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Globalization
|
||||
//
|
||||
// The following Markdown:
|
||||
// # Fruits
|
||||
// In botany, a [fruit](https://en.wikipedia.org/wiki/Fruit) is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.
|
||||
//
|
||||
// > Fruits are good for health
|
||||
// -- Anonymous
|
||||
//
|
||||
// # میوە
|
||||
// [میوە](https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95) یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو
|
||||
//
|
||||
// > میوە بۆ تەندروستی باشە
|
||||
// -- نەزانراو
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h1 id="fruits">Fruits</h1>
|
||||
// <p>In botany, a <a href="https://en.wikipedia.org/wiki/Fruit">fruit</a> is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.</p>
|
||||
// <blockquote>
|
||||
// <p>Fruits are good for health
|
||||
// -- Anonymous</p>
|
||||
// </blockquote>
|
||||
// <h1 id="section" dir="rtl">میوە</h1>
|
||||
// <p dir="rtl"><a href="https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95" dir="rtl">میوە</a> یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو</p>
|
||||
// <blockquote dir="rtl">
|
||||
// <p dir="rtl">میوە بۆ تەندروستی باشە
|
||||
// -- نەزانراو</p>
|
||||
// </blockquote>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Globalization\n");
|
||||
TestParser.TestSpec("# Fruits\nIn botany, a [fruit](https://en.wikipedia.org/wiki/Fruit) is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.\n\n> Fruits are good for health\n-- Anonymous\n\n# میوە\n[میوە](https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95) یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو\n\n> میوە بۆ تەندروستی باشە\n-- نەزانراو", "<h1 id=\"fruits\">Fruits</h1>\n<p>In botany, a <a href=\"https://en.wikipedia.org/wiki/Fruit\">fruit</a> is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.</p>\n<blockquote>\n<p>Fruits are good for health\n-- Anonymous</p>\n</blockquote>\n<h1 id=\"section\" dir=\"rtl\">میوە</h1>\n<p dir=\"rtl\"><a href=\"https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95\" dir=\"rtl\">میوە</a> یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو</p>\n<blockquote dir=\"rtl\">\n<p dir=\"rtl\">میوە بۆ تەندروستی باشە\n-- نەزانراو</p>\n</blockquote>", "globalization+advanced+emojis");
|
||||
}
|
||||
|
||||
// Lists:
|
||||
[Test]
|
||||
public void ExtensionsGlobalization_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Globalization
|
||||
//
|
||||
// The following Markdown:
|
||||
// ## Types of fruits
|
||||
// - Berries
|
||||
// - Strawberry
|
||||
// - kiwifruit
|
||||
// - Citrus
|
||||
// - Orange
|
||||
// - Lemon
|
||||
//
|
||||
// ## Examples of fruits :yum:
|
||||
// 1. Apple
|
||||
// 2. Banana
|
||||
// 3. Orange
|
||||
//
|
||||
// ## Grocery List
|
||||
// - [X] Watermelon
|
||||
// - [X] Apricot
|
||||
// - [ ] Fig
|
||||
//
|
||||
// ## نموونەی میوە :yum:
|
||||
// 1. ? سێو
|
||||
// 2. 5 مۆز
|
||||
// 3. پرتەقاڵ
|
||||
//
|
||||
// ## جۆرەکانی میوە
|
||||
// - توو
|
||||
// - فڕاولە
|
||||
// - کیوی
|
||||
// - مزرەمەنی
|
||||
// - پڕتەقاڵ
|
||||
// - لیمۆ
|
||||
//
|
||||
// ## لیستی کڕین
|
||||
// - [X] شووتی
|
||||
// - [X] قەیسی
|
||||
// - [ ] هەنجیر
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <h2 id="types-of-fruits">Types of fruits</h2>
|
||||
// <ul>
|
||||
// <li>Berries
|
||||
// <ul>
|
||||
// <li>Strawberry</li>
|
||||
// <li>kiwifruit</li>
|
||||
// </ul>
|
||||
// </li>
|
||||
// <li>Citrus
|
||||
// <ul>
|
||||
// <li>Orange</li>
|
||||
// <li>Lemon</li>
|
||||
// </ul>
|
||||
// </li>
|
||||
// </ul>
|
||||
// <h2 id="examples-of-fruits">Examples of fruits 😋</h2>
|
||||
// <ol>
|
||||
// <li>Apple</li>
|
||||
// <li>Banana</li>
|
||||
// <li>Orange</li>
|
||||
// </ol>
|
||||
// <h2 id="grocery-list">Grocery List</h2>
|
||||
// <ul class="contains-task-list">
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Watermelon</li>
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Apricot</li>
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" /> Fig</li>
|
||||
// </ul>
|
||||
// <h2 id="section" dir="rtl">نموونەی میوە 😋</h2>
|
||||
// <ol dir="rtl">
|
||||
// <li>? سێو</li>
|
||||
// <li>5 مۆز</li>
|
||||
// <li> پرتەقاڵ</li>
|
||||
// </ol>
|
||||
// <h2 id="section-1" dir="rtl">جۆرەکانی میوە</h2>
|
||||
// <ul dir="rtl">
|
||||
// <li>توو
|
||||
// <ul dir="rtl">
|
||||
// <li>فڕاولە</li>
|
||||
// <li>کیوی</li>
|
||||
// </ul>
|
||||
// </li>
|
||||
// <li>مزرەمەنی
|
||||
// <ul dir="rtl">
|
||||
// <li>پڕتەقاڵ</li>
|
||||
// <li>لیمۆ</li>
|
||||
// </ul>
|
||||
// </li>
|
||||
// </ul>
|
||||
// <h2 id="section-2" dir="rtl">لیستی کڕین</h2>
|
||||
// <ul class="contains-task-list" dir="rtl">
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> شووتی</li>
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> قەیسی</li>
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" /> هەنجیر</li>
|
||||
// </ul>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Globalization\n");
|
||||
TestParser.TestSpec("## Types of fruits\n- Berries\n - Strawberry\n - kiwifruit\n- Citrus\n - Orange\n - Lemon\n\n## Examples of fruits :yum:\n1. Apple\n2. Banana\n3. Orange\n\n## Grocery List\n- [X] Watermelon\n- [X] Apricot\n- [ ] Fig \n\n## نموونەی میوە :yum:\n1. ? سێو\n2. 5 مۆز \n3. پرتەقاڵ\n\n## جۆرەکانی میوە\n- توو\n - فڕاولە\n - کیوی\n- مزرەمەنی\n - پڕتەقاڵ\n - لیمۆ\n\n## لیستی کڕین\n- [X] شووتی\n- [X] قەیسی\n- [ ] هەنجیر", "<h2 id=\"types-of-fruits\">Types of fruits</h2>\n<ul>\n<li>Berries\n<ul>\n<li>Strawberry</li>\n<li>kiwifruit</li>\n</ul>\n</li>\n<li>Citrus\n<ul>\n<li>Orange</li>\n<li>Lemon</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"examples-of-fruits\">Examples of fruits 😋</h2>\n<ol>\n<li>Apple</li>\n<li>Banana</li>\n<li>Orange</li>\n</ol>\n<h2 id=\"grocery-list\">Grocery List</h2>\n<ul class=\"contains-task-list\">\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" checked=\"checked\" /> Watermelon</li>\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" checked=\"checked\" /> Apricot</li>\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" /> Fig</li>\n</ul>\n<h2 id=\"section\" dir=\"rtl\">نموونەی میوە 😋</h2>\n<ol dir=\"rtl\">\n<li>? سێو</li>\n<li>5 مۆز</li>\n<li> پرتەقاڵ</li>\n</ol>\n<h2 id=\"section-1\" dir=\"rtl\">جۆرەکانی میوە</h2>\n<ul dir=\"rtl\">\n<li>توو\n<ul dir=\"rtl\">\n<li>فڕاولە</li>\n<li>کیوی</li>\n</ul>\n</li>\n<li>مزرەمەنی\n<ul dir=\"rtl\">\n<li>پڕتەقاڵ</li>\n<li>لیمۆ</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"section-2\" dir=\"rtl\">لیستی کڕین</h2>\n<ul class=\"contains-task-list\" dir=\"rtl\">\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" checked=\"checked\" /> شووتی</li>\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" checked=\"checked\" /> قەیسی</li>\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" /> هەنجیر</li>\n</ul>", "globalization+advanced+emojis");
|
||||
}
|
||||
|
||||
// Tables:
|
||||
[Test]
|
||||
public void ExtensionsGlobalization_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Globalization
|
||||
//
|
||||
// The following Markdown:
|
||||
// Nutrition |Apple | Oranges
|
||||
// --|-- | --
|
||||
// Calories|52|47
|
||||
// Sugar|10g|9g
|
||||
//
|
||||
// پێکهاتە |سێو | پڕتەقاڵ
|
||||
// --|-- | --
|
||||
// کالۆری|٥٢|٤٧
|
||||
// شەکر| ١٠گ|٩گ
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>Nutrition</th>
|
||||
// <th>Apple</th>
|
||||
// <th>Oranges</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>Calories</td>
|
||||
// <td>52</td>
|
||||
// <td>47</td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td>Sugar</td>
|
||||
// <td>10g</td>
|
||||
// <td>9g</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
// <table dir="rtl" align="right">
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>پێکهاتە</th>
|
||||
// <th>سێو</th>
|
||||
// <th>پڕتەقاڵ</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>کالۆری</td>
|
||||
// <td>٥٢</td>
|
||||
// <td>٤٧</td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td>شەکر</td>
|
||||
// <td>١٠گ</td>
|
||||
// <td>٩گ</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Globalization\n");
|
||||
TestParser.TestSpec("Nutrition |Apple | Oranges\n--|-- | --\nCalories|52|47\nSugar|10g|9g\n\n پێکهاتە |سێو | پڕتەقاڵ\n--|-- | --\nکالۆری|٥٢|٤٧\nشەکر| ١٠گ|٩گ", "<table>\n<thead>\n<tr>\n<th>Nutrition</th>\n<th>Apple</th>\n<th>Oranges</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Calories</td>\n<td>52</td>\n<td>47</td>\n</tr>\n<tr>\n<td>Sugar</td>\n<td>10g</td>\n<td>9g</td>\n</tr>\n</tbody>\n</table>\n<table dir=\"rtl\" align=\"right\">\n<thead>\n<tr>\n<th>پێکهاتە</th>\n<th>سێو</th>\n<th>پڕتەقاڵ</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>کالۆری</td>\n<td>٥٢</td>\n<td>٤٧</td>\n</tr>\n<tr>\n<td>شەکر</td>\n<td>١٠گ</td>\n<td>٩گ</td>\n</tr>\n</tbody>\n</table>", "globalization+advanced+emojis");
|
||||
}
|
||||
}
|
||||
}
|
||||
189
src/Markdig.Tests/Specs/GlobalizationSpecs.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Extensions
|
||||
|
||||
This section describes the different extensions supported:
|
||||
|
||||
## Globalization
|
||||
Adds support for RTL content by adding `dir="rtl"` and `align="right` attributes to the appropriate html elements. Left to right text is not affected by this extension.
|
||||
|
||||
Whether a markdown block is marked as RTL or not is determined by the [first strong character](https://en.wikipedia.org/wiki/Bi-directional_text#Strong_characters) of the block.
|
||||
|
||||
**Note**: You might need to add `<meta charset="UTF-8">` to the head of the html file to be able to see the result correctly.
|
||||
|
||||
Headings and block quotes:
|
||||
```````````````````````````````` example
|
||||
# Fruits
|
||||
In botany, a [fruit](https://en.wikipedia.org/wiki/Fruit) is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.
|
||||
|
||||
> Fruits are good for health
|
||||
-- Anonymous
|
||||
|
||||
# میوە
|
||||
[میوە](https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95) یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو
|
||||
|
||||
> میوە بۆ تەندروستی باشە
|
||||
-- نەزانراو
|
||||
.
|
||||
<h1 id="fruits">Fruits</h1>
|
||||
<p>In botany, a <a href="https://en.wikipedia.org/wiki/Fruit">fruit</a> is the seed-bearing structure in flowering plants (also known as angiosperms) formed from the ovary after flowering.</p>
|
||||
<blockquote>
|
||||
<p>Fruits are good for health
|
||||
-- Anonymous</p>
|
||||
</blockquote>
|
||||
<h1 id="section" dir="rtl">میوە</h1>
|
||||
<p dir="rtl"><a href="https://ckb.wikipedia.org/wiki/%D9%85%DB%8C%D9%88%DB%95" dir="rtl">میوە</a> یان مێوە بەروبوومی ڕوەکیە کە ڕوەکەکان ھەڵیان ئەگرن وەک بەرگێک بۆ تۆوەکانیان، بە زۆری جیادەکرێتەوە بە شیرینی یان ترشی لە تامدا و بە بوونی بڕێکی زۆر ئاو</p>
|
||||
<blockquote dir="rtl">
|
||||
<p dir="rtl">میوە بۆ تەندروستی باشە
|
||||
-- نەزانراو</p>
|
||||
</blockquote>
|
||||
````````````````````````````````
|
||||
|
||||
Lists:
|
||||
```````````````````````````````` example
|
||||
## Types of fruits
|
||||
- Berries
|
||||
- Strawberry
|
||||
- kiwifruit
|
||||
- Citrus
|
||||
- Orange
|
||||
- Lemon
|
||||
|
||||
## Examples of fruits :yum:
|
||||
1. Apple
|
||||
2. Banana
|
||||
3. Orange
|
||||
|
||||
## Grocery List
|
||||
- [X] Watermelon
|
||||
- [X] Apricot
|
||||
- [ ] Fig
|
||||
|
||||
## نموونەی میوە :yum:
|
||||
1. ? سێو
|
||||
2. 5 مۆز
|
||||
3. پرتەقاڵ
|
||||
|
||||
## جۆرەکانی میوە
|
||||
- توو
|
||||
- فڕاولە
|
||||
- کیوی
|
||||
- مزرەمەنی
|
||||
- پڕتەقاڵ
|
||||
- لیمۆ
|
||||
|
||||
## لیستی کڕین
|
||||
- [X] شووتی
|
||||
- [X] قەیسی
|
||||
- [ ] هەنجیر
|
||||
.
|
||||
<h2 id="types-of-fruits">Types of fruits</h2>
|
||||
<ul>
|
||||
<li>Berries
|
||||
<ul>
|
||||
<li>Strawberry</li>
|
||||
<li>kiwifruit</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Citrus
|
||||
<ul>
|
||||
<li>Orange</li>
|
||||
<li>Lemon</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="examples-of-fruits">Examples of fruits 😋</h2>
|
||||
<ol>
|
||||
<li>Apple</li>
|
||||
<li>Banana</li>
|
||||
<li>Orange</li>
|
||||
</ol>
|
||||
<h2 id="grocery-list">Grocery List</h2>
|
||||
<ul class="contains-task-list">
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Watermelon</li>
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Apricot</li>
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" /> Fig</li>
|
||||
</ul>
|
||||
<h2 id="section" dir="rtl">نموونەی میوە 😋</h2>
|
||||
<ol dir="rtl">
|
||||
<li>? سێو</li>
|
||||
<li>5 مۆز</li>
|
||||
<li> پرتەقاڵ</li>
|
||||
</ol>
|
||||
<h2 id="section-1" dir="rtl">جۆرەکانی میوە</h2>
|
||||
<ul dir="rtl">
|
||||
<li>توو
|
||||
<ul dir="rtl">
|
||||
<li>فڕاولە</li>
|
||||
<li>کیوی</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>مزرەمەنی
|
||||
<ul dir="rtl">
|
||||
<li>پڕتەقاڵ</li>
|
||||
<li>لیمۆ</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="section-2" dir="rtl">لیستی کڕین</h2>
|
||||
<ul class="contains-task-list" dir="rtl">
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> شووتی</li>
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> قەیسی</li>
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" /> هەنجیر</li>
|
||||
</ul>
|
||||
````````````````````````````````
|
||||
|
||||
Tables:
|
||||
|
||||
```````````````````````````````` example
|
||||
Nutrition |Apple | Oranges
|
||||
--|-- | --
|
||||
Calories|52|47
|
||||
Sugar|10g|9g
|
||||
|
||||
پێکهاتە |سێو | پڕتەقاڵ
|
||||
--|-- | --
|
||||
کالۆری|٥٢|٤٧
|
||||
شەکر| ١٠گ|٩گ
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nutrition</th>
|
||||
<th>Apple</th>
|
||||
<th>Oranges</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Calories</td>
|
||||
<td>52</td>
|
||||
<td>47</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sugar</td>
|
||||
<td>10g</td>
|
||||
<td>9g</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table dir="rtl" align="right">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>پێکهاتە</th>
|
||||
<th>سێو</th>
|
||||
<th>پڕتەقاڵ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>کالۆری</td>
|
||||
<td>٥٢</td>
|
||||
<td>٤٧</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>شەکر</td>
|
||||
<td>١٠گ</td>
|
||||
<td>٩گ</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
````````````````````````````````
|
||||
398
src/Markdig.Tests/Specs/GridTableSpecs.generated.cs
Normal file
@@ -0,0 +1,398 @@
|
||||
|
||||
// --------------------------------
|
||||
// Grid Tables
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.GridTables
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsGridTable
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Grid Table
|
||||
//
|
||||
// A grid table allows to have multiple lines per cells and allows to span cells over multiple columns. The following shows a simple grid table
|
||||
//
|
||||
// ```
|
||||
// +---------+---------+
|
||||
// | Header | Header |
|
||||
// | Column1 | Column2 |
|
||||
// +=========+=========+
|
||||
// | 1. ab | > This is a quote
|
||||
// | 2. cde | > For the second column
|
||||
// | 3. f |
|
||||
// +---------+---------+
|
||||
// | Second row spanning
|
||||
// | on two columns
|
||||
// +---------+---------+
|
||||
// | Back | |
|
||||
// | to | |
|
||||
// | one | |
|
||||
// | column | |
|
||||
// ```
|
||||
//
|
||||
// **Rule #1**
|
||||
// The first line of a grid table must a **row separator**. It must start with the column separator character `+` used to separate columns in a row separator. Each column separator is:
|
||||
// - starting by optional spaces
|
||||
// - followed by an optional `:` to specify left align, followed by optional spaces
|
||||
// - followed by a sequence of at least one `-` character, followed by optional spaces
|
||||
// - followed by an optional `:` to specify right align (or center align if left align is also defined)
|
||||
// - ending by optional spaces
|
||||
//
|
||||
// The first row separator must be followed by a *regular row*. A regular row must start with the character `|` that is starting at the same position than the column separator `+` of the first row separator.
|
||||
//
|
||||
//
|
||||
// The following is a valid row separator
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +---------+---------+
|
||||
// | This is | a table |
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <col style="width:50%" />
|
||||
// <col style="width:50%" />
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>This is</td>
|
||||
// <td>a table</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+---------+---------+\n| This is | a table |", "<table>\n<col style=\"width:50%\" />\n<col style=\"width:50%\" />\n<tbody>\n<tr>\n<td>This is</td>\n<td>a table</td>\n</tr>\n</tbody>\n</table>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// The following is not a valid row separator
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// |-----xxx----+---------+
|
||||
// | This is | not a table
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>|-----xxx----+---------+
|
||||
// | This is | not a table</p>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("|-----xxx----+---------+\n| This is | not a table", "<p>|-----xxx----+---------+\n| This is | not a table</p>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// **Rule #2**
|
||||
// A regular row can continue a previous regular row when column separator `|` are positioned at the same position than the previous line. If they are positioned at the same location, the column may span over multiple columns:
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +---------+---------+---------+
|
||||
// | Col1 | Col2 | Col3 |
|
||||
// | Col1a | Col2a | Col3a |
|
||||
// | Col1b | Col3b |
|
||||
// | Col1c |
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <col style="width:33.33%" />
|
||||
// <col style="width:33.33%" />
|
||||
// <col style="width:33.33%" />
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>Col1
|
||||
// Col1a</td>
|
||||
// <td>Col2
|
||||
// Col2a</td>
|
||||
// <td>Col3
|
||||
// Col3a</td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td colspan="2">Col1b</td>
|
||||
// <td>Col3b</td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td colspan="3">Col1c</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+---------+---------+---------+\n| Col1 | Col2 | Col3 |\n| Col1a | Col2a | Col3a |\n| Col1b | Col3b |\n| Col1c |", "<table>\n<col style=\"width:33.33%\" />\n<col style=\"width:33.33%\" />\n<col style=\"width:33.33%\" />\n<tbody>\n<tr>\n<td>Col1\nCol1a</td>\n<td>Col2\nCol2a</td>\n<td>Col3\nCol3a</td>\n</tr>\n<tr>\n<td colspan=\"2\">Col1b</td>\n<td>Col3b</td>\n</tr>\n<tr>\n<td colspan=\"3\">Col1c</td>\n</tr>\n</tbody>\n</table>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// A row header is separated using `+========+` instead of `+---------+`:
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +---------+---------+
|
||||
// | This is | a table |
|
||||
// +=========+=========+
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <col style="width:50%" />
|
||||
// <col style="width:50%" />
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>This is</th>
|
||||
// <th>a table</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+---------+---------+\n| This is | a table |\n+=========+=========+", "<table>\n<col style=\"width:50%\" />\n<col style=\"width:50%\" />\n<thead>\n<tr>\n<th>This is</th>\n<th>a table</th>\n</tr>\n</thead>\n</table>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// The last column separator `|` may be omitted:
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +---------+---------+
|
||||
// | This is | a table with a longer text in the second column
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <col style="width:50%" />
|
||||
// <col style="width:50%" />
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>This is</td>
|
||||
// <td>a table with a longer text in the second column</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+---------+---------+\n| This is | a table with a longer text in the second column", "<table>\n<col style=\"width:50%\" />\n<col style=\"width:50%\" />\n<tbody>\n<tr>\n<td>This is</td>\n<td>a table with a longer text in the second column</td>\n</tr>\n</tbody>\n</table>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// The respective width of the columns are calculated from the ratio between the total size of the first table row without counting the `+`: `+----+--------+----+` would be divided between:
|
||||
//
|
||||
// Total size is : 16
|
||||
//
|
||||
// - `----` -> 4
|
||||
// - `--------` -> 8
|
||||
// - `----` -> 4
|
||||
//
|
||||
// So the width would be 4/16 = 25%, 8/16 = 50%, 4/16 = 25%
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +----+--------+----+
|
||||
// | A | B C D | E |
|
||||
// +----+--------+----+
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <col style="width:25%" />
|
||||
// <col style="width:50%" />
|
||||
// <col style="width:25%" />
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>A</td>
|
||||
// <td>B C D</td>
|
||||
// <td>E</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+----+--------+----+\n| A | B C D | E |\n+----+--------+----+", "<table>\n<col style=\"width:25%\" />\n<col style=\"width:50%\" />\n<col style=\"width:25%\" />\n<tbody>\n<tr>\n<td>A</td>\n<td>B C D</td>\n<td>E</td>\n</tr>\n</tbody>\n</table>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// Alignment might be specified on the first row using the character `:`:
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +-----+:---:+-----+
|
||||
// | A | B | C |
|
||||
// +-----+-----+-----+
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <col style="width:33.33%" />
|
||||
// <col style="width:33.33%" />
|
||||
// <col style="width:33.33%" />
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>A</td>
|
||||
// <td style="text-align: center;">B</td>
|
||||
// <td>C</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 7\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+-----+:---:+-----+\n| A | B | C |\n+-----+-----+-----+", "<table>\n<col style=\"width:33.33%\" />\n<col style=\"width:33.33%\" />\n<col style=\"width:33.33%\" />\n<tbody>\n<tr>\n<td>A</td>\n<td style=\"text-align: center;\">B</td>\n<td>C</td>\n</tr>\n</tbody>\n</table>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// A grid table may have cells spanning both columns and rows:
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +---+---+---+
|
||||
// | AAAAA | B |
|
||||
// +---+---+ B +
|
||||
// | D | E | B |
|
||||
// + D +---+---+
|
||||
// | D | CCCCC |
|
||||
// +---+---+---+
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <col style="width:33.33%" />
|
||||
// <col style="width:33.33%" />
|
||||
// <col style="width:33.33%" />
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td colspan="2">AAAAA</td>
|
||||
// <td rowspan="2">B
|
||||
// B
|
||||
// B</td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td rowspan="2">D
|
||||
// D
|
||||
// D</td>
|
||||
// <td>E</td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td colspan="2">CCCCC</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 8\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+---+---+---+\n| AAAAA | B |\n+---+---+ B +\n| D | E | B |\n+ D +---+---+\n| D | CCCCC |\n+---+---+---+", "<table>\n<col style=\"width:33.33%\" />\n<col style=\"width:33.33%\" />\n<col style=\"width:33.33%\" />\n<tbody>\n<tr>\n<td colspan=\"2\">AAAAA</td>\n<td rowspan=\"2\">B\nB\nB</td>\n</tr>\n<tr>\n<td rowspan=\"2\">D\nD\nD</td>\n<td>E</td>\n</tr>\n<tr>\n<td colspan=\"2\">CCCCC</td>\n</tr>\n</tbody>\n</table>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// A grid table may have cells with both colspan and rowspan:
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example009()
|
||||
{
|
||||
// Example 9
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +---+---+---+
|
||||
// | AAAAA | B |
|
||||
// + AAAAA +---+
|
||||
// | AAAAA | C |
|
||||
// +---+---+---+
|
||||
// | D | E | F |
|
||||
// +---+---+---+
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <col style="width:33.33%" />
|
||||
// <col style="width:33.33%" />
|
||||
// <col style="width:33.33%" />
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td colspan="2" rowspan="2">AAAAA
|
||||
// AAAAA
|
||||
// AAAAA</td>
|
||||
// <td>B</td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td>C</td>
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <td>D</td>
|
||||
// <td>E</td>
|
||||
// <td>F</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example 9\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+---+---+---+\n| AAAAA | B |\n+ AAAAA +---+\n| AAAAA | C |\n+---+---+---+\n| D | E | F |\n+---+---+---+", "<table>\n<col style=\"width:33.33%\" />\n<col style=\"width:33.33%\" />\n<col style=\"width:33.33%\" />\n<tbody>\n<tr>\n<td colspan=\"2\" rowspan=\"2\">AAAAA\nAAAAA\nAAAAA</td>\n<td>B</td>\n</tr>\n<tr>\n<td>C</td>\n</tr>\n<tr>\n<td>D</td>\n<td>E</td>\n<td>F</td>\n</tr>\n</tbody>\n</table>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// A grid table may not have irregularly shaped cells:
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example010()
|
||||
{
|
||||
// Example 10
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +---+---+---+
|
||||
// | AAAAA | B |
|
||||
// + A +---+ B +
|
||||
// | A | C | B |
|
||||
// +---+---+---+
|
||||
// | DDDDD | E |
|
||||
// +---+---+---+
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>+---+---+---+
|
||||
// | AAAAA | B |
|
||||
// + A +---+ B +
|
||||
// | A | C | B |
|
||||
// +---+---+---+
|
||||
// | DDDDD | E |
|
||||
// +---+---+---+</p>
|
||||
|
||||
Console.WriteLine("Example 10\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+---+---+---+\n| AAAAA | B |\n+ A +---+ B +\n| A | C | B |\n+---+---+---+\n| DDDDD | E |\n+---+---+---+", "<p>+---+---+---+\n| AAAAA | B |\n+ A +---+ B +\n| A | C | B |\n+---+---+---+\n| DDDDD | E |\n+---+---+---+</p>", "gridtables|advanced");
|
||||
}
|
||||
|
||||
// An empty `+` on a line should result in a simple empty list output:
|
||||
[Test]
|
||||
public void ExtensionsGridTable_Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions / Grid Table
|
||||
//
|
||||
// The following Markdown:
|
||||
// +
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ul>
|
||||
// <li></li>
|
||||
// </ul>
|
||||
|
||||
Console.WriteLine("Example 11\nSection Extensions / Grid Table\n");
|
||||
TestParser.TestSpec("+", "<ul>\n<li></li>\n</ul>", "gridtables|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,8 +42,8 @@ The following is a valid row separator
|
||||
| This is | a table |
|
||||
.
|
||||
<table>
|
||||
<col style="width:50%">
|
||||
<col style="width:50%">
|
||||
<col style="width:50%" />
|
||||
<col style="width:50%" />
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>This is</td>
|
||||
@@ -70,13 +70,13 @@ A regular row can continue a previous regular row when column separator `|` are
|
||||
+---------+---------+---------+
|
||||
| Col1 | Col2 | Col3 |
|
||||
| Col1a | Col2a | Col3a |
|
||||
| Col12 | Col3b |
|
||||
| Col123 |
|
||||
| Col1b | Col3b |
|
||||
| Col1c |
|
||||
.
|
||||
<table>
|
||||
<col style="width:33.33%">
|
||||
<col style="width:33.33%">
|
||||
<col style="width:33.33%">
|
||||
<col style="width:33.33%" />
|
||||
<col style="width:33.33%" />
|
||||
<col style="width:33.33%" />
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Col1
|
||||
@@ -87,11 +87,11 @@ Col2a</td>
|
||||
Col3a</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">Col12</td>
|
||||
<td></td>
|
||||
<td colspan="2">Col1b</td>
|
||||
<td>Col3b</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">Col123</td>
|
||||
<td colspan="3">Col1c</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -105,8 +105,8 @@ A row header is separated using `+========+` instead of `+---------+`:
|
||||
+=========+=========+
|
||||
.
|
||||
<table>
|
||||
<col style="width:50%">
|
||||
<col style="width:50%">
|
||||
<col style="width:50%" />
|
||||
<col style="width:50%" />
|
||||
<thead>
|
||||
<tr>
|
||||
<th>This is</th>
|
||||
@@ -123,8 +123,8 @@ The last column separator `|` may be omitted:
|
||||
| This is | a table with a longer text in the second column
|
||||
.
|
||||
<table>
|
||||
<col style="width:50%">
|
||||
<col style="width:50%">
|
||||
<col style="width:50%" />
|
||||
<col style="width:50%" />
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>This is</td>
|
||||
@@ -150,9 +150,9 @@ So the width would be 4/16 = 25%, 8/16 = 50%, 4/16 = 25%
|
||||
+----+--------+----+
|
||||
.
|
||||
<table>
|
||||
<col style="width:25%">
|
||||
<col style="width:50%">
|
||||
<col style="width:25%">
|
||||
<col style="width:25%" />
|
||||
<col style="width:50%" />
|
||||
<col style="width:25%" />
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>A</td>
|
||||
@@ -172,9 +172,9 @@ Alignment might be specified on the first row using the character `:`:
|
||||
+-----+-----+-----+
|
||||
.
|
||||
<table>
|
||||
<col style="width:33.33%">
|
||||
<col style="width:33.33%">
|
||||
<col style="width:33.33%">
|
||||
<col style="width:33.33%" />
|
||||
<col style="width:33.33%" />
|
||||
<col style="width:33.33%" />
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>A</td>
|
||||
@@ -184,3 +184,103 @@ Alignment might be specified on the first row using the character `:`:
|
||||
</tbody>
|
||||
</table>
|
||||
````````````````````````````````
|
||||
|
||||
A grid table may have cells spanning both columns and rows:
|
||||
|
||||
```````````````````````````````` example
|
||||
+---+---+---+
|
||||
| AAAAA | B |
|
||||
+---+---+ B +
|
||||
| D | E | B |
|
||||
+ D +---+---+
|
||||
| D | CCCCC |
|
||||
+---+---+---+
|
||||
.
|
||||
<table>
|
||||
<col style="width:33.33%" />
|
||||
<col style="width:33.33%" />
|
||||
<col style="width:33.33%" />
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2">AAAAA</td>
|
||||
<td rowspan="2">B
|
||||
B
|
||||
B</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">D
|
||||
D
|
||||
D</td>
|
||||
<td>E</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">CCCCC</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
````````````````````````````````
|
||||
|
||||
A grid table may have cells with both colspan and rowspan:
|
||||
|
||||
```````````````````````````````` example
|
||||
+---+---+---+
|
||||
| AAAAA | B |
|
||||
+ AAAAA +---+
|
||||
| AAAAA | C |
|
||||
+---+---+---+
|
||||
| D | E | F |
|
||||
+---+---+---+
|
||||
.
|
||||
<table>
|
||||
<col style="width:33.33%" />
|
||||
<col style="width:33.33%" />
|
||||
<col style="width:33.33%" />
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2" rowspan="2">AAAAA
|
||||
AAAAA
|
||||
AAAAA</td>
|
||||
<td>B</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>D</td>
|
||||
<td>E</td>
|
||||
<td>F</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
````````````````````````````````
|
||||
|
||||
A grid table may not have irregularly shaped cells:
|
||||
|
||||
```````````````````````````````` example
|
||||
+---+---+---+
|
||||
| AAAAA | B |
|
||||
+ A +---+ B +
|
||||
| A | C | B |
|
||||
+---+---+---+
|
||||
| DDDDD | E |
|
||||
+---+---+---+
|
||||
.
|
||||
<p>+---+---+---+
|
||||
| AAAAA | B |
|
||||
+ A +---+ B +
|
||||
| A | C | B |
|
||||
+---+---+---+
|
||||
| DDDDD | E |
|
||||
+---+---+---+</p>
|
||||
````````````````````````````````
|
||||
|
||||
An empty `+` on a line should result in a simple empty list output:
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
+
|
||||
.
|
||||
<ul>
|
||||
<li></li>
|
||||
</ul>
|
||||
````````````````````````````````
|
||||
|
||||
39
src/Markdig.Tests/Specs/HardlineBreakSpecs.generated.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
// --------------------------------
|
||||
// Hardline Breaks
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.HardlineBreaks
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsHardlineBreak
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// This section describes the different extensions supported:
|
||||
//
|
||||
// ## Hardline break
|
||||
//
|
||||
// When this extension is used, a new line in a paragraph block will result in a hardline break `<br>`:
|
||||
[Test]
|
||||
public void ExtensionsHardlineBreak_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Hardline break
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a paragraph
|
||||
// with a break inside
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a paragraph<br />
|
||||
// with a break inside</p>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Hardline break\n");
|
||||
TestParser.TestSpec("This is a paragraph\nwith a break inside", "<p>This is a paragraph<br />\nwith a break inside</p>", "hardlinebreak|advanced+hardlinebreak");
|
||||
}
|
||||
}
|
||||
}
|
||||
259
src/Markdig.Tests/Specs/JiraLinks.generated.cs
Normal file
@@ -0,0 +1,259 @@
|
||||
|
||||
// --------------------------------
|
||||
// Jira Links
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.JiraLinks
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestJiraLinks
|
||||
{
|
||||
// ## Jira Links
|
||||
//
|
||||
// The JiraLinks extension will automatically add links to JIRA issue items within your markdown, e.g. XX-1234. For this to happen, you must configure the extension when adding to the pipeline, e.g.
|
||||
//
|
||||
// ```
|
||||
// var pipeline = new MarkdownPipelineBuilder()
|
||||
// .UseJiraLinks(new JiraLinkOptions("http://your.company.abc"))
|
||||
// .Build();
|
||||
// ```
|
||||
//
|
||||
// The rules for detecting a link are:
|
||||
//
|
||||
// - The project key must be composed of one or more capitalized ASCII letters or digits `[A-Z,0-9]+`
|
||||
// - A single hyphen `-` must separate the project key and issue number.
|
||||
// - The issue number is composed of 1 or more digits `[0, 9]+`
|
||||
// - The reference must be preceded by either `(` or whitespace or EOF.
|
||||
// - The reference must be followed by either `)` or whitespace or EOF.
|
||||
//
|
||||
// The following are valid examples:
|
||||
[Test]
|
||||
public void JiraLinks_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a ABCD-123 issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <a href="http://your.company.abc/browse/ABCD-123" target="_blank">ABCD-123</a> issue</p>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a ABCD-123 issue", "<p>This is a <a href=\"http://your.company.abc/browse/ABCD-123\" target=\"_blank\">ABCD-123</a> issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a ABC4-123 issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <a href="http://your.company.abc/browse/ABC4-123" target="_blank">ABC4-123</a> issue</p>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a ABC4-123 issue", "<p>This is a <a href=\"http://your.company.abc/browse/ABC4-123\" target=\"_blank\">ABC4-123</a> issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a ABC45-123 issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <a href="http://your.company.abc/browse/ABC45-123" target="_blank">ABC45-123</a> issue</p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a ABC45-123 issue", "<p>This is a <a href=\"http://your.company.abc/browse/ABC45-123\" target=\"_blank\">ABC45-123</a> issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a KIRA-1 issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <a href="http://your.company.abc/browse/KIRA-1" target="_blank">KIRA-1</a> issue</p>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a KIRA-1 issue", "<p>This is a <a href=\"http://your.company.abc/browse/KIRA-1\" target=\"_blank\">KIRA-1</a> issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a Z-1 issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <a href="http://your.company.abc/browse/Z-1" target="_blank">Z-1</a> issue</p>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a Z-1 issue", "<p>This is a <a href=\"http://your.company.abc/browse/Z-1\" target=\"_blank\">Z-1</a> issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
// These are also valid links with `(` and `)`:
|
||||
[Test]
|
||||
public void JiraLinks_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a (ABCD-123) issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a (<a href="http://your.company.abc/browse/ABCD-123" target="_blank">ABCD-123</a>) issue</p>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a (ABCD-123) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/ABCD-123\" target=\"_blank\">ABCD-123</a>) issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a (ABC4-123) issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a (<a href="http://your.company.abc/browse/ABC4-123" target="_blank">ABC4-123</a>) issue</p>
|
||||
|
||||
Console.WriteLine("Example 7\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a (ABC4-123) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/ABC4-123\" target=\"_blank\">ABC4-123</a>) issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a (KIRA-1) issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a (<a href="http://your.company.abc/browse/KIRA-1" target="_blank">KIRA-1</a>) issue</p>
|
||||
|
||||
Console.WriteLine("Example 8\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a (KIRA-1) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/KIRA-1\" target=\"_blank\">KIRA-1</a>) issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example009()
|
||||
{
|
||||
// Example 9
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a (Z-1) issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a (<a href="http://your.company.abc/browse/Z-1" target="_blank">Z-1</a>) issue</p>
|
||||
|
||||
Console.WriteLine("Example 9\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is a (Z-1) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/Z-1\" target=\"_blank\">Z-1</a>) issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
// These are not valid links:
|
||||
[Test]
|
||||
public void JiraLinks_Example010()
|
||||
{
|
||||
// Example 10
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not aJIRA-123 issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not aJIRA-123 issue</p>
|
||||
|
||||
Console.WriteLine("Example 10\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is not aJIRA-123 issue", "<p>This is not aJIRA-123 issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not 4JIRA-123 issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not 4JIRA-123 issue</p>
|
||||
|
||||
Console.WriteLine("Example 11\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is not 4JIRA-123 issue", "<p>This is not 4JIRA-123 issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example012()
|
||||
{
|
||||
// Example 12
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not JIRA-123a issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not JIRA-123a issue</p>
|
||||
|
||||
Console.WriteLine("Example 12\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is not JIRA-123a issue", "<p>This is not JIRA-123a issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example013()
|
||||
{
|
||||
// Example 13
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not JIRA- issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not JIRA- issue</p>
|
||||
|
||||
Console.WriteLine("Example 13\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is not JIRA- issue", "<p>This is not JIRA- issue</p>", "jiralinks");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JiraLinks_Example014()
|
||||
{
|
||||
// Example 14
|
||||
// Section: Jira Links
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not JIR4- issue
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not JIR4- issue</p>
|
||||
|
||||
Console.WriteLine("Example 14\nSection Jira Links\n");
|
||||
TestParser.TestSpec("This is not JIR4- issue", "<p>This is not JIR4- issue</p>", "jiralinks");
|
||||
}
|
||||
}
|
||||
}
|
||||
107
src/Markdig.Tests/Specs/JiraLinks.md
Normal file
@@ -0,0 +1,107 @@
|
||||
## Jira Links
|
||||
|
||||
The JiraLinks extension will automatically add links to JIRA issue items within your markdown, e.g. XX-1234. For this to happen, you must configure the extension when adding to the pipeline, e.g.
|
||||
|
||||
```
|
||||
var pipeline = new MarkdownPipelineBuilder()
|
||||
.UseJiraLinks(new JiraLinkOptions("http://your.company.abc"))
|
||||
.Build();
|
||||
```
|
||||
|
||||
The rules for detecting a link are:
|
||||
|
||||
- The project key must be composed of one or more capitalized ASCII letters or digits `[A-Z,0-9]+`
|
||||
- A single hyphen `-` must separate the project key and issue number.
|
||||
- The issue number is composed of 1 or more digits `[0, 9]+`
|
||||
- The reference must be preceded by either `(` or whitespace or EOF.
|
||||
- The reference must be followed by either `)` or whitespace or EOF.
|
||||
|
||||
The following are valid examples:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a ABCD-123 issue
|
||||
.
|
||||
<p>This is a <a href="http://your.company.abc/browse/ABCD-123" target="_blank">ABCD-123</a> issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a ABC4-123 issue
|
||||
.
|
||||
<p>This is a <a href="http://your.company.abc/browse/ABC4-123" target="_blank">ABC4-123</a> issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a ABC45-123 issue
|
||||
.
|
||||
<p>This is a <a href="http://your.company.abc/browse/ABC45-123" target="_blank">ABC45-123</a> issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a KIRA-1 issue
|
||||
.
|
||||
<p>This is a <a href="http://your.company.abc/browse/KIRA-1" target="_blank">KIRA-1</a> issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a Z-1 issue
|
||||
.
|
||||
<p>This is a <a href="http://your.company.abc/browse/Z-1" target="_blank">Z-1</a> issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
These are also valid links with `(` and `)`:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a (ABCD-123) issue
|
||||
.
|
||||
<p>This is a (<a href="http://your.company.abc/browse/ABCD-123" target="_blank">ABCD-123</a>) issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a (ABC4-123) issue
|
||||
.
|
||||
<p>This is a (<a href="http://your.company.abc/browse/ABC4-123" target="_blank">ABC4-123</a>) issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a (KIRA-1) issue
|
||||
.
|
||||
<p>This is a (<a href="http://your.company.abc/browse/KIRA-1" target="_blank">KIRA-1</a>) issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a (Z-1) issue
|
||||
.
|
||||
<p>This is a (<a href="http://your.company.abc/browse/Z-1" target="_blank">Z-1</a>) issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
These are not valid links:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not aJIRA-123 issue
|
||||
.
|
||||
<p>This is not aJIRA-123 issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not 4JIRA-123 issue
|
||||
.
|
||||
<p>This is not 4JIRA-123 issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not JIRA-123a issue
|
||||
.
|
||||
<p>This is not JIRA-123a issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not JIRA- issue
|
||||
.
|
||||
<p>This is not JIRA- issue</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not JIR4- issue
|
||||
.
|
||||
<p>This is not JIR4- issue</p>
|
||||
````````````````````````````````
|
||||
216
src/Markdig.Tests/Specs/ListExtraSpecs.generated.cs
Normal file
@@ -0,0 +1,216 @@
|
||||
|
||||
// --------------------------------
|
||||
// List Extras
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.ListExtras
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsOrderedListWithAlphaLetter
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// The following additional list items are supported:
|
||||
//
|
||||
// ## Ordered list with alpha letter
|
||||
//
|
||||
// Allows to use a list using an alpha letter instead of a number
|
||||
[Test]
|
||||
public void ExtensionsOrderedListWithAlphaLetter_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Ordered list with alpha letter
|
||||
//
|
||||
// The following Markdown:
|
||||
// a. First item
|
||||
// b. Second item
|
||||
// c. Last item
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol type="a">
|
||||
// <li>First item</li>
|
||||
// <li>Second item</li>
|
||||
// <li>Last item</li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Ordered list with alpha letter\n");
|
||||
TestParser.TestSpec("a. First item\nb. Second item\nc. Last item", "<ol type=\"a\">\n<li>First item</li>\n<li>Second item</li>\n<li>Last item</li>\n</ol>", "listextras|advanced");
|
||||
}
|
||||
|
||||
// It works also for uppercase alpha:
|
||||
[Test]
|
||||
public void ExtensionsOrderedListWithAlphaLetter_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Ordered list with alpha letter
|
||||
//
|
||||
// The following Markdown:
|
||||
// A. First item
|
||||
// B. Second item
|
||||
// C. Last item
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol type="A">
|
||||
// <li>First item</li>
|
||||
// <li>Second item</li>
|
||||
// <li>Last item</li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Ordered list with alpha letter\n");
|
||||
TestParser.TestSpec("A. First item\nB. Second item\nC. Last item", "<ol type=\"A\">\n<li>First item</li>\n<li>Second item</li>\n<li>Last item</li>\n</ol>", "listextras|advanced");
|
||||
}
|
||||
|
||||
// Like for numbered list, a list can start with a different letter
|
||||
[Test]
|
||||
public void ExtensionsOrderedListWithAlphaLetter_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Ordered list with alpha letter
|
||||
//
|
||||
// The following Markdown:
|
||||
// b. First item
|
||||
// c. Second item
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol type="a" start="2">
|
||||
// <li>First item</li>
|
||||
// <li>Second item</li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Ordered list with alpha letter\n");
|
||||
TestParser.TestSpec("b. First item\nc. Second item", "<ol type=\"a\" start=\"2\">\n<li>First item</li>\n<li>Second item</li>\n</ol>", "listextras|advanced");
|
||||
}
|
||||
|
||||
// A different type of list will break the existing list:
|
||||
[Test]
|
||||
public void ExtensionsOrderedListWithAlphaLetter_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Ordered list with alpha letter
|
||||
//
|
||||
// The following Markdown:
|
||||
// a. First item1
|
||||
// b. Second item
|
||||
// A. First item2
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol type="a">
|
||||
// <li>First item1</li>
|
||||
// <li>Second item</li>
|
||||
// </ol>
|
||||
// <ol type="A">
|
||||
// <li>First item2</li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Ordered list with alpha letter\n");
|
||||
TestParser.TestSpec("a. First item1\nb. Second item\nA. First item2", "<ol type=\"a\">\n<li>First item1</li>\n<li>Second item</li>\n</ol>\n<ol type=\"A\">\n<li>First item2</li>\n</ol>", "listextras|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsOrderedListWithRomanLetter
|
||||
{
|
||||
// ## Ordered list with roman letter
|
||||
//
|
||||
// Allows to use a list using a roman number instead of a number.
|
||||
[Test]
|
||||
public void ExtensionsOrderedListWithRomanLetter_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / Ordered list with roman letter
|
||||
//
|
||||
// The following Markdown:
|
||||
// i. First item
|
||||
// ii. Second item
|
||||
// iii. Third item
|
||||
// iv. Last item
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol type="i">
|
||||
// <li>First item</li>
|
||||
// <li>Second item</li>
|
||||
// <li>Third item</li>
|
||||
// <li>Last item</li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / Ordered list with roman letter\n");
|
||||
TestParser.TestSpec("i. First item\nii. Second item\niii. Third item\niv. Last item", "<ol type=\"i\">\n<li>First item</li>\n<li>Second item</li>\n<li>Third item</li>\n<li>Last item</li>\n</ol>", "listextras|advanced");
|
||||
}
|
||||
|
||||
// It works also for uppercase alpha:
|
||||
[Test]
|
||||
public void ExtensionsOrderedListWithRomanLetter_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / Ordered list with roman letter
|
||||
//
|
||||
// The following Markdown:
|
||||
// I. First item
|
||||
// II. Second item
|
||||
// III. Third item
|
||||
// IV. Last item
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol type="I">
|
||||
// <li>First item</li>
|
||||
// <li>Second item</li>
|
||||
// <li>Third item</li>
|
||||
// <li>Last item</li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / Ordered list with roman letter\n");
|
||||
TestParser.TestSpec("I. First item\nII. Second item\nIII. Third item\nIV. Last item", "<ol type=\"I\">\n<li>First item</li>\n<li>Second item</li>\n<li>Third item</li>\n<li>Last item</li>\n</ol>", "listextras|advanced");
|
||||
}
|
||||
|
||||
// Like for numbered list, a list can start with a different letter
|
||||
[Test]
|
||||
public void ExtensionsOrderedListWithRomanLetter_Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Extensions / Ordered list with roman letter
|
||||
//
|
||||
// The following Markdown:
|
||||
// ii. First item
|
||||
// iii. Second item
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol type="i" start="2">
|
||||
// <li>First item</li>
|
||||
// <li>Second item</li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 7\nSection Extensions / Ordered list with roman letter\n");
|
||||
TestParser.TestSpec("ii. First item\niii. Second item", "<ol type=\"i\" start=\"2\">\n<li>First item</li>\n<li>Second item</li>\n</ol>", "listextras|advanced");
|
||||
}
|
||||
|
||||
// Lists can be restarted, specifying the start point.
|
||||
[Test]
|
||||
public void ExtensionsOrderedListWithRomanLetter_Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Extensions / Ordered list with roman letter
|
||||
//
|
||||
// The following Markdown:
|
||||
// 1. First item
|
||||
//
|
||||
// Some text
|
||||
//
|
||||
// 2. Second item
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ol>
|
||||
// <li>First item</li>
|
||||
// </ol>
|
||||
// <p>Some text</p>
|
||||
// <ol start="2">
|
||||
// <li>Second item</li>
|
||||
// </ol>
|
||||
|
||||
Console.WriteLine("Example 8\nSection Extensions / Ordered list with roman letter\n");
|
||||
TestParser.TestSpec("1. First item\n\nSome text\n\n2. Second item", "<ol>\n<li>First item</li>\n</ol>\n<p>Some text</p>\n<ol start=\"2\">\n<li>Second item</li>\n</ol>", "listextras|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ Like for numbered list, a list can start with a different letter
|
||||
b. First item
|
||||
c. Second item
|
||||
.
|
||||
<ol type="a" start="b">
|
||||
<ol type="a" start="2">
|
||||
<li>First item</li>
|
||||
<li>Second item</li>
|
||||
</ol>
|
||||
@@ -100,8 +100,26 @@ Like for numbered list, a list can start with a different letter
|
||||
ii. First item
|
||||
iii. Second item
|
||||
.
|
||||
<ol type="i" start="ii">
|
||||
<ol type="i" start="2">
|
||||
<li>First item</li>
|
||||
<li>Second item</li>
|
||||
</ol>
|
||||
````````````````````````````````
|
||||
|
||||
Lists can be restarted, specifying the start point.
|
||||
|
||||
```````````````````````````````` example
|
||||
1. First item
|
||||
|
||||
Some text
|
||||
|
||||
2. Second item
|
||||
.
|
||||
<ol>
|
||||
<li>First item</li>
|
||||
</ol>
|
||||
<p>Some text</p>
|
||||
<ol start="2">
|
||||
<li>Second item</li>
|
||||
</ol>
|
||||
````````````````````````````````
|
||||
|
||||
327
src/Markdig.Tests/Specs/MathSpecs.generated.cs
Normal file
@@ -0,0 +1,327 @@
|
||||
|
||||
// --------------------------------
|
||||
// Math
|
||||
// --------------------------------
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests.Specs.Math
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestExtensionsMathInline
|
||||
{
|
||||
// # Extensions
|
||||
//
|
||||
// Adds support for mathematics spans:
|
||||
//
|
||||
// ## Math Inline
|
||||
//
|
||||
// Allows to define a mathematic block embraced by `$...$`
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example001()
|
||||
{
|
||||
// Example 1
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a $math block$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <span class="math">\(math block\)</span></p>
|
||||
|
||||
Console.WriteLine("Example 1\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a $math block$", "<p>This is a <span class=\"math\">\\(math block\\)</span></p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// Or by `$$...$$` embracing it by:
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example002()
|
||||
{
|
||||
// Example 2
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a $$math block$$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <span class="math">\(math block\)</span></p>
|
||||
|
||||
Console.WriteLine("Example 2\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a $$math block$$", "<p>This is a <span class=\"math\">\\(math block\\)</span></p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// Newlines inside an inline math are not allowed:
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example003()
|
||||
{
|
||||
// Example 3
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not a $$math
|
||||
// block$$ and? this is a $$math block$$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not a $$math
|
||||
// block$$ and? this is a <span class="math">\(math block\)</span></p>
|
||||
|
||||
Console.WriteLine("Example 3\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is not a $$math \nblock$$ and? this is a $$math block$$", "<p>This is not a $$math\nblock$$ and? this is a <span class=\"math\">\\(math block\\)</span></p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not a $math
|
||||
// block$ and? this is a $math block$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not a $math
|
||||
// block$ and? this is a <span class="math">\(math block\)</span></p>
|
||||
|
||||
Console.WriteLine("Example 4\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is not a $math \nblock$ and? this is a $math block$", "<p>This is not a $math\nblock$ and? this is a <span class=\"math\">\\(math block\\)</span></p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// An opening `$` can be followed by a space if the closing is also preceded by a space `$`:
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a $ math block $
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <span class="math">\(math block\)</span></p>
|
||||
|
||||
Console.WriteLine("Example 5\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a $ math block $", "<p>This is a <span class=\"math\">\\(math block\\)</span></p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a $ math block $ after
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <span class="math">\(math block\)</span> after</p>
|
||||
|
||||
Console.WriteLine("Example 6\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a $ math block $ after", "<p>This is a <span class=\"math\">\\(math block\\)</span> after</p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a $$ math block $$ after
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <span class="math">\(math block\)</span> after</p>
|
||||
|
||||
Console.WriteLine("Example 7\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a $$ math block $$ after", "<p>This is a <span class=\"math\">\\(math block\\)</span> after</p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a not $ math block$ because there is not a whitespace before the closing
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a not $ math block$ because there is not a whitespace before the closing</p>
|
||||
|
||||
Console.WriteLine("Example 8\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a not $ math block$ because there is not a whitespace before the closing", "<p>This is a not $ math block$ because there is not a whitespace before the closing</p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// For the opening `$` it requires a space or a punctuation before (but cannot be used within a word):
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example009()
|
||||
{
|
||||
// Example 9
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not a m$ath block$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not a m$ath block$</p>
|
||||
|
||||
Console.WriteLine("Example 9\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is not a m$ath block$", "<p>This is not a m$ath block$</p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// For the closing `$` it requires a space after or a punctuation (but cannot be preceded by a space and cannot be used within a word):
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example010()
|
||||
{
|
||||
// Example 10
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is not a $math bloc$k
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is not a $math bloc$k</p>
|
||||
|
||||
Console.WriteLine("Example 10\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is not a $math bloc$k", "<p>This is not a $math bloc$k</p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// For the closing `$` it requires a space after or a punctuation (but cannot be preceded by a space and cannot be used within a word):
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is should not match a 16$ or a $15
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is should not match a 16$ or a $15</p>
|
||||
|
||||
Console.WriteLine("Example 11\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is should not match a 16$ or a $15", "<p>This is should not match a 16$ or a $15</p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// A `$` can be escaped between a math inline block by using the escape `\\`
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example012()
|
||||
{
|
||||
// Example 12
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a $math \$ block$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <span class="math">\(math \$ block\)</span></p>
|
||||
|
||||
Console.WriteLine("Example 12\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a $math \\$ block$", "<p>This is a <span class=\"math\">\\(math \\$ block\\)</span></p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// At most, two `$` will be matched for the opening and closing:
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example013()
|
||||
{
|
||||
// Example 13
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a $$$math block$$$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <span class="math">\($math block$\)</span></p>
|
||||
|
||||
Console.WriteLine("Example 13\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a $$$math block$$$", "<p>This is a <span class=\"math\">\\($math block$\\)</span></p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// Regular text can come both before and after the math inline
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example014()
|
||||
{
|
||||
// Example 14
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is a $math block$ with text on both sides.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is a <span class="math">\(math block\)</span> with text on both sides.</p>
|
||||
|
||||
Console.WriteLine("Example 14\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is a $math block$ with text on both sides.", "<p>This is a <span class=\"math\">\\(math block\\)</span> with text on both sides.</p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// A mathematic block takes precedence over standard emphasis `*` `_`:
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example015()
|
||||
{
|
||||
// Example 15
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// This is *a $math* block$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is *a <span class="math">\(math* block\)</span></p>
|
||||
|
||||
Console.WriteLine("Example 15\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("This is *a $math* block$", "<p>This is *a <span class=\"math\">\\(math* block\\)</span></p>", "mathematics|advanced");
|
||||
}
|
||||
|
||||
// An opening $$ at the beginning of a line should not be interpreted as a Math block:
|
||||
[Test]
|
||||
public void ExtensionsMathInline_Example016()
|
||||
{
|
||||
// Example 16
|
||||
// Section: Extensions / Math Inline
|
||||
//
|
||||
// The following Markdown:
|
||||
// $$ math $$ starting at a line
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><span class="math">\(math\)</span> starting at a line</p>
|
||||
|
||||
Console.WriteLine("Example 16\nSection Extensions / Math Inline\n");
|
||||
TestParser.TestSpec("$$ math $$ starting at a line", "<p><span class=\"math\">\\(math\\)</span> starting at a line</p>", "mathematics|advanced");
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class TestExtensionsMathBlock
|
||||
{
|
||||
// ## Math Block
|
||||
//
|
||||
// The match block can spawn on multiple lines by having a $$ starting on a line.
|
||||
// It is working as a fenced code block.
|
||||
[Test]
|
||||
public void ExtensionsMathBlock_Example017()
|
||||
{
|
||||
// Example 17
|
||||
// Section: Extensions / Math Block
|
||||
//
|
||||
// The following Markdown:
|
||||
// $$
|
||||
// \begin{equation}
|
||||
// \int_0^\infty \frac{x^3}{e^x-1}\,dx = \frac{\pi^4}{15}
|
||||
// \label{eq:sample}
|
||||
// \end{equation}
|
||||
// $$
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <div class="math">
|
||||
// \[
|
||||
// \begin{equation}
|
||||
// \int_0^\infty \frac{x^3}{e^x-1}\,dx = \frac{\pi^4}{15}
|
||||
// \label{eq:sample}
|
||||
// \end{equation}
|
||||
// \]</div>
|
||||
|
||||
Console.WriteLine("Example 17\nSection Extensions / Math Block\n");
|
||||
TestParser.TestSpec("$$\n\\begin{equation}\n \\int_0^\\infty \\frac{x^3}{e^x-1}\\,dx = \\frac{\\pi^4}{15}\n \\label{eq:sample}\n\\end{equation}\n$$", "<div class=\"math\">\n\\[\n\\begin{equation}\n \\int_0^\\infty \\frac{x^3}{e^x-1}\\,dx = \\frac{\\pi^4}{15}\n \\label{eq:sample}\n\\end{equation}\n\\]</div>", "mathematics|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ Allows to define a mathematic block embraced by `$...$`
|
||||
```````````````````````````````` example
|
||||
This is a $math block$
|
||||
.
|
||||
<p>This is a <span class="math">math block</span></p>
|
||||
<p>This is a <span class="math">\(math block\)</span></p>
|
||||
````````````````````````````````
|
||||
|
||||
Or by `$$...$$` embracing it by:
|
||||
@@ -17,15 +17,50 @@ Or by `$$...$$` embracing it by:
|
||||
```````````````````````````````` example
|
||||
This is a $$math block$$
|
||||
.
|
||||
<p>This is a <span class="math">math block</span></p>
|
||||
<p>This is a <span class="math">\(math block\)</span></p>
|
||||
````````````````````````````````
|
||||
|
||||
The opening `$` and closing `$` is following the rules of the emphasis delimiter `_`:
|
||||
Newlines inside an inline math are not allowed:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not a $ math block $
|
||||
This is not a $$math
|
||||
block$$ and? this is a $$math block$$
|
||||
.
|
||||
<p>This is not a $ math block $</p>
|
||||
<p>This is not a $$math
|
||||
block$$ and? this is a <span class="math">\(math block\)</span></p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is not a $math
|
||||
block$ and? this is a $math block$
|
||||
.
|
||||
<p>This is not a $math
|
||||
block$ and? this is a <span class="math">\(math block\)</span></p>
|
||||
````````````````````````````````
|
||||
An opening `$` can be followed by a space if the closing is also preceded by a space `$`:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a $ math block $
|
||||
.
|
||||
<p>This is a <span class="math">\(math block\)</span></p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a $ math block $ after
|
||||
.
|
||||
<p>This is a <span class="math">\(math block\)</span> after</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a $$ math block $$ after
|
||||
.
|
||||
<p>This is a <span class="math">\(math block\)</span> after</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a not $ math block$ because there is not a whitespace before the closing
|
||||
.
|
||||
<p>This is a not $ math block$ because there is not a whitespace before the closing</p>
|
||||
````````````````````````````````
|
||||
|
||||
For the opening `$` it requires a space or a punctuation before (but cannot be used within a word):
|
||||
@@ -57,7 +92,7 @@ A `$` can be escaped between a math inline block by using the escape `\\`
|
||||
```````````````````````````````` example
|
||||
This is a $math \$ block$
|
||||
.
|
||||
<p>This is a <span class="math">math \$ block</span></p>
|
||||
<p>This is a <span class="math">\(math \$ block\)</span></p>
|
||||
````````````````````````````````
|
||||
|
||||
At most, two `$` will be matched for the opening and closing:
|
||||
@@ -65,15 +100,29 @@ At most, two `$` will be matched for the opening and closing:
|
||||
```````````````````````````````` example
|
||||
This is a $$$math block$$$
|
||||
.
|
||||
<p>This is a <span class="math">$math block$</span></p>
|
||||
<p>This is a <span class="math">\($math block$\)</span></p>
|
||||
````````````````````````````````
|
||||
|
||||
Regular text can come both before and after the math inline
|
||||
|
||||
```````````````````````````````` example
|
||||
This is a $math block$ with text on both sides.
|
||||
.
|
||||
<p>This is a <span class="math">\(math block\)</span> with text on both sides.</p>
|
||||
````````````````````````````````
|
||||
A mathematic block takes precedence over standard emphasis `*` `_`:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is *a $math* block$
|
||||
.
|
||||
<p>This is *a <span class="math">math* block</span></p>
|
||||
<p>This is *a <span class="math">\(math* block\)</span></p>
|
||||
````````````````````````````````
|
||||
An opening $$ at the beginning of a line should not be interpreted as a Math block:
|
||||
|
||||
```````````````````````````````` example
|
||||
$$ math $$ starting at a line
|
||||
.
|
||||
<p><span class="math">\(math\)</span> starting at a line</p>
|
||||
````````````````````````````````
|
||||
|
||||
## Math Block
|
||||
@@ -89,9 +138,11 @@ $$
|
||||
\end{equation}
|
||||
$$
|
||||
.
|
||||
<div class="math">\begin{equation}
|
||||
<div class="math">
|
||||
\[
|
||||
\begin{equation}
|
||||
\int_0^\infty \frac{x^3}{e^x-1}\,dx = \frac{\pi^4}{15}
|
||||
\label{eq:sample}
|
||||
\end{equation}
|
||||
</div>
|
||||
\]</div>
|
||||
````````````````````````````````
|
||||
|
||||