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