Annotation of loncom/homework/imageresponse.pm, revision 1.20
1.12 albertel 1: # The LearningOnline Network with CAPA
1.14 albertel 2: # image click response style
3: #
1.20 ! albertel 4: # $Id: imageresponse.pm,v 1.19 2002/07/23 14:41:06 sakharuk Exp $
1.14 albertel 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: #
1.1 albertel 28:
1.12 albertel 29: #FIXME assumes multiple possbile submissions but only one is possible currently
1.3 albertel 30:
1.1 albertel 31: package Apache::imageresponse;
32: use strict;
33:
1.16 harris41 34: BEGIN {
1.12 albertel 35: &Apache::lonxml::register('Apache::imageresponse',('imageresponse'));
1.1 albertel 36: }
37:
38: sub start_imageresponse {
1.12 albertel 39: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.13 albertel 40: my $result;
1.12 albertel 41: #when in a radiobutton response use these
42: &Apache::lonxml::register('Apache::imageresponse',('foilgroup','foil','text','image','rectangle','conceptgroup'));
43: push (@Apache::lonxml::namespace,'imageresponse');
44: my $id = &Apache::response::start_response($parstack,$safeeval);
1.13 albertel 45: if ($target eq 'meta') {
46: $result=&Apache::response::meta_package_write('imageresponse');
47: }
48: return $result;
1.1 albertel 49: }
50:
51: sub end_imageresponse {
1.12 albertel 52: &Apache::response::end_response;
53: pop @Apache::lonxml::namespace;
1.15 albertel 54: &Apache::lonxml::deregister('Apache::imageresponse',('foilgroup','foil','text','image','rectangle','conceptgroup'));
1.12 albertel 55: return '';
1.1 albertel 56: }
57:
1.20 ! albertel 58: %Apache::response::foilgroup=();
1.1 albertel 59: sub start_foilgroup {
1.20 ! albertel 60: %Apache::response::foilgroup=();
1.12 albertel 61: $Apache::imageresponse::conceptgroup=0;
62: &Apache::response::setrandomnumber();
63: return '';
1.1 albertel 64: }
65:
1.2 albertel 66: sub getfoilcounts {
1.12 albertel 67: my ($parstack,$safeeval)=@_;
68:
69: my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,'-2');
70: # +1 since instructors will count from 1
71: my $count = $#{ $Apache::response::foilgroup{'names'} }+1;
1.18 albertel 72: if (&Apache::response::showallfoils()) { $max=$count; }
1.12 albertel 73: return ($count,$max);
1.2 albertel 74: }
75:
76: sub whichfoils {
1.12 albertel 77: my ($max)=@_;
78: if (!defined(@{ $Apache::response::foilgroup{'names'} })) { return; }
79: my @names = @{ $Apache::response::foilgroup{'names'} };
80: my @whichopt =();
81: while ((($#whichopt+1) < $max) && ($#names > -1)) {
82: &Apache::lonxml::debug("Have $#whichopt max is $max");
1.18 albertel 83: my $aopt;
84: if (&Apache::response::showallfoils()) {
85: $aopt=0;
86: } else {
87: $aopt=int(rand($#names+1));
88: }
1.12 albertel 89: &Apache::lonxml::debug("From $#names elms, picking $aopt");
90: $aopt=splice(@names,$aopt,1);
91: &Apache::lonxml::debug("Picked $aopt");
92: push (@whichopt,$aopt);
93: }
94: return @whichopt;
1.2 albertel 95: }
96:
97: sub displayfoils {
1.12 albertel 98: my (@whichopt) = @_;
99: my $result ='';
100: my $name;
101: my $temp=1;
102: foreach $name (@whichopt) {
103: $result.=$Apache::response::foilgroup{"$name.text"}."<br />\n";
104: my $image=$Apache::response::foilgroup{"$name.image"};
105: if ($Apache::lonhomework::history{"resource.$Apache::inputtags::part.solved"} =~ /^correct/ ) {
106: $result.="<img src=\"$image\"/> <br />\n";
107: } else {
108: $result.="<input type=\"image\" name=\"HWVAL_$Apache::inputtags::response['-1']:$temp\" src=\"$image\"/> <br />\n";
109: }
110: $temp++;
111: }
112: return $result;
1.2 albertel 113: }
114:
1.3 albertel 115: sub gradefoils {
1.12 albertel 116: my (@whichopt) = @_;
117: my $x;
118: my $y;
119: my $result;
120: my $id=$Apache::inputtags::response['-1'];
121: my $temp=1;
122: foreach my $name (@whichopt) {
123: $x=$ENV{"form.HWVAL_$id:$temp.x"};
124: $y=$ENV{"form.HWVAL_$id:$temp.y"};
125: &Apache::lonxml::debug("Got a x of $x and a y of $y for $name");
126: if (defined(@{ $Apache::response::foilgroup{"$name.area"} })) {
127: my @areas = @{ $Apache::response::foilgroup{"$name.area"} };
128: my $grade="INCORRECT";
129: foreach my $area (@areas) {
130: &Apache::lonxml::debug("Area is $area for $name");
131: $area =~ m/([a-z]*):/;
132: &Apache::lonxml::debug("Area of type $1");
133: if ($1 eq 'rectangle') {
134: $grade=&grade_rectangle($area,$x,$y);
135: } else {
136: &Apache::lonxml::error("Unknown area style $area");
1.9 albertel 137: }
1.12 albertel 138: &Apache::lonxml::debug("Area said $grade");
139: if ($grade eq 'APPROX_ANS') { last; }
140: }
141: &Apache::lonxml::debug("Foil was $grade");
142: if ($grade eq 'INCORRECT') { $result= 'INCORRECT'; }
143: if (($grade eq 'APPROX_ANS') && ($result ne 'APPROX_ANS')) { $result=$grade; }
144: &Apache::lonxml::debug("Question is $result");
145: $temp++;
146: }
147: }
148: $Apache::lonhomework::results{"resource.$Apache::inputtags::part.$id.submission"}="$x:$y";
149: $Apache::lonhomework::results{"resource.$Apache::inputtags::part.$id.awarddetail"}=$result;
150: return '';
1.3 albertel 151: }
152:
1.1 albertel 153: sub end_foilgroup {
1.12 albertel 154: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
155: my $result='';
156: my @whichopt;
157: if ($target eq 'web' || $target eq 'grade') {
158: my ($count,$max) = &getfoilcounts($parstack,$safeeval);
159: if ($count>$max) { $count=$max }
160: &Apache::lonxml::debug("Count is $count from $max");
161: @whichopt = &whichfoils($max);
162: }
163: if ($target eq 'web') {
164: $result=&displayfoils(@whichopt);
165: }
166: if ($target eq 'grade') {
167: if ( defined $ENV{'form.submitted'}) {
168: &gradefoils(@whichopt);
1.3 albertel 169: }
1.12 albertel 170: }
171: return $result;
1.1 albertel 172: }
173:
174: sub start_conceptgroup {
1.12 albertel 175: $Apache::imageresponse::conceptgroup=1;
1.20 ! albertel 176: %Apache::response::conceptgroup=();
1.12 albertel 177: return '';
1.1 albertel 178: }
179:
180: sub end_conceptgroup {
1.12 albertel 181: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
182: $Apache::imageresponse::conceptgroup=0;
183: if ($target eq 'web' || $target eq 'grade') {
184: if (defined(@{ $Apache::response::conceptgroup{'names'} })) {
185: my @names = @{ $Apache::response::conceptgroup{'names'} };
186: my $pick=int(rand($#names+1));
187: my $name=$names[$pick];
188: if (defined(@{ $Apache::response::conceptgroup{"$name.area"} })) {
189: push @{ $Apache::response::foilgroup{'names'} }, $name;
190: $Apache::response::foilgroup{"$name.text"} = $Apache::response::conceptgroup{"$name.text"};
191: $Apache::response::foilgroup{"$name.image"} = $Apache::response::conceptgroup{"$name.image"};
192: push(@{ $Apache::response::foilgroup{"$name.area"} }, @{ $Apache::response::conceptgroup{"$name.area"} });
193: my $concept = &Apache::lonxml::get_param('concept',$parstack,$safeeval);
194: $Apache::response::foilgroup{"$name.concept"} = $concept;
195: &Apache::lonxml::debug("Selecting $name in $concept");
196: }
1.9 albertel 197: }
1.12 albertel 198: }
199: return '';
1.1 albertel 200: }
201:
1.12 albertel 202: $Apache::imageresponse::curname='';
1.1 albertel 203: sub start_foil {
1.12 albertel 204: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
205: if ($target eq 'web' || $target eq 'grade') {
206: my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
207: if ($name eq '') { $name=$Apache::lonxml::curdepth; }
1.18 albertel 208: if ( $Apache::imageresponse::conceptgroup
209: && !&Apache::response::showallfoils()) {
1.12 albertel 210: push(@{ $Apache::response::conceptgroup{'names'} }, $name);
211: } else {
212: push(@{ $Apache::response::foilgroup{'names'} }, $name);
213: }
214: $Apache::imageresponse::curname=$name;
215: }
216: return '';
1.1 albertel 217: }
218:
219: sub end_foil {
1.12 albertel 220: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
221: return '';
1.1 albertel 222: }
223:
224: sub start_text {
1.12 albertel 225: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
226: if ($target eq 'web') { &Apache::lonxml::startredirection; }
227: return '';
1.1 albertel 228: }
229:
230: sub end_text {
1.12 albertel 231: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
232: if ($target eq 'web') {
233: my $name = $Apache::imageresponse::curname;
1.18 albertel 234: if ( $Apache::imageresponse::conceptgroup
235: && !&Apache::response::showallfoils() ) {
1.12 albertel 236: $Apache::response::conceptgroup{"$name.text"} = &Apache::lonxml::endredirection;
237: } else {
238: $Apache::response::foilgroup{"$name.text"} = &Apache::lonxml::endredirection;
1.7 albertel 239: }
1.12 albertel 240: }
241: return '';
1.1 albertel 242: }
243:
244: sub start_image {
1.12 albertel 245: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
1.19 sakharuk 246: if ($target eq 'web' || $target eq 'tex') { &Apache::lonxml::startredirection; }
1.12 albertel 247: return '';
1.1 albertel 248: }
249:
250: sub end_image {
1.19 sakharuk 251: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
252: my $currentstring = '';
1.12 albertel 253: if ($target eq 'web') {
254: my $name = $Apache::imageresponse::curname;
255: my $image = &Apache::lonxml::endredirection;
256: &Apache::lonxml::debug("out is $image");
1.18 albertel 257: if ( $Apache::imageresponse::conceptgroup
258: && !&Apache::response::showallfoils()) {
1.12 albertel 259: $Apache::response::conceptgroup{"$name.image"} = $image;
260: } else {
261: $Apache::response::foilgroup{"$name.image"} = $image;
1.7 albertel 262: }
1.19 sakharuk 263: } elsif ($target eq 'tex') {
264: my $src = &Apache::lonxml::endredirection;
265: $src=&Apache::lonnet::filelocation($Apache::lonxml::pwd[-1],$src);
266: my $width_param = '';
267: my $height_param = '';
268: my $scaling = .3;
269: my $image = Image::Magick->new;
270: my $current_figure = $image->Read($src);
271: $width_param = $image->Get('width') * $scaling;;
272: $height_param = $image->Get('height') * $scaling;;
273: undef $image;
274: my $epssrc = $src;
275: $epssrc =~ s/(\.gif|\.jpg)$/\.eps/i;
276: if (not -e $epssrc) {
277: my $localfile = $epssrc;
278: $localfile =~ s/.*(\/res)/$1/;
279: my $file;
280: my $path;
281: if ($localfile =~ m!(.*)/([^/]*)$!) {
282: $file = $2;
283: $path = $1.'/';
284: }
285: my $signal_eps = 0;
286: my @content_directory = &Apache::lonnet::dirlist($path);
287: for (my $iy=0;$iy<=$#content_directory;$iy++) {
288: my @tempo_array = split(/&/,$content_directory[$iy]);
289: $content_directory[$iy] = $tempo_array[0];
290: if ($file eq $tempo_array[0]) {
291: $signal_eps = 1;
292: last;
293: }
294: }
295: if ($signal_eps) {
296: my $eps_file = &Apache::lonnet::getfile($localfile);
297: } else {
298: $localfile = $src;
299: $localfile =~ s/.*(\/res)/$1/;
300: my $as = &Apache::lonnet::getfile($src);
301: }
302: }
303: my $file;
304: my $path;
305: if ($src =~ m!(.*)/([^/]*)$!) {
306: $file = $2;
307: $path = $1.'/';
308: }
309: my $newsrc = $src;
310: $newsrc =~ s/(\.gif|\.jpg)$/\.eps/i;
311: $file=~s/(\.gif|\.jpg)$/\.eps/i;
312: #do we have any specified size of the picture?
313: my $TeXwidth = &Apache::lonxml::get_param('TeXwidth',$parstack,$safeeval);
314: my $TeXheight = &Apache::lonxml::get_param('TeXheight',$parstack,$safeeval);
315: my $width = &Apache::lonxml::get_param('width',$parstack,$safeeval);
316: if ($TeXwidth ne '') {
317: $width_param = $TeXwidth;
318: } elsif ($TeXheight ne '') {
319: $width_param = $TeXheight/$height_param*$width_param;
320: } elsif ($width ne '') {
321: $width_param = $width*$scaling;
322: }
323: #where can we find the picture?
324: if (-e $newsrc) {
325: if ($path) {
326: $currentstring .= '\vskip 0 mm \noindent\graphicspath{{'.$path.'}}\fbox{\includegraphics[width='.$width_param.' mm]{'.$file.'}} ';
327: }
328: } else {
329: my $temp_file;
330: my $filename = "/home/httpd/prtspool/$ENV{'user.name'}_$ENV{'user.domain'}_printout.dat";
331: $temp_file = Apache::File->new('>>'.$filename);
332: print $temp_file "$src\n";
333: $currentstring .= '\vskip 0 mm \graphicspath{{/home/httpd/prtspool/}}\fbox{\includegraphics[width='.$width_param.' mm]{'.$file.'}} ';
334: }
335: }
336: return $currentstring;
1.1 albertel 337: }
338:
339: sub start_rectangle {
1.12 albertel 340: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
341: if ($target eq 'web' || $target eq 'grade') { &Apache::lonxml::startredirection; }
342: return '';
1.1 albertel 343: }
344:
1.3 albertel 345: sub grade_rectangle {
1.12 albertel 346: my ($spec,$x,$y) = @_;
347: &Apache::lonxml::debug("Spec is $spec");
348: $spec=~m/rectangle:\(([0-9]+),([0-9]+)\)\-\(([0-9]+),([0-9]+)\)/;
349: my $x1=$1;
350: my $y1=$2;
351: my $x2=$3;
352: my $y2=$4;
353: &Apache::lonxml::debug("Point $x1,$y1,$x2,$y2");
354: if ($x1 > $x2) { my $temp=$x1;$x1=$x2;$x2=$temp; }
355: if ($y1 > $y2) { my $temp=$y1;$y1=$y2;$y2=$temp; }
1.17 albertel 356: if (($x >= $x1) && ($x <= $x2) && ($y >= $y1) && ($y <= $y2)) {
357: return 'APPROX_ANS';
358: }
1.12 albertel 359: return 'INCORRECT';
1.3 albertel 360: }
361:
1.1 albertel 362: sub end_rectangle {
1.12 albertel 363: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
364: if ($target eq 'web' || $target eq 'grade') {
365: my $name = $Apache::imageresponse::curname;
366: my $area = &Apache::lonxml::endredirection;
367: &Apache::lonxml::debug("out is $area for $name");
1.18 albertel 368: if ( $Apache::imageresponse::conceptgroup
369: && !&Apache::response::showallfoils()) {
1.12 albertel 370: push @{ $Apache::response::conceptgroup{"$name.area"} },"rectangle:$area";
371: } else {
372: push @{ $Apache::response::foilgroup{"$name.area"} },"rectangle:$area";
1.7 albertel 373: }
1.12 albertel 374: }
375: return '';
1.1 albertel 376: }
377: 1;
378: __END__
379:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>