1<?php 2 3/** 4 * GFM spec examples that GfmSpecTest should skip, keyed by example number 5 * (as numbered in spec.txt / the rendered spec). 6 * 7 * Add entries here ONLY for behavior DokuWiki has explicitly decided not to 8 * implement — not for features that are merely pending. Unimplemented 9 * features should show as real failures so they remain visible TODOs on 10 * the branch. 11 * 12 * Each value is a short human-readable reason that will appear in phpunit's 13 * skip output. 14 */ 15 16return [ 17 // -------------------------------------------------------------------- 18 // Thematic breaks (GfmHr) — strict-only HR is intentional. The 19 // delimiter run must be bare: no leading, trailing, or internal 20 // whitespace in either DW or GFM flavor. The list-precedence cases 21 // additionally need a GfmListblock guard that is out of scope. 22 // -------------------------------------------------------------------- 23 17 => 'thematic break: 0-3 spaces of leading indent. Strict policy:' 24 . ' opener must be at column 0 in either flavor.', 25 21 => 'thematic break: spaces between delimiter chars (`- - -`).' 26 . ' Strict policy: bare run only.', 27 22 => 'thematic break: spaces between delimiter chars (`** * **`).' 28 . ' Strict policy: bare run only.', 29 23 => 'thematic break: spaces between delimiter chars (`- -`).' 30 . ' Strict policy: bare run only.', 31 24 => 'thematic break: trailing spaces after the run. Strict policy:' 32 . ' bare run only.', 33 29 => 'thematic break: Setext heading underline `Foo\n---` should' 34 . ' render as `<h2>`. Setext headings are deliberately not' 35 . ' supported — `---` collides with DokuWiki HR and `===` would' 36 . ' collide with DokuWiki heading syntax.', 37 30 => 'thematic break vs. list-item precedence (`* * *` between list' 38 . ' items): requires internal-space HR support and a GfmListblock' 39 . ' guard so the list refuses to absorb the HR-shaped line. Both' 40 . ' out of scope; the line stays a list-item body.', 41 31 => 'thematic break inside list with different bullet (`- * * *`):' 42 . ' depends on internal-space HR support inside the sub-parsed' 43 . ' item body. See example 30.', 44 45 // -------------------------------------------------------------------- 46 // Setext headings (§4.3) — deliberately not supported across the 47 // whole section. The `---` underline collides with DokuWiki\'s HR 48 // syntax and `===` would collide with DokuWiki\'s heading delimiter. 49 // Same rationale as #29 (thematic break vs. Setext underline), 50 // #111 (fence after Setext), and #212 (Setext after blockquote). 51 // 52 // Examples #62, #64, #67, #68, #69, #71, #74 are NOT listed: those 53 // are cases where Setext is deliberately NOT triggered (blockquote / 54 // list / paragraph wins, or blank lines disambiguate), so the spec 55 // output matches DokuWiki\'s no-Setext rendering and they pass 56 // naturally. 57 // 58 // #58 and #75 also depend on DokuWiki\'s strict-bare-run HR rule 59 // (`--- -` and `* * *` need internal-space HR, see #21-23) — they 60 // sit in the Setext section because the spec uses them to 61 // illustrate Setext-underline edge cases. 62 // -------------------------------------------------------------------- 63 50 => 'Setext heading (`Foo *bar*\n=====` / `\n-----`): Setext' 64 . ' headings deliberately not supported — `---`/`===` underlines' 65 . ' collide with DokuWiki HR / heading syntax.', 66 51 => 'Setext heading with multi-line content: Setext headings' 67 . ' deliberately not supported (see #50).', 68 52 => 'Setext heading with indented multi-line content: Setext' 69 . ' headings deliberately not supported (see #50).', 70 53 => 'Setext heading with any-length underline: Setext headings' 71 . ' deliberately not supported (see #50).', 72 54 => 'Setext heading with 3-space-indented content / underline:' 73 . ' Setext headings deliberately not supported (see #50).', 74 55 => 'Setext heading: 4-space-indented content forms code block,' 75 . ' then `---` HR. Setext headings deliberately not supported' 76 . ' (see #50).', 77 56 => 'Setext heading: underline indented up to 3 spaces with' 78 . ' trailing spaces. Setext headings deliberately not' 79 . ' supported (see #50).', 80 57 => 'Setext heading vs. 4-space-indented underline (paragraph' 81 . ' wins). Setext headings deliberately not supported (see #50).', 82 58 => 'Setext heading: underline cannot contain internal spaces' 83 . ' (`= =` / `--- -`). Setext headings deliberately not supported' 84 . ' (see #50); also depends on internal-space HR support DokuWiki' 85 . ' lacks (see #21-23).', 86 59 => 'Setext heading: trailing spaces in content do not cause a' 87 . ' line break. Setext headings deliberately not supported (see' 88 . ' #50).', 89 60 => 'Setext heading: trailing backslash in content. Setext' 90 . ' headings deliberately not supported (see #50).', 91 61 => 'Setext heading: block-structure precedence over inline.' 92 . ' Setext headings deliberately not supported (see #50).', 93 63 => 'Setext heading: underline cannot be a lazy continuation in' 94 . ' a blockquote. Setext headings deliberately not supported' 95 . ' (see #50).', 96 65 => 'Setext heading: preceding paragraph becomes part of heading' 97 . ' content. Setext headings deliberately not supported (see #50).', 98 66 => 'Setext heading: no blank line required before/after. Setext' 99 . ' headings deliberately not supported (see #50).', 100 70 => 'Setext heading: 4-space-indented content forms code block,' 101 . ' then `---` HR. Setext headings deliberately not supported' 102 . ' (see #50).', 103 72 => 'Setext heading with backslash-escaped marker `\\> foo`.' 104 . ' Setext headings deliberately not supported (see #50).', 105 73 => 'Setext heading: blank-line-separated paragraph + heading +' 106 . ' paragraph. Setext headings deliberately not supported (see' 107 . ' #50).', 108 75 => 'Setext heading boundary: `* * *` should be HR (cannot count' 109 . ' as Setext underline). Setext headings deliberately not' 110 . ' supported (see #50); also depends on internal-space HR' 111 . ' support DokuWiki lacks (see #21-23).', 112 76 => 'Setext heading: backslash-escaped underline `\\---` keeps' 113 . ' content as paragraph. Setext headings deliberately not' 114 . ' supported (see #50).', 115 116 // -------------------------------------------------------------------- 117 // Fenced code blocks (GfmCode / GfmFile) — deliberate simplifications 118 // versus strict GFM. All of these are consequences of lexer constraints 119 // (no regex backreferences) or the deliberate column-0-only policy. 120 // -------------------------------------------------------------------- 121 94 => 'fenced code: closing fence must be ≥ opening length — DokuWiki' 122 . ' accepts any 3+ run as a closer (no regex backreferences for' 123 . ' length pairing). Deliberate relaxation.', 124 95 => 'fenced code (tilde variant): closing fence must be ≥ opening' 125 . ' length — see example 94.', 126 96 => 'fenced code: unclosed fence — DokuWiki convention requires a' 127 . ' closer (matches DW <code> tag), so unclosed fences stay' 128 . ' literal rather than consuming to EOF. GFM\'s "close at end"' 129 . ' rule is really "close at any container boundary" in' 130 . ' CommonMark\'s two-pass block parser, which our single-pass' 131 . ' lexer cannot implement.', 132 97 => 'fenced code: unclosed fence with intervening short run — stays' 133 . ' literal, see example 96.', 134 98 => 'fenced code inside blockquote: GFM closes the fence at the' 135 . ' blockquote\'s end, but DokuWiki requires an explicit closing' 136 . ' fence and the single-pass lexer has no notion of container' 137 . ' boundaries to close at. Same root cause as example 96 —' 138 . ' unclosed fences stay literal.', 139 101 => 'fenced code: opener indented 1 space — DokuWiki requires' 140 . ' column-0 fences. Indent tolerance + per-line body dedent out' 141 . ' of scope.', 142 102 => 'fenced code: opener indented 2 spaces — see example 101.', 143 103 => 'fenced code: opener indented 3 spaces — see example 101.', 144 105 => 'fenced code: closer indented 2 spaces — column-0-only policy,' 145 . ' see example 101.', 146 106 => 'fenced code: indented opener with less-indented closer —' 147 . ' column-0-only policy, see example 101.', 148 107 => 'fenced code: 4-space-indented closer — with column-0-only' 149 . ' policy there is no valid closer, so the fence stays literal' 150 . ' (see example 96).', 151 109 => 'fenced code: malformed closer `~~~ ~~` (space-broken run) —' 152 . ' with no valid closer the fence stays literal (see example 96).', 153 108 => 'fenced code: `` `` is not a valid fence; GFM falls back to an' 154 . ' inline code span of length 3. Inline spans with n≥3 not' 155 . ' implemented (GfmBacktickSingle/Double cover only n=1, n=2).', 156 111 => 'fenced code interrupting Setext heading (`foo\n---`): Setext' 157 . ' headings are deliberately not supported — the `---` underline' 158 . ' collides with DokuWiki\'s horizontal rule and `===` would' 159 . ' collide with DokuWiki heading syntax.', 160 115 => 'fenced code: `` `` backtick-fence-with-backticks-in-info-string' 161 . ' is invalid; GFM falls back to n=3 inline span — inline spans' 162 . ' with n≥3 not implemented. See example 108.', 163 164 // -------------------------------------------------------------------- 165 // HTML blocks (§4.6) — raw HTML pass-through is not supported 166 // -------------------------------------------------------------------- 167 118 => 'raw HTML block (script/pre/style/textarea group): raw HTML pass-through not supported — DokuWiki escapes `<` as `<`', 168 119 => 'raw HTML block: raw HTML pass-through not supported', 169 120 => 'raw HTML block: raw HTML pass-through not supported', 170 121 => 'raw HTML block: raw HTML pass-through not supported', 171 122 => 'raw HTML block (comment): raw HTML pass-through not supported', 172 123 => 'raw HTML block (processing instruction): raw HTML pass-through not supported', 173 124 => 'raw HTML block (declaration): raw HTML pass-through not supported', 174 125 => 'raw HTML block (CDATA): raw HTML pass-through not supported', 175 126 => 'raw HTML block (block-level tag group): raw HTML pass-through not supported', 176 127 => 'raw HTML block: raw HTML pass-through not supported', 177 128 => 'raw HTML block: raw HTML pass-through not supported', 178 129 => 'raw HTML block: raw HTML pass-through not supported', 179 130 => 'raw HTML block: raw HTML pass-through not supported', 180 131 => 'raw HTML block: raw HTML pass-through not supported', 181 132 => 'raw HTML block: raw HTML pass-through not supported', 182 133 => 'raw HTML block: raw HTML pass-through not supported', 183 134 => 'raw HTML block: raw HTML pass-through not supported', 184 135 => 'raw HTML block: raw HTML pass-through not supported', 185 136 => 'raw HTML block (any-tag group): raw HTML pass-through not supported', 186 137 => 'raw HTML block: raw HTML pass-through not supported', 187 138 => 'raw HTML block: raw HTML pass-through not supported', 188 139 => 'raw HTML block: raw HTML pass-through not supported', 189 140 => 'raw HTML block: raw HTML pass-through not supported', 190 141 => 'raw HTML block: raw HTML pass-through not supported', 191 142 => 'raw HTML block: raw HTML pass-through not supported', 192 143 => 'raw HTML block: raw HTML pass-through not supported', 193 144 => 'raw HTML block: raw HTML pass-through not supported', 194 145 => 'raw HTML block: raw HTML pass-through not supported', 195 146 => 'raw HTML block: raw HTML pass-through not supported', 196 147 => 'raw HTML block: raw HTML pass-through not supported', 197 148 => 'raw HTML block: raw HTML pass-through not supported', 198 149 => 'raw HTML block: raw HTML pass-through not supported', 199 150 => 'raw HTML block: raw HTML pass-through not supported', 200 151 => 'raw HTML block: raw HTML pass-through not supported', 201 152 => 'raw HTML block: raw HTML pass-through not supported', 202 153 => 'raw HTML block: raw HTML pass-through not supported', 203 154 => 'raw HTML block: raw HTML pass-through not supported', 204 155 => 'raw HTML block: raw HTML pass-through not supported', 205 156 => 'raw HTML block: raw HTML pass-through not supported', 206 157 => 'raw HTML block: raw HTML pass-through not supported', 207 158 => 'raw HTML block: raw HTML pass-through not supported', 208 159 => 'raw HTML block: raw HTML pass-through not supported', 209 160 => 'raw HTML block: raw HTML pass-through not supported', 210 211 // -------------------------------------------------------------------- 212 // Link reference definitions (§4.7) — single-pass lexer cannot resolve 213 // forward references, so the `[foo]: /url` definition lines are not 214 // recognised and the matching `[foo]` references stay literal. Same 215 // rationale as the reference-link entries at #535-579. 216 // Examples #168, #180-182 are NOT listed: their definitions are 217 // invalid (empty URL / inside indented code / inside fenced code / 218 // attached to a paragraph), so the spec also expects literal output 219 // for the `[foo]` reference, and DW agrees. 220 // -------------------------------------------------------------------- 221 161 => 'link reference definition: forward-reference definitions not supported (single-pass lexer)', 222 162 => 'link reference definition: forward-reference definitions not supported (single-pass lexer)', 223 163 => 'link reference definition (multi-line title): forward-reference definitions not supported (single-pass lexer)', 224 164 => 'link reference definition (case-insensitive label): forward-reference definitions not supported (single-pass lexer)', 225 165 => 'link reference definition (Unicode case folding): forward-reference definitions not supported (single-pass lexer)', 226 166 => 'link reference definition (whitespace-collapsed label): forward-reference definitions not supported (single-pass lexer)', 227 167 => 'link reference definition (no link text used): forward-reference definitions not supported (single-pass lexer)', 228 169 => 'link reference definition (pointy-bracket destination): forward-reference definitions not supported (single-pass lexer)', 229 170 => 'link reference definition (no title, blank line in between): forward-reference definitions not supported (single-pass lexer)', 230 171 => 'link reference definition (title only, no destination): forward-reference definitions not supported (single-pass lexer)', 231 172 => 'link reference definition (multiple definitions): forward-reference definitions not supported (single-pass lexer)', 232 173 => 'link reference definition (first wins on duplicate label): forward-reference definitions not supported (single-pass lexer)', 233 174 => 'link reference definition (label case-insensitive): forward-reference definitions not supported (single-pass lexer)', 234 175 => 'link reference definition (used as paragraph delimiter): forward-reference definitions not supported (single-pass lexer)', 235 176 => 'link reference definition (no body following): forward-reference definitions not supported (single-pass lexer)', 236 177 => 'link reference definition (label with surrounding whitespace): forward-reference definitions not supported (single-pass lexer)', 237 178 => 'link reference definition (indented up to 3 spaces): forward-reference definitions not supported (single-pass lexer)', 238 179 => 'link reference definition (multi-line definition with title): forward-reference definitions not supported (single-pass lexer)', 239 183 => 'link reference definition (does not interrupt paragraph): forward-reference definitions not supported (single-pass lexer)', 240 184 => 'link reference definition (between blockquote and paragraph): forward-reference definitions not supported (single-pass lexer)', 241 185 => 'link reference definition (lone definition emits nothing): forward-reference definitions not supported (single-pass lexer)', 242 186 => 'link reference definition (definition then HR): forward-reference definitions not supported (single-pass lexer)', 243 187 => 'link reference definition (multiple defs in a row): forward-reference definitions not supported (single-pass lexer)', 244 188 => 'link reference definition (def inside blockquote): forward-reference definitions not supported (single-pass lexer)', 245 329 => 'reference link with entity-decoded URL in definition: depends on' 246 . ' link reference definitions, which forward-reference definitions' 247 . ' are not supported (single-pass lexer)', 248 249 // -------------------------------------------------------------------- 250 // Code-span edge cases that collide with project-wide decisions 251 // (no raw HTML, no GFM angle-bracket autolinks, typography on by 252 // default) or with the single-pass lexer's limits. 253 // -------------------------------------------------------------------- 254 351 => 'code span vs. emphasis: cross-positional precedence would require' 255 . ' a pre-scan pass — the single-pass lexer matches leftmost-first' 256 . ' and cannot reject an earlier emphasis opener because a later' 257 . ' backtick span would consume its closer', 258 352 => 'code span vs. link `[not a `link](/foo`)`: the link opener is' 259 . ' leftmost but a backtick span inside its label should consume' 260 . ' the closing `]` and `)` — single-pass lexer matches' 261 . ' leftmost-first and cannot reorder spans (see #351).', 262 353 => 'code span: the trailing `"` outside the span is converted to a' 263 . ' curly quote by DokuWiki typography, diverging from the spec HTML', 264 327 => 'raw HTML tag with entity in attribute: raw HTML pass-through not supported', 265 354 => 'raw HTML tag pass-through: raw HTML pass-through not supported', 266 356 => 'GFM angle-bracket autolink `<http://…>`: not implemented — we' 267 . ' rely on DokuWiki\'s existing bare-URL detection, which does not' 268 . ' parse `<URL>` form', 269 270 // -------------------------------------------------------------------- 271 // CommonMark §6.2 flanking-delimiter analysis — deliberately not 272 // implemented. DokuWiki's regex lexer uses leftmost-match and cannot 273 // apply CommonMark's left/right-flanking rules that distinguish 274 // word-chars, whitespace, and punctuation for `*`/`_` delimiters, or 275 // the "multiple-of-3" rule for overlapping runs. These examples all 276 // rely on that machinery. 277 // -------------------------------------------------------------------- 278 279 // Unicode whitespace in flanking context. Our `\s` is ASCII-only 280 // because the lexer doesn't set the PCRE `u` flag. 281 363 => 'Unicode whitespace (U+00A0) flanking — requires u-flag-aware regex', 282 283 // Punctuation-adjacent flanking for `*` / `_` / `**` / `__` 284 362 => 'flanking: punctuation-adjacent `*` (left-flanking vs. right-flanking)', 285 368 => 'flanking: punctuation-adjacent `_`', 286 372 => 'flanking: intraword `_` with punctuation inside', 287 377 => 'flanking: `*` followed by `(` requires punctuation-aware flanking', 288 378 => 'flanking: nested `*(*foo*)*` requires flanking + balanced-pair analysis', 289 382 => 'flanking: nested `_(_foo_)_` requires flanking + balanced-pair analysis', 290 389 => 'flanking: punctuation-adjacent `**`', 291 394 => 'flanking: punctuation-adjacent `__`', 292 401 => 'flanking: `**` followed by `(`', 293 404 => 'flanking: nested `*bar*` inside `**foo ... foo**` with punctuation', 294 407 => 'flanking: `__` followed by `(`', 295 470 => 'flanking: nested `*_foo_*` requires balanced-pair analysis', 296 472 => 'flanking: nested `_*foo*_` requires balanced-pair analysis', 297 298 // Intraword `__` strong (even multibyte) — flanking rule for `_` requires 299 // examining whether the delimiter run is word-boundary-flanking, which our 300 // simple lookbehind/lookahead approximation doesn't fully match. 301 395 => 'flanking: intraword `__` (`foo__bar__`) — left-flanking vs right-flanking', 302 396 => 'flanking: intraword `__` across digits (`5__6__78`)', 303 397 => 'flanking: intraword `__` with Cyrillic', 304 398 => 'flanking: `__foo, __bar__, baz__` — flanking + balanced pairing', 305 409 => 'flanking: `__foo__bar` — intraword close', 306 410 => 'flanking: intraword `__` with Cyrillic (leading)', 307 411 => 'flanking: `__foo__bar__baz__` — multiple `__` pairs with flanking', 308 412 => 'flanking: `__(bar)__.` — punctuation-adjacent', 309 310 // Overlapping / multiple-of-3 rule for runs 311 416 => 'CommonMark rule 9 (overlapping same-delimiter `_foo _bar_ baz_`)', 312 417 => 'CommonMark overlapping `_` / `__` with flanking', 313 418 => 'CommonMark overlapping `*foo *bar**` — multiple-of-3 rule', 314 419 => 'CommonMark nested `*foo **bar** baz*` — balanced-pair analysis', 315 421 => 'CommonMark overlapping `*foo**bar*` — multiple-of-3', 316 422 => 'CommonMark nested `***foo** bar*` — triple-delimiter analysis', 317 423 => 'CommonMark nested `*foo **bar***` — triple-delimiter analysis', 318 424 => 'CommonMark nested `*foo**bar***` — triple-delimiter analysis', 319 425 => 'CommonMark triple `foo***bar***baz` — triple-delimiter analysis', 320 426 => 'CommonMark long delimiter runs `foo******bar*********baz`', 321 427 => 'CommonMark deeply nested `*foo **bar *baz* bim** bop*`', 322 434 => 'CommonMark overlapping `__foo __bar__ baz__` — multiple-of-3', 323 435 => 'CommonMark `____foo__ bar__` — leading long delimiter run', 324 436 => 'CommonMark `**foo **bar****` — trailing long delimiter run', 325 439 => 'CommonMark nested `***foo* bar**` — triple-delimiter', 326 440 => 'CommonMark nested `**foo *bar***` — triple-delimiter', 327 441 => 'CommonMark deeply nested `**foo *bar **baz** bim* bop**`', 328 329 // `__foo_` / `_foo__` — mixing `_` and `__` requires flanking to decide 330 // which delimiter pairs open/close. 331 463 => 'flanking: `__foo_` — mixed `_`/`__` pairing', 332 464 => 'flanking: `_foo__` — mixed `_`/`__` pairing', 333 465 => 'flanking: `___foo__` — delimiter-run length analysis', 334 466 => 'flanking: `____foo_` — delimiter-run length analysis', 335 467 => 'flanking: `__foo___` — delimiter-run length analysis', 336 468 => 'flanking: `_foo____` — delimiter-run length analysis', 337 338 // Long delimiter runs require excess-drop logic (2 outer chars dropped 339 // from each side). Stack-based pairing needed — out of scope. 340 473 => 'CommonMark `****foo****` — excess-drop (4+4 → strong only)', 341 474 => 'CommonMark `____foo____` — excess-drop (4+4 → strong only)', 342 475 => 'CommonMark `******foo******` — excess-drop (6+6 → strong only)', 343 477 => 'CommonMark `_____foo_____` — excess-drop (5+5 → em+strong, 2 dropped each side)', 344 345 // Overlapping / crossing delimiters 346 478 => 'CommonMark `*foo _bar* baz_` — overlapping different delimiters', 347 479 => 'CommonMark `*foo __bar *baz bim__ bam*` — crossing delimiters', 348 480 => 'CommonMark `**foo **bar baz**` — overlapping same delimiter', 349 350 // Emphasis vs. angle-bracket autolink: same root cause as #351 (the 351 // single-pass lexer matches leftmost-first and cannot reject an 352 // earlier `**`/`__` opener because a later `<URL>` autolink would 353 // consume its closer). 354 489 => 'emphasis vs. angle-bracket autolink `**a<http://...?q=**>`:' 355 . ' leftmost-match cannot reorder spans — see #351 for the' 356 . ' single-pass-lexer rationale.', 357 490 => 'emphasis vs. angle-bracket autolink `__a<http://...?q=__>`:' 358 . ' leftmost-match cannot reorder spans — see #351.', 359 360 // -------------------------------------------------------------------- 361 // Inline link `[text](url)` — features GfmLink deliberately does not 362 // implement. Either rarely-used syntax paid for with disproportionate 363 // regex complexity, or single-pass-lexer limits that can't be worked 364 // around inside one mode. 365 // -------------------------------------------------------------------- 366 367 // GFM link title attribute (`"title"` / `'title'` / `(title)` after 368 // the URL). Parses cleanly but is discarded: DokuWiki's link handler 369 // instructions have no title-attribute slot, and plumbing one through 370 // every renderer is out of scope for GfmLink. 371 328 => 'link with entity-decoded URL and title: URL side decodes correctly,' 372 . ' but the title attribute is discarded — DokuWiki link instructions' 373 . ' have no title slot.', 374 493 => 'link title attribute: GfmLink parses but discards — DokuWiki link instructions have no title slot', 375 513 => 'link title attribute (three quoting styles): discarded by GfmLink', 376 515 => 'link title separated by non-breaking space: title slot not supported', 377 516 => 'link title with nested balanced quotes: Markdown.pl quirk, not supported', 378 517 => 'link title with different quote type for inner quotes: title slot not supported', 379 518 => 'multi-line link title: title slot not supported', 380 381 // Pointy-bracket link destinations `<...>`. Rarely used; regex cost 382 // and interaction with raw-HTML detection outweigh the benefit. 383 496 => 'pointy-bracket link destination `<>`: not supported', 384 498 => 'pointy-bracket destination with spaces `<...>`: not supported', 385 500 => 'pointy-bracket destination with newline: not supported', 386 501 => 'pointy-bracket destination containing `)`: not supported', 387 502 => 'pointy-bracket destination with trailing backslash: not supported', 388 503 => 'malformed pointy-bracket destinations: renderer output differs', 389 507 => 'pointy-bracket destination wrapping unbalanced parens: not supported', 390 391 // Balanced-parens inside URL destinations. 392 505 => 'balanced-parens in URL destination: not supported (regex single-level)', 393 394 // Other URL-level edges. 395 495 => 'empty URL destination `[link]()`: pattern requires non-empty URL', 396 510 => 'backslash in URL destination: URL-encoding differs from spec', 397 511 => 'HTML entity / percent-encoding in URL: renderer normalization differs', 398 512 => 'link destination that parses as a title: edge case not supported', 399 337 => 'entity-decoded `"` inside link URL slot: spec rejects the' 400 . ' link because the decoded `"` would split URL from title, but' 401 . ' GfmLink uses a permissive `[^)\n]+` URL slot and accepts the' 402 . ' whole run as the URL — strict GFM URL rejection not implemented', 403 404 // Inherent single-pass-lexer limits for link text containing nested 405 // structures. These cannot be resolved inside one mode. 406 522 => 'nested bracket forms inner link, outer falls back to literal', 407 526 => 'nested links: inner is a link, outer falls back to literal', 408 527 => 'nested links inside emphasis: not supported', 409 529 => 'link text grouping vs. emphasis: leftmost-match cannot override', 410 530 => 'emphasis/bracket crossing: leftmost-match cannot override', 411 532 => 'raw HTML inside link text: project-wide "no raw HTML" limit', 412 533 => 'code span inside link text: requires pre-scan pass (see #351)', 413 534 => 'autolink inside link text: raw `<URL>` autolinks not supported (see #356)', 414 415 // Reference links (`[text][id]`, `[text][]`, `[foo]` with matching 416 // `[foo]: url` definition). Not implemented: resolving forward 417 // references would require a two-pass parse, but DokuWiki's lexer is 418 // single-pass. Inline links `[text](url)` are the only supported 419 // form. 420 535 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 421 536 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 422 537 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 423 538 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 424 539 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 425 540 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 426 541 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 427 542 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 428 543 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 429 544 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 430 545 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 431 546 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 432 547 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 433 548 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 434 549 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 435 550 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 436 551 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 437 552 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 438 553 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 439 557 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 440 558 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 441 560 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 442 561 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)', 443 562 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)', 444 563 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)', 445 564 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)', 446 565 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 447 566 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 448 567 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 449 568 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 450 569 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 451 570 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)', 452 571 => 'shortcut reference link with escape: forward-reference definitions not supported (single-pass lexer)', 453 572 => 'shortcut reference link with emphasis: forward-reference definitions not supported (single-pass lexer)', 454 573 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 455 574 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 456 575 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 457 576 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 458 577 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 459 578 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 460 579 => 'reference link: forward-reference definitions not supported (single-pass lexer)', 461 462 // -------------------------------------------------------------------- 463 // Inline image ``. The XHTML renderer's default media 464 // rendering diverges from GFM's bare <img> (it wraps in a details <a> 465 // with fetch.php/detail.php proxy URLs) — GfmSpecTest uses 466 // SpecCompatRenderer to emit spec-shape bare <img>, so only the 467 // parser-level or feature-level gaps remain as skips: title attribute 468 // (no DW slot), reference images, pointy-bracket destinations, nested 469 // brackets, and escape-dependent cases. 470 // -------------------------------------------------------------------- 471 472 580 => 'image with title attribute: GfmMedia discards titles (no DW slot)', 473 581 => 'reference-style image: forward-reference definitions not supported (single-pass lexer)', 474 582 => 'nested image-in-image `](y)`: alt class forbids brackets;' 475 . ' leftmost-match cannot reorder — outer falls back to literal (see #526)', 476 583 => 'link-in-image alt `](y)`: alt class forbids brackets;' 477 . ' leftmost-match cannot reorder — outer falls back to literal (see #526)', 478 584 => 'collapsed reference-style image: forward-reference definitions not supported', 479 585 => 'full reference-style image: forward-reference definitions not supported', 480 587 => 'image with title attribute: title discarded (no DW slot)', 481 588 => 'pointy-bracket image destination ``: not supported (see GfmLink #496)', 482 590 => 'reference-style image: forward-reference definitions not supported', 483 591 => 'reference-style image (case-insensitive label): forward-reference definitions not supported', 484 592 => 'collapsed reference-style image `![foo][]`: forward-reference definitions not supported', 485 593 => 'collapsed reference-style image with emphasis in label: forward-reference definitions not supported', 486 594 => 'collapsed reference-style image (case-insensitive): forward-reference definitions not supported', 487 595 => 'reference-style image with intervening whitespace: forward-reference definitions not supported', 488 596 => 'shortcut reference-style image `![foo]`: forward-reference definitions not supported', 489 597 => 'shortcut reference-style image with emphasis: forward-reference definitions not supported', 490 598 => 'image with unescaped nested brackets `![[foo]]`: literal-fallback behavior not supported', 491 599 => 'shortcut reference-style image (case-insensitive): forward-reference definitions not supported', 492 600 => 'image-via-reference fallback `!\[foo]` with `[foo]: /url`: forward-reference definitions not supported (single-pass lexer)', 493 601 => 'image-via-reference fallback `\![foo]` with `[foo]: /url`: forward-reference definitions not supported (single-pass lexer)', 494 495 // -------------------------------------------------------------------- 496 // ATX heading collisions with DokuWiki-specific behavior. 497 // -------------------------------------------------------------------- 498 38 => 'ATX heading with leading spaces: GFM tolerates 0-3 spaces of' 499 . ' indent before the opener; we require the `#` at column 0.' 500 . ' Indent tolerance collides with DokuWiki\'s 2-space-indent' 501 . ' preformatted block and isn\'t worth untangling', 502 39 => 'indented code block: DokuWiki uses 2-space indent for' 503 . ' preformatted; GFM 4-space indented code blocks are not' 504 . ' implemented', 505 40 => 'indented code block: 4-space indent after a paragraph is a' 506 . ' continuation in GFM but preformatted in DokuWiki — not' 507 . ' implemented', 508 41 => 'ATX heading with leading spaces: second heading is indented' 509 . ' by 2 spaces; we require the `#` at column 0', 510 49 => 'empty ATX heading: DokuWiki\'s XHTML renderer deliberately' 511 . ' skips blank headings (blank() guard in Doku_Renderer_xhtml::header)', 512 513 // -------------------------------------------------------------------- 514 // List items / Lists — list features GfmListblock deliberately does 515 // not implement. The simplifications are by design: indentation uses 516 // a fixed 2-space-multiple step starting at 0, lazy continuation is 517 // not supported, and the rewriter groups items by 'u'/'o' type only. 518 // The buckets are: 519 // 520 // A. Extra spaces after the marker. CommonMark rolls them (up to 521 // 4) into the content column; we dedent at `marker_width + 1`, 522 // collapsing the extras. 523 // B. 1- or 3-space indent for nesting (we round down to nearest 2). 524 // C. Lazy continuation (column-0 paragraph wrap inside an item). 525 // D. Strict CommonMark loose/tight classification (every blank line 526 // between items / inside items reclassifies; we use a simpler 527 // single-paragraph-tight, multi-paragraph-loose rule). 528 // E. Marker-character-change splits ordered lists ('.' vs ')') or 529 // unordered ('-' vs '+' vs '*'). Our rewriter groups by 'u' / 'o' 530 // type only, not by marker character. 531 // F. List interrupting a paragraph without a blank line — requires a 532 // multi-pass block parser to revisit prior text. 533 // 534 // Examples that depend on a pending mode (GfmQuote, GfmEscape, …) are 535 // intentionally NOT skipped — they remain visible failing tests until 536 // the mode lands. 537 // -------------------------------------------------------------------- 538 // -------------------------------------------------------------------- 539 // Block quotes — deliberate scope reductions vs. strict GFM. The 540 // unified GfmQuote mode (replacing DW Quote) covers `>` blockquotes 541 // for both DW and MD pages, but several CommonMark blockquote rules 542 // are out of scope: 543 // 544 // - 1-3 space indent before `>` (column-0-only policy, consistent 545 // with GfmCode / GfmFile / GfmHeader). 546 // - Lazy continuation (paragraph text without `>` on continuation 547 // lines). Same policy as GfmListblock — markers required on 548 // every line. 549 // - Headers inside quotes — sub-parser excludes BASEONLY so header 550 // instructions don't drive TOC/section-edit anchors that don't 551 // compose with `<blockquote>`. Same rationale as GfmListblock's 552 // header exclusion inside list items. 553 // - Setext-style block constructs (the `---` underline collides 554 // with DW's HR rule). 555 // 556 // Examples that depend on still-pending modes (GfmHr) are 557 // intentionally NOT skipped — they stay visible until those modes 558 // land. 559 // -------------------------------------------------------------------- 560 206 => 'block quotes: header inside quote — sub-parser excludes' 561 . ' BASEONLY (TOC / section-edit anchors do not compose with' 562 . ' `<blockquote>`). Same policy as GfmListblock for `<li>`.', 563 207 => 'block quotes: header inside quote with no space after `>` —' 564 . ' see #206 for the BASEONLY exclusion rationale.', 565 208 => 'block quotes: leading-space `>` (1-3 spaces of indent) —' 566 . ' column-0-only policy, consistent with GfmCode / GfmFile.', 567 210 => 'block quotes: lazy continuation `> # Foo\n> bar\nbaz` —' 568 . ' every quote line must begin with `>` at column 0. Same' 569 . ' policy as GfmListblock.', 570 211 => 'block quotes: lazy continuation `> bar\nbaz\n> foo` —' 571 . ' see #210.', 572 212 => 'block quotes: Setext heading underline `---` after `> foo`' 573 . ' — no Setext headings (the `---` collides with DW HR syntax).', 574 215 => 'block quotes: fenced code block split across blockquote' 575 . ' boundary — fence inside quote followed by non-`>` lines' 576 . ' depends on the same lazy-continuation rule we do not' 577 . ' implement (see #210).', 578 216 => 'block quotes: lazy continuation `> foo\n - bar` — see #210.', 579 225 => 'block quotes: lazy continuation `> bar\nbaz` — see #210.', 580 227 => 'block quotes: lazy continuation `> bar\n>\nbaz` — see #210.', 581 228 => 'block quotes: lazy continuation in nested quote' 582 . ' `> > > foo\nbar` — see #210.', 583 229 => 'block quotes: lazy continuation across nested levels' 584 . ' `>>> foo\n> bar\n>>baz` — see #210.', 585 586 232 => 'list items: marker-width content-column alignment (A)', 587 235 => 'list items: marker-width content-column alignment (A)', 588 249 => 'list items: marker-width-driven content-column alignment for `10. foo` (A)', 589 254 => 'list items: marker-width content-column alignment edge case (A)', 590 258 => 'list items: marker-width content-column for `1. foo` (A)', 591 263 => 'list items: indent ambiguity at column 0/1/2 (B)', 592 264 => 'list items: 1-space-indent variation (B)', 593 265 => 'list items: marker-width with multi-line continuation (A)', 594 266 => 'list items: marker-width with multi-line continuation (A)', 595 267 => 'list items: lazy continuation (C)', 596 268 => 'list items: lazy continuation (C)', 597 270 => 'list items: lazy continuation across blank line (C+D)', 598 273 => 'list items: list interrupting a paragraph without blank line (F)', 599 275 => 'list items: 3-space indent rounds to 2 — sub-list under previous item (B)', 600 276 => 'list items: marker-width content-column with mixed types (A+E)', 601 277 => 'list items: nested markers on a single line (A)', 602 278 => 'list items: marker-character switch splits the list (E)', 603 281 => 'lists: marker-character change splits unordered list `-` -> `+` (E)', 604 282 => 'lists: ordered delimiter switch splits list `.` -> `)` (E)', 605 284 => 'lists: list interrupting paragraph without blank line (F)', 606 286 => 'lists: marker-width content-column alignment for ordered list (A)', 607 287 => 'lists: triple blank line + indented continuation in deeply nested item (D)', 608 288 => 'lists: marker-character change at deeper level (E)', 609 289 => 'lists: marker-character change with type switch (E)', 610 290 => 'lists: 1-space-indent variations of items, all stay top-level (B)', 611 291 => 'lists: 1-space-indent variations on ordered list (B)', 612 292 => 'lists: marker-character change splits inside nested list (E)', 613 293 => 'lists: marker-character change with mixed indent (E+B)', 614 294 => 'lists: lazy continuation across types (C+E)', 615 295 => 'lists: lazy continuation in nested list (C)', 616 296 => 'lists: lazy continuation across blank line (C+D)', 617 297 => 'lists: blank-line classification for loose/tight in nested list (D)', 618 298 => 'lists: blank-line classification (D)', 619 300 => 'lists: blank-line classification with marker change (D+E)', 620 301 => 'lists: blank-line classification + marker-width alignment (D+A)', 621 304 => 'lists: blank line between sub-list items affects loose/tight (D)', 622 305 => 'lists: blank line between deeply nested items (D)', 623 306 => 'lists: blank line at the end of a loose list affects classification (D)', 624 625 // -------------------------------------------------------------------- 626 // Backslash-escape examples (§6.1) that fail for reasons unrelated to 627 // GfmEscape itself: renderer divergences, typography conversion, and 628 // already-skipped GFM features (autolinks, raw HTML, reference links, 629 // discarded link titles). The escape mechanic itself works. 630 // -------------------------------------------------------------------- 631 308 => 'backslash escapes: apostrophe is rendered as `'` by DW while' 632 . ' the spec expects a literal `\'` — renderer policy difference,' 633 . ' not an escape bug', 634 310 => 'backslash escapes: DW typography converts straight `"..."` to curly' 635 . ' quotes when $conf[typography] is on, diverging from spec output', 636 316 => 'backslash escapes inside angle-bracket autolinks: GFM autolink' 637 . ' `<URL>` form not implemented (see example 356)', 638 317 => 'backslash escapes inside raw HTML: raw HTML pass-through is not' 639 . ' supported by default (see example 354)', 640 318 => 'backslash escapes in link title: title attribute is discarded — DW' 641 . ' link instructions have no title slot', 642 319 => 'backslash escapes in reference-link definition: link reference' 643 . ' definitions not supported (single-pass lexer cannot resolve' 644 . ' forward references)', 645 646 // -------------------------------------------------------------------- 647 // Raw HTML (§6.6) — inline raw HTML pass-through. Same project-wide 648 // decision as HTML blocks (#118-160): DokuWiki escapes `<` as `<` 649 // by default; the `<html>` block is the opt-in. Examples #637 and 650 // #640 are intentionally NOT listed — the spec there expects literal 651 // `<...>` escaping for malformed tags, which DW also produces, 652 // so they pass naturally. 653 // -------------------------------------------------------------------- 654 632 => 'raw HTML inline (open tag): raw HTML pass-through not supported', 655 633 => 'raw HTML inline (closing tag): raw HTML pass-through not supported', 656 634 => 'raw HTML inline (multi-line attributes): raw HTML pass-through not supported', 657 635 => 'raw HTML inline (line breaks in attributes): raw HTML pass-through not supported', 658 636 => 'raw HTML inline (custom tags / attribute syntax): raw HTML pass-through not supported', 659 638 => 'raw HTML inline (illegal attribute names): raw HTML pass-through not supported', 660 639 => 'raw HTML inline (illegal attribute values): raw HTML pass-through not supported', 661 641 => 'raw HTML inline (open and closing tags): raw HTML pass-through not supported', 662 642 => 'raw HTML inline (HTML comment): raw HTML pass-through not supported', 663 643 => 'raw HTML inline (invalid comment): raw HTML pass-through not supported', 664 644 => 'raw HTML inline (processing instruction): raw HTML pass-through not supported', 665 645 => 'raw HTML inline (declaration): raw HTML pass-through not supported', 666 646 => 'raw HTML inline (declaration single-letter name): raw HTML pass-through not supported', 667 647 => 'raw HTML inline (declaration EMPTY): raw HTML pass-through not supported', 668 648 => 'raw HTML inline (CDATA section): raw HTML pass-through not supported', 669 649 => 'raw HTML inline (entity reference inside attribute): raw HTML pass-through not supported', 670 650 => 'raw HTML inline (backslash escape inside attribute): raw HTML pass-through not supported', 671 651 => 'raw HTML inline (entity-escaped quote inside attribute): raw HTML pass-through not supported', 672 673 // -------------------------------------------------------------------- 674 // Hard line breaks (GfmLinebreak) — both delimiter forms (two trailing 675 // spaces and `\` before newline) work in paragraphs, emphasis, and 676 // other inline containers. The skipped cases sit inside raw HTML tags, 677 // which DokuWiki does not pass through by default. 678 // -------------------------------------------------------------------- 679 662 => 'hard line break inside a raw HTML tag: raw HTML pass-through not supported', 680 663 => 'hard line break (backslash form) inside a raw HTML tag — see' 681 . ' #662. Raw HTML out of scope.', 682]; 683