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

1.389     foxr        1: # The LearningOnline Network
1.1       www         2: # Printout
                      3: #
1.551   ! foxr        4: # $Id: lonprintout.pm,v 1.550 2009/04/17 10:08:42 foxr 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.551   ! foxr     1477: 	    &Apache::lonnet::logthis("include_pdf 3");
        !          1478: 	    
        !          1479: 	    my $texversion = &include_pdf($urlp);
        !          1480: 	    $texversion = &latex_header_footer_remove($texversion);
        !          1481: 	    $result .= $texversion;
1.550     foxr     1482: 	}
1.459     foxr     1483:     }
                   1484:     if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\begin{document})/$1 \\fbox\{RANDOM SEED IS $rndseed\} /;}
                   1485:     return $result;
                   1486: }
                   1487: 
1.177     sakharuk 1488: sub output_data {
1.184     sakharuk 1489:     my ($r,$helper,$rparmhash) = @_;
                   1490:     my %parmhash = %$rparmhash;
1.515     foxr     1491:     $ssi_error = 0;		# This will be set nonzero by failing ssi's.
1.459     foxr     1492:     $resources_printed = '';
1.499     foxr     1493:     my $do_postprocessing = 1;
1.433     albertel 1494:     my $js = <<ENDPART;
                   1495: <script type="text/javascript">
1.264     sakharuk 1496:     var editbrowser;
                   1497:     function openbrowser(formname,elementname,only,omit) {
                   1498:         var url = '/res/?';
                   1499:         if (editbrowser == null) {
                   1500:             url += 'launch=1&';
                   1501:         }
                   1502:         url += 'catalogmode=interactive&';
                   1503:         url += 'mode=parmset&';
                   1504:         url += 'form=' + formname + '&';
                   1505:         if (only != null) {
                   1506:             url += 'only=' + only + '&';
                   1507:         } 
                   1508:         if (omit != null) {
                   1509:             url += 'omit=' + omit + '&';
                   1510:         }
                   1511:         url += 'element=' + elementname + '';
                   1512:         var title = 'Browser';
                   1513:         var options = 'scrollbars=1,resizable=1,menubar=0';
                   1514:         options += ',width=700,height=600';
                   1515:         editbrowser = open(url,title,options,'1');
                   1516:         editbrowser.focus();
                   1517:     }
                   1518: </script>
1.140     sakharuk 1519: ENDPART
                   1520: 
1.512     foxr     1521: 
                   1522: 
1.433     albertel 1523:     my $start_page  = &Apache::loncommon::start_page('Preparing Printout',$js);
                   1524:     my $msg = &mt('Please stand by while processing your print request, this may take some time ...');
1.363     foxr     1525: 
1.433     albertel 1526:     $r->print($start_page."\n<p>\n$msg\n</p>\n");
1.372     foxr     1527: 
1.363     foxr     1528:     # fetch the pagebreaks and store them in the course environment
                   1529:     # The page breaks will be pulled into the hash %page_breaks which is
                   1530:     # indexed by symb and contains 1's for each break.
                   1531: 
1.373     albertel 1532:     $env{'form.pagebreaks'}  = $helper->{'VARS'}->{'FINISHPAGE'};
                   1533:     $env{'form.lastprinttype'} = $helper->{'VARS'}->{'PRINT_TYPE'}; 
1.363     foxr     1534:     &Apache::loncommon::store_course_settings('print',
1.366     foxr     1535: 					      {'pagebreaks'    => 'scalar',
                   1536: 					       'lastprinttype' => 'scalar'});
1.363     foxr     1537: 
1.364     albertel 1538:     my %page_breaks  = &get_page_breaks($helper);
1.363     foxr     1539: 
1.140     sakharuk 1540:     my $format_from_helper = $helper->{'VARS'}->{'FORMAT'};
                   1541:     my ($result,$selectionmade) = ('','');
                   1542:     my $number_of_columns = 1; #used only for pages to determine the width of the cell
                   1543:     my @temporary_array=split /\|/,$format_from_helper;
1.539     onken    1544:     my ($laystyle,$numberofcolumns,$papersize,$pdfFormFields)=@temporary_array;
1.140     sakharuk 1545:     if ($laystyle eq 'L') {
                   1546: 	$laystyle='album';
                   1547:     } else {
                   1548: 	$laystyle='book';
                   1549:     }
1.177     sakharuk 1550:     my ($textwidth,$textheight,$oddoffset,$evenoffset) = &page_format($papersize,$laystyle,$numberofcolumns);
1.373     albertel 1551:     my $assignment =  $env{'form.assignment'};
1.275     sakharuk 1552:     my $LaTeXwidth=&recalcto_mm($textwidth); 
1.272     sakharuk 1553:     my @print_array=();
1.274     sakharuk 1554:     my @student_names=();
1.360     albertel 1555: 
1.512     foxr     1556:      
1.360     albertel 1557:     #  Common settings for the %form has:
                   1558:     # In some cases these settings get overriddent by specific cases, but the
                   1559:     # settings are common enough to make it worthwhile factoring them out
                   1560:     # here.
                   1561:     #
                   1562:     my %form;
                   1563:     $form{'grade_target'} = 'tex';
                   1564:     $form{'textwidth'}    = &get_textwidth($helper, $LaTeXwidth);
1.539     onken    1565:     $form{'pdfFormFields'} = $pdfFormFields;
1.372     foxr     1566: 
                   1567:     # If form.showallfoils is set, then request all foils be shown:
                   1568:     # privilege will be enforced both by not allowing the 
                   1569:     # check box selecting this option to be presnt unless it's ok,
                   1570:     # and by lonresponse's priv. check.
                   1571:     # The if is here because lonresponse.pm only cares that
                   1572:     # showallfoils is defined, not what the value is.
                   1573: 
                   1574:     if ($helper->{'VARS'}->{'showallfoils'} eq "1") { 
                   1575: 	$form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'};
                   1576:     }
1.504     albertel 1577:     
                   1578:     if ($helper->{'VARS'}->{'style_file'}=~/\w/) {
1.520     raeburn  1579: 	&Apache::lonnet::appenv({'construct.style' =>
                   1580: 				$helper->{'VARS'}->{'style_file'}});
1.504     albertel 1581:     } elsif ($env{'construct.style'}) {
1.549     raeburn  1582: 	&Apache::lonnet::delenv('construct.style');
1.504     albertel 1583:     }
                   1584: 
1.372     foxr     1585: 
1.140     sakharuk 1586:     if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') {
1.143     sakharuk 1587:       #-- single document - problem, page, html, xml, ...
1.343     albertel 1588: 	my ($currentURL,$cleanURL);
1.375     foxr     1589: 
1.162     sakharuk 1590: 	if ($helper->{'VARS'}->{'construction'} ne '1') {
1.185     sakharuk 1591:             #prints published resource
1.153     sakharuk 1592: 	    $currentURL=$helper->{'VARS'}->{'postdata'};
1.343     albertel 1593: 	    $cleanURL=&Apache::lonenc::check_decrypt($currentURL);
1.143     sakharuk 1594: 	} else {
1.512     foxr     1595: 
1.185     sakharuk 1596:             #prints resource from the construction space
1.240     albertel 1597: 	    $currentURL='/'.$helper->{'VARS'}->{'filename'};
1.206     sakharuk 1598: 	    if ($currentURL=~/([^?]+)/) {$currentURL=$1;}
1.343     albertel 1599: 	    $cleanURL=$currentURL;
1.143     sakharuk 1600: 	}
1.140     sakharuk 1601: 	$selectionmade = 1;
1.413     albertel 1602: 	if ($cleanURL!~m|^/adm/|
                   1603: 	    && $cleanURL=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.169     albertel 1604: 	    my $rndseed=time;
1.242     sakharuk 1605: 	    my $texversion='';
                   1606: 	    if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') {
                   1607: 		my %moreenv;
1.343     albertel 1608: 		$moreenv{'request.filename'}=$cleanURL;
1.290     sakharuk 1609:                 if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {$form{'problemtype'}='exam';}
1.242     sakharuk 1610: 		$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310     sakharuk 1611: 		$form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.242     sakharuk 1612: 		$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309     sakharuk 1613: 		$form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511     foxr     1614: 		$form{'print_annotations'}=$helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
                   1615: 		if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
                   1616: 		    ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
                   1617: 		    $form{'problem_split'}='yes';
                   1618: 		}
1.242     sakharuk 1619: 		if ($helper->{'VARS'}->{'curseed'}) {
                   1620: 		    $rndseed=$helper->{'VARS'}->{'curseed'};
                   1621: 		}
                   1622: 		$form{'rndseed'}=$rndseed;
1.520     raeburn  1623: 		&Apache::lonnet::appenv(\%moreenv);
1.428     albertel 1624: 
                   1625: 		&Apache::lonxml::clear_problem_counter();
                   1626: 
1.375     foxr     1627: 		$resources_printed .= $currentURL.':';
1.515     foxr     1628: 		$texversion.=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.428     albertel 1629: 
1.511     foxr     1630: 		#  Add annotations if required:
                   1631: 	    
1.428     albertel 1632: 		&Apache::lonxml::clear_problem_counter();
                   1633: 
1.242     sakharuk 1634: 		&Apache::lonnet::delenv('request.filename');
1.230     albertel 1635: 	    }
1.423     foxr     1636: 	    # current document with answers.. no need to encap in minipage
                   1637: 	    #  since there's only one answer.
                   1638: 
1.242     sakharuk 1639: 	    if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   1640: 	       ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.353     foxr     1641: 		$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.166     albertel 1642: 		$form{'grade_target'}='answer';
1.167     albertel 1643: 		$form{'answer_output_mode'}='tex';
1.169     albertel 1644: 		$form{'rndseed'}=$rndseed;
1.401     albertel 1645:                 if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {
                   1646: 		    $form{'problemtype'}='exam';
                   1647: 		}
1.375     foxr     1648: 		$resources_printed .= $currentURL.':';
1.515     foxr     1649: 		my $answer=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.511     foxr     1650: 		
                   1651: 
1.242     sakharuk 1652: 		if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   1653: 		    $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
                   1654: 		} else {
                   1655: 		    $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.245     sakharuk 1656: 		    if ($helper->{'VARS'}->{'construction'} ne '1') {
1.477     albertel 1657: 			my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
                   1658: 			$title = &Apache::lonxml::latex_special_symbols($title);
                   1659: 			$texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.343     albertel 1660: 			$texversion.=&path_to_problem($cleanURL,$LaTeXwidth);
1.245     sakharuk 1661: 		    } else {
                   1662: 			$texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
1.343     albertel 1663: 			my $URLpath=$cleanURL;
1.245     sakharuk 1664: 			$URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
1.504     albertel 1665: 			$texversion.=&path_to_problem($URLpath,$LaTeXwidth);
1.245     sakharuk 1666: 		    }
1.242     sakharuk 1667: 		    $texversion.='\vskip 1 mm '.$answer.'\end{document}';
                   1668: 		}
1.511     foxr     1669: 
                   1670: 
                   1671: 		
                   1672: 
1.550     foxr     1673: 	    
1.511     foxr     1674: 	    }
                   1675: 	    # Print annotations.
                   1676: 
                   1677: 
                   1678: 	    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1679: 		my $annotation .= &annotate($currentURL);
                   1680: 		$texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
1.163     sakharuk 1681: 	    }
1.511     foxr     1682: 
                   1683: 
1.214     sakharuk 1684: 	    if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1.215     sakharuk 1685: 		$texversion=&IndexCreation($texversion,$currentURL);
1.214     sakharuk 1686: 	    }
1.219     sakharuk 1687: 	    if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
                   1688: 		$texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$currentURL| \\strut\\\\\\strut /;
                   1689: 
                   1690: 	    }
1.162     sakharuk 1691: 	    $result .= $texversion;
                   1692: 	    if ($currentURL=~m/\.page\s*$/) {
                   1693: 		($result,$number_of_columns) = &page_cleanup($result);
                   1694: 	    }
1.413     albertel 1695:         } elsif ($cleanURL!~m|^/adm/|
                   1696: 		 && $currentURL=~/\.sequence$/ && $helper->{'VARS'}->{'construction'} eq '1') {
1.227     sakharuk 1697:             #printing content of sequence from the construction space	
                   1698: 	    $currentURL=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;
1.551   ! foxr     1699: #	    $result .= &print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.459     foxr     1700: 	    $result .= &print_construction_sequence($currentURL, $helper, %form,
                   1701: 						    $LaTeXwidth);
                   1702: 	    $result .= '\end{document}';  
                   1703: 	    if (!($result =~ /\\begin\{document\}/)) {
                   1704: 		$result = &print_latex_header() . $result;
1.227     sakharuk 1705: 	    }
1.459     foxr     1706: 	    # End construction space sequence.
1.456     raeburn  1707: 	} elsif ($cleanURL=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { 
1.258     sakharuk 1708: 		$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.298     sakharuk 1709: 		if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;}
1.375     foxr     1710: 		$resources_printed .= $currentURL.':';
1.515     foxr     1711: 		my $texversion=&ssi_with_retries($currentURL, $ssi_retry_count, %form);
1.511     foxr     1712: 		if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1713: 		    my $annotation = &annotate($currentURL);
                   1714: 		    $texversion    =~ s/(\\end{document})/$annotation$1/;
                   1715: 		}
1.258     sakharuk 1716: 		$result .= $texversion;
1.550     foxr     1717: 	} elsif ($cleanURL =~/\.tex$/) {
1.498     foxr     1718: 	    # For this sort of print of a single LaTeX file,
                   1719: 	    # We can just print the LaTeX file as it is uninterpreted in any way:
                   1720: 	    #
                   1721: 
                   1722: 	    $result = &fetch_raw_resource($currentURL);
1.511     foxr     1723: 	    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1724: 		my $annotation = &annotate($currentURL);
                   1725: 		$result =~ s/(\\end{document})/$annotation$1/;
                   1726: 	    }
                   1727: 
1.499     foxr     1728: 	    $do_postprocessing = 0; # Don't massage the result.
1.498     foxr     1729: 
1.550     foxr     1730: 	} elsif ($cleanURL =~ /\.pdf$/i) {
1.551   ! foxr     1731: 	    &Apache::lonnet::logthis("include_pdf 1");
1.550     foxr     1732: 	    $result .= &include_pdf($cleanURL);
1.551   ! foxr     1733: 	    $result .= '\end{document}';
1.162     sakharuk 1734: 	} else {
1.414     albertel 1735: 	    $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'},
                   1736: 				  $helper->{'VARS'}->{'symb'});
1.162     sakharuk 1737: 	}
1.354     foxr     1738:     } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems')       or
1.142     sakharuk 1739:              ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or
1.354     foxr     1740:              ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems')       or
                   1741: 	     ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources')      or # BUGBUG
