1be906b56SAndreas Gohr<?php 2be906b56SAndreas Gohr 3be906b56SAndreas Gohrnamespace dokuwiki\Parsing\ParserMode; 4be906b56SAndreas Gohr 571096e46SAndreas Gohruse dokuwiki\Parsing\Handler; 671096e46SAndreas Gohruse dokuwiki\Parsing\Handler\Nest; 7c8dd1b9dSAndreas Gohruse dokuwiki\Parsing\ModeRegistry; 8c8dd1b9dSAndreas Gohr 9be906b56SAndreas Gohrclass Footnote extends AbstractMode 10be906b56SAndreas Gohr{ 11*47a02a10SAndreas Gohr /** @inheritdoc */ 12*47a02a10SAndreas Gohr protected function allowedCategories(): array 13be906b56SAndreas Gohr { 14*47a02a10SAndreas Gohr return [ 15c8dd1b9dSAndreas Gohr ModeRegistry::CATEGORY_CONTAINER, 16c8dd1b9dSAndreas Gohr ModeRegistry::CATEGORY_FORMATTING, 1756c730b5SAndreas Gohr ModeRegistry::CATEGORY_SUBSTITUTION, 18c8dd1b9dSAndreas Gohr ModeRegistry::CATEGORY_PROTECTED, 19c8dd1b9dSAndreas Gohr ModeRegistry::CATEGORY_DISABLED, 20*47a02a10SAndreas Gohr ]; 21*47a02a10SAndreas Gohr } 22be906b56SAndreas Gohr 23*47a02a10SAndreas Gohr /** 24*47a02a10SAndreas Gohr * Footnotes cannot nest, so footnote is excluded from its own content. 25*47a02a10SAndreas Gohr * 26*47a02a10SAndreas Gohr * @inheritdoc 27*47a02a10SAndreas Gohr */ 28*47a02a10SAndreas Gohr protected function filterAllowedModes(array $modes): array 29*47a02a10SAndreas Gohr { 30*47a02a10SAndreas Gohr return array_values(array_filter($modes, static fn($m) => $m !== 'footnote')); 31be906b56SAndreas Gohr } 32be906b56SAndreas Gohr 33be906b56SAndreas Gohr /** @inheritdoc */ 3471096e46SAndreas Gohr public function getSort() 3571096e46SAndreas Gohr { 3671096e46SAndreas Gohr return 150; 3771096e46SAndreas Gohr } 3871096e46SAndreas Gohr 3971096e46SAndreas Gohr /** @inheritdoc */ 40be906b56SAndreas Gohr public function connectTo($mode) 41be906b56SAndreas Gohr { 42be906b56SAndreas Gohr $this->Lexer->addEntryPattern( 43be906b56SAndreas Gohr '\x28\x28(?=.*\x29\x29)', 44be906b56SAndreas Gohr $mode, 45be906b56SAndreas Gohr 'footnote' 46be906b56SAndreas Gohr ); 47be906b56SAndreas Gohr } 48be906b56SAndreas Gohr 49be906b56SAndreas Gohr /** @inheritdoc */ 50be906b56SAndreas Gohr public function postConnect() 51be906b56SAndreas Gohr { 52be906b56SAndreas Gohr $this->Lexer->addExitPattern( 53be906b56SAndreas Gohr '\x29\x29', 54be906b56SAndreas Gohr 'footnote' 55be906b56SAndreas Gohr ); 56be906b56SAndreas Gohr } 57be906b56SAndreas Gohr 58be906b56SAndreas Gohr /** @inheritdoc */ 5971096e46SAndreas Gohr public function handle($match, $state, $pos, Handler $handler) 60be906b56SAndreas Gohr { 6171096e46SAndreas Gohr switch ($state) { 6271096e46SAndreas Gohr case DOKU_LEXER_ENTER: 6371096e46SAndreas Gohr // footnotes can not be nested - however due to limitations in lexer it can't be prevented 6471096e46SAndreas Gohr // we will still enter a new footnote mode, we just do nothing 6571096e46SAndreas Gohr if ($handler->getStatus('footnote')) { 6671096e46SAndreas Gohr $handler->addCall('cdata', [$match], $pos); 6771096e46SAndreas Gohr break; 6871096e46SAndreas Gohr } 6971096e46SAndreas Gohr $handler->setStatus('footnote', true); 7071096e46SAndreas Gohr 7171096e46SAndreas Gohr $handler->setCallWriter(new Nest($handler->getCallWriter(), 'footnote_close')); 7271096e46SAndreas Gohr $handler->addCall('footnote_open', [], $pos); 7371096e46SAndreas Gohr break; 7471096e46SAndreas Gohr case DOKU_LEXER_EXIT: 7571096e46SAndreas Gohr // check whether we have already exited the footnote mode, can happen if the modes were nested 7671096e46SAndreas Gohr if (!$handler->getStatus('footnote')) { 7771096e46SAndreas Gohr $handler->addCall('cdata', [$match], $pos); 7871096e46SAndreas Gohr break; 7971096e46SAndreas Gohr } 8071096e46SAndreas Gohr 8171096e46SAndreas Gohr $handler->setStatus('footnote', false); 8271096e46SAndreas Gohr $handler->addCall('footnote_close', [], $pos); 8371096e46SAndreas Gohr 8471096e46SAndreas Gohr /** @var Nest $reWriter */ 8571096e46SAndreas Gohr $reWriter = $handler->getCallWriter(); 8671096e46SAndreas Gohr $handler->setCallWriter($reWriter->process()); 8771096e46SAndreas Gohr break; 8871096e46SAndreas Gohr case DOKU_LEXER_UNMATCHED: 8971096e46SAndreas Gohr $handler->addCall('cdata', [$match], $pos); 9071096e46SAndreas Gohr break; 9171096e46SAndreas Gohr } 9271096e46SAndreas Gohr return true; 93be906b56SAndreas Gohr } 94be906b56SAndreas Gohr} 95