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

1.562     foxr        1: #
1.389     foxr        2: # The LearningOnline Network
1.1       www         3: # Printout
                      4: #
1.586   ! raeburn     5: # $Id: lonprintout.pm,v 1.585 2010/09/15 16:37: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'};
                   2708: 	 if ($number_per_page eq '0' || $number_per_page eq 'all') {
                   2709: 	     $number_per_page=$num_todo;
                   2710: 	 }
                   2711: 	 my $flag_latex_header_remove = 'NO'; 
                   2712: 	 my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75');
1.295     albertel 2713: 	 my $count=0;
1.292     albertel 2714: 	 foreach my $code (sort(@allcodes)) {
1.295     albertel 2715: 	     my $file_num=int($count/$number_per_page);
1.381     albertel 2716: 	     if ($code_type eq 'number') { 
                   2717: 		 $moreenv{'CODE'}=$code;
                   2718: 	     } else {
                   2719: 		 $moreenv{'CODE'}=&num_to_letters($code);
                   2720: 	     }
1.375     foxr     2721: 	     my ($output,$fullname, $printed)=
1.288     albertel 2722: 		 &print_resources($r,$helper,'anonymous',$type,\%moreenv,
1.360     albertel 2723: 				  \@master_seq,$flag_latex_header_remove,
                   2724: 				  $LaTeXwidth);
1.375     foxr     2725: 	     $resources_printed .= ":";
1.295     albertel 2726: 	     $print_array[$file_num].=$output;
1.288     albertel 2727: 	     &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
                   2728: 				       &mt('last assignment').' '.$fullname);
                   2729: 	     $flag_latex_header_remove = 'YES';
1.295     albertel 2730: 	     $count++;
1.331     albertel 2731: 	     if (&Apache::loncommon::connection_aborted($r)) { last; }
1.288     albertel 2732: 	 }
                   2733: 	 &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
                   2734: 	 $result .= $print_array[0].'  \end{document}';
                   2735:      } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') {      
1.151     sakharuk 2736:     #prints selected problems from the subdirectory 
                   2737: 	$selectionmade = 6;
                   2738:         my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};
1.154     sakharuk 2739: 	@list_of_files=sort @list_of_files;
1.175     sakharuk 2740: 	my $flag_latex_header_remove = 'NO'; 
                   2741: 	my $rndseed=time;
1.230     albertel 2742: 	if ($helper->{'VARS'}->{'curseed'}) {
                   2743: 	    $rndseed=$helper->{'VARS'}->{'curseed'};
                   2744: 	}
1.151     sakharuk 2745: 	for (my $i=0;$i<=$#list_of_files;$i++) {
1.521     foxr     2746: 
                   2747: 	    &Apache::lonenc::reset_enc();
                   2748: 
1.152     sakharuk 2749: 	    my $urlp = $list_of_files[$i];
1.253     sakharuk 2750: 	    $urlp=~s|//|/|;
1.152     sakharuk 2751: 	    if ($urlp=~/\//) {
1.353     foxr     2752: 		$form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.175     sakharuk 2753: 		$form{'rndseed'}=$rndseed;
1.152     sakharuk 2754: 		if ($urlp =~ m|/home/([^/]+)/public_html|) {
                   2755: 		    $urlp =~ s|/home/([^/]*)/public_html|/~$1|;
                   2756: 		} else {
1.302     sakharuk 2757: 		    $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;
1.152     sakharuk 2758: 		}
1.375     foxr     2759: 		$resources_printed .= $urlp.':';
1.515     foxr     2760: 		my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.251     sakharuk 2761: 		if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1.253     sakharuk 2762: 		   ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     2763: 		    #  Don't permanently pervert %form:
                   2764: 		    my %answerform = %form;
                   2765: 		    $answerform{'grade_target'}='answer';
                   2766: 		    $answerform{'answer_output_mode'}='tex';
                   2767: 		    $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
                   2768: 		    $answerform{'rndseed'}=$rndseed;
1.375     foxr     2769: 		    $resources_printed .= $urlp.':';
1.515     foxr     2770: 		    my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.251     sakharuk 2771: 		    if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   2772: 			$texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
                   2773: 		    } else {
1.253     sakharuk 2774: 			$texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
                   2775: 			if ($helper->{'VARS'}->{'construction'} ne '1') {
                   2776: 			    $texversion.='\vskip 0 mm \noindent ';
                   2777: 			    $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
                   2778: 			} else {
                   2779: 			    $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
                   2780: 			    my $URLpath=$urlp;
                   2781: 			    $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
                   2782: 			    $texversion.=&path_to_problem ($URLpath,$LaTeXwidth);
                   2783: 			}
                   2784: 			$texversion.='\vskip 1 mm '.$answer.'\end{document}';
1.251     sakharuk 2785: 		    }
1.174     sakharuk 2786: 		}
1.515     foxr     2787:                 #this chunk is responsible for printing the path to problem
                   2788: 
1.253     sakharuk 2789: 		my $newurlp=$urlp;
                   2790: 		if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;}
                   2791: 		$newurlp=&path_to_problem($newurlp,$LaTeXwidth);
1.242     sakharuk 2792: 		$texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;
1.152     sakharuk 2793: 		if ($flag_latex_header_remove ne 'NO') {
                   2794: 		    $texversion = &latex_header_footer_remove($texversion);
                   2795: 		} else {
                   2796: 		    $texversion =~ s/\\end{document}//;
1.216     sakharuk 2797: 		}
                   2798: 		if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
                   2799: 		    $texversion=&IndexCreation($texversion,$urlp);
1.152     sakharuk 2800: 		}
1.219     sakharuk 2801: 		if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
                   2802: 		    $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
                   2803: 		    
                   2804: 		}
1.152     sakharuk 2805: 		$result .= $texversion;
                   2806: 	    }
                   2807: 	    $flag_latex_header_remove = 'YES';  
1.151     sakharuk 2808: 	}
1.175     sakharuk 2809: 	if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;}
1.152     sakharuk 2810: 	$result .= '\end{document}';      	
1.140     sakharuk 2811:     }
                   2812: #-------------------------------------------------------- corrections for the different page formats
1.499     foxr     2813: 
                   2814:     # Only post process if that has not been turned off e.g. by a raw latex resource.
                   2815: 
                   2816:     if ($do_postprocessing) {
                   2817: 	$result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade);
                   2818: 	$result = &latex_corrections($number_of_columns,$result,$selectionmade,
                   2819: 				     $helper->{'VARS'}->{'ANSWER_TYPE'});
                   2820: 	#if ($numberofcolumns == 1) {
1.451     albertel 2821: 	$result =~ s/\\textwidth\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /;
                   2822: 	$result =~ s/\\textheight\s*=?\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /;
                   2823: 	$result =~ s/\\evensidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
                   2824: 	$result =~ s/\\oddsidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
1.499     foxr     2825: 	#}
                   2826:     }
1.367     foxr     2827: 
1.515     foxr     2828:     # Set URLback if this is a construction space print so we can provide
                   2829:     # a link to the resource being edited.
                   2830:     #
1.274     sakharuk 2831: 
1.276     sakharuk 2832:     my $URLback=''; #link to original document
1.510     albertel 2833:     if ($helper->{'VARS'}->{'construction'} eq '1') {
1.276     sakharuk 2834: 	#prints resource from the construction space
                   2835: 	$URLback='/'.$helper->{'VARS'}->{'filename'};
1.279     albertel 2836: 	if ($URLback=~/([^?]+)/) {
                   2837: 	    $URLback=$1;
                   2838: 	    $URLback=~s|^/~|/priv/|;
                   2839: 	}
1.276     sakharuk 2840:     }
1.556     foxr     2841:     #
                   2842:     # Final adjustment of the font size:
                   2843:     #
                   2844: 
                   2845:     $result = set_font_size($result);
1.375     foxr     2846: 
1.525     www      2847: #-- writing .tex file in prtspool 
                   2848:     my $temp_file;
                   2849:     my $identifier = &Apache::loncommon::get_cgi_id();
                   2850:     my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex";
                   2851:     if (!($#print_array>0)) { 
                   2852:        unless ($temp_file = Apache::File->new('>'.$filename)) {
                   2853: 	  $r->log_error("Couldn't open $filename for output $!");
                   2854: 	  return SERVER_ERROR; 
                   2855:        }
                   2856:        print $temp_file $result;
                   2857:        my $begin=index($result,'\begin{document}',0);
                   2858:        my $inc=substr($result,0,$begin+16); 
1.515     foxr     2859:     } else {
1.525     www      2860:        my $begin=index($result,'\begin{document}',0);
                   2861:        my $inc=substr($result,0,$begin+16);
                   2862:        for (my $i=0;$i<=$#print_array;$i++) {
                   2863: 	  if ($i==0) {
                   2864: 	      $print_array[$i]=$result;
                   2865: 	  } else {
                   2866: 	      $print_array[$i].='\end{document}';
                   2867: 	      $print_array[$i] = 
                   2868: 		&latex_corrections($number_of_columns,$print_array[$i],
                   2869: 				   $selectionmade, 
                   2870: 				   $helper->{'VARS'}->{'ANSWER_TYPE'});
1.515     foxr     2871: 	    
1.525     www      2872: 	      my $anobegin=index($print_array[$i],'\setcounter{page}',0);
                   2873: 	      substr($print_array[$i],0,$anobegin)='';
                   2874: 	      $print_array[$i]=$inc.$print_array[$i];
                   2875: 	  }
                   2876: 	  my $temp_file;
                   2877: 	  my $newfilename=$filename;
                   2878: 	  my $num=$i+1;
                   2879: 	  $newfilename =~s/\.tex$//; 
                   2880: 	  $newfilename=sprintf("%s_%03d.tex",$newfilename, $num);
                   2881: 	  unless ($temp_file = Apache::File->new('>'.$newfilename)) {
                   2882: 	      $r->log_error("Couldn't open $newfilename for output $!");
                   2883: 	      return SERVER_ERROR; 
                   2884: 	  }
                   2885: 	  print $temp_file $print_array[$i];
                   2886:        }
                   2887:     }
                   2888:     my $student_names='';
                   2889:     if ($#print_array>0) {
                   2890:         for (my $i=0;$i<=$#print_array;$i++) {
                   2891:   	  $student_names.=$student_names[$i].'_ENDPERSON_';
1.515     foxr     2892: 	}
1.525     www      2893:     } else {
                   2894: 	if ($#student_names>-1) {
                   2895: 	   $student_names=$student_names[0].'_ENDPERSON_';
1.515     foxr     2896: 	} else {
1.525     www      2897:            my $fullname = &get_name($env{'user.name'},$env{'user.domain'});
                   2898: 	   $student_names=join(':',$env{'user.name'},$env{'user.domain'},
1.515     foxr     2899: 				    $env{'request.course.sec'},$fullname).
                   2900: 					'_ENDPERSON_'.'_END_';
                   2901: 	}
1.525     www      2902:      }
1.515     foxr     2903: 	
1.525     www      2904:      # logic for now is too complex to trace if this has been defined
                   2905:      #  yet.
                   2906:      my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   2907:      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   2908:      &Apache::lonnet::appenv({'cgi.'.$identifier.'.file'   => $filename,
1.515     foxr     2909: 				'cgi.'.$identifier.'.layout'  => $laystyle,
                   2910: 				'cgi.'.$identifier.'.numcol'  => $numberofcolumns,
                   2911: 				'cgi.'.$identifier.'.paper'  => $papersize,
                   2912: 				'cgi.'.$identifier.'.selection' => $selectionmade,
                   2913: 				'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
                   2914: 				'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
                   2915: 				'cgi.'.$identifier.'.role' => $perm{'pav'},
                   2916: 				'cgi.'.$identifier.'.numberoffiles' => $#print_array,
                   2917: 				'cgi.'.$identifier.'.studentnames' => $student_names,
1.520     raeburn  2918: 				'cgi.'.$identifier.'.backref' => $URLback,});
1.525     www      2919:     &Apache::lonnet::appenv({"cgi.$identifier.user"    => $env{'user.name'},
1.515     foxr     2920: 				"cgi.$identifier.domain"  => $env{'user.domain'},
                   2921: 				"cgi.$identifier.courseid" => $cnum, 
                   2922: 				"cgi.$identifier.coursedom" => $cdom, 
1.520     raeburn  2923: 				"cgi.$identifier.resources" => $resources_printed});
1.515     foxr     2924: 	
1.525     www      2925:     my $end_page = &Apache::loncommon::end_page();
1.529     raeburn  2926:     my $continue_text = &mt('Continue');
1.525     www      2927:     # If there's been an unrecoverable SSI error, report it to the user
                   2928:     if ($ssi_error) {
                   2929:         my $helpurl = &Apache::loncommon::top_nav_help('Helpdesk');
1.554     bisitz   2930:         $r->print('<br /><p class="LC_error">'.&mt('An unrecoverable network error occurred:').'</p><p>'.
1.526     www      2931:                   &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:').
                   2932:                   '<br />'.$ssi_last_error_resource.'<br />'.$ssi_last_error.
                   2933:                   '</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  2934:                   &mt('You may be able to reprint the individual resources for which this error occurred, as the issue may be temporary.').
1.525     www      2935:                   '<br />'.&mt('If the error persists, please contact the [_1] for assistance.',$helpurl).'</p><p>'.
                   2936:                   &mt('We apologize for the inconvenience.').'</p>'.
1.528     raeburn  2937:                   '<a href="/cgi-bin/printout.pl?'.$identifier.'">'.$continue_text.'</a>'.$end_page);
1.525     www      2938:     } else {
1.515     foxr     2939: 	$r->print(<<FINALEND);
1.317     albertel 2940: <br />
1.288     albertel 2941: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.528     raeburn  2942: <a href="/cgi-bin/printout.pl?$identifier">$continue_text</a>
1.431     albertel 2943: $end_page
1.140     sakharuk 2944: FINALEND
1.528     raeburn  2945:     }                                     # endif ssi errors.
1.140     sakharuk 2946: }
                   2947: 
