--- loncom/xml/lonxml.pm 2003/09/14 23:57:18 1.276 +++ loncom/xml/lonxml.pm 2004/03/02 22:45:56 1.307 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # XML Parser Module # -# $Id: lonxml.pm,v 1.276 2003/09/14 23:57:18 www Exp $ +# $Id: lonxml.pm,v 1.307 2004/03/02 22:45:56 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -96,6 +96,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 +106,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 @@ -159,6 +161,15 @@ $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=''; if ($ENV{'browser.mathml'}) { @@ -175,18 +186,13 @@ sub xmlbegin { } sub xmlend { - my ($discussiononly,$symb)=@_; - my $discussion=''; - if ($ENV{'request.course.id'}) { - my $crs='/'.$ENV{'request.course.id'}; - if ($ENV{'request.course.sec'}) { - $crs.='_'.$ENV{'request.course.sec'}; - } - $crs=~s/\_/\//g; - $discussion=&Apache::lonfeedback::list_discussion - ($crs,$symb,$discussiononly); + my $mode='xml'; + my $status='OPEN'; + if ($Apache::lonhomework::parsing_a_problem) { + $mode='problem'; + $status=$Apache::inputtags::status[-1]; } - return $discussion.($discussiononly?'':''); + return &Apache::lonfeedback::list_discussion($mode,$status).''; } sub tokeninputfield { @@ -278,13 +284,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; } @@ -317,6 +323,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? @@ -333,6 +340,13 @@ sub xmlparse { &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 = (); @@ -357,6 +371,7 @@ sub xmlparse { if ($ENV{'request.uri'}) { &writeallows($ENV{'request.uri'}); } + &do_registered_ssi(); if ($Apache::lonxml::counter_changed) { &store_counter() } return $finaloutput; } @@ -390,10 +405,13 @@ sub latex_special_symbols { $string =~ s/_/ /g; } else { $string=~s/\\ /\\char92 /g; - $string=~s/\^/\\char94 /g; + $string=~s/\^/\\\^\\strut /g; $string=~s/\~/\\char126 /g; - $string=~s/(&[^A-Za-z\#])/\\$1/g; - $string=~s/([^&])\#/$1\\#/g; + #fixup & if it doesn't look like + # { or α + $string=~s/(&(?!((\#[0-9]+)|([a-z]+));))/\\$1/gi; + $string=~s/([^&\\])\#/$1\\#/g; + $string=~s/\#\#/\#\\#/g; $string=~s/(\$|_|{|})/\\$1/g; $string=~s/\\char92 /\\texttt{\\char92}/g; $string=~s/(>|<)/\$$1\$/g; #more or less @@ -477,7 +495,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; @@ -488,6 +506,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)) { @@ -496,9 +516,9 @@ sub inner_xmlparse { } # Encode any high ASCII characters - if (!$Apache::lonxml::prevent_entity_encode) { - $result=&HTML::Entities::encode($result,"\200-\377"); - } +# if (!$Apache::lonxml::prevent_entity_encode) { +# $result=&HTML::Entities::encode($result,"\200-\377"); +# } if ($Apache::lonxml::redirection) { $Apache::lonxml::outputstack['-1'] .= $result; } else { @@ -607,6 +627,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; @@ -650,6 +673,7 @@ 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'); @@ -726,6 +750,7 @@ 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'); #need to inspect this class of ops # $safeeval->deny(":base_orig"); @@ -736,6 +761,28 @@ sub init_safespace { $safeinit .= ';$external::randomseed='.$rndseed.';'; &Apache::lonxml::debug("Setting rndseed to $rndseed"); &Apache::run::run($safeinit,$safeeval); + + my $subroutine=<<'EVALUATESUB'; +sub __LC_INTERNAL_EVALUATE__ { + my ($__LC__a,$__LC__b,$__LC__c)=@_; + my $__LC__prefix; + while(1){ + { + use strict; + no strict "vars"; + if (eval(defined(eval($__LC__a.$__LC__b)))) { + return $__LC__prefix.eval($__LC__a.$__LC__b.$__LC__c); + } + } + $__LC__prefix.=substr($__LC__a,0,1,""); + if ($__LC__a!~/^(\$|&|\#)/) { last; } + } + return $__LC__prefix.$__LC__a.$__LC__b.$__LC__c; +} +EVALUATESUB + $safeeval->permit("require"); + $safeeval->reval($subroutine); + $safeeval->deny("require"); } sub default_homework_load { @@ -797,7 +844,7 @@ 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 $curdepth=join('_',@Apache::lonxml::depthcounter); @@ -860,17 +907,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; @@ -894,7 +937,7 @@ sub get_all_text { } elsif ($token->[0] eq 'E') { if ( $token->[1] =~ /^$tag$/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]}. @@ -1002,6 +1045,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 # @@ -1041,6 +1097,7 @@ ENDSCRIPT sub storefile { my ($file,$contents)=@_; + &Apache::lonnet::correct_line_ends(\$contents); if (my $fh=Apache::File->new('>'.$file)) { print $fh $contents; $fh->close(); @@ -1092,21 +1149,24 @@ sub inserteditinfo { } 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 my $editfooter=(<
$xml_help - + $buttons

$buttons @@ -1154,9 +1214,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; @@ -1177,7 +1237,8 @@ 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())." "); + $request->print("".&mt('Updated').": ". +&Apache::lonlocal::locallocaltime(time)." "); } } } @@ -1185,13 +1246,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 @@ -1255,19 +1318,25 @@ 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"); + } } 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

-    print "ERROR:".join("\n",@_)."\n";
+      $request->print($Apache::lonxml::warnings_error_header.
+		      "ERROR:".join("
\n",@_)."
\n"); + $Apache::lonxml::warnings_error_header=''; } else { - print "An Error occured while processing this resource. The instructor has been notified.
"; + $request->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 @@ -1280,21 +1349,21 @@ sub error { "Error [$declutter]",join('
',@_)); } } - - #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; } + $request->print($Apache::lonxml::warnings_error_header. + "WARNING:".join('
',@_)."
\n"); + $Apache::lonxml::warnings_error_header=''; + } + } } sub get_param { @@ -1302,6 +1371,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) { @@ -1325,6 +1397,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)) {