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