1bcefb8aeSAndreas Gohr<?php 2bcefb8aeSAndreas Gohr 3bcefb8aeSAndreas Gohrnamespace dokuwiki\test\Parsing\ParserMode; 4bcefb8aeSAndreas Gohr 5bcefb8aeSAndreas Gohruse dokuwiki\Parsing\ParserMode\GfmEmphasis; 6bcefb8aeSAndreas Gohr 7bcefb8aeSAndreas Gohr/** 8bcefb8aeSAndreas Gohr * Tests for the GFM asterisk emphasis mode (`*text*`). 9bcefb8aeSAndreas Gohr */ 10bcefb8aeSAndreas Gohrclass GfmEmphasisTest extends ParserTestBase 11bcefb8aeSAndreas Gohr{ 12bcefb8aeSAndreas Gohr public function setUp(): void 13bcefb8aeSAndreas Gohr { 14bcefb8aeSAndreas Gohr parent::setUp(); 15*47a02a10SAndreas Gohr $this->setSyntax('md'); 16bcefb8aeSAndreas Gohr } 17bcefb8aeSAndreas Gohr 18bcefb8aeSAndreas Gohr function testBasicAsterisk() 19bcefb8aeSAndreas Gohr { 20bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 21bcefb8aeSAndreas Gohr $this->P->parse('Foo *Bar* Baz'); 22bcefb8aeSAndreas Gohr $calls = [ 23bcefb8aeSAndreas Gohr ['document_start', []], 24bcefb8aeSAndreas Gohr ['p_open', []], 25bcefb8aeSAndreas Gohr ['cdata', ["\nFoo "]], 26bcefb8aeSAndreas Gohr ['emphasis_open', []], 27bcefb8aeSAndreas Gohr ['cdata', ['Bar']], 28bcefb8aeSAndreas Gohr ['emphasis_close', []], 29bcefb8aeSAndreas Gohr ['cdata', [' Baz']], 30bcefb8aeSAndreas Gohr ['p_close', []], 31bcefb8aeSAndreas Gohr ['document_end', []], 32bcefb8aeSAndreas Gohr ]; 33bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 34bcefb8aeSAndreas Gohr } 35bcefb8aeSAndreas Gohr 36bcefb8aeSAndreas Gohr function testSingleCharacter() 37bcefb8aeSAndreas Gohr { 38bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 39bcefb8aeSAndreas Gohr $this->P->parse('foo *b* bar'); 40bcefb8aeSAndreas Gohr $calls = [ 41bcefb8aeSAndreas Gohr ['document_start', []], 42bcefb8aeSAndreas Gohr ['p_open', []], 43bcefb8aeSAndreas Gohr ['cdata', ["\nfoo "]], 44bcefb8aeSAndreas Gohr ['emphasis_open', []], 45bcefb8aeSAndreas Gohr ['cdata', ['b']], 46bcefb8aeSAndreas Gohr ['emphasis_close', []], 47bcefb8aeSAndreas Gohr ['cdata', [' bar']], 48bcefb8aeSAndreas Gohr ['p_close', []], 49bcefb8aeSAndreas Gohr ['document_end', []], 50bcefb8aeSAndreas Gohr ]; 51bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 52bcefb8aeSAndreas Gohr } 53bcefb8aeSAndreas Gohr 54bcefb8aeSAndreas Gohr function testMultipleWords() 55bcefb8aeSAndreas Gohr { 56bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 57bcefb8aeSAndreas Gohr $this->P->parse('*three four five*'); 58bcefb8aeSAndreas Gohr $calls = [ 59bcefb8aeSAndreas Gohr ['document_start', []], 60bcefb8aeSAndreas Gohr ['p_open', []], 61bcefb8aeSAndreas Gohr ['cdata', ["\n"]], 62bcefb8aeSAndreas Gohr ['emphasis_open', []], 63bcefb8aeSAndreas Gohr ['cdata', ['three four five']], 64bcefb8aeSAndreas Gohr ['emphasis_close', []], 65bcefb8aeSAndreas Gohr ['cdata', ['']], 66bcefb8aeSAndreas Gohr ['p_close', []], 67bcefb8aeSAndreas Gohr ['document_end', []], 68bcefb8aeSAndreas Gohr ]; 69bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 70bcefb8aeSAndreas Gohr } 71bcefb8aeSAndreas Gohr 72bcefb8aeSAndreas Gohr function testTwoSeparateEmphasisOnOneLine() 73bcefb8aeSAndreas Gohr { 74bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 75bcefb8aeSAndreas Gohr $this->P->parse('*one* and *two*'); 76bcefb8aeSAndreas Gohr $calls = [ 77bcefb8aeSAndreas Gohr ['document_start', []], 78bcefb8aeSAndreas Gohr ['p_open', []], 79bcefb8aeSAndreas Gohr ['cdata', ["\n"]], 80bcefb8aeSAndreas Gohr ['emphasis_open', []], 81bcefb8aeSAndreas Gohr ['cdata', ['one']], 82bcefb8aeSAndreas Gohr ['emphasis_close', []], 83bcefb8aeSAndreas Gohr ['cdata', [' and ']], 84bcefb8aeSAndreas Gohr ['emphasis_open', []], 85bcefb8aeSAndreas Gohr ['cdata', ['two']], 86bcefb8aeSAndreas Gohr ['emphasis_close', []], 87bcefb8aeSAndreas Gohr ['cdata', ['']], 88bcefb8aeSAndreas Gohr ['p_close', []], 89bcefb8aeSAndreas Gohr ['document_end', []], 90bcefb8aeSAndreas Gohr ]; 91bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 92bcefb8aeSAndreas Gohr } 93bcefb8aeSAndreas Gohr 94bcefb8aeSAndreas Gohr function testUnmatchedOpenerDoesNotEmphasise() 95bcefb8aeSAndreas Gohr { 96bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 97bcefb8aeSAndreas Gohr $this->P->parse('foo *bar with no closer'); 98bcefb8aeSAndreas Gohr $calls = [ 99bcefb8aeSAndreas Gohr ['document_start', []], 100bcefb8aeSAndreas Gohr ['p_open', []], 101bcefb8aeSAndreas Gohr ['cdata', ["\nfoo *bar with no closer"]], 102bcefb8aeSAndreas Gohr ['p_close', []], 103bcefb8aeSAndreas Gohr ['document_end', []], 104bcefb8aeSAndreas Gohr ]; 105bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 106bcefb8aeSAndreas Gohr } 107bcefb8aeSAndreas Gohr 108bcefb8aeSAndreas Gohr function testOpenerFollowedBySpaceDoesNotEmphasise() 109bcefb8aeSAndreas Gohr { 110bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 111bcefb8aeSAndreas Gohr $this->P->parse('foo * bar* baz'); 112bcefb8aeSAndreas Gohr $calls = [ 113bcefb8aeSAndreas Gohr ['document_start', []], 114bcefb8aeSAndreas Gohr ['p_open', []], 115bcefb8aeSAndreas Gohr ['cdata', ["\nfoo * bar* baz"]], 116bcefb8aeSAndreas Gohr ['p_close', []], 117bcefb8aeSAndreas Gohr ['document_end', []], 118bcefb8aeSAndreas Gohr ]; 119bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 120bcefb8aeSAndreas Gohr } 121bcefb8aeSAndreas Gohr 122bcefb8aeSAndreas Gohr function testEmptyDelimiterDoesNotEmphasise() 123bcefb8aeSAndreas Gohr { 124bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 125bcefb8aeSAndreas Gohr $this->P->parse('foo ** bar'); 126bcefb8aeSAndreas Gohr $calls = [ 127bcefb8aeSAndreas Gohr ['document_start', []], 128bcefb8aeSAndreas Gohr ['p_open', []], 129bcefb8aeSAndreas Gohr ['cdata', ["\nfoo ** bar"]], 130bcefb8aeSAndreas Gohr ['p_close', []], 131bcefb8aeSAndreas Gohr ['document_end', []], 132bcefb8aeSAndreas Gohr ]; 133bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 134bcefb8aeSAndreas Gohr } 135bcefb8aeSAndreas Gohr 136bcefb8aeSAndreas Gohr function testUnderscoreIsNotEmphasised() 137bcefb8aeSAndreas Gohr { 138bcefb8aeSAndreas Gohr // GfmEmphasis handles `*` only — `_` is reserved to avoid the 139685560ebSAndreas Gohr // `__underline__` conflict with DokuWiki's underline syntax; 140685560ebSAndreas Gohr // GfmEmphasisUnderscore handles `_` separately when MD-preferred. 141bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 142bcefb8aeSAndreas Gohr $this->P->parse('foo _bar_ baz'); 143bcefb8aeSAndreas Gohr $calls = [ 144bcefb8aeSAndreas Gohr ['document_start', []], 145bcefb8aeSAndreas Gohr ['p_open', []], 146bcefb8aeSAndreas Gohr ['cdata', ["\nfoo _bar_ baz"]], 147bcefb8aeSAndreas Gohr ['p_close', []], 148bcefb8aeSAndreas Gohr ['document_end', []], 149bcefb8aeSAndreas Gohr ]; 150bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 151bcefb8aeSAndreas Gohr } 152bcefb8aeSAndreas Gohr 153bcefb8aeSAndreas Gohr function testMultilineEmphasis() 154bcefb8aeSAndreas Gohr { 155bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 156bcefb8aeSAndreas Gohr $this->P->parse("*line\nline\nline*"); 157bcefb8aeSAndreas Gohr $calls = [ 158bcefb8aeSAndreas Gohr ['document_start', []], 159bcefb8aeSAndreas Gohr ['p_open', []], 160bcefb8aeSAndreas Gohr ['cdata', ["\n"]], 161bcefb8aeSAndreas Gohr ['emphasis_open', []], 162bcefb8aeSAndreas Gohr ['cdata', ["line\nline\nline"]], 163bcefb8aeSAndreas Gohr ['emphasis_close', []], 164bcefb8aeSAndreas Gohr ['cdata', ['']], 165bcefb8aeSAndreas Gohr ['p_close', []], 166bcefb8aeSAndreas Gohr ['document_end', []], 167bcefb8aeSAndreas Gohr ]; 168bcefb8aeSAndreas Gohr $this->assertCalls($calls, $this->H->calls); 169bcefb8aeSAndreas Gohr } 170bcefb8aeSAndreas Gohr 171bcefb8aeSAndreas Gohr function testModeNameIsDistinctFromInstructionName() 172bcefb8aeSAndreas Gohr { 173bcefb8aeSAndreas Gohr // The lexer mode is registered as 'gfm_emphasis' (to avoid collision 174bcefb8aeSAndreas Gohr // with DW Emphasis), but instructions are 'emphasis_open/close' 175bcefb8aeSAndreas Gohr // so the existing XHTML renderer emits <em>. 176bcefb8aeSAndreas Gohr $mode = new GfmEmphasis(); 177bcefb8aeSAndreas Gohr $this->assertSame(80, $mode->getSort()); 178bcefb8aeSAndreas Gohr } 179bcefb8aeSAndreas Gohr 180bcefb8aeSAndreas Gohr function testDoesNotSpanParagraphBoundary() 181bcefb8aeSAndreas Gohr { 182bcefb8aeSAndreas Gohr // An unclosed `*` followed by a blank line must stay literal — the 183bcefb8aeSAndreas Gohr // entry pattern's lookahead is paragraph-boundary-safe. 184bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 185bcefb8aeSAndreas Gohr $this->P->parse("*open\n\nclose*"); 186bcefb8aeSAndreas Gohr $modes = array_column($this->H->calls, 0); 187bcefb8aeSAndreas Gohr $this->assertNotContains('emphasis_open', $modes, 188bcefb8aeSAndreas Gohr 'GfmEmphasis must not open when the closing `*` is past a blank line'); 189bcefb8aeSAndreas Gohr } 190bcefb8aeSAndreas Gohr 191bcefb8aeSAndreas Gohr function testAllowsSingleNewline() 192bcefb8aeSAndreas Gohr { 193bcefb8aeSAndreas Gohr // Single newlines are fine inside emphasis (multi-line emphasis). 194bcefb8aeSAndreas Gohr $this->P->addMode('gfm_emphasis', new GfmEmphasis()); 195bcefb8aeSAndreas Gohr $this->P->parse("*open\nclose*"); 196bcefb8aeSAndreas Gohr $modes = array_column($this->H->calls, 0); 197bcefb8aeSAndreas Gohr $this->assertContains('emphasis_open', $modes, 198bcefb8aeSAndreas Gohr 'GfmEmphasis must still match across a single newline'); 199bcefb8aeSAndreas Gohr } 200bcefb8aeSAndreas Gohr} 201