Diff for /loncom/xml/lonxml.pm between versions 1.129 and 1.143

version 1.129, 2001/09/14 20:18:13 version 1.143, 2002/01/01 16:37:20
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
 # XML Parser Module   # XML Parser Module 
 #  #
   # $Id$
   #
   # Copyright Michigan State University Board of Trustees
   #
   # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   #
   # LON-CAPA is free software; you can redistribute it and/or modify
   # it under the terms of the GNU General Public License as published by
   # the Free Software Foundation; either version 2 of the License, or
   # (at your option) any later version.
   #
   # LON-CAPA is distributed in the hope that it will be useful,
   # but WITHOUT ANY WARRANTY; without even the implied warranty of
   # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   # GNU General Public License for more details.
   #
   # You should have received a copy of the GNU General Public License
   # along with LON-CAPA; if not, write to the Free Software
   # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   #
   # /home/httpd/html/adm/gpl.txt
   #
   # http://www.lon-capa.org/
   #
   # Copyright for TtHfunc and TtMfunc by Ian Hutchinson. 
   # TtHfunc and TtMfunc (the "Code") may be compiled and linked into 
   # binary executable programs or libraries distributed by the 
   # Michigan State University (the "Licensee"), but any binaries so 
   # distributed are hereby licensed only for use in the context
   # of a program or computational system for which the Licensee is the 
   # primary author or distributor, and which performs substantial 
   # additional tasks beyond the translation of (La)TeX into HTML.
   # The C source of the Code may not be distributed by the Licensee
   # to any other parties under any circumstances.
   #
 # last modified 06/26/00 by Alexander Sakharuk  # last modified 06/26/00 by Alexander Sakharuk
 # 11/6 Gerd Kortemeyer  # 11/6 Gerd Kortemeyer
 # 6/1/1 Gerd Kortemeyer  # 6/1/1 Gerd Kortemeyer
Line 14 Line 49
 # 6/16 Gerd Kortemeyer  # 6/16 Gerd Kortemeyer
 # 7/27 H. K. Ng  # 7/27 H. K. Ng
 # 8/7,8/9,8/10,8/11,8/15,8/16,8/17,8/18,8/20,8/23,8/24 Gerd Kortemeyer  # 8/7,8/9,8/10,8/11,8/15,8/16,8/17,8/18,8/20,8/23,8/24 Gerd Kortemeyer
   # Guy Albertelli
   # 9/26 Gerd Kortemeyer
   # Dec Guy Albertelli
   # YEAR=2002
   # 1/1 Gerd Kortemeyer
   #
   
 package Apache::lonxml;   package Apache::lonxml; 
 use vars   use vars 
Line 28  use Math::Random qw(:all); Line 69  use Math::Random qw(:all);
 use Opcode;  use Opcode;
   
 sub register {  sub register {
   my $space;    my ($space,@taglist) = @_;
   my @taglist;    foreach my $temptag (@taglist) {
   my $temptag;      push(@{ $Apache::lonxml::alltags{$temptag} },$space);
   ($space,@taglist) = @_;  
   foreach $temptag (@taglist) {  
     $Apache::lonxml::alltags{$temptag}=$space;  
   }    }
 }  }
   
   sub deregister {
     my ($space,@taglist) = @_;
     foreach my $temptag (@taglist) {
       my $tempspace = $Apache::lonxml::alltags{$temptag}[-1];
       if ($tempspace eq $space) {
         pop(@{ $Apache::lonxml::alltags{$temptag} });
       }
     }
     #&printalltags();
   }
   
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use Apache::lontexconvert;  use Apache::lontexconvert;
 use Apache::style;  use Apache::style;
Line 46  use Apache::scripttag; Line 95  use Apache::scripttag;
 use Apache::edit;  use Apache::edit;
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::File;  use Apache::File;
   use Apache::loncommon;
   
 #==================================================   Main subroutine: xmlparse    #==================================================   Main subroutine: xmlparse  
 #debugging control, to turn on debugging modify the correct handler  #debugging control, to turn on debugging modify the correct handler
