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