Annotation of loncom/xml/lonxml.pm, revision 1.531.2.4

1.2       sakharuk    1: # The LearningOnline Network with CAPA
1.3       sakharuk    2: # XML Parser Module 
1.2       sakharuk    3: #
1.531.2.4! raeburn     4: # $Id: lonxml.pm,v 1.531.2.3 2012/05/25 15:01:31 raeburn Exp $
1.139     www         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: # Copyright for TtHfunc and TtMfunc by Ian Hutchinson. 
                     29: # TtHfunc and TtMfunc (the "Code") may be compiled and linked into 
                     30: # binary executable programs or libraries distributed by the 
                     31: # Michigan State University (the "Licensee"), but any binaries so 
                     32: # distributed are hereby licensed only for use in the context
                     33: # of a program or computational system for which the Licensee is the 
                     34: # primary author or distributor, and which performs substantial 
                     35: # additional tasks beyond the translation of (La)TeX into HTML.
                     36: # The C source of the Code may not be distributed by the Licensee
                     37: # to any other parties under any circumstances.
                     38: #
1.316     albertel   39: 
1.489     jms        40: =pod
                     41: 
                     42: =head1 NAME
                     43: 
                     44: Apache::lonxml
                     45: 
                     46: =head1 SYNOPSIS
                     47: 
                     48: XML Parsing Module
                     49: 
                     50: This is part of the LearningOnline Network with CAPA project
                     51: described at http://www.lon-capa.org.
                     52: 
                     53: 
                     54: =head1 SUBROUTINES
                     55: 
                     56: =cut
                     57: 
                     58: 
1.2       sakharuk   59: 
1.4       albertel   60: package Apache::lonxml; 
1.33      www        61: use vars 
1.410     albertel   62: qw(@pwd @outputstack $redirection $import @extlinks $metamode $evaluate %insertlist @namespace $errorcount $warningcount);
1.1       sakharuk   63: use strict;
1.444     albertel   64: use LONCAPA;
1.167     albertel   65: use HTML::LCParser();
1.161     albertel   66: use HTML::TreeBuilder();
                     67: use HTML::Entities();
                     68: use Safe();
                     69: use Safe::Hole();
                     70: use Math::Cephes();
                     71: use Math::Random();
                     72: use Opcode();
1.271     www        73: use POSIX qw(strftime);
1.339     albertel   74: use Time::HiRes qw( gettimeofday tv_interval );
1.393     albertel   75: use Symbol();
1.266     bowersj2   76: 
1.72      albertel   77: sub register {
1.141     albertel   78:   my ($space,@taglist) = @_;
                     79:   foreach my $temptag (@taglist) {
                     80:     push(@{ $Apache::lonxml::alltags{$temptag} },$space);
1.72      albertel   81:   }
                     82: }
                     83: 
1.141     albertel   84: sub deregister {
                     85:   my ($space,@taglist) = @_;
                     86:   foreach my $temptag (@taglist) {
                     87:     my $tempspace = $Apache::lonxml::alltags{$temptag}[-1];
                     88:     if ($tempspace eq $space) {
                     89:       pop(@{ $Apache::lonxml::alltags{$temptag} });
                     90:     }
                     91:   }
1.142     albertel   92:   #&printalltags();
1.141     albertel   93: }
                     94: 
1.46      www        95: use Apache::Constants qw(:common);
1.161     albertel   96: use Apache::lontexconvert();
                     97: use Apache::style();
                     98: use Apache::run();
                     99: use Apache::londefdef();
                    100: use Apache::scripttag();
1.285     www       101: use Apache::languagetags();
1.161     albertel  102: use Apache::edit();
1.266     bowersj2  103: use Apache::inputtags();
                    104: use Apache::outputtags();
1.372     albertel  105: use Apache::lonnet;
1.161     albertel  106: use Apache::File();
                    107: use Apache::loncommon();
1.198     www       108: use Apache::lonfeedback();
1.200     www       109: use Apache::lonmsg();
1.217     matthew   110: use Apache::loncacc();
1.431     www       111: use Apache::lonmaxima();
1.494     www       112: use Apache::lonr();
1.280     www       113: use Apache::lonlocal;
1.501     raeburn   114: use Apache::lonhtmlcommon();
1.520     www       115: use Apache::functionplotresponse();
1.529     raeburn   116: use Apache::lonnavmaps();
1.79      www       117: 
1.462     foxr      118: #====================================   Main subroutine: xmlparse  
                    119: 
1.72      albertel  120: #debugging control, to turn on debugging modify the correct handler
1.462     foxr      121: 
1.72      albertel  122: $Apache::lonxml::debug=0;
1.206     albertel  123: 
                    124: # keeps count of the number of warnings and errors generated in a parse
                    125: $warningcount=0;
                    126: $errorcount=0;
1.72      albertel  127: 
                    128: #path to the directory containing the file currently being processed
                    129: @pwd=();
                    130: 
                    131: #these two are used for capturing a subset of the output for later processing,
                    132: #don't touch them directly use &startredirection and &endredirection
                    133: @outputstack = ();
                    134: $redirection = 0;
                    135: 
                    136: #controls wheter the <import> tag actually does
                    137: $import = 1;
                    138: @extlinks=();
                    139: 
                    140: # meta mode is a bit weird only some output is to be turned off
                    141: #<output> tag turns metamode off (defined in londefdef.pm)
                    142: $metamode = 0;
                    143: 
                    144: # turns on and of run::evaluate actually derefencing var refs
                    145: $evaluate = 1;
1.7       albertel  146: 
1.74      albertel  147: # data structure for eidt mode, determines what tags can go into what other tags
                    148: %insertlist=();
1.68      www       149: 
1.99      albertel  150: # stores the list of active tag namespaces
1.76      albertel  151: @namespace=();
                    152: 
1.448     albertel  153: # stores all Scrit Vars displays for later showing
                    154: my @script_var_displays=();
                    155: 
1.172     albertel  156: # a pointer the the Apache request object
                    157: $Apache::lonxml::request='';
                    158: 
1.216     sakharuk  159: # a problem number counter, and check on ether it is used
1.237     sakharuk  160: $Apache::lonxml::counter=1;
1.204     albertel  161: $Apache::lonxml::counter_changed=0;
                    162: 
1.462     foxr      163: # Part counter hash.   In analysis mode, the
                    164: # problems can use this to record which parts increment the counter
                    165: # by how much.  The counter subs will maintain this hash via
                    166: # their optional part parameters.  Note that the assumption is that
                    167: # analysis is done in one request and therefore it is not necessary to
                    168: # save this information request-to-request.
                    169: 
                    170: 
                    171: %Apache::lonxml::counters_per_part = ();
                    172: 
1.212     albertel  173: #internal check on whether to look at style defs
                    174: $Apache::lonxml::usestyle=1;
1.260     albertel  175: 
                    176: #locations used to store the parameter string for style substitutions
                    177: $Apache::lonxml::style_values='';
                    178: $Apache::lonxml::style_end_values='';
1.212     albertel  179: 
1.281     albertel  180: #array of ssi calls that need to occur after we are done parsing
                    181: @Apache::lonxml::ssi_info=();
                    182: 
1.282     albertel  183: #should we do the postag variable interpolation
                    184: $Apache::lonxml::post_evaluate=1;
                    185: 
1.295     albertel  186: #a header message to emit in the case of any generated warning or errors
                    187: $Apache::lonxml::warnings_error_header='';
                    188: 
1.396     foxr      189: #  Control whether or not LaTeX symbols should be substituted for their
                    190: #  \ style equivalents...this may be turned off e.g. in an verbatim
                    191: #  environment.
                    192: 
                    193: $Apache::lonxml::substitute_LaTeX_symbols = 1; # Starts out on.
                    194: 
                    195: sub enable_LaTeX_substitutions {
                    196:     $Apache::lonxml::substitute_LaTeX_symbols = 1;
                    197: }
                    198: sub disable_LaTeX_substitutions {
                    199:     $Apache::lonxml::substitute_LaTeX_symbols = 0;
                    200: }
                    201: 
1.68      www       202: sub xmlend {
1.335     sakharuk  203:     my ($target,$parser)=@_;
1.278     www       204:     my $mode='xml';
                    205:     my $status='OPEN';
1.368     albertel  206:     if ($Apache::lonhomework::parsing_a_problem ||
                    207: 	$Apache::lonhomework::parsing_a_task ) {
1.278     www       208: 	$mode='problem';
                    209: 	$status=$Apache::inputtags::status[-1]; 
                    210:     }
1.362     matthew   211:     my $discussion;
1.379     albertel  212:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                    213: 					   ['LONCAPA_INTERNAL_no_discussion']);
1.528     www       214:     if (
                    215:            (   (!exists($env{'form.LONCAPA_INTERNAL_no_discussion'})) 
                    216:             || ($env{'form.LONCAPA_INTERNAL_no_discussion'} ne 'true')
                    217:            ) 
                    218:         && ($env{'form.inhibitmenu'} ne 'yes')
                    219:        ) {
1.362     matthew   220:         $discussion=&Apache::lonfeedback::list_discussion($mode,$status);
                    221:     }
1.334     sakharuk  222:     if ($target eq 'tex') {
1.335     sakharuk  223: 	$discussion.='<tex>\keephidden{ENDOFPROBLEM}\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\end{document}</tex>';
1.334     sakharuk  224: 	&Apache::lonxml::newparser($parser,\$discussion,'');
                    225: 	return '';
                    226:     }
1.405     albertel  227: 
1.407     albertel  228:     return $discussion;
1.119     www       229: }
                    230: 
1.531.2.2  raeburn   231: sub tokeninputfield {
                    232:     my $defhost=$Apache::lonnet::perlvar{'lonHostID'};
                    233:     $defhost=~tr/a-z/A-Z/;
                    234:     return (<<ENDINPUTFIELD)
                    235: <script type="text/javascript">
                    236:     function updatetoken() {
                    237:         var comp=new Array;
                    238:         var barcode=unescape(document.tokeninput.barcode.value);
                    239:         comp=barcode.split('*');
                    240:         if (typeof(comp[0])!="undefined") {
                    241:             document.tokeninput.codeone.value=comp[0];
                    242:         }
                    243:         if (typeof(comp[1])!="undefined") {
                    244:             document.tokeninput.codetwo.value=comp[1];
                    245:         }
                    246:         if (typeof(comp[2])!="undefined") {
                    247:             comp[2]=comp[2].toUpperCase();
                    248:             document.tokeninput.codethree.value=comp[2];
                    249:         }
                    250:         document.tokeninput.barcode.value='';
                    251:     }
                    252: </script>
                    253: <form method="post" name="tokeninput" action="">
                    254: <table border="2" bgcolor="#FFFFBB">
                    255: <tr><th>DocID Checkin</th></tr>
                    256: <tr><td>
                    257: <table>
                    258: <tr>
                    259: <td>Scan in Barcode</td>
                    260: <td><input type="text" size="22" name="barcode"
                    261: onchange="updatetoken()"/></td>
                    262: </tr>
                    263: <tr><td><i>or</i> Type in DocID</td>
                    264: <td>
                    265: <input type="text" size="5" name="codeone" />
                    266: <b><font size="+2">*</font></b>
                    267: <input type="text" size="5" name="codetwo" />
                    268: <b><font size="+2">*</font></b>
                    269: <input type="text" size="10" name="codethree" value="$defhost"
                    270: onchange="this.value=this.value.toUpperCase()" />
                    271: </td></tr>
                    272: </table>
                    273: </td></tr>
                    274: <tr><td><input type="submit" value="Check in DocID" /></td></tr>
                    275: </table>
                    276: </form>
                    277: ENDINPUTFIELD
                    278: }
                    279: 
                    280: sub maketoken {
                    281:     my ($symb,$tuname,$tudom,$tcrsid)=@_;
                    282:     unless ($symb) {
                    283:         $symb=&Apache::lonnet::symbread();
                    284:     }
                    285:     unless ($tuname) {
                    286:         $tuname=$env{'user.name'};
                    287:         $tudom=$env{'user.domain'};
                    288:         $tcrsid=$env{'request.course.id'};
                    289:     }
                    290:     return &Apache::lonnet::checkout($symb,$tuname,$tudom,$tcrsid);
                    291: }
                    292: 
                    293: sub printtokenheader {
                    294:     my ($target,$token,$tsymb,$tcrsid,$tudom,$tuname)=@_;
                    295:     unless ($token) { return ''; }
                    296: 
                    297:     my ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser();
                    298:     unless ($tsymb) {
                    299:         $tsymb=$symb;
                    300:     }
                    301:     unless ($tuname) {
                    302:         $tuname=$name;
                    303:         $tudom=$domain;
                    304:         $tcrsid=$courseid;
                    305:     }
                    306: 
                    307:     my $plainname=&Apache::loncommon::plainname($tuname,$tudom);
                    308: 
                    309:     if ($target eq 'web') {
                    310:         my %idhash=&Apache::lonnet::idrget($tudom,($tuname));
                    311:         return
                    312:  '<img align="right" src="/cgi-bin/barcode.png?encode='.$token.'" />'.
                    313:                &mt('Checked out for').' '.$plainname.
                    314:                '<br />'.&mt('User').': '.$tuname.' at '.$tudom.
                    315:                '<br />'.&mt('ID').': '.$idhash{$tuname}.
                    316:                '<br />'.&mt('CourseID').': '.$tcrsid.
                    317:                '<br />'.&mt('Course').': '.$env{'course.'.$tcrsid.'.description'}.
                    318:                '<br />'.&mt('DocID').': '.$token.
                    319:                '<br />'.&mt('Time').': '.&Apache::lonlocal::locallocaltime().'<hr />';
                    320:     } else {
                    321:         return $token;
                    322:     }
                    323: }
                    324: 
1.48      albertel  325: sub printalltags {
                    326:   my $temp;
                    327:   foreach $temp (sort keys %Apache::lonxml::alltags) {
1.141     albertel  328:     &Apache::lonxml::debug("$temp -- ".
                    329: 		  join(',',@{ $Apache::lonxml::alltags{$temp} }));
1.48      albertel  330:   }
                    331: }
