--- loncom/interface/lonprintout.pm 2006/08/14 22:20:20 1.479 +++ loncom/interface/lonprintout.pm 2006/10/20 17:37:20 1.488 @@ -2,7 +2,7 @@ # The LearningOnline Network # Printout # -# $Id: lonprintout.pm,v 1.479 2006/08/14 22:20:20 foxr Exp $ +# $Id: lonprintout.pm,v 1.488 2006/10/20 17:37:20 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -23,7 +23,6 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt -# # http://www.lon-capa.org/ # # @@ -50,6 +49,33 @@ my %perm; my %parmhash; my $resources_printed; +# +# printf_style_subst item format_string repl +# +# Does printf style substitution for a format string that +# can have %[n]item in it.. wherever, %[n]item occurs, +# rep is substituted in format_string. Note that +# [n] is an optional integer length. If provided, +# repl is truncated to at most [n] characters prior to +# substitution. +# +sub printf_style_subst { + my ($item, $format_string, $repl) = @_; + + while ($format_string =~m/\G[^%]*(%(\d*)\Q$item\E)/g) { + my $fmt = $1; + my $size = $2; + my $subst = $repl; + if ($size ne "") { + $subst = substr($subst, 0, $size); + } + my $newpos = pos($format_string) + length($subst) - length($fmt); + $format_string =~ s/\Q$fmt\E\G/$subst/; + pos($format_string)=$newpos; + } + return $format_string; +} + # Format a header according to a format. # @@ -60,17 +86,48 @@ my $resources_printed; # %n - Student name. # sub format_page_header { - my ($format, $assignment, $course, $student) = @_; + my ($width, $format, $assignment, $course, $student) = @_; + $width = &recalcto_mm($width); # Get width in mm. # Default format? if ($format eq '') { + # For the default format, we may need to truncate + # elements.. To do this we need to get the page width. + # we assume that each character is about 2mm in width. + # (correct for the header text size??). We ignore + # any formatting (e.g. boldfacing in this). + # + # - Allow the student/course to be one line. + # but only truncate the course. + # - Allow the assignment to be 2 lines (wrapped). + # + my $chars_per_line = $width/2; # Character/textline. + + + my $firstline = "$student $course"; + if (length($firstline) > $chars_per_line) { + my $lastchar = $chars_per_line - length($student) - 1; + if ($lastchar > 0) { + $course = substr($course, 0, $lastchar); + } else { # Nothing left of course: + $course = ''; + } + } + if (length($assignment) > $chars_per_line) { + $assignment = substr($assignment, 0, $chars_per_line); + } + $format = "\\textbf{$student} $course \\hfill \\thepage \\\\ \\textit{$assignment}"; } else { - $format =~ s/%a/$assignment/g; - $format =~ s/%c/$course/g; - $format =~ s/%n/$student/g; + # An open question is how to handle long user formatted page headers... + # A possible future is to support e.g. %na so that the user can control + # the truncation of the elements that can appear in the header. + # + $format = &printf_style_subst("a", $format, $assignment); + $format = &printf_style_subst("c", $format, $course); + $format = &printf_style_subst("n", $format, $student); } @@ -628,8 +685,8 @@ my %page_formats= '2' => ['3.66 in','9.8 in', '-0.57 in','-0.57 in','0.7 cm'] }, 'album' => { - '1' => [ '8.8 in', '6.8 in','-0.55 in', '-0.83 in','1 cm'], - '2' => [ '4.4 in', '6.8 in','-0.5 in', '-1.5 in','3.5 in'] + '1' => [ '8.8 in', '6.8 in','-0.55 in', '-0.55 in','1 cm'], + '2' => [ '4.8 in', '6.8 in','-0.5 in', '-1.0 in','3.5 in'] }, }, 'legal' => { @@ -761,7 +818,7 @@ sub page_format_transformation { my $courseidinfo = &get_course(); if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo } my $header_text = $parmhash{'print_header_format'}; - $header_text = &format_page_header($header_text, $assignment, + $header_text = &format_page_header($textwidth, $header_text, $assignment, $courseidinfo, $name); my $topmargintoinsert = ''; if ($topmargin ne '0') {$topmargintoinsert='\setlength{\topmargin}{'.$topmargin.'}';} @@ -812,6 +869,8 @@ sub details_for_menu { if (!$postdata) { $postdata=$helper->{VARS}{'postdata'}; } my $name_of_resource = &Apache::lonnet::gettitle($postdata); my $symbolic = &Apache::lonnet::symbread($postdata); + return if ( $symbolic eq ''); + my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symbolic); $map=&Apache::lonnet::clutter($map); my $name_of_sequence = &Apache::lonnet::gettitle($map); @@ -1110,10 +1169,7 @@ sub print_construction_sequence { $answerform{'answer_output_mode'}='tex'; $answerform{'rndseed'}=$rndseed; $answerform{'problem_split'}=$parmhash{'problem_stream_switch'}; - if ($urlp=~/\/res\//) { - $env{'request.state'}='published'; - } - + if ($urlp=~/\/res\//) {$env{'request.state'}='published';} $resources_printed .= $urlp.':'; my $answer=&Apache::lonnet::ssi($urlp,%answerform); if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { @@ -1201,8 +1257,6 @@ 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 ...'); - - $r->print($start_page."\n
\n$msg\n
\n"); # fetch the pagebreaks and store them in the course environment @@ -1254,7 +1308,6 @@ ENDPART } if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') { - #-- single document - problem, page, html, xml, ... my ($currentURL,$cleanURL); @@ -1471,7 +1524,7 @@ ENDPART if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo } $prevassignment=$assignment; my $header_text = $parmhash{'print_header_format'}; - $header_text = &format_page_header($header_text, + $header_text = &format_page_header($textwidth, $header_text, $assignment, $courseidinfo, $name); @@ -2009,7 +2062,7 @@ sub print_resources { if ($usersection ne '') {$courseidinfo.=' - Sec. '.$usersection} my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header'); my $header_line = - &format_page_header($parmhash{'print_header_format'}, + &format_page_header($LaTeXwidth, $parmhash{'print_header_format'}, $currentassignment, $courseidinfo, $fullname); my $header_start = ($columns_in_format == 1) ? '\lhead' : '\fancyhead[LO]'; @@ -2130,6 +2183,7 @@ sub printHelper { $helper->declareVar('FINISHPAGE'); $helper->declareVar('PRINT_TYPE'); $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. @@ -2141,6 +2195,8 @@ sub printHelper { {'pagebreaks' => 'scalar', 'lastprinttype' => 'scalar'}); + # This will persistently load in the data we want from the + # very first screen. if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) { if (!defined ($env{"form.CURRENT_STATE"})) { @@ -2155,16 +2211,17 @@ sub printHelper { } - - # This will persistently load in the data we want from the - # very first screen. + # Detect whether we're coming from construction space if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) { $helper->{VARS}->{'filename'} = "~$1/$2"; $helper->{VARS}->{'construction'} = 1; - } elsif ($env{'form.postdata'}) { + } else { if ($env{'form.postdata'}) { $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'}); + if ( $helper->{VARS}->{'symb'} eq '') { + $helper->{VARS}->{'postdata'} = $env{'form.postdata'}; + } } if ($env{'form.symb'}) { $helper->{VARS}->{'symb'} = $env{'form.symb'}; @@ -2174,6 +2231,7 @@ sub printHelper { } } + if ($env{'form.symb'}) { $helper->{VARS}->{'symb'} = $env{'form.symb'}; } @@ -2185,26 +2243,31 @@ sub printHelper { &Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'}); my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper); if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;} + # Extract map my $symb = $helper->{VARS}->{'symb'}; my ($map, $id, $url); my $subdir; + my $is_published=0; # True when printing from resource space. # Get the resource name from construction space - if ($helper->{VARS}->{'construction'}) { $resourceTitle = substr($helper->{VARS}->{'filename'}, rindex($helper->{VARS}->{'filename'}, '/')+1); $subdir = substr($helper->{VARS}->{'filename'}, 0, rindex($helper->{VARS}->{'filename'}, '/') + 1); - } elsif ($env{'form.postdata'} =~ /^\/res\//) { # Get resource name from res space. - $helper->{VARS}->{'postdata'} = $env{'form.postdata'}; + } else { + if ($symb ne '') { + ($map, $id, $url) = &Apache::lonnet::decode_symb($symb); + $helper->{VARS}->{'postdata'} = + &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url)); + } else { + $url = $helper->{VARS}->{'postdata'}; + $is_published=1; # From resource space. + } + $url = &Apache::lonnet::clutter($url); - } elsif (!$helper->{VARS}->{'postdata'}) { - ($map, $id, $url) = &Apache::lonnet::decode_symb($symb); - $helper->{VARS}->{'postdata'} = - &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url)); if (!$resourceTitle) { # if the resource doesn't have a title, use the filename my $postdata = $helper->{VARS}->{'postdata'}; $resourceTitle = substr($postdata, rindex($postdata, '/') + 1); @@ -2224,11 +2287,6 @@ sub printHelper { # "Delete everything after the last slash." $subdir =~ s|/[^/]+$||; - if (not $helper->{VARS}->{'construction'}) { - $subdir=$Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$subdir; - } - # "Remove all duplicate slashes." - $subdir =~ s|/+|/|g; # What can be printed is a very dynamic decision based on # lots of factors. So we need to dynamically build this list. @@ -2269,10 +2327,9 @@ sub printHelper { "' variable='FINISHPAGE' />"; } - if (($helper->{'VARS'}->{'construction'} ne '1') && + if (($helper->{'VARS'}->{'construction'} ne '1' ) && $helper->{VARS}->{'postdata'} && - ($helper->{VARS}->{'postdata'} !~ /^\/res\//) && $helper->{VARS}->{'assignment'}) { # Allow problems from sequence push @{$printChoices}, [&mt('Selected Problems in folder [_1]',$sequenceTitle), 'map_problems', 'CHOOSE_PROBLEMS']; @@ -2308,9 +2365,9 @@ HELPERFRAGMENT # If the user has pfo (print for otheres) allow them to print all # problems and resources in the entier course, optionally for selected students - if ($perm{'pfo'} && - $helper->{VARS}->{'postdata'} !~/^\/res\// && - $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/) { + 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']; &Apache::lonxml::xmlparse($r, 'helper', <