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

1.469     foxr        1: #
1.389     foxr        2: # The LearningOnline Network
1.1       www         3: # Printout
                      4: #
1.508   ! albertel    5: # $Id: lonprintout.pm,v 1.507 2007/08/29 00:55:37 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
                   1972:     if ($helper->{'VARS'}->{'construction'} ne '1') {
                   1973: 	#prints published resource
1.439     www      1974: 	$URLback=&escape('/adm/flip?postdata=return:');
1.276     sakharuk 1975:     } else {
                   1976: 	#prints resource from the construction space
                   1977: 	$URLback='/'.$helper->{'VARS'}->{'filename'};
1.279     albertel 1978: 	if ($URLback=~/([^?]+)/) {
                   1979: 	    $URLback=$1;
                   1980: 	    $URLback=~s|^/~|/priv/|;
                   1981: 	}
1.276     sakharuk 1982:     }
1.375     foxr     1983:     # logic for now is too complex to trace if this has been defined
                   1984:     #  yet.
                   1985:     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   1986:     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.257     sakharuk 1987:     &Apache::lonnet::appenv('cgi.'.$identifier.'.file'   => $filename,
                   1988:                             'cgi.'.$identifier.'.layout'  => $laystyle,
                   1989:                             'cgi.'.$identifier.'.numcol'  => $numberofcolumns,
1.303     sakharuk 1990: 			    'cgi.'.$identifier.'.paper'  => $papersize,
1.257     sakharuk 1991:                             'cgi.'.$identifier.'.selection' => $selectionmade,
1.375     foxr     1992: 			    'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
                   1993: 			    'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
1.397     albertel 1994: 			    'cgi.'.$identifier.'.role' => $perm{'pav'},
1.375     foxr     1995:                             'cgi.'.$identifier.'.numberoffiles' => $#print_array,
                   1996:                             'cgi.'.$identifier.'.studentnames' => $student_names,
                   1997:                             'cgi.'.$identifier.'.backref' => $URLback,);
                   1998:     &Apache::lonnet::appenv("cgi.$identifier.user"    => $env{'user.name'},
                   1999: 			    "cgi.$identifier.domain"  => $env{'user.domain'},
                   2000: 			    "cgi.$identifier.courseid" => $cnum, 
                   2001: 			    "cgi.$identifier.coursedom" => $cdom, 
                   2002: 			    "cgi.$identifier.resources" => $resources_printed);
                   2003: 
1.431     albertel 2004:     my $end_page = &Apache::loncommon::end_page();
                   2005:     $r->print(<<FINALEND);
1.317     albertel 2006: <br />
1.288     albertel 2007: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.317     albertel 2008: <a href="/cgi-bin/printout.pl?$identifier">Continue</a>
1.431     albertel 2009: $end_page
1.140     sakharuk 2010: FINALEND
                   2011: }
                   2012: 
1.288     albertel 2013: 
                   2014: sub get_CODE {
1.381     albertel 2015:     my ($all_codes,$num,$seed,$size,$type)=@_;
1.288     albertel 2016:     my $max='1'.'0'x$size;
                   2017:     my $newcode;
                   2018:     while(1) {
1.392     albertel 2019: 	$newcode=sprintf("%0".$size."d",int(rand($max)));
1.288     albertel 2020: 	if (!exists($$all_codes{$newcode})) {
                   2021: 	    $$all_codes{$newcode}=1;
1.381     albertel 2022: 	    if ($type eq 'number' ) {
                   2023: 		return $newcode;
                   2024: 	    } else {
                   2025: 		return &num_to_letters($newcode);
                   2026: 	    }
1.288     albertel 2027: 	}
                   2028:     }
                   2029: }
1.140     sakharuk 2030: 
1.284     albertel 2031: sub print_resources {
1.360     albertel 2032:     my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422     albertel 2033: 	$LaTeXwidth)=@_;
1.284     albertel 2034:     my $current_output = ''; 
1.375     foxr     2035:     my $printed = '';
1.284     albertel 2036:     my ($username,$userdomain,$usersection) = split /:/,$person;
                   2037:     my $fullname = &get_name($username,$userdomain);
1.492     foxr     2038:     my $namepostfix = "\\\\";	# Both anon and not anon should get the same vspace.
1.288     albertel 2039:     if ($person =~ 'anon') {
1.492     foxr     2040: 	$namepostfix .="Name: ";
1.288     albertel 2041: 	$fullname = "CODE - ".$moreenv->{'CODE'};
                   2042:     }
1.444     foxr     2043:     #  Fullname may have special latex characters that need \ prefixing:
                   2044:     #
                   2045: 
1.350     foxr     2046:     my $i           = 0;
1.284     albertel 2047:     #goes through all resources, checks if they are available for 
                   2048:     #current student, and produces output   
1.428     albertel 2049: 
                   2050:     &Apache::lonxml::clear_problem_counter();
1.364     albertel 2051:     my %page_breaks  = &get_page_breaks($helper);
1.476     albertel 2052:     my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440     foxr     2053:     #
1.441     foxr     2054:     #   end each student with a 
1.440     foxr     2055:     #   Special that allows the post processor to even out the page
                   2056:     #   counts later.  Nasty problem this... it would be really
                   2057:     #   nice to put the special in as a postscript comment
1.441     foxr     2058:     #   e.g. \special{ps:\ENDOFSTUDENTSTAMP}  unfortunately,
1.440     foxr     2059:     #   The special gets passed the \ and dvips puts it in the output file
1.441     foxr     2060:     #   so we will just rely on prntout.pl to strip  ENDOFSTUDENTSTAMP from the
                   2061:     #   postscript.  Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440     foxr     2062:     #
1.363     foxr     2063: 
1.284     albertel 2064:     foreach my $curresline (@{$master_seq})  {
1.351     foxr     2065: 	if (defined $page_breaks{$curresline}) {
1.350     foxr     2066: 	    if($i != 0) {
                   2067: 		$current_output.= "\\newpage\n";
                   2068: 	    }
                   2069: 	}
                   2070: 	$i++;
1.284     albertel 2071: 	if ( !($type eq 'problems' && 
                   2072: 	       ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
                   2073: 	    my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
                   2074: 	    if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414     albertel 2075: 		if ($res_url!~m|^ext/|
1.413     albertel 2076: 		    && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375     foxr     2077: 		    $printed .= $curresline.':';
1.428     albertel 2078: 
                   2079: 		    &Apache::lonxml::remember_problem_counter();    
                   2080: 
1.373     albertel 2081: 		    my $rendered = &Apache::loncommon::get_student_view($curresline,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428     albertel 2082: 
1.305     sakharuk 2083: 		    if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   2084: 		       ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     2085: 			#   Use a copy of the hash so we don't pervert it on future loop passes.
                   2086: 			my %answerenv = %{$moreenv};
                   2087: 			$answerenv{'answer_output_mode'}='tex';
                   2088: 			$answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428     albertel 2089: 			
                   2090: 			&Apache::lonxml::restore_problem_counter();
                   2091: 
1.380     foxr     2092: 			my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428     albertel 2093: 
1.305     sakharuk 2094: 			if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   2095: 			    $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
                   2096: 			} else {
1.423     foxr     2097: 
                   2098: 			    
                   2099: 			    my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477     albertel 2100: 			    my $title = &Apache::lonnet::gettitle($curresline);
                   2101: 			    $title = &Apache::lonxml::latex_special_symbols($title);
                   2102: 			    my $body   ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
                   2103: 			    $body     .=&path_to_problem($res_url,$LaTeXwidth);
1.423     foxr     2104: 			    $body     .='\vskip 1 mm '.$ansrendered;
                   2105: 			    $body     = &encapsulate_minipage($body);
                   2106: 			    $rendered = $header.$body;
1.305     sakharuk 2107: 			}
                   2108: 		    }
                   2109: 		    if ($remove_latex_header eq 'YES') {
                   2110: 			$rendered = &latex_header_footer_remove($rendered);
                   2111: 		    } else {
                   2112: 			$rendered =~ s/\\end{document}//;
                   2113: 		    }
                   2114: 		    $current_output .= $rendered;		    
1.456     raeburn  2115: 		} elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.375     foxr     2116: 		    $printed .= $curresline.':';
1.373     albertel 2117: 		    my $rendered = &Apache::loncommon::get_student_view($curresline,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428     albertel 2118: 
1.305     sakharuk 2119: 		    if ($remove_latex_header eq 'YES') {
                   2120: 			$rendered = &latex_header_footer_remove($rendered);
1.284     albertel 2121: 		    } else {
1.305     sakharuk 2122: 			$rendered =~ s/\\end{document}//;
1.284     albertel 2123: 		    }
1.421     foxr     2124: 		    $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
                   2125: 
1.284     albertel 2126: 		} else {
1.414     albertel 2127: 		    my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305     sakharuk 2128: 		    if ($remove_latex_header ne 'NO') {
                   2129: 			$rendered = &latex_header_footer_remove($rendered);
                   2130: 		    } else {
                   2131: 			$rendered =~ s/\\end{document}//;
                   2132: 		    }
                   2133: 		    $current_output .= $rendered;
1.284     albertel 2134: 		}
                   2135: 	    }
                   2136: 	    $remove_latex_header = 'YES';
                   2137: 	}
