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

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

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