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