Annotation of loncom/interface/lonprintout.pm, revision 1.557
1.389 foxr 1: # The LearningOnline Network
1.1 www 2: # Printout
3: #
1.557 ! foxr 4: # $Id: lonprintout.pm,v 1.556.2.1 2009/06/23 10:22:38 foxr Exp $
1.11 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: # http://www.lon-capa.org/
26: #
1.3 sakharuk 27: #
1.1 www 28: package Apache::lonprintout;
29:
30: use strict;
1.10 albertel 31: use Apache::Constants qw(:common :http);
1.2 sakharuk 32: use Apache::lonxml;
33: use Apache::lonnet;
1.54 sakharuk 34: use Apache::loncommon;
1.13 sakharuk 35: use Apache::inputtags;
1.54 sakharuk 36: use Apache::grades;
1.13 sakharuk 37: use Apache::edit;
1.5 sakharuk 38: use Apache::File();
1.68 sakharuk 39: use Apache::lonnavmaps;
1.511 foxr 40: use Apache::admannotations;
1.521 foxr 41: use Apache::lonenc;
1.531 foxr 42: use Apache::entities;
1.550 foxr 43: use Apache::londefdef;
44:
45: use File::Basename;
1.531 foxr 46:
1.515 foxr 47: use HTTP::Response;
1.511 foxr 48:
1.491 albertel 49: use LONCAPA::map();
1.34 sakharuk 50: use POSIX qw(strftime);
1.255 www 51: use Apache::lonlocal;
1.429 foxr 52: use Carp;
1.439 www 53: use LONCAPA;
1.60 sakharuk 54:
1.397 albertel 55: my %perm;
1.454 foxr 56: my %parmhash;
1.459 foxr 57: my $resources_printed;
1.454 foxr 58:
1.515 foxr 59: # Global variables that describe errors in ssi calls detected by ssi_with_retries.
60: #
61:
62: my $ssi_error; # True if there was an ssi error.
63: my $ssi_last_error_resource; # The resource URI that could not be fetched.
64: my $ssi_last_error; # The error text from the server. (e.g. 500 Server timed out).
65:
66: #
67: # Our ssi max retry count.
68: #
69:
70: my $ssi_retry_count = 5; # Some arbitrary value.
71:
72:
1.556 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.556 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)$/) {
1.557 ! foxr 1478:
1.459 foxr 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.556 foxr 1522: $font_size = $helper->{'VARS'}->{'fontsize'};
1.499 foxr 1523: my $do_postprocessing = 1;
1.433 albertel 1524: my $js = <<ENDPART;
1525: <script type="text/javascript">
1.264 sakharuk 1526: var editbrowser;
1527: function openbrowser(formname,elementname,only,omit) {
1528: var url = '/res/?';
1529: if (editbrowser == null) {
1530: url += 'launch=1&';
1531: }
1532: url += 'catalogmode=interactive&';
1533: url += 'mode=parmset&';
1534: url += 'form=' + formname + '&';
1535: if (only != null) {
1536: url += 'only=' + only + '&';
1537: }
1538: if (omit != null) {
1539: url += 'omit=' + omit + '&';
1540: }
1541: url += 'element=' + elementname + '';
1542: var title = 'Browser';
1543: var options = 'scrollbars=1,resizable=1,menubar=0';
1544: options += ',width=700,height=600';
1545: editbrowser = open(url,title,options,'1');
1546: editbrowser.focus();
1547: }
1548: </script>
1.140 sakharuk 1549: ENDPART
1550:
1.512 foxr 1551:
1552:
1.433 albertel 1553: my $start_page = &Apache::loncommon::start_page('Preparing Printout',$js);
1554: my $msg = &mt('Please stand by while processing your print request, this may take some time ...');
1.363 foxr 1555:
1.433 albertel 1556: $r->print($start_page."\n<p>\n$msg\n</p>\n");
1.372 foxr 1557:
1.363 foxr 1558: # fetch the pagebreaks and store them in the course environment
1559: # The page breaks will be pulled into the hash %page_breaks which is
1560: # indexed by symb and contains 1's for each break.
1561:
1.373 albertel 1562: $env{'form.pagebreaks'} = $helper->{'VARS'}->{'FINISHPAGE'};
1563: $env{'form.lastprinttype'} = $helper->{'VARS'}->{'PRINT_TYPE'};
1.363 foxr 1564: &Apache::loncommon::store_course_settings('print',
1.366 foxr 1565: {'pagebreaks' => 'scalar',
1566: 'lastprinttype' => 'scalar'});
1.363 foxr 1567:
1.364 albertel 1568: my %page_breaks = &get_page_breaks($helper);
1.363 foxr 1569:
1.140 sakharuk 1570: my $format_from_helper = $helper->{'VARS'}->{'FORMAT'};
1571: my ($result,$selectionmade) = ('','');
1572: my $number_of_columns = 1; #used only for pages to determine the width of the cell
1573: my @temporary_array=split /\|/,$format_from_helper;
1.539 onken 1574: my ($laystyle,$numberofcolumns,$papersize,$pdfFormFields)=@temporary_array;
1.140 sakharuk 1575: if ($laystyle eq 'L') {
1576: $laystyle='album';
1577: } else {
1578: $laystyle='book';
1579: }
1.177 sakharuk 1580: my ($textwidth,$textheight,$oddoffset,$evenoffset) = &page_format($papersize,$laystyle,$numberofcolumns);
1.373 albertel 1581: my $assignment = $env{'form.assignment'};
1.275 sakharuk 1582: my $LaTeXwidth=&recalcto_mm($textwidth);
1.272 sakharuk 1583: my @print_array=();
1.274 sakharuk 1584: my @student_names=();
1.360 albertel 1585:
1.512 foxr 1586:
1.360 albertel 1587: # Common settings for the %form has:
1588: # In some cases these settings get overriddent by specific cases, but the
1589: # settings are common enough to make it worthwhile factoring them out
1590: # here.
1591: #
1592: my %form;
1593: $form{'grade_target'} = 'tex';
1594: $form{'textwidth'} = &get_textwidth($helper, $LaTeXwidth);
1.539 onken 1595: $form{'pdfFormFields'} = $pdfFormFields;
1.372 foxr 1596:
1597: # If form.showallfoils is set, then request all foils be shown:
1598: # privilege will be enforced both by not allowing the
1599: # check box selecting this option to be presnt unless it's ok,
1600: # and by lonresponse's priv. check.
1601: # The if is here because lonresponse.pm only cares that
1602: # showallfoils is defined, not what the value is.
1603:
1604: if ($helper->{'VARS'}->{'showallfoils'} eq "1") {
1605: $form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'};
1606: }
1.504 albertel 1607:
1608: if ($helper->{'VARS'}->{'style_file'}=~/\w/) {
1.520 raeburn 1609: &Apache::lonnet::appenv({'construct.style' =>
1610: $helper->{'VARS'}->{'style_file'}});
1.504 albertel 1611: } elsif ($env{'construct.style'}) {
1.549 raeburn 1612: &Apache::lonnet::delenv('construct.style');
1.504 albertel 1613: }
1614:
1.372 foxr 1615:
1.140 sakharuk 1616: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') {
1.143 sakharuk 1617: #-- single document - problem, page, html, xml, ...
1.343 albertel 1618: my ($currentURL,$cleanURL);
1.375 foxr 1619:
1.162 sakharuk 1620: if ($helper->{'VARS'}->{'construction'} ne '1') {
1.185 sakharuk 1621: #prints published resource
1.153 sakharuk 1622: $currentURL=$helper->{'VARS'}->{'postdata'};
1.343 albertel 1623: $cleanURL=&Apache::lonenc::check_decrypt($currentURL);
1.143 sakharuk 1624: } else {
1.512 foxr 1625:
1.185 sakharuk 1626: #prints resource from the construction space
1.240 albertel 1627: $currentURL='/'.$helper->{'VARS'}->{'filename'};
1.206 sakharuk 1628: if ($currentURL=~/([^?]+)/) {$currentURL=$1;}
1.343 albertel 1629: $cleanURL=$currentURL;
1.143 sakharuk 1630: }
1.140 sakharuk 1631: $selectionmade = 1;
1.413 albertel 1632: if ($cleanURL!~m|^/adm/|
1.557 ! foxr 1633: && $cleanURL=~/\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/) {
1.169 albertel 1634: my $rndseed=time;
1.242 sakharuk 1635: my $texversion='';
1636: if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') {
1637: my %moreenv;
1.343 albertel 1638: $moreenv{'request.filename'}=$cleanURL;
1.290 sakharuk 1639: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {$form{'problemtype'}='exam';}
1.242 sakharuk 1640: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310 sakharuk 1641: $form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.242 sakharuk 1642: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309 sakharuk 1643: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 1644: $form{'print_annotations'}=$helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1645: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
1646: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
1647: $form{'problem_split'}='yes';
1648: }
1.242 sakharuk 1649: if ($helper->{'VARS'}->{'curseed'}) {
1650: $rndseed=$helper->{'VARS'}->{'curseed'};
1651: }
1652: $form{'rndseed'}=$rndseed;
1.520 raeburn 1653: &Apache::lonnet::appenv(\%moreenv);
1.428 albertel 1654:
1655: &Apache::lonxml::clear_problem_counter();
1656:
1.375 foxr 1657: $resources_printed .= $currentURL.':';
1.515 foxr 1658: $texversion.=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.428 albertel 1659:
1.511 foxr 1660: # Add annotations if required:
1661:
1.428 albertel 1662: &Apache::lonxml::clear_problem_counter();
1663:
1.242 sakharuk 1664: &Apache::lonnet::delenv('request.filename');
1.230 albertel 1665: }
1.423 foxr 1666: # current document with answers.. no need to encap in minipage
1667: # since there's only one answer.
1668:
1.242 sakharuk 1669: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1670: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.353 foxr 1671: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.166 albertel 1672: $form{'grade_target'}='answer';
1.167 albertel 1673: $form{'answer_output_mode'}='tex';
1.169 albertel 1674: $form{'rndseed'}=$rndseed;
1.401 albertel 1675: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {
1676: $form{'problemtype'}='exam';
1677: }
1.375 foxr 1678: $resources_printed .= $currentURL.':';
1.515 foxr 1679: my $answer=&ssi_with_retries($currentURL,$ssi_retry_count, %form);
1.511 foxr 1680:
1681:
1.242 sakharuk 1682: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
1683: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1684: } else {
1685: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.245 sakharuk 1686: if ($helper->{'VARS'}->{'construction'} ne '1') {
1.477 albertel 1687: my $title = &Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'});
1688: $title = &Apache::lonxml::latex_special_symbols($title);
1689: $texversion.='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.343 albertel 1690: $texversion.=&path_to_problem($cleanURL,$LaTeXwidth);
1.245 sakharuk 1691: } else {
1692: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
1.343 albertel 1693: my $URLpath=$cleanURL;
1.245 sakharuk 1694: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
1.504 albertel 1695: $texversion.=&path_to_problem($URLpath,$LaTeXwidth);
1.245 sakharuk 1696: }
1.242 sakharuk 1697: $texversion.='\vskip 1 mm '.$answer.'\end{document}';
1698: }
1.511 foxr 1699:
1700:
1701:
1702:
1.550 foxr 1703:
1.511 foxr 1704: }
1705: # Print annotations.
1706:
1707:
1708: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1709: my $annotation .= &annotate($currentURL);
1710: $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
1.163 sakharuk 1711: }
1.511 foxr 1712:
1713:
1.214 sakharuk 1714: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1.215 sakharuk 1715: $texversion=&IndexCreation($texversion,$currentURL);
1.214 sakharuk 1716: }
1.219 sakharuk 1717: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
1718: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$currentURL| \\strut\\\\\\strut /;
1719:
1720: }
1.162 sakharuk 1721: $result .= $texversion;
1722: if ($currentURL=~m/\.page\s*$/) {
1723: ($result,$number_of_columns) = &page_cleanup($result);
1724: }
1.413 albertel 1725: } elsif ($cleanURL!~m|^/adm/|
1.557 ! foxr 1726: && $currentURL=~/\.(sequence|page)$/ && $helper->{'VARS'}->{'construction'} eq '1') {
1.227 sakharuk 1727: #printing content of sequence from the construction space
1728: $currentURL=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;
1.551 foxr 1729: # $result .= &print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.459 foxr 1730: $result .= &print_construction_sequence($currentURL, $helper, %form,
1731: $LaTeXwidth);
1732: $result .= '\end{document}';
1733: if (!($result =~ /\\begin\{document\}/)) {
1734: $result = &print_latex_header() . $result;
1.227 sakharuk 1735: }
1.459 foxr 1736: # End construction space sequence.
1.456 raeburn 1737: } elsif ($cleanURL=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.258 sakharuk 1738: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.298 sakharuk 1739: if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;}
1.375 foxr 1740: $resources_printed .= $currentURL.':';
1.515 foxr 1741: my $texversion=&ssi_with_retries($currentURL, $ssi_retry_count, %form);
1.511 foxr 1742: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1743: my $annotation = &annotate($currentURL);
1744: $texversion =~ s/(\\end{document})/$annotation$1/;
1745: }
1.258 sakharuk 1746: $result .= $texversion;
1.550 foxr 1747: } elsif ($cleanURL =~/\.tex$/) {
1.498 foxr 1748: # For this sort of print of a single LaTeX file,
1749: # We can just print the LaTeX file as it is uninterpreted in any way:
1750: #
1751:
1752: $result = &fetch_raw_resource($currentURL);
1.511 foxr 1753: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1754: my $annotation = &annotate($currentURL);
1755: $result =~ s/(\\end{document})/$annotation$1/;
1756: }
1757:
1.499 foxr 1758: $do_postprocessing = 0; # Don't massage the result.
1.498 foxr 1759:
1.550 foxr 1760: } elsif ($cleanURL =~ /\.pdf$/i) {
1761: $result .= &include_pdf($cleanURL);
1.551 foxr 1762: $result .= '\end{document}';
1.162 sakharuk 1763: } else {
1.414 albertel 1764: $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'},
1765: $helper->{'VARS'}->{'symb'});
1.162 sakharuk 1766: }
1.354 foxr 1767: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') or
1.142 sakharuk 1768: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or
1.354 foxr 1769: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') or
1770: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') or # BUGBUG
1.536 foxr 1771: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences')
1772: ) {
1.511 foxr 1773:
1774:
1.141 sakharuk 1775: #-- produce an output string
1.296 sakharuk 1776: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') {
1777: $selectionmade = 2;
1778: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') {
1779: $selectionmade = 3;
1.536 foxr 1780: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems')
1781: ) {
1.296 sakharuk 1782: $selectionmade = 4;
1.354 foxr 1783: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') { #BUGBUG
1784: $selectionmade = 4;
1.296 sakharuk 1785: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') {
1786: $selectionmade = 7;
1787: }
1.193 sakharuk 1788: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310 sakharuk 1789: $form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.203 sakharuk 1790: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309 sakharuk 1791: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 1792: $form{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1793: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
1794: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') ) {
1795: $form{'problem_split'}='yes';
1796: }
1.141 sakharuk 1797: my $flag_latex_header_remove = 'NO';
1798: my $flag_page_in_sequence = 'NO';
1799: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.193 sakharuk 1800: my $prevassignment='';
1.428 albertel 1801:
1802: &Apache::lonxml::clear_problem_counter();
1803:
1.416 foxr 1804: my $pbreakresources = keys %page_breaks;
1.141 sakharuk 1805: for (my $i=0;$i<=$#master_seq;$i++) {
1.350 foxr 1806:
1.521 foxr 1807: &Apache::lonenc::reset_enc();
1808:
1809:
1.350 foxr 1810: # Note due to document structure, not allowed to put \newpage
1811: # prior to the first resource
1812:
1.351 foxr 1813: if (defined $page_breaks{$master_seq[$i]}) {
1.350 foxr 1814: if($i != 0) {
1815: $result.="\\newpage\n";
1816: }
1817: }
1.521 foxr 1818: my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]);
1.237 albertel 1819: $urlp=&Apache::lonnet::clutter($urlp);
1.166 albertel 1820: $form{'symb'}=$master_seq[$i];
1.407 albertel 1821:
1.521 foxr 1822:
1.407 albertel 1823: my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem
1.521 foxr 1824:
1.267 sakharuk 1825: if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;}
1.247 sakharuk 1826: if ($i==0) {$prevassignment=$assignment;}
1.297 sakharuk 1827: my $texversion='';
1.413 albertel 1828: if ($urlp!~m|^/adm/|
1829: && $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 1830: $resources_printed .= $urlp.':';
1.428 albertel 1831: &Apache::lonxml::remember_problem_counter();
1.515 foxr 1832: $texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.296 sakharuk 1833: if ($urlp=~/\.page$/) {
1834: ($texversion,my $number_of_columns_page) = &page_cleanup($texversion);
1835: if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;}
1836: $texversion =~ s/\\end{document}\d*/\\end{document}/;
1837: $flag_page_in_sequence = 'YES';
1838: }
1.428 albertel 1839:
1.296 sakharuk 1840: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1841: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 1842: # Don't permanently pervert the %form hash
1843: my %answerform = %form;
1844: $answerform{'grade_target'}='answer';
1845: $answerform{'answer_output_mode'}='tex';
1.375 foxr 1846: $resources_printed .= $urlp.':';
1.428 albertel 1847:
1848: &Apache::lonxml::restore_problem_counter();
1.515 foxr 1849: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.428 albertel 1850:
1.296 sakharuk 1851: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
1852: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1.249 sakharuk 1853: } else {
1.307 sakharuk 1854: if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) {
1.296 sakharuk 1855: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.552 foxr 1856: $texversion =~ s/\\begin{document}//;
1.477 albertel 1857: my $title = &Apache::lonnet::gettitle($master_seq[$i]);
1858: $title = &Apache::lonxml::latex_special_symbols($title);
1859: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.423 foxr 1860: $body .= &path_to_problem ($urlp,$LaTeXwidth);
1861: $body .='\vskip 1 mm '.$answer;
1862: $body = &encapsulate_minipage($body);
1863: $texversion .= $body;
1.296 sakharuk 1864: } else {
1865: $texversion='';
1866: }
1.249 sakharuk 1867: }
1.511 foxr 1868:
1.246 sakharuk 1869: }
1.511 foxr 1870: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1871: my $annotation .= &annotate($urlp);
1872: $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
1873: }
1874:
1.296 sakharuk 1875: if ($flag_latex_header_remove ne 'NO') {
1876: $texversion = &latex_header_footer_remove($texversion);
1877: } else {
1878: $texversion =~ s/\\end{document}//;
1879: }
1880: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
1881: $texversion=&IndexCreation($texversion,$urlp);
1882: }
1883: if (($selectionmade == 4) and ($assignment ne $prevassignment)) {
1884: my $name = &get_name();
1885: my $courseidinfo = &get_course();
1886: $prevassignment=$assignment;
1.455 albertel 1887: my $header_text = $parmhash{'print_header_format'};
1.486 foxr 1888: $header_text = &format_page_header($textwidth, $header_text,
1.455 albertel 1889: $assignment,
1890: $courseidinfo,
1891: $name);
1.552 foxr 1892:
1.417 foxr 1893: if ($numberofcolumns eq '1') {
1.455 albertel 1894: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{'.$header_text.'}} \vskip 5 mm ';
1.416 foxr 1895: } else {
1.455 albertel 1896: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\fancyhead[LO]{'.$header_text.'}} \vskip 5 mm ';
1.416 foxr 1897: }
1.296 sakharuk 1898: }
1899: $result .= $texversion;
1900: $flag_latex_header_remove = 'YES';
1.456 raeburn 1901: } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.301 sakharuk 1902: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1903: if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;}
1.375 foxr 1904: $resources_printed .= $urlp.':';
1.515 foxr 1905: my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.511 foxr 1906: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
1907: my $annotation = &annotate($urlp);
1908: $texversion =~ s/(\\end{document)/$annotation$1/;
1909: }
1910:
1.301 sakharuk 1911: if ($flag_latex_header_remove ne 'NO') {
1912: $texversion = &latex_header_footer_remove($texversion);
1.550 foxr 1913: } else {
1.301 sakharuk 1914: $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/;
1915: }
1916: $result .= $texversion;
1917: $flag_latex_header_remove = 'YES';
1.550 foxr 1918: } elsif ($urlp=~ /\.pdf$/i) {
1919: if ($i > 0) {
1920: $result .= '\cleardoublepage';
1921: }
1922: $result .= &include_pdf($urlp);
1923: if ($i != $#master_seq) {
1924: if ($numberofcolumns eq '1') {
1925: $result .= '\newpage';
1926: } else {
1927: # the \\'s seem to be needed to let LaTeX know there's something
1928: # on the page since LaTeX seems to not like to clear an empty page.
1929: #
1930: $result .= '\\ \cleardoublepage';
1931: }
1932: }
1933: $flag_latex_header_remove = 'YES';
1934:
1.141 sakharuk 1935: } else {
1.414 albertel 1936: $texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'},
1937: $master_seq[$i]);
1.297 sakharuk 1938: if ($flag_latex_header_remove ne 'NO') {
1939: $texversion = &latex_header_footer_remove($texversion);
1940: } else {
1941: $texversion =~ s/\\end{document}//;
1942: }
1943: $result .= $texversion;
1944: $flag_latex_header_remove = 'YES';
1.296 sakharuk 1945: }
1.550 foxr 1946: if (&Apache::loncommon::connection_aborted($r)) {
1947: last;
1948: }
1.141 sakharuk 1949: }
1.428 albertel 1950: &Apache::lonxml::clear_problem_counter();
1.344 foxr 1951: if ($flag_page_in_sequence eq 'YES') {
1952: $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;
1953: }
1.141 sakharuk 1954: $result .= '\end{document}';
1.284 albertel 1955: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1.536 foxr 1956: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ||
1.284 albertel 1957: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){
1.353 foxr 1958:
1959:
1.150 sakharuk 1960: #-- prints assignments for whole class or for selected students
1.284 albertel 1961: my $type;
1.536 foxr 1962: if (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1963: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ) {
1.254 sakharuk 1964: $selectionmade=5;
1.284 albertel 1965: $type='problems';
1.254 sakharuk 1966: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') {
1967: $selectionmade=8;
1.284 albertel 1968: $type='resources';
1.254 sakharuk 1969: }
1.150 sakharuk 1970: my @students=split /\|\|\|/, $helper->{'VARS'}->{'STUDENTS'};
1.341 foxr 1971: # The normal sort order is by section then by students within the
1972: # section. If the helper var student_sort is 1, then the user has elected
1973: # to override this and output the students by name.
1974: # Each element of the students array is of the form:
1975: # username:domain:section:last, first:status
1976: #
1.429 foxr 1977: # Note that student sort is not compatible with printing
1978: # 1 section per pdf...so that setting overrides.
1.341 foxr 1979: #
1.429 foxr 1980: if (($helper->{'VARS'}->{'student_sort'} eq 1) &&
1981: ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) {
1.341 foxr 1982: @students = sort compare_names @students;
1983: }
1.429 foxr 1984: &adjust_number_to_print($helper);
1985:
1.278 albertel 1986: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq '0' ||
1987: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'all' ) {
1988: $helper->{'VARS'}->{'NUMBER_TO_PRINT'}=$#students+1;
1989: }
1.429 foxr 1990: # If we are splitting on section boundaries, we need
1991: # to remember that in split_on_sections and
1992: # print all of the students in the list.
1993: #
1994: my $split_on_sections = 0;
1995: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'section') {
1996: $split_on_sections = 1;
1997: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1;
1998: }
1.150 sakharuk 1999: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.350 foxr 2000:
1.150 sakharuk 2001: #loop over students
1.552 foxr 2002: my $flag_latex_header_remove = 'NO';
1.150 sakharuk 2003: my %moreenv;
1.330 sakharuk 2004: $moreenv{'instructor_comments'}='hide';
1.285 albertel 2005: $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth);
1.309 sakharuk 2006: $moreenv{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 2007: $moreenv{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1.353 foxr 2008: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'};
1.369 foxr 2009: $moreenv{'suppress_tries'} = $parmhash{'suppress_tries'};
1.511 foxr 2010: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
2011: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
2012: $moreenv{'problem_split'}='yes';
2013: }
1.318 albertel 2014: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75');
1.272 sakharuk 2015: my $student_counter=-1;
1.429 foxr 2016: my $i = 0;
1.430 albertel 2017: my $last_section = (split(/:/,$students[0]))[2];
1.150 sakharuk 2018: foreach my $person (@students) {
1.350 foxr 2019:
1.373 albertel 2020: my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";
1.311 sakharuk 2021: if (-e $duefile) {
2022: my $temp_file = Apache::File->new('>>'.$duefile);
2023: print $temp_file "1969\n";
2024: }
1.272 sakharuk 2025: $student_counter++;
1.429 foxr 2026: if ($split_on_sections) {
1.430 albertel 2027: my $this_section = (split(/:/,$person))[2];
1.429 foxr 2028: if ($this_section ne $last_section) {
2029: $i++;
2030: $last_section = $this_section;
2031: }
2032: } else {
2033: $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'});
2034: }
1.375 foxr 2035: my ($output,$fullname, $printed)=&print_resources($r,$helper,
1.353 foxr 2036: $person,$type,
2037: \%moreenv,\@master_seq,
1.360 albertel 2038: $flag_latex_header_remove,
1.422 albertel 2039: $LaTeXwidth);
1.375 foxr 2040: $resources_printed .= ":";
1.284 albertel 2041: $print_array[$i].=$output;
2042: $student_names[$i].=$person.':'.$fullname.'_END_';
2043: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname);
2044: $flag_latex_header_remove = 'YES';
1.331 albertel 2045: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 2046: }
2047: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
2048: $result .= $print_array[0].' \end{document}';
2049: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon') ||
2050: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon') ) {
1.373 albertel 2051: my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
2052: my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
1.288 albertel 2053: my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'};
2054: my $code_name=$helper->{'VARS'}->{'ANON_CODE_STORAGE_NAME'};
1.292 albertel 2055: my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'};
1.385 foxr 2056: my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'};
1.388 foxr 2057: my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'};
2058:
1.381 albertel 2059: my $code_option=$helper->{'VARS'}->{'CODE_OPTION'};
1.542 raeburn 2060: my @lines = &Apache::grades::get_scantronformat_file();
1.381 albertel 2061: my ($code_type,$code_length)=('letter',6);
1.542 raeburn 2062: foreach my $line (@lines) {
1.381 albertel 2063: my ($name,$type,$length) = (split(/:/,$line))[0,2,4];
2064: if ($name eq $code_option) {
2065: $code_length=$length;
2066: if ($type eq 'number') { $code_type = 'number'; }
2067: }
2068: }
1.288 albertel 2069: my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth));
1.353 foxr 2070: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'};
1.420 albertel 2071: $moreenv{'instructor_comments'}='hide';
1.288 albertel 2072: my $seed=time+($$<<16)+($$);
1.292 albertel 2073: my @allcodes;
2074: if ($old_name) {
1.381 albertel 2075: my %result=&Apache::lonnet::get('CODEs',
2076: [$old_name,"type\0$old_name"],
2077: $cdom,$cnum);
2078: $code_type=$result{"type\0$old_name"};
1.292 albertel 2079: @allcodes=split(',',$result{$old_name});
1.336 albertel 2080: $num_todo=scalar(@allcodes);
1.389 foxr 2081: } elsif ($selected_code) { # Selection value is always numeric.
1.388 foxr 2082: $num_todo = 1;
2083: @allcodes = ($selected_code);
1.385 foxr 2084: } elsif ($single_code) {
2085:
1.387 foxr 2086: $num_todo = 1; # Unconditionally one code to do.
1.385 foxr 2087: # If an alpha code have to convert to numbers so it can be
2088: # converted back to letters again :-)
2089: #
2090: if ($code_type ne 'number') {
2091: $single_code = &letters_to_num($single_code);
2092: }
2093: @allcodes = ($single_code);
1.292 albertel 2094: } else {
2095: my %allcodes;
1.299 albertel 2096: srand($seed);
1.292 albertel 2097: for (my $i=0;$i<$num_todo;$i++) {
1.381 albertel 2098: $moreenv{'CODE'}=&get_CODE(\%allcodes,$i,$seed,$code_length,
2099: $code_type);
1.292 albertel 2100: }
2101: if ($code_name) {
2102: &Apache::lonnet::put('CODEs',
1.381 albertel 2103: {
2104: $code_name =>join(',',keys(%allcodes)),
2105: "type\0$code_name" => $code_type
2106: },
1.292 albertel 2107: $cdom,$cnum);
2108: }
2109: @allcodes=keys(%allcodes);
2110: }
1.336 albertel 2111: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
2112: my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'});
1.452 albertel 2113: &adjust_number_to_print($helper);
1.336 albertel 2114: my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'};
2115: if ($number_per_page eq '0' || $number_per_page eq 'all') {
2116: $number_per_page=$num_todo;
2117: }
2118: my $flag_latex_header_remove = 'NO';
2119: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75');
1.295 albertel 2120: my $count=0;
1.292 albertel 2121: foreach my $code (sort(@allcodes)) {
1.295 albertel 2122: my $file_num=int($count/$number_per_page);
1.381 albertel 2123: if ($code_type eq 'number') {
2124: $moreenv{'CODE'}=$code;
2125: } else {
2126: $moreenv{'CODE'}=&num_to_letters($code);
2127: }
1.375 foxr 2128: my ($output,$fullname, $printed)=
1.288 albertel 2129: &print_resources($r,$helper,'anonymous',$type,\%moreenv,
1.360 albertel 2130: \@master_seq,$flag_latex_header_remove,
2131: $LaTeXwidth);
1.375 foxr 2132: $resources_printed .= ":";
1.295 albertel 2133: $print_array[$file_num].=$output;
1.288 albertel 2134: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
2135: &mt('last assignment').' '.$fullname);
2136: $flag_latex_header_remove = 'YES';
1.295 albertel 2137: $count++;
1.331 albertel 2138: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.288 albertel 2139: }
2140: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
2141: $result .= $print_array[0].' \end{document}';
2142: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') {
1.151 sakharuk 2143: #prints selected problems from the subdirectory
2144: $selectionmade = 6;
2145: my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};
1.154 sakharuk 2146: @list_of_files=sort @list_of_files;
1.175 sakharuk 2147: my $flag_latex_header_remove = 'NO';
2148: my $rndseed=time;
1.230 albertel 2149: if ($helper->{'VARS'}->{'curseed'}) {
2150: $rndseed=$helper->{'VARS'}->{'curseed'};
2151: }
1.151 sakharuk 2152: for (my $i=0;$i<=$#list_of_files;$i++) {
1.521 foxr 2153:
2154: &Apache::lonenc::reset_enc();
2155:
1.152 sakharuk 2156: my $urlp = $list_of_files[$i];
1.253 sakharuk 2157: $urlp=~s|//|/|;
1.152 sakharuk 2158: if ($urlp=~/\//) {
1.353 foxr 2159: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.175 sakharuk 2160: $form{'rndseed'}=$rndseed;
1.152 sakharuk 2161: if ($urlp =~ m|/home/([^/]+)/public_html|) {
2162: $urlp =~ s|/home/([^/]*)/public_html|/~$1|;
2163: } else {
1.302 sakharuk 2164: $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;
1.152 sakharuk 2165: }
1.375 foxr 2166: $resources_printed .= $urlp.':';
1.515 foxr 2167: my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.251 sakharuk 2168: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1.253 sakharuk 2169: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2170: # Don't permanently pervert %form:
2171: my %answerform = %form;
2172: $answerform{'grade_target'}='answer';
2173: $answerform{'answer_output_mode'}='tex';
2174: $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
2175: $answerform{'rndseed'}=$rndseed;
1.375 foxr 2176: $resources_printed .= $urlp.':';
1.515 foxr 2177: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.251 sakharuk 2178: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2179: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
2180: } else {
1.253 sakharuk 2181: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
2182: if ($helper->{'VARS'}->{'construction'} ne '1') {
2183: $texversion.='\vskip 0 mm \noindent ';
2184: $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
2185: } else {
2186: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
2187: my $URLpath=$urlp;
2188: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
2189: $texversion.=&path_to_problem ($URLpath,$LaTeXwidth);
2190: }
2191: $texversion.='\vskip 1 mm '.$answer.'\end{document}';
1.251 sakharuk 2192: }
1.174 sakharuk 2193: }
1.515 foxr 2194: #this chunk is responsible for printing the path to problem
2195:
1.253 sakharuk 2196: my $newurlp=$urlp;
2197: if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;}
2198: $newurlp=&path_to_problem($newurlp,$LaTeXwidth);
1.242 sakharuk 2199: $texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;
1.152 sakharuk 2200: if ($flag_latex_header_remove ne 'NO') {
2201: $texversion = &latex_header_footer_remove($texversion);
2202: } else {
2203: $texversion =~ s/\\end{document}//;
1.216 sakharuk 2204: }
2205: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
2206: $texversion=&IndexCreation($texversion,$urlp);
1.152 sakharuk 2207: }
1.219 sakharuk 2208: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
2209: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
2210:
2211: }
1.152 sakharuk 2212: $result .= $texversion;
2213: }
2214: $flag_latex_header_remove = 'YES';
1.151 sakharuk 2215: }
1.175 sakharuk 2216: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;}
1.152 sakharuk 2217: $result .= '\end{document}';
1.140 sakharuk 2218: }
2219: #-------------------------------------------------------- corrections for the different page formats
1.499 foxr 2220:
2221: # Only post process if that has not been turned off e.g. by a raw latex resource.
2222:
2223: if ($do_postprocessing) {
2224: $result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade);
2225: $result = &latex_corrections($number_of_columns,$result,$selectionmade,
2226: $helper->{'VARS'}->{'ANSWER_TYPE'});
2227: #if ($numberofcolumns == 1) {
1.451 albertel 2228: $result =~ s/\\textwidth\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /;
2229: $result =~ s/\\textheight\s*=?\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /;
2230: $result =~ s/\\evensidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
2231: $result =~ s/\\oddsidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
1.499 foxr 2232: #}
2233: }
1.367 foxr 2234:
1.515 foxr 2235: # Set URLback if this is a construction space print so we can provide
2236: # a link to the resource being edited.
2237: #
1.274 sakharuk 2238:
1.276 sakharuk 2239: my $URLback=''; #link to original document
1.510 albertel 2240: if ($helper->{'VARS'}->{'construction'} eq '1') {
1.276 sakharuk 2241: #prints resource from the construction space
2242: $URLback='/'.$helper->{'VARS'}->{'filename'};
1.279 albertel 2243: if ($URLback=~/([^?]+)/) {
2244: $URLback=$1;
2245: $URLback=~s|^/~|/priv/|;
2246: }
1.276 sakharuk 2247: }
1.556 foxr 2248: #
2249: # Final adjustment of the font size:
2250: #
2251:
2252: $result = set_font_size($result);
1.375 foxr 2253:
1.525 www 2254: #-- writing .tex file in prtspool
2255: my $temp_file;
2256: my $identifier = &Apache::loncommon::get_cgi_id();
2257: my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex";
2258: if (!($#print_array>0)) {
2259: unless ($temp_file = Apache::File->new('>'.$filename)) {
2260: $r->log_error("Couldn't open $filename for output $!");
2261: return SERVER_ERROR;
2262: }
2263: print $temp_file $result;
2264: my $begin=index($result,'\begin{document}',0);
2265: my $inc=substr($result,0,$begin+16);
1.515 foxr 2266: } else {
1.525 www 2267: my $begin=index($result,'\begin{document}',0);
2268: my $inc=substr($result,0,$begin+16);
2269: for (my $i=0;$i<=$#print_array;$i++) {
2270: if ($i==0) {
2271: $print_array[$i]=$result;
2272: } else {
2273: $print_array[$i].='\end{document}';
2274: $print_array[$i] =
2275: &latex_corrections($number_of_columns,$print_array[$i],
2276: $selectionmade,
2277: $helper->{'VARS'}->{'ANSWER_TYPE'});
1.515 foxr 2278:
1.525 www 2279: my $anobegin=index($print_array[$i],'\setcounter{page}',0);
2280: substr($print_array[$i],0,$anobegin)='';
2281: $print_array[$i]=$inc.$print_array[$i];
2282: }
2283: my $temp_file;
2284: my $newfilename=$filename;
2285: my $num=$i+1;
2286: $newfilename =~s/\.tex$//;
2287: $newfilename=sprintf("%s_%03d.tex",$newfilename, $num);
2288: unless ($temp_file = Apache::File->new('>'.$newfilename)) {
2289: $r->log_error("Couldn't open $newfilename for output $!");
2290: return SERVER_ERROR;
2291: }
2292: print $temp_file $print_array[$i];
2293: }
2294: }
2295: my $student_names='';
2296: if ($#print_array>0) {
2297: for (my $i=0;$i<=$#print_array;$i++) {
2298: $student_names.=$student_names[$i].'_ENDPERSON_';
1.515 foxr 2299: }
1.525 www 2300: } else {
2301: if ($#student_names>-1) {
2302: $student_names=$student_names[0].'_ENDPERSON_';
1.515 foxr 2303: } else {
1.525 www 2304: my $fullname = &get_name($env{'user.name'},$env{'user.domain'});
2305: $student_names=join(':',$env{'user.name'},$env{'user.domain'},
1.515 foxr 2306: $env{'request.course.sec'},$fullname).
2307: '_ENDPERSON_'.'_END_';
2308: }
1.525 www 2309: }
1.515 foxr 2310:
1.525 www 2311: # logic for now is too complex to trace if this has been defined
2312: # yet.
2313: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
2314: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2315: &Apache::lonnet::appenv({'cgi.'.$identifier.'.file' => $filename,
1.515 foxr 2316: 'cgi.'.$identifier.'.layout' => $laystyle,
2317: 'cgi.'.$identifier.'.numcol' => $numberofcolumns,
2318: 'cgi.'.$identifier.'.paper' => $papersize,
2319: 'cgi.'.$identifier.'.selection' => $selectionmade,
2320: 'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
2321: 'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
2322: 'cgi.'.$identifier.'.role' => $perm{'pav'},
2323: 'cgi.'.$identifier.'.numberoffiles' => $#print_array,
2324: 'cgi.'.$identifier.'.studentnames' => $student_names,
1.520 raeburn 2325: 'cgi.'.$identifier.'.backref' => $URLback,});
1.525 www 2326: &Apache::lonnet::appenv({"cgi.$identifier.user" => $env{'user.name'},
1.515 foxr 2327: "cgi.$identifier.domain" => $env{'user.domain'},
2328: "cgi.$identifier.courseid" => $cnum,
2329: "cgi.$identifier.coursedom" => $cdom,
1.520 raeburn 2330: "cgi.$identifier.resources" => $resources_printed});
1.515 foxr 2331:
1.525 www 2332: my $end_page = &Apache::loncommon::end_page();
1.529 raeburn 2333: my $continue_text = &mt('Continue');
1.525 www 2334: # If there's been an unrecoverable SSI error, report it to the user
2335: if ($ssi_error) {
2336: my $helpurl = &Apache::loncommon::top_nav_help('Helpdesk');
1.554 bisitz 2337: $r->print('<br /><p class="LC_error">'.&mt('An unrecoverable network error occurred:').'</p><p>'.
1.526 www 2338: &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:').
2339: '<br />'.$ssi_last_error_resource.'<br />'.$ssi_last_error.
2340: '</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 2341: &mt('You may be able to reprint the individual resources for which this error occurred, as the issue may be temporary.').
1.525 www 2342: '<br />'.&mt('If the error persists, please contact the [_1] for assistance.',$helpurl).'</p><p>'.
2343: &mt('We apologize for the inconvenience.').'</p>'.
1.528 raeburn 2344: '<a href="/cgi-bin/printout.pl?'.$identifier.'">'.$continue_text.'</a>'.$end_page);
1.525 www 2345: } else {
1.515 foxr 2346: $r->print(<<FINALEND);
1.317 albertel 2347: <br />
1.288 albertel 2348: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.528 raeburn 2349: <a href="/cgi-bin/printout.pl?$identifier">$continue_text</a>
1.431 albertel 2350: $end_page
1.140 sakharuk 2351: FINALEND
1.528 raeburn 2352: } # endif ssi errors.
1.140 sakharuk 2353: }
2354:
1.288 albertel 2355:
2356: sub get_CODE {
1.381 albertel 2357: my ($all_codes,$num,$seed,$size,$type)=@_;
1.288 albertel 2358: my $max='1'.'0'x$size;
2359: my $newcode;
2360: while(1) {
1.392 albertel 2361: $newcode=sprintf("%0".$size."d",int(rand($max)));
1.288 albertel 2362: if (!exists($$all_codes{$newcode})) {
2363: $$all_codes{$newcode}=1;
1.381 albertel 2364: if ($type eq 'number' ) {
2365: return $newcode;
2366: } else {
2367: return &num_to_letters($newcode);
2368: }
1.288 albertel 2369: }
2370: }
2371: }
1.140 sakharuk 2372:
1.284 albertel 2373: sub print_resources {
1.360 albertel 2374: my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422 albertel 2375: $LaTeXwidth)=@_;
1.284 albertel 2376: my $current_output = '';
1.375 foxr 2377: my $printed = '';
1.284 albertel 2378: my ($username,$userdomain,$usersection) = split /:/,$person;
2379: my $fullname = &get_name($username,$userdomain);
1.492 foxr 2380: my $namepostfix = "\\\\"; # Both anon and not anon should get the same vspace.
1.288 albertel 2381: if ($person =~ 'anon') {
1.492 foxr 2382: $namepostfix .="Name: ";
1.288 albertel 2383: $fullname = "CODE - ".$moreenv->{'CODE'};
2384: }
1.444 foxr 2385: # Fullname may have special latex characters that need \ prefixing:
2386: #
2387:
1.350 foxr 2388: my $i = 0;
1.284 albertel 2389: #goes through all resources, checks if they are available for
2390: #current student, and produces output
1.428 albertel 2391:
2392: &Apache::lonxml::clear_problem_counter();
1.364 albertel 2393: my %page_breaks = &get_page_breaks($helper);
1.476 albertel 2394: my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440 foxr 2395: #
1.441 foxr 2396: # end each student with a
1.440 foxr 2397: # Special that allows the post processor to even out the page
2398: # counts later. Nasty problem this... it would be really
2399: # nice to put the special in as a postscript comment
1.441 foxr 2400: # e.g. \special{ps:\ENDOFSTUDENTSTAMP} unfortunately,
1.440 foxr 2401: # The special gets passed the \ and dvips puts it in the output file
1.441 foxr 2402: # so we will just rely on prntout.pl to strip ENDOFSTUDENTSTAMP from the
2403: # postscript. Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440 foxr 2404: #
1.363 foxr 2405:
1.511 foxr 2406:
1.284 albertel 2407: foreach my $curresline (@{$master_seq}) {
1.351 foxr 2408: if (defined $page_breaks{$curresline}) {
1.350 foxr 2409: if($i != 0) {
2410: $current_output.= "\\newpage\n";
2411: }
2412: }
2413: $i++;
1.511 foxr 2414:
1.284 albertel 2415: if ( !($type eq 'problems' &&
2416: ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
2417: my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
2418: if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414 albertel 2419: if ($res_url!~m|^ext/|
1.413 albertel 2420: && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 2421: $printed .= $curresline.':';
1.428 albertel 2422:
2423: &Apache::lonxml::remember_problem_counter();
2424:
1.526 www 2425: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.428 albertel 2426:
1.305 sakharuk 2427: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
2428: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2429: # Use a copy of the hash so we don't pervert it on future loop passes.
2430: my %answerenv = %{$moreenv};
2431: $answerenv{'answer_output_mode'}='tex';
2432: $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428 albertel 2433:
2434: &Apache::lonxml::restore_problem_counter();
2435:
1.380 foxr 2436: my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428 albertel 2437:
1.305 sakharuk 2438: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2439: $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
2440: } else {
1.423 foxr 2441:
2442:
2443: my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.552 foxr 2444: $header =~ s/\\begin{document}//; #<<<<<
1.477 albertel 2445: my $title = &Apache::lonnet::gettitle($curresline);
2446: $title = &Apache::lonxml::latex_special_symbols($title);
2447: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
2448: $body .=&path_to_problem($res_url,$LaTeXwidth);
1.423 foxr 2449: $body .='\vskip 1 mm '.$ansrendered;
2450: $body = &encapsulate_minipage($body);
2451: $rendered = $header.$body;
1.305 sakharuk 2452: }
2453: }
1.511 foxr 2454:
2455: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2456: my $url = &Apache::lonnet::clutter($res_url);
2457: my $annotation = &annotate($url);
2458: $rendered =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
2459: }
1.305 sakharuk 2460: if ($remove_latex_header eq 'YES') {
2461: $rendered = &latex_header_footer_remove($rendered);
2462: } else {
2463: $rendered =~ s/\\end{document}//;
2464: }
2465: $current_output .= $rendered;
1.456 raeburn 2466: } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.375 foxr 2467: $printed .= $curresline.':';
1.528 raeburn 2468: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.511 foxr 2469: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2470: my $url = &Apache::lonnet::clutter($res_url);
2471: my $annotation = &annotate($url);
2472: $annotation =~ s/(\\end{document})/$annotation$1/;
2473: }
1.305 sakharuk 2474: if ($remove_latex_header eq 'YES') {
2475: $rendered = &latex_header_footer_remove($rendered);
1.284 albertel 2476: } else {
1.305 sakharuk 2477: $rendered =~ s/\\end{document}//;
1.284 albertel 2478: }
1.421 foxr 2479: $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
1.552 foxr 2480: } elsif($res_url = ~/\.pdf$/) {
2481: my $url = &Apache::lonnet::clutter($res_url);
2482: my $rendered = &include_pdf($url);
2483: if ($remove_latex_header ne 'NO') {
2484: $rendered = &latex_header_footer_remove($rendered);
2485: }
2486: $current_output .= $rendered;
1.284 albertel 2487: } else {
1.414 albertel 2488: my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305 sakharuk 2489: if ($remove_latex_header ne 'NO') {
2490: $rendered = &latex_header_footer_remove($rendered);
2491: } else {
2492: $rendered =~ s/\\end{document}//;
2493: }
2494: $current_output .= $rendered;
1.284 albertel 2495: }
2496: }
2497: $remove_latex_header = 'YES';
1.550 foxr 2498: }
1.331 albertel 2499: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 2500: }
1.552 foxr 2501:
2502:
1.284 albertel 2503: my $courseidinfo = &get_course();
2504: my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476 albertel 2505: my $header_line =
1.486 foxr 2506: &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.537 foxr 2507: $currentassignment, $courseidinfo, $fullname, $usersection);
1.476 albertel 2508: my $header_start = ($columns_in_format == 1) ? '\lhead'
2509: : '\fancyhead[LO]';
2510: $header_line = $header_start.'{'.$header_line.'}';
1.284 albertel 2511: if ($current_output=~/\\documentclass/) {
1.476 albertel 2512: $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.284 albertel 2513: } else {
1.476 albertel 2514: my $blankpages =
2515: '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
2516:
2517: $current_output = '\strut\vspace*{-6 mm}\\newline'.
2518: ©right_line().' \newpage '.$blankpages.$end_of_student.
2519: '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
2520: $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284 albertel 2521: }
1.440 foxr 2522: #
2523: # Close the student bracketing.
2524: #
1.375 foxr 2525: return ($current_output,$fullname, $printed);
1.284 albertel 2526:
2527: }
1.140 sakharuk 2528:
1.3 sakharuk 2529: sub handler {
2530:
2531: my $r = shift;
1.397 albertel 2532:
2533: &init_perm();
1.114 bowersj2 2534:
1.416 foxr 2535:
1.67 www 2536:
1.397 albertel 2537: my $helper = printHelper($r);
2538: if (!ref($helper)) {
2539: return $helper;
1.60 sakharuk 2540: }
1.177 sakharuk 2541:
1.184 sakharuk 2542:
1.454 foxr 2543: %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353 foxr 2544:
1.416 foxr 2545:
1.350 foxr 2546:
2547:
1.367 foxr 2548: # If a figure conversion queue file exists for this user.domain
2549: # we delete it since it can only be bad (if it were good, printout.pl
2550: # would have deleted it the last time around.
2551:
1.373 albertel 2552: my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367 foxr 2553: if(-e $conversion_queuefile) {
2554: unlink $conversion_queuefile;
2555: }
1.515 foxr 2556:
2557:
1.184 sakharuk 2558: &output_data($r,$helper,\%parmhash);
1.2 sakharuk 2559: return OK;
1.60 sakharuk 2560: }
1.2 sakharuk 2561:
1.131 bowersj2 2562: use Apache::lonhelper;
1.130 sakharuk 2563:
1.223 bowersj2 2564: sub addMessage {
2565: my $text = shift;
2566: my $paramHash = Apache::lonhelper::getParamHash();
2567: $paramHash->{MESSAGE_TEXT} = $text;
2568: Apache::lonhelper::message->new();
2569: }
2570:
1.416 foxr 2571:
1.238 bowersj2 2572:
1.397 albertel 2573: sub init_perm {
2574: undef(%perm);
2575: $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
2576: if (!$perm{'pav'}) {
2577: $perm{'pav'}=&Apache::lonnet::allowed('pav',
2578: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2579: }
1.465 albertel 2580: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397 albertel 2581: if (!$perm{'pfo'}) {
2582: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',
2583: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2584: }
2585: }
2586:
1.507 albertel 2587: sub get_randomly_ordered_warning {
2588: my ($helper,$map) = @_;
2589:
2590: my $message;
2591:
2592: my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
2593: my $navmap = Apache::lonnavmaps::navmap->new();
1.547 raeburn 2594: if (defined($navmap)) {
2595: my $res = $navmap->getResourceByUrl($map);
2596: if ($res) {
2597: my $func =
2598: sub { return ($_[0]->is_map() && $_[0]->randomorder); };
2599: my @matches = $navmap->retrieveResources($res, $func,1,1,1);
2600: if (@matches) {
2601: $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.";
2602: }
2603: }
2604: if ($message) {
2605: return '<message type="warning">'.$message.'</message>';
2606: }
2607: } else {
2608: $message = "Retrieval of information about ordering of resources failed.";
2609: return '<message type="warning">'.$message.'</message>';
1.507 albertel 2610: }
2611: return;
2612: }
2613:
1.131 bowersj2 2614: sub printHelper {
1.115 bowersj2 2615: my $r = shift;
2616:
2617: if ($r->header_only) {
1.373 albertel 2618: if ($env{'browser.mathml'}) {
1.241 www 2619: &Apache::loncommon::content_type($r,'text/xml');
1.131 bowersj2 2620: } else {
1.241 www 2621: &Apache::loncommon::content_type($r,'text/html');
1.131 bowersj2 2622: }
2623: $r->send_http_header;
2624: return OK;
1.115 bowersj2 2625: }
2626:
1.131 bowersj2 2627: # Send header, nocache
1.373 albertel 2628: if ($env{'browser.mathml'}) {
1.241 www 2629: &Apache::loncommon::content_type($r,'text/xml');
1.115 bowersj2 2630: } else {
1.241 www 2631: &Apache::loncommon::content_type($r,'text/html');
1.115 bowersj2 2632: }
2633: &Apache::loncommon::no_cache($r);
2634: $r->send_http_header;
2635: $r->rflush();
2636:
1.131 bowersj2 2637: # Unfortunately, this helper is so complicated we have to
2638: # write it by hand
2639:
2640: Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
2641:
1.176 bowersj2 2642: my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146 bowersj2 2643: $helper->declareVar('symb');
1.156 bowersj2 2644: $helper->declareVar('postdata');
1.290 sakharuk 2645: $helper->declareVar('curseed');
2646: $helper->declareVar('probstatus');
1.156 bowersj2 2647: $helper->declareVar('filename');
2648: $helper->declareVar('construction');
1.178 sakharuk 2649: $helper->declareVar('assignment');
1.262 sakharuk 2650: $helper->declareVar('style_file');
1.340 foxr 2651: $helper->declareVar('student_sort');
1.363 foxr 2652: $helper->declareVar('FINISHPAGE');
1.366 foxr 2653: $helper->declareVar('PRINT_TYPE');
1.372 foxr 2654: $helper->declareVar("showallfoils");
1.483 foxr 2655: $helper->declareVar("STUDENTS");
1.363 foxr 2656:
1.518 foxr 2657:
2658:
2659:
2660:
1.363 foxr 2661: # The page breaks can get loaded initially from the course environment:
1.394 foxr 2662: # But we only do this in the initial state so that they are allowed to change.
2663: #
1.366 foxr 2664:
1.416 foxr 2665: # $helper->{VARS}->{FINISHPAGE} = '';
1.363 foxr 2666:
2667: &Apache::loncommon::restore_course_settings('print',
1.366 foxr 2668: {'pagebreaks' => 'scalar',
2669: 'lastprinttype' => 'scalar'});
2670:
1.483 foxr 2671: # This will persistently load in the data we want from the
2672: # very first screen.
1.394 foxr 2673:
2674: if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
2675: if (!defined ($env{"form.CURRENT_STATE"})) {
2676:
2677: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
2678: } else {
2679: my $state = $env{"form.CURRENT_STATE"};
2680: if ($state eq "START") {
2681: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
2682: }
2683: }
2684:
1.366 foxr 2685: }
1.481 albertel 2686:
1.156 bowersj2 2687: # Detect whether we're coming from construction space
1.373 albertel 2688: if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235 bowersj2 2689: $helper->{VARS}->{'filename'} = "~$1/$2";
1.156 bowersj2 2690: $helper->{VARS}->{'construction'} = 1;
1.481 albertel 2691: } else {
1.373 albertel 2692: if ($env{'form.postdata'}) {
2693: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482 albertel 2694: if ( $helper->{VARS}->{'symb'} eq '') {
2695: $helper->{VARS}->{'postdata'} = $env{'form.postdata'};
2696: }
1.156 bowersj2 2697: }
1.373 albertel 2698: if ($env{'form.symb'}) {
2699: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156 bowersj2 2700: }
1.373 albertel 2701: if ($env{'form.url'}) {
1.156 bowersj2 2702: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
2703: }
1.416 foxr 2704:
1.157 bowersj2 2705: }
1.481 albertel 2706:
1.373 albertel 2707: if ($env{'form.symb'}) {
2708: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146 bowersj2 2709: }
1.373 albertel 2710: if ($env{'form.url'}) {
1.140 sakharuk 2711: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153 sakharuk 2712:
1.140 sakharuk 2713: }
1.343 albertel 2714: $helper->{VARS}->{'symb'}=
2715: &Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335 albertel 2716: my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178 sakharuk 2717: if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481 albertel 2718:
1.156 bowersj2 2719:
1.146 bowersj2 2720: # Extract map
2721: my $symb = $helper->{VARS}->{'symb'};
1.156 bowersj2 2722: my ($map, $id, $url);
2723: my $subdir;
1.483 foxr 2724: my $is_published=0; # True when printing from resource space.
1.156 bowersj2 2725:
2726: # Get the resource name from construction space
2727: if ($helper->{VARS}->{'construction'}) {
2728: $resourceTitle = substr($helper->{VARS}->{'filename'},
2729: rindex($helper->{VARS}->{'filename'}, '/')+1);
2730: $subdir = substr($helper->{VARS}->{'filename'},
2731: 0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481 albertel 2732: } else {
1.482 albertel 2733: if ($symb ne '') {
2734: ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
2735: $helper->{VARS}->{'postdata'} =
2736: &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
2737: } else {
2738: $url = $helper->{VARS}->{'postdata'};
1.483 foxr 2739: $is_published=1; # From resource space.
1.482 albertel 2740: }
2741: $url = &Apache::lonnet::clutter($url);
1.481 albertel 2742:
1.156 bowersj2 2743: if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238 bowersj2 2744: my $postdata = $helper->{VARS}->{'postdata'};
2745: $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156 bowersj2 2746: }
2747: $subdir = &Apache::lonnet::filelocation("", $url);
1.128 bowersj2 2748: }
1.373 albertel 2749: if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
2750: $helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230 albertel 2751: }
1.373 albertel 2752: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
1.512 foxr 2753: $helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
1.290 sakharuk 2754: }
1.115 bowersj2 2755:
1.192 bowersj2 2756: my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
2757:
1.481 albertel 2758: Apache::lonhelper::registerHelperTags();
1.119 bowersj2 2759:
1.131 bowersj2 2760: # "Delete everything after the last slash."
1.119 bowersj2 2761: $subdir =~ s|/[^/]+$||;
2762:
1.131 bowersj2 2763: # What can be printed is a very dynamic decision based on
2764: # lots of factors. So we need to dynamically build this list.
2765: # To prevent security leaks, states are only added to the wizard
2766: # if they can be reached, which ensures manipulating the form input
2767: # won't allow anyone to reach states they shouldn't have permission
2768: # to reach.
2769:
2770: # printChoices is tracking the kind of printing the user can
2771: # do, and will be used in a choices construction later.
2772: # In the meantime we will be adding states and elements to
2773: # the helper by hand.
2774: my $printChoices = [];
2775: my $paramHash;
1.130 sakharuk 2776:
1.240 albertel 2777: if ($resourceTitle) {
1.458 www 2778: push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156 bowersj2 2779: }
2780:
1.238 bowersj2 2781: # Useful filter strings
1.540 raeburn 2782: my $isProblem = '($res->is_problem()||$res->contains_problem||$res->is_practice()) ';
1.238 bowersj2 2783: $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.541 raeburn 2784: my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice()';
1.287 albertel 2785: my $isNotMap = '!$res->is_sequence()';
1.238 bowersj2 2786: $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
2787: my $isMap = '$res->is_map()';
1.342 albertel 2788: my $symbFilter = '$res->shown_symb()';
2789: my $urlValue = '$res->link()';
1.238 bowersj2 2790:
2791: $helper->declareVar('SEQUENCE');
2792:
1.465 albertel 2793: # If we're in a sequence...
1.416 foxr 2794:
1.465 albertel 2795: my $start_new_option;
2796: if ($perm{'pav'}) {
2797: $start_new_option =
2798: "<option text='".&mt('Start new page<br />before selected').
2799: "' variable='FINISHPAGE' />";
2800: }
1.238 bowersj2 2801:
1.483 foxr 2802: if (($helper->{'VARS'}->{'construction'} ne '1' ) &&
1.243 bowersj2 2803: $helper->{VARS}->{'postdata'} &&
2804: $helper->{VARS}->{'assignment'}) {
1.131 bowersj2 2805: # Allow problems from sequence
1.546 bisitz 2806: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'), 'map_problems', 'CHOOSE_PROBLEMS'];
1.131 bowersj2 2807: # Allow all resources from sequence
1.546 bisitz 2808: 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 2809:
1.131 bowersj2 2810: my $helperFragment = <<HELPERFRAGMENT;
1.155 sakharuk 2811: <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print">
1.435 foxr 2812: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2813: closeallpages="1">
1.144 bowersj2 2814: <nextstate>PAGESIZE</nextstate>
1.435 foxr 2815: <filterfunc>return $isProblem;</filterfunc>
1.131 bowersj2 2816: <mapurl>$map</mapurl>
1.238 bowersj2 2817: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2818: $start_new_option
1.131 bowersj2 2819: </resource>
2820: </state>
2821:
1.155 sakharuk 2822: <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print">
1.435 foxr 2823: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 2824: closeallpages="1">
1.144 bowersj2 2825: <nextstate>PAGESIZE</nextstate>
1.435 foxr 2826: <filterfunc>return $isNotMap;</filterfunc>
1.131 bowersj2 2827: <mapurl>$map</mapurl>
1.238 bowersj2 2828: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2829: $start_new_option
1.131 bowersj2 2830: </resource>
2831: </state>
2832: HELPERFRAGMENT
1.121 bowersj2 2833:
1.326 sakharuk 2834: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121 bowersj2 2835: }
2836:
1.546 bisitz 2837: # If the user has pfo (print for others) allow them to print all
2838: # problems and resources in the entire course, optionally for selected students
1.483 foxr 2839: if ($perm{'pfo'} && !$is_published &&
1.481 albertel 2840: ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) {
2841:
1.509 albertel 2842: push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
2843: push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.536 foxr 2844: 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 2845: &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS);
1.155 sakharuk 2846: <state name="ALL_PROBLEMS" title="Select Problem(s) to print">
1.287 albertel 2847: <resource variable="RESOURCES" toponly='0' multichoice="1"
2848: suppressEmptySequences='0' addstatus="1" closeallpages="1">
1.144 bowersj2 2849: <nextstate>PAGESIZE</nextstate>
1.192 bowersj2 2850: <filterfunc>return $isProblemOrMap;</filterfunc>
1.287 albertel 2851: <choicefunc>return $isNotMap;</choicefunc>
1.238 bowersj2 2852: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2853: $start_new_option
1.284 albertel 2854: </resource>
2855: </state>
1.354 foxr 2856: <state name="ALL_RESOURCES" title="Select Resource(s) to print">
2857: <resource variable="RESOURCES" toponly='0' multichoice='1'
2858: suppressEmptySequences='0' addstatus='1' closeallpages='1'>
2859: <nextstate>PAGESIZE</nextstate>
2860: <filterfunc>return $isNotMap; </filterfunc>
2861: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2862: $start_new_option
1.354 foxr 2863: </resource>
2864: </state>
1.536 foxr 2865: <state name="ALL_PROBLEMS_STUDENTS" title="Select Problem(s) to print">
2866: <resource variable="RESOURCES" toponly='0' multichoice="1"
2867: suppressEmptySequences='0' addstatus="1" closeallpages="1">
2868: <nextstate>STUDENTS1</nextstate>
2869: <filterfunc>return $isProblemOrMap;</filterfunc>
2870: <choicefunc>return $isNotMap;</choicefunc>
2871: <valuefunc>return $symbFilter;</valuefunc>
2872: $start_new_option
2873: </resource>
2874: </state>
2875: <state name="STUDENTS1" title="Select People">
2876: <message><b>Select sorting order of printout</b> </message>
2877: <choices variable='student_sort'>
2878: <choice computer='0'>Sort by section then student</choice>
2879: <choice computer='1'>Sort by students across sections.</choice>
2880: </choices>
2881: <message><br /><hr /><br /> </message>
2882: <student multichoice='1' variable="STUDENTS" nextstate="PRINT_FORMATTING" coursepersonnel="1"/>
2883: </state>
2884:
1.284 albertel 2885: ALL_PROBLEMS
1.132 bowersj2 2886:
1.284 albertel 2887: if ($helper->{VARS}->{'assignment'}) {
1.546 bisitz 2888: 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'];
2889: 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 2890: }
1.424 foxr 2891:
1.507 albertel 2892: my $randomly_ordered_warning =
2893: &get_randomly_ordered_warning($helper,$map);
2894:
1.424 foxr 2895: # resource_selector will hold a few states that:
2896: # - Allow resources to be selected for printing.
2897: # - Determine pagination between assignments.
2898: # - Determine how many assignments should be bundled into a single PDF.
2899: # TODO:
2900: # Probably good to do things like separate this up into several vars, each
2901: # with one state, and use REGEXPs at inclusion time to set state names
2902: # and next states for better mix and match capability
2903: #
1.284 albertel 2904: my $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 2905: <state name="SELECT_PROBLEMS" title="Select resources to print">
1.507 albertel 2906: $randomly_ordered_warning
2907:
1.424 foxr 2908: <nextstate>PRINT_FORMATTING</nextstate>
1.284 albertel 2909: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 2910: <resource variable="RESOURCES" multichoice="1" addstatus="1"
2911: closeallpages="1">
1.254 sakharuk 2912: <filterfunc>return $isProblem;</filterfunc>
1.148 bowersj2 2913: <mapurl>$map</mapurl>
1.254 sakharuk 2914: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 2915: $start_new_option
1.147 bowersj2 2916: </resource>
1.424 foxr 2917: </state>
2918: <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155 sakharuk 2919: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149 bowersj2 2920: <choices variable="EMPTY_PAGES">
1.204 sakharuk 2921: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
2922: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
2923: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
2924: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 2925: </choices>
1.424 foxr 2926: <nextstate>PAGESIZE</nextstate>
1.429 foxr 2927: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
2928: <choices variable="SPLIT_PDFS">
2929: <choice computer="all">All assignments in a single PDF file</choice>
2930: <choice computer="sections">Each PDF contains exactly one section</choice>
2931: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 2932: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
2933: Specify the number of assignments per PDF:</choice>
1.429 foxr 2934: </choices>
1.424 foxr 2935: </state>
1.284 albertel 2936: RESOURCE_SELECTOR
2937:
2938: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS);
2939: <state name="CHOOSE_STUDENTS" title="Select Students and Resources">
1.485 albertel 2940: <message><b>Select sorting order of printout</b> </message>
1.340 foxr 2941: <choices variable='student_sort'>
2942: <choice computer='0'>Sort by section then student</choice>
2943: <choice computer='1'>Sort by students across sections.</choice>
2944: </choices>
1.437 foxr 2945: <message><br /><hr /><br /> </message>
1.425 foxr 2946: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_PROBLEMS" coursepersonnel="1"/>
1.424 foxr 2947: </state>
1.284 albertel 2948: $resource_selector
1.131 bowersj2 2949: CHOOSE_STUDENTS
1.292 albertel 2950:
1.373 albertel 2951: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2952: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292 albertel 2953: my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
2954: my $namechoice='<choice></choice>';
1.337 albertel 2955: foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294 albertel 2956: if ($name =~ /^error: 2 /) { next; }
1.381 albertel 2957: if ($name =~ /^type\0/) { next; }
1.292 albertel 2958: $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
2959: }
1.389 foxr 2960:
2961:
2962: my %code_values;
1.405 albertel 2963: my %codes_to_print;
1.411 albertel 2964: foreach my $key (@names) {
1.389 foxr 2965: %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405 albertel 2966: foreach my $key (keys(%code_values)) {
2967: $codes_to_print{$key} = 1;
1.388 foxr 2968: }
2969: }
1.389 foxr 2970:
1.452 albertel 2971: my $code_selection;
1.405 albertel 2972: foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389 foxr 2973: my $choice = $code;
2974: if ($code =~ /^[A-Z]+$/) { # Alpha code
2975: $choice = &letters_to_num($code);
2976: }
1.432 albertel 2977: push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388 foxr 2978: }
1.436 albertel 2979: if (%codes_to_print) {
2980: $code_selection .='
1.472 albertel 2981: <message><b>Choose single CODE from list:</b></message>
1.448 albertel 2982: <message></td><td></message>
1.452 albertel 2983: <dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
2984: <choice></choice>
1.448 albertel 2985: <exec>
2986: push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
2987: </exec>
1.452 albertel 2988: </dropdown>
1.468 foxr 2989: <message></td></tr><tr><td></message>
1.436 albertel 2990: '.$/;
1.448 albertel 2991:
1.436 albertel 2992: }
1.432 albertel 2993:
1.542 raeburn 2994: my @lines = &Apache::grades::get_scantronformat_file();
1.381 albertel 2995: my $codechoice='';
1.542 raeburn 2996: foreach my $line (@lines) {
1.381 albertel 2997: my ($name,$description,$code_type,$code_length)=
2998: (split(/:/,$line))[0,1,2,4];
2999: if ($code_length > 0 &&
3000: $code_type =~/^(letter|number|-1)/) {
3001: $codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
3002: }
3003: }
3004: if ($codechoice eq '') {
3005: $codechoice='<choice computer="default">Default</choice>';
3006: }
1.284 albertel 3007: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1);
1.468 foxr 3008: <state name="CHOOSE_ANON1" title="Specify CODEd Assignments">
1.424 foxr 3009: <nextstate>SELECT_PROBLEMS</nextstate>
1.468 foxr 3010: <message><h4>Fill out one of the forms below</h4></message>
3011: <message><br /><hr /> <br /></message>
3012: <message><h3>Generate new CODEd Assignments</h3></message>
3013: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 3014: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
3015: <validator>
3016: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.382 foxr 3017: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 3018: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
3019: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 3020: return "You need to specify the number of assignments to print";
3021: }
3022: return undef;
3023: </validator>
3024: </string>
3025: <message></td></tr><tr><td></message>
1.501 albertel 3026: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 3027: <message></td><td></message>
3028: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
3029: <message></td></tr><tr><td></message>
3030: <message><b>Bubble sheet type:</b></message>
3031: <message></td><td></message>
3032: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
3033: $codechoice
3034: </dropdown>
1.468 foxr 3035: <message></td></tr><tr><td colspan="2"></td></tr><tr><td></message>
3036: <message></td></tr><tr><td></table></message>
1.472 albertel 3037: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
1.468 foxr 3038: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 3039: <string variable="SINGLE_CODE" size="10">
1.382 foxr 3040: <validator>
3041: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 3042: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
3043: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.382 foxr 3044: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
3045: \$helper->{'VARS'}{'CODE_OPTION'});
3046: } else {
3047: return undef; # Other forces control us.
3048: }
3049: </validator>
3050: </string>
1.472 albertel 3051: <message></td></tr><tr><td></message>
1.432 albertel 3052: $code_selection
1.468 foxr 3053: <message></td></tr></table></message>
1.472 albertel 3054: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
1.468 foxr 3055: <message><b>Select saved CODEs:</b></message>
1.381 albertel 3056: <message></td><td></message>
1.292 albertel 3057: <dropdown variable="REUSE_OLD_CODES">
3058: $namechoice
3059: </dropdown>
1.412 albertel 3060: <message></td></tr></table></message>
1.284 albertel 3061: </state>
1.424 foxr 3062: $resource_selector
1.284 albertel 3063: CHOOSE_ANON1
1.254 sakharuk 3064:
1.272 sakharuk 3065:
1.254 sakharuk 3066: if ($helper->{VARS}->{'assignment'}) {
1.546 bisitz 3067: 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'];
3068: 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 3069: }
1.284 albertel 3070:
3071:
3072: $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 3073: <state name="SELECT_RESOURCES" title="Select Resources">
1.507 albertel 3074: $randomly_ordered_warning
3075:
1.424 foxr 3076: <nextstate>PRINT_FORMATTING</nextstate>
1.254 sakharuk 3077: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 3078: <resource variable="RESOURCES" multichoice="1" addstatus="1"
3079: closeallpages="1">
1.254 sakharuk 3080: <filterfunc>return $isNotMap;</filterfunc>
3081: <mapurl>$map</mapurl>
3082: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 3083: $start_new_option
1.254 sakharuk 3084: </resource>
1.424 foxr 3085: </state>
3086: <state name="PRINT_FORMATTING" title="Format of the print job">
3087: <nextstate>NUMBER_PER_PDF</nextstate>
1.254 sakharuk 3088: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
3089: <choices variable="EMPTY_PAGES">
3090: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
3091: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
3092: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
3093: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 3094: </choices>
1.424 foxr 3095: <nextstate>PAGESIZE</nextstate>
1.429 foxr 3096: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
3097: <choices variable="SPLIT_PDFS">
3098: <choice computer="all">All assignments in a single PDF file</choice>
3099: <choice computer="sections">Each PDF contains exactly one section</choice>
3100: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 3101: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
3102: Specify the number of assignments per PDF:</choice>
1.429 foxr 3103: </choices>
1.424 foxr 3104: </state>
1.284 albertel 3105: RESOURCE_SELECTOR
3106:
3107: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
3108: <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340 foxr 3109: <choices variable='student_sort'>
3110: <choice computer='0'>Sort by section then student</choice>
3111: <choice computer='1'>Sort by students across sections.</choice>
3112: </choices>
1.437 foxr 3113: <message><br /><hr /><br /></message>
1.426 foxr 3114: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340 foxr 3115:
1.424 foxr 3116: </state>
1.284 albertel 3117: $resource_selector
1.254 sakharuk 3118: CHOOSE_STUDENTS1
3119:
1.284 albertel 3120: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472 albertel 3121: <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424 foxr 3122: <nextstate>SELECT_RESOURCES</nextstate>
1.472 albertel 3123: <message><h4>Fill out one of the forms below</h4></message>
3124: <message><br /><hr /> <br /></message>
3125: <message><h3>Generate new CODEd Assignments</h3></message>
3126: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 3127: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
3128: <validator>
3129: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386 foxr 3130: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 3131: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
3132: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 3133: return "You need to specify the number of assignments to print";
3134: }
3135: return undef;
3136: </validator>
3137: </string>
3138: <message></td></tr><tr><td></message>
1.501 albertel 3139: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 3140: <message></td><td></message>
3141: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
3142: <message></td></tr><tr><td></message>
3143: <message><b>Bubble sheet type:</b></message>
3144: <message></td><td></message>
3145: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
3146: $codechoice
3147: </dropdown>
1.472 albertel 3148: <message></td></tr><tr><td></table></message>
3149: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
3150: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 3151: <string variable="SINGLE_CODE" size="10">
1.386 foxr 3152: <validator>
3153: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 3154: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
3155: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386 foxr 3156: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
3157: \$helper->{'VARS'}{'CODE_OPTION'});
3158: } else {
3159: return undef; # Other forces control us.
3160: }
3161: </validator>
3162: </string>
1.472 albertel 3163: <message></td></tr><tr><td></message>
1.432 albertel 3164: $code_selection
1.472 albertel 3165: <message></td></tr></table></message>
3166: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
3167: <message><b>Select saved CODEs:</b></message>
1.381 albertel 3168: <message></td><td></message>
1.294 albertel 3169: <dropdown variable="REUSE_OLD_CODES">
3170: $namechoice
3171: </dropdown>
1.412 albertel 3172: <message></td></tr></table></message>
1.424 foxr 3173: </state>
1.284 albertel 3174: $resource_selector
3175: CHOOSE_ANON2
1.481 albertel 3176: }
3177:
1.121 bowersj2 3178: # FIXME: That RE should come from a library somewhere.
1.483 foxr 3179: if (($perm{'pav'}
1.482 albertel 3180: && $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
3181: && (defined($helper->{'VARS'}->{'construction'})
3182: ||
3183: (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
3184: &&
3185: $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483 foxr 3186: ))
3187: && $helper->{VARS}->{'assignment'} eq ""
1.482 albertel 3188: ) {
1.238 bowersj2 3189:
1.482 albertel 3190: my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
1.546 bisitz 3191: 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 3192: my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482 albertel 3193: <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458 www 3194:
1.138 bowersj2 3195: <files variable="FILES" multichoice='1'>
1.144 bowersj2 3196: <nextstate>PAGESIZE</nextstate>
1.138 bowersj2 3197: <filechoice>return '$subdir';</filechoice>
1.139 bowersj2 3198: CHOOSE_FROM_SUBDIR
3199:
1.238 bowersj2 3200: # this is broken up because I really want interpolation above,
3201: # and I really DON'T want it below
1.139 bowersj2 3202: $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225 bowersj2 3203: <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
3204: $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131 bowersj2 3205: </filefilter>
1.138 bowersj2 3206: </files>
1.131 bowersj2 3207: </state>
3208: CHOOSE_FROM_SUBDIR
1.139 bowersj2 3209: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131 bowersj2 3210: }
1.238 bowersj2 3211:
3212: # Allow the user to select any sequence in the course, feed it to
3213: # another resource selector for that sequence
1.483 foxr 3214: if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509 albertel 3215: push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249 sakharuk 3216: 'select_sequences', 'CHOOSE_SEQUENCE'];
1.244 bowersj2 3217: my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
3218: #Escape apostrophes and backslashes for Perl
3219: $escapedSequenceName =~ s/\\/\\\\/g;
3220: $escapedSequenceName =~ s/'/\\'/g;
1.239 bowersj2 3221: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238 bowersj2 3222: <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
3223: <message>Select the sequence to print resources from:</message>
3224: <resource variable="SEQUENCE">
3225: <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
3226: <filterfunc>return \$res->is_sequence;</filterfunc>
3227: <valuefunc>return $urlValue;</valuefunc>
1.447 foxr 3228: <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391 foxr 3229: </choicefunc>
1.238 bowersj2 3230: </resource>
3231: </state>
3232: <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
3233: <message>(mark desired resources then click "next" button) <br /></message>
1.435 foxr 3234: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 3235: closeallpages="1">
1.238 bowersj2 3236: <nextstate>PAGESIZE</nextstate>
1.466 albertel 3237: <filterfunc>return $isNotMap</filterfunc>
1.244 bowersj2 3238: <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238 bowersj2 3239: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 3240: $start_new_option
1.238 bowersj2 3241: </resource>
3242: </state>
3243: CHOOSE_FROM_ANY_SEQUENCE
1.239 bowersj2 3244: }
1.481 albertel 3245:
1.131 bowersj2 3246: # Generate the first state, to select which resources get printed.
1.223 bowersj2 3247: Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131 bowersj2 3248: $paramHash = Apache::lonhelper::getParamHash();
1.155 sakharuk 3249: $paramHash->{MESSAGE_TEXT} = "";
1.131 bowersj2 3250: Apache::lonhelper::message->new();
3251: $paramHash = Apache::lonhelper::getParamHash();
3252: $paramHash->{'variable'} = 'PRINT_TYPE';
3253: $paramHash->{CHOICES} = $printChoices;
3254: Apache::lonhelper::choices->new();
1.161 bowersj2 3255:
1.223 bowersj2 3256: my $startedTable = 0; # have we started an HTML table yet? (need
3257: # to close it later)
3258:
1.397 albertel 3259: if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or
1.170 sakharuk 3260: ($helper->{VARS}->{'construction'} eq '1')) {
1.544 bisitz 3261: &addMessage('<br />'
3262: .'<h3>'.&mt('Print Options').'</h3>'
3263: .&Apache::lonhtmlcommon::start_pick_box()
3264: .&Apache::lonhtmlcommon::row_title(
3265: '<label for="ANSWER_TYPE_forminput">'
3266: .&mt('Print Answers')
3267: .'</label>'
3268: )
3269: );
1.161 bowersj2 3270: $paramHash = Apache::lonhelper::getParamHash();
1.162 sakharuk 3271: $paramHash->{'variable'} = 'ANSWER_TYPE';
3272: $helper->declareVar('ANSWER_TYPE');
1.161 bowersj2 3273: $paramHash->{CHOICES} = [
1.242 sakharuk 3274: ['Without Answers', 'yes'],
3275: ['With Answers', 'no'],
1.368 albertel 3276: ['Only Answers', 'only']
1.289 sakharuk 3277: ];
1.210 sakharuk 3278: Apache::lonhelper::dropdown->new();
1.544 bisitz 3279: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.223 bowersj2 3280: $startedTable = 1;
1.556 foxr 3281:
3282: #
3283: # Select font size.
3284: #
3285:
3286: $helper->declareVar('fontsize');
3287: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Font Size')));
3288: my $xmlfrag = << "FONT_SELECTION";
3289:
3290:
3291: <dropdown variable='fontsize' multichoice='0', allowempty='0'>
3292: <defaultvalue>
3293: return 'normalsize';
3294: </defaultvalue>
3295: <choice computer='tiny'>Tiny</choice>
3296: <choice computer='sub/superscriptsize'>Script Size</choice>
3297: <choice computer='footnotesize'>Footnote Size</choice>
3298: <choice computer='small'>Small</choice>
3299: <choice computer='normalsize'>Normal (default)</choice>
3300: <choice computer='large'>larger than normal</choice>
3301: <choice computer='Large'>Even larger than normal</choice>
3302: <choice computer='LARGE'>Still larger than normal</choice>
3303: <choice computer='huge'>huge font size</choice>
3304: <choice computer='Huge'>Largest possible size</choice>
3305: </dropdown>
3306: FONT_SELECTION
3307: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
3308: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.161 bowersj2 3309: }
1.209 sakharuk 3310:
1.397 albertel 3311: if ($perm{'pav'}) {
1.223 bowersj2 3312: if (!$startedTable) {
1.497 www 3313: addMessage("<hr width='33%' /><table><tr><td align='right'>".
3314: '<label for="LATEX_TYPE_forminput">'.
3315: &mt('LaTeX mode').
3316: "</label>: </td><td>");
1.223 bowersj2 3317: $startedTable = 1;
3318: } else {
1.544 bisitz 3319: &addMessage(&Apache::lonhtmlcommon::row_title(
3320: '<label for="LATEX_TYPE_forminput">'
3321: .&mt('LaTeX mode')
3322: .'</label>'
3323: )
3324: );
1.223 bowersj2 3325: }
1.203 sakharuk 3326: $paramHash = Apache::lonhelper::getParamHash();
3327: $paramHash->{'variable'} = 'LATEX_TYPE';
3328: $helper->declareVar('LATEX_TYPE');
3329: if ($helper->{VARS}->{'construction'} eq '1') {
3330: $paramHash->{CHOICES} = [
1.223 bowersj2 3331: ['standard LaTeX mode', 'standard'],
3332: ['LaTeX batchmode', 'batchmode'], ];
1.203 sakharuk 3333: } else {
3334: $paramHash->{CHOICES} = [
1.223 bowersj2 3335: ['LaTeX batchmode', 'batchmode'],
3336: ['standard LaTeX mode', 'standard'] ];
1.203 sakharuk 3337: }
1.210 sakharuk 3338: Apache::lonhelper::dropdown->new();
1.218 sakharuk 3339:
1.544 bisitz 3340: &addMessage(&Apache::lonhtmlcommon::row_closure()
3341: .&Apache::lonhtmlcommon::row_title(
3342: '<label for="TABLE_CONTENTS_forminput">'
3343: .&mt('Print Table of Contents')
3344: .'</label>'
3345: )
3346: );
1.209 sakharuk 3347: $paramHash = Apache::lonhelper::getParamHash();
3348: $paramHash->{'variable'} = 'TABLE_CONTENTS';
3349: $helper->declareVar('TABLE_CONTENTS');
3350: $paramHash->{CHOICES} = [
1.223 bowersj2 3351: ['No', 'no'],
3352: ['Yes', 'yes'] ];
1.210 sakharuk 3353: Apache::lonhelper::dropdown->new();
1.544 bisitz 3354: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.214 sakharuk 3355:
1.220 sakharuk 3356: if (not $helper->{VARS}->{'construction'}) {
1.545 bisitz 3357: &addMessage(&Apache::lonhtmlcommon::row_title(
3358: '<label for="TABLE_INDEX_forminput">'
3359: .&mt('Print Index')
3360: .'</label>'
3361: )
3362: );
1.220 sakharuk 3363: $paramHash = Apache::lonhelper::getParamHash();
3364: $paramHash->{'variable'} = 'TABLE_INDEX';
3365: $helper->declareVar('TABLE_INDEX');
3366: $paramHash->{CHOICES} = [
1.223 bowersj2 3367: ['No', 'no'],
3368: ['Yes', 'yes'] ];
1.220 sakharuk 3369: Apache::lonhelper::dropdown->new();
1.545 bisitz 3370: &addMessage(&Apache::lonhtmlcommon::row_closure());
3371: &addMessage(&Apache::lonhtmlcommon::row_title(
3372: '<label for="PRINT_DISCUSSIONS_forminput">'
3373: .&mt('Print Discussions')
3374: .'</label>'
3375: )
3376: );
1.309 sakharuk 3377: $paramHash = Apache::lonhelper::getParamHash();
3378: $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';
3379: $helper->declareVar('PRINT_DISCUSSIONS');
3380: $paramHash->{CHOICES} = [
3381: ['No', 'no'],
3382: ['Yes', 'yes'] ];
3383: Apache::lonhelper::dropdown->new();
1.545 bisitz 3384: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.372 foxr 3385:
1.511 foxr 3386: # Prompt for printing annotations too.
3387:
1.545 bisitz 3388: &addMessage(&Apache::lonhtmlcommon::row_title(
3389: '<label for="PRINT_ANNOTATIONS_forminput">'
3390: .&mt('Print Annotations')
3391: .'</label>'
3392: )
3393: );
1.511 foxr 3394: $paramHash = Apache::lonhelper::getParamHash();
3395: $paramHash->{'variable'} = "PRINT_ANNOTATIONS";
3396: $helper->declareVar("PRINT_ANNOTATIONS");
3397: $paramHash->{CHOICES} = [
3398: ['No', 'no'],
3399: ['Yes', 'yes']];
3400: Apache::lonhelper::dropdown->new();
1.545 bisitz 3401: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.511 foxr 3402:
1.545 bisitz 3403: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Foils')));
1.397 albertel 3404: $paramHash = Apache::lonhelper::getParamHash();
3405: $paramHash->{'multichoice'} = "true";
3406: $paramHash->{'allowempty'} = "true";
3407: $paramHash->{'variable'} = "showallfoils";
1.555 bisitz 3408: $paramHash->{'CHOICES'} = [ [&mt('Show All Foils'), "1"] ];
1.397 albertel 3409: Apache::lonhelper::choices->new();
1.545 bisitz 3410: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.220 sakharuk 3411: }
1.219 sakharuk 3412:
1.230 albertel 3413: if ($helper->{'VARS'}->{'construction'}) {
1.505 albertel 3414: my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497 www 3415: my $randseedtext=&mt("Use random seed");
3416: my $stylefiletext=&mt("Use style file");
1.506 albertel 3417: my $selectfiletext=&mt("Select style file");
1.497 www 3418:
1.544 bisitz 3419: my $xmlfrag .= '<message>'
3420: .&Apache::lonhtmlcommon::row_title('<label for="curseed_forminput">'
3421: .$randseedtext
3422: .'</label>'
3423: )
3424: .'</message>
3425: <string variable="curseed" size="15" maxlength="15">
3426: <defaultvalue>
3427: return '.$helper->{VARS}->{'curseed'}.';
3428: </defaultvalue>'
3429: .'</string>'
3430: .'<message>'
3431: .&Apache::lonhtmlcommon::row_closure()
3432: .&Apache::lonhtmlcommon::row_title('<label for="style_file">'
3433: .$stylefiletext
3434: .'</label>'
3435: )
3436: .'</message>
1.504 albertel 3437: <string variable="style_file" size="40">
1.544 bisitz 3438: <defaultvalue>
3439: return '.$stylevalue.';
3440: </defaultvalue>
3441: </string><message> '
3442: .qq|<a href="javascript:openbrowser('helpform','style_file_forminput','sty')">|
3443: .$selectfiletext.'</a>'
3444: .&Apache::lonhtmlcommon::row_closure()
1.555 bisitz 3445: .&Apache::lonhtmlcommon::row_title(&mt('Show All Foils'))
1.544 bisitz 3446: .'</message>
1.371 foxr 3447: <choices allowempty="1" multichoice="true" variable="showallfoils">
1.544 bisitz 3448: <choice computer="1"> </choice>
3449: </choices>'
3450: .'<message>'
3451: .&Apache::lonhtmlcommon::row_closure()
3452: .'</message>';
1.230 albertel 3453: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.512 foxr 3454:
3455:
1.544 bisitz 3456: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Problem Type')));
1.512 foxr 3457: #
3458: # Initial value from construction space:
3459: #
3460: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
3461: $helper->{VARS}->{'probstatus'} = $env{'form.problemtype'}; # initial value
3462: }
1.518 foxr 3463: $xmlfrag = << "PROBTYPE";
3464: <dropdown variable="probstatus" multichoice="0" allowempty="0">
3465: <defaultvalue>
3466: return "$helper->{VARS}->{'probstatus'}";
3467: </defaultvalue>
3468: <choice computer="problem">Homework Problem</choice>
3469: <choice computer="exam">Exam Problem</choice>
3470: <choice computer="survey">Survey question</choice>
3471: </dropdown>
3472: PROBTYPE
3473: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.544 bisitz 3474: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.512 foxr 3475:
1.556 foxr 3476:
3477:
1.544 bisitz 3478: }
1.223 bowersj2 3479: }
1.264 sakharuk 3480:
3481:
3482:
1.218 sakharuk 3483:
1.223 bowersj2 3484: if ($startedTable) {
1.544 bisitz 3485: &addMessage(&Apache::lonhtmlcommon::end_pick_box());
1.215 sakharuk 3486: }
1.161 bowersj2 3487:
1.131 bowersj2 3488: Apache::lonprintout::page_format_state->new("FORMAT");
3489:
1.144 bowersj2 3490: # Generate the PAGESIZE state which will offer the user the margin
3491: # choices if they select one column
3492: Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
3493: Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
3494:
3495:
1.131 bowersj2 3496: $helper->process();
3497:
1.416 foxr 3498:
1.131 bowersj2 3499: # MANUAL BAILOUT CONDITION:
3500: # If we're in the "final" state, bailout and return to handler
3501: if ($helper->{STATE} eq 'FINAL') {
3502: return $helper;
3503: }
1.130 sakharuk 3504:
1.131 bowersj2 3505: $r->print($helper->display());
1.395 www 3506: if ($helper->{STATE} eq 'START') {
3507: &recently_generated($r);
3508: }
1.333 albertel 3509: &Apache::lonhelper::unregisterHelperTags();
1.115 bowersj2 3510:
3511: return OK;
3512: }
3513:
1.1 www 3514:
3515: 1;
1.119 bowersj2 3516:
3517: package Apache::lonprintout::page_format_state;
3518:
3519: =pod
3520:
1.131 bowersj2 3521: =head1 Helper element: page_format_state
3522:
3523: See lonhelper.pm documentation for discussion of the helper framework.
1.119 bowersj2 3524:
1.131 bowersj2 3525: Apache::lonprintout::page_format_state is an element that gives the
3526: user an opportunity to select the page layout they wish to print
3527: with: Number of columns, portrait/landscape, and paper size. If you
3528: want to change the paper size choices, change the @paperSize array
3529: contents in this package.
1.119 bowersj2 3530:
1.131 bowersj2 3531: page_format_state is always directly invoked in lonprintout.pm, so there
3532: is no tag interface. You actually pass parameters to the constructor.
1.119 bowersj2 3533:
3534: =over 4
3535:
1.131 bowersj2 3536: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119 bowersj2 3537:
3538: =back
3539:
3540: =cut
3541:
1.131 bowersj2 3542: use Apache::lonhelper;
1.119 bowersj2 3543:
3544: no strict;
1.131 bowersj2 3545: @ISA = ("Apache::lonhelper::element");
1.119 bowersj2 3546: use strict;
1.266 sakharuk 3547: use Apache::lonlocal;
1.373 albertel 3548: use Apache::lonnet;
1.119 bowersj2 3549:
3550: my $maxColumns = 2;
1.376 albertel 3551: # it'd be nice if these all worked
3552: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
3553: # "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
3554: # "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]",
3555: # "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326 sakharuk 3556: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
1.376 albertel 3557: "a4 [210x297 mm]");
1.119 bowersj2 3558:
3559: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
3560: # Paper type
3561:
3562: sub new {
1.131 bowersj2 3563: my $self = Apache::lonhelper::element->new();
1.119 bowersj2 3564:
1.135 bowersj2 3565: shift;
3566:
1.131 bowersj2 3567: $self->{'variable'} = shift;
1.134 bowersj2 3568: my $helper = Apache::lonhelper::getHelper();
1.135 bowersj2 3569: $helper->declareVar($self->{'variable'});
1.131 bowersj2 3570: bless($self);
1.119 bowersj2 3571: return $self;
3572: }
3573:
3574: sub render {
3575: my $self = shift;
1.131 bowersj2 3576: my $helper = Apache::lonhelper::getHelper();
1.119 bowersj2 3577: my $result = '';
1.131 bowersj2 3578: my $var = $self->{'variable'};
1.266 sakharuk 3579: my $PageLayout=&mt('Page layout');
3580: my $NumberOfColumns=&mt('Number of columns');
3581: my $PaperType=&mt('Paper type');
1.506 albertel 3582: my $landscape=&mt('Landscape');
3583: my $portrait=&mt('Portrait');
1.539 onken 3584: my $pdfFormLabel=&mt('PDF-Formfields');
3585: my $with=&mt('with Formfields');
3586: my $without=&mt('without Formfields');
1.556 foxr 3587:
3588:
1.544 bisitz 3589: $result.='<h3>'.&mt('Layout Options').'</h3>'
3590: .&Apache::loncommon::start_data_table()
3591: .&Apache::loncommon::start_data_table_header_row()
3592: .'<th>'.$PageLayout.'</th>'
3593: .'<th>'.$NumberOfColumns.'</th>'
3594: .'<th>'.$PaperType.'</th>'
3595: .'<th>'.$pdfFormLabel.'</th>'
3596: .&Apache::loncommon::end_data_table_header_row()
3597: .&Apache::loncommon::start_data_table_row()
3598: .'<td>'
3599: .'<label><input type="radio" name="'.${var}.'.layout" value="L" />'.$landscape.'</label><br />'
3600: .'<label><input type="radio" name="'.${var}.'.layout" value="P" checked="checked" />'.$portrait.'</label>'
3601: .'</td>';
1.119 bowersj2 3602:
1.544 bisitz 3603: $result.='<td align="center">'
3604: .'<select name="'.${var}.'.cols">';
1.119 bowersj2 3605:
3606: my $i;
3607: for ($i = 1; $i <= $maxColumns; $i++) {
1.144 bowersj2 3608: if ($i == 2) {
1.553 bisitz 3609: $result .= '<option value="'.$i.'" selected="selected">'.$i.'</option>'."\n";
1.119 bowersj2 3610: } else {
1.553 bisitz 3611: $result .= '<option value="'.$i.'">'.$i.'</option>'."\n";
1.119 bowersj2 3612: }
3613: }
3614:
3615: $result .= "</select></td><td>\n";
3616: $result .= "<select name='${var}.paper'>\n";
3617:
1.373 albertel 3618: my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398 albertel 3619: my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
3620: $DefaultPaperSize=~s/\s//g;
1.304 sakharuk 3621: if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119 bowersj2 3622: $i = 0;
3623: foreach (@paperSize) {
1.326 sakharuk 3624: $_=~/(\w+)/;
3625: my $papersize=$1;
1.304 sakharuk 3626: if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.553 bisitz 3627: $result .= '<option selected="selected" value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119 bowersj2 3628: } else {
1.553 bisitz 3629: $result .= '<option value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119 bowersj2 3630: }
3631: $i++;
3632: }
1.539 onken 3633: $result .= <<HTML;
3634: </select>
3635: </td>
3636: <td align='center'>
3637: <select name='${var}.pdfFormFields'>
1.553 bisitz 3638: <option selected="selected" value="no">$without</option>
3639: <option value="yes">$with</option>
1.539 onken 3640: </select>
3641: </td>
3642: HTML
1.544 bisitz 3643: $result.=&Apache::loncommon::end_data_table_row()
3644: .&Apache::loncommon::end_data_table();
1.539 onken 3645:
1.119 bowersj2 3646: return $result;
1.135 bowersj2 3647: }
3648:
3649: sub postprocess {
3650: my $self = shift;
3651:
3652: my $var = $self->{'variable'};
1.136 bowersj2 3653: my $helper = Apache::lonhelper->getHelper();
1.135 bowersj2 3654: $helper->{VARS}->{$var} =
1.373 albertel 3655: $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
1.539 onken 3656: $env{"form.$var.paper"} . '|' . $env{"form.$var.pdfFormFields"};
1.135 bowersj2 3657: return 1;
1.119 bowersj2 3658: }
3659:
3660: 1;
1.144 bowersj2 3661:
3662: package Apache::lonprintout::page_size_state;
3663:
3664: =pod
3665:
3666: =head1 Helper element: page_size_state
3667:
3668: See lonhelper.pm documentation for discussion of the helper framework.
3669:
3670: Apache::lonprintout::page_size_state is an element that gives the
3671: user the opportunity to further refine the page settings if they
3672: select a single-column page.
3673:
3674: page_size_state is always directly invoked in lonprintout.pm, so there
3675: is no tag interface. You actually pass parameters to the constructor.
3676:
3677: =over 4
3678:
3679: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
3680:
3681: =back
3682:
3683: =cut
3684:
3685: use Apache::lonhelper;
1.373 albertel 3686: use Apache::lonnet;
1.144 bowersj2 3687: no strict;
3688: @ISA = ("Apache::lonhelper::element");
3689: use strict;
3690:
3691:
3692:
3693: sub new {
3694: my $self = Apache::lonhelper::element->new();
3695:
3696: shift; # disturbs me (probably prevents subclassing) but works (drops
3697: # package descriptor)... - Jeremy
3698:
3699: $self->{'variable'} = shift;
3700: my $helper = Apache::lonhelper::getHelper();
3701: $helper->declareVar($self->{'variable'});
3702:
3703: # The variable name of the format element, so we can look into
3704: # $helper->{VARS} to figure out whether the columns are one or two
3705: $self->{'formatvar'} = shift;
3706:
1.463 foxr 3707:
1.144 bowersj2 3708: $self->{NEXTSTATE} = shift;
3709: bless($self);
1.467 foxr 3710:
1.144 bowersj2 3711: return $self;
3712: }
3713:
3714: sub render {
3715: my $self = shift;
3716: my $helper = Apache::lonhelper::getHelper();
3717: my $result = '';
3718: my $var = $self->{'variable'};
3719:
1.467 foxr 3720:
3721:
1.144 bowersj2 3722: if (defined $self->{ERROR_MSG}) {
1.464 albertel 3723: $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144 bowersj2 3724: }
3725:
1.438 foxr 3726: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463 foxr 3727:
3728: # Use format to get sensible defaults for the margins:
3729:
3730:
3731: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
3732: ($papersize) = split(/ /, $papersize);
3733:
3734:
3735: if ($laystyle eq 'L') {
3736: $laystyle = 'album';
3737: } else {
3738: $laystyle = 'book';
3739: }
3740:
3741:
1.464 albertel 3742: my %size;
3743: ($size{'width_and_units'},
3744: $size{'height_and_units'},
3745: $size{'margin_and_units'})=
3746: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463 foxr 3747:
1.464 albertel 3748: foreach my $dimension ('width','height','margin') {
3749: ($size{$dimension},$size{$dimension.'_unit'}) =
3750: split(/ +/, $size{$dimension.'_and_units'},2);
3751:
3752: foreach my $unit ('cm','in') {
3753: $size{$dimension.'_options'} .= '<option ';
3754: if ($size{$dimension.'_unit'} eq $unit) {
3755: $size{$dimension.'_options'} .= 'selected="selected" ';
3756: }
3757: $size{$dimension.'_options'} .= '>'.$unit.'</option>';
3758: }
1.438 foxr 3759: }
3760:
1.470 foxr 3761: # Adjust margin for LaTeX margin: .. requires units == cm or in.
3762:
3763: if ($size{'margin_unit'} eq 'in') {
3764: $size{'margin'} += 1;
3765: } else {
3766: $size{'margin'} += 2.54;
3767: }
1.548 bisitz 3768: my %lt = &Apache::lonlocal::texthash(
3769: 'format' => 'How should each column be formatted?',
3770: 'width' => 'Width',
3771: 'height' => 'Height',
3772: 'margin' => 'Left Margin'
3773: );
3774:
3775: $result .= '<p>'.$lt{'format'}.'</p>'
3776: .&Apache::lonhtmlcommon::start_pick_box()
3777: .&Apache::lonhtmlcommon::row_title($lt{'width'})
3778: .'<input type="text" name="'.$var.'.width" value="'.$size{'width'}.'" size="4" />'
3779: .'<select name="'.$var.'.widthunit">'
3780: .$size{'width_options'}
3781: .'</select>'
3782: .&Apache::lonhtmlcommon::row_closure()
3783: .&Apache::lonhtmlcommon::row_title($lt{'height'})
3784: .'<input type="text" name="'.$var.'.height" value="'.$size{'height'}.'" size="4" />'
3785: .'<select name="'.$var.'.heightunit">'
3786: .$size{'height_options'}
3787: .'</select>'
3788: .&Apache::lonhtmlcommon::row_closure()
3789: .&Apache::lonhtmlcommon::row_title($lt{'margin'})
3790: .'<input type="text" name="'.$var.'.lmargin" value="'.$size{'margin'}.'" size="4" />'
3791: .'<select name="'.$var.'.lmarginunit">'
3792: .$size{'margin_options'}
3793: .'</select>'
3794: .&Apache::lonhtmlcommon::row_closure(1)
3795: .&Apache::lonhtmlcommon::end_pick_box();
3796: # <p>Hint: Some instructors like to leave scratch space for the student by
3797: # making the width much smaller than the width of the page.</p>
1.144 bowersj2 3798:
3799: return $result;
3800: }
3801:
1.470 foxr 3802:
1.144 bowersj2 3803: sub preprocess {
3804: my $self = shift;
3805: my $helper = Apache::lonhelper::getHelper();
3806:
3807: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467 foxr 3808:
3809: # If the user does not have 'pav' privilege, set default widths and
3810: # on to the next state right away.
3811: #
3812: if (!$perm{'pav'}) {
3813: my $var = $self->{'variable'};
3814: my $format = $helper->{VARS}->{$self->{'formatvar'}};
3815:
3816: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
3817: ($papersize) = split(/ /, $papersize);
3818:
3819:
3820: if ($laystyle eq 'L') {
3821: $laystyle = 'album';
3822: } else {
3823: $laystyle = 'book';
3824: }
3825: # Figure out some good defaults for the print out and set them:
3826:
3827: my %size;
3828: ($size{'width'},
3829: $size{'height'},
3830: $size{'lmargin'})=
3831: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
3832:
3833: foreach my $dim ('width', 'height', 'lmargin') {
3834: my ($value, $units) = split(/ /, $size{$dim});
1.470 foxr 3835:
1.467 foxr 3836: $helper->{VARS}->{"$var.".$dim} = $value;
3837: $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
3838:
3839: }
3840:
3841:
3842: # Transition to the next state
3843:
3844: $helper->changeState($self->{NEXTSTATE});
3845: }
1.144 bowersj2 3846:
3847: return 1;
3848: }
3849:
3850: sub postprocess {
3851: my $self = shift;
3852:
3853: my $var = $self->{'variable'};
3854: my $helper = Apache::lonhelper->getHelper();
1.373 albertel 3855: my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"};
3856: my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"};
3857: my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"};
3858: $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"};
3859: $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"};
3860: $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"};
1.144 bowersj2 3861:
3862: my $error = '';
3863:
3864: # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed
3865: # by an optional period, followed by digits, ending the string
3866:
1.464 albertel 3867: if ($width !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3868: $error .= "Invalid width; please type only a number.<br />\n";
3869: }
1.464 albertel 3870: if ($height !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3871: $error .= "Invalid height; please type only a number.<br />\n";
3872: }
1.464 albertel 3873: if ($lmargin !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 3874: $error .= "Invalid left margin; please type only a number.<br />\n";
1.470 foxr 3875: } else {
3876: # Adjust for LaTeX 1.0 inch margin:
3877:
3878: if ($env{"form.${var}.lmarginunit"} eq "in") {
3879: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
3880: } else {
3881: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
3882: }
1.144 bowersj2 3883: }
3884:
3885: if (!$error) {
3886: Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
3887: return 1;
3888: } else {
3889: $self->{ERROR_MSG} = $error;
3890: return 0;
3891: }
3892: }
3893:
3894:
1.119 bowersj2 3895:
1.1 www 3896: __END__
1.6 sakharuk 3897:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>