1.331     albertel 2138: 	if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284     albertel 2139:     }
                   2140:     my $courseidinfo = &get_course();
                   2141:     if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo }
                   2142:     if ($usersection ne '') {$courseidinfo.=' - Sec. '.$usersection}
                   2143:     my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476     albertel 2144:     my $header_line =
1.486     foxr     2145: 	&format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.476     albertel 2146: 			    $currentassignment, $courseidinfo, $fullname);
                   2147:     my $header_start = ($columns_in_format == 1) ? '\lhead'
                   2148: 	                                         : '\fancyhead[LO]';
                   2149:     $header_line = $header_start.'{'.$header_line.'}';
                   2150: 
1.284     albertel 2151:     if ($current_output=~/\\documentclass/) {
1.476     albertel 2152: 	$current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.284     albertel 2153:     } else {
1.476     albertel 2154: 	my $blankpages = 
                   2155: 	    '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
                   2156: 	    
                   2157: 	$current_output = '\strut\vspace*{-6 mm}\\newline'.
                   2158: 	    &copyright_line().' \newpage '.$blankpages.$end_of_student.
                   2159: 	    '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
                   2160: 	    $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284     albertel 2161:     }
1.440     foxr     2162:     #
                   2163:     #  Close the student bracketing.
                   2164:     #
1.375     foxr     2165:     return ($current_output,$fullname, $printed);
1.284     albertel 2166: 
                   2167: }
1.140     sakharuk 2168: 
1.3       sakharuk 2169: sub handler {
                   2170: 
                   2171:     my $r = shift;
1.397     albertel 2172:     
                   2173:     &init_perm();
1.114     bowersj2 2174: 
1.416     foxr     2175: 
1.67      www      2176: 
1.397     albertel 2177:     my $helper = printHelper($r);
                   2178:     if (!ref($helper)) {
                   2179: 	return $helper;
1.60      sakharuk 2180:     }
1.177     sakharuk 2181:    
1.184     sakharuk 2182: 
1.454     foxr     2183:     %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353     foxr     2184:  
1.416     foxr     2185: 
1.350     foxr     2186: 
                   2187: 
1.367     foxr     2188:     #  If a figure conversion queue file exists for this user.domain
                   2189:     # we delete it since it can only be bad (if it were good, printout.pl
                   2190:     # would have deleted it the last time around.
                   2191: 
1.373     albertel 2192:     my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367     foxr     2193:     if(-e $conversion_queuefile) {
                   2194: 	unlink $conversion_queuefile;
                   2195:     }
1.184     sakharuk 2196:     &output_data($r,$helper,\%parmhash);
1.2       sakharuk 2197:     return OK;
1.60      sakharuk 2198: } 
1.2       sakharuk 2199: 
1.131     bowersj2 2200: use Apache::lonhelper;
1.130     sakharuk 2201: 
1.223     bowersj2 2202: sub addMessage {
                   2203:     my $text = shift;
                   2204:     my $paramHash = Apache::lonhelper::getParamHash();
                   2205:     $paramHash->{MESSAGE_TEXT} = $text;
                   2206:     Apache::lonhelper::message->new();
                   2207: }
                   2208: 
1.416     foxr     2209: 
1.238     bowersj2 2210: 
1.397     albertel 2211: sub init_perm {
                   2212:     undef(%perm);
                   2213:     $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
                   2214:     if (!$perm{'pav'}) {
                   2215: 	$perm{'pav'}=&Apache::lonnet::allowed('pav',
                   2216: 		  $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   2217:     }
1.465     albertel 2218:     $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397     albertel 2219:     if (!$perm{'pfo'}) {
                   2220: 	$perm{'pfo'}=&Apache::lonnet::allowed('pfo',
                   2221: 		  $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   2222:     }
                   2223: }
                   2224: 
1.507     albertel 2225: sub get_randomly_ordered_warning {
                   2226:     my ($helper,$map) = @_;
                   2227: 
                   2228:     my $message;
                   2229: 
                   2230:     my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
                   2231:     my $navmap = Apache::lonnavmaps::navmap->new();
                   2232:     my $res = $navmap->getResourceByUrl($map);
                   2233:     if ($res) {
                   2234: 	my $func = 
                   2235: 	    sub { return ($_[0]->is_map() && $_[0]->randomorder); };
                   2236: 	my @matches = $navmap->retrieveResources($res, $func,1,1,1);
                   2237: 	if (@matches) {
1.508   ! albertel 2238: 	    $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 2239: 	}
                   2240:     }
                   2241:     if ($message) {
                   2242: 	return '<message type="warning">'.$message.'</message>';
                   2243:     }
                   2244:     return;
                   2245: }
                   2246: 
1.131     bowersj2 2247: sub printHelper {
1.115     bowersj2 2248:     my $r = shift;
                   2249: 
                   2250:     if ($r->header_only) {
1.373     albertel 2251:         if ($env{'browser.mathml'}) {
1.241     www      2252:             &Apache::loncommon::content_type($r,'text/xml');
1.131     bowersj2 2253:         } else {
1.241     www      2254:             &Apache::loncommon::content_type($r,'text/html');
1.131     bowersj2 2255:         }
                   2256:         $r->send_http_header;
                   2257:         return OK;
1.115     bowersj2 2258:     }
                   2259: 
1.131     bowersj2 2260:     # Send header, nocache
1.373     albertel 2261:     if ($env{'browser.mathml'}) {
1.241     www      2262:         &Apache::loncommon::content_type($r,'text/xml');
1.115     bowersj2 2263:     } else {
1.241     www      2264:         &Apache::loncommon::content_type($r,'text/html');
1.115     bowersj2 2265:     }
                   2266:     &Apache::loncommon::no_cache($r);
                   2267:     $r->send_http_header;
                   2268:     $r->rflush();
                   2269: 
1.131     bowersj2 2270:     # Unfortunately, this helper is so complicated we have to
                   2271:     # write it by hand
                   2272: 
                   2273:     Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
                   2274:     
1.176     bowersj2 2275:     my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146     bowersj2 2276:     $helper->declareVar('symb');
1.156     bowersj2 2277:     $helper->declareVar('postdata');    
1.290     sakharuk 2278:     $helper->declareVar('curseed'); 
                   2279:     $helper->declareVar('probstatus');   
1.156     bowersj2 2280:     $helper->declareVar('filename');
                   2281:     $helper->declareVar('construction');
1.178     sakharuk 2282:     $helper->declareVar('assignment');
1.262     sakharuk 2283:     $helper->declareVar('style_file');
1.340     foxr     2284:     $helper->declareVar('student_sort');
1.363     foxr     2285:     $helper->declareVar('FINISHPAGE');
1.366     foxr     2286:     $helper->declareVar('PRINT_TYPE');
1.372     foxr     2287:     $helper->declareVar("showallfoils");
1.483     foxr     2288:     $helper->declareVar("STUDENTS");
1.363     foxr     2289: 
                   2290:     #  The page breaks can get loaded initially from the course environment:
1.394     foxr     2291:     # But we only do this in the initial state so that they are allowed to change.
                   2292:     #
1.366     foxr     2293: 
1.416     foxr     2294:     # $helper->{VARS}->{FINISHPAGE} = '';
1.363     foxr     2295:     
                   2296:     &Apache::loncommon::restore_course_settings('print',
1.366     foxr     2297: 						{'pagebreaks'  => 'scalar',
                   2298: 					         'lastprinttype' => 'scalar'});
                   2299:     
1.483     foxr     2300:     # This will persistently load in the data we want from the
                   2301:     # very first screen.
1.394     foxr     2302:     
                   2303:     if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
                   2304: 	if (!defined ($env{"form.CURRENT_STATE"})) {
                   2305: 	    
                   2306: 	    $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
                   2307: 	} else {
                   2308: 	    my $state = $env{"form.CURRENT_STATE"};
                   2309: 	    if ($state eq "START") {
                   2310: 		$helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
                   2311: 	    }
                   2312: 	}
                   2313: 	
1.366     foxr     2314:     }
1.481     albertel 2315: 
1.483     foxr     2316: 
1.156     bowersj2 2317:     # Detect whether we're coming from construction space
1.373     albertel 2318:     if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235     bowersj2 2319:         $helper->{VARS}->{'filename'} = "~$1/$2";
1.156     bowersj2 2320:         $helper->{VARS}->{'construction'} = 1;
1.481     albertel 2321:     } else {
1.373     albertel 2322:         if ($env{'form.postdata'}) {
                   2323:             $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482     albertel 2324: 	    if ( $helper->{VARS}->{'symb'} eq '') {
                   2325: 		$helper->{VARS}->{'postdata'} = $env{'form.postdata'};
                   2326: 	    }
1.156     bowersj2 2327:         }
1.373     albertel 2328:         if ($env{'form.symb'}) {
                   2329:             $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156     bowersj2 2330:         }
1.373     albertel 2331:         if ($env{'form.url'}) {
1.156     bowersj2 2332:             $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
                   2333:         }
1.416     foxr     2334: 
1.157     bowersj2 2335:     }
1.481     albertel 2336: 
1.373     albertel 2337:     if ($env{'form.symb'}) {
                   2338:         $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146     bowersj2 2339:     }
1.373     albertel 2340:     if ($env{'form.url'}) {
1.140     sakharuk 2341:         $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153     sakharuk 2342: 
1.140     sakharuk 2343:     }
1.343     albertel 2344:     $helper->{VARS}->{'symb'}=
                   2345: 	&Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335     albertel 2346:     my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178     sakharuk 2347:     if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481     albertel 2348: 
1.156     bowersj2 2349:     
1.146     bowersj2 2350:     # Extract map
                   2351:     my $symb = $helper->{VARS}->{'symb'};
1.156     bowersj2 2352:     my ($map, $id, $url);
                   2353:     my $subdir;
1.483     foxr     2354:     my $is_published=0;		# True when printing from resource space.
1.156     bowersj2 2355: 
                   2356:     # Get the resource name from construction space
                   2357:     if ($helper->{VARS}->{'construction'}) {
                   2358:         $resourceTitle = substr($helper->{VARS}->{'filename'}, 
                   2359:                                 rindex($helper->{VARS}->{'filename'}, '/')+1);
                   2360:         $subdir = substr($helper->{VARS}->{'filename'},
                   2361:                          0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481     albertel 2362:     } else {
1.482     albertel 2363: 	if ($symb ne '') {
                   2364: 	    ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
                   2365: 	    $helper->{VARS}->{'postdata'} = 
                   2366: 		&Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
                   2367: 	} else {
                   2368: 	    $url = $helper->{VARS}->{'postdata'};
1.483     foxr     2369: 	    $is_published=1;	# From resource space.
1.482     albertel 2370: 	}
                   2371: 	$url = &Apache::lonnet::clutter($url);
1.481     albertel 2372: 
1.156     bowersj2 2373:         if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238     bowersj2 2374:             my $postdata = $helper->{VARS}->{'postdata'};
                   2375:             $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156     bowersj2 2376:         }
                   2377:         $subdir = &Apache::lonnet::filelocation("", $url);
1.128     bowersj2 2378:     }
1.373     albertel 2379:     if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
                   2380: 	$helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230     albertel 2381:     }
