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