openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

test.js (38035B)


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