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*57d757d1SAndreas Gohr $ws = '[\s/\#~:\.?+=&%@!\-;,\x28\x29\]\[{}><"\']'; // whitespace 762*57d757d1SAndreas Gohr $nws = '[^\s/\#~:\.?+=&%@!\-;,\x28\x29\]\[{}><"\']'; // non whitespace 7630cecf9d5Sandi 7640cecf9d5Sandi $this->Lexer->addSpecialPattern( 765*57d757d1SAndreas Gohr "(?<=^|$ws)'(?=$nws)",$mode,'singlequoteopening' 7660cecf9d5Sandi ); 7670cecf9d5Sandi $this->Lexer->addSpecialPattern( 768*57d757d1SAndreas Gohr "(?<=^|$nws)'(?=$|$ws)",$mode,'singlequoteclosing' 7690cecf9d5Sandi ); 7700cecf9d5Sandi $this->Lexer->addSpecialPattern( 771*57d757d1SAndreas Gohr "(?<=^|$nws)'(?=$|$nws)",$mode,'apostrophe' 7720cecf9d5Sandi ); 7730cecf9d5Sandi $this->Lexer->addSpecialPattern( 774*57d757d1SAndreas Gohr "(?<=^|$ws)\"(?=$nws)",$mode,'doublequoteopening' 7750cecf9d5Sandi ); 776*57d757d1SAndreas Gohr $this->Lexer->addSpecialPattern( 777*57d757d1SAndreas Gohr "(?<=^|$nws)\"",$mode,'doublequoteclosing' 778*57d757d1SAndreas Gohr ); 779*57d757d1SAndreas 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