1.288     albertel 2948: 
                   2949: sub get_CODE {
1.381     albertel 2950:     my ($all_codes,$num,$seed,$size,$type)=@_;
1.288     albertel 2951:     my $max='1'.'0'x$size;
                   2952:     my $newcode;
                   2953:     while(1) {
1.392     albertel 2954: 	$newcode=sprintf("%0".$size."d",int(rand($max)));
1.288     albertel 2955: 	if (!exists($$all_codes{$newcode})) {
                   2956: 	    $$all_codes{$newcode}=1;
1.381     albertel 2957: 	    if ($type eq 'number' ) {
                   2958: 		return $newcode;
                   2959: 	    } else {
                   2960: 		return &num_to_letters($newcode);
                   2961: 	    }
1.288     albertel 2962: 	}
                   2963:     }
                   2964: }
1.140     sakharuk 2965: 
1.284     albertel 2966: sub print_resources {
1.360     albertel 2967:     my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422     albertel 2968: 	$LaTeXwidth)=@_;
1.284     albertel 2969:     my $current_output = ''; 
1.375     foxr     2970:     my $printed = '';
1.284     albertel 2971:     my ($username,$userdomain,$usersection) = split /:/,$person;
                   2972:     my $fullname = &get_name($username,$userdomain);
1.492     foxr     2973:     my $namepostfix = "\\\\";	# Both anon and not anon should get the same vspace.
1.288     albertel 2974:     if ($person =~ 'anon') {
1.492     foxr     2975: 	$namepostfix .="Name: ";
1.288     albertel 2976: 	$fullname = "CODE - ".$moreenv->{'CODE'};
                   2977:     }
1.444     foxr     2978:     #  Fullname may have special latex characters that need \ prefixing:
                   2979:     #
                   2980: 
1.350     foxr     2981:     my $i           = 0;
1.284     albertel 2982:     #goes through all resources, checks if they are available for 
                   2983:     #current student, and produces output   
1.428     albertel 2984: 
                   2985:     &Apache::lonxml::clear_problem_counter();
1.364     albertel 2986:     my %page_breaks  = &get_page_breaks($helper);
1.476     albertel 2987:     my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440     foxr     2988:     #
1.441     foxr     2989:     #   end each student with a 
1.440     foxr     2990:     #   Special that allows the post processor to even out the page
                   2991:     #   counts later.  Nasty problem this... it would be really
                   2992:     #   nice to put the special in as a postscript comment
1.441     foxr     2993:     #   e.g. \special{ps:\ENDOFSTUDENTSTAMP}  unfortunately,
1.440     foxr     2994:     #   The special gets passed the \ and dvips puts it in the output file
1.441     foxr     2995:     #   so we will just rely on prntout.pl to strip  ENDOFSTUDENTSTAMP from the
                   2996:     #   postscript.  Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440     foxr     2997:     #
1.568     foxr     2998:     my $syllabus_first = 0;
1.284     albertel 2999:     foreach my $curresline (@{$master_seq})  {
1.351     foxr     3000: 	if (defined $page_breaks{$curresline}) {
1.350     foxr     3001: 	    if($i != 0) {
                   3002: 		$current_output.= "\\newpage\n";
                   3003: 	    }
                   3004: 	}
1.569     foxr     3005: 	$current_output .= &get_extra_vspaces($helper, $curresline);
1.350     foxr     3006: 	$i++;
1.511     foxr     3007: 
1.284     albertel 3008: 	if ( !($type eq 'problems' && 
1.582     raeburn  3009: 	       ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library|page)$/)) ) {
1.284     albertel 3010: 	    my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
                   3011: 	    if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414     albertel 3012: 		if ($res_url!~m|^ext/|
1.413     albertel 3013: 		    && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375     foxr     3014: 		    $printed .= $curresline.':';
1.428     albertel 3015: 		    &Apache::lonxml::remember_problem_counter();    
                   3016: 
1.526     www      3017: 		    my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.582     raeburn  3018:                     if ($res_url =~ /\.page$/) {
                   3019:                         if ($remove_latex_header eq 'NO') {
                   3020:                             if (!($rendered =~ /\\begin\{document\}/)) {
                   3021:                                 $rendered = &print_latex_header().$rendered;
                   3022:                             }
                   3023:                         }
                   3024:                         if ($remove_latex_header eq 'YES') {
                   3025:                             $rendered = &latex_header_footer_remove($rendered);
                   3026:                         } else {
                   3027:                             $rendered =~ s/\\end{document}\d*//;
                   3028:                         }
                   3029:                     }
1.305     sakharuk 3030: 		    if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
                   3031: 		       ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380     foxr     3032: 			#   Use a copy of the hash so we don't pervert it on future loop passes.
                   3033: 			my %answerenv = %{$moreenv};
                   3034: 			$answerenv{'answer_output_mode'}='tex';
                   3035: 			$answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428     albertel 3036: 			
                   3037: 			&Apache::lonxml::restore_problem_counter();
                   3038: 
1.380     foxr     3039: 			my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428     albertel 3040: 
1.305     sakharuk 3041: 			if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
                   3042: 			    $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
                   3043: 			} else {
1.423     foxr     3044: 
                   3045: 			    
                   3046: 			    my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.582     raeburn  3047:                             unless ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only') {
                   3048:                                 $header =~ s/\\begin{document}//;     #<<<<<
                   3049:                             }
1.477     albertel 3050: 			    my $title = &Apache::lonnet::gettitle($curresline);
                   3051: 			    $title = &Apache::lonxml::latex_special_symbols($title);
                   3052: 			    my $body   ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
                   3053: 			    $body     .=&path_to_problem($res_url,$LaTeXwidth);
1.423     foxr     3054: 			    $body     .='\vskip 1 mm '.$ansrendered;
                   3055: 			    $body     = &encapsulate_minipage($body);
                   3056: 			    $rendered = $header.$body;
1.305     sakharuk 3057: 			}
                   3058: 		    }
1.511     foxr     3059: 		    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   3060: 			my $url = &Apache::lonnet::clutter($res_url);
                   3061: 			my $annotation = &annotate($url);
                   3062: 			$rendered =~  s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
                   3063: 		    }
1.562     foxr     3064: 		    my $junk;
1.305     sakharuk 3065: 		    if ($remove_latex_header eq 'YES') {
                   3066: 			$rendered = &latex_header_footer_remove($rendered);
                   3067: 		    } else {
                   3068: 			$rendered =~ s/\\end{document}//;
                   3069: 		    }
                   3070: 		    $current_output .= $rendered;		    
1.456     raeburn  3071: 		} elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.568     foxr     3072: 		    if ($i == 1) {
                   3073: 			$syllabus_first = 1;
                   3074: 		    }
1.375     foxr     3075: 		    $printed .= $curresline.':';
1.528     raeburn  3076: 		    my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.511     foxr     3077: 		    if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
                   3078: 			my $url = &Apache::lonnet::clutter($res_url);
                   3079: 			my $annotation = &annotate($url);
                   3080: 			$annotation    =~ s/(\\end{document})/$annotation$1/;
                   3081: 		    }
1.305     sakharuk 3082: 		    if ($remove_latex_header eq 'YES') {
                   3083: 			$rendered = &latex_header_footer_remove($rendered);
1.284     albertel 3084: 		    } else {
1.305     sakharuk 3085: 			$rendered =~ s/\\end{document}//;
1.284     albertel 3086: 		    }
1.421     foxr     3087: 		    $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
1.552     foxr     3088: 		} elsif($res_url = ~/\.pdf$/) {
                   3089: 		    my $url = &Apache::lonnet::clutter($res_url);
                   3090: 		    my $rendered  = &include_pdf($url);
                   3091: 		    if ($remove_latex_header ne 'NO') {
                   3092: 			$rendered = &latex_header_footer_remove($rendered);
                   3093: 		    }
                   3094: 		    $current_output .= $rendered;
1.284     albertel 3095: 		} else {
1.414     albertel 3096: 		    my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305     sakharuk 3097: 		    if ($remove_latex_header ne 'NO') {
                   3098: 			$rendered = &latex_header_footer_remove($rendered);
                   3099: 		    } else {
                   3100: 			$rendered =~ s/\\end{document}//;
                   3101: 		    }
                   3102: 		    $current_output .= $rendered;
1.284     albertel 3103: 		}
                   3104: 	    }
                   3105: 	    $remove_latex_header = 'YES';
1.550     foxr     3106: 	} 
1.331     albertel 3107: 	if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284     albertel 3108:     }
1.552     foxr     3109: 
1.583     raeburn  3110:     if ($syllabus_first) {
                   3111:         $current_output =~ s/\\\\ Last updated:/Last updated:/
                   3112:     }
1.284     albertel 3113:     my $courseidinfo = &get_course();
                   3114:     my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476     albertel 3115:     my $header_line =
1.486     foxr     3116: 	&format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.537     foxr     3117: 			    $currentassignment, $courseidinfo, $fullname, $usersection);
1.476     albertel 3118:     my $header_start = ($columns_in_format == 1) ? '\lhead'
                   3119: 	                                         : '\fancyhead[LO]';
                   3120:     $header_line = $header_start.'{'.$header_line.'}';
1.583     raeburn  3121:     if ($current_output=~/\\documentclass/) {
1.476     albertel 3122: 	$current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.284     albertel 3123:     } else {
1.476     albertel 3124: 	my $blankpages = 
                   3125: 	    '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
                   3126: 	    
                   3127: 	$current_output = '\strut\vspace*{-6 mm}\\newline'.
                   3128: 	    &copyright_line().' \newpage '.$blankpages.$end_of_student.
                   3129: 	    '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
                   3130: 	    $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284     albertel 3131:     }
