--- loncom/xml/lonplot.pm	2002/02/27 16:54:58	1.50
+++ loncom/xml/lonplot.pm	2002/03/22 14:48:00	1.59
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Dynamic plot
 #
-# $Id: lonplot.pm,v 1.50 2002/02/27 16:54:58 matthew Exp $
+# $Id: lonplot.pm,v 1.59 2002/03/22 14:48:00 matthew Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -29,7 +29,7 @@
 # 12/17 12/18 12/19 12/20 12/21 12/27 12/28 12/30 12/31 Matthew
 # 01/01/02 Matthew
 # 01/02 01/03 01/04 01/07 01/08 01/09 Matthew
-# 01/21 02/05 02/06 Matthew
+# 01/21 02/05 02/06 2/28Matthew
 
 package Apache::lonplot;
 
@@ -144,6 +144,8 @@ A <b>gnuplot</b> tag can contain the fol
     <dd> Allows specification of the x and y coordinate 'tics' on the axes.
 This is mostly used to adjust the grid lines when a grid is displayed.
 </dl>
+If you are having trouble with your plot, please read the help
+available on Plot Curve.
 ENDPLOTHELP
 
 my %gnuplot_defaults = 
@@ -360,8 +362,8 @@ first tag will be the X data and the sec
 </p>
     <dt> Curve Function
     <dd> The <b>function</b> tag allows you to specify the curve to be 
-plotted as a formula that gnuplot can understand.  Be careful using this
-tag - it is surprisingly easy to give gnuplot a function it cannot deal
+plotted as a formula that gnuplot can understand.  <b>Be careful using this
+tag.</b>  It is surprisingly easy to give gnuplot a function it cannot deal
 with properly.  Be explicit: 2*sin(2*3.141592*x/4) will work but
 2sin(2*3.141592x/4) will not.  If you do not receive any errors in the
 gnuplot data but still do not have an image produced, it is likely there
@@ -413,10 +415,7 @@ sub start_gnuplot {
 	     ('title','xlabel','ylabel','key','axis','label','curve',
 	      'xtics','ytics'));
     push (@Apache::lonxml::namespace,'lonplot');
