![]() ![]() | ![]() |
- need to pad the number with leading zeros
1: # The LearningOnline Network 2: # Printout 3: # 4: # $Id: lonprintout.pm,v 1.293 2004/04/22 22:59:11 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 GDBM_File; 45: 46: 47: my %hash; 48: my $LaTeXwidth = 0; 49: 50: 51: sub latex_header_footer_remove { 52: my $text = shift; 53: $text =~ s/\\end{document}//; 54: $text =~ s/\\documentclass([^&]*)\\begin{document}//; 55: return $text; 56: } 57: 58: 59: sub character_chart { 60: my $result = shift; 61: $result =~ s/&\#0?0?(7|9);//g; 62: $result =~ s/&\#0?(10|13);//g; 63: $result =~ s/&\#0?32;/ /g; 64: $result =~ s/&\#0?33;/!/g; 65: $result =~ s/&(\#0?34|quot);/\"/g; 66: $result =~ s/&\#0?35;/\\\#/g; 67: $result =~ s/&\#0?36;/\\\$/g; 68: $result =~ s/&\#0?37;/\\%/g; 69: $result =~ s/&(\#0?38|amp);/\\&/g; 70: $result =~ s/&\#(0?39|146);/\'/g; 71: $result =~ s/&\#0?40;/(/g; 72: $result =~ s/&\#0?41;/)/g; 73: $result =~ s/&\#0?42;/\*/g; 74: $result =~ s/&\#0?43;/\+/g; 75: $result =~ s/&\#(0?44|130);/,/g; 76: $result =~ s/&\#0?45;/-/g; 77: $result =~ s/&\#0?46;/\./g; 78: $result =~ s/&\#0?47;/\//g; 79: $result =~ s/&\#0?48;/0/g; 80: $result =~ s/&\#0?49;/1/g; 81: $result =~ s/&\#0?50;/2/g; 82: $result =~ s/&\#0?51;/3/g; 83: $result =~ s/&\#0?52;/4/g; 84: $result =~ s/&\#0?53;/5/g; 85: $result =~ s/&\#0?54;/6/g; 86: $result =~ s/&\#0?55;/7/g; 87: $result =~ s/&\#0?56;/8/g; 88: $result =~ s/&\#0?57;/9/g; 89: $result =~ s/&\#0?58;/:/g; 90: $result =~ s/&\#0?59;/;/g; 91: $result =~ s/&(\#0?60|lt|\#139);/\$<\$/g; 92: $result =~ s/&\#0?61;/\\ensuremath\{=\}/g; 93: $result =~ s/&(\#0?62|gt|\#155);/\\ensuremath\{>\}/g; 94: $result =~ s/&\#0?63;/\?/g; 95: $result =~ s/&\#0?65;/A/g; 96: $result =~ s/&\#0?66;/B/g; 97: $result =~ s/&\#0?67;/C/g; 98: $result =~ s/&\#0?68;/D/g; 99: $result =~ s/&\#0?69;/E/g; 100: $result =~ s/&\#0?70;/F/g; 101: $result =~ s/&\#0?71;/G/g; 102: $result =~ s/&\#0?72;/H/g; 103: $result =~ s/&\#0?73;/I/g; 104: $result =~ s/&\#0?74;/J/g; 105: $result =~ s/&\#0?75;/K/g; 106: $result =~ s/&\#0?76;/L/g; 107: $result =~ s/&\#0?77;/M/g; 108: $result =~ s/&\#0?78;/N/g; 109: $result =~ s/&\#0?79;/O/g; 110: $result =~ s/&\#0?80;/P/g; 111: $result =~ s/&\#0?81;/Q/g; 112: $result =~ s/&\#0?82;/R/g; 113: $result =~ s/&\#0?83;/S/g; 114: $result =~ s/&\#0?84;/T/g; 115: $result =~ s/&\#0?85;/U/g; 116: $result =~ s/&\#0?86;/V/g; 117: $result =~ s/&\#0?87;/W/g; 118: $result =~ s/&\#0?88;/X/g; 119: $result =~ s/&\#0?89;/Y/g; 120: $result =~ s/&\#0?90;/Z/g; 121: $result =~ s/&\#0?91;/[/g; 122: $result =~ s/&\#0?92;/\\ensuremath\{\\setminus\}/g; 123: $result =~ s/&\#0?93;/]/g; 124: $result =~ s/&\#(0?94|136);/\\ensuremath\{\\wedge\}/g; 125: $result =~ s/&\#(0?95|138|154);/\\underline{\\makebox[2mm]{\\strut}}/g; 126: $result =~ s/&\#(0?96|145);/\`/g; 127: $result =~ s/&\#0?97;/a/g; 128: $result =~ s/&\#0?98;/b/g; 129: $result =~ s/&\#0?99;/c/g; 130: $result =~ s/&\#100;/d/g; 131: $result =~ s/&\#101;/e/g; 132: $result =~ s/&\#102;/f/g; 133: $result =~ s/&\#103;/g/g; 134: $result =~ s/&\#104;/h/g; 135: $result =~ s/&\#105;/i/g; 136: $result =~ s/&\#106;/j/g; 137: $result =~ s/&\#107;/k/g; 138: $result =~ s/&\#108;/l/g; 139: $result =~ s/&\#109;/m/g; 140: $result =~ s/&\#110;/n/g; 141: $result =~ s/&\#111;/o/g; 142: $result =~ s/&\#112;/p/g; 143: $result =~ s/&\#113;/q/g; 144: $result =~ s/&\#114;/r/g; 145: $result =~ s/&\#115;/s/g; 146: $result =~ s/&\#116;/t/g; 147: $result =~ s/&\#117;/u/g; 148: $result =~ s/&\#118;/v/g; 149: $result =~ s/&\#119;/w/g; 150: $result =~ s/&\#120;/x/g; 151: $result =~ s/&\#121;/y/g; 152: $result =~ s/&\#122;/z/g; 153: $result =~ s/&\#123;/\\{/g; 154: $result =~ s/&\#124;/\|/g; 155: $result =~ s/&\#125;/\\}/g; 156: $result =~ s/&\#126;/\~/g; 157: $result =~ s/&\#131;/\\textflorin /g; 158: $result =~ s/&\#132;/\"/g; 159: $result =~ s/&\#133;/\\ensuremath\{\\ldots\}/g; 160: $result =~ s/&\#134;/\\ensuremath\{\\dagger\}/g; 161: $result =~ s/&\#135;/\\ensuremath\{\\ddagger\}/g; 162: $result =~ s/&\#137;/\\textperthousand /g; 163: $result =~ s/&\#140;/{\\OE}/g; 164: $result =~ s/&\#147;/\`\`/g; 165: $result =~ s/&\#148;/\'\'/g; 166: $result =~ s/&\#149;/\\ensuremath\{\\bullet\}/g; 167: $result =~ s/&\#150;/--/g; 168: $result =~ s/&\#151;/---/g; 169: $result =~ s/&\#152;/\\ensuremath\{\\sim\}/g; 170: $result =~ s/&\#153;/\\texttrademark /g; 171: $result =~ s/&\#156;/\\oe/g; 172: $result =~ s/&\#159;/\\\"Y/g; 173: $result =~ s/&(\#160|nbsp);/~/g; 174: $result =~ s/&(\#161|iexcl);/!\`/g; 175: $result =~ s/&(\#162|cent);/\\textcent /g; 176: $result =~ s/&(\#163|pound);/\\pounds /g; 177: $result =~ s/&(\#164|curren);/\\textcurrency /g; 178: $result =~ s/&(\#165|yen);/\\textyen /g; 179: $result =~ s/&(\#166|brvbar);/\\textbrokenbar /g; 180: $result =~ s/&(\#167|sect);/\\textsection /g; 181: $result =~ s/&(\#168|uml);/\\texthighdieresis /g; 182: $result =~ s/&(\#169|copy);/\\copyright /g; 183: $result =~ s/&(\#170|ordf);/\\textordfeminine /g; 184: $result =~ s/&(\#172|not);/\\ensuremath\{\\neg\}/g; 185: $result =~ s/&(\#173|shy);/ - /g; 186: $result =~ s/&(\#174|reg);/\\textregistered /g; 187: $result =~ s/&(\#175|macr);/\\ensuremath\{^{-}\}/g; 188: $result =~ s/&(\#176|deg);/\\ensuremath\{^{\\circ}\}/g; 189: $result =~ s/&(\#177|plusmn);/\\ensuremath\{\\pm\}/g; 190: $result =~ s/&(\#178|sup2);/\\ensuremath\{^2\}/g; 191: $result =~ s/&(\#179|sup3);/\\ensuremath\{^3\}/g; 192: $result =~ s/&(\#180|acute);/\\textacute /g; 193: $result =~ s/&(\#181|micro);/\\ensuremath\{\\mu\}/g; 194: $result =~ s/&(\#182|para);/\\P/g; 195: $result =~ s/&(\#183|middot);/\\ensuremath\{\\cdot\}/g; 196: $result =~ s/&(\#184|cedil);/\\c{\\strut}/g; 197: $result =~ s/&(\#185|sup1);/\\ensuremath\{^1\}/g; 198: $result =~ s/&(\#186|ordm);/\\textordmasculine /g; 199: $result =~ s/&(\#188|frac14);/\\textonequarter /g; 200: $result =~ s/&(\#189|frac12);/\\textonehalf /g; 201: $result =~ s/&(\#190|frac34);/\\textthreequarters /g; 202: $result =~ s/&(\#191|iquest);/?\`/g; 203: $result =~ s/&(\#192|Agrave);/\\\`{A}/g; 204: $result =~ s/&(\#193|Aacute);/\\\'{A}/g; 205: $result =~ s/&(\#194|Acirc);/\\^{A}/g; 206: $result =~ s/&(\#195|Atilde);/\\~{A}/g; 207: $result =~ s/&(\#196|Auml);/\\\"{A}/g; 208: $result =~ s/&(\#197|Aring);/{\\AA}/g; 209: $result =~ s/&(\#198|AElig);/{\\AE}/g; 210: $result =~ s/&(\#199|Ccedil);/\\c{c}/g; 211: $result =~ s/&(\#200|Egrave);/\\\`{E}/g; 212: $result =~ s/&(\#201|Eacute);/\\\'{E}/g; 213: $result =~ s/&(\#202|Ecirc);/\\^{E}/g; 214: $result =~ s/&(\#203|Euml);/\\\"{E}/g; 215: $result =~ s/&(\#204|Igrave);/\\\`{I}/g; 216: $result =~ s/&(\#205|Iacute);/\\\'{I}/g; 217: $result =~ s/&(\#206|Icirc);/\\^{I}/g; 218: $result =~ s/&(\#207|Iuml);/\\\"{I}/g; 219: $result =~ s/&(\#209|Ntilde);/\\~{N}/g; 220: $result =~ s/&(\#210|Ograve);/\\\`{O}/g; 221: $result =~ s/&(\#211|Oacute);/\\\'{O}/g; 222: $result =~ s/&(\#212|Ocirc);/\\^{O}/g; 223: $result =~ s/&(\#213|Otilde);/\\~{O}/g; 224: $result =~ s/&(\#214|Ouml);/\\\"{O}/g; 225: $result =~ s/&(\#215|times);/\\ensuremath\{\\times\}/g; 226: $result =~ s/&(\#216|Oslash);/{\\O}/g; 227: $result =~ s/&(\#217|Ugrave);/\\\`{U}/g; 228: $result =~ s/&(\#218|Uacute);/\\\'{U}/g; 229: $result =~ s/&(\#219|Ucirc);/\\^{U}/g; 230: $result =~ s/&(\#220|Uuml);/\\\"{U}/g; 231: $result =~ s/&(\#221|Yacute);/\\\'{Y}/g; 232: $result =~ s/&(\#223|szlig);/\\ss/g; 233: $result =~ s/&(\#224|agrave);/\\\`{a}/g; 234: $result =~ s/&(\#225|aacute);/\\\'{a}/g; 235: $result =~ s/&(\#226|acirc);/\\^{a}/g; 236: $result =~ s/&(\#227|atilde);/\\~{a}/g; 237: $result =~ s/&(\#228|auml);/\\\"{a}/g; 238: $result =~ s/&(\#229|aring);/{\\aa}/g; 239: $result =~ s/&(\#230|aelig);/{\\ae}/g; 240: $result =~ s/&(\#231|ccedil);/\\c{c}/g; 241: $result =~ s/&(\#232|egrave);/\\\`{e}/g; 242: $result =~ s/&(\#233|eacute);/\\\'{e}/g; 243: $result =~ s/&(\#234|ecirc);/\\^{e}/g; 244: $result =~ s/&(\#235|euml);/\\\"{e}/g; 245: $result =~ s/&(\#236|igrave);/\\\`{i}/g; 246: $result =~ s/&(\#237|iacute);/\\\'{i}/g; 247: $result =~ s/&(\#238|icirc);/\\^{i}/g; 248: $result =~ s/&(\#239|iuml);/\\\"{i}/g; 249: $result =~ s/&(\#240|eth);/\\ensuremath\{\\partial\}/g; 250: $result =~ s/&(\#241|ntilde);/\\~{n}/g; 251: $result =~ s/&(\#242|ograve);/\\\`{o}/g; 252: $result =~ s/&(\#243|oacute);/\\\'{o}/g; 253: $result =~ s/&(\#244|ocirc);/\\^{o}/g; 254: $result =~ s/&(\#245|otilde);/\\~{o}/g; 255: $result =~ s/&(\#246|ouml);/\\\"{o}/g; 256: $result =~ s/&(\#247|divide);/\\ensuremath\{\\div\}/g; 257: $result =~ s/&(\#248|oslash);/{\\o}/g; 258: $result =~ s/&(\#249|ugrave);/\\\`{u}/g; 259: $result =~ s/&(\#250|uacute);/\\\'{u}/g; 260: $result =~ s/&(\#251|ucirc);/\\^{u}/g; 261: $result =~ s/&(\#252|uuml);/\\\"{u}/g; 262: $result =~ s/&(\#253|yacute);/\\\'{y}/g; 263: $result =~ s/&(\#255|yuml);/\\\"{y}/g; 264: $result =~ s/&\#952;/\\ensuremath\{\\theta\}/g; 265: #Greek Alphabet 266: $result =~ s/&(alpha|\#945);/\\ensuremath\{\\alpha\}/g; 267: $result =~ s/&(beta|\#946);/\\ensuremath\{\\beta\}/g; 268: $result =~ s/&(gamma|\#947);/\\ensuremath\{\\gamma\}/g; 269: $result =~ s/&(delta|\#948);/\\ensuremath\{\\delta\}/g; 270: $result =~ s/&(epsilon|\#949);/\\ensuremath\{\\epsilon\}/g; 271: $result =~ s/&(zeta|\#950);/\\ensuremath\{\\zeta\}/g; 272: $result =~ s/&(eta|\#951);/\\ensuremath\{\\eta\}/g; 273: $result =~ s/&(theta|\#952);/\\ensuremath\{\\theta\}/g; 274: $result =~ s/&(iota|\#953);/\\ensuremath\{\\iota\}/g; 275: $result =~ s/&(kappa|\#954);/\\ensuremath\{\\kappa\}/g; 276: $result =~ s/&(lambda|\#955);/\\ensuremath\{\\lambda\}/g; 277: $result =~ s/&(mu|\#956);/\\ensuremath\{\\mu\}/g; 278: $result =~ s/&(nu|\#957);/\\ensuremath\{\\nu\}/g; 279: $result =~ s/&(xi|\#958);/\\ensuremath\{\\xi\}/g; 280: $result =~ s/&(omicron|\#959);/o/g; 281: $result =~ s/&(pi|\#960);/\\ensuremath\{\\pi\}/g; 282: $result =~ s/&(rho|\#961);/\\ensuremath\{\\rho\}/g; 283: $result =~ s/&(sigma|\#963);/\\ensuremath\{\\sigma\}/g; 284: $result =~ s/&(tau|\#964);/\\ensuremath\{\\tau\}/g; 285: $result =~ s/&(upsilon|\#965);/\\ensuremath\{\\upsilon\}/g; 286: $result =~ s/&(phi|\#966);/\\ensuremath\{\\phi\}/g; 287: $result =~ s/&(chi|\#967);/\\ensuremath\{\\chi\}/g; 288: $result =~ s/&(psi|\#968);/\\ensuremath\{\\psi\}/g; 289: $result =~ s/&(omega|\#969);/\\ensuremath\{\\omega\}/g; 290: $result =~ s/&(thetasym|\#977);/\\ensuremath\{\\vartheta\}/g; 291: $result =~ s/&(piv|\#982);/\\ensuremath\{\\varpi\}/g; 292: $result =~ s/&(Alpha|\#913);/A/g; 293: $result =~ s/&(Beta|\#914);/B/g; 294: $result =~ s/&(Gamma|\#915);/\\ensuremath\{\\Gamma\}/g; 295: $result =~ s/&(Delta|\#916);/\\ensuremath\{\\Delta\}/g; 296: $result =~ s/&(Epsilon|\#917);/E/g; 297: $result =~ s/&(Zeta|\#918);/Z/g; 298: $result =~ s/&(Eta|\#919);/H/g; 299: $result =~ s/&(Theta|\#920);/\\ensuremath\{\\Theta\}/g; 300: $result =~ s/&(Iota|\#921);/I/g; 301: $result =~ s/&(Kappa|\#922);/K/g; 302: $result =~ s/&(Lambda|\#923);/\\ensuremath\{\\Lambda\}/g; 303: $result =~ s/&(Mu|\#924);/M/g; 304: $result =~ s/&(Nu|\#925);/N/g; 305: $result =~ s/&(Xi|\#926);/\\ensuremath\{\\Xi\}/g; 306: $result =~ s/&(Omicron|\#927);/O/g; 307: $result =~ s/&(Pi|\#928);/\\ensuremath\{\\Pi\}/g; 308: $result =~ s/&(Rho|\#929);/P/g; 309: $result =~ s/&(Sigma|\#931);/\\ensuremath\{\\Sigma\}/g; 310: $result =~ s/&(Tau|\#932);/T/g; 311: $result =~ s/&(Upsilon|\#933);/\\ensuremath\{\\Upsilon\}/g; 312: $result =~ s/&(Phi|\#934);/\\ensuremath\{\\Phi\}/g; 313: $result =~ s/&(Chi|\#935);/X/g; 314: $result =~ s/&(Psi|\#936);/\\ensuremath\{\\Psi\}/g; 315: $result =~ s/&(Omega|\#937);/\\ensuremath\{\\Omega\}/g; 316: #Arrows (extended HTML 4.01) 317: $result =~ s/&(larr|\#8592);/\\ensuremath\{\\leftarrow\}/g; 318: $result =~ s/&(uarr|\#8593);/\\ensuremath\{\\uparrow\}/g; 319: $result =~ s/&(rarr|\#8594);/\\ensuremath\{\\rightarrow\}/g; 320: $result =~ s/&(darr|\#8595);/\\ensuremath\{\\downarrow\}/g; 321: $result =~ s/&(harr|\#8596);/\\ensuremath\{\\leftrightarrow\}/g; 322: $result =~ s/&(lArr|\#8656);/\\ensuremath\{\\Leftarrow\}/g; 323: $result =~ s/&(uArr|\#8657);/\\ensuremath\{\\Uparrow\}/g; 324: $result =~ s/&(rArr|\#8658);/\\ensuremath\{\\Rightarrow\}/g; 325: $result =~ s/&(dArr|\#8659);/\\ensuremath\{\\Downarrow\}/g; 326: $result =~ s/&(hArr|\#8660);/\\ensuremath\{\\Leftrightarrow\}/g; 327: #Mathematical Operators (extended HTML 4.01) 328: $result =~ s/&(forall|\#8704);/\\ensuremath\{\\forall\}/g; 329: $result =~ s/&(part|\#8706);/\\ensuremath\{\\partial\}/g; 330: $result =~ s/&(exist|\#8707);/\\ensuremath\{\\exists\}/g; 331: $result =~ s/&(empty|\#8709);/\\ensuremath\{\\emptyset\}/g; 332: $result =~ s/&(nabla|\#8711);/\\ensuremath\{\\nabla\}/g; 333: $result =~ s/&(isin|\#8712);/\\ensuremath\{\\in\}/g; 334: $result =~ s/&(notin|\#8713);/\\ensuremath\{\\notin\}/g; 335: $result =~ s/&(ni|\#8715);/\\ensuremath\{\\ni\}/g; 336: $result =~ s/&(prod|\#8719);/\\ensuremath\{\\prod\}/g; 337: $result =~ s/&(sum|\#8721);/\\ensuremath\{\\sum\}/g; 338: $result =~ s/&(minus|\#8722);/\\ensuremath\{-\}/g; 339: $result =~ s/&(lowast|\#8727);/\\ensuremath\{*\}/g; 340: $result =~ s/&(radic|\#8730);/\\ensuremath\{\\surd\}/g; 341: $result =~ s/&(prop|\#8733);/\\ensuremath\{\\propto\}/g; 342: $result =~ s/&(infin|\#8734);/\\ensuremath\{\\infty\}/g; 343: $result =~ s/&(ang|\#8736);/\\ensuremath\{\\angle\}/g; 344: $result =~ s/&(and|\#8743);/\\ensuremath\{\\wedge\}/g; 345: $result =~ s/&(or|\#8744);/\\ensuremath\{\\vee\}/g; 346: $result =~ s/&(cap|\#8745);/\\ensuremath\{\\cap\}/g; 347: $result =~ s/&(cup|\#8746);/\\ensuremath\{\\cup\}/g; 348: $result =~ s/&(int|\#8747);/\\ensuremath\{\\int\}/g; 349: $result =~ s/&(sim|\#8764);/\\ensuremath\{\\sim\}/g; 350: $result =~ s/&(cong|\#8773);/\\ensuremath\{\\cong\}/g; 351: $result =~ s/&(asymp|\#8776);/\\ensuremath\{\\approx\}/g; 352: $result =~ s/&(ne|\#8800);/\\ensuremath\{\\not=\}/g; 353: $result =~ s/&(equiv|\#8801);/\\ensuremath\{\\equiv\}/g; 354: $result =~ s/&(le|\#8804);/\\ensuremath\{\\leq\}/g; 355: $result =~ s/&(ge|\#8805);/\\ensuremath\{\\geq\}/g; 356: $result =~ s/&(sub|\#8834);/\\ensuremath\{\\subset\}/g; 357: $result =~ s/&(sup|\#8835);/\\ensuremath\{\\supset\}/g; 358: $result =~ s/&(nsub|\#8836);/\\ensuremath\{\\not\\subset\}/g; 359: $result =~ s/&(sube|\#8838);/\\ensuremath\{\\subseteq\}/g; 360: $result =~ s/&(supe|\#8839);/\\ensuremath\{\\supseteq\}/g; 361: $result =~ s/&(oplus|\#8853);/\\ensuremath\{\\oplus\}/g; 362: $result =~ s/&(otimes|\#8855);/\\ensuremath\{\\otimes\}/g; 363: $result =~ s/&(perp|\#8869);/\\ensuremath\{\\perp\}/g; 364: $result =~ s/&(sdot|\#8901);/\\ensuremath\{\\cdot\}/g; 365: #Geometric Shapes (extended HTML 4.01) 366: $result =~ s/&(loz|\#9674);/\\ensuremath\{\\Diamond\}/g; 367: #Miscellaneous Symbols (extended HTML 4.01) 368: $result =~ s/&(spades|\#9824);/\\ensuremath\{\\spadesuit\}/g; 369: $result =~ s/&(clubs|\#9827);/\\ensuremath\{\\clubsuit\}/g; 370: $result =~ s/&(hearts|\#9829);/\\ensuremath\{\\heartsuit\}/g; 371: $result =~ s/&(diams|\#9830);/\\ensuremath\{\\diamondsuit\}/g; 372: return $result; 373: } 374: 375: 376: sub page_format { 377: # 378: #Correspondence between $papersize variable and real paper format: 379: # 0 - "Letter [8 1/2x11 in]" 380: # 1 - "Legal [8 1/2x14 in]" 381: # 2 - "Ledger/Tabloid [11x17 in]" 382: # 3 - "Executive [7 1/2x10 in]" 383: # 4 - "A2 [420x594 mm]" 384: # 5 - "A3 [297x420 mm]" 385: # 6 - "A4 [210x297 mm]" 386: # 7 - "A5 [148x210 mm]" 387: # 8 - "A6 [105x148 mm]" 388: # 389: my ($papersize,$layout,$numberofcolumns) = @_; 390: my ($textwidth,$textheight,$oddoffset,$evenoffset,$topmargin) = (0,0,0,0,0); 391: if ($papersize eq '0') { 392: if ($layout eq 'book') { 393: if ($numberofcolumns == 1) { 394: $textwidth = '7.1 in'; #'18 cm'; 395: $textheight = '10.2 in'; #'25.9 cm'; 396: $oddoffset = '-0.57 in'; 397: $evenoffset = '-0.57 in'; 398: } elsif ($numberofcolumns == 2) { 399: $textwidth = '3.66 in'; #'93 mm'; 400: $textheight = '10.2 in'; #'25.9 cm'; 401: $oddoffset = '-0.57 in'; 402: $evenoffset = '-0.57 in'; 403: } 404: } elsif ($layout eq 'album') { 405: if ($numberofcolumns eq '1') { 406: $textwidth = '8.8 in'; 407: $textheight = '6.8 in'; 408: $oddoffset = '-40 pt'; 409: $evenoffset = '-60 pt'; 410: } elsif ($numberofcolumns == 2) { 411: $textwidth = '4.4 in'; 412: $textheight = '6.8 in'; 413: $oddoffset = '-0.5 in'; 414: $evenoffset = '-1.5 in'; 415: $topmargin = '3.5 in'; 416: } 417: } 418: # } elsif($papersize eq '1') { 419: # } elsif($papersize eq '2') { 420: # } elsif($papersize eq '3'/) { 421: } elsif($papersize eq '6') { 422: if ($layout eq 'book') { 423: if ($numberofcolumns == 1) { 424: $textwidth = '18 cm'; 425: $textheight = '28 cm'; 426: $oddoffset = '-0.57 in'; 427: $evenoffset = '-0.57 in'; 428: } elsif ($numberofcolumns == 2) { 429: $textwidth = '96 mm'; 430: $textheight = '2 cm'; 431: $oddoffset = '-0.57 in'; 432: $evenoffset = '-0.57 in'; 433: } 434: } elsif ($layout eq 'album') { 435: if ($numberofcolumns eq '1') { 436: $textwidth = '8.5 in'; 437: $textheight = '7.7 in'; 438: $oddoffset = '-40 pt'; 439: $evenoffset = '-60 pt'; 440: } elsif ($numberofcolumns == 2) { 441: $textwidth = '3.9 in'; 442: $textheight = '7.7 in'; 443: $oddoffset = '-40 pt'; 444: $evenoffset = '-60 pt'; 445: } 446: } 447: # } elsif($papersize eq '5') { 448: # } elsif($papersize eq '4') { 449: # } elsif($papersize eq '7') { 450: # } elsif($papersize eq '8') { 451: } 452: return $textwidth,$textheight,$oddoffset,$evenoffset,$topmargin; 453: } 454: 455: 456: sub get_name { 457: my ($uname,$udom)=@_; 458: if (!defined($uname)) { $uname=$ENV{'user.name'}; } 459: if (!defined($udom)) { $udom=$ENV{'user.domain'}; } 460: my $plainname=&Apache::loncommon::plainname($uname,$udom); 461: if ($plainname=~/^\s*$/) { $plainname=$uname.'@'.$udom; } 462: $plainname=&Apache::lonxml::latex_special_symbols($plainname,'header'); 463: return $plainname; 464: } 465: 466: sub get_course { 467: my $courseidinfo; 468: if (defined($ENV{'request.course.id'})) { 469: $courseidinfo = &Apache::lonxml::latex_special_symbols(&Apache::lonnet::unescape($ENV{'course.'.$ENV{'request.course.id'}.'.description'}),'header'); 470: } 471: return $courseidinfo; 472: } 473: 474: sub page_format_transformation { 475: my ($papersize,$layout,$numberofcolumns,$choice,$text,$assignment,$tableofcontents,$indexlist) = @_; 476: my ($textwidth,$textheight,$oddoffset,$evenoffset,$topmargin); 477: $assignment=&Apache::lonxml::latex_special_symbols($assignment,'header'); 478: ($textwidth,$textheight,$oddoffset,$evenoffset,$topmargin) = &page_format($papersize,$layout,$numberofcolumns,$topmargin); 479: my $name = &get_name(); 480: my $courseidinfo = &get_course(); 481: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo } 482: if ($layout eq 'album') { 483: my $topmargintoinsert = ''; 484: if ($topmargin ne '0') {$topmargintoinsert='\setlength{\topmargin}{'.$topmargin.'}';} 485: $text =~ s/\\begin{document}/\\setlength{\\oddsidemargin}{$oddoffset}\\setlength{\\evensidemargin}{$evenoffset}$topmargintoinsert\\setlength{\\textwidth}{$textwidth}\\setlength{\\textheight}{$textheight}\\setlength{\\textfloatsep}{8pt plus 2\.0pt minus 4\.0pt}\\newlength{\\minipagewidth}\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\\usepackage{fancyhdr}\\pagestyle{fancy}\\rhead{}\\chead{}\\lhead{\\textbf{$name} $courseidinfo \\hfill \\thepage \\\\ \\textit{$assignment}} \\begin{document}\\voffset=-0\.8 cm\\setcounter{page}{1} /; 486: } elsif ($layout eq 'book') { 487: if ($choice ne 'All class print') { 488: $text =~ s/\\begin{document}/\\textheight $textheight\\oddsidemargin = $evenoffset\\evensidemargin = $evenoffset\\textwidth= $textwidth\\newlength{\\minipagewidth}\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\\renewcommand{\\ref}{\\keephidden\}\\usepackage{fancyhdr}\\pagestyle{fancy}\\rhead{}\\chead{}\\lhead{\\textbf{$name} $courseidinfo \\hfill \\thepage \\\\ \\textit{$assignment}}\\begin{document}\\voffset=-0\.8 cm\\setcounter{page}{1}/; 489: } else { 490: $text =~ s/\\pagestyle{fancy}\\rhead{}\\chead{}\s*\\begin{document}/\\textheight = $textheight\\oddsidemargin = $evenoffset\\evensidemargin = $evenoffset\\textwidth= $textwidth\\newlength{\\minipagewidth}\\setlength{\\minipagewidth}{\\textwidth\/\$number_of_columns-0\.2cm}\\renewcommand{\\ref}{\\keephidden\}\\pagestyle{fancy}\\rhead{}\\chead{}\\begin{document}\\voffset=-0\.8cm\\setcounter{page}{1} \\vskip 5 mm /; 491: } 492: } 493: if ($tableofcontents eq 'yes') {$text=~s/(\\setcounter\{page\}\{1\})/$1 \\tableofcontents\\newpage /;} 494: if ($indexlist eq 'yes') { 495: $text=~s/(\\begin{document})/\\makeindex $1/; 496: $text=~s/(\\end{document})/\\strut\\\\\\strut\\printindex $1/; 497: } 498: return $text; 499: } 500: 501: 502: sub page_cleanup { 503: my $result = shift; 504: 505: $result =~ m/\\end{document}(\d*)$/; 506: my $number_of_columns = $1; 507: my $insert = '{'; 508: for (my $id=1;$id<=$number_of_columns;$id++) { $insert .='l'; } 509: $insert .= '}'; 510: $result =~ s/(\\begin{longtable})INSERTTHEHEADOFLONGTABLE\\endfirsthead\\endhead/$1$insert/g; 511: $result =~ s/&\s*REMOVETHEHEADOFLONGTABLE\\\\/\\\\/g; 512: return $result,$number_of_columns; 513: } 514: 515: 516: sub details_for_menu { 517: 518: my $name_of_resourse = &Apache::lonnet::gettitle($ENV{'form.postdata'}); 519: my $symbolic = &Apache::lonnet::symbread($ENV{'form.postdata'}); 520: my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symbolic); 521: $map=&Apache::lonnet::clutter($map); 522: my $name_of_sequence = &Apache::lonnet::gettitle($map); 523: if ($name_of_sequence =~ /^\s*$/) { 524: $map =~ m|([^/]+)$|; 525: $name_of_sequence = $1; 526: } 527: my $name_of_map = &Apache::lonnet::gettitle($ENV{'request.course.uri'}); 528: if ($name_of_map =~ /^\s*$/) { 529: $ENV{'request.course.uri'} =~ m|([^/]+)$|; 530: $name_of_map = $1; 531: } 532: return ($name_of_resourse,$name_of_sequence,$name_of_map); 533: 534: } 535: 536: 537: sub latex_corrections { 538: 539: my ($number_of_columns,$result) = @_; 540: 541: # $result =~ s/\\includegraphics{/\\includegraphics\[width=\\minipagewidth\]{/g; 542: $result =~ s/\$number_of_columns/$number_of_columns/g; 543: $result =~ s/(\\end{document})/\\strut\\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/; 544: $result =~ s/(\\end{longtable}\s*)(\\strut\\newline\\noindent\\makebox\[\\textwidth\/$number_of_columns\]\[b\]{\\hrulefill})/$2$1/g; 545: $result =~ s/(\\end{longtable}\s*)\\strut\\newline/$1/g; 546: #-- LaTeX corrections 547: my $first_comment = index($result,'<!--',0); 548: while ($first_comment != -1) { 549: my $end_comment = index($result,'-->',$first_comment); 550: substr($result,$first_comment,$end_comment-$first_comment+3) = ''; 551: $first_comment = index($result,'<!--',$first_comment); 552: } 553: $result =~ s/^\s+$//gm; #remove empty lines 554: $result =~ s/(\s)(\s+)/$1/g; #removes more than one empty space 555: $result =~ s/\\\\\s*\\vskip/\\vskip/gm; 556: $result =~ s/\\\\\s*\\noindent\s*(\\\\)+/\\\\\\noindent /g; 557: $result =~ s/{\\par }\s*\\\\/\\\\/gm; 558: $result =~ s/\\\\\s+\[/ \[/g; 559: $result =~ s/\b__+\b/\\makebox\[1 cm\]\[b\]{\\hrulefill}/g; 560: #conversion of html characters to LaTeX equivalents 561: if ($result =~ m/&(\w+|#\d+);/) { 562: $result = &character_chart($result); 563: } 564: $result =~ s/(\\end{tabular})\s*\\vskip 0 mm/$1/g; 565: $result =~ s/(\\begin{enumerate})\s*\\noindent/$1/g; 566: 567: return $result; 568: } 569: 570: 571: sub index_table { 572: my $currentURL = shift; 573: my $insex_string=''; 574: $currentURL=~s/\.([^\/+])$/\.$1\.meta/; 575: $insex_string=&Apache::lonnet::metadata($currentURL,'keywords'); 576: return $insex_string; 577: } 578: 579: 580: sub IndexCreation { 581: my ($texversion,$currentURL)=@_; 582: my @key_words=split(/,/,&index_table($currentURL)); 583: my $chunk=''; 584: my $st=index $texversion,'\addcontentsline{toc}{subsection}{'; 585: if ($st>0) { 586: for (my $i=0;$i<3;$i++) {$st=(index $texversion,'}',$st+1);} 587: $chunk=substr($texversion,0,$st+1); 588: substr($texversion,0,$st+1)=' '; 589: } 590: foreach my $key_word (@key_words) { 591: if ($key_word=~/\S+/) { 592: $texversion=~s/\b($key_word)\b/$1 \\index{$key_word} /i; 593: } 594: } 595: if ($st>0) {substr($texversion,0,1)=$chunk;} 596: return $texversion; 597: } 598: 599: sub print_latex_header { 600: my $mode=shift; 601: my $output='\documentclass[letterpaper]{article}'; 602: if ($mode eq 'batchmode') { 603: $output.='\batchmode'; 604: } 605: $output.='\newcommand{\keephidden}[1]{}\renewcommand{\deg}{$^{\circ}$}'. 606: '\usepackage{longtable}\usepackage{textcomp}\usepackage{makeidx}'. 607: '\usepackage[dvips]{graphicx}\usepackage{epsfig}\usepackage{calc}'. 608: '\newenvironment{choicelist}{\begin{list}{}{\setlength{\rightmargin}{0in}'. 609: '\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.05in}'. 610: '\setlength{\itemsep}{0.022in}\setlength{\parsep}{0in}'. 611: '\setlength{\belowdisplayskip}{0.04in}\setlength{\abovedisplayskip}{0.05in}'. 612: '\setlength{\abovedisplayshortskip}{-0.04in}'. 613: '\setlength{\belowdisplayshortskip}{0.04in}}}{\end{list}}'. 614: '\renewenvironment{theindex}{\begin{list}{}{{\vskip 1mm \noindent \large'. 615: '\textbf{Index}} \newline \setlength{\rightmargin}{0in}'. 616: '\setlength{\leftmargin}{0.13in}\setlength{\topsep}{0.01in}'. 617: '\setlength{\itemsep}{0.1in}\setlength{\parsep}{-0.02in}'. 618: '\setlength{\belowdisplayskip}{0.01in}\setlength{\abovedisplayskip}{0.01in}'. 619: '\setlength{\abovedisplayshortskip}{-0.04in}'. 620: '\setlength{\belowdisplayshortskip}{0.01in}}}{\end{list}}\begin{document}'; 621: return $output; 622: } 623: 624: sub path_to_problem { 625: my ($urlp,$LaTeXwidth)=@_; 626: my $newurlp = ''; 627: $LaTeXwidth=~s/\s*mm\s*$//; 628: my $HowMany = length($urlp)*2; 629: if ($HowMany > $LaTeXwidth) { 630: my @temporrary = split '/',$urlp; 631: my $HowManyNew = 0; 632: for (my $ii=0;$ii<=$#temporrary;$ii++) { 633: if ($temporrary[$ii] ne '') { 634: $HowManyNew += length($temporrary[$ii])*2; 635: if ($HowManyNew < $LaTeXwidth ) { 636: $newurlp .= '/'.$temporrary[$ii]; 637: } else { 638: $HowManyNew = 0; 639: $newurlp .= '|\vskip -1 mm \noindent \verb|'; 640: $ii--; 641: } 642: } 643: } 644: } else { 645: $newurlp=$urlp; 646: } 647: return '{\small\noindent\verb|'.$newurlp.'|\vskip 0 mm}'; 648: } 649: 650: sub recalcto_mm { 651: my $textwidth=shift; 652: my $LaTeXwidth; 653: if ($textwidth=~/(\d+\.?\d*)\s*cm/) { 654: $LaTeXwidth = $1*10; 655: } elsif ($textwidth=~/(\d+\.?\d*)\s*mm/) { 656: $LaTeXwidth = $1; 657: } elsif ($textwidth=~/(\d+\.?\d*)\s*in/) { 658: $LaTeXwidth = $1*25.4; 659: } 660: $LaTeXwidth.=' mm'; 661: return $LaTeXwidth; 662: } 663: 664: sub get_textwidth { 665: my ($helper,$LaTeXwidth)=@_; 666: my $textwidth=$LaTeXwidth; 667: if ($helper->{'VARS'}->{'pagesize.width'}=~/\d+/ && 668: $helper->{'VARS'}->{'pagesize.widthunit'}=~/\w+/) { 669: $textwidth=&recalcto_mm($helper->{'VARS'}->{'pagesize.width'}.' '. 670: $helper->{'VARS'}->{'pagesize.widthunit'}); 671: } 672: return $textwidth; 673: } 674: 675: sub output_data { 676: my ($r,$helper,$rparmhash) = @_; 677: my %parmhash = %$rparmhash; 678: my $bodytag=&Apache::loncommon::bodytag('Preparing Printout'); 679: $r->print(<<ENDPART); 680: <html> 681: <script type="text/javascript" language="Javascript" > 682: var editbrowser; 683: function openbrowser(formname,elementname,only,omit) { 684: var url = '/res/?'; 685: if (editbrowser == null) { 686: url += 'launch=1&'; 687: } 688: url += 'catalogmode=interactive&'; 689: url += 'mode=parmset&'; 690: url += 'form=' + formname + '&'; 691: if (only != null) { 692: url += 'only=' + only + '&'; 693: } 694: if (omit != null) { 695: url += 'omit=' + omit + '&'; 696: } 697: url += 'element=' + elementname + ''; 698: var title = 'Browser'; 699: var options = 'scrollbars=1,resizable=1,menubar=0'; 700: options += ',width=700,height=600'; 701: editbrowser = open(url,title,options,'1'); 702: editbrowser.focus(); 703: } 704: </script> 705: <head> 706: <title>LON-CAPA output for printing</title> 707: </head> 708: $bodytag 709: Please stand by while processing your print request, this may take some time ... 710: ENDPART 711: 712: my $format_from_helper = $helper->{'VARS'}->{'FORMAT'}; 713: my ($result,$selectionmade) = ('',''); 714: my $number_of_columns = 1; #used only for pages to determine the width of the cell 715: my @temporary_array=split /\|/,$format_from_helper; 716: my ($laystyle,$numberofcolumns,$papersize)=@temporary_array; 717: if ($laystyle eq 'L') { 718: $laystyle='album'; 719: } else { 720: $laystyle='book'; 721: } 722: my ($textwidth,$textheight,$oddoffset,$evenoffset) = &page_format($papersize,$laystyle,$numberofcolumns); 723: my $assignment = $ENV{'form.assignment'}; 724: my $LaTeXwidth=&recalcto_mm($textwidth); 725: my @print_array=(); 726: my @student_names=(); 727: 728: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'current_document') { 729: #-- single document - problem, page, html, xml, ... 730: my $currentURL; 731: if ($helper->{'VARS'}->{'construction'} ne '1') { 732: #prints published resource 733: $currentURL=$helper->{'VARS'}->{'postdata'}; 734: } else { 735: #prints resource from the construction space 736: $currentURL='/'.$helper->{'VARS'}->{'filename'}; 737: if ($currentURL=~/([^?]+)/) {$currentURL=$1;} 738: } 739: $selectionmade = 1; 740: if ($currentURL=~/\.(problem|exam|quiz|assess|survey|form|library|page|xml|html|htm|xhtml|xhtm)$/) { 741: my $rndseed=time; 742: my $texversion=''; 743: if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') { 744: my %moreenv; 745: $moreenv{'request.filename'}=$currentURL; 746: if ($helper->{'VARS'}->{'style_file'}=~/\w/) { 747: $moreenv{'construct.style'}=$helper->{'VARS'}->{'style_file'}; 748: my $dom = $ENV{'user.domain'}; 749: my $user = $ENV{'user.name'}; 750: my $put_result = &Apache::lonnet::put('environment',{'construct.style'=>$helper->{'VARS'}->{'style_file'}},$dom,$user); 751: } 752: my %form; 753: if ($helper->{'VARS'}->{'probstatus'} eq 'exam') {$form{'problemtype'}='exam';} 754: $form{'grade_target'}='tex'; 755: $form{'textwidth'}=&get_textwidth($helper,$LaTeXwidth); 756: $form{'problem_split'}=$parmhash{'problem_stream_switch'}; 757: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 758: if ($helper->{'VARS'}->{'curseed'}) { 759: $rndseed=$helper->{'VARS'}->{'curseed'}; 760: } 761: $form{'rndseed'}=$rndseed; 762: &Apache::lonnet::appenv(%moreenv); 763: &Apache::lonnet::delenv('form.counter'); 764: &Apache::lonxml::init_counter(); 765: $texversion.=&Apache::lonnet::ssi($currentURL,%form); 766: &Apache::lonnet::delenv('form.counter'); 767: &Apache::lonnet::delenv('request.filename'); 768: } 769: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 770: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { 771: my %form; 772: $form{'grade_target'}='answer'; 773: $form{'answer_output_mode'}='tex'; 774: $form{'rndseed'}=$rndseed; 775: my $answer=&Apache::lonnet::ssi($currentURL,%form); 776: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 777: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; 778: } else { 779: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 780: if ($helper->{'VARS'}->{'construction'} ne '1') { 781: $texversion.='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'}).'}\vskip 0 mm '; 782: $texversion.=&path_to_problem ($currentURL,$LaTeXwidth); 783: } else { 784: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm '; 785: my $URLpath=$currentURL; 786: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/; 787: $texversion.=&path_to_problem ($URLpath,$LaTeXwidth); 788: } 789: $texversion.='\vskip 1 mm '.$answer.'\end{document}'; 790: } 791: } 792: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { 793: $texversion=&IndexCreation($texversion,$currentURL); 794: } 795: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') { 796: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$currentURL| \\strut\\\\\\strut /; 797: 798: } 799: $result .= $texversion; 800: if ($currentURL=~m/\.page\s*$/) { 801: ($result,$number_of_columns) = &page_cleanup($result); 802: } 803: } elsif ($currentURL=~/\.sequence$/ && $helper->{'VARS'}->{'construction'} eq '1') { 804: #printing content of sequence from the construction space 805: my $flag_latex_header_remove = 'NO'; 806: my $rndseed=time; 807: if ($helper->{'VARS'}->{'curseed'}) { 808: $rndseed=$helper->{'VARS'}->{'curseed'}; 809: } 810: $currentURL=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|; 811: my $errtext=&Apache::lonratedt::mapread($currentURL); 812: for (my $member=0;$member<=$#Apache::lonratedt::order;$member++) { 813: $Apache::lonratedt::resources[$Apache::lonratedt::order[$member]]=~/^([^:]*):([^:]*):/; 814: my $urlp=$2; 815: if ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|xml|html|htm|xhtml|xhtm)$/) { 816: my $texversion=''; 817: if ($helper->{'VARS'}->{'ANSWER_TYPE'} ne 'only') { 818: my %form; 819: $form{'grade_target'}='tex'; 820: $form{'textwidth'}=&get_textwidth($helper,$LaTeXwidth); 821: $form{'problem_split'}=$parmhash{'problem_stream_switch'}; 822: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 823: $form{'rndseed'}=$rndseed; 824: $texversion=&Apache::lonnet::ssi($urlp,%form); 825: } 826: if((($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 827: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) && 828: ($urlp=~/\.(problem|exam|quiz|assess|survey|form|library|page)$/)) { 829: my %form; 830: $form{'grade_target'}='answer'; 831: $form{'answer_output_mode'}='tex'; 832: $form{'rndseed'}=$rndseed; 833: if ($urlp=~/\/res\//) {$ENV{'request.state'}='published';} 834: my $answer=&Apache::lonnet::ssi($urlp,%form); 835: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 836: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; 837: } else { 838: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 839: $texversion.='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($helper->{'VARS'}->{'symb'}).'}\vskip 0 mm '; 840: $texversion.=&path_to_problem ($currentURL,$LaTeXwidth); 841: $texversion.='\vskip 1 mm '.$answer.'\end{document}'; 842: } 843: } 844: if ($flag_latex_header_remove ne 'NO') { 845: $texversion = &latex_header_footer_remove($texversion); 846: } else { 847: $texversion =~ s/\\end{document}//; 848: } 849: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { 850: $texversion=&IndexCreation($texversion,$urlp); 851: } 852: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URpL'} eq 'yes') { 853: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /; 854: } 855: $result.=$texversion; 856: $flag_latex_header_remove = 'YES'; 857: } elsif ($urlp=~/\.(sequence|page)$/) { 858: $result.='\strut\newline\noindent Sequence/page '.$urlp.'\strut\newline\noindent\makebox[\textwidth/$number_of_columns][b]{\hrulefill}\newline\noindent '; 859: } 860: } 861: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\begin{document})/$1 \\fbox\{RANDOM SEED IS $rndseed\} /;} 862: $result .= '\end{document}'; 863: } elsif ($currentURL=~/\/smppg$/) { 864: my %form; 865: $form{'grade_target'}='tex'; 866: $form{'textwidth'}=&get_textwidth($helper,$LaTeXwidth); 867: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 868: my $texversion=&Apache::lonnet::ssi($currentURL,%form); 869: $result .= $texversion; 870: } else { 871: $result.='\documentclass[letterpaper]{article}\usepackage{calc}\begin{document}Printout of this type of document is currently not supported: '; 872: if ($currentURL=~/\/(aboutme|syllabus|bulletinboard|smppg)$/) { 873: $result.=$1; 874: } elsif ($currentURL=~/\/ext\//) { 875: $result.=' \strut \\\\ THIS IS EXTERNAL RESOURCE WITH URL \strut \\\\ '.$currentURL.' '; 876: } else { 877: $result.=$currentURL; 878: } 879: $result.=' \end{document}' 880: } 881: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') or 882: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') or 883: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') or 884: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences')) { 885: #-- produce an output string 886: my %form=(); 887: $form{'grade_target'}='tex'; 888: $form{'textwidth'}=&get_textwidth($helper,$LaTeXwidth); 889: $form{'problem_split'}=$parmhash{'problem_stream_switch'}; 890: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 891: my $flag_latex_header_remove = 'NO'; 892: my $flag_page_in_sequence = 'NO'; 893: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'}; 894: my $prevassignment=''; 895: &Apache::lonnet::delenv('form.counter'); 896: &Apache::lonxml::init_counter(); 897: for (my $i=0;$i<=$#master_seq;$i++) { 898: my (undef,undef,$urlp)=&Apache::lonnet::decode_symb($master_seq[$i]); 899: $urlp=&Apache::lonnet::clutter($urlp); 900: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems') { 901: $selectionmade = 2; 902: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'map_problems_pages') { 903: $selectionmade = 3; 904: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'all_problems') { 905: $selectionmade = 4; 906: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'select_sequences') { 907: $selectionmade = 7; 908: } 909: $form{'symb'}=$master_seq[$i]; 910: my ($sequence)=&Apache::lonnet::decode_symb($master_seq[$i]); 911: my $assignment=&Apache::lonxml::latex_special_symbols(&Apache::lonnet::gettitle($sequence),'header'); #tittle of the assignment which contains this problem 912: if ($selectionmade==7) {$helper->{VARS}->{'assignment'}=$assignment;} 913: if ($i==0) {$prevassignment=$assignment;} 914: #&Apache::lonnet::logthis("Trying to get $urlp with symb $master_seq[$i]"); 915: my $texversion.=&Apache::lonnet::ssi($urlp,%form); 916: if ($urlp=~/\.page$/) { 917: ($texversion,my $number_of_columns_page) = &page_cleanup($texversion); 918: if ($number_of_columns_page > $number_of_columns) {$number_of_columns=$number_of_columns_page;} 919: $texversion =~ s/\\end{document}\d*/\\end{document}/; 920: $flag_page_in_sequence = 'YES'; 921: } 922: my $lonidsdir=$r->dir_config('lonIDsDir'); 923: my $envfile=$ENV{'user.environment'}; 924: $envfile=~/\/([^\/]+)\.id$/; 925: $envfile=$1; 926: &Apache::lonnet::transfer_profile_to_env($lonidsdir,$envfile); 927: my $current_counter=$ENV{'form.counter'}; 928: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 929: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { 930: my %form; 931: $form{'grade_target'}='answer'; 932: $form{'answer_output_mode'}='tex'; 933: my $answer=&Apache::lonnet::ssi($urlp,%form); 934: &Apache::lonnet::appenv(('form.counter' => $current_counter)); 935: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 936: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; 937: } else { 938: if ($urlp=~/\.(problem|exam|quiz|library)$/) { 939: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 940: $texversion.='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($urlp).'}\vskip 0 mm '; 941: $texversion.=&path_to_problem ($urlp,$LaTeXwidth); 942: $texversion.='\vskip 1 mm '.$answer; 943: } else { 944: $texversion=''; 945: } 946: } 947: } 948: if ($flag_latex_header_remove ne 'NO') { 949: $texversion = &latex_header_footer_remove($texversion); 950: } else { 951: $texversion =~ s/\\end{document}//; 952: } 953: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { 954: $texversion=&IndexCreation($texversion,$urlp); 955: } 956: if (($selectionmade == 4) and ($assignment ne $prevassignment)) { 957: my $name = &get_name(); 958: my $courseidinfo = &get_course(); 959: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo } 960: $prevassignment=$assignment; 961: $result .='\newpage \noindent\parbox{\minipagewidth}{\noindent\\lhead{\\textit{\\textbf{'.$name.'}}'.$courseidinfo.' \\hfill \\thepage \\\\ \\textit{'.$assignment.'}}} \vskip -5 mm '; 962: } 963: $result .= $texversion; 964: $flag_latex_header_remove = 'YES'; 965: } 966: &Apache::lonnet::delenv('form.counter'); 967: if ($flag_page_in_sequence eq 'YES') {$result =~ s/\\usepackage{calc}/\\usepackage{calc}\\usepackage{longtable}/;} 968: $result .= '\end{document}'; 969: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') || 970: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students')){ 971: #-- prints assignments for whole class or for selected students 972: my $type; 973: if ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_students') { 974: $selectionmade=5; 975: $type='problems'; 976: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_students') { 977: $selectionmade=8; 978: $type='resources'; 979: } 980: my @students=split /\|\|\|/, $helper->{'VARS'}->{'STUDENTS'}; 981: if ($helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq '0' || 982: $helper->{'VARS'}->{'NUMBER_TO_PRINT'} eq 'all' ) { 983: $helper->{'VARS'}->{'NUMBER_TO_PRINT'}=$#students+1; 984: } 985: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'}; 986: #loop over students 987: my $flag_latex_header_remove = 'NO'; 988: my %moreenv; 989: $moreenv{'textwidth'}=&get_textwidth($helper,$LaTeXwidth); 990: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$#students+1); 991: my $student_counter=-1; 992: foreach my $person (@students) { 993: $student_counter++; 994: my $i=int($student_counter/$helper->{'VARS'}{'NUMBER_TO_PRINT'}); 995: my ($output,$fullname)=&print_resources($r,$helper,$person,$type,\%moreenv,\@master_seq,$flag_latex_header_remove); 996: $print_array[$i].=$output; 997: $student_names[$i].=$person.':'.$fullname.'_END_'; 998: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,&mt('last student').' '.$fullname); 999: $flag_latex_header_remove = 'YES'; 1000: } 1001: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); 1002: $result .= $print_array[0].' \end{document}'; 1003: } elsif (($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_for_anon') || 1004: ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'resources_for_anon') ) { 1005: my $cdom =$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; 1006: my $cnum =$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; 1007: my $num_todo=$helper->{'VARS'}->{'NUMBER_TO_PRINT_TOTAL'}; 1008: my $code_name=$helper->{'VARS'}->{'ANON_CODE_STORAGE_NAME'}; 1009: my $old_name=$helper->{'VARS'}->{'REUSE_OLD_CODES'}; 1010: my @master_seq=split /\|\|\|/, $helper->{'VARS'}->{'RESOURCES'}; 1011: my ($type) = split(/_/,$helper->{'VARS'}->{'PRINT_TYPE'}); 1012: my $flag_latex_header_remove = 'NO'; 1013: my %moreenv = ('textwidth' => &get_textwidth($helper,$LaTeXwidth)); 1014: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Print Status','Class Print Status',$num_todo,'inline'); 1015: my $seed=time+($$<<16)+($$); 1016: my @allcodes; 1017: if ($old_name) { 1018: my %result=&Apache::lonnet::get('CODEs',[$old_name],$cdom,$cnum); 1019: @allcodes=split(',',$result{$old_name}); 1020: } else { 1021: my %allcodes; 1022: for (my $i=0;$i<$num_todo;$i++) { 1023: $moreenv{'CODE'}=&get_CODE(\%allcodes,$i,$seed,'6'); 1024: } 1025: if ($code_name) { 1026: &Apache::lonnet::put('CODEs', 1027: {$code_name =>join(',',keys(%allcodes))}, 1028: $cdom,$cnum); 1029: } 1030: @allcodes=keys(%allcodes); 1031: } 1032: my $i=0; 1033: foreach my $code (sort(@allcodes)) { 1034: $moreenv{'CODE'}=&num_to_letters($code); 1035: my ($output,$fullname)= 1036: &print_resources($r,$helper,'anonymous',$type,\%moreenv, 1037: \@master_seq,$flag_latex_header_remove); 1038: $print_array[$i].=$output; 1039: &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state, 1040: &mt('last assignment').' '.$fullname); 1041: $flag_latex_header_remove = 'YES'; 1042: $i++; 1043: } 1044: &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); 1045: $result .= $print_array[0].' \end{document}'; 1046: } elsif ($helper->{'VARS'}->{'PRINT_TYPE'} eq 'problems_from_directory') { 1047: #prints selected problems from the subdirectory 1048: $selectionmade = 6; 1049: my @list_of_files=split /\|\|\|/, $helper->{'VARS'}->{'FILES'}; 1050: @list_of_files=sort @list_of_files; 1051: my $flag_latex_header_remove = 'NO'; 1052: my $rndseed=time; 1053: if ($helper->{'VARS'}->{'curseed'}) { 1054: $rndseed=$helper->{'VARS'}->{'curseed'}; 1055: } 1056: for (my $i=0;$i<=$#list_of_files;$i++) { 1057: my $urlp = $list_of_files[$i]; 1058: $urlp=~s|//|/|; 1059: if ($urlp=~/\//) { 1060: my %form; 1061: $form{'grade_target'}='tex'; 1062: $form{'textwidth'}=&get_textwidth($helper,$LaTeXwidth); 1063: $form{'rndseed'}=$rndseed; 1064: if ($urlp =~ m|/home/([^/]+)/public_html|) { 1065: $urlp =~ s|/home/([^/]*)/public_html|/~$1|; 1066: } else { 1067: $urlp =~ s|^/home/httpd/html||; 1068: } 1069: my $texversion=&Apache::lonnet::ssi($urlp,%form); 1070: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 1071: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { 1072: my %form; 1073: $form{'grade_target'}='answer'; 1074: $form{'answer_output_mode'}='tex'; 1075: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1076: $form{'rndseed'}=$rndseed; 1077: my $answer=&Apache::lonnet::ssi($urlp,%form); 1078: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 1079: $texversion=~s/(\\keephidden{ENDOFPROBLEM})/$answer$1/; 1080: } else { 1081: $texversion=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 1082: if ($helper->{'VARS'}->{'construction'} ne '1') { 1083: $texversion.='\vskip 0 mm \noindent '; 1084: $texversion.=&path_to_problem ($urlp,$LaTeXwidth); 1085: } else { 1086: $texversion.='\vskip 0 mm \noindent\textbf{Prints from construction space - there is no title.}\vskip 0 mm '; 1087: my $URLpath=$urlp; 1088: $URLpath=~s/~([^\/]+)/public_html\/$1\/$1/; 1089: $texversion.=&path_to_problem ($URLpath,$LaTeXwidth); 1090: } 1091: $texversion.='\vskip 1 mm '.$answer.'\end{document}'; 1092: } 1093: } 1094: #this chunck is responsible for printing the path to problem 1095: my $newurlp=$urlp; 1096: if ($newurlp=~/~/) {$newurlp=~s|\/~([^\/]+)\/|\/home\/$1\/public_html\/|;} 1097: $newurlp=&path_to_problem($newurlp,$LaTeXwidth); 1098: $texversion =~ s/(\\begin{minipage}{\\textwidth})/$1 $newurlp/; 1099: if ($flag_latex_header_remove ne 'NO') { 1100: $texversion = &latex_header_footer_remove($texversion); 1101: } else { 1102: $texversion =~ s/\\end{document}//; 1103: } 1104: if ($helper->{'VARS'}->{'TABLE_INDEX'} eq 'yes') { 1105: $texversion=&IndexCreation($texversion,$urlp); 1106: } 1107: if ($helper->{'VARS'}->{'CONSTR_RESOURSE_URL'} eq 'yes') { 1108: $texversion=~s/(\\addcontentsline\{toc\}\{subsection\}\{[^\}]*\})/$1 URL: \\verb|$urlp| \\strut\\\\\\strut /; 1109: 1110: } 1111: $result .= $texversion; 1112: } 1113: $flag_latex_header_remove = 'YES'; 1114: } 1115: if ($helper->{VARS}->{'construction'} eq '1') {$result=~s/(\\typeout)/ RANDOM SEED IS $rndseed $1/;} 1116: $result .= '\end{document}'; 1117: } 1118: #-------------------------------------------------------- corrections for the different page formats 1119: $result = &page_format_transformation($papersize,$laystyle,$numberofcolumns,$helper->{'VARS'}->{'PRINT_TYPE'},$result,$helper->{VARS}->{'assignment'},$helper->{'VARS'}->{'TABLE_CONTENTS'},$helper->{'VARS'}->{'TABLE_INDEX'}); 1120: $result = &latex_corrections($number_of_columns,$result); 1121: for (my $i=1;$i<=$#print_array;$i++) {$print_array[$i] = &latex_corrections($number_of_columns,$print_array[$i]);} 1122: #changes page's parameters for the one column output 1123: if ($numberofcolumns == 1) { 1124: $result =~ s/\\textwidth\s*=\s*\d*\.?\d*\s*(cm|mm|in)/\\textwidth= $helper->{'VARS'}->{'pagesize.width'} $helper->{'VARS'}->{'pagesize.widthunit'} /; 1125: $result =~ s/\\textheight\s*=\s*\d*\.?\d*\s*(cm|mm|in)/\\textheight $helper->{'VARS'}->{'pagesize.height'} $helper->{'VARS'}->{'pagesize.heightunit'} /; 1126: $result =~ s/\\evensidemargin\s*=\s*\d*\.?\d*\s*(cm|mm|in)/\\evensidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /; 1127: $result =~ s/\\oddsidemargin\s*=\s*\d*\.?\d*\s*(cm|mm|in)/\\oddsidemargin= $helper->{'VARS'}->{'pagesize.lmargin'} $helper->{'VARS'}->{'pagesize.lmarginunit'} /; 1128: } 1129: #-- writing .tex file in prtspool 1130: my $temp_file; 1131: my $identifier = &Apache::loncommon::get_cgi_id(); 1132: my $filename = "/home/httpd/prtspool/$ENV{'user.name'}_$ENV{'user.domain'}_printout_".$identifier.".tex"; 1133: if (!($#print_array>0)) { 1134: unless ($temp_file = Apache::File->new('>'.$filename)) { 1135: $r->log_error("Couldn't open $filename for output $!"); 1136: return SERVER_ERROR; 1137: } 1138: print $temp_file $result; 1139: my $begin=index($result,'\begin{document}',0); 1140: my $inc=substr($result,0,$begin+16); 1141: } else { 1142: my $begin=index($result,'\begin{document}',0); 1143: my $inc=substr($result,0,$begin+16); 1144: for (my $i=0;$i<=$#print_array;$i++) { 1145: if ($i==0) { 1146: $print_array[$i]=$result; 1147: } else { 1148: my $anobegin=index($print_array[$i],'\setcounter{page}',0); 1149: substr($print_array[$i],0,$anobegin)=''; 1150: $print_array[$i]=$inc.$print_array[$i].'\end{document}'; 1151: } 1152: my $temp_file; 1153: my $newfilename=$filename; 1154: my $num=$i+1; 1155: $newfilename =~s/\.tex$/_$num\.tex/; 1156: unless ($temp_file = Apache::File->new('>'.$newfilename)) { 1157: $r->log_error("Couldn't open $newfilename for output $!"); 1158: return SERVER_ERROR; 1159: } 1160: print $temp_file $print_array[$i]; 1161: } 1162: } 1163: my $student_names=''; 1164: if ($#print_array>0) { 1165: for (my $i=0;$i<=$#print_array;$i++) { 1166: $student_names.=$student_names[$i].'_ENDPERSON_'; 1167: } 1168: } else { 1169: if ($#student_names>-1) { 1170: $student_names=$student_names[0].'_ENDPERSON_'; 1171: } else { 1172: my $fullname = &get_name($ENV{'user.name'},$ENV{'user.domain'}); 1173: $student_names=join(':',$ENV{'user.name'},$ENV{'user.domain'}, 1174: $ENV{'request.course.sec'},$fullname). 1175: '_ENDPERSON_'.'_END_'; 1176: } 1177: } 1178: 1179: my $URLback=''; #link to original document 1180: if ($helper->{'VARS'}->{'construction'} ne '1') { 1181: #prints published resource 1182: $URLback=$helper->{'VARS'}->{'postdata'}; 1183: } else { 1184: #prints resource from the construction space 1185: $URLback='/'.$helper->{'VARS'}->{'filename'}; 1186: if ($URLback=~/([^?]+)/) { 1187: $URLback=$1; 1188: $URLback=~s|^/~|/priv/|; 1189: } 1190: } 1191: 1192: &Apache::lonnet::appenv('cgi.'.$identifier.'.file' => $filename, 1193: 'cgi.'.$identifier.'.layout' => $laystyle, 1194: 'cgi.'.$identifier.'.numcol' => $numberofcolumns, 1195: 'cgi.'.$identifier.'.selection' => $selectionmade, 1196: 'cgi.'.$identifier.'tableofcontents' => $helper->{'VARS'}->{'TABLE_CONTENTS'}, 1197: 'cgi.'.$identifier.'tableofindex' => $helper->{'VARS'}->{'TABLE_INDEX'}, 1198: 'cgi.'.$identifier.'role' => $ENV{'request.role.adv'}, 1199: 'cgi.'.$identifier.'numberoffiles' => $#print_array, 1200: 'cgi.'.$identifier.'studentnames' => $student_names, 1201: 'cgi.'.$identifier.'backref' => $URLback,); 1202: 1203: $r->print(<<FINALEND); 1204: <meta http-equiv="Refresh" content="0; url=/cgi-bin/printout.pl?$identifier" /> 1205: </body> 1206: </html> 1207: FINALEND 1208: } 1209: 1210: sub num_to_letters { 1211: my ($num) = @_; 1212: my @nums= split('',$num); 1213: my @num_to_let=('A'..'Z'); 1214: my $word; 1215: foreach my $digit (@nums) { $word.=$num_to_let[$digit]; } 1216: return $word; 1217: } 1218: 1219: sub get_CODE { 1220: my ($all_codes,$num,$seed,$size)=@_; 1221: my $max='1'.'0'x$size; 1222: srand($seed); 1223: my $newcode; 1224: while(1) { 1225: $newcode=sprintf("%06d",int(rand($max))); 1226: if (!exists($$all_codes{$newcode})) { 1227: $$all_codes{$newcode}=1; 1228: return &num_to_letters($newcode); 1229: } 1230: } 1231: } 1232: 1233: sub print_resources { 1234: my ($r,$helper,$person,$type,$moreenv,$master_seq,$remove_latex_header)=@_; 1235: my $current_output = ''; 1236: my ($username,$userdomain,$usersection) = split /:/,$person; 1237: my $fullname = &get_name($username,$userdomain); 1238: if ($person =~ 'anon') { 1239: $fullname = "CODE - ".$moreenv->{'CODE'}; 1240: } 1241: #goes through all resources, checks if they are available for 1242: #current student, and produces output 1243: &Apache::lonnet::delenv('form.counter'); 1244: &Apache::lonxml::init_counter(); 1245: foreach my $curresline (@{$master_seq}) { 1246: if ( !($type eq 'problems' && 1247: ($curresline!~ m/\.(problem|exam|quiz|assess|survey|form|library)$/)) ) { 1248: my ($map,$id,$res_url) = &Apache::lonnet::decode_symb($curresline); 1249: if (&Apache::lonnet::allowed('bre',$res_url)) { 1250: my $rendered = &Apache::loncommon::get_student_view($curresline,$username,$userdomain,$ENV{'request.course.id'},'tex',$moreenv); 1251: my $lonidsdir=$r->dir_config('lonIDsDir'); 1252: my $envfile=$ENV{'user.environment'}; 1253: $envfile=~/\/([^\/]+)\.id$/; 1254: $envfile=$1; 1255: &Apache::lonnet::transfer_profile_to_env($lonidsdir,$envfile); 1256: my $current_counter=$ENV{'form.counter'}; 1257: if(($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') || 1258: ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'only')) { 1259: my %form; 1260: $form{'answer_output_mode'}='tex'; 1261: $form{'latex_type'}=$helper->{'VARS'}->{'LATEX_TYPE'}; 1262: my $ansrendered = &Apache::loncommon::get_student_answers($curresline,$username,$userdomain,$ENV{'request.course.id'},%form); 1263: &Apache::lonnet::appenv(('form.counter' => $current_counter)); 1264: if ($helper->{'VARS'}->{'ANSWER_TYPE'} eq 'no') { 1265: $rendered=~s/(\\keephidden{ENDOFPROBLEM})/$ansrendered$1/; 1266: } else { 1267: $rendered=&print_latex_header($helper->{'VARS'}->{'LATEX_TYPE'}); 1268: $rendered.='\vskip 0 mm \noindent\textbf{'.&Apache::lonnet::gettitle($curresline).'}\vskip 0 mm '; 1269: $rendered.=&path_to_problem ($curresline,$LaTeXwidth); 1270: $rendered.='\vskip 1 mm '.$ansrendered; 1271: } 1272: } 1273: if ($remove_latex_header eq 'YES') { 1274: $rendered = &latex_header_footer_remove($rendered); 1275: } else { 1276: $rendered =~ s/\\end{document}//; 1277: } 1278: $current_output .= $rendered; 1279: } 1280: $remove_latex_header = 'YES'; 1281: } 1282: } 1283: my $courseidinfo = &get_course(); 1284: if (defined($courseidinfo)) { $courseidinfo=' - '.$courseidinfo } 1285: if ($usersection ne '') {$courseidinfo.=' - Sec. '.$usersection} 1286: my $currentassignment=&Apache::lonxml::latex_special_symbols($helper->{VARS}->{'assignment'},'header'); 1287: if ($current_output=~/\\documentclass/) { 1288: $current_output =~ s/\\begin{document}/\\setlength{\\topmargin}{1cm} \\begin{document}\\noindent\\lhead{\\textit{\\textbf{$fullname}}$courseidinfo \\hfill \\thepage \\\\ \\textit{$currentassignment}}\\vskip 3 mm /; 1289: } else { 1290: my $blankpages = ''; 1291: for (my $j=0;$j<$helper->{'VARS'}->{'EMPTY_PAGES'};$j++) {$blankpages.='\clearpage\strut\clearpage';} 1292: $current_output = '\strut\\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 }\\newpage '.$blankpages.'\setcounter{page}{1}\noindent\parbox{\minipagewidth}{\noindent\\lhead{\\textit{\\textbf{'.$fullname.'}}'.$courseidinfo.' \\hfill \\thepage \\\\ \\textit{'.$currentassignment.'}}} \vskip -5 mm '.$current_output; 1293: } 1294: return ($current_output,$fullname); 1295: 1296: } 1297: 1298: sub handler { 1299: 1300: my $r = shift; 1301: my $helper; 1302: 1303: # my $loaderror=&Apache::lonnet::overloaderror($r); 1304: # if ($loaderror) { return $loaderror; } 1305: # $loaderror= 1306: # &Apache::lonnet::overloaderror($r, 1307: # $ENV{'course.'.$ENV{'request.course.id'}.'.home'}); 1308: # if ($loaderror) { return $loaderror; } 1309: 1310: my $result = printHelper($r); 1311: if (!ref($result)) { 1312: return $result; 1313: } 1314: $helper = $result; 1315: 1316: # my $key; 1317: # foreach $key (keys %{$helper->{'VARS'}}) { 1318: # $r->print(' '.$key.'->'.$helper->{'VARS'}->{$key}.'<-<br />'); 1319: # } 1320: # foreach $key (keys %ENV) { 1321: # $r->print(' '.$key.'->'.$ENV{$key}.'<-<br />'); 1322: # } 1323: # return OK; 1324: 1325: my %parmhash=&Apache::lonnet::coursedescription($ENV{'request.course.id'}); 1326: 1327: # my $key; 1328: # foreach $key (keys %parmhash) { 1329: # $r->print(' '.$key.'->'.$parmhash{$key}.'<-<br />'); 1330: # } 1331: # return OK; 1332: 1333: &output_data($r,$helper,\%parmhash); 1334: return OK; 1335: } 1336: 1337: use Apache::lonhelper; 1338: 1339: sub addMessage { 1340: my $text = shift; 1341: my $paramHash = Apache::lonhelper::getParamHash(); 1342: $paramHash->{MESSAGE_TEXT} = $text; 1343: Apache::lonhelper::message->new(); 1344: } 1345: 1346: use Data::Dumper; 1347: 1348: sub printHelper { 1349: my $r = shift; 1350: 1351: if ($ENV{'request.course.id'}) { 1352: my $fn=$ENV{'request.course.fn'}; 1353: tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640); 1354: } 1355: 1356: if ($r->header_only) { 1357: if ($ENV{'browser.mathml'}) { 1358: &Apache::loncommon::content_type($r,'text/xml'); 1359: } else { 1360: &Apache::loncommon::content_type($r,'text/html'); 1361: } 1362: $r->send_http_header; 1363: return OK; 1364: } 1365: 1366: # Send header, nocache 1367: if ($ENV{'browser.mathml'}) { 1368: &Apache::loncommon::content_type($r,'text/xml'); 1369: } else { 1370: &Apache::loncommon::content_type($r,'text/html'); 1371: } 1372: &Apache::loncommon::no_cache($r); 1373: $r->send_http_header; 1374: $r->rflush(); 1375: 1376: # Unfortunately, this helper is so complicated we have to 1377: # write it by hand 1378: 1379: Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); 1380: 1381: my $helper = Apache::lonhelper::helper->new("Printing Helper"); 1382: $helper->declareVar('symb'); 1383: $helper->declareVar('postdata'); 1384: $helper->declareVar('curseed'); 1385: $helper->declareVar('probstatus'); 1386: $helper->declareVar('filename'); 1387: $helper->declareVar('construction'); 1388: $helper->declareVar('assignment'); 1389: $helper->declareVar('style_file'); 1390: 1391: # This will persistently load in the data we want from the 1392: # very first screen. 1393: # Detect whether we're coming from construction space 1394: if ($ENV{'form.postdata'}=~/^(?:http:\/\/[^\/]+\/|\/|)\~([^\/]+)\/(.*)$/) { 1395: $helper->{VARS}->{'filename'} = "~$1/$2"; 1396: $helper->{VARS}->{'construction'} = 1; 1397: } else { 1398: if ($ENV{'form.postdata'}) { 1399: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($ENV{'form.postdata'}); 1400: } 1401: if ($ENV{'form.symb'}) { 1402: $helper->{VARS}->{'symb'} = $ENV{'form.symb'}; 1403: } 1404: if ($ENV{'form.url'}) { 1405: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'}); 1406: } 1407: } 1408: 1409: if ($ENV{'form.symb'}) { 1410: $helper->{VARS}->{'symb'} = $ENV{'form.symb'}; 1411: } 1412: if ($ENV{'form.url'}) { 1413: $helper->{VARS}->{'symb'} = &Apache::lonnet::symbread($helper->{VARS}->{'postdata'}); 1414: 1415: } 1416: 1417: my ($resourceTitle,$sequenceTitle,$mapTitle) = &details_for_menu; 1418: if ($sequenceTitle ne '') {$helper->{VARS}->{'assignment'}=$sequenceTitle;} 1419: 1420: 1421: # Extract map 1422: my $symb = $helper->{VARS}->{'symb'}; 1423: my ($map, $id, $url); 1424: my $subdir; 1425: 1426: # Get the resource name from construction space 1427: if ($helper->{VARS}->{'construction'}) { 1428: $resourceTitle = substr($helper->{VARS}->{'filename'}, 1429: rindex($helper->{VARS}->{'filename'}, '/')+1); 1430: $subdir = substr($helper->{VARS}->{'filename'}, 1431: 0, rindex($helper->{VARS}->{'filename'}, '/') + 1); 1432: } else { 1433: ($map, $id, $url) = &Apache::lonnet::decode_symb($symb); 1434: $helper->{VARS}->{'postdata'} = Apache::lonnet::clutter($url); 1435: 1436: if (!$resourceTitle) { # if the resource doesn't have a title, use the filename 1437: my $postdata = $helper->{VARS}->{'postdata'}; 1438: $resourceTitle = substr($postdata, rindex($postdata, '/') + 1); 1439: } 1440: $subdir = &Apache::lonnet::filelocation("", $url); 1441: } 1442: if (!$helper->{VARS}->{'curseed'} && $ENV{'form.curseed'}) { 1443: $helper->{VARS}->{'curseed'}=$ENV{'form.curseed'}; 1444: } 1445: if (!$helper->{VARS}->{'probstatus'} && $ENV{'form.problemtype'}) { 1446: $helper->{VARS}->{'probstatus'}=$ENV{'form.problemtype'}; 1447: } 1448: 1449: my $userCanSeeHidden = Apache::lonnavmaps::advancedUser(); 1450: my $userPriviledged = ($ENV{'request.role'}=~m/^cc\./ or 1451: $ENV{'request.role'}=~m/^in\./ or 1452: $ENV{'request.role'}=~m/^ta\./); 1453: 1454: Apache::lonhelper::registerHelperTags(); 1455: 1456: # "Delete everything after the last slash." 1457: $subdir =~ s|/[^/]+$||; 1458: if (not $helper->{VARS}->{'construction'}) { 1459: $subdir='/home/httpd/html/res/'.$subdir; 1460: } 1461: # "Remove all duplicate slashes." 1462: $subdir =~ s|/+|/|g; 1463: 1464: # What can be printed is a very dynamic decision based on 1465: # lots of factors. So we need to dynamically build this list. 1466: # To prevent security leaks, states are only added to the wizard 1467: # if they can be reached, which ensures manipulating the form input 1468: # won't allow anyone to reach states they shouldn't have permission 1469: # to reach. 1470: 1471: # printChoices is tracking the kind of printing the user can 1472: # do, and will be used in a choices construction later. 1473: # In the meantime we will be adding states and elements to 1474: # the helper by hand. 1475: my $printChoices = []; 1476: my $paramHash; 1477: 1478: if ($resourceTitle) { 1479: push @{$printChoices}, ["<b><i>$resourceTitle</i></b> (".&mt('what you just saw on the screen').")", 'current_document', 'PAGESIZE']; 1480: } 1481: 1482: # Useful filter strings 1483: my $isProblem = '($res->is_problem()||$res->contains_problem) '; 1484: $isProblem .= ' && !$res->randomout()' if !$userCanSeeHidden; 1485: my $isProblemOrMap = '$res->is_problem() || $res->contains_problem() || $res->is_sequence()'; 1486: my $isNotMap = '!$res->is_sequence()'; 1487: $isNotMap .= ' && !$res->randomout()' if !$userCanSeeHidden; 1488: my $isMap = '$res->is_map()'; 1489: my $symbFilter = '$res->symb()'; 1490: my $urlValue = '$res->src()'; 1491: 1492: $helper->declareVar('SEQUENCE'); 1493: 1494: # Useful for debugging: Dump the help vars 1495: #$r->print(Dumper($helper->{VARS})); 1496: #$r->print($map); 1497: 1498: # If we're in a sequence... 1499: if (($helper->{'VARS'}->{'construction'} ne '1') && 1500: $helper->{VARS}->{'postdata'} && 1501: $helper->{VARS}->{'assignment'}) { 1502: # Allow problems from sequence 1503: push @{$printChoices}, ["<b>".&mt('Problems')."</b> ".&mt('in')." <b><i>$sequenceTitle</i></b>", 'map_problems', 'CHOOSE_PROBLEMS']; 1504: # Allow all resources from sequence 1505: push @{$printChoices}, ["<b>".&mt('Resources')."</b> ".&mt('in')." <b><i>$sequenceTitle</i></b>", 'map_problems_pages', 'CHOOSE_PROBLEMS_HTML']; 1506: 1507: my $helperFragment = <<HELPERFRAGMENT; 1508: <state name="CHOOSE_PROBLEMS" title="Select Problem(s) to print"> 1509: <message>(mark them then click "next" button) <br /></message> 1510: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1" 1511: closeallpages="1"> 1512: <nextstate>PAGESIZE</nextstate> 1513: <filterfunc>return $isProblem;</filterfunc> 1514: <mapurl>$map</mapurl> 1515: <valuefunc>return $symbFilter;</valuefunc> 1516: </resource> 1517: </state> 1518: 1519: <state name="CHOOSE_PROBLEMS_HTML" title="Select Resource(s) to print"> 1520: <message>(mark them then click "next" button) <br /></message> 1521: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1" 1522: closeallpages="1"> 1523: <nextstate>PAGESIZE</nextstate> 1524: <filterfunc>return $isNotMap;</filterfunc> 1525: <mapurl>$map</mapurl> 1526: <valuefunc>return $symbFilter;</valuefunc> 1527: </resource> 1528: </state> 1529: HELPERFRAGMENT 1530: 1531: &Apache::lonxml::xmlparse($r, 'helper', $helperFragment); 1532: } 1533: 1534: # If the user is priviledged, allow them to print all 1535: # problems in the course, optionally for selected students 1536: if ($userPriviledged && ($helper->{VARS}->{'postdata'}=~/\/res\//)) { 1537: push @{$printChoices}, ['<b>Problems</b> from <b>entire course</b>', 'all_problems', 'ALL_PROBLEMS']; 1538: &Apache::lonxml::xmlparse($r, 'helper', <<ALL_PROBLEMS); 1539: <state name="ALL_PROBLEMS" title="Select Problem(s) to print"> 1540: <message>(mark them then click "next" button) <br /></message> 1541: <resource variable="RESOURCES" toponly='0' multichoice="1" 1542: suppressEmptySequences='0' addstatus="1" closeallpages="1"> 1543: <nextstate>PAGESIZE</nextstate> 1544: <filterfunc>return $isProblemOrMap;</filterfunc> 1545: <choicefunc>return $isNotMap;</choicefunc> 1546: <valuefunc>return $symbFilter;</valuefunc> 1547: </resource> 1548: </state> 1549: ALL_PROBLEMS 1550: 1551: if ($helper->{VARS}->{'assignment'}) { 1552: 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']; 1553: 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']; 1554: } 1555: my $resource_selector=<<RESOURCE_SELECTOR; 1556: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message> 1557: <resource variable="RESOURCES" multichoice="1" addstatus="1" 1558: closeallpages="1"> 1559: <filterfunc>return $isProblem;</filterfunc> 1560: <mapurl>$map</mapurl> 1561: <valuefunc>return $symbFilter;</valuefunc> 1562: </resource> 1563: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message> 1564: <choices variable="EMPTY_PAGES"> 1565: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice> 1566: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice> 1567: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice> 1568: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice> 1569: </choices> 1570: <message><hr width='33%' /><b>Number of assignments printed at the same time: </b></message> 1571: <string variable="NUMBER_TO_PRINT" maxlength="5" size="5"><defaultvalue>"all"</defaultvalue></string> 1572: RESOURCE_SELECTOR 1573: 1574: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS); 1575: <state name="CHOOSE_STUDENTS" title="Select Students and Resources"> 1576: <student multichoice='1' variable="STUDENTS" nextstate="PAGESIZE" /> 1577: $resource_selector 1578: </state> 1579: CHOOSE_STUDENTS 1580: 1581: my $cdom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; 1582: my $cnum = $ENV{'course.'.$ENV{'request.course.id'}.'.num'}; 1583: my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum); 1584: my $namechoice='<choice></choice>'; 1585: foreach my $name (@names) { 1586: $namechoice.='<choice computer="'.$name.'">'.$name.'</choice>'; 1587: } 1588: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON1); 1589: <state name="CHOOSE_ANON1" title="Select Students and Resources"> 1590: <nextstate>PAGESIZE</nextstate> 1591: <message><hr width='33%' /><b>Number of anonymous assignments to print?</b></message> 1592: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5"></string> 1593: <message><br /><b>Names to store the CODEs under for later:</b></message> 1594: <string variable="ANON_CODE_STORAGE_NAME" maxlength="50" size="20" /> 1595: <message><hr width='33%' /></message> 1596: <message><b>Reprint a set of saved CODEs:</b></message> 1597: <dropdown variable="REUSE_OLD_CODES"> 1598: $namechoice 1599: </dropdown> 1600: <message><hr width='33%' /></message> 1601: $resource_selector 1602: </state> 1603: CHOOSE_ANON1 1604: 1605: 1606: if ($helper->{VARS}->{'assignment'}) { 1607: 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']; 1608: 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']; 1609: } 1610: 1611: 1612: $resource_selector=<<RESOURCE_SELECTOR; 1613: <message><br /><big><i><b>Select resources for the assignment</b></i></big><br /></message> 1614: <resource variable="RESOURCES" multichoice="1" addstatus="1" 1615: closeallpages="1"> 1616: <filterfunc>return $isNotMap;</filterfunc> 1617: <mapurl>$map</mapurl> 1618: <valuefunc>return $symbFilter;</valuefunc> 1619: </resource> 1620: <message><br /><big><i><b>How should the results be printed?</b></i></big><br /></message> 1621: <choices variable="EMPTY_PAGES"> 1622: <choice computer='0'>Start each student\'s assignment on a new page/column (add a pagefeed after each assignment)</choice> 1623: <choice computer='1'>Add one empty page/column after each student\'s assignment</choice> 1624: <choice computer='2'>Add two empty pages/column after each student\'s assignment</choice> 1625: <choice computer='3'>Add three empty pages/column after each student\'s assignment</choice> 1626: </choices> 1627: <message><hr width='33%' /><b>Number of assignments printed at the same time: </b></message> 1628: <string variable="NUMBER_TO_PRINT" maxlength="5" size="5"><defaultvalue>"all"</defaultvalue></string> 1629: RESOURCE_SELECTOR 1630: 1631: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_STUDENTS1); 1632: <state name="CHOOSE_STUDENTS1" title="Select Students and Resources"> 1633: <student multichoice='1' variable="STUDENTS" nextstate="PAGESIZE" /> 1634: $resource_selector 1635: </state> 1636: CHOOSE_STUDENTS1 1637: 1638: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_ANON2); 1639: <state name="CHOOSE_ANON2" title="Select Students and Resources"> 1640: <message><hr width='33%' /><b>How many Anonymous exams to print?</b></message> 1641: <string variable="NUMBER_TO_PRINT_TOTAL" maxlength="5" size="5"></string> 1642: <message><hr width='33%' /></message> 1643: $resource_selector 1644: </state> 1645: CHOOSE_ANON2 1646: } 1647: 1648: # FIXME: That RE should come from a library somewhere. 1649: 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 $ENV{'request.role.adv'} and $subdir ne '/home/httpd/html/res/') { 1650: push @{$printChoices}, ["<b>".&mt('Problems')."</b> ".&mt('from current subdirectory')." <b><i>$subdir</i></b>", 'problems_from_directory', 'CHOOSE_FROM_SUBDIR']; 1651: 1652: my $f = '$filename'; 1653: my $xmlfrag = <<CHOOSE_FROM_SUBDIR; 1654: <state name="CHOOSE_FROM_SUBDIR" title="Select File(s) from <b><small>$subdir</small></b> to print"> 1655: <message>(mark them then click "next" button) <br /></message> 1656: <files variable="FILES" multichoice='1'> 1657: <nextstate>PAGESIZE</nextstate> 1658: <filechoice>return '$subdir';</filechoice> 1659: CHOOSE_FROM_SUBDIR 1660: 1661: # this is broken up because I really want interpolation above, 1662: # and I really DON'T want it below 1663: $xmlfrag .= <<'CHOOSE_FROM_SUBDIR'; 1664: <filefilter>return Apache::lonhelper::files::not_old_version($filename) && 1665: $filename =~ m/\.(problem|exam|quiz|assess|survey|form|library)$/; 1666: </filefilter> 1667: </files> 1668: </state> 1669: CHOOSE_FROM_SUBDIR 1670: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag); 1671: } 1672: 1673: # Allow the user to select any sequence in the course, feed it to 1674: # another resource selector for that sequence 1675: if (!$helper->{VARS}->{'construction'}) { 1676: push @$printChoices, ["<b>Resources</b> from <b>selected sequence</b> in course", 1677: 'select_sequences', 'CHOOSE_SEQUENCE']; 1678: my $escapedSequenceName = $helper->{VARS}->{'SEQUENCE'}; 1679: #Escape apostrophes and backslashes for Perl 1680: $escapedSequenceName =~ s/\\/\\\\/g; 1681: $escapedSequenceName =~ s/'/\\'/g; 1682: &Apache::lonxml::xmlparse($r, 'helper', <<CHOOSE_FROM_ANY_SEQUENCE); 1683: <state name="CHOOSE_SEQUENCE" title="Select Sequence To Print From"> 1684: <message>Select the sequence to print resources from:</message> 1685: <resource variable="SEQUENCE"> 1686: <nextstate>CHOOSE_FROM_ANY_SEQUENCE</nextstate> 1687: <filterfunc>return \$res->is_sequence;</filterfunc> 1688: <valuefunc>return $urlValue;</valuefunc> 1689: </resource> 1690: </state> 1691: <state name="CHOOSE_FROM_ANY_SEQUENCE" title="Select Resources To Print"> 1692: <message>(mark desired resources then click "next" button) <br /></message> 1693: <resource variable="RESOURCES" multichoice="1" toponly='1' addstatus="1" 1694: closeallpages="1"> 1695: <nextstate>PAGESIZE</nextstate> 1696: <filterfunc>return $isProblem</filterfunc> 1697: <mapurl evaluate='1'>return '$escapedSequenceName';</mapurl> 1698: <valuefunc>return $symbFilter;</valuefunc> 1699: </resource> 1700: </state> 1701: CHOOSE_FROM_ANY_SEQUENCE 1702: } 1703: 1704: # Generate the first state, to select which resources get printed. 1705: Apache::lonhelper::state->new("START", "Select Printing Options:"); 1706: $paramHash = Apache::lonhelper::getParamHash(); 1707: $paramHash->{MESSAGE_TEXT} = ""; 1708: Apache::lonhelper::message->new(); 1709: $paramHash = Apache::lonhelper::getParamHash(); 1710: $paramHash->{'variable'} = 'PRINT_TYPE'; 1711: $helper->declareVar('PRINT_TYPE'); 1712: $paramHash->{CHOICES} = $printChoices; 1713: Apache::lonhelper::choices->new(); 1714: 1715: my $startedTable = 0; # have we started an HTML table yet? (need 1716: # to close it later) 1717: 1718: if (($ENV{'request.role.adv'} and &Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) or 1719: ($helper->{VARS}->{'construction'} eq '1')) { 1720: addMessage("<hr width='33%' /><table><tr><td align='right'>Print: </td><td>"); 1721: $paramHash = Apache::lonhelper::getParamHash(); 1722: $paramHash->{'variable'} = 'ANSWER_TYPE'; 1723: $helper->declareVar('ANSWER_TYPE'); 1724: $paramHash->{CHOICES} = [ 1725: ['Without Answers', 'yes'], 1726: ['With Answers', 'no'], 1727: ['Only Answers', 'only'], 1728: ['As Exam Problem', 'exam'] 1729: ]; 1730: Apache::lonhelper::dropdown->new(); 1731: addMessage("</td></tr>"); 1732: $startedTable = 1; 1733: } 1734: 1735: if ($ENV{'request.role.adv'}) { 1736: if (!$startedTable) { 1737: addMessage("<hr width='33%' /><table><tr><td align='right'>LaTeX mode: </td><td>"); 1738: $startedTable = 1; 1739: } else { 1740: addMessage("<tr><td align='right'>LaTeX mode: </td><td>"); 1741: } 1742: $paramHash = Apache::lonhelper::getParamHash(); 1743: $paramHash->{'variable'} = 'LATEX_TYPE'; 1744: $helper->declareVar('LATEX_TYPE'); 1745: if ($helper->{VARS}->{'construction'} eq '1') { 1746: $paramHash->{CHOICES} = [ 1747: ['standard LaTeX mode', 'standard'], 1748: ['LaTeX batchmode', 'batchmode'], ]; 1749: } else { 1750: $paramHash->{CHOICES} = [ 1751: ['LaTeX batchmode', 'batchmode'], 1752: ['standard LaTeX mode', 'standard'] ]; 1753: } 1754: Apache::lonhelper::dropdown->new(); 1755: 1756: addMessage("</td></tr><tr><td align='right'>Print Table of Contents: </td><td>"); 1757: $paramHash = Apache::lonhelper::getParamHash(); 1758: $paramHash->{'variable'} = 'TABLE_CONTENTS'; 1759: $helper->declareVar('TABLE_CONTENTS'); 1760: $paramHash->{CHOICES} = [ 1761: ['No', 'no'], 1762: ['Yes', 'yes'] ]; 1763: Apache::lonhelper::dropdown->new(); 1764: addMessage("</td></tr>"); 1765: 1766: if (not $helper->{VARS}->{'construction'}) { 1767: addMessage("<tr><td align='right'>Print Index: </td><td>"); 1768: $paramHash = Apache::lonhelper::getParamHash(); 1769: $paramHash->{'variable'} = 'TABLE_INDEX'; 1770: $helper->declareVar('TABLE_INDEX'); 1771: $paramHash->{CHOICES} = [ 1772: ['No', 'no'], 1773: ['Yes', 'yes'] ]; 1774: Apache::lonhelper::dropdown->new(); 1775: addMessage("</td></tr>"); 1776: } 1777: 1778: if ($helper->{'VARS'}->{'construction'}) { 1779: my $stylevalue=$ENV{'construct.style'}; 1780: my $xmlfrag .= <<"RNDSEED"; 1781: <message><tr><td align='right'>Use random seed: </td><td></message> 1782: <string variable="curseed" size="15" maxlength="15"> 1783: <defaultvalue> 1784: return $helper->{VARS}->{'curseed'}; 1785: </defaultvalue> 1786: </string> 1787: <message></td></tr><tr><td align="right">Use style file:</td><td></message> 1788: <message><input type="text" size="40" name="style_file_value" value="$stylevalue" /> <a href="javascript:openbrowser('helpform','style_file','sty')">Select style file</a> </td><td></message> 1789: <message></td></tr></message> 1790: RNDSEED 1791: &Apache::lonxml::xmlparse($r, 'helper', $xmlfrag); 1792: $helper->{'VARS'}->{'style_file'}=$ENV{'form.style_file_value'}; 1793: } 1794: } 1795: 1796: 1797: 1798: 1799: if ($startedTable) { 1800: addMessage("</table>"); 1801: } 1802: 1803: Apache::lonprintout::page_format_state->new("FORMAT"); 1804: 1805: # Generate the PAGESIZE state which will offer the user the margin 1806: # choices if they select one column 1807: Apache::lonhelper::state->new("PAGESIZE", "Set Margins"); 1808: Apache::lonprintout::page_size_state->new('pagesize', 'FORMAT', 'FINAL'); 1809: 1810: 1811: $helper->process(); 1812: 1813: # MANUAL BAILOUT CONDITION: 1814: # If we're in the "final" state, bailout and return to handler 1815: if ($helper->{STATE} eq 'FINAL') { 1816: return $helper; 1817: } 1818: 1819: $r->print($helper->display()); 1820: 1821: Apache::lonhelper::unregisterHelperTags(); 1822: 1823: untie %hash; 1824: 1825: return OK; 1826: } 1827: 1828: 1829: 1; 1830: 1831: package Apache::lonprintout::page_format_state; 1832: 1833: =pod 1834: 1835: =head1 Helper element: page_format_state 1836: 1837: See lonhelper.pm documentation for discussion of the helper framework. 1838: 1839: Apache::lonprintout::page_format_state is an element that gives the 1840: user an opportunity to select the page layout they wish to print 1841: with: Number of columns, portrait/landscape, and paper size. If you 1842: want to change the paper size choices, change the @paperSize array 1843: contents in this package. 1844: 1845: page_format_state is always directly invoked in lonprintout.pm, so there 1846: is no tag interface. You actually pass parameters to the constructor. 1847: 1848: =over 4 1849: 1850: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME. 1851: 1852: =back 1853: 1854: =cut 1855: 1856: use Apache::lonhelper; 1857: 1858: no strict; 1859: @ISA = ("Apache::lonhelper::element"); 1860: use strict; 1861: use Apache::lonlocal; 1862: 1863: my $maxColumns = 2; 1864: my @paperSize = ("Letter [8 1/2x11 in]", "Legal [8 1/2x14 in]", 1865: "Ledger/Tabloid [11x17 in]", "Executive [7 1/2x10 in]", 1866: "A2 [420x594 mm]", "A3 [297x420 mm]", "A4 [210x297 mm]", 1867: "A5 [148x210 mm]", "A6 [105x148 mm]" ); 1868: 1869: # Tentative format: Orientation (L = Landscape, P = portrait) | Colnum | 1870: # Paper type 1871: 1872: sub new { 1873: my $self = Apache::lonhelper::element->new(); 1874: 1875: shift; 1876: 1877: $self->{'variable'} = shift; 1878: my $helper = Apache::lonhelper::getHelper(); 1879: $helper->declareVar($self->{'variable'}); 1880: bless($self); 1881: return $self; 1882: } 1883: 1884: sub render { 1885: my $self = shift; 1886: my $helper = Apache::lonhelper::getHelper(); 1887: my $result = ''; 1888: my $var = $self->{'variable'}; 1889: my $PageLayout=&mt('Page layout'); 1890: my $NumberOfColumns=&mt('Number of columns'); 1891: my $PaperType=&mt('Paper type'); 1892: $result .= <<STATEHTML; 1893: 1894: <hr width="33%" /> 1895: <table cellpadding="3"> 1896: <tr> 1897: <td align="center"><b>$PageLayout</b></td> 1898: <td align="center"><b>$NumberOfColumns</b></td> 1899: <td align="center"><b>$PaperType</b></td> 1900: </tr> 1901: <tr> 1902: <td> 1903: <input type="radio" name="${var}.layout" value="L" /> Landscape<br /> 1904: <input type="radio" name="${var}.layout" value="P" checked='1' /> Portrait 1905: </td> 1906: <td align="center"> 1907: <select name="${var}.cols"> 1908: STATEHTML 1909: 1910: my $i; 1911: for ($i = 1; $i <= $maxColumns; $i++) { 1912: if ($i == 2) { 1913: $result .= "<option value='$i' selected>$i</option>\n"; 1914: } else { 1915: $result .= "<option value='$i'>$i</option>\n"; 1916: } 1917: } 1918: 1919: $result .= "</select></td><td>\n"; 1920: $result .= "<select name='${var}.paper'>\n"; 1921: 1922: $i = 0; 1923: foreach (@paperSize) { 1924: if ($i == 0) { 1925: $result .= "<option selected value='$i'>" . $paperSize[$i] . "</option>\n"; 1926: } else { 1927: $result .= "<option value='$i'>" . $paperSize[$i] . "</option>\n"; 1928: } 1929: $i++; 1930: } 1931: 1932: $result .= "</select></td></tr></table>"; 1933: return $result; 1934: } 1935: 1936: sub postprocess { 1937: my $self = shift; 1938: 1939: my $var = $self->{'variable'}; 1940: my $helper = Apache::lonhelper->getHelper(); 1941: $helper->{VARS}->{$var} = 1942: $ENV{"form.$var.layout"} . '|' . $ENV{"form.$var.cols"} . '|' . 1943: $ENV{"form.$var.paper"}; 1944: return 1; 1945: } 1946: 1947: 1; 1948: 1949: package Apache::lonprintout::page_size_state; 1950: 1951: =pod 1952: 1953: =head1 Helper element: page_size_state 1954: 1955: See lonhelper.pm documentation for discussion of the helper framework. 1956: 1957: Apache::lonprintout::page_size_state is an element that gives the 1958: user the opportunity to further refine the page settings if they 1959: select a single-column page. 1960: 1961: page_size_state is always directly invoked in lonprintout.pm, so there 1962: is no tag interface. You actually pass parameters to the constructor. 1963: 1964: =over 4 1965: 1966: =item * B<new>(varName): varName is where the print information will be stored in the format FIXME. 1967: 1968: =back 1969: 1970: =cut 1971: 1972: use Apache::lonhelper; 1973: 1974: no strict; 1975: @ISA = ("Apache::lonhelper::element"); 1976: use strict; 1977: 1978: 1979: 1980: sub new { 1981: my $self = Apache::lonhelper::element->new(); 1982: 1983: shift; # disturbs me (probably prevents subclassing) but works (drops 1984: # package descriptor)... - Jeremy 1985: 1986: $self->{'variable'} = shift; 1987: my $helper = Apache::lonhelper::getHelper(); 1988: $helper->declareVar($self->{'variable'}); 1989: 1990: # The variable name of the format element, so we can look into 1991: # $helper->{VARS} to figure out whether the columns are one or two 1992: $self->{'formatvar'} = shift; 1993: 1994: # The state to transition to after selection, or after discovering 1995: # the cols are not set to 1 1996: $self->{NEXTSTATE} = shift; 1997: bless($self); 1998: return $self; 1999: } 2000: 2001: sub render { 2002: my $self = shift; 2003: my $helper = Apache::lonhelper::getHelper(); 2004: my $result = ''; 2005: my $var = $self->{'variable'}; 2006: 2007: if (defined $self->{ERROR_MSG}) { 2008: $result .= '<br /><font color="#FF0000">' . $self->{ERROR_MSG} . '</font><br />'; 2009: } 2010: 2011: $result .= <<ELEMENTHTML; 2012: 2013: <p>How should the column be formatted?</p> 2014: 2015: <table cellpadding='3'> 2016: <tr> 2017: <td align='right'><b>Width</b>:</td> 2018: <td align='left'><input type='text' name='$var.width' value='18' size='4'></td> 2019: <td align='left'> 2020: <select name='$var.widthunit'> 2021: <option>cm</option><option>in</option> 2022: </select> 2023: </td> 2024: </tr> 2025: <tr> 2026: <td align='right'><b>Height</b>:</td> 2027: <td align='left'><input type='text' name="$var.height" value="25.9" size='4'></td> 2028: <td align='left'> 2029: <select name='$var.heightunit'> 2030: <option>cm</option><option>in</option> 2031: </select> 2032: </td> 2033: </tr> 2034: <tr> 2035: <td align='right'><b>Left margin</b>:</td> 2036: <td align='left'><input type='text' name='$var.lmargin' value='-1.5' size='4'></td> 2037: <td align='left'> 2038: <select name='$var.lmarginunit'> 2039: <option>cm</option><option>in</option> 2040: </select> 2041: </td> 2042: </tr> 2043: </table> 2044: 2045: <p>Hint: Some instructors like to leave scratch space for the student by 2046: making the width much smaller than the width of the page.</p> 2047: 2048: ELEMENTHTML 2049: 2050: return $result; 2051: } 2052: 2053: # If the user didn't select 1 column, skip this state. 2054: sub preprocess { 2055: my $self = shift; 2056: my $helper = Apache::lonhelper::getHelper(); 2057: 2058: my $format = $helper->{VARS}->{$self->{'formatvar'}}; 2059: if (substr($format, 2, 1) ne '1') { 2060: $helper->changeState($self->{NEXTSTATE}); 2061: } 2062: 2063: return 1; 2064: } 2065: 2066: sub postprocess { 2067: my $self = shift; 2068: 2069: my $var = $self->{'variable'}; 2070: my $helper = Apache::lonhelper->getHelper(); 2071: my $width = $helper->{VARS}->{$var .'.width'} = $ENV{"form.${var}.width"}; 2072: my $height = $helper->{VARS}->{$var .'.height'} = $ENV{"form.${var}.height"}; 2073: my $lmargin = $helper->{VARS}->{$var .'.lmargin'} = $ENV{"form.${var}.lmargin"}; 2074: $helper->{VARS}->{$var .'.widthunit'} = $ENV{"form.${var}.widthunit"}; 2075: $helper->{VARS}->{$var .'.heightunit'} = $ENV{"form.${var}.heightunit"}; 2076: $helper->{VARS}->{$var .'.lmarginunit'} = $ENV{"form.${var}.lmarginunit"}; 2077: 2078: my $error = ''; 2079: 2080: # /^-?[0-9]+(\.[0-9]*)?$/ -> optional minus, at least on digit, followed 2081: # by an optional period, followed by digits, ending the string 2082: 2083: if ($width !~ /^-?[0-9]+(\.[0-9]*)?$/) { 2084: $error .= "Invalid width; please type only a number.<br />\n"; 2085: } 2086: if ($height !~ /^-?[0-9]+(\.[0-9]*)?$/) { 2087: $error .= "Invalid height; please type only a number.<br />\n"; 2088: } 2089: if ($lmargin !~ /^-?[0-9]+(\.[0-9]*)?$/) { 2090: $error .= "Invalid left margin; please type only a number.<br />\n"; 2091: } 2092: 2093: if (!$error) { 2094: Apache::lonhelper::getHelper()->changeState($self->{NEXTSTATE}); 2095: return 1; 2096: } else { 2097: $self->{ERROR_MSG} = $error; 2098: return 0; 2099: } 2100: } 2101: 2102: 2103: 2104: __END__ 2105: