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

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

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