1.373     albertel 2382:     if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
                   2383: 	$helper->{VARS}->{'probstatus'}=$env{'form.problemtype'};
1.290     sakharuk 2384:     }
1.115     bowersj2 2385: 
1.192     bowersj2 2386:     my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
                   2387: 
1.481     albertel 2388:     Apache::lonhelper::registerHelperTags();
1.119     bowersj2 2389: 
1.131     bowersj2 2390:     # "Delete everything after the last slash."
1.119     bowersj2 2391:     $subdir =~ s|/[^/]+$||;
                   2392: 
1.131     bowersj2 2393:     # What can be printed is a very dynamic decision based on
                   2394:     # lots of factors. So we need to dynamically build this list.
                   2395:     # To prevent security leaks, states are only added to the wizard
                   2396:     # if they can be reached, which ensures manipulating the form input
                   2397:     # won't allow anyone to reach states they shouldn't have permission
                   2398:     # to reach.
                   2399: 
                   2400:     # printChoices is tracking the kind of printing the user can
                   2401:     # do, and will be used in a choices construction later.
                   2402:     # In the meantime we will be adding states and elements to
                   2403:     # the helper by hand.
                   2404:     my $printChoices = [];
                   2405:     my $paramHash;
1.130     sakharuk 2406: 
1.240     albertel 2407:     if ($resourceTitle) {
1.458     www      2408:         push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156     bowersj2 2409:     }
                   2410: 
1.238     bowersj2 2411:     # Useful filter strings
1.287     albertel 2412:     my $isProblem = '($res->is_problem()||$res->contains_problem) ';
1.238     bowersj2 2413:     $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.287     albertel 2414:     my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence()';
                   2415:     my $isNotMap = '!$res->is_sequence()';
1.238     bowersj2 2416:     $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
                   2417:     my $isMap = '$res->is_map()';
1.342     albertel 2418:     my $symbFilter = '$res->shown_symb()';
                   2419:     my $urlValue = '$res->link()';
1.238     bowersj2 2420: 
                   2421:     $helper->declareVar('SEQUENCE');
                   2422: 
1.465     albertel 2423:     # If we're in a sequence...
1.416     foxr     2424: 
1.465     albertel 2425:     my $start_new_option;
                   2426:     if ($perm{'pav'}) {
                   2427: 	$start_new_option = 
                   2428: 	    "<option text='".&mt('Start new page<br />before selected').
                   2429: 	    "' variable='FINISHPAGE' />";
                   2430:     }
1.238     bowersj2 2431: 
1.483     foxr     2432:     if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
1.350     foxr     2433: 
1.243     bowersj2 2434: 	$helper->{VARS}->{'postdata'} &&
                   2435: 	$helper->{VARS}->{'assignment'}) {
1.131     bowersj2 2436:         # Allow problems from sequence
1.458     www      2437:         push @{$printChoices}, [&mt('Selected <b>Problems</b> in folder <b><i>[_1]</i></b>',$sequenceTitle), 'map_problems', 'CHOOSE_PROBLEMS'];
1.131     bowersj2 2438:         # Allow all resources from sequence
1.458     www      2439:         push @{$printChoices}, [&mt('Selected <b>Resources</b> in folder <b><i>[_1]</i></b>',$sequenceTitle), 'map_problems_pages', 'CHOOSE_PROBLEMS_HTML'];
1.465     albertel 2440: 
1.131     bowersj2 2441:         my $helperFragment = <<HELPERFRAGMENT;
1.155     sakharuk 2442:   <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print">
1.435     foxr     2443:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 2444:               closeallpages="1">
1.144     bowersj2 2445:       <nextstate>PAGESIZE</nextstate>
1.435     foxr     2446:       <filterfunc>return $isProblem;</filterfunc>
1.131     bowersj2 2447:       <mapurl>$map</mapurl>
1.238     bowersj2 2448:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2449:       $start_new_option
1.131     bowersj2 2450:       </resource>
                   2451:     </state>
                   2452: 
1.155     sakharuk 2453:   <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print">
1.435     foxr     2454:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 2455:               closeallpages="1">
1.144     bowersj2 2456:       <nextstate>PAGESIZE</nextstate>
1.435     foxr     2457:       <filterfunc>return $isNotMap;</filterfunc>
1.131     bowersj2 2458:       <mapurl>$map</mapurl>
1.238     bowersj2 2459:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2460:       $start_new_option
1.131     bowersj2 2461:       </resource>
                   2462:     </state>
                   2463: HELPERFRAGMENT
1.121     bowersj2 2464: 
1.326     sakharuk 2465: 	&Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121     bowersj2 2466:     }
                   2467: 
1.397     albertel 2468:     # If the user has pfo (print for otheres) allow them to print all 
1.354     foxr     2469:     # problems and resources  in the entier course, optionally for selected students
1.483     foxr     2470:     if ($perm{'pfo'} &&  !$is_published  &&
1.481     albertel 2471:         ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) { 
                   2472: 
1.458     www      2473:         push @{$printChoices}, ['Selected <b>Problems</b> from <b>entire course</b>', 'all_problems', 'ALL_PROBLEMS'];
                   2474: 	push @{$printChoices}, ['Selected <b>Resources</b> from <b>entire course</b>', 'all_resources', 'ALL_RESOURCES'];
1.284     albertel 2475:          &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS);
1.155     sakharuk 2476:   <state name="ALL_PROBLEMS" title="Select Problem(s) to print">
1.287     albertel 2477:     <resource variable="RESOURCES" toponly='0' multichoice="1"
                   2478: 	suppressEmptySequences='0' addstatus="1" closeallpages="1">
1.144     bowersj2 2479:       <nextstate>PAGESIZE</nextstate>
1.192     bowersj2 2480:       <filterfunc>return $isProblemOrMap;</filterfunc>
1.287     albertel 2481:       <choicefunc>return $isNotMap;</choicefunc>
1.238     bowersj2 2482:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2483:       $start_new_option
1.284     albertel 2484:     </resource>
                   2485:   </state>
