Annotation of loncom/homework/matchresponse.pm, revision 1.44
1.1 albertel 1: # The LearningOnline Network with CAPA
2: # Full matching style response
3: #
1.44 ! sakharuk 4: # $Id: matchresponse.pm,v 1.43 2004/07/08 17:45:28 sakharuk Exp $
1.1 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: #
28:
29: package Apache::matchresponse;
30: use strict;
31: use HTML::Entities();
32: use Math::Random();
1.37 albertel 33: use Apache::optionresponse();
34: use Apache::lonlocal;
1.6 sakharuk 35:
1.1 albertel 36: BEGIN {
37: &Apache::lonxml::register('Apache::matchresponse',('matchresponse'));
38: }
39:
40: sub start_matchresponse {
41: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
42: my $result;
43: #when in a matchresponse use these
44: &Apache::lonxml::register('Apache::matchresponse',
45: ('foilgroup','foil','conceptgroup','item',
46: 'itemgroup'));
47: push (@Apache::lonxml::namespace,'matchresponse');
48: my $id = &Apache::response::start_response($parstack,$safeeval);
49: %Apache::hint::match=();
1.37 albertel 50: undef(%Apache::response::foilnames);
1.1 albertel 51: if ($target eq 'meta') {
52: $result=&Apache::response::meta_package_write('matchresponse');
53: } elsif ($target eq 'edit' ) {
54: $result.=&Apache::edit::start_table($token).
55: '<tr><td>'.&Apache::lonxml::description($token)."</td><td>Delete:".
56: &Apache::edit::deletelist($target,$token)
57: ."</td><td> ".&Apache::edit::end_row()
58: .&Apache::edit::start_spanning_row();
59:
60: $result.=
61: &Apache::edit::text_arg('Max Number Of Shown Foils:','max',$token,'4').
62: &Apache::edit::select_arg('Randomize Foil Order','randomize',
63: ['yes','no'],$token).
64: &Apache::edit::end_row().&Apache::edit::start_spanning_row()."\n";
65: } elsif ($target eq 'modified') {
66: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
67: $safeeval,'max',
68: 'randomize');
69: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
1.28 albertel 70: } elsif ($target eq 'analyze') {
71: my $part_id="$Apache::inputtags::part.$id";
72: push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id);
1.1 albertel 73: }
74: return $result;
75: }
76:
77: sub end_matchresponse {
78: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
79: my $result;
80: if ($target eq 'edit') { $result=&Apache::edit::end_table(); }
81: &Apache::response::end_response;
82: pop @Apache::lonxml::namespace;
83: &Apache::lonxml::deregister('Apache::matchresponse',
84: ('foilgroup','foil','conceptgroup'));
1.37 albertel 85: undef(%Apache::response::foilnames);
1.1 albertel 86: return $result;
87: }
88:
89: %Apache::response::itemgroup=();
90: sub start_itemgroup {
91: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
92: my $result;
93: %Apache::response::itemgroup=();
1.4 albertel 94: %Apache::matchresponse::itemtable=();
1.15 albertel 95:
1.1 albertel 96: if ($target eq 'edit') {
97: $result=&Apache::edit::tag_start($target,$token);
98: $result.=&Apache::edit::select_arg('Randomize Order:','randomize',
99: ['yes','no'],$token);
1.4 albertel 100: $result.=&Apache::edit::select_arg('Items Display Location:',
101: 'location',
102: ['top','bottom','left','right'],
103: $token);
1.1 albertel 104: $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
1.4 albertel 105: } elsif ($target eq 'modified') {
106: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
107: $safeeval,'randomize',
108: 'location');
109: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
1.21 sakharuk 110: } elsif ($target eq 'web' or $target eq 'tex') {
1.4 albertel 111: $Apache::matchresponse::itemtable{'location'}=
112: &Apache::lonxml::get_param('location',$parstack,$safeeval);
1.43 sakharuk 113: $Apache::matchresponse::TeXitemgroupwidth=&Apache::lonxml::get_param('TeXitemgroupwidth',$parstack,$safeeval,undef,0);
1.1 albertel 114: }
115: return $result;
116: }
117:
118: sub end_itemgroup {
119: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
120: my $result;
121:
1.17 albertel 122: if ($target eq 'edit') { $result=&Apache::edit::end_table(); }
1.1 albertel 123: if (!defined(@{ $Apache::response::itemgroup{'names'} })) { return; }
124: my @names=@{ $Apache::response::itemgroup{'names'} };
125: my $randomize =&Apache::lonxml::get_param('randomize',$parstack,$safeeval);
1.2 albertel 126: if ($randomize ne 'no' ) {
1.18 albertel 127: @names=&Apache::response::whichorder($#names+1,$randomize,0,
128: \%Apache::response::itemgroup);
1.1 albertel 129: }
1.30 albertel 130: if ($target eq 'analyze') {
131: my $partid="$Apache::inputtags::part.$Apache::inputtags::response[-1]";
132: push (@{ $Apache::lonhomework::analyze{"$partid.items"} }, @names);
133: }
1.1 albertel 134: my %letter_name_map;
135: my %name_letter_map;
136: my @alphabet=('A'..'Z');
137: my $i=0;
138: foreach my $name (@names) {
139: $letter_name_map{$alphabet[$i]}=$name;
140: $name_letter_map{$name}=$alphabet[$i];
141: $i++;
142: }
1.15 albertel 143: $Apache::response::itemgroup{'letter_name_map'}=\%letter_name_map;
1.1 albertel 144: $Apache::response::itemgroup{'name_letter_map'}=\%name_letter_map;
145: if ($target eq 'web') {
1.4 albertel 146: my $table='<table>';
1.1 albertel 147: my $i=0;
148: foreach my $name (@names) {
1.4 albertel 149: $table.='<tr><td>'.$alphabet[$i].'</td><td>'.
1.1 albertel 150: $Apache::response::itemgroup{$name.'.text'}.
151: '</td></tr>';
152: $i++;
153: }
1.4 albertel 154: $table.='</table>';
155: $Apache::matchresponse::itemtable{'display'}=$table;
1.5 sakharuk 156: } elsif ($target eq 'tex') {
1.39 sakharuk 157: my $table=' \begin{description}\setlength{\leftmargin}{2em}\setlength{\labelwidth}{1em}\setlength{\itemsep}{0.5pt plus1pt minus2pt}\setlength{\listparindent}{0em} ';
1.5 sakharuk 158: my $i=0;
159: foreach my $name (@names) {
1.11 sakharuk 160: $Apache::response::itemgroup{$name.'.text'}=~s/\$\$/\$/g;
1.19 sakharuk 161: $table.='\item['.$alphabet[$i].'] '.
1.21 sakharuk 162: $Apache::response::itemgroup{$name.'.text'};
1.5 sakharuk 163: $i++;
164: }
1.40 sakharuk 165: $table.=' \end{description} \strut ';
166: if ($Apache::lonhomework::type eq 'exam') {$table.='\vskip -13 mm \strut ';}
1.5 sakharuk 167: $Apache::matchresponse::itemtable{'display'}=$table;
1.17 albertel 168: }
1.1 albertel 169: return $result;
170: }
171:
172: sub start_item {
173: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
174: my $result='';
1.30 albertel 175: if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
1.1 albertel 176: &Apache::lonxml::startredirection;
177: } elsif ($target eq 'edit') {
1.3 albertel 178: my $randomize=&Apache::lonxml::get_param('randomize',$parstack,
179: $safeeval,'-2');
1.1 albertel 180: $result=&Apache::edit::tag_start($target,$token,"Item");
181: $result.=&Apache::edit::text_arg('Name:','name',$token);
1.3 albertel 182: if ($randomize ne 'no') {
183: $result.=&Apache::edit::select_arg('Location:','location',
184: ['random','top','bottom'],
185: $token);
186: }
187: $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
1.1 albertel 188: } elsif ($target eq 'modified') {
189: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
1.3 albertel 190: $safeeval,'name',
191: 'location');
1.1 albertel 192: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
193: }
194: return $result;
195: }
196:
197: sub end_item {
198: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
199: my $text ='';
200: my $result = '';
1.30 albertel 201: if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
1.1 albertel 202: $text=&Apache::lonxml::endredirection;
203: }
204: if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
1.30 albertel 205: $target eq 'edit' || $target eq 'tex' || $target eq 'analyze') {
1.1 albertel 206: my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
1.3 albertel 207: my $location=&Apache::lonxml::get_param('location',$parstack,
208: $safeeval);
1.1 albertel 209: &Apache::lonxml::debug("Got a name of :$name:");
210: if (!$name) { $name=$Apache::lonxml::curdepth; }
211: &Apache::lonxml::debug("Using a name of :$name:");
212: push @{ $Apache::response::itemgroup{'names'} }, $name;
213: $Apache::response::itemgroup{"$name.text"} = $text;
1.3 albertel 214: $Apache::response::itemgroup{"$name.location"} = $location;
1.1 albertel 215: }
216: if ($target eq 'edit') {
217: $result.= &Apache::edit::tag_end($target,$token,'');
218: }
219: return $result;
220: }
221:
222: sub insert_item {
223: return '
224: <item name="">
225: <startouttext />
226: <endouttext />
227: </item>';
228: }
229:
230: %Apache::response::foilgroup=();
231: sub start_foilgroup {
232: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
233: my $result;
234: %Apache::response::foilgroup=();
235: $Apache::matchresponse::conceptgroup=0;
1.41 albertel 236: &Apache::response::pushrandomnumber();
1.1 albertel 237: if ($target eq 'edit') {
238: $result.=&Apache::edit::start_table($token)
239: ."<tr><td>Collection Of Foils</td><td>Delete:"
240: .&Apache::edit::deletelist($target,$token)
241: ."</td><td> ".&Apache::edit::end_row()
242: .&Apache::edit::start_spanning_row()."\n";
243: }
244: return $result;
245: }
246:
247: sub end_foilgroup {
248: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
249: my $result;
1.28 albertel 250: if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' || $target eq 'tex' || $target eq 'analyze') {
1.1 albertel 251: my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,'-2');
252: my $randomize = &Apache::lonxml::get_param('randomize',$parstack,
253: $safeeval,'-2');
1.5 sakharuk 254: if ($target eq 'web' || $target eq 'tex') {
1.1 albertel 255: $result=&displayfoils($target,$max,$randomize);
256: } elsif ($target eq 'answer' ) {
257: $result=&displayanswers($max,$randomize);
258: } elsif ( $target eq 'grade') {
259: &grade_response($max,$randomize);
1.28 albertel 260: } elsif ( $target eq 'analyze') {
261: my @shown=&whichfoils($max,$randomize);
262: &Apache::response::analyze_store_foilgroup(\@shown,
1.29 albertel 263: ['text','value','location']);
1.28 albertel 264: #FIXME need to store options in some way
1.1 albertel 265: }
1.20 sakharuk 266: &Apache::lonxml::increment_counter(&getfoilcounts($max));
1.1 albertel 267: } elsif ($target eq 'edit') {
268: $result=&Apache::edit::end_table();
269: }
1.41 albertel 270: &Apache::response::poprandomnumber();
1.1 albertel 271: return $result;
1.29 albertel 272: }
273:
274: sub whichfoils {
275: my ($max,$randomize)=@_;
276: return &Apache::response::whichorder(&getfoilcounts($max),
277: $randomize,
278: &Apache::response::showallfoils(),
279: \%Apache::response::foilgroup);
1.1 albertel 280: }
281:
282: sub displayanswers {
283: my ($max,$randomize,@opt)=@_;
284: if (!defined(@{ $Apache::response::foilgroup{'names'} })) { return; }
285: my @names = @{ $Apache::response::foilgroup{'names'} };
1.18 albertel 286: my @whichfoils = &Apache::response::whichorder(&getfoilcounts($max),
287: $randomize,
288: &Apache::response::showallfoils(),
289: \%Apache::response::foilgroup);
1.1 albertel 290: my $result=&Apache::response::answer_header('matchresponse');
291: my %name_letter_map;
292: if (defined(%{ $Apache::response::itemgroup{'name_letter_map'} })) {
293: %name_letter_map=
294: %{ $Apache::response::itemgroup{'name_letter_map'} };
295: }
296: foreach my $name (@whichfoils) {
297: my $value_name=$Apache::response::foilgroup{$name.'.value'};
298: my $letter=$name_letter_map{$value_name};
299: $result.=&Apache::response::answer_part('matchresponse',$letter);
300: }
301: $result.=&Apache::response::answer_footer('matchresponse');
302: return $result;
303: }
304:
305:
306: sub grade_response {
307: my ($max,$randomize)=@_;
1.18 albertel 308: my (@whichfoils)=&Apache::response::whichorder(&getfoilcounts($max),
309: $randomize,
310: &Apache::response::showallfoils(),
311: \%Apache::response::foilgroup);
1.1 albertel 312: if (!defined($ENV{'form.submitted'})) { return; }
313: my %responsehash;
314: my %grade;
1.33 albertel 315: my ($temp,$right,$wrong,$ignored)=(1,0,0,0);
1.1 albertel 316: my %letter_name_map;
317: if (defined(%{ $Apache::response::itemgroup{'letter_name_map'} })) {
318: %letter_name_map=
319: %{ $Apache::response::itemgroup{'letter_name_map'} };
320: }
1.30 albertel 321: my @items;
1.1 albertel 322: foreach my $name (@whichfoils) {
1.34 albertel 323: my $response = &Apache::response::getresponse($temp,'letter');
1.30 albertel 324: push(@items,$response);
1.1 albertel 325: my $responsename = $letter_name_map{$response};
326: my $value=$Apache::response::foilgroup{$name.'.value'};
327: if ( $response =~ /[^\s]/) {
1.31 albertel 328: $responsehash{$name}=$responsename;
1.33 albertel 329: &Apache::lonxml::debug("submitted a $response($responsename) for $value<br />\n");
1.1 albertel 330: if ($value eq $responsename) {
331: $grade{$name}='1'; $right++;
332: } else {
333: $grade{$name}='0'; $wrong++;
334: }
335: } else {
336: $ignored++;
337: }
338: $temp++;
339: }
340: my $part=$Apache::inputtags::part;
341: my $id = $Apache::inputtags::response['-1'];
342: my $responsestr=&Apache::lonnet::hash2str(%responsehash);
1.30 albertel 343: my $itemstr =&Apache::lonnet::array2str(@items);
1.1 albertel 344: my $gradestr =&Apache::lonnet::hash2str(%grade);
1.30 albertel 345: my %previous=&Apache::response::check_for_previous($responsestr,$part,$id);
1.1 albertel 346: &Apache::lonxml::debug("Got $right right and $wrong wrong, and $ignored were ignored ");
347: $Apache::lonhomework::results{"resource.$part.$id.submission"}=
348: $responsestr;
1.30 albertel 349: $Apache::lonhomework::results{"resource.$part.$id.submissionitems"}=
350: $itemstr;
1.1 albertel 351: $Apache::lonhomework::results{"resource.$part.$id.submissiongrading"}=
352: $gradestr;
1.34 albertel 353: if (!$Apache::lonhomework::scantronmode) {
354: my $ad;
355: if ($wrong==0 && $ignored==0) {
356: $ad='EXACT_ANS';
357: } elsif ($wrong==0 && $right==0) {
358: #nothing submitted
359: } else {
360: if ($ignored==0) {
361: $ad='INCORRECT';
362: } else {
363: $ad='MISSING_ANSWER';
364: }
365: }
366: $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=$ad;
367: &Apache::response::handle_previous(\%previous,$ad);
368: } else {
369: my $ad;
370: if ($wrong==0 && $right==0) {
371: #nothing submitted
372: } else {
373: $ad='ASSIGNED_SCORE';
374: $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=
375: $ad;
376: $Apache::lonhomework::results{"resource.$part.$id.awarded"}=
1.35 albertel 377: $right/(scalar(@whichfoils));
1.34 albertel 378: $Apache::lonhomework::results{"resource.$part.$id.numfoils"}=
1.35 albertel 379: scalar(@whichfoils);
1.34 albertel 380: }
381: }
1.1 albertel 382: }
383:
1.4 albertel 384: sub itemdisplay {
385: my ($location)=@_;
386: if ($location eq 'top' &&
387: !defined($Apache::matchresponse::itemtable{'location'})) {
388: return $Apache::matchresponse::itemtable{'display'};
389: }
390: if ($Apache::matchresponse::itemtable{'location'} eq $location) {
391: return $Apache::matchresponse::itemtable{'display'};
392: }
393: return undef;
394: }
1.1 albertel 395: sub displayfoils {
396: my ($target,$max,$randomize)=@_;
397: my $result;
1.4 albertel 398: my $question;
1.18 albertel 399: my (@whichfoils)=&Apache::response::whichorder(&getfoilcounts($max),
400: $randomize,
401: &Apache::response::showallfoils(),
402: \%Apache::response::foilgroup);
1.1 albertel 403: my $part=$Apache::inputtags::part;
404: my $solved=$Apache::lonhomework::history{"resource.$part.solved"};
405: my %letter_name_map;
406: if (defined(%{ $Apache::response::itemgroup{'letter_name_map'} })) {
407: %letter_name_map=
408: %{ $Apache::response::itemgroup{'letter_name_map'} };
409: }
410: my %name_letter_map;
411: if (defined(%{ $Apache::response::itemgroup{'name_letter_map'} })) {
412: %name_letter_map=
413: %{ $Apache::response::itemgroup{'name_letter_map'} };
414: }
1.25 albertel 415: if ( &Apache::response::show_answer() && ($target ne 'tex')) {
1.1 albertel 416: foreach my $name (@whichfoils) {
417: my $text=$Apache::response::foilgroup{$name.'.text'};
418: my $value=$Apache::response::foilgroup{$name.'.value'};
419: my $letter=$name_letter_map{$value};
1.5 sakharuk 420: if ($target eq 'tex') {
421: $question.=' \\\\ '.$letter.':'.$text;
422: } else {
423: $question.='<br />'.$letter.':'.$text;
424: }
1.1 albertel 425: }
426: } else {
427: my $i = 0;
1.36 albertel 428: my $temp=1;
1.1 albertel 429: my $id=$Apache::inputtags::response[-1];
430: my $part=$Apache::inputtags::part;
431: my $lastresponse=$Apache::lonhomework::history{"resource.$part.$id.submission"};
1.9 sakharuk 432: my %lastresponse=&Apache::lonnet::str2hash($lastresponse);
433: my @alphabet=('A'..'Z');
1.15 albertel 434: my @used_letters=sort(keys(%letter_name_map));
1.20 sakharuk 435: my $internal_counter=$Apache::lonxml::counter;
1.1 albertel 436: foreach my $name (@whichfoils) {
437: my $lastopt=$lastresponse{$name};
438: my $last_letter=$name_letter_map{$lastopt};
1.5 sakharuk 439: my $optionlist = '';
1.7 sakharuk 440: if ($target ne 'tex') {
441: $optionlist="<option></option>\n";
442: } else {
443: if ($Apache::lonhomework::type ne 'exam') {
444: $optionlist='\framebox[5 mm][s]{\tiny\strut}';
445: }
446: }
1.1 albertel 447: my $option;
1.15 albertel 448: foreach $option (@used_letters) {
1.1 albertel 449: if ($option eq $last_letter) {
1.6 sakharuk 450: if ($target ne 'tex') {$optionlist.="<option selected=\"on\">$option</option>\n";}
1.1 albertel 451: } else {
1.6 sakharuk 452: if ($target ne 'tex') {$optionlist.="<option>$option</option>\n";}
1.1 albertel 453: }
454: }
1.19 sakharuk 455: if ($target ne 'tex' && $Apache::lonhomework::type ne 'exam') {
1.5 sakharuk 456: $optionlist='<select name="HWVAL_'.
457: $Apache::inputtags::response[-1].':'.$temp.'">'.
458: $optionlist."</select>\n";
459: }
1.1 albertel 460: my $text=$Apache::response::foilgroup{$name.'.text'};
1.5 sakharuk 461: if ($target ne 'tex') {
1.19 sakharuk 462: if ($Apache::lonhomework::type ne 'exam') {
463: $question.='<br />'.$optionlist.$text."\n";
464: } else {
465: $question.='<br />'.$text."\n";
466: }
1.6 sakharuk 467: if ($Apache::lonhomework::type eq 'exam') {
1.42 albertel 468: my @blank;
469: $question.=&Apache::optionresponse::webbubbles(\@used_letters,\@blank,$temp,$last_letter);
1.6 sakharuk 470: }
471: } else {
472: if ($Apache::lonhomework::type eq 'exam') {
473: $question.=' '.$optionlist.$text."\n";
1.13 sakharuk 474: my @emptyItems = ();
1.16 albertel 475: for (my $i=0;$i<=$#used_letters;$i++) {push @emptyItems, ' ';}
1.40 sakharuk 476: $question.='\vskip -1 mm\noindent\begin{enumerate}\item[\textbf{'.$internal_counter.'}.]'.&Apache::optionresponse::bubbles(\@used_letters,\@emptyItems).'\end{enumerate} \vskip -8 mm \strut ';
1.20 sakharuk 477: $internal_counter++;
1.6 sakharuk 478: } else {
1.22 sakharuk 479: $question.=' '.$optionlist.$text.'\strut\\\\\strut '."\n";
1.6 sakharuk 480: }
1.5 sakharuk 481: }
1.1 albertel 482: $temp++;
483: }
1.4 albertel 484: }
485: if ($result=&itemdisplay('top')) {
486: $result.=$question;
487: } elsif ($result=&itemdisplay('bottom')) {
488: $result=$question.$result;
489: } elsif ($result=&itemdisplay('right')) {
1.32 sakharuk 490: if ($target ne 'tex') {
491: $result='<table><tr><td>'.$question.'</td><td>'.$result.
492: '</td></tr></table>';
493: } else {
1.39 sakharuk 494: my $tabsize=&Apache::londefdef::recalc($ENV{'form.textwidth'});
1.43 sakharuk 495: my ($lefttabsize,$righttabsize)=(0,0);
496: if ($Apache::matchresponse::TeXitemgroupwidth ne '') {
497: $Apache::matchresponse::TeXitemgroupwidth=~/(\d*.?\d*)/;
498: $lefttabsize=$tabsize*$1/100;
499: $righttabsize=0.95*($tabsize-$lefttabsize);
500: } else {
501: $tabsize=~/(\d+\.?\d*)/;
502: $lefttabsize=$1/2.1;
503: $righttabsize=0.95*($1-$lefttabsize);
504: }
505: $lefttabsize.=' mm ';
506: $righttabsize.=' mm ';
507: $result='\setlength{\tabcolsep}{1 mm}\begin{tabular}{p{'.$righttabsize.'}p{'.$lefttabsize.'}}\begin{minipage}{'.$righttabsize.'}'.$question.'\end{minipage}&\begin{minipage}{'.$lefttabsize.'}'.$result.'\end{minipage}\end{tabular}';
1.32 sakharuk 508: }
1.4 albertel 509: } elsif ($result=&itemdisplay('left')) {
1.32 sakharuk 510: if ($target ne 'tex') {
511: $result='<table><tr><td>'.$result.'</td><td>'.$question.
512: '</td></tr></table>';
513: } else {
1.39 sakharuk 514: my $tabsize=&Apache::londefdef::recalc($ENV{'form.textwidth'});
1.43 sakharuk 515: my ($lefttabsize,$righttabsize)=(0,0);
516: if ($Apache::matchresponse::TeXitemgroupwidth ne '') {
517: $Apache::matchresponse::TeXitemgroupwidth=~/(\d*.?\d*)/;
518: $lefttabsize=$tabsize*$1/100;
519: $righttabsize=0.95*($tabsize-$lefttabsize);
520: } else {
521: $tabsize=~/(\d+\.?\d*)/;
1.44 ! sakharuk 522: $lefttabsize=$1/2.1;
1.43 sakharuk 523: $righttabsize=0.95*($1-$lefttabsize);
524: }
525: $lefttabsize.=' mm ';
526: $righttabsize.=' mm ';
527: $result='\setlength{\tabcolsep}{1 mm}\begin{tabular}{p{'.$lefttabsize.'}p{'.$righttabsize.'}}\begin{minipage}{'.$lefttabsize.'}'.$result.'\end{minipage}&\begin{minipage}{'.$righttabsize.'}'.$question.'\end{minipage}\end{tabular}';
1.32 sakharuk 528: }
1.1 albertel 529: }
1.5 sakharuk 530: if ($target ne 'tex') {$result.="<br />";} else {$result.=' \\\\ ';}
1.1 albertel 531: return $result;
532: }
533:
534: sub getfoilcounts {
535: my ($max)=@_;
536: # +1 since instructors will count from 1
537: my $count = $#{ $Apache::response::foilgroup{'names'} }+1;
538: if (&Apache::response::showallfoils()) { $max=$count; }
539: if ($count>$max) { $count=$max }
540: &Apache::lonxml::debug("Count is $count from $max");
541: return $count;
542: }
543:
544:
545: sub start_conceptgroup {
546: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
547: $Apache::matchresponse::conceptgroup=1;
548: %Apache::response::conceptgroup=();
549: my $result;
550: if ($target eq 'edit') {
551: $result.=&Apache::edit::tag_start($target,$token,
552: "Concept Grouped Foils");
553: $result.=&Apache::edit::text_arg('Concept:','concept',$token,'50').
554: &Apache::edit::end_row().&Apache::edit::start_spanning_row();
555: }
556: if ($target eq 'modified') {
557: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
558: $safeeval,'concept');
559: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
560: }
561: return $result;
562: }
563:
564: sub end_conceptgroup {
565: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
566: $Apache::matchresponse::conceptgroup=0;
567: my $result='';
1.28 albertel 568: if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
569: $target eq 'tex' || $target eq 'analyze') {
570: &Apache::response::pick_foil_for_concept($target,
571: ['value','text','location'],
572: \%Apache::hint::match,
573: $parstack,$safeeval);
1.1 albertel 574: } elsif ($target eq 'edit') {
575: $result=&Apache::edit::end_table();
576: }
577: return $result;
578: }
579:
580: sub insert_conceptgroup {
581: my $result="\n\t\t<conceptgroup concept=\"\">".&insert_foil()."\n\t\t</conceptgroup>\n";
582: return $result;
583: }
584:
585: sub start_foil {
586: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
587: my $result='';
1.28 albertel 588: if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
1.1 albertel 589: &Apache::lonxml::startredirection;
590: } elsif ($target eq 'edit') {
591: $result=&Apache::edit::tag_start($target,$token,"Foil");
592: my $level='-2';
593: if ($$tagstack[-2] eq 'conceptgroup') { $level = '-3'; }
594: $result.=&Apache::edit::text_arg('Name:','name',$token);
595: my @names;
596: if (defined(@{ $Apache::response::itemgroup{'names'} })) {
597: @names=@{ $Apache::response::itemgroup{'names'} };
598: }
599: $result.= &Apache::edit::select_or_text_arg('Correct Option:','value',['unused',@names],$token,'15');
600: my $randomize=&Apache::lonxml::get_param('randomize',$parstack,
601: $safeeval,'-3');
602: if ($randomize ne 'no') {
603: $result.=&Apache::edit::select_arg('Location:','location',
604: ['random','top','bottom'],$token);
605: }
606: $result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
607: } elsif ($target eq 'modified') {
608: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
609: $safeeval,'value',
610: 'name','location');
611: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
612: }
613: return $result;
614: }
615:
616: sub end_foil {
617: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
618: my $text ='';
619: my $result = '';
1.28 albertel 620: if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
1.1 albertel 621: $text=&Apache::lonxml::endredirection;
622: }
1.28 albertel 623: if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
624: $target eq 'tex' || $target eq 'analyze') {
1.1 albertel 625: my $value = &Apache::lonxml::get_param('value',$parstack,$safeeval);
626: if ($value ne 'unused') {
627: my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
628: &Apache::lonxml::debug("Got a name of :$name:");
629: if (!$name) { $name=$Apache::lonxml::curdepth; }
630: &Apache::lonxml::debug("Using a name of :$name:");
1.37 albertel 631: if (defined($Apache::response::foilnames{$name})) {
632: &Apache::lonxml::error(&mt("Foil name <b><tt>[_1]</tt></b> appears more than once. Foil names need to be unique.",$name));
633: }
1.38 albertel 634: $Apache::response::foilnames{$name}++;
1.37 albertel 635: my $location =&Apache::lonxml::get_param('location',$parstack,
636: $safeeval);
1.1 albertel 637: if ( $Apache::matchresponse::conceptgroup
638: && !&Apache::response::showallfoils() ) {
639: push @{ $Apache::response::conceptgroup{'names'} }, $name;
640: $Apache::response::conceptgroup{"$name.value"} = $value;
1.19 sakharuk 641: if ($target eq 'tex' && $Apache::lonhomework::type eq 'exam') {
1.14 sakharuk 642: $Apache::response::conceptgroup{"$name.text"} = ' $\triangleright$ '.$text;
643: } else {
644: $Apache::response::conceptgroup{"$name.text"} = $text;
645: }
1.1 albertel 646: $Apache::response::conceptgroup{"$name.location"} = $location;
647: } else {
648: push @{ $Apache::response::foilgroup{'names'} }, $name;
649: $Apache::response::foilgroup{"$name.value"} = $value;
1.16 albertel 650: if ($Apache::lonhomework::type eq 'exam') {
1.19 sakharuk 651: if ($target eq 'tex') {
652: $Apache::response::foilgroup{"$name.text"} = '\vskip 5 mm $\triangleright$ '.$text;
653: } else {
654: $Apache::response::foilgroup{"$name.text"} = $text;
655: }
1.14 sakharuk 656: } else {
657: if ($target eq 'tex') {
1.24 sakharuk 658: $Apache::response::foilgroup{"$name.text"} = $text;
1.14 sakharuk 659: } else {
660: $Apache::response::foilgroup{"$name.text"} = $text;
661: }
662: }
1.1 albertel 663: $Apache::response::foilgroup{"$name.location"} = $location;
664: }
665: }
666: }
667: if ($target eq 'edit') {
668: $result.= &Apache::edit::tag_end($target,$token,'');
669: }
670: return $result;
671: }
672:
673: sub insert_foil {
674: return '
675: <foil name="" value="unused">
676: <startouttext />
677: <endouttext />
678: </foil>';
679: }
680: 1;
681: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>