1.440     foxr     3132:     #
                   3133:     #  Close the student bracketing.
                   3134:     #
1.375     foxr     3135:     return ($current_output,$fullname, $printed);
1.284     albertel 3136: 
                   3137: }
1.140     sakharuk 3138: 
1.3       sakharuk 3139: sub handler {
                   3140: 
                   3141:     my $r = shift;
1.397     albertel 3142:     
                   3143:     &init_perm();
1.114     bowersj2 3144: 
1.416     foxr     3145: 
1.67      www      3146: 
1.397     albertel 3147:     my $helper = printHelper($r);
                   3148:     if (!ref($helper)) {
                   3149: 	return $helper;
1.60      sakharuk 3150:     }
1.177     sakharuk 3151:    
1.184     sakharuk 3152: 
1.454     foxr     3153:     %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353     foxr     3154:  
1.416     foxr     3155: 
1.350     foxr     3156: 
                   3157: 
1.367     foxr     3158:     #  If a figure conversion queue file exists for this user.domain
                   3159:     # we delete it since it can only be bad (if it were good, printout.pl
                   3160:     # would have deleted it the last time around.
                   3161: 
1.373     albertel 3162:     my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367     foxr     3163:     if(-e $conversion_queuefile) {
                   3164: 	unlink $conversion_queuefile;
                   3165:     }
1.515     foxr     3166:     
                   3167: 
1.184     sakharuk 3168:     &output_data($r,$helper,\%parmhash);
1.2       sakharuk 3169:     return OK;
1.60      sakharuk 3170: } 
1.2       sakharuk 3171: 
1.131     bowersj2 3172: use Apache::lonhelper;
1.130     sakharuk 3173: 
1.223     bowersj2 3174: sub addMessage {
                   3175:     my $text = shift;
                   3176:     my $paramHash = Apache::lonhelper::getParamHash();
                   3177:     $paramHash->{MESSAGE_TEXT} = $text;
                   3178:     Apache::lonhelper::message->new();
                   3179: }
                   3180: 
1.416     foxr     3181: 
1.238     bowersj2 3182: 
1.397     albertel 3183: sub init_perm {
                   3184:     undef(%perm);
                   3185:     $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
                   3186:     if (!$perm{'pav'}) {
                   3187: 	$perm{'pav'}=&Apache::lonnet::allowed('pav',
                   3188: 		  $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   3189:     }
1.465     albertel 3190:     $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397     albertel 3191:     if (!$perm{'pfo'}) {
                   3192: 	$perm{'pfo'}=&Apache::lonnet::allowed('pfo',
                   3193: 		  $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   3194:     }
1.585     raeburn  3195:     $perm{'vgr'}=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});
                   3196:     if (!$perm{'vgr'}) {
                   3197:         $perm{'vgr'}=&Apache::lonnet::allowed('vgr',
                   3198:                    $env{'request.course.id'}.'/'.$env{'request.course.sec'});
                   3199:     }
1.397     albertel 3200: }
                   3201: 
1.507     albertel 3202: sub get_randomly_ordered_warning {
                   3203:     my ($helper,$map) = @_;
                   3204: 
                   3205:     my $message;
                   3206: 
                   3207:     my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
                   3208:     my $navmap = Apache::lonnavmaps::navmap->new();
1.547     raeburn  3209:     if (defined($navmap)) {
                   3210:         my $res = $navmap->getResourceByUrl($map);
                   3211:         if ($res) {
                   3212: 	    my $func = 
                   3213: 	        sub { return ($_[0]->is_map() && $_[0]->randomorder); };
                   3214: 	    my @matches = $navmap->retrieveResources($res, $func,1,1,1);
                   3215: 	    if (@matches) {
                   3216: 	        $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.";
                   3217: 	    }
                   3218:         }
                   3219:         if ($message) {
                   3220: 	    return '<message type="warning">'.$message.'</message>';
                   3221:         }
                   3222:     } else {
                   3223:         $message = "Retrieval of information about ordering of resources failed."; 
                   3224:         return '<message type="warning">'.$message.'</message>';
1.507     albertel 3225:     }
                   3226:     return;
                   3227: }
                   3228: 
1.131     bowersj2 3229: sub printHelper {
1.115     bowersj2 3230:     my $r = shift;
                   3231: 
                   3232:     if ($r->header_only) {
1.373     albertel 3233:         if ($env{'browser.mathml'}) {
1.241     www      3234:             &Apache::loncommon::content_type($r,'text/xml');
1.131     bowersj2 3235:         } else {
1.241     www      3236:             &Apache::loncommon::content_type($r,'text/html');
1.131     bowersj2 3237:         }
                   3238:         $r->send_http_header;
                   3239:         return OK;
1.115     bowersj2 3240:     }
                   3241: 
1.131     bowersj2 3242:     # Send header, nocache
1.373     albertel 3243:     if ($env{'browser.mathml'}) {
1.241     www      3244:         &Apache::loncommon::content_type($r,'text/xml');
1.115     bowersj2 3245:     } else {
1.241     www      3246:         &Apache::loncommon::content_type($r,'text/html');
1.115     bowersj2 3247:     }
                   3248:     &Apache::loncommon::no_cache($r);
                   3249:     $r->send_http_header;
                   3250:     $r->rflush();
                   3251: 
1.131     bowersj2 3252:     # Unfortunately, this helper is so complicated we have to
                   3253:     # write it by hand
                   3254: 
                   3255:     Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
                   3256:     
1.176     bowersj2 3257:     my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146     bowersj2 3258:     $helper->declareVar('symb');
1.156     bowersj2 3259:     $helper->declareVar('postdata');    
1.290     sakharuk 3260:     $helper->declareVar('curseed'); 
                   3261:     $helper->declareVar('probstatus');   
1.156     bowersj2 3262:     $helper->declareVar('filename');
                   3263:     $helper->declareVar('construction');
1.178     sakharuk 3264:     $helper->declareVar('assignment');
1.262     sakharuk 3265:     $helper->declareVar('style_file');
1.340     foxr     3266:     $helper->declareVar('student_sort');
1.363     foxr     3267:     $helper->declareVar('FINISHPAGE');
1.366     foxr     3268:     $helper->declareVar('PRINT_TYPE');
1.372     foxr     3269:     $helper->declareVar("showallfoils");
1.483     foxr     3270:     $helper->declareVar("STUDENTS");
1.569     foxr     3271:     $helper->declareVar("EXTRASPACE");
1.518     foxr     3272: 
                   3273:    
                   3274: 
                   3275: 
1.569     foxr     3276:     #  The page breaks and extra spaces
                   3277:     #  can get loaded initially from the course environment:
1.394     foxr     3278:     # But we only do this in the initial state so that they are allowed to change.
                   3279:     #
1.366     foxr     3280: 
1.363     foxr     3281:     
                   3282:     &Apache::loncommon::restore_course_settings('print',
1.366     foxr     3283: 						{'pagebreaks'  => 'scalar',
1.569     foxr     3284: 						 'extraspace'  => 'scalar',
1.570     foxr     3285: 						 'extraspace_units' => 'scalar',
1.366     foxr     3286: 					         'lastprinttype' => 'scalar'});
                   3287:     
1.483     foxr     3288:     # This will persistently load in the data we want from the
                   3289:     # very first screen.
1.394     foxr     3290:     
                   3291:     if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
                   3292: 	if (!defined ($env{"form.CURRENT_STATE"})) {
                   3293: 	    
                   3294: 	    $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
1.569     foxr     3295: 	    $helper->{VARS}->{EXTRASPACE} = $env{'form.extraspace'};
1.570     foxr     3296: 	    $helper->{VARS}->{EXTRASPACE_UNITS} = $env{'form.extraspace_units'};
1.394     foxr     3297: 	} else {
                   3298: 	    my $state = $env{"form.CURRENT_STATE"};
                   3299: 	    if ($state eq "START") {
                   3300: 		$helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
1.569     foxr     3301: 		$helper->{VARS}->{EXTRASPACE} = $env{'form.extraspace'};
1.570     foxr     3302: 		$helper->{VARS}->{EXTRASPACE_UNITS} = $env{'form.extraspace_units'};
                   3303: 		
1.394     foxr     3304: 	    }
                   3305: 	}
                   3306: 	
1.366     foxr     3307:     }
1.481     albertel 3308: 
1.156     bowersj2 3309:     # Detect whether we're coming from construction space
1.373     albertel 3310:     if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235     bowersj2 3311:         $helper->{VARS}->{'filename'} = "~$1/$2";
1.156     bowersj2 3312:         $helper->{VARS}->{'construction'} = 1;
1.481     albertel 3313:     } else {
1.373     albertel 3314:         if ($env{'form.postdata'}) {
                   3315:             $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482     albertel 3316: 	    if ( $helper->{VARS}->{'symb'} eq '') {
                   3317: 		$helper->{VARS}->{'postdata'} = $env{'form.postdata'};
                   3318: 	    }
1.156     bowersj2 3319:         }
1.373     albertel 3320:         if ($env{'form.symb'}) {
                   3321:             $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156     bowersj2 3322:         }
1.373     albertel 3323:         if ($env{'form.url'}) {
1.156     bowersj2 3324:             $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
                   3325:         }
1.416     foxr     3326: 
1.157     bowersj2 3327:     }
1.481     albertel 3328: 
1.373     albertel 3329:     if ($env{'form.symb'}) {
                   3330:         $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146     bowersj2 3331:     }
1.373     albertel 3332:     if ($env{'form.url'}) {
1.140     sakharuk 3333:         $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153     sakharuk 3334: 
1.140     sakharuk 3335:     }
1.343     albertel 3336:     $helper->{VARS}->{'symb'}=
                   3337: 	&Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335     albertel 3338:     my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178     sakharuk 3339:     if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481     albertel 3340: 
1.156     bowersj2 3341:     
1.146     bowersj2 3342:     # Extract map
                   3343:     my $symb = $helper->{VARS}->{'symb'};
1.156     bowersj2 3344:     my ($map, $id, $url);
                   3345:     my $subdir;
1.483     foxr     3346:     my $is_published=0;		# True when printing from resource space.
1.156     bowersj2 3347: 
                   3348:     # Get the resource name from construction space
                   3349:     if ($helper->{VARS}->{'construction'}) {
                   3350:         $resourceTitle = substr($helper->{VARS}->{'filename'}, 
                   3351:                                 rindex($helper->{VARS}->{'filename'}, '/')+1);
                   3352:         $subdir = substr($helper->{VARS}->{'filename'},
                   3353:                          0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481     albertel 3354:     } else {
1.562     foxr     3355: 	# From course space:
                   3356: 
1.482     albertel 3357: 	if ($symb ne '') {
                   3358: 	    ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
                   3359: 	    $helper->{VARS}->{'postdata'} = 
                   3360: 		&Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
                   3361: 	} else {
                   3362: 	    $url = $helper->{VARS}->{'postdata'};
1.483     foxr     3363: 	    $is_published=1;	# From resource space.
1.482     albertel 3364: 	}
                   3365: 	$url = &Apache::lonnet::clutter($url);
1.156     bowersj2 3366:         if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238     bowersj2 3367:             my $postdata = $helper->{VARS}->{'postdata'};
                   3368:             $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156     bowersj2 3369:         }
                   3370:         $subdir = &Apache::lonnet::filelocation("", $url);
1.128     bowersj2 3371:     }
1.373     albertel 3372:     if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
                   3373: 	$helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230     albertel 3374:     }
1.373     albertel 3375:     if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
1.512     foxr     3376: 	$helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
1.290     sakharuk 3377:     }
1.115     bowersj2 3378: 
1.192     bowersj2 3379:     my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
                   3380: 
