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