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