Diff for /loncom/xml/lonxml.pm between versions 1.153 and 1.258

version 1.153, 2002/02/21 04:18:59 version 1.258, 2003/05/28 21:05:33
Line 41 Line 41
 # 6/1/1 Gerd Kortemeyer  # 6/1/1 Gerd Kortemeyer
 # 2/21,3/13 Guy  # 2/21,3/13 Guy
 # 3/29,5/4 Gerd Kortemeyer  # 3/29,5/4 Gerd Kortemeyer
 # 5/10 Scott Harrison  
 # 5/26 Gerd Kortemeyer  # 5/26 Gerd Kortemeyer
 # 5/27 H. K. Ng  # 5/27 H. K. Ng
 # 6/2,6/3,6/8,6/9 Gerd Kortemeyer  # 6/2,6/3,6/8,6/9 Gerd Kortemeyer
Line 60 Line 59
   
 package Apache::lonxml;   package Apache::lonxml; 
 use vars   use vars 
 qw(@pwd @outputstack $redirection $import @extlinks $metamode $evaluate %insertlist @namespace);  qw(@pwd @outputstack $redirection $import @extlinks $metamode $evaluate %insertlist @namespace $prevent_entity_encode $errorcount $warningcount);
 use strict;  use strict;
 use HTML::TokeParser;  use HTML::LCParser();
 use HTML::TreeBuilder;  use HTML::TreeBuilder();
 use Safe;  use HTML::Entities();
 use Safe::Hole;  use Safe();
 use Math::Cephes qw(:trigs :hypers :bessels erf erfc);  use Safe::Hole();
 use Math::Random qw(:all);  use Math::Cephes();
 use Opcode;  use Math::Random();
   use Opcode();
   
 sub register {  sub register {
   my ($space,@taglist) = @_;    my ($space,@taglist) = @_;
Line 89  sub deregister { Line 89  sub deregister {
 }  }
   
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use Apache::lontexconvert;  use Apache::lontexconvert();
 use Apache::style;  use Apache::style();
 use Apache::run;  use Apache::run();
 use Apache::londefdef;  use Apache::londefdef();
 use Apache::scripttag;  use Apache::scripttag();
 use Apache::edit;  use Apache::edit();
 use Apache::lonnet;  use Apache::lonnet();
 use Apache::File;  use Apache::File();
 use Apache::loncommon;  use Apache::loncommon();
   use Apache::lonfeedback();
   use Apache::lonmsg();
   use Apache::loncacc();
   
 #==================================================   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
 $Apache::lonxml::debug=0;  $Apache::lonxml::debug=0;
   
   # keeps count of the number of warnings and errors generated in a parse
   $warningcount=0;
   $errorcount=0;
   
 #path to the directory containing the file currently being processed  #path to the directory containing the file currently being processed
 @pwd=();  @pwd=();
   
Line 128  $evaluate = 1; Line 135  $evaluate = 1;
 # stores the list of active tag namespaces  # stores the list of active tag namespaces
 @namespace=();  @namespace=();
   
   # if 0 all high ASCII characters will be encoded into HTML Entities
   $prevent_entity_encode=0;
   
 # has the dynamic menu been updated to know about this resource  # has the dynamic menu been updated to know about this resource
 $Apache::lonxml::registered=0;  $Apache::lonxml::registered=0;
   
   # a pointer the the Apache request object
   $Apache::lonxml::request='';
   
   # a problem number counter, and check on ether it is used
   $Apache::lonxml::counter=1;
   $Apache::lonxml::counter_changed=0;
   
   #internal check on whether to look at style defs
   $Apache::lonxml::usestyle=1;
   
 sub xmlbegin {  sub xmlbegin {
   my $output='';    my $output='';
   if ($ENV{'browser.mathml'}) {    if ($ENV{'browser.mathml'}) {
Line 147  sub xmlbegin { Line 167  sub xmlbegin {
 }  }
   
 sub xmlend {  sub xmlend {
       my ($discussiononly,$symb)=@_;
     my $discussion='';      my $discussion='';
     if ($ENV{'request.course.id'}) {      if ($ENV{'request.course.id'}) {
        my $crs='/'.$ENV{'request.course.id'};         my $crs='/'.$ENV{'request.course.id'};
Line 155  sub xmlend { Line 176  sub xmlend {
        }                          }                 
        $crs=~s/\_/\//g;         $crs=~s/\_/\//g;
        my $seeid=&Apache::lonnet::allowed('rin',$crs);         my $seeid=&Apache::lonnet::allowed('rin',$crs);
        my $symb=&Apache::lonnet::symbread();         unless ($symb) {
              $symb=&Apache::lonnet::symbread();
          }
        if ($symb) {         if ($symb) {
           my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},            my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},
                      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'});       $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
           if ($contrib{'version'}) {            if ($contrib{'version'}) {
               $discussion.=                unless ($discussiononly) {
                   '<address><hr /><h2>Course Discussion of Resource</h2>';                   $discussion.=
                     '<address><hr />';
        }
               my $idx;                my $idx;
               for ($idx=1;$idx<=$contrib{'version'};$idx++) {                for ($idx=1;$idx<=$contrib{'version'};$idx++) {
  my $hidden=($contrib{'hidden'}=~/\.$idx\./);   my $hidden=($contrib{'hidden'}=~/\.$idx\./);
  unless (($hidden) && (!$seeid)) {   my $deleted=($contrib{'deleted'}=~/\.$idx\./);
    unless ((($hidden) && (!$seeid)) || ($deleted)) {
                  my $message=$contrib{$idx.':message'};                   my $message=$contrib{$idx.':message'};
                  $message=~s/\n/\<br \/\>/g;                   $message=~s/\n/\<br \/\>/g;
    $message=&Apache::lontexconvert::msgtexconverted($message);
                    if ($contrib{$idx.':attachmenturl'}) {
                        my ($fname,$ft)
                           =($contrib{$idx.':attachmenturl'}=~/\/(\w+)\.(\w+)$/);
        $message.='<p>Attachment: <a href="'.
          &Apache::lonnet::tokenwrapper($contrib{$idx.':attachmenturl'}).
                        '"><tt>'.$fname.'.'.$ft.'</tt></a>';
                    }
                  if ($message) {                   if ($message) {
                   if ($hidden) {                    if ($hidden) {
       $message='<font color="#888888">'.$message.'</font>';        $message='<font color="#888888">'.$message.'</font>';
                   }                    }
                     my $screenname=&Apache::loncommon::screenname(
                                  $contrib{$idx.':sendername'},
          $contrib{$idx.':senderdomain'});
                     my $plainname=&Apache::loncommon::nickname(
                                  $contrib{$idx.':sendername'},
          $contrib{$idx.':senderdomain'});
   
                   my $sender='Anonymous';                    my $sender='Anonymous';
                   if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {                    if ((!$contrib{$idx.':anonymous'}) || ($seeid)) {
                       $sender=$contrib{$idx.':sendername'}.' at '.                        $sender=&Apache::loncommon::aboutmewrapper(
       $contrib{$idx.':senderdomain'};                                 $plainname,
                                  $contrib{$idx.':sendername'},
                                  $contrib{$idx.':senderdomain'}).' ('.
                                 $contrib{$idx.':sendername'}.' at '.
         $contrib{$idx.':senderdomain'}.')';
                       if ($contrib{$idx.':anonymous'}) {                        if ($contrib{$idx.':anonymous'}) {
   $sender.=' (anonymous)';    $sender.=' [anonymous] '.
                                        $screenname;
                       }                        }
                       if ($seeid) {                        if ($seeid) {
   if ($hidden) {    if ($hidden) {
Line 187  sub xmlend { Line 233  sub xmlend {
                           } else {                            } else {
                              $sender.=' <a href="/adm/feedback?hide='.                               $sender.=' <a href="/adm/feedback?hide='.
  $symb.':::'.$idx.'">Hide</a>';   $symb.':::'.$idx.'">Hide</a>';
   }    }                     
                       }                                               $sender.=' <a href="/adm/feedback?deldisc='.
    $symb.':::'.$idx.'">Delete</a>';
                         }
                     } else {
                         if ($screenname) {
     $sender='<i>'.$screenname.'</i>';
                         }
                   }                    }
   $discussion.='<p><b>'.$sender.'</b> ('.    $discussion.='<p><b>'.$sender.'</b> ('.
                       localtime($contrib{$idx.':timestamp'}).                        localtime($contrib{$idx.':timestamp'}).
Line 197  sub xmlend { Line 249  sub xmlend {
         }          }
                }                  } 
               }                }
               $discussion.='</address>';                unless ($discussiononly) {
                    $discussion.='</address>';
         }
             }
             if ($discussiononly) {
         $discussion.=(<<ENDDISCUSS);
   <form action="/adm/feedback" method="post" name="mailform" enctype="multipart/form-data">
   <input type="submit" name="discuss" value="Post Discussion" />
   <input type="submit" name="anondiscuss" value="Post Anonymous Discussion" />
   <input type="hidden" name="symb" value="$symb" />
   <input type="hidden" name="sendit" value="true" />
   <br />
   <font size="1">Note: in anonymous discussion, your name is visible only to
   course faculty</font><br />
   <textarea name=comment cols=60 rows=10 wrap=hard></textarea>
   <p>
   Attachment (128 KB max size): <input type="file" name="attachment" />
   </p>
   </form>
   ENDDISCUSS
                $discussion.=&Apache::lonfeedback::generate_preview_button();
           }            }
        }         }
     }      }
     return $discussion.'</html>';      return $discussion.($discussiononly?'':'</html>');
 }  }
   
 sub tokeninputfield {  sub tokeninputfield {
     my $defhost=$Apache::lonnet::perlvar{'lonHostID'};      my $defhost=$Apache::lonnet::perlvar{'lonHostID'};
     $defhost=~tr/a-z/A-Z/;      $defhost=~tr/a-z/A-Z/;
     return (<<ENDINPUTFIELD)      return (<<ENDINPUTFIELD)
 <script>  <script type="text/javascript">
     function updatetoken() {      function updatetoken() {
  var comp=new Array;   var comp=new Array;
         var barcode=unescape(document.tokeninput.barcode.value);          var barcode=unescape(document.tokeninput.barcode.value);
Line 292  sub printtokenheader { Line 364  sub printtokenheader {
     if ($target eq 'web') {      if ($target eq 'web') {
         my %idhash=&Apache::lonnet::idrget($tudom,($tuname));          my %idhash=&Apache::lonnet::idrget($tudom,($tuname));
  return    return 
  '<img align="right" src="/cgi-bin/barcode.gif?encode='.$token.'" />'.   '<img align="right" src="/cgi-bin/barcode.png?encode='.$token.'" />'.
                'Checked out for '.$plainname.                 'Checked out for '.$plainname.
                '<br />User: '.$tuname.' at '.$tudom.                 '<br />User: '.$tuname.' at '.$tudom.
        '<br />ID: '.$idhash{$tuname}.         '<br />ID: '.$idhash{$tuname}.
Line 308  sub printtokenheader { Line 380  sub printtokenheader {
 sub fontsettings() {  sub fontsettings() {
     my $headerstring='';      my $headerstring='';
     if (($ENV{'browser.os'} eq 'mac') && (!$ENV{'browser.mathml'})) {       if (($ENV{'browser.os'} eq 'mac') && (!$ENV{'browser.mathml'})) { 
          $headerstring.=   $headerstring.=
              '<meta Content-Type="text/html; charset=x-mac-roman">';      '<meta Content-Type="text/html; charset=x-mac-roman">';
       } elsif (!$ENV{'browser.mathml'}) {
    $headerstring.=
       '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
     }      }
     return $headerstring;      return $headerstring;
 }  }
   
 sub registerurl {  
     my $forcereg=shift;  
     if ($ENV{'request.publicaccess'}) {  
  return   
          '<script>function LONCAPAreg(){} function LONCAPAstale(){}</script>';  
     }  
     if ($Apache::lonxml::registered && !$forcereg) { return ''; }  
     $Apache::lonxml::registered=1;  
     if (($ENV{'REQUEST_URI'}!~/^\/(res\/)*adm\//) || ($forcereg)) {  
         my $hwkadd='';  
         if ($ENV{'REQUEST_URI'}=~/\.(problem|exam|quiz|assess|survey|form)$/) {  
     if (&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {  
  $hwkadd.=(<<ENDSUBM);  
                      menu.switchbutton  
            (7,1,'subm.gif','view sub','missions',  
                 'gocmd("/adm/grades","submission")');  
 ENDSUBM  
             }  
     if (&Apache::lonnet::allowed('mgr',$ENV{'request.course.id'})) {  
  $hwkadd.=(<<ENDGRDS);  
                      menu.switchbutton  
            (7,2,'pgrd.gif','problem','grades',  
                 'gocmd("/adm/grades","viewgrades")');  
 ENDGRDS  
             }  
     if (&Apache::lonnet::allowed('opa',$ENV{'request.course.id'})) {  
  $hwkadd.=(<<ENDPARM);  
                      menu.switchbutton  
            (7,3,'pparm.gif','problem','parms',  
                 'gocmd("/adm/parmset","set")');  
 ENDPARM  
             }  
  }  
  return (<<ENDREGTHIS);  
        
 <script language="JavaScript">  
 // BEGIN LON-CAPA Internal  
   
     function LONCAPAreg() {  
   menu=window.open("","LONCAPAmenu");  
           menu.clearTimeout(menu.menucltim);  
   menu.currentURL=window.location.pathname;  
           menu.currentStale=0;  
           menu.clearbut(3,1);  
           menu.switchbutton  
        (6,3,'catalog.gif','catalog','info','catalog_info()');  
           menu.switchbutton  
        (8,1,'eval.gif','evaluate','this','gopost("/adm/evaluate",currentURL)');  
           menu.switchbutton  
     (8,2,'fdbk.gif','feedback','on this','gopost("/adm/feedback",currentURL)');  
           menu.switchbutton  
      (8,3,'prt.gif','prepare','printout','gopost("/adm/printout",currentURL)');  
           menu.switchbutton  
        (2,1,'back.gif','backward','','gopost("/adm/flip","back:"+currentURL)');  
           menu.switchbutton  
      (2,3,'forw.gif','forward','','gopost("/adm/flip","forward:"+currentURL)');  
           menu.switchbutton  
                             (9,1,'sbkm.gif','set','bookmark','set_bookmark()');  
           menu.switchbutton  
                          (9,2,'vbkm.gif','view','bookmark','edit_bookmarks()');  
           menu.switchbutton  
                                (9,3,'anot.gif','anno-','tations','annotate()');  
           $hwkadd  
     }  
   
     function LONCAPAstale() {  
   menu=window.open("","LONCAPAmenu");  
           menu.currentStale=1;  
           menu.switchbutton  
              (3,1,'reload.gif','return','location','go(currentURL)');  
           menu.clearbut(7,1);  
           menu.clearbut(7,2);  
           menu.clearbut(7,3);  
           menu.menucltim=menu.setTimeout(  
  'clearbut(2,1);clearbut(2,3);clearbut(8,1);clearbut(8,2);clearbut(8,3);'+  
  'clearbut(9,1);clearbut(9,2);clearbut(9,3);clearbut(6,3)',  
   2000);  
   
       }  
   
 // END LON-CAPA Internal  
 </script>  
 ENDREGTHIS  
   
     } else {  
         return (<<ENDDONOTREGTHIS);  
   
 <script language="JavaScript">  
 // BEGIN LON-CAPA Internal  
   
     function LONCAPAreg() {  
   menu=window.open("","LONCAPAmenu");  
           menu.currentStale=1;  
           menu.clearbut(2,1);  
           menu.clearbut(2,3);  
           menu.clearbut(8,1);  
           menu.clearbut(8,2);  
           menu.clearbut(8,3);  
           if (menu.currentURL) {  
              menu.switchbutton  
               (3,1,'reload.gif','return','location','go(currentURL)');  
    } else {  
       menu.clearbut(3,1);  
           }  
     }  
   
     function LONCAPAstale() {  
     }  
   
 // END LON-CAPA Internal  
 </script>  
 ENDDONOTREGTHIS  
   
     }  
 }  
   
 sub loadevents() {  
     return 'LONCAPAreg();';  
 }  
   
 sub unloadevents() {  
     return 'LONCAPAstale();';  
 }  
   
 sub printalltags {  sub printalltags {
   my $temp;    my $temp;
   foreach $temp (sort keys %Apache::lonxml::alltags) {    foreach $temp (sort keys %Apache::lonxml::alltags) {
Line 447  sub printalltags { Line 398  sub printalltags {
 }  }
   
 sub xmlparse {  sub xmlparse {
  my ($target,$content_file_string,$safeinit,%style_for_target) = @_;   my ($request,$target,$content_file_string,$safeinit,%style_for_target) = @_;
   
    &setup_globals($request,$target);
    &Apache::inputtags::initialize_inputtags();
    &Apache::outputtags::initialize_outputtags();
    &Apache::edit::initialize_edit();
   
   #
   # do we have a course style file?
   #
   
  &setup_globals($target);   if ($ENV{'request.course.id'} && $ENV{'request.state'} ne 'construct') {
  #&printalltags();       my $bodytext=
    $ENV{'course.'.$ENV{'request.course.id'}.'.default_xml_style'};
        if ($bodytext) {
          my $location=&Apache::lonnet::filelocation('',$bodytext);
          my $styletext=&Apache::lonnet::getfile($location);
          if ($styletext ne '-1') {
             %style_for_target = (%style_for_target,
                             &Apache::style::styleparser($target,$styletext));
          }
       }
    }
   #&printalltags();
  my @pars = ();   my @pars = ();
  my $pwd=$ENV{'request.filename'};   my $pwd=$ENV{'request.filename'};
  $pwd =~ s:/[^/]*$::;   $pwd =~ s:/[^/]*$::;
Line 469  sub xmlparse { Line 440  sub xmlparse {
   
  my $finaloutput = &inner_xmlparse($target,\@stack,\@parstack,\@pars,   my $finaloutput = &inner_xmlparse($target,\@stack,\@parstack,\@pars,
    $safeeval,\%style_for_target);     $safeeval,\%style_for_target);
   
  if ($ENV{'request.uri'}) {   if ($ENV{'request.uri'}) {
     &writeallows($ENV{'request.uri'});      &writeallows($ENV{'request.uri'});
  }   }
    if ($Apache::lonxml::counter_changed) { &store_counter() }
  return $finaloutput;   return $finaloutput;
 }  }
   
Line 485  sub htmlclean { Line 458  sub htmlclean {
   
     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) {
        $output=~s/\<[\/]*(body|head|html)\>//gis;         $output=~s/\<[\/]*(body|head|html)\>//gis;
Line 496  sub htmlclean { Line 469  sub htmlclean {
     return $output;      return $output;
 }  }
   
   sub latex_special_symbols {
       my ($current_token,$stack,$parstack,$where)=@_;
       if ($where eq 'header') {
    $current_token =~ s/(\\|_|\^)/ /g;
    $current_token =~ s/(\$|%|\#|&|\{|\})/\\$1/g;
       } else {
    $current_token=~s/\\ /\\char92 /g;
    $current_token=~s/\^/\\char94 /g;
    $current_token=~s/\~/\\char126 /g;
    $current_token=~s/(&[^A-Za-z\#])/\\$1/g;
    $current_token=~s/([^&])\#/$1\\#/g;
    $current_token=~s/(\$|_|{|})/\\$1/g;
    $current_token=~s/\\char92 /\\texttt{\\char92}/g;
    $current_token=~s/(>|<)/\$$1\$/g; #more or less
    if ($current_token=~m/\d%/) {$current_token =~ s/(\d)%/$1\\%/g;} #percent after digit
    if ($current_token=~m/\s%/) {$current_token =~ s/(\s)%/$1\\%/g;} #persent after space
       }
       return $current_token;
   }
   
 sub inner_xmlparse {  sub inner_xmlparse {
   my ($target,$stack,$parstack,$pars,$safeeval,$style_for_target)=@_;    my ($target,$stack,$parstack,$pars,$safeeval,$style_for_target)=@_;
   my $finaloutput = '';    my $finaloutput = '';
   my $result;    my $result;
   my $token;    my $token;
     my $dontpop=0;
   while ( $#$pars > -1 ) {    while ( $#$pars > -1 ) {
     while ($token = $$pars['-1']->get_token) {      while ($token = $$pars['-1']->get_token) {
       if (($token->[0] eq 'T') || ($token->[0] eq 'C') || ($token->[0] eq 'D') ) {        if (($token->[0] eq 'T') || ($token->[0] eq 'C') || ($token->[0] eq 'D') ) {
  if ($metamode<1) {   if ($metamode<1) {
   $result=$token->[1];      my $text=$token->[1];
       if ($token->[0] eq 'C' && $target eq 'tex') {
    $text = '';
   # $text = '%'.$text."\n";
       }
       $result.=$text;
  }   }
       } elsif ($token->[0] eq 'PI') {        } elsif ($token->[0] eq 'PI') {
  if ($metamode<1) {   if ($metamode<1) {
Line 517  sub inner_xmlparse { Line 516  sub inner_xmlparse {
  # 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 ($Apache::lonxml::usestyle &&
   if ($Apache::lonxml::redirection) {      exists($$style_for_target{$token->[1]})) {
     $Apache::lonxml::outputstack['-1'] .=      $Apache::lonxml::usestyle=0;
       &recurse($$style_for_target{$token->[1]},$target,$safeeval,      my $string=$$style_for_target{$token->[1]}.
        $style_for_target,@$parstack);        '<LONCAPA_INTERNAL_TURN_STYLE_ON />';
   } else {      &Apache::lonxml::newparser($pars,\$string);
     $finaloutput .= &recurse($$style_for_target{$token->[1]},$target,      $Apache::lonxml::style_values=$$parstack[-1];
      $safeeval,$style_for_target,@$parstack);  
   }  
  } 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   if ($Apache::lonxml::usestyle &&
  while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) {      exists($$style_for_target{'/'."$token->[1]"})) {
   my $lasttag=$$stack[-1];      $Apache::lonxml::usestyle=0;
   if ($token->[1] =~ /^$lasttag$/i) {      my $string=$$style_for_target{'/'.$token->[1]}.
     &Apache::lonxml::warning('Using tag &lt;/'.$token->[1].'&gt; as end tag to &lt;'.$$stack[-1].'&gt;');        '<LONCAPA_INTERNAL_TURN_STYLE_ON end="'.$token->[1].'" />';
     last;      &Apache::lonxml::newparser($pars,\$string);
   } else {      $Apache::lonxml::style_values=$$parstack[-1];
     &Apache::lonxml::warning('Found tag &lt;/'.$token->[1].'&gt; when looking for &lt;/'.$$stack[-1].'&gt; in file');      $dontpop=1;
     &end_tag($stack,$parstack,$token);  
   }  
  }  
   
  if (exists($$style_for_target{'/'."$token->[1]"})) {  
   if ($Apache::lonxml::redirection) {  
     $Apache::lonxml::outputstack['-1'] .=    
       &recurse($$style_for_target{'/'."$token->[1]"},  
        $target,$safeeval,$style_for_target,@$parstack);  
   } else {  
     $finaloutput .= &recurse($$style_for_target{'/'."$token->[1]"},  
      $target,$safeeval,$style_for_target,  
      @$parstack);  
   }  
  } else {   } else {
   $result = &callsub("end_$token->[1]", $target, $token, $stack,      #clear out any tags that didn't end
      $parstack, $pars,$safeeval, $style_for_target);      while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) {
    my $lasttag=$$stack[-1];
    if ($token->[1] =~ /^$lasttag$/i) {
       &Apache::lonxml::warning('Using tag &lt;/'.$token->[1].'&gt; on line '.$token->[3].' as end tag to &lt;'.$$stack[-1].'&gt;');
       last;
    } else {
       &Apache::lonxml::warning('Found tag &lt;/'.$token->[1].'&gt; on line '.$token->[3].' when looking for &lt;/'.$$stack[-1].'&gt; in file');
       &end_tag($stack,$parstack,$token);
    }
       }
       $result = &callsub("end_$token->[1]", $target, $token, $stack,
          $parstack, $pars,$safeeval, $style_for_target);
  }   }
       } else {        } else {
  &Apache::lonxml::error("Unknown token event :$token->[0]:$token->[1]:");   &Apache::lonxml::error("Unknown token event :$token->[0]:$token->[1]:");
       }        }
       #evaluate variable refs in result        #evaluate variable refs in result
       if ($result ne "") {        if ($result ne "") {
  if ( $#$parstack > -1 ) {    my $extras;
   if ($Apache::lonxml::redirection) {    if (!$Apache::lonxml::usestyle) {
     $Apache::lonxml::outputstack['-1'] .=         $extras=$Apache::lonxml::style_values;
       &Apache::run::evaluate($result,$safeeval,$$parstack['-1']);  
   } else {  
     $finaloutput .= &Apache::run::evaluate($result,$safeeval,  
    $$parstack['-1']);  
   }    }
    if ( $#$parstack > -1 ) {
     $result=&Apache::run::evaluate($result,$safeeval,$extras.$$parstack[-1]);
  } else {   } else {
   $finaloutput .= &Apache::run::evaluate($result,$safeeval,'');    $result= &Apache::run::evaluate($result,$safeeval,$extras);
  }   }
  $result = '';        }
       }         if (($token->[0] eq 'T') || ($token->[0] eq 'C') || ($token->[0] eq 'D') ) {
       if ($token->[0] eq 'E') {     #Style file definitions should be correct
     if ($target eq 'tex' && ($Apache::lonxml::usestyle)) {
         $result=&latex_special_symbols($result,$stack,$parstack);
     }
         }
   
         # Encode any high ASCII characters
         if (!$Apache::lonxml::prevent_entity_encode) {
    $result=&HTML::Entities::encode($result,"\200-\377");
         }
         if ($Apache::lonxml::redirection) {
    $Apache::lonxml::outputstack['-1'] .= $result;
         } else {
    $finaloutput.=$result;
         }
         $result = '';
   
         if ($token->[0] eq 'E' && !$dontpop) {
  &end_tag($stack,$parstack,$token);   &end_tag($stack,$parstack,$token);
       }        }
         $dontpop=0;
       }
       if ($#$pars > -1) {
    pop @$pars;
    pop @Apache::lonxml::pwd;
     }      }
     pop @$pars;  
     pop @Apache::lonxml::pwd;  
   }    }
   
   # if ($target eq 'meta') {    # if ($target eq 'meta') {
   #   $finaloutput.=&endredirection;    #   $finaloutput.=&endredirection;
   # }    # }
   
   
   if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {    if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {
     $finaloutput=&afterburn($finaloutput);      $finaloutput=&afterburn($finaloutput);
   }    }    
   return $finaloutput;    return $finaloutput;
 }  }
   
 sub recurse {  
   my @innerstack = ();   
   my @innerparstack = ();  
   my ($newarg,$target,$safeeval,$style_for_target,@parstack) = @_;  
   my @pat = ();  
   &newparser(\@pat,\$newarg);  
   my $tokenpat;  
   my $partstring = '';  
   my $output='';  
   my $decls='';  
   &Apache::lonxml::debug("Recursing");  
   while ( $#pat > -1 ) {  
     while  ($tokenpat = $pat[$#pat]->get_token) {  
       if (($tokenpat->[0] eq 'T') || ($tokenpat->[0] eq 'C') || ($tokenpat->[0] eq 'D') ) {  
  if ($metamode<1) { $partstring=$tokenpat->[1]; }  
       } elsif ($tokenpat->[0] eq 'PI') {  
  if ($metamode<1) { $partstring=$tokenpat->[2]; }  
       } elsif ($tokenpat->[0] eq 'S') {  
  push (@innerstack,$tokenpat->[1]);  
  push (@innerparstack,&parstring($tokenpat));  
  &increasedepth($tokenpat);  
  $partstring = &callsub("start_$tokenpat->[1]", $target, $tokenpat,  
        \@innerstack, \@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)) {  
   my $lasttag=$innerstack[-1];  
   if ($tokenpat->[1] =~ /^$lasttag$/i) {  
     &Apache::lonxml::warning('Using tag &lt;/'.$tokenpat->[1].'&gt; as end tag to &lt;'.$innerstack[-1].'&gt;');  
     last;  
   } else {  
     &Apache::lonxml::warning('Found tag &lt;/'.$tokenpat->[1].'&gt; when looking for &lt;/'.$innerstack[-1].'&gt; in file');  
     &end_tag(\@innerstack,\@innerparstack,$tokenpat);  
   }  
  }  
  $partstring = &callsub("end_$tokenpat->[1]", $target, $tokenpat,  
        \@innerstack, \@innerparstack, \@pat,  
        $safeeval, $style_for_target);  
       } else {  
  &Apache::lonxml::error("Unknown token event :$tokenpat->[0]:$tokenpat->[1]:");  
       }  
       #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;  
     pop @Apache::lonxml::pwd;  
   }  
   &Apache::lonxml::debug("Exiting Recursing");  
   return $output;  
 }  
   
 sub callsub {  sub callsub {
   my ($sub,$target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;    my ($sub,$target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   my $currentstring='';    my $currentstring='';
Line 673  sub callsub { Line 614  sub callsub {
     my $sub1;      my $sub1;
     no strict 'refs';      no strict 'refs';
     my $tag=$token->[1];      my $tag=$token->[1];
   # get utterly rid of extended html tags
       if ($tag=~/^x\-/i) { return ''; }
     my $space=$Apache::lonxml::alltags{$tag}[-1];      my $space=$Apache::lonxml::alltags{$tag}[-1];
     if (!$space) {      if (!$space) {
       $tag=~tr/A-Z/a-z/;        $tag=~tr/A-Z/a-z/;
Line 707  sub callsub { Line 650  sub callsub {
       #    &Apache::lonxml::debug("nodefalt:$nodefault:");        #    &Apache::lonxml::debug("nodefalt:$nodefault:");
       if ($currentstring eq '' && $nodefault eq '') {        if ($currentstring eq '' && $nodefault eq '') {
  if ($target eq 'edit') {   if ($target eq 'edit') {
   &Apache::lonxml::debug("doing default edit for $token->[1]");    #&Apache::lonxml::debug("doing default edit for $token->[1]");
   if ($token->[0] eq 'S') {    if ($token->[0] eq 'S') {
     $currentstring = &Apache::edit::tag_start($target,$token);      $currentstring = &Apache::edit::tag_start($target,$token);
   } elsif ($token->[0] eq 'E') {    } elsif ($token->[0] eq 'E') {
Line 717  sub callsub { Line 660  sub callsub {
   if ($token->[0] eq 'S') {    if ($token->[0] eq 'S') {
     $currentstring = $token->[4];      $currentstring = $token->[4];
     $currentstring.=&Apache::edit::handle_insert();      $currentstring.=&Apache::edit::handle_insert();
     } elsif ($token->[0] eq 'E') {
       $currentstring = $token->[2];
               $currentstring.=&Apache::edit::handle_insertafter($token->[1]);
   } else {    } else {
     $currentstring = $token->[2];      $currentstring = $token->[2];
   }    }
Line 729  sub callsub { Line 675  sub callsub {
 }  }
   
 sub setup_globals {  sub setup_globals {
   my ($target)=@_;    my ($request,$target)=@_;
     $Apache::lonxml::request=$request;
   $Apache::lonxml::registered = 0;    $Apache::lonxml::registered = 0;
     $errorcount=0;
     $warningcount=0;
     $Apache::lonxml::default_homework_loaded=0;
     $Apache::lonxml::usestyle=1;
     &init_counter();
   @Apache::lonxml::pwd=();    @Apache::lonxml::pwd=();
   @Apache::lonxml::extlinks=();    @Apache::lonxml::extlinks=();
   if ($target eq 'meta') {    if ($target eq 'meta') {
Line 758  sub setup_globals { Line 710  sub setup_globals {
     $Apache::lonxml::metamode = 0;      $Apache::lonxml::metamode = 0;
     $Apache::lonxml::evaluate = 0;      $Apache::lonxml::evaluate = 0;
     $Apache::lonxml::import = 0;      $Apache::lonxml::import = 0;
     } elsif ($target eq 'analyze') {
       $Apache::lonxml::redirection = 0;
       $Apache::lonxml::metamode = 0;
       $Apache::lonxml::evaluate = 1;
       $Apache::lonxml::import = 1;
   } else {    } else {
     $Apache::lonxml::redirection = 0;      $Apache::lonxml::redirection = 0;
     $Apache::lonxml::metamode = 0;      $Apache::lonxml::metamode = 0;
Line 773  sub init_safespace { Line 730  sub init_safespace {
   $safeeval->permit("sort");    $safeeval->permit("sort");
   $safeeval->deny(":base_io");    $safeeval->deny(":base_io");
   $safehole->wrap(\&Apache::scripttag::xmlparse,$safeeval,'&xmlparse');    $safehole->wrap(\&Apache::scripttag::xmlparse,$safeeval,'&xmlparse');
     $safehole->wrap(\&Apache::outputtags::multipart,$safeeval,'&multipart');
   $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT');    $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT');
       
   $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin');    $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin');
Line 794  sub init_safespace { Line 752  sub init_safespace {
   $safehole->wrap(\&Math::Cephes::y1,$safeeval,'&y1');    $safehole->wrap(\&Math::Cephes::y1,$safeeval,'&y1');
   $safehole->wrap(\&Math::Cephes::yn,$safeeval,'&yn');    $safehole->wrap(\&Math::Cephes::yn,$safeeval,'&yn');
   $safehole->wrap(\&Math::Cephes::yv,$safeeval,'&yv');    $safehole->wrap(\&Math::Cephes::yv,$safeeval,'&yv');
     
     $safehole->wrap(\&Math::Cephes::bdtr  ,$safeeval,'&bdtr'  );
     $safehole->wrap(\&Math::Cephes::bdtrc ,$safeeval,'&bdtrc' );
     $safehole->wrap(\&Math::Cephes::bdtri ,$safeeval,'&bdtri' );
     $safehole->wrap(\&Math::Cephes::btdtr ,$safeeval,'&btdtr' );
     $safehole->wrap(\&Math::Cephes::chdtr ,$safeeval,'&chdtr' );
     $safehole->wrap(\&Math::Cephes::chdtrc,$safeeval,'&chdtrc');
     $safehole->wrap(\&Math::Cephes::chdtri,$safeeval,'&chdtri');
     $safehole->wrap(\&Math::Cephes::fdtr  ,$safeeval,'&fdtr'  );
     $safehole->wrap(\&Math::Cephes::fdtrc ,$safeeval,'&fdtrc' );
     $safehole->wrap(\&Math::Cephes::fdtri ,$safeeval,'&fdtri' );
     $safehole->wrap(\&Math::Cephes::gdtr  ,$safeeval,'&gdtr'  );
     $safehole->wrap(\&Math::Cephes::gdtrc ,$safeeval,'&gdtrc' );
     $safehole->wrap(\&Math::Cephes::nbdtr ,$safeeval,'&nbdtr' );
     $safehole->wrap(\&Math::Cephes::nbdtrc,$safeeval,'&nbdtrc');
     $safehole->wrap(\&Math::Cephes::nbdtri,$safeeval,'&nbdtri');
     $safehole->wrap(\&Math::Cephes::ndtr  ,$safeeval,'&ndtr'  );
     $safehole->wrap(\&Math::Cephes::ndtri ,$safeeval,'&ndtri' );
     $safehole->wrap(\&Math::Cephes::pdtr  ,$safeeval,'&pdtr'  );
     $safehole->wrap(\&Math::Cephes::pdtrc ,$safeeval,'&pdtrc' );
     $safehole->wrap(\&Math::Cephes::pdtri ,$safeeval,'&pdtri' );
     $safehole->wrap(\&Math::Cephes::stdtr ,$safeeval,'&stdtr' );
     $safehole->wrap(\&Math::Cephes::stdtri,$safeeval,'&stdtri');
   
   #  $safehole->wrap(\&Math::Cephes::new_fract,$safeeval,'&new_fract');
   #  $safehole->wrap(\&Math::Cephes::radd,$safeeval,'&radd');
   #  $safehole->wrap(\&Math::Cephes::rsub,$safeeval,'&rsub');
   #  $safehole->wrap(\&Math::Cephes::rmul,$safeeval,'&rmul');
   #  $safehole->wrap(\&Math::Cephes::rdiv,$safeeval,'&rdiv');
   #  $safehole->wrap(\&Math::Cephes::euclid,$safeeval,'&euclid');
   
   $safehole->wrap(\&Math::Random::random_beta,$safeeval,'&math_random_beta');    $safehole->wrap(\&Math::Random::random_beta,$safeeval,'&math_random_beta');
   $safehole->wrap(\&Math::Random::random_chi_square,$safeeval,'&math_random_chi_square');    $safehole->wrap(\&Math::Random::random_chi_square,$safeeval,'&math_random_chi_square');
   $safehole->wrap(\&Math::Random::random_exponential,$safeeval,'&math_random_exponential');    $safehole->wrap(\&Math::Random::random_exponential,$safeeval,'&math_random_exponential');
Line 823  sub init_safespace { Line 812  sub init_safespace {
   my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();    my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();
   $rndseed=&Apache::lonnet::rndseed($symb,$courseid,$domain,$name);    $rndseed=&Apache::lonnet::rndseed($symb,$courseid,$domain,$name);
   $safeinit .= ';$external::randomseed='.$rndseed.';';    $safeinit .= ';$external::randomseed='.$rndseed.';';
     &Apache::lonxml::debug("Setting rndseed to $rndseed");
   &Apache::run::run($safeinit,$safeeval);    &Apache::run::run($safeinit,$safeeval);
 }  }
   
   sub default_homework_load {
       my ($safeeval)=@_;
       &Apache::lonxml::debug('Loading default_homework');
       my $default=&Apache::lonnet::getfile('/home/httpd/html/res/adm/includes/default_homework.lcpm');
       if ($default eq -1) {
    &Apache::lonxml::error("<b>Unable to find <i>default_homework.lcpm</i></b>");
       } else {
    &Apache::run::run($default,$safeeval);
    $Apache::lonxml::default_homework_loaded=1;
       }
   }
   
 sub startredirection {  sub startredirection {
   $Apache::lonxml::redirection++;    $Apache::lonxml::redirection++;
   push (@Apache::lonxml::outputstack, '');    push (@Apache::lonxml::outputstack, '');
Line 881  sub decreasedepth { Line 883  sub decreasedepth {
 #print "<br />e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n";  #print "<br />e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n";
 }  }
   
 sub get_all_text {  sub get_all_text_unbalanced {
   #there is a copy of this in lonpublisher.pm
    my($tag,$pars)= @_;
    my $token;
    my $result='';
    $tag='<'.$tag.'>';
    while ($token = $$pars[-1]->get_token) {
      if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
        $result.=$token->[1];
      } elsif ($token->[0] eq 'PI') {
        $result.=$token->[2];
      } elsif ($token->[0] eq 'S') {
        $result.=$token->[4];
      } elsif ($token->[0] eq 'E')  {
        $result.=$token->[2];
      }
      if ($result =~ /(.*)\Q$tag\E(.*)/s) {
        &Apache::lonxml::debug('Got a winner with leftovers ::'.$2);
        &Apache::lonxml::debug('Result is :'.$1);
        $result=$1;
        my $redo=$tag.$2;
        &Apache::lonxml::newparser($pars,\$redo);
        last;
      }
    }
    return $result
   }
   
   sub increment_counter {
       my ($increment) = @_;
       if (defined($increment) && $increment gt 0) {
    $Apache::lonxml::counter+=$increment;
       } else {
    $Apache::lonxml::counter++;
       }
       $Apache::lonxml::counter_changed=1;
   }
   
   sub init_counter {
       if (defined($ENV{'form.counter'})) {
    $Apache::lonxml::counter=$ENV{'form.counter'};
    $Apache::lonxml::counter_changed=0;
       } else {
    $Apache::lonxml::counter=1;
    $Apache::lonxml::counter_changed=1;
       }
   }
   
   sub store_counter {
       &Apache::lonnet::appenv(('form.counter' => $Apache::lonxml::counter));
       return '';
   }
   
   sub get_all_text {
  my($tag,$pars)= @_;   my($tag,$pars)= @_;
    &Apache::lonxml::debug("Got a ".ref($pars));
    my $gotfullstack=1;
    if (ref($pars) ne 'ARRAY') {
        $gotfullstack=0;
        $pars=[$pars];
    }
  my $depth=0;   my $depth=0;
  my $token;   my $token;
  my $result='';   my $result='';
  if ( $tag =~ m:^/: ) {    if ( $tag =~ m:^/: ) { 
    my $tag=substr($tag,1);      my $tag=substr($tag,1); 
 #   &Apache::lonxml::debug("have:$tag:");     #&Apache::lonxml::debug("have:$tag:");
    while (($depth >=0) && ($token = $pars->get_token)) {     my $top_empty=0;
 #     &Apache::lonxml::debug("e token:$token->[0]:$depth:$token->[1]");     while (($depth >=0) && ($#$pars > -1) && (!$top_empty)) {
      if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {       while (($depth >=0) && ($token = $$pars[-1]->get_token)) {
        $result.=$token->[1];         #&Apache::lonxml::debug("e token:$token->[0]:$depth:$token->[1]:".$#$pars.":".$#Apache::lonxml::pwd);
      } elsif ($token->[0] eq 'PI') {         if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
        $result.=$token->[2];   $result.=$token->[1];
      } elsif ($token->[0] eq 'S') {         } elsif ($token->[0] eq 'PI') {
        if ($token->[1] =~ /^$tag$/i) { $depth++; }   $result.=$token->[2];
        $result.=$token->[4];         } elsif ($token->[0] eq 'S') {
      } elsif ($token->[0] eq 'E')  {   if ($token->[1] =~ /^$tag$/i) { $depth++; }
        if ( $token->[1] =~ /^$tag$/i) { $depth--; }   $result.=$token->[4];
        #skip sending back the last end tag         } elsif ($token->[0] eq 'E')  {
        if ($depth > -1) { $result.=$token->[2]; } else {   if ( $token->[1] =~ /^$tag$/i) { $depth--; }
  $pars->unget_token($token);   #skip sending back the last end tag
    if ($depth > -1) { $result.=$token->[2]; } else {
      $$pars[-1]->unget_token($token);
    }
        }         }
      }       }
        if (($depth >=0) && ($#$pars == 0) ) { $top_empty=1; }
        if (($depth >=0) && ($#$pars > 0) ) {
          pop(@$pars);
          pop(@Apache::lonxml::pwd);
        }
    }     }
  } else {     if ($top_empty && $depth >= 0) {
    while ($token = $pars->get_token) {         #never found the end tag ran out of text, throw error send back blank
 #     &Apache::lonxml::debug("s token:$token->[0]:$depth:$token->[1]");         &error('Never found end tag for &lt;'.$tag.'&gt;');
      if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {         if ($gotfullstack) {
        $result.=$token->[1];     my $newstring='</'.$tag.'>'.$result;
      } elsif ($token->[0] eq 'PI') {     &Apache::lonxml::newparser($pars,\$newstring);
        $result.=$token->[2];  
      } elsif ($token->[0] eq 'S') {  
        if ( $token->[1] =~ /^$tag$/i) {  
  $pars->unget_token($token); last;  
        } else {  
  $result.=$token->[4];  
        }         }
      } elsif ($token->[0] eq 'E')  {         $result='';
        $result.=$token->[2];  
      }  
    }     }
    } else {
        while ($#$pars > -1) {
    while ($token = $$pars[-1]->get_token) {
        #&Apache::lonxml::debug("s token:$token->[0]:$depth:$token->[1]");
        if (($token->[0] eq 'T')||($token->[0] eq 'C')||
    ($token->[0] eq 'D')) {
    $result.=$token->[1];
        } elsif ($token->[0] eq 'PI') {
    $result.=$token->[2];
        } elsif ($token->[0] eq 'S') {
    if ( $token->[1] =~ /^$tag$/i) {
        $$pars[-1]->unget_token($token); last;
    } else {
        $result.=$token->[4];
    }
        } elsif ($token->[0] eq 'E')  {
    $result.=$token->[2];
        }
    }
    if (($#$pars > 0) ) {
        pop(@$pars);
        pop(@Apache::lonxml::pwd);
    } else { last; }
        }
    }
    if ($result =~ m|<LONCAPA_INTERNAL_TURN_STYLE_ON />|) {
        $Apache::lonxml::usestyle=1;
  }   }
 # &Apache::lonxml::debug("Exit:$result:");   #&Apache::lonxml::debug("Exit:$result:");
  return $result   return $result
 }  }
   
 sub newparser {  sub newparser {
   my ($parser,$contentref,$dir) = @_;    my ($parser,$contentref,$dir) = @_;
   push (@$parser,HTML::TokeParser->new($contentref));    push (@$parser,HTML::LCParser->new($contentref));
   $$parser['-1']->xml_mode('1');    $$parser['-1']->xml_mode('1');
   if ( $dir eq '' ) {    if ( $dir eq '' ) {
     push (@Apache::lonxml::pwd, $Apache::lonxml::pwd[$#Apache::lonxml::pwd]);      push (@Apache::lonxml::pwd, $Apache::lonxml::pwd[$#Apache::lonxml::pwd]);
   } else {    } else {
     push (@Apache::lonxml::pwd, $dir);      push (@Apache::lonxml::pwd, $dir);
   }     } 
 #  &Apache::lonxml::debug("pwd:$#Apache::lonxml::pwd");  
 #  &Apache::lonxml::debug("pwd:$Apache::lonxml::pwd[$#Apache::lonxml::pwd]");  
 }  }
   
 sub parstring {  sub parstring {
Line 948  sub parstring { Line 1033  sub parstring {
   foreach (@{$token->[3]}) {    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\";"
     }      }
Line 978  sub writeallows { Line 1063  sub writeallows {
 #  #
 sub afterburn {  sub afterburn {
     my $result=shift;      my $result=shift;
     foreach (split(/&/,$ENV{'QUERY_STRING'})) {      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
        my ($name, $value) = split(/=/,$_);      ['highlight','anchor','link']);
        $value =~ tr/+/ /;  
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;  
        if (($name eq 'highlight')||($name eq 'anchor')||($name eq 'link')) {  
            unless ($ENV{'form.'.$name}) {  
               $ENV{'form.'.$name}=$value;  
    }  
        }  
     }  
     if ($ENV{'form.highlight'}) {      if ($ENV{'form.highlight'}) {
        foreach (split(/\,/,$ENV{'form.highlight'})) {         foreach (split(/\,/,$ENV{'form.highlight'})) {
            my $anchorname=$_;             my $anchorname=$_;
Line 1010  sub afterburn { Line 1087  sub afterburn {
         $matchthis=~s/\_+/\\s\+/g;          $matchthis=~s/\_+/\\s\+/g;
         $result=~s/($matchthis)/\<a name=\"$anchorname\"\>$1\<\/a\>/s;          $result=~s/($matchthis)/\<a name=\"$anchorname\"\>$1\<\/a\>/s;
         $result.=(<<"ENDSCRIPT");          $result.=(<<"ENDSCRIPT");
 <script>  <script type="text/javascript">
     document.location.hash='$anchorname';      document.location.hash='$anchorname';
 </script>  </script>
 ENDSCRIPT  ENDSCRIPT
Line 1049  SIMPLECONTENT Line 1126  SIMPLECONTENT
   
 sub inserteditinfo {  sub inserteditinfo {
       my ($result,$filecontents)=@_;        my ($result,$filecontents)=@_;
       $filecontents =~ s:</textarea>:&lt;/textarea&gt;:ig;        $filecontents = &HTML::Entities::encode($filecontents);
 #      my $editheader='<a href="#editsection">Edit below</a><hr />';  #      my $editheader='<a href="#editsection">Edit below</a><hr />';
         my $xml_help = '<table><tr><td>'.
     &Apache::loncommon::help_open_topic("Greek_Symbols",'Greek Symbols',
         undef,undef,600)
         .'</td><td>'.
             &Apache::loncommon::help_open_topic("Other_Symbols",'Other Symbols',
         undef,undef,600)
         .'</td></tr></table>';
         my $titledisplay=&display_title();
         my $buttons=(<<BUTTONS);
   <input type="submit" name="attemptclean" 
          value="Save and then attempt to clean HTML" />
   <input type="submit" name="savethisfile" value="Save this" />
   <input type="submit" name="viewmode" value="View" />
   BUTTONS
       my $editfooter=(<<ENDFOOTER);        my $editfooter=(<<ENDFOOTER);
 <hr />  <hr />
 <a name="editsection" />  <a name="editsection" />
 <form method="post">  <form method="post">
   $xml_help
   <input type="hidden" name="editmode" value="Edit" />
   $buttons<br />
 <textarea cols="80" rows="40" name="filecont">$filecontents</textarea>  <textarea cols="80" rows="40" name="filecont">$filecontents</textarea>
   <br />$buttons
 <br />  <br />
 <input type="hidden" name="showmode" value="Edit" />  
 <input type="submit" name="attemptclean"   
        value="Save and then attempt to clean HTML" />  
 <input type="submit" name="savethisfile" value="Save this" />  
 <input type="submit" name="showmode" value="View" />  
 </form>  </form>
   $titledisplay
 ENDFOOTER  ENDFOOTER
 #      $result=~s/(\<body[^\>]*\>)/$1$editheader/is;  #      $result=~s/(\<body[^\>]*\>)/$1$editheader/is;
       $result=~s/(\<\/body\>)/$editfooter/is;        $result=~s/(\<\/body\>)/$editfooter/is;
Line 1097  sub get_target { Line 1188  sub get_target {
 }  }
   
 sub handler {  sub handler {
   my $request=shift;      my $request=shift;
       
   my $target=&get_target();      my $target=&get_target();
       
   $Apache::lonxml::debug=0;      $Apache::lonxml::debug=$ENV{'user.debug'};
       
   if ($ENV{'browser.mathml'}) {      if ($ENV{'browser.mathml'}) {
     $request->content_type('text/xml');   $request->content_type('text/xml');
   } else {      } else {
     $request->content_type('text/html');   $request->content_type('text/html');
   }      }
   &Apache::loncommon::no_cache($request);      &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;
   
   
   my $file=&Apache::lonnet::filelocation("",$request->uri);      my $file=&Apache::lonnet::filelocation("",$request->uri);
 #  #
 # Edit action? Save file.  # Edit action? Save file.
 #  #
   unless ($ENV{'request.state'} eq 'published') {      unless ($ENV{'request.state'} eq 'published') {
       if (($ENV{'form.savethisfile'}) || ($ENV{'form.attemptclean'})) {   if (($ENV{'form.savethisfile'}) || ($ENV{'form.attemptclean'})) {
   &storefile($file,$ENV{'form.filecont'});      &storefile($file,$ENV{'form.filecont'});
       }   }
   }      }
   my %mystyle;      my %mystyle;
   my $result = '';      my $result = '';
   my $filecontents=&Apache::lonnet::getfile($file);      my $filecontents=&Apache::lonnet::getfile($file);
   if ($filecontents == -1) {      if ($filecontents eq -1) {
     $result=(<<ENDNOTFOUND);   $result=(<<ENDNOTFOUND);
 <html>  <html>
 <head>  <head>
 <title>File not found</title>  <title>File not found</title>
Line 1138  sub handler { Line 1229  sub handler {
 </html>  </html>
 ENDNOTFOUND  ENDNOTFOUND
     $filecontents='';      $filecontents='';
     if ($ENV{'request.state'} ne 'published') {   if ($ENV{'request.state'} ne 'published') {
       $filecontents=&createnewhtml();      $filecontents=&createnewhtml();
       $ENV{'form.showmode'}='Edit'; #force edit mode      $ENV{'form.editmode'}='Edit'; #force edit mode
     }   }
   } else {      } else {
     unless ($ENV{'request.state'} eq 'published') {   unless ($ENV{'request.state'} eq 'published') {
       if ($ENV{'form.attemptclean'}) {      if ($ENV{'form.attemptclean'}) {
  $filecontents=&htmlclean($filecontents,1);   $filecontents=&htmlclean($filecontents,1);
       }      }
     }   }
     if ($ENV{'form.showmode'} ne 'Edit') {   if (!$ENV{'form.editmode'} || $ENV{'form.viewmode'}) {
       $result = &Apache::lonxml::xmlparse($target,$filecontents,'',%mystyle);      $result = &Apache::lonxml::xmlparse($request,$target,$filecontents,
    '',%mystyle);
    }
     }      }
   }      
   
 #  #
 # Edit action? Insert editing commands  # Edit action? Insert editing commands
 #  #
   unless ($ENV{'request.state'} eq 'published') {      unless ($ENV{'request.state'} eq 'published') {
     if ($ENV{'form.showmode'} eq 'Edit') {   if ($ENV{'form.editmode'} && (!($ENV{'form.viewmode'}))) {
       $result='<html><body bgcolor="#FFFFFF"></body></html>';      my $displayfile=$request->uri;
       $result=&inserteditinfo($result,$filecontents);      $displayfile=~s/^\/[^\/]*//;
       $result='<html><body bgcolor="#FFFFFF"><h3>'.$displayfile.
    '</h3></body></html>';
       $result=&inserteditinfo($result,$filecontents);
    }
     }      }
   }      
       writeallows($request->uri);
   writeallows($request->uri);      
   
   $request->print($result);      $request->print($result);
       
   return OK;      return OK;
   }
   
   sub display_title {
       my $result;
       if ($ENV{'request.state'} eq 'construct') {
    my $title=&Apache::lonnet::gettitle();
    if (!defined($title) || $title eq '') {
       $title = $ENV{'request.filename'};
       $title = substr($title, rindex($title, '/') + 1);
    }
    $result = "<script type='text/javascript'>top.document.title = '$title - LON-CAPA Construction Space';</script>";
       }
       return $result;
 }  }
   
 sub debug {  sub debug {
   if ($Apache::lonxml::debug eq 1) {    if ($Apache::lonxml::debug eq 1) {
     $|=1;      $|=1;
     print("DEBUG:".join('<br />',@_)."<br />\n");      print('<font size="-2"<pre>DEBUG:'.&HTML::Entities::encode($_[0])."</pre></font>\n");
   }    }
 }  }
   
 sub error {  sub error {
     $errorcount++;
   if (($Apache::lonxml::debug eq 1) || ($ENV{'request.state'} eq 'construct') ) {    if (($Apache::lonxml::debug eq 1) || ($ENV{'request.state'} eq 'construct') ) {
     print "<b>ERROR:</b>".join('<br />',@_)."<br />\n";      # If printing in construction space, put the error inside <pre></pre>
       print "<b>ERROR:</b>".join("\n",@_)."\n";
   } else {    } else {
     print "<b>An Error occured while processing this resource. The instructor has been notified.</b> <br />";      print "<b>An Error occured while processing this resource. The instructor has been notified.</b> <br />";
     #notify author      #notify author
     &Apache::lonmsg::author_res_msg($ENV{'request.filename'},join('<br />',@_));      &Apache::lonmsg::author_res_msg($ENV{'request.filename'},join('<br />',@_));
     #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 (undef,%users)=&Apache::lonfeedback::decide_receiver(undef,0,1,1,1);
       my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'});        my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'});
       foreach my $user (split /\,/, $users) {        foreach (keys %users) {
  ($user,my $domain) = split /:/, $user;   my ($user,$domain) = split(/:/, $_);
  &Apache::lonmsg::user_normal_msg($user,$domain,   &Apache::lonmsg::user_normal_msg($user,$domain,
         "Error [$declutter]",join('<br />',@_));          "Error [$declutter]",join('<br />',@_));
       }        }
Line 1202  sub error { Line 1313  sub error {
 }  }
   
 sub warning {  sub warning {
   if ($ENV{'request.state'} eq 'construct') {    $warningcount++;
     if ($ENV{'request.state'} eq 'construct' || $Apache::lonxml::debug) {
     print "<b>W</b>ARNING<b>:</b>".join('<br />',@_)."<br />\n";      print "<b>W</b>ARNING<b>:</b>".join('<br />',@_)."<br />\n";
   }    }
 }  }
   
 sub get_param {  sub get_param {
   my ($param,$parstack,$safeeval,$context) = @_;      my ($param,$parstack,$safeeval,$context,$case_insensitive) = @_;
   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]; }
   if ( $args =~ /my \$$param=\"/ ) {      if ( ! $args ) { return undef; }
     return &Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'      if ( $case_insensitive ) {
   } else {   if ($args =~ s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei) {
     return undef;      return &Apache::run::run("{$args;".'return $'.$param.'}',
   }                                       $safeeval); #'
    } else {
       return undef;
    }
       } else {
    if ( $args =~ /my \$\Q$param\E=\"/ ) {
       return &Apache::run::run("{$args;".'return $'.$param.'}',
                                        $safeeval); #'
    } else {
       return undef;
    }
       }
 }  }
   
 sub get_param_var {  sub get_param_var {
   my ($param,$parstack,$safeeval,$context) = @_;    my ($param,$parstack,$safeeval,$context,$case_insensitive) = @_;
   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]; }
   if ( $args !~ /my \$$param=\"/ ) { return undef; }    &Apache::lonxml::debug("Args are $args param is $param");
     if ($case_insensitive) {
         if (! ($args=~s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei)) {
     return undef;
         }
     } elsif ( $args !~ /my \$\Q$param\E=\"/ ) { return undef; }
   my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'    my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
   if ($value =~ /^[\$\@\%]/) {    &Apache::lonxml::debug("first run is $value");
     return &Apache::run::run("return $value",$safeeval,1);    if ($value =~ /^[\$\@\%]\w+$/) {
         &Apache::lonxml::debug("doing second");
         my @result=&Apache::run::run("return $value",$safeeval,1);
         if (!defined($result[0])) {
     return $value
         } else {
     if (wantarray) { return @result; } else { return $result[0]; }
         }
   } else {    } else {
     return $value;      return $value;
   }    }
Line 1289  sub description { Line 1424  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,$courseid,$domain,$name);    my ($symb,$courseid,$domain,$name,$publicuser);
   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 1300  sub whichuser { Line 1435  sub whichuser {
       $name=$ENV{'form.grade_username'};        $name=$ENV{'form.grade_username'};
     }      }
   } else {    } else {
     $symb=&Apache::lonnet::symbread();        $symb=&Apache::lonnet::symbread();
     $courseid=$ENV{'request.course.id'};        $courseid=$ENV{'request.course.id'};
     $domain=$ENV{'user.domain'};        $domain=$ENV{'user.domain'};
     $name=$ENV{'user.name'};        $name=$ENV{'user.name'};
         if ($name eq 'public' && $domain eq 'public') {
     if (!defined($ENV{'form.username'})) {
         $ENV{'form.username'}.=time.rand(10000000);
     }
     $name.=$ENV{'form.username'};
         }
   }    }
   return ($symb,$courseid,$domain,$name);    return ($symb,$courseid,$domain,$name,$publicuser);
 }  }
   
 1;  1;

Removed from v.1.153  
changed lines
  Added in v.1.258


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.