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