Line 216  sub maketoken { Line 266  sub maketoken {
 }  }
   
 sub printtokenheader {  sub printtokenheader {
     my ($target,$token,$symb,$tuname,$tudom,$tcrsid)=@_;      my ($target,$token,$tsymb,$tcrsid,$tudom,$tuname)=@_;
     unless ($token) { return ''; }      unless ($token) { return ''; }
   
     unless ($symb) {      my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();
  $symb=&Apache::lonnet::symbread();      unless ($tsymb) {
    $tsymb=$symb;
     }      }
     unless ($tuname) {      unless ($tuname) {
  $tuname=$ENV{'user.name'};   $tuname=$name;
         $tudom=$ENV{'user.domain'};          $tudom=$domain;
         $tcrsid=$ENV{'request.course.id'};          $tcrsid=$courseid;
     }      }
   
     my %reply=&Apache::lonnet::get('environment',      my %reply=&Apache::lonnet::get('environment',
Line 260  sub fontsettings() { Line 311  sub fontsettings() {
   
 sub registerurl {  sub registerurl {
     my $forcereg=shift;      my $forcereg=shift;
       if ($ENV{'request.publicaccess'}) {
    return 
            '<script>function LONCAPAreg(){} function LONCAPAstale(){}</script>';
       }
     if ($Apache::lonxml::registered && !$forcereg) { return ''; }      if ($Apache::lonxml::registered && !$forcereg) { return ''; }
     $Apache::lonxml::registered=1;      $Apache::lonxml::registered=1;
     if (($ENV{'REQUEST_URI'}!~/^\/(res\/)*adm\//) || ($forcereg)) {      if (($ENV{'REQUEST_URI'}!~/^\/(res\/)*adm\//) || ($forcereg)) {
Line 381  sub unloadevents() { Line 436  sub unloadevents() {
 sub printalltags {  sub printalltags {
   my $temp;    my $temp;
   foreach $temp (sort keys %Apache::lonxml::alltags) {    foreach $temp (sort keys %Apache::lonxml::alltags) {
     &Apache::lonxml::debug("$temp -- $Apache::lonxml::alltags{$temp}");      &Apache::lonxml::debug("$temp -- ".
     join(',',@{ $Apache::lonxml::alltags{$temp} }));
   }    }
 }  }
   
Line 419  sub htmlclean { Line 475  sub htmlclean {
   
     my $tree = HTML::TreeBuilder->new;      my $tree = HTML::TreeBuilder->new;
     $tree->ignore_unknown(0);      $tree->ignore_unknown(0);
       
     $tree->parse($raw);      $tree->parse($raw);
   
     my $output= $tree->as_HTML(undef,' ');      my $output= $tree->as_HTML(undef,' ');
        
     $output=~s/\<(br|hr|img|meta|allow)([^\>\/]*)\>/\<$1$2 \/\>/gis;      $output=~s/\<(br|hr|img|meta|allow)([^\>\/]*)\>/\<$1$2 \/\>/gis;
     $output=~s/\<\/(br|hr|img|meta|allow)\>//gis;      $output=~s/\<\/(br|hr|img|meta|allow)\>//gis;
     unless ($full) {      unless ($full) {
Line 451  sub inner_xmlparse { Line 507  sub inner_xmlparse {
   $result=$token->[2];    $result=$token->[2];
  }   }
       } elsif ($token->[0] eq 'S') {        } elsif ($token->[0] eq 'S') {
  # add tag to stack       # add tag to stack
  push (@$stack,$token->[1]);   push (@$stack,$token->[1]);
  # add parameters list to another stack   # add parameters list to another stack
  push (@$parstack,&parstring($token));   push (@$parstack,&parstring($token));
  &increasedepth($token);          &increasedepth($token);
  if (exists $$style_for_target{$token->[1]}) {   if (exists $$style_for_target{$token->[1]}) {
   if ($Apache::lonxml::redirection) {    if ($Apache::lonxml::redirection) {
     $Apache::lonxml::outputstack['-1'] .=        $Apache::lonxml::outputstack['-1'] .=
       &recurse($$style_for_target{$token->[1]},$target,$safeeval,        &recurse($$style_for_target{$token->[1]},$target,$safeeval,
        $style_for_target,@$parstack);         $style_for_target,@$parstack);
   } else {    } else {
Line 468  sub inner_xmlparse { Line 524  sub inner_xmlparse {
  } else {   } else {
   $result = &callsub("start_$token->[1]", $target, $token, $stack,    $result = &callsub("start_$token->[1]", $target, $token, $stack,
      $parstack, $pars, $safeeval, $style_for_target);       $parstack, $pars, $safeeval, $style_for_target);
  }                 }
       } elsif ($token->[0] eq 'E') {        } elsif ($token->[0] eq 'E') {
  #clear out any tags that didn't end   #clear out any tags that didn't end
  while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) {   while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) {
   &Apache::lonxml::warning("Unbalanced tags in resource $$stack['-1']");    &Apache::lonxml::warning('Missing tag &lt;/'.$$stack['-1'].'&gt; in file');
   &end_tag($stack,$parstack,$token);    &end_tag($stack,$parstack,$token);
  }   }
   
  if (exists $$style_for_target{'/'."$token->[1]"}) {   if (exists($$style_for_target{'/'."$token->[1]"})) {
   if ($Apache::lonxml::redirection) {    if ($Apache::lonxml::redirection) {
     $Apache::lonxml::outputstack['-1'] .=        $Apache::lonxml::outputstack['-1'] .=  
       &recurse($$style_for_target{'/'."$token->[1]"},        &recurse($$style_for_target{'/'."$token->[1]"},
Line 486  sub inner_xmlparse { Line 542  sub inner_xmlparse {
      $target,$safeeval,$style_for_target,       $target,$safeeval,$style_for_target,
      @$parstack);       @$parstack);
   }    }
       
  } else {   } else {
   $result = &callsub("end_$token->[1]", $target, $token, $stack,    $result = &callsub("end_$token->[1]", $target, $token, $stack,
      $parstack, $pars,$safeeval, $style_for_target);       $parstack, $pars,$safeeval, $style_for_target);
Line 537  sub recurse { Line 592  sub recurse {
   my $partstring = '';    my $partstring = '';
   my $output='';    my $output='';
   my $decls='';    my $decls='';
     &Apache::lonxml::debug("Recursing");
   while ( $#pat > -1 ) {    while ( $#pat > -1 ) {
     while  ($tokenpat = $pat[$#pat]->get_token) {      while  ($tokenpat = $pat[$#pat]->get_token) {
       if (($tokenpat->[0] eq 'T') || ($tokenpat->[0] eq 'C') || ($tokenpat->[0] eq 'D') ) {        if (($tokenpat->[0] eq 'T') || ($tokenpat->[0] eq 'C') || ($tokenpat->[0] eq 'D') ) {
Line 554  sub recurse { Line 610  sub recurse {
  #clear out any tags that didn't end   #clear out any tags that didn't end
  while ($tokenpat->[1] ne $innerstack[$#innerstack]    while ($tokenpat->[1] ne $innerstack[$#innerstack] 
        && ($#innerstack > -1)) {         && ($#innerstack > -1)) {
   &Apache::lonxml::warning("Unbalanced tags in resource $innerstack['-1']");    &Apache::lonxml::warning('Missing tag &lt;/'.$innerstack['-1'].'&gt; in style');
   &end_tag(\@innerstack,\@innerparstack,$tokenpat);    &end_tag(\@innerstack,\@innerparstack,$tokenpat);
  }   }
  $partstring = &callsub("end_$tokenpat->[1]", $target, $tokenpat,   $partstring = &callsub("end_$tokenpat->[1]", $target, $tokenpat,
Line 588  sub recurse { Line 644  sub recurse {
     pop @pat;      pop @pat;
     pop @Apache::lonxml::pwd;      pop @Apache::lonxml::pwd;
   }    }
     &Apache::lonxml::debug("Exiting Recursing");
   return $output;    return $output;
 }  }
   
Line 599  sub callsub { Line 656  sub callsub {
     my $sub1;      my $sub1;
     no strict 'refs';      no strict 'refs';
     my $tag=$token->[1];      my $tag=$token->[1];
     my $space=$Apache::lonxml::alltags{$tag};      my $space=$Apache::lonxml::alltags{$tag}[-1];
     if (!$space) {      if (!$space) {
  $tag=~tr/A-Z/a-z/;        $tag=~tr/A-Z/a-z/;
  $sub=~tr/A-Z/a-z/;   $sub=~tr/A-Z/a-z/;
  $space=$Apache::lonxml::alltags{$tag}   $space=$Apache::lonxml::alltags{$tag}[-1]
     }      }
   
     my $deleted=0;      my $deleted=0;
Line 799  sub decreasedepth { Line 856  sub decreasedepth {
     $Apache::lonxml::olddepth=$Apache::lonxml::depth+1;      $Apache::lonxml::olddepth=$Apache::lonxml::depth+1;
   }    }
   if (  $Apache::lonxml::depth < -1) {    if (  $Apache::lonxml::depth < -1) {
     &Apache::lonxml::warning("Unbalanced tags in resource");         &Apache::lonxml::warning("Missing tags, unable to properly run file.");
     $Apache::lonxml::depth='-1';      $Apache::lonxml::depth='-1';
   }    }
   my $curdepth=join('_',@Apache::lonxml::depthcounter);    my $curdepth=join('_',@Apache::lonxml::depthcounter);
Line 871  sub newparser { Line 928  sub newparser {
 sub parstring {  sub parstring {
   my ($token) = @_;    my ($token) = @_;
   my $temp='';    my $temp='';
   map {    foreach (@{$token->[3]}) {
     unless ($_=~/\W/) {      unless ($_=~/\W/) {
       my $val=$token->[2]->{$_};        my $val=$token->[2]->{$_};
       $val =~ s/([\%\@\\])/\\$1/g;        $val =~ s/([\%\@\\])/\\$1/g;
       #if ($val =~ m/^[\%\@]/) { $val="\\".$val; }        #if ($val =~ m/^[\%\@]/) { $val="\\".$val; }
       $temp .= "my \$$_=\"$val\";"        $temp .= "my \$$_=\"$val\";"
     }      }
   } @{$token->[3]};    }
   return $temp;    return $temp;
 }  }
   
Line 891  sub writeallows { Line 948  sub writeallows {
     my $thisdir=$thisurl;      my $thisdir=$thisurl;
     $thisdir=~s/\/[^\/]+$//;      $thisdir=~s/\/[^\/]+$//;
     my %httpref=();      my %httpref=();
     map {      foreach (@extlinks) {
        $httpref{'httpref.'.         $httpref{'httpref.'.
          &Apache::lonnet::hreflocation($thisdir,$_)}=$thisurl;           &Apache::lonnet::hreflocation($thisdir,$_)}=$thisurl;
     } @extlinks;      }
     @extlinks=();      @extlinks=();
     &Apache::lonnet::appenv(%httpref);      &Apache::lonnet::appenv(%httpref);
 }  }
Line 904  sub writeallows { Line 961  sub writeallows {
 #  #
 sub afterburn {  sub afterburn {
     my $result=shift;      my $result=shift;
     map {      foreach (split(/&/,$ENV{'QUERY_STRING'})) {
        my ($name, $value) = split(/=/,$_);         my ($name, $value) = split(/=/,$_);
        $value =~ tr/+/ /;         $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;         $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
Line 913  sub afterburn { Line 970  sub afterburn {
               $ENV{'form.'.$name}=$value;                $ENV{'form.'.$name}=$value;
    }     }
        }         }
     } (split(/&/,$ENV{'QUERY_STRING'}));      }
     if ($ENV{'form.highlight'}) {      if ($ENV{'form.highlight'}) {
         map {         foreach (split(/\,/,$ENV{'form.highlight'})) {
            my $anchorname=$_;             my $anchorname=$_;
    my $matchthis=$anchorname;     my $matchthis=$anchorname;
            $matchthis=~s/\_+/\\s\+/g;             $matchthis=~s/\_+/\\s\+/g;
            $result=~s/($matchthis)/\<font color=\"red\"\>$1\<\/font\>/gs;             $result=~s/($matchthis)/\<font color=\"red\"\>$1\<\/font\>/gs;
        } split(/\,/,$ENV{'form.highlight'});         }
     }      }
     if ($ENV{'form.link'}) {      if ($ENV{'form.link'}) {
         map {         foreach (split(/\,/,$ENV{'form.link'})) {
            my ($anchorname,$linkurl)=split(/\>/,$_);             my ($anchorname,$linkurl)=split(/\>/,$_);
    my $matchthis=$anchorname;     my $matchthis=$anchorname;
            $matchthis=~s/\_+/\\s\+/g;             $matchthis=~s/\_+/\\s\+/g;
            $result=~s/($matchthis)/\<a href=\"$linkurl\"\>$1\<\/a\>/gs;             $result=~s/($matchthis)/\<a href=\"$linkurl\"\>$1\<\/a\>/gs;
        } split(/\,/,$ENV{'form.link'});         }
     }      }
     if ($ENV{'form.anchor'}) {      if ($ENV{'form.anchor'}) {
         my $anchorname=$ENV{'form.anchor'};          my $anchorname=$ENV{'form.anchor'};
Line 999  sub handler { Line 1056  sub handler {
   } else {    } else {
     $request->content_type('text/html');      $request->content_type('text/html');
   }    }
       &Apache::loncommon::no_cache($request);
   $request->send_http_header;    $request->send_http_header;
     
   return OK if $request->header_only;    return OK if $request->header_only;
   
   
Line 1068  sub error { Line 1125  sub error {
     #notify course      #notify course
     if ( $ENV{'request.course.id'} ) {      if ( $ENV{'request.course.id'} ) {
       my $users=$ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'};        my $users=$ENV{'course.'.$ENV{'request.course.id'}.'.comment.email'};
         my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'});
       foreach my $user (split /\,/, $users) {        foreach my $user (split /\,/, $users) {
  ($user,my $domain) = split /:/, $user;   ($user,my $domain) = split /:/, $user;
  &Apache::lonmsg::user_normal_msg($user,$domain,"Error in $ENV{'request.filename'}",$_[0]);   &Apache::lonmsg::user_normal_msg($user,$domain,
           "Error [$declutter]",$_[0]);
       }        }
     }      }
   
Line 1091  sub get_param { Line 1150  sub get_param {
   if ( ! $context ) { $context = -1; }    if ( ! $context ) { $context = -1; }
   my $args ='';    my $args ='';
   if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }    if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
   return &Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'    if ( $args =~ /my \$$param=\"/ ) {
       return &Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
     } else {
       return undef;
     }
   }
   
   sub get_param_var {
     my ($param,$parstack,$safeeval,$context) = @_;
     if ( ! $context ) { $context = -1; }
     my $args ='';
     if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
     if ( $args !~ /my \$$param=\"/ ) { return undef; }
     my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
     if ($value =~ /^[\$\@\%]/) {
       return &Apache::run::run("return $value",$safeeval,1);
     } else {
       return $value;
     }
 }  }
   
 sub register_insert {  sub register_insert {
Line 1104  sub register_insert { Line 1181  sub register_insert {
     if ( $line =~ /^\#/ || $line =~ /^\s*\n/) { next; }      if ( $line =~ /^\#/ || $line =~ /^\s*\n/) { next; }
     if ( $line =~ /TABLE/ ) { last; }      if ( $line =~ /TABLE/ ) { last; }
     my ($tag,$descrip,$color,$function,$show) = split(/,/, $line);      my ($tag,$descrip,$color,$function,$show) = split(/,/, $line);
     $insertlist{"$tagnum.tag"} = $tag;      if ($tag) {
     $insertlist{"$tagnum.description"} = $descrip;        $insertlist{"$tagnum.tag"} = $tag;
     $insertlist{"$tagnum.color"} = $color;        $insertlist{"$tagnum.description"} = $descrip;
     $insertlist{"$tagnum.function"} = $function;        $insertlist{"$tagnum.color"} = $color;
     $insertlist{"$tagnum.show"}= $show;        $insertlist{"$tagnum.function"} = $function;
     $insertlist{"$tag.num"}=$tagnum;        if (!defined($show)) { $show='yes'; }
     $tagnum++;        $insertlist{"$tagnum.show"}= $show;
         $insertlist{"$tag.num"}=$tagnum;
         $tagnum++;
       }
   }    }
   $i++; #skipping TABLE line    $i++; #skipping TABLE line
   $tagnum = 0;    $tagnum = 0;
Line 1131  sub register_insert { Line 1211  sub register_insert {
   
 sub description {  sub description {
   my ($token)=@_;    my ($token)=@_;
   return $insertlist{$insertlist{"$token->[1].num"}.'.description'};    my $tagnum;
     my $tag=$token->[1];
     foreach my $namespace (reverse @Apache::lonxml::namespace) {
       my $testtag=$namespace.'::'.$tag;
       $tagnum=$insertlist{"$testtag.num"};
       if (defined($tagnum)) { last; }
     }
     if (!defined ($tagnum)) { $tagnum=$Apache::lonxml::insertlist{"$tag.num"}; }
     return $insertlist{$tagnum.'.description'};
 }  }
   
 # ----------------------------------------------------------------- whichuser  # ----------------------------------------------------------------- whichuser
Line 1139  sub description { Line 1227  sub description {
 # calls to lonnet functions for this setup.  # calls to lonnet functions for this setup.
 # - looks for form.grade_ parameters  # - looks for form.grade_ parameters
 sub whichuser {  sub whichuser {
   my $symb=&Apache::lonnet::symbread();    my ($symb,$courseid,$domain,$name);
   my $courseid=$ENV{'request.course.id'};  
   my $domain=$ENV{'user.domain'};  
   my $name=$ENV{'user.name'};  
   if (defined($ENV{'form.grade_symb'})) {    if (defined($ENV{'form.grade_symb'})) {
     my $tmp_courseid=$ENV{'form.grade_courseid'};      my $tmp_courseid=$ENV{'form.grade_courseid'};
     my $allowed=&Apache::lonnet::allowed('mgr',$tmp_courseid);      my $allowed=&Apache::lonnet::allowed('mgr',$tmp_courseid);
Line 1152  sub whichuser { Line 1237  sub whichuser {
       $domain=$ENV{'form.grade_domain'};        $domain=$ENV{'form.grade_domain'};
       $name=$ENV{'form.grade_username'};        $name=$ENV{'form.grade_username'};
     }      }
     } else {
       $symb=&Apache::lonnet::symbread();
       $courseid=$ENV{'request.course.id'};
       $domain=$ENV{'user.domain'};
       $name=$ENV{'user.name'};
   }    }
   return ($symb,$courseid,$domain,$name);    return ($symb,$courseid,$domain,$name);
 }  }

Removed from v.1.129  
changed lines
  Added in v.1.143


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