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