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

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

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