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