1.31      sakharuk  332: 
1.3       sakharuk  333: sub xmlparse {
1.172     albertel  334:  my ($request,$target,$content_file_string,$safeinit,%style_for_target) = @_;
1.96      albertel  335: 
1.172     albertel  336:  &setup_globals($request,$target);
1.232     albertel  337:  &Apache::inputtags::initialize_inputtags();
1.370     albertel  338:  &Apache::bridgetask::initialize_bridgetask();
1.232     albertel  339:  &Apache::outputtags::initialize_outputtags();
                    340:  &Apache::edit::initialize_edit();
1.287     albertel  341:  &Apache::londefdef::initialize_londefdef();
1.244     albertel  342: 
1.178     www       343: #
                    344: # do we have a course style file?
                    345: #
                    346: 
1.372     albertel  347:  if ($env{'request.course.id'} && $env{'request.state'} ne 'construct') {
1.178     www       348:      my $bodytext=
1.372     albertel  349: 	 $env{'course.'.$env{'request.course.id'}.'.default_xml_style'};
1.178     www       350:      if ($bodytext) {
1.337     albertel  351: 	 foreach my $file (split(',',$bodytext)) {
                    352: 	     my $location=&Apache::lonnet::filelocation('',$file);
                    353: 	     my $styletext=&Apache::lonnet::getfile($location);
                    354: 	     if ($styletext ne '-1') {
                    355: 		 %style_for_target = (%style_for_target,
                    356: 				      &Apache::style::styleparser($target,$styletext));
                    357: 	     }
                    358: 	 }
                    359:      }
1.449     albertel  360:  } elsif ($env{'construct.style'}
                    361: 	  && ($env{'request.state'} eq 'construct')) {
1.372     albertel  362:      my $location=&Apache::lonnet::filelocation('',$env{'construct.style'});
1.291     sakharuk  363:      my $styletext=&Apache::lonnet::getfile($location);
1.449     albertel  364:      if ($styletext ne '-1') {
                    365: 	 %style_for_target = (%style_for_target,
                    366: 			      &Apache::style::styleparser($target,$styletext));
                    367:      }
1.178     www       368:  }
1.255     sakharuk  369: #&printalltags();
1.16      albertel  370:  my @pars = ();
1.372     albertel  371:  my $pwd=$env{'request.filename'};
1.23      albertel  372:  $pwd =~ s:/[^/]*$::;
                    373:  &newparser(\@pars,\$content_file_string,$pwd);
1.24      sakharuk  374: 
1.3       sakharuk  375:  my $safeeval = new Safe;
1.40      albertel  376:  my $safehole = new Safe::Hole;
1.82      ng        377:  &init_safespace($target,$safeeval,$safehole,$safeinit);
1.3       sakharuk  378: #-------------------- Redefinition of the target in the case of compound target
                    379: 
                    380:  ($target, my @tenta) = split('&&',$target);
                    381: 
1.150     albertel  382:  my @stack = ();
1.3       sakharuk  383:  my @parstack = ();
1.358     albertel  384:  &initdepth();
                    385:  &init_alarm();
1.101     albertel  386:  my $finaloutput = &inner_xmlparse($target,\@stack,\@parstack,\@pars,
1.394     albertel  387: 				   $safeeval,\%style_for_target,1);
1.255     sakharuk  388: 
1.425     albertel  389:  if (@stack) {
1.482     bisitz    390:      &warning(&mt('At end of file some tags were still left unclosed:').
                    391: 	      ' <tt>&lt;'.join('&gt;</tt>, <tt>&lt;',reverse(@stack)).
1.425     albertel  392: 	      '&gt;</tt>');
                    393:  }
1.372     albertel  394:  if ($env{'request.uri'}) {
                    395:     &writeallows($env{'request.uri'});
1.125     www       396:  }
1.281     albertel  397:  &do_registered_ssi();
1.204     albertel  398:  if ($Apache::lonxml::counter_changed) { &store_counter() }
1.393     albertel  399: 
                    400:  &clean_safespace($safeeval);
                    401: 
1.448     albertel  402:  if (@script_var_displays) {
1.527     www       403:      my $scriptoutput = join('',@script_var_displays);
                    404:      $finaloutput=~s{(</body>\s*</html>)\s*$}{$scriptoutput$1}s;
1.448     albertel  405:      undef(@script_var_displays);
                    406:  }
1.469     albertel  407:  &init_state();
1.372     albertel  408:  if ($env{'form.return_only_error_and_warning_counts'}) {
1.473     www       409:      if ($env{'request.filename'}=~/\.(html|htm|xml)$/i) { 
                    410:         my $error=&verify_html($content_file_string);
                    411:         if ($error) { $errorcount++; }
                    412:      }
1.361     www       413:      return "$errorcount:$warningcount";
                    414:  }
1.3       sakharuk  415:  return $finaloutput;
1.106     www       416: }
                    417: 
1.191     albertel  418: sub latex_special_symbols {
1.272     albertel  419:     my ($string,$where)=@_;
1.396     foxr      420:     #
                    421:     #  If e.g. in verbatim mode, then don't substitute.
                    422:     #  but return original string.
                    423:     #
                    424:     if (!($Apache::lonxml::substitute_LaTeX_symbols)) {
                    425: 	return $string;
                    426:     }
1.235     sakharuk  427:     if ($where eq 'header') {
1.414     foxr      428: 	$string =~ s/\\/\$\\backslash\$/g; # \  -> $\backslash$ per LaTex line by line pg  10.
1.311     albertel  429: 	$string =~ s/(\$|%|\{|\})/\\$1/g;
                    430: 	$string=&Apache::lonprintout::character_chart($string);
                    431: 	# any & or # leftover should be safe to just escape
                    432:         $string=~s/([^\\])\&/$1\\\&/g;
                    433:         $string=~s/([^\\])\#/$1\\\#/g;
1.415     foxr      434: 	$string =~ s/_/\\_/g;              # _ -> \_
                    435: 	$string =~ s/\^/\\\^{}/g;          # ^ -> \^{} 
1.229     sakharuk  436:     } else {
1.312     albertel  437: 	$string=~s/\\/\\ensuremath{\\backslash}/g;
1.367     albertel  438: 	$string=~s/\\\%|\%/\\\%/g;
                    439: 	$string=~s/\\{|{/\\{/g;
                    440: 	$string=~s/\\}|}/\\}/g;
1.378     albertel  441: 	$string=~s/\\ensuremath\\{\\backslash\\}/\\ensuremath{\\backslash}/g;
1.367     albertel  442: 	$string=~s/\\\$|\$/\\\$/g;
                    443: 	$string=~s/\\\_|\_/\\\_/g;
1.313     albertel  444:         $string=~s/([^\\]|^)(\~|\^)/$1\\$2\\strut /g;
1.310     sakharuk  445: 	$string=~s/(>|<)/\\ensuremath\{$1\}/g; #more or less
1.311     albertel  446: 	$string=&Apache::lonprintout::character_chart($string);
                    447: 	# any & or # leftover should be safe to just escape
1.367     albertel  448: 	$string=~s/\\\&|\&/\\\&/g;
                    449: 	$string=~s/\\\#|\#/\\\#/g;
1.332     sakharuk  450:         $string=~s/\|/\$\\mid\$/g;
1.310     sakharuk  451: #single { or } How to escape?
1.229     sakharuk  452:     }
1.272     albertel  453:     return $string;
1.188     sakharuk  454: }
                    455: 
1.101     albertel  456: sub inner_xmlparse {
1.394     albertel  457:   my ($target,$stack,$parstack,$pars,$safeeval,$style_for_target,$start)=@_;
1.101     albertel  458:   my $finaloutput = '';
                    459:   my $result;
                    460:   my $token;
1.258     albertel  461:   my $dontpop=0;
1.389     albertel  462:   my $startredirection = $Apache::lonxml::redirection;
1.101     albertel  463:   while ( $#$pars > -1 ) {
                    464:     while ($token = $$pars['-1']->get_token) {
1.261     albertel  465:       if (($token->[0] eq 'T') || ($token->[0] eq 'C') ) {
1.101     albertel  466: 	if ($metamode<1) {
1.190     albertel  467: 	    my $text=$token->[1];
1.193     albertel  468: 	    if ($token->[0] eq 'C' && $target eq 'tex') {
1.239     sakharuk  469: 		$text = '';
                    470: #		$text = '%'.$text."\n";
1.182     sakharuk  471: 	    }
1.190     albertel  472: 	    $result.=$text;
1.101     albertel  473: 	}
1.261     albertel  474:       } elsif (($token->[0] eq 'D')) {
                    475: 	if ($metamode<1 && $target eq 'web') {
                    476: 	    my $text=$token->[1];
                    477: 	    $result.=$text;
                    478: 	}
1.101     albertel  479:       } elsif ($token->[0] eq 'PI') {
1.261     albertel  480: 	if ($metamode<1 && $target eq 'web') {
1.101     albertel  481: 	  $result=$token->[2];
                    482: 	}
                    483:       } elsif ($token->[0] eq 'S') {
1.140     albertel  484: 	# add tag to stack
1.101     albertel  485: 	push (@$stack,$token->[1]);
                    486: 	# add parameters list to another stack
                    487: 	push (@$parstack,&parstring($token));
1.140     albertel  488: 	&increasedepth($token);
1.212     albertel  489: 	if ($Apache::lonxml::usestyle &&
                    490: 	    exists($$style_for_target{$token->[1]})) {
                    491: 	    $Apache::lonxml::usestyle=0;
                    492: 	    my $string=$$style_for_target{$token->[1]}.
                    493: 	      '<LONCAPA_INTERNAL_TURN_STYLE_ON />';
                    494: 	    &Apache::lonxml::newparser($pars,\$string);
1.257     albertel  495: 	    $Apache::lonxml::style_values=$$parstack[-1];
1.259     albertel  496: 	    $Apache::lonxml::style_end_values=$$parstack[-1];
1.101     albertel  497: 	} else {
                    498: 	  $result = &callsub("start_$token->[1]", $target, $token, $stack,
                    499: 			     $parstack, $pars, $safeeval, $style_for_target);
1.140     albertel  500: 	}
1.101     albertel  501:       } elsif ($token->[0] eq 'E') {
1.212     albertel  502: 	if ($Apache::lonxml::usestyle &&
                    503: 	    exists($$style_for_target{'/'."$token->[1]"})) {
                    504: 	    $Apache::lonxml::usestyle=0;
                    505: 	    my $string=$$style_for_target{'/'.$token->[1]}.
1.258     albertel  506: 	      '<LONCAPA_INTERNAL_TURN_STYLE_ON end="'.$token->[1].'" />';
1.212     albertel  507: 	    &Apache::lonxml::newparser($pars,\$string);
1.259     albertel  508: 	    $Apache::lonxml::style_values=$Apache::lonxml::style_end_values;
                    509: 	    $Apache::lonxml::style_end_values='';
1.258     albertel  510: 	    $dontpop=1;
1.101     albertel  511: 	} else {
1.258     albertel  512: 	    #clear out any tags that didn't end
                    513: 	    while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) {
                    514: 		my $lasttag=$$stack[-1];
1.317     albertel  515: 		if ($token->[1] =~ /^\Q$lasttag\E$/i) {
1.483     bisitz    516: 		    &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;'));
1.258     albertel  517: 		    last;
                    518: 		} else {
1.483     bisitz    519:                     &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;'));
1.258     albertel  520: 		    &end_tag($stack,$parstack,$token);
                    521: 		}
                    522: 	    }
                    523: 	    $result = &callsub("end_$token->[1]", $target, $token, $stack,
                    524: 			       $parstack, $pars,$safeeval, $style_for_target);
1.101     albertel  525: 	}
                    526:       } else {
                    527: 	&Apache::lonxml::error("Unknown token event :$token->[0]:$token->[1]:");
                    528:       }
                    529:       #evaluate variable refs in result
1.282     albertel  530:       if ($Apache::lonxml::post_evaluate &&$result ne "") {
1.257     albertel  531: 	  my $extras;
                    532: 	  if (!$Apache::lonxml::usestyle) {
                    533: 	      $extras=$Apache::lonxml::style_values;
                    534: 	  }
1.488     raeburn   535: 	  if ( $#$parstack > -1 ) {
                    536: 	      $result=&Apache::run::evaluate($result,$safeeval,$extras.$$parstack[-1]);
                    537: 	  } else {
                    538: 	      $result= &Apache::run::evaluate($result,$safeeval,$extras);
1.487     raeburn   539:           }
1.163     albertel  540:       }
1.282     albertel  541:       $Apache::lonxml::post_evaluate=1;
                    542: 
1.190     albertel  543:       if (($token->[0] eq 'T') || ($token->[0] eq 'C') || ($token->[0] eq 'D') ) {
1.249     albertel  544: 	  #Style file definitions should be correct
1.250     albertel  545: 	  if ($target eq 'tex' && ($Apache::lonxml::usestyle)) {
1.311     albertel  546: 	      $result=&latex_special_symbols($result);
1.249     albertel  547: 	  }
1.190     albertel  548:       }
                    549: 
1.169     albertel  550:       if ($Apache::lonxml::redirection) {
                    551: 	$Apache::lonxml::outputstack['-1'] .= $result;
                    552:       } else {
                    553: 	$finaloutput.=$result;
                    554:       }
                    555:       $result = '';
                    556: 
1.258     albertel  557:       if ($token->[0] eq 'E' && !$dontpop) {
1.101     albertel  558: 	&end_tag($stack,$parstack,$token);
                    559:       }
1.258     albertel  560:       $dontpop=0;
1.224     albertel  561:     }	
1.212     albertel  562:     if ($#$pars > -1) {
                    563: 	pop @$pars;
                    564: 	pop @Apache::lonxml::pwd;
                    565:     }
1.101     albertel  566:   }
                    567: 
                    568:   # if ($target eq 'meta') {
                    569:   #   $finaloutput.=&endredirection;
                    570:   # }
                    571: 
1.394     albertel  572:   if ( $start && $target eq 'grade') { &endredirection(); }
1.389     albertel  573:   if ( $Apache::lonxml::redirection > $startredirection) {
                    574:       while ($Apache::lonxml::redirection > $startredirection) {
                    575: 	  $finaloutput .= &endredirection();
1.387     albertel  576:       }
                    577:   }
1.101     albertel  578:   if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {
                    579:     $finaloutput=&afterburn($finaloutput);
1.509     www       580:   }
                    581:   if ($target eq 'modified') {
                    582: # if modfied, handle startpart and endpart
                    583:      $finaloutput=~s/\<startpartmarker[^\>]*\>(.*)\<endpartmarker[^\>]*\>/<part>$1<\/part>/gs;
1.216     sakharuk  584:   }	    
1.101     albertel  585:   return $finaloutput;
                    586: }
1.67      www       587: 
1.318     matthew   588: ## 
                    589: ## Looks to see if there is a subroutine defined for this tag.  If so, call it,
                    590: ## otherwise do not call it as we do not know what it is.
                    591: ##
