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