Diff for /loncom/interface/lonprintout.pm between versions 1.583 and 1.627.2.1

version 1.583, 2010/08/04 22:17:14 version 1.627.2.1, 2012/12/28 00:25:11
Line 1 Line 1
 #  
 # The LearningOnline Network  # The LearningOnline Network
 # Printout  # Printout
 #  #
Line 28 Line 27
 #  #
 package Apache::lonprintout;  package Apache::lonprintout;
 use strict;  use strict;
   use POSIX;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::lonxml;  use Apache::lonxml;
 use Apache::lonnet;  use Apache::lonnet;
Line 41  use Apache::admannotations; Line 41  use Apache::admannotations;
 use Apache::lonenc;  use Apache::lonenc;
 use Apache::entities;  use Apache::entities;
 use Apache::londefdef;  use Apache::londefdef;
   # use Apache::structurelags; # for language management.
   
 use File::Basename;  use File::Basename;
   
 use HTTP::Response;  use HTTP::Response;
   
 use LONCAPA::map();  use LONCAPA::map();
 use POSIX qw(strftime);  use POSIX qw(ctime);
 use Apache::lonlocal;  use Apache::lonlocal;
 use Carp;  use Carp;
 use LONCAPA;  use LONCAPA;
   
   
 my %perm;  my %perm;
 my %parmhash;  my %parmhash;
 my $resources_printed;  my $resources_printed;
Line 76  my $font_size = 'normalsize'; # Default Line 77  my $font_size = 'normalsize'; # Default
   
 #----------------------------  Helper helpers. -------------------------  #----------------------------  Helper helpers. -------------------------
   
 #  Returns the text needd for a student chooser.  ## 
   # Filter function to determine if a resource is a printable sequence.
   #
   # @param $res -Resource to check.
   #
   # @return 1 - printable and a resource
   #         0 - either notm a sequence or not printable.
   #
   sub printable_sequence {
       my $res = shift;
   
       # Non-sequences are not listed:
   
       if (!$res->is_sequence()) {
    return 0;
       }
   
       # Person with pav or pfo can always print:
   
       if ($perm{'pav'} || $perm{'pfo'}) {
    return 1;
       }
   
       if ($res->is_sequence()) {
    my $symb = $res->symb();
    my $navmap   = $res->{NAV_MAP};
   
    # Find the first resource in the map:
   
    my $iterator = $navmap->getIterator($res, undef, undef, 1, 1);
    my $first    = $iterator->next();
   
    while (1) {
       if ($first == $iterator->END_ITERATOR) { last; }
       if (ref($first) && ! $first->is_sequence()) {last; }
       $first = $iterator->next();
    }
   
   
    # Might be an empty map:
   
    if (!ref($first)) {
       return 0;
    }
    my $partsref = $first->parts();
    my @parts    = @$partsref;
    my ($open, $close) = $navmap->map_printdates($first, $parts[0]);
    return &printable($open, $close);
       }
       return 0;
   }
   
   # BZ5209:
   #    Create the states needed to run the helper for incomplete problems from
   #    the current folder for selected students.
   #    This includes:
   #    -  A resource selector limited to problems (incompleteness must be
   #       calculated on a student per student basis.
   #    -  A student selector.
   #    -  Tie in to the FORMAT of the print job.
   #
   # States:
   #   CHOOSE_INCOMPLETE_PEOPLE_SEQ      - Resource selection.
   #   CHOOSE_STUDENTS_INCOMPLETE        - Student selection.
   #   CHOOSE_STUDENTS_INCOMPLETE_FORMAT - Format selection
   # Parameters:
   #    helper - the helper which already contains info about the current folder we can
   #             purloin.
   #    url    - Top url of the sequence
   # Return:
   #     XML that can be parsed by the helper to drive the state machine.
   #
   sub create_incomplete_folder_selstud_helper($helper)
   {
       my ($helper, $map)  = @_;
   
   
       my $symbFilter = '$res->shown_symb()';
       my $selFilter   = '$res->is_problem()';
   
   
       my $resource_chooser = &generate_resource_chooser('CHOOSE_INCOMPLETE_PEOPLE_SEQ',
         'Select problem(s) to print',
         'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
         'RESOURCES',
         'CHOOSE_STUDENTS_INCOMPLETE',
         $map,
         $selFilter,
         '',
         $symbFilter, 
         '');
   
       my $student_chooser = &generate_student_chooser('CHOOSE_STUDENTS_INCOMPLETE',
    'student_sort',
    'STUDENTS',
    'CHOOSE_STUDENTS_INCOMPLETE_FORMAT');
   
       my $format_chooser = &generate_format_selector($helper,
    'Format of the print job',
    'CHOOSE_STUDENTS_INCOMPLETE_FORMAT'); # end state.
   
       return $resource_chooser . $student_chooser . $format_chooser;
   }  
   
   
   # BZ 5209
   #     Create the states needed to run the helper for incomplete problems from
   #     the current folder for selected students.
   #     This includes:
   #     - A resource selector limited to problems.  (incompleteness must be calculated
   #       on a student per student basis.
   #     - A student selector.
   #     - Tie in to format for the print job.
   # States:
   #    INCOMPLETE_PROBLEMS_COURSE_RESOURCES - Resource selector.
   #    INCOMPLETE_PROBLEMS_COURSE_STUDENTS  - Student selector.
   #    INCOMPLETE_PROBLEMS_COURSE_FORMAT    - Format selection.
   #
   # Parameters:
   #   helper   - Helper we are creating states for.
   # Returns:
   #   Text that can be parsed by the helper.
   # 
   
   sub create_incomplete_course_helper {
       my $helper = shift;
   
       my $filter = '$res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice())';
       my $symbfilter = '$res->shown_symb()';
       
       my $resource_chooser = &generate_resource_chooser('INCOMPLETE_PROBLEMS_COURSE_RESOURCES',
         'Select problem(s) to print',
         'multichoice = "1" suppressEmptySequences="0" addstatus="1" closeallpagtes="1"',
         'RESOURCES',
         'INCOMPLETE_PROBLEMS_COURSE_STUDENTS',
         '',
         $filter,
         '',
         $symbfilter,
         '');
   
       my $people_chooser  = &generate_student_chooser('INCOMPLETE_PROBLEMS_COURSE_STUDENTS',
       'student_sort',
       'STUDENTS',
       'INCOMPLETE_PROBLEMS_COURSE_FORMAT');
   
       my $format = &generate_format_selector($helper,
      'Format of the print job',
      'INCOMPLETE_PROBLEMS_COURSE_FORMAT'); # end state.
   
       return $resource_chooser . $people_chooser . $format;
   
   
   }
   
   # BZ5209 
   #   Creates the states needed to run the print helper for a student
   #   that wants to print his incomplete problems from the current folder.
   # Parameters:
   #   $helper - helper we are generating states for.
   #   $map    - The map for which the student wants incomplete problems.
   # Returns:
   #   XML that defines the helper states being created.
   #
   # States:
   #   CHOOSE_INCOMPLETE_SEQ  - Resource selector.
   #
   sub create_incomplete_folder_helper {
       my ($helper, $map) = @_;
   
       my $filter    = '$res->is_problem()';
       $filter      .= ' && $res->resprintable() ';
       $filter      .= ' && $res->is_incomplete() ';
   
       my $symfilter = '$res->shown_symb()';
   
       my $resource_chooser = &generate_resource_chooser('CHOOSE_INCOMPLETE_SEQ',
         'Select problem(s) to print',
         'multichoice="1", toponly ="1", addstatus="1", closeallpages="1"',
         'RESOURCES',
         'PAGESIZE',
         $map,
         $filter, '', 
         $symfilter,
         '');
   
       return $resource_chooser;
   }
   
   
   #  Returns the text neded for a student chooser.
 #  that text must still be parsed by the helper xml parser.  #  that text must still be parsed by the helper xml parser.
 # Parameters:  # Parameters:
 #   this_state   - State name of the chooser.  #   this_state   - State name of the chooser.
Line 164  CHOOSE_RESOURCES Line 355  CHOOSE_RESOURCES
       </resource>        </resource>
     </state>      </state>
 CHOOSE_RESOURCES  CHOOSE_RESOURCES
   
     return $result;      return $result;
 }  }
 #  #
