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

version 1.2, 2000/06/23 20:40:06 version 1.13, 2000/07/25 21:28:22
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,%style_for_target) = @_;
   my @value_style = ();   my $pars = HTML::TokeParser->new(\$content_file_string);
   my $current_key = '';   my $currentstring = '';
   my $current_value = '';   my $finaloutput = ''; 
   my $stoken;   my $newarg = '';
   my $flag;                     my $safeeval = new Safe;
   my $iele;   $safeeval->permit("entereval");
    $safeeval->permit(":base_math");
   my $pstyle = HTML::TokeParser->new(\$content_style_string);  #-------------------- Redefinition of the target in the case of compound target
   
   while ($stoken = $pstyle->get_token) {   ($target, my @tenta) = split('&&',$target);
 #----------------------------------------------------- start for tag definition  
    if ($stoken->[0] eq 'S' and $stoken->[1] eq 'definetag') {  #------------------------- Stack definition (in stack we have all current tags)
 #-------------------------------------------------------------- new key in hash  
     $current_key = $stoken->[2]{name};   my @stack = (); 
     $flag = 0;   my @parstack = ();
 #-------------------------------------------------------------- metadata output  
     if ($target eq 'meta') {  #------------------------------------- Parse input string (content_file_string)
      while ($stoken = $pstyle->get_token and $stoken->[1] ne 'definetag') {    
        if ($stoken->[0] eq 'S' and $stoken->[1] eq 'meta') {   my $token;
         while ($stoken = $pstyle->get_token and $stoken->[1] ne 'meta') {   
     $current_value .= $stoken->[1];   while ($token = $pars->get_token) {
         }     if ($token->[0] eq 'T') {
        $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));
        
        if (exists $style_for_target{$token->[1]}) {
          #basically recurse, but we never got more than one level down so just 
          #create the new context here
          my @innerstack = (); 
          my @innerparstack = ();
          # use style file definition
          $newarg = $style_for_target{$token->[1]};       
          my $pat = HTML::TokeParser->new(\$newarg);
          my $tokenpat = '';
          my $partstring = '';
   
          while  ($tokenpat = $pat->get_token) {
    if ($tokenpat->[0] eq 'T') {
      $partstring = $tokenpat->[1];
    } elsif ($tokenpat->[0] eq 'S') {
      push (@innerstack,$tokenpat->[1]);
      push (@innerparstack,&parstring($tokenpat));
      $partstring = &callsub("start_$tokenpat->[1]", 
     $target, $tokenpat, \@innerparstack,
     $pat, $safeeval);
    } elsif ($tokenpat->[0] eq 'E') {
      #clear out any tags that didn't end
      while ($tokenpat->[1] ne $innerstack[$#innerstack] 
     && ($#innerstack > 0)) {pop @innerstack;pop @innerparstack;}
      $partstring = &callsub("end_$tokenpat->[1]",
     $target, $tokenpat, \@innerparstack,
     $pat, $safeeval);
    }
    #pass both the variable to the style tag, and the tag we 
    #are processing inside the <definedtag>
    if ($partstring ne "" ) {
      $finaloutput .= &Apache::run::evaluate($partstring,$safeeval,
    $parstack[$#parstack].$innerparstack[$#innerparstack]);
    }
    if ($tokenpat->[0] eq 'E') { pop @innerstack;pop @innerparstack; }
        }         }
      }       } else {
     } else {         my $result = &callsub("start_$token->[1]", $target, $token,\@parstack,
 #--------------------------------------------------------------- outtext output       $pars, $safeeval);
      while ($stoken = $pstyle->get_token and $stoken->[1] ne 'outtext') {         if ($result ne "" ) {
    if ($stoken->[1] eq 'definetag') {   $finaloutput .= &Apache::run::evaluate($result,$safeeval,
      $flag = 1;   $parstack[$#parstack]);
              last;  
    }  
       }  
      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) {     } elsif ($token->[0] eq 'E')  {
  while ($stoken = $pstyle->get_token) {       #clear out any tags that didn't end
  if ($stoken->[1] ne $target) {       while ($token->[1] ne $stack[$#stack] 
    if ($stoken->[0] eq 'S') {      && ($#stack > 0)) {pop @stack;pop @parstack;}
        my $flagelem = 0;  
                for (my $i=$#value_style-1;$i>0;$i=$i-2) {       if (exists $style_for_target{'/'."$token->[1]"}) {
    if ($stoken->[1] eq $value_style[$i]) {         my @innerstack = (); 
        $flagelem = 1;         my @innerparstack = ();
                        $iele = $i+1;         $newarg = $style_for_target{'/'."$token->[1]"};
                        last;         my $pat = HTML::TokeParser->new(\$newarg);
    }         my $tokenpat;
        }         my $partstring = '';
        if ($flagelem == 0) {         
          $current_value .= $stoken->[4];         while  ($tokenpat = $pat->get_token) {
             } else {   if ($tokenpat->[0] eq 'T') {
    $current_value .= $value_style[$iele];     $partstring = $tokenpat->[1];
        }   } elsif ($tokenpat->[0] eq 'S') {
    }      push (@innerstack,$tokenpat->[1]);
            if ($stoken->[0] eq 'E') {     push (@innerparstack,&parstring($tokenpat));
        my $flagelem = 0;     $partstring = &callsub("start_$tokenpat->[1]", 
                for (my $i=$#value_style-1;$i>0;$i=$i-2) {    $target, $tokenpat, \@innerparstack,
    if ('/'.$stoken->[1] eq $value_style[$i]) {    $pat, $safeeval);
        $flagelem = 1;   } elsif ($tokenpat->[0] eq 'E') {
                        $iele = $i+1;     #clear out any tags that didn't end
                        last;     while ($tokenpat->[1] ne $innerstack[$#innerstack] 
    }    && ($#innerstack > 0)) {pop @innerstack;pop @innerparstack;}
        }     $partstring = &callsub("end_$tokenpat->[1]",
        if ($flagelem == 0) {    $target, $tokenpat, \@innerparstack,
                  $current_value .= $stoken->[2];    $pat, $safeeval);
             } else {  
    $current_value .= $value_style[$iele];  
        }  
    }   
            if ($stoken->[0] eq 'T') {  
              $current_value .= $stoken->[1];   
    }                   
  }  else {        
  last;  
  }   }
         }   #pass both the variable to the style tag, and the tag we 
        } elsif ($stoken->[0] eq 'S' and $stoken->[1] ne $target) {   #are processing inside the <definedtag>
   my $tempotempo = $stoken->[1];   if ( $partstring ne "" ) {
    while ($stoken = $pstyle->get_token and $stoken->[1] ne $tempotempo) {     $finaloutput .= &Apache::run::evaluate($partstring,$safeeval,
    }   $parstack[$#parstack].$innerparstack[$#innerparstack]);
    }
    if ($tokenpat->[0] eq 'E') { pop @innerstack;pop @innerparstack; }
          }
        } else {
          my $result = &callsub("end_$token->[1]", $target, $token, \@parstack,
        $pars,$safeeval);
          if ($result ne "") {
    $finaloutput .= &Apache::run::evaluate($result,$safeeval,
    $parstack[$#parstack]);
        }         }
        }
        pop @stack; 
        pop @parstack;
      }
    }
    return $finaloutput;
   }
   
        while ($stoken = $pstyle->get_token) {  sub callsub {
         if ($stoken->[0] eq 'T') {    my ($sub,$target,$token,$parstack,$parser,$safeeval)=@_;
           $current_value .= $stoken->[1];    my $currentstring='';
  }     {
         if ($stoken->[0] eq 'E') {      no strict 'refs';
   last;      if (my $space=$Apache::lonxml::alltags{$token->[1]}) {
  }         #print "Calling sub $sub in $space \n";
         if ($stoken->[0] eq 'S') {        $sub="$space\:\:$sub";
   last;        $currentstring = &$sub($target,$token,\@$parstack,$parser,$safeeval);
  }      } else {
        }             #print "NOT Calling sub $sub\n";
             if (defined($token->[4])) {
    $currentstring = $token->[4];
         } else {
    $currentstring = $token->[2];
       }        }
      }  
     }      }
           use strict 'refs';
    }        }
    $current_value =~ s/(\s)+/$1/g;    return $currentstring;
      if ($current_value ne ' ' and $current_value ne '' ) {    
        push (@value_style,lc $current_key,$current_value);  
      }  
      $current_key = '';  
      $current_value = '';           
   
   }    
   my %style_for_target = @value_style;     
 #--------------------------------------------------------------- check printing  
 #  while (($current_key,$current_value) = each %style_for_target) {  
 #       print "$current_key => $current_value\n";  
 #  }  
 #---------------------------------------------------------------- return result  
   return %style_for_target;   
 }  }
   
   sub parstring {
     my ($token) = @_;
     my $temp='';
     map {$temp .= "my \$$_=\"$token->[2]->{$_}\";"} @{$token->[3]};
     return $temp;
   }
 1;  1;
 __END__  __END__
   
   
   
   
   

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


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