--- loncom/xml/londefdef.pm	2006/01/04 23:14:24	1.310
+++ loncom/xml/londefdef.pm	2006/03/23 23:47:12	1.324
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Tags Default Definition Module 
 #
-# $Id: londefdef.pm,v 1.310 2006/01/04 23:14:24 albertel Exp $
+# $Id: londefdef.pm,v 1.324 2006/03/23 23:47:12 albertel Exp $
 # 
 #
 # Copyright Michigan State University Board of Trustees
@@ -105,11 +105,21 @@ sub start_m {
 	    $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
 	    #&Apache::lonxml::debug("M is evaulated to:$inside:");
 	}
+	my $tex = $inside;
 	my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval);
 	$currentstring = &Apache::lontexconvert::converted(\$inside,$display);
 	if ($Apache::lontexconvert::errorstring) {
-	    &Apache::lonxml::warning("tth error: ".
-				     $Apache::lontexconvert::errorstring);
+	    my $errormsg='<pre>'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'</pre> occured while attempting to convert this TeX: <pre>';
+	    $tex = &HTML::Entities::encode($tex,'<>&"');
+	    my ($linenumber) =
+		($Apache::lontexconvert::errorstring =~ /Line (\d+)/);
+	    if (defined($linenumber)) {
+		my @tex=split("\n",$tex);
+		$tex[$linenumber]='<b><font color="red">'.
+		    $tex[$linenumber].'</font></b>';
+		$tex=join("\n",@tex);
+	    }
+	    &Apache::lonxml::warning($errormsg.$tex.'</pre>');
 	    $Apache::lontexconvert::errorstring='';
 	}
 	#&Apache::lonxml::debug("M is ends with:$currentstring:");
