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

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

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