diff options
Diffstat (limited to 'Master/texmf-dist/doc/latex/csvtools/csvtools.pl')
-rwxr-xr-x | Master/texmf-dist/doc/latex/csvtools/csvtools.pl | 1995 |
1 files changed, 1995 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/csvtools/csvtools.pl b/Master/texmf-dist/doc/latex/csvtools/csvtools.pl new file mode 100755 index 00000000000..131134124e7 --- /dev/null +++ b/Master/texmf-dist/doc/latex/csvtools/csvtools.pl @@ -0,0 +1,1995 @@ +#!/usr/bin/perl -w + +# File : csvtools.pl +# Author : Dr Nicola Talbot +# Date : 26 June 2007 +# Description : Perl script to accompany csvtools.sty +# : Allows you to substitute \CSVtotabular, \CSVtolongtable and \applyCSVfile commands with the appropriate LaTeX code +# Version : 0.6b (1 September 2006). + +# usage : csvtools <in-file> <out-file> + +if ($#ARGV != 1) +{ + die "Syntax : $0 <in-file> <out-file>\n"; +} + +($FILENAME,$OUTPUT) = @ARGV; + +open FILENAME or die "Can't open '$FILENAME'\n"; + +$ext = substr($FILENAME, -4); + +if (($ext eq ".tex") or ($ext eq ".dtx") or ($ext eq ".ltx")) +{ + $LOGFILE = substr($FILENAME,0,length($FILENAME)-4) . ".log"; +} +else +{ + $LOGFILE = $FILENAME . ".log"; +} + +open LOGFILE or die "Can't open log file '$LOGFILE'. Make sure you run LaTeX before using $0\n"; + +while (<LOGFILE>) +{ + if (/\\c@([a-zA-Z]+)=\\count/) + { + $counter{$1} = 0; + } +} + +$counter{'csvrownumber'} = 0; + +close LOGFILE; + +open OUTPUT, ">$OUTPUT" or die; + +# global csvsort options + +$globalsort{'verbose'}=1; +$globalsort{'sort'}='alphabetical ascending'; +$globalsort{'variable'}='\field{1}'; +$globalsort{'sfirstdataline'}=1; +$globalsort{'firstdataline'}=2; + +$keyvaldefaults{'verbose'}='true'; + +$csvpieouterlabel="\\field{1}"; +$csvpieinnerlabel="\\field{2}\\%"; +$separator=","; + +while (<FILENAME>) +{ + $restofline = $_; + local($comment) = ""; + + if ($restofline=~m/(\\*)%/) + { + $n = length($1); + + if ($n%2 == 0) + { + $restofline = "$`$1"; + $comment = "%$'"; + $_ = $restofline; + } + } + + if ($restofline=~/\\setcsvseparator\s*{([^}]*)}/) + { + $separator=$1 if defined($1); + } + + if ($restofline=~/\\renewcommand\*?\s*{?\\csvpieinnerlabel}?/) + { + print OUTPUT $`; + + $restofline=$'; + $lineno=$.; + + ($csvpieinnerlabel,$restofline,$done)=&getnextgroup($restofline); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $restofline .= $nextline; + ($csvpieinnerlabel,$restofline,$done)=&getnextgroup($restofline); + } + else + { + die "Unexpected EOF while parsing \\renewcommand on line $lineno\n"; + } + } + + $_ = $restofline; + } + + if ($restofline=~/\\renewcommand\*?\s*{?\\csvpieouterlabel}?/) + { + print OUTPUT $`; + + $restofline=$'; + $lineno=$.; + + ($csvpieouterlabel,$restofline,$done)=&getnextgroup($restofline); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $restofline .= $nextline; + ($csvpieouterlabel,$restofline,$done)=&getnextgroup($restofline); + } + else + { + die "Unexpected EOF while parsing \\renewcommand on line $lineno\n"; + } + } + + $_ = $restofline; + } + + while ($restofline=~/\\stepcounter(.*)/) + { + $line = $_; + + ($ctr,$restofline,$done) = &getnextgroup($1); + + $startline=$.; + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + $restofline = $restofline . $nextline; + + ($ctr,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning first argument to \\stepcounter on line $startline\n"; + } + } + + $counter{$ctr}++; + + $_ = $line; + } + + $restofline = $_; + + while ($restofline=~/\\refstepcounter(.*)/) + { + $line = $_; + + ($ctr,$restofline,$done) = &getnextgroup($1); + + $startline=$.; + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + $restofline = $restofline . $nextline; + + ($ctr,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning first argument to \\stepcounter on line $startline\n"; + } + } + + $counter{$ctr}++; + + $_ = $line; + } + + $restofline = $_; + + while ($restofline=~/\\setcounter(.*)/) + { + $line = $_; + + ($ctr,$restofline,$done) = &getnextgroup($1); + + $startline=$.; + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + $restofline = $restofline . $nextline; + + ($ctr,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning first argument to \\stepcounter on line $startline\n"; + } + } + + ($num,$restofline,$done) = &getnextgroup($restofline); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + $restofline = $restofline . $nextline; + + ($num,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning second argument to \\stepcounter on line $startline\n"; + } + } + + $num=~s/\\value{(.+)}/$counter{$1}/; + + $counter{$ctr} = $num; + + $_ = $line; + } + + $restofline = $_; + + while ($restofline=~/\\addtocounter(.*)/) + { + $line = $_; + + ($ctr,$restofline,$done) = &getnextgroup($1); + + $startline=$.; + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + $restofline = $restofline . $nextline; + + ($ctr,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning first argument to \\stepcounter on line $startline\n"; + } + } + + ($num,$restofline,$done) = &getnextgroup($restofline); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + $restofline = $restofline . $nextline; + + ($num,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning second argument to \\stepcounter on line $startline\n"; + } + } + + $num=~s/\\value{(.+)}/$counter{$1}/; + + $counter{$ctr} = $counter{$ctr} + $num; + + $_ = $line; + } + + $restofline = $_; + + while ($restofline=~/^(.*)\\csvGetEntry(.*)$/) + { + $start = $1; + $restofline = $2; + + ($ctr,$restofline,$done) = &getnextgroup($restofline); + + $startline=$.; + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $restofline = $restofline . $nextline; + + ($ctr,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning first argument to \\csvGetEntry on line $startline\n"; + } + } + + ($entry,$restofline,$done) = &getnextgroup($restofline); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $restofline = $restofline . $nextline; + + ($entry,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning first argument to \\csvGetEntry on line $startline\n"; + } + } + $_ = $start . "\\csname $entry\\roman{$ctr}\\endcsname" . $restofline; + #$_ = $start. $data{$entry}[$counter{$ctr}] . $restofline; + } + + $restofline = $_; + + while ($restofline=~/\\usepackage(.*)/) + { + $line = $_; + + $startline=$.; + + $restofline = $1; + + $options = ''; + + if ($restofline=~/^\s*\[/) + { + ($options,$restofline,$done) = &getnextoptionalgroup($restofline); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + $restofline = $restofline . $nextline; + + ($options,$restofline,$done) = &getnextoptionalgroup($restofline); + } + else + { + die "EOF found whilst scanning optional argument to \\usepackage on line $startline\n"; + } + } + } + + + ($package,$restofline,$done) = &getnextgroup($restofline); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + $restofline = $restofline . $nextline; + + ($package,$restofline,$done) = &getnextgroup($restofline); + } + else + { + die "EOF found whilst scanning argument to \\usepackage on line $startline\n"; + } + } + + if ($package eq 'csvsort' and $options) + { + %hash = &getKeyValues($options,%keyvaldefaults); + + foreach $key (keys(%hash)) + { + $globalsort{$key}=$hash{$key}; + } + } + + $_ = $line; + } + + $restofline = $_; + + if (/^(.*)\\CSVtotabular(.*)$/) + { + print OUTPUT "$1$comment"; + $comment=""; + + $line = $2; + $lineno = $.; + + ($csvname,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for CVS filename on line $lineno\n"; + } + } + + $csvname=~s/\\csname (.*)\\roman{(.*)}\\endcsname/$data{$1}[$counter{$2}]/; + + $line = $restofline; + + ($alignment,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $restofline . $nextline; + + ($alignment,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for CVS column alignment on line $lineno\n"; + } + } + + $line = $restofline; + + ($FIRST,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $restofline . $nextline; + + ($FIRST,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\CSVtotabular third argument on line $lineno\n"; + } + } + + $line = $restofline; + + ($MIDDLE,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $restofline . $nextline; + + ($MIDDLE,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\CSVtotabular fourth argument on line $lineno\n"; + } + } + + $line = $restofline; + + ($LAST,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $restofline . $nextline; + + ($LAST,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\CSVtotabular fifth argument on line $lineno\n"; + } + } + + &csvtotabular($csvname, $alignment, $FIRST, $MIDDLE, $LAST, + "tabular"); + + print OUTPUT "$restofline\n"; + } + elsif (/^(.*)\\CSVtolongtable(.*)$/) + { + print OUTPUT "$1$comment"; + $comment=""; + + $line = $2; + $lineno = $.; + + ($csvname,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $line . $nextline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for CVS filename on line $lineno\n"; + } + } + + $csvname=~s/\\csname (.*)\\roman{(.*)}\\endcsname/$data{$1}[$counter{$2}]/; + + $line = $restofline; + + ($alignment,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $restofline . $nextline; + + ($alignment,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for CVS column alignment on line $.\n"; + } + } + + $line = $restofline; + + ($FIRST,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $restofline . $nextline; + + ($FIRST,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\CSVtolongtable third argument on line $.\n"; + } + } + + $line = $restofline; + + ($MIDDLE,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $restofline . $nextline; + + ($MIDDLE,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\CSVtolongtable fourth argument on line $.\n"; + } + } + + $line = $restofline; + + ($LAST,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline = <FILENAME>) + { + $line = $restofline . $nextline; + + ($LAST,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\CSVtolongtable fifth argument on line $.\n"; + } + } + + &csvtotabular($csvname, $alignment, $FIRST, $MIDDLE, $LAST, + "longtable"); + + print OUTPUT "$restofline\n"; + } + elsif (/^(.*)\\applyCSVfile(\*)?(.*)$/) + { + print OUTPUT "$1$comment"; + $comment=""; + + $starred = defined($2); + + $restofline = $3; + $lineno = $.; + + $restofline = &eatinitialspaces($restofline); + $restofline = &eatcomments($restofline); + + $startrow = $starred ? 1 : 2; + + if (/^\[([0-9]+)\](.*)/) + { + $startrow = $1; + + $restofline = $2; + } + + $line=$restofline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\applyCSVfile*[$startrow] first argument on line $lineno\n"; + } + } + + $csvname=~s/\\csname (.*)\\roman{(.*)}\\endcsname/$data{$1}[$counter{$2}]/; + + $line=$restofline; + + ($body,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($body,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\applyCSVfile*[$startrow] second argument on line $lineno\n"; + } + } + + if ($starred) + { + &applyCSVfilestar($csvname, $body, $startrow); + } + else + { + &applyCSVfile($csvname, $body, $startrow); + } + + print OUTPUT "$restofline\n"; + } + elsif (/^(.*)\\sortapplyCSVfile(\*)?(.*)$/) + { + print OUTPUT "$1$comment"; + $comment=""; + + $starred = defined($2); + + $restofline = $3; + $lineno = $.; + + $restofline = &eatinitialspaces($restofline); + $restofline = &eatcomments($restofline); + + $line=$restofline; + + $options = ''; + + if ($restofline=~/^\s*\[/) + { + ($options,$restofline,$done) = &getnextoptionalgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($options,$restofline,$done) = &getnextoptionalgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortapplyCSVfile optional argument on line $lineno\n"; + } + } + } + + $line=$restofline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortapplyCSVfile argument on line $lineno\n"; + } + } + + $csvname=~s/\\csname (.*)\\roman{(.*)}\\endcsname/$data{$1}[$counter{$2}]/; + + $line=$restofline; + + ($body,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($body,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortapplyCSVfile argument on line $lineno\n"; + } + } + + if ($starred) + { + &sortapplyCSVfilestar($csvname, $body, $options); + } + else + { + &sortapplyCSVfile($csvname, $body, $options); + } + + print OUTPUT "$restofline\n"; + } + elsif (/^(.*)\\sortCSVto(tabular|longtable)(.*)$/) + { + print OUTPUT "$1$comment"; + $comment=""; + + $envname = $2; + $restofline = $3; + $lineno = $.; + + $restofline = &eatinitialspaces($restofline); + $restofline = &eatcomments($restofline); + + $line=$restofline; + + $options = ''; + + if ($restofline=~/^\s*\[/) + { + ($options,$restofline,$done) = &getnextoptionalgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($options,$restofline,$done) = &getnextoptionalgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortCSVto$envname first argument on line $lineno\n"; + } + } + } + + $line=$restofline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortCSVto$envname argument on line $lineno\n"; + } + } + + $csvname=~s/\\csname (.*)\\roman{(.*)}\\endcsname/$data{$1}[$counter{$2}]/; + + $line=$restofline; + + ($align,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($align,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortCSVto$envname argument on line $lineno\n"; + } + } + + $line=$restofline; + + ($headrow,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($headrow,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortCSVto$envname argument on line $lineno\n"; + } + } + + $line=$restofline; + + ($midrows,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($midrows,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortCSVto$envname argument on line $lineno\n"; + } + } + + $line=$restofline; + + ($lastrow,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($lastrow,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\sortCSVto$envname argument on line $lineno\n"; + } + } + + &sortCSVtotabular($csvname,$align,$headrow,$midrows,$lastrow, + $envname,$options); + + print OUTPUT "$restofline\n"; + } + elsif (/^(.*)\\csvpiechart(\*)?(.*)$/) + { + print OUTPUT "$1$comment"; + $comment=""; + + $lineno = $.; + + $starred = defined($2); + + $restofline = $3; + + $restofline = &eatinitialspaces($restofline); + $restofline = &eatcomments($restofline); + + $startrow= $starred ? 1 : 2; + + $line=$restofline; + + ($options,$restofline,$done) = &getnextoptionalgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($options,$restofline,$done) = &getnextoptionalgroup($line); + } + else + { + die "EOF found whilst scanning for \\csvpiechart optional argument on line $lineno\n"; + } + } + + $line=$restofline; + + ($label,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($label,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\csvpiechart second argument on line $lineno\n"; + } + } + + $line=$restofline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + + while (!$done) + { + if ($nextline= <FILENAME>) + { + $line = $restofline . $nextline; + + ($csvname,$restofline,$done) = &getnextgroup($line); + } + else + { + die "EOF found whilst scanning for \\csvpiechart second argument on line $lineno\n"; + } + } + + print OUTPUT "\\csvpiesetkeys{$options}%\n"; + + if ($options=~m/firstrow\s*=\s*(\d+)/) + { + $startrow=$1; + } + + if ($starred) + { + &csvpiechartstar($label, $csvname, $startrow); + } + else + { + &csvpiechart($label, $csvname, $startrow); + } + + print OUTPUT "$restofline\n"; + } + else + { + print OUTPUT "$_$comment"; + } +} + +sub doapplyCSV{ + local($csvrow, $body, @idx, %HoH) = @_; + local($row, $entry); + + $counter{'csvrownumber'} = 0; + print OUTPUT "\\setcounter{csvrownumber}{0}\\relax\n"; + + foreach ($row=1; $row <= $csvrow; $row++) + { + print "."; + + local($THISROW) = $body; + + $THISROW = &csvSaveEntry($THISROW,$row,%HoH); + + foreach $entry ( keys %{$HoH[$row]}) + { + $replacementval=$HoH[$row]{$entry}; + + $THISROW =~ s/\\insertbyname{$entry}/$replacementval/g; + + $THISROW =~ s/\\insert$entry/$replacementval/g; + + local($column) = $idx{$entry}+1; + + $THISROW =~ s/\\field{(\d+)}/$1eq$column?$replacementval:$&/emg; + + $THISROW = &ifnextrowlast($THISROW, ($row==$csvrow-1)); + } + + print OUTPUT "\\refstepcounter{csvrownumber}\\relax\n$THISROW"; + $counter{'csvrownumber'}++; + } +} + +sub doapplyCSVstar{ + local($body, $csvrow, $numcols, @entry) = @_; + local($row,$column); + + print OUTPUT "\\setcounter{csvrownumber}{0}\\relax\n"; + $counter{'csvrownumber'} = 0; + + for ($row=0; $row < $csvrow; $row++) + { + print "."; + + $THISROW = $body; + + for ($column=0; $column < $numcols; $column++) + { + $replacementval=$entry[$row][$column]; + + $THISROW =~ s/\\field{(\d+)}/$1eq$column+1?$replacementval:$&/emg; + + $THISROW = &ifnextrowlast($THISROW, ($row==$csvrow-1)); + } + + print OUTPUT "\\refstepcounter{csvrownumber}$THISROW"; + $counter{'csvrownumber'}++; + } + +} + +sub getCSVvalues{ + local($CSVFILE, $startrow) = @_; + local(@idx, %HoH, @fields); + + open FH, $CSVFILE or die "Can't open file '$CSVFILE'\n"; + + local ($csvrow)=0; + + while (<FH>) + { + if ($. == 1) + { + # get header row + + chop; + + @fields = &getEntries($_); + + local($numcols) = 0; + + foreach $field (@fields) + { + $idx{$field} = $numcols; + + $numcols++; + } + } + elsif ($. >= $startrow) + { + next unless /$separator/; + + chop; + + $csvrow++; + $rec = {}; + + $HoH[$csvrow] = $rec; + + local(@entries) = &getEntries($_); + + local ($i) = 0; + + foreach $e (@entries) + { + $rec->{$fields[$i]} = $e; + $i++; + } + } + } + + close FH; + + return ($csvrow, @idx, %HoH); +} + +sub getCSVvaluesstar +{ + local($CSVFILE, $startrow) = @_; + open FH, $CSVFILE or die "Can't open file '$CSVFILE'\n"; + + $csvrow=0; + + while (<FH>) + { + if ($. >= $startrow) + { + chop; + + @fields = &getEntries($_); + + $numcols = 0; + + foreach $field (@fields) + { + $entry[$csvrow][$numcols] = $field; + + $numcols++; + } + + $csvrow++; + } + } + + close FH; + + return ($csvrow, $numcols, @entry); +} + +sub csvpiechart +{ + local($value, $CSVFILE, $startrow) = @_; + + print "Converting \\csvpiechart[$options]{$label}{$csvname}\n"; + print OUTPUT "% \\csvpiechart[$options]{$label}{$csvname} converted using csvtools.pl\n"; + print OUTPUT "%>> START INSERT\n"; + + # read in data from CSV file + local($csvrow, @idx, %HoH) = &getCSVvalues($CSVFILE,$startrow); + + # first compute parameters + + print OUTPUT "\\edef\\csvstartang{\\thecsvstartangle}\\relax\n"; + $body = "\\csvsetsegmentparams{\\thecsvrownumber}{$value}\\relax\n"; + + &doapplyCSV($csvrow, $body, @idx, %HoH); + + print OUTPUT "\\setcounter{csvstartangle}{\\csvstartang}\\relax\n"; + + # compute offsets for cutaway segments + + print OUTPUT "\\ifthenelse{\\equal{\\csvpiecutaways}{}}{}{\\csvcomputeoffsets}\\relax\n"; + + # now do the pie chart + + print OUTPUT "\\begin{tikzpicture}\n"; + + $body = "\\renewcommand*{\\csvpieinnerlabel}{$csvpieinnerlabel}\n"; + $body .= "\\renewcommand*{\\csvpieouterlabel}{$csvpieouterlabel}\n"; + $body .= "\\csvpiesegment{$value}\n"; + + &doapplyCSV($csvrow, $body, %HoH); + + print OUTPUT "\\end{tikzpicture}"; + print OUTPUT "%<< END INSERT\n"; + print "\n"; +} + +sub csvpiechartstar +{ + local($value, $CSVFILE, $startrow) = @_; + + print "Converting \\csvpiechart*[$options]{$label}{$csvname}\n"; + print OUTPUT "% \\csvpiechart*[$options]{$label}{$csvname} converted using csvtools.pl\n"; + print OUTPUT "%>> START INSERT\n"; + + local($csvrow, $numcols, @entry) = &getCSVvaluesstar($CSVFILE, $startrow); + + # first compute parameters + + print OUTPUT "\\edef\\csvstartang{\\thecsvstartangle}\\relax\n"; + $body = "\\csvsetsegmentparams{\\thecsvrownumber}{$value}\\relax\n"; + + &doapplyCSVstar($body, $csvrow, $numcols, @entry); + + print OUTPUT "\\setcounter{csvstartangle}{\\csvstartang}\\relax\n"; + + # compute offsets for cutaway segments + + print OUTPUT "\\ifthenelse{\\equal{\\csvpiecutaways}{}}{}{\\csvcomputeoffsets}\\relax\n"; + + $body = "\\renewcommand*{\\csvpieinnerlabel}{$csvpieinnerlabel}\\relax\n"; + $body .= "\\renewcommand*{\\csvpieouterlabel}{$csvpieouterlabel}\\relax\n"; + $body .= "\\csvpiesegment{$value}\\relax\n"; + + print OUTPUT "\\begin{tikzpicture}\n"; + + &doapplyCSVstar($body, $csvrow, $numcols, @entry); + + print OUTPUT "\\end{tikzpicture}"; + print OUTPUT "%<< END INSERT\n"; + print "\n"; +} + +sub applyCSVfile +{ + my ($CSVFILE,$body,$startrow) = @_; + + print "Converting \\applyCSVfile{$CSVFILE}"; + print OUTPUT "\% \\applyCSVfile{$CSVFILE}... converted using csvtools.pl\n"; + print OUTPUT "\%>> START INSERT\n"; + + # read in data from CSV file + local($csvrow, @idx, %HoH) = &getCSVvalues($CSVFILE,$startrow); + + # apply data + + &doapplyCSV($csvrow, $body, @idx, %HoH); + + print "\n"; + + print OUTPUT "\%<< END INSERT\n"; +} + +sub sortapplyCSVfile +{ + my ($CSVFILE,$body,$options) = @_; + + print "Converting \\sortapplyCSVfile{$CSVFILE}"; + print OUTPUT "\% \\sortapplyCSVfile{$CSVFILE}... converted using csvtools.pl\n"; + print OUTPUT "\%>> START INSERT\n"; + + # get options + %hash = &getKeyValues($options) if $options; + + local($startrow) = defined($hash{'firstdataline'}) + ? $hash{'firstdataline'} + : $globalsort{'firstdataline'}; + + local ($sortorder) = $hash{'sort'}; + + # read in data from CSV file + local($csvrow, @idx, %HoH) = &getCSVvalues($CSVFILE,$startrow); + + # get sort variable + + local($variable) = defined($hash{'variable'}) + ? $hash{'variable'} + : $globalsort{'variable'}; + + local(@rowdata)=(); + + print OUTPUT "\\bgroup\n"; + + # set field labels + + foreach $entry (keys %{$HoH[1]}) + { + print OUTPUT "\\setcsvfieldlabel{"; + print OUTPUT ($idx{$entry}+1).'}{'; + print OUTPUT "$entry}%\n"; + } + + print OUTPUT "\\def\\csvsortlist{%\n"; + + # construct list + + foreach ($row=1; $row <= $csvrow; $row++) + { + print "."; + + local($sortkey) = $variable; + + $sortkey = &csvSaveEntry($sortkey,$row,%HoH); + + foreach $entry ( keys %{$HoH[$row]}) + { + $replacementval=$HoH[$row]{$entry}; + + $sortkey =~ s/\\insertbyname{$entry}/$replacementval/g; + + $sortkey =~ s/\\insert$entry/$replacementval/g; + + local($column) = $idx{$entry}+1; + + $rowdata[$idx{$entry}] = $replacementval; + + $sortkey =~ s/\\field{(\d+)}/$1eq$column?$replacementval:$&/emg; + } + + print OUTPUT "{$sortkey}{".join($separator,@rowdata)."}"; + + print OUTPUT ($row == $csvrow ? "%\n" : ",%\n"); + } + + print OUTPUT "}%\n"; + + print OUTPUT "\\sortapplyCSVdata"; + + if (defined($sortorder)) + { + print OUTPUT "[$sortorder]"; + } + + print OUTPUT "{\\csvsortlist}{%\n"; + + print OUTPUT "$body}%\n"; + + print OUTPUT "\\egroup\n"; + print OUTPUT "\%<< END INSERT\n"; + + print "\n"; +} + +sub sortapplyCSVfilestar +{ + my ($CSVFILE,$body,$options) = @_; + + print "Converting \\sortapplyCSVfile*{$CSVFILE}"; + print OUTPUT "\% \\sortapplyCSVfile*{$CSVFILE}... converted using csvtools.pl\n"; + print OUTPUT "\%>> START INSERT\n"; + + # get options + %hash = &getKeyValues($options) if $options; + + local($startrow) = defined($hash{'sfirstdataline'}) + ? $hash{'sfirstdataline'} + : $globalsort{'sfirstdataline'}; + + local ($sortorder) = $hash{'sort'}; + + local($csvrow, $numcols, @entry) = &getCSVvaluesstar($CSVFILE, $startrow); + + # get sort variable + + local($variable) = defined($hash{'variable'}) + ? $hash{'variable'} + : $globalsort{'variable'}; + + local(@rowdata)=(); + + print OUTPUT "\\bgroup\n"; + + print OUTPUT "\\def\\csvsortlist{%\n"; + + # construct list + + for ($row=0; $row < $csvrow; $row++) + { + print "."; + + local($sortkey) = $variable; + + for ($column=0; $column < $numcols; $column++) + { + $replacementval=$entry[$row][$column]; + + $sortkey =~ s/\\field{(\d+)}/$1eq$column+1?$replacementval:$&/emg; + $rowdata[$column] = $replacementval; + } + + print OUTPUT "{$sortkey}{".join($separator,@rowdata)."}"; + + print OUTPUT ($row == $csvrow-1 ? "%\n" : ",%\n"); + } + + print OUTPUT "}%\n"; + + print OUTPUT "\\sortapplyCSVdata*"; + + if (defined($sortorder)) + { + print OUTPUT "[$sortorder]"; + } + + print OUTPUT "{\\csvsortlist}{%\n"; + + print OUTPUT "$body}%\n"; + + print OUTPUT "\\egroup\n"; + + print "\n"; + + print OUTPUT "\%<< END INSERT\n"; +} + +sub sortCSVtotabular +{ + my ($CSVFILE,$align,$headrow,$midrows,$lastrow,$envname,$options) = @_; + + print "Converting \\sortCSVto${envname}{$CSVFILE}"; + print OUTPUT "\% \\sortCSVto${envname}{$CSVFILE}... converted using csvtools.pl\n"; + print OUTPUT "\%>> START INSERT\n"; + + # get options + %hash = &getKeyValues($options) if $options; + + local($startrow) = defined($hash{'firstdataline'}) + ? $hash{'firstdataline'} + : $globalsort{'firstdataline'}; + + local ($sortorder) = $hash{'sort'}; + + # read in data from CSV file + local($csvrow, @idx, %HoH) = &getCSVvalues($CSVFILE,$startrow); + + # get sort variable + + local($variable) = defined($hash{'variable'}) + ? $hash{'variable'} + : $globalsort{'variable'}; + + local(@rowdata)=(); + + print OUTPUT "\\bgroup\n"; + + # set field labels + + foreach $entry (keys %{$HoH[1]}) + { + print OUTPUT "\\setcsvfieldlabel{"; + print OUTPUT ($idx{$entry}+1).'}{'; + print OUTPUT "$entry}%\n"; + } + + print OUTPUT "\\def\\csvsortlist{%\n"; + + # construct list + + foreach ($row=1; $row <= $csvrow; $row++) + { + print "."; + + local($sortkey) = $variable; + + $sortkey = &csvSaveEntry($sortkey,$row,%HoH); + + foreach $entry ( keys %{$HoH[$row]}) + { + $replacementval=$HoH[$row]{$entry}; + + $sortkey =~ s/\\insertbyname{$entry}/$replacementval/g; + + $sortkey =~ s/\\insert$entry/$replacementval/g; + + local($column) = $idx{$entry}+1; + + $rowdata[$idx{$entry}] = $replacementval; + + $sortkey =~ s/\\field{(\d+)}/$1eq$column?$replacementval:$&/emg; + } + + print OUTPUT "{$sortkey}{".join($separator,@rowdata)."}"; + + print OUTPUT ($row == $csvrow ? "%\n" : ",%\n"); + } + + print OUTPUT "}%\n"; + + if (defined($sortorder)) + { + print OUTPUT "\\setkeys{csvsort.sty}{sort=$sortorder}"; + } + + print OUTPUT "\\sortCSVdatatotabular"; + + print OUTPUT "{$csvrow}{\\csvsortlist}{$align}%\n"; + print OUTPUT "{$headrow}%\n"; + print OUTPUT "{$midrows}%\n"; + print OUTPUT "{$lastrow}%\n"; + print OUTPUT "{$envname}%\n"; + + print OUTPUT "\\egroup\n"; + print OUTPUT "\%<< END INSERT\n"; + + print "\n"; +} + +sub csvSaveEntry +{ + my ($STR,$row,%HoH) = @_; + + $rowctr = "csvrownumber"; + + while (($pos = index($STR, "\\csvSaveEntry")) > -1) + { + $start = substr($STR,0,$pos); + $restofline = substr($STR,$pos+13); + + $restofline = &eatcomments($restofline); + $restofline = &eatinitialspaces($restofline); + + if (substr($restofline,0,1) eq "[") + { + if (($i = index($restofline,"]")) > -1) + { + $rowctr = substr($restofline, 1, $i-1); + + $restofline = substr($restofline, $i+1); + } + else + { + die "unmatched [ in \\csvSaveEntry\n"; + } + + $row = $counter{$rowctr}; + } + + ($group,$restofline,$done) = &getnextgroup($restofline); + + if (!$done) + { + die "argument to \\csvSaveEntry[$rowctr] not found in >>$restofline<<\n"; + } + + $val = $HoH[$row]{$group}; + + $STR = $start . "\\expandafter\\gdef\\csname $group\\roman{$rowctr}\\endcsname{$val}" . $restofline; + + $data{$group}[$row] = $HoH[$row]{$group}; + } + + return $STR; +} + +sub applyCSVfilestar +{ + my ($CSVFILE,$body,$startrow) = @_; + + print "Converting \\applyCSVfile*{$CSVFILE}"; + + $counter{'csvrownumber'} = 0; + local($csvrow, $numcols, @entry) = &getCSVvaluesstar($CSVFILE, $startrow); + + &doapplyCSVstar($body, $csvrow, $numcols, @entry); + + print "\n"; + + print OUTPUT "\%<< END INSERT\n"; +} + +sub csvtotabular +{ + my ($CSVFILE,$ALIGN,$START,$MID,$END,$environment) = @_; + + print "Converting \\CSVtotabular{$CSVFILE}"; + + print OUTPUT "\% \\CSVtotabular{$CSVFILE}... converted using $0\n"; + print OUTPUT "\%>> START INSERT\n"; + + # read in data from CSV file + local($csvrow, @idx, %HoH) = &getCSVvalues($CSVFILE,2); + + print OUTPUT "\\setcounter{csvrownumber}{0}%\n"; + $counter{csvrownumber} = 0; + print OUTPUT "\\begin{$environment}{$ALIGN}\n"; + + print OUTPUT "$START"; + + foreach ($row=1; $row <= $csvrow; $row++ ) + { + print "."; + + if ($row == $csvrow) + { + $THISROW=$END; + } + else + { + $THISROW=$MID; + } + + foreach $entry ( keys %{$HoH[$row]}) + { + $replacementval=$HoH[$row]{$entry}; + + $THISROW =~ s/\\insertbyname{$entry}/$replacementval/g; + + $THISROW =~ s/\\insert$entry/$replacementval/g; + + $column = $idx{$entry}; + + $THISROW =~ s/\\field{$column}/$replacementval/g; + + $THISROW = &ifnextrowlast($THISROW, ($row==$csvrow-1)); + } + + print OUTPUT "\\refstepcounter{csvrownumber}$THISROW"; + $counter{csvrownumber}++; + } + + print OUTPUT "\\end{$environment}"; + print OUTPUT "\%<< END INSERT\n"; + + print "\n"; +} + +sub ifnextrowlast +{ + my ($STR, $nextislast) = @_; + + if (($pos = index($STR, "\\ifnextrowlast")) > -1) + { + $strbegin = substr($STR,0,$pos); + $strend = substr($STR,$pos+14); + + ($firstarg,$strend,$done) = &getnextgroup($strend); + + if (!$done) + { + die "Can't find first argument to \\ifnextrowlast\n"; + } + + ($secondarg,$strend,$done) = &getnextgroup($strend); + + if (!$done) + { + die "Can't find second argument to \\ifnextrowlast\n"; + } + + if ($nextislast) + { + $STR = $strbegin . $firstarg . $strend; + } + else + { + $STR = $strbegin . $secondarg . $strend; + } + } + + return $STR; +} + +sub eatcomments +{ + local ($_) = @_; + + if (m/(\\{1}%[^%]*)*(\\*)%/) + { + $pre = $`; + $pre .= $1 if defined($1); + $pre .= $2; + + local($n) = length($2); + + if ($n%2 == 0) + { + $_ = $pre; + } + } + + return $_; +} + +sub eatinitialspaces +{ + local ($_) = @_; + +# while (substr($STR,0,1) eq " " or substr($STR,0,1) eq "\n" +# or substr($STR,0,1) eq "\r" or substr($STR,0,1) eq "\t") +# { +# $STR = substr($STR,1); +# } + + s/^(\s)*//sg; + + return $_; +} + +sub getnextgroup +{ + my($curline) = @_; + + $curline = &eatcomments($curline); + + $curline = &eatinitialspaces($curline); + + # check to see if current string is blank + + if ($curline!~/[^\s]+/m) + { + return ("",$curline,0); + } + + if (($group = substr($curline,0,1)) ne "{") + { + # next group hasn't been delimited with braces + # return first non-whitespace character + + $curline = substr($curline,1); + + # unless it's a backslash, in which case get command name + + if ($group eq "\\") + { + if ($curline=~/([a-zA-Z]+)(^[a-zA-Z].*)/m) + { + $group = $1; + + $curline = $2; + } + else + { + # command is made up of backslash followed by symbol + + $curline=~/([\W_0-9\s\\])(.*)/m; + + $group = $1; + + $curline = $2; + } + } + + return ($group,$curline,1); + } + + my $pos=index($curline, "{"); + my $startpos=$pos; + my $posopen=0; + my $posclose=0; + + my $bracelevel = 1; + + my $done=0; + + while (!$done) + { + $pos++; + + $posopen = index($curline, "{", $pos); + + # check to make sure it's not a \{ + + while ((substr($curline, $posopen-1,1) eq "\\") and ($posopen > 0)) + { + # count how many backlashes come before it. + + $i = $posopen-1; + + $numbs = 1; + + while ((substr($curline, $i-1,1) eq "\\") and ($i > 0)) + { + $numbs++; + $i--; + } + + # is $numbs is odd, we have a \{, otherwise we have \\{ + + if ($numbs%2 == 0) + { + last; + } + else + { + $posopen = index($curline, "{", $posopen+1); + } + } + + $posclose= index($curline, "}", $pos); + + # check to make sure it's not a \} + + while ((substr($curline, $posclose-1,1) eq "\\") and ($posclose > 0)) + { + # count how many backlashes come before it. + + $i = $posclose-1; + + $numbs = 1; + + while ((substr($curline, $i-1,1) eq "\\") and ($i > 0)) + { + $numbs++; + $i--; + } + + # is $numbs is odd, we have a \}, otherwise we have \\} + + if ($numbs%2 == 0) + { + last; + } + else + { + $posclose = index($curline, "}", $posclose+1); + } + } + + if (($posopen==-1) and ($posclose==-1)) + { + $done=1; + } + elsif ($posopen==-1) + { + $pos=$posclose; + + $bracelevel--; + + if ($bracelevel==0) + { + $group = substr($curline, $startpos+1, $pos-$startpos-1); + + $curline = substr($curline, $pos+1); + + return ($group,$curline,1); + } + } + elsif ($posclose==-1) + { + $pos=$posopen; + + $bracelevel++; + } + elsif ($posopen<$posclose) + { + $pos=$posopen; + + $bracelevel++; + } + elsif ($posclose<$posopen) + { + $pos=$posclose; + + $bracelevel--; + + if ($bracelevel==0) + { + $group = substr($curline, $startpos+1, $pos-$startpos-1); + + $curline = substr($curline, $pos+1); + + return ($group,$curline,1); + } + } + } + + # closing brace must be on another line + + return ("", $curline, 0); +} + +sub getnextoptionalgroup +{ + my($curline) = @_; + + $curline = &eatcomments($curline); + + $curline = &eatinitialspaces($curline); + + # check to see if current string is blank + + if ($curline!~/[^\s]+/m) + { + return ("","",0); + } + + if (($group = substr($curline,0,1)) ne "[") + { + # no optional argument present + return ("", $curline, 1); + } + + $posopen = index($curline, "["); + + # search for first occurance of ] + + $posclose = index($curline, "]"); + + if ($posclose < 0) + { + # closing bracket not on this line + return ("", $curline, 0); + } + + # is there a { in the substring? + + $group = substr($curline, $posopen, $posclose+1); + $contents = $group; + $restofline = substr($curline, $posclose+$posopen+1); + + while (($idx=index($group, "{")) > 0) + { + $post = substr($group, $idx); + + $subgroup=""; + ($subgroup,$remainder,$done) = &getnextgroup($post); + + if ($done) + { + $group = $remainder; + } + else + { + # ] is in a group, so look for next one + $posclose = index($restofline, "]"); + + if ($posclose < 0) + { + # closing bracket not on this line + return ("", $curline, 0); + } + else + { + $contents .= substr($restofline,0,$posclose); + $group = $contents; + } + } + } + + $contents=~s/^\[(.*)\]$/$1/; + + return ($contents, $restofline, 1); +} + +# get all entries in a row +# modified version of code given in Perl FAQ + +sub getEntries{ + local($row)=@_; + + @entries = (); + push(@entries, $+) while $row =~ m{ + "([^\"\\]*(?:\\.[^\"\\]*)*)"$separator? # groups the phrase inside the quotes + | ([^$separator]+)$separator? + | $separator + }gx; + push(@entries, undef) if substr($row,-1,1) eq $separator; + + @entries; +} + +# extract key=value pairs from list + +sub getKeyValues{ + local($list,%defaults)=@_; + local(%hash)=(); + + # remove leading commas and spaces + + $list=~s/^[\s,]*//; + + while ($list=~/^\s*([^,=]+)\s*/) + { + $key=$1; + + $value = ''; + + if ($list=~s/^\s*$key\s*=\s*{/{/) + { + ($value,$list,$done) = &getnextgroup($list); + } + elsif ($list=~s/^\s*$key\s*=\s*([^,]*)\s*//) + { + $value = $1; + } + elsif ($list=~s/^\s*$key\s*(,|$)//) + { + if (defined($defaults{$key})) + { + $value = $defaults{$key}; + } + else + { + print "don't know default value for $key key\n"; + } + } + + $hash{$key} = $value; + + # remove trailing commas + + $list=~s/^[\s,]*//; + } + + %hash; +} + +1; |