10cecf9d5Sandi<?php 2*36dc94bbSAndreas Gohr 3*36dc94bbSAndreas Gohruse dokuwiki\ParserMode\Base; 4*36dc94bbSAndreas Gohruse dokuwiki\ParserMode\ModeInterface; 5*36dc94bbSAndreas Gohr 6ee20e7d1Sandi/** 7ee20e7d1Sandi * Define various types of modes used by the parser - they are used to 8ee20e7d1Sandi * populate the list of modes another mode accepts 9ee20e7d1Sandi */ 10ee20e7d1Sandiglobal $PARSER_MODES; 11ee20e7d1Sandi$PARSER_MODES = array( 12ee20e7d1Sandi // containers are complex modes that can contain many other modes 13ee20e7d1Sandi // hr breaks the principle but they shouldn't be used in tables / lists 14ee20e7d1Sandi // so they are put here 15ee20e7d1Sandi 'container' => array('listblock','table','quote','hr'), 16ee20e7d1Sandi 17ee20e7d1Sandi // some mode are allowed inside the base mode only 18ee20e7d1Sandi 'baseonly' => array('header'), 19ee20e7d1Sandi 20ee20e7d1Sandi // modes for styling text -- footnote behaves similar to styling 21ee20e7d1Sandi 'formatting' => array('strong', 'emphasis', 'underline', 'monospace', 22ee20e7d1Sandi 'subscript', 'superscript', 'deleted', 'footnote'), 23ee20e7d1Sandi 24ee20e7d1Sandi // modes where the token is simply replaced - they can not contain any 25ee20e7d1Sandi // other modes 26ee20e7d1Sandi 'substition' => array('acronym','smiley','wordblock','entity', 27ee20e7d1Sandi 'camelcaselink', 'internallink','media', 28ee20e7d1Sandi 'externallink','linebreak','emaillink', 29ee20e7d1Sandi 'windowssharelink','filelink','notoc', 30ee20e7d1Sandi 'nocache','multiplyentity','quotes','rss'), 31ee20e7d1Sandi 32ee20e7d1Sandi // modes which have a start and end token but inside which 33ee20e7d1Sandi // no other modes should be applied 3407f89c3cSAnika Henke 'protected' => array('preformatted','code','file','php','html','htmlblock','phpblock'), 35ee20e7d1Sandi 36ee20e7d1Sandi // inside this mode no wiki markup should be applied but lineendings 37ee20e7d1Sandi // and whitespace isn't preserved 38ee20e7d1Sandi 'disabled' => array('unformatted'), 39ee20e7d1Sandi 40ee20e7d1Sandi // used to mark paragraph boundaries 41ee20e7d1Sandi 'paragraphs' => array('eol') 42ee20e7d1Sandi); 43ee20e7d1Sandi 440cecf9d5Sandi//------------------------------------------------------------------- 450cecf9d5Sandi 460cecf9d5Sandi/** 470cecf9d5Sandi * Sets up the Lexer with modes and points it to the Handler 480cecf9d5Sandi * For an intro to the Lexer see: wiki:parser 490cecf9d5Sandi */ 500cecf9d5Sandiclass Doku_Parser { 510cecf9d5Sandi 520cecf9d5Sandi var $Handler; 530cecf9d5Sandi 54e3ab6fc5SMichael Hamann /** 55e3ab6fc5SMichael Hamann * @var Doku_Lexer $Lexer 56e3ab6fc5SMichael Hamann */ 570cecf9d5Sandi var $Lexer; 580cecf9d5Sandi 590cecf9d5Sandi var $modes = array(); 600cecf9d5Sandi 6144881bd0Shenning.noren var $connected = false; 620cecf9d5Sandi 63276820f7SScrutinizer Auto-Fixer /** 64*36dc94bbSAndreas Gohr * @param Base $BaseMode 65276820f7SScrutinizer Auto-Fixer */ 6645e8987eSChristopher Smith function addBaseMode($BaseMode) { 6745e8987eSChristopher Smith $this->modes['base'] = $BaseMode; 680cecf9d5Sandi if ( !$this->Lexer ) { 6967f9913dSAndreas Gohr $this->Lexer = new Doku_Lexer($this->Handler,'base', true); 700cecf9d5Sandi } 7145e8987eSChristopher Smith $this->modes['base']->Lexer = $this->Lexer; 720cecf9d5Sandi } 730cecf9d5Sandi 740cecf9d5Sandi /** 750cecf9d5Sandi * PHP preserves order of associative elements 760cecf9d5Sandi * Mode sequence is important 77f50a239bSTakamura * 78f50a239bSTakamura * @param string $name 79*36dc94bbSAndreas Gohr * @param ModeInterface $Mode 800cecf9d5Sandi */ 81*36dc94bbSAndreas Gohr function addMode($name, ModeInterface $Mode) { 820cecf9d5Sandi if ( !isset($this->modes['base']) ) { 83*36dc94bbSAndreas Gohr $this->addBaseMode(new Base()); 840cecf9d5Sandi } 8545e8987eSChristopher Smith $Mode->Lexer = $this->Lexer; 8645e8987eSChristopher Smith $this->modes[$name] = $Mode; 870cecf9d5Sandi } 880cecf9d5Sandi 890cecf9d5Sandi function connectModes() { 900cecf9d5Sandi 910cecf9d5Sandi if ( $this->connected ) { 920cecf9d5Sandi return; 930cecf9d5Sandi } 940cecf9d5Sandi 950cecf9d5Sandi foreach ( array_keys($this->modes) as $mode ) { 960cecf9d5Sandi 970cecf9d5Sandi // Base isn't connected to anything 980cecf9d5Sandi if ( $mode == 'base' ) { 990cecf9d5Sandi continue; 1000cecf9d5Sandi } 1010cecf9d5Sandi $this->modes[$mode]->preConnect(); 1020cecf9d5Sandi 1030cecf9d5Sandi foreach ( array_keys($this->modes) as $cm ) { 1040cecf9d5Sandi 1050cecf9d5Sandi if ( $this->modes[$cm]->accepts($mode) ) { 1060cecf9d5Sandi $this->modes[$mode]->connectTo($cm); 1070cecf9d5Sandi } 1080cecf9d5Sandi 1090cecf9d5Sandi } 1100cecf9d5Sandi 1110cecf9d5Sandi $this->modes[$mode]->postConnect(); 1120cecf9d5Sandi } 1130cecf9d5Sandi 11444881bd0Shenning.noren $this->connected = true; 1150cecf9d5Sandi } 1160cecf9d5Sandi 1170cecf9d5Sandi function parse($doc) { 1180cecf9d5Sandi if ( $this->Lexer ) { 1190cecf9d5Sandi $this->connectModes(); 1200cecf9d5Sandi // Normalize CRs and pad doc 1210cecf9d5Sandi $doc = "\n".str_replace("\r\n","\n",$doc)."\n"; 1220cecf9d5Sandi $this->Lexer->parse($doc); 123433bef32Sandi $this->Handler->_finalize(); 1240cecf9d5Sandi return $this->Handler->calls; 1250cecf9d5Sandi } else { 12644881bd0Shenning.noren return false; 1270cecf9d5Sandi } 1280cecf9d5Sandi } 1290cecf9d5Sandi 1300cecf9d5Sandi} 1310cecf9d5Sandi 132340756e4Sandi 133e3776c06SMichael Hamann//Setup VIM: ex: et ts=4 : 134