File:  [LON-CAPA] / loncom / xml / scripttag.pm
Revision 1.165: download - view: text, annotated - select for diffs
Sun Feb 5 23:00:06 2012 UTC (12 years, 4 months ago) by raeburn
Branches: MAIN
CVS tags: HEAD
- Support use of .js files as dependencies in web pages uploaded directly
  to a course (e.g., for Camtasia).

    1: # The LearningOnline Network with CAPA
    2: # <script> definiton
    3: #
    4: # $Id: scripttag.pm,v 1.165 2012/02/05 23:00:06 raeburn Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: 
   29: package Apache::scripttag;
   30: 
   31: use strict;
   32: use Apache::lonnet;
   33: use Apache::lonlocal;
   34: use Apache::style();
   35: 
   36: #Globals
   37: # this used to pass around the standard callsub arguments to a tag func
   38: # so xmlparse can reenter the inner_xmlparse loop.
   39: 
   40: @Apache::scripttag::parser_env = ();
   41: BEGIN {
   42:   &Apache::lonxml::register('Apache::scripttag',
   43: 			    ('script','scriptlib','parserlib','import',
   44: 			     'window','windowlink','togglebox','display','storetc','physnet',
   45: 			     'standalone','comment','num','parse','algebra',
   46: 			     'LONCAPA_INTERNAL_TURN_STYLE_ON',
   47: 			     'LONCAPA_INTERNAL_TURN_STYLE_OFF'));
   48: }
   49: 
   50: sub start_LONCAPA_INTERNAL_TURN_STYLE_ON {
   51:     $Apache::lonxml::usestyle=1;
   52:     $Apache::lonxml::style_values='';
   53:     return ('','no');
   54: }
   55: 
   56: sub end_LONCAPA_INTERNAL_TURN_STYLE_ON {
   57:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
   58:     my $end=&Apache::lonxml::get_param('end',$parstack,$safeeval);
   59:     if (defined($end)) {
   60: 	&Apache::lonxml::end_tag($tagstack,$parstack,$token);
   61:     }
   62:     return ('','no');
   63: }
   64: 
   65: sub start_LONCAPA_INTERNAL_TURN_STYLE_OFF {
   66:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
   67:     $Apache::lonxml::usestyle=0;
   68:     my $end=&Apache::lonxml::get_param('end',$parstack,$safeeval);
   69:     if (!$end) {
   70: 	$Apache::lonxml::style_values=$$parstack[-1];
   71: 	$Apache::lonxml::style_end_values=$$parstack[-1];
   72:     } else {
   73: 	$Apache::lonxml::style_values=$Apache::lonxml::style_end_values;
   74: 	$Apache::lonxml::style_end_values='';
   75:     }
   76:     return ('','no');
   77: }
   78: 
   79: sub end_LONCAPA_INTERNAL_TURN_STYLE_OFF {
   80:     return ('','no');
   81: }
   82: 
   83: sub start_script {
   84:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
   85:   @Apache::scripttag::parser_env = @_;
   86:   my $result='';
   87:   my $type= &Apache::lonxml::get_param('type',$parstack,$safeeval);
   88:   &Apache::lonxml::debug("found type of $type");
   89:   if ($type eq "loncapa/perl") {
   90:     if ( $target eq "modified" ) {
   91: 	$result=$token->[4].&Apache::edit::modifiedfield('/script',$parser);
   92:     } elsif ( $target eq 'web' || $target eq 'tex' ||
   93: 	      $target eq 'grade' || $target eq 'webgrade' ||
   94: 	      $target eq 'answer' || $target eq 'analyze' ) {
   95: 	my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/script",$parser);
   96: 	if (!$Apache::lonxml::default_homework_loaded) {
   97: 	    &Apache::lonxml::default_homework_load($safeeval);
   98: 	}
   99: 	&Apache::run::run($bodytext,$safeeval);
  100: 	if (($target eq 'answer') &&
  101: 	    ($env{'form.answer_output_mode'} ne 'tex') &&
  102: 	    ($Apache::lonhomework::viewgrades == 'F')) {
  103: 	    $Apache::lonxml::evaluate--;
  104: 	    my (undef,undef,$udom,$uname)=&Apache::lonnet::whichuser();
  105: 	    $uname =~s/\W//g;
  106: 	    $udom  =~s/\W//g;
  107: 	    my $function_name = 
  108: 		join('_','LONCAPA_scriptvars',$uname,$udom,
  109: 		     $env{'form.counter'},$Apache::lonxml::curdepth);
  110:             &Apache::lonxml::add_script_result(
  111: 	             &Apache::loncommon::modal_adhoc_window($function_name,500,500,
  112:                             '<pre>'.&Apache::run::dump($target,$safeeval).'</pre>',
  113:                             &mt('Script Vars'))."<br />");
  114: 	}
  115:     } elsif ($target eq "edit" ) {
  116:       #&Apache::run::run($bodytext,$safeeval);
  117:       #$result="<br /> &lt;$token->[1]&gt; output: <br />$bodytext<br />Source:<br />";
  118: 	my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/script",$parser);
  119: 	$result=&Apache::edit::tag_start($target,$token,'Script');
  120: 	$result.=&Apache::edit::editfield($token->[1],$bodytext,'',80,4);
  121:     } elsif ($target eq 'meta') {
  122: 	my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/script",$parser);
  123:     }
  124:   } else {
  125:       my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/script",$parser);
  126:       if ($target ne "meta" && $target ne 'tex' && $target ne 'answer') {
  127: 	  $result = $token->[4];
  128: 	  $result.=$bodytext;
  129:           if ($type eq "text/javascript") {
  130:               my $src=&Apache::lonxml::get_param('src',$parstack,$safeeval,undef,1);
  131:               if (($src =~ /\.js$/) && ($src !~ m{^(/|https?://)})) {
  132:                   my ($path,$scriptname) = ($src =~ m{^(.+)/([^/]*)$});
  133:                   my $docuri =
  134:                       $Apache::lonnet::env{'request.noversionuri'};
  135:                   my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
  136:                   my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
  137:                   if ($docuri =~ m{^(\Q/uploaded/$cdom/$cnum\E)/(docs/.*/)[^/]+$}) {
  138:                       my $prefix = $1;
  139:                       my $relpath = $2;
  140:                       my $cleanrelpath;
  141:                       foreach my $dir (split(/\//,$relpath.$path)) {
  142:                           next if ($dir eq '.');
  143:                           if ($dir eq '..') {
  144:                               $cleanrelpath =~ s{([^/]+/)$}{};
  145:                           } else {
  146:                               $cleanrelpath .= $dir.'/';
  147:                           }
  148:                       }
  149:                       $cleanrelpath =~ s{/$}{};
  150:                       if ($cleanrelpath ne '') {
  151:                           $src = $prefix.'/'.$cleanrelpath.'/'.$scriptname;
  152:                       } else {
  153:                           $src = $prefix.'/'.$scriptname;
  154:                       }
  155:                       if ($src ne '') {
  156:                           &Apache::lonxml::extlink($src);
  157:                       }
  158:                   }
  159:               }
  160:           }
  161:       }
  162:   }
  163:   return $result;
  164: }
  165: 
  166: sub end_script {
  167:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
  168:   if ( $target eq "meta" ) { return ''; } 
  169:   my $type = &Apache::lonxml::get_param('type',$parstack,$safeeval);
  170:   my $result='';
  171:   #other script blocks need to survive
  172:   if ($type ne "loncapa/perl" && $target ne 'tex') {
  173:     return $token->[2];
  174:   } elsif ($target eq 'edit' ) {
  175:     return &Apache::edit::end_table();
  176:   } elsif ($target eq 'answer') {
  177:     $Apache::lonxml::evaluate++;
  178:   }
  179:   return '';
  180: }
  181: 
  182: sub start_display {
  183:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
  184:   @Apache::scripttag::parser_env = @_;
  185:   my $result;
  186: 
  187:   if ( $target eq "modified" ) {
  188:       $result=$token->[4].&Apache::edit::modifiedfield("/display",$parser);
  189:   } elsif ( $target eq 'web' || $target eq 'tex' ||
  190: 	    $target eq 'grade' || $target eq 'webgrade' ||
  191: 	    $target eq 'answer' || $target eq 'analyze') {
  192:       my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/display",$parser);
  193:       if (!$Apache::lonxml::default_homework_loaded) {
  194: 	  &Apache::lonxml::default_homework_load($safeeval);
  195:       }
  196:       $result=&Apache::run::run($bodytext,$safeeval);
  197:       if ($target eq 'grade' || $target eq 'answer' ||
  198: 	  $target eq 'analyze') {
  199: 	  # grade/answer/analyxe should produce no output but if we
  200: 	  # are redirecting, the redirecter should know what to do
  201: 	  # with the output
  202: 	  if (!$Apache::lonxml::redirection) { $result=''; }
  203:       }
  204:       $Apache::lonxml::post_evaluate=0;
  205:   } elsif ($target eq "edit" ) {
  206:     my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/display",$parser);
  207:     #$result = 
  208:     #  "<br /> &lt;$token->[1]&gt; output: <br />$bodytext<br />Source:<br />";
  209:     #$result.=&Apache::edit::editfield($token->[1],$bodytext,'',40,1);
  210:     $result=&Apache::edit::tag_start($target,$token,'Script With Display');
  211:     $result.=&Apache::edit::editfield($token->[1],$bodytext,'',80,1)
  212:   } elsif ($target eq 'meta') {
  213:       my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/display",$parser);
  214:   }
  215:   return $result;
  216: }
  217: 
  218: sub end_display {
  219:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
  220:   if ($target eq 'edit' ) { return &Apache::edit::end_table(); }
  221:   return '';
  222: }
  223: 
  224: sub start_scriptlib {
  225:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  226:   my $bodytext;
  227:   my $result ='';
  228:   my $error='';
  229: 
  230:   if ($target eq 'web' || $target eq 'tex' || $target eq 'grade' ||
  231:       $target eq 'meta' || $target eq 'edit' || $target eq 'answer' ||
  232:       $target eq 'analyze' || $target eq 'webgrade') {
  233:     $bodytext=$$parser[$#$parser]->get_text("/scriptlib");
  234:     $bodytext=&Apache::run::evaluate($bodytext,$safeeval,
  235: 				     $$parstack[$#$parstack]);
  236:     my $location=&Apache::lonnet::filelocation($Apache::lonxml::pwd['-1'],
  237: 					       $bodytext);
  238:     my $script=&Apache::lonnet::getfile($location);
  239:     if ($script == -1) {
  240:       if ($target eq 'edit') {
  241:         $error='</tr><tr><td>'.&mt('Errors').'</td><td colspan="2"><b>'.&mt(' Unable to find [_1]','<span class="LC_filename">'.$location.'</span>').'</b></td>'."\n";
  242:       } else {
  243: 	&Apache::lonxml::error("<b> Unable to find <i>$location</i> for scriptlib</b>");
  244: 	return "";
  245:       }
  246:     }
  247:     &Apache::run::run($script,$safeeval);
  248:     #&Apache::lonxml::debug("ran $bodytext:<br />".&Apache::lonnet::getfile($bodytext)."<br />");
  249:   }
  250:   if ($target eq "edit" ) {
  251:     $result=
  252:       &Apache::edit::tag_start($target,$token,'New Script Functions').
  253: 	&Apache::edit::editline($token->[1],$bodytext,'scriptlib',40).
  254:             &Apache::edit::browse(undef,'textnode').
  255: 	  $error.'</td></tr>'.
  256: 	    &Apache::edit::end_table();
  257:   }
  258:   if ($target eq "modified" ) {
  259:       $result=$token->[4].&Apache::edit::modifiedfield("/scriptlib",$parser);
  260:   }
  261:   return $result;
  262: }
  263: 
  264: sub end_scriptlib {
  265:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  266:   my @result;
  267:   if ($target eq "edit" ) { $result[1]='no'; }
  268:   return @result;
  269: }
  270: 
  271: sub start_parserlib {
  272:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  273:   my $bodytext;
  274:   my $result ="";
  275:   my $error='';
  276:   if ($target eq 'web' || $target eq 'tex' || $target eq 'grade' ||
  277:       $target eq 'meta' || $target eq 'edit' || $target eq 'answer' ||
  278:       $target eq 'analyze' || $target eq 'webgrade') {
  279:     $bodytext=$$parser[$#$parser]->get_text("/parserlib");
  280:     $bodytext=&Apache::run::evaluate($bodytext,$safeeval,
  281: 				     $$parstack[$#$parstack]);
  282:     my $location=&Apache::lonnet::filelocation($Apache::lonxml::pwd['-1'],
  283: 					       $bodytext);
  284:     my $styletext=&Apache::lonnet::getfile($location);
  285:     #&Apache::lonxml::debug("found :$bodytext: in :$location: with :$styletext:");
  286:     if ($styletext == -1) {
  287:       if ($target eq 'edit') {
  288: 	$error='</tr><tr><td>Errors</td><td colspan="2"><b> Unable to find <i>'.$location.'</i></b></td>'."\n";
  289:       } else {
  290: 	&Apache::lonxml::error("<b> Unable to find <i>$location</i> for parserlib</b>");
  291: 	return "";
  292:       }
  293:     }
  294:     %$style = ( %$style , &Apache::style::styleparser($target,$styletext));
  295:   }
  296:   if ($target eq "edit" ) {
  297:     $result=
  298:       &Apache::edit::tag_start($target,$token,'New Tag Definitions').
  299: 	&Apache::edit::editline($token->[1],$bodytext,'',40).
  300: 	  $error.'</td></tr>'.
  301: 	    &Apache::edit::end_table();
  302:   }
  303:   if ($target eq "modified" ) {
  304:       $result=$token->[4].&Apache::edit::modifiedfield("/parserlib",$parser);
  305:   }
  306:   return $result;
  307: }
  308: 
  309: sub end_parserlib {
  310:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  311:   my @result;
  312:   if ($target eq "edit" ) { $result[1]='no'; }
  313:   return @result;
  314: }
  315: 
  316: sub start_window {
  317:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  318:     my $result = '';
  319:     if ($target eq 'web' || $target eq 'webgrade') {
  320: 	&Apache::lonxml::startredirection;
  321:     } elsif ($target eq 'tex') {
  322:         my $printtext=&Apache::lonxml::get_param('printtext',$parstack,$safeeval);
  323:         if ($printtext=~/\w/) {
  324: # If printtext is given, do not output any intervening information
  325:            &Apache::lonxml::startredirection;
  326:         } else {
  327:            $result = '\unskip\footnote{';
  328:         }
  329:     } elsif ($target eq 'edit') {
  330: 	$result.=&Apache::edit::tag_start($target,$token);
  331: 	$result.=&Apache::edit::text_arg('Text of Link:','linktext',$token,70);
  332: 	$result.=&Apache::edit::text_arg('Height:','height',$token,5);
  333: 	$result.=&Apache::edit::text_arg('Width:','width',$token,5);
  334:         $result.=&Apache::edit::text_arg('Printed text (optional):','printtext',$token,20);
  335: 	$result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
  336:     } elsif ($target eq 'modified') {
  337: 	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
  338: 						     $safeeval,'linktext',
  339: 						     'width','height');
  340: 	if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
  341:     }
  342:     return $result;  
  343: }
  344: 
  345: sub end_window {
  346:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  347:   my $result;
  348:   if ($target eq 'web' || $target eq 'webgrade') {
  349:     my $output=&Apache::lonxml::endredirection;
  350:     my $linktext= &Apache::lonxml::get_param('linktext',$parstack,$safeeval);
  351:     if (!$linktext) { $linktext='<sup>*</sup>'; }
  352:     my $width= &Apache::lonxml::get_param('width',$parstack,$safeeval);
  353:     if (!$width) { $width='500'; }
  354:     my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);
  355:     if (!$height) { $height='200'; }
  356:     $result=&Apache::loncommon::modal_adhoc_window
  357:            ("LONCAPA_newwindow_$Apache::lonxml::curdepth",$width,$height,$output,$linktext);
  358:   } elsif ($target eq 'tex') {
  359:       my $printtext=&Apache::lonxml::get_param('printtext',$parstack,$safeeval);
  360:       if ($printtext=~/\w/) {
  361: # If a "printtext" is given, proceed to retrieve all intervening information and trash it
  362:          my $output=&Apache::lonxml::endredirection;
  363: # Use printtext instead
  364:          $result=$printtext;
  365:       } else {
  366:          $result='}';
  367:       }
  368:   } else {
  369:       $result = '';
  370:   }
  371:   return $result; 
  372: }
  373: 
  374: 
  375: sub start_windowlink {
  376:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  377:     my $result = '';
  378:     if ($target eq 'web' || $target eq 'webgrade') {
  379:         &Apache::lonxml::startredirection;
  380:     } elsif ($target eq 'edit') {
  381:         $result.=&Apache::edit::tag_start($target,$token);
  382:         $result.=&Apache::edit::text_arg('Link:','href',$token,70);
  383:         $result.=&Apache::edit::text_arg('Height:','height',$token,5);
  384:         $result.=&Apache::edit::text_arg('Width:','width',$token,5);
  385:         $result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
  386:     } elsif ($target eq 'modified') {
  387:         my $constructtag=&Apache::edit::get_new_args($token,$parstack,
  388:                                                      $safeeval,'href',
  389:                                                      'width','height');
  390:         if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
  391:     }
  392:     return $result;
  393: }
  394: 
  395: sub end_windowlink {
  396:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  397:   my $result;
  398:   if ($target eq 'web' || $target eq 'webgrade') {
  399:     my $output=&Apache::lonxml::endredirection;
  400:     my $href= &Apache::lonxml::get_param('href',$parstack,$safeeval);
  401:     if (!$href) { $href='/adm/rat/empty.html'; }
  402:     my $width= &Apache::lonxml::get_param('width',$parstack,$safeeval);
  403:     if (!$width) { $width='500'; }
  404:     my $height= &Apache::lonxml::get_param('height',$parstack,$safeeval);
  405:     if (!$height) { $height='200'; }
  406:     $result=&Apache::loncommon::modal_link($href,$output,$width,$height);
  407:   } else {
  408:       $result = '';
  409:   }
  410:   return $result;
  411: }
  412: 
  413: 
  414: sub start_togglebox {
  415:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  416:     my $result = '';
  417:     if ($target eq 'web' || $target eq 'webgrade') {
  418:         my $id="LONCAPA_togglebox_$Apache::lonxml::curdepth";
  419:         my $heading=&Apache::lonxml::get_param('heading',$parstack,$safeeval);
  420:         unless ($heading) { $heading=''; } else { $heading.=' '; }
  421:         my $showtext=&Apache::lonxml::get_param('showtext',$parstack,$safeeval);
  422:         my $hidetext=&Apache::lonxml::get_param('hidetext',$parstack,$safeeval);
  423:         my $headerbg=&Apache::lonxml::get_param('headerbg',$parstack,$safeeval);
  424:         $result=&Apache::loncommon::start_togglebox($id,$heading,$headerbg,$hidetext,$showtext);
  425:     } elsif ($target eq 'tex') {
  426:         my $heading=&Apache::lonxml::get_param('heading',$parstack,$safeeval);
  427:         unless ($heading) { $heading=''; } else { $heading.=' '; }
  428:         $result = "\n\n".'\fbox{{\bf '.$heading.'} \qquad '."\n";
  429:     } elsif ($target eq 'edit') {
  430:         $result.=&Apache::edit::tag_start($target,$token);
  431:         $result.=&Apache::edit::text_arg('Heading:','heading',$token,70);
  432:         $result.=&Apache::edit::text_arg('Header Background:','headerbg',$token,7);
  433:         $result.=&Apache::edit::text_arg('Show text:','showtext',$token,10);
  434:         $result.=&Apache::edit::text_arg('Hide text:','hidetext',$token,10);
  435:         $result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
  436:     } elsif ($target eq 'modified') {
  437:         my $constructtag=&Apache::edit::get_new_args($token,$parstack,
  438:                                                      $safeeval,'heading',
  439:                                                      'showtext','hidetext',
  440:                                                      'headerbg','textbg');
  441:         if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
  442:     }
  443:     return $result;
  444: }
  445: 
  446: sub end_togglebox {
  447:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  448:   my $result;
  449:   if ($target eq 'web' || $target eq 'webgrade') {
  450:     $result=&Apache::loncommon::end_togglebox();
  451:   } elsif ($target eq 'tex') {
  452:       $result = "}\n\n";
  453:   } else {
  454:       $result = '';
  455:   }
  456:   return $result;
  457: }
  458: 
  459: 
  460: 
  461: sub start_import {
  462:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  463:   my $bodytext=$$parser[$#$parser]->get_text("/import");
  464:   my $result ="";
  465: 
  466:   $bodytext=&Apache::run::evaluate($bodytext,$safeeval,$$parstack[$#$parstack]);
  467: 
  468:   if ($target eq 'web' ||  $target eq 'webgrade' || $target eq 'grade' 
  469:       || $target eq 'answer' || $target eq 'tex' || $target eq 'analyze' ) {
  470:     # FIXME this probably needs to be smart about construction vs.
  471:     # non construction space.
  472:     my $location=&Apache::lonnet::filelocation($Apache::lonxml::pwd['-1'],$bodytext);
  473:     my $file=&Apache::lonnet::getfile($location);
  474:     if ($file == -1) {
  475:       &Apache::lonxml::error("<b> Unable to find <i>$bodytext as $location</i> for import</b>");
  476:       return "";
  477:     }
  478:     my $importmode=&Apache::lonxml::get_param('importmode',$parstack,$safeeval);
  479:     if (($importmode eq 'problem') || ($importmode eq 'part')) {
  480: # We are using import to import published problems
  481:        if (($importmode eq 'problem') || ($file=~/<part[^<]*>/s)) {
  482: # We explicitly don't want this to be a separate part or the problem already has parts
  483:           $file=~s/^\s*<problem>/<library>/s;
  484: 	  $file=~s/<\/problem>\s*$/<\/library>/s;
  485:        } else {
  486: # We want this to be a separate part, but it currently is not
  487:           $file=~s/^\s*<problem>/<library><part>/s;
  488: 	  $file=~s/<\/problem>\s*$/<\/part><\/library>/s;
  489:        }
  490:     }
  491:     my $dir=$location;
  492:     $dir=~s:/[^/]*$::;
  493:     #  &Apache::lonxml::debug("directory $dir $location file $file \n<b>END</b>\n");
  494:     my $id= &Apache::lonxml::get_id($parstack,$safeeval);
  495:     if (!$id) { $id=$Apache::lonxml::curdepth; }
  496:     push(@Apache::inputtags::import,$id);
  497:     push(@Apache::inputtags::importlist,$id);
  498: 
  499:     &Apache::lonxml::newparser($parser,\$file,$dir);
  500: 
  501:   } elsif ($target eq "edit" ) {
  502:     $result.=&Apache::edit::tag_start($target,$token);
  503:     my $location=$token->[1];
  504:     $location=~s/^\s*//s;
  505:     $location=~s/\s*$//s;
  506:     $result.=&Apache::edit::editline($location,$bodytext,'',40);
  507:     $result.=&Apache::edit::browse(undef,'textnode');
  508:     $result.= '&nbsp;<label>'.&mt('Import as:').
  509:               '<select name="importmode_'.$Apache::lonxml::curdepth.'">';
  510:     my %options=&Apache::lonlocal::texthash(''        => 'as standard library',
  511:                                             'problem' => 'as problem',
  512:                                             'part'    => 'as problem part(s)');
  513:     foreach my $option (sort(keys(%options))) {
  514:        $result.='<option value="'.$option.'"';
  515:        if ($option eq &Apache::lonxml::get_param('importmode',$parstack,$safeeval)) {
  516:           $result.=' selected="selected"';
  517:        }
  518:        $result.='>'.$options{$option}.'</option>';
  519:     }
  520:     $result.='</select></label>';
  521:     #FIXME this need to convert $bodytext to be a contruction space reference
  522:     #my $location=&Apache::lonnet::filelocation($Apache::lonxml::pwd['-1'],$bodytext);
  523:     #$result.="Click<a href=\"$location\">here</a> to edit<br />"
  524:   } elsif ($target eq 'modified') {
  525:       &Apache::edit::get_new_args($token,$parstack,$safeeval,'importmode');
  526:       $result='<import id="'.$token->[2]{'id'}.'" importmode="'.$token->[2]{'importmode'}.'">';
  527:       $result.=&Apache::edit::modifiedfield("/import",$parser);
  528:   } elsif ($target eq 'meta') {
  529:     my $id= &Apache::lonxml::get_id($parstack,$safeeval);
  530:     $result.='<import part="'.$Apache::inputtags::part;
  531:     if ($id) {
  532:       $result.='" id="'.$id;
  533:     }
  534:     $result.='" importmode="'.$token->[2]{'importmode'}.'">';
  535:     $result.=$bodytext;
  536:     $result.='</import>';
  537:   }
  538:   return $result;
  539: }
  540: 
  541: sub end_import {
  542:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  543:   pop(@Apache::inputtags::import);
  544:   my $result;
  545:   if ($target eq 'edit' ) { $result=&Apache::edit::end_row.
  546: 				&Apache::edit::end_table(); }
  547:   return $result;
  548: }
  549: 
  550: sub start_storetc {
  551:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  552:   my $result = '';
  553:   &Apache::lonxml::startredirection;
  554:   return $result; 
  555: }
  556: 
  557: sub end_storetc {
  558:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  559:     my $result;
  560:     my $output=&Apache::lonxml::endredirection;
  561:     $output =~ s/\"/\&quot\;/g;
  562:     $result = '{\bf '.$output.'.}}\write\tcfile{\protect\tcpc{ '.$output.'.}{\the\value{relpage}}}';
  563:     return $result;
  564: }
  565: 
  566: 
  567: sub start_physnet {
  568:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  569:     my $bodytext = '/adm/includes/physnet.sty';
  570:     my $location=&Apache::lonnet::filelocation($Apache::lonxml::pwd['-1'],$bodytext);
  571:     my $cbistyletext=&Apache::lonnet::getfile($location);
  572: 
  573:     %$style = (%$style,&Apache::style::styleparser($target,$cbistyletext));
  574:     $$parser['-1']->unget_token($token);
  575: #    if ( defined($$style{'physnet'}) ) {
  576: #        &Apache::lonxml::newparser($parser,\$$style{'physnet'});
  577: #    }
  578:     return "";
  579: }
  580: 
  581: sub end_physnet {
  582:   return '';
  583: }
  584: 
  585: sub start_standalone {
  586:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  587:   my $result='';
  588:   if ($target eq 'web' || $target eq 'webgrade') {
  589:     if ( $env{'request.course.id'} ) {
  590:       my $inside = &Apache::lonxml::get_all_text("/standalone",$parser,$style);
  591:     } else {
  592:       $result='<table bgcolor="#E1E1E1" border="2"><tr><td>';
  593:     }
  594:   }
  595:   return $result;
  596: }
  597: 
  598: sub end_standalone {
  599:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  600:   my $result='';
  601:   if ($target eq 'web' || $target eq 'webgrade' ) {
  602:     if ( $env{'request.course.id'} ) {
  603:     } else {
  604:       $result='</td></tr></table>';
  605:     }
  606:   }
  607:   return $result;
  608: }
  609: 
  610: sub start_comment {
  611:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  612:   my $result='';
  613:   if ($target eq 'edit') {
  614:     $result=&Apache::edit::tag_start($target,$token);
  615:     my $bodytext=&Apache::lonxml::get_all_text("/comment",$parser,$style);
  616:     $result.=&Apache::edit::editfield($token->[1],$bodytext,'',80,4)
  617:   } elsif ( $target eq 'modified') {
  618:     $result=$token->[4].&Apache::edit::modifiedfield("/comment",$parser);
  619:   } elsif ( $target eq 'web'    || $target eq 'tex'  || $target eq 'grade'   ||
  620: 	    $target eq 'answer' || $target eq 'meta' || $target eq 'analyze' ||
  621: 	    $target eq 'webgrade') {
  622:     #normally throw away comments
  623:     my $bodytext=&Apache::lonxml::get_all_text("/comment",$parser,$style);
  624:   }
  625:   return $result;
  626: }
  627: 
  628: sub end_comment {
  629:   my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
  630:   if ($target eq 'edit' ) { return &Apache::edit::end_table(); }
  631:   return '';
  632: }
  633: 
  634: 
  635: sub xmlparse {
  636:   my ($string) = @_;
  637:   &Apache::lonxml::debug("xmlparse recursion starting with $string");
  638:   # Apache::run::evaluate does an 'eval' on the name of the subroutine
  639:   # if it detects something that looks like a subroutine, this ends up calling
  640:   # things without any arguments and since perl is nice enough to pass
  641:   # along the default arguments when you don't explicitly say no arguments
  642:   # if you call &xmlparse, it gets &xmlparse passed as it argument.
  643:   # Same thing soccurs with &chemparse.
  644:   if ($string eq '&xmlparse') { return '&xmlparse'; }
  645:   if ($string eq '&chemparse') { return '&chemparse'; }
  646:   my ($target,$token,$tagstack,$parstack,$oldparser,$safeeval,$style)=
  647:     @Apache::scripttag::parser_env;
  648:   my @parser;
  649:   &Apache::lonxml::newparser(\@parser,\$string);
  650:   &Apache::lonxml::startredirection();
  651:   my $result=&Apache::lonxml::inner_xmlparse($target,$tagstack,
  652: 					     $parstack,\@parser,
  653: 					     $safeeval,$style);
  654:   $result.=&Apache::lonxml::endredirection();
  655:   &Apache::lonxml::debug("target is $target xmlparse recursion ending with $result");
  656:   return $result;
  657: }
  658: 
  659: sub start_num {
  660:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
  661:     my $result = '';
  662:     my $inside = &Apache::lonxml::get_all_text_unbalanced("/num",$parser);
  663:     if ($target eq 'tex' || $target eq 'web' || $target eq 'webgrade') {
  664: 	$inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
  665: 	if (!$Apache::lonxml::default_homework_loaded) {
  666: 	    &Apache::lonxml::default_homework_load($safeeval);
  667: 	}
  668: 	@Apache::scripttag::parser_env = @_;
  669: 	my $format=&Apache::lonxml::get_param('format',$parstack,$safeeval);
  670: 	$result=&Apache::run::run("return &prettyprint(q\0$inside\0,q\0$format\0);",$safeeval);
  671:     }    
  672:     return $result;
  673: }
  674: 
  675: sub end_num {
  676:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
  677:     my $result = '';
  678:     return $result;
  679: }
  680: 
  681: sub start_parse {
  682:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
  683:     my $result = '';
  684:     if ( $target eq 'web'    || $target eq 'tex'    ||
  685: 	 $target eq 'grade'  || $target eq 'answer' ||
  686: 	 $target eq 'analyze'|| $target eq 'webgrade') {
  687: 	my $inside = &Apache::lonxml::get_all_text_unbalanced("/parse",$parser);
  688: 	$inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
  689: 	if (!$Apache::lonxml::default_homework_loaded) {
  690: 	    &Apache::lonxml::default_homework_load($safeeval);
  691: 	}
  692: 	@Apache::scripttag::parser_env = @_;
  693: 	$result=&Apache::run::run("return &xmlparse(q\0$inside\0);",$safeeval);
  694: 	if ($target eq 'grade' || $target eq 'answer' ||
  695: 	    $target eq 'analyze') {
  696: 	    # grade/answer/analyxe should produce no output but if we
  697: 	    # are redirecting, the redirecter should know what to do
  698: 	    # with the output
  699: 	    if (!$Apache::lonxml::redirection) { $result=''; }
  700: 	}
  701:     }
  702:     return $result;
  703: }
  704: 
  705: sub end_parse {
  706:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
  707:     my $result = '';
  708:     return $result;
  709: }
  710: 
  711: sub start_algebra {
  712:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
  713:     my $result = '';
  714:     if ( $target eq 'web'     || $target eq 'tex'    ||
  715: 	 $target eq 'grade'   || $target eq 'answer' ||
  716: 	 $target eq 'analyze' || $target eq 'webgrade') {
  717: 	my $inside = &Apache::lonxml::get_all_text_unbalanced("/algebra",$parser);
  718: 	$inside = &Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
  719: 	if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
  720: 	    my $style=&Apache::lonxml::get_param('style',$parstack,$safeeval);
  721: 	    $result=&Apache::lontexconvert::algebra($inside,$target,$style,$parstack,$safeeval);
  722: 	}
  723: 	$Apache::lonxml::post_evaluate=0;
  724:     }
  725:     return $result;
  726: }
  727: 
  728: sub end_algebra {
  729:     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
  730:     my $result = '';
  731:     return $result;
  732: }
  733: 
  734: 1;
  735: __END__
  736: 
  737: =pod
  738: 
  739: =head1 NAME
  740: 
  741: Apache::scripttag.pm
  742: 
  743: =head1 SYNOPSIS
  744: 
  745: implements <script>, <scriptlib>, <parserlib>,
  746: and <import>
  747: 
  748: This is part of the LearningOnline Network with CAPA project
  749: described at http://www.lon-capa.org.
  750: 
  751: =cut
  752: 

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