Line 217  sub generate_code_selector { Line 407  sub generate_code_selector {
     <message></td><td></message>      <message></td><td></message>
     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />      <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
     <message></td></tr><tr><td></message>      <message></td></tr><tr><td></message>
     <message><b>Bubble sheet type:</b></message>      <message><b>Bubblesheet type:</b></message>
     <message></td><td></message>      <message></td><td></message>
     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">      <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
     $bubble_types      $bubble_types
Line 256  CHOOSE_ANON1 Line 446  CHOOSE_ANON1
    return $result;     return $result;
 }  }
   
   #  Returns the XML for choosing how assignments are to be formatted 
   #  that text must still be parsed by the helper xml parser.
   # Parameters: 3 (required)
   
   #   helper       - The helper; $helper->{'VARS'}->{'PRINT_TYPE'} used
   #                  to check if splitting PDFs by section can be offered.
   #   title        - Title for the current state. 
   #   this_state   - State name of the chooser.
   
   sub generate_format_selector {
       my ($helper,$title,$this_state) = @_;
       my $secpdfoption;
       unless (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon')     ||
               ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon_page') ||
               ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon')  ) {
           $secpdfoption =  '<choice computer="sections">Each PDF contains exactly one section</choice>';
       }
       return <<RESOURCE_SELECTOR;
       <state name="$this_state" title="$title">
       <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
       <choices variable="EMPTY_PAGES">
         <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
         <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
         <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
         <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
       </choices>
       <nextstate>PAGESIZE</nextstate>
       <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
       <choices variable="SPLIT_PDFS">
          <choice computer="all">All assignments in a single PDF file</choice>
          $secpdfoption
          <choice computer="oneper">Each PDF contains exactly one assignment</choice>
          <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
               Specify the number of assignments per PDF:</choice>
       </choices>
       </state>
   RESOURCE_SELECTOR
   }
   
 #-----------------------------------------------------------------------  #-----------------------------------------------------------------------
   
   # Computes an open and close date from a list of open/close dates for a resource's
   # parts.
   #
   # @param \@opens - reference to an array of open dates.
   # @param \@closes - reference to an array of close dates.
   #
   # @return ($open, $close) 
   #
   # @note If open/close dates are not defined they will be retunred as undef
   # @note It is possible for there to be no overlap in which case -1,-1 
   #       will be returned.
   # @note The algorithm used is to take the latest open date and the earliest end date.
   #
   sub compute_open_window {
       my ($opensref, $closesref) = @_;
   
       my @opens   = @$opensref;
       my @closes  = @$closesref;
   
       # latest open date:
       my $latest_open;
   
       foreach my $open (@opens) {
    if (!defined($latest_open) || ($open > $latest_open)) {
       $latest_open = $open;
    }
       }
       # Earliest close:
   
       my $earliest_close;
       foreach my $close (@closes) {
    if (!defined($earliest_close) || ($close < $earliest_close)) {
       $earliest_close = $close;
    }
       }
   
       # If no overlap...both are -1 as promised.
   
       if (defined($earliest_close) && defined($latest_open)
    && ($earliest_close < $latest_open)) {
    $latest_open  = -1;
    $earliest_close = -1;
       }
       
       return ($latest_open, $earliest_close);
     
   }
   
   ##
   #  Determines if 'now' is within the set of printable dates.
   #
   #  @param $open_date - Starting date/timestamp.
   #  @param $close_date - Ending date/timestamp.
   #
   #  @return 0 - Not open.
   #  @return 1 - open.
   #
   sub printable {
       my ($open_date, $close_date) = @_;
   
   
       my $now = time();
   
       # Have to do a bit of fancy footwork around undefined open/close dates:
   
       if ($open_date && ($open_date > $now)) {
    return 0;
       }
   
       if ($close_date && ($close_date < $now)) {
    return 0;
       }
       
       return 1;
   
   }
   
   ##
   # Returns the innermost print start/print end dates for a resource.
   # This is done by looking at the start/end dates for its parts and choosing
   # the intersection of those dates.
   # 
   # @param res - lonnvamaps::resource object that represents the resource.
   #
   # @return (opendate, closedate)
   #
   # @note If open/close dates are not defined they will be retunred as undef
   # @note It is possible for there to be no overlap in which case -1,-1 
   #       will be returned.
   # @note The algorithm used is to take the latest open date and the earliest end date.
   #
   
   sub get_print_dates {
       my $res = shift;
       my $partsref = $res->parts();
       my @parts;
       if (ref($partsref) eq 'ARRAY') {
           @parts   = @{$partsref};
       }
       my $open_date;
       my $close_date;
       my @open_dates;
       my @close_dates;
   
   
       if (@parts) {
    foreach my $part (@parts) {
       my $partopen  = $res->parmval('printstartdate', $part);
       my $partclose = $res->parmval('printenddate',  $part);
   
       push(@open_dates, $partopen);
       push(@close_dates, $partclose);
    }
       }
   
       ($open_date, $close_date)  = &compute_open_window(\@open_dates, \@close_dates);
   
       if ($open_date) {
    $open_date  = POSIX::strftime('%D', localtime($open_date));
       }
       if ($close_date) {
    $close_date = POSIX::strftime('%D', localtime($close_date));
       }
   
       return ($open_date, $close_date);
   }
   
   ##
   # Get the dates for which a course says a resource can be printed.  This is like
   # get_print_dates but namvaps::course_print_dates are gotten...and not converted
   # to times either.
   #
   # @param $res - Reference to a resource has from lonnvampas::resource.
   #
   # @return (opendate, closedate)
   #
   sub course_print_dates {
       my $res = shift;
       my $partsref = $res->parts();
       my @parts    = @$partsref;
       my $open_date;
       my $close_date;
       my @open_dates;
       my @close_dates;
       my $navmap = $res->{NAV_MAP}; # Slightly OO dirty.
   
       # Don't bother looping over undefined or empty parts arraY;
   
       if (@parts) {
    foreach my $part (@parts) {
       my ($partopen, $partclose) = $navmap->course_printdates($res, $part);
       push(@open_dates, $partopen);
       push(@close_dates, $partclose);
    }
    ($open_date, $close_date) = &compute_open_window(\@open_dates, \@close_dates);
       }
       return ($open_date, $close_date);
   }
   ##
   # Same as above but for the enclosing map:
   #
   sub map_print_dates {
       my $res = shift;
       my $partsref = $res->parts();
       my @parts    = @$partsref;
       my $open_date;
       my $close_date;
       my @open_dates;
       my @close_dates;
       my $navmap = $res->{NAV_MAP}; # slightly OO dirty.
   
   
       # Don't bother looping over undefined or empty parts arraY;
   
       if (@parts) {
    foreach my $part (@parts) {
       my ($partopen, $partclose) = $navmap->map_printdates($res, $part);
       push(@open_dates, $partopen);
       push(@close_dates, $partclose);
    }
    ($open_date, $close_date) = &compute_open_window(\@open_dates, \@close_dates);
       }
       return ($open_date, $close_date);
   }
   
   # Determine if a resource is incomplete given the map:
   # Parameters:
   #   $username - Name of user for whom we are checking.
   #   $domain   - Domain of user we are checking.
   #   $map - map name.
   # Returns:
   #     0 - map is not incomplete.
   #     1 - map is incomplete.
   #
   sub incomplete {
       my ($username, $domain, $map) = @_;
   
   
       my $navmap = Apache::lonnavmaps::navmap->new($username, $domain);
       
   
       if (defined($navmap)) {
    my $res = $navmap->getResourceByUrl($map);
    my $result = $res->is_incomplete();
    return $result;
       } else {
    return 1;
       }
   }
   #
   #  When printing for students, the resoures and order of the
   #  resources may need to be altered if there are folders with
   #  random selectiopn or random ordering (or both) enabled.
   #  This sub computes the set of resources to print for a student
   #  modified both by random ordering and selection and filtered
   #  to only those that are in the original set selcted to be printed.
   #
   # Parameters:
   #   $map - The URL of the folder being printed.
   #          Used to determine which startResource and finishResource
   #          to use when using the navmap's getIterator method.
   #   $seq   - The original set of resources to print.
   #            (really an array of resource names (array of symb's).
   #   $who   - Student/domain for whome the sequence will be generated.
   #   $code  - CODE being printed when printing Problems/Resources
   #            from folder for CODEd assignments
   #
   # Implicit inputs:
   #   $
   # Returns:
   #   reference to an array of resources that can be passed to
   #   print_resources.
   # 
   sub master_seq_to_person_seq {
       my ($map, $seq, $who, $code) = @_;
   
   
       my ($username, $userdomain, $usersection) = split(/:/, $who);
   
       # Toss the sequence up into a hash so that we have O(1) lookup time.
       # on the items that come out of the user's list of resources.
       #
   
       my %seq_hash = map {$_  => 1} @$seq;
       my @output_seq;
       
       my $navmap           = Apache::lonnavmaps::navmap->new($username, $userdomain,
                                                              $code);
       my ($start,$finish);
   
       if ($map) {
           my $mapres = $navmap->getResourceByUrl($map);
           if ($mapres->is_map()) {
               $start = $mapres->map_start();
               $finish = $mapres->map_finish();
           }
       }
       unless ($start && $finish) {
           $start = $navmap->firstResource();
           $finish = $navmap->finishResource();
       }
   
       my $iterator         = $navmap->getIterator($start,$finish,{},1);
   
       #  Iterate on the resource..select the items that are randomly selected
       #  and that are in the seq_has.  Presumably the iterator will take care
       # of the random ordering part of the deal.
       #
       my $curres;
       while ($curres = $iterator->next()) {
    #
    #  Only process resources..that are not removed by randomout...
    #  and are selected for printint as well.
    #
   
           if (ref($curres) && ! $curres->randomout()) {
               my $currsymb = $curres->symb();
               if (exists($seq_hash{$currsymb})) {
                   push(@output_seq, $currsymb);
       }
    }
       }
   
       return \@output_seq; # for now.
       
   }
   
   
 # Fetch the contents of a resource, uninterpreted.  # Fetch the contents of a resource, uninterpreted.
 # This is used here to fetch a latex file to be included  # This is used here to fetch a latex file to be included
