--- loncom/interface/lonprintout.pm 2006/08/03 02:36:56 1.476
+++ loncom/interface/lonprintout.pm 2006/10/17 09:56:16 1.487
@@ -2,7 +2,7 @@
# The LearningOnline Network
# Printout
#
-# $Id: lonprintout.pm,v 1.476 2006/08/03 02:36:56 albertel Exp $
+# $Id: lonprintout.pm,v 1.487 2006/10/17 09:56:16 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,40 @@ 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 =~ /%\d*\Q$item\E/) {
+ my $start = $-[0];
+ my $end = $+[0];
+ my $len = $end - $start;
+
+ # see if we need to truncate:
+
+ my $subst = $repl;
+ my $fmt = substr($format_string, $start, $len);
+ my $size = $fmt;
+ $size =~ s/%(\d*)\Q$item\E/$1/;
+ if ($size ne "") {
+ $subst = substr($subst, 0, $size);
+ }
+ $format_string =~ s/%(\d*)\Q$item\E/$subst/;
+
+ }
+
+ return $format_string;
+}
+
# Format a header according to a format.
#
@@ -60,17 +93,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 +692,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 +825,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 +876,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);
@@ -1119,7 +1185,9 @@ sub print_construction_sequence {
# If necessary, encapsulate answer in minipage:
$texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
- my $body ='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'}).'}\vskip 0 mm ';
+ my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
+ $title = &Apache::lonxml::latex_special_symbols($title);
+ my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
$body.=&path_to_problem($urlp,$LaTeXwidth);
$body.='\vskip 1 mm '.$answer.'\end{document}';
$body = &encapsulate_minipage($body);
@@ -1314,7 +1382,9 @@ ENDPART
} else {
$texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
if ($helper->{'VARS'}->{'construction'} ne '1') {
- $texversion.='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'}).'}\vskip 0 mm ';
+ my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
+ $title = &Apache::lonxml::latex_special_symbols($title);
+ $texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
$texversion.=&path_to_problem($cleanURL,$LaTeXwidth);
} else {
$texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
@@ -1435,7 +1505,9 @@ ENDPART
} else {
if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) {
$texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
- my $body ='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($master_seq[$i]).'}\vskip 0 mm ';
+ my $title = &Apache::lonnet::gettitle($master_seq[$i]);
+ $title = &Apache::lonxml::latex_special_symbols($title);
+ my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
$body .= &path_to_problem ($urlp,$LaTeXwidth);
$body .='\vskip 1 mm '.$answer;
$body = &encapsulate_minipage($body);
@@ -1459,7 +1531,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);
@@ -1952,8 +2024,10 @@ sub print_resources {
my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
- my $body ='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($curresline).'}\vskip 0 mm ';
- $body .=&path_to_problem($res_url,$LaTeXwidth);
+ my $title = &Apache::lonnet::gettitle($curresline);
+ $title = &Apache::lonxml::latex_special_symbols($title);
+ my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
+ $body .=&path_to_problem($res_url,$LaTeXwidth);
$body .='\vskip 1 mm '.$ansrendered;
$body = &encapsulate_minipage($body);
$rendered = $header.$body;
@@ -1995,7 +2069,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]';
@@ -2116,6 +2190,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.
@@ -2127,6 +2202,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"})) {
@@ -2141,9 +2218,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";
@@ -2151,6 +2226,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'};
@@ -2178,6 +2256,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'}) {
@@ -2186,9 +2265,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'};
@@ -2209,11 +2294,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.
@@ -2254,7 +2334,7 @@ sub printHelper {
"' variable='FINISHPAGE' />";
}
- if (($helper->{'VARS'}->{'construction'} ne '1') &&
+ if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
$helper->{VARS}->{'postdata'} &&
$helper->{VARS}->{'assignment'}) {
@@ -2292,7 +2372,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'];
@@ -2320,7 +2400,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'];
}
@@ -2367,7 +2447,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.
@@ -2495,7 +2575,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'];
}
@@ -2605,12 +2685,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
@@ -2631,7 +2720,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'};