--- loncom/interface/lonprintout.pm 2007/04/20 20:33:35 1.499 +++ loncom/interface/lonprintout.pm 2008/03/24 18:24:30 1.519.2.3 @@ -1,8 +1,7 @@ -# # The LearningOnline Network # Printout # -# $Id: lonprintout.pm,v 1.499 2007/04/20 20:33:35 foxr Exp $ +# $Id: lonprintout.pm,v 1.519.2.3 2008/03/24 18:24:30 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -38,6 +37,10 @@ use Apache::grades; use Apache::edit; use Apache::File(); use Apache::lonnavmaps; +use Apache::admannotations; +use Apache::lonenc; +use HTTP::Response; + use LONCAPA::map(); use POSIX qw(strftime); use Apache::lonlocal; @@ -48,6 +51,21 @@ my %perm; my %parmhash; my $resources_printed; +# Global variables that describe errors in ssi calls detected by ssi_with_retries. +# + +my $ssi_error; # True if there was an ssi error. +my $ssi_last_error_resource; # The resource URI that could not be fetched. +my $ssi_last_error; # The error text from the server. (e.g. 500 Server timed out). + +# +# Our ssi max retry count. +# + +my $ssi_retry_count = 5; # Some arbitrary value. + + + # Fetch the contents of a resource, uninterpreted. # This is used here to fetch a latex file to be included # verbatim into the printout< @@ -60,22 +78,86 @@ sub fetch_raw_resource { my ($url) = @_; my $filename = &Apache::lonnet::filelocation("", $url); - # - # fetch if needed: - # - if (! -e $filename) { - my $repcopy_result = &Apache::lonnet::repcopy($filename); + my $contents = &Apache::lonnet::getfile($filename); - if ($repcopy_result ne 'ok') { - return "File open failed for $filename"; # This will bomb the print. - } + if ($contents == -1) { + return "File open failed for $filename"; # This will bomb the print. } - my $contents = &Apache::lonnet::readfile($filename); - return $contents; + } +# Fetch the annotations associated with a URL and +# put a centered 'annotations:' title. +# This is all suppressed if the annotations are empty. +# +sub annotate { + my ($symb) = @_; + + my $annotation_text = &Apache::admannotations::get_annotation($symb, 1); + + + my $result = ""; + + if (length($annotation_text) > 0) { + $result .= '\\hspace*{\\fill} \\\\[\\baselineskip] \textbf{Annotations:} \\\\ '; + $result .= "\n"; + $result .= &Apache::lonxml::latex_special_symbols($annotation_text,""); # Escape latex. + $result .= "\n\n"; + } + return $result; +} + + +# +# ssi_with_retries - Does the server side include of a resource. +# if the ssi call returns an error we'll retry it up to +# the number of times requested by the caller. +# If we still have a proble, no text is appended to the +# output and we set some global variables. +# to indicate to the caller an SSI error occurred. +# All of this is supposed to deal with the issues described +# in LonCAPA BZ 5631 see: +# http://bugs.lon-capa.org/show_bug.cgi?id=5631 +# by informing the user that this happened. +# +# Parameters: +# resource - The resource to include. This is passed directly, without +# interpretation to lonnet::ssi. +# form - The form hash parameters that guide the interpretation of the resource +# +# retries - Number of retries allowed before giving up completely. +# Returns: +# On success, returns the rendered resource identified by the resource parameter. +# Side Effects: +# The following global variables can be set: +# ssi_error - If an unrecoverable error occurred this becomes true. +# It is up to the caller to initialize this to false +# if desired. +# ssi_last_error_resource - If an unrecoverable error occurred, this is the value +# of the resource that could not be rendered by the ssi +# call. +# ssi_last_error - The error string fetched from the ssi response +# in the event of an error. +# +sub ssi_with_retries { + my ($resource, $retries, %form) = @_; + + + my ($content, $response) = &Apache::loncommon::ssi_with_retries($resource, $retries, %form); + if (!$response->is_success) { + $ssi_error = 1; + $ssi_last_error_resource = $resource; + $ssi_last_error = $response->code . " " . $response->message; + + &Apache::lonnet::logthis("Error in SSI resource: $resource Error: $ssi_last_error"); + } + + return $content; + +} + # # printf_style_subst item format_string repl # @@ -726,6 +808,7 @@ sub character_chart { $result =~ s/&(hearts|\#9829);/\\ensuremath\{\\heartsuit\}/g; $result =~ s/&(diams|\#9830);/\\ensuremath\{\\diamondsuit\}/g; # Chemically useful 'things' contributed by Hon Kie (bug 4652). + $result =~ s/&\#8636;/\\ensuremath\{\\leftharpoonup\}/g; $result =~ s/&\#8637;/\\ensuremath\{\\leftharpoondown\}/g; $result =~ s/&\#8640;/\\ensuremath\{\\rightharpoonup\}/g; @@ -739,6 +822,13 @@ sub character_chart { $result =~ s/&\#8600;/\\ensuremath\{\\searrow\}/g; $result =~ s/&\#8601;/\\ensuremath\{\\swarrow\}/g; $result =~ s/&\#8598;/\\ensuremath\{\\nwarrow\}/g; + + # Left/right quotations: + + $result =~ s/&(ldquo|#8220);/\`\`/g; + $result =~ s/&(rdquo|#8221);/\'\'/g; + + return $result; } @@ -758,7 +848,7 @@ my %page_formats= 'legal' => { 'book' => { '1' => ['7.1 in','13 in',,'-0.57 in','-0.57 in','-0.5 in'], - '2' => ['3.16 in','13 in','-0.57 in','-0.57 in','-0.5 in'] + '2' => ['3.66 in','13 in','-0.57 in','-0.57 in','-0.5 in'] }, 'album' => { '1' => ['12 in','7.1 in',,'-0.57 in','-0.57 in','-0.5 in'], @@ -873,7 +963,11 @@ sub page_format_transformation { my ($textwidth,$textheight,$oddoffset,$evenoffset,$topmargin); if ($selectionmade eq '4') { - $assignment='Problems from the Whole Course'; + if ($choice eq 'all_problems') { + $assignment='Problems from the Whole Course'; + } else { + $assignment='Resources from the Whole Course'; + } } else { $assignment=&Apache::lonxml::latex_special_symbols($assignment,'header'); } @@ -1033,6 +1127,7 @@ sub print_latex_header { '\usepackage[dvips]{graphicx}\usepackage{epsfig}'."\n". '\usepackage{wrapfig}'. '\usepackage{picins}\usepackage{calc}'."\n". + '\usepackage[utf8]{inputenc}'."\n". '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}'."\n". '\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}'."\n". '\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}'."\n". @@ -1224,7 +1319,7 @@ sub print_construction_sequence { $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; $form{'rndseed'}=$rndseed; $resources_printed .=$urlp.':'; - $texversion=&Apache::lonnet::ssi($urlp,%form); + $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form); } if((($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) && @@ -1237,7 +1332,7 @@ sub print_construction_sequence { $answerform{'problem_split'}=$parmhash{'problem_stream_switch'}; if ($urlp=~/\/res\//) {$env{'request.state'}='published';} $resources_printed .= $urlp.':'; - my $answer=&Apache::lonnet::ssi($urlp,%answerform); + my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform); if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; } else { @@ -1292,6 +1387,7 @@ sub print_construction_sequence { sub output_data { my ($r,$helper,$rparmhash) = @_; my %parmhash = %$rparmhash; + $ssi_error = 0; # This will be set nonzero by failing ssi's. $resources_printed = ''; my $do_postprocessing = 1; my $js = < ENDPART + + my $start_page = &Apache::loncommon::start_page('Preparing Printout',$js); my $msg = &mt('Please stand by while processing your print request, this may take some time ...'); @@ -1354,6 +1452,7 @@ ENDPART my @print_array=(); my @student_names=(); + # Common settings for the %form has: # In some cases these settings get overriddent by specific cases, but the # settings are common enough to make it worthwhile factoring them out @@ -1373,6 +1472,14 @@ ENDPART if ($helper->{'VARS'}->{'showallfoils'} eq "1") { $form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'}; } + + if ($helper->{'VARS'}->{'style_file'}=~/\w/) { + &Apache::lonnet::appenv('construct.style' => + $helper->{'VARS'}->{'style_file'}); + } elsif ($env{'construct.style'}) { + &Apache::lonnet::delenv('construct\\.style'); + } + if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') { #-- single document - problem, page, html, xml, ... @@ -1383,6 +1490,7 @@ ENDPART $currentURL=$helper->{'VARS'}->{'postdata'}; $cleanURL=&Apache::lonenc::check_decrypt($currentURL); } else { + #prints resource from the construction space $currentURL='/'.$helper->{'VARS'}->{'filename'}; if ($currentURL=~/([^?]+)/) {$currentURL=$1;} @@ -1396,18 +1504,16 @@ ENDPART if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') { my %moreenv; $moreenv{'request.filename'}=$cleanURL; - if ($helper->{'VARS'}->{'style_file'}=~/\w/) { - $moreenv{'construct.style'}=$helper->{'VARS'}->{'style_file'}; - my $dom = $env{'user.domain'}; - my $user = $env{'user.name'}; - my $put_result = &Apache::lonnet::put('environment',{'construct.style'=>$helper->{'VARS'}->{'style_file'}},$dom,$user); - } if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {$form{'problemtype'}='exam';} $form{'problem_split'}=$parmhash{'problem_stream_switch'}; $form{'suppress_tries'}=$parmhash{'suppress_tries'}; $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'}; - if ($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') {$form{'problem_split'}='yes';} + $form{'print_annotations'}=$helper->{'VARS'}->{'PRINT_ANNOTATIONS'}; + if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') || + ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) { + $form{'problem_split'}='yes'; + } if ($helper->{'VARS'}->{'curseed'}) { $rndseed=$helper->{'VARS'}->{'curseed'}; } @@ -1417,8 +1523,10 @@ ENDPART &Apache::lonxml::clear_problem_counter(); $resources_printed .= $currentURL.':'; - $texversion.=&Apache::lonnet::ssi($currentURL,%form); + $texversion.=&ssi_with_retries($currentURL,$ssi_retry_count, %form); + # Add annotations if required: + &Apache::lonxml::clear_problem_counter(); &Apache::lonnet::delenv('request.filename'); @@ -1436,7 +1544,9 @@ ENDPART $form{'problemtype'}='exam'; } $resources_printed .= $currentURL.':'; - my $answer=&Apache::lonnet::ssi($currentURL,%form); + my $answer=&ssi_with_retries($currentURL,$ssi_retry_count, %form); + + if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; } else { @@ -1450,11 +1560,24 @@ ENDPART $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm '; my $URLpath=$cleanURL; $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/; - $texversion.=&path_to_problem ($URLpath,$LaTeXwidth); + $texversion.=&path_to_problem($URLpath,$LaTeXwidth); } $texversion.='\vskip 1 mm '.$answer.'\end{document}'; } + + + + } + # Print annotations. + + + if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') { + my $annotation .= &annotate($currentURL); + $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/; + } + + if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { $texversion=&IndexCreation($texversion,$currentURL); } @@ -1482,7 +1605,11 @@ ENDPART $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;} $resources_printed .= $currentURL.':'; - my $texversion=&Apache::lonnet::ssi($currentURL,%form); + my $texversion=&ssi_with_retries($currentURL, $ssi_retry_count, %form); + if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') { + my $annotation = &annotate($currentURL); + $texversion =~ s/(\\end{document})/$annotation$1/; + } $result .= $texversion; } elsif ($cleanURL =~/.tex$/) { # For this sort of print of a single LaTeX file, @@ -1490,6 +1617,11 @@ ENDPART # $result = &fetch_raw_resource($currentURL); + if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') { + my $annotation = &annotate($currentURL); + $result =~ s/(\\end{document})/$annotation$1/; + } + $do_postprocessing = 0; # Don't massage the result. } else { @@ -1501,6 +1633,8 @@ ENDPART ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') or ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') or # BUGBUG ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences')) { + + #-- produce an output string if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') { $selectionmade = 2; @@ -1517,7 +1651,11 @@ ENDPART $form{'suppress_tries'}=$parmhash{'suppress_tries'}; $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'}; - if ($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') {$form{'problem_split'}='yes';} + $form{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'}; + if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') || + ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') ) { + $form{'problem_split'}='yes'; + } my $flag_latex_header_remove = 'NO'; my $flag_page_in_sequence = 'NO'; my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'}; @@ -1528,6 +1666,8 @@ ENDPART my $pbreakresources = keys %page_breaks; for (my $i=0;$i<=$#master_seq;$i++) { + &Apache::lonenc::reset_enc(); + # Note due to document structure, not allowed to put \newpage # prior to the first resource @@ -1536,20 +1676,20 @@ ENDPART $result.="\\newpage\n"; } } - my ($sequence,undef,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]); + my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]); $urlp=&Apache::lonnet::clutter($urlp); $form{'symb'}=$master_seq[$i]; my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem + if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;} if ($i==0) {$prevassignment=$assignment;} my $texversion=''; if ($urlp!~m|^/adm/| && $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) { $resources_printed .= $urlp.':'; - &Apache::lonxml::remember_problem_counter(); - $texversion.=&Apache::lonnet::ssi($urlp,%form); + $texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form); if ($urlp=~/\.page$/) { ($texversion,my $number_of_columns_page) = &page_cleanup($texversion); if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;} @@ -1566,7 +1706,7 @@ ENDPART $resources_printed .= $urlp.':'; &Apache::lonxml::restore_problem_counter(); - my $answer=&Apache::lonnet::ssi($urlp,%answerform); + my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform); if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; @@ -1584,7 +1724,13 @@ ENDPART $texversion=''; } } + } + if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') { + my $annotation .= &annotate($urlp); + $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/; + } + if ($flag_latex_header_remove ne 'NO') { $texversion = &latex_header_footer_remove($texversion); } else { @@ -1615,7 +1761,12 @@ ENDPART $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;} $resources_printed .= $urlp.':'; - my $texversion=&Apache::lonnet::ssi($urlp,%form); + my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form); + if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') { + my $annotation = &annotate($urlp); + $texversion =~ s/(\\end{document)/$annotation$1/; + } + if ($flag_latex_header_remove ne 'NO') { $texversion = &latex_header_footer_remove($texversion); } else { @@ -1691,9 +1842,13 @@ ENDPART $moreenv{'instructor_comments'}='hide'; $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth); $moreenv{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'}; + $moreenv{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'}; $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'}; $moreenv{'suppress_tries'} = $parmhash{'suppress_tries'}; - if ($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') {$moreenv{'problem_split'}='yes';} + if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') || + ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) { + $moreenv{'problem_split'}='yes'; + } my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75'); my $student_counter=-1; my $i = 0; @@ -1833,6 +1988,9 @@ ENDPART $rndseed=$helper->{'VARS'}->{'curseed'}; } for (my $i=0;$i<=$#list_of_files;$i++) { + + &Apache::lonenc::reset_enc(); + my $urlp = $list_of_files[$i]; $urlp=~s|//|/|; if ($urlp=~/\//) { @@ -1844,7 +2002,7 @@ ENDPART $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||; } $resources_printed .= $urlp.':'; - my $texversion=&Apache::lonnet::ssi($urlp,%form); + my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form); if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { # Don't permanently pervert %form: @@ -1854,7 +2012,7 @@ ENDPART $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; $answerform{'rndseed'}=$rndseed; $resources_printed .= $urlp.':'; - my $answer=&Apache::lonnet::ssi($urlp,%answerform); + my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform); if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; } else { @@ -1871,7 +2029,8 @@ ENDPART $texversion.='\vskip 1 mm '.$answer.'\end{document}'; } } - #this chunck is responsible for printing the path to problem + #this chunk is responsible for printing the path to problem + my $newurlp=$urlp; if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;} $newurlp=&path_to_problem($newurlp,$LaTeXwidth); @@ -1911,68 +2070,12 @@ ENDPART #} } -#-- writing .tex file in prtspool - my $temp_file; - my $identifier = &Apache::loncommon::get_cgi_id(); - my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex"; - if (!($#print_array>0)) { - unless ($temp_file = Apache::File->new('>'.$filename)) { - $r->log_error("Couldn't open $filename for output $!"); - return SERVER_ERROR; - } - print $temp_file $result; - my $begin=index($result,'\begin{document}',0); - my $inc=substr($result,0,$begin+16); - } else { - my $begin=index($result,'\begin{document}',0); - my $inc=substr($result,0,$begin+16); - for (my $i=0;$i<=$#print_array;$i++) { - if ($i==0) { - $print_array[$i]=$result; - } else { - $print_array[$i].='\end{document}'; - $print_array[$i] = - &latex_corrections($number_of_columns,$print_array[$i], - $selectionmade, - $helper->{'VARS'}->{'ANSWER_TYPE'}); - - my $anobegin=index($print_array[$i],'\setcounter{page}',0); - substr($print_array[$i],0,$anobegin)=''; - $print_array[$i]=$inc.$print_array[$i]; - } - my $temp_file; - my $newfilename=$filename; - my $num=$i+1; - $newfilename =~s/\.tex$//; - $newfilename=sprintf("%s_%03d.tex",$newfilename, $num); - unless ($temp_file = Apache::File->new('>'.$newfilename)) { - $r->log_error("Couldn't open $newfilename for output $!"); - return SERVER_ERROR; - } - print $temp_file $print_array[$i]; - } - } - my $student_names=''; - if ($#print_array>0) { - for (my $i=0;$i<=$#print_array;$i++) { - $student_names.=$student_names[$i].'_ENDPERSON_'; - } - } else { - if ($#student_names>-1) { - $student_names=$student_names[0].'_ENDPERSON_'; - } else { - my $fullname = &get_name($env{'user.name'},$env{'user.domain'}); - $student_names=join(':',$env{'user.name'},$env{'user.domain'}, - $env{'request.course.sec'},$fullname). - '_ENDPERSON_'.'_END_'; - } - } + # Set URLback if this is a construction space print so we can provide + # a link to the resource being edited. + # my $URLback=''; #link to original document - if ($helper->{'VARS'}->{'construction'} ne '1') { - #prints published resource - $URLback=&escape('/adm/flip?postdata=return:'); - } else { + if ($helper->{'VARS'}->{'construction'} eq '1') { #prints resource from the construction space $URLback='/'.$helper->{'VARS'}->{'filename'}; if ($URLback=~/([^?]+)/) { @@ -1980,34 +2083,121 @@ ENDPART $URLback=~s|^/~|/priv/|; } } - # logic for now is too complex to trace if this has been defined - # yet. - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - &Apache::lonnet::appenv('cgi.'.$identifier.'.file' => $filename, - 'cgi.'.$identifier.'.layout' => $laystyle, - 'cgi.'.$identifier.'.numcol' => $numberofcolumns, - 'cgi.'.$identifier.'.paper' => $papersize, - 'cgi.'.$identifier.'.selection' => $selectionmade, - 'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'}, - 'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'}, - 'cgi.'.$identifier.'.role' => $perm{'pav'}, - 'cgi.'.$identifier.'.numberoffiles' => $#print_array, - 'cgi.'.$identifier.'.studentnames' => $student_names, - 'cgi.'.$identifier.'.backref' => $URLback,); - &Apache::lonnet::appenv("cgi.$identifier.user" => $env{'user.name'}, - "cgi.$identifier.domain" => $env{'user.domain'}, - "cgi.$identifier.courseid" => $cnum, - "cgi.$identifier.coursedom" => $cdom, - "cgi.$identifier.resources" => $resources_printed); - my $end_page = &Apache::loncommon::end_page(); - $r->print(<print(' +
+

