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