Annotation of loncom/interface/lonprintout.pm, revision 1.568.2.1
1.562 foxr 1: #
1.389 foxr 2: # The LearningOnline Network
1.1 www 3: # Printout
4: #
1.568.2.1! raeburn 5: # $Id: lonprintout.pm,v 1.568 2009/12/21 12:11:51 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.568 foxr 2808: my $syllabus_first = 0;
1.284 albertel 2809: foreach my $curresline (@{$master_seq}) {
1.351 foxr 2810: if (defined $page_breaks{$curresline}) {
1.350 foxr 2811: if($i != 0) {
2812: $current_output.= "\\newpage\n";
2813: }
2814: }
2815: $i++;
1.511 foxr 2816:
1.284 albertel 2817: if ( !($type eq 'problems' &&
2818: ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
2819: my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
2820: if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414 albertel 2821: if ($res_url!~m|^ext/|
1.413 albertel 2822: && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 2823: $printed .= $curresline.':';
1.428 albertel 2824: &Apache::lonxml::remember_problem_counter();
2825:
1.526 www 2826: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.305 sakharuk 2827: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
2828: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2829: # Use a copy of the hash so we don't pervert it on future loop passes.
2830: my %answerenv = %{$moreenv};
2831: $answerenv{'answer_output_mode'}='tex';
2832: $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428 albertel 2833:
2834: &Apache::lonxml::restore_problem_counter();
2835:
1.380 foxr 2836: my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428 albertel 2837:
1.305 sakharuk 2838: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2839: $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
2840: } else {
1.423 foxr 2841:
2842:
2843: my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.552 foxr 2844: $header =~ s/\\begin{document}//; #<<<<<
1.477 albertel 2845: my $title = &Apache::lonnet::gettitle($curresline);
2846: $title = &Apache::lonxml::latex_special_symbols($title);
2847: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
2848: $body .=&path_to_problem($res_url,$LaTeXwidth);
1.423 foxr 2849: $body .='\vskip 1 mm '.$ansrendered;
2850: $body = &encapsulate_minipage($body);
2851: $rendered = $header.$body;
1.305 sakharuk 2852: }
2853: }
1.511 foxr 2854: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2855: my $url = &Apache::lonnet::clutter($res_url);
2856: my $annotation = &annotate($url);
2857: $rendered =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
2858: }
1.562 foxr 2859: my $junk;
1.305 sakharuk 2860: if ($remove_latex_header eq 'YES') {
2861: $rendered = &latex_header_footer_remove($rendered);
2862: } else {
2863: $rendered =~ s/\\end{document}//;
2864: }
2865: $current_output .= $rendered;
1.456 raeburn 2866: } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.568 foxr 2867: if ($i == 1) {
2868: $syllabus_first = 1;
2869: }
1.375 foxr 2870: $printed .= $curresline.':';
1.528 raeburn 2871: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.511 foxr 2872: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2873: my $url = &Apache::lonnet::clutter($res_url);
2874: my $annotation = &annotate($url);
2875: $annotation =~ s/(\\end{document})/$annotation$1/;
2876: }
1.305 sakharuk 2877: if ($remove_latex_header eq 'YES') {
2878: $rendered = &latex_header_footer_remove($rendered);
1.284 albertel 2879: } else {
1.305 sakharuk 2880: $rendered =~ s/\\end{document}//;
1.284 albertel 2881: }
1.421 foxr 2882: $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut ';
1.552 foxr 2883: } elsif($res_url = ~/\.pdf$/) {
2884: my $url = &Apache::lonnet::clutter($res_url);
2885: my $rendered = &include_pdf($url);
2886: if ($remove_latex_header ne 'NO') {
2887: $rendered = &latex_header_footer_remove($rendered);
2888: }
2889: $current_output .= $rendered;
1.284 albertel 2890: } else {
1.414 albertel 2891: my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline);
1.305 sakharuk 2892: if ($remove_latex_header ne 'NO') {
2893: $rendered = &latex_header_footer_remove($rendered);
2894: } else {
2895: $rendered =~ s/\\end{document}//;
2896: }
2897: $current_output .= $rendered;
1.284 albertel 2898: }
2899: }
2900: $remove_latex_header = 'YES';
1.550 foxr 2901: }
1.331 albertel 2902: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 2903: }
1.552 foxr 2904:
2905:
1.284 albertel 2906: my $courseidinfo = &get_course();
2907: my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header');
1.476 albertel 2908: my $header_line =
1.486 foxr 2909: &format_page_header($LaTeXwidth, $parmhash{'print_header_format'},
1.537 foxr 2910: $currentassignment, $courseidinfo, $fullname, $usersection);
1.476 albertel 2911: my $header_start = ($columns_in_format == 1) ? '\lhead'
2912: : '\fancyhead[LO]';
2913: $header_line = $header_start.'{'.$header_line.'}';
1.568 foxr 2914: if ($current_output=~/\\documentclass/ && (!$syllabus_first)) {
1.476 albertel 2915: $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent$header_line$namepostfix}\\vskip 5 mm /;
1.568 foxr 2916: } elsif ($syllabus_first) {
2917:
2918: $current_output =~ s/\\\\ Last updated:/Last updated:/
1.284 albertel 2919: } else {
1.476 albertel 2920: my $blankpages =
2921: '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
2922:
2923: $current_output = '\strut\vspace*{-6 mm}\\newline'.
2924: ©right_line().' \newpage '.$blankpages.$end_of_student.
2925: '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
2926: $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284 albertel 2927: }
1.440 foxr 2928: #
2929: # Close the student bracketing.
2930: #
1.375 foxr 2931: return ($current_output,$fullname, $printed);
1.284 albertel 2932:
2933: }
1.140 sakharuk 2934:
1.3 sakharuk 2935: sub handler {
2936:
2937: my $r = shift;
1.397 albertel 2938:
2939: &init_perm();
1.114 bowersj2 2940:
1.416 foxr 2941:
1.67 www 2942:
1.397 albertel 2943: my $helper = printHelper($r);
2944: if (!ref($helper)) {
2945: return $helper;
1.60 sakharuk 2946: }
1.177 sakharuk 2947:
1.184 sakharuk 2948:
1.454 foxr 2949: %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353 foxr 2950:
1.416 foxr 2951:
1.350 foxr 2952:
2953:
1.367 foxr 2954: # If a figure conversion queue file exists for this user.domain
2955: # we delete it since it can only be bad (if it were good, printout.pl
2956: # would have deleted it the last time around.
2957:
1.373 albertel 2958: my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367 foxr 2959: if(-e $conversion_queuefile) {
2960: unlink $conversion_queuefile;
2961: }
1.515 foxr 2962:
2963:
1.184 sakharuk 2964: &output_data($r,$helper,\%parmhash);
1.2 sakharuk 2965: return OK;
1.60 sakharuk 2966: }
1.2 sakharuk 2967:
1.131 bowersj2 2968: use Apache::lonhelper;
1.130 sakharuk 2969:
1.223 bowersj2 2970: sub addMessage {
2971: my $text = shift;
2972: my $paramHash = Apache::lonhelper::getParamHash();
2973: $paramHash->{MESSAGE_TEXT} = $text;
2974: Apache::lonhelper::message->new();
2975: }
2976:
1.416 foxr 2977:
1.238 bowersj2 2978:
1.397 albertel 2979: sub init_perm {
2980: undef(%perm);
2981: $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
2982: if (!$perm{'pav'}) {
2983: $perm{'pav'}=&Apache::lonnet::allowed('pav',
2984: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2985: }
1.465 albertel 2986: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397 albertel 2987: if (!$perm{'pfo'}) {
2988: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',
2989: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2990: }
2991: }
2992:
1.507 albertel 2993: sub get_randomly_ordered_warning {
2994: my ($helper,$map) = @_;
2995:
2996: my $message;
2997:
2998: my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
2999: my $navmap = Apache::lonnavmaps::navmap->new();
1.547 raeburn 3000: if (defined($navmap)) {
3001: my $res = $navmap->getResourceByUrl($map);
3002: if ($res) {
3003: my $func =
3004: sub { return ($_[0]->is_map() && $_[0]->randomorder); };
3005: my @matches = $navmap->retrieveResources($res, $func,1,1,1);
3006: if (@matches) {
3007: $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.";
3008: }
3009: }
3010: if ($message) {
3011: return '<message type="warning">'.$message.'</message>';
3012: }
3013: } else {
3014: $message = "Retrieval of information about ordering of resources failed.";
3015: return '<message type="warning">'.$message.'</message>';
1.507 albertel 3016: }
3017: return;
3018: }
3019:
1.131 bowersj2 3020: sub printHelper {
1.115 bowersj2 3021: my $r = shift;
3022:
3023: if ($r->header_only) {
1.373 albertel 3024: if ($env{'browser.mathml'}) {
1.241 www 3025: &Apache::loncommon::content_type($r,'text/xml');
1.131 bowersj2 3026: } else {
1.241 www 3027: &Apache::loncommon::content_type($r,'text/html');
1.131 bowersj2 3028: }
3029: $r->send_http_header;
3030: return OK;
1.115 bowersj2 3031: }
3032:
1.131 bowersj2 3033: # Send header, nocache
1.373 albertel 3034: if ($env{'browser.mathml'}) {
1.241 www 3035: &Apache::loncommon::content_type($r,'text/xml');
1.115 bowersj2 3036: } else {
1.241 www 3037: &Apache::loncommon::content_type($r,'text/html');
1.115 bowersj2 3038: }
3039: &Apache::loncommon::no_cache($r);
3040: $r->send_http_header;
3041: $r->rflush();
3042:
1.131 bowersj2 3043: # Unfortunately, this helper is so complicated we have to
3044: # write it by hand
3045:
3046: Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
3047:
1.176 bowersj2 3048: my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146 bowersj2 3049: $helper->declareVar('symb');
1.156 bowersj2 3050: $helper->declareVar('postdata');
1.290 sakharuk 3051: $helper->declareVar('curseed');
3052: $helper->declareVar('probstatus');
1.156 bowersj2 3053: $helper->declareVar('filename');
3054: $helper->declareVar('construction');
1.178 sakharuk 3055: $helper->declareVar('assignment');
1.262 sakharuk 3056: $helper->declareVar('style_file');
1.340 foxr 3057: $helper->declareVar('student_sort');
1.363 foxr 3058: $helper->declareVar('FINISHPAGE');
1.366 foxr 3059: $helper->declareVar('PRINT_TYPE');
1.372 foxr 3060: $helper->declareVar("showallfoils");
1.483 foxr 3061: $helper->declareVar("STUDENTS");
1.363 foxr 3062:
1.518 foxr 3063:
3064:
3065:
3066:
1.363 foxr 3067: # The page breaks can get loaded initially from the course environment:
1.394 foxr 3068: # But we only do this in the initial state so that they are allowed to change.
3069: #
1.366 foxr 3070:
1.416 foxr 3071: # $helper->{VARS}->{FINISHPAGE} = '';
1.363 foxr 3072:
3073: &Apache::loncommon::restore_course_settings('print',
1.366 foxr 3074: {'pagebreaks' => 'scalar',
3075: 'lastprinttype' => 'scalar'});
3076:
1.483 foxr 3077: # This will persistently load in the data we want from the
3078: # very first screen.
1.394 foxr 3079:
3080: if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
3081: if (!defined ($env{"form.CURRENT_STATE"})) {
3082:
3083: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
3084: } else {
3085: my $state = $env{"form.CURRENT_STATE"};
3086: if ($state eq "START") {
3087: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
3088: }
3089: }
3090:
1.366 foxr 3091: }
1.481 albertel 3092:
1.156 bowersj2 3093: # Detect whether we're coming from construction space
1.373 albertel 3094: if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235 bowersj2 3095: $helper->{VARS}->{'filename'} = "~$1/$2";
1.156 bowersj2 3096: $helper->{VARS}->{'construction'} = 1;
1.481 albertel 3097: } else {
1.373 albertel 3098: if ($env{'form.postdata'}) {
3099: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482 albertel 3100: if ( $helper->{VARS}->{'symb'} eq '') {
3101: $helper->{VARS}->{'postdata'} = $env{'form.postdata'};
3102: }
1.156 bowersj2 3103: }
1.373 albertel 3104: if ($env{'form.symb'}) {
3105: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156 bowersj2 3106: }
1.373 albertel 3107: if ($env{'form.url'}) {
1.156 bowersj2 3108: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
3109: }
1.416 foxr 3110:
1.157 bowersj2 3111: }
1.481 albertel 3112:
1.373 albertel 3113: if ($env{'form.symb'}) {
3114: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146 bowersj2 3115: }
1.373 albertel 3116: if ($env{'form.url'}) {
1.140 sakharuk 3117: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153 sakharuk 3118:
1.140 sakharuk 3119: }
1.343 albertel 3120: $helper->{VARS}->{'symb'}=
3121: &Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335 albertel 3122: my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178 sakharuk 3123: if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481 albertel 3124:
1.156 bowersj2 3125:
1.146 bowersj2 3126: # Extract map
3127: my $symb = $helper->{VARS}->{'symb'};
1.156 bowersj2 3128: my ($map, $id, $url);
3129: my $subdir;
1.483 foxr 3130: my $is_published=0; # True when printing from resource space.
1.156 bowersj2 3131:
3132: # Get the resource name from construction space
3133: if ($helper->{VARS}->{'construction'}) {
3134: $resourceTitle = substr($helper->{VARS}->{'filename'},
3135: rindex($helper->{VARS}->{'filename'}, '/')+1);
3136: $subdir = substr($helper->{VARS}->{'filename'},
3137: 0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481 albertel 3138: } else {
1.562 foxr 3139: # From course space:
3140:
1.482 albertel 3141: if ($symb ne '') {
3142: ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
3143: $helper->{VARS}->{'postdata'} =
3144: &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
3145: } else {
3146: $url = $helper->{VARS}->{'postdata'};
1.483 foxr 3147: $is_published=1; # From resource space.
1.482 albertel 3148: }
3149: $url = &Apache::lonnet::clutter($url);
1.156 bowersj2 3150: if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238 bowersj2 3151: my $postdata = $helper->{VARS}->{'postdata'};
3152: $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156 bowersj2 3153: }
3154: $subdir = &Apache::lonnet::filelocation("", $url);
1.128 bowersj2 3155: }
1.373 albertel 3156: if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
3157: $helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230 albertel 3158: }
1.373 albertel 3159: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
1.512 foxr 3160: $helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
1.290 sakharuk 3161: }
1.115 bowersj2 3162:
1.192 bowersj2 3163: my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
3164:
1.481 albertel 3165: Apache::lonhelper::registerHelperTags();
1.119 bowersj2 3166:
1.131 bowersj2 3167: # "Delete everything after the last slash."
1.119 bowersj2 3168: $subdir =~ s|/[^/]+$||;
3169:
1.131 bowersj2 3170: # What can be printed is a very dynamic decision based on
3171: # lots of factors. So we need to dynamically build this list.
3172: # To prevent security leaks, states are only added to the wizard
3173: # if they can be reached, which ensures manipulating the form input
3174: # won't allow anyone to reach states they shouldn't have permission
3175: # to reach.
3176:
3177: # printChoices is tracking the kind of printing the user can
3178: # do, and will be used in a choices construction later.
3179: # In the meantime we will be adding states and elements to
3180: # the helper by hand.
3181: my $printChoices = [];
3182: my $paramHash;
1.130 sakharuk 3183:
1.240 albertel 3184: if ($resourceTitle) {
1.458 www 3185: push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156 bowersj2 3186: }
3187:
1.238 bowersj2 3188: # Useful filter strings
1.540 raeburn 3189: my $isProblem = '($res->is_problem()||$res->contains_problem||$res->is_practice()) ';
1.238 bowersj2 3190: $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.541 raeburn 3191: my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice()';
1.287 albertel 3192: my $isNotMap = '!$res->is_sequence()';
1.238 bowersj2 3193: $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
3194: my $isMap = '$res->is_map()';
1.342 albertel 3195: my $symbFilter = '$res->shown_symb()';
3196: my $urlValue = '$res->link()';
1.238 bowersj2 3197:
3198: $helper->declareVar('SEQUENCE');
3199:
1.465 albertel 3200: # If we're in a sequence...
1.416 foxr 3201:
1.465 albertel 3202: my $start_new_option;
3203: if ($perm{'pav'}) {
3204: $start_new_option =
3205: "<option text='".&mt('Start new page<br />before selected').
3206: "' variable='FINISHPAGE' />";
3207: }
1.238 bowersj2 3208:
1.562 foxr 3209: # If not construction space user can print the components of a page:
3210:
3211: my $page_ispage;
3212: my $page_title;
3213: if (!$helper->{VARS}->{'construction'}) {
3214: my $varspostdata = $helper->{VARS}->{'postdata'};
3215: my $varsassignment = $helper->{VARS}->{'assignment'};
3216: my $page_navmap = Apache::lonnavmaps::navmap->new();
1.563 foxr 3217: if (defined($page_navmap)) {
3218: my @page_resources = $page_navmap->retrieveResources($url);
3219: if(defined($page_resources[0])) {
3220: $page_ispage = $page_resources[0]->is_page();
3221: $page_title = $page_resources[0]->title();
3222: my $resourcesymb = $page_resources[0]->symb();
3223: my ($pagemap, $pageid, $pageurl) = &Apache::lonnet::decode_symb($symb);
3224: if ($page_ispage) {
3225: push @{$printChoices},
3226: [&mt('Selected [_1]Problems[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'),
3227: 'map_problems_in_page',
3228: 'CHOOSE_PROBLEMS_PAGE'];
3229: push @{$printChoices},
3230: [&mt('Selected [_1]Resources[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'),
3231: 'map_resources_in_page',
3232: 'CHOOSE_RESOURCES_PAGE'];
3233: }
1.562 foxr 3234: my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS_PAGE',
3235: 'Select Problem(s) to print',
3236: "multichoice='1' toponly='1' addstatus='1' closeallpages='1'",
3237: 'RESOURCES',
3238: 'PAGESIZE',
3239: $url,
3240: $isProblem, '', $symbFilter,
3241: $start_new_option);
3242:
3243:
3244: $helperFragment .= &generate_resource_chooser('CHOOSE_RESOURCES_PAGE',
3245: 'Select Resource(s) to print',
3246: 'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
3247: 'RESOURCES',
3248: 'PAGESIZE',
3249: $url,
3250: $isNotMap, '', $symbFilter,
3251: $start_new_option);
3252:
3253:
3254:
3255:
3256:
3257: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
3258:
1.563 foxr 3259: }
3260: }
1.562 foxr 3261: }
3262:
3263: if (($helper->{'VAR'}->{'construction'} ne '1' ) &&
1.243 bowersj2 3264: $helper->{VARS}->{'postdata'} &&
3265: $helper->{VARS}->{'assignment'}) {
1.131 bowersj2 3266: # Allow problems from sequence
1.562 foxr 3267: push @{$printChoices},
3268: [&mt('Selected [_1]Problems[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'),
3269: 'map_problems',
3270: 'CHOOSE_PROBLEMS'];
1.131 bowersj2 3271: # Allow all resources from sequence
1.562 foxr 3272: push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'),
3273: 'map_problems_pages',
3274: 'CHOOSE_PROBLEMS_HTML'];
3275: my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS',
3276: 'Select Problem(s) to print',
3277: 'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
3278: 'RESOURCES',
3279: 'PAGESIZE',
3280: $map,
3281: $isProblem, '',
3282: $symbFilter,
3283: $start_new_option);
3284: $helperFragment .= &generate_resource_chooser('CHOOSE_PROBLEMS_HTML',
3285: 'Select Resource(s) to print',
3286: 'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
3287: 'RESOURCES',
3288: 'PAGESIZE',
3289: $map,
3290: $isNotMap, '',
3291: $symbFilter,
3292: $start_new_option);
1.121 bowersj2 3293:
1.326 sakharuk 3294: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121 bowersj2 3295: }
3296:
1.546 bisitz 3297: # If the user has pfo (print for others) allow them to print all
3298: # problems and resources in the entire course, optionally for selected students
1.562 foxr 3299: my $post_data = $helper->{VARS}->{'postdata'};
1.483 foxr 3300: if ($perm{'pfo'} && !$is_published &&
1.562 foxr 3301: ($post_data=~/\/res\// || $post_data =~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) {
1.481 albertel 3302:
1.509 albertel 3303: push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
3304: push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.536 foxr 3305: 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 3306: my $suffixXml = <<ALL_PROBLEMS;
1.536 foxr 3307: <state name="STUDENTS1" title="Select People">
3308: <message><b>Select sorting order of printout</b> </message>
3309: <choices variable='student_sort'>
3310: <choice computer='0'>Sort by section then student</choice>
3311: <choice computer='1'>Sort by students across sections.</choice>
3312: </choices>
3313: <message><br /><hr /><br /> </message>
3314: <student multichoice='1' variable="STUDENTS" nextstate="PRINT_FORMATTING" coursepersonnel="1"/>
3315: </state>
1.284 albertel 3316: ALL_PROBLEMS
1.562 foxr 3317: &Apache::lonxml::xmlparse($r, 'helper',
3318: &generate_resource_chooser('ALL_PROBLEMS',
3319: 'SelectProblem(s) to print',
3320: 'multichoice="1" suppressEmptySequences="0" addstatus="1" closeallpages="1"',
3321: 'RESOURCES',
3322: 'PAGESIZE',
3323: '',
3324: $isProblemOrMap, $isNotMap,
3325: $symbFilter,
3326: $start_new_option) .
3327: &generate_resource_chooser('ALL_RESOURCES',
3328: 'Select Resource(s) to print',
3329: " toponly='0' multichoice='1' suppressEmptySequences='0' addstatus='1' closeallpages='1'",
3330: 'RESOURCES',
3331: 'PAGESIZE',
3332: '',
3333: $isNotMap,'',$symbFilter,
3334: $start_new_option) .
3335: &generate_resource_chooser('ALL_PROBLEMS_STUDENTS',
3336: 'Select Problem(s) to print',
3337: 'toponly="0" multichoice="1" suppressEmptySequences="0" addstatus="1" closeallpages="1"',
3338: 'RESOURCES',
3339: 'STUDENTS1',
3340: '',
3341: $isProblemOrMap,'' , $symbFilter,
3342: $start_new_option) .
3343: $suffixXml
3344: );
1.132 bowersj2 3345:
1.284 albertel 3346: if ($helper->{VARS}->{'assignment'}) {
1.562 foxr 3347:
3348: # If we were looking at a page, allow a selection of problems from the page
3349: # either for selected students or for coded assignments.
3350:
3351: if ($page_ispage) {
3352: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from page [_3] for [_4]selected people[_5]',
3353: '<b>', '</b>', '<b><i>'.$page_title.'</i></b>', '<b>', '</b>'),
3354: 'problems_for_students_from_page', 'CHOOSE_TGT_STUDENTS_PAGE'];
3355: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from page [_3] for [_4]CODEd assignments[_5]',
3356: '<b>', '</b>', '<b><i>'.$page_title.'</i></b>', '<b>', '</b>'),
3357: 'problems_for_anon_page', 'CHOOSE_ANON1_PAGE'];
3358: }
3359: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]selected people[_5]',
3360: '<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'),
3361: 'problems_for_students', 'CHOOSE_STUDENTS'];
3362: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]CODEd assignments[_5]',
3363: '<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'),
3364: 'problems_for_anon', 'CHOOSE_ANON1'];
1.284 albertel 3365: }
1.424 foxr 3366:
1.507 albertel 3367: my $randomly_ordered_warning =
3368: &get_randomly_ordered_warning($helper,$map);
3369:
1.424 foxr 3370: # resource_selector will hold a few states that:
3371: # - Allow resources to be selected for printing.
3372: # - Determine pagination between assignments.
3373: # - Determine how many assignments should be bundled into a single PDF.
3374: # TODO:
3375: # Probably good to do things like separate this up into several vars, each
3376: # with one state, and use REGEXPs at inclusion time to set state names
3377: # and next states for better mix and match capability
3378: #
1.562 foxr 3379: my $resource_selector= &generate_resource_chooser('SELECT_PROBLEMS',
3380: 'Select resources to print',
3381: 'multichoice="1" addstatus="1" closeallpages="1"',
3382: 'RESOURCES',
3383: 'PRINT_FORMATTING',
1.568.2.1! raeburn 3384: $map,
1.562 foxr 3385: $isProblem, '', $symbFilter,
3386: $start_new_option);
3387: $resource_selector .= <<RESOURCE_SELECTOR;
1.424 foxr 3388: <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155 sakharuk 3389: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149 bowersj2 3390: <choices variable="EMPTY_PAGES">
1.204 sakharuk 3391: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
3392: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
3393: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
3394: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 3395: </choices>
1.424 foxr 3396: <nextstate>PAGESIZE</nextstate>
1.429 foxr 3397: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
3398: <choices variable="SPLIT_PDFS">
3399: <choice computer="all">All assignments in a single PDF file</choice>
3400: <choice computer="sections">Each PDF contains exactly one section</choice>
3401: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 3402: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
3403: Specify the number of assignments per PDF:</choice>
1.429 foxr 3404: </choices>
1.424 foxr 3405: </state>
1.284 albertel 3406: RESOURCE_SELECTOR
1.562 foxr 3407: $resource_selector .= &generate_resource_chooser('CHOOSE_STUDENTS_PAGE',
3408: 'Select Problem(s) to print',
3409: "multichoice='1' addstatus='1' closeallpages ='1'",
3410: 'RESOURCES',
3411: 'PRINT_FORMATTING',
3412: $url,
3413: $isProblem, '', $symbFilter,
3414: $start_new_option);
3415:
3416:
3417: # Generate student choosers.
3418:
3419:
1.284 albertel 3420:
1.562 foxr 3421: &Apache::lonxml::xmlparse($r, 'helper',
3422: &generate_student_chooser('CHOOSE_TGT_STUDENTS_PAGE',
3423: 'student_sort',
3424: 'STUDENTS',
3425: 'CHOOSE_STUDENTS_PAGE'));
3426: &Apache::lonxml::xmlparse($r, 'helper',
3427: &generate_student_chooser('CHOOSE_STUDENTS',
3428: 'student_sort',
3429: 'STUDENTS',
3430: 'SELECT_PROBLEMS'));
3431: &Apache::lonxml::xmlparse($r, 'helper', $resource_selector);
1.292 albertel 3432:
1.373 albertel 3433: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
3434: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292 albertel 3435: my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
3436: my $namechoice='<choice></choice>';
1.337 albertel 3437: foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294 albertel 3438: if ($name =~ /^error: 2 /) { next; }
1.381 albertel 3439: if ($name =~ /^type\0/) { next; }
1.292 albertel 3440: $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
3441: }
1.389 foxr 3442:
3443:
3444: my %code_values;
1.405 albertel 3445: my %codes_to_print;
1.411 albertel 3446: foreach my $key (@names) {
1.389 foxr 3447: %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405 albertel 3448: foreach my $key (keys(%code_values)) {
3449: $codes_to_print{$key} = 1;
1.388 foxr 3450: }
3451: }
1.389 foxr 3452:
1.452 albertel 3453: my $code_selection;
1.405 albertel 3454: foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389 foxr 3455: my $choice = $code;
3456: if ($code =~ /^[A-Z]+$/) { # Alpha code
3457: $choice = &letters_to_num($code);
3458: }
1.432 albertel 3459: push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388 foxr 3460: }
1.436 albertel 3461: if (%codes_to_print) {
3462: $code_selection .='
1.472 albertel 3463: <message><b>Choose single CODE from list:</b></message>
1.448 albertel 3464: <message></td><td></message>
1.452 albertel 3465: <dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
3466: <choice></choice>
1.448 albertel 3467: <exec>
3468: push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
3469: </exec>
1.452 albertel 3470: </dropdown>
1.468 foxr 3471: <message></td></tr><tr><td></message>
1.436 albertel 3472: '.$/;
1.448 albertel 3473:
1.436 albertel 3474: }
1.432 albertel 3475:
1.542 raeburn 3476: my @lines = &Apache::grades::get_scantronformat_file();
1.381 albertel 3477: my $codechoice='';
1.542 raeburn 3478: foreach my $line (@lines) {
1.381 albertel 3479: my ($name,$description,$code_type,$code_length)=
3480: (split(/:/,$line))[0,1,2,4];
3481: if ($code_length > 0 &&
3482: $code_type =~/^(letter|number|-1)/) {
3483: $codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
3484: }
3485: }
3486: if ($codechoice eq '') {
3487: $codechoice='<choice computer="default">Default</choice>';
3488: }
1.562 foxr 3489: my $anon1 = &generate_code_selector($helper,
3490: 'CHOOSE_ANON1',
3491: 'SELECT_PROBLEMS',
3492: $codechoice,
3493: $code_selection,
3494: $namechoice) . $resource_selector;
3495:
3496:
3497: &Apache::lonxml::xmlparse($r, 'helper',$anon1);
3498:
3499: my $anon_page = &generate_code_selector($helper,
3500: 'CHOOSE_ANON1_PAGE',
3501: 'SELECT_PROBLEMS_PAGE',
3502: $codechoice,
3503: $code_selection,
3504: $namechoice) .
3505: &generate_resource_chooser('SELECT_PROBLEMS_PAGE',
3506: 'Select Problem(s) to print',
3507: "multichoice='1' addstatus='1' closeallpages ='1'",
3508: 'RESOURCES',
3509: 'PRINT_FORMATTING',
3510: $url,
3511: $isProblem, '', $symbFilter,
3512: $start_new_option);
3513: &Apache::lonxml::xmlparse($r, 'helper', $anon_page);
1.254 sakharuk 3514:
1.272 sakharuk 3515:
1.254 sakharuk 3516: if ($helper->{VARS}->{'assignment'}) {
1.546 bisitz 3517: 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'];
3518: 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 3519: }
1.284 albertel 3520:
3521:
3522: $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 3523: <state name="SELECT_RESOURCES" title="Select Resources">
1.507 albertel 3524: $randomly_ordered_warning
1.424 foxr 3525: <nextstate>PRINT_FORMATTING</nextstate>
1.254 sakharuk 3526: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 3527: <resource variable="RESOURCES" multichoice="1" addstatus="1"
3528: closeallpages="1">
1.254 sakharuk 3529: <filterfunc>return $isNotMap;</filterfunc>
3530: <mapurl>$map</mapurl>
3531: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 3532: $start_new_option
1.254 sakharuk 3533: </resource>
1.424 foxr 3534: </state>
1.562 foxr 3535:
1.424 foxr 3536: <state name="PRINT_FORMATTING" title="Format of the print job">
3537: <nextstate>NUMBER_PER_PDF</nextstate>
1.254 sakharuk 3538: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
3539: <choices variable="EMPTY_PAGES">
3540: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
3541: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
3542: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
3543: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 3544: </choices>
1.424 foxr 3545: <nextstate>PAGESIZE</nextstate>
1.429 foxr 3546: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
3547: <choices variable="SPLIT_PDFS">
3548: <choice computer="all">All assignments in a single PDF file</choice>
3549: <choice computer="sections">Each PDF contains exactly one section</choice>
3550: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 3551: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
3552: Specify the number of assignments per PDF:</choice>
1.429 foxr 3553: </choices>
1.424 foxr 3554: </state>
1.284 albertel 3555: RESOURCE_SELECTOR
3556:
3557: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
3558: <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340 foxr 3559: <choices variable='student_sort'>
3560: <choice computer='0'>Sort by section then student</choice>
3561: <choice computer='1'>Sort by students across sections.</choice>
3562: </choices>
1.437 foxr 3563: <message><br /><hr /><br /></message>
1.426 foxr 3564: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340 foxr 3565:
1.424 foxr 3566: </state>
1.284 albertel 3567: $resource_selector
1.254 sakharuk 3568: CHOOSE_STUDENTS1
3569:
1.284 albertel 3570: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472 albertel 3571: <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424 foxr 3572: <nextstate>SELECT_RESOURCES</nextstate>
1.472 albertel 3573: <message><h4>Fill out one of the forms below</h4></message>
3574: <message><br /><hr /> <br /></message>
3575: <message><h3>Generate new CODEd Assignments</h3></message>
3576: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 3577: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
3578: <validator>
3579: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386 foxr 3580: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 3581: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
3582: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 3583: return "You need to specify the number of assignments to print";
3584: }
3585: return undef;
3586: </validator>
3587: </string>
3588: <message></td></tr><tr><td></message>
1.501 albertel 3589: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 3590: <message></td><td></message>
3591: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
3592: <message></td></tr><tr><td></message>
3593: <message><b>Bubble sheet type:</b></message>
3594: <message></td><td></message>
3595: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
3596: $codechoice
3597: </dropdown>
1.472 albertel 3598: <message></td></tr><tr><td></table></message>
3599: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
3600: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 3601: <string variable="SINGLE_CODE" size="10">
1.386 foxr 3602: <validator>
3603: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 3604: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
3605: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386 foxr 3606: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
3607: \$helper->{'VARS'}{'CODE_OPTION'});
3608: } else {
3609: return undef; # Other forces control us.
3610: }
3611: </validator>
3612: </string>
1.472 albertel 3613: <message></td></tr><tr><td></message>
1.432 albertel 3614: $code_selection
1.472 albertel 3615: <message></td></tr></table></message>
3616: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
3617: <message><b>Select saved CODEs:</b></message>
1.381 albertel 3618: <message></td><td></message>
1.294 albertel 3619: <dropdown variable="REUSE_OLD_CODES">
3620: $namechoice
3621: </dropdown>
1.412 albertel 3622: <message></td></tr></table></message>
1.424 foxr 3623: </state>
1.284 albertel 3624: $resource_selector
3625: CHOOSE_ANON2
1.481 albertel 3626: }
3627:
1.121 bowersj2 3628: # FIXME: That RE should come from a library somewhere.
1.483 foxr 3629: if (($perm{'pav'}
1.482 albertel 3630: && $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
3631: && (defined($helper->{'VARS'}->{'construction'})
3632: ||
3633: (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
3634: &&
3635: $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483 foxr 3636: ))
3637: && $helper->{VARS}->{'assignment'} eq ""
1.482 albertel 3638: ) {
3639: my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
1.546 bisitz 3640: 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 3641: my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482 albertel 3642: <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458 www 3643:
1.138 bowersj2 3644: <files variable="FILES" multichoice='1'>
1.144 bowersj2 3645: <nextstate>PAGESIZE</nextstate>
1.138 bowersj2 3646: <filechoice>return '$subdir';</filechoice>
1.139 bowersj2 3647: CHOOSE_FROM_SUBDIR
3648:
1.238 bowersj2 3649: # this is broken up because I really want interpolation above,
3650: # and I really DON'T want it below
1.139 bowersj2 3651: $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225 bowersj2 3652: <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
3653: $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131 bowersj2 3654: </filefilter>
1.138 bowersj2 3655: </files>
1.131 bowersj2 3656: </state>
3657: CHOOSE_FROM_SUBDIR
1.139 bowersj2 3658: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131 bowersj2 3659: }
1.238 bowersj2 3660:
3661: # Allow the user to select any sequence in the course, feed it to
3662: # another resource selector for that sequence
1.483 foxr 3663: if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509 albertel 3664: push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249 sakharuk 3665: 'select_sequences', 'CHOOSE_SEQUENCE'];
1.244 bowersj2 3666: my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
3667: #Escape apostrophes and backslashes for Perl
3668: $escapedSequenceName =~ s/\\/\\\\/g;
3669: $escapedSequenceName =~ s/'/\\'/g;
1.239 bowersj2 3670: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238 bowersj2 3671: <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
3672: <message>Select the sequence to print resources from:</message>
3673: <resource variable="SEQUENCE">
3674: <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
3675: <filterfunc>return \$res->is_sequence;</filterfunc>
3676: <valuefunc>return $urlValue;</valuefunc>
1.447 foxr 3677: <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391 foxr 3678: </choicefunc>
1.238 bowersj2 3679: </resource>
3680: </state>
3681: <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
3682: <message>(mark desired resources then click "next" button) <br /></message>
1.435 foxr 3683: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 3684: closeallpages="1">
1.238 bowersj2 3685: <nextstate>PAGESIZE</nextstate>
1.466 albertel 3686: <filterfunc>return $isNotMap</filterfunc>
1.244 bowersj2 3687: <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238 bowersj2 3688: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 3689: $start_new_option
1.238 bowersj2 3690: </resource>
3691: </state>
3692: CHOOSE_FROM_ANY_SEQUENCE
1.239 bowersj2 3693: }
1.481 albertel 3694:
1.131 bowersj2 3695: # Generate the first state, to select which resources get printed.
1.223 bowersj2 3696: Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131 bowersj2 3697: $paramHash = Apache::lonhelper::getParamHash();
1.155 sakharuk 3698: $paramHash->{MESSAGE_TEXT} = "";
1.131 bowersj2 3699: Apache::lonhelper::message->new();
3700: $paramHash = Apache::lonhelper::getParamHash();
3701: $paramHash->{'variable'} = 'PRINT_TYPE';
3702: $paramHash->{CHOICES} = $printChoices;
3703: Apache::lonhelper::choices->new();
1.161 bowersj2 3704:
1.223 bowersj2 3705: my $startedTable = 0; # have we started an HTML table yet? (need
3706: # to close it later)
3707:
1.397 albertel 3708: if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or
1.170 sakharuk 3709: ($helper->{VARS}->{'construction'} eq '1')) {
1.544 bisitz 3710: &addMessage('<br />'
3711: .'<h3>'.&mt('Print Options').'</h3>'
3712: .&Apache::lonhtmlcommon::start_pick_box()
3713: .&Apache::lonhtmlcommon::row_title(
3714: '<label for="ANSWER_TYPE_forminput">'
3715: .&mt('Print Answers')
3716: .'</label>'
3717: )
3718: );
1.161 bowersj2 3719: $paramHash = Apache::lonhelper::getParamHash();
1.162 sakharuk 3720: $paramHash->{'variable'} = 'ANSWER_TYPE';
3721: $helper->declareVar('ANSWER_TYPE');
1.161 bowersj2 3722: $paramHash->{CHOICES} = [
1.242 sakharuk 3723: ['Without Answers', 'yes'],
3724: ['With Answers', 'no'],
1.368 albertel 3725: ['Only Answers', 'only']
1.289 sakharuk 3726: ];
1.210 sakharuk 3727: Apache::lonhelper::dropdown->new();
1.544 bisitz 3728: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.223 bowersj2 3729: $startedTable = 1;
1.556 foxr 3730:
3731: #
3732: # Select font size.
3733: #
3734:
3735: $helper->declareVar('fontsize');
3736: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Font Size')));
3737: my $xmlfrag = << "FONT_SELECTION";
3738:
3739:
3740: <dropdown variable='fontsize' multichoice='0', allowempty='0'>
3741: <defaultvalue>
3742: return 'normalsize';
3743: </defaultvalue>
3744: <choice computer='tiny'>Tiny</choice>
3745: <choice computer='sub/superscriptsize'>Script Size</choice>
3746: <choice computer='footnotesize'>Footnote Size</choice>
3747: <choice computer='small'>Small</choice>
3748: <choice computer='normalsize'>Normal (default)</choice>
3749: <choice computer='large'>larger than normal</choice>
3750: <choice computer='Large'>Even larger than normal</choice>
3751: <choice computer='LARGE'>Still larger than normal</choice>
3752: <choice computer='huge'>huge font size</choice>
3753: <choice computer='Huge'>Largest possible size</choice>
3754: </dropdown>
3755: FONT_SELECTION
3756: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
3757: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.161 bowersj2 3758: }
1.209 sakharuk 3759:
1.397 albertel 3760: if ($perm{'pav'}) {
1.223 bowersj2 3761: if (!$startedTable) {
1.497 www 3762: addMessage("<hr width='33%' /><table><tr><td align='right'>".
3763: '<label for="LATEX_TYPE_forminput">'.
3764: &mt('LaTeX mode').
3765: "</label>: </td><td>");
1.223 bowersj2 3766: $startedTable = 1;
3767: } else {
1.544 bisitz 3768: &addMessage(&Apache::lonhtmlcommon::row_title(
3769: '<label for="LATEX_TYPE_forminput">'
3770: .&mt('LaTeX mode')
3771: .'</label>'
3772: )
3773: );
1.223 bowersj2 3774: }
1.203 sakharuk 3775: $paramHash = Apache::lonhelper::getParamHash();
3776: $paramHash->{'variable'} = 'LATEX_TYPE';
3777: $helper->declareVar('LATEX_TYPE');
3778: if ($helper->{VARS}->{'construction'} eq '1') {
3779: $paramHash->{CHOICES} = [
1.223 bowersj2 3780: ['standard LaTeX mode', 'standard'],
3781: ['LaTeX batchmode', 'batchmode'], ];
1.203 sakharuk 3782: } else {
3783: $paramHash->{CHOICES} = [
1.223 bowersj2 3784: ['LaTeX batchmode', 'batchmode'],
3785: ['standard LaTeX mode', 'standard'] ];
1.203 sakharuk 3786: }
1.210 sakharuk 3787: Apache::lonhelper::dropdown->new();
1.218 sakharuk 3788:
1.544 bisitz 3789: &addMessage(&Apache::lonhtmlcommon::row_closure()
3790: .&Apache::lonhtmlcommon::row_title(
3791: '<label for="TABLE_CONTENTS_forminput">'
3792: .&mt('Print Table of Contents')
3793: .'</label>'
3794: )
3795: );
1.209 sakharuk 3796: $paramHash = Apache::lonhelper::getParamHash();
3797: $paramHash->{'variable'} = 'TABLE_CONTENTS';
3798: $helper->declareVar('TABLE_CONTENTS');
3799: $paramHash->{CHOICES} = [
1.223 bowersj2 3800: ['No', 'no'],
3801: ['Yes', 'yes'] ];
1.210 sakharuk 3802: Apache::lonhelper::dropdown->new();
1.544 bisitz 3803: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.214 sakharuk 3804:
1.220 sakharuk 3805: if (not $helper->{VARS}->{'construction'}) {
1.545 bisitz 3806: &addMessage(&Apache::lonhtmlcommon::row_title(
3807: '<label for="TABLE_INDEX_forminput">'
3808: .&mt('Print Index')
3809: .'</label>'
3810: )
3811: );
1.220 sakharuk 3812: $paramHash = Apache::lonhelper::getParamHash();
3813: $paramHash->{'variable'} = 'TABLE_INDEX';
3814: $helper->declareVar('TABLE_INDEX');
3815: $paramHash->{CHOICES} = [
1.223 bowersj2 3816: ['No', 'no'],
3817: ['Yes', 'yes'] ];
1.220 sakharuk 3818: Apache::lonhelper::dropdown->new();
1.545 bisitz 3819: &addMessage(&Apache::lonhtmlcommon::row_closure());
3820: &addMessage(&Apache::lonhtmlcommon::row_title(
3821: '<label for="PRINT_DISCUSSIONS_forminput">'
3822: .&mt('Print Discussions')
3823: .'</label>'
3824: )
3825: );
1.309 sakharuk 3826: $paramHash = Apache::lonhelper::getParamHash();
3827: $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';
3828: $helper->declareVar('PRINT_DISCUSSIONS');
3829: $paramHash->{CHOICES} = [
3830: ['No', 'no'],
3831: ['Yes', 'yes'] ];
3832: Apache::lonhelper::dropdown->new();
1.545 bisitz 3833: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.372 foxr 3834:
1.511 foxr 3835: # Prompt for printing annotations too.
3836:
1.545 bisitz 3837: &addMessage(&Apache::lonhtmlcommon::row_title(
3838: '<label for="PRINT_ANNOTATIONS_forminput">'
3839: .&mt('Print Annotations')
3840: .'</label>'
3841: )
3842: );
1.511 foxr 3843: $paramHash = Apache::lonhelper::getParamHash();
3844: $paramHash->{'variable'} = "PRINT_ANNOTATIONS";
3845: $helper->declareVar("PRINT_ANNOTATIONS");
3846: $paramHash->{CHOICES} = [
3847: ['No', 'no'],
3848: ['Yes', 'yes']];
3849: Apache::lonhelper::dropdown->new();
1.545 bisitz 3850: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.511 foxr 3851:
1.545 bisitz 3852: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Foils')));
1.397 albertel 3853: $paramHash = Apache::lonhelper::getParamHash();
3854: $paramHash->{'multichoice'} = "true";
3855: $paramHash->{'allowempty'} = "true";
3856: $paramHash->{'variable'} = "showallfoils";
1.555 bisitz 3857: $paramHash->{'CHOICES'} = [ [&mt('Show All Foils'), "1"] ];
1.397 albertel 3858: Apache::lonhelper::choices->new();
1.545 bisitz 3859: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.220 sakharuk 3860: }
1.219 sakharuk 3861:
1.230 albertel 3862: if ($helper->{'VARS'}->{'construction'}) {
1.505 albertel 3863: my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497 www 3864: my $randseedtext=&mt("Use random seed");
3865: my $stylefiletext=&mt("Use style file");
1.506 albertel 3866: my $selectfiletext=&mt("Select style file");
1.497 www 3867:
1.544 bisitz 3868: my $xmlfrag .= '<message>'
3869: .&Apache::lonhtmlcommon::row_title('<label for="curseed_forminput">'
3870: .$randseedtext
3871: .'</label>'
3872: )
3873: .'</message>
3874: <string variable="curseed" size="15" maxlength="15">
3875: <defaultvalue>
3876: return '.$helper->{VARS}->{'curseed'}.';
3877: </defaultvalue>'
3878: .'</string>'
3879: .'<message>'
3880: .&Apache::lonhtmlcommon::row_closure()
3881: .&Apache::lonhtmlcommon::row_title('<label for="style_file">'
3882: .$stylefiletext
3883: .'</label>'
3884: )
3885: .'</message>
1.504 albertel 3886: <string variable="style_file" size="40">
1.544 bisitz 3887: <defaultvalue>
3888: return '.$stylevalue.';
3889: </defaultvalue>
3890: </string><message> '
3891: .qq|<a href="javascript:openbrowser('helpform','style_file_forminput','sty')">|
3892: .$selectfiletext.'</a>'
3893: .&Apache::lonhtmlcommon::row_closure()
1.555 bisitz 3894: .&Apache::lonhtmlcommon::row_title(&mt('Show All Foils'))
1.544 bisitz 3895: .'</message>
1.371 foxr 3896: <choices allowempty="1" multichoice="true" variable="showallfoils">
1.544 bisitz 3897: <choice computer="1"> </choice>
3898: </choices>'
3899: .'<message>'
3900: .&Apache::lonhtmlcommon::row_closure()
3901: .'</message>';
1.230 albertel 3902: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.512 foxr 3903:
3904:
1.544 bisitz 3905: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Problem Type')));
1.512 foxr 3906: #
3907: # Initial value from construction space:
3908: #
3909: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
3910: $helper->{VARS}->{'probstatus'} = $env{'form.problemtype'}; # initial value
3911: }
1.518 foxr 3912: $xmlfrag = << "PROBTYPE";
3913: <dropdown variable="probstatus" multichoice="0" allowempty="0">
3914: <defaultvalue>
3915: return "$helper->{VARS}->{'probstatus'}";
3916: </defaultvalue>
3917: <choice computer="problem">Homework Problem</choice>
3918: <choice computer="exam">Exam Problem</choice>
3919: <choice computer="survey">Survey question</choice>
3920: </dropdown>
3921: PROBTYPE
3922: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.544 bisitz 3923: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.512 foxr 3924:
1.556 foxr 3925:
3926:
1.544 bisitz 3927: }
1.223 bowersj2 3928: }
1.264 sakharuk 3929:
3930:
3931:
1.218 sakharuk 3932:
1.223 bowersj2 3933: if ($startedTable) {
1.544 bisitz 3934: &addMessage(&Apache::lonhtmlcommon::end_pick_box());
1.215 sakharuk 3935: }
1.161 bowersj2 3936:
1.131 bowersj2 3937: Apache::lonprintout::page_format_state->new("FORMAT");
3938:
1.144 bowersj2 3939: # Generate the PAGESIZE state which will offer the user the margin
3940: # choices if they select one column
3941: Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
3942: Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
3943:
3944:
1.131 bowersj2 3945: $helper->process();
3946:
1.416 foxr 3947:
1.131 bowersj2 3948: # MANUAL BAILOUT CONDITION:
3949: # If we're in the "final" state, bailout and return to handler
3950: if ($helper->{STATE} eq 'FINAL') {
3951: return $helper;
3952: }
1.130 sakharuk 3953:
1.131 bowersj2 3954: $r->print($helper->display());
1.395 www 3955: if ($helper->{STATE} eq 'START') {
3956: &recently_generated($r);
3957: }
1.333 albertel 3958: &Apache::lonhelper::unregisterHelperTags();
1.115 bowersj2 3959:
3960: return OK;
3961: }
3962:
1.1 www 3963:
3964: 1;
1.119 bowersj2 3965:
3966: package Apache::lonprintout::page_format_state;
3967:
3968: =pod
3969:
1.131 bowersj2 3970: =head1 Helper element: page_format_state
3971:
3972: See lonhelper.pm documentation for discussion of the helper framework.
1.119 bowersj2 3973:
1.131 bowersj2 3974: Apache::lonprintout::page_format_state is an element that gives the
3975: user an opportunity to select the page layout they wish to print
3976: with: Number of columns, portrait/landscape, and paper size. If you
3977: want to change the paper size choices, change the @paperSize array
3978: contents in this package.
1.119 bowersj2 3979:
1.131 bowersj2 3980: page_format_state is always directly invoked in lonprintout.pm, so there
3981: is no tag interface. You actually pass parameters to the constructor.
1.119 bowersj2 3982:
3983: =over 4
3984:
1.131 bowersj2 3985: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119 bowersj2 3986:
3987: =back
3988:
3989: =cut
3990:
1.131 bowersj2 3991: use Apache::lonhelper;
1.119 bowersj2 3992:
3993: no strict;
1.131 bowersj2 3994: @ISA = ("Apache::lonhelper::element");
1.119 bowersj2 3995: use strict;
1.266 sakharuk 3996: use Apache::lonlocal;
1.373 albertel 3997: use Apache::lonnet;
1.119 bowersj2 3998:
3999: my $maxColumns = 2;
1.376 albertel 4000: # it'd be nice if these all worked
4001: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
4002: # "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
4003: # "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]",
4004: # "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326 sakharuk 4005: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
1.376 albertel 4006: "a4 [210x297 mm]");
1.119 bowersj2 4007:
4008: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
4009: # Paper type
4010:
4011: sub new {
1.131 bowersj2 4012: my $self = Apache::lonhelper::element->new();
1.119 bowersj2 4013:
1.135 bowersj2 4014: shift;
4015:
1.131 bowersj2 4016: $self->{'variable'} = shift;
1.134 bowersj2 4017: my $helper = Apache::lonhelper::getHelper();
1.135 bowersj2 4018: $helper->declareVar($self->{'variable'});
1.131 bowersj2 4019: bless($self);
1.119 bowersj2 4020: return $self;
4021: }
4022:
4023: sub render {
4024: my $self = shift;
1.131 bowersj2 4025: my $helper = Apache::lonhelper::getHelper();
1.119 bowersj2 4026: my $result = '';
1.131 bowersj2 4027: my $var = $self->{'variable'};
1.266 sakharuk 4028: my $PageLayout=&mt('Page layout');
4029: my $NumberOfColumns=&mt('Number of columns');
4030: my $PaperType=&mt('Paper type');
1.506 albertel 4031: my $landscape=&mt('Landscape');
4032: my $portrait=&mt('Portrait');
1.539 onken 4033: my $pdfFormLabel=&mt('PDF-Formfields');
4034: my $with=&mt('with Formfields');
4035: my $without=&mt('without Formfields');
1.556 foxr 4036:
4037:
1.544 bisitz 4038: $result.='<h3>'.&mt('Layout Options').'</h3>'
4039: .&Apache::loncommon::start_data_table()
4040: .&Apache::loncommon::start_data_table_header_row()
4041: .'<th>'.$PageLayout.'</th>'
4042: .'<th>'.$NumberOfColumns.'</th>'
4043: .'<th>'.$PaperType.'</th>'
4044: .'<th>'.$pdfFormLabel.'</th>'
4045: .&Apache::loncommon::end_data_table_header_row()
4046: .&Apache::loncommon::start_data_table_row()
4047: .'<td>'
4048: .'<label><input type="radio" name="'.${var}.'.layout" value="L" />'.$landscape.'</label><br />'
4049: .'<label><input type="radio" name="'.${var}.'.layout" value="P" checked="checked" />'.$portrait.'</label>'
4050: .'</td>';
1.119 bowersj2 4051:
1.544 bisitz 4052: $result.='<td align="center">'
4053: .'<select name="'.${var}.'.cols">';
1.119 bowersj2 4054:
4055: my $i;
4056: for ($i = 1; $i <= $maxColumns; $i++) {
1.144 bowersj2 4057: if ($i == 2) {
1.553 bisitz 4058: $result .= '<option value="'.$i.'" selected="selected">'.$i.'</option>'."\n";
1.119 bowersj2 4059: } else {
1.553 bisitz 4060: $result .= '<option value="'.$i.'">'.$i.'</option>'."\n";
1.119 bowersj2 4061: }
4062: }
4063:
4064: $result .= "</select></td><td>\n";
4065: $result .= "<select name='${var}.paper'>\n";
4066:
1.373 albertel 4067: my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398 albertel 4068: my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
4069: $DefaultPaperSize=~s/\s//g;
1.304 sakharuk 4070: if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119 bowersj2 4071: $i = 0;
4072: foreach (@paperSize) {
1.326 sakharuk 4073: $_=~/(\w+)/;
4074: my $papersize=$1;
1.304 sakharuk 4075: if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.553 bisitz 4076: $result .= '<option selected="selected" value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119 bowersj2 4077: } else {
1.553 bisitz 4078: $result .= '<option value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119 bowersj2 4079: }
4080: $i++;
4081: }
1.539 onken 4082: $result .= <<HTML;
4083: </select>
4084: </td>
4085: <td align='center'>
4086: <select name='${var}.pdfFormFields'>
1.553 bisitz 4087: <option selected="selected" value="no">$without</option>
4088: <option value="yes">$with</option>
1.539 onken 4089: </select>
4090: </td>
4091: HTML
1.544 bisitz 4092: $result.=&Apache::loncommon::end_data_table_row()
4093: .&Apache::loncommon::end_data_table();
1.539 onken 4094:
1.119 bowersj2 4095: return $result;
1.135 bowersj2 4096: }
4097:
4098: sub postprocess {
4099: my $self = shift;
4100:
4101: my $var = $self->{'variable'};
1.136 bowersj2 4102: my $helper = Apache::lonhelper->getHelper();
1.135 bowersj2 4103: $helper->{VARS}->{$var} =
1.373 albertel 4104: $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
1.539 onken 4105: $env{"form.$var.paper"} . '|' . $env{"form.$var.pdfFormFields"};
1.135 bowersj2 4106: return 1;
1.119 bowersj2 4107: }
4108:
4109: 1;
1.144 bowersj2 4110:
4111: package Apache::lonprintout::page_size_state;
4112:
4113: =pod
4114:
4115: =head1 Helper element: page_size_state
4116:
4117: See lonhelper.pm documentation for discussion of the helper framework.
4118:
4119: Apache::lonprintout::page_size_state is an element that gives the
4120: user the opportunity to further refine the page settings if they
4121: select a single-column page.
4122:
4123: page_size_state is always directly invoked in lonprintout.pm, so there
4124: is no tag interface. You actually pass parameters to the constructor.
4125:
4126: =over 4
4127:
4128: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
4129:
4130: =back
4131:
4132: =cut
4133:
4134: use Apache::lonhelper;
1.373 albertel 4135: use Apache::lonnet;
1.144 bowersj2 4136: no strict;
4137: @ISA = ("Apache::lonhelper::element");
4138: use strict;
4139:
4140:
4141:
4142: sub new {
4143: my $self = Apache::lonhelper::element->new();
4144:
4145: shift; # disturbs me (probably prevents subclassing) but works (drops
4146: # package descriptor)... - Jeremy
4147:
4148: $self->{'variable'} = shift;
4149: my $helper = Apache::lonhelper::getHelper();
4150: $helper->declareVar($self->{'variable'});
4151:
4152: # The variable name of the format element, so we can look into
4153: # $helper->{VARS} to figure out whether the columns are one or two
4154: $self->{'formatvar'} = shift;
4155:
1.463 foxr 4156:
1.144 bowersj2 4157: $self->{NEXTSTATE} = shift;
4158: bless($self);
1.467 foxr 4159:
1.144 bowersj2 4160: return $self;
4161: }
4162:
4163: sub render {
4164: my $self = shift;
4165: my $helper = Apache::lonhelper::getHelper();
4166: my $result = '';
4167: my $var = $self->{'variable'};
4168:
1.467 foxr 4169:
4170:
1.144 bowersj2 4171: if (defined $self->{ERROR_MSG}) {
1.464 albertel 4172: $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144 bowersj2 4173: }
4174:
1.438 foxr 4175: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463 foxr 4176:
4177: # Use format to get sensible defaults for the margins:
4178:
4179:
4180: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
4181: ($papersize) = split(/ /, $papersize);
4182:
1.559 foxr 4183: $laystyle = &Apache::lonprintout::map_laystyle($laystyle);
1.463 foxr 4184:
4185:
4186:
1.464 albertel 4187: my %size;
4188: ($size{'width_and_units'},
4189: $size{'height_and_units'},
4190: $size{'margin_and_units'})=
4191: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463 foxr 4192:
1.464 albertel 4193: foreach my $dimension ('width','height','margin') {
4194: ($size{$dimension},$size{$dimension.'_unit'}) =
4195: split(/ +/, $size{$dimension.'_and_units'},2);
4196:
4197: foreach my $unit ('cm','in') {
4198: $size{$dimension.'_options'} .= '<option ';
4199: if ($size{$dimension.'_unit'} eq $unit) {
4200: $size{$dimension.'_options'} .= 'selected="selected" ';
4201: }
4202: $size{$dimension.'_options'} .= '>'.$unit.'</option>';
4203: }
1.438 foxr 4204: }
4205:
1.470 foxr 4206: # Adjust margin for LaTeX margin: .. requires units == cm or in.
4207:
4208: if ($size{'margin_unit'} eq 'in') {
4209: $size{'margin'} += 1;
4210: } else {
4211: $size{'margin'} += 2.54;
4212: }
1.548 bisitz 4213: my %lt = &Apache::lonlocal::texthash(
4214: 'format' => 'How should each column be formatted?',
4215: 'width' => 'Width',
4216: 'height' => 'Height',
4217: 'margin' => 'Left Margin'
4218: );
4219:
4220: $result .= '<p>'.$lt{'format'}.'</p>'
4221: .&Apache::lonhtmlcommon::start_pick_box()
4222: .&Apache::lonhtmlcommon::row_title($lt{'width'})
4223: .'<input type="text" name="'.$var.'.width" value="'.$size{'width'}.'" size="4" />'
4224: .'<select name="'.$var.'.widthunit">'
4225: .$size{'width_options'}
4226: .'</select>'
4227: .&Apache::lonhtmlcommon::row_closure()
4228: .&Apache::lonhtmlcommon::row_title($lt{'height'})
4229: .'<input type="text" name="'.$var.'.height" value="'.$size{'height'}.'" size="4" />'
4230: .'<select name="'.$var.'.heightunit">'
4231: .$size{'height_options'}
4232: .'</select>'
4233: .&Apache::lonhtmlcommon::row_closure()
4234: .&Apache::lonhtmlcommon::row_title($lt{'margin'})
4235: .'<input type="text" name="'.$var.'.lmargin" value="'.$size{'margin'}.'" size="4" />'
4236: .'<select name="'.$var.'.lmarginunit">'
4237: .$size{'margin_options'}
4238: .'</select>'
4239: .&Apache::lonhtmlcommon::row_closure(1)
4240: .&Apache::lonhtmlcommon::end_pick_box();
4241: # <p>Hint: Some instructors like to leave scratch space for the student by
4242: # making the width much smaller than the width of the page.</p>
1.144 bowersj2 4243:
4244: return $result;
4245: }
4246:
1.470 foxr 4247:
1.144 bowersj2 4248: sub preprocess {
4249: my $self = shift;
4250: my $helper = Apache::lonhelper::getHelper();
4251:
4252: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467 foxr 4253:
4254: # If the user does not have 'pav' privilege, set default widths and
4255: # on to the next state right away.
4256: #
4257: if (!$perm{'pav'}) {
4258: my $var = $self->{'variable'};
4259: my $format = $helper->{VARS}->{$self->{'formatvar'}};
4260:
4261: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
4262: ($papersize) = split(/ /, $papersize);
4263:
4264:
1.560 foxr 4265: $laystyle = &Apache::lonprintout::map_laystyle($laystyle);
1.559 foxr 4266:
1.467 foxr 4267: # Figure out some good defaults for the print out and set them:
4268:
4269: my %size;
4270: ($size{'width'},
4271: $size{'height'},
4272: $size{'lmargin'})=
4273: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
4274:
4275: foreach my $dim ('width', 'height', 'lmargin') {
4276: my ($value, $units) = split(/ /, $size{$dim});
1.470 foxr 4277:
1.467 foxr 4278: $helper->{VARS}->{"$var.".$dim} = $value;
4279: $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
4280:
4281: }
4282:
4283:
4284: # Transition to the next state
4285:
4286: $helper->changeState($self->{NEXTSTATE});
4287: }
1.144 bowersj2 4288:
4289: return 1;
4290: }
4291:
4292: sub postprocess {
4293: my $self = shift;
4294:
4295: my $var = $self->{'variable'};
4296: my $helper = Apache::lonhelper->getHelper();
1.373 albertel 4297: my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"};
4298: my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"};
4299: my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"};
4300: $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"};
4301: $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"};
4302: $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"};
1.144 bowersj2 4303:
4304: my $error = '';
4305:
4306: # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed
4307: # by an optional period, followed by digits, ending the string
4308:
1.464 albertel 4309: if ($width !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 4310: $error .= "Invalid width; please type only a number.<br />\n";
4311: }
1.464 albertel 4312: if ($height !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 4313: $error .= "Invalid height; please type only a number.<br />\n";
4314: }
1.464 albertel 4315: if ($lmargin !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 4316: $error .= "Invalid left margin; please type only a number.<br />\n";
1.470 foxr 4317: } else {
4318: # Adjust for LaTeX 1.0 inch margin:
4319:
4320: if ($env{"form.${var}.lmarginunit"} eq "in") {
4321: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
4322: } else {
4323: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
4324: }
1.144 bowersj2 4325: }
4326:
4327: if (!$error) {
4328: Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
4329: return 1;
4330: } else {
4331: $self->{ERROR_MSG} = $error;
4332: return 0;
4333: }
4334: }
4335:
4336:
1.119 bowersj2 4337:
1.1 www 4338: __END__
1.6 sakharuk 4339:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>