1.354     foxr     2486:   <state name="ALL_RESOURCES" title="Select Resource(s) to print">
                   2487:     <resource variable="RESOURCES" toponly='0' multichoice='1'
                   2488:               suppressEmptySequences='0' addstatus='1' closeallpages='1'>
                   2489:       <nextstate>PAGESIZE</nextstate>
                   2490:       <filterfunc>return $isNotMap; </filterfunc>
                   2491:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2492:       $start_new_option
1.354     foxr     2493:     </resource>
                   2494:   </state>
1.284     albertel 2495: ALL_PROBLEMS
1.132     bowersj2 2496: 
1.284     albertel 2497: 	if ($helper->{VARS}->{'assignment'}) {
1.483     foxr     2498: 	    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      2499: 	    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 2500: 	}
1.424     foxr     2501: 
1.507     albertel 2502: 	my $randomly_ordered_warning = 
                   2503: 	    &get_randomly_ordered_warning($helper,$map);
                   2504: 
1.424     foxr     2505: 	# resource_selector will hold a few states that:
                   2506: 	#   - Allow resources to be selected for printing.
                   2507: 	#   - Determine pagination between assignments.
                   2508: 	#   - Determine how many assignments should be bundled into a single PDF.
                   2509:         # TODO:
                   2510: 	#    Probably good to do things like separate this up into several vars, each
                   2511: 	#    with one state, and use REGEXPs at inclusion time to set state names
                   2512: 	#    and next states for better mix and match capability
                   2513: 	#
1.284     albertel 2514: 	my $resource_selector=<<RESOURCE_SELECTOR;
1.424     foxr     2515:     <state name="SELECT_PROBLEMS" title="Select resources to print">
1.507     albertel 2516:     $randomly_ordered_warning
                   2517: 
1.424     foxr     2518:    <nextstate>PRINT_FORMATTING</nextstate> 
1.284     albertel 2519:    <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287     albertel 2520:     <resource variable="RESOURCES" multichoice="1" addstatus="1" 
                   2521:               closeallpages="1">
1.254     sakharuk 2522:       <filterfunc>return $isProblem;</filterfunc>
1.148     bowersj2 2523:       <mapurl>$map</mapurl>
1.254     sakharuk 2524:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2525:       $start_new_option
1.147     bowersj2 2526:       </resource>
1.424     foxr     2527:     </state>
                   2528:     <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155     sakharuk 2529:     <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149     bowersj2 2530:     <choices variable="EMPTY_PAGES">
1.204     sakharuk 2531:       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
                   2532:       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
                   2533:       <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
                   2534:       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284     albertel 2535:     </choices>
1.424     foxr     2536:     <nextstate>PAGESIZE</nextstate>
1.429     foxr     2537:     <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
                   2538:     <choices variable="SPLIT_PDFS">
                   2539:        <choice computer="all">All assignments in a single PDF file</choice>
                   2540:        <choice computer="sections">Each PDF contains exactly one section</choice>
                   2541:        <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449     albertel 2542:        <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
                   2543:             Specify the number of assignments per PDF:</choice>
1.429     foxr     2544:     </choices>
1.424     foxr     2545:     </state>
1.284     albertel 2546: RESOURCE_SELECTOR
                   2547: 
                   2548:         &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS);
                   2549:   <state name="CHOOSE_STUDENTS" title="Select Students and Resources">
1.485     albertel 2550:       <message><b>Select sorting order of printout</b> </message>
1.340     foxr     2551:     <choices variable='student_sort'>
                   2552:       <choice computer='0'>Sort by section then student</choice>
                   2553:       <choice computer='1'>Sort by students across sections.</choice>
                   2554:     </choices>
1.437     foxr     2555:       <message><br /><hr /><br /> </message>
1.425     foxr     2556:       <student multichoice='1' variable="STUDENTS" nextstate="SELECT_PROBLEMS" coursepersonnel="1"/>
1.424     foxr     2557:   </state>
1.284     albertel 2558:     $resource_selector
1.131     bowersj2 2559: CHOOSE_STUDENTS
1.292     albertel 2560: 
1.373     albertel 2561: 	my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2562: 	my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292     albertel 2563:         my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
                   2564: 	my $namechoice='<choice></choice>';
1.337     albertel 2565: 	foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294     albertel 2566: 	    if ($name =~ /^error: 2 /) { next; }
1.381     albertel 2567: 	    if ($name =~ /^type\0/) { next; }
1.292     albertel 2568: 	    $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
                   2569: 	}
1.389     foxr     2570: 
                   2571: 
                   2572: 	my %code_values;
1.405     albertel 2573: 	my %codes_to_print;
1.411     albertel 2574: 	foreach my $key (@names) {
1.389     foxr     2575: 	    %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405     albertel 2576: 	    foreach my $key (keys(%code_values)) {
                   2577: 		$codes_to_print{$key} = 1;
1.388     foxr     2578: 	    }
                   2579: 	}
1.389     foxr     2580: 
1.452     albertel 2581: 	my $code_selection;
1.405     albertel 2582: 	foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389     foxr     2583: 	    my $choice  = $code;
                   2584: 	    if ($code =~ /^[A-Z]+$/) { # Alpha code
                   2585: 		$choice = &letters_to_num($code);
                   2586: 	    }
1.432     albertel 2587: 	    push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388     foxr     2588: 	}
1.436     albertel 2589: 	if (%codes_to_print) {
                   2590: 	    $code_selection .='   
1.472     albertel 2591: 	    <message><b>Choose single CODE from list:</b></message>
1.448     albertel 2592: 		<message></td><td></message>
1.452     albertel 2593: 		<dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
                   2594:                   <choice></choice>
1.448     albertel 2595:                   <exec>
                   2596:                      push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
                   2597:                   </exec>
1.452     albertel 2598: 		</dropdown>
1.468     foxr     2599: 	    <message></td></tr><tr><td></message>
1.436     albertel 2600:             '.$/;
1.448     albertel 2601: 
1.436     albertel 2602: 	}
1.432     albertel 2603: 
                   2604: 	
1.381     albertel 2605: 	open(FH,$Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
                   2606: 	my $codechoice='';
                   2607: 	foreach my $line (<FH>) {
                   2608: 	    my ($name,$description,$code_type,$code_length)=
                   2609: 		(split(/:/,$line))[0,1,2,4];
                   2610: 	    if ($code_length > 0 && 
                   2611: 		$code_type =~/^(letter|number|-1)/) {
                   2612: 		$codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
                   2613: 	    }
                   2614: 	}
                   2615: 	if ($codechoice eq '') {
                   2616: 	    $codechoice='<choice computer="default">Default</choice>';
                   2617: 	}
1.284     albertel 2618:         &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1);
1.468     foxr     2619:   <state name="CHOOSE_ANON1" title="Specify CODEd Assignments">
1.424     foxr     2620:     <nextstate>SELECT_PROBLEMS</nextstate>
1.468     foxr     2621:     <message><h4>Fill out one of the forms below</h4></message>
                   2622:     <message><br /><hr /> <br /></message>
                   2623:     <message><h3>Generate new CODEd Assignments</h3></message>
                   2624:     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362     albertel 2625:     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
                   2626:        <validator>
                   2627: 	if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.382     foxr     2628: 	    !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
1.388     foxr     2629:             !\$helper->{'VARS'}{'SINGLE_CODE'}                    &&
                   2630: 	    !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362     albertel 2631: 	    return "You need to specify the number of assignments to print";
                   2632: 	}
                   2633: 	return undef;
                   2634:        </validator>
                   2635:     </string>
                   2636:     <message></td></tr><tr><td></message>
1.501     albertel 2637:     <message><b>Names to save the CODEs under for later:</b></message>
1.412     albertel 2638:     <message></td><td></message>
                   2639:     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
                   2640:     <message></td></tr><tr><td></message>
                   2641:     <message><b>Bubble sheet type:</b></message>
                   2642:     <message></td><td></message>
                   2643:     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
                   2644:     $codechoice
                   2645:     </dropdown>
1.468     foxr     2646:     <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>
                   2647:     <message></td></tr><tr><td></table></message>
1.472     albertel 2648:     <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
1.468     foxr     2649:     <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412     albertel 2650:     <string variable="SINGLE_CODE" size="10">
1.382     foxr     2651:         <validator>
                   2652: 	   if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&
1.388     foxr     2653: 	      !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&
                   2654: 	      !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.382     foxr     2655: 	      return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
                   2656: 						      \$helper->{'VARS'}{'CODE_OPTION'});
                   2657: 	   } else {
                   2658: 	       return undef;	# Other forces control us.
                   2659: 	   }
                   2660:         </validator>
                   2661:     </string>
1.472     albertel 2662:     <message></td></tr><tr><td></message>
1.432     albertel 2663:         $code_selection
1.468     foxr     2664:     <message></td></tr></table></message>
1.472     albertel 2665:     <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
1.468     foxr     2666:     <message><b>Select saved CODEs:</b></message>
1.381     albertel 2667:     <message></td><td></message>
1.292     albertel 2668:     <dropdown variable="REUSE_OLD_CODES">
                   2669:         $namechoice
                   2670:     </dropdown>
