Annotation of loncom/interface/lonprintout.pm, revision 1.540
1.389 foxr 1: # The LearningOnline Network
1.1 www 2: # Printout
3: #
1.540 ! raeburn 4: # $Id: lonprintout.pm,v 1.539 2008/09/05 11:16:13 onken 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;
1.539 onken 1484: my ($laystyle,$numberofcolumns,$papersize,$pdfFormFields)=@temporary_array;
1.140 sakharuk 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.539 onken 1505: $form{'pdfFormFields'} = $pdfFormFields;
1.372 foxr 1506:
1507: # If form.showallfoils is set, then request all foils be shown:
1508: # privilege will be enforced both by not allowing the
1509: # check box selecting this option to be presnt unless it's ok,
1510: # and by lonresponse's priv. check.
1511: # The if is here because lonresponse.pm only cares that
1512: # showallfoils is defined, not what the value is.
1513:
1514: if ($helper->{'VARS'}->{'showallfoils'} eq "1") {
1515: $form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'};
1516: }
1.504 albertel 1517:
1518: if ($helper->{'VARS'}->{'style_file'}=~/\w/) {
1.520 raeburn 1519: &Apache::lonnet::appenv({'construct.style' =>
1520: $helper->{'VARS'}->{'style_file'}});
1.504 albertel 1521: } elsif ($env{'construct.style'}) {
1522: &Apache::lonnet::delenv('construct\\.style');
1523: }
1524:
1.372 foxr 1525:
1.140 sakharuk 1526: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') {
1.143 sakharuk 1527: #-- single document - problem, page, html, xml, ...
1.343 albertel 1528: my ($currentURL,$cleanURL);
1.375 foxr 1529:
1.162 sakharuk 1530: if ($helper->{'VARS'}->{'construction'} ne '1') {
1.185 sakharuk 1531: #prints published resource
1.153 sakharuk 1532: $currentURL=$helper->{'VARS'}->{'postdata'};
1.343 albertel 1533: $cleanURL=&Apache::lonenc::check_decrypt($currentURL);
1.143 sakharuk 1534: } else {
1.512 foxr 1535:
1.185 sakharuk 1536: #prints resource from the construction space
1.240 albertel 1537: $currentURL='/'.$helper->{'VARS'}->{'filename'};
1.206 sakharuk 1538: if ($currentURL=~/([^?]+)/) {$currentURL=$1;}
1.343 albertel 1539: $cleanURL=$currentURL;
1.143 sakharuk 1540: }
1.140 sakharuk 1541: $selectionmade = 1;
1.413 albertel 1542: if ($cleanURL!~m|^/adm/|
1543: && $cleanURL=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.169 albertel 1544: my $rndseed=time;
1.242 sakharuk 1545: my $texversion='';
1546: if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') {
1547: my %moreenv;
1.343 albertel 1548: $moreenv{'request.filename'}=$cleanURL;
1.290 sakharuk 1549: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {$form{'problemtype'}='exam';}
1.242 sakharuk 1550: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310 sakharuk 1551: $form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.242 sakharuk 1552: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309 sakharuk 1553: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 1554: $form{'print_annotations'}=$helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1555: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
1556: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
1557: $form{'problem_split'}='yes';
1558: }
1.242 sakharuk 1559: if ($helper->{'VARS'}->{'curseed'}) {
1560: $rndseed=$helper->{'VARS'}->{'curseed'};
1561: }
1562: $form{'rndseed'}=$rndseed;
1.520 raeburn 1563: &Apache::lonnet::appenv(\%moreenv);
1.428 albertel 1564:
1565: &Apache::lonxml::clear_problem_counter();
1566:
1.375 foxr 1567: $resources_printed .= $currentURL.':';
1.515 foxr 1568: $texversion.=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.428 albertel 1569:
1.511 foxr 1570: # Add annotations if required:
1571:
1.428 albertel 1572: &Apache::lonxml::clear_problem_counter();
1573:
1.242 sakharuk 1574: &Apache::lonnet::delenv('request.filename');
1.230 albertel 1575: }
1.423 foxr 1576: # current document with answers.. no need to encap in minipage
1577: # since there's only one answer.
1578:
1.242 sakharuk 1579: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1580: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.353 foxr 1581: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.166 albertel 1582: $form{'grade_target'}='answer';
1.167 albertel 1583: $form{'answer_output_mode'}='tex';
1.169 albertel 1584: $form{'rndseed'}=$rndseed;
1.401 albertel 1585: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {
1586: $form{'problemtype'}='exam';
1587: }
1.375 foxr 1588: $resources_printed .= $currentURL.':';
1.515 foxr 1589: my $answer=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.511 foxr 1590:
1591:
1.242 sakharuk 1592: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
1593: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1594: } else {
1595: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.245 sakharuk 1596: if ($helper->{'VARS'}->{'construction'} ne '1') {
1.477 albertel 1597: my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
1598: $title = &Apache::lonxml::latex_special_symbols($title);
1599: $texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.343 albertel 1600: $texversion.=&path_to_problem($cleanURL,$LaTeXwidth);
1.245 sakharuk 1601: } else {
1602: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
1.343 albertel 1603: my $URLpath=$cleanURL;
1.245 sakharuk 1604: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
1.504 albertel 1605: $texversion.=&path_to_problem($URLpath,$LaTeXwidth);
1.245 sakharuk 1606: }
1.242 sakharuk 1607: $texversion.='\vskip 1 mm '.$answer.'\end{document}';
1608: }
1.511 foxr 1609:
1610:
1611:
1612:
1613: }
1614: # Print annotations.
1615:
1616:
1617: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1618: my $annotation .= &annotate($currentURL);
1619: $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
1.163 sakharuk 1620: }
1.511 foxr 1621:
1622:
1.214 sakharuk 1623: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1.215 sakharuk 1624: $texversion=&IndexCreation($texversion,$currentURL);
1.214 sakharuk 1625: }
1.219 sakharuk 1626: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
1627: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$currentURL| \\strut\\\\\\strut /;
1628:
1629: }
1.162 sakharuk 1630: $result .= $texversion;
1631: if ($currentURL=~m/\.page\s*$/) {
1632: ($result,$number_of_columns) = &page_cleanup($result);
1633: }
1.413 albertel 1634: } elsif ($cleanURL!~m|^/adm/|
1635: && $currentURL=~/\.sequence$/ && $helper->{'VARS'}->{'construction'} eq '1') {
1.227 sakharuk 1636: #printing content of sequence from the construction space
1637: $currentURL=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;
1.459 foxr 1638: $result .= &print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1639: $result .= &print_construction_sequence($currentURL, $helper, %form,
1640: $LaTeXwidth);
1641: $result .= '\end{document}';
1642: if (!($result =~ /\\begin\{document\}/)) {
1643: $result = &print_latex_header() . $result;
1.227 sakharuk 1644: }
1.459 foxr 1645: # End construction space sequence.
1.456 raeburn 1646: } elsif ($cleanURL=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.258 sakharuk 1647: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.298 sakharuk 1648: if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;}
1.375 foxr 1649: $resources_printed .= $currentURL.':';
1.515 foxr 1650: my $texversion=&ssi_with_retries($currentURL, $ssi_retry_count, %form);
1.511 foxr 1651: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1652: my $annotation = &annotate($currentURL);
1653: $texversion =~ s/(\\end{document})/$annotation$1/;
1654: }
1.258 sakharuk 1655: $result .= $texversion;
1.498 foxr 1656: } elsif ($cleanURL =~/.tex$/) {
1657: # For this sort of print of a single LaTeX file,
1658: # We can just print the LaTeX file as it is uninterpreted in any way:
1659: #
1660:
1661: $result = &fetch_raw_resource($currentURL);
1.511 foxr 1662: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1663: my $annotation = &annotate($currentURL);
1664: $result =~ s/(\\end{document})/$annotation$1/;
1665: }
1666:
1.499 foxr 1667: $do_postprocessing = 0; # Don't massage the result.
1.498 foxr 1668:
1.162 sakharuk 1669: } else {
1.414 albertel 1670: $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'},
1671: $helper->{'VARS'}->{'symb'});
1.162 sakharuk 1672: }
1.354 foxr 1673: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') or
1.142 sakharuk 1674: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or
1.354 foxr 1675: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') or
1676: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') or # BUGBUG
1.536 foxr 1677: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences')
1678: ) {
1.511 foxr 1679:
1680:
1.141 sakharuk 1681: #-- produce an output string
1.296 sakharuk 1682: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') {
1683: $selectionmade = 2;
1684: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') {
1685: $selectionmade = 3;
1.536 foxr 1686: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems')
1687: ) {
1.296 sakharuk 1688: $selectionmade = 4;
1.354 foxr 1689: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') { #BUGBUG
1690: $selectionmade = 4;
1.296 sakharuk 1691: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') {
1692: $selectionmade = 7;
1693: }
1.193 sakharuk 1694: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310 sakharuk 1695: $form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.203 sakharuk 1696: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309 sakharuk 1697: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 1698: $form{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1699: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
1700: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') ) {
1701: $form{'problem_split'}='yes';
1702: }
1.141 sakharuk 1703: my $flag_latex_header_remove = 'NO';
1704: my $flag_page_in_sequence = 'NO';
1705: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.193 sakharuk 1706: my $prevassignment='';
1.428 albertel 1707:
1708: &Apache::lonxml::clear_problem_counter();
1709:
1.416 foxr 1710: my $pbreakresources = keys %page_breaks;
1.141 sakharuk 1711: for (my $i=0;$i<=$#master_seq;$i++) {
1.350 foxr 1712:
1.521 foxr 1713: &Apache::lonenc::reset_enc();
1714:
1715:
1.350 foxr 1716: # Note due to document structure, not allowed to put \newpage
1717: # prior to the first resource
1718:
1.351 foxr 1719: if (defined $page_breaks{$master_seq[$i]}) {
1.350 foxr 1720: if($i != 0) {
1721: $result.="\\newpage\n";
1722: }
1723: }
1.521 foxr 1724: my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]);
1.237 albertel 1725: $urlp=&Apache::lonnet::clutter($urlp);
1.166 albertel 1726: $form{'symb'}=$master_seq[$i];
1.407 albertel 1727:
1.521 foxr 1728:
1.407 albertel 1729: my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem
1.521 foxr 1730:
1.267 sakharuk 1731: if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;}
1.247 sakharuk 1732: if ($i==0) {$prevassignment=$assignment;}
1.297 sakharuk 1733: my $texversion='';
1.413 albertel 1734: if ($urlp!~m|^/adm/|
1735: && $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 1736: $resources_printed .= $urlp.':';
1.428 albertel 1737: &Apache::lonxml::remember_problem_counter();
1.515 foxr 1738: $texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.296 sakharuk 1739: if ($urlp=~/\.page$/) {
1740: ($texversion,my $number_of_columns_page) = &page_cleanup($texversion);
1741: if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;}
1742: $texversion =~ s/\\end{document}\d*/\\end{document}/;
1743: $flag_page_in_sequence = 'YES';
1744: }
1.428 albertel 1745:
1.296 sakharuk 1746: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1747: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 1748: # Don't permanently pervert the %form hash
1749: my %answerform = %form;
1750: $answerform{'grade_target'}='answer';
1751: $answerform{'answer_output_mode'}='tex';
1.375 foxr 1752: $resources_printed .= $urlp.':';
1.428 albertel 1753:
1754: &Apache::lonxml::restore_problem_counter();
1.515 foxr 1755: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.428 albertel 1756:
1.296 sakharuk 1757: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
1758: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1.249 sakharuk 1759: } else {
1.307 sakharuk 1760: if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) {
1.296 sakharuk 1761: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477 albertel 1762: my $title = &Apache::lonnet::gettitle($master_seq[$i]);
1763: $title = &Apache::lonxml::latex_special_symbols($title);
1764: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.423 foxr 1765: $body .= &path_to_problem ($urlp,$LaTeXwidth);
1766: $body .='\vskip 1 mm '.$answer;
1767: $body = &encapsulate_minipage($body);
1768: $texversion .= $body;
1.296 sakharuk 1769: } else {
1770: $texversion='';
1771: }
1.249 sakharuk 1772: }
1.511 foxr 1773:
1.246 sakharuk 1774: }
1.511 foxr 1775: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1776: my $annotation .= &annotate($urlp);
1777: $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
1778: }
1779:
1.296 sakharuk 1780: if ($flag_latex_header_remove ne 'NO') {
1781: $texversion = &latex_header_footer_remove($texversion);
1782: } else {
1783: $texversion =~ s/\\end{document}//;
1784: }
1785: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1786: $texversion=&IndexCreation($texversion,$urlp);
1787: }
1788: if (($selectionmade == 4) and ($assignment ne $prevassignment)) {
1789: my $name = &get_name();
1790: my $courseidinfo = &get_course();
1791: $prevassignment=$assignment;
1.455 albertel 1792: my $header_text = $parmhash{'print_header_format'};
1.486 foxr 1793: $header_text = &format_page_header($textwidth, $header_text,
1.455 albertel 1794: $assignment,
1795: $courseidinfo,
1796: $name);
1.417 foxr 1797: if ($numberofcolumns eq '1') {
1.455 albertel 1798: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{'.$header_text.'}} \vskip 5 mm ';
1.416 foxr 1799: } else {
1.455 albertel 1800: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\fancyhead[LO]{'.$header_text.'}} \vskip 5 mm ';
1.416 foxr 1801: }
1.296 sakharuk 1802: }
1803: $result .= $texversion;
1804: $flag_latex_header_remove = 'YES';
1.456 raeburn 1805: } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.301 sakharuk 1806: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1807: if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;}
1.375 foxr 1808: $resources_printed .= $urlp.':';
1.515 foxr 1809: my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.511 foxr 1810: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1811: my $annotation = &annotate($urlp);
1812: $texversion =~ s/(\\end{document)/$annotation$1/;
1813: }
1814:
1.301 sakharuk 1815: if ($flag_latex_header_remove ne 'NO') {
1816: $texversion = &latex_header_footer_remove($texversion);
1817: } else {
1818: $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/;
1819: }
1820: $result .= $texversion;
1821: $flag_latex_header_remove = 'YES';
1.141 sakharuk 1822: } else {
1.414 albertel 1823: $texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'},
1824: $master_seq[$i]);
1.297 sakharuk 1825: if ($flag_latex_header_remove ne 'NO') {
1826: $texversion = &latex_header_footer_remove($texversion);
1827: } else {
1828: $texversion =~ s/\\end{document}//;
1829: }
1830: $result .= $texversion;
1831: $flag_latex_header_remove = 'YES';
1.296 sakharuk 1832: }
1.331 albertel 1833: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.141 sakharuk 1834: }
1.428 albertel 1835: &Apache::lonxml::clear_problem_counter();
1.344 foxr 1836: if ($flag_page_in_sequence eq 'YES') {
1837: $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;
1838: }
1.141 sakharuk 1839: $result .= '\end{document}';
1.284 albertel 1840: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1.536 foxr 1841: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ||
1.284 albertel 1842: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){
1.353 foxr 1843:
1844:
1.150 sakharuk 1845: #-- prints assignments for whole class or for selected students
1.284 albertel 1846: my $type;
1.536 foxr 1847: if (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1848: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ) {
1.254 sakharuk 1849: $selectionmade=5;
1.284 albertel 1850: $type='problems';
1.254 sakharuk 1851: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') {
1852: $selectionmade=8;
1.284 albertel 1853: $type='resources';
1.254 sakharuk 1854: }
1.150 sakharuk 1855: my @students=split /\|\|\|/, $helper->{'VARS'}->{'STUDENTS'};
1.341 foxr 1856: # The normal sort order is by section then by students within the
1857: # section. If the helper var student_sort is 1, then the user has elected
1858: # to override this and output the students by name.
1859: # Each element of the students array is of the form:
1860: # username:domain:section:last, first:status
1861: #
1.429 foxr 1862: # Note that student sort is not compatible with printing
1863: # 1 section per pdf...so that setting overrides.
1.341 foxr 1864: #
1.429 foxr 1865: if (($helper->{'VARS'}->{'student_sort'} eq 1) &&
1866: ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) {
1.341 foxr 1867: @students = sort compare_names @students;
1868: }
1.429 foxr 1869: &adjust_number_to_print($helper);
1870:
1.278 albertel 1871: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq '0' ||
1872: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'all' ) {
1873: $helper->{'VARS'}->{'NUMBER_TO_PRINT'}=$#students+1;
1874: }
1.429 foxr 1875: # If we are splitting on section boundaries, we need
1876: # to remember that in split_on_sections and
1877: # print all of the students in the list.
1878: #
1879: my $split_on_sections = 0;
1880: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'section') {
1881: $split_on_sections = 1;
1882: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1;
1883: }
1.150 sakharuk 1884: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.350 foxr 1885:
1.150 sakharuk 1886: #loop over students
1887: my $flag_latex_header_remove = 'NO';
1888: my %moreenv;
1.330 sakharuk 1889: $moreenv{'instructor_comments'}='hide';
1.285 albertel 1890: $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth);
1.309 sakharuk 1891: $moreenv{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 1892: $moreenv{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1.353 foxr 1893: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'};
1.369 foxr 1894: $moreenv{'suppress_tries'} = $parmhash{'suppress_tries'};
1.511 foxr 1895: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
1896: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
1897: $moreenv{'problem_split'}='yes';
1898: }
1.318 albertel 1899: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75');
1.272 sakharuk 1900: my $student_counter=-1;
1.429 foxr 1901: my $i = 0;
1.430 albertel 1902: my $last_section = (split(/:/,$students[0]))[2];
1.150 sakharuk 1903: foreach my $person (@students) {
1.350 foxr 1904:
1.373 albertel 1905: my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";
1.311 sakharuk 1906: if (-e $duefile) {
1907: my $temp_file = Apache::File->new('>>'.$duefile);
1908: print $temp_file "1969\n";
1909: }
1.272 sakharuk 1910: $student_counter++;
1.429 foxr 1911: if ($split_on_sections) {
1.430 albertel 1912: my $this_section = (split(/:/,$person))[2];
1.429 foxr 1913: if ($this_section ne $last_section) {
1914: $i++;
1915: $last_section = $this_section;
1916: }
1917: } else {
1918: $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'});
1919: }
1.375 foxr 1920: my ($output,$fullname, $printed)=&print_resources($r,$helper,
1.353 foxr 1921: $person,$type,
1922: \%moreenv,\@master_seq,
1.360 albertel 1923: $flag_latex_header_remove,
1.422 albertel 1924: $LaTeXwidth);
1.375 foxr 1925: $resources_printed .= ":";
1.284 albertel 1926: $print_array[$i].=$output;
1927: $student_names[$i].=$person.':'.$fullname.'_END_';
1928: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname);
1929: $flag_latex_header_remove = 'YES';
1.331 albertel 1930: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 1931: }
1932: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
1933: $result .= $print_array[0].' \end{document}';
1934: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon') ||
1935: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon') ) {
1.373 albertel 1936: my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
1937: my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
1.288 albertel 1938: my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'};
1939: my $code_name=$helper->{'VARS'}->{'ANON_CODE_STORAGE_NAME'};
1.292 albertel 1940: my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'};
1.385 foxr 1941: my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'};
1.388 foxr 1942: my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'};
1943:
1.381 albertel 1944: my $code_option=$helper->{'VARS'}->{'CODE_OPTION'};
1945: open(FH,$Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
1946: my ($code_type,$code_length)=('letter',6);
1947: foreach my $line (<FH>) {
1948: my ($name,$type,$length) = (split(/:/,$line))[0,2,4];
1949: if ($name eq $code_option) {
1950: $code_length=$length;
1951: if ($type eq 'number') { $code_type = 'number'; }
1952: }
1953: }
1.288 albertel 1954: my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth));
1.353 foxr 1955: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'};
1.420 albertel 1956: $moreenv{'instructor_comments'}='hide';
1.288 albertel 1957: my $seed=time+($$<<16)+($$);
1.292 albertel 1958: my @allcodes;
1959: if ($old_name) {
1.381 albertel 1960: my %result=&Apache::lonnet::get('CODEs',
1961: [$old_name,"type\0$old_name"],
1962: $cdom,$cnum);
1963: $code_type=$result{"type\0$old_name"};
1.292 albertel 1964: @allcodes=split(',',$result{$old_name});
1.336 albertel 1965: $num_todo=scalar(@allcodes);
1.389 foxr 1966: } elsif ($selected_code) { # Selection value is always numeric.
1.388 foxr 1967: $num_todo = 1;
1968: @allcodes = ($selected_code);
1.385 foxr 1969: } elsif ($single_code) {
1970:
1.387 foxr 1971: $num_todo = 1; # Unconditionally one code to do.
1.385 foxr 1972: # If an alpha code have to convert to numbers so it can be
1973: # converted back to letters again :-)
1974: #
1975: if ($code_type ne 'number') {
1976: $single_code = &letters_to_num($single_code);
1977: }
1978: @allcodes = ($single_code);
1.292 albertel 1979: } else {
1980: my %allcodes;
1.299 albertel 1981: srand($seed);
1.292 albertel 1982: for (my $i=0;$i<$num_todo;$i++) {
1.381 albertel 1983: $moreenv{'CODE'}=&get_CODE(\%allcodes,$i,$seed,$code_length,
1984: $code_type);
1.292 albertel 1985: }
1986: if ($code_name) {
1987: &Apache::lonnet::put('CODEs',
1.381 albertel 1988: {
1989: $code_name =>join(',',keys(%allcodes)),
1990: "type\0$code_name" => $code_type
1991: },
1.292 albertel 1992: $cdom,$cnum);
1993: }
1994: @allcodes=keys(%allcodes);
1995: }
1.336 albertel 1996: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1997: my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'});
1.452 albertel 1998: &adjust_number_to_print($helper);
1.336 albertel 1999: my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'};
2000: if ($number_per_page eq '0' || $number_per_page eq 'all') {
2001: $number_per_page=$num_todo;
2002: }
2003: my $flag_latex_header_remove = 'NO';
2004: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75');
1.295 albertel 2005: my $count=0;
1.292 albertel 2006: foreach my $code (sort(@allcodes)) {
1.295 albertel 2007: my $file_num=int($count/$number_per_page);
1.381 albertel 2008: if ($code_type eq 'number') {
2009: $moreenv{'CODE'}=$code;
2010: } else {
2011: $moreenv{'CODE'}=&num_to_letters($code);
2012: }
1.375 foxr 2013: my ($output,$fullname, $printed)=
1.288 albertel 2014: &print_resources($r,$helper,'anonymous',$type,\%moreenv,
1.360 albertel 2015: \@master_seq,$flag_latex_header_remove,
2016: $LaTeXwidth);
1.375 foxr 2017: $resources_printed .= ":";
1.295 albertel 2018: $print_array[$file_num].=$output;
1.288 albertel 2019: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
2020: &mt('last assignment').' '.$fullname);
2021: $flag_latex_header_remove = 'YES';
1.295 albertel 2022: $count++;
1.331 albertel 2023: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.288 albertel 2024: }
2025: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
2026: $result .= $print_array[0].' \end{document}';
2027: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') {
1.151 sakharuk 2028: #prints selected problems from the subdirectory
2029: $selectionmade = 6;
2030: my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};
1.154 sakharuk 2031: @list_of_files=sort @list_of_files;
1.175 sakharuk 2032: my $flag_latex_header_remove = 'NO';
2033: my $rndseed=time;
1.230 albertel 2034: if ($helper->{'VARS'}->{'curseed'}) {
2035: $rndseed=$helper->{'VARS'}->{'curseed'};
2036: }
1.151 sakharuk 2037: for (my $i=0;$i<=$#list_of_files;$i++) {
1.521 foxr 2038:
2039: &Apache::lonenc::reset_enc();
2040:
1.152 sakharuk 2041: my $urlp = $list_of_files[$i];
1.253 sakharuk 2042: $urlp=~s|//|/|;
1.152 sakharuk 2043: if ($urlp=~/\//) {
1.353 foxr 2044: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.175 sakharuk 2045: $form{'rndseed'}=$rndseed;
1.152 sakharuk 2046: if ($urlp =~ m|/home/([^/]+)/public_html|) {
2047: $urlp =~ s|/home/([^/]*)/public_html|/~$1|;
2048: } else {
1.302 sakharuk 2049: $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;
1.152 sakharuk 2050: }
1.375 foxr 2051: $resources_printed .= $urlp.':';
1.515 foxr 2052: my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.251 sakharuk 2053: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1.253 sakharuk 2054: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2055: # Don't permanently pervert %form:
2056: my %answerform = %form;
2057: $answerform{'grade_target'}='answer';
2058: $answerform{'answer_output_mode'}='tex';
2059: $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
2060: $answerform{'rndseed'}=$rndseed;
1.375 foxr 2061: $resources_printed .= $urlp.':';
1.515 foxr 2062: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.251 sakharuk 2063: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2064: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
2065: } else {
1.253 sakharuk 2066: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
2067: if ($helper->{'VARS'}->{'construction'} ne '1') {
2068: $texversion.='\vskip 0 mm \noindent ';
2069: $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
2070: } else {
2071: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
2072: my $URLpath=$urlp;
2073: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
2074: $texversion.=&path_to_problem ($URLpath,$LaTeXwidth);
2075: }
2076: $texversion.='\vskip 1 mm '.$answer.'\end{document}';
1.251 sakharuk 2077: }
1.174 sakharuk 2078: }
1.515 foxr 2079: #this chunk is responsible for printing the path to problem
2080:
1.253 sakharuk 2081: my $newurlp=$urlp;
2082: if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;}
2083: $newurlp=&path_to_problem($newurlp,$LaTeXwidth);
1.242 sakharuk 2084: $texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;
1.152 sakharuk 2085: if ($flag_latex_header_remove ne 'NO') {
2086: $texversion = &latex_header_footer_remove($texversion);
2087: } else {
2088: $texversion =~ s/\\end{document}//;
1.216 sakharuk 2089: }
2090: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
2091: $texversion=&IndexCreation($texversion,$urlp);
1.152 sakharuk 2092: }
1.219 sakharuk 2093: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
2094: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
2095:
2096: }
1.152 sakharuk 2097: $result .= $texversion;
2098: }
2099: $flag_latex_header_remove = 'YES';
1.151 sakharuk 2100: }
1.175 sakharuk 2101: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;}
1.152 sakharuk 2102: $result .= '\end{document}';
1.140 sakharuk 2103: }
2104: #-------------------------------------------------------- corrections for the different page formats
1.499 foxr 2105:
2106: # Only post process if that has not been turned off e.g. by a raw latex resource.
2107:
2108: if ($do_postprocessing) {
2109: $result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade);
2110: $result = &latex_corrections($number_of_columns,$result,$selectionmade,
2111: $helper->{'VARS'}->{'ANSWER_TYPE'});
2112: #if ($numberofcolumns == 1) {
1.451 albertel 2113: $result =~ s/\\textwidth\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /;
2114: $result =~ s/\\textheight\s*=?\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /;
2115: $result =~ s/\\evensidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
2116: $result =~ s/\\oddsidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
1.499 foxr 2117: #}
2118: }
1.367 foxr 2119:
1.515 foxr 2120: # Set URLback if this is a construction space print so we can provide
2121: # a link to the resource being edited.
2122: #
1.274 sakharuk 2123:
1.276 sakharuk 2124: my $URLback=''; #link to original document
1.510 albertel 2125: if ($helper->{'VARS'}->{'construction'} eq '1') {
1.276 sakharuk 2126: #prints resource from the construction space
2127: $URLback='/'.$helper->{'VARS'}->{'filename'};
1.279 albertel 2128: if ($URLback=~/([^?]+)/) {
2129: $URLback=$1;
2130: $URLback=~s|^/~|/priv/|;
2131: }
1.276 sakharuk 2132: }
1.375 foxr 2133:
1.525 www 2134: #-- writing .tex file in prtspool
2135: my $temp_file;
2136: my $identifier = &Apache::loncommon::get_cgi_id();
2137: my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex";
2138: if (!($#print_array>0)) {
2139: unless ($temp_file = Apache::File->new('>'.$filename)) {
2140: $r->log_error("Couldn't open $filename for output $!");
2141: return SERVER_ERROR;
2142: }
2143: print $temp_file $result;
2144: my $begin=index($result,'\begin{document}',0);
2145: my $inc=substr($result,0,$begin+16);
1.515 foxr 2146: } else {
1.525 www 2147: my $begin=index($result,'\begin{document}',0);
2148: my $inc=substr($result,0,$begin+16);
2149: for (my $i=0;$i<=$#print_array;$i++) {
2150: if ($i==0) {
2151: $print_array[$i]=$result;
2152: } else {
2153: $print_array[$i].='\end{document}';
2154: $print_array[$i] =
2155: &latex_corrections($number_of_columns,$print_array[$i],
2156: $selectionmade,
2157: $helper->{'VARS'}->{'ANSWER_TYPE'});
1.515 foxr 2158:
1.525 www 2159: my $anobegin=index($print_array[$i],'\setcounter{page}',0);
2160: substr($print_array[$i],0,$anobegin)='';
2161: $print_array[$i]=$inc.$print_array[$i];
2162: }
2163: my $temp_file;
2164: my $newfilename=$filename;
2165: my $num=$i+1;
2166: $newfilename =~s/\.tex$//;
2167: $newfilename=sprintf("%s_%03d.tex",$newfilename, $num);
2168: unless ($temp_file = Apache::File->new('>'.$newfilename)) {
2169: $r->log_error("Couldn't open $newfilename for output $!");
2170: return SERVER_ERROR;
2171: }
2172: print $temp_file $print_array[$i];
2173: }
2174: }
2175: my $student_names='';
2176: if ($#print_array>0) {
2177: for (my $i=0;$i<=$#print_array;$i++) {
2178: $student_names.=$student_names[$i].'_ENDPERSON_';
1.515 foxr 2179: }
1.525 www 2180: } else {
2181: if ($#student_names>-1) {
2182: $student_names=$student_names[0].'_ENDPERSON_';
1.515 foxr 2183: } else {
1.525 www 2184: my $fullname = &get_name($env{'user.name'},$env{'user.domain'});
2185: $student_names=join(':',$env{'user.name'},$env{'user.domain'},
1.515 foxr 2186: $env{'request.course.sec'},$fullname).
2187: '_ENDPERSON_'.'_END_';
2188: }
1.525 www 2189: }
1.515 foxr 2190:
1.525 www 2191: # logic for now is too complex to trace if this has been defined
2192: # yet.
2193: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
2194: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2195: &Apache::lonnet::appenv({'cgi.'.$identifier.'.file' => $filename,
1.515 foxr 2196: 'cgi.'.$identifier.'.layout' => $laystyle,
2197: 'cgi.'.$identifier.'.numcol' => $numberofcolumns,
2198: 'cgi.'.$identifier.'.paper' => $papersize,
2199: 'cgi.'.$identifier.'.selection' => $selectionmade,
2200: 'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
2201: 'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
2202: 'cgi.'.$identifier.'.role' => $perm{'pav'},
2203: 'cgi.'.$identifier.'.numberoffiles' => $#print_array,
2204: 'cgi.'.$identifier.'.studentnames' => $student_names,
1.520 raeburn 2205: 'cgi.'.$identifier.'.backref' => $URLback,});
1.525 www 2206: &Apache::lonnet::appenv({"cgi.$identifier.user" => $env{'user.name'},
1.515 foxr 2207: "cgi.$identifier.domain" => $env{'user.domain'},
2208: "cgi.$identifier.courseid" => $cnum,
2209: "cgi.$identifier.coursedom" => $cdom,
1.520 raeburn 2210: "cgi.$identifier.resources" => $resources_printed});
1.515 foxr 2211:
1.525 www 2212: my $end_page = &Apache::loncommon::end_page();
1.529 raeburn 2213: my $continue_text = &mt('Continue');
1.525 www 2214: # If there's been an unrecoverable SSI error, report it to the user
2215: if ($ssi_error) {
2216: my $helpurl = &Apache::loncommon::top_nav_help('Helpdesk');
2217: $r->print('<br /><h2>'.&mt('An unrecoverable network error occurred:').'</h2><p> '.
1.526 www 2218: &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:').
2219: '<br />'.$ssi_last_error_resource.'<br />'.$ssi_last_error.
2220: '</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 2221: &mt('You may be able to reprint the individual resources for which this error occurred, as the issue may be temporary.').
1.525 www 2222: '<br />'.&mt('If the error persists, please contact the [_1] for assistance.',$helpurl).'</p><p>'.
2223: &mt('We apologize for the inconvenience.').'</p>'.
1.528 raeburn 2224: '<a href="/cgi-bin/printout.pl?'.$identifier.'">'.$continue_text.'</a>'.$end_page);
1.525 www 2225: } else {
1.515 foxr 2226: $r->print(<<FINALEND);
1.317 albertel 2227: <br />
1.288 albertel 2228: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.528 raeburn 2229: <a href="/cgi-bin/printout.pl?$identifier">$continue_text</a>
1.431 albertel 2230: $end_page
1.140 sakharuk 2231: FINALEND
1.528 raeburn 2232: } # endif ssi errors.
1.140 sakharuk 2233: }
2234:
1.288 albertel 2235:
2236: sub get_CODE {
1.381 albertel 2237: my ($all_codes,$num,$seed,$size,$type)=@_;
1.288 albertel 2238: my $max='1'.'0'x$size;
2239: my $newcode;
2240: while(1) {
1.392 albertel 2241: $newcode=sprintf("%0".$size."d",int(rand($max)));
1.288 albertel 2242: if (!exists($$all_codes{$newcode})) {
2243: $$all_codes{$newcode}=1;
1.381 albertel 2244: if ($type eq 'number' ) {
2245: return $newcode;
2246: } else {
2247: return &num_to_letters($newcode);
2248: }
1.288 albertel 2249: }
2250: }
2251: }
1.140 sakharuk 2252:
1.284 albertel 2253: sub print_resources {
1.360 albertel 2254: my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422 albertel 2255: $LaTeXwidth)=@_;
1.284 albertel 2256: my $current_output = '';
1.375 foxr 2257: my $printed = '';
1.284 albertel 2258: my ($username,$userdomain,$usersection) = split /:/,$person;
2259: my $fullname = &get_name($username,$userdomain);
1.492 foxr 2260: my $namepostfix = "\\\\"; # Both anon and not anon should get the same vspace.
1.288 albertel 2261: if ($person =~ 'anon') {
1.492 foxr 2262: $namepostfix .="Name: ";
1.288 albertel 2263: $fullname = "CODE - ".$moreenv->{'CODE'};
2264: }
1.444 foxr 2265: # Fullname may have special latex characters that need \ prefixing:
2266: #
2267:
1.350 foxr 2268: my $i = 0;
1.284 albertel 2269: #goes through all resources, checks if they are available for
2270: #current student, and produces output
1.428 albertel 2271:
2272: &Apache::lonxml::clear_problem_counter();
1.364 albertel 2273: my %page_breaks = &get_page_breaks($helper);
1.476 albertel 2274: my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440 foxr 2275: #
1.441 foxr 2276: # end each student with a
1.440 foxr 2277: # Special that allows the post processor to even out the page
2278: # counts later. Nasty problem this... it would be really
2279: # nice to put the special in as a postscript comment
1.441 foxr 2280: # e.g. \special{ps:\ENDOFSTUDENTSTAMP} unfortunately,
1.440 foxr 2281: # The special gets passed the \ and dvips puts it in the output file
1.441 foxr 2282: # so we will just rely on prntout.pl to strip ENDOFSTUDENTSTAMP from the
2283: # postscript. Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440 foxr 2284: #
1.363 foxr 2285:
1.511 foxr 2286:
1.284 albertel 2287: foreach my $curresline (@{$master_seq}) {
1.351 foxr 2288: if (defined $page_breaks{$curresline}) {
1.350 foxr 2289: if($i != 0) {
2290: $current_output.= "\\newpage\n";
2291: }
2292: }
2293: $i++;
1.511 foxr 2294:
1.284 albertel 2295: if ( !($type eq 'problems' &&
2296: ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
2297: my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
2298: if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414 albertel 2299: if ($res_url!~m|^ext/|
1.413 albertel 2300: && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 2301: $printed .= $curresline.':';
1.428 albertel 2302:
2303: &Apache::lonxml::remember_problem_counter();
2304:
1.526 www 2305: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428 albertel 2306:
1.305 sakharuk 2307: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
2308: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2309: # Use a copy of the hash so we don't pervert it on future loop passes.
2310: my %answerenv = %{$moreenv};
2311: $answerenv{'answer_output_mode'}='tex';
2312: $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428 albertel 2313:
2314: &Apache::lonxml::restore_problem_counter();
2315:
1.380 foxr 2316: my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428 albertel 2317:
1.305 sakharuk 2318: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2319: $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
2320: } else {
1.423 foxr 2321:
2322:
2323: my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477 albertel 2324: my $title = &Apache::lonnet::gettitle($curresline);
2325: $title = &Apache::lonxml::latex_special_symbols($title);
2326: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
2327: $body .=&path_to_problem($res_url,$LaTeXwidth);
1.423 foxr 2328: $body .='\vskip 1 mm '.$ansrendered;
2329: $body = &encapsulate_minipage($body);
2330: $rendered = $header.$body;
1.305 sakharuk 2331: }
2332: }
1.511 foxr 2333:
2334: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2335: my $url = &Apache::lonnet::clutter($res_url);
2336: my $annotation = &annotate($url);
2337: $rendered =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
2338: }
1.305 sakharuk 2339: if ($remove_latex_header eq 'YES') {
2340: $rendered = &latex_header_footer_remove($rendered);
2341: } else {
2342: $rendered =~ s/\\end{document}//;
2343: }
2344: $current_output .= $rendered;
1.456 raeburn 2345: } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.375 foxr 2346: $printed .= $curresline.':';
1.528 raeburn 2347: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.511 foxr 2348: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2349: my $url = &Apache::lonnet::clutter($res_url);
2350: my $annotation = &annotate($url);
2351: $annotation =~ s/(\\end{document})/$annotation$1/;
2352: }
1.305 sakharuk 2353: if ($remove_latex_header eq 'YES') {
2354: $rendered = &latex_header_footer_remove($rendered);
1.284 albertel 2355: } else {
1.305 sakharuk 2356: $rendered =~ s/\\end{document}//;
1.284 albertel 2357: }
1.421 foxr 2358: $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
2359:
1.284 albertel 2360: } else {
1.414 albertel 2361: my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305 sakharuk 2362: if ($remove_latex_header ne 'NO') {
2363: $rendered = &latex_header_footer_remove($rendered);
2364: } else {
2365: $rendered =~ s/\\end{document}//;
2366: }
2367: $current_output .= $rendered;
1.284 albertel 2368: }
2369: }
2370: $remove_latex_header = 'YES';
2371: }
1.331 albertel 2372: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 2373: }
2374: my $courseidinfo = &get_course();
2375: my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476 albertel 2376: my $header_line =
1.486 foxr 2377: &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.537 foxr 2378: $currentassignment, $courseidinfo, $fullname, $usersection);
1.476 albertel 2379: my $header_start = ($columns_in_format == 1) ? '\lhead'
2380: : '\fancyhead[LO]';
2381: $header_line = $header_start.'{'.$header_line.'}';
2382:
1.284 albertel 2383: if ($current_output=~/\\documentclass/) {
1.476 albertel 2384: $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.284 albertel 2385: } else {
1.476 albertel 2386: my $blankpages =
2387: '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
2388:
2389: $current_output = '\strut\vspace*{-6 mm}\\newline'.
2390: ©right_line().' \newpage '.$blankpages.$end_of_student.
2391: '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
2392: $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284 albertel 2393: }
1.440 foxr 2394: #
2395: # Close the student bracketing.
2396: #
1.375 foxr 2397: return ($current_output,$fullname, $printed);
1.284 albertel 2398:
2399: }
1.140 sakharuk 2400:
1.3 sakharuk 2401: sub handler {
2402:
2403: my $r = shift;
1.397 albertel 2404:
2405: &init_perm();
1.114 bowersj2 2406:
1.416 foxr 2407:
1.67 www 2408:
1.397 albertel 2409: my $helper = printHelper($r);
2410: if (!ref($helper)) {
2411: return $helper;
1.60 sakharuk 2412: }
1.177 sakharuk 2413:
1.184 sakharuk 2414:
1.454 foxr 2415: %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353 foxr 2416:
1.416 foxr 2417:
1.350 foxr 2418:
2419:
1.367 foxr 2420: # If a figure conversion queue file exists for this user.domain
2421: # we delete it since it can only be bad (if it were good, printout.pl
2422: # would have deleted it the last time around.
2423:
1.373 albertel 2424: my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367 foxr 2425: if(-e $conversion_queuefile) {
2426: unlink $conversion_queuefile;
2427: }
1.515 foxr 2428:
2429:
1.184 sakharuk 2430: &output_data($r,$helper,\%parmhash);
1.2 sakharuk 2431: return OK;
1.60 sakharuk 2432: }
1.2 sakharuk 2433:
1.131 bowersj2 2434: use Apache::lonhelper;
1.130 sakharuk 2435:
1.223 bowersj2 2436: sub addMessage {
2437: my $text = shift;
2438: my $paramHash = Apache::lonhelper::getParamHash();
2439: $paramHash->{MESSAGE_TEXT} = $text;
2440: Apache::lonhelper::message->new();
2441: }
2442:
1.416 foxr 2443:
1.238 bowersj2 2444:
1.397 albertel 2445: sub init_perm {
2446: undef(%perm);
2447: $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
2448: if (!$perm{'pav'}) {
2449: $perm{'pav'}=&Apache::lonnet::allowed('pav',
2450: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2451: }
1.465 albertel 2452: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397 albertel 2453: if (!$perm{'pfo'}) {
2454: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',
2455: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2456: }
2457: }
2458:
1.507 albertel 2459: sub get_randomly_ordered_warning {
2460: my ($helper,$map) = @_;
2461:
2462: my $message;
2463:
2464: my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
2465: my $navmap = Apache::lonnavmaps::navmap->new();
2466: my $res = $navmap->getResourceByUrl($map);
2467: if ($res) {
2468: my $func =
2469: sub { return ($_[0]->is_map() && $_[0]->randomorder); };
2470: my @matches = $navmap->retrieveResources($res, $func,1,1,1);
2471: if (@matches) {
1.508 albertel 2472: $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 2473: }
2474: }
2475: if ($message) {
2476: return '<message type="warning">'.$message.'</message>';
2477: }
2478: return;
2479: }
2480:
1.131 bowersj2 2481: sub printHelper {
1.115 bowersj2 2482: my $r = shift;
2483:
2484: if ($r->header_only) {
1.373 albertel 2485: if ($env{'browser.mathml'}) {
1.241 www 2486: &Apache::loncommon::content_type($r,'text/xml');
1.131 bowersj2 2487: } else {
1.241 www 2488: &Apache::loncommon::content_type($r,'text/html');
1.131 bowersj2 2489: }
2490: $r->send_http_header;
2491: return OK;
1.115 bowersj2 2492: }
2493:
1.131 bowersj2 2494: # Send header, nocache
1.373 albertel 2495: if ($env{'browser.mathml'}) {
1.241 www 2496: &Apache::loncommon::content_type($r,'text/xml');
1.115 bowersj2 2497: } else {
1.241 www 2498: &Apache::loncommon::content_type($r,'text/html');
1.115 bowersj2 2499: }
2500: &Apache::loncommon::no_cache($r);
2501: $r->send_http_header;
2502: $r->rflush();
2503:
1.131 bowersj2 2504: # Unfortunately, this helper is so complicated we have to
2505: # write it by hand
2506:
2507: Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
2508:
1.176 bowersj2 2509: my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146 bowersj2 2510: $helper->declareVar('symb');
1.156 bowersj2 2511: $helper->declareVar('postdata');
1.290 sakharuk 2512: $helper->declareVar('curseed');
2513: $helper->declareVar('probstatus');
1.156 bowersj2 2514: $helper->declareVar('filename');
2515: $helper->declareVar('construction');
1.178 sakharuk 2516: $helper->declareVar('assignment');
1.262 sakharuk 2517: $helper->declareVar('style_file');
1.340 foxr 2518: $helper->declareVar('student_sort');
1.363 foxr 2519: $helper->declareVar('FINISHPAGE');
1.366 foxr 2520: $helper->declareVar('PRINT_TYPE');
1.372 foxr 2521: $helper->declareVar("showallfoils");
1.483 foxr 2522: $helper->declareVar("STUDENTS");
1.363 foxr 2523:
1.518 foxr 2524:
2525:
2526:
2527:
1.363 foxr 2528: # The page breaks can get loaded initially from the course environment:
1.394 foxr 2529: # But we only do this in the initial state so that they are allowed to change.
2530: #
1.366 foxr 2531:
1.416 foxr 2532: # $helper->{VARS}->{FINISHPAGE} = '';
1.363 foxr 2533:
2534: &Apache::loncommon::restore_course_settings('print',
1.366 foxr 2535: {'pagebreaks' => 'scalar',
2536: 'lastprinttype' => 'scalar'});
2537:
1.483 foxr 2538: # This will persistently load in the data we want from the
2539: # very first screen.
1.394 foxr 2540:
2541: if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
2542: if (!defined ($env{"form.CURRENT_STATE"})) {
2543:
2544: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
2545: } else {
2546: my $state = $env{"form.CURRENT_STATE"};
2547: if ($state eq "START") {
2548: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
2549: }
2550: }
2551:
1.366 foxr 2552: }
1.481 albertel 2553:
1.483 foxr 2554:
1.156 bowersj2 2555: # Detect whether we're coming from construction space
1.373 albertel 2556: if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235 bowersj2 2557: $helper->{VARS}->{'filename'} = "~$1/$2";
1.156 bowersj2 2558: $helper->{VARS}->{'construction'} = 1;
1.481 albertel 2559: } else {
1.373 albertel 2560: if ($env{'form.postdata'}) {
2561: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482 albertel 2562: if ( $helper->{VARS}->{'symb'} eq '') {
2563: $helper->{VARS}->{'postdata'} = $env{'form.postdata'};
2564: }
1.156 bowersj2 2565: }
1.373 albertel 2566: if ($env{'form.symb'}) {
2567: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156 bowersj2 2568: }
1.373 albertel 2569: if ($env{'form.url'}) {
1.156 bowersj2 2570: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
2571: }
1.416 foxr 2572:
1.157 bowersj2 2573: }
1.481 albertel 2574:
1.373 albertel 2575: if ($env{'form.symb'}) {
2576: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146 bowersj2 2577: }
1.373 albertel 2578: if ($env{'form.url'}) {
1.140 sakharuk 2579: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153 sakharuk 2580:
1.140 sakharuk 2581: }
1.343 albertel 2582: $helper->{VARS}->{'symb'}=
2583: &Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335 albertel 2584: my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178 sakharuk 2585: if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481 albertel 2586:
1.156 bowersj2 2587:
1.146 bowersj2 2588: # Extract map
2589: my $symb = $helper->{VARS}->{'symb'};
1.156 bowersj2 2590: my ($map, $id, $url);
2591: my $subdir;
1.483 foxr 2592: my $is_published=0; # True when printing from resource space.
1.156 bowersj2 2593:
2594: # Get the resource name from construction space
2595: if ($helper->{VARS}->{'construction'}) {
2596: $resourceTitle = substr($helper->{VARS}->{'filename'},
2597: rindex($helper->{VARS}->{'filename'}, '/')+1);
2598: $subdir = substr($helper->{VARS}->{'filename'},
2599: 0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481 albertel 2600: } else {
1.482 albertel 2601: if ($symb ne '') {
2602: ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
2603: $helper->{VARS}->{'postdata'} =
2604: &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
2605: } else {
2606: $url = $helper->{VARS}->{'postdata'};
1.483 foxr 2607: $is_published=1; # From resource space.
1.482 albertel 2608: }
2609: $url = &Apache::lonnet::clutter($url);
1.481 albertel 2610:
1.156 bowersj2 2611: if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238 bowersj2 2612: my $postdata = $helper->{VARS}->{'postdata'};
2613: $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156 bowersj2 2614: }
2615: $subdir = &Apache::lonnet::filelocation("", $url);
1.128 bowersj2 2616: }
1.373 albertel 2617: if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
2618: $helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230 albertel 2619: }
1.373 albertel 2620: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
1.512 foxr 2621: $helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
1.290 sakharuk 2622: }
1.115 bowersj2 2623:
1.192 bowersj2 2624: my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
2625:
1.481 albertel 2626: Apache::lonhelper::registerHelperTags();
1.119 bowersj2 2627:
1.131 bowersj2 2628: # "Delete everything after the last slash."
1.119 bowersj2 2629: $subdir =~ s|/[^/]+$||;
2630:
1.131 bowersj2 2631: # What can be printed is a very dynamic decision based on
2632: # lots of factors. So we need to dynamically build this list.
2633: # To prevent security leaks, states are only added to the wizard
2634: # if they can be reached, which ensures manipulating the form input
2635: # won't allow anyone to reach states they shouldn't have permission
2636: # to reach.
2637:
2638: # printChoices is tracking the kind of printing the user can
2639: # do, and will be used in a choices construction later.
2640: # In the meantime we will be adding states and elements to
2641: # the helper by hand.
2642: my $printChoices = [];
2643: my $paramHash;
1.130 sakharuk 2644:
1.240 albertel 2645: if ($resourceTitle) {
1.458 www 2646: push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156 bowersj2 2647: }
2648:
1.238 bowersj2 2649: # Useful filter strings
1.540 ! raeburn 2650: my $isProblem = '($res->is_problem()||$res->contains_problem||$res->is_practice()) ';
1.238 bowersj2 2651: $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.287 albertel 2652: my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence()';
2653: my $isNotMap = '!$res->is_sequence()';
1.238 bowersj2 2654: $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
2655: my $isMap = '$res->is_map()';
1.342 albertel 2656: my $symbFilter = '$res->shown_symb()';
2657: my $urlValue = '$res->link()';
1.238 bowersj2 2658:
2659: $helper->declareVar('SEQUENCE');
2660:
1.465 albertel 2661: # If we're in a sequence...
1.416 foxr 2662:
1.465 albertel 2663: my $start_new_option;
2664: if ($perm{'pav'}) {
2665: $start_new_option =
2666: "<option text='".&mt('Start new page<br />before selected').
2667: "' variable='FINISHPAGE' />";
2668: }
1.238 bowersj2 2669:
1.483 foxr 2670: if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
1.350 foxr 2671:
1.243 bowersj2 2672: $helper->{VARS}->{'postdata'} &&
2673: $helper->{VARS}->{'assignment'}) {
1.131 bowersj2 2674: # Allow problems from sequence
1.458 www 2675: push @{$printChoices}, [&mt('Selected <b>Problems</b> in folder <b><i>[_1]</i></b>',$sequenceTitle), 'map_problems', 'CHOOSE_PROBLEMS'];
1.131 bowersj2 2676: # Allow all resources from sequence
1.458 www 2677: push @{$printChoices}, [&mt('Selected <b>Resources</b> in folder <b><i>[_1]</i></b>',$sequenceTitle), 'map_problems_pages', 'CHOOSE_PROBLEMS_HTML'];
1.465 albertel 2678:
1.131 bowersj2 2679: my $helperFragment = <<HELPERFRAGMENT;
1.155 sakharuk 2680: <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print">
1.435 foxr 2681: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2682: closeallpages="1">
1.144 bowersj2 2683: <nextstate>PAGESIZE</nextstate>
1.435 foxr 2684: <filterfunc>return $isProblem;</filterfunc>
1.131 bowersj2 2685: <mapurl>$map</mapurl>
1.238 bowersj2 2686: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2687: $start_new_option
1.131 bowersj2 2688: </resource>
2689: </state>
2690:
1.155 sakharuk 2691: <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print">
1.435 foxr 2692: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2693: closeallpages="1">
1.144 bowersj2 2694: <nextstate>PAGESIZE</nextstate>
1.435 foxr 2695: <filterfunc>return $isNotMap;</filterfunc>
1.131 bowersj2 2696: <mapurl>$map</mapurl>
1.238 bowersj2 2697: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2698: $start_new_option
1.131 bowersj2 2699: </resource>
2700: </state>
2701: HELPERFRAGMENT
1.121 bowersj2 2702:
1.326 sakharuk 2703: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121 bowersj2 2704: }
2705:
1.397 albertel 2706: # If the user has pfo (print for otheres) allow them to print all
1.354 foxr 2707: # problems and resources in the entier course, optionally for selected students
1.483 foxr 2708: if ($perm{'pfo'} && !$is_published &&
1.481 albertel 2709: ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) {
2710:
1.509 albertel 2711: push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
2712: push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.536 foxr 2713: 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 2714: &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS);
1.155 sakharuk 2715: <state name="ALL_PROBLEMS" title="Select Problem(s) to print">
1.287 albertel 2716: <resource variable="RESOURCES" toponly='0' multichoice="1"
2717: suppressEmptySequences='0' addstatus="1" closeallpages="1">
1.144 bowersj2 2718: <nextstate>PAGESIZE</nextstate>
1.192 bowersj2 2719: <filterfunc>return $isProblemOrMap;</filterfunc>
1.287 albertel 2720: <choicefunc>return $isNotMap;</choicefunc>
1.238 bowersj2 2721: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2722: $start_new_option
1.284 albertel 2723: </resource>
2724: </state>
1.354 foxr 2725: <state name="ALL_RESOURCES" title="Select Resource(s) to print">
2726: <resource variable="RESOURCES" toponly='0' multichoice='1'
2727: suppressEmptySequences='0' addstatus='1' closeallpages='1'>
2728: <nextstate>PAGESIZE</nextstate>
2729: <filterfunc>return $isNotMap; </filterfunc>
2730: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2731: $start_new_option
1.354 foxr 2732: </resource>
2733: </state>
1.536 foxr 2734: <state name="ALL_PROBLEMS_STUDENTS" title="Select Problem(s) to print">
2735: <resource variable="RESOURCES" toponly='0' multichoice="1"
2736: suppressEmptySequences='0' addstatus="1" closeallpages="1">
2737: <nextstate>STUDENTS1</nextstate>
2738: <filterfunc>return $isProblemOrMap;</filterfunc>
2739: <choicefunc>return $isNotMap;</choicefunc>
2740: <valuefunc>return $symbFilter;</valuefunc>
2741: $start_new_option
2742: </resource>
2743: </state>
2744: <state name="STUDENTS1" title="Select People">
2745: <message><b>Select sorting order of printout</b> </message>
2746: <choices variable='student_sort'>
2747: <choice computer='0'>Sort by section then student</choice>
2748: <choice computer='1'>Sort by students across sections.</choice>
2749: </choices>
2750: <message><br /><hr /><br /> </message>
2751: <student multichoice='1' variable="STUDENTS" nextstate="PRINT_FORMATTING" coursepersonnel="1"/>
2752: </state>
2753:
1.284 albertel 2754: ALL_PROBLEMS
1.132 bowersj2 2755:
1.284 albertel 2756: if ($helper->{VARS}->{'assignment'}) {
1.483 foxr 2757: 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 2758: 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 2759: }
1.424 foxr 2760:
1.507 albertel 2761: my $randomly_ordered_warning =
2762: &get_randomly_ordered_warning($helper,$map);
2763:
1.424 foxr 2764: # resource_selector will hold a few states that:
2765: # - Allow resources to be selected for printing.
2766: # - Determine pagination between assignments.
2767: # - Determine how many assignments should be bundled into a single PDF.
2768: # TODO:
2769: # Probably good to do things like separate this up into several vars, each
2770: # with one state, and use REGEXPs at inclusion time to set state names
2771: # and next states for better mix and match capability
2772: #
1.284 albertel 2773: my $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 2774: <state name="SELECT_PROBLEMS" title="Select resources to print">
1.507 albertel 2775: $randomly_ordered_warning
2776:
1.424 foxr 2777: <nextstate>PRINT_FORMATTING</nextstate>
1.284 albertel 2778: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 2779: <resource variable="RESOURCES" multichoice="1" addstatus="1"
2780: closeallpages="1">
1.254 sakharuk 2781: <filterfunc>return $isProblem;</filterfunc>
1.148 bowersj2 2782: <mapurl>$map</mapurl>
1.254 sakharuk 2783: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2784: $start_new_option
1.147 bowersj2 2785: </resource>
1.424 foxr 2786: </state>
2787: <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155 sakharuk 2788: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149 bowersj2 2789: <choices variable="EMPTY_PAGES">
1.204 sakharuk 2790: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
2791: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
2792: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
2793: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 2794: </choices>
1.424 foxr 2795: <nextstate>PAGESIZE</nextstate>
1.429 foxr 2796: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
2797: <choices variable="SPLIT_PDFS">
2798: <choice computer="all">All assignments in a single PDF file</choice>
2799: <choice computer="sections">Each PDF contains exactly one section</choice>
2800: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 2801: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
2802: Specify the number of assignments per PDF:</choice>
1.429 foxr 2803: </choices>
1.424 foxr 2804: </state>
1.284 albertel 2805: RESOURCE_SELECTOR
2806:
2807: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS);
2808: <state name="CHOOSE_STUDENTS" title="Select Students and Resources">
1.485 albertel 2809: <message><b>Select sorting order of printout</b> </message>
1.340 foxr 2810: <choices variable='student_sort'>
2811: <choice computer='0'>Sort by section then student</choice>
2812: <choice computer='1'>Sort by students across sections.</choice>
2813: </choices>
1.437 foxr 2814: <message><br /><hr /><br /> </message>
1.425 foxr 2815: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_PROBLEMS" coursepersonnel="1"/>
1.424 foxr 2816: </state>
1.284 albertel 2817: $resource_selector
1.131 bowersj2 2818: CHOOSE_STUDENTS
1.292 albertel 2819:
1.373 albertel 2820: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2821: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292 albertel 2822: my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
2823: my $namechoice='<choice></choice>';
1.337 albertel 2824: foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294 albertel 2825: if ($name =~ /^error: 2 /) { next; }
1.381 albertel 2826: if ($name =~ /^type\0/) { next; }
1.292 albertel 2827: $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
2828: }
1.389 foxr 2829:
2830:
2831: my %code_values;
1.405 albertel 2832: my %codes_to_print;
1.411 albertel 2833: foreach my $key (@names) {
1.389 foxr 2834: %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405 albertel 2835: foreach my $key (keys(%code_values)) {
2836: $codes_to_print{$key} = 1;
1.388 foxr 2837: }
2838: }
1.389 foxr 2839:
1.452 albertel 2840: my $code_selection;
1.405 albertel 2841: foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389 foxr 2842: my $choice = $code;
2843: if ($code =~ /^[A-Z]+$/) { # Alpha code
2844: $choice = &letters_to_num($code);
2845: }
1.432 albertel 2846: push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388 foxr 2847: }
1.436 albertel 2848: if (%codes_to_print) {
2849: $code_selection .='
1.472 albertel 2850: <message><b>Choose single CODE from list:</b></message>
1.448 albertel 2851: <message></td><td></message>
1.452 albertel 2852: <dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
2853: <choice></choice>
1.448 albertel 2854: <exec>
2855: push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
2856: </exec>
1.452 albertel 2857: </dropdown>
1.468 foxr 2858: <message></td></tr><tr><td></message>
1.436 albertel 2859: '.$/;
1.448 albertel 2860:
1.436 albertel 2861: }
1.432 albertel 2862:
2863:
1.381 albertel 2864: open(FH,$Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
2865: my $codechoice='';
2866: foreach my $line (<FH>) {
2867: my ($name,$description,$code_type,$code_length)=
2868: (split(/:/,$line))[0,1,2,4];
2869: if ($code_length > 0 &&
2870: $code_type =~/^(letter|number|-1)/) {
2871: $codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
2872: }
2873: }
2874: if ($codechoice eq '') {
2875: $codechoice='<choice computer="default">Default</choice>';
2876: }
1.284 albertel 2877: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1);
1.468 foxr 2878: <state name="CHOOSE_ANON1" title="Specify CODEd Assignments">
1.424 foxr 2879: <nextstate>SELECT_PROBLEMS</nextstate>
1.468 foxr 2880: <message><h4>Fill out one of the forms below</h4></message>
2881: <message><br /><hr /> <br /></message>
2882: <message><h3>Generate new CODEd Assignments</h3></message>
2883: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 2884: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
2885: <validator>
2886: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.382 foxr 2887: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 2888: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
2889: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 2890: return "You need to specify the number of assignments to print";
2891: }
2892: return undef;
2893: </validator>
2894: </string>
2895: <message></td></tr><tr><td></message>
1.501 albertel 2896: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 2897: <message></td><td></message>
2898: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
2899: <message></td></tr><tr><td></message>
2900: <message><b>Bubble sheet type:</b></message>
2901: <message></td><td></message>
2902: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
2903: $codechoice
2904: </dropdown>
1.468 foxr 2905: <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>
2906: <message></td></tr><tr><td></table></message>
1.472 albertel 2907: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
1.468 foxr 2908: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 2909: <string variable="SINGLE_CODE" size="10">
1.382 foxr 2910: <validator>
2911: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 2912: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
2913: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.382 foxr 2914: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
2915: \$helper->{'VARS'}{'CODE_OPTION'});
2916: } else {
2917: return undef; # Other forces control us.
2918: }
2919: </validator>
2920: </string>
1.472 albertel 2921: <message></td></tr><tr><td></message>
1.432 albertel 2922: $code_selection
1.468 foxr 2923: <message></td></tr></table></message>
1.472 albertel 2924: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
1.468 foxr 2925: <message><b>Select saved CODEs:</b></message>
1.381 albertel 2926: <message></td><td></message>
1.292 albertel 2927: <dropdown variable="REUSE_OLD_CODES">
2928: $namechoice
2929: </dropdown>
1.412 albertel 2930: <message></td></tr></table></message>
1.284 albertel 2931: </state>
1.424 foxr 2932: $resource_selector
1.284 albertel 2933: CHOOSE_ANON1
1.254 sakharuk 2934:
1.272 sakharuk 2935:
1.254 sakharuk 2936: if ($helper->{VARS}->{'assignment'}) {
1.483 foxr 2937: 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 2938: 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 2939: }
1.284 albertel 2940:
2941:
2942: $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 2943: <state name="SELECT_RESOURCES" title="Select Resources">
1.507 albertel 2944: $randomly_ordered_warning
2945:
1.424 foxr 2946: <nextstate>PRINT_FORMATTING</nextstate>
1.254 sakharuk 2947: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 2948: <resource variable="RESOURCES" multichoice="1" addstatus="1"
2949: closeallpages="1">
1.254 sakharuk 2950: <filterfunc>return $isNotMap;</filterfunc>
2951: <mapurl>$map</mapurl>
2952: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2953: $start_new_option
1.254 sakharuk 2954: </resource>
1.424 foxr 2955: </state>
2956: <state name="PRINT_FORMATTING" title="Format of the print job">
2957: <nextstate>NUMBER_PER_PDF</nextstate>
1.254 sakharuk 2958: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
2959: <choices variable="EMPTY_PAGES">
2960: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
2961: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
2962: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
2963: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 2964: </choices>
1.424 foxr 2965: <nextstate>PAGESIZE</nextstate>
1.429 foxr 2966: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
2967: <choices variable="SPLIT_PDFS">
2968: <choice computer="all">All assignments in a single PDF file</choice>
2969: <choice computer="sections">Each PDF contains exactly one section</choice>
2970: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 2971: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
2972: Specify the number of assignments per PDF:</choice>
1.429 foxr 2973: </choices>
1.424 foxr 2974: </state>
1.284 albertel 2975: RESOURCE_SELECTOR
2976:
2977: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
2978: <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340 foxr 2979: <choices variable='student_sort'>
2980: <choice computer='0'>Sort by section then student</choice>
2981: <choice computer='1'>Sort by students across sections.</choice>
2982: </choices>
1.437 foxr 2983: <message><br /><hr /><br /></message>
1.426 foxr 2984: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340 foxr 2985:
1.424 foxr 2986: </state>
1.284 albertel 2987: $resource_selector
1.254 sakharuk 2988: CHOOSE_STUDENTS1
2989:
1.284 albertel 2990: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472 albertel 2991: <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424 foxr 2992: <nextstate>SELECT_RESOURCES</nextstate>
1.472 albertel 2993: <message><h4>Fill out one of the forms below</h4></message>
2994: <message><br /><hr /> <br /></message>
2995: <message><h3>Generate new CODEd Assignments</h3></message>
2996: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 2997: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
2998: <validator>
2999: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386 foxr 3000: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 3001: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
3002: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 3003: return "You need to specify the number of assignments to print";
3004: }
3005: return undef;
3006: </validator>
3007: </string>
3008: <message></td></tr><tr><td></message>
1.501 albertel 3009: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 3010: <message></td><td></message>
3011: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
3012: <message></td></tr><tr><td></message>
3013: <message><b>Bubble sheet type:</b></message>
3014: <message></td><td></message>
3015: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
3016: $codechoice
3017: </dropdown>
1.472 albertel 3018: <message></td></tr><tr><td></table></message>
3019: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
3020: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 3021: <string variable="SINGLE_CODE" size="10">
1.386 foxr 3022: <validator>
3023: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 3024: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
3025: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386 foxr 3026: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
3027: \$helper->{'VARS'}{'CODE_OPTION'});
3028: } else {
3029: return undef; # Other forces control us.
3030: }
3031: </validator>
3032: </string>
1.472 albertel 3033: <message></td></tr><tr><td></message>
1.432 albertel 3034: $code_selection
1.472 albertel 3035: <message></td></tr></table></message>
3036: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
3037: <message><b>Select saved CODEs:</b></message>
1.381 albertel 3038: <message></td><td></message>
1.294 albertel 3039: <dropdown variable="REUSE_OLD_CODES">
3040: $namechoice
3041: </dropdown>
1.412 albertel 3042: <message></td></tr></table></message>
1.424 foxr 3043: </state>
1.284 albertel 3044: $resource_selector
3045: CHOOSE_ANON2
1.481 albertel 3046: }
3047:
1.121 bowersj2 3048: # FIXME: That RE should come from a library somewhere.
1.483 foxr 3049: if (($perm{'pav'}
1.482 albertel 3050: && $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
3051: && (defined($helper->{'VARS'}->{'construction'})
3052: ||
3053: (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
3054: &&
3055: $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483 foxr 3056: ))
3057: && $helper->{VARS}->{'assignment'} eq ""
1.482 albertel 3058: ) {
1.238 bowersj2 3059:
1.482 albertel 3060: my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
3061: 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 3062: my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482 albertel 3063: <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458 www 3064:
1.138 bowersj2 3065: <files variable="FILES" multichoice='1'>
1.144 bowersj2 3066: <nextstate>PAGESIZE</nextstate>
1.138 bowersj2 3067: <filechoice>return '$subdir';</filechoice>
1.139 bowersj2 3068: CHOOSE_FROM_SUBDIR
3069:
1.238 bowersj2 3070: # this is broken up because I really want interpolation above,
3071: # and I really DON'T want it below
1.139 bowersj2 3072: $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225 bowersj2 3073: <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
3074: $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131 bowersj2 3075: </filefilter>
1.138 bowersj2 3076: </files>
1.131 bowersj2 3077: </state>
3078: CHOOSE_FROM_SUBDIR
1.139 bowersj2 3079: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131 bowersj2 3080: }
1.238 bowersj2 3081:
3082: # Allow the user to select any sequence in the course, feed it to
3083: # another resource selector for that sequence
1.483 foxr 3084: if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509 albertel 3085: push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249 sakharuk 3086: 'select_sequences', 'CHOOSE_SEQUENCE'];
1.244 bowersj2 3087: my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
3088: #Escape apostrophes and backslashes for Perl
3089: $escapedSequenceName =~ s/\\/\\\\/g;
3090: $escapedSequenceName =~ s/'/\\'/g;
1.239 bowersj2 3091: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238 bowersj2 3092: <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
3093: <message>Select the sequence to print resources from:</message>
3094: <resource variable="SEQUENCE">
3095: <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
3096: <filterfunc>return \$res->is_sequence;</filterfunc>
3097: <valuefunc>return $urlValue;</valuefunc>
1.447 foxr 3098: <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391 foxr 3099: </choicefunc>
1.238 bowersj2 3100: </resource>
3101: </state>
3102: <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
3103: <message>(mark desired resources then click "next" button) <br /></message>
1.435 foxr 3104: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 3105: closeallpages="1">
1.238 bowersj2 3106: <nextstate>PAGESIZE</nextstate>
1.466 albertel 3107: <filterfunc>return $isNotMap</filterfunc>
1.244 bowersj2 3108: <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238 bowersj2 3109: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 3110: $start_new_option
1.238 bowersj2 3111: </resource>
3112: </state>
3113: CHOOSE_FROM_ANY_SEQUENCE
1.239 bowersj2 3114: }
1.481 albertel 3115:
1.131 bowersj2 3116: # Generate the first state, to select which resources get printed.
1.223 bowersj2 3117: Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131 bowersj2 3118: $paramHash = Apache::lonhelper::getParamHash();
1.155 sakharuk 3119: $paramHash->{MESSAGE_TEXT} = "";
1.131 bowersj2 3120: Apache::lonhelper::message->new();
3121: $paramHash = Apache::lonhelper::getParamHash();
3122: $paramHash->{'variable'} = 'PRINT_TYPE';
3123: $paramHash->{CHOICES} = $printChoices;
3124: Apache::lonhelper::choices->new();
1.161 bowersj2 3125:
1.223 bowersj2 3126: my $startedTable = 0; # have we started an HTML table yet? (need
3127: # to close it later)
3128:
1.397 albertel 3129: if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or
1.170 sakharuk 3130: ($helper->{VARS}->{'construction'} eq '1')) {
1.497 www 3131: addMessage("<hr width='33%' /><table><tr><td align='right'>".
3132: '<label for="ANSWER_TYPE_forminput">'.
3133: &mt('Print').
3134: "</label>: </td><td>");
1.161 bowersj2 3135: $paramHash = Apache::lonhelper::getParamHash();
1.162 sakharuk 3136: $paramHash->{'variable'} = 'ANSWER_TYPE';
3137: $helper->declareVar('ANSWER_TYPE');
1.161 bowersj2 3138: $paramHash->{CHOICES} = [
1.242 sakharuk 3139: ['Without Answers', 'yes'],
3140: ['With Answers', 'no'],
1.368 albertel 3141: ['Only Answers', 'only']
1.289 sakharuk 3142: ];
1.210 sakharuk 3143: Apache::lonhelper::dropdown->new();
1.223 bowersj2 3144: addMessage("</td></tr>");
3145: $startedTable = 1;
1.161 bowersj2 3146: }
1.209 sakharuk 3147:
1.397 albertel 3148: if ($perm{'pav'}) {
1.223 bowersj2 3149: if (!$startedTable) {
1.497 www 3150: addMessage("<hr width='33%' /><table><tr><td align='right'>".
3151: '<label for="LATEX_TYPE_forminput">'.
3152: &mt('LaTeX mode').
3153: "</label>: </td><td>");
1.223 bowersj2 3154: $startedTable = 1;
3155: } else {
1.497 www 3156: addMessage("<tr><td align='right'>".
3157: '<label for="LATEX_TYPE_forminput">'.
3158: &mt('LaTeX mode').
3159: "</label>: </td><td>");
1.223 bowersj2 3160: }
1.203 sakharuk 3161: $paramHash = Apache::lonhelper::getParamHash();
3162: $paramHash->{'variable'} = 'LATEX_TYPE';
3163: $helper->declareVar('LATEX_TYPE');
3164: if ($helper->{VARS}->{'construction'} eq '1') {
3165: $paramHash->{CHOICES} = [
1.223 bowersj2 3166: ['standard LaTeX mode', 'standard'],
3167: ['LaTeX batchmode', 'batchmode'], ];
1.203 sakharuk 3168: } else {
3169: $paramHash->{CHOICES} = [
1.223 bowersj2 3170: ['LaTeX batchmode', 'batchmode'],
3171: ['standard LaTeX mode', 'standard'] ];
1.203 sakharuk 3172: }
1.210 sakharuk 3173: Apache::lonhelper::dropdown->new();
1.218 sakharuk 3174:
1.497 www 3175: addMessage("</td></tr><tr><td align='right'>".
1.506 albertel 3176: '<label for="TABLE_CONTENTS_forminput">'.
1.497 www 3177: &mt('Print Table of Contents').
3178: "</label>: </td><td>");
1.209 sakharuk 3179: $paramHash = Apache::lonhelper::getParamHash();
3180: $paramHash->{'variable'} = 'TABLE_CONTENTS';
3181: $helper->declareVar('TABLE_CONTENTS');
3182: $paramHash->{CHOICES} = [
1.223 bowersj2 3183: ['No', 'no'],
3184: ['Yes', 'yes'] ];
1.210 sakharuk 3185: Apache::lonhelper::dropdown->new();
1.223 bowersj2 3186: addMessage("</td></tr>");
1.214 sakharuk 3187:
1.220 sakharuk 3188: if (not $helper->{VARS}->{'construction'}) {
1.497 www 3189: addMessage("<tr><td align='right'>".
3190: '<label for="TABLE_INDEX_forminput">'.
3191: &mt('Print Index').
3192: "</label>: </td><td>");
1.220 sakharuk 3193: $paramHash = Apache::lonhelper::getParamHash();
3194: $paramHash->{'variable'} = 'TABLE_INDEX';
3195: $helper->declareVar('TABLE_INDEX');
3196: $paramHash->{CHOICES} = [
1.223 bowersj2 3197: ['No', 'no'],
3198: ['Yes', 'yes'] ];
1.220 sakharuk 3199: Apache::lonhelper::dropdown->new();
1.223 bowersj2 3200: addMessage("</td></tr>");
1.497 www 3201: addMessage("<tr><td align='right'>".
3202: '<label for="PRINT_DISCUSSIONS_forminput">'.
3203: &mt('Print Discussions').
3204: "</label>: </td><td>");
1.309 sakharuk 3205: $paramHash = Apache::lonhelper::getParamHash();
3206: $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';
3207: $helper->declareVar('PRINT_DISCUSSIONS');
3208: $paramHash->{CHOICES} = [
3209: ['No', 'no'],
3210: ['Yes', 'yes'] ];
3211: Apache::lonhelper::dropdown->new();
3212: addMessage("</td></tr>");
1.372 foxr 3213:
1.511 foxr 3214: # Prompt for printing annotations too.
3215:
3216: addMessage("<tr><td align='right'>".
3217: '<label for="PRINT_ANNOTATIONS_forminput">'.
3218: &mt('Print Annotations').
3219: "</label>:</td><td>");
3220: $paramHash = Apache::lonhelper::getParamHash();
3221: $paramHash->{'variable'} = "PRINT_ANNOTATIONS";
3222: $helper->declareVar("PRINT_ANNOTATIONS");
3223: $paramHash->{CHOICES} = [
3224: ['No', 'no'],
3225: ['Yes', 'yes']];
3226: Apache::lonhelper::dropdown->new();
3227: addMessage("</td></tr>");
3228:
1.397 albertel 3229: addMessage("<tr><td align = 'right'> </td><td>");
3230: $paramHash = Apache::lonhelper::getParamHash();
3231: $paramHash->{'multichoice'} = "true";
3232: $paramHash->{'allowempty'} = "true";
3233: $paramHash->{'variable'} = "showallfoils";
3234: $paramHash->{'CHOICES'} = [ ["Show all foils", "1"] ];
3235: Apache::lonhelper::choices->new();
3236: addMessage("</td></tr>");
1.220 sakharuk 3237: }
1.219 sakharuk 3238:
1.230 albertel 3239: if ($helper->{'VARS'}->{'construction'}) {
1.505 albertel 3240: my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497 www 3241: my $randseedtext=&mt("Use random seed");
3242: my $stylefiletext=&mt("Use style file");
1.506 albertel 3243: my $selectfiletext=&mt("Select style file");
1.497 www 3244:
1.265 sakharuk 3245: my $xmlfrag .= <<"RNDSEED";
1.497 www 3246: <message><tr><td align='right'>
3247: <label for="curseed_forminput">$randseedtext</label>:
3248: </td><td></message>
1.230 albertel 3249: <string variable="curseed" size="15" maxlength="15">
3250: <defaultvalue>
3251: return $helper->{VARS}->{'curseed'};
3252: </defaultvalue>
1.262 sakharuk 3253: </string>
1.497 www 3254: <message></td></tr><tr><td align="right">
1.503 albertel 3255: <label for="style_file">$stylefiletext</label>:
1.497 www 3256: </td><td></message>
1.504 albertel 3257: <string variable="style_file" size="40">
3258: <defaultvalue>
1.505 albertel 3259: return $stylevalue;
1.504 albertel 3260: </defaultvalue>
1.506 albertel 3261: </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 3262: <choices allowempty="1" multichoice="true" variable="showallfoils">
1.506 albertel 3263: <choice computer="1">Show all foils</choice>
1.371 foxr 3264: </choices>
1.378 albertel 3265: <message></td></tr></message>
1.230 albertel 3266: RNDSEED
3267: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.512 foxr 3268:
3269:
3270: addMessage("<tr><td>Problem Type:</td><td>");
3271: #
3272: # Initial value from construction space:
3273: #
3274: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
3275: $helper->{VARS}->{'probstatus'} = $env{'form.problemtype'}; # initial value
3276: }
1.518 foxr 3277: $xmlfrag = << "PROBTYPE";
3278: <dropdown variable="probstatus" multichoice="0" allowempty="0">
3279: <defaultvalue>
3280: return "$helper->{VARS}->{'probstatus'}";
3281: </defaultvalue>
3282: <choice computer="problem">Homework Problem</choice>
3283: <choice computer="exam">Exam Problem</choice>
3284: <choice computer="survey">Survey question</choice>
3285: </dropdown>
3286: PROBTYPE
3287: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
3288:
1.512 foxr 3289: addMessage("</td></tr>");
3290:
1.372 foxr 3291: }
1.223 bowersj2 3292: }
1.264 sakharuk 3293:
3294:
3295:
1.218 sakharuk 3296:
1.223 bowersj2 3297: if ($startedTable) {
3298: addMessage("</table>");
1.215 sakharuk 3299: }
1.161 bowersj2 3300:
1.131 bowersj2 3301: Apache::lonprintout::page_format_state->new("FORMAT");
3302:
1.144 bowersj2 3303: # Generate the PAGESIZE state which will offer the user the margin
3304: # choices if they select one column
3305: Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
3306: Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
3307:
3308:
1.131 bowersj2 3309: $helper->process();
3310:
1.416 foxr 3311:
1.131 bowersj2 3312: # MANUAL BAILOUT CONDITION:
3313: # If we're in the "final" state, bailout and return to handler
3314: if ($helper->{STATE} eq 'FINAL') {
3315: return $helper;
3316: }
1.130 sakharuk 3317:
1.131 bowersj2 3318: $r->print($helper->display());
1.395 www 3319: if ($helper->{STATE} eq 'START') {
3320: &recently_generated($r);
3321: }
1.333 albertel 3322: &Apache::lonhelper::unregisterHelperTags();
1.115 bowersj2 3323:
3324: return OK;
3325: }
3326:
1.1 www 3327:
3328: 1;
1.119 bowersj2 3329:
3330: package Apache::lonprintout::page_format_state;
3331:
3332: =pod
3333:
1.131 bowersj2 3334: =head1 Helper element: page_format_state
3335:
3336: See lonhelper.pm documentation for discussion of the helper framework.
1.119 bowersj2 3337:
1.131 bowersj2 3338: Apache::lonprintout::page_format_state is an element that gives the
3339: user an opportunity to select the page layout they wish to print
3340: with: Number of columns, portrait/landscape, and paper size. If you
3341: want to change the paper size choices, change the @paperSize array
3342: contents in this package.
1.119 bowersj2 3343:
1.131 bowersj2 3344: page_format_state is always directly invoked in lonprintout.pm, so there
3345: is no tag interface. You actually pass parameters to the constructor.
1.119 bowersj2 3346:
3347: =over 4
3348:
1.131 bowersj2 3349: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119 bowersj2 3350:
3351: =back
3352:
3353: =cut
3354:
1.131 bowersj2 3355: use Apache::lonhelper;
1.119 bowersj2 3356:
3357: no strict;
1.131 bowersj2 3358: @ISA = ("Apache::lonhelper::element");
1.119 bowersj2 3359: use strict;
1.266 sakharuk 3360: use Apache::lonlocal;
1.373 albertel 3361: use Apache::lonnet;
1.119 bowersj2 3362:
3363: my $maxColumns = 2;
1.376 albertel 3364: # it'd be nice if these all worked
3365: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
3366: # "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
3367: # "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]",
3368: # "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326 sakharuk 3369: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
1.376 albertel 3370: "a4 [210x297 mm]");
1.119 bowersj2 3371:
3372: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
3373: # Paper type
3374:
3375: sub new {
1.131 bowersj2 3376: my $self = Apache::lonhelper::element->new();
1.119 bowersj2 3377:
1.135 bowersj2 3378: shift;
3379:
1.131 bowersj2 3380: $self->{'variable'} = shift;
1.134 bowersj2 3381: my $helper = Apache::lonhelper::getHelper();
1.135 bowersj2 3382: $helper->declareVar($self->{'variable'});
1.131 bowersj2 3383: bless($self);
1.119 bowersj2 3384: return $self;
3385: }
3386:
3387: sub render {
3388: my $self = shift;
1.131 bowersj2 3389: my $helper = Apache::lonhelper::getHelper();
1.119 bowersj2 3390: my $result = '';
1.131 bowersj2 3391: my $var = $self->{'variable'};
1.266 sakharuk 3392: my $PageLayout=&mt('Page layout');
3393: my $NumberOfColumns=&mt('Number of columns');
3394: my $PaperType=&mt('Paper type');
1.506 albertel 3395: my $landscape=&mt('Landscape');
3396: my $portrait=&mt('Portrait');
1.539 onken 3397: my $pdfFormLabel=&mt('PDF-Formfields');
3398: my $with=&mt('with Formfields');
3399: my $without=&mt('without Formfields');
1.119 bowersj2 3400: $result .= <<STATEHTML;
3401:
1.223 bowersj2 3402: <hr width="33%" />
1.119 bowersj2 3403: <table cellpadding="3">
3404: <tr>
1.266 sakharuk 3405: <td align="center"><b>$PageLayout</b></td>
3406: <td align="center"><b>$NumberOfColumns</b></td>
3407: <td align="center"><b>$PaperType</b></td>
1.539 onken 3408: <td align="center"><b>$pdfFormLabel</b></td>
1.119 bowersj2 3409: </tr>
3410: <tr>
3411: <td>
1.506 albertel 3412: <label><input type="radio" name="${var}.layout" value="L" /> $landscape </label><br />
3413: <label><input type="radio" name="${var}.layout" value="P" checked='1' /> $portrait </label>
1.119 bowersj2 3414: </td>
1.155 sakharuk 3415: <td align="center">
1.119 bowersj2 3416: <select name="${var}.cols">
3417: STATEHTML
3418:
3419: my $i;
3420: for ($i = 1; $i <= $maxColumns; $i++) {
1.144 bowersj2 3421: if ($i == 2) {
1.119 bowersj2 3422: $result .= "<option value='$i' selected>$i</option>\n";
3423: } else {
3424: $result .= "<option value='$i'>$i</option>\n";
3425: }
3426: }
3427:
3428: $result .= "</select></td><td>\n";
3429: $result .= "<select name='${var}.paper'>\n";
3430:
1.373 albertel 3431: my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398 albertel 3432: my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
3433: $DefaultPaperSize=~s/\s//g;
1.304 sakharuk 3434: if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119 bowersj2 3435: $i = 0;
3436: foreach (@paperSize) {
1.326 sakharuk 3437: $_=~/(\w+)/;
3438: my $papersize=$1;
1.304 sakharuk 3439: if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.326 sakharuk 3440: $result .= "<option selected value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119 bowersj2 3441: } else {
1.326 sakharuk 3442: $result .= "<option value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119 bowersj2 3443: }
3444: $i++;
3445: }
1.539 onken 3446: $result .= <<HTML;
3447: </select>
3448: </td>
3449: <td align='center'>
3450: <select name='${var}.pdfFormFields'>
3451: <option selected value='no'>$without</option>
3452: <option value='yes'>$with</option>
3453: </select>
3454: </td>
3455: </tr></table>
3456: HTML
3457:
1.119 bowersj2 3458: return $result;
1.135 bowersj2 3459: }
3460:
3461: sub postprocess {
3462: my $self = shift;
3463:
3464: my $var = $self->{'variable'};
1.136 bowersj2 3465: my $helper = Apache::lonhelper->getHelper();
1.135 bowersj2 3466: $helper->{VARS}->{$var} =
1.373 albertel 3467: $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
1.539 onken 3468: $env{"form.$var.paper"} . '|' . $env{"form.$var.pdfFormFields"};
1.135 bowersj2 3469: return 1;
1.119 bowersj2 3470: }
3471:
3472: 1;
1.144 bowersj2 3473:
3474: package Apache::lonprintout::page_size_state;
3475:
3476: =pod
3477:
3478: =head1 Helper element: page_size_state
3479:
3480: See lonhelper.pm documentation for discussion of the helper framework.
3481:
3482: Apache::lonprintout::page_size_state is an element that gives the
3483: user the opportunity to further refine the page settings if they
3484: select a single-column page.
3485:
3486: page_size_state is always directly invoked in lonprintout.pm, so there
3487: is no tag interface. You actually pass parameters to the constructor.
3488:
3489: =over 4
3490:
3491: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
3492:
3493: =back
3494:
3495: =cut
3496:
3497: use Apache::lonhelper;
1.373 albertel 3498: use Apache::lonnet;
1.144 bowersj2 3499: no strict;
3500: @ISA = ("Apache::lonhelper::element");
3501: use strict;
3502:
3503:
3504:
3505: sub new {
3506: my $self = Apache::lonhelper::element->new();
3507:
3508: shift; # disturbs me (probably prevents subclassing) but works (drops
3509: # package descriptor)... - Jeremy
3510:
3511: $self->{'variable'} = shift;
3512: my $helper = Apache::lonhelper::getHelper();
3513: $helper->declareVar($self->{'variable'});
3514:
3515: # The variable name of the format element, so we can look into
3516: # $helper->{VARS} to figure out whether the columns are one or two
3517: $self->{'formatvar'} = shift;
3518:
1.463 foxr 3519:
1.144 bowersj2 3520: $self->{NEXTSTATE} = shift;
3521: bless($self);
1.467 foxr 3522:
1.144 bowersj2 3523: return $self;
3524: }
3525:
3526: sub render {
3527: my $self = shift;
3528: my $helper = Apache::lonhelper::getHelper();
3529: my $result = '';
3530: my $var = $self->{'variable'};
3531:
1.467 foxr 3532:
3533:
1.144 bowersj2 3534: if (defined $self->{ERROR_MSG}) {
1.464 albertel 3535: $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144 bowersj2 3536: }
3537:
1.438 foxr 3538: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463 foxr 3539:
3540: # Use format to get sensible defaults for the margins:
3541:
3542:
3543: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
3544: ($papersize) = split(/ /, $papersize);
3545:
3546:
3547: if ($laystyle eq 'L') {
3548: $laystyle = 'album';
3549: } else {
3550: $laystyle = 'book';
3551: }
3552:
3553:
1.464 albertel 3554: my %size;
3555: ($size{'width_and_units'},
3556: $size{'height_and_units'},
3557: $size{'margin_and_units'})=
3558: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463 foxr 3559:
1.464 albertel 3560: foreach my $dimension ('width','height','margin') {
3561: ($size{$dimension},$size{$dimension.'_unit'}) =
3562: split(/ +/, $size{$dimension.'_and_units'},2);
3563:
3564: foreach my $unit ('cm','in') {
3565: $size{$dimension.'_options'} .= '<option ';
3566: if ($size{$dimension.'_unit'} eq $unit) {
3567: $size{$dimension.'_options'} .= 'selected="selected" ';
3568: }
3569: $size{$dimension.'_options'} .= '>'.$unit.'</option>';
3570: }
1.438 foxr 3571: }
3572:
1.470 foxr 3573: # Adjust margin for LaTeX margin: .. requires units == cm or in.
3574:
3575: if ($size{'margin_unit'} eq 'in') {
3576: $size{'margin'} += 1;
3577: } else {
3578: $size{'margin'} += 2.54;
3579: }
1.506 albertel 3580: my %text = ('format' => 'How should each column be formatted?',
3581: 'width' => 'Width:',
3582: 'height' => 'Height:',
3583: 'margin' => 'Left Margin:',);
3584: %text = &Apache::lonlocal::texthash(%text);
3585:
1.144 bowersj2 3586: $result .= <<ELEMENTHTML;
3587:
1.506 albertel 3588: <p>$text{'format'}</p>
1.144 bowersj2 3589:
3590: <table cellpadding='3'>
3591: <tr>
1.506 albertel 3592: <td align='right'><b>$text{'width'}</b></td>
1.464 albertel 3593: <td align='left'><input type='text' name='$var.width' value="$size{'width'}" size='4' /></td>
1.144 bowersj2 3594: <td align='left'>
3595: <select name='$var.widthunit'>
1.464 albertel 3596: $size{'width_options'}
1.144 bowersj2 3597: </select>
3598: </td>
3599: </tr>
3600: <tr>
1.506 albertel 3601: <td align='right'><b>$text{'height'}</b></td>
1.464 albertel 3602: <td align='left'><input type='text' name="$var.height" value="$size{'height'}" size='4' /></td>
1.144 bowersj2 3603: <td align='left'>
3604: <select name='$var.heightunit'>
1.464 albertel 3605: $size{'height_options'}
1.144 bowersj2 3606: </select>
3607: </td>
3608: </tr>
3609: <tr>
1.506 albertel 3610: <td align='right'><b>$text{'margin'}</b></td>
1.464 albertel 3611: <td align='left'><input type='text' name='$var.lmargin' value="$size{'margin'}" size='4' /></td>
1.144 bowersj2 3612: <td align='left'>
1.186 bowersj2 3613: <select name='$var.lmarginunit'>
1.464 albertel 3614: $size{'margin_options'}
1.144 bowersj2 3615: </select>
3616: </td>
3617: </tr>
3618: </table>
3619:
1.464 albertel 3620: <!--<p>Hint: Some instructors like to leave scratch space for the student by
3621: making the width much smaller than the width of the page.</p>-->
1.144 bowersj2 3622:
3623: ELEMENTHTML
3624:
3625: return $result;
3626: }
3627:
1.470 foxr 3628:
1.144 bowersj2 3629: sub preprocess {
3630: my $self = shift;
3631: my $helper = Apache::lonhelper::getHelper();
3632:
3633: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467 foxr 3634:
3635: # If the user does not have 'pav' privilege, set default widths and
3636: # on to the next state right away.
3637: #
3638: if (!$perm{'pav'}) {
3639: my $var = $self->{'variable'};
3640: my $format = $helper->{VARS}->{$self->{'formatvar'}};
3641:
3642: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
3643: ($papersize) = split(/ /, $papersize);
3644:
3645:
3646: if ($laystyle eq 'L') {
3647: $laystyle = 'album';
3648: } else {
3649: $laystyle = 'book';
3650: }
3651: # Figure out some good defaults for the print out and set them:
3652:
3653: my %size;
3654: ($size{'width'},
3655: $size{'height'},
3656: $size{'lmargin'})=
3657: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
3658:
3659: foreach my $dim ('width', 'height', 'lmargin') {
3660: my ($value, $units) = split(/ /, $size{$dim});
1.470 foxr 3661:
1.467 foxr 3662: $helper->{VARS}->{"$var.".$dim} = $value;
3663: $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
3664:
3665: }
3666:
3667:
3668: # Transition to the next state
3669:
3670: $helper->changeState($self->{NEXTSTATE});
3671: }
1.144 bowersj2 3672:
3673: return 1;
3674: }
3675:
3676: sub postprocess {
3677: my $self = shift;
3678:
3679: my $var = $self->{'variable'};
3680: my $helper = Apache::lonhelper->getHelper();
1.373 albertel 3681: my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"};
3682: my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"};
3683: my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"};
3684: $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"};
3685: $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"};
3686: $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"};
1.144 bowersj2 3687:
3688: my $error = '';
3689:
3690: # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed
3691: # by an optional period, followed by digits, ending the string
3692:
1.464 albertel 3693: if ($width !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3694: $error .= "Invalid width; please type only a number.<br />\n";
3695: }
1.464 albertel 3696: if ($height !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3697: $error .= "Invalid height; please type only a number.<br />\n";
3698: }
1.464 albertel 3699: if ($lmargin !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3700: $error .= "Invalid left margin; please type only a number.<br />\n";
1.470 foxr 3701: } else {
3702: # Adjust for LaTeX 1.0 inch margin:
3703:
3704: if ($env{"form.${var}.lmarginunit"} eq "in") {
3705: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
3706: } else {
3707: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
3708: }
1.144 bowersj2 3709: }
3710:
3711: if (!$error) {
3712: Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
3713: return 1;
3714: } else {
3715: $self->{ERROR_MSG} = $error;
3716: return 0;
3717: }
3718: }
3719:
3720:
1.119 bowersj2 3721:
1.1 www 3722: __END__
1.6 sakharuk 3723:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>