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

1.2       sakharuk    1: # The LearningOnline Network with CAPA
1.3       sakharuk    2: # XML Parser Module 
1.2       sakharuk    3: #
1.323   ! www         4: # $Id: lonxml.pm,v 1.322 2004/06/04 22:56:46 albertel 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.2       sakharuk   40: 
1.4       albertel   41: package Apache::lonxml; 
1.33      www        42: use vars 
1.320     www        43: qw(@pwd @outputstack $redirection $import @extlinks $metamode $evaluate %insertlist @namespace $errorcount $warningcount @htmlareafields);
1.1       sakharuk   44: use strict;
1.167     albertel   45: use HTML::LCParser();
1.161     albertel   46: use HTML::TreeBuilder();
                     47: use HTML::Entities();
                     48: use Safe();
                     49: use Safe::Hole();
                     50: use Math::Cephes();
                     51: use Math::Random();
                     52: use Opcode();
1.271     www        53: use POSIX qw(strftime);
1.72      albertel   54: 
1.266     bowersj2   55: 
1.72      albertel   56: sub register {
1.141     albertel   57:   my ($space,@taglist) = @_;
                     58:   foreach my $temptag (@taglist) {
                     59:     push(@{ $Apache::lonxml::alltags{$temptag} },$space);
1.72      albertel   60:   }
                     61: }
                     62: 
1.141     albertel   63: sub deregister {
                     64:   my ($space,@taglist) = @_;
                     65:   foreach my $temptag (@taglist) {
                     66:     my $tempspace = $Apache::lonxml::alltags{$temptag}[-1];
                     67:     if ($tempspace eq $space) {
                     68:       pop(@{ $Apache::lonxml::alltags{$temptag} });
                     69:     }
                     70:   }
1.142     albertel   71:   #&printalltags();
1.141     albertel   72: }
                     73: 
1.46      www        74: use Apache::Constants qw(:common);
1.161     albertel   75: use Apache::lontexconvert();
                     76: use Apache::style();
                     77: use Apache::run();
                     78: use Apache::londefdef();
                     79: use Apache::scripttag();
1.285     www        80: use Apache::languagetags();
1.161     albertel   81: use Apache::edit();
1.266     bowersj2   82: use Apache::inputtags();
                     83: use Apache::outputtags();
1.161     albertel   84: use Apache::lonnet();
                     85: use Apache::File();
                     86: use Apache::loncommon();
1.198     www        87: use Apache::lonfeedback();
1.200     www        88: use Apache::lonmsg();
1.217     matthew    89: use Apache::loncacc();
1.280     www        90: use Apache::lonlocal;
1.79      www        91: 
1.72      albertel   92: #==================================================   Main subroutine: xmlparse  
                     93: #debugging control, to turn on debugging modify the correct handler
                     94: $Apache::lonxml::debug=0;
1.206     albertel   95: 
                     96: # keeps count of the number of warnings and errors generated in a parse
                     97: $warningcount=0;
                     98: $errorcount=0;
1.72      albertel   99: 
                    100: #path to the directory containing the file currently being processed
                    101: @pwd=();
                    102: 
                    103: #these two are used for capturing a subset of the output for later processing,
                    104: #don't touch them directly use &startredirection and &endredirection
                    105: @outputstack = ();
                    106: $redirection = 0;
                    107: 
                    108: #controls wheter the <import> tag actually does
                    109: $import = 1;
                    110: @extlinks=();
                    111: 
                    112: # meta mode is a bit weird only some output is to be turned off
                    113: #<output> tag turns metamode off (defined in londefdef.pm)
                    114: $metamode = 0;
                    115: 
                    116: # turns on and of run::evaluate actually derefencing var refs
                    117: $evaluate = 1;
1.7       albertel  118: 
1.74      albertel  119: # data structure for eidt mode, determines what tags can go into what other tags
                    120: %insertlist=();
1.68      www       121: 
1.99      albertel  122: # stores the list of active tag namespaces
1.76      albertel  123: @namespace=();
                    124: 
1.99      albertel  125: # has the dynamic menu been updated to know about this resource
                    126: $Apache::lonxml::registered=0;
                    127: 
1.172     albertel  128: # a pointer the the Apache request object
                    129: $Apache::lonxml::request='';
                    130: 
1.216     sakharuk  131: # a problem number counter, and check on ether it is used
1.237     sakharuk  132: $Apache::lonxml::counter=1;
1.204     albertel  133: $Apache::lonxml::counter_changed=0;
                    134: 
1.212     albertel  135: #internal check on whether to look at style defs
                    136: $Apache::lonxml::usestyle=1;
1.260     albertel  137: 
                    138: #locations used to store the parameter string for style substitutions
                    139: $Apache::lonxml::style_values='';
                    140: $Apache::lonxml::style_end_values='';
1.212     albertel  141: 
1.281     albertel  142: #array of ssi calls that need to occur after we are done parsing
                    143: @Apache::lonxml::ssi_info=();
                    144: 
1.282     albertel  145: #should we do the postag variable interpolation
                    146: $Apache::lonxml::post_evaluate=1;
                    147: 
1.295     albertel  148: #a header message to emit in the case of any generated warning or errors
                    149: $Apache::lonxml::warnings_error_header='';
                    150: 
1.68      www       151: sub xmlbegin {
                    152:   my $output='';
                    153:   if ($ENV{'browser.mathml'}) {
                    154:       $output='<?xml version="1.0"?>'
                    155:             .'<?xml-stylesheet type="text/css" href="/adm/MathML/mathml.css"?>'
                    156:             .'<!DOCTYPE html SYSTEM "/adm/MathML/mathml.dtd" '
                    157:             .'[<!ENTITY mathns "http://www.w3.org/1998/Math/MathML">]>'
                    158:             .'<html xmlns:math="http://www.w3.org/1998/Math/MathML" ' 
                    159: 		.'xmlns="http://www.w3.org/TR/REC-html40">';
                    160:   } else {
                    161:       $output='<html>';
                    162:   }
                    163:   return $output;
                    164: }
                    165: 
                    166: sub xmlend {
1.278     www       167:     my $mode='xml';
                    168:     my $status='OPEN';
                    169:     if ($Apache::lonhomework::parsing_a_problem) {
                    170: 	$mode='problem';
                    171: 	$status=$Apache::inputtags::status[-1]; 
                    172:     }
1.298     albertel  173:     return &Apache::lonfeedback::list_discussion($mode,$status).'</html>';
1.119     www       174: }
                    175: 
                    176: sub tokeninputfield {
1.120     www       177:     my $defhost=$Apache::lonnet::perlvar{'lonHostID'};
                    178:     $defhost=~tr/a-z/A-Z/;
1.119     www       179:     return (<<ENDINPUTFIELD)
1.226     albertel  180: <script type="text/javascript">
1.120     www       181:     function updatetoken() {
                    182: 	var comp=new Array;
                    183:         var barcode=unescape(document.tokeninput.barcode.value);
                    184:         comp=barcode.split('*');
                    185:         if (typeof(comp[0])!="undefined") {
                    186: 	    document.tokeninput.codeone.value=comp[0];
                    187: 	}
                    188:         if (typeof(comp[1])!="undefined") {
                    189: 	    document.tokeninput.codetwo.value=comp[1];
                    190: 	}
                    191:         if (typeof(comp[2])!="undefined") {
                    192:             comp[2]=comp[2].toUpperCase();
                    193: 	    document.tokeninput.codethree.value=comp[2];
                    194: 	}
                    195:         document.tokeninput.barcode.value='';
                    196:     }  
                    197: </script>
                    198: <form method="post" name="tokeninput">
1.119     www       199: <table border="2" bgcolor="#FFFFBB">
                    200: <tr><th>DocID Checkin</th></tr>
                    201: <tr><td>
                    202: <table>
                    203: <tr>
                    204: <td>Scan in Barcode</td>
1.120     www       205: <td><input type="text" size="22" name="barcode" 
                    206: onChange="updatetoken()"/></td>
1.119     www       207: </tr>
                    208: <tr><td><i>or</i> Type in DocID</td>
                    209: <td>
                    210: <input type="text" size="5" name="codeone" />
1.120     www       211: <b><font size="+2">*</font></b>
1.119     www       212: <input type="text" size="5" name="codetwo" />
1.120     www       213: <b><font size="+2">*</font></b>
                    214: <input type="text" size="10" name="codethree" value="$defhost" 
                    215: onChange="this.value=this.value.toUpperCase()" />
1.119     www       216: </td></tr>
                    217: </table>
                    218: </td></tr>
                    219: <tr><td><input type="submit" value="Check in DocID" /></td></tr>
                    220: </table>
                    221: </form>
                    222: ENDINPUTFIELD
1.112     www       223: }
                    224: 
1.116     www       225: sub maketoken {
1.118     www       226:     my ($symb,$tuname,$tudom,$tcrsid)=@_;
1.112     www       227:     unless ($symb) {
                    228: 	$symb=&Apache::lonnet::symbread();
                    229:     }
                    230:     unless ($tuname) {
                    231: 	$tuname=$ENV{'user.name'};
                    232:         $tudom=$ENV{'user.domain'};
                    233:         $tcrsid=$ENV{'request.course.id'};
                    234:     }
1.116     www       235: 
1.118     www       236:     return &Apache::lonnet::checkout($symb,$tuname,$tudom,$tcrsid);
                    237: }
                    238: 
                    239: sub printtokenheader {
1.133     albertel  240:     my ($target,$token,$tsymb,$tcrsid,$tudom,$tuname)=@_;
1.116     www       241:     unless ($token) { return ''; }
1.118     www       242: 
1.133     albertel  243:     my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();
                    244:     unless ($tsymb) {
                    245: 	$tsymb=$symb;
1.118     www       246:     }
                    247:     unless ($tuname) {
1.133     albertel  248: 	$tuname=$name;
                    249:         $tudom=$domain;
                    250:         $tcrsid=$courseid;
1.118     www       251:     }
1.114     www       252: 
                    253:     my %reply=&Apache::lonnet::get('environment',
                    254:               ['firstname','middlename','lastname','generation'],
                    255:               $tudom,$tuname);
                    256:     my $plainname=$reply{'firstname'}.' '. 
                    257:                   $reply{'middlename'}.' '.
                    258:                   $reply{'lastname'}.' '.
                    259: 		  $reply{'generation'};
                    260: 
1.112     www       261:     if ($target eq 'web') {
1.145     www       262:         my %idhash=&Apache::lonnet::idrget($tudom,($tuname));
1.115     www       263: 	return 
1.221     albertel  264:  '<img align="right" src="/cgi-bin/barcode.png?encode='.$token.'" />'.
1.284     www       265:                &mt('Checked out for').' '.$plainname.
                    266:                '<br />'.&mt('User').': '.$tuname.' at '.$tudom.
                    267: 	       '<br />'.&mt('ID').': '.$idhash{$tuname}.
                    268: 	       '<br />'.&mt('CourseID').': '.$tcrsid.
                    269: 	       '<br />'.&mt('Course').': '.$ENV{'course.'.$tcrsid.'.description'}.
                    270:                '<br />'.&mt('DocID').': '.$token.
                    271:                '<br />'.&mt('Time').': '.&Apache::lonlocal::locallocaltime().'<hr />';
1.112     www       272:     } else {
1.121     albertel  273:         return $token;
1.112     www       274:     }
1.68      www       275: }
                    276: 
