# The LearningOnline Network with CAPA # TeX Conversion Module # # $Id: lontexconvert.pm,v 1.52 2005/02/24 09:37:43 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/ # # Copyright for TtHfunc and TtMfunc by Ian Hutchinson. # TtHfunc and TtMfunc (the "Code") may be compiled and linked into # binary executable programs or libraries distributed by the # Michigan State University (the "Licensee"), but any binaries so # distributed are hereby licensed only for use in the context # of a program or computational system for which the Licensee is the # primary author or distributor, and which performs substantial # additional tasks beyond the translation of (La)TeX into HTML. # The C source of the Code may not be distributed by the Licensee # to any other parties under any circumstances. # package Apache::lontexconvert; use strict; use tth(); use vars qw($errorstring); use Apache(); use Apache::lonmsg(); use Apache::lonxml(); use Apache::lonmenu(); use Apache::lonlocal; # ====================================================================== Header sub init_tth { my $options=$ENV{'course.'.$ENV{'request.course.id'}.'.tthoptions'}; if ($ENV{'browser.mathml'}) { &tth::ttminit(); if ($ENV{'browser.unicode'}) { &tth::ttmoptions('-L -u1 '.$options); } else { &tth::ttmoptions('-L -u0 '.$options); } } else { &tth::tthinit(); if ($ENV{'browser.unicode'}) { &tth::tthoptions('-L -u1 '.$options); } else { &tth::tthoptions('-L -u0 '.$options); } } } sub header { $errorstring=''; my $time=time; &init_tth(); return &Apache::lonxml::xmlbegin(). "\n\n". &Apache::lonxml::fontsettings(). &Apache::lonmenu::registerurl(undef,'tex'). "\n\n"; } # ================================================================== Conversion $Apache::lontexconvert::messedup=0; # we need this routine because &converted can get called from inside # of the safespace (through &xmlparse('stuff') which doesn't # allow the opcode for alarm, so we need to compile this before we get # into the safe space since opcode checks only occur at compile time sub convert_real { my ($texstring)=@_; my ($xmlstring,$errorstring); local $SIG{SEGV}=sub { $Apache::lontexconvert::messedup=1; die; }; local $SIG{ALRM}=sub { &Apache::lonnet::logthis("ALRM"); $xmlstring='['.&mt("TeX unconverted due to errors").']'; $Apache::lontexconvert::messedup=1; die &mt("TeX unconverted due to errors"); }; alarm($Apache::lonnet::perlvar{'lonScriptTimeout'}); if ($ENV{'browser.mathml'}) { $xmlstring=&tth::ttm($$texstring); $xmlstring=~s/\/\/g; $xmlstring=~s/\/\/g; $xmlstring=~s/\/\\<\/p\>/g; $errorstring.=&tth::ttmerror(); } else { $xmlstring=&tth::tth($$texstring); $errorstring.=&tth::ttherror(); $xmlstring=~s---g; } $xmlstring=~s/^\s*\
request(); $request->child_terminate(); } return $xmlstring; } # ====================================================================== Footer sub footer { my $xmlstring=''; if ($ENV{'request.state'} eq 'construct') { $xmlstring.='
'.$errorstring.'
'; } else { &Apache::lonmsg::author_res_msg($ENV{'request.filename'},$errorstring); } # -------------------------------------------------------------------- End Body $xmlstring.=&Apache::lonxml::xmlend(); return $xmlstring; } # ------------------------------------------------------------ Message display sub to_convert { my ($string) = @_; $string=~s/\/ /gs; # $string=~s/\s/ /gs; $string=&HTML::Entities::decode($string); return &converted(\$string); } sub smiley { my $expression=shift; if ($ENV{'browser.imagesuppress'} eq 'on') { return $expression; } my %smileys=('\:\-\)' => 'smiley', '8\-\)' => 'coolsmile', '8\-(I|\|)' => 'coolindiff', ':\-(I|\|)' => 'neutral', '\:\-(o|O|\(\))' => 'shocked', ':\-\(' => 'frowny', '\;\-\)' => 'wink', '\:\-P' => 'baeh', '\:\-(\\\|\\/)' => 'hrrm', '\:\-D' => 'bigsmile', '\:\-C' => 'angry', '\:(\'|\`)\-\(' => 'cry', '\:\-(X|\#)' => 'lipsrsealed', '\:\-S' => 'huh'); my $iconpath=$Apache::lonnet::perlvar{'lonIconsURL'}; foreach (keys %smileys) { $expression=~s/$_/\/gs; } return $expression; } sub msgtexconverted { my ($message,$email) = @_; $errorstring=''; &init_tth(); my $outmessage=''; my $tex=0; foreach (split(/(?:\<\;|\<)\/*m\s*(?:\>\;|\>)/i,$message)) { if ($tex) { if ($email) { $outmessage.=''.&to_convert($_).'
'; $tex=0;
	    } else {
		$outmessage.=&to_convert($_); $tex=0;
	    }
	} else {
            $outmessage.=&smiley($_); $tex=1;
	}
    }
    if (wantarray) {
	return ($outmessage,$errorstring);
    } else {
	return $outmessage.$errorstring;
    }
}

sub algebra {
    use AlgParser;

    my ($string,$target)=@_;
    my $parser = new AlgParserWithImplicitExpand;
    $string=&prepare_algebra($string);
    my $ret = $parser->parse($string);
    my $result='['.&mt('Algebra unconverted due to previous errors').']';
    if ( ref($ret) ) {
	#$parser->tostring();
	$parser->normalize();
	my $latex=$parser->tolatex();
	$latex=&postprocess_algebra($latex);
	$latex='$'.$latex.'$';
	if ($target eq 'web' || $target eq 'analyze') {
	    $result = &converted(\$latex);
	} else {
	    $result = $latex;
	}
    } else {
	&Apache::lonxml::error($parser->{'htmlerror'});
    }
}

sub prepare_algebra {
    my ($string)=@_;

    # makes the decision about what is a minus sign easier supposedly
    $string =~ s/([\=\>\<\%\!\#] *)-/$1 zeroplace -/g;

    return $string;
}

sub postprocess_algebra {
    my ($string)=@_;
    
    # moodle had these and I don't know why, ignoring them for now
    # $string =~s/\\fun/ /g;

    # sqrt(3,4) -> \sqrt\let{3,4\right}, which is annoying
    $string =~s/\\left\{/\{/g;
    $string =~s/\\right\}/\}/g;
    
    # sqrt(3,4) means the 4 root of 3
    $string =~s/\\sqrt{([^,]+),([^\}]+)}/\\sqrt[$2]{$1}/gs;

    # remove the extra () in the denominator of a \frac
    $string =~s/\\frac{(.+?)}{\\left\((.+?)\\right\)}/\\frac{$1}{$2}/gs;

    &Apache::lonnet::logthis($string);
    return $string;
}
1;
__END__