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

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

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