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