--- loncom/xml/londefdef.pm 2002/10/08 20:18:36 1.93 +++ loncom/xml/londefdef.pm 2023/03/25 22:11:11 1.471 @@ -1,8 +1,8 @@ # The LearningOnline Network with CAPA -# Tags Default Definition Module +# Tags Default Definition Module +# +# $Id: londefdef.pm,v 1.471 2023/03/25 22:11:11 raeburn Exp $ # -# $Id: londefdef.pm,v 1.93 2002/10/08 20:18:36 sakharuk Exp $ -# # # Copyright Michigan State University Board of Trustees # @@ -25,2518 +25,4819 @@ # /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 +## 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 +# 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. # -# -# last modified 06/26/00 by Alexander Sakharuk -# 11/6,11/30,02/01/01,5/4 Gerd Kortemeyer -# 01/18 Alex Sakharuk -package Apache::londefdef; +package Apache::londefdef; use Apache::lonnet; use strict; use Apache::lonxml; -use Apache::File(); +use Apache::lontable; use Image::Magick; +use Apache::lonmenu(); +use Apache::lonmeta(); +use Apache::lonlocal; +use Apache::loncommon(); +use Apache::Constants qw(:common); +use File::Basename; +use LONCAPA(); +# use Data::Dumper; BEGIN { - &Apache::lonxml::register('Apache::londefdef',('a','abbr','acronym','address','allow','applet','area','b','base','basefont','bgo','bgsound','big','blink','blockquote','blankspace','body','br','button','caption','center','cite','code','col','colgroup','dd','del','dfn','dir','div','dl','dt','em','embed','externallink','fieldset','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','i','iframe','img','input','ins','insert','isindex','kbd','keygen','label','layer','legend','li','link','m','map','marquee','menu','meta','multicol','nobr','noembed','noframes','nolayer','noscript','object','ol','optgroup','option','output','p','param','pre','q','s','samp','select','server','small','spacer','span','strike','strong','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','u','ul','var','wbr')); + &Apache::lonxml::register('Apache::londefdef',('a','abbr','acronym','accessrule','address','allow','applet','area','b','base','basefont','bgo','bgsound','big','blink','blockquote','blankspace','body','br','button','caption','center','cite','code','col','colgroup','dd','del','dfn','dir','div','dl','dt','em','embed','externallink','fieldset','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','i','iframe','img','input','ins','insert','isindex','kbd','keygen','label','layer','legend','li','link','m','map','marquee','menu','meta','multicol','nobr','noembed','noframes','nolayer','noscript','object','ol','optgroup','option','output','p','param','pre','q','s','samp','select','server','small','spacer','span','strike','strong','style','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','tthoption','u','ul','var','wbr','hideweboutput')); + +} + +sub initialize_londefdef { + $Apache::londefdef::TD_redirection=0; + @Apache::londefdef::table = (); + $Apache::londefdef::select=0; + undef(@Apache::londefdef::description); + @Apache::londefdef::DD=(0); + @Apache::londefdef::DT=(0); + @Apache::londefdef::seenDT=(0); + $Apache::londefdef::list_index=0; + undef($Apache::londefdef::head); + undef($Apache::londefdef::title); } #======================= TAG SUBROUTINES ===================== #-- sub start_output { - my ($target) = @_; - if ($target eq 'meta') { $Apache::lonxml::metamode--; } - return ''; + my ($target) = @_; + if ($target eq 'meta') { $Apache::lonxml::metamode--; } + return ''; } sub end_output { - my ($target) = @_; - if ($target eq 'meta') { $Apache::lonxml::metamode++; } - return ''; + my ($target) = @_; + if ($target eq 'meta') { $Apache::lonxml::metamode++; } + return ''; } #-- tag sub start_m { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $Apache::lonxml::prevent_entity_encode++; - my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser); - $inside ='\\documentstyle{article}'.$inside; - &Apache::lonxml::debug("M is starting with:$inside:"); - my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval); - if ($eval eq 'on') { - $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]); - #&Apache::lonxml::debug("M is evaulated to:$inside:"); - } - $currentstring = &Apache::lontexconvert::converted(\$inside); - if ($Apache::lontexconvert::errorstring) { - &Apache::lonxml::warning("tth error: ". - $Apache::lontexconvert::errorstring); - $Apache::lontexconvert::errorstring=''; - } - #&Apache::lonxml::debug("M is ends with:$currentstring:"); - } elsif ($target eq 'tex') { - $currentstring = &Apache::lonxml::get_all_text_unbalanced("/m",$parser); - if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';} - } else { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; + my $currentstring = ''; my $inside = &Apache::lonxml::get_all_text_unbalanced("/m",$parser); - } - return $currentstring; + if ($target eq 'web' || $target eq 'analyze') { + &Apache::lonxml::debug("M is starting with:$inside:"); + if (!($inside =~ /^\s*\$.*\$\s*$/ || $inside =~ /^\s*\\[([].*\\[)\]]\s*$/)) { + # Non-math LaTeX will not be rendered correctly with MathJax + # and it should be avoided anyway. + # On top of that, MathJax will render math without $, but + # it will fail with tth. This is worth a warning. + # (even though some people might just use latex for printing) + &Apache::lonxml::warning(&mt('Missing $ in [_1].','<m>')); + } elsif (($env{'browser.type'} eq 'safari') && ($env{'form.editxmltext'}) && + (($env{'form.problemmode'} eq 'view') || ($env{'form.problemmode'} eq 'discard'))) { + my $delimiter; + if ($inside =~ /\$$/) { + $delimiter = '$'; + } elsif ($inside =~ /\\([)\]])$/) { + $delimiter = $1; + } + if ($delimiter) { + &Apache::lonxml::warning(&mt('Insert a space between [_1] and [_2].', + $delimiter,'</m>')); + } + } + my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval); + if ($eval eq 'on') { + $inside=&Apache::run::evaluate($inside,$safeeval,$$parstack[-1]); + #&Apache::lonxml::debug("M is evaluated to:$inside:"); + } + my $tex = $inside; + my $display=&Apache::lonxml::get_param('display',$parstack,$safeeval); + $currentstring = &Apache::lontexconvert::converted(\$inside,$display); + if ($Apache::lontexconvert::errorstring) { + my $errormsg='
'.&HTML::Entities::encode($Apache::lontexconvert::errorstring,'<>&"').'
occurred while attempting to convert this TeX:
';
+	    $tex = &HTML::Entities::encode($tex,'<>&"');
+	    my ($linenumber) =
+		($Apache::lontexconvert::errorstring =~ /Line (\d+)/);
+	    if (defined($linenumber)) {
+		my @tex=split("\n",$tex);
+		$tex[$linenumber]=''.
+		    $tex[$linenumber].'';
+		$tex=join("\n",@tex);
+	    }
+	    &Apache::lonxml::warning($errormsg.$tex.'
'); + $Apache::lontexconvert::errorstring=''; + } + #&Apache::lonxml::debug("M is ends with:$currentstring:"); + $Apache::lonxml::post_evaluate=0; + } elsif ($target eq 'tex') { + + $currentstring = $inside; + my $eval=&Apache::lonxml::get_param('eval',$parstack,$safeeval); + if ($eval eq 'on') { + $currentstring=&Apache::run::evaluate($currentstring,$safeeval,$$parstack[-1]); + } + if ($currentstring=~/^(\s*\\\\\s*)*$/) {$currentstring = ' \vskip 0 mm ';} + # detect simple math mode entry exits, and convert them + # to use \ensuremath ... unless there's a \verb inside. + if (! ($currentstring=~/\\verb/)) { + if ($currentstring=~/^\s*\$[^\$].*\$\s*$/) { + $currentstring=~s/^(\s*)\$/$1/; + $currentstring=~s/\$(\s*)$/$1/; + $currentstring='\ensuremath{'.$currentstring.'}'; + } + } + $Apache::lonxml::post_evaluate=0; + } + return $currentstring; } + sub end_m { - my ($target,$token) = @_; - my $currentstring = ''; - if ($target eq 'web') { - $Apache::lonxml::prevent_entity_encode--; - } elsif ($target eq 'tex') { - $currentstring = ""; - } elsif ($target eq 'meta') { - } - return $currentstring; -} -#-- tag - sub start_html { - my ($target,$token) = @_; - my $currentstring = ''; - if ($ENV{'browser.mathml'}) { - &tth::ttminit(); - } else { - &tth::tthinit(); + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'tex') { + $currentstring = ""; + } + return $currentstring; +} + +sub start_tthoption { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style) = @_; + my $result; + if ($target eq 'web' || $target eq 'webgrade') { + my $inside = &Apache::lonxml::get_all_text("/tthoption",$parser, + $style); + $inside=~s/^\s*//; + if ($env{'browser.mathml'}) { + &tth::ttmoptions($inside); + } else { + &tth::tthoptions($inside); + } + } + return $result; +} + +sub end_tthoption { + my ($target,$token) = @_; + my $result; + return $result; +} + +#-- tag (end tag optional) +sub start_html { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'edit' || $target eq 'webgrade' ) { + # start_body() takes care of emitting the + } elsif ($target eq 'tex') { + + $currentstring .= &latex_header(); + } + return $currentstring; +} + +sub end_html { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + # end_body takes care of the + } + return $currentstring; +} + +#-- tag (end tag optional) +sub start_head { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + &Apache::lonxml::startredirection(); + } + return $currentstring; +} + +sub end_head { + my ($target,$token) = @_; + my $currentstring = ''; + if (($target eq 'web' && $env{'request.state'} eq 'published') || + ($target eq 'webgrade' && $env{'request.state'} eq 'published')) { + # in case there is a but no + if ($Apache::lonxml::redirection) { + $Apache::londefdef::head = &Apache::lonxml::endredirection(); + } + } + return $currentstring; +} + +#-- tag (end tag required) +sub start_map { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_map { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#-- tag (end tag forbidden) +sub start_input { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[4]; + } + return $currentstring; +} + +sub end_input { + my ($target,$token) = @_; + my $currentstring = ''; + if ($target eq 'web' || $target eq 'webgrade') { + $currentstring = $token->[2]; + } + return $currentstring; +} + +#--