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