Line 360  sub include_pdf { Line 876  sub include_pdf {
     # (unlikely).  If it did exist, add the pdf to the set of files/images that      # (unlikely).  If it did exist, add the pdf to the set of files/images that
     # need tob e converted for this print job:      # need tob e converted for this print job:
   
     $file =~ s|(.*)/res/|/home/httpd/html/res/|;      my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
       $file =~ s{(.*)/res/}{$londocroot/res/};
   
     open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat");      open(FILE,">>$Apache::lonnet::perlvar{'lonPrtDir'}/$env{'user.name'}_$env{'user.domain'}_printout.dat");
     print FILE ("$file\n");      print FILE ("$file\n");
     close (FILE);      close (FILE);
   
Line 385  sub include_pdf { Line 902  sub include_pdf {
   
   
 }  }
   ##
   #  Collect the various \select_language{language_name}
   #  latex tags to build a \usepackage[lang-list]{babel} which will
   #  appear just prior to the \begin{document} at the front of the concatenated
   #  set of resources:
   # @param doc - The string of latex to search/replace.
   # @return string
   # @retval - the modified document stringt.
   #
   sub collect_languages {
       my $doc = shift;
       my %languages;
       while ($doc =~ /\\selectlanguage{(\w+)}/mg) {
    $languages{$1} = 1; # allows us to request each language exactly once.
       }
       my @lang_list = (keys(%languages)); # List of unique languages
       if (scalar @lang_list) {
    my $babel_header = '\usepackage[' . join(',', @lang_list) .']{babel}'. "\n";
    $doc =~ s/\\begin{document}/$babel_header\\begin{document}/;
       }
       return $doc;
   }
   #-------------------------------------------------------------------
   
 #  #
 #   ssi_with_retries- Does the server side include of a resource.  #   ssi_with_retries- Does the server side include of a resource.
Line 432  sub ssi_with_retries { Line 971  sub ssi_with_retries {
  $ssi_last_error_resource = $resource;   $ssi_last_error_resource = $resource;
  $ssi_last_error          = $response->code . " " . $response->message;   $ssi_last_error          = $response->code . " " . $response->message;
         $content='\section*{!!! An error occurred !!!}';          $content='\section*{!!! An error occurred !!!}';
  &Apache::lonnet::logthis("Error in SSI resource: $resource Error: $ssi_last_error");  
     }      }
   
     return $content;      return $content;
Line 448  sub get_student_view_with_retries { Line 986  sub get_student_view_with_retries {
         $ssi_last_error_resource = $curresline.' for user '.$username.':'.$userdomain;          $ssi_last_error_resource = $curresline.' for user '.$username.':'.$userdomain;
         $ssi_last_error          = $response->code . " " . $response->message;          $ssi_last_error          = $response->code . " " . $response->message;
         $content='\section*{!!! An error occurred !!!}';          $content='\section*{!!! An error occurred !!!}';
         &Apache::lonnet::logthis("Error in SSI (student view) resource: $curresline Error: $ssi_last_error User: $username:$userdomain");  
     }      }
     return $content;      return $content;
   
Line 511  sub printf_style_subst { Line 1048  sub printf_style_subst {
 #     %s    - The section if it is supplied.  #     %s    - The section if it is supplied.
 #  #
 sub format_page_header {  sub format_page_header {
     my ($width, $format, $assignment, $course, $student, $section) = @_;      my ($width, $format, $assignment, $course, $student) = @_;
   
   
   
     $width = &recalcto_mm($width); # Get width in mm.      $width = &recalcto_mm($width); # Get width in mm.
     my $chars_per_line = int($width/1.6);   # Character/textline.      my $chars_per_line = int($width/2);   # Character/textline.
   
     #  Default format?      #  Default format?
   
Line 532  sub format_page_header { Line 1069  sub format_page_header {
  # - Allow the assignment to be 2 lines (wrapped).   # - Allow the assignment to be 2 lines (wrapped).
  #   #
   
           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);
           }
   
  my $name_length    = int($chars_per_line *3 /4);          $format =  "\\textbf{$student} $course \\hfill \\thepage \\\\ \\textit{$assignment}";
  my $sec_length     = int($chars_per_line / 5);  
   
  $format  = "%$name_length".'n';      } else {
           # 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!!!
   
  if ($section) {      }
     $format .=  ' - Sec: '."%$sec_length".'s';  
  }  
   
  $format .= '\\\\%c \\\\ %a';      return $format;
           
   
     }  
     # 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);  
     $format =  &printf_style_subst("s", $format, $section);  
       
       
     # 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!!!  
           
     # If the user has role author, $course and $assignment are empty so      # If the user has role author, $course and $assignment are empty so
     # there is '\\ \\ ' in the page header. That's cause a error in LaTeX      # there is '\\ \\ ' in the page header. That's cause a error in LaTeX
Line 703  sub is_code_valid { Line 1244  sub is_code_valid {
     }      }
   
 }  }
   #
   # Compare two students by section (Used to sort by section).
   #
   #  Implicit inputs, 
   #    $a - The first one
   #    $b - The second one.
   #
   #  Returns:
   #     a-section cmp b-section
   #
   sub compare_sections {
       my ($u1, $d1, $s1, $n1, $stat1) = split(/:/, $a);
       my ($u2, $d2, $s2, $n2, $stat2) = split(/:/, $b);
   
       return $s1 cmp $s2;
   }
   
 #   Compare two students by name.  The students are in the form  #   Compare two students by name.  The students are in the form
 #   returned by the helper:  #   returned by the helper:
Line 1279  sub get_course { Line 1836  sub get_course {
     my $courseidinfo;      my $courseidinfo;
     if (defined($env{'request.course.id'})) {      if (defined($env{'request.course.id'})) {
  $courseidinfo = &Apache::lonxml::latex_special_symbols(&unescape($env{'course.'.$env{'request.course.id'}.'.description'}),'header');   $courseidinfo = &Apache::lonxml::latex_special_symbols(&unescape($env{'course.'.$env{'request.course.id'}.'.description'}),'header');
  my $sec = $env{'request.course.sec'};  
       
     }      }
     return $courseidinfo;      return $courseidinfo;
 }  }
Line 1303  sub page_format_transformation { Line 1858  sub page_format_transformation {
   
     my $name = &get_name();      my $name = &get_name();
     my $courseidinfo = &get_course();      my $courseidinfo = &get_course();
       if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo }
     my $header_text  = $parmhash{'print_header_format'};      my $header_text  = $parmhash{'print_header_format'};
     $header_text     = &format_page_header($textwidth, $header_text, $assignment,      $header_text     = &format_page_header($textwidth, $header_text, $assignment,
    $courseidinfo, $name);     $courseidinfo, $name);
Line 1511  sub unsupported { Line 2067  sub unsupported {
     my $result.= &print_latex_header($mode);      my $result.= &print_latex_header($mode);
     if ($currentURL=~m|^(/adm/wrapper/)?ext/|) {      if ($currentURL=~m|^(/adm/wrapper/)?ext/|) {
  $currentURL=~s|^(/adm/wrapper/)?ext/|http://|;   $currentURL=~s|^(/adm/wrapper/)?ext/|http://|;
           $currentURL=~s|^http://https://|https://|;
  my $title=&Apache::lonnet::gettitle($symb);   my $title=&Apache::lonnet::gettitle($symb);
  $title = &Apache::lonxml::latex_special_symbols($title);   $title = &Apache::lonxml::latex_special_symbols($title);
  $result.=' \strut \\\\ '.$title.' \strut \\\\ '.$currentURL.' ';   $result.=' \strut \\\\ '.$title.' \strut \\\\ '.$currentURL.' ';
Line 1536  sub map_laystyle { Line 2093  sub map_laystyle {
   
 sub print_page_in_course {  sub print_page_in_course {
     my ($helper, $rparmhash, $currentURL, $resources) = @_;      my ($helper, $rparmhash, $currentURL, $resources) = @_;
   
     my %parmhash       = %$rparmhash;      my %parmhash       = %$rparmhash;
     my @page_resources = @$resources;      my @page_resources = @$resources;
     my $mode = $helper->{'VARS'}->{'LATEX_TYPE'};      my $mode = $helper->{'VARS'}->{'LATEX_TYPE'};
Line 1589  sub print_page_in_course { Line 2147  sub print_page_in_course {
     my @page_resources = $navmap->retrieveResources($resource_src);      my @page_resources = $navmap->retrieveResources($resource_src);
     $result           .= &print_page_in_course($helper, $rparmhash,       $result           .= &print_page_in_course($helper, $rparmhash, 
        $resource_src, \@page_resources);         $resource_src, \@page_resources);
           } elsif ($resource->ext()) {
               $result .= &unsupported($currentURL,$mode,$symb);
  }   }
  # these resources go through the XML transformer:   # these resources go through the XML transformer:
   
  elsif ($resource_src =~ /\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/)  {   elsif ($resource_src =~ /\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/)  {
   
     my $urlp = &Apache::lonnet::clutter($resource_src);      my $urlp = &Apache::lonnet::clutter($resource_src);
   
     my %form;      my %form;
     my %moreenv;      my %moreenv;
   
Line 1655  sub print_page_in_course { Line 2217  sub print_page_in_course {
  $texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';   $texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
  $texversion.=&path_to_problem($urlp,$LaTeXwidth);   $texversion.=&path_to_problem($urlp,$LaTeXwidth);
     } else {      } else {
  $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';   $texversion.='\vskip 0 mm \noindent\textbf{'.
  my $URLpath=$urlp;                          &mt("Printing from Construction Space: No Title").'}\vskip 0 mm ';
  $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;   $texversion.=&path_to_problem($urlp,$LaTeXwidth);
  $texversion.=&path_to_problem($URLpath,$LaTeXwidth);  
     }      }
     $texversion.='\vskip 1 mm '.$answer.'\end{document}';      $texversion.='\vskip 1 mm '.$answer.'\end{document}';
  }   }
Line 1707  sub print_page_in_course { Line 2268  sub print_page_in_course {
 # List of recently generated print files  # List of recently generated print files
 #  #
 sub recently_generated {  sub recently_generated {
     my $r=shift;      my ($prtspool) = @_;
     my $prtspool=$r->dir_config('lonPrtDir');      my $output;
     my $zip_result;      my $zip_result;
     my $pdf_result;      my $pdf_result;
     opendir(DIR,$prtspool);      opendir(DIR,$prtspool);
Line 1741  sub recently_generated { Line 2302  sub recently_generated {
  if ($ext eq 'zip') { $zip_result .= $result; }   if ($ext eq 'zip') { $zip_result .= $result; }
     }      }
     if ($zip_result || $pdf_result) {      if ($zip_result || $pdf_result) {
         $r->print('<hr />');          $output ='<hr />';
     }      }
     if ($zip_result) {      if ($zip_result) {
  $r->print('<h3>'.&mt('Recently generated printout zip files')."</h3>\n"   $output .='<h3>'.&mt('Recently generated printout zip files')."</h3>\n"
                   .&Apache::loncommon::start_data_table()                    .&Apache::loncommon::start_data_table()
                   .&Apache::loncommon::start_data_table_header_row()                    .&Apache::loncommon::start_data_table_header_row()
                   .'<th>'.&mt('Download').'</th>'                    .'<th>'.&mt('Download').'</th>'
Line 1752  sub recently_generated { Line 2313  sub recently_generated {
                   .'<th>'.&mt('File Size (Bytes)').'</th>'                    .'<th>'.&mt('File Size (Bytes)').'</th>'
                   .&Apache::loncommon::end_data_table_header_row()                    .&Apache::loncommon::end_data_table_header_row()
                   .$zip_result                    .$zip_result
                   .&Apache::loncommon::end_data_table()                    .&Apache::loncommon::end_data_table();
         );  
     }      }
     if ($pdf_result) {      if ($pdf_result) {
  $r->print('<h3>'.&mt('Recently generated printouts')."</h3>\n"   $output .='<h3>'.&mt('Recently generated printouts')."</h3>\n"
                   .&Apache::loncommon::start_data_table()                    .&Apache::loncommon::start_data_table()
                   .&Apache::loncommon::start_data_table_header_row()                    .&Apache::loncommon::start_data_table_header_row()
                   .'<th>'.&mt('Download').'</th>'                    .'<th>'.&mt('Download').'</th>'
Line 1764  sub recently_generated { Line 2324  sub recently_generated {
                   .'<th>'.&mt('File Size (Bytes)').'</th>'                    .'<th>'.&mt('File Size (Bytes)').'</th>'
                   .&Apache::loncommon::end_data_table_header_row()                    .&Apache::loncommon::end_data_table_header_row()
                   .$pdf_result                    .$pdf_result
                   .&Apache::loncommon::end_data_table()                    .&Apache::loncommon::end_data_table();
         );  
     }      }
       return $output;
 }  }
   
 #  #
Line 1926  sub set_form_extraspace { Line 2486  sub set_form_extraspace {
 #  #
 sub print_construction_sequence {  sub print_construction_sequence {
     my ($currentURL, $helper, %form, $LaTeXwidth) = @_;      my ($currentURL, $helper, %form, $LaTeXwidth) = @_;
   
     my $result;      my $result;
     my $rndseed=time;      my $rndseed=time;
     if ($helper->{'VARS'}->{'curseed'}) {      if ($helper->{'VARS'}->{'curseed'}) {
  $rndseed=$helper->{'VARS'}->{'curseed'};   $rndseed=$helper->{'VARS'}->{'curseed'};
     }      }
     my $errtext=&LONCAPA::map::mapread($currentURL);      my $errtext=&LONCAPA::map::mapread(&Apache::lonnet::filelocation('',$currentURL));
   
     #       # 
     #  These make this all support recursing for subsequences.      #  These make this all support recursing for subsequences.
     #      #
     my @order    = @LONCAPA::map::order;      my @order    = @LONCAPA::map::order;
     my @resources = @LONCAPA::map::resources;       my @resources = @LONCAPA::map::resources; 
   
     for (my $member=0;$member<=$#order;$member++) {      for (my $member=0;$member<=$#order;$member++) {
  $resources[$order[$member]]=~/^([^:]*):([^:]*):/;   $resources[$order[$member]]=~/^([^:]*):([^:]*):/;
  my $urlp=$2;   my $urlp=$2;
Line 1952  sub print_construction_sequence { Line 2515  sub print_construction_sequence {
     }      }
     if((($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||      if((($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
  ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) &&    ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) && 
        ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page)$/)) {         ($urlp=~/$LONCAPA::assess_page_re/)) {
  #  Don't permanently modify %$form...   #  Don't permanently modify %$form...
  my %answerform = %form;   my %answerform = %form;
  $answerform{'grade_target'}='answer';   $answerform{'grade_target'}='answer';
Line 1996  sub print_construction_sequence { Line 2559  sub print_construction_sequence {
     # IF sequence, recurse:      # IF sequence, recurse:
           
     if ($urlp =~ /\.sequence$/) {      if ($urlp =~ /\.sequence$/) {
  my $sequence_url = $urlp;   $result .= &print_construction_sequence($urlp, 
  my $domain       = $env{'user.domain'}; # Constr. space only on local  
  my $user         = $env{'user.name'};  
   
  $sequence_url    =~ s/^\/res\/$domain/\/home/;  
  $sequence_url    =~ s/^(\/home\/$user)/$1\/public_html/;  
 # $sequence_url    =~ s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;  
  $result .= &print_construction_sequence($sequence_url,   
  $helper, %form,    $helper, %form, 
  $LaTeXwidth);   $LaTeXwidth);
     }      }
Line 2027  sub print_construction_sequence { Line 2583  sub print_construction_sequence {
     return $result;      return $result;
 }  }
   
   #
   #  Top level for generating print output.
   #
   #  May call print_resources if multiple resources will be printed.
   #
   #  The main driver is $selectionmade which reflects the type of print out
   #  requested:
   #   Value    Print type:
   #   1        Print resource that's being looked at.
   #   2        Print problems in a map or in a page.
   #   3        Print pages in a map or resources in a page.
   #   4        Print all problems  or all resources.
   #   5        Print problems for seleted students.
   #   6        Print selected problems from a folder.
   #   7        Print print selected resources from some scope.
   #   8        Print resources for selected students.
   #
   #BZ 5209
   #   2        map_incomplete_problems_seq Print incomplete problems from the current
   #            folder in student context.
   #   5      map_incomplete_problems_people_seq Print incomplete problems from the
   #            current folder in privileged context.
   #    5      incomplete_problems_selpeople_course Print incomplete problems for
   #            selected people from the entire course.
   #
   #   Item 101 has much the same processing as 8,
   #
   #  Differences:  Item 101, 102 require per-student filtering of the resource
   #  set so that only the incomplete resources are printed.
   #  For item 100, filtering was done at the helper level.
   
 sub output_data {  sub output_data {
   
     my ($r,$helper,$rparmhash) = @_;      my ($r,$helper,$rparmhash) = @_;
     my %parmhash = %$rparmhash;      my %parmhash = %$rparmhash;
     $ssi_error = 0; # This will be set nonzero by failing ssi's.      $ssi_error = 0; # This will be set nonzero by failing ssi's.
     $resources_printed = '';      $resources_printed = '';
     $font_size = $helper->{'VARS'}->{'fontsize'};      $font_size = $helper->{'VARS'}->{'fontsize'};
       my $print_type = $helper->{'VARS'}->{'PRINT_TYPE'}; # Allows textual simplification.
     my $do_postprocessing = 1;      my $do_postprocessing = 1;
     my $js = <<ENDPART;      my $js = <<ENDPART;
 <script type="text/javascript">  <script type="text/javascript">
Line 2082  ENDPART Line 2671  ENDPART
   
     $env{'form.pagebreaks'}  = $helper->{'VARS'}->{'FINISHPAGE'};      $env{'form.pagebreaks'}  = $helper->{'VARS'}->{'FINISHPAGE'};
     &set_form_extraspace($helper);      &set_form_extraspace($helper);
     $env{'form.lastprinttype'} = $helper->{'VARS'}->{'PRINT_TYPE'};       $env{'form.lastprinttype'} = $print_type; 
     &Apache::loncommon::store_course_settings('print',      &Apache::loncommon::store_course_settings('print',
       {'pagebreaks'    => 'scalar',        {'pagebreaks'    => 'scalar',
        'extraspace'    => 'scalar',         'extraspace'    => 'scalar',
Line 2132  ENDPART Line 2721  ENDPART
  &Apache::lonnet::delenv('construct.style');   &Apache::lonnet::delenv('construct.style');
     }      }
   
     if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') {      if ($print_type eq 'current_document') {
       #-- single document - problem, page, html, xml, ...        #-- single document - problem, page, html, xml, ...
  my ($currentURL,$cleanURL);   my ($currentURL,$cleanURL);
   
Line 2143  ENDPART Line 2732  ENDPART
  } else {   } else {
   
             #prints resource from the construction space              #prints resource from the construction space
     $currentURL='/'.$helper->{'VARS'}->{'filename'};      $currentURL=$helper->{'VARS'}->{'filename'};
     if ($currentURL=~/([^?]+)/) {$currentURL=$1;}  
     $cleanURL=$currentURL;      $cleanURL=$currentURL;
  }   }
  $selectionmade = 1;   $selectionmade = 1;
         
  if ($cleanURL!~m|^/adm/|   if ($cleanURL!~m|^/adm/|
     && $cleanURL=~/\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/) {      && $cleanURL=~/\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/) {
     my $rndseed=time;      my $rndseed=time;
Line 2187  ENDPART Line 2776  ENDPART
   
     if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||      if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
        ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {         ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
   
  $form{'problem_split'}=$parmhash{'problem_stream_switch'};   $form{'problem_split'}=$parmhash{'problem_stream_switch'};
  $form{'grade_target'}='answer';   $form{'grade_target'}='answer';
  $form{'answer_output_mode'}='tex';   $form{'answer_output_mode'}='tex';
Line 2208  ENDPART Line 2798  ENDPART
  $texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';   $texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
  $texversion.=&path_to_problem($cleanURL,$LaTeXwidth);   $texversion.=&path_to_problem($cleanURL,$LaTeXwidth);
     } else {      } else {
  $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';   $texversion.='\vskip 0 mm \noindent\textbf{'.
  my $URLpath=$cleanURL;                          &mt("Printing from Construction Space: No Title").'}\vskip 0 mm ';
  $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;  
  $texversion.=&path_to_problem($URLpath,$LaTeXwidth);   $texversion.=&path_to_problem($cleanURL,$LaTeXwidth);
     }      }
     $texversion.='\vskip 1 mm '.$answer.'\end{document}';      $texversion.='\vskip 1 mm '.$answer.'\end{document}';
  }   }
Line 2243  ENDPART Line 2833  ENDPART
     }      }
         } elsif ($cleanURL!~m|^/adm/|          } elsif ($cleanURL!~m|^/adm/|
  && $currentURL=~/\.(sequence|page)$/ && $helper->{'VARS'}->{'construction'} eq '1') {   && $currentURL=~/\.(sequence|page)$/ && $helper->{'VARS'}->{'construction'} eq '1') {
             #printing content of sequence from the construction space  
   
   
     $currentURL=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;  
     $result .= &print_construction_sequence($currentURL, $helper, %form,      $result .= &print_construction_sequence($currentURL, $helper, %form,
     $LaTeXwidth);      $LaTeXwidth);
     $result .= '\end{document}';        $result .= '\end{document}';  
Line 2294  ENDPART Line 2880  ENDPART
     $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'},      $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'},
   $helper->{'VARS'}->{'symb'});    $helper->{'VARS'}->{'symb'});
  }   }
     } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems')       or      } elsif (($print_type eq 'map_problems')          or
      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_in_page') or       ($print_type eq 'map_problems_in_page')  or
      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_resources_in_page') or       ($print_type eq 'map_resources_in_page') or
              ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or               ($print_type eq 'map_problems_pages')    or
              ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems')       or               ($print_type eq 'all_problems')          or
      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources')      or # BUGBUG       ($print_type eq 'all_resources')         or # BUGBUG
      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences')        ($print_type eq 'select_sequences')      or
        ($print_type eq 'map_incomplete_problems_seq')
      ) {       ) {
   
     
         #-- produce an output string          #-- produce an output string
  if (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems')  or   if (($print_type eq 'map_problems')                or
     ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_in_page') ) {      ($print_type eq 'map_incomplete_problems_seq') or
       ($print_type eq 'map_problems_in_page') ) {
     $selectionmade = 2;      $selectionmade = 2;
  } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or   } elsif (($print_type eq 'map_problems_pages') or
  ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_resources_in_page'))   ($print_type eq 'map_resources_in_page'))
  {   {
     $selectionmade = 3;      $selectionmade = 3;
  } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems')    } elsif (($print_type eq 'all_problems') 
  ) {   ) {
     $selectionmade = 4;      $selectionmade = 4;
  } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') {  #BUGBUG   } elsif ($print_type eq 'all_resources') {  #BUGBUG
     $selectionmade = 4;      $selectionmade = 4;
  } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') {   } elsif ($print_type eq 'select_sequences') {
     $selectionmade = 7;      $selectionmade = 7;
  }   }
   
  $form{'problem_split'}=$parmhash{'problem_stream_switch'};   $form{'problem_split'}=$parmhash{'problem_stream_switch'};
  $form{'suppress_tries'}=$parmhash{'suppress_tries'};   $form{'suppress_tries'}=$parmhash{'suppress_tries'};
  $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};   $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
Line 2369  ENDPART Line 2957  ENDPART
                     unless (($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only') ||                      unless (($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only') ||
                             (($i==0) &&                              (($i==0) &&
                              (($urlp=~/\.page$/) ||                               (($urlp=~/\.page$/) ||
                               ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_in_page') ||                                ($print_type eq 'map_problems_in_page') ||
                               ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_resources_in_page')))) {                                ($print_type eq 'map_resources_in_page')))) {
                         $flag_latex_header_remove = 'YES';                          $flag_latex_header_remove = 'YES';
                     }                      }
  }   }
Line 2405  ENDPART Line 2993  ENDPART
                             $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;                              $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
                         }                          }
     } else {      } else {
  if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page)$/) {   if ($urlp=~/$LONCAPA::assess_page_re/) {
     $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});      $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
 #    $texversion =~ s/\\begin{document}//; # FIXME  #    $texversion =~ s/\\begin{document}//; # FIXME
     my $title = &Apache::lonnet::gettitle($master_seq[$i]);      my $title = &Apache::lonnet::gettitle($master_seq[$i]);
Line 2437  ENDPART Line 3025  ENDPART
  if (($selectionmade == 4) and ($assignment ne $prevassignment)) {   if (($selectionmade == 4) and ($assignment ne $prevassignment)) {
     my $name = &get_name();      my $name = &get_name();
     my $courseidinfo = &get_course();      my $courseidinfo = &get_course();
                       if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo }
     $prevassignment=$assignment;      $prevassignment=$assignment;
     my $header_text = $parmhash{'print_header_format'};      my $header_text = $parmhash{'print_header_format'};
     $header_text    = &format_page_header($textwidth, $header_text,      $header_text    = &format_page_header($textwidth, $header_text,
   $assignment,     $assignment, 
   $courseidinfo,     $courseidinfo, 
   $name);    $name);
   
     if ($numberofcolumns eq '1') {      if ($numberofcolumns eq '1') {
  $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{'.$header_text.'}} \vskip 5 mm ';   $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{'.$header_text.'}} \vskip 5 mm ';
     } else {      } else {
Line 2510  ENDPART Line 3098  ENDPART
     $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;      $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;
  }   }
  $result .= '\end{document}';   $result .= '\end{document}';
      } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||       } elsif (($print_type eq 'problems_for_students')           ||
       ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students_from_page') ||        ($print_type eq 'problems_for_students_from_page') ||
       ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ||        ($print_type eq 'all_problems_students')           ||
       ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){        ($print_type eq 'resources_for_students')          ||
         ($print_type eq 'incomplete_problems_selpeople_course') ||
         ($print_type eq 'map_incomplete_problems_people_seq')){
   
   
      #-- prints assignments for whole class or for selected students         #-- prints assignments for whole class or for selected students  
  my $type;   my $type;
  if (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||   if (($print_type eq 'problems_for_students')           ||
      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students_from_page') ||       ($print_type eq 'problems_for_students_from_page') ||
      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ) {       ($print_type eq 'all_problems_students')           ||
        ($print_type eq 'incomplete_problems_selpeople_course') ||
        ($print_type eq 'map_incomplete_problems_people_seq')) {
      $selectionmade=5;       $selectionmade=5;
      $type='problems';       $type='problems';
  } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') {   } elsif ($print_type eq 'resources_for_students') {
      $selectionmade=8;       $selectionmade=8;
      $type='resources';       $type='resources';
  }   }
Line 2540  ENDPART Line 3132  ENDPART
  if (($helper->{'VARS'}->{'student_sort'}    eq 1)  &&    if (($helper->{'VARS'}->{'student_sort'}    eq 1)  && 
      ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) {       ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) {
      @students = sort compare_names  @students;       @students = sort compare_names  @students;
    } else {
        @students = sort compare_sections @students; 
  }   }
  &adjust_number_to_print($helper);   &adjust_number_to_print($helper);
   
Line 2558  ENDPART Line 3152  ENDPART
  }   }
  my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};   my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
   
            my $map;
            if ($helper->{VARS}->{'symb'}) {
                ($map, my $id, my $resource) =
                    &Apache::lonnet::decode_symb($helper->{VARS}->{'symb'});
            }
   
  #loop over students   #loop over students
   
   my $flag_latex_header_remove = 'NO';    my $flag_latex_header_remove = 'NO';
Line 2572  ENDPART Line 3172  ENDPART
      ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {       ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
      $moreenv{'problem_split'}='yes';       $moreenv{'problem_split'}='yes';
  }   }
  my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75');   my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$#students+1);
  my $student_counter=-1;   my $student_counter=-1;
  my $i = 0;   my $i = 0;
  my $last_section = (split(/:/,$students[0]))[2];   my $last_section = (split(/:/,$students[0]))[2];
  foreach my $person (@students) {   foreach my $person (@students) {
   
              my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";               my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";
      if (-e $duefile) {       if (-e $duefile) {
  my $temp_file = Apache::File->new('>>'.$duefile);   my $temp_file = Apache::File->new('>>'.$duefile);
Line 2593  ENDPART Line 3192  ENDPART
      } else {       } else {
  $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'});   $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'});
      }       }
        my $actual_seq = master_seq_to_person_seq($map, \@master_seq,
                                                          $person);
      my ($output,$fullname, $printed)=&print_resources($r,$helper,       my ($output,$fullname, $printed)=&print_resources($r,$helper,
      $person,$type,       $person,$type,
      \%moreenv,\@master_seq,       \%moreenv,  $actual_seq,
      $flag_latex_header_remove,       $flag_latex_header_remove,
      $LaTeXwidth);       $LaTeXwidth);
      $resources_printed .= ":";       $resources_printed .= ":";
Line 2608  ENDPART Line 3209  ENDPART
  }   }
  &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);   &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
  $result .= $print_array[0].'  \end{document}';   $result .= $print_array[0].'  \end{document}';
      } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon')     ||       } elsif (($print_type eq 'problems_for_anon')      ||
       ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon_page') ||        ($print_type eq 'problems_for_anon_page') ||
       ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon')  ) {         ($print_type eq 'resources_for_anon')  ) { 
  my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};   my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
  my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};   my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
  my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'};   my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'};
Line 2618  ENDPART Line 3219  ENDPART
  my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'};   my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'};
  my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'};   my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'};
  my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'};   my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'};
   
  my $code_option=$helper->{'VARS'}->{'CODE_OPTION'};   my $code_option=$helper->{'VARS'}->{'CODE_OPTION'};
          my @lines = &Apache::grades::get_scantronformat_file();           my @lines = &Apache::grades::get_scantronformat_file();
  my ($code_type,$code_length)=('letter',6);   my ($code_type,$code_length,$bubbles_per_row)=('letter',6,10);
  foreach my $line (@lines) {   foreach my $line (@lines) {
      my ($name,$type,$length) = (split(/:/,$line))[0,2,4];               chomp($line);
        my ($name,$type,$length,$bubbles_per_item) = 
                    (split(/:/,$line))[0,2,4,17];
      if ($name eq $code_option) {       if ($name eq $code_option) {
  $code_length=$length;   $code_length=$length;
  if ($type eq 'number') { $code_type = 'number'; }   if ($type eq 'number') { $code_type = 'number'; }
                    chomp($bubbles_per_item); 
                    if (($bubbles_per_item ne '') && ($bubbles_per_item > 0)) {
                        $bubbles_per_row = $bubbles_per_item; 
                    }
      }       }
  }   }
            my ($randomorder,$randompick,$map);
            if ($helper->{VARS}{'symb'}) {
                ($map, my $id, my $resource) =
                    &Apache::lonnet::decode_symb($helper->{VARS}{'symb'});
                my $navmap = Apache::lonnavmaps::navmap->new();
                if (defined($navmap)) {
                    if ($map) {
                        my $mapres = $navmap->getResourceByUrl($map);
                        $randomorder = $mapres->randomorder();
                        $randompick = $mapres->randompick();
                    }
                }
            }
  my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth));   my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth));
  $moreenv{'problem_split'}    = $parmhash{'problem_stream_switch'};   $moreenv{'problem_split'}    = $parmhash{'problem_stream_switch'};
          $moreenv{'instructor_comments'}='hide';           $moreenv{'instructor_comments'}='hide';
            $moreenv{'bubbles_per_row'} = $bubbles_per_row;
  my $seed=time+($$<<16)+($$);   my $seed=time+($$<<16)+($$);
  my @allcodes;   my @allcodes;
  if ($old_name) {   if ($old_name) {
Line 2672  ENDPART Line 3292  ENDPART
      @allcodes=keys(%allcodes);       @allcodes=keys(%allcodes);
  }   }
  my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};   my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
  my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'});   my ($type) = split(/_/,$print_type);
  &adjust_number_to_print($helper);   &adjust_number_to_print($helper);
  my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'};   my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'};
  if ($number_per_page eq '0' || $number_per_page eq 'all') {   if ($number_per_page eq '0' || $number_per_page eq 'all'
      $number_per_page=$num_todo;       || $number_per_page eq 'section') {
        $number_per_page=$num_todo > 0 ? $num_todo : 1;
  }   }
  my $flag_latex_header_remove = 'NO';    my $flag_latex_header_remove = 'NO'; 
  my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75');   my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$num_todo);
  my $count=0;   my $count=0;
  foreach my $code (sort(@allcodes)) {   foreach my $code (sort(@allcodes)) {
      my $file_num=int($count/$number_per_page);       my $file_num=int($count/$number_per_page);
Line 2688  ENDPART Line 3309  ENDPART
      } else {       } else {
  $moreenv{'CODE'}=&num_to_letters($code);   $moreenv{'CODE'}=&num_to_letters($code);
      }       }
                my $actual_seq = \@master_seq;
                if ($randomorder) {
                    $env{'form.CODE'} = $moreenv{'CODE'};
                    $actual_seq = master_seq_to_person_seq($map, \@master_seq,
                                                           undef,
                                                           $moreenv{'CODE'});
                    delete($env{'form.CODE'});
                }
      my ($output,$fullname, $printed)=       my ($output,$fullname, $printed)=
  &print_resources($r,$helper,'anonymous',$type,\%moreenv,   &print_resources($r,$helper,'anonymous',$type,\%moreenv,
   \@master_seq,$flag_latex_header_remove,    $actual_seq,$flag_latex_header_remove,
   $LaTeXwidth);    $LaTeXwidth);
      $resources_printed .= ":";       $resources_printed .= ":";
      $print_array[$file_num].=$output;       $print_array[$file_num].=$output;
