Annotation of loncom/interface/lonprintout.pm, revision 1.554

1.389     foxr        1: # The LearningOnline Network
1.1       www         2: # Printout
                      3: #
1.554   ! bisitz      4: # $Id: lonprintout.pm,v 1.553 2009/05/06 16:19:34 bisitz Exp $
1.11      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: # http://www.lon-capa.org/
                     26: #
1.3       sakharuk   27: #
1.1       www        28: package Apache::lonprintout;
                     29: 
                     30: use strict;
1.10      albertel   31: use Apache::Constants qw(:common :http);
1.2       sakharuk   32: use Apache::lonxml;
                     33: use Apache::lonnet;
1.54      sakharuk   34: use Apache::loncommon;
1.13      sakharuk   35: use Apache::inputtags;
1.54      sakharuk   36: use Apache::grades;
1.13      sakharuk   37: use Apache::edit;
1.5       sakharuk   38: use Apache::File();
1.68      sakharuk   39: use Apache::lonnavmaps;
1.511     foxr       40: use Apache::admannotations;
1.521     foxr       41: use Apache::lonenc;
1.531     foxr       42: use Apache::entities;
1.550     foxr       43: use Apache::londefdef;
                     44: 
                     45: use File::Basename;
1.531     foxr       46: 
1.515     foxr       47: use HTTP::Response;
1.511     foxr       48: 
1.491     albertel   49: use LONCAPA::map();
1.34      sakharuk   50: use POSIX qw(strftime);
1.255     www        51: use Apache::lonlocal;
1.429     foxr       52: use Carp;
1.439     www        53: use LONCAPA;
1.60      sakharuk   54: 
1.397     albertel   55: my %perm;
1.454     foxr       56: my %parmhash;
1.459     foxr       57: my $resources_printed;
1.454     foxr       58: 
1.515     foxr       59: # Global variables that describe errors in ssi calls detected  by ssi_with_retries.
                     60: #
                     61: 
                     62: my $ssi_error;			# True if there was an ssi error.
                     63: my $ssi_last_error_resource;	# The resource URI that could not be fetched.
                     64: my $ssi_last_error;		# The error text from the server. (e.g. 500 Server timed out).
                     65: 
                     66: #
                     67: #  Our ssi max retry count.
                     68: #
                     69: 
                     70: my $ssi_retry_count = 5;	# Some arbitrary value.
                     71: 
                     72: 
                     73: 
1.498     foxr       74: # Fetch the contents of a resource, uninterpreted.
                     75: # This is used here to fetch a latex file to be included
                     76: # verbatim into the printout<
                     77: # NOTE: Ask Guy if there is a lonnet function similar to this?
                     78: #
                     79: # Parameters:
                     80: #   URL of the file
                     81: #
                     82: sub fetch_raw_resource {
                     83:     my ($url) = @_;
                     84: 
                     85:     my $filename  = &Apache::lonnet::filelocation("", $url);
1.500     foxr       86:     my $contents  = &Apache::lonnet::getfile($filename);
1.498     foxr       87: 
1.500     foxr       88:     if ($contents == -1) {
                     89: 	return "File open failed for $filename";      # This will bomb the print.
1.498     foxr       90:     }
1.500     foxr       91:     return $contents;
1.498     foxr       92: 
                     93:     
                     94: }
                     95: 
1.511     foxr       96: #  Fetch the annotations associated with a URL and 
                     97: #  put a centered 'annotations:' title.
                     98: #  This is all suppressed if the annotations are empty.
                     99: #
                    100: sub annotate {
                    101:     my ($symb) = @_;
                    102: 
                    103:     my $annotation_text = &Apache::admannotations::get_annotation($symb, 1);
                    104: 
                    105: 
                    106:     my $result = "";
                    107: 
                    108:     if (length($annotation_text) > 0) {
                    109: 	$result .= '\\hspace*{\\fill} \\\\[\\baselineskip] \textbf{Annotations:} \\\\ ';
                    110: 	$result .= "\n";
                    111: 	$result .= &Apache::lonxml::latex_special_symbols($annotation_text,"");	# Escape latex.
                    112: 	$result .= "\n\n";
                    113:     }
                    114:     return $result;
                    115: }
                    116: 
1.550     foxr      117: # include_pdf - PDF files are included into the 
                    118: # output as follows:
                    119: #  - The PDF, if necessary, is replicated.
                    120: #  - The PDF is added to the list of files to convert to postscript (along with the images).
                    121: #  - The LaTeX is added to include the final converted postscript in the file as an included
                    122: #    job.  The assumption is that the includedpsheader.ps header will be included.
                    123: #
                    124: # Parameters:
                    125: #   pdf_uri   - URI of the PDF file to include.
                    126: #   
                    127: # Returns:
                    128: #  The LaTeX to include.
                    129: #
                    130: # Assumptions:
                    131: #    The uri is actually a PDF file
                    132: #    The postscript will have the includepsheader.ps included.
                    133: #
                    134: #
                    135: sub include_pdf {
                    136:     my ($pdf_uri) = @_;
                    137: 
                    138:     # Where is the file? If not local we'll need to repcopy it:'
                    139: 
                    140:     my $file = &Apache::lonnet::filelocation('', $pdf_uri);
                    141:     if (! -e $file) {
                    142: 	&Apache::lonnet::repcopy($file);
                    143: 	$file = &Apache::lonnet::filelocation('',$pdf_uri);
                    144:     }
                    145: 
                    146:     #  The file isn ow replicated locally.. or it did not exist in the first place
                    147:     # (unlikely).  If it did exist, add the pdf to the set of files/images that
                    148:     # need tob e converted for this print job:
                    149: 
                    150:     $file =~ s|(.*)/res/|/home/httpd/html/res/|;
                    151: 
                    152:     open(FILE,">>/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat");
                    153:     print FILE ("$file\n");
                    154:     close (FILE);
                    155: 
                    156:     # Construct the special to put out.  To do this we need to get the
                    157:     # resulting filename after conversion.  The file will have the same name
                    158:     # but will be in the user's spool directory with converted images.
                    159: 
                    160:     my $dirname = "/home/httpd/prtspool/$env{'user.name'}/";
                    161:     my ( $base, $path,  $ext) = &fileparse($file, '.pdf');
                    162: #    my $destname = $dirname.'/'.$base.'.eps'; # Not really an eps but easier in printout.pl
                    163:     $base =~ s/ /\_/g;
                    164: 
                    165: 
1.551     foxr      166:     my $output = &print_latex_header();
1.550     foxr      167:     $output    .= '\special{ps: _begin_job_ ('
                    168: 	.$base.'.pdf.eps'.
                    169: 	')run _end_job_}';
                    170: 
                    171:     return $output;
                    172: 
                    173: 
                    174: }
                    175: 
1.515     foxr      176: 
                    177: #
                    178: #   ssi_with_retries - Does the server side include of a resource.
                    179: #                      if the ssi call returns an error we'll retry it up to
                    180: #                      the number of times requested by the caller.
                    181: #                      If we still have a proble, no text is appended to the
                    182: #                      output and we set some global variables.
1.523     raeburn   183: #                      to indicate to the caller an SSI error occurred.  
1.515     foxr      184: #                      All of this is supposed to deal with the issues described
                    185: #                      in LonCAPA BZ 5631 see:
                    186: #                      http://bugs.lon-capa.org/show_bug.cgi?id=5631
                    187: #                      by informing the user that this happened.
                    188: #
                    189: # Parameters:
                    190: #   resource   - The resource to include.  This is passed directly, without
                    191: #                interpretation to lonnet::ssi.
                    192: #   form       - The form hash parameters that guide the interpretation of the resource
                    193: #                
                    194: #   retries    - Number of retries allowed before giving up completely.
                    195: # Returns:
                    196: #   On success, returns the rendered resource identified by the resource parameter.
                    197: # Side Effects:
                    198: #   The following global variables can be set:
1.523     raeburn   199: #    ssi_error                - If an unrecoverable error occurred this becomes true.
1.515     foxr      200: #                               It is up to the caller to initialize this to false
                    201: #                               if desired.
1.523     raeburn   202: #    ssi_last_error_resource  - If an unrecoverable error occurred, this is the value
1.515     foxr      203: #                               of the resource that could not be rendered by the ssi
                    204: #                               call.
                    205: #    ssi_last_error           - The error string fetched from the ssi response
                    206: #                               in the event of an error.
                    207: #
                    208: sub ssi_with_retries {
                    209:     my ($resource, $retries, %form) = @_;
                    210: 
                    211: 
1.516     foxr      212:     my ($content, $response) = &Apache::loncommon::ssi_with_retries($resource, $retries, %form);
                    213:     if (!$response->is_success) {
1.515     foxr      214: 	$ssi_error               = 1;
                    215: 	$ssi_last_error_resource = $resource;
1.516     foxr      216: 	$ssi_last_error          = $response->code . " " . $response->message;
1.528     raeburn   217:         $content='\section*{!!! An error occurred !!!}';	
1.519     foxr      218: 	&Apache::lonnet::logthis("Error in SSI resource: $resource Error: $ssi_last_error");
1.515     foxr      219:     }
1.516     foxr      220: 
                    221:     return $content;
                    222: 
1.515     foxr      223: }
                    224: 
1.524     www       225: sub get_student_view_with_retries {
                    226:     my ($curresline,$retries,$username,$userdomain,$courseid,$target,$moreenv)=@_;
                    227: 
                    228:     my ($content, $response) = &Apache::loncommon::get_student_view_with_retries($curresline,$retries,$username,$userdomain,$courseid,$target,$moreenv);
                    229:     if (!$response->is_success) {
                    230:         $ssi_error               = 1;
1.526     www       231:         $ssi_last_error_resource = $curresline.' for user '.$username.':'.$userdomain;
1.524     www       232:         $ssi_last_error          = $response->code . " " . $response->message;
1.528     raeburn   233:         $content='\section*{!!! An error occurred !!!}';
1.526     www       234:         &Apache::lonnet::logthis("Error in SSI (student view) resource: $curresline Error: $ssi_last_error User: $username:$userdomain");
1.524     www       235:     }
                    236:     return $content;
                    237: 
                    238: }
                    239: 
1.486     foxr      240: #
                    241: #   printf_style_subst  item format_string repl
                    242: #  
                    243: # Does printf style substitution for a format string that
                    244: # can have %[n]item in it.. wherever, %[n]item occurs,
                    245: # rep is substituted in format_string.  Note that
                    246: # [n] is an optional integer length.  If provided,
                    247: # repl is truncated to at most [n] characters prior to 
                    248: # substitution.
                    249: #
                    250: sub printf_style_subst {
                    251:     my ($item, $format_string, $repl) = @_;
1.490     foxr      252:     my $result = "";
                    253:     while ($format_string =~ /(%)(\d*)\Q$item\E/g ) {
1.488     albertel  254: 	my $fmt = $1;
                    255: 	my $size = $2;
1.486     foxr      256: 	my $subst = $repl;
                    257: 	if ($size ne "") {
                    258: 	    $subst = substr($subst, 0, $size);
1.490     foxr      259: 	    
                    260: 	    #  Here's a nice edge case.. supose the end of the
                    261: 	    #  substring is a \.  In that case may have  just
                    262: 	    #  chopped off a TeX escape... in that case, we append
                    263: 	    #   " " for the trailing character, and let the field 
                    264: 	    #  spill over a bit (sigh).
                    265: 	    #  We don't just chop off the last character in order to deal
                    266: 	    #  with one last pathology, and that would be if substr had
                    267: 	    #  trimmed us to e.g. \\\  
                    268: 
                    269: 
                    270: 	    if ($subst =~ /\\$/) {
                    271: 		$subst .= " ";
                    272: 	    }
1.486     foxr      273: 	}
1.490     foxr      274: 	my $item_pos = pos($format_string);
                    275: 	$result .= substr($format_string, 0, $item_pos - length($size) -2) . $subst;
                    276:         $format_string = substr($format_string, pos($format_string));
1.486     foxr      277:     }
1.490     foxr      278: 
                    279:     # Put the residual format string into the result:
                    280: 
                    281:     $result .= $format_string;
                    282: 
                    283:     return $result;
1.486     foxr      284: }
                    285: 
1.454     foxr      286: 
                    287: # Format a header according to a format.  
                    288: # 
                    289: 
                    290: # Substitutions:
                    291: #     %a    - Assignment name.
                    292: #     %c    - Course name.
                    293: #     %n    - Student name.
1.537     foxr      294: #     %s    - The section if it is supplied.
1.454     foxr      295: #
                    296: sub format_page_header {
1.537     foxr      297:     my ($width, $format, $assignment, $course, $student, $section) = @_;
                    298: 
1.454     foxr      299:     
1.486     foxr      300:     $width = &recalcto_mm($width); # Get width in mm.
1.454     foxr      301:     #  Default format?
                    302: 
                    303:     if ($format eq '') {
1.486     foxr      304: 	# For the default format, we may need to truncate
                    305: 	# elements..  To do this we need to get the page width.
                    306: 	# we assume that each character is about 2mm in width.
                    307: 	# (correct for the header text size??).  We ignore
                    308: 	# any formatting (e.g. boldfacing in this).
                    309: 	# 
                    310: 	# - Allow the student/course to be one line.
                    311: 	#   but only truncate the course.
                    312: 	# - Allow the assignment to be 2 lines (wrapped).
                    313: 	#
                    314: 	my $chars_per_line = $width/2; # Character/textline.
1.537     foxr      315: 	
                    316: 
                    317: 
                    318: 	my $name_length    = int($chars_per_line *3 /4);
                    319: 	my $sec_length     = int($chars_per_line / 5);
1.486     foxr      320: 
1.537     foxr      321: 	$format  = "%$name_length".'n';
1.486     foxr      322: 
1.537     foxr      323: 	if ($section) {
                    324: 	    $format .=  ' - Sec: '."%$sec_length".'s';
1.486     foxr      325: 	}
1.489     foxr      326: 
1.537     foxr      327: 	$format .= '\\\\%c \\\\ %a';
                    328:         
1.490     foxr      329: 
1.454     foxr      330:     }
1.537     foxr      331:     # An open question is how to handle long user formatted page headers...
                    332:     # A possible future is to support e.g. %na so that the user can control
                    333:     # the truncation of the elements that can appear in the header.
                    334:     #
                    335:     $format =  &printf_style_subst("a", $format, $assignment);
                    336:     $format =  &printf_style_subst("c", $format, $course);
                    337:     $format =  &printf_style_subst("n", $format, $student);
                    338:     $format =  &printf_style_subst("s", $format, $section);
                    339:     
                    340:     
                    341:     # If the user put %'s in the format string, they  must be escaped
                    342:     # to \% else LaTeX will think they are comments and terminate
                    343:     # the line.. which is bad!!!
                    344:     
1.538     onken     345:     # If the user has role author, $course and $assignment are empty so
                    346:     # there is '\\ \\ ' in the page header. That's cause a error in LaTeX
                    347:     if($format =~ /\\\\\s\\\\\s/) {
                    348:         #TODO find sensible caption for page header
                    349:         my $testPrintout = '\\\\'.&mt('Construction Space').' \\\\'.&mt('Test-Printout ');
                    350:         $format =~ s/\\\\\s\\\\\s/$testPrintout/;
                    351:     }
1.454     foxr      352:     
                    353: 
                    354:     return $format;
                    355:     
                    356: }
1.397     albertel  357: 
1.385     foxr      358: #
                    359: #   Convert a numeric code to letters
                    360: #
                    361: sub num_to_letters {
                    362:     my ($num) = @_;
                    363:     my @nums= split('',$num);
                    364:     my @num_to_let=('A'..'Z');
                    365:     my $word;
                    366:     foreach my $digit (@nums) { $word.=$num_to_let[$digit]; }
                    367:     return $word;
                    368: }
                    369: #   Convert a letter code to numeric.
                    370: #
                    371: sub letters_to_num {
                    372:     my ($letters) = @_;
                    373:     my @letters = split('', uc($letters));
1.490     foxr      374:    my %substitution;
1.385     foxr      375:     my $digit = 0;
                    376:     foreach my $letter ('A'..'J') {
                    377: 	$substitution{$letter} = $digit;
                    378: 	$digit++;
                    379:     }
                    380:     #  The substitution is done as below to preserve leading
                    381:     #  zeroes which are needed to keep the code size exact
                    382:     #
                    383:     my $result ="";
                    384:     foreach my $letter (@letters) {
                    385: 	$result.=$substitution{$letter};
                    386:     }
                    387:     return $result;
                    388: }
                    389: 
1.383     foxr      390: #  Determine if a code is a valid numeric code.  Valid
                    391: #  numeric codes must be comprised entirely of digits and
1.384     albertel  392: #  have a correct number of digits.
1.383     foxr      393: #
                    394: #  Parameters:
                    395: #     value      - proposed code value.
1.384     albertel  396: #     num_digits - Number of digits required.
1.383     foxr      397: #
                    398: sub is_valid_numeric_code {
1.384     albertel  399:     my ($value, $num_digits) = @_;
1.383     foxr      400:     #   Remove leading/trailing whitespace;
1.387     foxr      401:     $value =~ s/^\s*//g;
                    402:     $value =~ s/\s*$//g;
1.383     foxr      403:     
                    404:     #  All digits?
1.387     foxr      405:     if ($value !~ /^[0-9]+$/) {
1.383     foxr      406: 	return "Numeric code $value has invalid characters - must only be digits";
                    407:     }
1.384     albertel  408:     if (length($value) != $num_digits) {
                    409: 	return "Numeric code $value incorrect number of digits (correct = $num_digits)";
                    410:     }
1.385     foxr      411:     return undef;
1.383     foxr      412: }
                    413: #   Determines if a code is a valid alhpa code.  Alpha codes
                    414: #   are ciphers that map  [A-J,a-j] -> 0..9 0..9.
1.384     albertel  415: #   They also have a correct digit count.
1.383     foxr      416: # Parameters:
                    417: #     value          - Proposed code value.
1.384     albertel  418: #     num_letters    - correct number of letters.
1.383     foxr      419: # Note:
                    420: #    leading and trailing whitespace are ignored.
                    421: #
                    422: sub is_valid_alpha_code {
1.384     albertel  423:     my ($value, $num_letters) = @_;
1.383     foxr      424:     
                    425:      # strip leading and trailing spaces.
                    426: 
                    427:     $value =~ s/^\s*//g;
                    428:     $value =~ s/\s*$//g;
                    429: 
                    430:     #  All alphas in the right range?
1.384     albertel  431:     if ($value !~ /^[A-J,a-j]+$/) {
1.383     foxr      432: 	return "Invalid letter code $value must only contain A-J";
                    433:     }
1.384     albertel  434:     if (length($value) != $num_letters) {
                    435: 	return "Letter code $value has incorrect number of letters (correct = $num_letters)";
                    436:     }
1.385     foxr      437:     return undef;
1.383     foxr      438: }
                    439: 
1.382     foxr      440: #   Determine if a code entered by the user in a helper is valid.
                    441: #   valid depends on the code type and the type of code selected.
                    442: #   The type of code selected can either be numeric or 
                    443: #   Alphabetic.  If alphabetic, the code, in fact is a simple
                    444: #   substitution cipher for the actual numeric code: 0->A, 1->B ...
                    445: #   We'll be nice and be case insensitive for alpha codes.
                    446: # Parameters:
                    447: #    code_value    - the value of the code the user typed in.
                    448: #    code_option   - The code type selected from the set in the scantron format
                    449: #                    table.
                    450: # Returns:
                    451: #    undef         - The code is valid.
                    452: #    other         - An error message indicating what's wrong.
                    453: #
                    454: sub is_code_valid {
                    455:     my ($code_value, $code_option) = @_;
1.383     foxr      456:     my ($code_type, $code_length) = ('letter', 6);	# defaults.
1.542     raeburn   457:     my @lines = &Apache::grades::get_scantronformat_file();
                    458:     foreach my $line (@lines) {
1.383     foxr      459: 	my ($name, $type, $length) = (split(/:/, $line))[0,2,4];
                    460: 	if($name eq $code_option) {
                    461: 	    $code_length = $length;
                    462: 	    if($type eq 'number') {
                    463: 		$code_type = 'number';
                    464: 	    }
                    465: 	}
                    466:     }
                    467:     my $valid;
                    468:     if ($code_type eq 'number') {
1.385     foxr      469: 	return &is_valid_numeric_code($code_value, $code_length);
1.383     foxr      470:     } else {
1.385     foxr      471: 	return &is_valid_alpha_code($code_value, $code_length);
1.383     foxr      472:     }
1.382     foxr      473: 
                    474: }
                    475: 
1.341     foxr      476: #   Compare two students by name.  The students are in the form
                    477: #   returned by the helper:
                    478: #      user:domain:section:last,   first:status
                    479: #   This is a helper function for the perl sort built-in  therefore:
                    480: # Implicit Inputs:
                    481: #    $a     - The first element to compare (global)
                    482: #    $b     - The second element to compare (global)
                    483: # Returns:
                    484: #   -1   - $a < $b
                    485: #    0   - $a == $b
                    486: #   +1   - $a > $b
                    487: #   Note that the initial comparison is done on the last names with the
                    488: #   first names only used to break the tie.
                    489: #
                    490: #
                    491: sub compare_names {
                    492:     #  First split the names up into the primary fields.
                    493: 
                    494:     my ($u1, $d1, $s1, $n1, $stat1) = split(/:/, $a);
                    495:     my ($u2, $d2, $s2, $n2, $stat2) = split(/:/, $b);
                    496: 
                    497:     # Now split the last name and first name of each n:
                    498:     #
                    499: 
                    500:     my ($l1,$f1) = split(/,/, $n1);
                    501:     my ($l2,$f2) = split(/,/, $n2);
                    502: 
                    503:     # We don't bother to remove the leading/trailing whitespace from the
                    504:     # firstname, unless the last names compare identical.
                    505: 
                    506:     if($l1 lt $l2) {
                    507: 	return -1;
                    508:     }
                    509:     if($l1 gt $l2) {
                    510: 	return  1;
                    511:     }
                    512: 
                    513:     # Break the tie on the first name, but there are leading (possibly trailing
                    514:     # whitespaces to get rid of first 
                    515:     #
                    516:     $f1 =~ s/^\s+//;		# Remove leading...
                    517:     $f1 =~ s/\s+$//;		# Trailing spaces from first 1...
                    518:     
                    519:     $f2 =~ s/^\s+//;
                    520:     $f2 =~ s/\s+$//;		# And the same for first 2...
                    521: 
                    522:     if($f1 lt $f2) {
                    523: 	return -1;
                    524:     }
                    525:     if($f1 gt $f2) {
                    526: 	return 1;
                    527:     }
                    528:     
                    529:     #  Must be the same name.
                    530: 
                    531:     return 0;
                    532: }
                    533: 
1.71      sakharuk  534: sub latex_header_footer_remove {
                    535:     my $text = shift;
                    536:     $text =~ s/\\end{document}//;
                    537:     $text =~ s/\\documentclass([^&]*)\\begin{document}//;
                    538:     return $text;
                    539: }
1.423     foxr      540: #
                    541: #  If necessary, encapsulate text inside 
                    542: #  a minipage env.
                    543: #  necessity is determined by the problem_split param.
                    544: #
                    545: sub encapsulate_minipage {
                    546:     my ($text) = @_;
1.427     albertel  547:     if (!($env{'form.problem.split'} =~ /yes/i)) {
1.423     foxr      548: 	$text = '\begin{minipage}{\textwidth}'.$text.'\end{minipage}';
                    549:     }
                    550:     return $text;
                    551: }
1.429     foxr      552: #
                    553: #  The NUMBER_TO_PRINT and SPLIT_PDFS
                    554: #  variables interact, this sub looks at these two parameters
                    555: #  and comes up with a final value for NUMBER_TO_PRINT which can be:
                    556: #     all     - if SPLIT_PDFS eq 'all'.
                    557: #     1       - if SPLIT_PDFS eq 'oneper'
                    558: #     section - if SPLIT_PDFS eq 'sections'
                    559: #     <unchanged> - if SPLIT_PDFS eq 'usenumber'
                    560: #
                    561: sub adjust_number_to_print {
                    562:     my $helper = shift;
1.71      sakharuk  563: 
1.429     foxr      564:     my $split_pdf = $helper->{'VARS'}->{'SPLIT_PDFS'};
                    565:     
                    566:     if ($split_pdf eq 'all') {
                    567: 	$helper->{'VARS'}->{'NUMBER_TO_PRINT'} = 'all';
                    568:     } elsif ($split_pdf eq 'oneper') {
                    569: 	$helper->{'VARS'}->{'NUMBER_TO_PRINT'} = 1;
                    570:     } elsif ($split_pdf eq 'sections') {
                    571: 	$helper->{'VARS'}->{'NUMBER_TO_PRINT'} = 'section';
                    572:     } elsif ($split_pdf eq 'usenumber') {
                    573: 	#  Unmodified.
                    574:     } else {
                    575: 	# Error!!!!
1.536     foxr      576: 	
                    577: 	croak "bad SPLIT_PDFS: $split_pdf in lonprintout::adjust_number_to_print";
1.429     foxr      578: 
                    579:     }
                    580: }