1.412     albertel 2671:     <message></td></tr></table></message>
1.284     albertel 2672:   </state>
1.424     foxr     2673:   $resource_selector
1.284     albertel 2674: CHOOSE_ANON1
1.254     sakharuk 2675: 
1.272     sakharuk 2676: 
1.254     sakharuk 2677: 	if ($helper->{VARS}->{'assignment'}) {
1.483     foxr     2678: 	    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 2679: 	    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 2680: 	}
1.284     albertel 2681: 	    
                   2682: 
                   2683: 	$resource_selector=<<RESOURCE_SELECTOR;
1.424     foxr     2684:     <state name="SELECT_RESOURCES" title="Select Resources">
1.507     albertel 2685:     $randomly_ordered_warning
                   2686: 
1.424     foxr     2687:     <nextstate>PRINT_FORMATTING</nextstate>
1.254     sakharuk 2688:     <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287     albertel 2689:     <resource variable="RESOURCES" multichoice="1" addstatus="1" 
                   2690:               closeallpages="1">
1.254     sakharuk 2691:       <filterfunc>return $isNotMap;</filterfunc>
                   2692:       <mapurl>$map</mapurl>
                   2693:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2694:       $start_new_option
1.254     sakharuk 2695:       </resource>
1.424     foxr     2696:     </state>
                   2697:     <state name="PRINT_FORMATTING" title="Format of the print job">
                   2698:     <nextstate>NUMBER_PER_PDF</nextstate>
1.254     sakharuk 2699:     <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
                   2700:     <choices variable="EMPTY_PAGES">
                   2701:       <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
                   2702:       <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
                   2703:       <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
                   2704:       <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284     albertel 2705:     </choices>
1.424     foxr     2706:     <nextstate>PAGESIZE</nextstate>
1.429     foxr     2707:     <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
                   2708:     <choices variable="SPLIT_PDFS">
                   2709:        <choice computer="all">All assignments in a single PDF file</choice>
                   2710:        <choice computer="sections">Each PDF contains exactly one section</choice>
                   2711:        <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449     albertel 2712:        <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
                   2713:            Specify the number of assignments per PDF:</choice>
1.429     foxr     2714:     </choices>
1.424     foxr     2715:     </state>
1.284     albertel 2716: RESOURCE_SELECTOR
                   2717: 
                   2718: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
                   2719:   <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340     foxr     2720:     <choices variable='student_sort'>
                   2721:       <choice computer='0'>Sort by section then student</choice>
                   2722:       <choice computer='1'>Sort by students across sections.</choice>
                   2723:     </choices>
1.437     foxr     2724:     <message><br /><hr /><br /></message>
1.426     foxr     2725:     <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340     foxr     2726: 
1.424     foxr     2727:     </state>
1.284     albertel 2728:     $resource_selector
1.254     sakharuk 2729: CHOOSE_STUDENTS1
                   2730: 
1.284     albertel 2731: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472     albertel 2732:   <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424     foxr     2733:     <nextstate>SELECT_RESOURCES</nextstate>
1.472     albertel 2734:     <message><h4>Fill out one of the forms below</h4></message>
                   2735:     <message><br /><hr /> <br /></message>
                   2736:     <message><h3>Generate new CODEd Assignments</h3></message>
                   2737:     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362     albertel 2738:     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
                   2739:        <validator>
                   2740: 	if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386     foxr     2741: 	    !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
1.388     foxr     2742: 	    !\$helper->{'VARS'}{'SINGLE_CODE'}                   &&
                   2743: 	    !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362     albertel 2744: 	    return "You need to specify the number of assignments to print";
                   2745: 	}
                   2746: 	return undef;
                   2747:        </validator>
                   2748:     </string>
                   2749:     <message></td></tr><tr><td></message>
1.501     albertel 2750:     <message><b>Names to save the CODEs under for later:</b></message>
1.412     albertel 2751:     <message></td><td></message>
                   2752:     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
                   2753:     <message></td></tr><tr><td></message>
                   2754:     <message><b>Bubble sheet type:</b></message>
                   2755:     <message></td><td></message>
                   2756:     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
                   2757:     $codechoice
                   2758:     </dropdown>
1.472     albertel 2759:     <message></td></tr><tr><td></table></message>
                   2760:     <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
                   2761:     <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412     albertel 2762:     <string variable="SINGLE_CODE" size="10">
1.386     foxr     2763:         <validator>
                   2764: 	   if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&
1.388     foxr     2765: 	      !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&
                   2766: 	      !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386     foxr     2767: 	      return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
                   2768: 						      \$helper->{'VARS'}{'CODE_OPTION'});
                   2769: 	   } else {
                   2770: 	       return undef;	# Other forces control us.
                   2771: 	   }
                   2772:         </validator>
                   2773:     </string>
1.472     albertel 2774:     <message></td></tr><tr><td></message>
1.432     albertel 2775:         $code_selection
1.472     albertel 2776:     <message></td></tr></table></message>
                   2777:     <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
                   2778:     <message><b>Select saved CODEs:</b></message>
1.381     albertel 2779:     <message></td><td></message>
1.294     albertel 2780:     <dropdown variable="REUSE_OLD_CODES">
                   2781:         $namechoice
                   2782:     </dropdown>
1.412     albertel 2783:     <message></td></tr></table></message>
1.424     foxr     2784:   </state>
1.284     albertel 2785:     $resource_selector
                   2786: CHOOSE_ANON2
1.481     albertel 2787:     }
                   2788: 
1.121     bowersj2 2789:     # FIXME: That RE should come from a library somewhere.
1.483     foxr     2790:     if (($perm{'pav'} 
1.482     albertel 2791: 	&& $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
                   2792: 	&& (defined($helper->{'VARS'}->{'construction'})
                   2793: 	    ||
                   2794: 	    (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
                   2795: 	     && 
                   2796: 	     $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483     foxr     2797: 	    )) 
                   2798: 	&& $helper->{VARS}->{'assignment'} eq ""
1.482     albertel 2799: 	) {
1.238     bowersj2 2800: 
1.482     albertel 2801: 	my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
                   2802:         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 2803:         my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482     albertel 2804:   <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458     www      2805: 
1.138     bowersj2 2806:     <files variable="FILES" multichoice='1'>
1.144     bowersj2 2807:       <nextstate>PAGESIZE</nextstate>
1.138     bowersj2 2808:       <filechoice>return '$subdir';</filechoice>
1.139     bowersj2 2809: CHOOSE_FROM_SUBDIR
                   2810:         
1.238     bowersj2 2811:         # this is broken up because I really want interpolation above,
                   2812:         # and I really DON'T want it below
1.139     bowersj2 2813:         $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225     bowersj2 2814:       <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
                   2815: 	  $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131     bowersj2 2816:       </filefilter>
1.138     bowersj2 2817:       </files>
1.131     bowersj2 2818:     </state>
                   2819: CHOOSE_FROM_SUBDIR
1.139     bowersj2 2820:         &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131     bowersj2 2821:     }
1.238     bowersj2 2822: 
                   2823:     # Allow the user to select any sequence in the course, feed it to
                   2824:     # another resource selector for that sequence
1.483     foxr     2825:     if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.458     www      2826: 	push @$printChoices, ["Selected <b>Resources</b> from <b>selected folder</b> in course",
1.249     sakharuk 2827: 			      'select_sequences', 'CHOOSE_SEQUENCE'];
1.244     bowersj2 2828: 	my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
                   2829: 	#Escape apostrophes and backslashes for Perl
                   2830: 	$escapedSequenceName =~ s/\\/\\\\/g;
                   2831: 	$escapedSequenceName =~ s/'/\\'/g;
1.239     bowersj2 2832: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238     bowersj2 2833:   <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
                   2834:     <message>Select the sequence to print resources from:</message>
                   2835:     <resource variable="SEQUENCE">
                   2836:       <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
                   2837:       <filterfunc>return \$res->is_sequence;</filterfunc>
                   2838:       <valuefunc>return $urlValue;</valuefunc>
1.447     foxr     2839:       <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391     foxr     2840: 	</choicefunc>
1.238     bowersj2 2841:       </resource>
                   2842:     </state>
                   2843:   <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
                   2844:     <message>(mark desired resources then click "next" button) <br /></message>
1.435     foxr     2845:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 2846:               closeallpages="1">
1.238     bowersj2 2847:       <nextstate>PAGESIZE</nextstate>
1.466     albertel 2848:       <filterfunc>return $isNotMap</filterfunc>
1.244     bowersj2 2849:       <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238     bowersj2 2850:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 2851:       $start_new_option
1.238     bowersj2 2852:       </resource>
                   2853:     </state>
                   2854: CHOOSE_FROM_ANY_SEQUENCE
1.239     bowersj2 2855: }
1.481     albertel 2856: 
1.131     bowersj2 2857:     # Generate the first state, to select which resources get printed.
1.223     bowersj2 2858:     Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131     bowersj2 2859:     $paramHash = Apache::lonhelper::getParamHash();
1.155     sakharuk 2860:     $paramHash->{MESSAGE_TEXT} = "";
1.131     bowersj2 2861:     Apache::lonhelper::message->new();
                   2862:     $paramHash = Apache::lonhelper::getParamHash();
                   2863:     $paramHash->{'variable'} = 'PRINT_TYPE';
                   2864:     $paramHash->{CHOICES} = $printChoices;
                   2865:     Apache::lonhelper::choices->new();
