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