'.&mt('An unrecoverable network error occurred:').'

+

+ '.&mt('One of the resources ([_1]) you chose to print could not be rendered due to an unrecoverable error when communicating with a server:',$ssi_last_error_resource).' +
+'.$ssi_last_error.' +

+

'. +&mt('It is recommended that you try printing again later, as this error may mean the server was just temporarily unavailable, or is down for maintenance.').'
'. +&mt('If the error persists, please contact the [_1] for assistance.',$helpurl). +'

'. +&mt('We apologize for the inconvenience.'). +'

'. +$end_page); + + } else { + +#-- writing .tex file in prtspool + my $temp_file; + my $identifier = &Apache::loncommon::get_cgi_id(); + my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex"; + if (!($#print_array>0)) { + unless ($temp_file = Apache::File->new('>'.$filename)) { + $r->log_error("Couldn't open $filename for output $!"); + return SERVER_ERROR; + } + print $temp_file $result; + my $begin=index($result,'\begin{document}',0); + my $inc=substr($result,0,$begin+16); + } else { + my $begin=index($result,'\begin{document}',0); + my $inc=substr($result,0,$begin+16); + for (my $i=0;$i<=$#print_array;$i++) { + if ($i==0) { + $print_array[$i]=$result; + } else { + $print_array[$i].='\end{document}'; + $print_array[$i] = + &latex_corrections($number_of_columns,$print_array[$i], + $selectionmade, + $helper->{'VARS'}->{'ANSWER_TYPE'}); + + my $anobegin=index($print_array[$i],'\setcounter{page}',0); + substr($print_array[$i],0,$anobegin)=''; + $print_array[$i]=$inc.$print_array[$i]; + } + my $temp_file; + my $newfilename=$filename; + my $num=$i+1; + $newfilename =~s/\.tex$//; + $newfilename=sprintf("%s_%03d.tex",$newfilename, $num); + unless ($temp_file = Apache::File->new('>'.$newfilename)) { + $r->log_error("Couldn't open $newfilename for output $!"); + return SERVER_ERROR; + } + print $temp_file $print_array[$i]; + } + + } + my $student_names=''; + if ($#print_array>0) { + for (my $i=0;$i<=$#print_array;$i++) { + $student_names.=$student_names[$i].'_ENDPERSON_'; + } + } else { + if ($#student_names>-1) { + $student_names=$student_names[0].'_ENDPERSON_'; + } else { + my $fullname = &get_name($env{'user.name'},$env{'user.domain'}); + $student_names=join(':',$env{'user.name'},$env{'user.domain'}, + $env{'request.course.sec'},$fullname). + '_ENDPERSON_'.'_END_'; + } + } + + # logic for now is too complex to trace if this has been defined + # yet. + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + &Apache::lonnet::appenv('cgi.'.$identifier.'.file' => $filename, + 'cgi.'.$identifier.'.layout' => $laystyle, + 'cgi.'.$identifier.'.numcol' => $numberofcolumns, + 'cgi.'.$identifier.'.paper' => $papersize, + 'cgi.'.$identifier.'.selection' => $selectionmade, + 'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'}, + 'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'}, + 'cgi.'.$identifier.'.role' => $perm{'pav'}, + 'cgi.'.$identifier.'.numberoffiles' => $#print_array, + 'cgi.'.$identifier.'.studentnames' => $student_names, + 'cgi.'.$identifier.'.backref' => $URLback,); + &Apache::lonnet::appenv("cgi.$identifier.user" => $env{'user.name'}, + "cgi.$identifier.domain" => $env{'user.domain'}, + "cgi.$identifier.courseid" => $cnum, + "cgi.$identifier.coursedom" => $cdom, + "cgi.$identifier.resources" => $resources_printed); + + my $end_page = &Apache::loncommon::end_page(); + $r->print(< Continue $end_page FINALEND + } # endif ssi errors. } @@ -2061,6 +2251,7 @@ sub print_resources { # postscript. Each ENDOFSTUDENTSTAMP will go on a line by itself. # + foreach my $curresline (@{$master_seq}) { if (defined $page_breaks{$curresline}) { if($i != 0) { @@ -2068,6 +2259,7 @@ sub print_resources { } } $i++; + if ( !($type eq 'problems' && ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) { my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline); @@ -2106,6 +2298,12 @@ sub print_resources { $rendered = $header.$body; } } + + if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') { + my $url = &Apache::lonnet::clutter($res_url); + my $annotation = &annotate($url); + $rendered =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/; + } if ($remove_latex_header eq 'YES') { $rendered = &latex_header_footer_remove($rendered); } else { @@ -2115,7 +2313,11 @@ sub print_resources { } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { $printed .= $curresline.':'; my $rendered = &Apache::loncommon::get_student_view($curresline,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv); - + if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') { + my $url = &Apache::lonnet::clutter($res_url); + my $annotation = &annotate($url); + $annotation =~ s/(\\end{document})/$annotation$1/; + } if ($remove_latex_header eq 'YES') { $rendered = &latex_header_footer_remove($rendered); } else { @@ -2193,6 +2395,8 @@ sub handler { if(-e $conversion_queuefile) { unlink $conversion_queuefile; } + + &output_data($r,$helper,\%parmhash); return OK; } @@ -2222,6 +2426,28 @@ sub init_perm { } } +sub get_randomly_ordered_warning { + my ($helper,$map) = @_; + + my $message; + + my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'}; + my $navmap = Apache::lonnavmaps::navmap->new(); + my $res = $navmap->getResourceByUrl($map); + if ($res) { + my $func = + sub { return ($_[0]->is_map() && $_[0]->randomorder); }; + my @matches = $navmap->retrieveResources($res, $func,1,1,1); + if (@matches) { + $message = "Some of the items below are in folders set to be randomly ordered. However, when printing the contents of these folders, they will be printed in the original order for all students, not the randomized order."; + } + } + if ($message) { + return ''.$message.''; + } + return; +} + sub printHelper { my $r = shift; @@ -2265,6 +2491,10 @@ sub printHelper { $helper->declareVar("showallfoils"); $helper->declareVar("STUDENTS"); + + + + # The page breaks can get loaded initially from the course environment: # But we only do this in the initial state so that they are allowed to change. # @@ -2358,7 +2588,7 @@ sub printHelper { $helper->{VARS}->{'curseed'}=$env{'form.curseed'}; } if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) { - $helper->{VARS}->{'probstatus'}=$env{'form.problemtype'}; + $helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'}; } my $userCanSeeHidden = Apache::lonnavmaps::advancedUser(); @@ -2448,8 +2678,8 @@ HELPERFRAGMENT if ($perm{'pfo'} && !$is_published && ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) { - push @{$printChoices}, ['Selected Problems from entire course', 'all_problems', 'ALL_PROBLEMS']; - push @{$printChoices}, ['Selected Resources from entire course', 'all_resources', 'ALL_RESOURCES']; + push @{$printChoices}, [&mtn('Selected Problems from entire course'), 'all_problems', 'ALL_PROBLEMS']; + push @{$printChoices}, [&mtn('Selected Resources from entire course'), 'all_resources', 'ALL_RESOURCES']; &Apache::lonxml::xmlparse($r, 'helper', < Problems from folder [_1] for CODEd assignments",$sequenceTitle), 'problems_for_anon', 'CHOOSE_ANON1']; } + my $randomly_ordered_warning = + &get_randomly_ordered_warning($helper,$map); + # resource_selector will hold a few states that: # - Allow resources to be selected for printing. # - Determine pagination between assignments. @@ -2488,6 +2721,8 @@ ALL_PROBLEMS # my $resource_selector=< + $randomly_ordered_warning + PRINT_FORMATTING
Select resources for the assignment
- Names to store the CODEs under for later: + Names to save the CODEs under for later: @@ -2655,6 +2890,8 @@ CHOOSE_ANON1 $resource_selector=< + $randomly_ordered_warning + PRINT_FORMATTING
Select resources for the assignment
- Names to store the CODEs under for later: + Names to save the CODEs under for later: @@ -2794,7 +3031,7 @@ CHOOSE_FROM_SUBDIR # Allow the user to select any sequence in the course, feed it to # another resource selector for that sequence if (!$helper->{VARS}->{'construction'} && !$is_published) { - push @$printChoices, ["Selected Resources from selected folder in course", + push @$printChoices, [&mtn("Selected Resources from selected folder in course"), 'select_sequences', 'CHOOSE_SEQUENCE']; my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'}; #Escape apostrophes and backslashes for Perl @@ -2885,7 +3122,7 @@ CHOOSE_FROM_ANY_SEQUENCE Apache::lonhelper::dropdown->new(); addMessage("". - ''. + ': "); $paramHash = Apache::lonhelper::getParamHash(); @@ -2923,6 +3160,21 @@ CHOOSE_FROM_ANY_SEQUENCE Apache::lonhelper::dropdown->new(); addMessage(""); + # Prompt for printing annotations too. + + addMessage("". + ':"); + $paramHash = Apache::lonhelper::getParamHash(); + $paramHash->{'variable'} = "PRINT_ANNOTATIONS"; + $helper->declareVar("PRINT_ANNOTATIONS"); + $paramHash->{CHOICES} = [ + ['No', 'no'], + ['Yes', 'yes']]; + Apache::lonhelper::dropdown->new(); + addMessage(""); + addMessage(" "); $paramHash = Apache::lonhelper::getParamHash(); $paramHash->{'multichoice'} = "true"; @@ -2934,9 +3186,10 @@ CHOOSE_FROM_ANY_SEQUENCE } if ($helper->{'VARS'}->{'construction'}) { - my $stylevalue=$env{'construct.style'}; + my $stylevalue='$Apache::lonnet::env{"construct.style"}'; my $randseedtext=&mt("Use random seed"); my $stylefiletext=&mt("Use style file"); + my $selectfiletext=&mt("Select style file"); my $xmlfrag .= <<"RNDSEED"; @@ -2948,17 +3201,42 @@ CHOOSE_FROM_ANY_SEQUENCE - : + : -   Select style file + + + return $stylevalue; + +   $selectfiletext - Show all foils? + Show all foils RNDSEED &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag); - $helper->{'VARS'}->{'style_file'}=$env{'form.style_file_value'}; + + + addMessage("Problem Type:"); + # + # Initial value from construction space: + # + if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) { + $helper->{VARS}->{'probstatus'} = $env{'form.problemtype'}; # initial value + } + $xmlfrag = << "PROBTYPE"; + + + return "$helper->{VARS}->{'probstatus'}"; + + Homework Problem + Exam Problem + Survey question + +PROBTYPE + &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag); + addMessage(""); + } } @@ -3063,6 +3341,8 @@ sub render { my $PageLayout=&mt('Page layout'); my $NumberOfColumns=&mt('Number of columns'); my $PaperType=&mt('Paper type'); + my $landscape=&mt('Landscape'); + my $portrait=&mt('Portrait'); $result .= < @@ -3074,8 +3354,8 @@ sub render { -
- +
+