--- loncom/xml/lonxml.pm 2003/09/15 19:56:44 1.278 +++ loncom/xml/lonxml.pm 2004/10/05 20:18:29 1.341 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # XML Parser Module # -# $Id: lonxml.pm,v 1.278 2003/09/15 19:56:44 www Exp $ +# $Id: lonxml.pm,v 1.341 2004/10/05 20:18:29 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -36,30 +36,11 @@ # The C source of the Code may not be distributed by the Licensee # to any other parties under any circumstances. # -# last modified 06/26/00 by Alexander Sakharuk -# 11/6 Gerd Kortemeyer -# 6/1/1 Gerd Kortemeyer -# 2/21,3/13 Guy -# 3/29,5/4 Gerd Kortemeyer -# 5/26 Gerd Kortemeyer -# 5/27 H. K. Ng -# 6/2,6/3,6/8,6/9 Gerd Kortemeyer -# 6/12,6/13 H. K. Ng -# 6/16 Gerd Kortemeyer -# 7/27 H. K. Ng -# 8/7,8/9,8/10,8/11,8/15,8/16,8/17,8/18,8/20,8/23,8/24 Gerd Kortemeyer -# Guy Albertelli -# 9/26 Gerd Kortemeyer -# Dec Guy Albertelli -# YEAR=2002 -# 1/1 Gerd Kortemeyer -# 1/2 Matthew Hall -# 1/3 Gerd Kortemeyer -# + package Apache::lonxml; use vars -qw(@pwd @outputstack $redirection $import @extlinks $metamode $evaluate %insertlist @namespace $prevent_entity_encode $errorcount $warningcount); +qw(@pwd @outputstack $redirection $import @extlinks $metamode $evaluate %insertlist @namespace $errorcount $warningcount @htmlareafields); use strict; use HTML::LCParser(); use HTML::TreeBuilder(); @@ -70,7 +51,7 @@ use Math::Cephes(); use Math::Random(); use Opcode(); use POSIX qw(strftime); - +use Time::HiRes qw( gettimeofday tv_interval ); sub register { my ($space,@taglist) = @_; @@ -96,6 +77,7 @@ use Apache::style(); use Apache::run(); use Apache::londefdef(); use Apache::scripttag(); +use Apache::languagetags(); use Apache::edit(); use Apache::inputtags(); use Apache::outputtags(); @@ -105,6 +87,7 @@ use Apache::loncommon(); use Apache::lonfeedback(); use Apache::lonmsg(); use Apache::loncacc(); +use Apache::lonlocal; #================================================== Main subroutine: xmlparse #debugging control, to turn on debugging modify the correct handler @@ -139,9 +122,6 @@ $evaluate = 1; # stores the list of active tag namespaces @namespace=(); -# if 0 all high ASCII characters will be encoded into HTML Entities -$prevent_entity_encode=0; - # has the dynamic menu been updated to know about this resource $Apache::lonxml::registered=0; @@ -159,8 +139,18 @@ $Apache::lonxml::usestyle=1; $Apache::lonxml::style_values=''; $Apache::lonxml::style_end_values=''; +#array of ssi calls that need to occur after we are done parsing +@Apache::lonxml::ssi_info=(); + +#should we do the postag variable interpolation +$Apache::lonxml::post_evaluate=1; + +#a header message to emit in the case of any generated warning or errors +$Apache::lonxml::warnings_error_header=''; + sub xmlbegin { my $output=''; + @htmlareafields=(); if ($ENV{'browser.mathml'}) { $output='' .'' @@ -175,13 +165,21 @@ sub xmlbegin { } sub xmlend { + my ($target,$parser)=@_; my $mode='xml'; my $status='OPEN'; if ($Apache::lonhomework::parsing_a_problem) { $mode='problem'; $status=$Apache::inputtags::status[-1]; } - return &Apache::lonfeedback::list_discussion().''; + my $discussion=&Apache::lonfeedback::list_discussion($mode,$status); + if ($target eq 'tex') { + $discussion.='\keephidden{ENDOFPROBLEM}\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\end{document}'; + &Apache::lonxml::newparser($parser,\$discussion,''); + return ''; + } else { + return $discussion.''; + } } sub tokeninputfield { @@ -273,13 +271,13 @@ sub printtokenheader { my %idhash=&Apache::lonnet::idrget($tudom,($tuname)); return ''. - 'Checked out for '.$plainname. - '
User: '.$tuname.' at '.$tudom. - '
ID: '.$idhash{$tuname}. - '
CourseID: '.$tcrsid. - '
Course: '.$ENV{'course.'.$tcrsid.'.description'}. - '
DocID: '.$token. - '
Time: '.localtime().'
'; + &mt('Checked out for').' '.$plainname. + '
'.&mt('User').': '.$tuname.' at '.$tudom. + '
'.&mt('ID').': '.$idhash{$tuname}. + '
'.&mt('CourseID').': '.$tcrsid. + '
'.&mt('Course').': '.$ENV{'course.'.$tcrsid.'.description'}. + '
'.&mt('DocID').': '.$token. + '
'.&mt('Time').': '.&Apache::lonlocal::locallocaltime().'
'; } else { return $token; } @@ -312,6 +310,7 @@ sub xmlparse { &Apache::inputtags::initialize_inputtags(); &Apache::outputtags::initialize_outputtags(); &Apache::edit::initialize_edit(); + &Apache::londefdef::initialize_londefdef(); # # do we have a course style file? @@ -321,13 +320,22 @@ sub xmlparse { my $bodytext= $ENV{'course.'.$ENV{'request.course.id'}.'.default_xml_style'}; if ($bodytext) { - my $location=&Apache::lonnet::filelocation('',$bodytext); - my $styletext=&Apache::lonnet::getfile($location); + foreach my $file (split(',',$bodytext)) { + my $location=&Apache::lonnet::filelocation('',$file); + my $styletext=&Apache::lonnet::getfile($location); + if ($styletext ne '-1') { + %style_for_target = (%style_for_target, + &Apache::style::styleparser($target,$styletext)); + } + } + } + } elsif ($ENV{'construct.style'} && ($ENV{'request.state'} eq 'construct')) { + my $location=&Apache::lonnet::filelocation('',$ENV{'construct.style'}); + my $styletext=&Apache::lonnet::getfile($location); if ($styletext ne '-1') { %style_for_target = (%style_for_target, &Apache::style::styleparser($target,$styletext)); - } - } + } } #&printalltags(); my @pars = (); @@ -352,6 +360,7 @@ sub xmlparse { if ($ENV{'request.uri'}) { &writeallows($ENV{'request.uri'}); } + &do_registered_ssi(); if ($Apache::lonxml::counter_changed) { &store_counter() } return $finaloutput; } @@ -381,20 +390,28 @@ sub latex_special_symbols { my ($string,$where)=@_; if ($where eq 'header') { $string =~ s/(\\|_|\^)/ /g; - $string =~ s/(\$|%|\#|&|\{|\})/\\$1/g; + $string =~ s/(\$|%|\{|\})/\\$1/g; $string =~ s/_/ /g; + $string=&Apache::lonprintout::character_chart($string); + # any & or # leftover should be safe to just escape + $string=~s/([^\\])\&/$1\\\&/g; + $string=~s/([^\\])\#/$1\\\#/g; } else { - $string=~s/\\ /\\char92 /g; - $string=~s/\^/\\char94 /g; - $string=~s/\~/\\char126 /g; - $string=~s/(&[^A-Za-z\#])/\\$1/g; - $string=~s/([^&])\#/$1\\#/g; - $string=~s/(\$|_|{|})/\\$1/g; - $string=~s/\\char92 /\\texttt{\\char92}/g; - $string=~s/(>|<)/\$$1\$/g; #more or less - if ($string=~m/\d%/) {$string =~ s/(\d)%/$1\\%/g;} #percent after digit - if ($string=~m/\s%/) {$string =~ s/(\s)%/$1\\%/g;} #percent after space - if ($string eq '%.') {$string = '\%.';} #percent at the end of statement + $string=~s/\\/\\ensuremath{\\backslash}/g; + $string=~s/([^\\]|^)\%/$1\\\%/g; + $string=~s/([^\\]|^)\$/$1\\\$/g; + $string=~s/([^\\])\_/$1\\_/g; + $string=~s/\$\$/\$\\\$/g; + $string=~s/\_\_/\_\\\_/g; + $string=~s/\#\#/\#\\\#/g; + $string=~s/([^\\]|^)(\~|\^)/$1\\$2\\strut /g; + $string=~s/(>|<)/\\ensuremath\{$1\}/g; #more or less + $string=&Apache::lonprintout::character_chart($string); + # any & or # leftover should be safe to just escape + $string=~s/([^\\]|^)\&/$1\\\&/g; + $string=~s/([^\\]|^)\#/$1\\\#/g; + $string=~s/\|/\$\\mid\$/g; +#single { or } How to escape? } return $string; } @@ -457,7 +474,7 @@ sub inner_xmlparse { #clear out any tags that didn't end while ($token->[1] ne $$stack['-1'] && ($#$stack > -1)) { my $lasttag=$$stack[-1]; - if ($token->[1] =~ /^$lasttag$/i) { + if ($token->[1] =~ /^\Q$lasttag\E$/i) { &Apache::lonxml::warning('Using tag </'.$token->[1].'> on line '.$token->[3].' as end tag to <'.$$stack[-1].'>'); last; } else { @@ -472,7 +489,7 @@ sub inner_xmlparse { &Apache::lonxml::error("Unknown token event :$token->[0]:$token->[1]:"); } #evaluate variable refs in result - if ($result ne "") { + if ($Apache::lonxml::post_evaluate &&$result ne "") { my $extras; if (!$Apache::lonxml::usestyle) { $extras=$Apache::lonxml::style_values; @@ -483,6 +500,8 @@ sub inner_xmlparse { $result= &Apache::run::evaluate($result,$safeeval,$extras); } } + $Apache::lonxml::post_evaluate=1; + if (($token->[0] eq 'T') || ($token->[0] eq 'C') || ($token->[0] eq 'D') ) { #Style file definitions should be correct if ($target eq 'tex' && ($Apache::lonxml::usestyle)) { @@ -490,10 +509,6 @@ sub inner_xmlparse { } } - # Encode any high ASCII characters - if (!$Apache::lonxml::prevent_entity_encode) { - $result=&HTML::Entities::encode($result,"\200-\377"); - } if ($Apache::lonxml::redirection) { $Apache::lonxml::outputstack['-1'] .= $result; } else { @@ -523,6 +538,10 @@ sub inner_xmlparse { return $finaloutput; } +## +## Looks to see if there is a subroutine defined for this tag. If so, call it, +## otherwise do not call it as we do not know what it is. +## sub callsub { my ($sub,$target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $currentstring=''; @@ -555,6 +574,10 @@ sub callsub { $parstack,$parser,$safeeval, $style); } else { + if ($target eq 'tex') { + # throw away tag name + return ''; + } #&Apache::lonxml::debug("NOT Calling sub $sub in $space $metamode"); if ($metamode <1) { if (defined($token->[4]) && ($metamode < 1)) { @@ -595,6 +618,7 @@ sub setup_globals { my ($request,$target)=@_; $Apache::lonxml::request=$request; $Apache::lonxml::registered = 0; + @Apache::lonxml::htmlareafields=(); $errorcount=0; $warningcount=0; $Apache::lonxml::default_homework_loaded=0; @@ -602,6 +626,9 @@ sub setup_globals { &init_counter(); @Apache::lonxml::pwd=(); @Apache::lonxml::extlinks=(); + @Apache::lonxml::ssi_info=(); + $Apache::lonxml::post_evaluate=1; + $Apache::lonxml::warnings_error_header=''; if ($target eq 'meta') { $Apache::lonxml::redirection = 0; $Apache::lonxml::metamode = 1; @@ -645,11 +672,14 @@ sub init_safespace { $safeeval->permit("entereval"); $safeeval->permit(":base_math"); $safeeval->permit("sort"); + $safeeval->permit("time"); $safeeval->deny(":base_io"); $safehole->wrap(\&Apache::scripttag::xmlparse,$safeeval,'&xmlparse'); $safehole->wrap(\&Apache::outputtags::multipart,$safeeval,'&multipart'); $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT'); - + $safehole->wrap(\&Apache::chemresponse::chem_standard_order,$safeeval, + '&chem_standard_order'); + $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin'); $safehole->wrap(\&Math::Cephes::acos,$safeeval,'&acos'); $safehole->wrap(\&Math::Cephes::atan,$safeeval,'&atan'); @@ -721,16 +751,21 @@ sub init_safespace { $safehole->wrap(\&Math::Random::random_set_seed_from_phrase,$safeeval,'&random_set_seed_from_phrase'); $safehole->wrap(\&Math::Random::random_get_seed,$safeeval,'&random_get_seed'); $safehole->wrap(\&Math::Random::random_set_seed,$safeeval,'&random_set_seed'); + $safehole->wrap(\&Apache::lonxml::error,$safeeval,'&LONCAPA_INTERNAL_ERROR'); + $safehole->wrap(\&Apache::lonxml::debug,$safeeval,'&LONCAPA_INTERNAL_DEBUG'); + $safehole->wrap(\&Apache::caparesponse::get_sigrange,$safeeval,'&LONCAPA_INTERNAL_get_sigrange'); #need to inspect this class of ops # $safeeval->deny(":base_orig"); + $safeeval->permit("require"); $safeinit .= ';$external::target="'.$target.'";'; my $rndseed; my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser(); $rndseed=&Apache::lonnet::rndseed($symb,$courseid,$domain,$name); - $safeinit .= ';$external::randomseed='.$rndseed.';'; + $safeinit .= ';$external::randomseed="'.$rndseed.'";'; &Apache::lonxml::debug("Setting rndseed to $rndseed"); &Apache::run::run($safeinit,$safeeval); + } sub default_homework_load { @@ -745,18 +780,26 @@ sub default_homework_load { } } +my $metamode_was; sub startredirection { - $Apache::lonxml::redirection++; - push (@Apache::lonxml::outputstack, ''); + if (!$Apache::lonxml::redirection) { + $metamode_was=$Apache::lonxml::metamode; + } + $Apache::lonxml::metamode=0; + $Apache::lonxml::redirection++; + push (@Apache::lonxml::outputstack, ''); } sub endredirection { - if (!$Apache::lonxml::redirection) { - &Apache::lonxml::error("Endredirection was called, before a startredirection, perhaps you have unbalanced tags. Some debuging information:".join ":",caller); - return ''; - } - $Apache::lonxml::redirection--; - pop @Apache::lonxml::outputstack; + if (!$Apache::lonxml::redirection) { + &Apache::lonxml::error("Endredirection was called, before a startredirection, perhaps you have unbalanced tags. Some debuging information:".join ":",caller); + return ''; + } + $Apache::lonxml::redirection--; + if (!$Apache::lonxml::redirection) { + $Apache::lonxml::metamode=$metamode_was; + } + pop @Apache::lonxml::outputstack; } sub end_tag { @@ -772,6 +815,8 @@ sub initdepth { $Apache::lonxml::olddepth=-1; } +my @timers; +my $lasttime; sub increasedepth { my ($token) = @_; $Apache::lonxml::depth++; @@ -779,8 +824,15 @@ sub increasedepth { if ($Apache::lonxml::depthcounter[$Apache::lonxml::depth]==1) { $Apache::lonxml::olddepth=$Apache::lonxml::depth; } + my $time; + if ($Apache::lonxml::debug eq "1") { + push(@timers,[&gettimeofday()]); + $time=&tv_interval($lasttime); + $lasttime=[&gettimeofday()]; + } + my $spacing=' 'x($Apache::lonxml::depth-1); my $curdepth=join('_',@Apache::lonxml::depthcounter); - &Apache::lonxml::debug("s $Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1]\n"); + &Apache::lonxml::debug("s$spacing$Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1] : $time : \n"); #print "
s $Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1]\n"; } @@ -792,40 +844,47 @@ sub decreasedepth { $Apache::lonxml::olddepth=$Apache::lonxml::depth+1; } if ( $Apache::lonxml::depth < -1) { - &Apache::lonxml::warning("Missing tags, unable to properly run file."); + &Apache::lonxml::warning(&mt("Missing tags, unable to properly run file.")); $Apache::lonxml::depth='-1'; } + my ($timer,$time); + if ($Apache::lonxml::debug eq "1") { + $timer=pop(@timers); + $time=&tv_interval($lasttime); + $lasttime=[&gettimeofday()]; + } + my $spacing=' 'x$Apache::lonxml::depth; my $curdepth=join('_',@Apache::lonxml::depthcounter); - &Apache::lonxml::debug("e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n"); + &Apache::lonxml::debug("e$spacing$Apache::lonxml::depth : $Apache::lonxml::olddepth : $curdepth : $token->[1] : $time : ".&tv_interval($timer)."\n"); #print "
e $Apache::lonxml::depth : $Apache::lonxml::olddepth : $token->[1] : $curdepth\n"; } sub get_all_text_unbalanced { #there is a copy of this in lonpublisher.pm - my($tag,$pars)= @_; - my $token; - my $result=''; - $tag='<'.$tag.'>'; - while ($token = $$pars[-1]->get_token) { - if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) { - $result.=$token->[1]; - } elsif ($token->[0] eq 'PI') { - $result.=$token->[2]; - } elsif ($token->[0] eq 'S') { - $result.=$token->[4]; - } elsif ($token->[0] eq 'E') { - $result.=$token->[2]; - } - if ($result =~ /(.*)\Q$tag\E(.*)/s) { - &Apache::lonxml::debug('Got a winner with leftovers ::'.$2); - &Apache::lonxml::debug('Result is :'.$1); - $result=$1; - my $redo=$tag.$2; - &Apache::lonxml::newparser($pars,\$redo); - last; - } - } - return $result + my($tag,$pars)= @_; + my $token; + my $result=''; + $tag='<'.$tag.'>'; + while ($token = $$pars[-1]->get_token) { + if (($token->[0] eq 'T')||($token->[0] eq 'C')||($token->[0] eq 'D')) { + $result.=$token->[1]; + } elsif ($token->[0] eq 'PI') { + $result.=$token->[2]; + } elsif ($token->[0] eq 'S') { + $result.=$token->[4]; + } elsif ($token->[0] eq 'E') { + $result.=$token->[2]; + } + if ($result =~ /\Q$tag\E/is) { + ($result,my $redo)=$result =~ /(.*)\Q$tag\E(.*)/is; + #&Apache::lonxml::debug('Got a winner with leftovers ::'.$2); + #&Apache::lonxml::debug('Result is :'.$1); + $redo=$tag.$redo; + &Apache::lonxml::newparser($pars,\$redo); + last; + } + } + return $result } sub increment_counter { @@ -855,17 +914,13 @@ sub store_counter { sub get_all_text { my($tag,$pars,$style)= @_; - &Apache::lonxml::debug("Got a ".ref($pars)); my $gotfullstack=1; if (ref($pars) ne 'ARRAY') { $gotfullstack=0; $pars=[$pars]; } - &Apache::lonxml::debug("Got a ".ref($style)); if (ref($style) ne 'HASH') { $style={}; - } else { - &Apache::lonhomework::showhash(%$style); } my $depth=0; my $token; @@ -882,14 +937,14 @@ sub get_all_text { } elsif ($token->[0] eq 'PI') { $result.=$token->[2]; } elsif ($token->[0] eq 'S') { - if ($token->[1] =~ /^$tag$/i) { $depth++; } - if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_ON$/i) { $Apache::lonxml::usestyle=1; } - if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_OFF$/i) { $Apache::lonxml::usestyle=0; } + if ($token->[1] =~ /^\Q$tag\E$/i) { $depth++; } + if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_ON$/) { $Apache::lonxml::usestyle=1; } + if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_OFF$/) { $Apache::lonxml::usestyle=0; } $result.=$token->[4]; } elsif ($token->[0] eq 'E') { - if ( $token->[1] =~ /^$tag$/i) { $depth--; } + if ( $token->[1] =~ /^\Q$tag\E$/i) { $depth--; } #skip sending back the last end tag - if ($depth == 0 && exists($$style{'/'.$token->[1]})) { + if ($depth == 0 && exists($$style{'/'.$token->[1]}) && $Apache::lonxml::usestyle) { my $string= ''. $$style{'/'.$token->[1]}. @@ -916,7 +971,7 @@ sub get_all_text { #never found the end tag ran out of text, throw error send back blank &error('Never found end tag for <'.$tag. '> current string
'.
-		   &HTML::Entities::encode($result).
+		   &HTML::Entities::encode($result,'<>&"').
 		   '
'); if ($gotfullstack) { my $newstring=''.$result; @@ -934,13 +989,13 @@ sub get_all_text { } elsif ($token->[0] eq 'PI') { $result.=$token->[2]; } elsif ($token->[0] eq 'S') { - if ( $token->[1] =~ /^$tag$/i) { + if ( $token->[1] =~ /^\Q$tag\E$/i) { $$pars[-1]->unget_token($token); last; } else { $result.=$token->[4]; } - if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_ON$/i) { $Apache::lonxml::usestyle=1; } - if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_OFF$/i) { $Apache::lonxml::usestyle=0; } + if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_ON$/) { $Apache::lonxml::usestyle=1; } + if ($token->[1] =~ /^LONCAPA_INTERNAL_TURN_STYLE_OFF$/) { $Apache::lonxml::usestyle=0; } } elsif ($token->[0] eq 'E') { $result.=$token->[2]; } @@ -973,6 +1028,7 @@ sub parstring { unless ($_=~/\W/) { my $val=$token->[2]->{$_}; $val =~ s/([\%\@\\\"\'])/\\$1/g; + $val =~ s/^(\$\d)/\\$1/; #if ($val =~ m/^[\%\@]/) { $val="\\".$val; } $temp .= "my \$$_=\"$val\";"; } @@ -997,6 +1053,19 @@ sub writeallows { &Apache::lonnet::appenv(%httpref); } +sub register_ssi { + my ($url,%form)=@_; + push (@Apache::lonxml::ssi_info,{'url'=>$url,'form'=>\%form}); + return ''; +} + +sub do_registered_ssi { + foreach my $info (@Apache::lonxml::ssi_info) { + my %form=%{ $info->{'form'}}; + my $url=$info->{'url'}; + &Apache::lonnet::ssi($url,%form); + } +} # # Afterburner handles anchors, highlights and links # @@ -1009,7 +1078,7 @@ sub afterburn { my $anchorname=$_; my $matchthis=$anchorname; $matchthis=~s/\_+/\\s\+/g; - $result=~s/($matchthis)/\$1\<\/font\>/gs; + $result=~s/(\Q$matchthis\E)/\$1\<\/font\>/gs; } } if ($ENV{'form.link'}) { @@ -1017,14 +1086,14 @@ sub afterburn { my ($anchorname,$linkurl)=split(/\>/,$_); my $matchthis=$anchorname; $matchthis=~s/\_+/\\s\+/g; - $result=~s/($matchthis)/\$1\<\/a\>/gs; + $result=~s/(\Q$matchthis\E)/\$1\<\/a\>/gs; } } if ($ENV{'form.anchor'}) { my $anchorname=$ENV{'form.anchor'}; my $matchthis=$anchorname; $matchthis=~s/\_+/\\s\+/g; - $result=~s/($matchthis)/\$1\<\/a\>/s; + $result=~s/(\Q$matchthis\E)/\$1\<\/a\>/s; $result.=(<<"ENDSCRIPT"); +FULLPAGE + $result=~s/\]*)\>/\/i; + $xml_help=&Apache::loncommon::helpLatexCheatsheet(); } my $cleanbut = ''; if ($filetype eq 'html') { - $cleanbut=''; + $cleanbut=''; } my $titledisplay=&display_title(); + my %lt=&Apache::lonlocal::texthash('st' => 'Save this', + 'vi' => 'View', + 'ed' => 'Edit'); my $buttons=(< - + + BUTTONS + $buttons.=&Apache::lonhtmlcommon::spelllink('xmledit','filecont'); + $buttons.=&Apache::lonhtmlcommon::htmlareaselectactive('filecont'); my $editfooter=(< -
+ $xml_help - + $buttons
- +
$buttons
$titledisplay + ENDFOOTER # $result=~s/(\]*\>)/$1$editheader/is; $result=~s/(\<\/body\>)/$editfooter/is; @@ -1149,9 +1242,9 @@ sub handler { $Apache::lonxml::debug=$ENV{'user.debug'}; if ($ENV{'browser.mathml'}) { - $request->content_type('text/xml'); + &Apache::loncommon::content_type($request,'text/xml'); } else { - $request->content_type('text/html'); + &Apache::loncommon::content_type($request,'text/html'); } &Apache::loncommon::no_cache($request); $request->send_http_header; @@ -1172,7 +1265,10 @@ sub handler { unless ($ENV{'request.state'} eq 'published') { if (($ENV{'form.savethisfile'}) || ($ENV{'form.attemptclean'})) { if (&storefile($file,$ENV{'form.filecont'})) { - $request->print("Updated: ". strftime("%d %b %H:%M:%S",localtime())." "); + &Apache::lonxml::info("". + &mt('Updated').": ". + &Apache::lonlocal::locallocaltime(time). + " "); } } } @@ -1180,13 +1276,15 @@ sub handler { my $result = ''; my $filecontents=&Apache::lonnet::getfile($file); if ($filecontents eq -1) { + my $bodytag=&Apache::loncommon::bodytag('File Error'); + my $fnf=&mt('File not found'); $result=(< -File not found +$fnf - -File not found: $file +$bodytag +$fnf: $file ENDNOTFOUND @@ -1222,7 +1320,9 @@ ENDNOTFOUND if ($ENV{'form.editmode'} && (!($ENV{'form.viewmode'}))) { my $displayfile=$request->uri; $displayfile=~s/^\/[^\/]*//; - $result='

'.$displayfile. + $result=''. + &Apache::lonxml::message_location().'

'. + $displayfile. '

'; $result=&inserteditinfo($result,$filecontents,$filetype); } @@ -1230,7 +1330,7 @@ ENDNOTFOUND if ($filetype eq 'html') { writeallows($request->uri); } - + &Apache::lonxml::add_messages(\$result); $request->print($result); return OK; @@ -1250,46 +1350,90 @@ sub display_title { } sub debug { - if ($Apache::lonxml::debug eq 1) { - $|=1; - print('DEBUG:'.&HTML::Entities::encode($_[0])."\n"); - } + if ($Apache::lonxml::debug eq "1") { + $|=1; + my $request=$Apache::lonxml::request; + if (!$request) { $request=Apache->request; } + $request->print('
DEBUG:'.&HTML::Entities::encode($_[0],'<>&"')."
\n"); +# &Apache::lonnet::logthis($_[0]); + } } sub error { - $errorcount++; - if (($Apache::lonxml::debug eq 1) || ($ENV{'request.state'} eq 'construct') ) { - # If printing in construction space, put the error inside

-    print "ERROR:".join("\n",@_)."\n";
-  } else {
-    print "An Error occured while processing this resource. The instructor has been notified. 
"; - #notify author - &Apache::lonmsg::author_res_msg($ENV{'request.filename'},join('
',@_)); - #notify course - if ( $ENV{'request.course.id'} ) { - my (undef,%users)=&Apache::lonfeedback::decide_receiver(undef,0,1,1,1); - my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'}); - foreach (keys %users) { - my ($user,$domain) = split(/:/, $_); - &Apache::lonmsg::user_normal_msg($user,$domain, - "Error [$declutter]",join('
',@_)); - } + $errorcount++; + if (($Apache::lonxml::debug eq 1) || ($ENV{'request.state'} eq 'construct') ) { + # If printing in construction space, put the error inside

+	push(@Apache::lonxml::error_messages,
+	     $Apache::lonxml::warnings_error_header.
+	     "ERROR:".join("
\n",@_)."
\n"); + $Apache::lonxml::warnings_error_header=''; + } else { + my $errormsg; + my ($symb)=&Apache::lonnet::symbread(); + if ( !$symb ) { + #public or browsers + $errormsg=&mt("An error occured while processing this resource. The author has been notified."); + } + #notify author + &Apache::lonmsg::author_res_msg($ENV{'request.filename'},join('
',@_)); + #notify course + if ( $symb && $ENV{'request.course.id'} ) { + my (undef,%users)=&Apache::lonfeedback::decide_receiver(undef,0,1,1,1); + my $declutter=&Apache::lonnet::declutter($ENV{'request.filename'}); + my @userlist; + foreach (keys %users) { + my ($user,$domain) = split(/:/, $_); + push(@userlist,"$user\@$domain"); + &Apache::lonmsg::user_normal_msg($user,$domain, + "Error [$declutter]",join('
',@_)); + } + if ($ENV{'request.role.adv'}) { + $errormsg=&mt("An error occured while processing this resource. The course personnel ([_1]) and the author have been notified.",join(', ',@userlist)); + } else { + $errormsg=&mt("An error occured while processing this resource. The instructor has been notified."); + } + } + push(@Apache::lonxml::error_messages,"$errormsg
"); } - - #FIXME probably shouldn't have me get everything forever. - &Apache::lonmsg::user_normal_msg('albertel','msu',"Error in $ENV{'request.filename'}",join('
',@_)); - #&Apache::lonmsg::user_normal_msg('albertel','103',"Error in $ENV{'request.filename'}",$_[0]); - } } sub warning { - $warningcount++; + $warningcount++; - if ($ENV{'form.grade_target'} ne 'tex') { - if ($ENV{'request.state'} eq 'construct' || $Apache::lonxml::debug) { - print "WARNING:".join('
',@_)."
\n"; - } - } + if ($ENV{'form.grade_target'} ne 'tex') { + if ($ENV{'request.state'} eq 'construct' || $Apache::lonxml::debug) { + my $request=$Apache::lonxml::request; + if (!$request) { $request=Apache->request; } + push(@Apache::lonxml::warning_messages, + $Apache::lonxml::warnings_error_header. + "WARNING:".join('
',@_)."
\n"); + $Apache::lonxml::warnings_error_header=''; + } + } +} + +sub info { + if ($ENV{'form.grade_target'} ne 'tex' + && $ENV{'request.state'} eq 'construct') { + push(@Apache::lonxml::info_messages,join('
',@_)."
\n"); + } +} + +sub message_location { + return '__LONCAPA_INTERNAL_MESSAGE_LOCATION__'; +} + +sub add_messages { + my ($msg)=@_; + my $result=join(' ', + @Apache::lonxml::info_messages, + @Apache::lonxml::error_messages, + @Apache::lonxml::warning_messages); + undef(@Apache::lonxml::info_messages); + undef(@Apache::lonxml::error_messages); + undef(@Apache::lonxml::warning_messages); + $$msg=~s/__LONCAPA_INTERNAL_MESSAGE_LOCATION__/$result/; + $$msg=~s/__LONCAPA_INTERNAL_MESSAGE_LOCATION__//g; } sub get_param { @@ -1297,6 +1441,9 @@ sub get_param { if ( ! $context ) { $context = -1; } my $args =''; if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; } + if ( ! $Apache::lonxml::usestyle ) { + $args=$Apache::lonxml::style_values.$args; + } if ( ! $args ) { return undef; } if ( $case_insensitive ) { if ($args =~ s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei) { @@ -1320,6 +1467,9 @@ sub get_param_var { if ( ! $context ) { $context = -1; } my $args =''; if ( $#$parstack > (-2-$context) ) { $args=$$parstack[$context]; } + if ( ! $Apache::lonxml::usestyle ) { + $args=$Apache::lonxml::style_values.$args; + } &Apache::lonxml::debug("Args are $args param is $param"); if ($case_insensitive) { if (! ($args=~s/(my \$)(\Q$param\E)(=\")/$1.lc($2).$3/ei)) { @@ -1328,7 +1478,7 @@ sub get_param_var { } elsif ( $args !~ /my \$\Q$param\E=\"/ ) { return undef; } my $value=&Apache::run::run("{$args;".'return $'.$param.'}',$safeeval); #' &Apache::lonxml::debug("first run is $value"); - if ($value =~ /^[\$\@\%]\w+$/) { + if ($value =~ /^[\$\@\%][a-zA-Z_]\w*$/) { &Apache::lonxml::debug("doing second"); my @result=&Apache::run::run("return $value",$safeeval,1); if (!defined($result[0])) {