Line 2702  ENDPART Line 3331  ENDPART
  }   }
  &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);   &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
  $result .= $print_array[0].'  \end{document}';   $result .= $print_array[0].'  \end{document}';
      } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') {             } elsif ($print_type eq 'problems_from_directory') {      
     #prints selected problems from the subdirectory       #prints selected problems from the subdirectory 
  $selectionmade = 6;   $selectionmade = 6;
         my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};          my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};
Line 2721  ENDPART Line 3350  ENDPART
     if ($urlp=~/\//) {      if ($urlp=~/\//) {
  $form{'problem_split'}=$parmhash{'problem_stream_switch'};   $form{'problem_split'}=$parmhash{'problem_stream_switch'};
  $form{'rndseed'}=$rndseed;   $form{'rndseed'}=$rndseed;
  if ($urlp =~ m|/home/([^/]+)/public_html|) {   $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;
     $urlp =~ s|/home/([^/]*)/public_html|/~$1|;  
  } else {  
     $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;  
  }  
  $resources_printed .= $urlp.':';   $resources_printed .= $urlp.':';
  my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);   my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
  if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||   if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
Line 2746  ENDPART Line 3371  ENDPART
     $texversion.='\vskip 0 mm \noindent ';      $texversion.='\vskip 0 mm \noindent ';
     $texversion.=&path_to_problem ($urlp,$LaTeXwidth);      $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
  } else {   } else {
     $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';      $texversion.='\vskip 0 mm \noindent\textbf{'.
     my $URLpath=$urlp;                                           &mt("Printing from Construction Space: No Title").'}\vskip 0 mm ';
     $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;      $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
     $texversion.=&path_to_problem ($URLpath,$LaTeXwidth);  
  }   }
  $texversion.='\vskip 1 mm '.$answer.'\end{document}';   $texversion.='\vskip 1 mm '.$answer.'\end{document}';
     }      }
  }   }
                 #this chunk is responsible for printing the path to problem                  #this chunk is responsible for printing the path to problem
   
  my $newurlp=$urlp;   my $newurlp=&path_to_problem($urlp,$LaTeXwidth);
  if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;}  
  $newurlp=&path_to_problem($newurlp,$LaTeXwidth);  
  $texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;   $texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;
  if ($flag_latex_header_remove ne 'NO') {   if ($flag_latex_header_remove ne 'NO') {
     $texversion = &latex_header_footer_remove($texversion);      $texversion = &latex_header_footer_remove($texversion);
Line 2784  ENDPART Line 3406  ENDPART
     # Only post process if that has not been turned off e.g. by a raw latex resource.      # Only post process if that has not been turned off e.g. by a raw latex resource.
   
     if ($do_postprocessing) {      if ($do_postprocessing) {
  $result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade);   $result = &page_format_transformation($papersize,
         $laystyle,$numberofcolumns,
         $print_type,$result,
         $helper->{VARS}->{'assignment'},
         $helper->{'VARS'}->{'TABLE_CONTENTS'},
         $helper->{'VARS'}->{'TABLE_INDEX'},
         $selectionmade);
  $result = &latex_corrections($number_of_columns,$result,$selectionmade,   $result = &latex_corrections($number_of_columns,$result,$selectionmade,
      $helper->{'VARS'}->{'ANSWER_TYPE'});       $helper->{'VARS'}->{'ANSWER_TYPE'});
  #if ($numberofcolumns == 1) {   #if ($numberofcolumns == 1) {
Line 2801  ENDPART Line 3429  ENDPART
   
     my $URLback=''; #link to original document      my $URLback=''; #link to original document
     if ($helper->{'VARS'}->{'construction'} eq '1') {      if ($helper->{'VARS'}->{'construction'} eq '1') {
  #prints resource from the construction space   $URLback=$helper->{'VARS'}->{'filename'};
  $URLback='/'.$helper->{'VARS'}->{'filename'};  
  if ($URLback=~/([^?]+)/) {  
     $URLback=$1;  
     $URLback=~s|^/~|/priv/|;  
  }  
     }      }
     #      #
     # Final adjustment of the font size:      # Final adjustment of the font size:
Line 2814  ENDPART Line 3437  ENDPART
   
     $result = set_font_size($result);      $result = set_font_size($result);
   
       # Insert any babel headers required.
   
       $result       = &collect_languages($result);
   
   
 #-- writing .tex file in prtspool   #-- writing .tex file in prtspool 
     my $temp_file;      my $temp_file;
     my $identifier = &Apache::loncommon::get_cgi_id();      my $identifier = &Apache::loncommon::get_cgi_id();
Line 2941  sub print_resources { Line 3569  sub print_resources {
     my ($username,$userdomain,$usersection) = split /:/,$person;      my ($username,$userdomain,$usersection) = split /:/,$person;
     my $fullname = &get_name($username,$userdomain);      my $fullname = &get_name($username,$userdomain);
     my $namepostfix = "\\\\"; # Both anon and not anon should get the same vspace.      my $namepostfix = "\\\\"; # Both anon and not anon should get the same vspace.
     if ($person =~ 'anon') {  
  $namepostfix .="Name: ";  
       #
       # Figure out if we need to filter the output by
       # the incomplete problems for that person
       #
       my $print_type = $helper->{'VARS'}->{'PRINT_TYPE'};
       my $print_incomplete = 0;
       if (($print_type eq 'map_incomplete_problems_people_seq')   ||
    ($print_type eq 'incomplete_problems_selpeople_course')) {
    $print_incomplete = 1;
       }
       if ($person eq 'anonymous') {
    $namepostfix .=&mt('Name:')." ";
  $fullname = "CODE - ".$moreenv->{'CODE'};   $fullname = "CODE - ".$moreenv->{'CODE'};
     }      }
   
     #  Fullname may have special latex characters that need \ prefixing:      #  Fullname may have special latex characters that need \ prefixing:
     #      #
   
     my $i           = 0;      my $i           = 0;
       my $actually_printed = 0; # Count of resources printed.
     #goes through all resources, checks if they are available for       #goes through all resources, checks if they are available for 
     #current student, and produces output         #current student, and produces output   
   
Line 2965  sub print_resources { Line 3607  sub print_resources {
     #   so we will just rely on prntout.pl to strip  ENDOFSTUDENTSTAMP from the      #   so we will just rely on prntout.pl to strip  ENDOFSTUDENTSTAMP from the
     #   postscript.  Each ENDOFSTUDENTSTAMP will go on a line by itself.      #   postscript.  Each ENDOFSTUDENTSTAMP will go on a line by itself.
     #      #
   
     my $syllabus_first = 0;      my $syllabus_first = 0;
       my $current_assignment = "";
       my $assignment;
       my $courseidinfo = &get_course();
       if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo }
       if ($usersection ne '') {$courseidinfo.=' - Sec. '.$usersection}
   
     foreach my $curresline (@{$master_seq})  {      foreach my $curresline (@{$master_seq})  {
  if (defined $page_breaks{$curresline}) {   if (defined $page_breaks{$curresline}) {
     if($i != 0) {      if($i != 0) {
Line 2974  sub print_resources { Line 3623  sub print_resources {
  }   }
  $current_output .= &get_extra_vspaces($helper, $curresline);   $current_output .= &get_extra_vspaces($helper, $curresline);
  $i++;   $i++;
    my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
   
    # See if we need to emit a new header:
   
  if ( !($type eq 'problems' &&    if ( !($type eq 'problems' && 
        ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library|page)$/)) ) {         ($curresline!~ m/$LONCAPA::assess_page_re/)) ) {
     my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);      if ($print_incomplete && !&incomplete($username, $userdomain, $res_url)) {
    next;
       }
       $actually_printed++; # we're going to print one.
     if (&Apache::lonnet::allowed('bre',$res_url)) {      if (&Apache::lonnet::allowed('bre',$res_url)) {
  if ($res_url!~m|^ext/|   if ($res_url!~m|^ext/|
     && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {      && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
Line 2991  sub print_resources { Line 3646  sub print_resources {
                                 $rendered = &print_latex_header().$rendered;                                  $rendered = &print_latex_header().$rendered;
                             }                              }
                         }                          }
   ;
                         if ($remove_latex_header eq 'YES') {                          if ($remove_latex_header eq 'YES') {
                             $rendered = &latex_header_footer_remove($rendered);                              $rendered = &latex_header_footer_remove($rendered);
                         } else {                          } else {
Line 3002  sub print_resources { Line 3658  sub print_resources {
  #   Use a copy of the hash so we don't pervert it on future loop passes.   #   Use a copy of the hash so we don't pervert it on future loop passes.
  my %answerenv = %{$moreenv};   my %answerenv = %{$moreenv};
  $answerenv{'answer_output_mode'}='tex';   $answerenv{'answer_output_mode'}='tex';
   
   
  $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};   $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
   
  &Apache::lonxml::restore_problem_counter();   &Apache::lonxml::restore_problem_counter();
Line 3073  sub print_resources { Line 3731  sub print_resources {
  }   }
     }      }
     $remove_latex_header = 'YES';      $remove_latex_header = 'YES';
  }    }
    $assignment = &Apache::lonxml::latex_special_symbols(
       &Apache::lonnet::gettitle($map), 'header');
    if (($assignment ne $current_assignment) && ($assignment ne "")) {
       my $header_line = &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
     $assignment, $courseidinfo, 
     $fullname);
       my $header_start = ($columns_in_format == 1) ? '\lhead'
    : '\fancyhead[LO]';
       $header_line = $header_start.'{'.$header_line.'}';
       $current_output = $current_output . $header_line;
       $current_assignment = $assignment;
    }
   
  if (&Apache::loncommon::connection_aborted($r)) { last; }   if (&Apache::loncommon::connection_aborted($r)) { last; }
     }      }
       # If we are printing incomplete it's possible we don't have
       # anything to print.  The print subsystem is not so good at handling
       # that so we're going to generate a stub that says there are no
       # incomplete resources for the person.
       #
   
       if ($actually_printed == 0) {
    $current_output  = &encapsulate_minipage("\\vskip -10mm \nNo incomplete resources\n \\vskip 100 mm { }\n");
    if ($remove_latex_header eq "NO") {
       $current_output = &print_latex_header() . $current_output;
    } else {
       $current_output = &latex_header_footer_remove($current_output);
    }
       }
   
     if ($syllabus_first) {      if ($syllabus_first) {
         $current_output =~ s/\\\\ Last updated:/Last updated:/          $current_output =~ s/\\\\ Last updated:/Last updated:/
     }      }
     my $courseidinfo = &get_course();      if (0) {
     my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');   my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
     my $header_line =   my $header_line =
  &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},      &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
     $currentassignment, $courseidinfo, $fullname, $usersection);   $currentassignment, $courseidinfo, $fullname);
     my $header_start = ($columns_in_format == 1) ? '\lhead'   my $header_start = ($columns_in_format == 1) ? '\lhead'
                                          : '\fancyhead[LO]';      : '\fancyhead[LO]';
     $header_line = $header_start.'{'.$header_line.'}';   $header_line = $header_start.'{'.$header_line.'}';
       }
     if ($current_output=~/\\documentclass/) {      if ($current_output=~/\\documentclass/) {
  $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;  # $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
    $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$namepostfix}\\vskip 5 mm /;
   
     } else {      } else {
  my $blankpages =    my $blankpages = 
     '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};      '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
       
   # $current_output = '\strut\vspace*{-6 mm}\\newline'.
   #    &copyright_line().' \newpage '.$blankpages.$end_of_student.
   #    '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
   #    $header_line.$namepostfix. '} \vskip 5 mm '.$current_output;
  $current_output = '\strut\vspace*{-6 mm}\\newline'.   $current_output = '\strut\vspace*{-6 mm}\\newline'.
     &copyright_line().' \newpage '.$blankpages.$end_of_student.      &copyright_line().' \newpage '.$blankpages.$end_of_student.
     '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.      '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'
     $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;      .$namepostfix. '} \vskip 5 mm '.$current_output;
   
     }      }
     #      #
     #  Close the student bracketing.      #  Close the student bracketing.
Line 3106  sub print_resources { Line 3799  sub print_resources {
   
 }  }
   
   sub printing_blocked {
       my ($r,$blocktext) = @_;
       my $title = &mt('Preparing Printout');
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/printout',
                                               text=> $title});
       my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs($title);
       &Apache::loncommon::content_type($r,'text/html');
       &Apache::loncommon::no_cache($r);
       $r->send_http_header;
       $r->print(&Apache::loncommon::start_page('Preparing Printout').
                 $breadcrumbs.
                 $blocktext.
                 &Apache::loncommon::end_page());
       return;
   }
   
 sub handler {  sub handler {
   
     my $r = shift;      my $r = shift;
   
       if ($env{'request.course.id'}) {
           my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
           my ($blocked,$blocktext) = 
               &Apache::loncommon::blocking_status('printout',$cnum,$cdom);
           if ($blocked) {
               my $checkrole = "cm./$cdom/$cnum";
               if ($env{'request.course.sec'} ne '') {
                   $checkrole .= "/$env{'request.course.sec'}";
               }
               unless ((&Apache::lonnet::allowed('evb',undef,undef,$checkrole)) && 
                       ($env{'request.role'} !~ m{^st\./$cdom/$cnum})) {
                   &printing_blocked($r,$blocktext);
                   return OK;
               }
           }
       }
           
     &init_perm();      &init_perm();
   
   
   
     my $helper = printHelper($r);      my $helper = printHelper($r);
     if (!ref($helper)) {      if (!ref($helper)) {
  return $helper;   return $helper;
Line 3137  sub handler { Line 3862  sub handler {
   
     &output_data($r,$helper,\%parmhash);      &output_data($r,$helper,\%parmhash);
     return OK;      return OK;
 }   }
   
 use Apache::lonhelper;  use Apache::lonhelper;
   
Line 3162  sub init_perm { Line 3887  sub init_perm {
  $perm{'pfo'}=&Apache::lonnet::allowed('pfo',   $perm{'pfo'}=&Apache::lonnet::allowed('pfo',
   $env{'request.course.id'}.'/'.$env{'request.course.sec'});    $env{'request.course.id'}.'/'.$env{'request.course.sec'});
     }      }
       $perm{'vgr'}=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});
       if (!$perm{'vgr'}) {
           $perm{'vgr'}=&Apache::lonnet::allowed('vgr',
                      $env{'request.course.id'}.'/'.$env{'request.course.sec'});
       }
 }  }
   
 sub get_randomly_ordered_warning {  sub get_randomly_ordered_warning {
Line 3177  sub get_randomly_ordered_warning { Line 3907  sub get_randomly_ordered_warning {
     my $func =       my $func = 
         sub { return ($_[0]->is_map() && $_[0]->randomorder); };          sub { return ($_[0]->is_map() && $_[0]->randomorder); };
     my @matches = $navmap->retrieveResources($res, $func,1,1,1);      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 type="warning">'.$message.'</message>';  
         }          }
     } else {      } else {
         $message = "Retrieval of information about ordering of resources failed.";           $message = "Retrieval of information about ordering of resources failed."; 
Line 3272  sub printHelper { Line 3997  sub printHelper {
     }      }
   
     # Detect whether we're coming from construction space      # Detect whether we're coming from construction space
     if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {      if ($env{'form.postdata'}=~m{^/priv}) {
         $helper->{VARS}->{'filename'} = "~$1/$2";          $helper->{VARS}->{'filename'} = $env{'form.postdata'};
         $helper->{VARS}->{'construction'} = 1;          $helper->{VARS}->{'construction'} = 1;
     } else {      } else {
         if ($env{'form.postdata'}) {          if ($env{'form.postdata'}) {
Line 3309  sub printHelper { Line 4034  sub printHelper {
     my ($map, $id, $url);      my ($map, $id, $url);
     my $subdir;      my $subdir;
     my $is_published=0; # True when printing from resource space.      my $is_published=0; # True when printing from resource space.
       my $res_printable = 1; # By default the current resource is printable.    
       my $userCanPrint = ($perm{'pav'} || $perm{'pfo'});
       my $res_printstartdate;
       my $res_printenddate;
       my $map_open = 0;
       my $map_close = 0xffffffff;
       my $course_open = 0;
       my $course_close = 0xffffffff;
   
     # Get the resource name from construction space      # Get the resource name from construction space
     if ($helper->{VARS}->{'construction'}) {      if ($helper->{VARS}->{'construction'}) {
Line 3323  sub printHelper { Line 4056  sub printHelper {
     ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);      ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
     $helper->{VARS}->{'postdata'} =       $helper->{VARS}->{'postdata'} = 
  &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));   &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
       my $navmap = Apache::lonnavmaps::navmap->new();
       my $res   = $navmap->getBySymb($symb);
       $res_printable  = $res->resprintable() | $userCanPrint; #printability in course context
       ($res_printstartdate, $res_printenddate) = &get_print_dates($res);
       ($course_open, $course_close) = &course_print_dates($res);
       ($map_open, $map_close)       = &map_print_dates($res);
   
  } else {   } else {
       # Resource space.
   
     $url = $helper->{VARS}->{'postdata'};      $url = $helper->{VARS}->{'postdata'};
     $is_published=1; # From resource space.      $is_published=1; # From resource space.
  }   }
Line 3333  sub printHelper { Line 4075  sub printHelper {
             $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);              $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
         }          }
         $subdir = &Apache::lonnet::filelocation("", $url);          $subdir = &Apache::lonnet::filelocation("", $url);
   
   
     }      }
     if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {      if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
  $helper->{VARS}->{'curseed'}=$env{'form.curseed'};   $helper->{VARS}->{'curseed'}=$env{'form.curseed'};
     }      }
   
     if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {      if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
  $helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};   $helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
     }      }
Line 3362  sub printHelper { Line 4107  sub printHelper {
     my $printChoices = [];      my $printChoices = [];
     my $paramHash;      my $paramHash;
   
     if ($resourceTitle) {      # If there is a current resource and it is printable
       # Give that as a choice.
   
       if ($resourceTitle && $res_printable) {
         push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];          push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
     }      } 
   
     # Useful filter strings      # Useful filter strings
     my $isProblem = '($res->is_problem()||$res->contains_problem||$res->is_practice()) ';  
       my $isPrintable = ' && $res->resprintable()';
   
       my $isProblem = '(($res->is_problem()||$res->contains_problem() ||$res->is_practice()))';
       $isProblem .= $isPrintable unless $userCanPrint;
     $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;      $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
     my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice()';      my $isProblemOrMap = '($res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice())';
     my $isNotMap = '!$res->is_sequence()';      $isProblemOrMap .= $isPrintable unless $userCanPrint;
       my $isNotMap = '(!$res->is_sequence())';
       $isNotMap .= $isPrintable unless $userCanPrint;
     $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;      $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
     my $isMap = '$res->is_map()';      my $isMap = '$res->is_map()';
     my $symbFilter = '$res->shown_symb()';      $isMap .= $isPrintable unless $userCanPrint;
       my $symbFilter = '$res->shown_symb() ';
     my $urlValue = '$res->link()';      my $urlValue = '$res->link()';
   
     $helper->declareVar('SEQUENCE');      $helper->declareVar('SEQUENCE');
Line 3453  sub printHelper { Line 4208  sub printHelper {
     if (($helper->{'VAR'}->{'construction'} ne '1' ) &&      if (($helper->{'VAR'}->{'construction'} ne '1' ) &&
  $helper->{VARS}->{'postdata'} &&   $helper->{VARS}->{'postdata'} &&
  $helper->{VARS}->{'assignment'}) {   $helper->{VARS}->{'assignment'}) {
   
    # BZ 5209 - Print incomplete problems from sequence:
    # the exact form of this depends on whether or not we are privileged or a mere
    # plebe of s student:
   
    my $printSelector = 'map_incomplete_problems_seq';
    my $nextState     = 'CHOOSE_INCOMPLETE_SEQ';
    my $textSuffix    = '';
   
    if ($userCanPrint)  {
       $printSelector = 'map_incomplete_problems_people_seq';
       $nextState     = 'CHOOSE_INCOMPLETE_PEOPLE_SEQ';
       $textSuffix    = ' for selected students';
       my $helperStates =
    &create_incomplete_folder_selstud_helper($helper, $map); 
       &Apache::lonxml::xmlparse($r, 'helper', $helperStates);
    } else {
       if (&printable($map_open, $map_close)) {
    my $helperStates = &create_incomplete_folder_helper($helper, $map); # Create needed states for student.
    &Apache::lonxml::xmlparse($r, 'helper', $helperStates);
       } else {
    # TODO: Figure out how to break the news...this folder is not printable.
       }
    }
   
    if ($userCanPrint || &printable($map_open, $map_close)) {
       push(@{$printChoices},
    [&mt('Selected  [_1]Incomplete Problems[_2] from folder [_3]' . $textSuffix,
         '<b>', '</b>',
         '<b><i>'. $sequenceTitle . '</b></i>'),
     $printSelector,
     $nextState]);
    }
         # Allow problems from sequence          # Allow problems from sequence
         push @{$printChoices},    if ($userCanPrint || &printable($map_open, $map_close)) {
       push @{$printChoices}, 
     [&mt('Selected [_1]Problems[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'),       [&mt('Selected [_1]Problems[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'), 
      'map_problems',        'map_problems', 
      'CHOOSE_PROBLEMS'];       'CHOOSE_PROBLEMS'];
         # Allow all resources from sequence      # Allow all resources from sequence
         push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'),       push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'), 
  'map_problems_pages',       'map_problems_pages', 
  'CHOOSE_PROBLEMS_HTML'];      'CHOOSE_PROBLEMS_HTML'];
         my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS',      my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS',
  'Select Problem(s) to print',      'Select Problem(s) to print',
  'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',      'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
  'RESOURCES',      'RESOURCES',
  'PAGESIZE',      'PAGESIZE',
  $map,      $map,
  $isProblem, '',      $isProblem, '',
  $symbFilter,      $symbFilter,
  $start_new_option);      $start_new_option);
  $helperFragment .= &generate_resource_chooser('CHOOSE_PROBLEMS_HTML',      $helperFragment .= &generate_resource_chooser('CHOOSE_PROBLEMS_HTML',
       'Select Resource(s) to print',    'Select Resource(s) to print',
        'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',    'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
       'RESOURCES',    'RESOURCES',
       'PAGESIZE',    'PAGESIZE',
       $map,    $map,
       $isNotMap, '',    $isNotMap, '',
       $symbFilter,    $symbFilter,
       $start_new_option);    $start_new_option);
       
  &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);      &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
    } else {
       # TODO: Figure out how to tell them the folder is not printable.
    }
     }      }
    # If the user has pfo (print for others) allow them to print all 
     # If the user has pfo (print for others) allow them to print all    # problems and resources  in the entire course, optionally for selected students
     # problems and resources  in the entire course, optionally for selected students   my $post_data = $helper->{VARS}->{'postdata'};
     my $post_data = $helper->{VARS}->{'postdata'};      
     if ($perm{'pfo'} &&  !$is_published  &&      if ($perm{'pfo'} &&  !$is_published  &&
         ($post_data=~/\/res\// || $post_data =~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) {           ($post_data=~/\/res\// || $post_data =~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) { 
   
    # BZ 5209 - incomplete problems from entire course:
   
    push(@{$printChoices},
        [&mtn('Selected <b>Incomplete Problems</b> from <b>entire course</b> for selected people'),
         'incomplete_problems_selpeople_course', 'INCOMPLETE_PROBLEMS_COURSE_RESOURCES']);
    my $helperFragment = &create_incomplete_course_helper($helper); # Create needed states.
   
    &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
   
    #  Selected problems/resources from entire course:
   
         push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];          push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
  push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];   push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
  push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b> for <b>selected people</b>'), 'all_problems_students', 'ALL_PROBLEMS_STUDENTS'];   push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b> for <b>selected people</b>'), 'all_problems_students', 'ALL_PROBLEMS_STUDENTS'];
Line 3555  ALL_PROBLEMS Line 4358  ALL_PROBLEMS
  }   }
   
  my $randomly_ordered_warning =    my $randomly_ordered_warning = 
     &get_randomly_ordered_warning($helper,$map);              &get_randomly_ordered_warning($helper, $map);
   
  # resource_selector will hold a few states that:   # resource_selector will hold a few states that:
  #   - Allow resources to be selected for printing.   #   - Allow resources to be selected for printing.