1.161     bowersj2 2866: 
1.223     bowersj2 2867:     my $startedTable = 0; # have we started an HTML table yet? (need
                   2868:                           # to close it later)
                   2869: 
1.397     albertel 2870:     if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or 
1.170     sakharuk 2871: 	($helper->{VARS}->{'construction'} eq '1')) {
1.497     www      2872: 	addMessage("<hr width='33%' /><table><tr><td align='right'>".
                   2873:                    '<label for="ANSWER_TYPE_forminput">'.
                   2874:                    &mt('Print').
                   2875:                    "</label>: </td><td>");
1.161     bowersj2 2876:         $paramHash = Apache::lonhelper::getParamHash();
1.162     sakharuk 2877: 	$paramHash->{'variable'} = 'ANSWER_TYPE';   
                   2878: 	$helper->declareVar('ANSWER_TYPE');         
1.161     bowersj2 2879:         $paramHash->{CHOICES} = [
1.242     sakharuk 2880:                                    ['Without Answers', 'yes'],
                   2881:                                    ['With Answers', 'no'],
1.368     albertel 2882:                                    ['Only Answers', 'only']
1.289     sakharuk 2883:                                 ];
1.210     sakharuk 2884:         Apache::lonhelper::dropdown->new();
1.223     bowersj2 2885: 	addMessage("</td></tr>");
                   2886: 	$startedTable = 1;
1.161     bowersj2 2887:     }
1.209     sakharuk 2888: 
1.397     albertel 2889:     if ($perm{'pav'}) {
1.223     bowersj2 2890: 	if (!$startedTable) {
1.497     www      2891: 	    addMessage("<hr width='33%' /><table><tr><td align='right'>".
                   2892:                        '<label for="LATEX_TYPE_forminput">'.
                   2893:                        &mt('LaTeX mode').
                   2894:                        "</label>: </td><td>");
1.223     bowersj2 2895: 	    $startedTable = 1;
                   2896: 	} else {
1.497     www      2897: 	    addMessage("<tr><td align='right'>".
                   2898:                        '<label for="LATEX_TYPE_forminput">'.
                   2899:                         &mt('LaTeX mode').
                   2900:                        "</label>: </td><td>");
1.223     bowersj2 2901: 	}
1.203     sakharuk 2902:         $paramHash = Apache::lonhelper::getParamHash();
                   2903: 	$paramHash->{'variable'} = 'LATEX_TYPE';   
                   2904: 	$helper->declareVar('LATEX_TYPE');  
                   2905: 	if ($helper->{VARS}->{'construction'} eq '1') {       
                   2906: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 2907: 				     ['standard LaTeX mode', 'standard'], 
                   2908: 				     ['LaTeX batchmode', 'batchmode'], ];
1.203     sakharuk 2909: 	} else {
                   2910: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 2911: 				     ['LaTeX batchmode', 'batchmode'],
                   2912: 				     ['standard LaTeX mode', 'standard'] ];
1.203     sakharuk 2913: 	}
1.210     sakharuk 2914:         Apache::lonhelper::dropdown->new();
1.218     sakharuk 2915:  
1.497     www      2916: 	addMessage("</td></tr><tr><td align='right'>".
1.506     albertel 2917:                    '<label for="TABLE_CONTENTS_forminput">'.
1.497     www      2918:                    &mt('Print Table of Contents').
                   2919:                    "</label>: </td><td>");
1.209     sakharuk 2920:         $paramHash = Apache::lonhelper::getParamHash();
                   2921: 	$paramHash->{'variable'} = 'TABLE_CONTENTS';   
                   2922: 	$helper->declareVar('TABLE_CONTENTS');         
                   2923:         $paramHash->{CHOICES} = [
1.223     bowersj2 2924:                                    ['No', 'no'],
                   2925:                                    ['Yes', 'yes'] ];
1.210     sakharuk 2926:         Apache::lonhelper::dropdown->new();
1.223     bowersj2 2927: 	addMessage("</td></tr>");
1.214     sakharuk 2928:         
1.220     sakharuk 2929: 	if (not $helper->{VARS}->{'construction'}) {
1.497     www      2930: 	    addMessage("<tr><td align='right'>".
                   2931:                        '<label for="TABLE_INDEX_forminput">'.
                   2932:                        &mt('Print Index').
                   2933:                        "</label>: </td><td>");
1.220     sakharuk 2934: 	    $paramHash = Apache::lonhelper::getParamHash();
                   2935: 	    $paramHash->{'variable'} = 'TABLE_INDEX';   
                   2936: 	    $helper->declareVar('TABLE_INDEX');         
                   2937: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 2938: 				     ['No', 'no'],
                   2939: 				     ['Yes', 'yes'] ];
1.220     sakharuk 2940: 	    Apache::lonhelper::dropdown->new();
1.223     bowersj2 2941: 	    addMessage("</td></tr>");
1.497     www      2942: 	    addMessage("<tr><td align='right'>".
                   2943:                        '<label for="PRINT_DISCUSSIONS_forminput">'.
                   2944:                        &mt('Print Discussions').
                   2945:                        "</label>: </td><td>");
1.309     sakharuk 2946: 	    $paramHash = Apache::lonhelper::getParamHash();
                   2947: 	    $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';   
                   2948: 	    $helper->declareVar('PRINT_DISCUSSIONS');         
                   2949: 	    $paramHash->{CHOICES} = [
                   2950: 				     ['No', 'no'],
                   2951: 				     ['Yes', 'yes'] ];
                   2952: 	    Apache::lonhelper::dropdown->new();
                   2953: 	    addMessage("</td></tr>");
1.372     foxr     2954: 
1.397     albertel 2955: 	    addMessage("<tr><td align = 'right'>  </td><td>");
                   2956: 	    $paramHash = Apache::lonhelper::getParamHash();
                   2957: 	    $paramHash->{'multichoice'} = "true";
                   2958: 	    $paramHash->{'allowempty'}  = "true";
                   2959: 	    $paramHash->{'variable'}   = "showallfoils";
                   2960: 	    $paramHash->{'CHOICES'} = [ ["Show all foils", "1"] ];
                   2961: 	    Apache::lonhelper::choices->new();
                   2962: 	    addMessage("</td></tr>");
1.220     sakharuk 2963: 	}
1.219     sakharuk 2964: 
1.230     albertel 2965: 	if ($helper->{'VARS'}->{'construction'}) { 
1.505     albertel 2966: 	    my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497     www      2967:             my $randseedtext=&mt("Use random seed");
                   2968:             my $stylefiletext=&mt("Use style file");
1.506     albertel 2969:             my $selectfiletext=&mt("Select style file");
1.497     www      2970: 
1.265     sakharuk 2971: 	    my $xmlfrag .= <<"RNDSEED";
1.497     www      2972: 	    <message><tr><td align='right'>
                   2973:             <label for="curseed_forminput">$randseedtext</label>:
                   2974:             </td><td></message>
1.230     albertel 2975: 	    <string variable="curseed" size="15" maxlength="15">
                   2976: 		<defaultvalue>
                   2977: 	            return $helper->{VARS}->{'curseed'};
                   2978: 	        </defaultvalue>
1.262     sakharuk 2979: 	    </string>
1.497     www      2980: 	     <message></td></tr><tr><td align="right">
1.503     albertel 2981:              <label for="style_file">$stylefiletext</label>:
1.497     www      2982:              </td><td></message>
1.504     albertel 2983:              <string variable="style_file" size="40">
                   2984: 		<defaultvalue>
1.505     albertel 2985: 	            return $stylevalue;
1.504     albertel 2986: 	        </defaultvalue>
1.506     albertel 2987:              </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     2988: 	     <choices allowempty="1" multichoice="true" variable="showallfoils">
1.506     albertel 2989:                 <choice computer="1">Show all foils</choice>
1.371     foxr     2990:              </choices>
1.378     albertel 2991: 	     <message></td></tr></message>
1.230     albertel 2992: RNDSEED
                   2993:             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.372     foxr     2994: 	} 
1.223     bowersj2 2995:     }
1.264     sakharuk 2996: 
                   2997: 
                   2998: 
