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