1<?php 2 3use dokuwiki\ParserMode\Base; 4use dokuwiki\ParserMode\ModeInterface; 5 6/** 7 * Define various types of modes used by the parser - they are used to 8 * populate the list of modes another mode accepts 9 */ 10global $PARSER_MODES; 11$PARSER_MODES = array( 12 // containers are complex modes that can contain many other modes 13 // hr breaks the principle but they shouldn't be used in tables / lists 14 // so they are put here 15 'container' => array('listblock','table','quote','hr'), 16 17 // some mode are allowed inside the base mode only 18 'baseonly' => array('header'), 19 20 // modes for styling text -- footnote behaves similar to styling 21 'formatting' => array('strong', 'emphasis', 'underline', 'monospace', 22 'subscript', 'superscript', 'deleted', 'footnote'), 23 24 // modes where the token is simply replaced - they can not contain any 25 // other modes 26 'substition' => array('acronym','smiley','wordblock','entity', 27 'camelcaselink', 'internallink','media', 28 'externallink','linebreak','emaillink', 29 'windowssharelink','filelink','notoc', 30 'nocache','multiplyentity','quotes','rss'), 31 32 // modes which have a start and end token but inside which 33 // no other modes should be applied 34 'protected' => array('preformatted','code','file','php','html','htmlblock','phpblock'), 35 36 // inside this mode no wiki markup should be applied but lineendings 37 // and whitespace isn't preserved 38 'disabled' => array('unformatted'), 39 40 // used to mark paragraph boundaries 41 'paragraphs' => array('eol') 42); 43 44//------------------------------------------------------------------- 45 46/** 47 * Sets up the Lexer with modes and points it to the Handler 48 * For an intro to the Lexer see: wiki:parser 49 */ 50class Doku_Parser { 51 52 var $Handler; 53 54 /** 55 * @var Doku_Lexer $Lexer 56 */ 57 var $Lexer; 58 59 var $modes = array(); 60 61 var $connected = false; 62 63 /** 64 * @param Base $BaseMode 65 */ 66 function addBaseMode($BaseMode) { 67 $this->modes['base'] = $BaseMode; 68 if ( !$this->Lexer ) { 69 $this->Lexer = new Doku_Lexer($this->Handler,'base', true); 70 } 71 $this->modes['base']->Lexer = $this->Lexer; 72 } 73 74 /** 75 * PHP preserves order of associative elements 76 * Mode sequence is important 77 * 78 * @param string $name 79 * @param ModeInterface $Mode 80 */ 81 function addMode($name, ModeInterface $Mode) { 82 if ( !isset($this->modes['base']) ) { 83 $this->addBaseMode(new Base()); 84 } 85 $Mode->Lexer = $this->Lexer; 86 $this->modes[$name] = $Mode; 87 } 88 89 function connectModes() { 90 91 if ( $this->connected ) { 92 return; 93 } 94 95 foreach ( array_keys($this->modes) as $mode ) { 96 97 // Base isn't connected to anything 98 if ( $mode == 'base' ) { 99 continue; 100 } 101 $this->modes[$mode]->preConnect(); 102 103 foreach ( array_keys($this->modes) as $cm ) { 104 105 if ( $this->modes[$cm]->accepts($mode) ) { 106 $this->modes[$mode]->connectTo($cm); 107 } 108 109 } 110 111 $this->modes[$mode]->postConnect(); 112 } 113 114 $this->connected = true; 115 } 116 117 function parse($doc) { 118 if ( $this->Lexer ) { 119 $this->connectModes(); 120 // Normalize CRs and pad doc 121 $doc = "\n".str_replace("\r\n","\n",$doc)."\n"; 122 $this->Lexer->parse($doc); 123 $this->Handler->_finalize(); 124 return $this->Handler->calls; 125 } else { 126 return false; 127 } 128 } 129 130} 131 132 133//Setup VIM: ex: et ts=4 : 134