1<?php 2/** 3 * Plugin relativens: Links & media that don't start with / or : default 4 * to being relative to the namespace in which the current page is. 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Peter Lamberg (pe78 [at] lodju.dyndns dot org) 8 * @based_on "pagespace" plugin by Symon Bent and "baselink" plugin Robert Meerman. Contains portion of code from dokuwiki source file handler.php. 9 */ 10 11if(!defined('DOKU_INC')) die(); 12 13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 14require_once(DOKU_PLUGIN.'syntax.php'); 15 16class syntax_plugin_relativens extends DokuWiki_Syntax_Plugin { 17 18 function getInfo() { 19 return array('author' => 'Peter Lamberg', 20 'email' => 'pe78 [at] lodju.dyndns dot org', 21 'date' => '2008-12-30', 22 'name' => 'relativens', 23 'desc' => "Plugin relativens: Links & media that don't start with / or : default to being relative to the namespace in which the current page is.", 24 'url' => 'http://www.dokuwiki.org/plugin:relativens'); 25 } 26 27 function getType() { 28 return 'substition'; 29 } 30 31 // before built in links & media 32 function getSort(){ return 299; } 33 34 function connectTo($mode) { 35 $this->Lexer->addSpecialPattern("\[\[.+?\]\]",$mode,'plugin_relativens'); 36 $this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'plugin_relativens'); 37 } 38 39 function handle($match, $state, $pos, &$handler) { 40 // Following link parsing code is originally copied from Dokuwiki handler.php 41 42 // See which one we caught 43 $isMedia = preg_match('/^\{\{/', $link); 44 45 $isMedia = 0; 46 47 $originalMatch = $match; 48 49 // Strip the opening and closing markup 50 // At same time detect if this is media or link 51 // handler.media and handler.internallink do this too, but 52 // they don't check if they replaced anything. 53 $match = preg_replace(array('/^\{\{/','/\}\}$/u'),'',$match, 2, $isMedia); 54 $match = preg_replace(array('/^\[\[/','/\]\]$/u'),'',$match, 2); 55 56 // Split title from URL 57 $linkAndTitle = preg_split('/\|/u',$match,2); 58 $linkTrimmed = trim($linkAndTitle[0]); 59 60 $modifiedMatch = $originalMatch; 61 62 // Give special treatment to the first few characters 63 // of internal links and media links (media links are always "internal"?). 64 // Sadly excluding the non internal links is a complicated process 65 // and we end up doing it twice, but at least the results of these 66 // handle functions are cached. 67 if($isMedia || $this->isLinkInternal($linkTrimmed)) { 68 // unless it's explicitly absolute, 69 // Make it look like relative 70 $modifiedMatch = preg_replace('/(^(?:\[\[|\{\{)\s*)(?![\:\/])/', '\\1./', $modifiedMatch, 1); 71 } 72 // let the regular handler take care of the rest 73 if($isMedia) { 74 $handler->media($modifiedMatch, $state, $pos); 75 } 76 else 77 { 78 $handler->internallink($modifiedMatch, $state, $pos); 79 } 80 } 81 82 function isLinkInternal($linkPart) { 83 // If conditions copied from Dokuwiki handler.php 84 if ( preg_match('/^[a-zA-Z\.]+>{1}.*$/u',$linkPart) ) { 85 return false; 86 }elseif ( preg_match('/^\\\\\\\\[\w.:?\-;,]+?\\\\/u',$linkPart) ) { 87 return false; 88 }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$linkPart) ) { 89 return false; 90 }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$linkPart) ) { 91 return false; 92 }elseif ( preg_match('!^#.+!',$linkPart) ) { 93 return false; 94 }else{ 95 return true; 96 } 97 } 98 99 function render($mode, &$renderer, $data) { 100 // Should never come here, since we leech the original handler for most processing 101 return false; 102 } 103 104} 105 106 107