172b2703bSAndreas Gohr<?php 272b2703bSAndreas Gohr 372b2703bSAndreas Gohr/** 472b2703bSAndreas Gohr * GFM spec examples that GfmSpecTest should skip, keyed by example number 572b2703bSAndreas Gohr * (as numbered in spec.txt / the rendered spec). 672b2703bSAndreas Gohr * 772b2703bSAndreas Gohr * Add entries here ONLY for behavior DokuWiki has explicitly decided not to 872b2703bSAndreas Gohr * implement — not for features that are merely pending. Unimplemented 972b2703bSAndreas Gohr * features should show as real failures so they remain visible TODOs on 1072b2703bSAndreas Gohr * the branch. 1172b2703bSAndreas Gohr * 1272b2703bSAndreas Gohr * Each value is a short human-readable reason that will appear in phpunit's 1372b2703bSAndreas Gohr * skip output. 1472b2703bSAndreas Gohr */ 1572b2703bSAndreas Gohr 1672b2703bSAndreas Gohrreturn [ 1772b2703bSAndreas Gohr // -------------------------------------------------------------------- 188ed75a23SAndreas Gohr // Code-span edge cases that collide with project-wide decisions 198ed75a23SAndreas Gohr // (no raw HTML, no GFM angle-bracket autolinks, typography on by 208ed75a23SAndreas Gohr // default) or with the single-pass lexer's limits. 218ed75a23SAndreas Gohr // -------------------------------------------------------------------- 228ed75a23SAndreas Gohr 351 => 'code span vs. emphasis: cross-positional precedence would require' 238ed75a23SAndreas Gohr . ' a pre-scan pass — the single-pass lexer matches leftmost-first' 248ed75a23SAndreas Gohr . ' and cannot reject an earlier emphasis opener because a later' 258ed75a23SAndreas Gohr . ' backtick span would consume its closer', 268ed75a23SAndreas Gohr 353 => 'code span: the trailing `"` outside the span is converted to a' 278ed75a23SAndreas Gohr . ' curly quote by DokuWiki typography, diverging from the spec HTML', 288ed75a23SAndreas Gohr 354 => 'raw HTML tag pass-through: DokuWiki does not render raw HTML by' 298ed75a23SAndreas Gohr . ' default; `<html>` blocks are the opt-in', 308ed75a23SAndreas Gohr 356 => 'GFM angle-bracket autolink `<http://…>`: not implemented — we' 318ed75a23SAndreas Gohr . ' rely on DokuWiki\'s existing bare-URL detection, which does not' 328ed75a23SAndreas Gohr . ' parse `<URL>` form', 338ed75a23SAndreas Gohr 348ed75a23SAndreas Gohr // -------------------------------------------------------------------- 3572b2703bSAndreas Gohr // CommonMark §6.2 flanking-delimiter analysis — deliberately not 3672b2703bSAndreas Gohr // implemented. DokuWiki's regex lexer uses leftmost-match and cannot 3772b2703bSAndreas Gohr // apply CommonMark's left/right-flanking rules that distinguish 3872b2703bSAndreas Gohr // word-chars, whitespace, and punctuation for `*`/`_` delimiters, or 3972b2703bSAndreas Gohr // the "multiple-of-3" rule for overlapping runs. These examples all 4072b2703bSAndreas Gohr // rely on that machinery. 4172b2703bSAndreas Gohr // -------------------------------------------------------------------- 4272b2703bSAndreas Gohr 4372b2703bSAndreas Gohr // Unicode whitespace in flanking context. Our `\s` is ASCII-only 4472b2703bSAndreas Gohr // because the lexer doesn't set the PCRE `u` flag. 4572b2703bSAndreas Gohr 363 => 'Unicode whitespace (U+00A0) flanking — requires u-flag-aware regex', 4672b2703bSAndreas Gohr 4772b2703bSAndreas Gohr // Punctuation-adjacent flanking for `*` / `_` / `**` / `__` 4872b2703bSAndreas Gohr 362 => 'flanking: punctuation-adjacent `*` (left-flanking vs. right-flanking)', 4972b2703bSAndreas Gohr 368 => 'flanking: punctuation-adjacent `_`', 5072b2703bSAndreas Gohr 372 => 'flanking: intraword `_` with punctuation inside', 5172b2703bSAndreas Gohr 377 => 'flanking: `*` followed by `(` requires punctuation-aware flanking', 5272b2703bSAndreas Gohr 378 => 'flanking: nested `*(*foo*)*` requires flanking + balanced-pair analysis', 5372b2703bSAndreas Gohr 382 => 'flanking: nested `_(_foo_)_` requires flanking + balanced-pair analysis', 5472b2703bSAndreas Gohr 389 => 'flanking: punctuation-adjacent `**`', 5572b2703bSAndreas Gohr 394 => 'flanking: punctuation-adjacent `__`', 5672b2703bSAndreas Gohr 401 => 'flanking: `**` followed by `(`', 5772b2703bSAndreas Gohr 404 => 'flanking: nested `*bar*` inside `**foo ... foo**` with punctuation', 5872b2703bSAndreas Gohr 407 => 'flanking: `__` followed by `(`', 5972b2703bSAndreas Gohr 470 => 'flanking: nested `*_foo_*` requires balanced-pair analysis', 6072b2703bSAndreas Gohr 472 => 'flanking: nested `_*foo*_` requires balanced-pair analysis', 6172b2703bSAndreas Gohr 6272b2703bSAndreas Gohr // Intraword `__` strong (even multibyte) — flanking rule for `_` requires 6372b2703bSAndreas Gohr // examining whether the delimiter run is word-boundary-flanking, which our 6472b2703bSAndreas Gohr // simple lookbehind/lookahead approximation doesn't fully match. 6572b2703bSAndreas Gohr 395 => 'flanking: intraword `__` (`foo__bar__`) — left-flanking vs right-flanking', 6672b2703bSAndreas Gohr 396 => 'flanking: intraword `__` across digits (`5__6__78`)', 6772b2703bSAndreas Gohr 397 => 'flanking: intraword `__` with Cyrillic', 6872b2703bSAndreas Gohr 398 => 'flanking: `__foo, __bar__, baz__` — flanking + balanced pairing', 6972b2703bSAndreas Gohr 409 => 'flanking: `__foo__bar` — intraword close', 7072b2703bSAndreas Gohr 410 => 'flanking: intraword `__` with Cyrillic (leading)', 7172b2703bSAndreas Gohr 411 => 'flanking: `__foo__bar__baz__` — multiple `__` pairs with flanking', 7272b2703bSAndreas Gohr 412 => 'flanking: `__(bar)__.` — punctuation-adjacent', 7372b2703bSAndreas Gohr 7472b2703bSAndreas Gohr // Overlapping / multiple-of-3 rule for runs 7572b2703bSAndreas Gohr 416 => 'CommonMark rule 9 (overlapping same-delimiter `_foo _bar_ baz_`)', 7672b2703bSAndreas Gohr 417 => 'CommonMark overlapping `_` / `__` with flanking', 7772b2703bSAndreas Gohr 418 => 'CommonMark overlapping `*foo *bar**` — multiple-of-3 rule', 7872b2703bSAndreas Gohr 419 => 'CommonMark nested `*foo **bar** baz*` — balanced-pair analysis', 7972b2703bSAndreas Gohr 421 => 'CommonMark overlapping `*foo**bar*` — multiple-of-3', 8072b2703bSAndreas Gohr 422 => 'CommonMark nested `***foo** bar*` — triple-delimiter analysis', 8172b2703bSAndreas Gohr 423 => 'CommonMark nested `*foo **bar***` — triple-delimiter analysis', 8272b2703bSAndreas Gohr 424 => 'CommonMark nested `*foo**bar***` — triple-delimiter analysis', 8372b2703bSAndreas Gohr 425 => 'CommonMark triple `foo***bar***baz` — triple-delimiter analysis', 8472b2703bSAndreas Gohr 426 => 'CommonMark long delimiter runs `foo******bar*********baz`', 8572b2703bSAndreas Gohr 427 => 'CommonMark deeply nested `*foo **bar *baz* bim** bop*`', 8672b2703bSAndreas Gohr 434 => 'CommonMark overlapping `__foo __bar__ baz__` — multiple-of-3', 8772b2703bSAndreas Gohr 435 => 'CommonMark `____foo__ bar__` — leading long delimiter run', 8872b2703bSAndreas Gohr 436 => 'CommonMark `**foo **bar****` — trailing long delimiter run', 8972b2703bSAndreas Gohr 439 => 'CommonMark nested `***foo* bar**` — triple-delimiter', 9072b2703bSAndreas Gohr 440 => 'CommonMark nested `**foo *bar***` — triple-delimiter', 9172b2703bSAndreas Gohr 441 => 'CommonMark deeply nested `**foo *bar **baz** bim* bop**`', 9272b2703bSAndreas Gohr 9372b2703bSAndreas Gohr // `__foo_` / `_foo__` — mixing `_` and `__` requires flanking to decide 9472b2703bSAndreas Gohr // which delimiter pairs open/close. 9572b2703bSAndreas Gohr 463 => 'flanking: `__foo_` — mixed `_`/`__` pairing', 9672b2703bSAndreas Gohr 464 => 'flanking: `_foo__` — mixed `_`/`__` pairing', 9772b2703bSAndreas Gohr 465 => 'flanking: `___foo__` — delimiter-run length analysis', 9872b2703bSAndreas Gohr 466 => 'flanking: `____foo_` — delimiter-run length analysis', 9972b2703bSAndreas Gohr 467 => 'flanking: `__foo___` — delimiter-run length analysis', 10072b2703bSAndreas Gohr 468 => 'flanking: `_foo____` — delimiter-run length analysis', 10172b2703bSAndreas Gohr 10272b2703bSAndreas Gohr // Long delimiter runs require excess-drop logic (2 outer chars dropped 10372b2703bSAndreas Gohr // from each side). Stack-based pairing needed — out of scope. 10472b2703bSAndreas Gohr 473 => 'CommonMark `****foo****` — excess-drop (4+4 → strong only)', 10572b2703bSAndreas Gohr 474 => 'CommonMark `____foo____` — excess-drop (4+4 → strong only)', 10672b2703bSAndreas Gohr 475 => 'CommonMark `******foo******` — excess-drop (6+6 → strong only)', 10772b2703bSAndreas Gohr 477 => 'CommonMark `_____foo_____` — excess-drop (5+5 → em+strong, 2 dropped each side)', 10872b2703bSAndreas Gohr 10972b2703bSAndreas Gohr // Overlapping / crossing delimiters 11072b2703bSAndreas Gohr 478 => 'CommonMark `*foo _bar* baz_` — overlapping different delimiters', 11172b2703bSAndreas Gohr 479 => 'CommonMark `*foo __bar *baz bim__ bam*` — crossing delimiters', 11272b2703bSAndreas Gohr 480 => 'CommonMark `**foo **bar baz**` — overlapping same delimiter', 1138719732dSAndreas Gohr 1148719732dSAndreas Gohr // -------------------------------------------------------------------- 115*e89aeebdSAndreas Gohr // Inline link `[text](url)` — features GfmLink deliberately does not 116*e89aeebdSAndreas Gohr // implement. Either rarely-used syntax paid for with disproportionate 117*e89aeebdSAndreas Gohr // regex complexity, or single-pass-lexer limits that can't be worked 118*e89aeebdSAndreas Gohr // around inside one mode. 119*e89aeebdSAndreas Gohr // -------------------------------------------------------------------- 120*e89aeebdSAndreas Gohr 121*e89aeebdSAndreas Gohr // GFM link title attribute (`"title"` / `'title'` / `(title)` after 122*e89aeebdSAndreas Gohr // the URL). Parses cleanly but is discarded: DokuWiki's link handler 123*e89aeebdSAndreas Gohr // instructions have no title-attribute slot, and plumbing one through 124*e89aeebdSAndreas Gohr // every renderer is out of scope for GfmLink. 125*e89aeebdSAndreas Gohr 493 => 'link title attribute: GfmLink parses but discards — DokuWiki link instructions have no title slot', 126*e89aeebdSAndreas Gohr 513 => 'link title attribute (three quoting styles): discarded by GfmLink', 127*e89aeebdSAndreas Gohr 515 => 'link title separated by non-breaking space: title slot not supported', 128*e89aeebdSAndreas Gohr 516 => 'link title with nested balanced quotes: Markdown.pl quirk, not supported', 129*e89aeebdSAndreas Gohr 517 => 'link title with different quote type for inner quotes: title slot not supported', 130*e89aeebdSAndreas Gohr 518 => 'multi-line link title: title slot not supported', 131*e89aeebdSAndreas Gohr 132*e89aeebdSAndreas Gohr // Pointy-bracket link destinations `<...>`. Rarely used; regex cost 133*e89aeebdSAndreas Gohr // and interaction with raw-HTML detection outweigh the benefit. 134*e89aeebdSAndreas Gohr 496 => 'pointy-bracket link destination `<>`: not supported', 135*e89aeebdSAndreas Gohr 498 => 'pointy-bracket destination with spaces `<...>`: not supported', 136*e89aeebdSAndreas Gohr 500 => 'pointy-bracket destination with newline: not supported', 137*e89aeebdSAndreas Gohr 501 => 'pointy-bracket destination containing `)`: not supported', 138*e89aeebdSAndreas Gohr 502 => 'pointy-bracket destination with trailing backslash: not supported', 139*e89aeebdSAndreas Gohr 503 => 'malformed pointy-bracket destinations: renderer output differs', 140*e89aeebdSAndreas Gohr 507 => 'pointy-bracket destination wrapping unbalanced parens: not supported', 141*e89aeebdSAndreas Gohr 142*e89aeebdSAndreas Gohr // Balanced-parens inside URL destinations. 143*e89aeebdSAndreas Gohr 505 => 'balanced-parens in URL destination: not supported (regex single-level)', 144*e89aeebdSAndreas Gohr 145*e89aeebdSAndreas Gohr // Other URL-level edges. 146*e89aeebdSAndreas Gohr 495 => 'empty URL destination `[link]()`: pattern requires non-empty URL', 147*e89aeebdSAndreas Gohr 510 => 'backslash in URL destination: URL-encoding differs from spec', 148*e89aeebdSAndreas Gohr 511 => 'HTML entity / percent-encoding in URL: renderer normalization differs', 149*e89aeebdSAndreas Gohr 512 => 'link destination that parses as a title: edge case not supported', 150*e89aeebdSAndreas Gohr 151*e89aeebdSAndreas Gohr // Inherent single-pass-lexer limits for link text containing nested 152*e89aeebdSAndreas Gohr // structures. These cannot be resolved inside one mode. 153*e89aeebdSAndreas Gohr 522 => 'nested bracket forms inner link, outer falls back to literal', 154*e89aeebdSAndreas Gohr 526 => 'nested links: inner is a link, outer falls back to literal', 155*e89aeebdSAndreas Gohr 527 => 'nested links inside emphasis: not supported', 156*e89aeebdSAndreas Gohr 529 => 'link text grouping vs. emphasis: leftmost-match cannot override', 157*e89aeebdSAndreas Gohr 530 => 'emphasis/bracket crossing: leftmost-match cannot override', 158*e89aeebdSAndreas Gohr 532 => 'raw HTML inside link text: project-wide "no raw HTML" limit', 159*e89aeebdSAndreas Gohr 533 => 'code span inside link text: requires pre-scan pass (see #351)', 160*e89aeebdSAndreas Gohr 534 => 'autolink inside link text: raw `<URL>` autolinks not supported (see #356)', 161*e89aeebdSAndreas Gohr 162*e89aeebdSAndreas Gohr // Reference links (`[text][id]`, `[text][]`, `[foo]` with matching 163*e89aeebdSAndreas Gohr // `[foo]: url` definition). Not implemented: resolving forward 164*e89aeebdSAndreas Gohr // references would require a two-pass parse, but DokuWiki's lexer is 165*e89aeebdSAndreas Gohr // single-pass. Inline links `[text](url)` are the only supported 166*e89aeebdSAndreas Gohr // form. 167*e89aeebdSAndreas Gohr 535 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 168*e89aeebdSAndreas Gohr 536 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 169*e89aeebdSAndreas Gohr 537 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 170*e89aeebdSAndreas Gohr 538 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 171*e89aeebdSAndreas Gohr 539 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 172*e89aeebdSAndreas Gohr 540 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 173*e89aeebdSAndreas Gohr 541 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 174*e89aeebdSAndreas Gohr 542 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 175*e89aeebdSAndreas Gohr 543 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 176*e89aeebdSAndreas Gohr 544 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 177*e89aeebdSAndreas Gohr 545 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 178*e89aeebdSAndreas Gohr 546 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 179*e89aeebdSAndreas Gohr 547 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 180*e89aeebdSAndreas Gohr 548 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 181*e89aeebdSAndreas Gohr 549 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 182*e89aeebdSAndreas Gohr 550 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 183*e89aeebdSAndreas Gohr 551 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 184*e89aeebdSAndreas Gohr 552 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 185*e89aeebdSAndreas Gohr 553 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 186*e89aeebdSAndreas Gohr 557 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 187*e89aeebdSAndreas Gohr 558 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 188*e89aeebdSAndreas Gohr 560 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 189*e89aeebdSAndreas Gohr 561 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)', 190*e89aeebdSAndreas Gohr 562 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)', 191*e89aeebdSAndreas Gohr 563 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)', 192*e89aeebdSAndreas Gohr 564 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)', 193*e89aeebdSAndreas Gohr 565 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 194*e89aeebdSAndreas Gohr 566 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 195*e89aeebdSAndreas Gohr 567 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 196*e89aeebdSAndreas Gohr 568 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 197*e89aeebdSAndreas Gohr 569 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 198*e89aeebdSAndreas Gohr 570 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 199*e89aeebdSAndreas Gohr 571 => 'shortcut reference link with escape: forward-reference definitions not supported (single-pass lexer)', 200*e89aeebdSAndreas Gohr 572 => 'shortcut reference link with emphasis: forward-reference definitions not supported (single-pass lexer)', 201*e89aeebdSAndreas Gohr 573 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 202*e89aeebdSAndreas Gohr 574 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 203*e89aeebdSAndreas Gohr 575 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 204*e89aeebdSAndreas Gohr 576 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 205*e89aeebdSAndreas Gohr 577 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 206*e89aeebdSAndreas Gohr 578 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 207*e89aeebdSAndreas Gohr 579 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 208*e89aeebdSAndreas Gohr 209*e89aeebdSAndreas Gohr // -------------------------------------------------------------------- 2108719732dSAndreas Gohr // ATX heading collisions with DokuWiki-specific behavior. 2118719732dSAndreas Gohr // -------------------------------------------------------------------- 2128719732dSAndreas Gohr 38 => 'ATX heading with leading spaces: GFM tolerates 0-3 spaces of' 2138719732dSAndreas Gohr . ' indent before the opener; we require the `#` at column 0.' 2148719732dSAndreas Gohr . ' Indent tolerance collides with DokuWiki\'s 2-space-indent' 2158719732dSAndreas Gohr . ' preformatted block and isn\'t worth untangling', 2168719732dSAndreas Gohr 39 => 'indented code block: DokuWiki uses 2-space indent for' 2178719732dSAndreas Gohr . ' preformatted; GFM 4-space indented code blocks are not' 2188719732dSAndreas Gohr . ' implemented', 2198719732dSAndreas Gohr 40 => 'indented code block: 4-space indent after a paragraph is a' 2208719732dSAndreas Gohr . ' continuation in GFM but preformatted in DokuWiki — not' 2218719732dSAndreas Gohr . ' implemented', 2228719732dSAndreas Gohr 41 => 'ATX heading with leading spaces: second heading is indented' 2238719732dSAndreas Gohr . ' by 2 spaces; we require the `#` at column 0', 2248719732dSAndreas Gohr 49 => 'empty ATX heading: DokuWiki\'s XHTML renderer deliberately' 2258719732dSAndreas Gohr . ' skips blank headings (blank() guard in Doku_Renderer_xhtml::header)', 22672b2703bSAndreas Gohr]; 227