User:Mysid/scripts
From Wikipedia, the free encyclopedia
This script is now outdated – see Wikipedia:WikiProject Chemistry/Structure drawing workgroup/Mysid's script
The exported chemical structures from BKchem are tiny in dimensions, not cropped, and use some SVG features not supported by librsvg (the library used by MediaWiki). Thus I use the following bloated Perl script to correct this (as well as to make the files more compact):
# scale.pl # Scales an SVG image produced by bkchem up by 400 % and removes some # things to circumvent bugs in MediaWiki # Rounding sub round { ($_[0]*10 - int ($_[0]*10) >= .5) ? int ($_[0]*10)/10 + .1 : int ($_[0]*10)/10; } for (qx!cat $ARGV[0]!) { # Scale viewbox up if(/<svg .*viewBox="0 0 (\d+) (\d+)"/) { $w = $1*2; $h = $2*2; $_ = "<svg width=\"".$w."px\" height=\"".$h."px\" version=\"1.0\" viewBox=\"0 0 $w $h\" xmlns=\"http://www.w3.org/2000/svg\">\n"; } # Replace baseline-shift with a y-offset tspan if (/y="([\d\.]+)">.*<tspan baseline-shift="sub"/) { $vy = $1; $oy = $1+3.25; s/baseline-shift="sub"/y="$oy"/g; s/<\/tspan>([^<]+)</<\/tspan><tspan y="$vy">$1<\/tspan></g; } # Scale vectors up; also save space by rounding down to 1/10 pixel resolution & removing redundant declarations s/(\d+\.\d+)/round($1*4)/gee unless(/version/); s/font-family="helvetica" font-size="12pt" //; # Scale fonts up by 400 % s/12pt/48pt/; s/75\%/36pt/g; $lines .= $_; } # Remove redundant grouping tags $lines =~ s/<\/g>\s+<g stroke="\#000000" stroke-width="4">\s//g; # Write out a preliminary version open(out,">".$ARGV[0]."_tmp.svg"); print out $lines; close (out); # Get the actual dimensions of the rendered image, cropped, by rendering it in Inkscape @dime = qx!perl dim.pl $ARGV[0]_tmp.svg!; chomp(@dime[-1]); ($w,$h) = split(/ /,@dime[-1]); # Set the output filename $fname = "output"; if ($ARGV[0] =~ /(.+)\.svg/) { $fname = $1."2"; } open (out,">".$fname.".svg"); # Write out the final image for(qx!cat $ARGV[0]_tmp.svg!) { if(/<svg .*viewBox="0 0 \d+ \d+"/) { $_ = "<svg width=\"".$w."px\" height=\"".$h."px\" version=\"1.0\" viewBox=\"0 0 $w $h\" xmlns=\"http://www.w3.org/2000/svg\">\n"; } print out $_; } close(out); unlink($ARGV[0]."_tmp.svg"); print "$fname.svg done\n";
where dim.pl
contains
use Image::Magick; $a = $ARGV[0]; unlink("tmp.png"); print STDERR "inkscape...\n"; # Render the image system("inkscape -e tmp.png $a"); # Initialize Imagemagick $image = Image::Magick->new; $image->Read("tmp.png"); $he = $image->Get('height'); $wi = $image->Get('width'); $maxy = $maxx = 0; $miny = $he; $minx = $wi; unlink("tmp.gray"); print STDERR "convert...\n"; # Make a raw 8-bit grayscale version for simple perl input system("convert tmp.png -depth 8 tmp.gray"); print STDERR "crop...\n"; open(img,"tmp.gray"); # Find the borders of the actual black data inside the image canvas for $y (1..$he) { for $x (1..$wi) { read(img,$b,1); if (ord($b) < 255) { $miny = $y if ($y<$miny); $minx = $x if ($x<$minx); $maxy = $y if ($y>$maxy); $maxx = $x if ($x>$maxx); } } } # Pad them a little and output print ($maxx+$minx+($maxx*0.05)); print " ".($maxy+$miny+($maxy*0.05))."\n";
Usage: perl scale.pl oldpic.svg
Produces oldpic2.svg
Requires: Linux, Perl, Inkscape, Imagemagick (I haven't really considered portability as I was the only one supposed to use this script)