123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- <?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;
- }
- }
|