Inline SVG extension

From assela Pathirana
Revision as of 07:28, 12 March 2006 by Root (talk | contribs)
Jump to navigationJump to search

Following is a very simple piece of work. Feel free to comment, particularly about alternative approaches and so on.

Purpose & Quick Howto

To enable including in-line svg code in a wiki document, using client browser's capability (native as in mozilla firefox or with a plug-in as in internet explorer and Adobe's SVG plugin).

Do I need this extension

Probably not! You can achieve the same results using standard mediawiki tools

  • Upload the svg file as an image
  • Then use it in an [[Image:foobar]] tag. It works for many browsers.

And if you want to play it safe (remember many old browsers might not support svg format!)

Howto

Follow the steps below:

  • Cut and paste the source code below in to a file named SVGtag.php in your extensions directory
  • Call SVGtag.php by adding following line to the end of LocalSettings.php
    include("extensions/SVGtag.php");
  • Include svg code as follows:
    <svgcode calling_arguments>

<svg various arguments come here> svg code here </svg> </svgcode>

    • For example
      <svgcode width="300" height="200" version="1.1">

<svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="300" height="200"

    viewBox="0 0 300 350" >

<rect x="0.5" y="0.5" fill="#FFFFFF" stroke="#000000" width="250" height="175"/> </svg>

</svgcode>

See the bottom of this article to see whether your browser support svg.

Background

See Also: SVG

In a perfect world, there is no need to use fancy method to incorporate a SVG script to a web page. However, the conflicts in various browser standards make the waters muddy. There are several methods to do this, depending on targeted browser, but nothing works perfectly for everything[1]. The best compromise seems to be having the svg code in a separate file and include that file in a special object/embed/iframe tag. the latter seems to work best in both worlds (i.e. Mozilla, native svg rendering and IE assisted by Adobe SVG plug in.

<iframe src="file.svg" width="500" height="500">
</iframe>

can show a properly formatted svg file in most of the modern browsers.

How it works

(see metawikipedia:Write_your_own_MediaWiki_extension first.)

  • The extension registers a hook to Mediawiki wgParser requesting it to run returnSVGtagged function whenever
    <svgtag> blah blah </svgtag>
    is found in the code, using 'blah blah' (code between <svgtag> and </svgtag> as the argument.
  • returnSVGtagged function does the following
    1. Creates a unique file name based on MD5 checksum of the svg code in the argument.
    2. Checks whether a file by that name exists
    3. if no
      1. create a new file under that name with svg code as argument
    4. end if
    5. return a iframe tag calling the unique file name.

Source Code

<?php
#----------------------------------------------------------------------------
#Copyright 2006 Assela Pathirana
#----------------------------------------------------------------------------
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#-------------------------------------------------------------------------------
#    Inspired by svgextension.
#-------------------------------------------------------------------------------
$wgExtensionFunctions[] = "wfSVGtag";

function wfSVGtag() {
	global $wgParser;
	$wgParser->setHook( "svgcode", "returnSVGtagged" );
}

function returnSVGtagged( $code, $argv)
{
	global $wgUploadDirectory, $wgUploadPath, $IP, $wgArticlePath, $wgTmpDirectory;
	$hash = md5( $code );
  $tmploc="/svgcode/";
  $extension=".svg";
  $svgversion=$argv["version"];
  $boxwidth=$argv["width"];
  $boxheight=$argv["height"];
  if (!is_numeric($boxwidth)){
    $boxwidth="500";
  }
  if (!is_numeric($boxheight)){
    $boxheight="500";
  }
  if ($svgversion==""){
    $svgversion='1.1';
  }
  $svgversion2=str_replace(".","",$svgversion);
  $dest = $wgUploadDirectory.$tmploc;
  $path= $wgUploadPath.$tmploc;
	if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); }
	if ( ! is_dir( $wgTmpDirectory ) ) { mkdir( $wgTmpDirectory, 0777 ); }

	$outfile = $dest . $hash.$extension;
  $pname = $path . $hash.$extension;
	if ( !  file_exists( $outfile ) ) {
		$ptr = fopen($outfile, "w");
    $header=
    '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG '.$svgversion.'//EN" "http://www.w3.org/Graphics/SVG/'.$svgversion.
    '/DTD/svg'.$svgversion2.'.dtd" [ <!ENTITY ns_svg "http://www.w3.org/2000/svg">'.
    '<!ENTITY ns_xlink "http://www.w3.org/1999/xlink"> ]>';
		fwrite($ptr, $header);
		fwrite($ptr, $code);
		fclose($ptr);
  } 
 		$txt  = "<iframe src=$pname width='".$boxwidth."' height='".$boxheight."' ></iframe>";
    return $txt;
}

?>

SVG Browser Test

