Diff for /loncom/xml/lonxml.pm between versions 1.461 and 1.515

version 1.461, 2007/09/12 14:34:52 version 1.515, 2010/09/29 15:47:21
Line 37 Line 37
 # to any other parties under any circumstances.  # to any other parties under any circumstances.
 #  #
   
   =pod
   
   =head1 NAME
   
   Apache::lonxml
   
   =head1 SYNOPSIS
   
   XML Parsing Module
   
   This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   
   =head1 SUBROUTINES
   
   =cut
   
   
   
 package Apache::lonxml;   package Apache::lonxml; 
 use vars   use vars 
Line 90  use Apache::lonfeedback(); Line 109  use Apache::lonfeedback();
 use Apache::lonmsg();  use Apache::lonmsg();
 use Apache::loncacc();  use Apache::loncacc();
 use Apache::lonmaxima();  use Apache::lonmaxima();
   use Apache::lonr();
 use Apache::lonlocal;  use Apache::lonlocal;
   use Apache::lonhtmlcommon();
   
   #====================================   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  # keeps count of the number of warnings and errors generated in a parse
Line 135  $Apache::lonxml::request=''; Line 158  $Apache::lonxml::request='';
 $Apache::lonxml::counter=1;  $Apache::lonxml::counter=1;
 $Apache::lonxml::counter_changed=0;  $Apache::lonxml::counter_changed=0;
   
   # Part counter hash.   In analysis mode, the
   # problems can use this to record which parts increment the counter
   # by how much.  The counter subs will maintain this hash via
   # their optional part parameters.  Note that the assumption is that
   # analysis is done in one request and therefore it is not necessary to
   # save this information request-to-request.
   
   
   %Apache::lonxml::counters_per_part = ();
   
 #internal check on whether to look at style defs  #internal check on whether to look at style defs
 $Apache::lonxml::usestyle=1;  $Apache::lonxml::usestyle=1;
   
