1<?php 2 3/** 4 * This plugin allows to insert a section of a page 5 * The section can be shown in different ways: 6 * 1. The section is shown as it is like a simple include 7 * 2. The first link in the section is shown (direct or with the parameters used) 8 * 3. The text before an after the link is shown as a footnote or plain text or not 9 * It can be used to reference one link or text on multiple pages 10 * It is usefull to reference to one links that are often updatet 11 * 12 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 13 * @author Dietrich Wittenberg <info.wittenberg@online.de> 14 */ 15 16// must be run within Dokuwiki 17//if(!defined('DOKU_INC')) die(); 18 19if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 20if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 21require_once(DOKU_PLUGIN.'syntax.php'); 22require_once (DWTOOLS.'lib.php'); 23 24function _getFN($ns, $file){ 25 26 // check for wiki page = $ns:$file (or $file where no namespace) 27 $nsFile = ($ns) ? "$ns:$file" : $file; 28 if (@file_exists(wikiFN($nsFile)) && auth_quickaclcheck($nsFile)) return $nsFile; 29 // no namespace left, exit with no file found 30 if (!$ns) return ''; 31 // remove deepest namespace level and call function recursively 32 $i = strrpos($ns, ":"); 33 $ns = ($i) ? substr($ns, 0, $i) : false; 34 return _getFN($ns, $file); 35} 36 37// defaults to the root linkfile: links 38function _get_linkfile($file_ns, $file) { 39 global $ID; 40 // discover file containing the links 41 $file_ns = ($file_ns == "") ? getNS($ID) : $file_ns; 42 $linksfile = _getFN($file_ns, $file); 43 if ($linksfile != "") return (io_readFile(wikiFN($linksfile))); 44 return ""; 45} 46 47/** 48 * split a string by a special string 49 * 50 * @param string $section 51 * @param string $link 52 * @return array(string, string) 53 */ 54function _split_text($section, $link) { 55 $ret=explode($link, trim($section), 2); 56 return $ret; 57} 58 59// change params of link depending on type 60function _check_translate($type, $link, $params) { 61 if (trim($params) != "") { // change syntax-params --> link-params 62 switch ($type) { 63 case 'internallink': // rendrerer maybe: interwikilink, locallink, internallink, windowssharelink, externallink, emaillink 64 // convert [[$ns|$para]] --> [[$ns|$params]] 65 list($ns, $para) = preg_split('/[\|]/',substr($link, 2, -2), 2); 66 $link=substr($link,0,2).$ns."|".$params.substr($link,-2,2); 67 break; 68 case 'media': // rendrerer mayabe: externalmedia, internalmedia 69 // convert {{$ns?$para}} --> {{$ns?$params}} 70 list($ns, $para) = preg_split('/[\?]/',substr($link, 2, -2), 2); 71 $link=substr($link,0,2).$ns."?".$params.substr($link,-2,2); 72 break; 73 case "windowssharelink": // rendrerer mayabe: windowssharelink 74 case 'externallink': // rendrerer mayabe: externallink 75 case "emaillink": // rendrerer mayabe: emaillink 76 case 'filelink': // rendrerer mayabe: filelink 77 // convert to internallink and set new params 78 $link="[[".$link."|".$params."]]"; 79 $type="internallink"; 80 break; 81 } 82 } 83 return (array($type, $link)); 84} 85 86class syntax_plugin_dwinsect extends DokuWiki_Syntax_Plugin { 87 88 function syntax_plugin_dwinsect() { 89 } 90 91/* not longer needed for DokuWiki 2009-12-25 “Lemming” and later 92 function getInfo(){ 93 return array( 94 'author' => 'Dietrich Wittenberg', 95 'email' => 'info.wittenberg@online.de', 96 'date' => '2012-07-01', 97 'name' => 'plugin dwinsect', 98 'desc' => 'INcludes a SECtion or the first link in the section. The link can be interpreted', 99 'url' => 'http://dokuwiki.org/plugin:dwinsect', 100 ); 101 } 102*/ 103 function getType(){ return 'substition'; } 104 function getAllowedTypes() { return array('disabled'); } // 'formatting', 'substition', 105 function getPType(){ return 'normal'; } 106 function getSort(){ return 199; } 107 108 109 function connectTo($mode) { 110 $pattern='\[\*\(.*?(?=\)\])\)\]'; // [*(.....)] 111 $this->Lexer->addSpecialPattern($pattern, $mode, 'plugin_dwinsect' ); 112 } 113 114 //function postConnect() { $this->Lexer->addExitPattern('}', 'plugin_dwinsect');} 115 116 /** 117 * Handle the match 118 */ 119 function handle($match, $state, $pos, &$handler){ 120 121 switch ($state) { 122 case DOKU_LEXER_ENTER: 123 case DOKU_LEXER_MATCHED: 124 case DOKU_LEXER_UNMATCHED: 125 case DOKU_LEXER_EXIT: 126 break; 127 128 case DOKU_LEXER_SPECIAL: 129 //match_all:[ * ( ... ... )] 130 //syntax :[ * ( ns:file#anchor | params )] 131 $pattern='/\[\*\('.'(?:(.*?)#)?([^|\)]*)'.'[|]?'.'(.*)'.'\)]/'; 132 preg_match($pattern, $match, $subjects); 133 list($match_all, $ns_file, $anchor, $params)=$subjects; 134 135 // load nearest pagefile to wikitext 136 $this->wikitext=_get_linkfile($ns_file, $this->getConf('linklistname')); 137 138 // anchor: anchor_name?param1=val1¶m2=val2 ... 139 // $anchor_params => array(param1 => val1, param2 => val2, ...) 140 list($anchor_name, $anchor_params) = $this->_get_params($anchor); 141 142 // ( section[0] ) 143 // ( section[1] )( section[2] ) 144 // (=== anchor_name ===)(text1 url text2) ==== | $end 145 $pattern='#(={2,}+[ ]*'.preg_quote(trim($anchor_name)).'[ ]*={2,}+\s*)(.*?)' .'(?=={2,}+|$)#s'; 146 if (preg_match($pattern, $this->wikitext, $section)) { 147 148 // found section-name matching $anchor !!! trim spaces from anchor 149 list($link_type, $link) = _get_firstlink($section[2]); // find link in section[2]: link 150 list($text1, $text2) = _split_text($section[2], $link); // split text1, text2 by link: text1 link text2 151 152 switch ($anchor_params['link']) { 153 case "translate": 154 // translate link depending on type: link' 155 list($link_type, $link) = _check_translate($link_type, $link, $params); 156 break; 157 case "none": 158 $link = ""; 159 break; 160 case "plane": 161 default: 162 break; 163 } 164 165 switch ($anchor_params['text']) { 166 case "footnote": 167 $text1 = ($text1) ? "((".$text1."))" : ""; 168 $text2 = ($text2) ? "((".$text2."))" : ""; 169 break; 170 case "none": 171 $text1 = ""; 172 $text2 = ""; 173 break; 174 case "plain": 175 default: 176 break; 177 } 178 179 switch ($anchor_params['include']) { 180 case "plain": 181 $wiki = $section[0]; 182 break; 183 case "link": 184 $wiki = $text1.$link.$text2; 185 break; 186 case "none": 187 default: 188 $wiki = ""; 189 break; 190 } 191 $instructions=p_get_instructions($wiki); 192 array_shift($instructions); //remove document open 193 array_shift($instructions); //remove paragraph open 194 array_pop($instructions); //remove document close 195 array_pop($instructions); //remove paragraph close 196 return array($state, array($instructions, false)); 197 } else { 198 $wiki=$anchor_name.(($params) ? "|".$params : ""); // not found section-name matching: anchor_name|anchor_params 199 return array($state, array($wiki, true)); 200 } 201 break; 202 } 203 return array(); 204 } 205 206 /** 207 * Create output 208 */ 209 function render($mode, &$renderer, $data) { 210 211 if($mode == 'xhtml'){ 212 list($state, $result) = $data; 213 switch ($state) { 214 case DOKU_LEXER_ENTER: 215 case DOKU_LEXER_MATCHED: 216 case DOKU_LEXER_UNMATCHED: 217 case DOKU_LEXER_EXIT: 218 //$renderer->info['cache'] = false; 219 break; 220 221 case DOKU_LEXER_SPECIAL: 222 list($instructions, $error) = $result; 223 if ($error === true) { // render the link as an syntax-error 224 $renderer->internallink("[*(".$instructions.")]"); // instructions contains the error-text 225 } else { 226 //$renderer->doc.=p_render('xhtml', $instructions, $info); // instruction contains an array of instructions 227 $renderer->nest($instructions); 228 } 229 break; 230 } 231 return true; 232 } 233 return false; 234 } 235 236// private class functions 237 function _get_params($anchor) { 238 // anchor: "anchorname?param1=val1¶m2=val2 ..." 239 // init defaults to valid params 240 $anchor_params['text'] = $this->getConf('insecttext'); // "footnote"; 241 $anchor_params['link'] = $this->getConf('insectlink'); // "translate"; 242 $anchor_params['include'] = $this->getConf('insectinclude'); // "link"; 243 // split anchor_name from params 244 list($anchor_name, $params) = preg_split('/[\?]/', $anchor, 2); 245 // split params into anchor_params 246 if ($params) { 247 $a=explode("&", $params); 248 foreach ($a as $p) { 249 list($key, $val) = explode("=", $p); 250 $anchor_params[$key]=$val; 251 } 252 } 253 return array($anchor_name, $anchor_params); 254 } 255 256 function _render_text(&$renderer, $text, $flag) { 257 if ($text) { 258 switch ($flag) { 259 case 'footnote': 260 $renderer->footnote_open(); 261 $renderer->doc.=_stripp(p_render('xhtml',p_get_instructions($text),$info)); 262 $renderer->footnote_close(); 263 break; 264 case 'plain': 265 $renderer->doc.=_stripp(p_render('xhtml',p_get_instructions($text),$info)); 266 break; 267 } 268 } 269 } 270 271 function _render_link(&$renderer, $hndl, $args) { 272 // render the link with type of $hndl: use dokuwiki core-functions 273 switch ($hndl) { 274 case 'internallink': 275 case 'locallink': 276 case 'filelink': 277 case "windowssharelink": 278 case 'externallink': 279 case "emaillink": $renderer->$hndl($args[0], $args[1]); break; 280 case 'interwikilink': $renderer->$hndl($args[0], $args[1], $args[2], $args[3]); break; 281 case 'internalmedia': 282 case 'externalmedia': $renderer->$hndl($args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6]); break; 283 } 284 } 285 286} 287//Setup VIM: ex: et ts=4 enc=utf-8 :