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

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

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