--- loncom/xml/lonxml.pm 2003/08/13 14:23:37 1.271 +++ loncom/xml/lonxml.pm 2004/02/05 21:00:15 1.300 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # XML Parser Module # -# $Id: lonxml.pm,v 1.271 2003/08/13 14:23:37 www Exp $ +# $Id: lonxml.pm,v 1.300 2004/02/05 21:00:15 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,113 +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; - my $seeid=&Apache::lonnet::allowed('rin',$crs); - unless ($symb) { - $symb=&Apache::lonnet::symbread(); - } - if ($symb) { - my %contrib=&Apache::lonnet::restore($symb,$ENV{'request.course.id'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); - if ($contrib{'version'}) { - unless ($discussiononly) { - $discussion.= - '

'; - } - my $idx; - for ($idx=1;$idx<=$contrib{'version'};$idx++) { - my $hidden=($contrib{'hidden'}=~/\.$idx\./); - my $deleted=($contrib{'deleted'}=~/\.$idx\./); - unless ((($hidden) && (!$seeid)) || ($deleted)) { - my $message=$contrib{$idx.':message'}; - $message=~s/\n/\
/g; - $message=&Apache::lontexconvert::msgtexconverted($message); - if ($contrib{$idx.':attachmenturl'}) { - my ($fname,$ft) - =($contrib{$idx.':attachmenturl'}=~/\/(\w+)\.(\w+)$/); - $message.='

Attachment: '.$fname.'.'.$ft.''; - } - if ($message) { - if ($hidden) { - $message=''.$message.''; - } - my $screenname=&Apache::loncommon::screenname( - $contrib{$idx.':sendername'}, - $contrib{$idx.':senderdomain'}); - my $plainname=&Apache::loncommon::nickname( - $contrib{$idx.':sendername'}, - $contrib{$idx.':senderdomain'}); - - my $sender='Anonymous'; - if ((!$contrib{$idx.':anonymous'}) || ($seeid)) { - $sender=&Apache::loncommon::aboutmewrapper( - $plainname, - $contrib{$idx.':sendername'}, - $contrib{$idx.':senderdomain'}).' ('. - $contrib{$idx.':sendername'}.' at '. - $contrib{$idx.':senderdomain'}.')'; - if ($contrib{$idx.':anonymous'}) { - $sender.=' [anonymous] '. - $screenname; - } - if ($seeid) { - if ($hidden) { - $sender.=' Make Visible'; - } else { - $sender.=' Hide'; - } - $sender.=' Delete'; - } - } else { - if ($screenname) { - $sender=''.$screenname.''; - } - } - $discussion.='

'.$sender.' ('. - localtime($contrib{$idx.':timestamp'}). - '):

'.$message. - '

'; - } - } - } - unless ($discussiononly) { - $discussion.='
'; - } - } - if ($discussiononly) { - $discussion.=(< - - - - -
-Note: in anonymous discussion, your name is visible only to -course faculty
- -

-Attachment (128 KB max size): -

- -ENDDISCUSS - $discussion.=&Apache::lonfeedback::generate_preview_button(); - } - } + 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 { @@ -373,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; } @@ -412,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? @@ -428,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 = (); @@ -452,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; } @@ -478,24 +398,27 @@ sub htmlclean { } sub latex_special_symbols { - my ($current_token,$stack,$parstack,$where)=@_; + my ($string,$where)=@_; if ($where eq 'header') { - $current_token =~ s/(\\|_|\^)/ /g; - $current_token =~ s/(\$|%|\#|&|\{|\})/\\$1/g; + $string =~ s/(\\|_|\^)/ /g; + $string =~ s/(\$|%|\#|&|\{|\})/\\$1/g; + $string =~ s/_/ /g; } else { - $current_token=~s/\\ /\\char92 /g; - $current_token=~s/\^/\\char94 /g; - $current_token=~s/\~/\\char126 /g; - $current_token=~s/(&[^A-Za-z\#])/\\$1/g; - $current_token=~s/([^&])\#/$1\\#/g; - $current_token=~s/(\$|_|{|})/\\$1/g; - $current_token=~s/\\char92 /\\texttt{\\char92}/g; - $current_token=~s/(>|<)/\$$1\$/g; #more or less - if ($current_token=~m/\d%/) {$current_token =~ s/(\d)%/$1\\%/g;} #percent after digit - if ($current_token=~m/\s%/) {$current_token =~ s/(\s)%/$1\\%/g;} #persent after space - if ($current_token eq '%.') {$current_token = '\%.';} #persent at the end of statement + $string=~s/\\ /\\char92 /g; + $string=~s/\^/\\\^\\strut /g; + $string=~s/\~/\\char126 /g; + #fixup & if it doesn't look like + # { or α + $string=~s/(&(?!((\#[0-9]+)|([a-z]+));))/\\$1/gi; + $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 } - return $current_token; + return $string; } sub inner_xmlparse { @@ -571,7 +494,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; @@ -582,17 +505,19 @@ 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)) { - $result=&latex_special_symbols($result,$stack,$parstack); + $result=&latex_special_symbols($result); } } # 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 { @@ -701,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; @@ -744,6 +672,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'); @@ -891,7 +820,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); @@ -954,17 +883,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; @@ -988,7 +913,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]}. @@ -1096,6 +1021,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 # @@ -1135,6 +1073,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(); @@ -1163,25 +1102,47 @@ SIMPLECONTENT return $filecontents; } +sub createnewsty { + my $filecontents=(< + + + + + +SIMPLECONTENT + return $filecontents; +} + sub inserteditinfo { - my ($result,$filecontents)=@_; + my ($result,$filecontents,$filetype)=@_; $filecontents = &HTML::Entities::encode($filecontents); # my $editheader='Edit below
'; - my $xml_help = Apache::loncommon::helpLatexCheatsheet(); + my $xml_help = ''; + if ($filetype eq 'html') { + $xml_help=Apache::loncommon::helpLatexCheatsheet(); + } + my $cleanbut = ''; + if ($filetype eq 'html') { + $cleanbut=''; + } my $titledisplay=&display_title(); + my %lt=&Apache::lonlocal::texthash('st' => 'Save this', + 'vi' => 'View', + 'ed' => 'Edit'); my $buttons=(< - - +$cleanbut + + BUTTONS my $editfooter=(<
$xml_help - + $buttons

$buttons @@ -1229,9 +1190,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; @@ -1240,13 +1201,20 @@ sub handler { my $file=&Apache::lonnet::filelocation("",$request->uri); + my $filetype; + if ($file =~ /\.sty$/) { + $filetype='sty'; + } else { + $filetype='html'; + } # # Edit action? Save file. # 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)." "); } } } @@ -1254,19 +1222,25 @@ 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 $filecontents=''; if ($ENV{'request.state'} ne 'published') { - $filecontents=&createnewhtml(); + if ($filetype eq 'sty') { + $filecontents=&createnewsty(); + } else { + $filecontents=&createnewhtml(); + } $ENV{'form.editmode'}='Edit'; #force edit mode } } else { @@ -1294,11 +1268,11 @@ ENDNOTFOUND $displayfile=~s/^\/[^\/]*//; $result='

'.$displayfile. '

'; - $result=&inserteditinfo($result,$filecontents); + $result=&inserteditinfo($result,$filecontents,$filetype); } } - - writeallows($request->uri); + if ($filetype eq 'html') { writeallows($request->uri); } + $request->print($result); @@ -1320,19 +1294,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 @@ -1353,13 +1333,17 @@ sub error { } 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 { @@ -1367,6 +1351,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) { @@ -1390,6 +1377,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)) {