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

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

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