1.536     foxr     1742: 	     ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') 
                   1743: 	     ) { 
1.511     foxr     1744: 
                   1745: 
1.141     sakharuk 1746:         #-- produce an output string
1.296     sakharuk 1747: 	if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') {
                   1748: 	    $selectionmade = 2;
                   1749: 	} elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') {
                   1750: 	    $selectionmade = 3;
1.536     foxr     1751: 	} elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') 
                   1752: 		 ) {
1.296     sakharuk 1753: 	    $selectionmade = 4;
1.354     foxr     1754: 	} elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') {  #BUGBUG
                   1755: 	    $selectionmade = 4;
1.296     sakharuk 1756: 	} elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') {
                   1757: 	    $selectionmade = 7;
                   1758: 	}
1.193     sakharuk 1759: 	$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310     sakharuk 1760: 	$form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.203     sakharuk 1761: 	$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309     sakharuk 1762: 	$form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511     foxr     1763: 	$form{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
                   1764: 	if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes')   ||
                   1765: 	    ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') ) {
                   1766: 	    $form{'problem_split'}='yes';
                   1767: 	}
1.141     sakharuk 1768: 	my $flag_latex_header_remove = 'NO';
                   1769: 	my $flag_page_in_sequence = 'NO';
                   1770: 	my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.193     sakharuk 1771: 	my $prevassignment='';
1.428     albertel 1772: 
                   1773: 	&Apache::lonxml::clear_problem_counter();
                   1774: 
1.416     foxr     1775: 	my $pbreakresources = keys %page_breaks;
1.141     sakharuk 1776: 	for (my $i=0;$i<=$#master_seq;$i++) {
1.350     foxr     1777: 
1.521     foxr     1778: 	    &Apache::lonenc::reset_enc();
                   1779: 
                   1780: 
1.350     foxr     1781: 	    # Note due to document structure, not allowed to put \newpage
                   1782: 	    # prior to the first resource
                   1783: 
1.351     foxr     1784: 	    if (defined $page_breaks{$master_seq[$i]}) {
1.350     foxr     1785: 		if($i != 0) {
                   1786: 		    $result.="\\newpage\n";
                   1787: 		}
                   1788: 	    }
1.521     foxr     1789: 	    my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]);
1.237     albertel 1790: 	    $urlp=&Apache::lonnet::clutter($urlp);
1.166     albertel 1791: 	    $form{'symb'}=$master_seq[$i];
1.407     albertel 1792: 
1.521     foxr     1793: 
1.407     albertel 1794: 	    my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem
1.521     foxr     1795: 
1.267     sakharuk 1796: 	    if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;}
1.247     sakharuk 1797: 	    if ($i==0) {$prevassignment=$assignment;}
1.297     sakharuk 1798: 	    my $texversion='';
1.413     albertel 1799: 	    if ($urlp!~m|^/adm/|
                   1800: 		&& $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375     foxr     1801: 		$resources_printed .= $urlp.':';
1.428     albertel 1802: 		&Apache::lonxml::remember_problem_counter();
1.515     foxr     1803: 		$texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.296     sakharuk 1804: 		if ($urlp=~/\.page$/) {
                   1805: 		    ($texversion,my $number_of_columns_page) = &page_cleanup($texversion);
                   1806: 		    if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;} 
                   1807: 		    $texversion =~ s/\\end{document}\d*/\\end{document}/;
                   1808: 		    $flag_page_in_sequence = 'YES';
                   1809: 		} 
1.428     albertel 1810: 
1.296     sakharuk 1811: 		if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   1812: 		   ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     1813: 		    #  Don't permanently pervert the %form hash
                   1814: 		    my %answerform = %form;
                   1815: 		    $answerform{'grade_target'}='answer';
                   1816: 		    $answerform{'answer_output_mode'}='tex';
1.375     foxr     1817: 		    $resources_printed .= $urlp.':';
1.428     albertel 1818: 
                   1819: 		    &Apache::lonxml::restore_problem_counter();
1.515     foxr     1820: 		    my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.428     albertel 1821: 
1.296     sakharuk 1822: 		    if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   1823: 			$texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1.249     sakharuk 1824: 		    } else {
1.307     sakharuk 1825: 			if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) {
1.296     sakharuk 1826: 			    $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477     albertel 1827: 			    my $title = &Apache::lonnet::gettitle($master_seq[$i]);
                   1828: 			    $title = &Apache::lonxml::latex_special_symbols($title);
                   1829: 			    my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.423     foxr     1830: 			    $body   .= &path_to_problem ($urlp,$LaTeXwidth);
                   1831: 			    $body   .='\vskip 1 mm '.$answer;
                   1832: 			    $body    = &encapsulate_minipage($body);
                   1833: 			    $texversion .= $body;
1.296     sakharuk 1834: 			} else {
                   1835: 			    $texversion='';
                   1836: 			}
1.249     sakharuk 1837: 		    }
1.511     foxr     1838: 
1.246     sakharuk 1839: 		}
1.511     foxr     1840: 		if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1841: 		    my $annotation .= &annotate($urlp);
                   1842: 		    $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
                   1843: 		}
                   1844: 
1.296     sakharuk 1845: 		if ($flag_latex_header_remove ne 'NO') {
                   1846: 		    $texversion = &latex_header_footer_remove($texversion);
                   1847: 		} else {
                   1848: 		    $texversion =~ s/\\end{document}//;
                   1849: 		}
                   1850: 		if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
                   1851: 		    $texversion=&IndexCreation($texversion,$urlp);
                   1852: 		}
                   1853: 		if (($selectionmade == 4) and ($assignment ne $prevassignment)) {
                   1854: 		    my $name = &get_name();
                   1855: 		    my $courseidinfo = &get_course();
                   1856: 		    $prevassignment=$assignment;
1.455     albertel 1857: 		    my $header_text = $parmhash{'print_header_format'};
1.486     foxr     1858: 		    $header_text    = &format_page_header($textwidth, $header_text,
1.455     albertel 1859: 							  $assignment, 
                   1860: 							  $courseidinfo, 
                   1861: 							  $name);
1.417     foxr     1862: 		    if ($numberofcolumns eq '1') {
1.455     albertel 1863: 			$result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{'.$header_text.'}} \vskip 5 mm ';
1.416     foxr     1864: 		    } else {
1.455     albertel 1865: 			$result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\fancyhead[LO]{'.$header_text.'}} \vskip 5 mm ';
1.416     foxr     1866: 		    }			
1.296     sakharuk 1867: 		}
                   1868: 		$result .= $texversion;
                   1869: 		$flag_latex_header_remove = 'YES';   
1.456     raeburn  1870: 	    } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { 
1.301     sakharuk 1871: 		$form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
                   1872: 		if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;}
1.375     foxr     1873: 		$resources_printed .= $urlp.':';
1.515     foxr     1874: 		my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.511     foxr     1875: 		if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   1876: 		    my $annotation = &annotate($urlp);
                   1877: 		    $texversion =~ s/(\\end{document)/$annotation$1/;
                   1878: 		}
                   1879: 
1.301     sakharuk 1880: 		if ($flag_latex_header_remove ne 'NO') {
                   1881: 		    $texversion = &latex_header_footer_remove($texversion);
1.550     foxr     1882: 		} else {	
1.301     sakharuk 1883: 		    $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/;
                   1884: 		}
                   1885: 		$result .= $texversion;
                   1886: 		$flag_latex_header_remove = 'YES'; 
1.550     foxr     1887: 	    } elsif ($urlp=~ /\.pdf$/i) {
                   1888: 		if ($i > 0) {
                   1889: 		    $result .= '\cleardoublepage';
                   1890: 		}
1.551   ! foxr     1891: 		&Apache::lonnet::logthis("include_pdf 2");
        !          1892: 
1.550     foxr     1893: 		$result .= &include_pdf($urlp);
                   1894: 		if ($i != $#master_seq) {
                   1895: 		    if ($numberofcolumns eq '1') {
                   1896: 			$result .= '\newpage';
                   1897: 		    } else {
                   1898: 			# the \\'s seem to be needed to let LaTeX know there's something
                   1899: 			# on the page since LaTeX seems to not like to clear an empty page.
                   1900: 			#
                   1901: 			$result .= '\\ \cleardoublepage';
                   1902: 		    }
                   1903: 		}
                   1904: 		$flag_latex_header_remove = 'YES';
                   1905: 
1.141     sakharuk 1906: 	    } else {
1.414     albertel 1907: 		$texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'},
                   1908: 					 $master_seq[$i]);
1.297     sakharuk 1909: 		if ($flag_latex_header_remove ne 'NO') {
                   1910: 		    $texversion = &latex_header_footer_remove($texversion);
                   1911: 		} else {
                   1912: 		    $texversion =~ s/\\end{document}//;
                   1913: 		}
                   1914: 		$result .= $texversion;
                   1915: 		$flag_latex_header_remove = 'YES';   
1.296     sakharuk 1916: 	    }	    
1.550     foxr     1917: 	    if (&Apache::loncommon::connection_aborted($r)) { 
                   1918: 		last; 
                   1919: 	    }
1.141     sakharuk 1920: 	}
1.428     albertel 1921: 	&Apache::lonxml::clear_problem_counter();
1.344     foxr     1922: 	if ($flag_page_in_sequence eq 'YES') {
                   1923: 	    $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;
                   1924: 	}	
1.141     sakharuk 1925: 	$result .= '\end{document}';
1.284     albertel 1926:      } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1.536     foxr     1927: 	      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ||
1.284     albertel 1928: 	      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){
1.353     foxr     1929: 
                   1930: 
1.150     sakharuk 1931:      #-- prints assignments for whole class or for selected students  
1.284     albertel 1932: 	 my $type;
1.536     foxr     1933: 	 if (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
                   1934: 	     ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ) {
1.254     sakharuk 1935: 	     $selectionmade=5;
1.284     albertel 1936: 	     $type='problems';
1.254     sakharuk 1937: 	 } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') {
                   1938: 	     $selectionmade=8;
1.284     albertel 1939: 	     $type='resources';
1.254     sakharuk 1940: 	 }
1.150     sakharuk 1941: 	 my @students=split /\|\|\|/, $helper->{'VARS'}->{'STUDENTS'};
1.341     foxr     1942: 	 #   The normal sort order is by section then by students within the
                   1943: 	 #   section. If the helper var student_sort is 1, then the user has elected
                   1944: 	 #   to override this and output the students by name.
                   1945: 	 #    Each element of the students array is of the form:
                   1946: 	 #       username:domain:section:last, first:status
                   1947: 	 #    
1.429     foxr     1948: 	 #  Note that student sort is not compatible with printing 
                   1949: 	 #  1 section per pdf...so that setting overrides.
1.341     foxr     1950: 	 #   
1.429     foxr     1951: 	 if (($helper->{'VARS'}->{'student_sort'}    eq 1)  && 
                   1952: 	     ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) {
1.341     foxr     1953: 	     @students = sort compare_names  @students;
                   1954: 	 }
1.429     foxr     1955: 	 &adjust_number_to_print($helper);
                   1956: 
1.278     albertel 1957:          if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq '0' ||
                   1958: 	     $helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'all' ) {
                   1959: 	     $helper->{'VARS'}->{'NUMBER_TO_PRINT'}=$#students+1;
                   1960: 	 }
1.429     foxr     1961: 	 # If we are splitting on section boundaries, we need 
                   1962: 	 # to remember that in split_on_sections and 
                   1963: 	 # print all of the students in the list.
                   1964: 	 #
                   1965: 	 my $split_on_sections = 0;
                   1966: 	 if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'section') {
                   1967: 	     $split_on_sections = 1;
                   1968: 	     $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1;
                   1969: 	 }
1.150     sakharuk 1970: 	 my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.350     foxr     1971: 
1.150     sakharuk 1972: 	 #loop over students
                   1973: 	 my $flag_latex_header_remove = 'NO'; 
                   1974: 	 my %moreenv;
1.330     sakharuk 1975:          $moreenv{'instructor_comments'}='hide';
1.285     albertel 1976: 	 $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth);
1.309     sakharuk 1977: 	 $moreenv{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511     foxr     1978: 	 $moreenv{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1.353     foxr     1979: 	 $moreenv{'problem_split'}    = $parmhash{'problem_stream_switch'};
1.369     foxr     1980: 	 $moreenv{'suppress_tries'}   = $parmhash{'suppress_tries'};
1.511     foxr     1981: 	 if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes')  ||
                   1982: 	     ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
                   1983: 	     $moreenv{'problem_split'}='yes';
                   1984: 	 }
1.318     albertel 1985: 	 my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75');
1.272     sakharuk 1986: 	 my $student_counter=-1;
1.429     foxr     1987: 	 my $i = 0;
1.430     albertel 1988: 	 my $last_section = (split(/:/,$students[0]))[2];
1.150     sakharuk 1989: 	 foreach my $person (@students) {
1.350     foxr     1990: 
1.373     albertel 1991:              my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";
1.311     sakharuk 1992: 	     if (-e $duefile) {
                   1993: 		 my $temp_file = Apache::File->new('>>'.$duefile);
                   1994: 		 print $temp_file "1969\n";
                   1995: 	     }
1.272     sakharuk 1996: 	     $student_counter++;
1.429     foxr     1997: 	     if ($split_on_sections) {
1.430     albertel 1998: 		 my $this_section = (split(/:/,$person))[2];
1.429     foxr     1999: 		 if ($this_section ne $last_section) {
                   2000: 		     $i++;
                   2001: 		     $last_section = $this_section;
                   2002: 		 }
                   2003: 	     } else {
                   2004: 		 $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'});
                   2005: 	     }
1.375     foxr     2006: 	     my ($output,$fullname, $printed)=&print_resources($r,$helper,
1.353     foxr     2007: 						     $person,$type,
                   2008: 						     \%moreenv,\@master_seq,
1.360     albertel 2009: 						     $flag_latex_header_remove,
1.422     albertel 2010: 						     $LaTeXwidth);
1.375     foxr     2011: 	     $resources_printed .= ":";
1.284     albertel 2012: 	     $print_array[$i].=$output;
                   2013: 	     $student_names[$i].=$person.':'.$fullname.'_END_';
                   2014: 	     &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname);
                   2015: 	     $flag_latex_header_remove = 'YES';
1.331     albertel 2016: 	     if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284     albertel 2017: 	 }
                   2018: 	 &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
                   2019: 	 $result .= $print_array[0].'  \end{document}';
                   2020:      } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon')     ||
                   2021: 	      ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon')  ) { 
1.373     albertel 2022: 	 my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
                   2023: 	 my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
1.288     albertel 2024: 	 my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'};
                   2025: 	 my $code_name=$helper->{'VARS'}->{'ANON_CODE_STORAGE_NAME'};
1.292     albertel 2026: 	 my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'};
1.385     foxr     2027: 	 my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'};
1.388     foxr     2028: 	 my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'};
                   2029: 
