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

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

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