# The LearningOnline Network with CAPA # chemical equation style response # # $Id: chemresponse.pm,v 1.7 2003/06/30 20:41:12 albertel Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # # package Apache::chemresponse; use strict; use Apache::lonxml; use Apache::lonnet; BEGIN { &Apache::lonxml::register('Apache::chemresponse',('organicresponse','organicstructure','reactionresponse')); } sub seperate_jme_window { my ($smile_input,$jme_input,$molecule,$options)=@_; my $smilesection; if (defined($smile_input)) { $smilesection=< Molecule Editor
You have to enable Java and JavaScript on your machine.
JME Editor courtesy of Peter Ertl, Novartis

  
CHEMPAGE $body=&HTML::Entities::encode($body); $body=~s/\n/ /g; my $result=< CHEMINPUT return $result; } sub start_organicresponse { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; my $partid = $Apache::inputtags::part; my $id = &Apache::response::start_response($parstack,$safeeval); if ($target eq 'meta') { } elsif ($target eq 'web') { my $molecule; if (defined($Apache::lonhomework::history{"resource.$partid.$id.molecule"})) { $molecule=$Apache::lonhomework::history{"resource.$partid.$id.molecule"}; } else { $molecule=&Apache::lonxml::get_param('molecule',$parstack, $safeeval); } my $multipart=&Apache::lonxml::get_param('multipart',$parstack, $safeeval); if ($multipart eq 'yes') { $multipart = 'multipart'; } else { $multipart =''; } $result=&seperate_jme_window("HWVAL_$id","MOLECULE_$id",$molecule,$multipart); $result.= ''; } elsif ($target eq 'edit') { $result .=&Apache::edit::tag_start($target,$token); $result .=''. &Apache::edit::text_arg('Starting Molecule:','molecule', $token,40); my $molecule=&Apache::lonxml::get_param('molecule',$parstack, $safeeval); $result .=&seperate_jme_window(undef, &Apache::edit::html_element_name('molecule'), $molecule,'multipart'); $result .='
'; $result .=&Apache::edit::text_arg('Correct Answer:','answer', $token,40); $result .=&Apache::edit::hidden_arg('jmeanswer',$token); my $jmeanswer=&Apache::lonxml::get_param('jmeanswer',$parstack, $safeeval); $result .=&seperate_jme_window( &Apache::edit::html_element_name('answer'), &Apache::edit::html_element_name('jmeanswer'), $jmeanswer,'multipart'); $result .=''. &Apache::edit::select_arg('Multipart:','multipart', ['no','yes'],$token); $result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row(); } elsif ($target eq 'modified') { my $constructtag=&Apache::edit::get_new_args($token,$parstack, $safeeval,'molecule', 'answer','jmeanswer', 'multipart'); if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); } } return $result; } sub end_organicresponse { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; if ($target eq 'grade' && defined($ENV{'form.submitted'})) { &Apache::response::setup_params($$tagstack[-1]); my $response = &Apache::response::getresponse(); if ( $response =~ /[^\s]/) { my $partid = $Apache::inputtags::part; my $id = $Apache::inputtags::response['-1']; my $answer=&Apache::lonxml::get_param('answer',$parstack,$safeeval); my %previous = &Apache::response::check_for_previous($response,$partid,$id); $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response; &Apache::lonxml::debug("submitted a $response for $answer
\n"); my $ad; if ($response eq $answer) { $ad='EXACT_ANS'; } else { $ad='INCORRECT'; } &Apache::response::handle_previous(\%previous,$ad); $Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad; $Apache::lonhomework::results{"resource.$partid.$id.molecule"}=$ENV{"form.MOLECULE_$id"}; } } elsif ($target eq "edit") { $result.= &Apache::edit::tag_end($target,$token,''); } &Apache::response::end_response; return $result; } sub start_organicstructure { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; if ($target eq 'web') { my $width=&Apache::lonxml::get_param('width',$parstack,$safeeval); my $height=&Apache::lonxml::get_param('height',$parstack,$safeeval); my $molecule=&Apache::lonxml::get_param('molecule',$parstack,$safeeval); $result=< CHEMOUTPUT } elsif ($target eq 'edit') { $result .=&Apache::edit::tag_start($target,$token); $result .=&Apache::edit::text_arg('Width:','width',$token,5); $result .=&Apache::edit::text_arg('Height:','height',$token,5); $result .=&Apache::edit::text_arg('Molecule:','molecule',$token,40); my $molecule=&Apache::lonxml::get_param('molecule',$parstack, $safeeval); $result .=&seperate_jme_window(undef, &Apache::edit::html_element_name('molecule'), $molecule,'multipart'); $result .=&Apache::edit::end_row().&Apache::edit::start_spanning_row(); } elsif ($target eq 'modified') { my $constructtag=&Apache::edit::get_new_args($token,$parstack, $safeeval,'molecule', 'width','height'); if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); } } return $result; } sub end_organicstructure { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; if ($target eq "edit") { $result.= &Apache::edit::tag_end($target,$token,''); } return $result; } sub reaction_javascript { my $rightarrow; if ($ENV{'browser.unicode'}) { $rightarrow=" → " } else { $rightarrow=" ® "; } my $result=< var level; var reactants; var products; function parse_reaction(string) { var reaction_array = string.split('->'); var i; reactants = new Array(0); products = new Array(0); if (reaction_array.length > 0) reactants = reaction_array[0].split(' +'); if (reaction_array.length > 1) products = reaction_array[1].split(' +'); } function to_capa(string) { var reaction = ""; var i; parse_reaction(string); for (i = 0; i < reactants.length; i++) reactants[i] = capa_component(reactants[i]); for (i = 0; i < products.length; i++) products[i] = capa_component(products[i]); reactants.sort(); products.sort(); for (i = 0; i < reactants.length-1; i++) { reaction += reactants[i]; reaction += " + "; } if (i < reactants.length) reaction += reactants[i]; if (products.length > 0) { reaction += " -> "; for (i = 0; i < products.length-1; i++) { reaction += products[i]; reaction += " + "; } if (i < products.length) reaction += products[i]; } return reaction; } function capa_component(string) { var reactant = ""; var i = 0; level = 0; for (;string.substring(i,i+1) == ' ';i++) ; for (;isDigit(string.substring(i,i+1));i++) reactant += string.substring(i,i+1); for (;i < string.length;i++) reactant += capa_char(string.substring(i,i+1)); return reactant; } function capa_char(chr) { if (level == 0) { // baseline if (chr == '^') level = 1; if (chr == ' ') return ""; return chr; } if (level == 1) { // superscript if (isDigit(chr)) return chr; level = 0; return chr; } } function to_html(string) { var reaction = ""; var i; parse_reaction(string); for (i = 0; i < reactants.length-1; i++) { reaction += html_component(reactants[i]); reaction += " + "; } if (i < reactants.length) reaction += html_component(reactants[i]); if (products.length > 0) { reaction += " $rightarrow "; for (i = 0; i < products.length-1; i++) { reaction += html_component(products[i]); reaction += " + "; } if (i < products.length) reaction += html_component(products[i]); } return reaction; } function html_component(string) { var reactant = ""; var i = 0; level = 0; for (;string.substring(i,i+1) == ' ';i++) ; for (;isDigit(string.substring(i,i+1));i++) reactant += string.substring(i,i+1); for (;i < string.length;i++) reactant += html_char(string.substring(i,i+1)); return reactant; } function html_char(chr) { if (level == 0) { // baseline if (isDigit(chr)) return chr.sub(); if (chr == '^') { level = 1; return ""; } if (chr == '+') // baseline or superscript return "?"; if (chr == ' ') return ""; return chr; } if (level == 1) { // superscript if (isDigit(chr)) return chr.sup(); if (chr == '+' || chr == '-') { level = 0; return chr.sup(); } if (chr == ' ') { level = 0; return ""; } level = 0; return chr; } } function isDigit(string) { if (string >= '0' && string <='9') return 1; else return 0; } function openHelpWindow() { window.open("reaction_help.html","","scrollbars=yes,resizable=yes,width=550,height=600") } function submitReaction() { reaction = to_capa(document.form.text.value); if (reaction == "") { alert("Nothing to submit"); } else { name = "INPUT" + ((problem < 10) ? "0" : "") + problem; i = 0; while (parent.opener.document.CAPA.elements[i].name != name) i++; parent.opener.document.CAPA.elements[i].value = reaction; parent.opener.document.CAPA.submit(); } } REACTIONJAVASCRIPT return $result; } sub start_reactionresponse { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; my $id = &Apache::response::start_response($parstack,$safeeval); if ($target eq 'web') { $result.=< EDITREACTION # $result.=&reaction_javascript(); # $result.=''; # $result.='' } elsif ($target eq "edit") { } return $result; } sub end_reactionresponse { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result; if ($target eq "edit") { $result.= &Apache::edit::tag_end($target,$token,''); } &Apache::response::end_response; return $result; } 1; __END__