1.481     albertel 3381:     Apache::lonhelper::registerHelperTags();
1.119     bowersj2 3382: 
1.131     bowersj2 3383:     # "Delete everything after the last slash."
1.119     bowersj2 3384:     $subdir =~ s|/[^/]+$||;
                   3385: 
1.131     bowersj2 3386:     # What can be printed is a very dynamic decision based on
                   3387:     # lots of factors. So we need to dynamically build this list.
                   3388:     # To prevent security leaks, states are only added to the wizard
                   3389:     # if they can be reached, which ensures manipulating the form input
                   3390:     # won't allow anyone to reach states they shouldn't have permission
                   3391:     # to reach.
                   3392: 
                   3393:     # printChoices is tracking the kind of printing the user can
                   3394:     # do, and will be used in a choices construction later.
                   3395:     # In the meantime we will be adding states and elements to
                   3396:     # the helper by hand.
                   3397:     my $printChoices = [];
                   3398:     my $paramHash;
1.130     sakharuk 3399: 
1.240     albertel 3400:     if ($resourceTitle) {
1.458     www      3401:         push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156     bowersj2 3402:     }
                   3403: 
1.238     bowersj2 3404:     # Useful filter strings
1.540     raeburn  3405:     my $isProblem = '($res->is_problem()||$res->contains_problem||$res->is_practice()) ';
1.238     bowersj2 3406:     $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.541     raeburn  3407:     my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice()';
1.287     albertel 3408:     my $isNotMap = '!$res->is_sequence()';
1.238     bowersj2 3409:     $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
                   3410:     my $isMap = '$res->is_map()';
1.342     albertel 3411:     my $symbFilter = '$res->shown_symb()';
                   3412:     my $urlValue = '$res->link()';
1.238     bowersj2 3413: 
                   3414:     $helper->declareVar('SEQUENCE');
                   3415: 
1.465     albertel 3416:     # If we're in a sequence...
1.416     foxr     3417: 
1.465     albertel 3418:     my $start_new_option;
                   3419:     if ($perm{'pav'}) {
                   3420: 	$start_new_option = 
                   3421: 	    "<option text='".&mt('Start new page<br />before selected').
1.569     foxr     3422: 	    "' variable='FINISHPAGE' />".
1.570     foxr     3423: 	    "<option text='".&mt('Extra space<br />before selected').
1.569     foxr     3424: 	    "' variable='EXTRASPACE' type='text' />" .
                   3425: 	    "<option " .
1.570     foxr     3426: 	    "' variable='POSSIBLE_RESOURCES' type='hidden' />".
                   3427: 	    "<option text='".&mt('Space units<br />check for mm').
                   3428: 	    "' variable='EXTRASPACE_UNITS' type='checkbox' />"
                   3429: 	    ;
                   3430: 	    
1.569     foxr     3431: 
1.465     albertel 3432:     }
1.238     bowersj2 3433: 
1.562     foxr     3434:     # If not construction space user can print the components of a page:
                   3435: 
                   3436:     my $page_ispage;
                   3437:     my $page_title;
                   3438:     if (!$helper->{VARS}->{'construction'}) {
                   3439: 	my $varspostdata = $helper->{VARS}->{'postdata'};
                   3440: 	my $varsassignment = $helper->{VARS}->{'assignment'};
                   3441: 	my $page_navmap         = Apache::lonnavmaps::navmap->new();
1.563     foxr     3442: 	if (defined($page_navmap)) {
                   3443: 	    my @page_resources      = $page_navmap->retrieveResources($url);
                   3444: 	    if(defined($page_resources[0])) {
                   3445: 		$page_ispage       = $page_resources[0]->is_page();
                   3446: 		$page_title     = $page_resources[0]->title();
                   3447: 		my $resourcesymb   = $page_resources[0]->symb();
                   3448: 		my ($pagemap, $pageid, $pageurl) = &Apache::lonnet::decode_symb($symb);
                   3449: 		if ($page_ispage) {
                   3450: 		    push @{$printChoices}, 
                   3451: 		    [&mt('Selected [_1]Problems[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'), 
                   3452: 		     'map_problems_in_page', 
                   3453: 		     'CHOOSE_PROBLEMS_PAGE'];
                   3454: 		    push @{$printChoices}, 
                   3455: 		    [&mt('Selected [_1]Resources[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'), 
                   3456: 		     'map_resources_in_page', 
                   3457: 		     'CHOOSE_RESOURCES_PAGE'];
                   3458: 		}
1.562     foxr     3459:         my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS_PAGE',
                   3460: 							'Select Problem(s) to print',
                   3461: 							"multichoice='1' toponly='1' addstatus='1' closeallpages='1'",
                   3462: 							'RESOURCES',
                   3463: 							'PAGESIZE',
                   3464: 							$url,
                   3465: 							$isProblem, '',  $symbFilter,
                   3466: 							$start_new_option);
                   3467: 
                   3468: 
                   3469:       $helperFragment .= &generate_resource_chooser('CHOOSE_RESOURCES_PAGE',
                   3470: 						    'Select Resource(s) to print',
                   3471: 						    'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
                   3472: 						    'RESOURCES',
                   3473: 						    'PAGESIZE',
                   3474: 						    $url,
                   3475: 						    $isNotMap, '', $symbFilter,
                   3476: 						    $start_new_option);
                   3477: 
                   3478: 						    
                   3479: 
                   3480: 
                   3481: 
                   3482: 	&Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
                   3483: 	
1.563     foxr     3484: 	    }
                   3485: 	}
1.562     foxr     3486:     }
                   3487: 
                   3488:     if (($helper->{'VAR'}->{'construction'} ne '1' ) &&
1.243     bowersj2 3489: 	$helper->{VARS}->{'postdata'} &&
                   3490: 	$helper->{VARS}->{'assignment'}) {
1.131     bowersj2 3491:         # Allow problems from sequence
1.562     foxr     3492:         push @{$printChoices}, 
                   3493: 	    [&mt('Selected [_1]Problems[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'), 
                   3494: 	     'map_problems', 
                   3495: 	     'CHOOSE_PROBLEMS'];
1.131     bowersj2 3496:         # Allow all resources from sequence
1.562     foxr     3497:         push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'), 
                   3498: 				'map_problems_pages', 
                   3499: 				'CHOOSE_PROBLEMS_HTML'];
                   3500:         my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS',
                   3501: 							'Select Problem(s) to print',
                   3502: 							'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
                   3503: 							'RESOURCES',
                   3504: 							'PAGESIZE',
                   3505: 							$map,
                   3506: 							$isProblem, '',
                   3507: 							$symbFilter,
                   3508: 							$start_new_option);
                   3509: 	$helperFragment .= &generate_resource_chooser('CHOOSE_PROBLEMS_HTML',
                   3510: 						      'Select Resource(s) to print',
                   3511: 						      	'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
                   3512: 						      'RESOURCES',
                   3513: 						      'PAGESIZE',
                   3514: 						      $map,
                   3515: 						      $isNotMap, '',
                   3516: 						      $symbFilter,
                   3517: 						      $start_new_option);
1.121     bowersj2 3518: 
1.326     sakharuk 3519: 	&Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121     bowersj2 3520:     }
                   3521: 
1.546     bisitz   3522:     # If the user has pfo (print for others) allow them to print all 
                   3523:     # problems and resources  in the entire course, optionally for selected students
1.562     foxr     3524:     my $post_data = $helper->{VARS}->{'postdata'};
1.483     foxr     3525:     if ($perm{'pfo'} &&  !$is_published  &&
1.562     foxr     3526:         ($post_data=~/\/res\// || $post_data =~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) { 
1.481     albertel 3527: 
1.509     albertel 3528:         push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
                   3529: 	push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.536     foxr     3530: 	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     3531: my $suffixXml = <<ALL_PROBLEMS;
1.536     foxr     3532:   <state name="STUDENTS1" title="Select People">
                   3533:       <message><b>Select sorting order of printout</b> </message>
                   3534:     <choices variable='student_sort'>
                   3535:       <choice computer='0'>Sort by section then student</choice>
                   3536:       <choice computer='1'>Sort by students across sections.</choice>
                   3537:     </choices>
                   3538:       <message><br /><hr /><br /> </message>
                   3539:       <student multichoice='1' variable="STUDENTS" nextstate="PRINT_FORMATTING" coursepersonnel="1"/>
                   3540:   </state>
1.284     albertel 3541: ALL_PROBLEMS
1.562     foxr     3542:          &Apache::lonxml::xmlparse($r, 'helper', 
                   3543: 				   &generate_resource_chooser('ALL_PROBLEMS',
                   3544: 							      'SelectProblem(s) to print',
                   3545: 							      'multichoice="1" suppressEmptySequences="0" addstatus="1" closeallpages="1"',
                   3546: 							      'RESOURCES',
                   3547: 							      'PAGESIZE',
                   3548: 							      '',
                   3549: 							      $isProblemOrMap, $isNotMap,
                   3550: 							      $symbFilter,
                   3551: 							      $start_new_option) .
                   3552: 				   &generate_resource_chooser('ALL_RESOURCES',
                   3553: 							      'Select Resource(s) to print',
                   3554: 							      " toponly='0' multichoice='1' suppressEmptySequences='0' addstatus='1' closeallpages='1'",
                   3555: 							      'RESOURCES',
                   3556: 							      'PAGESIZE',
                   3557: 							      '',
                   3558: 							      $isNotMap,'',$symbFilter,
                   3559: 							      $start_new_option) .
                   3560: 				   &generate_resource_chooser('ALL_PROBLEMS_STUDENTS',
                   3561: 							      'Select Problem(s) to print',
                   3562: 							      'toponly="0" multichoice="1" suppressEmptySequences="0" addstatus="1" closeallpages="1"',
                   3563: 							      'RESOURCES',
                   3564: 							      'STUDENTS1',
                   3565: 							      '',
                   3566: 							      $isProblemOrMap,'' , $symbFilter,
                   3567: 							      $start_new_option) .
                   3568: 				     $suffixXml
                   3569: 				   );
1.132     bowersj2 3570: 
1.284     albertel 3571: 	if ($helper->{VARS}->{'assignment'}) {
1.562     foxr     3572: 
                   3573: 	    # If we were looking at a page, allow a selection of problems from the page
                   3574: 	    # either for selected students or for coded assignments.
                   3575: 
                   3576: 	    if ($page_ispage) {
                   3577: 		push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from page [_3] for [_4]selected people[_5]',
                   3578: 					    '<b>', '</b>', '<b><i>'.$page_title.'</i></b>', '<b>', '</b>'),
                   3579: 					'problems_for_students_from_page', 'CHOOSE_TGT_STUDENTS_PAGE'];
                   3580: 		push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from page [_3] for [_4]CODEd assignments[_5]',
                   3581: 					    '<b>', '</b>', '<b><i>'.$page_title.'</i></b>', '<b>', '</b>'),
                   3582: 					'problems_for_anon_page', 'CHOOSE_ANON1_PAGE'];
                   3583: 	    }
                   3584: 	    push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]selected people[_5]',
                   3585: 					'<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 
                   3586: 				    'problems_for_students', 'CHOOSE_STUDENTS'];
                   3587: 	    push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]CODEd assignments[_5]',
                   3588: 					'<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'), 
                   3589: 				    'problems_for_anon', 'CHOOSE_ANON1'];
1.284     albertel 3590: 	}
1.424     foxr     3591: 
1.507     albertel 3592: 	my $randomly_ordered_warning = 
                   3593: 	    &get_randomly_ordered_warning($helper,$map);
                   3594: 
