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

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

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