Line 3574  ALL_PROBLEMS Line 4377  ALL_PROBLEMS
   $map,    $map,
   $isProblem, '', $symbFilter,    $isProblem, '', $symbFilter,
   $start_new_option);    $start_new_option);
  $resource_selector .=  <<RESOURCE_SELECTOR;   $resource_selector .=  &generate_format_selector($helper,
     <state name="PRINT_FORMATTING" title="How should results be printed?">                                                           'How should results be printed?',
     <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>                                                           'PRINT_FORMATTING').
     <choices variable="EMPTY_PAGES">                                 &generate_resource_chooser('CHOOSE_STUDENTS_PAGE',
       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>  
       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>  
       <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>  
       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>  
     </choices>  
     <nextstate>PAGESIZE</nextstate>  
     <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>  
     <choices variable="SPLIT_PDFS">  
        <choice computer="all">All assignments in a single PDF file</choice>  
        <choice computer="sections">Each PDF contains exactly one section</choice>  
        <choice computer="oneper">Each PDF contains exactly one assignment</choice>  
        <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">  
             Specify the number of assignments per PDF:</choice>  
     </choices>  
     </state>  
 RESOURCE_SELECTOR  
         $resource_selector .= &generate_resource_chooser('CHOOSE_STUDENTS_PAGE',  
  'Select Problem(s) to print',   'Select Problem(s) to print',
  "multichoice='1' addstatus='1' closeallpages ='1'",   "multichoice='1' addstatus='1' closeallpages ='1'",
  'RESOURCES',   'RESOURCES',
Line 3704  RESOURCE_SELECTOR Line 4490  RESOURCE_SELECTOR
   
   
  if ($helper->{VARS}->{'assignment'}) {   if ($helper->{VARS}->{'assignment'}) {
   
       # Assignment printing:
   
     push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3] for [_4]selected people[_5]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 'resources_for_students', 'CHOOSE_STUDENTS1'];      push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3] for [_4]selected people[_5]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 'resources_for_students', 'CHOOSE_STUDENTS1'];
     push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3] for [_4]CODEd assignments[_5]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 'resources_for_anon', 'CHOOSE_ANON2'];      push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3] for [_4]CODEd assignments[_5]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 'resources_for_anon', 'CHOOSE_ANON2'];
  }   }
