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