Annotation of loncom/interface/lonprintout.pm, revision 1.531
1.389 foxr 1: # The LearningOnline Network
1.1 www 2: # Printout
3: #
1.531 ! foxr 4: # $Id: lonprintout.pm,v 1.530 2008/04/22 10:24:24 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.517 foxr 1153: '\usepackage[utf8]{inputenc}'."\n".
1.531 ! foxr 1154: '\usepackage[T1]{fontenc}'."\n".
! 1155: '\usepackage{latexsym}'."\n".
1.527 foxr 1156: '\usepackage{amsmath}'.
1157: '\usepackage{amssymb}'.
1158: '\usepackage{amsfonts}'.
1159: '\usepackage{amsthm}'.
1160: '\usepackage{amscd}'.
1.340 foxr 1161: '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}'."\n".
1162: '\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}'."\n".
1163: '\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}'."\n".
1164: '\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}'."\n".
1165: '\setlength{\abovedisplayshortskip}{-0.04in}'."\n".
1166: '\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'."\n".
1167: '\renewenvironment{theindex}{\begin{list}{}{{\vskip 1mm \noindent \large'."\n".
1168: '\textbf{Index}} \newline \setlength{\rightmargin}{0in}'."\n".
1169: '\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.01in}'."\n".
1170: '\setlength{\itemsep}{0.1in}\setlength{\parsep}{-0.02in}'."\n".
1171: '\setlength{\belowdisplayskip}{0.01in}\setlength{\abovedisplayskip}{0.01in}'."\n".
1172: '\setlength{\abovedisplayshortskip}{-0.04in}'."\n".
1173: '\setlength{\belowdisplayshortskip}{0.01in}}}{\end{list}}\begin{document}'."\n";
1.242 sakharuk 1174: return $output;
1175: }
1176:
1177: sub path_to_problem {
1.328 albertel 1178: my ($urlp,$colwidth)=@_;
1.404 albertel 1179: $urlp=&Apache::lonnet::clutter($urlp);
1180:
1.242 sakharuk 1181: my $newurlp = '';
1.328 albertel 1182: $colwidth=~s/\s*mm\s*$//;
1183: #characters average about 2 mm in width
1.360 albertel 1184: if (length($urlp)*2 > $colwidth) {
1.404 albertel 1185: my @elements = split('/',$urlp);
1.328 albertel 1186: my $curlength=0;
1187: foreach my $element (@elements) {
1.404 albertel 1188: if ($element eq '') { next; }
1.328 albertel 1189: if ($curlength+(length($element)*2) > $colwidth) {
1.404 albertel 1190: $newurlp .= '|\vskip -1 mm \verb|';
1191: $curlength=length($element)*2;
1.328 albertel 1192: } else {
1193: $curlength+=length($element)*2;
1.242 sakharuk 1194: }
1.328 albertel 1195: $newurlp.='/'.$element;
1.242 sakharuk 1196: }
1.253 sakharuk 1197: } else {
1198: $newurlp=$urlp;
1.242 sakharuk 1199: }
1200: return '{\small\noindent\verb|'.$newurlp.'|\vskip 0 mm}';
1201: }
1.215 sakharuk 1202:
1.275 sakharuk 1203: sub recalcto_mm {
1204: my $textwidth=shift;
1205: my $LaTeXwidth;
1.339 albertel 1206: if ($textwidth=~/(-?\d+\.?\d*)\s*cm/) {
1.275 sakharuk 1207: $LaTeXwidth = $1*10;
1.339 albertel 1208: } elsif ($textwidth=~/(-?\d+\.?\d*)\s*mm/) {
1.275 sakharuk 1209: $LaTeXwidth = $1;
1.339 albertel 1210: } elsif ($textwidth=~/(-?\d+\.?\d*)\s*in/) {
1.275 sakharuk 1211: $LaTeXwidth = $1*25.4;
1212: }
1213: $LaTeXwidth.=' mm';
1214: return $LaTeXwidth;
1215: }
1216:
1.285 albertel 1217: sub get_textwidth {
1218: my ($helper,$LaTeXwidth)=@_;
1.286 albertel 1219: my $textwidth=$LaTeXwidth;
1.285 albertel 1220: if ($helper->{'VARS'}->{'pagesize.width'}=~/\d+/ &&
1221: $helper->{'VARS'}->{'pagesize.widthunit'}=~/\w+/) {
1.286 albertel 1222: $textwidth=&recalcto_mm($helper->{'VARS'}->{'pagesize.width'}.' '.
1223: $helper->{'VARS'}->{'pagesize.widthunit'});
1.285 albertel 1224: }
1.286 albertel 1225: return $textwidth;
1.285 albertel 1226: }
1227:
1.296 sakharuk 1228:
1229: sub unsupported {
1.414 albertel 1230: my ($currentURL,$mode,$symb)=@_;
1.307 sakharuk 1231: if ($mode ne '') {$mode='\\'.$mode}
1.308 sakharuk 1232: my $result.= &print_latex_header($mode);
1.414 albertel 1233: if ($currentURL=~m|^(/adm/wrapper/)?ext/|) {
1234: $currentURL=~s|^(/adm/wrapper/)?ext/|http://|;
1235: my $title=&Apache::lonnet::gettitle($symb);
1236: $title = &Apache::lonxml::latex_special_symbols($title);
1237: $result.=' \strut \\\\ '.$title.' \strut \\\\ '.$currentURL.' ';
1.296 sakharuk 1238: } else {
1239: $result.=$currentURL;
1240: }
1.419 albertel 1241: $result.= '\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill} \end{document}';
1.296 sakharuk 1242: return $result;
1243: }
1244:
1245:
1.363 foxr 1246: #
1.395 www 1247: # List of recently generated print files
1248: #
1249: sub recently_generated {
1250: my $r=shift;
1251: my $prtspool=$r->dir_config('lonPrtDir');
1.400 albertel 1252: my $zip_result;
1253: my $pdf_result;
1.395 www 1254: opendir(DIR,$prtspool);
1.400 albertel 1255:
1256: my @files =
1257: grep(/^$env{'user.name'}_$env{'user.domain'}_printout_(\d+)_.*\.(pdf|zip)$/,readdir(DIR));
1.395 www 1258: closedir(DIR);
1.400 albertel 1259:
1260: @files = sort {
1261: my ($actime) = (stat($prtspool.'/'.$a))[10];
1262: my ($bctime) = (stat($prtspool.'/'.$b))[10];
1263: return $bctime <=> $actime;
1264: } (@files);
1265:
1266: foreach my $filename (@files) {
1267: my ($ext) = ($filename =~ m/(pdf|zip)$/);
1268: my ($cdev,$cino,$cmode,$cnlink,
1269: $cuid,$cgid,$crdev,$csize,
1270: $catime,$cmtime,$cctime,
1271: $cblksize,$cblocks)=stat($prtspool.'/'.$filename);
1272: my $result="<a href='/prtspool/$filename'>".
1273: &mt('Generated [_1] ([_2] bytes)',
1274: &Apache::lonlocal::locallocaltime($cctime),$csize).
1275: '</a><br />';
1276: if ($ext eq 'pdf') { $pdf_result .= $result; }
1277: if ($ext eq 'zip') { $zip_result .= $result; }
1278: }
1279: if ($zip_result) {
1280: $r->print('<h4>'.&mt('Recently generated printout zip files')."</h4>\n"
1281: .$zip_result);
1282: }
1283: if ($pdf_result) {
1284: $r->print('<h4>'.&mt('Recently generated printouts')."</h4>\n"
1285: .$pdf_result);
1.396 albertel 1286: }
1.395 www 1287: }
1288:
1289: #
1.363 foxr 1290: # Retrieve the hash of page breaks.
1291: #
1292: # Inputs:
1293: # helper - reference to helper object.
1294: # Outputs
1295: # A reference to a page break hash.
1296: #
1297: #
1.418 foxr 1298: #use Data::Dumper;
1299: #sub dump_helper_vars {
1300: # my ($helper) = @_;
1301: # my $helpervars = Dumper($helper->{'VARS'});
1302: # &Apache::lonnet::logthis("Dump of helper vars:\n $helpervars");
1303: #}
1.363 foxr 1304:
1.481 albertel 1305: sub get_page_breaks {
1306: my ($helper) = @_;
1307: my %page_breaks;
1308:
1309: foreach my $break (split /\|\|\|/, $helper->{'VARS'}->{'FINISHPAGE'}) {
1310: $page_breaks{$break} = 1;
1311: }
1312: return %page_breaks;
1313: }
1.363 foxr 1314:
1.459 foxr 1315: # Output a sequence (recursively if neeed)
1316: # from construction space.
1317: # Parameters:
1318: # url = URL of the sequence to print.
1319: # helper - Reference to the helper hash.
1320: # form - Copy of the format hash.
1321: # LaTeXWidth
1322: # Returns:
1323: # Text to add to the printout.
1324: # NOTE if the first element of the outermost sequence
1325: # is itself a sequence, the outermost caller may need to
1326: # prefix the latex with the page headers stuff.
1327: #
1328: sub print_construction_sequence {
1329: my ($currentURL, $helper, %form, $LaTeXwidth) = @_;
1330: my $result;
1331: my $rndseed=time;
1332: if ($helper->{'VARS'}->{'curseed'}) {
1333: $rndseed=$helper->{'VARS'}->{'curseed'};
1334: }
1.491 albertel 1335: my $errtext=&LONCAPA::map::mapread($currentURL);
1.459 foxr 1336: #
1337: # These make this all support recursing for subsequences.
1338: #
1.491 albertel 1339: my @order = @LONCAPA::map::order;
1340: my @resources = @LONCAPA::map::resources;
1.459 foxr 1341: for (my $member=0;$member<=$#order;$member++) {
1342: $resources[$order[$member]]=~/^([^:]*):([^:]*):/;
1343: my $urlp=$2;
1344: if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/) {
1345: my $texversion='';
1346: if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') {
1347: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1348: $form{'suppress_tries'}=$parmhash{'suppress_tries'};
1349: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1350: $form{'rndseed'}=$rndseed;
1351: $resources_printed .=$urlp.':';
1.515 foxr 1352: $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.459 foxr 1353: }
1354: if((($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1355: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) &&
1356: ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page)$/)) {
1357: # Don't permanently modify %$form...
1358: my %answerform = %form;
1359: $answerform{'grade_target'}='answer';
1360: $answerform{'answer_output_mode'}='tex';
1361: $answerform{'rndseed'}=$rndseed;
1362: $answerform{'problem_split'}=$parmhash{'problem_stream_switch'};
1.481 albertel 1363: if ($urlp=~/\/res\//) {$env{'request.state'}='published';}
1.459 foxr 1364: $resources_printed .= $urlp.':';
1.515 foxr 1365: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.459 foxr 1366: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
1367: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1368: } else {
1369: # If necessary, encapsulate answer in minipage:
1370:
1371: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477 albertel 1372: my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
1373: $title = &Apache::lonxml::latex_special_symbols($title);
1374: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.459 foxr 1375: $body.=&path_to_problem($urlp,$LaTeXwidth);
1376: $body.='\vskip 1 mm '.$answer.'\end{document}';
1377: $body = &encapsulate_minipage($body);
1378: $texversion.=$body;
1379: }
1380: }
1381: $texversion = &latex_header_footer_remove($texversion);
1382:
1383: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1384: $texversion=&IndexCreation($texversion,$urlp);
1385: }
1386: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
1387: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
1388: }
1389: $result.=$texversion;
1390:
1391: } elsif ($urlp=~/\.(sequence|page)$/) {
1392:
1393: # header:
1394:
1395: $result.='\strut\newline\noindent Sequence/page '.$urlp.'\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent ';
1396:
1397: # IF sequence, recurse:
1398:
1399: if ($urlp =~ /\.sequence$/) {
1400: my $sequence_url = $urlp;
1401: my $domain = $env{'user.domain'}; # Constr. space only on local
1402: my $user = $env{'user.name'};
1403:
1404: $sequence_url =~ s/^\/res\/$domain/\/home/;
1405: $sequence_url =~ s/^(\/home\/$user)/$1\/public_html/;
1406: # $sequence_url =~ s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;
1407: $result .= &print_construction_sequence($sequence_url,
1408: $helper, %form,
1409: $LaTeXwidth);
1410: }
1411: }
1412: }
1413: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\begin{document})/$1 \\fbox\{RANDOM SEED IS $rndseed\} /;}
1414: return $result;
1415: }
1416:
1.177 sakharuk 1417: sub output_data {
1.184 sakharuk 1418: my ($r,$helper,$rparmhash) = @_;
1419: my %parmhash = %$rparmhash;
1.515 foxr 1420: $ssi_error = 0; # This will be set nonzero by failing ssi's.
1.459 foxr 1421: $resources_printed = '';
1.499 foxr 1422: my $do_postprocessing = 1;
1.433 albertel 1423: my $js = <<ENDPART;
1424: <script type="text/javascript">
1.264 sakharuk 1425: var editbrowser;
1426: function openbrowser(formname,elementname,only,omit) {
1427: var url = '/res/?';
1428: if (editbrowser == null) {
1429: url += 'launch=1&';
1430: }
1431: url += 'catalogmode=interactive&';
1432: url += 'mode=parmset&';
1433: url += 'form=' + formname + '&';
1434: if (only != null) {
1435: url += 'only=' + only + '&';
1436: }
1437: if (omit != null) {
1438: url += 'omit=' + omit + '&';
1439: }
1440: url += 'element=' + elementname + '';
1441: var title = 'Browser';
1442: var options = 'scrollbars=1,resizable=1,menubar=0';
1443: options += ',width=700,height=600';
1444: editbrowser = open(url,title,options,'1');
1445: editbrowser.focus();
1446: }
1447: </script>
1.140 sakharuk 1448: ENDPART
1449:
1.512 foxr 1450:
1451:
1.433 albertel 1452: my $start_page = &Apache::loncommon::start_page('Preparing Printout',$js);
1453: my $msg = &mt('Please stand by while processing your print request, this may take some time ...');
1.363 foxr 1454:
1.433 albertel 1455: $r->print($start_page."\n<p>\n$msg\n</p>\n");
1.372 foxr 1456:
1.363 foxr 1457: # fetch the pagebreaks and store them in the course environment
1458: # The page breaks will be pulled into the hash %page_breaks which is
1459: # indexed by symb and contains 1's for each break.
1460:
1.373 albertel 1461: $env{'form.pagebreaks'} = $helper->{'VARS'}->{'FINISHPAGE'};
1462: $env{'form.lastprinttype'} = $helper->{'VARS'}->{'PRINT_TYPE'};
1.363 foxr 1463: &Apache::loncommon::store_course_settings('print',
1.366 foxr 1464: {'pagebreaks' => 'scalar',
1465: 'lastprinttype' => 'scalar'});
1.363 foxr 1466:
1.364 albertel 1467: my %page_breaks = &get_page_breaks($helper);
1.363 foxr 1468:
1.140 sakharuk 1469: my $format_from_helper = $helper->{'VARS'}->{'FORMAT'};
1470: my ($result,$selectionmade) = ('','');
1471: my $number_of_columns = 1; #used only for pages to determine the width of the cell
1472: my @temporary_array=split /\|/,$format_from_helper;
1473: my ($laystyle,$numberofcolumns,$papersize)=@temporary_array;
1474: if ($laystyle eq 'L') {
1475: $laystyle='album';
1476: } else {
1477: $laystyle='book';
1478: }
1.177 sakharuk 1479: my ($textwidth,$textheight,$oddoffset,$evenoffset) = &page_format($papersize,$laystyle,$numberofcolumns);
1.373 albertel 1480: my $assignment = $env{'form.assignment'};
1.275 sakharuk 1481: my $LaTeXwidth=&recalcto_mm($textwidth);
1.272 sakharuk 1482: my @print_array=();
1.274 sakharuk 1483: my @student_names=();
1.360 albertel 1484:
1.512 foxr 1485:
1.360 albertel 1486: # Common settings for the %form has:
1487: # In some cases these settings get overriddent by specific cases, but the
1488: # settings are common enough to make it worthwhile factoring them out
1489: # here.
1490: #
1491: my %form;
1492: $form{'grade_target'} = 'tex';
1493: $form{'textwidth'} = &get_textwidth($helper, $LaTeXwidth);
1.372 foxr 1494:
1495: # If form.showallfoils is set, then request all foils be shown:
1496: # privilege will be enforced both by not allowing the
1497: # check box selecting this option to be presnt unless it's ok,
1498: # and by lonresponse's priv. check.
1499: # The if is here because lonresponse.pm only cares that
1500: # showallfoils is defined, not what the value is.
1501:
1502: if ($helper->{'VARS'}->{'showallfoils'} eq "1") {
1503: $form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'};
1504: }
1.504 albertel 1505:
1506: if ($helper->{'VARS'}->{'style_file'}=~/\w/) {
1.520 raeburn 1507: &Apache::lonnet::appenv({'construct.style' =>
1508: $helper->{'VARS'}->{'style_file'}});
1.504 albertel 1509: } elsif ($env{'construct.style'}) {
1510: &Apache::lonnet::delenv('construct\\.style');
1511: }
1512:
1.372 foxr 1513:
1.140 sakharuk 1514: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') {
1.143 sakharuk 1515: #-- single document - problem, page, html, xml, ...
1.343 albertel 1516: my ($currentURL,$cleanURL);
1.375 foxr 1517:
1.162 sakharuk 1518: if ($helper->{'VARS'}->{'construction'} ne '1') {
1.185 sakharuk 1519: #prints published resource
1.153 sakharuk 1520: $currentURL=$helper->{'VARS'}->{'postdata'};
1.343 albertel 1521: $cleanURL=&Apache::lonenc::check_decrypt($currentURL);
1.143 sakharuk 1522: } else {
1.512 foxr 1523:
1.185 sakharuk 1524: #prints resource from the construction space
1.240 albertel 1525: $currentURL='/'.$helper->{'VARS'}->{'filename'};
1.206 sakharuk 1526: if ($currentURL=~/([^?]+)/) {$currentURL=$1;}
1.343 albertel 1527: $cleanURL=$currentURL;
1.143 sakharuk 1528: }
1.140 sakharuk 1529: $selectionmade = 1;
1.413 albertel 1530: if ($cleanURL!~m|^/adm/|
1531: && $cleanURL=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.169 albertel 1532: my $rndseed=time;
1.242 sakharuk 1533: my $texversion='';
1534: if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') {
1535: my %moreenv;
1.343 albertel 1536: $moreenv{'request.filename'}=$cleanURL;
1.290 sakharuk 1537: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {$form{'problemtype'}='exam';}
1.242 sakharuk 1538: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310 sakharuk 1539: $form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.242 sakharuk 1540: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309 sakharuk 1541: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 1542: $form{'print_annotations'}=$helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1543: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
1544: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
1545: $form{'problem_split'}='yes';
1546: }
1.242 sakharuk 1547: if ($helper->{'VARS'}->{'curseed'}) {
1548: $rndseed=$helper->{'VARS'}->{'curseed'};
1549: }
1550: $form{'rndseed'}=$rndseed;
1.520 raeburn 1551: &Apache::lonnet::appenv(\%moreenv);
1.428 albertel 1552:
1553: &Apache::lonxml::clear_problem_counter();
1554:
1.375 foxr 1555: $resources_printed .= $currentURL.':';
1.515 foxr 1556: $texversion.=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.428 albertel 1557:
1.511 foxr 1558: # Add annotations if required:
1559:
1.428 albertel 1560: &Apache::lonxml::clear_problem_counter();
1561:
1.242 sakharuk 1562: &Apache::lonnet::delenv('request.filename');
1.230 albertel 1563: }
1.423 foxr 1564: # current document with answers.. no need to encap in minipage
1565: # since there's only one answer.
1566:
1.242 sakharuk 1567: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1568: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.353 foxr 1569: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.166 albertel 1570: $form{'grade_target'}='answer';
1.167 albertel 1571: $form{'answer_output_mode'}='tex';
1.169 albertel 1572: $form{'rndseed'}=$rndseed;
1.401 albertel 1573: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {
1574: $form{'problemtype'}='exam';
1575: }
1.375 foxr 1576: $resources_printed .= $currentURL.':';
1.515 foxr 1577: my $answer=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.511 foxr 1578:
1579:
1.242 sakharuk 1580: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
1581: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1582: } else {
1583: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.245 sakharuk 1584: if ($helper->{'VARS'}->{'construction'} ne '1') {
1.477 albertel 1585: my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
1586: $title = &Apache::lonxml::latex_special_symbols($title);
1587: $texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.343 albertel 1588: $texversion.=&path_to_problem($cleanURL,$LaTeXwidth);
1.245 sakharuk 1589: } else {
1590: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
1.343 albertel 1591: my $URLpath=$cleanURL;
1.245 sakharuk 1592: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
1.504 albertel 1593: $texversion.=&path_to_problem($URLpath,$LaTeXwidth);
1.245 sakharuk 1594: }
1.242 sakharuk 1595: $texversion.='\vskip 1 mm '.$answer.'\end{document}';
1596: }
1.511 foxr 1597:
1598:
1599:
1600:
1601: }
1602: # Print annotations.
1603:
1604:
1605: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1606: my $annotation .= &annotate($currentURL);
1607: $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
1.163 sakharuk 1608: }
1.511 foxr 1609:
1610:
1.214 sakharuk 1611: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1.215 sakharuk 1612: $texversion=&IndexCreation($texversion,$currentURL);
1.214 sakharuk 1613: }
1.219 sakharuk 1614: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
1615: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$currentURL| \\strut\\\\\\strut /;
1616:
1617: }
1.162 sakharuk 1618: $result .= $texversion;
1619: if ($currentURL=~m/\.page\s*$/) {
1620: ($result,$number_of_columns) = &page_cleanup($result);
1621: }
1.413 albertel 1622: } elsif ($cleanURL!~m|^/adm/|
1623: && $currentURL=~/\.sequence$/ && $helper->{'VARS'}->{'construction'} eq '1') {
1.227 sakharuk 1624: #printing content of sequence from the construction space
1625: $currentURL=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;
1.459 foxr 1626: $result .= &print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1627: $result .= &print_construction_sequence($currentURL, $helper, %form,
1628: $LaTeXwidth);
1629: $result .= '\end{document}';
1630: if (!($result =~ /\\begin\{document\}/)) {
1631: $result = &print_latex_header() . $result;
1.227 sakharuk 1632: }
1.459 foxr 1633: # End construction space sequence.
1.456 raeburn 1634: } elsif ($cleanURL=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.258 sakharuk 1635: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.298 sakharuk 1636: if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;}
1.375 foxr 1637: $resources_printed .= $currentURL.':';
1.515 foxr 1638: my $texversion=&ssi_with_retries($currentURL, $ssi_retry_count, %form);
1.511 foxr 1639: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1640: my $annotation = &annotate($currentURL);
1641: $texversion =~ s/(\\end{document})/$annotation$1/;
1642: }
1.258 sakharuk 1643: $result .= $texversion;
1.498 foxr 1644: } elsif ($cleanURL =~/.tex$/) {
1645: # For this sort of print of a single LaTeX file,
1646: # We can just print the LaTeX file as it is uninterpreted in any way:
1647: #
1648:
1649: $result = &fetch_raw_resource($currentURL);
1.511 foxr 1650: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1651: my $annotation = &annotate($currentURL);
1652: $result =~ s/(\\end{document})/$annotation$1/;
1653: }
1654:
1.499 foxr 1655: $do_postprocessing = 0; # Don't massage the result.
1.498 foxr 1656:
1.162 sakharuk 1657: } else {
1.414 albertel 1658: $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'},
1659: $helper->{'VARS'}->{'symb'});
1.162 sakharuk 1660: }
1.354 foxr 1661: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') or
1.142 sakharuk 1662: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or
1.354 foxr 1663: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') or
1664: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') or # BUGBUG
1.252 sakharuk 1665: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences')) {
1.511 foxr 1666:
1667:
1.141 sakharuk 1668: #-- produce an output string
1.296 sakharuk 1669: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') {
1670: $selectionmade = 2;
1671: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') {
1672: $selectionmade = 3;
1673: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') {
1674: $selectionmade = 4;
1.354 foxr 1675: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') { #BUGBUG
1676: $selectionmade = 4;
1.296 sakharuk 1677: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') {
1678: $selectionmade = 7;
1679: }
1.193 sakharuk 1680: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310 sakharuk 1681: $form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.203 sakharuk 1682: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309 sakharuk 1683: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 1684: $form{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1685: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
1686: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') ) {
1687: $form{'problem_split'}='yes';
1688: }
1.141 sakharuk 1689: my $flag_latex_header_remove = 'NO';
1690: my $flag_page_in_sequence = 'NO';
1691: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.193 sakharuk 1692: my $prevassignment='';
1.428 albertel 1693:
1694: &Apache::lonxml::clear_problem_counter();
1695:
1.416 foxr 1696: my $pbreakresources = keys %page_breaks;
1.141 sakharuk 1697: for (my $i=0;$i<=$#master_seq;$i++) {
1.350 foxr 1698:
1.521 foxr 1699: &Apache::lonenc::reset_enc();
1700:
1701:
1.350 foxr 1702: # Note due to document structure, not allowed to put \newpage
1703: # prior to the first resource
1704:
1.351 foxr 1705: if (defined $page_breaks{$master_seq[$i]}) {
1.350 foxr 1706: if($i != 0) {
1707: $result.="\\newpage\n";
1708: }
1709: }
1.521 foxr 1710: my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]);
1.237 albertel 1711: $urlp=&Apache::lonnet::clutter($urlp);
1.166 albertel 1712: $form{'symb'}=$master_seq[$i];
1.407 albertel 1713:
1.521 foxr 1714:
1.407 albertel 1715: my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem
1.521 foxr 1716:
1.267 sakharuk 1717: if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;}
1.247 sakharuk 1718: if ($i==0) {$prevassignment=$assignment;}
1.297 sakharuk 1719: my $texversion='';
1.413 albertel 1720: if ($urlp!~m|^/adm/|
1721: && $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 1722: $resources_printed .= $urlp.':';
1.428 albertel 1723: &Apache::lonxml::remember_problem_counter();
1.515 foxr 1724: $texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.296 sakharuk 1725: if ($urlp=~/\.page$/) {
1726: ($texversion,my $number_of_columns_page) = &page_cleanup($texversion);
1727: if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;}
1728: $texversion =~ s/\\end{document}\d*/\\end{document}/;
1729: $flag_page_in_sequence = 'YES';
1730: }
1.428 albertel 1731:
1.296 sakharuk 1732: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1733: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 1734: # Don't permanently pervert the %form hash
1735: my %answerform = %form;
1736: $answerform{'grade_target'}='answer';
1737: $answerform{'answer_output_mode'}='tex';
1.375 foxr 1738: $resources_printed .= $urlp.':';
1.428 albertel 1739:
1740: &Apache::lonxml::restore_problem_counter();
1.515 foxr 1741: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.428 albertel 1742:
1.296 sakharuk 1743: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
1744: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1.249 sakharuk 1745: } else {
1.307 sakharuk 1746: if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) {
1.296 sakharuk 1747: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477 albertel 1748: my $title = &Apache::lonnet::gettitle($master_seq[$i]);
1749: $title = &Apache::lonxml::latex_special_symbols($title);
1750: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.423 foxr 1751: $body .= &path_to_problem ($urlp,$LaTeXwidth);
1752: $body .='\vskip 1 mm '.$answer;
1753: $body = &encapsulate_minipage($body);
1754: $texversion .= $body;
1.296 sakharuk 1755: } else {
1756: $texversion='';
1757: }
1.249 sakharuk 1758: }
1.511 foxr 1759:
1.246 sakharuk 1760: }
1.511 foxr 1761: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1762: my $annotation .= &annotate($urlp);
1763: $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
1764: }
1765:
1.296 sakharuk 1766: if ($flag_latex_header_remove ne 'NO') {
1767: $texversion = &latex_header_footer_remove($texversion);
1768: } else {
1769: $texversion =~ s/\\end{document}//;
1770: }
1771: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1772: $texversion=&IndexCreation($texversion,$urlp);
1773: }
1774: if (($selectionmade == 4) and ($assignment ne $prevassignment)) {
1775: my $name = &get_name();
1776: my $courseidinfo = &get_course();
1777: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo }
1778: $prevassignment=$assignment;
1.455 albertel 1779: my $header_text = $parmhash{'print_header_format'};
1.486 foxr 1780: $header_text = &format_page_header($textwidth, $header_text,
1.455 albertel 1781: $assignment,
1782: $courseidinfo,
1783: $name);
1.417 foxr 1784: if ($numberofcolumns eq '1') {
1.455 albertel 1785: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{'.$header_text.'}} \vskip 5 mm ';
1.416 foxr 1786: } else {
1.455 albertel 1787: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\fancyhead[LO]{'.$header_text.'}} \vskip 5 mm ';
1.416 foxr 1788: }
1.296 sakharuk 1789: }
1790: $result .= $texversion;
1791: $flag_latex_header_remove = 'YES';
1.456 raeburn 1792: } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.301 sakharuk 1793: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1794: if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;}
1.375 foxr 1795: $resources_printed .= $urlp.':';
1.515 foxr 1796: my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.511 foxr 1797: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1798: my $annotation = &annotate($urlp);
1799: $texversion =~ s/(\\end{document)/$annotation$1/;
1800: }
1801:
1.301 sakharuk 1802: if ($flag_latex_header_remove ne 'NO') {
1803: $texversion = &latex_header_footer_remove($texversion);
1804: } else {
1805: $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/;
1806: }
1807: $result .= $texversion;
1808: $flag_latex_header_remove = 'YES';
1.141 sakharuk 1809: } else {
1.414 albertel 1810: $texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'},
1811: $master_seq[$i]);
1.297 sakharuk 1812: if ($flag_latex_header_remove ne 'NO') {
1813: $texversion = &latex_header_footer_remove($texversion);
1814: } else {
1815: $texversion =~ s/\\end{document}//;
1816: }
1817: $result .= $texversion;
1818: $flag_latex_header_remove = 'YES';
1.296 sakharuk 1819: }
1.331 albertel 1820: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.141 sakharuk 1821: }
1.428 albertel 1822: &Apache::lonxml::clear_problem_counter();
1.344 foxr 1823: if ($flag_page_in_sequence eq 'YES') {
1824: $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;
1825: }
1.141 sakharuk 1826: $result .= '\end{document}';
1.284 albertel 1827: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1828: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){
1.353 foxr 1829:
1830:
1.150 sakharuk 1831: #-- prints assignments for whole class or for selected students
1.284 albertel 1832: my $type;
1.254 sakharuk 1833: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') {
1834: $selectionmade=5;
1.284 albertel 1835: $type='problems';
1.254 sakharuk 1836: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') {
1837: $selectionmade=8;
1.284 albertel 1838: $type='resources';
1.254 sakharuk 1839: }
1.150 sakharuk 1840: my @students=split /\|\|\|/, $helper->{'VARS'}->{'STUDENTS'};
1.341 foxr 1841: # The normal sort order is by section then by students within the
1842: # section. If the helper var student_sort is 1, then the user has elected
1843: # to override this and output the students by name.
1844: # Each element of the students array is of the form:
1845: # username:domain:section:last, first:status
1846: #
1.429 foxr 1847: # Note that student sort is not compatible with printing
1848: # 1 section per pdf...so that setting overrides.
1.341 foxr 1849: #
1.429 foxr 1850: if (($helper->{'VARS'}->{'student_sort'} eq 1) &&
1851: ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) {
1.341 foxr 1852: @students = sort compare_names @students;
1853: }
1.429 foxr 1854: &adjust_number_to_print($helper);
1855:
1.278 albertel 1856: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq '0' ||
1857: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'all' ) {
1858: $helper->{'VARS'}->{'NUMBER_TO_PRINT'}=$#students+1;
1859: }
1.429 foxr 1860: # If we are splitting on section boundaries, we need
1861: # to remember that in split_on_sections and
1862: # print all of the students in the list.
1863: #
1864: my $split_on_sections = 0;
1865: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'section') {
1866: $split_on_sections = 1;
1867: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1;
1868: }
1.150 sakharuk 1869: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.350 foxr 1870:
1.150 sakharuk 1871: #loop over students
1872: my $flag_latex_header_remove = 'NO';
1873: my %moreenv;
1.330 sakharuk 1874: $moreenv{'instructor_comments'}='hide';
1.285 albertel 1875: $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth);
1.309 sakharuk 1876: $moreenv{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 1877: $moreenv{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1.353 foxr 1878: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'};
1.369 foxr 1879: $moreenv{'suppress_tries'} = $parmhash{'suppress_tries'};
1.511 foxr 1880: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
1881: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
1882: $moreenv{'problem_split'}='yes';
1883: }
1.318 albertel 1884: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75');
1.272 sakharuk 1885: my $student_counter=-1;
1.429 foxr 1886: my $i = 0;
1.430 albertel 1887: my $last_section = (split(/:/,$students[0]))[2];
1.150 sakharuk 1888: foreach my $person (@students) {
1.350 foxr 1889:
1.373 albertel 1890: my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";
1.311 sakharuk 1891: if (-e $duefile) {
1892: my $temp_file = Apache::File->new('>>'.$duefile);
1893: print $temp_file "1969\n";
1894: }
1.272 sakharuk 1895: $student_counter++;
1.429 foxr 1896: if ($split_on_sections) {
1.430 albertel 1897: my $this_section = (split(/:/,$person))[2];
1.429 foxr 1898: if ($this_section ne $last_section) {
1899: $i++;
1900: $last_section = $this_section;
1901: }
1902: } else {
1903: $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'});
1904: }
1.375 foxr 1905: my ($output,$fullname, $printed)=&print_resources($r,$helper,
1.353 foxr 1906: $person,$type,
1907: \%moreenv,\@master_seq,
1.360 albertel 1908: $flag_latex_header_remove,
1.422 albertel 1909: $LaTeXwidth);
1.375 foxr 1910: $resources_printed .= ":";
1.284 albertel 1911: $print_array[$i].=$output;
1912: $student_names[$i].=$person.':'.$fullname.'_END_';
1913: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname);
1914: $flag_latex_header_remove = 'YES';
1.331 albertel 1915: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 1916: }
1917: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
1918: $result .= $print_array[0].' \end{document}';
1919: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon') ||
1920: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon') ) {
1.373 albertel 1921: my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
1922: my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
1.288 albertel 1923: my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'};
1924: my $code_name=$helper->{'VARS'}->{'ANON_CODE_STORAGE_NAME'};
1.292 albertel 1925: my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'};
1.385 foxr 1926: my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'};
1.388 foxr 1927: my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'};
1928:
1.381 albertel 1929: my $code_option=$helper->{'VARS'}->{'CODE_OPTION'};
1930: open(FH,$Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
1931: my ($code_type,$code_length)=('letter',6);
1932: foreach my $line (<FH>) {
1933: my ($name,$type,$length) = (split(/:/,$line))[0,2,4];
1934: if ($name eq $code_option) {
1935: $code_length=$length;
1936: if ($type eq 'number') { $code_type = 'number'; }
1937: }
1938: }
1.288 albertel 1939: my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth));
1.353 foxr 1940: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'};
1.420 albertel 1941: $moreenv{'instructor_comments'}='hide';
1.288 albertel 1942: my $seed=time+($$<<16)+($$);
1.292 albertel 1943: my @allcodes;
1944: if ($old_name) {
1.381 albertel 1945: my %result=&Apache::lonnet::get('CODEs',
1946: [$old_name,"type\0$old_name"],
1947: $cdom,$cnum);
1948: $code_type=$result{"type\0$old_name"};
1.292 albertel 1949: @allcodes=split(',',$result{$old_name});
1.336 albertel 1950: $num_todo=scalar(@allcodes);
1.389 foxr 1951: } elsif ($selected_code) { # Selection value is always numeric.
1.388 foxr 1952: $num_todo = 1;
1953: @allcodes = ($selected_code);
1.385 foxr 1954: } elsif ($single_code) {
1955:
1.387 foxr 1956: $num_todo = 1; # Unconditionally one code to do.
1.385 foxr 1957: # If an alpha code have to convert to numbers so it can be
1958: # converted back to letters again :-)
1959: #
1960: if ($code_type ne 'number') {
1961: $single_code = &letters_to_num($single_code);
1962: }
1963: @allcodes = ($single_code);
1.292 albertel 1964: } else {
1965: my %allcodes;
1.299 albertel 1966: srand($seed);
1.292 albertel 1967: for (my $i=0;$i<$num_todo;$i++) {
1.381 albertel 1968: $moreenv{'CODE'}=&get_CODE(\%allcodes,$i,$seed,$code_length,
1969: $code_type);
1.292 albertel 1970: }
1971: if ($code_name) {
1972: &Apache::lonnet::put('CODEs',
1.381 albertel 1973: {
1974: $code_name =>join(',',keys(%allcodes)),
1975: "type\0$code_name" => $code_type
1976: },
1.292 albertel 1977: $cdom,$cnum);
1978: }
1979: @allcodes=keys(%allcodes);
1980: }
1.336 albertel 1981: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1982: my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'});
1.452 albertel 1983: &adjust_number_to_print($helper);
1.336 albertel 1984: my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'};
1985: if ($number_per_page eq '0' || $number_per_page eq 'all') {
1986: $number_per_page=$num_todo;
1987: }
1988: my $flag_latex_header_remove = 'NO';
1989: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75');
1.295 albertel 1990: my $count=0;
1.292 albertel 1991: foreach my $code (sort(@allcodes)) {
1.295 albertel 1992: my $file_num=int($count/$number_per_page);
1.381 albertel 1993: if ($code_type eq 'number') {
1994: $moreenv{'CODE'}=$code;
1995: } else {
1996: $moreenv{'CODE'}=&num_to_letters($code);
1997: }
1.375 foxr 1998: my ($output,$fullname, $printed)=
1.288 albertel 1999: &print_resources($r,$helper,'anonymous',$type,\%moreenv,
1.360 albertel 2000: \@master_seq,$flag_latex_header_remove,
2001: $LaTeXwidth);
1.375 foxr 2002: $resources_printed .= ":";
1.295 albertel 2003: $print_array[$file_num].=$output;
1.288 albertel 2004: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
2005: &mt('last assignment').' '.$fullname);
2006: $flag_latex_header_remove = 'YES';
1.295 albertel 2007: $count++;
1.331 albertel 2008: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.288 albertel 2009: }
2010: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
2011: $result .= $print_array[0].' \end{document}';
2012: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') {
1.151 sakharuk 2013: #prints selected problems from the subdirectory
2014: $selectionmade = 6;
2015: my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};
1.154 sakharuk 2016: @list_of_files=sort @list_of_files;
1.175 sakharuk 2017: my $flag_latex_header_remove = 'NO';
2018: my $rndseed=time;
1.230 albertel 2019: if ($helper->{'VARS'}->{'curseed'}) {
2020: $rndseed=$helper->{'VARS'}->{'curseed'};
2021: }
1.151 sakharuk 2022: for (my $i=0;$i<=$#list_of_files;$i++) {
1.521 foxr 2023:
2024: &Apache::lonenc::reset_enc();
2025:
1.152 sakharuk 2026: my $urlp = $list_of_files[$i];
1.253 sakharuk 2027: $urlp=~s|//|/|;
1.152 sakharuk 2028: if ($urlp=~/\//) {
1.353 foxr 2029: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.175 sakharuk 2030: $form{'rndseed'}=$rndseed;
1.152 sakharuk 2031: if ($urlp =~ m|/home/([^/]+)/public_html|) {
2032: $urlp =~ s|/home/([^/]*)/public_html|/~$1|;
2033: } else {
1.302 sakharuk 2034: $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;
1.152 sakharuk 2035: }
1.375 foxr 2036: $resources_printed .= $urlp.':';
1.515 foxr 2037: my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.251 sakharuk 2038: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1.253 sakharuk 2039: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2040: # Don't permanently pervert %form:
2041: my %answerform = %form;
2042: $answerform{'grade_target'}='answer';
2043: $answerform{'answer_output_mode'}='tex';
2044: $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
2045: $answerform{'rndseed'}=$rndseed;
1.375 foxr 2046: $resources_printed .= $urlp.':';
1.515 foxr 2047: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.251 sakharuk 2048: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2049: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
2050: } else {
1.253 sakharuk 2051: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
2052: if ($helper->{'VARS'}->{'construction'} ne '1') {
2053: $texversion.='\vskip 0 mm \noindent ';
2054: $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
2055: } else {
2056: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
2057: my $URLpath=$urlp;
2058: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
2059: $texversion.=&path_to_problem ($URLpath,$LaTeXwidth);
2060: }
2061: $texversion.='\vskip 1 mm '.$answer.'\end{document}';
1.251 sakharuk 2062: }
1.174 sakharuk 2063: }
1.515 foxr 2064: #this chunk is responsible for printing the path to problem
2065:
1.253 sakharuk 2066: my $newurlp=$urlp;
2067: if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;}
2068: $newurlp=&path_to_problem($newurlp,$LaTeXwidth);
1.242 sakharuk 2069: $texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;
1.152 sakharuk 2070: if ($flag_latex_header_remove ne 'NO') {
2071: $texversion = &latex_header_footer_remove($texversion);
2072: } else {
2073: $texversion =~ s/\\end{document}//;
1.216 sakharuk 2074: }
2075: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
2076: $texversion=&IndexCreation($texversion,$urlp);
1.152 sakharuk 2077: }
1.219 sakharuk 2078: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
2079: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
2080:
2081: }
1.152 sakharuk 2082: $result .= $texversion;
2083: }
2084: $flag_latex_header_remove = 'YES';
1.151 sakharuk 2085: }
1.175 sakharuk 2086: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;}
1.152 sakharuk 2087: $result .= '\end{document}';
1.140 sakharuk 2088: }
2089: #-------------------------------------------------------- corrections for the different page formats
1.499 foxr 2090:
2091: # Only post process if that has not been turned off e.g. by a raw latex resource.
2092:
2093: if ($do_postprocessing) {
2094: $result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade);
2095: $result = &latex_corrections($number_of_columns,$result,$selectionmade,
2096: $helper->{'VARS'}->{'ANSWER_TYPE'});
2097: #if ($numberofcolumns == 1) {
1.451 albertel 2098: $result =~ s/\\textwidth\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /;
2099: $result =~ s/\\textheight\s*=?\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /;
2100: $result =~ s/\\evensidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
2101: $result =~ s/\\oddsidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
1.499 foxr 2102: #}
2103: }
1.367 foxr 2104:
1.515 foxr 2105: # Set URLback if this is a construction space print so we can provide
2106: # a link to the resource being edited.
2107: #
1.274 sakharuk 2108:
1.276 sakharuk 2109: my $URLback=''; #link to original document
1.510 albertel 2110: if ($helper->{'VARS'}->{'construction'} eq '1') {
1.276 sakharuk 2111: #prints resource from the construction space
2112: $URLback='/'.$helper->{'VARS'}->{'filename'};
1.279 albertel 2113: if ($URLback=~/([^?]+)/) {
2114: $URLback=$1;
2115: $URLback=~s|^/~|/priv/|;
2116: }
1.276 sakharuk 2117: }
1.375 foxr 2118:
1.525 www 2119: #-- writing .tex file in prtspool
2120: my $temp_file;
2121: my $identifier = &Apache::loncommon::get_cgi_id();
2122: my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex";
2123: if (!($#print_array>0)) {
2124: unless ($temp_file = Apache::File->new('>'.$filename)) {
2125: $r->log_error("Couldn't open $filename for output $!");
2126: return SERVER_ERROR;
2127: }
2128: print $temp_file $result;
2129: my $begin=index($result,'\begin{document}',0);
2130: my $inc=substr($result,0,$begin+16);
1.515 foxr 2131: } else {
1.525 www 2132: my $begin=index($result,'\begin{document}',0);
2133: my $inc=substr($result,0,$begin+16);
2134: for (my $i=0;$i<=$#print_array;$i++) {
2135: if ($i==0) {
2136: $print_array[$i]=$result;
2137: } else {
2138: $print_array[$i].='\end{document}';
2139: $print_array[$i] =
2140: &latex_corrections($number_of_columns,$print_array[$i],
2141: $selectionmade,
2142: $helper->{'VARS'}->{'ANSWER_TYPE'});
1.515 foxr 2143:
1.525 www 2144: my $anobegin=index($print_array[$i],'\setcounter{page}',0);
2145: substr($print_array[$i],0,$anobegin)='';
2146: $print_array[$i]=$inc.$print_array[$i];
2147: }
2148: my $temp_file;
2149: my $newfilename=$filename;
2150: my $num=$i+1;
2151: $newfilename =~s/\.tex$//;
2152: $newfilename=sprintf("%s_%03d.tex",$newfilename, $num);
2153: unless ($temp_file = Apache::File->new('>'.$newfilename)) {
2154: $r->log_error("Couldn't open $newfilename for output $!");
2155: return SERVER_ERROR;
2156: }
2157: print $temp_file $print_array[$i];
2158: }
2159: }
2160: my $student_names='';
2161: if ($#print_array>0) {
2162: for (my $i=0;$i<=$#print_array;$i++) {
2163: $student_names.=$student_names[$i].'_ENDPERSON_';
1.515 foxr 2164: }
1.525 www 2165: } else {
2166: if ($#student_names>-1) {
2167: $student_names=$student_names[0].'_ENDPERSON_';
1.515 foxr 2168: } else {
1.525 www 2169: my $fullname = &get_name($env{'user.name'},$env{'user.domain'});
2170: $student_names=join(':',$env{'user.name'},$env{'user.domain'},
1.515 foxr 2171: $env{'request.course.sec'},$fullname).
2172: '_ENDPERSON_'.'_END_';
2173: }
1.525 www 2174: }
1.515 foxr 2175:
1.525 www 2176: # logic for now is too complex to trace if this has been defined
2177: # yet.
2178: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
2179: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2180: &Apache::lonnet::appenv({'cgi.'.$identifier.'.file' => $filename,
1.515 foxr 2181: 'cgi.'.$identifier.'.layout' => $laystyle,
2182: 'cgi.'.$identifier.'.numcol' => $numberofcolumns,
2183: 'cgi.'.$identifier.'.paper' => $papersize,
2184: 'cgi.'.$identifier.'.selection' => $selectionmade,
2185: 'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
2186: 'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
2187: 'cgi.'.$identifier.'.role' => $perm{'pav'},
2188: 'cgi.'.$identifier.'.numberoffiles' => $#print_array,
2189: 'cgi.'.$identifier.'.studentnames' => $student_names,
1.520 raeburn 2190: 'cgi.'.$identifier.'.backref' => $URLback,});
1.525 www 2191: &Apache::lonnet::appenv({"cgi.$identifier.user" => $env{'user.name'},
1.515 foxr 2192: "cgi.$identifier.domain" => $env{'user.domain'},
2193: "cgi.$identifier.courseid" => $cnum,
2194: "cgi.$identifier.coursedom" => $cdom,
1.520 raeburn 2195: "cgi.$identifier.resources" => $resources_printed});
1.515 foxr 2196:
1.525 www 2197: my $end_page = &Apache::loncommon::end_page();
1.529 raeburn 2198: my $continue_text = &mt('Continue');
1.525 www 2199: # If there's been an unrecoverable SSI error, report it to the user
2200: if ($ssi_error) {
2201: my $helpurl = &Apache::loncommon::top_nav_help('Helpdesk');
2202: $r->print('<br /><h2>'.&mt('An unrecoverable network error occurred:').'</h2><p> '.
1.526 www 2203: &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:').
2204: '<br />'.$ssi_last_error_resource.'<br />'.$ssi_last_error.
2205: '</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 2206: &mt('You may be able to reprint the individual resources for which this error occurred, as the issue may be temporary.').
1.525 www 2207: '<br />'.&mt('If the error persists, please contact the [_1] for assistance.',$helpurl).'</p><p>'.
2208: &mt('We apologize for the inconvenience.').'</p>'.
1.528 raeburn 2209: '<a href="/cgi-bin/printout.pl?'.$identifier.'">'.$continue_text.'</a>'.$end_page);
1.525 www 2210: } else {
1.515 foxr 2211: $r->print(<<FINALEND);
1.317 albertel 2212: <br />
1.288 albertel 2213: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.528 raeburn 2214: <a href="/cgi-bin/printout.pl?$identifier">$continue_text</a>
1.431 albertel 2215: $end_page
1.140 sakharuk 2216: FINALEND
1.528 raeburn 2217: } # endif ssi errors.
1.140 sakharuk 2218: }
2219:
1.288 albertel 2220:
2221: sub get_CODE {
1.381 albertel 2222: my ($all_codes,$num,$seed,$size,$type)=@_;
1.288 albertel 2223: my $max='1'.'0'x$size;
2224: my $newcode;
2225: while(1) {
1.392 albertel 2226: $newcode=sprintf("%0".$size."d",int(rand($max)));
1.288 albertel 2227: if (!exists($$all_codes{$newcode})) {
2228: $$all_codes{$newcode}=1;
1.381 albertel 2229: if ($type eq 'number' ) {
2230: return $newcode;
2231: } else {
2232: return &num_to_letters($newcode);
2233: }
1.288 albertel 2234: }
2235: }
2236: }
1.140 sakharuk 2237:
1.284 albertel 2238: sub print_resources {
1.360 albertel 2239: my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422 albertel 2240: $LaTeXwidth)=@_;
1.284 albertel 2241: my $current_output = '';
1.375 foxr 2242: my $printed = '';
1.284 albertel 2243: my ($username,$userdomain,$usersection) = split /:/,$person;
2244: my $fullname = &get_name($username,$userdomain);
1.492 foxr 2245: my $namepostfix = "\\\\"; # Both anon and not anon should get the same vspace.
1.288 albertel 2246: if ($person =~ 'anon') {
1.492 foxr 2247: $namepostfix .="Name: ";
1.288 albertel 2248: $fullname = "CODE - ".$moreenv->{'CODE'};
2249: }
1.444 foxr 2250: # Fullname may have special latex characters that need \ prefixing:
2251: #
2252:
1.350 foxr 2253: my $i = 0;
1.284 albertel 2254: #goes through all resources, checks if they are available for
2255: #current student, and produces output
1.428 albertel 2256:
2257: &Apache::lonxml::clear_problem_counter();
1.364 albertel 2258: my %page_breaks = &get_page_breaks($helper);
1.476 albertel 2259: my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440 foxr 2260: #
1.441 foxr 2261: # end each student with a
1.440 foxr 2262: # Special that allows the post processor to even out the page
2263: # counts later. Nasty problem this... it would be really
2264: # nice to put the special in as a postscript comment
1.441 foxr 2265: # e.g. \special{ps:\ENDOFSTUDENTSTAMP} unfortunately,
1.440 foxr 2266: # The special gets passed the \ and dvips puts it in the output file
1.441 foxr 2267: # so we will just rely on prntout.pl to strip ENDOFSTUDENTSTAMP from the
2268: # postscript. Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440 foxr 2269: #
1.363 foxr 2270:
1.511 foxr 2271:
1.284 albertel 2272: foreach my $curresline (@{$master_seq}) {
1.351 foxr 2273: if (defined $page_breaks{$curresline}) {
1.350 foxr 2274: if($i != 0) {
2275: $current_output.= "\\newpage\n";
2276: }
2277: }
2278: $i++;
1.511 foxr 2279:
1.284 albertel 2280: if ( !($type eq 'problems' &&
2281: ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
2282: my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
2283: if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414 albertel 2284: if ($res_url!~m|^ext/|
1.413 albertel 2285: && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 2286: $printed .= $curresline.':';
1.428 albertel 2287:
2288: &Apache::lonxml::remember_problem_counter();
2289:
1.526 www 2290: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428 albertel 2291:
1.305 sakharuk 2292: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
2293: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2294: # Use a copy of the hash so we don't pervert it on future loop passes.
2295: my %answerenv = %{$moreenv};
2296: $answerenv{'answer_output_mode'}='tex';
2297: $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428 albertel 2298:
2299: &Apache::lonxml::restore_problem_counter();
2300:
1.380 foxr 2301: my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428 albertel 2302:
1.305 sakharuk 2303: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2304: $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
2305: } else {
1.423 foxr 2306:
2307:
2308: my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.477 albertel 2309: my $title = &Apache::lonnet::gettitle($curresline);
2310: $title = &Apache::lonxml::latex_special_symbols($title);
2311: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
2312: $body .=&path_to_problem($res_url,$LaTeXwidth);
1.423 foxr 2313: $body .='\vskip 1 mm '.$ansrendered;
2314: $body = &encapsulate_minipage($body);
2315: $rendered = $header.$body;
1.305 sakharuk 2316: }
2317: }
1.511 foxr 2318:
2319: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2320: my $url = &Apache::lonnet::clutter($res_url);
2321: my $annotation = &annotate($url);
2322: $rendered =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
2323: }
1.305 sakharuk 2324: if ($remove_latex_header eq 'YES') {
2325: $rendered = &latex_header_footer_remove($rendered);
2326: } else {
2327: $rendered =~ s/\\end{document}//;
2328: }
2329: $current_output .= $rendered;
1.456 raeburn 2330: } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.375 foxr 2331: $printed .= $curresline.':';
1.528 raeburn 2332: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.511 foxr 2333: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2334: my $url = &Apache::lonnet::clutter($res_url);
2335: my $annotation = &annotate($url);
2336: $annotation =~ s/(\\end{document})/$annotation$1/;
2337: }
1.305 sakharuk 2338: if ($remove_latex_header eq 'YES') {
2339: $rendered = &latex_header_footer_remove($rendered);
1.284 albertel 2340: } else {
1.305 sakharuk 2341: $rendered =~ s/\\end{document}//;
1.284 albertel 2342: }
1.421 foxr 2343: $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
2344:
1.284 albertel 2345: } else {
1.414 albertel 2346: my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305 sakharuk 2347: if ($remove_latex_header ne 'NO') {
2348: $rendered = &latex_header_footer_remove($rendered);
2349: } else {
2350: $rendered =~ s/\\end{document}//;
2351: }
2352: $current_output .= $rendered;
1.284 albertel 2353: }
2354: }
2355: $remove_latex_header = 'YES';
2356: }
1.331 albertel 2357: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 2358: }
2359: my $courseidinfo = &get_course();
2360: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo }
2361: if ($usersection ne '') {$courseidinfo.=' - Sec. '.$usersection}
2362: my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476 albertel 2363: my $header_line =
1.486 foxr 2364: &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.476 albertel 2365: $currentassignment, $courseidinfo, $fullname);
2366: my $header_start = ($columns_in_format == 1) ? '\lhead'
2367: : '\fancyhead[LO]';
2368: $header_line = $header_start.'{'.$header_line.'}';
2369:
1.284 albertel 2370: if ($current_output=~/\\documentclass/) {
1.476 albertel 2371: $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.284 albertel 2372: } else {
1.476 albertel 2373: my $blankpages =
2374: '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
2375:
2376: $current_output = '\strut\vspace*{-6 mm}\\newline'.
2377: ©right_line().' \newpage '.$blankpages.$end_of_student.
2378: '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
2379: $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284 albertel 2380: }
1.440 foxr 2381: #
2382: # Close the student bracketing.
2383: #
1.375 foxr 2384: return ($current_output,$fullname, $printed);
1.284 albertel 2385:
2386: }
1.140 sakharuk 2387:
1.3 sakharuk 2388: sub handler {
2389:
2390: my $r = shift;
1.397 albertel 2391:
2392: &init_perm();
1.114 bowersj2 2393:
1.416 foxr 2394:
1.67 www 2395:
1.397 albertel 2396: my $helper = printHelper($r);
2397: if (!ref($helper)) {
2398: return $helper;
1.60 sakharuk 2399: }
1.177 sakharuk 2400:
1.184 sakharuk 2401:
1.454 foxr 2402: %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353 foxr 2403:
1.416 foxr 2404:
1.350 foxr 2405:
2406:
1.367 foxr 2407: # If a figure conversion queue file exists for this user.domain
2408: # we delete it since it can only be bad (if it were good, printout.pl
2409: # would have deleted it the last time around.
2410:
1.373 albertel 2411: my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367 foxr 2412: if(-e $conversion_queuefile) {
2413: unlink $conversion_queuefile;
2414: }
1.515 foxr 2415:
2416:
1.184 sakharuk 2417: &output_data($r,$helper,\%parmhash);
1.2 sakharuk 2418: return OK;
1.60 sakharuk 2419: }
1.2 sakharuk 2420:
1.131 bowersj2 2421: use Apache::lonhelper;
1.130 sakharuk 2422:
1.223 bowersj2 2423: sub addMessage {
2424: my $text = shift;
2425: my $paramHash = Apache::lonhelper::getParamHash();
2426: $paramHash->{MESSAGE_TEXT} = $text;
2427: Apache::lonhelper::message->new();
2428: }
2429:
1.416 foxr 2430:
1.238 bowersj2 2431:
1.397 albertel 2432: sub init_perm {
2433: undef(%perm);
2434: $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
2435: if (!$perm{'pav'}) {
2436: $perm{'pav'}=&Apache::lonnet::allowed('pav',
2437: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2438: }
1.465 albertel 2439: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397 albertel 2440: if (!$perm{'pfo'}) {
2441: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',
2442: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2443: }
2444: }
2445:
1.507 albertel 2446: sub get_randomly_ordered_warning {
2447: my ($helper,$map) = @_;
2448:
2449: my $message;
2450:
2451: my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
2452: my $navmap = Apache::lonnavmaps::navmap->new();
2453: my $res = $navmap->getResourceByUrl($map);
2454: if ($res) {
2455: my $func =
2456: sub { return ($_[0]->is_map() && $_[0]->randomorder); };
2457: my @matches = $navmap->retrieveResources($res, $func,1,1,1);
2458: if (@matches) {
1.508 albertel 2459: $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 2460: }
2461: }
2462: if ($message) {
2463: return '<message type="warning">'.$message.'</message>';
2464: }
2465: return;
2466: }
2467:
1.131 bowersj2 2468: sub printHelper {
1.115 bowersj2 2469: my $r = shift;
2470:
2471: if ($r->header_only) {
1.373 albertel 2472: if ($env{'browser.mathml'}) {
1.241 www 2473: &Apache::loncommon::content_type($r,'text/xml');
1.131 bowersj2 2474: } else {
1.241 www 2475: &Apache::loncommon::content_type($r,'text/html');
1.131 bowersj2 2476: }
2477: $r->send_http_header;
2478: return OK;
1.115 bowersj2 2479: }
2480:
1.131 bowersj2 2481: # Send header, nocache
1.373 albertel 2482: if ($env{'browser.mathml'}) {
1.241 www 2483: &Apache::loncommon::content_type($r,'text/xml');
1.115 bowersj2 2484: } else {
1.241 www 2485: &Apache::loncommon::content_type($r,'text/html');
1.115 bowersj2 2486: }
2487: &Apache::loncommon::no_cache($r);
2488: $r->send_http_header;
2489: $r->rflush();
2490:
1.131 bowersj2 2491: # Unfortunately, this helper is so complicated we have to
2492: # write it by hand
2493:
2494: Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
2495:
1.176 bowersj2 2496: my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146 bowersj2 2497: $helper->declareVar('symb');
1.156 bowersj2 2498: $helper->declareVar('postdata');
1.290 sakharuk 2499: $helper->declareVar('curseed');
2500: $helper->declareVar('probstatus');
1.156 bowersj2 2501: $helper->declareVar('filename');
2502: $helper->declareVar('construction');
1.178 sakharuk 2503: $helper->declareVar('assignment');
1.262 sakharuk 2504: $helper->declareVar('style_file');
1.340 foxr 2505: $helper->declareVar('student_sort');
1.363 foxr 2506: $helper->declareVar('FINISHPAGE');
1.366 foxr 2507: $helper->declareVar('PRINT_TYPE');
1.372 foxr 2508: $helper->declareVar("showallfoils");
1.483 foxr 2509: $helper->declareVar("STUDENTS");
1.363 foxr 2510:
1.518 foxr 2511:
2512:
2513:
2514:
1.363 foxr 2515: # The page breaks can get loaded initially from the course environment:
1.394 foxr 2516: # But we only do this in the initial state so that they are allowed to change.
2517: #
1.366 foxr 2518:
1.416 foxr 2519: # $helper->{VARS}->{FINISHPAGE} = '';
1.363 foxr 2520:
2521: &Apache::loncommon::restore_course_settings('print',
1.366 foxr 2522: {'pagebreaks' => 'scalar',
2523: 'lastprinttype' => 'scalar'});
2524:
1.483 foxr 2525: # This will persistently load in the data we want from the
2526: # very first screen.
1.394 foxr 2527:
2528: if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
2529: if (!defined ($env{"form.CURRENT_STATE"})) {
2530:
2531: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
2532: } else {
2533: my $state = $env{"form.CURRENT_STATE"};
2534: if ($state eq "START") {
2535: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
2536: }
2537: }
2538:
1.366 foxr 2539: }
1.481 albertel 2540:
1.483 foxr 2541:
1.156 bowersj2 2542: # Detect whether we're coming from construction space
1.373 albertel 2543: if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235 bowersj2 2544: $helper->{VARS}->{'filename'} = "~$1/$2";
1.156 bowersj2 2545: $helper->{VARS}->{'construction'} = 1;
1.481 albertel 2546: } else {
1.373 albertel 2547: if ($env{'form.postdata'}) {
2548: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482 albertel 2549: if ( $helper->{VARS}->{'symb'} eq '') {
2550: $helper->{VARS}->{'postdata'} = $env{'form.postdata'};
2551: }
1.156 bowersj2 2552: }
1.373 albertel 2553: if ($env{'form.symb'}) {
2554: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156 bowersj2 2555: }
1.373 albertel 2556: if ($env{'form.url'}) {
1.156 bowersj2 2557: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
2558: }
1.416 foxr 2559:
1.157 bowersj2 2560: }
1.481 albertel 2561:
1.373 albertel 2562: if ($env{'form.symb'}) {
2563: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146 bowersj2 2564: }
1.373 albertel 2565: if ($env{'form.url'}) {
1.140 sakharuk 2566: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153 sakharuk 2567:
1.140 sakharuk 2568: }
1.343 albertel 2569: $helper->{VARS}->{'symb'}=
2570: &Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335 albertel 2571: my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178 sakharuk 2572: if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481 albertel 2573:
1.156 bowersj2 2574:
1.146 bowersj2 2575: # Extract map
2576: my $symb = $helper->{VARS}->{'symb'};
1.156 bowersj2 2577: my ($map, $id, $url);
2578: my $subdir;
1.483 foxr 2579: my $is_published=0; # True when printing from resource space.
1.156 bowersj2 2580:
2581: # Get the resource name from construction space
2582: if ($helper->{VARS}->{'construction'}) {
2583: $resourceTitle = substr($helper->{VARS}->{'filename'},
2584: rindex($helper->{VARS}->{'filename'}, '/')+1);
2585: $subdir = substr($helper->{VARS}->{'filename'},
2586: 0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481 albertel 2587: } else {
1.482 albertel 2588: if ($symb ne '') {
2589: ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
2590: $helper->{VARS}->{'postdata'} =
2591: &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
2592: } else {
2593: $url = $helper->{VARS}->{'postdata'};
1.483 foxr 2594: $is_published=1; # From resource space.
1.482 albertel 2595: }
2596: $url = &Apache::lonnet::clutter($url);
1.481 albertel 2597:
1.156 bowersj2 2598: if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238 bowersj2 2599: my $postdata = $helper->{VARS}->{'postdata'};
2600: $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156 bowersj2 2601: }
2602: $subdir = &Apache::lonnet::filelocation("", $url);
1.128 bowersj2 2603: }
1.373 albertel 2604: if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
2605: $helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230 albertel 2606: }
1.373 albertel 2607: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
1.512 foxr 2608: $helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
1.290 sakharuk 2609: }
1.115 bowersj2 2610:
1.192 bowersj2 2611: my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
2612:
1.481 albertel 2613: Apache::lonhelper::registerHelperTags();
1.119 bowersj2 2614:
1.131 bowersj2 2615: # "Delete everything after the last slash."
1.119 bowersj2 2616: $subdir =~ s|/[^/]+$||;
2617:
1.131 bowersj2 2618: # What can be printed is a very dynamic decision based on
2619: # lots of factors. So we need to dynamically build this list.
2620: # To prevent security leaks, states are only added to the wizard
2621: # if they can be reached, which ensures manipulating the form input
2622: # won't allow anyone to reach states they shouldn't have permission
2623: # to reach.
2624:
2625: # printChoices is tracking the kind of printing the user can
2626: # do, and will be used in a choices construction later.
2627: # In the meantime we will be adding states and elements to
2628: # the helper by hand.
2629: my $printChoices = [];
2630: my $paramHash;
1.130 sakharuk 2631:
1.240 albertel 2632: if ($resourceTitle) {
1.458 www 2633: push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156 bowersj2 2634: }
2635:
1.238 bowersj2 2636: # Useful filter strings
1.287 albertel 2637: my $isProblem = '($res->is_problem()||$res->contains_problem) ';
1.238 bowersj2 2638: $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.287 albertel 2639: my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence()';
2640: my $isNotMap = '!$res->is_sequence()';
1.238 bowersj2 2641: $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
2642: my $isMap = '$res->is_map()';
1.342 albertel 2643: my $symbFilter = '$res->shown_symb()';
2644: my $urlValue = '$res->link()';
1.238 bowersj2 2645:
2646: $helper->declareVar('SEQUENCE');
2647:
1.465 albertel 2648: # If we're in a sequence...
1.416 foxr 2649:
1.465 albertel 2650: my $start_new_option;
2651: if ($perm{'pav'}) {
2652: $start_new_option =
2653: "<option text='".&mt('Start new page<br />before selected').
2654: "' variable='FINISHPAGE' />";
2655: }
1.238 bowersj2 2656:
1.483 foxr 2657: if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
1.350 foxr 2658:
1.243 bowersj2 2659: $helper->{VARS}->{'postdata'} &&
2660: $helper->{VARS}->{'assignment'}) {
1.131 bowersj2 2661: # Allow problems from sequence
1.458 www 2662: push @{$printChoices}, [&mt('Selected <b>Problems</b> in folder <b><i>[_1]</i></b>',$sequenceTitle), 'map_problems', 'CHOOSE_PROBLEMS'];
1.131 bowersj2 2663: # Allow all resources from sequence
1.458 www 2664: push @{$printChoices}, [&mt('Selected <b>Resources</b> in folder <b><i>[_1]</i></b>',$sequenceTitle), 'map_problems_pages', 'CHOOSE_PROBLEMS_HTML'];
1.465 albertel 2665:
1.131 bowersj2 2666: my $helperFragment = <<HELPERFRAGMENT;
1.155 sakharuk 2667: <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print">
1.435 foxr 2668: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2669: closeallpages="1">
1.144 bowersj2 2670: <nextstate>PAGESIZE</nextstate>
1.435 foxr 2671: <filterfunc>return $isProblem;</filterfunc>
1.131 bowersj2 2672: <mapurl>$map</mapurl>
1.238 bowersj2 2673: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2674: $start_new_option
1.131 bowersj2 2675: </resource>
2676: </state>
2677:
1.155 sakharuk 2678: <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print">
1.435 foxr 2679: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2680: closeallpages="1">
1.144 bowersj2 2681: <nextstate>PAGESIZE</nextstate>
1.435 foxr 2682: <filterfunc>return $isNotMap;</filterfunc>
1.131 bowersj2 2683: <mapurl>$map</mapurl>
1.238 bowersj2 2684: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2685: $start_new_option
1.131 bowersj2 2686: </resource>
2687: </state>
2688: HELPERFRAGMENT
1.121 bowersj2 2689:
1.326 sakharuk 2690: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121 bowersj2 2691: }
2692:
1.397 albertel 2693: # If the user has pfo (print for otheres) allow them to print all
1.354 foxr 2694: # problems and resources in the entier course, optionally for selected students
1.483 foxr 2695: if ($perm{'pfo'} && !$is_published &&
1.481 albertel 2696: ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) {
2697:
1.509 albertel 2698: push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
2699: push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.284 albertel 2700: &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS);
1.155 sakharuk 2701: <state name="ALL_PROBLEMS" title="Select Problem(s) to print">
1.287 albertel 2702: <resource variable="RESOURCES" toponly='0' multichoice="1"
2703: suppressEmptySequences='0' addstatus="1" closeallpages="1">
1.144 bowersj2 2704: <nextstate>PAGESIZE</nextstate>
1.192 bowersj2 2705: <filterfunc>return $isProblemOrMap;</filterfunc>
1.287 albertel 2706: <choicefunc>return $isNotMap;</choicefunc>
1.238 bowersj2 2707: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2708: $start_new_option
1.284 albertel 2709: </resource>
2710: </state>
1.354 foxr 2711: <state name="ALL_RESOURCES" title="Select Resource(s) to print">
2712: <resource variable="RESOURCES" toponly='0' multichoice='1'
2713: suppressEmptySequences='0' addstatus='1' closeallpages='1'>
2714: <nextstate>PAGESIZE</nextstate>
2715: <filterfunc>return $isNotMap; </filterfunc>
2716: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2717: $start_new_option
1.354 foxr 2718: </resource>
2719: </state>
1.284 albertel 2720: ALL_PROBLEMS
1.132 bowersj2 2721:
1.284 albertel 2722: if ($helper->{VARS}->{'assignment'}) {
1.483 foxr 2723: 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 2724: 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 2725: }
1.424 foxr 2726:
1.507 albertel 2727: my $randomly_ordered_warning =
2728: &get_randomly_ordered_warning($helper,$map);
2729:
1.424 foxr 2730: # resource_selector will hold a few states that:
2731: # - Allow resources to be selected for printing.
2732: # - Determine pagination between assignments.
2733: # - Determine how many assignments should be bundled into a single PDF.
2734: # TODO:
2735: # Probably good to do things like separate this up into several vars, each
2736: # with one state, and use REGEXPs at inclusion time to set state names
2737: # and next states for better mix and match capability
2738: #
1.284 albertel 2739: my $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 2740: <state name="SELECT_PROBLEMS" title="Select resources to print">
1.507 albertel 2741: $randomly_ordered_warning
2742:
1.424 foxr 2743: <nextstate>PRINT_FORMATTING</nextstate>
1.284 albertel 2744: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 2745: <resource variable="RESOURCES" multichoice="1" addstatus="1"
2746: closeallpages="1">
1.254 sakharuk 2747: <filterfunc>return $isProblem;</filterfunc>
1.148 bowersj2 2748: <mapurl>$map</mapurl>
1.254 sakharuk 2749: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2750: $start_new_option
1.147 bowersj2 2751: </resource>
1.424 foxr 2752: </state>
2753: <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155 sakharuk 2754: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149 bowersj2 2755: <choices variable="EMPTY_PAGES">
1.204 sakharuk 2756: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
2757: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
2758: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
2759: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 2760: </choices>
1.424 foxr 2761: <nextstate>PAGESIZE</nextstate>
1.429 foxr 2762: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
2763: <choices variable="SPLIT_PDFS">
2764: <choice computer="all">All assignments in a single PDF file</choice>
2765: <choice computer="sections">Each PDF contains exactly one section</choice>
2766: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 2767: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
2768: Specify the number of assignments per PDF:</choice>
1.429 foxr 2769: </choices>
1.424 foxr 2770: </state>
1.284 albertel 2771: RESOURCE_SELECTOR
2772:
2773: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS);
2774: <state name="CHOOSE_STUDENTS" title="Select Students and Resources">
1.485 albertel 2775: <message><b>Select sorting order of printout</b> </message>
1.340 foxr 2776: <choices variable='student_sort'>
2777: <choice computer='0'>Sort by section then student</choice>
2778: <choice computer='1'>Sort by students across sections.</choice>
2779: </choices>
1.437 foxr 2780: <message><br /><hr /><br /> </message>
1.425 foxr 2781: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_PROBLEMS" coursepersonnel="1"/>
1.424 foxr 2782: </state>
1.284 albertel 2783: $resource_selector
1.131 bowersj2 2784: CHOOSE_STUDENTS
1.292 albertel 2785:
1.373 albertel 2786: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2787: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292 albertel 2788: my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
2789: my $namechoice='<choice></choice>';
1.337 albertel 2790: foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294 albertel 2791: if ($name =~ /^error: 2 /) { next; }
1.381 albertel 2792: if ($name =~ /^type\0/) { next; }
1.292 albertel 2793: $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
2794: }
1.389 foxr 2795:
2796:
2797: my %code_values;
1.405 albertel 2798: my %codes_to_print;
1.411 albertel 2799: foreach my $key (@names) {
1.389 foxr 2800: %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405 albertel 2801: foreach my $key (keys(%code_values)) {
2802: $codes_to_print{$key} = 1;
1.388 foxr 2803: }
2804: }
1.389 foxr 2805:
1.452 albertel 2806: my $code_selection;
1.405 albertel 2807: foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389 foxr 2808: my $choice = $code;
2809: if ($code =~ /^[A-Z]+$/) { # Alpha code
2810: $choice = &letters_to_num($code);
2811: }
1.432 albertel 2812: push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388 foxr 2813: }
1.436 albertel 2814: if (%codes_to_print) {
2815: $code_selection .='
1.472 albertel 2816: <message><b>Choose single CODE from list:</b></message>
1.448 albertel 2817: <message></td><td></message>
1.452 albertel 2818: <dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
2819: <choice></choice>
1.448 albertel 2820: <exec>
2821: push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
2822: </exec>
1.452 albertel 2823: </dropdown>
1.468 foxr 2824: <message></td></tr><tr><td></message>
1.436 albertel 2825: '.$/;
1.448 albertel 2826:
1.436 albertel 2827: }
1.432 albertel 2828:
2829:
1.381 albertel 2830: open(FH,$Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
2831: my $codechoice='';
2832: foreach my $line (<FH>) {
2833: my ($name,$description,$code_type,$code_length)=
2834: (split(/:/,$line))[0,1,2,4];
2835: if ($code_length > 0 &&
2836: $code_type =~/^(letter|number|-1)/) {
2837: $codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
2838: }
2839: }
2840: if ($codechoice eq '') {
2841: $codechoice='<choice computer="default">Default</choice>';
2842: }
1.284 albertel 2843: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1);
1.468 foxr 2844: <state name="CHOOSE_ANON1" title="Specify CODEd Assignments">
1.424 foxr 2845: <nextstate>SELECT_PROBLEMS</nextstate>
1.468 foxr 2846: <message><h4>Fill out one of the forms below</h4></message>
2847: <message><br /><hr /> <br /></message>
2848: <message><h3>Generate new CODEd Assignments</h3></message>
2849: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 2850: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
2851: <validator>
2852: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.382 foxr 2853: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 2854: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
2855: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 2856: return "You need to specify the number of assignments to print";
2857: }
2858: return undef;
2859: </validator>
2860: </string>
2861: <message></td></tr><tr><td></message>
1.501 albertel 2862: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 2863: <message></td><td></message>
2864: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
2865: <message></td></tr><tr><td></message>
2866: <message><b>Bubble sheet type:</b></message>
2867: <message></td><td></message>
2868: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
2869: $codechoice
2870: </dropdown>
1.468 foxr 2871: <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>
2872: <message></td></tr><tr><td></table></message>
1.472 albertel 2873: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
1.468 foxr 2874: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 2875: <string variable="SINGLE_CODE" size="10">
1.382 foxr 2876: <validator>
2877: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 2878: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
2879: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.382 foxr 2880: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
2881: \$helper->{'VARS'}{'CODE_OPTION'});
2882: } else {
2883: return undef; # Other forces control us.
2884: }
2885: </validator>
2886: </string>
1.472 albertel 2887: <message></td></tr><tr><td></message>
1.432 albertel 2888: $code_selection
1.468 foxr 2889: <message></td></tr></table></message>
1.472 albertel 2890: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
1.468 foxr 2891: <message><b>Select saved CODEs:</b></message>
1.381 albertel 2892: <message></td><td></message>
1.292 albertel 2893: <dropdown variable="REUSE_OLD_CODES">
2894: $namechoice
2895: </dropdown>
1.412 albertel 2896: <message></td></tr></table></message>
1.284 albertel 2897: </state>
1.424 foxr 2898: $resource_selector
1.284 albertel 2899: CHOOSE_ANON1
1.254 sakharuk 2900:
1.272 sakharuk 2901:
1.254 sakharuk 2902: if ($helper->{VARS}->{'assignment'}) {
1.483 foxr 2903: 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 2904: 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 2905: }
1.284 albertel 2906:
2907:
2908: $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 2909: <state name="SELECT_RESOURCES" title="Select Resources">
1.507 albertel 2910: $randomly_ordered_warning
2911:
1.424 foxr 2912: <nextstate>PRINT_FORMATTING</nextstate>
1.254 sakharuk 2913: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 2914: <resource variable="RESOURCES" multichoice="1" addstatus="1"
2915: closeallpages="1">
1.254 sakharuk 2916: <filterfunc>return $isNotMap;</filterfunc>
2917: <mapurl>$map</mapurl>
2918: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2919: $start_new_option
1.254 sakharuk 2920: </resource>
1.424 foxr 2921: </state>
2922: <state name="PRINT_FORMATTING" title="Format of the print job">
2923: <nextstate>NUMBER_PER_PDF</nextstate>
1.254 sakharuk 2924: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
2925: <choices variable="EMPTY_PAGES">
2926: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
2927: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
2928: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
2929: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 2930: </choices>
1.424 foxr 2931: <nextstate>PAGESIZE</nextstate>
1.429 foxr 2932: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
2933: <choices variable="SPLIT_PDFS">
2934: <choice computer="all">All assignments in a single PDF file</choice>
2935: <choice computer="sections">Each PDF contains exactly one section</choice>
2936: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 2937: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
2938: Specify the number of assignments per PDF:</choice>
1.429 foxr 2939: </choices>
1.424 foxr 2940: </state>
1.284 albertel 2941: RESOURCE_SELECTOR
2942:
2943: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
2944: <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340 foxr 2945: <choices variable='student_sort'>
2946: <choice computer='0'>Sort by section then student</choice>
2947: <choice computer='1'>Sort by students across sections.</choice>
2948: </choices>
1.437 foxr 2949: <message><br /><hr /><br /></message>
1.426 foxr 2950: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340 foxr 2951:
1.424 foxr 2952: </state>
1.284 albertel 2953: $resource_selector
1.254 sakharuk 2954: CHOOSE_STUDENTS1
2955:
1.284 albertel 2956: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472 albertel 2957: <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424 foxr 2958: <nextstate>SELECT_RESOURCES</nextstate>
1.472 albertel 2959: <message><h4>Fill out one of the forms below</h4></message>
2960: <message><br /><hr /> <br /></message>
2961: <message><h3>Generate new CODEd Assignments</h3></message>
2962: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 2963: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
2964: <validator>
2965: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386 foxr 2966: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 2967: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
2968: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 2969: return "You need to specify the number of assignments to print";
2970: }
2971: return undef;
2972: </validator>
2973: </string>
2974: <message></td></tr><tr><td></message>
1.501 albertel 2975: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 2976: <message></td><td></message>
2977: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
2978: <message></td></tr><tr><td></message>
2979: <message><b>Bubble sheet type:</b></message>
2980: <message></td><td></message>
2981: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
2982: $codechoice
2983: </dropdown>
1.472 albertel 2984: <message></td></tr><tr><td></table></message>
2985: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
2986: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 2987: <string variable="SINGLE_CODE" size="10">
1.386 foxr 2988: <validator>
2989: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 2990: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
2991: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386 foxr 2992: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
2993: \$helper->{'VARS'}{'CODE_OPTION'});
2994: } else {
2995: return undef; # Other forces control us.
2996: }
2997: </validator>
2998: </string>
1.472 albertel 2999: <message></td></tr><tr><td></message>
1.432 albertel 3000: $code_selection
1.472 albertel 3001: <message></td></tr></table></message>
3002: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
3003: <message><b>Select saved CODEs:</b></message>
1.381 albertel 3004: <message></td><td></message>
1.294 albertel 3005: <dropdown variable="REUSE_OLD_CODES">
3006: $namechoice
3007: </dropdown>
1.412 albertel 3008: <message></td></tr></table></message>
1.424 foxr 3009: </state>
1.284 albertel 3010: $resource_selector
3011: CHOOSE_ANON2
1.481 albertel 3012: }
3013:
1.121 bowersj2 3014: # FIXME: That RE should come from a library somewhere.
1.483 foxr 3015: if (($perm{'pav'}
1.482 albertel 3016: && $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
3017: && (defined($helper->{'VARS'}->{'construction'})
3018: ||
3019: (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
3020: &&
3021: $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483 foxr 3022: ))
3023: && $helper->{VARS}->{'assignment'} eq ""
1.482 albertel 3024: ) {
1.238 bowersj2 3025:
1.482 albertel 3026: my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
3027: 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 3028: my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482 albertel 3029: <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458 www 3030:
1.138 bowersj2 3031: <files variable="FILES" multichoice='1'>
1.144 bowersj2 3032: <nextstate>PAGESIZE</nextstate>
1.138 bowersj2 3033: <filechoice>return '$subdir';</filechoice>
1.139 bowersj2 3034: CHOOSE_FROM_SUBDIR
3035:
1.238 bowersj2 3036: # this is broken up because I really want interpolation above,
3037: # and I really DON'T want it below
1.139 bowersj2 3038: $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225 bowersj2 3039: <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
3040: $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131 bowersj2 3041: </filefilter>
1.138 bowersj2 3042: </files>
1.131 bowersj2 3043: </state>
3044: CHOOSE_FROM_SUBDIR
1.139 bowersj2 3045: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131 bowersj2 3046: }
1.238 bowersj2 3047:
3048: # Allow the user to select any sequence in the course, feed it to
3049: # another resource selector for that sequence
1.483 foxr 3050: if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509 albertel 3051: push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249 sakharuk 3052: 'select_sequences', 'CHOOSE_SEQUENCE'];
1.244 bowersj2 3053: my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
3054: #Escape apostrophes and backslashes for Perl
3055: $escapedSequenceName =~ s/\\/\\\\/g;
3056: $escapedSequenceName =~ s/'/\\'/g;
1.239 bowersj2 3057: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238 bowersj2 3058: <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
3059: <message>Select the sequence to print resources from:</message>
3060: <resource variable="SEQUENCE">
3061: <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
3062: <filterfunc>return \$res->is_sequence;</filterfunc>
3063: <valuefunc>return $urlValue;</valuefunc>
1.447 foxr 3064: <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391 foxr 3065: </choicefunc>
1.238 bowersj2 3066: </resource>
3067: </state>
3068: <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
3069: <message>(mark desired resources then click "next" button) <br /></message>
1.435 foxr 3070: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 3071: closeallpages="1">
1.238 bowersj2 3072: <nextstate>PAGESIZE</nextstate>
1.466 albertel 3073: <filterfunc>return $isNotMap</filterfunc>
1.244 bowersj2 3074: <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238 bowersj2 3075: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 3076: $start_new_option
1.238 bowersj2 3077: </resource>
3078: </state>
3079: CHOOSE_FROM_ANY_SEQUENCE
1.239 bowersj2 3080: }
1.481 albertel 3081:
1.131 bowersj2 3082: # Generate the first state, to select which resources get printed.
1.223 bowersj2 3083: Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131 bowersj2 3084: $paramHash = Apache::lonhelper::getParamHash();
1.155 sakharuk 3085: $paramHash->{MESSAGE_TEXT} = "";
1.131 bowersj2 3086: Apache::lonhelper::message->new();
3087: $paramHash = Apache::lonhelper::getParamHash();
3088: $paramHash->{'variable'} = 'PRINT_TYPE';
3089: $paramHash->{CHOICES} = $printChoices;
3090: Apache::lonhelper::choices->new();
1.161 bowersj2 3091:
1.223 bowersj2 3092: my $startedTable = 0; # have we started an HTML table yet? (need
3093: # to close it later)
3094:
1.397 albertel 3095: if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or
1.170 sakharuk 3096: ($helper->{VARS}->{'construction'} eq '1')) {
1.497 www 3097: addMessage("<hr width='33%' /><table><tr><td align='right'>".
3098: '<label for="ANSWER_TYPE_forminput">'.
3099: &mt('Print').
3100: "</label>: </td><td>");
1.161 bowersj2 3101: $paramHash = Apache::lonhelper::getParamHash();
1.162 sakharuk 3102: $paramHash->{'variable'} = 'ANSWER_TYPE';
3103: $helper->declareVar('ANSWER_TYPE');
1.161 bowersj2 3104: $paramHash->{CHOICES} = [
1.242 sakharuk 3105: ['Without Answers', 'yes'],
3106: ['With Answers', 'no'],
1.368 albertel 3107: ['Only Answers', 'only']
1.289 sakharuk 3108: ];
1.210 sakharuk 3109: Apache::lonhelper::dropdown->new();
1.223 bowersj2 3110: addMessage("</td></tr>");
3111: $startedTable = 1;
1.161 bowersj2 3112: }
1.209 sakharuk 3113:
1.397 albertel 3114: if ($perm{'pav'}) {
1.223 bowersj2 3115: if (!$startedTable) {
1.497 www 3116: addMessage("<hr width='33%' /><table><tr><td align='right'>".
3117: '<label for="LATEX_TYPE_forminput">'.
3118: &mt('LaTeX mode').
3119: "</label>: </td><td>");
1.223 bowersj2 3120: $startedTable = 1;
3121: } else {
1.497 www 3122: addMessage("<tr><td align='right'>".
3123: '<label for="LATEX_TYPE_forminput">'.
3124: &mt('LaTeX mode').
3125: "</label>: </td><td>");
1.223 bowersj2 3126: }
1.203 sakharuk 3127: $paramHash = Apache::lonhelper::getParamHash();
3128: $paramHash->{'variable'} = 'LATEX_TYPE';
3129: $helper->declareVar('LATEX_TYPE');
3130: if ($helper->{VARS}->{'construction'} eq '1') {
3131: $paramHash->{CHOICES} = [
1.223 bowersj2 3132: ['standard LaTeX mode', 'standard'],
3133: ['LaTeX batchmode', 'batchmode'], ];
1.203 sakharuk 3134: } else {
3135: $paramHash->{CHOICES} = [
1.223 bowersj2 3136: ['LaTeX batchmode', 'batchmode'],
3137: ['standard LaTeX mode', 'standard'] ];
1.203 sakharuk 3138: }
1.210 sakharuk 3139: Apache::lonhelper::dropdown->new();
1.218 sakharuk 3140:
1.497 www 3141: addMessage("</td></tr><tr><td align='right'>".
1.506 albertel 3142: '<label for="TABLE_CONTENTS_forminput">'.
1.497 www 3143: &mt('Print Table of Contents').
3144: "</label>: </td><td>");
1.209 sakharuk 3145: $paramHash = Apache::lonhelper::getParamHash();
3146: $paramHash->{'variable'} = 'TABLE_CONTENTS';
3147: $helper->declareVar('TABLE_CONTENTS');
3148: $paramHash->{CHOICES} = [
1.223 bowersj2 3149: ['No', 'no'],
3150: ['Yes', 'yes'] ];
1.210 sakharuk 3151: Apache::lonhelper::dropdown->new();
1.223 bowersj2 3152: addMessage("</td></tr>");
1.214 sakharuk 3153:
1.220 sakharuk 3154: if (not $helper->{VARS}->{'construction'}) {
1.497 www 3155: addMessage("<tr><td align='right'>".
3156: '<label for="TABLE_INDEX_forminput">'.
3157: &mt('Print Index').
3158: "</label>: </td><td>");
1.220 sakharuk 3159: $paramHash = Apache::lonhelper::getParamHash();
3160: $paramHash->{'variable'} = 'TABLE_INDEX';
3161: $helper->declareVar('TABLE_INDEX');
3162: $paramHash->{CHOICES} = [
1.223 bowersj2 3163: ['No', 'no'],
3164: ['Yes', 'yes'] ];
1.220 sakharuk 3165: Apache::lonhelper::dropdown->new();
1.223 bowersj2 3166: addMessage("</td></tr>");
1.497 www 3167: addMessage("<tr><td align='right'>".
3168: '<label for="PRINT_DISCUSSIONS_forminput">'.
3169: &mt('Print Discussions').
3170: "</label>: </td><td>");
1.309 sakharuk 3171: $paramHash = Apache::lonhelper::getParamHash();
3172: $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';
3173: $helper->declareVar('PRINT_DISCUSSIONS');
3174: $paramHash->{CHOICES} = [
3175: ['No', 'no'],
3176: ['Yes', 'yes'] ];
3177: Apache::lonhelper::dropdown->new();
3178: addMessage("</td></tr>");
1.372 foxr 3179:
1.511 foxr 3180: # Prompt for printing annotations too.
3181:
3182: addMessage("<tr><td align='right'>".
3183: '<label for="PRINT_ANNOTATIONS_forminput">'.
3184: &mt('Print Annotations').
3185: "</label>:</td><td>");
3186: $paramHash = Apache::lonhelper::getParamHash();
3187: $paramHash->{'variable'} = "PRINT_ANNOTATIONS";
3188: $helper->declareVar("PRINT_ANNOTATIONS");
3189: $paramHash->{CHOICES} = [
3190: ['No', 'no'],
3191: ['Yes', 'yes']];
3192: Apache::lonhelper::dropdown->new();
3193: addMessage("</td></tr>");
3194:
1.397 albertel 3195: addMessage("<tr><td align = 'right'> </td><td>");
3196: $paramHash = Apache::lonhelper::getParamHash();
3197: $paramHash->{'multichoice'} = "true";
3198: $paramHash->{'allowempty'} = "true";
3199: $paramHash->{'variable'} = "showallfoils";
3200: $paramHash->{'CHOICES'} = [ ["Show all foils", "1"] ];
3201: Apache::lonhelper::choices->new();
3202: addMessage("</td></tr>");
1.220 sakharuk 3203: }
1.219 sakharuk 3204:
1.230 albertel 3205: if ($helper->{'VARS'}->{'construction'}) {
1.505 albertel 3206: my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497 www 3207: my $randseedtext=&mt("Use random seed");
3208: my $stylefiletext=&mt("Use style file");
1.506 albertel 3209: my $selectfiletext=&mt("Select style file");
1.497 www 3210:
1.265 sakharuk 3211: my $xmlfrag .= <<"RNDSEED";
1.497 www 3212: <message><tr><td align='right'>
3213: <label for="curseed_forminput">$randseedtext</label>:
3214: </td><td></message>
1.230 albertel 3215: <string variable="curseed" size="15" maxlength="15">
3216: <defaultvalue>
3217: return $helper->{VARS}->{'curseed'};
3218: </defaultvalue>
1.262 sakharuk 3219: </string>
1.497 www 3220: <message></td></tr><tr><td align="right">
1.503 albertel 3221: <label for="style_file">$stylefiletext</label>:
1.497 www 3222: </td><td></message>
1.504 albertel 3223: <string variable="style_file" size="40">
3224: <defaultvalue>
1.505 albertel 3225: return $stylevalue;
1.504 albertel 3226: </defaultvalue>
1.506 albertel 3227: </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 3228: <choices allowempty="1" multichoice="true" variable="showallfoils">
1.506 albertel 3229: <choice computer="1">Show all foils</choice>
1.371 foxr 3230: </choices>
1.378 albertel 3231: <message></td></tr></message>
1.230 albertel 3232: RNDSEED
3233: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.512 foxr 3234:
3235:
3236: addMessage("<tr><td>Problem Type:</td><td>");
3237: #
3238: # Initial value from construction space:
3239: #
3240: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
3241: $helper->{VARS}->{'probstatus'} = $env{'form.problemtype'}; # initial value
3242: }
1.518 foxr 3243: $xmlfrag = << "PROBTYPE";
3244: <dropdown variable="probstatus" multichoice="0" allowempty="0">
3245: <defaultvalue>
3246: return "$helper->{VARS}->{'probstatus'}";
3247: </defaultvalue>
3248: <choice computer="problem">Homework Problem</choice>
3249: <choice computer="exam">Exam Problem</choice>
3250: <choice computer="survey">Survey question</choice>
3251: </dropdown>
3252: PROBTYPE
3253: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
3254:
1.512 foxr 3255: addMessage("</td></tr>");
3256:
1.372 foxr 3257: }
1.223 bowersj2 3258: }
1.264 sakharuk 3259:
3260:
3261:
1.218 sakharuk 3262:
1.223 bowersj2 3263: if ($startedTable) {
3264: addMessage("</table>");
1.215 sakharuk 3265: }
1.161 bowersj2 3266:
1.131 bowersj2 3267: Apache::lonprintout::page_format_state->new("FORMAT");
3268:
1.144 bowersj2 3269: # Generate the PAGESIZE state which will offer the user the margin
3270: # choices if they select one column
3271: Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
3272: Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
3273:
3274:
1.131 bowersj2 3275: $helper->process();
3276:
1.416 foxr 3277:
1.131 bowersj2 3278: # MANUAL BAILOUT CONDITION:
3279: # If we're in the "final" state, bailout and return to handler
3280: if ($helper->{STATE} eq 'FINAL') {
3281: return $helper;
3282: }
1.130 sakharuk 3283:
1.131 bowersj2 3284: $r->print($helper->display());
1.395 www 3285: if ($helper->{STATE} eq 'START') {
3286: &recently_generated($r);
3287: }
1.333 albertel 3288: &Apache::lonhelper::unregisterHelperTags();
1.115 bowersj2 3289:
3290: return OK;
3291: }
3292:
1.1 www 3293:
3294: 1;
1.119 bowersj2 3295:
3296: package Apache::lonprintout::page_format_state;
3297:
3298: =pod
3299:
1.131 bowersj2 3300: =head1 Helper element: page_format_state
3301:
3302: See lonhelper.pm documentation for discussion of the helper framework.
1.119 bowersj2 3303:
1.131 bowersj2 3304: Apache::lonprintout::page_format_state is an element that gives the
3305: user an opportunity to select the page layout they wish to print
3306: with: Number of columns, portrait/landscape, and paper size. If you
3307: want to change the paper size choices, change the @paperSize array
3308: contents in this package.
1.119 bowersj2 3309:
1.131 bowersj2 3310: page_format_state is always directly invoked in lonprintout.pm, so there
3311: is no tag interface. You actually pass parameters to the constructor.
1.119 bowersj2 3312:
3313: =over 4
3314:
1.131 bowersj2 3315: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119 bowersj2 3316:
3317: =back
3318:
3319: =cut
3320:
1.131 bowersj2 3321: use Apache::lonhelper;
1.119 bowersj2 3322:
3323: no strict;
1.131 bowersj2 3324: @ISA = ("Apache::lonhelper::element");
1.119 bowersj2 3325: use strict;
1.266 sakharuk 3326: use Apache::lonlocal;
1.373 albertel 3327: use Apache::lonnet;
1.119 bowersj2 3328:
3329: my $maxColumns = 2;
1.376 albertel 3330: # it'd be nice if these all worked
3331: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
3332: # "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
3333: # "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]",
3334: # "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326 sakharuk 3335: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
1.376 albertel 3336: "a4 [210x297 mm]");
1.119 bowersj2 3337:
3338: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
3339: # Paper type
3340:
3341: sub new {
1.131 bowersj2 3342: my $self = Apache::lonhelper::element->new();
1.119 bowersj2 3343:
1.135 bowersj2 3344: shift;
3345:
1.131 bowersj2 3346: $self->{'variable'} = shift;
1.134 bowersj2 3347: my $helper = Apache::lonhelper::getHelper();
1.135 bowersj2 3348: $helper->declareVar($self->{'variable'});
1.131 bowersj2 3349: bless($self);
1.119 bowersj2 3350: return $self;
3351: }
3352:
3353: sub render {
3354: my $self = shift;
1.131 bowersj2 3355: my $helper = Apache::lonhelper::getHelper();
1.119 bowersj2 3356: my $result = '';
1.131 bowersj2 3357: my $var = $self->{'variable'};
1.266 sakharuk 3358: my $PageLayout=&mt('Page layout');
3359: my $NumberOfColumns=&mt('Number of columns');
3360: my $PaperType=&mt('Paper type');
1.506 albertel 3361: my $landscape=&mt('Landscape');
3362: my $portrait=&mt('Portrait');
1.119 bowersj2 3363: $result .= <<STATEHTML;
3364:
1.223 bowersj2 3365: <hr width="33%" />
1.119 bowersj2 3366: <table cellpadding="3">
3367: <tr>
1.266 sakharuk 3368: <td align="center"><b>$PageLayout</b></td>
3369: <td align="center"><b>$NumberOfColumns</b></td>
3370: <td align="center"><b>$PaperType</b></td>
1.119 bowersj2 3371: </tr>
3372: <tr>
3373: <td>
1.506 albertel 3374: <label><input type="radio" name="${var}.layout" value="L" /> $landscape </label><br />
3375: <label><input type="radio" name="${var}.layout" value="P" checked='1' /> $portrait </label>
1.119 bowersj2 3376: </td>
1.155 sakharuk 3377: <td align="center">
1.119 bowersj2 3378: <select name="${var}.cols">
3379: STATEHTML
3380:
3381: my $i;
3382: for ($i = 1; $i <= $maxColumns; $i++) {
1.144 bowersj2 3383: if ($i == 2) {
1.119 bowersj2 3384: $result .= "<option value='$i' selected>$i</option>\n";
3385: } else {
3386: $result .= "<option value='$i'>$i</option>\n";
3387: }
3388: }
3389:
3390: $result .= "</select></td><td>\n";
3391: $result .= "<select name='${var}.paper'>\n";
3392:
1.373 albertel 3393: my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398 albertel 3394: my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
3395: $DefaultPaperSize=~s/\s//g;
1.304 sakharuk 3396: if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119 bowersj2 3397: $i = 0;
3398: foreach (@paperSize) {
1.326 sakharuk 3399: $_=~/(\w+)/;
3400: my $papersize=$1;
1.304 sakharuk 3401: if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.326 sakharuk 3402: $result .= "<option selected value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119 bowersj2 3403: } else {
1.326 sakharuk 3404: $result .= "<option value='$papersize'>" . $paperSize[$i] . "</option>\n";
1.119 bowersj2 3405: }
3406: $i++;
3407: }
3408: $result .= "</select></td></tr></table>";
3409: return $result;
1.135 bowersj2 3410: }
3411:
3412: sub postprocess {
3413: my $self = shift;
3414:
3415: my $var = $self->{'variable'};
1.136 bowersj2 3416: my $helper = Apache::lonhelper->getHelper();
1.135 bowersj2 3417: $helper->{VARS}->{$var} =
1.373 albertel 3418: $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
3419: $env{"form.$var.paper"};
1.135 bowersj2 3420: return 1;
1.119 bowersj2 3421: }
3422:
3423: 1;
1.144 bowersj2 3424:
3425: package Apache::lonprintout::page_size_state;
3426:
3427: =pod
3428:
3429: =head1 Helper element: page_size_state
3430:
3431: See lonhelper.pm documentation for discussion of the helper framework.
3432:
3433: Apache::lonprintout::page_size_state is an element that gives the
3434: user the opportunity to further refine the page settings if they
3435: select a single-column page.
3436:
3437: page_size_state is always directly invoked in lonprintout.pm, so there
3438: is no tag interface. You actually pass parameters to the constructor.
3439:
3440: =over 4
3441:
3442: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
3443:
3444: =back
3445:
3446: =cut
3447:
3448: use Apache::lonhelper;
1.373 albertel 3449: use Apache::lonnet;
1.144 bowersj2 3450: no strict;
3451: @ISA = ("Apache::lonhelper::element");
3452: use strict;
3453:
3454:
3455:
3456: sub new {
3457: my $self = Apache::lonhelper::element->new();
3458:
3459: shift; # disturbs me (probably prevents subclassing) but works (drops
3460: # package descriptor)... - Jeremy
3461:
3462: $self->{'variable'} = shift;
3463: my $helper = Apache::lonhelper::getHelper();
3464: $helper->declareVar($self->{'variable'});
3465:
3466: # The variable name of the format element, so we can look into
3467: # $helper->{VARS} to figure out whether the columns are one or two
3468: $self->{'formatvar'} = shift;
3469:
1.463 foxr 3470:
1.144 bowersj2 3471: $self->{NEXTSTATE} = shift;
3472: bless($self);
1.467 foxr 3473:
1.144 bowersj2 3474: return $self;
3475: }
3476:
3477: sub render {
3478: my $self = shift;
3479: my $helper = Apache::lonhelper::getHelper();
3480: my $result = '';
3481: my $var = $self->{'variable'};
3482:
1.467 foxr 3483:
3484:
1.144 bowersj2 3485: if (defined $self->{ERROR_MSG}) {
1.464 albertel 3486: $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144 bowersj2 3487: }
3488:
1.438 foxr 3489: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463 foxr 3490:
3491: # Use format to get sensible defaults for the margins:
3492:
3493:
3494: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
3495: ($papersize) = split(/ /, $papersize);
3496:
3497:
3498: if ($laystyle eq 'L') {
3499: $laystyle = 'album';
3500: } else {
3501: $laystyle = 'book';
3502: }
3503:
3504:
1.464 albertel 3505: my %size;
3506: ($size{'width_and_units'},
3507: $size{'height_and_units'},
3508: $size{'margin_and_units'})=
3509: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463 foxr 3510:
1.464 albertel 3511: foreach my $dimension ('width','height','margin') {
3512: ($size{$dimension},$size{$dimension.'_unit'}) =
3513: split(/ +/, $size{$dimension.'_and_units'},2);
3514:
3515: foreach my $unit ('cm','in') {
3516: $size{$dimension.'_options'} .= '<option ';
3517: if ($size{$dimension.'_unit'} eq $unit) {
3518: $size{$dimension.'_options'} .= 'selected="selected" ';
3519: }
3520: $size{$dimension.'_options'} .= '>'.$unit.'</option>';
3521: }
1.438 foxr 3522: }
3523:
1.470 foxr 3524: # Adjust margin for LaTeX margin: .. requires units == cm or in.
3525:
3526: if ($size{'margin_unit'} eq 'in') {
3527: $size{'margin'} += 1;
3528: } else {
3529: $size{'margin'} += 2.54;
3530: }
1.506 albertel 3531: my %text = ('format' => 'How should each column be formatted?',
3532: 'width' => 'Width:',
3533: 'height' => 'Height:',
3534: 'margin' => 'Left Margin:',);
3535: %text = &Apache::lonlocal::texthash(%text);
3536:
1.144 bowersj2 3537: $result .= <<ELEMENTHTML;
3538:
1.506 albertel 3539: <p>$text{'format'}</p>
1.144 bowersj2 3540:
3541: <table cellpadding='3'>
3542: <tr>
1.506 albertel 3543: <td align='right'><b>$text{'width'}</b></td>
1.464 albertel 3544: <td align='left'><input type='text' name='$var.width' value="$size{'width'}" size='4' /></td>
1.144 bowersj2 3545: <td align='left'>
3546: <select name='$var.widthunit'>
1.464 albertel 3547: $size{'width_options'}
1.144 bowersj2 3548: </select>
3549: </td>
3550: </tr>
3551: <tr>
1.506 albertel 3552: <td align='right'><b>$text{'height'}</b></td>
1.464 albertel 3553: <td align='left'><input type='text' name="$var.height" value="$size{'height'}" size='4' /></td>
1.144 bowersj2 3554: <td align='left'>
3555: <select name='$var.heightunit'>
1.464 albertel 3556: $size{'height_options'}
1.144 bowersj2 3557: </select>
3558: </td>
3559: </tr>
3560: <tr>
1.506 albertel 3561: <td align='right'><b>$text{'margin'}</b></td>
1.464 albertel 3562: <td align='left'><input type='text' name='$var.lmargin' value="$size{'margin'}" size='4' /></td>
1.144 bowersj2 3563: <td align='left'>
1.186 bowersj2 3564: <select name='$var.lmarginunit'>
1.464 albertel 3565: $size{'margin_options'}
1.144 bowersj2 3566: </select>
3567: </td>
3568: </tr>
3569: </table>
3570:
1.464 albertel 3571: <!--<p>Hint: Some instructors like to leave scratch space for the student by
3572: making the width much smaller than the width of the page.</p>-->
1.144 bowersj2 3573:
3574: ELEMENTHTML
3575:
3576: return $result;
3577: }
3578:
1.470 foxr 3579:
1.144 bowersj2 3580: sub preprocess {
3581: my $self = shift;
3582: my $helper = Apache::lonhelper::getHelper();
3583:
3584: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467 foxr 3585:
3586: # If the user does not have 'pav' privilege, set default widths and
3587: # on to the next state right away.
3588: #
3589: if (!$perm{'pav'}) {
3590: my $var = $self->{'variable'};
3591: my $format = $helper->{VARS}->{$self->{'formatvar'}};
3592:
3593: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
3594: ($papersize) = split(/ /, $papersize);
3595:
3596:
3597: if ($laystyle eq 'L') {
3598: $laystyle = 'album';
3599: } else {
3600: $laystyle = 'book';
3601: }
3602: # Figure out some good defaults for the print out and set them:
3603:
3604: my %size;
3605: ($size{'width'},
3606: $size{'height'},
3607: $size{'lmargin'})=
3608: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
3609:
3610: foreach my $dim ('width', 'height', 'lmargin') {
3611: my ($value, $units) = split(/ /, $size{$dim});
1.470 foxr 3612:
1.467 foxr 3613: $helper->{VARS}->{"$var.".$dim} = $value;
3614: $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
3615:
3616: }
3617:
3618:
3619: # Transition to the next state
3620:
3621: $helper->changeState($self->{NEXTSTATE});
3622: }
1.144 bowersj2 3623:
3624: return 1;
3625: }
3626:
3627: sub postprocess {
3628: my $self = shift;
3629:
3630: my $var = $self->{'variable'};
3631: my $helper = Apache::lonhelper->getHelper();
1.373 albertel 3632: my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"};
3633: my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"};
3634: my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"};
3635: $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"};
3636: $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"};
3637: $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"};
1.144 bowersj2 3638:
3639: my $error = '';
3640:
3641: # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed
3642: # by an optional period, followed by digits, ending the string
3643:
1.464 albertel 3644: if ($width !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3645: $error .= "Invalid width; please type only a number.<br />\n";
3646: }
1.464 albertel 3647: if ($height !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3648: $error .= "Invalid height; please type only a number.<br />\n";
3649: }
1.464 albertel 3650: if ($lmargin !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3651: $error .= "Invalid left margin; please type only a number.<br />\n";
1.470 foxr 3652: } else {
3653: # Adjust for LaTeX 1.0 inch margin:
3654:
3655: if ($env{"form.${var}.lmarginunit"} eq "in") {
3656: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
3657: } else {
3658: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
3659: }
1.144 bowersj2 3660: }
3661:
3662: if (!$error) {
3663: Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
3664: return 1;
3665: } else {
3666: $self->{ERROR_MSG} = $error;
3667: return 0;
3668: }
3669: }
3670:
3671:
1.119 bowersj2 3672:
1.1 www 3673: __END__
1.6 sakharuk 3674:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>