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