xref: /dokuwiki/inc/parser/parser.php (revision ee20e7d16637625e900f518b6b46a61bfa30fe6e)
10cecf9d5Sandi<?php
20cecf9d5Sandi
30cecf9d5Sandiif(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
40cecf9d5Sandi
50cecf9d5Sandirequire_once DOKU_INC . 'inc/parser/lexer.php';
60cecf9d5Sandirequire_once DOKU_INC . 'inc/parser/handler.php';
70cecf9d5Sandi
8*ee20e7d1Sandi
9*ee20e7d1Sandi/**
10*ee20e7d1Sandi * Define various types of modes used by the parser - they are used to
11*ee20e7d1Sandi * populate the list of modes another mode accepts
12*ee20e7d1Sandi */
13*ee20e7d1Sandiglobal $PARSER_MODES;
14*ee20e7d1Sandi$PARSER_MODES = array(
15*ee20e7d1Sandi    // containers are complex modes that can contain many other modes
16*ee20e7d1Sandi    // hr breaks the principle but they shouldn't be used in tables / lists
17*ee20e7d1Sandi    // so they are put here
18*ee20e7d1Sandi    'container'    => array('listblock','table','quote','hr'),
19*ee20e7d1Sandi
20*ee20e7d1Sandi    // some mode are allowed inside the base mode only
21*ee20e7d1Sandi    'baseonly'     => array('header'),
22*ee20e7d1Sandi
23*ee20e7d1Sandi    // modes for styling text -- footnote behaves similar to styling
24*ee20e7d1Sandi    'formatting'   => array('strong', 'emphasis', 'underline', 'monospace',
25*ee20e7d1Sandi                            'subscript', 'superscript', 'deleted', 'footnote'),
26*ee20e7d1Sandi
27*ee20e7d1Sandi    // modes where the token is simply replaced - they can not contain any
28*ee20e7d1Sandi    // other modes
29*ee20e7d1Sandi    'substition'   => array('acronym','smiley','wordblock','entity',
30*ee20e7d1Sandi                            'camelcaselink', 'internallink','media',
31*ee20e7d1Sandi                            'externallink','linebreak','emaillink',
32*ee20e7d1Sandi                            'windowssharelink','filelink','notoc',
33*ee20e7d1Sandi                            'nocache','multiplyentity','quotes','rss'),
34*ee20e7d1Sandi
35*ee20e7d1Sandi    // modes which have a start and end token but inside which
36*ee20e7d1Sandi    // no other modes should be applied
37*ee20e7d1Sandi    'protected'    => array('preformatted','code','file','php','html'),
38*ee20e7d1Sandi
39*ee20e7d1Sandi    // inside this mode no wiki markup should be applied but lineendings
40*ee20e7d1Sandi    // and whitespace isn't preserved
41*ee20e7d1Sandi    'disabled'     => array('unformatted'),
42*ee20e7d1Sandi
43*ee20e7d1Sandi    // used to mark paragraph boundaries
44*ee20e7d1Sandi    'paragraphs'   => array('eol')
45*ee20e7d1Sandi);
46*ee20e7d1Sandi
470cecf9d5Sandi//-------------------------------------------------------------------
480cecf9d5Sandi
490cecf9d5Sandi/**
500cecf9d5Sandi* Sets up the Lexer with modes and points it to the Handler
510cecf9d5Sandi* For an intro to the Lexer see: wiki:parser
520cecf9d5Sandi*/
530cecf9d5Sandiclass Doku_Parser {
540cecf9d5Sandi
550cecf9d5Sandi    var $Handler;
560cecf9d5Sandi
570cecf9d5Sandi    var $Lexer;
580cecf9d5Sandi
590cecf9d5Sandi    var $modes = array();
600cecf9d5Sandi
610cecf9d5Sandi    var $connected = FALSE;
620cecf9d5Sandi
63b7c441b9SHarry Fuecks    function addBaseMode(& $BaseMode) {
64b7c441b9SHarry Fuecks        $this->modes['base'] = & $BaseMode;
650cecf9d5Sandi        if ( !$this->Lexer ) {
660cecf9d5Sandi            $this->Lexer = & new Doku_Lexer($this->Handler,'base', TRUE);
670cecf9d5Sandi        }
680cecf9d5Sandi        $this->modes['base']->Lexer = & $this->Lexer;
690cecf9d5Sandi    }
700cecf9d5Sandi
710cecf9d5Sandi    /**
720cecf9d5Sandi    * PHP preserves order of associative elements
730cecf9d5Sandi    * Mode sequence is important
740cecf9d5Sandi    */
750cecf9d5Sandi    function addMode($name, & $Mode) {
760cecf9d5Sandi        if ( !isset($this->modes['base']) ) {
77b7c441b9SHarry Fuecks            $this->addBaseMode(new Doku_Parser_Mode_Base());
780cecf9d5Sandi        }
790cecf9d5Sandi        $Mode->Lexer = & $this->Lexer;
800cecf9d5Sandi        $this->modes[$name] = & $Mode;
810cecf9d5Sandi    }
820cecf9d5Sandi
830cecf9d5Sandi    function connectModes() {
840cecf9d5Sandi
850cecf9d5Sandi        if ( $this->connected ) {
860cecf9d5Sandi            return;
870cecf9d5Sandi        }
880cecf9d5Sandi
890cecf9d5Sandi        foreach ( array_keys($this->modes) as $mode ) {
900cecf9d5Sandi
910cecf9d5Sandi            // Base isn't connected to anything
920cecf9d5Sandi            if ( $mode == 'base' ) {
930cecf9d5Sandi                continue;
940cecf9d5Sandi            }
950cecf9d5Sandi
960cecf9d5Sandi            $this->modes[$mode]->preConnect();
970cecf9d5Sandi
980cecf9d5Sandi            foreach ( array_keys($this->modes) as $cm ) {
990cecf9d5Sandi
1000cecf9d5Sandi                if ( $this->modes[$cm]->accepts($mode) ) {
1010cecf9d5Sandi                    $this->modes[$mode]->connectTo($cm);
1020cecf9d5Sandi                }
1030cecf9d5Sandi
1040cecf9d5Sandi            }
1050cecf9d5Sandi
1060cecf9d5Sandi            $this->modes[$mode]->postConnect();
1070cecf9d5Sandi        }
1080cecf9d5Sandi
1090cecf9d5Sandi        $this->connected = TRUE;
1100cecf9d5Sandi    }
1110cecf9d5Sandi
1120cecf9d5Sandi    function parse($doc) {
1130cecf9d5Sandi        if ( $this->Lexer ) {
1140cecf9d5Sandi            $this->connectModes();
1150cecf9d5Sandi            // Normalize CRs and pad doc
1160cecf9d5Sandi            $doc = "\n".str_replace("\r\n","\n",$doc)."\n";
1170cecf9d5Sandi            $this->Lexer->parse($doc);
118433bef32Sandi            $this->Handler->_finalize();
1190cecf9d5Sandi            return $this->Handler->calls;
1200cecf9d5Sandi        } else {
1210cecf9d5Sandi            return FALSE;
1220cecf9d5Sandi        }
1230cecf9d5Sandi    }
1240cecf9d5Sandi
1250cecf9d5Sandi}
1260cecf9d5Sandi
1270cecf9d5Sandi//-------------------------------------------------------------------
1280cecf9d5Sandi/**
1290cecf9d5Sandi * This class and all the subclasses below are
1300cecf9d5Sandi * used to reduce the effort required to register
1310cecf9d5Sandi * modes with the Lexer. For performance these
1320cecf9d5Sandi * could all be eliminated later perhaps, or
1330cecf9d5Sandi * the Parser could be serialized to a file once
1340cecf9d5Sandi * all modes are registered
135702eb898Sandi *
1360b7c14c2Sandi * @author Harry Fuecks <hfuecks@gmail.com>
1370cecf9d5Sandi*/
1380cecf9d5Sandiclass Doku_Parser_Mode {
1390cecf9d5Sandi
1400cecf9d5Sandi    var $Lexer;
1410cecf9d5Sandi
1420cecf9d5Sandi    var $allowedModes = array();
1430cecf9d5Sandi
1440cecf9d5Sandi    // Called before any calls to connectTo
1450cecf9d5Sandi    function preConnect() {}
1460cecf9d5Sandi
1470cecf9d5Sandi    function connectTo($mode) {}
1480cecf9d5Sandi
1490cecf9d5Sandi    // Called after all calls to connectTo
1500cecf9d5Sandi    function postConnect() {}
1510cecf9d5Sandi
1520cecf9d5Sandi    function accepts($mode) {
1530cecf9d5Sandi        return in_array($mode, $this->allowedModes );
1540cecf9d5Sandi    }
1550cecf9d5Sandi
1560cecf9d5Sandi}
1570cecf9d5Sandi
1580cecf9d5Sandi//-------------------------------------------------------------------
1590cecf9d5Sandiclass Doku_Parser_Mode_Base extends Doku_Parser_Mode {
1600cecf9d5Sandi
1610cecf9d5Sandi    function Doku_Parser_Mode_Base() {
162*ee20e7d1Sandi        global $PARSER_MODES;
1630cecf9d5Sandi
1640cecf9d5Sandi        $this->allowedModes = array_merge (
165*ee20e7d1Sandi                $PARSER_MODES['container'],
166*ee20e7d1Sandi                $PARSER_MODES['baseonly'],
167*ee20e7d1Sandi                $PARSER_MODES['paragraphs'],
168*ee20e7d1Sandi                $PARSER_MODES['formatting'],
169*ee20e7d1Sandi                $PARSER_MODES['substition'],
170*ee20e7d1Sandi                $PARSER_MODES['protected'],
171*ee20e7d1Sandi                $PARSER_MODES['disabled']
1720cecf9d5Sandi            );
1730cecf9d5Sandi    }
1740cecf9d5Sandi}
1750cecf9d5Sandi
1760cecf9d5Sandi//-------------------------------------------------------------------
1770cecf9d5Sandiclass Doku_Parser_Mode_Footnote extends Doku_Parser_Mode {
1780cecf9d5Sandi
1790cecf9d5Sandi    function Doku_Parser_Mode_Footnote() {
180*ee20e7d1Sandi        global $PARSER_MODES;
1810cecf9d5Sandi
1820cecf9d5Sandi        $this->allowedModes = array_merge (
183*ee20e7d1Sandi                $PARSER_MODES['container'],
184*ee20e7d1Sandi                $PARSER_MODES['formatting'],
185*ee20e7d1Sandi                $PARSER_MODES['substition'],
186*ee20e7d1Sandi                $PARSER_MODES['protected'],
187*ee20e7d1Sandi                $PARSER_MODES['disabled']
1880cecf9d5Sandi            );
1890cecf9d5Sandi
1900cecf9d5Sandi    }
1910cecf9d5Sandi
1920cecf9d5Sandi    function connectTo($mode) {
1930cecf9d5Sandi        $this->Lexer->addEntryPattern(
1940cecf9d5Sandi            '\x28\x28(?=.*\x29\x29)',$mode,'footnote'
1950cecf9d5Sandi            );
1960cecf9d5Sandi    }
1970cecf9d5Sandi
1980cecf9d5Sandi    function postConnect() {
1990cecf9d5Sandi        $this->Lexer->addExitPattern(
2000cecf9d5Sandi            '\x29\x29','footnote'
2010cecf9d5Sandi            );
2020cecf9d5Sandi
2030cecf9d5Sandi    }
2040cecf9d5Sandi
2050cecf9d5Sandi}
2060cecf9d5Sandi
2070cecf9d5Sandi//-------------------------------------------------------------------
2080cecf9d5Sandiclass Doku_Parser_Mode_Header extends Doku_Parser_Mode {
2090cecf9d5Sandi
2100cecf9d5Sandi    function preConnect() {
211506ae684Sandi        //we're not picky about the closing ones, two are enough
2120cecf9d5Sandi
2130cecf9d5Sandi        // Header 1 is special case - match 6 or more
2140cecf9d5Sandi        $this->Lexer->addSpecialPattern(
2156f0c5dbfSandi                            '[ \t]*={6,}[^\n]+={2,}[ \t]*(?=\n)',
2160cecf9d5Sandi                            'base',
2170cecf9d5Sandi                            'header'
2180cecf9d5Sandi                        );
2190cecf9d5Sandi
2200cecf9d5Sandi        // For the rest, match exactly
2210cecf9d5Sandi        for ( $i = 5; $i > 1; $i--) {
2220cecf9d5Sandi            $this->Lexer->addSpecialPattern(
2236f0c5dbfSandi                                '[ \t]*={'.$i.'}[^\n]+={2,}[ \t]*(?=\n)',
2240cecf9d5Sandi                                'base',
2250cecf9d5Sandi                                'header'
2260cecf9d5Sandi                            );
2270cecf9d5Sandi        }
2280cecf9d5Sandi    }
2290cecf9d5Sandi
2300cecf9d5Sandi}
2310cecf9d5Sandi
2320cecf9d5Sandi//-------------------------------------------------------------------
2330cecf9d5Sandiclass Doku_Parser_Mode_NoToc extends Doku_Parser_Mode {
2340cecf9d5Sandi
2350cecf9d5Sandi    function connectTo($mode) {
2360cecf9d5Sandi        $this->Lexer->addSpecialPattern('~~NOTOC~~',$mode,'notoc');
2370cecf9d5Sandi    }
2380cecf9d5Sandi
2390cecf9d5Sandi}
2400cecf9d5Sandi
2410cecf9d5Sandi//-------------------------------------------------------------------
2429dc2c2afSandiclass Doku_Parser_Mode_NoCache extends Doku_Parser_Mode {
2439dc2c2afSandi
2449dc2c2afSandi    function connectTo($mode) {
2459dc2c2afSandi        $this->Lexer->addSpecialPattern('~~NOCACHE~~',$mode,'nocache');
2469dc2c2afSandi    }
2479dc2c2afSandi
2489dc2c2afSandi}
2499dc2c2afSandi
2509dc2c2afSandi//-------------------------------------------------------------------
2510cecf9d5Sandiclass Doku_Parser_Mode_Linebreak extends Doku_Parser_Mode {
2520cecf9d5Sandi
2530cecf9d5Sandi    function connectTo($mode) {
2545e100747Sandi        $this->Lexer->addSpecialPattern('\x5C{2}(?=\s)',$mode,'linebreak');
2550cecf9d5Sandi    }
2560cecf9d5Sandi}
2570cecf9d5Sandi
2580cecf9d5Sandi//-------------------------------------------------------------------
2590cecf9d5Sandiclass Doku_Parser_Mode_Eol extends Doku_Parser_Mode {
2600cecf9d5Sandi
2610cecf9d5Sandi    function connectTo($mode) {
2620cecf9d5Sandi        $badModes = array('listblock','table');
2630cecf9d5Sandi        if ( in_array($mode, $badModes) ) {
2640cecf9d5Sandi            return;
2650cecf9d5Sandi        }
2660cecf9d5Sandi        $this->Lexer->addSpecialPattern('\n',$mode,'eol');
2670cecf9d5Sandi    }
2680cecf9d5Sandi}
2690cecf9d5Sandi
2700cecf9d5Sandi//-------------------------------------------------------------------
2710cecf9d5Sandiclass Doku_Parser_Mode_HR extends Doku_Parser_Mode {
2720cecf9d5Sandi
2730cecf9d5Sandi    function connectTo($mode) {
2746f0c5dbfSandi        $this->Lexer->addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr');
2750cecf9d5Sandi    }
2760cecf9d5Sandi
2770cecf9d5Sandi}
2780cecf9d5Sandi
2790cecf9d5Sandi//-------------------------------------------------------------------
2800cecf9d5Sandiclass Doku_Parser_Mode_Formatting extends Doku_Parser_Mode {
2810cecf9d5Sandi    var $type;
2820cecf9d5Sandi
2830cecf9d5Sandi    var $formatting = array (
2840cecf9d5Sandi        'strong' => array (
2850cecf9d5Sandi            'entry'=>'\*\*(?=.*\*\*)',
2860cecf9d5Sandi            'exit'=>'\*\*',
2870cecf9d5Sandi            ),
2880cecf9d5Sandi
2890cecf9d5Sandi        'emphasis'=> array (
2900cecf9d5Sandi            'entry'=>'//(?=.*//)',
2910cecf9d5Sandi            'exit'=>'//',
2920cecf9d5Sandi            ),
2930cecf9d5Sandi
2940cecf9d5Sandi        'underline'=> array (
2950cecf9d5Sandi            'entry'=>'__(?=.*__)',
2960cecf9d5Sandi            'exit'=>'__',
2970cecf9d5Sandi            ),
2980cecf9d5Sandi
2990cecf9d5Sandi        'monospace'=> array (
3000cecf9d5Sandi            'entry'=>'\x27\x27(?=.*\x27\x27)',
3010cecf9d5Sandi            'exit'=>'\x27\x27',
3020cecf9d5Sandi            ),
3030cecf9d5Sandi
3040cecf9d5Sandi        'subscript'=> array (
3050cecf9d5Sandi            'entry'=>'<sub>(?=.*\x3C/sub\x3E)',
3060cecf9d5Sandi            'exit'=>'</sub>',
3070cecf9d5Sandi            ),
3080cecf9d5Sandi
3090cecf9d5Sandi        'superscript'=> array (
3100cecf9d5Sandi            'entry'=>'<sup>(?=.*\x3C/sup\x3E)',
3110cecf9d5Sandi            'exit'=>'</sup>',
3120cecf9d5Sandi            ),
3130cecf9d5Sandi
3140cecf9d5Sandi        'deleted'=> array (
3150cecf9d5Sandi            'entry'=>'<del>(?=.*\x3C/del\x3E)',
3160cecf9d5Sandi            'exit'=>'</del>',
3170cecf9d5Sandi            ),
3180cecf9d5Sandi        );
3190cecf9d5Sandi
3200cecf9d5Sandi    function Doku_Parser_Mode_Formatting($type) {
321*ee20e7d1Sandi        global $PARSER_MODES;
3220cecf9d5Sandi
3230cecf9d5Sandi        if ( !array_key_exists($type, $this->formatting) ) {
3240cecf9d5Sandi            trigger_error('Invalid formatting type '.$type, E_USER_WARNING);
3250cecf9d5Sandi        }
3260cecf9d5Sandi
3270cecf9d5Sandi        $this->type = $type;
3280cecf9d5Sandi
329*ee20e7d1Sandi        // formatting may contain other formatting but not it self
330*ee20e7d1Sandi        $modes = $PARSER_MODES['formatting'];
331*ee20e7d1Sandi        $key = array_search($type, $modes);
332*ee20e7d1Sandi        if ( is_int($key) ) {
333*ee20e7d1Sandi            unset($modes[$key]);
334*ee20e7d1Sandi        }
3350cecf9d5Sandi
336*ee20e7d1Sandi        $this->allowedModes = array_merge (
337*ee20e7d1Sandi                $modes,
338*ee20e7d1Sandi                $PARSER_MODES['substition'],
339*ee20e7d1Sandi                $PARSER_MODES['disabled']
340*ee20e7d1Sandi            );
3410cecf9d5Sandi    }
3420cecf9d5Sandi
3430cecf9d5Sandi    function connectTo($mode) {
3440cecf9d5Sandi
3450cecf9d5Sandi        // Can't nest formatting in itself
3460cecf9d5Sandi        if ( $mode == $this->type ) {
3470cecf9d5Sandi            return;
3480cecf9d5Sandi        }
3490cecf9d5Sandi
3500cecf9d5Sandi        $this->Lexer->addEntryPattern(
3510cecf9d5Sandi                $this->formatting[$this->type]['entry'],
3520cecf9d5Sandi                $mode,
3530cecf9d5Sandi                $this->type
3540cecf9d5Sandi            );
3550cecf9d5Sandi    }
3560cecf9d5Sandi
3570cecf9d5Sandi    function postConnect() {
3580cecf9d5Sandi
3590cecf9d5Sandi        $this->Lexer->addExitPattern(
3600cecf9d5Sandi            $this->formatting[$this->type]['exit'],
3610cecf9d5Sandi            $this->type
3620cecf9d5Sandi            );
3630cecf9d5Sandi
3640cecf9d5Sandi    }
3650cecf9d5Sandi}
3660cecf9d5Sandi
3670cecf9d5Sandi//-------------------------------------------------------------------
3680cecf9d5Sandiclass Doku_Parser_Mode_ListBlock extends Doku_Parser_Mode {
3690cecf9d5Sandi
3700cecf9d5Sandi    function Doku_Parser_Mode_ListBlock() {
371*ee20e7d1Sandi        global $PARSER_MODES;
3720cecf9d5Sandi
3730cecf9d5Sandi        $this->allowedModes = array_merge (
374*ee20e7d1Sandi                $PARSER_MODES['formatting'],
375*ee20e7d1Sandi                $PARSER_MODES['substition'],
376*ee20e7d1Sandi                $PARSER_MODES['disabled'],
377*ee20e7d1Sandi                $PARSER_MODES['protected'] #XXX new
3780cecf9d5Sandi            );
379702eb898Sandi
380*ee20e7d1Sandi    //    $this->allowedModes[] = 'footnote';
3810cecf9d5Sandi    }
3820cecf9d5Sandi
3830cecf9d5Sandi    function connectTo($mode) {
3840cecf9d5Sandi        $this->Lexer->addEntryPattern('\n {2,}[\-\*]',$mode,'listblock');
3850cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\t{1,}[\-\*]',$mode,'listblock');
3860cecf9d5Sandi
3870cecf9d5Sandi        $this->Lexer->addPattern('\n {2,}[\-\*]','listblock');
3880cecf9d5Sandi        $this->Lexer->addPattern('\n\t{1,}[\-\*]','listblock');
3890cecf9d5Sandi
3900cecf9d5Sandi    }
3910cecf9d5Sandi
3920cecf9d5Sandi    function postConnect() {
3930cecf9d5Sandi        $this->Lexer->addExitPattern('\n','listblock');
3940cecf9d5Sandi    }
3950cecf9d5Sandi}
3960cecf9d5Sandi
3970cecf9d5Sandi//-------------------------------------------------------------------
3980cecf9d5Sandiclass Doku_Parser_Mode_Table extends Doku_Parser_Mode {
3990cecf9d5Sandi
4000cecf9d5Sandi    function Doku_Parser_Mode_Table() {
401*ee20e7d1Sandi        global $PARSER_MODES;
4020cecf9d5Sandi
4030cecf9d5Sandi        $this->allowedModes = array_merge (
404*ee20e7d1Sandi                $PARSER_MODES['formatting'],
405*ee20e7d1Sandi                $PARSER_MODES['substition'],
406*ee20e7d1Sandi                $PARSER_MODES['disabled'],
407*ee20e7d1Sandi                $PARSER_MODES['protected'] #XXX new
4080cecf9d5Sandi            );
409*ee20e7d1Sandi        #$this->allowedModes[] = 'footnote';
410*ee20e7d1Sandi        #$this->allowedModes[] = 'preformatted';
411*ee20e7d1Sandi        #$this->allowedModes[] = 'unformatted';
4120cecf9d5Sandi    }
4130cecf9d5Sandi
4140cecf9d5Sandi    function connectTo($mode) {
4150cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\^',$mode,'table');
4160cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\|',$mode,'table');
4170cecf9d5Sandi    }
4180cecf9d5Sandi
4190cecf9d5Sandi    function postConnect() {
4200cecf9d5Sandi        $this->Lexer->addPattern('\n\^','table');
4210cecf9d5Sandi        $this->Lexer->addPattern('\n\|','table');
4220cecf9d5Sandi        $this->Lexer->addPattern(' {2,}','table');
4230cecf9d5Sandi        $this->Lexer->addPattern('\^','table');
4240cecf9d5Sandi        $this->Lexer->addPattern('\|','table');
4250cecf9d5Sandi        $this->Lexer->addExitPattern('\n','table');
4260cecf9d5Sandi    }
4270cecf9d5Sandi}
4280cecf9d5Sandi
4290cecf9d5Sandi//-------------------------------------------------------------------
4300cecf9d5Sandiclass Doku_Parser_Mode_Unformatted extends Doku_Parser_Mode {
4310cecf9d5Sandi
4320cecf9d5Sandi    function connectTo($mode) {
4330cecf9d5Sandi        $this->Lexer->addEntryPattern('<nowiki>(?=.*\x3C/nowiki\x3E)',$mode,'unformatted');
4340cecf9d5Sandi        $this->Lexer->addEntryPattern('%%(?=.*%%)',$mode,'unformattedalt');
4350cecf9d5Sandi    }
4360cecf9d5Sandi
4370cecf9d5Sandi    function postConnect() {
4380cecf9d5Sandi        $this->Lexer->addExitPattern('</nowiki>','unformatted');
4390cecf9d5Sandi        $this->Lexer->addExitPattern('%%','unformattedalt');
4400cecf9d5Sandi        $this->Lexer->mapHandler('unformattedalt','unformatted');
4410cecf9d5Sandi    }
4420cecf9d5Sandi
4430cecf9d5Sandi}
4440cecf9d5Sandi
4450cecf9d5Sandi//-------------------------------------------------------------------
4460cecf9d5Sandiclass Doku_Parser_Mode_PHP extends Doku_Parser_Mode {
4470cecf9d5Sandi
4480cecf9d5Sandi    function connectTo($mode) {
4490cecf9d5Sandi        $this->Lexer->addEntryPattern('<php>(?=.*\x3C/php\x3E)',$mode,'php');
4500cecf9d5Sandi    }
4510cecf9d5Sandi
4520cecf9d5Sandi    function postConnect() {
4530cecf9d5Sandi        $this->Lexer->addExitPattern('</php>','php');
4540cecf9d5Sandi    }
4550cecf9d5Sandi
4560cecf9d5Sandi}
4570cecf9d5Sandi
4580cecf9d5Sandi//-------------------------------------------------------------------
4590cecf9d5Sandiclass Doku_Parser_Mode_HTML extends Doku_Parser_Mode {
4600cecf9d5Sandi
4610cecf9d5Sandi    function connectTo($mode) {
4620cecf9d5Sandi        $this->Lexer->addEntryPattern('<html>(?=.*\x3C/html\x3E)',$mode,'html');
4630cecf9d5Sandi    }
4640cecf9d5Sandi
4650cecf9d5Sandi    function postConnect() {
4660cecf9d5Sandi        $this->Lexer->addExitPattern('</html>','html');
4670cecf9d5Sandi    }
4680cecf9d5Sandi
4690cecf9d5Sandi}
4700cecf9d5Sandi
4710cecf9d5Sandi//-------------------------------------------------------------------
4720cecf9d5Sandiclass Doku_Parser_Mode_Preformatted extends Doku_Parser_Mode {
4730cecf9d5Sandi
4740cecf9d5Sandi    function connectTo($mode) {
4750cecf9d5Sandi        // Has hard coded awareness of lists...
4760cecf9d5Sandi        $this->Lexer->addEntryPattern('\n  (?![\*\-])',$mode,'preformatted');
4770cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\t(?![\*\-])',$mode,'preformatted');
4780cecf9d5Sandi
4790cecf9d5Sandi        // How to effect a sub pattern with the Lexer!
4800cecf9d5Sandi        $this->Lexer->addPattern('\n  ','preformatted');
4810cecf9d5Sandi        $this->Lexer->addPattern('\n\t','preformatted');
4820cecf9d5Sandi
4830cecf9d5Sandi    }
4840cecf9d5Sandi
4850cecf9d5Sandi    function postConnect() {
4860cecf9d5Sandi        $this->Lexer->addExitPattern('\n','preformatted');
4870cecf9d5Sandi    }
4880cecf9d5Sandi
4890cecf9d5Sandi}
4900cecf9d5Sandi
4910cecf9d5Sandi//-------------------------------------------------------------------
4920cecf9d5Sandiclass Doku_Parser_Mode_Code extends Doku_Parser_Mode {
4930cecf9d5Sandi
4940cecf9d5Sandi    function connectTo($mode) {
4950cecf9d5Sandi        $this->Lexer->addEntryPattern('<code(?=.*\x3C/code\x3E)',$mode,'code');
4960cecf9d5Sandi    }
4970cecf9d5Sandi
4980cecf9d5Sandi    function postConnect() {
4990cecf9d5Sandi        $this->Lexer->addExitPattern('</code>','code');
5000cecf9d5Sandi    }
5010cecf9d5Sandi
5020cecf9d5Sandi}
5030cecf9d5Sandi
5040cecf9d5Sandi//-------------------------------------------------------------------
5050cecf9d5Sandiclass Doku_Parser_Mode_File extends Doku_Parser_Mode {
5060cecf9d5Sandi
5070cecf9d5Sandi    function connectTo($mode) {
5080cecf9d5Sandi        $this->Lexer->addEntryPattern('<file>(?=.*\x3C/file\x3E)',$mode,'file');
5090cecf9d5Sandi    }
5100cecf9d5Sandi
5110cecf9d5Sandi    function postConnect() {
5120cecf9d5Sandi        $this->Lexer->addExitPattern('</file>','file');
5130cecf9d5Sandi    }
5140cecf9d5Sandi
5150cecf9d5Sandi}
5160cecf9d5Sandi
5170cecf9d5Sandi//-------------------------------------------------------------------
5180cecf9d5Sandiclass Doku_Parser_Mode_Quote extends Doku_Parser_Mode {
5190cecf9d5Sandi
5200cecf9d5Sandi    function Doku_Parser_Mode_Quote() {
521*ee20e7d1Sandi        global $PARSER_MODES;
5220cecf9d5Sandi
5230cecf9d5Sandi        $this->allowedModes = array_merge (
524*ee20e7d1Sandi                $PARSER_MODES['formatting'],
525*ee20e7d1Sandi                $PARSER_MODES['substition'],
526*ee20e7d1Sandi                $PARSER_MODES['disabled'],
527*ee20e7d1Sandi                $PARSER_MODES['protected'] #XXX new
5280cecf9d5Sandi            );
529*ee20e7d1Sandi            #$this->allowedModes[] = 'footnote';
530*ee20e7d1Sandi            #$this->allowedModes[] = 'preformatted';
531*ee20e7d1Sandi            #$this->allowedModes[] = 'unformatted';
5320cecf9d5Sandi    }
5330cecf9d5Sandi
5340cecf9d5Sandi    function connectTo($mode) {
5350cecf9d5Sandi        $this->Lexer->addEntryPattern('\n>{1,}',$mode,'quote');
5360cecf9d5Sandi    }
5370cecf9d5Sandi
5380cecf9d5Sandi    function postConnect() {
5390cecf9d5Sandi        $this->Lexer->addPattern('\n>{1,}','quote');
5400cecf9d5Sandi        $this->Lexer->addExitPattern('\n','quote');
5410cecf9d5Sandi    }
5420cecf9d5Sandi
5430cecf9d5Sandi}
5440cecf9d5Sandi
5450cecf9d5Sandi//-------------------------------------------------------------------
5460cecf9d5Sandiclass Doku_Parser_Mode_Acronym extends Doku_Parser_Mode {
5470cecf9d5Sandi    // A list
5480cecf9d5Sandi    var $acronyms = array();
5490cecf9d5Sandi    var $pattern = '';
5500cecf9d5Sandi
5510cecf9d5Sandi    function Doku_Parser_Mode_Acronym($acronyms) {
5520cecf9d5Sandi        $this->acronyms = $acronyms;
5530cecf9d5Sandi    }
5540cecf9d5Sandi
5550cecf9d5Sandi    function preConnect() {
5560cecf9d5Sandi        $sep = '';
5570cecf9d5Sandi        foreach ( $this->acronyms as $acronym ) {
5580cecf9d5Sandi            $this->pattern .= $sep.'(?<=\b)'.Doku_Lexer_Escape($acronym).'(?=\b)';
5590cecf9d5Sandi            $sep = '|';
5600cecf9d5Sandi        }
5610cecf9d5Sandi    }
5620cecf9d5Sandi
5630cecf9d5Sandi    function connectTo($mode) {
5640cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
5650cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'acronym');
5660cecf9d5Sandi        }
5670cecf9d5Sandi    }
5680cecf9d5Sandi
5690cecf9d5Sandi}
5700cecf9d5Sandi
5710cecf9d5Sandi//-------------------------------------------------------------------
5720cecf9d5Sandiclass Doku_Parser_Mode_Smiley extends Doku_Parser_Mode {
5730cecf9d5Sandi    // A list
5740cecf9d5Sandi    var $smileys = array();
5750cecf9d5Sandi    var $pattern = '';
5760cecf9d5Sandi
5770cecf9d5Sandi    function Doku_Parser_Mode_Smiley($smileys) {
5780cecf9d5Sandi        $this->smileys = $smileys;
5790cecf9d5Sandi    }
5800cecf9d5Sandi
5810cecf9d5Sandi    function preConnect() {
5820cecf9d5Sandi        $sep = '';
5830cecf9d5Sandi        foreach ( $this->smileys as $smiley ) {
5840cecf9d5Sandi            $this->pattern .= $sep.Doku_Lexer_Escape($smiley);
5850cecf9d5Sandi            $sep = '|';
5860cecf9d5Sandi        }
5870cecf9d5Sandi    }
5880cecf9d5Sandi
5890cecf9d5Sandi    function connectTo($mode) {
5900cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
5910cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'smiley');
5920cecf9d5Sandi        }
5930cecf9d5Sandi    }
5940cecf9d5Sandi
5950cecf9d5Sandi}
5960cecf9d5Sandi
5970cecf9d5Sandi//-------------------------------------------------------------------
5980cecf9d5Sandiclass Doku_Parser_Mode_Wordblock extends Doku_Parser_Mode {
5990cecf9d5Sandi    // A list
6000cecf9d5Sandi    var $badwords = array();
6010cecf9d5Sandi    var $pattern = '';
6020cecf9d5Sandi
6030cecf9d5Sandi    function Doku_Parser_Mode_Wordblock($badwords) {
6040cecf9d5Sandi        $this->badwords = $badwords;
6050cecf9d5Sandi    }
6060cecf9d5Sandi
6070cecf9d5Sandi    function preConnect() {
6080cecf9d5Sandi
6090cecf9d5Sandi        if ( count($this->badwords) == 0 ) {
6100cecf9d5Sandi            return;
6110cecf9d5Sandi        }
6120cecf9d5Sandi
6130cecf9d5Sandi        $sep = '';
6140cecf9d5Sandi        foreach ( $this->badwords as $badword ) {
6150cecf9d5Sandi            $this->pattern .= $sep.'(?<=\b)(?i)'.Doku_Lexer_Escape($badword).'(?-i)(?=\b)';
6160cecf9d5Sandi            $sep = '|';
6170cecf9d5Sandi        }
6180cecf9d5Sandi
6190cecf9d5Sandi    }
6200cecf9d5Sandi
6210cecf9d5Sandi    function connectTo($mode) {
6220cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
6230cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'wordblock');
6240cecf9d5Sandi        }
6250cecf9d5Sandi    }
6260cecf9d5Sandi
6270cecf9d5Sandi}
6280cecf9d5Sandi
6290cecf9d5Sandi//-------------------------------------------------------------------
6300cecf9d5Sandi/**
6314de671bcSandi* @TODO Quotes and 640x480 are not supported - just straight replacements here
6320cecf9d5Sandi*/
6330cecf9d5Sandiclass Doku_Parser_Mode_Entity extends Doku_Parser_Mode {
6340cecf9d5Sandi    // A list
6350cecf9d5Sandi    var $entities = array();
6360cecf9d5Sandi    var $pattern = '';
6370cecf9d5Sandi
6380cecf9d5Sandi    function Doku_Parser_Mode_Entity($entities) {
6390cecf9d5Sandi        $this->entities = $entities;
6400cecf9d5Sandi    }
6410cecf9d5Sandi
6420cecf9d5Sandi    function preConnect() {
6430cecf9d5Sandi        $sep = '';
6440cecf9d5Sandi        foreach ( $this->entities as $entity ) {
6450cecf9d5Sandi            $this->pattern .= $sep.Doku_Lexer_Escape($entity);
6460cecf9d5Sandi            $sep = '|';
6470cecf9d5Sandi        }
6480cecf9d5Sandi    }
6490cecf9d5Sandi
6500cecf9d5Sandi    function connectTo($mode) {
6510cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
6520cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'entity');
6530cecf9d5Sandi        }
6540cecf9d5Sandi    }
6550cecf9d5Sandi
6560cecf9d5Sandi}
6570cecf9d5Sandi
6580cecf9d5Sandi//-------------------------------------------------------------------
6590cecf9d5Sandi// Implements the 640x480 replacement
6600cecf9d5Sandiclass Doku_Parser_Mode_MultiplyEntity extends Doku_Parser_Mode {
6610cecf9d5Sandi
6620cecf9d5Sandi    function connectTo($mode) {
6630cecf9d5Sandi
6640cecf9d5Sandi        $this->Lexer->addSpecialPattern(
6650cecf9d5Sandi                    '(?<=\b)\d+[x|X]\d+(?=\b)',$mode,'multiplyentity'
6660cecf9d5Sandi                );
6670cecf9d5Sandi
6680cecf9d5Sandi    }
6690cecf9d5Sandi
6700cecf9d5Sandi}
6710cecf9d5Sandi
6720cecf9d5Sandi//-------------------------------------------------------------------
6730cecf9d5Sandiclass Doku_Parser_Mode_Quotes extends Doku_Parser_Mode {
6740cecf9d5Sandi
6750cecf9d5Sandi    function connectTo($mode) {
6760cecf9d5Sandi
6770cecf9d5Sandi        $this->Lexer->addSpecialPattern(
6780cecf9d5Sandi                    '(?<=\s)\'(?=\S)',$mode,'singlequoteopening'
6790cecf9d5Sandi                );
6800cecf9d5Sandi        $this->Lexer->addSpecialPattern(
6814de671bcSandi                    '(?<=^|\S)\'',$mode,'singlequoteclosing'
6820cecf9d5Sandi                );
6830cecf9d5Sandi        $this->Lexer->addSpecialPattern(
6844de671bcSandi                    '(?<=^|\s)"(?=\S)',$mode,'doublequoteopening'
6850cecf9d5Sandi                );
6860cecf9d5Sandi        $this->Lexer->addSpecialPattern(
6870cecf9d5Sandi                    '(?<=\S)"',$mode,'doublequoteclosing'
6880cecf9d5Sandi                );
6890cecf9d5Sandi
6900cecf9d5Sandi    }
6910cecf9d5Sandi
6920cecf9d5Sandi}
6930cecf9d5Sandi
6940cecf9d5Sandi//-------------------------------------------------------------------
6950cecf9d5Sandiclass Doku_Parser_Mode_CamelCaseLink extends Doku_Parser_Mode {
6960cecf9d5Sandi
6970cecf9d5Sandi    function connectTo($mode) {
6980cecf9d5Sandi        $this->Lexer->addSpecialPattern(
6990cecf9d5Sandi                '\b[A-Z]+[a-z]+[A-Z][A-Za-z]*\b',$mode,'camelcaselink'
7000cecf9d5Sandi            );
7010cecf9d5Sandi    }
7020cecf9d5Sandi
7030cecf9d5Sandi}
7040cecf9d5Sandi
7050cecf9d5Sandi//-------------------------------------------------------------------
7060cecf9d5Sandiclass Doku_Parser_Mode_InternalLink extends Doku_Parser_Mode {
7070cecf9d5Sandi
7080cecf9d5Sandi    function connectTo($mode) {
7090cecf9d5Sandi        // Word boundaries?
7100cecf9d5Sandi        $this->Lexer->addSpecialPattern("\[\[[^\]]+?\]\]",$mode,'internallink');
7110cecf9d5Sandi    }
7120cecf9d5Sandi
7130cecf9d5Sandi}
7140cecf9d5Sandi
7150cecf9d5Sandi//-------------------------------------------------------------------
7160cecf9d5Sandiclass Doku_Parser_Mode_Media extends Doku_Parser_Mode {
7170cecf9d5Sandi
7180cecf9d5Sandi    function connectTo($mode) {
7190cecf9d5Sandi        // Word boundaries?
7200cecf9d5Sandi        $this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'media');
7210cecf9d5Sandi    }
7220cecf9d5Sandi
7230cecf9d5Sandi}
7240cecf9d5Sandi
7250cecf9d5Sandi//-------------------------------------------------------------------
726b625487dSandiclass Doku_Parser_Mode_RSS extends Doku_Parser_Mode {
727b625487dSandi
728b625487dSandi    function connectTo($mode) {
729b625487dSandi        $this->Lexer->addSpecialPattern("\{\{rss>[^\}]+\}\}",$mode,'rss');
730b625487dSandi    }
731b625487dSandi
732b625487dSandi}
733b625487dSandi
734b625487dSandi//-------------------------------------------------------------------
7350cecf9d5Sandiclass Doku_Parser_Mode_ExternalLink extends Doku_Parser_Mode {
7360cecf9d5Sandi    var $schemes = array('http','https','telnet','gopher','wais','ftp','ed2k','irc');
7370cecf9d5Sandi    var $patterns = array();
7380cecf9d5Sandi
7390cecf9d5Sandi    function preConnect() {
7400cecf9d5Sandi
7410cecf9d5Sandi        $ltrs = '\w';
7420cecf9d5Sandi        $gunk = '/\#~:.?+=&%@!\-';
7430cecf9d5Sandi        $punc = '.:?\-;,';
7440cecf9d5Sandi        $host = $ltrs.$punc;
7450cecf9d5Sandi        $any  = $ltrs.$gunk.$punc;
7460cecf9d5Sandi
7470cecf9d5Sandi        foreach ( $this->schemes as $scheme ) {
7486f0c5dbfSandi            $this->patterns[] = '\b(?i)'.$scheme.'(?-i)://['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
7490cecf9d5Sandi        }
7500cecf9d5Sandi
7516f0c5dbfSandi        $this->patterns[] = '\b(?i)www?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
7526f0c5dbfSandi        $this->patterns[] = '\b(?i)ftp?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
7530cecf9d5Sandi
7540cecf9d5Sandi    }
7550cecf9d5Sandi
7560cecf9d5Sandi    function connectTo($mode) {
7570cecf9d5Sandi        foreach ( $this->patterns as $pattern ) {
7580cecf9d5Sandi            $this->Lexer->addSpecialPattern($pattern,$mode,'externallink');
7590cecf9d5Sandi        }
7600cecf9d5Sandi    }
7610cecf9d5Sandi
7620cecf9d5Sandi}
7630cecf9d5Sandi
7640cecf9d5Sandi//-------------------------------------------------------------------
7650cecf9d5Sandiclass Doku_Parser_Mode_FileLink extends Doku_Parser_Mode {
7660cecf9d5Sandi
7670cecf9d5Sandi    var $pattern;
7680cecf9d5Sandi
7690cecf9d5Sandi    function preConnect() {
7700cecf9d5Sandi
7710cecf9d5Sandi        $ltrs = '\w';
7720cecf9d5Sandi        $gunk = '/\#~:.?+=&%@!\-';
7730cecf9d5Sandi        $punc = '.:?\-;,';
7740cecf9d5Sandi        $host = $ltrs.$punc;
7750cecf9d5Sandi        $any  = $ltrs.$gunk.$punc;
7760cecf9d5Sandi
7770cecf9d5Sandi        $this->pattern = '\b(?i)file(?-i)://['.$any.']+?['.
7780cecf9d5Sandi            $punc.']*[^'.$any.']';
7790cecf9d5Sandi    }
7800cecf9d5Sandi
7810cecf9d5Sandi    function connectTo($mode) {
7820cecf9d5Sandi        $this->Lexer->addSpecialPattern(
7830cecf9d5Sandi            $this->pattern,$mode,'filelink');
7840cecf9d5Sandi    }
7850cecf9d5Sandi
7860cecf9d5Sandi
7870cecf9d5Sandi}
7880cecf9d5Sandi
7890cecf9d5Sandi//-------------------------------------------------------------------
7900cecf9d5Sandiclass Doku_Parser_Mode_WindowsShareLink extends Doku_Parser_Mode {
7910cecf9d5Sandi
7920cecf9d5Sandi    var $pattern;
7930cecf9d5Sandi
7940cecf9d5Sandi    function preConnect() {
7950cecf9d5Sandi
7960cecf9d5Sandi        $ltrs = '\w';
7970cecf9d5Sandi        $gunk = '/\#~:.?+=&%@!\-';
7980cecf9d5Sandi        $punc = '.:?\-;,';
7990cecf9d5Sandi        $host = $ltrs.$punc;
8000cecf9d5Sandi        $any  = $ltrs.$gunk.$punc;
8010cecf9d5Sandi
8029c315eaeSandi        $this->pattern = "[$gunk$punc\s]\\\\\\\\[$host]+?\\\\[$any]+?(?=['.$punc.']*[^'.$any.'])";
8030cecf9d5Sandi    }
8040cecf9d5Sandi
8050cecf9d5Sandi    function connectTo($mode) {
8060cecf9d5Sandi        $this->Lexer->addSpecialPattern(
8070cecf9d5Sandi            $this->pattern,$mode,'windowssharelink');
8080cecf9d5Sandi    }
8090cecf9d5Sandi
8100cecf9d5Sandi
8110cecf9d5Sandi}
8120cecf9d5Sandi
8130cecf9d5Sandi//-------------------------------------------------------------------
81471352defSandiclass Doku_Parser_Mode_EmailLink extends Doku_Parser_Mode {
8150cecf9d5Sandi
8160cecf9d5Sandi    function connectTo($mode) {
8170cecf9d5Sandi    //<([\w0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)>
81871352defSandi        $this->Lexer->addSpecialPattern("<[\w0-9\-_.]+?@[\w\-]+\.[\w\-\.]+\.*[\w]+>",$mode,'emaillink');
8190cecf9d5Sandi    }
8200cecf9d5Sandi
8210cecf9d5Sandi}
8220cecf9d5Sandi
8230cecf9d5Sandi//-------------------------------------------------------------------
824*ee20e7d1Sandi//
825*ee20e7d1Sandi// XXX deprecated - replace by $PARSER_MODES
826*ee20e7d1Sandi//
8270cecf9d5Sandi// Help fns to keep mode lists - used to make it easier to populate
8280cecf9d5Sandi// the list of modes another mode accepts
8290cecf9d5Sandi
830*ee20e7d1Sandi/*
831*ee20e7d1Sandi
8320cecf9d5Sandi// Can contain many other modes
8330cecf9d5Sandi// E.g. a footnote can containing formatting etc.
8340cecf9d5Sandifunction Doku_Parser_BlockContainers() {
8350cecf9d5Sandi    $modes = array(
8360cecf9d5Sandi        'footnote', 'listblock', 'table','quote',
8370cecf9d5Sandi        // hr breaks the principle but HRs should not be used in tables / lists
8380cecf9d5Sandi        // so put it here
8390cecf9d5Sandi        'hr',
8400cecf9d5Sandi    );
8410cecf9d5Sandi    return $modes;
8420cecf9d5Sandi}
8430cecf9d5Sandi
8440cecf9d5Sandi// Used to mark paragraph boundaries
8450cecf9d5Sandifunction Doku_Parser_Paragraphs() {
8460cecf9d5Sandi    $modes = array(
8470cecf9d5Sandi        'eol'
8480cecf9d5Sandi    );
8490cecf9d5Sandi    return $modes;
8500cecf9d5Sandi}
8510cecf9d5Sandi
8520cecf9d5Sandi// Can only be used by the base mode
8530cecf9d5Sandifunction Doku_Parser_BaseOnly() {
8540cecf9d5Sandi    $modes = array(
8550cecf9d5Sandi        'header'
8560cecf9d5Sandi    );
8570cecf9d5Sandi    return $modes;
8580cecf9d5Sandi}
8590cecf9d5Sandi
8600cecf9d5Sandi// "Styling" modes that format text.
8610cecf9d5Sandifunction Doku_Parser_Formatting($remove = '') {
8620cecf9d5Sandi    $modes = array(
8630cecf9d5Sandi        'strong', 'emphasis', 'underline', 'monospace',
8640cecf9d5Sandi        'subscript', 'superscript', 'deleted',
8650cecf9d5Sandi        );
8660cecf9d5Sandi    $key = array_search($remove, $modes);
8670cecf9d5Sandi    if ( is_int($key) ) {
8680cecf9d5Sandi        unset($modes[$key]);
8690cecf9d5Sandi    }
8700cecf9d5Sandi
8710cecf9d5Sandi    return $modes;
8720cecf9d5Sandi}
8730cecf9d5Sandi
8740cecf9d5Sandi// Modes where the token is simply replaced - contain no
8750cecf9d5Sandi// other modes
8760cecf9d5Sandifunction Doku_Parser_Substition() {
8770cecf9d5Sandi    $modes = array(
8780cecf9d5Sandi        'acronym','smiley','wordblock','entity','camelcaselink',
87971352defSandi        'internallink','media','externallink','linebreak','emaillink',
8809dc2c2afSandi        'windowssharelink','filelink','notoc','nocache','multiplyentity',
881f1cf0e10Sandi        'quotes','rss',
8820cecf9d5Sandi    );
8830cecf9d5Sandi    return $modes;
8840cecf9d5Sandi}
8850cecf9d5Sandi
8860cecf9d5Sandi// Modes which have a start and end token but inside which
8870cecf9d5Sandi// no other modes should be applied
8880cecf9d5Sandifunction Doku_Parser_Protected() {
8890cecf9d5Sandi    $modes = array(
8900cecf9d5Sandi        'preformatted','code','file',
8910cecf9d5Sandi        'php','html','quote',
8920cecf9d5Sandi    );
8930cecf9d5Sandi    return $modes;
8940cecf9d5Sandi}
8950cecf9d5Sandi
8960cecf9d5Sandi// Disable wiki markup inside this mode
8970cecf9d5Sandifunction Doku_Parser_Disabled() {
8980cecf9d5Sandi    $modes = array(
8990cecf9d5Sandi        'unformatted'
9000cecf9d5Sandi    );
9010cecf9d5Sandi    return $modes;
9020cecf9d5Sandi}
903*ee20e7d1Sandi*/
9040cecf9d5Sandi
905*ee20e7d1Sandi// --------------------------------------------------------------------------
906340756e4Sandi
907b625487dSandi//Setup VIM: ex: et ts=4 enc=utf-8 :
908