1.218     sakharuk 2999: 
1.223     bowersj2 3000:     if ($startedTable) {
                   3001: 	addMessage("</table>");
1.215     sakharuk 3002:     }
1.161     bowersj2 3003: 
1.131     bowersj2 3004:     Apache::lonprintout::page_format_state->new("FORMAT");
                   3005: 
1.144     bowersj2 3006:     # Generate the PAGESIZE state which will offer the user the margin
                   3007:     # choices if they select one column
                   3008:     Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
                   3009:     Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
                   3010: 
                   3011: 
1.131     bowersj2 3012:     $helper->process();
                   3013: 
1.416     foxr     3014: 
1.131     bowersj2 3015:     # MANUAL BAILOUT CONDITION:
                   3016:     # If we're in the "final" state, bailout and return to handler
                   3017:     if ($helper->{STATE} eq 'FINAL') {
                   3018:         return $helper;
                   3019:     }    
1.130     sakharuk 3020: 
1.131     bowersj2 3021:     $r->print($helper->display());
1.395     www      3022:     if ($helper->{STATE} eq 'START') {
                   3023: 	&recently_generated($r);
                   3024:     }
1.333     albertel 3025:     &Apache::lonhelper::unregisterHelperTags();
1.115     bowersj2 3026: 
                   3027:     return OK;
                   3028: }
                   3029: 
1.1       www      3030: 
                   3031: 1;
1.119     bowersj2 3032: 
                   3033: package Apache::lonprintout::page_format_state;
                   3034: 
                   3035: =pod
                   3036: 
1.131     bowersj2 3037: =head1 Helper element: page_format_state
                   3038: 
                   3039: See lonhelper.pm documentation for discussion of the helper framework.
1.119     bowersj2 3040: 
1.131     bowersj2 3041: Apache::lonprintout::page_format_state is an element that gives the 
                   3042: user an opportunity to select the page layout they wish to print 
                   3043: with: Number of columns, portrait/landscape, and paper size. If you 
                   3044: want to change the paper size choices, change the @paperSize array 
                   3045: contents in this package.
1.119     bowersj2 3046: 
1.131     bowersj2 3047: page_format_state is always directly invoked in lonprintout.pm, so there
                   3048: is no tag interface. You actually pass parameters to the constructor.
1.119     bowersj2 3049: 
                   3050: =over 4
                   3051: 
1.131     bowersj2 3052: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119     bowersj2 3053: 
                   3054: =back
                   3055: 
                   3056: =cut
                   3057: 
1.131     bowersj2 3058: use Apache::lonhelper;
1.119     bowersj2 3059: 
                   3060: no strict;
1.131     bowersj2 3061: @ISA = ("Apache::lonhelper::element");
1.119     bowersj2 3062: use strict;
1.266     sakharuk 3063: use Apache::lonlocal;
1.373     albertel 3064: use Apache::lonnet;
1.119     bowersj2 3065: 
                   3066: my $maxColumns = 2;
1.376     albertel 3067: # it'd be nice if these all worked
                   3068: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 
                   3069: #                 "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
                   3070: #                 "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]", 
                   3071: #                 "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326     sakharuk 3072: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 
1.376     albertel 3073: 		 "a4 [210x297 mm]");
1.119     bowersj2 3074: 
                   3075: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
                   3076: #                   Paper type
                   3077: 
                   3078: sub new { 
1.131     bowersj2 3079:     my $self = Apache::lonhelper::element->new();
1.119     bowersj2 3080: 
1.135     bowersj2 3081:     shift;
                   3082: 
1.131     bowersj2 3083:     $self->{'variable'} = shift;
1.134     bowersj2 3084:     my $helper = Apache::lonhelper::getHelper();
1.135     bowersj2 3085:     $helper->declareVar($self->{'variable'});
1.131     bowersj2 3086:     bless($self);
1.119     bowersj2 3087:     return $self;
                   3088: }
                   3089: 
                   3090: sub render {
                   3091:     my $self = shift;
1.131     bowersj2 3092:     my $helper = Apache::lonhelper::getHelper();
1.119     bowersj2 3093:     my $result = '';
1.131     bowersj2 3094:     my $var = $self->{'variable'};
1.266     sakharuk 3095:     my $PageLayout=&mt('Page layout');
                   3096:     my $NumberOfColumns=&mt('Number of columns');
                   3097:     my $PaperType=&mt('Paper type');
1.506     albertel 3098:     my $landscape=&mt('Landscape');
                   3099:     my $portrait=&mt('Portrait');
1.119     bowersj2 3100:     $result .= <<STATEHTML;
                   3101: 
1.223     bowersj2 3102: <hr width="33%" />
1.119     bowersj2 3103: <table cellpadding="3">
                   3104:   <tr>
1.266     sakharuk 3105:     <td align="center"><b>$PageLayout</b></td>
                   3106:     <td align="center"><b>$NumberOfColumns</b></td>
                   3107:     <td align="center"><b>$PaperType</b></td>
1.119     bowersj2 3108:   </tr>
                   3109:   <tr>
                   3110:     <td>
1.506     albertel 3111:       <label><input type="radio" name="${var}.layout" value="L" /> $landscape </label><br />
                   3112:       <label><input type="radio" name="${var}.layout" value="P" checked='1'  /> $portrait </label>
1.119     bowersj2 3113:     </td>
1.155     sakharuk 3114:     <td align="center">
1.119     bowersj2 3115:       <select name="${var}.cols">
                   3116: STATEHTML
                   3117: 
                   3118:     my $i;
                   3119:     for ($i = 1; $i <= $maxColumns; $i++) {
1.144     bowersj2 3120:         if ($i == 2) {
1.119     bowersj2 3121:             $result .= "<option value='$i' selected>$i</option>\n";
                   3122:         } else {
                   3123:             $result .= "<option value='$i'>$i</option>\n";
                   3124:         }
                   3125:     }
                   3126: 
                   3127:     $result .= "</select></td><td>\n";
                   3128:     $result .= "<select name='${var}.paper'>\n";
                   3129: 
1.373     albertel 3130:     my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398     albertel 3131:     my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
                   3132:     $DefaultPaperSize=~s/\s//g;
1.304     sakharuk 3133:     if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119     bowersj2 3134:     $i = 0;
                   3135:     foreach (@paperSize) {
1.326     sakharuk 3136: 	$_=~/(\w+)/;
                   3137: 	my $papersize=$1;
1.304     sakharuk 3138:         if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.326     sakharuk 3139:             $result .= "<option selected value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119     bowersj2 3140:         } else {
1.326     sakharuk 3141:             $result .= "<option value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119     bowersj2 3142:         }
                   3143:         $i++;
                   3144:     }
                   3145:     $result .= "</select></td></tr></table>";
                   3146:     return $result;
1.135     bowersj2 3147: }
                   3148: 
                   3149: sub postprocess {
                   3150:     my $self = shift;
                   3151: 
                   3152:     my $var = $self->{'variable'};
1.136     bowersj2 3153:     my $helper = Apache::lonhelper->getHelper();
1.135     bowersj2 3154:     $helper->{VARS}->{$var} = 
1.373     albertel 3155:         $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
                   3156:         $env{"form.$var.paper"};
1.135     bowersj2 3157:     return 1;
1.119     bowersj2 3158: }
                   3159: 
                   3160: 1;
1.144     bowersj2 3161: 
                   3162: package Apache::lonprintout::page_size_state;
                   3163: 
                   3164: =pod
                   3165: 
                   3166: =head1 Helper element: page_size_state
                   3167: 
                   3168: See lonhelper.pm documentation for discussion of the helper framework.
                   3169: 
                   3170: Apache::lonprintout::page_size_state is an element that gives the 
                   3171: user the opportunity to further refine the page settings if they
                   3172: select a single-column page.
                   3173: 
                   3174: page_size_state is always directly invoked in lonprintout.pm, so there
                   3175: is no tag interface. You actually pass parameters to the constructor.
                   3176: 
                   3177: =over 4
                   3178: 
                   3179: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
                   3180: 
                   3181: =back
                   3182: 
                   3183: =cut
                   3184: 
                   3185: use Apache::lonhelper;