1.70      www       277: sub fontsettings() {
                    278:     my $headerstring='';
                    279:     if (($ENV{'browser.os'} eq 'mac') && (!$ENV{'browser.mathml'})) { 
1.248     albertel  280: 	$headerstring.=
                    281: 	    '<meta Content-Type="text/html; charset=x-mac-roman">';
1.263     albertel  282:     } elsif (!$ENV{'browser.mathml'} && $ENV{'browser.unicode'}) {
1.248     albertel  283: 	$headerstring.=
                    284: 	    '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1.70      www       285:     }
                    286:     return $headerstring;
1.68      www       287: }
                    288: 
1.48      albertel  289: sub printalltags {
                    290:   my $temp;
                    291:   foreach $temp (sort keys %Apache::lonxml::alltags) {
1.141     albertel  292:     &Apache::lonxml::debug("$temp -- ".
                    293: 		  join(',',@{ $Apache::lonxml::alltags{$temp} }));
1.48      albertel  294:   }
                    295: }
1.31      sakharuk  296: 
1.3       sakharuk  297: sub xmlparse {
1.172     albertel  298:  my ($request,$target,$content_file_string,$safeinit,%style_for_target) = @_;
1.96      albertel  299: 
1.172     albertel  300:  &setup_globals($request,$target);
1.232     albertel  301:  &Apache::inputtags::initialize_inputtags();
                    302:  &Apache::outputtags::initialize_outputtags();
                    303:  &Apache::edit::initialize_edit();
1.287     albertel  304:  &Apache::londefdef::initialize_londefdef();
1.244     albertel  305: 
1.178     www       306: #
                    307: # do we have a course style file?
                    308: #
                    309: 
1.208     albertel  310:  if ($ENV{'request.course.id'} && $ENV{'request.state'} ne 'construct') {
1.178     www       311:      my $bodytext=
                    312: 	 $ENV{'course.'.$ENV{'request.course.id'}.'.default_xml_style'};
                    313:      if ($bodytext) {
                    314:        my $location=&Apache::lonnet::filelocation('',$bodytext);
                    315:        my $styletext=&Apache::lonnet::getfile($location);
                    316:        if ($styletext ne '-1') {
                    317:           %style_for_target = (%style_for_target,
                    318:                           &Apache::style::styleparser($target,$styletext));
                    319:        }
                    320:     }
1.292     sakharuk  321:  } elsif ($ENV{'construct.style'} && ($ENV{'request.state'} eq 'construct')) {
                    322:      my $location=&Apache::lonnet::filelocation('',$ENV{'construct.style'});
1.291     sakharuk  323:      my $styletext=&Apache::lonnet::getfile($location);
                    324:        if ($styletext ne '-1') {
                    325:           %style_for_target = (%style_for_target,
                    326:                           &Apache::style::styleparser($target,$styletext));
                    327:       }
1.178     www       328:  }
1.255     sakharuk  329: #&printalltags();
1.16      albertel  330:  my @pars = ();
1.23      albertel  331:  my $pwd=$ENV{'request.filename'};
                    332:  $pwd =~ s:/[^/]*$::;
                    333:  &newparser(\@pars,\$content_file_string,$pwd);
1.24      sakharuk  334: 
1.3       sakharuk  335:  my $safeeval = new Safe;
1.40      albertel  336:  my $safehole = new Safe::Hole;
1.82      ng        337:  &init_safespace($target,$safeeval,$safehole,$safeinit);
1.3       sakharuk  338: #-------------------- Redefinition of the target in the case of compound target
                    339: 
                    340:  ($target, my @tenta) = split('&&',$target);
                    341: 
1.150     albertel  342:  my @stack = ();
1.3       sakharuk  343:  my @parstack = ();
1.17      albertel  344:  &initdepth;
1.67      www       345: 
1.101     albertel  346:  my $finaloutput = &inner_xmlparse($target,\@stack,\@parstack,\@pars,
                    347: 				   $safeeval,\%style_for_target);
1.255     sakharuk  348: 
1.125     www       349:  if ($ENV{'request.uri'}) {
                    350:     &writeallows($ENV{'request.uri'});
                    351:  }
1.281     albertel  352:  &do_registered_ssi();
1.204     albertel  353:  if ($Apache::lonxml::counter_changed) { &store_counter() }
1.3       sakharuk  354:  return $finaloutput;
1.106     www       355: }
                    356: 
                    357: sub htmlclean {
1.107     www       358:     my ($raw,$full)=@_;
1.106     www       359: 
                    360:     my $tree = HTML::TreeBuilder->new;
                    361:     $tree->ignore_unknown(0);
1.140     albertel  362: 
1.106     www       363:     $tree->parse($raw);
                    364: 
1.107     www       365:     my $output= $tree->as_HTML(undef,' ');
1.140     albertel  366: 
1.161     albertel  367:     $output=~s/\<(br|hr|img|meta|allow)(.*?)\>/\<$1$2 \/\>/gis;
1.111     www       368:     $output=~s/\<\/(br|hr|img|meta|allow)\>//gis;
1.107     www       369:     unless ($full) {
                    370:        $output=~s/\<[\/]*(body|head|html)\>//gis;
                    371:     }
1.106     www       372: 
                    373:     $tree = $tree->delete;
                    374: 
                    375:     return $output;
1.15      albertel  376: }
                    377: 
1.191     albertel  378: sub latex_special_symbols {
1.272     albertel  379:     my ($string,$where)=@_;
1.235     sakharuk  380:     if ($where eq 'header') {
1.272     albertel  381: 	$string =~ s/(\\|_|\^)/ /g;
1.311     albertel  382: 	$string =~ s/(\$|%|\{|\})/\\$1/g;
1.273     sakharuk  383: 	$string =~ s/_/ /g;
1.311     albertel  384: 	$string=&Apache::lonprintout::character_chart($string);
                    385: 	# any & or # leftover should be safe to just escape
                    386:         $string=~s/([^\\])\&/$1\\\&/g;
                    387:         $string=~s/([^\\])\#/$1\\\#/g;
1.229     sakharuk  388:     } else {
1.312     albertel  389: 	$string=~s/\\/\\ensuremath{\\backslash}/g;
1.313     albertel  390: 	$string=~s/([^\\]|^)\%/$1\\\%/g;
                    391: 	$string=~s/([^\\]|^)(\$|_)/$1\\$2/g;
1.310     sakharuk  392: 	$string=~s/\$\$/\$\\\$/g;
                    393: 	$string=~s/\#\#/\#\\\#/g;
1.313     albertel  394:         $string=~s/([^\\]|^)(\~|\^)/$1\\$2\\strut /g;
1.310     sakharuk  395: 	$string=~s/(>|<)/\\ensuremath\{$1\}/g; #more or less
1.311     albertel  396: 	$string=&Apache::lonprintout::character_chart($string);
                    397: 	# any & or # leftover should be safe to just escape
1.313     albertel  398:         $string=~s/([^\\]|^)\&/$1\\\&/g;
                    399:         $string=~s/([^\\]|^)\#/$1\\\#/g;
1.310     sakharuk  400: #single { or } How to escape?
1.229     sakharuk  401:     }
1.272     albertel  402:     return $string;
1.188     sakharuk  403: }
                    404: 
1.101     albertel  405: sub inner_xmlparse {
                    406:   my ($target,$stack,$parstack,$pars,$safeeval,$style_for_target)=@_;
                    407:   my $finaloutput = '';
                    408:   my $result;
                    409:   my $token;
1.258     albertel  410:   my $dontpop=0;
1.101     albertel  411:   while ( $#$pars > -1 ) {
                    412:     while ($token = $$pars['-1']->get_token) {
1.261     albertel  413:       if (($token->[0] eq 'T') || ($token->[0] eq 'C') ) {
1.101     albertel  414: 	if ($metamode<1) {
1.190     albertel  415: 	    my $text=$token->[1];
1.193     albertel  416: 	    if ($token->[0] eq 'C' && $target eq 'tex') {
1.239     sakharuk  417: 		$text = '';
                    418: #		$text = '%'.$text."\n";
1.182     sakharuk  419: 	    }
1.190     albertel  420: 	    $result.=$text;
1.101     albertel  421: 	}
1.261     albertel  422:       } elsif (($token->[0] eq 'D')) {
                    423: 	if ($metamode<1 && $target eq 'web') {
                    424: 	    my $text=$token->[1];
                    425: 	    $result.=$text;
                    426: 	}
1.101     albertel  427:       } elsif ($token->[0] eq 'PI') {
1.261     albertel  428: 	if ($metamode<1 && $target eq 'web') {
1.101     albertel  429: 	  $result=$token->[2];
                    430: 	}
                    431:       } elsif ($token->[0] eq 'S') {
1.140     albertel  432: 	# add tag to stack
1.101     albertel  433: 	push (@$stack,$token->[1]);
                    434: 	# add parameters list to another stack
                    435: 	push (@$parstack,&parstring($token));
1.140     albertel  436: 	&increasedepth($token);
1.212     albertel  437: 	if ($Apache::lonxml::usestyle &&
                    438: 	    exists($$style_for_target{$token->[1]})) {
                    439: 	    $Apache::lonxml::usestyle=0;
                    440: 	    my $string=$$style_for_target{$token->[1]}.
                    441: 	      '<LONCAPA_INTERNAL_TURN_STYLE_ON />';
                    442: 	    &Apache::lonxml::newparser($pars,\$string);
1.257     albertel  443: 	    $Apache::lonxml::style_values=$$parstack[-1];
1.259     albertel  444: 	    $Apache::lonxml::style_end_values=$$parstack[-1];
1.101     albertel  445: 	} else {
                    446: 	  $result = &callsub("start_$token->[1]", $target, $token, $stack,
                    447: 			     $parstack, $pars, $safeeval, $style_for_target);
1.140     albertel  448: 	}
1.101     albertel  449:       } elsif ($token->[0] eq 'E') {
1.212     albertel  450: 	if ($Apache::lonxml::usestyle &&
                    451: 	    exists($$style_for_target{'/'."$token->[1]"})) {
                    452: 	    $Apache::lonxml::usestyle=0;
                    453: 	    my $string=$$style_for_target{'/'.$token->[1]}.
1.258     albertel  454: 	      '<LONCAPA_INTERNAL_TURN_STYLE_ON end="'.$token->[1].'" />';
1.212     albertel  455: 	    &Apache::lonxml::newparser($pars,\$string);
1.259     albertel  456: 	    $Apache::lonxml::style_values=$Apache::lonxml::style_end_values;
                    457: 	    $Apache::lonxml::style_end_values='';
1.258     albertel  458: 	    $dontpop=1;
1.101     albertel  459: 	} else {
1.258     albertel  460: 	    #clear out any tags that didn't end
                    461: 	    while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) {
                    462: 		my $lasttag=$$stack[-1];
1.317     albertel  463: 		if ($token->[1] =~ /^\Q$lasttag\E$/i) {
1.258     albertel  464: 		    &Apache::lonxml::warning('Using tag &lt;/'.$token->[1].'&gt; on line '.$token->[3].' as end tag to &lt;'.$$stack[-1].'&gt;');
                    465: 		    last;
                    466: 		} else {
                    467: 		    &Apache::lonxml::warning('Found tag &lt;/'.$token->[1].'&gt; on line '.$token->[3].' when looking for &lt;/'.$$stack[-1].'&gt; in file');
                    468: 		    &end_tag($stack,$parstack,$token);
                    469: 		}
                    470: 	    }
                    471: 	    $result = &callsub("end_$token->[1]", $target, $token, $stack,
                    472: 			       $parstack, $pars,$safeeval, $style_for_target);
1.101     albertel  473: 	}
                    474:       } else {
                    475: 	&Apache::lonxml::error("Unknown token event :$token->[0]:$token->[1]:");
                    476:       }
                    477:       #evaluate variable refs in result
1.282     albertel  478:       if ($Apache::lonxml::post_evaluate &&$result ne "") {
1.257     albertel  479: 	  my $extras;
                    480: 	  if (!$Apache::lonxml::usestyle) {
                    481: 	      $extras=$Apache::lonxml::style_values;
                    482: 	  }
1.101     albertel  483: 	if ( $#$parstack > -1 ) {
1.257     albertel  484: 	  $result=&Apache::run::evaluate($result,$safeeval,$extras.$$parstack[-1]);
1.101     albertel  485: 	} else {
1.257     albertel  486: 	  $result= &Apache::run::evaluate($result,$safeeval,$extras);
1.101     albertel  487: 	}
1.163     albertel  488:       }
1.282     albertel  489:       $Apache::lonxml::post_evaluate=1;
                    490: 
1.190     albertel  491:       if (($token->[0] eq 'T') || ($token->[0] eq 'C') || ($token->[0] eq 'D') ) {
1.249     albertel  492: 	  #Style file definitions should be correct
1.250     albertel  493: 	  if ($target eq 'tex' && ($Apache::lonxml::usestyle)) {
1.311     albertel  494: 	      $result=&latex_special_symbols($result);
1.249     albertel  495: 	  }
1.190     albertel  496:       }
                    497: 
1.169     albertel  498:       if ($Apache::lonxml::redirection) {
                    499: 	$Apache::lonxml::outputstack['-1'] .= $result;
                    500:       } else {
                    501: 	$finaloutput.=$result;
                    502:       }
                    503:       $result = '';
                    504: 
1.258     albertel  505:       if ($token->[0] eq 'E' && !$dontpop) {
1.101     albertel  506: 	&end_tag($stack,$parstack,$token);
                    507:       }
1.258     albertel  508:       $dontpop=0;
1.224     albertel  509:     }	
1.212     albertel  510:     if ($#$pars > -1) {
                    511: 	pop @$pars;
                    512: 	pop @Apache::lonxml::pwd;
                    513:     }
1.101     albertel  514:   }
                    515: 
                    516:   # if ($target eq 'meta') {
                    517:   #   $finaloutput.=&endredirection;
                    518:   # }
                    519: 
1.169     albertel  520: 
1.101     albertel  521:   if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) {
                    522:     $finaloutput=&afterburn($finaloutput);
1.216     sakharuk  523:   }	    
1.101     albertel  524:   return $finaloutput;
                    525: }
