1<?php 2/** 3 * format plugin: Parses external command blocks 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Jason Grout <jason-doku@creativetrax.com> 7 * @version 2007-02-22 8 * heavily based on the graphviz plugin (with the dokutexit extensions) and the gnuplot plugin. 9 */ 10 11if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 12require_once(DOKU_INC.'inc/init.php'); 13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 14require_once(DOKU_PLUGIN.'syntax.php'); 15 16 17/** 18 * All DokuWiki plugins to extend the parser/rendering mechanism 19 * need to inherit from this class 20 */ 21class syntax_plugin_format extends DokuWiki_Syntax_Plugin { 22 23 24 function getInfo(){ 25 return array( 26 'author' => 'Jason Grout', 27 'email' => 'jason-doku@creativetrax.com', 28 'date' => '2007-02-22', 29 'name' => 'format Plugin', 30 'desc' => 'Sends text to external program', 31 'url' => 'https://www.dokuwiki.org/plugin:format', 32 ); 33 } 34 35 /** 36 * What kind of syntax are we? 37 */ 38 function getType(){ 39 return 'protected'; 40 } 41 42 /** 43 * Where to sort in? 44 */ 45 function getSort(){ 46 return 100; 47 } 48 49 50 /** 51 * Connect pattern to lexer 52 */ 53 function connectTo($mode) { 54 $this->Lexer->addEntryPattern('<format(?=.*?</format>)',$mode,'plugin_format'); 55 } 56 57 function postConnect() { 58 $this->Lexer->addExitPattern('</format>','plugin_format'); 59 } 60 61 /** 62 * Handle the match 63 */ 64 65 66 function handle($match, $state, $pos) { 67 global $conf; 68 if ( $state == DOKU_LEXER_UNMATCHED ) { 69 $matches = preg_split('/>/u',$match,2); 70 $matches[0] = trim($matches[0]); 71 if ( trim($matches[0]) == '' ) { 72 $matches[0] = NULL; 73 } 74 // $matches[0] is the format name 75 // $matches[1] is the text inside the format block 76 return array($matches[1],$matches[0]); 77 } 78 return TRUE; 79 } 80 /** 81 * Create output 82 */ 83 function render($mode, &$renderer, $data) { 84 global $conf; 85 $program = $data[1]; 86 $text = $data[0]; 87 if(($mode == 'xhtml' || $mode == 'latex' ) 88 && strlen($text) > 1 89 && strlen($program) > 0) { 90 91 $config = $this->getConf($program); 92 if(!$config || !$config[$mode]) { 93 $renderer->doc .='** "'.$renderer->_xmlEntities($program) 94 .'" format not configured for '.$mode.' output**'; 95 return true; 96 } 97 98 if($config[$mode]['ext']=='multipart') { 99 $multipart = true; 100 } else { 101 $multipart = false; 102 } 103 104 // TODO: make directory mediadir/format/program/namespace/page 105 $dirname = $conf['mediadir'] . '/format/' . $program; 106 if( !is_dir($dirname) ) 107 io_mkdir_p($dirname); //Using dokuwiki framework 108 109 $hashname = md5(serialize($data)).'.'.$config[$mode]['ext']; 110 111 $medianame = $dirname.'/'.$hashname; 112 $medians = ":format:".$program.":"; 113 if($multipart) { 114 $medians = $medians.$hashname.":"; 115 } 116 117 if($multipart) { 118 $outfilename = $medianame.'/home.txt'; 119 } else { 120 $outfilename = ''; 121 } 122 123 if ( ! is_readable($medianame) ) { 124 if($multipart) { //create directory 125 io_mkdir_p($medianame); 126 } 127 if ($this->createMedia($medianame, $outfilename, $multipart, 128 $text, $program, $mode)===false) { 129 $renderer->doc .= '**ERROR RENDERING '.$config['name'].'**'; 130 131 // TODO: Make this portable 132 `rm -rf $medianame`; 133 134 return true; 135 } 136 } 137 138 // $medianame is the name of the media file if not multipart 139 // $medianame is the name of the media directory if multipart 140 // $medians is the namespace in which the media file(s) live. 141 // if multipart, then it is $dirname:$medianame, if not, then it is $dirname 142 143 if($multipart) { 144 // replace the @DOKUMEDIA:name:filename@ with a call to internalmedia 145 /* $renderer->doc .= "<pre>".preg_replace('/@DOKUMEDIA:([^:]*):([^@]*)@/e', 146 "'</pre>'.\$renderer->internalmedia(\$medians.'$2', '$1').'<pre>'", 147 $renderer->_xmlEntities(file_get_contents($outfilename)))."</pre>"; 148 */ 149 } else { 150 151 switch($mode) { 152 case 'xhtml': 153 $renderer->doc .= $renderer->internalmedia($medians.$hashname, 154 $config['name']); 155 break; 156 case 'latex': 157 $renderer->doc .= "\\begin{figure}[h]\n"; 158 $renderer->doc .= "\t\\begin{center}\n"; 159 $renderer->doc .= "\t\t\\includegraphics{"; 160 $renderer->doc .= $medianame; 161 $renderer->doc .= "}\n"; 162 $renderer->doc .= "\t\\end{center}\n"; 163 $renderer->doc .= "\\end{figure}\n"; 164 break; 165 } 166 } 167 168 169 return true; 170 } 171 172 return false; 173 } 174 175 176 177 function createMedia($medianame, $outfilename, $multipart, &$text, $program, $mode='xhtml') { 178 global $conf; 179 $config = $this->getConf($program); 180 if(!$config || !$config[$mode]) return false; 181 182 183 184 $tmpinput = tempnam($this->getConf('tmpdir'), "dokuwiki.format"); 185 $pre = str_replace(array('@INFILE@','@OUTFILE@','@MEDIAFILE@'), 186 array($tmpinput, $outfilename, $medianame), 187 $config[$mode]['pre']); 188 $post = str_replace(array('@INFILE@','@OUTFILE@','@MEDIAFILE@'), 189 array($tmpinput, $outfilename,$medianame), 190 $config[$mode]['post']); 191 192 $wrappeddata = $pre.$text.$post; 193 //$this->printpre($wrappeddata); 194 io_saveFile($tmpinput, $wrappeddata); //Using dokuwiki framework 195 196 // TODO: do I need to initialize these variables before passing them to exec? 197 $output=array(); 198 $retval=''; 199 200 // Replace the variable strings 201 $command=str_replace(array('@INFILE@','@OUTFILE@','@MEDIAFILE@'), 202 array($tmpinput, $outfilename, $medianame), 203 $config[$mode]['command']) 204 //$this->printpre($command); 205 exec($command,$output,$retval); 206 //$this->printpre(print_r($output,true)); 207 unlink($tmpinput); 208 return $retval; 209 } 210 function printpre($data) { 211 print("<pre>".$data."</pre>"); 212 } 213 214} 215 216?>