PHP and Javascript implementations of a simple markdown parser
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. class InlineTests extends BaseTest {
  2. /** @type {Markdown} */
  3. parser;
  4. md(markdown) {
  5. return normalizeWhitespace(this.parser.toHTML(markdown));
  6. }
  7. setUp() {
  8. this.parser = Markdown.completeParser;
  9. }
  10. test_simpleText() {
  11. let markdown = 'Lorem ipsum';
  12. let expected = 'Lorem ipsum';
  13. let actual = this.md(markdown);
  14. this.assertEqual(actual, expected);
  15. }
  16. test_strong() {
  17. let markdown = 'Lorem **ipsum** dolor **sit**';
  18. let expected = 'Lorem <strong>ipsum</strong> dolor <strong>sit</strong>';
  19. let actual = this.md(markdown);
  20. this.assertEqual(actual, expected);
  21. }
  22. test_emphasis() {
  23. let markdown = 'Lorem _ipsum_ dolor _sit_';
  24. let expected = 'Lorem <em>ipsum</em> dolor <em>sit</em>';
  25. let actual = this.md(markdown);
  26. this.assertEqual(actual, expected);
  27. }
  28. test_strongEmphasis_cleanNesting1() {
  29. let markdown = 'Lorem **ipsum *dolor* sit** amet';
  30. let expected = 'Lorem <strong>ipsum <em>dolor</em> sit</strong> amet';
  31. let actual = this.md(markdown);
  32. this.assertEqual(actual, expected);
  33. }
  34. test_strongEmphasis_cleanNesting2() {
  35. let markdown = 'Lorem *ipsum **dolor** sit* amet';
  36. let expected = 'Lorem <em>ipsum <strong>dolor</strong> sit</em> amet';
  37. let actual = this.md(markdown);
  38. this.assertEqual(actual, expected);
  39. }
  40. test_strongEmphasis_tightNesting() {
  41. let markdown = 'Lorem ***ipsum*** dolor';
  42. let expected = 'Lorem <strong><em>ipsum</em></strong> dolor';
  43. let actual = this.md(markdown);
  44. this.assertEqual(actual, expected);
  45. }
  46. test_strongEmphasis_lopsidedNesting1() {
  47. let markdown = 'Lorem ***ipsum* dolor** sit';
  48. let expected = 'Lorem <strong><em>ipsum</em> dolor</strong> sit';
  49. let actual = this.md(markdown);
  50. this.assertEqual(actual, expected);
  51. }
  52. test_strongEmphasis_lopsidedNesting2() {
  53. let markdown = 'Lorem ***ipsum** dolor* sit';
  54. let expected = 'Lorem <em><strong>ipsum</strong> dolor</em> sit';
  55. let actual = this.md(markdown);
  56. this.assertEqual(actual, expected);
  57. }
  58. test_strongEmphasis_lopsidedNesting3() {
  59. let markdown = 'Lorem **ipsum *dolor*** sit';
  60. let expected = 'Lorem <strong>ipsum <em>dolor</em></strong> sit';
  61. let actual = this.md(markdown);
  62. this.assertEqual(actual, expected);
  63. }
  64. test_strongEmphasis_lopsidedNesting4() {
  65. let markdown = 'Lorem *ipsum **dolor*** sit';
  66. let expected = 'Lorem <em>ipsum <strong>dolor</strong></em> sit';
  67. let actual = this.md(markdown);
  68. this.assertEqual(actual, expected);
  69. }
  70. test_inlineCode() {
  71. let markdown = 'Lorem `ipsum` dolor';
  72. let expected = 'Lorem <code>ipsum</code> dolor';
  73. let actual = this.md(markdown);
  74. this.assertEqual(actual, expected);
  75. }
  76. test_inlineCode_withInnerBacktick() {
  77. let markdown = 'Lorem ``ip`su`m`` dolor';
  78. let expected = 'Lorem <code>ip`su`m</code> dolor';
  79. let actual = this.md(markdown);
  80. this.assertEqual(actual, expected);
  81. }
  82. test_strikethrough_double() {
  83. let markdown = 'Lorem ~~ipsum~~ dolor';
  84. let expected = 'Lorem <s>ipsum</s> dolor';
  85. let actual = this.md(markdown);
  86. this.assertEqual(actual, expected);
  87. }
  88. test_subscript() {
  89. let markdown = 'H~2~O';
  90. let expected = 'H<sub>2</sub>O';
  91. let actual = this.md(markdown);
  92. this.assertEqual(actual, expected);
  93. }
  94. test_superscript() {
  95. let markdown = 'E=mc^2^';
  96. let expected = 'E=mc<sup>2</sup>';
  97. let actual = this.md(markdown);
  98. this.assertEqual(actual, expected);
  99. }
  100. test_highlight() {
  101. let markdown = 'Lorem ==ipsum== dolor';
  102. let expected = 'Lorem <mark>ipsum</mark> dolor';
  103. let actual = this.md(markdown);
  104. this.assertEqual(actual, expected);
  105. }
  106. test_underline() {
  107. let markdown = 'Lorem __ipsum__ dolor';
  108. let expected = 'Lorem <u>ipsum</u> dolor';
  109. let actual = this.md(markdown);
  110. this.assertEqual(actual, expected);
  111. }
  112. test_link_fullyQualified() {
  113. let markdown = 'Lorem [ipsum](https://example.com/path/page.html) dolor';
  114. let expected = 'Lorem <a href="https://example.com/path/page.html">ipsum</a> dolor';
  115. let actual = this.md(markdown);
  116. this.assertEqual(actual, expected);
  117. }
  118. test_link_relative() {
  119. let markdown = 'Lorem [ipsum](page.html) dolor';
  120. let expected = 'Lorem <a href="page.html">ipsum</a> dolor';
  121. let actual = this.md(markdown);
  122. this.assertEqual(actual, expected);
  123. }
  124. test_link_title() {
  125. let markdown = 'Lorem [ipsum](page.html "link title") dolor';
  126. let expected = 'Lorem <a href="page.html" title="link title">ipsum</a> dolor';
  127. let actual = this.md(markdown);
  128. this.assertEqual(actual, expected);
  129. }
  130. test_link_literal() {
  131. let markdown = 'Lorem <https://example.com> dolor';
  132. let expected = 'Lorem <a href="https://example.com">https://example.com</a> dolor';
  133. let actual = this.md(markdown);
  134. this.assertEqual(actual, expected);
  135. }
  136. test_link_ref() {
  137. let markdown = "Lorem [ipsum][ref] dolor\n\n[ref]: https://example.com";
  138. let expected = '<p>Lorem <a href="https://example.com">ipsum</a> dolor</p>';
  139. let actual = this.md(markdown);
  140. this.assertEqual(actual, expected);
  141. }
  142. test_link_email() {
  143. let markdown = 'Lorem [ipsum](user@example.com) dolor';
  144. let expected = 'Lorem <a href="mailto:&#117;&#115;&#101;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;">ipsum</a> dolor';
  145. let actual = this.md(markdown);
  146. this.assertEqual(actual, expected);
  147. }
  148. test_link_email_withTitle() {
  149. let markdown = 'Lorem [ipsum](user@example.com "title") dolor';
  150. let expected = 'Lorem <a href="mailto:&#117;&#115;&#101;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;" title="title">ipsum</a> dolor';
  151. let actual = this.md(markdown);
  152. this.assertEqual(actual, expected);
  153. }
  154. test_link_literalEmail() {
  155. let markdown = 'Lorem <user@example.com> dolor';
  156. let expected = 'Lorem <a href="mailto:&#117;&#115;&#101;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;">&#117;&#115;&#101;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;</a> dolor';
  157. let actual = this.md(markdown);
  158. this.assertEqual(actual, expected);
  159. }
  160. test_link_image() {
  161. let markdown = 'Lorem [![alt](image.jpg)](page.html) ipsum';
  162. let expected = 'Lorem <a href="page.html"><img src="image.jpg" alt="alt"></a> ipsum';
  163. let actual = this.md(markdown);
  164. this.assertEqual(actual, expected);
  165. }
  166. test_link_image_complex() {
  167. let markdown = 'Lorem [![alt] (image.jpg "image title")] (page.html "link title") ipsum';
  168. let expected = 'Lorem <a href="page.html" title="link title"><img src="image.jpg" alt="alt" title="image title"></a> ipsum';
  169. let actual = this.md(markdown);
  170. this.assertEqual(actual, expected);
  171. }
  172. test_image() {
  173. let markdown = 'Lorem ![alt text](image.jpg) dolor';
  174. let expected = 'Lorem <img src="image.jpg" alt="alt text"> dolor';
  175. let actual = this.md(markdown);
  176. this.assertEqual(actual, expected);
  177. }
  178. test_image_noAlt() {
  179. let markdown = 'Lorem ![](image.jpg) dolor';
  180. let expected = 'Lorem <img src="image.jpg"> dolor';
  181. let actual = this.md(markdown);
  182. this.assertEqual(actual, expected);
  183. }
  184. test_image_withTitle() {
  185. let markdown = 'Lorem ![alt text](image.jpg "image title") dolor';
  186. let expected = 'Lorem <img src="image.jpg" alt="alt text" title="image title"> dolor';
  187. let actual = this.md(markdown);
  188. this.assertEqual(actual, expected);
  189. }
  190. test_image_ref() {
  191. let markdown = 'Lorem ![alt text][ref] dolor\n\n' +
  192. '[ref]: image.jpg "image title"';
  193. let expected = '<p>Lorem <img src="image.jpg" alt="alt text" title="image title"> dolor</p>';
  194. let actual = this.md(markdown);
  195. this.assertEqual(actual, expected);
  196. }
  197. test_htmlTags() {
  198. let markdown = 'Lorem <strong title=\'with " quote\' id="with \' apostrophe" lang=unquoted translate forbidden="true">ipsum</strong> dolor';
  199. let expected = 'Lorem <strong title="with &quot; quote" id="with \' apostrophe" lang="unquoted" translate>ipsum</strong> dolor';
  200. let actual = this.md(markdown);
  201. this.assertEqual(actual, expected);
  202. }
  203. }