-    if ($target eq 'web') {
-	my $inside = &Apache::lonxml::get_all_text("/gnuplot",$$parser[-1]);
-	$inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
-	&Apache::lonxml::newparser($parser,\$inside);
+    if ($target eq 'web' || $target eq 'tex') {
 	&get_attributes(\%plot,\%gnuplot_defaults,$parstack,$safeeval,
 			$tagstack->[-1]);
     } elsif ($target eq 'edit') {
@@ -441,23 +440,38 @@ sub end_gnuplot {
     &Apache::lonxml::deregister('Apache::lonplot',
 	('title','xlabel','ylabel','key','axis','label','curve'));
     my $result = '';
-    if ($target eq 'web') {
+    my $randnumber;
+    # need to call rand everytime start_script would evaluate, as the
+    # safe space rand number generator and the global rand generator 
+    # are not seperate
+    if ($target eq 'web' || $target eq 'tex' || $target eq 'grade' ||
+	$target eq 'answer') {
+      $randnumber=int(rand(1000));
+    }
+    if ($target eq 'web' || $target eq 'tex') {
 	&check_inputs(); # Make sure we have all the data we need
 	##
 	## Determine filename
 	my $tmpdir = '/home/httpd/perl/tmp/';
 	my $filename = $ENV{'user.name'}.'_'.$ENV{'user.domain'}.
-	    '_'.time.'_'.$$.int(rand(1000)).'_plot.data';
+	    '_'.time.'_'.$$.$randnumber.'_plot.data';
 	## Write the plot description to the file
-	&write_gnuplot_file($tmpdir,$filename);
+	&write_gnuplot_file($tmpdir,$filename,$target);
+	$filename = &Apache::lonnet::escape($filename);
 	## return image tag for the plot
-	$result .= <<"ENDIMAGE";
-<img src    = "/cgi-bin/plot.gif?$filename" 
+	if ($target eq 'web') {
+	    $result .= <<"ENDIMAGE";
+<img src    = "/cgi-bin/plot.gif?file=$filename&output=gif" 
      width  = "$plot{'width'}" 
      height = "$plot{'height'}"
      align  = "$plot{'align'}"
      alt    = "image should be /cgi-bin/plot.gif?$filename" />
 ENDIMAGE
+        } elsif ($target eq 'tex') {
+	    &Apache::lonnet::ssi('cgi-bin/plot.gif?file=$filename'.
+				 '&output=eps');
+	    $result = "$filename.eps";
+	}
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -469,7 +483,7 @@ ENDIMAGE
 sub start_xtics {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	&get_attributes(\%xtics,\%tic_defaults,$parstack,$safeeval,
 		    $tagstack->[-1]);
     } elsif ($target eq 'edit') {
@@ -489,7 +503,7 @@ sub start_xtics {
 sub end_xtics {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -500,7 +514,7 @@ sub end_xtics {
 sub start_ytics {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	&get_attributes(\%ytics,\%tic_defaults,$parstack,$safeeval,
 		    $tagstack->[-1]);
     } elsif ($target eq 'edit') {
@@ -520,7 +534,7 @@ sub start_ytics {
 sub end_ytics {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -532,7 +546,7 @@ sub end_ytics {
 sub start_key {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	&get_attributes(\%key,\%key_defaults,$parstack,$safeeval,
 		    $tagstack->[-1]);
     } elsif ($target eq 'edit') {
@@ -551,7 +565,7 @@ sub start_key {
 sub end_key {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -562,8 +576,9 @@ sub end_key {
 sub start_title {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	$title = &Apache::lonxml::get_all_text("/title",$$parser[-1]);
+	$title=&Apache::run::evaluate($title,$safeeval,$$parstack[-1]);
 	$title =~ s/\n/ /g;
 	if (length($title) > $max_str_len) {
 	    $title = substr($title,0,$max_str_len);
@@ -573,7 +588,7 @@ sub start_title {
 	my $text=&Apache::lonxml::get_all_text("/title",$$parser[-1]);
 	$result.=&Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	my $text=$$parser[-1]->get_text("/title");
 	$result.=&Apache::edit::rebuild_tag($token);
@@ -585,7 +600,7 @@ sub start_title {
 sub end_title {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -595,8 +610,9 @@ sub end_title {
 sub start_xlabel {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	$xlabel = &Apache::lonxml::get_all_text("/xlabel",$$parser[-1]);
+	$xlabel=&Apache::run::evaluate($xlabel,$safeeval,$$parstack[-1]);
 	$xlabel =~ s/\n/ /g;
 	if (length($xlabel) > $max_str_len) {
 	    $xlabel = substr($xlabel,0,$max_str_len);
@@ -606,7 +622,7 @@ sub start_xlabel {
 	my $text=&Apache::lonxml::get_all_text("/xlabel",$$parser[-1]);
 	$result.=&Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	my $text=$$parser[-1]->get_text("/xlabel");
 	$result.=&Apache::edit::rebuild_tag($token);	
@@ -618,7 +634,7 @@ sub start_xlabel {
 sub end_xlabel {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -629,8 +645,9 @@ sub end_xlabel {
 sub start_ylabel {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	$ylabel = &Apache::lonxml::get_all_text("/ylabel",$$parser[-1]);
+	$ylabel = &Apache::run::evaluate($ylabel,$safeeval,$$parstack[-1]);
 	$ylabel =~ s/\n/ /g;
 	if (length($ylabel) > $max_str_len) {
 	    $ylabel = substr($ylabel,0,$max_str_len);
@@ -640,7 +657,7 @@ sub start_ylabel {
 	my $text = &Apache::lonxml::get_all_text("/ylabel",$$parser[-1]);
 	$result .= &Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	my $text=$$parser[-1]->get_text("/ylabel");
 	$result.=&Apache::edit::rebuild_tag($token);
@@ -652,7 +669,7 @@ sub start_ylabel {
 sub end_ylabel {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -663,11 +680,12 @@ sub end_ylabel {
 sub start_label {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	my %label;
 	&get_attributes(\%label,\%label_defaults,$parstack,$safeeval,
 		    $tagstack->[-1]);
 	my $text = &Apache::lonxml::get_all_text("/label",$$parser[-1]);
+	$text = &Apache::run::evaluate($text,$safeeval,$$parstack[-1]);
 	$text =~ s/\n/ /g;
 	$text = substr($text,0,$max_str_len) if (length($text) > $max_str_len);
 	$label{'text'} = $text;
@@ -678,7 +696,7 @@ sub start_label {
 	my $text = &Apache::lonxml::get_all_text("/label",$$parser[-1]);
 	$result .= &Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	&Apache::edit::get_new_args
 	    ($token,$parstack,$safeeval,keys(%label_defaults));
@@ -692,7 +710,7 @@ sub start_label {
 sub end_label {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -705,7 +723,7 @@ sub start_curve {
     my $result='';
     &Apache::lonxml::register('Apache::lonplot',('function','data'));
     push (@Apache::lonxml::namespace,'curve');
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	my %curve;
 	&get_attributes(\%curve,\%curve_defaults,$parstack,$safeeval,
 		    $tagstack->[-1]);
@@ -730,7 +748,7 @@ sub end_curve {
     my $result = '';
     pop @Apache::lonxml::namespace;
     &Apache::lonxml::deregister('Apache::lonplot',('function','data'));
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     }
@@ -741,19 +759,20 @@ sub end_curve {
 sub start_function {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	if (exists($curves[-1]->{'data'})) {
 	    &Apache::lonxml::warning('Use of <function> precludes use of <data>.  The <data> will be omitted in favor of the <function> declaration.');
 	    delete $curves[-1]->{'data'} ;
 	}
-	$curves[-1]->{'function'} = 
-	    &Apache::lonxml::get_all_text("/function",$$parser[-1]);
+        my $function = &Apache::lonxml::get_all_text("/function",$$parser[-1]);
+	$function = &Apache::run::evaluate($function,$safeeval,$$parstack[-1]);
+	$curves[-1]->{'function'} = $function; 
     } elsif ($target eq 'edit') {
 	$result .= &Apache::edit::tag_start($target,$token,'Gnuplot compatible curve function');
 	my $text = &Apache::lonxml::get_all_text("/function",$$parser[-1]);
 	$result .= &Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	$result.=&Apache::edit::rebuild_tag($token);
 	my $text=$$parser[-1]->get_text("/function");
@@ -765,7 +784,7 @@ sub start_function {
 sub end_function {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result .= &Apache::edit::end_table();
     }
@@ -776,7 +795,7 @@ sub end_function {
 sub start_data {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	if (exists($curves[-1]->{'function'})) {
 	    &Apache::lonxml::warning('Use of <data> precludes use of .'.
 	    '<function>.  The <function> will be omitted in favor of '.
@@ -784,6 +803,7 @@ sub start_data {
 	    delete($curves[-1]->{'function'});
 	}
 	my $datatext = &Apache::lonxml::get_all_text("/data",$$parser[-1]);
+	$datatext=&Apache::run::evaluate($datatext,$safeeval,$$parstack[-1]);
 	# Deal with cases where we're given an array...
 	if ($datatext =~ /^\@/) {
 	    $datatext = &Apache::run::run('return "'.$datatext.'"',
@@ -828,7 +848,7 @@ sub start_data {
 	my $text = &Apache::lonxml::get_all_text("/data",$$parser[-1]);
 	$result .= &Apache::edit::end_row().
 	    &Apache::edit::start_spanning_row().
-	    &Apache::edit::editfield('',$text,'',60,1);
+	    &Apache::edit::textfield('',$text,'',60);
     } elsif ($target eq 'modified') {
 	$result.=&Apache::edit::rebuild_tag($token);
 	my $text=$$parser[-1]->get_text("/data");
@@ -840,7 +860,7 @@ sub start_data {
 sub end_data {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result .= &Apache::edit::end_table();
     }
@@ -851,7 +871,7 @@ sub end_data {
 sub start_axis {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result='';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
 	&get_attributes(\%axis,\%axis_defaults,$parstack,$safeeval,
 			$tagstack->[-1]);
     } elsif ($target eq 'edit') {
@@ -870,7 +890,7 @@ sub start_axis {
 sub end_axis {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'tex') {
     } elsif ($target eq 'edit') {
 	$result.=&Apache::edit::tag_end($target,$token);
     } elsif ($target eq 'modified') {
@@ -916,7 +936,7 @@ sub get_attributes{
 
 ##------------------------------------------------------- write_gnuplot_file
 sub write_gnuplot_file {
-    my ($tmpdir,$filename)= @_;
+    my ($tmpdir,$filename,$target)= @_;
     my $gnuplot_input = '';
     my $curve;
     # Collect all the colors
@@ -930,13 +950,18 @@ sub write_gnuplot_file {
 		       $plot{'fgcolor'}        );
     }
     # set term
-    $gnuplot_input .= 'set term gif ';
-    $gnuplot_input .= 'transparent ' if ($plot{'transparent'} eq 'on');
-    $gnuplot_input .= $plot{'font'} . ' ';
-    $gnuplot_input .= 'size '.$plot{'width'}.','.$plot{'height'}.' ';
-    $gnuplot_input .= "@Colors\n";
-    # set output
-    $gnuplot_input .= "set output\n";
+    if ($target eq 'web') {
+	$gnuplot_input .= 'set term gif ';
+	$gnuplot_input .= 'transparent ' if ($plot{'transparent'} eq 'on');
+	$gnuplot_input .= $plot{'font'} . ' ';
+	$gnuplot_input .= 'size '.$plot{'width'}.','.$plot{'height'}.' ';
+	$gnuplot_input .= "@Colors\n";
+	# set output
+	$gnuplot_input .= "set output\n";
+    } elsif ($target eq 'tex') {
+	$gnuplot_input .= "set term postscript eps monochrome\n";
+	$gnuplot_input .= "set output \"$filename.eps\"\n";
+    }
     # grid
     $gnuplot_input .= 'set grid'.$/ if ($plot{'grid'} eq 'on');
     # border