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