File:
[LON-CAPA] /
loncom /
homework /
chemresponse.pm
Revision
1.98:
download - view:
text,
annotated -
select for diffs
Mon Sep 21 14:24:54 2015 UTC (9 years ago) by
raeburn
Branches:
MAIN
CVS tags:
version_2_11_3_uiuc,
version_2_11_3_msu,
version_2_11_3,
version_2_11_2_uiuc,
version_2_11_2_msu,
version_2_11_2_educog,
version_2_11_2,
HEAD
- Bug 6800
- Move HTML files used for pop-up window in reactionresponse to
/adm/reactionresponse directory to support public access.
- Replace use of &EXT('query.') with javascript to retrieve values for
reaction, field and id from query string, and replace call to &xmlparse()
with HTML entity to provide rightarrow.
1: # The LearningOnline Network with CAPA
2: # chemical equation style response
3: #
4: # $Id: chemresponse.pm,v 1.98 2015/09/21 14:24:54 raeburn 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::chemresponse;
30: use strict;
31: use Apache::lonxml;
32: use Apache::lonnet;
33: use Apache::lonlocal;
34: use lib '/home/httpd/lib/perl/';
35: use LONCAPA;
36:
37:
38: BEGIN {
39: &Apache::lonxml::register('Apache::chemresponse',('organicresponse','organicstructure','reactionresponse','chem'));
40: }
41:
42: sub chem_standard_order {
43: my ($reaction) = @_;
44: my ($re,$pr) = split(/->|<=>/,$reaction);
45: my @reactants = split(/\s\+/,$re);
46: my @products = split(/\s\+/,$pr);
47: foreach my $substance (@reactants,@products) {
48: $substance =~ s/(\^\d*)\s+/$1_/g; # protect superscript space
49: $substance =~ s/\s*//g; # strip whitespace
50: $substance =~ s/_/ /g; # restore superscript space
51: }
52: @reactants = sort @reactants;
53: @products = sort @products;
54: my $standard = '';
55: foreach my $substance (@reactants) {
56: $standard .= $substance;
57: $standard .= ' + ';
58: }
59: $standard =~ s/ \+ $//; # get rid of trailing plus sign
60: $standard .= ' -> ';
61: foreach my $substance (@products) {
62: $standard .= $substance;
63: $standard .= ' + ';
64: }
65: $standard =~ s/ \+ $//; # get rid of trailing plus sign
66: return $standard;
67: }
68:
69: sub separate_jme_window {
70: my ($smile_input,$jme_input,$molecule,$options,$shown_text)=@_;
71: my $usejsme = 1;
72: if (($env{'request.course.id'}) && ($env{'request.state'} ne 'construct')) {
73: if (exists($env{'course.'.$env{'request.course.id'}.'.usejsme'})) {
74: if ($env{'course.'.$env{'request.course.id'}.'.usejsme'} eq '0') {
75: $usejsme = 0;
76: }
77: } else {
78: my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
79: if ($domdefs{'usejsme'} eq '0') {
80: $usejsme = 0;
81: }
82: }
83: } else {
84: my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
85: if ($domdefs{'usejsme'} eq '0') {
86: $usejsme = 0;
87: }
88: }
89: if ($usejsme) {
90: if ($env{'browser.type'} eq 'safari') {
91: unless ($env{'browser.mobile'}) {
92: if ($env{'browser.version'} < 534) {
93: $usejsme = 0;
94: }
95: }
96: } elsif ($env{'browser.type'} eq 'mozilla') {
97: if ($env{'browser.version'} < 5) {
98: $usejsme = 0;
99: } elsif ($env{'browser.info'} =~ /^firefox\-([\d\.]+)/) {
100: my $firefox = $1;
101: if ($firefox < 12) {
102: $usejsme = 0;
103: }
104: }
105: } elsif ($env{'browser.type'} eq 'explorer') {
106: if ($env{'browser.version'} < 7) {
107: $usejsme = 0;
108: }
109: } elsif ($env{'browser.type'} eq 'opera') {
110: if ($env{'browser.version'} < 15) {
111: $usejsme = 0;
112: }
113: }
114: } else {
115: if ($env{'browser.mobile'}) {
116: $usejsme = 1;
117: }
118: }
119: my $linkstyle = 'display:none';
120: my $creditstyle = 'display:inline';
121: if ($env{'browser.type'} eq 'explorer') {
122: if (($env{'browser.os'} eq 'win') && ($env{'browser.version'} < 9)) {
123: $linkstyle = 'display:inline';
124: $creditstyle = 'display:none';
125: }
126: }
127: my $smilesection;
128: if (defined($smile_input)) {
129: my $smiles;
130: if ($usejsme) {
131: $smiles = 'document.JME.smiles()';
132: } else {
133: $smiles = 'document.applets.JME.smiles()';
134: }
135: $smilesection=<<SMILESECTION;
136: opener.document.lonhomework.$smile_input.value = $smiles;
137: SMILESECTION
138: }
139: my $jmesection;
140: my $jmefile;
141: if (defined($jme_input)) {
142: if ($usejsme) {
143: $jmefile = 'document.JME.jmeFile()';
144: } else {
145: $jmefile = 'document.applets.JME.jmeFile()';
146: }
147: $jmesection=<<JMESECTION;
148: opener.document.lonhomework.$jme_input.value = $jmefile;
149: JMESECTION
150: }
151:
152: if ($molecule) {
153: if ($usejsme) {
154: $molecule = 'document.JME.readMolecule("'.$molecule.'")';
155: } else {
156: $molecule='<param name="jme" value="'.$molecule.'" />';
157: }
158: }
159: my $insert_answer;
160: if ($shown_text eq '') {
161: $insert_answer=
162: '<input type="button" name="submit" value="'.&mt('Insert Answer').'" onclick="javascript:submitSmiles();" /><br />';
163: }
164:
165:
166:
167: my ($jsme_js,$js,$buttonstyle,$viewportjs,$resizejs);
168: if ($usejsme) {
169: $buttonstyle = 'display:none';
170: $resizejs =<<RESIZEJS;
171: <script type="text/javascript">
172: function callResize() {
173: var timer;
174: clearTimeout(timer);
175: timer=setTimeout('resize_jsme()',100);
176: }
177:
178: window.onresize = callResize;
179:
180: function resize_jsme() {
181: init_geometry();
182: var vph = Geometry.getViewportHeight();
183: var vpw = Geometry.getViewportWidth();
184: var lowerdivheight = document.getElementById('JMEbuttons').offsetHeight;
185: var formheight = document.getElementById('JMEform').offsetHeight;
186: var freevspace = vph-(lowerdivheight+50);
187: var freehspace = vpw-20;
188: if (typeof jsmeApplet !== 'undefined') {
189: jsmeApplet.setSize(freehspace,freevspace);
190: }
191: }
192: </script>
193: RESIZEJS
194: $resizejs = &Apache::loncommon::js_ready($resizejs);
195: $jsme_js = '
196: <script type="text/javascript" language="javascript" src="/adm/jsme/jsme.nocache.js"></script>'."\n";
197: $js =<<CHEMJS;
198: <script type="text/javascript">
199: function jsmeOnLoad() {
200: document.getElementById('JMErefresh').style.display="none";
201: document.getElementById('JMEcredits').style.display="inline";
202: jsmeApplet = new JSApplet.JSME("jme", "420px", "330px");
203: document.JME = jsmeApplet;
204: $molecule;
205: document.getElementById('JMEbuttons').style.display="block";
206: callResize();
207: }
208:
209: function submitSmiles() {
210: jmeFile = document.JME.jmeFile();
211: if (jmeFile == "") {
212: alert("Nothing to submit");
213: } else {
214: $jmesection
215: $smilesection
216: window.close();
217: }
218: }
219: function openHelpWindow() {
220: window.open("http://peter-ertl.com/jsme/2013_03/help.html","","scrollbars=yes,resizable=yes,width=500,height=600");
221: }
222:
223: </script>
224:
225: CHEMJS
226:
227: $viewportjs = &Apache::loncommon::viewport_geometry_js();
228: $viewportjs = '<script type="text/javascript">'."\n".
229: $viewportjs."\n".
230: '</script>';
231:
232: } else {
233: $buttonstyle = 'display:block';
234: $js =<<CHEMJS;
235: <script type="text/javascript">
236: function submitSmiles() {
237: jmeFile = document.applets.JME.jmeFile();
238: if (jmeFile == "") {
239: alert("Nothing to submit");
240: } else {
241: $jmesection
242: $smilesection
243: window.close();
244: }
245: }
246: function openHelpWindow() {
247: window.open("/adm/jme/jme_help.html","","scrollbars=yes,resizable=yes,width=500,height=600");
248: }
249: function substituent(r) {document.applets.JME.setSubstituent(r);}
250: </script>
251: CHEMJS
252: }
253:
254: my $start_page =
255: &Apache::loncommon::start_page('Molecule Editor',$viewportjs,
256: {'only_body' => 1,
257: 'js_ready' => 1,
258: 'bgcolor' => '#FFFFFF',});
259: my $end_page =
260: &Apache::loncommon::end_page({'js_ready' => 1,});
261: my $java_not_enabled=&Apache::lonhtmlcommon::java_not_enabled();
262: my %lt = &Apache::lonlocal::texthash(
263: 'seltext' => 'Select substituent...',
264: 'close' => 'Close',
265: 'help' => 'Help',
266: );
267: my $body = "
268: $jsme_js
269: $js".'
270: <center>
271: <form action="" id="JMEform">
272: ';
273: if ($usejsme) {
274: $body.= <<"ENDCHEM";
275: <div id="jme">
276: <div id="JMEcredits" style="$creditstyle">
277: <span style="font-size:small; font-family:arial,sans-serif;"><a href="http://peter-ertl.com/jsme/">JSME Molecular Editor</a> courtesy of Peter Ertl (Novartis) and Bruno Bienfait</span></div>
278: </div>
279: ENDCHEM
280: } else {
281: $body.=<<CHEMPAGE;
282: <table width="440"><tr>
283: <td></td>
284: <td align="right">
285: <select onchange="javascript:substituent(options[selectedIndex].text)">
286: <option>$lt{'seltext'}</option>
287: <option>-C(=O)OH</option>
288: <option>-C(=O)OMe</option>
289: <option>-OC(=O)Me</option>
290: <option>-CMe3</option>
291: <option>-CF3</option>
292: <option>-CCl3</option>
293: <option>-NO2</option>
294: <option>-SO2-NH2</option>
295: <option>-NH-SO2-Me</option>
296: <option>-NMe2</option>
297: <option>-C#N</option>
298: <option>-C#C-Me</option>
299: <option>-C#CH</option>
300: </select>
301: </td></tr>
302: </table>
303: <applet code="JME.class" name="JME" archive="/adm/jme/JME.jar" width="440" height="390" mayscript>
304: $java_not_enabled
305: $molecule
306: <param name="options" value="$options" />
307: </applet>
308: <br />
309: <font face="arial,helvetica,sans-serif" size="-1"><a href="http://www.molinspiration.com/jme/index.html">JME Editor</a> courtesy of Peter Ertl, Novartis</font>
310: CHEMPAGE
311: }
312: $body .= <<CHEMPAGE;
313: <div id="JMEbuttons" style="$buttonstyle">
314: $insert_answer
315: <input type="button" value="$lt{'close'}" onclick="javascript:window.close()" />
316:
317: <input type="button" value="$lt{'help'}" onclick="javascript:openHelpWindow()" />
318: </div>
319: <div id="JMErefresh" style="$linkstyle">
320: <a href="javascript:location.reload();">Display Molecule Editor</a>
321: </div>
322: </form>
323: </center>
324: CHEMPAGE
325:
326: $body=&Apache::loncommon::js_ready($body);
327: my $nothing=&Apache::lonhtmlcommon::javascript_nothing();
328: my $docopen=&Apache::lonhtmlcommon::javascript_docopen();
329: my $display=&mt('Draw Molecule');
330: if (defined($shown_text)) { $display=&mt($shown_text); }
331: my $iconpath=$Apache::lonnet::perlvar{'lonIconsURL'};
332: my $function =
333: 'LONCAPA_draw_molecule_'.&get_uniq_name();
334: my $result=<<CHEMINPUT;
335: <script type="text/javascript">
336: function $function() {
337: editor=window.open($nothing,'jmeedit','width=500,height=500,menubar=no,scrollbars=no,resizable=yes');
338: if (editor) {
339: editor.$docopen;
340: editor.document.write('$start_page $body $resizejs $end_page');
341: editor.document.close();
342: editor.focus();
343: }
344: }
345: </script>
346: CHEMINPUT
347: my $jscall = "javascript:$function();void(0);";
348: if ($shown_text eq '') {
349: $result .=<<PENCIL;
350: <a href="$jscall"><img class="stift" src="$iconpath/stift.gif" alt="$display" title="$display" /></a>
351: PENCIL
352: } else {
353: $result .= '<input type="button" value="'.&mt($shown_text).'" onclick="$jscall" />';
354: }
355: return $result;
356: }
357: sub jme_img {
358: my ($jme,$smile,$width,$options)=@_;
359: my $id=&Apache::loncommon::get_cgi_id();
360: my $result='<img alt="'.$smile.'" src="/cgi-bin/convertjme.pl?'.$id.'"';
361: if ($options =~ /border/) { $result.= ' border="1"'; }
362: $result.=' />';
363: &Apache::lonnet::appenv({'cgi.'.$id.'.JME' =>
364: &escape($jme),
365: 'cgi.'.$id.'.PNG' => 1,
366: 'cgi.'.$id.'.WIDTH' => $width});
367: return $result;
368: }
369:
370: sub start_organicresponse {
371: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
372: my $result;
373: my $partid = $Apache::inputtags::part;
374: my $id = &Apache::response::start_response($parstack,$safeeval);
375: if ($target eq 'meta') {
376: $result=&Apache::response::meta_package_write('organicresponse');
377: } elsif ($target eq 'web') {
378: my $jmeanswer=&Apache::lonxml::get_param('jmeanswer',$parstack,
379: $safeeval);
380: if (&Apache::response::show_answer()) {
381: my $jmeanswer=&Apache::lonxml::get_param('jmeanswer',$parstack,
382: $safeeval);
383: if ($jmeanswer ne '') {
384: my $options=&Apache::lonxml::get_param('options',$parstack,
385: $safeeval);
386: my $width=&Apache::lonxml::get_param('width',$parstack,
387: $safeeval);
388: my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,
389: $safeeval);
390: $result.=&jme_img($jmeanswer,$answers[0],$width,$options);
391: }
392: } else {
393: $result.= '<input type="hidden" name="MOLECULE_'.$id.'" value="" />';
394: }
395: } elsif ($target eq 'edit') {
396: $result .=&Apache::edit::tag_start($target,$token);
397: my $options=&Apache::lonxml::get_param('options',$parstack,
398: $safeeval);
399: if ($options !~ /multipart/) { $options.=',multipart'; }
400: $result .='<span class="LC_nobreak">'.
401: &Apache::edit::text_arg('Starting Molecule:','molecule',
402: $token,40);
403: my $molecule=&Apache::lonxml::get_param('molecule',$parstack,
404: $safeeval);
405: $result .=&separate_jme_window(undef,
406: &Apache::edit::html_element_name('molecule'),
407: $molecule,$options);
408: $result .='</span><br /><span class="LC_nobreak">';
409: $result .=&Apache::edit::text_arg('Correct Answer:','answer',
410: $token,40);
411: $result .='</span><br /><span class="LC_nobreak">';
412: $result .=&Apache::edit::text_arg('JME string of the answer - automatically updated by "Insert Answer" in the JME pop-up (click pencil):',
413: 'jmeanswer',$token);
414: my $jmeanswer=&Apache::lonxml::get_param('jmeanswer',$parstack,
415: $safeeval);
416: $result .=&separate_jme_window(
417: &Apache::edit::html_element_name('answer'),
418: &Apache::edit::html_element_name('jmeanswer'),
419: $jmeanswer,$options);
420: $result .='</span><br />';
421: $result .=&Apache::edit::checked_arg('Options:','options',
422: [ ['autoez','Auto E,Z stereochemistry'],
423: ['multipart','Multipart Structures'],
424: ['nostereo','No stereochemistry'],
425: ['reaction','Is a reaction'],
426: ['number','Able to number atoms'] ],
427: ,$token);
428: $result .=&Apache::edit::text_arg('Width of correct answer image:',
429: 'width',$token,10);
430: $result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
431: } elsif ($target eq 'modified') {
432: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
433: $safeeval,'molecule',
434: 'answer','jmeanswer',
435: 'options','width');
436: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
437: }
438:
439: return $result;
440: }
441:
442: sub end_organicresponse {
443: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
444: my $result;
445:
446: my $partid = $Apache::inputtags::part;
447: my $id = $Apache::inputtags::response['-1'];
448:
449: if ($target eq 'grade'
450: && &Apache::response::submitted()
451: && $Apache::lonhomework::type eq 'exam') {
452:
453: &Apache::response::scored_response($partid,$id);
454:
455: } elsif ($target eq 'grade'
456: && &Apache::response::submitted()
457: && $Apache::lonhomework::type ne 'exam') {
458:
459: &Apache::response::setup_params($$tagstack[-1],$safeeval);
460: my $response = &Apache::response::getresponse();
461: if ( $response =~ /[^\s]/) {
462: my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval);
463: my %previous = &Apache::response::check_for_previous($response,$partid,$id);
464: $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response;
465: my $ad;
466: foreach my $answer (@answers) {
467: &Apache::lonxml::debug("submitted a $response for $answer<br \>\n");
468: if ($response eq $answer) {
469: $ad='EXACT_ANS';
470: last;
471: } else {
472: $ad='INCORRECT';
473: }
474: }
475: if ($ad) {
476: if ($Apache::lonhomework::type eq 'survey') {
477: $ad='SUBMITTED';
478: } elsif ($Apache::lonhomework::type eq 'surveycred') {
479: $ad='SUBMITTED_CREDIT';
480: } elsif ($Apache::lonhomework::type eq 'anonsurvey') {
481: $ad='ANONYMOUS';
482: } elsif ($Apache::lonhomework::type eq 'anonsurveycred') {
483: $ad='ANONYMOUS_CREDIT';
484: }
485: }
486: &Apache::response::handle_previous(\%previous,$ad);
487: $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad;
488: $Apache::lonhomework::results{"resource.$partid.$id.molecule"}=$env{"form.MOLECULE_$id"};
489: }
490: } elsif ($target eq "edit") {
491: $result.= &Apache::edit::tag_end($target,$token,'');
492: } elsif ($target eq 'answer') {
493: my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,
494: $safeeval);
495: $result.=&Apache::response::answer_header('organicresponse');
496: foreach my $answer (@answers) {
497: $result.=&Apache::response::answer_part('organicresponse',$answer);
498: }
499: $result.=&Apache::response::answer_footer('organicresponse');
500: }
501: if ($target eq 'web') {
502: &Apache::response::setup_prior_tries_hash(\&format_prior_answer_organic,
503: ['molecule'])
504: }
505:
506: if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
507: $target eq 'tex' || $target eq 'analyze') {
508: my $repetition = &Apache::response::repetition();
509: &Apache::lonxml::increment_counter($repetition,"$partid.$id"); # part.response
510: if ($target eq 'analyze') {
511: $Apache::lonhomework::analyze{"$partid.$id.type"} = 'organicresponse';
512: push (@{ $Apache::lonhomework::analyze{"parts"} },"$partid.$id");
513: &Apache::lonhomework::set_bubble_lines();
514: }
515: }
516: if ($target eq 'web' ) {
517: my ($showpencil,$shown_text);
518: if ($Apache::inputtags::status['-1'] eq 'CAN_ANSWER') {
519: $showpencil = 1;
520: } elsif (&Apache::response::show_answer()) {
521: my $jmeanswer=&Apache::lonxml::get_param('jmeanswer',$parstack, $safeeval);
522: if ($jmeanswer eq '') {
523: $showpencil = 1;
524: $shown_text="Show Your Last Answer";
525: }
526: }
527: if ($showpencil) {
528: my $options=&Apache::lonxml::get_param('options',$parstack,
529: $safeeval);
530:
531: my $molecule;
532: if (defined($Apache::lonhomework::history{"resource.$partid.$id.molecule"})) {
533: $molecule=$Apache::lonhomework::history{"resource.$partid.$id.molecule"};
534: } else {
535: $molecule=&Apache::lonxml::get_param('molecule',$parstack,
536: $safeeval);
537: }
538: $result.=&separate_jme_window("HWVAL_$id","MOLECULE_$id",$molecule,
539: $options,$shown_text);
540: }
541: }
542: &Apache::response::end_response();
543: return $result;
544: }
545:
546: sub format_prior_answer_organic {
547: my ($mode,$answer,$other_data) = @_;
548: my $result=&mt('Smile representation: [_1]','"<tt>'.$answer.'</tt>"');
549: my $jme=$other_data->[0];
550: $result.=&jme_img($jme,$answer,400);
551: return $result;
552: }
553:
554: sub start_organicstructure {
555: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
556: my $result;
557: if ($target eq 'web') {
558: my $width=&Apache::lonxml::get_param('width',$parstack,$safeeval);
559: my $molecule=&Apache::lonxml::get_param('molecule',$parstack,$safeeval);
560: my $options=&Apache::lonxml::get_param('options',$parstack,$safeeval);
561: my $id=&Apache::loncommon::get_cgi_id();
562: $result="<img src='/cgi-bin/convertjme.pl?$id'";
563: if ($options =~ /border/) { $result.= ' border="1"'; }
564: $result.=' />';
565: &Apache::lonnet::appenv(
566: {'cgi.'.$id.'.JME' => &escape($molecule),
567: 'cgi.'.$id.'.PNG' => 1,
568: 'cgi.'.$id.'.WIDTH' => $width});
569: } elsif ($target eq 'tex') {
570: my $texwidth=&Apache::lonxml::get_param('texwidth',$parstack,$safeeval,undef,1);
571: my $webwidth=&Apache::lonxml::get_param('width', $parstack, $safeeval);
572: my $webheight=&Apache::lonxml::get_param('height', $parstack, $safeeval);
573: if (!$webheight) { $webheight = $webwidth; }
574: if (!$texwidth) { $texwidth='90'; }
575: $result = "%DYNAMICIMAGE:$webwidth:$webheight:$texwidth\n";
576: my $molecule=&Apache::lonxml::get_param('molecule',$parstack,$safeeval);
577: my $options=&Apache::lonxml::get_param('options',$parstack,$safeeval);
578: my $filename = $env{'user.name'}.'_'.$env{'user.domain'}.
579: '_'.time.'_'.$$.int(rand(1000)).'_organicstructure';
580: my $id=$filename;
581: &Apache::lonnet::appenv(
582: {'cgi.'.$id.'.JME' => &escape($molecule),
583: 'cgi.'.$id.'.PS' => 1,
584: 'cgi.'.$id.'.WIDTH' => $texwidth});
585: $id=&escape($id);
586: &Apache::lonxml::register_ssi("/cgi-bin/convertjme.pl?$id");
587: if ($options =~ /border/) { $result.= '\fbox{'; }
588: $result .= '\graphicspath{{'.LONCAPA::tempdir().
589: '}}\includegraphics[width='.$texwidth.' mm]{'.$filename.'.eps}';
590: if ($options =~ /border/) { $result.= '} '; }
591: } elsif ($target eq 'edit') {
592: $result .=&Apache::edit::tag_start($target,$token);
593: $result .=&Apache::edit::text_arg('Width (pixels):','width',$token,5);
594: $result .=&Apache::edit::text_arg('TeXwidth (mm):','texwidth',$token,5);
595: $result .='<span class="LC_nobreak">';
596: $result .=&Apache::edit::text_arg('Molecule:','molecule',$token,40);
597: my $molecule=&Apache::lonxml::get_param('molecule',$parstack,
598: $safeeval);
599: my $options=&Apache::lonxml::get_param('options',$parstack,
600: $safeeval);
601: if ($options !~ /reaction/) {
602: $options.= ',multipart,number';
603: }
604:
605: $result .=&separate_jme_window(undef,
606: &Apache::edit::html_element_name('molecule'),
607: $molecule,$options);
608: $result.="</span><br />";
609: $result .=&Apache::edit::checked_arg('Options:','options',
610: [ ['reaction','Is a reaction'],
611: ['border','Draw a border'] ],
612: $token);
613: $result .=&Apache::edit::end_row();
614: } elsif ($target eq 'modified') {
615: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
616: $safeeval,'molecule',
617: 'width','texwidth',
618: 'options');
619: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
620: }
621: return $result;
622: }
623:
624: sub end_organicstructure {
625: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
626: my $result;
627: if ($target eq "edit") {
628: $result.= &Apache::edit::tag_end($target,$token,'');
629: }
630: return $result;
631: }
632:
633: sub edit_reaction_button {
634: my ($id,$field,$reaction)=@_;
635: my $id_es=&escape($id);
636: my $field_es=&escape($field);
637: my $reaction_es=&escape($reaction);
638: my $docopen=&Apache::lonhtmlcommon::javascript_docopen();
639: my $iconpath=$Apache::lonnet::perlvar{'lonIconsURL'};
640: my $display=&mt('Edit Answer');
641: my $start_page =
642: &Apache::loncommon::start_page('LON-CAPA Reaction Editor',undef,
643: {'frameset' => 1,
644: 'js_ready' => 1,
645: 'add_entries' => {
646: 'rows' => "30%,*",
647: 'border' => "0",}},);
648: my $end_page =
649: &Apache::loncommon::end_page({'frameset' => 1,
650: 'js_ready' => 1});
651: my $result=<<EDITREACTION;
652: <script type="text/javascript">
653: // <!--
654: function create_reaction_window_${id}_${field} () {
655: editor=window.open('','','width=500,height=270,scrollbars=no,resizable=yes');
656: editor.$docopen;
657: editor.document.writeln('$start_page <frame src="/adm/reactionresponse/reaction_viewer.html?inhibitmenu=yes" name="viewer" scrolling="no" /> <frame src="/adm/reactionresponse/reaction_editor.html?inhibitmenu=yes&reaction=$reaction_es&id=$id_es&field=$field_es" name="editor" scrolling="no" /> $end_page');
658: editor.document.close();
659: }
660: // -->
661: </script>
662: <a href="javascript:create_reaction_window_${id}_${field}();void(0);"><img class="stift" src='$iconpath/stift.gif' alt='$display' title='$display' /></a>
663: EDITREACTION
664: return $result;
665: }
666:
667: sub start_reactionresponse {
668: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
669: my $result;
670: my $id = &Apache::response::start_response($parstack,$safeeval);
671: if ($target eq 'meta') {
672: $result=&Apache::response::meta_package_write('reactionresponse');
673: } elsif ($target eq 'web') {
674: my $partid = $Apache::inputtags::part;
675: my $id = $Apache::inputtags::response['-1'];
676: if ( &Apache::response::show_answer() ) {
677: my $ans=&Apache::lonxml::get_param('answer',$parstack,$safeeval);
678: if (!$Apache::lonxml::default_homework_loaded) {
679: &Apache::lonxml::default_homework_load($safeeval);
680: }
681: @Apache::scripttag::parser_env = @_;
682: $Apache::inputtags::answertxt{$id}=[&Apache::run::run("return &chemparse(q\0$ans\0);",$safeeval)];
683: }
684: } elsif ($target eq "edit") {
685: $result .=&Apache::edit::tag_start($target,$token);
686: my $answer=&Apache::lonxml::get_param('answer',$parstack,
687: $safeeval);
688: $result .='<span class="LC_nobreak">'.
689: &Apache::edit::text_arg('Answer:','answer',$token,40);
690: $result .=&edit_reaction_button($id,&Apache::edit::html_element_name('answer'),$answer).'</span>';
691: my $initial=&Apache::lonxml::get_param('initial',$parstack,$safeeval);
692: $result.='<span class="LC_nobreak">'.
693: &Apache::edit::text_arg('Initial Reaction:','initial',$token,40);
694: $result .=&edit_reaction_button($id,&Apache::edit::html_element_name('initial'),$initial).'</span>';
695: $result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
696: } elsif ($target eq 'modified') {
697: my $constructtag=&Apache::edit::get_new_args($token,$parstack,
698: $safeeval,'answer',
699: 'initial');
700: if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
701: }
702: return $result;
703: }
704:
705: sub end_reactionresponse {
706: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
707: my $result;
708:
709: my $partid = $Apache::inputtags::part;
710: my $id = $Apache::inputtags::response['-1'];
711:
712: if ($target eq 'grade'
713: && &Apache::response::submitted()
714: && $Apache::lonhomework::type eq 'exam') {
715:
716: &Apache::response::scored_response($partid,$id);
717:
718: } elsif ($target eq 'grade'
719: && &Apache::response::submitted()
720: && $Apache::lonhomework::type ne 'exam') {
721:
722: &Apache::response::setup_params($$tagstack[-1],$safeeval);
723: my $response = &Apache::response::getresponse();
724: if ( $response =~ /[^\s]/) {
725: my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,$safeeval);
726: my %previous = &Apache::response::check_for_previous($response,$partid,$id);
727: $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response;
728: my $ad;
729: foreach my $answer (@answers) {
730: &Apache::lonxml::debug("submitted a $response for $answer<br \>\n");
731: if (&chem_standard_order($response) eq
732: &chem_standard_order($answer)) {
733: $ad='EXACT_ANS';
734: } else {
735: $ad='INCORRECT';
736: }
737: }
738: if ($ad) {
739: if ($Apache::lonhomework::type eq 'survey') {
740: $ad='SUBMITTED';
741: } elsif ($ad && $Apache::lonhomework::type eq 'surveycred') {
742: $ad='SUBMITTED_CREDIT';
743: } elsif ($ad && $Apache::lonhomework::type eq 'anonsurvey') {
744: $ad='ANONYMOUS';
745: } elsif ($ad && $Apache::lonhomework::type eq 'anonsurveycred') {
746: $ad='ANONYMOUS_CREDIT';
747: }
748: }
749: &Apache::response::handle_previous(\%previous,$ad);
750: $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad;
751: }
752: } elsif ($target eq "edit") {
753: $result.= &Apache::edit::tag_end($target,$token,'');
754: } elsif ($target eq 'answer') {
755: my (@answers)=&Apache::lonxml::get_param_var('answer',$parstack,
756: $safeeval);
757: $result.=&Apache::response::answer_header('reactionresponse');
758: foreach my $answer (@answers) {
759: $result.=&Apache::response::answer_part('reactionresponse',
760: $answer);
761: }
762: $result.=&Apache::response::answer_footer('reactionresponse');
763: }
764: if ($target eq 'web') {
765: &Apache::response::setup_prior_tries_hash(\&format_prior_response_reaction);
766: }
767:
768: if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
769: $target eq 'tex' || $target eq 'analyze') {
770: my $repetition = &Apache::response::repetition();
771: &Apache::lonxml::increment_counter($repetition,"$partid.$id");
772: if ($target eq 'analyze') {
773: $Apache::lonhomework::analyze{"$partid.$id.type"} = 'reactionresponse';
774: push (@{ $Apache::lonhomework::analyze{"parts"} },"$partid.$id");
775: &Apache::lonhomework::set_bubble_lines();
776: }
777: }
778: my $status=$Apache::inputtags::status['-1'];
779: if (($target eq 'web') && ($Apache::lonhomework::type ne 'exam') && ($status eq 'CAN_ANSWER')) {
780: my $reaction=$Apache::lonhomework::history{"resource.$partid.$id.submission"};
781: if ($reaction eq '') { $reaction=&Apache::lonxml::get_param('initial',$parstack,$safeeval); }
782: $result.=&edit_reaction_button($id,"HWVAL_$id",$reaction);
783: }
784: &Apache::response::end_response();
785: return $result;
786: }
787:
788: sub format_prior_response_reaction {
789: my ($mode,$answer) =@_;
790: return '<span class="LC_prior_reaction">'.
791: &HTML::Entities::encode($answer,'"<>&').'</span>';
792: }
793:
794: sub start_chem {
795: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
796: my $result = '';
797: my $inside = &Apache::lonxml::get_all_text_unbalanced("/chem",$parser);
798: if ($target eq 'tex' || $target eq 'web') {
799: $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]);
800: if (!$Apache::lonxml::default_homework_loaded) {
801: &Apache::lonxml::default_homework_load($safeeval);
802: }
803: @Apache::scripttag::parser_env = @_;
804: $result=&Apache::run::run("return &chemparse(q\0$inside\0);",$safeeval);
805: }
806: return $result;
807: }
808:
809: sub end_chem {
810: my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_;
811: my $result = '';
812: return $result;
813: }
814:
815: my $uniq=0;
816: sub get_uniq_name {
817: $uniq++;
818: return 'uniquename'.$uniq;
819: }
820:
821: 1;
822: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>