1.381     albertel 2030: 	 my $code_option=$helper->{'VARS'}->{'CODE_OPTION'};
1.542     raeburn  2031:          my @lines = &Apache::grades::get_scantronformat_file();
1.381     albertel 2032: 	 my ($code_type,$code_length)=('letter',6);
1.542     raeburn  2033: 	 foreach my $line (@lines) {
1.381     albertel 2034: 	     my ($name,$type,$length) = (split(/:/,$line))[0,2,4];
                   2035: 	     if ($name eq $code_option) {
                   2036: 		 $code_length=$length;
                   2037: 		 if ($type eq 'number') { $code_type = 'number'; }
                   2038: 	     }
                   2039: 	 }
1.288     albertel 2040: 	 my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth));
1.353     foxr     2041: 	 $moreenv{'problem_split'}    = $parmhash{'problem_stream_switch'};
1.420     albertel 2042:          $moreenv{'instructor_comments'}='hide';
1.288     albertel 2043: 	 my $seed=time+($$<<16)+($$);
1.292     albertel 2044: 	 my @allcodes;
                   2045: 	 if ($old_name) {
1.381     albertel 2046: 	     my %result=&Apache::lonnet::get('CODEs',
                   2047: 					     [$old_name,"type\0$old_name"],
                   2048: 					     $cdom,$cnum);
                   2049: 	     $code_type=$result{"type\0$old_name"};
1.292     albertel 2050: 	     @allcodes=split(',',$result{$old_name});
1.336     albertel 2051: 	     $num_todo=scalar(@allcodes);
1.389     foxr     2052: 	 } elsif ($selected_code) { # Selection value is always numeric.
1.388     foxr     2053: 	     $num_todo = 1;
                   2054: 	     @allcodes = ($selected_code);
1.385     foxr     2055: 	 } elsif ($single_code) {
                   2056: 
1.387     foxr     2057: 	     $num_todo    = 1;	# Unconditionally one code to do.
1.385     foxr     2058: 	     # If an alpha code have to convert to numbers so it can be
                   2059: 	     # converted back to letters again :-)
                   2060: 	     #
                   2061: 	     if ($code_type ne 'number') {
                   2062: 		 $single_code = &letters_to_num($single_code);
                   2063: 	     }
                   2064: 	     @allcodes = ($single_code);
1.292     albertel 2065: 	 } else {
                   2066: 	     my %allcodes;
1.299     albertel 2067: 	     srand($seed);
1.292     albertel 2068: 	     for (my $i=0;$i<$num_todo;$i++) {
1.381     albertel 2069: 		 $moreenv{'CODE'}=&get_CODE(\%allcodes,$i,$seed,$code_length,
                   2070: 					    $code_type);
1.292     albertel 2071: 	     }
                   2072: 	     if ($code_name) {
                   2073: 		 &Apache::lonnet::put('CODEs',
1.381     albertel 2074: 				      {
                   2075: 					$code_name =>join(',',keys(%allcodes)),
                   2076: 					"type\0$code_name" => $code_type
                   2077: 				      },
1.292     albertel 2078: 				      $cdom,$cnum);
                   2079: 	     }
                   2080: 	     @allcodes=keys(%allcodes);
                   2081: 	 }
1.336     albertel 2082: 	 my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
                   2083: 	 my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'});
1.452     albertel 2084: 	 &adjust_number_to_print($helper);
1.336     albertel 2085: 	 my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'};
                   2086: 	 if ($number_per_page eq '0' || $number_per_page eq 'all') {
                   2087: 	     $number_per_page=$num_todo;
                   2088: 	 }
                   2089: 	 my $flag_latex_header_remove = 'NO'; 
                   2090: 	 my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75');
1.295     albertel 2091: 	 my $count=0;
1.292     albertel 2092: 	 foreach my $code (sort(@allcodes)) {
1.295     albertel 2093: 	     my $file_num=int($count/$number_per_page);
1.381     albertel 2094: 	     if ($code_type eq 'number') { 
                   2095: 		 $moreenv{'CODE'}=$code;
                   2096: 	     } else {
                   2097: 		 $moreenv{'CODE'}=&num_to_letters($code);
                   2098: 	     }
1.375     foxr     2099: 	     my ($output,$fullname, $printed)=
1.288     albertel 2100: 		 &print_resources($r,$helper,'anonymous',$type,\%moreenv,
1.360     albertel 2101: 				  \@master_seq,$flag_latex_header_remove,
                   2102: 				  $LaTeXwidth);
1.375     foxr     2103: 	     $resources_printed .= ":";
1.295     albertel 2104: 	     $print_array[$file_num].=$output;
1.288     albertel 2105: 	     &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
                   2106: 				       &mt('last assignment').' '.$fullname);
                   2107: 	     $flag_latex_header_remove = 'YES';
1.295     albertel 2108: 	     $count++;
1.331     albertel 2109: 	     if (&Apache::loncommon::connection_aborted($r)) { last; }
1.288     albertel 2110: 	 }
                   2111: 	 &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
                   2112: 	 $result .= $print_array[0].'  \end{document}';
                   2113:      } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') {      
1.151     sakharuk 2114:     #prints selected problems from the subdirectory 
                   2115: 	$selectionmade = 6;
                   2116:         my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};
1.154     sakharuk 2117: 	@list_of_files=sort @list_of_files;
1.175     sakharuk 2118: 	my $flag_latex_header_remove = 'NO'; 
                   2119: 	my $rndseed=time;
1.230     albertel 2120: 	if ($helper->{'VARS'}->{'curseed'}) {
                   2121: 	    $rndseed=$helper->{'VARS'}->{'curseed'};
                   2122: 	}
1.151     sakharuk 2123: 	for (my $i=0;$i<=$#list_of_files;$i++) {
1.521     foxr     2124: 
                   2125: 	    &Apache::lonenc::reset_enc();
                   2126: 
1.152     sakharuk 2127: 	    my $urlp = $list_of_files[$i];
1.253     sakharuk 2128: 	    $urlp=~s|//|/|;
1.152     sakharuk 2129: 	    if ($urlp=~/\//) {
1.353     foxr     2130: 		$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.175     sakharuk 2131: 		$form{'rndseed'}=$rndseed;
1.152     sakharuk 2132: 		if ($urlp =~ m|/home/([^/]+)/public_html|) {
                   2133: 		    $urlp =~ s|/home/([^/]*)/public_html|/~$1|;
                   2134: 		} else {
1.302     sakharuk 2135: 		    $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;
1.152     sakharuk 2136: 		}
1.375     foxr     2137: 		$resources_printed .= $urlp.':';
1.515     foxr     2138: 		my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.251     sakharuk 2139: 		if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1.253     sakharuk 2140: 		   ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     2141: 		    #  Don't permanently pervert %form:
                   2142: 		    my %answerform = %form;
                   2143: 		    $answerform{'grade_target'}='answer';
                   2144: 		    $answerform{'answer_output_mode'}='tex';
                   2145: 		    $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
                   2146: 		    $answerform{'rndseed'}=$rndseed;
1.375     foxr     2147: 		    $resources_printed .= $urlp.':';
1.515     foxr     2148: 		    my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.251     sakharuk 2149: 		    if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   2150: 			$texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
                   2151: 		    } else {
1.253     sakharuk 2152: 			$texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
                   2153: 			if ($helper->{'VARS'}->{'construction'} ne '1') {
                   2154: 			    $texversion.='\vskip 0 mm \noindent ';
                   2155: 			    $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
                   2156: 			} else {
                   2157: 			    $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
                   2158: 			    my $URLpath=$urlp;
                   2159: 			    $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
                   2160: 			    $texversion.=&path_to_problem ($URLpath,$LaTeXwidth);
                   2161: 			}
                   2162: 			$texversion.='\vskip 1 mm '.$answer.'\end{document}';
1.251     sakharuk 2163: 		    }
1.174     sakharuk 2164: 		}
1.515     foxr     2165:                 #this chunk is responsible for printing the path to problem
                   2166: 
1.253     sakharuk 2167: 		my $newurlp=$urlp;
                   2168: 		if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;}
                   2169: 		$newurlp=&path_to_problem($newurlp,$LaTeXwidth);
1.242     sakharuk 2170: 		$texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;
1.152     sakharuk 2171: 		if ($flag_latex_header_remove ne 'NO') {
                   2172: 		    $texversion = &latex_header_footer_remove($texversion);
                   2173: 		} else {
                   2174: 		    $texversion =~ s/\\end{document}//;
1.216     sakharuk 2175: 		}
                   2176: 		if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
                   2177: 		    $texversion=&IndexCreation($texversion,$urlp);
1.152     sakharuk 2178: 		}
1.219     sakharuk 2179: 		if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
                   2180: 		    $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
                   2181: 		    
                   2182: 		}
1.152     sakharuk 2183: 		$result .= $texversion;
                   2184: 	    }
                   2185: 	    $flag_latex_header_remove = 'YES';  
1.151     sakharuk 2186: 	}
1.175     sakharuk 2187: 	if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;}
1.152     sakharuk 2188: 	$result .= '\end{document}';      	
1.140     sakharuk 2189:     }
                   2190: #-------------------------------------------------------- corrections for the different page formats
1.499     foxr     2191: 
                   2192:     # Only post process if that has not been turned off e.g. by a raw latex resource.
                   2193: 
                   2194:     if ($do_postprocessing) {
                   2195: 	$result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade);
                   2196: 	$result = &latex_corrections($number_of_columns,$result,$selectionmade,
                   2197: 				     $helper->{'VARS'}->{'ANSWER_TYPE'});
                   2198: 	#if ($numberofcolumns == 1) {
1.451     albertel 2199: 	$result =~ s/\\textwidth\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /;
                   2200: 	$result =~ s/\\textheight\s*=?\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /;
                   2201: 	$result =~ s/\\evensidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
                   2202: 	$result =~ s/\\oddsidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
1.499     foxr     2203: 	#}
                   2204:     }
1.367     foxr     2205: 
1.515     foxr     2206:     # Set URLback if this is a construction space print so we can provide
                   2207:     # a link to the resource being edited.
                   2208:     #
1.274     sakharuk 2209: 
1.276     sakharuk 2210:     my $URLback=''; #link to original document
1.510     albertel 2211:     if ($helper->{'VARS'}->{'construction'} eq '1') {
1.276     sakharuk 2212: 	#prints resource from the construction space
                   2213: 	$URLback='/'.$helper->{'VARS'}->{'filename'};
1.279     albertel 2214: 	if ($URLback=~/([^?]+)/) {
                   2215: 	    $URLback=$1;
                   2216: 	    $URLback=~s|^/~|/priv/|;
                   2217: 	}
1.276     sakharuk 2218:     }
1.375     foxr     2219: 
1.525     www      2220: #-- writing .tex file in prtspool 
                   2221:     my $temp_file;
                   2222:     my $identifier = &Apache::loncommon::get_cgi_id();
                   2223:     my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex";
                   2224:     if (!($#print_array>0)) { 
                   2225:        unless ($temp_file = Apache::File->new('>'.$filename)) {
                   2226: 	  $r->log_error("Couldn't open $filename for output $!");
                   2227: 	  return SERVER_ERROR; 
                   2228:        }
                   2229:        print $temp_file $result;
                   2230:        my $begin=index($result,'\begin{document}',0);
                   2231:        my $inc=substr($result,0,$begin+16); 
1.515     foxr     2232:     } else {
1.525     www      2233:        my $begin=index($result,'\begin{document}',0);
                   2234:        my $inc=substr($result,0,$begin+16);
                   2235:        for (my $i=0;$i<=$#print_array;$i++) {
                   2236: 	  if ($i==0) {
                   2237: 	      $print_array[$i]=$result;
                   2238: 	  } else {
                   2239: 	      $print_array[$i].='\end{document}';
                   2240: 	      $print_array[$i] = 
                   2241: 		&latex_corrections($number_of_columns,$print_array[$i],
                   2242: 				   $selectionmade, 
                   2243: 				   $helper->{'VARS'}->{'ANSWER_TYPE'});
1.515     foxr     2244: 	    
1.525     www      2245: 	      my $anobegin=index($print_array[$i],'\setcounter{page}',0);
                   2246: 	      substr($print_array[$i],0,$anobegin)='';
                   2247: 	      $print_array[$i]=$inc.$print_array[$i];
                   2248: 	  }
                   2249: 	  my $temp_file;
                   2250: 	  my $newfilename=$filename;
                   2251: 	  my $num=$i+1;
                   2252: 	  $newfilename =~s/\.tex$//; 
                   2253: 	  $newfilename=sprintf("%s_%03d.tex",$newfilename, $num);
                   2254: 	  unless ($temp_file = Apache::File->new('>'.$newfilename)) {
                   2255: 	      $r->log_error("Couldn't open $newfilename for output $!");
                   2256: 	      return SERVER_ERROR; 
                   2257: 	  }
                   2258: 	  print $temp_file $print_array[$i];
                   2259:        }
                   2260:     }
                   2261:     my $student_names='';
                   2262:     if ($#print_array>0) {
                   2263:         for (my $i=0;$i<=$#print_array;$i++) {
                   2264:   	  $student_names.=$student_names[$i].'_ENDPERSON_';
1.515     foxr     2265: 	}
1.525     www      2266:     } else {
                   2267: 	if ($#student_names>-1) {
                   2268: 	   $student_names=$student_names[0].'_ENDPERSON_';
1.515     foxr     2269: 	} else {
1.525     www      2270:            my $fullname = &get_name($env{'user.name'},$env{'user.domain'});
                   2271: 	   $student_names=join(':',$env{'user.name'},$env{'user.domain'},
1.515     foxr     2272: 				    $env{'request.course.sec'},$fullname).
                   2273: 					'_ENDPERSON_'.'_END_';
                   2274: 	}
1.525     www      2275:      }
1.515     foxr     2276: 	
1.525     www      2277:      # logic for now is too complex to trace if this has been defined
                   2278:      #  yet.
                   2279:      my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   2280:      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2281:      &Apache::lonnet::appenv({'cgi.'.$identifier.'.file'   => $filename,
1.515     foxr     2282: 				'cgi.'.$identifier.'.layout'  => $laystyle,
                   2283: 				'cgi.'.$identifier.'.numcol'  => $numberofcolumns,
                   2284: 				'cgi.'.$identifier.'.paper'  => $papersize,
                   2285: 				'cgi.'.$identifier.'.selection' => $selectionmade,
                   2286: 				'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
                   2287: 				'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
                   2288: 				'cgi.'.$identifier.'.role' => $perm{'pav'},
                   2289: 				'cgi.'.$identifier.'.numberoffiles' => $#print_array,
                   2290: 				'cgi.'.$identifier.'.studentnames' => $student_names,
1.520     raeburn  2291: 				'cgi.'.$identifier.'.backref' => $URLback,});
1.525     www      2292:     &Apache::lonnet::appenv({"cgi.$identifier.user"    => $env{'user.name'},
1.515     foxr     2293: 				"cgi.$identifier.domain"  => $env{'user.domain'},
                   2294: 				"cgi.$identifier.courseid" => $cnum, 
                   2295: 				"cgi.$identifier.coursedom" => $cdom, 
1.520     raeburn  2296: 				"cgi.$identifier.resources" => $resources_printed});
1.515     foxr     2297: 	
1.525     www      2298:     my $end_page = &Apache::loncommon::end_page();
1.529     raeburn  2299:     my $continue_text = &mt('Continue');
1.525     www      2300:     # If there's been an unrecoverable SSI error, report it to the user
                   2301:     if ($ssi_error) {
                   2302:         my $helpurl = &Apache::loncommon::top_nav_help('Helpdesk');
                   2303:         $r->print('<br /><h2>'.&mt('An unrecoverable network error occurred:').'</h2><p>  '.
1.526     www      2304:                   &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:').
                   2305:                   '<br />'.$ssi_last_error_resource.'<br />'.$ssi_last_error.
                   2306:                   '</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  2307:                   &mt('You may be able to reprint the individual resources for which this error occurred, as the issue may be temporary.').
1.525     www      2308:                   '<br />'.&mt('If the error persists, please contact the [_1] for assistance.',$helpurl).'</p><p>'.
                   2309:                   &mt('We apologize for the inconvenience.').'</p>'.
1.528     raeburn  2310:                   '<a href="/cgi-bin/printout.pl?'.$identifier.'">'.$continue_text.'</a>'.$end_page);
1.525     www      2311:     } else {
1.515     foxr     2312: 	$r->print(<<FINALEND);
1.317     albertel 2313: <br />
1.288     albertel 2314: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.528     raeburn  2315: <a href="/cgi-bin/printout.pl?$identifier">$continue_text</a>
1.431     albertel 2316: $end_page
1.140     sakharuk 2317: FINALEND
1.528     raeburn  2318:     }                                     # endif ssi errors.
1.140     sakharuk 2319: }
                   2320: 
