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