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