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