1<?php 2 3if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 4 5require_once DOKU_INC . 'inc/parser/lexer.php'; 6require_once DOKU_INC . 'inc/parser/handler.php'; 7 8 9/** 10 * Define various types of modes used by the parser - they are used to 11 * populate the list of modes another mode accepts 12 */ 13global $PARSER_MODES; 14$PARSER_MODES = array( 15 // containers are complex modes that can contain many other modes 16 // hr breaks the principle but they shouldn't be used in tables / lists 17 // so they are put here 18 'container' => array('listblock','table','quote','hr'), 19 20 // some mode are allowed inside the base mode only 21 'baseonly' => array('header'), 22 23 // modes for styling text -- footnote behaves similar to styling 24 'formatting' => array('strong', 'emphasis', 'underline', 'monospace', 25 'subscript', 'superscript', 'deleted', 'footnote'), 26 27 // modes where the token is simply replaced - they can not contain any 28 // other modes 29 'substition' => array('acronym','smiley','wordblock','entity', 30 'camelcaselink', 'internallink','media', 31 'externallink','linebreak','emaillink', 32 'windowssharelink','filelink','notoc', 33 'nocache','multiplyentity','quotes','rss'), 34 35 // modes which have a start and end token but inside which 36 // no other modes should be applied 37 'protected' => array('preformatted','code','file','php','html'), 38 39 // inside this mode no wiki markup should be applied but lineendings 40 // and whitespace isn't preserved 41 'disabled' => array('unformatted'), 42 43 // used to mark paragraph boundaries 44 'paragraphs' => array('eol') 45); 46 47//------------------------------------------------------------------- 48 49/** 50* Sets up the Lexer with modes and points it to the Handler 51* For an intro to the Lexer see: wiki:parser 52*/ 53class Doku_Parser { 54 55 var $Handler; 56 57 var $Lexer; 58 59 var $modes = array(); 60 61 var $connected = FALSE; 62 63 function addBaseMode(& $BaseMode) { 64 $this->modes['base'] = & $BaseMode; 65 if ( !$this->Lexer ) { 66 $this->Lexer = & new Doku_Lexer($this->Handler,'base', TRUE); 67 } 68 $this->modes['base']->Lexer = & $this->Lexer; 69 } 70 71 /** 72 * PHP preserves order of associative elements 73 * Mode sequence is important 74 */ 75 function addMode($name, & $Mode) { 76 if ( !isset($this->modes['base']) ) { 77 $this->addBaseMode(new Doku_Parser_Mode_Base()); 78 } 79 $Mode->Lexer = & $this->Lexer; 80 $this->modes[$name] = & $Mode; 81 } 82 83 function connectModes() { 84 85 if ( $this->connected ) { 86 return; 87 } 88 89 foreach ( array_keys($this->modes) as $mode ) { 90 91 // Base isn't connected to anything 92 if ( $mode == 'base' ) { 93 continue; 94 } 95 96 $this->modes[$mode]->preConnect(); 97 98 foreach ( array_keys($this->modes) as $cm ) { 99 100 if ( $this->modes[$cm]->accepts($mode) ) { 101 $this->modes[$mode]->connectTo($cm); 102 } 103 104 } 105 106 $this->modes[$mode]->postConnect(); 107 } 108 109 $this->connected = TRUE; 110 } 111 112 function parse($doc) { 113 if ( $this->Lexer ) { 114 $this->connectModes(); 115 // Normalize CRs and pad doc 116 $doc = "\n".str_replace("\r\n","\n",$doc)."\n"; 117 $this->Lexer->parse($doc); 118 $this->Handler->_finalize(); 119 return $this->Handler->calls; 120 } else { 121 return FALSE; 122 } 123 } 124 125} 126 127//------------------------------------------------------------------- 128/** 129 * This class and all the subclasses below are 130 * used to reduce the effort required to register 131 * modes with the Lexer. For performance these 132 * could all be eliminated later perhaps, or 133 * the Parser could be serialized to a file once 134 * all modes are registered 135 * 136 * @author Harry Fuecks <hfuecks@gmail.com> 137*/ 138class Doku_Parser_Mode { 139 140 var $Lexer; 141 142 var $allowedModes = array(); 143 144 // Called before any calls to connectTo 145 function preConnect() {} 146 147 function connectTo($mode) {} 148 149 // Called after all calls to connectTo 150 function postConnect() {} 151 152 function accepts($mode) { 153 return in_array($mode, $this->allowedModes ); 154 } 155 156} 157 158//------------------------------------------------------------------- 159class Doku_Parser_Mode_Base extends Doku_Parser_Mode { 160 161 function Doku_Parser_Mode_Base() { 162 global $PARSER_MODES; 163 164 $this->allowedModes = array_merge ( 165 $PARSER_MODES['container'], 166 $PARSER_MODES['baseonly'], 167 $PARSER_MODES['paragraphs'], 168 $PARSER_MODES['formatting'], 169 $PARSER_MODES['substition'], 170 $PARSER_MODES['protected'], 171 $PARSER_MODES['disabled'] 172 ); 173 } 174} 175 176//------------------------------------------------------------------- 177class Doku_Parser_Mode_Footnote extends Doku_Parser_Mode { 178 179 function Doku_Parser_Mode_Footnote() { 180 global $PARSER_MODES; 181 182 $this->allowedModes = array_merge ( 183 $PARSER_MODES['container'], 184 $PARSER_MODES['formatting'], 185 $PARSER_MODES['substition'], 186 $PARSER_MODES['protected'], 187 $PARSER_MODES['disabled'] 188 ); 189 190 } 191 192 function connectTo($mode) { 193 $this->Lexer->addEntryPattern( 194 '\x28\x28(?=.*\x29\x29)',$mode,'footnote' 195 ); 196 } 197 198 function postConnect() { 199 $this->Lexer->addExitPattern( 200 '\x29\x29','footnote' 201 ); 202 203 } 204 205} 206 207//------------------------------------------------------------------- 208class Doku_Parser_Mode_Header extends Doku_Parser_Mode { 209 210 function preConnect() { 211 //we're not picky about the closing ones, two are enough 212 213 // Header 1 is special case - match 6 or more 214 $this->Lexer->addSpecialPattern( 215 '[ \t]*={6,}[^\n]+={2,}[ \t]*(?=\n)', 216 'base', 217 'header' 218 ); 219 220 // For the rest, match exactly 221 for ( $i = 5; $i > 1; $i--) { 222 $this->Lexer->addSpecialPattern( 223 '[ \t]*={'.$i.'}[^\n]+={2,}[ \t]*(?=\n)', 224 'base', 225 'header' 226 ); 227 } 228 } 229 230} 231 232//------------------------------------------------------------------- 233class Doku_Parser_Mode_NoToc extends Doku_Parser_Mode { 234 235 function connectTo($mode) { 236 $this->Lexer->addSpecialPattern('~~NOTOC~~',$mode,'notoc'); 237 } 238 239} 240 241//------------------------------------------------------------------- 242class Doku_Parser_Mode_NoCache extends Doku_Parser_Mode { 243 244 function connectTo($mode) { 245 $this->Lexer->addSpecialPattern('~~NOCACHE~~',$mode,'nocache'); 246 } 247 248} 249 250//------------------------------------------------------------------- 251class Doku_Parser_Mode_Linebreak extends Doku_Parser_Mode { 252 253 function connectTo($mode) { 254 $this->Lexer->addSpecialPattern('\x5C{2}(?=\s)',$mode,'linebreak'); 255 } 256} 257 258//------------------------------------------------------------------- 259class Doku_Parser_Mode_Eol extends Doku_Parser_Mode { 260 261 function connectTo($mode) { 262 $badModes = array('listblock','table'); 263 if ( in_array($mode, $badModes) ) { 264 return; 265 } 266 $this->Lexer->addSpecialPattern('\n',$mode,'eol'); 267 } 268} 269 270//------------------------------------------------------------------- 271class Doku_Parser_Mode_HR extends Doku_Parser_Mode { 272 273 function connectTo($mode) { 274 $this->Lexer->addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr'); 275 } 276 277} 278 279//------------------------------------------------------------------- 280class Doku_Parser_Mode_Formatting extends Doku_Parser_Mode { 281 var $type; 282 283 var $formatting = array ( 284 'strong' => array ( 285 'entry'=>'\*\*(?=.*\*\*)', 286 'exit'=>'\*\*', 287 ), 288 289 'emphasis'=> array ( 290 'entry'=>'//(?=.*//)', 291 'exit'=>'//', 292 ), 293 294 'underline'=> array ( 295 'entry'=>'__(?=.*__)', 296 'exit'=>'__', 297 ), 298 299 'monospace'=> array ( 300 'entry'=>'\x27\x27(?=.*\x27\x27)', 301 'exit'=>'\x27\x27', 302 ), 303 304 'subscript'=> array ( 305 'entry'=>'<sub>(?=.*\x3C/sub\x3E)', 306 'exit'=>'</sub>', 307 ), 308 309 'superscript'=> array ( 310 'entry'=>'<sup>(?=.*\x3C/sup\x3E)', 311 'exit'=>'</sup>', 312 ), 313 314 'deleted'=> array ( 315 'entry'=>'<del>(?=.*\x3C/del\x3E)', 316 'exit'=>'</del>', 317 ), 318 ); 319 320 function Doku_Parser_Mode_Formatting($type) { 321 global $PARSER_MODES; 322 323 if ( !array_key_exists($type, $this->formatting) ) { 324 trigger_error('Invalid formatting type '.$type, E_USER_WARNING); 325 } 326 327 $this->type = $type; 328 329 // formatting may contain other formatting but not it self 330 $modes = $PARSER_MODES['formatting']; 331 $key = array_search($type, $modes); 332 if ( is_int($key) ) { 333 unset($modes[$key]); 334 } 335 336 $this->allowedModes = array_merge ( 337 $modes, 338 $PARSER_MODES['substition'], 339 $PARSER_MODES['disabled'] 340 ); 341 } 342 343 function connectTo($mode) { 344 345 // Can't nest formatting in itself 346 if ( $mode == $this->type ) { 347 return; 348 } 349 350 $this->Lexer->addEntryPattern( 351 $this->formatting[$this->type]['entry'], 352 $mode, 353 $this->type 354 ); 355 } 356 357 function postConnect() { 358 359 $this->Lexer->addExitPattern( 360 $this->formatting[$this->type]['exit'], 361 $this->type 362 ); 363 364 } 365} 366 367//------------------------------------------------------------------- 368class Doku_Parser_Mode_ListBlock extends Doku_Parser_Mode { 369 370 function Doku_Parser_Mode_ListBlock() { 371 global $PARSER_MODES; 372 373 $this->allowedModes = array_merge ( 374 $PARSER_MODES['formatting'], 375 $PARSER_MODES['substition'], 376 $PARSER_MODES['disabled'], 377 $PARSER_MODES['protected'] #XXX new 378 ); 379 380 // $this->allowedModes[] = 'footnote'; 381 } 382 383 function connectTo($mode) { 384 $this->Lexer->addEntryPattern('\n {2,}[\-\*]',$mode,'listblock'); 385 $this->Lexer->addEntryPattern('\n\t{1,}[\-\*]',$mode,'listblock'); 386 387 $this->Lexer->addPattern('\n {2,}[\-\*]','listblock'); 388 $this->Lexer->addPattern('\n\t{1,}[\-\*]','listblock'); 389 390 } 391 392 function postConnect() { 393 $this->Lexer->addExitPattern('\n','listblock'); 394 } 395} 396 397//------------------------------------------------------------------- 398class Doku_Parser_Mode_Table extends Doku_Parser_Mode { 399 400 function Doku_Parser_Mode_Table() { 401 global $PARSER_MODES; 402 403 $this->allowedModes = array_merge ( 404 $PARSER_MODES['formatting'], 405 $PARSER_MODES['substition'], 406 $PARSER_MODES['disabled'], 407 $PARSER_MODES['protected'] #XXX new 408 ); 409 #$this->allowedModes[] = 'footnote'; 410 #$this->allowedModes[] = 'preformatted'; 411 #$this->allowedModes[] = 'unformatted'; 412 } 413 414 function connectTo($mode) { 415 $this->Lexer->addEntryPattern('\n\^',$mode,'table'); 416 $this->Lexer->addEntryPattern('\n\|',$mode,'table'); 417 } 418 419 function postConnect() { 420 $this->Lexer->addPattern('\n\^','table'); 421 $this->Lexer->addPattern('\n\|','table'); 422 $this->Lexer->addPattern(' {2,}','table'); 423 $this->Lexer->addPattern('\^','table'); 424 $this->Lexer->addPattern('\|','table'); 425 $this->Lexer->addExitPattern('\n','table'); 426 } 427} 428 429//------------------------------------------------------------------- 430class Doku_Parser_Mode_Unformatted extends Doku_Parser_Mode { 431 432 function connectTo($mode) { 433 $this->Lexer->addEntryPattern('<nowiki>(?=.*\x3C/nowiki\x3E)',$mode,'unformatted'); 434 $this->Lexer->addEntryPattern('%%(?=.*%%)',$mode,'unformattedalt'); 435 } 436 437 function postConnect() { 438 $this->Lexer->addExitPattern('</nowiki>','unformatted'); 439 $this->Lexer->addExitPattern('%%','unformattedalt'); 440 $this->Lexer->mapHandler('unformattedalt','unformatted'); 441 } 442 443} 444 445//------------------------------------------------------------------- 446class Doku_Parser_Mode_PHP extends Doku_Parser_Mode { 447 448 function connectTo($mode) { 449 $this->Lexer->addEntryPattern('<php>(?=.*\x3C/php\x3E)',$mode,'php'); 450 } 451 452 function postConnect() { 453 $this->Lexer->addExitPattern('</php>','php'); 454 } 455 456} 457 458//------------------------------------------------------------------- 459class Doku_Parser_Mode_HTML extends Doku_Parser_Mode { 460 461 function connectTo($mode) { 462 $this->Lexer->addEntryPattern('<html>(?=.*\x3C/html\x3E)',$mode,'html'); 463 } 464 465 function postConnect() { 466 $this->Lexer->addExitPattern('</html>','html'); 467 } 468 469} 470 471//------------------------------------------------------------------- 472class Doku_Parser_Mode_Preformatted extends Doku_Parser_Mode { 473 474 function connectTo($mode) { 475 // Has hard coded awareness of lists... 476 $this->Lexer->addEntryPattern('\n (?![\*\-])',$mode,'preformatted'); 477 $this->Lexer->addEntryPattern('\n\t(?![\*\-])',$mode,'preformatted'); 478 479 // How to effect a sub pattern with the Lexer! 480 $this->Lexer->addPattern('\n ','preformatted'); 481 $this->Lexer->addPattern('\n\t','preformatted'); 482 483 } 484 485 function postConnect() { 486 $this->Lexer->addExitPattern('\n','preformatted'); 487 } 488 489} 490 491//------------------------------------------------------------------- 492class Doku_Parser_Mode_Code extends Doku_Parser_Mode { 493 494 function connectTo($mode) { 495 $this->Lexer->addEntryPattern('<code(?=.*\x3C/code\x3E)',$mode,'code'); 496 } 497 498 function postConnect() { 499 $this->Lexer->addExitPattern('</code>','code'); 500 } 501 502} 503 504//------------------------------------------------------------------- 505class Doku_Parser_Mode_File extends Doku_Parser_Mode { 506 507 function connectTo($mode) { 508 $this->Lexer->addEntryPattern('<file>(?=.*\x3C/file\x3E)',$mode,'file'); 509 } 510 511 function postConnect() { 512 $this->Lexer->addExitPattern('</file>','file'); 513 } 514 515} 516 517//------------------------------------------------------------------- 518class Doku_Parser_Mode_Quote extends Doku_Parser_Mode { 519 520 function Doku_Parser_Mode_Quote() { 521 global $PARSER_MODES; 522 523 $this->allowedModes = array_merge ( 524 $PARSER_MODES['formatting'], 525 $PARSER_MODES['substition'], 526 $PARSER_MODES['disabled'], 527 $PARSER_MODES['protected'] #XXX new 528 ); 529 #$this->allowedModes[] = 'footnote'; 530 #$this->allowedModes[] = 'preformatted'; 531 #$this->allowedModes[] = 'unformatted'; 532 } 533 534 function connectTo($mode) { 535 $this->Lexer->addEntryPattern('\n>{1,}',$mode,'quote'); 536 } 537 538 function postConnect() { 539 $this->Lexer->addPattern('\n>{1,}','quote'); 540 $this->Lexer->addExitPattern('\n','quote'); 541 } 542 543} 544 545//------------------------------------------------------------------- 546class Doku_Parser_Mode_Acronym extends Doku_Parser_Mode { 547 // A list 548 var $acronyms = array(); 549 var $pattern = ''; 550 551 function Doku_Parser_Mode_Acronym($acronyms) { 552 $this->acronyms = $acronyms; 553 } 554 555 function preConnect() { 556 $sep = ''; 557 foreach ( $this->acronyms as $acronym ) { 558 $this->pattern .= $sep.'(?<=\b)'.Doku_Lexer_Escape($acronym).'(?=\b)'; 559 $sep = '|'; 560 } 561 } 562 563 function connectTo($mode) { 564 if ( strlen($this->pattern) > 0 ) { 565 $this->Lexer->addSpecialPattern($this->pattern,$mode,'acronym'); 566 } 567 } 568 569} 570 571//------------------------------------------------------------------- 572class Doku_Parser_Mode_Smiley extends Doku_Parser_Mode { 573 // A list 574 var $smileys = array(); 575 var $pattern = ''; 576 577 function Doku_Parser_Mode_Smiley($smileys) { 578 $this->smileys = $smileys; 579 } 580 581 function preConnect() { 582 $sep = ''; 583 foreach ( $this->smileys as $smiley ) { 584 $this->pattern .= $sep.Doku_Lexer_Escape($smiley); 585 $sep = '|'; 586 } 587 } 588 589 function connectTo($mode) { 590 if ( strlen($this->pattern) > 0 ) { 591 $this->Lexer->addSpecialPattern($this->pattern,$mode,'smiley'); 592 } 593 } 594 595} 596 597//------------------------------------------------------------------- 598class Doku_Parser_Mode_Wordblock extends Doku_Parser_Mode { 599 // A list 600 var $badwords = array(); 601 var $pattern = ''; 602 603 function Doku_Parser_Mode_Wordblock($badwords) { 604 $this->badwords = $badwords; 605 } 606 607 function preConnect() { 608 609 if ( count($this->badwords) == 0 ) { 610 return; 611 } 612 613 $sep = ''; 614 foreach ( $this->badwords as $badword ) { 615 $this->pattern .= $sep.'(?<=\b)(?i)'.Doku_Lexer_Escape($badword).'(?-i)(?=\b)'; 616 $sep = '|'; 617 } 618 619 } 620 621 function connectTo($mode) { 622 if ( strlen($this->pattern) > 0 ) { 623 $this->Lexer->addSpecialPattern($this->pattern,$mode,'wordblock'); 624 } 625 } 626 627} 628 629//------------------------------------------------------------------- 630/** 631* @TODO Quotes and 640x480 are not supported - just straight replacements here 632*/ 633class Doku_Parser_Mode_Entity extends Doku_Parser_Mode { 634 // A list 635 var $entities = array(); 636 var $pattern = ''; 637 638 function Doku_Parser_Mode_Entity($entities) { 639 $this->entities = $entities; 640 } 641 642 function preConnect() { 643 $sep = ''; 644 foreach ( $this->entities as $entity ) { 645 $this->pattern .= $sep.Doku_Lexer_Escape($entity); 646 $sep = '|'; 647 } 648 } 649 650 function connectTo($mode) { 651 if ( strlen($this->pattern) > 0 ) { 652 $this->Lexer->addSpecialPattern($this->pattern,$mode,'entity'); 653 } 654 } 655 656} 657 658//------------------------------------------------------------------- 659// Implements the 640x480 replacement 660class Doku_Parser_Mode_MultiplyEntity extends Doku_Parser_Mode { 661 662 function connectTo($mode) { 663 664 $this->Lexer->addSpecialPattern( 665 '(?<=\b)\d+[x|X]\d+(?=\b)',$mode,'multiplyentity' 666 ); 667 668 } 669 670} 671 672//------------------------------------------------------------------- 673class Doku_Parser_Mode_Quotes extends Doku_Parser_Mode { 674 675 function connectTo($mode) { 676 677 $this->Lexer->addSpecialPattern( 678 '(?<=\s)\'(?=\S)',$mode,'singlequoteopening' 679 ); 680 $this->Lexer->addSpecialPattern( 681 '(?<=^|\S)\'',$mode,'singlequoteclosing' 682 ); 683 $this->Lexer->addSpecialPattern( 684 '(?<=^|\s)"(?=\S)',$mode,'doublequoteopening' 685 ); 686 $this->Lexer->addSpecialPattern( 687 '(?<=\S)"',$mode,'doublequoteclosing' 688 ); 689 690 } 691 692} 693 694//------------------------------------------------------------------- 695class Doku_Parser_Mode_CamelCaseLink extends Doku_Parser_Mode { 696 697 function connectTo($mode) { 698 $this->Lexer->addSpecialPattern( 699 '\b[A-Z]+[a-z]+[A-Z][A-Za-z]*\b',$mode,'camelcaselink' 700 ); 701 } 702 703} 704 705//------------------------------------------------------------------- 706class Doku_Parser_Mode_InternalLink extends Doku_Parser_Mode { 707 708 function connectTo($mode) { 709 // Word boundaries? 710 $this->Lexer->addSpecialPattern("\[\[.+?\]\]",$mode,'internallink'); 711 } 712 713} 714 715//------------------------------------------------------------------- 716class Doku_Parser_Mode_Media extends Doku_Parser_Mode { 717 718 function connectTo($mode) { 719 // Word boundaries? 720 $this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'media'); 721 } 722 723} 724 725//------------------------------------------------------------------- 726class Doku_Parser_Mode_RSS extends Doku_Parser_Mode { 727 728 function connectTo($mode) { 729 $this->Lexer->addSpecialPattern("\{\{rss>[^\}]+\}\}",$mode,'rss'); 730 } 731 732} 733 734//------------------------------------------------------------------- 735class Doku_Parser_Mode_ExternalLink extends Doku_Parser_Mode { 736 var $schemes = array('http','https','telnet','gopher','wais','ftp','ed2k','irc'); 737 var $patterns = array(); 738 739 function preConnect() { 740 741 $ltrs = '\w'; 742 $gunk = '/\#~:.?+=&%@!\-'; 743 $punc = '.:?\-;,'; 744 $host = $ltrs.$punc; 745 $any = $ltrs.$gunk.$punc; 746 747 foreach ( $this->schemes as $scheme ) { 748 $this->patterns[] = '\b(?i)'.$scheme.'(?-i)://['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; 749 } 750 751 $this->patterns[] = '\b(?i)www?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; 752 $this->patterns[] = '\b(?i)ftp?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])'; 753 754 } 755 756 function connectTo($mode) { 757 foreach ( $this->patterns as $pattern ) { 758 $this->Lexer->addSpecialPattern($pattern,$mode,'externallink'); 759 } 760 } 761 762} 763 764//------------------------------------------------------------------- 765class Doku_Parser_Mode_FileLink extends Doku_Parser_Mode { 766 767 var $pattern; 768 769 function preConnect() { 770 771 $ltrs = '\w'; 772 $gunk = '/\#~:.?+=&%@!\-'; 773 $punc = '.:?\-;,'; 774 $host = $ltrs.$punc; 775 $any = $ltrs.$gunk.$punc; 776 777 $this->pattern = '\b(?i)file(?-i)://['.$any.']+?['. 778 $punc.']*[^'.$any.']'; 779 } 780 781 function connectTo($mode) { 782 $this->Lexer->addSpecialPattern( 783 $this->pattern,$mode,'filelink'); 784 } 785 786 787} 788 789//------------------------------------------------------------------- 790class Doku_Parser_Mode_WindowsShareLink extends Doku_Parser_Mode { 791 792 var $pattern; 793 794 function preConnect() { 795 796 $ltrs = '\w'; 797 $gunk = '/\#~:.?+=&%@!\-'; 798 $punc = '.:?\-;,'; 799 $host = $ltrs.$punc; 800 $any = $ltrs.$gunk.$punc; 801 802 $this->pattern = "[$gunk$punc\s]\\\\\\\\[$host]+?\\\\[$any]+?(?=['.$punc.']*[^'.$any.'])"; 803 } 804 805 function connectTo($mode) { 806 $this->Lexer->addSpecialPattern( 807 $this->pattern,$mode,'windowssharelink'); 808 } 809 810 811} 812 813//------------------------------------------------------------------- 814class Doku_Parser_Mode_EmailLink extends Doku_Parser_Mode { 815 816 function connectTo($mode) { 817 //<([\w0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)> 818 $this->Lexer->addSpecialPattern("<[\w0-9\-_.]+?@[\w\-]+\.[\w\-\.]+\.*[\w]+>",$mode,'emaillink'); 819 } 820 821} 822 823//------------------------------------------------------------------- 824// 825// XXX deprecated - replace by $PARSER_MODES 826// 827// Help fns to keep mode lists - used to make it easier to populate 828// the list of modes another mode accepts 829 830/* 831 832// Can contain many other modes 833// E.g. a footnote can containing formatting etc. 834function Doku_Parser_BlockContainers() { 835 $modes = array( 836 'footnote', 'listblock', 'table','quote', 837 // hr breaks the principle but HRs should not be used in tables / lists 838 // so put it here 839 'hr', 840 ); 841 return $modes; 842} 843 844// Used to mark paragraph boundaries 845function Doku_Parser_Paragraphs() { 846 $modes = array( 847 'eol' 848 ); 849 return $modes; 850} 851 852// Can only be used by the base mode 853function Doku_Parser_BaseOnly() { 854 $modes = array( 855 'header' 856 ); 857 return $modes; 858} 859 860// "Styling" modes that format text. 861function Doku_Parser_Formatting($remove = '') { 862 $modes = array( 863 'strong', 'emphasis', 'underline', 'monospace', 864 'subscript', 'superscript', 'deleted', 865 ); 866 $key = array_search($remove, $modes); 867 if ( is_int($key) ) { 868 unset($modes[$key]); 869 } 870 871 return $modes; 872} 873 874// Modes where the token is simply replaced - contain no 875// other modes 876function Doku_Parser_Substition() { 877 $modes = array( 878 'acronym','smiley','wordblock','entity','camelcaselink', 879 'internallink','media','externallink','linebreak','emaillink', 880 'windowssharelink','filelink','notoc','nocache','multiplyentity', 881 'quotes','rss', 882 ); 883 return $modes; 884} 885 886// Modes which have a start and end token but inside which 887// no other modes should be applied 888function Doku_Parser_Protected() { 889 $modes = array( 890 'preformatted','code','file', 891 'php','html','quote', 892 ); 893 return $modes; 894} 895 896// Disable wiki markup inside this mode 897function Doku_Parser_Disabled() { 898 $modes = array( 899 'unformatted' 900 ); 901 return $modes; 902} 903*/ 904 905// -------------------------------------------------------------------------- 906 907//Setup VIM: ex: et ts=4 enc=utf-8 : 908