diff options
Diffstat (limited to 'platform/www/inc/Parsing/Parser.php')
-rw-r--r-- | platform/www/inc/Parsing/Parser.php | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/platform/www/inc/Parsing/Parser.php b/platform/www/inc/Parsing/Parser.php new file mode 100644 index 0000000..63f0141 --- /dev/null +++ b/platform/www/inc/Parsing/Parser.php @@ -0,0 +1,128 @@ +<?php + +namespace dokuwiki\Parsing; + +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 = array(); + + /** @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 */ + + \dokuwiki\Debug\DebugHelper::dbgCustomDeprecationEvent( + 'finalize()', + get_class($this->handler) . '::_finalize()', + __METHOD__, + __FILE__, + __LINE__ + ); + $this->handler->_finalize(); + } else { + $this->handler->finalize(); + } + return $this->handler->calls; + } + +} |