![]() ![]() | ![]() |
- mode <head> </headh> <</body> elimination
1: # The LearningOnline Network 2: # Printout 3: # 4: # $Id: lonprintout.pm,v 1.431 2006/03/15 22:11:04 albertel Exp $ 5: # 6: # Copyright Michigan State University Board of Trustees 7: # 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA). 9: # 10: # LON-CAPA is free software; you can redistribute it and/or modify 11: # it under the terms of the GNU General Public License as published by 12: # the Free Software Foundation; either version 2 of the License, or 13: # (at your option) any later version. 14: # 15: # LON-CAPA is distributed in the hope that it will be useful, 16: # but WITHOUT ANY WARRANTY; without even the implied warranty of 17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: # GNU General Public License for more details. 19: # 20: # You should have received a copy of the GNU General Public License 21: # along with LON-CAPA; if not, write to the Free Software 22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23: # 24: # /home/httpd/html/adm/gpl.txt 25: # 26: # http://www.lon-capa.org/ 27: # 28: # 29: package Apache::lonprintout; 30: 31: use strict; 32: use Apache::Constants qw(:common :http); 33: use Apache::lonxml; 34: use Apache::lonnet; 35: use Apache::loncommon; 36: use Apache::inputtags; 37: use Apache::grades; 38: use Apache::edit; 39: use Apache::File(); 40: use Apache::lonnavmaps; 41: use Apache::lonratedt; 42: use POSIX qw(strftime); 43: use Apache::lonlocal; 44: use Carp; 45: 46: my %perm; 47: 48: # 49: # Convert a numeric code to letters 50: # 51: sub num_to_letters { 52: my ($num) = @_; 53: my @nums= split('',$num); 54: my @num_to_let=('A'..'Z'); 55: my $word; 56: foreach my $digit (@nums) { $word.=$num_to_let[$digit]; } 57: return $word; 58: } 59: # Convert a letter code to numeric. 60: # 61: sub letters_to_num { 62: my ($letters) = @_; 63: my @letters = split('', uc($letters)); 64: my %substitution; 65: my $digit = 0; 66: foreach my $letter ('A'..'J') { 67: $substitution{$letter} = $digit; 68: $digit++; 69: } 70: # The substitution is done as below to preserve leading 71: # zeroes which are needed to keep the code size exact 72: # 73: my $result =""; 74: foreach my $letter (@letters) { 75: $result.=$substitution{$letter}; 76: } 77: return $result; 78: } 79: 80: # Determine if a code is a valid numeric code. Valid 81: # numeric codes must be comprised entirely of digits and 82: # have a correct number of digits. 83: # 84: # Parameters: 85: # value - proposed code value. 86: # num_digits - Number of digits required. 87: # 88: sub is_valid_numeric_code { 89: my ($value, $num_digits) = @_; 90: # Remove leading/trailing whitespace; 91: $value =~ s/^\s*//g; 92: $value =~ s/\s*$//g; 93: 94: # All digits? 95: if ($value !~ /^[0-9]+$/) { 96: return "Numeric code $value has invalid characters - must only be digits"; 97: } 98: if (length($value) != $num_digits) { 99: return "Numeric code $value incorrect number of digits (correct = $num_digits)"; 100: } 101: return undef; 102: } 103: # Determines if a code is a valid alhpa code. Alpha codes 104: # are ciphers that map [A-J,a-j] -> 0..9 0..9. 105: # They also have a correct digit count. 106: # Parameters: 107: # value - Proposed code value. 108: # num_letters - correct number of letters. 109: # Note: 110: # leading and trailing whitespace are ignored. 111: # 112: sub is_valid_alpha_code { 113: my ($value, $num_letters) = @_; 114: 115: # strip leading and trailing spaces. 116: 117: $value =~ s/^\s*//g; 118: $value =~ s/\s*$//g; 119: 120: # All alphas in the right range? 121: if ($value !~ /^[A-J,a-j]+$/) { 122: return "Invalid letter code $value must only contain A-J"; 123: } 124: if (length($value) != $num_letters) { 125: return "Letter code $value has incorrect number of letters (correct = $num_letters)"; 126: } 127: return undef; 128: } 129: 130: # Determine if a code entered by the user in a helper is valid. 131: # valid depends on the code type and the type of code selected. 132: # The type of code selected can either be numeric or 133: # Alphabetic. If alphabetic, the code, in fact is a simple 134: # substitution cipher for the actual numeric code: 0->A, 1->B ... 135: # We'll be nice and be case insensitive for alpha codes. 136: # Parameters: 137: # code_value - the value of the code the user typed in. 138: # code_option - The code type selected from the set in the scantron format 139: # table. 140: # Returns: 141: # undef - The code is valid. 142: # other - An error message indicating what's wrong. 143: # 144: sub is_code_valid { 145: my ($code_value, $code_option) = @_; 146: my ($code_type, $code_length) = ('letter', 6); # defaults. 147: open(FG, $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab'); 148: foreach my $line (<FG>) { 149: my ($name, $type, $length) = (split(/:/, $line))[0,2,4]; 150: if($name eq $code_option) { 151: $code_length = $length; 152: if($type eq 'number') { 153: $code_type = 'number'; 154: } 155: } 156: } 157: my $valid; 158: if ($code_type eq 'number') { 159: return &is_valid_numeric_code($code_value, $code_length); 160: } else { 161: return &is_valid_alpha_code($code_value, $code_length); 162: } 163: 164: } 165: 166: # Compare two students by name. The students are in the form 167: # returned by the helper: 168: # user:domain:section:last, first:status 169: # This is a helper function for the perl sort built-in therefore: 170: # Implicit Inputs: 171: # $a - The first element to compare (global) 172: # $b - The second element to compare (global) 173: # Returns: 174: # -1 - $a < $b 175: # 0 - $a == $b 176: # +1 - $a > $b 177: # Note that the initial comparison is done on the last names with the 178: # first names only used to break the tie. 179: # 180: # 181: sub compare_names { 182: # First split the names up into the primary fields. 183: 184: my ($u1, $d1, $s1, $n1, $stat1) = split(/:/, $a); 185: my ($u2, $d2, $s2, $n2, $stat2) = split(/:/, $b); 186: 187: # Now split the last name and first name of each n: 188: # 189: 190: my ($l1,$f1) = split(/,/, $n1); 191: my ($l2,$f2) = split(/,/, $n2); 192: 193: # We don't bother to remove the leading/trailing whitespace from the 194: # firstname, unless the last names compare identical. 195: 196: if($l1 lt $l2) { 197: return -1; 198: } 199: if($l1 gt $l2) { 200: return 1; 201: } 202: 203: # Break the tie on the first name, but there are leading (possibly trailing 204: # whitespaces to get rid of first 205: # 206: $f1 =~ s/^\s+//; # Remove leading... 207: $f1 =~ s/\s+$//; # Trailing spaces from first 1... 208: 209: $f2 =~ s/^\s+//; 210: $f2 =~ s/\s+$//; # And the same for first 2... 211: 212: if($f1 lt $f2) { 213: return -1; 214: } 215: if($f1 gt $f2) { 216: return 1; 217: } 218: 219: # Must be the same name. 220: 221: return 0; 222: } 223: 224: sub latex_header_footer_remove { 225: my $text = shift; 226: $text =~ s/\\end{document}//; 227: $text =~ s/\\documentclass([^&]*)\\begin{document}//; 228: return $text; 229: } 230: # 231: # If necessary, encapsulate text inside 232: # a minipage env. 233: # necessity is determined by the problem_split param. 234: # 235: sub encapsulate_minipage { 236: my ($text) = @_; 237: if (!($env{'form.problem.split'} =~ /yes/i)) { 238: $text = '\begin{minipage}{\textwidth}'.$text.'\end{minipage}'; 239: } 240: return $text; 241: } 242: # 243: # The NUMBER_TO_PRINT and SPLIT_PDFS 244: # variables interact, this sub looks at these two parameters 245: # and comes up with a final value for NUMBER_TO_PRINT which can be: 246: # all - if SPLIT_PDFS eq 'all'. 247: # 1 - if SPLIT_PDFS eq 'oneper' 248: # section - if SPLIT_PDFS eq 'sections' 249: # <unchanged> - if SPLIT_PDFS eq 'usenumber' 250: # 251: sub adjust_number_to_print { 252: my $helper = shift; 253: 254: my $split_pdf = $helper->{'VARS'}->{'SPLIT_PDFS'}; 255: 256: if ($split_pdf eq 'all') { 257: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = 'all'; 258: } elsif ($split_pdf eq 'oneper') { 259: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = 1; 260: } elsif ($split_pdf eq 'sections') { 261: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = 'section'; 262: } elsif ($split_pdf eq 'usenumber') { 263: # Unmodified. 264: } else { 265: # Error!!!! 266: 267: croak "bad SPLIT_PDFS: $split_pdf in lonprintout::adjust_number_to_print"; 268: } 269: } 270: 271: sub character_chart { 272: my $result = shift; 273: $result =~ s/&\#0?0?(7|9);//g; 274: $result =~ s/&\#0?(10|13);//g; 275: $result =~ s/&\#0?32;/ /g; 276: $result =~ s/&\#0?33;/!/g; 277: $result =~ s/&(\#0?34|quot);/\"/g; 278: $result =~ s/&\#0?35;/\\\#/g; 279: $result =~ s/&\#0?36;/\\\$/g; 280: $result =~ s/&\#0?37;/\\%/g; 281: $result =~ s/&(\#0?38|amp);/\\&/g; 282: $result =~ s/&\#(0?39|146);/\'/g; 283: $result =~ s/&\#0?40;/(/g; 284: $result =~ s/&\#0?41;/)/g; 285: $result =~ s/&\#0?42;/\*/g; 286: $result =~ s/&\#0?43;/\+/g; 287: $result =~ s/&\#(0?44|130);/,/g; 288: $result =~ s/&\#0?45;/-/g; 289: $result =~ s/&\#0?46;/\./g; 290: $result =~ s/&\#0?47;/\//g; 291: $result =~ s/&\#0?48;/0/g; 292: $result =~ s/&\#0?49;/1/g; 293: $result =~ s/&\#0?50;/2/g; 294: $result =~ s/&\#0?51;/3/g; 295: $result =~ s/&\#0?52;/4/g; 296: $result =~ s/&\#0?53;/5/g; 297: $result =~ s/&\#0?54;/6/g; 298: $result =~ s/&\#0?55;/7/g; 299: $result =~ s/&\#0?56;/8/g; 300: $result =~ s/&\#0?57;/9/g; 301: $result =~ s/&\#0?58;/:/g; 302: $result =~ s/&\#0?59;/;/g; 303: $result =~ s/&(\#0?60|lt|\#139);/\$<\$/g; 304: $result =~ s/&\#0?61;/\\ensuremath\{=\}/g; 305: $result =~ s/&(\#0?62|gt|\#155);/\\ensuremath\{>\}/g; 306: $result =~ s/&\#0?63;/\?/g; 307: $result =~ s/&\#0?65;/A/g; 308: $result =~ s/&\#0?66;/B/g; 309: $result =~ s/&\#0?67;/C/g; 310: $result =~ s/&\#0?68;/D/g; 311: $result =~ s/&\#0?69;/E/g; 312: $result =~ s/&\#0?70;/F/g; 313: $result =~ s/&\#0?71;/G/g; 314: $result =~ s/&\#0?72;/H/g; 315: $result =~ s/&\#0?73;/I/g; 316: $result =~ s/&\#0?74;/J/g; 317: $result =~ s/&\#0?75;/K/g; 318: $result =~ s/&\#0?76;/L/g; 319: $result =~ s/&\#0?77;/M/g; 320: $result =~ s/&\#0?78;/N/g; 321: $result =~ s/&\#0?79;/O/g; 322: $result =~ s/&\#0?80;/P/g; 323: $result =~ s/&\#0?81;/Q/g; 324: $result =~ s/&\#0?82;/R/g; 325: $result =~ s/&\#0?83;/S/g; 326: $result =~ s/&\#0?84;/T/g; 327: $result =~ s/&\#0?85;/U/g; 328: $result =~ s/&\#0?86;/V/g; 329: $result =~ s/&\#0?87;/W/g; 330: $result =~ s/&\#0?88;/X/g; 331: $result =~ s/&\#0?89;/Y/g; 332: $result =~ s/&\#0?90;/Z/g; 333: $result =~ s/&\#0?91;/[/g; 334: $result =~ s/&\#0?92;/\\ensuremath\{\\setminus\}/g; 335: $result =~ s/&\#0?93;/]/g; 336: $result =~ s/&\#(0?94|136);/\\ensuremath\{\\wedge\}/g; 337: $result =~ s/&\#(0?95|138|154);/\\underline{\\makebox[2mm]{\\strut}}/g; 338: $result =~ s/&\#(0?96|145);/\`/g; 339: $result =~ s/&\#0?97;/a/g; 340: $result =~ s/&\#0?98;/b/g; 341: $result =~ s/&\#0?99;/c/g; 342: $result =~ s/&\#100;/d/g; 343: $result =~ s/&\#101;/e/g; 344: $result =~ s/&\#102;/f/g; 345: $result =~ s/&\#103;/g/g; 346: $result =~ s/&\#104;/h/g; 347: $result =~ s/&\#105;/i/g; 348: $result =~ s/&\#106;/j/g; 349: $result =~ s/&\#107;/k/g; 350: $result =~ s/&\#108;/l/g; 351: $result =~ s/&\#109;/m/g; 352: $result =~ s/&\#110;/n/g; 353: $result =~ s/&\#111;/o/g; 354: $result =~ s/&\#112;/p/g; 355: $result =~ s/&\#113;/q/g; 356: $result =~ s/&\#114;/r/g; 357: $result =~ s/&\#115;/s/g; 358: $result =~ s/&\#116;/t/g; 359: $result =~ s/&\#117;/u/g; 360: $result =~ s/&\#118;/v/g; 361: $result =~ s/&\#119;/w/g; 362: $result =~ s/&\#120;/x/g; 363: $result =~ s/&\#121;/y/g; 364: $result =~ s/&\#122;/z/g; 365: $result =~ s/&\#123;/\\{/g; 366: $result =~ s/&\#124;/\|/g; 367: $result =~ s/&\#125;/\\}/g; 368: $result =~ s/&\#126;/\~/g; 369: $result =~ s/&\#131;/\\textflorin /g; 370: $result =~ s/&\#132;/\"/g; 371: $result =~ s/&\#133;/\\ensuremath\{\\ldots\}/g; 372: $result =~ s/&\#134;/\\ensuremath\{\\dagger\}/g; 373: $result =~ s/&\#135;/\\ensuremath\{\\ddagger\}/g; 374: $result =~ s/&\#137;/\\textperthousand /g; 375: $result =~ s/&\#140;/{\\OE}/g; 376: $result =~ s/&\#147;/\`\`/g; 377: $result =~ s/&\#148;/\'\'/g; 378: $result =~ s/&\#149;/\\ensuremath\{\\bullet\}/g; 379: $result =~ s/&\#150;/--/g; 380: $result =~ s/&\#151;/---/g; 381: $result =~ s/&\#152;/\\ensuremath\{\\sim\}/g; 382: $result =~ s/&\#153;/\\texttrademark /g; 383: $result =~ s/&\#156;/\\oe/g; 384: $result =~ s/&\#159;/\\\"Y/g; 385: $result =~ s/&(\#160|nbsp);/~/g; 386: $result =~ s/&(\#161|iexcl);/!\`/g; 387: $result =~ s/&(\#162|cent);/\\textcent /g; 388: $result =~ s/&(\#163|pound);/\\pounds /g; 389: $result =~ s/&(\#164|curren);/\\textcurrency /g; 390: $result =~ s/&(\#165|yen);/\\textyen /g; 391: $result =~ s/&(\#166|brvbar);/\\textbrokenbar /g; 392: $result =~ s/&(\#167|sect);/\\textsection /g; 393: $result =~ s/&(\#168|uml);/\\texthighdieresis /g; 394: $result =~ s/&(\#169|copy);/\\copyright /g; 395: $result =~ s/&(\#170|ordf);/\\textordfeminine /g; 396: $result =~ s/&(\#172|not);/\\ensuremath\{\\neg\}/g; 397: $result =~ s/&(\#173|shy);/ - /g; 398: $result =~ s/&(\#174|reg);/\\textregistered /g; 399: $result =~ s/&(\#175|macr);/\\ensuremath\{^{-}\}/g; 400: $result =~ s/&(\#176|deg);/\\ensuremath\{^{\\circ}\}/g; 401: $result =~ s/&(\#177|plusmn);/\\ensuremath\{\\pm\}/g; 402: $result =~ s/&(\#178|sup2);/\\ensuremath\{^2\}/g; 403: $result =~ s/&(\#179|sup3);/\\ensuremath\{^3\}/g; 404: $result =~ s/&(\#180|acute);/\\textacute /g; 405: $result =~ s/&(\#181|micro);/\\ensuremath\{\\mu\}/g; 406: $result =~ s/&(\#182|para);/\\P/g; 407: $result =~ s/&(\#183|middot);/\\ensuremath\{\\cdot\}/g; 408: $result =~ s/&(\#184|cedil);/\\c{\\strut}/g; 409: $result =~ s/&(\#185|sup1);/\\ensuremath\{^1\}/g; 410: $result =~ s/&(\#186|ordm);/\\textordmasculine /g; 411: $result =~ s/&(\#188|frac14);/\\textonequarter /g; 412: $result =~ s/&(\#189|frac12);/\\textonehalf /g; 413: $result =~ s/&(\#190|frac34);/\\textthreequarters /g; 414: $result =~ s/&(\#191|iquest);/?\`/g; 415: $result =~ s/&(\#192|Agrave);/\\\`{A}/g; 416: $result =~ s/&(\#193|Aacute);/\\\'{A}/g; 417: $result =~ s/&(\#194|Acirc);/\\^{A}/g; 418: $result =~ s/&(\#195|Atilde);/\\~{A}/g; 419: $result =~ s/&(\#196|Auml);/\\\"{A}/g; 420: $result =~ s/&(\#197|Aring);/{\\AA}/g; 421: $result =~ s/&(\#198|AElig);/{\\AE}/g; 422: $result =~ s/&(\#199|Ccedil);/\\c{c}/g; 423: $result =~ s/&(\#200|Egrave);/\\\`{E}/g; 424: $result =~ s/&(\#201|Eacute);/\\\'{E}/g; 425: $result =~ s/&(\#202|Ecirc);/\\^{E}/g; 426: $result =~ s/&(\#203|Euml);/\\\"{E}/g; 427: $result =~ s/&(\#204|Igrave);/\\\`{I}/g; 428: $result =~ s/&(\#205|Iacute);/\\\'{I}/g; 429: $result =~ s/&(\#206|Icirc);/\\^{I}/g; 430: $result =~ s/&(\#207|Iuml);/\\\"{I}/g; 431: $result =~ s/&(\#209|Ntilde);/\\~{N}/g; 432: $result =~ s/&(\#210|Ograve);/\\\`{O}/g; 433: $result =~ s/&(\#211|Oacute);/\\\'{O}/g; 434: $result =~ s/&(\#212|Ocirc);/\\^{O}/g; 435: $result =~ s/&(\#213|Otilde);/\\~{O}/g; 436: $result =~ s/&(\#214|Ouml);/\\\"{O}/g; 437: $result =~ s/&(\#215|times);/\\ensuremath\{\\times\}/g; 438: $result =~ s/&(\#216|Oslash);/{\\O}/g; 439: $result =~ s/&(\#217|Ugrave);/\\\`{U}/g; 440: $result =~ s/&(\#218|Uacute);/\\\'{U}/g; 441: $result =~ s/&(\#219|Ucirc);/\\^{U}/g; 442: $result =~ s/&(\#220|Uuml);/\\\"{U}/g; 443: $result =~ s/&(\#221|Yacute);/\\\'{Y}/g; 444: $result =~ s/&(\#223|szlig);/{\\ss}/g; 445: $result =~ s/&(\#224|agrave);/\\\`{a}/g; 446: $result =~ s/&(\#225|aacute);/\\\'{a}/g; 447: $result =~ s/&(\#226|acirc);/\\^{a}/g; 448: $result =~ s/&(\#227|atilde);/\\~{a}/g; 449: $result =~ s/&(\#228|auml);/\\\"{a}/g; 450: $result =~ s/&(\#229|aring);/{\\aa}/g; 451: $result =~ s/&(\#230|aelig);/{\\ae}/g; 452: $result =~ s/&(\#231|ccedil);/\\c{c}/g; 453: $result =~ s/&(\#232|egrave);/\\\`{e}/g; 454: $result =~ s/&(\#233|eacute);/\\\'{e}/g; 455: $result =~ s/&(\#234|ecirc);/\\^{e}/g; 456: $result =~ s/&(\#235|euml);/\\\"{e}/g; 457: $result =~ s/&(\#236|igrave);/\\\`{i}/g; 458: $result =~ s/&(\#237|iacute);/\\\'{i}/g; 459: $result =~ s/&(\#238|icirc);/\\^{i}/g; 460: $result =~ s/&(\#239|iuml);/\\\"{i}/g; 461: $result =~ s/&(\#240|eth);/\\ensuremath\{\\partial\}/g; 462: $result =~ s/&(\#241|ntilde);/\\~{n}/g; 463: $result =~ s/&(\#242|ograve);/\\\`{o}/g; 464: $result =~ s/&(\#243|oacute);/\\\'{o}/g; 465: $result =~ s/&(\#244|ocirc);/\\^{o}/g; 466: $result =~ s/&(\#245|otilde);/\\~{o}/g; 467: $result =~ s/&(\#246|ouml);/\\\"{o}/g; 468: $result =~ s/&(\#247|divide);/\\ensuremath\{\\div\}/g; 469: $result =~ s/&(\#248|oslash);/{\\o}/g; 470: $result =~ s/&(\#249|ugrave);/\\\`{u}/g; 471: $result =~ s/&(\#250|uacute);/\\\'{u}/g; 472: $result =~ s/&(\#251|ucirc);/\\^{u}/g; 473: $result =~ s/&(\#252|uuml);/\\\"{u}/g; 474: $result =~ s/&(\#253|yacute);/\\\'{y}/g; 475: $result =~ s/&(\#255|yuml);/\\\"{y}/g; 476: $result =~ s/&\#295;/\\ensuremath\{\\hbar\}/g; 477: $result =~ s/&\#952;/\\ensuremath\{\\theta\}/g; 478: #Greek Alphabet 479: $result =~ s/&(alpha|\#945);/\\ensuremath\{\\alpha\}/g; 480: $result =~ s/&(beta|\#946);/\\ensuremath\{\\beta\}/g; 481: $result =~ s/&(gamma|\#947);/\\ensuremath\{\\gamma\}/g; 482: $result =~ s/&(delta|\#948);/\\ensuremath\{\\delta\}/g; 483: $result =~ s/&(epsilon|\#949);/\\ensuremath\{\\epsilon\}/g; 484: $result =~ s/&(zeta|\#950);/\\ensuremath\{\\zeta\}/g; 485: $result =~ s/&(eta|\#951);/\\ensuremath\{\\eta\}/g; 486: $result =~ s/&(theta|\#952);/\\ensuremath\{\\theta\}/g; 487: $result =~ s/&(iota|\#953);/\\ensuremath\{\\iota\}/g; 488: $result =~ s/&(kappa|\#954);/\\ensuremath\{\\kappa\}/g; 489: $result =~ s/&(lambda|\#955);/\\ensuremath\{\\lambda\}/g; 490: $result =~ s/&(mu|\#956);/\\ensuremath\{\\mu\}/g; 491: $result =~ s/&(nu|\#957);/\\ensuremath\{\\nu\}/g; 492: $result =~ s/&(xi|\#958);/\\ensuremath\{\\xi\}/g; 493: $result =~ s/&(omicron|\#959);/o/g; 494: $result =~ s/&(pi|\#960);/\\ensuremath\{\\pi\}/g; 495: $result =~ s/&(rho|\#961);/\\ensuremath\{\\rho\}/g; 496: $result =~ s/&(sigma|\#963);/\\ensuremath\{\\sigma\}/g; 497: $result =~ s/&(tau|\#964);/\\ensuremath\{\\tau\}/g; 498: $result =~ s/&(upsilon|\#965);/\\ensuremath\{\\upsilon\}/g; 499: $result =~ s/&(phi|\#966);/\\ensuremath\{\\phi\}/g; 500: $result =~ s/&(chi|\#967);/\\ensuremath\{\\chi\}/g; 501: $result =~ s/&(psi|\#968);/\\ensuremath\{\\psi\}/g; 502: $result =~ s/&(omega|\#969);/\\ensuremath\{\\omega\}/g; 503: $result =~ s/&(thetasym|\#977);/\\ensuremath\{\\vartheta\}/g; 504: $result =~ s/&(piv|\#982);/\\ensuremath\{\\varpi\}/g; 505: $result =~ s/&(Alpha|\#913);/A/g; 506: $result =~ s/&(Beta|\#914);/B/g; 507: $result =~ s/&(Gamma|\#915);/\\ensuremath\{\\Gamma\}/g; 508: $result =~ s/&(Delta|\#916);/\\ensuremath\{\\Delta\}/g; 509: $result =~ s/&(Epsilon|\#917);/E/g; 510: $result =~ s/&(Zeta|\#918);/Z/g; 511: $result =~ s/&(Eta|\#919);/H/g; 512: $result =~ s/&(Theta|\#920);/\\ensuremath\{\\Theta\}/g; 513: $result =~ s/&(Iota|\#921);/I/g; 514: $result =~ s/&(Kappa|\#922);/K/g; 515: $result =~ s/&(Lambda|\#923);/\\ensuremath\{\\Lambda\}/g; 516: $result =~ s/&(Mu|\#924);/M/g; 517: $result =~ s/&(Nu|\#925);/N/g; 518: $result =~ s/&(Xi|\#926);/\\ensuremath\{\\Xi\}/g; 519: $result =~ s/&(Omicron|\#927);/O/g; 520: $result =~ s/&(Pi|\#928);/\\ensuremath\{\\Pi\}/g; 521: $result =~ s/&(Rho|\#929);/P/g; 522: $result =~ s/&(Sigma|\#931);/\\ensuremath\{\\Sigma\}/g; 523: $result =~ s/&(Tau|\#932);/T/g; 524: $result =~ s/&(Upsilon|\#933);/\\ensuremath\{\\Upsilon\}/g; 525: $result =~ s/&(Phi|\#934);/\\ensuremath\{\\Phi\}/g; 526: $result =~ s/&(Chi|\#935);/X/g; 527: $result =~ s/&(Psi|\#936);/\\ensuremath\{\\Psi\}/g; 528: $result =~ s/&(Omega|\#937);/\\ensuremath\{\\Omega\}/g; 529: #Arrows (extended HTML 4.01) 530: $result =~ s/&(larr|\#8592);/\\ensuremath\{\\leftarrow\}/g; 531: $result =~ s/&(uarr|\#8593);/\\ensuremath\{\\uparrow\}/g; 532: $result =~ s/&(rarr|\#8594);/\\ensuremath\{\\rightarrow\}/g; 533: $result =~ s/&(darr|\#8595);/\\ensuremath\{\\downarrow\}/g; 534: $result =~ s/&(harr|\#8596);/\\ensuremath\{\\leftrightarrow\}/g; 535: $result =~ s/&(lArr|\#8656);/\\ensuremath\{\\Leftarrow\}/g; 536: $result =~ s/&(uArr|\#8657);/\\ensuremath\{\\Uparrow\}/g; 537: $result =~ s/&(rArr|\#8658);/\\ensuremath\{\\Rightarrow\}/g; 538: $result =~ s/&(dArr|\#8659);/\\ensuremath\{\\Downarrow\}/g; 539: $result =~ s/&(hArr|\#8660);/\\ensuremath\{\\Leftrightarrow\}/g; 540: #Mathematical Operators (extended HTML 4.01) 541: $result =~ s/&(forall|\#8704);/\\ensuremath\{\\forall\}/g; 542: $result =~ s/&(part|\#8706);/\\ensuremath\{\\partial\}/g; 543: $result =~ s/&(exist|\#8707);/\\ensuremath\{\\exists\}/g; 544: $result =~ s/&(empty|\#8709);/\\ensuremath\{\\emptyset\}/g; 545: $result =~ s/&(nabla|\#8711);/\\ensuremath\{\\nabla\}/g; 546: $result =~ s/&(isin|\#8712);/\\ensuremath\{\\in\}/g; 547: $result =~ s/&(notin|\#8713);/\\ensuremath\{\\notin\}/g; 548: $result =~ s/&(ni|\#8715);/\\ensuremath\{\\ni\}/g; 549: $result =~ s/&(prod|\#8719);/\\ensuremath\{\\prod\}/g; 550: $result =~ s/&(sum|\#8721);/\\ensuremath\{\\sum\}/g; 551: $result =~ s/&(minus|\#8722);/\\ensuremath\{-\}/g; 552: $result =~ s/–/\\ensuremath\{-\}/g; 553: $result =~ s/&(lowast|\#8727);/\\ensuremath\{*\}/g; 554: $result =~ s/&(radic|\#8730);/\\ensuremath\{\\surd\}/g; 555: $result =~ s/&(prop|\#8733);/\\ensuremath\{\\propto\}/g; 556: $result =~ s/&(infin|\#8734);/\\ensuremath\{\\infty\}/g; 557: $result =~ s/&(ang|\#8736);/\\ensuremath\{\\angle\}/g; 558: $result =~ s/&(and|\#8743);/\\ensuremath\{\\wedge\}/g; 559: $result =~ s/&(or|\#8744);/\\ensuremath\{\\vee\}/g; 560: $result =~ s/&(cap|\#8745);/\\ensuremath\{\\cap\}/g; 561: $result =~ s/&(cup|\#8746);/\\ensuremath\{\\cup\}/g; 562: $result =~ s/&(int|\#8747);/\\ensuremath\{\\int\}/g; 563: $result =~ s/&(sim|\#8764);/\\ensuremath\{\\sim\}/g; 564: $result =~ s/&(cong|\#8773);/\\ensuremath\{\\cong\}/g; 565: $result =~ s/&(asymp|\#8776);/\\ensuremath\{\\approx\}/g; 566: $result =~ s/&(ne|\#8800);/\\ensuremath\{\\not=\}/g; 567: $result =~ s/&(equiv|\#8801);/\\ensuremath\{\\equiv\}/g; 568: $result =~ s/&(le|\#8804);/\\ensuremath\{\\leq\}/g; 569: $result =~ s/&(ge|\#8805);/\\ensuremath\{\\geq\}/g; 570: $result =~ s/&(sub|\#8834);/\\ensuremath\{\\subset\}/g; 571: $result =~ s/&(sup|\#8835);/\\ensuremath\{\\supset\}/g; 572: $result =~ s/&(nsub|\#8836);/\\ensuremath\{\\not\\subset\}/g; 573: $result =~ s/&(sube|\#8838);/\\ensuremath\{\\subseteq\}/g; 574: $result =~ s/&(supe|\#8839);/\\ensuremath\{\\supseteq\}/g; 575: $result =~ s/&(oplus|\#8853);/\\ensuremath\{\\oplus\}/g; 576: $result =~ s/&(otimes|\#8855);/\\ensuremath\{\\otimes\}/g; 577: $result =~ s/&(perp|\#8869);/\\ensuremath\{\\perp\}/g; 578: $result =~ s/&(sdot|\#8901);/\\ensuremath\{\\cdot\}/g; 579: #Geometric Shapes (extended HTML 4.01) 580: $result =~ s/&(loz|\#9674);/\\ensuremath\{\\Diamond\}/g; 581: #Miscellaneous Symbols (extended HTML 4.01) 582: $result =~ s/&(spades|\#9824);/\\ensuremath\{\\spadesuit\}/g; 583: $result =~ s/&(clubs|\#9827);/\\ensuremath\{\\clubsuit\}/g; 584: $result =~ s/&(hearts|\#9829);/\\ensuremath\{\\heartsuit\}/g; 585: $result =~ s/&(diams|\#9830);/\\ensuremath\{\\diamondsuit\}/g; 586: return $result; 587: } 588: 589: 590: #width, height, oddsidemargin, evensidemargin, topmargin 591: my %page_formats= 592: ('letter' => { 593: 'book' => { 594: '1' => [ '7.1 in','9.8 in', '-0.57 in','-0.57 in','0.7 cm'], 595: '2' => ['3.66 in','9.8 in', '-0.57 in','-0.57 in','0.7 cm'] 596: }, 597: 'album' => { 598: '1' => [ '8.8 in', '6.8 in','-40 pt in', '-60 pt','1 cm'], 599: '2' => [ '4.4 in', '6.8 in','-0.5 in', '-1.5 in','3.5 in'] 600: }, 601: }, 602: 'legal' => { 603: 'book' => { 604: '1' => ['7.1 in','13 in',,'-0.57 in','-0.57 in','-0.5 in'], 605: '2' => ['3.16 in','13 in','-0.57 in','-0.57 in','-0.5 in'] 606: }, 607: 'album' => { 608: '1' => ['12 in','7.1 in',,'-0.57 in','-0.57 in','-0.5 in'], 609: '2' => ['6.0 in','7.1 in','-1 in','-1 in','5 in'] 610: }, 611: }, 612: 'tabloid' => { 613: 'book' => { 614: '1' => ['9.8 in','16 in','-0.57 in','-0.57 in','-0.5 in'], 615: '2' => ['4.9 in','16 in','-0.57 in','-0.57 in','-0.5 in'] 616: }, 617: 'album' => { 618: '1' => ['16 in','9.8 in','-0.57 in','-0.57 in','-0.5 in'], 619: '2' => ['16 in','4.9 in','-0.57 in','-0.57 in','-0.5 in'] 620: }, 621: }, 622: 'executive' => { 623: 'book' => { 624: '1' => ['6.8 in','9 in','-0.57 in','-0.57 in','1.2 in'], 625: '2' => ['3.1 in','9 in','-0.57 in','-0.57 in','1.2 in'] 626: }, 627: 'album' => { 628: '1' => [], 629: '2' => [] 630: }, 631: }, 632: 'a2' => { 633: 'book' => { 634: '1' => [], 635: '2' => [] 636: }, 637: 'album' => { 638: '1' => [], 639: '2' => [] 640: }, 641: }, 642: 'a3' => { 643: 'book' => { 644: '1' => [], 645: '2' => [] 646: }, 647: 'album' => { 648: '1' => [], 649: '2' => [] 650: }, 651: }, 652: 'a4' => { 653: 'book' => { 654: '1' => ['176 mm','272 mm','-40 pt in','-60 pt','-0.5 in'], 655: '2' => [ '91 mm','272 mm','-40 pt in','-60 pt','-0.5 in'] 656: }, 657: 'album' => { 658: '1' => ['8.5 in','7.7 in','-40 pt in','-60 pt','0 in'], 659: '2' => ['3.9 in','7.7 in','-40 pt in','-60 pt','0 in'] 660: }, 661: }, 662: 'a5' => { 663: 'book' => { 664: '1' => [], 665: '2' => [] 666: }, 667: 'album' => { 668: '1' => [], 669: '2' => [] 670: }, 671: }, 672: 'a6' => { 673: 'book' => { 674: '1' => [], 675: '2' => [] 676: }, 677: 'album' => { 678: '1' => [], 679: '2' => [] 680: }, 681: }, 682: ); 683: 684: sub page_format { 685: # 686: #Supported paper format: "Letter [8 1/2x11 in]", "Legal [8 1/2x14 in]", 687: # "Ledger/Tabloid [11x17 in]", "Executive [7 1/2x10 in]", 688: # "A2 [420x594 mm]", "A3 [297x420 mm]", 689: # "A4 [210x297 mm]", "A5 [148x210 mm]", 690: # "A6 [105x148 mm]" 691: # 692: my ($papersize,$layout,$numberofcolumns) = @_; 693: return @{$page_formats{$papersize}->{$layout}->{$numberofcolumns}}; 694: } 695: 696: 697: sub get_name { 698: my ($uname,$udom)=@_; 699: if (!defined($uname)) { $uname=$env{'user.name'}; } 700: if (!defined($udom)) { $udom=$env{'user.domain'}; } 701: my $plainname=&Apache::loncommon::plainname($uname,$udom); 702: if ($plainname=~/^\s*$/) { $plainname=$uname.'@'.$udom; } 703: $plainname=&Apache::lonxml::latex_special_symbols($plainname,'header'); 704: return $plainname; 705: } 706: 707: sub get_course { 708: my $courseidinfo; 709: if (defined($env{'request.course.id'})) { 710: $courseidinfo = &Apache::lonxml::latex_special_symbols(&Apache::lonnet::unescape($env{'course.'.$env{'request.course.id'}.'.description'}),'header'); 711: } 712: return $courseidinfo; 713: } 714: 715: sub page_format_transformation { 716: my ($papersize,$layout,$numberofcolumns,$choice,$text,$assignment,$tableofcontents,$indexlist,$selectionmade) = @_; 717: my ($textwidth,$textheight,$oddoffset,$evenoffset,$topmargin); 718: if ($selectionmade eq '4') { 719: $assignment='Problems from the Whole Course'; 720: } else { 721: $assignment=&Apache::lonxml::latex_special_symbols($assignment,'header'); 722: } 723: ($textwidth,$textheight,$oddoffset,$evenoffset,$topmargin) = &page_format($papersize,$layout,$numberofcolumns,$topmargin); 724: my $name = &get_name(); 725: my $courseidinfo = &get_course(); 726: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo } 727: my $topmargintoinsert = ''; 728: if ($topmargin ne '0') {$topmargintoinsert='\setlength{\topmargin}{'.$topmargin.'}';} 729: my $fancypagestatement=''; 730: if ($numberofcolumns eq '2') { 731: $fancypagestatement="\\fancyhead{}\\fancyhead[LO]{\\textbf{$name} $courseidinfo \\hfill \\thepage \\\\ \\textit{$assignment}}"; 732: } else { 733: $fancypagestatement="\\rhead{}\\chead{}\\lhead{\\textbf{$name} $courseidinfo \\hfill \\thepage \\\\ \\textit{$assignment}}"; 734: } 735: if ($layout eq 'album') { 736: $text =~ s/\\begin{document}/\\setlength{\\oddsidemargin}{$oddoffset}\\setlength{\\evensidemargin}{$evenoffset}$topmargintoinsert\n\\setlength{\\textwidth}{$textwidth}\\setlength{\\textheight}{$textheight}\\setlength{\\textfloatsep}{8pt plus 2\.0pt minus 4\.0pt}\n\\newlength{\\minipagewidth}\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\\usepackage{fancyhdr}\\addtolength{\\headheight}{\\baselineskip}\n\\pagestyle{fancy}$fancypagestatement\\begin{document}\\voffset=-0\.8 cm\\setcounter{page}{1}\n /; 737: } elsif ($layout eq 'book') { 738: if ($choice ne 'All class print') { 739: $text =~ s/\\begin{document}/\\textheight $textheight\\oddsidemargin = $evenoffset\\evensidemargin = $evenoffset $topmargintoinsert\n\\textwidth= $textwidth\\newlength{\\minipagewidth}\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\n\\renewcommand{\\ref}{\\keephidden\}\\usepackage{fancyhdr}\\addtolength{\\headheight}{\\baselineskip}\\pagestyle{fancy}$fancypagestatement\\begin{document}\n\\voffset=-0\.8 cm\\setcounter{page}{1}\n/; 740: } else { 741: $text =~ s/\\pagestyle{fancy}\\rhead{}\\chead{}\s*\\begin{document}/\\textheight = $textheight\\oddsidemargin = $evenoffset\n\\evensidemargin = $evenoffset $topmargintoinsert\\textwidth= $textwidth\\newlength{\\minipagewidth}\n\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\\renewcommand{\\ref}{\\keephidden\}\\pagestyle{fancy}\\rhead{}\\chead{}\\begin{document}\\voffset=-0\.8cm\n\\setcounter{page}{1} \\vskip 5 mm\n /; 742: } 743: if ($papersize eq 'a4') { 744: $text =~ s/(\\begin{document})/$1\\special{papersize=210mm,297mm}/; 745: } 746: } 747: if ($tableofcontents eq 'yes') {$text=~s/(\\setcounter\{page\}\{1\})/$1 \\tableofcontents\\newpage /;} 748: if ($indexlist eq 'yes') { 749: $text=~s/(\\begin{document})/\\makeindex $1/; 750: $text=~s/(\\end{document})/\\strut\\\\\\strut\\printindex $1/; 751: } 752: return $text; 753: } 754: 755: 756: sub page_cleanup { 757: my $result = shift; 758: 759: $result =~ m/\\end{document}(\d*)$/; 760: my $number_of_columns = $1; 761: my $insert = '{'; 762: for (my $id=1;$id<=$number_of_columns;$id++) { $insert .='l'; } 763: $insert .= '}'; 764: $result =~ s/(\\begin{longtable})INSERTTHEHEADOFLONGTABLE\\endfirsthead\\endhead/$1$insert/g; 765: $result =~ s/&\s*REMOVETHEHEADOFLONGTABLE\\\\/\\\\/g; 766: return $result,$number_of_columns; 767: } 768: 769: 770: sub details_for_menu { 771: my ($helper)=@_; 772: my $postdata=$env{'form.postdata'}; 773: if (!$postdata) { $postdata=$helper->{VARS}{'postdata'}; } 774: my $name_of_resource = &Apache::lonnet::gettitle($postdata); 775: my $symbolic = &Apache::lonnet::symbread($postdata); 776: my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symbolic); 777: $map=&Apache::lonnet::clutter($map); 778: my $name_of_sequence = &Apache::lonnet::gettitle($map); 779: if ($name_of_sequence =~ /^\s*$/) { 780: $map =~ m|([^/]+)$|; 781: $name_of_sequence = $1; 782: } 783: my $name_of_map = &Apache::lonnet::gettitle($env{'request.course.uri'}); 784: if ($name_of_map =~ /^\s*$/) { 785: $env{'request.course.uri'} =~ m|([^/]+)$|; 786: $name_of_map = $1; 787: } 788: return ($name_of_resource,$name_of_sequence,$name_of_map); 789: } 790: 791: 792: sub latex_corrections { 793: my ($number_of_columns,$result,$selectionmade,$answer_mode) = @_; 794: # $result =~ s/\\includegraphics{/\\includegraphics\[width=\\minipagewidth\]{/g; 795: $result =~ s/\$number_of_columns/$number_of_columns/g; 796: if ($selectionmade eq '1' || $answer_mode eq 'only') { 797: $result =~ s/(\\end{document})/\\strut\\vskip 0 mm\\noindent\\makebox\[\\textwidth\/$number_of_columns\]\[b\]{\\hrulefill}\\newline\\noindent\\tiny Printed from LON-CAPA\\copyright MSU{\\hfill} Licensed under GNU General Public License $1/; 798: } else { 799: $result =~ s/(\\end{document})/\\strut\\vspace\*{-4 mm}\\newline\\noindent\\makebox\[\\textwidth\/$number_of_columns\]\[b\]{\\hrulefill}\\newline\\noindent\\tiny Printed from LON-CAPA\\copyright MSU{\\hfill} Licensed under GNU General Public License $1/; 800: } 801: $result =~ s/(\\end{longtable}\s*)(\\strut\\newline\\noindent\\makebox\[\\textwidth\/$number_of_columns\]\[b\]{\\hrulefill})/$2$1/g; 802: $result =~ s/(\\end{longtable}\s*)\\strut\\newline/$1/g; 803: #-- LaTeX corrections 804: my $first_comment = index($result,'<!--',0); 805: while ($first_comment != -1) { 806: my $end_comment = index($result,'-->',$first_comment); 807: substr($result,$first_comment,$end_comment-$first_comment+3) = ''; 808: $first_comment = index($result,'<!--',$first_comment); 809: } 810: $result =~ s/^\s+$//gm; #remove empty lines 811: #removes more than one empty space 812: $result =~ s|(\s\s+)|($1=~/[\n\r]/)?"\n":" "|ge; 813: $result =~ s/\\\\\s*\\vskip/\\vskip/gm; 814: $result =~ s/\\\\\s*\\noindent\s*(\\\\)+/\\\\\\noindent /g; 815: $result =~ s/{\\par }\s*\\\\/\\\\/gm; 816: $result =~ s/\\\\\s+\[/ \[/g; 817: #conversion of html characters to LaTeX equivalents 818: if ($result =~ m/&(\w+|#\d+);/) { 819: $result = &character_chart($result); 820: } 821: $result =~ s/(\\end{tabular})\s*\\vskip 0 mm/$1/g; 822: $result =~ s/(\\begin{enumerate})\s*\\noindent/$1/g; 823: return $result; 824: } 825: 826: 827: sub index_table { 828: my $currentURL = shift; 829: my $insex_string=''; 830: $currentURL=~s/\.([^\/+])$/\.$1\.meta/; 831: $insex_string=&Apache::lonnet::metadata($currentURL,'keywords'); 832: return $insex_string; 833: } 834: 835: 836: sub IndexCreation { 837: my ($texversion,$currentURL)=@_; 838: my @key_words=split(/,/,&index_table($currentURL)); 839: my $chunk=''; 840: my $st=index $texversion,'\addcontentsline{toc}{subsection}{'; 841: if ($st>0) { 842: for (my $i=0;$i<3;$i++) {$st=(index $texversion,'}',$st+1);} 843: $chunk=substr($texversion,0,$st+1); 844: substr($texversion,0,$st+1)=' '; 845: } 846: foreach my $key_word (@key_words) { 847: if ($key_word=~/\S+/) { 848: $texversion=~s/\b($key_word)\b/$1 \\index{$key_word} /i; 849: } 850: } 851: if ($st>0) {substr($texversion,0,1)=$chunk;} 852: return $texversion; 853: } 854: 855: sub print_latex_header { 856: my $mode=shift; 857: my $output='\documentclass[letterpaper,twoside]{article}'; 858: if (($mode eq 'batchmode') || (!$perm{'pav'})) { 859: $output.='\batchmode'; 860: } 861: $output.='\newcommand{\keephidden}[1]{}\renewcommand{\deg}{$^{\circ}$}'."\n". 862: '\usepackage{multirow}'."\n". 863: '\usepackage{longtable}\usepackage{textcomp}\usepackage{makeidx}'."\n". 864: '\usepackage[dvips]{graphicx}\usepackage{epsfig}'."\n". 865: '\usepackage{wrapfig}'. 866: '\usepackage{picins}\usepackage{calc}'."\n". 867: '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}'."\n". 868: '\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}'."\n". 869: '\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}'."\n". 870: '\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}'."\n". 871: '\setlength{\abovedisplayshortskip}{-0.04in}'."\n". 872: '\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'."\n". 873: '\renewenvironment{theindex}{\begin{list}{}{{\vskip 1mm \noindent \large'."\n". 874: '\textbf{Index}} \newline \setlength{\rightmargin}{0in}'."\n". 875: '\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.01in}'."\n". 876: '\setlength{\itemsep}{0.1in}\setlength{\parsep}{-0.02in}'."\n". 877: '\setlength{\belowdisplayskip}{0.01in}\setlength{\abovedisplayskip}{0.01in}'."\n". 878: '\setlength{\abovedisplayshortskip}{-0.04in}'."\n". 879: '\setlength{\belowdisplayshortskip}{0.01in}}}{\end{list}}\begin{document}'."\n"; 880: return $output; 881: } 882: 883: sub path_to_problem { 884: my ($urlp,$colwidth)=@_; 885: $urlp=&Apache::lonnet::clutter($urlp); 886: 887: my $newurlp = ''; 888: $colwidth=~s/\s*mm\s*$//; 889: #characters average about 2 mm in width 890: if (length($urlp)*2 > $colwidth) { 891: my @elements = split('/',$urlp); 892: my $curlength=0; 893: foreach my $element (@elements) { 894: if ($element eq '') { next; } 895: if ($curlength+(length($element)*2) > $colwidth) { 896: $newurlp .= '|\vskip -1 mm \verb|'; 897: $curlength=length($element)*2; 898: } else { 899: $curlength+=length($element)*2; 900: } 901: $newurlp.='/'.$element; 902: } 903: } else { 904: $newurlp=$urlp; 905: } 906: return '{\small\noindent\verb|'.$newurlp.'|\vskip 0 mm}'; 907: } 908: 909: sub recalcto_mm { 910: my $textwidth=shift; 911: my $LaTeXwidth; 912: if ($textwidth=~/(-?\d+\.?\d*)\s*cm/) { 913: $LaTeXwidth = $1*10; 914: } elsif ($textwidth=~/(-?\d+\.?\d*)\s*mm/) { 915: $LaTeXwidth = $1; 916: } elsif ($textwidth=~/(-?\d+\.?\d*)\s*in/) { 917: $LaTeXwidth = $1*25.4; 918: } 919: $LaTeXwidth.=' mm'; 920: return $LaTeXwidth; 921: } 922: 923: sub get_textwidth { 924: my ($helper,$LaTeXwidth)=@_; 925: my $textwidth=$LaTeXwidth; 926: if ($helper->{'VARS'}->{'pagesize.width'}=~/\d+/ && 927: $helper->{'VARS'}->{'pagesize.widthunit'}=~/\w+/) { 928: $textwidth=&recalcto_mm($helper->{'VARS'}->{'pagesize.width'}.' '. 929: $helper->{'VARS'}->{'pagesize.widthunit'}); 930: } 931: return $textwidth; 932: } 933: 934: 935: sub unsupported { 936: my ($currentURL,$mode,$symb)=@_; 937: if ($mode ne '') {$mode='\\'.$mode} 938: my $result.= &print_latex_header($mode); 939: if ($currentURL=~m|^(/adm/wrapper/)?ext/|) { 940: $currentURL=~s|^(/adm/wrapper/)?ext/|http://|; 941: my $title=&Apache::lonnet::gettitle($symb); 942: $title = &Apache::lonxml::latex_special_symbols($title); 943: $result.=' \strut \\\\ '.$title.' \strut \\\\ '.$currentURL.' '; 944: } else { 945: $result.=$currentURL; 946: } 947: $result.= '\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill} \end{document}'; 948: return $result; 949: } 950: 951: 952: # 953: # List of recently generated print files 954: # 955: sub recently_generated { 956: my $r=shift; 957: my $prtspool=$r->dir_config('lonPrtDir'); 958: my $zip_result; 959: my $pdf_result; 960: opendir(DIR,$prtspool); 961: 962: my @files = 963: grep(/^$env{'user.name'}_$env{'user.domain'}_printout_(\d+)_.*\.(pdf|zip)$/,readdir(DIR)); 964: closedir(DIR); 965: 966: @files = sort { 967: my ($actime) = (stat($prtspool.'/'.$a))[10]; 968: my ($bctime) = (stat($prtspool.'/'.$b))[10]; 969: return $bctime <=> $actime; 970: } (@files); 971: 972: foreach my $filename (@files) { 973: my ($ext) = ($filename =~ m/(pdf|zip)$/); 974: my ($cdev,$cino,$cmode,$cnlink, 975: $cuid,$cgid,$crdev,$csize, 976: $catime,$cmtime,$cctime, 977: $cblksize,$cblocks)=stat($prtspool.'/'.$filename); 978: my $result="<a href='/prtspool/$filename'>". 979: &mt('Generated [_1] ([_2] bytes)', 980: &Apache::lonlocal::locallocaltime($cctime),$csize). 981: '</a><br />'; 982: if ($ext eq 'pdf') { $pdf_result .= $result; } 983: if ($ext eq 'zip') { $zip_result .= $result; } 984: } 985: if ($zip_result) { 986: $r->print('<h4>'.&mt('Recently generated printout zip files')."</h4>\n" 987: .$zip_result); 988: } 989: if ($pdf_result) { 990: $r->print('<h4>'.&mt('Recently generated printouts')."</h4>\n" 991: .$pdf_result); 992: } 993: } 994: 995: # 996: # Retrieve the hash of page breaks. 997: # 998: # Inputs: 999: # helper - reference to helper object. 1000: # Outputs 1001: # A reference to a page break hash. 1002: # 1003: # 1004: #use Data::Dumper; 1005: #sub dump_helper_vars { 1006: # my ($helper) = @_; 1007: # my $helpervars = Dumper($helper->{'VARS'}); 1008: # &Apache::lonnet::logthis("Dump of helper vars:\n $helpervars"); 1009: #} 1010: 1011: sub get_page_breaks { 1012: my ($helper) = @_; 1013: my %page_breaks; 1014: 1015: foreach my $break (split /\|\|\|/, $helper->{'VARS'}->{'FINISHPAGE'}) { 1016: $page_breaks{$break} = 1; 1017: } 1018: return %page_breaks; 1019: } 1020: 1021: sub output_data { 1022: my ($r,$helper,$rparmhash) = @_; 1023: my %parmhash = %$rparmhash; 1024: my $resources_printed = ''; 1025: my $html=&Apache::lonxml::xmlbegin(); 1026: my $headtag = &Apache::loncommon::headtag('Preparing Printout'); 1027: my $end_headtag = &Apache::loncommon::endheadtag(); 1028: my $bodytag = &Apache::loncommon::bodytag('Preparing Printout'); 1029: $r->print(<<ENDPART); 1030: $html 1031: $headtag 1032: <script type="text/javascript" language="Javascript"> 1033: var editbrowser; 1034: function openbrowser(formname,elementname,only,omit) { 1035: var url = '/res/?'; 1036: if (editbrowser == null) { 1037: url += 'launch=1&'; 1038: } 1039: url += 'catalogmode=interactive&'; 1040: url += 'mode=parmset&'; 1041: url += 'form=' + formname + '&'; 1042: if (only != null) { 1043: url += 'only=' + only + '&'; 1044: } 1045: if (omit != null) { 1046: url += 'omit=' + omit + '&'; 1047: } 1048: url += 'element=' + elementname + ''; 1049: var title = 'Browser'; 1050: var options = 'scrollbars=1,resizable=1,menubar=0'; 1051: options += ',width=700,height=600'; 1052: editbrowser = open(url,title,options,'1'); 1053: editbrowser.focus(); 1054: } 1055: </script> 1056: $end_headtag 1057: $bodytag 1058: <p> 1059: Please stand by while processing your print request, this may take some time ... 1060: </p> 1061: ENDPART 1062: 1063: 1064: 1065: # fetch the pagebreaks and store them in the course environment 1066: # The page breaks will be pulled into the hash %page_breaks which is 1067: # indexed by symb and contains 1's for each break. 1068: 1069: $env{'form.pagebreaks'} = $helper->{'VARS'}->{'FINISHPAGE'}; 1070: $env{'form.lastprinttype'} = $helper->{'VARS'}->{'PRINT_TYPE'}; 1071: &Apache::loncommon::store_course_settings('print', 1072: {'pagebreaks' => 'scalar', 1073: 'lastprinttype' => 'scalar'}); 1074: 1075: my %page_breaks = &get_page_breaks($helper); 1076: 1077: my $format_from_helper = $helper->{'VARS'}->{'FORMAT'}; 1078: my ($result,$selectionmade) = ('',''); 1079: my $number_of_columns = 1; #used only for pages to determine the width of the cell 1080: my @temporary_array=split /\|/,$format_from_helper; 1081: my ($laystyle,$numberofcolumns,$papersize)=@temporary_array; 1082: if ($laystyle eq 'L') { 1083: $laystyle='album'; 1084: } else { 1085: $laystyle='book'; 1086: } 1087: my ($textwidth,$textheight,$oddoffset,$evenoffset) = &page_format($papersize,$laystyle,$numberofcolumns); 1088: my $assignment = $env{'form.assignment'}; 1089: my $LaTeXwidth=&recalcto_mm($textwidth); 1090: my @print_array=(); 1091: my @student_names=(); 1092: 1093: # Common settings for the %form has: 1094: # In some cases these settings get overriddent by specific cases, but the 1095: # settings are common enough to make it worthwhile factoring them out 1096: # here. 1097: # 1098: my %form; 1099: $form{'grade_target'} = 'tex'; 1100: $form{'textwidth'} = &get_textwidth($helper, $LaTeXwidth); 1101: 1102: # If form.showallfoils is set, then request all foils be shown: 1103: # privilege will be enforced both by not allowing the 1104: # check box selecting this option to be presnt unless it's ok, 1105: # and by lonresponse's priv. check. 1106: # The if is here because lonresponse.pm only cares that 1107: # showallfoils is defined, not what the value is. 1108: 1109: if ($helper->{'VARS'}->{'showallfoils'} eq "1") { 1110: $form{'showallfoils'} = $helper->{'VARS'}->{'showallfoils'}; 1111: } 1112: 1113: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') { 1114: #-- single document - problem, page, html, xml, ... 1115: my ($currentURL,$cleanURL); 1116: 1117: if ($helper->{'VARS'}->{'construction'} ne '1') { 1118: #prints published resource 1119: $currentURL=$helper->{'VARS'}->{'postdata'}; 1120: $cleanURL=&Apache::lonenc::check_decrypt($currentURL); 1121: } else { 1122: #prints resource from the construction space 1123: $currentURL='/'.$helper->{'VARS'}->{'filename'}; 1124: if ($currentURL=~/([^?]+)/) {$currentURL=$1;} 1125: $cleanURL=$currentURL; 1126: } 1127: $selectionmade = 1; 1128: if ($cleanURL!~m|^/adm/| 1129: && $cleanURL=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) { 1130: my $rndseed=time; 1131: my $texversion=''; 1132: if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') { 1133: my %moreenv; 1134: $moreenv{'request.filename'}=$cleanURL; 1135: if ($helper->{'VARS'}->{'style_file'}=~/\w/) { 1136: $moreenv{'construct.style'}=$helper->{'VARS'}->{'style_file'}; 1137: my $dom = $env{'user.domain'}; 1138: my $user = $env{'user.name'}; 1139: my $put_result = &Apache::lonnet::put('environment',{'construct.style'=>$helper->{'VARS'}->{'style_file'}},$dom,$user); 1140: } 1141: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {$form{'problemtype'}='exam';} 1142: $form{'problem_split'}=$parmhash{'problem_stream_switch'}; 1143: $form{'suppress_tries'}=$parmhash{'suppress_tries'}; 1144: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1145: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'}; 1146: if ($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') {$form{'problem_split'}='yes';} 1147: if ($helper->{'VARS'}->{'curseed'}) { 1148: $rndseed=$helper->{'VARS'}->{'curseed'}; 1149: } 1150: $form{'rndseed'}=$rndseed; 1151: &Apache::lonnet::appenv(%moreenv); 1152: 1153: &Apache::lonxml::clear_problem_counter(); 1154: 1155: $resources_printed .= $currentURL.':'; 1156: $texversion.=&Apache::lonnet::ssi($currentURL,%form); 1157: 1158: &Apache::lonxml::clear_problem_counter(); 1159: 1160: &Apache::lonnet::delenv('request.filename'); 1161: } 1162: # current document with answers.. no need to encap in minipage 1163: # since there's only one answer. 1164: 1165: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 1166: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { 1167: $form{'problem_split'}=$parmhash{'problem_stream_switch'}; 1168: $form{'grade_target'}='answer'; 1169: $form{'answer_output_mode'}='tex'; 1170: $form{'rndseed'}=$rndseed; 1171: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') { 1172: $form{'problemtype'}='exam'; 1173: } 1174: $resources_printed .= $currentURL.':'; 1175: my $answer=&Apache::lonnet::ssi($currentURL,%form); 1176: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 1177: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; 1178: } else { 1179: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 1180: if ($helper->{'VARS'}->{'construction'} ne '1') { 1181: $texversion.='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'}).'}\vskip 0 mm '; 1182: $texversion.=&path_to_problem($cleanURL,$LaTeXwidth); 1183: } else { 1184: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm '; 1185: my $URLpath=$cleanURL; 1186: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/; 1187: $texversion.=&path_to_problem ($URLpath,$LaTeXwidth); 1188: } 1189: $texversion.='\vskip 1 mm '.$answer.'\end{document}'; 1190: } 1191: } 1192: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { 1193: $texversion=&IndexCreation($texversion,$currentURL); 1194: } 1195: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') { 1196: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$currentURL| \\strut\\\\\\strut /; 1197: 1198: } 1199: $result .= $texversion; 1200: if ($currentURL=~m/\.page\s*$/) { 1201: ($result,$number_of_columns) = &page_cleanup($result); 1202: } 1203: } elsif ($cleanURL!~m|^/adm/| 1204: && $currentURL=~/\.sequence$/ && $helper->{'VARS'}->{'construction'} eq '1') { 1205: #printing content of sequence from the construction space 1206: my $flag_latex_header_remove = 'NO'; 1207: my $rndseed=time; 1208: if ($helper->{'VARS'}->{'curseed'}) { 1209: $rndseed=$helper->{'VARS'}->{'curseed'}; 1210: } 1211: $currentURL=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|; 1212: my $errtext=&Apache::lonratedt::mapread($currentURL); 1213: for (my $member=0;$member<=$#Apache::lonratedt::order;$member++) { 1214: $Apache::lonratedt::resources[$Apache::lonratedt::order[$member]]=~/^([^:]*):([^:]*):/; 1215: my $urlp=$2; 1216: if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/) { 1217: my $texversion=''; 1218: if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') { 1219: $form{'problem_split'}=$parmhash{'problem_stream_switch'}; 1220: $form{'suppress_tries'}=$parmhash{'suppress_tries'}; 1221: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1222: $form{'rndseed'}=$rndseed; 1223: $resources_printed .=$urlp.':'; 1224: $texversion=&Apache::lonnet::ssi($urlp,%form); 1225: } 1226: if((($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 1227: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) && 1228: ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page)$/)) { 1229: # Don't permanently modify %$form... 1230: my %answerform = %form; 1231: $answerform{'grade_target'}='answer'; 1232: $answerform{'answer_output_mode'}='tex'; 1233: $answerform{'rndseed'}=$rndseed; 1234: $answerform{'problem_split'}=$parmhash{'problem_stream_switch'}; 1235: if ($urlp=~/\/res\//) {$env{'request.state'}='published';} 1236: $resources_printed .= $urlp.':'; 1237: my $answer=&Apache::lonnet::ssi($urlp,%answerform); 1238: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 1239: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; 1240: } else { 1241: # If necessary, encapsulate answer in minipage: 1242: 1243: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 1244: my $body ='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'}).'}\vskip 0 mm '; 1245: $body.=&path_to_problem($urlp,$LaTeXwidth); 1246: $body.='\vskip 1 mm '.$answer.'\end{document}'; 1247: $body = &encapsulate_minipage($body); 1248: $texversion.=$body; 1249: } 1250: } 1251: if ($flag_latex_header_remove ne 'NO') { 1252: $texversion = &latex_header_footer_remove($texversion); 1253: } else { 1254: $texversion =~ s/\\end{document}//; 1255: } 1256: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { 1257: $texversion=&IndexCreation($texversion,$urlp); 1258: } 1259: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URpL'} eq 'yes') { 1260: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /; 1261: } 1262: $result.=$texversion; 1263: $flag_latex_header_remove = 'YES'; 1264: } elsif ($urlp=~/\.(sequence|page)$/) { 1265: $result.='\strut\newline\noindent Sequence/page '.$urlp.'\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent '; 1266: } 1267: } 1268: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\begin{document})/$1 \\fbox\{RANDOM SEED IS $rndseed\} /;} 1269: $result .= '\end{document}'; 1270: } elsif ($cleanURL=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { 1271: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1272: if ($currentURL=~/\/syllabus$/) {$currentURL=~s/\/res//;} 1273: $resources_printed .= $currentURL.':'; 1274: my $texversion=&Apache::lonnet::ssi($currentURL,%form); 1275: $result .= $texversion; 1276: } else { 1277: $result.=&unsupported($currentURL,$helper->{'VARS'}->{'LATEX_TYPE'}, 1278: $helper->{'VARS'}->{'symb'}); 1279: } 1280: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') or 1281: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or 1282: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') or 1283: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') or # BUGBUG 1284: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences')) { 1285: #-- produce an output string 1286: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') { 1287: $selectionmade = 2; 1288: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') { 1289: $selectionmade = 3; 1290: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') { 1291: $selectionmade = 4; 1292: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_resources') { #BUGBUG 1293: $selectionmade = 4; 1294: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') { 1295: $selectionmade = 7; 1296: } 1297: $form{'problem_split'}=$parmhash{'problem_stream_switch'}; 1298: $form{'suppress_tries'}=$parmhash{'suppress_tries'}; 1299: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1300: $form{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'}; 1301: if ($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') {$form{'problem_split'}='yes';} 1302: my $flag_latex_header_remove = 'NO'; 1303: my $flag_page_in_sequence = 'NO'; 1304: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'}; 1305: my $prevassignment=''; 1306: 1307: &Apache::lonxml::clear_problem_counter(); 1308: 1309: my $pbreakresources = keys %page_breaks; 1310: for (my $i=0;$i<=$#master_seq;$i++) { 1311: 1312: # Note due to document structure, not allowed to put \newpage 1313: # prior to the first resource 1314: 1315: if (defined $page_breaks{$master_seq[$i]}) { 1316: if($i != 0) { 1317: $result.="\\newpage\n"; 1318: } 1319: } 1320: my ($sequence,undef,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]); 1321: $urlp=&Apache::lonnet::clutter($urlp); 1322: $form{'symb'}=$master_seq[$i]; 1323: 1324: my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #title of the assignment which contains this problem 1325: if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;} 1326: if ($i==0) {$prevassignment=$assignment;} 1327: my $texversion=''; 1328: if ($urlp!~m|^/adm/| 1329: && $urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) { 1330: $resources_printed .= $urlp.':'; 1331: 1332: &Apache::lonxml::remember_problem_counter(); 1333: 1334: $texversion.=&Apache::lonnet::ssi($urlp,%form); 1335: if ($urlp=~/\.page$/) { 1336: ($texversion,my $number_of_columns_page) = &page_cleanup($texversion); 1337: if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;} 1338: $texversion =~ s/\\end{document}\d*/\\end{document}/; 1339: $flag_page_in_sequence = 'YES'; 1340: } 1341: 1342: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 1343: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { 1344: # Don't permanently pervert the %form hash 1345: my %answerform = %form; 1346: $answerform{'grade_target'}='answer'; 1347: $answerform{'answer_output_mode'}='tex'; 1348: $resources_printed .= $urlp.':'; 1349: 1350: &Apache::lonxml::restore_problem_counter(); 1351: my $answer=&Apache::lonnet::ssi($urlp,%answerform); 1352: 1353: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 1354: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; 1355: } else { 1356: if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library)$/) { 1357: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 1358: my $body ='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($master_seq[$i]).'}\vskip 0 mm '; 1359: $body .= &path_to_problem ($urlp,$LaTeXwidth); 1360: $body .='\vskip 1 mm '.$answer; 1361: $body = &encapsulate_minipage($body); 1362: $texversion .= $body; 1363: } else { 1364: $texversion=''; 1365: } 1366: } 1367: } 1368: if ($flag_latex_header_remove ne 'NO') { 1369: $texversion = &latex_header_footer_remove($texversion); 1370: } else { 1371: $texversion =~ s/\\end{document}//; 1372: } 1373: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { 1374: $texversion=&IndexCreation($texversion,$urlp); 1375: } 1376: if (($selectionmade == 4) and ($assignment ne $prevassignment)) { 1377: my $name = &get_name(); 1378: my $courseidinfo = &get_course(); 1379: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo } 1380: $prevassignment=$assignment; 1381: if ($numberofcolumns eq '1') { 1382: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{\\textit{\\textbf{'.$name.'}}'.$courseidinfo.' \\hfill \\thepage \\\\ \\textit{'.$assignment.'}}} \vskip 5 mm '; 1383: } else { 1384: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\fancyhead[LO]{\\textit{\\textbf{'.$name.'}}'.$courseidinfo.' \\hfill \\thepage \\\\ \\textit{'.$assignment.'}}} \vskip 5 mm '; 1385: } 1386: } 1387: $result .= $texversion; 1388: $flag_latex_header_remove = 'YES'; 1389: } elsif ($urlp=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { 1390: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1391: if ($urlp=~/\/syllabus$/) {$urlp=~s/\/res//;} 1392: $resources_printed .= $urlp.':'; 1393: my $texversion=&Apache::lonnet::ssi($urlp,%form); 1394: if ($flag_latex_header_remove ne 'NO') { 1395: $texversion = &latex_header_footer_remove($texversion); 1396: } else { 1397: $texversion =~ s/\\end{document}/\\vskip 0\.5mm\\noindent\\makebox\[\\textwidth\/\$number_of_columns\]\[b\]\{\\hrulefill\}/; 1398: } 1399: $result .= $texversion; 1400: $flag_latex_header_remove = 'YES'; 1401: } else { 1402: $texversion=&unsupported($urlp,$helper->{'VARS'}->{'LATEX_TYPE'}, 1403: $master_seq[$i]); 1404: if ($flag_latex_header_remove ne 'NO') { 1405: $texversion = &latex_header_footer_remove($texversion); 1406: } else { 1407: $texversion =~ s/\\end{document}//; 1408: } 1409: $result .= $texversion; 1410: $flag_latex_header_remove = 'YES'; 1411: } 1412: if (&Apache::loncommon::connection_aborted($r)) { last; } 1413: } 1414: &Apache::lonxml::clear_problem_counter(); 1415: if ($flag_page_in_sequence eq 'YES') { 1416: $result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/; 1417: } 1418: $result .= '\end{document}'; 1419: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') || 1420: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){ 1421: 1422: 1423: #-- prints assignments for whole class or for selected students 1424: my $type; 1425: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') { 1426: $selectionmade=5; 1427: $type='problems'; 1428: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') { 1429: $selectionmade=8; 1430: $type='resources'; 1431: } 1432: my @students=split /\|\|\|/, $helper->{'VARS'}->{'STUDENTS'}; 1433: # The normal sort order is by section then by students within the 1434: # section. If the helper var student_sort is 1, then the user has elected 1435: # to override this and output the students by name. 1436: # Each element of the students array is of the form: 1437: # username:domain:section:last, first:status 1438: # 1439: # Note that student sort is not compatible with printing 1440: # 1 section per pdf...so that setting overrides. 1441: # 1442: if (($helper->{'VARS'}->{'student_sort'} eq 1) && 1443: ($helper->{'VARS'}->{'SPLIT_PDFS'} ne "sections")) { 1444: @students = sort compare_names @students; 1445: } 1446: &adjust_number_to_print($helper); 1447: 1448: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq '0' || 1449: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'all' ) { 1450: $helper->{'VARS'}->{'NUMBER_TO_PRINT'}=$#students+1; 1451: } 1452: # If we are splitting on section boundaries, we need 1453: # to remember that in split_on_sections and 1454: # print all of the students in the list. 1455: # 1456: my $split_on_sections = 0; 1457: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'section') { 1458: $split_on_sections = 1; 1459: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} = $#students+1; 1460: } 1461: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'}; 1462: 1463: #loop over students 1464: my $flag_latex_header_remove = 'NO'; 1465: my %moreenv; 1466: $moreenv{'instructor_comments'}='hide'; 1467: $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth); 1468: $moreenv{'print_discussions'}=$helper->{'VARS'}->{'PRINT_DISCUSSIONS'}; 1469: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'}; 1470: $moreenv{'suppress_tries'} = $parmhash{'suppress_tries'}; 1471: if ($helper->{'VARS'}->{'PRINT_DISCUSSIONS'} eq 'yes') {$moreenv{'problem_split'}='yes';} 1472: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1,'inline','75'); 1473: my $student_counter=-1; 1474: my $i = 0; 1475: my $last_section = (split(/:/,$students[0]))[2]; 1476: foreach my $person (@students) { 1477: 1478: my $duefile="/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.due"; 1479: if (-e $duefile) { 1480: my $temp_file = Apache::File->new('>>'.$duefile); 1481: print $temp_file "1969\n"; 1482: } 1483: $student_counter++; 1484: if ($split_on_sections) { 1485: my $this_section = (split(/:/,$person))[2]; 1486: if ($this_section ne $last_section) { 1487: $i++; 1488: $last_section = $this_section; 1489: } 1490: } else { 1491: $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'}); 1492: } 1493: my ($output,$fullname, $printed)=&print_resources($r,$helper, 1494: $person,$type, 1495: \%moreenv,\@master_seq, 1496: $flag_latex_header_remove, 1497: $LaTeXwidth); 1498: $resources_printed .= ":"; 1499: $print_array[$i].=$output; 1500: $student_names[$i].=$person.':'.$fullname.'_END_'; 1501: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname); 1502: $flag_latex_header_remove = 'YES'; 1503: if (&Apache::loncommon::connection_aborted($r)) { last; } 1504: } 1505: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); 1506: $result .= $print_array[0].' \end{document}'; 1507: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon') || 1508: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon') ) { 1509: my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'}; 1510: my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'}; 1511: my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'}; 1512: my $code_name=$helper->{'VARS'}->{'ANON_CODE_STORAGE_NAME'}; 1513: my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'}; 1514: my $single_code = $helper->{'VARS'}->{'SINGLE_CODE'}; 1515: my $selected_code = $helper->{'VARS'}->{'CODE_SELECTED_FROM_LIST'}; 1516: 1517: my $code_option=$helper->{'VARS'}->{'CODE_OPTION'}; 1518: open(FH,$Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab'); 1519: my ($code_type,$code_length)=('letter',6); 1520: foreach my $line (<FH>) { 1521: my ($name,$type,$length) = (split(/:/,$line))[0,2,4]; 1522: if ($name eq $code_option) { 1523: $code_length=$length; 1524: if ($type eq 'number') { $code_type = 'number'; } 1525: } 1526: } 1527: my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth)); 1528: $moreenv{'problem_split'} = $parmhash{'problem_stream_switch'}; 1529: $moreenv{'instructor_comments'}='hide'; 1530: my $seed=time+($$<<16)+($$); 1531: my @allcodes; 1532: if ($old_name) { 1533: my %result=&Apache::lonnet::get('CODEs', 1534: [$old_name,"type\0$old_name"], 1535: $cdom,$cnum); 1536: $code_type=$result{"type\0$old_name"}; 1537: @allcodes=split(',',$result{$old_name}); 1538: $num_todo=scalar(@allcodes); 1539: } elsif ($selected_code) { # Selection value is always numeric. 1540: $num_todo = 1; 1541: @allcodes = ($selected_code); 1542: } elsif ($single_code) { 1543: 1544: $num_todo = 1; # Unconditionally one code to do. 1545: # If an alpha code have to convert to numbers so it can be 1546: # converted back to letters again :-) 1547: # 1548: if ($code_type ne 'number') { 1549: $single_code = &letters_to_num($single_code); 1550: } 1551: @allcodes = ($single_code); 1552: } else { 1553: my %allcodes; 1554: srand($seed); 1555: for (my $i=0;$i<$num_todo;$i++) { 1556: $moreenv{'CODE'}=&get_CODE(\%allcodes,$i,$seed,$code_length, 1557: $code_type); 1558: } 1559: if ($code_name) { 1560: &Apache::lonnet::put('CODEs', 1561: { 1562: $code_name =>join(',',keys(%allcodes)), 1563: "type\0$code_name" => $code_type 1564: }, 1565: $cdom,$cnum); 1566: } 1567: @allcodes=keys(%allcodes); 1568: } 1569: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'}; 1570: my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'}); 1571: my $number_per_page=$helper->{'VARS'}->{'NUMBER_TO_PRINT'}; 1572: if ($number_per_page eq '0' || $number_per_page eq 'all') { 1573: $number_per_page=$num_todo; 1574: } 1575: my $flag_latex_header_remove = 'NO'; 1576: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline','75'); 1577: my $count=0; 1578: foreach my $code (sort(@allcodes)) { 1579: my $file_num=int($count/$number_per_page); 1580: if ($code_type eq 'number') { 1581: $moreenv{'CODE'}=$code; 1582: } else { 1583: $moreenv{'CODE'}=&num_to_letters($code); 1584: } 1585: my ($output,$fullname, $printed)= 1586: &print_resources($r,$helper,'anonymous',$type,\%moreenv, 1587: \@master_seq,$flag_latex_header_remove, 1588: $LaTeXwidth); 1589: $resources_printed .= ":"; 1590: $print_array[$file_num].=$output; 1591: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state, 1592: &mt('last assignment').' '.$fullname); 1593: $flag_latex_header_remove = 'YES'; 1594: $count++; 1595: if (&Apache::loncommon::connection_aborted($r)) { last; } 1596: } 1597: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); 1598: $result .= $print_array[0].' \end{document}'; 1599: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') { 1600: #prints selected problems from the subdirectory 1601: $selectionmade = 6; 1602: my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'}; 1603: @list_of_files=sort @list_of_files; 1604: my $flag_latex_header_remove = 'NO'; 1605: my $rndseed=time; 1606: if ($helper->{'VARS'}->{'curseed'}) { 1607: $rndseed=$helper->{'VARS'}->{'curseed'}; 1608: } 1609: for (my $i=0;$i<=$#list_of_files;$i++) { 1610: my $urlp = $list_of_files[$i]; 1611: $urlp=~s|//|/|; 1612: if ($urlp=~/\//) { 1613: $form{'problem_split'}=$parmhash{'problem_stream_switch'}; 1614: $form{'rndseed'}=$rndseed; 1615: if ($urlp =~ m|/home/([^/]+)/public_html|) { 1616: $urlp =~ s|/home/([^/]*)/public_html|/~$1|; 1617: } else { 1618: $urlp =~ s|^$Apache::lonnet::perlvar{'lonDocRoot'}||; 1619: } 1620: $resources_printed .= $urlp.':'; 1621: my $texversion=&Apache::lonnet::ssi($urlp,%form); 1622: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 1623: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { 1624: # Don't permanently pervert %form: 1625: my %answerform = %form; 1626: $answerform{'grade_target'}='answer'; 1627: $answerform{'answer_output_mode'}='tex'; 1628: $answerform{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1629: $answerform{'rndseed'}=$rndseed; 1630: $resources_printed .= $urlp.':'; 1631: my $answer=&Apache::lonnet::ssi($urlp,%answerform); 1632: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 1633: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; 1634: } else { 1635: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 1636: if ($helper->{'VARS'}->{'construction'} ne '1') { 1637: $texversion.='\vskip 0 mm \noindent '; 1638: $texversion.=&path_to_problem ($urlp,$LaTeXwidth); 1639: } else { 1640: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm '; 1641: my $URLpath=$urlp; 1642: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/; 1643: $texversion.=&path_to_problem ($URLpath,$LaTeXwidth); 1644: } 1645: $texversion.='\vskip 1 mm '.$answer.'\end{document}'; 1646: } 1647: } 1648: #this chunck is responsible for printing the path to problem 1649: my $newurlp=$urlp; 1650: if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;} 1651: $newurlp=&path_to_problem($newurlp,$LaTeXwidth); 1652: $texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/; 1653: if ($flag_latex_header_remove ne 'NO') { 1654: $texversion = &latex_header_footer_remove($texversion); 1655: } else { 1656: $texversion =~ s/\\end{document}//; 1657: } 1658: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { 1659: $texversion=&IndexCreation($texversion,$urlp); 1660: } 1661: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') { 1662: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /; 1663: 1664: } 1665: $result .= $texversion; 1666: } 1667: $flag_latex_header_remove = 'YES'; 1668: } 1669: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;} 1670: $result .= '\end{document}'; 1671: } 1672: #-------------------------------------------------------- corrections for the different page formats 1673: $result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'},$selectionmade); 1674: $result = &latex_corrections($number_of_columns,$result,$selectionmade, 1675: $helper->{'VARS'}->{'ANSWER_TYPE'}); 1676: for (my $i=1;$i<=$#print_array;$i++) { 1677: $print_array[$i] = 1678: &latex_corrections($number_of_columns,$print_array[$i], 1679: $selectionmade, 1680: $helper->{'VARS'}->{'ANSWER_TYPE'}); 1681: } 1682: #changes page's parameters for the one column output 1683: if ($numberofcolumns == 1) { 1684: $result =~ s/\\textwidth\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /; 1685: $result =~ s/\\textheight\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /; 1686: $result =~ s/\\evensidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /; 1687: $result =~ s/\\oddsidemargin\s*=\s*-?\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /; 1688: } 1689: 1690: #-- writing .tex file in prtspool 1691: my $temp_file; 1692: my $identifier = &Apache::loncommon::get_cgi_id(); 1693: my $filename = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout_$identifier.tex"; 1694: if (!($#print_array>0)) { 1695: unless ($temp_file = Apache::File->new('>'.$filename)) { 1696: $r->log_error("Couldn't open $filename for output $!"); 1697: return SERVER_ERROR; 1698: } 1699: print $temp_file $result; 1700: my $begin=index($result,'\begin{document}',0); 1701: my $inc=substr($result,0,$begin+16); 1702: } else { 1703: my $begin=index($result,'\begin{document}',0); 1704: my $inc=substr($result,0,$begin+16); 1705: for (my $i=0;$i<=$#print_array;$i++) { 1706: if ($i==0) { 1707: $print_array[$i]=$result; 1708: } else { 1709: my $anobegin=index($print_array[$i],'\setcounter{page}',0); 1710: substr($print_array[$i],0,$anobegin)=''; 1711: $print_array[$i]=$inc.$print_array[$i].'\end{document}'; 1712: } 1713: my $temp_file; 1714: my $newfilename=$filename; 1715: my $num=$i+1; 1716: $newfilename =~s/\.tex$//; 1717: $newfilename=sprintf("%s_%03d.tex",$newfilename, $num); 1718: unless ($temp_file = Apache::File->new('>'.$newfilename)) { 1719: $r->log_error("Couldn't open $newfilename for output $!"); 1720: return SERVER_ERROR; 1721: } 1722: print $temp_file $print_array[$i]; 1723: } 1724: } 1725: my $student_names=''; 1726: if ($#print_array>0) { 1727: for (my $i=0;$i<=$#print_array;$i++) { 1728: $student_names.=$student_names[$i].'_ENDPERSON_'; 1729: } 1730: } else { 1731: if ($#student_names>-1) { 1732: $student_names=$student_names[0].'_ENDPERSON_'; 1733: } else { 1734: my $fullname = &get_name($env{'user.name'},$env{'user.domain'}); 1735: $student_names=join(':',$env{'user.name'},$env{'user.domain'}, 1736: $env{'request.course.sec'},$fullname). 1737: '_ENDPERSON_'.'_END_'; 1738: } 1739: } 1740: 1741: my $URLback=''; #link to original document 1742: if ($helper->{'VARS'}->{'construction'} ne '1') { 1743: #prints published resource 1744: $URLback=&Apache::lonnet::escape('/adm/flip?postdata=return:'); 1745: } else { 1746: #prints resource from the construction space 1747: $URLback='/'.$helper->{'VARS'}->{'filename'}; 1748: if ($URLback=~/([^?]+)/) { 1749: $URLback=$1; 1750: $URLback=~s|^/~|/priv/|; 1751: } 1752: } 1753: # logic for now is too complex to trace if this has been defined 1754: # yet. 1755: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; 1756: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; 1757: &Apache::lonnet::appenv('cgi.'.$identifier.'.file' => $filename, 1758: 'cgi.'.$identifier.'.layout' => $laystyle, 1759: 'cgi.'.$identifier.'.numcol' => $numberofcolumns, 1760: 'cgi.'.$identifier.'.paper' => $papersize, 1761: 'cgi.'.$identifier.'.selection' => $selectionmade, 1762: 'cgi.'.$identifier.'.tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'}, 1763: 'cgi.'.$identifier.'.tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'}, 1764: 'cgi.'.$identifier.'.role' => $perm{'pav'}, 1765: 'cgi.'.$identifier.'.numberoffiles' => $#print_array, 1766: 'cgi.'.$identifier.'.studentnames' => $student_names, 1767: 'cgi.'.$identifier.'.backref' => $URLback,); 1768: &Apache::lonnet::appenv("cgi.$identifier.user" => $env{'user.name'}, 1769: "cgi.$identifier.domain" => $env{'user.domain'}, 1770: "cgi.$identifier.courseid" => $cnum, 1771: "cgi.$identifier.coursedom" => $cdom, 1772: "cgi.$identifier.resources" => $resources_printed); 1773: 1774: my $end_page = &Apache::loncommon::end_page(); 1775: $r->print(<<FINALEND); 1776: <br /> 1777: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" /> 1778: <a href="/cgi-bin/printout.pl?$identifier">Continue</a> 1779: $end_page 1780: FINALEND 1781: } 1782: 1783: 1784: sub get_CODE { 1785: my ($all_codes,$num,$seed,$size,$type)=@_; 1786: my $max='1'.'0'x$size; 1787: my $newcode; 1788: while(1) { 1789: $newcode=sprintf("%0".$size."d",int(rand($max))); 1790: if (!exists($$all_codes{$newcode})) { 1791: $$all_codes{$newcode}=1; 1792: if ($type eq 'number' ) { 1793: return $newcode; 1794: } else { 1795: return &num_to_letters($newcode); 1796: } 1797: } 1798: } 1799: } 1800: 1801: sub print_resources { 1802: my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header, 1803: $LaTeXwidth)=@_; 1804: my $current_output = ''; 1805: my $printed = ''; 1806: my ($username,$userdomain,$usersection) = split /:/,$person; 1807: my $fullname = &get_name($username,$userdomain); 1808: my $namepostfix; 1809: if ($person =~ 'anon') { 1810: $namepostfix="\\\\Name: "; 1811: $fullname = "CODE - ".$moreenv->{'CODE'}; 1812: } 1813: my $i = 0; 1814: #goes through all resources, checks if they are available for 1815: #current student, and produces output 1816: 1817: &Apache::lonxml::clear_problem_counter(); 1818: my %page_breaks = &get_page_breaks($helper); 1819: my @format_array = split(/\|/,$helper->{'VARS'}->{'FORMAT'}); 1820: my $columns_in_format = $format_array[1]; 1821: 1822: foreach my $curresline (@{$master_seq}) { 1823: if (defined $page_breaks{$curresline}) { 1824: if($i != 0) { 1825: $current_output.= "\\newpage\n"; 1826: } 1827: } 1828: $i++; 1829: if ( !($type eq 'problems' && 1830: ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) { 1831: my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline); 1832: if (&Apache::lonnet::allowed('bre',$res_url)) { 1833: if ($res_url!~m|^ext/| 1834: && $res_url=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) { 1835: $printed .= $curresline.':'; 1836: 1837: &Apache::lonxml::remember_problem_counter(); 1838: 1839: my $rendered = &Apache::loncommon::get_student_view($curresline,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv); 1840: 1841: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 1842: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { 1843: # Use a copy of the hash so we don't pervert it on future loop passes. 1844: my %answerenv = %{$moreenv}; 1845: $answerenv{'answer_output_mode'}='tex'; 1846: $answerenv{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1847: 1848: &Apache::lonxml::restore_problem_counter(); 1849: 1850: my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$env{'request.course.id'},%answerenv); 1851: 1852: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 1853: $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/; 1854: } else { 1855: 1856: 1857: my $header =&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 1858: my $body ='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($curresline).'}\vskip 0 mm '; 1859: $body .=&path_to_problem($res_url,$LaTeXwidth); 1860: $body .='\vskip 1 mm '.$ansrendered; 1861: $body = &encapsulate_minipage($body); 1862: $rendered = $header.$body; 1863: } 1864: } 1865: if ($remove_latex_header eq 'YES') { 1866: $rendered = &latex_header_footer_remove($rendered); 1867: } else { 1868: $rendered =~ s/\\end{document}//; 1869: } 1870: $current_output .= $rendered; 1871: } elsif ($res_url=~/\/(smppg|syllabus|aboutme|bulletinboard)$/) { 1872: $printed .= $curresline.':'; 1873: my $rendered = &Apache::loncommon::get_student_view($curresline,$username,$userdomain,$env{'request.course.id'},'tex',$moreenv); 1874: 1875: if ($remove_latex_header eq 'YES') { 1876: $rendered = &latex_header_footer_remove($rendered); 1877: } else { 1878: $rendered =~ s/\\end{document}//; 1879: } 1880: $current_output .= $rendered.'\vskip 0.5mm\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\strut \vskip 0 mm \strut '; 1881: 1882: } else { 1883: my $rendered = &unsupported($res_url,$helper->{'VARS'}->{'LATEX_TYPE'},$curresline); 1884: if ($remove_latex_header ne 'NO') { 1885: $rendered = &latex_header_footer_remove($rendered); 1886: } else { 1887: $rendered =~ s/\\end{document}//; 1888: } 1889: $current_output .= $rendered; 1890: } 1891: } 1892: $remove_latex_header = 'YES'; 1893: } 1894: if (&Apache::loncommon::connection_aborted($r)) { last; } 1895: } 1896: my $courseidinfo = &get_course(); 1897: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo } 1898: if ($usersection ne '') {$courseidinfo.=' - Sec. '.$usersection} 1899: my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header'); 1900: if ($current_output=~/\\documentclass/) { 1901: if ($columns_in_format == 1) { 1902: $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent\\lhead{\\textit{\\textbf{$fullname}}$courseidinfo \\hfill \\thepage \\\\ \\textit{$currentassignment}$namepostfix}}\\vskip 5 mm /; 1903: } else { 1904: $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\parbox{\\minipagewidth}{\\noindent\\fancyhead[LO]{\\textit{\\textbf{$fullname}}$courseidinfo \\hfill \\thepage \\\\ \\textit{$currentassignment}$namepostfix}}\\vskip 5 mm /; 1905: 1906: } 1907: } else { 1908: my $blankpages = ''; 1909: for (my $j=0;$j<$helper->{'VARS'}->{'EMPTY_PAGES'};$j++) {$blankpages.='\clearpage\strut\clearpage';} 1910: if ($columns_in_format == 1) { 1911: $current_output = '\strut\vspace*{-6 mm}\\newline\\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 }\\newpage '.$blankpages.'\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent\\lhead{\\textit{\\textbf{'.$fullname.'}}'.$courseidinfo.' \\hfill \\thepage \\\\ \\textit{'.$currentassignment.'}'.$namepostfix.'}} \vskip 5 mm '.$current_output; 1912: } else { 1913: $current_output = '\strut\vspace*{-6 mm}\\newline\\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 }\\newpage '.$blankpages.'\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent\\fancyhead[LO]{\\textit{\\textbf{'.$fullname.'}}'.$courseidinfo.' \\hfill \\thepage \\\\ \\textit{'.$currentassignment.'}'.$namepostfix.'}} \vskip 5 mm '.$current_output; 1914: } 1915: } 1916: return ($current_output,$fullname, $printed); 1917: 1918: } 1919: 1920: sub handler { 1921: 1922: my $r = shift; 1923: 1924: &init_perm(); 1925: 1926: 1927: 1928: my $helper = printHelper($r); 1929: if (!ref($helper)) { 1930: return $helper; 1931: } 1932: 1933: 1934: my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'}); 1935: 1936: 1937: 1938: 1939: # If a figure conversion queue file exists for this user.domain 1940: # we delete it since it can only be bad (if it were good, printout.pl 1941: # would have deleted it the last time around. 1942: 1943: my $conversion_queuefile = "/home/httpd/prtspool/$env{'user.name'}_$env{'user.domain'}_printout.dat"; 1944: if(-e $conversion_queuefile) { 1945: unlink $conversion_queuefile; 1946: } 1947: &output_data($r,$helper,\%parmhash); 1948: return OK; 1949: } 1950: 1951: use Apache::lonhelper; 1952: 1953: sub addMessage { 1954: my $text = shift; 1955: my $paramHash = Apache::lonhelper::getParamHash(); 1956: $paramHash->{MESSAGE_TEXT} = $text; 1957: Apache::lonhelper::message->new(); 1958: } 1959: 1960: 1961: 1962: sub init_perm { 1963: undef(%perm); 1964: $perm{'pav'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'}); 1965: if (!$perm{'pav'}) { 1966: $perm{'pav'}=&Apache::lonnet::allowed('pav', 1967: $env{'request.course.id'}.'/'.$env{'request.course.sec'}); 1968: } 1969: $perm{'pfo'}=&Apache::lonnet::allowed('pav',$env{'request.course.id'}); 1970: if (!$perm{'pfo'}) { 1971: $perm{'pfo'}=&Apache::lonnet::allowed('pfo', 1972: $env{'request.course.id'}.'/'.$env{'request.course.sec'}); 1973: } 1974: } 1975: 1976: sub printHelper { 1977: my $r = shift; 1978: 1979: if ($r->header_only) { 1980: if ($env{'browser.mathml'}) { 1981: &Apache::loncommon::content_type($r,'text/xml'); 1982: } else { 1983: &Apache::loncommon::content_type($r,'text/html'); 1984: } 1985: $r->send_http_header; 1986: return OK; 1987: } 1988: 1989: # Send header, nocache 1990: if ($env{'browser.mathml'}) { 1991: &Apache::loncommon::content_type($r,'text/xml'); 1992: } else { 1993: &Apache::loncommon::content_type($r,'text/html'); 1994: } 1995: &Apache::loncommon::no_cache($r); 1996: $r->send_http_header; 1997: $r->rflush(); 1998: 1999: # Unfortunately, this helper is so complicated we have to 2000: # write it by hand 2001: 2002: Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); 2003: 2004: my $helper = Apache::lonhelper::helper->new("Printing Helper"); 2005: $helper->declareVar('symb'); 2006: $helper->declareVar('postdata'); 2007: $helper->declareVar('curseed'); 2008: $helper->declareVar('probstatus'); 2009: $helper->declareVar('filename'); 2010: $helper->declareVar('construction'); 2011: $helper->declareVar('assignment'); 2012: $helper->declareVar('style_file'); 2013: $helper->declareVar('student_sort'); 2014: $helper->declareVar('FINISHPAGE'); 2015: $helper->declareVar('PRINT_TYPE'); 2016: $helper->declareVar("showallfoils"); 2017: 2018: # The page breaks can get loaded initially from the course environment: 2019: # But we only do this in the initial state so that they are allowed to change. 2020: # 2021: 2022: # $helper->{VARS}->{FINISHPAGE} = ''; 2023: 2024: &Apache::loncommon::restore_course_settings('print', 2025: {'pagebreaks' => 'scalar', 2026: 'lastprinttype' => 'scalar'}); 2027: 2028: 2029: if($helper->{VARS}->{PRINT_TYPE} eq $env{'form.lastprinttype'}) { 2030: if (!defined ($env{"form.CURRENT_STATE"})) { 2031: 2032: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'}; 2033: } else { 2034: my $state = $env{"form.CURRENT_STATE"}; 2035: if ($state eq "START") { 2036: $helper->{VARS}->{FINISHPAGE} = $env{'form.pagebreaks'}; 2037: } 2038: } 2039: 2040: } 2041: 2042: 2043: # This will persistently load in the data we want from the 2044: # very first screen. 2045: # Detect whether we're coming from construction space 2046: if ($env{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) { 2047: $helper->{VARS}->{'filename'} = "~$1/$2"; 2048: $helper->{VARS}->{'construction'} = 1; 2049: } else { 2050: if ($env{'form.postdata'}) { 2051: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($env{'form.postdata'}); 2052: } 2053: if ($env{'form.symb'}) { 2054: $helper->{VARS}->{'symb'} = $env{'form.symb'}; 2055: } 2056: if ($env{'form.url'}) { 2057: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'}); 2058: } 2059: 2060: } 2061: 2062: if ($env{'form.symb'}) { 2063: $helper->{VARS}->{'symb'} = $env{'form.symb'}; 2064: } 2065: if ($env{'form.url'}) { 2066: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'}); 2067: 2068: } 2069: $helper->{VARS}->{'symb'}= 2070: &Apache::lonenc::check_encrypt($helper->{VARS}->{'symb'}); 2071: my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu($helper); 2072: if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;} 2073: 2074: 2075: # Extract map 2076: my $symb = $helper->{VARS}->{'symb'}; 2077: my ($map, $id, $url); 2078: my $subdir; 2079: 2080: # Get the resource name from construction space 2081: if ($helper->{VARS}->{'construction'}) { 2082: $resourceTitle = substr($helper->{VARS}->{'filename'}, 2083: rindex($helper->{VARS}->{'filename'}, '/')+1); 2084: $subdir = substr($helper->{VARS}->{'filename'}, 2085: 0, rindex($helper->{VARS}->{'filename'}, '/') + 1); 2086: } else { 2087: ($map, $id, $url) = &Apache::lonnet::decode_symb($symb); 2088: $helper->{VARS}->{'postdata'} = 2089: &Apache::lonenc::check_encrypt(&Apache::lonnet::clutter($url)); 2090: 2091: if (!$resourceTitle) { # if the resource doesn't have a title, use the filename 2092: my $postdata = $helper->{VARS}->{'postdata'}; 2093: $resourceTitle = substr($postdata, rindex($postdata, '/') + 1); 2094: } 2095: $subdir = &Apache::lonnet::filelocation("", $url); 2096: } 2097: if (!$helper->{VARS}->{'curseed'} && $env{'form.curseed'}) { 2098: $helper->{VARS}->{'curseed'}=$env{'form.curseed'}; 2099: } 2100: if (!$helper->{VARS}->{'probstatus'} && $env{'form.problemtype'}) { 2101: $helper->{VARS}->{'probstatus'}=$env{'form.problemtype'}; 2102: } 2103: 2104: my $userCanSeeHidden = Apache::lonnavmaps::advancedUser(); 2105: 2106: Apache::lonhelper::registerHelperTags(); 2107: 2108: # "Delete everything after the last slash." 2109: $subdir =~ s|/[^/]+$||; 2110: if (not $helper->{VARS}->{'construction'}) { 2111: $subdir=$Apache::lonnet::perlvar{'lonDocRoot'}.'/res/'.$subdir; 2112: } 2113: # "Remove all duplicate slashes." 2114: $subdir =~ s|/+|/|g; 2115: 2116: # What can be printed is a very dynamic decision based on 2117: # lots of factors. So we need to dynamically build this list. 2118: # To prevent security leaks, states are only added to the wizard 2119: # if they can be reached, which ensures manipulating the form input 2120: # won't allow anyone to reach states they shouldn't have permission 2121: # to reach. 2122: 2123: # printChoices is tracking the kind of printing the user can 2124: # do, and will be used in a choices construction later. 2125: # In the meantime we will be adding states and elements to 2126: # the helper by hand. 2127: my $printChoices = []; 2128: my $paramHash; 2129: 2130: if ($resourceTitle) { 2131: push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('what you just saw on the screen').")", 'current_document', 'PAGESIZE']; 2132: } 2133: 2134: # Useful filter strings 2135: my $isProblem = '($res->is_problem()||$res->contains_problem) '; 2136: $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden; 2137: my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence()'; 2138: my $isNotMap = '!$res->is_sequence()'; 2139: $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden; 2140: my $isMap = '$res->is_map()'; 2141: my $symbFilter = '$res->shown_symb()'; 2142: my $urlValue = '$res->link()'; 2143: 2144: $helper->declareVar('SEQUENCE'); 2145: 2146: 2147: 2148: # If we're in a sequence... 2149: if (($helper->{'VARS'}->{'construction'} ne '1') && 2150: 2151: $helper->{VARS}->{'postdata'} && 2152: $helper->{VARS}->{'assignment'}) { 2153: # Allow problems from sequence 2154: push @{$printChoices}, ["<b>".&mt('Problems')."</b> ".&mt('in')." <b><i>$sequenceTitle</i></b>", 'map_problems', 'CHOOSE_PROBLEMS']; 2155: # Allow all resources from sequence 2156: push @{$printChoices}, ["<b>".&mt('Resources')."</b> ".&mt('in')." <b><i>$sequenceTitle</i></b>", 'map_problems_pages', 'CHOOSE_PROBLEMS_HTML']; 2157: 2158: my $helperFragment = <<HELPERFRAGMENT; 2159: <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print"> 2160: <message>(mark them then click "next" button) <br /></message> 2161: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1" 2162: closeallpages="1"> 2163: <nextstate>PAGESIZE</nextstate> 2164: <filterfunc>return $isProblem;</filterfunc> 2165: <mapurl>$map</mapurl> 2166: <valuefunc>return $symbFilter;</valuefunc> 2167: <option text='Newpage' variable='FINISHPAGE' /> 2168: </resource> 2169: </state> 2170: 2171: <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print"> 2172: <message>(mark them then click "next" button) <br /></message> 2173: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1" 2174: closeallpages="1"> 2175: <nextstate>PAGESIZE</nextstate> 2176: <filterfunc>return $isNotMap;</filterfunc> 2177: <mapurl>$map</mapurl> 2178: <valuefunc>return $symbFilter;</valuefunc> 2179: <option text='Newpage' variable='FINISHPAGE' /> 2180: </resource> 2181: </state> 2182: HELPERFRAGMENT 2183: 2184: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment); 2185: } 2186: 2187: # If the user has pfo (print for otheres) allow them to print all 2188: # problems and resources in the entier course, optionally for selected students 2189: if ($perm{'pfo'} && 2190: ($helper->{VARS}->{'postdata'}=~/\/res\// || $helper->{VARS}->{'postdata'}=~/\/(syllabus|smppg|aboutme|bulletinboard)$/)) { 2191: 2192: push @{$printChoices}, ['<b>Problems</b> from <b>entire course</b>', 'all_problems', 'ALL_PROBLEMS']; 2193: push @{$printChoices}, ['<b>Resources</b> from <b>entire course</b>', 'all_resources', 'ALL_RESOURCES']; 2194: &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS); 2195: <state name="ALL_PROBLEMS" title="Select Problem(s) to print"> 2196: <message>(mark them then click "next" button) <br /></message> 2197: <resource variable="RESOURCES" toponly='0' multichoice="1" 2198: suppressEmptySequences='0' addstatus="1" closeallpages="1"> 2199: <nextstate>PAGESIZE</nextstate> 2200: <filterfunc>return $isProblemOrMap;</filterfunc> 2201: <choicefunc>return $isNotMap;</choicefunc> 2202: <valuefunc>return $symbFilter;</valuefunc> 2203: <option text='Newpage' variable='FINISHPAGE' /> 2204: </resource> 2205: </state> 2206: <state name="ALL_RESOURCES" title="Select Resource(s) to print"> 2207: <message>(Mark them then click "next" button) <br /> </message> 2208: <resource variable="RESOURCES" toponly='0' multichoice='1' 2209: suppressEmptySequences='0' addstatus='1' closeallpages='1'> 2210: <nextstate>PAGESIZE</nextstate> 2211: <filterfunc>return $isNotMap; </filterfunc> 2212: <valuefunc>return $symbFilter;</valuefunc> 2213: <option text='NewPage' variable='FINISHPAGE' /> 2214: </resource> 2215: </state> 2216: ALL_PROBLEMS 2217: 2218: if ($helper->{VARS}->{'assignment'}) { 2219: push @{$printChoices}, ["<b>".&mt('Problems')."</b> ".&mt('from')." <b><i>$sequenceTitle</i></b> ".&mt('for')." <b>".&mt('selected students')."</b>", 'problems_for_students', 'CHOOSE_STUDENTS']; 2220: push @{$printChoices}, ["<b>".&mt('Problems')."</b> ".&mt('from')." <b><i>$sequenceTitle</i></b> ".&mt('for')." <b>".&mt('anonymous students')."</b>", 'problems_for_anon', 'CHOOSE_ANON1']; 2221: } 2222: 2223: # resource_selector will hold a few states that: 2224: # - Allow resources to be selected for printing. 2225: # - Determine pagination between assignments. 2226: # - Determine how many assignments should be bundled into a single PDF. 2227: # TODO: 2228: # Probably good to do things like separate this up into several vars, each 2229: # with one state, and use REGEXPs at inclusion time to set state names 2230: # and next states for better mix and match capability 2231: # 2232: my $resource_selector=<<RESOURCE_SELECTOR; 2233: <state name="SELECT_PROBLEMS" title="Select resources to print"> 2234: <nextstate>PRINT_FORMATTING</nextstate> 2235: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message> 2236: <resource variable="RESOURCES" multichoice="1" addstatus="1" 2237: closeallpages="1"> 2238: <filterfunc>return $isProblem;</filterfunc> 2239: <mapurl>$map</mapurl> 2240: <valuefunc>return $symbFilter;</valuefunc> 2241: <option text='New Page' variable='FINISHPAGE' /> 2242: </resource> 2243: </state> 2244: <state name="PRINT_FORMATTING" title="How should results be printed?"> 2245: <nextstate>NUMBER_PER_PDF</nextstate> 2246: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message> 2247: <choices variable="EMPTY_PAGES"> 2248: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice> 2249: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice> 2250: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice> 2251: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice> 2252: </choices> 2253: </state> 2254: <state name="NUMBER_PER_PDF" title="Number printed at once"> 2255: <nextstate>PAGESIZE</nextstate> 2256: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message> 2257: <choices variable="SPLIT_PDFS"> 2258: <choice computer="all">All assignments in a single PDF file</choice> 2259: <choice computer="sections">Each PDF contains exactly one section</choice> 2260: <choice computer="oneper">Each PDF contains exactly one assignment</choice> 2261: <choice computer="usenumber">Specify Number:</choice> 2262: </choices> 2263: <string variable="NUMBER_TO_PRINT" maxlength="5" size="5"><defaultvalue>"all"</defaultvalue></string> 2264: </state> 2265: RESOURCE_SELECTOR 2266: 2267: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS); 2268: <state name="CHOOSE_STUDENTS" title="Select Students and Resources"> 2269: <message><b>Select sort order</b> </message> 2270: <choices variable='student_sort'> 2271: <choice computer='0'>Sort by section then student</choice> 2272: <choice computer='1'>Sort by students across sections.</choice> 2273: </choices> 2274: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_PROBLEMS" coursepersonnel="1"/> 2275: </state> 2276: $resource_selector 2277: CHOOSE_STUDENTS 2278: 2279: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; 2280: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; 2281: my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum); 2282: my $namechoice='<choice></choice>'; 2283: foreach my $name (sort {uc($a) cmp uc($b)} @names) { 2284: if ($name =~ /^error: 2 /) { next; } 2285: if ($name =~ /^type\0/) { next; } 2286: $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>'; 2287: } 2288: 2289: 2290: my %code_values; 2291: my %codes_to_print; 2292: foreach my $key (@names) { 2293: %code_values = &Apache::grades::get_codes($key, $cdom, $cnum); 2294: foreach my $key (keys(%code_values)) { 2295: $codes_to_print{$key} = 1; 2296: } 2297: } 2298: 2299: my $code_selection = "<choice></choice>\n"; 2300: foreach my $code (sort {uc($a) cmp uc($b)} (keys(%codes_to_print))) { 2301: my $choice = $code; 2302: if ($code =~ /^[A-Z]+$/) { # Alpha code 2303: $choice = &letters_to_num($code); 2304: } 2305: $code_selection .= ' <choice computer="'.$choice.'">'.$code."</choice>\n"; 2306: } 2307: open(FH,$Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab'); 2308: my $codechoice=''; 2309: foreach my $line (<FH>) { 2310: my ($name,$description,$code_type,$code_length)= 2311: (split(/:/,$line))[0,1,2,4]; 2312: if ($code_length > 0 && 2313: $code_type =~/^(letter|number|-1)/) { 2314: $codechoice.='<choice computer="'.$name.'">'.$description.'</choice>'; 2315: } 2316: } 2317: if ($codechoice eq '') { 2318: $codechoice='<choice computer="default">Default</choice>'; 2319: } 2320: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1); 2321: <state name="CHOOSE_ANON1" title="Select Students and Resources"> 2322: <nextstate>SELECT_PROBLEMS</nextstate> 2323: <message><table><tr><td><b>Number of anonymous assignments to print:</b></td><td></message> 2324: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5"> 2325: <validator> 2326: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) && 2327: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} && 2328: !\$helper->{'VARS'}{'SINGLE_CODE'} && 2329: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) { 2330: return "You need to specify the number of assignments to print"; 2331: } 2332: return undef; 2333: </validator> 2334: </string> 2335: <message></td></tr><tr><td></message> 2336: <message><b>Names to store the CODEs under for later:</b></message> 2337: <message></td><td></message> 2338: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" /> 2339: <message></td></tr><tr><td></message> 2340: <message><b>Bubble sheet type:</b></message> 2341: <message></td><td></message> 2342: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0"> 2343: $codechoice 2344: </dropdown> 2345: <message></td></tr><tr><td colspan="2"><hr width='33%' /></td></tr><tr><td></message> 2346: <message></td></tr><tr><td></message> 2347: <message><b>Enter a CODE to print:</b></td><td></message> 2348: <string variable="SINGLE_CODE" size="10"> 2349: <validator> 2350: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} && 2351: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} && 2352: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) { 2353: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'}, 2354: \$helper->{'VARS'}{'CODE_OPTION'}); 2355: } else { 2356: return undef; # Other forces control us. 2357: } 2358: </validator> 2359: </string> 2360: <message></td></tr><tr><td colspan="2"><hr width='33%' /></td></tr><tr><td></message> 2361: <message><b>Reprint a set of saved CODEs:</b></message> 2362: <message></td><td></message> 2363: <dropdown variable="REUSE_OLD_CODES"> 2364: $namechoice 2365: </dropdown> 2366: <message></td></tr></table></message> 2367: <message><hr width='33%' /></message> 2368: </state> 2369: $resource_selector 2370: CHOOSE_ANON1 2371: 2372: 2373: if ($helper->{VARS}->{'assignment'}) { 2374: push @{$printChoices}, ["<b>".&mt('Resources')."</b> ".&mt('from')." <b><i>$sequenceTitle</i></b> ".&mt('for')." <b>".&mt('selected students')."</b>", 'resources_for_students', 'CHOOSE_STUDENTS1']; 2375: push @{$printChoices}, ["<b>".&mt('Resources')."</b> ".&mt('from')." <b><i>$sequenceTitle</i></b> ".&mt('for')." <b>".&mt('anonymous students')."</b>", 'resources_for_anon', 'CHOOSE_ANON2']; 2376: } 2377: 2378: 2379: $resource_selector=<<RESOURCE_SELECTOR; 2380: <state name="SELECT_RESOURCES" title="Select Resources"> 2381: <nextstate>PRINT_FORMATTING</nextstate> 2382: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message> 2383: <resource variable="RESOURCES" multichoice="1" addstatus="1" 2384: closeallpages="1"> 2385: <filterfunc>return $isNotMap;</filterfunc> 2386: <mapurl>$map</mapurl> 2387: <valuefunc>return $symbFilter;</valuefunc> 2388: <option text='Newpage' variable='FINISHPAGE' /> 2389: </resource> 2390: </state> 2391: <state name="PRINT_FORMATTING" title="Format of the print job"> 2392: <nextstate>NUMBER_PER_PDF</nextstate> 2393: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message> 2394: <choices variable="EMPTY_PAGES"> 2395: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice> 2396: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice> 2397: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice> 2398: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice> 2399: </choices> 2400: </state> 2401: <state name="NUMBER_PER_PDF" title="Number assignments per pdf"> 2402: <nextstate>PAGESIZE</nextstate> 2403: <message><hr width='33%' /><b>How do you want assignments split into PDF files? </b></message> 2404: <choices variable="SPLIT_PDFS"> 2405: <choice computer="all">All assignments in a single PDF file</choice> 2406: <choice computer="sections">Each PDF contains exactly one section</choice> 2407: <choice computer="oneper">Each PDF contains exactly one assignment</choice> 2408: <choice computer="usenumber">Specify Number:</choice> 2409: </choices> 2410: <string variable="NUMBER_TO_PRINT" maxlength="5" size="5"><defaultvalue>"all"</defaultvalue></string> 2411: </state> 2412: RESOURCE_SELECTOR 2413: 2414: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1); 2415: <state name="CHOOSE_STUDENTS1" title="Select Students and Resources"> 2416: <choices variable='student_sort'> 2417: <choice computer='0'>Sort by section then student</choice> 2418: <choice computer='1'>Sort by students across sections.</choice> 2419: </choices> 2420: <student multichoice='1' variable="STUDENTS" nextstate="SELECT_RESOURCES" coursepersonnel="1" /> 2421: 2422: </state> 2423: $resource_selector 2424: CHOOSE_STUDENTS1 2425: 2426: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2); 2427: <state name="CHOOSE_ANON2" title="Select Students and Resources"> 2428: <nextstate>SELECT_RESOURCES</nextstate> 2429: <message><table><tr><td><b>Number of anonymous assignments to print:</b></td><td></message> 2430: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5"> 2431: <validator> 2432: if (((\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'}+0) < 1) && 2433: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} && 2434: !\$helper->{'VARS'}{'SINGLE_CODE'} && 2435: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) { 2436: return "You need to specify the number of assignments to print"; 2437: } 2438: return undef; 2439: </validator> 2440: </string> 2441: <message></td></tr><tr><td></message> 2442: <message><b>Names to store the CODEs under for later:</b></message> 2443: <message></td><td></message> 2444: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" /> 2445: <message></td></tr><tr><td></message> 2446: <message><b>Bubble sheet type:</b></message> 2447: <message></td><td></message> 2448: <dropdown variable="CODE_OPTION" multichoice="0" allowempty="0"> 2449: $codechoice 2450: </dropdown> 2451: <message></td></tr><tr><td colspan="2"><hr width='33%' /></td></tr><tr><td></message> 2452: <message></td></tr><tr><td></message> 2453: <message><b>Enter a CODE to print:</b></td><td></message> 2454: <string variable="SINGLE_CODE" size="10"> 2455: <validator> 2456: if(!\$helper->{'VARS'}{'NUMBER_TO_PRINT_TOTAL'} && 2457: !\$helper->{'VARS'}{'REUSE_OLD_CODES'} && 2458: !\$helper->{'VARS'}{'CODE_SELECTED_FROM_LIST'}) { 2459: return &Apache::lonprintout::is_code_valid(\$helper->{'VARS'}{'SINGLE_CODE'}, 2460: \$helper->{'VARS'}{'CODE_OPTION'}); 2461: } else { 2462: return undef; # Other forces control us. 2463: } 2464: </validator> 2465: </string> 2466: <message></td></tr><tr><td colspan="2"><hr width='33%' /></td></tr><tr><td></message> 2467: <message><b>Reprint a set of saved CODEs:</b></message> 2468: <message></td><td></message> 2469: <dropdown variable="REUSE_OLD_CODES"> 2470: $namechoice 2471: </dropdown> 2472: <message></td></tr></table></message> 2473: <message><hr width='33%' /></message> 2474: </state> 2475: $resource_selector 2476: CHOOSE_ANON2 2477: } 2478: 2479: # FIXME: That RE should come from a library somewhere. 2480: if ((((&Apache::lonnet::allowed('bre',$subdir) eq 'F') and ($helper->{VARS}->{'postdata'}=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)/)) or defined $helper->{'VARS'}->{'construction'}) and $perm{'pav'} and $subdir ne $Apache::lonnet::perlvar{'lonDocRoot'}.'/res/') { 2481: push @{$printChoices}, ["<b>".&mt('Problems')."</b> ".&mt('from current subdirectory')." <b><i>$subdir</i></b>", 'problems_from_directory', 'CHOOSE_FROM_SUBDIR']; 2482: 2483: my $f = '$filename'; 2484: my $xmlfrag = <<CHOOSE_FROM_SUBDIR; 2485: <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$subdir</small></b> to print"> 2486: <message>(mark them then click "next" button) <br /></message> 2487: <files variable="FILES" multichoice='1'> 2488: <nextstate>PAGESIZE</nextstate> 2489: <filechoice>return '$subdir';</filechoice> 2490: CHOOSE_FROM_SUBDIR 2491: 2492: # this is broken up because I really want interpolation above, 2493: # and I really DON'T want it below 2494: $xmlfrag .= <<'CHOOSE_FROM_SUBDIR'; 2495: <filefilter>return Apache::lonhelper::files::not_old_version($filename) && 2496: $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/; 2497: </filefilter> 2498: </files> 2499: </state> 2500: CHOOSE_FROM_SUBDIR 2501: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag); 2502: } 2503: 2504: # Allow the user to select any sequence in the course, feed it to 2505: # another resource selector for that sequence 2506: if (!$helper->{VARS}->{'construction'}) { 2507: push @$printChoices, ["<b>Resources</b> from <b>selected sequence</b> in course", 2508: 'select_sequences', 'CHOOSE_SEQUENCE']; 2509: my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'}; 2510: #Escape apostrophes and backslashes for Perl 2511: $escapedSequenceName =~ s/\\/\\\\/g; 2512: $escapedSequenceName =~ s/'/\\'/g; 2513: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE); 2514: <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From"> 2515: <message>Select the sequence to print resources from:</message> 2516: <resource variable="SEQUENCE"> 2517: <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate> 2518: <filterfunc>return \$res->is_sequence;</filterfunc> 2519: <valuefunc>return $urlValue;</valuefunc> 2520: <choicefunc>return \$res->hasResource(\$res,sub { return !\$_[0]->is_sequence() },0,0); 2521: </choicefunc> 2522: </resource> 2523: </state> 2524: <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print"> 2525: <message>(mark desired resources then click "next" button) <br /></message> 2526: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1" 2527: closeallpages="1"> 2528: <nextstate>PAGESIZE</nextstate> 2529: <filterfunc>return $isProblem</filterfunc> 2530: <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl> 2531: <valuefunc>return $symbFilter;</valuefunc> 2532: <option text='Newpage' variable='FINISHPAGE' /> 2533: </resource> 2534: </state> 2535: CHOOSE_FROM_ANY_SEQUENCE 2536: } 2537: 2538: # Generate the first state, to select which resources get printed. 2539: Apache::lonhelper::state->new("START", "Select Printing Options:"); 2540: $paramHash = Apache::lonhelper::getParamHash(); 2541: $paramHash->{MESSAGE_TEXT} = ""; 2542: Apache::lonhelper::message->new(); 2543: $paramHash = Apache::lonhelper::getParamHash(); 2544: $paramHash->{'variable'} = 'PRINT_TYPE'; 2545: $paramHash->{CHOICES} = $printChoices; 2546: Apache::lonhelper::choices->new(); 2547: 2548: my $startedTable = 0; # have we started an HTML table yet? (need 2549: # to close it later) 2550: 2551: if (($perm{'pav'} and &Apache::lonnet::allowed('vgr',$env{'request.course.id'})) or 2552: ($helper->{VARS}->{'construction'} eq '1')) { 2553: addMessage("<hr width='33%' /><table><tr><td align='right'>Print: </td><td>"); 2554: $paramHash = Apache::lonhelper::getParamHash(); 2555: $paramHash->{'variable'} = 'ANSWER_TYPE'; 2556: $helper->declareVar('ANSWER_TYPE'); 2557: $paramHash->{CHOICES} = [ 2558: ['Without Answers', 'yes'], 2559: ['With Answers', 'no'], 2560: ['Only Answers', 'only'] 2561: ]; 2562: Apache::lonhelper::dropdown->new(); 2563: addMessage("</td></tr>"); 2564: $startedTable = 1; 2565: } 2566: 2567: if ($perm{'pav'}) { 2568: if (!$startedTable) { 2569: addMessage("<hr width='33%' /><table><tr><td align='right'>LaTeX mode: </td><td>"); 2570: $startedTable = 1; 2571: } else { 2572: addMessage("<tr><td align='right'>LaTeX mode: </td><td>"); 2573: } 2574: $paramHash = Apache::lonhelper::getParamHash(); 2575: $paramHash->{'variable'} = 'LATEX_TYPE'; 2576: $helper->declareVar('LATEX_TYPE'); 2577: if ($helper->{VARS}->{'construction'} eq '1') { 2578: $paramHash->{CHOICES} = [ 2579: ['standard LaTeX mode', 'standard'], 2580: ['LaTeX batchmode', 'batchmode'], ]; 2581: } else { 2582: $paramHash->{CHOICES} = [ 2583: ['LaTeX batchmode', 'batchmode'], 2584: ['standard LaTeX mode', 'standard'] ]; 2585: } 2586: Apache::lonhelper::dropdown->new(); 2587: 2588: addMessage("</td></tr><tr><td align='right'>Print Table of Contents: </td><td>"); 2589: $paramHash = Apache::lonhelper::getParamHash(); 2590: $paramHash->{'variable'} = 'TABLE_CONTENTS'; 2591: $helper->declareVar('TABLE_CONTENTS'); 2592: $paramHash->{CHOICES} = [ 2593: ['No', 'no'], 2594: ['Yes', 'yes'] ]; 2595: Apache::lonhelper::dropdown->new(); 2596: addMessage("</td></tr>"); 2597: 2598: if (not $helper->{VARS}->{'construction'}) { 2599: addMessage("<tr><td align='right'>Print Index: </td><td>"); 2600: $paramHash = Apache::lonhelper::getParamHash(); 2601: $paramHash->{'variable'} = 'TABLE_INDEX'; 2602: $helper->declareVar('TABLE_INDEX'); 2603: $paramHash->{CHOICES} = [ 2604: ['No', 'no'], 2605: ['Yes', 'yes'] ]; 2606: Apache::lonhelper::dropdown->new(); 2607: addMessage("</td></tr>"); 2608: addMessage("<tr><td align='right'>Print Discussions: </td><td>"); 2609: $paramHash = Apache::lonhelper::getParamHash(); 2610: $paramHash->{'variable'} = 'PRINT_DISCUSSIONS'; 2611: $helper->declareVar('PRINT_DISCUSSIONS'); 2612: $paramHash->{CHOICES} = [ 2613: ['No', 'no'], 2614: ['Yes', 'yes'] ]; 2615: Apache::lonhelper::dropdown->new(); 2616: addMessage("</td></tr>"); 2617: 2618: addMessage("<tr><td align = 'right'> </td><td>"); 2619: $paramHash = Apache::lonhelper::getParamHash(); 2620: $paramHash->{'multichoice'} = "true"; 2621: $paramHash->{'allowempty'} = "true"; 2622: $paramHash->{'variable'} = "showallfoils"; 2623: $paramHash->{'CHOICES'} = [ ["Show all foils", "1"] ]; 2624: Apache::lonhelper::choices->new(); 2625: addMessage("</td></tr>"); 2626: } 2627: 2628: if ($helper->{'VARS'}->{'construction'}) { 2629: my $stylevalue=$env{'construct.style'}; 2630: my $xmlfrag .= <<"RNDSEED"; 2631: <message><tr><td align='right'>Use random seed: </td><td></message> 2632: <string variable="curseed" size="15" maxlength="15"> 2633: <defaultvalue> 2634: return $helper->{VARS}->{'curseed'}; 2635: </defaultvalue> 2636: </string> 2637: <message></td></tr><tr><td align="right">Use style file:</td><td></message> 2638: <message><input type="text" size="40" name="style_file_value" value="$stylevalue" /> <a href="javascript:openbrowser('helpform','style_file_value','sty')">Select style file</a> </td><tr><td></message> 2639: <choices allowempty="1" multichoice="true" variable="showallfoils"> 2640: <choice computer="1">Show all foils?</choice> 2641: </choices> 2642: <message></td></tr></message> 2643: RNDSEED 2644: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag); 2645: $helper->{'VARS'}->{'style_file'}=$env{'form.style_file_value'}; 2646: 2647: } 2648: } 2649: 2650: 2651: 2652: 2653: if ($startedTable) { 2654: addMessage("</table>"); 2655: } 2656: 2657: Apache::lonprintout::page_format_state->new("FORMAT"); 2658: 2659: # Generate the PAGESIZE state which will offer the user the margin 2660: # choices if they select one column 2661: Apache::lonhelper::state->new("PAGESIZE", "Set Margins"); 2662: Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL'); 2663: 2664: 2665: $helper->process(); 2666: 2667: 2668: # MANUAL BAILOUT CONDITION: 2669: # If we're in the "final" state, bailout and return to handler 2670: if ($helper->{STATE} eq 'FINAL') { 2671: return $helper; 2672: } 2673: 2674: $r->print($helper->display()); 2675: if ($helper->{STATE} eq 'START') { 2676: &recently_generated($r); 2677: } 2678: &Apache::lonhelper::unregisterHelperTags(); 2679: 2680: return OK; 2681: } 2682: 2683: 2684: 1; 2685: 2686: package Apache::lonprintout::page_format_state; 2687: 2688: =pod 2689: 2690: =head1 Helper element: page_format_state 2691: 2692: See lonhelper.pm documentation for discussion of the helper framework. 2693: 2694: Apache::lonprintout::page_format_state is an element that gives the 2695: user an opportunity to select the page layout they wish to print 2696: with: Number of columns, portrait/landscape, and paper size. If you 2697: want to change the paper size choices, change the @paperSize array 2698: contents in this package. 2699: 2700: page_format_state is always directly invoked in lonprintout.pm, so there 2701: is no tag interface. You actually pass parameters to the constructor. 2702: 2703: =over 4 2704: 2705: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME. 2706: 2707: =back 2708: 2709: =cut 2710: 2711: use Apache::lonhelper; 2712: 2713: no strict; 2714: @ISA = ("Apache::lonhelper::element"); 2715: use strict; 2716: use Apache::lonlocal; 2717: use Apache::lonnet; 2718: 2719: my $maxColumns = 2; 2720: # it'd be nice if these all worked 2721: #my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 2722: # "tabloid (ledger) [11x17 in]", "executive [7 1/2x10 in]", 2723: # "a2 [420x594 mm]", "a3 [297x420 mm]", "a4 [210x297 mm]", 2724: # "a5 [148x210 mm]", "a6 [105x148 mm]" ); 2725: my @paperSize = ("letter [8 1/2x11 in]", "legal [8 1/2x14 in]", 2726: "a4 [210x297 mm]"); 2727: 2728: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum | 2729: # Paper type 2730: 2731: sub new { 2732: my $self = Apache::lonhelper::element->new(); 2733: 2734: shift; 2735: 2736: $self->{'variable'} = shift; 2737: my $helper = Apache::lonhelper::getHelper(); 2738: $helper->declareVar($self->{'variable'}); 2739: bless($self); 2740: return $self; 2741: } 2742: 2743: sub render { 2744: my $self = shift; 2745: my $helper = Apache::lonhelper::getHelper(); 2746: my $result = ''; 2747: my $var = $self->{'variable'}; 2748: my $PageLayout=&mt('Page layout'); 2749: my $NumberOfColumns=&mt('Number of columns'); 2750: my $PaperType=&mt('Paper type'); 2751: $result .= <<STATEHTML; 2752: 2753: <hr width="33%" /> 2754: <table cellpadding="3"> 2755: <tr> 2756: <td align="center"><b>$PageLayout</b></td> 2757: <td align="center"><b>$NumberOfColumns</b></td> 2758: <td align="center"><b>$PaperType</b></td> 2759: </tr> 2760: <tr> 2761: <td> 2762: <label><input type="radio" name="${var}.layout" value="L" /> Landscape </label><br /> 2763: <label><input type="radio" name="${var}.layout" value="P" checked='1' /> Portrait </label> 2764: </td> 2765: <td align="center"> 2766: <select name="${var}.cols"> 2767: STATEHTML 2768: 2769: my $i; 2770: for ($i = 1; $i <= $maxColumns; $i++) { 2771: if ($i == 2) { 2772: $result .= "<option value='$i' selected>$i</option>\n"; 2773: } else { 2774: $result .= "<option value='$i'>$i</option>\n"; 2775: } 2776: } 2777: 2778: $result .= "</select></td><td>\n"; 2779: $result .= "<select name='${var}.paper'>\n"; 2780: 2781: my %parmhash=&Apache::lonnet::coursedescription($env{'request.course.id'}); 2782: my $DefaultPaperSize=lc($parmhash{'default_paper_size'}); 2783: $DefaultPaperSize=~s/\s//g; 2784: if ($DefaultPaperSize eq '') {$DefaultPaperSize='letter';} 2785: $i = 0; 2786: foreach (@paperSize) { 2787: $_=~/(\w+)/; 2788: my $papersize=$1; 2789: if ($paperSize[$i]=~/$DefaultPaperSize/) { 2790: $result .= "<option selected value='$papersize'>" . $paperSize[$i] . "</option>\n"; 2791: } else { 2792: $result .= "<option value='$papersize'>" . $paperSize[$i] . "</option>\n"; 2793: } 2794: $i++; 2795: } 2796: $result .= "</select></td></tr></table>"; 2797: return $result; 2798: } 2799: 2800: sub postprocess { 2801: my $self = shift; 2802: 2803: my $var = $self->{'variable'}; 2804: my $helper = Apache::lonhelper->getHelper(); 2805: $helper->{VARS}->{$var} = 2806: $env{"form.$var.layout"} . '|' . $env{"form.$var.cols"} . '|' . 2807: $env{"form.$var.paper"}; 2808: return 1; 2809: } 2810: 2811: 1; 2812: 2813: package Apache::lonprintout::page_size_state; 2814: 2815: =pod 2816: 2817: =head1 Helper element: page_size_state 2818: 2819: See lonhelper.pm documentation for discussion of the helper framework. 2820: 2821: Apache::lonprintout::page_size_state is an element that gives the 2822: user the opportunity to further refine the page settings if they 2823: select a single-column page. 2824: 2825: page_size_state is always directly invoked in lonprintout.pm, so there 2826: is no tag interface. You actually pass parameters to the constructor. 2827: 2828: =over 4 2829: 2830: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME. 2831: 2832: =back 2833: 2834: =cut 2835: 2836: use Apache::lonhelper; 2837: use Apache::lonnet; 2838: no strict; 2839: @ISA = ("Apache::lonhelper::element"); 2840: use strict; 2841: 2842: 2843: 2844: sub new { 2845: my $self = Apache::lonhelper::element->new(); 2846: 2847: shift; # disturbs me (probably prevents subclassing) but works (drops 2848: # package descriptor)... - Jeremy 2849: 2850: $self->{'variable'} = shift; 2851: my $helper = Apache::lonhelper::getHelper(); 2852: $helper->declareVar($self->{'variable'}); 2853: 2854: # The variable name of the format element, so we can look into 2855: # $helper->{VARS} to figure out whether the columns are one or two 2856: $self->{'formatvar'} = shift; 2857: 2858: # The state to transition to after selection, or after discovering 2859: # the cols are not set to 1 2860: $self->{NEXTSTATE} = shift; 2861: bless($self); 2862: return $self; 2863: } 2864: 2865: sub render { 2866: my $self = shift; 2867: my $helper = Apache::lonhelper::getHelper(); 2868: my $result = ''; 2869: my $var = $self->{'variable'}; 2870: 2871: if (defined $self->{ERROR_MSG}) { 2872: $result .= '<br /><font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br />'; 2873: } 2874: 2875: $result .= <<ELEMENTHTML; 2876: 2877: <p>How should the column be formatted?</p> 2878: 2879: <table cellpadding='3'> 2880: <tr> 2881: <td align='right'><b>Width</b>:</td> 2882: <td align='left'><input type='text' name='$var.width' value='18' size='4'></td> 2883: <td align='left'> 2884: <select name='$var.widthunit'> 2885: <option>cm</option><option>in</option> 2886: </select> 2887: </td> 2888: </tr> 2889: <tr> 2890: <td align='right'><b>Height</b>:</td> 2891: <td align='left'><input type='text' name="$var.height" value="25.9" size='4'></td> 2892: <td align='left'> 2893: <select name='$var.heightunit'> 2894: <option>cm</option><option>in</option> 2895: </select> 2896: </td> 2897: </tr> 2898: <tr> 2899: <td align='right'><b>Left margin</b>:</td> 2900: <td align='left'><input type='text' name='$var.lmargin' value='-1.5' size='4'></td> 2901: <td align='left'> 2902: <select name='$var.lmarginunit'> 2903: <option>cm</option><option>in</option> 2904: </select> 2905: </td> 2906: </tr> 2907: </table> 2908: 2909: <p>Hint: Some instructors like to leave scratch space for the student by 2910: making the width much smaller than the width of the page.</p> 2911: 2912: ELEMENTHTML 2913: 2914: return $result; 2915: } 2916: 2917: # If the user didn't select 1 column, skip this state. 2918: sub preprocess { 2919: my $self = shift; 2920: my $helper = Apache::lonhelper::getHelper(); 2921: 2922: my $format = $helper->{VARS}->{$self->{'formatvar'}}; 2923: if (substr($format, 2, 1) ne '1') { 2924: $helper->changeState($self->{NEXTSTATE}); 2925: } 2926: 2927: return 1; 2928: } 2929: 2930: sub postprocess { 2931: my $self = shift; 2932: 2933: my $var = $self->{'variable'}; 2934: my $helper = Apache::lonhelper->getHelper(); 2935: my $width = $helper->{VARS}->{$var .'.width'} = $env{"form.${var}.width"}; 2936: my $height = $helper->{VARS}->{$var .'.height'} = $env{"form.${var}.height"}; 2937: my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $env{"form.${var}.lmargin"}; 2938: $helper->{VARS}->{$var .'.widthunit'} = $env{"form.${var}.widthunit"}; 2939: $helper->{VARS}->{$var .'.heightunit'} = $env{"form.${var}.heightunit"}; 2940: $helper->{VARS}->{$var .'.lmarginunit'} = $env{"form.${var}.lmarginunit"}; 2941: 2942: my $error = ''; 2943: 2944: # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed 2945: # by an optional period, followed by digits, ending the string 2946: 2947: if ($width !~ /^-?[0-9]+(\.[0-9]*)?$/) { 2948: $error .= "Invalid width; please type only a number.<br />\n"; 2949: } 2950: if ($height !~ /^-?[0-9]+(\.[0-9]*)?$/) { 2951: $error .= "Invalid height; please type only a number.<br />\n"; 2952: } 2953: if ($lmargin !~ /^-?[0-9]+(\.[0-9]*)?$/) { 2954: $error .= "Invalid left margin; please type only a number.<br />\n"; 2955: } 2956: 2957: if (!$error) { 2958: Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE}); 2959: return 1; 2960: } else { 2961: $self->{ERROR_MSG} = $error; 2962: return 0; 2963: } 2964: } 2965: 2966: 2967: 2968: __END__ 2969: