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