Annotation of loncom/interface/lonprintout.pm, revision 1.509
1.469 foxr 1: #
1.389 foxr 2: # The LearningOnline Network
1.1 www 3: # Printout
4: #
1.509 ! albertel 5: # $Id: lonprintout.pm,v 1.508 2007/09/05 00:56:55 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
1972: if ($helper->{'VARS'}->{'construction'} ne '1') {
1973: #prints published resource
1.439 www 1974: $URLback=&escape('/adm/flip?postdata=return:');
1.276 sakharuk 1975: } else {
1976: #prints resource from the construction space
1977: $URLback='/'.$helper->{'VARS'}->{'filename'};
1.279 albertel 1978: if ($URLback=~/([^?]+)/) {
1979: $URLback=$1;
1980: $URLback=~s|^/~|/priv/|;
1981: }
1.276 sakharuk 1982: }
1.375 foxr 1983: # logic for now is too complex to trace if this has been defined
1984: # yet.
1985: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1986: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1.257 sakharuk 1987: &Apache::lonnet::appenv('cgi.'.$identifier.'.file' => $filename,
1988: 'cgi.'.$identifier.'.layout' => $laystyle,
1989: 'cgi.'.$identifier.'.numcol' => $numberofcolumns,
1.303 sakharuk 1990: 'cgi.'.$identifier.'.paper' => $papersize,
1.257 sakharuk 1991: 'cgi.'.$identifier.'.selection' => $selectionmade,
1.375 foxr 1992: 'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
1993: 'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
1.397 albertel 1994: 'cgi.'.$identifier.'.role' => $perm{'pav'},
1.375 foxr 1995: 'cgi.'.$identifier.'.numberoffiles' => $#print_array,
1996: 'cgi.'.$identifier.'.studentnames' => $student_names,
1997: 'cgi.'.$identifier.'.backref' => $URLback,);
1998: &Apache::lonnet::appenv("cgi.$identifier.user" => $env{'user.name'},
1999: "cgi.$identifier.domain" => $env{'user.domain'},
2000: "cgi.$identifier.courseid" => $cnum,
2001: "cgi.$identifier.coursedom" => $cdom,
2002: "cgi.$identifier.resources" => $resources_printed);
2003:
1.431 albertel 2004: my $end_page = &Apache::loncommon::end_page();
2005: $r->print(<<FINALEND);
1.317 albertel 2006: <br />
1.288 albertel 2007: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.317 albertel 2008: <a href="/cgi-bin/printout.pl?$identifier">Continue</a>
1.431 albertel 2009: $end_page
1.140 sakharuk 2010: FINALEND
2011: }
2012:
1.288 albertel 2013:
2014: sub get_CODE {
1.381 albertel 2015: my ($all_codes,$num,$seed,$size,$type)=@_;
1.288 albertel 2016: my $max='1'.'0'x$size;
2017: my $newcode;
2018: while(1) {
1.392 albertel 2019: $newcode=sprintf("%0".$size."d",int(rand($max)));
1.288 albertel 2020: if (!exists($$all_codes{$newcode})) {
2021: $$all_codes{$newcode}=1;
1.381 albertel 2022: if ($type eq 'number' ) {
2023: return $newcode;
2024: } else {
2025: return &num_to_letters($newcode);
2026: }
1.288 albertel 2027: }
2028: }
2029: }
1.140 sakharuk 2030:
1.284 albertel 2031: sub print_resources {
1.360 albertel 2032: my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422 albertel 2033: $LaTeXwidth)=@_;
1.284 albertel 2034: my $current_output = '';
1.375 foxr 2035: my $printed = '';
1.284 albertel 2036: my ($username,$userdomain,$usersection) = split /:/,$person;
2037: my $fullname = &get_name($username,$userdomain);
1.492 foxr 2038: my $namepostfix = "\\\\"; # Both anon and not anon should get the same vspace.
1.288 albertel 2039: if ($person =~ 'anon') {
1.492 foxr 2040: $namepostfix .="Name: ";
1.288 albertel 2041: $fullname = "CODE - ".$moreenv->{'CODE'};
2042: }
1.444 foxr 2043: # Fullname may have special latex characters that need \ prefixing:
2044: #
2045:
1.350 foxr 2046: my $i = 0;
1.284 albertel 2047: #goes through all resources, checks if they are available for
2048: #current student, and produces output
1.428 albertel 2049:
2050: &Apache::lonxml::clear_problem_counter();
1.364 albertel 2051: my %page_breaks = &get_page_breaks($helper);
1.476 albertel 2052: my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440 foxr 2053: #
1.441 foxr 2054: # end each student with a
1.440 foxr 2055: # Special that allows the post processor to even out the page
2056: # counts later. Nasty problem this... it would be really
2057: # nice to put the special in as a postscript comment
1.441 foxr 2058: # e.g. \special{ps:\ENDOFSTUDENTSTAMP} unfortunately,
1.440 foxr 2059: # The special gets passed the \ and dvips puts it in the output file
1.441 foxr 2060: # so we will just rely on prntout.pl to strip ENDOFSTUDENTSTAMP from the
2061: # postscript. Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440 foxr 2062: #
1.363 foxr 2063:
1.284 albertel 2064: foreach my $curresline (@{$master_seq}) {
1.351 foxr 2065: if (defined $page_breaks{$curresline}) {
1.350 foxr 2066: if($i != 0) {
2067: $current_output.= "\\newpage\n";
2068: }
2069: }
2070: $i++;
1.284 albertel 2071: if ( !($type eq 'problems' &&
2072: ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
2073: my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
2074: if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414 albertel 2075: if ($res_url!~m|^ext/|
1.413 albertel 2076: && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 2077: $printed .= $curresline.':';
1.428 albertel 2078:
2079: &Apache::lonxml::remember_problem_counter();
2080:
1.373 albertel 2081: my $rendered = &Apache::loncommon::get_student_view($curresline,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428 albertel 2082:
1.305 sakharuk 2083: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
2084: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2085: # Use a copy of the hash so we don't pervert it on future loop passes.
2086: my %answerenv = %{$moreenv};
2087: $answerenv{'answer_output_mode'}='tex';
2088: $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428 albertel 2089:
2090: &Apache::lonxml::restore_problem_counter();
2091:
1.380 foxr 2092: my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428 albertel 2093:
1.305 sakharuk 2094: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2095: $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
2096: } else {
1.423 foxr 2097:
2098:
2099: my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477 albertel 2100: my $title = &Apache::lonnet::gettitle($curresline);
2101: $title = &Apache::lonxml::latex_special_symbols($title);
2102: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
2103: $body .=&path_to_problem($res_url,$LaTeXwidth);
1.423 foxr 2104: $body .='\vskip 1 mm '.$ansrendered;
2105: $body = &encapsulate_minipage($body);
2106: $rendered = $header.$body;
1.305 sakharuk 2107: }
2108: }
2109: if ($remove_latex_header eq 'YES') {
2110: $rendered = &latex_header_footer_remove($rendered);
2111: } else {
2112: $rendered =~ s/\\end{document}//;
2113: }
2114: $current_output .= $rendered;
1.456 raeburn 2115: } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.375 foxr 2116: $printed .= $curresline.':';
1.373 albertel 2117: my $rendered = &Apache::loncommon::get_student_view($curresline,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428 albertel 2118:
1.305 sakharuk 2119: if ($remove_latex_header eq 'YES') {
2120: $rendered = &latex_header_footer_remove($rendered);
1.284 albertel 2121: } else {
1.305 sakharuk 2122: $rendered =~ s/\\end{document}//;
1.284 albertel 2123: }
1.421 foxr 2124: $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
2125:
1.284 albertel 2126: } else {
1.414 albertel 2127: my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305 sakharuk 2128: if ($remove_latex_header ne 'NO') {
2129: $rendered = &latex_header_footer_remove($rendered);
2130: } else {
2131: $rendered =~ s/\\end{document}//;
2132: }
2133: $current_output .= $rendered;
1.284 albertel 2134: }
2135: }
2136: $remove_latex_header = 'YES';
2137: }
1.331 albertel 2138: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 2139: }
2140: my $courseidinfo = &get_course();
2141: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo }
2142: if ($usersection ne '') {$courseidinfo.=' - Sec. '.$usersection}
2143: my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476 albertel 2144: my $header_line =
1.486 foxr 2145: &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.476 albertel 2146: $currentassignment, $courseidinfo, $fullname);
2147: my $header_start = ($columns_in_format == 1) ? '\lhead'
2148: : '\fancyhead[LO]';
2149: $header_line = $header_start.'{'.$header_line.'}';
2150:
1.284 albertel 2151: if ($current_output=~/\\documentclass/) {
1.476 albertel 2152: $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.284 albertel 2153: } else {
1.476 albertel 2154: my $blankpages =
2155: '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
2156:
2157: $current_output = '\strut\vspace*{-6 mm}\\newline'.
2158: ©right_line().' \newpage '.$blankpages.$end_of_student.
2159: '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
2160: $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284 albertel 2161: }
1.440 foxr 2162: #
2163: # Close the student bracketing.
2164: #
1.375 foxr 2165: return ($current_output,$fullname, $printed);
1.284 albertel 2166:
2167: }
1.140 sakharuk 2168:
1.3 sakharuk 2169: sub handler {
2170:
2171: my $r = shift;
1.397 albertel 2172:
2173: &init_perm();
1.114 bowersj2 2174:
1.416 foxr 2175:
1.67 www 2176:
1.397 albertel 2177: my $helper = printHelper($r);
2178: if (!ref($helper)) {
2179: return $helper;
1.60 sakharuk 2180: }
1.177 sakharuk 2181:
1.184 sakharuk 2182:
1.454 foxr 2183: %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353 foxr 2184:
1.416 foxr 2185:
1.350 foxr 2186:
2187:
1.367 foxr 2188: # If a figure conversion queue file exists for this user.domain
2189: # we delete it since it can only be bad (if it were good, printout.pl
2190: # would have deleted it the last time around.
2191:
1.373 albertel 2192: my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367 foxr 2193: if(-e $conversion_queuefile) {
2194: unlink $conversion_queuefile;
2195: }
1.184 sakharuk 2196: &output_data($r,$helper,\%parmhash);
1.2 sakharuk 2197: return OK;
1.60 sakharuk 2198: }
1.2 sakharuk 2199:
1.131 bowersj2 2200: use Apache::lonhelper;
1.130 sakharuk 2201:
1.223 bowersj2 2202: sub addMessage {
2203: my $text = shift;
2204: my $paramHash = Apache::lonhelper::getParamHash();
2205: $paramHash->{MESSAGE_TEXT} = $text;
2206: Apache::lonhelper::message->new();
2207: }
2208:
1.416 foxr 2209:
1.238 bowersj2 2210:
1.397 albertel 2211: sub init_perm {
2212: undef(%perm);
2213: $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
2214: if (!$perm{'pav'}) {
2215: $perm{'pav'}=&Apache::lonnet::allowed('pav',
2216: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2217: }
1.465 albertel 2218: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397 albertel 2219: if (!$perm{'pfo'}) {
2220: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',
2221: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2222: }
2223: }
2224:
1.507 albertel 2225: sub get_randomly_ordered_warning {
2226: my ($helper,$map) = @_;
2227:
2228: my $message;
2229:
2230: my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
2231: my $navmap = Apache::lonnavmaps::navmap->new();
2232: my $res = $navmap->getResourceByUrl($map);
2233: if ($res) {
2234: my $func =
2235: sub { return ($_[0]->is_map() && $_[0]->randomorder); };
2236: my @matches = $navmap->retrieveResources($res, $func,1,1,1);
2237: if (@matches) {
1.508 albertel 2238: $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 2239: }
2240: }
2241: if ($message) {
2242: return '<message type="warning">'.$message.'</message>';
2243: }
2244: return;
2245: }
2246:
1.131 bowersj2 2247: sub printHelper {
1.115 bowersj2 2248: my $r = shift;
2249:
2250: if ($r->header_only) {
1.373 albertel 2251: if ($env{'browser.mathml'}) {
1.241 www 2252: &Apache::loncommon::content_type($r,'text/xml');
1.131 bowersj2 2253: } else {
1.241 www 2254: &Apache::loncommon::content_type($r,'text/html');
1.131 bowersj2 2255: }
2256: $r->send_http_header;
2257: return OK;
1.115 bowersj2 2258: }
2259:
1.131 bowersj2 2260: # Send header, nocache
1.373 albertel 2261: if ($env{'browser.mathml'}) {
1.241 www 2262: &Apache::loncommon::content_type($r,'text/xml');
1.115 bowersj2 2263: } else {
1.241 www 2264: &Apache::loncommon::content_type($r,'text/html');
1.115 bowersj2 2265: }
2266: &Apache::loncommon::no_cache($r);
2267: $r->send_http_header;
2268: $r->rflush();
2269:
1.131 bowersj2 2270: # Unfortunately, this helper is so complicated we have to
2271: # write it by hand
2272:
2273: Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
2274:
1.176 bowersj2 2275: my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146 bowersj2 2276: $helper->declareVar('symb');
1.156 bowersj2 2277: $helper->declareVar('postdata');
1.290 sakharuk 2278: $helper->declareVar('curseed');
2279: $helper->declareVar('probstatus');
1.156 bowersj2 2280: $helper->declareVar('filename');
2281: $helper->declareVar('construction');
1.178 sakharuk 2282: $helper->declareVar('assignment');
1.262 sakharuk 2283: $helper->declareVar('style_file');
1.340 foxr 2284: $helper->declareVar('student_sort');
1.363 foxr 2285: $helper->declareVar('FINISHPAGE');
1.366 foxr 2286: $helper->declareVar('PRINT_TYPE');
1.372 foxr 2287: $helper->declareVar("showallfoils");
1.483 foxr 2288: $helper->declareVar("STUDENTS");
1.363 foxr 2289:
2290: # The page breaks can get loaded initially from the course environment:
1.394 foxr 2291: # But we only do this in the initial state so that they are allowed to change.
2292: #
1.366 foxr 2293:
1.416 foxr 2294: # $helper->{VARS}->{FINISHPAGE} = '';
1.363 foxr 2295:
2296: &Apache::loncommon::restore_course_settings('print',
1.366 foxr 2297: {'pagebreaks' => 'scalar',
2298: 'lastprinttype' => 'scalar'});
2299:
1.483 foxr 2300: # This will persistently load in the data we want from the
2301: # very first screen.
1.394 foxr 2302:
2303: if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
2304: if (!defined ($env{"form.CURRENT_STATE"})) {
2305:
2306: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
2307: } else {
2308: my $state = $env{"form.CURRENT_STATE"};
2309: if ($state eq "START") {
2310: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
2311: }
2312: }
2313:
1.366 foxr 2314: }
1.481 albertel 2315:
1.483 foxr 2316:
1.156 bowersj2 2317: # Detect whether we're coming from construction space
1.373 albertel 2318: if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235 bowersj2 2319: $helper->{VARS}->{'filename'} = "~$1/$2";
1.156 bowersj2 2320: $helper->{VARS}->{'construction'} = 1;
1.481 albertel 2321: } else {
1.373 albertel 2322: if ($env{'form.postdata'}) {
2323: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482 albertel 2324: if ( $helper->{VARS}->{'symb'} eq '') {
2325: $helper->{VARS}->{'postdata'} = $env{'form.postdata'};
2326: }
1.156 bowersj2 2327: }
1.373 albertel 2328: if ($env{'form.symb'}) {
2329: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156 bowersj2 2330: }
1.373 albertel 2331: if ($env{'form.url'}) {
1.156 bowersj2 2332: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
2333: }
1.416 foxr 2334:
1.157 bowersj2 2335: }
1.481 albertel 2336:
1.373 albertel 2337: if ($env{'form.symb'}) {
2338: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146 bowersj2 2339: }
1.373 albertel 2340: if ($env{'form.url'}) {
1.140 sakharuk 2341: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153 sakharuk 2342:
1.140 sakharuk 2343: }
1.343 albertel 2344: $helper->{VARS}->{'symb'}=
2345: &Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335 albertel 2346: my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178 sakharuk 2347: if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481 albertel 2348:
1.156 bowersj2 2349:
1.146 bowersj2 2350: # Extract map
2351: my $symb = $helper->{VARS}->{'symb'};
1.156 bowersj2 2352: my ($map, $id, $url);
2353: my $subdir;
1.483 foxr 2354: my $is_published=0; # True when printing from resource space.
1.156 bowersj2 2355:
2356: # Get the resource name from construction space
2357: if ($helper->{VARS}->{'construction'}) {
2358: $resourceTitle = substr($helper->{VARS}->{'filename'},
2359: rindex($helper->{VARS}->{'filename'}, '/')+1);
2360: $subdir = substr($helper->{VARS}->{'filename'},
2361: 0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481 albertel 2362: } else {
1.482 albertel 2363: if ($symb ne '') {
2364: ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
2365: $helper->{VARS}->{'postdata'} =
2366: &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
2367: } else {
2368: $url = $helper->{VARS}->{'postdata'};
1.483 foxr 2369: $is_published=1; # From resource space.
1.482 albertel 2370: }
2371: $url = &Apache::lonnet::clutter($url);
1.481 albertel 2372:
1.156 bowersj2 2373: if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238 bowersj2 2374: my $postdata = $helper->{VARS}->{'postdata'};
2375: $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156 bowersj2 2376: }
2377: $subdir = &Apache::lonnet::filelocation("", $url);
1.128 bowersj2 2378: }
1.373 albertel 2379: if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
2380: $helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230 albertel 2381: }
1.373 albertel 2382: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
2383: $helper->{VARS}->{'probstatus'}=$env{'form.problemtype'};
1.290 sakharuk 2384: }
1.115 bowersj2 2385:
1.192 bowersj2 2386: my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
2387:
1.481 albertel 2388: Apache::lonhelper::registerHelperTags();
1.119 bowersj2 2389:
1.131 bowersj2 2390: # "Delete everything after the last slash."
1.119 bowersj2 2391: $subdir =~ s|/[^/]+$||;
2392:
1.131 bowersj2 2393: # What can be printed is a very dynamic decision based on
2394: # lots of factors. So we need to dynamically build this list.
2395: # To prevent security leaks, states are only added to the wizard
2396: # if they can be reached, which ensures manipulating the form input
2397: # won't allow anyone to reach states they shouldn't have permission
2398: # to reach.
2399:
2400: # printChoices is tracking the kind of printing the user can
2401: # do, and will be used in a choices construction later.
2402: # In the meantime we will be adding states and elements to
2403: # the helper by hand.
2404: my $printChoices = [];
2405: my $paramHash;
1.130 sakharuk 2406:
1.240 albertel 2407: if ($resourceTitle) {
1.458 www 2408: push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156 bowersj2 2409: }
2410:
1.238 bowersj2 2411: # Useful filter strings
1.287 albertel 2412: my $isProblem = '($res->is_problem()||$res->contains_problem) ';
1.238 bowersj2 2413: $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.287 albertel 2414: my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence()';
2415: my $isNotMap = '!$res->is_sequence()';
1.238 bowersj2 2416: $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
2417: my $isMap = '$res->is_map()';
1.342 albertel 2418: my $symbFilter = '$res->shown_symb()';
2419: my $urlValue = '$res->link()';
1.238 bowersj2 2420:
2421: $helper->declareVar('SEQUENCE');
2422:
1.465 albertel 2423: # If we're in a sequence...
1.416 foxr 2424:
1.465 albertel 2425: my $start_new_option;
2426: if ($perm{'pav'}) {
2427: $start_new_option =
2428: "<option text='".&mt('Start new page<br />before selected').
2429: "' variable='FINISHPAGE' />";
2430: }
1.238 bowersj2 2431:
1.483 foxr 2432: if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
1.350 foxr 2433:
1.243 bowersj2 2434: $helper->{VARS}->{'postdata'} &&
2435: $helper->{VARS}->{'assignment'}) {
1.131 bowersj2 2436: # Allow problems from sequence
1.458 www 2437: push @{$printChoices}, [&mt('Selected <b>Problems</b> in folder <b><i>[_1]</i></b>',$sequenceTitle), 'map_problems', 'CHOOSE_PROBLEMS'];
1.131 bowersj2 2438: # Allow all resources from sequence
1.458 www 2439: push @{$printChoices}, [&mt('Selected <b>Resources</b> in folder <b><i>[_1]</i></b>',$sequenceTitle), 'map_problems_pages', 'CHOOSE_PROBLEMS_HTML'];
1.465 albertel 2440:
1.131 bowersj2 2441: my $helperFragment = <<HELPERFRAGMENT;
1.155 sakharuk 2442: <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print">
1.435 foxr 2443: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2444: closeallpages="1">
1.144 bowersj2 2445: <nextstate>PAGESIZE</nextstate>
1.435 foxr 2446: <filterfunc>return $isProblem;</filterfunc>
1.131 bowersj2 2447: <mapurl>$map</mapurl>
1.238 bowersj2 2448: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2449: $start_new_option
1.131 bowersj2 2450: </resource>
2451: </state>
2452:
1.155 sakharuk 2453: <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print">
1.435 foxr 2454: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2455: closeallpages="1">
1.144 bowersj2 2456: <nextstate>PAGESIZE</nextstate>
1.435 foxr 2457: <filterfunc>return $isNotMap;</filterfunc>
1.131 bowersj2 2458: <mapurl>$map</mapurl>
1.238 bowersj2 2459: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2460: $start_new_option
1.131 bowersj2 2461: </resource>
2462: </state>
2463: HELPERFRAGMENT
1.121 bowersj2 2464:
1.326 sakharuk 2465: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121 bowersj2 2466: }
2467:
1.397 albertel 2468: # If the user has pfo (print for otheres) allow them to print all
1.354 foxr 2469: # problems and resources in the entier course, optionally for selected students
1.483 foxr 2470: if ($perm{'pfo'} && !$is_published &&
1.481 albertel 2471: ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) {
2472:
1.509 ! albertel 2473: push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
! 2474: push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.284 albertel 2475: &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS);
1.155 sakharuk 2476: <state name="ALL_PROBLEMS" title="Select Problem(s) to print">
1.287 albertel 2477: <resource variable="RESOURCES" toponly='0' multichoice="1"
2478: suppressEmptySequences='0' addstatus="1" closeallpages="1">
1.144 bowersj2 2479: <nextstate>PAGESIZE</nextstate>
1.192 bowersj2 2480: <filterfunc>return $isProblemOrMap;</filterfunc>
1.287 albertel 2481: <choicefunc>return $isNotMap;</choicefunc>
1.238 bowersj2 2482: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2483: $start_new_option
1.284 albertel 2484: </resource>
2485: </state>
1.354 foxr 2486: <state name="ALL_RESOURCES" title="Select Resource(s) to print">
2487: <resource variable="RESOURCES" toponly='0' multichoice='1'
2488: suppressEmptySequences='0' addstatus='1' closeallpages='1'>
2489: <nextstate>PAGESIZE</nextstate>
2490: <filterfunc>return $isNotMap; </filterfunc>
2491: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2492: $start_new_option
1.354 foxr 2493: </resource>
2494: </state>
1.284 albertel 2495: ALL_PROBLEMS
1.132 bowersj2 2496:
1.284 albertel 2497: if ($helper->{VARS}->{'assignment'}) {
1.483 foxr 2498: 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 2499: 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 2500: }
1.424 foxr 2501:
1.507 albertel 2502: my $randomly_ordered_warning =
2503: &get_randomly_ordered_warning($helper,$map);
2504:
1.424 foxr 2505: # resource_selector will hold a few states that:
2506: # - Allow resources to be selected for printing.
2507: # - Determine pagination between assignments.
2508: # - Determine how many assignments should be bundled into a single PDF.
2509: # TODO:
2510: # Probably good to do things like separate this up into several vars, each
2511: # with one state, and use REGEXPs at inclusion time to set state names
2512: # and next states for better mix and match capability
2513: #
1.284 albertel 2514: my $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 2515: <state name="SELECT_PROBLEMS" title="Select resources to print">
1.507 albertel 2516: $randomly_ordered_warning
2517:
1.424 foxr 2518: <nextstate>PRINT_FORMATTING</nextstate>
1.284 albertel 2519: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 2520: <resource variable="RESOURCES" multichoice="1" addstatus="1"
2521: closeallpages="1">
1.254 sakharuk 2522: <filterfunc>return $isProblem;</filterfunc>
1.148 bowersj2 2523: <mapurl>$map</mapurl>
1.254 sakharuk 2524: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2525: $start_new_option
1.147 bowersj2 2526: </resource>
1.424 foxr 2527: </state>
2528: <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155 sakharuk 2529: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149 bowersj2 2530: <choices variable="EMPTY_PAGES">
1.204 sakharuk 2531: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
2532: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
2533: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
2534: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 2535: </choices>
1.424 foxr 2536: <nextstate>PAGESIZE</nextstate>
1.429 foxr 2537: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
2538: <choices variable="SPLIT_PDFS">
2539: <choice computer="all">All assignments in a single PDF file</choice>
2540: <choice computer="sections">Each PDF contains exactly one section</choice>
2541: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 2542: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
2543: Specify the number of assignments per PDF:</choice>
1.429 foxr 2544: </choices>
1.424 foxr 2545: </state>
1.284 albertel 2546: RESOURCE_SELECTOR
2547:
2548: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS);
2549: <state name="CHOOSE_STUDENTS" title="Select Students and Resources">
1.485 albertel 2550: <message><b>Select sorting order of printout</b> </message>
1.340 foxr 2551: <choices variable='student_sort'>
2552: <choice computer='0'>Sort by section then student</choice>
2553: <choice computer='1'>Sort by students across sections.</choice>
2554: </choices>
1.437 foxr 2555: <message><br /><hr /><br /> </message>
1.425 foxr 2556: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_PROBLEMS" coursepersonnel="1"/>
1.424 foxr 2557: </state>
1.284 albertel 2558: $resource_selector
1.131 bowersj2 2559: CHOOSE_STUDENTS
1.292 albertel 2560:
1.373 albertel 2561: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2562: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292 albertel 2563: my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
2564: my $namechoice='<choice></choice>';
1.337 albertel 2565: foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294 albertel 2566: if ($name =~ /^error: 2 /) { next; }
1.381 albertel 2567: if ($name =~ /^type\0/) { next; }
1.292 albertel 2568: $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
2569: }
1.389 foxr 2570:
2571:
2572: my %code_values;
1.405 albertel 2573: my %codes_to_print;
1.411 albertel 2574: foreach my $key (@names) {
1.389 foxr 2575: %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405 albertel 2576: foreach my $key (keys(%code_values)) {
2577: $codes_to_print{$key} = 1;
1.388 foxr 2578: }
2579: }
1.389 foxr 2580:
1.452 albertel 2581: my $code_selection;
1.405 albertel 2582: foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389 foxr 2583: my $choice = $code;
2584: if ($code =~ /^[A-Z]+$/) { # Alpha code
2585: $choice = &letters_to_num($code);
2586: }
1.432 albertel 2587: push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388 foxr 2588: }
1.436 albertel 2589: if (%codes_to_print) {
2590: $code_selection .='
1.472 albertel 2591: <message><b>Choose single CODE from list:</b></message>
1.448 albertel 2592: <message></td><td></message>
1.452 albertel 2593: <dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
2594: <choice></choice>
1.448 albertel 2595: <exec>
2596: push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
2597: </exec>
1.452 albertel 2598: </dropdown>
1.468 foxr 2599: <message></td></tr><tr><td></message>
1.436 albertel 2600: '.$/;
1.448 albertel 2601:
1.436 albertel 2602: }
1.432 albertel 2603:
2604:
1.381 albertel 2605: open(FH,$Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
2606: my $codechoice='';
2607: foreach my $line (<FH>) {
2608: my ($name,$description,$code_type,$code_length)=
2609: (split(/:/,$line))[0,1,2,4];
2610: if ($code_length > 0 &&
2611: $code_type =~/^(letter|number|-1)/) {
2612: $codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
2613: }
2614: }
2615: if ($codechoice eq '') {
2616: $codechoice='<choice computer="default">Default</choice>';
2617: }
1.284 albertel 2618: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1);
1.468 foxr 2619: <state name="CHOOSE_ANON1" title="Specify CODEd Assignments">
1.424 foxr 2620: <nextstate>SELECT_PROBLEMS</nextstate>
1.468 foxr 2621: <message><h4>Fill out one of the forms below</h4></message>
2622: <message><br /><hr /> <br /></message>
2623: <message><h3>Generate new CODEd Assignments</h3></message>
2624: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 2625: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
2626: <validator>
2627: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.382 foxr 2628: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 2629: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
2630: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 2631: return "You need to specify the number of assignments to print";
2632: }
2633: return undef;
2634: </validator>
2635: </string>
2636: <message></td></tr><tr><td></message>
1.501 albertel 2637: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 2638: <message></td><td></message>
2639: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
2640: <message></td></tr><tr><td></message>
2641: <message><b>Bubble sheet type:</b></message>
2642: <message></td><td></message>
2643: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
2644: $codechoice
2645: </dropdown>
1.468 foxr 2646: <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>
2647: <message></td></tr><tr><td></table></message>
1.472 albertel 2648: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
1.468 foxr 2649: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 2650: <string variable="SINGLE_CODE" size="10">
1.382 foxr 2651: <validator>
2652: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 2653: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
2654: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.382 foxr 2655: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
2656: \$helper->{'VARS'}{'CODE_OPTION'});
2657: } else {
2658: return undef; # Other forces control us.
2659: }
2660: </validator>
2661: </string>
1.472 albertel 2662: <message></td></tr><tr><td></message>
1.432 albertel 2663: $code_selection
1.468 foxr 2664: <message></td></tr></table></message>
1.472 albertel 2665: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
1.468 foxr 2666: <message><b>Select saved CODEs:</b></message>
1.381 albertel 2667: <message></td><td></message>
1.292 albertel 2668: <dropdown variable="REUSE_OLD_CODES">
2669: $namechoice
2670: </dropdown>
1.412 albertel 2671: <message></td></tr></table></message>
1.284 albertel 2672: </state>
1.424 foxr 2673: $resource_selector
1.284 albertel 2674: CHOOSE_ANON1
1.254 sakharuk 2675:
1.272 sakharuk 2676:
1.254 sakharuk 2677: if ($helper->{VARS}->{'assignment'}) {
1.483 foxr 2678: 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 2679: 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 2680: }
1.284 albertel 2681:
2682:
2683: $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 2684: <state name="SELECT_RESOURCES" title="Select Resources">
1.507 albertel 2685: $randomly_ordered_warning
2686:
1.424 foxr 2687: <nextstate>PRINT_FORMATTING</nextstate>
1.254 sakharuk 2688: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 2689: <resource variable="RESOURCES" multichoice="1" addstatus="1"
2690: closeallpages="1">
1.254 sakharuk 2691: <filterfunc>return $isNotMap;</filterfunc>
2692: <mapurl>$map</mapurl>
2693: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2694: $start_new_option
1.254 sakharuk 2695: </resource>
1.424 foxr 2696: </state>
2697: <state name="PRINT_FORMATTING" title="Format of the print job">
2698: <nextstate>NUMBER_PER_PDF</nextstate>
1.254 sakharuk 2699: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
2700: <choices variable="EMPTY_PAGES">
2701: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
2702: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
2703: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
2704: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 2705: </choices>
1.424 foxr 2706: <nextstate>PAGESIZE</nextstate>
1.429 foxr 2707: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
2708: <choices variable="SPLIT_PDFS">
2709: <choice computer="all">All assignments in a single PDF file</choice>
2710: <choice computer="sections">Each PDF contains exactly one section</choice>
2711: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 2712: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
2713: Specify the number of assignments per PDF:</choice>
1.429 foxr 2714: </choices>
1.424 foxr 2715: </state>
1.284 albertel 2716: RESOURCE_SELECTOR
2717:
2718: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
2719: <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340 foxr 2720: <choices variable='student_sort'>
2721: <choice computer='0'>Sort by section then student</choice>
2722: <choice computer='1'>Sort by students across sections.</choice>
2723: </choices>
1.437 foxr 2724: <message><br /><hr /><br /></message>
1.426 foxr 2725: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340 foxr 2726:
1.424 foxr 2727: </state>
1.284 albertel 2728: $resource_selector
1.254 sakharuk 2729: CHOOSE_STUDENTS1
2730:
1.284 albertel 2731: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472 albertel 2732: <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424 foxr 2733: <nextstate>SELECT_RESOURCES</nextstate>
1.472 albertel 2734: <message><h4>Fill out one of the forms below</h4></message>
2735: <message><br /><hr /> <br /></message>
2736: <message><h3>Generate new CODEd Assignments</h3></message>
2737: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 2738: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
2739: <validator>
2740: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386 foxr 2741: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 2742: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
2743: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 2744: return "You need to specify the number of assignments to print";
2745: }
2746: return undef;
2747: </validator>
2748: </string>
2749: <message></td></tr><tr><td></message>
1.501 albertel 2750: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 2751: <message></td><td></message>
2752: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
2753: <message></td></tr><tr><td></message>
2754: <message><b>Bubble sheet type:</b></message>
2755: <message></td><td></message>
2756: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
2757: $codechoice
2758: </dropdown>
1.472 albertel 2759: <message></td></tr><tr><td></table></message>
2760: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
2761: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 2762: <string variable="SINGLE_CODE" size="10">
1.386 foxr 2763: <validator>
2764: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 2765: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
2766: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386 foxr 2767: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
2768: \$helper->{'VARS'}{'CODE_OPTION'});
2769: } else {
2770: return undef; # Other forces control us.
2771: }
2772: </validator>
2773: </string>
1.472 albertel 2774: <message></td></tr><tr><td></message>
1.432 albertel 2775: $code_selection
1.472 albertel 2776: <message></td></tr></table></message>
2777: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
2778: <message><b>Select saved CODEs:</b></message>
1.381 albertel 2779: <message></td><td></message>
1.294 albertel 2780: <dropdown variable="REUSE_OLD_CODES">
2781: $namechoice
2782: </dropdown>
1.412 albertel 2783: <message></td></tr></table></message>
1.424 foxr 2784: </state>
1.284 albertel 2785: $resource_selector
2786: CHOOSE_ANON2
1.481 albertel 2787: }
2788:
1.121 bowersj2 2789: # FIXME: That RE should come from a library somewhere.
1.483 foxr 2790: if (($perm{'pav'}
1.482 albertel 2791: && $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
2792: && (defined($helper->{'VARS'}->{'construction'})
2793: ||
2794: (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
2795: &&
2796: $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483 foxr 2797: ))
2798: && $helper->{VARS}->{'assignment'} eq ""
1.482 albertel 2799: ) {
1.238 bowersj2 2800:
1.482 albertel 2801: my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
2802: 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 2803: my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482 albertel 2804: <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458 www 2805:
1.138 bowersj2 2806: <files variable="FILES" multichoice='1'>
1.144 bowersj2 2807: <nextstate>PAGESIZE</nextstate>
1.138 bowersj2 2808: <filechoice>return '$subdir';</filechoice>
1.139 bowersj2 2809: CHOOSE_FROM_SUBDIR
2810:
1.238 bowersj2 2811: # this is broken up because I really want interpolation above,
2812: # and I really DON'T want it below
1.139 bowersj2 2813: $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225 bowersj2 2814: <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
2815: $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131 bowersj2 2816: </filefilter>
1.138 bowersj2 2817: </files>
1.131 bowersj2 2818: </state>
2819: CHOOSE_FROM_SUBDIR
1.139 bowersj2 2820: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131 bowersj2 2821: }
1.238 bowersj2 2822:
2823: # Allow the user to select any sequence in the course, feed it to
2824: # another resource selector for that sequence
1.483 foxr 2825: if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509 ! albertel 2826: push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249 sakharuk 2827: 'select_sequences', 'CHOOSE_SEQUENCE'];
1.244 bowersj2 2828: my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
2829: #Escape apostrophes and backslashes for Perl
2830: $escapedSequenceName =~ s/\\/\\\\/g;
2831: $escapedSequenceName =~ s/'/\\'/g;
1.239 bowersj2 2832: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238 bowersj2 2833: <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
2834: <message>Select the sequence to print resources from:</message>
2835: <resource variable="SEQUENCE">
2836: <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
2837: <filterfunc>return \$res->is_sequence;</filterfunc>
2838: <valuefunc>return $urlValue;</valuefunc>
1.447 foxr 2839: <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391 foxr 2840: </choicefunc>
1.238 bowersj2 2841: </resource>
2842: </state>
2843: <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
2844: <message>(mark desired resources then click "next" button) <br /></message>
1.435 foxr 2845: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2846: closeallpages="1">
1.238 bowersj2 2847: <nextstate>PAGESIZE</nextstate>
1.466 albertel 2848: <filterfunc>return $isNotMap</filterfunc>
1.244 bowersj2 2849: <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238 bowersj2 2850: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2851: $start_new_option
1.238 bowersj2 2852: </resource>
2853: </state>
2854: CHOOSE_FROM_ANY_SEQUENCE
1.239 bowersj2 2855: }
1.481 albertel 2856:
1.131 bowersj2 2857: # Generate the first state, to select which resources get printed.
1.223 bowersj2 2858: Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131 bowersj2 2859: $paramHash = Apache::lonhelper::getParamHash();
1.155 sakharuk 2860: $paramHash->{MESSAGE_TEXT} = "";
1.131 bowersj2 2861: Apache::lonhelper::message->new();
2862: $paramHash = Apache::lonhelper::getParamHash();
2863: $paramHash->{'variable'} = 'PRINT_TYPE';
2864: $paramHash->{CHOICES} = $printChoices;
2865: Apache::lonhelper::choices->new();
1.161 bowersj2 2866:
1.223 bowersj2 2867: my $startedTable = 0; # have we started an HTML table yet? (need
2868: # to close it later)
2869:
1.397 albertel 2870: if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or
1.170 sakharuk 2871: ($helper->{VARS}->{'construction'} eq '1')) {
1.497 www 2872: addMessage("<hr width='33%' /><table><tr><td align='right'>".
2873: '<label for="ANSWER_TYPE_forminput">'.
2874: &mt('Print').
2875: "</label>: </td><td>");
1.161 bowersj2 2876: $paramHash = Apache::lonhelper::getParamHash();
1.162 sakharuk 2877: $paramHash->{'variable'} = 'ANSWER_TYPE';
2878: $helper->declareVar('ANSWER_TYPE');
1.161 bowersj2 2879: $paramHash->{CHOICES} = [
1.242 sakharuk 2880: ['Without Answers', 'yes'],
2881: ['With Answers', 'no'],
1.368 albertel 2882: ['Only Answers', 'only']
1.289 sakharuk 2883: ];
1.210 sakharuk 2884: Apache::lonhelper::dropdown->new();
1.223 bowersj2 2885: addMessage("</td></tr>");
2886: $startedTable = 1;
1.161 bowersj2 2887: }
1.209 sakharuk 2888:
1.397 albertel 2889: if ($perm{'pav'}) {
1.223 bowersj2 2890: if (!$startedTable) {
1.497 www 2891: addMessage("<hr width='33%' /><table><tr><td align='right'>".
2892: '<label for="LATEX_TYPE_forminput">'.
2893: &mt('LaTeX mode').
2894: "</label>: </td><td>");
1.223 bowersj2 2895: $startedTable = 1;
2896: } else {
1.497 www 2897: addMessage("<tr><td align='right'>".
2898: '<label for="LATEX_TYPE_forminput">'.
2899: &mt('LaTeX mode').
2900: "</label>: </td><td>");
1.223 bowersj2 2901: }
1.203 sakharuk 2902: $paramHash = Apache::lonhelper::getParamHash();
2903: $paramHash->{'variable'} = 'LATEX_TYPE';
2904: $helper->declareVar('LATEX_TYPE');
2905: if ($helper->{VARS}->{'construction'} eq '1') {
2906: $paramHash->{CHOICES} = [
1.223 bowersj2 2907: ['standard LaTeX mode', 'standard'],
2908: ['LaTeX batchmode', 'batchmode'], ];
1.203 sakharuk 2909: } else {
2910: $paramHash->{CHOICES} = [
1.223 bowersj2 2911: ['LaTeX batchmode', 'batchmode'],
2912: ['standard LaTeX mode', 'standard'] ];
1.203 sakharuk 2913: }
1.210 sakharuk 2914: Apache::lonhelper::dropdown->new();
1.218 sakharuk 2915:
1.497 www 2916: addMessage("</td></tr><tr><td align='right'>".
1.506 albertel 2917: '<label for="TABLE_CONTENTS_forminput">'.
1.497 www 2918: &mt('Print Table of Contents').
2919: "</label>: </td><td>");
1.209 sakharuk 2920: $paramHash = Apache::lonhelper::getParamHash();
2921: $paramHash->{'variable'} = 'TABLE_CONTENTS';
2922: $helper->declareVar('TABLE_CONTENTS');
2923: $paramHash->{CHOICES} = [
1.223 bowersj2 2924: ['No', 'no'],
2925: ['Yes', 'yes'] ];
1.210 sakharuk 2926: Apache::lonhelper::dropdown->new();
1.223 bowersj2 2927: addMessage("</td></tr>");
1.214 sakharuk 2928:
1.220 sakharuk 2929: if (not $helper->{VARS}->{'construction'}) {
1.497 www 2930: addMessage("<tr><td align='right'>".
2931: '<label for="TABLE_INDEX_forminput">'.
2932: &mt('Print Index').
2933: "</label>: </td><td>");
1.220 sakharuk 2934: $paramHash = Apache::lonhelper::getParamHash();
2935: $paramHash->{'variable'} = 'TABLE_INDEX';
2936: $helper->declareVar('TABLE_INDEX');
2937: $paramHash->{CHOICES} = [
1.223 bowersj2 2938: ['No', 'no'],
2939: ['Yes', 'yes'] ];
1.220 sakharuk 2940: Apache::lonhelper::dropdown->new();
1.223 bowersj2 2941: addMessage("</td></tr>");
1.497 www 2942: addMessage("<tr><td align='right'>".
2943: '<label for="PRINT_DISCUSSIONS_forminput">'.
2944: &mt('Print Discussions').
2945: "</label>: </td><td>");
1.309 sakharuk 2946: $paramHash = Apache::lonhelper::getParamHash();
2947: $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';
2948: $helper->declareVar('PRINT_DISCUSSIONS');
2949: $paramHash->{CHOICES} = [
2950: ['No', 'no'],
2951: ['Yes', 'yes'] ];
2952: Apache::lonhelper::dropdown->new();
2953: addMessage("</td></tr>");
1.372 foxr 2954:
1.397 albertel 2955: addMessage("<tr><td align = 'right'> </td><td>");
2956: $paramHash = Apache::lonhelper::getParamHash();
2957: $paramHash->{'multichoice'} = "true";
2958: $paramHash->{'allowempty'} = "true";
2959: $paramHash->{'variable'} = "showallfoils";
2960: $paramHash->{'CHOICES'} = [ ["Show all foils", "1"] ];
2961: Apache::lonhelper::choices->new();
2962: addMessage("</td></tr>");
1.220 sakharuk 2963: }
1.219 sakharuk 2964:
1.230 albertel 2965: if ($helper->{'VARS'}->{'construction'}) {
1.505 albertel 2966: my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497 www 2967: my $randseedtext=&mt("Use random seed");
2968: my $stylefiletext=&mt("Use style file");
1.506 albertel 2969: my $selectfiletext=&mt("Select style file");
1.497 www 2970:
1.265 sakharuk 2971: my $xmlfrag .= <<"RNDSEED";
1.497 www 2972: <message><tr><td align='right'>
2973: <label for="curseed_forminput">$randseedtext</label>:
2974: </td><td></message>
1.230 albertel 2975: <string variable="curseed" size="15" maxlength="15">
2976: <defaultvalue>
2977: return $helper->{VARS}->{'curseed'};
2978: </defaultvalue>
1.262 sakharuk 2979: </string>
1.497 www 2980: <message></td></tr><tr><td align="right">
1.503 albertel 2981: <label for="style_file">$stylefiletext</label>:
1.497 www 2982: </td><td></message>
1.504 albertel 2983: <string variable="style_file" size="40">
2984: <defaultvalue>
1.505 albertel 2985: return $stylevalue;
1.504 albertel 2986: </defaultvalue>
1.506 albertel 2987: </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 2988: <choices allowempty="1" multichoice="true" variable="showallfoils">
1.506 albertel 2989: <choice computer="1">Show all foils</choice>
1.371 foxr 2990: </choices>
1.378 albertel 2991: <message></td></tr></message>
1.230 albertel 2992: RNDSEED
2993: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.372 foxr 2994: }
1.223 bowersj2 2995: }
1.264 sakharuk 2996:
2997:
2998:
1.218 sakharuk 2999:
1.223 bowersj2 3000: if ($startedTable) {
3001: addMessage("</table>");
1.215 sakharuk 3002: }
1.161 bowersj2 3003:
1.131 bowersj2 3004: Apache::lonprintout::page_format_state->new("FORMAT");
3005:
1.144 bowersj2 3006: # Generate the PAGESIZE state which will offer the user the margin
3007: # choices if they select one column
3008: Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
3009: Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
3010:
3011:
1.131 bowersj2 3012: $helper->process();
3013:
1.416 foxr 3014:
1.131 bowersj2 3015: # MANUAL BAILOUT CONDITION:
3016: # If we're in the "final" state, bailout and return to handler
3017: if ($helper->{STATE} eq 'FINAL') {
3018: return $helper;
3019: }
1.130 sakharuk 3020:
1.131 bowersj2 3021: $r->print($helper->display());
1.395 www 3022: if ($helper->{STATE} eq 'START') {
3023: &recently_generated($r);
3024: }
1.333 albertel 3025: &Apache::lonhelper::unregisterHelperTags();
1.115 bowersj2 3026:
3027: return OK;
3028: }
3029:
1.1 www 3030:
3031: 1;
1.119 bowersj2 3032:
3033: package Apache::lonprintout::page_format_state;
3034:
3035: =pod
3036:
1.131 bowersj2 3037: =head1 Helper element: page_format_state
3038:
3039: See lonhelper.pm documentation for discussion of the helper framework.
1.119 bowersj2 3040:
1.131 bowersj2 3041: Apache::lonprintout::page_format_state is an element that gives the
3042: user an opportunity to select the page layout they wish to print
3043: with: Number of columns, portrait/landscape, and paper size. If you
3044: want to change the paper size choices, change the @paperSize array
3045: contents in this package.
1.119 bowersj2 3046:
1.131 bowersj2 3047: page_format_state is always directly invoked in lonprintout.pm, so there
3048: is no tag interface. You actually pass parameters to the constructor.
1.119 bowersj2 3049:
3050: =over 4
3051:
1.131 bowersj2 3052: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119 bowersj2 3053:
3054: =back
3055:
3056: =cut
3057:
1.131 bowersj2 3058: use Apache::lonhelper;
1.119 bowersj2 3059:
3060: no strict;
1.131 bowersj2 3061: @ISA = ("Apache::lonhelper::element");
1.119 bowersj2 3062: use strict;
1.266 sakharuk 3063: use Apache::lonlocal;
1.373 albertel 3064: use Apache::lonnet;
1.119 bowersj2 3065:
3066: my $maxColumns = 2;
1.376 albertel 3067: # it'd be nice if these all worked
3068: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
3069: # "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
3070: # "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]",
3071: # "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326 sakharuk 3072: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
1.376 albertel 3073: "a4 [210x297 mm]");
1.119 bowersj2 3074:
3075: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
3076: # Paper type
3077:
3078: sub new {
1.131 bowersj2 3079: my $self = Apache::lonhelper::element->new();
1.119 bowersj2 3080:
1.135 bowersj2 3081: shift;
3082:
1.131 bowersj2 3083: $self->{'variable'} = shift;
1.134 bowersj2 3084: my $helper = Apache::lonhelper::getHelper();
1.135 bowersj2 3085: $helper->declareVar($self->{'variable'});
1.131 bowersj2 3086: bless($self);
1.119 bowersj2 3087: return $self;
3088: }
3089:
3090: sub render {
3091: my $self = shift;
1.131 bowersj2 3092: my $helper = Apache::lonhelper::getHelper();
1.119 bowersj2 3093: my $result = '';
1.131 bowersj2 3094: my $var = $self->{'variable'};
1.266 sakharuk 3095: my $PageLayout=&mt('Page layout');
3096: my $NumberOfColumns=&mt('Number of columns');
3097: my $PaperType=&mt('Paper type');
1.506 albertel 3098: my $landscape=&mt('Landscape');
3099: my $portrait=&mt('Portrait');
1.119 bowersj2 3100: $result .= <<STATEHTML;
3101:
1.223 bowersj2 3102: <hr width="33%" />
1.119 bowersj2 3103: <table cellpadding="3">
3104: <tr>
1.266 sakharuk 3105: <td align="center"><b>$PageLayout</b></td>
3106: <td align="center"><b>$NumberOfColumns</b></td>
3107: <td align="center"><b>$PaperType</b></td>
1.119 bowersj2 3108: </tr>
3109: <tr>
3110: <td>
1.506 albertel 3111: <label><input type="radio" name="${var}.layout" value="L" /> $landscape </label><br />
3112: <label><input type="radio" name="${var}.layout" value="P" checked='1' /> $portrait </label>
1.119 bowersj2 3113: </td>
1.155 sakharuk 3114: <td align="center">
1.119 bowersj2 3115: <select name="${var}.cols">
3116: STATEHTML
3117:
3118: my $i;
3119: for ($i = 1; $i <= $maxColumns; $i++) {
1.144 bowersj2 3120: if ($i == 2) {
1.119 bowersj2 3121: $result .= "<option value='$i' selected>$i</option>\n";
3122: } else {
3123: $result .= "<option value='$i'>$i</option>\n";
3124: }
3125: }
3126:
3127: $result .= "</select></td><td>\n";
3128: $result .= "<select name='${var}.paper'>\n";
3129:
1.373 albertel 3130: my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398 albertel 3131: my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
3132: $DefaultPaperSize=~s/\s//g;
1.304 sakharuk 3133: if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119 bowersj2 3134: $i = 0;
3135: foreach (@paperSize) {
1.326 sakharuk 3136: $_=~/(\w+)/;
3137: my $papersize=$1;
1.304 sakharuk 3138: if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.326 sakharuk 3139: $result .= "<option selected value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119 bowersj2 3140: } else {
1.326 sakharuk 3141: $result .= "<option value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119 bowersj2 3142: }
3143: $i++;
3144: }
3145: $result .= "</select></td></tr></table>";
3146: return $result;
1.135 bowersj2 3147: }
3148:
3149: sub postprocess {
3150: my $self = shift;
3151:
3152: my $var = $self->{'variable'};
1.136 bowersj2 3153: my $helper = Apache::lonhelper->getHelper();
1.135 bowersj2 3154: $helper->{VARS}->{$var} =
1.373 albertel 3155: $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
3156: $env{"form.$var.paper"};
1.135 bowersj2 3157: return 1;
1.119 bowersj2 3158: }
3159:
3160: 1;
1.144 bowersj2 3161:
3162: package Apache::lonprintout::page_size_state;
3163:
3164: =pod
3165:
3166: =head1 Helper element: page_size_state
3167:
3168: See lonhelper.pm documentation for discussion of the helper framework.
3169:
3170: Apache::lonprintout::page_size_state is an element that gives the
3171: user the opportunity to further refine the page settings if they
3172: select a single-column page.
3173:
3174: page_size_state is always directly invoked in lonprintout.pm, so there
3175: is no tag interface. You actually pass parameters to the constructor.
3176:
3177: =over 4
3178:
3179: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
3180:
3181: =back
3182:
3183: =cut
3184:
3185: use Apache::lonhelper;
1.373 albertel 3186: use Apache::lonnet;
1.144 bowersj2 3187: no strict;
3188: @ISA = ("Apache::lonhelper::element");
3189: use strict;
3190:
3191:
3192:
3193: sub new {
3194: my $self = Apache::lonhelper::element->new();
3195:
3196: shift; # disturbs me (probably prevents subclassing) but works (drops
3197: # package descriptor)... - Jeremy
3198:
3199: $self->{'variable'} = shift;
3200: my $helper = Apache::lonhelper::getHelper();
3201: $helper->declareVar($self->{'variable'});
3202:
3203: # The variable name of the format element, so we can look into
3204: # $helper->{VARS} to figure out whether the columns are one or two
3205: $self->{'formatvar'} = shift;
3206:
1.463 foxr 3207:
1.144 bowersj2 3208: $self->{NEXTSTATE} = shift;
3209: bless($self);
1.467 foxr 3210:
1.144 bowersj2 3211: return $self;
3212: }
3213:
3214: sub render {
3215: my $self = shift;
3216: my $helper = Apache::lonhelper::getHelper();
3217: my $result = '';
3218: my $var = $self->{'variable'};
3219:
1.467 foxr 3220:
3221:
1.144 bowersj2 3222: if (defined $self->{ERROR_MSG}) {
1.464 albertel 3223: $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144 bowersj2 3224: }
3225:
1.438 foxr 3226: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463 foxr 3227:
3228: # Use format to get sensible defaults for the margins:
3229:
3230:
3231: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
3232: ($papersize) = split(/ /, $papersize);
3233:
3234:
3235: if ($laystyle eq 'L') {
3236: $laystyle = 'album';
3237: } else {
3238: $laystyle = 'book';
3239: }
3240:
3241:
1.464 albertel 3242: my %size;
3243: ($size{'width_and_units'},
3244: $size{'height_and_units'},
3245: $size{'margin_and_units'})=
3246: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463 foxr 3247:
1.464 albertel 3248: foreach my $dimension ('width','height','margin') {
3249: ($size{$dimension},$size{$dimension.'_unit'}) =
3250: split(/ +/, $size{$dimension.'_and_units'},2);
3251:
3252: foreach my $unit ('cm','in') {
3253: $size{$dimension.'_options'} .= '<option ';
3254: if ($size{$dimension.'_unit'} eq $unit) {
3255: $size{$dimension.'_options'} .= 'selected="selected" ';
3256: }
3257: $size{$dimension.'_options'} .= '>'.$unit.'</option>';
3258: }
1.438 foxr 3259: }
3260:
1.470 foxr 3261: # Adjust margin for LaTeX margin: .. requires units == cm or in.
3262:
3263: if ($size{'margin_unit'} eq 'in') {
3264: $size{'margin'} += 1;
3265: } else {
3266: $size{'margin'} += 2.54;
3267: }
1.506 albertel 3268: my %text = ('format' => 'How should each column be formatted?',
3269: 'width' => 'Width:',
3270: 'height' => 'Height:',
3271: 'margin' => 'Left Margin:',);
3272: %text = &Apache::lonlocal::texthash(%text);
3273:
1.144 bowersj2 3274: $result .= <<ELEMENTHTML;
3275:
1.506 albertel 3276: <p>$text{'format'}</p>
1.144 bowersj2 3277:
3278: <table cellpadding='3'>
3279: <tr>
1.506 albertel 3280: <td align='right'><b>$text{'width'}</b></td>
1.464 albertel 3281: <td align='left'><input type='text' name='$var.width' value="$size{'width'}" size='4' /></td>
1.144 bowersj2 3282: <td align='left'>
3283: <select name='$var.widthunit'>
1.464 albertel 3284: $size{'width_options'}
1.144 bowersj2 3285: </select>
3286: </td>
3287: </tr>
3288: <tr>
1.506 albertel 3289: <td align='right'><b>$text{'height'}</b></td>
1.464 albertel 3290: <td align='left'><input type='text' name="$var.height" value="$size{'height'}" size='4' /></td>
1.144 bowersj2 3291: <td align='left'>
3292: <select name='$var.heightunit'>
1.464 albertel 3293: $size{'height_options'}
1.144 bowersj2 3294: </select>
3295: </td>
3296: </tr>
3297: <tr>
1.506 albertel 3298: <td align='right'><b>$text{'margin'}</b></td>
1.464 albertel 3299: <td align='left'><input type='text' name='$var.lmargin' value="$size{'margin'}" size='4' /></td>
1.144 bowersj2 3300: <td align='left'>
1.186 bowersj2 3301: <select name='$var.lmarginunit'>
1.464 albertel 3302: $size{'margin_options'}
1.144 bowersj2 3303: </select>
3304: </td>
3305: </tr>
3306: </table>
3307:
1.464 albertel 3308: <!--<p>Hint: Some instructors like to leave scratch space for the student by
3309: making the width much smaller than the width of the page.</p>-->
1.144 bowersj2 3310:
3311: ELEMENTHTML
3312:
3313: return $result;
3314: }
3315:
1.470 foxr 3316:
1.144 bowersj2 3317: sub preprocess {
3318: my $self = shift;
3319: my $helper = Apache::lonhelper::getHelper();
3320:
3321: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467 foxr 3322:
3323: # If the user does not have 'pav' privilege, set default widths and
3324: # on to the next state right away.
3325: #
3326: if (!$perm{'pav'}) {
3327: my $var = $self->{'variable'};
3328: my $format = $helper->{VARS}->{$self->{'formatvar'}};
3329:
3330: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
3331: ($papersize) = split(/ /, $papersize);
3332:
3333:
3334: if ($laystyle eq 'L') {
3335: $laystyle = 'album';
3336: } else {
3337: $laystyle = 'book';
3338: }
3339: # Figure out some good defaults for the print out and set them:
3340:
3341: my %size;
3342: ($size{'width'},
3343: $size{'height'},
3344: $size{'lmargin'})=
3345: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
3346:
3347: foreach my $dim ('width', 'height', 'lmargin') {
3348: my ($value, $units) = split(/ /, $size{$dim});
1.470 foxr 3349:
1.467 foxr 3350: $helper->{VARS}->{"$var.".$dim} = $value;
3351: $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
3352:
3353: }
3354:
3355:
3356: # Transition to the next state
3357:
3358: $helper->changeState($self->{NEXTSTATE});
3359: }
1.144 bowersj2 3360:
3361: return 1;
3362: }
3363:
3364: sub postprocess {
3365: my $self = shift;
3366:
3367: my $var = $self->{'variable'};
3368: my $helper = Apache::lonhelper->getHelper();
1.373 albertel 3369: my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"};
3370: my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"};
3371: my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"};
3372: $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"};
3373: $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"};
3374: $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"};
1.144 bowersj2 3375:
3376: my $error = '';
3377:
3378: # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed
3379: # by an optional period, followed by digits, ending the string
3380:
1.464 albertel 3381: if ($width !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3382: $error .= "Invalid width; please type only a number.<br />\n";
3383: }
1.464 albertel 3384: if ($height !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3385: $error .= "Invalid height; please type only a number.<br />\n";
3386: }
1.464 albertel 3387: if ($lmargin !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3388: $error .= "Invalid left margin; please type only a number.<br />\n";
1.470 foxr 3389: } else {
3390: # Adjust for LaTeX 1.0 inch margin:
3391:
3392: if ($env{"form.${var}.lmarginunit"} eq "in") {
3393: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
3394: } else {
3395: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
3396: }
1.144 bowersj2 3397: }
3398:
3399: if (!$error) {
3400: Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
3401: return 1;
3402: } else {
3403: $self->{ERROR_MSG} = $error;
3404: return 0;
3405: }
3406: }
3407:
3408:
1.119 bowersj2 3409:
1.1 www 3410: __END__
1.6 sakharuk 3411:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>