1.288     albertel 2321: 
                   2322: sub get_CODE {
1.381     albertel 2323:     my ($all_codes,$num,$seed,$size,$type)=@_;
1.288     albertel 2324:     my $max='1'.'0'x$size;
                   2325:     my $newcode;
                   2326:     while(1) {
1.392     albertel 2327: 	$newcode=sprintf("%0".$size."d",int(rand($max)));
1.288     albertel 2328: 	if (!exists($$all_codes{$newcode})) {
                   2329: 	    $$all_codes{$newcode}=1;
1.381     albertel 2330: 	    if ($type eq 'number' ) {
                   2331: 		return $newcode;
                   2332: 	    } else {
                   2333: 		return &num_to_letters($newcode);
                   2334: 	    }
1.288     albertel 2335: 	}
                   2336:     }
                   2337: }
1.140     sakharuk 2338: 
1.284     albertel 2339: sub print_resources {
1.360     albertel 2340:     my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422     albertel 2341: 	$LaTeXwidth)=@_;
1.284     albertel 2342:     my $current_output = ''; 
1.375     foxr     2343:     my $printed = '';
1.284     albertel 2344:     my ($username,$userdomain,$usersection) = split /:/,$person;
                   2345:     my $fullname = &get_name($username,$userdomain);
1.492     foxr     2346:     my $namepostfix = "\\\\";	# Both anon and not anon should get the same vspace.
1.288     albertel 2347:     if ($person =~ 'anon') {
1.492     foxr     2348: 	$namepostfix .="Name: ";
1.288     albertel 2349: 	$fullname = "CODE - ".$moreenv->{'CODE'};
                   2350:     }
1.444     foxr     2351:     #  Fullname may have special latex characters that need \ prefixing:
                   2352:     #
                   2353: 
1.350     foxr     2354:     my $i           = 0;
1.284     albertel 2355:     #goes through all resources, checks if they are available for 
                   2356:     #current student, and produces output   
1.428     albertel 2357: 
                   2358:     &Apache::lonxml::clear_problem_counter();
1.364     albertel 2359:     my %page_breaks  = &get_page_breaks($helper);
1.476     albertel 2360:     my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440     foxr     2361:     #
1.441     foxr     2362:     #   end each student with a 
1.440     foxr     2363:     #   Special that allows the post processor to even out the page
                   2364:     #   counts later.  Nasty problem this... it would be really
                   2365:     #   nice to put the special in as a postscript comment
1.441     foxr     2366:     #   e.g. \special{ps:\ENDOFSTUDENTSTAMP}  unfortunately,
1.440     foxr     2367:     #   The special gets passed the \ and dvips puts it in the output file
1.441     foxr     2368:     #   so we will just rely on prntout.pl to strip  ENDOFSTUDENTSTAMP from the
                   2369:     #   postscript.  Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440     foxr     2370:     #
1.363     foxr     2371: 
1.511     foxr     2372: 
1.284     albertel 2373:     foreach my $curresline (@{$master_seq})  {
1.351     foxr     2374: 	if (defined $page_breaks{$curresline}) {
1.350     foxr     2375: 	    if($i != 0) {
                   2376: 		$current_output.= "\\newpage\n";
                   2377: 	    }
                   2378: 	}
                   2379: 	$i++;
1.511     foxr     2380: 
1.284     albertel 2381: 	if ( !($type eq 'problems' && 
                   2382: 	       ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
                   2383: 	    my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
                   2384: 	    if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414     albertel 2385: 		if ($res_url!~m|^ext/|
1.413     albertel 2386: 		    && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375     foxr     2387: 		    $printed .= $curresline.':';
1.428     albertel 2388: 
                   2389: 		    &Apache::lonxml::remember_problem_counter();    
                   2390: 
1.526     www      2391: 		    my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428     albertel 2392: 
1.305     sakharuk 2393: 		    if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   2394: 		       ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     2395: 			#   Use a copy of the hash so we don't pervert it on future loop passes.
                   2396: 			my %answerenv = %{$moreenv};
                   2397: 			$answerenv{'answer_output_mode'}='tex';
                   2398: 			$answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428     albertel 2399: 			
                   2400: 			&Apache::lonxml::restore_problem_counter();
                   2401: 
1.380     foxr     2402: 			my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428     albertel 2403: 
1.305     sakharuk 2404: 			if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   2405: 			    $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
                   2406: 			} else {
1.423     foxr     2407: 
                   2408: 			    
                   2409: 			    my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477     albertel 2410: 			    my $title = &Apache::lonnet::gettitle($curresline);
                   2411: 			    $title = &Apache::lonxml::latex_special_symbols($title);
                   2412: 			    my $body   ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
                   2413: 			    $body     .=&path_to_problem($res_url,$LaTeXwidth);
1.423     foxr     2414: 			    $body     .='\vskip 1 mm '.$ansrendered;
                   2415: 			    $body     = &encapsulate_minipage($body);
                   2416: 			    $rendered = $header.$body;
1.305     sakharuk 2417: 			}
                   2418: 		    }
1.511     foxr     2419: 
                   2420: 		    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   2421: 			my $url = &Apache::lonnet::clutter($res_url);
                   2422: 			my $annotation = &annotate($url);
                   2423: 			$rendered =~  s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
                   2424: 		    }
1.305     sakharuk 2425: 		    if ($remove_latex_header eq 'YES') {
                   2426: 			$rendered = &latex_header_footer_remove($rendered);
                   2427: 		    } else {
                   2428: 			$rendered =~ s/\\end{document}//;
                   2429: 		    }
                   2430: 		    $current_output .= $rendered;		    
1.456     raeburn  2431: 		} elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.375     foxr     2432: 		    $printed .= $curresline.':';
1.528     raeburn  2433: 		    my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.511     foxr     2434: 		    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   2435: 			my $url = &Apache::lonnet::clutter($res_url);
                   2436: 			my $annotation = &annotate($url);
                   2437: 			$annotation    =~ s/(\\end{document})/$annotation$1/;
                   2438: 		    }
1.305     sakharuk 2439: 		    if ($remove_latex_header eq 'YES') {
                   2440: 			$rendered = &latex_header_footer_remove($rendered);
1.284     albertel 2441: 		    } else {
1.305     sakharuk 2442: 			$rendered =~ s/\\end{document}//;
1.284     albertel 2443: 		    }
1.421     foxr     2444: 		    $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
                   2445: 
1.284     albertel 2446: 		} else {
1.414     albertel 2447: 		    my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305     sakharuk 2448: 		    if ($remove_latex_header ne 'NO') {
                   2449: 			$rendered = &latex_header_footer_remove($rendered);
                   2450: 		    } else {
                   2451: 			$rendered =~ s/\\end{document}//;
                   2452: 		    }
                   2453: 		    $current_output .= $rendered;
1.284     albertel 2454: 		}
                   2455: 	    }
                   2456: 	    $remove_latex_header = 'YES';
1.550     foxr     2457: 	} 
1.331     albertel 2458: 	if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284     albertel 2459:     }
                   2460:     my $courseidinfo = &get_course();
                   2461:     my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476     albertel 2462:     my $header_line =
1.486     foxr     2463: 	&format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.537     foxr     2464: 			    $currentassignment, $courseidinfo, $fullname, $usersection);
1.476     albertel 2465:     my $header_start = ($columns_in_format == 1) ? '\lhead'
                   2466: 	                                         : '\fancyhead[LO]';
                   2467:     $header_line = $header_start.'{'.$header_line.'}';
                   2468: 
1.284     albertel 2469:     if ($current_output=~/\\documentclass/) {
1.476     albertel 2470: 	$current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.284     albertel 2471:     } else {
1.476     albertel 2472: 	my $blankpages = 
                   2473: 	    '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
                   2474: 	    
                   2475: 	$current_output = '\strut\vspace*{-6 mm}\\newline'.
                   2476: 	    &copyright_line().' \newpage '.$blankpages.$end_of_student.
                   2477: 	    '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
                   2478: 	    $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284     albertel 2479:     }
1.440     foxr     2480:     #
                   2481:     #  Close the student bracketing.
                   2482:     #
1.375     foxr     2483:     return ($current_output,$fullname, $printed);
1.284     albertel 2484: 
                   2485: }
1.140     sakharuk 2486: 
1.3       sakharuk 2487: sub handler {
                   2488: 
                   2489:     my $r = shift;
1.397     albertel 2490:     
                   2491:     &init_perm();
1.114     bowersj2 2492: 
1.416     foxr     2493: 
1.67      www      2494: 
1.397     albertel 2495:     my $helper = printHelper($r);
                   2496:     if (!ref($helper)) {
                   2497: 	return $helper;
1.60      sakharuk 2498:     }
1.177     sakharuk 2499:    
1.184     sakharuk 2500: 
1.454     foxr     2501:     %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353     foxr     2502:  
1.416     foxr     2503: 
1.350     foxr     2504: 
                   2505: 
1.367     foxr     2506:     #  If a figure conversion queue file exists for this user.domain
                   2507:     # we delete it since it can only be bad (if it were good, printout.pl
                   2508:     # would have deleted it the last time around.
                   2509: 
1.373     albertel 2510:     my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367     foxr     2511:     if(-e $conversion_queuefile) {
                   2512: 	unlink $conversion_queuefile;
                   2513:     }
1.515     foxr     2514:     
                   2515: 
1.184     sakharuk 2516:     &output_data($r,$helper,\%parmhash);
1.2       sakharuk 2517:     return OK;
1.60      sakharuk 2518: } 
1.2       sakharuk 2519: 
1.131     bowersj2 2520: use Apache::lonhelper;
1.130     sakharuk 2521: 
1.223     bowersj2 2522: sub addMessage {
                   2523:     my $text = shift;
                   2524:     my $paramHash = Apache::lonhelper::getParamHash();
                   2525:     $paramHash->{MESSAGE_TEXT} = $text;
                   2526:     Apache::lonhelper::message->new();
                   2527: }
                   2528: 