1.424     foxr     3595: 	# resource_selector will hold a few states that:
                   3596: 	#   - Allow resources to be selected for printing.
                   3597: 	#   - Determine pagination between assignments.
                   3598: 	#   - Determine how many assignments should be bundled into a single PDF.
                   3599:         # TODO:
                   3600: 	#    Probably good to do things like separate this up into several vars, each
                   3601: 	#    with one state, and use REGEXPs at inclusion time to set state names
                   3602: 	#    and next states for better mix and match capability
                   3603: 	#
1.562     foxr     3604: 	my $resource_selector= &generate_resource_chooser('SELECT_PROBLEMS',
                   3605: 							  'Select resources to print',
                   3606: 							  'multichoice="1" addstatus="1" closeallpages="1"',
                   3607: 							  'RESOURCES', 
                   3608: 							  'PRINT_FORMATTING',
1.571     droeschl 3609: 							  $map,
1.562     foxr     3610: 							  $isProblem, '', $symbFilter,
                   3611: 							  $start_new_option);
1.586   ! raeburn  3612:         my $secpdfoption;
        !          3613:         unless (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon')     ||
        !          3614:                 ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon_page') ||
        !          3615:                 ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon')  ) {
        !          3616:             $secpdfoption =  '<choice computer="sections">Each PDF contains exactly one section</choice>';
        !          3617:         }
        !          3618: 	$resource_selector .=  &generate_format_selector($helper,
        !          3619:                                                          'How should results be printed?').
        !          3620:                                &generate_resource_chooser('CHOOSE_STUDENTS_PAGE',
1.562     foxr     3621: 							'Select Problem(s) to print',
                   3622: 							"multichoice='1' addstatus='1' closeallpages ='1'",
                   3623: 							'RESOURCES',
                   3624: 							'PRINT_FORMATTING',
                   3625: 							$url,
                   3626: 							$isProblem, '',  $symbFilter,
                   3627: 							$start_new_option);
                   3628: 
                   3629: 
                   3630: # Generate student choosers.
                   3631: 
                   3632: 
1.284     albertel 3633: 
1.562     foxr     3634:         &Apache::lonxml::xmlparse($r, 'helper',
                   3635: 				  &generate_student_chooser('CHOOSE_TGT_STUDENTS_PAGE',
                   3636: 							    'student_sort',
                   3637: 							    'STUDENTS',
                   3638: 							    'CHOOSE_STUDENTS_PAGE'));
                   3639: 	&Apache::lonxml::xmlparse($r, 'helper', 
                   3640: 				  &generate_student_chooser('CHOOSE_STUDENTS',
                   3641: 							    'student_sort',
                   3642: 							    'STUDENTS',
                   3643: 							    'SELECT_PROBLEMS'));
                   3644: 	&Apache::lonxml::xmlparse($r, 'helper', $resource_selector);
1.292     albertel 3645: 
1.373     albertel 3646: 	my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   3647: 	my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292     albertel 3648:         my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
                   3649: 	my $namechoice='<choice></choice>';
1.337     albertel 3650: 	foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294     albertel 3651: 	    if ($name =~ /^error: 2 /) { next; }
1.381     albertel 3652: 	    if ($name =~ /^type\0/) { next; }
1.292     albertel 3653: 	    $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
                   3654: 	}
1.389     foxr     3655: 
                   3656: 
                   3657: 	my %code_values;
1.405     albertel 3658: 	my %codes_to_print;
1.411     albertel 3659: 	foreach my $key (@names) {
1.389     foxr     3660: 	    %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405     albertel 3661: 	    foreach my $key (keys(%code_values)) {
                   3662: 		$codes_to_print{$key} = 1;
1.388     foxr     3663: 	    }
                   3664: 	}
1.389     foxr     3665: 
1.452     albertel 3666: 	my $code_selection;
1.405     albertel 3667: 	foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389     foxr     3668: 	    my $choice  = $code;
                   3669: 	    if ($code =~ /^[A-Z]+$/) { # Alpha code
                   3670: 		$choice = &letters_to_num($code);
                   3671: 	    }
1.432     albertel 3672: 	    push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388     foxr     3673: 	}
1.436     albertel 3674: 	if (%codes_to_print) {
                   3675: 	    $code_selection .='   
1.472     albertel 3676: 	    <message><b>Choose single CODE from list:</b></message>
1.448     albertel 3677: 		<message></td><td></message>
1.452     albertel 3678: 		<dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
                   3679:                   <choice></choice>
1.448     albertel 3680:                   <exec>
                   3681:                      push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
                   3682:                   </exec>
1.452     albertel 3683: 		</dropdown>
1.468     foxr     3684: 	    <message></td></tr><tr><td></message>
1.436     albertel 3685:             '.$/;
1.448     albertel 3686: 
1.436     albertel 3687: 	}
1.432     albertel 3688: 
1.542     raeburn  3689:         my @lines = &Apache::grades::get_scantronformat_file();
1.381     albertel 3690: 	my $codechoice='';
1.542     raeburn  3691: 	foreach my $line (@lines) {
1.381     albertel 3692: 	    my ($name,$description,$code_type,$code_length)=
                   3693: 		(split(/:/,$line))[0,1,2,4];
                   3694: 	    if ($code_length > 0 && 
                   3695: 		$code_type =~/^(letter|number|-1)/) {
                   3696: 		$codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
                   3697: 	    }
                   3698: 	}
                   3699: 	if ($codechoice eq '') {
                   3700: 	    $codechoice='<choice computer="default">Default</choice>';
                   3701: 	}
1.562     foxr     3702: 	my $anon1 = &generate_code_selector($helper, 
                   3703: 					    'CHOOSE_ANON1',
                   3704: 					    'SELECT_PROBLEMS',
                   3705: 					    $codechoice,
                   3706: 					    $code_selection,
                   3707: 					    $namechoice) . $resource_selector;
                   3708: 					    
                   3709: 					    
                   3710:         &Apache::lonxml::xmlparse($r, 'helper',$anon1);
                   3711: 
                   3712: 	my $anon_page = &generate_code_selector($helper,
                   3713: 						'CHOOSE_ANON1_PAGE',
                   3714: 						'SELECT_PROBLEMS_PAGE',
                   3715: 						$codechoice,
                   3716: 						$code_selection,
                   3717: 						$namechoice) .
                   3718: 			&generate_resource_chooser('SELECT_PROBLEMS_PAGE',
                   3719: 						   'Select Problem(s) to print',
                   3720: 						   "multichoice='1' addstatus='1' closeallpages ='1'",
                   3721: 						   'RESOURCES',
                   3722: 						   'PRINT_FORMATTING',
                   3723: 						   $url,
                   3724: 						   $isProblem, '',  $symbFilter,
                   3725: 						   $start_new_option);
                   3726: 	&Apache::lonxml::xmlparse($r, 'helper', $anon_page);
1.254     sakharuk 3727: 
1.272     sakharuk 3728: 
1.254     sakharuk 3729: 	if ($helper->{VARS}->{'assignment'}) {
1.546     bisitz   3730: 	    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'];
                   3731: 	    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 3732: 	}
1.284     albertel 3733: 	    
                   3734: 
                   3735: 	$resource_selector=<<RESOURCE_SELECTOR;
1.424     foxr     3736:     <state name="SELECT_RESOURCES" title="Select Resources">
1.507     albertel 3737:     $randomly_ordered_warning
1.424     foxr     3738:     <nextstate>PRINT_FORMATTING</nextstate>
1.254     sakharuk 3739:     <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287     albertel 3740:     <resource variable="RESOURCES" multichoice="1" addstatus="1" 
                   3741:               closeallpages="1">
1.254     sakharuk 3742:       <filterfunc>return $isNotMap;</filterfunc>
                   3743:       <mapurl>$map</mapurl>
                   3744:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 3745:       $start_new_option
1.254     sakharuk 3746:       </resource>
1.424     foxr     3747:     </state>
1.284     albertel 3748: RESOURCE_SELECTOR
                   3749: 
1.586   ! raeburn  3750:         my $nextstate = '<nextstate>NUMBER_PER_PDF</nextstate>'; 
        !          3751:         $resource_selector .= &generate_format_selector($helper,
        !          3752:                                                         'Format of the print job',
        !          3753:                                                         $nextstate);
1.284     albertel 3754: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
                   3755:   <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340     foxr     3756:     <choices variable='student_sort'>
                   3757:       <choice computer='0'>Sort by section then student</choice>
                   3758:       <choice computer='1'>Sort by students across sections.</choice>
                   3759:     </choices>
1.437     foxr     3760:     <message><br /><hr /><br /></message>
1.426     foxr     3761:     <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340     foxr     3762: 
1.424     foxr     3763:     </state>
1.284     albertel 3764:     $resource_selector
1.254     sakharuk 3765: CHOOSE_STUDENTS1
                   3766: 
1.284     albertel 3767: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472     albertel 3768:   <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424     foxr     3769:     <nextstate>SELECT_RESOURCES</nextstate>
1.472     albertel 3770:     <message><h4>Fill out one of the forms below</h4></message>
                   3771:     <message><br /><hr /> <br /></message>
                   3772:     <message><h3>Generate new CODEd Assignments</h3></message>
                   3773:     <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.579     foxr     3774:     <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5"  noproceed="1">
1.362     albertel 3775:        <validator>
                   3776: 	if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386     foxr     3777: 	    !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                &&
1.388     foxr     3778: 	    !\$helper->{'VARS'}{'SINGLE_CODE'}                   &&
                   3779: 	    !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362     albertel 3780: 	    return "You need to specify the number of assignments to print";
                   3781: 	}
1.578     foxr     3782:         if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) >= 1)  &&
                   3783:              (\$helper->{'VARS'}{'SINGLE_CODE'} ne '') ) {
                   3784:             return 'Specifying number of codes to print and a specific code is not compatible';
                   3785:         }
1.362     albertel 3786: 	return undef;
                   3787:        </validator>
                   3788:     </string>
                   3789:     <message></td></tr><tr><td></message>
1.501     albertel 3790:     <message><b>Names to save the CODEs under for later:</b></message>
1.412     albertel 3791:     <message></td><td></message>
                   3792:     <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
                   3793:     <message></td></tr><tr><td></message>
                   3794:     <message><b>Bubble sheet type:</b></message>
                   3795:     <message></td><td></message>
                   3796:     <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
                   3797:     $codechoice
                   3798:     </dropdown>
1.472     albertel 3799:     <message></td></tr><tr><td></table></message>
                   3800:     <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
                   3801:     <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412     albertel 3802:     <string variable="SINGLE_CODE" size="10">
1.386     foxr     3803:         <validator>
                   3804: 	   if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}           &&
1.388     foxr     3805: 	      !\$helper->{'VARS'}{'REUSE_OLD_CODES'}                 &&
                   3806: 	      !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386     foxr     3807: 	      return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
                   3808: 						      \$helper->{'VARS'}{'CODE_OPTION'});
1.577     foxr     3809: 	  } elsif (\$helper->{'VARS'}{'SINGLE_CODE'} ne ''){
1.578     foxr     3810: 	      return 'Specifying a code name is incompatible specifying number of codes.';
1.386     foxr     3811: 	   } else {
                   3812: 	       return undef;	# Other forces control us.
                   3813: 	   }
                   3814:         </validator>
                   3815:     </string>
1.472     albertel 3816:     <message></td></tr><tr><td></message>
1.432     albertel 3817:         $code_selection
1.472     albertel 3818:     <message></td></tr></table></message>
                   3819:     <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
                   3820:     <message><b>Select saved CODEs:</b></message>
1.381     albertel 3821:     <message></td><td></message>
1.294     albertel 3822:     <dropdown variable="REUSE_OLD_CODES">
                   3823:         $namechoice
                   3824:     </dropdown>
