--- loncom/xml/lontexconvert.pm 2001/05/03 21:28:53 1.1 +++ loncom/xml/lontexconvert.pm 2005/02/24 09:06:14 1.50 @@ -1,70 +1,143 @@ # The LearningOnline Network with CAPA # TeX Conversion Module # -# 05/29/00,05/30,10/11,10/20 Gerd Kortemeyer -# 05/03/2001 Scott Harrison +# $Id: lontexconvert.pm,v 1.50 2005/02/24 09:06:14 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 tth(); use vars qw($errorstring); -use Apache::lonmsg; +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; - my $addhead=< - if (window.location.pathname!="/res/adm/pages/menu.html") { - menu=window.open("","LONCAPAmenu"); - menu.currentURL=window.location.href; - } - -END - if ($ENV{'browser.mathml'}) { - &tth::ttminit(); - return '' - .'' - .']>' - .'' - ."$addhead" - ."\n"; - } else { - &tth::tthinit(); - my $headerstring=''; - if ($ENV{'browser.os'} eq 'mac') { - $headerstring.="\n" - .'' - ."\n$addhead\n"; - } - else { - $headerstring.="$addhead"; - } - return $headerstring."\n"; - } + $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*\
/\/g; - $xmlstring=~s/\/\/g; - $xmlstring=~s/\/\\<\/p\>/g; - $errorstring.=&tth::ttmerror(); - } else { - $xmlstring=&tth::tth($$texstring); - $errorstring.=&tth::ttherror(); - } - return $xmlstring; + my $xmlstring='['.&mt('UNDISPLAYABLE').']'; + if ($Apache::lontexconvert::messedup) { + return '['.&mt('TeX unconverted due to previous errors').']'; + } + eval(<<'ENDCONV'); + ($xmlstring,$errorstring)=&convert_real($texstring) +ENDCONV + if ($@) { + $errorstring.=&mt("Evaluation Error: ").$@; + $Apache::lontexconvert::messedup=1; + } + if ($Apache::lontexconvert::messedup || &tth::tthmessedup() || + $errorstring) { + &Apache::lonnet::logthis("Trying to kill myself"); + $Apache::lontexconvert::messedup=1; + my $request=Apache->request(); + $request->child_terminate(); + } + return $xmlstring; } # ====================================================================== Footer @@ -77,10 +150,111 @@ sub footer { &Apache::lonmsg::author_res_msg($ENV{'request.filename'},$errorstring); } # -------------------------------------------------------------------- End Body - $xmlstring.=''; + $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 =~/\\left\{/\{/g;
+    # $string =~/\\right\}/\}/g;
+    # $string =~/\\fun/ /g;
+
+    return $string;
+}
 1;
 __END__