test.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: http://codemirror.net/LICENSE
  3. (function() {
  4. var mode = CodeMirror.getMode({tabSize: 4}, "markdown");
  5. function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
  6. var modeHighlightFormatting = CodeMirror.getMode({tabSize: 4}, {name: "markdown", highlightFormatting: true});
  7. function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); }
  8. FT("formatting_emAsterisk",
  9. "[em&formatting&formatting-em *][em foo][em&formatting&formatting-em *]");
  10. FT("formatting_emUnderscore",
  11. "[em&formatting&formatting-em _][em foo][em&formatting&formatting-em _]");
  12. FT("formatting_strongAsterisk",
  13. "[strong&formatting&formatting-strong **][strong foo][strong&formatting&formatting-strong **]");
  14. FT("formatting_strongUnderscore",
  15. "[strong&formatting&formatting-strong __][strong foo][strong&formatting&formatting-strong __]");
  16. FT("formatting_codeBackticks",
  17. "[comment&formatting&formatting-code `][comment foo][comment&formatting&formatting-code `]");
  18. FT("formatting_doubleBackticks",
  19. "[comment&formatting&formatting-code ``][comment foo ` bar][comment&formatting&formatting-code ``]");
  20. FT("formatting_atxHeader",
  21. "[header&header-1&formatting&formatting-header&formatting-header-1 #][header&header-1 foo # bar ][header&header-1&formatting&formatting-header&formatting-header-1 #]");
  22. FT("formatting_setextHeader",
  23. "foo",
  24. "[header&header-1&formatting&formatting-header&formatting-header-1 =]");
  25. FT("formatting_blockquote",
  26. "[quote&quote-1&formatting&formatting-quote&formatting-quote-1 > ][quote&quote-1 foo]");
  27. FT("formatting_list",
  28. "[variable-2&formatting&formatting-list&formatting-list-ul - ][variable-2 foo]");
  29. FT("formatting_list",
  30. "[variable-2&formatting&formatting-list&formatting-list-ol 1. ][variable-2 foo]");
  31. FT("formatting_link",
  32. "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string (][string http://example.com/][string&formatting&formatting-link-string )]");
  33. FT("formatting_linkReference",
  34. "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string [][string bar][string&formatting&formatting-link-string ]]]",
  35. "[link&formatting&formatting-link [][link bar][link&formatting&formatting-link ]]:] [string http://example.com/]");
  36. FT("formatting_linkWeb",
  37. "[link&formatting&formatting-link <][link http://example.com/][link&formatting&formatting-link >]");
  38. FT("formatting_linkEmail",
  39. "[link&formatting&formatting-link <][link user@example.com][link&formatting&formatting-link >]");
  40. FT("formatting_escape",
  41. "[formatting-escape \\*]");
  42. MT("plainText",
  43. "foo");
  44. // Don't style single trailing space
  45. MT("trailingSpace1",
  46. "foo ");
  47. // Two or more trailing spaces should be styled with line break character
  48. MT("trailingSpace2",
  49. "foo[trailing-space-a ][trailing-space-new-line ]");
  50. MT("trailingSpace3",
  51. "foo[trailing-space-a ][trailing-space-b ][trailing-space-new-line ]");
  52. MT("trailingSpace4",
  53. "foo[trailing-space-a ][trailing-space-b ][trailing-space-a ][trailing-space-new-line ]");
  54. // Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
  55. MT("codeBlocksUsing4Spaces",
  56. " [comment foo]");
  57. // Code blocks using 4 spaces with internal indentation
  58. MT("codeBlocksUsing4SpacesIndentation",
  59. " [comment bar]",
  60. " [comment hello]",
  61. " [comment world]",
  62. " [comment foo]",
  63. "bar");
  64. // Code blocks using 4 spaces with internal indentation
  65. MT("codeBlocksUsing4SpacesIndentation",
  66. " foo",
  67. " [comment bar]",
  68. " [comment hello]",
  69. " [comment world]");
  70. // Code blocks should end even after extra indented lines
  71. MT("codeBlocksWithTrailingIndentedLine",
  72. " [comment foo]",
  73. " [comment bar]",
  74. " [comment baz]",
  75. " ",
  76. "hello");
  77. // Code blocks using 1 tab (regardless of CodeMirror.indentWithTabs value)
  78. MT("codeBlocksUsing1Tab",
  79. "\t[comment foo]");
  80. // Inline code using backticks
  81. MT("inlineCodeUsingBackticks",
  82. "foo [comment `bar`]");
  83. // Block code using single backtick (shouldn't work)
  84. MT("blockCodeSingleBacktick",
  85. "[comment `]",
  86. "foo",
  87. "[comment `]");
  88. // Unclosed backticks
  89. // Instead of simply marking as CODE, it would be nice to have an
  90. // incomplete flag for CODE, that is styled slightly different.
  91. MT("unclosedBackticks",
  92. "foo [comment `bar]");
  93. // Per documentation: "To include a literal backtick character within a
  94. // code span, you can use multiple backticks as the opening and closing
  95. // delimiters"
  96. MT("doubleBackticks",
  97. "[comment ``foo ` bar``]");
  98. // Tests based on Dingus
  99. // http://daringfireball.net/projects/markdown/dingus
  100. //
  101. // Multiple backticks within an inline code block
  102. MT("consecutiveBackticks",
  103. "[comment `foo```bar`]");
  104. // Multiple backticks within an inline code block with a second code block
  105. MT("consecutiveBackticks",
  106. "[comment `foo```bar`] hello [comment `world`]");
  107. // Unclosed with several different groups of backticks
  108. MT("unclosedBackticks",
  109. "[comment ``foo ``` bar` hello]");
  110. // Closed with several different groups of backticks
  111. MT("closedBackticks",
  112. "[comment ``foo ``` bar` hello``] world");
  113. // atx headers
  114. // http://daringfireball.net/projects/markdown/syntax#header
  115. MT("atxH1",
  116. "[header&header-1 # foo]");
  117. MT("atxH2",
  118. "[header&header-2 ## foo]");
  119. MT("atxH3",
  120. "[header&header-3 ### foo]");
  121. MT("atxH4",
  122. "[header&header-4 #### foo]");
  123. MT("atxH5",
  124. "[header&header-5 ##### foo]");
  125. MT("atxH6",
  126. "[header&header-6 ###### foo]");
  127. // H6 - 7x '#' should still be H6, per Dingus
  128. // http://daringfireball.net/projects/markdown/dingus
  129. MT("atxH6NotH7",
  130. "[header&header-6 ####### foo]");
  131. // Inline styles should be parsed inside headers
  132. MT("atxH1inline",
  133. "[header&header-1 # foo ][header&header-1&em *bar*]");
  134. // Setext headers - H1, H2
  135. // Per documentation, "Any number of underlining =’s or -’s will work."
  136. // http://daringfireball.net/projects/markdown/syntax#header
  137. // Ideally, the text would be marked as `header` as well, but this is
  138. // not really feasible at the moment. So, instead, we're testing against
  139. // what works today, to avoid any regressions.
  140. //
  141. // Check if single underlining = works
  142. MT("setextH1",
  143. "foo",
  144. "[header&header-1 =]");
  145. // Check if 3+ ='s work
  146. MT("setextH1",
  147. "foo",
  148. "[header&header-1 ===]");
  149. // Check if single underlining - works
  150. MT("setextH2",
  151. "foo",
  152. "[header&header-2 -]");
  153. // Check if 3+ -'s work
  154. MT("setextH2",
  155. "foo",
  156. "[header&header-2 ---]");
  157. // Single-line blockquote with trailing space
  158. MT("blockquoteSpace",
  159. "[quote&quote-1 > foo]");
  160. // Single-line blockquote
  161. MT("blockquoteNoSpace",
  162. "[quote&quote-1 >foo]");
  163. // No blank line before blockquote
  164. MT("blockquoteNoBlankLine",
  165. "foo",
  166. "[quote&quote-1 > bar]");
  167. // Nested blockquote
  168. MT("blockquoteSpace",
  169. "[quote&quote-1 > foo]",
  170. "[quote&quote-1 >][quote&quote-2 > foo]",
  171. "[quote&quote-1 >][quote&quote-2 >][quote&quote-3 > foo]");
  172. // Single-line blockquote followed by normal paragraph
  173. MT("blockquoteThenParagraph",
  174. "[quote&quote-1 >foo]",
  175. "",
  176. "bar");
  177. // Multi-line blockquote (lazy mode)
  178. MT("multiBlockquoteLazy",
  179. "[quote&quote-1 >foo]",
  180. "[quote&quote-1 bar]");
  181. // Multi-line blockquote followed by normal paragraph (lazy mode)
  182. MT("multiBlockquoteLazyThenParagraph",
  183. "[quote&quote-1 >foo]",
  184. "[quote&quote-1 bar]",
  185. "",
  186. "hello");
  187. // Multi-line blockquote (non-lazy mode)
  188. MT("multiBlockquote",
  189. "[quote&quote-1 >foo]",
  190. "[quote&quote-1 >bar]");
  191. // Multi-line blockquote followed by normal paragraph (non-lazy mode)
  192. MT("multiBlockquoteThenParagraph",
  193. "[quote&quote-1 >foo]",
  194. "[quote&quote-1 >bar]",
  195. "",
  196. "hello");
  197. // Check list types
  198. MT("listAsterisk",
  199. "foo",
  200. "bar",
  201. "",
  202. "[variable-2 * foo]",
  203. "[variable-2 * bar]");
  204. MT("listPlus",
  205. "foo",
  206. "bar",
  207. "",
  208. "[variable-2 + foo]",
  209. "[variable-2 + bar]");
  210. MT("listDash",
  211. "foo",
  212. "bar",
  213. "",
  214. "[variable-2 - foo]",
  215. "[variable-2 - bar]");
  216. MT("listNumber",
  217. "foo",
  218. "bar",
  219. "",
  220. "[variable-2 1. foo]",
  221. "[variable-2 2. bar]");
  222. // Lists require a preceding blank line (per Dingus)
  223. MT("listBogus",
  224. "foo",
  225. "1. bar",
  226. "2. hello");
  227. // List after header
  228. MT("listAfterHeader",
  229. "[header&header-1 # foo]",
  230. "[variable-2 - bar]");
  231. // Formatting in lists (*)
  232. MT("listAsteriskFormatting",
  233. "[variable-2 * ][variable-2&em *foo*][variable-2 bar]",
  234. "[variable-2 * ][variable-2&strong **foo**][variable-2 bar]",
  235. "[variable-2 * ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
  236. "[variable-2 * ][variable-2&comment `foo`][variable-2 bar]");
  237. // Formatting in lists (+)
  238. MT("listPlusFormatting",
  239. "[variable-2 + ][variable-2&em *foo*][variable-2 bar]",
  240. "[variable-2 + ][variable-2&strong **foo**][variable-2 bar]",
  241. "[variable-2 + ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
  242. "[variable-2 + ][variable-2&comment `foo`][variable-2 bar]");
  243. // Formatting in lists (-)
  244. MT("listDashFormatting",
  245. "[variable-2 - ][variable-2&em *foo*][variable-2 bar]",
  246. "[variable-2 - ][variable-2&strong **foo**][variable-2 bar]",
  247. "[variable-2 - ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
  248. "[variable-2 - ][variable-2&comment `foo`][variable-2 bar]");
  249. // Formatting in lists (1.)
  250. MT("listNumberFormatting",
  251. "[variable-2 1. ][variable-2&em *foo*][variable-2 bar]",
  252. "[variable-2 2. ][variable-2&strong **foo**][variable-2 bar]",
  253. "[variable-2 3. ][variable-2&strong **][variable-2&em&strong *foo**][variable-2&em *][variable-2 bar]",
  254. "[variable-2 4. ][variable-2&comment `foo`][variable-2 bar]");
  255. // Paragraph lists
  256. MT("listParagraph",
  257. "[variable-2 * foo]",
  258. "",
  259. "[variable-2 * bar]");
  260. // Multi-paragraph lists
  261. //
  262. // 4 spaces
  263. MT("listMultiParagraph",
  264. "[variable-2 * foo]",
  265. "",
  266. "[variable-2 * bar]",
  267. "",
  268. " [variable-2 hello]");
  269. // 4 spaces, extra blank lines (should still be list, per Dingus)
  270. MT("listMultiParagraphExtra",
  271. "[variable-2 * foo]",
  272. "",
  273. "[variable-2 * bar]",
  274. "",
  275. "",
  276. " [variable-2 hello]");
  277. // 4 spaces, plus 1 space (should still be list, per Dingus)
  278. MT("listMultiParagraphExtraSpace",
  279. "[variable-2 * foo]",
  280. "",
  281. "[variable-2 * bar]",
  282. "",
  283. " [variable-2 hello]",
  284. "",
  285. " [variable-2 world]");
  286. // 1 tab
  287. MT("listTab",
  288. "[variable-2 * foo]",
  289. "",
  290. "[variable-2 * bar]",
  291. "",
  292. "\t[variable-2 hello]");
  293. // No indent
  294. MT("listNoIndent",
  295. "[variable-2 * foo]",
  296. "",
  297. "[variable-2 * bar]",
  298. "",
  299. "hello");
  300. // Blockquote
  301. MT("blockquote",
  302. "[variable-2 * foo]",
  303. "",
  304. "[variable-2 * bar]",
  305. "",
  306. " [variable-2&quote&quote-1 > hello]");
  307. // Code block
  308. MT("blockquoteCode",
  309. "[variable-2 * foo]",
  310. "",
  311. "[variable-2 * bar]",
  312. "",
  313. " [comment > hello]",
  314. "",
  315. " [variable-2 world]");
  316. // Code block followed by text
  317. MT("blockquoteCodeText",
  318. "[variable-2 * foo]",
  319. "",
  320. " [variable-2 bar]",
  321. "",
  322. " [comment hello]",
  323. "",
  324. " [variable-2 world]");
  325. // Nested list
  326. MT("listAsteriskNested",
  327. "[variable-2 * foo]",
  328. "",
  329. " [variable-3 * bar]");
  330. MT("listPlusNested",
  331. "[variable-2 + foo]",
  332. "",
  333. " [variable-3 + bar]");
  334. MT("listDashNested",
  335. "[variable-2 - foo]",
  336. "",
  337. " [variable-3 - bar]");
  338. MT("listNumberNested",
  339. "[variable-2 1. foo]",
  340. "",
  341. " [variable-3 2. bar]");
  342. MT("listMixed",
  343. "[variable-2 * foo]",
  344. "",
  345. " [variable-3 + bar]",
  346. "",
  347. " [keyword - hello]",
  348. "",
  349. " [variable-2 1. world]");
  350. MT("listBlockquote",
  351. "[variable-2 * foo]",
  352. "",
  353. " [variable-3 + bar]",
  354. "",
  355. " [quote&quote-1&variable-3 > hello]");
  356. MT("listCode",
  357. "[variable-2 * foo]",
  358. "",
  359. " [variable-3 + bar]",
  360. "",
  361. " [comment hello]");
  362. // Code with internal indentation
  363. MT("listCodeIndentation",
  364. "[variable-2 * foo]",
  365. "",
  366. " [comment bar]",
  367. " [comment hello]",
  368. " [comment world]",
  369. " [comment foo]",
  370. " [variable-2 bar]");
  371. // List nesting edge cases
  372. MT("listNested",
  373. "[variable-2 * foo]",
  374. "",
  375. " [variable-3 * bar]",
  376. "",
  377. " [variable-2 hello]"
  378. );
  379. MT("listNested",
  380. "[variable-2 * foo]",
  381. "",
  382. " [variable-3 * bar]",
  383. "",
  384. " [variable-3 * foo]"
  385. );
  386. // Code followed by text
  387. MT("listCodeText",
  388. "[variable-2 * foo]",
  389. "",
  390. " [comment bar]",
  391. "",
  392. "hello");
  393. // Following tests directly from official Markdown documentation
  394. // http://daringfireball.net/projects/markdown/syntax#hr
  395. MT("hrSpace",
  396. "[hr * * *]");
  397. MT("hr",
  398. "[hr ***]");
  399. MT("hrLong",
  400. "[hr *****]");
  401. MT("hrSpaceDash",
  402. "[hr - - -]");
  403. MT("hrDashLong",
  404. "[hr ---------------------------------------]");
  405. // Inline link with title
  406. MT("linkTitle",
  407. "[link [[foo]]][string (http://example.com/ \"bar\")] hello");
  408. // Inline link without title
  409. MT("linkNoTitle",
  410. "[link [[foo]]][string (http://example.com/)] bar");
  411. // Inline link with image
  412. MT("linkImage",
  413. "[link [[][tag ![[foo]]][string (http://example.com/)][link ]]][string (http://example.com/)] bar");
  414. // Inline link with Em
  415. MT("linkEm",
  416. "[link [[][link&em *foo*][link ]]][string (http://example.com/)] bar");
  417. // Inline link with Strong
  418. MT("linkStrong",
  419. "[link [[][link&strong **foo**][link ]]][string (http://example.com/)] bar");
  420. // Inline link with EmStrong
  421. MT("linkEmStrong",
  422. "[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string (http://example.com/)] bar");
  423. // Image with title
  424. MT("imageTitle",
  425. "[tag ![[foo]]][string (http://example.com/ \"bar\")] hello");
  426. // Image without title
  427. MT("imageNoTitle",
  428. "[tag ![[foo]]][string (http://example.com/)] bar");
  429. // Image with asterisks
  430. MT("imageAsterisks",
  431. "[tag ![[*foo*]]][string (http://example.com/)] bar");
  432. // Not a link. Should be normal text due to square brackets being used
  433. // regularly in text, especially in quoted material, and no space is allowed
  434. // between square brackets and parentheses (per Dingus).
  435. MT("notALink",
  436. "[[foo]] (bar)");
  437. // Reference-style links
  438. MT("linkReference",
  439. "[link [[foo]]][string [[bar]]] hello");
  440. // Reference-style links with Em
  441. MT("linkReferenceEm",
  442. "[link [[][link&em *foo*][link ]]][string [[bar]]] hello");
  443. // Reference-style links with Strong
  444. MT("linkReferenceStrong",
  445. "[link [[][link&strong **foo**][link ]]][string [[bar]]] hello");
  446. // Reference-style links with EmStrong
  447. MT("linkReferenceEmStrong",
  448. "[link [[][link&strong **][link&em&strong *foo**][link&em *][link ]]][string [[bar]]] hello");
  449. // Reference-style links with optional space separator (per docuentation)
  450. // "You can optionally use a space to separate the sets of brackets"
  451. MT("linkReferenceSpace",
  452. "[link [[foo]]] [string [[bar]]] hello");
  453. // Should only allow a single space ("...use *a* space...")
  454. MT("linkReferenceDoubleSpace",
  455. "[[foo]] [[bar]] hello");
  456. // Reference-style links with implicit link name
  457. MT("linkImplicit",
  458. "[link [[foo]]][string [[]]] hello");
  459. // @todo It would be nice if, at some point, the document was actually
  460. // checked to see if the referenced link exists
  461. // Link label, for reference-style links (taken from documentation)
  462. MT("labelNoTitle",
  463. "[link [[foo]]:] [string http://example.com/]");
  464. MT("labelIndented",
  465. " [link [[foo]]:] [string http://example.com/]");
  466. MT("labelSpaceTitle",
  467. "[link [[foo bar]]:] [string http://example.com/ \"hello\"]");
  468. MT("labelDoubleTitle",
  469. "[link [[foo bar]]:] [string http://example.com/ \"hello\"] \"world\"");
  470. MT("labelTitleDoubleQuotes",
  471. "[link [[foo]]:] [string http://example.com/ \"bar\"]");
  472. MT("labelTitleSingleQuotes",
  473. "[link [[foo]]:] [string http://example.com/ 'bar']");
  474. MT("labelTitleParenthese",
  475. "[link [[foo]]:] [string http://example.com/ (bar)]");
  476. MT("labelTitleInvalid",
  477. "[link [[foo]]:] [string http://example.com/] bar");
  478. MT("labelLinkAngleBrackets",
  479. "[link [[foo]]:] [string <http://example.com/> \"bar\"]");
  480. MT("labelTitleNextDoubleQuotes",
  481. "[link [[foo]]:] [string http://example.com/]",
  482. "[string \"bar\"] hello");
  483. MT("labelTitleNextSingleQuotes",
  484. "[link [[foo]]:] [string http://example.com/]",
  485. "[string 'bar'] hello");
  486. MT("labelTitleNextParenthese",
  487. "[link [[foo]]:] [string http://example.com/]",
  488. "[string (bar)] hello");
  489. MT("labelTitleNextMixed",
  490. "[link [[foo]]:] [string http://example.com/]",
  491. "(bar\" hello");
  492. MT("linkWeb",
  493. "[link <http://example.com/>] foo");
  494. MT("linkWebDouble",
  495. "[link <http://example.com/>] foo [link <http://example.com/>]");
  496. MT("linkEmail",
  497. "[link <user@example.com>] foo");
  498. MT("linkEmailDouble",
  499. "[link <user@example.com>] foo [link <user@example.com>]");
  500. MT("emAsterisk",
  501. "[em *foo*] bar");
  502. MT("emUnderscore",
  503. "[em _foo_] bar");
  504. MT("emInWordAsterisk",
  505. "foo[em *bar*]hello");
  506. MT("emInWordUnderscore",
  507. "foo[em _bar_]hello");
  508. // Per documentation: "...surround an * or _ with spaces, it’ll be
  509. // treated as a literal asterisk or underscore."
  510. MT("emEscapedBySpaceIn",
  511. "foo [em _bar _ hello_] world");
  512. MT("emEscapedBySpaceOut",
  513. "foo _ bar[em _hello_]world");
  514. MT("emEscapedByNewline",
  515. "foo",
  516. "_ bar[em _hello_]world");
  517. // Unclosed emphasis characters
  518. // Instead of simply marking as EM / STRONG, it would be nice to have an
  519. // incomplete flag for EM and STRONG, that is styled slightly different.
  520. MT("emIncompleteAsterisk",
  521. "foo [em *bar]");
  522. MT("emIncompleteUnderscore",
  523. "foo [em _bar]");
  524. MT("strongAsterisk",
  525. "[strong **foo**] bar");
  526. MT("strongUnderscore",
  527. "[strong __foo__] bar");
  528. MT("emStrongAsterisk",
  529. "[em *foo][em&strong **bar*][strong hello**] world");
  530. MT("emStrongUnderscore",
  531. "[em _foo][em&strong __bar_][strong hello__] world");
  532. // "...same character must be used to open and close an emphasis span.""
  533. MT("emStrongMixed",
  534. "[em _foo][em&strong **bar*hello__ world]");
  535. MT("emStrongMixed",
  536. "[em *foo][em&strong __bar_hello** world]");
  537. // These characters should be escaped:
  538. // \ backslash
  539. // ` backtick
  540. // * asterisk
  541. // _ underscore
  542. // {} curly braces
  543. // [] square brackets
  544. // () parentheses
  545. // # hash mark
  546. // + plus sign
  547. // - minus sign (hyphen)
  548. // . dot
  549. // ! exclamation mark
  550. MT("escapeBacktick",
  551. "foo \\`bar\\`");
  552. MT("doubleEscapeBacktick",
  553. "foo \\\\[comment `bar\\\\`]");
  554. MT("escapeAsterisk",
  555. "foo \\*bar\\*");
  556. MT("doubleEscapeAsterisk",
  557. "foo \\\\[em *bar\\\\*]");
  558. MT("escapeUnderscore",
  559. "foo \\_bar\\_");
  560. MT("doubleEscapeUnderscore",
  561. "foo \\\\[em _bar\\\\_]");
  562. MT("escapeHash",
  563. "\\# foo");
  564. MT("doubleEscapeHash",
  565. "\\\\# foo");
  566. MT("escapeNewline",
  567. "\\",
  568. "[em *foo*]");
  569. // Tests to make sure GFM-specific things aren't getting through
  570. MT("taskList",
  571. "[variable-2 * [ ]] bar]");
  572. MT("fencedCodeBlocks",
  573. "[comment ```]",
  574. "foo",
  575. "[comment ```]");
  576. // Tests that require XML mode
  577. MT("xmlMode",
  578. "[tag&bracket <][tag div][tag&bracket >]",
  579. "*foo*",
  580. "[tag&bracket <][tag http://github.com][tag&bracket />]",
  581. "[tag&bracket </][tag div][tag&bracket >]",
  582. "[link <http://github.com/>]");
  583. MT("xmlModeWithMarkdownInside",
  584. "[tag&bracket <][tag div] [attribute markdown]=[string 1][tag&bracket >]",
  585. "[em *foo*]",
  586. "[link <http://github.com/>]",
  587. "[tag </div>]",
  588. "[link <http://github.com/>]",
  589. "[tag&bracket <][tag div][tag&bracket >]",
  590. "[tag&bracket </][tag div][tag&bracket >]");
  591. })();