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

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

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