xref: /dokuwiki/inc/parser/parser.php (revision 36dc94bb8b05aaaff6fdcf55dd6af80ca30d22b1)
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