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