File:  [LON-CAPA] / loncom / homework / loncapamath.pm
Revision 1.1: download - view: text, annotated - select for diffs
Mon Jun 29 15:42:07 2015 UTC (6 years, 10 months ago) by damieng
Branches: MAIN
CVS tags: version_2_12_X, HEAD
added implementation for <lm>

# The LearningOnline Network with CAPA 
# <lm>: 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 <lm>.
    # 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 '<b>'.$result.'</b>';
        } 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__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>