# The LearningOnline Network with CAPA # : math with the LON-CAPA syntax # # $Id: loncapamath.pm,v 1.1 2015/06/29 15:42:07 damieng 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::loncapamath; use strict; use warnings; use utf8; use Try::Tiny; use aliased 'Apache::math_parser::CalcException'; use aliased 'Apache::math_parser::ParseException'; use aliased 'Apache::math_parser::Parser'; use aliased 'Apache::math_parser::ENode'; use aliased 'Apache::math_parser::CalcEnv'; BEGIN { &Apache::lonxml::register('Apache::loncapamath',('lm')); } sub start_lm { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; # Implementation note: this is using ENode::toTex, but we could also # use a client-side implementation to display . # While we use LaTeX for printing, turning the math into TeX for the web # ensures that results will be more similar between web and print targets # than they would be with a client-side implementation turning the # parsed math directly into MathML. $Apache::lonxml::post_evaluate = 0; if ($target ne 'web' && $target ne 'tex') { return; } my $text = &Apache::lonxml::get_all_text_unbalanced("/lm", $parser); my $mode = &Apache::lonxml::get_param('mode',$parstack,$safeeval); $text = &Apache::run::evaluate($text, $safeeval, $$parstack[-1]); my $tex; my $implicit_operators = 1; my $unit_mode; if (defined $mode && $mode eq 'units') { $unit_mode = 1; } else { $unit_mode = 0; } my ($p, $root, $env); my $result; try { $p = Parser->new($implicit_operators, $unit_mode); $root = $p->parse($text); $env = CalcEnv->new($unit_mode); $tex = $root->toTeX(); } catch { # NOTE: return cannot be used within a try/catch with Try::Tiny if (UNIVERSAL::isa($_,CalcException)) { $result = "Calculation error: ".$_->getLocalizedMessage(); } elsif (UNIVERSAL::isa($_,ParseException)) { $result = "Parsing error: ".$_->getLocalizedMessage(); } else { $result = "Internal error: $_"; } }; if (defined $result) { if ($target eq 'web') { return ''.$result.''; } elsif ($target eq 'tex') { return '\bf{'.$result.'}'; } } if ($target eq 'web') { my $display = &Apache::lonxml::get_param('display', $parstack, $safeeval); $tex = '$'.$tex.'$'; $result = &Apache::lontexconvert::converted(\$tex, $display); } elsif ($target eq 'tex') { $result = '\ensuremath{'.$tex.'}'; } return $result; } sub end_lm { my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; return ''; } 1; __END__