--- loncom/xml/lonxml.pm	2005/07/10 21:43:35	1.381
+++ loncom/xml/lonxml.pm	2005/11/10 21:28:21	1.387
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # XML Parser Module 
 #
-# $Id: lonxml.pm,v 1.381 2005/07/10 21:43:35 www Exp $
+# $Id: lonxml.pm,v 1.387 2005/11/10 21:28:21 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -527,7 +527,13 @@ sub inner_xmlparse {
   #   $finaloutput.=&endredirection;
   # }
 
-
+  if ($target eq 'grade') { &endredirection(); }
+  if ( $Apache::lonxml::redirection ) {
+      &error("Unclean exit of parser, text still being redirected. This is likely due to there being missing end tags.");
+      while ($Apache::lonxml::redirection) {
+	  $finaloutput.=&endredirection();
+      }
+  }
   if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {
     $finaloutput=&afterburn($finaloutput);
   }	    
@@ -636,7 +642,7 @@ sub setup_globals {
     $Apache::lonxml::evaluate = 1;
     $Apache::lonxml::import = 1;
   } elsif ($target eq 'grade') {
-    &startredirection;
+    &startredirection(); #ended in inner_xmlparse on exit
     $Apache::lonxml::metamode = 0;
     $Apache::lonxml::evaluate = 1;
     $Apache::lonxml::import = 1;
@@ -665,6 +671,9 @@ sub setup_globals {
 
 sub init_safespace {
   my ($target,$safeeval,$safehole,$safeinit) = @_;
+  $safeeval->deny_only(':dangerous');
+  $safeeval->reval('use Math::Complex;');
+  $safeeval->permit_only(":default");
   $safeeval->permit("entereval");
   $safeeval->permit(":base_math");
   $safeeval->permit("sort");
@@ -722,6 +731,36 @@ sub init_safespace {
   $safehole->wrap(\&Math::Cephes::stdtr ,$safeeval,'&stdtr' );
   $safehole->wrap(\&Math::Cephes::stdtri,$safeeval,'&stdtri');
 
+  $safehole->wrap(\&Math::Cephes::Matrix::mat,$safeeval,'&mat');
+  $safehole->wrap(\&Math::Cephes::Matrix::new,$safeeval,
+		  '&Math::Cephes::Matrix::new');
+  $safehole->wrap(\&Math::Cephes::Matrix::coef,$safeeval,
+		  '&Math::Cephes::Matrix::coef');
+  $safehole->wrap(\&Math::Cephes::Matrix::clr,$safeeval,
+		  '&Math::Cephes::Matrix::clr');
+  $safehole->wrap(\&Math::Cephes::Matrix::add,$safeeval,
+		  '&Math::Cephes::Matrix::add');
+  $safehole->wrap(\&Math::Cephes::Matrix::sub,$safeeval,
+		  '&Math::Cephes::Matrix::sub');
+  $safehole->wrap(\&Math::Cephes::Matrix::mul,$safeeval,
+		  '&Math::Cephes::Matrix::mul');
+  $safehole->wrap(\&Math::Cephes::Matrix::div,$safeeval,
+		  '&Math::Cephes::Matrix::div');
+  $safehole->wrap(\&Math::Cephes::Matrix::inv,$safeeval,
+		  '&Math::Cephes::Matrix::inv');
+  $safehole->wrap(\&Math::Cephes::Matrix::transp,$safeeval,
+		  '&Math::Cephes::Matrix::transp');
+  $safehole->wrap(\&Math::Cephes::Matrix::simq,$safeeval,
+		  '&Math::Cephes::Matrix::simq');
+  $safehole->wrap(\&Math::Cephes::Matrix::mat_to_vec,$safeeval,
+		  '&Math::Cephes::Matrix::mat_to_vec');
+  $safehole->wrap(\&Math::Cephes::Matrix::vec_to_mat,$safeeval,
+		  '&Math::Cephes::Matrix::vec_to_mat');
+  $safehole->wrap(\&Math::Cephes::Matrix::check,$safeeval,
+		  '&Math::Cephes::Matrix::check');
+  $safehole->wrap(\&Math::Cephes::Matrix::check,$safeeval,
+		  '&Math::Cephes::Matrix::check');
+
 #  $safehole->wrap(\&Math::Cephes::new_fract,$safeeval,'&new_fract');
 #  $safehole->wrap(\&Math::Cephes::radd,$safeeval,'&radd');
 #  $safehole->wrap(\&Math::Cephes::rsub,$safeeval,'&rsub');
@@ -893,7 +932,11 @@ sub get_all_text_unbalanced {
     $tag='<'.$tag.'>';
     while ($token = $$pars[-1]->get_token) {
 	if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
-	    $result.=$token->[1];
+	    if ($token->[0] eq 'T' && $token->[2]) {
+		$result.='<![CDATA['.$token->[1].']]>';
+	    } else {
+		$result.=$token->[1];
+	    }
 	} elsif ($token->[0] eq 'PI') {
 	    $result.=$token->[2];
 	} elsif ($token->[0] eq 'S') {
@@ -959,7 +1002,11 @@ sub get_all_text {
 	    while (($depth >=0) && ($token = $$pars[-1]->get_token)) {
 		#&Apache::lonxml::debug("e token:$token->[0]:$depth:$token->[1]:".$#$pars.":".$#Apache::lonxml::pwd);
 		if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
-		    $result.=$token->[1];
+		    if ($token->[2]) {
+			$result.='<![CDATA['.$token->[1].']]>';
+		    } else {
+			$result.=$token->[1];
+		    }
 		} elsif ($token->[0] eq 'PI') {
 		    $result.=$token->[2];
 		} elsif ($token->[0] eq 'S') {
@@ -1011,7 +1058,11 @@ sub get_all_text {
 		#&Apache::lonxml::debug("s token:$token->[0]:$depth:$token->[1]");
 		if (($token->[0] eq 'T')||($token->[0] eq 'C')||
 		    ($token->[0] eq 'D')) {
-		    $result.=$token->[1];
+		    if ($token->[2]) {
+			$result.='<![CDATA['.$token->[1].']]>';
+		    } else {
+			$result.=$token->[1];
+		    }
 		} elsif ($token->[0] eq 'PI') {
 		    $result.=$token->[2];
 		} elsif ($token->[0] eq 'S') {
@@ -1064,6 +1115,14 @@ sub parstring {
   return $temp;
 }
 
+sub extlink {
+    my ($res,$exact)=@_;
+    if (!$exact) {
+	$res=&Apache::lonnet::hreflocation($Apache::lonxml::pwd[-1],$res);
+    }
+    push(@Apache::lonxml::extlinks,$res)	 
+}
+
 sub writeallows {
     unless ($#extlinks>=0) { return; }
     my $thisurl = &Apache::lonnet::clutter(shift);
@@ -1340,13 +1399,16 @@ ENDNOTFOUND
 	    }
 #
 # we are in construction space, see if edit mode forced
-            &Apache::loncommon::get_unprocessed_cgi
-                          ($ENV{'QUERY_STRING'},['editmode']);
+            &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+						    ['editmode']);
 	}
 	if (!$env{'form.editmode'} || $env{'form.viewmode'}) {
 	    $result = &Apache::lonxml::xmlparse($request,$target,$filecontents,
 						'',%mystyle);
 	    undef($Apache::lonhomework::parsing_a_task);
+	    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+						    ['rawmode']);
+	    if ($env{'rawmode'}) { $result = $filecontents; }
 	}
     }