Diff for /loncom/xml/lonxml.pm between versions 1.2 and 1.22

version 1.2, 2000/06/23 20:40:06 version 1.22, 2000/10/02 22:19:19
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # Style Parser Module   # XML Parser Module 
 #  #
 # last modified 06/23/00 by Alexander Sakharuk  # last modified 06/26/00 by Alexander Sakharuk
   
 package Apache::lonstyleparser;   package Apache::lonxml; 
   
 use strict;  use strict;
 use HTML::TokeParser;  use HTML::TokeParser;
   use Safe;
   use Opcode;
   
 #============================================================= style subroutine   sub register {
     my $space;
 sub styleparser {    my @taglist;
     my $temptag;
   my ($target,$content_style_string) = @_;    ($space,@taglist) = @_;
     foreach $temptag (@taglist) {
 #------------------------------------------- target redefinition (if necessary)       $Apache::lonxml::alltags{$temptag}=$space;
         }
   my @target_string = '';  }
   my $element;                                       
      use Apache::style;
   ($element,@target_string) = split ('&&',$target);  use Apache::lontexconvert;
   use Apache::run;
   map {$content_style_string =~ s/\<(.*)$_\>/\<$1$element\>/g; } @target_string;  use Apache::londefdef;
      use Apache::scripttag;
   $target = $element;  #==================================================   Main subroutine: xmlparse  
      
 #-------------------------------------------- create a table for defined target  sub xmlparse {
 #----------------------------------------- from the information from Style File  
    my ($target,$content_file_string,$safeinit,%style_for_target) = @_;
   my @value_style = ();   my @pars = ();
   my $current_key = '';   push (@pars,HTML::TokeParser->new(\$content_file_string));
   my $current_value = '';   my $currentstring = '';
   my $stoken;   my $finaloutput = ''; 
   my $flag;                     my $newarg = '';
   my $iele;   my $result;
    my $safeeval = new Safe;
   my $pstyle = HTML::TokeParser->new(\$content_style_string);   $safeeval->permit("entereval");
    $safeeval->permit(":base_math");
   while ($stoken = $pstyle->get_token) {   $safeeval->deny(":base_io");
 #----------------------------------------------------- start for tag definition  #need to inspect this class of ops
    if ($stoken->[0] eq 'S' and $stoken->[1] eq 'definetag') {  # $safeeval->deny(":base_orig");
 #-------------------------------------------------------------- new key in hash   $safeinit .= ';$external::target='.$target.';';
     $current_key = $stoken->[2]{name};   &Apache::run::run($safeinit,$safeeval);
     $flag = 0;  #-------------------- Redefinition of the target in the case of compound target
 #-------------------------------------------------------------- metadata output  
     if ($target eq 'meta') {   ($target, my @tenta) = split('&&',$target);
      while ($stoken = $pstyle->get_token and $stoken->[1] ne 'definetag') {   
        if ($stoken->[0] eq 'S' and $stoken->[1] eq 'meta') {   my @stack = (); 
         while ($stoken = $pstyle->get_token and $stoken->[1] ne 'meta') {   my @parstack = ();
     $current_value .= $stoken->[1];   &initdepth;
         }   my $token;
    while ( $#pars > -1 ) {
      while ($token = $pars[$#pars]->get_token) {
        if ($token->[0] eq 'T') {
          $result=$token->[1];
   #       $finaloutput .= &Apache::run::evaluate($token->[1],$safeeval,'');
        } elsif ($token->[0] eq 'S') {
          # add tag to stack    
          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 {
    $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;&decreasedepth($token);}
          
          if (exists $style_for_target{'/'."$token->[1]"}) {
    $finaloutput .= &recurse($style_for_target{'/'."$token->[1]"},
     $target,$safeeval,\%style_for_target,
     @parstack);
          } else {
    $result = &callsub("end_$token->[1]", $target, $token, \@parstack,
          \@pars,$safeeval, \%style_for_target);
        }         }
      }       }
     } else {       if ($result ne "" ) {
 #--------------------------------------------------------------- outtext output         if ( $#parstack > -1 ) { 
      while ($stoken = $pstyle->get_token and $stoken->[1] ne 'outtext') {   $finaloutput .= &Apache::run::evaluate($result,$safeeval,
    if ($stoken->[1] eq 'definetag') {   $parstack[$#parstack]);
      $flag = 1;         } else {
              last;   $finaloutput .= &Apache::run::evaluate($result,$safeeval,'');
    }  
       }  
      if ($flag == 0) {   
        while ($stoken = $pstyle->get_token and $stoken->[0] ne 'S') {  
     $current_value .= $stoken->[1];  
        }  
       while ($stoken->[1] ne 'definetag') {  
        if ($stoken->[0] eq 'S' and $stoken->[1] eq $target) {  
  while ($stoken = $pstyle->get_token) {  
  if ($stoken->[1] ne $target) {  
    if ($stoken->[0] eq 'S') {  
        my $flagelem = 0;  
                for (my $i=$#value_style-1;$i>0;$i=$i-2) {  
    if ($stoken->[1] eq $value_style[$i]) {  
        $flagelem = 1;  
                        $iele = $i+1;  
                        last;  
    }  
        }  
        if ($flagelem == 0) {  
          $current_value .= $stoken->[4];  
             } else {  
    $current_value .= $value_style[$iele];  
        }  
    }   
            if ($stoken->[0] eq 'E') {  
        my $flagelem = 0;  
                for (my $i=$#value_style-1;$i>0;$i=$i-2) {  
    if ('/'.$stoken->[1] eq $value_style[$i]) {  
        $flagelem = 1;  
                        $iele = $i+1;  
                        last;  
    }  
        }  
        if ($flagelem == 0) {  
                  $current_value .= $stoken->[2];  
             } else {  
    $current_value .= $value_style[$iele];  
        }  
    }   
            if ($stoken->[0] eq 'T') {  
              $current_value .= $stoken->[1];   
    }                   
  }  else {        
  last;  
  }  
         }  
        } elsif ($stoken->[0] eq 'S' and $stoken->[1] ne $target) {  
   my $tempotempo = $stoken->[1];  
    while ($stoken = $pstyle->get_token and $stoken->[1] ne $tempotempo) {  
    }  
        }         }
          $result = '';
        }
        if ($token->[0] eq 'E') { pop @stack;pop @parstack;&decreasedepth($token);}
      }
      pop @pars;
    }
    return $finaloutput;
   }
   
        while ($stoken = $pstyle->get_token) {  sub recurse {
         if ($stoken->[0] eq 'T') {    
           $current_value .= $stoken->[1];    my @innerstack = (); 
  }     my @innerparstack = ();
         if ($stoken->[0] eq 'E') {    my ($newarg,$target,$safeeval,$style_for_target,@parstack) = @_;
   last;    my @pat = ();
  }     push (@pat,HTML::TokeParser->new(\$newarg));
         if ($stoken->[0] eq 'S') {    my $tokenpat;
   last;    my $partstring = '';
     my $output='';
     my $decls='';
     while ( $#pat > -1 ) {
       while  ($tokenpat = $pat[$#pat]->get_token) {
         if ($tokenpat->[0] eq 'T') {
    $partstring = $tokenpat->[1];
         } 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;
    &decreasedepth($tokenpat);}
    $partstring = &callsub("end_$tokenpat->[1]",
          $target, $tokenpat, \@innerparstack,
          \@pat, $safeeval, $style_for_target);
         }
         #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;
    }        }
    $current_value =~ s/(\s)+/$1/g;    return $output;
      if ($current_value ne ' ' and $current_value ne '' ) {    }
        push (@value_style,lc $current_key,$current_value);  
      }  sub callsub {
      $current_key = '';    my ($sub,$target,$token,$parstack,$parser,$safeeval,$style)=@_;
      $current_value = '';             my $currentstring='';
     {
       no strict 'refs';
       if (my $space=$Apache::lonxml::alltags{$token->[1]}) {
         &Apache::lonxml::debug("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 {
         &Apache::lonxml::debug("NOT Calling sub $sub in $space<br>\n");
         if (defined($token->[4])) {
    $currentstring = $token->[4];
         } else {
    $currentstring = $token->[2];
         }
       }
       use strict 'refs';
     }
     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 %style_for_target = @value_style;     
 #--------------------------------------------------------------- check printing   my($tag,$pars)= @_;
 #  while (($current_key,$current_value) = each %style_for_target) {   my $depth=0;
 #       print "$current_key => $current_value\n";   my $token;
 #  }   my $result='';
 #---------------------------------------------------------------- return result   while (($depth >=0) && ($token = $pars->get_token)) {
   return %style_for_target;      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 {
       if ($_=~/\w+/) {
         $temp .= "my \$$_=\"$token->[2]->{$_}\";"
       }
     } @{$token->[3]};
     return $temp;
   }
   
   $Apache::lonxml::debug=0;
   sub debug {
     if ($Apache::lonxml::debug eq 1) {
       print "DEBUG:".$_[0]."<br>\n";
     }
   }
   sub error {
     if ($Apache::lonxml::debug eq 1) {
       print "ERROR:".$_[0]."<br>\n";
     }
   }
   sub warning {
     if ($Apache::lonxml::debug eq 1) {
       print "WARNING:".$_[0]."<br>\n";
     }
 }  }
   
 1;  1;
 __END__  __END__
   
   
   
   
   

Removed from v.1.2  
changed lines
  Added in v.1.22


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>