1# more_amsmath.perl 2# by Ross Moore <ross@mpce.mq.edu.au> 1-19-98 3# 4# Extension to LaTeX2HTML to load further features from 5# the AMS packages, using advanced parsing 6# This package requires the `math' extension to be loaded 7# e.g. via switches: 8# 9# -no_math -html_version 3.2,math 10# OR -no_math -html_version 4.0,math 11# 12# This extension is loaded automatically from amstex.perl 13# when the \usepackage{amstex} or \usepackage{amsmath} 14# commands are used. 15# 16# Change Log: 17# =========== 18 19package main; 20# 21 22if ($HTML_VERSION < 3) { 23 print "\n*** advanced features of the AMS math packages require HTML 3.2 or later ***\n"; 24 return(1); 25} 26 27$display_env_rx = join('|', $display_env_rx 28 ,'gather','multline','align','split'); 29 30sub do_htmlmath_array { 31 local($colspec) = @_; 32 if (defined &do_env_array) { 33 join('', $comment, "<P ALIGN=\"CENTER\">$sbig" 34 , $labels, "\n<MATH CLASS=\"EQNARRAY\">" 35 , &do_env_array("$O$max_id${C}$colspec$O$max_id$C$_") 36 , "</MATH>\n$ebig</P>" ) 37 } else { 38 join('', $comment, '<P ALIGN="CENTER">', $labels, 39 , &process_undefined_environment($env, $id , $_),'</P>') 40 } 41} 42 43 44sub set_math_size { 45 local($mode) = @_; 46 local($ssize,$esize); 47 ($ssize,$esize) = ("<BIG>","</BIG>") 48 if (!($mode =~ /inline/)&&($DISP_SCALE_FACTOR) 49 &&($DISP_SCALE_FACTOR >= 1.2 )); 50 if ($USING_STYLES) { 51 $ssize .= '<SPAN CLASS="MATH">'; 52 $esize = '</SPAN>'.$esize; 53 } 54 ($ssize,$esize) 55} 56 57sub set_math_valign { 58 local($numbering) = @_; 59 if (($numbering)&&(/^\s*\\begin<([<#])(\d+)([#>])>($array_env_rx)/)) { 60 #RRM: align on the middle, if a array-environment follows... 61 # (since aligning to the top/bottom of a table looks terrible) 62 " VALIGN=\"MIDDLE\"" 63 } else { 64 # ...otherwise align on the baseline, where possible 65 join(''," VALIGN=\"", 66 ($NETSCAPE_HTML)? "BASELINE" : "MIDDLE","\""); 67 } 68} 69 70sub get_eqn_number { 71 local($outer_num, $scan) = @_; 72 # an explicit \tag overrides \notag , \nonumber or *-variant 73 local($labels,$tag); 74 ($scan,$labels) = &extract_labels($scan); # extract labels 75 $scan =~ s/\n/ /g; 76 if ($scan =~ s/\\tag(\*|star\b)?\s*(($O|$OP)\d+($C|$CP))(.*)\2//) { 77 local($star) = $1; $tag = $5; 78 $tag = &translate_environments($tag) if ($tag =~ /\\begin/); 79 $tag = &translate_commands($tag) if ($tag =~ /\\/); 80 $tag = (($star)? $tag : $EQNO_START.$tag.$EQNO_END ); 81 } elsif (($outer_num)&&(!($scan)||!($scan =~ s/\\no(tag|number)//)) 82 &&(!($scan =~ /^\s*\\begin(<(<|#)\d+(>|#)>)($outer_math_rx)\b/)) 83 ){ 84 $global{'eqn_number'}++ ; 85 if ($subequation_level) { 86 local($sub_tag) = &get_counter_value('equation'); 87 $tag = join('', $EQNO_START 88 , $eqno_prefix 89 , &falph($sub_tag) 90 , $EQNO_END); 91 } else { 92 $tag = join('', $EQNO_START 93 , &simplify(&translate_commands('\theequation')) 94 , $EQNO_END); 95 } 96 } else { $tag = ';SPMnbsp;;SPMnbsp;;SPMnbsp;' } 97 if ($labels) { 98 $labels =~ s/$anchor_mark/$tag/o; 99 ($labels , $scan); 100 } else { ($tag , $scan) } 101} 102 103$outer_math_rx = "(fl|x|xx)?align(at)?|multline|gather|(sub)?equation"; 104 105sub get_mult_eqn_number { 106 local($num_rows,$valign, $scan) = @_; 107 local($align,$tag); 108 $align = " VALIGN=\"$valign\"" if $valign; 109 ($tag,$scan) = &get_eqn_number(1,$scan); 110 $tag = join('', $align, " ROWSPAN=$num_rows", $etag , $tag); 111 ($tag , $scan); 112} 113 114sub start_math_display { 115 join('' 116# , (($border||($attribs)||!($outer_math))? '': "<P></P>") 117 , ((($doimage)||!($outer_math))? '': "\n<DIV$math_class>") 118 , (($labels)? $labels : '') , $comment 119 , @_ ); 120} 121 122sub end_math_display { 123 join('', @_ , ((($doimage)||!($outer_math))? '' : 124 "</DIV>\n<BR CLEAR=\"ALL\">" )); 125} 126 127sub embed_display { 128 # cancel <BIG> tags when alignment inside subequations 129 return( join('', $ebig, @_[0], $sbig) ) 130 if ($outer_math && $subequation_level); 131 # just return contents when alignment inside equation/multline 132 return(@_[0]) if $outer_math; 133 134 # at the outermost level 135 if (($border)||($attribs)) { 136 join('',"<BR>\n<DIV$math_class>\n" 137 , &make_table( $border, $attribs, '', '', '', @_ ) 138 , "\n<BR CLEAR=\"ALL\">"); 139 } else { join('', "<P></P>", @_ , "<P></P>") } 140} 141 142$smdiv_rx = "<(BR|DIV)"; 143$spdisplay = (($HTML_VERSION > 3.1)? "<DIV ":"<P "). "ALIGN=\"CENTER\">"; 144$epdisplay = (($HTML_VERSION > 3.1)? "</DIV>\n":'')."<BR CLEAR=\"ALL\">\n<P>"; 145$mdisp_width = " WIDTH=\"100%\""; 146$smarray = "<TABLE"; 147$smarrayB = " CELLPADDING=\"0\""; 148$emarray = "\n</TABLE>"; 149$smrow = "\n<TR"; # must be followed by alignment or ">" 150$emrow = "</TR>"; 151$emtag = ">"; 152$smncell = "\n<TD NOWRAP"; 153$smcell = "\n<TD"; 154$emcell = "</TD>"; 155$mcalign = " ALIGN=\"CENTER\">"; 156$mlalign = " ALIGN=\"LEFT\">"; 157$mralign = " ALIGN=\"RIGHT\">"; 158$mvalign = " VALIGN=\"MIDDLE\""; 159$smlcell = $smncell.$mlalign; 160$smccell = $smncell.$mcalign; 161$smrcell = $smncell.$mralign; 162$mnocell = "\n<TD>"; 163$mspace = "\ "; 164$mdlim = $html_specials{'&'}; 165 166$lseqno = "$eqno_class WIDTH=\"10\" ALIGN=\"LEFT\">\n"; 167$rseqno = "$eqno_class WIDTH=\"10\" ALIGN=\"RIGHT\">\n"; 168 169 170# do these indirectly, so that they only over-ride the existing 171# ones when the right combination of packages is present. 172 173eval "sub do_env_equation { \&process_env_equation(1,\@_); }"; 174eval "sub do_env_equationstar { \&process_env_equation(0,\@_); }"; 175 176sub do_env_subequations { 177 local($contents) = @_[0]; 178 local($prev_eqn_number) = $global{'eqn_number'}++; 179 local($eqno_prefix) = &translate_commands('\theequation'); 180 $eqno_prefix =~ s/\s+$//; 181 ++$subequation_level; 182 local($outer_math) = 'subequations' unless $outer_math; 183 $global{'eqn_number'} = 0; 184 $contents = &process_env_equation(1, $contents); 185 --$subequation_level; 186 $global{'eqn_number'} = ++$prev_eqn_number; 187 $contents; 188} 189 190sub process_env_equation { 191 local($numbered, $_) = @_; 192 local($math_mode, $failed, $labels, $comment, $doimage) = ("equation",'','','',''); 193 local($attribs, $border); 194 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 195 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 196 local($saved) = &revert_array_envs($_); 197 local($falign) = 'CENTER'; 198 local($sbig,$ebig)= &set_math_size($math_mode); 199 $failed = 1 if ($NO_SIMPLE_MATH); # simplifies the next call 200 ($labels, $comment, $_) = &process_math_env($math_mode,$_); 201 $failed = 0; 202 203 $failed = (/$htmlimage_rx|$htmlimage_pr_rx/); # force an image 204 local($outer_math) = $env unless ($outer_math); 205 206 if ($USING_STYLES) { 207 $env_id =~ s/(CLASS=\")(\w+)/$1$outer_math/; 208 $env_style{$outer_math} = "" unless ($env_style{$outer_math}); 209 $env_id = ' CLASS="'.$outer_math.'"' unless $env_id; 210 } 211 212 if ($failed) { 213 local($this_env) = $outer_math; 214 if (!($this_env =~ s/(star|\*)$/\*/)) { $global{'eqn_number'}++ }; 215 $_ = &process_undefined_environment($this_env, $id, $saved); 216 $falign = (($EQN_TAGS =~ /L/)? 'LEFT' : 'RIGHT') if $numbered; 217 local($fsdisplay,$fedisplay) = ($spdisplay,$epdisplay); 218 if (!($fsdisplay =~ s/(ALIGN\s*=\s*\")[^\"]*\"/$1$falign\"/)) { 219 $fsdisplay .= "<DIV$env_id ALIGN=\"$falign\">"; 220 $fedisplay = '</DIV>'.$epdisplay; 221 } 222 $_ = join('', $fsdisplay, $labels, $comment, $_, $fedisplay); 223 224 } elsif ($NO_SIMPLE_MATH) { 225# if ($NO_SIMPLE_MATH) { 226 $failed = 0; 227 s/$htmlimage_rx/$doimage = $&;''/eo ; # force an image 228 s/$htmlimage_pr_rx/$doimage .= $&;''/eo ; # force an image 229 local($valign) = &set_math_valign(); 230 local($sarray, $srow, $scell, $calign, $ecell, $erow, $earray); 231 232# local($env_id) = $env_id; 233# if ($USING_STYLES) { 234# $env_id =~ s/(CLASS=\")(\w+)/$1$outer_math/; 235# $env_style{$env} = "" unless ($env_style{$env}); 236# } 237 238 ($sarray, $erow, $earray, $sempty, $calign) = ( 239 $smarray.$env_id.$smarrayB.$mdisp_width.$mcalign 240 , $emrow , $emarray, $emcell.$mnocell, $mcalign ); 241 $env_id = ''; 242 243 local($return) = &start_math_display ( $sarray ); 244 245 local($eqno, $inner_numbered); 246 ($eqno, $_) = &get_eqn_number($numbered,$_); 247 local($valign) = &set_math_valign($eqno); 248 249 $_ = &protect_array_envs($_); 250 if ($_ =~ /\s*\\begin\s*$O\d+$C\s*align/) { 251 # no equation numbering --- handled by the inner-alignment 252 $inner_numbered = 1; 253 ($srow, $scell, $ecell) = ( 254 $smrow.$valign.$emtag, $smncell , $emcell); 255 $return .= $srow . $scell; 256 } elsif ($EQN_TAGS =~ /L/) { 257 # equation number on left 258 ($srow, $scell, $ecell) = ( 259# $smrow.$valign.$emtag.$smcell.$mcalign, $smncell , $emcell); 260 $smrow.$valign.$emtag.$smcell.$lseqno, $smncell , $emcell); 261 $return .= $srow . $eqno . $ecell . $scell; 262 } else { 263 # equation number on right 264 ($srow, $scell, $ecell) = ( 265 $smrow.$valign.$emtag , $smncell , $emcell); 266 $return .= $srow . $scell ; 267 } 268 269 if (s/\\shove(righ|lef)t//) { 270 local($whichway) = $1; 271 $return .= (($1 =~/lef/)? $mlalign : $mralign ); 272 if (($doimage)||($failed)) { 273 $_ = &process_math_in_latex("indisplay",'','' 274 , $doimage.$_ ) unless ($_ eq ''); 275 } else { 276 $_ = &make_math('display','','',$_) unless ($_ eq '') 277 } 278 if (!($_ eq '')) { 279 $return .= join('' 280 , (($whichway =~ /lef/)? $mspace.$mspace : '') 281 , ((/^$smarray/)? $_ : $sbig.$_.$ebig ) 282 , (($whichway =~ /lef/)? '' : $mspace.$mspace ) 283 , $ecell , $erow); 284 } else { $return .= join('', $mspace , $ecell, $erow); } 285 } else { 286 $thismath = $_; 287 $thismath =~ s/(^\s*|\s*$)//gm; 288 if (($doimage)||($failed)) { 289 $thismath = &process_math_in_latex("indisplay",'','' 290 , $doimage.$thismath ) unless ($thismath eq '' ); 291 } else { 292 if ($thismath =~ /$subAMS_array_env_rx/) { 293 $outer_math =~ s/(equation)(star)?$/$1star/; 294 $thismath = &make_math($outer_math,'','', $thismath); 295 } else { 296 $thismath = &make_math('display','','', $thismath) 297 unless ( $thismath eq '' ); 298 } 299 } 300 if ($thismath ne '') { 301 $return .= join('', $calign 302 , (($thismath =~ /^$smarray/)? $thismath 303 : $sbig . $thismath . $ebig ) 304 , $ecell); 305 } else { 306 $return .= join('', $sempty, "\ ", $ecell); 307 } 308 } 309# $return .= $smncell.$mcalign.$eqno.$ecell 310 $return .= $smncell.$rseqno.$eqno.$ecell 311 unless (($EQN_TAGS =~ /L/)||$inner_numbered); # eqn-num on right 312 $return .= $erow; 313 314 $_ = &end_math_display($return , $earray ); 315 } else { 316 $_ = &do_htmlmath_array('c'); 317 } 318 319 undef $outer_math unless ($subequation_level); 320 &embed_display($_); 321} 322 323 324### Multiline formulas 325 326 327sub do_env_multline { 328 &process_env_multline(1,@_); 329} 330sub do_env_multlinestar { 331 &process_env_multline(0,@_); 332} 333 334sub process_env_multline { 335 local($numbered, $_) = @_; 336 local($math_mode, $failed, $labels, $comment, $doimage) = ("equation",'','','',''); 337 local($attribs, $border); 338 local($outer_math) = $env unless ($outer_math); 339 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 340 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 341 local($saved) = $_; 342 local($sbig,$ebig)= &set_math_size($math_mode); 343 $failed = 1 if ($NO_SIMPLE_MATH); # simplifies the next call 344 ($labels, $comment, $_) = &process_math_env($math_mode,$_); 345 346 local($falign) = 'CENTER'; 347 $failed = (/$htmlimage_rx|$htmlimage_pr_rx/) unless ($outer_math); # force an image 348 local($outer_math) = $env unless ($outer_math); 349 350 if ($failed) { 351 $_ = &process_undefined_environment( 352 'multline'.(($numbered) ? '':"*"), $id, $saved); 353 $falign = (($EQN_TAGS =~ /L/)? 'LEFT' : 'RIGHT') if $numbered; 354 local($fsdisplay,$fedisplay) = ($spdisplay,$epdisplay); 355 if (!($fsdisplay =~ s/(ALIGN\s*=\s*\")[^\"]*\"/$1$falign\"/)) { 356 $fsdisplay .= "<DIV ALIGN=\"$falign\">"; 357 $fedisplay = '</DIV>'.$epdisplay; 358 } 359 $_ = join('', $fsdisplay, $labels, $comment, $_, $fedisplay); 360 361 } elsif ($NO_SIMPLE_MATH) { 362 $failed = 0; 363 s/$htmlimage_rx/$doimage = $&;''/eo ; # force an image 364 s/$htmlimage_pr_rx/$doimage .= $&;''/eo ; # force an image 365 local($valign) = &set_math_valign(); 366 local($sarray, $srow, $scell, $calign, $ecell, $erow, $earray); 367 368 local($env_id) = $env_id; 369 if ($USING_STYLES) { 370 $env_style{$env} = "" unless ($env_style{$env}); 371 } 372 ($sarray, $erow, $earray, $sempty, $calign) = ( 373 $smarray.$env_id.$smarrayB.$mdisp_width.$mcalign 374 , $emrow , $emarray, $emcell.$mnocell, $mlalign ); 375 $env_id = ''; 376 377 local($return) = &start_math_display ( $sarray ); 378 379 local($eqno); 380 ($eqno, $_) = &get_eqn_number($numbered,$_); 381 local($valign) = &set_math_valign($eqno); 382 383 $_ = &protect_array_envs($_); 384 385 if ($EQN_TAGS =~ /L/) { 386 # equation number on left 387 ($srow, $scell, $ecell) = ( 388# $smrow.$valign.$emtag.$smcell.$mcalign , $smncell , $emcell); 389 $smrow.$valign.$emtag.$smcell.$lseqno , $smncell , $emcell); 390 $return .= $srow . $eqno . $ecell . $scell; 391 } else { # equation number on right 392 ($srow, $scell, $ecell) = ( 393 $smrow.$valign.$emtag , $smncell, $emcell); 394 $return .= $srow . $scell ; 395 } 396 397 local(@rows,$thismath); 398 s/\\\\[ \t]*(\*|\[[^\]]*])/\\\\/g; # remove forced line-heights 399 @rows = split(/\\\\/); 400 $#rows-- if ( $rows[$#rows] =~ /^\s*$/ ); 401 local($row_cnt); 402 foreach (@rows) { # displaymath 403 if ($row_cnt) { 404 $eqno = '' if ($EQN_TAGS =~ /L/); 405 $calign = $mcalign; 406 $calign = $mralign if ($row_cnt == $#rows ); 407 $return .= $erow . $srow . $scell ; 408 } 409 $row_cnt++; 410 411 if (s/\\shove(righ|lef)t//) { 412 local($whichway) = $1; 413 $return .= (($1 =~/lef/)? $mlalign : $mralign ); 414 if (($doimage)||($failed)) { 415 $_ = &process_math_in_latex("indisplay",'','' 416 , $doimage.$_ ) unless ($_ eq ''); 417 } else { 418 $_ = &make_math('display','','',$_) unless ($_ eq '') 419 } 420 if (!($_ eq '')) { 421 $return .= join('' 422 , (($whichway =~ /lef/)? $mspace.$mspace : '') 423 , ((/^$smarray/)? $_ : $sbig.$_.$ebig ) 424 , (($whichway =~ /lef/)? '' : $mspace.$mspace ) 425 , $ecell , $erow); 426 } else { $return .= join('', $mspace , $ecell , $erow); } 427 next; 428 } 429 430 # columns to be set using \displaystyle 431 $thismath = $_; 432 $thismath =~ s/(^\s*|\s*$)//gm; 433 if (($doimage)||($failed)) { 434 $thismath = &process_math_in_latex("indisplay",'','' 435 , $doimage.$thismath ) unless ($thismath eq '' ); 436 } else { 437 $thismath = &make_math('displaymath','','' 438 , $thismath) unless ( $thismath eq '' ); 439 } 440 if ($thismath ne '') { 441 $return .= join('', $calign 442 , (($row_cnt == 1)? $mspace.$mspace : '') 443 , (($thismath=~/^$smarray/)? $thismath 444 : $sbig.$thismath.$ebig ) 445 , (($row_cnt == 1+$#rows )? $mspace.$mspace : '') 446 , $ecell); 447 } else { 448 $return .= join('', $sempty, "\ ", $ecell); 449 } 450 } 451 452# $return .= $smncell.$mcalign.$eqno.$ecell 453 $return .= $smncell.$rseqno.$eqno.$ecell 454 unless ($EQN_TAGS =~ /L/); # eqn-num on right 455 $return .= $erow; 456 457 $_ = &end_math_display($return , $earray ); 458 } else { 459 $_ = &do_htmlmath_array('c'); 460 } 461 undef $outer_math unless ($subequation_level); 462 &embed_display($_); 463} 464 465 466sub process_intertext { 467 local($eq_nums, $_) = @_; 468 local($text,$post); 469 s/\\intertext//o; $_ = $'; 470 local($pre) = $`; $pre =~ s/(^\s*|\s*$)//go; 471 local($span) = (/$mdlim/) + $eq_nums + 1; 472 $text = &missing_braces unless ( 473 (s/$next_pair_pr_rx/$text = $2;''/e) 474 ||(s/$next_pair_rx/$text = $2;''/e)); 475 $post = $_; $post =~ s/(^\s*|\s*$)//go; 476 $text = &translate_commands(&translate_environments($text)) 477 if ($text =~ /\\/); 478 $text = join('', $smrow, $emtag 479 , (($span > 1) ? $smcell." COLSPAN=$span".$mlalign : $smlcell) 480 , "<BR>", $text, "<P><BR>", $emcell, $emrow); 481 ($text, $pre . $post ); 482} 483 484sub do_env_align { 485 local($_) = @_; 486 local($math_mode, $attribs, $border) = ("equation",'',''); 487 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 488 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 489 $_ = &process_env_align(1,"align",'','',$_); 490 &embed_display($_); 491} 492 493sub do_env_alignstar { 494 local($_) = @_; 495 local($math_mode, $attribs, $border) = ("equation",'',''); 496 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 497 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 498 $_ = &process_env_align(0,"align*",'','',$_); 499 &embed_display($_); 500} 501 502sub do_env_alignat { 503 local($_) = @_; 504 local($aligns); 505 $aligns = &missing_braces unless ( 506 (s/$next_pair_pr_rx/$aligns = $2;''/e) 507 ||(s/$next_pair_rx/$aligns = $2;''/e )); 508 local($math_mode, $attribs, $border) = ("equation",'',''); 509 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 510 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 511 $_ = &process_env_align(1,"alignat",$aligns,'',$_); 512 &embed_display($_); 513} 514 515sub do_env_alignatstar { 516 local($_) = @_; 517 local($aligns); 518 $aligns = &missing_braces unless ( 519 (s/$next_pair_pr_rx/$aligns = $2;''/e) 520 ||(s/$next_pair_rx/$aligns = $2;''/e )); 521 local($math_mode, $attribs, $border) = ("equation",'',''); 522 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 523 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 524 $_ = &process_env_align(0,"alignat*",$aligns,'',$_); 525 &embed_display($_); 526} 527 528sub do_env_xalignat { 529 local($_) = @_; 530 local($aligns); 531 $aligns = &missing_braces unless ( 532 (s/$next_pair_pr_rx/$aligns = $2;''/e) 533 ||(s/$next_pair_rx/$aligns = $2;''/e )); 534 local($math_mode, $attribs, $border) = ("equation",'',''); 535 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 536 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 537 $_ = &process_env_align(1,"xalignat",$aligns,'',$_); 538 &embed_display($_); 539} 540 541sub do_env_xalignatstar { 542 local($_) = @_; 543 local($aligns); 544 $aligns = &missing_braces unless ( 545 (s/$next_pair_pr_rx/$aligns = $2;''/e) 546 ||(s/$next_pair_rx/$aligns = $2;''/e )); 547 local($math_mode, $attribs, $border) = ("equation",'',''); 548 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 549 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 550 $_ = &process_env_align(0,"xalignat*",$aligns,'',$_); 551 &embed_display($_); 552} 553 554sub do_env_xxalignat { 555 local($_) = @_; 556 local($aligns); 557 $aligns = &missing_braces unless ( 558 (s/$next_pair_pr_rx/$aligns = $2;''/e) 559 ||(s/$next_pair_rx/$aligns = $2;''/e )); 560 local($math_mode, $attribs, $border) = ("equation",'',''); 561 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 562 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 563 $_ = &process_env_align(1,"xxalignat",$aligns,'',$_); 564 &embed_display($_); 565} 566 567sub do_env_xxalignatstar { 568 local($_) = @_; 569 local($aligns); 570 $aligns = &missing_braces unless ( 571 (s/$next_pair_pr_rx/$aligns = $2;''/e) 572 ||(s/$next_pair_rx/$aligns = $2;''/e )); 573 local($math_mode, $attribs, $border) = ("equation",'',''); 574 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 575 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 576 $_ = &process_env_align(0,"xxalignat*",$aligns,'',$_); 577 &embed_display($_); 578} 579 580sub do_env_flalign { 581 local($_) = @_; 582 local($math_mode, $attribs, $border) = ("equation",'',''); 583 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 584 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 585 $_ = &process_env_align(1,"flalign",'','',$_); 586 &embed_display($_); 587} 588 589sub do_env_flalignstar { 590 local($_) = @_; 591 local($math_mode, $attribs, $border) = ("equation",'',''); 592 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 593 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 594 $_ = &process_env_align(0,"flalign*",'','',$_); 595 &embed_display($_); 596} 597 598sub do_env_gather { 599 local($_) = @_; 600 local($math_mode, $attribs, $border) = ("equation",'',''); 601 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 602 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 603 $_ = &process_env_align(1,"gather",'','c',$_); 604 &embed_display($_); 605} 606 607sub do_env_gatherstar { 608 local($_) = @_; 609 local($math_mode, $attribs, $border) = ("equation",'',''); 610 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 611 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 612 $_ = &process_env_align(0,"gather*",'','c',$_); 613 &embed_display($_); 614} 615 616sub process_env_align{ 617 # parameters 618 # $numbered : 0 = *-version, no implicit equation-numbering 619 # $outer-math : outer-most environment 620 # $num_aligns : expected number of alignment pairs per row 621 # $align_spec : alignment of rows without any `&'s 622 # $_ : the row/column data 623 # 624 # if $num_aligns is empty, count the number of cells delimiters (`&`) 625 # per row --- align columns alternating right-/left- 626 # 627 # use the $align_spec only when there is just a single column 628 # 629 local($numbered, $outer_math, $num_aligns, $align_spec, $_) = @_; 630 local($failed, $labels, $comment, $def_align) = ('','','',''); 631 local($saved)= $_; 632 local($falign)= 'CENTER'; 633 $saved = join('',"\\begin\{$env\}$num_aligns" 634 , $_, "\\end\{$env\}\n") if ($outer_math); 635 $num_aligns = 2*$num_aligns - 1 if ($num_aligns); 636 if ($align_spec =~ /(l|r)/) { 637 $def_align = (($1 eq 'l')? $smlcell : $smrcell ) } 638 elsif ($align_spec eq 'c') { $def_align = $smccell } 639# elsif (!$num_aligns) { $def_align = $smlcell } 640 elsif (!$num_aligns) { $def_align = $smccell } 641 642 local($sbig,$ebig)= &set_math_size($math_mode); 643 $failed = 1 if ($NO_SIMPLE_MATH); # simplifies the next call 644 ($labels, $comment, $_) = &process_math_env($math_mode,$_) 645 unless ($outer_math); 646 647 $failed = (/$htmlimage_rx|$htmlimage_pr_rx/); # force an image 648 if ($failed) { 649 local($this_env) = ($outer_math ? $outer_math : $env ); 650 if ($saved =~ s/^\s*\\begin((($O|$OP)\d+($C|$CP|))|\{)\Q$this_env\E(\2|\})//){ 651 $saved =~ s/\\end((($O|$OP)\d+($C|$CP))|\{)\Q$this_env\E(\2|\})\s*$//s; 652 } 653 $_ = &process_undefined_environment($this_env,$id,$saved); 654 655 $falign = (($EQN_TAGS =~ /L/)? 'LEFT' : 'RIGHT') if $numbered; 656 local($fsdisplay,$fedisplay) = ($spdisplay,$epdisplay); 657 if (!($fsdisplay =~ s/(ALIGN\s*=\s*\")[^\"]*\"/$1$falign\"/)) { 658 $fsdisplay .= "<DIV ALIGN=\"$falign\">"; 659 $fedisplay = '</DIV>'.$epdisplay; 660 } 661 $_ = join('', $fsdisplay, $labels, $comment, $_, $fedisplay); 662 663 } elsif ($NO_SIMPLE_MATH) { 664 $failed = 0; 665 s/$htmlimage_rx/$doimage = $&;''/eo ; # force images of parts 666 s/$htmlimage_pr_rx/$doimage .= $&;''/eo ; # force an image 667 668 local($env_id) = $env_id; 669 if ($USING_STYLES) { 670 $env_id =~ s/(CLASS=\")(\w+)/$1$outer_math/; 671 $env_style{$env} = "" unless ($env_style{$env}); 672 } 673 local($sarray, $erow, $earray, $sempty, $calign) = ( 674 $smarray.$env_id.$smarrayB.$mdisp_width.$mcalign, $emrow 675 , $emarray, $mnocell.$mspace, $mcalign ); 676 $env_id = ''; 677 678 local($valign, $scell, $eqno) = ($mvalign,'',''); 679 local($srow, $ecell, $slcell, $srcell) = ( 680 $smrow.$valign.$emtag , $emcell 681 , $smncell.$mlalign, $smncell.$mralign ); 682 683 local($return) = &start_math_display ( $sarray ); 684 685 # revert all protection, before protecting alignment in sub-envs 686 $_ = &revert_array_envs($_); 687 $_ = &protect_array_envs($_); 688 689 if ($EQN_TAGS =~ /L/) { 690 # equation number on left 691 ($srow, $scell, $ecell) = ( $smrow.$valign.$emtag.$smcell 692 , $smncell , $emcell); 693 } else { 694 # equation number on right 695 ($srow, $scell, $ecell) = ( 696 $smrow.$valign.$emtag , $smncell, $emcell ); 697 } 698 699 local($xcols) = '0'; 700 701 local(@rows, @cols, $eqno, $thismath); 702 s/\\\\[ \t]*(\*|\[[^\]]*])/\\\\/g; # remove forced line-heights 703 @rows = split(/\\\\/); 704 $#rows-- if ( $rows[$#rows] =~ /^\s*$/ ); 705 foreach (@rows) { # displaymath 706 next if (/^\s*$/); # ignore last row, if empty 707 708 if (/\\intertext/) { 709 local($extra_row); 710 #der -- David Rourke 711 #there is an equation-number cell, even if empty 712 #($extra_row,$_) = &process_intertext($numbered,$_); 713 ($extra_row,$_) = &process_intertext(1,$_); 714 $return .= $extra_row; 715 } 716 ($eqno, $_) = &get_eqn_number($numbered,$_); 717 $valign = &set_math_valign($eqno); 718 719 if ($EQN_TAGS =~ /L/) { 720# $return .= $srow.$mcalign.$eqno.$ecell 721 $return .= $srow.$lseqno.$eqno.$ecell 722 } else { $return .= $srow } 723 724 local($scell) = $srcell; # so 1st cell is right-aligned... 725 726 local($xcols) = $num_aligns - (/$mdlim/g); 727 if ($num_aligns) { 728 while ($xcols > 0) { $_ .= $mdlim; $xcols--; } 729 if ($xcols < 0) { 730 local($orig_code) = &revert_to_raw_tex($_); 731 &write_warnings("\ntoo many cols in alignment:\n\t$orig_code"); 732 print "\ntoo many columns in alignment:\n$orig_code\n"; 733 } 734 # ... unless there is no explicit alignment 735 } elsif ($xcols == 0) { $scell = $def_align } 736 737 if (s/\\shove(righ|lef)t//) { 738 local($whichway) = $1; 739 $return .= (($1 =~/lef/)? $slcell : $srcell ); 740 if (($doimage)||($failed)) { 741 $_ = &process_math_in_latex("indisplay",'','' 742 , $doimage.$_ ) unless ($_ eq ''); 743 } else { 744 $_ = &revert_array_envs($_); 745 $_ = &make_math('display','','',$_) unless ($_ eq '') 746 } 747 if (!($_ eq '')) { 748 $return .= join('' 749 , (($whichway =~ /lef/)? $mspace.$mspace : '') 750 , ((/^$smarray/)? $_ : $sbig.$_.$ebig ) 751 , (($whichway =~ /lef/)? '' : $mspace.$mspace ) 752 , $ecell); 753 } else { $return .= join('', $mspace , $ecell); } 754 755# $return .= $smncell.$mcalign.$eqno.$ecell 756 $return .= $smncell.$rseqno.$eqno.$ecell 757 unless ($EQN_TAGS =~ /L/); # eqn-num on right 758 $return .= $erow; 759 next; 760 } 761 762 # columns to be set using \displaystyle 763 @cols = split(/$mdlim/o); 764 local($col_cnt); 765 foreach (@cols) { # set in displaymath 766 # alternating right/left aligned 767 $scell = (($scell eq $slcell)? $srcell : $slcell) if ($col_cnt); 768 $thismath = $_; $col_cnt++; 769 $thismath =~ s/(^\s*|\s*$)//gm; 770 if (($doimage)||($failed)) { 771 $thismath = &process_math_in_latex("indisplay",'','' 772 , $doimage.$thismath ) unless ($thismath eq '' ); 773 } elsif ($thismath ne '') { 774 $thismath = &revert_array_envs($thismath); 775 $thismath = &make_math('display','','',$thismath); 776 } 777 if ($thismath ne '') { 778 $return .= join('', $scell 779 , (($thismath=~/^$smarray/)? $thismath 780 : $sbig.$thismath.$ebig ) 781 , $ecell); 782 } else { $return .= $sempty.$ecell; } 783 } 784 785# $return .= $smncell.$mcalign.$eqno.$ecell 786 $return .= $smncell.$rseqno.$eqno.$ecell 787 unless ($EQN_TAGS =~ /L/); # eqn-num on right 788 $return .= $erow; 789 } 790 $_ = &end_math_display($return , $earray ); 791 } else { 792 $_ = &do_htmlmath_array(''); 793 } 794 $_; 795} 796 797sub do_env_aligned { 798 local($_) = @_; 799 local($saved) = join('' 800 , "\\begin\{aligned\}" 801 , &revert_array_envs($_) 802 , "\\end\{aligned\}\n" 803 ); 804 local($inner_math) = 'aligned'; 805 &process_undefined_environment( 806 'displaymath' , ++$global{'max_id'}, $saved); 807} 808sub do_env_alignedat { 809 local($_) = @_; 810 $_ = &revert_array_envs($_); 811 local($saved) = join('' 812 , "\\begin\{alignedat\}" 813 , &revert_array_envs($_) 814 , "\\end\{alignedat\}\n" 815 ); 816 local($inner_math) = 'alignedat'; 817 &process_undefined_environment( 818 'displaymath' , ++$global{'max_id'}, $saved); 819} 820sub do_env_gathered { 821 local($_) = @_; 822 $_ = &revert_array_envs($_); 823 local($saved) = join('' 824 , "\\begin\{gathered\}\n" 825 , &revert_array_envs($_) 826 , "\\end\{gathered\}\n" 827 ); 828 local($inner_math) = 'gathered'; 829 &process_undefined_environment( 830 'displaymath' , ++$global{'max_id'}, $saved); 831} 832sub do_env_cases { 833 local($_) = @_; 834 $_ = &revert_array_envs($_); 835 local($saved) = join('' 836 ,"\\begin\{cases\}\n" 837 , &revert_array_envs($_) 838 , "\\end\{cases\}\n" 839 ); 840 local($inner_math) = 'cases'; 841 &process_undefined_environment( 842 'displaymath' , ++$global{'max_id'}, $saved); 843} 844 845sub do_env_split { 846 local($_) = @_; 847 local($failed, $labels, $comment, $doimage) = ('',''); 848 local($saved) = join('',"\\begin\{split\}\n", $_, "\\end\{split\}\n"); 849 local($sbig,$ebig)= &set_math_size($math_mode); 850 $failed = 1 if ($NO_SIMPLE_MATH); # simplifies the next call 851 852 local($falign) = 'CENTER'; 853 $failed = (/$htmlimage_rx|$htmlimage_pr_rx/) unless ($outer_math); # force an image 854 local($outer_math) = $env unless ($outer_math); 855 856 if ($failed) { 857 $_ = &process_undefined_environment( 858 $outer_math.(($numbered) ? '':"*"), $id, $saved); 859 $falign = (($EQN_TAGS =~ /L/)? 'LEFT' : 'RIGHT') if $numbered; 860 local($fsdisplay,$fedisplay) = ($spdisplay,$epdisplay); 861 if (!($fsdisplay =~ s/(ALIGN\s*=\s*\")[^\"]*\"/$1$falign\"/)) { 862 $fsdisplay .= "<DIV ALIGN=\"$falign\">"; 863 $fedisplay = '</DIV>'.$epdisplay; 864 } 865 $_ = join('', $fsdisplay, $labels, $comment, $_, $fedisplay); 866 867 } elsif ($NO_SIMPLE_MATH) { 868 $failed = 0; 869 local($outer_math) = 0; # not an "outer" environment 870 871 s/$htmlimage_rx/$doimage = $&;''/eo ; # forces images of cells 872 s/$htmlimage_pr_rx/$doimage .= $&;''/eo ; # force an image 873 local($valign) = &set_math_valign(); 874 local($sarray, $srow, $scell, $calign, $ecell, $erow, $earray); 875 876 local($env_id) = $env_id; 877 if ($USING_STYLES) { 878 $env_style{$env} = "" unless ($env_style{$env}); 879 } 880 ($sarray, $erow, $earray, $sempty, $calign) = ( 881 $smarray.$env_id.$smarrayB.$emtag, $emrow 882 , $emarray, $mnocell.$mspace, $mcalign ); 883 $env_id = ''; 884 885 ($srow, $scell, $ecell, $slcell, $srcell) = ( 886 $smrow.$valign.$emtag , $smncell, $emcell 887 , $smcell.$mralign, $smncell.$mlalign ); 888 889 local($return) = &start_math_display ( $sarray ); 890 891 $_ = &protect_array_envs($_); 892 893 local(@rows,$eqno,$thismath); 894 s/\\\\[ \t]*(\*|\[[^\]]*])/\\\\/g; # remove forced line-heights 895 @rows = split(/\\\\/); 896 $#rows-- if ( $rows[$#rows] =~ /^\s*$/ ); 897 foreach (@rows) { # displaymath 898 next if (/^\s*$/); # ignore last row, if empty 899 900 if (s/\\shove(righ|lef)t//) { 901 local($whichway) = $1; 902 $return .= (($1 =~/lef/)? $mlalign : $mralign ); 903 if (($doimage)||($failed)) { 904 $_ = &process_math_in_latex("indisplay",'','' 905 , $doimage.$_ ) unless ($_ eq ''); 906 } else { 907 $_ = &make_math('display','','',$_) unless ($_ eq '') 908 } 909 if (!($_ eq '')) { 910 $return .= join('' 911 , (($whichway =~ /lef/)? $mspace.$mspace : '') 912 , ((/^$smarray/)? $_ : $sbig.$_.$ebig ) 913 , (($whichway =~ /lef/)? '' : $mspace.$mspace ) 914 , $ecell , $erow); 915 } else { $return .= join('', $mspace , $ecell, $erow); } 916 next; 917 } else { 918 $return .= $srow; 919 } 920 921 # columns to be set using \displaystyle 922 @cols = split(/$mdlim/o); 923 # left column, set using \displaystyle 924 $thismath = shift(@cols); 925 $thismath =~ s/(^\s*|\s*$)//gm; 926 if (($doimage)||($failed)) { 927 $thismath = &process_math_in_latex("indisplay",'','' 928 , $doimage.$thismath ) unless ($thismath eq '' ); 929 } else { 930 $thismath = &make_math('display','','' 931 , $thismath) unless ( $thismath eq '' ); 932 } 933 if (!($thismath eq '')) { 934 $return .= join('', $slcell 935 , (($thismath=~/^$smarray/)? $thismath 936 : $sbig.$thismath.$ebig ) 937 , $ecell); 938 } else { $return .= $sempty.$ecell; } 939 940 # right column, set using \displaystyle 941 $thismath = shift(@cols); 942 $thismath =~ s/(^\s*|\s*$)//gm; 943 if (($doimage)||($failed)) { 944 $thismath = &process_math_in_latex("indisplay",'','' 945 , $doimage.$thismath ) unless ($thismath eq '' ); 946 } else { 947 $thismath = &make_math('display','','' 948 , $thismath) unless ( $thismath eq '' ); 949 } 950 if (!($thismath eq '')) { 951 $return .= join('', $srcell 952 , (($thismath=~/^$smarray/)? $thismath 953 : $sbig.$thismath.$ebig ) 954 , $ecell); 955 } else { $return .= $sempty . $ecell} 956 957 $return .= $erow; 958 } 959 $_ = &end_math_display($return , $earray ); 960 } else { 961 $_ = &do_htmlmath_array('rl'); 962 } 963 $_; 964} 965 9661; # This must be the last line 967 968 969 970 971 972 973 974 975 976 977 978 979