--- loncom/interface/lonprintout.pm 2006/08/08 17:32:02 1.477
+++ loncom/interface/lonprintout.pm 2006/10/24 10:37:58 1.490
@@ -2,7 +2,7 @@
# The LearningOnline Network
# Printout
#
-# $Id: lonprintout.pm,v 1.477 2006/08/08 17:32:02 albertel Exp $
+# $Id: lonprintout.pm,v 1.490 2006/10/24 10:37:58 foxr 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,52 @@ 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) = @_;
+ my $result = "";
+ while ($format_string =~ /(%)(\d*)\Q$item\E/g ) {
+ my $fmt = $1;
+ my $size = $2;
+ my $subst = $repl;
+ if ($size ne "") {
+ $subst = substr($subst, 0, $size);
+
+ # Here's a nice edge case.. supose the end of the
+ # substring is a \. In that case may have just
+ # chopped off a TeX escape... in that case, we append
+ # " " for the trailing character, and let the field
+ # spill over a bit (sigh).
+ # We don't just chop off the last character in order to deal
+ # with one last pathology, and that would be if substr had
+ # trimmed us to e.g. \\\
+
+
+ if ($subst =~ /\\$/) {
+ $subst .= " ";
+ }
+ }
+ my $item_pos = pos($format_string);
+ $result .= substr($format_string, 0, $item_pos - length($size) -2) . $subst;
+ $format_string = substr($format_string, pos($format_string));
+ }
+
+ # Put the residual format string into the result:
+
+ $result .= $format_string;
+
+ return $result;
+}
+
# Format a header according to a format.
#
@@ -60,17 +105,54 @@ 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);
+
+ # If the user put %'s in the format string, they must be escaped
+ # to \% else LaTeX will think they are comments and terminate
+ # the line.. which is bad!!!
+
+
}
@@ -94,7 +176,7 @@ sub num_to_letters {
sub letters_to_num {
my ($letters) = @_;
my @letters = split('', uc($letters));
- my %substitution;
+ my %substitution;
my $digit = 0;
foreach my $letter ('A'..'J') {
$substitution{$letter} = $digit;
@@ -628,8 +710,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 +843,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 +894,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);
@@ -1465,7 +1549,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);
@@ -2003,7 +2087,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]';
@@ -2124,6 +2208,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.
@@ -2135,6 +2220,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"})) {
@@ -2149,9 +2236,7 @@ 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";
@@ -2159,6 +2244,9 @@ sub printHelper {
} 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'};
@@ -2186,6 +2274,7 @@ sub printHelper {
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'}) {
@@ -2194,9 +2283,15 @@ sub printHelper {
$subdir = substr($helper->{VARS}->{'filename'},
0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
} else {
- ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
- $helper->{VARS}->{'postdata'} =
- &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
+ 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);
if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
my $postdata = $helper->{VARS}->{'postdata'};
@@ -2217,11 +2312,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.
@@ -2262,7 +2352,7 @@ sub printHelper {
"' variable='FINISHPAGE' />";
}
- if (($helper->{'VARS'}->{'construction'} ne '1') &&
+ if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
$helper->{VARS}->{'postdata'} &&
$helper->{VARS}->{'assignment'}) {
@@ -2300,7 +2390,7 @@ 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'} &&
+ 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'];
@@ -2328,7 +2418,7 @@ HELPERFRAGMENT
ALL_PROBLEMS
if ($helper->{VARS}->{'assignment'}) {
- push @{$printChoices}, [&mt("Selected Problems from folder [_1] for selected students",$sequenceTitle), 'problems_for_students', 'CHOOSE_STUDENTS'];
+ push @{$printChoices}, [&mt("Selected Problems from folder [_1] for selected people",$sequenceTitle), 'problems_for_students', 'CHOOSE_STUDENTS'];
push @{$printChoices}, [&mt("Selected Problems from folder [_1] for CODEd assignments",$sequenceTitle), 'problems_for_anon', 'CHOOSE_ANON1'];
}
@@ -2375,7 +2465,7 @@ RESOURCE_SELECTOR
&Apache::lonxml::xmlparse($r, 'helper', <
- Select sort order
+ Select sorting order of printout
Sort by section then student
Sort by students across sections.
@@ -2503,7 +2593,7 @@ CHOOSE_ANON1
if ($helper->{VARS}->{'assignment'}) {
- push @{$printChoices}, [&mt("Selected Resources from folder [_1] for selected students",$sequenceTitle), 'resources_for_students', 'CHOOSE_STUDENTS1'];
+ push @{$printChoices}, [&mt("Selected Resources from folder [_1] for selected people",$sequenceTitle), 'resources_for_students', 'CHOOSE_STUDENTS1'];
push @{$printChoices}, [&mt("Selected Resources from folder [_1] for CODEd assignments",$sequenceTitle), 'resources_for_anon', 'CHOOSE_ANON2'];
}
@@ -2613,12 +2703,21 @@ CHOOSE_ANON2
}
# FIXME: That RE should come from a library somewhere.
- if ((((&Apache::lonnet::allowed('bre',$subdir) eq 'F') and ($helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)) or defined $helper->{'VARS'}->{'construction'}) and $perm{'pav'} and $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/') {
- push @{$printChoices}, [&mt("Selected Problems from current subdirectory [_1]",$subdir), 'problems_from_directory', 'CHOOSE_FROM_SUBDIR'];
+ if (($perm{'pav'}
+ && $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
+ && (defined($helper->{'VARS'}->{'construction'})
+ ||
+ (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
+ &&
+ $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
+ ))
+ && $helper->{VARS}->{'assignment'} eq ""
+ ) {
- my $f = '$filename';
+ my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
+ push @{$printChoices}, [&mt("Selected Problems from current subdirectory [_1]",$pretty_dir), 'problems_from_directory', 'CHOOSE_FROM_SUBDIR'];
my $xmlfrag = <
+
PAGESIZE
@@ -2639,7 +2738,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'}) {
+ if (!$helper->{VARS}->{'construction'} && !$is_published) {
push @$printChoices, ["Selected Resources from selected folder in course",
'select_sequences', 'CHOOSE_SEQUENCE'];
my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};