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

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

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