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

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

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