--- loncom/xml/lonxml.pm	2000/08/03 19:34:11	1.16
+++ loncom/xml/lonxml.pm	2000/09/19 18:05:21	1.20
@@ -29,7 +29,7 @@ use Apache::scripttag;
 
 sub xmlparse {
 
- my ($target,$content_file_string,%style_for_target) = @_;
+ my ($target,$content_file_string,$safeinit,%style_for_target) = @_;
  my @pars = ();
  push (@pars,HTML::TokeParser->new(\$content_file_string));
  my $currentstring = '';
@@ -39,14 +39,18 @@ sub xmlparse {
  my $safeeval = new Safe;
  $safeeval->permit("entereval");
  $safeeval->permit(":base_math");
+ $safeeval->deny(":base_io");
+#need to inspect this class of ops
+# $safeeval->deny(":base_orig");
+ if ( $safeinit ne '') {&Apache::run::run($safeinit,$safeeval);}
 #-------------------- Redefinition of the target in the case of compound target
 
  ($target, my @tenta) = split('&&',$target);
 
  my @stack = (); 
  my @parstack = ();
+ &initdepth;
  my $token;
- print $#pars;
  while ( $#pars > -1 ) {
    while ($token = $pars[$#pars]->get_token) {
      if ($token->[0] eq 'T') {
@@ -57,26 +61,26 @@ sub xmlparse {
        push (@stack,$token->[1]);
        # add parameters list to another stack
        push (@parstack,&parstring($token));
-       
+       &increasedepth($token);       
        if (exists $style_for_target{$token->[1]}) {
 	 $finaloutput .= &recurse($style_for_target{$token->[1]},
 				  $target,$safeeval,\%style_for_target,
 				  @parstack);
        } else {
-	 my $result = &callsub("start_$token->[1]", $target, $token,\@parstack,
+	 $result = &callsub("start_$token->[1]", $target, $token,\@parstack,
 			       \@pars, $safeeval, \%style_for_target);
        }              
      } elsif ($token->[0] eq 'E')  {
        #clear out any tags that didn't end
        while ($token->[1] ne $stack[$#stack] 
-	      && ($#stack > -1)) {pop @stack;pop @parstack;}
+	      && ($#stack > -1)) {pop @stack;pop @parstack;&decreasedepth($token);}
        
        if (exists $style_for_target{'/'."$token->[1]"}) {
 	 $finaloutput .= &recurse($style_for_target{'/'."$token->[1]"},
 				  $target,$safeeval,\%style_for_target,
 				  @parstack);
        } else {
-	 my $result = &callsub("end_$token->[1]", $target, $token, \@parstack,
+	 $result = &callsub("end_$token->[1]", $target, $token, \@parstack,
 			       \@pars,$safeeval, \%style_for_target);
        }
      }
@@ -89,7 +93,7 @@ sub xmlparse {
        }
        $result = '';
      }
-     if ($token->[0] eq 'E') { pop @stack;pop @parstack; }
+     if ($token->[0] eq 'E') { pop @stack;pop @parstack;&decreasedepth($token);}
    }
    pop @pars;
  }
@@ -114,13 +118,15 @@ sub recurse {
       } elsif ($tokenpat->[0] eq 'S') {
 	push (@innerstack,$tokenpat->[1]);
 	push (@innerparstack,&parstring($tokenpat));
+	&increasedepth($tokenpat);
 	$partstring = &callsub("start_$tokenpat->[1]", 
 			       $target, $tokenpat, \@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)) {pop @innerstack;pop @innerparstack;}
+	       && ($#innerstack > -1)) {pop @innerstack;pop @innerparstack;
+					&decreasedepth($tokenpat);}
 	$partstring = &callsub("end_$tokenpat->[1]",
 			       $target, $tokenpat, \@innerparstack,
 			       \@pat, $safeeval, $style_for_target);
@@ -144,7 +150,8 @@ sub recurse {
 	$output .= &Apache::run::evaluate($partstring,$safeeval,$decls);
 	$partstring = '';
       }
-      if ($tokenpat->[0] eq 'E') { pop @innerstack;pop @innerparstack; }
+      if ($tokenpat->[0] eq 'E') { pop @innerstack;pop @innerparstack;
+				 &decreasedepth($tokenpat);}
     }
     pop @pat;
   }
@@ -157,12 +164,13 @@ sub callsub {
   {
     no strict 'refs';
     if (my $space=$Apache::lonxml::alltags{$token->[1]}) {
-      #print "Calling sub $sub in $space \n";
+      #print "Calling sub $sub in $space<br>\n";
       $sub="$space\:\:$sub";
+      $Apache::lonxml::curdepth=join('_',@Apache::lonxml::depthcounter);
       $currentstring = &$sub($target,$token,$parstack,$parser,
 			     $safeeval,$style);
     } else {
-      #print "NOT Calling sub $sub\n";
+      #print "NOT Calling sub $sub<br>\n";
       if (defined($token->[4])) {
 	$currentstring = $token->[4];
       } else {
@@ -174,10 +182,62 @@ sub callsub {
   return $currentstring;
 }
 
+sub initdepth {
+  @Apache::lonxml::depthcounter=();
+  $Apache::lonxml::depth=-1;
+  $Apache::lonxml::olddepth=-1;
+}
+
+sub increasedepth {
+  my ($token) = @_;
+  if ($Apache::lonxml::depth<$Apache::lonxml::olddepth-1) {
+    $#Apache::lonxml::depthcounter--;
+    $Apache::lonxml::olddepth=$Apache::lonxml::depth;
+  }
+  $Apache::lonxml::depth++;
+#  print "<br>s $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1]<br>\n";
+  $Apache::lonxml::depthcounter[$Apache::lonxml::depth]++;
+  if ($Apache::lonxml::depthcounter[$Apache::lonxml::depth]==1) {
+    $Apache::lonxml::olddepth=$Apache::lonxml::depth;
+  }
+}
+
+sub decreasedepth {
+  my ($token) = @_;
+  $Apache::lonxml::depth--;
+#  print "<br>e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1]<br>\n";
+}
+
+sub get_all_text {
+
+ my($tag,$pars)= @_;
+ my $depth=0;
+ my $token;
+ my $result='';
+ while (($depth >=0) && ($token = $pars->get_token)) {
+   if ($token->[0] eq 'T') {
+     $result.=$token->[1];
+   } elsif ($token->[0] eq 'S') {
+     if ($token->[1] eq $tag) { $depth++; }
+     $result.=$token->[4];
+   } elsif ($token->[0] eq 'E')  {
+     if ($token->[1] eq $tag) { $depth--; }
+     #skip sending back the last end tag
+     if ($depth > -1) { $result.=$token->[2]; }
+   }
+ }
+ return $result
+}
+
+
 sub parstring {
   my ($token) = @_;
   my $temp='';
-  map {$temp .= "my \$$_=\"$token->[2]->{$_}\";"} @{$token->[3]};
+  map {
+    if ($_=~/\w+/) {
+      $temp .= "my \$$_=\"$token->[2]->{$_}\";"
+    }
+  } @{$token->[3]};
   return $temp;
 }
 1;