Diff for /loncom/interface/lonprintout.pm between versions 1.560.2.5 and 1.632

version 1.560.2.5, 2009/10/12 10:59:48 version 1.632, 2013/06/01 00:22:37
Line 1 Line 1
 #  
   
   
 # The LearningOnline Network  # The LearningOnline Network
 # Printout  # Printout
 #  #
Line 30 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 43  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 78  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 {
       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 92  sub generate_student_chooser { Line 280  sub generate_student_chooser {
  $sort_choice,    $sort_choice, 
  $variable,    $variable, 
  $next_state) = @_;   $next_state) = @_;
     &Apache::lonnet::logthis("Student chooser next state: $next_state, this state: $this_state");  
     my $result = <<CHOOSE_STUDENTS;      my $result = <<CHOOSE_STUDENTS;
   <state name="$this_state" title="Select Students and Resources">    <state name="$this_state" title="Select Students and Resources">
       <message><b>Select sorting order of printout</b> </message>        <message><b>Select sorting order of printout</b> </message>
Line 148  sub generate_resource_chooser { Line 335  sub generate_resource_chooser {
  $value_func,   $value_func,
  $start_new_option)  = @_;   $start_new_option)  = @_;
   
     &Apache::lonnet::logthis("Top URL = $top_url");  
     my $result = <<CHOOSE_RESOURCES;      my $result = <<CHOOSE_RESOURCES;
 <state name="$this_state" title="$prompt_text">  <state name="$this_state" title="$prompt_text">
     <resource variable="$variable" $resource_options      <resource variable="$variable" $resource_options
Line 168  CHOOSE_RESOURCES Line 354  CHOOSE_RESOURCES
       </resource>        </resource>
     </state>      </state>
 CHOOSE_RESOURCES  CHOOSE_RESOURCES
   
     return $result;      return $result;
 }  }
   #
   #   Generate the helper XML for a code choice helper dialog:
   #
   # Paramters:
   #   $helper       - Reference to the helper.
   #   $state        - Name of the state for the chooser.
   #   $next_state   - Name fo the state to follow the chooser.
   #   $bubble_types - Populates the bubble sheet type dropt down.
   #   $code_selections - Provides set of code choices that have been used
   #   $saved_codes  - Provides the list of saved codes.
   #
   # Returns;
   #   The Xml of the code chooser.
   #
   sub generate_code_selector {
       my ($helper,
    $state,
    $next_state,
    $bubble_types,
    $code_selections,
    $saved_codes) = @_; # Unpack the parameters.
   
       my $result = <<CHOOSE_ANON1;
     <state name="$state" title="Specify CODEd Assignments">
       <nextstate>$next_state</nextstate>
       <message><h4>Fill out one of the forms below</h4></message>
       <message><br /><hr /> <br /></message>
       <message><h3>Generate new CODEd Assignments</h3></message>
       <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
       <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5"  noproceed="1">
          <validator>
    if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
       !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
               !\$helper->{'VARS'}{'SINGLE_CODE'}                    &&
       !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'} ) {
   
       return "You need to specify the number of assignments to print";
    }
           if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) >= 1)  &&
                (\$helper->{'VARS'}{'SINGLE_CODE'} ne '') ) {
               return 'Specifying number of codes to print and a specific code is not compatible';
           }
    return undef;
          </validator>
       </string>
       <message></td></tr><tr><td></message>
       <message><b>Names to save the CODEs under for later:</b></message>
       <message></td><td></message>
       <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
       <message></td></tr><tr><td></message>
       <message><b>Bubblesheet type:</b></message>
       <message></td><td></message>
       <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
       $bubble_types
       </dropdown>
       <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>
       <message></td></tr><tr><td></table></message>
       <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
       <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
       <string variable="SINGLE_CODE" size="10">
           <validator>
      if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&
         !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&
         !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
         return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
         \$helper->{'VARS'}{'CODE_OPTION'});
     } elsif (\$helper->{'VARS'}{'SINGLE_CODE'} ne ''){
         return 'Specifying a code name is incompatible with specifying number of codes.';
      } else {
          return undef; # Other forces control us.
      }
           </validator>
       </string>
       <message></td></tr><tr><td></message>
           $code_selections
       <message></td></tr></table></message>
       <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
       <message><b>Select saved CODEs:</b></message>
       <message></td><td></message>
       <dropdown variable="REUSE_OLD_CODES">
           $saved_codes
       </dropdown>
       <message></td></tr></table></message>
     </state>
   CHOOSE_ANON1
   
      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, $nohidemap) = @_;
   
   
       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 $unhidden;
       if ($perm{'pav'} && $perm{'vgr'} && $nohidemap) {
           $unhidden = &Apache::lonnet::clutter($map);
       }
       
       my $navmap           = Apache::lonnavmaps::navmap->new($username, $userdomain,
                                                              $code, $unhidden);
       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 230  sub set_font_size { Line 832  sub set_font_size {
   
     my ($text) = @_;      my ($text) = @_;
   
     $text =~ s/\\begin{document}/\\begin{document}{\\$font_size/;      # There appear to be cases where the font directive is empty.. in which
       # case the first substituion would  insert a spurious \ oh happy day.
       # as this has been the cause of much mystery and hair pulling _sigh_
   
       if ($font_size ne '') {
   
    $text =~ s/\\begin{document}/\\begin{document}{\\$font_size/;
       }
     $text =~ s/\\end{document}/}\\end{document}/;      $text =~ s/\\end{document}/}\\end{document}/;
     return $text;      return $text;
   
Line 270  sub include_pdf { Line 879  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 295  sub include_pdf { Line 905  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 342  sub ssi_with_retries { Line 974  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 358  sub get_student_view_with_retries { Line 989  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 423  sub printf_style_subst { Line 1053  sub printf_style_subst {
 sub format_page_header {  sub format_page_header {
     my ($width, $format, $assignment, $course, $student, $section) = @_;      my ($width, $format, $assignment, $course, $student, $section) = @_;
   
       
   
     $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.
   
     #  Default format?      #  Default format?
   
     if ($format eq '') {      if ($format eq '') {
Line 438  sub format_page_header { Line 1071  sub format_page_header {
  #   but only truncate the course.   #   but only truncate the course.
  # - Allow the assignment to be 2 lines (wrapped).   # - Allow the assignment to be 2 lines (wrapped).
  #   #
  my $chars_per_line = $width/2; # Character/textline.  
   
   
   
   
  my $name_length    = int($chars_per_line *3 /4);   my $name_length    = int($chars_per_line *3 /4);
  my $sec_length     = int($chars_per_line / 5);   my $sec_length     = int($chars_per_line / 5);
Line 476  sub format_page_header { Line 1108  sub format_page_header {
         my $testPrintout = '\\\\'.&mt('Construction Space').' \\\\'.&mt('Test-Printout ');          my $testPrintout = '\\\\'.&mt('Construction Space').' \\\\'.&mt('Test-Printout ');
         $format =~ s/\\\\\s\\\\\s/$testPrintout/;          $format =~ s/\\\\\s\\\\\s/$testPrintout/;
     }      }
           #
       #  We're going to trust LaTeX to break lines appropriately, but
       #  we'll truncate anything that's more than 3 lines worth of
       # text.  This is also assuming (which will probably end badly)
       # nobody's going to embed LaTeX control sequences in the title
       # header or rather that those control sequences won't get broken
       # by the stuff below.
       #
       my $total_length = 3*$chars_per_line;
       if (length($format) > $total_length) {
    $format = substr($format, 0, $total_length);
       }
   
   
     return $format;      return $format;
           
Line 599  sub is_code_valid { Line 1243  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 1187  sub page_format_transformation { Line 1847  sub page_format_transformation {
   
     if ($selectionmade eq '4') {      if ($selectionmade eq '4') {
  if ($choice eq 'all_problems') {   if ($choice eq 'all_problems') {
     $assignment='Problems from the Whole Course';              $assignment=&mt('Problems from the Whole Course');
  } else {   } else {
     $assignment='Resources from the Whole Course';              $assignment=&mt('Resources from the Whole Course');
  }   }
     } else {      } else {
  $assignment=&Apache::lonxml::latex_special_symbols($assignment,'header');   $assignment=&Apache::lonxml::latex_special_symbols($assignment,'header');
Line 1219  sub page_format_transformation { Line 1879  sub page_format_transformation {
     $text =~ s/\\pagestyle{fancy}\\rhead{}\\chead{}\s*\\begin{document}/\\textheight = $textheight\\oddsidemargin = $evenoffset\n\\evensidemargin = $evenoffset $topmargintoinsert\\textwidth= $textwidth\\newlength{\\minipagewidth}\n\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\\renewcommand{\\ref}{\\keephidden\}\\pagestyle{fancy}\\rhead{}\\chead{}\\usepackage{booktabs}\\begin{document}\\voffset=-0\.8cm\n\\setcounter{page}{1}  \\vskip 5 mm\n /;      $text =~ s/\\pagestyle{fancy}\\rhead{}\\chead{}\s*\\begin{document}/\\textheight = $textheight\\oddsidemargin = $evenoffset\n\\evensidemargin = $evenoffset $topmargintoinsert\\textwidth= $textwidth\\newlength{\\minipagewidth}\n\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\\renewcommand{\\ref}{\\keephidden\}\\pagestyle{fancy}\\rhead{}\\chead{}\\usepackage{booktabs}\\begin{document}\\voffset=-0\.8cm\n\\setcounter{page}{1}  \\vskip 5 mm\n /;
  }   }
  if ($papersize eq 'a4') {   if ($papersize eq 'a4') {
     $text =~ s/(\\begin{document})/$1\\special{papersize=210mm,297mm}/;      my $papersize_text;
       if ($perm{'pav'}) {
    $papersize_text = '\\special{papersize=210mm,297mm}';
       } else {
    $papersize_text = '\special{papersize=210mm,297mm}';
       }
       $text =~ s/(\\begin{document})/$1$papersize_text/;
  }   }
     }      }
     if ($tableofcontents eq 'yes') {$text=~s/(\\setcounter\{page\}\{1\})/$1 \\tableofcontents\\newpage /;}      if ($tableofcontents eq 'yes') {$text=~s/(\\setcounter\{page\}\{1\})/$1 \\tableofcontents\\newpage /;}
Line 1401  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 1426  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 1450  sub print_page_in_course { Line 2118  sub print_page_in_course {
  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);
     } else {      } else {
  $result.=$currentURL;          my $esc_currentURL= $currentURL;
           $esc_currentURL =~ s/_/\\_/g;
    $result.=$esc_currentURL;
     }      }
     $result .= '\\\\';      $result .= '\\\\';
   
Line 1463  sub print_page_in_course { Line 2133  sub print_page_in_course {
   
     # First is the overall page description.  This is then followed by the       # First is the overall page description.  This is then followed by the 
     # components of the page. Each of which must be printed independently.      # components of the page. Each of which must be printed independently.
   
     my $the_page = shift(@page_resources);       my $the_page = shift(@page_resources); 
   
   
     foreach my $resource (@page_resources) {      foreach my $resource (@page_resources) {
  my $resource_src   = $resource->src(); # Essentially the URL of the resource.   my $resource_src   = $resource->src(); # Essentially the URL of the resource.
  $result           .= $resource->title() . '\\\\';   $result           .= $resource->title() . '\\\\';
Line 1477  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|page|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 1491  sub print_page_in_course { Line 2165  sub print_page_in_course {
   
     $form{'grade_target'}  = 'tex';      $form{'grade_target'}  = 'tex';
     $form{'textwidth'}    = &get_textwidth($helper, $LaTeXwidth);      $form{'textwidth'}    = &get_textwidth($helper, $LaTeXwidth);
     $form{'pdfFormFiels'} = $pdfFormFields; #       $form{'pdfFormFields'} = $pdfFormFields; # 
     $form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'};          $form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'};    
           
     $form{'problem_split'}=$parmhash{'problem_stream_switch'};      $form{'problem_split'}=$parmhash{'problem_stream_switch'};
Line 1543  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 1595  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 1629  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 1640  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 1652  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 1666  sub recently_generated { Line 2338  sub recently_generated {
 #    A reference to a page break hash.  #    A reference to a page break hash.
 #  #
 #  #
 use Data::Dumper;  # use Data::Dumper;
 #sub dump_helper_vars {  # sub dump_helper_vars {
 #    my ($helper) = @_;  #    my ($helper) = @_;
 #    my $helpervars = Dumper($helper->{'VARS'});  #    my $helpervars = Dumper($helper->{'VARS'});
 #    &Apache::lonnet::logthis("Dump of helper vars:\n $helpervars");  #    &Apache::lonnet::logthis("Dump of helper vars:\n $helpervars");
Line 1682  sub get_page_breaks  { Line 2354  sub get_page_breaks  {
     }      }
     return %page_breaks;      return %page_breaks;
 }  }
   # 
   #   Returns text to insert for any extra vskip prior to the resource.
   #   Parameters:
   #     helper   - Reference to the helper object driving the printout.
   #     resource - Identifies the resource about to be printed.
   #
   #   This is done as follows:
   #    POSSIBLE_RESOURCES has the list of possible resources.
   #    EXTRASPACE         has the list of extra space values.
   #    EXTRASPACE_UNITS   is the set of resources for which the units are
   #                       mm. All others are 'in'.
   #    
   #    The resource is found in the POSSIBLE_RESOURCES to get the index
   #    of the EXTRASPACE value.
   #
   #   In order to speed this up for lengthy printouts, the first time,
   #   POSSIBLE_RESOURCES is turned into a look up hash and
   #   EXTRASPACE is turned into an array.
   #
   
   
   my %possible_resources;
   my %extraspace_mm;
   my @extraspace;
   my $skips_loaded       = 0;
   
   #  Function to load the skips hash and array
   
   sub load_skips {
   
       my ($helper)  = @_;
   
       #  If this is the first time, unrap the resources and extra spaces:
   
       if (!$skips_loaded) {
    @extraspace = (split(/\|\|\|/, $helper->{'VARS'}->{'EXTRASPACE'}));
    my @resource_list = (split(/\|\|\|/, $helper->{'VARS'}->{'POSSIBLE_RESOURCES'}));
    my $i = 0;
    foreach my $resource (@resource_list) {
       $possible_resources{$resource} = $i;
       $i++;
    }
    foreach my $mm_resource (split(/\|\|\|/, $helper->{'VARS'}->{'EXTRASPACE_UNITS'})) {
       $extraspace_mm{$mm_resource} = 1;
    }
    $skips_loaded = 1;
       }
   }
   
   sub get_extra_vspaces {
       my ($helper, $resource) = @_;
   
       &load_skips($helper);
   
       #  Lookup the resource in the possible resources hash.. that is the index
       # into the extraspace array that gives us either an empty string or
       # the number of mm to skip:
   
       my $index = $possible_resources{$resource};
       my $skip  = $extraspace[$index];
   
       my $result = '';
       if ($skip ne '') {
    my $units = 'in';
    if (defined($extraspace_mm{$resource})) {
       $units = 'mm';
    }
    $result = '\vskip '.$skip.' '.$units;
       }
   
   
       return $result;
   
   
   }
   
   #
   #  The resource chooser part of the helper needs more than just
   #  the value of the extraspaces var to recover the value into a text
   #  field option.  This sub produces the required format for the saved var:
   #  specifically 
   #    ||| separated fields of the form resourcename=value
   #
   #  Parameters:
   #    $helper     - Refers to the helper we are configuring
   #  Implicit input:
   #     $helper->{'VARS'}->{'EXTRASPACE'}  - the spaces helper var has the text field
   #                                          value.
   #     $helper->{'VARS'}->{'EXTRASPACE_UNITS'} - units for the skips (checkboxes).
   #     $helper->{'VARS'}->{'POSSIBLE_RESOURCES'}  - has the list of resources. |||
   #                                          separated of course.
   #  Implicit outputs:
   #     $env{'form.extraspace'}
   #     $env{'form.extraspace_units'}
   #
   sub set_form_extraspace {
       my ($helper) = @_;
   
       # the most convenient way to do this is to drive from the skips arrays/hash.
       # may not be the fastest, but this is once per print request so it's not so
       # speed critical:
   
       &load_skips($helper);
   
       my $result = '';
   
       foreach my $resource (keys(%possible_resources)) {
    my $vskip = $extraspace[$possible_resources{$resource}];
    $result  .= $resource .'=' . $vskip . '|||';
       }
   
       $env{'form.extraspace'}  = $result;
       $env{'form.extraspace_units'} = $helper->{'VARS'}->{'EXTRASPACE_UNITS'};
       return $result;
       
   }
   
 #  Output a sequence (recursively if neeed)  #  Output a sequence (recursively if neeed)
 #  from construction space.  #  from construction space.
Line 1698  sub get_page_breaks  { Line 2486  sub get_page_breaks  {
 #  #
 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 1724  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 1768  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 1799  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 1853  ENDPART Line 2670  ENDPART
     # indexed by symb and contains 1's for each break.      # indexed by symb and contains 1's for each break.
   
     $env{'form.pagebreaks'}  = $helper->{'VARS'}->{'FINISHPAGE'};      $env{'form.pagebreaks'}  = $helper->{'VARS'}->{'FINISHPAGE'};
     $env{'form.lastprinttype'} = $helper->{'VARS'}->{'PRINT_TYPE'};       &set_form_extraspace($helper);
       $env{'form.lastprinttype'} = $print_type; 
     &Apache::loncommon::store_course_settings('print',      &Apache::loncommon::store_course_settings('print',
       {'pagebreaks'    => 'scalar',        {'pagebreaks'    => 'scalar',
          'extraspace'    => 'scalar',
          'extraspace_units' => 'scalar',
        'lastprinttype' => 'scalar'});         'lastprinttype' => 'scalar'});
   
     my %page_breaks  = &get_page_breaks($helper);      my %page_breaks  = &get_page_breaks($helper);
   
     my $format_from_helper = $helper->{'VARS'}->{'FORMAT'};      my $format_from_helper = $helper->{'VARS'}->{'FORMAT'};
Line 1902  ENDPART Line 2721  ENDPART
  &Apache::lonnet::delenv('construct.style');   &Apache::lonnet::delenv('construct.style');
     }      }
   
       if ($print_type eq 'current_document') {
     if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') {  
       #-- single document - problem, page, html, xml, ...        #-- single document - problem, page, html, xml, ...
  my ($currentURL,$cleanURL);   my ($currentURL,$cleanURL);
   
Line 1914  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 1958  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 1979  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 2014  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_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});  
     $result .= &print_construction_sequence($currentURL, $helper, %form,      $result .= &print_construction_sequence($currentURL, $helper, %form,
     $LaTeXwidth);      $LaTeXwidth);
     $result .= '\end{document}';        $result .= '\end{document}';  
Line 2030  ENDPART Line 2844  ENDPART
  $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};   $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
  if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;}   if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;}
  $resources_printed .= $currentURL.':';   $resources_printed .= $currentURL.':';
  my $texversion=&ssi_with_retries($currentURL, $ssi_retry_count, %form);   my $texversion = &ssi_with_retries($currentURL, $ssi_retry_count, %form);
  if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {   if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
     my $annotation = &annotate($currentURL);      my $annotation = &annotate($currentURL);
     $texversion    =~ s/(\\end{document})/$annotation$1/;      $texversion    =~ s/(\\end{document})/$annotation$1/;
Line 2063  ENDPART Line 2877  ENDPART
   
                 
  } else {   } else {
     &Apache::lonnet::logthis("Unsupported type handler");  
     $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'))
  {   {
     &Apache::lonnet::logthis("Selectionmade => 3");  
     $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 2124  ENDPART Line 2938  ENDPART
     $result.="\\newpage\n";      $result.="\\newpage\n";
  }   }
     }      }
     my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]);      $result .= &get_extra_vspaces($helper, $master_seq[$i]);
       my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]);
     $urlp=&Apache::lonnet::clutter($urlp);      $urlp=&Apache::lonnet::clutter($urlp);
     $form{'symb'}=$master_seq[$i];      $form{'symb'}=$master_seq[$i];
   
     &Apache::lonnet::logthis("Element $i Sequence $sequence Middle $middle_thingy URLP $urlp");  
     my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem      my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem
   
     if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;}      if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;}
Line 2136  ENDPART Line 2950  ENDPART
     my $texversion='';      my $texversion='';
     if ($urlp!~m|^/adm/|      if ($urlp!~m|^/adm/|
  && $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {   && $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
  &Apache::lonnet::logthis("Problem");  
  $resources_printed .= $urlp.':';   $resources_printed .= $urlp.':';
  &Apache::lonxml::remember_problem_counter();   &Apache::lonxml::remember_problem_counter();
  &Apache::lonnet::logthis("Fetching tex for $urlp");   if ($flag_latex_header_remove eq 'NO') {
  my $debug = Dumper(%form);      $texversion.=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});  # RF
  &Apache::lonnet::logthis("Form: $debug");                      unless (($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only') ||
                               (($i==0) &&
                                (($urlp=~/\.page$/) ||
                                 ($print_type eq 'map_problems_in_page') ||
                                 ($print_type eq 'map_resources_in_page')))) {
                           $flag_latex_header_remove = 'YES';
                       }
    }
  $texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form);   $texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form);
  &Apache::lonnet::logthis("texversion so far: $texversion");  
  if ($urlp=~/\.page$/) {   if ($urlp=~/\.page$/) {
     &Apache::lonnet::logthis("Special page actions");  
     ($texversion,my $number_of_columns_page) = &page_cleanup($texversion);      ($texversion,my $number_of_columns_page) = &page_cleanup($texversion);
     if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;}       if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;} 
     $texversion =~ s/\\end{document}\d*/\\end{document}/;      $texversion =~ s/\\end{document}\d*/\\end{document}/;
     $flag_page_in_sequence = 'YES';      $flag_page_in_sequence = 'YES';
  }    }
   
  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')) {
Line 2163  ENDPART Line 2980  ENDPART
   
     &Apache::lonxml::restore_problem_counter();      &Apache::lonxml::restore_problem_counter();
     my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);      my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
                       if ($urlp =~ /\.page$/) {
                           $answer =~ s/\\end{document}(\d*)$//;
                       }
     if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {      if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
  $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;                          if ($urlp =~ /\.page$/) {
                               my @probs = split(/\\keephidden{ENDOFPROBLEM}/,$texversion);
                               my $lastprob = pop(@probs);
                               $texversion = join('\keephidden{ENDOFPROBLEM}',@probs).
                               $answer.'\keephidden{ENDOFPROBLEM}'.$lastprob;
                           } else {
                               $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
                           }
     } else {      } else {
  if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) {   if ($urlp=~/$LONCAPA::assess_page_re/) {
     &Apache::lonnet::logthis("problem printing");  
     $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});      $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
     $texversion =~ s/\\begin{document}//;  #    $texversion =~ s/\\begin{document}//; # FIXME
     my $title = &Apache::lonnet::gettitle($master_seq[$i]);      my $title = &Apache::lonnet::gettitle($master_seq[$i]);
     $title = &Apache::lonxml::latex_special_symbols($title);      $title = &Apache::lonxml::latex_special_symbols($title);
     my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';      my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
Line 2190  ENDPART Line 3015  ENDPART
  }   }
   
  if ($flag_latex_header_remove ne 'NO') {   if ($flag_latex_header_remove ne 'NO') {
     &Apache::lonnet::logthis("Removing header/footer 1");  
     $texversion = &latex_header_footer_remove($texversion);      $texversion = &latex_header_footer_remove($texversion);
     &Apache::lonnet::logthis("With h/f removed we have: $texversion");  
  } else {   } else {
     $texversion =~ s/\\end{document}//;      $texversion =~ s/\\end{document}//;
  }   }
Line 2208  ENDPART Line 3031  ENDPART
   $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 2216  ENDPART Line 3038  ENDPART
     }      }
  }   }
  $result .= $texversion;   $result .= $texversion;
  &Apache::lonnet::logthis("About to set rem header true with $result");  
  $flag_latex_header_remove = 'YES';      $flag_latex_header_remove = 'YES';   
     } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {       } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { 
  $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};   $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
  if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;}   if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;}
  $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'}->{'PRINT_ANNOTATIONS'} eq 'yes') {   if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
     my $annotation = &annotate($urlp);      my $annotation = &annotate($urlp);
     $texversion =~ s/(\\end{document)/$annotation$1/;      $texversion =~ s/(\\end{document)/$annotation$1/;
  }   }
   
  if ($flag_latex_header_remove ne 'NO') {   if ($flag_latex_header_remove ne 'NO') {
     &Apache::lonnet::logthis("Removing header & footer 2");  
     $texversion = &latex_header_footer_remove($texversion);      $texversion = &latex_header_footer_remove($texversion);
  } else {   } else {
     $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/;      $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/;
Line 2240  ENDPART Line 3060  ENDPART
  if ($i > 0) {   if ($i > 0) {
     $result .= '\cleardoublepage';      $result .= '\cleardoublepage';
  }   }
  $result .= &include_pdf($urlp);                  my $texfrompdf = &include_pdf($urlp);
                   if ($flag_latex_header_remove ne 'NO') {
                       $texfrompdf = &latex_header_footer_remove($texfrompdf);
                   }
                   $result .= $texfrompdf;
  if ($i != $#master_seq) {   if ($i != $#master_seq) {
     if ($numberofcolumns eq '1') {      if ($numberofcolumns eq '1') {
  $result .= '\newpage';   $result .= '\newpage';
Line 2257  ENDPART Line 3081  ENDPART
  $texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'},   $texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'},
  $master_seq[$i]);   $master_seq[$i]);
  if ($flag_latex_header_remove ne 'NO') {   if ($flag_latex_header_remove ne 'NO') {
     &Apache::lonnet::logthis("Removing header/footer 3");  
     $texversion = &latex_header_footer_remove($texversion);      $texversion = &latex_header_footer_remove($texversion);
  } else {   } else {
     $texversion =~ s/\\end{document}//;      $texversion =~ s/\\end{document}//;
  }   }
  $result .= $texversion;   $result .= $texversion;
  $flag_latex_header_remove = 'YES';      $flag_latex_header_remove = 'YES';   
     }          }
     if (&Apache::loncommon::connection_aborted($r)) {       if (&Apache::loncommon::connection_aborted($r)) { 
  last;    last; 
     }      }
