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