1b7c79e2bSDaniel Hofer<?php 2*55913da9SDaniel Hofer 3b7c79e2bSDaniel Hofer/** 4b7c79e2bSDaniel Hofer * DokuWiki Plugin autonumbering (Action Component) 5b7c79e2bSDaniel Hofer * 6b7c79e2bSDaniel Hofer * Adds autonumbering support for DokuWiki headings. 7b7c79e2bSDaniel Hofer * 8b7c79e2bSDaniel Hofer * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 9b7c79e2bSDaniel Hofer */ 10b7c79e2bSDaniel Hofer 11*55913da9SDaniel Hofer// phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols 12b7c79e2bSDaniel Hoferuse dokuwiki\Extension\ActionPlugin; 13b7c79e2bSDaniel Hoferuse dokuwiki\Extension\Event; 14b7c79e2bSDaniel Hoferuse dokuwiki\Extension\EventHandler; 15b7c79e2bSDaniel Hofer 16b7c79e2bSDaniel Hofer// must be run within DokuWiki 17*55913da9SDaniel Hoferif (!defined('DOKU_INC')) { 18*55913da9SDaniel Hofer die(); 19*55913da9SDaniel Hofer} 20*55913da9SDaniel Hofer// phpcs:enable 21b7c79e2bSDaniel Hofer 22b7c79e2bSDaniel Hoferclass action_plugin_autonumbering extends ActionPlugin 23b7c79e2bSDaniel Hofer{ 24b7c79e2bSDaniel Hofer /** 25b7c79e2bSDaniel Hofer * @inheritDoc 26b7c79e2bSDaniel Hofer */ 27b7c79e2bSDaniel Hofer public function register(EventHandler $controller) 28b7c79e2bSDaniel Hofer { 29b7c79e2bSDaniel Hofer $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'numberHeaders'); 30b7c79e2bSDaniel Hofer } 31b7c79e2bSDaniel Hofer 32b7c79e2bSDaniel Hofer /** 33b7c79e2bSDaniel Hofer * Rebuild autonumbering calls in document order and replace heading markers. 34b7c79e2bSDaniel Hofer * 35b7c79e2bSDaniel Hofer * DokuWiki headings are parsed as plain header calls, so syntax plugins are 36b7c79e2bSDaniel Hofer * not evaluated inside them. Walking the final instruction list keeps heading 37b7c79e2bSDaniel Hofer * and body counters in the same order. 38b7c79e2bSDaniel Hofer * 39b7c79e2bSDaniel Hofer * @param Event $event Event object 40b7c79e2bSDaniel Hofer * @param mixed $param optional parameter passed when the event was registered 41b7c79e2bSDaniel Hofer * @return void 42b7c79e2bSDaniel Hofer */ 43b7c79e2bSDaniel Hofer public function numberHeaders(Event $event, $param) 44b7c79e2bSDaniel Hofer { 45b7c79e2bSDaniel Hofer if (!$event->data instanceof Doku_Handler) { 46b7c79e2bSDaniel Hofer return; 47b7c79e2bSDaniel Hofer } 48b7c79e2bSDaniel Hofer 49b7c79e2bSDaniel Hofer global $COUNTER; 50b7c79e2bSDaniel Hofer $COUNTER = []; 51b7c79e2bSDaniel Hofer 52b7c79e2bSDaniel Hofer foreach ($event->data->calls as &$call) { 53b7c79e2bSDaniel Hofer if ($call[0] === 'header') { 54b7c79e2bSDaniel Hofer $call[1][0] = $this->replaceHeaderMarkers($call[1][0], $event->data); 55b7c79e2bSDaniel Hofer continue; 56b7c79e2bSDaniel Hofer } 57b7c79e2bSDaniel Hofer 58b7c79e2bSDaniel Hofer if ($call[0] !== 'plugin' || $call[1][0] !== 'autonumbering') { 59b7c79e2bSDaniel Hofer continue; 60b7c79e2bSDaniel Hofer } 61b7c79e2bSDaniel Hofer 62b7c79e2bSDaniel Hofer $syntax = plugin_load('syntax', 'autonumbering'); 63b7c79e2bSDaniel Hofer if (!$syntax instanceof syntax_plugin_autonumbering) { 64b7c79e2bSDaniel Hofer continue; 65b7c79e2bSDaniel Hofer } 66b7c79e2bSDaniel Hofer 67b7c79e2bSDaniel Hofer $call[1][1] = $syntax->handle($call[1][3], $call[1][2], $call[2], $event->data); 68b7c79e2bSDaniel Hofer } 69b7c79e2bSDaniel Hofer unset($call); 70b7c79e2bSDaniel Hofer } 71b7c79e2bSDaniel Hofer 72b7c79e2bSDaniel Hofer /** 73b7c79e2bSDaniel Hofer * Replace autonumbering markers in a heading title with plain heading text. 74b7c79e2bSDaniel Hofer * 75b7c79e2bSDaniel Hofer * @param string $title heading title 76b7c79e2bSDaniel Hofer * @param Doku_Handler $handler parser handler 77b7c79e2bSDaniel Hofer * @return string 78b7c79e2bSDaniel Hofer */ 79b7c79e2bSDaniel Hofer protected function replaceHeaderMarkers($title, Doku_Handler $handler) 80b7c79e2bSDaniel Hofer { 81b7c79e2bSDaniel Hofer $syntax = plugin_load('syntax', 'autonumbering'); 82b7c79e2bSDaniel Hofer if (!$syntax instanceof syntax_plugin_autonumbering) { 83b7c79e2bSDaniel Hofer return $title; 84b7c79e2bSDaniel Hofer } 85b7c79e2bSDaniel Hofer 86b7c79e2bSDaniel Hofer return preg_replace_callback( 87b7c79e2bSDaniel Hofer '/~~[a-zA-Z0-9_\.#@]*#[a-zA-Z0-9_\.#@]*~~/', 88b7c79e2bSDaniel Hofer function ($matches) use ($syntax, $handler) { 89b7c79e2bSDaniel Hofer $data = $syntax->handle($matches[0], DOKU_LEXER_SPECIAL, null, $handler); 90b7c79e2bSDaniel Hofer if (empty($data)) { 91b7c79e2bSDaniel Hofer return $matches[0]; 92b7c79e2bSDaniel Hofer } 93b7c79e2bSDaniel Hofer 94b7c79e2bSDaniel Hofer return strip_tags($data[0]); 95b7c79e2bSDaniel Hofer }, 96b7c79e2bSDaniel Hofer $title 97b7c79e2bSDaniel Hofer ); 98b7c79e2bSDaniel Hofer } 99b7c79e2bSDaniel Hofer} 100