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

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

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