1.7       albertel  592: sub callsub {
1.84      albertel  593:   my ($sub,$target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.7       albertel  594:   my $currentstring='';
1.72      albertel  595:   my $nodefault;
1.7       albertel  596:   {
1.59      albertel  597:     my $sub1;
1.7       albertel  598:     no strict 'refs';
1.68      www       599:     my $tag=$token->[1];
1.236     www       600: # get utterly rid of extended html tags
                    601:     if ($tag=~/^x\-/i) { return ''; }
1.141     albertel  602:     my $space=$Apache::lonxml::alltags{$tag}[-1];
1.68      www       603:     if (!$space) {
1.141     albertel  604:      	$tag=~tr/A-Z/a-z/;
1.68      www       605: 	$sub=~tr/A-Z/a-z/;
1.141     albertel  606: 	$space=$Apache::lonxml::alltags{$tag}[-1]
1.68      www       607:     }
1.97      albertel  608: 
                    609:     my $deleted=0;
                    610:     if (($token->[0] eq 'S') && ($target eq 'modified')) {
                    611:       $deleted=&Apache::edit::handle_delete($space,$target,$token,$tagstack,
                    612: 					     $parstack,$parser,$safeeval,
                    613: 					     $style);
                    614:     }
                    615:     if (!$deleted) {
                    616:       if ($space) {
1.220     albertel  617: 	#&Apache::lonxml::debug("Calling sub $sub in $space $metamode");
1.97      albertel  618: 	$sub1="$space\:\:$sub";
                    619: 	($currentstring,$nodefault) = &$sub1($target,$token,$tagstack,
                    620: 					     $parstack,$parser,$safeeval,
                    621: 					     $style);
                    622:       } else {
1.318     matthew   623:           if ($target eq 'tex') {
                    624:               # throw away tag name
                    625:               return '';
                    626:           }
1.220     albertel  627: 	#&Apache::lonxml::debug("NOT Calling sub $sub in $space $metamode");
1.97      albertel  628: 	if ($metamode <1) {
                    629: 	  if (defined($token->[4]) && ($metamode < 1)) {
                    630: 	    $currentstring = $token->[4];
                    631: 	  } else {
                    632: 	    $currentstring = $token->[2];
                    633: 	  }
1.62      sakharuk  634: 	}
1.7       albertel  635:       }
1.97      albertel  636:       #    &Apache::lonxml::debug("nodefalt:$nodefault:");
                    637:       if ($currentstring eq '' && $nodefault eq '') {
                    638: 	if ($target eq 'edit') {
1.220     albertel  639: 	  #&Apache::lonxml::debug("doing default edit for $token->[1]");
1.97      albertel  640: 	  if ($token->[0] eq 'S') {
                    641: 	    $currentstring = &Apache::edit::tag_start($target,$token);
                    642: 	  } elsif ($token->[0] eq 'E') {
                    643: 	    $currentstring = &Apache::edit::tag_end($target,$token);
                    644: 	  }
1.441     albertel  645: 	}
                    646:       }
                    647:       if ($target eq 'modified' && $nodefault eq '') {
                    648: 	  if ($currentstring eq '') {
                    649: 	      if ($token->[0] eq 'S') {
                    650: 		  $currentstring = $token->[4];
                    651: 	      } elsif ($token->[0] eq 'E') {
                    652: 		  $currentstring = $token->[2];
                    653: 	      } else {
                    654: 		  $currentstring = $token->[2];
                    655: 	      }
                    656: 	  }
1.97      albertel  657: 	  if ($token->[0] eq 'S') {
1.447     albertel  658: 	      $currentstring.=&Apache::edit::handle_insert();
1.210     www       659: 	  } elsif ($token->[0] eq 'E') {
1.447     albertel  660: 	      $currentstring.=&Apache::edit::handle_insertafter($token->[1]);
1.97      albertel  661: 	  }
1.72      albertel  662:       }
1.7       albertel  663:     }
                    664:     use strict 'refs';
                    665:   }
                    666:   return $currentstring;
1.82      ng        667: }
                    668: 
1.465     albertel  669: {
                    670:     my %state;
                    671: 
                    672:     sub init_state {
                    673: 	undef(%state);
                    674:     }
                    675:     
                    676:     sub set_state {
                    677: 	my ($key,$value) = @_;
                    678: 	$state{$key} = $value;
                    679: 	return $value;
                    680:     }
                    681:     sub get_state {
                    682: 	my ($key) = @_;
                    683: 	return $state{$key};
                    684:     }
                    685: }
                    686: 
1.96      albertel  687: sub setup_globals {
1.172     albertel  688:   my ($request,$target)=@_;
                    689:   $Apache::lonxml::request=$request;
1.205     www       690:   $errorcount=0;
                    691:   $warningcount=0;
1.490     www       692:   $Apache::lonxml::internal_error=0;
1.207     albertel  693:   $Apache::lonxml::default_homework_loaded=0;
1.212     albertel  694:   $Apache::lonxml::usestyle=1;
1.204     albertel  695:   &init_counter();
1.462     foxr      696:   &clear_bubble_lines_for_part();
1.465     albertel  697:   &init_state();
1.469     albertel  698:   &set_state('target',$target);
1.101     albertel  699:   @Apache::lonxml::pwd=();
1.124     albertel  700:   @Apache::lonxml::extlinks=();
1.448     albertel  701:   @script_var_displays=();
1.281     albertel  702:   @Apache::lonxml::ssi_info=();
1.282     albertel  703:   $Apache::lonxml::post_evaluate=1;
1.295     albertel  704:   $Apache::lonxml::warnings_error_header='';
1.397     albertel  705:   $Apache::lonxml::substitute_LaTeX_symbols = 1;
1.96      albertel  706:   if ($target eq 'meta') {
                    707:     $Apache::lonxml::redirection = 0;
                    708:     $Apache::lonxml::metamode = 1;
                    709:     $Apache::lonxml::evaluate = 1;
                    710:     $Apache::lonxml::import = 0;
1.129     albertel  711:   } elsif ($target eq 'answer') {
                    712:     $Apache::lonxml::redirection = 0;
                    713:     $Apache::lonxml::metamode = 1;
                    714:     $Apache::lonxml::evaluate = 1;
                    715:     $Apache::lonxml::import = 1;
1.96      albertel  716:   } elsif ($target eq 'grade') {
1.387     albertel  717:     &startredirection(); #ended in inner_xmlparse on exit
1.96      albertel  718:     $Apache::lonxml::metamode = 0;
                    719:     $Apache::lonxml::evaluate = 1;
                    720:     $Apache::lonxml::import = 1;
                    721:   } elsif ($target eq 'modified') {
                    722:     $Apache::lonxml::redirection = 0;
                    723:     $Apache::lonxml::metamode = 0;
                    724:     $Apache::lonxml::evaluate = 0;
                    725:     $Apache::lonxml::import = 0;
                    726:   } elsif ($target eq 'edit') {
                    727:     $Apache::lonxml::redirection = 0;
                    728:     $Apache::lonxml::metamode = 0;
                    729:     $Apache::lonxml::evaluate = 0;
                    730:     $Apache::lonxml::import = 0;
1.163     albertel  731:   } elsif ($target eq 'analyze') {
                    732:     $Apache::lonxml::redirection = 0;
                    733:     $Apache::lonxml::metamode = 0;
                    734:     $Apache::lonxml::evaluate = 1;
                    735:     $Apache::lonxml::import = 1;
1.96      albertel  736:   } else {
                    737:     $Apache::lonxml::redirection = 0;
                    738:     $Apache::lonxml::metamode = 0;
                    739:     $Apache::lonxml::evaluate = 1;
                    740:     $Apache::lonxml::import = 1;
                    741:   }
                    742: }
                    743: 
1.82      ng        744: sub init_safespace {
                    745:   my ($target,$safeeval,$safehole,$safeinit) = @_;
1.511     foxr      746:   $safeeval->reval('use Math::Complex;');
                    747:   $safeeval->reval('use LaTeX::Table;');
1.393     albertel  748:   $safeeval->deny_only(':dangerous');
1.383     albertel  749:   $safeeval->permit_only(":default");
1.82      ng        750:   $safeeval->permit("entereval");
                    751:   $safeeval->permit(":base_math");
                    752:   $safeeval->permit("sort");
1.286     albertel  753:   $safeeval->permit("time");
1.480     www       754:   $safeeval->permit("caller");
1.371     albertel  755:   $safeeval->deny("rand");
                    756:   $safeeval->deny("srand");
1.82      ng        757:   $safeeval->deny(":base_io");
1.102     albertel  758:   $safehole->wrap(\&Apache::scripttag::xmlparse,$safeeval,'&xmlparse');
1.251     albertel  759:   $safehole->wrap(\&Apache::outputtags::multipart,$safeeval,'&multipart');
1.82      ng        760:   $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT');
1.324     albertel  761:   $safehole->wrap(\&Apache::chemresponse::chem_standard_order,$safeeval,
                    762: 		  '&chem_standard_order');
1.369     albertel  763:   $safehole->wrap(\&Apache::response::check_status,$safeeval,'&check_status');
1.471     bisitz    764:   $safehole->wrap(\&Apache::response::implicit_multiplication,$safeeval,'&implicit_multiplication');
1.324     albertel  765: 
1.431     www       766:   $safehole->wrap(\&Apache::lonmaxima::maxima_eval,$safeeval,'&maxima_eval');
1.432     www       767:   $safehole->wrap(\&Apache::lonmaxima::maxima_check,$safeeval,'&maxima_check');
1.433     albertel  768:   $safehole->wrap(\&Apache::lonmaxima::maxima_cas_formula_fix,$safeeval,
                    769: 		  '&maxima_cas_formula_fix');
                    770: 
1.494     www       771:   $safehole->wrap(\&Apache::lonr::r_eval,$safeeval,'&r_eval');
1.497     www       772:   $safehole->wrap(\&Apache::lonr::Rentry,$safeeval,'&Rentry');
                    773:   $safehole->wrap(\&Apache::lonr::Rarray,$safeeval,'&Rarray');
1.494     www       774:   $safehole->wrap(\&Apache::lonr::r_check,$safeeval,'&r_check');
                    775:   $safehole->wrap(\&Apache::lonr::r_cas_formula_fix,$safeeval,
                    776:                   '&r_cas_formula_fix');
                    777:  
1.433     albertel  778:   $safehole->wrap(\&Apache::caparesponse::capa_formula_fix,$safeeval,
                    779: 		  '&capa_formula_fix');
1.431     www       780: 
1.480     www       781:   $safehole->wrap(\&Apache::lonlocal::locallocaltime,$safeeval,
                    782:                   '&locallocaltime');
                    783: 
1.82      ng        784:   $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin');
                    785:   $safehole->wrap(\&Math::Cephes::acos,$safeeval,'&acos');
                    786:   $safehole->wrap(\&Math::Cephes::atan,$safeeval,'&atan');
                    787:   $safehole->wrap(\&Math::Cephes::sinh,$safeeval,'&sinh');
                    788:   $safehole->wrap(\&Math::Cephes::cosh,$safeeval,'&cosh');
                    789:   $safehole->wrap(\&Math::Cephes::tanh,$safeeval,'&tanh');
                    790:   $safehole->wrap(\&Math::Cephes::asinh,$safeeval,'&asinh');
                    791:   $safehole->wrap(\&Math::Cephes::acosh,$safeeval,'&acosh');
                    792:   $safehole->wrap(\&Math::Cephes::atanh,$safeeval,'&atanh');
                    793:   $safehole->wrap(\&Math::Cephes::erf,$safeeval,'&erf');
                    794:   $safehole->wrap(\&Math::Cephes::erfc,$safeeval,'&erfc');
                    795:   $safehole->wrap(\&Math::Cephes::j0,$safeeval,'&j0');
                    796:   $safehole->wrap(\&Math::Cephes::j1,$safeeval,'&j1');
                    797:   $safehole->wrap(\&Math::Cephes::jn,$safeeval,'&jn');
                    798:   $safehole->wrap(\&Math::Cephes::jv,$safeeval,'&jv');
                    799:   $safehole->wrap(\&Math::Cephes::y0,$safeeval,'&y0');
                    800:   $safehole->wrap(\&Math::Cephes::y1,$safeeval,'&y1');
                    801:   $safehole->wrap(\&Math::Cephes::yn,$safeeval,'&yn');
                    802:   $safehole->wrap(\&Math::Cephes::yv,$safeeval,'&yv');
1.215     albertel  803:   
                    804:   $safehole->wrap(\&Math::Cephes::bdtr  ,$safeeval,'&bdtr'  );
                    805:   $safehole->wrap(\&Math::Cephes::bdtrc ,$safeeval,'&bdtrc' );
                    806:   $safehole->wrap(\&Math::Cephes::bdtri ,$safeeval,'&bdtri' );
                    807:   $safehole->wrap(\&Math::Cephes::btdtr ,$safeeval,'&btdtr' );
                    808:   $safehole->wrap(\&Math::Cephes::chdtr ,$safeeval,'&chdtr' );
                    809:   $safehole->wrap(\&Math::Cephes::chdtrc,$safeeval,'&chdtrc');
                    810:   $safehole->wrap(\&Math::Cephes::chdtri,$safeeval,'&chdtri');
                    811:   $safehole->wrap(\&Math::Cephes::fdtr  ,$safeeval,'&fdtr'  );
                    812:   $safehole->wrap(\&Math::Cephes::fdtrc ,$safeeval,'&fdtrc' );
                    813:   $safehole->wrap(\&Math::Cephes::fdtri ,$safeeval,'&fdtri' );
                    814:   $safehole->wrap(\&Math::Cephes::gdtr  ,$safeeval,'&gdtr'  );
                    815:   $safehole->wrap(\&Math::Cephes::gdtrc ,$safeeval,'&gdtrc' );
                    816:   $safehole->wrap(\&Math::Cephes::nbdtr ,$safeeval,'&nbdtr' );
                    817:   $safehole->wrap(\&Math::Cephes::nbdtrc,$safeeval,'&nbdtrc');
                    818:   $safehole->wrap(\&Math::Cephes::nbdtri,$safeeval,'&nbdtri');
                    819:   $safehole->wrap(\&Math::Cephes::ndtr  ,$safeeval,'&ndtr'  );
                    820:   $safehole->wrap(\&Math::Cephes::ndtri ,$safeeval,'&ndtri' );
                    821:   $safehole->wrap(\&Math::Cephes::pdtr  ,$safeeval,'&pdtr'  );
                    822:   $safehole->wrap(\&Math::Cephes::pdtrc ,$safeeval,'&pdtrc' );
                    823:   $safehole->wrap(\&Math::Cephes::pdtri ,$safeeval,'&pdtri' );
                    824:   $safehole->wrap(\&Math::Cephes::stdtr ,$safeeval,'&stdtr' );
                    825:   $safehole->wrap(\&Math::Cephes::stdtri,$safeeval,'&stdtri');
                    826: 
1.383     albertel  827:   $safehole->wrap(\&Math::Cephes::Matrix::mat,$safeeval,'&mat');
                    828:   $safehole->wrap(\&Math::Cephes::Matrix::new,$safeeval,
                    829: 		  '&Math::Cephes::Matrix::new');
                    830:   $safehole->wrap(\&Math::Cephes::Matrix::coef,$safeeval,
                    831: 		  '&Math::Cephes::Matrix::coef');
                    832:   $safehole->wrap(\&Math::Cephes::Matrix::clr,$safeeval,
                    833: 		  '&Math::Cephes::Matrix::clr');
                    834:   $safehole->wrap(\&Math::Cephes::Matrix::add,$safeeval,
                    835: 		  '&Math::Cephes::Matrix::add');
                    836:   $safehole->wrap(\&Math::Cephes::Matrix::sub,$safeeval,
                    837: 		  '&Math::Cephes::Matrix::sub');
                    838:   $safehole->wrap(\&Math::Cephes::Matrix::mul,$safeeval,
                    839: 		  '&Math::Cephes::Matrix::mul');
                    840:   $safehole->wrap(\&Math::Cephes::Matrix::div,$safeeval,
                    841: 		  '&Math::Cephes::Matrix::div');
                    842:   $safehole->wrap(\&Math::Cephes::Matrix::inv,$safeeval,
                    843: 		  '&Math::Cephes::Matrix::inv');
                    844:   $safehole->wrap(\&Math::Cephes::Matrix::transp,$safeeval,
                    845: 		  '&Math::Cephes::Matrix::transp');
                    846:   $safehole->wrap(\&Math::Cephes::Matrix::simq,$safeeval,
                    847: 		  '&Math::Cephes::Matrix::simq');
                    848:   $safehole->wrap(\&Math::Cephes::Matrix::mat_to_vec,$safeeval,
                    849: 		  '&Math::Cephes::Matrix::mat_to_vec');
                    850:   $safehole->wrap(\&Math::Cephes::Matrix::vec_to_mat,$safeeval,
                    851: 		  '&Math::Cephes::Matrix::vec_to_mat');
                    852:   $safehole->wrap(\&Math::Cephes::Matrix::check,$safeeval,
                    853: 		  '&Math::Cephes::Matrix::check');
                    854:   $safehole->wrap(\&Math::Cephes::Matrix::check,$safeeval,
                    855: 		  '&Math::Cephes::Matrix::check');
                    856: 
1.215     albertel  857: #  $safehole->wrap(\&Math::Cephes::new_fract,$safeeval,'&new_fract');
                    858: #  $safehole->wrap(\&Math::Cephes::radd,$safeeval,'&radd');
                    859: #  $safehole->wrap(\&Math::Cephes::rsub,$safeeval,'&rsub');
                    860: #  $safehole->wrap(\&Math::Cephes::rmul,$safeeval,'&rmul');
                    861: #  $safehole->wrap(\&Math::Cephes::rdiv,$safeeval,'&rdiv');
                    862: #  $safehole->wrap(\&Math::Cephes::euclid,$safeeval,'&euclid');
                    863: 
1.91      ng        864:   $safehole->wrap(\&Math::Random::random_beta,$safeeval,'&math_random_beta');
                    865:   $safehole->wrap(\&Math::Random::random_chi_square,$safeeval,'&math_random_chi_square');
                    866:   $safehole->wrap(\&Math::Random::random_exponential,$safeeval,'&math_random_exponential');
                    867:   $safehole->wrap(\&Math::Random::random_f,$safeeval,'&math_random_f');
                    868:   $safehole->wrap(\&Math::Random::random_gamma,$safeeval,'&math_random_gamma');
                    869:   $safehole->wrap(\&Math::Random::random_multivariate_normal,$safeeval,'&math_random_multivariate_normal');
                    870:   $safehole->wrap(\&Math::Random::random_multinomial,$safeeval,'&math_random_multinomial');
                    871:   $safehole->wrap(\&Math::Random::random_noncentral_chi_square,$safeeval,'&math_random_noncentral_chi_square');
                    872:   $safehole->wrap(\&Math::Random::random_noncentral_f,$safeeval,'&math_random_noncentral_f');
                    873:   $safehole->wrap(\&Math::Random::random_normal,$safeeval,'&math_random_normal');
                    874:   $safehole->wrap(\&Math::Random::random_permutation,$safeeval,'&math_random_permutation');
1.93      ng        875:   $safehole->wrap(\&Math::Random::random_permuted_index,$safeeval,'&math_random_permuted_index');
1.91      ng        876:   $safehole->wrap(\&Math::Random::random_uniform,$safeeval,'&math_random_uniform');
                    877:   $safehole->wrap(\&Math::Random::random_poisson,$safeeval,'&math_random_poisson');
                    878:   $safehole->wrap(\&Math::Random::random_uniform_integer,$safeeval,'&math_random_uniform_integer');
                    879:   $safehole->wrap(\&Math::Random::random_negative_binomial,$safeeval,'&math_random_negative_binomial');
                    880:   $safehole->wrap(\&Math::Random::random_binomial,$safeeval,'&math_random_binomial');
                    881:   $safehole->wrap(\&Math::Random::random_seed_from_phrase,$safeeval,'&random_seed_from_phrase');
                    882:   $safehole->wrap(\&Math::Random::random_set_seed_from_phrase,$safeeval,'&random_set_seed_from_phrase');
                    883:   $safehole->wrap(\&Math::Random::random_get_seed,$safeeval,'&random_get_seed');
                    884:   $safehole->wrap(\&Math::Random::random_set_seed,$safeeval,'&random_set_seed');
1.458     albertel  885:   $safehole->wrap(\&Apache::loncommon::languages,$safeeval,'&languages');
1.305     albertel  886:   $safehole->wrap(\&Apache::lonxml::error,$safeeval,'&LONCAPA_INTERNAL_ERROR');
1.311     albertel  887:   $safehole->wrap(\&Apache::lonxml::debug,$safeeval,'&LONCAPA_INTERNAL_DEBUG');
1.420     albertel  888:   $safehole->wrap(\&Apache::lonnet::logthis,$safeeval,'&LONCAPA_INTERNAL_LOGTHIS');
                    889:   $safehole->wrap(\&Apache::inputtags::finalizeawards,$safeeval,'&LONCAPA_INTERNAL_FINALIZEAWARDS');
1.322     albertel  890:   $safehole->wrap(\&Apache::caparesponse::get_sigrange,$safeeval,'&LONCAPA_INTERNAL_get_sigrange');
1.521     www       891:   $safehole->wrap(\&Apache::functionplotresponse::fpr_val,$safeeval,'&fpr_val');
1.520     www       892:   $safehole->wrap(\&Apache::functionplotresponse::fpr_f,$safeeval,'&fpr_f');
                    893:   $safehole->wrap(\&Apache::functionplotresponse::fpr_dfdx,$safeeval,'&fpr_dfdx');
                    894:   $safehole->wrap(\&Apache::functionplotresponse::fpr_d2fdx2,$safeeval,'&fpr_d2fdx2');
1.524     www       895:   $safehole->wrap(\&Apache::functionplotresponse::fpr_vectorcoords,$safeeval,'&fpr_vectorcoords');
                    896:   $safehole->wrap(\&Apache::functionplotresponse::fpr_objectcoords,$safeeval,'&fpr_objectcoords');
                    897:   $safehole->wrap(\&Apache::functionplotresponse::fpr_vectorlength,$safeeval,'&fpr_vectorlength');
                    898:   $safehole->wrap(\&Apache::functionplotresponse::fpr_vectorangle,$safeeval,'&fpr_vectorangle');
1.520     www       899: 
1.430     albertel  900: #  use Data::Dumper;
                    901: #  $safehole->wrap(\&Data::Dumper::Dumper,$safeeval,'&LONCAPA_INTERNAL_Dumper');
1.82      ng        902: #need to inspect this class of ops
                    903: # $safeeval->deny(":base_orig");
1.331     albertel  904:   $safeeval->permit("require");
1.91      ng        905:   $safeinit .= ';$external::target="'.$target.'";';
1.82      ng        906:   &Apache::run::run($safeinit,$safeeval);
1.373     albertel  907:   &initialize_rndseed($safeeval);
                    908: }
1.303     albertel  909: 
1.393     albertel  910: sub clean_safespace {
                    911:     my ($safeeval) = @_;
                    912:     delete_package_recurse($safeeval->{Root});
                    913: }
                    914: 
                    915: sub delete_package_recurse {
                    916:      my ($package) = @_;
                    917:      my @subp;
                    918:      {
                    919: 	 no strict 'refs';
                    920: 	 while (my ($key,$val) = each(%{*{"$package\::"}})) {
                    921: 	     if (!defined($val)) { next; }
                    922: 	     local (*ENTRY) = $val;
                    923: 	     if (defined *ENTRY{HASH} && $key =~ /::$/ &&
                    924: 		 $key ne "main::" && $key ne "<none>::")
                    925: 	     {
                    926: 		 my ($p) = $package ne "main" ? "$package\::" : "";
                    927: 		 ($p .= $key) =~ s/::$//;
                    928: 		 push(@subp,$p);
                    929: 	     }
                    930: 	 }
                    931:      }
                    932:      foreach my $p (@subp) {
                    933: 	 delete_package_recurse($p);
                    934:      }
                    935:      Symbol::delete_package($package);
                    936: }
                    937: 
1.373     albertel  938: sub initialize_rndseed {
                    939:     my ($safeeval)=@_;
                    940:     my $rndseed;
1.423     albertel  941:     my ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser();
1.373     albertel  942:     $rndseed=&Apache::lonnet::rndseed($symb,$courseid,$domain,$name);
                    943:     my $safeinit = '$external::randomseed="'.$rndseed.'";';
                    944:     &Apache::lonxml::debug("Setting rndseed to $rndseed");
                    945:     &Apache::run::run($safeinit,$safeeval);
1.207     albertel  946: }
                    947: 
                    948: sub default_homework_load {
                    949:     my ($safeeval)=@_;
                    950:     &Apache::lonxml::debug('Loading default_homework');
1.522     raeburn   951:     my $default=&Apache::lonnet::getfile($Apache::lonnet::perlvar{'lonIncludes'}.
                    952:                                          '/default_homework.lcpm');
1.241     albertel  953:     if ($default eq -1) {
1.207     albertel  954: 	&Apache::lonxml::error("<b>Unable to find <i>default_homework.lcpm</i></b>");
                    955:     } else {
                    956: 	&Apache::run::run($default,$safeeval);
                    957: 	$Apache::lonxml::default_homework_loaded=1;
                    958:     }
1.17      albertel  959: }
                    960: 
1.358     albertel  961: {
                    962:     my $alarm_depth;
                    963:     sub init_alarm {
                    964: 	alarm(0);
                    965: 	$alarm_depth=0;
                    966:     }
                    967: 
                    968:     sub start_alarm {
                    969: 	if ($alarm_depth<1) {
                    970: 	    my $old=alarm($Apache::lonnet::perlvar{'lonScriptTimeout'});
                    971: 	    if ($old) {
                    972: 		&Apache::lonxml::error("Cancelled an alarm of $old, this shouldn't occur.");
                    973: 	    }
                    974: 	}
                    975: 	$alarm_depth++;
                    976:     }
                    977: 
                    978:     sub end_alarm {
                    979: 	$alarm_depth--;
                    980: 	if ($alarm_depth<1) { alarm(0); }
                    981:     }
                    982: }
1.328     albertel  983: my $metamode_was;
1.55      albertel  984: sub startredirection {
1.328     albertel  985:     if (!$Apache::lonxml::redirection) {
                    986: 	$metamode_was=$Apache::lonxml::metamode;
                    987:     }
                    988:     $Apache::lonxml::metamode=0;
                    989:     $Apache::lonxml::redirection++;
                    990:     push (@Apache::lonxml::outputstack, '');
1.55      albertel  991: }
                    992: 
                    993: sub endredirection {
1.328     albertel  994:     if (!$Apache::lonxml::redirection) {
1.380     www       995: 	&Apache::lonxml::error("Endredirection was called before a startredirection, perhaps you have unbalanced tags. Some debugging information:".join ":",caller);
1.328     albertel  996: 	return '';
                    997:     }
                    998:     $Apache::lonxml::redirection--;
                    999:     if (!$Apache::lonxml::redirection) {
                   1000: 	$Apache::lonxml::metamode=$metamode_was;
                   1001:     }
                   1002:     pop @Apache::lonxml::outputstack;
1.97      albertel 1003: }
1.459     albertel 1004: sub in_redirection {
                   1005:     return ($Apache::lonxml::redirection > 0)
                   1006: }
1.97      albertel 1007: 
                   1008: sub end_tag {
                   1009:   my ($tagstack,$parstack,$token)=@_;
                   1010:   pop(@$tagstack);
                   1011:   pop(@$parstack);
                   1012:   &decreasedepth($token);
1.55      albertel 1013: }
                   1014: 
1.17      albertel 1015: sub initdepth {
                   1016:   @Apache::lonxml::depthcounter=();
1.439     albertel 1017:   undef($Apache::lonxml::last_depth_count);
1.17      albertel 1018: }
                   1019: 
1.438     albertel 1020: 
1.339     albertel 1021: my @timers;
                   1022: my $lasttime;
1.438     albertel 1023: # @Apache::lonxml::depthcounter -> count of tags that exist so
                   1024: #                                  far at each level
1.439     albertel 1025: # $Apache::lonxml::last_depth_count -> when ascending, need to
                   1026: # remember the count for the level below the current level (for
                   1027: # example going from 1_2 -> 1 -> 1_3 need to remember the 2 )
1.438     albertel 1028: 
1.17      albertel 1029: sub increasedepth {
1.19      albertel 1030:   my ($token) = @_;
1.439     albertel 1031:   push(@Apache::lonxml::depthcounter,$Apache::lonxml::last_depth_count+1);
                   1032:   undef($Apache::lonxml::last_depth_count);
1.340     albertel 1033:   my $time;
                   1034:   if ($Apache::lonxml::debug eq "1") {
                   1035:       push(@timers,[&gettimeofday()]);
                   1036:       $time=&tv_interval($lasttime);
                   1037:       $lasttime=[&gettimeofday()];
                   1038:   }
1.439     albertel 1039:   my $spacing='  'x($#Apache::lonxml::depthcounter);
1.438     albertel 1040:   $Apache::lonxml::curdepth=join('_',@Apache::lonxml::depthcounter);
1.439     albertel 1041: #  &Apache::lonxml::debug("s$spacing$Apache::lonxml::depth : $Apache::lonxml::olddepth : $Apache::lonxml::curdepth : $token->[1] : $time");
1.54      albertel 1042: #print "<br />s $Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1]\n";
1.17      albertel 1043: }
                   1044: 
                   1045: sub decreasedepth {
1.19      albertel 1046:   my ($token) = @_;
1.439     albertel 1047:   if (  $#Apache::lonxml::depthcounter == -1) {
                   1048:       &Apache::lonxml::warning(&mt("Missing tags, unable to properly run file."));
1.43      albertel 1049:   }
1.439     albertel 1050:   $Apache::lonxml::last_depth_count = pop(@Apache::lonxml::depthcounter);
                   1051: 
1.340     albertel 1052:   my ($timer,$time);
                   1053:   if ($Apache::lonxml::debug eq "1") {
                   1054:       $timer=pop(@timers);
                   1055:       $time=&tv_interval($lasttime);
                   1056:       $lasttime=[&gettimeofday()];
                   1057:   }
1.439     albertel 1058:   my $spacing='  'x($#Apache::lonxml::depthcounter);
                   1059:   $Apache::lonxml::curdepth = join('_',@Apache::lonxml::depthcounter);
                   1060: #  &Apache::lonxml::debug("e$spacing$Apache::lonxml::depth : $Apache::lonxml::olddepth : $Apache::lonxml::curdepth : $token->[1] : $time : ".&tv_interval($timer));
1.54      albertel 1061: #print "<br />e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n";
1.1       sakharuk 1062: }
1.19      albertel 1063: 
1.399     albertel 1064: sub get_id {
                   1065:     my ($parstack,$safeeval)=@_;
                   1066:     my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval);
1.449     albertel 1067:     if ($env{'request.state'} eq 'construct' && $id =~ /([._]|[^\w\d\s[:punct:]])/) {
1.498     bisitz   1068: 	&error(&mt('ID [_1] contains invalid characters. IDs are only allowed to contain letters, numbers, spaces and -','"<tt>'.$id.'</tt>"'));
1.399     albertel 1069:     }
                   1070:     if ($id =~ /^\s*$/) { $id = $Apache::lonxml::curdepth; }
                   1071:     return $id;
                   1072: }
                   1073: 
1.180     albertel 1074: sub get_all_text_unbalanced {
1.190     albertel 1075: #there is a copy of this in lonpublisher.pm
1.326     albertel 1076:     my($tag,$pars)= @_;
                   1077:     my $token;
                   1078:     my $result='';
                   1079:     $tag='<'.$tag.'>';
                   1080:     while ($token = $$pars[-1]->get_token) {
                   1081: 	if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
1.386     albertel 1082: 	    if ($token->[0] eq 'T' && $token->[2]) {
1.382     albertel 1083: 		$result.='<![CDATA['.$token->[1].']]>';
                   1084: 	    } else {
                   1085: 		$result.=$token->[1];
                   1086: 	    }
1.326     albertel 1087: 	} elsif ($token->[0] eq 'PI') {
                   1088: 	    $result.=$token->[2];
                   1089: 	} elsif ($token->[0] eq 'S') {
                   1090: 	    $result.=$token->[4];
                   1091: 	} elsif ($token->[0] eq 'E')  {
                   1092: 	    $result.=$token->[2];
                   1093: 	}
                   1094: 	if ($result =~ /\Q$tag\E/is) {
                   1095: 	    ($result,my $redo)=$result =~ /(.*)\Q$tag\E(.*)/is;
                   1096: 	    #&Apache::lonxml::debug('Got a winner with leftovers ::'.$2);
                   1097: 	    #&Apache::lonxml::debug('Result is :'.$1);
                   1098: 	    $redo=$tag.$redo;
                   1099: 	    &Apache::lonxml::newparser($pars,\$redo);
                   1100: 	    last;
                   1101: 	}
                   1102:     }
                   1103:     return $result
1.462     foxr     1104: 
1.204     albertel 1105: }
                   1106: 
1.462     foxr     1107: #########################################################################
                   1108: #                                                                       #
                   1109: #           bubble line counter management                              #
                   1110: #                                                                       #
                   1111: #########################################################################
                   1112: 
1.447     albertel 1113: =pod
                   1114: 
                   1115: For bubble grading mode and exam bubble printing mode, the tracking of
                   1116: the current 'bubble line number' is stored in the %env element
                   1117: 'form.counter', and is modifed and handled by the following routines.
                   1118: 
                   1119: The value of it is stored in $Apache:lonxml::counter when live and
                   1120: stored back to env after done.
                   1121: 
1.522     raeburn  1122: =item &increment_counter($increment, $part_response);
1.447     albertel 1123: 
                   1124: Increments the internal counter environment variable a specified amount
                   1125: 
                   1126: Optional Arguments:
                   1127:   $increment - amount to increment by (defaults to 1)
1.462     foxr     1128:                Also 1 if the value is negative or zero.
1.467     foxr     1129:   $part_response - A concatenation of the part and response id
                   1130:                    identifying exactly what is being 'answered'.
                   1131: 
1.447     albertel 1132: 
                   1133: =cut
                   1134: 
1.204     albertel 1135: sub increment_counter {
1.467     foxr     1136:     my ($increment, $part_response) = @_;
1.481     raeburn  1137:     if ($env{'form.grade_noincrement'}) { return; }
1.462     foxr     1138:     if (!defined($increment) || $increment le 0) {
                   1139: 	$increment = 1;
                   1140:     }
                   1141:     $Apache::lonxml::counter += $increment;
                   1142: 
1.466     foxr     1143:     # If the caller supplied the response_id parameter, 
1.462     foxr     1144:     # Maintain its counter.. creating if necessary.
                   1145: 
1.470     albertel 1146:     if (defined($part_response)) {
1.467     foxr     1147: 	if (!defined($Apache::lonxml::counters_per_part{$part_response})) {
                   1148: 	    $Apache::lonxml::counters_per_part{$part_response} = 0;
1.462     foxr     1149: 	}
1.467     foxr     1150: 	$Apache::lonxml::counters_per_part{$part_response} += $increment;
                   1151: 	my $new_value = $Apache::lonxml::counters_per_part{$part_response};
1.247     albertel 1152:     }
1.462     foxr     1153: 	
1.289     sakharuk 1154:     $Apache::lonxml::counter_changed=1;
1.204     albertel 1155: }
                   1156: 
1.447     albertel 1157: =pod
                   1158: 
1.461     foxr     1159: =item &init_counter($increment);
1.447     albertel 1160: 
                   1161: Initialize the internal counter environment variable
                   1162: 
                   1163: =cut
                   1164: 
1.204     albertel 1165: sub init_counter {
1.391     albertel 1166:     if ($env{'request.state'} eq 'construct') {
                   1167: 	$Apache::lonxml::counter=1;
                   1168: 	$Apache::lonxml::counter_changed=1;
                   1169:     } elsif (defined($env{'form.counter'})) {
1.372     albertel 1170: 	$Apache::lonxml::counter=$env{'form.counter'};
1.247     albertel 1171: 	$Apache::lonxml::counter_changed=0;
1.237     sakharuk 1172:     } else {
1.204     albertel 1173: 	$Apache::lonxml::counter=1;
1.247     albertel 1174: 	$Apache::lonxml::counter_changed=1;
1.204     albertel 1175:     }
                   1176: }
                   1177: 
                   1178: sub store_counter {
1.474     raeburn  1179:     &Apache::lonnet::appenv({'form.counter' => $Apache::lonxml::counter});
1.401     albertel 1180:     $Apache::lonxml::counter_changed=0;
1.204     albertel 1181:     return '';
1.180     albertel 1182: }
                   1183: 
1.398     albertel 1184: {
                   1185:     my $state;
                   1186:     sub clear_problem_counter {
                   1187: 	undef($state);
                   1188: 	&Apache::lonnet::delenv('form.counter');
                   1189: 	&Apache::lonxml::init_counter();
                   1190: 	&Apache::lonxml::store_counter();
                   1191:     }
                   1192: 
                   1193:     sub remember_problem_counter {
1.422     albertel 1194: 	&Apache::lonnet::transfer_profile_to_env(undef,undef,1);
1.398     albertel 1195: 	$state = $env{'form.counter'};
                   1196:     }
                   1197: 
                   1198:     sub restore_problem_counter {
                   1199: 	if (defined($state)) {
1.474     raeburn  1200: 	    &Apache::lonnet::appenv({'form.counter' => $state});
1.398     albertel 1201: 	}
                   1202:     }
1.401     albertel 1203:     sub get_problem_counter {
                   1204: 	if ($Apache::lonxml::counter_changed) { &store_counter() }
1.422     albertel 1205: 	&Apache::lonnet::transfer_profile_to_env(undef,undef,1);
1.401     albertel 1206: 	return $env{'form.counter'};
                   1207:     }
1.398     albertel 1208: }
                   1209: 
1.462     foxr     1210: =pod
                   1211: 
1.468     albertel 1212: =item  bubble_lines_for_part(part_response)
1.462     foxr     1213: 
                   1214: Returns the number of lines required to get a response for
1.467     foxr     1215: $part_response (this is just $Apache::lonxml::counters_per_part{$part_response}
1.462     foxr     1216: 
                   1217: =cut
                   1218: 
                   1219: sub bubble_lines_for_part {
1.467     foxr     1220:     my ($part_response) = @_;
1.462     foxr     1221: 
1.467     foxr     1222:     if (!defined($Apache::lonxml::counters_per_part{$part_response})) {
1.462     foxr     1223: 	return 0;
                   1224:     } else {
1.467     foxr     1225: 	return $Apache::lonxml::counters_per_part{$part_response};
1.462     foxr     1226:     }
                   1227: }
                   1228: 
                   1229: =pod
                   1230: 
                   1231: =item clear_bubble_lines_for_part
                   1232: 
                   1233: Clears the hash of bubble lines per part.  If a caller
                   1234: needs to analyze several resources this should be called between
                   1235: resources to reset the hash for each problem being analyzed.
                   1236: 
                   1237: =cut
                   1238: 
                   1239: sub clear_bubble_lines_for_part {
                   1240:     undef(%Apache::lonxml::counters_per_part);
                   1241: }
                   1242: 
                   1243: =pod
                   1244: 
1.468     albertel 1245: =item set_bubble_lines(part_response, value)
1.462     foxr     1246: 
                   1247: If there is a problem part, that for whatever reason
                   1248: requires bubble lines that are not
                   1249: the same as the counter increment, it can call this sub during
                   1250: analysis to set its hash value explicitly.
                   1251: 
                   1252: =cut
                   1253: 
                   1254: sub set_bubble_lines {
1.467     foxr     1255:     my ($part_response, $value) = @_;
1.462     foxr     1256: 
1.467     foxr     1257:     $Apache::lonxml::counters_per_part{$part_response} = $value;
1.462     foxr     1258: }
                   1259: 
                   1260: =pod
                   1261: 
                   1262: =item get_bubble_line_hash
                   1263: 
                   1264: Returns the current bubble line hash.  This is assumed to 
                   1265: be small so we return a copy
                   1266: 
                   1267: 
                   1268: =cut
                   1269: 
                   1270: sub get_bubble_line_hash {
                   1271:     return %Apache::lonxml::counters_per_part;
                   1272: }
                   1273: 
                   1274: 
                   1275: #--------------------------------------------------
                   1276: 
1.19      albertel 1277: sub get_all_text {
1.270     albertel 1278:     my($tag,$pars,$style)= @_;
                   1279:     my $gotfullstack=1;
                   1280:     if (ref($pars) ne 'ARRAY') {
                   1281: 	$gotfullstack=0;
                   1282: 	$pars=[$pars];
                   1283:     }
                   1284:     if (ref($style) ne 'HASH') {
                   1285: 	$style={};
                   1286:     }
                   1287:     my $depth=0;
                   1288:     my $token;
                   1289:     my $result='';
                   1290:     if ( $tag =~ m:^/: ) { 
                   1291: 	my $tag=substr($tag,1); 
                   1292: 	#&Apache::lonxml::debug("have:$tag:");
                   1293: 	my $top_empty=0;
                   1294: 	while (($depth >=0) && ($#$pars > -1) && (!$top_empty)) {
                   1295: 	    while (($depth >=0) && ($token = $$pars[-1]->get_token)) {
                   1296: 		#&Apache::lonxml::debug("e token:$token->[0]:$depth:$token->[1]:".$#$pars.":".$#Apache::lonxml::pwd);
                   1297: 		if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
1.382     albertel 1298: 		    if ($token->[2]) {
                   1299: 			$result.='<![CDATA['.$token->[1].']]>';
                   1300: 		    } else {
                   1301: 			$result.=$token->[1];
                   1302: 		    }
1.270     albertel 1303: 		} elsif ($token->[0] eq 'PI') {
                   1304: 		    $result.=$token->[2];
                   1305: 		} elsif ($token->[0] eq 'S') {
1.316     albertel 1306: 		    if ($token->[1] =~ /^\Q$tag\E$/i) { $depth++; }
                   1307: 		    if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_ON$/) { $Apache::lonxml::usestyle=1; }
                   1308: 		    if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_OFF$/) { $Apache::lonxml::usestyle=0; }
1.270     albertel 1309: 		    $result.=$token->[4];
                   1310: 		} elsif ($token->[0] eq 'E')  {
1.316     albertel 1311: 		    if ( $token->[1] =~ /^\Q$tag\E$/i) { $depth--; }
1.270     albertel 1312: 		    #skip sending back the last end tag
1.283     albertel 1313: 		    if ($depth == 0 && exists($$style{'/'.$token->[1]}) && $Apache::lonxml::usestyle) {
1.270     albertel 1314: 			my $string=
                   1315: 			    '<LONCAPA_INTERNAL_TURN_STYLE_OFF end="yes" />'.
                   1316: 				$$style{'/'.$token->[1]}.
                   1317: 				    $token->[2].
                   1318: 					'<LONCAPA_INTERNAL_TURN_STYLE_ON />';
                   1319: 			&Apache::lonxml::newparser($pars,\$string);
                   1320: 			#&Apache::lonxml::debug("reParsing $string");
                   1321: 			next;
                   1322: 		    }
                   1323: 		    if ($depth > -1) {
                   1324: 			$result.=$token->[2];
                   1325: 		    } else {
                   1326: 			$$pars[-1]->unget_token($token);
                   1327: 		    }
                   1328: 		}
                   1329: 	    }
                   1330: 	    if (($depth >=0) && ($#$pars == 0) ) { $top_empty=1; }
                   1331: 	    if (($depth >=0) && ($#$pars > 0) ) {
                   1332: 		pop(@$pars);
                   1333: 		pop(@Apache::lonxml::pwd);
                   1334: 	    }
                   1335: 	}
                   1336: 	if ($top_empty && $depth >= 0) {
                   1337: 	    #never found the end tag ran out of text, throw error send back blank
                   1338: 	    &error('Never found end tag for &lt;'.$tag.
                   1339: 		   '&gt; current string <pre>'.
1.314     albertel 1340: 		   &HTML::Entities::encode($result,'<>&"').
1.270     albertel 1341: 		   '</pre>');
                   1342: 	    if ($gotfullstack) {
                   1343: 		my $newstring='</'.$tag.'>'.$result;
                   1344: 		&Apache::lonxml::newparser($pars,\$newstring);
                   1345: 	    }
                   1346: 	    $result='';
                   1347: 	}
                   1348:     } else {
                   1349: 	while ($#$pars > -1) {
                   1350: 	    while ($token = $$pars[-1]->get_token) {
                   1351: 		#&Apache::lonxml::debug("s token:$token->[0]:$depth:$token->[1]");
                   1352: 		if (($token->[0] eq 'T')||($token->[0] eq 'C')||
                   1353: 		    ($token->[0] eq 'D')) {
1.382     albertel 1354: 		    if ($token->[2]) {
                   1355: 			$result.='<![CDATA['.$token->[1].']]>';
                   1356: 		    } else {
                   1357: 			$result.=$token->[1];
                   1358: 		    }
1.270     albertel 1359: 		} elsif ($token->[0] eq 'PI') {
                   1360: 		    $result.=$token->[2];
                   1361: 		} elsif ($token->[0] eq 'S') {
1.316     albertel 1362: 		    if ( $token->[1] =~ /^\Q$tag\E$/i) {
1.270     albertel 1363: 			$$pars[-1]->unget_token($token); last;
                   1364: 		    } else {
                   1365: 			$result.=$token->[4];
                   1366: 		    }
1.316     albertel 1367: 		    if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_ON$/) { $Apache::lonxml::usestyle=1; }
                   1368: 		    if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_OFF$/) { $Apache::lonxml::usestyle=0; }
1.270     albertel 1369: 		} elsif ($token->[0] eq 'E')  {
                   1370: 		    $result.=$token->[2];
                   1371: 		}
                   1372: 	    }
                   1373: 	    if (($#$pars > 0) ) {
                   1374: 		pop(@$pars);
                   1375: 		pop(@Apache::lonxml::pwd);
                   1376: 	    } else { last; }
                   1377: 	}
                   1378:     }
                   1379:     #&Apache::lonxml::debug("Exit:$result:");
                   1380:     return $result
1.19      albertel 1381: }
                   1382: 
1.23      albertel 1383: sub newparser {
                   1384:   my ($parser,$contentref,$dir) = @_;
1.167     albertel 1385:   push (@$parser,HTML::LCParser->new($contentref));
1.365     albertel 1386:   $$parser[-1]->xml_mode(1);
                   1387:   $$parser[-1]->marked_sections(1);
1.23      albertel 1388:   if ( $dir eq '' ) {
                   1389:     push (@Apache::lonxml::pwd, $Apache::lonxml::pwd[$#Apache::lonxml::pwd]);
                   1390:   } else {
                   1391:     push (@Apache::lonxml::pwd, $dir);
                   1392:   } 
                   1393: }
1.1       sakharuk 1394: 
1.8       albertel 1395: sub parstring {
1.417     albertel 1396:     my ($token) = @_;
                   1397:     my (@vars,@values);
                   1398:     foreach my $attr (@{$token->[3]}) {
                   1399: 	if ($attr!~/\W/) {
                   1400: 	    my $val=$token->[2]->{$attr};
                   1401: 	    $val =~ s/([\%\@\\\"\'])/\\$1/g;
                   1402: 	    $val =~ s/(\$[^\{a-zA-Z_])/\\$1/g;
                   1403: 	    $val =~ s/(\$)$/\\$1/;
                   1404: 	    #if ($val =~ m/^[\%\@]/) { $val="\\".$val; }
                   1405: 	    push(@vars,"\$$attr");
                   1406: 	    push(@values,"\"$val\"");
                   1407: 	}
                   1408:     }
                   1409:     my $var_init = 
                   1410: 	(@vars) ? 'my ('.join(',',@vars).') = ('.join(',',@values).');'
                   1411: 	        : '';
                   1412:     return $var_init;
1.8       albertel 1413: }
1.22      albertel 1414: 
1.384     albertel 1415: sub extlink {
                   1416:     my ($res,$exact)=@_;
                   1417:     if (!$exact) {
                   1418: 	$res=&Apache::lonnet::hreflocation($Apache::lonxml::pwd[-1],$res);
                   1419:     }
                   1420:     push(@Apache::lonxml::extlinks,$res)	 
                   1421: }
                   1422: 
1.34      www      1423: sub writeallows {
1.126     www      1424:     unless ($#extlinks>=0) { return; }
1.377     albertel 1425:     my $thisurl = &Apache::lonnet::clutter(shift);
1.372     albertel 1426:     if ($env{'httpref.'.$thisurl}) {
                   1427: 	$thisurl=$env{'httpref.'.$thisurl};
1.111     www      1428:     }
1.34      www      1429:     my $thisdir=$thisurl;
                   1430:     $thisdir=~s/\/[^\/]+$//;
                   1431:     my %httpref=();
1.142     albertel 1432:     foreach (@extlinks) {
1.34      www      1433:        $httpref{'httpref.'.
1.444     albertel 1434:  	        &Apache::lonnet::hreflocation($thisdir,&unescape($_))}=$thisurl;
1.142     albertel 1435:     }
1.126     www      1436:     @extlinks=();
1.474     raeburn  1437:     &Apache::lonnet::appenv(\%httpref);
1.34      www      1438: }
                   1439: 
1.281     albertel 1440: sub register_ssi {
                   1441:     my ($url,%form)=@_;
                   1442:     push (@Apache::lonxml::ssi_info,{'url'=>$url,'form'=>\%form});
                   1443:     return '';
                   1444: }
                   1445: 
                   1446: sub do_registered_ssi {
                   1447:     foreach my $info (@Apache::lonxml::ssi_info) {
                   1448: 	my %form=%{ $info->{'form'}};
                   1449: 	my $url=$info->{'url'};
                   1450: 	&Apache::lonnet::ssi($url,%form);
                   1451:     }
                   1452: }
1.448     albertel 1453: 
                   1454: sub add_script_result {
                   1455:     my ($display) = @_;
                   1456:     push(@script_var_displays, $display);
                   1457: }
                   1458: 
1.66      www      1459: #
                   1460: # Afterburner handles anchors, highlights and links
                   1461: #
                   1462: sub afterburn {
                   1463:     my $result=shift;
1.154     albertel 1464:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1465: 					    ['highlight','anchor','link']);
1.372     albertel 1466:     if ($env{'form.highlight'}) {
                   1467:        foreach (split(/\,/,$env{'form.highlight'})) {
1.66      www      1468:            my $anchorname=$_;
                   1469: 	   my $matchthis=$anchorname;
                   1470:            $matchthis=~s/\_+/\\s\+/g;
1.317     albertel 1471:            $result=~s/(\Q$matchthis\E)/\<font color=\"red\"\>$1\<\/font\>/gs;
1.142     albertel 1472:        }
1.66      www      1473:     }
1.372     albertel 1474:     if ($env{'form.link'}) {
                   1475:        foreach (split(/\,/,$env{'form.link'})) {
1.66      www      1476:            my ($anchorname,$linkurl)=split(/\>/,$_);
                   1477: 	   my $matchthis=$anchorname;
                   1478:            $matchthis=~s/\_+/\\s\+/g;
1.317     albertel 1479:            $result=~s/(\Q$matchthis\E)/\<a href=\"$linkurl\"\>$1\<\/a\>/gs;
1.142     albertel 1480:        }
1.66      www      1481:     }
1.372     albertel 1482:     if ($env{'form.anchor'}) {
                   1483:         my $anchorname=$env{'form.anchor'};
1.66      www      1484: 	my $matchthis=$anchorname;
                   1485:         $matchthis=~s/\_+/\\s\+/g;
1.317     albertel 1486:         $result=~s/(\Q$matchthis\E)/\<a name=\"$anchorname\"\>$1\<\/a\>/s;
1.66      www      1487:         $result.=(<<"ENDSCRIPT");
1.226     albertel 1488: <script type="text/javascript">
1.66      www      1489:     document.location.hash='$anchorname';
                   1490: </script>
                   1491: ENDSCRIPT
                   1492:     }
                   1493:     return $result;
                   1494: }
                   1495: 
1.79      www      1496: sub storefile {
                   1497:     my ($file,$contents)=@_;
1.290     albertel 1498:     &Apache::lonnet::correct_line_ends(\$contents);
1.79      www      1499:     if (my $fh=Apache::File->new('>'.$file)) {
                   1500: 	print $fh $contents;
                   1501:         $fh->close();
1.271     www      1502:         return 1;
1.147     albertel 1503:     } else {
1.482     bisitz   1504: 	&warning(&mt('Unable to save file [_1]','<tt>'.$file.'</tt>'));
1.271     www      1505: 	return 0;
1.79      www      1506:     }
                   1507: }
                   1508: 
1.151     albertel 1509: sub createnewhtml {
1.321     www      1510:     my $title=&mt('Title of document goes here');
                   1511:     my $body=&mt('Body of document goes here');
                   1512:     my $filecontents=(<<SIMPLECONTENT);
1.78      www      1513: <html>
                   1514: <head>
1.321     www      1515: <title>$title</title>
1.78      www      1516: </head>
                   1517: <body bgcolor="#FFFFFF">
1.321     www      1518: $body
1.78      www      1519: </body>
                   1520: </html>
                   1521: SIMPLECONTENT
1.321     www      1522:     return $filecontents;
1.151     albertel 1523: }
                   1524: 
1.274     albertel 1525: sub createnewsty {
                   1526:   my $filecontents=(<<SIMPLECONTENT);
                   1527: <definetag name="">
                   1528:     <render>
                   1529:        <web></web>
                   1530:        <tex></tex>
                   1531:     </render>
                   1532: </definetag>
                   1533: SIMPLECONTENT
                   1534:   return $filecontents;
                   1535: }
                   1536: 
1.493     raeburn  1537: sub createnewjs {
                   1538:     my $filecontents=(<<SIMPLECONTENT);
                   1539: <script type="text/javascript" language="Javascript">
                   1540: 
                   1541: </script>
                   1542: SIMPLECONTENT
                   1543:     return $filecontents;
                   1544: }
                   1545: 
1.472     www      1546: sub verify_html {
                   1547:     my ($filecontents)=@_;
1.516     raeburn  1548:     my ($is_html,$is_xml);
                   1549:     if ($filecontents =~/(?:\<|\&lt\;)\?xml[^\<]*\?(?:\>|\&gt\;)/is) {
                   1550:         $is_xml = 1;
1.518     raeburn  1551:     } elsif ($filecontents =~/(?:\<|\&lt\;)html(?:\s+[^\<]+|\s*)(?:\>|\&gt\;)/is) {
1.516     raeburn  1552:         $is_html = 1;
                   1553:     }
                   1554:     unless ($is_xml || $is_html) {
                   1555:         return &mt('File does not have [_1] or [_2] starting tag','&lt;html&gt;','&lt;?xml ?&gt;');
                   1556:     }
                   1557:     if ($is_html) {
                   1558:         if ($filecontents!~/(?:\<|\&lt\;)\/html(?:\>|\&gt\;)/is) {
                   1559:             return &mt('File does not have [_1] ending tag','&lt;html&gt;');
                   1560:         }
                   1561:         if ($filecontents!~/(?:\<|\&lt\;)(?:body|frameset)[^\<]*(?:\>|\&gt\;)/is) {
                   1562:             return &mt('File does not have [_1] or [_2] starting tag','&lt;body&gt;','&lt;frameset&gt;');
                   1563:         }
                   1564:         if ($filecontents!~/(?:\<|\&lt\;)\/(?:body|frameset)[^\<]*(?:\>|\&gt\;)/is) {
                   1565:             return &mt('File does not have [_1] or [_2] ending tag','&lt;body&gt;','&lt;frameset&gt;');
                   1566:         }
1.472     www      1567:     }
                   1568:     return '';
                   1569: }
1.147     albertel 1570: 
1.478     www      1571: sub renderingoptions {
                   1572:     my %langchoices=('' => '');
                   1573:     foreach (&Apache::loncommon::languageids()) {
                   1574:         if (&Apache::loncommon::supportedlanguagecode($_)) {
                   1575:             $langchoices{&Apache::loncommon::supportedlanguagecode($_)}
                   1576:                        = &Apache::loncommon::plainlanguagedescription($_);
                   1577:         }
                   1578:     }
1.500     raeburn  1579:     my $output;
                   1580:     unless ($env{'form.forceedit'}) {
1.504     bisitz   1581:        $output .=
                   1582:            '<span class="LC_nobreak">'.
1.500     raeburn  1583:            &mt('Language:').' '.
1.504     bisitz   1584:            &Apache::loncommon::select_form(
                   1585:                $env{'form.languages'},
                   1586:                'languages',
1.510     raeburn  1587:                {&Apache::lonlocal::texthash(%langchoices)}).
1.504     bisitz   1588:            '</span>';
1.500     raeburn  1589:     }
1.504     bisitz   1590:     $output .=
                   1591:      ' <span class="LC_nobreak">'.
1.479     bisitz   1592:        &mt('Math Rendering:').' '.
1.504     bisitz   1593:        &Apache::loncommon::select_form(
                   1594:            $env{'form.texengine'},
                   1595:            'texengine',
1.510     raeburn  1596:            {&Apache::lonlocal::texthash
1.504     bisitz   1597:                (''        => '',
                   1598:                 'tth'     => 'tth (TeX to HTML)',
1.531.2.3  raeburn  1599:                 'MathJax' => 'MathJax',
1.526     dseaton  1600:   		'jsMath'  => 'jsMath',
1.510     raeburn  1601:                 'mimetex' => 'mimetex (Convert to Images)')}).
1.504     bisitz   1602:      '</span>';
1.500     raeburn  1603:     return $output;
1.478     www      1604: }
                   1605: 
1.151     albertel 1606: sub inserteditinfo {
1.530     raeburn  1607:       my ($filecontents,$filetype,$filename,$symb,$itemtitle) = @_;
1.314     albertel 1608:       $filecontents = &HTML::Entities::encode($filecontents,'<>&"');
1.274     albertel 1609:       my $xml_help = '';
1.321     www      1610:       my $initialize='';
1.452     albertel 1611:       my $textarea_id = 'filecont';
1.530     raeburn  1612:       my ($dragmath_button,$deps_button);
1.452     albertel 1613:       my ($add_to_onload, $add_to_onresize);
1.456     albertel 1614:       $initialize=&Apache::lonhtmlcommon::spellheader();
1.514     raeburn  1615:       if (($filetype eq 'html') && (&Apache::lonhtmlcommon::htmlareabrowser())) {
1.463     albertel 1616: 	  my $lang = &Apache::lonhtmlcommon::htmlarea_lang();
1.512     raeburn  1617:           my %textarea_args = (
                   1618:                                 fullpage => 'true',
                   1619:                                 dragmath => 'math',
                   1620:                               );
1.514     raeburn  1621:           $initialize .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args); 
                   1622:       }
                   1623:       $initialize .= (<<FULLPAGE);
1.321     www      1624: <script type="text/javascript">
1.514     raeburn  1625: // <![CDATA[
1.321     www      1626:     function initDocument() {
1.463     albertel 1627: 	resize_textarea('$textarea_id','LC_aftertextarea');
1.321     www      1628:     }
1.514     raeburn  1629: // ]]>
1.321     www      1630: </script>
                   1631: FULLPAGE
1.514     raeburn  1632:       if ($filetype eq 'html') {
1.530     raeburn  1633:           if ($symb) {
                   1634:               $deps_button = &Apache::lonhtmlcommon::dependencies_button()."\n";
                   1635:               $initialize .= 
                   1636:                   &Apache::lonhtmlcommon::dependencycheck_js($symb,$itemtitle)."\n";
                   1637:           }
1.514     raeburn  1638:           $dragmath_button = '<span id="math_filecont">'.&Apache::lonhtmlcommon::dragmath_button('filecont',1).'</span>';
                   1639:           $initialize .= "\n".&Apache::lonhtmlcommon::dragmath_js('EditMathPopup');
1.512     raeburn  1640:       }
1.456     albertel 1641:       $add_to_onload = 'initDocument();';
                   1642:       $add_to_onresize = "resize_textarea('$textarea_id','LC_aftertextarea');";
                   1643: 
                   1644:       if ($filetype eq 'html') {
1.321     www      1645: 	  $xml_help=&Apache::loncommon::helpLatexCheatsheet();
1.274     albertel 1646:       }
1.452     albertel 1647: 
1.254     albertel 1648:       my $titledisplay=&display_title();
1.512     raeburn  1649:       my $textareaclass;
1.426     banghart 1650:       my %lt=&Apache::lonlocal::texthash('st' => 'Save and Edit',
                   1651: 					 'vi' => 'Save and View',
1.427     banghart 1652: 					 'dv' => 'Discard Edits and View',
1.428     banghart 1653: 					 'un' => 'undo',
1.280     www      1654: 					 'ed' => 'Edit');
1.512     raeburn  1655:       my $spelllink = &Apache::lonhtmlcommon::spelllink('xmledit','filecont');
1.451     albertel 1656:       my $textarea_events = &Apache::edit::element_change_detection();
                   1657:       my $form_events     = &Apache::edit::form_change_detection();
1.491     raeburn  1658:       my $htmlerror;
                   1659:       if ($filetype eq 'html') {
                   1660:           $htmlerror=&verify_html($filecontents);
                   1661:           if ($htmlerror) {
                   1662:               $htmlerror='<span class="LC_error">'.$htmlerror.'</span>';
                   1663:           }
1.501     raeburn  1664:           if (&Apache::lonhtmlcommon::htmlareabrowser()) {
1.515     raeburn  1665:               $textareaclass = 'class="LC_richDefaultOff"';
1.501     raeburn  1666:           }
1.472     www      1667:       }
1.78      www      1668:       my $editfooter=(<<ENDFOOTER);
1.321     www      1669: $initialize
1.78      www      1670: <a name="editsection" />
1.451     albertel 1671: <form $form_events method="post" name="xmledit">
1.470     albertel 1672:   <div class="LC_edit_problem_editxml_header">
                   1673:     <table class="LC_edit_problem_header_title"><tr><td>
                   1674:         $filename
                   1675:       </td><td align="right">
                   1676:         $xml_help
                   1677:       </td></tr>
                   1678:     </table>
                   1679:     <div class="LC_edit_problem_discards">
                   1680:       <input type="submit" name="discardview" accesskey="d" value="$lt{'dv'}" />
                   1681:       <input type="submit" name="Undo" accesskey="u" value="$lt{'un'}" />
1.530     raeburn  1682:       $htmlerror $deps_button $dragmath_button
1.470     albertel 1683:     </div>
                   1684:     <div class="LC_edit_problem_saves">
                   1685:       <input type="submit" name="savethisfile" accesskey="s" value="$lt{'st'}" />
                   1686:       <input type="submit" name="viewmode" accesskey="v" value="$lt{'vi'}" />
                   1687:     </div>
                   1688:   </div>
1.513     raeburn  1689:   <textarea $textarea_events style="width:100%" cols="80" rows="44" name="filecont" id="filecont" $textareaclass>$filecontents</textarea><br />$spelllink
1.470     albertel 1690:   <div id="LC_aftertextarea">
                   1691:     <br />
                   1692:     $titledisplay
                   1693:   </div>
1.78      www      1694: </form>
1.321     www      1695: </body>
1.78      www      1696: ENDFOOTER
1.452     albertel 1697:       return ($editfooter,$add_to_onload,$add_to_onresize);;
1.78      www      1698: }
                   1699: 
1.152     albertel 1700: sub get_target {
1.372     albertel 1701:   my $viewgrades=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});
                   1702:   if ( $env{'request.state'} eq 'published') {
                   1703:     if ( defined($env{'form.grade_target'})
1.152     albertel 1704: 	 && ($viewgrades == 'F' )) {
1.372     albertel 1705:       return ($env{'form.grade_target'});
                   1706:     } elsif (defined($env{'form.grade_target'})) {
                   1707:       if (($env{'form.grade_target'} eq 'web') ||
                   1708: 	  ($env{'form.grade_target'} eq 'tex') ) {
                   1709: 	return $env{'form.grade_target'}
1.153     albertel 1710:       } else {
                   1711: 	return 'web';
                   1712:       }
1.152     albertel 1713:     } else {
                   1714:       return 'web';
                   1715:     }
1.372     albertel 1716:   } elsif ($env{'request.state'} eq 'construct') {
                   1717:     if ( defined($env{'form.grade_target'})) {
                   1718:       return ($env{'form.grade_target'});
1.152     albertel 1719:     } else {
                   1720:       return 'web';
                   1721:     }
                   1722:   } else {
                   1723:     return 'web';
                   1724:   }
                   1725: }
                   1726: 
1.24      sakharuk 1727: sub handler {
1.255     sakharuk 1728:     my $request=shift;
1.493     raeburn  1729: 
1.255     sakharuk 1730:     my $target=&get_target();
1.372     albertel 1731:     $Apache::lonxml::debug=$env{'user.debug'};
1.255     sakharuk 1732:     
1.364     albertel 1733:     &Apache::loncommon::content_type($request,'text/html');
1.255     sakharuk 1734:     &Apache::loncommon::no_cache($request);
1.372     albertel 1735:     if ($env{'request.state'} eq 'published') {
1.363     albertel 1736: 	$request->set_last_modified(&Apache::lonnet::metadata($request->uri,
                   1737: 							      'lastrevisiondate'));
                   1738:     }
1.499     raeburn  1739:     # Embedded Flash movies from Camtasia served from https will not display in IE
                   1740:     #   if XML config file has expired from cache.    
                   1741:     if ($ENV{'SERVER_PORT'} == 443) {
                   1742:         if ($request->uri =~ /\.xml$/) {
                   1743:             my ($httpbrowser,$clientbrowser) =
                   1744:                 &Apache::loncommon::decode_user_agent($request);
                   1745:             if ($clientbrowser =~ /^explorer$/i) {
                   1746:                 delete $request->headers_out->{'Cache-control'};
                   1747:                 delete $request->headers_out->{'Pragma'};
                   1748:                 my $expiration = time + 60;
                   1749:                 my $date=strftime("%a, %d %b %Y %H:%M:%S GMT",gmtime($expiration));
                   1750:                 $request->headers_out->set("Expires" => $date);
                   1751:             }
                   1752:         }
                   1753:     }
1.255     sakharuk 1754:     $request->send_http_header;
                   1755:     
                   1756:     return OK if $request->header_only;
1.68      www      1757: 
                   1758: 
1.255     sakharuk 1759:     my $file=&Apache::lonnet::filelocation("",$request->uri);
1.502     raeburn  1760:     my ($filetype,$breadcrumbtext);
                   1761:     if ($file =~ /\.(sty|css|js|txt|tex)$/) {
1.493     raeburn  1762: 	$filetype=$1;
1.274     albertel 1763:     } else {
                   1764: 	$filetype='html';
                   1765:     }
1.502     raeburn  1766:     if ($filetype eq 'sty') {
                   1767:         $breadcrumbtext = 'Style File Editor';
                   1768:     } elsif ($filetype eq 'js') {
                   1769:         $breadcrumbtext = 'Javascript Editor';
                   1770:     } elsif ($filetype eq 'css') {
                   1771:         $breadcrumbtext = 'CSS Editor';
                   1772:     } elsif ($filetype eq 'txt') {
                   1773:         $breadcrumbtext = 'Text Editor';
                   1774:     } elsif ($filetype eq 'tex') {
                   1775:         $breadcrumbtext = 'TeX Editor';
                   1776:     } else {
                   1777:         $breadcrumbtext = 'HTML Editor';
                   1778:     }
1.493     raeburn  1779: 
1.78      www      1780: #
                   1781: # Edit action? Save file.
                   1782: #
1.428     banghart 1783:     if (!($env{'request.state'} eq 'published')) {
                   1784: 	if ($env{'form.savethisfile'} || $env{'form.viewmode'} || $env{'form.Undo'}) {
1.429     albertel 1785: 	    my $html_file=&Apache::lonnet::getfile($file);
                   1786: 	    my $error = &Apache::lonhomework::handle_save_or_undo($request, \$html_file, \$env{'form.filecont'});
1.472     www      1787:             if ($env{'form.savethisfile'}) {
                   1788:                 $env{'form.editmode'}='Edit'; #force edit mode
                   1789:             }
1.255     sakharuk 1790: 	}
                   1791:     }
                   1792:     my %mystyle;
                   1793:     my $result = '';
                   1794:     my $filecontents=&Apache::lonnet::getfile($file);
                   1795:     if ($filecontents eq -1) {
1.402     albertel 1796: 	my $start_page=&Apache::loncommon::start_page('File Error');
1.412     albertel 1797: 	my $end_page=&Apache::loncommon::end_page();
1.495     bisitz   1798:         my $errormsg='<p class="LC_error">'
                   1799:                     .&mt('File not found: [_1]'
                   1800:                         ,'<span class="LC_filename">'.$file.'</span>')
                   1801:                     .'</p>';
1.255     sakharuk 1802: 	$result=(<<ENDNOTFOUND);
1.402     albertel 1803: $start_page
1.495     bisitz   1804: $errormsg
1.402     albertel 1805: $end_page
1.78      www      1806: ENDNOTFOUND
1.343     albertel 1807:         $filecontents='';
1.372     albertel 1808: 	if ($env{'request.state'} ne 'published') {
1.274     albertel 1809: 	    if ($filetype eq 'sty') {
                   1810: 		$filecontents=&createnewsty();
1.493     raeburn  1811:             } elsif ($filetype eq 'js') {
                   1812:                 $filecontents=&createnewjs();
1.502     raeburn  1813:             } elsif ($filetype ne 'css' && $filetype ne 'txt' && $filetype ne 'tex') {
1.274     albertel 1814: 		$filecontents=&createnewhtml();
                   1815: 	    }
1.372     albertel 1816: 	    $env{'form.editmode'}='Edit'; #force edit mode
1.255     sakharuk 1817: 	}
                   1818:     } else {
1.372     albertel 1819: 	unless ($env{'request.state'} eq 'published') {
1.343     albertel 1820: 	    if ($filecontents=~/BEGIN LON-CAPA Internal/) {
1.381     www      1821: 		&Apache::lonxml::error(&mt('This file appears to be a rendering of a LON-CAPA resource. If this is correct, this resource will act very oddly and incorrectly.'));
1.343     albertel 1822: 	    }
1.264     www      1823: #
                   1824: # we are in construction space, see if edit mode forced
1.385     albertel 1825:             &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1826: 						    ['editmode']);
1.255     sakharuk 1827: 	}
1.427     banghart 1828: 	if (!$env{'form.editmode'} || $env{'form.viewmode'} || $env{'form.discardview'}) {
1.493     raeburn  1829:             if ($filetype eq 'html' || $filetype eq 'sty') {
                   1830: 	        &Apache::structuretags::reset_problem_globals();
                   1831: 	        $result = &Apache::lonxml::xmlparse($request,$target,
                   1832:                                                     $filecontents,'',%mystyle);
1.455     albertel 1833: 	    # .html files may contain <problem> or <Task> need to clean
                   1834: 	    # up if it did
1.493     raeburn  1835: 	        &Apache::structuretags::reset_problem_globals();
                   1836: 	        &Apache::lonhomework::finished_parsing();
1.502     raeburn  1837:             } elsif ($filetype eq 'tex') {
1.503     raeburn  1838:                 $result = &Apache::lontexconvert::converted(\$filecontents,
                   1839:                               $env{'form.texengine'});
                   1840:                 if ($env{'form.return_only_error_and_warning_counts'}) {
                   1841:                     $result = "$errorcount:$warningcount";
                   1842:                 }
1.493     raeburn  1843:             } else {
                   1844:                 $result = $filecontents;
                   1845:             }
1.385     albertel 1846: 	    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1847: 						    ['rawmode']);
1.395     albertel 1848: 	    if ($env{'form.rawmode'}) { $result = $filecontents; }
1.503     raeburn  1849:             if (($filetype ne 'html') && 
                   1850:                 (!$env{'form.return_only_error_and_warning_counts'})) {
1.502     raeburn  1851:                 my $nochgview = 1;
1.495     bisitz   1852:                 my $controls = '';
                   1853:                     if ($env{'request.state'} eq 'construct') {
                   1854:                         $controls = &Apache::loncommon::head_subbox(
                   1855:                                         &Apache::loncommon::CSTR_pageheader()
                   1856:                                        .&Apache::londefdef::edit_controls($nochgview));
                   1857:                     }
1.502     raeburn  1858:                 if ($filetype ne 'sty' && $filetype ne 'tex') {
1.493     raeburn  1859:                     $result =~ s/</&lt;/g;
                   1860:                     $result =~ s/>/&gt;/g;
                   1861:                     $result = '<table class="LC_sty_begin">'.
                   1862:                               '<tr><td><b><pre>'.$result.
                   1863:                               '</pre></b></td></tr></table>';
                   1864:                 }
1.506     droeschl 1865:                 my $brcrum;
                   1866:                 if ($env{'request.state'} eq 'construct') {
1.523     raeburn  1867:                     $brcrum = [{'href' => &Apache::loncommon::authorspace($request->uri),
1.506     droeschl 1868:                                 'text' => 'Construction Space'},
                   1869:                                {'href' => '',
                   1870:                                 'text' => $breadcrumbtext}];
1.493     raeburn  1871:                 } else {
1.506     droeschl 1872:                     $brcrum = ''; # FIXME: Where are we?
1.493     raeburn  1873:                 }
1.506     droeschl 1874:                 my %options = ('bread_crumbs' => $brcrum,
                   1875:                                'bgcolor'      => '#FFFFFF');
                   1876:                 $result =
                   1877:                     &Apache::loncommon::start_page(undef,undef,\%options)
                   1878:                    .$controls
                   1879:                    .$result
                   1880:                    .&Apache::loncommon::end_page();
1.493     raeburn  1881:             }
1.495     bisitz   1882:         }
1.147     albertel 1883:     }
1.456     albertel 1884: 
1.78      www      1885: #
                   1886: # Edit action? Insert editing commands
                   1887: #
1.372     albertel 1888:     unless ($env{'request.state'} eq 'published') {
1.427     banghart 1889: 	if ($env{'form.editmode'} && (!($env{'form.viewmode'})) && (!($env{'form.discardview'})))
1.450     albertel 1890: 	{
1.530     raeburn  1891:             my ($displayfile,$url,$symb,$itemtitle);
                   1892: 	    $displayfile=$request->uri;
                   1893:             if ($request->uri =~ m{^/uploaded/}) {
                   1894:                 ($symb,$itemtitle,$displayfile) = 
                   1895:                     &get_courseupload_hierarchy($request->uri);
1.529     raeburn  1896:             } else {
                   1897: 	        $displayfile=~s/^\/[^\/]*//;
                   1898:             }
1.470     albertel 1899: 
1.452     albertel 1900: 	    my ($edit_info, $add_to_onload, $add_to_onresize)=
1.530     raeburn  1901: 		&inserteditinfo($filecontents,$filetype,$displayfile,$symb,$itemtitle);
1.450     albertel 1902: 
                   1903: 	    my %options = 
                   1904: 		('add_entries' =>
1.495     bisitz   1905:                    {'onresize'     => $add_to_onresize,
                   1906:                     'onload'       => $add_to_onload,   });
1.500     raeburn  1907:             my $header;
                   1908:             if ($env{'request.state'} eq 'construct') {
                   1909:                 $options{'bread_crumbs'} = [{
1.523     raeburn  1910:                             'href' => &Apache::loncommon::authorspace($request->uri),
1.500     raeburn  1911:                             'text' => 'Construction Space'},
                   1912:                            {'href' => '',
1.502     raeburn  1913:                             'text' => $breadcrumbtext}];
1.500     raeburn  1914:                 $header = &Apache::loncommon::head_subbox(
                   1915:                               &Apache::loncommon::CSTR_pageheader());
                   1916:             }
1.452     albertel 1917: 	    my $js =
                   1918: 		&Apache::edit::js_change_detection().
                   1919: 		&Apache::loncommon::resize_textarea_js();
1.451     albertel 1920: 	    my $start_page = &Apache::loncommon::start_page(undef,$js,
1.402     albertel 1921: 							    \%options);
1.495     bisitz   1922:             $result = $start_page
1.500     raeburn  1923:                      .$header
1.495     bisitz   1924:                      .&Apache::lonxml::message_location()
                   1925:                      .$edit_info
                   1926:                      .&Apache::loncommon::end_page();
1.493     raeburn  1927:         }
1.147     albertel 1928:     }
1.402     albertel 1929:     if ($filetype eq 'html') { &writeallows($request->uri); }
1.501     raeburn  1930: 
1.309     albertel 1931:     &Apache::lonxml::add_messages(\$result);
1.255     sakharuk 1932:     $request->print($result);
                   1933:     
                   1934:     return OK;
1.253     albertel 1935: }
                   1936: 
                   1937: sub display_title {
                   1938:     my $result;
1.372     albertel 1939:     if ($env{'request.state'} eq 'construct') {
1.253     albertel 1940: 	my $title=&Apache::lonnet::gettitle();
                   1941: 	if (!defined($title) || $title eq '') {
1.372     albertel 1942: 	    $title = $env{'request.filename'};
1.253     albertel 1943: 	    $title = substr($title, rindex($title, '/') + 1);
                   1944: 	}
1.476     bisitz   1945:         $result = "<script type='text/javascript'>top.document.title = '$title - LON-CAPA "
                   1946:                   .&mt('Construction Space')."';</script>";
1.253     albertel 1947:     }
                   1948:     return $result;
1.24      sakharuk 1949: }
1.147     albertel 1950: 
1.530     raeburn  1951: sub get_courseupload_hierarchy {
                   1952:     my ($url) = @_;
                   1953:     my ($symb,$itemtitle,$displaypath);
                   1954:     if ($env{'request.course.id'}) {
1.531.2.4! raeburn  1955:         $symb = &Apache::lonnet::symbread($url);
1.530     raeburn  1956:         my ($map,$id,$res)=&Apache::lonnet::decode_symb($symb);
                   1957:         my $navmap=Apache::lonnavmaps::navmap->new;
                   1958:         if (ref($navmap)) {
                   1959:             my $res = $navmap->getBySymb($symb);
                   1960:             if (ref($res)) {
                   1961:                 my @pathitems =
                   1962:                     &Apache::loncommon::get_folder_hierarchy($navmap,$map,1);
                   1963:                 $itemtitle = $res->compTitle();
                   1964:                 push(@pathitems,$itemtitle);
                   1965:                 $displaypath = join(' &raquo; ',@pathitems);
                   1966:             }
                   1967:         }
                   1968:     }
                   1969:     return ($symb,$itemtitle,$displaypath);
                   1970: }
                   1971: 
1.22      albertel 1972: sub debug {
1.298     albertel 1973:     if ($Apache::lonxml::debug eq "1") {
                   1974: 	$|=1;
1.300     albertel 1975: 	my $request=$Apache::lonxml::request;
1.388     albertel 1976: 	if (!$request) {
                   1977: 	    eval { $request=Apache->request; };
                   1978: 	}
                   1979: 	if (!$request) {
                   1980: 	    eval { $request=Apache2::RequestUtil->request; };
                   1981: 	}
1.314     albertel 1982: 	$request->print('<font size="-2"><pre>DEBUG:'.&HTML::Entities::encode($_[0],'<>&"')."</pre></font>\n");
1.346     albertel 1983: 	#&Apache::lonnet::logthis($_[0]);
1.298     albertel 1984:     }
1.22      albertel 1985: }
1.49      albertel 1986: 
1.348     albertel 1987: sub show_error_warn_msg {
1.522     raeburn  1988:     if (($env{'request.filename'} eq 
                   1989:          $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/lib/templates/simpleproblem.problem') &&
                   1990:         (&Apache::lonnet::allowed('mdc',$env{'request.course.id'}))) {
1.351     albertel 1991: 	return 1;
                   1992:     }
1.348     albertel 1993:     return (($Apache::lonxml::debug eq 1) ||
1.372     albertel 1994: 	    ($env{'request.state'} eq 'construct') ||
1.348     albertel 1995: 	    ($Apache::lonhomework::browse eq 'F'
                   1996: 	     &&
1.372     albertel 1997: 	     $env{'form.show_errors'} eq 'on'));
1.348     albertel 1998: }
                   1999: 
1.22      albertel 2000: sub error {
1.454     albertel 2001:     my @errors = @_;
                   2002: 
1.336     albertel 2003:     $errorcount++;
1.454     albertel 2004: 
1.490     www      2005:     $Apache::lonxml::internal_error=1;
                   2006: 
1.454     albertel 2007:     if (defined($Apache::inputtags::part)) {
                   2008: 	if ( @Apache::inputtags::response ) {
                   2009: 	    push(@errors,
                   2010: 		 &mt("This error occurred while processing response [_1] in part [_2]",
                   2011: 		     $Apache::inputtags::response[-1],
                   2012: 		     $Apache::inputtags::part));
                   2013: 	} else {
                   2014: 	    push(@errors,
                   2015: 		 &mt("This error occurred while processing part [_1]",
                   2016: 		     $Apache::inputtags::part));
                   2017: 	}
                   2018:     }
                   2019: 
1.348     albertel 2020:     if ( &show_error_warn_msg() ) {
1.336     albertel 2021: 	# If printing in construction space, put the error inside <pre></pre>
                   2022: 	push(@Apache::lonxml::error_messages,
1.484     bisitz   2023: 	     $Apache::lonxml::warnings_error_header
                   2024:              .'<div class="LC_error">'
                   2025:              .'<b>'.&mt('ERROR:').' </b>'.join("<br />\n",@errors)
                   2026:              ."</div>\n");
1.336     albertel 2027: 	$Apache::lonxml::warnings_error_header='';
                   2028:     } else {
                   2029: 	my $errormsg;
                   2030: 	my ($symb)=&Apache::lonnet::symbread();
                   2031: 	if ( !$symb ) {
                   2032: 	    #public or browsers
1.486     bisitz   2033: 	    $errormsg=&mt("An error occurred while processing this resource. The author has been notified.");
1.403     albertel 2034: 	}
1.413     albertel 2035: 	my $host=$Apache::lonnet::perlvar{'lonHostID'};
1.476     bisitz   2036: 	push(@errors,
                   2037:         &mt("The error occurred on host [_1]",
                   2038:              "<tt>$host</tt>"));
1.454     albertel 2039: 
                   2040: 	my $msg = join('<br />', @errors);
                   2041: 
1.336     albertel 2042: 	#notify author
1.403     albertel 2043: 	&Apache::lonmsg::author_res_msg($env{'request.filename'},$msg);
1.336     albertel 2044: 	#notify course
1.372     albertel 2045: 	if ( $symb && $env{'request.course.id'} ) {
1.380     www      2046: 	    my $cnum=$env{'course.'.$env{'request.course.id'}.'.num'};
                   2047: 	    my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.440     albertel 2048: 	    my (undef,%users)=&Apache::lonmsg::decide_receiver(undef,0,1,1,1);
1.372     albertel 2049: 	    my $declutter=&Apache::lonnet::declutter($env{'request.filename'});
1.435     raeburn  2050:             my $baseurl = &Apache::lonnet::clutter($declutter);
1.336     albertel 2051: 	    my @userlist;
                   2052: 	    foreach (keys %users) {
                   2053: 		my ($user,$domain) = split(/:/, $_);
1.531     bisitz   2054: 		push(@userlist,"$user:$domain");
1.380     www      2055: 		my $key=$declutter.'_'.$user.'_'.$domain;
                   2056: 		my %lastnotified=&Apache::lonnet::get('nohist_xmlerrornotifications',
                   2057: 						      [$key],
                   2058: 						      $cdom,$cnum);
                   2059: 		my $now=time;
                   2060: 		if ($now-$lastnotified{$key}>86400) {
1.434     raeburn  2061:                     my $title = &Apache::lonnet::gettitle($symb);
                   2062:                     my $sentmessage;
1.380     www      2063: 		    &Apache::lonmsg::user_normal_msg($user,$domain,
1.435     raeburn  2064: 		        "Error [$title]",$msg,'',$baseurl,'','',
1.434     raeburn  2065:                         \$sentmessage,$symb,$title,1);
1.380     www      2066: 		    &Apache::lonnet::put('nohist_xmlerrornotifications',
                   2067: 					 {$key => $now},
                   2068: 					 $cdom,$cnum);		
                   2069: 		}
1.336     albertel 2070: 	    }
1.372     albertel 2071: 	    if ($env{'request.role.adv'}) {
1.486     bisitz   2072: 		$errormsg=&mt("An error occurred while processing this resource. The course personnel ([_1]) and the author have been notified.",join(', ',@userlist));
1.336     albertel 2073: 	    } else {
1.486     bisitz   2074: 		$errormsg=&mt("An error occurred while processing this resource. The instructor has been notified.");
1.336     albertel 2075: 	    }
                   2076: 	}
1.531     bisitz   2077: 	push(@Apache::lonxml::error_messages,"<span class=\"LC_warning\">$errormsg</span><br />");
1.52      albertel 2078:     }
1.22      albertel 2079: }
1.49      albertel 2080: 
1.22      albertel 2081: sub warning {
1.295     albertel 2082:     $warningcount++;
1.261     albertel 2083:   
1.372     albertel 2084:     if ($env{'form.grade_target'} ne 'tex') {
1.348     albertel 2085: 	if ( &show_error_warn_msg() ) {
1.309     albertel 2086: 	    push(@Apache::lonxml::warning_messages,
1.484     bisitz   2087: 		 $Apache::lonxml::warnings_error_header
                   2088:                 .'<div class="LC_warning">'
                   2089:                 .&mt('[_1]W[_2]ARNING','<b>','</b>')."<b>:</b> ".join('<br />',@_)
                   2090:                 ."</div>\n"
1.482     bisitz   2091:                 );
1.295     albertel 2092: 	    $Apache::lonxml::warnings_error_header='';
                   2093: 	}
                   2094:     }
1.309     albertel 2095: }
                   2096: 
                   2097: sub info {
1.372     albertel 2098:     if ($env{'form.grade_target'} ne 'tex' 
                   2099: 	&& $env{'request.state'} eq 'construct') {
1.309     albertel 2100: 	push(@Apache::lonxml::info_messages,join('<br />',@_)."<br />\n");
                   2101:     }
                   2102: }
                   2103: 
                   2104: sub message_location {
                   2105:     return '__LONCAPA_INTERNAL_MESSAGE_LOCATION__';
                   2106: }
                   2107: 
                   2108: sub add_messages {
                   2109:     my ($msg)=@_;
                   2110:     my $result=join(' ',
                   2111: 		    @Apache::lonxml::info_messages,
                   2112: 		    @Apache::lonxml::error_messages,
                   2113: 		    @Apache::lonxml::warning_messages);
                   2114:     undef(@Apache::lonxml::info_messages);
                   2115:     undef(@Apache::lonxml::error_messages);
                   2116:     undef(@Apache::lonxml::warning_messages);
                   2117:     $$msg=~s/__LONCAPA_INTERNAL_MESSAGE_LOCATION__/$result/;
                   2118:     $$msg=~s/__LONCAPA_INTERNAL_MESSAGE_LOCATION__//g;
1.83      albertel 2119: }
                   2120: 
                   2121: sub get_param {
1.213     albertel 2122:     my ($param,$parstack,$safeeval,$context,$case_insensitive) = @_;
                   2123:     if ( ! $context ) { $context = -1; }
                   2124:     my $args ='';
                   2125:     if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
1.297     sakharuk 2126:     if ( ! $Apache::lonxml::usestyle ) {
                   2127: 	$args=$Apache::lonxml::style_values.$args;
                   2128:     }
1.213     albertel 2129:     if ( ! $args ) { return undef; }
                   2130:     if ( $case_insensitive ) {
1.417     albertel 2131: 	if ($args =~ s/(my (?:.*))(\$\Q$param\E[,\)])/$1.lc($2)/ei) {
1.213     albertel 2132: 	    return &Apache::run::run("{$args;".'return $'.$param.'}',
                   2133:                                      $safeeval); #'
                   2134: 	} else {
                   2135: 	    return undef;
                   2136: 	}
                   2137:     } else {
1.417     albertel 2138: 	if ( $args =~ /my .*\$\Q$param\E[,\)]/ ) {
1.213     albertel 2139: 	    return &Apache::run::run("{$args;".'return $'.$param.'}',
                   2140:                                      $safeeval); #'
                   2141: 	} else {
                   2142: 	    return undef;
                   2143: 	}
                   2144:     }
1.22      albertel 2145: }
                   2146: 
1.132     albertel 2147: sub get_param_var {
1.213     albertel 2148:   my ($param,$parstack,$safeeval,$context,$case_insensitive) = @_;
1.132     albertel 2149:   if ( ! $context ) { $context = -1; }
                   2150:   my $args ='';
                   2151:   if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
1.297     sakharuk 2152:   if ( ! $Apache::lonxml::usestyle ) {
                   2153:       $args=$Apache::lonxml::style_values.$args;
                   2154:   }
1.230     albertel 2155:   &Apache::lonxml::debug("Args are $args param is $param");
1.213     albertel 2156:   if ($case_insensitive) {
1.419     albertel 2157:       if (! ($args=~s/(my (?:.*))(\$\Q$param\E[,\)])/$1.lc($2)/ei)) {
1.213     albertel 2158: 	  return undef;
                   2159:       }
1.419     albertel 2160:   } elsif ( $args !~ /my .*\$\Q$param\E[,\)]/ ) { return undef; }
1.132     albertel 2161:   my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
1.230     albertel 2162:   &Apache::lonxml::debug("first run is $value");
1.341     albertel 2163:   if ($value =~ /^[\$\@\%][a-zA-Z_]\w*$/) {
1.230     albertel 2164:       &Apache::lonxml::debug("doing second");
                   2165:       my @result=&Apache::run::run("return $value",$safeeval,1);
                   2166:       if (!defined($result[0])) {
                   2167: 	  return $value
                   2168:       } else {
                   2169: 	  if (wantarray) { return @result; } else { return $result[0]; }
                   2170:       }
1.132     albertel 2171:   } else {
                   2172:     return $value;
                   2173:   }
                   2174: }
                   2175: 
