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