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