1.416     foxr     2529: 
1.238     bowersj2 2530: 
1.397     albertel 2531: sub init_perm {
                   2532:     undef(%perm);
                   2533:     $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
                   2534:     if (!$perm{'pav'}) {
                   2535: 	$perm{'pav'}=&Apache::lonnet::allowed('pav',
                   2536: 		  $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   2537:     }
1.465     albertel 2538:     $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397     albertel 2539:     if (!$perm{'pfo'}) {
                   2540: 	$perm{'pfo'}=&Apache::lonnet::allowed('pfo',
                   2541: 		  $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   2542:     }
                   2543: }
                   2544: 
1.507     albertel 2545: sub get_randomly_ordered_warning {
                   2546:     my ($helper,$map) = @_;
                   2547: 
                   2548:     my $message;
                   2549: 
                   2550:     my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
                   2551:     my $navmap = Apache::lonnavmaps::navmap->new();
1.547     raeburn  2552:     if (defined($navmap)) {
                   2553:         my $res = $navmap->getResourceByUrl($map);
                   2554:         if ($res) {
                   2555: 	    my $func = 
                   2556: 	        sub { return ($_[0]->is_map() && $_[0]->randomorder); };
                   2557: 	    my @matches = $navmap->retrieveResources($res, $func,1,1,1);
                   2558: 	    if (@matches) {
                   2559: 	        $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.";
                   2560: 	    }
                   2561:         }
                   2562:         if ($message) {
                   2563: 	    return '<message type="warning">'.$message.'</message>';
                   2564:         }
                   2565:     } else {
                   2566:         $message = "Retrieval of information about ordering of resources failed."; 
                   2567:         return '<message type="warning">'.$message.'</message>';
1.507     albertel 2568:     }
                   2569:     return;
                   2570: }
                   2571: 
1.131     bowersj2 2572: sub printHelper {
1.115     bowersj2 2573:     my $r = shift;
                   2574: 
                   2575:     if ($r->header_only) {
1.373     albertel 2576:         if ($env{'browser.mathml'}) {
1.241     www      2577:             &Apache::loncommon::content_type($r,'text/xml');
1.131     bowersj2 2578:         } else {
1.241     www      2579:             &Apache::loncommon::content_type($r,'text/html');
1.131     bowersj2 2580:         }
                   2581:         $r->send_http_header;
                   2582:         return OK;
1.115     bowersj2 2583:     }
                   2584: 
1.131     bowersj2 2585:     # Send header, nocache
1.373     albertel 2586:     if ($env{'browser.mathml'}) {
1.241     www      2587:         &Apache::loncommon::content_type($r,'text/xml');
1.115     bowersj2 2588:     } else {
1.241     www      2589:         &Apache::loncommon::content_type($r,'text/html');
1.115     bowersj2 2590:     }
                   2591:     &Apache::loncommon::no_cache($r);
                   2592:     $r->send_http_header;
                   2593:     $r->rflush();
                   2594: 
1.131     bowersj2 2595:     # Unfortunately, this helper is so complicated we have to
                   2596:     # write it by hand
                   2597: 
                   2598:     Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
                   2599:     
1.176     bowersj2 2600:     my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146     bowersj2 2601:     $helper->declareVar('symb');
1.156     bowersj2 2602:     $helper->declareVar('postdata');    
1.290     sakharuk 2603:     $helper->declareVar('curseed'); 
                   2604:     $helper->declareVar('probstatus');   
1.156     bowersj2 2605:     $helper->declareVar('filename');
                   2606:     $helper->declareVar('construction');
1.178     sakharuk 2607:     $helper->declareVar('assignment');
1.262     sakharuk 2608:     $helper->declareVar('style_file');
1.340     foxr     2609:     $helper->declareVar('student_sort');
1.363     foxr     2610:     $helper->declareVar('FINISHPAGE');
1.366     foxr     2611:     $helper->declareVar('PRINT_TYPE');
1.372     foxr     2612:     $helper->declareVar("showallfoils");
1.483     foxr     2613:     $helper->declareVar("STUDENTS");
1.363     foxr     2614: 
1.518     foxr     2615: 
                   2616:    
                   2617: 
                   2618: 
1.363     foxr     2619:     #  The page breaks can get loaded initially from the course environment:
1.394     foxr     2620:     # But we only do this in the initial state so that they are allowed to change.
                   2621:     #
1.366     foxr     2622: 
1.416     foxr     2623:     # $helper->{VARS}->{FINISHPAGE} = '';
1.363     foxr     2624:     
                   2625:     &Apache::loncommon::restore_course_settings('print',
1.366     foxr     2626: 						{'pagebreaks'  => 'scalar',
                   2627: 					         'lastprinttype' => 'scalar'});
                   2628:     
1.483     foxr     2629:     # This will persistently load in the data we want from the
                   2630:     # very first screen.
1.394     foxr     2631:     
                   2632:     if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
                   2633: 	if (!defined ($env{"form.CURRENT_STATE"})) {
                   2634: 	    
                   2635: 	    $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
                   2636: 	} else {
                   2637: 	    my $state = $env{"form.CURRENT_STATE"};
                   2638: 	    if ($state eq "START") {
                   2639: 		$helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
                   2640: 	    }
                   2641: 	}
                   2642: 	
1.366     foxr     2643:     }
1.481     albertel 2644: 
1.156     bowersj2 2645:     # Detect whether we're coming from construction space
1.373     albertel 2646:     if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235     bowersj2 2647:         $helper->{VARS}->{'filename'} = "~$1/$2";
1.156     bowersj2 2648:         $helper->{VARS}->{'construction'} = 1;
1.481     albertel 2649:     } else {
1.373     albertel 2650:         if ($env{'form.postdata'}) {
                   2651:             $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482     albertel 2652: 	    if ( $helper->{VARS}->{'symb'} eq '') {
                   2653: 		$helper->{VARS}->{'postdata'} = $env{'form.postdata'};
                   2654: 	    }
1.156     bowersj2 2655:         }
1.373     albertel 2656:         if ($env{'form.symb'}) {
                   2657:             $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156     bowersj2 2658:         }
1.373     albertel 2659:         if ($env{'form.url'}) {
1.156     bowersj2 2660:             $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
                   2661:         }
1.416     foxr     2662: 
1.157     bowersj2 2663:     }
1.481     albertel 2664: 
1.373     albertel 2665:     if ($env{'form.symb'}) {
                   2666:         $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146     bowersj2 2667:     }
1.373     albertel 2668:     if ($env{'form.url'}) {
1.140     sakharuk 2669:         $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153     sakharuk 2670: 
1.140     sakharuk 2671:     }
1.343     albertel 2672:     $helper->{VARS}->{'symb'}=
                   2673: 	&Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335     albertel 2674:     my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178     sakharuk 2675:     if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481     albertel 2676: 
1.156     bowersj2 2677:     
1.146     bowersj2 2678:     # Extract map
                   2679:     my $symb = $helper->{VARS}->{'symb'};
1.156     bowersj2 2680:     my ($map, $id, $url);
                   2681:     my $subdir;
1.483     foxr     2682:     my $is_published=0;		# True when printing from resource space.
1.156     bowersj2 2683: 
                   2684:     # Get the resource name from construction space
                   2685:     if ($helper->{VARS}->{'construction'}) {
                   2686:         $resourceTitle = substr($helper->{VARS}->{'filename'}, 
                   2687:                                 rindex($helper->{VARS}->{'filename'}, '/')+1);
                   2688:         $subdir = substr($helper->{VARS}->{'filename'},
                   2689:                          0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481     albertel 2690:     } else {
1.482     albertel 2691: 	if ($symb ne '') {
                   2692: 	    ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
                   2693: 	    $helper->{VARS}->{'postdata'} = 
                   2694: 		&Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
                   2695: 	} else {
                   2696: 	    $url = $helper->{VARS}->{'postdata'};
1.483     foxr     2697: 	    $is_published=1;	# From resource space.
1.482     albertel 2698: 	}
                   2699: 	$url = &Apache::lonnet::clutter($url);
1.481     albertel 2700: 
1.156     bowersj2 2701:         if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238     bowersj2 2702:             my $postdata = $helper->{VARS}->{'postdata'};
                   2703:             $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156     bowersj2 2704:         }
                   2705:         $subdir = &Apache::lonnet::filelocation("", $url);
1.128     bowersj2 2706:     }
1.373     albertel 2707:     if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
                   2708: 	$helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230     albertel 2709:     }
1.373     albertel 2710:     if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
1.512     foxr     2711: 	$helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
1.290     sakharuk 2712:     }
1.115     bowersj2 2713: 
1.192     bowersj2 2714:     my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
                   2715: 
1.481     albertel 2716:     Apache::lonhelper::registerHelperTags();
1.119     bowersj2 2717: 
1.131     bowersj2 2718:     # "Delete everything after the last slash."
1.119     bowersj2 2719:     $subdir =~ s|/[^/]+$||;
                   2720: 
1.131     bowersj2 2721:     # What can be printed is a very dynamic decision based on
                   2722:     # lots of factors. So we need to dynamically build this list.
                   2723:     # To prevent security leaks, states are only added to the wizard
                   2724:     # if they can be reached, which ensures manipulating the form input
                   2725:     # won't allow anyone to reach states they shouldn't have permission
                   2726:     # to reach.
                   2727: 
                   2728:     # printChoices is tracking the kind of printing the user can
                   2729:     # do, and will be used in a choices construction later.
                   2730:     # In the meantime we will be adding states and elements to
                   2731:     # the helper by hand.
                   2732:     my $printChoices = [];
                   2733:     my $paramHash;
1.130     sakharuk 2734: 
1.240     albertel 2735:     if ($resourceTitle) {
1.458     www      2736:         push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156     bowersj2 2737:     }
                   2738: 
1.238     bowersj2 2739:     # Useful filter strings
1.540     raeburn  2740:     my $isProblem = '($res->is_problem()||$res->contains_problem||$res->is_practice()) ';
1.238     bowersj2 2741:     $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.541     raeburn  2742:     my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice()';
1.287     albertel 2743:     my $isNotMap = '!$res->is_sequence()';
1.238     bowersj2 2744:     $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
                   2745:     my $isMap = '$res->is_map()';
1.342     albertel 2746:     my $symbFilter = '$res->shown_symb()';
                   2747:     my $urlValue = '$res->link()';
1.238     bowersj2 2748: 
                   2749:     $helper->declareVar('SEQUENCE');
                   2750: 
1.465     albertel 2751:     # If we're in a sequence...
1.416     foxr     2752: 
1.465     albertel 2753:     my $start_new_option;
                   2754:     if ($perm{'pav'}) {
                   2755: 	$start_new_option = 
                   2756: 	    "<option text='".&mt('Start new page<br />before selected').
                   2757: 	    "' variable='FINISHPAGE' />";
                   2758:     }
1.238     bowersj2 2759: 
1.483     foxr     2760:     if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
1.243     bowersj2 2761: 	$helper->{VARS}->{'postdata'} &&
                   2762: 	$helper->{VARS}->{'assignment'}) {
1.131     bowersj2 2763:         # Allow problems from sequence
1.546     bisitz   2764:         push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'), 'map_problems', 'CHOOSE_PROBLEMS'];
1.131     bowersj2 2765:         # Allow all resources from sequence
1.546     bisitz   2766:         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 2767: 
1.131     bowersj2 2768:         my $helperFragment = <<HELPERFRAGMENT;
1.155     sakharuk 2769:   <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print">
1.435     foxr     2770:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 2771:               closeallpages="1">
1.144     bowersj2 2772:       <nextstate>PAGESIZE</nextstate>
1.435     foxr     2773:       <filterfunc>return $isProblem;</filterfunc>
1.131     bowersj2 2774:       <mapurl>$map</mapurl>
1.238     bowersj2 2775:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2776:       $start_new_option
1.131     bowersj2 2777:       </resource>
                   2778:     </state>
                   2779: 
1.155     sakharuk 2780:   <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print">
1.435     foxr     2781:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 2782:               closeallpages="1">
1.144     bowersj2 2783:       <nextstate>PAGESIZE</nextstate>
1.435     foxr     2784:       <filterfunc>return $isNotMap;</filterfunc>
1.131     bowersj2 2785:       <mapurl>$map</mapurl>
1.238     bowersj2 2786:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2787:       $start_new_option
1.131     bowersj2 2788:       </resource>
                   2789:     </state>
                   2790: HELPERFRAGMENT
1.121     bowersj2 2791: 
1.326     sakharuk 2792: 	&Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121     bowersj2 2793:     }
                   2794: 
1.546     bisitz   2795:     # If the user has pfo (print for others) allow them to print all 
                   2796:     # problems and resources  in the entire course, optionally for selected students
1.483     foxr     2797:     if ($perm{'pfo'} &&  !$is_published  &&
1.481     albertel 2798:         ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) { 
                   2799: 
1.509     albertel 2800:         push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
                   2801: 	push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.536     foxr     2802: 	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 2803:          &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS);
1.155     sakharuk 2804:   <state name="ALL_PROBLEMS" title="Select Problem(s) to print">
1.287     albertel 2805:     <resource variable="RESOURCES" toponly='0' multichoice="1"
                   2806: 	suppressEmptySequences='0' addstatus="1" closeallpages="1">
1.144     bowersj2 2807:       <nextstate>PAGESIZE</nextstate>
1.192     bowersj2 2808:       <filterfunc>return $isProblemOrMap;</filterfunc>
1.287     albertel 2809:       <choicefunc>return $isNotMap;</choicefunc>
1.238     bowersj2 2810:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2811:       $start_new_option
1.284     albertel 2812:     </resource>
                   2813:   </state>
1.354     foxr     2814:   <state name="ALL_RESOURCES" title="Select Resource(s) to print">
                   2815:     <resource variable="RESOURCES" toponly='0' multichoice='1'
                   2816:               suppressEmptySequences='0' addstatus='1' closeallpages='1'>
                   2817:       <nextstate>PAGESIZE</nextstate>
                   2818:       <filterfunc>return $isNotMap; </filterfunc>
                   2819:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2820:       $start_new_option
1.354     foxr     2821:     </resource>
                   2822:   </state>
1.536     foxr     2823:   <state name="ALL_PROBLEMS_STUDENTS" title="Select Problem(s) to print">
                   2824:     <resource variable="RESOURCES" toponly='0' multichoice="1"
                   2825: 	suppressEmptySequences='0' addstatus="1" closeallpages="1">
                   2826:       <nextstate>STUDENTS1</nextstate>
                   2827:       <filterfunc>return $isProblemOrMap;</filterfunc>
                   2828:       <choicefunc>return $isNotMap;</choicefunc>
                   2829:       <valuefunc>return $symbFilter;</valuefunc>
                   2830:       $start_new_option
                   2831:     </resource>
                   2832:   </state>
                   2833:   <state name="STUDENTS1" title="Select People">
                   2834:       <message><b>Select sorting order of printout</b> </message>
                   2835:     <choices variable='student_sort'>
                   2836:       <choice computer='0'>Sort by section then student</choice>
                   2837:       <choice computer='1'>Sort by students across sections.</choice>
                   2838:     </choices>
                   2839:       <message><br /><hr /><br /> </message>
                   2840:       <student multichoice='1' variable="STUDENTS" nextstate="PRINT_FORMATTING" coursepersonnel="1"/>
                   2841:   </state>
                   2842: 
1.284     albertel 2843: ALL_PROBLEMS
1.132     bowersj2 2844: 
1.284     albertel 2845: 	if ($helper->{VARS}->{'assignment'}) {
1.546     bisitz   2846: 	    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'];
                   2847: 	    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 2848: 	}
1.424     foxr     2849: 
1.507     albertel 2850: 	my $randomly_ordered_warning = 
                   2851: 	    &get_randomly_ordered_warning($helper,$map);
                   2852: 
1.424     foxr     2853: 	# resource_selector will hold a few states that:
                   2854: 	#   - Allow resources to be selected for printing.
                   2855: 	#   - Determine pagination between assignments.
                   2856: 	#   - Determine how many assignments should be bundled into a single PDF.
                   2857:         # TODO:
                   2858: 	#    Probably good to do things like separate this up into several vars, each
                   2859: 	#    with one state, and use REGEXPs at inclusion time to set state names
                   2860: 	#    and next states for better mix and match capability
                   2861: 	#
1.284     albertel 2862: 	my $resource_selector=<<RESOURCE_SELECTOR;
1.424     foxr     2863:     <state name="SELECT_PROBLEMS" title="Select resources to print">
1.507     albertel 2864:     $randomly_ordered_warning
                   2865: 
1.424     foxr     2866:    <nextstate>PRINT_FORMATTING</nextstate> 
1.284     albertel 2867:    <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287     albertel 2868:     <resource variable="RESOURCES" multichoice="1" addstatus="1" 
                   2869:               closeallpages="1">
1.254     sakharuk 2870:       <filterfunc>return $isProblem;</filterfunc>
1.148     bowersj2 2871:       <mapurl>$map</mapurl>
1.254     sakharuk 2872:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2873:       $start_new_option
1.147     bowersj2 2874:       </resource>
1.424     foxr     2875:     </state>
                   2876:     <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155     sakharuk 2877:     <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149     bowersj2 2878:     <choices variable="EMPTY_PAGES">
1.204     sakharuk 2879:       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
                   2880:       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
                   2881:       <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
                   2882:       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284     albertel 2883:     </choices>
1.424     foxr     2884:     <nextstate>PAGESIZE</nextstate>
1.429     foxr     2885:     <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
                   2886:     <choices variable="SPLIT_PDFS">
                   2887:        <choice computer="all">All assignments in a single PDF file</choice>
                   2888:        <choice computer="sections">Each PDF contains exactly one section</choice>
                   2889:        <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449     albertel 2890:        <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
                   2891:             Specify the number of assignments per PDF:</choice>