1.412     albertel 3825:     <message></td></tr></table></message>
1.424     foxr     3826:   </state>
1.284     albertel 3827:     $resource_selector
                   3828: CHOOSE_ANON2
1.481     albertel 3829:     }
                   3830: 
1.121     bowersj2 3831:     # FIXME: That RE should come from a library somewhere.
1.483     foxr     3832:     if (($perm{'pav'} 
1.482     albertel 3833: 	&& $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
                   3834: 	&& (defined($helper->{'VARS'}->{'construction'})
                   3835: 	    ||
                   3836: 	    (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
                   3837: 	     && 
                   3838: 	     $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483     foxr     3839: 	    )) 
                   3840: 	&& $helper->{VARS}->{'assignment'} eq ""
1.482     albertel 3841: 	) {
                   3842: 	my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
1.546     bisitz   3843:         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 3844:         my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482     albertel 3845:   <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458     www      3846: 
1.138     bowersj2 3847:     <files variable="FILES" multichoice='1'>
1.144     bowersj2 3848:       <nextstate>PAGESIZE</nextstate>
1.138     bowersj2 3849:       <filechoice>return '$subdir';</filechoice>
1.139     bowersj2 3850: CHOOSE_FROM_SUBDIR
                   3851:         
1.238     bowersj2 3852:         # this is broken up because I really want interpolation above,
                   3853:         # and I really DON'T want it below
1.139     bowersj2 3854:         $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225     bowersj2 3855:       <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
                   3856: 	  $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131     bowersj2 3857:       </filefilter>
1.138     bowersj2 3858:       </files>
1.131     bowersj2 3859:     </state>
                   3860: CHOOSE_FROM_SUBDIR
1.139     bowersj2 3861:         &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131     bowersj2 3862:     }
1.238     bowersj2 3863: 
                   3864:     # Allow the user to select any sequence in the course, feed it to
                   3865:     # another resource selector for that sequence
1.483     foxr     3866:     if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509     albertel 3867: 	push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249     sakharuk 3868: 			      'select_sequences', 'CHOOSE_SEQUENCE'];
1.244     bowersj2 3869: 	my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
                   3870: 	#Escape apostrophes and backslashes for Perl
                   3871: 	$escapedSequenceName =~ s/\\/\\\\/g;
                   3872: 	$escapedSequenceName =~ s/'/\\'/g;
1.239     bowersj2 3873: 	&Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238     bowersj2 3874:   <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
                   3875:     <message>Select the sequence to print resources from:</message>
                   3876:     <resource variable="SEQUENCE">
                   3877:       <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
                   3878:       <filterfunc>return \$res->is_sequence;</filterfunc>
                   3879:       <valuefunc>return $urlValue;</valuefunc>
1.447     foxr     3880:       <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391     foxr     3881: 	</choicefunc>
1.238     bowersj2 3882:       </resource>
                   3883:     </state>
                   3884:   <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
                   3885:     <message>(mark desired resources then click "next" button) <br /></message>
1.435     foxr     3886:     <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287     albertel 3887:               closeallpages="1">
1.238     bowersj2 3888:       <nextstate>PAGESIZE</nextstate>
1.466     albertel 3889:       <filterfunc>return $isNotMap</filterfunc>
1.244     bowersj2 3890:       <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238     bowersj2 3891:       <valuefunc>return $symbFilter;</valuefunc>
1.465     albertel 3892:       $start_new_option
1.238     bowersj2 3893:       </resource>
                   3894:     </state>
                   3895: CHOOSE_FROM_ANY_SEQUENCE
1.239     bowersj2 3896: }
1.481     albertel 3897: 
1.131     bowersj2 3898:     # Generate the first state, to select which resources get printed.
1.223     bowersj2 3899:     Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131     bowersj2 3900:     $paramHash = Apache::lonhelper::getParamHash();
1.155     sakharuk 3901:     $paramHash->{MESSAGE_TEXT} = "";
1.131     bowersj2 3902:     Apache::lonhelper::message->new();
                   3903:     $paramHash = Apache::lonhelper::getParamHash();
                   3904:     $paramHash->{'variable'} = 'PRINT_TYPE';
                   3905:     $paramHash->{CHOICES} = $printChoices;
                   3906:     Apache::lonhelper::choices->new();
1.161     bowersj2 3907: 
1.223     bowersj2 3908:     my $startedTable = 0; # have we started an HTML table yet? (need
                   3909:                           # to close it later)
                   3910: 
1.585     raeburn  3911:     if (($perm{'pav'} and $perm{'vgr'}) or 
1.170     sakharuk 3912: 	($helper->{VARS}->{'construction'} eq '1')) {
1.544     bisitz   3913: 	&addMessage('<br />'
                   3914:                    .'<h3>'.&mt('Print Options').'</h3>'
                   3915:                    .&Apache::lonhtmlcommon::start_pick_box()
                   3916:                    .&Apache::lonhtmlcommon::row_title(
                   3917:                        '<label for="ANSWER_TYPE_forminput">'
                   3918:                       .&mt('Print Answers')
                   3919:                       .'</label>'
                   3920:                     )
                   3921:         );
1.161     bowersj2 3922:         $paramHash = Apache::lonhelper::getParamHash();
1.162     sakharuk 3923: 	$paramHash->{'variable'} = 'ANSWER_TYPE';   
                   3924: 	$helper->declareVar('ANSWER_TYPE');         
1.161     bowersj2 3925:         $paramHash->{CHOICES} = [
1.242     sakharuk 3926:                                    ['Without Answers', 'yes'],
                   3927:                                    ['With Answers', 'no'],
1.368     albertel 3928:                                    ['Only Answers', 'only']
1.289     sakharuk 3929:                                 ];
1.210     sakharuk 3930:         Apache::lonhelper::dropdown->new();
1.544     bisitz   3931: 	&addMessage(&Apache::lonhtmlcommon::row_closure());
1.223     bowersj2 3932: 	$startedTable = 1;
1.556     foxr     3933: 
                   3934: #
                   3935: #  Select font size.
                   3936: #
                   3937: 
                   3938:             $helper->declareVar('fontsize');
                   3939:             &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Font Size')));
                   3940:             my $xmlfrag = << "FONT_SELECTION";
                   3941: 
                   3942:           
                   3943:             <dropdown variable='fontsize' multichoice='0', allowempty='0'>
                   3944:             <defaultvalue>
                   3945: 		  return 'normalsize';
                   3946:             </defaultvalue>
                   3947:             <choice computer='tiny'>Tiny</choice>
                   3948:             <choice computer='sub/superscriptsize'>Script Size</choice>
                   3949:             <choice computer='footnotesize'>Footnote Size</choice>
                   3950:             <choice computer='small'>Small</choice>
                   3951:             <choice computer='normalsize'>Normal (default)</choice>
                   3952:             <choice computer='large'>larger than normal</choice>
                   3953:             <choice computer='Large'>Even larger than normal</choice>
                   3954:             <choice computer='LARGE'>Still larger than normal</choice>
                   3955:             <choice computer='huge'>huge font size</choice>
                   3956:             <choice computer='Huge'>Largest possible size</choice>
                   3957:             </dropdown>
                   3958: FONT_SELECTION
                   3959:             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
                   3960:             &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.161     bowersj2 3961:     }
1.209     sakharuk 3962: 
1.397     albertel 3963:     if ($perm{'pav'}) {
1.223     bowersj2 3964: 	if (!$startedTable) {
1.497     www      3965: 	    addMessage("<hr width='33%' /><table><tr><td align='right'>".
                   3966:                        '<label for="LATEX_TYPE_forminput">'.
                   3967:                        &mt('LaTeX mode').
                   3968:                        "</label>: </td><td>");
1.223     bowersj2 3969: 	    $startedTable = 1;
                   3970: 	} else {
1.544     bisitz   3971: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   3972:                            '<label for="LATEX_TYPE_forminput">'
                   3973:                            .&mt('LaTeX mode')
                   3974:                            .'</label>'
                   3975:                         )
                   3976:             );
1.223     bowersj2 3977: 	}
1.203     sakharuk 3978:         $paramHash = Apache::lonhelper::getParamHash();
                   3979: 	$paramHash->{'variable'} = 'LATEX_TYPE';   
                   3980: 	$helper->declareVar('LATEX_TYPE');  
                   3981: 	if ($helper->{VARS}->{'construction'} eq '1') {       
                   3982: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 3983: 				     ['standard LaTeX mode', 'standard'], 
                   3984: 				     ['LaTeX batchmode', 'batchmode'], ];
1.203     sakharuk 3985: 	} else {
                   3986: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 3987: 				     ['LaTeX batchmode', 'batchmode'],
                   3988: 				     ['standard LaTeX mode', 'standard'] ];
1.203     sakharuk 3989: 	}
1.210     sakharuk 3990:         Apache::lonhelper::dropdown->new();
1.218     sakharuk 3991:  
1.544     bisitz   3992: 	&addMessage(&Apache::lonhtmlcommon::row_closure()
                   3993:                    .&Apache::lonhtmlcommon::row_title(
                   3994:                         '<label for="TABLE_CONTENTS_forminput">'
                   3995:                        .&mt('Print Table of Contents')
                   3996:                        .'</label>'
                   3997:                     )
                   3998:         );
1.209     sakharuk 3999:         $paramHash = Apache::lonhelper::getParamHash();
                   4000: 	$paramHash->{'variable'} = 'TABLE_CONTENTS';   
                   4001: 	$helper->declareVar('TABLE_CONTENTS');         
                   4002:         $paramHash->{CHOICES} = [
1.223     bowersj2 4003:                                    ['No', 'no'],
                   4004:                                    ['Yes', 'yes'] ];
1.210     sakharuk 4005:         Apache::lonhelper::dropdown->new();
1.544     bisitz   4006: 	&addMessage(&Apache::lonhtmlcommon::row_closure());
1.214     sakharuk 4007:         
1.220     sakharuk 4008: 	if (not $helper->{VARS}->{'construction'}) {
1.545     bisitz   4009: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   4010:                             '<label for="TABLE_INDEX_forminput">'
                   4011:                            .&mt('Print Index')
                   4012:                            .'</label>'
                   4013:                         )
                   4014:             );
1.220     sakharuk 4015: 	    $paramHash = Apache::lonhelper::getParamHash();
                   4016: 	    $paramHash->{'variable'} = 'TABLE_INDEX';   
                   4017: 	    $helper->declareVar('TABLE_INDEX');         
                   4018: 	    $paramHash->{CHOICES} = [
1.223     bowersj2 4019: 				     ['No', 'no'],
                   4020: 				     ['Yes', 'yes'] ];
1.220     sakharuk 4021: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   4022:             &addMessage(&Apache::lonhtmlcommon::row_closure());
                   4023:             &addMessage(&Apache::lonhtmlcommon::row_title(
                   4024:                             '<label for="PRINT_DISCUSSIONS_forminput">'
                   4025:                            .&mt('Print Discussions')
                   4026:                            .'</label>'
                   4027:                         )
                   4028:             );
1.309     sakharuk 4029: 	    $paramHash = Apache::lonhelper::getParamHash();
                   4030: 	    $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';   
                   4031: 	    $helper->declareVar('PRINT_DISCUSSIONS');         
                   4032: 	    $paramHash->{CHOICES} = [
                   4033: 				     ['No', 'no'],
                   4034: 				     ['Yes', 'yes'] ];
                   4035: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   4036:             &addMessage(&Apache::lonhtmlcommon::row_closure());
1.372     foxr     4037: 
1.511     foxr     4038: 	    # Prompt for printing annotations too.
                   4039: 		
1.545     bisitz   4040: 	    &addMessage(&Apache::lonhtmlcommon::row_title(
                   4041:                             '<label for="PRINT_ANNOTATIONS_forminput">'
                   4042:                            .&mt('Print Annotations')
                   4043:                            .'</label>'
                   4044:                         )
                   4045:             );
