Annotation of loncom/interface/lonprintout.pm, revision 1.566
1.562 foxr 1: #
1.389 foxr 2: # The LearningOnline Network
1.1 www 3: # Printout
4: #
1.566 ! foxr 5: # $Id: lonprintout.pm,v 1.565 2009/11/17 11:32:23 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.564 foxr 2122: my $texversion = &print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
2123: $texversion .= &ssi_with_retries($currentURL, $ssi_retry_count, %form);
1.511 foxr 2124: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2125: my $annotation = &annotate($currentURL);
2126: $texversion =~ s/(\\end{document})/$annotation$1/;
2127: }
1.258 sakharuk 2128: $result .= $texversion;
1.550 foxr 2129: } elsif ($cleanURL =~/\.tex$/) {
1.498 foxr 2130: # For this sort of print of a single LaTeX file,
2131: # We can just print the LaTeX file as it is uninterpreted in any way:
2132: #
2133:
2134: $result = &fetch_raw_resource($currentURL);
1.511 foxr 2135: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2136: my $annotation = &annotate($currentURL);
2137: $result =~ s/(\\end{document})/$annotation$1/;
2138: }
2139:
1.499 foxr 2140: $do_postprocessing = 0; # Don't massage the result.
1.498 foxr 2141:
1.550 foxr 2142: } elsif ($cleanURL =~ /\.pdf$/i) {
2143: $result .= &include_pdf($cleanURL);
1.551 foxr 2144: $result .= '\end{document}';
1.559 foxr 2145: } elsif ($cleanURL =~ /\.page$/i) { # Print page in non construction space contexts.
2146:
2147: # Determine the set of resources in the map of the page:
2148:
2149: my $navmap = Apache::lonnavmaps::navmap->new();
2150: my @page_resources = $navmap->retrieveResources($cleanURL);
2151: $result .= &print_page_in_course($helper, $rparmhash,
2152: $cleanURL, \@page_resources);
2153:
2154:
1.162 sakharuk 2155: } else {
1.559 foxr 2156: &Apache::lonnet::logthis("Unsupported type handler");
1.414 albertel 2157: $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'},
2158: $helper->{'VARS'}->{'symb'});
1.162 sakharuk 2159: }
1.354 foxr 2160: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') or
1.562 foxr 2161: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_in_page') or
2162: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_resources_in_page') or
1.142 sakharuk 2163: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or
1.354 foxr 2164: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') or
2165: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') or # BUGBUG
1.536 foxr 2166: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences')
2167: ) {
1.511 foxr 2168:
2169:
1.141 sakharuk 2170: #-- produce an output string
1.562 foxr 2171: if (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') or
2172: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_in_page') ) {
1.296 sakharuk 2173: $selectionmade = 2;
1.562 foxr 2174: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or
2175: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_resources_in_page'))
2176: {
1.296 sakharuk 2177: $selectionmade = 3;
1.536 foxr 2178: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems')
2179: ) {
1.296 sakharuk 2180: $selectionmade = 4;
1.354 foxr 2181: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') { #BUGBUG
2182: $selectionmade = 4;
1.296 sakharuk 2183: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') {
2184: $selectionmade = 7;
2185: }
1.193 sakharuk 2186: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.310 sakharuk 2187: $form{'suppress_tries'}=$parmhash{'suppress_tries'};
1.203 sakharuk 2188: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.309 sakharuk 2189: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 2190: $form{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
2191: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
2192: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') ) {
2193: $form{'problem_split'}='yes';
2194: }
1.141 sakharuk 2195: my $flag_latex_header_remove = 'NO';
2196: my $flag_page_in_sequence = 'NO';
2197: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.193 sakharuk 2198: my $prevassignment='';
1.428 albertel 2199:
2200: &Apache::lonxml::clear_problem_counter();
2201:
1.416 foxr 2202: my $pbreakresources = keys %page_breaks;
1.141 sakharuk 2203: for (my $i=0;$i<=$#master_seq;$i++) {
1.350 foxr 2204:
1.521 foxr 2205: &Apache::lonenc::reset_enc();
2206:
2207:
1.350 foxr 2208: # Note due to document structure, not allowed to put \newpage
2209: # prior to the first resource
2210:
1.351 foxr 2211: if (defined $page_breaks{$master_seq[$i]}) {
1.350 foxr 2212: if($i != 0) {
2213: $result.="\\newpage\n";
2214: }
2215: }
1.564 foxr 2216: my ($sequence,$middle_thingy,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]);
1.237 albertel 2217: $urlp=&Apache::lonnet::clutter($urlp);
1.166 albertel 2218: $form{'symb'}=$master_seq[$i];
1.407 albertel 2219:
2220: my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem
1.521 foxr 2221:
1.267 sakharuk 2222: if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;}
1.247 sakharuk 2223: if ($i==0) {$prevassignment=$assignment;}
1.297 sakharuk 2224: my $texversion='';
1.413 albertel 2225: if ($urlp!~m|^/adm/|
2226: && $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 2227: $resources_printed .= $urlp.':';
1.428 albertel 2228: &Apache::lonxml::remember_problem_counter();
1.566 ! foxr 2229: if ($flag_latex_header_remove eq 'NO') {
! 2230: $texversion.=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); # RF
! 2231: $flag_latex_header_remove = 'YES';
! 2232: }
1.515 foxr 2233: $texversion.=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.296 sakharuk 2234: if ($urlp=~/\.page$/) {
2235: ($texversion,my $number_of_columns_page) = &page_cleanup($texversion);
2236: if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;}
2237: $texversion =~ s/\\end{document}\d*/\\end{document}/;
2238: $flag_page_in_sequence = 'YES';
2239: }
1.428 albertel 2240:
1.296 sakharuk 2241: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
2242: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2243: # Don't permanently pervert the %form hash
2244: my %answerform = %form;
2245: $answerform{'grade_target'}='answer';
2246: $answerform{'answer_output_mode'}='tex';
1.375 foxr 2247: $resources_printed .= $urlp.':';
1.428 albertel 2248:
2249: &Apache::lonxml::restore_problem_counter();
1.515 foxr 2250: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.428 albertel 2251:
1.296 sakharuk 2252: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2253: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
1.249 sakharuk 2254: } else {
1.307 sakharuk 2255: if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) {
1.296 sakharuk 2256: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.552 foxr 2257: $texversion =~ s/\\begin{document}//;
1.477 albertel 2258: my $title = &Apache::lonnet::gettitle($master_seq[$i]);
2259: $title = &Apache::lonxml::latex_special_symbols($title);
2260: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
1.423 foxr 2261: $body .= &path_to_problem ($urlp,$LaTeXwidth);
2262: $body .='\vskip 1 mm '.$answer;
2263: $body = &encapsulate_minipage($body);
2264: $texversion .= $body;
1.296 sakharuk 2265: } else {
2266: $texversion='';
2267: }
1.249 sakharuk 2268: }
1.511 foxr 2269:
1.246 sakharuk 2270: }
1.511 foxr 2271: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2272: my $annotation .= &annotate($urlp);
2273: $texversion =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
2274: }
2275:
1.296 sakharuk 2276: if ($flag_latex_header_remove ne 'NO') {
2277: $texversion = &latex_header_footer_remove($texversion);
2278: } else {
2279: $texversion =~ s/\\end{document}//;
2280: }
2281: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
2282: $texversion=&IndexCreation($texversion,$urlp);
2283: }
2284: if (($selectionmade == 4) and ($assignment ne $prevassignment)) {
2285: my $name = &get_name();
2286: my $courseidinfo = &get_course();
2287: $prevassignment=$assignment;
1.455 albertel 2288: my $header_text = $parmhash{'print_header_format'};
1.486 foxr 2289: $header_text = &format_page_header($textwidth, $header_text,
1.455 albertel 2290: $assignment,
2291: $courseidinfo,
2292: $name);
1.552 foxr 2293:
1.417 foxr 2294: if ($numberofcolumns eq '1') {
1.455 albertel 2295: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{'.$header_text.'}} \vskip 5 mm ';
1.416 foxr 2296: } else {
1.455 albertel 2297: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\fancyhead[LO]{'.$header_text.'}} \vskip 5 mm ';
1.416 foxr 2298: }
1.296 sakharuk 2299: }
2300: $result .= $texversion;
2301: $flag_latex_header_remove = 'YES';
1.456 raeburn 2302: } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
1.301 sakharuk 2303: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
2304: if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;}
1.375 foxr 2305: $resources_printed .= $urlp.':';
1.564 foxr 2306: my $texversion = &print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
2307: $texversion .= &ssi_with_retries($urlp, $ssi_retry_count, %form);
1.511 foxr 2308: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2309: my $annotation = &annotate($urlp);
2310: $texversion =~ s/(\\end{document)/$annotation$1/;
2311: }
2312:
1.301 sakharuk 2313: if ($flag_latex_header_remove ne 'NO') {
2314: $texversion = &latex_header_footer_remove($texversion);
1.550 foxr 2315: } else {
1.301 sakharuk 2316: $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/;
2317: }
2318: $result .= $texversion;
2319: $flag_latex_header_remove = 'YES';
1.550 foxr 2320: } elsif ($urlp=~ /\.pdf$/i) {
2321: if ($i > 0) {
2322: $result .= '\cleardoublepage';
2323: }
2324: $result .= &include_pdf($urlp);
2325: if ($i != $#master_seq) {
2326: if ($numberofcolumns eq '1') {
2327: $result .= '\newpage';
2328: } else {
2329: # the \\'s seem to be needed to let LaTeX know there's something
2330: # on the page since LaTeX seems to not like to clear an empty page.
2331: #
2332: $result .= '\\ \cleardoublepage';
2333: }
2334: }
2335: $flag_latex_header_remove = 'YES';
2336:
1.141 sakharuk 2337: } else {
1.414 albertel 2338: $texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'},
2339: $master_seq[$i]);
1.297 sakharuk 2340: if ($flag_latex_header_remove ne 'NO') {
2341: $texversion = &latex_header_footer_remove($texversion);
2342: } else {
2343: $texversion =~ s/\\end{document}//;
2344: }
2345: $result .= $texversion;
2346: $flag_latex_header_remove = 'YES';
1.296 sakharuk 2347: }
1.550 foxr 2348: if (&Apache::loncommon::connection_aborted($r)) {
2349: last;
2350: }
1.141 sakharuk 2351: }
1.428 albertel 2352: &Apache::lonxml::clear_problem_counter();
1.344 foxr 2353: if ($flag_page_in_sequence eq 'YES') {
2354: $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;
2355: }
1.141 sakharuk 2356: $result .= '\end{document}';
1.284 albertel 2357: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1.562 foxr 2358: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students_from_page') ||
1.536 foxr 2359: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ||
1.284 albertel 2360: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){
1.353 foxr 2361:
2362:
1.150 sakharuk 2363: #-- prints assignments for whole class or for selected students
1.284 albertel 2364: my $type;
1.536 foxr 2365: if (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') ||
1.562 foxr 2366: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students_from_page') ||
1.536 foxr 2367: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems_students') ) {
1.254 sakharuk 2368: $selectionmade=5;
1.284 albertel 2369: $type='problems';
1.254 sakharuk 2370: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') {
2371: $selectionmade=8;
1.284 albertel 2372: $type='resources';
1.254 sakharuk 2373: }
1.150 sakharuk 2374: my @students=split /\|\|\|/, $helper->{'VARS'}->{'STUDENTS'};
1.341 foxr 2375: # The normal sort order is by section then by students within the
2376: # section. If the helper var student_sort is 1, then the user has elected
2377: # to override this and output the students by name.
2378: # Each element of the students array is of the form:
2379: # username:domain:section:last, first:status
2380: #
1.429 foxr 2381: # Note that student sort is not compatible with printing
2382: # 1 section per pdf...so that setting overrides.
1.341 foxr 2383: #
1.429 foxr 2384: if (($helper->{'VARS'}->{'student_sort'} eq 1) &&
2385: ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) {
1.341 foxr 2386: @students = sort compare_names @students;
2387: }
1.429 foxr 2388: &adjust_number_to_print($helper);
2389:
1.278 albertel 2390: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq '0' ||
2391: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'all' ) {
2392: $helper->{'VARS'}->{'NUMBER_TO_PRINT'}=$#students+1;
2393: }
1.429 foxr 2394: # If we are splitting on section boundaries, we need
2395: # to remember that in split_on_sections and
2396: # print all of the students in the list.
2397: #
2398: my $split_on_sections = 0;
2399: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'section') {
2400: $split_on_sections = 1;
2401: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1;
2402: }
1.150 sakharuk 2403: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
1.350 foxr 2404:
1.150 sakharuk 2405: #loop over students
1.562 foxr 2406:
2407: my $flag_latex_header_remove = 'NO';
1.150 sakharuk 2408: my %moreenv;
1.330 sakharuk 2409: $moreenv{'instructor_comments'}='hide';
1.285 albertel 2410: $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth);
1.309 sakharuk 2411: $moreenv{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'};
1.511 foxr 2412: $moreenv{'print_annotations'} = $helper->{'VARS'}->{'PRINT_ANNOTATIONS'};
1.353 foxr 2413: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'};
1.369 foxr 2414: $moreenv{'suppress_tries'} = $parmhash{'suppress_tries'};
1.511 foxr 2415: if (($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') ||
2416: ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes')) {
2417: $moreenv{'problem_split'}='yes';
2418: }
1.318 albertel 2419: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75');
1.272 sakharuk 2420: my $student_counter=-1;
1.429 foxr 2421: my $i = 0;
1.430 albertel 2422: my $last_section = (split(/:/,$students[0]))[2];
1.150 sakharuk 2423: foreach my $person (@students) {
1.350 foxr 2424:
1.373 albertel 2425: my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due";
1.311 sakharuk 2426: if (-e $duefile) {
2427: my $temp_file = Apache::File->new('>>'.$duefile);
2428: print $temp_file "1969\n";
2429: }
1.272 sakharuk 2430: $student_counter++;
1.429 foxr 2431: if ($split_on_sections) {
1.430 albertel 2432: my $this_section = (split(/:/,$person))[2];
1.429 foxr 2433: if ($this_section ne $last_section) {
2434: $i++;
2435: $last_section = $this_section;
2436: }
2437: } else {
2438: $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'});
2439: }
1.375 foxr 2440: my ($output,$fullname, $printed)=&print_resources($r,$helper,
1.353 foxr 2441: $person,$type,
2442: \%moreenv,\@master_seq,
1.360 albertel 2443: $flag_latex_header_remove,
1.422 albertel 2444: $LaTeXwidth);
1.375 foxr 2445: $resources_printed .= ":";
1.284 albertel 2446: $print_array[$i].=$output;
2447: $student_names[$i].=$person.':'.$fullname.'_END_';
2448: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname);
2449: $flag_latex_header_remove = 'YES';
1.331 albertel 2450: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.284 albertel 2451: }
2452: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
2453: $result .= $print_array[0].' \end{document}';
2454: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon') ||
1.562 foxr 2455: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon_page') ||
1.284 albertel 2456: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon') ) {
1.373 albertel 2457: my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
2458: my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
1.288 albertel 2459: my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'};
2460: my $code_name=$helper->{'VARS'}->{'ANON_CODE_STORAGE_NAME'};
1.292 albertel 2461: my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'};
1.385 foxr 2462: my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'};
1.388 foxr 2463: my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'};
2464:
1.381 albertel 2465: my $code_option=$helper->{'VARS'}->{'CODE_OPTION'};
1.542 raeburn 2466: my @lines = &Apache::grades::get_scantronformat_file();
1.381 albertel 2467: my ($code_type,$code_length)=('letter',6);
1.542 raeburn 2468: foreach my $line (@lines) {
1.381 albertel 2469: my ($name,$type,$length) = (split(/:/,$line))[0,2,4];
2470: if ($name eq $code_option) {
2471: $code_length=$length;
2472: if ($type eq 'number') { $code_type = 'number'; }
2473: }
2474: }
1.288 albertel 2475: my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth));
1.353 foxr 2476: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'};
1.420 albertel 2477: $moreenv{'instructor_comments'}='hide';
1.288 albertel 2478: my $seed=time+($$<<16)+($$);
1.292 albertel 2479: my @allcodes;
2480: if ($old_name) {
1.381 albertel 2481: my %result=&Apache::lonnet::get('CODEs',
2482: [$old_name,"type\0$old_name"],
2483: $cdom,$cnum);
2484: $code_type=$result{"type\0$old_name"};
1.292 albertel 2485: @allcodes=split(',',$result{$old_name});
1.336 albertel 2486: $num_todo=scalar(@allcodes);
1.389 foxr 2487: } elsif ($selected_code) { # Selection value is always numeric.
1.388 foxr 2488: $num_todo = 1;
2489: @allcodes = ($selected_code);
1.385 foxr 2490: } elsif ($single_code) {
2491:
1.387 foxr 2492: $num_todo = 1; # Unconditionally one code to do.
1.385 foxr 2493: # If an alpha code have to convert to numbers so it can be
2494: # converted back to letters again :-)
2495: #
2496: if ($code_type ne 'number') {
2497: $single_code = &letters_to_num($single_code);
2498: }
2499: @allcodes = ($single_code);
1.292 albertel 2500: } else {
2501: my %allcodes;
1.299 albertel 2502: srand($seed);
1.292 albertel 2503: for (my $i=0;$i<$num_todo;$i++) {
1.381 albertel 2504: $moreenv{'CODE'}=&get_CODE(\%allcodes,$i,$seed,$code_length,
2505: $code_type);
1.292 albertel 2506: }
2507: if ($code_name) {
2508: &Apache::lonnet::put('CODEs',
1.381 albertel 2509: {
2510: $code_name =>join(',',keys(%allcodes)),
2511: "type\0$code_name" => $code_type
2512: },
1.292 albertel 2513: $cdom,$cnum);
2514: }
2515: @allcodes=keys(%allcodes);
2516: }
1.336 albertel 2517: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'};
2518: my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'});
1.452 albertel 2519: &adjust_number_to_print($helper);
1.336 albertel 2520: my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'};
2521: if ($number_per_page eq '0' || $number_per_page eq 'all') {
2522: $number_per_page=$num_todo;
2523: }
2524: my $flag_latex_header_remove = 'NO';
2525: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75');
1.295 albertel 2526: my $count=0;
1.292 albertel 2527: foreach my $code (sort(@allcodes)) {
1.295 albertel 2528: my $file_num=int($count/$number_per_page);
1.381 albertel 2529: if ($code_type eq 'number') {
2530: $moreenv{'CODE'}=$code;
2531: } else {
2532: $moreenv{'CODE'}=&num_to_letters($code);
2533: }
1.375 foxr 2534: my ($output,$fullname, $printed)=
1.288 albertel 2535: &print_resources($r,$helper,'anonymous',$type,\%moreenv,
1.360 albertel 2536: \@master_seq,$flag_latex_header_remove,
2537: $LaTeXwidth);
1.375 foxr 2538: $resources_printed .= ":";
1.295 albertel 2539: $print_array[$file_num].=$output;
1.288 albertel 2540: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
2541: &mt('last assignment').' '.$fullname);
2542: $flag_latex_header_remove = 'YES';
1.295 albertel 2543: $count++;
1.331 albertel 2544: if (&Apache::loncommon::connection_aborted($r)) { last; }
1.288 albertel 2545: }
2546: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
2547: $result .= $print_array[0].' \end{document}';
2548: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') {
1.151 sakharuk 2549: #prints selected problems from the subdirectory
2550: $selectionmade = 6;
2551: my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'};
1.154 sakharuk 2552: @list_of_files=sort @list_of_files;
1.175 sakharuk 2553: my $flag_latex_header_remove = 'NO';
2554: my $rndseed=time;
1.230 albertel 2555: if ($helper->{'VARS'}->{'curseed'}) {
2556: $rndseed=$helper->{'VARS'}->{'curseed'};
2557: }
1.151 sakharuk 2558: for (my $i=0;$i<=$#list_of_files;$i++) {
1.521 foxr 2559:
2560: &Apache::lonenc::reset_enc();
2561:
1.152 sakharuk 2562: my $urlp = $list_of_files[$i];
1.253 sakharuk 2563: $urlp=~s|//|/|;
1.152 sakharuk 2564: if ($urlp=~/\//) {
1.353 foxr 2565: $form{'problem_split'}=$parmhash{'problem_stream_switch'};
1.175 sakharuk 2566: $form{'rndseed'}=$rndseed;
1.152 sakharuk 2567: if ($urlp =~ m|/home/([^/]+)/public_html|) {
2568: $urlp =~ s|/home/([^/]*)/public_html|/~$1|;
2569: } else {
1.302 sakharuk 2570: $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||;
1.152 sakharuk 2571: }
1.375 foxr 2572: $resources_printed .= $urlp.':';
1.515 foxr 2573: my $texversion=&ssi_with_retries($urlp, $ssi_retry_count, %form);
1.251 sakharuk 2574: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
1.253 sakharuk 2575: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2576: # Don't permanently pervert %form:
2577: my %answerform = %form;
2578: $answerform{'grade_target'}='answer';
2579: $answerform{'answer_output_mode'}='tex';
2580: $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
2581: $answerform{'rndseed'}=$rndseed;
1.375 foxr 2582: $resources_printed .= $urlp.':';
1.515 foxr 2583: my $answer=&ssi_with_retries($urlp, $ssi_retry_count, %answerform);
1.251 sakharuk 2584: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2585: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/;
2586: } else {
1.253 sakharuk 2587: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
2588: if ($helper->{'VARS'}->{'construction'} ne '1') {
2589: $texversion.='\vskip 0 mm \noindent ';
2590: $texversion.=&path_to_problem ($urlp,$LaTeXwidth);
2591: } else {
2592: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm ';
2593: my $URLpath=$urlp;
2594: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/;
2595: $texversion.=&path_to_problem ($URLpath,$LaTeXwidth);
2596: }
2597: $texversion.='\vskip 1 mm '.$answer.'\end{document}';
1.251 sakharuk 2598: }
1.174 sakharuk 2599: }
1.515 foxr 2600: #this chunk is responsible for printing the path to problem
2601:
1.253 sakharuk 2602: my $newurlp=$urlp;
2603: if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;}
2604: $newurlp=&path_to_problem($newurlp,$LaTeXwidth);
1.242 sakharuk 2605: $texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/;
1.152 sakharuk 2606: if ($flag_latex_header_remove ne 'NO') {
2607: $texversion = &latex_header_footer_remove($texversion);
2608: } else {
2609: $texversion =~ s/\\end{document}//;
1.216 sakharuk 2610: }
2611: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') {
2612: $texversion=&IndexCreation($texversion,$urlp);
1.152 sakharuk 2613: }
1.219 sakharuk 2614: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') {
2615: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /;
2616:
2617: }
1.152 sakharuk 2618: $result .= $texversion;
2619: }
2620: $flag_latex_header_remove = 'YES';
1.151 sakharuk 2621: }
1.175 sakharuk 2622: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;}
1.152 sakharuk 2623: $result .= '\end{document}';
1.140 sakharuk 2624: }
2625: #-------------------------------------------------------- corrections for the different page formats
1.499 foxr 2626:
2627: # Only post process if that has not been turned off e.g. by a raw latex resource.
2628:
2629: if ($do_postprocessing) {
2630: $result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade);
2631: $result = &latex_corrections($number_of_columns,$result,$selectionmade,
2632: $helper->{'VARS'}->{'ANSWER_TYPE'});
2633: #if ($numberofcolumns == 1) {
1.451 albertel 2634: $result =~ s/\\textwidth\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /;
2635: $result =~ s/\\textheight\s*=?\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /;
2636: $result =~ s/\\evensidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
2637: $result =~ s/\\oddsidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /;
1.499 foxr 2638: #}
2639: }
1.367 foxr 2640:
1.515 foxr 2641: # Set URLback if this is a construction space print so we can provide
2642: # a link to the resource being edited.
2643: #
1.274 sakharuk 2644:
1.276 sakharuk 2645: my $URLback=''; #link to original document
1.510 albertel 2646: if ($helper->{'VARS'}->{'construction'} eq '1') {
1.276 sakharuk 2647: #prints resource from the construction space
2648: $URLback='/'.$helper->{'VARS'}->{'filename'};
1.279 albertel 2649: if ($URLback=~/([^?]+)/) {
2650: $URLback=$1;
2651: $URLback=~s|^/~|/priv/|;
2652: }
1.276 sakharuk 2653: }
1.556 foxr 2654: #
2655: # Final adjustment of the font size:
2656: #
2657:
2658: $result = set_font_size($result);
1.375 foxr 2659:
1.525 www 2660: #-- writing .tex file in prtspool
2661: my $temp_file;
2662: my $identifier = &Apache::loncommon::get_cgi_id();
2663: my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex";
2664: if (!($#print_array>0)) {
2665: unless ($temp_file = Apache::File->new('>'.$filename)) {
2666: $r->log_error("Couldn't open $filename for output $!");
2667: return SERVER_ERROR;
2668: }
2669: print $temp_file $result;
2670: my $begin=index($result,'\begin{document}',0);
2671: my $inc=substr($result,0,$begin+16);
1.515 foxr 2672: } else {
1.525 www 2673: my $begin=index($result,'\begin{document}',0);
2674: my $inc=substr($result,0,$begin+16);
2675: for (my $i=0;$i<=$#print_array;$i++) {
2676: if ($i==0) {
2677: $print_array[$i]=$result;
2678: } else {
2679: $print_array[$i].='\end{document}';
2680: $print_array[$i] =
2681: &latex_corrections($number_of_columns,$print_array[$i],
2682: $selectionmade,
2683: $helper->{'VARS'}->{'ANSWER_TYPE'});
1.515 foxr 2684:
1.525 www 2685: my $anobegin=index($print_array[$i],'\setcounter{page}',0);
2686: substr($print_array[$i],0,$anobegin)='';
2687: $print_array[$i]=$inc.$print_array[$i];
2688: }
2689: my $temp_file;
2690: my $newfilename=$filename;
2691: my $num=$i+1;
2692: $newfilename =~s/\.tex$//;
2693: $newfilename=sprintf("%s_%03d.tex",$newfilename, $num);
2694: unless ($temp_file = Apache::File->new('>'.$newfilename)) {
2695: $r->log_error("Couldn't open $newfilename for output $!");
2696: return SERVER_ERROR;
2697: }
2698: print $temp_file $print_array[$i];
2699: }
2700: }
2701: my $student_names='';
2702: if ($#print_array>0) {
2703: for (my $i=0;$i<=$#print_array;$i++) {
2704: $student_names.=$student_names[$i].'_ENDPERSON_';
1.515 foxr 2705: }
1.525 www 2706: } else {
2707: if ($#student_names>-1) {
2708: $student_names=$student_names[0].'_ENDPERSON_';
1.515 foxr 2709: } else {
1.525 www 2710: my $fullname = &get_name($env{'user.name'},$env{'user.domain'});
2711: $student_names=join(':',$env{'user.name'},$env{'user.domain'},
1.515 foxr 2712: $env{'request.course.sec'},$fullname).
2713: '_ENDPERSON_'.'_END_';
2714: }
1.525 www 2715: }
1.515 foxr 2716:
1.525 www 2717: # logic for now is too complex to trace if this has been defined
2718: # yet.
2719: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
2720: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2721: &Apache::lonnet::appenv({'cgi.'.$identifier.'.file' => $filename,
1.515 foxr 2722: 'cgi.'.$identifier.'.layout' => $laystyle,
2723: 'cgi.'.$identifier.'.numcol' => $numberofcolumns,
2724: 'cgi.'.$identifier.'.paper' => $papersize,
2725: 'cgi.'.$identifier.'.selection' => $selectionmade,
2726: 'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'},
2727: 'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'},
2728: 'cgi.'.$identifier.'.role' => $perm{'pav'},
2729: 'cgi.'.$identifier.'.numberoffiles' => $#print_array,
2730: 'cgi.'.$identifier.'.studentnames' => $student_names,
1.520 raeburn 2731: 'cgi.'.$identifier.'.backref' => $URLback,});
1.525 www 2732: &Apache::lonnet::appenv({"cgi.$identifier.user" => $env{'user.name'},
1.515 foxr 2733: "cgi.$identifier.domain" => $env{'user.domain'},
2734: "cgi.$identifier.courseid" => $cnum,
2735: "cgi.$identifier.coursedom" => $cdom,
1.520 raeburn 2736: "cgi.$identifier.resources" => $resources_printed});
1.515 foxr 2737:
1.525 www 2738: my $end_page = &Apache::loncommon::end_page();
1.529 raeburn 2739: my $continue_text = &mt('Continue');
1.525 www 2740: # If there's been an unrecoverable SSI error, report it to the user
2741: if ($ssi_error) {
2742: my $helpurl = &Apache::loncommon::top_nav_help('Helpdesk');
1.554 bisitz 2743: $r->print('<br /><p class="LC_error">'.&mt('An unrecoverable network error occurred:').'</p><p>'.
1.526 www 2744: &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:').
2745: '<br />'.$ssi_last_error_resource.'<br />'.$ssi_last_error.
2746: '</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 2747: &mt('You may be able to reprint the individual resources for which this error occurred, as the issue may be temporary.').
1.525 www 2748: '<br />'.&mt('If the error persists, please contact the [_1] for assistance.',$helpurl).'</p><p>'.
2749: &mt('We apologize for the inconvenience.').'</p>'.
1.528 raeburn 2750: '<a href="/cgi-bin/printout.pl?'.$identifier.'">'.$continue_text.'</a>'.$end_page);
1.525 www 2751: } else {
1.515 foxr 2752: $r->print(<<FINALEND);
1.317 albertel 2753: <br />
1.288 albertel 2754: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" />
1.528 raeburn 2755: <a href="/cgi-bin/printout.pl?$identifier">$continue_text</a>
1.431 albertel 2756: $end_page
1.140 sakharuk 2757: FINALEND
1.528 raeburn 2758: } # endif ssi errors.
1.140 sakharuk 2759: }
2760:
1.288 albertel 2761:
2762: sub get_CODE {
1.381 albertel 2763: my ($all_codes,$num,$seed,$size,$type)=@_;
1.288 albertel 2764: my $max='1'.'0'x$size;
2765: my $newcode;
2766: while(1) {
1.392 albertel 2767: $newcode=sprintf("%0".$size."d",int(rand($max)));
1.288 albertel 2768: if (!exists($$all_codes{$newcode})) {
2769: $$all_codes{$newcode}=1;
1.381 albertel 2770: if ($type eq 'number' ) {
2771: return $newcode;
2772: } else {
2773: return &num_to_letters($newcode);
2774: }
1.288 albertel 2775: }
2776: }
2777: }
1.140 sakharuk 2778:
1.284 albertel 2779: sub print_resources {
1.360 albertel 2780: my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header,
1.422 albertel 2781: $LaTeXwidth)=@_;
1.284 albertel 2782: my $current_output = '';
1.375 foxr 2783: my $printed = '';
1.284 albertel 2784: my ($username,$userdomain,$usersection) = split /:/,$person;
2785: my $fullname = &get_name($username,$userdomain);
1.492 foxr 2786: my $namepostfix = "\\\\"; # Both anon and not anon should get the same vspace.
1.288 albertel 2787: if ($person =~ 'anon') {
1.492 foxr 2788: $namepostfix .="Name: ";
1.288 albertel 2789: $fullname = "CODE - ".$moreenv->{'CODE'};
2790: }
1.444 foxr 2791: # Fullname may have special latex characters that need \ prefixing:
2792: #
2793:
1.350 foxr 2794: my $i = 0;
1.284 albertel 2795: #goes through all resources, checks if they are available for
2796: #current student, and produces output
1.428 albertel 2797:
2798: &Apache::lonxml::clear_problem_counter();
1.364 albertel 2799: my %page_breaks = &get_page_breaks($helper);
1.476 albertel 2800: my $columns_in_format = (split(/\|/,$helper->{'VARS'}->{'FORMAT'}))[1];
1.440 foxr 2801: #
1.441 foxr 2802: # end each student with a
1.440 foxr 2803: # Special that allows the post processor to even out the page
2804: # counts later. Nasty problem this... it would be really
2805: # nice to put the special in as a postscript comment
1.441 foxr 2806: # e.g. \special{ps:\ENDOFSTUDENTSTAMP} unfortunately,
1.440 foxr 2807: # The special gets passed the \ and dvips puts it in the output file
1.441 foxr 2808: # so we will just rely on prntout.pl to strip ENDOFSTUDENTSTAMP from the
2809: # postscript. Each ENDOFSTUDENTSTAMP will go on a line by itself.
1.440 foxr 2810: #
1.363 foxr 2811:
1.284 albertel 2812: foreach my $curresline (@{$master_seq}) {
1.351 foxr 2813: if (defined $page_breaks{$curresline}) {
1.350 foxr 2814: if($i != 0) {
2815: $current_output.= "\\newpage\n";
2816: }
2817: }
2818: $i++;
1.511 foxr 2819:
1.284 albertel 2820: if ( !($type eq 'problems' &&
2821: ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) {
2822: my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline);
2823: if (&Apache::lonnet::allowed('bre',$res_url)) {
1.414 albertel 2824: if ($res_url!~m|^ext/|
1.413 albertel 2825: && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) {
1.375 foxr 2826: $printed .= $curresline.':';
1.428 albertel 2827: &Apache::lonxml::remember_problem_counter();
2828:
1.526 www 2829: my $rendered = &get_student_view_with_retries($curresline,$ssi_retry_count,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv);
1.305 sakharuk 2830: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') ||
2831: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) {
1.380 foxr 2832: # Use a copy of the hash so we don't pervert it on future loop passes.
2833: my %answerenv = %{$moreenv};
2834: $answerenv{'answer_output_mode'}='tex';
2835: $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'};
1.428 albertel 2836:
2837: &Apache::lonxml::restore_problem_counter();
2838:
1.380 foxr 2839: my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv);
1.428 albertel 2840:
1.305 sakharuk 2841: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') {
2842: $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/;
2843: } else {
1.423 foxr 2844:
2845:
2846: my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'});
1.552 foxr 2847: $header =~ s/\\begin{document}//; #<<<<<
1.477 albertel 2848: my $title = &Apache::lonnet::gettitle($curresline);
2849: $title = &Apache::lonxml::latex_special_symbols($title);
2850: my $body ='\vskip 0 mm \noindent\textbf{'.$title.'}\vskip 0 mm ';
2851: $body .=&path_to_problem($res_url,$LaTeXwidth);
1.423 foxr 2852: $body .='\vskip 1 mm '.$ansrendered;
2853: $body = &encapsulate_minipage($body);
2854: $rendered = $header.$body;
1.305 sakharuk 2855: }
2856: }
1.511 foxr 2857: if ($helper->{'VARS'}->{'PRINT_ANNOTATIONS'} eq 'yes') {
2858: my $url = &Apache::lonnet::clutter($res_url);
2859: my $annotation = &annotate($url);
2860: $rendered =~ s/(\\keephidden{ENDOFPROBLEM})/$annotation$1/;
2861: }
1.562 foxr 2862: my $junk;
1.305 sakharuk 2863: if ($remove_latex_header eq 'YES') {
2864: $rendered = &latex_header_footer_remove($rendered);
2865: } else {
2866: $rendered =~ s/\\end{document}//;
2867: }
2868: $current_output .= $rendered;
1.456 raeburn 2869: } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) {
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.284 albertel 2914: if ($current_output=~/\\documentclass/) {
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.284 albertel 2916: } else {
1.476 albertel 2917: my $blankpages =
2918: '\clearpage\strut\clearpage'x$helper->{'VARS'}->{'EMPTY_PAGES'};
2919:
2920: $current_output = '\strut\vspace*{-6 mm}\\newline'.
2921: ©right_line().' \newpage '.$blankpages.$end_of_student.
2922: '\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent'.
2923: $header_line.$namepostfix.'} \vskip 5 mm '.$current_output;
1.284 albertel 2924: }
1.440 foxr 2925: #
2926: # Close the student bracketing.
2927: #
1.375 foxr 2928: return ($current_output,$fullname, $printed);
1.284 albertel 2929:
2930: }
1.140 sakharuk 2931:
1.3 sakharuk 2932: sub handler {
2933:
2934: my $r = shift;
1.397 albertel 2935:
2936: &init_perm();
1.114 bowersj2 2937:
1.416 foxr 2938:
1.67 www 2939:
1.397 albertel 2940: my $helper = printHelper($r);
2941: if (!ref($helper)) {
2942: return $helper;
1.60 sakharuk 2943: }
1.177 sakharuk 2944:
1.184 sakharuk 2945:
1.454 foxr 2946: %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.353 foxr 2947:
1.416 foxr 2948:
1.350 foxr 2949:
2950:
1.367 foxr 2951: # If a figure conversion queue file exists for this user.domain
2952: # we delete it since it can only be bad (if it were good, printout.pl
2953: # would have deleted it the last time around.
2954:
1.373 albertel 2955: my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat";
1.367 foxr 2956: if(-e $conversion_queuefile) {
2957: unlink $conversion_queuefile;
2958: }
1.515 foxr 2959:
2960:
1.184 sakharuk 2961: &output_data($r,$helper,\%parmhash);
1.2 sakharuk 2962: return OK;
1.60 sakharuk 2963: }
1.2 sakharuk 2964:
1.131 bowersj2 2965: use Apache::lonhelper;
1.130 sakharuk 2966:
1.223 bowersj2 2967: sub addMessage {
2968: my $text = shift;
2969: my $paramHash = Apache::lonhelper::getParamHash();
2970: $paramHash->{MESSAGE_TEXT} = $text;
2971: Apache::lonhelper::message->new();
2972: }
2973:
1.416 foxr 2974:
1.238 bowersj2 2975:
1.397 albertel 2976: sub init_perm {
2977: undef(%perm);
2978: $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'});
2979: if (!$perm{'pav'}) {
2980: $perm{'pav'}=&Apache::lonnet::allowed('pav',
2981: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2982: }
1.465 albertel 2983: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',$env{'request.course.id'});
1.397 albertel 2984: if (!$perm{'pfo'}) {
2985: $perm{'pfo'}=&Apache::lonnet::allowed('pfo',
2986: $env{'request.course.id'}.'/'.$env{'request.course.sec'});
2987: }
2988: }
2989:
1.507 albertel 2990: sub get_randomly_ordered_warning {
2991: my ($helper,$map) = @_;
2992:
2993: my $message;
2994:
2995: my $postdata = $env{'form.postdata'} || $helper->{VARS}{'postdata'};
2996: my $navmap = Apache::lonnavmaps::navmap->new();
1.547 raeburn 2997: if (defined($navmap)) {
2998: my $res = $navmap->getResourceByUrl($map);
2999: if ($res) {
3000: my $func =
3001: sub { return ($_[0]->is_map() && $_[0]->randomorder); };
3002: my @matches = $navmap->retrieveResources($res, $func,1,1,1);
3003: if (@matches) {
3004: $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.";
3005: }
3006: }
3007: if ($message) {
3008: return '<message type="warning">'.$message.'</message>';
3009: }
3010: } else {
3011: $message = "Retrieval of information about ordering of resources failed.";
3012: return '<message type="warning">'.$message.'</message>';
1.507 albertel 3013: }
3014: return;
3015: }
3016:
1.131 bowersj2 3017: sub printHelper {
1.115 bowersj2 3018: my $r = shift;
3019:
3020: if ($r->header_only) {
1.373 albertel 3021: if ($env{'browser.mathml'}) {
1.241 www 3022: &Apache::loncommon::content_type($r,'text/xml');
1.131 bowersj2 3023: } else {
1.241 www 3024: &Apache::loncommon::content_type($r,'text/html');
1.131 bowersj2 3025: }
3026: $r->send_http_header;
3027: return OK;
1.115 bowersj2 3028: }
3029:
1.131 bowersj2 3030: # Send header, nocache
1.373 albertel 3031: if ($env{'browser.mathml'}) {
1.241 www 3032: &Apache::loncommon::content_type($r,'text/xml');
1.115 bowersj2 3033: } else {
1.241 www 3034: &Apache::loncommon::content_type($r,'text/html');
1.115 bowersj2 3035: }
3036: &Apache::loncommon::no_cache($r);
3037: $r->send_http_header;
3038: $r->rflush();
3039:
1.131 bowersj2 3040: # Unfortunately, this helper is so complicated we have to
3041: # write it by hand
3042:
3043: Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING});
3044:
1.176 bowersj2 3045: my $helper = Apache::lonhelper::helper->new("Printing Helper");
1.146 bowersj2 3046: $helper->declareVar('symb');
1.156 bowersj2 3047: $helper->declareVar('postdata');
1.290 sakharuk 3048: $helper->declareVar('curseed');
3049: $helper->declareVar('probstatus');
1.156 bowersj2 3050: $helper->declareVar('filename');
3051: $helper->declareVar('construction');
1.178 sakharuk 3052: $helper->declareVar('assignment');
1.262 sakharuk 3053: $helper->declareVar('style_file');
1.340 foxr 3054: $helper->declareVar('student_sort');
1.363 foxr 3055: $helper->declareVar('FINISHPAGE');
1.366 foxr 3056: $helper->declareVar('PRINT_TYPE');
1.372 foxr 3057: $helper->declareVar("showallfoils");
1.483 foxr 3058: $helper->declareVar("STUDENTS");
1.363 foxr 3059:
1.518 foxr 3060:
3061:
3062:
3063:
1.363 foxr 3064: # The page breaks can get loaded initially from the course environment:
1.394 foxr 3065: # But we only do this in the initial state so that they are allowed to change.
3066: #
1.366 foxr 3067:
1.416 foxr 3068: # $helper->{VARS}->{FINISHPAGE} = '';
1.363 foxr 3069:
3070: &Apache::loncommon::restore_course_settings('print',
1.366 foxr 3071: {'pagebreaks' => 'scalar',
3072: 'lastprinttype' => 'scalar'});
3073:
1.483 foxr 3074: # This will persistently load in the data we want from the
3075: # very first screen.
1.394 foxr 3076:
3077: if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) {
3078: if (!defined ($env{"form.CURRENT_STATE"})) {
3079:
3080: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
3081: } else {
3082: my $state = $env{"form.CURRENT_STATE"};
3083: if ($state eq "START") {
3084: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'};
3085: }
3086: }
3087:
1.366 foxr 3088: }
1.481 albertel 3089:
1.156 bowersj2 3090: # Detect whether we're coming from construction space
1.373 albertel 3091: if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) {
1.235 bowersj2 3092: $helper->{VARS}->{'filename'} = "~$1/$2";
1.156 bowersj2 3093: $helper->{VARS}->{'construction'} = 1;
1.481 albertel 3094: } else {
1.373 albertel 3095: if ($env{'form.postdata'}) {
3096: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'});
1.482 albertel 3097: if ( $helper->{VARS}->{'symb'} eq '') {
3098: $helper->{VARS}->{'postdata'} = $env{'form.postdata'};
3099: }
1.156 bowersj2 3100: }
1.373 albertel 3101: if ($env{'form.symb'}) {
3102: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.156 bowersj2 3103: }
1.373 albertel 3104: if ($env{'form.url'}) {
1.156 bowersj2 3105: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
3106: }
1.416 foxr 3107:
1.157 bowersj2 3108: }
1.481 albertel 3109:
1.373 albertel 3110: if ($env{'form.symb'}) {
3111: $helper->{VARS}->{'symb'} = $env{'form.symb'};
1.146 bowersj2 3112: }
1.373 albertel 3113: if ($env{'form.url'}) {
1.140 sakharuk 3114: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'});
1.153 sakharuk 3115:
1.140 sakharuk 3116: }
1.343 albertel 3117: $helper->{VARS}->{'symb'}=
3118: &Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'});
1.335 albertel 3119: my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper);
1.178 sakharuk 3120: if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;}
1.481 albertel 3121:
1.156 bowersj2 3122:
1.146 bowersj2 3123: # Extract map
3124: my $symb = $helper->{VARS}->{'symb'};
1.156 bowersj2 3125: my ($map, $id, $url);
3126: my $subdir;
1.483 foxr 3127: my $is_published=0; # True when printing from resource space.
1.156 bowersj2 3128:
3129: # Get the resource name from construction space
3130: if ($helper->{VARS}->{'construction'}) {
3131: $resourceTitle = substr($helper->{VARS}->{'filename'},
3132: rindex($helper->{VARS}->{'filename'}, '/')+1);
3133: $subdir = substr($helper->{VARS}->{'filename'},
3134: 0, rindex($helper->{VARS}->{'filename'}, '/') + 1);
1.481 albertel 3135: } else {
1.562 foxr 3136: # From course space:
3137:
1.482 albertel 3138: if ($symb ne '') {
3139: ($map, $id, $url) = &Apache::lonnet::decode_symb($symb);
3140: $helper->{VARS}->{'postdata'} =
3141: &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url));
3142: } else {
3143: $url = $helper->{VARS}->{'postdata'};
1.483 foxr 3144: $is_published=1; # From resource space.
1.482 albertel 3145: }
3146: $url = &Apache::lonnet::clutter($url);
1.156 bowersj2 3147: if (!$resourceTitle) { # if the resource doesn't have a title, use the filename
1.238 bowersj2 3148: my $postdata = $helper->{VARS}->{'postdata'};
3149: $resourceTitle = substr($postdata, rindex($postdata, '/') + 1);
1.156 bowersj2 3150: }
3151: $subdir = &Apache::lonnet::filelocation("", $url);
1.128 bowersj2 3152: }
1.373 albertel 3153: if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) {
3154: $helper->{VARS}->{'curseed'}=$env{'form.curseed'};
1.230 albertel 3155: }
1.373 albertel 3156: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
1.512 foxr 3157: $helper->{VARS}->{'probstatus'}=$env{'form.problemstatus'};
1.290 sakharuk 3158: }
1.115 bowersj2 3159:
1.192 bowersj2 3160: my $userCanSeeHidden = Apache::lonnavmaps::advancedUser();
3161:
1.481 albertel 3162: Apache::lonhelper::registerHelperTags();
1.119 bowersj2 3163:
1.131 bowersj2 3164: # "Delete everything after the last slash."
1.119 bowersj2 3165: $subdir =~ s|/[^/]+$||;
3166:
1.131 bowersj2 3167: # What can be printed is a very dynamic decision based on
3168: # lots of factors. So we need to dynamically build this list.
3169: # To prevent security leaks, states are only added to the wizard
3170: # if they can be reached, which ensures manipulating the form input
3171: # won't allow anyone to reach states they shouldn't have permission
3172: # to reach.
3173:
3174: # printChoices is tracking the kind of printing the user can
3175: # do, and will be used in a choices construction later.
3176: # In the meantime we will be adding states and elements to
3177: # the helper by hand.
3178: my $printChoices = [];
3179: my $paramHash;
1.130 sakharuk 3180:
1.240 albertel 3181: if ($resourceTitle) {
1.458 www 3182: push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('the resource you just saw on the screen').")", 'current_document', 'PAGESIZE'];
1.156 bowersj2 3183: }
3184:
1.238 bowersj2 3185: # Useful filter strings
1.540 raeburn 3186: my $isProblem = '($res->is_problem()||$res->contains_problem||$res->is_practice()) ';
1.238 bowersj2 3187: $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden;
1.541 raeburn 3188: my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence() || $res->is_practice()';
1.287 albertel 3189: my $isNotMap = '!$res->is_sequence()';
1.238 bowersj2 3190: $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden;
3191: my $isMap = '$res->is_map()';
1.342 albertel 3192: my $symbFilter = '$res->shown_symb()';
3193: my $urlValue = '$res->link()';
1.238 bowersj2 3194:
3195: $helper->declareVar('SEQUENCE');
3196:
1.465 albertel 3197: # If we're in a sequence...
1.416 foxr 3198:
1.465 albertel 3199: my $start_new_option;
3200: if ($perm{'pav'}) {
3201: $start_new_option =
3202: "<option text='".&mt('Start new page<br />before selected').
3203: "' variable='FINISHPAGE' />";
3204: }
1.238 bowersj2 3205:
1.562 foxr 3206: # If not construction space user can print the components of a page:
3207:
3208: my $page_ispage;
3209: my $page_title;
3210: if (!$helper->{VARS}->{'construction'}) {
3211: my $varspostdata = $helper->{VARS}->{'postdata'};
3212: my $varsassignment = $helper->{VARS}->{'assignment'};
3213: my $page_navmap = Apache::lonnavmaps::navmap->new();
1.563 foxr 3214: if (defined($page_navmap)) {
3215: my @page_resources = $page_navmap->retrieveResources($url);
3216: if(defined($page_resources[0])) {
3217: $page_ispage = $page_resources[0]->is_page();
3218: $page_title = $page_resources[0]->title();
3219: my $resourcesymb = $page_resources[0]->symb();
3220: my ($pagemap, $pageid, $pageurl) = &Apache::lonnet::decode_symb($symb);
3221: if ($page_ispage) {
3222: push @{$printChoices},
3223: [&mt('Selected [_1]Problems[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'),
3224: 'map_problems_in_page',
3225: 'CHOOSE_PROBLEMS_PAGE'];
3226: push @{$printChoices},
3227: [&mt('Selected [_1]Resources[_2] from page [_3]', '<b>', '</b>', '<b><i>'.$page_title.'</i></b>'),
3228: 'map_resources_in_page',
3229: 'CHOOSE_RESOURCES_PAGE'];
3230: }
1.562 foxr 3231: my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS_PAGE',
3232: 'Select Problem(s) to print',
3233: "multichoice='1' toponly='1' addstatus='1' closeallpages='1'",
3234: 'RESOURCES',
3235: 'PAGESIZE',
3236: $url,
3237: $isProblem, '', $symbFilter,
3238: $start_new_option);
3239:
3240:
3241: $helperFragment .= &generate_resource_chooser('CHOOSE_RESOURCES_PAGE',
3242: 'Select Resource(s) to print',
3243: 'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
3244: 'RESOURCES',
3245: 'PAGESIZE',
3246: $url,
3247: $isNotMap, '', $symbFilter,
3248: $start_new_option);
3249:
3250:
3251:
3252:
3253:
3254: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
3255:
1.563 foxr 3256: }
3257: }
1.562 foxr 3258: }
3259:
3260: if (($helper->{'VAR'}->{'construction'} ne '1' ) &&
1.243 bowersj2 3261: $helper->{VARS}->{'postdata'} &&
3262: $helper->{VARS}->{'assignment'}) {
1.131 bowersj2 3263: # Allow problems from sequence
1.562 foxr 3264: push @{$printChoices},
3265: [&mt('Selected [_1]Problems[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'),
3266: 'map_problems',
3267: 'CHOOSE_PROBLEMS'];
1.131 bowersj2 3268: # Allow all resources from sequence
1.562 foxr 3269: push @{$printChoices}, [&mt('Selected [_1]Resources[_2] from folder [_3]','<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>'),
3270: 'map_problems_pages',
3271: 'CHOOSE_PROBLEMS_HTML'];
3272: my $helperFragment = &generate_resource_chooser('CHOOSE_PROBLEMS',
3273: 'Select Problem(s) to print',
3274: 'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
3275: 'RESOURCES',
3276: 'PAGESIZE',
3277: $map,
3278: $isProblem, '',
3279: $symbFilter,
3280: $start_new_option);
3281: $helperFragment .= &generate_resource_chooser('CHOOSE_PROBLEMS_HTML',
3282: 'Select Resource(s) to print',
3283: 'multichoice="1" toponly="1" addstatus="1" closeallpages="1"',
3284: 'RESOURCES',
3285: 'PAGESIZE',
3286: $map,
3287: $isNotMap, '',
3288: $symbFilter,
3289: $start_new_option);
1.121 bowersj2 3290:
1.326 sakharuk 3291: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment);
1.121 bowersj2 3292: }
3293:
1.546 bisitz 3294: # If the user has pfo (print for others) allow them to print all
3295: # problems and resources in the entire course, optionally for selected students
1.562 foxr 3296: my $post_data = $helper->{VARS}->{'postdata'};
1.483 foxr 3297: if ($perm{'pfo'} && !$is_published &&
1.562 foxr 3298: ($post_data=~/\/res\// || $post_data =~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) {
1.481 albertel 3299:
1.509 albertel 3300: push @{$printChoices}, [&mtn('Selected <b>Problems</b> from <b>entire course</b>'), 'all_problems', 'ALL_PROBLEMS'];
3301: push @{$printChoices}, [&mtn('Selected <b>Resources</b> from <b>entire course</b>'), 'all_resources', 'ALL_RESOURCES'];
1.536 foxr 3302: 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 3303: my $suffixXml = <<ALL_PROBLEMS;
1.536 foxr 3304: <state name="STUDENTS1" title="Select People">
3305: <message><b>Select sorting order of printout</b> </message>
3306: <choices variable='student_sort'>
3307: <choice computer='0'>Sort by section then student</choice>
3308: <choice computer='1'>Sort by students across sections.</choice>
3309: </choices>
3310: <message><br /><hr /><br /> </message>
3311: <student multichoice='1' variable="STUDENTS" nextstate="PRINT_FORMATTING" coursepersonnel="1"/>
3312: </state>
1.284 albertel 3313: ALL_PROBLEMS
1.562 foxr 3314: &Apache::lonxml::xmlparse($r, 'helper',
3315: &generate_resource_chooser('ALL_PROBLEMS',
3316: 'SelectProblem(s) to print',
3317: 'multichoice="1" suppressEmptySequences="0" addstatus="1" closeallpages="1"',
3318: 'RESOURCES',
3319: 'PAGESIZE',
3320: '',
3321: $isProblemOrMap, $isNotMap,
3322: $symbFilter,
3323: $start_new_option) .
3324: &generate_resource_chooser('ALL_RESOURCES',
3325: 'Select Resource(s) to print',
3326: " toponly='0' multichoice='1' suppressEmptySequences='0' addstatus='1' closeallpages='1'",
3327: 'RESOURCES',
3328: 'PAGESIZE',
3329: '',
3330: $isNotMap,'',$symbFilter,
3331: $start_new_option) .
3332: &generate_resource_chooser('ALL_PROBLEMS_STUDENTS',
3333: 'Select Problem(s) to print',
3334: 'toponly="0" multichoice="1" suppressEmptySequences="0" addstatus="1" closeallpages="1"',
3335: 'RESOURCES',
3336: 'STUDENTS1',
3337: '',
3338: $isProblemOrMap,'' , $symbFilter,
3339: $start_new_option) .
3340: $suffixXml
3341: );
1.132 bowersj2 3342:
1.284 albertel 3343: if ($helper->{VARS}->{'assignment'}) {
1.562 foxr 3344:
3345: # If we were looking at a page, allow a selection of problems from the page
3346: # either for selected students or for coded assignments.
3347:
3348: if ($page_ispage) {
3349: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from page [_3] for [_4]selected people[_5]',
3350: '<b>', '</b>', '<b><i>'.$page_title.'</i></b>', '<b>', '</b>'),
3351: 'problems_for_students_from_page', 'CHOOSE_TGT_STUDENTS_PAGE'];
3352: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from page [_3] for [_4]CODEd assignments[_5]',
3353: '<b>', '</b>', '<b><i>'.$page_title.'</i></b>', '<b>', '</b>'),
3354: 'problems_for_anon_page', 'CHOOSE_ANON1_PAGE'];
3355: }
3356: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]selected people[_5]',
3357: '<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'),
3358: 'problems_for_students', 'CHOOSE_STUDENTS'];
3359: push @{$printChoices}, [&mt('Selected [_1]Problems[_2] from folder [_3] for [_4]CODEd assignments[_5]',
3360: '<b>','</b>','<b><i>'.$sequenceTitle.'</i></b>','<b>','</b>'),
3361: 'problems_for_anon', 'CHOOSE_ANON1'];
1.284 albertel 3362: }
1.424 foxr 3363:
1.507 albertel 3364: my $randomly_ordered_warning =
3365: &get_randomly_ordered_warning($helper,$map);
3366:
1.424 foxr 3367: # resource_selector will hold a few states that:
3368: # - Allow resources to be selected for printing.
3369: # - Determine pagination between assignments.
3370: # - Determine how many assignments should be bundled into a single PDF.
3371: # TODO:
3372: # Probably good to do things like separate this up into several vars, each
3373: # with one state, and use REGEXPs at inclusion time to set state names
3374: # and next states for better mix and match capability
3375: #
1.562 foxr 3376: my $resource_selector= &generate_resource_chooser('SELECT_PROBLEMS',
3377: 'Select resources to print',
3378: 'multichoice="1" addstatus="1" closeallpages="1"',
3379: 'RESOURCES',
3380: 'PRINT_FORMATTING',
3381: '',
3382: $isProblem, '', $symbFilter,
3383: $start_new_option);
3384: $resource_selector .= <<RESOURCE_SELECTOR;
1.424 foxr 3385: <state name="PRINT_FORMATTING" title="How should results be printed?">
1.155 sakharuk 3386: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
1.149 bowersj2 3387: <choices variable="EMPTY_PAGES">
1.204 sakharuk 3388: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
3389: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
3390: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
3391: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 3392: </choices>
1.424 foxr 3393: <nextstate>PAGESIZE</nextstate>
1.429 foxr 3394: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
3395: <choices variable="SPLIT_PDFS">
3396: <choice computer="all">All assignments in a single PDF file</choice>
3397: <choice computer="sections">Each PDF contains exactly one section</choice>
3398: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 3399: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
3400: Specify the number of assignments per PDF:</choice>
1.429 foxr 3401: </choices>
1.424 foxr 3402: </state>
1.284 albertel 3403: RESOURCE_SELECTOR
1.562 foxr 3404: $resource_selector .= &generate_resource_chooser('CHOOSE_STUDENTS_PAGE',
3405: 'Select Problem(s) to print',
3406: "multichoice='1' addstatus='1' closeallpages ='1'",
3407: 'RESOURCES',
3408: 'PRINT_FORMATTING',
3409: $url,
3410: $isProblem, '', $symbFilter,
3411: $start_new_option);
3412:
3413:
3414: # Generate student choosers.
3415:
3416:
1.284 albertel 3417:
1.562 foxr 3418: &Apache::lonxml::xmlparse($r, 'helper',
3419: &generate_student_chooser('CHOOSE_TGT_STUDENTS_PAGE',
3420: 'student_sort',
3421: 'STUDENTS',
3422: 'CHOOSE_STUDENTS_PAGE'));
3423: &Apache::lonxml::xmlparse($r, 'helper',
3424: &generate_student_chooser('CHOOSE_STUDENTS',
3425: 'student_sort',
3426: 'STUDENTS',
3427: 'SELECT_PROBLEMS'));
3428: &Apache::lonxml::xmlparse($r, 'helper', $resource_selector);
1.292 albertel 3429:
1.373 albertel 3430: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
3431: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.292 albertel 3432: my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
3433: my $namechoice='<choice></choice>';
1.337 albertel 3434: foreach my $name (sort {uc($a) cmp uc($b)} @names) {
1.294 albertel 3435: if ($name =~ /^error: 2 /) { next; }
1.381 albertel 3436: if ($name =~ /^type\0/) { next; }
1.292 albertel 3437: $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>';
3438: }
1.389 foxr 3439:
3440:
3441: my %code_values;
1.405 albertel 3442: my %codes_to_print;
1.411 albertel 3443: foreach my $key (@names) {
1.389 foxr 3444: %code_values = &Apache::grades::get_codes($key, $cdom, $cnum);
1.405 albertel 3445: foreach my $key (keys(%code_values)) {
3446: $codes_to_print{$key} = 1;
1.388 foxr 3447: }
3448: }
1.389 foxr 3449:
1.452 albertel 3450: my $code_selection;
1.405 albertel 3451: foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) {
1.389 foxr 3452: my $choice = $code;
3453: if ($code =~ /^[A-Z]+$/) { # Alpha code
3454: $choice = &letters_to_num($code);
3455: }
1.432 albertel 3456: push(@{$helper->{DATA}{ALL_CODE_CHOICES}},[$code,$choice]);
1.388 foxr 3457: }
1.436 albertel 3458: if (%codes_to_print) {
3459: $code_selection .='
1.472 albertel 3460: <message><b>Choose single CODE from list:</b></message>
1.448 albertel 3461: <message></td><td></message>
1.452 albertel 3462: <dropdown variable="CODE_SELECTED_FROM_LIST" multichoice="0" allowempty="0">
3463: <choice></choice>
1.448 albertel 3464: <exec>
3465: push(@{$state->{CHOICES}},@{$helper->{DATA}{ALL_CODE_CHOICES}});
3466: </exec>
1.452 albertel 3467: </dropdown>
1.468 foxr 3468: <message></td></tr><tr><td></message>
1.436 albertel 3469: '.$/;
1.448 albertel 3470:
1.436 albertel 3471: }
1.432 albertel 3472:
1.542 raeburn 3473: my @lines = &Apache::grades::get_scantronformat_file();
1.381 albertel 3474: my $codechoice='';
1.542 raeburn 3475: foreach my $line (@lines) {
1.381 albertel 3476: my ($name,$description,$code_type,$code_length)=
3477: (split(/:/,$line))[0,1,2,4];
3478: if ($code_length > 0 &&
3479: $code_type =~/^(letter|number|-1)/) {
3480: $codechoice.='<choice computer="'.$name.'">'.$description.'</choice>';
3481: }
3482: }
3483: if ($codechoice eq '') {
3484: $codechoice='<choice computer="default">Default</choice>';
3485: }
1.562 foxr 3486: my $anon1 = &generate_code_selector($helper,
3487: 'CHOOSE_ANON1',
3488: 'SELECT_PROBLEMS',
3489: $codechoice,
3490: $code_selection,
3491: $namechoice) . $resource_selector;
3492:
3493:
3494: &Apache::lonxml::xmlparse($r, 'helper',$anon1);
3495:
3496: my $anon_page = &generate_code_selector($helper,
3497: 'CHOOSE_ANON1_PAGE',
3498: 'SELECT_PROBLEMS_PAGE',
3499: $codechoice,
3500: $code_selection,
3501: $namechoice) .
3502: &generate_resource_chooser('SELECT_PROBLEMS_PAGE',
3503: 'Select Problem(s) to print',
3504: "multichoice='1' addstatus='1' closeallpages ='1'",
3505: 'RESOURCES',
3506: 'PRINT_FORMATTING',
3507: $url,
3508: $isProblem, '', $symbFilter,
3509: $start_new_option);
3510: &Apache::lonxml::xmlparse($r, 'helper', $anon_page);
1.254 sakharuk 3511:
1.272 sakharuk 3512:
1.254 sakharuk 3513: if ($helper->{VARS}->{'assignment'}) {
1.546 bisitz 3514: 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'];
3515: 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 3516: }
1.284 albertel 3517:
3518:
3519: $resource_selector=<<RESOURCE_SELECTOR;
1.424 foxr 3520: <state name="SELECT_RESOURCES" title="Select Resources">
1.507 albertel 3521: $randomly_ordered_warning
1.424 foxr 3522: <nextstate>PRINT_FORMATTING</nextstate>
1.254 sakharuk 3523: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message>
1.287 albertel 3524: <resource variable="RESOURCES" multichoice="1" addstatus="1"
3525: closeallpages="1">
1.254 sakharuk 3526: <filterfunc>return $isNotMap;</filterfunc>
3527: <mapurl>$map</mapurl>
3528: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 3529: $start_new_option
1.254 sakharuk 3530: </resource>
1.424 foxr 3531: </state>
1.562 foxr 3532:
1.424 foxr 3533: <state name="PRINT_FORMATTING" title="Format of the print job">
3534: <nextstate>NUMBER_PER_PDF</nextstate>
1.254 sakharuk 3535: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message>
3536: <choices variable="EMPTY_PAGES">
3537: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice>
3538: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice>
3539: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice>
3540: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice>
1.284 albertel 3541: </choices>
1.424 foxr 3542: <nextstate>PAGESIZE</nextstate>
1.429 foxr 3543: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message>
3544: <choices variable="SPLIT_PDFS">
3545: <choice computer="all">All assignments in a single PDF file</choice>
3546: <choice computer="sections">Each PDF contains exactly one section</choice>
3547: <choice computer="oneper">Each PDF contains exactly one assignment</choice>
1.449 albertel 3548: <choice computer="usenumber" relatedvalue="NUMBER_TO_PRINT">
3549: Specify the number of assignments per PDF:</choice>
1.429 foxr 3550: </choices>
1.424 foxr 3551: </state>
1.284 albertel 3552: RESOURCE_SELECTOR
3553:
3554: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1);
3555: <state name="CHOOSE_STUDENTS1" title="Select Students and Resources">
1.340 foxr 3556: <choices variable='student_sort'>
3557: <choice computer='0'>Sort by section then student</choice>
3558: <choice computer='1'>Sort by students across sections.</choice>
3559: </choices>
1.437 foxr 3560: <message><br /><hr /><br /></message>
1.426 foxr 3561: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" />
1.340 foxr 3562:
1.424 foxr 3563: </state>
1.284 albertel 3564: $resource_selector
1.254 sakharuk 3565: CHOOSE_STUDENTS1
3566:
1.284 albertel 3567: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2);
1.472 albertel 3568: <state name="CHOOSE_ANON2" title="Select CODEd Assignments">
1.424 foxr 3569: <nextstate>SELECT_RESOURCES</nextstate>
1.472 albertel 3570: <message><h4>Fill out one of the forms below</h4></message>
3571: <message><br /><hr /> <br /></message>
3572: <message><h3>Generate new CODEd Assignments</h3></message>
3573: <message><table><tr><td><b>Number of CODEd assignments to print:</b></td><td></message>
1.362 albertel 3574: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5">
3575: <validator>
3576: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) &&
1.386 foxr 3577: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
1.388 foxr 3578: !\$helper->{'VARS'}{'SINGLE_CODE'} &&
3579: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.362 albertel 3580: return "You need to specify the number of assignments to print";
3581: }
3582: return undef;
3583: </validator>
3584: </string>
3585: <message></td></tr><tr><td></message>
1.501 albertel 3586: <message><b>Names to save the CODEs under for later:</b></message>
1.412 albertel 3587: <message></td><td></message>
3588: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" />
3589: <message></td></tr><tr><td></message>
3590: <message><b>Bubble sheet type:</b></message>
3591: <message></td><td></message>
3592: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0">
3593: $codechoice
3594: </dropdown>
1.472 albertel 3595: <message></td></tr><tr><td></table></message>
3596: <message><br /><hr /><h3>Print a Specific CODE </h3><br /><table></message>
3597: <message><tr><td><b>Enter a CODE to print:</b></td><td></message>
1.412 albertel 3598: <string variable="SINGLE_CODE" size="10">
1.386 foxr 3599: <validator>
3600: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} &&
1.388 foxr 3601: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} &&
3602: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) {
1.386 foxr 3603: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'},
3604: \$helper->{'VARS'}{'CODE_OPTION'});
3605: } else {
3606: return undef; # Other forces control us.
3607: }
3608: </validator>
3609: </string>
1.472 albertel 3610: <message></td></tr><tr><td></message>
1.432 albertel 3611: $code_selection
1.472 albertel 3612: <message></td></tr></table></message>
3613: <message><hr /><h3>Reprint a Set of Saved CODEs</h3><table><tr><td></message>
3614: <message><b>Select saved CODEs:</b></message>
1.381 albertel 3615: <message></td><td></message>
1.294 albertel 3616: <dropdown variable="REUSE_OLD_CODES">
3617: $namechoice
3618: </dropdown>
1.412 albertel 3619: <message></td></tr></table></message>
1.424 foxr 3620: </state>
1.284 albertel 3621: $resource_selector
3622: CHOOSE_ANON2
1.481 albertel 3623: }
3624:
1.121 bowersj2 3625: # FIXME: That RE should come from a library somewhere.
1.483 foxr 3626: if (($perm{'pav'}
1.482 albertel 3627: && $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'
3628: && (defined($helper->{'VARS'}->{'construction'})
3629: ||
3630: (&Apache::lonnet::allowed('bre',$subdir) eq 'F'
3631: &&
3632: $helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)
1.483 foxr 3633: ))
3634: && $helper->{VARS}->{'assignment'} eq ""
1.482 albertel 3635: ) {
3636: my $pretty_dir = &Apache::lonnet::hreflocation($subdir);
1.546 bisitz 3637: 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 3638: my $xmlfrag = <<CHOOSE_FROM_SUBDIR;
1.482 albertel 3639: <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$pretty_dir</small></b> to print">
1.458 www 3640:
1.138 bowersj2 3641: <files variable="FILES" multichoice='1'>
1.144 bowersj2 3642: <nextstate>PAGESIZE</nextstate>
1.138 bowersj2 3643: <filechoice>return '$subdir';</filechoice>
1.139 bowersj2 3644: CHOOSE_FROM_SUBDIR
3645:
1.238 bowersj2 3646: # this is broken up because I really want interpolation above,
3647: # and I really DON'T want it below
1.139 bowersj2 3648: $xmlfrag .= <<'CHOOSE_FROM_SUBDIR';
1.225 bowersj2 3649: <filefilter>return Apache::lonhelper::files::not_old_version($filename) &&
3650: $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/;
1.131 bowersj2 3651: </filefilter>
1.138 bowersj2 3652: </files>
1.131 bowersj2 3653: </state>
3654: CHOOSE_FROM_SUBDIR
1.139 bowersj2 3655: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.131 bowersj2 3656: }
1.238 bowersj2 3657:
3658: # Allow the user to select any sequence in the course, feed it to
3659: # another resource selector for that sequence
1.483 foxr 3660: if (!$helper->{VARS}->{'construction'} && !$is_published) {
1.509 albertel 3661: push @$printChoices, [&mtn("Selected <b>Resources</b> from <b>selected folder</b> in course"),
1.249 sakharuk 3662: 'select_sequences', 'CHOOSE_SEQUENCE'];
1.244 bowersj2 3663: my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'};
3664: #Escape apostrophes and backslashes for Perl
3665: $escapedSequenceName =~ s/\\/\\\\/g;
3666: $escapedSequenceName =~ s/'/\\'/g;
1.239 bowersj2 3667: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE);
1.238 bowersj2 3668: <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From">
3669: <message>Select the sequence to print resources from:</message>
3670: <resource variable="SEQUENCE">
3671: <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate>
3672: <filterfunc>return \$res->is_sequence;</filterfunc>
3673: <valuefunc>return $urlValue;</valuefunc>
1.447 foxr 3674: <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0);
1.391 foxr 3675: </choicefunc>
1.238 bowersj2 3676: </resource>
3677: </state>
3678: <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print">
3679: <message>(mark desired resources then click "next" button) <br /></message>
1.435 foxr 3680: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1"
1.287 albertel 3681: closeallpages="1">
1.238 bowersj2 3682: <nextstate>PAGESIZE</nextstate>
1.466 albertel 3683: <filterfunc>return $isNotMap</filterfunc>
1.244 bowersj2 3684: <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl>
1.238 bowersj2 3685: <valuefunc>return $symbFilter;</valuefunc>
1.465 albertel 3686: $start_new_option
1.238 bowersj2 3687: </resource>
3688: </state>
3689: CHOOSE_FROM_ANY_SEQUENCE
1.239 bowersj2 3690: }
1.481 albertel 3691:
1.131 bowersj2 3692: # Generate the first state, to select which resources get printed.
1.223 bowersj2 3693: Apache::lonhelper::state->new("START", "Select Printing Options:");
1.131 bowersj2 3694: $paramHash = Apache::lonhelper::getParamHash();
1.155 sakharuk 3695: $paramHash->{MESSAGE_TEXT} = "";
1.131 bowersj2 3696: Apache::lonhelper::message->new();
3697: $paramHash = Apache::lonhelper::getParamHash();
3698: $paramHash->{'variable'} = 'PRINT_TYPE';
3699: $paramHash->{CHOICES} = $printChoices;
3700: Apache::lonhelper::choices->new();
1.161 bowersj2 3701:
1.223 bowersj2 3702: my $startedTable = 0; # have we started an HTML table yet? (need
3703: # to close it later)
3704:
1.397 albertel 3705: if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or
1.170 sakharuk 3706: ($helper->{VARS}->{'construction'} eq '1')) {
1.544 bisitz 3707: &addMessage('<br />'
3708: .'<h3>'.&mt('Print Options').'</h3>'
3709: .&Apache::lonhtmlcommon::start_pick_box()
3710: .&Apache::lonhtmlcommon::row_title(
3711: '<label for="ANSWER_TYPE_forminput">'
3712: .&mt('Print Answers')
3713: .'</label>'
3714: )
3715: );
1.161 bowersj2 3716: $paramHash = Apache::lonhelper::getParamHash();
1.162 sakharuk 3717: $paramHash->{'variable'} = 'ANSWER_TYPE';
3718: $helper->declareVar('ANSWER_TYPE');
1.161 bowersj2 3719: $paramHash->{CHOICES} = [
1.242 sakharuk 3720: ['Without Answers', 'yes'],
3721: ['With Answers', 'no'],
1.368 albertel 3722: ['Only Answers', 'only']
1.289 sakharuk 3723: ];
1.210 sakharuk 3724: Apache::lonhelper::dropdown->new();
1.544 bisitz 3725: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.223 bowersj2 3726: $startedTable = 1;
1.556 foxr 3727:
3728: #
3729: # Select font size.
3730: #
3731:
3732: $helper->declareVar('fontsize');
3733: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Font Size')));
3734: my $xmlfrag = << "FONT_SELECTION";
3735:
3736:
3737: <dropdown variable='fontsize' multichoice='0', allowempty='0'>
3738: <defaultvalue>
3739: return 'normalsize';
3740: </defaultvalue>
3741: <choice computer='tiny'>Tiny</choice>
3742: <choice computer='sub/superscriptsize'>Script Size</choice>
3743: <choice computer='footnotesize'>Footnote Size</choice>
3744: <choice computer='small'>Small</choice>
3745: <choice computer='normalsize'>Normal (default)</choice>
3746: <choice computer='large'>larger than normal</choice>
3747: <choice computer='Large'>Even larger than normal</choice>
3748: <choice computer='LARGE'>Still larger than normal</choice>
3749: <choice computer='huge'>huge font size</choice>
3750: <choice computer='Huge'>Largest possible size</choice>
3751: </dropdown>
3752: FONT_SELECTION
3753: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
3754: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.161 bowersj2 3755: }
1.209 sakharuk 3756:
1.397 albertel 3757: if ($perm{'pav'}) {
1.223 bowersj2 3758: if (!$startedTable) {
1.497 www 3759: addMessage("<hr width='33%' /><table><tr><td align='right'>".
3760: '<label for="LATEX_TYPE_forminput">'.
3761: &mt('LaTeX mode').
3762: "</label>: </td><td>");
1.223 bowersj2 3763: $startedTable = 1;
3764: } else {
1.544 bisitz 3765: &addMessage(&Apache::lonhtmlcommon::row_title(
3766: '<label for="LATEX_TYPE_forminput">'
3767: .&mt('LaTeX mode')
3768: .'</label>'
3769: )
3770: );
1.223 bowersj2 3771: }
1.203 sakharuk 3772: $paramHash = Apache::lonhelper::getParamHash();
3773: $paramHash->{'variable'} = 'LATEX_TYPE';
3774: $helper->declareVar('LATEX_TYPE');
3775: if ($helper->{VARS}->{'construction'} eq '1') {
3776: $paramHash->{CHOICES} = [
1.223 bowersj2 3777: ['standard LaTeX mode', 'standard'],
3778: ['LaTeX batchmode', 'batchmode'], ];
1.203 sakharuk 3779: } else {
3780: $paramHash->{CHOICES} = [
1.223 bowersj2 3781: ['LaTeX batchmode', 'batchmode'],
3782: ['standard LaTeX mode', 'standard'] ];
1.203 sakharuk 3783: }
1.210 sakharuk 3784: Apache::lonhelper::dropdown->new();
1.218 sakharuk 3785:
1.544 bisitz 3786: &addMessage(&Apache::lonhtmlcommon::row_closure()
3787: .&Apache::lonhtmlcommon::row_title(
3788: '<label for="TABLE_CONTENTS_forminput">'
3789: .&mt('Print Table of Contents')
3790: .'</label>'
3791: )
3792: );
1.209 sakharuk 3793: $paramHash = Apache::lonhelper::getParamHash();
3794: $paramHash->{'variable'} = 'TABLE_CONTENTS';
3795: $helper->declareVar('TABLE_CONTENTS');
3796: $paramHash->{CHOICES} = [
1.223 bowersj2 3797: ['No', 'no'],
3798: ['Yes', 'yes'] ];
1.210 sakharuk 3799: Apache::lonhelper::dropdown->new();
1.544 bisitz 3800: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.214 sakharuk 3801:
1.220 sakharuk 3802: if (not $helper->{VARS}->{'construction'}) {
1.545 bisitz 3803: &addMessage(&Apache::lonhtmlcommon::row_title(
3804: '<label for="TABLE_INDEX_forminput">'
3805: .&mt('Print Index')
3806: .'</label>'
3807: )
3808: );
1.220 sakharuk 3809: $paramHash = Apache::lonhelper::getParamHash();
3810: $paramHash->{'variable'} = 'TABLE_INDEX';
3811: $helper->declareVar('TABLE_INDEX');
3812: $paramHash->{CHOICES} = [
1.223 bowersj2 3813: ['No', 'no'],
3814: ['Yes', 'yes'] ];
1.220 sakharuk 3815: Apache::lonhelper::dropdown->new();
1.545 bisitz 3816: &addMessage(&Apache::lonhtmlcommon::row_closure());
3817: &addMessage(&Apache::lonhtmlcommon::row_title(
3818: '<label for="PRINT_DISCUSSIONS_forminput">'
3819: .&mt('Print Discussions')
3820: .'</label>'
3821: )
3822: );
1.309 sakharuk 3823: $paramHash = Apache::lonhelper::getParamHash();
3824: $paramHash->{'variable'} = 'PRINT_DISCUSSIONS';
3825: $helper->declareVar('PRINT_DISCUSSIONS');
3826: $paramHash->{CHOICES} = [
3827: ['No', 'no'],
3828: ['Yes', 'yes'] ];
3829: Apache::lonhelper::dropdown->new();
1.545 bisitz 3830: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.372 foxr 3831:
1.511 foxr 3832: # Prompt for printing annotations too.
3833:
1.545 bisitz 3834: &addMessage(&Apache::lonhtmlcommon::row_title(
3835: '<label for="PRINT_ANNOTATIONS_forminput">'
3836: .&mt('Print Annotations')
3837: .'</label>'
3838: )
3839: );
1.511 foxr 3840: $paramHash = Apache::lonhelper::getParamHash();
3841: $paramHash->{'variable'} = "PRINT_ANNOTATIONS";
3842: $helper->declareVar("PRINT_ANNOTATIONS");
3843: $paramHash->{CHOICES} = [
3844: ['No', 'no'],
3845: ['Yes', 'yes']];
3846: Apache::lonhelper::dropdown->new();
1.545 bisitz 3847: &addMessage(&Apache::lonhtmlcommon::row_closure());
1.511 foxr 3848:
1.545 bisitz 3849: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Foils')));
1.397 albertel 3850: $paramHash = Apache::lonhelper::getParamHash();
3851: $paramHash->{'multichoice'} = "true";
3852: $paramHash->{'allowempty'} = "true";
3853: $paramHash->{'variable'} = "showallfoils";
1.555 bisitz 3854: $paramHash->{'CHOICES'} = [ [&mt('Show All Foils'), "1"] ];
1.397 albertel 3855: Apache::lonhelper::choices->new();
1.545 bisitz 3856: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.220 sakharuk 3857: }
1.219 sakharuk 3858:
1.230 albertel 3859: if ($helper->{'VARS'}->{'construction'}) {
1.505 albertel 3860: my $stylevalue='$Apache::lonnet::env{"construct.style"}';
1.497 www 3861: my $randseedtext=&mt("Use random seed");
3862: my $stylefiletext=&mt("Use style file");
1.506 albertel 3863: my $selectfiletext=&mt("Select style file");
1.497 www 3864:
1.544 bisitz 3865: my $xmlfrag .= '<message>'
3866: .&Apache::lonhtmlcommon::row_title('<label for="curseed_forminput">'
3867: .$randseedtext
3868: .'</label>'
3869: )
3870: .'</message>
3871: <string variable="curseed" size="15" maxlength="15">
3872: <defaultvalue>
3873: return '.$helper->{VARS}->{'curseed'}.';
3874: </defaultvalue>'
3875: .'</string>'
3876: .'<message>'
3877: .&Apache::lonhtmlcommon::row_closure()
3878: .&Apache::lonhtmlcommon::row_title('<label for="style_file">'
3879: .$stylefiletext
3880: .'</label>'
3881: )
3882: .'</message>
1.504 albertel 3883: <string variable="style_file" size="40">
1.544 bisitz 3884: <defaultvalue>
3885: return '.$stylevalue.';
3886: </defaultvalue>
3887: </string><message> '
3888: .qq|<a href="javascript:openbrowser('helpform','style_file_forminput','sty')">|
3889: .$selectfiletext.'</a>'
3890: .&Apache::lonhtmlcommon::row_closure()
1.555 bisitz 3891: .&Apache::lonhtmlcommon::row_title(&mt('Show All Foils'))
1.544 bisitz 3892: .'</message>
1.371 foxr 3893: <choices allowempty="1" multichoice="true" variable="showallfoils">
1.544 bisitz 3894: <choice computer="1"> </choice>
3895: </choices>'
3896: .'<message>'
3897: .&Apache::lonhtmlcommon::row_closure()
3898: .'</message>';
1.230 albertel 3899: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.512 foxr 3900:
3901:
1.544 bisitz 3902: &addMessage(&Apache::lonhtmlcommon::row_title(&mt('Problem Type')));
1.512 foxr 3903: #
3904: # Initial value from construction space:
3905: #
3906: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) {
3907: $helper->{VARS}->{'probstatus'} = $env{'form.problemtype'}; # initial value
3908: }
1.518 foxr 3909: $xmlfrag = << "PROBTYPE";
3910: <dropdown variable="probstatus" multichoice="0" allowempty="0">
3911: <defaultvalue>
3912: return "$helper->{VARS}->{'probstatus'}";
3913: </defaultvalue>
3914: <choice computer="problem">Homework Problem</choice>
3915: <choice computer="exam">Exam Problem</choice>
3916: <choice computer="survey">Survey question</choice>
3917: </dropdown>
3918: PROBTYPE
3919: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag);
1.544 bisitz 3920: &addMessage(&Apache::lonhtmlcommon::row_closure(1));
1.512 foxr 3921:
1.556 foxr 3922:
3923:
1.544 bisitz 3924: }
1.223 bowersj2 3925: }
1.264 sakharuk 3926:
3927:
3928:
1.218 sakharuk 3929:
1.223 bowersj2 3930: if ($startedTable) {
1.544 bisitz 3931: &addMessage(&Apache::lonhtmlcommon::end_pick_box());
1.215 sakharuk 3932: }
1.161 bowersj2 3933:
1.131 bowersj2 3934: Apache::lonprintout::page_format_state->new("FORMAT");
3935:
1.144 bowersj2 3936: # Generate the PAGESIZE state which will offer the user the margin
3937: # choices if they select one column
3938: Apache::lonhelper::state->new("PAGESIZE", "Set Margins");
3939: Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL');
3940:
3941:
1.131 bowersj2 3942: $helper->process();
3943:
1.416 foxr 3944:
1.131 bowersj2 3945: # MANUAL BAILOUT CONDITION:
3946: # If we're in the "final" state, bailout and return to handler
3947: if ($helper->{STATE} eq 'FINAL') {
3948: return $helper;
3949: }
1.130 sakharuk 3950:
1.131 bowersj2 3951: $r->print($helper->display());
1.395 www 3952: if ($helper->{STATE} eq 'START') {
3953: &recently_generated($r);
3954: }
1.333 albertel 3955: &Apache::lonhelper::unregisterHelperTags();
1.115 bowersj2 3956:
3957: return OK;
3958: }
3959:
1.1 www 3960:
3961: 1;
1.119 bowersj2 3962:
3963: package Apache::lonprintout::page_format_state;
3964:
3965: =pod
3966:
1.131 bowersj2 3967: =head1 Helper element: page_format_state
3968:
3969: See lonhelper.pm documentation for discussion of the helper framework.
1.119 bowersj2 3970:
1.131 bowersj2 3971: Apache::lonprintout::page_format_state is an element that gives the
3972: user an opportunity to select the page layout they wish to print
3973: with: Number of columns, portrait/landscape, and paper size. If you
3974: want to change the paper size choices, change the @paperSize array
3975: contents in this package.
1.119 bowersj2 3976:
1.131 bowersj2 3977: page_format_state is always directly invoked in lonprintout.pm, so there
3978: is no tag interface. You actually pass parameters to the constructor.
1.119 bowersj2 3979:
3980: =over 4
3981:
1.131 bowersj2 3982: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
1.119 bowersj2 3983:
3984: =back
3985:
3986: =cut
3987:
1.131 bowersj2 3988: use Apache::lonhelper;
1.119 bowersj2 3989:
3990: no strict;
1.131 bowersj2 3991: @ISA = ("Apache::lonhelper::element");
1.119 bowersj2 3992: use strict;
1.266 sakharuk 3993: use Apache::lonlocal;
1.373 albertel 3994: use Apache::lonnet;
1.119 bowersj2 3995:
3996: my $maxColumns = 2;
1.376 albertel 3997: # it'd be nice if these all worked
3998: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
3999: # "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]",
4000: # "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]",
4001: # "a5 [148x210 mm]", "a6 [105x148 mm]" );
1.326 sakharuk 4002: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]",
1.376 albertel 4003: "a4 [210x297 mm]");
1.119 bowersj2 4004:
4005: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum |
4006: # Paper type
4007:
4008: sub new {
1.131 bowersj2 4009: my $self = Apache::lonhelper::element->new();
1.119 bowersj2 4010:
1.135 bowersj2 4011: shift;
4012:
1.131 bowersj2 4013: $self->{'variable'} = shift;
1.134 bowersj2 4014: my $helper = Apache::lonhelper::getHelper();
1.135 bowersj2 4015: $helper->declareVar($self->{'variable'});
1.131 bowersj2 4016: bless($self);
1.119 bowersj2 4017: return $self;
4018: }
4019:
4020: sub render {
4021: my $self = shift;
1.131 bowersj2 4022: my $helper = Apache::lonhelper::getHelper();
1.119 bowersj2 4023: my $result = '';
1.131 bowersj2 4024: my $var = $self->{'variable'};
1.266 sakharuk 4025: my $PageLayout=&mt('Page layout');
4026: my $NumberOfColumns=&mt('Number of columns');
4027: my $PaperType=&mt('Paper type');
1.506 albertel 4028: my $landscape=&mt('Landscape');
4029: my $portrait=&mt('Portrait');
1.539 onken 4030: my $pdfFormLabel=&mt('PDF-Formfields');
4031: my $with=&mt('with Formfields');
4032: my $without=&mt('without Formfields');
1.556 foxr 4033:
4034:
1.544 bisitz 4035: $result.='<h3>'.&mt('Layout Options').'</h3>'
4036: .&Apache::loncommon::start_data_table()
4037: .&Apache::loncommon::start_data_table_header_row()
4038: .'<th>'.$PageLayout.'</th>'
4039: .'<th>'.$NumberOfColumns.'</th>'
4040: .'<th>'.$PaperType.'</th>'
4041: .'<th>'.$pdfFormLabel.'</th>'
4042: .&Apache::loncommon::end_data_table_header_row()
4043: .&Apache::loncommon::start_data_table_row()
4044: .'<td>'
4045: .'<label><input type="radio" name="'.${var}.'.layout" value="L" />'.$landscape.'</label><br />'
4046: .'<label><input type="radio" name="'.${var}.'.layout" value="P" checked="checked" />'.$portrait.'</label>'
4047: .'</td>';
1.119 bowersj2 4048:
1.544 bisitz 4049: $result.='<td align="center">'
4050: .'<select name="'.${var}.'.cols">';
1.119 bowersj2 4051:
4052: my $i;
4053: for ($i = 1; $i <= $maxColumns; $i++) {
1.144 bowersj2 4054: if ($i == 2) {
1.553 bisitz 4055: $result .= '<option value="'.$i.'" selected="selected">'.$i.'</option>'."\n";
1.119 bowersj2 4056: } else {
1.553 bisitz 4057: $result .= '<option value="'.$i.'">'.$i.'</option>'."\n";
1.119 bowersj2 4058: }
4059: }
4060:
4061: $result .= "</select></td><td>\n";
4062: $result .= "<select name='${var}.paper'>\n";
4063:
1.373 albertel 4064: my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'});
1.398 albertel 4065: my $DefaultPaperSize=lc($parmhash{'default_paper_size'});
4066: $DefaultPaperSize=~s/\s//g;
1.304 sakharuk 4067: if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';}
1.119 bowersj2 4068: $i = 0;
4069: foreach (@paperSize) {
1.326 sakharuk 4070: $_=~/(\w+)/;
4071: my $papersize=$1;
1.304 sakharuk 4072: if ($paperSize[$i]=~/$DefaultPaperSize/) {
1.553 bisitz 4073: $result .= '<option selected="selected" value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119 bowersj2 4074: } else {
1.553 bisitz 4075: $result .= '<option value="'.$papersize.'">'.$paperSize[$i].'</option>'."\n";
1.119 bowersj2 4076: }
4077: $i++;
4078: }
1.539 onken 4079: $result .= <<HTML;
4080: </select>
4081: </td>
4082: <td align='center'>
4083: <select name='${var}.pdfFormFields'>
1.553 bisitz 4084: <option selected="selected" value="no">$without</option>
4085: <option value="yes">$with</option>
1.539 onken 4086: </select>
4087: </td>
4088: HTML
1.544 bisitz 4089: $result.=&Apache::loncommon::end_data_table_row()
4090: .&Apache::loncommon::end_data_table();
1.539 onken 4091:
1.119 bowersj2 4092: return $result;
1.135 bowersj2 4093: }
4094:
4095: sub postprocess {
4096: my $self = shift;
4097:
4098: my $var = $self->{'variable'};
1.136 bowersj2 4099: my $helper = Apache::lonhelper->getHelper();
1.135 bowersj2 4100: $helper->{VARS}->{$var} =
1.373 albertel 4101: $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' .
1.539 onken 4102: $env{"form.$var.paper"} . '|' . $env{"form.$var.pdfFormFields"};
1.135 bowersj2 4103: return 1;
1.119 bowersj2 4104: }
4105:
4106: 1;
1.144 bowersj2 4107:
4108: package Apache::lonprintout::page_size_state;
4109:
4110: =pod
4111:
4112: =head1 Helper element: page_size_state
4113:
4114: See lonhelper.pm documentation for discussion of the helper framework.
4115:
4116: Apache::lonprintout::page_size_state is an element that gives the
4117: user the opportunity to further refine the page settings if they
4118: select a single-column page.
4119:
4120: page_size_state is always directly invoked in lonprintout.pm, so there
4121: is no tag interface. You actually pass parameters to the constructor.
4122:
4123: =over 4
4124:
4125: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME.
4126:
4127: =back
4128:
4129: =cut
4130:
4131: use Apache::lonhelper;
1.373 albertel 4132: use Apache::lonnet;
1.144 bowersj2 4133: no strict;
4134: @ISA = ("Apache::lonhelper::element");
4135: use strict;
4136:
4137:
4138:
4139: sub new {
4140: my $self = Apache::lonhelper::element->new();
4141:
4142: shift; # disturbs me (probably prevents subclassing) but works (drops
4143: # package descriptor)... - Jeremy
4144:
4145: $self->{'variable'} = shift;
4146: my $helper = Apache::lonhelper::getHelper();
4147: $helper->declareVar($self->{'variable'});
4148:
4149: # The variable name of the format element, so we can look into
4150: # $helper->{VARS} to figure out whether the columns are one or two
4151: $self->{'formatvar'} = shift;
4152:
1.463 foxr 4153:
1.144 bowersj2 4154: $self->{NEXTSTATE} = shift;
4155: bless($self);
1.467 foxr 4156:
1.144 bowersj2 4157: return $self;
4158: }
4159:
4160: sub render {
4161: my $self = shift;
4162: my $helper = Apache::lonhelper::getHelper();
4163: my $result = '';
4164: my $var = $self->{'variable'};
4165:
1.467 foxr 4166:
4167:
1.144 bowersj2 4168: if (defined $self->{ERROR_MSG}) {
1.464 albertel 4169: $result .= '<br /><span class="LC_error">' . $self->{ERROR_MSG} . '</span><br />';
1.144 bowersj2 4170: }
4171:
1.438 foxr 4172: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.463 foxr 4173:
4174: # Use format to get sensible defaults for the margins:
4175:
4176:
4177: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
4178: ($papersize) = split(/ /, $papersize);
4179:
1.559 foxr 4180: $laystyle = &Apache::lonprintout::map_laystyle($laystyle);
1.463 foxr 4181:
4182:
4183:
1.464 albertel 4184: my %size;
4185: ($size{'width_and_units'},
4186: $size{'height_and_units'},
4187: $size{'margin_and_units'})=
4188: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
1.463 foxr 4189:
1.464 albertel 4190: foreach my $dimension ('width','height','margin') {
4191: ($size{$dimension},$size{$dimension.'_unit'}) =
4192: split(/ +/, $size{$dimension.'_and_units'},2);
4193:
4194: foreach my $unit ('cm','in') {
4195: $size{$dimension.'_options'} .= '<option ';
4196: if ($size{$dimension.'_unit'} eq $unit) {
4197: $size{$dimension.'_options'} .= 'selected="selected" ';
4198: }
4199: $size{$dimension.'_options'} .= '>'.$unit.'</option>';
4200: }
1.438 foxr 4201: }
4202:
1.470 foxr 4203: # Adjust margin for LaTeX margin: .. requires units == cm or in.
4204:
4205: if ($size{'margin_unit'} eq 'in') {
4206: $size{'margin'} += 1;
4207: } else {
4208: $size{'margin'} += 2.54;
4209: }
1.548 bisitz 4210: my %lt = &Apache::lonlocal::texthash(
4211: 'format' => 'How should each column be formatted?',
4212: 'width' => 'Width',
4213: 'height' => 'Height',
4214: 'margin' => 'Left Margin'
4215: );
4216:
4217: $result .= '<p>'.$lt{'format'}.'</p>'
4218: .&Apache::lonhtmlcommon::start_pick_box()
4219: .&Apache::lonhtmlcommon::row_title($lt{'width'})
4220: .'<input type="text" name="'.$var.'.width" value="'.$size{'width'}.'" size="4" />'
4221: .'<select name="'.$var.'.widthunit">'
4222: .$size{'width_options'}
4223: .'</select>'
4224: .&Apache::lonhtmlcommon::row_closure()
4225: .&Apache::lonhtmlcommon::row_title($lt{'height'})
4226: .'<input type="text" name="'.$var.'.height" value="'.$size{'height'}.'" size="4" />'
4227: .'<select name="'.$var.'.heightunit">'
4228: .$size{'height_options'}
4229: .'</select>'
4230: .&Apache::lonhtmlcommon::row_closure()
4231: .&Apache::lonhtmlcommon::row_title($lt{'margin'})
4232: .'<input type="text" name="'.$var.'.lmargin" value="'.$size{'margin'}.'" size="4" />'
4233: .'<select name="'.$var.'.lmarginunit">'
4234: .$size{'margin_options'}
4235: .'</select>'
4236: .&Apache::lonhtmlcommon::row_closure(1)
4237: .&Apache::lonhtmlcommon::end_pick_box();
4238: # <p>Hint: Some instructors like to leave scratch space for the student by
4239: # making the width much smaller than the width of the page.</p>
1.144 bowersj2 4240:
4241: return $result;
4242: }
4243:
1.470 foxr 4244:
1.144 bowersj2 4245: sub preprocess {
4246: my $self = shift;
4247: my $helper = Apache::lonhelper::getHelper();
4248:
4249: my $format = $helper->{VARS}->{$self->{'formatvar'}};
1.467 foxr 4250:
4251: # If the user does not have 'pav' privilege, set default widths and
4252: # on to the next state right away.
4253: #
4254: if (!$perm{'pav'}) {
4255: my $var = $self->{'variable'};
4256: my $format = $helper->{VARS}->{$self->{'formatvar'}};
4257:
4258: my ($laystyle, $cols, $papersize) = split(/\|/, $format);
4259: ($papersize) = split(/ /, $papersize);
4260:
4261:
1.560 foxr 4262: $laystyle = &Apache::lonprintout::map_laystyle($laystyle);
1.559 foxr 4263:
1.467 foxr 4264: # Figure out some good defaults for the print out and set them:
4265:
4266: my %size;
4267: ($size{'width'},
4268: $size{'height'},
4269: $size{'lmargin'})=
4270: &Apache::lonprintout::page_format($papersize, $laystyle, $cols);
4271:
4272: foreach my $dim ('width', 'height', 'lmargin') {
4273: my ($value, $units) = split(/ /, $size{$dim});
1.470 foxr 4274:
1.467 foxr 4275: $helper->{VARS}->{"$var.".$dim} = $value;
4276: $helper->{VARS}->{"$var.".$dim.'unit'} = $units;
4277:
4278: }
4279:
4280:
4281: # Transition to the next state
4282:
4283: $helper->changeState($self->{NEXTSTATE});
4284: }
1.144 bowersj2 4285:
4286: return 1;
4287: }
4288:
4289: sub postprocess {
4290: my $self = shift;
4291:
4292: my $var = $self->{'variable'};
4293: my $helper = Apache::lonhelper->getHelper();
1.373 albertel 4294: my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"};
4295: my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"};
4296: my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"};
4297: $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"};
4298: $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"};
4299: $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"};
1.144 bowersj2 4300:
4301: my $error = '';
4302:
4303: # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed
4304: # by an optional period, followed by digits, ending the string
4305:
1.464 albertel 4306: if ($width !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 4307: $error .= "Invalid width; please type only a number.<br />\n";
4308: }
1.464 albertel 4309: if ($height !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 4310: $error .= "Invalid height; please type only a number.<br />\n";
4311: }
1.464 albertel 4312: if ($lmargin !~ /^-?[0-9]*(\.[0-9]*)?$/) {
1.144 bowersj2 4313: $error .= "Invalid left margin; please type only a number.<br />\n";
1.470 foxr 4314: } else {
4315: # Adjust for LaTeX 1.0 inch margin:
4316:
4317: if ($env{"form.${var}.lmarginunit"} eq "in") {
4318: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 1;
4319: } else {
4320: $helper->{VARS}->{$var.'.lmargin'} = $lmargin - 2.54;
4321: }
1.144 bowersj2 4322: }
4323:
4324: if (!$error) {
4325: Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE});
4326: return 1;
4327: } else {
4328: $self->{ERROR_MSG} = $error;
4329: return 0;
4330: }
4331: }
4332:
4333:
1.119 bowersj2 4334:
1.1 www 4335: __END__
1.6 sakharuk 4336:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>