#!/usr/bin/perl -w # gpdiagram is copyright (C) 2003 Michael J Miller # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License. This program # is distributed without any warranty (not even the implied warranty of # merchantability or fitness for a particular purpose). use strict; my $programname="gpdiagram v0.51 (20-Mar-2003)"; ####################################################################### # This is where you tell gpdiagram the name of your gnuplot program. # If it's not in your path, you will need to include the full name # (e.g. for Windows: my $GNUPLOT='c:\dir1\dir2\pgnuplot.exe';) my $GNUPLOT='gnuplot'; # 'gnuplot' for Linux; 'pgnuplot' for Windows ####################################################################### # This is the main executable. print STDERR "\n$programname\nCopyright (C) 2003 Michael J Miller\n". "This program comes with absolutely no warranty.\n\n"; my ($inputfilename, $outputfilename)=@ARGV; my $input; if (defined $inputfilename) { local $/=undef; open FILE, "< $inputfilename"; $input=; close FILE; } else { local $/=undef; $input= }; my $setup; my $terminal="";my $fontname=""; my $fontsize=12; my $shrinkby; if (defined $outputfilename) { if ($outputfilename =~ m/\.ps$/) { $terminal="postscript"; $fontname="Helvetica"; $fontsize=36; $setup="set terminal postscript eps enhanced". " color solid \"$fontname\" $fontsize;\n"; } elsif ($outputfilename =~ m/\.png$/) { $terminal="png"; $fontsize=20; #large=30, medium=20, small=10 $setup="set terminal png medium color;\n" }; if ($outputfilename =~ /^-./) { $setup.="set output;\n" } else { $setup.="set output \"$outputfilename\";\n" }; }; $setup.="set nokey; set noborder; set noxtics; set noytics;\n". "set size ratio -1; set angles degree; set parametric;\n". "set bmargin 1;\n"; my $plot="plot [0:1] \\\n"; my $data="\n"; my $C=" lt -1 lw 2"; # Color my $N='[+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)'; # Matches a number my $Q=q/'[^']*?'|"[^"]*?"/; # Matches a quoted string my $type; $input =~ s/([^\s])//; foreach (split /$1/, $input) { next if (!/$N|$Q/); #???? $type = lc $1 if (s/^\s*([a-z]+)//i); # Use previous type otherwise my @params; push @params, $1 while (/($N|$Q)/g); # warn "$type @params\n"; if ($type=~/^(point|line|bezier|spline)$/) { $data.="@_\n" while (@_=splice(@params, 0, 2)); $data.="e\n"; if ($type eq "point") { $plot.=" '-' with points $C,\\\n" } elsif ($type eq "line") { $plot.=" '-' with lines $C,\\\n" } elsif ($type eq "bezier"){ $plot.=" '-' smooth bezier $C,\\\n" } elsif ($type eq "spline"){ $plot.=" '-' smooth cspline $C,\\\n" } } elsif ($type eq "comment") {} elsif ($type eq "dimensions") { my ($w, $h)=@params; $shrinkby=($w/5>$h/3.5) ? $w/5 : $h/3.5; } elsif ($type eq "set") { $setup.="set ".substr($params[0],1,-1)."\n" } elsif ($type eq "font" && $terminal eq "postscript") { foreach (@params) { if (/$N/) { $fontsize=$_ } elsif (/$Q/) { ($fontname) = /.(.*)./; }; }; } elsif ($type eq "title") { $setup.="set title $params[0] \"$fontname,$fontsize\";\n"; } elsif ($type eq "label") { my ($x, $y, $label)=@params; if (!defined $shrinkby && $label=~m/^['"][<>^_]/) { warn "Set dimensions for proper label offsets.\n"; $shrinkby=1; }; my $delta=$fontsize*$shrinkby/220; while ($label =~ s/^(['"])([<>^_])/$1/) { if ($2 eq "<") { $x=$x-$delta } elsif ($2 eq ">") { $x=$x+$delta } elsif ($2 eq "^") { $y=$y+$delta } elsif ($2 eq "_") { $y=$y-$delta }; }; $setup.="set label $label at $x,$y". " center font \"$fontname,$fontsize\";\n"; } elsif ($type eq "arrow") { my ($x1,$y1,$x2,$y2)=@params; $setup.="set arrow from $x1,$y1 to $x2,$y2 $C;\n"; } elsif ($type eq "circle"){ my ($x,$y,$r,$t0,$t1)=@params; $t0=0 if (!defined $t0); $t1=360 if (!defined $t1); my $d=$t1-$t0; $plot.=" $x+$r*cos($t0+$d*t), $x+$r*sin($t0+$d*t) $C,\\\n"; } elsif ($type eq "ellipse"){ my ($x,$y,$rx,$ry,$t0,$t1)=@params; $t0=0 if (!defined $t0); $t1=360 if (!defined $t1); my $d=$t1-$t0; $plot.=" $x+$rx*cos($t0+$d*t), $y+$ry*sin($t0+$d*t) $C,\\\n"; } elsif ($type eq "triangle") { my ($x1,$y1,$x2,$y2,$x3,$y3)=@params; $data.="$x1 $y1\n$x2 $y2\n$x3 $y3\n$x1 $y1\ne\n"; $plot.=" '-' with lines $C,\\\n"; } elsif ($type eq "rectangle") { my ($x1,$y1,$x2,$y2)=@params; $data.="$x1 $y1\n$x2 $y1\n$x2 $y2\n$x1 $y2\n$x1 $y1\ne\n"; $plot.=" '-' with lines $C,\\\n"; } elsif ($type eq "graph") { my ($a, $b, $f)=@params; my $x="($a+($b-$a)*t)"; $f =~ s/.(.*)./$1/; $f =~ s/x/$x/g; $plot.=" $x,$f $C,\\\n"; } elsif ($type eq "color") { my $t=lc $params[0]; $t =~ s/.(.*)./$1/; if ($t eq "varies") { $C="" } elsif ($t eq "black") { $C=" lt -1 lw 2 " } elsif ($t eq "red") { $C=" lt 1 lw 4 " } elsif ($t eq "blue") { $C=" lt 2 lw 4 " } elsif ($t eq "green") { $C=" lt 3 lw 4 " } } }; $plot =~ s/,\\$//; open FILE, "> tempfile.gpd"; print FILE $setup, $plot, $data; if (!defined $outputfilename) { print FILE "pause -1\n"; print STDERR "Displaying graph on screen. Press to exit.\n"; } close FILE; system "$GNUPLOT tempfile.gpd"; unlink "tempfile.gpd";