1.67      www       526: 
1.318     matthew   527: ## 
                    528: ## Looks to see if there is a subroutine defined for this tag.  If so, call it,
                    529: ## otherwise do not call it as we do not know what it is.
                    530: ##
1.7       albertel  531: sub callsub {
1.84      albertel  532:   my ($sub,$target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.7       albertel  533:   my $currentstring='';
1.72      albertel  534:   my $nodefault;
1.7       albertel  535:   {
1.59      albertel  536:     my $sub1;
1.7       albertel  537:     no strict 'refs';
1.68      www       538:     my $tag=$token->[1];
1.236     www       539: # get utterly rid of extended html tags
                    540:     if ($tag=~/^x\-/i) { return ''; }
1.141     albertel  541:     my $space=$Apache::lonxml::alltags{$tag}[-1];
1.68      www       542:     if (!$space) {
1.141     albertel  543:      	$tag=~tr/A-Z/a-z/;
1.68      www       544: 	$sub=~tr/A-Z/a-z/;
1.141     albertel  545: 	$space=$Apache::lonxml::alltags{$tag}[-1]
1.68      www       546:     }
1.97      albertel  547: 
                    548:     my $deleted=0;
                    549:     $Apache::lonxml::curdepth=join('_',@Apache::lonxml::depthcounter);
                    550:     if (($token->[0] eq 'S') && ($target eq 'modified')) {
                    551:       $deleted=&Apache::edit::handle_delete($space,$target,$token,$tagstack,
                    552: 					     $parstack,$parser,$safeeval,
                    553: 					     $style);
                    554:     }
                    555:     if (!$deleted) {
                    556:       if ($space) {
1.220     albertel  557: 	#&Apache::lonxml::debug("Calling sub $sub in $space $metamode");
1.97      albertel  558: 	$sub1="$space\:\:$sub";
                    559: 	($currentstring,$nodefault) = &$sub1($target,$token,$tagstack,
                    560: 					     $parstack,$parser,$safeeval,
                    561: 					     $style);
                    562:       } else {
1.318     matthew   563:           if ($target eq 'tex') {
                    564:               # throw away tag name
                    565:               return '';
                    566:           }
1.220     albertel  567: 	#&Apache::lonxml::debug("NOT Calling sub $sub in $space $metamode");
1.97      albertel  568: 	if ($metamode <1) {
                    569: 	  if (defined($token->[4]) && ($metamode < 1)) {
                    570: 	    $currentstring = $token->[4];
                    571: 	  } else {
                    572: 	    $currentstring = $token->[2];
                    573: 	  }
1.62      sakharuk  574: 	}
1.7       albertel  575:       }
1.97      albertel  576:       #    &Apache::lonxml::debug("nodefalt:$nodefault:");
                    577:       if ($currentstring eq '' && $nodefault eq '') {
                    578: 	if ($target eq 'edit') {
1.220     albertel  579: 	  #&Apache::lonxml::debug("doing default edit for $token->[1]");
1.97      albertel  580: 	  if ($token->[0] eq 'S') {
                    581: 	    $currentstring = &Apache::edit::tag_start($target,$token);
                    582: 	  } elsif ($token->[0] eq 'E') {
                    583: 	    $currentstring = &Apache::edit::tag_end($target,$token);
                    584: 	  }
                    585: 	} elsif ($target eq 'modified') {
                    586: 	  if ($token->[0] eq 'S') {
                    587: 	    $currentstring = $token->[4];
                    588: 	    $currentstring.=&Apache::edit::handle_insert();
1.210     www       589: 	  } elsif ($token->[0] eq 'E') {
                    590: 	    $currentstring = $token->[2];
                    591:             $currentstring.=&Apache::edit::handle_insertafter($token->[1]);
1.97      albertel  592: 	  } else {
                    593: 	    $currentstring = $token->[2];
                    594: 	  }
1.72      albertel  595: 	}
                    596:       }
1.7       albertel  597:     }
                    598:     use strict 'refs';
                    599:   }
                    600:   return $currentstring;
1.82      ng        601: }
                    602: 
1.96      albertel  603: sub setup_globals {
1.172     albertel  604:   my ($request,$target)=@_;
                    605:   $Apache::lonxml::request=$request;
1.99      albertel  606:   $Apache::lonxml::registered = 0;
1.205     www       607:   $errorcount=0;
                    608:   $warningcount=0;
1.207     albertel  609:   $Apache::lonxml::default_homework_loaded=0;
1.212     albertel  610:   $Apache::lonxml::usestyle=1;
1.204     albertel  611:   &init_counter();
1.101     albertel  612:   @Apache::lonxml::pwd=();
1.124     albertel  613:   @Apache::lonxml::extlinks=();
1.281     albertel  614:   @Apache::lonxml::ssi_info=();
1.282     albertel  615:   $Apache::lonxml::post_evaluate=1;
1.295     albertel  616:   $Apache::lonxml::warnings_error_header='';
1.96      albertel  617:   if ($target eq 'meta') {
                    618:     $Apache::lonxml::redirection = 0;
                    619:     $Apache::lonxml::metamode = 1;
                    620:     $Apache::lonxml::evaluate = 1;
                    621:     $Apache::lonxml::import = 0;
1.129     albertel  622:   } elsif ($target eq 'answer') {
                    623:     $Apache::lonxml::redirection = 0;
                    624:     $Apache::lonxml::metamode = 1;
                    625:     $Apache::lonxml::evaluate = 1;
                    626:     $Apache::lonxml::import = 1;
1.96      albertel  627:   } elsif ($target eq 'grade') {
                    628:     &startredirection;
                    629:     $Apache::lonxml::metamode = 0;
                    630:     $Apache::lonxml::evaluate = 1;
                    631:     $Apache::lonxml::import = 1;
                    632:   } elsif ($target eq 'modified') {
                    633:     $Apache::lonxml::redirection = 0;
                    634:     $Apache::lonxml::metamode = 0;
                    635:     $Apache::lonxml::evaluate = 0;
                    636:     $Apache::lonxml::import = 0;
                    637:   } elsif ($target eq 'edit') {
                    638:     $Apache::lonxml::redirection = 0;
                    639:     $Apache::lonxml::metamode = 0;
                    640:     $Apache::lonxml::evaluate = 0;
                    641:     $Apache::lonxml::import = 0;
1.163     albertel  642:   } elsif ($target eq 'analyze') {
                    643:     $Apache::lonxml::redirection = 0;
                    644:     $Apache::lonxml::metamode = 0;
                    645:     $Apache::lonxml::evaluate = 1;
                    646:     $Apache::lonxml::import = 1;
1.96      albertel  647:   } else {
                    648:     $Apache::lonxml::redirection = 0;
                    649:     $Apache::lonxml::metamode = 0;
                    650:     $Apache::lonxml::evaluate = 1;
                    651:     $Apache::lonxml::import = 1;
                    652:   }
                    653: }
                    654: 
1.82      ng        655: sub init_safespace {
                    656:   my ($target,$safeeval,$safehole,$safeinit) = @_;
                    657:   $safeeval->permit("entereval");
                    658:   $safeeval->permit(":base_math");
                    659:   $safeeval->permit("sort");
1.286     albertel  660:   $safeeval->permit("time");
1.82      ng        661:   $safeeval->deny(":base_io");
1.102     albertel  662:   $safehole->wrap(\&Apache::scripttag::xmlparse,$safeeval,'&xmlparse');
1.251     albertel  663:   $safehole->wrap(\&Apache::outputtags::multipart,$safeeval,'&multipart');
1.82      ng        664:   $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT');
                    665:   
                    666:   $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin');
                    667:   $safehole->wrap(\&Math::Cephes::acos,$safeeval,'&acos');
                    668:   $safehole->wrap(\&Math::Cephes::atan,$safeeval,'&atan');
                    669:   $safehole->wrap(\&Math::Cephes::sinh,$safeeval,'&sinh');
                    670:   $safehole->wrap(\&Math::Cephes::cosh,$safeeval,'&cosh');
                    671:   $safehole->wrap(\&Math::Cephes::tanh,$safeeval,'&tanh');
                    672:   $safehole->wrap(\&Math::Cephes::asinh,$safeeval,'&asinh');
                    673:   $safehole->wrap(\&Math::Cephes::acosh,$safeeval,'&acosh');
                    674:   $safehole->wrap(\&Math::Cephes::atanh,$safeeval,'&atanh');
                    675:   $safehole->wrap(\&Math::Cephes::erf,$safeeval,'&erf');
                    676:   $safehole->wrap(\&Math::Cephes::erfc,$safeeval,'&erfc');
                    677:   $safehole->wrap(\&Math::Cephes::j0,$safeeval,'&j0');
                    678:   $safehole->wrap(\&Math::Cephes::j1,$safeeval,'&j1');
                    679:   $safehole->wrap(\&Math::Cephes::jn,$safeeval,'&jn');
                    680:   $safehole->wrap(\&Math::Cephes::jv,$safeeval,'&jv');
                    681:   $safehole->wrap(\&Math::Cephes::y0,$safeeval,'&y0');
                    682:   $safehole->wrap(\&Math::Cephes::y1,$safeeval,'&y1');
                    683:   $safehole->wrap(\&Math::Cephes::yn,$safeeval,'&yn');
                    684:   $safehole->wrap(\&Math::Cephes::yv,$safeeval,'&yv');
1.215     albertel  685:   
                    686:   $safehole->wrap(\&Math::Cephes::bdtr  ,$safeeval,'&bdtr'  );
                    687:   $safehole->wrap(\&Math::Cephes::bdtrc ,$safeeval,'&bdtrc' );
                    688:   $safehole->wrap(\&Math::Cephes::bdtri ,$safeeval,'&bdtri' );
                    689:   $safehole->wrap(\&Math::Cephes::btdtr ,$safeeval,'&btdtr' );
                    690:   $safehole->wrap(\&Math::Cephes::chdtr ,$safeeval,'&chdtr' );
                    691:   $safehole->wrap(\&Math::Cephes::chdtrc,$safeeval,'&chdtrc');
                    692:   $safehole->wrap(\&Math::Cephes::chdtri,$safeeval,'&chdtri');
                    693:   $safehole->wrap(\&Math::Cephes::fdtr  ,$safeeval,'&fdtr'  );
                    694:   $safehole->wrap(\&Math::Cephes::fdtrc ,$safeeval,'&fdtrc' );
                    695:   $safehole->wrap(\&Math::Cephes::fdtri ,$safeeval,'&fdtri' );
                    696:   $safehole->wrap(\&Math::Cephes::gdtr  ,$safeeval,'&gdtr'  );
                    697:   $safehole->wrap(\&Math::Cephes::gdtrc ,$safeeval,'&gdtrc' );
                    698:   $safehole->wrap(\&Math::Cephes::nbdtr ,$safeeval,'&nbdtr' );
                    699:   $safehole->wrap(\&Math::Cephes::nbdtrc,$safeeval,'&nbdtrc');
                    700:   $safehole->wrap(\&Math::Cephes::nbdtri,$safeeval,'&nbdtri');
                    701:   $safehole->wrap(\&Math::Cephes::ndtr  ,$safeeval,'&ndtr'  );
                    702:   $safehole->wrap(\&Math::Cephes::ndtri ,$safeeval,'&ndtri' );
                    703:   $safehole->wrap(\&Math::Cephes::pdtr  ,$safeeval,'&pdtr'  );
                    704:   $safehole->wrap(\&Math::Cephes::pdtrc ,$safeeval,'&pdtrc' );
                    705:   $safehole->wrap(\&Math::Cephes::pdtri ,$safeeval,'&pdtri' );
                    706:   $safehole->wrap(\&Math::Cephes::stdtr ,$safeeval,'&stdtr' );
                    707:   $safehole->wrap(\&Math::Cephes::stdtri,$safeeval,'&stdtri');
                    708: 
                    709: #  $safehole->wrap(\&Math::Cephes::new_fract,$safeeval,'&new_fract');
                    710: #  $safehole->wrap(\&Math::Cephes::radd,$safeeval,'&radd');
                    711: #  $safehole->wrap(\&Math::Cephes::rsub,$safeeval,'&rsub');
                    712: #  $safehole->wrap(\&Math::Cephes::rmul,$safeeval,'&rmul');
                    713: #  $safehole->wrap(\&Math::Cephes::rdiv,$safeeval,'&rdiv');
                    714: #  $safehole->wrap(\&Math::Cephes::euclid,$safeeval,'&euclid');
                    715: 
1.91      ng        716:   $safehole->wrap(\&Math::Random::random_beta,$safeeval,'&math_random_beta');
                    717:   $safehole->wrap(\&Math::Random::random_chi_square,$safeeval,'&math_random_chi_square');
                    718:   $safehole->wrap(\&Math::Random::random_exponential,$safeeval,'&math_random_exponential');
                    719:   $safehole->wrap(\&Math::Random::random_f,$safeeval,'&math_random_f');
                    720:   $safehole->wrap(\&Math::Random::random_gamma,$safeeval,'&math_random_gamma');
                    721:   $safehole->wrap(\&Math::Random::random_multivariate_normal,$safeeval,'&math_random_multivariate_normal');
                    722:   $safehole->wrap(\&Math::Random::random_multinomial,$safeeval,'&math_random_multinomial');
                    723:   $safehole->wrap(\&Math::Random::random_noncentral_chi_square,$safeeval,'&math_random_noncentral_chi_square');
                    724:   $safehole->wrap(\&Math::Random::random_noncentral_f,$safeeval,'&math_random_noncentral_f');
                    725:   $safehole->wrap(\&Math::Random::random_normal,$safeeval,'&math_random_normal');
                    726:   $safehole->wrap(\&Math::Random::random_permutation,$safeeval,'&math_random_permutation');
1.93      ng        727:   $safehole->wrap(\&Math::Random::random_permuted_index,$safeeval,'&math_random_permuted_index');
1.91      ng        728:   $safehole->wrap(\&Math::Random::random_uniform,$safeeval,'&math_random_uniform');
                    729:   $safehole->wrap(\&Math::Random::random_poisson,$safeeval,'&math_random_poisson');
                    730:   $safehole->wrap(\&Math::Random::random_uniform_integer,$safeeval,'&math_random_uniform_integer');
                    731:   $safehole->wrap(\&Math::Random::random_negative_binomial,$safeeval,'&math_random_negative_binomial');
                    732:   $safehole->wrap(\&Math::Random::random_binomial,$safeeval,'&math_random_binomial');
                    733:   $safehole->wrap(\&Math::Random::random_seed_from_phrase,$safeeval,'&random_seed_from_phrase');
                    734:   $safehole->wrap(\&Math::Random::random_set_seed_from_phrase,$safeeval,'&random_set_seed_from_phrase');
                    735:   $safehole->wrap(\&Math::Random::random_get_seed,$safeeval,'&random_get_seed');
                    736:   $safehole->wrap(\&Math::Random::random_set_seed,$safeeval,'&random_set_seed');
1.305     albertel  737:   $safehole->wrap(\&Apache::lonxml::error,$safeeval,'&LONCAPA_INTERNAL_ERROR');
1.311     albertel  738:   $safehole->wrap(\&Apache::lonxml::debug,$safeeval,'&LONCAPA_INTERNAL_DEBUG');
1.322     albertel  739:   $safehole->wrap(\&Apache::caparesponse::get_sigrange,$safeeval,'&LONCAPA_INTERNAL_get_sigrange');
1.91      ng        740: 
1.82      ng        741: #need to inspect this class of ops
                    742: # $safeeval->deny(":base_orig");
1.91      ng        743:   $safeinit .= ';$external::target="'.$target.'";';
1.121     albertel  744:   my $rndseed;
1.123     albertel  745:   my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();
                    746:   $rndseed=&Apache::lonnet::rndseed($symb,$courseid,$domain,$name);
1.319     albertel  747:   $safeinit .= ';$external::randomseed="'.$rndseed.'";';
1.249     albertel  748:   &Apache::lonxml::debug("Setting rndseed to $rndseed");
1.82      ng        749:   &Apache::run::run($safeinit,$safeeval);
1.303     albertel  750: 
                    751:   my $subroutine=<<'EVALUATESUB';
                    752: sub __LC_INTERNAL_EVALUATE__ {
                    753:     my ($__LC__a,$__LC__b,$__LC__c)=@_;
                    754:     my $__LC__prefix;
                    755:     while(1){
                    756: 	{ 
1.306     albertel  757: 	    use strict;
                    758: 	    no strict "vars";
1.303     albertel  759: 	    if (eval(defined(eval($__LC__a.$__LC__b)))) {
1.306     albertel  760: 		return $__LC__prefix.eval($__LC__a.$__LC__b.$__LC__c);
1.303     albertel  761: 	    }
                    762: 	}
                    763: 	$__LC__prefix.=substr($__LC__a,0,1,"");
                    764: 	if ($__LC__a!~/^(\$|&|\#)/) { last; }
                    765:     }
1.306     albertel  766:     return $__LC__prefix.$__LC__a.$__LC__b.$__LC__c;
1.303     albertel  767: }
                    768: EVALUATESUB
                    769:     $safeeval->permit("require");
                    770:     $safeeval->reval($subroutine);
                    771:     $safeeval->deny("require");
1.207     albertel  772: }
                    773: 
                    774: sub default_homework_load {
                    775:     my ($safeeval)=@_;
                    776:     &Apache::lonxml::debug('Loading default_homework');
                    777:     my $default=&Apache::lonnet::getfile('/home/httpd/html/res/adm/includes/default_homework.lcpm');
1.241     albertel  778:     if ($default eq -1) {
1.207     albertel  779: 	&Apache::lonxml::error("<b>Unable to find <i>default_homework.lcpm</i></b>");
                    780:     } else {
                    781: 	&Apache::run::run($default,$safeeval);
                    782: 	$Apache::lonxml::default_homework_loaded=1;
                    783:     }
1.17      albertel  784: }
                    785: 
1.55      albertel  786: sub startredirection {
                    787:   $Apache::lonxml::redirection++;
                    788:   push (@Apache::lonxml::outputstack, '');
                    789: }
                    790: 
                    791: sub endredirection {
                    792:   if (!$Apache::lonxml::redirection) {
1.72      albertel  793:     &Apache::lonxml::error("Endredirection was called, before a startredirection, perhaps you have unbalanced tags. Some debuging information:".join ":",caller);
1.55      albertel  794:     return '';
                    795:   }
                    796:   $Apache::lonxml::redirection--;
                    797:   pop @Apache::lonxml::outputstack;
1.97      albertel  798: }
                    799: 
                    800: sub end_tag {
                    801:   my ($tagstack,$parstack,$token)=@_;
                    802:   pop(@$tagstack);
                    803:   pop(@$parstack);
                    804:   &decreasedepth($token);
1.55      albertel  805: }
                    806: 
1.17      albertel  807: sub initdepth {
                    808:   @Apache::lonxml::depthcounter=();
                    809:   $Apache::lonxml::depth=-1;
                    810:   $Apache::lonxml::olddepth=-1;
                    811: }
                    812: 
                    813: sub increasedepth {
1.19      albertel  814:   my ($token) = @_;
1.17      albertel  815:   $Apache::lonxml::depth++;
                    816:   $Apache::lonxml::depthcounter[$Apache::lonxml::depth]++;
                    817:   if ($Apache::lonxml::depthcounter[$Apache::lonxml::depth]==1) {
                    818:     $Apache::lonxml::olddepth=$Apache::lonxml::depth;
                    819:   }
1.42      albertel  820:   my $curdepth=join('_',@Apache::lonxml::depthcounter);
1.64      albertel  821:   &Apache::lonxml::debug("s $Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1]\n");
1.54      albertel  822: #print "<br />s $Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1]\n";
1.17      albertel  823: }
                    824: 
                    825: sub decreasedepth {
1.19      albertel  826:   my ($token) = @_;
1.17      albertel  827:   $Apache::lonxml::depth--;
1.36      albertel  828:   if ($Apache::lonxml::depth<$Apache::lonxml::olddepth-1) {
                    829:     $#Apache::lonxml::depthcounter--;
                    830:     $Apache::lonxml::olddepth=$Apache::lonxml::depth+1;
                    831:   }
1.43      albertel  832:   if (  $Apache::lonxml::depth < -1) {
1.280     www       833:     &Apache::lonxml::warning(&mt("Missing tags, unable to properly run file."));
1.43      albertel  834:     $Apache::lonxml::depth='-1';
                    835:   }
1.42      albertel  836:   my $curdepth=join('_',@Apache::lonxml::depthcounter);
1.64      albertel  837:   &Apache::lonxml::debug("e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n");
1.54      albertel  838: #print "<br />e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n";
1.1       sakharuk  839: }
1.19      albertel  840: 
1.180     albertel  841: sub get_all_text_unbalanced {
1.190     albertel  842: #there is a copy of this in lonpublisher.pm
1.180     albertel  843:  my($tag,$pars)= @_;
                    844:  my $token;
                    845:  my $result='';
                    846:  $tag='<'.$tag.'>';
                    847:  while ($token = $$pars[-1]->get_token) {
                    848:    if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
                    849:      $result.=$token->[1];
                    850:    } elsif ($token->[0] eq 'PI') {
                    851:      $result.=$token->[2];
                    852:    } elsif ($token->[0] eq 'S') {
                    853:      $result.=$token->[4];
                    854:    } elsif ($token->[0] eq 'E')  {
                    855:      $result.=$token->[2];
                    856:    }
1.316     albertel  857:    if ($result =~ /(.*)\Q$tag\E(.*)/is) {
1.180     albertel  858:      &Apache::lonxml::debug('Got a winner with leftovers ::'.$2);
                    859:      &Apache::lonxml::debug('Result is :'.$1);
                    860:      $result=$1;
                    861:      my $redo=$tag.$2;
                    862:      &Apache::lonxml::newparser($pars,\$redo);
                    863:      last;
                    864:    }
                    865:  }
                    866:  return $result
1.204     albertel  867: }
                    868: 
                    869: sub increment_counter {
1.247     albertel  870:     my ($increment) = @_;
1.289     sakharuk  871:     if (defined($increment) && $increment gt 0) {
                    872: 	$Apache::lonxml::counter+=$increment;
                    873:     } else {
                    874: 	$Apache::lonxml::counter++;
1.247     albertel  875:     }
1.289     sakharuk  876:     $Apache::lonxml::counter_changed=1;
1.204     albertel  877: }
                    878: 
                    879: sub init_counter {
                    880:     if (defined($ENV{'form.counter'})) {
                    881: 	$Apache::lonxml::counter=$ENV{'form.counter'};
1.247     albertel  882: 	$Apache::lonxml::counter_changed=0;
1.237     sakharuk  883:     } else {
1.204     albertel  884: 	$Apache::lonxml::counter=1;
1.247     albertel  885: 	$Apache::lonxml::counter_changed=1;
1.204     albertel  886:     }
                    887: }
                    888: 
                    889: sub store_counter {
                    890:     &Apache::lonnet::appenv(('form.counter' => $Apache::lonxml::counter));
                    891:     return '';
1.180     albertel  892: }
                    893: 
1.19      albertel  894: sub get_all_text {
1.270     albertel  895:     my($tag,$pars,$style)= @_;
                    896:     my $gotfullstack=1;
                    897:     if (ref($pars) ne 'ARRAY') {
                    898: 	$gotfullstack=0;
                    899: 	$pars=[$pars];
                    900:     }
                    901:     if (ref($style) ne 'HASH') {
                    902: 	$style={};
                    903:     }
                    904:     my $depth=0;
                    905:     my $token;
                    906:     my $result='';
                    907:     if ( $tag =~ m:^/: ) { 
                    908: 	my $tag=substr($tag,1); 
                    909: 	#&Apache::lonxml::debug("have:$tag:");
                    910: 	my $top_empty=0;
                    911: 	while (($depth >=0) && ($#$pars > -1) && (!$top_empty)) {
                    912: 	    while (($depth >=0) && ($token = $$pars[-1]->get_token)) {
                    913: 		#&Apache::lonxml::debug("e token:$token->[0]:$depth:$token->[1]:".$#$pars.":".$#Apache::lonxml::pwd);
                    914: 		if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) {
                    915: 		    $result.=$token->[1];
                    916: 		} elsif ($token->[0] eq 'PI') {
                    917: 		    $result.=$token->[2];
                    918: 		} elsif ($token->[0] eq 'S') {
1.316     albertel  919: 		    if ($token->[1] =~ /^\Q$tag\E$/i) { $depth++; }
                    920: 		    if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_ON$/) { $Apache::lonxml::usestyle=1; }
                    921: 		    if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_OFF$/) { $Apache::lonxml::usestyle=0; }
1.270     albertel  922: 		    $result.=$token->[4];
                    923: 		} elsif ($token->[0] eq 'E')  {
1.316     albertel  924: 		    if ( $token->[1] =~ /^\Q$tag\E$/i) { $depth--; }
1.270     albertel  925: 		    #skip sending back the last end tag
1.283     albertel  926: 		    if ($depth == 0 && exists($$style{'/'.$token->[1]}) && $Apache::lonxml::usestyle) {
1.270     albertel  927: 			my $string=
                    928: 			    '<LONCAPA_INTERNAL_TURN_STYLE_OFF end="yes" />'.
                    929: 				$$style{'/'.$token->[1]}.
                    930: 				    $token->[2].
                    931: 					'<LONCAPA_INTERNAL_TURN_STYLE_ON />';
                    932: 			&Apache::lonxml::newparser($pars,\$string);
                    933: 			#&Apache::lonxml::debug("reParsing $string");
                    934: 			next;
                    935: 		    }
                    936: 		    if ($depth > -1) {
                    937: 			$result.=$token->[2];
                    938: 		    } else {
                    939: 			$$pars[-1]->unget_token($token);
                    940: 		    }
                    941: 		}
                    942: 	    }
                    943: 	    if (($depth >=0) && ($#$pars == 0) ) { $top_empty=1; }
                    944: 	    if (($depth >=0) && ($#$pars > 0) ) {
                    945: 		pop(@$pars);
                    946: 		pop(@Apache::lonxml::pwd);
                    947: 	    }
                    948: 	}
                    949: 	if ($top_empty && $depth >= 0) {
                    950: 	    #never found the end tag ran out of text, throw error send back blank
                    951: 	    &error('Never found end tag for &lt;'.$tag.
                    952: 		   '&gt; current string <pre>'.
1.314     albertel  953: 		   &HTML::Entities::encode($result,'<>&"').
1.270     albertel  954: 		   '</pre>');
                    955: 	    if ($gotfullstack) {
                    956: 		my $newstring='</'.$tag.'>'.$result;
                    957: 		&Apache::lonxml::newparser($pars,\$newstring);
                    958: 	    }
                    959: 	    $result='';
                    960: 	}
                    961:     } else {
                    962: 	while ($#$pars > -1) {
                    963: 	    while ($token = $$pars[-1]->get_token) {
                    964: 		#&Apache::lonxml::debug("s token:$token->[0]:$depth:$token->[1]");
                    965: 		if (($token->[0] eq 'T')||($token->[0] eq 'C')||
                    966: 		    ($token->[0] eq 'D')) {
                    967: 		    $result.=$token->[1];
                    968: 		} elsif ($token->[0] eq 'PI') {
                    969: 		    $result.=$token->[2];
                    970: 		} elsif ($token->[0] eq 'S') {
1.316     albertel  971: 		    if ( $token->[1] =~ /^\Q$tag\E$/i) {
1.270     albertel  972: 			$$pars[-1]->unget_token($token); last;
                    973: 		    } else {
                    974: 			$result.=$token->[4];
                    975: 		    }
1.316     albertel  976: 		    if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_ON$/) { $Apache::lonxml::usestyle=1; }
                    977: 		    if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_OFF$/) { $Apache::lonxml::usestyle=0; }
1.270     albertel  978: 		} elsif ($token->[0] eq 'E')  {
                    979: 		    $result.=$token->[2];
                    980: 		}
                    981: 	    }
                    982: 	    if (($#$pars > 0) ) {
                    983: 		pop(@$pars);
                    984: 		pop(@Apache::lonxml::pwd);
                    985: 	    } else { last; }
                    986: 	}
                    987:     }
                    988:     #&Apache::lonxml::debug("Exit:$result:");
                    989:     return $result
1.19      albertel  990: }
                    991: 
1.23      albertel  992: sub newparser {
                    993:   my ($parser,$contentref,$dir) = @_;
1.167     albertel  994:   push (@$parser,HTML::LCParser->new($contentref));
1.56      albertel  995:   $$parser['-1']->xml_mode('1');
1.23      albertel  996:   if ( $dir eq '' ) {
                    997:     push (@Apache::lonxml::pwd, $Apache::lonxml::pwd[$#Apache::lonxml::pwd]);
                    998:   } else {
                    999:     push (@Apache::lonxml::pwd, $dir);
                   1000:   } 
                   1001: }
1.1       sakharuk 1002: 
1.8       albertel 1003: sub parstring {
                   1004:   my ($token) = @_;
                   1005:   my $temp='';
1.142     albertel 1006:   foreach (@{$token->[3]}) {
1.35      www      1007:     unless ($_=~/\W/) {
1.42      albertel 1008:       my $val=$token->[2]->{$_};
1.231     albertel 1009:       $val =~ s/([\%\@\\\"\'])/\\$1/g;
1.51      albertel 1010:       #if ($val =~ m/^[\%\@]/) { $val="\\".$val; }
1.267     sakharuk 1011:       $temp .= "my \$$_=\"$val\";";
1.20      albertel 1012:     }
1.142     albertel 1013:   }
1.8       albertel 1014:   return $temp;
                   1015: }
1.22      albertel 1016: 
1.34      www      1017: sub writeallows {
1.126     www      1018:     unless ($#extlinks>=0) { return; }
1.34      www      1019:     my $thisurl='/res/'.&Apache::lonnet::declutter(shift);
1.111     www      1020:     if ($ENV{'httpref.'.$thisurl}) {
                   1021: 	$thisurl=$ENV{'httpref.'.$thisurl};
                   1022:     }
1.34      www      1023:     my $thisdir=$thisurl;
                   1024:     $thisdir=~s/\/[^\/]+$//;
                   1025:     my %httpref=();
1.142     albertel 1026:     foreach (@extlinks) {
1.34      www      1027:        $httpref{'httpref.'.
1.125     www      1028:  	        &Apache::lonnet::hreflocation($thisdir,$_)}=$thisurl;
1.142     albertel 1029:     }
1.126     www      1030:     @extlinks=();
1.34      www      1031:     &Apache::lonnet::appenv(%httpref);
                   1032: }
                   1033: 
1.281     albertel 1034: sub register_ssi {
                   1035:     my ($url,%form)=@_;
                   1036:     push (@Apache::lonxml::ssi_info,{'url'=>$url,'form'=>\%form});
                   1037:     return '';
                   1038: }
                   1039: 
                   1040: sub do_registered_ssi {
                   1041:     foreach my $info (@Apache::lonxml::ssi_info) {
                   1042: 	my %form=%{ $info->{'form'}};
                   1043: 	my $url=$info->{'url'};
                   1044: 	&Apache::lonnet::ssi($url,%form);
                   1045:     }
                   1046: }
1.66      www      1047: #
                   1048: # Afterburner handles anchors, highlights and links
                   1049: #
                   1050: sub afterburn {
                   1051:     my $result=shift;
1.154     albertel 1052:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1053: 					    ['highlight','anchor','link']);
1.66      www      1054:     if ($ENV{'form.highlight'}) {
1.142     albertel 1055:        foreach (split(/\,/,$ENV{'form.highlight'})) {
1.66      www      1056:            my $anchorname=$_;
                   1057: 	   my $matchthis=$anchorname;
                   1058:            $matchthis=~s/\_+/\\s\+/g;
1.317     albertel 1059:            $result=~s/(\Q$matchthis\E)/\<font color=\"red\"\>$1\<\/font\>/gs;
1.142     albertel 1060:        }
1.66      www      1061:     }
                   1062:     if ($ENV{'form.link'}) {
1.142     albertel 1063:        foreach (split(/\,/,$ENV{'form.link'})) {
1.66      www      1064:            my ($anchorname,$linkurl)=split(/\>/,$_);
                   1065: 	   my $matchthis=$anchorname;
                   1066:            $matchthis=~s/\_+/\\s\+/g;
1.317     albertel 1067:            $result=~s/(\Q$matchthis\E)/\<a href=\"$linkurl\"\>$1\<\/a\>/gs;
1.142     albertel 1068:        }
1.66      www      1069:     }
                   1070:     if ($ENV{'form.anchor'}) {
                   1071:         my $anchorname=$ENV{'form.anchor'};
                   1072: 	my $matchthis=$anchorname;
                   1073:         $matchthis=~s/\_+/\\s\+/g;
1.317     albertel 1074:         $result=~s/(\Q$matchthis\E)/\<a name=\"$anchorname\"\>$1\<\/a\>/s;
1.66      www      1075:         $result.=(<<"ENDSCRIPT");
1.226     albertel 1076: <script type="text/javascript">
1.66      www      1077:     document.location.hash='$anchorname';
                   1078: </script>
                   1079: ENDSCRIPT
                   1080:     }
                   1081:     return $result;
                   1082: }
                   1083: 
1.79      www      1084: sub storefile {
                   1085:     my ($file,$contents)=@_;
1.290     albertel 1086:     &Apache::lonnet::correct_line_ends(\$contents);
1.79      www      1087:     if (my $fh=Apache::File->new('>'.$file)) {
                   1088: 	print $fh $contents;
                   1089:         $fh->close();
1.271     www      1090:         return 1;
1.147     albertel 1091:     } else {
1.271     www      1092: 	&warning("Unable to save file $file");
                   1093: 	return 0;
1.79      www      1094:     }
                   1095: }
                   1096: 
1.151     albertel 1097: sub createnewhtml {
1.321     www      1098:     my $title=&mt('Title of document goes here');
                   1099:     my $body=&mt('Body of document goes here');
                   1100:     my $filecontents=(<<SIMPLECONTENT);
                   1101: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml/11/DTD/xhtml11.dtd">
1.78      www      1102: <html>
                   1103: <head>
1.321     www      1104: <title>$title</title>
1.78      www      1105: </head>
                   1106: <body bgcolor="#FFFFFF">
1.321     www      1107: $body
1.78      www      1108: </body>
                   1109: </html>
                   1110: SIMPLECONTENT
1.321     www      1111:     return $filecontents;
1.151     albertel 1112: }
                   1113: 
1.274     albertel 1114: sub createnewsty {
                   1115:   my $filecontents=(<<SIMPLECONTENT);
                   1116: <definetag name="">
                   1117:     <render>
                   1118:        <web></web>
                   1119:        <tex></tex>
                   1120:     </render>
                   1121: </definetag>
                   1122: SIMPLECONTENT
                   1123:   return $filecontents;
                   1124: }
                   1125: 
1.147     albertel 1126: 
1.151     albertel 1127: sub inserteditinfo {
1.274     albertel 1128:       my ($result,$filecontents,$filetype)=@_;
1.314     albertel 1129:       $filecontents = &HTML::Entities::encode($filecontents,'<>&"');
1.147     albertel 1130: #      my $editheader='<a href="#editsection">Edit below</a><hr />';
1.274     albertel 1131:       my $xml_help = '';
1.321     www      1132:       my $initialize='';
1.274     albertel 1133:       if ($filetype eq 'html') {
1.323   ! www      1134: 	  my $addbuttons=&Apache::lonhtmlcommon::htmlareaaddbuttons();
1.321     www      1135: 	  $initialize=&Apache::lonhtmlcommon::htmlareaheaders().(<<FULLPAGE);
                   1136: <script type="text/javascript">
1.323   ! www      1137: $addbuttons
        !          1138: 
1.321     www      1139:     HTMLArea.loadPlugin("FullPage");
                   1140: 
                   1141:     function initDocument() {
1.323   ! www      1142: 	var editor=new HTMLArea("filecont",config);
1.321     www      1143: 	editor.registerPlugin(FullPage);
                   1144: 	editor.generate();
                   1145:     }
                   1146: </script>
                   1147: FULLPAGE
                   1148:           $result=~s/\<body([^\>]*)\>/\<body onload="initDocument()" $1\>/i;
                   1149: 	  $xml_help=&Apache::loncommon::helpLatexCheatsheet();
1.274     albertel 1150:       }
                   1151:       my $cleanbut = '';
                   1152:       if ($filetype eq 'html') {
1.280     www      1153: 	  $cleanbut='<input type="submit" name="attemptclean" value="'.
                   1154: 	      &mt('Save and then attempt to clean HTML').'" />';
1.274     albertel 1155:       }
1.254     albertel 1156:       my $titledisplay=&display_title();
1.280     www      1157:       my %lt=&Apache::lonlocal::texthash('st' => 'Save this',
                   1158: 					 'vi' => 'View',
                   1159: 					 'ed' => 'Edit');
1.161     albertel 1160:       my $buttons=(<<BUTTONS);
1.274     albertel 1161: $cleanbut
1.304     matthew  1162: <input type="submit" name="savethisfile" accesskey="s"  value="$lt{'st'}" />
                   1163: <input type="submit" name="viewmode" accesskey="v" value="$lt{'vi'}" />
1.161     albertel 1164: BUTTONS
1.78      www      1165:       my $editfooter=(<<ENDFOOTER);
1.321     www      1166: $initialize
1.78      www      1167: <hr />
                   1168: <a name="editsection" />
                   1169: <form method="post">
1.240     albertel 1170: $xml_help
1.280     www      1171: <input type="hidden" name="editmode" value="$lt{'ed'}" />
1.170     www      1172: $buttons<br />
1.321     www      1173: <textarea cols="80" rows="44" name="filecont" id="filecont">$filecontents</textarea>
1.170     www      1174: <br />$buttons
1.78      www      1175: <br />
                   1176: </form>
1.254     albertel 1177: $titledisplay
1.321     www      1178: </body>
1.78      www      1179: ENDFOOTER
1.147     albertel 1180: #      $result=~s/(\<body[^\>]*\>)/$1$editheader/is;
1.78      www      1181:       $result=~s/(\<\/body\>)/$editfooter/is;
                   1182:       return $result;
                   1183: }
                   1184: 
1.152     albertel 1185: sub get_target {
                   1186:   my $viewgrades=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'});
                   1187:   if ( $ENV{'request.state'} eq 'published') {
                   1188:     if ( defined($ENV{'form.grade_target'})
                   1189: 	 && ($viewgrades == 'F' )) {
                   1190:       return ($ENV{'form.grade_target'});
1.153     albertel 1191:     } elsif (defined($ENV{'form.grade_target'})) {
                   1192:       if (($ENV{'form.grade_target'} eq 'web') ||
                   1193: 	  ($ENV{'form.grade_target'} eq 'tex') ) {
                   1194: 	return $ENV{'form.grade_target'}
                   1195:       } else {
                   1196: 	return 'web';
                   1197:       }
1.152     albertel 1198:     } else {
                   1199:       return 'web';
                   1200:     }
                   1201:   } elsif ($ENV{'request.state'} eq 'construct') {
                   1202:     if ( defined($ENV{'form.grade_target'})) {
                   1203:       return ($ENV{'form.grade_target'});
                   1204:     } else {
                   1205:       return 'web';
                   1206:     }
                   1207:   } else {
                   1208:     return 'web';
                   1209:   }
                   1210: }
                   1211: 
1.24      sakharuk 1212: sub handler {
1.255     sakharuk 1213:     my $request=shift;
                   1214:     
                   1215:     my $target=&get_target();
                   1216:     
1.258     albertel 1217:     $Apache::lonxml::debug=$ENV{'user.debug'};
1.255     sakharuk 1218:     
                   1219:     if ($ENV{'browser.mathml'}) {
1.280     www      1220: 	&Apache::loncommon::content_type($request,'text/xml');
1.255     sakharuk 1221:     } else {
1.280     www      1222: 	&Apache::loncommon::content_type($request,'text/html');
1.255     sakharuk 1223:     }
                   1224:     &Apache::loncommon::no_cache($request);
                   1225:     $request->send_http_header;
                   1226:     
                   1227:     return OK if $request->header_only;
1.68      www      1228: 
                   1229: 
1.255     sakharuk 1230:     my $file=&Apache::lonnet::filelocation("",$request->uri);
1.274     albertel 1231:     my $filetype;
                   1232:     if ($file =~ /\.sty$/) {
                   1233: 	$filetype='sty';
                   1234:     } else {
                   1235: 	$filetype='html';
                   1236:     }
1.78      www      1237: #
                   1238: # Edit action? Save file.
                   1239: #
1.255     sakharuk 1240:     unless ($ENV{'request.state'} eq 'published') {
                   1241: 	if (($ENV{'form.savethisfile'}) || ($ENV{'form.attemptclean'})) {
1.271     www      1242: 	    if (&storefile($file,$ENV{'form.filecont'})) {
1.309     albertel 1243: 		&Apache::lonxml::info("<font COLOR=\"#0000FF\">".
                   1244: 				      &mt('Updated').": ".
                   1245: 				      &Apache::lonlocal::locallocaltime(time).
                   1246: 				      " </font>");
1.271     www      1247: 	    } 
1.255     sakharuk 1248: 	}
                   1249:     }
                   1250:     my %mystyle;
                   1251:     my $result = '';
                   1252:     my $filecontents=&Apache::lonnet::getfile($file);
                   1253:     if ($filecontents eq -1) {
1.284     www      1254: 	my $bodytag=&Apache::loncommon::bodytag('File Error');
                   1255: 	my $fnf=&mt('File not found');
1.255     sakharuk 1256: 	$result=(<<ENDNOTFOUND);
1.78      www      1257: <html>
                   1258: <head>
1.284     www      1259: <title>$fnf</title>
1.78      www      1260: </head>
1.284     www      1261: $bodytag
                   1262: <b>$fnf: $file</b>
1.78      www      1263: </body>
                   1264: </html>
                   1265: ENDNOTFOUND
1.50      albertel 1266:     $filecontents='';
1.255     sakharuk 1267: 	if ($ENV{'request.state'} ne 'published') {
1.274     albertel 1268: 	    if ($filetype eq 'sty') {
                   1269: 		$filecontents=&createnewsty();
                   1270: 	    } else {
                   1271: 		$filecontents=&createnewhtml();
                   1272: 	    }
1.255     sakharuk 1273: 	    $ENV{'form.editmode'}='Edit'; #force edit mode
                   1274: 	}
                   1275:     } else {
                   1276: 	unless ($ENV{'request.state'} eq 'published') {
                   1277: 	    if ($ENV{'form.attemptclean'}) {
                   1278: 		$filecontents=&htmlclean($filecontents,1);
                   1279: 	    }
1.264     www      1280: #
                   1281: # we are in construction space, see if edit mode forced
                   1282:             &Apache::loncommon::get_unprocessed_cgi
                   1283:                           ($ENV{'QUERY_STRING'},['editmode']);
1.255     sakharuk 1284: 	}
                   1285: 	if (!$ENV{'form.editmode'} || $ENV{'form.viewmode'}) {
                   1286: 	    $result = &Apache::lonxml::xmlparse($request,$target,$filecontents,
                   1287: 						'',%mystyle);
                   1288: 	}
1.147     albertel 1289:     }
1.255     sakharuk 1290:     
1.78      www      1291: #
                   1292: # Edit action? Insert editing commands
                   1293: #
1.255     sakharuk 1294:     unless ($ENV{'request.state'} eq 'published') {
                   1295: 	if ($ENV{'form.editmode'} && (!($ENV{'form.viewmode'}))) {
                   1296: 	    my $displayfile=$request->uri;
                   1297: 	    $displayfile=~s/^\/[^\/]*//;
1.309     albertel 1298: 	    $result='<html><body bgcolor="#FFFFFF">'.
                   1299: 		&Apache::lonxml::message_location().'<h3>'.
                   1300: 		$displayfile.
1.255     sakharuk 1301: 		'</h3></body></html>';
1.274     albertel 1302: 	    $result=&inserteditinfo($result,$filecontents,$filetype);
1.255     sakharuk 1303: 	}
1.147     albertel 1304:     }
1.274     albertel 1305:     if ($filetype eq 'html') { writeallows($request->uri); }
                   1306: 	
1.255     sakharuk 1307:     
1.309     albertel 1308:     &Apache::lonxml::add_messages(\$result);
1.255     sakharuk 1309:     $request->print($result);
                   1310:     
                   1311:     return OK;
1.253     albertel 1312: }
                   1313: 
                   1314: sub display_title {
                   1315:     my $result;
                   1316:     if ($ENV{'request.state'} eq 'construct') {
                   1317: 	my $title=&Apache::lonnet::gettitle();
                   1318: 	if (!defined($title) || $title eq '') {
                   1319: 	    $title = $ENV{'request.filename'};
                   1320: 	    $title = substr($title, rindex($title, '/') + 1);
                   1321: 	}
                   1322: 	$result = "<script type='text/javascript'>top.document.title = '$title - LON-CAPA Construction Space';</script>";
                   1323:     }
                   1324:     return $result;
1.24      sakharuk 1325: }
1.147     albertel 1326: 
1.22      albertel 1327: sub debug {
1.298     albertel 1328:     if ($Apache::lonxml::debug eq "1") {
                   1329: 	$|=1;
1.300     albertel 1330: 	my $request=$Apache::lonxml::request;
                   1331: 	if (!$request) { $request=Apache->request; }
1.314     albertel 1332: 	$request->print('<font size="-2"><pre>DEBUG:'.&HTML::Entities::encode($_[0],'<>&"')."</pre></font>\n");
1.298     albertel 1333:     }
1.22      albertel 1334: }
1.49      albertel 1335: 
1.22      albertel 1336: sub error {
1.205     www      1337:   $errorcount++;
1.300     albertel 1338:   my $request=$Apache::lonxml::request;
                   1339:   if (!$request) { $request=Apache->request; }
1.74      albertel 1340:   if (($Apache::lonxml::debug eq 1) || ($ENV{'request.state'} eq 'construct') ) {
1.166     matthew  1341:     # If printing in construction space, put the error inside <pre></pre>
1.309     albertel 1342:       push(@Apache::lonxml::error_messages,
                   1343: 	   $Apache::lonxml::warnings_error_header.
                   1344: 	   "<b>ERROR:</b>".join("<br />\n",@_)."<br />\n");
1.295     albertel 1345:       $Apache::lonxml::warnings_error_header='';
1.52      albertel 1346:   } else {
1.309     albertel 1347:       push(@Apache::lonxml::error_messages,
                   1348: 	   "<b>An Error occured while processing this resource. The instructor has been notified.</b> <br />");
1.52      albertel 1349:     #notify author
1.146     albertel 1350:     &Apache::lonmsg::author_res_msg($ENV{'request.filename'},join('<br />',@_));
1.52      albertel 1351:     #notify course
                   1352:     if ( $ENV{'request.course.id'} ) {
1.209     www      1353:       my (undef,%users)=&Apache::lonfeedback::decide_receiver(undef,0,1,1,1);
1.143     www      1354:       my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'});
1.209     www      1355:       foreach (keys %users) {
                   1356: 	my ($user,$domain) = split(/:/, $_);
1.143     www      1357: 	&Apache::lonmsg::user_normal_msg($user,$domain,
1.146     albertel 1358:         "Error [$declutter]",join('<br />',@_));
1.52      albertel 1359:       }
                   1360:     }
                   1361:   }
1.22      albertel 1362: }
1.49      albertel 1363: 
1.22      albertel 1364: sub warning {
1.295     albertel 1365:     $warningcount++;
1.261     albertel 1366:   
1.295     albertel 1367:     if ($ENV{'form.grade_target'} ne 'tex') {
                   1368: 	if ($ENV{'request.state'} eq 'construct' || $Apache::lonxml::debug) {
1.300     albertel 1369: 	    my $request=$Apache::lonxml::request;
                   1370: 	    if (!$request) { $request=Apache->request; }
1.309     albertel 1371: 	    push(@Apache::lonxml::warning_messages,
                   1372: 		 $Apache::lonxml::warnings_error_header.
                   1373: 		 "<b>W</b>ARNING<b>:</b>".join('<br />',@_)."<br />\n");
1.295     albertel 1374: 	    $Apache::lonxml::warnings_error_header='';
                   1375: 	}
                   1376:     }
1.309     albertel 1377: }
                   1378: 
                   1379: sub info {
                   1380:     if ($ENV{'form.grade_target'} ne 'tex' 
                   1381: 	&& $ENV{'request.state'} eq 'construct') {
                   1382: 	push(@Apache::lonxml::info_messages,join('<br />',@_)."<br />\n");
                   1383:     }
                   1384: }
                   1385: 
                   1386: sub message_location {
                   1387:     return '__LONCAPA_INTERNAL_MESSAGE_LOCATION__';
                   1388: }
                   1389: 
                   1390: sub add_messages {
                   1391:     my ($msg)=@_;
                   1392:     my $result=join(' ',
                   1393: 		    @Apache::lonxml::info_messages,
                   1394: 		    @Apache::lonxml::error_messages,
                   1395: 		    @Apache::lonxml::warning_messages);
                   1396:     undef(@Apache::lonxml::info_messages);
                   1397:     undef(@Apache::lonxml::error_messages);
                   1398:     undef(@Apache::lonxml::warning_messages);
                   1399:     $$msg=~s/__LONCAPA_INTERNAL_MESSAGE_LOCATION__/$result/;
                   1400:     $$msg=~s/__LONCAPA_INTERNAL_MESSAGE_LOCATION__//g;
1.83      albertel 1401: }
                   1402: 
                   1403: sub get_param {
1.213     albertel 1404:     my ($param,$parstack,$safeeval,$context,$case_insensitive) = @_;
                   1405:     if ( ! $context ) { $context = -1; }
                   1406:     my $args ='';
                   1407:     if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
1.297     sakharuk 1408:     if ( ! $Apache::lonxml::usestyle ) {
                   1409: 	$args=$Apache::lonxml::style_values.$args;
                   1410:     }
1.213     albertel 1411:     if ( ! $args ) { return undef; }
                   1412:     if ( $case_insensitive ) {
                   1413: 	if ($args =~ s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei) {
                   1414: 	    return &Apache::run::run("{$args;".'return $'.$param.'}',
                   1415:                                      $safeeval); #'
                   1416: 	} else {
                   1417: 	    return undef;
                   1418: 	}
                   1419:     } else {
                   1420: 	if ( $args =~ /my \$\Q$param\E=\"/ ) {
                   1421: 	    return &Apache::run::run("{$args;".'return $'.$param.'}',
                   1422:                                      $safeeval); #'
                   1423: 	} else {
                   1424: 	    return undef;
                   1425: 	}
                   1426:     }
1.22      albertel 1427: }
                   1428: 
1.132     albertel 1429: sub get_param_var {
1.213     albertel 1430:   my ($param,$parstack,$safeeval,$context,$case_insensitive) = @_;
1.132     albertel 1431:   if ( ! $context ) { $context = -1; }
                   1432:   my $args ='';
                   1433:   if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; }
1.297     sakharuk 1434:   if ( ! $Apache::lonxml::usestyle ) {
                   1435:       $args=$Apache::lonxml::style_values.$args;
                   1436:   }
1.230     albertel 1437:   &Apache::lonxml::debug("Args are $args param is $param");
1.213     albertel 1438:   if ($case_insensitive) {
                   1439:       if (! ($args=~s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei)) {
                   1440: 	  return undef;
                   1441:       }
                   1442:   } elsif ( $args !~ /my \$\Q$param\E=\"/ ) { return undef; }
1.132     albertel 1443:   my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #'
1.230     albertel 1444:   &Apache::lonxml::debug("first run is $value");
                   1445:   if ($value =~ /^[\$\@\%]\w+$/) {
                   1446:       &Apache::lonxml::debug("doing second");
                   1447:       my @result=&Apache::run::run("return $value",$safeeval,1);
                   1448:       if (!defined($result[0])) {
                   1449: 	  return $value
                   1450:       } else {
                   1451: 	  if (wantarray) { return @result; } else { return $result[0]; }
                   1452:       }
1.132     albertel 1453:   } else {
                   1454:     return $value;
                   1455:   }
                   1456: }
                   1457: 
1.74      albertel 1458: sub register_insert {
1.75      albertel 1459:   my @data = split /\n/, &Apache::lonnet::getfile('/home/httpd/lonTabs/insertlist.tab');
1.74      albertel 1460:   my $i;
1.76      albertel 1461:   my $tagnum=0;
1.74      albertel 1462:   my @order;
                   1463:   for ($i=0;$i < $#data; $i++) {
                   1464:     my $line = $data[$i];
                   1465:     if ( $line =~ /^\#/ || $line =~ /^\s*\n/) { next; }
                   1466:     if ( $line =~ /TABLE/ ) { last; }
1.268     bowersj2 1467:     my ($tag,$descrip,$color,$function,$show,$helpfile,$helpdesc) = split(/,/, $line);
1.135     albertel 1468:     if ($tag) {
                   1469:       $insertlist{"$tagnum.tag"} = $tag;
                   1470:       $insertlist{"$tagnum.description"} = $descrip;
                   1471:       $insertlist{"$tagnum.color"} = $color;
                   1472:       $insertlist{"$tagnum.function"} = $function;
                   1473:       if (!defined($show)) { $show='yes'; }
                   1474:       $insertlist{"$tagnum.show"}= $show;
1.268     bowersj2 1475:       $insertlist{"$tagnum.helpfile"} = $helpfile;
                   1476:       $insertlist{"$tagnum.helpdesc"} = $helpdesc;
1.135     albertel 1477:       $insertlist{"$tag.num"}=$tagnum;
                   1478:       $tagnum++;
                   1479:     }
1.74      albertel 1480:   }
1.76      albertel 1481:   $i++; #skipping TABLE line
                   1482:   $tagnum = 0;
1.74      albertel 1483:   for (;$i < $#data;$i++) {
                   1484:     my $line = $data[$i];
1.76      albertel 1485:     my ($mnemonic,@which) = split(/ +/,$line);
                   1486:     my $tag = $insertlist{"$tagnum.tag"};
1.144     matthew  1487:     for (my $j=0;$j <=$#which;$j++) {
1.74      albertel 1488:       if ( $which[$j] eq 'Y' ) {
1.76      albertel 1489: 	if ($insertlist{"$j.show"} ne 'no') {
                   1490: 	  push(@{ $insertlist{"$tag.which"} },$j);
                   1491: 	}
1.74      albertel 1492:       }
                   1493:     }
1.76      albertel 1494:     $tagnum++;
1.74      albertel 1495:   }
                   1496: }
1.98      albertel 1497: 
                   1498: sub description {
                   1499:   my ($token)=@_;
1.138     albertel 1500:   my $tagnum;
                   1501:   my $tag=$token->[1];
                   1502:   foreach my $namespace (reverse @Apache::lonxml::namespace) {
                   1503:     my $testtag=$namespace.'::'.$tag;
                   1504:     $tagnum=$insertlist{"$testtag.num"};
                   1505:     if (defined($tagnum)) { last; }
                   1506:   }
                   1507:   if (!defined ($tagnum)) { $tagnum=$Apache::lonxml::insertlist{"$tag.num"}; }
                   1508:   return $insertlist{$tagnum.'.description'};
1.268     bowersj2 1509: }
                   1510: 
                   1511: # Returns a list containing the help file, and the description
                   1512: sub helpinfo {
                   1513:   my ($token)=@_;
                   1514:   my $tagnum;
                   1515:   my $tag=$token->[1];
                   1516:   foreach my $namespace (reverse @Apache::lonxml::namespace) {
                   1517:     my $testtag=$namespace.'::'.$tag;
                   1518:     $tagnum=$insertlist{"$testtag.num"};
                   1519:     if (defined($tagnum)) { last; }
                   1520:   }
                   1521:   if (!defined ($tagnum)) { $tagnum=$Apache::lonxml::insertlist{"$tag.num"}; }
                   1522:   return ($insertlist{$tagnum.'.helpfile'}, $insertlist{$tagnum.'.helpdesc'});
1.98      albertel 1523: }
1.123     albertel 1524: 
                   1525: # ----------------------------------------------------------------- whichuser
                   1526: # returns a list of $symb, $courseid, $domain, $name that is correct for
                   1527: # calls to lonnet functions for this setup.
                   1528: # - looks for form.grade_ parameters
                   1529: sub whichuser {
1.262     matthew  1530:   my ($passedsymb)=@_;
1.245     albertel 1531:   my ($symb,$courseid,$domain,$name,$publicuser);
1.123     albertel 1532:   if (defined($ENV{'form.grade_symb'})) {
                   1533:     my $tmp_courseid=$ENV{'form.grade_courseid'};
1.269     albertel 1534:     my $allowed=&Apache::lonnet::allowed('vgr',$tmp_courseid);
1.123     albertel 1535:     if ($allowed) {
                   1536:       $symb=$ENV{'form.grade_symb'};
                   1537:       $courseid=$ENV{'form.grade_courseid'};
                   1538:       $domain=$ENV{'form.grade_domain'};
                   1539:       $name=$ENV{'form.grade_username'};
                   1540:     }
1.134     albertel 1541:   } else {
1.262     matthew  1542:       if (!$passedsymb) {
                   1543:           $symb=&Apache::lonnet::symbread();
                   1544:       } else {
                   1545:           $symb=$passedsymb;
                   1546:       }
1.244     albertel 1547:       $courseid=$ENV{'request.course.id'};
                   1548:       $domain=$ENV{'user.domain'};
                   1549:       $name=$ENV{'user.name'};
                   1550:       if ($name eq 'public' && $domain eq 'public') {
                   1551: 	  if (!defined($ENV{'form.username'})) {
                   1552: 	      $ENV{'form.username'}.=time.rand(10000000);
                   1553: 	  }
                   1554: 	  $name.=$ENV{'form.username'};
                   1555:       }
1.123     albertel 1556:   }
1.245     albertel 1557:   return ($symb,$courseid,$domain,$name,$publicuser);
1.123     albertel 1558: }
                   1559: 
1.1       sakharuk 1560: 1;
                   1561: __END__
1.68      www      1562: 
                   1563: 

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.