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

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

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