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

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

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