test.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. (function() {
  4. var config = {tabSize: 4, indentUnit: 2}
  5. var mode = CodeMirror.getMode(config, "markdown");
  6. function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
  7. var modeHighlightFormatting = CodeMirror.getMode(config, {name: "markdown", highlightFormatting: true});
  8. function FT(name) { test.mode(name, modeHighlightFormatting, Array.prototype.slice.call(arguments, 1)); }
  9. var modeMT_noXml = CodeMirror.getMode(config, {name: "markdown", xml: false});
  10. function MT_noXml(name) { test.mode(name, modeMT_noXml, Array.prototype.slice.call(arguments, 1)); }
  11. var modeMT_noFencedHighlight = CodeMirror.getMode(config, {name: "markdown", fencedCodeBlockHighlighting: false});
  12. function MT_noFencedHighlight(name) { test.mode(name, modeMT_noFencedHighlight, Array.prototype.slice.call(arguments, 1)); }
  13. var modeAtxNoSpace = CodeMirror.getMode(config, {name: "markdown", allowAtxHeaderWithoutSpace: true});
  14. function AtxNoSpaceTest(name) { test.mode(name, modeAtxNoSpace, Array.prototype.slice.call(arguments, 1)); }
  15. var modeOverrideClasses = CodeMirror.getMode(config, {
  16. name: "markdown",
  17. strikethrough: true,
  18. emoji: true,
  19. tokenTypeOverrides: {
  20. "header" : "override-header",
  21. "code" : "override-code",
  22. "quote" : "override-quote",
  23. "list1" : "override-list1",
  24. "list2" : "override-list2",
  25. "list3" : "override-list3",
  26. "hr" : "override-hr",
  27. "image" : "override-image",
  28. "imageAltText": "override-image-alt-text",
  29. "imageMarker": "override-image-marker",
  30. "linkInline" : "override-link-inline",
  31. "linkEmail" : "override-link-email",
  32. "linkText" : "override-link-text",
  33. "linkHref" : "override-link-href",
  34. "em" : "override-em",
  35. "strong" : "override-strong",
  36. "strikethrough" : "override-strikethrough",
  37. "emoji" : "override-emoji"
  38. }});
  39. function TokenTypeOverrideTest(name) { test.mode(name, modeOverrideClasses, Array.prototype.slice.call(arguments, 1)); }
  40. var modeFormattingOverride = CodeMirror.getMode(config, {
  41. name: "markdown",
  42. highlightFormatting: true,
  43. tokenTypeOverrides: {
  44. "formatting" : "override-formatting"
  45. }});
  46. function FormatTokenTypeOverrideTest(name) { test.mode(name, modeFormattingOverride, Array.prototype.slice.call(arguments, 1)); }
  47. var modeET = CodeMirror.getMode(config, {name: "markdown", emoji: true});
  48. function ET(name) { test.mode(name, modeET, Array.prototype.slice.call(arguments, 1)); }
  49. FT("formatting_emAsterisk",
  50. "[em&formatting&formatting-em *][em foo][em&formatting&formatting-em *]");
  51. FT("formatting_emUnderscore",
  52. "[em&formatting&formatting-em _][em foo][em&formatting&formatting-em _]");
  53. FT("formatting_strongAsterisk",
  54. "[strong&formatting&formatting-strong **][strong foo][strong&formatting&formatting-strong **]");
  55. FT("formatting_strongUnderscore",
  56. "[strong&formatting&formatting-strong __][strong foo][strong&formatting&formatting-strong __]");
  57. FT("formatting_codeBackticks",
  58. "[comment&formatting&formatting-code `][comment foo][comment&formatting&formatting-code `]");
  59. FT("formatting_doubleBackticks",
  60. "[comment&formatting&formatting-code ``][comment foo ` bar][comment&formatting&formatting-code ``]");
  61. FT("formatting_atxHeader",
  62. "[header&header-1&formatting&formatting-header&formatting-header-1 # ][header&header-1 foo # bar ][header&header-1&formatting&formatting-header&formatting-header-1 #]");
  63. FT("formatting_setextHeader",
  64. "[header&header-1 foo]",
  65. "[header&header-1&formatting&formatting-header&formatting-header-1 =]");
  66. FT("formatting_blockquote",
  67. "[quote&quote-1&formatting&formatting-quote&formatting-quote-1 > ][quote&quote-1 foo]");
  68. FT("formatting_list",
  69. "[variable-2&formatting&formatting-list&formatting-list-ul - ][variable-2 foo]");
  70. FT("formatting_list",
  71. "[variable-2&formatting&formatting-list&formatting-list-ol 1. ][variable-2 foo]");
  72. FT("formatting_link",
  73. "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string&url (][string&url http://example.com/][string&formatting&formatting-link-string&url )]");
  74. FT("formatting_linkReference",
  75. "[link&formatting&formatting-link [][link foo][link&formatting&formatting-link ]]][string&formatting&formatting-link-string&url [][string&url bar][string&formatting&formatting-link-string&url ]]]",
  76. "[link&formatting&formatting-link [][link bar][link&formatting&formatting-link ]]:] [string&url http://example.com/]");
  77. FT("formatting_linkWeb",
  78. "[link&formatting&formatting-link <][link http://example.com/][link&formatting&formatting-link >]");
  79. FT("formatting_linkEmail",
  80. "[link&formatting&formatting-link <][link user@example.com][link&formatting&formatting-link >]");
  81. FT("formatting_escape",
  82. "[formatting-escape \\*]");
  83. FT("formatting_image",
  84. "[formatting&formatting-image&image&image-marker !][formatting&formatting-image&image&image-alt-text&link [[][image&image-alt-text&link alt text][formatting&formatting-image&image&image-alt-text&link ]]][formatting&formatting-link-string&string&url (][url&string http://link.to/image.jpg][formatting&formatting-link-string&string&url )]");
  85. FT("codeBlock",
  86. "[comment&formatting&formatting-code-block ```css]",
  87. "[tag foo]",
  88. "[comment&formatting&formatting-code-block ```]");
  89. MT("plainText",
  90. "foo");
  91. // Don't style single trailing space
  92. MT("trailingSpace1",
  93. "foo ");
  94. // Two or more trailing spaces should be styled with line break character
  95. MT("trailingSpace2",
  96. "foo[trailing-space-a ][trailing-space-new-line ]");
  97. MT("trailingSpace3",
  98. "foo[trailing-space-a ][trailing-space-b ][trailing-space-new-line ]");
  99. MT("trailingSpace4",
  100. "foo[trailing-space-a ][trailing-space-b ][trailing-space-a ][trailing-space-new-line ]");
  101. // Code blocks using 4 spaces (regardless of CodeMirror.tabSize value)
  102. MT("codeBlocksUsing4Spaces",
  103. " [comment foo]");
  104. // Code blocks using 4 spaces with internal indentation
  105. MT("codeBlocksUsing4SpacesIndentation",
  106. " [comment bar]",
  107. " [comment hello]",
  108. " [comment world]",
  109. " [comment foo]",
  110. "bar");
  111. // Code blocks should end even after extra indented lines
  112. MT("codeBlocksWithTrailingIndentedLine",
  113. " [comment foo]",
  114. " [comment bar]",
  115. " [comment baz]",
  116. " ",
  117. "hello");
  118. // Code blocks using 1 tab (regardless of CodeMirror.indentWithTabs value)
  119. MT("codeBlocksUsing1Tab",
  120. "\t[comment foo]");
  121. // No code blocks directly after paragraph
  122. // http://spec.commonmark.org/0.19/#example-65
  123. MT("noCodeBlocksAfterParagraph",
  124. "Foo",
  125. " Bar");
  126. MT("codeBlocksAfterATX",
  127. "[header&header-1 # foo]",
  128. " [comment code]");
  129. MT("codeBlocksAfterSetext",
  130. "[header&header-2 foo]",
  131. "[header&header-2 ---]",
  132. " [comment code]");
  133. MT("codeBlocksAfterFencedCode",
  134. "[comment ```]",
  135. "[comment foo]",
  136. "[comment ```]",
  137. " [comment code]");
  138. // Inline code using backticks
  139. MT("inlineCodeUsingBackticks",
  140. "foo [comment `bar`]");
  141. // Block code using single backtick (shouldn't work)
  142. MT("blockCodeSingleBacktick",
  143. "[comment `]",
  144. "[comment foo]",
  145. "[comment `]");
  146. // Unclosed backticks
  147. // Instead of simply marking as CODE, it would be nice to have an
  148. // incomplete flag for CODE, that is styled slightly different.
  149. MT("unclosedBackticks",
  150. "foo [comment `bar]");
  151. // Per documentation: "To include a literal backtick character within a
  152. // code span, you can use multiple backticks as the opening and closing
  153. // delimiters"
  154. MT("doubleBackticks",
  155. "[comment ``foo ` bar``]");
  156. // Tests based on Dingus
  157. // http://daringfireball.net/projects/markdown/dingus
  158. //
  159. // Multiple backticks within an inline code block
  160. MT("consecutiveBackticks",
  161. "[comment `foo```bar`]");
  162. // Multiple backticks within an inline code block with a second code block
  163. MT("consecutiveBackticks",
  164. "[comment `foo```bar`] hello [comment `world`]");
  165. // Unclosed with several different groups of backticks
  166. MT("unclosedBackticks",
  167. "[comment ``foo ``` bar` hello]");
  168. // Closed with several different groups of backticks
  169. MT("closedBackticks",
  170. "[comment ``foo ``` bar` hello``] world");
  171. // info string cannot contain backtick, thus should result in inline code
  172. MT("closingFencedMarksOnSameLine",
  173. "[comment ``` code ```] foo");
  174. // atx headers
  175. // http://daringfireball.net/projects/markdown/syntax#header
  176. MT("atxH1",
  177. "[header&header-1 # foo]");
  178. MT("atxH2",
  179. "[header&header-2 ## foo]");
  180. MT("atxH3",
  181. "[header&header-3 ### foo]");
  182. MT("atxH4",
  183. "[header&header-4 #### foo]");
  184. MT("atxH5",
  185. "[header&header-5 ##### foo]");
  186. MT("atxH6",
  187. "[header&header-6 ###### foo]");
  188. // http://spec.commonmark.org/0.19/#example-24
  189. MT("noAtxH7",
  190. "####### foo");
  191. // http://spec.commonmark.org/0.19/#example-25
  192. MT("noAtxH1WithoutSpace",
  193. "#5 bolt");
  194. // CommonMark requires a space after # but most parsers don't
  195. AtxNoSpaceTest("atxNoSpaceAllowed_H1NoSpace",
  196. "[header&header-1 #foo]");
  197. AtxNoSpaceTest("atxNoSpaceAllowed_H4NoSpace",
  198. "[header&header-4 ####foo]");
  199. AtxNoSpaceTest("atxNoSpaceAllowed_H1Space",
  200. "[header&header-1 # foo]");
  201. // Inline styles should be parsed inside headers
  202. MT("atxH1inline",
  203. "[header&header-1 # foo ][header&header-1&em *bar*]");
  204. MT("atxIndentedTooMuch",
  205. "[header&header-1 # foo]",
  206. " [comment # bar]");
  207. // disable atx inside blockquote until we implement proper blockquote inner mode
  208. // TODO: fix to be CommonMark-compliant
  209. MT("atxNestedInsideBlockquote",
  210. "[quote&quote-1 > # foo]");
  211. MT("atxAfterBlockquote",
  212. "[quote&quote-1 > foo]",
  213. "[header&header-1 # bar]");
  214. // Setext headers - H1, H2
  215. // Per documentation, "Any number of underlining =’s or -’s will work."
  216. // http://daringfireball.net/projects/markdown/syntax#header
  217. // Ideally, the text would be marked as `header` as well, but this is
  218. // not really feasible at the moment. So, instead, we're testing against
  219. // what works today, to avoid any regressions.
  220. //
  221. // Check if single underlining = works
  222. MT("setextH1",
  223. "[header&header-1 foo]",
  224. "[header&header-1 =]");
  225. // Check if 3+ ='s work
  226. MT("setextH1",
  227. "[header&header-1 foo]",
  228. "[header&header-1 ===]");
  229. // Check if single underlining - works
  230. MT("setextH2",
  231. "[header&header-2 foo]",
  232. "[header&header-2 -]");
  233. // Check if 3+ -'s work
  234. MT("setextH2",
  235. "[header&header-2 foo]",
  236. "[header&header-2 ---]");
  237. // http://spec.commonmark.org/0.19/#example-45
  238. MT("setextH2AllowSpaces",
  239. "[header&header-2 foo]",
  240. " [header&header-2 ---- ]");
  241. // http://spec.commonmark.org/0.19/#example-44
  242. MT("noSetextAfterIndentedCodeBlock",
  243. " [comment foo]",
  244. "[hr ---]");
  245. MT("setextAfterFencedCode",
  246. "[comment ```]",
  247. "[comment foo]",
  248. "[comment ```]",
  249. "[header&header-2 bar]",
  250. "[header&header-2 ---]");
  251. MT("setextAferATX",
  252. "[header&header-1 # foo]",
  253. "[header&header-2 bar]",
  254. "[header&header-2 ---]");
  255. // http://spec.commonmark.org/0.19/#example-51
  256. MT("noSetextAfterQuote",
  257. "[quote&quote-1 > foo]",
  258. "[hr ---]",
  259. "",
  260. "[quote&quote-1 > foo]",
  261. "[quote&quote-1 bar]",
  262. "[hr ---]");
  263. MT("noSetextAfterList",
  264. "[variable-2 - foo]",
  265. "[hr ---]");
  266. MT("noSetextAfterList_listContinuation",
  267. "[variable-2 - foo]",
  268. "bar",
  269. "[hr ---]");
  270. MT("setextAfterList_afterIndentedCode",
  271. "[variable-2 - foo]",
  272. "",
  273. " [comment bar]",
  274. "[header&header-2 baz]",
  275. "[header&header-2 ---]");
  276. MT("setextAfterList_afterFencedCodeBlocks",
  277. "[variable-2 - foo]",
  278. "",
  279. " [comment ```]",
  280. " [comment bar]",
  281. " [comment ```]",
  282. "[header&header-2 baz]",
  283. "[header&header-2 ---]");
  284. MT("setextAfterList_afterHeader",
  285. "[variable-2 - foo]",
  286. " [variable-2&header&header-1 # bar]",
  287. "[header&header-2 baz]",
  288. "[header&header-2 ---]");
  289. MT("setextAfterList_afterHr",
  290. "[variable-2 - foo]",
  291. "",
  292. " [hr ---]",
  293. "[header&header-2 bar]",
  294. "[header&header-2 ---]");
  295. MT("setext_nestedInlineMarkup",
  296. "[header&header-1 foo ][em&header&header-1 *bar*]",
  297. "[header&header-1 =]");
  298. MT("setext_linkDef",
  299. "[link [[aaa]]:] [string&url http://google.com 'title']",
  300. "[hr ---]");
  301. // currently, looks max one line ahead, thus won't catch valid CommonMark
  302. // markup
  303. MT("setext_oneLineLookahead",
  304. "foo",
  305. "[header&header-1 bar]",
  306. "[header&header-1 =]");
  307. // ensure we don't regard space after dash as a list
  308. MT("setext_emptyList",
  309. "[header&header-2 foo]",
  310. "[header&header-2 - ]",
  311. "foo");
  312. // Single-line blockquote with trailing space
  313. MT("blockquoteSpace",
  314. "[quote&quote-1 > foo]");
  315. // Single-line blockquote
  316. MT("blockquoteNoSpace",
  317. "[quote&quote-1 >foo]");
  318. // No blank line before blockquote
  319. MT("blockquoteNoBlankLine",
  320. "foo",
  321. "[quote&quote-1 > bar]");
  322. MT("blockquoteNested",
  323. "[quote&quote-1 > foo]",
  324. "[quote&quote-1 >][quote&quote-2 > foo]",
  325. "[quote&quote-1 >][quote&quote-2 >][quote&quote-3 > foo]");
  326. // ensure quote-level is inferred correctly even if indented
  327. MT("blockquoteNestedIndented",
  328. " [quote&quote-1 > foo]",
  329. " [quote&quote-1 >][quote&quote-2 > foo]",
  330. " [quote&quote-1 >][quote&quote-2 >][quote&quote-3 > foo]");
  331. // ensure quote-level is inferred correctly even if indented
  332. MT("blockquoteIndentedTooMuch",
  333. "foo",
  334. " > bar");
  335. // Single-line blockquote followed by normal paragraph
  336. MT("blockquoteThenParagraph",
  337. "[quote&quote-1 >foo]",
  338. "",
  339. "bar");
  340. // Multi-line blockquote (lazy mode)
  341. MT("multiBlockquoteLazy",
  342. "[quote&quote-1 >foo]",
  343. "[quote&quote-1 bar]");
  344. // Multi-line blockquote followed by normal paragraph (lazy mode)
  345. MT("multiBlockquoteLazyThenParagraph",
  346. "[quote&quote-1 >foo]",
  347. "[quote&quote-1 bar]",
  348. "",
  349. "hello");
  350. // Multi-line blockquote (non-lazy mode)
  351. MT("multiBlockquote",
  352. "[quote&quote-1 >foo]",
  353. "[quote&quote-1 >bar]");
  354. // Multi-line blockquote followed by normal paragraph (non-lazy mode)
  355. MT("multiBlockquoteThenParagraph",
  356. "[quote&quote-1 >foo]",
  357. "[quote&quote-1 >bar]",
  358. "",
  359. "hello");
  360. // disallow lists inside blockquote for now because it causes problems outside blockquote
  361. // TODO: fix to be CommonMark-compliant
  362. MT("listNestedInBlockquote",
  363. "[quote&quote-1 > - foo]");
  364. // disallow fenced blocks inside blockquote because it causes problems outside blockquote
  365. // TODO: fix to be CommonMark-compliant
  366. MT("fencedBlockNestedInBlockquote",
  367. "[quote&quote-1 > ```]",
  368. "[quote&quote-1 > code]",
  369. "[quote&quote-1 > ```]",
  370. // ensure we still allow inline code
  371. "[quote&quote-1 > ][quote&quote-1&comment `code`]");
  372. // Header with leading space after continued blockquote (#3287, negative indentation)
  373. MT("headerAfterContinuedBlockquote",
  374. "[quote&quote-1 > foo]",
  375. "[quote&quote-1 bar]",
  376. "",
  377. " [header&header-1 # hello]");
  378. // Check list types
  379. MT("listAsterisk",
  380. "foo",
  381. "bar",
  382. "",
  383. "[variable-2 * foo]",
  384. "[variable-2 * bar]");
  385. MT("listPlus",
  386. "foo",
  387. "bar",
  388. "",
  389. "[variable-2 + foo]",
  390. "[variable-2 + bar]");
  391. MT("listDash",
  392. "foo",
  393. "bar",
  394. "",
  395. "[variable-2 - foo]",
  396. "[variable-2 - bar]");
  397. MT("listNumber",
  398. "foo",
  399. "bar",
  400. "",
  401. "[variable-2 1. foo]",
  402. "[variable-2 2. bar]");
  403. MT("listFromParagraph",
  404. "foo",
  405. "[variable-2 1. bar]",
  406. "[variable-2 2. hello]");
  407. // List after hr
  408. MT("listAfterHr",
  409. "[hr ---]",
  410. "[variable-2 - bar]");
  411. // List after header
  412. MT("listAfterHeader",
  413. "[header&header-1 # foo]",
  414. "[variable-2 - bar]");
  415. // hr after list
  416. MT("hrAfterList",
  417. "[variable-2 - foo]",
  418. "[hr -----]");
  419. MT("hrAfterFencedCode",
  420. "[comment ```]",
  421. "[comment code]",
  422. "[comment ```]",
  423. "[hr ---]");
  424. // allow hr inside lists
  425. // (require prev line to be empty or hr, TODO: non-CommonMark-compliant)
  426. MT("hrInsideList",
  427. "[variable-2 - foo]",
  428. "",
  429. " [hr ---]",
  430. " [hr ---]",
  431. "",
  432. " [comment ---]");
  433. MT("consecutiveHr",
  434. "[hr ---]",
  435. "[hr ---]",
  436. "[hr ---]");
  437. // Formatting in lists (*)
  438. MT("listAsteriskFormatting",
  439. "[variable-2 * ][variable-2&em *foo*][variable-2 bar]",
  440. "[variable-2 * ][variable-2&strong **foo**][variable-2 bar]",
  441. "[variable-2 * ][variable-2&em&strong ***foo***][variable-2 bar]",
  442. "[variable-2 * ][variable-2&comment `foo`][variable-2 bar]");
  443. // Formatting in lists (+)
  444. MT("listPlusFormatting",
  445. "[variable-2 + ][variable-2&em *foo*][variable-2 bar]",
  446. "[variable-2 + ][variable-2&strong **foo**][variable-2 bar]",
  447. "[variable-2 + ][variable-2&em&strong ***foo***][variable-2 bar]",
  448. "[variable-2 + ][variable-2&comment `foo`][variable-2 bar]");
  449. // Formatting in lists (-)
  450. MT("listDashFormatting",
  451. "[variable-2 - ][variable-2&em *foo*][variable-2 bar]",
  452. "[variable-2 - ][variable-2&strong **foo**][variable-2 bar]",
  453. "[variable-2 - ][variable-2&em&strong ***foo***][variable-2 bar]",
  454. "[variable-2 - ][variable-2&comment `foo`][variable-2 bar]");
  455. // Formatting in lists (1.)
  456. MT("listNumberFormatting",
  457. "[variable-2 1. ][variable-2&em *foo*][variable-2 bar]",
  458. "[variable-2 2. ][variable-2&strong **foo**][variable-2 bar]",
  459. "[variable-2 3. ][variable-2&em&strong ***foo***][variable-2 bar]",
  460. "[variable-2 4. ][variable-2&comment `foo`][variable-2 bar]");
  461. // Paragraph lists
  462. MT("listParagraph",
  463. "[variable-2 * foo]",
  464. "",
  465. "[variable-2 * bar]");
  466. // Multi-paragraph lists
  467. //
  468. // 4 spaces
  469. MT("listMultiParagraph",
  470. "[variable-2 * foo]",
  471. "",
  472. "[variable-2 * bar]",
  473. "",
  474. " [variable-2 hello]");
  475. // 4 spaces, extra blank lines (should still be list, per Dingus)
  476. MT("listMultiParagraphExtra",
  477. "[variable-2 * foo]",
  478. "",
  479. "[variable-2 * bar]",
  480. "",
  481. "",
  482. " [variable-2 hello]");
  483. // 4 spaces, plus 1 space (should still be list, per Dingus)
  484. MT("listMultiParagraphExtraSpace",
  485. "[variable-2 * foo]",
  486. "",
  487. "[variable-2 * bar]",
  488. "",
  489. " [variable-2 hello]",
  490. "",
  491. " [variable-2 world]");
  492. // 1 tab
  493. MT("listTab",
  494. "[variable-2 * foo]",
  495. "",
  496. "[variable-2 * bar]",
  497. "",
  498. "\t[variable-2 hello]");
  499. // No indent
  500. MT("listNoIndent",
  501. "[variable-2 * foo]",
  502. "",
  503. "[variable-2 * bar]",
  504. "",
  505. "hello");
  506. MT("listCommonMarkIndentationCode",
  507. "[variable-2 * Code blocks also affect]",
  508. " [variable-3 * The next level starts where the contents start.]",
  509. " [variable-3 * Anything less than that will keep the item on the same level.]",
  510. " [variable-3 * Each list item can indent the first level further and further.]",
  511. " [variable-3 * For the most part, this makes sense while writing a list.]",
  512. " [keyword * This means two items with same indentation can be different levels.]",
  513. " [keyword * Each level has an indent requirement that can change between items.]",
  514. " [keyword * A list item that meets this will be part of the next level.]",
  515. " [variable-3 * Otherwise, it will be part of the level where it does meet this.]",
  516. " [variable-2 * World]");
  517. // should handle nested and un-nested lists
  518. MT("listCommonMark_MixedIndents",
  519. "[variable-2 * list1]",
  520. " [variable-2 list1]",
  521. " [variable-2&header&header-1 # heading still part of list1]",
  522. " [variable-2 text after heading still part of list1]",
  523. "",
  524. " [comment indented codeblock]",
  525. " [variable-2 list1 after code block]",
  526. " [variable-3 * list2]",
  527. // amount of spaces on empty lines between lists doesn't matter
  528. " ",
  529. // extra empty lines irrelevant
  530. "",
  531. "",
  532. " [variable-3 indented text part of list2]",
  533. " [keyword * list3]",
  534. "",
  535. " [variable-3 text at level of list2]",
  536. "",
  537. " [variable-2 de-indented text part of list1 again]",
  538. "",
  539. " [variable-2&comment ```]",
  540. " [comment code]",
  541. " [variable-2&comment ```]",
  542. "",
  543. " [variable-2 text after fenced code]");
  544. // should correctly parse numbered list content indentation
  545. MT("listCommonMark_NumeberedListIndent",
  546. "[variable-2 1000. list with base indent of 6]",
  547. "",
  548. " [variable-2 text must be indented 6 spaces at minimum]",
  549. "",
  550. " [variable-2 9-spaces indented text still part of list]",
  551. "",
  552. " [comment indented codeblock starts at 10 spaces]",
  553. "",
  554. " [comment text indented by 5 spaces no longer belong to list]");
  555. // should consider tab as 4 spaces
  556. MT("listCommonMark_TabIndented",
  557. "[variable-2 * list]",
  558. "\t[variable-3 * list2]",
  559. "",
  560. "\t\t[variable-3 part of list2]");
  561. MT("listAfterBlockquote",
  562. "[quote&quote-1 > foo]",
  563. "[variable-2 - bar]");
  564. // shouldn't create sublist if it's indented more than allowed
  565. MT("nestedListIndentedTooMuch",
  566. "[variable-2 - foo]",
  567. " [variable-2 - bar]");
  568. MT("listIndentedTooMuchAfterParagraph",
  569. "foo",
  570. " - bar");
  571. // Blockquote
  572. MT("blockquote",
  573. "[variable-2 * foo]",
  574. "",
  575. "[variable-2 * bar]",
  576. "",
  577. " [variable-2&quote&quote-1 > hello]");
  578. // Code block
  579. MT("blockquoteCode",
  580. "[variable-2 * foo]",
  581. "",
  582. "[variable-2 * bar]",
  583. "",
  584. " [comment > hello]",
  585. "",
  586. " [variable-2 world]");
  587. // Code block followed by text
  588. MT("blockquoteCodeText",
  589. "[variable-2 * foo]",
  590. "",
  591. " [variable-2 bar]",
  592. "",
  593. " [comment hello]",
  594. "",
  595. " [variable-2 world]");
  596. // Nested list
  597. MT("listAsteriskNested",
  598. "[variable-2 * foo]",
  599. "",
  600. " [variable-3 * bar]");
  601. MT("listPlusNested",
  602. "[variable-2 + foo]",
  603. "",
  604. " [variable-3 + bar]");
  605. MT("listDashNested",
  606. "[variable-2 - foo]",
  607. "",
  608. " [variable-3 - bar]");
  609. MT("listNumberNested",
  610. "[variable-2 1. foo]",
  611. "",
  612. " [variable-3 2. bar]");
  613. MT("listMixed",
  614. "[variable-2 * foo]",
  615. "",
  616. " [variable-3 + bar]",
  617. "",
  618. " [keyword - hello]",
  619. "",
  620. " [variable-2 1. world]");
  621. MT("listBlockquote",
  622. "[variable-2 * foo]",
  623. "",
  624. " [variable-3 + bar]",
  625. "",
  626. " [quote&quote-1&variable-3 > hello]");
  627. MT("listCode",
  628. "[variable-2 * foo]",
  629. "",
  630. " [variable-3 + bar]",
  631. "",
  632. " [comment hello]");
  633. // Code with internal indentation
  634. MT("listCodeIndentation",
  635. "[variable-2 * foo]",
  636. "",
  637. " [comment bar]",
  638. " [comment hello]",
  639. " [comment world]",
  640. " [comment foo]",
  641. " [variable-2 bar]");
  642. // List nesting edge cases
  643. MT("listNested",
  644. "[variable-2 * foo]",
  645. "",
  646. " [variable-3 * bar]",
  647. "",
  648. " [variable-3 hello]"
  649. );
  650. MT("listNested",
  651. "[variable-2 * foo]",
  652. "",
  653. " [variable-3 * bar]",
  654. "",
  655. " [keyword * foo]"
  656. );
  657. // Code followed by text
  658. MT("listCodeText",
  659. "[variable-2 * foo]",
  660. "",
  661. " [comment bar]",
  662. "",
  663. "hello");
  664. // Following tests directly from official Markdown documentation
  665. // http://daringfireball.net/projects/markdown/syntax#hr
  666. MT("hrSpace",
  667. "[hr * * *]");
  668. MT("hr",
  669. "[hr ***]");
  670. MT("hrLong",
  671. "[hr *****]");
  672. MT("hrSpaceDash",
  673. "[hr - - -]");
  674. MT("hrDashLong",
  675. "[hr ---------------------------------------]");
  676. //Images
  677. MT("Images",
  678. "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)]")
  679. //Images with highlight alt text
  680. MT("imageEm",
  681. "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&em&image&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
  682. MT("imageStrong",
  683. "[image&image-marker !][image&image-alt-text&link [[][image-alt-text&strong&image&link **alt text**][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
  684. MT("imageEmStrong",
  685. "[image&image-marker !][image&image-alt-text&link [[][image&image-alt-text&em&strong&link ***alt text***][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)]");
  686. // Inline link with title
  687. MT("linkTitle",
  688. "[link [[foo]]][string&url (http://example.com/ \"bar\")] hello");
  689. // Inline link without title
  690. MT("linkNoTitle",
  691. "[link [[foo]]][string&url (http://example.com/)] bar");
  692. // Inline link with image
  693. MT("linkImage",
  694. "[link [[][link&image&image-marker !][link&image&image-alt-text&link [[alt text]]][string&url (http://link.to/image.jpg)][link ]]][string&url (http://example.com/)] bar");
  695. // Inline link with Em
  696. MT("linkEm",
  697. "[link [[][link&em *foo*][link ]]][string&url (http://example.com/)] bar");
  698. // Inline link with Strong
  699. MT("linkStrong",
  700. "[link [[][link&strong **foo**][link ]]][string&url (http://example.com/)] bar");
  701. // Inline link with EmStrong
  702. MT("linkEmStrong",
  703. "[link [[][link&em&strong ***foo***][link ]]][string&url (http://example.com/)] bar");
  704. MT("multilineLink",
  705. "[link [[foo]",
  706. "[link bar]]][string&url (https://foo#_a)]",
  707. "should not be italics")
  708. // Image with title
  709. MT("imageTitle",
  710. "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/ \"bar\")] hello");
  711. // Image without title
  712. MT("imageNoTitle",
  713. "[image&image-marker !][image&image-alt-text&link [[alt text]]][string&url (http://example.com/)] bar");
  714. // Image with asterisks
  715. MT("imageAsterisks",
  716. "[image&image-marker !][image&image-alt-text&link [[ ][image&image-alt-text&em&link *alt text*][image&image-alt-text&link ]]][string&url (http://link.to/image.jpg)] bar");
  717. // Not a link. Should be normal text due to square brackets being used
  718. // regularly in text, especially in quoted material, and no space is allowed
  719. // between square brackets and parentheses (per Dingus).
  720. MT("notALink",
  721. "[link [[foo]]] (bar)");
  722. // Reference-style links
  723. MT("linkReference",
  724. "[link [[foo]]][string&url [[bar]]] hello");
  725. // Reference-style links with Em
  726. MT("linkReferenceEm",
  727. "[link [[][link&em *foo*][link ]]][string&url [[bar]]] hello");
  728. // Reference-style links with Strong
  729. MT("linkReferenceStrong",
  730. "[link [[][link&strong **foo**][link ]]][string&url [[bar]]] hello");
  731. // Reference-style links with EmStrong
  732. MT("linkReferenceEmStrong",
  733. "[link [[][link&em&strong ***foo***][link ]]][string&url [[bar]]] hello");
  734. // Reference-style links with optional space separator (per documentation)
  735. // "You can optionally use a space to separate the sets of brackets"
  736. MT("linkReferenceSpace",
  737. "[link [[foo]]] [string&url [[bar]]] hello");
  738. // Should only allow a single space ("...use *a* space...")
  739. MT("linkReferenceDoubleSpace",
  740. "[link [[foo]]] [link [[bar]]] hello");
  741. // Reference-style links with implicit link name
  742. MT("linkImplicit",
  743. "[link [[foo]]][string&url [[]]] hello");
  744. // @todo It would be nice if, at some point, the document was actually
  745. // checked to see if the referenced link exists
  746. // Link label, for reference-style links (taken from documentation)
  747. MT("labelNoTitle",
  748. "[link [[foo]]:] [string&url http://example.com/]");
  749. MT("labelIndented",
  750. " [link [[foo]]:] [string&url http://example.com/]");
  751. MT("labelSpaceTitle",
  752. "[link [[foo bar]]:] [string&url http://example.com/ \"hello\"]");
  753. MT("labelDoubleTitle",
  754. "[link [[foo bar]]:] [string&url http://example.com/ \"hello\"] \"world\"");
  755. MT("labelTitleDoubleQuotes",
  756. "[link [[foo]]:] [string&url http://example.com/ \"bar\"]");
  757. MT("labelTitleSingleQuotes",
  758. "[link [[foo]]:] [string&url http://example.com/ 'bar']");
  759. MT("labelTitleParentheses",
  760. "[link [[foo]]:] [string&url http://example.com/ (bar)]");
  761. MT("labelTitleInvalid",
  762. "[link [[foo]]:] [string&url http://example.com/] bar");
  763. MT("labelLinkAngleBrackets",
  764. "[link [[foo]]:] [string&url <http://example.com/> \"bar\"]");
  765. MT("labelTitleNextDoubleQuotes",
  766. "[link [[foo]]:] [string&url http://example.com/]",
  767. "[string \"bar\"] hello");
  768. MT("labelTitleNextSingleQuotes",
  769. "[link [[foo]]:] [string&url http://example.com/]",
  770. "[string 'bar'] hello");
  771. MT("labelTitleNextParentheses",
  772. "[link [[foo]]:] [string&url http://example.com/]",
  773. "[string (bar)] hello");
  774. MT("labelTitleNextMixed",
  775. "[link [[foo]]:] [string&url http://example.com/]",
  776. "(bar\" hello");
  777. MT("labelEscape",
  778. "[link [[foo \\]] ]]:] [string&url http://example.com/]");
  779. MT("labelEscapeColon",
  780. "[link [[foo \\]]: bar]]:] [string&url http://example.com/]");
  781. MT("labelEscapeEnd",
  782. "\\[[foo\\]]: http://example.com/");
  783. MT("linkWeb",
  784. "[link <http://example.com/>] foo");
  785. MT("linkWebDouble",
  786. "[link <http://example.com/>] foo [link <http://example.com/>]");
  787. MT("linkEmail",
  788. "[link <user@example.com>] foo");
  789. MT("linkEmailDouble",
  790. "[link <user@example.com>] foo [link <user@example.com>]");
  791. MT("emAsterisk",
  792. "[em *foo*] bar");
  793. MT("emUnderscore",
  794. "[em _foo_] bar");
  795. MT("emInWordAsterisk",
  796. "foo[em *bar*]hello");
  797. MT("emInWordUnderscore",
  798. "foo_bar_hello");
  799. // Per documentation: "...surround an * or _ with spaces, it’ll be
  800. // treated as a literal asterisk or underscore."
  801. MT("emEscapedBySpaceIn",
  802. "foo [em _bar _ hello_] world");
  803. MT("emEscapedBySpaceOut",
  804. "foo _ bar [em _hello_] world");
  805. MT("emEscapedByNewline",
  806. "foo",
  807. "_ bar [em _hello_] world");
  808. // Unclosed emphasis characters
  809. // Instead of simply marking as EM / STRONG, it would be nice to have an
  810. // incomplete flag for EM and STRONG, that is styled slightly different.
  811. MT("emIncompleteAsterisk",
  812. "foo [em *bar]");
  813. MT("emIncompleteUnderscore",
  814. "foo [em _bar]");
  815. MT("strongAsterisk",
  816. "[strong **foo**] bar");
  817. MT("strongUnderscore",
  818. "[strong __foo__] bar");
  819. MT("emStrongAsterisk",
  820. "[em *foo][em&strong **bar*][strong hello**] world");
  821. MT("emStrongUnderscore",
  822. "[em _foo ][em&strong __bar_][strong hello__] world");
  823. // "...same character must be used to open and close an emphasis span.""
  824. MT("emStrongMixed",
  825. "[em _foo][em&strong **bar*hello__ world]");
  826. MT("emStrongMixed",
  827. "[em *foo ][em&strong __bar_hello** world]");
  828. MT("linkWithNestedParens",
  829. "[link [[foo]]][string&url (bar(baz))]")
  830. // These characters should be escaped:
  831. // \ backslash
  832. // ` backtick
  833. // * asterisk
  834. // _ underscore
  835. // {} curly braces
  836. // [] square brackets
  837. // () parentheses
  838. // # hash mark
  839. // + plus sign
  840. // - minus sign (hyphen)
  841. // . dot
  842. // ! exclamation mark
  843. MT("escapeBacktick",
  844. "foo \\`bar\\`");
  845. MT("doubleEscapeBacktick",
  846. "foo \\\\[comment `bar\\\\`]");
  847. MT("escapeAsterisk",
  848. "foo \\*bar\\*");
  849. MT("doubleEscapeAsterisk",
  850. "foo \\\\[em *bar\\\\*]");
  851. MT("escapeUnderscore",
  852. "foo \\_bar\\_");
  853. MT("doubleEscapeUnderscore",
  854. "foo \\\\[em _bar\\\\_]");
  855. MT("escapeHash",
  856. "\\# foo");
  857. MT("doubleEscapeHash",
  858. "\\\\# foo");
  859. MT("escapeNewline",
  860. "\\",
  861. "[em *foo*]");
  862. // Class override tests
  863. TokenTypeOverrideTest("overrideHeader1",
  864. "[override-header&override-header-1 # Foo]");
  865. TokenTypeOverrideTest("overrideHeader2",
  866. "[override-header&override-header-2 ## Foo]");
  867. TokenTypeOverrideTest("overrideHeader3",
  868. "[override-header&override-header-3 ### Foo]");
  869. TokenTypeOverrideTest("overrideHeader4",
  870. "[override-header&override-header-4 #### Foo]");
  871. TokenTypeOverrideTest("overrideHeader5",
  872. "[override-header&override-header-5 ##### Foo]");
  873. TokenTypeOverrideTest("overrideHeader6",
  874. "[override-header&override-header-6 ###### Foo]");
  875. TokenTypeOverrideTest("overrideCode",
  876. "[override-code `foo`]");
  877. TokenTypeOverrideTest("overrideCodeBlock",
  878. "[override-code ```]",
  879. "[override-code foo]",
  880. "[override-code ```]");
  881. TokenTypeOverrideTest("overrideQuote",
  882. "[override-quote&override-quote-1 > foo]",
  883. "[override-quote&override-quote-1 > bar]");
  884. TokenTypeOverrideTest("overrideQuoteNested",
  885. "[override-quote&override-quote-1 > foo]",
  886. "[override-quote&override-quote-1 >][override-quote&override-quote-2 > bar]",
  887. "[override-quote&override-quote-1 >][override-quote&override-quote-2 >][override-quote&override-quote-3 > baz]");
  888. TokenTypeOverrideTest("overrideLists",
  889. "[override-list1 - foo]",
  890. "",
  891. " [override-list2 + bar]",
  892. "",
  893. " [override-list3 * baz]",
  894. "",
  895. " [override-list1 1. qux]",
  896. "",
  897. " [override-list2 - quux]");
  898. TokenTypeOverrideTest("overrideHr",
  899. "[override-hr * * *]");
  900. TokenTypeOverrideTest("overrideImage",
  901. "[override-image&override-image-marker !][override-image&override-image-alt-text&link [[alt text]]][override-link-href&url (http://link.to/image.jpg)]");
  902. TokenTypeOverrideTest("overrideLinkText",
  903. "[override-link-text [[foo]]][override-link-href&url (http://example.com)]");
  904. TokenTypeOverrideTest("overrideLinkEmailAndInline",
  905. "[override-link-email <][override-link-inline foo@example.com>]");
  906. TokenTypeOverrideTest("overrideEm",
  907. "[override-em *foo*]");
  908. TokenTypeOverrideTest("overrideStrong",
  909. "[override-strong **foo**]");
  910. TokenTypeOverrideTest("overrideStrikethrough",
  911. "[override-strikethrough ~~foo~~]");
  912. TokenTypeOverrideTest("overrideEmoji",
  913. "[override-emoji :foo:]");
  914. FormatTokenTypeOverrideTest("overrideFormatting",
  915. "[override-formatting-escape \\*]");
  916. // Tests to make sure GFM-specific things aren't getting through
  917. MT("taskList",
  918. "[variable-2 * ][link&variable-2 [[ ]]][variable-2 bar]");
  919. MT("fencedCodeBlocks",
  920. "[comment ```]",
  921. "[comment foo]",
  922. "",
  923. "[comment bar]",
  924. "[comment ```]",
  925. "baz");
  926. MT("fencedCodeBlocks_invalidClosingFence_trailingText",
  927. "[comment ```]",
  928. "[comment foo]",
  929. "[comment ``` must not have trailing text]",
  930. "[comment baz]");
  931. MT("fencedCodeBlocks_invalidClosingFence_trailingTabs",
  932. "[comment ```]",
  933. "[comment foo]",
  934. "[comment ```\t]",
  935. "[comment baz]");
  936. MT("fencedCodeBlocks_validClosingFence",
  937. "[comment ```]",
  938. "[comment foo]",
  939. // may have trailing spaces
  940. "[comment ``` ]",
  941. "baz");
  942. MT("fencedCodeBlocksInList_closingFenceIndented",
  943. "[variable-2 - list]",
  944. " [variable-2&comment ```]",
  945. " [comment foo]",
  946. " [variable-2&comment ```]",
  947. " [variable-2 baz]");
  948. MT("fencedCodeBlocksInList_closingFenceIndentedTooMuch",
  949. "[variable-2 - list]",
  950. " [variable-2&comment ```]",
  951. " [comment foo]",
  952. " [comment ```]",
  953. " [comment baz]");
  954. MT("fencedCodeBlockModeSwitching",
  955. "[comment ```javascript]",
  956. "[variable foo]",
  957. "",
  958. "[comment ```]",
  959. "bar");
  960. MT_noFencedHighlight("fencedCodeBlock_noHighlight",
  961. "[comment ```javascript]",
  962. "[comment foo]",
  963. "[comment ```]");
  964. MT("fencedCodeBlockModeSwitchingObjc",
  965. "[comment ```objective-c]",
  966. "[keyword @property] [variable NSString] [operator *] [variable foo];",
  967. "[comment ```]",
  968. "bar");
  969. MT("fencedCodeBlocksMultipleChars",
  970. "[comment `````]",
  971. "[comment foo]",
  972. "[comment ```]",
  973. "[comment foo]",
  974. "[comment `````]",
  975. "bar");
  976. MT("fencedCodeBlocksTildes",
  977. "[comment ~~~]",
  978. "[comment foo]",
  979. "[comment ~~~]",
  980. "bar");
  981. MT("fencedCodeBlocksTildesMultipleChars",
  982. "[comment ~~~~~]",
  983. "[comment ~~~]",
  984. "[comment foo]",
  985. "[comment ~~~~~]",
  986. "bar");
  987. MT("fencedCodeBlocksMultipleChars",
  988. "[comment `````]",
  989. "[comment foo]",
  990. "[comment ```]",
  991. "[comment foo]",
  992. "[comment `````]",
  993. "bar");
  994. MT("fencedCodeBlocksMixed",
  995. "[comment ~~~]",
  996. "[comment ```]",
  997. "[comment foo]",
  998. "[comment ~~~]",
  999. "bar");
  1000. MT("fencedCodeBlocksAfterBlockquote",
  1001. "[quote&quote-1 > foo]",
  1002. "[comment ```]",
  1003. "[comment bar]",
  1004. "[comment ```]");
  1005. // fencedCode indented too much should act as simple indentedCode
  1006. // (hence has no highlight formatting)
  1007. FT("tooMuchIndentedFencedCode",
  1008. " [comment ```]",
  1009. " [comment code]",
  1010. " [comment ```]");
  1011. MT("autoTerminateFencedCodeWhenLeavingList",
  1012. "[variable-2 - list1]",
  1013. " [variable-3 - list2]",
  1014. " [variable-3&comment ```]",
  1015. " [comment code]",
  1016. " [variable-3 - list2]",
  1017. " [variable-2&comment ```]",
  1018. " [comment code]",
  1019. "[quote&quote-1 > foo]");
  1020. // Tests that require XML mode
  1021. MT("xmlMode",
  1022. "[tag&bracket <][tag div][tag&bracket >]",
  1023. " *foo*",
  1024. " [tag&bracket <][tag http://github.com][tag&bracket />]",
  1025. "[tag&bracket </][tag div][tag&bracket >]",
  1026. "[link <http://github.com/>]");
  1027. MT("xmlModeWithMarkdownInside",
  1028. "[tag&bracket <][tag div] [attribute markdown]=[string 1][tag&bracket >]",
  1029. "[em *foo*]",
  1030. "[link <http://github.com/>]",
  1031. "[tag </div>]",
  1032. "[link <http://github.com/>]",
  1033. "[tag&bracket <][tag div][tag&bracket >]",
  1034. "[tag&bracket </][tag div][tag&bracket >]");
  1035. MT("xmlModeLineBreakInTags",
  1036. "[tag&bracket <][tag div] [attribute id]=[string \"1\"]",
  1037. " [attribute class]=[string \"sth\"][tag&bracket >]xxx",
  1038. "[tag&bracket </][tag div][tag&bracket >]");
  1039. MT("xmlModeCommentWithBlankLine",
  1040. "[comment <!-- Hello]",
  1041. "",
  1042. "[comment World -->]");
  1043. MT("xmlModeCDATA",
  1044. "[atom <![CDATA[ Hello]",
  1045. "",
  1046. "[atom FooBar]",
  1047. "[atom Test ]]]]>]");
  1048. MT("xmlModePreprocessor",
  1049. "[meta <?php] [meta echo '1234'; ?>]");
  1050. MT_noXml("xmlHighlightDisabled",
  1051. "<div>foo</div>");
  1052. // Tests Emojis
  1053. ET("emojiDefault",
  1054. "[builtin :foobar:]");
  1055. ET("emojiTable",
  1056. " :--:");
  1057. })();