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 55e3ab6fc5SMichael Hamann /** 56e3ab6fc5SMichael Hamann * @var Doku_Lexer $Lexer 57e3ab6fc5SMichael Hamann */ 580cecf9d5Sandi var $Lexer; 590cecf9d5Sandi 600cecf9d5Sandi var $modes = array(); 610cecf9d5Sandi 6244881bd0Shenning.noren var $connected = false; 630cecf9d5Sandi 64276820f7SScrutinizer Auto-Fixer /** 65276820f7SScrutinizer Auto-Fixer * @param Doku_Parser_Mode_base $BaseMode 66276820f7SScrutinizer Auto-Fixer */ 6745e8987eSChristopher Smith function addBaseMode($BaseMode) { 6845e8987eSChristopher Smith $this->modes['base'] = $BaseMode; 690cecf9d5Sandi if ( !$this->Lexer ) { 7067f9913dSAndreas Gohr $this->Lexer = new Doku_Lexer($this->Handler,'base', true); 710cecf9d5Sandi } 7245e8987eSChristopher Smith $this->modes['base']->Lexer = $this->Lexer; 730cecf9d5Sandi } 740cecf9d5Sandi 750cecf9d5Sandi /** 760cecf9d5Sandi * PHP preserves order of associative elements 770cecf9d5Sandi * Mode sequence is important 78*f50a239bSTakamura * 79*f50a239bSTakamura * @param string $name 80*f50a239bSTakamura * @param Doku_Parser_Mode_Interface $Mode 810cecf9d5Sandi */ 8245e8987eSChristopher Smith function addMode($name, Doku_Parser_Mode_Interface $Mode) { 830cecf9d5Sandi if ( !isset($this->modes['base']) ) { 84107b01d6Sandi $this->addBaseMode(new Doku_Parser_Mode_base()); 850cecf9d5Sandi } 8645e8987eSChristopher Smith $Mode->Lexer = $this->Lexer; 8745e8987eSChristopher Smith $this->modes[$name] = $Mode; 880cecf9d5Sandi } 890cecf9d5Sandi 900cecf9d5Sandi function connectModes() { 910cecf9d5Sandi 920cecf9d5Sandi if ( $this->connected ) { 930cecf9d5Sandi return; 940cecf9d5Sandi } 950cecf9d5Sandi 960cecf9d5Sandi foreach ( array_keys($this->modes) as $mode ) { 970cecf9d5Sandi 980cecf9d5Sandi // Base isn't connected to anything 990cecf9d5Sandi if ( $mode == 'base' ) { 1000cecf9d5Sandi continue; 1010cecf9d5Sandi } 1020cecf9d5Sandi $this->modes[$mode]->preConnect(); 1030cecf9d5Sandi 1040cecf9d5Sandi foreach ( array_keys($this->modes) as $cm ) { 1050cecf9d5Sandi 1060cecf9d5Sandi if ( $this->modes[$cm]->accepts($mode) ) { 1070cecf9d5Sandi $this->modes[$mode]->connectTo($cm); 1080cecf9d5Sandi } 1090cecf9d5Sandi 1100cecf9d5Sandi } 1110cecf9d5Sandi 1120cecf9d5Sandi $this->modes[$mode]->postConnect(); 1130cecf9d5Sandi } 1140cecf9d5Sandi 11544881bd0Shenning.noren $this->connected = true; 1160cecf9d5Sandi } 1170cecf9d5Sandi 1180cecf9d5Sandi function parse($doc) { 1190cecf9d5Sandi if ( $this->Lexer ) { 1200cecf9d5Sandi $this->connectModes(); 1210cecf9d5Sandi // Normalize CRs and pad doc 1220cecf9d5Sandi $doc = "\n".str_replace("\r\n","\n",$doc)."\n"; 1230cecf9d5Sandi $this->Lexer->parse($doc); 124433bef32Sandi $this->Handler->_finalize(); 1250cecf9d5Sandi return $this->Handler->calls; 1260cecf9d5Sandi } else { 12744881bd0Shenning.noren return false; 1280cecf9d5Sandi } 1290cecf9d5Sandi } 1300cecf9d5Sandi 1310cecf9d5Sandi} 1320cecf9d5Sandi 1330cecf9d5Sandi//------------------------------------------------------------------- 1345a3e1f53SAndreas Gohr 1355a3e1f53SAndreas Gohr/** 1365a3e1f53SAndreas Gohr * Class Doku_Parser_Mode_Interface 1375a3e1f53SAndreas Gohr * 1385a3e1f53SAndreas Gohr * Defines a mode (syntax component) in the Parser 1395a3e1f53SAndreas Gohr */ 1405a3e1f53SAndreas Gohrinterface Doku_Parser_Mode_Interface { 1415a3e1f53SAndreas Gohr /** 1425a3e1f53SAndreas Gohr * returns a number used to determine in which order modes are added 1435a3e1f53SAndreas Gohr */ 1445a3e1f53SAndreas Gohr public function getSort(); 1455a3e1f53SAndreas Gohr 1465a3e1f53SAndreas Gohr /** 1475a3e1f53SAndreas Gohr * Called before any calls to connectTo 148276820f7SScrutinizer Auto-Fixer * @return void 1495a3e1f53SAndreas Gohr */ 1505a3e1f53SAndreas Gohr function preConnect(); 1515a3e1f53SAndreas Gohr 1525a3e1f53SAndreas Gohr /** 1535a3e1f53SAndreas Gohr * Connects the mode 1545a3e1f53SAndreas Gohr * 1555a3e1f53SAndreas Gohr * @param string $mode 156276820f7SScrutinizer Auto-Fixer * @return void 1575a3e1f53SAndreas Gohr */ 1585a3e1f53SAndreas Gohr function connectTo($mode); 1595a3e1f53SAndreas Gohr 1605a3e1f53SAndreas Gohr /** 1615a3e1f53SAndreas Gohr * Called after all calls to connectTo 162276820f7SScrutinizer Auto-Fixer * @return void 1635a3e1f53SAndreas Gohr */ 1645a3e1f53SAndreas Gohr function postConnect(); 1655a3e1f53SAndreas Gohr 1665a3e1f53SAndreas Gohr /** 1675a3e1f53SAndreas Gohr * Check if given mode is accepted inside this mode 1685a3e1f53SAndreas Gohr * 1695a3e1f53SAndreas Gohr * @param string $mode 1705a3e1f53SAndreas Gohr * @return bool 1715a3e1f53SAndreas Gohr */ 1725a3e1f53SAndreas Gohr function accepts($mode); 1735a3e1f53SAndreas Gohr} 1745a3e1f53SAndreas Gohr 1750cecf9d5Sandi/** 17672d89f96SAndreas Gohr * This class and all the subclasses below are used to reduce the effort required to register 17772d89f96SAndreas Gohr * modes with the Lexer. 17872d89f96SAndreas Gohr * 1790b7c14c2Sandi * @author Harry Fuecks <hfuecks@gmail.com> 1800cecf9d5Sandi */ 1815a3e1f53SAndreas Gohrclass Doku_Parser_Mode implements Doku_Parser_Mode_Interface { 182e3ab6fc5SMichael Hamann /** 183e3ab6fc5SMichael Hamann * @var Doku_Lexer $Lexer 184e3ab6fc5SMichael Hamann */ 1850cecf9d5Sandi var $Lexer; 1860cecf9d5Sandi var $allowedModes = array(); 1870cecf9d5Sandi 188107b01d6Sandi function getSort() { 189107b01d6Sandi trigger_error('getSort() not implemented in '.get_class($this), E_USER_WARNING); 190107b01d6Sandi } 191107b01d6Sandi 1920cecf9d5Sandi function preConnect() {} 1930cecf9d5Sandi function connectTo($mode) {} 1940cecf9d5Sandi function postConnect() {} 1950cecf9d5Sandi function accepts($mode) { 1966f9bd982SAndreas Gohr return in_array($mode, (array) $this->allowedModes ); 1970cecf9d5Sandi } 1985a3e1f53SAndreas Gohr} 1990cecf9d5Sandi 2005a3e1f53SAndreas Gohr/** 2015a3e1f53SAndreas Gohr * Basically the same as Doku_Parser_Mode but extends from DokuWiki_Plugin 2025a3e1f53SAndreas Gohr * 2035a3e1f53SAndreas Gohr * Adds additional functions to syntax plugins 2045a3e1f53SAndreas Gohr */ 2055a3e1f53SAndreas Gohrclass Doku_Parser_Mode_Plugin extends DokuWiki_Plugin implements Doku_Parser_Mode_Interface { 2065a3e1f53SAndreas Gohr /** 2075a3e1f53SAndreas Gohr * @var Doku_Lexer $Lexer 2085a3e1f53SAndreas Gohr */ 2095a3e1f53SAndreas Gohr var $Lexer; 2105a3e1f53SAndreas Gohr var $allowedModes = array(); 2115a3e1f53SAndreas Gohr 2127ac0b9feSAndreas Gohr /** 2137ac0b9feSAndreas Gohr * Sort for applying this mode 2147ac0b9feSAndreas Gohr * 2157ac0b9feSAndreas Gohr * @return int 2167ac0b9feSAndreas Gohr */ 2175a3e1f53SAndreas Gohr function getSort() { 2185a3e1f53SAndreas Gohr trigger_error('getSort() not implemented in '.get_class($this), E_USER_WARNING); 2195a3e1f53SAndreas Gohr } 2205a3e1f53SAndreas Gohr 2215a3e1f53SAndreas Gohr function preConnect() {} 2225a3e1f53SAndreas Gohr function connectTo($mode) {} 2235a3e1f53SAndreas Gohr function postConnect() {} 2245a3e1f53SAndreas Gohr function accepts($mode) { 2255a3e1f53SAndreas Gohr return in_array($mode, (array) $this->allowedModes ); 2265a3e1f53SAndreas Gohr } 2270cecf9d5Sandi} 2280cecf9d5Sandi 2290cecf9d5Sandi//------------------------------------------------------------------- 230107b01d6Sandiclass Doku_Parser_Mode_base extends Doku_Parser_Mode { 2310cecf9d5Sandi 23226e22ab8SChristopher Smith function __construct() { 233ee20e7d1Sandi global $PARSER_MODES; 2340cecf9d5Sandi 2350cecf9d5Sandi $this->allowedModes = array_merge ( 236ee20e7d1Sandi $PARSER_MODES['container'], 237ee20e7d1Sandi $PARSER_MODES['baseonly'], 238ee20e7d1Sandi $PARSER_MODES['paragraphs'], 239ee20e7d1Sandi $PARSER_MODES['formatting'], 240ee20e7d1Sandi $PARSER_MODES['substition'], 241ee20e7d1Sandi $PARSER_MODES['protected'], 242ee20e7d1Sandi $PARSER_MODES['disabled'] 2430cecf9d5Sandi ); 2440cecf9d5Sandi } 245107b01d6Sandi 246107b01d6Sandi function getSort() { 247107b01d6Sandi return 0; 248107b01d6Sandi } 2490cecf9d5Sandi} 2500cecf9d5Sandi 2510cecf9d5Sandi//------------------------------------------------------------------- 252107b01d6Sandiclass Doku_Parser_Mode_footnote extends Doku_Parser_Mode { 2530cecf9d5Sandi 25426e22ab8SChristopher Smith function __construct() { 255ee20e7d1Sandi global $PARSER_MODES; 2560cecf9d5Sandi 2570cecf9d5Sandi $this->allowedModes = array_merge ( 258ee20e7d1Sandi $PARSER_MODES['container'], 259ee20e7d1Sandi $PARSER_MODES['formatting'], 260ee20e7d1Sandi $PARSER_MODES['substition'], 261ee20e7d1Sandi $PARSER_MODES['protected'], 262ee20e7d1Sandi $PARSER_MODES['disabled'] 2630cecf9d5Sandi ); 2640cecf9d5Sandi 2652fe7363dSchris unset($this->allowedModes[array_search('footnote', $this->allowedModes)]); 2660cecf9d5Sandi } 2670cecf9d5Sandi 2680cecf9d5Sandi function connectTo($mode) { 2690cecf9d5Sandi $this->Lexer->addEntryPattern( 2700cecf9d5Sandi '\x28\x28(?=.*\x29\x29)',$mode,'footnote' 2710cecf9d5Sandi ); 2720cecf9d5Sandi } 2730cecf9d5Sandi 2740cecf9d5Sandi function postConnect() { 2750cecf9d5Sandi $this->Lexer->addExitPattern( 2760cecf9d5Sandi '\x29\x29','footnote' 2770cecf9d5Sandi ); 2780cecf9d5Sandi } 2790cecf9d5Sandi 280107b01d6Sandi function getSort() { 281107b01d6Sandi return 150; 282107b01d6Sandi } 2830cecf9d5Sandi} 2840cecf9d5Sandi 2850cecf9d5Sandi//------------------------------------------------------------------- 286107b01d6Sandiclass Doku_Parser_Mode_header extends Doku_Parser_Mode { 2870cecf9d5Sandi 2889fa736b0SAndreas Gohr function connectTo($mode) { 289506ae684Sandi //we're not picky about the closing ones, two are enough 2900cecf9d5Sandi $this->Lexer->addSpecialPattern( 29130fe9cd6SAndreas Gohr '[ \t]*={2,}[^\n]+={2,}[ \t]*(?=\n)', 2929fa736b0SAndreas Gohr $mode, 2930cecf9d5Sandi 'header' 2940cecf9d5Sandi ); 2950cecf9d5Sandi } 2960cecf9d5Sandi 297107b01d6Sandi function getSort() { 298107b01d6Sandi return 50; 299107b01d6Sandi } 3000cecf9d5Sandi} 3010cecf9d5Sandi 3020cecf9d5Sandi//------------------------------------------------------------------- 303107b01d6Sandiclass Doku_Parser_Mode_notoc extends Doku_Parser_Mode { 3040cecf9d5Sandi 3050cecf9d5Sandi function connectTo($mode) { 3060cecf9d5Sandi $this->Lexer->addSpecialPattern('~~NOTOC~~',$mode,'notoc'); 3070cecf9d5Sandi } 3080cecf9d5Sandi 309107b01d6Sandi function getSort() { 310107b01d6Sandi return 30; 311107b01d6Sandi } 3120cecf9d5Sandi} 3130cecf9d5Sandi 3140cecf9d5Sandi//------------------------------------------------------------------- 315107b01d6Sandiclass Doku_Parser_Mode_nocache extends Doku_Parser_Mode { 3169dc2c2afSandi 3179dc2c2afSandi function connectTo($mode) { 3189dc2c2afSandi $this->Lexer->addSpecialPattern('~~NOCACHE~~',$mode,'nocache'); 3199dc2c2afSandi } 3209dc2c2afSandi 321107b01d6Sandi function getSort() { 322107b01d6Sandi return 40; 323107b01d6Sandi } 3249dc2c2afSandi} 3259dc2c2afSandi 3269dc2c2afSandi//------------------------------------------------------------------- 327107b01d6Sandiclass Doku_Parser_Mode_linebreak extends Doku_Parser_Mode { 3280cecf9d5Sandi 3290cecf9d5Sandi function connectTo($mode) { 33030897fecSChris Smith $this->Lexer->addSpecialPattern('\x5C{2}(?:[ \t]|(?=\n))',$mode,'linebreak'); 3310cecf9d5Sandi } 332107b01d6Sandi 333107b01d6Sandi function getSort() { 334107b01d6Sandi return 140; 335107b01d6Sandi } 3360cecf9d5Sandi} 3370cecf9d5Sandi 3380cecf9d5Sandi//------------------------------------------------------------------- 339107b01d6Sandiclass Doku_Parser_Mode_eol extends Doku_Parser_Mode { 3400cecf9d5Sandi 3410cecf9d5Sandi function connectTo($mode) { 3420cecf9d5Sandi $badModes = array('listblock','table'); 3430cecf9d5Sandi if ( in_array($mode, $badModes) ) { 3440cecf9d5Sandi return; 3450cecf9d5Sandi } 34695c19ce7SChris Smith // see FS#1652, pattern extended to swallow preceding whitespace to avoid issues with lines that only contain whitespace 34795c19ce7SChris Smith $this->Lexer->addSpecialPattern('(?:^[ \t]*)?\n',$mode,'eol'); 3480cecf9d5Sandi } 349107b01d6Sandi 350107b01d6Sandi function getSort() { 351107b01d6Sandi return 370; 352107b01d6Sandi } 3530cecf9d5Sandi} 3540cecf9d5Sandi 3550cecf9d5Sandi//------------------------------------------------------------------- 356107b01d6Sandiclass Doku_Parser_Mode_hr extends Doku_Parser_Mode { 3570cecf9d5Sandi 3580cecf9d5Sandi function connectTo($mode) { 3596f0c5dbfSandi $this->Lexer->addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr'); 3600cecf9d5Sandi } 3610cecf9d5Sandi 362107b01d6Sandi function getSort() { 363107b01d6Sandi return 160; 364107b01d6Sandi } 3650cecf9d5Sandi} 3660cecf9d5Sandi 3670cecf9d5Sandi//------------------------------------------------------------------- 36803b54bb0SThorsten Staerk/** 36903b54bb0SThorsten Staerk * This class sets the markup for bold (=strong), 37003b54bb0SThorsten Staerk * italic (=emphasis), underline etc. 37103b54bb0SThorsten Staerk */ 372107b01d6Sandiclass Doku_Parser_Mode_formatting extends Doku_Parser_Mode { 3730cecf9d5Sandi var $type; 3740cecf9d5Sandi 3750cecf9d5Sandi var $formatting = array ( 3760cecf9d5Sandi 'strong' => array ( 3770cecf9d5Sandi 'entry'=>'\*\*(?=.*\*\*)', 3780cecf9d5Sandi 'exit'=>'\*\*', 379107b01d6Sandi 'sort'=>70 3800cecf9d5Sandi ), 3810cecf9d5Sandi 3820cecf9d5Sandi 'emphasis'=> array ( 38324b0ff2aSAndreas Gohr 'entry'=>'//(?=[^\x00]*[^:])', //hack for bugs #384 #763 #1468 3840cecf9d5Sandi 'exit'=>'//', 385107b01d6Sandi 'sort'=>80 3860cecf9d5Sandi ), 3870cecf9d5Sandi 3880cecf9d5Sandi 'underline'=> array ( 3890cecf9d5Sandi 'entry'=>'__(?=.*__)', 3900cecf9d5Sandi 'exit'=>'__', 391107b01d6Sandi 'sort'=>90 3920cecf9d5Sandi ), 3930cecf9d5Sandi 3940cecf9d5Sandi 'monospace'=> array ( 3950cecf9d5Sandi 'entry'=>'\x27\x27(?=.*\x27\x27)', 3960cecf9d5Sandi 'exit'=>'\x27\x27', 397107b01d6Sandi 'sort'=>100 3980cecf9d5Sandi ), 3990cecf9d5Sandi 4000cecf9d5Sandi 'subscript'=> array ( 40187858f84Schris 'entry'=>'<sub>(?=.*</sub>)', 4020cecf9d5Sandi 'exit'=>'</sub>', 403107b01d6Sandi 'sort'=>110 4040cecf9d5Sandi ), 4050cecf9d5Sandi 4060cecf9d5Sandi 'superscript'=> array ( 40787858f84Schris 'entry'=>'<sup>(?=.*</sup>)', 4080cecf9d5Sandi 'exit'=>'</sup>', 409107b01d6Sandi 'sort'=>120 4100cecf9d5Sandi ), 4110cecf9d5Sandi 4120cecf9d5Sandi 'deleted'=> array ( 41387858f84Schris 'entry'=>'<del>(?=.*</del>)', 4140cecf9d5Sandi 'exit'=>'</del>', 415107b01d6Sandi 'sort'=>130 4160cecf9d5Sandi ), 4170cecf9d5Sandi ); 4180cecf9d5Sandi 419276820f7SScrutinizer Auto-Fixer /** 420276820f7SScrutinizer Auto-Fixer * @param string $type 421276820f7SScrutinizer Auto-Fixer */ 42226e22ab8SChristopher Smith function __construct($type) { 423ee20e7d1Sandi global $PARSER_MODES; 4240cecf9d5Sandi 4250cecf9d5Sandi if ( !array_key_exists($type, $this->formatting) ) { 4260cecf9d5Sandi trigger_error('Invalid formatting type '.$type, E_USER_WARNING); 4270cecf9d5Sandi } 4280cecf9d5Sandi 4290cecf9d5Sandi $this->type = $type; 4300cecf9d5Sandi 431ee20e7d1Sandi // formatting may contain other formatting but not it self 432ee20e7d1Sandi $modes = $PARSER_MODES['formatting']; 433ee20e7d1Sandi $key = array_search($type, $modes); 434ee20e7d1Sandi if ( is_int($key) ) { 435ee20e7d1Sandi unset($modes[$key]); 436ee20e7d1Sandi } 4370cecf9d5Sandi 438ee20e7d1Sandi $this->allowedModes = array_merge ( 439ee20e7d1Sandi $modes, 440ee20e7d1Sandi $PARSER_MODES['substition'], 441ee20e7d1Sandi $PARSER_MODES['disabled'] 442ee20e7d1Sandi ); 4430cecf9d5Sandi } 4440cecf9d5Sandi 4450cecf9d5Sandi function connectTo($mode) { 4460cecf9d5Sandi 4470cecf9d5Sandi // Can't nest formatting in itself 4480cecf9d5Sandi if ( $mode == $this->type ) { 4490cecf9d5Sandi return; 4500cecf9d5Sandi } 4510cecf9d5Sandi 4520cecf9d5Sandi $this->Lexer->addEntryPattern( 4530cecf9d5Sandi $this->formatting[$this->type]['entry'], 4540cecf9d5Sandi $mode, 4550cecf9d5Sandi $this->type 4560cecf9d5Sandi ); 4570cecf9d5Sandi } 4580cecf9d5Sandi 4590cecf9d5Sandi function postConnect() { 4600cecf9d5Sandi 4610cecf9d5Sandi $this->Lexer->addExitPattern( 4620cecf9d5Sandi $this->formatting[$this->type]['exit'], 4630cecf9d5Sandi $this->type 4640cecf9d5Sandi ); 4650cecf9d5Sandi 4660cecf9d5Sandi } 467107b01d6Sandi 468107b01d6Sandi function getSort() { 469107b01d6Sandi return $this->formatting[$this->type]['sort']; 470107b01d6Sandi } 4710cecf9d5Sandi} 4720cecf9d5Sandi 4730cecf9d5Sandi//------------------------------------------------------------------- 474107b01d6Sandiclass Doku_Parser_Mode_listblock extends Doku_Parser_Mode { 4750cecf9d5Sandi 47626e22ab8SChristopher Smith function __construct() { 477ee20e7d1Sandi global $PARSER_MODES; 4780cecf9d5Sandi 4790cecf9d5Sandi $this->allowedModes = array_merge ( 480ee20e7d1Sandi $PARSER_MODES['formatting'], 481ee20e7d1Sandi $PARSER_MODES['substition'], 482ee20e7d1Sandi $PARSER_MODES['disabled'], 483ee20e7d1Sandi $PARSER_MODES['protected'] #XXX new 4840cecf9d5Sandi ); 485702eb898Sandi 486ee20e7d1Sandi // $this->allowedModes[] = 'footnote'; 4870cecf9d5Sandi } 4880cecf9d5Sandi 4890cecf9d5Sandi function connectTo($mode) { 49013ebcbe5SChristopher Smith $this->Lexer->addEntryPattern('[ \t]*\n {2,}[\-\*]',$mode,'listblock'); 49113ebcbe5SChristopher Smith $this->Lexer->addEntryPattern('[ \t]*\n\t{1,}[\-\*]',$mode,'listblock'); 4920cecf9d5Sandi 4930cecf9d5Sandi $this->Lexer->addPattern('\n {2,}[\-\*]','listblock'); 4940cecf9d5Sandi $this->Lexer->addPattern('\n\t{1,}[\-\*]','listblock'); 4950cecf9d5Sandi 4960cecf9d5Sandi } 4970cecf9d5Sandi 4980cecf9d5Sandi function postConnect() { 4990cecf9d5Sandi $this->Lexer->addExitPattern('\n','listblock'); 5000cecf9d5Sandi } 501107b01d6Sandi 502107b01d6Sandi function getSort() { 503107b01d6Sandi return 10; 504107b01d6Sandi } 5050cecf9d5Sandi} 5060cecf9d5Sandi 5070cecf9d5Sandi//------------------------------------------------------------------- 508107b01d6Sandiclass Doku_Parser_Mode_table extends Doku_Parser_Mode { 5090cecf9d5Sandi 51026e22ab8SChristopher Smith function __construct() { 511ee20e7d1Sandi global $PARSER_MODES; 5120cecf9d5Sandi 5130cecf9d5Sandi $this->allowedModes = array_merge ( 514ee20e7d1Sandi $PARSER_MODES['formatting'], 515ee20e7d1Sandi $PARSER_MODES['substition'], 516ee20e7d1Sandi $PARSER_MODES['disabled'], 517107b01d6Sandi $PARSER_MODES['protected'] 5180cecf9d5Sandi ); 5190cecf9d5Sandi } 5200cecf9d5Sandi 5210cecf9d5Sandi function connectTo($mode) { 5225a41afe6SChristopher Smith $this->Lexer->addEntryPattern('[\t ]*\n\^',$mode,'table'); 5235a41afe6SChristopher Smith $this->Lexer->addEntryPattern('[\t ]*\n\|',$mode,'table'); 5240cecf9d5Sandi } 5250cecf9d5Sandi 5260cecf9d5Sandi function postConnect() { 5270cecf9d5Sandi $this->Lexer->addPattern('\n\^','table'); 5280cecf9d5Sandi $this->Lexer->addPattern('\n\|','table'); 52925b97867Shakan.sandell $this->Lexer->addPattern('[\t ]*:::[\t ]*(?=[\|\^])','table'); 5309ab75d9eSAndreas Gohr $this->Lexer->addPattern('[\t ]+','table'); 5310cecf9d5Sandi $this->Lexer->addPattern('\^','table'); 5320cecf9d5Sandi $this->Lexer->addPattern('\|','table'); 5330cecf9d5Sandi $this->Lexer->addExitPattern('\n','table'); 5340cecf9d5Sandi } 535107b01d6Sandi 536107b01d6Sandi function getSort() { 537107b01d6Sandi return 60; 538107b01d6Sandi } 5390cecf9d5Sandi} 5400cecf9d5Sandi 5410cecf9d5Sandi//------------------------------------------------------------------- 542107b01d6Sandiclass Doku_Parser_Mode_unformatted extends Doku_Parser_Mode { 5430cecf9d5Sandi 5440cecf9d5Sandi function connectTo($mode) { 54587858f84Schris $this->Lexer->addEntryPattern('<nowiki>(?=.*</nowiki>)',$mode,'unformatted'); 5460cecf9d5Sandi $this->Lexer->addEntryPattern('%%(?=.*%%)',$mode,'unformattedalt'); 5470cecf9d5Sandi } 5480cecf9d5Sandi 5490cecf9d5Sandi function postConnect() { 5500cecf9d5Sandi $this->Lexer->addExitPattern('</nowiki>','unformatted'); 5510cecf9d5Sandi $this->Lexer->addExitPattern('%%','unformattedalt'); 5520cecf9d5Sandi $this->Lexer->mapHandler('unformattedalt','unformatted'); 5530cecf9d5Sandi } 5540cecf9d5Sandi 555107b01d6Sandi function getSort() { 556107b01d6Sandi return 170; 557107b01d6Sandi } 5580cecf9d5Sandi} 5590cecf9d5Sandi 5600cecf9d5Sandi//------------------------------------------------------------------- 561107b01d6Sandiclass Doku_Parser_Mode_php extends Doku_Parser_Mode { 5620cecf9d5Sandi 5630cecf9d5Sandi function connectTo($mode) { 56487858f84Schris $this->Lexer->addEntryPattern('<php>(?=.*</php>)',$mode,'php'); 56507f89c3cSAnika Henke $this->Lexer->addEntryPattern('<PHP>(?=.*</PHP>)',$mode,'phpblock'); 5660cecf9d5Sandi } 5670cecf9d5Sandi 5680cecf9d5Sandi function postConnect() { 5690cecf9d5Sandi $this->Lexer->addExitPattern('</php>','php'); 57007f89c3cSAnika Henke $this->Lexer->addExitPattern('</PHP>','phpblock'); 5710cecf9d5Sandi } 5720cecf9d5Sandi 573107b01d6Sandi function getSort() { 574107b01d6Sandi return 180; 575107b01d6Sandi } 5760cecf9d5Sandi} 5770cecf9d5Sandi 5780cecf9d5Sandi//------------------------------------------------------------------- 579107b01d6Sandiclass Doku_Parser_Mode_html extends Doku_Parser_Mode { 5800cecf9d5Sandi 5810cecf9d5Sandi function connectTo($mode) { 58287858f84Schris $this->Lexer->addEntryPattern('<html>(?=.*</html>)',$mode,'html'); 58307f89c3cSAnika Henke $this->Lexer->addEntryPattern('<HTML>(?=.*</HTML>)',$mode,'htmlblock'); 5840cecf9d5Sandi } 5850cecf9d5Sandi 5860cecf9d5Sandi function postConnect() { 5870cecf9d5Sandi $this->Lexer->addExitPattern('</html>','html'); 58807f89c3cSAnika Henke $this->Lexer->addExitPattern('</HTML>','htmlblock'); 5890cecf9d5Sandi } 5900cecf9d5Sandi 591107b01d6Sandi function getSort() { 592107b01d6Sandi return 190; 593107b01d6Sandi } 5940cecf9d5Sandi} 5950cecf9d5Sandi 5960cecf9d5Sandi//------------------------------------------------------------------- 597107b01d6Sandiclass Doku_Parser_Mode_preformatted extends Doku_Parser_Mode { 5980cecf9d5Sandi 5990cecf9d5Sandi function connectTo($mode) { 6000cecf9d5Sandi // Has hard coded awareness of lists... 6010cecf9d5Sandi $this->Lexer->addEntryPattern('\n (?![\*\-])',$mode,'preformatted'); 6020cecf9d5Sandi $this->Lexer->addEntryPattern('\n\t(?![\*\-])',$mode,'preformatted'); 6030cecf9d5Sandi 6040cecf9d5Sandi // How to effect a sub pattern with the Lexer! 6050cecf9d5Sandi $this->Lexer->addPattern('\n ','preformatted'); 6060cecf9d5Sandi $this->Lexer->addPattern('\n\t','preformatted'); 6070cecf9d5Sandi 6080cecf9d5Sandi } 6090cecf9d5Sandi 6100cecf9d5Sandi function postConnect() { 6110cecf9d5Sandi $this->Lexer->addExitPattern('\n','preformatted'); 6120cecf9d5Sandi } 6130cecf9d5Sandi 614107b01d6Sandi function getSort() { 615107b01d6Sandi return 20; 616107b01d6Sandi } 6170cecf9d5Sandi} 6180cecf9d5Sandi 6190cecf9d5Sandi//------------------------------------------------------------------- 620107b01d6Sandiclass Doku_Parser_Mode_code extends Doku_Parser_Mode { 6210cecf9d5Sandi 6220cecf9d5Sandi function connectTo($mode) { 623fc498a42SChristopher Smith $this->Lexer->addEntryPattern('<code\b(?=.*</code>)',$mode,'code'); 6240cecf9d5Sandi } 6250cecf9d5Sandi 6260cecf9d5Sandi function postConnect() { 6270cecf9d5Sandi $this->Lexer->addExitPattern('</code>','code'); 6280cecf9d5Sandi } 6290cecf9d5Sandi 630107b01d6Sandi function getSort() { 631107b01d6Sandi return 200; 632107b01d6Sandi } 6330cecf9d5Sandi} 6340cecf9d5Sandi 6350cecf9d5Sandi//------------------------------------------------------------------- 636107b01d6Sandiclass Doku_Parser_Mode_file extends Doku_Parser_Mode { 6370cecf9d5Sandi 6380cecf9d5Sandi function connectTo($mode) { 639fc498a42SChristopher Smith $this->Lexer->addEntryPattern('<file\b(?=.*</file>)',$mode,'file'); 6400cecf9d5Sandi } 6410cecf9d5Sandi 6420cecf9d5Sandi function postConnect() { 6430cecf9d5Sandi $this->Lexer->addExitPattern('</file>','file'); 6440cecf9d5Sandi } 6450cecf9d5Sandi 646107b01d6Sandi function getSort() { 647107b01d6Sandi return 210; 648107b01d6Sandi } 6490cecf9d5Sandi} 6500cecf9d5Sandi 6510cecf9d5Sandi//------------------------------------------------------------------- 652107b01d6Sandiclass Doku_Parser_Mode_quote extends Doku_Parser_Mode { 6530cecf9d5Sandi 65426e22ab8SChristopher Smith function __construct() { 655ee20e7d1Sandi global $PARSER_MODES; 6560cecf9d5Sandi 6570cecf9d5Sandi $this->allowedModes = array_merge ( 658ee20e7d1Sandi $PARSER_MODES['formatting'], 659ee20e7d1Sandi $PARSER_MODES['substition'], 660ee20e7d1Sandi $PARSER_MODES['disabled'], 661ee20e7d1Sandi $PARSER_MODES['protected'] #XXX new 6620cecf9d5Sandi ); 663ee20e7d1Sandi #$this->allowedModes[] = 'footnote'; 664ee20e7d1Sandi #$this->allowedModes[] = 'preformatted'; 665ee20e7d1Sandi #$this->allowedModes[] = 'unformatted'; 6660cecf9d5Sandi } 6670cecf9d5Sandi 6680cecf9d5Sandi function connectTo($mode) { 6690cecf9d5Sandi $this->Lexer->addEntryPattern('\n>{1,}',$mode,'quote'); 6700cecf9d5Sandi } 6710cecf9d5Sandi 6720cecf9d5Sandi function postConnect() { 6730cecf9d5Sandi $this->Lexer->addPattern('\n>{1,}','quote'); 6740cecf9d5Sandi $this->Lexer->addExitPattern('\n','quote'); 6750cecf9d5Sandi } 6760cecf9d5Sandi 677107b01d6Sandi function getSort() { 678107b01d6Sandi return 220; 679107b01d6Sandi } 6800cecf9d5Sandi} 6810cecf9d5Sandi 6820cecf9d5Sandi//------------------------------------------------------------------- 683107b01d6Sandiclass Doku_Parser_Mode_acronym extends Doku_Parser_Mode { 6840cecf9d5Sandi // A list 6850cecf9d5Sandi var $acronyms = array(); 6860cecf9d5Sandi var $pattern = ''; 6870cecf9d5Sandi 68826e22ab8SChristopher Smith function __construct($acronyms) { 6897cc4b757SChris Smith usort($acronyms,array($this,'_compare')); 6900cecf9d5Sandi $this->acronyms = $acronyms; 6910cecf9d5Sandi } 6920cecf9d5Sandi 6930cecf9d5Sandi function preConnect() { 694901c1c87SAndreas Gohr if(!count($this->acronyms)) return; 695901c1c87SAndreas Gohr 6968e266198SAndreas Gohr $bound = '[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]'; 697e6258e07SAndreas Gohr $acronyms = array_map('Doku_Lexer_Escape',$this->acronyms); 6988e266198SAndreas Gohr $this->pattern = '(?<=^|'.$bound.')(?:'.join('|',$acronyms).')(?='.$bound.')'; 6990cecf9d5Sandi } 7000cecf9d5Sandi 7010cecf9d5Sandi function connectTo($mode) { 702901c1c87SAndreas Gohr if(!count($this->acronyms)) return; 703901c1c87SAndreas Gohr 7040cecf9d5Sandi if ( strlen($this->pattern) > 0 ) { 7050cecf9d5Sandi $this->Lexer->addSpecialPattern($this->pattern,$mode,'acronym'); 7060cecf9d5Sandi } 7070cecf9d5Sandi } 7080cecf9d5Sandi 709107b01d6Sandi function getSort() { 710107b01d6Sandi return 240; 711107b01d6Sandi } 7127cc4b757SChris Smith 7137cc4b757SChris Smith /** 7147cc4b757SChris Smith * sort callback to order by string length descending 715*f50a239bSTakamura * 716*f50a239bSTakamura * @param string $a 717*f50a239bSTakamura * @param string $b 718*f50a239bSTakamura * 719*f50a239bSTakamura * @return int 7207cc4b757SChris Smith */ 7217cc4b757SChris Smith function _compare($a,$b) { 7227cc4b757SChris Smith $a_len = strlen($a); 7237cc4b757SChris Smith $b_len = strlen($b); 7247cc4b757SChris Smith if ($a_len > $b_len) { 7257cc4b757SChris Smith return -1; 7267cc4b757SChris Smith } else if ($a_len < $b_len) { 7277cc4b757SChris Smith return 1; 7287cc4b757SChris Smith } 7297cc4b757SChris Smith 7307cc4b757SChris Smith return 0; 7317cc4b757SChris Smith } 7320cecf9d5Sandi} 7330cecf9d5Sandi 7340cecf9d5Sandi//------------------------------------------------------------------- 735107b01d6Sandiclass Doku_Parser_Mode_smiley extends Doku_Parser_Mode { 7360cecf9d5Sandi // A list 7370cecf9d5Sandi var $smileys = array(); 7380cecf9d5Sandi var $pattern = ''; 7390cecf9d5Sandi 74026e22ab8SChristopher Smith function __construct($smileys) { 7410cecf9d5Sandi $this->smileys = $smileys; 7420cecf9d5Sandi } 7430cecf9d5Sandi 7440cecf9d5Sandi function preConnect() { 745d4834a19SStephane Chazelas if(!count($this->smileys) || $this->pattern != '') return; 746901c1c87SAndreas Gohr 7470cecf9d5Sandi $sep = ''; 7480cecf9d5Sandi foreach ( $this->smileys as $smiley ) { 7491b26635bSAndreas Gohr $this->pattern .= $sep.'(?<=\W|^)'.Doku_Lexer_Escape($smiley).'(?=\W|$)'; 7500cecf9d5Sandi $sep = '|'; 7510cecf9d5Sandi } 7520cecf9d5Sandi } 7530cecf9d5Sandi 7540cecf9d5Sandi function connectTo($mode) { 755901c1c87SAndreas Gohr if(!count($this->smileys)) return; 756901c1c87SAndreas Gohr 7570cecf9d5Sandi if ( strlen($this->pattern) > 0 ) { 7580cecf9d5Sandi $this->Lexer->addSpecialPattern($this->pattern,$mode,'smiley'); 7590cecf9d5Sandi } 7600cecf9d5Sandi } 7610cecf9d5Sandi 762107b01d6Sandi function getSort() { 763107b01d6Sandi return 230; 764107b01d6Sandi } 7650cecf9d5Sandi} 7660cecf9d5Sandi 7670cecf9d5Sandi//------------------------------------------------------------------- 768107b01d6Sandiclass Doku_Parser_Mode_wordblock extends Doku_Parser_Mode { 7690cecf9d5Sandi // A list 7700cecf9d5Sandi var $badwords = array(); 7710cecf9d5Sandi var $pattern = ''; 7720cecf9d5Sandi 77326e22ab8SChristopher Smith function __construct($badwords) { 7740cecf9d5Sandi $this->badwords = $badwords; 7750cecf9d5Sandi } 7760cecf9d5Sandi 7770cecf9d5Sandi function preConnect() { 7780cecf9d5Sandi 779d4834a19SStephane Chazelas if ( count($this->badwords) == 0 || $this->pattern != '') { 7800cecf9d5Sandi return; 7810cecf9d5Sandi } 7820cecf9d5Sandi 7830cecf9d5Sandi $sep = ''; 7840cecf9d5Sandi foreach ( $this->badwords as $badword ) { 7850cecf9d5Sandi $this->pattern .= $sep.'(?<=\b)(?i)'.Doku_Lexer_Escape($badword).'(?-i)(?=\b)'; 7860cecf9d5Sandi $sep = '|'; 7870cecf9d5Sandi } 7880cecf9d5Sandi 7890cecf9d5Sandi } 7900cecf9d5Sandi 7910cecf9d5Sandi function connectTo($mode) { 7920cecf9d5Sandi if ( strlen($this->pattern) > 0 ) { 7930cecf9d5Sandi $this->Lexer->addSpecialPattern($this->pattern,$mode,'wordblock'); 7940cecf9d5Sandi } 7950cecf9d5Sandi } 7960cecf9d5Sandi 797107b01d6Sandi function getSort() { 798107b01d6Sandi return 250; 799107b01d6Sandi } 8000cecf9d5Sandi} 8010cecf9d5Sandi 8020cecf9d5Sandi//------------------------------------------------------------------- 803107b01d6Sandiclass Doku_Parser_Mode_entity extends Doku_Parser_Mode { 8040cecf9d5Sandi // A list 8050cecf9d5Sandi var $entities = array(); 8060cecf9d5Sandi var $pattern = ''; 8070cecf9d5Sandi 80826e22ab8SChristopher Smith function __construct($entities) { 8090cecf9d5Sandi $this->entities = $entities; 8100cecf9d5Sandi } 8110cecf9d5Sandi 8120cecf9d5Sandi function preConnect() { 813d4834a19SStephane Chazelas if(!count($this->entities) || $this->pattern != '') return; 814901c1c87SAndreas Gohr 8150cecf9d5Sandi $sep = ''; 8160cecf9d5Sandi foreach ( $this->entities as $entity ) { 8170cecf9d5Sandi $this->pattern .= $sep.Doku_Lexer_Escape($entity); 8180cecf9d5Sandi $sep = '|'; 8190cecf9d5Sandi } 8200cecf9d5Sandi } 8210cecf9d5Sandi 8220cecf9d5Sandi function connectTo($mode) { 823901c1c87SAndreas Gohr if(!count($this->entities)) return; 824901c1c87SAndreas Gohr 8250cecf9d5Sandi if ( strlen($this->pattern) > 0 ) { 8260cecf9d5Sandi $this->Lexer->addSpecialPattern($this->pattern,$mode,'entity'); 8270cecf9d5Sandi } 8280cecf9d5Sandi } 8290cecf9d5Sandi 830107b01d6Sandi function getSort() { 831107b01d6Sandi return 260; 832107b01d6Sandi } 8330cecf9d5Sandi} 8340cecf9d5Sandi 8350cecf9d5Sandi//------------------------------------------------------------------- 8360cecf9d5Sandi// Implements the 640x480 replacement 837107b01d6Sandiclass Doku_Parser_Mode_multiplyentity extends Doku_Parser_Mode { 8380cecf9d5Sandi 8390cecf9d5Sandi function connectTo($mode) { 8400cecf9d5Sandi 8410cecf9d5Sandi $this->Lexer->addSpecialPattern( 84268df1afcSChris Smith '(?<=\b)(?:[1-9]|\d{2,})[xX]\d+(?=\b)',$mode,'multiplyentity' 8430cecf9d5Sandi ); 8440cecf9d5Sandi 8450cecf9d5Sandi } 8460cecf9d5Sandi 847107b01d6Sandi function getSort() { 848107b01d6Sandi return 270; 849107b01d6Sandi } 8500cecf9d5Sandi} 8510cecf9d5Sandi 8520cecf9d5Sandi//------------------------------------------------------------------- 853107b01d6Sandiclass Doku_Parser_Mode_quotes extends Doku_Parser_Mode { 8540cecf9d5Sandi 8550cecf9d5Sandi function connectTo($mode) { 8569426a41aSAndreas Gohr global $conf; 8579426a41aSAndreas Gohr 8585fc8a925SAndreas Gohr $ws = '\s/\#~:+=&%@\-\x28\x29\]\[{}><"\''; // whitespace 8595fc8a925SAndreas Gohr $punc = ';,\.?!'; 8600cecf9d5Sandi 8619426a41aSAndreas Gohr if($conf['typography'] == 2){ 8620cecf9d5Sandi $this->Lexer->addSpecialPattern( 8635fc8a925SAndreas Gohr "(?<=^|[$ws])'(?=[^$ws$punc])",$mode,'singlequoteopening' 8640cecf9d5Sandi ); 8650cecf9d5Sandi $this->Lexer->addSpecialPattern( 8665fc8a925SAndreas Gohr "(?<=^|[^$ws]|[$punc])'(?=$|[$ws$punc])",$mode,'singlequoteclosing' 8670cecf9d5Sandi ); 8680cecf9d5Sandi $this->Lexer->addSpecialPattern( 8695fc8a925SAndreas Gohr "(?<=^|[^$ws$punc])'(?=$|[^$ws$punc])",$mode,'apostrophe' 8700cecf9d5Sandi ); 8719426a41aSAndreas Gohr } 8729426a41aSAndreas Gohr 8730cecf9d5Sandi $this->Lexer->addSpecialPattern( 8745fc8a925SAndreas Gohr "(?<=^|[$ws])\"(?=[^$ws$punc])",$mode,'doublequoteopening' 8750cecf9d5Sandi ); 87657d757d1SAndreas Gohr $this->Lexer->addSpecialPattern( 8775fc8a925SAndreas Gohr "\"",$mode,'doublequoteclosing' 87857d757d1SAndreas Gohr ); 87957d757d1SAndreas Gohr 8800cecf9d5Sandi } 8810cecf9d5Sandi 882107b01d6Sandi function getSort() { 883107b01d6Sandi return 280; 884107b01d6Sandi } 8850cecf9d5Sandi} 8860cecf9d5Sandi 8870cecf9d5Sandi//------------------------------------------------------------------- 888107b01d6Sandiclass Doku_Parser_Mode_camelcaselink extends Doku_Parser_Mode { 8890cecf9d5Sandi 8900cecf9d5Sandi function connectTo($mode) { 8910cecf9d5Sandi $this->Lexer->addSpecialPattern( 8920cecf9d5Sandi '\b[A-Z]+[a-z]+[A-Z][A-Za-z]*\b',$mode,'camelcaselink' 8930cecf9d5Sandi ); 8940cecf9d5Sandi } 8950cecf9d5Sandi 896107b01d6Sandi function getSort() { 897107b01d6Sandi return 290; 898107b01d6Sandi } 8990cecf9d5Sandi} 9000cecf9d5Sandi 9010cecf9d5Sandi//------------------------------------------------------------------- 902107b01d6Sandiclass Doku_Parser_Mode_internallink extends Doku_Parser_Mode { 9030cecf9d5Sandi 9040cecf9d5Sandi function connectTo($mode) { 9050cecf9d5Sandi // Word boundaries? 90645a0fa15SAdrian Lang $this->Lexer->addSpecialPattern("\[\[(?:(?:[^[\]]*?\[.*?\])|.*?)\]\]",$mode,'internallink'); 9070cecf9d5Sandi } 9080cecf9d5Sandi 909107b01d6Sandi function getSort() { 910107b01d6Sandi return 300; 911107b01d6Sandi } 9120cecf9d5Sandi} 9130cecf9d5Sandi 9140cecf9d5Sandi//------------------------------------------------------------------- 915107b01d6Sandiclass Doku_Parser_Mode_media extends Doku_Parser_Mode { 9160cecf9d5Sandi 9170cecf9d5Sandi function connectTo($mode) { 9180cecf9d5Sandi // Word boundaries? 9190cecf9d5Sandi $this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'media'); 9200cecf9d5Sandi } 9210cecf9d5Sandi 922107b01d6Sandi function getSort() { 923107b01d6Sandi return 320; 924107b01d6Sandi } 9250cecf9d5Sandi} 9260cecf9d5Sandi 9270cecf9d5Sandi//------------------------------------------------------------------- 928107b01d6Sandiclass Doku_Parser_Mode_rss extends Doku_Parser_Mode { 929b625487dSandi 930b625487dSandi function connectTo($mode) { 931b625487dSandi $this->Lexer->addSpecialPattern("\{\{rss>[^\}]+\}\}",$mode,'rss'); 932b625487dSandi } 933b625487dSandi 934107b01d6Sandi function getSort() { 935107b01d6Sandi return 310; 936107b01d6Sandi } 937b625487dSandi} 938b625487dSandi 939b625487dSandi//------------------------------------------------------------------- 940107b01d6Sandiclass Doku_Parser_Mode_externallink extends Doku_Parser_Mode { 94136f2d7c1SGina Haeussge var $schemes = array(); 9420cecf9d5Sandi var $patterns = array(); 9430cecf9d5Sandi 9440cecf9d5Sandi function preConnect() { 945d4834a19SStephane Chazelas if(count($this->patterns)) return; 9460cecf9d5Sandi 9470cecf9d5Sandi $ltrs = '\w'; 9485d190f12SAndreas Gohr $gunk = '/\#~:.?+=&%@!\-\[\]'; 9490cecf9d5Sandi $punc = '.:?\-;,'; 9500cecf9d5Sandi $host = $ltrs.$punc; 9510cecf9d5Sandi $any = $ltrs.$gunk.$punc; 9520cecf9d5Sandi 95336f2d7c1SGina Haeussge $this->schemes = getSchemes(); 9540cecf9d5Sandi foreach ( $this->schemes as $scheme ) { 9556f0c5dbfSandi $this->patterns[] = '\b(?i)'.$scheme.'(?-i)://['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; 9560cecf9d5Sandi } 9570cecf9d5Sandi 9586f0c5dbfSandi $this->patterns[] = '\b(?i)www?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; 9596f0c5dbfSandi $this->patterns[] = '\b(?i)ftp?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; 9600cecf9d5Sandi } 9610cecf9d5Sandi 9620cecf9d5Sandi function connectTo($mode) { 963d4834a19SStephane Chazelas 9640cecf9d5Sandi foreach ( $this->patterns as $pattern ) { 9650cecf9d5Sandi $this->Lexer->addSpecialPattern($pattern,$mode,'externallink'); 9660cecf9d5Sandi } 9670cecf9d5Sandi } 9680cecf9d5Sandi 969107b01d6Sandi function getSort() { 970107b01d6Sandi return 330; 971107b01d6Sandi } 9720cecf9d5Sandi} 9730cecf9d5Sandi 9740cecf9d5Sandi//------------------------------------------------------------------- 975107b01d6Sandiclass Doku_Parser_Mode_filelink extends Doku_Parser_Mode { 9760cecf9d5Sandi 9770cecf9d5Sandi var $pattern; 9780cecf9d5Sandi 9790cecf9d5Sandi function preConnect() { 9800cecf9d5Sandi 9810cecf9d5Sandi $ltrs = '\w'; 9820cecf9d5Sandi $gunk = '/\#~:.?+=&%@!\-'; 9830cecf9d5Sandi $punc = '.:?\-;,'; 9840cecf9d5Sandi $host = $ltrs.$punc; 9850cecf9d5Sandi $any = $ltrs.$gunk.$punc; 9860cecf9d5Sandi 9870cecf9d5Sandi $this->pattern = '\b(?i)file(?-i)://['.$any.']+?['. 9880cecf9d5Sandi $punc.']*[^'.$any.']'; 9890cecf9d5Sandi } 9900cecf9d5Sandi 9910cecf9d5Sandi function connectTo($mode) { 9920cecf9d5Sandi $this->Lexer->addSpecialPattern( 9930cecf9d5Sandi $this->pattern,$mode,'filelink'); 9940cecf9d5Sandi } 9950cecf9d5Sandi 996107b01d6Sandi function getSort() { 997107b01d6Sandi return 360; 998107b01d6Sandi } 9990cecf9d5Sandi} 10000cecf9d5Sandi 10010cecf9d5Sandi//------------------------------------------------------------------- 1002107b01d6Sandiclass Doku_Parser_Mode_windowssharelink extends Doku_Parser_Mode { 10030cecf9d5Sandi 10040cecf9d5Sandi var $pattern; 10050cecf9d5Sandi 10060cecf9d5Sandi function preConnect() { 1007bfdeb23fSlupo49 $this->pattern = "\\\\\\\\\w+?(?:\\\\[\w-$]+)+"; 10080cecf9d5Sandi } 10090cecf9d5Sandi 10100cecf9d5Sandi function connectTo($mode) { 10110cecf9d5Sandi $this->Lexer->addSpecialPattern( 10120cecf9d5Sandi $this->pattern,$mode,'windowssharelink'); 10130cecf9d5Sandi } 10140cecf9d5Sandi 1015107b01d6Sandi function getSort() { 1016107b01d6Sandi return 350; 1017107b01d6Sandi } 10180cecf9d5Sandi} 10190cecf9d5Sandi 10200cecf9d5Sandi//------------------------------------------------------------------- 1021107b01d6Sandiclass Doku_Parser_Mode_emaillink extends Doku_Parser_Mode { 10220cecf9d5Sandi 10230cecf9d5Sandi function connectTo($mode) { 10240a1d30bfSchris // pattern below is defined in inc/mail.php 10250a1d30bfSchris $this->Lexer->addSpecialPattern('<'.PREG_PATTERN_VALID_EMAIL.'>',$mode,'emaillink'); 10260cecf9d5Sandi } 10270cecf9d5Sandi 1028107b01d6Sandi function getSort() { 1029107b01d6Sandi return 340; 1030107b01d6Sandi } 10310cecf9d5Sandi} 10320cecf9d5Sandi 1033340756e4Sandi 1034e3776c06SMichael Hamann//Setup VIM: ex: et ts=4 : 1035