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

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

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