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