--- loncom/xml/lonxml.pm 2004/10/18 19:50:43 1.332.2.2 +++ loncom/xml/lonxml.pm 2005/02/26 05:37:23 1.357 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # XML Parser Module # -# $Id: lonxml.pm,v 1.332.2.2 2004/10/18 19:50:43 albertel Exp $ +# $Id: lonxml.pm,v 1.357 2005/02/26 05:37:23 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) = @_; @@ -149,29 +149,43 @@ $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) { $mode='problem'; $status=$Apache::inputtags::status[-1]; } - return &Apache::lonfeedback::list_discussion($mode,$status).''; + 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 { @@ -275,11 +289,11 @@ sub printtokenheader { } } -sub fontsettings() { +sub fontsettings { my $headerstring=''; if (($ENV{'browser.os'} eq 'mac') && (!$ENV{'browser.mathml'})) { $headerstring.= - ''; + ''; } elsif (!$ENV{'browser.mathml'} && $ENV{'browser.unicode'}) { $headerstring.= ''; @@ -312,13 +326,15 @@ 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); - if ($styletext ne '-1') { - %style_for_target = (%style_for_target, - &Apache::style::styleparser($target,$styletext)); - } - } + 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); @@ -357,23 +373,29 @@ sub xmlparse { 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 { @@ -805,6 +827,8 @@ sub initdepth { $Apache::lonxml::olddepth=-1; } +my @timers; +my $lasttime; sub increasedepth { my ($token) = @_; $Apache::lonxml::depth++; @@ -812,8 +836,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 +859,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"; } @@ -1002,6 +1040,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\";"; } @@ -1127,7 +1167,11 @@ sub inserteditinfo { my $initialize=''; if ($filetype eq 'html') { my $addbuttons=&Apache::lonhtmlcommon::htmlareaaddbuttons(); - $initialize=&Apache::lonhtmlcommon::htmlareaheaders().(< $addbuttons @@ -1140,6 +1184,15 @@ $addbuttons } FULLPAGE + } else { + $initialize.=(< +$addbuttons + function initDocument() { + } + +FULLPAGE + } $result=~s/\]*)\>/\/i; $xml_help=&Apache::loncommon::helpLatexCheatsheet(); } @@ -1157,12 +1210,13 @@ $cleanbut BUTTONS + $buttons.=&Apache::lonhtmlcommon::spelllink('xmledit','filecont'); $buttons.=&Apache::lonhtmlcommon::htmlareaselectactive('filecont'); my $editfooter=(< -
+ $xml_help $buttons
@@ -1218,6 +1272,8 @@ sub handler { &Apache::loncommon::content_type($request,'text/html'); } &Apache::loncommon::no_cache($request); + $request->set_last_modified(&Apache::lonnet::metadata($request->uri, + 'lastrevisiondate')); $request->send_http_header; return OK if $request->header_only; @@ -1259,7 +1315,7 @@ $bodytag ENDNOTFOUND - $filecontents=''; + $filecontents=''; if ($ENV{'request.state'} ne 'published') { if ($filetype eq 'sty') { $filecontents=&createnewsty(); @@ -1270,6 +1326,10 @@ ENDNOTFOUND } } else { 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); } @@ -1291,7 +1351,11 @@ ENDNOTFOUND 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. '

'; @@ -1326,43 +1390,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 ( &show_error_warn_msg() ) { my $request=$Apache::lonxml::request; if (!$request) { $request=Apache->request; } push(@Apache::lonxml::warning_messages, @@ -1439,7 +1525,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,35 +1613,36 @@ 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 && - exists($ENV{'request.course.sec'}) && - $ENV{'request.course.sec'} !~ /^\s*$/) { - $allowed=&Apache::lonnet::allowed('vgr',$ENV{'form.grade_courseid'}. - '/'.$ENV{'request.course.sec'}); - } - 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; + 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); } 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.