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

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

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