1.71      sakharuk  581: 
1.531     foxr      582: 
1.37      sakharuk  583: sub character_chart {
1.531     foxr      584:     my $result = shift;
                    585:     return  &Apache::entities::replace_entities($result);
                    586: }
                    587: 
                    588: sub old_character_chart {
1.37      sakharuk  589:     my $result = shift;	
1.116     sakharuk  590:     $result =~ s/&\#0?0?(7|9);//g;
                    591:     $result =~ s/&\#0?(10|13);//g;
                    592:     $result =~ s/&\#0?32;/ /g;
                    593:     $result =~ s/&\#0?33;/!/g;
                    594:     $result =~ s/&(\#0?34|quot);/\"/g;
                    595:     $result =~ s/&\#0?35;/\\\#/g;
                    596:     $result =~ s/&\#0?36;/\\\$/g;
                    597:     $result =~ s/&\#0?37;/\\%/g; 
                    598:     $result =~ s/&(\#0?38|amp);/\\&/g; 
                    599:     $result =~ s/&\#(0?39|146);/\'/g;
                    600:     $result =~ s/&\#0?40;/(/g;
                    601:     $result =~ s/&\#0?41;/)/g;
                    602:     $result =~ s/&\#0?42;/\*/g;
                    603:     $result =~ s/&\#0?43;/\+/g;
                    604:     $result =~ s/&\#(0?44|130);/,/g;
                    605:     $result =~ s/&\#0?45;/-/g;
                    606:     $result =~ s/&\#0?46;/\./g;
                    607:     $result =~ s/&\#0?47;/\//g;
                    608:     $result =~ s/&\#0?48;/0/g;
                    609:     $result =~ s/&\#0?49;/1/g;
                    610:     $result =~ s/&\#0?50;/2/g;
                    611:     $result =~ s/&\#0?51;/3/g;
                    612:     $result =~ s/&\#0?52;/4/g;
                    613:     $result =~ s/&\#0?53;/5/g;
                    614:     $result =~ s/&\#0?54;/6/g;
                    615:     $result =~ s/&\#0?55;/7/g;
                    616:     $result =~ s/&\#0?56;/8/g;
                    617:     $result =~ s/&\#0?57;/9/g;
1.269     albertel  618:     $result =~ s/&\#0?58;/:/g;
1.116     sakharuk  619:     $result =~ s/&\#0?59;/;/g;
                    620:     $result =~ s/&(\#0?60|lt|\#139);/\$<\$/g;
1.281     sakharuk  621:     $result =~ s/&\#0?61;/\\ensuremath\{=\}/g;
                    622:     $result =~ s/&(\#0?62|gt|\#155);/\\ensuremath\{>\}/g;
1.116     sakharuk  623:     $result =~ s/&\#0?63;/\?/g;
                    624:     $result =~ s/&\#0?65;/A/g;
                    625:     $result =~ s/&\#0?66;/B/g;
                    626:     $result =~ s/&\#0?67;/C/g;
                    627:     $result =~ s/&\#0?68;/D/g;
                    628:     $result =~ s/&\#0?69;/E/g;
                    629:     $result =~ s/&\#0?70;/F/g;
                    630:     $result =~ s/&\#0?71;/G/g;
                    631:     $result =~ s/&\#0?72;/H/g;
                    632:     $result =~ s/&\#0?73;/I/g;
                    633:     $result =~ s/&\#0?74;/J/g;
                    634:     $result =~ s/&\#0?75;/K/g;
                    635:     $result =~ s/&\#0?76;/L/g;
                    636:     $result =~ s/&\#0?77;/M/g;
                    637:     $result =~ s/&\#0?78;/N/g;
                    638:     $result =~ s/&\#0?79;/O/g;
                    639:     $result =~ s/&\#0?80;/P/g;
                    640:     $result =~ s/&\#0?81;/Q/g;
                    641:     $result =~ s/&\#0?82;/R/g;
                    642:     $result =~ s/&\#0?83;/S/g;
                    643:     $result =~ s/&\#0?84;/T/g;
                    644:     $result =~ s/&\#0?85;/U/g;
                    645:     $result =~ s/&\#0?86;/V/g;
                    646:     $result =~ s/&\#0?87;/W/g;
                    647:     $result =~ s/&\#0?88;/X/g;
                    648:     $result =~ s/&\#0?89;/Y/g;
                    649:     $result =~ s/&\#0?90;/Z/g;
                    650:     $result =~ s/&\#0?91;/[/g;
1.281     sakharuk  651:     $result =~ s/&\#0?92;/\\ensuremath\{\\setminus\}/g;
1.116     sakharuk  652:     $result =~ s/&\#0?93;/]/g;
1.281     sakharuk  653:     $result =~ s/&\#(0?94|136);/\\ensuremath\{\\wedge\}/g;
1.116     sakharuk  654:     $result =~ s/&\#(0?95|138|154);/\\underline{\\makebox[2mm]{\\strut}}/g;
                    655:     $result =~ s/&\#(0?96|145);/\`/g;
                    656:     $result =~ s/&\#0?97;/a/g;
                    657:     $result =~ s/&\#0?98;/b/g;
                    658:     $result =~ s/&\#0?99;/c/g;
                    659:     $result =~ s/&\#100;/d/g;
                    660:     $result =~ s/&\#101;/e/g;
                    661:     $result =~ s/&\#102;/f/g;
                    662:     $result =~ s/&\#103;/g/g;
                    663:     $result =~ s/&\#104;/h/g;
                    664:     $result =~ s/&\#105;/i/g;
                    665:     $result =~ s/&\#106;/j/g;
                    666:     $result =~ s/&\#107;/k/g;
                    667:     $result =~ s/&\#108;/l/g;
                    668:     $result =~ s/&\#109;/m/g;
                    669:     $result =~ s/&\#110;/n/g;
                    670:     $result =~ s/&\#111;/o/g;
                    671:     $result =~ s/&\#112;/p/g;
                    672:     $result =~ s/&\#113;/q/g;
                    673:     $result =~ s/&\#114;/r/g;
                    674:     $result =~ s/&\#115;/s/g;
                    675:     $result =~ s/&\#116;/t/g;
                    676:     $result =~ s/&\#117;/u/g;
                    677:     $result =~ s/&\#118;/v/g;
                    678:     $result =~ s/&\#119;/w/g;
                    679:     $result =~ s/&\#120;/x/g;
                    680:     $result =~ s/&\#121;/y/g;
                    681:     $result =~ s/&\#122;/z/g;
                    682:     $result =~ s/&\#123;/\\{/g;
                    683:     $result =~ s/&\#124;/\|/g;
                    684:     $result =~ s/&\#125;/\\}/g;
                    685:     $result =~ s/&\#126;/\~/g;
                    686:     $result =~ s/&\#131;/\\textflorin /g;
                    687:     $result =~ s/&\#132;/\"/g;
1.281     sakharuk  688:     $result =~ s/&\#133;/\\ensuremath\{\\ldots\}/g;
                    689:     $result =~ s/&\#134;/\\ensuremath\{\\dagger\}/g;
                    690:     $result =~ s/&\#135;/\\ensuremath\{\\ddagger\}/g;
1.116     sakharuk  691:     $result =~ s/&\#137;/\\textperthousand /g;
                    692:     $result =~ s/&\#140;/{\\OE}/g;
                    693:     $result =~ s/&\#147;/\`\`/g;
                    694:     $result =~ s/&\#148;/\'\'/g;
1.281     sakharuk  695:     $result =~ s/&\#149;/\\ensuremath\{\\bullet\}/g;
1.494     albertel  696:     $result =~ s/&(\#150|\#8211);/--/g;
1.116     sakharuk  697:     $result =~ s/&\#151;/---/g;
1.281     sakharuk  698:     $result =~ s/&\#152;/\\ensuremath\{\\sim\}/g;
1.116     sakharuk  699:     $result =~ s/&\#153;/\\texttrademark /g;
                    700:     $result =~ s/&\#156;/\\oe/g;
                    701:     $result =~ s/&\#159;/\\\"Y/g;
1.283     albertel  702:     $result =~ s/&(\#160|nbsp);/~/g;
1.116     sakharuk  703:     $result =~ s/&(\#161|iexcl);/!\`/g;
                    704:     $result =~ s/&(\#162|cent);/\\textcent /g;
                    705:     $result =~ s/&(\#163|pound);/\\pounds /g; 
                    706:     $result =~ s/&(\#164|curren);/\\textcurrency /g;
                    707:     $result =~ s/&(\#165|yen);/\\textyen /g;
                    708:     $result =~ s/&(\#166|brvbar);/\\textbrokenbar /g;
                    709:     $result =~ s/&(\#167|sect);/\\textsection /g;
1.530     foxr      710:     $result =~ s/&(\#168|uml);/\\"\{\} /g;
1.116     sakharuk  711:     $result =~ s/&(\#169|copy);/\\copyright /g;
                    712:     $result =~ s/&(\#170|ordf);/\\textordfeminine /g;
1.281     sakharuk  713:     $result =~ s/&(\#172|not);/\\ensuremath\{\\neg\}/g;
1.116     sakharuk  714:     $result =~ s/&(\#173|shy);/ - /g;
                    715:     $result =~ s/&(\#174|reg);/\\textregistered /g;
1.281     sakharuk  716:     $result =~ s/&(\#175|macr);/\\ensuremath\{^{-}\}/g;
                    717:     $result =~ s/&(\#176|deg);/\\ensuremath\{^{\\circ}\}/g;
                    718:     $result =~ s/&(\#177|plusmn);/\\ensuremath\{\\pm\}/g;
                    719:     $result =~ s/&(\#178|sup2);/\\ensuremath\{^2\}/g;
                    720:     $result =~ s/&(\#179|sup3);/\\ensuremath\{^3\}/g;
1.530     foxr      721:     $result =~ s/&(\#180|acute);/\\'\{\} /g;
1.281     sakharuk  722:     $result =~ s/&(\#181|micro);/\\ensuremath\{\\mu\}/g;
1.116     sakharuk  723:     $result =~ s/&(\#182|para);/\\P/g;
1.281     sakharuk  724:     $result =~ s/&(\#183|middot);/\\ensuremath\{\\cdot\}/g;
1.116     sakharuk  725:     $result =~ s/&(\#184|cedil);/\\c{\\strut}/g;
1.281     sakharuk  726:     $result =~ s/&(\#185|sup1);/\\ensuremath\{^1\}/g;
1.116     sakharuk  727:     $result =~ s/&(\#186|ordm);/\\textordmasculine /g;
                    728:     $result =~ s/&(\#188|frac14);/\\textonequarter /g;
                    729:     $result =~ s/&(\#189|frac12);/\\textonehalf /g;
                    730:     $result =~ s/&(\#190|frac34);/\\textthreequarters /g;
                    731:     $result =~ s/&(\#191|iquest);/?\`/g;   
                    732:     $result =~ s/&(\#192|Agrave);/\\\`{A}/g;  
                    733:     $result =~ s/&(\#193|Aacute);/\\\'{A}/g; 
                    734:     $result =~ s/&(\#194|Acirc);/\\^{A}/g;
                    735:     $result =~ s/&(\#195|Atilde);/\\~{A}/g;
                    736:     $result =~ s/&(\#196|Auml);/\\\"{A}/g; 
                    737:     $result =~ s/&(\#197|Aring);/{\\AA}/g;
                    738:     $result =~ s/&(\#198|AElig);/{\\AE}/g;
                    739:     $result =~ s/&(\#199|Ccedil);/\\c{c}/g;
                    740:     $result =~ s/&(\#200|Egrave);/\\\`{E}/g;  
                    741:     $result =~ s/&(\#201|Eacute);/\\\'{E}/g;    
                    742:     $result =~ s/&(\#202|Ecirc);/\\^{E}/g;
                    743:     $result =~ s/&(\#203|Euml);/\\\"{E}/g;
                    744:     $result =~ s/&(\#204|Igrave);/\\\`{I}/g;
                    745:     $result =~ s/&(\#205|Iacute);/\\\'{I}/g;    
                    746:     $result =~ s/&(\#206|Icirc);/\\^{I}/g;
                    747:     $result =~ s/&(\#207|Iuml);/\\\"{I}/g;    
                    748:     $result =~ s/&(\#209|Ntilde);/\\~{N}/g;
                    749:     $result =~ s/&(\#210|Ograve);/\\\`{O}/g;
                    750:     $result =~ s/&(\#211|Oacute);/\\\'{O}/g;
                    751:     $result =~ s/&(\#212|Ocirc);/\\^{O}/g;
                    752:     $result =~ s/&(\#213|Otilde);/\\~{O}/g;
                    753:     $result =~ s/&(\#214|Ouml);/\\\"{O}/g;    
1.281     sakharuk  754:     $result =~ s/&(\#215|times);/\\ensuremath\{\\times\}/g;
1.116     sakharuk  755:     $result =~ s/&(\#216|Oslash);/{\\O}/g;
                    756:     $result =~ s/&(\#217|Ugrave);/\\\`{U}/g;    
                    757:     $result =~ s/&(\#218|Uacute);/\\\'{U}/g;
                    758:     $result =~ s/&(\#219|Ucirc);/\\^{U}/g;
                    759:     $result =~ s/&(\#220|Uuml);/\\\"{U}/g;
                    760:     $result =~ s/&(\#221|Yacute);/\\\'{Y}/g;
1.329     sakharuk  761:     $result =~ s/&(\#223|szlig);/{\\ss}/g;
1.116     sakharuk  762:     $result =~ s/&(\#224|agrave);/\\\`{a}/g;
                    763:     $result =~ s/&(\#225|aacute);/\\\'{a}/g;
                    764:     $result =~ s/&(\#226|acirc);/\\^{a}/g;
                    765:     $result =~ s/&(\#227|atilde);/\\~{a}/g;
                    766:     $result =~ s/&(\#228|auml);/\\\"{a}/g;
                    767:     $result =~ s/&(\#229|aring);/{\\aa}/g;
                    768:     $result =~ s/&(\#230|aelig);/{\\ae}/g;
                    769:     $result =~ s/&(\#231|ccedil);/\\c{c}/g;
                    770:     $result =~ s/&(\#232|egrave);/\\\`{e}/g;
                    771:     $result =~ s/&(\#233|eacute);/\\\'{e}/g;
                    772:     $result =~ s/&(\#234|ecirc);/\\^{e}/g;
                    773:     $result =~ s/&(\#235|euml);/\\\"{e}/g;
                    774:     $result =~ s/&(\#236|igrave);/\\\`{i}/g;
                    775:     $result =~ s/&(\#237|iacute);/\\\'{i}/g;
                    776:     $result =~ s/&(\#238|icirc);/\\^{i}/g;
                    777:     $result =~ s/&(\#239|iuml);/\\\"{i}/g;
1.281     sakharuk  778:     $result =~ s/&(\#240|eth);/\\ensuremath\{\\partial\}/g;
1.116     sakharuk  779:     $result =~ s/&(\#241|ntilde);/\\~{n}/g;
                    780:     $result =~ s/&(\#242|ograve);/\\\`{o}/g;
                    781:     $result =~ s/&(\#243|oacute);/\\\'{o}/g;
                    782:     $result =~ s/&(\#244|ocirc);/\\^{o}/g;
                    783:     $result =~ s/&(\#245|otilde);/\\~{o}/g;
                    784:     $result =~ s/&(\#246|ouml);/\\\"{o}/g;
1.281     sakharuk  785:     $result =~ s/&(\#247|divide);/\\ensuremath\{\\div\}/g;
1.116     sakharuk  786:     $result =~ s/&(\#248|oslash);/{\\o}/g;
                    787:     $result =~ s/&(\#249|ugrave);/\\\`{u}/g; 
                    788:     $result =~ s/&(\#250|uacute);/\\\'{u}/g;
                    789:     $result =~ s/&(\#251|ucirc);/\\^{u}/g;
                    790:     $result =~ s/&(\#252|uuml);/\\\"{u}/g;
                    791:     $result =~ s/&(\#253|yacute);/\\\'{y}/g;
                    792:     $result =~ s/&(\#255|yuml);/\\\"{y}/g;
1.399     albertel  793:     $result =~ s/&\#295;/\\ensuremath\{\\hbar\}/g;
1.281     sakharuk  794:     $result =~ s/&\#952;/\\ensuremath\{\\theta\}/g;
1.117     sakharuk  795: #Greek Alphabet
1.281     sakharuk  796:     $result =~ s/&(alpha|\#945);/\\ensuremath\{\\alpha\}/g;
                    797:     $result =~ s/&(beta|\#946);/\\ensuremath\{\\beta\}/g;
                    798:     $result =~ s/&(gamma|\#947);/\\ensuremath\{\\gamma\}/g;
                    799:     $result =~ s/&(delta|\#948);/\\ensuremath\{\\delta\}/g;
                    800:     $result =~ s/&(epsilon|\#949);/\\ensuremath\{\\epsilon\}/g;
                    801:     $result =~ s/&(zeta|\#950);/\\ensuremath\{\\zeta\}/g;
                    802:     $result =~ s/&(eta|\#951);/\\ensuremath\{\\eta\}/g;
                    803:     $result =~ s/&(theta|\#952);/\\ensuremath\{\\theta\}/g;
                    804:     $result =~ s/&(iota|\#953);/\\ensuremath\{\\iota\}/g;
                    805:     $result =~ s/&(kappa|\#954);/\\ensuremath\{\\kappa\}/g;
                    806:     $result =~ s/&(lambda|\#955);/\\ensuremath\{\\lambda\}/g;
                    807:     $result =~ s/&(mu|\#956);/\\ensuremath\{\\mu\}/g;
                    808:     $result =~ s/&(nu|\#957);/\\ensuremath\{\\nu\}/g;
                    809:     $result =~ s/&(xi|\#958);/\\ensuremath\{\\xi\}/g;
1.199     sakharuk  810:     $result =~ s/&(omicron|\#959);/o/g;
1.281     sakharuk  811:     $result =~ s/&(pi|\#960);/\\ensuremath\{\\pi\}/g;
                    812:     $result =~ s/&(rho|\#961);/\\ensuremath\{\\rho\}/g;
                    813:     $result =~ s/&(sigma|\#963);/\\ensuremath\{\\sigma\}/g;
                    814:     $result =~ s/&(tau|\#964);/\\ensuremath\{\\tau\}/g;
                    815:     $result =~ s/&(upsilon|\#965);/\\ensuremath\{\\upsilon\}/g;
                    816:     $result =~ s/&(phi|\#966);/\\ensuremath\{\\phi\}/g;
                    817:     $result =~ s/&(chi|\#967);/\\ensuremath\{\\chi\}/g;
                    818:     $result =~ s/&(psi|\#968);/\\ensuremath\{\\psi\}/g;
                    819:     $result =~ s/&(omega|\#969);/\\ensuremath\{\\omega\}/g;
                    820:     $result =~ s/&(thetasym|\#977);/\\ensuremath\{\\vartheta\}/g;
                    821:     $result =~ s/&(piv|\#982);/\\ensuremath\{\\varpi\}/g;
1.199     sakharuk  822:     $result =~ s/&(Alpha|\#913);/A/g;
                    823:     $result =~ s/&(Beta|\#914);/B/g;
1.281     sakharuk  824:     $result =~ s/&(Gamma|\#915);/\\ensuremath\{\\Gamma\}/g;
                    825:     $result =~ s/&(Delta|\#916);/\\ensuremath\{\\Delta\}/g;
1.199     sakharuk  826:     $result =~ s/&(Epsilon|\#917);/E/g;
                    827:     $result =~ s/&(Zeta|\#918);/Z/g;
                    828:     $result =~ s/&(Eta|\#919);/H/g;
1.281     sakharuk  829:     $result =~ s/&(Theta|\#920);/\\ensuremath\{\\Theta\}/g;
1.199     sakharuk  830:     $result =~ s/&(Iota|\#921);/I/g;
                    831:     $result =~ s/&(Kappa|\#922);/K/g;
1.281     sakharuk  832:     $result =~ s/&(Lambda|\#923);/\\ensuremath\{\\Lambda\}/g;
1.199     sakharuk  833:     $result =~ s/&(Mu|\#924);/M/g;
                    834:     $result =~ s/&(Nu|\#925);/N/g;
1.281     sakharuk  835:     $result =~ s/&(Xi|\#926);/\\ensuremath\{\\Xi\}/g;
1.199     sakharuk  836:     $result =~ s/&(Omicron|\#927);/O/g;
1.281     sakharuk  837:     $result =~ s/&(Pi|\#928);/\\ensuremath\{\\Pi\}/g;
1.199     sakharuk  838:     $result =~ s/&(Rho|\#929);/P/g;
1.281     sakharuk  839:     $result =~ s/&(Sigma|\#931);/\\ensuremath\{\\Sigma\}/g;
1.199     sakharuk  840:     $result =~ s/&(Tau|\#932);/T/g;
1.281     sakharuk  841:     $result =~ s/&(Upsilon|\#933);/\\ensuremath\{\\Upsilon\}/g;
                    842:     $result =~ s/&(Phi|\#934);/\\ensuremath\{\\Phi\}/g;
1.199     sakharuk  843:     $result =~ s/&(Chi|\#935);/X/g;
1.281     sakharuk  844:     $result =~ s/&(Psi|\#936);/\\ensuremath\{\\Psi\}/g;
                    845:     $result =~ s/&(Omega|\#937);/\\ensuremath\{\\Omega\}/g;
1.199     sakharuk  846: #Arrows (extended HTML 4.01)
1.281     sakharuk  847:     $result =~ s/&(larr|\#8592);/\\ensuremath\{\\leftarrow\}/g;
                    848:     $result =~ s/&(uarr|\#8593);/\\ensuremath\{\\uparrow\}/g;
                    849:     $result =~ s/&(rarr|\#8594);/\\ensuremath\{\\rightarrow\}/g;
                    850:     $result =~ s/&(darr|\#8595);/\\ensuremath\{\\downarrow\}/g;
                    851:     $result =~ s/&(harr|\#8596);/\\ensuremath\{\\leftrightarrow\}/g;
                    852:     $result =~ s/&(lArr|\#8656);/\\ensuremath\{\\Leftarrow\}/g;
                    853:     $result =~ s/&(uArr|\#8657);/\\ensuremath\{\\Uparrow\}/g;
                    854:     $result =~ s/&(rArr|\#8658);/\\ensuremath\{\\Rightarrow\}/g;
                    855:     $result =~ s/&(dArr|\#8659);/\\ensuremath\{\\Downarrow\}/g;
                    856:     $result =~ s/&(hArr|\#8660);/\\ensuremath\{\\Leftrightarrow\}/g;
1.199     sakharuk  857: #Mathematical Operators (extended HTML 4.01)
1.281     sakharuk  858:     $result =~ s/&(forall|\#8704);/\\ensuremath\{\\forall\}/g;
                    859:     $result =~ s/&(part|\#8706);/\\ensuremath\{\\partial\}/g;
                    860:     $result =~ s/&(exist|\#8707);/\\ensuremath\{\\exists\}/g;
                    861:     $result =~ s/&(empty|\#8709);/\\ensuremath\{\\emptyset\}/g;
                    862:     $result =~ s/&(nabla|\#8711);/\\ensuremath\{\\nabla\}/g;
                    863:     $result =~ s/&(isin|\#8712);/\\ensuremath\{\\in\}/g;
                    864:     $result =~ s/&(notin|\#8713);/\\ensuremath\{\\notin\}/g;
                    865:     $result =~ s/&(ni|\#8715);/\\ensuremath\{\\ni\}/g;
                    866:     $result =~ s/&(prod|\#8719);/\\ensuremath\{\\prod\}/g;
                    867:     $result =~ s/&(sum|\#8721);/\\ensuremath\{\\sum\}/g;
                    868:     $result =~ s/&(minus|\#8722);/\\ensuremath\{-\}/g;
1.390     albertel  869:     $result =~ s/–/\\ensuremath\{-\}/g;
1.281     sakharuk  870:     $result =~ s/&(lowast|\#8727);/\\ensuremath\{*\}/g;
                    871:     $result =~ s/&(radic|\#8730);/\\ensuremath\{\\surd\}/g;
                    872:     $result =~ s/&(prop|\#8733);/\\ensuremath\{\\propto\}/g;
                    873:     $result =~ s/&(infin|\#8734);/\\ensuremath\{\\infty\}/g;
                    874:     $result =~ s/&(ang|\#8736);/\\ensuremath\{\\angle\}/g;
                    875:     $result =~ s/&(and|\#8743);/\\ensuremath\{\\wedge\}/g;
                    876:     $result =~ s/&(or|\#8744);/\\ensuremath\{\\vee\}/g;
                    877:     $result =~ s/&(cap|\#8745);/\\ensuremath\{\\cap\}/g;
                    878:     $result =~ s/&(cup|\#8746);/\\ensuremath\{\\cup\}/g;
                    879:     $result =~ s/&(int|\#8747);/\\ensuremath\{\\int\}/g;
                    880:     $result =~ s/&(sim|\#8764);/\\ensuremath\{\\sim\}/g;
                    881:     $result =~ s/&(cong|\#8773);/\\ensuremath\{\\cong\}/g;
                    882:     $result =~ s/&(asymp|\#8776);/\\ensuremath\{\\approx\}/g;
                    883:     $result =~ s/&(ne|\#8800);/\\ensuremath\{\\not=\}/g;
                    884:     $result =~ s/&(equiv|\#8801);/\\ensuremath\{\\equiv\}/g;
                    885:     $result =~ s/&(le|\#8804);/\\ensuremath\{\\leq\}/g;
                    886:     $result =~ s/&(ge|\#8805);/\\ensuremath\{\\geq\}/g;
                    887:     $result =~ s/&(sub|\#8834);/\\ensuremath\{\\subset\}/g;
                    888:     $result =~ s/&(sup|\#8835);/\\ensuremath\{\\supset\}/g;
                    889:     $result =~ s/&(nsub|\#8836);/\\ensuremath\{\\not\\subset\}/g;
                    890:     $result =~ s/&(sube|\#8838);/\\ensuremath\{\\subseteq\}/g;
                    891:     $result =~ s/&(supe|\#8839);/\\ensuremath\{\\supseteq\}/g;
                    892:     $result =~ s/&(oplus|\#8853);/\\ensuremath\{\\oplus\}/g;
                    893:     $result =~ s/&(otimes|\#8855);/\\ensuremath\{\\otimes\}/g;
                    894:     $result =~ s/&(perp|\#8869);/\\ensuremath\{\\perp\}/g;
                    895:     $result =~ s/&(sdot|\#8901);/\\ensuremath\{\\cdot\}/g;
1.199     sakharuk  896: #Geometric Shapes (extended HTML 4.01)
1.281     sakharuk  897:     $result =~ s/&(loz|\#9674);/\\ensuremath\{\\Diamond\}/g;
1.199     sakharuk  898: #Miscellaneous Symbols (extended HTML 4.01)
1.281     sakharuk  899:     $result =~ s/&(spades|\#9824);/\\ensuremath\{\\spadesuit\}/g;
                    900:     $result =~ s/&(clubs|\#9827);/\\ensuremath\{\\clubsuit\}/g;
                    901:     $result =~ s/&(hearts|\#9829);/\\ensuremath\{\\heartsuit\}/g;
                    902:     $result =~ s/&(diams|\#9830);/\\ensuremath\{\\diamondsuit\}/g;
1.495     foxr      903: #   Chemically useful 'things' contributed by Hon Kie (bug 4652).
1.515     foxr      904: 
1.495     foxr      905:     $result =~ s/&\#8636;/\\ensuremath\{\\leftharpoonup\}/g;
                    906:     $result =~ s/&\#8637;/\\ensuremath\{\\leftharpoondown\}/g;
                    907:     $result =~ s/&\#8640;/\\ensuremath\{\\rightharpoonup\}/g;
                    908:     $result =~ s/&\#8641;/\\ensuremath\{\\rightharpoondown\}/g;
                    909:     $result =~ s/&\#8652;/\\ensuremath\{\\rightleftharpoons\}/g;
                    910:     $result =~ s/&\#8605;/\\ensuremath\{\\leadsto\}/g;
                    911:     $result =~ s/&\#8617;/\\ensuremath\{\\hookleftarrow\}/g;
                    912:     $result =~ s/&\#8618;/\\ensuremath\{\\hookrightarrow\}/g;
                    913:     $result =~ s/&\#8614;/\\ensuremath\{\\mapsto\}/g;
                    914:     $result =~ s/&\#8599;/\\ensuremath\{\\nearrow\}/g;
                    915:     $result =~ s/&\#8600;/\\ensuremath\{\\searrow\}/g;
                    916:     $result =~ s/&\#8601;/\\ensuremath\{\\swarrow\}/g;
                    917:     $result =~ s/&\#8598;/\\ensuremath\{\\nwarrow\}/g;
1.513     foxr      918: 
                    919:     # Left/right quotations:
                    920: 
                    921:     $result =~ s/&(ldquo|#8220);/\`\`/g;
                    922:     $result =~ s/&(rdquo|#8221);/\'\'/g;
                    923: 
                    924: 
1.37      sakharuk  925:     return $result;
                    926: }
1.41      sakharuk  927: 
                    928: 
1.327     albertel  929:                   #width, height, oddsidemargin, evensidemargin, topmargin
                    930: my %page_formats=
                    931:     ('letter' => {
                    932: 	 'book' => {
1.493     foxr      933: 	     '1' => [ '7.1 in','9.8 in', '-0.57 in','-0.57 in','0.275 in'],
                    934: 	     '2' => ['3.66 in','9.8 in', '-0.57 in','-0.57 in','0.275 in']
1.327     albertel  935: 	 },
                    936: 	 'album' => {
1.496     foxr      937: 	     '1' => [ '8.8 in', '6.8 in','-0.55 in',  '-0.55 in','0.394 in'],
1.484     albertel  938: 	     '2' => [ '4.8 in', '6.8 in','-0.5 in', '-1.0 in','3.5 in']
1.327     albertel  939: 	 },
                    940:      },
                    941:      'legal' => {
                    942: 	 'book' => {
                    943: 	     '1' => ['7.1 in','13 in',,'-0.57 in','-0.57 in','-0.5 in'],
1.514     foxr      944: 	     '2' => ['3.66 in','13 in','-0.57 in','-0.57 in','-0.5 in']
1.327     albertel  945: 	 },
                    946: 	 'album' => {
1.376     albertel  947: 	     '1' => ['12 in','7.1 in',,'-0.57 in','-0.57 in','-0.5 in'],
                    948:              '2' => ['6.0 in','7.1 in','-1 in','-1 in','5 in']
1.327     albertel  949:           },
                    950:      },
                    951:      'tabloid' => {
                    952: 	 'book' => {
                    953: 	     '1' => ['9.8 in','16 in','-0.57 in','-0.57 in','-0.5 in'],
                    954: 	     '2' => ['4.9 in','16 in','-0.57 in','-0.57 in','-0.5 in']
                    955: 	 },
                    956: 	 'album' => {
1.376     albertel  957: 	     '1' => ['16 in','9.8 in','-0.57 in','-0.57 in','-0.5 in'],
                    958: 	     '2' => ['16 in','4.9 in','-0.57 in','-0.57 in','-0.5 in']
1.327     albertel  959:           },
                    960:      },
                    961:      'executive' => {
                    962: 	 'book' => {
                    963: 	     '1' => ['6.8 in','9 in','-0.57 in','-0.57 in','1.2 in'],
                    964: 	     '2' => ['3.1 in','9 in','-0.57 in','-0.57 in','1.2 in']
                    965: 	 },
                    966: 	 'album' => {
                    967: 	     '1' => [],
                    968: 	     '2' => []
                    969:           },
                    970:      },
                    971:      'a2' => {
                    972: 	 'book' => {
                    973: 	     '1' => [],
                    974: 	     '2' => []
                    975: 	 },
                    976: 	 'album' => {
                    977: 	     '1' => [],
                    978: 	     '2' => []
                    979:           },
                    980:      },
                    981:      'a3' => {
                    982: 	 'book' => {
                    983: 	     '1' => [],
                    984: 	     '2' => []
                    985: 	 },
                    986: 	 'album' => {
                    987: 	     '1' => [],
                    988: 	     '2' => []
                    989:           },
                    990:      },
                    991:      'a4' => {
                    992: 	 'book' => {
1.493     foxr      993: 	     '1' => ['17.6 cm','27.2 cm','-1.397 cm','-2.11 cm','-1.27 cm'],
1.496     foxr      994: 	     '2' => [ '9.1 cm','27.2 cm','-1.397 cm','-2.11 cm','-1.27 cm']
1.327     albertel  995: 	 },
                    996: 	 'album' => {
1.496     foxr      997: 	     '1' => ['21.59 cm','19.558 cm','-1.397cm','-2.11 cm','0 cm'],
1.493     foxr      998: 	     '2' => ['9.91 cm','19.558 cm','-1.397 cm','-2.11 cm','0 cm']
1.327     albertel  999: 	 },
                   1000:      },
                   1001:      'a5' => {
                   1002: 	 'book' => {
                   1003: 	     '1' => [],
                   1004: 	     '2' => []
                   1005: 	 },
                   1006: 	 'album' => {
                   1007: 	     '1' => [],
                   1008: 	     '2' => []
                   1009:           },
                   1010:      },
                   1011:      'a6' => {
                   1012: 	 'book' => {
                   1013: 	     '1' => [],
                   1014: 	     '2' => []
                   1015: 	 },
                   1016: 	 'album' => {
                   1017: 	     '1' => [],
                   1018: 	     '2' => []
                   1019:           },
                   1020:      },
                   1021:      );
                   1022: 
1.177     sakharuk 1023: sub page_format {
1.140     sakharuk 1024: #
1.326     sakharuk 1025: #Supported paper format: "Letter [8 1/2x11 in]",      "Legal [8 1/2x14 in]",
                   1026: #                        "Ledger/Tabloid [11x17 in]", "Executive [7 1/2x10 in]",
                   1027: #                        "A2 [420x594 mm]",           "A3 [297x420 mm]",
                   1028: #                        "A4 [210x297 mm]",           "A5 [148x210 mm]",
                   1029: #                        "A6 [105x148 mm]"
1.140     sakharuk 1030: # 
                   1031:     my ($papersize,$layout,$numberofcolumns) = @_; 
1.327     albertel 1032:     return @{$page_formats{$papersize}->{$layout}->{$numberofcolumns}};
1.140     sakharuk 1033: }
1.76      sakharuk 1034: 
                   1035: 
1.126     albertel 1036: sub get_name {
                   1037:     my ($uname,$udom)=@_;
1.373     albertel 1038:     if (!defined($uname)) { $uname=$env{'user.name'}; }
                   1039:     if (!defined($udom)) { $udom=$env{'user.domain'}; }
1.126     albertel 1040:     my $plainname=&Apache::loncommon::plainname($uname,$udom);
1.213     albertel 1041:     if ($plainname=~/^\s*$/) { $plainname=$uname.'@'.$udom; }
1.453     foxr     1042:    $plainname=&Apache::lonxml::latex_special_symbols($plainname,'header');
1.213     albertel 1043:     return $plainname;
1.126     albertel 1044: }
                   1045: 
1.213     albertel 1046: sub get_course {
                   1047:     my $courseidinfo;
1.373     albertel 1048:     if (defined($env{'request.course.id'})) {
1.439     www      1049: 	$courseidinfo = &Apache::lonxml::latex_special_symbols(&unescape($env{'course.'.$env{'request.course.id'}.'.description'}),'header');
1.537     foxr     1050: 	my $sec = $env{'request.course.sec'};
                   1051: 	    
1.213     albertel 1052:     }
                   1053:     return $courseidinfo;
                   1054: }
1.177     sakharuk 1055: 
1.76      sakharuk 1056: sub page_format_transformation {
1.312     sakharuk 1057:     my ($papersize,$layout,$numberofcolumns,$choice,$text,$assignment,$tableofcontents,$indexlist,$selectionmade) = @_; 
1.202     sakharuk 1058:     my ($textwidth,$textheight,$oddoffset,$evenoffset,$topmargin);
1.454     foxr     1059: 
1.312     sakharuk 1060:     if ($selectionmade eq '4') {
1.502     foxr     1061: 	if ($choice eq 'all_problems') {
                   1062: 	    $assignment='Problems from the Whole Course';
                   1063: 	} else {
                   1064: 	    $assignment='Resources from the Whole Course';
                   1065: 	}
1.312     sakharuk 1066:     } else {
                   1067: 	$assignment=&Apache::lonxml::latex_special_symbols($assignment,'header');
                   1068:     }
1.261     sakharuk 1069:     ($textwidth,$textheight,$oddoffset,$evenoffset,$topmargin) = &page_format($papersize,$layout,$numberofcolumns,$topmargin);
1.454     foxr     1070: 
                   1071: 
1.126     albertel 1072:     my $name = &get_name();
1.213     albertel 1073:     my $courseidinfo = &get_course();
1.455     albertel 1074:     my $header_text  = $parmhash{'print_header_format'};
1.486     foxr     1075:     $header_text     = &format_page_header($textwidth, $header_text, $assignment,
1.455     albertel 1076: 					   $courseidinfo, $name);
1.319     sakharuk 1077:     my $topmargintoinsert = '';
                   1078:     if ($topmargin ne '0') {$topmargintoinsert='\setlength{\topmargin}{'.$topmargin.'}';}
1.325     sakharuk 1079:     my $fancypagestatement='';
                   1080:     if ($numberofcolumns eq '2') {
1.455     albertel 1081: 	$fancypagestatement="\\fancyhead{}\\fancyhead[LO]{$header_text}";
1.325     sakharuk 1082:     } else {
1.455     albertel 1083: 	$fancypagestatement="\\rhead{}\\chead{}\\lhead{$header_text}";
1.325     sakharuk 1084:     }
1.140     sakharuk 1085:     if ($layout eq 'album') {
1.550     foxr     1086: 	    $text =~ s/\\begin{document}/\\setlength{\\oddsidemargin}{$oddoffset}\\setlength{\\evensidemargin}{$evenoffset}$topmargintoinsert\n\\setlength{\\textwidth}{$textwidth}\\setlength{\\textheight}{$textheight}\\setlength{\\textfloatsep}{8pt plus 2\.0pt minus 4\.0pt}\n\\newlength{\\minipagewidth}\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\\usepackage{fancyhdr}\\addtolength{\\headheight}{\\baselineskip}\n\\pagestyle{fancy}$fancypagestatement\\usepackage{booktabs}\\begin{document}\\voffset=-0\.8 cm\\setcounter{page}{1}\n /;
1.140     sakharuk 1087:     } elsif ($layout eq 'book') {
                   1088: 	if ($choice ne 'All class print') { 
1.550     foxr     1089: 	    $text =~ s/\\begin{document}/\\textheight $textheight\\oddsidemargin = $evenoffset\\evensidemargin = $evenoffset $topmargintoinsert\n\\textwidth= $textwidth\\newlength{\\minipagewidth}\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\n\\renewcommand{\\ref}{\\keephidden\}\\usepackage{fancyhdr}\\addtolength{\\headheight}{\\baselineskip}\\pagestyle{fancy}$fancypagestatement\\usepackage{booktabs}\\begin{document}\n\\voffset=-0\.8 cm\\setcounter{page}{1}\n/;
1.140     sakharuk 1090: 	} else {
1.550     foxr     1091: 	    $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 /;
1.319     sakharuk 1092: 	}
1.326     sakharuk 1093: 	if ($papersize eq 'a4') {
1.319     sakharuk 1094: 	    $text =~ s/(\\begin{document})/$1\\special{papersize=210mm,297mm}/;
1.140     sakharuk 1095: 	}
                   1096:     }
1.214     sakharuk 1097:     if ($tableofcontents eq 'yes') {$text=~s/(\\setcounter\{page\}\{1\})/$1 \\tableofcontents\\newpage /;}
                   1098:     if ($indexlist eq 'yes') {
                   1099: 	$text=~s/(\\begin{document})/\\makeindex $1/;
                   1100: 	$text=~s/(\\end{document})/\\strut\\\\\\strut\\printindex $1/;
                   1101:     }
1.140     sakharuk 1102:     return $text;
                   1103: }
                   1104: 
                   1105: 
1.33      sakharuk 1106: sub page_cleanup {
                   1107:     my $result = shift;	
1.65      sakharuk 1108:  
                   1109:     $result =~ m/\\end{document}(\d*)$/;
1.34      sakharuk 1110:     my $number_of_columns = $1;
1.33      sakharuk 1111:     my $insert = '{';
1.34      sakharuk 1112:     for (my $id=1;$id<=$number_of_columns;$id++) { $insert .='l'; }
1.33      sakharuk 1113:     $insert .= '}';
1.65      sakharuk 1114:     $result =~ s/(\\begin{longtable})INSERTTHEHEADOFLONGTABLE\\endfirsthead\\endhead/$1$insert/g;
1.34      sakharuk 1115:     $result =~ s/&\s*REMOVETHEHEADOFLONGTABLE\\\\/\\\\/g;
                   1116:     return $result,$number_of_columns;
1.7       sakharuk 1117: }
1.5       sakharuk 1118: 
1.3       sakharuk 1119: 
1.60      sakharuk 1120: sub details_for_menu {
1.335     albertel 1121:     my ($helper)=@_;
1.373     albertel 1122:     my $postdata=$env{'form.postdata'};
1.335     albertel 1123:     if (!$postdata) { $postdata=$helper->{VARS}{'postdata'}; }
                   1124:     my $name_of_resource = &Apache::lonnet::gettitle($postdata);
                   1125:     my $symbolic = &Apache::lonnet::symbread($postdata);
1.482     albertel 1126:     return if ( $symbolic eq '');
                   1127: 
1.233     www      1128:     my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symbolic);
1.123     albertel 1129:     $map=&Apache::lonnet::clutter($map);
1.269     albertel 1130:     my $name_of_sequence = &Apache::lonnet::gettitle($map);
1.63      albertel 1131:     if ($name_of_sequence =~ /^\s*$/) {
1.123     albertel 1132: 	$map =~ m|([^/]+)$|;
                   1133: 	$name_of_sequence = $1;
1.63      albertel 1134:     }
1.373     albertel 1135:     my $name_of_map = &Apache::lonnet::gettitle($env{'request.course.uri'});
1.63      albertel 1136:     if ($name_of_map =~ /^\s*$/) {
1.373     albertel 1137: 	$env{'request.course.uri'} =~ m|([^/]+)$|;
1.123     albertel 1138: 	$name_of_map = $1;
                   1139:     }
1.335     albertel 1140:     return ($name_of_resource,$name_of_sequence,$name_of_map);
1.76      sakharuk 1141: }
                   1142: 
1.476     albertel 1143: sub copyright_line {
                   1144:     return '\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\vspace*{-2 mm}\newline\noindent{\tiny Printed from LON-CAPA\copyright MSU{\hfill} Licensed under GNU General Public License } ';
                   1145: }
                   1146: my $end_of_student = "\n".'\special{ps:ENDOFSTUDENTSTAMP}'."\n";
1.76      sakharuk 1147: 
                   1148: sub latex_corrections {
1.408     albertel 1149:     my ($number_of_columns,$result,$selectionmade,$answer_mode) = @_;
1.185     sakharuk 1150: #    $result =~ s/\\includegraphics{/\\includegraphics\[width=\\minipagewidth\]{/g;
1.476     albertel 1151:     my $copyright = &copyright_line();
1.408     albertel 1152:     if ($selectionmade eq '1' || $answer_mode eq 'only') {
1.476     albertel 1153: 	$result =~ s/(\\end{document})/\\strut\\vskip 0 mm $copyright $end_of_student $1/;
1.408     albertel 1154:     } else {
1.476     albertel 1155: 	$result =~ s/(\\end{document})/\\strut\\vspace\*{-4 mm}\\newline $copyright $end_of_student $1/;
1.316     sakharuk 1156:     }
1.476     albertel 1157:     $result =~ s/\$number_of_columns/$number_of_columns/g;
1.91      sakharuk 1158:     $result =~ s/(\\end{longtable}\s*)(\\strut\\newline\\noindent\\makebox\[\\textwidth\/$number_of_columns\]\[b\]{\\hrulefill})/$2$1/g;
                   1159:     $result =~ s/(\\end{longtable}\s*)\\strut\\newline/$1/g;
1.76      sakharuk 1160: #-- LaTeX corrections     
                   1161:     my $first_comment = index($result,'<!--',0);
                   1162:     while ($first_comment != -1) {
                   1163: 	my $end_comment = index($result,'-->',$first_comment);
                   1164: 	substr($result,$first_comment,$end_comment-$first_comment+3) = '';
                   1165: 	$first_comment = index($result,'<!--',$first_comment);
                   1166:     }
                   1167:     $result =~ s/^\s+$//gm; #remove empty lines
1.377     albertel 1168:     #removes more than one empty space
                   1169:     $result =~ s|(\s\s+)|($1=~/[\n\r]/)?"\n":" "|ge;
1.76      sakharuk 1170:     $result =~ s/\\\\\s*\\vskip/\\vskip/gm;
                   1171:     $result =~ s/\\\\\s*\\noindent\s*(\\\\)+/\\\\\\noindent /g;
                   1172:     $result =~ s/{\\par }\s*\\\\/\\\\/gm;
1.313     sakharuk 1173:     $result =~ s/\\\\\s+\[/ \[/g;
1.76      sakharuk 1174:     #conversion of html characters to LaTeX equivalents
                   1175:     if ($result =~ m/&(\w+|#\d+);/) {
                   1176: 	$result = &character_chart($result);
                   1177:     }
                   1178:     $result =~ s/(\\end{tabular})\s*\\vskip 0 mm/$1/g;
                   1179:     $result =~ s/(\\begin{enumerate})\s*\\noindent/$1/g;
                   1180:     return $result;
1.60      sakharuk 1181: }
                   1182: 
1.3       sakharuk 1183: 
1.214     sakharuk 1184: sub index_table {
                   1185:     my $currentURL = shift;
                   1186:     my $insex_string='';
                   1187:     $currentURL=~s/\.([^\/+])$/\.$1\.meta/;
                   1188:     $insex_string=&Apache::lonnet::metadata($currentURL,'keywords');
                   1189:     return $insex_string;
                   1190: }
                   1191: 
                   1192: 
1.215     sakharuk 1193: sub IndexCreation {
                   1194:     my ($texversion,$currentURL)=@_;
                   1195:     my @key_words=split(/,/,&index_table($currentURL));
                   1196:     my $chunk='';
                   1197:     my $st=index $texversion,'\addcontentsline{toc}{subsection}{';
                   1198:     if ($st>0) {
                   1199: 	for (my $i=0;$i<3;$i++) {$st=(index $texversion,'}',$st+1);}
                   1200: 	$chunk=substr($texversion,0,$st+1);
                   1201: 	substr($texversion,0,$st+1)=' ';
                   1202:     }
                   1203:     foreach my $key_word (@key_words) {
                   1204: 	if ($key_word=~/\S+/) {
                   1205: 	    $texversion=~s/\b($key_word)\b/$1 \\index{$key_word} /i;
                   1206: 	}
                   1207:     }			
                   1208:     if ($st>0) {substr($texversion,0,1)=$chunk;}
                   1209:     return $texversion;
                   1210: }
                   1211: 
1.242     sakharuk 1212: sub print_latex_header {
                   1213:     my $mode=shift;
1.550     foxr     1214: 
                   1215:     return &Apache::londefdef::latex_header($mode);
1.242     sakharuk 1216: }
                   1217: 
                   1218: sub path_to_problem {
1.328     albertel 1219:     my ($urlp,$colwidth)=@_;
1.404     albertel 1220:     $urlp=&Apache::lonnet::clutter($urlp);
                   1221: 
1.242     sakharuk 1222:     my $newurlp = '';
1.328     albertel 1223:     $colwidth=~s/\s*mm\s*$//;
                   1224: #characters average about 2 mm in width
1.360     albertel 1225:     if (length($urlp)*2 > $colwidth) {
1.404     albertel 1226: 	my @elements = split('/',$urlp);
1.328     albertel 1227: 	my $curlength=0;
                   1228: 	foreach my $element (@elements) {
1.404     albertel 1229: 	    if ($element eq '') { next; }
1.328     albertel 1230: 	    if ($curlength+(length($element)*2) > $colwidth) {
1.404     albertel 1231: 		$newurlp .=  '|\vskip -1 mm \verb|';
                   1232: 		$curlength=length($element)*2;
1.328     albertel 1233: 	    } else {
                   1234: 		$curlength+=length($element)*2;
1.242     sakharuk 1235: 	    }
1.328     albertel 1236: 	    $newurlp.='/'.$element;
1.242     sakharuk 1237: 	}
1.253     sakharuk 1238:     } else {
                   1239: 	$newurlp=$urlp;
1.242     sakharuk 1240:     }
                   1241:     return '{\small\noindent\verb|'.$newurlp.'|\vskip 0 mm}';
                   1242: }
1.215     sakharuk 1243: 
1.275     sakharuk 1244: sub recalcto_mm {
                   1245:     my $textwidth=shift;
                   1246:     my $LaTeXwidth;
1.339     albertel 1247:     if ($textwidth=~/(-?\d+\.?\d*)\s*cm/) {
1.275     sakharuk 1248: 	$LaTeXwidth = $1*10;
1.339     albertel 1249:     } elsif ($textwidth=~/(-?\d+\.?\d*)\s*mm/) {
1.275     sakharuk 1250: 	$LaTeXwidth = $1;
1.339     albertel 1251:     } elsif ($textwidth=~/(-?\d+\.?\d*)\s*in/) {
1.275     sakharuk 1252: 	$LaTeXwidth = $1*25.4;
                   1253:     }
                   1254:     $LaTeXwidth.=' mm';
                   1255:     return $LaTeXwidth;
                   1256: }
                   1257: 
1.285     albertel 1258: sub get_textwidth {
                   1259:     my ($helper,$LaTeXwidth)=@_;
1.286     albertel 1260:     my $textwidth=$LaTeXwidth;
1.285     albertel 1261:     if ($helper->{'VARS'}->{'pagesize.width'}=~/\d+/ &&
                   1262: 	$helper->{'VARS'}->{'pagesize.widthunit'}=~/\w+/) {
1.286     albertel 1263: 	$textwidth=&recalcto_mm($helper->{'VARS'}->{'pagesize.width'}.' '.
                   1264: 				$helper->{'VARS'}->{'pagesize.widthunit'});
1.285     albertel 1265:     }
1.286     albertel 1266:     return $textwidth;
1.285     albertel 1267: }
                   1268: 
1.296     sakharuk 1269: 
                   1270: sub unsupported {
1.414     albertel 1271:     my ($currentURL,$mode,$symb)=@_;
1.307     sakharuk 1272:     if ($mode ne '') {$mode='\\'.$mode}
1.308     sakharuk 1273:     my $result.= &print_latex_header($mode);
1.414     albertel 1274:     if ($currentURL=~m|^(/adm/wrapper/)?ext/|) {
                   1275: 	$currentURL=~s|^(/adm/wrapper/)?ext/|http://|;
                   1276: 	my $title=&Apache::lonnet::gettitle($symb);
                   1277: 	$title = &Apache::lonxml::latex_special_symbols($title);
                   1278: 	$result.=' \strut \\\\ '.$title.' \strut \\\\ '.$currentURL.' ';
1.296     sakharuk 1279:     } else {
                   1280: 	$result.=$currentURL;
                   1281:     }
1.419     albertel 1282:     $result.= '\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill} \end{document}';
1.296     sakharuk 1283:     return $result;
                   1284: }
                   1285: 
                   1286: 
1.363     foxr     1287: #
1.395     www      1288: # List of recently generated print files
                   1289: #
                   1290: sub recently_generated {
                   1291:     my $r=shift;
                   1292:     my $prtspool=$r->dir_config('lonPrtDir');
1.400     albertel 1293:     my $zip_result;
                   1294:     my $pdf_result;
1.395     www      1295:     opendir(DIR,$prtspool);
1.400     albertel 1296: 
                   1297:     my @files = 
                   1298: 	grep(/^$env{'user.name'}_$env{'user.domain'}_printout_(\d+)_.*\.(pdf|zip)$/,readdir(DIR));
1.395     www      1299:     closedir(DIR);
1.400     albertel 1300: 
                   1301:     @files = sort {
                   1302: 	my ($actime) = (stat($prtspool.'/'.$a))[10];
                   1303: 	my ($bctime) = (stat($prtspool.'/'.$b))[10];
                   1304: 	return $bctime <=> $actime;
                   1305:     } (@files);
                   1306: 
                   1307:     foreach my $filename (@files) {
                   1308: 	my ($ext) = ($filename =~ m/(pdf|zip)$/);
                   1309: 	my ($cdev,$cino,$cmode,$cnlink,
                   1310: 	    $cuid,$cgid,$crdev,$csize,
                   1311: 	    $catime,$cmtime,$cctime,
                   1312: 	    $cblksize,$cblocks)=stat($prtspool.'/'.$filename);
1.544     bisitz   1313:         my $ext_text = 'pdf' ? &mt('PDF File'):&mt('Zip File');
                   1314: 	my $result=&Apache::loncommon::start_data_table_row()
                   1315:                   .'<td>'
                   1316:                   .'<a href="/prtspool/'.$filename.'">'.$ext_text.'</a>'
                   1317:                   .'</td>'
                   1318:                   .'<td>'.&Apache::lonlocal::locallocaltime($cctime).'</td>'
                   1319:                   .'<td align="right">'.$csize.'</td>'
                   1320:                   .&Apache::loncommon::end_data_table_row();
1.400     albertel 1321: 	if ($ext eq 'pdf') { $pdf_result .= $result; }
                   1322: 	if ($ext eq 'zip') { $zip_result .= $result; }
                   1323:     }
1.544     bisitz   1324:     if ($zip_result || $pdf_result) {
                   1325:         $r->print('<hr />');
                   1326:     }
1.400     albertel 1327:     if ($zip_result) {
1.544     bisitz   1328: 	$r->print('<h3>'.&mt('Recently generated printout zip files')."</h3>\n"
                   1329:                   .&Apache::loncommon::start_data_table()
                   1330:                   .&Apache::loncommon::start_data_table_header_row()
                   1331:                   .'<th>'.&mt('Download').'</th>'
                   1332:                   .'<th>'.&mt('Creation Date').'</th>'
                   1333:                   .'<th>'.&mt('File Size (Bytes)').'</th>'
                   1334:                   .&Apache::loncommon::end_data_table_header_row()
                   1335:                   .$zip_result
                   1336:                   .&Apache::loncommon::end_data_table()
                   1337:         );
1.400     albertel 1338:     }
                   1339:     if ($pdf_result) {
1.544     bisitz   1340: 	$r->print('<h3>'.&mt('Recently generated printouts')."</h3>\n"
                   1341:                   .&Apache::loncommon::start_data_table()
                   1342:                   .&Apache::loncommon::start_data_table_header_row()
                   1343:                   .'<th>'.&mt('Download').'</th>'
                   1344:                   .'<th>'.&mt('Creation Date').'</th>'
                   1345:                   .'<th>'.&mt('File Size (Bytes)').'</th>'
                   1346:                   .&Apache::loncommon::end_data_table_header_row()
                   1347:                   .$pdf_result
                   1348:                   .&Apache::loncommon::end_data_table()
                   1349:         );
1.396     albertel 1350:     }
1.395     www      1351: }
                   1352: 
                   1353: #
1.363     foxr     1354: #   Retrieve the hash of page breaks.
                   1355: #
                   1356: #  Inputs:
                   1357: #    helper   - reference to helper object.
                   1358: #  Outputs
                   1359: #    A reference to a page break hash.
                   1360: #
                   1361: #
1.418     foxr     1362: #use Data::Dumper;
                   1363: #sub dump_helper_vars {
                   1364: #    my ($helper) = @_;
                   1365: #    my $helpervars = Dumper($helper->{'VARS'});
                   1366: #    &Apache::lonnet::logthis("Dump of helper vars:\n $helpervars");
                   1367: #}
1.363     foxr     1368: 
1.481     albertel 1369: sub get_page_breaks  {
                   1370:     my ($helper) = @_;
                   1371:     my %page_breaks;
                   1372: 
                   1373:     foreach my $break (split /\|\|\|/, $helper->{'VARS'}->{'FINISHPAGE'}) {
                   1374: 	$page_breaks{$break} = 1;
                   1375:     }
                   1376:     return %page_breaks;
                   1377: }
1.363     foxr     1378: 
1.459     foxr     1379: #  Output a sequence (recursively if neeed)
                   1380: #  from construction space.
                   1381: # Parameters:
                   1382: #    url     = URL of the sequence to print.
                   1383: #    helper  - Reference to the helper hash.
                   1384: #    form    - Copy of the format hash.
                   1385: #    LaTeXWidth
                   1386: # Returns:
                   1387: #   Text to add to the printout.
                   1388: #   NOTE if the first element of the outermost sequence
                   1389: #   is itself a sequence, the outermost caller may need to
                   1390: #   prefix the latex with the page headers stuff.
                   1391: #
                   1392: sub print_construction_sequence {
                   1393:     my ($currentURL, $helper, %form, $LaTeXwidth) = @_;
                   1394:     my $result;
                   1395:     my $rndseed=time;
                   1396:     if ($helper->{'VARS'}->{'curseed'}) {
                   1397: 	$rndseed=$helper->{'VARS'}->{'curseed'};
                   1398:     }
1.491     albertel 1399:     my $errtext=&LONCAPA::map::mapread($currentURL);
1.459     foxr     1400:     # 
                   1401:     #  These make this all support recursing for subsequences.
                   1402:     #
1.491     albertel 1403:     my @order    = @LONCAPA::map::order;
                   1404:     my @resources = @LONCAPA::map::resources; 
1.459     foxr     1405:     for (my $member=0;$member<=$#order;$member++) {
                   1406: 	$resources[$order[$member]]=~/^([^:]*):([^:]*):/;
                   1407: 	my $urlp=$2;
                   1408: 	if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/) {
                   1409: 	    my $texversion='';
                   1410: 	    if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') {
                   1411: 		$form{'problem_split'}=$parmhash{'problem_stream_switch'};
                   1412: 		$form{'suppress_tries'}=$parmhash{'suppress_tries'};
                   1413: 		$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
                   1414: 		$form{'rndseed'}=$rndseed;
                   1415: 		$resources_printed .=$urlp.':';
1.515     foxr     1416: 		$texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.459     foxr     1417: 	    }
                   1418: 	    if((($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   1419: 		($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) && 
                   1420: 	       ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page)$/)) {
                   1421: 		#  Don't permanently modify %$form...
                   1422: 		my %answerform = %form;
                   1423: 		$answerform{'grade_target'}='answer';
                   1424: 		$answerform{'answer_output_mode'}='tex';
                   1425: 		$answerform{'rndseed'}=$rndseed;
                   1426: 		$answerform{'problem_split'}=$parmhash{'problem_stream_switch'};
1.481     albertel 1427: 		if ($urlp=~/\/res\//) {$env{'request.state'}='published';}
1.459     foxr     1428: 		$resources_printed .= $urlp.':';
1.515     foxr     1429: 		my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.459     foxr     1430: 		if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   1431: 		    $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
                   1432: 		} else {
                   1433: 		    # If necessary, encapsulate answer in minipage:
                   1434: 		    
                   1435: 		    $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477     albertel 1436: 		    my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
                   1437: 		    $title = &Apache::lonxml::latex_special_symbols($title);
                   1438: 		    my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.459     foxr     1439: 		    $body.=&path_to_problem($urlp,$LaTeXwidth);
                   1440: 		    $body.='\vskip 1 mm '.$answer.'\end{document}';
                   1441: 		    $body = &encapsulate_minipage($body);
                   1442: 		    $texversion.=$body;
                   1443: 		}
                   1444: 	    }
                   1445: 	    $texversion = &latex_header_footer_remove($texversion);
                   1446: 
                   1447: 	    if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
                   1448: 		$texversion=&IndexCreation($texversion,$urlp);
                   1449: 	    }
                   1450: 	    if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
                   1451: 		$texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
                   1452: 	    }
                   1453: 	    $result.=$texversion;
                   1454: 
                   1455: 	} elsif ($urlp=~/\.(sequence|page)$/) {
                   1456: 	    
                   1457: 	    # header:
                   1458: 
                   1459: 	    $result.='\strut\newline\noindent Sequence/page '.$urlp.'\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent ';
                   1460: 
                   1461: 	    # IF sequence, recurse:
                   1462: 	    
                   1463: 	    if ($urlp =~ /\.sequence$/) {
                   1464: 		my $sequence_url = $urlp;
                   1465: 		my $domain       = $env{'user.domain'};	# Constr. space only on local
                   1466: 		my $user         = $env{'user.name'};
                   1467: 
                   1468: 		$sequence_url    =~ s/^\/res\/$domain/\/home/;
                   1469: 		$sequence_url    =~ s/^(\/home\/$user)/$1\/public_html/;
                   1470: #		$sequence_url    =~ s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;
                   1471: 		$result .= &print_construction_sequence($sequence_url, 
                   1472: 							$helper, %form, 
                   1473: 							$LaTeXwidth);
                   1474: 	    }
1.550     foxr     1475: 	}
                   1476: 	elsif ($urlp =~ /\.pdf$/i) {
1.552     foxr     1477: 	    my $texversion;
                   1478: 	    if ($member != 0) {
                   1479: 		$texversion .= '\cleardoublepage';
                   1480: 	    }
                   1481: 
                   1482: 	    $texversion .= &include_pdf($urlp);
                   1483: 	    $texversion = &latex_header_footer_remove($texversion);
                   1484: 	    if ($member != $#order) {
                   1485: 		$texversion .= '\\ \cleardoublepage';
                   1486: 	    }
1.551     foxr     1487: 	    
                   1488: 	    $result .= $texversion;
1.550     foxr     1489: 	}
1.459     foxr     1490:     }
                   1491:     if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\begin{document})/$1 \\fbox\{RANDOM SEED IS $rndseed\} /;}
                   1492:     return $result;
                   1493: }
                   1494: 
1.177     sakharuk 1495: sub output_data {
1.184     sakharuk 1496:     my ($r,$helper,$rparmhash) = @_;
                   1497:     my %parmhash = %$rparmhash;
1.515     foxr     1498:     $ssi_error = 0;		# This will be set nonzero by failing ssi's.
1.459     foxr     1499:     $resources_printed = '';
1.499     foxr     1500:     my $do_postprocessing = 1;
1.433     albertel 1501:     my $js = <<ENDPART;
                   1502: <script type="text/javascript">
1.264     sakharuk 1503:     var editbrowser;
                   1504:     function openbrowser(formname,elementname,only,omit) {
                   1505:         var url = '/res/?';
                   1506:         if (editbrowser == null) {
                   1507:             url += 'launch=1&';
                   1508:         }
                   1509:         url += 'catalogmode=interactive&';
                   1510:         url += 'mode=parmset&';
                   1511:         url += 'form=' + formname + '&';
                   1512:         if (only != null) {
                   1513:             url += 'only=' + only + '&';
                   1514:         } 
                   1515:         if (omit != null) {
                   1516:             url += 'omit=' + omit + '&';
                   1517:         }
                   1518:         url += 'element=' + elementname + '';
                   1519:         var title = 'Browser';
                   1520:         var options = 'scrollbars=1,resizable=1,menubar=0';
                   1521:         options += ',width=700,height=600';
                   1522:         editbrowser = open(url,title,options,'1');
                   1523:         editbrowser.focus();
                   1524:     }
                   1525: </script>
1.140     sakharuk 1526: ENDPART
                   1527: 
1.512     foxr     1528: 
                   1529: 
1.433     albertel 1530:     my $start_page  = &Apache::loncommon::start_page('Preparing Printout',$js);
                   1531:     my $msg = &mt('Please stand by while processing your print request, this may take some time ...');
1.363     foxr     1532: 
1.433     albertel 1533:     $r->print($start_page."\n<p>\n$msg\n</p>\n");
1.372     foxr     1534: 
1.363     foxr     1535:     # fetch the pagebreaks and store them in the course environment
                   1536:     # The page breaks will be pulled into the hash %page_breaks which is
                   1537:     # indexed by symb and contains 1's for each break.
                   1538: 
1.373     albertel 1539:     $env{'form.pagebreaks'}  = $helper->{'VARS'}->{'FINISHPAGE'};
                   1540:     $env{'form.lastprinttype'} = $helper->{'VARS'}->{'PRINT_TYPE'}; 
1.363     foxr     1541:     &Apache::loncommon::store_course_settings('print',
1.366     foxr     1542: 					      {'pagebreaks'    => 'scalar',
                   1543: 					       'lastprinttype' => 'scalar'});
1.363     foxr     1544: 
1.364     albertel 1545:     my %page_breaks  = &get_page_breaks($helper);
1.363     foxr     1546: 
1.140     sakharuk 1547:     my $format_from_helper = $helper->{'VARS'}->{'FORMAT'};
                   1548:     my ($result,$selectionmade) = ('','');
                   1549:     my $number_of_columns = 1; #used only for pages to determine the width of the cell
                   1550:     my @temporary_array=split /\|/,$format_from_helper;
1.539     onken    1551:     my ($laystyle,$numberofcolumns,$papersize,$pdfFormFields)=@temporary_array;
1.140     sakharuk 1552:     if ($laystyle eq 'L') {
                   1553: 	$laystyle='album';
                   1554:     } else {
                   1555: 	$laystyle='book';
                   1556:     }
1.177     sakharuk 1557:     my ($textwidth,$textheight,$oddoffset,$evenoffset) = &page_format($papersize,$laystyle,$numberofcolumns);
1.373     albertel 1558:     my $assignment =  $env{'form.assignment'};
1.275     sakharuk 1559:     my $LaTeXwidth=&recalcto_mm($textwidth); 
1.272     sakharuk 1560:     my @print_array=();
1.274     sakharuk 1561:     my @student_names=();
1.360     albertel 1562: 
1.512     foxr     1563:      
1.360     albertel 1564:     #  Common settings for the %form has:
                   1565:     # In some cases these settings get overriddent by specific cases, but the
                   1566:     # settings are common enough to make it worthwhile factoring them out
                   1567:     # here.
                   1568:     #
                   1569:     my %form;
                   1570:     $form{'grade_target'} = 'tex';
                   1571:     $form{'textwidth'}    = &get_textwidth($helper, $LaTeXwidth);
1.539     onken    1572:     $form{'pdfFormFields'} = $pdfFormFields;
1.372     foxr     1573: 
                   1574:     # If form.showallfoils is set, then request all foils be shown:
                   1575:     # privilege will be enforced both by not allowing the 
                   1576:     # check box selecting this option to be presnt unless it's ok,
                   1577:     # and by lonresponse's priv. check.
                   1578:     # The if is here because lonresponse.pm only cares that
                   1579:     # showallfoils is defined, not what the value is.
                   1580: 
                   1581:     if ($helper->{'VARS'}->{'showallfoils'} eq "1") { 
                   1582: 	$form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'};
                   1583:     }
1.504     albertel 1584:     
                   1585:     if ($helper->{'VARS'}->{'style_file'}=~/\w/) {
1.520     raeburn  1586: 	&Apache::lonnet::appenv({'construct.style' =>
                   1587: 				$helper->{'VARS'}->{'style_file'}});
1.504     albertel 1588:     } elsif ($env{'construct.style'}) {
1.549     raeburn  1589: 	&Apache::lonnet::delenv('construct.style');
1.504     albertel 1590:     }
                   1591: 
1.372     foxr     1592: 
1.140     sakharuk 1593:     if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') {
1.143     sakharuk 1594:       #-- single document - problem, page, html, xml, ...
1.343     albertel 1595: 	my ($currentURL,$cleanURL);
1.375     foxr     1596: 
1.162     sakharuk 1597: 	if ($helper->{'VARS'}->{'construction'} ne '1') {
1.185     sakharuk 1598:             #prints published resource
1.153     sakharuk 1599: 	    $currentURL=$helper->{'VARS'}->{'postdata'};
1.343     albertel 1600: 	    $cleanURL=&Apache::lonenc::check_decrypt($currentURL);
1.143     sakharuk 1601: 	} else {
1.512     foxr     1602: 
1.185     sakharuk 1603:             #prints resource from the construction space
1.240     albertel 1604: 	    $currentURL='/'.$helper->{'VARS'}->{'filename'};
1.206     sakharuk 1605: 	    if ($currentURL=~/([^?]+)/) {$currentURL=$1;}
1.343     albertel 1606: 	    $cleanURL=$currentURL;
1.143     sakharuk 1607: 	}
1.140     sakharuk 1608: 	$selectionmade = 1;
1.413     albertel 1609: 	if ($cleanURL!~m|^/adm/|
                   1610: 	    && $cleanURL=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.169     albertel 1611: 	    my $rndseed=time;
1.242     sakharuk 1612: 	    my $texversion='';
                   1613: 	    if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') {
                   1614: 		my %moreenv;
1.343     albertel 1615: 		$moreenv{'request.filename'}=$cleanURL;
1.290     sakharuk 1616:                 if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {$form{'problemtype'}='exam';}
1.242     sakharuk 1617: 		$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310     sakharuk 1618: 		$form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.242     sakharuk 1619: 		$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309     sakharuk 1620: 		$form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511     foxr     1621: 		$form{'print_annotations'}=$helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
                   1622: 		if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
                   1623: 		    ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
                   1624: 		    $form{'problem_split'}='yes';
                   1625: 		}
1.242     sakharuk 1626: 		if ($helper->{'VARS'}->{'curseed'}) {
                   1627: 		    $rndseed=$helper->{'VARS'}->{'curseed'};
                   1628: 		}
                   1629: 		$form{'rndseed'}=$rndseed;
1.520     raeburn  1630: 		&Apache::lonnet::appenv(\%moreenv);
1.428     albertel 1631: 
                   1632: 		&Apache::lonxml::clear_problem_counter();
                   1633: 
1.375     foxr     1634: 		$resources_printed .= $currentURL.':';
1.515     foxr     1635: 		$texversion.=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.428     albertel 1636: 
1.511     foxr     1637: 		#  Add annotations if required:
                   1638: 	    
1.428     albertel 1639: 		&Apache::lonxml::clear_problem_counter();
                   1640: 
1.242     sakharuk 1641: 		&Apache::lonnet::delenv('request.filename');
1.230     albertel 1642: 	    }
1.423     foxr     1643: 	    # current document with answers.. no need to encap in minipage
                   1644: 	    #  since there's only one answer.
                   1645: 
1.242     sakharuk 1646: 	    if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   1647: 	       ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.353     foxr     1648: 		$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.166     albertel 1649: 		$form{'grade_target'}='answer';
1.167     albertel 1650: 		$form{'answer_output_mode'}='tex';
1.169     albertel 1651: 		$form{'rndseed'}=$rndseed;
1.401     albertel 1652:                 if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {
                   1653: 		    $form{'problemtype'}='exam';
                   1654: 		}
1.375     foxr     1655: 		$resources_printed .= $currentURL.':';
1.515     foxr     1656: 		my $answer=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.511     foxr     1657: 		
                   1658: 
1.242     sakharuk 1659: 		if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   1660: 		    $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
                   1661: 		} else {
                   1662: 		    $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.245     sakharuk 1663: 		    if ($helper->{'VARS'}->{'construction'} ne '1') {
1.477     albertel 1664: 			my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
                   1665: 			$title = &Apache::lonxml::latex_special_symbols($title);
                   1666: 			$texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.343     albertel 1667: 			$texversion.=&path_to_problem($cleanURL,$LaTeXwidth);
1.245     sakharuk 1668: 		    } else {
                   1669: 			$texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
1.343     albertel 1670: 			my $URLpath=$cleanURL;
1.245     sakharuk 1671: 			$URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
1.504     albertel 1672: 			$texversion.=&path_to_problem($URLpath,$LaTeXwidth);
1.245     sakharuk 1673: 		    }
1.242     sakharuk 1674: 		    $texversion.='\vskip 1 mm '.$answer.'\end{document}';
                   1675: 		}
1.511     foxr     1676: 
                   1677: 
                   1678: 		
                   1679: 
1.550     foxr     1680: 	    
1.511     foxr     1681: 	    }
                   1682: 	    # Print annotations.
                   1683: 
                   1684: 
                   1685: 	    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1686: 		my $annotation .= &annotate($currentURL);
                   1687: 		$texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
1.163     sakharuk 1688: 	    }
1.511     foxr     1689: 
                   1690: 
1.214     sakharuk 1691: 	    if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1.215     sakharuk 1692: 		$texversion=&IndexCreation($texversion,$currentURL);
1.214     sakharuk 1693: 	    }
1.219     sakharuk 1694: 	    if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
                   1695: 		$texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$currentURL| \\strut\\\\\\strut /;
                   1696: 
                   1697: 	    }
1.162     sakharuk 1698: 	    $result .= $texversion;
                   1699: 	    if ($currentURL=~m/\.page\s*$/) {
                   1700: 		($result,$number_of_columns) = &page_cleanup($result);
                   1701: 	    }
1.413     albertel 1702:         } elsif ($cleanURL!~m|^/adm/|
                   1703: 		 && $currentURL=~/\.sequence$/ && $helper->{'VARS'}->{'construction'} eq '1') {
1.227     sakharuk 1704:             #printing content of sequence from the construction space	
                   1705: 	    $currentURL=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;
1.551     foxr     1706: #	    $result .= &print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.459     foxr     1707: 	    $result .= &print_construction_sequence($currentURL, $helper, %form,
                   1708: 						    $LaTeXwidth);
                   1709: 	    $result .= '\end{document}';  
                   1710: 	    if (!($result =~ /\\begin\{document\}/)) {
                   1711: 		$result = &print_latex_header() . $result;
1.227     sakharuk 1712: 	    }
1.459     foxr     1713: 	    # End construction space sequence.
1.456     raeburn  1714: 	} elsif ($cleanURL=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { 
1.258     sakharuk 1715: 		$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.298     sakharuk 1716: 		if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;}
1.375     foxr     1717: 		$resources_printed .= $currentURL.':';
1.515     foxr     1718: 		my $texversion=&ssi_with_retries($currentURL, $ssi_retry_count, %form);
1.511     foxr     1719: 		if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1720: 		    my $annotation = &annotate($currentURL);
                   1721: 		    $texversion    =~ s/(\\end{document})/$annotation$1/;
                   1722: 		}
1.258     sakharuk 1723: 		$result .= $texversion;
1.550     foxr     1724: 	} elsif ($cleanURL =~/\.tex$/) {
1.498     foxr     1725: 	    # For this sort of print of a single LaTeX file,
                   1726: 	    # We can just print the LaTeX file as it is uninterpreted in any way:
                   1727: 	    #
                   1728: 
                   1729: 	    $result = &fetch_raw_resource($currentURL);
1.511     foxr     1730: 	    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1731: 		my $annotation = &annotate($currentURL);
                   1732: 		$result =~ s/(\\end{document})/$annotation$1/;
                   1733: 	    }
                   1734: 
1.499     foxr     1735: 	    $do_postprocessing = 0; # Don't massage the result.
1.498     foxr     1736: 
1.550     foxr     1737: 	} elsif ($cleanURL =~ /\.pdf$/i) {
                   1738: 	    $result .= &include_pdf($cleanURL);
1.551     foxr     1739: 	    $result .= '\end{document}';
1.162     sakharuk 1740: 	} else {
1.414     albertel 1741: 	    $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'},
                   1742: 				  $helper->{'VARS'}->{'symb'});
1.162     sakharuk 1743: 	}
1.354     foxr     1744:     } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems')       or
1.142     sakharuk 1745:              ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or
1.354     foxr     1746:              ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems')       or
                   1747: 	     ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources')      or # BUGBUG
1.536     foxr     1748: 	     ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') 
                   1749: 	     ) { 
1.511     foxr     1750: 
                   1751: 
1.141     sakharuk 1752:         #-- produce an output string
1.296     sakharuk 1753: 	if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') {
                   1754: 	    $selectionmade = 2;
                   1755: 	} elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') {
                   1756: 	    $selectionmade = 3;
1.536     foxr     1757: 	} elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') 
                   1758: 		 ) {
1.296     sakharuk 1759: 	    $selectionmade = 4;
1.354     foxr     1760: 	} elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') {  #BUGBUG
                   1761: 	    $selectionmade = 4;
1.296     sakharuk 1762: 	} elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') {
                   1763: 	    $selectionmade = 7;
                   1764: 	}
1.193     sakharuk 1765: 	$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310     sakharuk 1766: 	$form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.203     sakharuk 1767: 	$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309     sakharuk 1768: 	$form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511     foxr     1769: 	$form{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
                   1770: 	if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes')   ||
                   1771: 	    ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') ) {
                   1772: 	    $form{'problem_split'}='yes';
                   1773: 	}
1.141     sakharuk 1774: 	my $flag_latex_header_remove = 'NO';
                   1775: 	my $flag_page_in_sequence = 'NO';
                   1776: 	my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.193     sakharuk 1777: 	my $prevassignment='';
1.428     albertel 1778: 
                   1779: 	&Apache::lonxml::clear_problem_counter();
                   1780: 
1.416     foxr     1781: 	my $pbreakresources = keys %page_breaks;
1.141     sakharuk 1782: 	for (my $i=0;$i<=$#master_seq;$i++) {
1.350     foxr     1783: 
1.521     foxr     1784: 	    &Apache::lonenc::reset_enc();
                   1785: 
                   1786: 
1.350     foxr     1787: 	    # Note due to document structure, not allowed to put \newpage
                   1788: 	    # prior to the first resource
                   1789: 
1.351     foxr     1790: 	    if (defined $page_breaks{$master_seq[$i]}) {
1.350     foxr     1791: 		if($i != 0) {
                   1792: 		    $result.="\\newpage\n";
                   1793: 		}
                   1794: 	    }
1.521     foxr     1795: 	    my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]);
1.237     albertel 1796: 	    $urlp=&Apache::lonnet::clutter($urlp);
1.166     albertel 1797: 	    $form{'symb'}=$master_seq[$i];
1.407     albertel 1798: 
1.521     foxr     1799: 
1.407     albertel 1800: 	    my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem
1.521     foxr     1801: 
1.267     sakharuk 1802: 	    if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;}
1.247     sakharuk 1803: 	    if ($i==0) {$prevassignment=$assignment;}
1.297     sakharuk 1804: 	    my $texversion='';
1.413     albertel 1805: 	    if ($urlp!~m|^/adm/|
                   1806: 		&& $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375     foxr     1807: 		$resources_printed .= $urlp.':';
1.428     albertel 1808: 		&Apache::lonxml::remember_problem_counter();
1.515     foxr     1809: 		$texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.296     sakharuk 1810: 		if ($urlp=~/\.page$/) {
                   1811: 		    ($texversion,my $number_of_columns_page) = &page_cleanup($texversion);
                   1812: 		    if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;} 
                   1813: 		    $texversion =~ s/\\end{document}\d*/\\end{document}/;
                   1814: 		    $flag_page_in_sequence = 'YES';
                   1815: 		} 
1.428     albertel 1816: 
1.296     sakharuk 1817: 		if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   1818: 		   ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     1819: 		    #  Don't permanently pervert the %form hash
                   1820: 		    my %answerform = %form;
                   1821: 		    $answerform{'grade_target'}='answer';
                   1822: 		    $answerform{'answer_output_mode'}='tex';
1.375     foxr     1823: 		    $resources_printed .= $urlp.':';
1.428     albertel 1824: 
                   1825: 		    &Apache::lonxml::restore_problem_counter();
1.515     foxr     1826: 		    my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.428     albertel 1827: 
1.296     sakharuk 1828: 		    if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   1829: 			$texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1.249     sakharuk 1830: 		    } else {
1.307     sakharuk 1831: 			if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) {
1.296     sakharuk 1832: 			    $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.552     foxr     1833: 			    $texversion =~ s/\\begin{document}//;
1.477     albertel 1834: 			    my $title = &Apache::lonnet::gettitle($master_seq[$i]);
                   1835: 			    $title = &Apache::lonxml::latex_special_symbols($title);
                   1836: 			    my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.423     foxr     1837: 			    $body   .= &path_to_problem ($urlp,$LaTeXwidth);
                   1838: 			    $body   .='\vskip 1 mm '.$answer;
                   1839: 			    $body    = &encapsulate_minipage($body);
                   1840: 			    $texversion .= $body;
1.296     sakharuk 1841: 			} else {
                   1842: 			    $texversion='';
                   1843: 			}
1.249     sakharuk 1844: 		    }
1.511     foxr     1845: 
1.246     sakharuk 1846: 		}
1.511     foxr     1847: 		if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1848: 		    my $annotation .= &annotate($urlp);
                   1849: 		    $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
                   1850: 		}
                   1851: 
1.296     sakharuk 1852: 		if ($flag_latex_header_remove ne 'NO') {
                   1853: 		    $texversion = &latex_header_footer_remove($texversion);
                   1854: 		} else {
                   1855: 		    $texversion =~ s/\\end{document}//;
                   1856: 		}
                   1857: 		if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
                   1858: 		    $texversion=&IndexCreation($texversion,$urlp);
                   1859: 		}
                   1860: 		if (($selectionmade == 4) and ($assignment ne $prevassignment)) {
                   1861: 		    my $name = &get_name();
                   1862: 		    my $courseidinfo = &get_course();
                   1863: 		    $prevassignment=$assignment;
1.455     albertel 1864: 		    my $header_text = $parmhash{'print_header_format'};
1.486     foxr     1865: 		    $header_text    = &format_page_header($textwidth, $header_text,
1.455     albertel 1866: 							  $assignment, 
                   1867: 							  $courseidinfo, 
                   1868: 							  $name);
1.552     foxr     1869: 
1.417     foxr     1870: 		    if ($numberofcolumns eq '1') {
1.455     albertel 1871: 			$result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{'.$header_text.'}} \vskip 5 mm ';
1.416     foxr     1872: 		    } else {
1.455     albertel 1873: 			$result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\fancyhead[LO]{'.$header_text.'}} \vskip 5 mm ';
1.416     foxr     1874: 		    }			
1.296     sakharuk 1875: 		}
                   1876: 		$result .= $texversion;
                   1877: 		$flag_latex_header_remove = 'YES';   
1.456     raeburn  1878: 	    } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { 
1.301     sakharuk 1879: 		$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
                   1880: 		if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;}
1.375     foxr     1881: 		$resources_printed .= $urlp.':';
1.515     foxr     1882: 		my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.511     foxr     1883: 		if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1884: 		    my $annotation = &annotate($urlp);
                   1885: 		    $texversion =~ s/(\\end{document)/$annotation$1/;
                   1886: 		}
                   1887: 
1.301     sakharuk 1888: 		if ($flag_latex_header_remove ne 'NO') {
                   1889: 		    $texversion = &latex_header_footer_remove($texversion);
1.550     foxr     1890: 		} else {	
1.301     sakharuk 1891: 		    $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/;
                   1892: 		}
                   1893: 		$result .= $texversion;
                   1894: 		$flag_latex_header_remove = 'YES'; 
1.550     foxr     1895: 	    } elsif ($urlp=~ /\.pdf$/i) {
                   1896: 		if ($i > 0) {
                   1897: 		    $result .= '\cleardoublepage';
                   1898: 		}
                   1899: 		$result .= &include_pdf($urlp);
                   1900: 		if ($i != $#master_seq) {
                   1901: 		    if ($numberofcolumns eq '1') {
                   1902: 			$result .= '\newpage';
                   1903: 		    } else {
                   1904: 			# the \\'s seem to be needed to let LaTeX know there's something
                   1905: 			# on the page since LaTeX seems to not like to clear an empty page.
                   1906: 			#
                   1907: 			$result .= '\\ \cleardoublepage';
                   1908: 		    }
                   1909: 		}
                   1910: 		$flag_latex_header_remove = 'YES';
                   1911: 
1.141     sakharuk 1912: 	    } else {
1.414     albertel 1913: 		$texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'},
                   1914: 					 $master_seq[$i]);
1.297     sakharuk 1915: 		if ($flag_latex_header_remove ne 'NO') {
                   1916: 		    $texversion = &latex_header_footer_remove($texversion);
                   1917: 		} else {
                   1918: 		    $texversion =~ s/\\end{document}//;
                   1919: 		}
                   1920: 		$result .= $texversion;
                   1921: 		$flag_latex_header_remove = 'YES';   
1.296     sakharuk 1922: 	    }	    
1.550     foxr     1923: 	    if (&Apache::loncommon::connection_aborted($r)) { 
                   1924: 		last; 
                   1925: 	    }
1.141     sakharuk 1926: 	}
1.428     albertel 1927: 	&Apache::lonxml::clear_problem_counter();
1.344     foxr     1928: 	if ($flag_page_in_sequence eq 'YES') {
                   1929: 	    $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;
                   1930: 	}	
1.141     sakharuk 1931: 	$result .= '\end{document}';
1.284     albertel 1932:      } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1.536     foxr     1933: 	      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ||
1.284     albertel 1934: 	      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){
1.353     foxr     1935: 
                   1936: 
1.150     sakharuk 1937:      #-- prints assignments for whole class or for selected students  
1.284     albertel 1938: 	 my $type;
1.536     foxr     1939: 	 if (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
                   1940: 	     ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ) {
1.254     sakharuk 1941: 	     $selectionmade=5;
1.284     albertel 1942: 	     $type='problems';
1.254     sakharuk 1943: 	 } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') {
                   1944: 	     $selectionmade=8;
1.284     albertel 1945: 	     $type='resources';
1.254     sakharuk 1946: 	 }
1.150     sakharuk 1947: 	 my @students=split /\|\|\|/, $helper->{'VARS'}->{'STUDENTS'};
1.341     foxr     1948: 	 #   The normal sort order is by section then by students within the
                   1949: 	 #   section. If the helper var student_sort is 1, then the user has elected
                   1950: 	 #   to override this and output the students by name.
                   1951: 	 #    Each element of the students array is of the form:
                   1952: 	 #       username:domain:section:last, first:status
                   1953: 	 #    
1.429     foxr     1954: 	 #  Note that student sort is not compatible with printing 
                   1955: 	 #  1 section per pdf...so that setting overrides.
1.341     foxr     1956: 	 #   
1.429     foxr     1957: 	 if (($helper->{'VARS'}->{'student_sort'}    eq 1)  && 
                   1958: 	     ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) {
1.341     foxr     1959: 	     @students = sort compare_names  @students;
                   1960: 	 }
1.429     foxr     1961: 	 &adjust_number_to_print($helper);
                   1962: 
1.278     albertel 1963:          if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq '0' ||
                   1964: 	     $helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'all' ) {
                   1965: 	     $helper->{'VARS'}->{'NUMBER_TO_PRINT'}=$#students+1;
                   1966: 	 }
1.429     foxr     1967: 	 # If we are splitting on section boundaries, we need 
                   1968: 	 # to remember that in split_on_sections and 
                   1969: 	 # print all of the students in the list.
                   1970: 	 #
                   1971: 	 my $split_on_sections = 0;
                   1972: 	 if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'section') {
                   1973: 	     $split_on_sections = 1;
                   1974: 	     $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1;
                   1975: 	 }
1.150     sakharuk 1976: 	 my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.350     foxr     1977: 
1.150     sakharuk 1978: 	 #loop over students
1.552     foxr     1979: 	 my $flag_latex_header_remove = 'NO';
1.150     sakharuk 1980: 	 my %moreenv;
1.330     sakharuk 1981:          $moreenv{'instructor_comments'}='hide';
1.285     albertel 1982: 	 $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth);
1.309     sakharuk 1983: 	 $moreenv{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511     foxr     1984: 	 $moreenv{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1.353     foxr     1985: 	 $moreenv{'problem_split'}    = $parmhash{'problem_stream_switch'};
1.369     foxr     1986: 	 $moreenv{'suppress_tries'}   = $parmhash{'suppress_tries'};
1.511     foxr     1987: 	 if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes')  ||
                   1988: 	     ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
                   1989: 	     $moreenv{'problem_split'}='yes';
                   1990: 	 }
1.318     albertel 1991: 	 my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75');
1.272     sakharuk 1992: 	 my $student_counter=-1;
1.429     foxr     1993: 	 my $i = 0;
1.430     albertel 1994: 	 my $last_section = (split(/:/,$students[0]))[2];
1.150     sakharuk 1995: 	 foreach my $person (@students) {
1.350     foxr     1996: 
1.373     albertel 1997:              my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";
1.311     sakharuk 1998: 	     if (-e $duefile) {
                   1999: 		 my $temp_file = Apache::File->new('>>'.$duefile);
                   2000: 		 print $temp_file "1969\n";
                   2001: 	     }
1.272     sakharuk 2002: 	     $student_counter++;
1.429     foxr     2003: 	     if ($split_on_sections) {
1.430     albertel 2004: 		 my $this_section = (split(/:/,$person))[2];
1.429     foxr     2005: 		 if ($this_section ne $last_section) {
                   2006: 		     $i++;
                   2007: 		     $last_section = $this_section;
                   2008: 		 }
                   2009: 	     } else {
                   2010: 		 $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'});
                   2011: 	     }
1.375     foxr     2012: 	     my ($output,$fullname, $printed)=&print_resources($r,$helper,
1.353     foxr     2013: 						     $person,$type,
                   2014: 						     \%moreenv,\@master_seq,
1.360     albertel 2015: 						     $flag_latex_header_remove,
1.422     albertel 2016: 						     $LaTeXwidth);
1.375     foxr     2017: 	     $resources_printed .= ":";
1.284     albertel 2018: 	     $print_array[$i].=$output;
                   2019: 	     $student_names[$i].=$person.':'.$fullname.'_END_';
                   2020: 	     &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname);
                   2021: 	     $flag_latex_header_remove = 'YES';
1.331     albertel 2022: 	     if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284     albertel 2023: 	 }
                   2024: 	 &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
                   2025: 	 $result .= $print_array[0].'  \end{document}';
                   2026:      } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon')     ||
                   2027: 	      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon')  ) { 
1.373     albertel 2028: 	 my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
                   2029: 	 my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
1.288     albertel 2030: 	 my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'};
                   2031: 	 my $code_name=$helper->{'VARS'}->{'ANON_CODE_STORAGE_NAME'};
1.292     albertel 2032: 	 my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'};
1.385     foxr     2033: 	 my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'};
1.388     foxr     2034: 	 my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'};
                   2035: 
1.381     albertel 2036: 	 my $code_option=$helper->{'VARS'}->{'CODE_OPTION'};
1.542     raeburn  2037:          my @lines = &Apache::grades::get_scantronformat_file();
1.381     albertel 2038: 	 my ($code_type,$code_length)=('letter',6);
1.542     raeburn  2039: 	 foreach my $line (@lines) {
1.381     albertel 2040: 	     my ($name,$type,$length) = (split(/:/,$line))[0,2,4];
                   2041: 	     if ($name eq $code_option) {
                   2042: 		 $code_length=$length;
                   2043: 		 if ($type eq 'number') { $code_type = 'number'; }
                   2044: 	     }
                   2045: 	 }
1.288     albertel 2046: 	 my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth));
1.353     foxr     2047: 	 $moreenv{'problem_split'}    = $parmhash{'problem_stream_switch'};
1.420     albertel 2048:          $moreenv{'instructor_comments'}='hide';
1.288     albertel 2049: 	 my $seed=time+($$<<16)+($$);
1.292     albertel 2050: 	 my @allcodes;
                   2051: 	 if ($old_name) {
1.381     albertel 2052: 	     my %result=&Apache::lonnet::get('CODEs',
                   2053: 					     [$old_name,"type\0$old_name"],
                   2054: 					     $cdom,$cnum);
                   2055: 	     $code_type=$result{"type\0$old_name"};
1.292     albertel 2056: 	     @allcodes=split(',',$result{$old_name});
1.336     albertel 2057: 	     $num_todo=scalar(@allcodes);
1.389     foxr     2058: 	 } elsif ($selected_code) { # Selection value is always numeric.
1.388     foxr     2059: 	     $num_todo = 1;
                   2060: 	     @allcodes = ($selected_code);
1.385     foxr     2061: 	 } elsif ($single_code) {
                   2062: 
1.387     foxr     2063: 	     $num_todo    = 1;	# Unconditionally one code to do.
1.385     foxr     2064: 	     # If an alpha code have to convert to numbers so it can be
                   2065: 	     # converted back to letters again :-)
                   2066: 	     #
                   2067: 	     if ($code_type ne 'number') {
                   2068: 		 $single_code = &letters_to_num($single_code);
                   2069: 	     }
                   2070: 	     @allcodes = ($single_code);
1.292     albertel 2071: 	 } else {
                   2072: 	     my %allcodes;
1.299     albertel 2073: 	     srand($seed);
1.292     albertel 2074: 	     for (my $i=0;$i<$num_todo;$i++) {
1.381     albertel 2075: 		 $moreenv{'CODE'}=&get_CODE(\%allcodes,$i,$seed,$code_length,
                   2076: 					    $code_type);
1.292     albertel 2077: 	     }
                   2078: 	     if ($code_name) {
                   2079: 		 &Apache::lonnet::put('CODEs',
1.381     albertel 2080: 				      {
                   2081: 					$code_name =>join(',',keys(%allcodes)),
                   2082: 					"type\0$code_name" => $code_type
                   2083: 				      },
1.292     albertel 2084: 				      $cdom,$cnum);
                   2085: 	     }
                   2086: 	     @allcodes=keys(%allcodes);
                   2087: 	 }
1.336     albertel 2088: 	 my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
                   2089: 	 my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'});
1.452     albertel 2090: 	 &adjust_number_to_print($helper);
1.336     albertel 2091: 	 my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'};
                   2092: 	 if ($number_per_page eq '0' || $number_per_page eq 'all') {
                   2093: 	     $number_per_page=$num_todo;
                   2094: 	 }
                   2095: 	 my $flag_latex_header_remove = 'NO'; 
                   2096: 	 my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75');
1.295     albertel 2097: 	 my $count=0;
1.292     albertel 2098: 	 foreach my $code (sort(@allcodes)) {
1.295     albertel 2099: 	     my $file_num=int($count/$number_per_page);
1.381     albertel 2100: 	     if ($code_type eq 'number') { 
                   2101: 		 $moreenv{'CODE'}=$code;
                   2102: 	     } else {
                   2103: 		 $moreenv{'CODE'}=&num_to_letters($code);
                   2104: 	     }
1.375     foxr     2105: 	     my ($output,$fullname, $printed)=
1.288     albertel 2106: 		 &print_resources($r,$helper,'anonymous',$type,\%moreenv,
1.360     albertel 2107: 				  \@master_seq,$flag_latex_header_remove,
                   2108: 				  $LaTeXwidth);
1.375     foxr     2109: 	     $resources_printed .= ":";
1.295     albertel 2110: 	     $print_array[$file_num].=$output;
1.288     albertel 2111: 	     &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
                   2112: 				       &mt('last assignment').' '.$fullname);
                   2113: 	     $flag_latex_header_remove = 'YES';
1.295     albertel 2114: 	     $count++;
1.331     albertel 2115: 	     if (&Apache::loncommon::connection_aborted($r)) { last; }
1.288     albertel 2116: 	 }
                   2117: 	 &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
                   2118: 	 $result .= $print_array[0].'  \end{document}';
                   2119:      } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') {      
1.151     sakharuk 2120:     #prints selected problems from the subdirectory 
                   2121: 	$selectionmade = 6;
                   2122:         my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};
1.154     sakharuk 2123: 	@list_of_files=sort @list_of_files;
1.175     sakharuk 2124: 	my $flag_latex_header_remove = 'NO'; 
                   2125: 	my $rndseed=time;
1.230     albertel 2126: 	if ($helper->{'VARS'}->{'curseed'}) {
                   2127: 	    $rndseed=$helper->{'VARS'}->{'curseed'};
                   2128: 	}
1.151     sakharuk 2129: 	for (my $i=0;$i<=$#list_of_files;$i++) {
1.521     foxr     2130: 
                   2131: 	    &Apache::lonenc::reset_enc();
                   2132: 
1.152     sakharuk 2133: 	    my $urlp = $list_of_files[$i];
1.253     sakharuk 2134: 	    $urlp=~s|//|/|;
1.152     sakharuk 2135: 	    if ($urlp=~/\//) {
1.353     foxr     2136: 		$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.175     sakharuk 2137: 		$form{'rndseed'}=$rndseed;
1.152     sakharuk 2138: 		if ($urlp =~ m|/home/([^/]+)/public_html|) {
                   2139: 		    $urlp =~ s|/home/([^/]*)/public_html|/~$1|;
                   2140: 		} else {
1.302     sakharuk 2141: 		    $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;
1.152     sakharuk 2142: 		}
1.375     foxr     2143: 		$resources_printed .= $urlp.':';
1.515     foxr     2144: 		my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.251     sakharuk 2145: 		if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1.253     sakharuk 2146: 		   ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     2147: 		    #  Don't permanently pervert %form:
                   2148: 		    my %answerform = %form;
                   2149: 		    $answerform{'grade_target'}='answer';
                   2150: 		    $answerform{'answer_output_mode'}='tex';
                   2151: 		    $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
                   2152: 		    $answerform{'rndseed'}=$rndseed;
1.375     foxr     2153: 		    $resources_printed .= $urlp.':';
1.515     foxr     2154: 		    my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.251     sakharuk 2155: 		    if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   2156: 			$texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
                   2157: 		    } else {
1.253     sakharuk 2158: 			$texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
                   2159: 			if ($helper->{'VARS'}->{'construction'} ne '1') {
                   2160: 			    $texversion.='\vskip 0 mm \noindent ';
                   2161: 			    $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
                   2162: 			} else {
                   2163: 			    $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
                   2164: 			    my $URLpath=$urlp;
                   2165: 			    $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
                   2166: 			    $texversion.=&path_to_problem ($URLpath,$LaTeXwidth);
                   2167: 			}
                   2168: 			$texversion.='\vskip 1 mm '.$answer.'\end{document}';
1.251     sakharuk 2169: 		    }
1.174     sakharuk 2170: 		}
1.515     foxr     2171:                 #this chunk is responsible for printing the path to problem
                   2172: 
1.253     sakharuk 2173: 		my $newurlp=$urlp;
                   2174: 		if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;}
                   2175: 		$newurlp=&path_to_problem($newurlp,$LaTeXwidth);
1.242     sakharuk 2176: 		$texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;
1.152     sakharuk 2177: 		if ($flag_latex_header_remove ne 'NO') {
                   2178: 		    $texversion = &latex_header_footer_remove($texversion);
                   2179: 		} else {
                   2180: 		    $texversion =~ s/\\end{document}//;
1.216     sakharuk 2181: 		}
                   2182: 		if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
                   2183: 		    $texversion=&IndexCreation($texversion,$urlp);
1.152     sakharuk 2184: 		}
1.219     sakharuk 2185: 		if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
                   2186: 		    $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
                   2187: 		    
                   2188: 		}
1.152     sakharuk 2189: 		$result .= $texversion;
                   2190: 	    }
                   2191: 	    $flag_latex_header_remove = 'YES';  
1.151     sakharuk 2192: 	}
1.175     sakharuk 2193: 	if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;}
1.152     sakharuk 2194: 	$result .= '\end{document}';      	
1.140     sakharuk 2195:     }
                   2196: #-------------------------------------------------------- corrections for the different page formats
1.499     foxr     2197: 
                   2198:     # Only post process if that has not been turned off e.g. by a raw latex resource.
                   2199: 
                   2200:     if ($do_postprocessing) {
                   2201: 	$result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade);
                   2202: 	$result = &latex_corrections($number_of_columns,$result,$selectionmade,
                   2203: 				     $helper->{'VARS'}->{'ANSWER_TYPE'});
                   2204: 	#if ($numberofcolumns == 1) {
1.451     albertel 2205: 	$result =~ s/\\textwidth\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /;
                   2206: 	$result =~ s/\\textheight\s*=?\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /;
                   2207: 	$result =~ s/\\evensidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
                   2208: 	$result =~ s/\\oddsidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
1.499     foxr     2209: 	#}
                   2210:     }
1.367     foxr     2211: 
1.515     foxr     2212:     # Set URLback if this is a construction space print so we can provide
                   2213:     # a link to the resource being edited.
                   2214:     #
1.274     sakharuk 2215: 
1.276     sakharuk 2216:     my $URLback=''; #link to original document
1.510     albertel 2217:     if ($helper->{'VARS'}->{'construction'} eq '1') {
1.276     sakharuk 2218: 	#prints resource from the construction space
                   2219: 	$URLback='/'.$helper->{'VARS'}->{'filename'};
1.279     albertel 2220: 	if ($URLback=~/([^?]+)/) {
                   2221: 	    $URLback=$1;
                   2222: 	    $URLback=~s|^/~|/priv/|;
                   2223: 	}
1.276     sakharuk 2224:     }
1.375     foxr     2225: 
1.525     www      2226: #-- writing .tex file in prtspool 
                   2227:     my $temp_file;
                   2228:     my $identifier = &Apache::loncommon::get_cgi_id();
                   2229:     my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex";
                   2230:     if (!($#print_array>0)) { 
                   2231:        unless ($temp_file = Apache::File->new('>'.$filename)) {
                   2232: 	  $r->log_error("Couldn't open $filename for output $!");
                   2233: 	  return SERVER_ERROR; 
                   2234:        }
                   2235:        print $temp_file $result;
                   2236:        my $begin=index($result,'\begin{document}',0);
                   2237:        my $inc=substr($result,0,$begin+16); 
1.515     foxr     2238:     } else {
1.525     www      2239:        my $begin=index($result,'\begin{document}',0);
                   2240:        my $inc=substr($result,0,$begin+16);
                   2241:        for (my $i=0;$i<=$#print_array;$i++) {
                   2242: 	  if ($i==0) {
                   2243: 	      $print_array[$i]=$result;
                   2244: 	  } else {
                   2245: 	      $print_array[$i].='\end{document}';
                   2246: 	      $print_array[$i] = 
                   2247: 		&latex_corrections($number_of_columns,$print_array[$i],
                   2248: 				   $selectionmade, 
                   2249: 				   $helper->{'VARS'}->{'ANSWER_TYPE'});
1.515     foxr     2250: 	    
1.525     www      2251: 	      my $anobegin=index($print_array[$i],'\setcounter{page}',0);
                   2252: 	      substr($print_array[$i],0,$anobegin)='';
                   2253: 	      $print_array[$i]=$inc.$print_array[$i];
                   2254: 	  }
                   2255: 	  my $temp_file;
                   2256: 	  my $newfilename=$filename;
                   2257: 	  my $num=$i+1;
                   2258: 	  $newfilename =~s/\.tex$//; 
                   2259: 	  $newfilename=sprintf("%s_%03d.tex",$newfilename, $num);
                   2260: 	  unless ($temp_file = Apache::File->new('>'.$newfilename)) {
                   2261: 	      $r->log_error("Couldn't open $newfilename for output $!");
                   2262: 	      return SERVER_ERROR; 
                   2263: 	  }
                   2264: 	  print $temp_file $print_array[$i];
                   2265:        }
                   2266:     }
                   2267:     my $student_names='';
                   2268:     if ($#print_array>0) {
                   2269:         for (my $i=0;$i<=$#print_array;$i++) {
                   2270:   	  $student_names.=$student_names[$i].'_ENDPERSON_';
1.515     foxr     2271: 	}
1.525     www      2272:     } else {
                   2273: 	if ($#student_names>-1) {
                   2274: 	   $student_names=$student_names[0].'_ENDPERSON_';
1.515     foxr     2275: 	} else {
1.525     www      2276:            my $fullname = &get_name($env{'user.name'},$env{'user.domain'});
                   2277: 	   $student_names=join(':',$env{'user.name'},$env{'user.domain'},
1.515     foxr     2278: 				    $env{'request.course.sec'},$fullname).
                   2279: 					'_ENDPERSON_'.'_END_';
                   2280: 	}
1.525     www      2281:      }
1.515     foxr     2282: 	
1.525     www      2283:      # logic for now is too complex to trace if this has been defined
                   2284:      #  yet.
                   2285:      my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   2286:      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2287:      &Apache::lonnet::appenv({'cgi.'.$identifier.'.file'   => $filename,
1.515     foxr     2288: 				'cgi.'.$identifier.'.layout'  => $laystyle,
                   2289: 				'cgi.'.$identifier.'.numcol'  => $numberofcolumns,
                   2290: 				'cgi.'.$identifier.'.paper'  => $papersize,
                   2291: 				'cgi.'.$identifier.'.selection' => $selectionmade,
                   2292: 				'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
                   2293: 				'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
                   2294: 				'cgi.'.$identifier.'.role' => $perm{'pav'},
                   2295: 				'cgi.'.$identifier.'.numberoffiles' => $#print_array,
                   2296: 				'cgi.'.$identifier.'.studentnames' => $student_names,
1.520     raeburn  2297: 				'cgi.'.$identifier.'.backref' => $URLback,});
1.525     www      2298:     &Apache::lonnet::appenv({"cgi.$identifier.user"    => $env{'user.name'},
1.515     foxr     2299: 				"cgi.$identifier.domain"  => $env{'user.domain'},
                   2300: 				"cgi.$identifier.courseid" => $cnum, 
                   2301: 				"cgi.$identifier.coursedom" => $cdom, 
1.520     raeburn  2302: 				"cgi.$identifier.resources" => $resources_printed});
1.515     foxr     2303: 	
1.525     www      2304:     my $end_page = &Apache::loncommon::end_page();
1.529     raeburn  2305:     my $continue_text = &mt('Continue');
1.525     www      2306:     # If there's been an unrecoverable SSI error, report it to the user
                   2307:     if ($ssi_error) {
                   2308:         my $helpurl = &Apache::loncommon::top_nav_help('Helpdesk');
1.554   ! bisitz   2309:         $r->print('<br /><p class="LC_error">'.&mt('An unrecoverable network error occurred:').'</p><p>'.
1.526     www      2310:                   &mt('At least one of the resources you chose to print could not be rendered due to an unrecoverable error when communicating with a server:').
                   2311:                   '<br />'.$ssi_last_error_resource.'<br />'.$ssi_last_error.
                   2312:                   '</p><p>'.&mt('You can continue using the link provided below, but make sure to carefully inspect your output file! The errors will be marked in the file.').'<br />'.
1.528     raeburn  2313:                   &mt('You may be able to reprint the individual resources for which this error occurred, as the issue may be temporary.').
1.525     www      2314:                   '<br />'.&mt('If the error persists, please contact the [_1] for assistance.',$helpurl).'</p><p>'.
                   2315:                   &mt('We apologize for the inconvenience.').'</p>'.
1.528     raeburn  2316:                   '<a href="/cgi-bin/printout.pl?'.$identifier.'">'.$continue_text.'</a>'.$end_page);
1.525     www      2317:     } else {
1.515     foxr     2318: 	$r->print(<<FINALEND);
1.317     albertel 2319: <br />
1.288     albertel 2320: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.528     raeburn  2321: <a href="/cgi-bin/printout.pl?$identifier">$continue_text</a>
1.431     albertel 2322: $end_page
1.140     sakharuk 2323: FINALEND
1.528     raeburn  2324:     }                                     # endif ssi errors.
1.140     sakharuk 2325: }
                   2326: 
1.288     albertel 2327: 
                   2328: sub get_CODE {
1.381     albertel 2329:     my ($all_codes,$num,$seed,$size,$type)=@_;
1.288     albertel 2330:     my $max='1'.'0'x$size;
                   2331:     my $newcode;
                   2332:     while(1) {
1.392     albertel 2333: 	$newcode=sprintf("%0".$size."d",int(rand($max)));
1.288     albertel 2334: 	if (!exists($$all_codes{$newcode})) {
                   2335: 	    $$all_codes{$newcode}=1;
1.381     albertel 2336: 	    if ($type eq 'number' ) {
                   2337: 		return $newcode;
                   2338: 	    } else {
                   2339: 		return &num_to_letters($newcode);
                   2340: 	    }
1.288     albertel 2341: 	}
                   2342:     }
                   2343: }
1.140     sakharuk 2344: 
1.284     albertel 2345: sub print_resources {
1.360     albertel 2346:     my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422     albertel 2347: 	$LaTeXwidth)=@_;
1.284     albertel 2348:     my $current_output = ''; 
1.375     foxr     2349:     my $printed = '';
1.284     albertel 2350:     my ($username,$userdomain,$usersection) = split /:/,$person;
                   2351:     my $fullname = &get_name($username,$userdomain);
1.492     foxr     2352:     my $namepostfix = "\\\\";	# Both anon and not anon should get the same vspace.
1.288     albertel 2353:     if ($person =~ 'anon') {
1.492     foxr     2354: 	$namepostfix .="Name: ";
1.288     albertel 2355: 	$fullname = "CODE - ".$moreenv->{'CODE'};
                   2356:     }
1.444     foxr     2357:     #  Fullname may have special latex characters that need \ prefixing:
                   2358:     #
                   2359: 
1.350     foxr     2360:     my $i           = 0;
1.284     albertel 2361:     #goes through all resources, checks if they are available for 
                   2362:     #current student, and produces output   
1.428     albertel 2363: 
                   2364:     &Apache::lonxml::clear_problem_counter();
1.364     albertel 2365:     my %page_breaks  = &get_page_breaks($helper);
1.476     albertel 2366:     my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440     foxr     2367:     #
1.441     foxr     2368:     #   end each student with a 
1.440     foxr     2369:     #   Special that allows the post processor to even out the page
                   2370:     #   counts later.  Nasty problem this... it would be really
                   2371:     #   nice to put the special in as a postscript comment
1.441     foxr     2372:     #   e.g. \special{ps:\ENDOFSTUDENTSTAMP}  unfortunately,
1.440     foxr     2373:     #   The special gets passed the \ and dvips puts it in the output file
1.441     foxr     2374:     #   so we will just rely on prntout.pl to strip  ENDOFSTUDENTSTAMP from the
                   2375:     #   postscript.  Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440     foxr     2376:     #
1.363     foxr     2377: 
1.511     foxr     2378: 
1.284     albertel 2379:     foreach my $curresline (@{$master_seq})  {
1.351     foxr     2380: 	if (defined $page_breaks{$curresline}) {
1.350     foxr     2381: 	    if($i != 0) {
                   2382: 		$current_output.= "\\newpage\n";
                   2383: 	    }
                   2384: 	}
                   2385: 	$i++;
1.511     foxr     2386: 
1.284     albertel 2387: 	if ( !($type eq 'problems' && 
                   2388: 	       ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
                   2389: 	    my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
                   2390: 	    if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414     albertel 2391: 		if ($res_url!~m|^ext/|
1.413     albertel 2392: 		    && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375     foxr     2393: 		    $printed .= $curresline.':';
1.428     albertel 2394: 
                   2395: 		    &Apache::lonxml::remember_problem_counter();    
                   2396: 
1.526     www      2397: 		    my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428     albertel 2398: 
1.305     sakharuk 2399: 		    if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   2400: 		       ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     2401: 			#   Use a copy of the hash so we don't pervert it on future loop passes.
                   2402: 			my %answerenv = %{$moreenv};
                   2403: 			$answerenv{'answer_output_mode'}='tex';
                   2404: 			$answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428     albertel 2405: 			
                   2406: 			&Apache::lonxml::restore_problem_counter();
                   2407: 
1.380     foxr     2408: 			my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428     albertel 2409: 
1.305     sakharuk 2410: 			if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   2411: 			    $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
                   2412: 			} else {
1.423     foxr     2413: 
                   2414: 			    
                   2415: 			    my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.552     foxr     2416: 			    $header =~ s/\\begin{document}//;     #<<<<<
1.477     albertel 2417: 			    my $title = &Apache::lonnet::gettitle($curresline);
                   2418: 			    $title = &Apache::lonxml::latex_special_symbols($title);
                   2419: 			    my $body   ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
                   2420: 			    $body     .=&path_to_problem($res_url,$LaTeXwidth);
1.423     foxr     2421: 			    $body     .='\vskip 1 mm '.$ansrendered;
                   2422: 			    $body     = &encapsulate_minipage($body);
                   2423: 			    $rendered = $header.$body;
1.305     sakharuk 2424: 			}
                   2425: 		    }
1.511     foxr     2426: 
                   2427: 		    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   2428: 			my $url = &Apache::lonnet::clutter($res_url);
                   2429: 			my $annotation = &annotate($url);
                   2430: 			$rendered =~  s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
                   2431: 		    }
1.305     sakharuk 2432: 		    if ($remove_latex_header eq 'YES') {
                   2433: 			$rendered = &latex_header_footer_remove($rendered);
                   2434: 		    } else {
                   2435: 			$rendered =~ s/\\end{document}//;
                   2436: 		    }
                   2437: 		    $current_output .= $rendered;		    
1.456     raeburn  2438: 		} elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.375     foxr     2439: 		    $printed .= $curresline.':';
1.528     raeburn  2440: 		    my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.511     foxr     2441: 		    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   2442: 			my $url = &Apache::lonnet::clutter($res_url);
                   2443: 			my $annotation = &annotate($url);
                   2444: 			$annotation    =~ s/(\\end{document})/$annotation$1/;
                   2445: 		    }
1.305     sakharuk 2446: 		    if ($remove_latex_header eq 'YES') {
                   2447: 			$rendered = &latex_header_footer_remove($rendered);
1.284     albertel 2448: 		    } else {
1.305     sakharuk 2449: 			$rendered =~ s/\\end{document}//;
1.284     albertel 2450: 		    }
1.421     foxr     2451: 		    $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
1.552     foxr     2452: 		} elsif($res_url = ~/\.pdf$/) {
                   2453: 		    my $url = &Apache::lonnet::clutter($res_url);
                   2454: 		    my $rendered  = &include_pdf($url);
                   2455: 		    if ($remove_latex_header ne 'NO') {
                   2456: 			$rendered = &latex_header_footer_remove($rendered);
                   2457: 		    }
                   2458: 		    $current_output .= $rendered;
1.284     albertel 2459: 		} else {
1.414     albertel 2460: 		    my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305     sakharuk 2461: 		    if ($remove_latex_header ne 'NO') {
                   2462: 			$rendered = &latex_header_footer_remove($rendered);
                   2463: 		    } else {
                   2464: 			$rendered =~ s/\\end{document}//;
                   2465: 		    }
                   2466: 		    $current_output .= $rendered;
1.284     albertel 2467: 		}
                   2468: 	    }
                   2469: 	    $remove_latex_header = 'YES';
1.550     foxr     2470: 	} 
1.331     albertel 2471: 	if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284     albertel 2472:     }
1.552     foxr     2473: 
                   2474: 
1.284     albertel 2475:     my $courseidinfo = &get_course();
                   2476:     my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476     albertel 2477:     my $header_line =
1.486     foxr     2478: 	&format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.537     foxr     2479: 			    $currentassignment, $courseidinfo, $fullname, $usersection);
1.476     albertel 2480:     my $header_start = ($columns_in_format == 1) ? '\lhead'
                   2481: 	                                         : '\fancyhead[LO]';
                   2482:     $header_line = $header_start.'{'.$header_line.'}';
1.284     albertel 2483:     if ($current_output=~/\\documentclass/) {
1.476     albertel 2484: 	$current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.284     albertel 2485:     } else {
1.476     albertel 2486: 	my $blankpages = 
                   2487: 	    '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
                   2488: 	    
                   2489: 	$current_output = '\strut\vspace*{-6 mm}\\newline'.
                   2490: 	    &copyright_line().' \newpage '.$blankpages.$end_of_student.
                   2491: 	    '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
                   2492: 	    $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284     albertel 2493:     }
1.440     foxr     2494:     #
                   2495:     #  Close the student bracketing.
                   2496:     #
1.375     foxr     2497:     return ($current_output,$fullname, $printed);
1.284     albertel 2498: 
                   2499: }
1.140     sakharuk 2500: 
1.3       sakharuk 2501: sub handler {
                   2502: 
                   2503:     my $r = shift;
1.397     albertel 2504:     
                   2505:     &init_perm();
1.114     bowersj2 2506: 
1.416     foxr     2507: 
1.67      www      2508: 
1.397     albertel 2509:     my $helper = printHelper($r);
                   2510:     if (!ref($helper)) {
                   2511: 	return $helper;
1.60      sakharuk 2512:     }
1.177     sakharuk 2513:    
1.184     sakharuk 2514: 
1.454     foxr     2515:     %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353     foxr     2516:  
1.416     foxr     2517: 
1.350     foxr     2518: 
                   2519: 
1.367     foxr     2520:     #  If a figure conversion queue file exists for this user.domain
                   2521:     # we delete it since it can only be bad (if it were good, printout.pl
                   2522:     # would have deleted it the last time around.
                   2523: 
1.373     albertel 2524:     my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367     foxr     2525:     if(-e $conversion_queuefile) {
                   2526: 	unlink $conversion_queuefile;
                   2527:     }
1.515     foxr     2528:     
                   2529: 
1.184     sakharuk 2530:     &output_data($r,$helper,\%parmhash);
1.2       sakharuk 2531:     return OK;
1.60      sakharuk 2532: } 
1.2       sakharuk 2533: 
1.131     bowersj2 2534: use Apache::lonhelper;
1.130     sakharuk 2535: 
1.223     bowersj2 2536: sub addMessage {
                   2537:     my $text = shift;
                   2538:     my $paramHash = Apache::lonhelper::getParamHash();
                   2539:     $paramHash->{MESSAGE_TEXT} = $text;
                   2540:     Apache::lonhelper::message->new();
                   2541: }
                   2542: 
1.416     foxr     2543: 
1.238     bowersj2 2544: 
1.397     albertel 2545: sub init_perm {
                   2546:     undef(%perm);
                   2547:     $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
                   2548:     if (!$perm{'pav'}) {
                   2549: 	$perm{'pav'}=&Apache::lonnet::allowed('pav',
                   2550: 		  $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   2551:     }
1.465     albertel 2552:     $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397     albertel 2553:     if (!$perm{'pfo'}) {
                   2554: 	$perm{'pfo'}=&Apache::lonnet::allowed('pfo',
                   2555: 		  $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   2556:     }
                   2557: }
                   2558: 
1.507     albertel 2559: sub get_randomly_ordered_warning {
                   2560:     my ($helper,$map) = @_;
                   2561: 
                   2562:     my $message;
                   2563: 
                   2564:     my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
                   2565:     my $navmap = Apache::lonnavmaps::navmap->new();
1.547     raeburn  2566:     if (defined($navmap)) {
                   2567:         my $res = $navmap->getResourceByUrl($map);
                   2568:         if ($res) {
                   2569: 	    my $func = 
                   2570: 	        sub { return ($_[0]->is_map() && $_[0]->randomorder); };
                   2571: 	    my @matches = $navmap->retrieveResources($res, $func,1,1,1);
                   2572: 	    if (@matches) {
                   2573: 	        $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.";
                   2574: 	    }
                   2575:         }
                   2576:         if ($message) {
                   2577: 	    return '<message type="warning">'.$message.'</message>';
                   2578:         }
                   2579:     } else {
                   2580:         $message = "Retrieval of information about ordering of resources failed."; 
                   2581:         return '<message type="warning">'.$message.'</message>';
1.507     albertel 2582:     }
                   2583:     return;
                   2584: }
                   2585: 
1.131     bowersj2 2586: sub printHelper {
1.115     bowersj2 2587:     my $r = shift;
                   2588: 
                   2589:     if ($r->header_only) {
1.373     albertel 2590:         if ($env{'browser.mathml'}) {
1.241     www      2591:             &Apache::loncommon::content_type($r,'text/xml');
1.131     bowersj2 2592:         } else {
1.241     www      2593:             &Apache::loncommon::content_type($r,'text/html');
1.131     bowersj2 2594:         }
                   2595:         $r->send_http_header;
                   2596:         return OK;
1.115     bowersj2 2597:     }
                   2598: 
1.131     bowersj2 2599:     # Send header, nocache
1.373     albertel 2600:     if ($env{'browser.mathml'}) {
1.241     www      2601:         &Apache::loncommon::content_type($r,'text/xml');
1.115     bowersj2 2602:     } else {
1.241     www      2603:         &Apache::loncommon::content_type($r,'text/html');
1.115     bowersj2 2604:     }
                   2605:     &Apache::loncommon::no_cache($r);
                   2606:     $r->send_http_header;
                   2607:     $r->rflush();
                   2608: 
1.131     bowersj2 2609:     # Unfortunately, this helper is so complicated we have to
                   2610:     # write it by hand
                   2611: 
                   2612:     Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
                   2613:     
1.176     bowersj2 2614:     my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146     bowersj2 2615:     $helper->declareVar('symb');
1.156     bowersj2 2616:     $helper->declareVar('postdata');    
1.290     sakharuk 2617:     $helper->declareVar('curseed'); 
                   2618:     $helper->declareVar('probstatus');   
1.156     bowersj2 2619:     $helper->declareVar('filename');
                   2620:     $helper->declareVar('construction');
1.178     sakharuk 2621:     $helper->declareVar('assignment');
1.262     sakharuk 2622:     $helper->declareVar('style_file');
1.340     foxr     2623:     $helper->declareVar('student_sort');
1.363     foxr     2624:     $helper->declareVar('FINISHPAGE');
1.366     foxr     2625:     $helper->declareVar('PRINT_TYPE');
1.372     foxr     2626:     $helper->declareVar("showallfoils");
1.483     foxr     2627:     $helper->declareVar("STUDENTS");
1.363     foxr     2628: 
1.518     foxr     2629: 
                   2630:    
                   2631: 
                   2632: 
1.363     foxr     2633:     #  The page breaks can get loaded initially from the course environment:
1.394     foxr     2634:     # But we only do this in the initial state so that they are allowed to change.
                   2635:     #
1.366     foxr     2636: 
1.416     foxr     2637:     # $helper->{VARS}->{FINISHPAGE} = '';
1.363     foxr     2638:     
                   2639:     &Apache::loncommon::restore_course_settings('print',
1.366     foxr     2640: 						{'pagebreaks'  => 'scalar',
                   2641: 					         'lastprinttype' => 'scalar'});
                   2642:     
1.483     foxr     2643:     # This will persistently load in the data we want from the
                   2644:     # very first screen.
1.394     foxr     2645:     
                   2646:     if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
                   2647: 	if (!defined ($env{"form.CURRENT_STATE"})) {
                   2648: 	    
                   2649: 	    $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
                   2650: 	} else {
                   2651: 	    my $state = $env{"form.CURRENT_STATE"};
                   2652: 	    if ($state eq "START") {
                   2653: 		$helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
                   2654: 	    }
                   2655: 	}
                   2656: 	
1.366     foxr     2657:     }
1.481     albertel 2658: 
1.156     bowersj2 2659:     # Detect whether we're coming from construction space
1.373     albertel 2660:     if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235     bowersj2 2661:         $helper->{VARS}->{'filename'} = "~$1/$2";
1.156     bowersj2 2662:         $helper->{VARS}->{'construction'} = 1;
1.481     albertel 2663:     } else {
1.373     albertel 2664:         if ($env{'form.postdata'}) {
                   2665:             $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482     albertel 2666: 	    if ( $helper->{VARS}->{'symb'} eq '') {
                   2667: 		$helper->{VARS}->{'postdata'} = $env{'form.postdata'};
                   2668: 	    }
1.156     bowersj2 2669:         }
1.373     albertel 2670:         if ($env{'form.symb'}) {
                   2671:             $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156     bowersj2 2672:         }
1.373     albertel 2673:         if ($env{'form.url'}) {
1.156     bowersj2 2674:             $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
                   2675:         }
1.416     foxr     2676: 
1.157     bowersj2 2677:     }
1.481     albertel 2678: 
1.373     albertel 2679:     if ($env{'form.symb'}) {
                   2680:         $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146     bowersj2 2681:     }
1.373     albertel 2682:     if ($env{'form.url'}) {
1.140     sakharuk 2683:         $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153     sakharuk 2684: 
1.140     sakharuk 2685:     }
1.343     albertel 2686:     $helper->{VARS}->{'symb'}=
                   2687: 	&Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335     albertel 2688:     my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178     sakharuk 2689:     if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481     albertel 2690: 
1.156     bowersj2 2691:     
1.146     bowersj2 2692:     # Extract map
                   2693:     my $symb = $helper->{VARS}->{'symb'};
1.156     bowersj2 2694:     my ($map, $id, $url);
                   2695:     my $subdir;
1.483     foxr     2696:     my $is_published=0;		# True when printing from resource space.
1.156     bowersj2 2697: 
                   2698:     # Get the resource name from construction space
                   2699:     if ($helper->{VARS}->{'construction'}) {
                   2700:         $resourceTitle = substr($helper->{VARS}->{'filename'}, 
                   2701:                                 rindex($helper->{VARS}->{'filename'}, '/')+1);
                   2702:         $subdir = substr($helper->{VARS}->{'filename'},
                   2703:                          0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481     albertel 2704:     } else {
1.482     albertel 2705: 	if ($symb ne '') {
                   2706: 	    ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
                   2707: 	    $helper->{VARS}->{'postdata'} = 
                   2708: 		&Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
                   2709: 	} else {
                   2710: 	    $url = $helper->{VARS}->{'postdata'};
1.483     foxr     2711: 	    $is_published=1;	# From resource space.
1.482     albertel 2712: 	}
                   2713: 	$url = &Apache::lonnet::clutter($url);
1.481     albertel 2714: 
1.156     bowersj2 2715:         if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238     bowersj2 2716:             my $postdata = $helper->{VARS}->{'postdata'};
                   2717:             $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156     bowersj2 2718:         }
                   2719:         $subdir = &Apache::lonnet::filelocation("", $url);
1.128     bowersj2 2720:     }
1.373     albertel 2721:     if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
                   2722: 	$helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230     albertel 2723:     }
1.373     albertel 2724:     if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
1.512     foxr     2725: 	$helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
1.290     sakharuk 2726:     }
1.115     bowersj2 2727: 
1.192     bowersj2 2728:     my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
                   2729: 
1.481     albertel 2730:     Apache::lonhelper::registerHelperTags();
1.119     bowersj2 2731: 
1.131     bowersj2 2732:     # "Delete everything after the last slash."
1.119     bowersj2 2733:     $subdir =~ s|/[^/]+$||;
                   2734: 
1.131     bowersj2 2735:     # What can be printed is a very dynamic decision based on
                   2736:     # lots of factors. So we need to dynamically build this list.
                   2737:     # To prevent security leaks, states are only added to the wizard
                   2738:     # if they can be reached, which ensures manipulating the form input
                   2739:     # won't allow anyone to reach states they shouldn't have permission
                   2740:     # to reach.
                   2741: 
                   2742:     # printChoices is tracking the kind of printing the user can
                   2743:     # do, and will be used in a choices construction later.
                   2744:     # In the meantime we will be adding states and elements to
                   2745:     # the helper by hand.
                   2746:     my $printChoices = [];
                   2747:     my $paramHash;
1.130     sakharuk 2748: 
1.240     albertel 2749:     if ($resourceTitle) {
1.458     www      2750:         push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156     bowersj2 2751:     }
                   2752: 
1.238     bowersj2 2753:     # Useful filter strings
1.540     raeburn  2754:     my $isProblem = '($res->is_problem()||$res->contains_problem||$res->is_practice()) ';
1.238     bowersj2 2755:     $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.541     raeburn  2756:     my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice()';
1.287     albertel 2757:     my $isNotMap = '!$res->is_sequence()';
1.238     bowersj2 2758:     $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
                   2759:     my $isMap = '$res->is_map()';
1.342     albertel 2760:     my $symbFilter = '$res->shown_symb()';
                   2761:     my $urlValue = '$res->link()';
1.238     bowersj2 2762: 
                   2763:     $helper->declareVar('SEQUENCE');
                   2764: 
1.465     albertel 2765:     # If we're in a sequence...
1.416     foxr     2766: 
1.465     albertel 2767:     my $start_new_option;
                   2768:     if ($perm{'pav'}) {
                   2769: 	$start_new_option = 
                   2770: 	    "<option text='".&mt('Start new page<br />before selected').
                   2771: 	    "' variable='FINISHPAGE' />";
                   2772:     }
1.238     bowersj2 2773: 
1.483     foxr     2774:     if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
1.243     bowersj2 2775: 	$helper->{VARS}->{'postdata'} &&
                   2776: 	$helper->{VARS}->{'assignment'}) {
1.131     bowersj2 2777:         # Allow problems from sequence
1.546     bisitz   2778:         push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'), 'map_problems', 'CHOOSE_PROBLEMS'];
1.131     bowersj2 2779:         # Allow all resources from sequence
1.546     bisitz   2780:         push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'), 'map_problems_pages', 'CHOOSE_PROBLEMS_HTML'];
1.465     albertel 2781: 
1.131     bowersj2 2782:         my $helperFragment = <<HELPERFRAGMENT;
1.155     sakharuk 2783:   <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print">
1.435     foxr     2784:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 2785:               closeallpages="1">
1.144     bowersj2 2786:       <nextstate>PAGESIZE</nextstate>
1.435     foxr     2787:       <filterfunc>return $isProblem;</filterfunc>
1.131     bowersj2 2788:       <mapurl>$map</mapurl>
1.238     bowersj2 2789:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2790:       $start_new_option
1.131     bowersj2 2791:       </resource>
                   2792:     </state>
                   2793: 
1.155     sakharuk 2794:   <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print">
1.435     foxr     2795:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 2796:               closeallpages="1">
1.144     bowersj2 2797:       <nextstate>PAGESIZE</nextstate>
1.435     foxr     2798:       <filterfunc>return $isNotMap;</filterfunc>
1.131     bowersj2 2799:       <mapurl>$map</mapurl>
1.238     bowersj2 2800:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2801:       $start_new_option
1.131     bowersj2 2802:       </resource>
                   2803:     </state>
                   2804: HELPERFRAGMENT
1.121     bowersj2 2805: 
1.326     sakharuk 2806: 	&Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121     bowersj2 2807:     }
                   2808: 
1.546     bisitz   2809:     # If the user has pfo (print for others) allow them to print all 
                   2810:     # problems and resources  in the entire course, optionally for selected students
1.483     foxr     2811:     if ($perm{'pfo'} &&  !$is_published  &&
1.481     albertel 2812:         ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) { 
                   2813: 
1.509     albertel 2814:         push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
                   2815: 	push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.536     foxr     2816: 	push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b> for <b>selected people</b>'), 'all_problems_students', 'ALL_PROBLEMS_STUDENTS'];
1.284     albertel 2817:          &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS);
1.155     sakharuk 2818:   <state name="ALL_PROBLEMS" title="Select Problem(s) to print">
1.287     albertel 2819:     <resource variable="RESOURCES" toponly='0' multichoice="1"
                   2820: 	suppressEmptySequences='0' addstatus="1" closeallpages="1">
1.144     bowersj2 2821:       <nextstate>PAGESIZE</nextstate>
1.192     bowersj2 2822:       <filterfunc>return $isProblemOrMap;</filterfunc>
1.287     albertel 2823:       <choicefunc>return $isNotMap;</choicefunc>
1.238     bowersj2 2824:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2825:       $start_new_option
1.284     albertel 2826:     </resource>
                   2827:   </state>
1.354     foxr     2828:   <state name="ALL_RESOURCES" title="Select Resource(s) to print">
                   2829:     <resource variable="RESOURCES" toponly='0' multichoice='1'
                   2830:               suppressEmptySequences='0' addstatus='1' closeallpages='1'>
                   2831:       <nextstate>PAGESIZE</nextstate>
                   2832:       <filterfunc>return $isNotMap; </filterfunc>
                   2833:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2834:       $start_new_option
1.354     foxr     2835:     </resource>
                   2836:   </state>
1.536     foxr     2837:   <state name="ALL_PROBLEMS_STUDENTS" title="Select Problem(s) to print">
                   2838:     <resource variable="RESOURCES" toponly='0' multichoice="1"
                   2839: 	suppressEmptySequences='0' addstatus="1" closeallpages="1">
                   2840:       <nextstate>STUDENTS1</nextstate>
                   2841:       <filterfunc>return $isProblemOrMap;</filterfunc>
                   2842:       <choicefunc>return $isNotMap;</choicefunc>
                   2843:       <valuefunc>return $symbFilter;</valuefunc>
                   2844:       $start_new_option
                   2845:     </resource>
                   2846:   </state>
                   2847:   <state name="STUDENTS1" title="Select People">
                   2848:       <message><b>Select sorting order of printout</b> </message>
                   2849:     <choices variable='student_sort'>
                   2850:       <choice computer='0'>Sort by section then student</choice>
                   2851:       <choice computer='1'>Sort by students across sections.</choice>
                   2852:     </choices>
                   2853:       <message><br /><hr /><br /> </message>
                   2854:       <student multichoice='1' variable="STUDENTS" nextstate="PRINT_FORMATTING" coursepersonnel="1"/>
                   2855:   </state>
                   2856: 
1.284     albertel 2857: ALL_PROBLEMS
1.132     bowersj2 2858: 
1.284     albertel 2859: 	if ($helper->{VARS}->{'assignment'}) {
1.546     bisitz   2860: 	    push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]selected people[_5]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 'problems_for_students', 'CHOOSE_STUDENTS'];
                   2861: 	    push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]CODEd assignments[_5]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 'problems_for_anon', 'CHOOSE_ANON1'];
1.284     albertel 2862: 	}
1.424     foxr     2863: 
1.507     albertel 2864: 	my $randomly_ordered_warning = 
                   2865: 	    &get_randomly_ordered_warning($helper,$map);
                   2866: 
1.424     foxr     2867: 	# resource_selector will hold a few states that:
                   2868: 	#   - Allow resources to be selected for printing.
                   2869: 	#   - Determine pagination between assignments.
                   2870: 	#   - Determine how many assignments should be bundled into a single PDF.
                   2871:         # TODO:
                   2872: 	#    Probably good to do things like separate this up into several vars, each
                   2873: 	#    with one state, and use REGEXPs at inclusion time to set state names
                   2874: 	#    and next states for better mix and match capability
                   2875: 	#
1.284     albertel 2876: 	my $resource_selector=<<RESOURCE_SELECTOR;
1.424     foxr     2877:     <state name="SELECT_PROBLEMS" title="Select resources to print">
1.507     albertel 2878:     $randomly_ordered_warning
                   2879: 
1.424     foxr     2880:    <nextstate>PRINT_FORMATTING</nextstate> 
1.284     albertel 2881:    <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287     albertel 2882:     <resource variable="RESOURCES" multichoice="1" addstatus="1" 
                   2883:               closeallpages="1">
1.254     sakharuk 2884:       <filterfunc>return $isProblem;</filterfunc>
1.148     bowersj2 2885:       <mapurl>$map</mapurl>
1.254     sakharuk 2886:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2887:       $start_new_option
1.147     bowersj2 2888:       </resource>
1.424     foxr     2889:     </state>
                   2890:     <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155     sakharuk 2891:     <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149     bowersj2 2892:     <choices variable="EMPTY_PAGES">
1.204     sakharuk 2893:       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
                   2894:       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
                   2895:       <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
                   2896:       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284     albertel 2897:     </choices>
1.424     foxr     2898:     <nextstate>PAGESIZE</nextstate>
1.429     foxr     2899:     <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
                   2900:     <choices variable="SPLIT_PDFS">
                   2901:        <choice computer="all">All assignments in a single PDF file</choice>
                   2902:        <choice computer="sections">Each PDF contains exactly one section</choice>
                   2903:        <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449     albertel 2904:        <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
                   2905:             Specify the number of assignments per PDF:</choice>
1.429     foxr     2906:     </choices>
1.424     foxr     2907:     </state>
1.284     albertel 2908: RESOURCE_SELECTOR
                   2909: 
                   2910:         &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS);
                   2911:   <state name="CHOOSE_STUDENTS" title="Select Students and Resources">
1.485     albertel 2912:       <message><b>Select sorting order of printout</b> </message>
1.340     foxr     2913:     <choices variable='student_sort'>
                   2914:       <choice computer='0'>Sort by section then student</choice>
                   2915:       <choice computer='1'>Sort by students across sections.</choice>
                   2916:     </choices>
1.437     foxr     2917:       <message><br /><hr /><br /> </message>
1.425     foxr     2918:       <student multichoice='1' variable="STUDENTS" nextstate="SELECT_PROBLEMS" coursepersonnel="1"/>
1.424     foxr     2919:   </state>
1.284     albertel 2920:     $resource_selector
1.131     bowersj2 2921: CHOOSE_STUDENTS
1.292     albertel 2922: 
1.373     albertel 2923: 	my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2924: 	my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292     albertel 2925:         my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
                   2926: 	my $namechoice='<choice></choice>';
1.337     albertel 2927: 	foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294     albertel 2928: 	    if ($name =~ /^error: 2 /) { next; }
1.381     albertel 2929: 	    if ($name =~ /^type\0/) { next; }
1.292     albertel 2930: 	    $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
                   2931: 	}
1.389     foxr     2932: 
                   2933: 
                   2934: 	my %code_values;
1.405     albertel 2935: 	my %codes_to_print;
1.411     albertel 2936: 	foreach my $key (@names) {
1.389     foxr     2937: 	    %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405     albertel 2938: 	    foreach my $key (keys(%code_values)) {
                   2939: 		$codes_to_print{$key} = 1;
1.388     foxr     2940: 	    }
                   2941: 	}
1.389     foxr     2942: 
1.452     albertel 2943: 	my $code_selection;
1.405     albertel 2944: 	foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389     foxr     2945: 	    my $choice  = $code;
                   2946: 	    if ($code =~ /^[A-Z]+$/) { # Alpha code
                   2947: 		$choice = &letters_to_num($code);
                   2948: 	    }
1.432     albertel 2949: 	    push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388     foxr     2950: 	}
1.436     albertel 2951: 	if (%codes_to_print) {
                   2952: 	    $code_selection .='   
1.472     albertel 2953: 	    <message><b>Choose single CODE from list:</b></message>
1.448     albertel 2954: 		<message></td><td></message>
1.452     albertel 2955: 		<dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
                   2956:                   <choice></choice>
1.448     albertel 2957:                   <exec>
                   2958:                      push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
                   2959:                   </exec>
1.452     albertel 2960: 		</dropdown>
1.468     foxr     2961: 	    <message></td></tr><tr><td></message>
1.436     albertel 2962:             '.$/;
1.448     albertel 2963: 
1.436     albertel 2964: 	}
1.432     albertel 2965: 
1.542     raeburn  2966:         my @lines = &Apache::grades::get_scantronformat_file();
1.381     albertel 2967: 	my $codechoice='';
1.542     raeburn  2968: 	foreach my $line (@lines) {
1.381     albertel 2969: 	    my ($name,$description,$code_type,$code_length)=
                   2970: 		(split(/:/,$line))[0,1,2,4];
                   2971: 	    if ($code_length > 0 && 
                   2972: 		$code_type =~/^(letter|number|-1)/) {
                   2973: 		$codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
                   2974: 	    }
                   2975: 	}
                   2976: 	if ($codechoice eq '') {
                   2977: 	    $codechoice='<choice computer="default">Default</choice>';
                   2978: 	}
1.284     albertel 2979:         &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1);
1.468     foxr     2980:   <state name="CHOOSE_ANON1" title="Specify CODEd Assignments">
1.424     foxr     2981:     <nextstate>SELECT_PROBLEMS</nextstate>
1.468     foxr     2982:     <message><h4>Fill out one of the forms below</h4></message>
                   2983:     <message><br /><hr /> <br /></message>
                   2984:     <message><h3>Generate new CODEd Assignments</h3></message>
                   2985:     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362     albertel 2986:     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
                   2987:        <validator>
                   2988: 	if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.382     foxr     2989: 	    !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
1.388     foxr     2990:             !\$helper->{'VARS'}{'SINGLE_CODE'}                    &&
                   2991: 	    !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362     albertel 2992: 	    return "You need to specify the number of assignments to print";
                   2993: 	}
                   2994: 	return undef;
                   2995:        </validator>
                   2996:     </string>
                   2997:     <message></td></tr><tr><td></message>
1.501     albertel 2998:     <message><b>Names to save the CODEs under for later:</b></message>
1.412     albertel 2999:     <message></td><td></message>
                   3000:     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
                   3001:     <message></td></tr><tr><td></message>
                   3002:     <message><b>Bubble sheet type:</b></message>
                   3003:     <message></td><td></message>
                   3004:     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
                   3005:     $codechoice
                   3006:     </dropdown>
1.468     foxr     3007:     <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>
                   3008:     <message></td></tr><tr><td></table></message>
1.472     albertel 3009:     <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
1.468     foxr     3010:     <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412     albertel 3011:     <string variable="SINGLE_CODE" size="10">
1.382     foxr     3012:         <validator>
                   3013: 	   if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&
1.388     foxr     3014: 	      !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&
                   3015: 	      !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.382     foxr     3016: 	      return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
                   3017: 						      \$helper->{'VARS'}{'CODE_OPTION'});
                   3018: 	   } else {
                   3019: 	       return undef;	# Other forces control us.
                   3020: 	   }
                   3021:         </validator>
                   3022:     </string>
1.472     albertel 3023:     <message></td></tr><tr><td></message>
1.432     albertel 3024:         $code_selection
1.468     foxr     3025:     <message></td></tr></table></message>
1.472     albertel 3026:     <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
1.468     foxr     3027:     <message><b>Select saved CODEs:</b></message>
1.381     albertel 3028:     <message></td><td></message>
1.292     albertel 3029:     <dropdown variable="REUSE_OLD_CODES">
                   3030:         $namechoice
                   3031:     </dropdown>
1.412     albertel 3032:     <message></td></tr></table></message>
1.284     albertel 3033:   </state>
1.424     foxr     3034:   $resource_selector
1.284     albertel 3035: CHOOSE_ANON1
1.254     sakharuk 3036: 
1.272     sakharuk 3037: 
1.254     sakharuk 3038: 	if ($helper->{VARS}->{'assignment'}) {
1.546     bisitz   3039: 	    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'];
                   3040: 	    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'];
1.254     sakharuk 3041: 	}
1.284     albertel 3042: 	    
                   3043: 
                   3044: 	$resource_selector=<<RESOURCE_SELECTOR;
1.424     foxr     3045:     <state name="SELECT_RESOURCES" title="Select Resources">
1.507     albertel 3046:     $randomly_ordered_warning
                   3047: 
1.424     foxr     3048:     <nextstate>PRINT_FORMATTING</nextstate>
1.254     sakharuk 3049:     <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287     albertel 3050:     <resource variable="RESOURCES" multichoice="1" addstatus="1" 
                   3051:               closeallpages="1">
1.254     sakharuk 3052:       <filterfunc>return $isNotMap;</filterfunc>
                   3053:       <mapurl>$map</mapurl>
                   3054:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 3055:       $start_new_option
1.254     sakharuk 3056:       </resource>
1.424     foxr     3057:     </state>
                   3058:     <state name="PRINT_FORMATTING" title="Format of the print job">
                   3059:     <nextstate>NUMBER_PER_PDF</nextstate>
1.254     sakharuk 3060:     <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
                   3061:     <choices variable="EMPTY_PAGES">
                   3062:       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
                   3063:       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
                   3064:       <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
                   3065:       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284     albertel 3066:     </choices>
1.424     foxr     3067:     <nextstate>PAGESIZE</nextstate>
1.429     foxr     3068:     <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
                   3069:     <choices variable="SPLIT_PDFS">
                   3070:        <choice computer="all">All assignments in a single PDF file</choice>
                   3071:        <choice computer="sections">Each PDF contains exactly one section</choice>
                   3072:        <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449     albertel 3073:        <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
                   3074:            Specify the number of assignments per PDF:</choice>
1.429     foxr     3075:     </choices>
1.424     foxr     3076:     </state>
1.284     albertel 3077: RESOURCE_SELECTOR
                   3078: 
                   3079: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
                   3080:   <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340     foxr     3081:     <choices variable='student_sort'>
                   3082:       <choice computer='0'>Sort by section then student</choice>
                   3083:       <choice computer='1'>Sort by students across sections.</choice>
                   3084:     </choices>
1.437     foxr     3085:     <message><br /><hr /><br /></message>
1.426     foxr     3086:     <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340     foxr     3087: 
1.424     foxr     3088:     </state>
1.284     albertel 3089:     $resource_selector
1.254     sakharuk 3090: CHOOSE_STUDENTS1
                   3091: 
1.284     albertel 3092: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472     albertel 3093:   <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424     foxr     3094:     <nextstate>SELECT_RESOURCES</nextstate>
1.472     albertel 3095:     <message><h4>Fill out one of the forms below</h4></message>
                   3096:     <message><br /><hr /> <br /></message>
                   3097:     <message><h3>Generate new CODEd Assignments</h3></message>
                   3098:     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362     albertel 3099:     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
                   3100:        <validator>
                   3101: 	if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386     foxr     3102: 	    !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
1.388     foxr     3103: 	    !\$helper->{'VARS'}{'SINGLE_CODE'}                   &&
                   3104: 	    !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362     albertel 3105: 	    return "You need to specify the number of assignments to print";
                   3106: 	}
                   3107: 	return undef;
                   3108:        </validator>
                   3109:     </string>
                   3110:     <message></td></tr><tr><td></message>
1.501     albertel 3111:     <message><b>Names to save the CODEs under for later:</b></message>
1.412     albertel 3112:     <message></td><td></message>
                   3113:     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
                   3114:     <message></td></tr><tr><td></message>
                   3115:     <message><b>Bubble sheet type:</b></message>
                   3116:     <message></td><td></message>
                   3117:     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
                   3118:     $codechoice
                   3119:     </dropdown>
1.472     albertel 3120:     <message></td></tr><tr><td></table></message>
                   3121:     <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
                   3122:     <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412     albertel 3123:     <string variable="SINGLE_CODE" size="10">
1.386     foxr     3124:         <validator>
                   3125: 	   if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&
1.388     foxr     3126: 	      !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&
                   3127: 	      !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386     foxr     3128: 	      return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
                   3129: 						      \$helper->{'VARS'}{'CODE_OPTION'});
                   3130: 	   } else {
                   3131: 	       return undef;	# Other forces control us.
                   3132: 	   }
                   3133:         </validator>
                   3134:     </string>
1.472     albertel 3135:     <message></td></tr><tr><td></message>
1.432     albertel 3136:         $code_selection
1.472     albertel 3137:     <message></td></tr></table></message>
                   3138:     <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
                   3139:     <message><b>Select saved CODEs:</b></message>
1.381     albertel 3140:     <message></td><td></message>
1.294     albertel 3141:     <dropdown variable="REUSE_OLD_CODES">
                   3142:         $namechoice
                   3143:     </dropdown>
1.412     albertel 3144:     <message></td></tr></table></message>
1.424     foxr     3145:   </state>
1.284     albertel 3146:     $resource_selector
                   3147: CHOOSE_ANON2
1.481     albertel 3148:     }
                   3149: 
1.121     bowersj2 3150:     # FIXME: That RE should come from a library somewhere.
1.483     foxr     3151:     if (($perm{'pav'} 
1.482     albertel 3152: 	&& $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
                   3153: 	&& (defined($helper->{'VARS'}->{'construction'})
                   3154: 	    ||
                   3155: 	    (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
                   3156: 	     && 
                   3157: 	     $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483     foxr     3158: 	    )) 
                   3159: 	&& $helper->{VARS}->{'assignment'} eq ""
1.482     albertel 3160: 	) {
1.238     bowersj2 3161: 
1.482     albertel 3162: 	my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
1.546     bisitz   3163:         push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from current subdirectory [_3]','<b>','</b>','<b><i>'.$pretty_dir.'</i></b>','<b>','</b>'), 'problems_from_directory', 'CHOOSE_FROM_SUBDIR'];
1.139     bowersj2 3164:         my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482     albertel 3165:   <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458     www      3166: 
1.138     bowersj2 3167:     <files variable="FILES" multichoice='1'>
1.144     bowersj2 3168:       <nextstate>PAGESIZE</nextstate>
1.138     bowersj2 3169:       <filechoice>return '$subdir';</filechoice>
1.139     bowersj2 3170: CHOOSE_FROM_SUBDIR
                   3171:         
1.238     bowersj2 3172:         # this is broken up because I really want interpolation above,
                   3173:         # and I really DON'T want it below
1.139     bowersj2 3174:         $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225     bowersj2 3175:       <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
                   3176: 	  $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131     bowersj2 3177:       </filefilter>
1.138     bowersj2 3178:       </files>
1.131     bowersj2 3179:     </state>
                   3180: CHOOSE_FROM_SUBDIR
1.139     bowersj2 3181:         &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131     bowersj2 3182:     }
1.238     bowersj2 3183: 
                   3184:     # Allow the user to select any sequence in the course, feed it to
                   3185:     # another resource selector for that sequence
1.483     foxr     3186:     if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509     albertel 3187: 	push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249     sakharuk 3188: 			      'select_sequences', 'CHOOSE_SEQUENCE'];
1.244     bowersj2 3189: 	my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
                   3190: 	#Escape apostrophes and backslashes for Perl
                   3191: 	$escapedSequenceName =~ s/\\/\\\\/g;
                   3192: 	$escapedSequenceName =~ s/'/\\'/g;
1.239     bowersj2 3193: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238     bowersj2 3194:   <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
                   3195:     <message>Select the sequence to print resources from:</message>
                   3196:     <resource variable="SEQUENCE">
                   3197:       <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
                   3198:       <filterfunc>return \$res->is_sequence;</filterfunc>
                   3199:       <valuefunc>return $urlValue;</valuefunc>
1.447     foxr     3200:       <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391     foxr     3201: 	</choicefunc>
1.238     bowersj2 3202:       </resource>
                   3203:     </state>
                   3204:   <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
                   3205:     <message>(mark desired resources then click "next" button) <br /></message>
1.435     foxr     3206:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 3207:               closeallpages="1">
1.238     bowersj2 3208:       <nextstate>PAGESIZE</nextstate>
1.466     albertel 3209:       <filterfunc>return $isNotMap</filterfunc>
1.244     bowersj2 3210:       <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238     bowersj2 3211:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 3212:       $start_new_option
1.238     bowersj2 3213:       </resource>
                   3214:     </state>
                   3215: CHOOSE_FROM_ANY_SEQUENCE
1.239     bowersj2 3216: }
1.481     albertel 3217: 
1.131     bowersj2 3218:     # Generate the first state, to select which resources get printed.
1.223     bowersj2 3219:     Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131     bowersj2 3220:     $paramHash = Apache::lonhelper::getParamHash();
1.155     sakharuk 3221:     $paramHash->{MESSAGE_TEXT} = "";
1.131     bowersj2 3222:     Apache::lonhelper::message->new();
                   3223:     $paramHash = Apache::lonhelper::getParamHash();
                   3224:     $paramHash->{'variable'} = 'PRINT_TYPE';
                   3225:     $paramHash->{CHOICES} = $printChoices;
                   3226:     Apache::lonhelper::choices->new();
1.161     bowersj2 3227: 
1.223     bowersj2 3228:     my $startedTable = 0; # have we started an HTML table yet? (need
                   3229:                           # to close it later)
                   3230: 
1.397     albertel 3231:     if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or 
1.170     sakharuk 3232: 	($helper->{VARS}->{'construction'} eq '1')) {
1.544     bisitz   3233: 	&addMessage('<br />'
                   3234:                    .'<h3>'.&mt('Print Options').'</h3>'
                   3235:                    .&Apache::lonhtmlcommon::start_pick_box()
                   3236: #                  .&Apache::lonhtmlcommon::row_headline()
                   3237: #                  .'<h3>'.&mt('Print Options').'</h3>'
                   3238: #                  .&Apache::lonhtmlcommon::row_closure()
                   3239:                    .&Apache::lonhtmlcommon::row_title(
                   3240:                        '<label for="ANSWER_TYPE_forminput">'
                   3241:                       .&mt('Print Answers')
                   3242:                       .'</label>'
                   3243:                     )
                   3244:         );
1.161     bowersj2 3245:         $paramHash = Apache::lonhelper::getParamHash();
1.162     sakharuk 3246: 	$paramHash->{'variable'} = 'ANSWER_TYPE';   
                   3247: 	$helper->declareVar('ANSWER_TYPE');         
1.161     bowersj2 3248:         $paramHash->{CHOICES} = [
1.242     sakharuk 3249:                                    ['Without Answers', 'yes'],
                   3250:                                    ['With Answers', 'no'],
1.368     albertel 3251:                                    ['Only Answers', 'only']
1.289     sakharuk 3252:                                 ];
1.210     sakharuk 3253:         Apache::lonhelper::dropdown->new();
1.544     bisitz   3254: 	&addMessage(&Apache::lonhtmlcommon::row_closure());
1.223     bowersj2 3255: 	$startedTable = 1;
1.161     bowersj2 3256:     }
1.209     sakharuk 3257: 
1.397     albertel 3258:     if ($perm{'pav'}) {
1.223     bowersj2 3259: 	if (!$startedTable) {
1.497     www      3260: 	    addMessage("<hr width='33%' /><table><tr><td align='right'>".
                   3261:                        '<label for="LATEX_TYPE_forminput">'.
                   3262:                        &mt('LaTeX mode').
                   3263:                        "</label>: </td><td>");
1.223     bowersj2 3264: 	    $startedTable = 1;
                   3265: 	} else {
1.544     bisitz   3266: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   3267:                            '<label for="LATEX_TYPE_forminput">'
                   3268:                            .&mt('LaTeX mode')
                   3269:                            .'</label>'
                   3270:                         )
                   3271:             );
1.223     bowersj2 3272: 	}
1.203     sakharuk 3273:         $paramHash = Apache::lonhelper::getParamHash();
                   3274: 	$paramHash->{'variable'} = 'LATEX_TYPE';   
                   3275: 	$helper->declareVar('LATEX_TYPE');  
                   3276: 	if ($helper->{VARS}->{'construction'} eq '1') {       
                   3277: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 3278: 				     ['standard LaTeX mode', 'standard'], 
                   3279: 				     ['LaTeX batchmode', 'batchmode'], ];
1.203     sakharuk 3280: 	} else {
                   3281: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 3282: 				     ['LaTeX batchmode', 'batchmode'],
                   3283: 				     ['standard LaTeX mode', 'standard'] ];
1.203     sakharuk 3284: 	}
1.210     sakharuk 3285:         Apache::lonhelper::dropdown->new();
1.218     sakharuk 3286:  
1.544     bisitz   3287: 	&addMessage(&Apache::lonhtmlcommon::row_closure()
                   3288:                    .&Apache::lonhtmlcommon::row_title(
                   3289:                         '<label for="TABLE_CONTENTS_forminput">'
                   3290:                        .&mt('Print Table of Contents')
                   3291:                        .'</label>'
                   3292:                     )
                   3293:         );
1.209     sakharuk 3294:         $paramHash = Apache::lonhelper::getParamHash();
                   3295: 	$paramHash->{'variable'} = 'TABLE_CONTENTS';   
                   3296: 	$helper->declareVar('TABLE_CONTENTS');         
                   3297:         $paramHash->{CHOICES} = [
1.223     bowersj2 3298:                                    ['No', 'no'],
                   3299:                                    ['Yes', 'yes'] ];
1.210     sakharuk 3300:         Apache::lonhelper::dropdown->new();
1.544     bisitz   3301: 	&addMessage(&Apache::lonhtmlcommon::row_closure());
1.214     sakharuk 3302:         
1.220     sakharuk 3303: 	if (not $helper->{VARS}->{'construction'}) {
1.545     bisitz   3304: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   3305:                             '<label for="TABLE_INDEX_forminput">'
                   3306:                            .&mt('Print Index')
                   3307:                            .'</label>'
                   3308:                         )
                   3309:             );
1.220     sakharuk 3310: 	    $paramHash = Apache::lonhelper::getParamHash();
                   3311: 	    $paramHash->{'variable'} = 'TABLE_INDEX';   
                   3312: 	    $helper->declareVar('TABLE_INDEX');         
                   3313: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 3314: 				     ['No', 'no'],
                   3315: 				     ['Yes', 'yes'] ];
1.220     sakharuk 3316: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   3317:             &addMessage(&Apache::lonhtmlcommon::row_closure());
                   3318:             &addMessage(&Apache::lonhtmlcommon::row_title(
                   3319:                             '<label for="PRINT_DISCUSSIONS_forminput">'
                   3320:                            .&mt('Print Discussions')
                   3321:                            .'</label>'
                   3322:                         )
                   3323:             );
1.309     sakharuk 3324: 	    $paramHash = Apache::lonhelper::getParamHash();
                   3325: 	    $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';   
                   3326: 	    $helper->declareVar('PRINT_DISCUSSIONS');         
                   3327: 	    $paramHash->{CHOICES} = [
                   3328: 				     ['No', 'no'],
                   3329: 				     ['Yes', 'yes'] ];
                   3330: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   3331:             &addMessage(&Apache::lonhtmlcommon::row_closure());
1.372     foxr     3332: 
1.511     foxr     3333: 	    # Prompt for printing annotations too.
                   3334: 		
1.545     bisitz   3335: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   3336:                             '<label for="PRINT_ANNOTATIONS_forminput">'
                   3337:                            .&mt('Print Annotations')
                   3338:                            .'</label>'
                   3339:                         )
                   3340:             );
1.511     foxr     3341: 	    $paramHash = Apache::lonhelper::getParamHash();
                   3342: 	    $paramHash->{'variable'} = "PRINT_ANNOTATIONS";
                   3343: 	    $helper->declareVar("PRINT_ANNOTATIONS");
                   3344: 	    $paramHash->{CHOICES} = [
                   3345: 				     ['No', 'no'],
                   3346: 				     ['Yes', 'yes']];
                   3347: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   3348:             &addMessage(&Apache::lonhtmlcommon::row_closure());
1.511     foxr     3349: 
1.545     bisitz   3350:             &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Foils')));
1.397     albertel 3351: 	    $paramHash = Apache::lonhelper::getParamHash();
                   3352: 	    $paramHash->{'multichoice'} = "true";
                   3353: 	    $paramHash->{'allowempty'}  = "true";
                   3354: 	    $paramHash->{'variable'}   = "showallfoils";
                   3355: 	    $paramHash->{'CHOICES'} = [ ["Show all foils", "1"] ];
                   3356: 	    Apache::lonhelper::choices->new();
1.545     bisitz   3357:             &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.220     sakharuk 3358: 	}
1.219     sakharuk 3359: 
1.230     albertel 3360: 	if ($helper->{'VARS'}->{'construction'}) { 
1.505     albertel 3361: 	    my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497     www      3362:             my $randseedtext=&mt("Use random seed");
                   3363:             my $stylefiletext=&mt("Use style file");
1.506     albertel 3364:             my $selectfiletext=&mt("Select style file");
1.497     www      3365: 
1.544     bisitz   3366: 	    my $xmlfrag .= '<message>'
                   3367:             .&Apache::lonhtmlcommon::row_title('<label for="curseed_forminput">'
                   3368:                                               .$randseedtext
                   3369:                                               .'</label>'
                   3370:              )
                   3371:             .'</message>
                   3372:             <string variable="curseed" size="15" maxlength="15">
                   3373:                 <defaultvalue>
                   3374:                    return '.$helper->{VARS}->{'curseed'}.';
                   3375:                 </defaultvalue>'
                   3376:             .'</string>'
                   3377:             .'<message>'
                   3378:             .&Apache::lonhtmlcommon::row_closure()
                   3379:             .&Apache::lonhtmlcommon::row_title('<label for="style_file">'
                   3380:                                               .$stylefiletext
                   3381:                                               .'</label>'
                   3382:              )
                   3383:             .'</message>
1.504     albertel 3384:              <string variable="style_file" size="40">
1.544     bisitz   3385:                 <defaultvalue>
                   3386:                     return '.$stylevalue.';
                   3387:                 </defaultvalue>
                   3388:              </string><message>&nbsp;'
                   3389: .qq|<a href="javascript:openbrowser('helpform','style_file_forminput','sty')">|
                   3390: .$selectfiletext.'</a>'
                   3391:             .&Apache::lonhtmlcommon::row_closure()
                   3392:             .&Apache::lonhtmlcommon::row_title(&mt('Show all foils'))
                   3393:             .'</message>
1.371     foxr     3394: 	     <choices allowempty="1" multichoice="true" variable="showallfoils">
1.544     bisitz   3395:                 <choice computer="1">&nbsp;</choice>
                   3396:              </choices>'
                   3397: 	    .'<message>'
                   3398:             .&Apache::lonhtmlcommon::row_closure()
                   3399:             .'</message>';
1.230     albertel 3400:             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.512     foxr     3401: 
                   3402: 
1.544     bisitz   3403:             &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Problem Type')));
1.512     foxr     3404: 	    #
                   3405: 	    # Initial value from construction space:
                   3406: 	    #
                   3407: 	    if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
                   3408: 		$helper->{VARS}->{'probstatus'} = $env{'form.problemtype'};	# initial value
                   3409: 	    }
1.518     foxr     3410: 	    $xmlfrag = << "PROBTYPE";
                   3411: 		<dropdown variable="probstatus" multichoice="0" allowempty="0">
                   3412: 		   <defaultvalue>
                   3413: 		      return "$helper->{VARS}->{'probstatus'}";
                   3414:                    </defaultvalue>
                   3415: 		   <choice computer="problem">Homework Problem</choice>
                   3416: 		   <choice computer="exam">Exam Problem</choice>
                   3417: 		   <choice computer="survey">Survey question</choice>
                   3418: 		</dropdown>
                   3419: PROBTYPE
                   3420:             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
                   3421: 	    
1.544     bisitz   3422:             &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.512     foxr     3423: 
1.544     bisitz   3424:         }
1.223     bowersj2 3425:     }
1.264     sakharuk 3426: 
                   3427: 
                   3428: 
1.218     sakharuk 3429: 
1.223     bowersj2 3430:     if ($startedTable) {
1.544     bisitz   3431:         &addMessage(&Apache::lonhtmlcommon::end_pick_box());
1.215     sakharuk 3432:     }
1.161     bowersj2 3433: 
1.131     bowersj2 3434:     Apache::lonprintout::page_format_state->new("FORMAT");
                   3435: 
1.144     bowersj2 3436:     # Generate the PAGESIZE state which will offer the user the margin
                   3437:     # choices if they select one column
                   3438:     Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
                   3439:     Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
                   3440: 
                   3441: 
1.131     bowersj2 3442:     $helper->process();
                   3443: 
1.416     foxr     3444: 
1.131     bowersj2 3445:     # MANUAL BAILOUT CONDITION:
                   3446:     # If we're in the "final" state, bailout and return to handler
                   3447:     if ($helper->{STATE} eq 'FINAL') {
                   3448:         return $helper;
                   3449:     }    
1.130     sakharuk 3450: 
1.131     bowersj2 3451:     $r->print($helper->display());
1.395     www      3452:     if ($helper->{STATE} eq 'START') {
                   3453: 	&recently_generated($r);
                   3454:     }
1.333     albertel 3455:     &Apache::lonhelper::unregisterHelperTags();
1.115     bowersj2 3456: 
                   3457:     return OK;
                   3458: }
                   3459: 
1.1       www      3460: 
                   3461: 1;
1.119     bowersj2 3462: 
                   3463: package Apache::lonprintout::page_format_state;
                   3464: 
                   3465: =pod
                   3466: 
1.131     bowersj2 3467: =head1 Helper element: page_format_state
                   3468: 
                   3469: See lonhelper.pm documentation for discussion of the helper framework.
1.119     bowersj2 3470: 
1.131     bowersj2 3471: Apache::lonprintout::page_format_state is an element that gives the 
                   3472: user an opportunity to select the page layout they wish to print 
                   3473: with: Number of columns, portrait/landscape, and paper size. If you 
                   3474: want to change the paper size choices, change the @paperSize array 
                   3475: contents in this package.
1.119     bowersj2 3476: 
1.131     bowersj2 3477: page_format_state is always directly invoked in lonprintout.pm, so there
                   3478: is no tag interface. You actually pass parameters to the constructor.
1.119     bowersj2 3479: 
                   3480: =over 4
                   3481: 
1.131     bowersj2 3482: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119     bowersj2 3483: 
                   3484: =back
                   3485: 
                   3486: =cut
                   3487: 
1.131     bowersj2 3488: use Apache::lonhelper;
1.119     bowersj2 3489: 
                   3490: no strict;
1.131     bowersj2 3491: @ISA = ("Apache::lonhelper::element");
1.119     bowersj2 3492: use strict;
1.266     sakharuk 3493: use Apache::lonlocal;
1.373     albertel 3494: use Apache::lonnet;
1.119     bowersj2 3495: 
                   3496: my $maxColumns = 2;
1.376     albertel 3497: # it'd be nice if these all worked
                   3498: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 
                   3499: #                 "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
                   3500: #                 "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]", 
                   3501: #                 "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326     sakharuk 3502: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 
1.376     albertel 3503: 		 "a4 [210x297 mm]");
1.119     bowersj2 3504: 
                   3505: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
                   3506: #                   Paper type
                   3507: 
                   3508: sub new { 
1.131     bowersj2 3509:     my $self = Apache::lonhelper::element->new();
1.119     bowersj2 3510: 
1.135     bowersj2 3511:     shift;
                   3512: 
1.131     bowersj2 3513:     $self->{'variable'} = shift;
1.134     bowersj2 3514:     my $helper = Apache::lonhelper::getHelper();
1.135     bowersj2 3515:     $helper->declareVar($self->{'variable'});
1.131     bowersj2 3516:     bless($self);
1.119     bowersj2 3517:     return $self;
                   3518: }
                   3519: 
                   3520: sub render {
                   3521:     my $self = shift;
1.131     bowersj2 3522:     my $helper = Apache::lonhelper::getHelper();
1.119     bowersj2 3523:     my $result = '';
1.131     bowersj2 3524:     my $var = $self->{'variable'};
1.266     sakharuk 3525:     my $PageLayout=&mt('Page layout');
                   3526:     my $NumberOfColumns=&mt('Number of columns');
                   3527:     my $PaperType=&mt('Paper type');
1.506     albertel 3528:     my $landscape=&mt('Landscape');
                   3529:     my $portrait=&mt('Portrait');
1.539     onken    3530:     my $pdfFormLabel=&mt('PDF-Formfields');
                   3531:     my $with=&mt('with Formfields');
                   3532:     my $without=&mt('without Formfields');
1.544     bisitz   3533:     $result.='<h3>'.&mt('Layout Options').'</h3>'
                   3534:             .&Apache::loncommon::start_data_table()
                   3535:             .&Apache::loncommon::start_data_table_header_row()
                   3536:             .'<th>'.$PageLayout.'</th>'
                   3537:             .'<th>'.$NumberOfColumns.'</th>'
                   3538:             .'<th>'.$PaperType.'</th>'
                   3539:             .'<th>'.$pdfFormLabel.'</th>'
                   3540:             .&Apache::loncommon::end_data_table_header_row()
                   3541:             .&Apache::loncommon::start_data_table_row()
                   3542:     .'<td>'
                   3543:     .'<label><input type="radio" name="'.${var}.'.layout" value="L" />'.$landscape.'</label><br />'
                   3544:     .'<label><input type="radio" name="'.${var}.'.layout" value="P" checked="checked" />'.$portrait.'</label>'
                   3545:     .'</td>';
1.119     bowersj2 3546: 
1.544     bisitz   3547:     $result.='<td align="center">'
                   3548:             .'<select name="'.${var}.'.cols">';
1.119     bowersj2 3549: 
                   3550:     my $i;
                   3551:     for ($i = 1; $i <= $maxColumns; $i++) {
1.144     bowersj2 3552:         if ($i == 2) {
1.553     bisitz   3553:             $result .= '<option value="'.$i.'" selected="selected">'.$i.'</option>'."\n";
1.119     bowersj2 3554:         } else {
1.553     bisitz   3555:             $result .= '<option value="'.$i.'">'.$i.'</option>'."\n";
1.119     bowersj2 3556:         }
                   3557:     }
                   3558: 
                   3559:     $result .= "</select></td><td>\n";
                   3560:     $result .= "<select name='${var}.paper'>\n";
                   3561: 
1.373     albertel 3562:     my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398     albertel 3563:     my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
                   3564:     $DefaultPaperSize=~s/\s//g;
1.304     sakharuk 3565:     if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119     bowersj2 3566:     $i = 0;
                   3567:     foreach (@paperSize) {
1.326     sakharuk 3568: 	$_=~/(\w+)/;
                   3569: 	my $papersize=$1;
1.304     sakharuk 3570:         if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.553     bisitz   3571:             $result .= '<option selected="selected" value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119     bowersj2 3572:         } else {
1.553     bisitz   3573:             $result .= '<option value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119     bowersj2 3574:         }
                   3575:         $i++;
                   3576:     }
1.539     onken    3577:     $result .= <<HTML;
                   3578:         </select>
                   3579:     </td>
                   3580:     <td align='center'>
                   3581:         <select name='${var}.pdfFormFields'>
1.553     bisitz   3582:             <option selected="selected" value="no">$without</option>
                   3583:             <option value="yes">$with</option>
1.539     onken    3584:         </select>
                   3585:     </td>
                   3586: HTML
1.544     bisitz   3587:     $result.=&Apache::loncommon::end_data_table_row()
                   3588:             .&Apache::loncommon::end_data_table();
1.539     onken    3589: 
1.119     bowersj2 3590:     return $result;
1.135     bowersj2 3591: }
                   3592: 
                   3593: sub postprocess {
                   3594:     my $self = shift;
                   3595: 
                   3596:     my $var = $self->{'variable'};
1.136     bowersj2 3597:     my $helper = Apache::lonhelper->getHelper();
1.135     bowersj2 3598:     $helper->{VARS}->{$var} = 
1.373     albertel 3599:         $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
1.539     onken    3600:         $env{"form.$var.paper"} . '|' . $env{"form.$var.pdfFormFields"};
1.135     bowersj2 3601:     return 1;
1.119     bowersj2 3602: }
                   3603: 
                   3604: 1;
1.144     bowersj2 3605: 
                   3606: package Apache::lonprintout::page_size_state;
                   3607: 
                   3608: =pod
                   3609: 
                   3610: =head1 Helper element: page_size_state
                   3611: 
                   3612: See lonhelper.pm documentation for discussion of the helper framework.
                   3613: 
                   3614: Apache::lonprintout::page_size_state is an element that gives the 
                   3615: user the opportunity to further refine the page settings if they
                   3616: select a single-column page.
                   3617: 
                   3618: page_size_state is always directly invoked in lonprintout.pm, so there
                   3619: is no tag interface. You actually pass parameters to the constructor.
                   3620: 
                   3621: =over 4
                   3622: 
                   3623: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
                   3624: 
                   3625: =back
                   3626: 
                   3627: =cut
                   3628: 
                   3629: use Apache::lonhelper;
1.373     albertel 3630: use Apache::lonnet;
1.144     bowersj2 3631: no strict;
                   3632: @ISA = ("Apache::lonhelper::element");
                   3633: use strict;
                   3634: 
                   3635: 
                   3636: 
                   3637: sub new { 
                   3638:     my $self = Apache::lonhelper::element->new();
                   3639: 
                   3640:     shift; # disturbs me (probably prevents subclassing) but works (drops
                   3641:            # package descriptor)... - Jeremy
                   3642: 
                   3643:     $self->{'variable'} = shift;
                   3644:     my $helper = Apache::lonhelper::getHelper();
                   3645:     $helper->declareVar($self->{'variable'});
                   3646: 
                   3647:     # The variable name of the format element, so we can look into 
                   3648:     # $helper->{VARS} to figure out whether the columns are one or two
                   3649:     $self->{'formatvar'} = shift;
                   3650: 
1.463     foxr     3651: 
1.144     bowersj2 3652:     $self->{NEXTSTATE} = shift;
                   3653:     bless($self);
1.467     foxr     3654: 
1.144     bowersj2 3655:     return $self;
                   3656: }
                   3657: 
                   3658: sub render {
                   3659:     my $self = shift;
                   3660:     my $helper = Apache::lonhelper::getHelper();
                   3661:     my $result = '';
                   3662:     my $var = $self->{'variable'};
                   3663: 
1.467     foxr     3664: 
                   3665: 
1.144     bowersj2 3666:     if (defined $self->{ERROR_MSG}) {
1.464     albertel 3667:         $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144     bowersj2 3668:     }
                   3669: 
1.438     foxr     3670:     my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463     foxr     3671: 
                   3672:     # Use format to get sensible defaults for the margins:
                   3673: 
                   3674: 
                   3675:     my ($laystyle, $cols, $papersize) = split(/\|/, $format);
                   3676:     ($papersize)                      = split(/ /, $papersize);
                   3677: 
                   3678: 
                   3679:     if ($laystyle eq 'L') {
                   3680: 	$laystyle = 'album';
                   3681:     } else {
                   3682: 	$laystyle = 'book';
                   3683:     }
                   3684: 
                   3685: 
1.464     albertel 3686:     my %size;
                   3687:     ($size{'width_and_units'},
                   3688:      $size{'height_and_units'},
                   3689:      $size{'margin_and_units'})=
                   3690: 	 &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463     foxr     3691:     
1.464     albertel 3692:     foreach my $dimension ('width','height','margin') {
                   3693: 	($size{$dimension},$size{$dimension.'_unit'}) =
                   3694: 	    split(/ +/, $size{$dimension.'_and_units'},2);
                   3695:        	
                   3696: 	foreach my $unit ('cm','in') {
                   3697: 	    $size{$dimension.'_options'} .= '<option ';
                   3698: 	    if ($size{$dimension.'_unit'} eq $unit) {
                   3699: 		$size{$dimension.'_options'} .= 'selected="selected" ';
                   3700: 	    }
                   3701: 	    $size{$dimension.'_options'} .= '>'.$unit.'</option>';
                   3702: 	}
1.438     foxr     3703:     }
                   3704: 
1.470     foxr     3705:     # Adjust margin for LaTeX margin: .. requires units == cm or in.
                   3706: 
                   3707:     if ($size{'margin_unit'} eq 'in') {
                   3708: 	$size{'margin'} += 1;
                   3709:     }  else {
                   3710: 	$size{'margin'} += 2.54;
                   3711:     }
1.548     bisitz   3712:     my %lt = &Apache::lonlocal::texthash(
                   3713:         'format' => 'How should each column be formatted?',
                   3714:         'width'  => 'Width',
                   3715:         'height' => 'Height',
                   3716:         'margin' => 'Left Margin'
                   3717:     );
                   3718: 
                   3719:     $result .= '<p>'.$lt{'format'}.'</p>'
                   3720:               .&Apache::lonhtmlcommon::start_pick_box()
                   3721:               .&Apache::lonhtmlcommon::row_title($lt{'width'})
                   3722:               .'<input type="text" name="'.$var.'.width" value="'.$size{'width'}.'" size="4" />'
                   3723:               .'<select name="'.$var.'.widthunit">'
                   3724:               .$size{'width_options'}
                   3725:               .'</select>'
                   3726:               .&Apache::lonhtmlcommon::row_closure()
                   3727:               .&Apache::lonhtmlcommon::row_title($lt{'height'})
                   3728:               .'<input type="text" name="'.$var.'.height" value="'.$size{'height'}.'" size="4" />'
                   3729:               .'<select name="'.$var.'.heightunit">'
                   3730:               .$size{'height_options'}
                   3731:               .'</select>'
                   3732:               .&Apache::lonhtmlcommon::row_closure()
                   3733:               .&Apache::lonhtmlcommon::row_title($lt{'margin'})
                   3734:               .'<input type="text" name="'.$var.'.lmargin" value="'.$size{'margin'}.'" size="4" />'
                   3735:               .'<select name="'.$var.'.lmarginunit">'
                   3736:               .$size{'margin_options'}
                   3737:               .'</select>'
                   3738:               .&Apache::lonhtmlcommon::row_closure(1)
                   3739:               .&Apache::lonhtmlcommon::end_pick_box();
                   3740:     # <p>Hint: Some instructors like to leave scratch space for the student by
                   3741:     # making the width much smaller than the width of the page.</p>
1.144     bowersj2 3742: 
                   3743:     return $result;
                   3744: }
                   3745: 
1.470     foxr     3746: 
1.144     bowersj2 3747: sub preprocess {
                   3748:     my $self = shift;
                   3749:     my $helper = Apache::lonhelper::getHelper();
                   3750: 
                   3751:     my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467     foxr     3752: 
                   3753:     #  If the user does not have 'pav' privilege, set default widths and
                   3754:     #  on to the next state right away.
                   3755:     #
                   3756:     if (!$perm{'pav'}) {
                   3757: 	my $var = $self->{'variable'};
                   3758: 	my $format = $helper->{VARS}->{$self->{'formatvar'}};
                   3759: 	
                   3760: 	my ($laystyle, $cols, $papersize) = split(/\|/, $format);
                   3761: 	($papersize)                      = split(/ /, $papersize);
                   3762: 	
                   3763: 	
                   3764: 	if ($laystyle eq 'L') {
                   3765: 	    $laystyle = 'album';
                   3766: 	} else {
                   3767: 	    $laystyle = 'book';
                   3768: 	}
                   3769: 	#  Figure out some good defaults for the print out and set them:
                   3770: 	
                   3771: 	my %size;
                   3772: 	($size{'width'},
                   3773: 	 $size{'height'},
                   3774: 	 $size{'lmargin'})=
                   3775: 	     &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
                   3776: 	
                   3777: 	foreach my $dim ('width', 'height', 'lmargin') {
                   3778: 	    my ($value, $units) = split(/ /, $size{$dim});
1.470     foxr     3779: 	    	    
1.467     foxr     3780: 	    $helper->{VARS}->{"$var.".$dim}      = $value;
                   3781: 	    $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
                   3782: 	    
                   3783: 	}
                   3784: 	
                   3785: 
                   3786: 	# Transition to the next state
                   3787: 
                   3788: 	$helper->changeState($self->{NEXTSTATE});
                   3789:     }
1.144     bowersj2 3790:    
                   3791:     return 1;
                   3792: }
                   3793: 
                   3794: sub postprocess {
                   3795:     my $self = shift;
                   3796: 
                   3797:     my $var = $self->{'variable'};
                   3798:     my $helper = Apache::lonhelper->getHelper();
1.373     albertel 3799:     my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"}; 
                   3800:     my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"}; 
                   3801:     my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"}; 
                   3802:     $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"}; 
                   3803:     $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"}; 
                   3804:     $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"}; 
1.144     bowersj2 3805: 
                   3806:     my $error = '';
                   3807: 
                   3808:     # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed 
                   3809:     # by an optional period, followed by digits, ending the string
                   3810: 
1.464     albertel 3811:     if ($width !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3812:         $error .= "Invalid width; please type only a number.<br />\n";
                   3813:     }
1.464     albertel 3814:     if ($height !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3815:         $error .= "Invalid height; please type only a number.<br />\n";
                   3816:     }
1.464     albertel 3817:     if ($lmargin !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3818:         $error .= "Invalid left margin; please type only a number.<br />\n";
1.470     foxr     3819:     } else {
                   3820: 	# Adjust for LaTeX 1.0 inch margin:
                   3821: 
                   3822: 	if ($env{"form.${var}.lmarginunit"} eq "in") {
                   3823: 	    $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
                   3824: 	} else {
                   3825: 	    $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
                   3826: 	}
1.144     bowersj2 3827:     }
                   3828: 
                   3829:     if (!$error) {
                   3830:         Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
                   3831:         return 1;
                   3832:     } else {
                   3833:         $self->{ERROR_MSG} = $error;
                   3834:         return 0;
                   3835:     }
                   3836: }
                   3837: 
                   3838: 
1.119     bowersj2 3839: 
1.1       www      3840: __END__
1.6       sakharuk 3841: 

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