--- loncom/xml/lonxml.pm	2002/10/21 20:31:06	1.207
+++ loncom/xml/lonxml.pm	2002/11/07 19:33:52	1.213
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # XML Parser Module 
 #
-# $Id: lonxml.pm,v 1.207 2002/10/21 20:31:06 albertel Exp $
+# $Id: lonxml.pm,v 1.213 2002/11/07 19:33:52 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -148,6 +148,9 @@ $Apache::lonxml::request='';
 $Apache::lonxml::counter=0;
 $Apache::lonxml::counter_changed=0;
 
+#internal check on whether to look at style defs
+$Apache::lonxml::usestyle=1;
+
 sub xmlbegin {
   my $output='';
   if ($ENV{'browser.mathml'}) {
@@ -528,7 +531,7 @@ sub xmlparse {
 # do we have a course style file?
 #
 
- if ($ENV{'request.course.id'}) {
+ if ($ENV{'request.course.id'} && $ENV{'request.state'} ne 'construct') {
      my $bodytext=
 	 $ENV{'course.'.$ENV{'request.course.id'}.'.default_xml_style'};
      if ($bodytext) {
@@ -630,15 +633,12 @@ sub inner_xmlparse {
 	# add parameters list to another stack
 	push (@$parstack,&parstring($token));
 	&increasedepth($token);
-	if (exists $$style_for_target{$token->[1]}) {
-	  if ($Apache::lonxml::redirection) {
-	    $Apache::lonxml::outputstack['-1'] .=
-	      &recurse($$style_for_target{$token->[1]},$target,$safeeval,
-		       $style_for_target,@$parstack);
-	  } else {
-	    $finaloutput .= &recurse($$style_for_target{$token->[1]},$target,
-				     $safeeval,$style_for_target,@$parstack);
-	  }
+	if ($Apache::lonxml::usestyle &&
+	    exists($$style_for_target{$token->[1]})) {
+	    $Apache::lonxml::usestyle=0;
+	    my $string=$$style_for_target{$token->[1]}.
+	      '<LONCAPA_INTERNAL_TURN_STYLE_ON />';
+	    &Apache::lonxml::newparser($pars,\$string);
 	} else {
 	  $result = &callsub("start_$token->[1]", $target, $token, $stack,
 			     $parstack, $pars, $safeeval, $style_for_target);
@@ -656,16 +656,12 @@ sub inner_xmlparse {
 	  }
 	}
 
-	if (exists($$style_for_target{'/'."$token->[1]"})) {
-	  if ($Apache::lonxml::redirection) {
-	    $Apache::lonxml::outputstack['-1'] .=  
-	      &recurse($$style_for_target{'/'."$token->[1]"},
-		       $target,$safeeval,$style_for_target,@$parstack);
-	  } else {
-	    $finaloutput .= &recurse($$style_for_target{'/'."$token->[1]"},
-				     $target,$safeeval,$style_for_target,
-				     @$parstack);
-	  }
+	if ($Apache::lonxml::usestyle &&
+	    exists($$style_for_target{'/'."$token->[1]"})) {
+	    $Apache::lonxml::usestyle=0;
+	    my $string=$$style_for_target{'/'.$token->[1]}.
+	      '<LONCAPA_INTERNAL_TURN_STYLE_ON />';
+	    &Apache::lonxml::newparser($pars,\$string);
 	} else {
 	  $result = &callsub("end_$token->[1]", $target, $token, $stack,
 			     $parstack, $pars,$safeeval, $style_for_target);
@@ -702,8 +698,10 @@ sub inner_xmlparse {
 	&end_tag($stack,$parstack,$token);
       }
     }
-    pop @$pars;
-    pop @Apache::lonxml::pwd;
+    if ($#$pars > -1) {
+	pop @$pars;
+	pop @Apache::lonxml::pwd;
+    }
   }
 
   # if ($target eq 'meta') {
@@ -717,78 +715,6 @@ sub inner_xmlparse {
   return $finaloutput;
 }
 
-sub recurse {
-  my @innerstack = (); 
-  my @innerparstack = ();
-  my ($newarg,$target,$safeeval,$style_for_target,@parstack) = @_;
-  my @pat = ();
-  &newparser(\@pat,\$newarg);
-  my $tokenpat;
-  my $partstring = '';
-  my $output='';
-  my $decls='';
-  &Apache::lonxml::debug("Recursing");
-  while ( $#pat > -1 ) {
-    while  ($tokenpat = $pat[$#pat]->get_token) {
-      if (($tokenpat->[0] eq 'T') || ($tokenpat->[0] eq 'C') || ($tokenpat->[0] eq 'D') ) {
-	if ($metamode<1) { $partstring=$tokenpat->[1]; }
-      } elsif ($tokenpat->[0] eq 'PI') {
-	if ($metamode<1) { $partstring=$tokenpat->[2]; }
-      } elsif ($tokenpat->[0] eq 'S') {
-	push (@innerstack,$tokenpat->[1]);
-	push (@innerparstack,&parstring($tokenpat));
-	&increasedepth($tokenpat);
-	$partstring = &callsub("start_$tokenpat->[1]", $target, $tokenpat,
-			       \@innerstack, \@innerparstack, \@pat,
-			       $safeeval, $style_for_target);
-      } elsif ($tokenpat->[0] eq 'E') {
-	#clear out any tags that didn't end
-	while ($tokenpat->[1] ne $innerstack[$#innerstack]
-	       && ($#innerstack > -1)) {
-	  my $lasttag=$innerstack[-1];
-	  if ($tokenpat->[1] =~ /^$lasttag$/i) {
-	    &Apache::lonxml::warning('Using tag &lt;/'.$tokenpat->[1].'&gt; as end tag to &lt;'.$innerstack[-1].'&gt;');
-	    last;
-	  } else {
-	    &Apache::lonxml::warning('Found tag &lt;/'.$tokenpat->[1].'&gt; when looking for &lt;/'.$innerstack[-1].'&gt; in file');
-	    &end_tag(\@innerstack,\@innerparstack,$tokenpat);
-	  }
-	}
-	$partstring = &callsub("end_$tokenpat->[1]", $target, $tokenpat,
-			       \@innerstack, \@innerparstack, \@pat,
-			       $safeeval, $style_for_target);
-      } else {
-	&Apache::lonxml::error("Unknown token event :$tokenpat->[0]:$tokenpat->[1]:");
-      }
-      #pass both the variable to the style tag, and the tag we 
-      #are processing inside the <definedtag>
-      if ( $partstring ne "" ) {
-	if ( $#parstack > -1 ) { 
-	  if ( $#innerparstack > -1 ) { 
-	    $decls= $parstack[$#parstack].$innerparstack[$#innerparstack];
-	  } else {
-	    $decls= $parstack[$#parstack];
-	  }
-	} else {
-	  if ( $#innerparstack > -1 ) { 
-	    $decls=$innerparstack[$#innerparstack];
-	  } else {
-	    $decls='';
-	  }
-	}
-	$output .= &Apache::run::evaluate($partstring,$safeeval,$decls);
-	$partstring = '';
-      }
-      if ($tokenpat->[0] eq 'E') { pop @innerstack;pop @innerparstack;
-				 &decreasedepth($tokenpat);}
-    }
-    pop @pat;
-    pop @Apache::lonxml::pwd;
-  }
-  &Apache::lonxml::debug("Exiting Recursing");
-  return $output;
-}
-
 sub callsub {
   my ($sub,$target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   my $currentstring='';
@@ -841,6 +767,9 @@ sub callsub {
 	  if ($token->[0] eq 'S') {
 	    $currentstring = $token->[4];
 	    $currentstring.=&Apache::edit::handle_insert();
+	  } elsif ($token->[0] eq 'E') {
+	    $currentstring = $token->[2];
+            $currentstring.=&Apache::edit::handle_insertafter($token->[1]);
 	  } else {
 	    $currentstring = $token->[2];
 	  }
@@ -859,6 +788,7 @@ sub setup_globals {
   $errorcount=0;
   $warningcount=0;
   $Apache::lonxml::default_homework_loaded=0;
+  $Apache::lonxml::usestyle=1;
   &init_counter();
   @Apache::lonxml::pwd=();
   @Apache::lonxml::extlinks=();
@@ -1043,7 +973,7 @@ sub get_all_text_unbalanced {
    } elsif ($token->[0] eq 'E')  {
      $result.=$token->[2];
    }
-   if ($result =~ /(.*)$tag(.*)/) {
+   if ($result =~ /(.*)\Q$tag\E(.*)/s) {
      &Apache::lonxml::debug('Got a winner with leftovers ::'.$2);
      &Apache::lonxml::debug('Result is :'.$1);
      $result=$1;
@@ -1077,48 +1007,68 @@ sub store_counter {
 
 sub get_all_text {
  my($tag,$pars)= @_;
+ &Apache::lonxml::debug("Got a ".ref($pars));
+ if (ref($pars) ne 'ARRAY') {
+     $pars=[$pars];
+ }
  my $depth=0;
  my $token;
  my $result='';
  if ( $tag =~ m:^/: ) { 
    my $tag=substr($tag,1); 
-#   &Apache::lonxml::debug("have:$tag:");
-   while (($depth >=0) && ($token = $pars->get_token)) {
-#     &Apache::lonxml::debug("e token:$token->[0]:$depth:$token->[1]");
-     if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
-       $result.=$token->[1];
-     } elsif ($token->[0] eq 'PI') {
-       $result.=$token->[2];
-     } elsif ($token->[0] eq 'S') {
-       if ($token->[1] =~ /^$tag$/i) { $depth++; }
-       $result.=$token->[4];
-     } elsif ($token->[0] eq 'E')  {
-       if ( $token->[1] =~ /^$tag$/i) { $depth--; }
-       #skip sending back the last end tag
-       if ($depth > -1) { $result.=$token->[2]; } else {
-	 $pars->unget_token($token);
+   #&Apache::lonxml::debug("have:$tag:");
+   while (($depth >=0) && ($#$pars > -1)) {
+     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];
+       } elsif ($token->[0] eq 'PI') {
+	 $result.=$token->[2];
+       } elsif ($token->[0] eq 'S') {
+	 if ($token->[1] =~ /^$tag$/i) { $depth++; }
+	 $result.=$token->[4];
+       } elsif ($token->[0] eq 'E')  {
+	 if ( $token->[1] =~ /^$tag$/i) { $depth--; }
+	 #skip sending back the last end tag
+	 if ($depth > -1) { $result.=$token->[2]; } else {
+	   $$pars[-1]->unget_token($token);
+	 }
        }
      }
+     if (($depth >=0) && ($#$pars > 0) ) {
+       pop(@$pars);
+       pop(@Apache::lonxml::pwd);
+     }
    }
  } else {
-   while ($token = $pars->get_token) {
-#     &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];
-     } elsif ($token->[0] eq 'PI') {
-       $result.=$token->[2];
-     } elsif ($token->[0] eq 'S') {
-       if ( $token->[1] =~ /^$tag$/i) {
-	 $pars->unget_token($token); last;
-       } else {
-	 $result.=$token->[4];
-       }
-     } elsif ($token->[0] eq 'E')  {
-       $result.=$token->[2];
+     while ($#$pars > -1) {
+	 while ($token = $$pars[-1]->get_token) {
+	     #&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];
+	     } elsif ($token->[0] eq 'PI') {
+		 $result.=$token->[2];
+	     } elsif ($token->[0] eq 'S') {
+		 if ( $token->[1] =~ /^$tag$/i) {
+		     $$pars[-1]->unget_token($token); last;
+		 } else {
+		     $result.=$token->[4];
+		 }
+	     } elsif ($token->[0] eq 'E')  {
+		 $result.=$token->[2];
+	     }
+	 }
+	 if (($#$pars > 0) ) {
+	     pop(@$pars);
+	     pop(@Apache::lonxml::pwd);
+	 } else { last; }
      }
-   }
  }
-# &Apache::lonxml::debug("Exit:$result:");
+ if ($result =~ m|<LONCAPA_INTERNAL_TURN_STYLE_ON />|) {
+     $Apache::lonxml::usestyle=1;
+ }
+ #&Apache::lonxml::debug("Exit:$result:");
  return $result
 }
 
@@ -1381,10 +1331,10 @@ sub error {
     &Apache::lonmsg::author_res_msg($ENV{'request.filename'},join('<br />',@_));
     #notify course
     if ( $ENV{'request.course.id'} ) {
-      my $users=$ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'};
+      my (undef,%users)=&Apache::lonfeedback::decide_receiver(undef,0,1,1,1);
       my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'});
-      foreach my $user (split /\,/, $users) {
-	($user,my $domain) = split /:/, $user;
+      foreach (keys %users) {
+	my ($user,$domain) = split(/:/, $_);
 	&Apache::lonmsg::user_normal_msg($user,$domain,
         "Error [$declutter]",join('<br />',@_));
       }
@@ -1404,24 +1354,38 @@ sub warning {
 }
 
 sub get_param {
-  my ($param,$parstack,$safeeval,$context) = @_;
-  if ( ! $context ) { $context = -1; }
-  my $args ='';
-  if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
-  if ( ! $args ) { return undef; }
-  if ( $args =~ /my \$$param=\"/ ) {
-    return &Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
-  } else {
-    return undef;
-  }
+    my ($param,$parstack,$safeeval,$context,$case_insensitive) = @_;
+    if ( ! $context ) { $context = -1; }
+    my $args ='';
+    if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
+    if ( ! $args ) { return undef; }
+    if ( $case_insensitive ) {
+	if ($args =~ s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei) {
+	    return &Apache::run::run("{$args;".'return $'.$param.'}',
+                                     $safeeval); #'
+	} else {
+	    return undef;
+	}
+    } else {
+	if ( $args =~ /my \$\Q$param\E=\"/ ) {
+	    return &Apache::run::run("{$args;".'return $'.$param.'}',
+                                     $safeeval); #'
+	} else {
+	    return undef;
+	}
+    }
 }
 
 sub get_param_var {
-  my ($param,$parstack,$safeeval,$context) = @_;
+  my ($param,$parstack,$safeeval,$context,$case_insensitive) = @_;
   if ( ! $context ) { $context = -1; }
   my $args ='';
   if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
-  if ( $args !~ /my \$$param=\"/ ) { return undef; }
+  if ($case_insensitive) {
+      if (! ($args=~s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei)) {
+	  return undef;
+      }
+  } elsif ( $args !~ /my \$\Q$param\E=\"/ ) { return undef; }
   my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
   if ($value =~ /^[\$\@\%]/) {
     return &Apache::run::run("return $value",$safeeval,1);