Line 3722  RESOURCE_SELECTOR Line 4511  RESOURCE_SELECTOR
       $start_new_option        $start_new_option
       </resource>        </resource>
     </state>      </state>
   
     <state name="PRINT_FORMATTING" title="Format of the print job">  
     <nextstate>NUMBER_PER_PDF</nextstate>  
     <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>  
     <choices variable="EMPTY_PAGES">  
       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>  
       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>  
       <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>  
       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>  
     </choices>  
     <nextstate>PAGESIZE</nextstate>  
     <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>  
     <choices variable="SPLIT_PDFS">  
        <choice computer="all">All assignments in a single PDF file</choice>  
        <choice computer="sections">Each PDF contains exactly one section</choice>  
        <choice computer="oneper">Each PDF contains exactly one assignment</choice>  
        <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">  
            Specify the number of assignments per PDF:</choice>  
     </choices>  
     </state>  
 RESOURCE_SELECTOR  RESOURCE_SELECTOR
   
           $resource_selector .= &generate_format_selector($helper,
                                                           'Format of the print job',
                                                           'PRINT_FORMATTING');
  &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);   &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
   <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">    <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
     <choices variable='student_sort'>      <choices variable='student_sort'>
Line 3784  CHOOSE_STUDENTS1 Line 4556  CHOOSE_STUDENTS1
     <message></td><td></message>      <message></td><td></message>
     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />      <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
     <message></td></tr><tr><td></message>      <message></td></tr><tr><td></message>
     <message><b>Bubble sheet type:</b></message>      <message><b>Bubblesheet type:</b></message>
     <message></td><td></message>      <message></td><td></message>
     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">      <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
     $codechoice      $codechoice
