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