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