--- loncom/xml/lonxml.pm 2008/09/05 12:11:45 1.485 +++ loncom/xml/lonxml.pm 2010/08/08 02:00:44 1.513 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # XML Parser Module # -# $Id: lonxml.pm,v 1.485 2008/09/05 12:11:45 onken Exp $ +# $Id: lonxml.pm,v 1.513 2010/08/08 02:00:44 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -37,6 +37,25 @@ # to any other parties under any circumstances. # +=pod + +=head1 NAME + +Apache::lonxml + +=head1 SYNOPSIS + +XML Parsing Module + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + + +=head1 SUBROUTINES + +=cut + + package Apache::lonxml; use vars @@ -90,7 +109,9 @@ use Apache::lonfeedback(); use Apache::lonmsg(); use Apache::loncacc(); use Apache::lonmaxima(); +use Apache::lonr(); use Apache::lonlocal; +use Apache::lonhtmlcommon(); #==================================== Main subroutine: xmlparse @@ -201,101 +222,6 @@ sub xmlend { return $discussion; } -sub tokeninputfield { - my $defhost=$Apache::lonnet::perlvar{'lonHostID'}; - $defhost=~tr/a-z/A-Z/; - return (< - function updatetoken() { - var comp=new Array; - var barcode=unescape(document.tokeninput.barcode.value); - comp=barcode.split('*'); - if (typeof(comp[0])!="undefined") { - document.tokeninput.codeone.value=comp[0]; - } - if (typeof(comp[1])!="undefined") { - document.tokeninput.codetwo.value=comp[1]; - } - if (typeof(comp[2])!="undefined") { - comp[2]=comp[2].toUpperCase(); - document.tokeninput.codethree.value=comp[2]; - } - document.tokeninput.barcode.value=''; - } - -
- - - - -
DocID Checkin
- - - - - - - -
Scan in Barcode
or Type in DocID - -* - -* - -
-
-
-ENDINPUTFIELD -} - -sub maketoken { - my ($symb,$tuname,$tudom,$tcrsid)=@_; - unless ($symb) { - $symb=&Apache::lonnet::symbread(); - } - unless ($tuname) { - $tuname=$env{'user.name'}; - $tudom=$env{'user.domain'}; - $tcrsid=$env{'request.course.id'}; - } - - return &Apache::lonnet::checkout($symb,$tuname,$tudom,$tcrsid); -} - -sub printtokenheader { - my ($target,$token,$tsymb,$tcrsid,$tudom,$tuname)=@_; - unless ($token) { return ''; } - - my ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser(); - unless ($tsymb) { - $tsymb=$symb; - } - unless ($tuname) { - $tuname=$name; - $tudom=$domain; - $tcrsid=$courseid; - } - - my $plainname=&Apache::loncommon::plainname($tuname,$tudom); - - if ($target eq 'web') { - my %idhash=&Apache::lonnet::idrget($tudom,($tuname)); - return - ''. - &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; - } -} - sub printalltags { my $temp; foreach $temp (sort keys %Apache::lonxml::alltags) { @@ -505,11 +431,11 @@ sub inner_xmlparse { if (!$Apache::lonxml::usestyle) { $extras=$Apache::lonxml::style_values; } - if ( $#$parstack > -1 ) { - $result=&Apache::run::evaluate($result,$safeeval,$extras.$$parstack[-1]); - } else { - $result= &Apache::run::evaluate($result,$safeeval,$extras); - } + if ( $#$parstack > -1 ) { + $result=&Apache::run::evaluate($result,$safeeval,$extras.$$parstack[-1]); + } else { + $result= &Apache::run::evaluate($result,$safeeval,$extras); + } } $Apache::lonxml::post_evaluate=1; @@ -550,6 +476,10 @@ sub inner_xmlparse { } if (($ENV{'QUERY_STRING'}) && ($target eq 'web')) { $finaloutput=&afterburn($finaloutput); + } + if ($target eq 'modified') { +# if modfied, handle startpart and endpart + $finaloutput=~s/\]*\>(.*)\]*\>/$1<\/part>/gs; } return $finaloutput; } @@ -658,6 +588,7 @@ sub setup_globals { $Apache::lonxml::request=$request; $errorcount=0; $warningcount=0; + $Apache::lonxml::internal_error=0; $Apache::lonxml::default_homework_loaded=0; $Apache::lonxml::usestyle=1; &init_counter(); @@ -711,8 +642,9 @@ sub setup_globals { sub init_safespace { my ($target,$safeeval,$safehole,$safeinit) = @_; - $safeeval->deny_only(':dangerous'); $safeeval->reval('use Math::Complex;'); + $safeeval->reval('use LaTeX::Table;'); + $safeeval->deny_only(':dangerous'); $safeeval->permit_only(":default"); $safeeval->permit("entereval"); $safeeval->permit(":base_math"); @@ -735,6 +667,13 @@ sub init_safespace { $safehole->wrap(\&Apache::lonmaxima::maxima_cas_formula_fix,$safeeval, '&maxima_cas_formula_fix'); + $safehole->wrap(\&Apache::lonr::r_eval,$safeeval,'&r_eval'); + $safehole->wrap(\&Apache::lonr::Rentry,$safeeval,'&Rentry'); + $safehole->wrap(\&Apache::lonr::Rarray,$safeeval,'&Rarray'); + $safehole->wrap(\&Apache::lonr::r_check,$safeeval,'&r_check'); + $safehole->wrap(\&Apache::lonr::r_cas_formula_fix,$safeeval, + '&r_cas_formula_fix'); + $safehole->wrap(\&Apache::caparesponse::capa_formula_fix,$safeeval, '&capa_formula_fix'); @@ -1015,7 +954,7 @@ sub get_id { my ($parstack,$safeeval)=@_; my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval); if ($env{'request.state'} eq 'construct' && $id =~ /([._]|[^\w\d\s[:punct:]])/) { - &error(&mt("ID "[_1]" contains invalid characters, IDs are only allowed to contain letters, numbers, spaces and -",''.$id.'')); + &error(&mt('ID [_1] contains invalid characters. IDs are only allowed to contain letters, numbers, spaces and -','"'.$id.'"')); } if ($id =~ /^\s*$/) { $id = $Apache::lonxml::curdepth; } return $id; @@ -1484,6 +1423,15 @@ SIMPLECONTENT return $filecontents; } +sub createnewjs { + my $filecontents=(< + + +SIMPLECONTENT + return $filecontents; +} + sub verify_html { my ($filecontents)=@_; if ($filecontents!~/(?:\<|\<\;)(?:html|xml)[^\<]*(?:\>|\>\;)/is) { @@ -1509,20 +1457,30 @@ sub renderingoptions { = &Apache::loncommon::plainlanguagedescription($_); } } - return - ''. - &mt('Language:').' '. - &Apache::loncommon::select_form($env{'form.languages'},'languages', - %langchoices).' - - '. + my $output; + unless ($env{'form.forceedit'}) { + $output .= + ''. + &mt('Language:').' '. + &Apache::loncommon::select_form( + $env{'form.languages'}, + 'languages', + {&Apache::lonlocal::texthash(%langchoices)}). + ''; + } + $output .= + ' '. &mt('Math Rendering:').' '. - &Apache::loncommon::select_form($env{'form.texengine'},'texengine', - ('' => '', - 'tth' => 'tth (TeX to HTML)', - 'jsMath' => 'jsMath', - 'mimetex' => 'mimetex (Convert to Images)')).' - '; + &Apache::loncommon::select_form( + $env{'form.texengine'}, + 'texengine', + {&Apache::lonlocal::texthash + ('' => '', + 'tth' => 'tth (TeX to HTML)', + 'jsMath' => 'jsMath', + 'mimetex' => 'mimetex (Convert to Images)')}). + ''; + return $output; } sub inserteditinfo { @@ -1531,37 +1489,18 @@ sub inserteditinfo { my $xml_help = ''; my $initialize=''; my $textarea_id = 'filecont'; + my $dragmath_button; my ($add_to_onload, $add_to_onresize); $initialize=&Apache::lonhtmlcommon::spellheader(); - if ($filetype eq 'html' - && (!&Apache::lonhtmlcommon::htmlareablocked() && - &Apache::lonhtmlcommon::htmlareabrowser())) { - $textarea_id .= '___Frame'; + if (($filetype eq 'html') && (&Apache::lonhtmlcommon::htmlareabrowser())) { my $lang = &Apache::lonhtmlcommon::htmlarea_lang(); - $initialize.=(< -lonca - function initDocument() { - var oFCKeditor = new FCKeditor('filecont'); - oFCKeditor.Config['CustomConfigurationsPath'] = '/fckeditor/loncapaconfig.js' ; - oFCKeditor.Config['FullPage'] = true - oFCKeditor.Config['AutoDetectLanguage'] = false; - oFCKeditor.Config['DefaultLanguage'] = "$lang"; - oFCKeditor.ReplaceTextarea(); - } - function check_if_dirty(editor) { - if (editor.IsDirty()) { - unClean(); - } - } - function FCKeditor_OnComplete(editor) { - editor.Events.AttachEvent("OnSelectionChange",check_if_dirty); - resize_textarea('$textarea_id','LC_aftertextarea'); - } - -FULLPAGE - } else { - $initialize.=(< 'true', + dragmath => 'math', + ); + $initialize .= + &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args). + (< function initDocument() { resize_textarea('$textarea_id','LC_aftertextarea'); @@ -1569,6 +1508,10 @@ FULLPAGE FULLPAGE } + if ($filetype eq 'html' || $filetype eq 'tex') { + $dragmath_button = ''.&Apache::lonhtmlcommon::dragmath_button('filecont',1).''; + $initialize .= "\n".&Apache::lonhtmlcommon::dragmath_js('EditMathPopup'); + } $add_to_onload = 'initDocument();'; $add_to_onresize = "resize_textarea('$textarea_id','LC_aftertextarea');"; @@ -1578,17 +1521,24 @@ FULLPAGE } my $titledisplay=&display_title(); + my $textareaclass; my %lt=&Apache::lonlocal::texthash('st' => 'Save and Edit', 'vi' => 'Save and View', 'dv' => 'Discard Edits and View', 'un' => 'undo', 'ed' => 'Edit'); - my $spelllink .=&Apache::lonhtmlcommon::spelllink('xmledit','filecont'); + my $spelllink = &Apache::lonhtmlcommon::spelllink('xmledit','filecont'); my $textarea_events = &Apache::edit::element_change_detection(); my $form_events = &Apache::edit::form_change_detection(); - my $htmlerror=&verify_html($filecontents); - if ($htmlerror) { - $htmlerror=''.$htmlerror.''; + my $htmlerror; + if ($filetype eq 'html') { + $htmlerror=&verify_html($filecontents); + if ($htmlerror) { + $htmlerror=''.$htmlerror.''; + } + if (&Apache::lonhtmlcommon::htmlareabrowser()) { + $textareaclass = 'class="LC_richDetectHtml"'; + } } my $editfooter=(< - $spelllink $htmlerror + $htmlerror $dragmath_button
- +
$spelllink

$titledisplay @@ -1651,9 +1601,8 @@ sub get_target { sub handler { my $request=shift; - + my $target=&get_target(); - $Apache::lonxml::debug=$env{'user.debug'}; &Apache::loncommon::content_type($request,'text/html'); @@ -1662,18 +1611,47 @@ sub handler { $request->set_last_modified(&Apache::lonnet::metadata($request->uri, 'lastrevisiondate')); } + # Embedded Flash movies from Camtasia served from https will not display in IE + # if XML config file has expired from cache. + if ($ENV{'SERVER_PORT'} == 443) { + if ($request->uri =~ /\.xml$/) { + my ($httpbrowser,$clientbrowser) = + &Apache::loncommon::decode_user_agent($request); + if ($clientbrowser =~ /^explorer$/i) { + delete $request->headers_out->{'Cache-control'}; + delete $request->headers_out->{'Pragma'}; + my $expiration = time + 60; + my $date=strftime("%a, %d %b %Y %H:%M:%S GMT",gmtime($expiration)); + $request->headers_out->set("Expires" => $date); + } + } + } $request->send_http_header; return OK if $request->header_only; my $file=&Apache::lonnet::filelocation("",$request->uri); - my $filetype; - if ($file =~ /\.sty$/) { - $filetype='sty'; + my ($filetype,$breadcrumbtext); + if ($file =~ /\.(sty|css|js|txt|tex)$/) { + $filetype=$1; } else { $filetype='html'; } + if ($filetype eq 'sty') { + $breadcrumbtext = 'Style File Editor'; + } elsif ($filetype eq 'js') { + $breadcrumbtext = 'Javascript Editor'; + } elsif ($filetype eq 'css') { + $breadcrumbtext = 'CSS Editor'; + } elsif ($filetype eq 'txt') { + $breadcrumbtext = 'Text Editor'; + } elsif ($filetype eq 'tex') { + $breadcrumbtext = 'TeX Editor'; + } else { + $breadcrumbtext = 'HTML Editor'; + } + # # Edit action? Save file. # @@ -1692,17 +1670,22 @@ sub handler { if ($filecontents eq -1) { my $start_page=&Apache::loncommon::start_page('File Error'); my $end_page=&Apache::loncommon::end_page(); - my $fnf=&mt('File not found'); + my $errormsg='

' + .&mt('File not found: [_1]' + ,''.$file.'') + .'

'; $result=(<$fnf: $file +$errormsg $end_page ENDNOTFOUND $filecontents=''; if ($env{'request.state'} ne 'published') { if ($filetype eq 'sty') { $filecontents=&createnewsty(); - } else { + } elsif ($filetype eq 'js') { + $filecontents=&createnewjs(); + } elsif ($filetype ne 'css' && $filetype ne 'txt' && $filetype ne 'tex') { $filecontents=&createnewhtml(); } $env{'form.editmode'}='Edit'; #force edit mode @@ -1718,28 +1701,63 @@ ENDNOTFOUND ['editmode']); } if (!$env{'form.editmode'} || $env{'form.viewmode'} || $env{'form.discardview'}) { - &Apache::structuretags::reset_problem_globals(); - $result = &Apache::lonxml::xmlparse($request,$target,$filecontents, - '',%mystyle); + if ($filetype eq 'html' || $filetype eq 'sty') { + &Apache::structuretags::reset_problem_globals(); + $result = &Apache::lonxml::xmlparse($request,$target, + $filecontents,'',%mystyle); # .html files may contain or need to clean # up if it did - &Apache::structuretags::reset_problem_globals(); - &Apache::lonhomework::finished_parsing(); + &Apache::structuretags::reset_problem_globals(); + &Apache::lonhomework::finished_parsing(); + } elsif ($filetype eq 'tex') { + $result = &Apache::lontexconvert::converted(\$filecontents, + $env{'form.texengine'}); + if ($env{'form.return_only_error_and_warning_counts'}) { + if (&verify_html(''.$result.'')) { + $errorcount++; + } + $result = "$errorcount:$warningcount"; + } + } else { + $result = $filecontents; + } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['rawmode']); if ($env{'form.rawmode'}) { $result = $filecontents; } - if ($filetype eq 'sty') { - my $controls = - ($env{'request.state'} eq 'construct') ? &Apache::londefdef::edit_controls() - : ''; - my %options = ('bgcolor' => '#FFFFFF'); - $result = - &Apache::loncommon::start_page(undef,undef,\%options). - $controls. - $result. - &Apache::loncommon::end_page(); - } - } + if (($filetype ne 'html') && + (!$env{'form.return_only_error_and_warning_counts'})) { + my $nochgview = 1; + my $controls = ''; + if ($env{'request.state'} eq 'construct') { + $controls = &Apache::loncommon::head_subbox( + &Apache::loncommon::CSTR_pageheader() + .&Apache::londefdef::edit_controls($nochgview)); + } + if ($filetype ne 'sty' && $filetype ne 'tex') { + $result =~ s//>/g; + $result = ''. + '
'.$result.
+                              '
'; + } + my $brcrum; + if ($env{'request.state'} eq 'construct') { + $brcrum = [{'href' => &Apache::loncommon::authorspace(), + 'text' => 'Construction Space'}, + {'href' => '', + 'text' => $breadcrumbtext}]; + } else { + $brcrum = ''; # FIXME: Where are we? + } + my %options = ('bread_crumbs' => $brcrum, + 'bgcolor' => '#FFFFFF'); + $result = + &Apache::loncommon::start_page(undef,undef,\%options) + .$controls + .$result + .&Apache::loncommon::end_page(); + } + } } # @@ -1756,26 +1774,32 @@ ENDNOTFOUND my %options = ('add_entries' => - {'onresize' => $add_to_onresize, - 'onload' => $add_to_onload, }); - - if ($env{'environment.remote'} ne 'off') { - $options{'bgcolor'} = '#FFFFFF'; - $options{'only_body'} = 1; - } + {'onresize' => $add_to_onresize, + 'onload' => $add_to_onload, }); + my $header; + if ($env{'request.state'} eq 'construct') { + $options{'bread_crumbs'} = [{ + 'href' => &Apache::loncommon::authorspace(), + 'text' => 'Construction Space'}, + {'href' => '', + 'text' => $breadcrumbtext}]; + $header = &Apache::loncommon::head_subbox( + &Apache::loncommon::CSTR_pageheader()); + } my $js = &Apache::edit::js_change_detection(). &Apache::loncommon::resize_textarea_js(); my $start_page = &Apache::loncommon::start_page(undef,$js, \%options); - $result=$start_page. - &Apache::lonxml::message_location(). - $edit_info. - &Apache::loncommon::end_page(); - } + $result = $start_page + .$header + .&Apache::lonxml::message_location() + .$edit_info + .&Apache::loncommon::end_page(); + } } if ($filetype eq 'html') { &writeallows($request->uri); } - + &Apache::lonxml::add_messages(\$result); $request->print($result); @@ -1828,6 +1852,8 @@ sub error { $errorcount++; + $Apache::lonxml::internal_error=1; + if (defined($Apache::inputtags::part)) { if ( @Apache::inputtags::response ) { push(@errors, @@ -1854,7 +1880,7 @@ sub error { my ($symb)=&Apache::lonnet::symbread(); if ( !$symb ) { #public or browsers - $errormsg=&mt("An error occured while processing this resource. The author has been notified."); + $errormsg=&mt("An error occurred while processing this resource. The author has been notified."); } my $host=$Apache::lonnet::perlvar{'lonHostID'}; push(@errors, @@ -1893,9 +1919,9 @@ sub error { } } 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)); + $errormsg=&mt("An error occurred 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."); + $errormsg=&mt("An error occurred while processing this resource. The instructor has been notified."); } } push(@Apache::lonxml::error_messages,"$errormsg
"); @@ -2142,24 +2168,20 @@ sub get_tag { =pod -=item &print_pdf_radiobutton(fieldname, value, text) +=item &print_pdf_radiobutton(fieldname, value) -Returns a latexline to generate a PDF-Form-Radiobutton with Text. +Returns a latexline to generate a PDF-Form-Radiobutton. +Note: Radiobuttons with equal names are automaticly grouped + in a selection-group. -$fieldname: PDF internalname of the radiobutton -$value: Value of radiobutton (read when dumping the PDF data) -$text: Text on the rightside of the radiobutton +$fieldname: PDF internalname of the radiobutton(group) +$value: Value of radiobutton =cut sub print_pdf_radiobutton { - my $result = ''; - my ($fieldName, $value, $text) = @_; - $result .= '\begin{tabularx}{\textwidth}{p{0cm}X}'."\n"; - $result .= '\radioButton[\symbolchoice{circle}]{'. - $fieldName.'}{10bp}{10bp}{'.$value.'}&'.$text."\n"; - $result .= '\end{tabularx}' . "\n"; - $result .= '\hspace{2mm}' . "\n"; - return $result; + my ($fieldname, $value) = @_; + return '\radioButton[\symbolchoice{circle}]{' + .$fieldname.'}{10bp}{10bp}{'.$value.'}'; } 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.