@@ -201,7 +211,7 @@ sub start_html {
 sub end_html {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'webgrade') {
 	$currentstring = '</html>';
     }
     return $currentstring;
@@ -211,7 +221,7 @@ sub end_html {
 sub start_head {
     my ($target,$token) = @_;
     my $currentstring = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'webgrade') {
 	$currentstring = $token->[4].&Apache::lonxml::fontsettings();
     } 
     return $currentstring;
@@ -220,7 +230,8 @@ sub start_head {
 sub end_head {
     my ($target,$token) = @_;
     my $currentstring = '';
-    if ($target eq 'web' && $env{'request.state'} eq 'published') {
+    if (($target eq 'web'      && $env{'request.state'} eq 'published') ||
+	($target eq 'webgrade' && $env{'request.state'} eq 'published')) {
 	$currentstring = &Apache::lonmenu::registerurl(undef,$target).
 	    $token->[2];    
     } 
@@ -356,7 +367,7 @@ sub end_form {
 sub start_title {
     my ($target,$token) = @_;
     my $currentstring = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'webgrade') {
 	$currentstring = $token->[4];     
     } elsif ($target eq 'tex') {
 	$currentstring .= '\keephidden{Title of the document:  ' 
@@ -371,7 +382,7 @@ sub start_title {
 sub end_title {
     my ($target,$token) = @_;
     my $currentstring = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'webgrade') {
 	$currentstring = $token->[2];    
     } elsif ($target eq 'tex') {
 	$currentstring .= '}';
@@ -502,7 +513,7 @@ sub start_body {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';
 
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'webgrade') {
 	if ($Apache::lonhomework::parsing_a_problem) {
 	    &Apache::lonxml::warning("<body> tag found inside of <problem> tag this can cause problems.");
 	    return '';
@@ -586,7 +597,7 @@ EDITBUTTON
 sub end_body {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = &end_p();	# Close off unclosed <p>
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'webgrade') {
 	$currentstring .= &Apache::lonxml::xmlend($target,$parser);
     } elsif ($target eq 'tex') {
 	$currentstring .= '\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent \end{document}';  
@@ -619,9 +630,6 @@ sub end_center {
 	$currentstring = $token->[2];     
     } elsif ($target eq 'tex') {
 	$currentstring = '\end{center}';  
-	if (&is_inside_of($tagstack, "table")) {
-	    $currentstring .= &center_correction();
-	}
     }
     return $currentstring;
 }
@@ -1187,6 +1195,7 @@ sub start_p {
 	    $closing_string = '</p>'; # Deal correctly with <p /> e.g.
 	}
     } elsif ($target eq 'tex' && !$para_disabled) {
+
 	$currentstring .= &end_p();	# close off prior para if in progress.
 	my $align=&Apache::lonxml::get_param('align',$parstack,$safeeval,undef,1);
 	if ($align eq 'center') {
@@ -1194,17 +1203,22 @@ sub start_p {
 	    $closing_string = '\end{center}';
 	    if (&is_inside_of($tagstack, "table")) {
 		$currentstring = &center_correction().$currentstring;
-		$closing_string .= &center_correction();
 	    }
 	} elsif ($align eq 'right') {
-	    $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';
-	    $closing_string= '}}';
+	    $currentstring.="\n".'{\flushright ';
+#	    $currentstring.='\makebox['.$env{'form.textwidth'}.']{\hfill\llap{';
+	    $closing_string= "}\n";
 	} elsif ($align eq 'left') {
-	    $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{\rlap{';
-	    $closing_string = '}\hfill}';
+	    $currentstring.= "\n".'{\flushleft ';
+#	    $currentstring.='\noindent\makebox['.$env{'form.textwidth'}.']{{';
+	    $closing_string = "}\n";
 	} else {
             $currentstring.='\par ';
-	    $closing_string = '\strut\\\\\strut ';
+	    if (&is_inside_of($tagstack, 'table')) {
+		$closing_string = '\vskip 0pt'; # Seems to be consistent with <p> in tables.
+	    } else {
+		$closing_string = '\strut\\\\\strut ';
+	    }
         }
 
     }
@@ -1539,7 +1553,6 @@ sub start_div {
 	    $endstring      = '\end{center}';
 	    if (&is_inside_of($tagstack, "table")) {
 		$currentstring = &center_correction().$currentstring;
-		$endstring .= &center_correction();
 	    }
 	}
 	elsif ($align eq 'right') {
@@ -1961,11 +1974,16 @@ sub start_table {
 
 	# width either comes forced from the TeXwidth or the width parameters.
 	# in either case it can be a percentage or absolute width.
-
+	# in the width case we ignore absolute width 
 	my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval,undef,0);
 	if (!defined($TeXwidth)) {
-	    $TeXwidth = &Apache::lonxml::get_param('width',$parstack,$safeeval,undef,1);
-	    if (!defined($TeXwidth)) { $TeXwidth = $textwidth; }
+	    my $htmlwidth = &Apache::lonxml::get_param('width',$parstack,
+						       $safeeval,undef,1);
+	    if ($htmlwidth =~ /%/) {
+		$TeXwidth = $htmlwidth;
+	    } else { 
+		$TeXwidth = $textwidth;
+	    }
 	} else {
 	    $Apache::londefdef::table[-1]{'forcedtablewidth'} = 1;
 	}
@@ -1975,7 +1993,12 @@ sub start_table {
             $Apache::londefdef::table[-1]{'width'}=$1*$textwidth/100;
 	} else {
 	    $Apache::londefdef::table[-1]{'width'}=$TeXwidth;
-	}        
+	}
+        #  In the end, however the table width cannot be wider than $textwidth...
+	
+	if ($Apache::londefdef::table[-1]{'width'} > $textwidth) {
+	    $Apache::londefdef::table[-1]{'width'} = $textwidth;
+	}
 
         #table's border
 	my $border = &Apache::lonxml::get_param('border',$parstack,$safeeval); 
@@ -2019,7 +2042,6 @@ sub end_table {
 	my $inmemory = '';
 	my $output = '';
 	my $WARNING='';
-	# &debug_dump_table($Apache::londefdef::table[-1]);
         #width of columns from TeXwidth attributes
 
 	for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
@@ -2206,18 +2228,26 @@ sub end_table {
 	for (my $in=0;$in<=$Apache::londefdef::table[-1]{'row_number'};$in++) {
 	    my $have_rowspan = 0;
 	    for (my $jn=0;$jn<=$#fwidth;$jn++) {
+
+		#-----------------------------------------------------------
+                #   I think this order of doing things will ensure that
+		#   single rowspan, columspan and combined row/colspans will
+                #   work correctly.  LaTeX is delicate here.
+		#    RF.
+
+		# Start a rowspan if necessary:
+
+		my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];
+		my $colspan = $Apache::londefdef::table[-1]{'colspan'}[$in][$jn];
 		#
 		#  Do the appropriate magic if this has a colspan
 		# 
-		my $colspan = $Apache::londefdef::table[-1]{'colspan'}[$in][$jn];
+
 		if ($colspan > 1) {
 		    $output .= '\multicolumn{'.
 			$colspan
 			.'}{|l|}{';
 		}
-		my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];
-
-		# Start a rowspan if necessary:
 
 		if ($rowspan > 1) {
 		    $have_rowspan++;
@@ -2226,6 +2256,7 @@ sub end_table {
 		if (($rowspan eq '^') || ($rowspan eq '_')) {
 		    $have_rowspan++;
 		}
+		#--------------------------------------------------------------
 
 		if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
 		    $output.=&center_correction().'\begin{center}';
@@ -2234,7 +2265,7 @@ sub end_table {
 		}
 		$output.=$Apache::londefdef::table[-1]{'content'}[$in][$jn];
 		if ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'c') {
-		    $output.='\end{center}'.&center_correction();
+		    $output.='\end{center}';
 		} elsif ($Apache::londefdef::table[-1]{'align'}[$in][$jn] eq 'r') {
 		    $output.='} ';
 		}
@@ -2260,9 +2291,11 @@ sub end_table {
 		$output .= ' \\\\ ';
 		for (my $jn=0; $jn<=$#fwidth;$jn++) {
 		    my $rowspan = $Apache::londefdef::table[-1]{'rowspan'}[$in][$jn];
-		    if (($rowspan <= 1) || ($rowspan eq '_')) {
-			my $column = $jn+1;
-			$output .= '\cline{'.$column.'-'.$column.'} ';
+		    if ($rowspan ne "^") {
+			if (($rowspan <= 1) || ($rowspan eq '_')) {
+			    my $column = $jn+1;
+			    $output .= '\cline{'.$column.'-'.$column.'} ';
+			}
 		    }
 		}
 
@@ -2432,6 +2465,13 @@ sub end_td_tex {
     $Apache::londefdef::table[-1]{'counter_columns'} = $current_column;
    
 
+    # Get the column and row spans.
+    # Colspan can be done via \multicolumn if I can figure out the data structs.
+
+    my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 0);
+    if (!$colspan) {
+	$colspan = 1;
+    }
 
     my $rowspan = &Apache::lonxml::get_param('rowspan', $parstack, $safeeval, undef, 0);
     if (!$rowspan) {
@@ -2440,11 +2480,13 @@ sub end_td_tex {
 
 
 
-    $Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column] = $rowspan;
-    for (my $i = 1; $i < $rowspan; $i++) {
-	$Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column] = '^';
-	if ($i == ($rowspan-1)) {
-	    $Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column] = '_';
+    for (my $c = 0; $c < $colspan; $c++) {
+	$Apache::londefdef::table[-1]{'rowspan'}[$current_row][$current_column+$c] = $rowspan;
+	for (my $i = 1; $i < $rowspan; $i++) {
+	    $Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column+$c] = '^';
+	    if ($i == ($rowspan-1)) {
+		$Apache::londefdef::table[-1]{'rowspan'}[$current_row+$i][$current_column+$c] = '_';
+	    }
 	}
     }
 
@@ -2539,13 +2581,7 @@ sub end_td_tex {
 
     push @ {$Apache::londefdef::table[-1]{'content'}[-1] },$data;
 
-    # Get the column and row spans.
-    # Colspan can be done via \multicolumn if I can figure out the data structs.
 
-    my $colspan = &Apache::lonxml::get_param('colspan', $parstack, $safeeval, undef, 0);
-    if (!$colspan) {
-	$colspan = 1;
-    }
 
 
     #  the colspan array will indicate how many columns will be spanned by this
@@ -2554,14 +2590,16 @@ sub end_td_tex {
     #  counter_columns is incremented in the start_td_tex, we adjust by colspan-1.
     #
 
-    $Apache::londefdef::table[-1]{'colspan'}[$current_row][$current_column] = $colspan;
     $Apache::londefdef::table[-1]{'counter_columns'} += $colspan -1;
-
-    # Put empty text in spanned cols.
-
     for (my $i = 0; $i < ($colspan -1); $i++) {
 	push @ {$Apache::londefdef::table[-1]{'content'}[-1] },'';
     }
+    for (my $r = 0; $r < $rowspan; $r++) {
+	$Apache::londefdef::table[-1]{'colspan'}[$current_row+$r][$current_column] = $colspan;
+	# Put empty text in spanned cols.
+	
+    }
+
 
 
     return '';
@@ -2735,13 +2773,17 @@ sub start_img {
 
     if ($target eq 'web') {
 	if ($env{'browser.imagesuppress'} ne 'on') {
-	    $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src});
-	} else {
-	    my $alttag= &Apache::lonxml::get_param
-		('alt',$parstack,$safeeval,undef,1);
-	    unless ($alttag) {
-		$alttag=&Apache::lonmeta::alttag
-		    ($Apache::lonxml::pwd[-1],$src);
+	    my $enc = ('yes' eq 
+		       lc(&Apache::lonxml::get_param('encrypturl',$parstack,
+						     $safeeval)));
+	    $currentstring.=&Apache::lonenc::encrypt_ref($token,{'src'=>$src},
+							 $enc);
+	} else {
+	    my $alttag = &Apache::lonxml::get_param('alt',$parstack,$safeeval,
+						    undef,1);
+	    if (!$alttag) {
+		$alttag = &Apache::lonmeta::alttag($Apache::lonxml::pwd[-1],
+						   $src);
 	    }
 	    $currentstring.='[IMAGE: '.$alttag.']';
 	}
@@ -2760,12 +2802,7 @@ sub start_img {
 						  $safeeval,
 						  undef,1));
 	if(!$align) {
-	    # disabled for now see BUG#4535
-	    if (0 && &is_inside_of($tagstack, "table")) {
-		$align = "right";      # Force wraptext use. 
-	    } else {
 		$align = "bottom";	# This is html's default so it's ours too.
-	    }
 	}
 	#
 	&Apache::lonxml::debug("Alignemnt = $align");
@@ -2780,11 +2817,18 @@ sub start_img {
 							    $parstack,
 							    $safeeval,
 							    undef,0);
-	&Apache::lonxml::debug("LaTeX rendering = $latex_rendering");
+	# &Apache::lonxml::debug("LaTeX rendering = $latex_rendering");
 	if(!$latex_rendering) {
-	    $latex_rendering = "texwrap";
+		$latex_rendering = "texwrap";
 	}
-	&Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src");
+	# using texwrap inside a table does not work. So, if after all of this,
+	# texwrap is on, we turn it off if we detect we're in a table:
+	#
+	if (($latex_rendering eq 'texwrap') && &is_inside_of($tagstack, "table")) {
+	    $latex_rendering = 'parpic';
+	}
+
+	# &Apache::lonxml::debug("LaTeX rendering = $latex_rendering image file: $src");
 
 	#if original gif/jpg/png file exist do following:
 	my $origsrc=$src;
@@ -2866,6 +2910,8 @@ sub start_img {
 						   ['','bottom','middle','top','left','right'],$token,5);
 	$currentstring .=&Apache::edit::select_arg('TeXwrap:', 'TeXwrap',
 						   ['', 'parbox', 'parpic'], $token, 2);
+	$currentstring .=&Apache::edit::select_arg('Encyrpt URL:','encrypturl',
+						   ['no','yes'], $token, 2);
 	$currentstring .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
 	my $src=    &Apache::lonxml::get_param('src',$parstack,$safeeval);
 	my $alt=    &Apache::lonxml::get_param('alt',$parstack,$safeeval);
@@ -2883,7 +2929,7 @@ sub start_img {
 	my $ctag=&Apache::edit::get_new_args($token,$parstack,
 					     $safeeval,'src','alt','align',
 					     'TeXwidth','TeXheight', 'TeXwrap',
-					     'width','height');
+					     'width','height','encrypturl');
 	my ($nsrc,$nwidth,$nheight)=
 	    ($token->[2]{'src'},$token->[2]{'width'},$token->[2]{'height'});
 	my $loc=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$nsrc);
@@ -3158,6 +3204,7 @@ sub start_pre {
 	$currentstring .= $token->[4];
     } elsif ($target eq 'tex') {
 	$currentstring .= '\begin{verbatim}';
+	&Apache::lonxml::disable_LaTeX_substitutions();
     } 
     return $currentstring;
 }
@@ -3169,6 +3216,7 @@ sub end_pre {
 	$currentstring .= $token->[2];
     } elsif ($target eq 'tex') {
 	$currentstring .= '\end{verbatim}';
+	&Apache::lonxml::enable_LaTeX_substitutions();
     }
     return $currentstring;
 }
@@ -3655,7 +3703,7 @@ sub end_legend {
 sub start_link {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_;
     my $currentstring = '';
-    if ($target eq 'web') {
+    if ($target eq 'web' || $target eq 'webgrade') {
 	my $href=&Apache::lonxml::get_param('href',$parstack,$safeeval,
 					    undef,1);
 	&Apache::lonxml::extlink($href);