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

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

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