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