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

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

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