Line 3868  CHOOSE_FROM_SUBDIR Line 4640  CHOOSE_FROM_SUBDIR
     <message>Select the sequence to print resources from:</message>      <message>Select the sequence to print resources from:</message>
     <resource variable="SEQUENCE">      <resource variable="SEQUENCE">
       <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>        <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
       <filterfunc>return \$res->is_sequence;</filterfunc>        <filterfunc>return &Apache::lonprintout::printable_sequence(\$res);</filterfunc>
       <valuefunc>return $urlValue;</valuefunc>        <valuefunc>return $urlValue;</valuefunc>
       <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);        <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
  </choicefunc>   </choicefunc>
Line 3890  CHOOSE_FROM_ANY_SEQUENCE Line 4662  CHOOSE_FROM_ANY_SEQUENCE
   
     # Generate the first state, to select which resources get printed.      # Generate the first state, to select which resources get printed.
     Apache::lonhelper::state->new("START", "Select Printing Options:");      Apache::lonhelper::state->new("START", "Select Printing Options:");
       if (!$res_printable) {
    $paramHash = Apache::lonhelper::getParamHash();
    $paramHash->{MESSAGE_TEXT} = 
       &mt('[_1]Printing for current resource is only possible between [_2] and [_3]',
           '<p><b>',$res_printstartdate, $res_printenddate.'</b></p>');
    Apache::lonhelper::message->new();
       }
       $paramHash = Apache::lonhelper::getParamHash();
     $paramHash = Apache::lonhelper::getParamHash();      $paramHash = Apache::lonhelper::getParamHash();
     $paramHash->{MESSAGE_TEXT} = "";      $paramHash->{MESSAGE_TEXT} = "";
     Apache::lonhelper::message->new();      Apache::lonhelper::message->new();
