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

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

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