Line 189  sub xmlend { Line 222  sub xmlend {
     return $discussion;      return $discussion;
 }  }
   
 sub tokeninputfield {  
     my $defhost=$Apache::lonnet::perlvar{'lonHostID'};  
     $defhost=~tr/a-z/A-Z/;  
     return (<<ENDINPUTFIELD)  
 <script type="text/javascript">  
     function updatetoken() {  
  var comp=new Array;  
         var barcode=unescape(document.tokeninput.barcode.value);  
         comp=barcode.split('*');  
         if (typeof(comp[0])!="undefined") {  
     document.tokeninput.codeone.value=comp[0];  
  }  
         if (typeof(comp[1])!="undefined") {  
     document.tokeninput.codetwo.value=comp[1];  
  }  
         if (typeof(comp[2])!="undefined") {  
             comp[2]=comp[2].toUpperCase();  
     document.tokeninput.codethree.value=comp[2];  
  }  
         document.tokeninput.barcode.value='';  
     }    
 </script>  
 <form method="post" name="tokeninput">  
 <table border="2" bgcolor="#FFFFBB">  
 <tr><th>DocID Checkin</th></tr>  
 <tr><td>  
 <table>  
 <tr>  
 <td>Scan in Barcode</td>  
 <td><input type="text" size="22" name="barcode"   
 onChange="updatetoken()"/></td>  
 </tr>  
 <tr><td><i>or</i> Type in DocID</td>  
 <td>  
 <input type="text" size="5" name="codeone" />  
 <b><font size="+2">*</font></b>  
 <input type="text" size="5" name="codetwo" />  
 <b><font size="+2">*</font></b>  
 <input type="text" size="10" name="codethree" value="$defhost"   
 onChange="this.value=this.value.toUpperCase()" />  
 </td></tr>  
 </table>  
 </td></tr>  
 <tr><td><input type="submit" value="Check in DocID" /></td></tr>  
 </table>  
 </form>  
 ENDINPUTFIELD  
 }  
   
 sub maketoken {  
     my ($symb,$tuname,$tudom,$tcrsid)=@_;  
     unless ($symb) {  
  $symb=&Apache::lonnet::symbread();  
     }  
     unless ($tuname) {  
  $tuname=$env{'user.name'};  
         $tudom=$env{'user.domain'};  
         $tcrsid=$env{'request.course.id'};  
     }  
   
     return &Apache::lonnet::checkout($symb,$tuname,$tudom,$tcrsid);  
 }  
   
 sub printtokenheader {  
     my ($target,$token,$tsymb,$tcrsid,$tudom,$tuname)=@_;  
     unless ($token) { return ''; }  
   
     my ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser();  
     unless ($tsymb) {  
  $tsymb=$symb;  
     }  
     unless ($tuname) {  
  $tuname=$name;  
         $tudom=$domain;  
         $tcrsid=$courseid;  
     }  
   
     my $plainname=&Apache::loncommon::plainname($tuname,$tudom);  
   
     if ($target eq 'web') {  
         my %idhash=&Apache::lonnet::idrget($tudom,($tuname));  
  return   
  '<img align="right" src="/cgi-bin/barcode.png?encode='.$token.'" />'.  
                &mt('Checked out for').' '.$plainname.  
                '<br />'.&mt('User').': '.$tuname.' at '.$tudom.  
        '<br />'.&mt('ID').': '.$idhash{$tuname}.  
        '<br />'.&mt('CourseID').': '.$tcrsid.  
        '<br />'.&mt('Course').': '.$env{'course.'.$tcrsid.'.description'}.  
                '<br />'.&mt('DocID').': '.$token.  
                '<br />'.&mt('Time').': '.&Apache::lonlocal::locallocaltime().'<hr />';  
     } else {  
         return $token;  
     }  
 }  
   
 sub printalltags {  sub printalltags {
   my $temp;    my $temp;
   foreach $temp (sort keys %Apache::lonxml::alltags) {    foreach $temp (sort keys %Apache::lonxml::alltags) {
Line 349  sub xmlparse { Line 287  sub xmlparse {
    $safeeval,\%style_for_target,1);     $safeeval,\%style_for_target,1);
   
  if (@stack) {   if (@stack) {
      &warning("At end of file some tags were still left unclosed, ".       &warning(&mt('At end of file some tags were still left unclosed:').
       '<tt>&lt;'.join('&gt;</tt>, <tt>&lt;',reverse(@stack)).        ' <tt>&lt;'.join('&gt;</tt>, <tt>&lt;',reverse(@stack)).
       '&gt;</tt>');        '&gt;</tt>');
  }   }
  if ($env{'request.uri'}) {   if ($env{'request.uri'}) {
Line 365  sub xmlparse { Line 303  sub xmlparse {
      $finaloutput .= join('',@script_var_displays);       $finaloutput .= join('',@script_var_displays);
      undef(@script_var_displays);       undef(@script_var_displays);
  }   }
    &init_state();
  if ($env{'form.return_only_error_and_warning_counts'}) {   if ($env{'form.return_only_error_and_warning_counts'}) {
        if ($env{'request.filename'}=~/\.(html|htm|xml)$/i) { 
           my $error=&verify_html($content_file_string);
           if ($error) { $errorcount++; }
        }
      return "$errorcount:$warningcount";       return "$errorcount:$warningcount";
  }   }
  return $finaloutput;   return $finaloutput;
Line 470  sub inner_xmlparse { Line 412  sub inner_xmlparse {
     while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) {      while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) {
  my $lasttag=$$stack[-1];   my $lasttag=$$stack[-1];
  if ($token->[1] =~ /^\Q$lasttag\E$/i) {   if ($token->[1] =~ /^\Q$lasttag\E$/i) {
     &Apache::lonxml::warning('Using tag &lt;/'.$token->[1].'&gt; on line '.$token->[3].' as end tag to &lt;'.$$stack[-1].'&gt;');      &Apache::lonxml::warning(&mt('Using tag [_1] on line [_2] as end tag to [_3]','&lt;/'.$token->[1].'&gt;','.$token->[3].','&lt;'.$$stack[-1].'&gt;'));
     last;      last;
  } else {   } else {
     &Apache::lonxml::warning('Found tag &lt;/'.$token->[1].'&gt; on line '.$token->[3].' when looking for &lt;/'.$$stack[-1].'&gt; in file');                      &Apache::lonxml::warning(&mt('Found tag [_1] on line [_2] when looking for [_3] in file.','&lt;/'.$token->[1].'&gt;',$token->[3],'&lt;/'.$$stack[-1].'&gt;'));
     &end_tag($stack,$parstack,$token);      &end_tag($stack,$parstack,$token);
  }   }
     }      }
Line 489  sub inner_xmlparse { Line 431  sub inner_xmlparse {
   if (!$Apache::lonxml::usestyle) {    if (!$Apache::lonxml::usestyle) {
       $extras=$Apache::lonxml::style_values;        $extras=$Apache::lonxml::style_values;
   }    }
  if ( $#$parstack > -1 ) {    if ( $#$parstack > -1 ) {
   $result=&Apache::run::evaluate($result,$safeeval,$extras.$$parstack[-1]);        $result=&Apache::run::evaluate($result,$safeeval,$extras.$$parstack[-1]);
  } else {    } else {
   $result= &Apache::run::evaluate($result,$safeeval,$extras);        $result= &Apache::run::evaluate($result,$safeeval,$extras);
  }            }
       }        }
       $Apache::lonxml::post_evaluate=1;        $Apache::lonxml::post_evaluate=1;
   
Line 534  sub inner_xmlparse { Line 476  sub inner_xmlparse {
   }    }
   if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {    if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {
     $finaloutput=&afterburn($finaloutput);      $finaloutput=&afterburn($finaloutput);
     }
     if ($target eq 'modified') {
   # if modfied, handle startpart and endpart
        $finaloutput=~s/\<startpartmarker[^\>]*\>(.*)\<endpartmarker[^\>]*\>/<part>$1<\/part>/gs;
   }        }    
   return $finaloutput;    return $finaloutput;
 }  }
Line 619  sub callsub { Line 565  sub callsub {
   return $currentstring;    return $currentstring;
 }  }
   
   {
       my %state;
   
       sub init_state {
    undef(%state);
       }
       
       sub set_state {
    my ($key,$value) = @_;
    $state{$key} = $value;
    return $value;
       }
       sub get_state {
    my ($key) = @_;
    return $state{$key};
       }
   }
   
 sub setup_globals {  sub setup_globals {
   my ($request,$target)=@_;    my ($request,$target)=@_;
   $Apache::lonxml::request=$request;    $Apache::lonxml::request=$request;
   $errorcount=0;    $errorcount=0;
   $warningcount=0;    $warningcount=0;
     $Apache::lonxml::internal_error=0;
   $Apache::lonxml::default_homework_loaded=0;    $Apache::lonxml::default_homework_loaded=0;
   $Apache::lonxml::usestyle=1;    $Apache::lonxml::usestyle=1;
   &init_counter();    &init_counter();
     &clear_bubble_lines_for_part();
     &init_state();
     &set_state('target',$target);
   @Apache::lonxml::pwd=();    @Apache::lonxml::pwd=();
   @Apache::lonxml::extlinks=();    @Apache::lonxml::extlinks=();
   @script_var_displays=();    @script_var_displays=();
Line 674  sub setup_globals { Line 642  sub setup_globals {
   
 sub init_safespace {  sub init_safespace {
   my ($target,$safeeval,$safehole,$safeinit) = @_;    my ($target,$safeeval,$safehole,$safeinit) = @_;
   $safeeval->deny_only(':dangerous');  
   $safeeval->reval('use Math::Complex;');    $safeeval->reval('use Math::Complex;');
     $safeeval->reval('use LaTeX::Table;');
     $safeeval->deny_only(':dangerous');
   $safeeval->permit_only(":default");    $safeeval->permit_only(":default");
   $safeeval->permit("entereval");    $safeeval->permit("entereval");
   $safeeval->permit(":base_math");    $safeeval->permit(":base_math");
   $safeeval->permit("sort");    $safeeval->permit("sort");
   $safeeval->permit("time");    $safeeval->permit("time");
     $safeeval->permit("caller");
   $safeeval->deny("rand");    $safeeval->deny("rand");
   $safeeval->deny("srand");    $safeeval->deny("srand");
   $safeeval->deny(":base_io");    $safeeval->deny(":base_io");
Line 690  sub init_safespace { Line 660  sub init_safespace {
   $safehole->wrap(\&Apache::chemresponse::chem_standard_order,$safeeval,    $safehole->wrap(\&Apache::chemresponse::chem_standard_order,$safeeval,
   '&chem_standard_order');    '&chem_standard_order');
   $safehole->wrap(\&Apache::response::check_status,$safeeval,'&check_status');    $safehole->wrap(\&Apache::response::check_status,$safeeval,'&check_status');
     $safehole->wrap(\&Apache::response::implicit_multiplication,$safeeval,'&implicit_multiplication');
   
   $safehole->wrap(\&Apache::lonmaxima::maxima_eval,$safeeval,'&maxima_eval');    $safehole->wrap(\&Apache::lonmaxima::maxima_eval,$safeeval,'&maxima_eval');
   $safehole->wrap(\&Apache::lonmaxima::maxima_check,$safeeval,'&maxima_check');    $safehole->wrap(\&Apache::lonmaxima::maxima_check,$safeeval,'&maxima_check');
   $safehole->wrap(\&Apache::lonmaxima::maxima_cas_formula_fix,$safeeval,    $safehole->wrap(\&Apache::lonmaxima::maxima_cas_formula_fix,$safeeval,
   '&maxima_cas_formula_fix');    '&maxima_cas_formula_fix');
   
     $safehole->wrap(\&Apache::lonr::r_eval,$safeeval,'&r_eval');
     $safehole->wrap(\&Apache::lonr::Rentry,$safeeval,'&Rentry');
     $safehole->wrap(\&Apache::lonr::Rarray,$safeeval,'&Rarray');
     $safehole->wrap(\&Apache::lonr::r_check,$safeeval,'&r_check');
     $safehole->wrap(\&Apache::lonr::r_cas_formula_fix,$safeeval,
                     '&r_cas_formula_fix');
    
   $safehole->wrap(\&Apache::caparesponse::capa_formula_fix,$safeeval,    $safehole->wrap(\&Apache::caparesponse::capa_formula_fix,$safeeval,
   '&capa_formula_fix');    '&capa_formula_fix');
   
     $safehole->wrap(\&Apache::lonlocal::locallocaltime,$safeeval,
                     '&locallocaltime');
   
   $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin');    $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin');
   $safehole->wrap(\&Math::Cephes::acos,$safeeval,'&acos');    $safehole->wrap(\&Math::Cephes::acos,$safeeval,'&acos');
   $safehole->wrap(\&Math::Cephes::atan,$safeeval,'&atan');    $safehole->wrap(\&Math::Cephes::atan,$safeeval,'&atan');
Line 973  sub get_id { Line 954  sub get_id {
     my ($parstack,$safeeval)=@_;      my ($parstack,$safeeval)=@_;
     my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval);      my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval);
     if ($env{'request.state'} eq 'construct' && $id =~ /([._]|[^\w\d\s[:punct:]])/) {      if ($env{'request.state'} eq 'construct' && $id =~ /([._]|[^\w\d\s[:punct:]])/) {
  &error(&mt("ID &quot;[_1]&quot; contains invalid characters, IDs are only allowed to contain letters, numbers, spaces and -",'<tt>'.$id.'</tt>'));   &error(&mt('ID [_1] contains invalid characters. IDs are only allowed to contain letters, numbers, spaces and -','"<tt>'.$id.'</tt>"'));
     }      }
     if ($id =~ /^\s*$/) { $id = $Apache::lonxml::curdepth; }      if ($id =~ /^\s*$/) { $id = $Apache::lonxml::curdepth; }
     return $id;      return $id;
Line 1009  sub get_all_text_unbalanced { Line 990  sub get_all_text_unbalanced {
  }   }
     }      }
     return $result      return $result
   
 }  }
   
   #########################################################################
   #                                                                       #
   #           bubble line counter management                              #
   #                                                                       #
   #########################################################################
   
 =pod  =pod
   
 For bubble grading mode and exam bubble printing mode, the tracking of  For bubble grading mode and exam bubble printing mode, the tracking of
Line 1026  Increments the internal counter environm Line 1014  Increments the internal counter environm
   
 Optional Arguments:  Optional Arguments:
   $increment - amount to increment by (defaults to 1)    $increment - amount to increment by (defaults to 1)
                  Also 1 if the value is negative or zero.
     $part_response - A concatenation of the part and response id
                      identifying exactly what is being 'answered'.
   
   
 =cut  =cut
   
 sub increment_counter {  sub increment_counter {
     my ($increment) = @_;      my ($increment, $part_response) = @_;
     if (defined($increment) && $increment gt 0) {      if ($env{'form.grade_noincrement'}) { return; }
  $Apache::lonxml::counter+=$increment;      if (!defined($increment) || $increment le 0) {
     } else {   $increment = 1;
  $Apache::lonxml::counter++;  
     }      }
       $Apache::lonxml::counter += $increment;
   
       # If the caller supplied the response_id parameter, 
       # Maintain its counter.. creating if necessary.
   
       if (defined($part_response)) {
    if (!defined($Apache::lonxml::counters_per_part{$part_response})) {
       $Apache::lonxml::counters_per_part{$part_response} = 0;
    }
    $Apache::lonxml::counters_per_part{$part_response} += $increment;
    my $new_value = $Apache::lonxml::counters_per_part{$part_response};
       }
   
     $Apache::lonxml::counter_changed=1;      $Apache::lonxml::counter_changed=1;
 }  }
   
Line 1061  sub init_counter { Line 1065  sub init_counter {
 }  }
   
 sub store_counter {  sub store_counter {
     &Apache::lonnet::appenv(('form.counter' => $Apache::lonxml::counter));      &Apache::lonnet::appenv({'form.counter' => $Apache::lonxml::counter});
     $Apache::lonxml::counter_changed=0;      $Apache::lonxml::counter_changed=0;
     return '';      return '';
 }  }
Line 1082  sub store_counter { Line 1086  sub store_counter {
   
     sub restore_problem_counter {      sub restore_problem_counter {
  if (defined($state)) {   if (defined($state)) {
     &Apache::lonnet::appenv(('form.counter' => $state));      &Apache::lonnet::appenv({'form.counter' => $state});
  }   }
     }      }
     sub get_problem_counter {      sub get_problem_counter {
Line 1092  sub store_counter { Line 1096  sub store_counter {
     }      }
 }  }
   
   =pod
   
   =item  bubble_lines_for_part(part_response)
   
   Returns the number of lines required to get a response for
   $part_response (this is just $Apache::lonxml::counters_per_part{$part_response}
   
   =cut
   
   sub bubble_lines_for_part {
       my ($part_response) = @_;
   
       if (!defined($Apache::lonxml::counters_per_part{$part_response})) {
    return 0;
       } else {
    return $Apache::lonxml::counters_per_part{$part_response};
       }
   }
   
   =pod
   
   =item clear_bubble_lines_for_part
   
   Clears the hash of bubble lines per part.  If a caller
   needs to analyze several resources this should be called between
   resources to reset the hash for each problem being analyzed.
   
   =cut
   
   sub clear_bubble_lines_for_part {
       undef(%Apache::lonxml::counters_per_part);
   }
   
   =pod
   
   =item set_bubble_lines(part_response, value)
   
   If there is a problem part, that for whatever reason
   requires bubble lines that are not
   the same as the counter increment, it can call this sub during
   analysis to set its hash value explicitly.
   
   =cut
   
   sub set_bubble_lines {
       my ($part_response, $value) = @_;
   
       $Apache::lonxml::counters_per_part{$part_response} = $value;
   }
   
   =pod
   
   =item get_bubble_line_hash
   
   Returns the current bubble line hash.  This is assumed to 
   be small so we return a copy
   
   
   =cut
   
   sub get_bubble_line_hash {
       return %Apache::lonxml::counters_per_part;
   }
   
   
   #--------------------------------------------------
   
 sub get_all_text {  sub get_all_text {
     my($tag,$pars,$style)= @_;      my($tag,$pars,$style)= @_;
     my $gotfullstack=1;      my $gotfullstack=1;
Line 1252  sub writeallows { Line 1323  sub writeallows {
          &Apache::lonnet::hreflocation($thisdir,&unescape($_))}=$thisurl;           &Apache::lonnet::hreflocation($thisdir,&unescape($_))}=$thisurl;
     }      }
     @extlinks=();      @extlinks=();
     &Apache::lonnet::appenv(%httpref);      &Apache::lonnet::appenv(\%httpref);
 }  }
   
 sub register_ssi {  sub register_ssi {
Line 1319  sub storefile { Line 1390  sub storefile {
         $fh->close();          $fh->close();
         return 1;          return 1;
     } else {      } else {
  &warning("Unable to save file $file");   &warning(&mt('Unable to save file [_1]','<tt>'.$file.'</tt>'));
  return 0;   return 0;
     }      }
 }  }
Line 1352  SIMPLECONTENT Line 1423  SIMPLECONTENT
   return $filecontents;    return $filecontents;
 }  }
   
   sub createnewjs {
       my $filecontents=(<<SIMPLECONTENT);
   <script type="text/javascript" language="Javascript">
   
   </script>
   SIMPLECONTENT
       return $filecontents;
   }
   
   sub verify_html {
       my ($filecontents)=@_;
       if ($filecontents!~/(?:\<|\&lt\;)(?:html|xml)[^\<]*(?:\>|\&gt\;)/is) {
          return &mt('File does not have [_1] or [_2] starting tag','&lt;html&gt;','&lt;xml&gt;');
       }
       if ($filecontents!~/(?:\<|\&lt\;)\/(?:html|xml)(?:\>|\&gt\;)/is) {
          return &mt('File does not have [_1] or [_2] ending tag','&lt;html&gt;','&lt;xml&gt;');
       }
       if ($filecontents!~/(?:\<|\&lt\;)(?:body|frameset)[^\<]*(?:\>|\&gt\;)/is) {
          return &mt('File does not have [_1] or [_2] starting tag','&lt;body&gt;','&lt;frameset&gt;');
       }
       if ($filecontents!~/(?:\<|\&lt\;)\/(?:body|frameset)[^\<]*(?:\>|\&gt\;)/is) {
          return &mt('File does not have [_1] or [_2] ending tag','&lt;body&gt;','&lt;frameset&gt;');
       }
       return '';
   }
   
   sub renderingoptions {
       my %langchoices=('' => '');
       foreach (&Apache::loncommon::languageids()) {
           if (&Apache::loncommon::supportedlanguagecode($_)) {
               $langchoices{&Apache::loncommon::supportedlanguagecode($_)}
                          = &Apache::loncommon::plainlanguagedescription($_);
           }
       }
       my $output;
       unless ($env{'form.forceedit'}) {
          $output .=
              '<span class="LC_nobreak">'.
              &mt('Language:').' '.
              &Apache::loncommon::select_form(
                  $env{'form.languages'},
                  'languages',
                  {&Apache::lonlocal::texthash(%langchoices)}).
              '</span>';
       }
       $output .=
        ' <span class="LC_nobreak">'.
          &mt('Math Rendering:').' '.
          &Apache::loncommon::select_form(
              $env{'form.texengine'},
              'texengine',
              {&Apache::lonlocal::texthash
                  (''        => '',
                   'tth'     => 'tth (TeX to HTML)',
                   'jsMath'  => 'jsMath',
                   'mimetex' => 'mimetex (Convert to Images)')}).
        '</span>';
       return $output;
   }
   
 sub inserteditinfo {  sub inserteditinfo {
       my ($filecontents,$filetype)=@_;        my ($filecontents, $filetype, $filename)=@_;
       $filecontents = &HTML::Entities::encode($filecontents,'<>&"');        $filecontents = &HTML::Entities::encode($filecontents,'<>&"');
 #      my $editheader='<a href="#editsection">Edit below</a><hr />';  
       my $xml_help = '';        my $xml_help = '';
       my $initialize='';        my $initialize='';
       my $textarea_id = 'filecont';        my $textarea_id = 'filecont';
         my $dragmath_button;
       my ($add_to_onload, $add_to_onresize);        my ($add_to_onload, $add_to_onresize);
       my $addbuttons=&Apache::lonhtmlcommon::htmlareaaddbuttons();  
       $initialize=&Apache::lonhtmlcommon::spellheader();        $initialize=&Apache::lonhtmlcommon::spellheader();
       if ($filetype eq 'html'         if (($filetype eq 'html') && (&Apache::lonhtmlcommon::htmlareabrowser())) {
   && (!&Apache::lonhtmlcommon::htmlareablocked() &&    my $lang = &Apache::lonhtmlcommon::htmlarea_lang();
       &Apache::lonhtmlcommon::htmlareabrowser())) {            my %textarea_args = (
   $textarea_id .= '_htmlarea';                                  fullpage => 'true',
   $initialize.=(<<FULLPAGE);                                  dragmath => 'math',
 <script type="text/javascript">                                );
 $addbuttons            $initialize .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args); 
         }
     HTMLArea.loadPlugin("FullPage");        $initialize .= (<<FULLPAGE);
   
     function initDocument() {  
  var editor=new HTMLArea("filecont",config);  
  editor.registerPlugin(FullPage);  
  editor.generate();  
  setTimeout(  
    function () {  
        HTMLArea._addEvents(editor._doc,  
    ["keypress","mousedown"], unClean);  
        editor._iframe.id = '$textarea_id';  
        resize_textarea('$textarea_id','LC_aftertextarea');  
    },300);  
     }  
 </script>  
 FULLPAGE  
       } else {  
   $initialize.=(<<FULLPAGE);  
 <script type="text/javascript">  <script type="text/javascript">
 $addbuttons  // <![CDATA[
     function initDocument() {      function initDocument() {
  resize_textarea('$textarea_id','LC_aftertextarea');   resize_textarea('$textarea_id','LC_aftertextarea');
     }      }
   // ]]>
 </script>  </script>
 FULLPAGE  FULLPAGE
         if ($filetype eq 'html') {
             $dragmath_button = '<span id="math_filecont">'.&Apache::lonhtmlcommon::dragmath_button('filecont',1).'</span>';
             $initialize .= "\n".&Apache::lonhtmlcommon::dragmath_js('EditMathPopup');
       }        }
   
       $add_to_onload = 'initDocument();';        $add_to_onload = 'initDocument();';
       $add_to_onresize = "resize_textarea('$textarea_id','LC_aftertextarea');";        $add_to_onresize = "resize_textarea('$textarea_id','LC_aftertextarea');";
   
Line 1405  FULLPAGE Line 1520  FULLPAGE
   $xml_help=&Apache::loncommon::helpLatexCheatsheet();    $xml_help=&Apache::loncommon::helpLatexCheatsheet();
       }        }
   
       my $cleanbut = '';  
   
       my $titledisplay=&display_title();        my $titledisplay=&display_title();
         my $textareaclass;
       my %lt=&Apache::lonlocal::texthash('st' => 'Save and Edit',        my %lt=&Apache::lonlocal::texthash('st' => 'Save and Edit',
  'vi' => 'Save and View',   'vi' => 'Save and View',
  'dv' => 'Discard Edits and View',   'dv' => 'Discard Edits and View',
  'un' => 'undo',   'un' => 'undo',
  'ed' => 'Edit');   'ed' => 'Edit');
       my $buttons=(<<BUTTONS);        my $spelllink = &Apache::lonhtmlcommon::spelllink('xmledit','filecont');
 $cleanbut  
 <input type="submit" name="discardview" accesskey="d"  value="$lt{'dv'}" />  
 <input type="submit" name="Undo" accesskey="u"  value="$lt{'un'}" /><hr />  
 <input type="submit" name="savethisfile" accesskey="s"  value="$lt{'st'}" />  
 <input type="submit" name="viewmode" accesskey="v" value="$lt{'vi'}" />  
 BUTTONS  
       $buttons.=&Apache::lonhtmlcommon::spelllink('xmledit','filecont');  
       my $textarea_events = &Apache::edit::element_change_detection();        my $textarea_events = &Apache::edit::element_change_detection();
       my $form_events     = &Apache::edit::form_change_detection();        my $form_events     = &Apache::edit::form_change_detection();
         my $htmlerror;
         if ($filetype eq 'html') {
             $htmlerror=&verify_html($filecontents);
             if ($htmlerror) {
                 $htmlerror='<span class="LC_error">'.$htmlerror.'</span>';
             }
             if (&Apache::lonhtmlcommon::htmlareabrowser()) {
                 $textareaclass = 'class="LC_richDefaultOff"';
             }
         }
       my $editfooter=(<<ENDFOOTER);        my $editfooter=(<<ENDFOOTER);
 $initialize  $initialize
 <hr />  
 <a name="editsection" />  <a name="editsection" />
 <form $form_events method="post" name="xmledit">  <form $form_events method="post" name="xmledit">
 $xml_help    <div class="LC_edit_problem_editxml_header">
 <input type="hidden" name="editmode" value="$lt{'ed'}" />      <table class="LC_edit_problem_header_title"><tr><td>
 $buttons<br />          $filename
 <textarea $textarea_events style="width:100%" cols="80" rows="44" name="filecont" id="filecont">$filecontents</textarea>        </td><td align="right">
 <div id="LC_aftertextarea">          $xml_help
 <br />$buttons        </td></tr>
 <br />      </table>
 $titledisplay      <div class="LC_edit_problem_discards">
 </div>        <input type="submit" name="discardview" accesskey="d" value="$lt{'dv'}" />
         <input type="submit" name="Undo" accesskey="u" value="$lt{'un'}" />
         $htmlerror $dragmath_button
       </div>
       <div class="LC_edit_problem_saves">
         <input type="submit" name="savethisfile" accesskey="s" value="$lt{'st'}" />
         <input type="submit" name="viewmode" accesskey="v" value="$lt{'vi'}" />
       </div>
     </div>
     <textarea $textarea_events style="width:100%" cols="80" rows="44" name="filecont" id="filecont" $textareaclass>$filecontents</textarea><br />$spelllink
     <div id="LC_aftertextarea">
       <br />
       $titledisplay
     </div>
 </form>  </form>
 </body>  </body>
 ENDFOOTER  ENDFOOTER
Line 1472  sub get_target { Line 1601  sub get_target {
   
 sub handler {  sub handler {
     my $request=shift;      my $request=shift;
       
     my $target=&get_target();      my $target=&get_target();
       
     $Apache::lonxml::debug=$env{'user.debug'};      $Apache::lonxml::debug=$env{'user.debug'};
           
     &Apache::loncommon::content_type($request,'text/html');      &Apache::loncommon::content_type($request,'text/html');
Line 1483  sub handler { Line 1611  sub handler {
  $request->set_last_modified(&Apache::lonnet::metadata($request->uri,   $request->set_last_modified(&Apache::lonnet::metadata($request->uri,
       'lastrevisiondate'));        'lastrevisiondate'));
     }      }
       # Embedded Flash movies from Camtasia served from https will not display in IE
       #   if XML config file has expired from cache.    
       if ($ENV{'SERVER_PORT'} == 443) {
           if ($request->uri =~ /\.xml$/) {
               my ($httpbrowser,$clientbrowser) =
                   &Apache::loncommon::decode_user_agent($request);
               if ($clientbrowser =~ /^explorer$/i) {
                   delete $request->headers_out->{'Cache-control'};
                   delete $request->headers_out->{'Pragma'};
                   my $expiration = time + 60;
                   my $date=strftime("%a, %d %b %Y %H:%M:%S GMT",gmtime($expiration));
                   $request->headers_out->set("Expires" => $date);
               }
           }
       }
     $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);
     my $filetype;      my ($filetype,$breadcrumbtext);
     if ($file =~ /\.sty$/) {      if ($file =~ /\.(sty|css|js|txt|tex)$/) {
  $filetype='sty';   $filetype=$1;
     } else {      } else {
  $filetype='html';   $filetype='html';
     }      }
       if ($filetype eq 'sty') {
           $breadcrumbtext = 'Style File Editor';
       } elsif ($filetype eq 'js') {
           $breadcrumbtext = 'Javascript Editor';
       } elsif ($filetype eq 'css') {
           $breadcrumbtext = 'CSS Editor';
       } elsif ($filetype eq 'txt') {
           $breadcrumbtext = 'Text Editor';
       } elsif ($filetype eq 'tex') {
           $breadcrumbtext = 'TeX Editor';
       } else {
           $breadcrumbtext = 'HTML Editor';
       }
   
 #  #
 # Edit action? Save file.  # Edit action? Save file.
 #  #
Line 1502  sub handler { Line 1659  sub handler {
  if ($env{'form.savethisfile'} || $env{'form.viewmode'} || $env{'form.Undo'}) {   if ($env{'form.savethisfile'} || $env{'form.viewmode'} || $env{'form.Undo'}) {
     my $html_file=&Apache::lonnet::getfile($file);      my $html_file=&Apache::lonnet::getfile($file);
     my $error = &Apache::lonhomework::handle_save_or_undo($request, \$html_file, \$env{'form.filecont'});      my $error = &Apache::lonhomework::handle_save_or_undo($request, \$html_file, \$env{'form.filecont'});
               if ($env{'form.savethisfile'}) {
                   $env{'form.editmode'}='Edit'; #force edit mode
               }
  }   }
     }      }
     my %mystyle;      my %mystyle;
Line 1510  sub handler { Line 1670  sub handler {
     if ($filecontents eq -1) {      if ($filecontents eq -1) {
  my $start_page=&Apache::loncommon::start_page('File Error');   my $start_page=&Apache::loncommon::start_page('File Error');
  my $end_page=&Apache::loncommon::end_page();   my $end_page=&Apache::loncommon::end_page();
  my $fnf=&mt('File not found');          my $errormsg='<p class="LC_error">'
                       .&mt('File not found: [_1]'
                           ,'<span class="LC_filename">'.$file.'</span>')
                       .'</p>';
  $result=(<<ENDNOTFOUND);   $result=(<<ENDNOTFOUND);
 $start_page  $start_page
 <b>$fnf: $file</b>  $errormsg
 $end_page  $end_page
 ENDNOTFOUND  ENDNOTFOUND
         $filecontents='';          $filecontents='';
  if ($env{'request.state'} ne 'published') {   if ($env{'request.state'} ne 'published') {
     if ($filetype eq 'sty') {      if ($filetype eq 'sty') {
  $filecontents=&createnewsty();   $filecontents=&createnewsty();
     } else {              } elsif ($filetype eq 'js') {
                   $filecontents=&createnewjs();
               } elsif ($filetype ne 'css' && $filetype ne 'txt' && $filetype ne 'tex') {
  $filecontents=&createnewhtml();   $filecontents=&createnewhtml();
     }      }
     $env{'form.editmode'}='Edit'; #force edit mode      $env{'form.editmode'}='Edit'; #force edit mode
Line 1536  ENDNOTFOUND Line 1701  ENDNOTFOUND
     ['editmode']);      ['editmode']);
  }   }
  if (!$env{'form.editmode'} || $env{'form.viewmode'} || $env{'form.discardview'}) {   if (!$env{'form.editmode'} || $env{'form.viewmode'} || $env{'form.discardview'}) {
     &Apache::structuretags::reset_problem_globals();              if ($filetype eq 'html' || $filetype eq 'sty') {
     $result = &Apache::lonxml::xmlparse($request,$target,$filecontents,          &Apache::structuretags::reset_problem_globals();
  '',%mystyle);          $result = &Apache::lonxml::xmlparse($request,$target,
                                                       $filecontents,'',%mystyle);
     # .html files may contain <problem> or <Task> need to clean      # .html files may contain <problem> or <Task> need to clean
     # up if it did      # up if it did
     &Apache::structuretags::reset_problem_globals();          &Apache::structuretags::reset_problem_globals();
     &Apache::lonhomework::finished_parsing();          &Apache::lonhomework::finished_parsing();
               } elsif ($filetype eq 'tex') {
                   $result = &Apache::lontexconvert::converted(\$filecontents,
                                 $env{'form.texengine'});
                   if ($env{'form.return_only_error_and_warning_counts'}) {
                       if (&verify_html('<html><body>'.$result.'</body></html>')) {
                           $errorcount++;
                       }
                       $result = "$errorcount:$warningcount";
                   }
               } else {
                   $result = $filecontents;
               }
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
     ['rawmode']);      ['rawmode']);
     if ($env{'form.rawmode'}) { $result = $filecontents; }      if ($env{'form.rawmode'}) { $result = $filecontents; }
     if ($filetype eq 'sty') {              if (($filetype ne 'html') && 
  my $controls =                  (!$env{'form.return_only_error_and_warning_counts'})) {
     ($env{'request.state'} eq 'construct') ? &Apache::londefdef::edit_controls()                  my $nochgview = 1;
                                            : '';                  my $controls = '';
  my %options = ('bgcolor' => '#FFFFFF');                      if ($env{'request.state'} eq 'construct') {
  $result =                           $controls = &Apache::loncommon::head_subbox(
     &Apache::loncommon::start_page(undef,undef,\%options).                                          &Apache::loncommon::CSTR_pageheader()
     $controls.                                         .&Apache::londefdef::edit_controls($nochgview));
     $result.                      }
     &Apache::loncommon::end_page();                  if ($filetype ne 'sty' && $filetype ne 'tex') {
     }                      $result =~ s/</&lt;/g;
  }                      $result =~ s/>/&gt;/g;
                       $result = '<table class="LC_sty_begin">'.
                                 '<tr><td><b><pre>'.$result.
                                 '</pre></b></td></tr></table>';
                   }
                   my $brcrum;
                   if ($env{'request.state'} eq 'construct') {
                       $brcrum = [{'href' => &Apache::loncommon::authorspace(),
                                   'text' => 'Construction Space'},
                                  {'href' => '',
                                   'text' => $breadcrumbtext}];
                   } else {
                       $brcrum = ''; # FIXME: Where are we?
                   }
                   my %options = ('bread_crumbs' => $brcrum,
                                  'bgcolor'      => '#FFFFFF');
                   $result =
                       &Apache::loncommon::start_page(undef,undef,\%options)
                      .$controls
                      .$result
                      .&Apache::loncommon::end_page();
               }
           }
     }      }
   
 #  #
Line 1566  ENDNOTFOUND Line 1766  ENDNOTFOUND
     unless ($env{'request.state'} eq 'published') {      unless ($env{'request.state'} eq 'published') {
  if ($env{'form.editmode'} && (!($env{'form.viewmode'})) && (!($env{'form.discardview'})))   if ($env{'form.editmode'} && (!($env{'form.viewmode'})) && (!($env{'form.discardview'})))
  {   {
     my ($edit_info, $add_to_onload, $add_to_onresize)=  
  &inserteditinfo($filecontents,$filetype);  
   
     my $displayfile=$request->uri;      my $displayfile=$request->uri;
     $displayfile=~s/^\/[^\/]*//;      $displayfile=~s/^\/[^\/]*//;
   
       my ($edit_info, $add_to_onload, $add_to_onresize)=
    &inserteditinfo($filecontents,$filetype,$displayfile);
   
     my %options =       my %options = 
  ('add_entries' =>   ('add_entries' =>
                    {'onresize' => $add_to_onresize,                     {'onresize'     => $add_to_onresize,
     'onload'   => $add_to_onload,   });                      'onload'       => $add_to_onload,   });
               my $header;
     if ($env{'environment.remote'} ne 'off') {              if ($env{'request.state'} eq 'construct') {
  $options{'bgcolor'}   = '#FFFFFF';                  $options{'bread_crumbs'} = [{
  $options{'only_body'} = 1;                              'href' => &Apache::loncommon::authorspace(),
     }                              'text' => 'Construction Space'},
                              {'href' => '',
                               'text' => $breadcrumbtext}];
                   $header = &Apache::loncommon::head_subbox(
                                 &Apache::loncommon::CSTR_pageheader());
               }
     my $js =      my $js =
  &Apache::edit::js_change_detection().   &Apache::edit::js_change_detection().
  &Apache::loncommon::resize_textarea_js();   &Apache::loncommon::resize_textarea_js();
     my $start_page = &Apache::loncommon::start_page(undef,$js,      my $start_page = &Apache::loncommon::start_page(undef,$js,
     \%options);      \%options);
     $result=$start_page.              $result = $start_page
  &Apache::lonxml::message_location().'<h3>'.                       .$header
  $displayfile.                       .&Apache::lonxml::message_location()
  '</h3>'.                       .$edit_info
  $edit_info.                       .&Apache::loncommon::end_page();
  &Apache::loncommon::end_page();          }
  }  
     }      }
     if ($filetype eq 'html') { &writeallows($request->uri); }      if ($filetype eq 'html') { &writeallows($request->uri); }
       
     &Apache::lonxml::add_messages(\$result);      &Apache::lonxml::add_messages(\$result);
     $request->print($result);      $request->print($result);
           
Line 1609  sub display_title { Line 1814  sub display_title {
     $title = $env{'request.filename'};      $title = $env{'request.filename'};
     $title = substr($title, rindex($title, '/') + 1);      $title = substr($title, rindex($title, '/') + 1);
  }   }
  $result = "<script type='text/javascript'>top.document.title = '$title - LON-CAPA Construction Space';</script>";          $result = "<script type='text/javascript'>top.document.title = '$title - LON-CAPA "
                     .&mt('Construction Space')."';</script>";
     }      }
     return $result;      return $result;
 }  }
Line 1646  sub error { Line 1852  sub error {
   
     $errorcount++;      $errorcount++;
   
       $Apache::lonxml::internal_error=1;
   
     if (defined($Apache::inputtags::part)) {      if (defined($Apache::inputtags::part)) {
  if ( @Apache::inputtags::response ) {   if ( @Apache::inputtags::response ) {
     push(@errors,      push(@errors,
Line 1662  sub error { Line 1870  sub error {
     if ( &show_error_warn_msg() ) {      if ( &show_error_warn_msg() ) {
  # If printing in construction space, put the error inside <pre></pre>   # If printing in construction space, put the error inside <pre></pre>
  push(@Apache::lonxml::error_messages,   push(@Apache::lonxml::error_messages,
      $Apache::lonxml::warnings_error_header.       $Apache::lonxml::warnings_error_header
      "<b>ERROR:</b>".join("<br />\n",@errors)."<br />\n");               .'<div class="LC_error">'
                .'<b>'.&mt('ERROR:').' </b>'.join("<br />\n",@errors)
                ."</div>\n");
  $Apache::lonxml::warnings_error_header='';   $Apache::lonxml::warnings_error_header='';
     } else {      } else {
  my $errormsg;   my $errormsg;
  my ($symb)=&Apache::lonnet::symbread();   my ($symb)=&Apache::lonnet::symbread();
  if ( !$symb ) {   if ( !$symb ) {
     #public or browsers      #public or browsers
     $errormsg=&mt("An error occured while processing this resource. The author has been notified.");      $errormsg=&mt("An error occurred while processing this resource. The author has been notified.");
  }   }
  my $host=$Apache::lonnet::perlvar{'lonHostID'};   my $host=$Apache::lonnet::perlvar{'lonHostID'};
  push(@errors, "The error occurred on host <tt>$host</tt>");   push(@errors,
           &mt("The error occurred on host [_1]",
                "<tt>$host</tt>"));
   
  my $msg = join('<br />', @errors);   my $msg = join('<br />', @errors);
   
Line 1707  sub error { Line 1919  sub error {
  }   }
     }      }
     if ($env{'request.role.adv'}) {      if ($env{'request.role.adv'}) {
  $errormsg=&mt("An error occured while processing this resource. The course personnel ([_1]) and the author have been notified.",join(', ',@userlist));   $errormsg=&mt("An error occurred while processing this resource. The course personnel ([_1]) and the author have been notified.",join(', ',@userlist));
     } else {      } else {
  $errormsg=&mt("An error occured while processing this resource. The instructor has been notified.");   $errormsg=&mt("An error occurred while processing this resource. The instructor has been notified.");
     }      }
  }   }
  push(@Apache::lonxml::error_messages,"<b>$errormsg</b> <br />");   push(@Apache::lonxml::error_messages,"<b>$errormsg</b> <br />");
Line 1722  sub warning { Line 1934  sub warning {
     if ($env{'form.grade_target'} ne 'tex') {      if ($env{'form.grade_target'} ne 'tex') {
  if ( &show_error_warn_msg() ) {   if ( &show_error_warn_msg() ) {
     push(@Apache::lonxml::warning_messages,      push(@Apache::lonxml::warning_messages,
  $Apache::lonxml::warnings_error_header.   $Apache::lonxml::warnings_error_header
  "<b>W</b>ARNING<b>:</b>".join('<br />',@_)."<br />\n");                  .'<div class="LC_warning">'
                   .&mt('[_1]W[_2]ARNING','<b>','</b>')."<b>:</b> ".join('<br />',@_)
                   ."</div>\n"
                   );
     $Apache::lonxml::warnings_error_header='';      $Apache::lonxml::warnings_error_header='';
  }   }
     }      }
Line 1948  sub get_tag { Line 2163  sub get_tag {
     return $insertlist{"$tagnum.tag"};      return $insertlist{"$tagnum.tag"};
 }  }
   
   ############################################################
   #                                           PDF-FORM-METHODS
   
   =pod
   
   =item &print_pdf_radiobutton(fieldname, value)
   
   Returns a latexline to generate a PDF-Form-Radiobutton.
   Note: Radiobuttons with equal names are automaticly grouped 
         in a selection-group.
   
   $fieldname: PDF internalname of the radiobutton(group)
   $value:     Value of radiobutton
   
   =cut
   sub print_pdf_radiobutton {
       my ($fieldname, $value) = @_;
       return '\radioButton[\symbolchoice{circle}]{'
              .$fieldname.'}{10bp}{10bp}{'.$value.'}';
   }
   
   
   =pod
   
   =item &print_pdf_start_combobox(fieldname)
   
   Starts a latexline to generate a PDF-Form-Combobox with text.
   
   $fieldname: PDF internal name of the Combobox
   
   =cut
   sub print_pdf_start_combobox {
       my $result;
       my ($fieldName) = @_;
       $result .= '\begin{tabularx}{\textwidth}{p{2.5cm}X}'."\n";
       $result .= '\comboBox[]{'.$fieldName.'}{2.3cm}{14bp}{'; # 
   
       return $result;
   }
   
   
   =pod
   
   =item &print_pdf_add_combobox_option(options)
   
   Generates a latexline to add Options to a PDF-Form-ComboBox.
   
   $option: PDF internal name of the Combobox-Option
   
   =cut
   sub print_pdf_add_combobox_option {
   
       my $result;
       my ($option) = @_;  
   
       $result .= '('.$option.')';
       
       return $result;
   }
   
   
   =pod
   
   =item &print_pdf_end_combobox(text) {
   
   Returns latexcode to end a PDF-Form-Combobox with text.
   
   =cut
   sub print_pdf_end_combobox {
       my $result;
       my ($text) = @_;
   
       $result .= '}&'.$text."\\\\\n";
       $result .= '\end{tabularx}' . "\n";
       $result .= '\hspace{2mm}' . "\n";
       return $result;
   }
   
   
   =pod
   
   =item &print_pdf_hiddenField(fieldname, user, domain)
   
   Returns a latexline to generate a PDF-Form-hiddenField with userdata.
   
   $fieldname label for hiddentextfield
   $user:    name of user
   $domain:  domain of user
   
   =cut
   sub print_pdf_hiddenfield {
       my $result;
       my ($fieldname, $user, $domain) = @_;
   
       $result .= '\textField [\F{\FHidden}\F{-\FPrint}\V{'.$domain.'&'.$user.'}]{'.$fieldname.'}{0in}{0in}'."\n";
   
       return $result;
   }
   
 1;  1;
 __END__  __END__
   
   

Removed from v.1.461  
changed lines
  Added in v.1.515


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