#!/usr/bin/perl
#
# Simple "little language" for building Reed-Kellogg diagrams
#
# We translate a simple line-oriented input format into .svg
#
# General notion of input:
#
# ID TYPE x y string
#
# "ID" is an arbitrary identifier used to recover calculated position values later on
# "TYPE" is the kind of diagram component, like "htext" or "otext"
# "x" and "y" are the starting x and y position in svg coordinates
# (note that these run left-to-right and top-to-bottom
# from an origin in the upper left corner of the figure)
#
# We are starting with
print "\n";
# and using
#
# which (at least on my machine in Adobe intepreter)
# yields 52.5 characters in 200 units, so charwidth ~ 5.71
$charwidth = sprintf("%.2f",200/52.5);
#
# We leave 1.5 charwidth on each side of each horizontal string,
$hmargin = sprintf("%.2f",1.5*$charwidth);
# and a bit more on the left of oblique strings:
$omargin = sprintf("%.2f", 1.8*$charwidth);
# and we need about 7 units minimum vertical space, sqrt(2*(7^2)) for modifiers
$vmin = 7; $vsmin = sprintf("%.2f", sqrt(2*($vmin**2)));
#
# post-subject line is 4 units below, 6.5 units above
$subjbelow = 4; $subjabove = 6.5;
# object line is 6.5 units above
$objabove = 6.5;
# indirect object line slants 2.5 charwidths to the right in x and y coords:
$iobjinc = 2.5*$charwidth;
while (){
chop;
print "\n";
if(/^#/){next;}
@f = split / +/;
#
# Type 1:
# ID htext x y
if($f[1] eq "htext" and $#f >= 6){
$words = join ' ',splice(@f,6);
$x1 = eval $f[2]; $y1 = eval $f[3];
$lmargin = eval $f[4]; $rmargin = eval $f[5];
# print "*****x1 is $x1 after eval of $f[2], y1 is $y1 after eval of $f[3]\n";
$nchars = length $words; # note problem with multibyte chars...
$xsize = $charwidth * $nchars + $lmargin + $rmargin;
$x2 = sprintf("%.2f", $x1+$xsize);
print "\n";
print " \n";
print "\n";
print "\t$words\n";
print "\t \n";
$lastx = $x2; $lasty = $y1;
$x1{$f[0]} = $x1; $y1{$f[0]} = $y1;
$x2{$f[0]} = $lastx; $y2{$f[0]} = $lasty;
}
#
# Type 2:
# ID otext x y
elsif($f[1] eq "otext" and $#f >= 4){
$words = join ' ',splice(@f,4);
$x1 = eval $f[2]; $y1 = eval $f[3];
# print "*****x1 is $x1 after eval of $f[2], y1 is $y1 after eval of $f[3]\n";
$nchars = length $words; # note problem with multibyte chars...
$xsize = $charwidth * $nchars + $omargin + $charwidth;
# line at 45 degrees, x and y increment is sqrt(d^2/2)
$xinc = sprintf("%.2f",sqrt(($xsize**2)/2));
$x2 = sprintf("%.2f",$x1+$xinc); $y2 = sprintf("%.2f",$y1+$xinc);
$pid = "P$f[0]";
print "\n";
print " \n";
print "\n";
print "$words \n";
print "\t \n";
$lastx = $x2; $lasty = $y1;
$x1{$f[0]} = $x1; $y1{$f[0]} = $y1;
$x2{$f[0]} = $x2; $y2{$f[0]} = $y2;
}
#
# Type 3:
# ID vtextdown x1 y1 lmargin rmargin string
if($f[1] eq "vtextdown" and $#f >= 6){
$words = join ' ',splice(@f,6);
$x1 = eval $f[2]; $y1 = eval $f[3];
$lmargin = eval $f[4]; $rmargin = eval $f[5];
# print "*****x1 is $x1 after eval of $f[2], y1 is $y1 after eval of $f[3]\n";
$nchars = length $words; # note problem with multibyte chars...
$xsize = $charwidth * $nchars + $lmargin + $rmargin;
$x2 = $x1;
$y2 = sprintf("%.2f", $y1+$xsize);
$pid = "P$f[0]";
print "\n";
print " \n";
print "\n";
print "$words \n";
print "\t \n";
$lastx = $x2; $lasty = $y2;
$x1{$f[0]} = $x1; $y1{$f[0]} = $y1;
$x2{$f[0]} = $x2; $y2{$f[0]} = $y2
}
#
# Type 4:
# ID vtextup x1 y1 lmargin rmargin string
if($f[1] eq "vtextup" and $#f >= 6){
$words = join ' ',splice(@f,6);
$x1 = eval $f[2]; $y1 = eval $f[3];
$lmargin = eval $f[4]; $rmargin = eval $f[5];
# print "*****x1 is $x1 after eval of $f[2], y1 is $y1 after eval of $f[3]\n";
$nchars = length $words; # note problem with multibyte chars...
$xsize = $charwidth * $nchars + $lmargin + $rmargin;
$x2 = $x1;
$y2 = sprintf("%.2f", $y1-$xsize);
$pid = "P$f[0]";
print "\n";
print " \n";
print "\n";
print "$words \n";
print "\t \n";
$lastx = $x2; $lasty = $y2;
$x1{$f[0]} = $x1; $y1{$f[0]} = $y1;
$x2{$f[0]} = $x2; $y2{$f[0]} = $y2
}
#
# Type 5:
# ID line x1 y1 x2 y2
# line from arbitrary point to arbitrary point
# note that y origin is upper left corner...
elsif($f[1] eq "line" and $#f == 5){
$x1 = eval $f[2]; $y1 = eval $f[3]; $x2 = eval $f[4]; $y2 = eval $f[5];
print "\n";
print " \n";
$x1{$f[0]} = $x1; $y1{$f[0]} = $y1;
$x2{$f[0]} = $x2; $y2{$f[0]} = $y2;
}
}
print " \n";