package Apache::lonxml; use strict; use HTML::TokeParser; use Safe; use Apache::Constants qw(:common); use Apache::lontexconvert; #======================================================= Main subroutine: xmlparse sub xmlparse { my ($target,$content_file_string,%style_for_target) = @_; my $pars = HTML::TokeParser->new(\$content_file_string); my $currentstring = ''; my $finaloutput = ''; my $newarg = ''; my $tempostring = ''; my $tempocont = ''; my $safeeval = new Safe; #------------------------- Redefinition of the target in the case of compound target ($target, my @tenta) = split('&&',$target); #------------------------------ Stack definition (in stack we have all current tags) my @stack = (); my @parstack = (); #------------------------------------------ Parse input string (content_file_string) my $token; while ($token = $pars->get_token) { if ($token->[0] eq 'T') { $finaloutput .= $token->[1]; $tempocont .= $token->[1]; } elsif ($token->[0] eq 'S') { #------------------------------------------------------------------ add tag to stack push (@stack,$token->[1]); #---------------------------------------------- add parameters list to another stack map {$tempostring .= "$_=$token->[2]->{$_},"} @{$token->[3]}; push (@parstack,$tempostring); $tempostring = ''; $tempocont = ''; if (exists $style_for_target{$token->[1]}) { #--------------------------------------------------------- use style file definition $newarg = $style_for_target{$token->[1]}; if (index($newarg,'script') != -1 ) { my $pat = HTML::TokeParser->new(\$newarg); my $tokenpat; my $partstring = ''; my $oustring = ''; my $outputstring; while ($tokenpat = $pat->get_token) { if ($tokenpat->[0] eq 'T') { $oustring .= $tokenpat->[1]; } elsif ($tokenpat->[0] eq 'S') { if ($tokenpat->[1] eq 'script') { while ($tokenpat = $pat->get_token and $tokenpat->[1] ne 'script') { if ($tokenpat->[0] eq 'S') { $partstring .= $tokenpat->[4]; } elsif ($tokenpat->[0] eq 'T') { $partstring .= $tokenpat->[1]; } elsif ($tokenpat->[0] eq 'E') { $partstring .= $tokenpat->[2]; } } map {$partstring =~ s/\$$_/$token->[2]->{$_}/g; } @{$token->[3]}; &run($partstring,$safeeval); $partstring = ''; } elsif ($tokenpat->[1] eq 'evaluate') { $outputstring = &evaluate($tokenpat->[2]{expression},$safeeval); $oustring .= $outputstring; } else { $oustring .= $tokenpat->[4]; } } elsif ($tokenpat->[0] eq 'E' and $tokenpat->[1] ne 'evaluate') { $oustring .= $tokenpat->[1]; } } $newarg = $oustring; } else { map {$newarg =~ s/\$$_/$token->[2]->{$_}/g; } @{$token->[3]}; } $finaloutput .= $newarg; } else { #----------------------------------------------------- use default definition of tag my $sub="start_$token->[1]"; { no strict 'refs'; if (defined (&$sub)) { $currentstring = &$sub($target,$token,\@parstack); $finaloutput .= $currentstring; $currentstring = ''; } else { $finaloutput .= $token->[4]; } use strict 'refs'; } } } elsif ($token->[0] eq 'E') { pop @stack; unless (exists $style_for_target{$token->[1]}) { my $sub="end_$token->[1]"; { no strict 'refs'; if (defined (&$sub)) { $currentstring = &$sub($target,$token,\@parstack); $finaloutput .= $currentstring; $currentstring = ''; } else { $finaloutput .= $token->[4]; } use strict 'refs'; } } #------------------------------------------------------- end tag from the style file if (exists $style_for_target{'/'."$token->[1]"}) { $newarg = $style_for_target{'/'."$token->[1]"}; my @very_temp = split(',',@parstack[$#parstack]); map {my @ret= split('=',$_); $newarg =~ s/\$$ret[0]/$ret[1]/g; } @very_temp; $finaloutput .= $newarg; } pop @parstack; } } return $finaloutput; } #================================================================== style subroutine sub styleparser { my ($target,$content_style_string) = @_; #------------------------------------------------ target redefinition (if necessary) my @target_string = ''; my $element; ($element,@target_string) = split ('&&',$target); map {$content_style_string =~ s/\<(.*)$_\>/\<$1$element\>/g; } @target_string; $target = $element; #------------------------------------------------- create a table for defined target #---------------------------------------------- from the information from Style File my @value_style = (); my $current_key = ''; my $current_value = ''; my $pstyle = HTML::TokeParser->new(\$content_style_string); my $stoken; while ($stoken = $pstyle->get_token) { #---------------------------------------------------------- start for tag definition if ($stoken->[0] eq 'S' and $stoken->[1] eq 'definetag') { #------------------------------------------------------------------- new key in hash $current_key = $stoken->[2]{name}; if ($target eq 'meta') { #-------------------------------------------------- reserved for the metadate output } else { #-------------------------------------------------------------------- outtext output while ($stoken = $pstyle->get_token and $stoken->[1] ne 'outtext') { } 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') { $current_value .= $stoken->[4]; } if ($stoken->[0] eq 'E') { $current_value .= $stoken->[2]; } if ($stoken->[0] eq 'T') { $current_value .= $stoken->[1]; } } else { last; } } } elsif ($stoken->[0] eq 'S' and $stoken->[1] ne $target) { while ($stoken = $pstyle->get_token and $stoken->[0] ne 'E') { } } while ($stoken = $pstyle->get_token) { if ($stoken->[0] eq 'T') { $current_value .= $stoken->[1]; } if ($stoken->[0] eq 'E') { last; } if ($stoken->[0] eq 'S') { last; } } } } } 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 %style_for_target; } #=============================================================== Subroutine definition #--------------------------------------------------------------------------------- Run sub evaluate { my ($expression,$safeeval) = @_; return $safeeval->reval($expression); } sub run { my ($code,$safeeval) = @_; $safeeval->reval($code); } #===================================================================== TAG SUBROUTINES #----------------------------------------------------------------------------- tag sub start_m { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = "\$out = lontexconvert::converted(\$in = '\$'.\""; } elsif ($target eq 'tex') { $currentstring = "\$"; } return $currentstring; } sub end_m { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = "\".'\$') "; } elsif ($target eq 'tex') { $currentstring = "\$"; } return $currentstring; } #-------------------------------------------------------------------------- tag sub start_html { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[4]; } return $currentstring; } sub end_html { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[2]; } return $currentstring; } #-------------------------------------------------------------------------- tag sub start_head { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[4]; } return $currentstring; } sub end_head { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[2]; } return $currentstring; } #--------------------------------------------------------------------------- tag sub start_map { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[4]; } return $currentstring; } sub end_map { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[2]; } return $currentstring; } #------------------------------------------------------------------------ tag sub start_applet { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[4]; } return $currentstring; } sub end_applet { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[2]; } return $currentstring; } #------------------------------------------------------------------------ tag sub start_input { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[4]; } return $currentstring; } sub end_input { my ($target,$token) = @_; my $currentstring = ''; if ($target eq 'web') { $currentstring = $token->[2]; } return $currentstring; } #----------------------------------------------------------------------