|
- <?php
-
- namespace dokuwiki\Parsing;
-
- use dokuwiki\Debug\DebugHelper;
- use Doku_Handler;
- use dokuwiki\Parsing\Lexer\Lexer;
- use dokuwiki\Parsing\ParserMode\Base;
- use dokuwiki\Parsing\ParserMode\ModeInterface;
-
- /**
- * Sets up the Lexer with modes and points it to the Handler
- * For an intro to the Lexer see: wiki:parser
- */
- class Parser
- {
- /** @var Doku_Handler */
- protected $handler;
-
- /** @var Lexer $lexer */
- protected $lexer;
-
- /** @var ModeInterface[] $modes */
- protected $modes = [];
-
- /** @var bool mode connections may only be set up once */
- protected $connected = false;
-
- /**
- * dokuwiki\Parsing\Doku_Parser constructor.
- *
- * @param Doku_Handler $handler
- */
- public function __construct(Doku_Handler $handler)
- {
- $this->handler = $handler;
- }
-
- /**
- * Adds the base mode and initialized the lexer
- *
- * @param Base $BaseMode
- */
- protected function addBaseMode($BaseMode)
- {
- $this->modes['base'] = $BaseMode;
- if (!$this->lexer) {
- $this->lexer = new Lexer($this->handler, 'base', true);
- }
- $this->modes['base']->Lexer = $this->lexer;
- }
-
- /**
- * Add a new syntax element (mode) to the parser
- *
- * PHP preserves order of associative elements
- * Mode sequence is important
- *
- * @param string $name
- * @param ModeInterface $Mode
- */
- public function addMode($name, ModeInterface $Mode)
- {
- if (!isset($this->modes['base'])) {
- $this->addBaseMode(new Base());
- }
- $Mode->Lexer = $this->lexer; // FIXME should be done by setter
- $this->modes[$name] = $Mode;
- }
-
- /**
- * Connect all modes with each other
- *
- * This is the last step before actually parsing.
- */
- protected function connectModes()
- {
-
- if ($this->connected) {
- return;
- }
-
- foreach (array_keys($this->modes) as $mode) {
- // Base isn't connected to anything
- if ($mode == 'base') {
- continue;
- }
- $this->modes[$mode]->preConnect();
-
- foreach (array_keys($this->modes) as $cm) {
- if ($this->modes[$cm]->accepts($mode)) {
- $this->modes[$mode]->connectTo($cm);
- }
- }
-
- $this->modes[$mode]->postConnect();
- }
-
- $this->connected = true;
- }
-
- /**
- * Parses wiki syntax to instructions
- *
- * @param string $doc the wiki syntax text
- * @return array instructions
- */
- public function parse($doc)
- {
- $this->connectModes();
- // Normalize CRs and pad doc
- $doc = "\n" . str_replace("\r\n", "\n", $doc) . "\n";
- $this->lexer->parse($doc);
-
- if (!method_exists($this->handler, 'finalize')) {
- /** @deprecated 2019-10 we have a legacy handler from a plugin, assume legacy _finalize exists */
-
- DebugHelper::dbgCustomDeprecationEvent(
- 'finalize()',
- get_class($this->handler) . '::_finalize()',
- __METHOD__,
- __FILE__,
- __LINE__
- );
- $this->handler->_finalize();
- } else {
- $this->handler->finalize();
- }
- return $this->handler->calls;
- }
- }
|