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

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

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