Line 2274  ENDPART Line 3097  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 2304  ENDPART Line 3131  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 2321  ENDPART Line 3150  ENDPART
      $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1;       $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1;
  }   }
  my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};   my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
  &Apache::lonnet::logthis("RESOURCES: ". $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
   
Line 2337  ENDPART Line 3171  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 2358  ENDPART Line 3191  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, undef, 1);
      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 .= ":";
      $print_array[$i].=$output;       $print_array[$i].=$output;
      $student_names[$i].=$person.':'.$fullname.'_END_';       $student_names[$i].=$person.':'.$fullname.'_END_';
      &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname);  #     &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname);
        &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,'last student');
      $flag_latex_header_remove = 'YES';       $flag_latex_header_remove = 'YES';
      if (&Apache::loncommon::connection_aborted($r)) { last; }       if (&Apache::loncommon::connection_aborted($r)) { last; }
  }   }
  &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 'resources_for_anon')  ) {         ($print_type eq 'problems_for_anon_page') ||
         ($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 2381  ENDPART Line 3218  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 2435  ENDPART Line 3291  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 2451  ENDPART Line 3308  ENDPART
      } else {       } else {
  $moreenv{'CODE'}=&num_to_letters($code);   $moreenv{'CODE'}=&num_to_letters($code);
      }       }
                my $actual_seq = \@master_seq;
                if ($randomorder || $randompick) {
                    $env{'form.CODE'} = $moreenv{'CODE'};
                    $actual_seq = master_seq_to_person_seq($map, \@master_seq,
                                                           undef,
                                                           $moreenv{'CODE'}, 1);
                    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 2465  ENDPART Line 3330  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 2484  ENDPART Line 3349  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 2509  ENDPART Line 3370  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') {
     &Apache::lonnet::logthis("Removing header/footer: 4");  
     $texversion = &latex_header_footer_remove($texversion);      $texversion = &latex_header_footer_remove($texversion);
  } else {   } else {
     $texversion =~ s/\\end{document}//;      $texversion =~ s/\\end{document}//;
Line 2548  ENDPART Line 3405  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 2565  ENDPART Line 3428  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 2578  ENDPART Line 3436  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 2705  sub print_resources { Line 3568  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 2729  sub print_resources { Line 3606  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.
     #      #
     &Apache::lonnet::logthis("In print_resources");  
       my $syllabus_first = 0;
       my $current_assignment = "";
       my $assignment;
       my $courseidinfo = &get_course();
   
     foreach my $curresline (@{$master_seq})  {      foreach my $curresline (@{$master_seq})  {
  &Apache::lonnet::logthis("Res: $curresline");  
  if (defined $page_breaks{$curresline}) {   if (defined $page_breaks{$curresline}) {
     if($i != 0) {      if($i != 0) {
  $current_output.= "\\newpage\n";   $current_output.= "\\newpage\n";
     }      }
  }   }
    $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)$/)) ) {         ($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 2750  sub print_resources { Line 3637  sub print_resources {
     &Apache::lonxml::remember_problem_counter();          &Apache::lonxml::remember_problem_counter();    
   
     my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);      my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
     &Apache::lonnet::logthis("student view: $rendered");                      if ($res_url =~ /\.page$/) {
                           if ($remove_latex_header eq 'NO') {
                               if (!($rendered =~ /\\begin\{document\}/)) {
                                   $rendered = &print_latex_header().$rendered;
                               }
                           }
   ;
                           if ($remove_latex_header eq 'YES') {
                               $rendered = &latex_header_footer_remove($rendered);
                           } else {
                               $rendered =~ s/\\end{document}\d*//;
                           }
                       }
     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')) {
  #   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 2768  sub print_resources { Line 3669  sub print_resources {
   
           
     my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});      my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
     $header =~ s/\\begin{document}//;     #<<<<<                              unless ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only') {
                                   $header =~ s/\\begin{document}//;     #<<<<<
                               }
     my $title = &Apache::lonnet::gettitle($curresline);      my $title = &Apache::lonnet::gettitle($curresline);
     $title = &Apache::lonxml::latex_special_symbols($title);      $title = &Apache::lonxml::latex_special_symbols($title);
     my $body   ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';      my $body   ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
Line 2778  sub print_resources { Line 3681  sub print_resources {
     $rendered = $header.$body;      $rendered = $header.$body;
  }   }
     }      }
     &Apache::lonnet::logthis("After preprending header: $rendered");  
     if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {      if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
  my $url = &Apache::lonnet::clutter($res_url);   my $url = &Apache::lonnet::clutter($res_url);
  my $annotation = &annotate($url);   my $annotation = &annotate($url);
  $rendered =~  s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;   $rendered =~  s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
     }      }
       my $junk;
     if ($remove_latex_header eq 'YES') {      if ($remove_latex_header eq 'YES') {
  &Apache::lonnet::logthis("Removing header/footer: 5");  
  $rendered = &latex_header_footer_remove($rendered);   $rendered = &latex_header_footer_remove($rendered);
     } else {      } else {
  $rendered =~ s/\\end{document}//;   $rendered =~ s/\\end{document}//;
     }      }
     $current_output .= $rendered;          $current_output .= $rendered;    
  } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {   } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
       if ($i == 1) {
    $syllabus_first = 1;
       }
     $printed .= $curresline.':';      $printed .= $curresline.':';
     my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);      my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
     if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {      if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
Line 2800  sub print_resources { Line 3705  sub print_resources {
  $annotation    =~ s/(\\end{document})/$annotation$1/;   $annotation    =~ s/(\\end{document})/$annotation$1/;
     }      }
     if ($remove_latex_header eq 'YES') {      if ($remove_latex_header eq 'YES') {
  &Apache::lonnet::logthis("Removing header/footer: 6");  
  $rendered = &latex_header_footer_remove($rendered);   $rendered = &latex_header_footer_remove($rendered);
     } else {      } else {
  $rendered =~ s/\\end{document}//;   $rendered =~ s/\\end{document}//;
Line 2810  sub print_resources { Line 3714  sub print_resources {
     my $url = &Apache::lonnet::clutter($res_url);      my $url = &Apache::lonnet::clutter($res_url);
     my $rendered  = &include_pdf($url);      my $rendered  = &include_pdf($url);
     if ($remove_latex_header ne 'NO') {      if ($remove_latex_header ne 'NO') {
  &Apache::lonnet::logthis("Removing header/footer: 7");  
  $rendered = &latex_header_footer_remove($rendered);   $rendered = &latex_header_footer_remove($rendered);
     }      }
     $current_output .= $rendered;      $current_output .= $rendered;
  } else {   } else {
     my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);      my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
     if ($remove_latex_header ne 'NO') {      if ($remove_latex_header ne 'NO') {
  &Apache::lonnet::logthis("Removing header/footer: 8");  
  $rendered = &latex_header_footer_remove($rendered);   $rendered = &latex_header_footer_remove($rendered);
     } else {      } else {
  $rendered =~ s/\\end{document}//;   $rendered =~ s/\\end{document}//;
Line 2826  sub print_resources { Line 3728  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, $usersection);
       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);
    }
       }
   
     my $courseidinfo = &get_course();      if ($syllabus_first) {
     my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');          $current_output =~ s/\\\\ Last updated:/Last updated:/
     my $header_line =      }
  &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},      if (0) {
     $currentassignment, $courseidinfo, $fullname, $usersection);   my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
     my $header_start = ($columns_in_format == 1) ? '\lhead'   my $header_line =
                                          : '\fancyhead[LO]';      &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
     $header_line = $header_start.'{'.$header_line.'}';   $currentassignment, $courseidinfo, $fullname, $usersection);
    my $header_start = ($columns_in_format == 1) ? '\lhead'
       : '\fancyhead[LO]';
    $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 2857  sub print_resources { Line 3796  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 2888  sub handler { Line 3859  sub handler {
   
     &output_data($r,$helper,\%parmhash);      &output_data($r,$helper,\%parmhash);
     return OK;      return OK;
 }   }
   
 use Apache::lonhelper;  use Apache::lonhelper;
   
Line 2913  sub init_perm { Line 3884  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 2928  sub get_randomly_ordered_warning { Line 3904  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 2984  sub printHelper { Line 3955  sub printHelper {
     $helper->declareVar('PRINT_TYPE');      $helper->declareVar('PRINT_TYPE');
     $helper->declareVar("showallfoils");      $helper->declareVar("showallfoils");
     $helper->declareVar("STUDENTS");      $helper->declareVar("STUDENTS");
       $helper->declareVar("EXTRASPACE");
   
         
   
   
     #  The page breaks can get loaded initially from the course environment:      #  The page breaks and extra spaces
       #  can get loaded initially from the course environment:
     # But we only do this in the initial state so that they are allowed to change.      # But we only do this in the initial state so that they are allowed to change.
     #      #
   
     # $helper->{VARS}->{FINISHPAGE} = '';  
           
     &Apache::loncommon::restore_course_settings('print',      &Apache::loncommon::restore_course_settings('print',
  {'pagebreaks'  => 'scalar',   {'pagebreaks'  => 'scalar',
    'extraspace'  => 'scalar',
    'extraspace_units' => 'scalar',
          'lastprinttype' => 'scalar'});           'lastprinttype' => 'scalar'});
           
     # This will persistently load in the data we want from the      # This will persistently load in the data we want from the
Line 3006  sub printHelper { Line 3979  sub printHelper {
  if (!defined ($env{"form.CURRENT_STATE"})) {   if (!defined ($env{"form.CURRENT_STATE"})) {
           
     $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};      $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
       $helper->{VARS}->{EXTRASPACE} = $env{'form.extraspace'};
       $helper->{VARS}->{EXTRASPACE_UNITS} = $env{'form.extraspace_units'};
  } else {   } else {
     my $state = $env{"form.CURRENT_STATE"};      my $state = $env{"form.CURRENT_STATE"};
     if ($state eq "START") {      if ($state eq "START") {
  $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};   $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
    $helper->{VARS}->{EXTRASPACE} = $env{'form.extraspace'};
    $helper->{VARS}->{EXTRASPACE_UNITS} = $env{'form.extraspace_units'};
   
     }      }
  }   }
   
     }      }
   
     # 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 3053  sub printHelper { Line 4031  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 3067  sub printHelper { Line 4053  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.
     &Apache::lonnet::logthis("Resource url $url");  
  }   }
  $url = &Apache::lonnet::clutter($url);   $url = &Apache::lonnet::clutter($url);
         if (!$resourceTitle) { # if the resource doesn't have a title, use the filename          if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
Line 3078  sub printHelper { Line 4072  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 3107  sub printHelper { Line 4104  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 3129  sub printHelper { Line 4136  sub printHelper {
     if ($perm{'pav'}) {      if ($perm{'pav'}) {
  $start_new_option =    $start_new_option = 
     "<option text='".&mt('Start new page<br />before selected').      "<option text='".&mt('Start new page<br />before selected').
     "' variable='FINISHPAGE' />";      "' variable='FINISHPAGE' />".
       "<option text='".&mt('Extra space<br />before selected').
       "' variable='EXTRASPACE' type='text' />" .
       "<option " .
       "' variable='POSSIBLE_RESOURCES' type='hidden' />".
       "<option text='".&mt('Space units<br />check for mm').
       "' variable='EXTRASPACE_UNITS' type='checkbox' />"
       ;
       
   
     }      }
   
     # If not construction space user can print the components of a page:      # If not construction space user can print the components of a page:
Line 3140  sub printHelper { Line 4156  sub printHelper {
  my $varspostdata = $helper->{VARS}->{'postdata'};   my $varspostdata = $helper->{VARS}->{'postdata'};
  my $varsassignment = $helper->{VARS}->{'assignment'};   my $varsassignment = $helper->{VARS}->{'assignment'};
  my $page_navmap         = Apache::lonnavmaps::navmap->new();   my $page_navmap         = Apache::lonnavmaps::navmap->new();
  my @page_resources      = $page_navmap->retrieveResources($url);   if (defined($page_navmap)) {
  if(defined($page_resources[0])) {      my @page_resources      = $page_navmap->retrieveResources($url);
  $page_ispage       = $page_resources[0]->is_page();      if(defined($page_resources[0])) {
  $page_title     = $page_resources[0]->title();   $page_ispage       = $page_resources[0]->is_page();
  my $resourcesymb   = $page_resources[0]->symb();   $page_title     = $page_resources[0]->title();
  my ($pagemap, $pageid, $pageurl) = &Apache::lonnet::decode_symb($symb);   my $resourcesymb   = $page_resources[0]->symb();
  if ($page_ispage) {   my ($pagemap, $pageid, $pageurl) = &Apache::lonnet::decode_symb($symb);
     push @{$printChoices},    if ($page_ispage) {
     [&mt('Selected [_1]Problems[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'),       push @{$printChoices}, 
      'map_problems_in_page',       [&mt('Selected [_1]Problems[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'), 
      'CHOOSE_PROBLEMS_PAGE'];       'map_problems_in_page', 
     push @{$printChoices},        'CHOOSE_PROBLEMS_PAGE'];
          [&mt('Selected [_1]Resources[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'),       push @{$printChoices}, 
   'map_resources_in_page',       [&mt('Selected [_1]Resources[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'), 
   'CHOOSE_RESOURCES_PAGE'];       'map_resources_in_page', 
  }       'CHOOSE_RESOURCES_PAGE'];
    }
         my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS_PAGE',          my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS_PAGE',
  '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'",
Line 3181  sub printHelper { Line 4198  sub printHelper {
   
  &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);   &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
   
     }      }
    }
     }      }
   
     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'];
  &Apache::lonnet::logthis("Map url : $map");      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 3279  ALL_PROBLEMS Line 4344  ALL_PROBLEMS
  'problems_for_students_from_page', 'CHOOSE_TGT_STUDENTS_PAGE'];   'problems_for_students_from_page', 'CHOOSE_TGT_STUDENTS_PAGE'];
  push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from page [_3] for [_4]CODEd assignments[_5]',   push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from page [_3] for [_4]CODEd assignments[_5]',
     '<b>', '</b>', '<b><i>'.$page_title.'</i></b>', '<b>', '</b>'),      '<b>', '</b>', '<b><i>'.$page_title.'</i></b>', '<b>', '</b>'),
  'problems_for_anon', 'CHOOSE_ANON1_PAGE'];   'problems_for_anon_page', 'CHOOSE_ANON1_PAGE'];
     }      }
     push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]selected people[_5]',      push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]selected people[_5]',
  '<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'),    '<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 
