--- loncom/xml/lonxml.pm	2004/07/27 23:35:34	1.333
+++ loncom/xml/lonxml.pm	2004/10/12 22:25:40	1.343
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # XML Parser Module 
 #
-# $Id: lonxml.pm,v 1.333 2004/07/27 23:35:34 www Exp $
+# $Id: lonxml.pm,v 1.343 2004/10/12 22:25:40 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -51,7 +51,7 @@ use Math::Cephes();
 use Math::Random();
 use Opcode();
 use POSIX qw(strftime);
-
+use Time::HiRes qw( gettimeofday tv_interval );
 
 sub register {
   my ($space,@taglist) = @_;
@@ -165,13 +165,21 @@ sub xmlbegin {
 }
 
 sub xmlend {
+    my ($target,$parser)=@_;
     my $mode='xml';
     my $status='OPEN';
     if ($Apache::lonhomework::parsing_a_problem) {
 	$mode='problem';
 	$status=$Apache::inputtags::status[-1]; 
     }
-    return &Apache::lonfeedback::list_discussion($mode,$status).'</html>';
+    my $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>';
+    }
 }
 
 sub tokeninputfield {
@@ -279,7 +287,7 @@ sub fontsettings() {
     my $headerstring='';
     if (($ENV{'browser.os'} eq 'mac') && (!$ENV{'browser.mathml'})) { 
 	$headerstring.=
-	    '<meta Content-Type="text/html; charset=x-mac-roman">';
+	    '<meta Content-Type="text/html; charset=x-mac-roman" />';
     } elsif (!$ENV{'browser.mathml'} && $ENV{'browser.unicode'}) {
 	$headerstring.=
 	    '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
@@ -312,13 +320,15 @@ sub xmlparse {
      my $bodytext=
 	 $ENV{'course.'.$ENV{'request.course.id'}.'.default_xml_style'};
      if ($bodytext) {
-       my $location=&Apache::lonnet::filelocation('',$bodytext);
-       my $styletext=&Apache::lonnet::getfile($location);
-       if ($styletext ne '-1') {
-          %style_for_target = (%style_for_target,
-                          &Apache::style::styleparser($target,$styletext));
-       }
-    }
+	 foreach my $file (split(',',$bodytext)) {
+	     my $location=&Apache::lonnet::filelocation('',$file);
+	     my $styletext=&Apache::lonnet::getfile($location);
+	     if ($styletext ne '-1') {
+		 %style_for_target = (%style_for_target,
+				      &Apache::style::styleparser($target,$styletext));
+	     }
+	 }
+     }
  } elsif ($ENV{'construct.style'} && ($ENV{'request.state'} eq 'construct')) {
      my $location=&Apache::lonnet::filelocation('',$ENV{'construct.style'});
      my $styletext=&Apache::lonnet::getfile($location);
@@ -805,6 +815,8 @@ sub initdepth {
   $Apache::lonxml::olddepth=-1;
 }
 
+my @timers;
+my $lasttime;
 sub increasedepth {
   my ($token) = @_;
   $Apache::lonxml::depth++;
@@ -812,8 +824,15 @@ sub increasedepth {
   if ($Apache::lonxml::depthcounter[$Apache::lonxml::depth]==1) {
     $Apache::lonxml::olddepth=$Apache::lonxml::depth;
   }
+  my $time;
+  if ($Apache::lonxml::debug eq "1") {
+      push(@timers,[&gettimeofday()]);
+      $time=&tv_interval($lasttime);
+      $lasttime=[&gettimeofday()];
+  }
+  my $spacing='  'x($Apache::lonxml::depth-1);
   my $curdepth=join('_',@Apache::lonxml::depthcounter);
-  &Apache::lonxml::debug("s $Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1]\n");
+  &Apache::lonxml::debug("s$spacing$Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1] : $time : \n");
 #print "<br />s $Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1]\n";
 }
 
@@ -828,8 +847,15 @@ sub decreasedepth {
     &Apache::lonxml::warning(&mt("Missing tags, unable to properly run file."));
     $Apache::lonxml::depth='-1';
   }
+  my ($timer,$time);
+  if ($Apache::lonxml::debug eq "1") {
+      $timer=pop(@timers);
+      $time=&tv_interval($lasttime);
+      $lasttime=[&gettimeofday()];
+  }
+  my $spacing='  'x$Apache::lonxml::depth;
   my $curdepth=join('_',@Apache::lonxml::depthcounter);
-  &Apache::lonxml::debug("e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n");
+  &Apache::lonxml::debug("e$spacing$Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1] : $time : ".&tv_interval($timer)."\n");
 #print "<br />e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n";
 }
 
@@ -1002,6 +1028,7 @@ sub parstring {
     unless ($_=~/\W/) {
       my $val=$token->[2]->{$_};
       $val =~ s/([\%\@\\\"\'])/\\$1/g;
+      $val =~ s/(\$[^{a-zA-Z_])/\\$1/g;
       #if ($val =~ m/^[\%\@]/) { $val="\\".$val; }
       $temp .= "my \$$_=\"$val\";";
     }
@@ -1159,6 +1186,7 @@ $cleanbut
 <input type="submit" name="viewmode" accesskey="v" value="$lt{'vi'}" />
 BUTTONS
       $buttons.=&Apache::lonhtmlcommon::spelllink('xmledit','filecont');
+      $buttons.=&Apache::lonhtmlcommon::htmlareaselectactive('filecont');
       my $editfooter=(<<ENDFOOTER);
 $initialize
 <hr />
@@ -1260,7 +1288,7 @@ $bodytag
 </body>
 </html>
 ENDNOTFOUND
-    $filecontents='';
+        $filecontents='';
 	if ($ENV{'request.state'} ne 'published') {
 	    if ($filetype eq 'sty') {
 		$filecontents=&createnewsty();
@@ -1271,6 +1299,10 @@ ENDNOTFOUND
 	}
     } else {
 	unless ($ENV{'request.state'} eq 'published') {
+	    if ($filecontents=~/BEGIN LON-CAPA Internal/) {
+		&Apache::lonxml::error(&mt('This file appears to be a rendering of a Lon-CAPA resource. If this is correct, this resource will act very oddly and incorrectly.'));
+	    }
+
 	    if ($ENV{'form.attemptclean'}) {
 		$filecontents=&htmlclean($filecontents,1);
 	    }
@@ -1332,31 +1364,41 @@ sub debug {
 }
 
 sub error {
-  $errorcount++;
-  my $request=$Apache::lonxml::request;
-  if (!$request) { $request=Apache->request; }
-  if (($Apache::lonxml::debug eq 1) || ($ENV{'request.state'} eq 'construct') ) {
-    # If printing in construction space, put the error inside <pre></pre>
-      push(@Apache::lonxml::error_messages,
-	   $Apache::lonxml::warnings_error_header.
-	   "<b>ERROR:</b>".join("<br />\n",@_)."<br />\n");
-      $Apache::lonxml::warnings_error_header='';
-  } else {
-      push(@Apache::lonxml::error_messages,
-	   "<b>An Error occured while processing this resource. The instructor has been notified.</b> <br />");
-    #notify author
-    &Apache::lonmsg::author_res_msg($ENV{'request.filename'},join('<br />',@_));
-    #notify course
-    if ( $ENV{'request.course.id'} ) {
-      my (undef,%users)=&Apache::lonfeedback::decide_receiver(undef,0,1,1,1);
-      my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'});
-      foreach (keys %users) {
-	my ($user,$domain) = split(/:/, $_);
-	&Apache::lonmsg::user_normal_msg($user,$domain,
-        "Error [$declutter]",join('<br />',@_));
-      }
+    $errorcount++;
+    if (($Apache::lonxml::debug eq 1) || ($ENV{'request.state'} eq 'construct') ) {
+	# If printing in construction space, put the error inside <pre></pre>
+	push(@Apache::lonxml::error_messages,
+	     $Apache::lonxml::warnings_error_header.
+	     "<b>ERROR:</b>".join("<br />\n",@_)."<br />\n");
+	$Apache::lonxml::warnings_error_header='';
+    } else {
+	my $errormsg;
+	my ($symb)=&Apache::lonnet::symbread();
+	if ( !$symb ) {
+	    #public or browsers
+	    $errormsg=&mt("An error occured while processing this resource. The author has been notified.");
+	} 
+	#notify author
+	&Apache::lonmsg::author_res_msg($ENV{'request.filename'},join('<br />',@_));
+	#notify course
+	if ( $symb && $ENV{'request.course.id'} ) {
+	    my (undef,%users)=&Apache::lonfeedback::decide_receiver(undef,0,1,1,1);
+	    my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'});
+	    my @userlist;
+	    foreach (keys %users) {
+		my ($user,$domain) = split(/:/, $_);
+		push(@userlist,"$user\@$domain");
+		&Apache::lonmsg::user_normal_msg($user,$domain,
+						 "Error [$declutter]",join('<br />',@_));
+	    }
+	    if ($ENV{'request.role.adv'}) {
+		$errormsg=&mt("An error occured while processing this resource. The course personnel ([_1]) and the author have been notified.",join(', ',@userlist));
+	    } else {
+		$errormsg=&mt("An error occured while processing this resource. The instructor has been notified.");
+	    }
+	}
+	push(@Apache::lonxml::error_messages,"<b>$errormsg</b> <br />");
     }
-  }
 }
 
 sub warning {
@@ -1440,7 +1482,7 @@ sub get_param_var {
   } elsif ( $args !~ /my \$\Q$param\E=\"/ ) { return undef; }
   my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
   &Apache::lonxml::debug("first run is $value");
-  if ($value =~ /^[\$\@\%]\w+$/) {
+  if ($value =~ /^[\$\@\%][a-zA-Z_]\w*$/) {
       &Apache::lonxml::debug("doing second");
       my @result=&Apache::run::run("return $value",$safeeval,1);
       if (!defined($result[0])) {