1.429     foxr     2892:     </choices>
1.424     foxr     2893:     </state>
1.284     albertel 2894: RESOURCE_SELECTOR
                   2895: 
                   2896:         &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS);
                   2897:   <state name="CHOOSE_STUDENTS" title="Select Students and Resources">
1.485     albertel 2898:       <message><b>Select sorting order of printout</b> </message>
1.340     foxr     2899:     <choices variable='student_sort'>
                   2900:       <choice computer='0'>Sort by section then student</choice>
                   2901:       <choice computer='1'>Sort by students across sections.</choice>
                   2902:     </choices>
1.437     foxr     2903:       <message><br /><hr /><br /> </message>
1.425     foxr     2904:       <student multichoice='1' variable="STUDENTS" nextstate="SELECT_PROBLEMS" coursepersonnel="1"/>
1.424     foxr     2905:   </state>
1.284     albertel 2906:     $resource_selector
1.131     bowersj2 2907: CHOOSE_STUDENTS
1.292     albertel 2908: 
1.373     albertel 2909: 	my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2910: 	my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292     albertel 2911:         my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
                   2912: 	my $namechoice='<choice></choice>';
1.337     albertel 2913: 	foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294     albertel 2914: 	    if ($name =~ /^error: 2 /) { next; }
1.381     albertel 2915: 	    if ($name =~ /^type\0/) { next; }
1.292     albertel 2916: 	    $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
                   2917: 	}
1.389     foxr     2918: 
                   2919: 
                   2920: 	my %code_values;
1.405     albertel 2921: 	my %codes_to_print;
1.411     albertel 2922: 	foreach my $key (@names) {
1.389     foxr     2923: 	    %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405     albertel 2924: 	    foreach my $key (keys(%code_values)) {
                   2925: 		$codes_to_print{$key} = 1;
1.388     foxr     2926: 	    }
                   2927: 	}
1.389     foxr     2928: 
1.452     albertel 2929: 	my $code_selection;
1.405     albertel 2930: 	foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389     foxr     2931: 	    my $choice  = $code;
                   2932: 	    if ($code =~ /^[A-Z]+$/) { # Alpha code
                   2933: 		$choice = &letters_to_num($code);
                   2934: 	    }
1.432     albertel 2935: 	    push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388     foxr     2936: 	}
1.436     albertel 2937: 	if (%codes_to_print) {
                   2938: 	    $code_selection .='   
1.472     albertel 2939: 	    <message><b>Choose single CODE from list:</b></message>
1.448     albertel 2940: 		<message></td><td></message>
1.452     albertel 2941: 		<dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
                   2942:                   <choice></choice>
1.448     albertel 2943:                   <exec>
                   2944:                      push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
                   2945:                   </exec>
1.452     albertel 2946: 		</dropdown>
1.468     foxr     2947: 	    <message></td></tr><tr><td></message>
1.436     albertel 2948:             '.$/;
1.448     albertel 2949: 
1.436     albertel 2950: 	}
1.432     albertel 2951: 
1.542     raeburn  2952:         my @lines = &Apache::grades::get_scantronformat_file();
1.381     albertel 2953: 	my $codechoice='';
1.542     raeburn  2954: 	foreach my $line (@lines) {
1.381     albertel 2955: 	    my ($name,$description,$code_type,$code_length)=
                   2956: 		(split(/:/,$line))[0,1,2,4];
                   2957: 	    if ($code_length > 0 && 
                   2958: 		$code_type =~/^(letter|number|-1)/) {
                   2959: 		$codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
                   2960: 	    }
                   2961: 	}
                   2962: 	if ($codechoice eq '') {
                   2963: 	    $codechoice='<choice computer="default">Default</choice>';
                   2964: 	}
1.284     albertel 2965:         &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1);
1.468     foxr     2966:   <state name="CHOOSE_ANON1" title="Specify CODEd Assignments">
1.424     foxr     2967:     <nextstate>SELECT_PROBLEMS</nextstate>
1.468     foxr     2968:     <message><h4>Fill out one of the forms below</h4></message>
                   2969:     <message><br /><hr /> <br /></message>
                   2970:     <message><h3>Generate new CODEd Assignments</h3></message>
                   2971:     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362     albertel 2972:     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
                   2973:        <validator>
                   2974: 	if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.382     foxr     2975: 	    !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
1.388     foxr     2976:             !\$helper->{'VARS'}{'SINGLE_CODE'}                    &&
                   2977: 	    !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362     albertel 2978: 	    return "You need to specify the number of assignments to print";
                   2979: 	}
                   2980: 	return undef;
                   2981:        </validator>
                   2982:     </string>
                   2983:     <message></td></tr><tr><td></message>
1.501     albertel 2984:     <message><b>Names to save the CODEs under for later:</b></message>
1.412     albertel 2985:     <message></td><td></message>
                   2986:     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
                   2987:     <message></td></tr><tr><td></message>
                   2988:     <message><b>Bubble sheet type:</b></message>
                   2989:     <message></td><td></message>
                   2990:     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
                   2991:     $codechoice
                   2992:     </dropdown>
1.468     foxr     2993:     <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>
                   2994:     <message></td></tr><tr><td></table></message>
1.472     albertel 2995:     <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
1.468     foxr     2996:     <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412     albertel 2997:     <string variable="SINGLE_CODE" size="10">
1.382     foxr     2998:         <validator>
                   2999: 	   if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&
1.388     foxr     3000: 	      !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&
                   3001: 	      !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.382     foxr     3002: 	      return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
                   3003: 						      \$helper->{'VARS'}{'CODE_OPTION'});
                   3004: 	   } else {
                   3005: 	       return undef;	# Other forces control us.
                   3006: 	   }
                   3007:         </validator>
                   3008:     </string>
1.472     albertel 3009:     <message></td></tr><tr><td></message>
1.432     albertel 3010:         $code_selection
1.468     foxr     3011:     <message></td></tr></table></message>
1.472     albertel 3012:     <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
1.468     foxr     3013:     <message><b>Select saved CODEs:</b></message>
1.381     albertel 3014:     <message></td><td></message>
1.292     albertel 3015:     <dropdown variable="REUSE_OLD_CODES">
                   3016:         $namechoice
                   3017:     </dropdown>
1.412     albertel 3018:     <message></td></tr></table></message>
1.284     albertel 3019:   </state>
1.424     foxr     3020:   $resource_selector
1.284     albertel 3021: CHOOSE_ANON1
1.254     sakharuk 3022: 
1.272     sakharuk 3023: 
1.254     sakharuk 3024: 	if ($helper->{VARS}->{'assignment'}) {
1.546     bisitz   3025: 	    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'];
                   3026: 	    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 3027: 	}
1.284     albertel 3028: 	    
                   3029: 
                   3030: 	$resource_selector=<<RESOURCE_SELECTOR;
1.424     foxr     3031:     <state name="SELECT_RESOURCES" title="Select Resources">
1.507     albertel 3032:     $randomly_ordered_warning
                   3033: 
1.424     foxr     3034:     <nextstate>PRINT_FORMATTING</nextstate>
1.254     sakharuk 3035:     <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287     albertel 3036:     <resource variable="RESOURCES" multichoice="1" addstatus="1" 
                   3037:               closeallpages="1">
1.254     sakharuk 3038:       <filterfunc>return $isNotMap;</filterfunc>
                   3039:       <mapurl>$map</mapurl>
                   3040:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 3041:       $start_new_option
1.254     sakharuk 3042:       </resource>
1.424     foxr     3043:     </state>
                   3044:     <state name="PRINT_FORMATTING" title="Format of the print job">
                   3045:     <nextstate>NUMBER_PER_PDF</nextstate>
1.254     sakharuk 3046:     <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
                   3047:     <choices variable="EMPTY_PAGES">
                   3048:       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
                   3049:       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
                   3050:       <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
                   3051:       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284     albertel 3052:     </choices>
1.424     foxr     3053:     <nextstate>PAGESIZE</nextstate>
1.429     foxr     3054:     <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
                   3055:     <choices variable="SPLIT_PDFS">
                   3056:        <choice computer="all">All assignments in a single PDF file</choice>
                   3057:        <choice computer="sections">Each PDF contains exactly one section</choice>
                   3058:        <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449     albertel 3059:        <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
                   3060:            Specify the number of assignments per PDF:</choice>
1.429     foxr     3061:     </choices>
1.424     foxr     3062:     </state>
1.284     albertel 3063: RESOURCE_SELECTOR
                   3064: 
                   3065: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
                   3066:   <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340     foxr     3067:     <choices variable='student_sort'>
                   3068:       <choice computer='0'>Sort by section then student</choice>
                   3069:       <choice computer='1'>Sort by students across sections.</choice>
                   3070:     </choices>
1.437     foxr     3071:     <message><br /><hr /><br /></message>
1.426     foxr     3072:     <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340     foxr     3073: 
1.424     foxr     3074:     </state>
1.284     albertel 3075:     $resource_selector
1.254     sakharuk 3076: CHOOSE_STUDENTS1
                   3077: 
1.284     albertel 3078: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472     albertel 3079:   <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424     foxr     3080:     <nextstate>SELECT_RESOURCES</nextstate>
1.472     albertel 3081:     <message><h4>Fill out one of the forms below</h4></message>
                   3082:     <message><br /><hr /> <br /></message>
                   3083:     <message><h3>Generate new CODEd Assignments</h3></message>
                   3084:     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362     albertel 3085:     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
                   3086:        <validator>
                   3087: 	if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386     foxr     3088: 	    !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
1.388     foxr     3089: 	    !\$helper->{'VARS'}{'SINGLE_CODE'}                   &&
                   3090: 	    !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362     albertel 3091: 	    return "You need to specify the number of assignments to print";
                   3092: 	}
                   3093: 	return undef;
                   3094:        </validator>
                   3095:     </string>
                   3096:     <message></td></tr><tr><td></message>
1.501     albertel 3097:     <message><b>Names to save the CODEs under for later:</b></message>
1.412     albertel 3098:     <message></td><td></message>
                   3099:     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
                   3100:     <message></td></tr><tr><td></message>
                   3101:     <message><b>Bubble sheet type:</b></message>
                   3102:     <message></td><td></message>
                   3103:     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
                   3104:     $codechoice
                   3105:     </dropdown>
1.472     albertel 3106:     <message></td></tr><tr><td></table></message>
                   3107:     <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
                   3108:     <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412     albertel 3109:     <string variable="SINGLE_CODE" size="10">
1.386     foxr     3110:         <validator>
                   3111: 	   if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&
1.388     foxr     3112: 	      !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&
                   3113: 	      !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386     foxr     3114: 	      return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
                   3115: 						      \$helper->{'VARS'}{'CODE_OPTION'});
                   3116: 	   } else {
                   3117: 	       return undef;	# Other forces control us.
                   3118: 	   }
                   3119:         </validator>
                   3120:     </string>
1.472     albertel 3121:     <message></td></tr><tr><td></message>
1.432     albertel 3122:         $code_selection
1.472     albertel 3123:     <message></td></tr></table></message>
                   3124:     <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
                   3125:     <message><b>Select saved CODEs:</b></message>
1.381     albertel 3126:     <message></td><td></message>
1.294     albertel 3127:     <dropdown variable="REUSE_OLD_CODES">
                   3128:         $namechoice
                   3129:     </dropdown>
1.412     albertel 3130:     <message></td></tr></table></message>
1.424     foxr     3131:   </state>
1.284     albertel 3132:     $resource_selector
                   3133: CHOOSE_ANON2
1.481     albertel 3134:     }
                   3135: 
1.121     bowersj2 3136:     # FIXME: That RE should come from a library somewhere.
1.483     foxr     3137:     if (($perm{'pav'} 
1.482     albertel 3138: 	&& $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
                   3139: 	&& (defined($helper->{'VARS'}->{'construction'})
                   3140: 	    ||
                   3141: 	    (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
                   3142: 	     && 
                   3143: 	     $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483     foxr     3144: 	    )) 
                   3145: 	&& $helper->{VARS}->{'assignment'} eq ""
1.482     albertel 3146: 	) {
1.238     bowersj2 3147: 
1.482     albertel 3148: 	my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
1.546     bisitz   3149:         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 3150:         my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482     albertel 3151:   <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458     www      3152: 
1.138     bowersj2 3153:     <files variable="FILES" multichoice='1'>
1.144     bowersj2 3154:       <nextstate>PAGESIZE</nextstate>
1.138     bowersj2 3155:       <filechoice>return '$subdir';</filechoice>
1.139     bowersj2 3156: CHOOSE_FROM_SUBDIR
                   3157:         
1.238     bowersj2 3158:         # this is broken up because I really want interpolation above,
                   3159:         # and I really DON'T want it below
1.139     bowersj2 3160:         $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225     bowersj2 3161:       <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
                   3162: 	  $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131     bowersj2 3163:       </filefilter>
1.138     bowersj2 3164:       </files>
1.131     bowersj2 3165:     </state>
                   3166: CHOOSE_FROM_SUBDIR
1.139     bowersj2 3167:         &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131     bowersj2 3168:     }
1.238     bowersj2 3169: 
                   3170:     # Allow the user to select any sequence in the course, feed it to
                   3171:     # another resource selector for that sequence
1.483     foxr     3172:     if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509     albertel 3173: 	push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249     sakharuk 3174: 			      'select_sequences', 'CHOOSE_SEQUENCE'];
1.244     bowersj2 3175: 	my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
                   3176: 	#Escape apostrophes and backslashes for Perl
                   3177: 	$escapedSequenceName =~ s/\\/\\\\/g;
                   3178: 	$escapedSequenceName =~ s/'/\\'/g;
1.239     bowersj2 3179: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238     bowersj2 3180:   <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
                   3181:     <message>Select the sequence to print resources from:</message>
                   3182:     <resource variable="SEQUENCE">
                   3183:       <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
                   3184:       <filterfunc>return \$res->is_sequence;</filterfunc>
                   3185:       <valuefunc>return $urlValue;</valuefunc>
1.447     foxr     3186:       <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391     foxr     3187: 	</choicefunc>
1.238     bowersj2 3188:       </resource>
                   3189:     </state>
                   3190:   <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
                   3191:     <message>(mark desired resources then click "next" button) <br /></message>
1.435     foxr     3192:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 3193:               closeallpages="1">
1.238     bowersj2 3194:       <nextstate>PAGESIZE</nextstate>
1.466     albertel 3195:       <filterfunc>return $isNotMap</filterfunc>
1.244     bowersj2 3196:       <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238     bowersj2 3197:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 3198:       $start_new_option
1.238     bowersj2 3199:       </resource>
                   3200:     </state>
                   3201: CHOOSE_FROM_ANY_SEQUENCE
