1<?php 2/** 3 * Plugin SVG: Converts inline SVG images 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Christopher Smith <chris@jalakai.co.uk> 7 */ 8 9if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 10if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 11require_once(DOKU_PLUGIN.'syntax.php'); 12 13/** 14 * Include an external file to reduce some clutter and define some 15 * functions. 16 */ 17require_once(DOKU_PLUGIN.'svg/header.php'); 18 19/** 20 * All DokuWiki plugins to extend the parser/rendering mechanism 21 * need to inherit from this class 22 */ 23class syntax_plugin_svg extends DokuWiki_Syntax_Plugin { 24 25 var $xml_data; 26 27 function getInfo(){ 28 return array( 29 'author' => 'Austen Dicken', 30 'email' => 'admin@cvpcs.org', 31 'date' => '2007-05-16', 32 'name' => 'DokuWiki SVG Plugin', 33 'desc' => 'Supplies a way to render SVG images inline within a document.', 34 'url' => 'http://www.cvpcs.org/dokuwiki/lib/exe/fetch.php?id=project%3Adokuwiki-svg&cache=cache&media=project:dokuwiki-svg.tar.gz', 35 ); 36 } 37 38 function getType(){ 39 return 'protected'; 40 } 41 42 function getSort(){ 43 return 999; 44 } 45 46 function connectTo($mode) { 47 $this->Lexer->addEntryPattern('<svgimage>',$mode,'plugin_svg'); 48 } 49 50 function postConnect() { 51 $this->Lexer->addExitPattern('</svgimage>','plugin_svg'); 52 } 53 54 function handle($match, $state, $pos, &$handler){ 55 switch ($state) { 56 case DOKU_LEXER_ENTER : 57 break; 58 case DOKU_LEXER_MATCHED : 59 break; 60 case DOKU_LEXER_UNMATCHED : 61 break; 62 case DOKU_LEXER_EXIT : 63 break; 64 case DOKU_LEXER_SPECIAL : 65 break; 66 } 67 return array( $state, $match ); 68 } 69 70 function render($mode, &$renderer, $data) { 71 global $syntax_plugin_svg_pcount; 72 if($mode == 'xhtml'){ 73 list( $state, $match ) = $data; 74 switch( $state ) 75 { 76 case DOKU_LEXER_ENTER : 77 $this->xml_data = ''; 78 break; 79 case DOKU_LEXER_EXIT : 80 if( $syntax_plugin_svg_pcount == 0 ) 81 { 82 $this->clearImages(); 83 } 84 $this->save(); 85 $this->renderSVG( $renderer ); 86 $syntax_plugin_svg_pcount++; 87 break; 88 default: 89 $this->xml_data .= $match; 90 break; 91 } 92 return true; 93 } 94 return false; 95 } 96 97 function clearImages() 98 { 99 foreach( glob( 100 SYNTAX_PLUGIN_SVG_MEDIADIR . 101 'media/' . 102 md5( getID() ) . 103 '*' 104 ) as $filename ) 105 { 106 unlink( $filename ); 107 } 108 } 109 110 function save() 111 { 112 global $syntax_plugin_svg_pcount; 113 114 $this->xml_data = ltrim( $this->xml_data ); 115 116 $filename = md5( getID() ) . $syntax_plugin_svg_pcount . '.svg'; 117 118 switch( $this->getConf( 'output' ) ) 119 { 120 case 'imagick': 121 if( extension_loaded( 'imagick' ) ) 122 { 123 $ih = new Imagick(); 124 $ih->readImageBlob( $this->xml_data ); 125 $ih->setImageFormat( $this->getConf( 'im_format' ) ); 126 $ih->writeImage( 127 SYNTAX_PLUGIN_SVG_MEDIADIR . 128 'media/' . 129 substr( $filename, 0, -3 ) . 130 strtolower( $this->getConf( 'im_format' ) ) 131 ); 132 $ih->destroy(); 133 break; 134 } 135 case 'magickwand': 136 if( extension_loaded( 'magickwand' ) ) 137 { 138 $mwh = NewMagickWand(); 139 MagickReadImageBlob( $mwh, $this->xml_data ); 140 MagickSetFormat( $mwh, $this->getConf( 'mw_format' ) ); 141 MagickPaintTransparentImage( $mwh, NewPixelWand( '#FFFFFF' ) ); 142 MagickWriteImage( 143 $mwh, 144 SYNTAX_PLUGIN_SVG_MEDIADIR . 145 'media/' . 146 substr( $filename, 0, -3 ) . 147 strtolower( $this->getConf( 'mw_format' ) ) 148 ); 149 DestroyMagickWand( $mwh ); 150 break; 151 } 152 case 'embed': 153 case 'object': 154 case 'iframe': 155 $fh = fopen( SYNTAX_PLUGIN_SVG_MEDIADIR . 'media/' . $filename, 'w' ); 156 fwrite( $fh, $this->xml_data ); 157 fclose( $fh ); 158 break; 159 } 160 } 161 162 function renderSVG( &$renderer ) 163 { 164 global $syntax_plugin_svg_pcount; 165 166 $svgp = new syntax_plugin_svg_parser(); 167 $svgp->parse( $this->xml_data ); 168 169 switch( $this->getConf( 'output' ) ) 170 { 171 case 'imagick': 172 if( extension_loaded( 'imagick' ) ) 173 { 174 $renderer->doc .= '<img src="' 175 . getBaseURL( true ) 176 . 'data/svg/media/' 177 . md5( getID() ) . $syntax_plugin_svg_pcount 178 . '.' . strtolower( $this->getConf( 'im_format' ) ) 179 . '" width="' 180 . $svgp->width . '" height="' 181 . $svgp->height . '" alt="SVGImage' 182 . $syntax_plugin_svg_pcount . '" />'; 183 184 break; 185 } 186 case 'magickwand': 187 if( extension_loaded( 'magickwand' ) ) 188 { 189 $renderer->doc .= '<img src="' 190 . getBaseURL( true ) 191 . 'data/svg/media/' 192 . md5( getID() ) . $syntax_plugin_svg_pcount 193 . '.' . strtolower( $this->getConf( 'mw_format' ) ) 194 . '" width="' 195 . $svgp->width . '" height="' 196 . $svgp->height . '" alt="SVGImage' 197 . $syntax_plugin_svg_pcount . '" />'; 198 199 break; 200 } 201 case 'embed': 202 $renderer->doc .= '<embed src="' 203 . getBaseURL( true ) 204 . 'data/svg/media/' 205 . md5( getID() ) . $syntax_plugin_svg_pcount . '.svg" width="' 206 . $svgp->width . '" height="' 207 . $svgp->height . '" ' 208 . 'type="image/svg+xml" ' 209 . 'pluginspage="http://www.adobe.com/svg/viewwer/install/" />'; 210 break; 211 case 'object': 212 $renderer->doc .= '<object data="' 213 . getBaseURL( true ) 214 . 'data/svg/media/' 215 . md5( getID() ) . $syntax_plugin_svg_pcount . '.svg" width="' 216 . $svgp->width . '" height="' 217 . $svgp->height . '" ' 218 . 'type="image/svg+xml" ' 219 . 'pluginspage="http://www.adobe.com/svg/viewwer/install/" />'; 220 case 'iframe': 221 $renderer->doc .= '<iframe style="border: none;" src="' 222 . getBaseURL( true ) 223 . 'data/svg/media/' 224 . md5( getID() ) . $syntax_plugin_svg_pcount . '.svg" width="' 225 . $svgp->width . '" height="' 226 . $svgp->height . '" ' 227 . 'type="image/svg+xml"></iframe>'; 228 break; 229 } 230 } 231} 232 233