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