1.438     albertel 2176: sub register_insert_xml {
                   2177:     my $parser = HTML::LCParser->new($Apache::lonnet::perlvar{'lonTabDir'}
                   2178: 				     .'/insertlist.xml');
                   2179:     my ($tagnum,$in_help)=(0,0);
1.442     albertel 2180:     my @alltags;
1.438     albertel 2181:     my $tag;
                   2182:     while (my $token = $parser->get_token()) {
                   2183: 	if ($token->[0] eq 'S') {
                   2184: 	    my $key;
1.525     raeburn  2185: 	    if ($token->[1] eq 'tag') {
1.438     albertel 2186: 		$tag = $token->[2]{'name'};
1.525     raeburn  2187:                 if (defined($tag)) {
                   2188: 		    $insertlist{$tagnum.'.tag'} = $tag;
                   2189: 		    $insertlist{$tag.'.num'}   = $tagnum;
                   2190: 		    push(@alltags,$tag);
                   2191:                 }
1.438     albertel 2192: 	    } elsif ($in_help && $token->[1] eq 'file') {
                   2193: 		$key = $tag.'.helpfile';
                   2194: 	    } elsif ($in_help && $token->[1] eq 'description') {
                   2195: 		$key = $tag.'.helpdesc';
                   2196: 	    } elsif ($token->[1] eq 'description' ||
                   2197: 		     $token->[1] eq 'color'       ||
                   2198: 		     $token->[1] eq 'show'          ) {
                   2199: 		$key = $tag.'.'.$token->[1];
                   2200: 	    } elsif ($token->[1] eq 'insert_sub') {
                   2201: 		$key = $tag.'.function';
                   2202: 	    } elsif ($token->[1] eq 'help') {
                   2203: 		$in_help=1;
                   2204: 	    } elsif ($token->[1] eq 'allow') {
1.442     albertel 2205: 		$key = $tag.'.allow';
1.438     albertel 2206: 	    }
                   2207: 	    if (defined($key)) {
                   2208: 		$insertlist{$key} = $parser->get_text();
                   2209: 		$insertlist{$key} =~ s/(^\s*|\s*$ )//gx;
                   2210: 	    }
                   2211: 	} elsif ($token->[0] eq 'E') {
                   2212: 	    if      ($token->[1] eq 'tag') {
                   2213: 		undef($tag);
                   2214: 		$tagnum++;
                   2215: 	    } elsif ($token->[1] eq 'help') {
                   2216: 		undef($in_help);
                   2217: 	    }
                   2218: 	}
                   2219:     }
1.442     albertel 2220:     
                   2221:     # parse the allows and ignore tags set to <show>no</show>
                   2222:     foreach my $tag (@alltags) {	
1.519     raeburn  2223:         next if (!exists($insertlist{$tag.'.allow'}));
                   2224: 	my $allow =  $insertlist{$tag.'.allow'};
1.442     albertel 2225:        	foreach my $element (split(',',$allow)) {
                   2226: 	    $element =~ s/(^\s*|\s*$ )//gx;
1.519     raeburn  2227: 	    if (!exists($insertlist{$element.'.show'})
                   2228:                 || $insertlist{$element.'.show'} ne 'no') {
1.442     albertel 2229: 		push(@{ $insertlist{$tag.'.which'} },$element);
                   2230: 	    }
                   2231: 	}
                   2232:     }
1.438     albertel 2233: }
                   2234: 
                   2235: sub register_insert {
                   2236:     return &register_insert_xml(@_);
                   2237: #    &dump_insertlist('2');
                   2238: }
                   2239: 
                   2240: sub dump_insertlist {
                   2241:     my ($ext) = @_;
                   2242:     open(XML,">/tmp/insertlist.xml.$ext");
                   2243:     print XML ("<insertlist>");
                   2244:     my $i=0;
                   2245: 
                   2246:     while (exists($insertlist{"$i.tag"})) {
                   2247: 	my $tag = $insertlist{"$i.tag"};
                   2248: 	print XML ("
                   2249: \t<tag name=\"$tag\">");
                   2250: 	if (defined($insertlist{"$tag.description"})) {
                   2251: 	    print XML ("
                   2252: \t\t<description>".$insertlist{"$tag.description"}."</description>");
                   2253: 	}
                   2254: 	if (defined($insertlist{"$tag.color"})) {
                   2255: 	    print XML ("
                   2256: \t\t<color>".$insertlist{"$tag.color"}."</color>");
                   2257: 	}
                   2258: 	if (defined($insertlist{"$tag.function"})) {
                   2259: 	    print XML ("
                   2260: \t\t<insert_sub>".$insertlist{"$tag.function"}."</insert_sub>");
                   2261: 	}
                   2262: 	if (defined($insertlist{"$tag.show"})
                   2263: 	    && $insertlist{"$tag.show"} ne 'yes') {
                   2264: 	    print XML ("
                   2265: \t\t<show>".$insertlist{"$tag.show"}."</show>");
                   2266: 	}
                   2267: 	if (defined($insertlist{"$tag.helpfile"})) {
                   2268: 	    print XML ("
                   2269: \t\t<help>
                   2270: \t\t\t<file>".$insertlist{"$tag.helpfile"}."</file>");
                   2271: 	    if ($insertlist{"$tag.helpdesc"} ne '') {
                   2272: 		print XML ("
                   2273: \t\t\t<description>".$insertlist{"$tag.helpdesc"}."</description>");
                   2274: 	    }
                   2275: 	    print XML ("
                   2276: \t\t</help>");
                   2277: 	}
                   2278: 	if (defined($insertlist{"$tag.which"})) {
                   2279: 	    print XML ("
                   2280: \t\t<allow>".join(',',sort(@{ $insertlist{"$tag.which"} }))."</allow>");
                   2281: 	}
                   2282: 	print XML ("
                   2283: \t</tag>");
                   2284: 	$i++;
                   2285:     }
                   2286:     print XML ("\n</insertlist>\n");
                   2287:     close(XML);
                   2288: }
                   2289: 
1.98      albertel 2290: sub description {
1.437     albertel 2291:     my ($token)=@_;
                   2292:     my $tag = &get_tag($token);
                   2293:     return $insertlist{$tag.'.description'};
1.268     bowersj2 2294: }
                   2295: 
                   2296: # Returns a list containing the help file, and the description
                   2297: sub helpinfo {
1.437     albertel 2298:     my ($token)=@_;
                   2299:     my $tag = &get_tag($token);
                   2300:     return ($insertlist{$tag.'.helpfile'}, $insertlist{$tag.'.helpdesc'});
                   2301: }
                   2302: 
                   2303: sub get_tag {
                   2304:     my ($token)=@_;
                   2305:     my $tagnum;
                   2306:     my $tag=$token->[1];
                   2307:     foreach my $namespace (reverse(@Apache::lonxml::namespace)) {
                   2308: 	my $testtag = $namespace.'::'.$tag;
                   2309: 	$tagnum = $insertlist{"$testtag.num"};
                   2310: 	last if (defined($tagnum));
                   2311:     }
                   2312:     if (!defined($tagnum)) {
                   2313: 	$tagnum = $Apache::lonxml::insertlist{"$tag.num"};
                   2314:     }
                   2315:     return $insertlist{"$tagnum.tag"};
1.98      albertel 2316: }
1.123     albertel 2317: 
1.485     onken    2318: ############################################################
                   2319: #                                           PDF-FORM-METHODS
                   2320: 
                   2321: =pod
                   2322: 
1.508     onken    2323: =item &print_pdf_radiobutton(fieldname, value)
1.485     onken    2324: 
1.508     onken    2325: Returns a latexline to generate a PDF-Form-Radiobutton.
                   2326: Note: Radiobuttons with equal names are automaticly grouped 
                   2327:       in a selection-group.
1.485     onken    2328: 
1.508     onken    2329: $fieldname: PDF internalname of the radiobutton(group)
                   2330: $value:     Value of radiobutton
1.485     onken    2331: 
                   2332: =cut
                   2333: sub print_pdf_radiobutton {
1.508     onken    2334:     my ($fieldname, $value) = @_;
                   2335:     return '\radioButton[\symbolchoice{circle}]{'
                   2336:            .$fieldname.'}{10bp}{10bp}{'.$value.'}';
1.485     onken    2337: }
                   2338: 
                   2339: 
                   2340: =pod
                   2341: 
                   2342: =item &print_pdf_start_combobox(fieldname)
                   2343: 
                   2344: Starts a latexline to generate a PDF-Form-Combobox with text.
                   2345: 
                   2346: $fieldname: PDF internal name of the Combobox
                   2347: 
                   2348: =cut
                   2349: sub print_pdf_start_combobox {
                   2350:     my $result;
                   2351:     my ($fieldName) = @_;
                   2352:     $result .= '\begin{tabularx}{\textwidth}{p{2.5cm}X}'."\n";
                   2353:     $result .= '\comboBox[]{'.$fieldName.'}{2.3cm}{14bp}{'; # 
                   2354: 
                   2355:     return $result;
                   2356: }
                   2357: 
                   2358: 
                   2359: =pod
                   2360: 
                   2361: =item &print_pdf_add_combobox_option(options)
                   2362: 
                   2363: Generates a latexline to add Options to a PDF-Form-ComboBox.
                   2364: 
                   2365: $option: PDF internal name of the Combobox-Option
                   2366: 
                   2367: =cut
                   2368: sub print_pdf_add_combobox_option {
                   2369: 
                   2370:     my $result;
                   2371:     my ($option) = @_;  
                   2372: 
                   2373:     $result .= '('.$option.')';
                   2374:     
                   2375:     return $result;
                   2376: }
                   2377: 
                   2378: 
                   2379: =pod
                   2380: 
                   2381: =item &print_pdf_end_combobox(text) {
                   2382: 
                   2383: Returns latexcode to end a PDF-Form-Combobox with text.
                   2384: 
                   2385: =cut
                   2386: sub print_pdf_end_combobox {
                   2387:     my $result;
                   2388:     my ($text) = @_;
                   2389: 
                   2390:     $result .= '}&'.$text."\\\\\n";
                   2391:     $result .= '\end{tabularx}' . "\n";
                   2392:     $result .= '\hspace{2mm}' . "\n";
                   2393:     return $result;
                   2394: }
                   2395: 
                   2396: 
                   2397: =pod
                   2398: 
                   2399: =item &print_pdf_hiddenField(fieldname, user, domain)
                   2400: 
                   2401: Returns a latexline to generate a PDF-Form-hiddenField with userdata.
                   2402: 
                   2403: $fieldname label for hiddentextfield
                   2404: $user:    name of user
                   2405: $domain:  domain of user
                   2406: 
                   2407: =cut
                   2408: sub print_pdf_hiddenfield {
                   2409:     my $result;
                   2410:     my ($fieldname, $user, $domain) = @_;
                   2411: 
                   2412:     $result .= '\textField [\F{\FHidden}\F{-\FPrint}\V{'.$domain.'&'.$user.'}]{'.$fieldname.'}{0in}{0in}'."\n";
                   2413: 
                   2414:     return $result;
                   2415: }
                   2416: 
1.1       sakharuk 2417: 1;
                   2418: __END__
1.68      www      2419: 

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.