1.511     foxr     4046: 	    $paramHash = Apache::lonhelper::getParamHash();
                   4047: 	    $paramHash->{'variable'} = "PRINT_ANNOTATIONS";
                   4048: 	    $helper->declareVar("PRINT_ANNOTATIONS");
                   4049: 	    $paramHash->{CHOICES} = [
                   4050: 				     ['No', 'no'],
                   4051: 				     ['Yes', 'yes']];
                   4052: 	    Apache::lonhelper::dropdown->new();
1.545     bisitz   4053:             &addMessage(&Apache::lonhtmlcommon::row_closure());
1.511     foxr     4054: 
1.545     bisitz   4055:             &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Foils')));
1.397     albertel 4056: 	    $paramHash = Apache::lonhelper::getParamHash();
                   4057: 	    $paramHash->{'multichoice'} = "true";
                   4058: 	    $paramHash->{'allowempty'}  = "true";
                   4059: 	    $paramHash->{'variable'}   = "showallfoils";
1.555     bisitz   4060: 	    $paramHash->{'CHOICES'} = [ [&mt('Show All Foils'), "1"] ];
1.397     albertel 4061: 	    Apache::lonhelper::choices->new();
1.545     bisitz   4062:             &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.220     sakharuk 4063: 	}
1.219     sakharuk 4064: 
1.230     albertel 4065: 	if ($helper->{'VARS'}->{'construction'}) { 
1.505     albertel 4066: 	    my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497     www      4067:             my $randseedtext=&mt("Use random seed");
                   4068:             my $stylefiletext=&mt("Use style file");
1.506     albertel 4069:             my $selectfiletext=&mt("Select style file");
1.497     www      4070: 
1.544     bisitz   4071: 	    my $xmlfrag .= '<message>'
                   4072:             .&Apache::lonhtmlcommon::row_title('<label for="curseed_forminput">'
                   4073:                                               .$randseedtext
                   4074:                                               .'</label>'
                   4075:              )
                   4076:             .'</message>
                   4077:             <string variable="curseed" size="15" maxlength="15">
                   4078:                 <defaultvalue>
                   4079:                    return '.$helper->{VARS}->{'curseed'}.';
                   4080:                 </defaultvalue>'
                   4081:             .'</string>'
                   4082:             .'<message>'
                   4083:             .&Apache::lonhtmlcommon::row_closure()
                   4084:             .&Apache::lonhtmlcommon::row_title('<label for="style_file">'
                   4085:                                               .$stylefiletext
                   4086:                                               .'</label>'
                   4087:              )
                   4088:             .'</message>
1.504     albertel 4089:              <string variable="style_file" size="40">
1.544     bisitz   4090:                 <defaultvalue>
                   4091:                     return '.$stylevalue.';
                   4092:                 </defaultvalue>
                   4093:              </string><message>&nbsp;'
                   4094: .qq|<a href="javascript:openbrowser('helpform','style_file_forminput','sty')">|
                   4095: .$selectfiletext.'</a>'
                   4096:             .&Apache::lonhtmlcommon::row_closure()
1.555     bisitz   4097:             .&Apache::lonhtmlcommon::row_title(&mt('Show All Foils'))
1.544     bisitz   4098:             .'</message>
1.371     foxr     4099: 	     <choices allowempty="1" multichoice="true" variable="showallfoils">
1.544     bisitz   4100:                 <choice computer="1">&nbsp;</choice>
                   4101:              </choices>'
                   4102: 	    .'<message>'
                   4103:             .&Apache::lonhtmlcommon::row_closure()
                   4104:             .'</message>';
1.230     albertel 4105:             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.512     foxr     4106: 
                   4107: 
1.544     bisitz   4108:             &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Problem Type')));
1.512     foxr     4109: 	    #
                   4110: 	    # Initial value from construction space:
                   4111: 	    #
                   4112: 	    if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
                   4113: 		$helper->{VARS}->{'probstatus'} = $env{'form.problemtype'};	# initial value
                   4114: 	    }
1.518     foxr     4115: 	    $xmlfrag = << "PROBTYPE";
                   4116: 		<dropdown variable="probstatus" multichoice="0" allowempty="0">
                   4117: 		   <defaultvalue>
                   4118: 		      return "$helper->{VARS}->{'probstatus'}";
                   4119:                    </defaultvalue>
                   4120: 		   <choice computer="problem">Homework Problem</choice>
                   4121: 		   <choice computer="exam">Exam Problem</choice>
                   4122: 		   <choice computer="survey">Survey question</choice>
1.572     raeburn  4123:                    ,choice computer="anonsurvey"Anonymous survey question</choice>
1.518     foxr     4124: 		</dropdown>
                   4125: PROBTYPE
                   4126:             &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.544     bisitz   4127:             &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.512     foxr     4128: 
1.556     foxr     4129: 
                   4130: 
1.544     bisitz   4131:         }
1.223     bowersj2 4132:     }
1.264     sakharuk 4133: 
                   4134: 
                   4135: 
1.218     sakharuk 4136: 
1.223     bowersj2 4137:     if ($startedTable) {
1.544     bisitz   4138:         &addMessage(&Apache::lonhtmlcommon::end_pick_box());
1.215     sakharuk 4139:     }
1.161     bowersj2 4140: 
1.131     bowersj2 4141:     Apache::lonprintout::page_format_state->new("FORMAT");
                   4142: 
1.144     bowersj2 4143:     # Generate the PAGESIZE state which will offer the user the margin
                   4144:     # choices if they select one column
                   4145:     Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
                   4146:     Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
                   4147: 
                   4148: 
1.131     bowersj2 4149:     $helper->process();
                   4150: 
1.416     foxr     4151: 
1.131     bowersj2 4152:     # MANUAL BAILOUT CONDITION:
                   4153:     # If we're in the "final" state, bailout and return to handler
                   4154:     if ($helper->{STATE} eq 'FINAL') {
                   4155:         return $helper;
                   4156:     }    
1.130     sakharuk 4157: 
1.584     raeburn  4158:     my $footer;
1.395     www      4159:     if ($helper->{STATE} eq 'START') {
1.584     raeburn  4160:         my $prtspool=$r->dir_config('lonPrtDir'); 
                   4161: 	$footer = &recently_generated($prtspool);
1.395     www      4162:     }
1.584     raeburn  4163:     $r->print($helper->display($footer));
1.333     albertel 4164:     &Apache::lonhelper::unregisterHelperTags();
1.115     bowersj2 4165: 
                   4166:     return OK;
                   4167: }
                   4168: 
1.1       www      4169: 
                   4170: 1;
1.119     bowersj2 4171: 
                   4172: package Apache::lonprintout::page_format_state;
                   4173: 
                   4174: =pod
                   4175: 
1.131     bowersj2 4176: =head1 Helper element: page_format_state
                   4177: 
                   4178: See lonhelper.pm documentation for discussion of the helper framework.
1.119     bowersj2 4179: 
1.131     bowersj2 4180: Apache::lonprintout::page_format_state is an element that gives the 
                   4181: user an opportunity to select the page layout they wish to print 
                   4182: with: Number of columns, portrait/landscape, and paper size. If you 
                   4183: want to change the paper size choices, change the @paperSize array 
                   4184: contents in this package.
1.119     bowersj2 4185: 
1.131     bowersj2 4186: page_format_state is always directly invoked in lonprintout.pm, so there
                   4187: is no tag interface. You actually pass parameters to the constructor.
1.119     bowersj2 4188: 
                   4189: =over 4
                   4190: 
1.131     bowersj2 4191: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119     bowersj2 4192: 
                   4193: =back
                   4194: 
                   4195: =cut
                   4196: 
1.131     bowersj2 4197: use Apache::lonhelper;
1.119     bowersj2 4198: 
                   4199: no strict;
1.131     bowersj2 4200: @ISA = ("Apache::lonhelper::element");
1.119     bowersj2 4201: use strict;
1.266     sakharuk 4202: use Apache::lonlocal;
1.373     albertel 4203: use Apache::lonnet;
1.119     bowersj2 4204: 
                   4205: my $maxColumns = 2;
1.376     albertel 4206: # it'd be nice if these all worked
                   4207: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 
                   4208: #                 "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
                   4209: #                 "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]", 
                   4210: #                 "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326     sakharuk 4211: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 
1.376     albertel 4212: 		 "a4 [210x297 mm]");
1.119     bowersj2 4213: 
                   4214: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
                   4215: #                   Paper type
                   4216: 
                   4217: sub new { 
1.131     bowersj2 4218:     my $self = Apache::lonhelper::element->new();
1.119     bowersj2 4219: 
1.135     bowersj2 4220:     shift;
                   4221: 
1.131     bowersj2 4222:     $self->{'variable'} = shift;
1.134     bowersj2 4223:     my $helper = Apache::lonhelper::getHelper();
1.135     bowersj2 4224:     $helper->declareVar($self->{'variable'});
1.131     bowersj2 4225:     bless($self);
1.119     bowersj2 4226:     return $self;
                   4227: }
                   4228: 
                   4229: sub render {
                   4230:     my $self = shift;
1.131     bowersj2 4231:     my $helper = Apache::lonhelper::getHelper();
1.119     bowersj2 4232:     my $result = '';
1.131     bowersj2 4233:     my $var = $self->{'variable'};
1.266     sakharuk 4234:     my $PageLayout=&mt('Page layout');
                   4235:     my $NumberOfColumns=&mt('Number of columns');
                   4236:     my $PaperType=&mt('Paper type');
1.506     albertel 4237:     my $landscape=&mt('Landscape');
                   4238:     my $portrait=&mt('Portrait');
1.539     onken    4239:     my $pdfFormLabel=&mt('PDF-Formfields');
                   4240:     my $with=&mt('with Formfields');
                   4241:     my $without=&mt('without Formfields');
1.556     foxr     4242:     
                   4243: 
1.544     bisitz   4244:     $result.='<h3>'.&mt('Layout Options').'</h3>'
                   4245:             .&Apache::loncommon::start_data_table()
                   4246:             .&Apache::loncommon::start_data_table_header_row()
                   4247:             .'<th>'.$PageLayout.'</th>'
                   4248:             .'<th>'.$NumberOfColumns.'</th>'
                   4249:             .'<th>'.$PaperType.'</th>'
                   4250:             .'<th>'.$pdfFormLabel.'</th>'
                   4251:             .&Apache::loncommon::end_data_table_header_row()
                   4252:             .&Apache::loncommon::start_data_table_row()
                   4253:     .'<td>'
                   4254:     .'<label><input type="radio" name="'.${var}.'.layout" value="L" />'.$landscape.'</label><br />'
                   4255:     .'<label><input type="radio" name="'.${var}.'.layout" value="P" checked="checked" />'.$portrait.'</label>'
                   4256:     .'</td>';
1.119     bowersj2 4257: 
1.544     bisitz   4258:     $result.='<td align="center">'
                   4259:             .'<select name="'.${var}.'.cols">';
1.119     bowersj2 4260: 
                   4261:     my $i;
                   4262:     for ($i = 1; $i <= $maxColumns; $i++) {
1.144     bowersj2 4263:         if ($i == 2) {
1.553     bisitz   4264:             $result .= '<option value="'.$i.'" selected="selected">'.$i.'</option>'."\n";
1.119     bowersj2 4265:         } else {
1.553     bisitz   4266:             $result .= '<option value="'.$i.'">'.$i.'</option>'."\n";
1.119     bowersj2 4267:         }
                   4268:     }
                   4269: 
                   4270:     $result .= "</select></td><td>\n";
                   4271:     $result .= "<select name='${var}.paper'>\n";
                   4272: 
1.373     albertel 4273:     my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398     albertel 4274:     my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
                   4275:     $DefaultPaperSize=~s/\s//g;
1.304     sakharuk 4276:     if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119     bowersj2 4277:     $i = 0;
                   4278:     foreach (@paperSize) {
1.326     sakharuk 4279: 	$_=~/(\w+)/;
                   4280: 	my $papersize=$1;
1.304     sakharuk 4281:         if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.553     bisitz   4282:             $result .= '<option selected="selected" value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119     bowersj2 4283:         } else {
1.553     bisitz   4284:             $result .= '<option value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119     bowersj2 4285:         }
                   4286:         $i++;
                   4287:     }
1.539     onken    4288:     $result .= <<HTML;
                   4289:         </select>
                   4290:     </td>
                   4291:     <td align='center'>
                   4292:         <select name='${var}.pdfFormFields'>
1.553     bisitz   4293:             <option selected="selected" value="no">$without</option>
                   4294:             <option value="yes">$with</option>
1.539     onken    4295:         </select>
                   4296:     </td>
                   4297: HTML
1.544     bisitz   4298:     $result.=&Apache::loncommon::end_data_table_row()
                   4299:             .&Apache::loncommon::end_data_table();
1.539     onken    4300: 
1.119     bowersj2 4301:     return $result;
1.135     bowersj2 4302: }
                   4303: 
                   4304: sub postprocess {
                   4305:     my $self = shift;
                   4306: 
                   4307:     my $var = $self->{'variable'};
1.136     bowersj2 4308:     my $helper = Apache::lonhelper->getHelper();
1.135     bowersj2 4309:     $helper->{VARS}->{$var} = 
1.373     albertel 4310:         $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
1.539     onken    4311:         $env{"form.$var.paper"} . '|' . $env{"form.$var.pdfFormFields"};
1.135     bowersj2 4312:     return 1;
1.119     bowersj2 4313: }
                   4314: 
                   4315: 1;
