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