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

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

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