xref: /dokuwiki/inc/parser/parser.php (revision 30897fec7ecf86fbc37c5a38d4a05c25203aaa44)
10cecf9d5Sandi<?php
2fa8adffeSAndreas Gohrif(!defined('DOKU_INC')) die('meh.');
30cecf9d5Sandirequire_once DOKU_INC . 'inc/parser/lexer.php';
40cecf9d5Sandirequire_once DOKU_INC . 'inc/parser/handler.php';
50cecf9d5Sandi
6ee20e7d1Sandi
7ee20e7d1Sandi/**
8ee20e7d1Sandi * Define various types of modes used by the parser - they are used to
9ee20e7d1Sandi * populate the list of modes another mode accepts
10ee20e7d1Sandi */
11ee20e7d1Sandiglobal $PARSER_MODES;
12ee20e7d1Sandi$PARSER_MODES = array(
13ee20e7d1Sandi    // containers are complex modes that can contain many other modes
14ee20e7d1Sandi    // hr breaks the principle but they shouldn't be used in tables / lists
15ee20e7d1Sandi    // so they are put here
16ee20e7d1Sandi    'container'    => array('listblock','table','quote','hr'),
17ee20e7d1Sandi
18ee20e7d1Sandi    // some mode are allowed inside the base mode only
19ee20e7d1Sandi    'baseonly'     => array('header'),
20ee20e7d1Sandi
21ee20e7d1Sandi    // modes for styling text -- footnote behaves similar to styling
22ee20e7d1Sandi    'formatting'   => array('strong', 'emphasis', 'underline', 'monospace',
23ee20e7d1Sandi                            'subscript', 'superscript', 'deleted', 'footnote'),
24ee20e7d1Sandi
25ee20e7d1Sandi    // modes where the token is simply replaced - they can not contain any
26ee20e7d1Sandi    // other modes
27ee20e7d1Sandi    'substition'   => array('acronym','smiley','wordblock','entity',
28ee20e7d1Sandi                            'camelcaselink', 'internallink','media',
29ee20e7d1Sandi                            'externallink','linebreak','emaillink',
30ee20e7d1Sandi                            'windowssharelink','filelink','notoc',
31ee20e7d1Sandi                            'nocache','multiplyentity','quotes','rss'),
32ee20e7d1Sandi
33ee20e7d1Sandi    // modes which have a start and end token but inside which
34ee20e7d1Sandi    // no other modes should be applied
3507f89c3cSAnika Henke    'protected'    => array('preformatted','code','file','php','html','htmlblock','phpblock'),
36ee20e7d1Sandi
37ee20e7d1Sandi    // inside this mode no wiki markup should be applied but lineendings
38ee20e7d1Sandi    // and whitespace isn't preserved
39ee20e7d1Sandi    'disabled'     => array('unformatted'),
40ee20e7d1Sandi
41ee20e7d1Sandi    // used to mark paragraph boundaries
42ee20e7d1Sandi    'paragraphs'   => array('eol')
43ee20e7d1Sandi);
44ee20e7d1Sandi
450cecf9d5Sandi//-------------------------------------------------------------------
460cecf9d5Sandi
470cecf9d5Sandi/**
480cecf9d5Sandi* Sets up the Lexer with modes and points it to the Handler
490cecf9d5Sandi* For an intro to the Lexer see: wiki:parser
500cecf9d5Sandi*/
510cecf9d5Sandiclass Doku_Parser {
520cecf9d5Sandi
530cecf9d5Sandi    var $Handler;
540cecf9d5Sandi
550cecf9d5Sandi    var $Lexer;
560cecf9d5Sandi
570cecf9d5Sandi    var $modes = array();
580cecf9d5Sandi
5944881bd0Shenning.noren    var $connected = false;
600cecf9d5Sandi
61b7c441b9SHarry Fuecks    function addBaseMode(& $BaseMode) {
62b7c441b9SHarry Fuecks        $this->modes['base'] = & $BaseMode;
630cecf9d5Sandi        if ( !$this->Lexer ) {
6444881bd0Shenning.noren            $this->Lexer = & new Doku_Lexer($this->Handler,'base', true);
650cecf9d5Sandi        }
660cecf9d5Sandi        $this->modes['base']->Lexer = & $this->Lexer;
670cecf9d5Sandi    }
680cecf9d5Sandi
690cecf9d5Sandi    /**
700cecf9d5Sandi    * PHP preserves order of associative elements
710cecf9d5Sandi    * Mode sequence is important
720cecf9d5Sandi    */
730cecf9d5Sandi    function addMode($name, & $Mode) {
740cecf9d5Sandi        if ( !isset($this->modes['base']) ) {
75107b01d6Sandi            $this->addBaseMode(new Doku_Parser_Mode_base());
760cecf9d5Sandi        }
770cecf9d5Sandi        $Mode->Lexer = & $this->Lexer;
780cecf9d5Sandi        $this->modes[$name] = & $Mode;
790cecf9d5Sandi    }
800cecf9d5Sandi
810cecf9d5Sandi    function connectModes() {
820cecf9d5Sandi
830cecf9d5Sandi        if ( $this->connected ) {
840cecf9d5Sandi            return;
850cecf9d5Sandi        }
860cecf9d5Sandi
870cecf9d5Sandi        foreach ( array_keys($this->modes) as $mode ) {
880cecf9d5Sandi
890cecf9d5Sandi            // Base isn't connected to anything
900cecf9d5Sandi            if ( $mode == 'base' ) {
910cecf9d5Sandi                continue;
920cecf9d5Sandi            }
930cecf9d5Sandi
940cecf9d5Sandi            $this->modes[$mode]->preConnect();
950cecf9d5Sandi
960cecf9d5Sandi            foreach ( array_keys($this->modes) as $cm ) {
970cecf9d5Sandi
980cecf9d5Sandi                if ( $this->modes[$cm]->accepts($mode) ) {
990cecf9d5Sandi                    $this->modes[$mode]->connectTo($cm);
1000cecf9d5Sandi                }
1010cecf9d5Sandi
1020cecf9d5Sandi            }
1030cecf9d5Sandi
1040cecf9d5Sandi            $this->modes[$mode]->postConnect();
1050cecf9d5Sandi        }
1060cecf9d5Sandi
10744881bd0Shenning.noren        $this->connected = true;
1080cecf9d5Sandi    }
1090cecf9d5Sandi
1100cecf9d5Sandi    function parse($doc) {
1110cecf9d5Sandi        if ( $this->Lexer ) {
1120cecf9d5Sandi            $this->connectModes();
1130cecf9d5Sandi            // Normalize CRs and pad doc
1140cecf9d5Sandi            $doc = "\n".str_replace("\r\n","\n",$doc)."\n";
1150cecf9d5Sandi            $this->Lexer->parse($doc);
116433bef32Sandi            $this->Handler->_finalize();
1170cecf9d5Sandi            return $this->Handler->calls;
1180cecf9d5Sandi        } else {
11944881bd0Shenning.noren            return false;
1200cecf9d5Sandi        }
1210cecf9d5Sandi    }
1220cecf9d5Sandi
1230cecf9d5Sandi}
1240cecf9d5Sandi
1250cecf9d5Sandi//-------------------------------------------------------------------
1260cecf9d5Sandi/**
1270cecf9d5Sandi * This class and all the subclasses below are
1280cecf9d5Sandi * used to reduce the effort required to register
1290cecf9d5Sandi * modes with the Lexer. For performance these
1300cecf9d5Sandi * could all be eliminated later perhaps, or
1310cecf9d5Sandi * the Parser could be serialized to a file once
1320cecf9d5Sandi * all modes are registered
133702eb898Sandi *
1340b7c14c2Sandi * @author Harry Fuecks <hfuecks@gmail.com>
1350cecf9d5Sandi*/
1360cecf9d5Sandiclass Doku_Parser_Mode {
1370cecf9d5Sandi
1380cecf9d5Sandi    var $Lexer;
1390cecf9d5Sandi
1400cecf9d5Sandi    var $allowedModes = array();
1410cecf9d5Sandi
142107b01d6Sandi    // returns a number used to determine in which order modes are added
143107b01d6Sandi    function getSort() {
144107b01d6Sandi        trigger_error('getSort() not implemented in '.get_class($this), E_USER_WARNING);
145107b01d6Sandi    }
146107b01d6Sandi
1470cecf9d5Sandi    // Called before any calls to connectTo
1480cecf9d5Sandi    function preConnect() {}
1490cecf9d5Sandi
150107b01d6Sandi    // Connects the mode
1510cecf9d5Sandi    function connectTo($mode) {}
1520cecf9d5Sandi
1530cecf9d5Sandi    // Called after all calls to connectTo
1540cecf9d5Sandi    function postConnect() {}
1550cecf9d5Sandi
1560cecf9d5Sandi    function accepts($mode) {
1576f9bd982SAndreas Gohr        return in_array($mode, (array) $this->allowedModes );
1580cecf9d5Sandi    }
1590cecf9d5Sandi
1600cecf9d5Sandi}
1610cecf9d5Sandi
1620cecf9d5Sandi//-------------------------------------------------------------------
163107b01d6Sandiclass Doku_Parser_Mode_base extends Doku_Parser_Mode {
1640cecf9d5Sandi
165107b01d6Sandi    function Doku_Parser_Mode_base() {
166ee20e7d1Sandi        global $PARSER_MODES;
1670cecf9d5Sandi
1680cecf9d5Sandi        $this->allowedModes = array_merge (
169ee20e7d1Sandi                $PARSER_MODES['container'],
170ee20e7d1Sandi                $PARSER_MODES['baseonly'],
171ee20e7d1Sandi                $PARSER_MODES['paragraphs'],
172ee20e7d1Sandi                $PARSER_MODES['formatting'],
173ee20e7d1Sandi                $PARSER_MODES['substition'],
174ee20e7d1Sandi                $PARSER_MODES['protected'],
175ee20e7d1Sandi                $PARSER_MODES['disabled']
1760cecf9d5Sandi            );
1770cecf9d5Sandi    }
178107b01d6Sandi
179107b01d6Sandi    function getSort() {
180107b01d6Sandi        return 0;
181107b01d6Sandi    }
1820cecf9d5Sandi}
1830cecf9d5Sandi
1840cecf9d5Sandi//-------------------------------------------------------------------
185107b01d6Sandiclass Doku_Parser_Mode_footnote extends Doku_Parser_Mode {
1860cecf9d5Sandi
187107b01d6Sandi    function Doku_Parser_Mode_footnote() {
188ee20e7d1Sandi        global $PARSER_MODES;
1890cecf9d5Sandi
1900cecf9d5Sandi        $this->allowedModes = array_merge (
191ee20e7d1Sandi                $PARSER_MODES['container'],
192ee20e7d1Sandi                $PARSER_MODES['formatting'],
193ee20e7d1Sandi                $PARSER_MODES['substition'],
194ee20e7d1Sandi                $PARSER_MODES['protected'],
195ee20e7d1Sandi                $PARSER_MODES['disabled']
1960cecf9d5Sandi            );
1970cecf9d5Sandi
1982fe7363dSchris        unset($this->allowedModes[array_search('footnote', $this->allowedModes)]);
1990cecf9d5Sandi    }
2000cecf9d5Sandi
2010cecf9d5Sandi    function connectTo($mode) {
2020cecf9d5Sandi        $this->Lexer->addEntryPattern(
2030cecf9d5Sandi            '\x28\x28(?=.*\x29\x29)',$mode,'footnote'
2040cecf9d5Sandi            );
2050cecf9d5Sandi    }
2060cecf9d5Sandi
2070cecf9d5Sandi    function postConnect() {
2080cecf9d5Sandi        $this->Lexer->addExitPattern(
2090cecf9d5Sandi            '\x29\x29','footnote'
2100cecf9d5Sandi            );
2110cecf9d5Sandi    }
2120cecf9d5Sandi
213107b01d6Sandi    function getSort() {
214107b01d6Sandi        return 150;
215107b01d6Sandi    }
2160cecf9d5Sandi}
2170cecf9d5Sandi
2180cecf9d5Sandi//-------------------------------------------------------------------
219107b01d6Sandiclass Doku_Parser_Mode_header extends Doku_Parser_Mode {
2200cecf9d5Sandi
2210cecf9d5Sandi    function preConnect() {
222506ae684Sandi        //we're not picky about the closing ones, two are enough
2230cecf9d5Sandi        $this->Lexer->addSpecialPattern(
22430fe9cd6SAndreas Gohr                            '[ \t]*={2,}[^\n]+={2,}[ \t]*(?=\n)',
2250cecf9d5Sandi                            'base',
2260cecf9d5Sandi                            'header'
2270cecf9d5Sandi                        );
2280cecf9d5Sandi    }
2290cecf9d5Sandi
230107b01d6Sandi    function getSort() {
231107b01d6Sandi        return 50;
232107b01d6Sandi    }
2330cecf9d5Sandi}
2340cecf9d5Sandi
2350cecf9d5Sandi//-------------------------------------------------------------------
236107b01d6Sandiclass Doku_Parser_Mode_notoc extends Doku_Parser_Mode {
2370cecf9d5Sandi
2380cecf9d5Sandi    function connectTo($mode) {
2390cecf9d5Sandi        $this->Lexer->addSpecialPattern('~~NOTOC~~',$mode,'notoc');
2400cecf9d5Sandi    }
2410cecf9d5Sandi
242107b01d6Sandi    function getSort() {
243107b01d6Sandi        return 30;
244107b01d6Sandi    }
2450cecf9d5Sandi}
2460cecf9d5Sandi
2470cecf9d5Sandi//-------------------------------------------------------------------
248107b01d6Sandiclass Doku_Parser_Mode_nocache extends Doku_Parser_Mode {
2499dc2c2afSandi
2509dc2c2afSandi    function connectTo($mode) {
2519dc2c2afSandi        $this->Lexer->addSpecialPattern('~~NOCACHE~~',$mode,'nocache');
2529dc2c2afSandi    }
2539dc2c2afSandi
254107b01d6Sandi    function getSort() {
255107b01d6Sandi        return 40;
256107b01d6Sandi    }
2579dc2c2afSandi}
2589dc2c2afSandi
2599dc2c2afSandi//-------------------------------------------------------------------
260107b01d6Sandiclass Doku_Parser_Mode_linebreak extends Doku_Parser_Mode {
2610cecf9d5Sandi
2620cecf9d5Sandi    function connectTo($mode) {
263*30897fecSChris Smith        $this->Lexer->addSpecialPattern('\x5C{2}(?:[ \t]|(?=\n))',$mode,'linebreak');
2640cecf9d5Sandi    }
265107b01d6Sandi
266107b01d6Sandi    function getSort() {
267107b01d6Sandi        return 140;
268107b01d6Sandi    }
2690cecf9d5Sandi}
2700cecf9d5Sandi
2710cecf9d5Sandi//-------------------------------------------------------------------
272107b01d6Sandiclass Doku_Parser_Mode_eol extends Doku_Parser_Mode {
2730cecf9d5Sandi
2740cecf9d5Sandi    function connectTo($mode) {
2750cecf9d5Sandi        $badModes = array('listblock','table');
2760cecf9d5Sandi        if ( in_array($mode, $badModes) ) {
2770cecf9d5Sandi            return;
2780cecf9d5Sandi        }
2790cecf9d5Sandi        $this->Lexer->addSpecialPattern('\n',$mode,'eol');
2800cecf9d5Sandi    }
281107b01d6Sandi
282107b01d6Sandi    function getSort() {
283107b01d6Sandi        return 370;
284107b01d6Sandi    }
2850cecf9d5Sandi}
2860cecf9d5Sandi
2870cecf9d5Sandi//-------------------------------------------------------------------
288107b01d6Sandiclass Doku_Parser_Mode_hr extends Doku_Parser_Mode {
2890cecf9d5Sandi
2900cecf9d5Sandi    function connectTo($mode) {
2916f0c5dbfSandi        $this->Lexer->addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr');
2920cecf9d5Sandi    }
2930cecf9d5Sandi
294107b01d6Sandi    function getSort() {
295107b01d6Sandi        return 160;
296107b01d6Sandi    }
2970cecf9d5Sandi}
2980cecf9d5Sandi
2990cecf9d5Sandi//-------------------------------------------------------------------
300107b01d6Sandiclass Doku_Parser_Mode_formatting extends Doku_Parser_Mode {
3010cecf9d5Sandi    var $type;
3020cecf9d5Sandi
3030cecf9d5Sandi    var $formatting = array (
3040cecf9d5Sandi        'strong' => array (
3050cecf9d5Sandi            'entry'=>'\*\*(?=.*\*\*)',
3060cecf9d5Sandi            'exit'=>'\*\*',
307107b01d6Sandi            'sort'=>70
3080cecf9d5Sandi            ),
3090cecf9d5Sandi
3100cecf9d5Sandi        'emphasis'=> array (
31124b0ff2aSAndreas Gohr            'entry'=>'//(?=[^\x00]*[^:])', //hack for bugs #384 #763 #1468
3120cecf9d5Sandi            'exit'=>'//',
313107b01d6Sandi            'sort'=>80
3140cecf9d5Sandi            ),
3150cecf9d5Sandi
3160cecf9d5Sandi        'underline'=> array (
3170cecf9d5Sandi            'entry'=>'__(?=.*__)',
3180cecf9d5Sandi            'exit'=>'__',
319107b01d6Sandi            'sort'=>90
3200cecf9d5Sandi            ),
3210cecf9d5Sandi
3220cecf9d5Sandi        'monospace'=> array (
3230cecf9d5Sandi            'entry'=>'\x27\x27(?=.*\x27\x27)',
3240cecf9d5Sandi            'exit'=>'\x27\x27',
325107b01d6Sandi            'sort'=>100
3260cecf9d5Sandi            ),
3270cecf9d5Sandi
3280cecf9d5Sandi        'subscript'=> array (
32987858f84Schris            'entry'=>'<sub>(?=.*</sub>)',
3300cecf9d5Sandi            'exit'=>'</sub>',
331107b01d6Sandi            'sort'=>110
3320cecf9d5Sandi            ),
3330cecf9d5Sandi
3340cecf9d5Sandi        'superscript'=> array (
33587858f84Schris            'entry'=>'<sup>(?=.*</sup>)',
3360cecf9d5Sandi            'exit'=>'</sup>',
337107b01d6Sandi            'sort'=>120
3380cecf9d5Sandi            ),
3390cecf9d5Sandi
3400cecf9d5Sandi        'deleted'=> array (
34187858f84Schris            'entry'=>'<del>(?=.*</del>)',
3420cecf9d5Sandi            'exit'=>'</del>',
343107b01d6Sandi            'sort'=>130
3440cecf9d5Sandi            ),
3450cecf9d5Sandi        );
3460cecf9d5Sandi
347107b01d6Sandi    function Doku_Parser_Mode_formatting($type) {
348ee20e7d1Sandi        global $PARSER_MODES;
3490cecf9d5Sandi
3500cecf9d5Sandi        if ( !array_key_exists($type, $this->formatting) ) {
3510cecf9d5Sandi            trigger_error('Invalid formatting type '.$type, E_USER_WARNING);
3520cecf9d5Sandi        }
3530cecf9d5Sandi
3540cecf9d5Sandi        $this->type = $type;
3550cecf9d5Sandi
356ee20e7d1Sandi        // formatting may contain other formatting but not it self
357ee20e7d1Sandi        $modes = $PARSER_MODES['formatting'];
358ee20e7d1Sandi        $key = array_search($type, $modes);
359ee20e7d1Sandi        if ( is_int($key) ) {
360ee20e7d1Sandi            unset($modes[$key]);
361ee20e7d1Sandi        }
3620cecf9d5Sandi
363ee20e7d1Sandi        $this->allowedModes = array_merge (
364ee20e7d1Sandi                $modes,
365ee20e7d1Sandi                $PARSER_MODES['substition'],
366ee20e7d1Sandi                $PARSER_MODES['disabled']
367ee20e7d1Sandi            );
3680cecf9d5Sandi    }
3690cecf9d5Sandi
3700cecf9d5Sandi    function connectTo($mode) {
3710cecf9d5Sandi
3720cecf9d5Sandi        // Can't nest formatting in itself
3730cecf9d5Sandi        if ( $mode == $this->type ) {
3740cecf9d5Sandi            return;
3750cecf9d5Sandi        }
3760cecf9d5Sandi
3770cecf9d5Sandi        $this->Lexer->addEntryPattern(
3780cecf9d5Sandi                $this->formatting[$this->type]['entry'],
3790cecf9d5Sandi                $mode,
3800cecf9d5Sandi                $this->type
3810cecf9d5Sandi            );
3820cecf9d5Sandi    }
3830cecf9d5Sandi
3840cecf9d5Sandi    function postConnect() {
3850cecf9d5Sandi
3860cecf9d5Sandi        $this->Lexer->addExitPattern(
3870cecf9d5Sandi            $this->formatting[$this->type]['exit'],
3880cecf9d5Sandi            $this->type
3890cecf9d5Sandi            );
3900cecf9d5Sandi
3910cecf9d5Sandi    }
392107b01d6Sandi
393107b01d6Sandi    function getSort() {
394107b01d6Sandi        return $this->formatting[$this->type]['sort'];
395107b01d6Sandi    }
3960cecf9d5Sandi}
3970cecf9d5Sandi
3980cecf9d5Sandi//-------------------------------------------------------------------
399107b01d6Sandiclass Doku_Parser_Mode_listblock extends Doku_Parser_Mode {
4000cecf9d5Sandi
401107b01d6Sandi    function Doku_Parser_Mode_listblock() {
402ee20e7d1Sandi        global $PARSER_MODES;
4030cecf9d5Sandi
4040cecf9d5Sandi        $this->allowedModes = array_merge (
405ee20e7d1Sandi                $PARSER_MODES['formatting'],
406ee20e7d1Sandi                $PARSER_MODES['substition'],
407ee20e7d1Sandi                $PARSER_MODES['disabled'],
408ee20e7d1Sandi                $PARSER_MODES['protected'] #XXX new
4090cecf9d5Sandi            );
410702eb898Sandi
411ee20e7d1Sandi    //    $this->allowedModes[] = 'footnote';
4120cecf9d5Sandi    }
4130cecf9d5Sandi
4140cecf9d5Sandi    function connectTo($mode) {
4150cecf9d5Sandi        $this->Lexer->addEntryPattern('\n {2,}[\-\*]',$mode,'listblock');
4160cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\t{1,}[\-\*]',$mode,'listblock');
4170cecf9d5Sandi
4180cecf9d5Sandi        $this->Lexer->addPattern('\n {2,}[\-\*]','listblock');
4190cecf9d5Sandi        $this->Lexer->addPattern('\n\t{1,}[\-\*]','listblock');
4200cecf9d5Sandi
4210cecf9d5Sandi    }
4220cecf9d5Sandi
4230cecf9d5Sandi    function postConnect() {
4240cecf9d5Sandi        $this->Lexer->addExitPattern('\n','listblock');
4250cecf9d5Sandi    }
426107b01d6Sandi
427107b01d6Sandi    function getSort() {
428107b01d6Sandi        return 10;
429107b01d6Sandi    }
4300cecf9d5Sandi}
4310cecf9d5Sandi
4320cecf9d5Sandi//-------------------------------------------------------------------
433107b01d6Sandiclass Doku_Parser_Mode_table extends Doku_Parser_Mode {
4340cecf9d5Sandi
435107b01d6Sandi    function Doku_Parser_Mode_table() {
436ee20e7d1Sandi        global $PARSER_MODES;
4370cecf9d5Sandi
4380cecf9d5Sandi        $this->allowedModes = array_merge (
439ee20e7d1Sandi                $PARSER_MODES['formatting'],
440ee20e7d1Sandi                $PARSER_MODES['substition'],
441ee20e7d1Sandi                $PARSER_MODES['disabled'],
442107b01d6Sandi                $PARSER_MODES['protected']
4430cecf9d5Sandi            );
4440cecf9d5Sandi    }
4450cecf9d5Sandi
4460cecf9d5Sandi    function connectTo($mode) {
4470cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\^',$mode,'table');
4480cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\|',$mode,'table');
4490cecf9d5Sandi    }
4500cecf9d5Sandi
4510cecf9d5Sandi    function postConnect() {
4520cecf9d5Sandi        $this->Lexer->addPattern('\n\^','table');
4530cecf9d5Sandi        $this->Lexer->addPattern('\n\|','table');
4549ab75d9eSAndreas Gohr        #$this->Lexer->addPattern(' {2,}','table');
4559ab75d9eSAndreas Gohr        $this->Lexer->addPattern('[\t ]+','table');
4560cecf9d5Sandi        $this->Lexer->addPattern('\^','table');
4570cecf9d5Sandi        $this->Lexer->addPattern('\|','table');
4580cecf9d5Sandi        $this->Lexer->addExitPattern('\n','table');
4590cecf9d5Sandi    }
460107b01d6Sandi
461107b01d6Sandi    function getSort() {
462107b01d6Sandi        return 60;
463107b01d6Sandi    }
4640cecf9d5Sandi}
4650cecf9d5Sandi
4660cecf9d5Sandi//-------------------------------------------------------------------
467107b01d6Sandiclass Doku_Parser_Mode_unformatted extends Doku_Parser_Mode {
4680cecf9d5Sandi
4690cecf9d5Sandi    function connectTo($mode) {
47087858f84Schris        $this->Lexer->addEntryPattern('<nowiki>(?=.*</nowiki>)',$mode,'unformatted');
4710cecf9d5Sandi        $this->Lexer->addEntryPattern('%%(?=.*%%)',$mode,'unformattedalt');
4720cecf9d5Sandi    }
4730cecf9d5Sandi
4740cecf9d5Sandi    function postConnect() {
4750cecf9d5Sandi        $this->Lexer->addExitPattern('</nowiki>','unformatted');
4760cecf9d5Sandi        $this->Lexer->addExitPattern('%%','unformattedalt');
4770cecf9d5Sandi        $this->Lexer->mapHandler('unformattedalt','unformatted');
4780cecf9d5Sandi    }
4790cecf9d5Sandi
480107b01d6Sandi    function getSort() {
481107b01d6Sandi        return 170;
482107b01d6Sandi    }
4830cecf9d5Sandi}
4840cecf9d5Sandi
4850cecf9d5Sandi//-------------------------------------------------------------------
486107b01d6Sandiclass Doku_Parser_Mode_php extends Doku_Parser_Mode {
4870cecf9d5Sandi
4880cecf9d5Sandi    function connectTo($mode) {
48987858f84Schris        $this->Lexer->addEntryPattern('<php>(?=.*</php>)',$mode,'php');
49007f89c3cSAnika Henke        $this->Lexer->addEntryPattern('<PHP>(?=.*</PHP>)',$mode,'phpblock');
4910cecf9d5Sandi    }
4920cecf9d5Sandi
4930cecf9d5Sandi    function postConnect() {
4940cecf9d5Sandi        $this->Lexer->addExitPattern('</php>','php');
49507f89c3cSAnika Henke        $this->Lexer->addExitPattern('</PHP>','phpblock');
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');
50807f89c3cSAnika Henke        $this->Lexer->addEntryPattern('<HTML>(?=.*</HTML>)',$mode,'htmlblock');
5090cecf9d5Sandi    }
5100cecf9d5Sandi
5110cecf9d5Sandi    function postConnect() {
5120cecf9d5Sandi        $this->Lexer->addExitPattern('</html>','html');
51307f89c3cSAnika Henke        $this->Lexer->addExitPattern('</HTML>','htmlblock');
5140cecf9d5Sandi    }
5150cecf9d5Sandi
516107b01d6Sandi    function getSort() {
517107b01d6Sandi        return 190;
518107b01d6Sandi    }
5190cecf9d5Sandi}
5200cecf9d5Sandi
5210cecf9d5Sandi//-------------------------------------------------------------------
522107b01d6Sandiclass Doku_Parser_Mode_preformatted extends Doku_Parser_Mode {
5230cecf9d5Sandi
5240cecf9d5Sandi    function connectTo($mode) {
5250cecf9d5Sandi        // Has hard coded awareness of lists...
5260cecf9d5Sandi        $this->Lexer->addEntryPattern('\n  (?![\*\-])',$mode,'preformatted');
5270cecf9d5Sandi        $this->Lexer->addEntryPattern('\n\t(?![\*\-])',$mode,'preformatted');
5280cecf9d5Sandi
5290cecf9d5Sandi        // How to effect a sub pattern with the Lexer!
5300cecf9d5Sandi        $this->Lexer->addPattern('\n  ','preformatted');
5310cecf9d5Sandi        $this->Lexer->addPattern('\n\t','preformatted');
5320cecf9d5Sandi
5330cecf9d5Sandi    }
5340cecf9d5Sandi
5350cecf9d5Sandi    function postConnect() {
5360cecf9d5Sandi        $this->Lexer->addExitPattern('\n','preformatted');
5370cecf9d5Sandi    }
5380cecf9d5Sandi
539107b01d6Sandi    function getSort() {
540107b01d6Sandi        return 20;
541107b01d6Sandi    }
5420cecf9d5Sandi}
5430cecf9d5Sandi
5440cecf9d5Sandi//-------------------------------------------------------------------
545107b01d6Sandiclass Doku_Parser_Mode_code extends Doku_Parser_Mode {
5460cecf9d5Sandi
5470cecf9d5Sandi    function connectTo($mode) {
54887858f84Schris        $this->Lexer->addEntryPattern('<code(?=.*</code>)',$mode,'code');
5490cecf9d5Sandi    }
5500cecf9d5Sandi
5510cecf9d5Sandi    function postConnect() {
5520cecf9d5Sandi        $this->Lexer->addExitPattern('</code>','code');
5530cecf9d5Sandi    }
5540cecf9d5Sandi
555107b01d6Sandi    function getSort() {
556107b01d6Sandi        return 200;
557107b01d6Sandi    }
5580cecf9d5Sandi}
5590cecf9d5Sandi
5600cecf9d5Sandi//-------------------------------------------------------------------
561107b01d6Sandiclass Doku_Parser_Mode_file extends Doku_Parser_Mode {
5620cecf9d5Sandi
5630cecf9d5Sandi    function connectTo($mode) {
5643d491f75SAndreas Gohr        $this->Lexer->addEntryPattern('<file(?=.*</file>)',$mode,'file');
5650cecf9d5Sandi    }
5660cecf9d5Sandi
5670cecf9d5Sandi    function postConnect() {
5680cecf9d5Sandi        $this->Lexer->addExitPattern('</file>','file');
5690cecf9d5Sandi    }
5700cecf9d5Sandi
571107b01d6Sandi    function getSort() {
572107b01d6Sandi        return 210;
573107b01d6Sandi    }
5740cecf9d5Sandi}
5750cecf9d5Sandi
5760cecf9d5Sandi//-------------------------------------------------------------------
577107b01d6Sandiclass Doku_Parser_Mode_quote extends Doku_Parser_Mode {
5780cecf9d5Sandi
579107b01d6Sandi    function Doku_Parser_Mode_quote() {
580ee20e7d1Sandi        global $PARSER_MODES;
5810cecf9d5Sandi
5820cecf9d5Sandi        $this->allowedModes = array_merge (
583ee20e7d1Sandi                $PARSER_MODES['formatting'],
584ee20e7d1Sandi                $PARSER_MODES['substition'],
585ee20e7d1Sandi                $PARSER_MODES['disabled'],
586ee20e7d1Sandi                $PARSER_MODES['protected'] #XXX new
5870cecf9d5Sandi            );
588ee20e7d1Sandi            #$this->allowedModes[] = 'footnote';
589ee20e7d1Sandi            #$this->allowedModes[] = 'preformatted';
590ee20e7d1Sandi            #$this->allowedModes[] = 'unformatted';
5910cecf9d5Sandi    }
5920cecf9d5Sandi
5930cecf9d5Sandi    function connectTo($mode) {
5940cecf9d5Sandi        $this->Lexer->addEntryPattern('\n>{1,}',$mode,'quote');
5950cecf9d5Sandi    }
5960cecf9d5Sandi
5970cecf9d5Sandi    function postConnect() {
5980cecf9d5Sandi        $this->Lexer->addPattern('\n>{1,}','quote');
5990cecf9d5Sandi        $this->Lexer->addExitPattern('\n','quote');
6000cecf9d5Sandi    }
6010cecf9d5Sandi
602107b01d6Sandi    function getSort() {
603107b01d6Sandi        return 220;
604107b01d6Sandi    }
6050cecf9d5Sandi}
6060cecf9d5Sandi
6070cecf9d5Sandi//-------------------------------------------------------------------
608107b01d6Sandiclass Doku_Parser_Mode_acronym extends Doku_Parser_Mode {
6090cecf9d5Sandi    // A list
6100cecf9d5Sandi    var $acronyms = array();
6110cecf9d5Sandi    var $pattern = '';
6120cecf9d5Sandi
613107b01d6Sandi    function Doku_Parser_Mode_acronym($acronyms) {
6147cc4b757SChris Smith    	usort($acronyms,array($this,'_compare'));
6150cecf9d5Sandi        $this->acronyms = $acronyms;
6160cecf9d5Sandi    }
6170cecf9d5Sandi
6180cecf9d5Sandi    function preConnect() {
619901c1c87SAndreas Gohr        if(!count($this->acronyms)) return;
620901c1c87SAndreas Gohr
6218e266198SAndreas Gohr        $bound = '[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]';
622e6258e07SAndreas Gohr        $acronyms = array_map('Doku_Lexer_Escape',$this->acronyms);
6238e266198SAndreas Gohr        $this->pattern = '(?<=^|'.$bound.')(?:'.join('|',$acronyms).')(?='.$bound.')';
6240cecf9d5Sandi    }
6250cecf9d5Sandi
6260cecf9d5Sandi    function connectTo($mode) {
627901c1c87SAndreas Gohr        if(!count($this->acronyms)) return;
628901c1c87SAndreas Gohr
6290cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
6300cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'acronym');
6310cecf9d5Sandi        }
6320cecf9d5Sandi    }
6330cecf9d5Sandi
634107b01d6Sandi    function getSort() {
635107b01d6Sandi        return 240;
636107b01d6Sandi    }
6377cc4b757SChris Smith
6387cc4b757SChris Smith    /**
6397cc4b757SChris Smith     * sort callback to order by string length descending
6407cc4b757SChris Smith     */
6417cc4b757SChris Smith    function _compare($a,$b) {
6427cc4b757SChris Smith        $a_len = strlen($a);
6437cc4b757SChris Smith        $b_len = strlen($b);
6447cc4b757SChris Smith        if ($a_len > $b_len) {
6457cc4b757SChris Smith          return -1;
6467cc4b757SChris Smith        } else if ($a_len < $b_len) {
6477cc4b757SChris Smith          return 1;
6487cc4b757SChris Smith        }
6497cc4b757SChris Smith
6507cc4b757SChris Smith    	return 0;
6517cc4b757SChris Smith    }
6520cecf9d5Sandi}
6530cecf9d5Sandi
6540cecf9d5Sandi//-------------------------------------------------------------------
655107b01d6Sandiclass Doku_Parser_Mode_smiley extends Doku_Parser_Mode {
6560cecf9d5Sandi    // A list
6570cecf9d5Sandi    var $smileys = array();
6580cecf9d5Sandi    var $pattern = '';
6590cecf9d5Sandi
660107b01d6Sandi    function Doku_Parser_Mode_smiley($smileys) {
6610cecf9d5Sandi        $this->smileys = $smileys;
6620cecf9d5Sandi    }
6630cecf9d5Sandi
6640cecf9d5Sandi    function preConnect() {
665d4834a19SStephane Chazelas        if(!count($this->smileys) || $this->pattern != '') return;
666901c1c87SAndreas Gohr
6670cecf9d5Sandi        $sep = '';
6680cecf9d5Sandi        foreach ( $this->smileys as $smiley ) {
6691b26635bSAndreas Gohr            $this->pattern .= $sep.'(?<=\W|^)'.Doku_Lexer_Escape($smiley).'(?=\W|$)';
6700cecf9d5Sandi            $sep = '|';
6710cecf9d5Sandi        }
6720cecf9d5Sandi    }
6730cecf9d5Sandi
6740cecf9d5Sandi    function connectTo($mode) {
675901c1c87SAndreas Gohr        if(!count($this->smileys)) return;
676901c1c87SAndreas Gohr
6770cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
6780cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'smiley');
6790cecf9d5Sandi        }
6800cecf9d5Sandi    }
6810cecf9d5Sandi
682107b01d6Sandi    function getSort() {
683107b01d6Sandi        return 230;
684107b01d6Sandi    }
6850cecf9d5Sandi}
6860cecf9d5Sandi
6870cecf9d5Sandi//-------------------------------------------------------------------
688107b01d6Sandiclass Doku_Parser_Mode_wordblock extends Doku_Parser_Mode {
6890cecf9d5Sandi    // A list
6900cecf9d5Sandi    var $badwords = array();
6910cecf9d5Sandi    var $pattern = '';
6920cecf9d5Sandi
693107b01d6Sandi    function Doku_Parser_Mode_wordblock($badwords) {
6940cecf9d5Sandi        $this->badwords = $badwords;
6950cecf9d5Sandi    }
6960cecf9d5Sandi
6970cecf9d5Sandi    function preConnect() {
6980cecf9d5Sandi
699d4834a19SStephane Chazelas        if ( count($this->badwords) == 0 || $this->pattern != '') {
7000cecf9d5Sandi            return;
7010cecf9d5Sandi        }
7020cecf9d5Sandi
7030cecf9d5Sandi        $sep = '';
7040cecf9d5Sandi        foreach ( $this->badwords as $badword ) {
7050cecf9d5Sandi            $this->pattern .= $sep.'(?<=\b)(?i)'.Doku_Lexer_Escape($badword).'(?-i)(?=\b)';
7060cecf9d5Sandi            $sep = '|';
7070cecf9d5Sandi        }
7080cecf9d5Sandi
7090cecf9d5Sandi    }
7100cecf9d5Sandi
7110cecf9d5Sandi    function connectTo($mode) {
7120cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
7130cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'wordblock');
7140cecf9d5Sandi        }
7150cecf9d5Sandi    }
7160cecf9d5Sandi
717107b01d6Sandi    function getSort() {
718107b01d6Sandi        return 250;
719107b01d6Sandi    }
7200cecf9d5Sandi}
7210cecf9d5Sandi
7220cecf9d5Sandi//-------------------------------------------------------------------
723107b01d6Sandiclass Doku_Parser_Mode_entity extends Doku_Parser_Mode {
7240cecf9d5Sandi    // A list
7250cecf9d5Sandi    var $entities = array();
7260cecf9d5Sandi    var $pattern = '';
7270cecf9d5Sandi
728107b01d6Sandi    function Doku_Parser_Mode_entity($entities) {
7290cecf9d5Sandi        $this->entities = $entities;
7300cecf9d5Sandi    }
7310cecf9d5Sandi
7320cecf9d5Sandi    function preConnect() {
733d4834a19SStephane Chazelas        if(!count($this->entities) || $this->pattern != '') return;
734901c1c87SAndreas Gohr
7350cecf9d5Sandi        $sep = '';
7360cecf9d5Sandi        foreach ( $this->entities as $entity ) {
7370cecf9d5Sandi            $this->pattern .= $sep.Doku_Lexer_Escape($entity);
7380cecf9d5Sandi            $sep = '|';
7390cecf9d5Sandi        }
7400cecf9d5Sandi    }
7410cecf9d5Sandi
7420cecf9d5Sandi    function connectTo($mode) {
743901c1c87SAndreas Gohr        if(!count($this->entities)) return;
744901c1c87SAndreas Gohr
7450cecf9d5Sandi        if ( strlen($this->pattern) > 0 ) {
7460cecf9d5Sandi            $this->Lexer->addSpecialPattern($this->pattern,$mode,'entity');
7470cecf9d5Sandi        }
7480cecf9d5Sandi    }
7490cecf9d5Sandi
750107b01d6Sandi    function getSort() {
751107b01d6Sandi        return 260;
752107b01d6Sandi    }
7530cecf9d5Sandi}
7540cecf9d5Sandi
7550cecf9d5Sandi//-------------------------------------------------------------------
7560cecf9d5Sandi// Implements the 640x480 replacement
757107b01d6Sandiclass Doku_Parser_Mode_multiplyentity extends Doku_Parser_Mode {
7580cecf9d5Sandi
7590cecf9d5Sandi    function connectTo($mode) {
7600cecf9d5Sandi
7610cecf9d5Sandi        $this->Lexer->addSpecialPattern(
76268df1afcSChris Smith                    '(?<=\b)(?:[1-9]|\d{2,})[xX]\d+(?=\b)',$mode,'multiplyentity'
7630cecf9d5Sandi                );
7640cecf9d5Sandi
7650cecf9d5Sandi    }
7660cecf9d5Sandi
767107b01d6Sandi    function getSort() {
768107b01d6Sandi        return 270;
769107b01d6Sandi    }
7700cecf9d5Sandi}
7710cecf9d5Sandi
7720cecf9d5Sandi//-------------------------------------------------------------------
773107b01d6Sandiclass Doku_Parser_Mode_quotes extends Doku_Parser_Mode {
7740cecf9d5Sandi
7750cecf9d5Sandi    function connectTo($mode) {
7769426a41aSAndreas Gohr        global $conf;
7779426a41aSAndreas Gohr
7785fc8a925SAndreas Gohr        $ws   =  '\s/\#~:+=&%@\-\x28\x29\]\[{}><"\'';   // whitespace
7795fc8a925SAndreas Gohr        $punc =  ';,\.?!';
7800cecf9d5Sandi
7819426a41aSAndreas Gohr        if($conf['typography'] == 2){
7820cecf9d5Sandi            $this->Lexer->addSpecialPattern(
7835fc8a925SAndreas Gohr                        "(?<=^|[$ws])'(?=[^$ws$punc])",$mode,'singlequoteopening'
7840cecf9d5Sandi                    );
7850cecf9d5Sandi            $this->Lexer->addSpecialPattern(
7865fc8a925SAndreas Gohr                        "(?<=^|[^$ws]|[$punc])'(?=$|[$ws$punc])",$mode,'singlequoteclosing'
7870cecf9d5Sandi                    );
7880cecf9d5Sandi            $this->Lexer->addSpecialPattern(
7895fc8a925SAndreas Gohr                        "(?<=^|[^$ws$punc])'(?=$|[^$ws$punc])",$mode,'apostrophe'
7900cecf9d5Sandi                    );
7919426a41aSAndreas Gohr        }
7929426a41aSAndreas Gohr
7930cecf9d5Sandi        $this->Lexer->addSpecialPattern(
7945fc8a925SAndreas Gohr                    "(?<=^|[$ws])\"(?=[^$ws$punc])",$mode,'doublequoteopening'
7950cecf9d5Sandi                );
79657d757d1SAndreas Gohr        $this->Lexer->addSpecialPattern(
7975fc8a925SAndreas Gohr                    "\"",$mode,'doublequoteclosing'
79857d757d1SAndreas Gohr                );
79957d757d1SAndreas Gohr
8000cecf9d5Sandi
8010cecf9d5Sandi    }
8020cecf9d5Sandi
803107b01d6Sandi    function getSort() {
804107b01d6Sandi        return 280;
805107b01d6Sandi    }
8060cecf9d5Sandi}
8070cecf9d5Sandi
8080cecf9d5Sandi//-------------------------------------------------------------------
809107b01d6Sandiclass Doku_Parser_Mode_camelcaselink extends Doku_Parser_Mode {
8100cecf9d5Sandi
8110cecf9d5Sandi    function connectTo($mode) {
8120cecf9d5Sandi        $this->Lexer->addSpecialPattern(
8130cecf9d5Sandi                '\b[A-Z]+[a-z]+[A-Z][A-Za-z]*\b',$mode,'camelcaselink'
8140cecf9d5Sandi            );
8150cecf9d5Sandi    }
8160cecf9d5Sandi
817107b01d6Sandi    function getSort() {
818107b01d6Sandi        return 290;
819107b01d6Sandi    }
8200cecf9d5Sandi}
8210cecf9d5Sandi
8220cecf9d5Sandi//-------------------------------------------------------------------
823107b01d6Sandiclass Doku_Parser_Mode_internallink extends Doku_Parser_Mode {
8240cecf9d5Sandi
8250cecf9d5Sandi    function connectTo($mode) {
8260cecf9d5Sandi        // Word boundaries?
827a6755281Sandi        $this->Lexer->addSpecialPattern("\[\[.+?\]\]",$mode,'internallink');
8280cecf9d5Sandi    }
8290cecf9d5Sandi
830107b01d6Sandi    function getSort() {
831107b01d6Sandi        return 300;
832107b01d6Sandi    }
8330cecf9d5Sandi}
8340cecf9d5Sandi
8350cecf9d5Sandi//-------------------------------------------------------------------
836107b01d6Sandiclass Doku_Parser_Mode_media extends Doku_Parser_Mode {
8370cecf9d5Sandi
8380cecf9d5Sandi    function connectTo($mode) {
8390cecf9d5Sandi        // Word boundaries?
8400cecf9d5Sandi        $this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'media');
8410cecf9d5Sandi    }
8420cecf9d5Sandi
843107b01d6Sandi    function getSort() {
844107b01d6Sandi        return 320;
845107b01d6Sandi    }
8460cecf9d5Sandi}
8470cecf9d5Sandi
8480cecf9d5Sandi//-------------------------------------------------------------------
849107b01d6Sandiclass Doku_Parser_Mode_rss extends Doku_Parser_Mode {
850b625487dSandi
851b625487dSandi    function connectTo($mode) {
852b625487dSandi        $this->Lexer->addSpecialPattern("\{\{rss>[^\}]+\}\}",$mode,'rss');
853b625487dSandi    }
854b625487dSandi
855107b01d6Sandi    function getSort() {
856107b01d6Sandi        return 310;
857107b01d6Sandi    }
858b625487dSandi}
859b625487dSandi
860b625487dSandi//-------------------------------------------------------------------
861107b01d6Sandiclass Doku_Parser_Mode_externallink extends Doku_Parser_Mode {
86236f2d7c1SGina Haeussge    var $schemes = array();
8630cecf9d5Sandi    var $patterns = array();
8640cecf9d5Sandi
8650cecf9d5Sandi    function preConnect() {
866d4834a19SStephane Chazelas        if(count($this->patterns)) return;
8670cecf9d5Sandi
8680cecf9d5Sandi        $ltrs = '\w';
8690cecf9d5Sandi        $gunk = '/\#~:.?+=&%@!\-';
8700cecf9d5Sandi        $punc = '.:?\-;,';
8710cecf9d5Sandi        $host = $ltrs.$punc;
8720cecf9d5Sandi        $any  = $ltrs.$gunk.$punc;
8730cecf9d5Sandi
87436f2d7c1SGina Haeussge        $this->schemes = getSchemes();
8750cecf9d5Sandi        foreach ( $this->schemes as $scheme ) {
8766f0c5dbfSandi            $this->patterns[] = '\b(?i)'.$scheme.'(?-i)://['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
8770cecf9d5Sandi        }
8780cecf9d5Sandi
8796f0c5dbfSandi        $this->patterns[] = '\b(?i)www?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
8806f0c5dbfSandi        $this->patterns[] = '\b(?i)ftp?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
8810cecf9d5Sandi    }
8820cecf9d5Sandi
8830cecf9d5Sandi    function connectTo($mode) {
884d4834a19SStephane Chazelas
8850cecf9d5Sandi        foreach ( $this->patterns as $pattern ) {
8860cecf9d5Sandi            $this->Lexer->addSpecialPattern($pattern,$mode,'externallink');
8870cecf9d5Sandi        }
8880cecf9d5Sandi    }
8890cecf9d5Sandi
890107b01d6Sandi    function getSort() {
891107b01d6Sandi        return 330;
892107b01d6Sandi    }
8930cecf9d5Sandi}
8940cecf9d5Sandi
8950cecf9d5Sandi//-------------------------------------------------------------------
896107b01d6Sandiclass Doku_Parser_Mode_filelink extends Doku_Parser_Mode {
8970cecf9d5Sandi
8980cecf9d5Sandi    var $pattern;
8990cecf9d5Sandi
9000cecf9d5Sandi    function preConnect() {
9010cecf9d5Sandi
9020cecf9d5Sandi        $ltrs = '\w';
9030cecf9d5Sandi        $gunk = '/\#~:.?+=&%@!\-';
9040cecf9d5Sandi        $punc = '.:?\-;,';
9050cecf9d5Sandi        $host = $ltrs.$punc;
9060cecf9d5Sandi        $any  = $ltrs.$gunk.$punc;
9070cecf9d5Sandi
9080cecf9d5Sandi        $this->pattern = '\b(?i)file(?-i)://['.$any.']+?['.
9090cecf9d5Sandi            $punc.']*[^'.$any.']';
9100cecf9d5Sandi    }
9110cecf9d5Sandi
9120cecf9d5Sandi    function connectTo($mode) {
9130cecf9d5Sandi        $this->Lexer->addSpecialPattern(
9140cecf9d5Sandi            $this->pattern,$mode,'filelink');
9150cecf9d5Sandi    }
9160cecf9d5Sandi
917107b01d6Sandi    function getSort() {
918107b01d6Sandi        return 360;
919107b01d6Sandi    }
9200cecf9d5Sandi}
9210cecf9d5Sandi
9220cecf9d5Sandi//-------------------------------------------------------------------
923107b01d6Sandiclass Doku_Parser_Mode_windowssharelink extends Doku_Parser_Mode {
9240cecf9d5Sandi
9250cecf9d5Sandi    var $pattern;
9260cecf9d5Sandi
9270cecf9d5Sandi    function preConnect() {
9286d447503Sandi        $this->pattern = "\\\\\\\\\w+?(?:\\\\[\w$]+)+";
9290cecf9d5Sandi    }
9300cecf9d5Sandi
9310cecf9d5Sandi    function connectTo($mode) {
9320cecf9d5Sandi        $this->Lexer->addSpecialPattern(
9330cecf9d5Sandi            $this->pattern,$mode,'windowssharelink');
9340cecf9d5Sandi    }
9350cecf9d5Sandi
936107b01d6Sandi    function getSort() {
937107b01d6Sandi        return 350;
938107b01d6Sandi    }
9390cecf9d5Sandi}
9400cecf9d5Sandi
9410cecf9d5Sandi//-------------------------------------------------------------------
942107b01d6Sandiclass Doku_Parser_Mode_emaillink extends Doku_Parser_Mode {
9430cecf9d5Sandi
9440cecf9d5Sandi    function connectTo($mode) {
9450a1d30bfSchris        // pattern below is defined in inc/mail.php
9460a1d30bfSchris        $this->Lexer->addSpecialPattern('<'.PREG_PATTERN_VALID_EMAIL.'>',$mode,'emaillink');
9470cecf9d5Sandi    }
9480cecf9d5Sandi
949107b01d6Sandi    function getSort() {
950107b01d6Sandi        return 340;
951107b01d6Sandi    }
9520cecf9d5Sandi}
9530cecf9d5Sandi
954340756e4Sandi
955b625487dSandi//Setup VIM: ex: et ts=4 enc=utf-8 :
956