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