xref: /dokuwiki/_test/tests/Parsing/Markdown/gfm-spec/skip.php (revision 3440a8c07d59952439e180d2c33a32262fd3a84c)
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    // Code-span edge cases that collide with project-wide decisions
19    // (no raw HTML, no GFM angle-bracket autolinks, typography on by
20    // default) or with the single-pass lexer's limits.
21    // --------------------------------------------------------------------
22    351 => 'code span vs. emphasis: cross-positional precedence would require'
23         . ' a pre-scan pass — the single-pass lexer matches leftmost-first'
24         . ' and cannot reject an earlier emphasis opener because a later'
25         . ' backtick span would consume its closer',
26    353 => 'code span: the trailing `"` outside the span is converted to a'
27         . ' curly quote by DokuWiki typography, diverging from the spec HTML',
28    354 => 'raw HTML tag pass-through: DokuWiki does not render raw HTML by'
29         . ' default; `<html>` blocks are the opt-in',
30    356 => 'GFM angle-bracket autolink `<http://…>`: not implemented — we'
31         . ' rely on DokuWiki\'s existing bare-URL detection, which does not'
32         . ' parse `<URL>` form',
33
34    // --------------------------------------------------------------------
35    // CommonMark §6.2 flanking-delimiter analysis — deliberately not
36    // implemented. DokuWiki's regex lexer uses leftmost-match and cannot
37    // apply CommonMark's left/right-flanking rules that distinguish
38    // word-chars, whitespace, and punctuation for `*`/`_` delimiters, or
39    // the "multiple-of-3" rule for overlapping runs. These examples all
40    // rely on that machinery.
41    // --------------------------------------------------------------------
42
43    // Unicode whitespace in flanking context. Our `\s` is ASCII-only
44    // because the lexer doesn't set the PCRE `u` flag.
45    363 => 'Unicode whitespace (U+00A0) flanking — requires u-flag-aware regex',
46
47    // Punctuation-adjacent flanking for `*` / `_` / `**` / `__`
48    362 => 'flanking: punctuation-adjacent `*` (left-flanking vs. right-flanking)',
49    368 => 'flanking: punctuation-adjacent `_`',
50    372 => 'flanking: intraword `_` with punctuation inside',
51    377 => 'flanking: `*` followed by `(` requires punctuation-aware flanking',
52    378 => 'flanking: nested `*(*foo*)*` requires flanking + balanced-pair analysis',
53    382 => 'flanking: nested `_(_foo_)_` requires flanking + balanced-pair analysis',
54    389 => 'flanking: punctuation-adjacent `**`',
55    394 => 'flanking: punctuation-adjacent `__`',
56    401 => 'flanking: `**` followed by `(`',
57    404 => 'flanking: nested `*bar*` inside `**foo ... foo**` with punctuation',
58    407 => 'flanking: `__` followed by `(`',
59    470 => 'flanking: nested `*_foo_*` requires balanced-pair analysis',
60    472 => 'flanking: nested `_*foo*_` requires balanced-pair analysis',
61
62    // Intraword `__` strong (even multibyte) — flanking rule for `_` requires
63    // examining whether the delimiter run is word-boundary-flanking, which our
64    // simple lookbehind/lookahead approximation doesn't fully match.
65    395 => 'flanking: intraword `__` (`foo__bar__`) — left-flanking vs right-flanking',
66    396 => 'flanking: intraword `__` across digits (`5__6__78`)',
67    397 => 'flanking: intraword `__` with Cyrillic',
68    398 => 'flanking: `__foo, __bar__, baz__` — flanking + balanced pairing',
69    409 => 'flanking: `__foo__bar` — intraword close',
70    410 => 'flanking: intraword `__` with Cyrillic (leading)',
71    411 => 'flanking: `__foo__bar__baz__` — multiple `__` pairs with flanking',
72    412 => 'flanking: `__(bar)__.` — punctuation-adjacent',
73
74    // Overlapping / multiple-of-3 rule for runs
75    416 => 'CommonMark rule 9 (overlapping same-delimiter `_foo _bar_ baz_`)',
76    417 => 'CommonMark overlapping `_` / `__` with flanking',
77    418 => 'CommonMark overlapping `*foo *bar**` — multiple-of-3 rule',
78    419 => 'CommonMark nested `*foo **bar** baz*` — balanced-pair analysis',
79    421 => 'CommonMark overlapping `*foo**bar*` — multiple-of-3',
80    422 => 'CommonMark nested `***foo** bar*` — triple-delimiter analysis',
81    423 => 'CommonMark nested `*foo **bar***` — triple-delimiter analysis',
82    424 => 'CommonMark nested `*foo**bar***` — triple-delimiter analysis',
83    425 => 'CommonMark triple `foo***bar***baz` — triple-delimiter analysis',
84    426 => 'CommonMark long delimiter runs `foo******bar*********baz`',
85    427 => 'CommonMark deeply nested `*foo **bar *baz* bim** bop*`',
86    434 => 'CommonMark overlapping `__foo __bar__ baz__` — multiple-of-3',
87    435 => 'CommonMark `____foo__ bar__` — leading long delimiter run',
88    436 => 'CommonMark `**foo **bar****` — trailing long delimiter run',
89    439 => 'CommonMark nested `***foo* bar**` — triple-delimiter',
90    440 => 'CommonMark nested `**foo *bar***` — triple-delimiter',
91    441 => 'CommonMark deeply nested `**foo *bar **baz** bim* bop**`',
92
93    // `__foo_` / `_foo__` — mixing `_` and `__` requires flanking to decide
94    // which delimiter pairs open/close.
95    463 => 'flanking: `__foo_` — mixed `_`/`__` pairing',
96    464 => 'flanking: `_foo__` — mixed `_`/`__` pairing',
97    465 => 'flanking: `___foo__` — delimiter-run length analysis',
98    466 => 'flanking: `____foo_` — delimiter-run length analysis',
99    467 => 'flanking: `__foo___` — delimiter-run length analysis',
100    468 => 'flanking: `_foo____` — delimiter-run length analysis',
101
102    // Long delimiter runs require excess-drop logic (2 outer chars dropped
103    // from each side). Stack-based pairing needed — out of scope.
104    473 => 'CommonMark `****foo****` — excess-drop (4+4 → strong only)',
105    474 => 'CommonMark `____foo____` — excess-drop (4+4 → strong only)',
106    475 => 'CommonMark `******foo******` — excess-drop (6+6 → strong only)',
107    477 => 'CommonMark `_____foo_____` — excess-drop (5+5 → em+strong, 2 dropped each side)',
108
109    // Overlapping / crossing delimiters
110    478 => 'CommonMark `*foo _bar* baz_` — overlapping different delimiters',
111    479 => 'CommonMark `*foo __bar *baz bim__ bam*` — crossing delimiters',
112    480 => 'CommonMark `**foo **bar baz**` — overlapping same delimiter',
113
114    // --------------------------------------------------------------------
115    // Inline link `[text](url)` — features GfmLink deliberately does not
116    // implement. Either rarely-used syntax paid for with disproportionate
117    // regex complexity, or single-pass-lexer limits that can't be worked
118    // around inside one mode.
119    // --------------------------------------------------------------------
120
121    // GFM link title attribute (`"title"` / `'title'` / `(title)` after
122    // the URL). Parses cleanly but is discarded: DokuWiki's link handler
123    // instructions have no title-attribute slot, and plumbing one through
124    // every renderer is out of scope for GfmLink.
125    493 => 'link title attribute: GfmLink parses but discards — DokuWiki link instructions have no title slot',
126    513 => 'link title attribute (three quoting styles): discarded by GfmLink',
127    515 => 'link title separated by non-breaking space: title slot not supported',
128    516 => 'link title with nested balanced quotes: Markdown.pl quirk, not supported',
129    517 => 'link title with different quote type for inner quotes: title slot not supported',
130    518 => 'multi-line link title: title slot not supported',
131
132    // Pointy-bracket link destinations `<...>`. Rarely used; regex cost
133    // and interaction with raw-HTML detection outweigh the benefit.
134    496 => 'pointy-bracket link destination `<>`: not supported',
135    498 => 'pointy-bracket destination with spaces `<...>`: not supported',
136    500 => 'pointy-bracket destination with newline: not supported',
137    501 => 'pointy-bracket destination containing `)`: not supported',
138    502 => 'pointy-bracket destination with trailing backslash: not supported',
139    503 => 'malformed pointy-bracket destinations: renderer output differs',
140    507 => 'pointy-bracket destination wrapping unbalanced parens: not supported',
141
142    // Balanced-parens inside URL destinations.
143    505 => 'balanced-parens in URL destination: not supported (regex single-level)',
144
145    // Other URL-level edges.
146    495 => 'empty URL destination `[link]()`: pattern requires non-empty URL',
147    510 => 'backslash in URL destination: URL-encoding differs from spec',
148    511 => 'HTML entity / percent-encoding in URL: renderer normalization differs',
149    512 => 'link destination that parses as a title: edge case not supported',
150
151    // Inherent single-pass-lexer limits for link text containing nested
152    // structures. These cannot be resolved inside one mode.
153    522 => 'nested bracket forms inner link, outer falls back to literal',
154    526 => 'nested links: inner is a link, outer falls back to literal',
155    527 => 'nested links inside emphasis: not supported',
156    529 => 'link text grouping vs. emphasis: leftmost-match cannot override',
157    530 => 'emphasis/bracket crossing: leftmost-match cannot override',
158    532 => 'raw HTML inside link text: project-wide "no raw HTML" limit',
159    533 => 'code span inside link text: requires pre-scan pass (see #351)',
160    534 => 'autolink inside link text: raw `<URL>` autolinks not supported (see #356)',
161
162    // Reference links (`[text][id]`, `[text][]`, `[foo]` with matching
163    // `[foo]: url` definition). Not implemented: resolving forward
164    // references would require a two-pass parse, but DokuWiki's lexer is
165    // single-pass. Inline links `[text](url)` are the only supported
166    // form.
167    535 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
168    536 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
169    537 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
170    538 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
171    539 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
172    540 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
173    541 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
174    542 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
175    543 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
176    544 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
177    545 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
178    546 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
179    547 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
180    548 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
181    549 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
182    550 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
183    551 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
184    552 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
185    553 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
186    557 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
187    558 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
188    560 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
189    561 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)',
190    562 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)',
191    563 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)',
192    564 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)',
193    565 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
194    566 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
195    567 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
196    568 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
197    569 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
198    570 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
199    571 => 'shortcut reference link with escape: forward-reference definitions not supported (single-pass lexer)',
200    572 => 'shortcut reference link with emphasis: forward-reference definitions not supported (single-pass lexer)',
201    573 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
202    574 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
203    575 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
204    576 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
205    577 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
206    578 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
207    579 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
208
209    // --------------------------------------------------------------------
210    // Inline image `![alt](url)`. The XHTML renderer's default media
211    // rendering diverges from GFM's bare <img> (it wraps in a details <a>
212    // with fetch.php/detail.php proxy URLs) — GfmSpecTest uses
213    // SpecCompatRenderer to emit spec-shape bare <img>, so only the
214    // parser-level or feature-level gaps remain as skips: title attribute
215    // (no DW slot), reference images, pointy-bracket destinations, nested
216    // brackets, and escape-dependent cases.
217    // --------------------------------------------------------------------
218
219    580 => 'image with title attribute: GfmMedia discards titles (no DW slot)',
220    581 => 'reference-style image: forward-reference definitions not supported (single-pass lexer)',
221    582 => 'nested image-in-image `![foo ![bar](x)](y)`: alt class forbids brackets;'
222         . ' leftmost-match cannot reorder — outer falls back to literal (see #526)',
223    583 => 'link-in-image alt `![foo [bar](x)](y)`: alt class forbids brackets;'
224         . ' leftmost-match cannot reorder — outer falls back to literal (see #526)',
225    584 => 'collapsed reference-style image: forward-reference definitions not supported',
226    585 => 'full reference-style image: forward-reference definitions not supported',
227    587 => 'image with title attribute: title discarded (no DW slot)',
228    588 => 'pointy-bracket image destination `![alt](<url>)`: not supported (see GfmLink #496)',
229    590 => 'reference-style image: forward-reference definitions not supported',
230    591 => 'reference-style image (case-insensitive label): forward-reference definitions not supported',
231    592 => 'collapsed reference-style image `![foo][]`: forward-reference definitions not supported',
232    593 => 'collapsed reference-style image with emphasis in label: forward-reference definitions not supported',
233    594 => 'collapsed reference-style image (case-insensitive): forward-reference definitions not supported',
234    595 => 'reference-style image with intervening whitespace: forward-reference definitions not supported',
235    596 => 'shortcut reference-style image `![foo]`: forward-reference definitions not supported',
236    597 => 'shortcut reference-style image with emphasis: forward-reference definitions not supported',
237    598 => 'image with unescaped nested brackets `![[foo]]`: literal-fallback behavior not supported',
238    599 => 'shortcut reference-style image (case-insensitive): forward-reference definitions not supported',
239    600 => 'escape in image syntax `!\[foo]`: depends on GfmEscape (pending)',
240    601 => 'backslash-escape of `!` before link: depends on GfmEscape (pending)',
241
242    // --------------------------------------------------------------------
243    // ATX heading collisions with DokuWiki-specific behavior.
244    // --------------------------------------------------------------------
245    38 => 'ATX heading with leading spaces: GFM tolerates 0-3 spaces of'
246        . ' indent before the opener; we require the `#` at column 0.'
247        . ' Indent tolerance collides with DokuWiki\'s 2-space-indent'
248        . ' preformatted block and isn\'t worth untangling',
249    39 => 'indented code block: DokuWiki uses 2-space indent for'
250        . ' preformatted; GFM 4-space indented code blocks are not'
251        . ' implemented',
252    40 => 'indented code block: 4-space indent after a paragraph is a'
253        . ' continuation in GFM but preformatted in DokuWiki — not'
254        . ' implemented',
255    41 => 'ATX heading with leading spaces: second heading is indented'
256        . ' by 2 spaces; we require the `#` at column 0',
257    49 => 'empty ATX heading: DokuWiki\'s XHTML renderer deliberately'
258        . ' skips blank headings (blank() guard in Doku_Renderer_xhtml::header)',
259];
260