1.144     bowersj2 4316: 
                   4317: package Apache::lonprintout::page_size_state;
                   4318: 
                   4319: =pod
                   4320: 
                   4321: =head1 Helper element: page_size_state
                   4322: 
                   4323: See lonhelper.pm documentation for discussion of the helper framework.
                   4324: 
                   4325: Apache::lonprintout::page_size_state is an element that gives the 
                   4326: user the opportunity to further refine the page settings if they
                   4327: select a single-column page.
                   4328: 
                   4329: page_size_state is always directly invoked in lonprintout.pm, so there
                   4330: is no tag interface. You actually pass parameters to the constructor.
                   4331: 
                   4332: =over 4
                   4333: 
                   4334: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
                   4335: 
                   4336: =back
                   4337: 
                   4338: =cut
                   4339: 
                   4340: use Apache::lonhelper;
1.373     albertel 4341: use Apache::lonnet;
1.144     bowersj2 4342: no strict;
                   4343: @ISA = ("Apache::lonhelper::element");
                   4344: use strict;
                   4345: 
                   4346: 
                   4347: 
                   4348: sub new { 
                   4349:     my $self = Apache::lonhelper::element->new();
                   4350: 
                   4351:     shift; # disturbs me (probably prevents subclassing) but works (drops
                   4352:            # package descriptor)... - Jeremy
                   4353: 
                   4354:     $self->{'variable'} = shift;
                   4355:     my $helper = Apache::lonhelper::getHelper();
                   4356:     $helper->declareVar($self->{'variable'});
                   4357: 
                   4358:     # The variable name of the format element, so we can look into 
                   4359:     # $helper->{VARS} to figure out whether the columns are one or two
                   4360:     $self->{'formatvar'} = shift;
                   4361: 
1.463     foxr     4362: 
1.144     bowersj2 4363:     $self->{NEXTSTATE} = shift;
                   4364:     bless($self);
1.467     foxr     4365: 
1.144     bowersj2 4366:     return $self;
                   4367: }
                   4368: 
                   4369: sub render {
                   4370:     my $self = shift;
                   4371:     my $helper = Apache::lonhelper::getHelper();
                   4372:     my $result = '';
                   4373:     my $var = $self->{'variable'};
                   4374: 
1.467     foxr     4375: 
                   4376: 
1.144     bowersj2 4377:     if (defined $self->{ERROR_MSG}) {
1.464     albertel 4378:         $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144     bowersj2 4379:     }
                   4380: 
1.438     foxr     4381:     my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463     foxr     4382: 
                   4383:     # Use format to get sensible defaults for the margins:
                   4384: 
                   4385: 
                   4386:     my ($laystyle, $cols, $papersize) = split(/\|/, $format);
                   4387:     ($papersize)                      = split(/ /, $papersize);
                   4388: 
1.559     foxr     4389:     $laystyle = &Apache::lonprintout::map_laystyle($laystyle);
1.463     foxr     4390: 
                   4391: 
                   4392: 
1.464     albertel 4393:     my %size;
                   4394:     ($size{'width_and_units'},
                   4395:      $size{'height_and_units'},
                   4396:      $size{'margin_and_units'})=
                   4397: 	 &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463     foxr     4398:     
1.464     albertel 4399:     foreach my $dimension ('width','height','margin') {
                   4400: 	($size{$dimension},$size{$dimension.'_unit'}) =
                   4401: 	    split(/ +/, $size{$dimension.'_and_units'},2);
                   4402:        	
                   4403: 	foreach my $unit ('cm','in') {
                   4404: 	    $size{$dimension.'_options'} .= '<option ';
                   4405: 	    if ($size{$dimension.'_unit'} eq $unit) {
                   4406: 		$size{$dimension.'_options'} .= 'selected="selected" ';
                   4407: 	    }
                   4408: 	    $size{$dimension.'_options'} .= '>'.$unit.'</option>';
                   4409: 	}
1.438     foxr     4410:     }
                   4411: 
1.470     foxr     4412:     # Adjust margin for LaTeX margin: .. requires units == cm or in.
                   4413: 
                   4414:     if ($size{'margin_unit'} eq 'in') {
                   4415: 	$size{'margin'} += 1;
                   4416:     }  else {
                   4417: 	$size{'margin'} += 2.54;
                   4418:     }
1.548     bisitz   4419:     my %lt = &Apache::lonlocal::texthash(
                   4420:         'format' => 'How should each column be formatted?',
                   4421:         'width'  => 'Width',
                   4422:         'height' => 'Height',
                   4423:         'margin' => 'Left Margin'
                   4424:     );
                   4425: 
                   4426:     $result .= '<p>'.$lt{'format'}.'</p>'
                   4427:               .&Apache::lonhtmlcommon::start_pick_box()
                   4428:               .&Apache::lonhtmlcommon::row_title($lt{'width'})
                   4429:               .'<input type="text" name="'.$var.'.width" value="'.$size{'width'}.'" size="4" />'
                   4430:               .'<select name="'.$var.'.widthunit">'
                   4431:               .$size{'width_options'}
                   4432:               .'</select>'
                   4433:               .&Apache::lonhtmlcommon::row_closure()
                   4434:               .&Apache::lonhtmlcommon::row_title($lt{'height'})
                   4435:               .'<input type="text" name="'.$var.'.height" value="'.$size{'height'}.'" size="4" />'
                   4436:               .'<select name="'.$var.'.heightunit">'
                   4437:               .$size{'height_options'}
                   4438:               .'</select>'
                   4439:               .&Apache::lonhtmlcommon::row_closure()
                   4440:               .&Apache::lonhtmlcommon::row_title($lt{'margin'})
                   4441:               .'<input type="text" name="'.$var.'.lmargin" value="'.$size{'margin'}.'" size="4" />'
                   4442:               .'<select name="'.$var.'.lmarginunit">'
                   4443:               .$size{'margin_options'}
                   4444:               .'</select>'
                   4445:               .&Apache::lonhtmlcommon::row_closure(1)
                   4446:               .&Apache::lonhtmlcommon::end_pick_box();
                   4447:     # <p>Hint: Some instructors like to leave scratch space for the student by
                   4448:     # making the width much smaller than the width of the page.</p>
1.144     bowersj2 4449: 
                   4450:     return $result;
                   4451: }
                   4452: 
1.470     foxr     4453: 
1.144     bowersj2 4454: sub preprocess {
                   4455:     my $self = shift;
                   4456:     my $helper = Apache::lonhelper::getHelper();
                   4457: 
                   4458:     my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467     foxr     4459: 
                   4460:     #  If the user does not have 'pav' privilege, set default widths and
                   4461:     #  on to the next state right away.
                   4462:     #
                   4463:     if (!$perm{'pav'}) {
                   4464: 	my $var = $self->{'variable'};
                   4465: 	my $format = $helper->{VARS}->{$self->{'formatvar'}};
                   4466: 	
                   4467: 	my ($laystyle, $cols, $papersize) = split(/\|/, $format);
                   4468: 	($papersize)                      = split(/ /, $papersize);
                   4469: 	
                   4470: 	
1.560     foxr     4471: 	$laystyle = &Apache::lonprintout::map_laystyle($laystyle);
1.559     foxr     4472: 
1.467     foxr     4473: 	#  Figure out some good defaults for the print out and set them:
                   4474: 	
                   4475: 	my %size;
                   4476: 	($size{'width'},
                   4477: 	 $size{'height'},
                   4478: 	 $size{'lmargin'})=
                   4479: 	     &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
                   4480: 	
                   4481: 	foreach my $dim ('width', 'height', 'lmargin') {
                   4482: 	    my ($value, $units) = split(/ /, $size{$dim});
1.470     foxr     4483: 	    	    
1.467     foxr     4484: 	    $helper->{VARS}->{"$var.".$dim}      = $value;
                   4485: 	    $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
                   4486: 	    
                   4487: 	}
                   4488: 	
                   4489: 
                   4490: 	# Transition to the next state
                   4491: 
                   4492: 	$helper->changeState($self->{NEXTSTATE});
                   4493:     }
1.144     bowersj2 4494:    
                   4495:     return 1;
                   4496: }
                   4497: 
                   4498: sub postprocess {
                   4499:     my $self = shift;
                   4500: 
                   4501:     my $var = $self->{'variable'};
                   4502:     my $helper = Apache::lonhelper->getHelper();
1.373     albertel 4503:     my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"}; 
                   4504:     my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"}; 
                   4505:     my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"}; 
                   4506:     $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"}; 
                   4507:     $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"}; 
                   4508:     $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"}; 
1.144     bowersj2 4509: 
                   4510:     my $error = '';
                   4511: 
                   4512:     # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed 
                   4513:     # by an optional period, followed by digits, ending the string
                   4514: 
1.464     albertel 4515:     if ($width !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 4516:         $error .= "Invalid width; please type only a number.<br />\n";
                   4517:     }
1.464     albertel 4518:     if ($height !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 4519:         $error .= "Invalid height; please type only a number.<br />\n";
                   4520:     }
1.464     albertel 4521:     if ($lmargin !~  /^-?[0-9]*(\.[0-9]*)?$/) {
1.144     bowersj2 4522:         $error .= "Invalid left margin; please type only a number.<br />\n";
1.470     foxr     4523:     } else {
                   4524: 	# Adjust for LaTeX 1.0 inch margin:
                   4525: 
                   4526: 	if ($env{"form.${var}.lmarginunit"} eq "in") {
                   4527: 	    $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
                   4528: 	} else {
                   4529: 	    $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
                   4530: 	}
1.144     bowersj2 4531:     }
                   4532: 
                   4533:     if (!$error) {
                   4534:         Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
                   4535:         return 1;
                   4536:     } else {
                   4537:         $self->{ERROR_MSG} = $error;
                   4538:         return 0;
                   4539:     }
                   4540: }
                   4541: 
                   4542: 
1.119     bowersj2 4543: 
1.1       www      4544: __END__
1.6       sakharuk 4545: 

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