1<?php 2/** 3 * Plugin asciidocjs - Use asciidoc inside dokuwiki 4 * 5 * To be run with Dokuwiki only 6 * 7 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 8 * @author Rüdiger Kessel <ruediger.kessel@gmail.com> 9 */ 10if(!defined('DOKU_INC')) die(); 11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 12 13 /** 14 * All DokuWiki plugins to extend the parser/rendering mechanism 15 * need to inherit from this class 16 */ 17 class syntax_plugin_asciidocjs extends DokuWiki_Syntax_Plugin { 18 19 20 public $scriptid = 0; 21 /** 22 * Get the type of syntax this plugin defines. 23 * 24 * @param none 25 * @return String <tt>'substition'</tt> (i.e. 'substitution'). 26 * @public 27 * @static 28 */ 29 function getType(){ 30 return 'protected'; 31 } 32 33 /** 34 * Where to sort in? 35 * 36 * @param none 37 * @return Integer <tt>6</tt>. 38 * @public 39 * @static 40 */ 41 function getSort(){ 42 return 1; 43 } 44 45 46 /** 47 * Connect lookup pattern to lexer. 48 * 49 * @param $aMode String The desired rendermode. 50 * @return none 51 * @public 52 * @see render() 53 */ 54 function connectTo($mode) { 55 $this->Lexer->addEntryPattern('<asciidoc>',$mode,'plugin_asciidocjs'); 56 $this->Lexer->addEntryPattern('//--asciidoc--//',$mode,'plugin_asciidocjs'); 57 } 58 59 function postConnect() { 60 $this->Lexer->addExitPattern('</asciidoc>','plugin_asciidocjs'); 61 } 62 63 64 /** 65 * Handler to prepare matched data for the rendering process. 66 * 67 * <p> 68 * The <tt>$aState</tt> parameter gives the type of pattern 69 * which triggered the call to this method: 70 * </p> 71 * @param $aAscdoc String The asciidoc text to convert. 72 */ 73 function run_asciidoctor($node,$ascdoc,$save_mode) { 74 if ($node==''){ 75 return '<!-- ascii-doc no node command -->'; 76 } 77 $html = ''; 78 $return_value = 1; 79 $descriptorspec = array( 80 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 81 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 82 2 => array("pipe", "w") // stderr 83 ); 84 $cwd = DOKU_PLUGIN.'asciidocjs'; 85 $env = array(); 86 $CMD=$node." asciidoc.js ".$save_mode; 87 $process = proc_open($CMD, $descriptorspec, $pipes, $cwd, $env); 88 if (is_resource($process)) { 89 // $pipes now looks like this: 90 // 0 => writeable handle connected to child stdin 91 // 1 => readable handle connected to child stdout 92 // Any error output will be appended to /tmp/error-output.txt 93 94 fwrite($pipes[0],$ascdoc); 95 fclose($pipes[0]); 96 97 $html=stream_get_contents($pipes[1]); 98 fclose($pipes[1]); 99 100 $error=stream_get_contents($pipes[2]); 101 fclose($pipes[2]); 102 103 // It is important that you close any pipes before calling 104 // proc_close in order to avoid a deadlock 105 $return_value = proc_close($process); 106 } 107 if ($return_value==0) { 108 return $html; 109 } else { 110 return "<!-- ascii-doc error $return_value: $error -->"; 111 } 112 } 113 /** 114 * Handler to prepare matched data for the rendering process. 115 * 116 * <p> 117 * The <tt>$aState</tt> parameter gives the type of pattern 118 * which triggered the call to this method: 119 * </p> 120 * <dl> 121 * <dt>DOKU_LEXER_ENTER</dt> 122 * <dd>a pattern set by <tt>addEntryPattern()</tt></dd> 123 * <dt>DOKU_LEXER_MATCHED</dt> 124 * <dd>a pattern set by <tt>addPattern()</tt></dd> 125 * <dt>DOKU_LEXER_EXIT</dt> 126 * <dd> a pattern set by <tt>addExitPattern()</tt></dd> 127 * <dt>DOKU_LEXER_SPECIAL</dt> 128 * <dd>a pattern set by <tt>addSpecialPattern()</tt></dd> 129 * <dt>DOKU_LEXER_UNMATCHED</dt> 130 * <dd>ordinary text encountered within the plugin's syntax mode 131 * which doesn't match any pattern.</dd> 132 * </dl> 133 * @param $aMatch String The text matched by the patterns. 134 * @param $aState Integer The lexer state for the match. 135 * @param $aPos Integer The character position of the matched text. 136 * @param $aHandler Object Reference to the Doku_Handler object. 137 * @return Integer The current lexer state for the match. 138 * @public 139 * @see render() 140 * @static 141 */ 142 function handle($match, $state, $pos, Doku_Handler $handler){ 143 switch ($state) { 144 case DOKU_LEXER_ENTER : 145 $data =''; 146 if ($this->scriptid==0){ 147 $data .= '<script type="module" src="'.DOKU_BASE.'lib/plugins/asciidocjs/asciidoc.js'.'" defer></script>'.PHP_EOL; 148 $data .= '<script type="text/javascript">'.PHP_EOL; 149 $data .= 'save_mode="'.$this->getConf('save_mode').'";</script>'.PHP_EOL; 150 } 151 return array($state, $data, ''); 152 case DOKU_LEXER_MATCHED : 153 break; 154 case DOKU_LEXER_UNMATCHED : 155 $data =''; 156 if ($this->getConf('save_mode')=='server'){ 157 $data.='<!-- ascii-doc start -->'; 158 $data.=$this->run_asciidoctor($this->getConf('exec_node'),$match,$this->getConf('save_mode')); 159 $data.='<!-- ascii-doc end -->'; 160 } else { 161 $SID="asciidoc_c".strval($this->scriptid); 162 $DID="asciidoc_t".strval($this->scriptid); 163 $this->scriptid+=1; 164 $data.='<div id="'.$DID.'"></div>'.PHP_EOL; 165 $data.='<script type="text/javascript">if (typeof asciidocs === "undefined") asciidocs=[];'.PHP_EOL; 166 $data.='asciidocs.push({"SID":"'.$SID.'","DID":"'.$DID.'"});</script>'.PHP_EOL; 167 $data.='<script id="'.$SID.'" type="text/json">'; 168 $data.='{"text":'.json_encode($match).'}'; 169 $data.='</script>'; 170 } 171 return array($state, $data, $match); 172 case DOKU_LEXER_EXIT : 173 return array($state, '', ''); 174 case DOKU_LEXER_SPECIAL : 175 break; 176 } 177 return array(); 178 } 179 180 /** 181 * Handle the actual output creation. 182 * 183 * <p> 184 * The method checks for the given <tt>$aFormat</tt> and returns 185 * <tt>FALSE</tt> when a format isn't supported. <tt>$aRenderer</tt> 186 * contains a reference to the renderer object which is currently 187 * handling the rendering. The contents of <tt>$aData</tt> is the 188 * return value of the <tt>handle()</tt> method. 189 * </p> 190 * @param $aFormat String The output format to generate. 191 * @param $aRenderer Object A reference to the renderer object. 192 * @param $aData Array The data created by the <tt>handle()</tt> 193 * method. 194 * @return Boolean <tt>TRUE</tt> if rendered successfully, or 195 * <tt>FALSE</tt> otherwise. 196 * @public 197 * @see handle() 198 */ 199 function render($mode, Doku_Renderer $renderer, $data) { 200 if($mode == 'xhtml'){ 201 if(is_a($renderer,'renderer_plugin_dw2pdf')){ 202 // this is the PDF export, render simple HTML here 203 $renderer->doc .= $this->run_asciidoctor($this->getConf('exec_node'),$data[2],$this->getConf('save_mode')); 204 }else{ 205 // this is normal XHTML for Browsers, be fancy here 206 $renderer->doc .= $data[1]; 207 } 208 return true; 209 } 210 return false; 211 } 212 } 213 214?> 215 216