summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/latex/csvtools/csvtools.pl
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/doc/latex/csvtools/csvtools.pl')
-rwxr-xr-xMaster/texmf-dist/doc/latex/csvtools/csvtools.pl1995
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;