--- loncom/xml/lonxml.pm	2004/12/09 23:45:59	1.350
+++ loncom/xml/lonxml.pm	2005/04/07 00:42:07	1.371
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # XML Parser Module 
 #
-# $Id: lonxml.pm,v 1.350 2004/12/09 23:45:59 albertel Exp $
+# $Id: lonxml.pm,v 1.371 2005/04/07 00:42:07 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -149,37 +149,49 @@ $Apache::lonxml::post_evaluate=1;
 $Apache::lonxml::warnings_error_header='';
 
 sub xmlbegin {
-  my $output='';
-  @htmlareafields=();
-  if ($ENV{'browser.mathml'}) {
-      $output='<?xml version="1.0"?>'
-            .'<?xml-stylesheet type="text/css" href="/adm/MathML/mathml.css"?>'
-            .'<!DOCTYPE html SYSTEM "/adm/MathML/mathml.dtd" '
-            .'[<!ENTITY mathns "http://www.w3.org/1998/Math/MathML">]>'
+    my ($style)=@_;
+    my $output='';
+    @htmlareafields=();
+    if ($ENV{'browser.mathml'}) {
+	$output='<?xml version="1.0"?>'
+            #.'<?xml-stylesheet type="text/css" href="/adm/MathML/mathml.css"?>'."\n"
+#            .'<!DOCTYPE html SYSTEM "/adm/MathML/mathml.dtd" '
+            
+#	    .'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [<!ENTITY mathns "http://www.w3.org/1998/Math/MathML">] >'
+	    .'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">'
             .'<html xmlns:math="http://www.w3.org/1998/Math/MathML" ' 
-		.'xmlns="http://www.w3.org/TR/REC-html40">';
-  } else {
-      $output='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>';
-  }
-  return $output;
+	    .'xmlns="http://www.w3.org/1999/xhtml">';
+    } else {
+	$output='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>';
+    }
+    if ($style eq 'encode') {
+	$output=&HTML::Entities::encode($output,'<>&"');
+    }
+    return $output;
 }
 
 sub xmlend {
     my ($target,$parser)=@_;
     my $mode='xml';
     my $status='OPEN';
-    if ($Apache::lonhomework::parsing_a_problem) {
+    if ($Apache::lonhomework::parsing_a_problem ||
+	$Apache::lonhomework::parsing_a_task ) {
 	$mode='problem';
 	$status=$Apache::inputtags::status[-1]; 
     }
-    my $discussion=&Apache::lonfeedback::list_discussion($mode,$status);    
+    my $discussion;
+    &Apache::loncommon::get_unprocessed_cgi
+        ($ENV{'query_string'},['LONCAPA_INTERNAL_no_discussion']);
+    if (! exists($ENV{'form.LONCAPA_INTERNAL_no_discussion'}) ||
+        $ENV{'form.LONCAPA_INTERNAL_no_discussion'} ne 'true') {
+        $discussion=&Apache::lonfeedback::list_discussion($mode,$status);
+    }
     if ($target eq 'tex') {
 	$discussion.='<tex>\keephidden{ENDOFPROBLEM}\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\end{document}</tex>';
 	&Apache::lonxml::newparser($parser,\$discussion,'');
 	return '';
     } else {
-	return $discussion.'</html>';
+	return $discussion.&Apache::loncommon::endbodytag();
     }
 }
 
@@ -284,7 +296,7 @@ sub printtokenheader {
     }
 }
 