Line 3901  CHOOSE_FROM_ANY_SEQUENCE Line 4681  CHOOSE_FROM_ANY_SEQUENCE
     my $startedTable = 0; # have we started an HTML table yet? (need      my $startedTable = 0; # have we started an HTML table yet? (need
                           # to close it later)                            # to close it later)
   
     if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or       if (($perm{'pav'} and $perm{'vgr'}) or 
  ($helper->{VARS}->{'construction'} eq '1')) {   ($helper->{VARS}->{'construction'} eq '1')) {
  &addMessage('<br />'   &addMessage('<br />'
                    .'<h3>'.&mt('Print Options').'</h3>'                     .'<h3>'.&mt('Print Options').'</h3>'
Line 4148  PROBTYPE Line 4928  PROBTYPE
         return $helper;          return $helper;
     }          }    
   
     $r->print($helper->display());      my $footer;
     if ($helper->{STATE} eq 'START') {      if ($helper->{STATE} eq 'START') {
  &recently_generated($r);          my $prtspool=$r->dir_config('lonPrtDir'); 
    $footer = &recently_generated($prtspool);
     }      }
       $r->print($helper->display($footer));
     &Apache::lonhelper::unregisterHelperTags();      &Apache::lonhelper::unregisterHelperTags();
   
     return OK;      return OK;
Line 4530  sub postprocess { Line 5312  sub postprocess {
     }      }
 }  }
   
   
   
 __END__  __END__
   

Removed from v.1.583  
changed lines
  Added in v.1.627.2.1


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>