Line 3290  ALL_PROBLEMS Line 4355  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 3306  ALL_PROBLEMS Line 4371  ALL_PROBLEMS
   'multichoice="1" addstatus="1" closeallpages="1"',    'multichoice="1" addstatus="1" closeallpages="1"',
   'RESOURCES',     'RESOURCES', 
   'PRINT_FORMATTING',    'PRINT_FORMATTING',
   '',    $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 3411  RESOURCE_SELECTOR Line 4459  RESOURCE_SELECTOR
  if ($codechoice eq '') {   if ($codechoice eq '') {
     $codechoice='<choice computer="default">Default</choice>';      $codechoice='<choice computer="default">Default</choice>';
  }   }
         &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1);   my $anon1 = &generate_code_selector($helper, 
   <state name="CHOOSE_ANON1" title="Specify CODEd Assignments">      'CHOOSE_ANON1',
     <nextstate>SELECT_PROBLEMS</nextstate>      'SELECT_PROBLEMS',
     <message><h4>Fill out one of the forms below</h4></message>      $codechoice,
     <message><br /><hr /> <br /></message>      $code_selection,
     <message><h3>Generate new CODEd Assignments</h3></message>      $namechoice) . $resource_selector;
     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>      
     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">      
        <validator>          &Apache::lonxml::xmlparse($r, 'helper',$anon1);
  if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&  
     !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&   my $anon_page = &generate_code_selector($helper,
             !\$helper->{'VARS'}{'SINGLE_CODE'}                    &&   'CHOOSE_ANON1_PAGE',
     !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {   'SELECT_PROBLEMS_PAGE',
     return "You need to specify the number of assignments to print";   $codechoice,
  }   $code_selection,
  return undef;   $namechoice) .
        </validator>   &generate_resource_chooser('SELECT_PROBLEMS_PAGE',
     </string>     'Select Problem(s) to print',
     <message></td></tr><tr><td></message>     "multichoice='1' addstatus='1' closeallpages ='1'",
     <message><b>Names to save the CODEs under for later:</b></message>     'RESOURCES',
     <message></td><td></message>     'PRINT_FORMATTING',
     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />     $url,
     <message></td></tr><tr><td></message>     $isProblem, '',  $symbFilter,
     <message><b>Bubble sheet type:</b></message>     $start_new_option);
     <message></td><td></message>   &Apache::lonxml::xmlparse($r, 'helper', $anon_page);
     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">  
     $codechoice  
     </dropdown>  
     <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>  
     <message></td></tr><tr><td></table></message>  
     <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>  
     <message><tr><td><b>Enter a CODE to print:</b></td><td></message>  
     <string variable="SINGLE_CODE" size="10">  
         <validator>  
    if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&  
       !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&  
       !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {  
       return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},  
       \$helper->{'VARS'}{'CODE_OPTION'});  
    } else {  
        return undef; # Other forces control us.  
    }  
         </validator>  
     </string>  
     <message></td></tr><tr><td></message>  
         $code_selection  
     <message></td></tr></table></message>  
     <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>  
     <message><b>Select saved CODEs:</b></message>  
     <message></td><td></message>  
     <dropdown variable="REUSE_OLD_CODES">  
         $namechoice  
     </dropdown>  
     <message></td></tr></table></message>  
   </state>  
   $resource_selector  
 CHOOSE_ANON1  
   
   
  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 3489  CHOOSE_ANON1 Line 4508  CHOOSE_ANON1
       $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 3531  CHOOSE_STUDENTS1 Line 4533  CHOOSE_STUDENTS1
     <message><br /><hr /> <br /></message>      <message><br /><hr /> <br /></message>
     <message><h3>Generate new CODEd Assignments</h3></message>      <message><h3>Generate new CODEd Assignments</h3></message>
     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>      <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">      <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5"  noproceed="1">
        <validator>         <validator>
  if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&   if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
     !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&      !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
