--- loncom/xml/lonxml.pm 2004/07/27 23:35:34 1.333 +++ loncom/xml/lonxml.pm 2005/05/03 06:44:56 1.373 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # XML Parser Module # -# $Id: lonxml.pm,v 1.333 2004/07/27 23:35:34 www Exp $ +# $Id: lonxml.pm,v 1.373 2005/05/03 06:44:56 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -51,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) = @_; @@ -81,7 +81,7 @@ use Apache::languagetags(); use Apache::edit(); use Apache::inputtags(); use Apache::outputtags(); -use Apache::lonnet(); +use Apache::lonnet; use Apache::File(); use Apache::loncommon(); use Apache::lonfeedback(); @@ -149,29 +149,50 @@ $Apache::lonxml::post_evaluate=1; $Apache::lonxml::warnings_error_header=''; sub xmlbegin { - my $output=''; - @htmlareafields=(); - if ($ENV{'browser.mathml'}) { - $output='' - .'' - .']>' + my ($style)=@_; + my $output=''; + @htmlareafields=(); + if ($env{'browser.mathml'}) { + $output='' + #.''."\n" +# .'] >' + .'' .''; - } else { - $output=''; - } - return $output; + .'xmlns="http://www.w3.org/1999/xhtml">'; + } else { + $output=''; + } + if ($style eq 'encode') { + $output=&HTML::Entities::encode($output,'<>&"'); + } + return $output; } sub xmlend { + my ($target,$parser)=@_; my $mode='xml'; my $status='OPEN'; - if ($Apache::lonhomework::parsing_a_problem) { + if ($Apache::lonhomework::parsing_a_problem || + $Apache::lonhomework::parsing_a_task ) { $mode='problem'; $status=$Apache::inputtags::status[-1]; } - return &Apache::lonfeedback::list_discussion($mode,$status).''; + my $discussion; + &Apache::loncommon::get_unprocessed_cgi + ($env{'query_string'},['LONCAPA_INTERNAL_no_discussion']); + if (! exists($env{'form.LONCAPA_INTERNAL_no_discussion'}) || + $env{'form.LONCAPA_INTERNAL_no_discussion'} ne 'true') { + $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.&Apache::loncommon::endbodytag(); + } } sub tokeninputfield { @@ -229,9 +250,9 @@ sub maketoken { $symb=&Apache::lonnet::symbread(); } unless ($tuname) { - $tuname=$ENV{'user.name'}; - $tudom=$ENV{'user.domain'}; - $tcrsid=$ENV{'request.course.id'}; + $tuname=$env{'user.name'}; + $tudom=$env{'user.domain'}; + $tcrsid=$env{'request.course.id'}; } return &Apache::lonnet::checkout($symb,$tuname,$tudom,$tcrsid); @@ -267,7 +288,7 @@ sub printtokenheader { '
'.&mt('User').': '.$tuname.' at '.$tudom. '
'.&mt('ID').': '.$idhash{$tuname}. '
'.&mt('CourseID').': '.$tcrsid. - '
'.&mt('Course').': '.$ENV{'course.'.$tcrsid.'.description'}. + '
'.&mt('Course').': '.$env{'course.'.$tcrsid.'.description'}. '
'.&mt('DocID').': '.$token. '
'.&mt('Time').': '.&Apache::lonlocal::locallocaltime().'
'; } else { @@ -275,12 +296,12 @@ sub printtokenheader { } } -sub fontsettings() { +sub fontsettings { my $headerstring=''; - if (($ENV{'browser.os'} eq 'mac') && (!$ENV{'browser.mathml'})) { + if (($env{'browser.os'} eq 'mac') && (!$env{'browser.mathml'})) { $headerstring.= - ''; - } elsif (!$ENV{'browser.mathml'} && $ENV{'browser.unicode'}) { + ''; + } elsif (!$env{'browser.mathml'} && $env{'browser.unicode'}) { $headerstring.= ''; } @@ -300,6 +321,7 @@ sub xmlparse { &setup_globals($request,$target); &Apache::inputtags::initialize_inputtags(); + &Apache::bridgetask::initialize_bridgetask(); &Apache::outputtags::initialize_outputtags(); &Apache::edit::initialize_edit(); &Apache::londefdef::initialize_londefdef(); @@ -308,19 +330,21 @@ sub xmlparse { # do we have a course style file? # - if ($ENV{'request.course.id'} && $ENV{'request.state'} ne 'construct') { + if ($env{'request.course.id'} && $env{'request.state'} ne 'construct') { my $bodytext= - $ENV{'course.'.$ENV{'request.course.id'}.'.default_xml_style'}; + $env{'course.'.$env{'request.course.id'}.'.default_xml_style'}; if ($bodytext) { - my $location=&Apache::lonnet::filelocation('',$bodytext); - 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'}); + 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, @@ -329,7 +353,7 @@ sub xmlparse { } #&printalltags(); my @pars = (); - my $pwd=$ENV{'request.filename'}; + my $pwd=$env{'request.filename'}; $pwd =~ s:/[^/]*$::; &newparser(\@pars,\$content_file_string,$pwd); @@ -342,38 +366,47 @@ sub xmlparse { my @stack = (); my @parstack = (); - &initdepth; - + &initdepth(); + &init_alarm(); my $finaloutput = &inner_xmlparse($target,\@stack,\@parstack,\@pars, $safeeval,\%style_for_target); - if ($ENV{'request.uri'}) { - &writeallows($ENV{'request.uri'}); + if ($env{'request.uri'}) { + &writeallows($env{'request.uri'}); } &do_registered_ssi(); if ($Apache::lonxml::counter_changed) { &store_counter() } + if ($env{'form.return_only_error_and_warning_counts'}) { + return "$errorcount:$warningcount"; + } return $finaloutput; } sub htmlclean { my ($raw,$full)=@_; +# Take care of CRLF etc - my $tree = HTML::TreeBuilder->new; - $tree->ignore_unknown(0); - - $tree->parse($raw); - - my $output= $tree->as_HTML(undef,' '); - - $output=~s/\<(br|hr|img|meta|allow)(.*?)\>/\<$1$2 \/\>/gis; - $output=~s/\<\/(br|hr|img|meta|allow)\>//gis; + $raw=~s/\r\f/\n/gs; $raw=~s/\f\r/\n/gs; + $raw=~s/\r\n/\n/gs; $raw=~s/\n\r/\n/gs; + $raw=~s/\f/\n/gs; $raw=~s/\r/\n/gs; + $raw=~s/\&\#10\;/\n/gs; $raw=~s/\&\#13\;/\n/gs; + +# Generate empty tags, remove wrong end tags + $raw=~s/\<(br|hr|img|meta|allow|basefont)([^\>\/]*?)\>/\<$1$2 \/\>/gis; + $raw=~s/\<\/(br|hr|img|meta|allow|basefont)\>//gis; unless ($full) { - $output=~s/\<[\/]*(body|head|html)\>//gis; + $raw=~s/\<[\/]*(body|head|html)\>//gis; } - - $tree = $tree->delete; - - return $output; +# Make standard tags lowercase + foreach ('html','body','head','meta','h1','h2','h3','h4','b','i','m', + 'table','tr','td','th','p','br','hr','img','embed','font', + 'a','strong','center','title','basefont','li','ol','ul', + 'input','select','form','option','script','pre') { + $raw=~s/\<$_\s*\>/\<$_\>/gis; + $raw=~s/\<\/$_\s*\>/<\/$_\>/gis; + $raw=~s/\<$_\s([^\>]*)\>/<$_ $1\>/gis; + } + return $raw; } sub latex_special_symbols { @@ -388,18 +421,17 @@ sub latex_special_symbols { $string=~s/([^\\])\#/$1\\\#/g; } else { $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/\\\%|\%/\\\%/g; + $string=~s/\\{|{/\\{/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/\\\&|\&/\\\&/g; + $string=~s/\\\#|\#/\\\#/g; $string=~s/\|/\$\\mid\$/g; #single { or } How to escape? } @@ -663,12 +695,15 @@ sub init_safespace { $safeeval->permit(":base_math"); $safeeval->permit("sort"); $safeeval->permit("time"); + $safeeval->deny("rand"); + $safeeval->deny("srand"); $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(\&Apache::response::check_status,$safeeval,'&check_status'); $safehole->wrap(\&Math::Cephes::asin,$safeeval,'&asin'); $safehole->wrap(\&Math::Cephes::acos,$safeeval,'&acos'); @@ -749,13 +784,18 @@ sub init_safespace { # $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.'";'; - &Apache::lonxml::debug("Setting rndseed to $rndseed"); &Apache::run::run($safeinit,$safeeval); + &initialize_rndseed($safeeval); +} +sub initialize_rndseed { + my ($safeeval)=@_; + my $rndseed; + my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser(); + $rndseed=&Apache::lonnet::rndseed($symb,$courseid,$domain,$name); + my $safeinit = '$external::randomseed="'.$rndseed.'";'; + &Apache::lonxml::debug("Setting rndseed to $rndseed"); + &Apache::run::run($safeinit,$safeeval); } sub default_homework_load { @@ -770,6 +810,28 @@ sub default_homework_load { } } +{ + my $alarm_depth; + sub init_alarm { + alarm(0); + $alarm_depth=0; + } + + sub start_alarm { + if ($alarm_depth<1) { + my $old=alarm($Apache::lonnet::perlvar{'lonScriptTimeout'}); + if ($old) { + &Apache::lonxml::error("Cancelled an alarm of $old, this shouldn't occur."); + } + } + $alarm_depth++; + } + + sub end_alarm { + $alarm_depth--; + if ($alarm_depth<1) { alarm(0); } + } +} my $metamode_was; sub startredirection { if (!$Apache::lonxml::redirection) { @@ -805,6 +867,8 @@ sub initdepth { $Apache::lonxml::olddepth=-1; } +my @timers; +my $lasttime; sub increasedepth { my ($token) = @_; $Apache::lonxml::depth++; @@ -812,8 +876,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"; } @@ -828,8 +899,15 @@ sub decreasedepth { &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"; } @@ -872,8 +950,8 @@ sub increment_counter { } sub init_counter { - if (defined($ENV{'form.counter'})) { - $Apache::lonxml::counter=$ENV{'form.counter'}; + if (defined($env{'form.counter'})) { + $Apache::lonxml::counter=$env{'form.counter'}; $Apache::lonxml::counter_changed=0; } else { $Apache::lonxml::counter=1; @@ -987,7 +1065,8 @@ sub get_all_text { sub newparser { my ($parser,$contentref,$dir) = @_; push (@$parser,HTML::LCParser->new($contentref)); - $$parser['-1']->xml_mode('1'); + $$parser[-1]->xml_mode(1); + $$parser[-1]->marked_sections(1); if ( $dir eq '' ) { push (@Apache::lonxml::pwd, $Apache::lonxml::pwd[$#Apache::lonxml::pwd]); } else { @@ -1002,6 +1081,8 @@ sub parstring { unless ($_=~/\W/) { my $val=$token->[2]->{$_}; $val =~ s/([\%\@\\\"\'])/\\$1/g; + $val =~ s/(\$[^{a-zA-Z_])/\\$1/g; + $val =~ s/(\$)$/\\$1/; #if ($val =~ m/^[\%\@]/) { $val="\\".$val; } $temp .= "my \$$_=\"$val\";"; } @@ -1012,8 +1093,8 @@ sub parstring { sub writeallows { unless ($#extlinks>=0) { return; } my $thisurl='/res/'.&Apache::lonnet::declutter(shift); - if ($ENV{'httpref.'.$thisurl}) { - $thisurl=$ENV{'httpref.'.$thisurl}; + if ($env{'httpref.'.$thisurl}) { + $thisurl=$env{'httpref.'.$thisurl}; } my $thisdir=$thisurl; $thisdir=~s/\/[^\/]+$//; @@ -1046,24 +1127,24 @@ sub afterburn { my $result=shift; &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['highlight','anchor','link']); - if ($ENV{'form.highlight'}) { - foreach (split(/\,/,$ENV{'form.highlight'})) { + if ($env{'form.highlight'}) { + foreach (split(/\,/,$env{'form.highlight'})) { my $anchorname=$_; my $matchthis=$anchorname; $matchthis=~s/\_+/\\s\+/g; $result=~s/(\Q$matchthis\E)/\$1\<\/font\>/gs; } } - if ($ENV{'form.link'}) { - foreach (split(/\,/,$ENV{'form.link'})) { + if ($env{'form.link'}) { + foreach (split(/\,/,$env{'form.link'})) { my ($anchorname,$linkurl)=split(/\>/,$_); my $matchthis=$anchorname; $matchthis=~s/\_+/\\s\+/g; $result=~s/(\Q$matchthis\E)/\$1\<\/a\>/gs; } } - if ($ENV{'form.anchor'}) { - my $anchorname=$ENV{'form.anchor'}; + if ($env{'form.anchor'}) { + my $anchorname=$env{'form.anchor'}; my $matchthis=$anchorname; $matchthis=~s/\_+/\\s\+/g; $result=~s/(\Q$matchthis\E)/\$1\<\/a\>/s; @@ -1128,7 +1209,10 @@ sub inserteditinfo { if ($filetype eq 'html') { my $addbuttons=&Apache::lonhtmlcommon::htmlareaaddbuttons(); $initialize=&Apache::lonhtmlcommon::htmlareaheaders(). - &Apache::lonhtmlcommon::spellheader().(< $addbuttons @@ -1141,6 +1225,15 @@ $addbuttons } FULLPAGE + } else { + $initialize.=(< +$addbuttons + function initDocument() { + } + +FULLPAGE + } $result=~s/\]*)\>/\/i; $xml_help=&Apache::loncommon::helpLatexCheatsheet(); } @@ -1159,6 +1252,7 @@ $cleanbut BUTTONS $buttons.=&Apache::lonhtmlcommon::spelllink('xmledit','filecont'); + $buttons.=&Apache::lonhtmlcommon::htmlareaselectactive('filecont'); my $editfooter=(< @@ -1167,7 +1261,7 @@ $initialize $xml_help $buttons
- +
$buttons
@@ -1180,24 +1274,24 @@ ENDFOOTER } sub get_target { - my $viewgrades=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'}); - if ( $ENV{'request.state'} eq 'published') { - if ( defined($ENV{'form.grade_target'}) + my $viewgrades=&Apache::lonnet::allowed('vgr',$env{'request.course.id'}); + if ( $env{'request.state'} eq 'published') { + if ( defined($env{'form.grade_target'}) && ($viewgrades == 'F' )) { - return ($ENV{'form.grade_target'}); - } elsif (defined($ENV{'form.grade_target'})) { - if (($ENV{'form.grade_target'} eq 'web') || - ($ENV{'form.grade_target'} eq 'tex') ) { - return $ENV{'form.grade_target'} + return ($env{'form.grade_target'}); + } elsif (defined($env{'form.grade_target'})) { + if (($env{'form.grade_target'} eq 'web') || + ($env{'form.grade_target'} eq 'tex') ) { + return $env{'form.grade_target'} } else { return 'web'; } } else { return 'web'; } - } elsif ($ENV{'request.state'} eq 'construct') { - if ( defined($ENV{'form.grade_target'})) { - return ($ENV{'form.grade_target'}); + } elsif ($env{'request.state'} eq 'construct') { + if ( defined($env{'form.grade_target'})) { + return ($env{'form.grade_target'}); } else { return 'web'; } @@ -1211,14 +1305,14 @@ sub handler { my $target=&get_target(); - $Apache::lonxml::debug=$ENV{'user.debug'}; + $Apache::lonxml::debug=$env{'user.debug'}; - if ($ENV{'browser.mathml'}) { - &Apache::loncommon::content_type($request,'text/xml'); - } else { - &Apache::loncommon::content_type($request,'text/html'); - } + &Apache::loncommon::content_type($request,'text/html'); &Apache::loncommon::no_cache($request); + if ($env{'request.state'} eq 'published') { + $request->set_last_modified(&Apache::lonnet::metadata($request->uri, + 'lastrevisiondate')); + } $request->send_http_header; return OK if $request->header_only; @@ -1234,9 +1328,9 @@ sub handler { # # Edit action? Save file. # - unless ($ENV{'request.state'} eq 'published') { - if (($ENV{'form.savethisfile'}) || ($ENV{'form.attemptclean'})) { - if (&storefile($file,$ENV{'form.filecont'})) { + unless ($env{'request.state'} eq 'published') { + if (($env{'form.savethisfile'}) || ($env{'form.attemptclean'})) { + if (&storefile($file,$env{'form.filecont'})) { &Apache::lonxml::info("". &mt('Updated').": ". &Apache::lonlocal::locallocaltime(time). @@ -1260,18 +1354,22 @@ $bodytag ENDNOTFOUND - $filecontents=''; - if ($ENV{'request.state'} ne 'published') { + $filecontents=''; + if ($env{'request.state'} ne 'published') { if ($filetype eq 'sty') { $filecontents=&createnewsty(); } else { $filecontents=&createnewhtml(); } - $ENV{'form.editmode'}='Edit'; #force edit mode + $env{'form.editmode'}='Edit'; #force edit mode } } else { - unless ($ENV{'request.state'} eq 'published') { - if ($ENV{'form.attemptclean'}) { + unless ($env{'request.state'} eq 'published') { + if ($filecontents=~/BEGIN LON-CAPA Internal/) { + &Apache::lonxml::error(&mt('This file appears to be a rendering of a Lon-CAPA resource. If this is correct, this resource will act very oddly and incorrectly.')); + } + + if ($env{'form.attemptclean'}) { $filecontents=&htmlclean($filecontents,1); } # @@ -1279,20 +1377,25 @@ ENDNOTFOUND &Apache::loncommon::get_unprocessed_cgi ($ENV{'QUERY_STRING'},['editmode']); } - if (!$ENV{'form.editmode'} || $ENV{'form.viewmode'}) { + if (!$env{'form.editmode'} || $env{'form.viewmode'}) { $result = &Apache::lonxml::xmlparse($request,$target,$filecontents, '',%mystyle); + undef($Apache::lonhomework::parsing_a_task); } } # # Edit action? Insert editing commands # - unless ($ENV{'request.state'} eq 'published') { - if ($ENV{'form.editmode'} && (!($ENV{'form.viewmode'}))) { + unless ($env{'request.state'} eq 'published') { + if ($env{'form.editmode'} && (!($env{'form.viewmode'}))) { my $displayfile=$request->uri; $displayfile=~s/^\/[^\/]*//; - $result=''. + my $bodytag=''; + if ($env{'environment.remote'} eq 'off') { + $bodytag=&Apache::loncommon::bodytag(); + } + $result=''.$bodytag. &Apache::lonxml::message_location().'

'. $displayfile. '

'; @@ -1310,10 +1413,10 @@ ENDNOTFOUND sub display_title { my $result; - if ($ENV{'request.state'} eq 'construct') { + if ($env{'request.state'} eq 'construct') { my $title=&Apache::lonnet::gettitle(); if (!defined($title) || $title eq '') { - $title = $ENV{'request.filename'}; + $title = $env{'request.filename'}; $title = substr($title, rindex($title, '/') + 1); } $result = ""; @@ -1327,43 +1430,65 @@ sub debug { my $request=$Apache::lonxml::request; if (!$request) { $request=Apache->request; } $request->print('
DEBUG:'.&HTML::Entities::encode($_[0],'<>&"')."
\n"); -# &Apache::lonnet::logthis($_[0]); + #&Apache::lonnet::logthis($_[0]); + } +} + +sub show_error_warn_msg { + if ($env{'request.filename'} eq '/home/httpd/html/res/lib/templates/simpleproblem.problem' && + &Apache::lonnet::allowed('mdc',$env{'request.course.id'})) { + return 1; } + return (($Apache::lonxml::debug eq 1) || + ($env{'request.state'} eq 'construct') || + ($Apache::lonhomework::browse eq 'F' + && + $env{'form.show_errors'} eq 'on')); } sub error { - $errorcount++; - my $request=$Apache::lonxml::request; - if (!$request) { $request=Apache->request; } - 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 { - push(@Apache::lonxml::error_messages, - "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 ( &show_error_warn_msg() ) { + # 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
"); } - } } sub warning { $warningcount++; - if ($ENV{'form.grade_target'} ne 'tex') { - if ($ENV{'request.state'} eq 'construct' || $Apache::lonxml::debug) { + if ($env{'form.grade_target'} ne 'tex') { + if ( &show_error_warn_msg() ) { my $request=$Apache::lonxml::request; if (!$request) { $request=Apache->request; } push(@Apache::lonxml::warning_messages, @@ -1375,8 +1500,8 @@ sub warning { } sub info { - if ($ENV{'form.grade_target'} ne 'tex' - && $ENV{'request.state'} eq 'construct') { + if ($env{'form.grade_target'} ne 'tex' + && $env{'request.state'} eq 'construct') { push(@Apache::lonxml::info_messages,join('
',@_)."
\n"); } } @@ -1440,7 +1565,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])) { @@ -1527,30 +1652,37 @@ sub helpinfo { sub whichuser { my ($passedsymb)=@_; my ($symb,$courseid,$domain,$name,$publicuser); - if (defined($ENV{'form.grade_symb'})) { - my $tmp_courseid=$ENV{'form.grade_courseid'}; - my $allowed=&Apache::lonnet::allowed('vgr',$tmp_courseid); - if ($allowed) { - $symb=$ENV{'form.grade_symb'}; - $courseid=$ENV{'form.grade_courseid'}; - $domain=$ENV{'form.grade_domain'}; - $name=$ENV{'form.grade_username'}; - } - } else { - if (!$passedsymb) { - $symb=&Apache::lonnet::symbread(); - } else { - $symb=$passedsymb; + if (defined($env{'form.grade_symb'})) { + my ($tmp_courseid)= + &Apache::loncommon::get_env_multiple('form.grade_courseid'); + my $allowed=&Apache::lonnet::allowed('vgr',$tmp_courseid); + if (!$allowed && + exists($env{'request.course.sec'}) && + $env{'request.course.sec'} !~ /^\s*$/) { + $allowed=&Apache::lonnet::allowed('vgr',$tmp_courseid. + '/'.$env{'request.course.sec'}); } - $courseid=$ENV{'request.course.id'}; - $domain=$ENV{'user.domain'}; - $name=$ENV{'user.name'}; - if ($name eq 'public' && $domain eq 'public') { - if (!defined($ENV{'form.username'})) { - $ENV{'form.username'}.=time.rand(10000000); - } - $name.=$ENV{'form.username'}; + if ($allowed) { + ($symb)=&Apache::loncommon::get_env_multiple('form.grade_symb'); + $courseid=$tmp_courseid; + ($domain)=&Apache::loncommon::get_env_multiple('form.grade_domain'); + ($name)=&Apache::loncommon::get_env_multiple('form.grade_username'); + return ($symb,$courseid,$domain,$name,$publicuser); + } + } + if (!$passedsymb) { + $symb=&Apache::lonnet::symbread(); + } else { + $symb=$passedsymb; + } + $courseid=$env{'request.course.id'}; + $domain=$env{'user.domain'}; + $name=$env{'user.name'}; + if ($name eq 'public' && $domain eq 'public') { + if (!defined($env{'form.username'})) { + $env{'form.username'}.=time.rand(10000000); } + $name.=$env{'form.username'}; } return ($symb,$courseid,$domain,$name,$publicuser); }