xref: /dokuwiki/inc/parser/parser.php (revision f43b6d3ab4d4788c8b5babddfcb2c53f5cfeb443)
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
8ee20e7d1Sandi
9ee20e7d1Sandi/**
10ee20e7d1Sandi * Define various types of modes used by the parser - they are used to
11ee20e7d1Sandi * populate the list of modes another mode accepts
12ee20e7d1Sandi */
13ee20e7d1Sandiglobal $PARSER_MODES;
14ee20e7d1Sandi$PARSER_MODES = array(
15ee20e7d1Sandi    // containers are complex modes that can contain many other modes
16ee20e7d1Sandi    // hr breaks the principle but they shouldn't be used in tables / lists
17ee20e7d1Sandi    // so they are put here
18ee20e7d1Sandi    'container'    => array('listblock','table','quote','hr'),
19ee20e7d1Sandi
20ee20e7d1Sandi    // some mode are allowed inside the base mode only
21ee20e7d1Sandi    'baseonly'     => array('header'),
22ee20e7d1Sandi
23ee20e7d1Sandi    // modes for styling text -- footnote behaves similar to styling
24ee20e7d1Sandi    'formatting'   => array('strong', 'emphasis', 'underline', 'monospace',
25ee20e7d1Sandi                            'subscript', 'superscript', 'deleted', 'footnote'),
26ee20e7d1Sandi
27ee20e7d1Sandi    // modes where the token is simply replaced - they can not contain any
28ee20e7d1Sandi    // other modes
29ee20e7d1Sandi    'substition'   => array('acronym','smiley','wordblock','entity',
30ee20e7d1Sandi                            'camelcaselink', 'internallink','media',
31ee20e7d1Sandi                            'externallink','linebreak','emaillink',
32ee20e7d1Sandi                            'windowssharelink','filelink','notoc',
33ee20e7d1Sandi                            'nocache','multiplyentity','quotes','rss'),
34ee20e7d1Sandi
35ee20e7d1Sandi    // modes which have a start and end token but inside which
36ee20e7d1Sandi    // no other modes should be applied
37ee20e7d1Sandi    'protected'    => array('preformatted','code','file','php','html'),
38ee20e7d1Sandi
39ee20e7d1Sandi    // inside this mode no wiki markup should be applied but lineendings
40ee20e7d1Sandi    // and whitespace isn't preserved
41ee20e7d1Sandi    'disabled'     => array('unformatted'),
42ee20e7d1Sandi
43ee20e7d1Sandi    // used to mark paragraph boundaries
44ee20e7d1Sandi    'paragraphs'   => array('eol')
45ee20e7d1Sandi);
46ee20e7d1Sandi
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
6144881bd0Shenning.noren    var $connected = false;
620cecf9d5Sandi
63b7c441b9SHarry Fuecks    function addBaseMode(& $BaseMode) {
64b7c441b9SHarry Fuecks        $this->modes['base'] = & $BaseMode;
650cecf9d5Sandi        if ( !$this->Lexer ) {
6644881bd0Shenning.noren            $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']) ) {
77107b01d6Sandi            $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
10944881bd0Shenning.noren        $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 {
12144881bd0Shenning.noren            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
144107b01d6Sandi    // returns a number used to determine in which order modes are added
145107b01d6Sandi    function getSort() {
146107b01d6Sandi        trigger_error('getSort() not implemented in '.get_class($this), E_USER_WARNING);
147107b01d6Sandi    }
148107b01d6Sandi
1490cecf9d5Sandi    // Called before any calls to connectTo
1500cecf9d5Sandi    function preConnect() {}
1510cecf9d5Sandi
152107b01d6Sandi    // Connects the mode
1530cecf9d5Sandi    function connectTo($mode) {}
1540cecf9d5Sandi
1550cecf9d5Sandi    // Called after all calls to connectTo
1560cecf9d5Sandi    function postConnect() {}
1570cecf9d5Sandi
1580cecf9d5Sandi    function accepts($mode) {
1590cecf9d5Sandi        return in_array($mode, $this->allowedModes );
1600cecf9d5Sandi    }
1610cecf9d5Sandi
1620cecf9d5Sandi}
1630cecf9d5Sandi
1640cecf9d5Sandi//-------------------------------------------------------------------
165107b01d6Sandiclass Doku_Parser_Mode_base extends Doku_Parser_Mode {
1660cecf9d5Sandi
167107b01d6Sandi    function Doku_Parser_Mode_base() {
168ee20e7d1Sandi        global $PARSER_MODES;
1690cecf9d5Sandi
1700cecf9d5Sandi        $this->allowedModes = array_merge (
171ee20e7d1Sandi                $PARSER_MODES['container'],
172ee20e7d1Sandi                $PARSER_MODES['baseonly'],
173ee20e7d1Sandi                $PARSER_MODES['paragraphs'],
174ee20e7d1Sandi                $PARSER_MODES['formatting'],
175ee20e7d1Sandi                $PARSER_MODES['substition'],
176ee20e7d1Sandi                $PARSER_MODES['protected'],
177ee20e7d1Sandi                $PARSER_MODES['disabled']
1780cecf9d5Sandi            );
1790cecf9d5Sandi    }
180107b01d6Sandi
181107b01d6Sandi    function getSort() {
182107b01d6Sandi        return 0;
183107b01d6Sandi    }
1840cecf9d5Sandi}
1850cecf9d5Sandi
1860cecf9d5Sandi//-------------------------------------------------------------------
187107b01d6Sandiclass Doku_Parser_Mode_footnote extends Doku_Parser_Mode {
1880cecf9d5Sandi
189107b01d6Sandi    function Doku_Parser_Mode_footnote() {
190ee20e7d1Sandi        global $PARSER_MODES;
1910cecf9d5Sandi
1920cecf9d5Sandi        $this->allowedModes = array_merge (
193ee20e7d1Sandi                $PARSER_MODES['container'],
194ee20e7d1Sandi                $PARSER_MODES['formatting'],
195ee20e7d1Sandi                $PARSER_MODES['substition'],
196ee20e7d1Sandi                $PARSER_MODES['protected'],
197ee20e7d1Sandi                $PARSER_MODES['disabled']
1980cecf9d5Sandi            );
1990cecf9d5Sandi
2002fe7363dSchris        unset($this->allowedModes[array_search('footnote', $this->allowedModes)]);
2010cecf9d5Sandi    }
2020cecf9d5Sandi
2030cecf9d5Sandi    function connectTo($mode) {
2040cecf9d5Sandi        $this->Lexer->addEntryPattern(
2050cecf9d5Sandi            '\x28\x28(?=.*\x29\x29)',$mode,'footnote'
2060cecf9d5Sandi            );
2070cecf9d5Sandi    }
2080cecf9d5Sandi
2090cecf9d5Sandi    function postConnect() {
2100cecf9d5Sandi        $this->Lexer->addExitPattern(
2110cecf9d5Sandi            '\x29\x29','footnote'
2120cecf9d5Sandi            );
2130cecf9d5Sandi    }
2140cecf9d5Sandi
215107b01d6Sandi    function getSort() {
216107b01d6Sandi        return 150;
217107b01d6Sandi    }
2180cecf9d5Sandi}
2190cecf9d5Sandi
2200cecf9d5Sandi//-------------------------------------------------------------------
221107b01d6Sandiclass Doku_Parser_Mode_header extends Doku_Parser_Mode {
2220cecf9d5Sandi
2230cecf9d5Sandi    function preConnect() {
224506ae684Sandi        //we're not picky about the closing ones, two are enough
2250cecf9d5Sandi        $this->Lexer->addSpecialPattern(
22630fe9cd6SAndreas Gohr                            '[ \t]*={2,}[^\n]+={2,}[ \t]*(?=\n)',
2270cecf9d5Sandi                            'base',
2280cecf9d5Sandi                            'header'
2290cecf9d5Sandi                        );
2300cecf9d5Sandi    }
2310cecf9d5Sandi
232107b01d6Sandi    function getSort() {
233107b01d6Sandi        return 50;
234107b01d6Sandi    }
2350cecf9d5Sandi}
2360cecf9d5Sandi
2370cecf9d5Sandi//-------------------------------------------------------------------
238107b01d6Sandiclass Doku_Parser_Mode_notoc extends Doku_Parser_Mode {
2390cecf9d5Sandi
2400cecf9d5Sandi    function connectTo($mode) {
2410cecf9d5Sandi        $this->Lexer->addSpecialPattern('~~NOTOC~~',$mode,'notoc');
2420cecf9d5Sandi    }
2430cecf9d5Sandi
244107b01d6Sandi    function getSort() {
245107b01d6Sandi        return 30;
246107b01d6Sandi    }
2470cecf9d5Sandi}
2480cecf9d5Sandi
2490cecf9d5Sandi//-------------------------------------------------------------------
250107b01d6Sandiclass Doku_Parser_Mode_nocache extends Doku_Parser_Mode {
2519dc2c2afSandi
2529dc2c2afSandi    function connectTo($mode) {
2539dc2c2afSandi        $this->Lexer->addSpecialPattern('~~NOCACHE~~',$mode,'nocache');
2549dc2c2afSandi    }
2559dc2c2afSandi
256107b01d6Sandi    function getSort() {
257107b01d6Sandi        return 40;
258107b01d6Sandi    }
2599dc2c2afSandi}
2609dc2c2afSandi
2619dc2c2afSandi//-------------------------------------------------------------------
262107b01d6Sandiclass Doku_Parser_Mode_linebreak extends Doku_Parser_Mode {
2630cecf9d5Sandi
2640cecf9d5Sandi    function connectTo($mode) {
2655e100747Sandi        $this->Lexer->addSpecialPattern('\x5C{2}(?=\s)',$mode,'linebreak');
2660cecf9d5Sandi    }
267107b01d6Sandi
268107b01d6Sandi    function getSort() {
269107b01d6Sandi        return 140;
270107b01d6Sandi    }
2710cecf9d5Sandi}
2720cecf9d5Sandi
2730cecf9d5Sandi//-------------------------------------------------------------------
274107b01d6Sandiclass Doku_Parser_Mode_eol extends Doku_Parser_Mode {
2750cecf9d5Sandi
2760cecf9d5Sandi    function connectTo($mode) {
2770cecf9d5Sandi        $badModes = array('listblock','table');
2780cecf9d5Sandi        if ( in_array($mode, $badModes) ) {
2790cecf9d5Sandi            return;
2800cecf9d5Sandi        }
2810cecf9d5Sandi        $this->Lexer->addSpecialPattern('\n',$mode,'eol');
2820cecf9d5Sandi    }
283107b01d6Sandi
284107b01d6Sandi    function getSort() {
285107b01d6Sandi        return 370;
286107b01d6Sandi    }
2870cecf9d5Sandi}
2880cecf9d5Sandi
2890cecf9d5Sandi//-------------------------------------------------------------------
290107b01d6Sandiclass Doku_Parser_Mode_hr extends Doku_Parser_Mode {
2910cecf9d5Sandi
2920cecf9d5Sandi    function connectTo($mode) {
2936f0c5dbfSandi        $this->Lexer->addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr');
2940cecf9d5Sandi    }
2950cecf9d5Sandi
296107b01d6Sandi    function getSort() {
297107b01d6Sandi        return 160;
298107b01d6Sandi    }
2990cecf9d5Sandi}
3000cecf9d5Sandi
3010cecf9d5Sandi//-------------------------------------------------------------------
302107b01d6Sandiclass Doku_Parser_Mode_formatting extends Doku_Parser_Mode {
3030cecf9d5Sandi    var $type;
3040cecf9d5Sandi
3050cecf9d5Sandi    var $formatting = array (
3060cecf9d5Sandi        'strong' => array (
3070cecf9d5Sandi            'entry'=>'\*\*(?=.*\*\*)',
3080cecf9d5Sandi            'exit'=>'\*\*',
309107b01d6Sandi            'sort'=>70
3100cecf9d5Sandi            ),
3110cecf9d5Sandi
3120cecf9d5Sandi        'emphasis'=> array (
313f4b3aca3SHarry Fuecks            'entry'=>'//(?=[^\x00]*[^:]//)', //hack for bug #384
3140cecf9d5Sandi            'exit'=>'//',
315107b01d6Sandi            'sort'=>80
3160cecf9d5Sandi            ),
3170cecf9d5Sandi
3180cecf9d5Sandi        'underline'=> array (
3190cecf9d5Sandi            'entry'=>'__(?=.*__)',
3200cecf9d5Sandi            'exit'=>'__',
321107b01d6Sandi            'sort'=>90
3220cecf9d5Sandi            ),
3230cecf9d5Sandi
3240cecf9d5Sandi        'monospace'=> array (
3250cecf9d5Sandi            'entry'=>'\x27\x27(?=.*\x27\x27)',
3260cecf9d5Sandi            'exit'=>'\x27\x27',
327107b01d6Sandi            'sort'=>100
3280cecf9d5Sandi            ),
3290cecf9d5Sandi
3300cecf9d5Sandi        'subscript'=> array (
33187858f84Schris            'entry'=>'<sub>(?=.*</sub>)',
3320cecf9d5Sandi            'exit'=>'</sub>',
333107b01d6Sandi            'sort'=>110
3340cecf9d5Sandi            ),
3350cecf9d5Sandi
3360cecf9d5Sandi        'superscript'=> array (
33787858f84Schris            'entry'=>'<sup>(?=.*</sup>)',
3380cecf9d5Sandi            'exit'=>'</sup>',
339107b01d6Sandi            'sort'=>120
3400cecf9d5Sandi            ),
3410cecf9d5Sandi
3420cecf9d5Sandi        'deleted'=> array (
34387858f84Schris            'entry'=>'<del>(?=.*</del>)',
3440cecf9d5Sandi            'exit'=>'</del>',
345107b01d6Sandi            'sort'=>130
3460cecf9d5Sandi            ),
3470cecf9d5Sandi        );
3480cecf9d5Sandi
349107b01d6Sandi    function Doku_Parser_Mode_formatting($type) {
350ee20e7d1Sandi        global $PARSER_MODES;
3510cecf9d5Sandi
3520cecf9d5Sandi        if ( !array_key_exists($type, $this->formatting) ) {
3530cecf9d5Sandi            trigger_error('Invalid formatting type '.$type, E_USER_WARNING);
3540cecf9d5Sandi        }
3550cecf9d5Sandi
3560cecf9d5Sandi        $this->type = $type;
3570cecf9d5Sandi
358ee20e7d1Sandi        // formatting may contain other formatting but not it self
359ee20e7d1Sandi        $modes = $PARSER_MODES['formatting'];
360ee20e7d1Sandi        $key = array_search($type, $modes);
361ee20e7d1Sandi        if ( is_int($key) ) {
362ee20e7d1Sandi            unset($modes[$key]);
363ee20e7d1Sandi        }
3640cecf9d5Sandi
365ee20e7d1Sandi        $this->allowedModes = array_merge (
366ee20e7d1Sandi                $modes,
367ee20e7d1Sandi                $PARSER_MODES['substition'],
368ee20e7d1Sandi                $PARSER_MODES['disabled']
369ee20e7d1Sandi            );
3700cecf9d5Sandi    }
3710cecf9d5Sandi
3720cecf9d5Sandi    function connectTo($mode) {
3730cecf9d5Sandi
3740cecf9d5Sandi        // Can't nest formatting in itself
3750cecf9d5Sandi        if ( $mode == $this->type ) {
3760cecf9d5Sandi            return;
3770cecf9d5Sandi        }
3780cecf9d5Sandi
3790cecf9d5Sandi        $this->Lexer->addEntryPattern(
3800cecf9d5Sandi                $this->formatting[$this->type]['entry'],
3810cecf9d5Sandi                $mode,
3820cecf9d5Sandi                $this->type
3830cecf9d5Sandi            );
3840cecf9d5Sandi    }
3850cecf9d5Sandi
3860cecf9d5Sandi    function postConnect() {
3870cecf9d5Sandi
3880cecf9d5Sandi        $this->Lexer->addExitPattern(
3890cecf9d5Sandi            $this->formatting[$this->type]['exit'],
3900cecf9d5Sandi            $this->type
3910cecf9d5Sandi            );
3920cecf9d5Sandi
3930cecf9d5Sandi    }
394107b01d6Sandi
395107b01d6Sandi    function getSort() {
396107b01d6Sandi        return $this->formatting[$this->type]['sort'];
397107b01d6Sandi    }
3980cecf9d5Sandi}
3990cecf9d5Sandi
4000cecf9d5Sandi//-------------------------------------------------------------------
401107b01d6Sandiclass Doku_Parser_Mode_listblock extends Doku_Parser_Mode {
4020cecf9d5Sandi
403107b01d6Sandi    function Doku_Parser_Mode_listblock() {
404ee20e7d1Sandi        global $PARSER_MODES;
4050cecf9d5Sandi
4060cecf9d5Sandi        $this->allowedModes = array_merge (
407ee20e7d1Sandi                $PARSER_MODES['formatting'],
408ee20e7d1Sandi                $PARSER_MODES['substition'],
409ee20e7d1Sandi                $PARSER_MODES['disabled'],
410ee20e7d1Sandi                $PARSER_MODES['protected'] #XXX new
4110cecf9d5Sandi            );
412702eb898Sandi
413ee20e7d1Sandi    //    $this->allowedModes[] = 'footnote';
4140cecf9d5Sandi    }
4150cecf9d5Sandi
4160cecf9d5Sandi    function connectTo($mode) {
4170cecf9d5Sandi        $this->Lexer->addEntryPattern('\n {2,}[\-\*]',$mode,'listblock');
4180cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\t{1,}[\-\*]',$mode,'listblock');
4190cecf9d5Sandi
4200cecf9d5Sandi        $this->Lexer->addPattern('\n {2,}[\-\*]','listblock');
4210cecf9d5Sandi        $this->Lexer->addPattern('\n\t{1,}[\-\*]','listblock');
4220cecf9d5Sandi
4230cecf9d5Sandi    }
4240cecf9d5Sandi
4250cecf9d5Sandi    function postConnect() {
4260cecf9d5Sandi        $this->Lexer->addExitPattern('\n','listblock');
4270cecf9d5Sandi    }
428107b01d6Sandi
429107b01d6Sandi    function getSort() {
430107b01d6Sandi        return 10;
431107b01d6Sandi    }
4320cecf9d5Sandi}
4330cecf9d5Sandi
4340cecf9d5Sandi//-------------------------------------------------------------------
435107b01d6Sandiclass Doku_Parser_Mode_table extends Doku_Parser_Mode {
4360cecf9d5Sandi
437107b01d6Sandi    function Doku_Parser_Mode_table() {
438ee20e7d1Sandi        global $PARSER_MODES;
4390cecf9d5Sandi
4400cecf9d5Sandi        $this->allowedModes = array_merge (
441ee20e7d1Sandi                $PARSER_MODES['formatting'],
442ee20e7d1Sandi                $PARSER_MODES['substition'],
443ee20e7d1Sandi                $PARSER_MODES['disabled'],
444107b01d6Sandi                $PARSER_MODES['protected']
4450cecf9d5Sandi            );
4460cecf9d5Sandi    }
4470cecf9d5Sandi
4480cecf9d5Sandi    function connectTo($mode) {
4490cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\^',$mode,'table');
4500cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\|',$mode,'table');
4510cecf9d5Sandi    }
4520cecf9d5Sandi
4530cecf9d5Sandi    function postConnect() {
4540cecf9d5Sandi        $this->Lexer->addPattern('\n\^','table');
4550cecf9d5Sandi        $this->Lexer->addPattern('\n\|','table');
4569ab75d9eSAndreas Gohr        #$this->Lexer->addPattern(' {2,}','table');
4579ab75d9eSAndreas Gohr        $this->Lexer->addPattern('[\t ]+','table');
4580cecf9d5Sandi        $this->Lexer->addPattern('\^','table');
4590cecf9d5Sandi        $this->Lexer->addPattern('\|','table');
4600cecf9d5Sandi        $this->Lexer->addExitPattern('\n','table');
4610cecf9d5Sandi    }
462107b01d6Sandi
463107b01d6Sandi    function getSort() {
464107b01d6Sandi        return 60;
465107b01d6Sandi    }
4660cecf9d5Sandi}
4670cecf9d5Sandi
4680cecf9d5Sandi//-------------------------------------------------------------------
469107b01d6Sandiclass Doku_Parser_Mode_unformatted extends Doku_Parser_Mode {
4700cecf9d5Sandi
4710cecf9d5Sandi    function connectTo($mode) {
47287858f84Schris        $this->Lexer->addEntryPattern('<nowiki>(?=.*</nowiki>)',$mode,'unformatted');
4730cecf9d5Sandi        $this->Lexer->addEntryPattern('%%(?=.*%%)',$mode,'unformattedalt');
4740cecf9d5Sandi    }
4750cecf9d5Sandi
4760cecf9d5Sandi    function postConnect() {
4770cecf9d5Sandi        $this->Lexer->addExitPattern('</nowiki>','unformatted');
4780cecf9d5Sandi        $this->Lexer->addExitPattern('%%','unformattedalt');
4790cecf9d5Sandi        $this->Lexer->mapHandler('unformattedalt','unformatted');
4800cecf9d5Sandi    }
4810cecf9d5Sandi
482107b01d6Sandi    function getSort() {
483107b01d6Sandi        return 170;
484107b01d6Sandi    }
4850cecf9d5Sandi}
4860cecf9d5Sandi
4870cecf9d5Sandi//-------------------------------------------------------------------
488107b01d6Sandiclass Doku_Parser_Mode_php extends Doku_Parser_Mode {
4890cecf9d5Sandi
4900cecf9d5Sandi    function connectTo($mode) {
49187858f84Schris        $this->Lexer->addEntryPattern('<php>(?=.*</php>)',$mode,'php');
4920cecf9d5Sandi    }
4930cecf9d5Sandi
4940cecf9d5Sandi    function postConnect() {
4950cecf9d5Sandi        $this->Lexer->addExitPattern('</php>','php');
4960cecf9d5Sandi    }
4970cecf9d5Sandi
498107b01d6Sandi    function getSort() {
499107b01d6Sandi        return 180;
500107b01d6Sandi    }
5010cecf9d5Sandi}
5020cecf9d5Sandi
5030cecf9d5Sandi//-------------------------------------------------------------------
504107b01d6Sandiclass Doku_Parser_Mode_html extends Doku_Parser_Mode {
5050cecf9d5Sandi
5060cecf9d5Sandi    function connectTo($mode) {
50787858f84Schris        $this->Lexer->addEntryPattern('<html>(?=.*</html>)',$mode,'html');
5080cecf9d5Sandi    }
5090cecf9d5Sandi
5100cecf9d5Sandi    function postConnect() {
5110cecf9d5Sandi        $this->Lexer->addExitPattern('</html>','html');
5120cecf9d5Sandi    }
5130cecf9d5Sandi
514107b01d6Sandi    function getSort() {
515107b01d6Sandi        return 190;
516107b01d6Sandi    }
5170cecf9d5Sandi}
5180cecf9d5Sandi
5190cecf9d5Sandi//-------------------------------------------------------------------
520107b01d6Sandiclass Doku_Parser_Mode_preformatted extends Doku_Parser_Mode {
5210cecf9d5Sandi
5220cecf9d5Sandi    function connectTo($mode) {
5230cecf9d5Sandi        // Has hard coded awareness of lists...
5240cecf9d5Sandi        $this->Lexer->addEntryPattern('\n  (?![\*\-])',$mode,'preformatted');
5250cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\t(?![\*\-])',$mode,'preformatted');
5260cecf9d5Sandi
5270cecf9d5Sandi        // How to effect a sub pattern with the Lexer!
5280cecf9d5Sandi        $this->Lexer->addPattern('\n  ','preformatted');
5290cecf9d5Sandi        $this->Lexer->addPattern('\n\t','preformatted');
5300cecf9d5Sandi
5310cecf9d5Sandi    }
5320cecf9d5Sandi
5330cecf9d5Sandi    function postConnect() {
5340cecf9d5Sandi        $this->Lexer->addExitPattern('\n','preformatted');
5350cecf9d5Sandi    }
5360cecf9d5Sandi
537107b01d6Sandi    function getSort() {
538107b01d6Sandi        return 20;
539107b01d6Sandi    }
5400cecf9d5Sandi}
5410cecf9d5Sandi
5420cecf9d5Sandi//-------------------------------------------------------------------
543107b01d6Sandiclass Doku_Parser_Mode_code extends Doku_Parser_Mode {
5440cecf9d5Sandi
5450cecf9d5Sandi    function connectTo($mode) {
54687858f84Schris        $this->Lexer->addEntryPattern('<code(?=.*</code>)',$mode,'code');
5470cecf9d5Sandi    }
5480cecf9d5Sandi
5490cecf9d5Sandi    function postConnect() {
5500cecf9d5Sandi        $this->Lexer->addExitPattern('</code>','code');
5510cecf9d5Sandi    }
5520cecf9d5Sandi
553107b01d6Sandi    function getSort() {
554107b01d6Sandi        return 200;
555107b01d6Sandi    }
5560cecf9d5Sandi}
5570cecf9d5Sandi
5580cecf9d5Sandi//-------------------------------------------------------------------
559107b01d6Sandiclass Doku_Parser_Mode_file extends Doku_Parser_Mode {
5600cecf9d5Sandi
5610cecf9d5Sandi    function connectTo($mode) {
56287858f84Schris        $this->Lexer->addEntryPattern('<file>(?=.*</file>)',$mode,'file');
5630cecf9d5Sandi    }
5640cecf9d5Sandi
5650cecf9d5Sandi    function postConnect() {
5660cecf9d5Sandi        $this->Lexer->addExitPattern('</file>','file');
5670cecf9d5Sandi    }
5680cecf9d5Sandi
569107b01d6Sandi    function getSort() {
570107b01d6Sandi        return 210;
571107b01d6Sandi    }
5720cecf9d5Sandi}
5730cecf9d5Sandi
5740cecf9d5Sandi//-------------------------------------------------------------------
575107b01d6Sandiclass Doku_Parser_Mode_quote extends Doku_Parser_Mode {
5760cecf9d5Sandi
577107b01d6Sandi    function Doku_Parser_Mode_quote() {
578ee20e7d1Sandi        global $PARSER_MODES;
5790cecf9d5Sandi
5800cecf9d5Sandi        $this->allowedModes = array_merge (
581ee20e7d1Sandi                $PARSER_MODES['formatting'],
582ee20e7d1Sandi                $PARSER_MODES['substition'],
583ee20e7d1Sandi                $PARSER_MODES['disabled'],
584ee20e7d1Sandi                $PARSER_MODES['protected'] #XXX new
5850cecf9d5Sandi            );
586ee20e7d1Sandi            #$this->allowedModes[] = 'footnote';
587ee20e7d1Sandi            #$this->allowedModes[] = 'preformatted';
588ee20e7d1Sandi            #$this->allowedModes[] = 'unformatted';
5890cecf9d5Sandi    }
5900cecf9d5Sandi
5910cecf9d5Sandi    function connectTo($mode) {
5920cecf9d5Sandi        $this->Lexer->addEntryPattern('\n>{1,}',$mode,'quote');
5930cecf9d5Sandi    }
5940cecf9d5Sandi
5950cecf9d5Sandi    function postConnect() {
5960cecf9d5Sandi        $this->Lexer->addPattern('\n>{1,}','quote');
5970cecf9d5Sandi        $this->Lexer->addExitPattern('\n','quote');
5980cecf9d5Sandi    }
5990cecf9d5Sandi
600107b01d6Sandi    function getSort() {
601107b01d6Sandi        return 220;
602107b01d6Sandi    }
6030cecf9d5Sandi}
6040cecf9d5Sandi
6050cecf9d5Sandi//-------------------------------------------------------------------
606107b01d6Sandiclass Doku_Parser_Mode_acronym extends Doku_Parser_Mode {
6070cecf9d5Sandi    // A list
6080cecf9d5Sandi    var $acronyms = array();
6090cecf9d5Sandi    var $pattern = '';
6100cecf9d5Sandi
611107b01d6Sandi    function Doku_Parser_Mode_acronym($acronyms) {
6120cecf9d5Sandi        $this->acronyms = $acronyms;
6130cecf9d5Sandi    }
6140cecf9d5Sandi
6150cecf9d5Sandi    function preConnect() {
616901c1c87SAndreas Gohr        if(!count($this->acronyms)) return;
617901c1c87SAndreas Gohr
6188e266198SAndreas Gohr        $bound = '[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]';
619e6258e07SAndreas Gohr        $acronyms = array_map('Doku_Lexer_Escape',$this->acronyms);
6208e266198SAndreas Gohr        $this->pattern = '(?<=^|'.$bound.')(?:'.join('|',$acronyms).')(?='.$bound.')';
6210cecf9d5Sandi    }
6220cecf9d5Sandi
6230cecf9d5Sandi    function connectTo($mode) {
624901c1c87SAndreas Gohr        if(!count($this->acronyms)) return;
625901c1c87SAndreas Gohr
6260cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
6270cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'acronym');
6280cecf9d5Sandi        }
6290cecf9d5Sandi    }
6300cecf9d5Sandi
631107b01d6Sandi    function getSort() {
632107b01d6Sandi        return 240;
633107b01d6Sandi    }
6340cecf9d5Sandi}
6350cecf9d5Sandi
6360cecf9d5Sandi//-------------------------------------------------------------------
637107b01d6Sandiclass Doku_Parser_Mode_smiley extends Doku_Parser_Mode {
6380cecf9d5Sandi    // A list
6390cecf9d5Sandi    var $smileys = array();
6400cecf9d5Sandi    var $pattern = '';
6410cecf9d5Sandi
642107b01d6Sandi    function Doku_Parser_Mode_smiley($smileys) {
6430cecf9d5Sandi        $this->smileys = $smileys;
6440cecf9d5Sandi    }
6450cecf9d5Sandi
6460cecf9d5Sandi    function preConnect() {
647d4834a19SStephane Chazelas        if(!count($this->smileys) || $this->pattern != '') return;
648901c1c87SAndreas Gohr
6490cecf9d5Sandi        $sep = '';
6500cecf9d5Sandi        foreach ( $this->smileys as $smiley ) {
6510cecf9d5Sandi            $this->pattern .= $sep.Doku_Lexer_Escape($smiley);
6520cecf9d5Sandi            $sep = '|';
6530cecf9d5Sandi        }
6540cecf9d5Sandi    }
6550cecf9d5Sandi
6560cecf9d5Sandi    function connectTo($mode) {
657901c1c87SAndreas Gohr        if(!count($this->smileys)) return;
658901c1c87SAndreas Gohr
6590cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
6600cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'smiley');
6610cecf9d5Sandi        }
6620cecf9d5Sandi    }
6630cecf9d5Sandi
664107b01d6Sandi    function getSort() {
665107b01d6Sandi        return 230;
666107b01d6Sandi    }
6670cecf9d5Sandi}
6680cecf9d5Sandi
6690cecf9d5Sandi//-------------------------------------------------------------------
670107b01d6Sandiclass Doku_Parser_Mode_wordblock extends Doku_Parser_Mode {
6710cecf9d5Sandi    // A list
6720cecf9d5Sandi    var $badwords = array();
6730cecf9d5Sandi    var $pattern = '';
6740cecf9d5Sandi
675107b01d6Sandi    function Doku_Parser_Mode_wordblock($badwords) {
6760cecf9d5Sandi        $this->badwords = $badwords;
6770cecf9d5Sandi    }
6780cecf9d5Sandi
6790cecf9d5Sandi    function preConnect() {
6800cecf9d5Sandi
681d4834a19SStephane Chazelas        if ( count($this->badwords) == 0 || $this->pattern != '') {
6820cecf9d5Sandi            return;
6830cecf9d5Sandi        }
6840cecf9d5Sandi
6850cecf9d5Sandi        $sep = '';
6860cecf9d5Sandi        foreach ( $this->badwords as $badword ) {
6870cecf9d5Sandi            $this->pattern .= $sep.'(?<=\b)(?i)'.Doku_Lexer_Escape($badword).'(?-i)(?=\b)';
6880cecf9d5Sandi            $sep = '|';
6890cecf9d5Sandi        }
6900cecf9d5Sandi
6910cecf9d5Sandi    }
6920cecf9d5Sandi
6930cecf9d5Sandi    function connectTo($mode) {
6940cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
6950cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'wordblock');
6960cecf9d5Sandi        }
6970cecf9d5Sandi    }
6980cecf9d5Sandi
699107b01d6Sandi    function getSort() {
700107b01d6Sandi        return 250;
701107b01d6Sandi    }
7020cecf9d5Sandi}
7030cecf9d5Sandi
7040cecf9d5Sandi//-------------------------------------------------------------------
7050cecf9d5Sandi/**
7064de671bcSandi* @TODO Quotes and 640x480 are not supported - just straight replacements here
7070cecf9d5Sandi*/
708107b01d6Sandiclass Doku_Parser_Mode_entity extends Doku_Parser_Mode {
7090cecf9d5Sandi    // A list
7100cecf9d5Sandi    var $entities = array();
7110cecf9d5Sandi    var $pattern = '';
7120cecf9d5Sandi
713107b01d6Sandi    function Doku_Parser_Mode_entity($entities) {
7140cecf9d5Sandi        $this->entities = $entities;
7150cecf9d5Sandi    }
7160cecf9d5Sandi
7170cecf9d5Sandi    function preConnect() {
718d4834a19SStephane Chazelas        if(!count($this->entities) || $this->pattern != '') return;
719901c1c87SAndreas Gohr
7200cecf9d5Sandi        $sep = '';
7210cecf9d5Sandi        foreach ( $this->entities as $entity ) {
7220cecf9d5Sandi            $this->pattern .= $sep.Doku_Lexer_Escape($entity);
7230cecf9d5Sandi            $sep = '|';
7240cecf9d5Sandi        }
7250cecf9d5Sandi    }
7260cecf9d5Sandi
7270cecf9d5Sandi    function connectTo($mode) {
728901c1c87SAndreas Gohr        if(!count($this->entities)) return;
729901c1c87SAndreas Gohr
7300cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
7310cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'entity');
7320cecf9d5Sandi        }
7330cecf9d5Sandi    }
7340cecf9d5Sandi
735107b01d6Sandi    function getSort() {
736107b01d6Sandi        return 260;
737107b01d6Sandi    }
7380cecf9d5Sandi}
7390cecf9d5Sandi
7400cecf9d5Sandi//-------------------------------------------------------------------
7410cecf9d5Sandi// Implements the 640x480 replacement
742107b01d6Sandiclass Doku_Parser_Mode_multiplyentity extends Doku_Parser_Mode {
7430cecf9d5Sandi
7440cecf9d5Sandi    function connectTo($mode) {
7450cecf9d5Sandi
7460cecf9d5Sandi        $this->Lexer->addSpecialPattern(
747e7464db8Sandi                    '(?<=\b)\d+[xX]\d+(?=\b)',$mode,'multiplyentity'
7480cecf9d5Sandi                );
7490cecf9d5Sandi
7500cecf9d5Sandi    }
7510cecf9d5Sandi
752107b01d6Sandi    function getSort() {
753107b01d6Sandi        return 270;
754107b01d6Sandi    }
7550cecf9d5Sandi}
7560cecf9d5Sandi
7570cecf9d5Sandi//-------------------------------------------------------------------
758107b01d6Sandiclass Doku_Parser_Mode_quotes extends Doku_Parser_Mode {
7590cecf9d5Sandi
7600cecf9d5Sandi    function connectTo($mode) {
761*f43b6d3aSAndreas Gohr        $ws  =  '[\s/\#~:+=&%@\-;,\x28\x29\]\[{}><"\']';   // whitespace
762*f43b6d3aSAndreas Gohr        $nws = '[^\s/\#~:+=&%@\-;,\x28\x29\]\[{}><"\']';  // non whitespace
7630cecf9d5Sandi
7640cecf9d5Sandi        $this->Lexer->addSpecialPattern(
76557d757d1SAndreas Gohr                    "(?<=^|$ws)'(?=$nws)",$mode,'singlequoteopening'
7660cecf9d5Sandi                );
7670cecf9d5Sandi        $this->Lexer->addSpecialPattern(
76857d757d1SAndreas Gohr                    "(?<=^|$nws)'(?=$|$ws)",$mode,'singlequoteclosing'
7690cecf9d5Sandi                );
7700cecf9d5Sandi        $this->Lexer->addSpecialPattern(
77157d757d1SAndreas Gohr                    "(?<=^|$nws)'(?=$|$nws)",$mode,'apostrophe'
7720cecf9d5Sandi                );
7730cecf9d5Sandi        $this->Lexer->addSpecialPattern(
77457d757d1SAndreas Gohr                    "(?<=^|$ws)\"(?=$nws)",$mode,'doublequoteopening'
7750cecf9d5Sandi                );
77657d757d1SAndreas Gohr        $this->Lexer->addSpecialPattern(
77757d757d1SAndreas Gohr                    "(?<=^|$nws)\"",$mode,'doublequoteclosing'
77857d757d1SAndreas Gohr                );
77957d757d1SAndreas Gohr
7800cecf9d5Sandi
7810cecf9d5Sandi    }
7820cecf9d5Sandi
783107b01d6Sandi    function getSort() {
784107b01d6Sandi        return 280;
785107b01d6Sandi    }
7860cecf9d5Sandi}
7870cecf9d5Sandi
7880cecf9d5Sandi//-------------------------------------------------------------------
789107b01d6Sandiclass Doku_Parser_Mode_camelcaselink extends Doku_Parser_Mode {
7900cecf9d5Sandi
7910cecf9d5Sandi    function connectTo($mode) {
7920cecf9d5Sandi        $this->Lexer->addSpecialPattern(
7930cecf9d5Sandi                '\b[A-Z]+[a-z]+[A-Z][A-Za-z]*\b',$mode,'camelcaselink'
7940cecf9d5Sandi            );
7950cecf9d5Sandi    }
7960cecf9d5Sandi
797107b01d6Sandi    function getSort() {
798107b01d6Sandi        return 290;
799107b01d6Sandi    }
8000cecf9d5Sandi}
8010cecf9d5Sandi
8020cecf9d5Sandi//-------------------------------------------------------------------
803107b01d6Sandiclass Doku_Parser_Mode_internallink extends Doku_Parser_Mode {
8040cecf9d5Sandi
8050cecf9d5Sandi    function connectTo($mode) {
8060cecf9d5Sandi        // Word boundaries?
807a6755281Sandi        $this->Lexer->addSpecialPattern("\[\[.+?\]\]",$mode,'internallink');
8080cecf9d5Sandi    }
8090cecf9d5Sandi
810107b01d6Sandi    function getSort() {
811107b01d6Sandi        return 300;
812107b01d6Sandi    }
8130cecf9d5Sandi}
8140cecf9d5Sandi
8150cecf9d5Sandi//-------------------------------------------------------------------
816107b01d6Sandiclass Doku_Parser_Mode_media extends Doku_Parser_Mode {
8170cecf9d5Sandi
8180cecf9d5Sandi    function connectTo($mode) {
8190cecf9d5Sandi        // Word boundaries?
8200cecf9d5Sandi        $this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'media');
8210cecf9d5Sandi    }
8220cecf9d5Sandi
823107b01d6Sandi    function getSort() {
824107b01d6Sandi        return 320;
825107b01d6Sandi    }
8260cecf9d5Sandi}
8270cecf9d5Sandi
8280cecf9d5Sandi//-------------------------------------------------------------------
829107b01d6Sandiclass Doku_Parser_Mode_rss extends Doku_Parser_Mode {
830b625487dSandi
831b625487dSandi    function connectTo($mode) {
832b625487dSandi        $this->Lexer->addSpecialPattern("\{\{rss>[^\}]+\}\}",$mode,'rss');
833b625487dSandi    }
834b625487dSandi
835107b01d6Sandi    function getSort() {
836107b01d6Sandi        return 310;
837107b01d6Sandi    }
838b625487dSandi}
839b625487dSandi
840b625487dSandi//-------------------------------------------------------------------
841107b01d6Sandiclass Doku_Parser_Mode_externallink extends Doku_Parser_Mode {
842ee3d998eSGuy Brand gb@isis.u-strasbg.fr    var $schemes = array('http','https','telnet','gopher','wais','ftp','ed2k','irc','ldap');
8430cecf9d5Sandi    var $patterns = array();
8440cecf9d5Sandi
8450cecf9d5Sandi    function preConnect() {
846d4834a19SStephane Chazelas        if(count($this->patterns)) return;
8470cecf9d5Sandi
8480cecf9d5Sandi        $ltrs = '\w';
8490cecf9d5Sandi        $gunk = '/\#~:.?+=&%@!\-';
8500cecf9d5Sandi        $punc = '.:?\-;,';
8510cecf9d5Sandi        $host = $ltrs.$punc;
8520cecf9d5Sandi        $any  = $ltrs.$gunk.$punc;
8530cecf9d5Sandi
8540cecf9d5Sandi        foreach ( $this->schemes as $scheme ) {
8556f0c5dbfSandi            $this->patterns[] = '\b(?i)'.$scheme.'(?-i)://['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
8560cecf9d5Sandi        }
8570cecf9d5Sandi
8586f0c5dbfSandi        $this->patterns[] = '\b(?i)www?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
8596f0c5dbfSandi        $this->patterns[] = '\b(?i)ftp?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
8600cecf9d5Sandi
8610cecf9d5Sandi    }
8620cecf9d5Sandi
8630cecf9d5Sandi    function connectTo($mode) {
864d4834a19SStephane Chazelas
8650cecf9d5Sandi        foreach ( $this->patterns as $pattern ) {
8660cecf9d5Sandi            $this->Lexer->addSpecialPattern($pattern,$mode,'externallink');
8670cecf9d5Sandi        }
8680cecf9d5Sandi    }
8690cecf9d5Sandi
870107b01d6Sandi    function getSort() {
871107b01d6Sandi        return 330;
872107b01d6Sandi    }
8730cecf9d5Sandi}
8740cecf9d5Sandi
8750cecf9d5Sandi//-------------------------------------------------------------------
876107b01d6Sandiclass Doku_Parser_Mode_filelink extends Doku_Parser_Mode {
8770cecf9d5Sandi
8780cecf9d5Sandi    var $pattern;
8790cecf9d5Sandi
8800cecf9d5Sandi    function preConnect() {
8810cecf9d5Sandi
8820cecf9d5Sandi        $ltrs = '\w';
8830cecf9d5Sandi        $gunk = '/\#~:.?+=&%@!\-';
8840cecf9d5Sandi        $punc = '.:?\-;,';
8850cecf9d5Sandi        $host = $ltrs.$punc;
8860cecf9d5Sandi        $any  = $ltrs.$gunk.$punc;
8870cecf9d5Sandi
8880cecf9d5Sandi        $this->pattern = '\b(?i)file(?-i)://['.$any.']+?['.
8890cecf9d5Sandi            $punc.']*[^'.$any.']';
8900cecf9d5Sandi    }
8910cecf9d5Sandi
8920cecf9d5Sandi    function connectTo($mode) {
8930cecf9d5Sandi        $this->Lexer->addSpecialPattern(
8940cecf9d5Sandi            $this->pattern,$mode,'filelink');
8950cecf9d5Sandi    }
8960cecf9d5Sandi
897107b01d6Sandi    function getSort() {
898107b01d6Sandi        return 360;
899107b01d6Sandi    }
9000cecf9d5Sandi}
9010cecf9d5Sandi
9020cecf9d5Sandi//-------------------------------------------------------------------
903107b01d6Sandiclass Doku_Parser_Mode_windowssharelink extends Doku_Parser_Mode {
9040cecf9d5Sandi
9050cecf9d5Sandi    var $pattern;
9060cecf9d5Sandi
9070cecf9d5Sandi    function preConnect() {
9086d447503Sandi        $this->pattern = "\\\\\\\\\w+?(?:\\\\[\w$]+)+";
9090cecf9d5Sandi    }
9100cecf9d5Sandi
9110cecf9d5Sandi    function connectTo($mode) {
9120cecf9d5Sandi        $this->Lexer->addSpecialPattern(
9130cecf9d5Sandi            $this->pattern,$mode,'windowssharelink');
9140cecf9d5Sandi    }
9150cecf9d5Sandi
916107b01d6Sandi    function getSort() {
917107b01d6Sandi        return 350;
918107b01d6Sandi    }
9190cecf9d5Sandi}
9200cecf9d5Sandi
9210cecf9d5Sandi//-------------------------------------------------------------------
922107b01d6Sandiclass Doku_Parser_Mode_emaillink extends Doku_Parser_Mode {
9230cecf9d5Sandi
9240cecf9d5Sandi    function connectTo($mode) {
9250a1d30bfSchris        // pattern below is defined in inc/mail.php
9260a1d30bfSchris        $this->Lexer->addSpecialPattern('<'.PREG_PATTERN_VALID_EMAIL.'>',$mode,'emaillink');
9270cecf9d5Sandi    }
9280cecf9d5Sandi
929107b01d6Sandi    function getSort() {
930107b01d6Sandi        return 340;
931107b01d6Sandi    }
9320cecf9d5Sandi}
9330cecf9d5Sandi
934340756e4Sandi
935b625487dSandi//Setup VIM: ex: et ts=4 enc=utf-8 :
936