1.373     albertel 3186: use Apache::lonnet;
1.144     bowersj2 3187: no strict;
                   3188: @ISA = ("Apache::lonhelper::element");
                   3189: use strict;
                   3190: 
                   3191: 
                   3192: 
                   3193: sub new { 
                   3194:     my $self = Apache::lonhelper::element->new();
                   3195: 
                   3196:     shift; # disturbs me (probably prevents subclassing) but works (drops
                   3197:            # package descriptor)... - Jeremy
                   3198: 
                   3199:     $self->{'variable'} = shift;
                   3200:     my $helper = Apache::lonhelper::getHelper();
                   3201:     $helper->declareVar($self->{'variable'});
                   3202: 
                   3203:     # The variable name of the format element, so we can look into 
                   3204:     # $helper->{VARS} to figure out whether the columns are one or two
                   3205:     $self->{'formatvar'} = shift;
                   3206: 
1.463     foxr     3207: 
1.144     bowersj2 3208:     $self->{NEXTSTATE} = shift;
                   3209:     bless($self);
1.467     foxr     3210: 
1.144     bowersj2 3211:     return $self;
                   3212: }
                   3213: 
                   3214: sub render {
                   3215:     my $self = shift;
                   3216:     my $helper = Apache::lonhelper::getHelper();
                   3217:     my $result = '';
                   3218:     my $var = $self->{'variable'};
                   3219: 
1.467     foxr     3220: 
                   3221: 
1.144     bowersj2 3222:     if (defined $self->{ERROR_MSG}) {
1.464     albertel 3223:         $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144     bowersj2 3224:     }
                   3225: 
1.438     foxr     3226:     my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463     foxr     3227: 
                   3228:     # Use format to get sensible defaults for the margins:
                   3229: 
                   3230: 
                   3231:     my ($laystyle, $cols, $papersize) = split(/\|/, $format);
                   3232:     ($papersize)                      = split(/ /, $papersize);
                   3233: 
                   3234: 
                   3235:     if ($laystyle eq 'L') {
                   3236: 	$laystyle = 'album';
                   3237:     } else {
                   3238: 	$laystyle = 'book';
                   3239:     }
                   3240: 
                   3241: 
1.464     albertel 3242:     my %size;
                   3243:     ($size{'width_and_units'},
                   3244:      $size{'height_and_units'},
                   3245:      $size{'margin_and_units'})=
                   3246: 	 &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463     foxr     3247:     
1.464     albertel 3248:     foreach my $dimension ('width','height','margin') {
                   3249: 	($size{$dimension},$size{$dimension.'_unit'}) =
                   3250: 	    split(/ +/, $size{$dimension.'_and_units'},2);
                   3251:        	
                   3252: 	foreach my $unit ('cm','in') {
                   3253: 	    $size{$dimension.'_options'} .= '<option ';
                   3254: 	    if ($size{$dimension.'_unit'} eq $unit) {
                   3255: 		$size{$dimension.'_options'} .= 'selected="selected" ';
                   3256: 	    }
                   3257: 	    $size{$dimension.'_options'} .= '>'.$unit.'</option>';
                   3258: 	}
1.438     foxr     3259:     }
                   3260: 
1.470     foxr     3261:     # Adjust margin for LaTeX margin: .. requires units == cm or in.
                   3262: 
                   3263:     if ($size{'margin_unit'} eq 'in') {
                   3264: 	$size{'margin'} += 1;
                   3265:     }  else {
                   3266: 	$size{'margin'} += 2.54;
                   3267:     }
1.506     albertel 3268:     my %text = ('format' => 'How should each column be formatted?',
                   3269: 		'width'  => 'Width:',
                   3270: 		'height' => 'Height:',
                   3271: 		'margin' => 'Left Margin:',);
                   3272:     %text = &Apache::lonlocal::texthash(%text);
                   3273: 
1.144     bowersj2 3274:     $result .= <<ELEMENTHTML;
                   3275: 
1.506     albertel 3276: <p>$text{'format'}</p>
1.144     bowersj2 3277: 
                   3278: <table cellpadding='3'>
                   3279:   <tr>
1.506     albertel 3280:     <td align='right'><b>$text{'width'}</b></td>
1.464     albertel 3281:     <td align='left'><input type='text' name='$var.width' value="$size{'width'}" size='4' /></td>
1.144     bowersj2 3282:     <td align='left'>
                   3283:       <select name='$var.widthunit'>
1.464     albertel 3284:       $size{'width_options'}
1.144     bowersj2 3285:       </select>
                   3286:     </td>
                   3287:   </tr>
                   3288:   <tr>
1.506     albertel 3289:     <td align='right'><b>$text{'height'}</b></td>
1.464     albertel 3290:     <td align='left'><input type='text' name="$var.height" value="$size{'height'}" size='4' /></td>
1.144     bowersj2 3291:     <td align='left'>
                   3292:       <select name='$var.heightunit'>
1.464     albertel 3293:       $size{'height_options'}
1.144     bowersj2 3294:       </select>
                   3295:     </td>
                   3296:   </tr>
                   3297:   <tr>
1.506     albertel 3298:     <td align='right'><b>$text{'margin'}</b></td>
1.464     albertel 3299:     <td align='left'><input type='text' name='$var.lmargin' value="$size{'margin'}" size='4' /></td>
1.144     bowersj2 3300:     <td align='left'>
1.186     bowersj2 3301:       <select name='$var.lmarginunit'>
1.464     albertel 3302:       $size{'margin_options'}
1.144     bowersj2 3303:       </select>
                   3304:     </td>
                   3305:   </tr>
                   3306: </table>
                   3307: 
1.464     albertel 3308: <!--<p>Hint: Some instructors like to leave scratch space for the student by
                   3309: making the width much smaller than the width of the page.</p>-->
1.144     bowersj2 3310: 
                   3311: ELEMENTHTML
                   3312: 
                   3313:     return $result;
                   3314: }
                   3315: 
1.470     foxr     3316: 
1.144     bowersj2 3317: sub preprocess {
                   3318:     my $self = shift;
                   3319:     my $helper = Apache::lonhelper::getHelper();
                   3320: 
                   3321:     my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467     foxr     3322: 
                   3323:     #  If the user does not have 'pav' privilege, set default widths and
                   3324:     #  on to the next state right away.
                   3325:     #
                   3326:     if (!$perm{'pav'}) {
                   3327: 	my $var = $self->{'variable'};
                   3328: 	my $format = $helper->{VARS}->{$self->{'formatvar'}};
                   3329: 	
                   3330: 	my ($laystyle, $cols, $papersize) = split(/\|/, $format);
                   3331: 	($papersize)                      = split(/ /, $papersize);
                   3332: 	
                   3333: 	
                   3334: 	if ($laystyle eq 'L') {
                   3335: 	    $laystyle = 'album';
                   3336: 	} else {
                   3337: 	    $laystyle = 'book';
                   3338: 	}
                   3339: 	#  Figure out some good defaults for the print out and set them:
                   3340: 	
                   3341: 	my %size;
                   3342: 	($size{'width'},
                   3343: 	 $size{'height'},
                   3344: 	 $size{'lmargin'})=
                   3345: 	     &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
                   3346: 	
                   3347: 	foreach my $dim ('width', 'height', 'lmargin') {
                   3348: 	    my ($value, $units) = split(/ /, $size{$dim});
1.470     foxr     3349: 	    	    
1.467     foxr     3350: 	    $helper->{VARS}->{"$var.".$dim}      = $value;
                   3351: 	    $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
                   3352: 	    
                   3353: 	}
                   3354: 	
                   3355: 
                   3356: 	# Transition to the next state
                   3357: 
                   3358: 	$helper->changeState($self->{NEXTSTATE});
                   3359:     }
1.144     bowersj2 3360:    
                   3361:     return 1;
                   3362: }
                   3363: 
                   3364: sub postprocess {
                   3365:     my $self = shift;
                   3366: 
                   3367:     my $var = $self->{'variable'};
                   3368:     my $helper = Apache::lonhelper->getHelper();
1.373     albertel 3369:     my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"}; 
                   3370:     my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"}; 
                   3371:     my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"}; 
                   3372:     $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"}; 
                   3373:     $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"}; 
                   3374:     $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"}; 
1.144     bowersj2 3375: 
                   3376:     my $error = '';
                   3377: 
                   3378:     # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed 
                   3379:     # by an optional period, followed by digits, ending the string
                   3380: 
1.464     albertel 3381:     if ($width !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3382:         $error .= "Invalid width; please type only a number.<br />\n";
                   3383:     }
1.464     albertel 3384:     if ($height !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3385:         $error .= "Invalid height; please type only a number.<br />\n";
                   3386:     }
1.464     albertel 3387:     if ($lmargin !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 3388:         $error .= "Invalid left margin; please type only a number.<br />\n";
1.470     foxr     3389:     } else {
                   3390: 	# Adjust for LaTeX 1.0 inch margin:
                   3391: 
                   3392: 	if ($env{"form.${var}.lmarginunit"} eq "in") {
                   3393: 	    $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
                   3394: 	} else {
                   3395: 	    $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
                   3396: 	}
1.144     bowersj2 3397:     }
                   3398: 
                   3399:     if (!$error) {
                   3400:         Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
                   3401:         return 1;
                   3402:     } else {
                   3403:         $self->{ERROR_MSG} = $error;
                   3404:         return 0;
                   3405:     }
                   3406: }
                   3407: 
                   3408: 
1.119     bowersj2 3409: 
1.1       www      3410: __END__
1.6       sakharuk 3411: 

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