<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="/rss.xsl.xml"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
    <title>Changes in ModeRegistryTest.php</title>
    <description></description>
    <language>en</language>
    <copyright>Copyright 2025</copyright>
    <generator>Java</generator><item>
        <title>47a02a102092be9e1e6f1ddaf158bdfffdb13d4f - Parsing: make parse syntax a per-parse value, drop ModeInterface</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#47a02a102092be9e1e6f1ddaf158bdfffdb13d4f</link>
        <description>Parsing: make parse syntax a per-parse value, drop ModeInterfaceThe active parse&apos;s syntax flavour is a per-parse question, not process-global state: within a single request a plugin can render bundledDokuWiki-syntax text inside an otherwise-Markdown page. Yet ModeRegistrywas a singleton that read $conf[&apos;syntax&apos;] and the $PARSER_MODES global,and every mode reached it through ModeRegistry::getInstance() &#8212; so theflavour lived in shared mutable state that two parses in one requestwould fight over.Make the registry a short-lived value instead:- ModeRegistry is constructed once per parse with an explicit $syntax  and injected into Parser, Handler and every mode. getSyntax() /  isDwPreferred() / isMdPreferred() consult $this-&gt;syntax; the  DOKU_UNITTEST-gated mode-list cache hack is gone (each registry is  fresh, nothing to invalidate).- p_get_instructions() is now the single place in the pipeline where  $conf[&apos;syntax&apos;] is read; from there the flavour travels as a  parameter. No code under inc/Parsing/ reads $conf[&apos;syntax&apos;] directly  anymore &#8212; the five syntax-reading modes (Preformatted, GfmHr,  GfmEscape, Externallink, GfmQuote) route through $this-&gt;registry.Keep the two concepts apart, as documented in the ModeRegistry andAbstractMode docblocks: the user&apos;s configured *preference* stays in$conf[&apos;syntax&apos;] for UI code (toolbar, settings), while the activeparse&apos;s syntax is a parameter carried by the registry.$PARSER_MODES is demoted to a deprecated, read-only mirror, publishedduring loadPluginModes() &#8212; third-party syntax plugins (columnlist,alphalist2, phpwikify, skipentity) and the bundled info plugin read theglobal directly, often from their constructors, so the taxonomy muststay visible there. No core code reads the mirror.Fold ModeInterface into AbstractMode while here: getSort()/handle() areabstract, the connect callbacks carry defaults, and the public $Lexer&quot;FIXME should be done by setter&quot; becomes setLexer()/getLexer() injectedby Parser::addMode() alongside the registry. Nested-content resolutionmoves to the allowedCategories()/filterAllowedModes() hooks, resolvedonce when the registry is attached.Tests build their own parser/registry through ParserTestBase::setSyntax()instead of mutating $conf and calling the removed ModeRegistry::reset().

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Thu, 04 Jun 2026 12:27:59 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
<item>
        <title>13a62f810fbd091d15ab734b467eaec0a6bf829a - rename syntax flavors &apos;dokuwiki&apos; / &apos;markdown&apos; to &apos;dw&apos; / &apos;md&apos;</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#13a62f810fbd091d15ab734b467eaec0a6bf829a</link>
        <description>rename syntax flavors &apos;dokuwiki&apos; / &apos;markdown&apos; to &apos;dw&apos; / &apos;md&apos;Symmetry with the existing &apos;dw+md&apos; / &apos;md+dw&apos; setting values.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Mon, 04 May 2026 10:18:11 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>c4bcbc2e0c397783de26c1e3c211d82d1ac21bb4 - add GfmLinebreak for GFM hard line breaks</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#c4bcbc2e0c397783de26c1e3c211d82d1ac21bb4</link>
        <description>add GfmLinebreak for GFM hard line breaksTwo-or-more trailing spaces, or a single backslash, immediately beforea non-final newline render as a `&lt;br/&gt;`. Both delimiter forms share asingle SUBSTITION mode at sort 140, loaded under any MD-active syntax(markdown, dw+md, md+dw); pure dokuwiki is unaffected.Reuses the existing `linebreak` handler call and renderer; no newinstructions or renderer changes. SpecCompatRenderer overrideslinebreak() to emit the spec&apos;s `&lt;br /&gt;` shape. Examples 662, 663(line break inside a raw HTML tag) are skipped &#8212; raw HTML is notpassed through by default.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Mon, 04 May 2026 09:21:04 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>3e6baeff313fa406e4d4b5dd2e5ab85ec7d7816d - replace DW Hr with unified GfmHr</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#3e6baeff313fa406e4d4b5dd2e5ab85ec7d7816d</link>
        <description>replace DW Hr with unified GfmHrSingle mode covers both DokuWiki (4+ dashes) and GFM (3+ of -/*/_)horizontal rules; pattern self-narrows on $conf[&apos;syntax&apos;]. Alwaysloaded across all four syntax settings, mirroring the GfmQuotereplacement pattern. Same `hr` handler call so renderers and thecall API are unchanged.Drops DW&apos;s old [ \t]* leading-whitespace tolerance &#8212; inert inpractice past 0-1 spaces (Preformatted at sort 20 interceptseverything &#8805; 2 spaces or any tab).Spec examples 13, 20, 26-28, 224 turn green; 17, 21-24, 29, 30, 31go to skip.php as deliberate non-implementations (whitespacetolerance and list-precedence cases).

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Thu, 30 Apr 2026 13:14:27 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>309a08521b24a6fff00f318e061096f69771bbad - replace DW Quote with unified GfmQuote</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#309a08521b24a6fff00f318e061096f69771bbad</link>
        <description>replace DW Quote with unified GfmQuoteGfmQuote covers blockquote parsing for both DokuWiki and GFM dialectsin a single mode. Same quote_open/quote_close handler instructions; aDW-preferred post-pass flattens sub-parsed paragraph wrapping intolinebreak calls so existing pages keep their &lt;br/&gt;-between-linesrendering. MD-preferred keeps the &lt;p&gt;-wrapped spec shape.Block content (lists, fenced code, tables) inside `&gt;` quotes nowrenders, since the body is sub-parsed. Headers stay excluded(BASEONLY) &#8212; TOC and section-edit anchors don&apos;t compose with&lt;blockquote&gt;, same rationale as GfmListblock.Convert ModeRegistry&apos;s sub-parser cache into an acquire/release poolto support same-key re-entrancy: a list inside a quote re-entersgfm_quote during the list-item sub-parse, and the inner call needsits own parser instance even though the exclusion key matches.GfmListblock is updated to use the new acquire/release primitives.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Thu, 30 Apr 2026 11:58:30 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>74031e463764923581b9204cebc0fc3f34ce881f - add GfmEscape for GFM backslash escapes</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#74031e463764923581b9204cebc0fc3f34ce881f</link>
        <description>add GfmEscape for GFM backslash escapesImplements GFM &#167;6.1 backslash-escape handling. GfmEscape is a sort-5inline mode in CATEGORY_SUBSTITION that claims `\X` for any escapableASCII punctuation char before competing delimiters can match. Theshared character class lives on Helpers\Escape so the lexer patternand the post-hoc unescape stay in lockstep.Whole-span captures (GfmCode info string, GfmLink label/URL) bypassthe lexer; those modes call Escape::unescapeBackslashes() on therelevant slot. GfmLink skips the unescape when the URL classifies asa windowssharelink so the leading \\host survives intact.GfmTable cells get a separate per-cell `\|` to `|` pass in therewriter to honour the tables-extension rule that pipes alwaysunescape, even inside code spans where standard &#167;6.1 escapes don&apos;tfire.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Tue, 28 Apr 2026 17:08:30 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>3dabe4e0a0d70b79a7aced8ac8a36d4b37a61024 - add GfmTable for GFM tables</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#3dabe4e0a0d70b79a7aced8ac8a36d4b37a61024</link>
        <description>add GfmTable for GFM tablesImplements the GFM pipe-table extension as a CONTAINER mode at sort 55,one below DW Table at 60. A lookahead-validated entry pattern asserts aheader line plus a `:?-+:?` delimiter row before consuming any input, sonon-table paragraphs containing pipes flow through unchanged. Cells areinline-only per spec.Handler\GfmTable rewrites the flat token stream into the canonicaltable_open / tablethead_* / tabletbody_* / table_close sequence, derivingper-column alignment from the delimiter row, padding short body rows(spec 202), truncating long ones (spec 204), and falling back to a singlecdata when the column count mismatches (spec 203).`tabletbody_open` / `tabletbody_close` are emitted for the first time;they are part of the base renderer API but DW Table never used them.Added to Block&apos;s blockOpen / blockClose lists alongside `tabletfoot_*`for symmetry. SpecCompatRenderer gains minimal table-element overridesso spec roundtrip output matches GFM&apos;s `&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;` shapewithout DW&apos;s wrapper div, row/col counter classes, or align-as-class.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Tue, 28 Apr 2026 12:34:24 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>685560eb3044321b3bdd0be40985871ced5f1d05 - add GfmListblock for GFM lists</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#685560eb3044321b3bdd0be40985871ced5f1d05</link>
        <description>add GfmListblock for GFM listsGfmListblock captures an entire list block atomically with oneaddSpecialPattern match, then walks the captured text in handle()grouping lines into items. Each item&apos;s body is dedented to itscontent column and parsed by ModeRegistry::getSubParser() soblock content (paragraphs, fenced code, blockquotes, pluginblocks) works inside items uniformly. Sub-parsed calls are wrappedin a Nest call before they reach the outer handler, matching theFootnote pattern: the main handler&apos;s Block rewriter treats nestas opaque and the renderer base class unwraps it transparently,so multi-paragraph items don&apos;t get double-wrapped in &lt;p&gt;.Marker syntax: -, *, + (unordered) or 1-9 digits followed by. or ) (ordered). Indentation is a 2-space-multiple step startingat 0; depth = (indent / 2) + 1, odd indents round down, tabs becometwo spaces. The first ordered item&apos;s number drives the startattribute on &lt;ol&gt; via the listo_open $start parameter.GfmLists subclasses AbstractListsRewriter with the GFM markerparser; the state machine on the base class is shared with DW Lists.GfmListblock loads only when $conf[&apos;syntax&apos;] is markdown or md+dw.Under those settings the DW Listblock is suppressed because the twolist models conflict &#8212; DW&apos;s mandatory 2-space indent rule vs GFM&apos;szero-indent top-level rule, and -/*/+ markers shared. Plugins thatrelied on Listblock loading under md+dw will see it absent there.Sub-parser exclusion set: CATEGORY_BASEONLY (no Header inside listitems) and gfm_listblock itself (defensive guard against re-entryon pathological inputs; nested lists are handled by the outerpattern, not by re-entry).Tests cover marker variants, ordered start numbers, nested lists attwo and three levels, inline formatting inside items, marker-character switches keeping one list, type switches splitting thelist, fenced code inside items, multi-paragraph (loose) items, andtwo regressions on blank-line tolerance inside the captured block.SpecCompatRenderer learns to render the list call sequence, andspec.txt tests for digit/marker-width/lazy-continuation behaviorthat GfmListblock deliberately doesn&apos;t implement are documented ingfm-spec/skip.php with the per-bucket reasons (A-F).Drops two now-obsolete entries from skip.php (image escapes thatland via earlier GfmLink/GfmMedia work) and inlines the Setextexplanation that previously pointed at SPEC.md. Replaces theSPEC.md reference in GfmEmphasisTest with the inline reason.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Tue, 28 Apr 2026 06:23:11 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>9172eccff11a70df61d7aad697f84bbd815147ce - add sub-parser support to Handler / Parser / ModeRegistry</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#9172eccff11a70df61d7aad697f84bbd815147ce</link>
        <description>add sub-parser support to Handler / Parser / ModeRegistryA block mode that wants to parse the body of one of its capturedmatches needs a second Parser instance configured with the activemodes minus whatever would re-enter the outer mode. Doing this byhand is verbose and easy to get wrong &#8212; modes hold a $Lexer slotthat addMode() overwrites, so the same mode object can&apos;t be sharedbetween the main parser and a sub-parser.Three small additions:  Handler::reset() &#8212; clears calls, status, currentModeName, and  installs a fresh CallWriter. Lets one Handler instance be parsed  against repeatedly without state bleed.  Parser::getHandler() &#8212; accessor; sub-parser callers need it to  reach the handler for reset() and for harvesting the produced  call list.  ModeRegistry::getSubParser($excludeCategories, $excludeModes) &#8212;  returns a cached Parser preconfigured with every active mode  except those excluded. Mode objects are cloned before being  attached so connectTo()&apos;s assignment to $Lexer does not clobber  the main parser&apos;s references. Cache key is the exclusion-set;  default exclusion is CATEGORY_BASEONLY (no Header inside the  sub-parsed content).Tests cover Handler::reset&apos;s full clear, sub-parser caching,default and custom exclusions, registry-reset propagation, andthe clone-not-share invariant for $Lexer.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Tue, 28 Apr 2026 06:22:27 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>96d096f148d7def1456456590bd2910ff9115c0f - remove getLineStartMarkers registry &#8212; sort order already wins</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#96d096f148d7def1456456590bd2910ff9115c0f</link>
        <description>remove getLineStartMarkers registry &#8212; sort order already winsPreformatted&apos;s entry pattern carried a `(?![\*\-])` negativelookahead to defer to list modes on indented bullet lines.0cecf9d50 (2005, &quot;new parser added&quot;) introduced it hardcoded;7958e6980 (2026, &quot;decouple hardcoded mode names in Eol andPreformatted&quot;) refactored that hardcoded knowledge intoregister/getLineStartMarkers on ModeRegistry so each list modeowned its marker chars. Both preserved the behavior verbatim;neither documented why it was needed.Tracing the lexer, it isn&apos;t. ParallelRegex merges all entrypatterns into one PCRE expression; PCRE returns the leftmostmatch and breaks ties on expression order. Modes are added insort order via ModeRegistry::getModes(), so Listblock (sort 10)always precedes Preformatted (sort 20) and wins the tie on&quot;  - foo&quot; without any lookahead. The only test that caught adifference was testPreformattedList, which happened to registermodes in non-canonical order - that was a test bug.This patch drops the lookahead in Preformatted::connectTo, theregisterLineStartMarkers call in Listblock::preConnect, theregister/getLineStartMarkers methods on ModeRegistry, and thethree registry-API unit tests. testPreformattedList nowregisters Listblock before Preformatted.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Mon, 27 Apr 2026 14:36:55 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>781f5c717ce516c65e49ebc3c46ab298520231d3 - gate monospace, unformatted, file on DokuWiki syntax</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#781f5c717ce516c65e49ebc3c46ab298520231d3</link>
        <description>gate monospace, unformatted, file on DokuWiki syntaxThese DokuWiki specific modes should only be loaded when DokuWiki syntaxis still wanted, not in Markdown-only mode.Expands the ModeRegistryTest data provider to cover the full always-loadedand DW-always sets.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Thu, 23 Apr 2026 14:19:44 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>b1c59bed2e3645a1f5f11438cdbe7d1596f4a3a4 - add GfmCode / GfmFile for fenced code blocks</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#b1c59bed2e3645a1f5f11438cdbe7d1596f4a3a4</link>
        <description>add GfmCode / GfmFile for fenced code blocksGfmCode (backticks) emits the `code` handler instruction; GfmFile(tildes) emits `file`. Column-0 fences only, no length pairingbetween opener and closer, and unclosed fences stay literal &#8212;matching DokuWiki&apos;s `&lt;code&gt;` tag convention. The info string acceptsDW&apos;s full attribute vocabulary (language, filename, [options])through a new shared `Helpers::parseCodeAttributes` that `Code`also uses, with `html` aliased to `html4strict` and `-` meaning &quot;nolanguage&quot;.Preformatted&apos;s indent threshold is now preference-gated: 2 spacesin DW-preferred settings, 4 spaces in MD-preferred, matching GFM&apos;sindented code block rule. A single tab is a trigger in both.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Thu, 23 Apr 2026 14:01:03 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;andi@splitbrain.org&gt;</dc:creator>
    </item>
<item>
        <title>3440a8c07d59952439e180d2c33a32262fd3a84c - add GfmMedia and extend GfmLink with image-as-label form</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#3440a8c07d59952439e180d2c33a32262fd3a84c</link>
        <description>add GfmMedia and extend GfmLink with image-as-label form- New GfmMedia parses `![alt](url)` with the full DokuWiki media-parameter  vocabulary in the URL slot (?100x200, ?right, ?nolink, ?recache, &#8230;).  Adds `?left`/`?right`/`?center` align keywords shared with DW `{{&#8230;}}`  &#8212; gives pure-Markdown users a way to align inline images.- GfmLink now also matches `[![alt](img)](target)` &#8212; the GFM equivalent  of `[[target|{{img}}]]`. Detection is post-entry, mirroring  Internallink&apos;s `^{{&#8230;}}$` check; one mode covers the whole family.- LinkDispatch trait replaced by Helpers::classifyLink and  Helpers::parseMediaParameters &#8212; two pure static methods, shared by  DW and GFM counterparts.- Entry patterns for GfmLink / GfmMedia simplified (permissive URL slot,  handle-time parsing), following DW&apos;s Internallink style.- GfmSpecTest drives a test-only SpecCompatRenderer that emits bare  &lt;img&gt; / &lt;a&gt; instead of DW&apos;s wiki-wrapped HTML, recovering 13 spec  tests that previously failed/skipped only because of renderer shape.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Wed, 22 Apr 2026 14:28:30 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
<item>
        <title>e89aeebd5989e476b6a69236d9aabf72a9a01f14 - add GfmLink for GFM inline links `[text](url)`</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#e89aeebd5989e476b6a69236d9aabf72a9a01f14</link>
        <description>add GfmLink for GFM inline links `[text](url)`Extracts the URL-classification ladder from Internallink into aLinkDispatch trait so both modes route identically across all sixDokuWiki link flavors (internal, external, interwiki, email,windowsshare, local anchor). GfmLink parses the `[text](url)` formwith optional `&quot;title&quot;` / `&apos;title&apos;` and hands the URL to the trait.The GFM title attribute is discarded &#8212; DokuWiki link instructionshave no slot for it.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Wed, 22 Apr 2026 10:30:14 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
<item>
        <title>8719732d06ab7306149725c7c5ea71deb8ff0382 - add GfmHeader for ATX headings (`# text` through `###### text`)</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#8719732d06ab7306149725c7c5ea71deb8ff0382</link>
        <description>add GfmHeader for ATX headings (`# text` through `###### text`)Opener must sit at column 0. GFM tolerates 0-3 spaces before the `#`but that collides with DokuWiki&apos;s 2-space-indent preformatted block,so the tolerance is dropped rather than plumbed across modes.Widen the XHTML renderer&apos;s section-node tracker from 5 slots to 6 soh6 doesn&apos;t hit &quot;Undefined array key 5&quot;. Extend GfmSpecTest&apos;s HTMLnormalizer to strip DokuWiki&apos;s section-div wrappers, section-editcomments, and header id/class attributes so heading spec examplescan validate semantic correctness.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Wed, 22 Apr 2026 08:50:19 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
<item>
        <title>8ed75a23932353c18b43f67323808e9a662f532a - add GfmBacktickSingle / GfmBacktickDouble for GFM inline code spans</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#8ed75a23932353c18b43f67323808e9a662f532a</link>
        <description>add GfmBacktickSingle / GfmBacktickDouble for GFM inline code spansTwo new inline formatting modes covering GFM code spans in their n=1and n=2 forms:  GfmBacktickSingle   `text`    &#8594; &lt;code&gt;text&lt;/code&gt;  GfmBacktickDouble   ``text``  &#8594; &lt;code&gt;text&lt;/code&gt;Both emit monospace_open and monospace_close around an unformatted()call (the same instruction shape as DokuWiki&apos;s two-single-quote pairwrapping a nowiki span), so renderers that distinguish verbatim textfrom plain cdata &#8212; metadata, indexer, non-XHTML backends &#8212; treat thebody as literal.GfmBacktickDouble extends GfmBacktickSingle to reuse handle() and thebody-normalization helper; only the delimiter length and the bodycharacter class differ. Both share sort 165 and gate on Markdownbeing loaded.Design notes:* The lexer has no backreferences, so each length is its own mode.  Length-boundary guards (?&lt;!`)...(?!`) on every opener and closer  ensure a run of two-or-more backticks is never read as an n=1  delimiter and a run of three-or-more is never read as n=2. The two  modes never steal each other&apos;s input regardless of registration  order &#8212; sort can&apos;t reach this kind of cross-position constraint.* Edge-whitespace handling and newline normalization live in handle(),  not in the regex. On DOKU_LEXER_UNMATCHED the body is normalized:    1. CR/LF and LF become single spaces (GFM line-ending rule).    2. If the body starts and ends with a space and is not entirely       whitespace, one space is stripped from each end.  That produces the right GFM output for the tricky cases without  special-casing the entry pattern:    ` `          &#8594; &lt;code&gt; &lt;/code&gt;    (all-whitespace, no strip)    ` a`         &#8594; &lt;code&gt; a&lt;/code&gt;   (asymmetric, no strip)    ` `` `       &#8594; &lt;code&gt;``&lt;/code&gt;   (interior run-of-2 + strip)    ``foo`bar``  &#8594; &lt;code&gt;foo`bar&lt;/code&gt;* Body character classes admit exactly the runs that cannot be valid  closers for this mode&apos;s length: n=1 allows `[^`] | ``+`, n=2 allows  `[^`] | `(?!`)`. That is what lets a single-backtick span contain  a pair and a double-backtick span contain a lone backtick.* allowedModes is empty &#8212; no other inline parsing runs inside a span.Deliberately not implemented, with skip.php entries explaining why:  351 &#8212; code-span precedence over emphasis (*foo`*` expected to render        as *foo&lt;code&gt;*&lt;/code&gt;). Cross-positional: the single-pass        lexer matches leftmost-first and cannot reject an earlier        emphasis opener because a later backtick span would consume        its closer. A proper fix would need a pre-scan pass; sort        values only break ties at the same position.  353 &#8212; the trailing &quot; outside the code span gets converted to a        curly quote by DokuWiki typography, diverging from spec HTML.  354 &#8212; raw HTML tag pass-through; DokuWiki does not render raw HTML        by default.  356 &#8212; GFM angle-bracket autolink &lt;http://&#8230;&gt;: not implemented.Per-mode unit tests cover basic matching, flanking via the length-boundary guards, interior-run support in the body, edge-spacestripping, newline normalization, all-whitespace bodies, paragraph-boundary rejection, content-is-literal, and sort values.ModeRegistryTest&apos;s gating data provider picks up both modes.Net effect on GfmSpecTest: eleven previously-red code-span examplesnow pass (339, 340, 341, 342, 344, 345, 346, 347, 349, 350, 357, 359&#8212; the simple pairs, edge-space, interior-run, newline-normalization,and mismatched-run cases). Four skipped. Three remain pending outsidethe code-span scope (emphasis interactions that need GfmLink oncethat lands).

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Wed, 22 Apr 2026 07:39:11 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
<item>
        <title>0244be5c08829b6ca187d7158bca94e7c2fd7be3 - add GfmDeleted mode for GFM strikethrough (`~~text~~`)</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#0244be5c08829b6ca187d7158bca94e7c2fd7be3</link>
        <description>add GfmDeleted mode for GFM strikethrough (`~~text~~`)Shares the deleted_open/deleted_close instructions with DW&apos;s &lt;del&gt; mode.Entry/exit anchors `(?&lt;!~)` / `(?!~)` reject runs of three or more tildesso fenced-code markers remain untouched. Also trim redundant class-leveldocblocks on sibling Gfm test files.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Tue, 21 Apr 2026 13:52:10 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
<item>
        <title>2bb62bca317961d66fa2908b40f183af01402a91 - add GFM em-wrapping-strong modes for `***foo***` / `___foo___`</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#2bb62bca317961d66fa2908b40f183af01402a91</link>
        <description>add GFM em-wrapping-strong modes for `***foo***` / `___foo___`Two new inline formatting modes that render triple-delimiter runs asem wrapping strong:  GfmEmphasisStrong            `***text***`  &#8594; &lt;em&gt;&lt;strong&gt;text&lt;/strong&gt;&lt;/em&gt;  GfmEmphasisStrongUnderscore  `___text___`  &#8594; same (MD-preferred only)Only the exact 3+3 symmetric case is handled. The other long-run andasymmetric variants (4+4, 5+5, `***foo**`, etc.) require CommonMark&apos;sstack-based delimiter-pairing algorithm with its flanking andmultiple-of-3 rules, which is explicitly out of scope; those examplesstay skipped in gfm-spec/skip.php.Implementation notes:* Patterns enforce exact 3+3 via `(?&lt;!\*)` / `(?&lt;!_)` lookbehinds  (preventing entry at the second `*` of a `****...` run) and  `(?!\*)` / `(?!_)` lookaheads after the closing triple (rejecting  `***foo****` etc.). Combined with the existing non-whitespace  adjacency lookaheads, all asymmetric cases cleanly fall through to  other modes or stay literal.* GfmEmphasisStrong overrides handle() to emit two instructions on  entry (emphasis_open + strong_open) and two on exit (strong_close  + emphasis_close). GfmEmphasisStrongUnderscore inherits that  handler &#8212; only delimiters and word-boundary rules differ.* Sort 65 &#8212; below Strong (70) and GfmEmphasis (80) so the em+strong  modes win the lexer race for `***`/`___` runs. Underscore variant  is MD-preferred-only, matching the existing gating of  GfmEmphasisUnderscore and GfmStrongUnderscore.Per-mode unit tests cover basic matching, single-char bodies,whitespace flanking rejection, paragraph-boundary rejection,longer-run rejection, asymmetric rejection, multibyte intrawordprotection, and sort values. ModeRegistryTest&apos;s gating data providerpicks up the two new rules.Net effect on GfmSpecTest: example #476 (`***foo***`) now passes;473/474/475/477 remain skipped as documented in skip.php.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Mon, 20 Apr 2026 18:59:51 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
<item>
        <title>bcefb8ae61f4ff776efdbad9508c8ee8e5c548a6 - add GFM emphasis and underscore-delimited strong modes</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#bcefb8ae61f4ff776efdbad9508c8ee8e5c548a6</link>
        <description>add GFM emphasis and underscore-delimited strong modesThree new inline formatting modes for GitHub Flavored Markdown:  GfmEmphasis            `*text*`    &#8594; &lt;em&gt;  GfmEmphasisUnderscore  `_text_`    &#8594; &lt;em&gt;    (MD-preferred only)  GfmStrongUnderscore    `__text__`  &#8594; &lt;strong&gt; (MD-preferred only)All three emit the same handler instructions as DokuWiki&apos;s Emphasis /Strong, so existing renderers need no changes.Design notes:* Lexer mode names use snake_case (gfm_emphasis, gfm_emphasis_underscore,  gfm_strong_underscore) to keep PascalCase readable at the class level.  The asterisk variant emits `emphasis_open`/`emphasis_close` via the  getInstructionName() hook, so DW&apos;s Emphasis (`//...//`) and  GfmEmphasis (`*...*`) can coexist in mixed modes without a lexer  state collision while still producing the same &lt;em&gt; output.* Underscore variants gate on Markdown-preferred syntax (`markdown`,  `md+dw`) because `__` otherwise means DW underline. GfmStrongUnderscore  sorts at 70 (matching Strong) &#8212; below Underline at 90 &#8212; so when loaded  it wins the lexer race for `__` runs. Underline is already gated out  of MD-preferred modes in the previous commit.* Entry patterns enforce the simplified CommonMark flanking rules  already shared across DW inline modes (non-whitespace adjacency,  no paragraph-boundary crossing) plus the word-boundary check for  underscore variants using NO_WORD_BEFORE / NO_WORD_AFTER. The  positive non-word-char enumeration makes them multibyte-safe without  requiring the `u` flag: `f&#252;r_etwas` and `&#1087;&#1088;&#1080;&#1089;&#1090;&#1072;&#1085;&#1103;&#1084;_&#1089;&#1090;&#1088;&#1077;&#1084;&#1103;&#1090;&#1089;&#1103;_`  correctly stay literal.Per-mode unit tests cover basic matching, single-char bodies,leading/trailing-whitespace rejection, empty-delimiter rejection,paragraph-boundary rejection, multibyte intraword protection, andsort values. ModeRegistryTest&apos;s gating data provider picks up thethree new rules.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Mon, 20 Apr 2026 18:52:28 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
<item>
        <title>35f9143299d2dffbdd38bff583fc52ac73d8d4a3 - gate Underline on DokuWiki-preferred syntax; tidy registry plumbing</title>
        <link>http://127.0.0.1:8080/history/dokuwiki/_test/tests/Parsing/ModeRegistryTest.php#35f9143299d2dffbdd38bff583fc52ac73d8d4a3</link>
        <description>gate Underline on DokuWiki-preferred syntax; tidy registry plumbingThree related changes to ModeRegistry, prep work for the Markdown modesthat follow.1. Underline (`__text__`) is moved out of loadAlwaysModes() and into   loadDokuWikiModes(), gated on a new `\$dwPreferred` check that   evaluates true for &apos;dokuwiki&apos; and &apos;dw+md&apos;. In MD-preferred settings   (&apos;markdown&apos; and &apos;md+dw&apos;) `__` will mean GFM strong, so loading   Underline there would conflict at the lexer level. Underline is   unchanged in the default &apos;dokuwiki&apos; setting.2. resolveModeClass() now PascalCases every `_`-separated segment of   the mode name, so `gfm_emphasis_underscore` resolves to   `GfmEmphasisUnderscore`. Existing lowercase-compound names like   `internallink` still resolve to `Internallink` (one segment,   ucfirst-ed) &#8212; no behaviour change for current modes. This prepares   the registry to load Gfm mode classes whose PascalCase filenames   preserve word boundaries for readability.3. ModeRegistryTest&apos;s multiple near-identical per-mode gating tests   are consolidated into a single data-provider-driven   testModeLoadingBySyntax, fed by a `\$rules` table that lists each   mode against its four-setting expected load state. Adding a new   gated mode now means one line in the provider. Currently only   Underline is listed; upcoming Gfm-mode commits will add theirs.

            List of files:
            /dokuwiki/_test/tests/Parsing/ModeRegistryTest.php</description>
        <pubDate>Mon, 20 Apr 2026 18:49:39 +0000</pubDate>
        <dc:creator>Andreas Gohr &lt;gohr@cosmocode.de&gt;</dc:creator>
    </item>
</channel>
</rss>