1.239     bowersj2 3202: }
1.481     albertel 3203: 
1.131     bowersj2 3204:     # Generate the first state, to select which resources get printed.
1.223     bowersj2 3205:     Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131     bowersj2 3206:     $paramHash = Apache::lonhelper::getParamHash();
1.155     sakharuk 3207:     $paramHash->{MESSAGE_TEXT} = "";
1.131     bowersj2 3208:     Apache::lonhelper::message->new();
                   3209:     $paramHash = Apache::lonhelper::getParamHash();
                   3210:     $paramHash->{'variable'} = 'PRINT_TYPE';
                   3211:     $paramHash->{CHOICES} = $printChoices;
                   3212:     Apache::lonhelper::choices->new();
1.161     bowersj2 3213: 
1.223     bowersj2 3214:     my $startedTable = 0; # have we started an HTML table yet? (need
                   3215:                           # to close it later)
                   3216: 
1.397     albertel 3217:     if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or 
1.170     sakharuk 3218: 	($helper->{VARS}->{'construction'} eq '1')) {
1.544     bisitz   3219: 	&addMessage('<br />'
                   3220:                    .'<h3>'.&mt('Print Options').'</h3>'
                   3221:                    .&Apache::lonhtmlcommon::start_pick_box()
                   3222: #                  .&Apache::lonhtmlcommon::row_headline()
                   3223: #                  .'<h3>'.&mt('Print Options').'</h3>'
                   3224: #                  .&Apache::lonhtmlcommon::row_closure()
                   3225:                    .&Apache::lonhtmlcommon::row_title(
                   3226:                        '<label for="ANSWER_TYPE_forminput">'
                   3227:                       .&mt('Print Answers')
                   3228:                       .'</label>'
                   3229:                     )
                   3230:         );
1.161     bowersj2 3231:         $paramHash = Apache::lonhelper::getParamHash();
1.162     sakharuk 3232: 	$paramHash->{'variable'} = 'ANSWER_TYPE';   
                   3233: 	$helper->declareVar('ANSWER_TYPE');         
1.161     bowersj2 3234:         $paramHash->{CHOICES} = [
1.242     sakharuk 3235:                                    ['Without Answers', 'yes'],
                   3236:                                    ['With Answers', 'no'],
1.368     albertel 3237:                                    ['Only Answers', 'only']
1.289     sakharuk 3238:                                 ];
1.210     sakharuk 3239:         Apache::lonhelper::dropdown->new();
1.544     bisitz   3240: 	&addMessage(&Apache::lonhtmlcommon::row_closure());
1.223     bowersj2 3241: 	$startedTable = 1;
1.161     bowersj2 3242:     }
1.209     sakharuk 3243: 
1.397     albertel 3244:     if ($perm{'pav'}) {
1.223     bowersj2 3245: 	if (!$startedTable) {
1.497     www      3246: 	    addMessage("<hr width='33%' /><table><tr><td align='right'>".
                   3247:                        '<label for="LATEX_TYPE_forminput">'.
                   3248:                        &mt('LaTeX mode').
                   3249:                        "</label>: </td><td>");
1.223     bowersj2 3250: 	    $startedTable = 1;
                   3251: 	} else {
1.544     bisitz   3252: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   3253:                            '<label for="LATEX_TYPE_forminput">'
                   3254:                            .&mt('LaTeX mode')
                   3255:                            .'</label>'
                   3256:                         )
                   3257:             );
1.223     bowersj2 3258: 	}
1.203     sakharuk 3259:         $paramHash = Apache::lonhelper::getParamHash();
                   3260: 	$paramHash->{'variable'} = 'LATEX_TYPE';   
                   3261: 	$helper->declareVar('LATEX_TYPE');  
                   3262: 	if ($helper->{VARS}->{'construction'} eq '1') {       
                   3263: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 3264: 				     ['standard LaTeX mode', 'standard'], 
                   3265: 				     ['LaTeX batchmode', 'batchmode'], ];
1.203     sakharuk 3266: 	} else {
                   3267: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 3268: 				     ['LaTeX batchmode', 'batchmode'],
                   3269: 				     ['standard LaTeX mode', 'standard'] ];
1.203     sakharuk 3270: 	}
1.210     sakharuk 3271:         Apache::lonhelper::dropdown->new();
1.218     sakharuk 3272:  
1.544     bisitz   3273: 	&addMessage(&Apache::lonhtmlcommon::row_closure()
                   3274:                    .&Apache::lonhtmlcommon::row_title(
                   3275:                         '<label for="TABLE_CONTENTS_forminput">'
                   3276:                        .&mt('Print Table of Contents')
                   3277:                        .'</label>'
                   3278:                     )
                   3279:         );
1.209     sakharuk 3280:         $paramHash = Apache::lonhelper::getParamHash();
                   3281: 	$paramHash->{'variable'} = 'TABLE_CONTENTS';   
                   3282: 	$helper->declareVar('TABLE_CONTENTS');         
                   3283:         $paramHash->{CHOICES} = [
1.223     bowersj2 3284:                                    ['No', 'no'],
                   3285:                                    ['Yes', 'yes'] ];
1.210     sakharuk 3286:         Apache::lonhelper::dropdown->new();
1.544     bisitz   3287: 	&addMessage(&Apache::lonhtmlcommon::row_closure());
1.214     sakharuk 3288:         
1.220     sakharuk 3289: 	if (not $helper->{VARS}->{'construction'}) {
1.545     bisitz   3290: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   3291:                             '<label for="TABLE_INDEX_forminput">'
                   3292:                            .&mt('Print Index')
                   3293:                            .'</label>'
                   3294:                         )
                   3295:             );
1.220     sakharuk 3296: 	    $paramHash = Apache::lonhelper::getParamHash();
                   3297: 	    $paramHash->{'variable'} = 'TABLE_INDEX';   
                   3298: 	    $helper->declareVar('TABLE_INDEX');         
                   3299: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 3300: 				     ['No', 'no'],
                   3301: 				     ['Yes', 'yes'] ];
1.220     sakharuk 3302: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   3303:             &addMessage(&Apache::lonhtmlcommon::row_closure());
                   3304:             &addMessage(&Apache::lonhtmlcommon::row_title(
                   3305:                             '<label for="PRINT_DISCUSSIONS_forminput">'
                   3306:                            .&mt('Print Discussions')
                   3307:                            .'</label>'
                   3308:                         )
                   3309:             );
1.309     sakharuk 3310: 	    $paramHash = Apache::lonhelper::getParamHash();
                   3311: 	    $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';   
                   3312: 	    $helper->declareVar('PRINT_DISCUSSIONS');         
                   3313: 	    $paramHash->{CHOICES} = [
                   3314: 				     ['No', 'no'],
                   3315: 				     ['Yes', 'yes'] ];
                   3316: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   3317:             &addMessage(&Apache::lonhtmlcommon::row_closure());
1.372     foxr     3318: 
1.511     foxr     3319: 	    # Prompt for printing annotations too.
                   3320: 		
1.545     bisitz   3321: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   3322:                             '<label for="PRINT_ANNOTATIONS_forminput">'
                   3323:                            .&mt('Print Annotations')
                   3324:                            .'</label>'
                   3325:                         )
                   3326:             );
1.511     foxr     3327: 	    $paramHash = Apache::lonhelper::getParamHash();
                   3328: 	    $paramHash->{'variable'} = "PRINT_ANNOTATIONS";
                   3329: 	    $helper->declareVar("PRINT_ANNOTATIONS");
                   3330: 	    $paramHash->{CHOICES} = [
                   3331: 				     ['No', 'no'],
                   3332: 				     ['Yes', 'yes']];
                   3333: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   3334:             &addMessage(&Apache::lonhtmlcommon::row_closure());
1.511     foxr     3335: 
1.545     bisitz   3336:             &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Foils')));
1.397     albertel 3337: 	    $paramHash = Apache::lonhelper::getParamHash();
                   3338: 	    $paramHash->{'multichoice'} = "true";
                   3339: 	    $paramHash->{'allowempty'}  = "true";
                   3340: 	    $paramHash->{'variable'}   = "showallfoils";
                   3341: 	    $paramHash->{'CHOICES'} = [ ["Show all foils", "1"] ];
                   3342: 	    Apache::lonhelper::choices->new();
1.545     bisitz   3343:             &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.220     sakharuk 3344: 	}
1.219     sakharuk 3345: 
1.230     albertel 3346: 	if ($helper->{'VARS'}->{'construction'}) { 
1.505     albertel 3347: 	    my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497     www      3348:             my $randseedtext=&mt("Use random seed");
                   3349:             my $stylefiletext=&mt("Use style file");
1.506     albertel 3350:             my $selectfiletext=&mt("Select style file");
1.497     www      3351: 
1.544     bisitz   3352: 	    my $xmlfrag .= '<message>'
                   3353:             .&Apache::lonhtmlcommon::row_title('<label for="curseed_forminput">'
                   3354:                                               .$randseedtext
                   3355:                                               .'</label>'
                   3356:              )
                   3357:             .'</message>
                   3358:             <string variable="curseed" size="15" maxlength="15">
                   3359:                 <defaultvalue>
                   3360:                    return '.$helper->{VARS}->{'curseed'}.';
                   3361:                 </defaultvalue>'
                   3362:             .'</string>'
                   3363:             .'<message>'
                   3364:             .&Apache::lonhtmlcommon::row_closure()
                   3365:             .&Apache::lonhtmlcommon::row_title('<label for="style_file">'
                   3366:                                               .$stylefiletext
                   3367:                                               .'</label>'
                   3368:              )
                   3369:             .'</message>
1.504     albertel 3370:              <string variable="style_file" size="40">
1.544     bisitz   3371:                 <defaultvalue>
                   3372:                     return '.$stylevalue.';
                   3373:                 </defaultvalue>
                   3374:              </string><message>&nbsp;'
                   3375: .qq|<a href="javascript:openbrowser('helpform','style_file_forminput','sty')">|
                   3376: .$selectfiletext.'</a>'
                   3377:             .&Apache::lonhtmlcommon::row_closure()
                   3378:             .&Apache::lonhtmlcommon::row_title(&mt('Show all foils'))
                   3379:             .'</message>
1.371     foxr     3380: 	     <choices allowempty="1" multichoice="true" variable="showallfoils">
1.544     bisitz   3381:                 <choice computer="1">&nbsp;</choice>
                   3382:              </choices>'
                   3383: 	    .'<message>'
                   3384:             .&Apache::lonhtmlcommon::row_closure()
                   3385:             .'</message>';
1.230     albertel 3386:             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.512     foxr     3387: 
                   3388: 
1.544     bisitz   3389:             &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Problem Type')));
1.512     foxr     3390: 	    #
                   3391: 	    # Initial value from construction space:
                   3392: 	    #
                   3393: 	    if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
                   3394: 		$helper->{VARS}->{'probstatus'} = $env{'form.problemtype'};	# initial value
                   3395: 	    }
1.518     foxr     3396: 	    $xmlfrag = << "PROBTYPE";
                   3397: 		<dropdown variable="probstatus" multichoice="0" allowempty="0">
                   3398: 		   <defaultvalue>
                   3399: 		      return "$helper->{VARS}->{'probstatus'}";
                   3400:                    </defaultvalue>
                   3401: 		   <choice computer="problem">Homework Problem</choice>
                   3402: 		   <choice computer="exam">Exam Problem</choice>
                   3403: 		   <choice computer="survey">Survey question</choice>
                   3404: 		</dropdown>
                   3405: PROBTYPE
                   3406:             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
                   3407: 	    
1.544     bisitz   3408:             &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.512     foxr     3409: 
1.544     bisitz   3410:         }
1.223     bowersj2 3411:     }
1.264     sakharuk 3412: 
                   3413: 
                   3414: 
1.218     sakharuk 3415: 
1.223     bowersj2 3416:     if ($startedTable) {
1.544     bisitz   3417:         &addMessage(&Apache::lonhtmlcommon::end_pick_box());
1.215     sakharuk 3418:     }
1.161     bowersj2 3419: 
1.131     bowersj2 3420:     Apache::lonprintout::page_format_state->new("FORMAT");
                   3421: 
1.144     bowersj2 3422:     # Generate the PAGESIZE state which will offer the user the margin
                   3423:     # choices if they select one column
                   3424:     Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
                   3425:     Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
                   3426: 
                   3427: 
1.131     bowersj2 3428:     $helper->process();
                   3429: 
1.416     foxr     3430: 
1.131     bowersj2 3431:     # MANUAL BAILOUT CONDITION:
                   3432:     # If we're in the "final" state, bailout and return to handler
                   3433:     if ($helper->{STATE} eq 'FINAL') {
                   3434:         return $helper;
                   3435:     }    
1.130     sakharuk 3436: 
1.131     bowersj2 3437:     $r->print($helper->display());
1.395     www      3438:     if ($helper->{STATE} eq 'START') {
                   3439: 	&recently_generated($r);
                   3440:     }
1.333     albertel 3441:     &Apache::lonhelper::unregisterHelperTags();
1.115     bowersj2 3442: 
                   3443:     return OK;
                   3444: }
                   3445: 
1.1       www      3446: 
                   3447: 1;
1.119     bowersj2 3448: 
                   3449: package Apache::lonprintout::page_format_state;
                   3450: 
                   3451: =pod
                   3452: 
1.131     bowersj2 3453: =head1 Helper element: page_format_state
                   3454: 
                   3455: See lonhelper.pm documentation for discussion of the helper framework.
1.119     bowersj2 3456: 
1.131     bowersj2 3457: Apache::lonprintout::page_format_state is an element that gives the 
                   3458: user an opportunity to select the page layout they wish to print 
                   3459: with: Number of columns, portrait/landscape, and paper size. If you 
                   3460: want to change the paper size choices, change the @paperSize array 
                   3461: contents in this package.
1.119     bowersj2 3462: 
1.131     bowersj2 3463: page_format_state is always directly invoked in lonprintout.pm, so there
                   3464: is no tag interface. You actually pass parameters to the constructor.
1.119     bowersj2 3465: 
                   3466: =over 4
                   3467: 
1.131     bowersj2 3468: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119     bowersj2 3469: 
                   3470: =back
                   3471: 
                   3472: =cut
                   3473: 
1.131     bowersj2 3474: use Apache::lonhelper;
1.119     bowersj2 3475: 
                   3476: no strict;
1.131     bowersj2 3477: @ISA = ("Apache::lonhelper::element");
1.119     bowersj2 3478: use strict;
1.266     sakharuk 3479: use Apache::lonlocal;
1.373     albertel 3480: use Apache::lonnet;
1.119     bowersj2 3481: 
                   3482: my $maxColumns = 2;
1.376     albertel 3483: # it'd be nice if these all worked
                   3484: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 
                   3485: #                 "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
                   3486: #                 "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]", 
                   3487: #                 "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326     sakharuk 3488: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 
