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