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