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