### Version 0.3, April 3, 1997
### extended math-parsing, when $NO_SIMPLE_MATH is set
### Version 0.4, July, August 1997 by Ross Moore
### extended math-parsing, when $NO_SIMPLE_MATH is set
### Version 0.5, many modifications and extensions
### made during 1997 and 1998 by Ross Moore
## Copyright (C) 1995 by Marcus E. Hennecke
## This program 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.
## This program 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 this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
if ($HTML_OPTIONS =~ /math/) {
do { $DOCTYPE = ''; $STRICT_HTML = 0 }
unless ($NO_SIMPLE_MATH||$NO_MATH_PARSING);
}
#########################
## Support HTML 3.0 math
#### Mathematical Formulas
package main;
sub do_env_math {
local($_) = @_;
local($math_mode, $failed, $labels, $comment,$img_params) = ("inline",'','');
$failed = (/$htmlimage_rx|$htmlimage_pr_rx/); # force an image
local($attribs, $border);
if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
local($saved) = $_;
($labels, $comment, $_) = &process_math_env($math_mode,$_);
if ($failed) {
$_ = join ('', $comment, $labels
, ($USING_STYLES ? '' : '')
, &process_undefined_environment("tex2html_wrap", $id, $saved)
, ($USING_STYLES ? '' : ''))
} elsif ($NO_SIMPLE_MATH) {
if ($USING_STYLES) {
$_ = join('', $comment, $labels
, '', $_ , "");
} else {
$_ = join('', $comment, $labels, " ", $_ );
}
} else {
$_ = join('', $comment, $labels, "");
}
if (($border||($attributes))&&($HTML_VERSION > 2.1 )) {
&make_table( $border, $attribs, '', '', '', $_ )
} else { $_ }
}
$math_start_rx = "(\\\$|\\\\\\(|\\\\math\\b)(\\begin(($O|$OP)\\d+($C|$CP))tex2html_wrap\\4)?";
$math_end_rx = "(\\end(($O|$OP)\\d+($C|$CP))tex2html_wrap\\7)?(\\\$|\\\\\\)|\\\\endmath\\b)";
sub do_env_tex2html_wrap {
local($_) = @_;
local($math_mode, $failed, $labels, $comment,$img_params) = ("inline",'','');
$failed = (/$htmlimage_rx|$htmlimage_pr_rx/); # force an image
local($attribs, $border);
if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
$* = 1; s/^\s*|\s*$//g; $*=0;
local($saved) = $_;
# if (s/^\\\(|^\$|^\\math|\\\)$|\$$|\\endmath//g) {}
if (s/^$math_start_rx|${math_end_rx}$//g) {}
elsif (/^\\ensuremath/om) { }
else { $failed = 1 }; # catch non-math environments or commands
($labels, $comment, $_) = &process_math_env($math_mode,$_);
if ($failed) {
$_ = join ('', $comment, $labels
, &process_undefined_environment("tex2html_wrap", $id, $saved));
} elsif ($NO_SIMPLE_MATH) {
# no need for comment/labels if already inside a math-env
if (defined $math_outer) { s/^\s*|\s*$//g }
else { $_ = $comment . $labels ." ".$_; }
} else {
$_ = $comment . $labels . "";
}
if (($border||($attribs))&&($HTML_VERSION > 2.1 )) {
&make_table( $border, $attribs, '', '', '', $_ )
} else { $_ }
}
sub do_env_tex2html_wrap_inline {
local($_) = @_;
local($math_mode, $failed, $labels, $comment) = ("inline",'','');
$failed = (/$htmlimage_rx|$htmlimage_pr_rx/); # force an image
local($attribs, $border);
if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
local($saved) = $_;
# s/(^\s*(\$|\\\()\s*|\s*(\$|\\\))\s*$)//g; # remove the \$ signs or \(..\)
# s/^\\ensuremath(($O|$OP)\d+($C|$CP))(.*)\1/$4/; # remove an ensuremath wrapper
if (s/^$math_start_rx|$math_end_rx$//gs ) {}
elsif (s/^\\ensuremath(($O|$OP)\d+($C|$CP))(.*)\1/$4/){} # remove an ensuremath wrapper
else { $failed = 1 }
s/\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_wrap\w*\2//g; # remove wrappers
$_ = &translate_environments($_) unless (($NO_SIMPLE_MATH)||($failed));
($labels, $comment, $_) = &process_math_env($math_mode,$_);
if ($failed) {
if ($USING_STYLES) {
$env_id =~ s/\"$/ image\"/;
$env_id = ' CLASS="MATH"' if ($env_id =~ /^\s*$/);
$_ = join ('', $labels, $comment, ""
, &process_undefined_environment("tex2html_wrap_inline", $id, $saved)
, "");
} else {
$_ = join ('', $labels, $comment
, &process_undefined_environment("tex2html_wrap_inline", $id, $saved));
}
} elsif (($NO_SIMPLE_MATH)&&($USING_STYLES)) {
$env_id = ' CLASS="MATH"' if ($env_id =~ /^\s*$/);
$_ = join('', $labels, $comment, "", $_, "");
} elsif ($NO_SIMPLE_MATH) {
$_ = join('', $labels, $comment, $_);
} else {
$_ = join('', $labels, $comment, "");
}
if (($border||($attribs))&&($HTML_VERSION > 2.1 )) {
&make_table( $border, $attribs, '', '', '', $_ )
} else { $_ }
}
# Allocate a fixed width for the equation-numbers:
#$seqno = "\n";
$mvalign = ' VALIGN="MIDDLE"';
sub do_env_equation {
local($_) = @_;
local($math_mode, $failed, $labels, $comment) = ("equation",'','');
$failed = (/$htmlimage_rx|$htmlimage_pr_rx/); # force an image
local($attribs, $border);
if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
local($saved) = $_;
local($sbig,$ebig);
($sbig,$ebig) = ('','')
if (($DISP_SCALE_FACTOR)&&($DISP_SCALE_FACTOR >= 1.2 ));
local($math_start,$math_end)= ($sbig,$ebig);
local($eqno) = ' '; # spacer, when no numbering
local($seqno) = join('',"\n | \n");
$* = 1;
do { # include the equation number, using a
$global{'eqn_number'}++;
$eqno = join('', $EQNO_START
, &simplify(&translate_commands('\theequation'))
, $EQNO_END);
} unless ((s/(\\nonumber|\\notag)//g)||(/\\tag/));
if (s/\\tag(\*)?//){
# AmS-TEX line-number tags.
local($nobrack,$before) = ($1,$`);
$_ = $';
s/next_pair_pr_rx//o;
if ($nobrack) { $eqno = $2 }
else { $eqno = join('',$EQNO_START, $2, $EQNO_END ) }
$_ = $before;
}
$* = 0;
local($halign) = " ALIGN=\"CENTER\"" unless $FLUSH_EQN;
if ($EQN_TAGS =~ /L/) {
# equation number on left
($math_start,$math_end) =
( "\n\n" . $seqno . $eqno
. "\n$sbig"
, "$ebig | \n ");
$border = $attribs = $env_id = '';
} else {
# equation number on right
($math_start,$math_end) =
("\n\n | "
. "$sbig"
, "$ebig | ". $seqno . $eqno ." \n ");
$border = $attribs = $env_id = '';
}
($labels, $comment, $_) = &process_math_env($math_mode,$_);
if ($failed) {
$_ = join ('', $comment, $labels, $math_start
, &process_undefined_environment('displaymath', $id, $saved)
, $math_end );
} elsif ($NO_SIMPLE_MATH) {
$_ = join('', "", $labels
, $comment, $math_start, "\n$_\n"
, $math_end, " " );
} else {
$_ = join('', ""
, $labels, $comment, $math_start
, "\n", $math_end );
}
if (($border||($attribs))&&($HTML_VERSION > 2.1 )) {
join(''," \n \n"
, &make_table( $border, $attribs, '', '', '', $_ )
, "\n ");
} else { $_ }
}
sub do_env_displaymath {
local($_) = @_;
local($math_mode, $failed, $labels, $comment) = ("display",'','');
$failed = (/$htmlimage_rx|$htmlimage_pr_rx/); # force an image
local($attribs, $border);
if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) }
local($saved) = $_;
local($sbig,$ebig);
($sbig,$ebig) = (' ','')
if (($DISP_SCALE_FACTOR)&&($DISP_SCALE_FACTOR >= 1.2 ));
($labels, $comment, $_) = &process_math_env($math_mode,$_);
if ($failed) {
$_ = join('', $comment, " " , $labels
, &process_undefined_environment("displaymath", $id, $saved )
, ' ' );
} elsif ($NO_SIMPLE_MATH) {
$_ =~ s/ /$&$sbig/sg;
$_ = "$comment\n$labels\n$sbig$_$ebig\n "
} else {
$_ = join('', $comment, "", $labels
, "$sbig\n\n$ebig ");
}
if (($border||($attribs))&&($HTML_VERSION > 2.1 )) {
join(''," \n\n"
, &make_table( $border, $attribs, '', '', '', $_ )
, "\n ");
} else { $_ }
}
### Some Common Structures
## Declare math mode and take care of sub- and superscripts. Also make
## sure to treat curly braces right.
sub make_math {
local($math_mode,$math_style,$math_face,$_) = @_;
# Do spacing
s/\\,/;SPMthinsp;/g;
s/\\!/;SPMnegsp;/g;
s/\\:/;SPMsp;/g;
s/\\;/;SPMthicksp;/g;
s/((^|[^\\])(\\\\)*)\\ /$1\\space /g; # convert \ to \space
s/\\limits/\&limits;/g; # preserve the \limits commands
# Find all _ and ^, but not \_ and \^
s/\\_/\\underscore/g;
s/\\^/\\circflex/g;
#RRM: The following code is just plain wrong !!!
# local(@terms) = split(/([_^])/);
# local($math,$i,$subsup,$level);
# # Do the sub- and superscripts
# $math = $terms[$[];
# for ( $i = $[+1; $i <= $#terms; $i+=2 ) {
# $subsup = ( $terms[$i] eq "_" ? "SUB" : "SUP" );
# $_ = $terms[$i+1];
# if ( s/$next_pair_rx// ) {
# $math .= "<$subsup>$2$subsup>$_";
# } else {
# s/^\s*(\w|\\[a-zA-Z]+)//;
# $math .= "<$subsup>$1$subsup>$_";
# };
# };
# $_ = $math;
#RRM: This works much better (from &simple_math_env ).
if ($NO_SIMPLE_MATH) {
s/\&ldots;/.../g;
$_ = &translate_math_commands($math_mode,$math_style,$math_face,0,$_);
# remove redundant tags
s/ \s*<\/I>//go;
s/<\/I>(\s*)/$1/go;
} else {
s/\^$any_next_pair_rx/$2<\/SUP>/go;
s/_$any_next_pair_rx/$2<\/SUB>/go;
s/\^(\\[a-zA-Z]+|.)/$1<\/SUP>/g;
s/_(\\[a-zA-Z]+|.)/$1<\/SUB>/g;
}
s/\\underscore/\\_/g;
s/\\circflex/\\^/g;
s/&limits;//g; # not implemented, except via an image
# Translate all commands inside the math environment
$_ = &translate_commands($_) unless ($NO_SIMPLE_MATH);
if ($NO_SIMPLE_MATH) {
s/{/{/g; s/}/}/g;
s/\s*×\s*/ x<\/TT> /g;
# s/\s*×\s*/ × /g;
s/\s*÷\s*/ ÷ /g;
s/\s*&circ?;\s*/o<\/TT>/g;
s/\s**\s*/ \*<\/TT> /g;
s/\s*&l?dots;\s*/.../g;
s/\s*∣\s*/ | /g;
s/\s*|\s*/\|/g;
s/\s*∥\s*/ || /g;
s/;SPM(thin)?sp;/ /g; s/ / /g; s/&sp;/ /g;
s/;SPMthicksp;/ /g; s/&thicksp;/ /g; s/ / /g;
# &replace_math_constructions($math_mode);
} else {
# Inside |