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