xref: /dokuwiki/_test/tests/Parsing/Markdown/gfm-spec/skip.php (revision b414dba2b10d2f550b453d752c86bb62343bec93)
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 `&lt;`',
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    493 => 'link title attribute: GfmLink parses but discards — DokuWiki link instructions have no title slot',
372    513 => 'link title attribute (three quoting styles): discarded by GfmLink',
373    515 => 'link title separated by non-breaking space: title slot not supported',
374    516 => 'link title with nested balanced quotes: Markdown.pl quirk, not supported',
375    517 => 'link title with different quote type for inner quotes: title slot not supported',
376    518 => 'multi-line link title: title slot not supported',
377
378    // Pointy-bracket link destinations `<...>`. Rarely used; regex cost
379    // and interaction with raw-HTML detection outweigh the benefit.
380    496 => 'pointy-bracket link destination `<>`: not supported',
381    498 => 'pointy-bracket destination with spaces `<...>`: not supported',
382    500 => 'pointy-bracket destination with newline: not supported',
383    501 => 'pointy-bracket destination containing `)`: not supported',
384    502 => 'pointy-bracket destination with trailing backslash: not supported',
385    503 => 'malformed pointy-bracket destinations: renderer output differs',
386    507 => 'pointy-bracket destination wrapping unbalanced parens: not supported',
387
388    // Balanced-parens inside URL destinations.
389    505 => 'balanced-parens in URL destination: not supported (regex single-level)',
390
391    // Other URL-level edges.
392    495 => 'empty URL destination `[link]()`: pattern requires non-empty URL',
393    510 => 'backslash in URL destination: URL-encoding differs from spec',
394    511 => 'HTML entity / percent-encoding in URL: renderer normalization differs',
395    512 => 'link destination that parses as a title: edge case not supported',
396    337 => 'entity-decoded `&quot;` inside link URL slot: spec rejects the'
397         . ' link because the decoded `"` would split URL from title, but'
398         . ' GfmLink uses a permissive `[^)\n]+` URL slot and accepts the'
399         . ' whole run as the URL — strict GFM URL rejection not implemented',
400
401    // Inherent single-pass-lexer limits for link text containing nested
402    // structures. These cannot be resolved inside one mode.
403    522 => 'nested bracket forms inner link, outer falls back to literal',
404    526 => 'nested links: inner is a link, outer falls back to literal',
405    527 => 'nested links inside emphasis: not supported',
406    529 => 'link text grouping vs. emphasis: leftmost-match cannot override',
407    530 => 'emphasis/bracket crossing: leftmost-match cannot override',
408    532 => 'raw HTML inside link text: project-wide "no raw HTML" limit',
409    533 => 'code span inside link text: requires pre-scan pass (see #351)',
410    534 => 'autolink inside link text: raw `<URL>` autolinks not supported (see #356)',
411
412    // Reference links (`[text][id]`, `[text][]`, `[foo]` with matching
413    // `[foo]: url` definition). Not implemented: resolving forward
414    // references would require a two-pass parse, but DokuWiki's lexer is
415    // single-pass. Inline links `[text](url)` are the only supported
416    // form.
417    535 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
418    536 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
419    537 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
420    538 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
421    539 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
422    540 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
423    541 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
424    542 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
425    543 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
426    544 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
427    545 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
428    546 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
429    547 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
430    548 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
431    549 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
432    550 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
433    551 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
434    552 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
435    553 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
436    557 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
437    558 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
438    560 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
439    561 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)',
440    562 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)',
441    563 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)',
442    564 => 'collapsed reference link: forward-reference definitions not supported (single-pass lexer)',
443    565 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
444    566 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
445    567 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
446    568 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
447    569 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
448    570 => 'shortcut reference link: forward-reference definitions not supported (single-pass lexer)',
449    571 => 'shortcut reference link with escape: forward-reference definitions not supported (single-pass lexer)',
450    572 => 'shortcut reference link with emphasis: forward-reference definitions not supported (single-pass lexer)',
451    573 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
452    574 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
453    575 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
454    576 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
455    577 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
456    578 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
457    579 => 'reference link: forward-reference definitions not supported (single-pass lexer)',
458
459    // --------------------------------------------------------------------
460    // Inline image `![alt](url)`. The XHTML renderer's default media
461    // rendering diverges from GFM's bare <img> (it wraps in a details <a>
462    // with fetch.php/detail.php proxy URLs) — GfmSpecTest uses
463    // SpecCompatRenderer to emit spec-shape bare <img>, so only the
464    // parser-level or feature-level gaps remain as skips: title attribute
465    // (no DW slot), reference images, pointy-bracket destinations, nested
466    // brackets, and escape-dependent cases.
467    // --------------------------------------------------------------------
468
469    580 => 'image with title attribute: GfmMedia discards titles (no DW slot)',
470    581 => 'reference-style image: forward-reference definitions not supported (single-pass lexer)',
471    582 => 'nested image-in-image `![foo ![bar](x)](y)`: alt class forbids brackets;'
472         . ' leftmost-match cannot reorder — outer falls back to literal (see #526)',
473    583 => 'link-in-image alt `![foo [bar](x)](y)`: alt class forbids brackets;'
474         . ' leftmost-match cannot reorder — outer falls back to literal (see #526)',
475    584 => 'collapsed reference-style image: forward-reference definitions not supported',
476    585 => 'full reference-style image: forward-reference definitions not supported',
477    587 => 'image with title attribute: title discarded (no DW slot)',
478    588 => 'pointy-bracket image destination `![alt](<url>)`: not supported (see GfmLink #496)',
479    590 => 'reference-style image: forward-reference definitions not supported',
480    591 => 'reference-style image (case-insensitive label): forward-reference definitions not supported',
481    592 => 'collapsed reference-style image `![foo][]`: forward-reference definitions not supported',
482    593 => 'collapsed reference-style image with emphasis in label: forward-reference definitions not supported',
483    594 => 'collapsed reference-style image (case-insensitive): forward-reference definitions not supported',
484    595 => 'reference-style image with intervening whitespace: forward-reference definitions not supported',
485    596 => 'shortcut reference-style image `![foo]`: forward-reference definitions not supported',
486    597 => 'shortcut reference-style image with emphasis: forward-reference definitions not supported',
487    598 => 'image with unescaped nested brackets `![[foo]]`: literal-fallback behavior not supported',
488    599 => 'shortcut reference-style image (case-insensitive): forward-reference definitions not supported',
489    600 => 'image-via-reference fallback `!\[foo]` with `[foo]: /url`: forward-reference definitions not supported (single-pass lexer)',
490    601 => 'image-via-reference fallback `\![foo]` with `[foo]: /url`: forward-reference definitions not supported (single-pass lexer)',
491
492    // --------------------------------------------------------------------
493    // ATX heading collisions with DokuWiki-specific behavior.
494    // --------------------------------------------------------------------
495    38 => 'ATX heading with leading spaces: GFM tolerates 0-3 spaces of'
496        . ' indent before the opener; we require the `#` at column 0.'
497        . ' Indent tolerance collides with DokuWiki\'s 2-space-indent'
498        . ' preformatted block and isn\'t worth untangling',
499    39 => 'indented code block: DokuWiki uses 2-space indent for'
500        . ' preformatted; GFM 4-space indented code blocks are not'
501        . ' implemented',
502    40 => 'indented code block: 4-space indent after a paragraph is a'
503        . ' continuation in GFM but preformatted in DokuWiki — not'
504        . ' implemented',
505    41 => 'ATX heading with leading spaces: second heading is indented'
506        . ' by 2 spaces; we require the `#` at column 0',
507    49 => 'empty ATX heading: DokuWiki\'s XHTML renderer deliberately'
508        . ' skips blank headings (blank() guard in Doku_Renderer_xhtml::header)',
509
510    // --------------------------------------------------------------------
511    // List items / Lists — list features GfmListblock deliberately does
512    // not implement. The simplifications are by design: indentation uses
513    // a fixed 2-space-multiple step starting at 0, lazy continuation is
514    // not supported, and the rewriter groups items by 'u'/'o' type only.
515    // The buckets are:
516    //
517    //  A. Extra spaces after the marker. CommonMark rolls them (up to
518    //     4) into the content column; we dedent at `marker_width + 1`,
519    //     collapsing the extras.
520    //  B. 1- or 3-space indent for nesting (we round down to nearest 2).
521    //  C. Lazy continuation (column-0 paragraph wrap inside an item).
522    //  D. Strict CommonMark loose/tight classification (every blank line
523    //     between items / inside items reclassifies; we use a simpler
524    //     single-paragraph-tight, multi-paragraph-loose rule).
525    //  E. Marker-character-change splits ordered lists ('.' vs ')') or
526    //     unordered ('-' vs '+' vs '*'). Our rewriter groups by 'u' / 'o'
527    //     type only, not by marker character.
528    //  F. List interrupting a paragraph without a blank line — requires a
529    //     multi-pass block parser to revisit prior text.
530    //
531    // Examples that depend on a pending mode (GfmQuote, GfmEscape, …) are
532    // intentionally NOT skipped — they remain visible failing tests until
533    // the mode lands.
534    // --------------------------------------------------------------------
535    // --------------------------------------------------------------------
536    // Block quotes — deliberate scope reductions vs. strict GFM. The
537    // unified GfmQuote mode (replacing DW Quote) covers `>` blockquotes
538    // for both DW and MD pages, but several CommonMark blockquote rules
539    // are out of scope:
540    //
541    // - 1-3 space indent before `>` (column-0-only policy, consistent
542    //   with GfmCode / GfmFile / GfmHeader).
543    // - Lazy continuation (paragraph text without `>` on continuation
544    //   lines). Same policy as GfmListblock — markers required on
545    //   every line.
546    // - Headers inside quotes — sub-parser excludes BASEONLY so header
547    //   instructions don't drive TOC/section-edit anchors that don't
548    //   compose with `<blockquote>`. Same rationale as GfmListblock's
549    //   header exclusion inside list items.
550    // - Setext-style block constructs (the `---` underline collides
551    //   with DW's HR rule).
552    //
553    // Examples that depend on still-pending modes (GfmHr) are
554    // intentionally NOT skipped — they stay visible until those modes
555    // land.
556    // --------------------------------------------------------------------
557    206 => 'block quotes: header inside quote — sub-parser excludes'
558         . ' BASEONLY (TOC / section-edit anchors do not compose with'
559         . ' `<blockquote>`). Same policy as GfmListblock for `<li>`.',
560    207 => 'block quotes: header inside quote with no space after `>` —'
561         . ' see #206 for the BASEONLY exclusion rationale.',
562    208 => 'block quotes: leading-space `>` (1-3 spaces of indent) —'
563         . ' column-0-only policy, consistent with GfmCode / GfmFile.',
564    210 => 'block quotes: lazy continuation `> # Foo\n> bar\nbaz` —'
565         . ' every quote line must begin with `>` at column 0. Same'
566         . ' policy as GfmListblock.',
567    211 => 'block quotes: lazy continuation `> bar\nbaz\n> foo` —'
568         . ' see #210.',
569    212 => 'block quotes: Setext heading underline `---` after `> foo`'
570         . ' — no Setext headings (the `---` collides with DW HR syntax).',
571    215 => 'block quotes: fenced code block split across blockquote'
572         . ' boundary — fence inside quote followed by non-`>` lines'
573         . ' depends on the same lazy-continuation rule we do not'
574         . ' implement (see #210).',
575    216 => 'block quotes: lazy continuation `> foo\n    - bar` — see #210.',
576    225 => 'block quotes: lazy continuation `> bar\nbaz` — see #210.',
577    227 => 'block quotes: lazy continuation `> bar\n>\nbaz` — see #210.',
578    228 => 'block quotes: lazy continuation in nested quote'
579         . ' `> > > foo\nbar` — see #210.',
580    229 => 'block quotes: lazy continuation across nested levels'
581         . ' `>>> foo\n> bar\n>>baz` — see #210.',
582
583    232 => 'list items: marker-width content-column alignment (A)',
584    235 => 'list items: marker-width content-column alignment (A)',
585    249 => 'list items: marker-width-driven content-column alignment for `10. foo` (A)',
586    254 => 'list items: marker-width content-column alignment edge case (A)',
587    258 => 'list items: marker-width content-column for `1.  foo` (A)',
588    263 => 'list items: indent ambiguity at column 0/1/2 (B)',
589    264 => 'list items: 1-space-indent variation (B)',
590    265 => 'list items: marker-width with multi-line continuation (A)',
591    266 => 'list items: marker-width with multi-line continuation (A)',
592    267 => 'list items: lazy continuation (C)',
593    268 => 'list items: lazy continuation (C)',
594    270 => 'list items: lazy continuation across blank line (C+D)',
595    273 => 'list items: list interrupting a paragraph without blank line (F)',
596    275 => 'list items: 3-space indent rounds to 2 — sub-list under previous item (B)',
597    276 => 'list items: marker-width content-column with mixed types (A+E)',
598    277 => 'list items: nested markers on a single line (A)',
599    278 => 'list items: marker-character switch splits the list (E)',
600    281 => 'lists: marker-character change splits unordered list `-` -> `+` (E)',
601    282 => 'lists: ordered delimiter switch splits list `.` -> `)` (E)',
602    284 => 'lists: list interrupting paragraph without blank line (F)',
603    286 => 'lists: marker-width content-column alignment for ordered list (A)',
604    287 => 'lists: triple blank line + indented continuation in deeply nested item (D)',
605    288 => 'lists: marker-character change at deeper level (E)',
606    289 => 'lists: marker-character change with type switch (E)',
607    290 => 'lists: 1-space-indent variations of items, all stay top-level (B)',
608    291 => 'lists: 1-space-indent variations on ordered list (B)',
609    292 => 'lists: marker-character change splits inside nested list (E)',
610    293 => 'lists: marker-character change with mixed indent (E+B)',
611    294 => 'lists: lazy continuation across types (C+E)',
612    295 => 'lists: lazy continuation in nested list (C)',
613    296 => 'lists: lazy continuation across blank line (C+D)',
614    297 => 'lists: blank-line classification for loose/tight in nested list (D)',
615    298 => 'lists: blank-line classification (D)',
616    300 => 'lists: blank-line classification with marker change (D+E)',
617    301 => 'lists: blank-line classification + marker-width alignment (D+A)',
618    304 => 'lists: blank line between sub-list items affects loose/tight (D)',
619    305 => 'lists: blank line between deeply nested items (D)',
620    306 => 'lists: blank line at the end of a loose list affects classification (D)',
621
622    // --------------------------------------------------------------------
623    // Backslash-escape examples (§6.1) that fail for reasons unrelated to
624    // GfmEscape itself: renderer divergences, typography conversion, and
625    // already-skipped GFM features (autolinks, raw HTML, reference links,
626    // discarded link titles). The escape mechanic itself works.
627    // --------------------------------------------------------------------
628    308 => 'backslash escapes: apostrophe is rendered as `&#039;` by DW while'
629         . ' the spec expects a literal `\'` — renderer policy difference,'
630         . ' not an escape bug',
631    310 => 'backslash escapes: DW typography converts straight `"..."` to curly'
632         . ' quotes when $conf[typography] is on, diverging from spec output',
633    316 => 'backslash escapes inside angle-bracket autolinks: GFM autolink'
634         . ' `<URL>` form not implemented (see example 356)',
635    317 => 'backslash escapes inside raw HTML: raw HTML pass-through is not'
636         . ' supported by default (see example 354)',
637    318 => 'backslash escapes in link title: title attribute is discarded — DW'
638         . ' link instructions have no title slot',
639    319 => 'backslash escapes in reference-link definition: link reference'
640         . ' definitions not supported (single-pass lexer cannot resolve'
641         . ' forward references)',
642
643    // --------------------------------------------------------------------
644    // Raw HTML (§6.6) — inline raw HTML pass-through. Same project-wide
645    // decision as HTML blocks (#118-160): DokuWiki escapes `<` as `&lt;`
646    // by default; the `<html>` block is the opt-in. Examples #637 and
647    // #640 are intentionally NOT listed — the spec there expects literal
648    // `&lt;...&gt;` escaping for malformed tags, which DW also produces,
649    // so they pass naturally.
650    // --------------------------------------------------------------------
651    632 => 'raw HTML inline (open tag): raw HTML pass-through not supported',
652    633 => 'raw HTML inline (closing tag): raw HTML pass-through not supported',
653    634 => 'raw HTML inline (multi-line attributes): raw HTML pass-through not supported',
654    635 => 'raw HTML inline (line breaks in attributes): raw HTML pass-through not supported',
655    636 => 'raw HTML inline (custom tags / attribute syntax): raw HTML pass-through not supported',
656    638 => 'raw HTML inline (illegal attribute names): raw HTML pass-through not supported',
657    639 => 'raw HTML inline (illegal attribute values): raw HTML pass-through not supported',
658    641 => 'raw HTML inline (open and closing tags): raw HTML pass-through not supported',
659    642 => 'raw HTML inline (HTML comment): raw HTML pass-through not supported',
660    643 => 'raw HTML inline (invalid comment): raw HTML pass-through not supported',
661    644 => 'raw HTML inline (processing instruction): raw HTML pass-through not supported',
662    645 => 'raw HTML inline (declaration): raw HTML pass-through not supported',
663    646 => 'raw HTML inline (declaration single-letter name): raw HTML pass-through not supported',
664    647 => 'raw HTML inline (declaration EMPTY): raw HTML pass-through not supported',
665    648 => 'raw HTML inline (CDATA section): raw HTML pass-through not supported',
666    649 => 'raw HTML inline (entity reference inside attribute): raw HTML pass-through not supported',
667    650 => 'raw HTML inline (backslash escape inside attribute): raw HTML pass-through not supported',
668    651 => 'raw HTML inline (entity-escaped quote inside attribute): raw HTML pass-through not supported',
669
670    // --------------------------------------------------------------------
671    // Hard line breaks (GfmLinebreak) — both delimiter forms (two trailing
672    // spaces and `\` before newline) work in paragraphs, emphasis, and
673    // other inline containers. The skipped cases sit inside raw HTML tags,
674    // which DokuWiki does not pass through by default.
675    // --------------------------------------------------------------------
676    662 => 'hard line break inside a raw HTML tag: raw HTML pass-through not supported',
677    663 => 'hard line break (backslash form) inside a raw HTML tag — see'
678         . ' #662. Raw HTML out of scope.',
679];
680