Line 3539  CHOOSE_STUDENTS1 Line 4541  CHOOSE_STUDENTS1
     !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {      !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
     return "You need to specify the number of assignments to print";      return "You need to specify the number of assignments to print";
  }   }
           if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) >= 1)  &&
                (\$helper->{'VARS'}{'SINGLE_CODE'} ne '') ) {
               return 'Specifying number of codes to print and a specific code is not compatible';
           }
  return undef;   return undef;
        </validator>         </validator>
     </string>      </string>
Line 3547  CHOOSE_STUDENTS1 Line 4553  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 3562  CHOOSE_STUDENTS1 Line 4568  CHOOSE_STUDENTS1
       !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {        !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
       return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},        return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
       \$helper->{'VARS'}{'CODE_OPTION'});        \$helper->{'VARS'}{'CODE_OPTION'});
     } elsif (\$helper->{'VARS'}{'SINGLE_CODE'} ne ''){
         return 'Specifying a code name is incompatible specifying number of codes.';
    } else {     } else {
        return undef; # Other forces control us.         return undef; # Other forces control us.
    }     }
Line 3629  CHOOSE_FROM_SUBDIR Line 4637  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 3651  CHOOSE_FROM_ANY_SEQUENCE Line 4659  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} = 
               '<p class="LC_info">'
              .&mt('Printing for current resource is only possible between [_1] and [_2]',
                   $res_printstartdate, $res_printenddate).'</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 3662  CHOOSE_FROM_ANY_SEQUENCE Line 4679  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 3872  FONT_SELECTION Line 4889  FONT_SELECTION
       return "$helper->{VARS}->{'probstatus'}";        return "$helper->{VARS}->{'probstatus'}";
                    </defaultvalue>                     </defaultvalue>
    <choice computer="problem">Homework Problem</choice>     <choice computer="problem">Homework Problem</choice>
    <choice computer="exam">Exam Problem</choice>     <choice computer="exam">Bubblesheet Exam Problem</choice>
    <choice computer="survey">Survey question</choice>     <choice computer="survey">Survey question</choice>
                      ,choice computer="anonsurvey"Anonymous survey question</choice>
  </dropdown>   </dropdown>
 PROBTYPE  PROBTYPE
             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);              &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
Line 3908  PROBTYPE Line 4926  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 4290  sub postprocess { Line 5310  sub postprocess {
     }      }
 }  }
   
   
   
 __END__  __END__
   

Removed from v.1.560.2.5  
changed lines
  Added in v.1.632


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