1.376     albertel 3489: 		 "a4 [210x297 mm]");
1.119     bowersj2 3490: 
                   3491: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
                   3492: #                   Paper type
                   3493: 
                   3494: sub new { 
1.131     bowersj2 3495:     my $self = Apache::lonhelper::element->new();
1.119     bowersj2 3496: 
1.135     bowersj2 3497:     shift;
                   3498: 
1.131     bowersj2 3499:     $self->{'variable'} = shift;
1.134     bowersj2 3500:     my $helper = Apache::lonhelper::getHelper();
1.135     bowersj2 3501:     $helper->declareVar($self->{'variable'});
1.131     bowersj2 3502:     bless($self);
1.119     bowersj2 3503:     return $self;
                   3504: }
                   3505: 
                   3506: sub render {
                   3507:     my $self = shift;
1.131     bowersj2 3508:     my $helper = Apache::lonhelper::getHelper();
1.119     bowersj2 3509:     my $result = '';
1.131     bowersj2 3510:     my $var = $self->{'variable'};
1.266     sakharuk 3511:     my $PageLayout=&mt('Page layout');
                   3512:     my $NumberOfColumns=&mt('Number of columns');
                   3513:     my $PaperType=&mt('Paper type');
1.506     albertel 3514:     my $landscape=&mt('Landscape');
                   3515:     my $portrait=&mt('Portrait');
1.539     onken    3516:     my $pdfFormLabel=&mt('PDF-Formfields');
                   3517:     my $with=&mt('with Formfields');
                   3518:     my $without=&mt('without Formfields');
1.544     bisitz   3519:     $result.='<h3>'.&mt('Layout Options').'</h3>'
                   3520:             .&Apache::loncommon::start_data_table()
                   3521:             .&Apache::loncommon::start_data_table_header_row()
                   3522:             .'<th>'.$PageLayout.'</th>'
                   3523:             .'<th>'.$NumberOfColumns.'</th>'
                   3524:             .'<th>'.$PaperType.'</th>'
                   3525:             .'<th>'.$pdfFormLabel.'</th>'
                   3526:             .&Apache::loncommon::end_data_table_header_row()
                   3527:             .&Apache::loncommon::start_data_table_row()
                   3528:     .'<td>'
                   3529:     .'<label><input type="radio" name="'.${var}.'.layout" value="L" />'.$landscape.'</label><br />'
                   3530:     .'<label><input type="radio" name="'.${var}.'.layout" value="P" checked="checked" />'.$portrait.'</label>'
                   3531:     .'</td>';
1.119     bowersj2 3532: 
1.544     bisitz   3533:     $result.='<td align="center">'
                   3534:             .'<select name="'.${var}.'.cols">';
1.119     bowersj2 3535: 
                   3536:     my $i;
                   3537:     for ($i = 1; $i <= $maxColumns; $i++) {
1.144     bowersj2 3538:         if ($i == 2) {
1.119     bowersj2 3539:             $result .= "<option value='$i' selected>$i</option>\n";
                   3540:         } else {
                   3541:             $result .= "<option value='$i'>$i</option>\n";
                   3542:         }
                   3543:     }
                   3544: 
                   3545:     $result .= "</select></td><td>\n";
                   3546:     $result .= "<select name='${var}.paper'>\n";
                   3547: 
1.373     albertel 3548:     my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398     albertel 3549:     my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
                   3550:     $DefaultPaperSize=~s/\s//g;
1.304     sakharuk 3551:     if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119     bowersj2 3552:     $i = 0;
                   3553:     foreach (@paperSize) {
1.326     sakharuk 3554: 	$_=~/(\w+)/;
                   3555: 	my $papersize=$1;
1.304     sakharuk 3556:         if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.326     sakharuk 3557:             $result .= "<option selected value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119     bowersj2 3558:         } else {
1.326     sakharuk 3559:             $result .= "<option value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119     bowersj2 3560:         }
                   3561:         $i++;
                   3562:     }
1.539     onken    3563:     $result .= <<HTML;
                   3564:         </select>
                   3565:     </td>
                   3566:     <td align='center'>
                   3567:         <select name='${var}.pdfFormFields'>
                   3568:             <option selected value='no'>$without</option>
                   3569:             <option value='yes'>$with</option>
                   3570:         </select>
                   3571:     </td>
                   3572: HTML
1.544     bisitz   3573:     $result.=&Apache::loncommon::end_data_table_row()
                   3574:             .&Apache::loncommon::end_data_table();
1.539     onken    3575: 
1.119     bowersj2 3576:     return $result;
1.135     bowersj2 3577: }
                   3578: 
                   3579: sub postprocess {
                   3580:     my $self = shift;
                   3581: 
                   3582:     my $var = $self->{'variable'};
1.136     bowersj2 3583:     my $helper = Apache::lonhelper->getHelper();
1.135     bowersj2 3584:     $helper->{VARS}->{$var} = 
1.373     albertel 3585:         $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
1.539     onken    3586:         $env{"form.$var.paper"} . '|' . $env{"form.$var.pdfFormFields"};
1.135     bowersj2 3587:     return 1;
1.119     bowersj2 3588: }
                   3589: 
                   3590: 1;
1.144     bowersj2 3591: 
                   3592: package Apache::lonprintout::page_size_state;
                   3593: 
                   3594: =pod
                   3595: 
                   3596: =head1 Helper element: page_size_state
                   3597: 
                   3598: See lonhelper.pm documentation for discussion of the helper framework.
                   3599: 
                   3600: Apache::lonprintout::page_size_state is an element that gives the 
                   3601: user the opportunity to further refine the page settings if they
                   3602: select a single-column page.
                   3603: 
                   3604: page_size_state is always directly invoked in lonprintout.pm, so there
                   3605: is no tag interface. You actually pass parameters to the constructor.
                   3606: 
                   3607: =over 4
                   3608: 
                   3609: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
                   3610: 
                   3611: =back
                   3612: 
                   3613: =cut
                   3614: 
                   3615: use Apache::lonhelper;
1.373     albertel 3616: use Apache::lonnet;
1.144     bowersj2 3617: no strict;
                   3618: @ISA = ("Apache::lonhelper::element");
                   3619: use strict;
                   3620: 
                   3621: 
                   3622: 
                   3623: sub new { 
                   3624:     my $self = Apache::lonhelper::element->new();
                   3625: 
                   3626:     shift; # disturbs me (probably prevents subclassing) but works (drops
                   3627:            # package descriptor)... - Jeremy
                   3628: 
                   3629:     $self->{'variable'} = shift;
                   3630:     my $helper = Apache::lonhelper::getHelper();
                   3631:     $helper->declareVar($self->{'variable'});
                   3632: 
                   3633:     # The variable name of the format element, so we can look into 
                   3634:     # $helper->{VARS} to figure out whether the columns are one or two
                   3635:     $self->{'formatvar'} = shift;
                   3636: 
1.463     foxr     3637: 
1.144     bowersj2 3638:     $self->{NEXTSTATE} = shift;
                   3639:     bless($self);
1.467     foxr     3640: 
1.144     bowersj2 3641:     return $self;
                   3642: }
                   3643: 
                   3644: sub render {
                   3645:     my $self = shift;
                   3646:     my $helper = Apache::lonhelper::getHelper();
                   3647:     my $result = '';
                   3648:     my $var = $self->{'variable'};
                   3649: 
1.467     foxr     3650: 
                   3651: 
1.144     bowersj2 3652:     if (defined $self->{ERROR_MSG}) {
1.464     albertel 3653:         $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144     bowersj2 3654:     }
                   3655: 
1.438     foxr     3656:     my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463     foxr     3657: 
                   3658:     # Use format to get sensible defaults for the margins:
                   3659: 
                   3660: 
                   3661:     my ($laystyle, $cols, $papersize) = split(/\|/, $format);
                   3662:     ($papersize)                      = split(/ /, $papersize);
                   3663: 
                   3664: 
                   3665:     if ($laystyle eq 'L') {
                   3666: 	$laystyle = 'album';
                   3667:     } else {
                   3668: 	$laystyle = 'book';
                   3669:     }
                   3670: 
                   3671: 
1.464     albertel 3672:     my %size;
                   3673:     ($size{'width_and_units'},
                   3674:      $size{'height_and_units'},
                   3675:      $size{'margin_and_units'})=
                   3676: 	 &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463     foxr     3677:     
1.464     albertel 3678:     foreach my $dimension ('width','height','margin') {
                   3679: 	($size{$dimension},$size{$dimension.'_unit'}) =
                   3680: 	    split(/ +/, $size{$dimension.'_and_units'},2);
                   3681:        	
                   3682: 	foreach my $unit ('cm','in') {
                   3683: 	    $size{$dimension.'_options'} .= '<option ';
                   3684: 	    if ($size{$dimension.'_unit'} eq $unit) {
                   3685: 		$size{$dimension.'_options'} .= 'selected="selected" ';
                   3686: 	    }
                   3687: 	    $size{$dimension.'_options'} .= '>'.$unit.'</option>';
                   3688: 	}
1.438     foxr     3689:     }
                   3690: 
1.470     foxr     3691:     # Adjust margin for LaTeX margin: .. requires units == cm or in.
                   3692: 
                   3693:     if ($size{'margin_unit'} eq 'in') {
                   3694: 	$size{'margin'} += 1;
                   3695:     }  else {
                   3696: 	$size{'margin'} += 2.54;
                   3697:     }
1.548     bisitz   3698:     my %lt = &Apache::lonlocal::texthash(
                   3699:         'format' => 'How should each column be formatted?',
                   3700:         'width'  => 'Width',
                   3701:         'height' => 'Height',
                   3702:         'margin' => 'Left Margin'
                   3703:     );
                   3704: 
                   3705:     $result .= '<p>'.$lt{'format'}.'</p>'
                   3706:               .&Apache::lonhtmlcommon::start_pick_box()
                   3707:               .&Apache::lonhtmlcommon::row_title($lt{'width'})
                   3708:               .'<input type="text" name="'.$var.'.width" value="'.$size{'width'}.'" size="4" />'
                   3709:               .'<select name="'.$var.'.widthunit">'
                   3710:               .$size{'width_options'}
                   3711:               .'</select>'
                   3712:               .&Apache::lonhtmlcommon::row_closure()
                   3713:               .&Apache::lonhtmlcommon::row_title($lt{'height'})
                   3714:               .'<input type="text" name="'.$var.'.height" value="'.$size{'height'}.'" size="4" />'
                   3715:               .'<select name="'.$var.'.heightunit">'
                   3716:               .$size{'height_options'}
                   3717:               .'</select>'
                   3718:               .&Apache::lonhtmlcommon::row_closure()
                   3719:               .&Apache::lonhtmlcommon::row_title($lt{'margin'})
                   3720:               .'<input type="text" name="'.$var.'.lmargin" value="'.$size{'margin'}.'" size="4" />'
                   3721:               .'<select name="'.$var.'.lmarginunit">'
                   3722:               .$size{'margin_options'}
                   3723:               .'</select>'
                   3724:               .&Apache::lonhtmlcommon::row_closure(1)
                   3725:               .&Apache::lonhtmlcommon::end_pick_box();
                   3726:     # <p>Hint: Some instructors like to leave scratch space for the student by
                   3727:     # making the width much smaller than the width of the page.</p>
1.144     bowersj2 3728: 
                   3729:     return $result;
                   3730: }
                   3731: 
1.470     foxr     3732: 
1.144     bowersj2 3733: sub preprocess {
                   3734:     my $self = shift;
                   3735:     my $helper = Apache::lonhelper::getHelper();
                   3736: 
                   3737:     my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467     foxr     3738: 
                   3739:     #  If the user does not have 'pav' privilege, set default widths and
                   3740:     #  on to the next state right away.
                   3741:     #
                   3742:     if (!$perm{'pav'}) {
                   3743: 	my $var = $self->{'variable'};
                   3744: 	my $format = $helper->{VARS}->{$self->{'formatvar'}};
                   3745: 	
                   3746: 	my ($laystyle, $cols, $papersize) = split(/\|/, $format);
                   3747: 	($papersize)                      = split(/ /, $papersize);
                   3748: 	
                   3749: 	
                   3750: 	if ($laystyle eq 'L') {
                   3751: 	    $laystyle = 'album';
                   3752: 	} else {
                   3753: 	    $laystyle = 'book';
                   3754: 	}
                   3755: 	#  Figure out some good defaults for the print out and set them:
                   3756: 	
                   3757: 	my %size;
                   3758: 	($size{'width'},
                   3759: 	 $size{'height'},
                   3760: 	 $size{'lmargin'})=
                   3761: 	     &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
                   3762: 	
                   3763: 	foreach my $dim ('width', 'height', 'lmargin') {
                   3764: 	    my ($value, $units) = split(/ /, $size{$dim});
1.470     foxr     3765: 	    	    
1.467     foxr     3766: 	    $helper->{VARS}->{"$var.".$dim}      = $value;
                   3767: 	    $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
                   3768: 	    
                   3769: 	}
                   3770: 	
                   3771: 
                   3772: 	# Transition to the next state
                   3773: 
                   3774: 	$helper->changeState($self->{NEXTSTATE});
                   3775:     }
1.144     bowersj2 3776:    
                   3777:     return 1;
                   3778: }
                   3779: 
                   3780: sub postprocess {
                   3781:     my $self = shift;
                   3782: 
                   3783:     my $var = $self->{'variable'};
                   3784:     my $helper = Apache::lonhelper->getHelper();
1.373     albertel 3785:     my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"}; 
                   3786:     my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"}; 
                   3787:     my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"}; 
                   3788:     $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"}; 
                   3789:     $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"}; 
                   3790:     $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"}; 
1.144     bowersj2 3791: 
                   3792:     my $error = '';
                   3793: 
                   3794:     # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed 
                   3795:     # by an optional period, followed by digits, ending the string
                   3796: 
1.464     albertel 3797:     if ($width !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3798:         $error .= "Invalid width; please type only a number.<br />\n";
                   3799:     }
1.464     albertel 3800:     if ($height !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3801:         $error .= "Invalid height; please type only a number.<br />\n";
                   3802:     }
1.464     albertel 3803:     if ($lmargin !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3804:         $error .= "Invalid left margin; please type only a number.<br />\n";
1.470     foxr     3805:     } else {
                   3806: 	# Adjust for LaTeX 1.0 inch margin:
                   3807: 
                   3808: 	if ($env{"form.${var}.lmarginunit"} eq "in") {
                   3809: 	    $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
                   3810: 	} else {
                   3811: 	    $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
                   3812: 	}
1.144     bowersj2 3813:     }
                   3814: 
                   3815:     if (!$error) {
                   3816:         Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
                   3817:         return 1;
                   3818:     } else {
                   3819:         $self->{ERROR_MSG} = $error;
                   3820:         return 0;
                   3821:     }
                   3822: }
                   3823: 
                   3824: 
1.119     bowersj2 3825: 
1.1       www      3826: __END__
1.6       sakharuk 3827: 

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