You can see the images here even if your browser does not support SVG.

Example1.svg

Example2.svg

File:Example3.svg

Then, if you see the same images below, then your browser supports SVG.

<svgcode width="300" height="200" version="1.1"> <svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="189.344" height="190.979" viewBox="0 0 189.344 190.979" overflow="visible" enable-background="new 0 0 189.344 190.979" xml:space="preserve"> <rect x="31.167" y="30.44" fill="#ED1C24" stroke="#000000" width="121.477" height="94.631"/> <rect x="67.368" y="66.547" fill="#00ADEF" stroke="#000000" width="121.476" height="94.631"/> <rect x="48.919" y="47.097" fill="#6C9D31" stroke="#000000" width="121.476" height="94.631"/> <radialGradient id="XMLID_2_" cx="33.5747" cy="32.0962" r="31.8353" gradientUnits="userSpaceOnUse"> <stop offset="0" style="stop-color:#FFFFFF"/> <stop offset="1" style="stop-color:#000000"/> </radialGradient> <polygon fill="url(#XMLID_2_)" stroke="#000000" points="66.066,40.507 43.529,43.18 32.955,63.261 23.448,42.653 1.083,38.802 17.744,23.392 14.496,0.931 34.3,12.015 54.658,1.985 50.236,24.245 "/> <g> <g> <line fill="none" x1="51.972" y1="108.292" x2="69.422" y2="185.474"/> <g> <g> <g> <circle fill="#FFFFFF" stroke="#FADB2A" stroke-width="0.997" stroke-miterlimit="10" cx="40.151" cy="141.565" r="3.183"/> <path fill="#FFFFFF" stroke="#ED248B" stroke-width="0.997" stroke-miterlimit="10" d="M81.368,140.921 c1.419,1.036,3.412,0.719,4.444-0.703c1.035-1.423,0.72-3.417-0.702-4.449c-1.424-1.033-3.416-0.717-4.451,0.706 C79.627,137.896,79.942,139.89,81.368,140.921z"/> <path fill="#FFFFFF" stroke="#00AB4E" stroke-width="0.997" stroke-miterlimit="10" d="M88.998,167.87 c-0.543,1.675,0.372,3.47,2.045,4.01c1.671,0.544,3.469-0.369,4.012-2.042c0.543-1.669-0.371-3.467-2.044-4.012 C91.338,165.284,89.542,166.195,88.998,167.87z"/> <path fill="none" stroke="#3B75BA" stroke-width="0.997" stroke-miterlimit="10" d="M84.077,150.453 c-1.036,1.421-0.719,3.414,0.702,4.447c1.422,1.036,3.416,0.719,4.448-0.707c1.033-1.419,0.719-3.412-0.705-4.446 C87.102,148.712,85.11,149.03,84.077,150.453z"/> <path fill="none" stroke="#F08731" stroke-width="0.997" stroke-miterlimit="10" d="M77.633,182.727 c-1.424,1.032-1.739,3.024-0.705,4.447c1.033,1.419,3.024,1.738,4.447,0.705c1.423-1.034,1.739-3.028,0.706-4.451 C81.049,182.006,79.055,181.691,77.633,182.727z"/> <path fill="none" stroke="#C6322C" stroke-width="0.997" stroke-miterlimit="10" d="M51.467,144.013 c-1.671,0.541-2.588,2.339-2.044,4.011c0.544,1.672,2.339,2.589,4.013,2.043c1.674-0.544,2.59-2.339,2.045-4.01 C54.936,144.385,53.142,143.47,51.467,144.013z"/> <path fill="none" stroke="#FADB2A" stroke-width="0.997" stroke-miterlimit="10" d="M62.434,161.619 c-1.759,0-3.185,1.428-3.185,3.189c-0.002,1.754,1.425,3.182,3.185,3.182c1.757,0,3.186-1.425,3.186-3.182 C65.619,163.047,64.191,161.619,62.434,161.619z"/> <path fill="#FFFFFF" stroke="#AC60A6" stroke-width="0.997" stroke-miterlimit="10" d="M52.596,178.394 c-1.424-1.036-3.416-0.723-4.45,0.701c-1.033,1.426-0.719,3.416,0.705,4.448c1.421,1.036,3.414,0.72,4.448-0.701 C54.333,181.417,54.017,179.425,52.596,178.394z"/> <path fill="#FFFFFF" stroke="#EB2891" stroke-width="0.997" stroke-miterlimit="10" d="M38.215,185.426 c-1.035-1.421-3.025-1.739-4.449-0.705c-1.421,1.033-1.738,3.024-0.702,4.446c1.032,1.425,3.022,1.74,4.445,0.707 C38.932,188.841,39.249,186.847,38.215,185.426z"/> <path fill="#FFFFFF" stroke="#77C047" stroke-width="0.997" stroke-miterlimit="10" d="M43.432,174.856 c-0.544-1.675-2.341-2.59-4.013-2.045c-1.672,0.54-2.586,2.338-2.044,4.01c0.543,1.674,2.34,2.591,4.013,2.044 C43.061,178.324,43.977,176.527,43.432,174.856z"/> <circle fill="#FFFFFF" stroke="#564E95" stroke-width="0.997" stroke-miterlimit="10" cx="38.964" cy="152.73" r="3.185"/> <circle fill="#FFFFFF" stroke="#ECA021" stroke-width="0.997" stroke-miterlimit="10" cx="57.438" cy="134.261" r="3.184"/> </g> <circle fill="#FFFFFF" stroke="#EB60A3" stroke-width="0.4985" stroke-miterlimit="10" cx="77.115" cy="146.784" r="2.03"/> <circle fill="#FFFFFF" stroke="#564E95" stroke-width="0.4985" stroke-miterlimit="10" cx="84.676" cy="161.624" r="2.031"/> <circle fill="#FFFFFF" stroke="#00AB4E" stroke-width="0.4985" stroke-miterlimit="10" cx="73.669" cy="172.223" r="2.03"/> <circle fill="none" stroke="#3B75BA" stroke-width="0.4985" stroke-miterlimit="10" cx="56.926" cy="156.024" r="2.03"/> <path fill="none" stroke="#F08731" stroke-width="0.4985" stroke-miterlimit="10" d="M80.904,174.822 c-0.908,0.66-1.109,1.928-0.449,2.837c0.659,0.906,1.928,1.107,2.836,0.45c0.907-0.662,1.108-1.933,0.449-2.837 C83.082,174.364,81.809,174.164,80.904,174.822z"/> <path fill="none" stroke="#C6322C" stroke-width="0.4985" stroke-miterlimit="10" d="M71.081,161.03 c-1.065,0.345-1.65,1.492-1.303,2.557c0.347,1.067,1.492,1.649,2.558,1.305c1.068-0.349,1.652-1.496,1.305-2.559 C73.292,161.266,72.148,160.682,71.081,161.03z"/> <path fill="none" stroke="#FADB2A" stroke-width="0.4985" stroke-miterlimit="10" d="M66.331,177.937 c-1.122,0-2.031,0.91-2.031,2.032c-0.001,1.118,0.909,2.029,2.031,2.029c1.12,0,2.029-0.907,2.029-2.029 S67.451,177.937,66.331,177.937z"/> <circle fill="#FFFFFF" stroke="#00A994" stroke-width="0.4985" stroke-miterlimit="10" cx="60.662" cy="179.07" r="2.03"/> <circle fill="#FFFFFF" stroke="#EB2891" stroke-width="0.4985" stroke-miterlimit="10" cx="51.491" cy="172.405" r="2.03"/> <circle fill="#FFFFFF" stroke="#77C047" stroke-width="0.4985" stroke-miterlimit="10" cx="46.559" cy="161.31" r="2.03"/> <circle fill="#FFFFFF" stroke="#ED7140" stroke-width="0.4985" stroke-miterlimit="10" cx="70.558" cy="154.42" r="2.031"/> <circle fill="#FFFFFF" stroke="#ECA021" stroke-width="0.4985" stroke-miterlimit="10" cx="60.666" cy="144.178" r="2.03"/> <circle fill="#FFFFFF" stroke="#FADB2A" stroke-width="0.4985" stroke-miterlimit="10" cx="72.357" cy="143.861" r="2.03"/> </g> </g> <g> <g> <g> <circle fill="#FFFFFF" stroke="#FADB2A" stroke-width="0.8103" stroke-miterlimit="10" cx="32.56" cy="91.972" r="2.587"/> <path fill="#FFFFFF" stroke="#ED248B" stroke-width="0.8103" stroke-miterlimit="10" d="M66.06,91.449 c1.154,0.842,2.773,0.584,3.612-0.571c0.841-1.157,0.585-2.776-0.57-3.616c-1.157-0.839-2.776-0.583-3.617,0.574 C64.646,88.99,64.902,90.61,66.06,91.449z"/> <path fill="#FFFFFF" stroke="#00AB4E" stroke-width="0.8103" stroke-miterlimit="10" d="M72.262,113.352 c-0.442,1.361,0.302,2.82,1.662,3.259c1.359,0.442,2.82-0.3,3.261-1.66c0.442-1.357-0.302-2.818-1.661-3.261 C74.164,111.25,72.705,111.991,72.262,113.352z"/> <path fill="none" stroke="#3B75BA" stroke-width="0.8103" stroke-miterlimit="10" d="M68.262,99.196 c-0.842,1.156-0.584,2.774,0.571,3.615c1.156,0.842,2.777,0.584,3.616-0.575c0.839-1.154,0.584-2.773-0.573-3.613 C70.721,97.781,69.102,98.039,68.262,99.196z"/> <circle fill="none" stroke="#F08731" stroke-width="0.8103" stroke-miterlimit="10" cx="64.546" cy="127.521" r="2.588"/> <circle fill="none" stroke="#C6322C" stroke-width="0.8103" stroke-miterlimit="10" cx="42.557" cy="96.422" r="2.587"/> <path fill="none" stroke="#FADB2A" stroke-width="0.8103" stroke-miterlimit="10" d="M50.671,108.272 c-1.43,0-2.588,1.161-2.588,2.591c-0.001,1.426,1.158,2.586,2.588,2.586c1.428,0,2.589-1.158,2.589-2.586 C53.26,109.433,52.099,108.272,50.671,108.272z"/> <path fill="#FFFFFF" stroke="#AC60A6" stroke-width="0.8103" stroke-miterlimit="10" d="M42.675,121.905 c-1.157-0.842-2.776-0.587-3.617,0.57c-0.839,1.159-0.584,2.776,0.573,3.615c1.155,0.842,2.774,0.586,3.615-0.57 C44.087,124.363,43.83,122.744,42.675,121.905z"/> <path fill="#FFFFFF" stroke="#EB2891" stroke-width="0.8103" stroke-miterlimit="10" d="M30.987,127.621 c-0.841-1.155-2.459-1.413-3.617-0.573c-1.155,0.839-1.412,2.458-0.57,3.613c0.838,1.158,2.457,1.414,3.613,0.574 C31.569,130.397,31.826,128.776,30.987,127.621z"/> <circle fill="#FFFFFF" stroke="#77C047" stroke-width="0.8103" stroke-miterlimit="10" cx="32.765" cy="119.829" r="2.588"/> <circle fill="#FFFFFF" stroke="#564E95" stroke-width="0.8103" stroke-miterlimit="10" cx="31.595" cy="101.047" r="2.588"/> <circle fill="#FFFFFF" stroke="#ECA021" stroke-width="0.8103" stroke-miterlimit="10" cx="46.611" cy="86.036" r="2.588"/> </g> <circle fill="#FFFFFF" stroke="#EB60A3" stroke-width="0.4052" stroke-miterlimit="10" cx="62.603" cy="96.213" r="1.65"/> <circle fill="#FFFFFF" stroke="#564E95" stroke-width="0.4052" stroke-miterlimit="10" cx="68.749" cy="108.276" r="1.651"/> <circle fill="#FFFFFF" stroke="#00AB4E" stroke-width="0.4052" stroke-miterlimit="10" cx="59.803" cy="116.89" r="1.65"/> <circle fill="none" stroke="#3B75BA" stroke-width="0.4052" stroke-miterlimit="10" cx="46.194" cy="103.724" r="1.65"/> <circle fill="none" stroke="#F08731" stroke-width="0.4052" stroke-miterlimit="10" cx="66.654" cy="120.339" r="1.651"/> <circle fill="none" stroke="#C6322C" stroke-width="0.4052" stroke-miterlimit="10" cx="58.209" cy="109.362" r="1.65"/> <path fill="none" stroke="#FADB2A" stroke-width="0.4052" stroke-miterlimit="10" d="M53.838,121.534 c-0.912,0-1.65,0.74-1.65,1.652c-0.001,0.908,0.738,1.649,1.65,1.649c0.911,0,1.65-0.737,1.65-1.649 S54.749,121.534,53.838,121.534z"/> <circle fill="#FFFFFF" stroke="#00A994" stroke-width="0.4052" stroke-miterlimit="10" cx="49.231" cy="122.455" r="1.65"/> <circle fill="#FFFFFF" stroke="#EB2891" stroke-width="0.4052" stroke-miterlimit="10" cx="41.778" cy="117.038" r="1.65"/> <circle fill="#FFFFFF" stroke="#77C047" stroke-width="0.4052" stroke-miterlimit="10" cx="37.768" cy="108.02" r="1.65"/> <circle fill="#FFFFFF" stroke="#ED7140" stroke-width="0.4052" stroke-miterlimit="10" cx="57.274" cy="102.42" r="1.65"/> <circle fill="#FFFFFF" stroke="#ECA021" stroke-width="0.4052" stroke-miterlimit="10" cx="49.234" cy="94.096" r="1.65"/> <circle fill="#FFFFFF" stroke="#FADB2A" stroke-width="0.4052" stroke-miterlimit="10" cx="58.737" cy="93.838" r="1.65"/> </g> </g> </g> </g> </svg> </svgcode>