Annotation of loncom/xml/lonxml.pm, revision 1.18

1.2       sakharuk    1: # The LearningOnline Network with CAPA
1.3       sakharuk    2: # XML Parser Module 
1.2       sakharuk    3: #
1.3       sakharuk    4: # last modified 06/26/00 by Alexander Sakharuk
1.2       sakharuk    5: 
1.4       albertel    6: package Apache::lonxml; 
1.1       sakharuk    7: 
                      8: use strict;
                      9: use HTML::TokeParser;
1.3       sakharuk   10: use Safe;
1.13      albertel   11: use Opcode;
1.7       albertel   12: 
                     13: sub register {
                     14:   my $space;
                     15:   my @taglist;
                     16:   my $temptag;
                     17:   ($space,@taglist) = @_;
                     18:   foreach $temptag (@taglist) {
                     19:     $Apache::lonxml::alltags{$temptag}=$space;
                     20:   }
                     21: }
1.11      sakharuk   22:                                      
1.4       albertel   23: use Apache::style;
1.3       sakharuk   24: use Apache::lontexconvert;
1.7       albertel   25: use Apache::run;
1.4       albertel   26: use Apache::londefdef;
1.7       albertel   27: use Apache::scripttag;
1.3       sakharuk   28: #==================================================   Main subroutine: xmlparse  
                     29: 
                     30: sub xmlparse {
                     31: 
1.18    ! albertel   32:  my ($target,$content_file_string,$safeinit,%style_for_target) = @_;
1.16      albertel   33:  my @pars = ();
                     34:  push (@pars,HTML::TokeParser->new(\$content_file_string));
1.3       sakharuk   35:  my $currentstring = '';
                     36:  my $finaloutput = ''; 
                     37:  my $newarg = '';
1.16      albertel   38:  my $result;
1.3       sakharuk   39:  my $safeeval = new Safe;
1.6       albertel   40:  $safeeval->permit("entereval");
1.13      albertel   41:  $safeeval->permit(":base_math");
1.18    ! albertel   42:  if ( $safeinit ne '') {&Apache::run::run($safeinit,$safeeval);}
1.3       sakharuk   43: #-------------------- Redefinition of the target in the case of compound target
                     44: 
                     45:  ($target, my @tenta) = split('&&',$target);
                     46: 
                     47:  my @stack = (); 
                     48:  my @parstack = ();
1.17      albertel   49:  &initdepth;
1.3       sakharuk   50:  my $token;
1.16      albertel   51:  while ( $#pars > -1 ) {
                     52:    while ($token = $pars[$#pars]->get_token) {
                     53:      if ($token->[0] eq 'T') {
                     54:        $result=$token->[1];
                     55: #       $finaloutput .= &Apache::run::evaluate($token->[1],$safeeval,'');
                     56:      } elsif ($token->[0] eq 'S') {
                     57:        # add tag to stack 	    
                     58:        push (@stack,$token->[1]);
                     59:        # add parameters list to another stack
                     60:        push (@parstack,&parstring($token));
1.17      albertel   61:        &increasedepth();       
1.16      albertel   62:        if (exists $style_for_target{$token->[1]}) {
                     63: 	 $finaloutput .= &recurse($style_for_target{$token->[1]},
                     64: 				  $target,$safeeval,\%style_for_target,
                     65: 				  @parstack);
                     66:        } else {
1.17      albertel   67: 	 $result = &callsub("start_$token->[1]", $target, $token,\@parstack,
1.16      albertel   68: 			       \@pars, $safeeval, \%style_for_target);
                     69:        }              
                     70:      } elsif ($token->[0] eq 'E')  {
                     71:        #clear out any tags that didn't end
                     72:        while ($token->[1] ne $stack[$#stack] 
1.17      albertel   73: 	      && ($#stack > -1)) {pop @stack;pop @parstack;&decreasedepth;}
1.16      albertel   74:        
                     75:        if (exists $style_for_target{'/'."$token->[1]"}) {
                     76: 	 $finaloutput .= &recurse($style_for_target{'/'."$token->[1]"},
                     77: 				  $target,$safeeval,\%style_for_target,
                     78: 				  @parstack);
                     79:        } else {
1.17      albertel   80: 	 $result = &callsub("end_$token->[1]", $target, $token, \@parstack,
1.16      albertel   81: 			       \@pars,$safeeval, \%style_for_target);
1.13      albertel   82:        }
1.16      albertel   83:      }
                     84:      if ($result ne "" ) {
                     85:        if ( $#parstack > -1 ) { 
1.13      albertel   86: 	 $finaloutput .= &Apache::run::evaluate($result,$safeeval,
                     87: 						$parstack[$#parstack]);
1.16      albertel   88:        } else {
                     89: 	 $finaloutput .= &Apache::run::evaluate($result,$safeeval,'');
1.13      albertel   90:        }
1.16      albertel   91:        $result = '';
1.2       sakharuk   92:      }
1.17      albertel   93:      if ($token->[0] eq 'E') { pop @stack;pop @parstack;&decreasedepth;}
1.5       albertel   94:    }
1.16      albertel   95:    pop @pars;
1.3       sakharuk   96:  }
                     97:  return $finaloutput;
1.15      albertel   98: }
                     99: 
                    100: sub recurse {
                    101:   
                    102:   my @innerstack = (); 
                    103:   my @innerparstack = ();
                    104:   my ($newarg,$target,$safeeval,$style_for_target,@parstack) = @_;
1.16      albertel  105:   my @pat = ();
                    106:   push (@pat,HTML::TokeParser->new(\$newarg));
1.15      albertel  107:   my $tokenpat;
                    108:   my $partstring = '';
                    109:   my $output='';
1.16      albertel  110:   my $decls='';
                    111:   while ( $#pat > -1 ) {
                    112:     while  ($tokenpat = $pat[$#pat]->get_token) {
                    113:       if ($tokenpat->[0] eq 'T') {
                    114: 	$partstring = $tokenpat->[1];
                    115:       } elsif ($tokenpat->[0] eq 'S') {
                    116: 	push (@innerstack,$tokenpat->[1]);
                    117: 	push (@innerparstack,&parstring($tokenpat));
1.17      albertel  118: 	&increasedepth();
1.16      albertel  119: 	$partstring = &callsub("start_$tokenpat->[1]", 
                    120: 			       $target, $tokenpat, \@innerparstack,
                    121: 			       \@pat, $safeeval, $style_for_target);
                    122:       } elsif ($tokenpat->[0] eq 'E') {
                    123: 	#clear out any tags that didn't end
                    124: 	while ($tokenpat->[1] ne $innerstack[$#innerstack] 
1.17      albertel  125: 	       && ($#innerstack > -1)) {pop @innerstack;pop @innerparstack;
                    126: 					&decreasedepth;}
1.16      albertel  127: 	$partstring = &callsub("end_$tokenpat->[1]",
                    128: 			       $target, $tokenpat, \@innerparstack,
                    129: 			       \@pat, $safeeval, $style_for_target);
                    130:       }
                    131:       #pass both the variable to the style tag, and the tag we 
                    132:       #are processing inside the <definedtag>
                    133:       if ( $partstring ne "" ) {
                    134: 	if ( $#parstack > -1 ) { 
                    135: 	  if ( $#innerparstack > -1 ) { 
                    136: 	    $decls= $parstack[$#parstack].$innerparstack[$#innerparstack];
                    137: 	  } else {
                    138: 	    $decls= $parstack[$#parstack];
                    139: 	  }
                    140: 	} else {
                    141: 	  if ( $#innerparstack > -1 ) { 
                    142: 	    $decls=$innerparstack[$#innerparstack];
                    143: 	  } else {
                    144: 	    $decls='';
                    145: 	  }
                    146: 	}
                    147: 	$output .= &Apache::run::evaluate($partstring,$safeeval,$decls);
                    148: 	$partstring = '';
                    149:       }
1.17      albertel  150:       if ($tokenpat->[0] eq 'E') { pop @innerstack;pop @innerparstack;
                    151: 				 &decreasedepth;}
1.15      albertel  152:     }
1.16      albertel  153:     pop @pat;
1.15      albertel  154:   }
                    155:   return $output;
1.7       albertel  156: }
                    157: 
                    158: sub callsub {
1.14      albertel  159:   my ($sub,$target,$token,$parstack,$parser,$safeeval,$style)=@_;
1.7       albertel  160:   my $currentstring='';
                    161:   {
                    162:     no strict 'refs';
                    163:     if (my $space=$Apache::lonxml::alltags{$token->[1]}) {
                    164:       #print "Calling sub $sub in $space \n";
                    165:       $sub="$space\:\:$sub";
1.17      albertel  166:       $Apache::lonxml::curdepth=join('_',@Apache::lonxml::depthcounter);
1.16      albertel  167:       $currentstring = &$sub($target,$token,$parstack,$parser,
                    168: 			     $safeeval,$style);
1.7       albertel  169:     } else {
1.12      sakharuk  170:       #print "NOT Calling sub $sub\n";
1.7       albertel  171:       if (defined($token->[4])) {
                    172: 	$currentstring = $token->[4];
                    173:       } else {
                    174: 	$currentstring = $token->[2];
                    175:       }
                    176:     }
                    177:     use strict 'refs';
                    178:   }
                    179:   return $currentstring;
1.17      albertel  180: }
                    181: 
                    182: sub initdepth {
                    183:   @Apache::lonxml::depthcounter=();
                    184:   $Apache::lonxml::depth=-1;
                    185:   $Apache::lonxml::olddepth=-1;
                    186: }
                    187: 
                    188: sub increasedepth {
                    189:   if ($Apache::lonxml::depth<$Apache::lonxml::olddepth-1) {
                    190:     $#Apache::lonxml::depthcounter--;
                    191:     $Apache::lonxml::olddepth=$Apache::lonxml::depth;
                    192:   }
                    193:   $Apache::lonxml::depth++;
                    194:   $Apache::lonxml::depthcounter[$Apache::lonxml::depth]++;
                    195:   if ($Apache::lonxml::depthcounter[$Apache::lonxml::depth]==1) {
                    196:     $Apache::lonxml::olddepth=$Apache::lonxml::depth;
                    197:   }
                    198: }
                    199: 
                    200: sub decreasedepth {
                    201:   $Apache::lonxml::depth--;
1.1       sakharuk  202: }
                    203: 
1.8       albertel  204: sub parstring {
                    205:   my ($token) = @_;
                    206:   my $temp='';
                    207:   map {$temp .= "my \$$_=\"$token->[2]->{$_}\";"} @{$token->[3]};
                    208:   return $temp;
                    209: }
1.1       sakharuk  210: 1;
                    211: __END__
1.11      sakharuk  212: 
                    213: 
                    214: 
                    215: 
                    216: 

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