-sub fontsettings() {
+sub fontsettings {
     my $headerstring='';
     if (($ENV{'browser.os'} eq 'mac') && (!$ENV{'browser.mathml'})) { 
 	$headerstring.=
@@ -309,6 +321,7 @@ sub xmlparse {
 
  &setup_globals($request,$target);
  &Apache::inputtags::initialize_inputtags();
+ &Apache::bridgetask::initialize_bridgetask();
  &Apache::outputtags::initialize_outputtags();
  &Apache::edit::initialize_edit();
  &Apache::londefdef::initialize_londefdef();
@@ -353,8 +366,8 @@ sub xmlparse {
 
  my @stack = ();
  my @parstack = ();
- &initdepth;
-
+ &initdepth();
+ &init_alarm();
  my $finaloutput = &inner_xmlparse($target,\@stack,\@parstack,\@pars,
 				   $safeeval,\%style_for_target);
 
@@ -363,28 +376,37 @@ sub xmlparse {
  }
  &do_registered_ssi();
  if ($Apache::lonxml::counter_changed) { &store_counter() }
+ if ($ENV{'form.return_only_error_and_warning_counts'}) {
+     return "$errorcount:$warningcount";
+ }
  return $finaloutput;
 }
 
 sub htmlclean {
     my ($raw,$full)=@_;
+# Take care of CRLF etc
 
-    my $tree = HTML::TreeBuilder->new;
-    $tree->ignore_unknown(0);
-
-    $tree->parse($raw);
-
-    my $output= $tree->as_HTML(undef,' ');
-
-    $output=~s/\<(br|hr|img|meta|allow)(.*?)\>/\<$1$2 \/\>/gis;
-    $output=~s/\<\/(br|hr|img|meta|allow)\>//gis;
+    $raw=~s/\r\f/\n/gs; $raw=~s/\f\r/\n/gs;
+    $raw=~s/\r\n/\n/gs; $raw=~s/\n\r/\n/gs;
+    $raw=~s/\f/\n/gs; $raw=~s/\r/\n/gs;
+    $raw=~s/\&\#10\;/\n/gs; $raw=~s/\&\#13\;/\n/gs;
+
+# Generate empty tags, remove wrong end tags
+    $raw=~s/\<(br|hr|img|meta|allow|basefont)([^\>\/]*?)\>/\<$1$2 \/\>/gis;
+    $raw=~s/\<\/(br|hr|img|meta|allow|basefont)\>//gis;
     unless ($full) {
-       $output=~s/\<[\/]*(body|head|html)\>//gis;
+       $raw=~s/\<[\/]*(body|head|html)\>//gis;
     }
-
-    $tree = $tree->delete;
-
-    return $output;
+# Make standard tags lowercase
+    foreach ('html','body','head','meta','h1','h2','h3','h4','b','i','m',
+             'table','tr','td','th','p','br','hr','img','embed','font',
+             'a','strong','center','title','basefont','li','ol','ul',
+             'input','select','form','option','script','pre') {
+	$raw=~s/\<$_\s*\>/\<$_\>/gis;
+        $raw=~s/\<\/$_\s*\>/<\/$_\>/gis;
+        $raw=~s/\<$_\s([^\>]*)\>/<$_ $1\>/gis;
+    }
+    return $raw;
 }
 
 sub latex_special_symbols {
@@ -399,18 +421,17 @@ sub latex_special_symbols {
         $string=~s/([^\\])\#/$1\\\#/g;
     } else {
 	$string=~s/\\/\\ensuremath{\\backslash}/g;
-	$string=~s/([^\\]|^)\%/$1\\\%/g;
-	$string=~s/([^\\]|^)\$/$1\\\$/g;
-	$string=~s/([^\\])\_/$1\\_/g;
-	$string=~s/\$\$/\$\\\$/g;
-	$string=~s/\_\_/\_\\\_/g;
-	$string=~s/\#\#/\#\\\#/g;
+	$string=~s/\\\%|\%/\\\%/g;
+	$string=~s/\\{|{/\\{/g;
+	$string=~s/\\}|}/\\}/g;
+	$string=~s/\\\$|\$/\\\$/g;
+	$string=~s/\\\_|\_/\\\_/g;
         $string=~s/([^\\]|^)(\~|\^)/$1\\$2\\strut /g;
 	$string=~s/(>|<)/\\ensuremath\{$1\}/g; #more or less
 	$string=&Apache::lonprintout::character_chart($string);
 	# any & or # leftover should be safe to just escape
-        $string=~s/([^\\]|^)\&/$1\\\&/g;
-        $string=~s/([^\\]|^)\#/$1\\\#/g;
+	$string=~s/\\\&|\&/\\\&/g;
+	$string=~s/\\\#|\#/\\\#/g;
         $string=~s/\|/\$\\mid\$/g;
 #single { or } How to escape?
     }
@@ -674,12 +695,15 @@ sub init_safespace {
   $safeeval->permit(":base_math");
   $safeeval->permit("sort");
   $safeeval->permit("time");
+  $safeeval->deny("rand");
+  $safeeval->deny("srand");
   $safeeval->deny(":base_io");
   $safehole->wrap(\&Apache::scripttag::xmlparse,$safeeval,'&xmlparse');
   $safehole->wrap(\&Apache::outputtags::multipart,$safeeval,'&multipart');
   $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT');
   $safehole->wrap(\&Apache::chemresponse::chem_standard_order,$safeeval,
 		  '&chem_standard_order');
+  $safehole->wrap(\&Apache::response::check_status,$safeeval,'&check_status');
 
   $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin');
   $safehole->wrap(\&Math::Cephes::acos,$safeeval,'&acos');
@@ -781,6 +805,28 @@ sub default_homework_load {
     }
 }
 
+{
+    my $alarm_depth;
+    sub init_alarm {
+	alarm(0);
+	$alarm_depth=0;
+    }
+
+    sub start_alarm {
+	if ($alarm_depth<1) {
+	    my $old=alarm($Apache::lonnet::perlvar{'lonScriptTimeout'});
+	    if ($old) {
+		&Apache::lonxml::error("Cancelled an alarm of $old, this shouldn't occur.");
+	    }
+	}
+	$alarm_depth++;
+    }
+
+    sub end_alarm {
+	$alarm_depth--;
+	if ($alarm_depth<1) { alarm(0); }
+    }
+}
 my $metamode_was;
 sub startredirection {
     if (!$Apache::lonxml::redirection) {
@@ -1014,7 +1060,8 @@ sub get_all_text {
 sub newparser {
   my ($parser,$contentref,$dir) = @_;
   push (@$parser,HTML::LCParser->new($contentref));
-  $$parser['-1']->xml_mode('1');
+  $$parser[-1]->xml_mode(1);
+  $$parser[-1]->marked_sections(1);
   if ( $dir eq '' ) {
     push (@Apache::lonxml::pwd, $Apache::lonxml::pwd[$#Apache::lonxml::pwd]);
   } else {
@@ -1209,7 +1256,7 @@ $initialize
 $xml_help
 <input type="hidden" name="editmode" value="$lt{'ed'}" />
 $buttons<br />
-<textarea cols="80" rows="44" name="filecont" id="filecont">$filecontents</textarea>
+<textarea style="width:100%" cols="80" rows="44" name="filecont" id="filecont">$filecontents</textarea>
 <br />$buttons
 <br />
 </form>
@@ -1255,12 +1302,12 @@ sub handler {
     
     $Apache::lonxml::debug=$ENV{'user.debug'};
     
-    if ($ENV{'browser.mathml'}) {
-	&Apache::loncommon::content_type($request,'text/xml');
-    } else {
-	&Apache::loncommon::content_type($request,'text/html');
-    }
+    &Apache::loncommon::content_type($request,'text/html');
     &Apache::loncommon::no_cache($request);
+    if ($ENV{'request.state'} eq 'published') {
+	$request->set_last_modified(&Apache::lonnet::metadata($request->uri,
+							      'lastrevisiondate'));
+    }
     $request->send_http_header;
     
     return OK if $request->header_only;
@@ -1328,6 +1375,7 @@ ENDNOTFOUND
 	if (!$ENV{'form.editmode'} || $ENV{'form.viewmode'}) {
 	    $result = &Apache::lonxml::xmlparse($request,$target,$filecontents,
 						'',%mystyle);
+	    undef($Apache::lonhomework::parsing_a_task);
 	}
     }
     
@@ -1382,6 +1430,10 @@ sub debug {
 }
 
 sub show_error_warn_msg {
+    if ($ENV{'request.filename'} eq '/home/httpd/html/res/lib/templates/simpleproblem.problem' &&
+	&Apache::lonnet::allowed('mdc',$ENV{'request.course.id'})) {
+	return 1;
+    }
     return (($Apache::lonxml::debug eq 1) ||
 	    ($ENV{'request.state'} eq 'construct') ||
 	    ($Apache::lonhomework::browse eq 'F'