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