1#- -*- perl -*- 2# 3# $Id: latex2html.pin,v 1.71 2004/01/06 23:49:54 RRM Exp $ 4# 5# Comprises patches and revisions by various authors: 6# See Changes, the log file of LaTeX2HTML. 7# 8# Original Copyright notice: 9# 10# LaTeX2HTML by Nikos Drakos <nikos@cbl.leeds.ac.uk> 11 12# **************************************************************** 13# LaTeX To HTML Translation ************************************** 14# **************************************************************** 15# LaTeX2HTML is a Perl program that translates LaTeX source 16# files into HTML (HyperText Markup Language). For each source 17# file given as an argument the translator will create a 18# directory containing the corresponding HTML files. 19# 20# The man page for this program is included at the end of this file 21# and can be viewed using "perldoc latex2html" 22# 23# For more information on this program and some examples of its 24# capabilities visit 25# 26# http://www.latex2html.org/ 27# 28# or see the accompanying documentation in the docs/ directory 29# 30# or 31# 32# http://www-texdev.ics.mq.edu.au/l2h/docs/manual/ 33# 34# or 35# 36# http://www.cbl.leeds.ac.uk/nikos/tex2html/doc/latex2html/ 37# 38# Original code written by Nikos Drakos, July 1993. 39# 40# Address: Computer Based Learning Unit 41# University of Leeds 42# Leeds, LS2 9JT 43# 44# Copyright (c) 1993-95. All rights reserved. 45# 46# 47# Extensively modified by Ross Moore, Herb Swan and others 48# 49# Address: Mathematics Department 50# Macquarie University 51# Sydney, Australia, 2109 52# 53# Copyright (c) 1996-2001. All rights reserved. 54# 55# See general license in the LICENSE file. 56# 57########################################################################## 58 59use 5.003; # refuse to work with old and buggy perl version 60#use strict; 61#use diagnostics; 62 63# include some perl packages; these come with the standard distribution 64use Getopt::Long; 65use Fcntl; 66use AnyDBM_File; 67 68# The following are global variables that also appear in some modules 69use vars qw($LATEX2HTMLDIR $LATEX2HTMLPLATDIR $SCRIPT 70 %Month %used_icons $inside_tabbing $TABLE_attribs 71 %mathentities $date_name $outer_math $TABLE__CELLPADDING_rx); 72 73#- NOTE: This file contains a sort of preprocessor information, similar 74#- to C's #define statement, so please be careful when removing comments! 75#- 76#- The (texlive) wrapper sets these values 77#- or it is stored in the enviroment 78#- 79#unless @wrapper@ || @texlive@ 80BEGIN { 81 # print "scanning for l2hdir\n"; 82 if($ENV{'LATEX2HTMLDIR'}) { 83 $LATEX2HTMLDIR = $ENV{'LATEX2HTMLDIR'}; 84 } else { 85 $ENV{'LATEX2HTMLDIR'} = $LATEX2HTMLDIR = '@LATEX2HTMLDIR@'; 86 } 87 88 if($ENV{'LATEX2HTMLPLATDIR'}) { 89 $LATEX2HTMLPLATDIR = $ENV{'LATEX2HTMLPLATDIR'}; 90 } else { 91 $LATEX2HTMLPLATDIR = '@LATEX2HTMLPLATDIR@'||$LATEX2HTMLDIR; 92 $ENV{'LATEX2HTMLPLATDIR'} = $LATEX2HTMLPLATDIR; 93 } 94 if(-d $LATEX2HTMLPLATDIR) { 95 push(@INC,$LATEX2HTMLPLATDIR); 96 } 97 98 if(-d $LATEX2HTMLDIR) { 99 push(@INC,$LATEX2HTMLDIR); 100 } else { 101 die qq{Fatal: Directory "$LATEX2HTMLDIR" does not exist.\n}; 102 } 103} 104#fi 105 106use L2hos; # Operating system dependent routines 107 108# $^W = 1; # turn on warnings 109 110my $RELEASE = '@distver@'; 111my ($REVISION) = q$Revision: 1.71 $ =~ /:\s*(\S+)/; 112 113# The key, which delimts expressions defined in the environment 114# depends on the operating system. 115$envkey = L2hos->pathd(); 116 117# $dd is the directory delimiter character 118$dd = L2hos->dd(); 119 120# make sure the $LATEX2HTMLDIR is on the search-path for forked processes 121if($ENV{'PERL5LIB'}) { 122 $ENV{'PERL5LIB'} .= "$envkey$LATEX2HTMLDIR" 123 unless($ENV{'PERL5LIB'} =~ m|\Q$LATEX2HTMLDIR\E|o); 124} else { 125 $ENV{'PERL5LIB'} = $LATEX2HTMLDIR; 126} 127 128# Local configuration, read at runtime 129# Read the $CONFIG_FILE (usually l2hconf.pm ) 130if($ENV{'L2HCONFIG'}) { 131 require $ENV{'L2HCONFIG'} || 132 die "Fatal (require $ENV{'L2HCONFIG'}): $!"; 133} else { 134 eval 'use l2hconf'; 135 if($@) { 136 die "Fatal (use l2hconf): $@\n"; 137 } 138} 139 140# MRO: Changed this to global value in config/config.pl 141# change these whenever you do a patch to this program and then 142# name the resulting patch file accordingly 143# $TVERSION = "@distver@"; 144#$TPATCHLEVEL = " beta"; 145#$TPATCHLEVEL = " release"; 146#$RELDATE = "(March 30, 1999)"; 147#$TEX2HTMLV_SHORT = $TVERSION . $TPATCHLEVEL; 148 149$TEX2HTMLV_SHORT = $RELEASE; 150$TEX2HTMLVERSION = "$TEX2HTMLV_SHORT ($REVISION)"; 151$TEX2HTMLADDRESS = "http://www.latex2html.org/"; 152$AUTHORADDRESS = "http://cbl.leeds.ac.uk/nikos/personal.html"; 153#$AUTHORADDRESS2 = "http://www-math.mpce.mq.edu.au/%7Eross/"; 154$AUTHORADDRESS2 = "http://www.maths.mq.edu.au/~ross/"; 155 156# Set $HOME to what the system considers the home directory 157$HOME = L2hos->home(); 158push(@INC,$HOME); 159 160# flush stdout with every print -- gives better feedback during 161# long computations 162$| = 1; 163 164# set Perl's subscript separator to LaTeX's illegal character. 165# (quite defensive but why not) 166$; = "\000"; 167 168# No arguments!! 169unless(@ARGV) { 170 die "Error: No files to process!\n"; 171} 172 173# Image prefix 174#if @texlive@ 175$IMAGE_PREFIX = L2hos->plat() eq 'dos' ? 'ps' : '_image'; 176#else 177 #if @plat@ eq 'dos' 178$IMAGE_PREFIX = 'ps'; 179 #else 180$IMAGE_PREFIX = '_image'; 181 #fi 182#fi - texlive 183 184# Partition prefix 185$PARTITION_PREFIX = 'part_' unless $PARTITION_PREFIX; 186 187# Author address 188@address_data = &address_data('ISO'); 189$ADDRESS = "$address_data[0]\n$address_data[1]"; 190 191# ensure non-zero defaults 192$MAX_SPLIT_DEPTH = 4 unless ($MAX_SPLIT_DEPTH); 193$MAX_LINK_DEPTH = 4 unless ($MAX_LINK_DEPTH); 194$TOC_DEPTH = 4 unless ($TOC_DEPTH); 195 196# A global value may already be set in the $CONFIG_FILE 197$INIT_FILE_NAME = $ENV{'L2HINIT_NAME'} || '.latex2html-init' 198 unless $INIT_FILE_NAME; 199 200# Read the $HOME/$INIT_FILE_NAME if one is found 201if (-f "$HOME$dd$INIT_FILE_NAME" && -r _) { 202 print "Note: Loading $HOME$dd$INIT_FILE_NAME\n"; 203 require("$HOME$dd$INIT_FILE_NAME"); 204 $INIT_FILE = "$HOME$dd$INIT_FILE_NAME"; 205 # _MRO_TODO_: Introduce a version to be checked? 206 die "Error: You have an out-of-date " . $HOME . 207 "$dd$INIT_FILE_NAME file.\nPlease update or delete it.\n" 208 if ($DESTDIR eq '.'); 209} 210 211# Read the $INIT_FILE_NAME file if one is found in current directory 212if ( L2hos->Cwd() ne $HOME && -f ".$dd$INIT_FILE_NAME" && -r _) { 213 print "Note: Loading .$dd$INIT_FILE_NAME\n"; 214 require(".$dd$INIT_FILE_NAME"); 215 $INIT_FILE = "$INIT_FILE_NAME"; 216} 217die "Error: '.' is an incorrect setting for DESTDIR.\n" . 218 "Please check your $INIT_FILE_NAME file.\n" 219 if ($DESTDIR eq '.'); 220 221# User home substitutions 222$LATEX2HTMLSTYLES =~ s/~([$dd$dd$envkey]|$)/$HOME$1/go; 223# the next line fails utterly on non-UNIX systems 224$LATEX2HTMLSTYLES =~ s/~([^$dd$dd$envkey]+)/L2hos->home($1)/geo; 225 226#absolutise the paths 227$LATEX2HTMLSTYLES = join($envkey, 228 map(L2hos->Make_directory_absolute($_), 229 split(/$envkey/o, $LATEX2HTMLSTYLES))); 230 231#HWS: That was the last reference to HOME. Now set HOME to $LATEX2HTMLDIR, 232# to enable dvips to see that version of .dvipsrc! But only if we 233# have DVIPS_MODE not set - yes - this is a horrible nasty kludge 234# MRO: The file has to be updated by configure _MRO_TODO_ 235 236if ($PK_GENERATION && ! $DVIPS_MODE) { 237 $ENV{HOME} = $LATEX2HTMLDIR; 238 delete $ENV{PRINTER}; # Overrides .dvipsrc 239} 240 241# language of the DTD specified in the <DOCTYPE...> tag 242$ISO_LANGUAGE = 'EN' unless $ISO_LANGUAGE; 243 244# Save the command line arguments, quote where necessary 245$argv = join(' ', map {/[\s#*!\$%]/ ? "'$_'" : $_ } @ARGV); 246 247# Pre-process the command line for backward compatibility 248foreach(@ARGV) { 249 s/^--?no_/-no/; # replace e.g. no_fork by nofork 250 # s/^[+](\d+)$/$1/; # remove + in front of integers 251} 252 253# Process command line options 254my %opt; 255unless(GetOptions(\%opt, # all non-linked options go into %opt 256 # option linkage (optional) 257 'help|h', 258 'version|V', 259 'split=s', 260 'link=s', 261 'toc_depth=i', \$TOC_DEPTH, 262 'toc_stars!', \$TOC_STARS, 263 'short_extn!', \$SHORTEXTN, 264 'iso_language=s', \$ISO_LANGUAGE, 265 'validate!', \$HTML_VALIDATE, 266 'latex!', 267 'djgpp!', \$DJGPP, 268 'fork!', \$CAN_FORK, 269 'external_images!', \$EXTERNAL_IMAGES, 270 'ascii_mode!', \$ASCII_MODE, 271 'lcase_tags!', \$LOWER_CASE_TAGS, 272 'ps_images!', \$PS_IMAGES, 273 'font_size=s', \$FONT_SIZE, 274 'tex_defs!', \$TEXDEFS, 275 'navigation!', 276 'top_navigation!', \$TOP_NAVIGATION, 277 'bottom_navigation!', \$BOTTOM_NAVIGATION, 278 'auto_navigation!', \$AUTO_NAVIGATION, 279 'index_in_navigation!', \$INDEX_IN_NAVIGATION, 280 'contents_in_navigation!', \$CONTENTS_IN_NAVIGATION, 281 'next_page_in_navigation!', \$NEXT_PAGE_IN_NAVIGATION, 282 'previous_page_in_navigation!', \$PREVIOUS_PAGE_IN_NAVIGATION, 283 'footnode!', 284 'numbered_footnotes!', \$NUMBERED_FOOTNOTES, 285 'prefix=s', \$PREFIX, 286 'auto_prefix!', \$AUTO_PREFIX, 287 'long_titles=i', \$LONG_TITLES, 288 'custom_titles!', \$CUSTOM_TITLES, 289 'title|t=s', \$TITLE, 290 'rooted!', \$ROOTED, 291 'rootdir=s', 292 'dir=s', \$FIXEDDIR, 293 'mkdir', \$MKDIR, 294 'address=s', \$ADDRESS, 295 'noaddress', 296 'subdir!', 297 'info=s', \$INFO, 298 'noinfo', 299 'auto_link!', 300 'reuse=i', \$REUSE, 301 'noreuse', 302 'antialias_text!', \$ANTI_ALIAS_TEXT, 303 'antialias!', \$ANTI_ALIAS, 304 'transparent!', \$TRANSPARENT_FIGURES, 305 'white!', \$WHITE_BACKGROUND, 306 'discard!', \$DISCARD_PS, 307 'image_type=s', \$IMAGE_TYPE, 308 'images!', 309 'accent_images=s', \$ACCENT_IMAGES, 310 'noaccent_images', 311 'style=s', \$STYLESHEET, 312 'parbox_images!', 313 'math!', 314 'math_parsing!', 315 'latin!', 316 'entities!', \$USE_ENTITY_NAMES, 317 'local_icons!', \$LOCAL_ICONS, 318 'scalable_fonts!', \$SCALABLE_FONTS, 319 'images_only!', \$IMAGES_ONLY, 320 'show_section_numbers!',\$SHOW_SECTION_NUMBERS, 321 'show_init!', \$SHOW_INIT_FILE, 322 'init_file=s', \$INIT_FILE, 323 'up_url=s', \$EXTERNAL_UP_LINK, 324 'up_title=s', \$EXTERNAL_UP_TITLE, 325 'down_url=s', \$EXTERNAL_DOWN_LINK, 326 'down_title=s', \$EXTERNAL_DOWN_TITLE, 327 'prev_url=s', \$EXTERNAL_PREV_LINK, 328 'prev_title=s', \$EXTERNAL_PREV_TITLE, 329 'index=s', \$EXTERNAL_INDEX, 330 'biblio=s', \$EXTERNAL_BIBLIO, 331 'contents=s', \$EXTERNAL_CONTENTS, 332 'external_file=s', \$EXTERNAL_FILE, 333 'short_index!', \$SHORT_INDEX, 334 'unsegment!', \$UNSEGMENT, 335 'debug!', \$DEBUG, 336 'tmp=s', \$TMP, 337 'ldump!', \$LATEX_DUMP, 338 'timing!', \$TIMING, 339 'verbosity=i', \$VERBOSITY, 340 'html_version=s', \$HTML_VERSION, 341 'strict!', \$STRICT_HTML, 342 'xbit!', \$XBIT_HACK, 343 'ssi!', \$ALLOW_SSI, 344 'php!', \$ALLOW_PHP, 345 'test_mode!' # undocumented switch 346 )) { 347 &usage(); 348 exit 1; 349} 350 351# interpret options, check option consistency 352if(defined $opt{'split'}) { 353 if ($opt{'split'} =~ /^(\+?)(\d+)$/) { 354 $MAX_SPLIT_DEPTH = $2; 355 if ($1) { $MAX_SPLIT_DEPTH *= -1; $REL_DEPTH = 1; } 356 } else { 357 &usage; 358 die "Error: Unrecognised value for -split: $opt{'split'}\n"; 359 } 360} 361if(defined $opt{'link'}) { 362 if ($opt{'link'} =~ /^(\+?)(\d+)$/) { 363 $MAX_LINK_DEPTH = $2; 364 if ($1) { $MAX_LINK_DEPTH *= -1 } 365 } else { 366 &usage; 367 die "Error: Unrecognised value for -link: $opt{'link'}\n"; 368 } 369} 370unless ($ISO_LANGUAGE =~ /^[A-Z.]+$/) { 371 die "Error: Language (-iso_language) must be uppercase and dots only: $ISO_LANGUAGE\n"; 372} 373if ($HTML_VALIDATE && !$HTML_VALIDATOR) { 374 die "Error: Need a HTML_VALIDATOR when -validate is specified.\n"; 375} 376&set_if_false($NOLATEX,$opt{latex}); # negate the option... 377if ($ASCII_MODE || $PS_IMAGES) { 378 $EXTERNAL_IMAGES = 1; 379} 380if ($FONT_SIZE && $FONT_SIZE !~ /^\d+pt$/) { 381 die "Error: Font size (-font_size) must end with 'pt': $FONT_SIZE\n" 382} 383&set_if_false($NO_NAVIGATION,$opt{navigation}); 384&set_if_false($NO_FOOTNODE,$opt{footnode}); 385if (defined $TITLE && !length($TITLE)) { 386 die "Error: Empty title (-title).\n"; 387} 388if ($opt{rootdir}) { 389 $ROOTED = 1; 390 $FIXEDDIR = $opt{rootdir}; 391} 392if ($FIXEDDIR && !-d $FIXEDDIR) { 393 if ($MKDIR) { 394 print "\n *** creating directory: $FIXEDDIR "; 395 die "Failed: $!\n" unless (mkdir($FIXEDDIR, 0755)); 396 # _TODO_ use File::Path to create a series of directories 397 } else { 398 &usage; 399 die "Error: Specified directory (-rootdir, -dir) does not exist.\n"; 400 } 401} 402&set_if_false($NO_SUBDIR, $opt{subdir}); 403&set_if_false($NO_AUTO_LINK, $opt{auto_link}); 404if ($opt{noreuse}) { 405 $REUSE = 0; 406} 407unless(grep(/^\Q$IMAGE_TYPE\E$/o, @IMAGE_TYPES)) { 408 die <<"EOF"; 409Error: No such image type '$IMAGE_TYPE'. 410 This installation supports (first is default): @IMAGE_TYPES 411EOF 412} 413&set_if_false($NO_IMAGES, $opt{images}); 414if ($opt{noaccent_images}) { 415 $ACCENT_IMAGES = ''; 416} 417if($opt{noaddress}) { 418 $ADDRESS = ''; 419} 420if($opt{noinfo}) { 421 $INFO = 0; 422} 423if($ACCENT_IMAGES && $ACCENT_IMAGES !~ /^[a-zA-Z,]+$/) { 424 die "Error: Single word or comma-list of style words needed for -accent_images, not: $_\n"; 425} 426&set_if_false($NO_PARBOX_IMAGES, $opt{parbox_images}); 427&set_if_false($NO_SIMPLE_MATH, $opt{math}); 428if (defined $opt{math_parsing}) { 429 $NO_MATH_PARSING = !$opt{math_parsing}; 430 $NO_SIMPLE_MATH = !$opt{math_parsing} unless(defined $opt{math}); 431} 432&set_if_false($NO_ISOLATIN, $opt{latin}); 433if ($INIT_FILE) { 434 if (-f $INIT_FILE && -r _) { 435 print "Note: Initialising with file: $INIT_FILE\n" 436 if ($DEBUG || $VERBOSITY); 437 require($INIT_FILE); 438 } else { 439 die "Error: Could not find file (-init_file): $INIT_FILE\n"; 440 } 441} 442foreach($EXTERNAL_UP_LINK, $EXTERNAL_DOWN_LINK, $EXTERNAL_PREV_LINK, 443 $EXTERNAL_INDEX, $EXTERNAL_BIBLIO, $EXTERNAL_CONTENTS) { 444 $_ ||= ''; # initialize 445 s/~/~/g; # protect `~' 446} 447if($TMP && !(-d $TMP && -w _)) { 448 die "Error: '$TMP' not usable as temporary directory.\n"; 449} 450if ($opt{help}) { 451 L2hos->perldoc($SCRIPT); 452 exit 0; 453} 454if ($opt{version}) { 455 &banner(); 456 exit 0; 457} 458if ($opt{test_mode}) { 459 $TITLE = 'LaTeX2HTML Test Document'; 460 $TEXEXPAND = "$PERL @srcdir@${dd}texexpand@scriptext@"; 461 $PSTOIMG = "$PERL @srcdir@${dd}pstoimg@scriptext@"; 462 $ICONSERVER = L2hos->path2URL("@srcdir@${dd}icons"); 463 $TEST_MODE = 1; 464 $RGBCOLORFILE = "@srcdir@${dd}styles${dd}rgb.txt"; 465 $CRAYOLAFILE = "@srcdir@${dd}styles${dd}crayola.txt"; 466} 467if($DEBUG) { 468 # make the OS-dependent functions more chatty, too 469 $L2hos::Verbose = 1; 470} 471 472undef %opt; # not needed any more 473 474#unless @have_images@ 475print "Warning: This system does not support generation of images\n" 476 unless($NO_IMAGES); 477$NO_IMAGES = 1; 478#fi 479 480$FIXEDDIR = $FIXEDDIR || $DESTDIR || ''; # for backward compatibility 481 482if ($EXTERNAL_UP_TITLE xor $EXTERNAL_UP_LINK) { 483 warn "Warning (-up_url, -up_title): Need to specify both a parent URL and a parent title!\n"; 484 $EXTERNAL_UP_TITLE = $EXTERNAL_UP_LINK = ""; 485} 486 487if ($EXTERNAL_DOWN_TITLE xor $EXTERNAL_DOWN_LINK) { 488 warn "Warning (-down_url, -down_title): Need to specify both a parent URL and a parent title!\n"; 489 $EXTERNAL_DOWN_TITLE = $EXTERNAL_DOWN_LINK = ""; 490} 491 492# $NO_NAVIGATION = 1 unless $MAX_SPLIT_DEPTH; # Martin Wilck 493 494if ($MAX_SPLIT_DEPTH && $MAX_SPLIT_DEPTH < 0) { 495 $MAX_SPLIT_DEPTH *= -1; $REL_DEPTH = 1; 496} 497if ($MAX_LINK_DEPTH && $MAX_LINK_DEPTH < 0) { 498 $MAX_LINK_DEPTH *= -1; $LEAF_LINKS = 1; 499} 500 501$FOOT_FILENAME = 'footnode' unless ($FOOT_FILENAME); 502$NO_FOOTNODE = 1 unless ($MAX_SPLIT_DEPTH || $NO_FOOTNODE); 503$NO_SPLIT = 1 unless $MAX_SPLIT_DEPTH; # _MRO_TODO_: is this needed at all? 504$SEGMENT = $SEGMENTED = 0; 505$NO_MATH_MARKUP = 1; 506 507# specify the filename extension to use with the generated HTML files 508if ($SHORTEXTN) { $EXTN = ".htm"; } # for HTML files on CDROM 509elsif ($ALLOW_PHP) { $EXTN = ".php"; } # has PHP dynamic includes 510 # with server-side includes (SSI) : 511elsif ($ALLOW_SSI && !$XBIT_HACK) { $EXTN = ".shtml"; } 512 # ordinary names, valid also for SSI with XBit hack : 513else { $EXTN = ".html"; } 514 515$NODE_NAME = 'node' unless (defined $NODE_NAME); 516 517# space for temporary files 518# different to the $TMPDIR for image-generation 519# MRO: No directory should end with $dd! 520$TMP_ = "TMP"; 521 522$TMP_PREFIX = "l2h" unless ($TMP_PREFIX); 523 524# This can be set to 1 when using a version of dvips that is safe 525# from the "dot-in-name" bug. 526# _TODO_ this should be determined by configure 527$DVIPS_SAFE = 1; 528 529$CHARSET = $charset || 'iso-8859-1'; 530 531#################################################################### 532# 533# If possible, use icons of the same type as generated images 534# 535if ($IMAGE_TYPE && %{"icons_$IMAGE_TYPE"}) { 536 %icons = %{"icons_$IMAGE_TYPE"}; 537} 538 539#################################################################### 540# 541# Figure out what options we need to pass to DVIPS and store that in 542# the $DVIPSOPT variable. Also, scaling is taken care of at the 543# dvips level if PK_GENERATION is set to 1, so adjust SCALE_FACTORs 544# accordingly. 545# 546if ($SCALABLE_FONTS) { 547 $PK_GENERATION = 0; 548 $DVIPS_MODE = ''; 549} 550 551if ($PK_GENERATION) { 552 if ($MATH_SCALE_FACTOR <= 0) { $MATH_SCALE_FACTOR = 2; } 553 if ($FIGURE_SCALE_FACTOR <= 0) { $FIGURE_SCALE_FACTOR = 2; } 554 my $saveMSF = $MATH_SCALE_FACTOR; 555 my $saveFSF = $FIGURE_SCALE_FACTOR; 556 my $desired_dpi = int($MATH_SCALE_FACTOR*75); 557 $FIGURE_SCALE_FACTOR = ($METAFONT_DPI / 72) * 558 ($FIGURE_SCALE_FACTOR / $MATH_SCALE_FACTOR) ; 559 $MATH_SCALE_FACTOR = $METAFONT_DPI / 72; 560 $dvi_mag = int(1000 * $desired_dpi / $METAFONT_DPI); 561 if ($dvi_mag > 1000) { 562 &write_warnings( 563 "WARNING: Your SCALE FACTOR is too large for PK_GENERATION.\n" . 564 " See $CONFIG_FILE for more information.\n"); 565 } 566 567 # RRM: over-sized scaling, using dvi-magnification 568 if ($EXTRA_IMAGE_SCALE) { 569 print "\n *** Images at $EXTRA_IMAGE_SCALE times resolution of displayed size ***\n"; 570 $desired_dpi = int($EXTRA_IMAGE_SCALE * $desired_dpi+.5); 571 print " desired_dpi = $desired_dpi METAFONT_DPI = $METAFONT_DPI\n" 572 if $DEBUG; 573 $dvi_mag = int(1000 * $desired_dpi / $METAFONT_DPI); 574 $MATH_SCALE_FACTOR = $saveMSF; 575 $FIGURE_SCALE_FACTOR = $saveFSF; 576 } 577 # no space after "-y", "-D", "-e" --- required by DVIPS under DOS ! 578 my $mode_switch = "-mode $DVIPS_MODE" if $DVIPS_MODE; 579 $DVIPSOPT .= " -y$dvi_mag -D$METAFONT_DPI $mode_switch -e5 "; 580} else { # no PK_GENERATION 581# if ($EXTRA_IMAGE_SCALE) { 582# &write_warnings( 583# "the \$EXTRA_IMAGE_SCALE feature requires either \$PK_GENERATION=1" 584# . " or the '-scalable_fonts' option"); 585# $EXTRA_IMAGE_SCALE = ''; 586# } 587 # MRO: shifted to l2hconf 588 #$DVIPSOPT .= ' -M'; 589} # end PK_GENERATION 590 591# The mapping from numbers to accents. 592# These are required to process the \accent command, which is found in 593# tables of contents whenever there is an accented character in a 594# caption or section title. Processing the \accent command makes 595# $encoded_*_number work properly (see &extract_captions) with 596# captions that contain accented characters. 597# I got the numbers from the plain.tex file, version 3.141. 598 599# Missing entries should be looked up by a native speaker. 600# Have a look at generate_accent_commands and $iso_8859_1_character_map. 601 602# MEH: added more accent types 603# MRO: only uppercase needed! 604%accent_type = ( 605 '18' => 'grave', # \` 606 '19' => 'acute', # `' 607 '20' => 'caron', # \v 608 '21' => 'breve', # \u 609 '22' => 'macr', # \= 610 '23' => 'ring', # 611 '24' => 'cedil', # \c 612 '94' => 'circ', # \^ 613 '95' => 'dot', # \. 614 '7D' => 'dblac', # \H 615 '7E' => 'tilde', # \~ 616 '7F' => 'uml', # \" 617); 618 619&driver; 620 621exit 0; # clean exit, no errors 622 623############################ Subroutines ################################## 624 625#check that $TMP is writable, if so create a subdirectory 626sub make_tmp_dir { 627 &close_dbm_database if $DJGPP; # to save file-handles 628 629#if @texlive@ 630 $TMP = "$DESTDIR$dd$TMP_"; 631 unless(-d $TMP) { 632 mkdir($TMP,0755); 633 } 634#fi 635 # determine a suitable temporary path 636 # 637 $TMPDIR = ''; 638 my @tmp_try = (); 639 push(@tmp_try, $TMP) if($TMP); 640 push(@tmp_try, "$DESTDIR$dd$TMP_") if($TMP_); 641 push(@tmp_try, $DESTDIR) if($DESTDIR); 642 push(@tmp_try, L2hos->Cwd()); 643 644 my $try; 645 TempTry: foreach $try (@tmp_try) { 646 next unless(-d $try && -w _); 647 my $tmp = "$try$dd$TMP_PREFIX$$"; 648 if(mkdir($tmp,0755)) { 649 $TMPDIR=$tmp; 650 last TempTry; 651 } else { 652 warn "Warning: Cannot create temporary directory '$tmp': $!\n"; 653 } 654 } 655 656 $dvips_warning = <<"EOF"; 657 658Warning: There is a '.' in \$TMPDIR, $DVIPS will probably fail. 659Set \$TMP to use a /tmp directory, or rename the working directory. 660EOF 661 die ($dvips_warning . "\n\$TMPDIR=$TMPDIR ***\n\n") 662 if ($TMPDIR =~ /\./ && $DVIPS =~ /dvips/ && !$DVIPS_SAFE); 663 664 &open_dbm_database if $DJGPP; 665} 666 667# MRO: set first parameter to the opposite of the second if second parameter is defined 668sub set_if_false { 669 $_[0] = !$_[1] if(defined $_[1]); 670} 671 672sub check_for_dots { 673 local($file) = @_; 674 if ($file =~ /\.[^.]*\./ && !$DVIPS_SAFE) { 675 die "\n\n\n *** Fatal Error --- but easy to fix ***\n" 676 . "\nCannot have '.' in file-name prefix, else dvips fails on images" 677 . "\nChange the name from $file and try again.\n\n"; 678 } 679} 680 681# Process each file ... 682sub driver { 683 local($FILE, $orig_cwd, %unknown_commands, %dependent, %depends_on 684 , %styleID, %env_style, $bbl_cnt, $dbg, %numbered_section); 685 # MRO: $texfilepath has to be global! 686 local(%styles_loaded); 687 $orig_cwd = L2hos->Cwd(); 688 689 print "\n *** initialise *** " if ($VERBOSITY > 1); 690 &initialise; # Initialise some global variables 691 692 print "\n *** check modes *** " if ($VERBOSITY > 1); 693 &ascii_mode if $ASCII_MODE; # Must come after initialization 694 &titles_language($TITLES_LANGUAGE); 695 &make_numbered_footnotes if ($NUMBERED_FOOTNOTES); 696 $dbg = $DEBUG ? "-debug" : ""; 697 $dbg .= (($VERBOSITY>2) ? " -verbose" : ""); 698 699 #use the same hashes for all files in a batch 700 local(%cached_env_img, %id_map, %symbolic_labels, %latex_labels) 701 if ($FIXEDDIR && $NO_SUBDIR); 702 703 local($MULTIPLE_FILES,$THIS_FILE); 704 $MULTIPLE_FILES = 1+$#ARGV if $ROOTED; 705 print "\n *** $MULTIPLE_FILES file".($MULTIPLE_FILES ? 's: ' : ': ') 706 . join(',',@ARGV) . " *** " if ($VERBOSITY > 1); 707 708 local(%section_info, %toc_section_info, %cite_info, %ref_files); 709 710 foreach $FILE (@ARGV) { 711 &check_for_dots($FILE) unless $DVIPS_SAFE; 712 ++$THIS_FILE if $MULTIPLE_FILES; 713 do { 714 %section_info = (); 715 %toc_section_info = (); 716 %cite_info = (); 717 %ref_files = (); 718 } unless $MULTIPLE_FILES; 719 local($bbl_nr) = 1; 720 721 # The number of reused images and those in images.tex 722 local($global_page_num) = (0) unless($FIXEDDIR && $NO_SUBDIR); 723 # The number of images in images.tex 724 local($new_page_num) = (0); # unless($FIXEDDIR && $NO_SUBDIR); 725 local($pid, $sections_rx, 726 , $outermost_level, %latex_body, $latex_body 727 , %encoded_section_number 728 , %verbatim, %new_command, %new_environment 729 , %provide_command, %renew_command, %new_theorem 730 , $preamble, $aux_preamble, $prelatex, @preamble); 731 732 # must retain these when all files are in the same directory 733 # else the images.pl and labels.pl files get clobbered 734 unless ($FIXEDDIR && $NO_SUBDIR) { 735 print "\nResetting image-cache" if ($#ARGV); 736 local(%cached_env_img, %id_map, %symbolic_labels, %latex_labels) 737 } 738 739## AYS: Allow extension other than .tex and make it optional 740 ($EXT = $FILE) =~ s/.*\.([^\.]*)$/$1/; 741 if ( $EXT eq $FILE ) { 742 $EXT = "tex"; 743 $FILE =~ s/$/.tex/; 744 } 745 746 #RRM: allow user-customisation, dependent on file-name 747 # e.g. add directories to $TEXINPUTS named for the file 748 # --- idea due to Fred Drake <fdrake@acm.org> 749 &custom_driver_hook($FILE) if (defined &custom_driver_hook); 750 751# JCL(jcl-dir) 752# We need absolute paths for TEXINPUTS here, because 753# we change the directory 754 if ($orig_cwd eq $texfilepath) { 755 &deal_with_texinputs($orig_cwd); 756 } else { 757 &deal_with_texinputs($orig_cwd, $texfilepath); 758 } 759 760 ($texfilepath, $FILE) = &get_full_path($FILE); 761 $texfilepath = '.' unless($texfilepath); 762 763 die "Cannot read $texfilepath$dd$FILE \n" 764 unless (-f "$texfilepath$dd$FILE"); 765 766 767# Tell texexpand which files we *don't* want to look at. 768 $ENV{'TEXE_DONT_INCLUDE'} = $DONT_INCLUDE if $DONT_INCLUDE; 769# Tell texexpand which files we *do* want to look at, e.g. 770# home-brew style files 771 $ENV{'TEXE_DO_INCLUDE'} = $DO_INCLUDE if $DO_INCLUDE; 772 773 $FILE =~ s/\.[^\.]*$//; ## AYS 774 $DESTDIR = ''; # start at empty 775 if ($FIXEDDIR) { 776 $DESTDIR = $FIXEDDIR unless ($FIXEDDIR eq '.'); 777 if (($ROOTED)&&!($texfilepath eq $orig_cwd)) { 778 $DESTDIR .= $dd . $FILE unless $NO_SUBDIR; 779 }; 780 } elsif ($texfilepath eq $orig_cwd) { 781 $DESTDIR = ($NO_SUBDIR ? '.' : $FILE); 782 } else { 783 $DESTDIR = $ROOTED ? '.' : $texfilepath; 784 $DESTDIR .= $dd . $FILE unless $NO_SUBDIR; 785 } 786 $PREFIX = "$FILE-" if $AUTO_PREFIX; 787 788 print "\nOPENING $texfilepath$dd$FILE.$EXT \n"; ## AYS 789 790 next unless (&new_dir($DESTDIR,'')); 791 # establish absolute path to $DESTDIR 792 $DESTDIR = L2hos->Make_directory_absolute($DESTDIR); 793 &make_tmp_dir; 794 print "\nNote: Working directory is $DESTDIR\n"; 795 print "Note: Images will be generated in $TMPDIR\n\n"; 796 797# Need to clean up a bit in case there's garbage left 798# from former runs. 799 if ($DESTDIR) { chdir($DESTDIR) || die "$!\n"; } 800 if (opendir (TMP,$TMP_)) { 801 foreach (readdir TMP) { 802 L2hos->Unlink("TMP_$dd$_") unless (/^\.\.?$/); 803 } 804 closedir TMP; 805 } 806 &cleanup(1); 807 unless(-d $TMP_) { 808 mkdir($TMP_, 0755) || 809 die "Cannot create directory '$TMP_': $!\n"; 810 } 811 chdir($orig_cwd); 812 813# RRM 14/5/98 moved this to occur earlier 814## JCL(jcl-dir) 815## We need absolute paths for TEXINPUTS here, because 816## we change the directory 817# if ($orig_cwd eq $texfilepath) { 818# &deal_with_texinputs($orig_cwd); 819# } else { 820# &deal_with_texinputs($orig_cwd, $texfilepath); 821# } 822 823 824# This needs $DESTDIR to have been created ... 825 print " *** calling `texexpand' ***" if ($VERBOSITY > 1); 826 local($unseg) = ($UNSEGMENT ? "-unsegment " : ""); 827 828# does DOS need to check these here ? 829# die "File $TEXEXPAND does not exist or is not executable\n" 830# unless (-x $TEXEXPAND); 831 L2hos->syswait("$TEXEXPAND $dbg -auto_exclude $unseg" 832 . "-save_styles \"$DESTDIR$dd$TMP_${dd}styles\" " 833 . ($TEXINPUTS ? "-texinputs \"$TEXINPUTS\" " : '' ) 834 . (($VERBOSITY >2) ? "-verbose " : '' ) 835 . "-out \"$DESTDIR$dd$TMP_$dd$FILE\" " 836 . "\"$texfilepath$dd$FILE.$EXT\"") 837 && die " texexpand failed: $!\n"; 838 print STDOUT "\n *** `texexpand' done ***\n" if ($VERBOSITY > 1); 839 840 chdir($DESTDIR) if $DESTDIR; 841 $SIG{'INT'} = 'handler'; 842 843 &open_dbm_database; 844 &initialise_sections; 845 print STDOUT "\n *** database open ***\n" if ($VERBOSITY > 1); 846 847 if ($IMAGES_ONLY) { 848 &make_off_line_images; 849 } else { 850 &rename_image_files; 851 &load_style_file_translations; 852 &make_language_rx; 853 &make_raw_arg_cmd_rx; 854# &make_isolatin1_rx unless ($NO_ISOLATIN); 855 &translate_titles; 856 &make_sections_rx; 857 print "\nReading ..."; 858 if ($SHORT_FILENAME) { 859 L2hos->Rename ("$TMP_$dd$FILE" ,"$TMP_$dd$SHORT_FILENAME" ); 860 &slurp_input_and_partition_and_pre_process( 861 "$TMP_$dd$SHORT_FILENAME"); 862 } else { 863 &slurp_input_and_partition_and_pre_process("$TMP_$dd$FILE"); 864 } 865 &add_preamble_head; 866 # Create a regular expressions 867 &set_depth_levels; 868 &make_sections_rx; 869 &make_order_sensitive_rx; 870 &add_document_info_page if ($INFO && !(/\\htmlinfo/)); 871 &add_bbl_and_idx_dummy_commands; 872 &translate; # Destructive! 873 } 874 &style_sheet; 875 &close_dbm_database; 876 &cleanup(); 877 878#JCL: read warnings from file to $warnings 879 local($warnings) = &get_warnings; 880 print "\n\n*********** WARNINGS *********** \n$warnings" 881 if ($warnings || $NO_IMAGES || $IMAGES_ONLY); 882 &image_cache_message if ($NO_IMAGES || $IMAGES_ONLY); 883 &image_message if ($warnings =~ /Failed to convert/io); 884 undef $warnings; 885 886# JCL - generate directory index entry. 887# Yet, a hard link, cause Perl lacks symlink() on some systems. 888 do { 889 local($EXTN) = $EXTN; 890 $EXTN =~ s/_\w+(\.html?)/$1/ if ($frame_main_name); 891 local($from,$to) = (eval($LINKPOINT),eval($LINKNAME)); 892 if (length($from) && length($to) && ($from ne $to)) { 893 #frames may have altered $EXTN 894 $from =~ s/$frame_main_name(\.html?)/$1/ if ($frame_main_name); 895 $to =~ s/$frame_main_name(\.html?)/$1/ if ($frame_main_name); 896 L2hos->Unlink($to); 897 L2hos->Link($from,$to); 898 } 899 } unless ($NO_AUTO_LINK || !($LINKPOINT) || !($LINKNAME)); 900 901 &html_validate if ($HTML_VALIDATE && $HTML_VALIDATOR); 902 903# Go back to the source directory 904 chdir($orig_cwd); 905 $TEST_MODE = $DESTDIR if($TEST_MODE); # save path 906 $DESTDIR = ''; 907 $OUT_NODE = 0 unless $FIXEDDIR; 908 $STYLESHEET = '' if ($STYLESHEET =~ /^\Q$FILE./); 909 } 910 print "\nUnknown commands: ". join(" ",keys %unknown_commands) 911 if %unknown_commands; 912###MEH -- math support 913 print "\nMath commands outside math: " . 914 join(" ",keys %commands_outside_math) . 915 "\n Output may look weird or may be faulty!\n" 916 if %commands_outside_math; 917 print "\nDone.\n"; 918 if($TEST_MODE) { 919 $TEST_MODE =~ s:[$dd$dd]+$::; 920 print "\nTo view the results, point your browser at:\n", 921 L2hos->path2URL(L2hos->Make_directory_absolute($TEST_MODE).$dd. 922 "index$EXTN"),"\n"; 923 } 924 $end_time = time; 925 $total_time = $end_time - $start_time; 926 print STDOUT join(' ',"Timing:",$total_time,"seconds\n") 927 if ($TIMING||$DEBUG||($VERBOSITY > 2)); 928 $_; 929} 930 931sub open_dbm_database { 932 # These are DBM (unix DataBase Management) arrays which are actually 933 # stored in external files. They are used for communication between 934 # the main process and forked child processes; 935 print STDOUT "\n"; # this mysteriously prevents a core dump ! 936 937 dbmopen(%verb, "$TMP_${dd}verb",0755); 938# dbmopen(%verbatim, "$TMP_${dd}verbatim",0755); 939 dbmopen(%verb_delim, "$TMP_${dd}verb_delim",0755); 940 dbmopen(%expanded,"$TMP_${dd}expanded",0755); 941# Holds max_id, verb_counter, verbatim_counter, eqn_number 942 dbmopen(%global, "$TMP_${dd}global",0755); 943# Hold style sheet information 944 dbmopen(%env_style, "$TMP_${dd}envstyles",0755); 945 dbmopen(%txt_style, "$TMP_${dd}txtstyles",0755); 946 dbmopen(%styleID, "$TMP_${dd}styleIDs",0755); 947 948# These next two are used during off-line image conversion 949# %new_id_map maps image id's to page_numbers of the images in images.tex 950# %image_params maps image_ids to conversion parameters for that image 951 dbmopen(%new_id_map, "$TMP_${dd}ID_MAP",0755); 952 dbmopen(%img_params, "$TMP_${dd}IMG_PARAMS",0755); 953 dbmopen(%orig_name_map, "$TMP_${dd}ORIG_MAP",0755); 954 955 $global{'max_id'} = ($global{'max_id'} | 0); 956 &read_mydb(\%verbatim, "verbatim"); 957 $global{'verb_counter'} = ($global{'verb_counter'} | 0); 958 $global{'verbatim_counter'} = ($global{'verbatim_counter'} | 0); 959 960 &read_mydb(\%new_command, "new_command"); 961 &read_mydb(\%renew_command, "renew_command"); 962 &read_mydb(\%provide_command, "provide_command"); 963 &read_mydb(\%new_theorem, "new_theorem"); 964 &read_mydb(\%new_environment, "new_environment"); 965 &read_mydb(\%dependent, "dependent"); 966# &read_mydb(\%env_style, "env_style"); 967# &read_mydb(\%styleID, "styleID"); 968 # MRO: Why should we use read_mydb instead of catfile? 969 $preamble = &catfile(&_dbname("preamble"),1) || ''; 970 $prelatex = &catfile(&_dbname("prelatex"),1) || ''; 971 $aux_preamble = &catfile(&_dbname("aux_preamble"),1) || ''; 972 &restore_critical_variables; 973} 974 975sub close_dbm_database { 976 &save_critical_variables; 977 dbmclose(%verb); undef %verb; 978# dbmclose(%verbatim); undef %verbatim; 979 dbmclose(%verb_delim); undef %verb_delim; 980 dbmclose(%expanded); undef %expanded; 981 dbmclose(%global); undef %global; 982 dbmclose(%env_style); undef %env_style; 983 dbmclose(%style_id); undef %style_id; 984 dbmclose(%new_id_map); undef %new_id_map; 985 dbmclose(%img_params); undef %img_params; 986 dbmclose(%orig_name_map); undef %orig_name_map; 987 dbmclose(%txt_style); undef %txt_style; 988 dbmclose(%styleID); undef %styleID; 989} 990 991sub clear_images_dbm_database { 992 # <Added calls to dbmclose dprhws> 993 # %new_id_map will be used by the off-line image conversion process 994 # 995 dbmclose(%new_id_map); 996 dbmclose(%img_params); 997 dbmclose(%orig_name_map); 998 undef %new_id_map; 999 undef %img_params; 1000 undef %orig_name_map; 1001 dbmopen(%new_id_map, "$TMP_${dd}ID_MAP",0755); 1002 dbmopen(%img_params, "$TMP_${dd}IMG_PARAMS",0755); 1003 dbmopen(%orig_name_map, "$TMP_${dd}ORIG_MAP",0755); 1004} 1005 1006sub initialise_sections { 1007 local($key); 1008 foreach $key (keys %numbered_section) { 1009 $global{$key} = $numbered_section{$key}} 1010} 1011 1012sub save_critical_variables { 1013 $global{'math_markup'} = $NO_MATH_MARKUP; 1014 $global{'charset'} = $CHARSET; 1015 $global{'charenc'} = $charset; 1016 $global{'language'} = $default_language; 1017 $global{'isolatin'} = $ISOLATIN_CHARS; 1018 $global{'unicode'} = $UNICODE_CHARS; 1019 if ($UNFINISHED_ENV) { 1020 $global{'unfinished_env'} = $UNFINISHED_ENV; 1021 $global{'replace_end_env'} = $REPLACE_END_ENV; 1022 } 1023 $global{'unfinished_comment'} = $UNFINISHED_COMMENT; 1024 if (@UNMATCHED_OPENING) { 1025 $global{'unmatched'} = join(',',@UNMATCHED_OPENING); 1026 } 1027} 1028 1029sub restore_critical_variables { 1030 $NO_MATH_MARKUP = ($global{'math_markup'}| 1031 (defined $NO_MATH_MARKUP ? $NO_MATH_MARKUP:1)); 1032 $CHARSET = ($global{'charset'}| $CHARSET); 1033 $charset = ($global{'charenc'}| $charset); 1034 $default_language = ($global{'language'}| 1035 (defined $default_language ? $default_language:'english')); 1036 $ISOLATIN_CHARS = ($global{'isolatin'}| 1037 (defined $ISOLATIN_CHARS ? $ISOLATIN_CHARS:0)); 1038 $UNICODE_CHARS = ($global{'unicode'}| 1039 (defined $UNICODE_CHARS ? $UNICODE_CHARS:0)); 1040 if ($global{'unfinished_env'}) { 1041 $UNFINISHED_ENV = $global{'unfinished_env'}; 1042 $REPLACE_END_ENV = $global{'replace_end_env'}; 1043 } 1044 $UNFINISHED_COMMENT = $global{'unfinished_comment'}; 1045 if ($global{'unmatched'}) { 1046 @UNMATCHED_OPENING = split(',',$global{'unmatched'}); 1047 } 1048 1049 # undef any renewed-commands... 1050 # so the new defs are read from %new_command 1051 local($cmd,$key,$code); 1052 foreach $key (keys %renew_command) { 1053 $cmd = "do_cmd_$key"; 1054 $code = "undef \&$cmd"; eval($code) if (defined &$cmd); 1055 if ($@) { print "\nundef \&do_cmd_$cmd failed"} 1056 } 1057} 1058 1059#JCL: The warnings should have been handled within the DBM database. 1060# Unfortunately if the contents of an array are more than ~900 (system 1061# dependent) chars long then dbm cannot handle it and gives error messages. 1062sub write_warnings { #clean 1063 my ($str) = @_; 1064 $str .= "\n" unless($str =~ /\n$/); 1065 print STDOUT "\n *** Warning: $str" if ($VERBOSITY > 1); 1066 my $warnings = ''; 1067 if(-f 'WARNINGS') { 1068 $warnings = &catfile('WARNINGS') || ''; 1069 } 1070 return () if ($warnings =~ /\Q$str\E/); 1071 if(open(OUT,">>WARNINGS")) { 1072 print OUT $str; 1073 close OUT; 1074 } else { 1075 print "\nError: Cannot append to 'WARNINGS': $!\n"; 1076 } 1077} 1078 1079sub get_warnings { 1080 return &catfile('WARNINGS',1) || ''; 1081} 1082 1083# MRO: Standardizing 1084sub catfile { 1085 my ($file,$ignore) = @_; 1086 unless(open(CATFILE,"<$file")) { 1087 print "\nError: Cannot read '$file': $!\n" 1088 unless($ignore); 1089 return undef; 1090 } 1091 local($/) = undef; # slurp in whole file 1092 my $contents = <CATFILE>; 1093 close(CATFILE); 1094 $contents; 1095} 1096 1097 1098sub html_validate { 1099 my ($extn) = $EXTN; 1100 if ($EXTN !~ /^\.html?$/i) { 1101 $extn =~ s/^[^\.]*(\.html?)$/$1/; 1102 } 1103 print "\n *** Validating ***\n"; 1104 my @htmls = glob("*$extn"); 1105 my $file; 1106 foreach $file (@htmls) { 1107 system("$HTML_VALIDATOR $file"); 1108 } 1109} 1110 1111sub lost_argument { 1112 local($cmd) = @_; 1113 &write_warnings("\nincomplete argument to command: \\$cmd"); 1114} 1115 1116#----------------------------------------------------------------------------- 1117 1118# These subroutines should have been handled within the DBM database. 1119# Unfortunately if the contents of an array are more than ~900 (system 1120# dependent) chars long then dbm cannot handle it and gives error messages. 1121# So here we save and then read the contents explicitly. 1122sub write_mydb { 1123 my ($db, $key, $str) = @_; 1124 &write_mydb_simple($db, "\n$mydb_mark#$key#$str"); 1125} 1126 1127# generate the DB file name from the DB name 1128sub _dbname { 1129 "$TMP_$dd$_[0]"; 1130} 1131 1132sub write_mydb_simple { 1133 my ($db, $str) = @_; 1134 my $file = &_dbname($db); 1135 if(open(DB,">>$file")) { 1136 print DB $str; 1137 close DB; 1138 } else { 1139 print "\nError: Cannot append to '$file': $!\n"; 1140 } 1141} 1142 1143sub clear_mydb { 1144 my ($db) = @_; 1145 my $file = &_dbname($db); 1146 if(open(DB,">$file")) { 1147 close DB; 1148 } else { 1149 print "\nError: Cannot clear '$file': $!\n"; 1150 } 1151} 1152 1153# Assumes the existence of a DB file which contains 1154# sequences of e.g. verbatim counters and verbatim contents. 1155sub read_mydb { 1156 my ($dbref,$name) = @_; 1157 my $contents = &catfile(&_dbname($name),1); 1158 return '' unless(defined $contents); 1159 my @tmp = split(/\n$mydb_mark#([^#]*)#/, $contents); 1160 my $i = 1; # Ignore the first element at 0 1161 print "\nDBM: $name open..." if ($VERBOSITY > 2); 1162 while ($i < scalar(@tmp)) { 1163 my $tmp1 = $tmp[$i]; 1164 my $tmp2 = $tmp[++$i]; 1165 $$dbref{$tmp1} = defined $tmp2 ? $tmp2 : ''; 1166 ++$i; 1167 }; 1168 $contents; 1169} 1170 1171#----------------------------------------------------------------------------- 1172 1173# Reads in a latex generated file (e.g. .bbl or .aux) 1174# It returns success or failure 1175# ****** and binds $_ in the caller as a side-effect ****** 1176sub process_ext_file { 1177 local($ext) = @_; 1178 local($found, $extfile,$dum,$texpath); 1179 $extfile = $EXTERNAL_FILE||$FILE; 1180 local($file) = &fulltexpath("$extfile.$ext"); 1181 $found = 0; 1182 &write_warnings( 1183 "\n$extfile.$EXT is newer than $extfile.$ext: Please rerun latex" . ## AYS 1184 (($ext =~ /bbl/) ? " and bibtex.\n" : ".\n")) 1185 if ( ($found = (-f $file)) && 1186 &newer(&fulltexpath("$extfile.$EXT"), $file)); ## AYS 1187 if ((!$found)&&($extfile =~ /\.$EXT$/)) { 1188 $file = &fulltexpath("$extfile"); 1189 &write_warnings( 1190 "\n$extfile is newer than $extfile: Please rerun latex" . ## AYS 1191 (($ext =~ /bbl/) ? " and bibtex.\n" : ".\n")) 1192 if ( ($found = (-f $file)) && 1193 &newer(&fulltexpath("$extfile"), $file)); ## AYS 1194 } 1195 1196 # check in other directories on the $TEXINPUTS paths 1197 if (!$found) { 1198 foreach $texpath (split /$envkey/, $TEXINPUTS ) { 1199 $file = "$texpath$dd$extfile.$ext"; 1200 last if ($found = (-f $file)); 1201 } 1202 } 1203 if ( $found ) { 1204 print "\nReading $ext file: $file ..."; 1205 # must allow @ within control-sequence names 1206 $dum = &do_cmd_makeatletter(); 1207 &slurp_input($file); 1208 if ($ext =~ /bbl/) { 1209 # remove the \newcommand{\etalchar}{...} since not needed 1210 s/^\\newcommand\{\\etalchar}[^\n\r]*[\n\r]+//s; 1211 } 1212 &pre_process; 1213 &substitute_meta_cmds if (%new_command || %new_environment); 1214 if ($ext eq "aux") { 1215 my $latex_pathname = L2hos->path2latex($file); 1216 $aux_preamble .= 1217 "\\AtBeginDocument{\\makeatletter\n\\input $latex_pathname\n\\makeatother\n}\n"; 1218 local(@extlines) = split ("\n", $_); 1219 print " translating ".(0+@extlines). " lines " if ($VERBOSITY >1); 1220 local($eline,$skip_to); #$_ = ''; 1221 foreach $eline (@extlines) { 1222 if ($skip_to) { next unless ($eline =~ s/$O$skip_to$C//) } 1223 $skip_to = ''; 1224 # skip lines added for pdfTeX/hyperref compatibility 1225 next if ($eline =~ /^\\(ifx|else|fi|global \\let|gdef|AtEndDocument|let )/); 1226 # remove \index and \label commands, else invalid links may result 1227 $eline =~ s/\\(index|label)\s*($O\d+$C).*\2//g; 1228 if ($eline =~ /\\(old)?contentsline/) { 1229 do { local($_,$save_AUX) = ($eline,$AUX_FILE); 1230 $AUX_FILE = 0; 1231 &wrap_shorthand_environments; 1232 #footnote markers upset the numbering 1233 s/\\footnote(mark|text)?//g; 1234 $eline = &translate_environments($_); 1235 $AUX_FILE = $save_AUX; 1236 undef $_ }; 1237 } elsif ($eline =~ s/^\\\@input//) { 1238 &do_cmd__at_input($eline); 1239 $eline = ''; 1240 } elsif ($eline =~ s/^\\\@setckpt$O(\d+)$C//) { 1241 $skip_to = $1; next; 1242 } 1243# $eline =~ s/$image_mark#([^#]+)#/print "\nIMAGE:",$img_params{$1},"\n";''/e; 1244# $_ .= &translate_commands(&translate_environments($eline)); 1245 $_ .= &translate_commands($eline) if $eline; 1246 } 1247 undef @extlines; 1248 } elsif ($ext =~ /$caption_suffixes/) { 1249 local(@extlines) = split ("\n", $_); 1250 print " translating ".(0+@extlines). " lines "if ($VERBOSITY >1); 1251 local($eline); $_ = ''; 1252 foreach $eline (@extlines) { 1253 # remove \index and \label commands, else invalid links may result 1254 $eline =~ s/\\(index|label)\s*($O\d+$C).*\2//gso; 1255 if ($eline =~ /\\(old)?contentsline/) { 1256 do { local($_,$save_PREAMBLE) = ($eline,$PREAMBLE); 1257 $PREAMBLE = 0; 1258 &wrap_shorthand_environments; 1259 $eline = &translate_environments($_); 1260 $PREAMBLE = $save_PREAMBLE; 1261 undef $_ }; 1262 } 1263 $_ .= &translate_commands($eline); 1264 } 1265 undef @extlines; 1266 } else { 1267 print " wrapping " if ($VERBOSITY >1); 1268 &wrap_shorthand_environments; 1269 $_ = &translate_commands(&translate_environments($_)); 1270 print " translating " if ($VERBOSITY >1); 1271 } 1272 print "\n processed size: ".length($_)."\n" if($VERBOSITY>1); 1273 $dum = &do_cmd_makeatother(); 1274 } else { 1275 print "\n*** Could not find file: $file ***\n" if ($DEBUG) 1276 }; 1277 $found; 1278} 1279 1280sub deal_with_texinputs { 1281# The dot precedes all, this let's local files override always. 1282# The dirs we want are given as parameter list. 1283 if(!$TEXINPUTS) { $TEXINPUTS = '.' } 1284 elsif ($TEXINPUTS =~ /^$envkey/) { 1285 $TEXINPUTS = '.'.$TEXINPUTS 1286 }; 1287 if ($ROOTED) {$TEXINPUTS .= "$envkey$FIXEDDIR"} 1288 $TEXINPUTS = &absolutize_path($TEXINPUTS); 1289 $ENV{'TEXINPUTS'} = join($envkey,".",@_,$TEXINPUTS,$ENV{'TEXINPUTS'}); 1290} 1291 1292# provided by Fred Drake 1293sub absolutize_path { 1294 my ($path) = @_; 1295 my $npath = ''; 1296 foreach $dir (split /$envkey/o, $path) { 1297 $npath .= L2hos->Make_directory_absolute($dir) . $envkey; 1298 } 1299 $npath =~ s/$envkey$//; 1300 $npath; 1301} 1302 1303sub add_document_info_page { 1304 # Uses $outermost_level 1305 # Nasty race conditions if the next two are done in parallel 1306 local($X) = ++$global{'max_id'}; 1307 local($Y) = ++$global{'max_id'}; 1308 ###MEH -- changed for math support: no underscores in commandnames 1309 $_ = join('', $_ 1310 , (($MAX_SPLIT_DEPTH <= $section_commands{$outermost_level})? 1311 "\n<HR>\n" : '') 1312 , "\\$outermost_level", "*" 1313 , "$O$X$C$O$Y$C\\infopagename$O$Y$C$O$X$C\n", 1314 , " \\textohtmlinfopage"); 1315} 1316 1317 1318# For each style file name in TMP_styles (generated by texexpand) look for a 1319# perl file in $LATEX2HTMLDIR/styles and load it. 1320sub load_style_file_translations { 1321 local($_, $style, $options, $dir); 1322 print "\n"; 1323 if ($TEXDEFS) { 1324 foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) { 1325 if (-f ($_ = "$dir${dd}texdefs.perl")) { 1326 print "\nLoading $_..."; 1327 require ($_); 1328 $styles_loaded{'texdefs'} = 1; 1329 last; 1330 } 1331 } 1332 } 1333 1334 # packages automatically implemented 1335 local($auto_styles) = $AUTO_STYLES; 1336 $auto_styles .= 'array|' if ($HTML_VERSION > 3.1); 1337 $auto_styles .= 'tabularx|' if ($HTML_VERSION > 3.1); 1338 $auto_styles .= 'theorem|'; 1339 1340 # these are not packages, but can appear as if class-options 1341 $auto_styles .= 'psamsfonts|'; 1342 $auto_styles .= 'noamsfonts|'; 1343 1344 $auto_styles =~ s/\|$//; 1345 1346 if(open(STYLES, "<$TMP_${dd}styles")) { 1347 while(<STYLES>) { 1348 if(s/^\s*(\S+)\s*(.*)$/$style = $1; $options = $2;/eo) { 1349 &do_require_package($style); 1350 $_ = $DONT_INCLUDE; 1351 s/:/|/g; 1352 &write_warnings("No implementation found for style \`$style\'\n") 1353 unless ($styles_loaded{$style} || $style =~ /^($_)$/ 1354 || $style =~ /$auto_styles/); 1355 1356 # MRO: Process options for packages 1357 &do_package_options($style,$options) if($options); 1358 } 1359 } 1360 close(STYLES); 1361 } else { 1362 print "\nError: Cannot read '$TMP_${dd}styles': $!\n"; 1363 } 1364} 1365 1366################## Weird Special case ################## 1367 1368# The new texexpand can be told to leave in \input and \include 1369# commands which contain code that the translator should simply pass 1370# to latex, such as the psfig stuff. These should still be seen by 1371# TeX, so we add them to the preamble ... 1372 1373sub do_include_lines { 1374 while (s/$include_line_rx//o) { 1375 local($include_line) = &revert_to_raw_tex($&); 1376 &add_to_preamble ('include', $include_line); 1377 } 1378} 1379 1380########################## Preprocessing ############################ 1381 1382# JCL(jcl-verb) 1383# The \verb declaration and the verbatim environment contain simulated 1384# typed text and should not be processed. Characters such as $,\,{,and } 1385# loose their special meanings and should not be considered when marking 1386# brackets etc. To achieve this \verb declarations and the contents of 1387# verbatim environments are replaced by markers. At the end the original 1388# text is put back into the document. 1389# The markers for verb and verbatim are different so that these commands 1390# can be restored to what the raw input was just in case they need to 1391# be passed to latex. 1392 1393sub pre_process { 1394 # Modifies $_; 1395 #JKR: We need support for some special environments. 1396 # This has to be here, because they might contain 1397 # structuring commands like \section etc. 1398 local(%comments); 1399 &pre_pre_process if (defined &pre_pre_process); 1400 s/\\\\/\\\\ /go; # Makes it unnecessary to look for escaped cmds 1401 &replace_html_special_chars; 1402 # Remove fake environment which should be invisible to LaTeX2HTML. 1403 s/\001//m; 1404 s/[%]end\s*{latexonly}/\001/gom; 1405 s/[%]begin\s*{latexonly}([^\001]*)\001/%/gos; 1406 s/\001//m; 1407 1408 &preprocess_alltt if defined(&preprocess_alltt); 1409 1410 $KEEP_FILE_MARKERS = 1; 1411 if ($KEEP_FILE_MARKERS) { 1412# if (s/%%% TEXEXPAND: \w+ FILE( MARKER)? (\S*).*/ 1413# '<tex2html_'.($1?'':'end').'file>'.qq|#$2#|."\n"/em) { 1414# $_ = "<tex2html_file>#$2#\n". $_ }; 1415 #RRM: ignore \n at end of included file, else \par may result 1416 if (s/(\n{1,2})?%%% TEXEXPAND: \w+ FILE( MARKER)? (\S*).*\n?/ 1417 ($2?$1:"\n").'<tex2html_'.($2?'':'end').'file>'.qq|#$3#|."\n"/em) { 1418 $_ = "<tex2html_file>#$3#\n". $_ }; 1419 } else { 1420 s/%%% TEXEXPAND[^\n]*\n//gm; 1421 } 1422 1423 # Move all LaTeX comments into a local list 1424 s/([ \t]*(^|\G|[^\\]))(%.*(\n[ \t]*|$))/print "%"; 1425 $comments{++$global{'verbatim_counter'}} = "$3"; 1426 &write_mydb("verbatim", $global{'verbatim_counter'}, $3); 1427 "$1$comment_mark".$global{'verbatim_counter'}."\n"/mge; 1428 # Remove the htmlonly-environment 1429 s/\\begin\s*{htmlonly}\s*\n?//gom; 1430 s/\\end\s*{htmlonly}\s*\n?//gom; 1431 # Remove enviroments which should be invisible to LaTeX2HTML. 1432 s/\n[^%\n]*\\end\s*{latexonly}\s*\n?/\001/gom; 1433 s/((^|\n)[^%\n]*)\\begin\s*{latexonly}([^\001]*)\001/$1/gom; 1434 s/\\end\s*{comment}\s*\n?/\001/gom; 1435 s/\\begin\s*{comment}([^\001]*)\001//gom; 1436 1437 # this used to be earlier, but that can create problems with comments 1438 &wrap_other_environments if (%other_environments); 1439 1440# s/\\\\/\\\\ /go; # Makes it unnecessary to look for escaped cmds 1441 local($next, $esc_del); 1442 &normalize_language_changes; 1443 # Patches by #JKR, #EI#, #JCL(jcl-verb) 1444 1445 #protect \verb|\begin/end....| parts, for LaTeX documentation 1446 s/(\\verb\*?(.))\\(begin|end)/$1\003$3/g; 1447 1448 local(@processedV); 1449 local($opt, $style_info,$before, $contents, $after, $env); 1450 while (($UNFINISHED_COMMENT)|| 1451 (/\\begin\s*($opt_arg_rx)?\s*\{($verbatim_env_rx|$keepcomments_rx)\}/o)) { 1452 ($opt, $style_info) = ($1,$2); 1453 $before=$contents=$after=$env=''; 1454 if ($UNFINISHED_COMMENT) { 1455 $UNFINISHED_COMMENT =~ s/([^:]*)::(\d+)/$env=$1;$after=$_; 1456 $before = join("",$unfinished_mark,$env,$2,"#");''/e; 1457 print "\nfound the lost \\end{$env}\n"; 1458 } 1459 #RRM: can we avoid copying long strings here ? 1460 # maybe this loop can be an s/.../../s with (.*?) 1461 # 1462 ($before, $after, $env) = ($`, $', $3) unless ($env); 1463 if (!($before =~ 1464 /\\begin(\s*\[[^\]]*\]\s*)?\{($verbatim_env_rx|$keepcomments_rx)\}/)) { 1465 push(@processedV,$before); 1466 print "'";$before = ''; 1467 } 1468 if ($after =~ /\s*\\end\{$env[*]?}/) { # Must NOT use the s///o option!!! 1469 ($contents, $after) = ($`, $'); 1470 $contents =~ s/^\n+/\n/s; 1471# $contents =~ s/\n+$//s; 1472 1473 # re-insert comments 1474 $contents =~ s/$comment_mark(\d+)\n?/$comments{$1}/g; 1475# $contents =~ s/$comment_mark(\d+)/$verbatim{$1}/g; 1476 1477 # revert '\\ ' -> '\\' only once 1478 if ($env =~ /rawhtml|$keepcomments_rx/i) { 1479 $contents = &revert_to_raw_tex($contents); 1480 } else { 1481 $contents =~ s/([^\\](?:\\\\)*\\)([$html_escape_chars])/$1.&special($2)/geos; 1482 $contents =~ s/\\\\ /\\\\/go; 1483 } 1484 1485 if ($env =~/$keepcomments_rx/) { 1486 $verbatim{++$global{'verbatim_counter'}} = "$contents"; 1487 } else { 1488 &write_mydb("verbatim", ++$global{'verbatim_counter'}, $contents); 1489 } 1490# $verbatim{$global{'verbatim_counter'}} = "$contents" if ($env =~/$keepcomments_rx/); 1491# $verbatim{$global{'verbatim_counter'}} = "$contents"; 1492 1493 if ($env =~ /rawhtml|$keepcomments_rx/i) { 1494 if ($before) { 1495 $after = join("",$verbatim_mark,$env 1496 ,$global{'verbatim_counter'},"#",$after); 1497 } else { 1498 push (@processedV, join("",$verbatim_mark,$env 1499 ,$global{'verbatim_counter'},"#")); 1500 } 1501 } elsif ($env =~ /tex2html_code/) { 1502 if ($before) { 1503 $after = join("","\\begin", $opt, "\{verbatim_code\}" 1504 , $verbatim_mark,$env 1505 , $global{'verbatim_counter'},"#" 1506 , "\\end\{verbatim_code\}",$after); 1507 } else { 1508 push (@processedV 1509 , join("","\\begin", $opt, "\{verbatim_code\}" 1510 , $verbatim_mark,$env 1511 , $global{'verbatim_counter'},"#" 1512 , "\\end\{verbatim_code\}")); 1513 } 1514 } else { 1515 if ($before) { 1516 $after = join("","\\begin", $opt, "\{tex2html_preform\}" 1517 , $verbatim_mark,$env 1518 , $global{'verbatim_counter'},"#" 1519 , "\\end\{tex2html_preform\}",$after); 1520 } else { 1521 push (@processedV 1522 , join("","\\begin", $opt, "\{tex2html_preform\}" 1523 , $verbatim_mark,$env 1524 , $global{'verbatim_counter'},"#" 1525 , "\\end\{tex2html_preform\}" )); 1526 } 1527 } 1528 } else { 1529 print "Cannot find \\end{$env}\n"; 1530 $after =~ s/$comment_mark(\d+)\n?/$comments{$1}/g; 1531# $after =~ s/$comment_mark(\d+)/$verbatim{$1}/g; 1532 if ($env =~ /rawhtml|$keepcomments_rx/i) { 1533 $after = &revert_to_raw_tex($contents); 1534 } else { 1535 $after =~ s/([^\\](?:\\\\)*\\)([$html_escape_chars])/$1.&special($2)/geos; 1536 $after =~ s/\\\\ /\\\\/go; 1537 } 1538 if ($env =~/$keepcomments_rx/) { 1539 $verbatim{++$global{'verbatim_counter'}} = "$after"; 1540 } else { 1541 &write_mydb("verbatim", ++$global{'verbatim_counter'}, $after ); 1542 } 1543 $after = join("",$unfinished_mark,$env 1544 ,$global{'verbatim_counter'},"#"); 1545 } 1546 $_ = join("",$before,$after); 1547 } 1548 print STDOUT "\nsensitive environments found: ".(int(0+@processedV/2))." " 1549 if((@processedV)&&($VERBOSITY > 1)); 1550 $_ = join('',@processedV, $_); undef @processedV; 1551 1552 #restore \verb|\begin/end....| parts, for LaTeX documentation 1553# $_ =~ s/(\\verb\W*?)\003(begin|end)/$1\\$2/g; 1554 $_ =~ s/(\\verb(;SPM\w+;|\W*?))\003(begin|end)/$1\\$3/g; 1555 1556 # Now do the \verb declarations 1557 # Patches by: #JKR, #EI#, #JCL(jcl-verb) 1558 # Tag \verb command and legal opening delimiter with unique number. 1559 # Replace tagged ones and its contents with $verb_mark & id number if the 1560 # closing delimiter can be found. After no more \verb's are to tag, revert 1561 # tagged one's to the original pattern. 1562 local($del,$contents,$verb_rerun); 1563 local($id) = $global{'verb_counter'}; 1564 # must tag only one alternation per loop 1565 ##RRM: can this be speeded up using a list ?? 1566 my $vbmark = $verb_mark; 1567 while (s/\\verb(\t*\*\t*)(\S)/"<verb$1".++$id.">$2"/e || 1568 s/\\verb()(\;SPM\w+\;|[^a-zA-Z*\s])/"<verb$1".++$id.">$2"/e || 1569 s/\\verb(\t\t*)([^*\s])/"<verb$1".++$id.">$2"/e) { 1570 1571 $del = $2; 1572 #RRM: retain knowledge of whether \verb* or \verb 1573 $vb_mark = ($1 =~/^\s*\*/? $verbstar_mark : $verb_mark); 1574 $esc_del = &escape_rx_chars($del); 1575 $esc_del = '' if (length($del) > 2); 1576 1577 # try to find closing delimiter and substitute the complete 1578 # statement with $verb_mark or $verbstar_mark 1579# s/(<verb[^\d>]*$id>[\Q$del\E])([^$esc_del\n]*)([\Q$del\E]|$comment_mark(\d+)\n?)/ 1580 s/(<verb[^\d>]*$id>\Q$del\E)([^$esc_del\n]*?)(\Q$del\E|$comment_mark(\d+)\n?)/ 1581 $contents=$2; 1582 if ($4) { $verb_rerun = 1; 1583 join('', "\\verb$del", $contents, $comments{$4}) 1584 } else { 1585 $contents =~ s|\\\\ |\\\\|g; 1586 $contents =~ s|\n| |g; 1587 $verb{$id}=$contents; 1588 $verb_delim{$id}=$del; 1589 join('',$vb_mark,$id,$verb_mark) 1590 } 1591 /e; 1592 } 1593 $global{'verb_counter'} = $id; 1594 # revert changes to fake verb statements 1595 s/<verb([^\d>]*)\d+>/\\verb$1/g; 1596 1597 #JKR: the comments include the linebreak and the following whitespace 1598# s/([^\\]|^)(%.*\n[ \t]*)+/$1/gom; # Remove Comments but not % which may be meaningful 1599 s/((^|\n)$comment_mark(\d+))+//gom; # Remove comment markers on new lines, but *not* the trailing \n 1600 s/(\\\w+|(\W?))($comment_mark\d*\n?)/($2)? $2.$3:($1? $1.' ':'')/egm; # Remove comment markers, not after braces 1601# s/(\W?)($comment_mark\d*\n?)/($1)? $1.$2:''/egm; # Remove comment markers, not after braces 1602 # Remove comment markers, but *not* the trailing \n 1603# HWS: Correctly remove multiple %%'s. 1604# 1605 s/\\%/\002/gm; 1606# s/(%.*\n[ \t]*)//gm; 1607 s/(%[^\n]*\n)[ \t]*/$comment_mark\n/gm; 1608 1609 s/\002/\\%/gm; 1610 1611 local($tmp1,$tmp2); 1612 s/^$unfinished_mark$keepcomments_rx(\d+)#\n?$verbatim_mark$keepcomments_rx(\d+)#/ 1613 $verbatim{$4}."\n\\end{$1}"/egm; # Raw TeX 1614 s/$verbatim_mark$keepcomments_rx(\d+)#/ 1615 $tmp1 = $1; 1616 $tmp2 = &protect_after_comments($verbatim{$2}); 1617 $tmp2 =~ s!\n$!!s; 1618 join ('', "\\begin{$tmp1}" 1619 , $tmp2 1620 , "\n\\end{$tmp1}" 1621 )/egm; # Raw TeX 1622 s/$unfinished_mark$keepcomments_rx(\d+)#/$UNFINISHED_COMMENT="$1::$2"; 1623 "\\begin{$1}\n".$verbatim{$2}/egm; # Raw TeX 1624 1625 $KEEP_FILE_MARKERS = 1; 1626 if ($KEEP_FILE_MARKERS) { 1627 s/%%% TEXEXPAND: \w+ FILE( MARKER) (\S*).*\n/ 1628 '<tex2html_'.($1?'':'end').'file>'.qq|#.$2#\n|/gem; 1629 } else { 1630 s/%%% TEXEXPAND[^\n]*\n//gm; 1631 } 1632 1633 &mark_string($_); 1634 1635 1636 # attempt to remove the \html \latex and \latexhtml commands 1637 s/\\latex\s*($O\d+$C)(.*)\1//gm; 1638 s/\\latexhtml\s*($O\d+$C)(.*)\1\s*($O\d+$C)(.*)\3/$4/sg; 1639 s/\\html\s*($O\d+$C)(.*)\1/$2/sg; 1640 s/\\html\s*($O\d+$C)//gm; 1641 1642# &make_unique($_); 1643} 1644 1645# RRM: When comments are retained, then ensure that they are benign 1646# by removing \s and escaping braces, 1647# so that environments/bracing cannot become unbalanced. 1648sub protect_after_comments { 1649 my ($verb_text) = @_; 1650# $verb_text =~ s/\%(.*)/'%'.&protect_helper($1)/eg; 1651 $verb_text =~ s/(^|[^\\])(\\\\)*\%(.*)/$1.$2.'%'.&protect_helper($3)/emg; 1652 $verb_text; 1653} 1654 1655sub protect_helper { 1656 my ($text) = @_; 1657 $text =~ s/\\/ /g; 1658 $text =~ s/(\{|\})/\\$1/g; 1659 $text; 1660} 1661 1662sub make_comment { 1663 local($type,$_) = @_; 1664 $_ =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg; 1665 $_ = &revert_to_raw_tex($_); s/^\n+//m; 1666 $_ =~ s/\\(index|label)\s*\{.*\}//sg; 1667 s/\-\-/- -/g; s/\-\-/- -/g; # cannot have -- inside a comment 1668 $_ = join('', '<!-- ', $type , "\n ", $_ , "\n -->" ); 1669 $verbatim{++$global{'verbatim_counter'}} = $_; 1670 &write_mydb('verbatim', $global{'verbatim_counter'}, $_ ); 1671 join('', $verbatim_mark, 'verbatim' , $global{'verbatim_counter'},'#') 1672} 1673 1674sub wrap_other_environments { 1675 local($key, $env, $start, $end, $opt_env, $opt_start); 1676 foreach $key (keys %other_environments) { 1677 # skip bogus entries 1678 next unless ($env = $other_environments{$key}); 1679 $key =~ s/:/($start,$end)=($`,$');':'/e; 1680 1681 if (($end =~ /^\#$/m) && ($start =~ /^\#/m)) { 1682 # catch Indica pre-processor language switches 1683 $opt_start = $'; 1684 if ($env =~ s/\[(\w*)\]//o) { 1685 $opt_env = join('','[', ($1 ? $1 : $opt_start ), ']'); 1686 } 1687 local($next); 1688 while ($_ =~ /$start\b/) { 1689 push(@pre_wrapped, $`, "\\begin\{pre_$env\}", $opt_env ); 1690 $_=$'; 1691 if (/(\n*)$end/) { 1692 push(@pre_wrapped, $`.$1,"\\end\{pre_$env\}$1"); 1693 $_ = $'; 1694 if (!(s/^N(IL)?//o)) {$_ = '#'.$_ } 1695 } else { 1696 print "\n *** unclosed $start...$end chunk ***\n"; 1697 last; 1698 } 1699 } 1700 $_ = join('', @pre_wrapped, $_); 1701 undef @pre_wrapped; 1702 1703 } elsif (($end=~/^\n$/) && ($start =~ /^\#/)) { 1704 # catch ITRANS pre-processor language info; $env = 'nowrap'; 1705 local($ilang) = $start; $ilang =~ s/^\#//m; 1706 s/$start\s*\=([^<\n%]*)\s*($comment_mark\d*|\n|%)/\\begin\{tex2html_$env\}\\ITRANSinfo\{$ilang\}\{$1\}\n\\end\{tex2html_$env\}$2/g; 1707 1708 } elsif (!$end &&($start =~ /^\#/m)) { 1709 # catch Indica pre-processor input-mode switches 1710 s/$start(.*)\n/\\begin\{tex2html_$env\}$&\\end\{tex2html_$env\}\n/g; 1711 1712 } elsif (($start eq $end)&&(length($start) == 1)) { 1713 $start =~ s/(\W)/\\$1/; $end = $start; 1714 s/([^$end])$start([^$end]+)$end/$1\\begin\{pre_$env\}$2\\end\{pre_$env\}/mg; 1715 } elsif ($start eq $end) { 1716 if (!($start =~ /\#\#/)) { 1717 $start =~ s/(\W)/\\$1/g; $end = $start; } 1718 local (@pre_wrapped); 1719 local($opt); $opt = '[indian]' if ($start =~ /^\#\#$/m); 1720 while ($_ =~ /$start/s) { 1721 push(@pre_wrapped, $` , "\\begin\{pre_$env\}$opt"); 1722 $_=$'; 1723 if (/$end/s) { 1724 push(@pre_wrapped, $`, "\\end\{pre_$env\}"); 1725 $_ = $'; 1726 } else { 1727 print "\n *** unclosed $start...$end chunk ***\n"; 1728 last; 1729 } 1730 } 1731 $_ = join('', @pre_wrapped, $_); 1732 undef @pre_wrapped; 1733 } elsif ($start && ($env =~ /itrans/)) { 1734 # ITRANS is of this form 1735 local($indic); if($start =~ /\#(\w+)$/m) {$indic = $1} 1736 #include the language-name as an optional parameter 1737 s/$start\b/\\begin\{pre_$env\}\[$indic\]/sg; 1738 s/$end\b/\\end\{pre_$env\}/sg; 1739 } elsif (($start)&&($end)) { 1740 s/$start\b/\\begin\{pre_$env\}/sg; 1741 s/$end\b/\\end\{pre_$env\}/sg; 1742 } 1743 } 1744 $_; 1745} 1746 1747#################### Marking Matching Brackets ###################### 1748 1749# Reads the entire input file and performs pre_processing operations 1750# on it before returning it as a single string. The pre_processing is 1751# done on separate chunks of the input file by separate Unix processes 1752# as determined by LaTeX \input commands, in order to reduce the memory 1753# requirements of LaTeX2HTML. 1754sub slurp_input_and_partition_and_pre_process { 1755 local($file) = @_; 1756 local(%string, @files, $pos); 1757 local ($count) = 1; 1758 1759 unless(open(SINPUT,"<$file")) { 1760 die "\nError: Cannot read '$file': $!\n"; 1761 } 1762 local(@file_string); 1763 print STDOUT "$file" if ($VERBOSITY >1); 1764 while (<SINPUT>) { 1765 if (/TEXEXPAND: INCLUDED FILE MARKER (\S*)/) { 1766 # Forking seems to screw up the rest of the input stream 1767 # We save the current position ... 1768 $pos = tell SINPUT; 1769 print STDOUT " fork at offset $pos " if ($VERBOSITY >1); 1770 $string{'STRING'} = join('',@file_string); @file_string = (); 1771 &write_string_out($count); 1772 delete $string{'STRING'}; 1773 # ... so that we can return to it 1774 seek(SINPUT, $pos, 0); 1775 print STDOUT "\nDoing $1 "; 1776 ++$count} 1777 else { 1778# $string{'STRING'} .= $_ 1779 push(@file_string,$_); 1780 } 1781 } 1782 $string{'STRING'} = join('',@file_string); @file_string = (); 1783 &write_string_out($count); 1784 delete $string{'STRING'}; 1785 close SINPUT; 1786 @files = (); 1787 if(opendir(DIR, $TMP_)) { 1788 @files = sort grep(/^\Q$PARTITION_PREFIX\E\d+/, readdir(DIR)); 1789 closedir(DIR); 1790 } 1791 1792 unless(@files) { 1793 die "\nFailed to read in document parts.\n". 1794 "Look up section Globbing in the troubleshooting manual.\n"; 1795 } 1796 1797 $count = 0; 1798 foreach $file (@files) { 1799 print STDOUT "\nappending file: $TMP_$dd$file " if ($VERBOSITY > 1); 1800 $_ .= (&catfile("$TMP_$dd$file") || ''); 1801 print STDOUT "\ntotal length: ".length($_)." characters\n" if ($VERBOSITY > 1); 1802 } 1803 die "\nFailed to read in document parts (out of memory?).\n" 1804 unless length($_); 1805 print STDOUT "\ntotal length: ".length($_)." characters\n" if ($VERBOSITY > 1); 1806} 1807 1808sub write_string_out { 1809 local($count) = @_; 1810 if ($count < 10) {$count = '00'.$count} 1811 elsif ($count < 100) {$count = '0'.$count} 1812 local($pid); 1813 # All open unflushed streams are inherited by the child. If this is 1814 # not set then the parent will *not* wait 1815 $| = 1; 1816 # fork returns 0 to the child and PID to the parent 1817 &write_mydb_simple("prelatex", $prelatex); 1818 &close_dbm_database; 1819 unless ($CAN_FORK) { 1820 &do_write_string_out; 1821 } else { 1822 unless ($pid = fork) { 1823 &do_write_string_out; 1824 exit 0; 1825 }; 1826 waitpid($pid,0); 1827 } 1828 &open_dbm_database; 1829} 1830 1831sub do_write_string_out { 1832 local($_); 1833 close (SINPUT) if($CAN_FORK); 1834 &open_dbm_database; 1835 $_ = delete $string{'STRING'}; 1836 # locate blank-lines, for paragraphs. 1837 # Replace verbatim environments etc. 1838 &pre_process; 1839 # locate the blank lines for \par s 1840 &substitute_pars; 1841 # Handle newcommand, newenvironment, newcounter ... 1842 &substitute_meta_cmds; 1843 &wrap_shorthand_environments; 1844 print STDOUT "\n *** End-of-partition ***" if ($VERBOSITY > 1); 1845 if(open(OUT, ">$TMP_$dd$PARTITION_PREFIX$count")) { 1846 print OUT $_; 1847 close(OUT); 1848 } else { 1849 print "\nError: Cannot write '$TMP_$dd$PARTITION_PREFIX$count': $!\n"; 1850 } 1851 print STDOUT $_ if ($VERBOSITY > 9); 1852 $preamble = join("\n",$preamble,@preamble); # undef @preamble; 1853 &write_mydb_simple("preamble", $preamble); 1854 # this was done earlier; it should not be repeated 1855 #&write_mydb_simple("prelatex", $prelatex); 1856 &write_mydb_simple("aux_preamble", $aux_preamble); 1857 &close_dbm_database; 1858} 1859 1860# Reads the entire input file into a 1861# single string. 1862sub slurp_input { 1863 local($file) = @_; 1864 local(%string); 1865 if(open(INPUT,"<$file")) { 1866 local(@file_string); 1867 while (<INPUT>) { 1868 push(@file_string, $_ ); 1869 } 1870 $string{'STRING'} = join('',@file_string); 1871 close INPUT; 1872 undef @file_string; 1873 } else { 1874 print "\nError: Cannot read '$file': $!\n"; 1875 } 1876 $_ = delete $string{'STRING'}; # Blow it away and return the result 1877} 1878 1879# MRO: make them more efficient 1880sub special { 1881 $html_specials{$_[0]} || $_[0]; 1882} 1883 1884sub special_inv { 1885 $html_specials_inv{$_[0]} || $_[0]; 1886} 1887 1888sub special_html { 1889 $html_special_entities{$_[0]} || $_[0]; 1890} 1891 1892sub special_html_inv { 1893 $html_spec_entities_inv{$_[0]} || $_[0]; 1894} 1895 1896# Mark each matching opening and closing bracket with a unique id. 1897sub mark_string { 1898 # local (*_) = @_; # Modifies $_ in the caller; 1899 # -> MRO: changed to $_[0] (same effect) 1900 # MRO: removed deprecated $*, replaced by option /m 1901 $_[0] =~ s/(^|[^\\])\\\{/$1tex2html_escaped_opening_bracket/gom; 1902 $_[0] =~ s/(^|[^\\])\\\{/$1tex2html_escaped_opening_bracket/gom; # repeat this 1903 $_[0] =~ s/(^|[^\\])\\}/$1tex2html_escaped_closing_bracket/gom; 1904 $_[0] =~ s/(^|[^\\])\\}/$1tex2html_escaped_closing_bracket/gom; # repeat this 1905 my $id = $global{'max_id'}; 1906 my $prev_id = $id; 1907 # mark all balanced braces 1908 # MRO: This should in fact mark all of them as the hierarchy is 1909 # processed inside-out. 1910 1 while($_[0] =~ s/\{([^{}]*)}/join("",$O,++$id,$C,$1,$O,$id,$C)/geo); 1911 # What follows seems esoteric... 1912 my @processedB = (); 1913 # Take one opening brace at a time 1914 while ($_[0] =~ /\{/) { 1915 my ($before,$after) = ($`,$'); 1916 my $change = 0; 1917 while (@UNMATCHED_OPENING && $before =~ /\}/) { 1918 my $this = pop(@UNMATCHED_OPENING); 1919 print "\n *** matching brace \#$this found ***\n"; 1920 $before =~ s/\}/join("",$O,$this,$C)/eo; 1921 $change = 1; 1922 } 1923 $_[0] = join('',$before,"\{",$after) if($change); 1924 # MRO: mark one opening brace 1925 if($_[0] =~ s/^([^{]*)\{/push(@processedB,$1);join('',$O,++$id,$C)/eos) { 1926 $before=''; $after=$'; 1927 } 1928 if ($after =~ /\}/) { 1929 $after =~ s/\}/join("",$O,$id,$C)/eo; 1930 $_[0] = join('',$before,$O,$id,$C,$after); 1931 } else { 1932 print "\n *** opening brace \#$id is unmatched ***\n"; 1933 $after =~ /^(.+\n)(.+\n)?/; 1934 print " preceding: $after \n"; 1935 push (@UNMATCHED_OPENING,$id); 1936 } 1937 } 1938 $_[0] = join('',@processedB,$_[0]); undef(@processedB); 1939 print STDOUT "\nInfo: bracketings found: ", $id - $prev_id,"\n" 1940 if ($VERBOSITY > 1); 1941 # process remaining closing braces 1942 while (@UNMATCHED_OPENING && $_[0] =~ /\}/) { 1943 my $this = pop(@UNMATCHED_OPENING); 1944 print "\n *** matching brace \#$this found ***\n"; 1945 $_[0] =~ s/\}/join("",$O,$this,$C)/eo; 1946 } 1947 1948 while ($_[0] =~ /\}/) { 1949 print "\n *** there was an unmatched closing \} "; 1950 my ($beforeline,$prevline,$afterline) = ($`, $`.$& , $'); 1951 $prevline =~ /\n([^\n]+)\}$/m; 1952 if ($1) { 1953 print "at the end of:\n" . $1 . "\}\n\n"; 1954 } else { 1955 $afterline =~ /^([^\n]+)\n/m; 1956 if ($1) { 1957 print "at the start of:\n\}" . $1 ."\n\n"; 1958 } else { 1959 $prevline =~ /\n([^\n]+)\n\}$/m; 1960 print "on a line by itself after:\n" . $1 . "\n\}\n\n"; 1961 } 1962 } 1963 $_[0] = $beforeline . $afterline; 1964 } 1965 $global{'max_id'} = $id; 1966 1967 # restore escaped braces 1968 $_[0] =~ s/tex2html_escaped_opening_bracket/\\{/go; 1969 $_[0] =~ s/tex2html_escaped_closing_bracket/\\}/go; 1970} 1971 1972sub replace_html_special_chars { 1973 # Replaces html special characters with markers unless preceded by "\" 1974 s/([^\\])(<|>|&|\"|``|'')/&special($1).&special($2)/geom; 1975 # MUST DO IT AGAIN JUST IN CASE THERE ARE CONSECUTIVE HTML SPECIALS 1976 s/([^\\])(<|>|&|\"|``|'')/&special($1).&special($2)/geom; 1977 s/^(<|>|&|\"|``|'')/&special($1)/geom; 1978} 1979 1980# used in \verbatiminput only: $html_escape_chars = '<>&'; 1981sub replace_all_html_special_chars { s/([$html_escape_chars])/&special($1)/geom; } 1982 1983# The bibliography and the index should be treated as separate sections 1984# in their own HTML files. The \bibliography{} command acts as a sectioning command 1985# that has the desired effect. But when the bibliography is constructed 1986# manually using the thebibliography environment, or when using the 1987# theindex environment it is not possible to use the normal sectioning 1988# mechanism. This subroutine inserts a \bibliography{} or a dummy 1989# \textohtmlindex command just before the appropriate environments 1990# to force sectioning. 1991sub add_bbl_and_idx_dummy_commands { 1992 local($id) = $global{'max_id'}; 1993 1994 s/([\\]begin\s*$O\d+$C\s*thebibliography)/$bbl_cnt++; $1/eg; 1995 ## if ($bbl_cnt == 1) { 1996 s/([\\]begin\s*$O\d+$C\s*thebibliography)/$id++; "\\bibliography$O$id$C$O$id$C $1"/geo; 1997 #} 1998 $global{'max_id'} = $id; 1999 s/([\\]begin\s*$O\d+$C\s*theindex)/\\textohtmlindex $1/o; 2000 s/[\\]printindex/\\textohtmlindex /o; 2001 &lib_add_bbl_and_idx_dummy_commands() if defined(&lib_add_bbl_and_idx_dummy_commands); 2002} 2003 2004 2005# Uses and modifies $default_language 2006# This would be straight-forward except when there are 2007# \MakeUppercase, \MakeLowercase or \uppercase , \lowercase commands 2008# present in the source. The cases have to be adjusted before the 2009# ISO-character code is set; e.g. with "z --> "Z in german.perl 2010# 2011sub convert_iso_latin_chars { 2012 local($_) = @_; 2013 local($next_language, $pattern); 2014 local($xafter, $before, $after, $funct, $level, $delim); 2015 local(@case_processed); 2016 while (/$case_change_rx/) { 2017 $xafter = $2; 2018# $before .= $`; 2019 push(@case_processed, $`); 2020 $funct = $3; 2021 $after = ''; 2022 $_ = $'; 2023 if ($xafter =~ /noexpand/) { $before .= "\\$funct"; next; } 2024 2025 s/^[\s%]*(.)/$delim=$1;''/eo; 2026 if ($delim =~ /{/ ) { 2027 # brackets not yet numbered... 2028# $before .= $funct . $delim; 2029 push(@case_processed, $funct . $delim); 2030 $level = 1; 2031 $after = $delim; 2032 while (($level)&&($_)&&(/[\{\}]/)) { 2033 $after .= $` . $&; 2034 $_ = $'; 2035 if ( "$&" eq "\{" ) {$level++} 2036 elsif ( "$&" eq "\}" ) { $level-- } 2037 else { print $_ } 2038 print "$level"; 2039 } 2040# $before .= $after; 2041 push(@case_processed, $after); 2042 } elsif ($delim eq "<") { 2043 # brackets numbered, but maybe not processed... 2044 s/((<|#)(\d+)(>|#)>).*\1//; 2045 $after .= $delim . $&; 2046 $_ = $'; 2047 print STDOUT "\n<$2$funct$4>" if ($VERBOSITY > 2); 2048 $funct =~ s/^\\//o; 2049 local($cmd) = "do_cmd_$funct"; 2050 $after = &$cmd($after); 2051# $before .= $after; 2052 push(@case_processed, $after); 2053 } elsif (($xafter)&&($delim eq "\\")) { 2054 # preceded by \expandafter ... 2055 # ...so expand the following macro first 2056 $funct =~ s/^\\//o; 2057 local($case_change) = $funct; 2058 s/^(\w+|\W)/$funct=$1;''/eo; 2059 local($cmd) = $funct; 2060 local($thiscmd) = "do_cmd_$funct"; 2061 if (defined &$thiscmd) { $_ = &$thiscmd($_) } 2062 elsif ($new_command{$funct}) { 2063 local($argn, $body, $opt) = split(/:!:/, $new_command{$funct}); 2064 do { ### local($_) = $body; 2065 &make_unique($body); 2066 } if ($body =~ /$O/); 2067 if ($argn) { 2068 do { 2069 local($before) = ''; 2070 local($after) = "\\$funct ".$_; 2071 $after = &substitute_newcmd; # may change $after 2072 $after =~ s/\\\@#\@\@/\\/o ; 2073 } 2074 } else { $_ = $body . $_; } 2075 } else { print "\nUNKNOWN COMMAND: $cmd "; } 2076 2077 $cmd = $case_change; 2078 $case_change = "do_cmd_$cmd"; 2079 if (defined &$case_change) { $_ = &$case_change($_) } 2080 } else { 2081 # this should not happen, but just in case... 2082 $funct =~ s/^\\//o; 2083 local($cmd) = "do_cmd_$funct"; 2084 print STDOUT "\n\n<$delim$funct>" if ($VERBOSITY > 2); 2085 $_ = join('', $delim , $_ ); 2086 if (defined &$cmd) { $_ = &$cmd($_) } 2087 } 2088 } 2089# $_ = join('', $before, $_) if ($before); 2090 $_ = join('', @case_processed, $_) if (@case_processed); 2091 2092 # ...now do the conversions 2093 ($before, $after, $funct) = ('','',''); 2094 @case_processed = (); 2095 if (/$language_rx/o) { 2096 ($next_language, $pattern, $before, $after) = (($2||$1), $&, $`, $'); 2097 $before = &convert_iso_latin_chars($before) if ($before); 2098# push(@case_processed, $pattern, $before); 2099 local($br_id) = ++$global{'max_id'}; 2100 $pattern = join('' , '\selectlanguage', $O.$br_id.$C 2101 , (($pattern =~ /original/) ? $TITLES_LANGUAGE : $next_language ) 2102 , $O.$br_id.$C ); 2103 push(@case_processed, $before, $pattern); 2104 push(@language_stack, $default_language); 2105 $default_language = $next_language; 2106 $_ = &convert_iso_latin_chars($after); 2107 $default_language = pop @language_stack; 2108 } else { 2109 $funct = $language_translations{$default_language}; 2110 (defined(&$funct) ? $_ = &$funct($_) : 2111 do { &write_warnings( 2112 "\nCould not find translation function for $default_language.\n\n") 2113 } 2114 ); 2115 if ($USE_UTF ||(!$NO_UTF &&(%unicode_table)&&length(%unicode_table)>2)) { 2116 &convert_to_unicode($_)}; 2117 } 2118 $_ = join('', @case_processed, $_); undef(@case_processed); 2119 $_; 2120} 2121 2122# May need to add something here later 2123sub english_translation { $_[0] } 2124 2125# This replaces \setlanguage{\language} with \languageTeX 2126# This makes the identification of language chunks easier. 2127sub normalize_language_changes { 2128 s/$setlanguage_rx/\\$2TeX/gs; 2129} 2130 2131sub get_current_language { 2132 return () if ($default_language eq $TITLES_LANGUAGE); 2133 local($lang,$lstyle) = ' LANG="'; 2134 $lang_code = $iso_languages{$default_language}; 2135 if (%styled_languages) { 2136 $lstyle = $styled_languages{$default_language}; 2137 $lstyle = '" CLASS="'.$lstyle if $lstyle; 2138 } 2139 ($lang_code ? $lang.$lang_code.$lstyle.'"' : ''); 2140} 2141 2142%styled_languages = (); 2143 2144sub do_cmd_htmllanguagestyle { 2145 local($_) = @_; 2146 local($class) = &get_next_optional_argument; 2147 local($lang) = &missing_braces unless ( 2148 (s/$next_pair_pr_rx/$lang=$2;''/e) 2149 ||(s/$next_pair_rx/$lang=$2;''/e)); 2150 return ($_) unless $lang; 2151 local($class) = $iso_languages{$lang} unless $class; 2152 if ($USING_STYLES && $class) { 2153 print "\nStyling language: $lang = \"$class\" "; 2154 $styled_languages{"$lang"} = $class; 2155 } 2156 $_; 2157} 2158 2159# General translation mechanism: 2160# 2161# 2162# The main program latex2html calls texexpand with the document name 2163# in order to expand some of its \input and \include statements, here 2164# also called 'merging', and to write a list of sensitized style, class, 2165# input, or include file names. 2166# When texexpand has finished, all is contained in one file, TMP_foo. 2167# (assumed foo.tex is the name of the document to translate). 2168# 2169# In this version, texexpand cares for following environments 2170# that may span include files / section boundaries: 2171# (For a more technical description, see texexpand.) 2172# a) \begin{comment} 2173# b) %begin{comment} 2174# c) \begin{any} introduced with \excludecomment 2175# d) %begin{any} 2176# e) \begin{verbatim} 2177# f) \begin{latexonly} 2178# g) %begin{latexonly} 2179# 2180# a)-d) cause texexpand to drop its contents, it will not show up in the 2181# output file. You can use this to 'comment out' a bunch of files, say. 2182# 2183# e)-g) prevent texexpand from expanding input files, but the environment 2184# content goes fully into the output file. 2185# 2186# Together with each merging of \input etc. there are so-called %%%texexpand 2187# markers accompanying the boundary. 2188# 2189# When latex2html reads in the output file, it uses these markers to write 2190# each part to a separate file, and process them further. 2191# 2192# 2193# If you have, for example: 2194# 2195# a) preample 2196# b) \begin{document} 2197# c) text 2198# d) \input{chapter} 2199# e) more text 2200# f) \end{document} 2201# 2202# you end up in two parts, part 1 is a)-c), part 2 is the rest. 2203# Regardless of environments spanning input files or sections. 2204# 2205# 2206# What now starts is meta command substitution: 2207# Therefore, latex2html forks a child process on the first part and waits 2208# until it finished, then forks another on the next part and so forth 2209# (see also &slurp_input_and_partition_and_preprocess). 2210# 2211# Here's what each child is doing: 2212# Each child process reads the new commands translated so far by the previous 2213# child from the TMP_global DBM database. 2214# After &pre_processing, it substitutes the meta commands (\newcommand, \def, 2215# and the like) it finds, and adds the freshly retrieved new commands to the 2216# list so far. 2217# This is done *only on its part* of the document; this saves upwards of memory. 2218# Finally, it writes its list of new commands (synopsis and bodies) to the 2219# DBM database, and exits. 2220# After the last child finished, latex2html reads in all parts and 2221# concatenates them. 2222# 2223# 2224# So, at this point in time (start of &translate), it again has the complete 2225# document, but now preprocessed and with new commands substituted. 2226# This has several disadvantages: an amount of commands is substituted (in 2227# TeX lingo, expanded) earlier than the rest. 2228# This causes trouble if commands really must get expanded at the point 2229# in time they show up. 2230# 2231# 2232# Then, still in &translate, latex2html uses the list of section commands to 2233# split the complete document into chunks. 2234# The chunks are not written to files yet. They are retained in the @sections 2235# list, but each chunk is handled separately. 2236# latex2html puts the current chunk to $_ and processes it with 2237# &translate_environments etc., then fetches the next chunk, and so on. 2238# This prevents environments that span section boundaries from getting 2239# translated, because \begin and \end cannot find one another, to say it this 2240# way. 2241# 2242# 2243# After the chunk is translated to HTML, it is written to a file. 2244# When all chunks are done, latex2html rereads each file to get cross 2245# references right, replace image markers with the image file names, and 2246# writes index and bibliography. 2247# 2248# 2249sub translate { 2250 &normalize_sections; # Deal with the *-form of sectioning commands 2251 2252 # Split the input into sections, keeping the preamble together 2253 # Due to the regular expression, each split will create 5 more entries. 2254 # Entry 1 and 2: non-letter/letter sectioning command, 2255 # entry 4: the delimiter (may be empty) 2256 # entry 5: the text. 2257 local($pre_section, @sections); 2258 if (/\\(startdocument|begin\s*($O\d+$C)\s*document\s*\2)/) { 2259 $pre_section = $`.$&; $_ = $'; 2260 } 2261 @sections = split(/$sections_rx/, $_); 2262 $sections[0] = $pre_section.$sections[0] if ($pre_section); 2263 undef $pre_section; 2264 local($sections) = int(scalar(@sections) / 5); 2265 2266 # Initialises $curr_sec_id to a list of 0's equal to 2267 # the number of sectioning commands. 2268 local(@curr_sec_id) = split(' ', &make_first_key); 2269 local(@segment_sec_id) = @curr_sec_id; 2270 local($i, $j, $current_depth) = (0,0,0); 2271 local($curr_sec) = $SHORT_FILENAME||$FILE; 2272 local($top_sec) = ($SEGMENT ? '' : 'top of '); 2273# local(%section_info, %toc_section_info, $CURRENT_FILE, %cite_info, %ref_files); 2274 local($CURRENT_FILE); 2275 # These filenames may be set when translating the corresponding commands. 2276 local($tocfile, $loffile, $lotfile, $footfile, $citefile, $idxfile, 2277 $figure_captions, $table_captions, $footnotes, $citations, %font_size, %index, 2278 %done, $t_title, $t_author, $t_date, $t_address, $t_affil, $changed); 2279 local(@authors,@affils,@addresses,@emails,@authorURLs); 2280 local(%index_labels, %index_segment, $preindex, %footnotes, %citefiles); 2281 local($segment_table_captions, $segment_figure_captions); 2282 local($dir,$nosave) = ('',''); 2283 local($del,$close_all,$open_all,$toc_sec_title,$multiple_toc); 2284 local($open_tags_R) = []; 2285 local(@save_open_tags)= (); 2286 local(@language_stack) = (); 2287 push (@language_stack, $default_language); 2288 2289# $LATEX_FONT_SIZE = '10pt' unless ($LATEX_FONT_SIZE); 2290 &process_aux_file 2291 if $SHOW_SECTION_NUMBERS || /\\(caption|(html|hyper)?((eq)?ref|cite))/; 2292 2293 require ("${PREFIX}internals.pl") if (-f "${PREFIX}internals.pl"); 2294#JCL(jcl-del) 2295 &make_single_cmd_rx; 2296# 2297 $tocfile = $EXTERNAL_CONTENTS; 2298 $idxfile = $EXTERNAL_INDEX; 2299 $citefile = $EXTERNAL_BIBLIO; $citefile =~ s/#.*$//; 2300 $citefiles{1} = $citefile if ($citefile); 2301 print "\nTranslating ..."; 2302 2303 while ($i <= @sections) { 2304 undef $_; 2305 $_ = $sections[$i]; 2306 s/^[\s]*//; # Remove initial blank lines 2307 2308 # The section command was removed when splitting ... 2309 s/^/\\$curr_sec$del/ if ($i > 0); # ... so put it back 2310 if ($current_depth < $MAX_SPLIT_DEPTH) { 2311 if (($footnotes)&&($NO_FOOTNODE)&&( $current_depth < $MAX_SPLIT_DEPTH)) { 2312 local($thesenotes) = &make_footnotes ; 2313 print OUTPUT $thesenotes; 2314 } 2315 $CURRENT_FILE = &make_name($curr_sec, join('_',@curr_sec_id)); 2316 2317 open(OUTPUT, ">$CURRENT_FILE") 2318 || die "Cannot write '$CURRENT_FILE': $!\n"; 2319 if ($XBIT_HACK) { # use Apache's XBit hack 2320 chmod 0744, $CURRENT_FILE; 2321 &check_htaccess; 2322 } else { 2323 chmod 0644, $CURRENT_FILE; 2324 } 2325 2326 if ($MULTIPLE_FILES && $ROOTED) { 2327 if ($DESTDIR =~ /^\Q$FIXEDDIR\E[$dd$dd]?([^$dd$dd]+)/) 2328 { $CURRENT_FILE = "$1$dd$CURRENT_FILE" }; 2329 } 2330 } 2331 &remove_document_env; 2332# &wrap_shorthand_environments; #RRM Is this needed ? 2333 print STDOUT "\n" if ($VERBOSITY); 2334 print STDOUT "\n" if ($VERBOSITY > 2); 2335 print $i/5,"/$sections"; 2336 print ":$top_sec$curr_sec:" if ($VERBOSITY); 2337 2338 # Must do this early ... It also sets $TITLE 2339 &process_command($sections_rx, $_) if (/^$sections_rx/); 2340 # reset tags saved from the previous section 2341 $open_tags_R = [ @save_open_tags ]; 2342 @save_open_tags = (); 2343 2344 local($curr_sec_tex); 2345 if ((! $TITLE) || ($TITLE eq $default_title)) { 2346 eval '$TITLE = '.$default_title; 2347 $TITLE = $default_title if $@; 2348 $curr_sec_tex = ($top_sec ? '' : 2349 join('', '"', &revert_to_raw_tex($curr_sec), '"')); 2350 print STDOUT "$curr_sec_tex for $CURRENT_FILE\n" if ($VERBOSITY); 2351 } else { 2352 local($tmp) = &purify($TITLE,1); 2353 $tmp = &revert_to_raw_tex($tmp); 2354 print STDOUT "\"$tmp\" for $CURRENT_FILE\n" if ($VERBOSITY); 2355 } 2356 2357 if (/\\(latextohtmlditchpreceding|startdocument)/m) { 2358 local($after) = $'; 2359 local($before) = $`.$&; 2360 $SEGMENT = 1 if ($1 =~ /startdocument/); 2361 print STDOUT "\n *** translating preamble ***\n" if ($VERBOSITY); 2362 $_ = &translate_preamble($before); 2363 s/\n\n//g; s/<BR>//g; # remove redundant blank lines and breaks 2364# 2365# &process_aux_file if $AUX_FILE_NEEDED; 2366# 2367 print STDOUT "\n *** preamble done ***\n" if ($VERBOSITY); 2368 $PREAMBLE = 0; 2369 $NESTING_LEVEL=0; 2370 &do_AtBeginDocument; 2371 $after =~ s/^\s*//m; 2372 print STDOUT (($VERBOSITY >2)? "\n*** Translating environments ***" : ";"); 2373 $after = &translate_environments($after); 2374 print STDOUT (($VERBOSITY >2)? "\n*** Translating commands ***" : ";"); 2375 $_ .= &translate_commands($after); 2376# $_ = &translate_commands($after); 2377 } else { 2378 &do_AtBeginDocument; 2379 $PREAMBLE = 0; 2380 $NESTING_LEVEL=0; 2381 print STDOUT (($VERBOSITY >2)? "\n*** Translating environments ***" : ";"); 2382 $_ = &translate_environments($_); 2383 print STDOUT (($VERBOSITY >2)? "\n*** Translating commands ***" : ";"); 2384 $_ = &translate_commands($_); 2385 } 2386 2387 # close any tags that remain open 2388 if (@$open_tags_R) { 2389 ($close_all,$open_all) = &preserve_open_tags(); 2390 $_ .= $close_all; 2391 @save_open_tags = @$open_tags_R; $open_tags_R = []; 2392 } else { ($close_all,$open_all) = ('','') } 2393 2394 print STDOUT (($VERBOSITY >2)? "\n*** Translations done ***" : "\n"); 2395# if (($footnotes)&&($NO_FOOTNODE)&&( $current_depth < $MAX_SPLIT_DEPTH)) { 2396# $_ .= &make_footnotes 2397# } 2398 print OUTPUT $_; 2399 2400 # Associate each id with the depth, the filename and the title 2401 ###MEH -- starred sections don't show up in TOC ... 2402 # RRM: ...unless $TOC_STARS is set 2403# $toc_sec_title = &simplify($toc_sec_title); 2404 $toc_sec_title = &purify($toc_sec_title);# if $SEGMENT; 2405 $toc_sec_title = &purify($TITLE) unless ($toc_sec_title); 2406 2407 if ($TOC_STARS) { 2408 $toc_section_info{join(' ',@curr_sec_id)} = 2409 "$current_depth$delim$CURRENT_FILE$delim$toc_sec_title" 2410# if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 2411 if ($current_depth <= $TOC_DEPTH); 2412 } else { 2413 $toc_section_info{join(' ',@curr_sec_id)} = 2414 "$current_depth$delim$CURRENT_FILE$delim$toc_sec_title" 2415 . ($curr_sec =~ /star$/ ? "$delim<tex2html_star_mark>" : "") 2416# if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 2417 if ($current_depth <= $TOC_DEPTH); 2418 } 2419 2420 # include $BODYTEXT in the section_info, when starting a new page 2421 $section_info{join(' ',@curr_sec_id)} = 2422 "$current_depth$delim$CURRENT_FILE$delim$TITLE$delim" 2423 . (($current_depth < $MAX_SPLIT_DEPTH)? $BODYTEXT: ""); 2424 2425 # Get type of section (see also the split above) 2426 $curr_sec = $sections[$i+1].$sections[$i+2]; 2427 $del = $sections[$i+4]; 2428 2429 # Get the depth of the current section; 2430# $curr_sec = $outermost_level unless $curr_sec; 2431 $current_depth = $section_commands{$curr_sec}; 2432 if ($after_segment) { 2433 $current_depth = $after_segment; 2434 $curr_sec_id[$after_segment] += $after_seg_num; 2435 ($after_segment,$after_seg_num) = ('',''); 2436 for($j=1+$current_depth; $j <= $#curr_sec_id; $j++) { 2437 $curr_sec_id[$j] = 0; 2438 } 2439 } 2440 if ($SEGMENT||$SEGMENTED) { 2441 for($j=1; $j <= $#curr_sec_id; $j++) { 2442 $curr_sec_id[$j] += $segment_sec_id[$j]; 2443 $segment_sec_id[$j] = 0; 2444 } 2445 }; 2446 2447 2448 # this may alter the section-keys 2449 $multiple_toc = 1 if ($MULTIPLE_FILES && $ROOTED && (/$toc_mark/)); 2450 2451 2452 #RRM : Should this be done here, or in \stepcounter ? 2453 @curr_sec_id = &new_level($current_depth, @curr_sec_id); 2454 2455 $toc_sec_title = $TITLE = $top_sec = ''; 2456 $i+=5; #skip to next text section 2457 } 2458 $open_tags_R = []; 2459 $open_all = ''; 2460 2461 $_ = undef; 2462 $_ = &make_footnotes if ($footnotes); 2463 $CURRENT_FILE = ''; 2464 print OUTPUT; 2465 close OUTPUT; 2466 2467 2468# # this may alter the section-keys 2469# &adjust_root_keys if $multiple_toc; 2470 2471 if ($PREPROCESS_IMAGES) { &preprocess_images } 2472 else { &make_image_file } 2473 print STDOUT "\n *** making images ***" if ($VERBOSITY > 1); 2474 &make_images; 2475 2476 # Link sections, add head/body/address do cross-refs etc 2477 print STDOUT "\n *** post-process ***" if ($VERBOSITY > 1); 2478 &post_process; 2479 2480 if (defined &document_post_post_process) { 2481 #BRM: extra document-wide post-processing 2482 print STDOUT "\n *** post-processing Document ***" if ($VERBOSITY > 1); 2483 &document_post_post_process(); 2484 } 2485 2486 print STDOUT "\n *** post-processed ***" if ($VERBOSITY > 1); 2487 ©_icons if $LOCAL_ICONS; 2488 if ($SEGMENT || $DEBUG || $SEGMENTED) { 2489 &save_captions_in_file("figure", $figure_captions) if $figure_captions; 2490 &save_captions_in_file("table", $table_captions) if $table_captions; 2491# &save_array_in_file ("captions", "figure_captions", 0, %figure_captions) if %figure_captions; 2492# &save_array_in_file ("captions", "table_captions", 0, %table_captions) if %table_captions; 2493 &save_array_in_file ("index", "index", 0, %index); 2494 &save_array_in_file ("sections", "section_info", 0, %section_info); 2495 &save_array_in_file ("contents", "toc_section_info", 0,%toc_section_info); 2496 &save_array_in_file ("index", "sub_index", 1, %sub_index) if %sub_index; 2497 &save_array_in_file ("index", "index_labels", 1, %index_labels) if %index_labels; 2498 &save_array_in_file ("index", "index_segment", 1, %index_segment) if %index_segment; 2499 &save_array_in_file ("index", "printable_key", 1, %printable_key) 2500 if (%printable_key || %index_segment); 2501 } 2502 elsif ($MULTIPLE_FILES && $ROOTED) { 2503 &save_array_in_file ("sections", "section_info", 0, %section_info); 2504 &save_array_in_file ("contents", "toc_section_info", 0, %toc_section_info); 2505 } 2506 &save_array_in_file ("internals", "ref_files", 0, %ref_files) if $changed; 2507 &save_array_in_file ("labels", "external_labels", 0, %ref_files); 2508 &save_array_in_file ("labels", "external_latex_labels", 1, %latex_labels); 2509 &save_array_in_file ("images", "cached_env_img", 0, %cached_env_img); 2510} 2511 2512# RRM: 2513sub translate_preamble { 2514 local($_) = @_; 2515 $PREAMBLE = 1; 2516 $NESTING_LEVEL=0; #counter for TeX group nesting level 2517 # remove some artificially inserted constructions 2518 s/\n${tex2html_deferred_rx}\\par\s*${tex2html_deferred_rx2}\n/\n/gm; 2519 s/\\newedcommand(<<\d+>>)([A-Za-z]+|[^A-Za-z])\1(\[\d+\])?(\[[^]]*\])?(<<\d+>>)[\w\W\n]*\5($comment_mark\d*)?//gm; 2520 s/\n{2,}/\n/ogm; 2521 2522 if (/\\htmlhead/) { 2523 print STDOUT "\nPREAMBLE: discarding...\n$`" if ($VERBOSITY > 4); 2524 local($after) = $&.$'; 2525 # translate segment preamble preceding \htmlhead 2526 &translate_commands(&translate_environments($`)); 2527 # translate \htmlhead and rest of preamble 2528 $_=&translate_commands(&translate_environments($after)); 2529 print STDOUT "\nPREAMBLE: retaining...\n$_" if ($VERBOSITY > 4); 2530 } else { 2531 # translate only preamble here (metacommands etc.) 2532 # there should be no textual results, if so, discard them 2533 &translate_commands(&translate_environments($_)); 2534 print STDOUT "\nPREAMBLE: discarding...\n$_" if ($VERBOSITY > 4); 2535 $_=""; 2536 }; 2537 $_ = &do_AtBeginDocument($_); 2538 if (! $SEGMENT) { $_ = ''} # segmented documents have a heading already 2539 $_; 2540} 2541 2542############################ Processing Environments ########################## 2543 2544sub wrap_shorthand_environments { 2545 # This wraps a dummy environment around environments that do not use 2546 # the begin-end convention. The wrapper will force them to be 2547 # evaluated by Latex rather than them being translated. 2548 # Wrap a dummy environment around matching TMPs. 2549 # s/^\$\$|([^\\])\$\$/{$1.&next_wrapper('tex2html_double_dollar')}/ge; 2550 # Wrap a dummy environment around matching $s. 2551 # s/^\$|([^\\])\$/{$1.&next_wrapper('$')}/ge; 2552 # s/tex2html_double_dollar/\$\$/go; 2553 # Do \(s and \[s 2554 # 2555 local($wrapper) = "tex2html_wrap_inline"; # \ensuremath wrapper 2556 print STDOUT "\n *** wrapping environments ***\n" if ($VERBOSITY > 3); 2557 2558 # MRO: replaced $* with /m 2559 print STDOUT "\\(" if ($VERBOSITY > 3); 2560 s/(^\\[(])|([^\\])(\\[(])/{$2.&make_any_wrapper(1,'',$wrapper).$1.$3}/geom; 2561 print STDOUT "\\)" if ($VERBOSITY > 3); 2562 s/(^\\[)]|[^\\]\\[)])/{$1.&make_any_wrapper(0,'',$wrapper)}/geom; 2563 2564 print STDOUT "\\[" if ($VERBOSITY > 3); 2565 s/(^\\[[])|([^\\])(\\[[])/{$2.&make_any_wrapper(1,1,"displaymath")}/geom; 2566 print STDOUT "\\]" if ($VERBOSITY > 3); 2567 s/(^\\[\]])|([^\\])(\\[\]])/{$2.&make_any_wrapper(0,1,"displaymath")}/geom; 2568 2569 print STDOUT "\$" if ($VERBOSITY > 3); 2570 s/$enspair/print "\$"; 2571 {&make_any_wrapper(1,'',$wrapper).$&.&make_any_wrapper(0,'',$wrapper)}/geom; 2572 2573 $double_dol_rx = '(^|[^\\\\])\\$\\$'; 2574 $single_dol_rx = '(^|[^\\\\])\\$'; 2575 print STDOUT "\$" if ($VERBOSITY > 3); 2576 2577 local($dollars_remain) = 0; 2578 $_ = &wrap_math_environment; 2579 $_ = &wrap_raw_arg_cmds; 2580} 2581 2582sub wrap_math_environment { 2583 2584 # This wraps math-type environments 2585 # The trick here is that the opening brace is the same as the close, 2586 # but they *can* still nest, in cases like this: 2587 # 2588 # $ outer stuff ... \hbox{ ... $ inner stuff $ ... } ... $ 2589 # 2590 # Note that the inner pair of $'s is nested within a group. So, to 2591 # handle these cases correctly, we need to make sure that the outer 2592 # brace-level is the same as the inner. --- rst 2593 #tex2html_wrap 2594 # And yet another problem: there is a scungy local idiom to do 2595 # this: $\_$ for a boldfaced underscore. xmosaic can't display the 2596 # resulting itty-bitty bitmap, for some reason; even if it could, it 2597 # would probably come out as an overbar because of the floating- 2598 # baseline problem. So, we have to special case this. --- rst again. 2599 2600 local ($processed_text, @processed_text, $before, $end_rx, $delim, $ifclosed); 2601 local ($underscore_match_rx) = "^\\s*\\\\\\_\\s*\\\$"; 2602 local ($wrapper); 2603 print STDOUT "\nwrap math:" if ($VERBOSITY > 3); 2604 2605 #find braced dollars, in tabular-specs 2606 while (/((($O|$OP)\d+($C|$CP))\s*)\$(\s*\2)/) { 2607 push (@processed_text, $`, $1.$dol_mark.$5); 2608 $_ = $'; 2609 } 2610 $_ = join('',@processed_text, $_) if (@processed_text); 2611 undef @processed_text; 2612 2613 $dollars_remain = 0; 2614 while (/$single_dol_rx/) { 2615 $processed_text .= $`.$1; 2616 $_ = $'; 2617 $wrapper = "tex2html_wrap_inline"; 2618 $end_rx = $single_dol_rx; # Default, unless we begin with $$. 2619 $delim = "\$"; 2620 2621 if (/^\$/ && (! $`)) { 2622 s/^\$//; 2623 $end_rx = $double_dol_rx; 2624 $delim = ""; # Cannot say "\$\$" inside displaymath 2625 $wrapper = "displaymath"; 2626 2627 } elsif (/$underscore_match_rx/ && (! $`)) { 2628 2629 # Special case for $\_$ ... 2630 2631 s/$underscore_match_rx//; 2632 $processed_text .= '\\_'; 2633 next; 2634 } 2635 2636 # Have an opening $ or $$. Find matching close, at same bracket level 2637# $processed_text .= &make_any_wrapper(1,'',$wrapper).$delim; 2638 2639 print STDOUT "\$" if ($VERBOSITY > 3); 2640 $ifclosed = 0; 2641 local($thismath); 2642 while (/$end_rx/) { 2643 # Forget the $$ if we are going to replace it with "displaymath" 2644 $before = $` . (($wrapper eq "displaymath")? "$1" : $&); 2645 last if ($before =~ /\\(sub)*(item|section|chapter|part|paragraph)(star)?\b/); 2646 $thismath .= $before; 2647 $_ = $'; 2648 s/^( [^\n])/\\space$1/s; #make sure a trailing space doesn't get lost. 2649 2650 # Found dollar sign inside open subgroup ... now see if it's 2651 # at the same brace-level ... 2652 2653 local ($losing, $br_rx) = (0, ''); 2654 print STDOUT "\$" if ($VERBOSITY > 3); 2655 while ($before =~ /$begin_cmd_rx/) { 2656 $br_rx = &make_end_cmd_rx($1); $before = $'; 2657 2658 if ($before =~ /$br_rx/) { $before = $'; } 2659 else { $losing = 1; last; } 2660 } 2661 do { $ifclosed = 1; last } unless $losing; 2662 2663 # It wasn't ... find the matching close brace farther on; then 2664 # keep going. 2665 2666 /$br_rx/; 2667 2668 $thismath .= $`.$&; 2669 2670 #RRM: may now contain unprocessed $s e.g. $\mbox{...$...$...}$ 2671 # the &do_cmd_mbox uses this specially to force an image 2672 # ...but there may be other situations; e.g. \hbox 2673 # so set a flag: 2674 $dollars_remain = 1; 2675 2676 $_ = $'; 2677 } 2678 2679 # Got to the end. Whew! 2680 if ($ifclosed) { 2681 # also process any nested math 2682 while (($dollars_remain)&&($delim eq "\$")) { 2683 local($saved) = $_; 2684 $thismath =~ s/\$$//; 2685 $_ = $thismath; 2686 $thismath = &wrap_math_environment; 2687 $thismath .= "\$"; 2688 $_ = $saved; 2689 } 2690 $processed_text .= &make_any_wrapper(1,'',$wrapper) . $delim 2691 . $thismath . &make_any_wrapper(0,'',$wrapper); 2692 } else { 2693 print STDERR "\n\n *** Error: unclosed math or extra `\$', before:\n$thismath\n\n"; 2694# # remove a $ to try to recover as much as possible. 2695# $thismath =~ s/([^\\]\\\\|[^\\])\$/$1\%\%/; 2696# $_ = $thismath . $_; $thismath = ""; 2697 print "\n$thismath\n\n\n$_\n\n\n"; die; 2698 2699 } 2700 } 2701 $processed_text . $_; 2702} 2703 2704sub translate_environments { 2705 local ($_) = @_; 2706 local($tmp, $capenv); 2707# print "\nTranslating environments ..."; 2708 local($after, @processedE); 2709 local ($contents, $before, $br_id, $env, $pattern); 2710 for (;;) { 2711# last unless (/$begin_env_rx/o); 2712 last unless (/$begin_env_rx|$begin_cmd_rx|\\(selectlanguage)/o); 2713# local ($contents, $before, $br_id, $env, $pattern); 2714 local($this_env, $opt_arg, $style_info); 2715 $contents = ''; 2716 # $1,$2 : optional argument/text --- stylesheet info 2717 # $3 : br_id (at the beginning of an environment name) 2718 # $4 : environment name 2719 # $5 : br_id of open-brace, when $3 == $4 == ''; 2720 # $6 : \selectlanguage{...} 2721 if ($7) { 2722 push(@processedE,$`); 2723 $_ = $'; 2724 if (defined &do_cmd_selectlanguage) { 2725 $_ = &do_cmd_selectlanguage($_); 2726 } else { 2727 local($cmd) = $7; 2728 $pattern = &missing_braces unless ( 2729 s/$next_pair_rx/$pattern = $2;''/e); 2730 local($trans) = $pattern.'_translation'; 2731 if (defined &$trans) { 2732 &set_default_language($pattern,$_); 2733 } 2734 undef $cmd; undef $trans; 2735 } 2736 next; 2737 } elsif ($4) { 2738 ($before, $opt_arg, $style_info, $br_id 2739 , $env, $after, $pattern) = ($`, $2, $3, $4, $5, $', $&); 2740 if (($before)&& (!($before =~ /$begin_env_rx|$begin_cmd_rx/))) { 2741 push(@processedE,$before); 2742 $_ = $pattern . $after; $before = ''; 2743 } 2744 } else { 2745 ($before, $br_id, $env, $after, $pattern) = ($`, $6, 'group', $', $&); 2746 if (($before)&& (!($before =~ /$begin_env_rx|$begin_cmd_rx/))) { 2747 push(@processedE,$before); 2748 $_ = $pattern . $after; $before = ''; 2749 } 2750 local($end_cmd_rx) = &make_end_cmd_rx($br_id); 2751 if ($after =~ /$end_cmd_rx/) { 2752 # ... find the the matching closing one 2753 $NESTING_LEVEL++; 2754 ($contents, $after) = ($`, $'); 2755 $contents = &process_group_env($contents); 2756 print STDOUT "\nOUT: {$br_id} ".length($contents) if ($VERBOSITY > 3); 2757 print STDOUT "\n:$contents\n" if ($VERBOSITY > 7); 2758 # THIS MARKS THE OPEN-CLOSE DELIMITERS AS PROCESSED 2759 $_ = join("", $before,"$OP$br_id$CP", $contents,"$OP$br_id$CP", $after); 2760 $NESTING_LEVEL--; 2761 } else { 2762 $pattern = &escape_rx_chars($pattern); 2763 s/$pattern//; 2764 print "\nCannot find matching bracket for $br_id"; 2765 $_ = join("", $before,"$OP$br_id$CP", $after); 2766 } 2767 next; 2768 } 2769 $contents = undef; 2770 local($defenv) = $env =~ /deferred/; 2771# local($color_env); 2772 local($color_env) 2773 unless ($env =~ /tabular|longtable|in(line|display)|math/); 2774 local($closures,$reopens); 2775 local(@save_open_tags) = @$open_tags_R unless ($defenv); 2776 local($open_tags_R) = [ @save_open_tags ] unless ($defenv); 2777 local(@saved_tags) if ($env =~ /tabular|longtable/); 2778 if ($env =~ /tabular|longtable|makeimage|in(line|display)/) { 2779 @save_open_tags = @$open_tags_R; 2780 $open_tags_R = [ @save_open_tags ]; 2781 # check for color 2782 local($color_test) = join(',',@$open_tags_R); 2783 if ($color_test =~ /(color\{[^}]*})/g ) { 2784 $color_env = $1; 2785 } # else { $color_env = '' } 2786 2787 if ($env =~ /tabular|longtable|makeimage/) { 2788 # close to the surrounding block-type tag 2789 ($closures,$reopens,@saved_tags) = &preserve_open_block_tags(); 2790 @save_open_tags = @$open_tags_R; 2791 $open_tags_R = [ @save_open_tags ]; 2792 if ($color_env) { 2793 $color_test = join(',',@saved_tags); 2794 if ($color_test =~ /(color\{[^}]*})/g ) { 2795 $color_env = $1; 2796 } 2797 } 2798 } elsif ($env =~ /in(line|display)/) { 2799 $closures = &close_all_tags() if ((&defined_env($env)) 2800 &&!($defenv)&&!($env=~/inline/)&&(!$declarations{$env})); 2801 if ($color_env) { 2802 $color_test = $declarations{$color_env}; 2803 $color_test =~ s/<\/.*$//; 2804 $closures .= "\n$color_test"; 2805 push (@$open_tags_R , $color_env); 2806 } 2807 } 2808 } elsif ($env =~ /alltt|tex2html_wrap/) { 2809 # alltt is constructed as paragraphs, not with <PRE> 2810 # tex2html_wrap creates an image, which is at text-level 2811 } else { 2812 $closures = &close_all_tags() if ((&defined_env($env)) 2813 &&!($defenv)&&(!$declarations{$env}) ); 2814 } 2815 # Sets $contents and modifies $after 2816 if (&find_end_env($env,$contents,$after)) { 2817 print STDOUT "\nIN-A {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2818 &process_command($counters_rx, $before) 2819 if ($before =~ /$counters_rx/); 2820 # This may modify $before and $after 2821 # Modifies $contents 2822#RRM: the do_env_... subroutines handle when to translate sub-environments 2823# $contents = &translate_environments($contents) if 2824## ((!$defenv) && (&defined_env($env)) && (! $raw_arg_cmds{$env}) 2825## && (!$declarations{$env}) 2826# ((&defined_env($env)) && (! $raw_arg_cmds{$env}) 2827# && (!($env =~ /latexonly|enumerate|figure|table|makeimage|wrap_inline/)) 2828# && ((! $NO_SIMPLE_MATH)||(!($env =~ /wrap/))) 2829# && (!($env =~ /(math|wrap|equation|eqnarray|makeimage|minipage|tabular)/) ) 2830# ); 2831 if ($opt_arg) { 2832 &process_environment(1, $env, $br_id, $style_info); # alters $contents 2833 } else { 2834 &process_environment(0, $env, $br_id, ''); 2835 } 2836 undef $_; 2837 print STDOUT "\nOUT-A {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2838 #JCL(jcl-env) - insert the $O$br_id$C stuff to handle environment grouping 2839 if (!($contents eq '')) { 2840 $after =~ s/^\n//o if ($defenv); 2841 $this_env = join("", $before, $closures 2842 , $contents 2843 , ($defenv ? '': &balance_tags()) 2844 , $reopens ); $_ = $after; 2845 } else { 2846 $this_env = join("", $before , $closures 2847 , ($defenv ? '': &balance_tags()) 2848 , $reopens ); $_ = $after; 2849 }; 2850 ### Evan Welsh <welsh@epcc.ed.ac.uk> added the next 24 lines ## 2851 } elsif (&defined_env($env)) { 2852 print STDOUT "\nIN-B {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2853 # If I specify a function for the environment then it 2854 # calls it with the contents truncated at the next section. 2855 # It assumes I know what I'm doing and doesn't give a 2856 # deferred warning. 2857 $contents = $after; 2858 if ($opt_arg) { 2859 $contents = &process_environment(1, $env, $br_id, $style_info); 2860 } else { 2861 $contents = &process_environment(0, $env, $br_id, ''); 2862 } 2863 print STDOUT "\nOUT-B {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2864 $this_env = join("", $before, $closures ,$contents, $reopens); 2865 2866 # there should not be anything left over 2867# $_ = $after; 2868 $_ = ''; 2869 } elsif ($ignore{$env}) { 2870 print STDOUT "\nIGNORED {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2871 # If I specify that the environment should be ignored then 2872 # it is but I get a deferred warning. 2873 $this_env = join("", $before , $closures , &balance_tags() 2874 , $contents, $reopens ); 2875 $_ = $after; 2876 &write_warnings("\n\\end{$env} not found (ignored).\n"); 2877 } elsif ($raw_arg_cmds{$env}) { 2878 print "\nIN-C {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2879 # If I specify that the environment should be passed to tex 2880 # then it is with the environment truncated at the next 2881 # section and I get a deferred warning. 2882 2883 $contents = $after; 2884 if ($opt_arg) { 2885 $contents = &process_environment(1, $env, $br_id, $style_info); 2886 } else { 2887 $contents = &process_environment(0, $env, $br_id, ''); 2888 } 2889 print STDOUT "\nOUT-C {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2890 $this_env = join("", $before, $closures 2891 , $contents, &balance_tags(), $reopens ); 2892 $_=''; 2893 &write_warnings( 2894 "\n\\end{$env $br_id} not found (truncated at next section boundary).\n"); 2895 } else { 2896 $pattern = &escape_rx_chars($pattern); 2897 s/$pattern/$closures/; 2898 print "\nCannot find \\end{$env $br_id}\n"; 2899 $_ .= join('', &balance_tags(), $reopens) unless ($defenv); 2900 } 2901 if ($this_env =~ /$begin_env_rx|$begin_cmd_rx/) { 2902 $_ = $this_env . $_; 2903 } else { push (@processedE, $this_env) } 2904 } 2905 $_ = join('',@processedE) . $_; 2906 $tmp = $_; undef $_; 2907 &process_command($counters_rx, $tmp) if ($tmp =~ /$counters_rx/); 2908 $_ = $tmp; undef $tmp; 2909 $_ 2910} 2911 2912sub find_end_env { 2913 # MRO: find_end_env($env,$contents,$rest) 2914 #local ($env, *ref_contents, *rest) = @_; 2915 my $env = $_[0]; 2916 my $be_rx = &make_begin_end_env_rx($env); 2917 my $count = 1; 2918 2919 while ($_[2] =~ /($be_rx)(\n?)/s) { # $rest 2920 $_[1] .= $`; # $contents 2921 2922 if ($2 eq "begin") { ++$count } 2923 else { --$count }; 2924 2925 #include any final \n at an {end} only 2926 $_[2] = (($2 eq 'end')? $5 : '') . $'; # $rest 2927 last if $count == 0; 2928 2929 $_[1] .= $1; # $contents 2930 } 2931 2932 if ($count != 0) { 2933 $_[2] = join('', $_[1], $_[2]); # $rest = join('', $contents, $rest); 2934 $_[1] = ''; # $contents 2935 return(0) 2936 } else { return(1) } 2937} 2938 2939 2940sub process_group_env { 2941 local($contents) = @_; 2942 local(@save_open_tags) = @$open_tags_R; 2943 local($open_tags_R) = [ @save_open_tags ]; 2944 print STDOUT "\nIN::{group $br_id}" if ($VERBOSITY > 4); 2945 print STDOUT "\n:$contents\n" if ($VERBOSITY > 6); 2946 2947 # need to catch explicit local font-changes 2948 local(%font_size) = %font_size if (/\\font\b/); 2949 2950 # record class/id info for a style-sheet entry 2951 local($env_id, $tmp, $etmp); 2952 if (($USING_STYLES) && !$PREAMBLE ) { $env_id = $br_id; } 2953# $env_id = "grp$br_id"; 2954# $styleID{$env_id} = " "; 2955# $env_id = " ID=\"$env_id\""; 2956# } 2957 2958 undef $_; 2959 $contents =~ s/^\s*$par_rx\s*//s; # don't start with a \par 2960 if ($contents =~ /^\s*\\($image_switch_rx)\b\s*/s) { 2961 # catch TeX-like environments: {\fontcmd ... } 2962 local($image_style) = $1; 2963 if ($USING_STYLES) { 2964 $env_style{$image_style} = " " unless ($env_style{$image_style}); 2965 } 2966 local($switch_cmd) = "do_cmd_${image_style}"; 2967 if (defined &$switch_cmd ) { 2968 eval "\$contents = \&${switch_cmd}(\$')"; 2969 print "\n*** &$switch_cmd didn't work: $@\n$contents\n\n" if ($@); 2970 } elsif ($contents =~ /$par_rx/) { 2971 # split into separate image for each paragraph 2972 local($par_style,$this_par_img) = ''; 2973 local(@par_pieces) = split($par_rx, $contents); 2974 local($this_par,$par_style,$par_comment); 2975 $contents = ''; 2976 while (@par_pieces) { 2977 $this_par = shift @par_pieces; 2978 if ($this_par =~ /^\s*\\($image_switch_rx)\b/s) { 2979 $image_style = $1; 2980 $par_style = 'P.'.$1; 2981 $env_style{$par_style} = " " unless ($env_style{$par_style}); 2982 } 2983# no comment: source is usually too highly encoded to be meaningful 2984# $par_comment = &make_comment($image_style,$this_par); 2985 $this_par_img = &process_in_latex("\{".$this_par."\}"); 2986 $contents .= join('' #,"\n", $par_comment 2987 , "\n<P" 2988 , (($USING_STYLES && $image_style)? " CLASS=\"$image_style\"" :'') 2989 ,">", $this_par_img 2990 , "</P>\n"); 2991 if (@par_pieces) { 2992 # discard the pieces from matching $par_rx 2993 $dum = shift @par_pieces; 2994 $dum = shift @par_pieces; 2995 $dum = shift @par_pieces; 2996 $dum = shift @par_pieces; 2997 $dum = shift @par_pieces; 2998 $dum = shift @par_pieces; 2999# $contents .= "\n</P>\n<P>"; 3000 } 3001 } 3002 } else { 3003 $contents = &process_undefined_environment("tex2html_accent_inline" 3004 , ++$global{'max_id'},"\{".$contents."\}"); 3005 } 3006 } elsif ($contents =~ /^\s*\\(html)?url\b($O\d+$C)[^<]*\2\s*/) { 3007 # do nothing 3008 $contents = &translate_environments($contents); 3009 $contents = &translate_commands($contents); 3010 } elsif (($env_switch_rx)&&($contents =~ s/^(\s*)\\($env_switch_rx)\b//s)) { 3011 # write directly into images.tex, protected by \begingroup...\endgroup 3012 local($prespace, $cmd, $tmp) = ($1,$2,"do_cmd_$2"); 3013 $latex_body .= "\n\\begingroup "; 3014 if (defined &$tmp) { 3015 eval("\$contents = &do_cmd_$cmd(\$contents)"); 3016 } 3017 $contents = &translate_environments($contents); 3018 $contents = &translate_commands($contents); 3019 undef $tmp; undef $cmd; 3020 $contents .= "\n\\endgroup "; 3021 } elsif ($contents =~ /^\s*\\([a-zA-Z]+)\b/s) { 3022 local($after_cmd) = $'; 3023 local($cmd) = $1; $tmp = "do_cmd_$cmd"; $etmp = "do_env_$cmd"; 3024 if (($cmd =~/^(rm(family)?|normalsize)$/) 3025 ||($declarations{$cmd}&&(defined &$tmp))) { 3026 do{ 3027 local(@save_open_tags) = @$open_tags_R; 3028 eval "\$contents = \&$tmp(\$after_cmd);"; 3029 print "\n*** eval &$tmp failed: $@\n$contents\n\n" if ($@); 3030 $contents .= &balance_tags(); 3031 }; 3032 } elsif ($declarations{$cmd}&&(defined &$etmp)) { 3033 eval "\$contents = \&$etmp(\$after_cmd);"; 3034 } else { 3035 $contents = &translate_environments($contents); 3036 $contents = &translate_commands($contents) 3037 if ($contents =~ /$match_br_rx/o); 3038 # Modifies $contents 3039 &process_command($single_cmd_rx,$contents) if ($contents =~ /\\/o); 3040 } 3041 undef $cmd; undef $tmp; undef $etmp; 3042 } else { 3043 $contents = &translate_environments($contents); 3044 $contents = &translate_commands($contents) 3045 if ($contents =~ /$match_br_rx/o); 3046 # Modifies $contents 3047 &process_command($single_cmd_rx,$contents) 3048 if ($contents =~ /\\/o); 3049 } 3050 $contents . &balance_tags(); 3051} 3052 3053# MODIFIES $contents 3054sub process_environment { 3055 local($opt, $env, $id, $styles) = @_; 3056 3057 local($envS) = $env; $envS =~ s/\*\s*$/star/; 3058 local($env_sub,$border,$attribs,$env_id) = ("do_env_$envS",'','',''); 3059 local($original) = $contents; 3060 3061 if ($env =~ /tex2html_deferred/ ) { 3062 $contents = &do_env_tex2html_deferred($contents); 3063 return ($contents); 3064 } 3065 $env_id = &read_style_info($opt, $env, $id, $styles) 3066 if (($USING_STYLES)&&($opt)); 3067 3068 if (&defined_env($env)) { 3069 print STDOUT ","; 3070 print STDOUT "{$env $id}" if ($VERBOSITY > 1); 3071# $env_sub =~ s/\*$/star/; 3072 $contents = &$env_sub($contents); 3073 3074 } elsif ($env =~ /tex2html_nowrap/) { 3075 #pass it on directly for LaTeX, via images.tex 3076 $contents = &process_undefined_environment($env, $id, $contents); 3077 return ($contents); 3078 3079# elsif (&special_env) { # &special_env modifies $contents 3080 } else { 3081 local($no_special_chars) = 0; 3082 local($failed) = 0; 3083 local($has_special_chars) = 0; 3084 &special_env; # modifies $contents 3085 print STDOUT "\n<MATH $env$id $contents>" if ($VERBOSITY > 3); 3086 if ($failed || $has_special_chars) { 3087 $contents = $original; 3088 $failed = 1; 3089 print STDOUT " !failed!\n" if ($VERBOSITY > 3); 3090 } 3091 } 3092 if (($contents) && ($contents eq $original)) { 3093 if ($ignore{$env}) { return(''); } 3094 # Generate picture 3095 if ($contents =~ s/$htmlborder_rx//o) { 3096 $attribs = $2; $border = (($4)? "$4" : 1) 3097 } elsif ($contents =~ s/$htmlborder_pr_rx//o) { 3098 $attribs = $2; $border = (($4)? "$4" : 1) 3099 } 3100 $contents = &process_undefined_environment($env, $id, $contents); 3101 $env_sub = "post_latex_$env_sub"; # i.e. post_latex_do_env_ENV 3102 if ( defined &$env_sub) { 3103 $contents = &$env_sub($contents); 3104 } elsif (($border||($attributes))&&($HTML_VERSION > 2.1)) { 3105 $contents = &make_table($border,$attribs,'','','',$contents); 3106 } else { 3107 $contents = join('',"<BR>\n",$contents,"\n<BR>") 3108 unless (!($contents)||($inner_math)||($env =~ 3109 /^(tex2html_wrap|tex2html_nowrap|\w*math|eq\w*n)/o )); 3110 } 3111 } 3112 $contents; 3113} 3114 3115 3116#RRM: This reads the style information contained in the optional argument 3117# to the \begin command. It is stored to be recovered later as an entry 3118# within the automatically-generated style-sheet, if $USING_STYLES is set. 3119# Syntax for this info is: 3120# <style names> ; <extra style-info> 3121 3122sub read_style_info { 3123 local($opt, $envS, $id, $styles) = @_; 3124 return() unless (($opt)&&($USING_STYLES)); 3125 # allow macro-expansion within the style-info 3126 $opt = &translate_commands($opt) if ($opt =~ /\\/); 3127 3128 # record class/id info for a style-sheet entry 3129 local($style_names, $style_extra, $env_id)=(''," ",''); 3130 if ($opt) { 3131 # if there is a `;' then <names> ; <extra> 3132 if ($styles =~ /^\s*([^\|]*)\|\s*(.*)$/) { 3133 $style_names = $1; $style_extra = $2; 3134 if ($style_names =~ /[=:;]/) { 3135 # cannot be <names>, so is <extra> 3136 $style_extra = $style_names.$style_extra; 3137 $style_names = ''; 3138 } 3139 } elsif ($styles =~ /[\=\:]/) { 3140 # cannot be <names>, so is <extras> 3141 $style_extra = $styles; 3142 } else { $style_names = $styles } 3143 $style_extra =~ s/\s*[=:]\s*/ : /go; 3144 $style_extra =~ s/([\w,\-]+)\s+([\w,\-]+)/$1 ; $2/go; 3145 $style_extra =~ s/\s*,\s*/ /go; 3146 3147 if ($style_names) { 3148 local($sname); 3149 local(@names) = split ( /\s+/ , $style_names ); 3150 # ensure a style-sheet entry for each new name 3151 foreach $sname (@names) { 3152 $env_style{$sname} = " " 3153 unless (($env_style{$sname})||($sname =~ /^\s*$/)); 3154 } 3155 } 3156 } 3157 # remove uninformative part of internally-defined env names 3158 $envS =~ s/tex2html_(\w+_)?(\w+)/$2/; $envS =~ s/preform/pre/; 3159 $env_id = $envS.$id; 3160 $styleID{$env_id} = $style_extra unless ($PREAMBLE); 3161 3162 if ($style_names) { $envS = "$style_names" } 3163 elsif (($envS =~ /^pre$/)&& 3164 (/^\\begin.*preform($O|$OP)\d+($C|$CP)$verbatim_mark(\w*[vV]erbatim)(\*?)/)) 3165 { $envS = $3.($4 ? 'star' : '') }; 3166 $env_style{$envS} = " " unless (($style_names)||($env_style{$envS})); 3167 $env_id = " ID=\"$env_id\"".(($envS) ? " CLASS=\"$envS\"" : ''); 3168 return($env_id); 3169} 3170 3171# RRM: This provides the mechanism to save style information in %env_style 3172# using LaTeX macros \htmlsetstyle and \htmladdtostyle 3173# 3174sub process_htmlstyles { 3175 local($mode, $_) = @_; 3176 local($pre_tags) = &get_next_optional_argument; 3177 local($class) = &missing_braces unless ( 3178 (s/$next_pair_pr_rx/$class = $2;''/e) 3179 ||(s/$next_pair_rx/$class = $2;''/e)); 3180 local($sinfo) = &missing_braces unless ( 3181 (s/$next_pair_pr_rx/$sinfo = $2;''/e) 3182 ||(s/$next_pair_rx/$sinfo = $2;''/e)); 3183 return ($_) unless ($class||$pre_tags); 3184 3185 $class = $pre_tags.($class ?'.':'').$class; 3186 $sinfo =~ s/\s*[:=]\s*/ : /g; 3187 $sinfo =~ s/\s*,\s*/ /g; 3188 if ($mode =~ /add/) { 3189 $sinfo = '; '.$sinfo if ($env_style{$class}); 3190 $env_style{$class} .= $sinfo; 3191 } else { $env_style{$class} = $sinfo } 3192 $_; 3193} 3194sub do_cmd_htmlsetstyle { &process_htmlstyles('set',@_) } 3195sub do_cmd_htmladdtostyle { &process_htmlstyles('add',@_) } 3196 3197 3198# The $<$, $>$, $|$ and $=>$, etc strings are replaced with their textual 3199# equivalents instead of passing them on to latex for processing in math-mode. 3200# This will not be necessary when the mechanism for passing environments 3201# to Latex is improved. 3202# RETURNS SUCCESS OR FAILURE 3203sub special_env { 3204 # Modifies $contents in its caller 3205 local($next)=''; 3206 local ($allow) = $HTML_VERSION ge '3.0' ? 3207 "[^#\$%&~\\\\{}]|\\limits" : "[^^#\$%&~_\\\\{}]"; 3208 #JKR: Use italics instead of bold #HWS: Generalize to include more symbols. 3209# $contents =~ s/^\$(\s*($html_specials_inv_rx|$allow)*\s*)\$(.)?/ 3210# $next=$3;&simple_math_env($1).(($next =~ m|\w|)? " ":'').$next/ige; 3211 $contents =~ s/^\$(\s*($html_specials_inv_rx|$allow)*\s*)\$$/ 3212 &simple_math_env($1)." "/ige; 3213 if ($contents =~ /\&\w*;/) { $has_math_chars=1 } 3214 if ($contents =~ /;SPM([a-zA-Z]+);/) { $has_special_chars=1 }; 3215} 3216 3217# Translate simple math environments into italic. 3218# Only letters should become italic; symbols should stay non-italic. 3219sub simple_math_env { 3220 local($mathcontents) = @_; 3221 if ($mathcontents eq '') { return("$mathcontents"); } 3222 elsif ($NO_SIMPLE_MATH) { # always make an image 3223 $failed = 1; return($mathcontents); 3224 } elsif ($mathcontents =~ /\\/) { # any macro kills "simple-math" 3225 local($save_math) = $mathcontents; 3226 local(@text_only) = (); 3227 while ((!$failed)&&($mathcontents =~ 3228 /\\((boldsymbol|bm)|(math|text)(bf|rm|it|tt)|times|[{}@#^_])(\b|[^A-Za-z]|$)/)) { 3229 # ...except when only simple styles 3230 push (@text_only, $`, ("$2$4" ? "\\simplemath".($4 ? $4 :"bf") :"\\$1") ); 3231 $mathcontents = $5.$'; 3232 $failed = 1 if ($` =~ /\\/); 3233 } 3234 $failed = 1 if ($mathcontents =~ /\\/); 3235 return($save_math) if $failed; 3236 $mathcontents = join('',@text_only,$mathcontents); 3237 } 3238 # Is there a problem here, with nested super/subscripts ? 3239 # Yes, so do each pattern-match for bracketings within a while-loop 3240 while ($mathcontents =~ s/\^$any_next_pair_rx/<SUP>$2<\/SUP>/go){}; 3241 while ($mathcontents =~ s/\^$any_next_pair_pr_rx/<SUP>$2<\/SUP>/go){}; 3242 while ($mathcontents =~ s/_$any_next_pair_rx/<SUB>$2<\/SUB>/g){}; 3243 while ($mathcontents =~ s/_$any_next_pair_pr_rx/<SUB>$2<\/SUB>/g){}; 3244 3245 $mathcontents =~ s/\^(\\[a-zA-Z]+|.)/<SUP>$1<\/SUP>/g; 3246 $mathcontents =~ s/_(\\[a-zA-Z]+|.)/<SUB>$1<\/SUB>/g; 3247 $mathcontents =~ s/(^|\s|[,;:'\?\.\[\]\(\)\+\-\=\!>]|[^\\<]\/|\d)(<(I|TT|B)>)?([a-zA-Z]([a-zA-Z ]*[a-zA-Z])?)(<\/\3>)?/ 3248 $1.(($2)? $2 :'<I>').$4.(($6)? $6 : '<\/I>')/eig; 3249 3250 $mathcontents =~ s/\\times($|\b|[^A-Za-z])/ x $1/g; 3251 $mathcontents =~ s/\\times($|\b|[^A-Za-z])/ x $1/g; 3252 $mathcontents =~ s/\\\\/<BR>\n/g; 3253 $mathcontents =~ s/\\\\/<BR>\n/g; 3254 $mathcontents =~ s/\\([,;])/ /g; 3255 $mathcontents =~ s/\\(\W)/$1/g; 3256 $mathcontents =~ s/ {2,}/ /g; 3257 3258 # any simple style changes remove enclosed <I> tags 3259 $mathcontents = &translate_commands($mathcontents) 3260 if ($mathcontents =~ /\\/); 3261 3262 $mathcontents =~ s/<I><\/(SUB|SUP)>/<\/$1><I>/g; 3263 $mathcontents =~ s/<(SUB|SUP)><\/I>/<\/I><$1>/g; 3264 $mathcontents =~ s/;<I>SPM([a-zA-Z]+)<\/I>;/;SPM$1;/go; 3265 $mathcontents =~ s/<(\/?)<I>(SUB|SUP|I|B|TT)<\/I>>/<$1$2>/g; 3266 $mathcontents =~ s/<\/(B|I|TT)><\1>//g; 3267 $mathcontents; 3268} 3269 3270sub do_cmd_simplemathrm { 3271 local ($_) = @_; 3272 local($text); 3273 $text = &missing_braces unless ( 3274 (s/$next_pair_pr_rx/$text = $2;''/e) 3275 ||(s/$next_pair_rx/$text = $2;''/e)); 3276 $text =~ s/<\/?I>//g; 3277 join('', $text, $_) 3278} 3279sub do_cmd_simplemathbf { 3280 local ($_) = @_; 3281 local($text); 3282 $text = &missing_braces unless ( 3283 (s/$next_pair_pr_rx/$text = $2;''/e) 3284 ||(s/$next_pair_rx/$text = $2;''/e)); 3285 $text =~ s/<\/?I>//g; 3286 join('','<B>', $text, '</B>', $_) 3287} 3288sub do_cmd_simplemathtt { 3289 local ($_) = @_; 3290 local($text); 3291 $text = &missing_braces unless ( 3292 (s/$next_pair_pr_rx/$text = $2;''/e) 3293 ||(s/$next_pair_rx/$text = $2;''/e)); 3294 $text =~ s/<\/?I>//g; 3295 join('','<TT>', $text, '</TT>', $_) 3296} 3297 3298sub process_math_in_latex { 3299 local($mode,$style,$level,$math) = @_; 3300 local(@anchors); 3301 if ($level) { 3302 $style = (($level > 1) ? "script" : "") . "script"; 3303 } elsif (! $style) { 3304 $style = (($mode =~/display|equation/)? "display" : "") 3305 } 3306 $style = "\\${style}style" if ($style); 3307 3308 # &process_undefined_environment changes $_ , so save it. 3309 local($after) = $_; 3310 3311 # the 'unless' catches nested AMS-aligned environments 3312 $mode = "tex2html_wrap_" . 3313 (($mode =~/display|equation|eqnarray/) ? 'indisplay' : 'inline') 3314 unless ($mode =~ /^equationstar/ && $outer_math =~ /^equationstar/); 3315 3316 $global{'max_id'}++; 3317 $math =~ s/\\(\n|$)/\\ $1/g; # catch \ at end of line or string 3318 $math =~ s/^\s*((\\!|;SPMnegsp;)\s*)*//g; # remove neg-space at start of string 3319 if ($mode =~ /tex2html_wrap_/ ) { 3320 $math = &process_undefined_environment( $mode 3321 , $global{'max_id'}, join('', "\$$style ", $math, "\$")); 3322 } else { 3323 # some AMS environments must be within {equation} not {displaymath} 3324 $math =~ s/displaymath/equation*/ 3325 if ($math =~ /\\begin\{(x+|fl)*align/); 3326 $math = &process_undefined_environment($mode, $global{'max_id'}, $math); 3327 } 3328 $math .= "\n" if ($math =~ /$comment_mark\s*\d+$/s); 3329 $_ = $after; 3330 # the delimiter \001 inhibits an unwanted \n at image-replacement 3331 $math . ($math =~ /$image_mark/? "\001" : ''); 3332} 3333 3334#RRM: Explicit font switches need images. Use the image_switch mechanism. 3335sub do_cmd_font { 3336 local($_) = @_; 3337 local($fontinfo,$fontname,$size) = ('','','10pt'); 3338 s/\s*\\(\w+)\s*=?\s*(.*)(\n|$)/$fontname=$1;$fontinfo=$2;''/eo; 3339 $image_switch_rx .= "|$fontname"; 3340 3341 if ($fontinfo =~ /([.\d]+\s*(true)?(pt|mm|cm))/ ) { $size = $1 } 3342 elsif ( $fontinfo =~ /[a-zA-Z]+(\d+)\b/ ) { $size = $1.'pt' } 3343 if ( $fontinfo =~ /(scaled|at)\s*\\?(.+)/) { $size .= " scaled $1" } 3344 $font_size{$fontname} = $size; 3345 $_; 3346} 3347sub wrap_cmd_font { 3348 local($cmd, $_) = @_; 3349 local ($args, $dummy, $pat) = ""; 3350 if (/\n/) { $args .= $`.$& ; $_ = $' } else {$args = $_; $_ = ''}; 3351 (&make_deferred_wrapper(1).$cmd.$padding.$args.&make_deferred_wrapper(0),$_) 3352} 3353 3354sub do_cmd_newfont { 3355 local($_) = @_; 3356 local($fontinfo,$fontname,$size) = ('','','10pt'); 3357 $fontname = &missing_braces unless ( 3358 (s/$next_pair_pr_rx/$fontname=$2;''/eo) 3359 ||(s/$next_pair_rx/$fontname=$2;''/eo)); 3360 $fontname=~ s/^\s*\\|\s*$//g; 3361 $image_switch_rx .= "|$fontname"; 3362 3363 $fontinfo = &missing_braces unless ( 3364 (s/$next_pair_pr_rx/$fontinfo=$2;''/eo) 3365 ||(s/$next_pair_rx/$fontinfo=$2;''/eo)); 3366 if ($fontinfo =~ /([.\d]+\s*(true)?(pt|mm|cm))/ ) { $size = $1 } 3367 elsif ( $fontinfo =~ /[a-zA-Z]+(\d+)\b/ ) { $size = $1.'pt' } 3368 if ( $fontinfo =~ /(scaled|at)\s*\\?(.+)/) { $size .= " scaled $1" } 3369 $font_size{$fontname} = $size; 3370 $_; 3371} 3372 3373sub defined_env { 3374 local($env) = @_; 3375 $env =~ s/\*$/star/; 3376 local($env_sub) = ("do_env_$env"); 3377 # The test using declarations should not be necessary but 'defined' 3378 # doesn't seem to recognise subroutines generated dynamically using 'eval'. 3379 # Remember that each entry in $declarations generates a dynamic prodedure ... 3380 ((defined &$env_sub) || ($declarations{$env})); 3381} 3382 3383# RRM: utility to add style information to stored image-parameters 3384# currently only (math) scaling info is included; 3385# current color, etc. could also be added here. 3386sub addto_encoding { 3387 local($env, $contents) = @_; 3388# $contents =~ s/(\\(begin|end)\s*)?<<\d*>>|\n//g; # RRM: remove env delimiters 3389 $contents =~ s/(\\(begin|end)\s*(<<\d*>>))|\n//g; # RRM: remove env delimiters 3390 # append scaling information for environments using it 3391 if (($MATH_SCALE_FACTOR) 3392 &&(($contents =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/) 3393 ||($env =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/)) 3394 ) { $contents .= ";MSF=$MATH_SCALE_FACTOR" } 3395 3396 if ($LATEX_FONT_SIZE =~ /([\d\.]+)pt/) { 3397 local($fsize) = $1; 3398 $contents .= ";LFS=$fsize" unless ($fsize ==10); 3399 } 3400 3401 if (($EXTRA_IMAGE_SCALE) 3402 &&(($contents =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/) 3403 ||($env =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/)) 3404 ) { $contents .= ";EIS=$EXTRA_IMAGE_SCALE" } 3405 3406 if (($DISP_SCALE_FACTOR) 3407 &&(($contents =~ /indisplay|displaymath|eqnarray|equation/) 3408 ||($env =~ /indisplay|displaymath|eqnarray|equation/)) 3409 &&!(($contents =~ /makeimage/)||($env =~ /makeimage/)) 3410 ) { $contents .= ";DSF=$DISP_SCALE_FACTOR" } 3411 3412 if (($EQN_TAGS) 3413 &&(($env =~ /eqnarray($|[^_\*])|equation/) 3414 ||($contents =~ /eqnarray($|[^_\*])|equation/)) 3415 &&!(($contents =~ /makeimage/)||($env =~ /makeimage/)) 3416 ) { $contents .= ";TAGS=$EQN_TAGS" } 3417 3418 if (($FIGURE_SCALE_FACTOR) 3419 &&!(($contents =~ /makeimage/)||($env =~ /makeimage/)) 3420 &&(($contents =~ /figure/)||($env =~ /figure/)) 3421 ) { $contents .= ";FSF=$FIGURE_SCALE_FACTOR"} 3422 3423 if (($ANTI_ALIAS) 3424 &&(($contents =~ /figure/)||($env =~ /figure/)) 3425 &&!(($contents =~ /makeimage/)||($env =~ /makeimage/)) 3426 ) { $contents .= ";AAF" } 3427 elsif ($ANTI_ALIAS_TEXT) { $contents .= ";AAT" } 3428 if (!$TRANSPARENT_FIGURES) { $contents .= ";NTR" } 3429 3430 $contents; 3431} 3432 3433sub process_undefined_environment { 3434 local($env, $id, $contents) = @_; 3435 if ($env =~ s/\*{2,}/*/) { print "\n*** $_[0] has too many \*s ***"}; 3436 3437 local($name,$cached,$raw_contents,$uucontents) = ("$env$id"); 3438 $name =~ s/\*/star/; 3439 local($oldimg,$size,$fullcontents,$imgID); 3440 return if ($AUX_FILE); 3441 3442 # catch \footnotemark within an image, especially if in math 3443 local(@foot_anchors,$foot_anchor); 3444 local($im_footnote,$im_mpfootnote) = ($global{'footnote'},$global{'mpfootnote'}); 3445 @foot_anchors = &process_image_footnote($contents) 3446 if ($contents =~ /\\footnote(mark)?\b/s); 3447 if ((@foot_anchors)&&($eqno)) { 3448 # append the markers to the equation-numbers 3449 $eqno .= join(' ', ' ', @foot_anchors); 3450 @foot_anchors = (); 3451 } 3452 3453 print STDOUT "\nUNDEF-IN {$env $id}:\n$contents\n" if ($VERBOSITY > 4); 3454 #RRM - LaTeX commands wrapped with this environment go directly into images.tex. 3455 if ($env =~ /tex2html_nowrap|^lrbox$/){ # leave off the wrapper, do not cache 3456 # totally ignore if in preamble... 3457 # ...since it will be put into images.tex anyway!! 3458 if (!($PREAMBLE)) { 3459 $contents =~ s/^\n+|\n+$/\n/g; 3460 local($lcontents) = join('', "\\begin{$env}", $contents , "\\end{$env}" ); 3461 $lcontents =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg; 3462 print STDOUT "pre-LATEX {$env}:\n$lcontents\n" if ($VERBOSITY > 3); 3463 $raw_contents = &revert_to_raw_tex($lcontents); 3464 print STDOUT "LATEX {$env}:\n$raw_contents\n" if ($VERBOSITY > 3); 3465 $latex_body .= "\n$raw_contents"."%\n\n" ; 3466 } 3467 return("") if ($env =~ /^lrbox/); 3468 # ignore enclosed environments; e.g. in \settolength commands 3469# $contents = &translate_environments($contents); # ignore environments 3470# $contents = &translate_commands($contents); 3471 # ...but apply any Perl settings that may be defined 3472 $contents = &process_command($single_cmd_rx,$contents); 3473 print STDOUT "\nOUT {$env $id}:\n$contents\n" if ($VERBOSITY > 4); 3474 return(""); 3475 } 3476 # catch pre-processor environments 3477 if ($PREPROCESS_IMAGES) { 3478 local($pre_env,$which, $done, $indic); 3479 while ($contents =~ /$pre_processor_env_rx/) { 3480 $done .= $`; $pre_env = $5; $which =$1; $contents = $'; 3481 if (($which =~ /begin/)&&($pre_env =~ /indica/)) { 3482 if ($contents =~ s/^\[(\w+)]//o) { $done .= '#'.$1 } 3483 } elsif (($which =~ /end/)&&($pre_env =~ /indica/)) { 3484 $done .= '#NIL'; 3485 } elsif (($which =~ /begin/)&&($pre_env =~ /itrans/)) { 3486 if ($contents =~ s/^\[(\w+)]/$indic=$1;''/e) 3487 { $done .= "\#$indic" } 3488 } elsif (($which =~ /end/)&&($pre_env =~ /itrans/)) { 3489 $done .= "\#end$indic"; 3490 } elsif ($which =~ /begin/) { 3491 $done .= (($which =~ /end/)? $end_preprocessor{$pre_env} 3492 : $begin_preprocessor{$pre_env} ) 3493 } 3494 } 3495 $contents = $done . $contents; 3496 } 3497 $fullcontents = $contents; # save for later \label search. 3498 # MRO: replaced $* with /m 3499 $contents =~ s/\n?$labels_rx(\%([^\n]+$|$EOL))?/\n/gm; 3500 3501 local($tmp) = $contents; 3502 $tmp =~ s/^((\\par|\%)?\s*\n)+$//g; 3503 return( &do_labels($fullcontents, "\ ") ) unless $tmp; 3504 3505 # just a comment as the contents of a cell in a math-display 3506 if ($tmp =~ /\$\\(display|text|(script)+)style\s*$comment_mark\d+\s*\$$/) 3507 { return ( &do_labels($fullcontents, "\ ") ) }; 3508 3509 $contents = "\n% latex2html id marker $id\n$contents" if 3510 (!$PREAMBLE &&($contents =~ /$order_sensitive_rx/) 3511 &&(!($env =~ /makeimage/))); 3512 3513 $env =~ s/displaymath/equation*/ 3514 if ($contents =~ /\\begin\{(x+|fl)*align/); 3515 #RRM: include the inline-color, when applicable 3516 $contents = join('' 3517 , (($inner_math =~ /in(display|line)/) ? '$' : '') 3518 , "\\begin{$env}" 3519 , ($color_env ? "\\bgroup\\$color_env" : '') 3520 , $contents , ($color_env ? "\\egroup" : '') 3521 , "\\end{$env}" 3522 , (($inner_math =~ /in(display|line)/) ? '$' : '') 3523 ) if ($contents); 3524 3525 # append to the name of special environments found within math 3526 if ($inner_math) { 3527 local($ext) = $inner_math; 3528 if ($inner_math =~ /(display|line)/){ $ext = 'in'.$1;}; 3529 $name =~ s/(\d+)$/_$ext$1/; 3530 } 3531 3532 if (!($latex_body{$name} = $contents)) { 3533 print "\n *** code for $name is too long ***\n"} 3534 if ($contents =~ /$htmlimage_rx/) { 3535 $uucontents = &special_encoding($env,$2,$contents); 3536 } elsif ($contents =~ /$htmlimage_pr_rx/) { 3537 $uucontents = &special_encoding($env,$2,$contents); 3538 } else { 3539 $uucontents = &encode(&addto_encoding($env,$contents)); 3540 } 3541 $cached = $cached_env_img{$uucontents}; 3542 print STDOUT "\nCACHED: $uucontents:\n$cached\n" if ($VERBOSITY > 4); 3543 if ($NOLATEX) { 3544 $id_map{$name} = "[$name]"; 3545 } elsif (defined ($_ = $cached)) { # Is it in our cache? 3546 # Have we already used it? 3547 if (($oldimg) = /SRC="$PREFIX$img_rx\.$IMAGE_TYPE"/o) { 3548 # No, check its size 3549 local($eis) = 1; 3550 # Does it have extra scaling ? 3551 if ($uucontents =~ /EIS=(.*);/) { $eis = $1 } 3552 ($size, $imgID) = &get_image_size("$PREFIX$oldimg.old", $eis); 3553 # Does it have extra scaling ? 3554# if ($uucontents =~ /EIS=(.*);/) { 3555# local($eis) = $1; local($w,$h); 3556# # quotes will not be there with HTML 2.0 3557# $size =~ s/(WIDTH=\")(\d*)(\".*HEIGHT=\")(\d*)\"/ 3558# $w = int($2\/$eis + .5); $h=int($4\/$eis + .5); 3559# "$1$w$3$h\""/e ; # insert the re-scaled size 3560# } 3561 # quotes will not be there with HTML 2.0 3562 $size =~ s/\"//g if ($HTML_VERSION < 2.2); 3563 if ($size && /\s$size\s/) { 3564 # Size is OK; recycle it! 3565 ++$global_page_num; 3566 $_ = $cached ; # ...perhaps restoring the desired size. 3567 s/(${PREFIX}T?img)\d+\.($IMAGE_TYPE|html)/ 3568 &rename_html($&,"$1$global_page_num.$2")/geo; 3569 } else { 3570 if ($env =~ /equation/) { &extract_eqno($name,$cached) } 3571 $_ = ""; # The old Image has wrong size! 3572 undef($cached); # (or it doesn't exist) 3573 } 3574 } 3575 s/(IMG\n)/$1$imgID/ if $imgID; 3576 3577 s/$PREFIX$img_rx\.new/$PREFIX$1.$IMAGE_TYPE/go; # Point to the actual image file(s) 3578 $id_map{$name} = $_; 3579 s/$PREFIX$img_rx\.$IMAGE_TYPE/$PREFIX$1.new/go; # But remember them as used. 3580 $cached_env_img{$uucontents} = $_; 3581 } 3582 3583 if (! defined($cached)) { # Must generate it anew. 3584 &clear_images_dbm_database 3585 unless ($new_page_num ||($NO_SUBDIR && $FIXEDDIR)); 3586 $new_id_map{$name} = $id_map{$name} = ++$global_page_num . "#" . 3587 ++$new_page_num; 3588 $orig_name_map{$id_map{$name}} = $name; 3589 $cached_env_img{$uucontents} = $id_map{$name} if ($REUSE == 2); 3590 3591 #RRM: this (old) code frequently crashes NDBM, so do it in 2 steps 3592# $img_params{$name} = join('#', &extract_parameters($contents)); 3593 local(@params) = &extract_parameters($contents); 3594 $img_params{$name} = join('#',@params); undef $params; 3595 print "\nIMAGE_PARAMS $name: ".$img_params{$name} if ($VERBOSITY > 3); 3596 3597 $contents =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg; 3598 print STDOUT "\nLATEX {$env}:\n$contents" if ($VERBOSITY > 3); 3599 $raw_contents = &revert_to_raw_tex($contents) unless ($contents =~ /^\s*$/) ; 3600 $raw_contents =~ s/\\pagebreak|\\newpage|\\clearpage/\\\\/go; 3601 print STDOUT "\nLATEX {$env}:\n$raw_contents\n" if ($VERBOSITY > 3); 3602 local($box_type) = ''; 3603 if ($raw_contents =~ /\\special\s*\{/) { 3604 $tex_specials{$name} = "1"; 3605 &write_warnings("\nenvironment $name contains \\special commands"); 3606 print STDOUT "\n *** environment $name contains \\special commands ***\n" 3607 if ($VERBOSITY); 3608 } elsif (($env =~ /$inline_env_rx/)||($inner_math =~ /in(line|display)/)) { 3609 # crop to the marks only... or shave a bit off the bottom 3610 if (($env =~ /tex2html_[^w]/)||$inner_math) { 3611 # e.g. accents, indic but not wrap 3612 $crop{$name} = "bl"; 3613 $box_type = "i"; 3614 } else { 3615 # ...or shave a bit off the bottom as well 3616 $crop{$name} = "bls"; 3617 $box_type = "h"; 3618 } 3619 } elsif (($env =~ /(eqnarray|equation)(\*|star)/)||($inner_math)) { 3620 # crop to minimum size... 3621 $crop{$name} = "blrl"; 3622 $box_type = "v"; 3623 } elsif ($env =~ /(picture|tex2html_wrap)(\*|star)?/) { 3624 # crop hbox to minimum size... 3625 $crop{$name} = ""; 3626 $box_type = "p"; 3627 } elsif ($env =~ /$display_env_rx/) { 3628 # crop vbox to minimum size... 3629 $crop{$name} = "blrl" ; 3630 if ($env =~ /(equation|eqnarray)((s)?$|\d)/) { 3631 # ... unless equation numbers are included ... 3632 if ($3) { # AMS {subequations} 3633 $global{'eqn_number'}=$prev_eqn_number if $prev_eqn_number; 3634 --$global{'eqn_number'}; 3635 } 3636 $raw_contents = join('' , 3637 (($eqno{$name}||$global{'eqn_number'})? 3638 &set_equation_counter($eqno{$name}) : '') 3639 , $raw_contents); 3640 $crop{$name} = "bl" ; 3641 } elsif ($HTML_VERSION < 2.2) { 3642 # ... HTML 2.0 cannot align images, so keep the full typeset width 3643 $crop{$name} = "bl" ; 3644 } 3645 $box_type = "v"; 3646 } 3647 3648 #RRM: include the TeX-code for the appropriate type of box. 3649 eval "\$raw_contents = \&make_$box_type"."box($name, \$raw_contents);"; 3650 3651 # JCL(jcl-pag) - remember html text if debug is set. 3652 local($_); 3653 if ($DEBUG) { 3654 $_ = $contents; 3655 s/\n/ /g; 3656 $_ = &revert_to_raw_tex($_); 3657 # incomplete or long commented code can break pre-processors 3658 if ($PREPROCESS_IMAGES) { 3659 $_ = ((/^(\\\w+)?\{[^\\\}\<]*\}?/)? $& : '').'...' ; 3660 $_ = '{ ... }' if ( length($_) > 100); 3661 } elsif ( length($_) > 200) { 3662 $_ = join('',substr($_,0,200),"...\}"); 3663 } 3664 s/\\(begin|end)/$1/g; s/[\000-\020]//g; 3665 $_ = join('',"% contents=",$_,"\n"); 3666 } 3667 $raw_contents = '\setcounter{equation}{'.$prev_eqn_number."}\n".$raw_contents 3668 if ($env =~ /subequations/); 3669 3670# JCL(jcl-pag) - build the page entries for images.tex: Each page is embraced to 3671# let most statements have only local effect. Each page must compile into a 3672# single dvi page to get proper image translation. Hence the invisible glue to 3673# get *at least* one page (raw_contents alone might not wield glue), and 3674# sufficing page length to get *exactly* one page. 3675# 3676 $latex_body .= "{\\newpage\\clearpage\n$_" . 3677# "$raw_contents\\hfill\\vglue1pt\\vfill}\n\n"; 3678# "$raw_contents\\hfill\\vss}\n\n" if ($raw_contents); 3679# "$raw_contents\\hfill\\lthtmlcheckvsize\\clearpage}\n\n" if ($raw_contents); 3680 "$raw_contents\\lthtmlcheckvsize\\clearpage}\n\n" if ($raw_contents); 3681 } 3682 print STDOUT "\nIMAGE_CODE:{$env $id}:\n$raw_contents\n" if ($VERBOSITY > 4); 3683 3684 # Anchor the labels and put a marker in the text; 3685 local($img) = &do_labels($fullcontents,"$image_mark#$name#"); 3686 print STDOUT "\nUNDEF_OUT {$env $id}:\n$img\n" if ($VERBOSITY > 4); 3687 return($img) unless (@foot_anchors); 3688 3689 # use the image as source to the 1st footnote, unless it is already an anchor. 3690 if ($img =~ /<\/?A>/) { 3691 join(' ', $img, @foot_anchors); 3692 } elsif ($#foot_anchors ==0) { 3693 $foot_anchor = shift @foot_anchors; 3694 $foot_anchor =~ s/<SUP>.*<\/SUP>/$img/; 3695# join(' ', $foot_anchor, @foot_anchors); 3696 $foot_anchor; 3697 } else { 3698 join(' ', $img, @foot_anchors); 3699 } 3700} 3701 3702sub special_encoding { # locally sets $EXTRA_IMAGE_SCALE 3703 local($env,$_,$contents) = @_; 3704 local($exscale) = /extrascale=([\.\d]*)/; 3705 local($EXTRA_IMAGE_SCALE) = $exscale if ($exscale); 3706 &encode(&addto_encoding($env,$contents)); 3707} 3708 3709 3710sub extract_eqno{ 3711 local($name,$contents) = @_; 3712 if ($contents =~ /<P ALIGN="\w+">\(([^<>])\)<\/P>$/) { 3713 if (($eqno{$name})&&!($eqno{$name} eq $1)) { 3714 &write_warnings("\nequation number for $name may be wrong.")}; 3715 $eqno{$name}="$1"; 3716 } 3717} 3718sub set_equation_counter{ 3719 if ( $global{'eqn_number'}) { 3720 "\\setcounter{equation}{". $global{'eqn_number'} ."}\n" 3721 } else { "\\setcounter{equation}{0}\n" } 3722} 3723 3724# RRM: 3 different types of boxing, for image environments. 3725 3726# general environments --- crops to width & height 3727sub make_box { 3728 local($id,$contents) = @_; 3729 "\\lthtmlfigureA{". $id ."}%\n". $contents ."%\n\\lthtmlfigureZ\n"; 3730} 3731 3732# inline math --- horizontal mode, captures height/depth + \mathsurround 3733sub make_hbox { 3734 local($id,$contents) = @_; 3735 if ($id =~ /indisplay/) { 3736 "\\lthtmlinlinemathA{". $id ."}%\n". $contents ."%\n\\lthtmlindisplaymathZ\n"; 3737 } else { 3738 "\\lthtmlinlinemathA{". $id ."}%\n". $contents ."%\n\\lthtmlinlinemathZ\n"; 3739 } 3740} 3741 3742# inline text-image (e.g. accents) --- horizontal mode, captures height/depth 3743sub make_ibox { 3744 local($id,$contents) = @_; 3745 "\\lthtmlinlineA{". $id ."}%\n". $contents ."%\n\\lthtmlinlineZ\n"; 3746} 3747 3748# centered images (e.g. picture environments) --- horizontal mode 3749sub make_pbox { 3750 local($id,$contents) = @_; 3751 "\\lthtmlpictureA{". $id ."}%\n". $contents ."%\n\\lthtmlpictureZ\n"; 3752} 3753 3754# displayed math --- vertical mode, captures height/depth + page-width 3755sub make_vbox { 3756 local($id,$contents) = @_; 3757 if (($HTML_VERSION >=3.2)&&($id =~/(equation|eqnarray)($|\d)/) &&! $failed ) { 3758 if ($contents =~ s/^\\setcounter\{equation\}\{\d+\}/$&%\n\\lthtmldisplayB\{$id\}%/) 3759 { $contents ."%\n\\lthtmldisplayZ\n" } 3760 else { "\\lthtmldisplayB{$id}%\n". $contents ."%\n\\lthtmldisplayZ\n" } 3761 } else { "\\lthtmldisplayA{$id}%\n". $contents ."%\n\\lthtmldisplayZ\n"} 3762} 3763 3764sub preprocess_images { 3765 do { 3766 print "\nWriting image.pre file ...\n"; 3767 open(ENV,">.$dd${PREFIX}images.pre") 3768 || die "\nCannot write '${PREFIX}images.pre': $!\n"; 3769 print ENV &make_latex($latex_body); 3770 print ENV "\n"; 3771 close ENV; 3772 ©_file($FILE, "bbl"); 3773 ©_file($FILE, "aux"); 3774 local($num_cmds, $cnt, $this, @cmds); 3775 @cmds = (split ('\n', $preprocessor_cmds)); 3776 $this_cmd = $num_cmds = 1+$#cmds; 3777 $cnt = $num_cmds; $preprocessor_cmds = ''; 3778 while (@cmds) { 3779 $this_cmd = shift @cmds; last unless ($this_cmd); 3780 $this_cmd =~ s/.pre /.tex$cnt / if(($cnt)&&($cnt < $num_cmds)); 3781 $cnt--; $this_cmd .= $cnt if ($cnt); 3782 $preprocessor_cmds .= $this_cmd."\n"; 3783 L2hos->syswait($this_cmd); 3784 } 3785 # save pre-processor commands in a file: preproc 3786 open(CMDS,">.$dd${PREFIX}preproc") 3787 || die "\nCannot write '${PREFIX}preproc': $!\n"; 3788 print CMDS $preprocessor_cmds ; 3789 close CMDS; 3790 3791 } if ((%latex_body) && ($latex_body =~ /newpage/)); 3792} 3793sub make_image_file { 3794 do { 3795 print "\nWriting image file ...\n"; 3796 open(ENV,">.$dd${PREFIX}images.tex") 3797 || die "\nCannot write '${PREFIX}images.tex': $!\n"; 3798 print ENV &make_latex($latex_body); 3799 print ENV "\n"; 3800 close ENV; 3801 ©_file($FILE, "bbl"); 3802 ©_file($FILE, "aux"); 3803 } if ((%latex_body) && ($latex_body =~ /newpage/)); 3804} 3805 3806sub make_latex_images{ 3807 &close_dbm_database if $DJGPP; 3808 local($dd) = $dd; $dd = '/' if ($dd eq "\\"); 3809 local($latex_call) = "$LATEX .$dd${PREFIX}images.tex"; 3810 print "$latex_call\n" if (($DEBUG)||($VERBOSITY > 1)); 3811 L2hos->syswait($latex_call); 3812 &open_dbm_database if $DJGPP; 3813} 3814 3815sub make_off_line_images { 3816 local($name, $page_num); 3817 if (!$NOLATEX && -f ".${dd}${PREFIX}images.tex") { 3818 &make_tmp_dir; # sets $TMPDIR and $DESTDIR 3819 $IMAGE_PREFIX =~ s/^_//o if ($TMPDIR); 3820 3821 &make_latex_images(); 3822 3823 print "\nGenerating postscript images using dvips ...\n"; 3824 &process_log_file(".$dd${PREFIX}images.log"); # Get eqn size info 3825 unless ($LaTeXERROR) { 3826 local($dvips_call) = 3827 "$DVIPS -S1 -i $DVIPSOPT -o$TMPDIR$dd${IMAGE_PREFIX} .${dd}${PREFIX}images.dvi"; 3828 print "$dvips_call\n" if (($DEBUG)||($VERBOSITY > 1)); 3829 3830 &close_dbm_database if $DJGPP; 3831 L2hos->syswait($dvips_call) && print "Error: $!\n"; 3832 undef $dvips_call; 3833 &open_dbm_database if $DJGPP; 3834 3835 # add suffix .ps to the file-names for each image 3836 if(opendir(DIR, $TMPDIR || '.')) { 3837 # use list-context instead; thanks De-Wei Yin <yin@asc.on.ca> 3838 my (@ALL_IMAGE_FILES) = grep /^$IMAGE_PREFIX\d+$/o, readdir(DIR); 3839 foreach (@ALL_IMAGE_FILES) { 3840 L2hos->Rename("$TMPDIR$dd$_", "$TMPDIR$dd$_.ps"); 3841 } 3842 closedir(DIR); 3843 } else { 3844 print "\nError: Cannot read dir '$TMPDIR': $!\n"; 3845 } 3846 } 3847 } 3848 if ($LaTeXERROR) { 3849 print "\n\n*** LaTeXERROR\n"; return(); 3850 } 3851 3852 while ( ($name, $page_num) = each %new_id_map) { 3853 # Extract the page, convert and save it 3854 &extract_image($page_num,$orig_name_map{$page_num}); 3855 } 3856} 3857 3858# Generate images for unknown environments, equations etc, and replace 3859# the markers in the main text with them. 3860# - $cached_env_img maps encoded contents to image URL's 3861# - $id_map maps $env$id to page numbers in the generated latex file and after 3862# the images are generated, maps page numbers to image URL's 3863# - $page_map maps page_numbers to image URL's (temporary map); 3864# Uses global variables $id_map and $cached_env_img, 3865# $new_page_num and $latex_body 3866 3867 3868sub make_images { 3869 local($name, $contents, $raw_contents, $uucontents, $page_num, 3870 $uucontents, %page_map, $img); 3871 # It is necessary to run LaTeX this early because we need the log file 3872 # which contains information used to determine equation alignment 3873 if ( $latex_body =~ /newpage/) { 3874 print "\n"; 3875 if ($LATEX_DUMP) { 3876 # dump a pre-compiled format 3877 if (!(-f "${PREFIX}images.fmt")) { 3878 print "$INILATEX ./${PREFIX}images.tex\n" 3879 if (($DEBUG)||($VERBOSITY > 1)); 3880 print "dumping ${PREFIX}images.fmt\n" 3881 unless ( L2hos->syswait("$INILATEX ./${PREFIX}images.tex")); 3882 } 3883 local ($img_fmt) = (-f "${PREFIX}images.fmt"); 3884 if ($img_fmt) { 3885 # use the pre-compiled format 3886 print "$TEX \"&./${PREFIX}images\" ./${PREFIX}images.tex\n" 3887 if (($DEBUG)||($VERBOSITY > 1)); 3888 L2hos->syswait("$TEX \"&./${PREFIX}images\" ./${PREFIX}images.tex"); 3889 } elsif (-f "${PREFIX}images.dvi") { 3890 print "${PREFIX}images.fmt failed, proceeding anyway\n"; 3891 } else { 3892 print "${PREFIX}images.fmt failed, trying without it\n"; 3893 print "$LATEX ./${PREFIX}images.tex\n" 3894 if (($DEBUG)||($VERBOSITY > 1)); 3895 L2hos->syswait("$LATEX ./${PREFIX}images.tex"); 3896 } 3897 } else { &make_latex_images() } 3898# local($latex_call) = "$LATEX .$dd${PREFIX}images.tex"; 3899# print "$latex_call\n" if (($DEBUG)||($VERBOSITY > 1)); 3900# L2hos->syswait("$latex_call"); 3901## print "$LATEX ./${PREFIX}images.tex\n" if (($DEBUG)||($VERBOSITY > 1)); 3902## L2hos->syswait("$LATEX ./${PREFIX}images.tex"); 3903## } 3904 $LaTeXERROR = 0; 3905 &process_log_file("./${PREFIX}images.log"); # Get image size info 3906 } 3907 if ($NO_IMAGES) { 3908 my $img = "image.$IMAGE_TYPE"; 3909 my $img_path = "$LATEX2HTMLDIR${dd}icons$dd$img"; 3910 L2hos->Copy($img_path, ".$dd$img") 3911 if(-e $img_path && !-e $img); 3912 } 3913 elsif ((!$NOLATEX) && ($latex_body =~ /newpage/) && !($LaTeXERROR)) { 3914 print "\nGenerating postscript images using dvips ...\n"; 3915 &make_tmp_dir; # sets $TMPDIR and $DESTDIR 3916 $IMAGE_PREFIX =~ s/^_//o if ($TMPDIR); 3917 3918 local($dvips_call) = 3919 "$DVIPS -S1 -i $DVIPSOPT -o$TMPDIR$dd$IMAGE_PREFIX .${dd}${PREFIX}images.dvi\n"; 3920 print $dvips_call if (($DEBUG)||($VERBOSITY > 1)); 3921 3922 if ((($PREFIX=~/\./)||($TMPDIR=~/\./)) && not($DVIPS_SAFE)) { 3923 print " *** There is a '.' in $TMPDIR or $PREFIX filename;\n" 3924 . " dvips will fail, so image-generation is aborted ***\n"; 3925 } else { 3926 &close_dbm_database if $DJGPP; 3927 L2hos->syswait($dvips_call) && print "Error: $!\n"; 3928 &open_dbm_database if $DJGPP; 3929 } 3930 3931 # append .ps suffix to the filenames 3932 if(opendir(DIR, $TMPDIR || '.')) { 3933 # use list-context instead; thanks De-Wei Yin <yin@asc.on.ca> 3934 my @ALL_IMAGE_FILES = grep /^$IMAGE_PREFIX\d+$/o, readdir(DIR); 3935 foreach (@ALL_IMAGE_FILES) { 3936 L2hos->Rename("$TMPDIR$dd$_", "$TMPDIR$dd$_.ps"); 3937 } 3938 closedir(DIR); 3939 } else { 3940 print "\nError: Cannot read dir '$TMPDIR': $!\n"; 3941 } 3942 } 3943 do {print "\n\n*** LaTeXERROR"; return()} if ($LaTeXERROR); 3944 return() if ($LaTeXERROR); # empty .dvi file 3945 L2hos->Unlink(".$dd${PREFIX}images.dvi") unless $DEBUG; 3946 3947 print "\n *** updating image cache\n" if ($VERBOSITY > 1); 3948 while ( ($uucontents, $_) = each %cached_env_img) { 3949 delete $cached_env_img{$uucontents} 3950 if ((/$PREFIX$img_rx\.$IMAGE_TYPE/o)&&!($DESTDIR&&$NO_SUBDIR)); 3951 $cached_env_img{$uucontents} = $_ 3952 if (s/$PREFIX$img_rx\.new/$PREFIX$1.$IMAGE_TYPE/go); 3953 } 3954 print "\n *** removing unnecessary images ***\n" if ($VERBOSITY > 1); 3955 while ( ($name, $page_num) = each %id_map) { 3956 $contents = $latex_body{$name}; 3957 if ($page_num =~ /^\d+\#\d+$/) { # If it is a page number 3958 do { # Extract the page, convert and save it 3959 $img = &extract_image($page_num,$orig_name_map{$page_num}); 3960 if ($contents =~ /$htmlimage_rx/) { 3961 $uucontents = &special_encoding($env,$2,$contents); 3962 } elsif ($contents =~ /$htmlimage_pr_rx/) { 3963 $uucontents = &special_encoding($env,$2,$contents); 3964 } else { 3965 $uucontents = &encode(&addto_encoding($contents,$contents)); 3966 } 3967 if (($HTML_VERSION >=3.2)||!($contents=~/$order_sensitive_rx/)){ 3968 $cached_env_img{$uucontents} = $img; 3969 } else { 3970 # Blow it away so it is not saved for next time 3971 delete $cached_env_img{$uucontents}; 3972 print "\nimage $name not recycled, contents may change (e.g. numbering)"; 3973 } 3974 $page_map{$page_num} = $img; 3975 } unless ($img = $page_map{$page_num}); # unless we've just done it 3976 $id_map{$name} = $img; 3977 } else { 3978 $img = $page_num; # it is already available from previous runs 3979 } 3980 print STDOUT " *** image done ***\n" if ($VERBOSITY > 2); 3981 } 3982 &write_warnings( 3983 "\nOne of the images is more than one page long.\n". 3984 "This may cause the rest of the images to get out of sync.\n\n") 3985 if (-f sprintf("%s%.3d%s", $IMAGE_PREFIX, ++$new_page_num, ".ps")); 3986 print "\n *** no more images ***\n" if ($VERBOSITY > 1); 3987 # MRO: The following cleanup seems to be incorrect: The DBM is 3988 # still open at this stage, this causes a lot of unlink errors 3989 # 3990 #do { &cleanup; print "\n *** clean ***\n" if ($VERBOSITY > 1);} 3991 # unless $DJGPP; 3992} 3993 3994# MRO: This copies the navigation icons from the distribution directory 3995# or an alternative specified in $ALTERNATIVE_ICONS 3996# to the document directory. 3997 3998sub copy_icons { 3999 local($icon,$_); 4000 print "\nCopying navigation icons ..."; 4001 foreach (keys %used_icons) { 4002 # each entry ends in gif or png 4003 if ($ALTERNATIVE_ICONS) { 4004 L2hos->Copy("$ALTERNATIVE_ICONS$dd$_", ".$dd$_") 4005 if (-e "$ALTERNATIVE_ICONS$dd$_" && !-e $_); 4006 } elsif (/(gif|png)$/) { 4007 L2hos->Copy("$LATEX2HTMLDIR${dd}icons$dd$_", ".$dd$_") 4008 if (-e "$LATEX2HTMLDIR${dd}icons$dd$_" && !-e $_); 4009 } 4010 } 4011} 4012 4013sub process_log_file { 4014 local($logfile) = @_; 4015 local($name,$before,$lengthsfound); 4016 local($TeXpt)= 72/72.27; 4017 local($image_counter); 4018 open(LOG, "<$logfile") || die "\nCannot read logfile '$logfile': $!\n"; 4019 while (<LOG>) { 4020 if (/Overfull/) { $before .= $_ } 4021 elsif (/latex2htmlLength ([a-zA-Z]+)=(\-?[\d\.]+)pt/) { 4022 ${$1} = 0.0+$2; $lengthsfound = 1; 4023 } elsif (/latex2htmlSize|l2hSize/) { 4024 /:([^:]*):/; 4025 $name = $1; $name =~ s/\*//g; 4026 ++$image_counter; 4027 s/:([0-9.]*)pt/$height{$name} = $1*$TeXpt;''/e; 4028 s/::([0-9.]*)pt/$depth{$name} = $1*$TeXpt;''/e; 4029 s/::([0-9.]*)pt/$width{$name} = $1*$TeXpt;''/e; 4030 s/\((.*)\)/$eqno{$name} = 1+$1;''/e; 4031 if ($before) { 4032 local($tmp); 4033 if ($before =~ /hbox\s*\((\d+\.?\d*)pt/) { 4034 $width{$name} = $width{$name}+$1*$TeXpt; 4035 } 4036 if ($before =~ /vbox\s*\((\d+\.?\d*)pt/) { 4037 $height{$name} = $height{$name}+$1*$TeXpt; 4038 } 4039 $before = ''; 4040 } 4041 } 4042 $LaTeXERROR = 1 if (/^No pages of output./); 4043 } 4044 4045 if ($LaTeXERROR) { 4046 print STDERR "\n\n *** LaTeX produced no output ***\n" 4047 . " *** no new images can be created\n" 4048 . " *** Examine the images.log file.\n\n"; 4049 return; 4050 } 4051 print STDOUT "\n *** processing $image_counter images ***\n"; 4052 print STDOUT "\n *** LATEX LOG OK. ***\n" if ($VERBOSITY > 1); 4053 4054 if ($lengthsfound) { 4055 $ODD_HMARGIN = $hoffset + $oddsidemargin; 4056 $EVEN_HMARGIN = $hoffset + $evensidemargin; 4057 $VMARGIN = $voffset + $topmargin + $headheight + $headsep; 4058 if ($dvi_mag >0 && $dvi_mag != 1000) { 4059 $ODD_HMARGIN = int($dvi_mag /1000 * $ODD_HMARGIN); 4060 $EVEN_HMARGIN = int($dvi_mag /1000 * $EVEN_HMARGIN); 4061 $VMARGIN = int($dvi_mag /1000 * $VMARGIN); 4062 } 4063 } else { 4064 $ODD_HMARGIN = 0; 4065 $EVEN_HMARGIN = 0; 4066 $VMARGIN = 0; 4067 } 4068 $ODD_HMARGIN = int($ODD_HMARGIN*$TeXpt + 72.5); 4069 $EVEN_HMARGIN = int($EVEN_HMARGIN*$TeXpt + 72.5); 4070 $VMARGIN = int($VMARGIN*$TeXpt + 72.5); 4071 close(LOG); 4072} 4073 4074sub extract_image { # clean 4075 my ($page_num,$name) = @_; 4076 4077 # The followin come out of %img_params 4078 my ($scale, $external, $thumbnail, $map, $psimage, $align, $usemap, 4079 $flip, $aalias, $trans, $exscale, $alt, $exstr); 4080 4081 my ($lwidth, $val) = (0, ''); 4082 my ($custom_size,$color_depth,$height,$width,$croparg); 4083 4084 print STDOUT "\nextracting $name as $page_num\n" if ($VERBOSITY > 1); 4085 # $global_num identifies this image in the original source file 4086 # $new_num identifies this image in images.tex 4087 my ($global_num, $new_num) = split(/#/, $page_num); 4088 $name =~ s/\*/star/; 4089 my ($env,$basename,$img) = ($name,"img$global_num",''); 4090 $env =~ s/\d+$//; 4091 $psname = sprintf("%s%.3d", "$TMPDIR$dd$IMAGE_PREFIX", $new_num); 4092 if ( $EXTERNAL_IMAGES && $PS_IMAGES ) { 4093 $img = "$basename.ps"; 4094 L2hos->Copy("$psname.ps", "${PREFIX}$img"); 4095 } else { 4096 $img = "$basename.$IMAGE_TYPE"; 4097 ($scale, $external, $thumbnail, $map, $psimage, $align, $usemap, 4098 $flip, $aalias, $trans, $exscale, $alt, $exstr) = 4099 split('#', $img_params{$name}); 4100 $lwidth = ($align =~ s/nojustify/middle/) ? 0 : $LINE_WIDTH; 4101 $alt = "ALT=\"$name\"" unless $alt; 4102 $exscale = $EXTRA_IMAGE_SCALE unless($exscale); 4103 if ($NO_IMAGES) { 4104 L2hos->Symlink("image.$IMAGE_TYPE", "${PREFIX}$img"); 4105 if ($thumbnail) { 4106 L2hos->Symlink("image.$IMAGE_TYPE", "${PREFIX}T$img"); 4107 $thumbnail = "${PREFIX}T$img"; 4108 } 4109 } else { 4110 # RRM: deal with size data 4111 if ($width{$name} < 0) { 4112 if ($exscale && $PK_GENERATION) { 4113 $height = int( 4114 $exscale*$height{$name}+ 4115 $exscale*$depth{$name} +.5); 4116 $width = int($exscale*$width{$name}-.5); 4117 } else { 4118 $height = int($height{$name}+$depth{$name}+.5); 4119 $width = int($width{$name}-.5); 4120 } 4121 $custom_size = "${width}x$height"; 4122 } elsif ($width{$name}) { 4123 if ($exscale && $PK_GENERATION) { 4124 $height = int( $height{$name} * $exscale + 4125 $depth{$name} * $exscale +.5); 4126 $width = int($width{$name} * $exscale +.5); 4127 } else { 4128 $height = int($height{$name}+$depth{$name}+.5); 4129 $width = int($width{$name}+.5); 4130 } 4131 $custom_size = "${width}x$height"; 4132 } else { 4133 $custom_size = ''; 4134 } 4135 # MRO: add first overall crop 4136 $croparg = '-crop a' . ($crop{$name} || '') . ' '; 4137 $page_num =~ s/^\d+#//o; 4138 $custom_size .= " -margins " 4139 . (($page_num % 2) ? $ODD_HMARGIN:$EVEN_HMARGIN) 4140 . ",$VMARGIN" if ($custom_size); 4141 4142 #RRM: \special commands may place ink outside the expected bounds: 4143 $custom_size = '' if ($tex_specials{$name}); 4144 4145 # MRO: Patches for image conversion with pstoimg 4146 # RRM: ...with modifications and fixes 4147 L2hos->Unlink("${PREFIX}$img"); 4148 &close_dbm_database if $DJGPP; 4149 print "Converting image #$new_num\n"; 4150 4151 if ( ($name =~ /figure/) || $psimage || $scale || $thumbnail) { 4152 $scale = $FIGURE_SCALE_FACTOR unless ($scale); 4153 print "\nFIGURE: $name scaled $scale $aalias\n" if ($VERBOSITY > 2); 4154 (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE " 4155 . ($DEBUG ? '-debug ' : '-quiet ' ) 4156 . ($TMPDIR ? "-tmp $TMPDIR " : '' ) 4157 . (($DISCARD_PS && !$thumbnail && !$psimage)? "-discard " :'') 4158 . (($INTERLACE) ? "-interlace " : '' ) 4159 . (((($ANTI_ALIAS)||($aalias))&&($aalias !~ /no|text/))? "-antialias ":'') 4160 . (($ANTI_ALIAS_TEXT||(($aalias =~/text/)&&($aalias !~/no/)))? 4161 "-aaliastext ":'') 4162 . (($custom_size) ? "-geometry $custom_size ": '' ) 4163 . $croparg 4164 . ($color_depth || '') 4165 . (($flip) ? "-flip $flip " : '' ) 4166 . (($scale > 0) ? "-scale $scale " : '' ) 4167 . (((($TRANSPARENT_FIGURES && ($env =~ /figure/o))||($trans)) 4168 &&(!($trans =~ /no/))) ? "-transparent " : '') 4169 . (($WHITE_BACKGROUND) ? "-white " : '' ) 4170 . "-out ${PREFIX}$img $psname.ps" 4171 ) ) # ||!(print "\nWriting image: ${PREFIX}$img")) 4172 && print "\nError while converting image: $!\n"; 4173 4174 if ($thumbnail) { # $thumbnail contains the reduction factor 4175 L2hos->Unlink("${PREFIX}T$img"); 4176 print "\nIMAGE thumbnail: $name" if ($VERBOSITY > 2); 4177 (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE " 4178 . ($DEBUG ? '-debug ' : '-quiet ' ) 4179 . ($TMPDIR ? "-tmp $TMPDIR " : '' ) 4180 . (($DISCARD_PS && !$psimage) ? "-discard " : '' ) 4181 . (($INTERLACE) ? "-interlace " : '' ) 4182 . ((($ANTI_ALIAS||($aalias))&&(!($aalias =~/no/)))? "-antialias " :'') 4183 . (($ANTI_ALIAS_TEXT||(($aalias =~/text/)&&($aalias !~/no/)))? 4184 "-aaliastext ":'') 4185 . (($custom_size) ? "-geometry $custom_size " : '' ) 4186 . ($color_depth || '') 4187 . (($flip) ? "-flip $flip " : '' ) 4188 . (($thumbnail > 0) ? "-scale $thumbnail " : '' ) 4189 . ((($trans)&&(!($trans =~ /no/))) ? "-transparent " : '') 4190 . (($WHITE_BACKGROUND) ? "-white " : '' ) 4191 . "-out ${PREFIX}T$img $psname.ps" 4192 ) ) # ||!(print "\nWriting image: ${PREFIX}T$img")) 4193 && print "\nError while converting thumbnail: $!\n"; 4194 $thumbnail = "${PREFIX}T$img"; 4195 } 4196 } elsif (($exscale &&(!$PK_GENERATION))&&($width{$name})) { 4197 my $under = ''; 4198 my $mathscale = ($MATH_SCALE_FACTOR > 0) ? $MATH_SCALE_FACTOR : 1; 4199 if (($DISP_SCALE_FACTOR > 0) && 4200 ( $name =~ /equation|eqnarray|display/)) 4201 { $mathscale *= $DISP_SCALE_FACTOR; }; 4202 if ($scale) { 4203 $scale *= $exscale if ($name =~ /makeimage|tab/); 4204 } else { 4205 $scale = $mathscale*$exscale; 4206 $under = "d" if (($name =~/inline|indisplay/)&&($depth{$name})); 4207 } 4208 print "\nIMAGE: $name scaled by $scale \n" if ($VERBOSITY > 2); 4209 (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE " 4210 . ($DEBUG ? '-debug ' : '-quiet ' ) 4211 . ($TMPDIR ? "-tmp $TMPDIR " : '' ) 4212 . (($DISCARD_PS)? "-discard " : '' ) 4213 . (($INTERLACE)? "-interlace " : '' ) 4214 . ((($ANTI_ALIAS_TEXT||($aalias))&&($aalias !=~/no/))? 4215 "-antialias -depth 1 " :'') 4216 . (($custom_size)? "-geometry $custom_size " : '' ) 4217 . $croparg 4218 . (($scale != 1)? "-scale $scale " : '' ) 4219 . ((($exscale)&&($exscale != 1)&& 4220 !($ANTI_ALIAS_TEXT &&($LATEX_COLOR)))? 4221 "-shoreup $exscale$under " :'') 4222 . ((($TRANSPARENT_FIGURES ||($trans)) 4223 &&(!($trans =~ /no/)))? "-transparent " : '') 4224 . (($WHITE_BACKGROUND && !$TRANSPARENT_FIGURES) ? "-white " : '' ) 4225 . "-out ${PREFIX}$img $psname.ps" 4226 ) ) # ||!(print "\nWriting image: ${PREFIX}$img")) 4227 && print "\nError while converting image: $!\n"; 4228 } else { 4229 print "\nIMAGE: $name\n" if ($VERBOSITY > 2); 4230 my $under = ''; 4231 my $mathscale = ($MATH_SCALE_FACTOR > 0) ? $MATH_SCALE_FACTOR : 1; 4232 if (($DISP_SCALE_FACTOR > 0) && 4233 ( $name =~ /equation|eqnarray|display/)) 4234 { $mathscale *= $DISP_SCALE_FACTOR; }; 4235 if (($scale)&&($exscale)) { 4236 $scale *= $exscale if ($name =~ /makeimage|tab/); 4237 } elsif ($scale) { 4238 } elsif (($mathscale)&&($exscale)) { 4239 $scale = $mathscale*$exscale; 4240 $under = "d" if (($name =~/inline|indisplay/)&&($depth{$name})); 4241 } elsif ($mathscale) { $scale = $mathscale; } 4242 4243 (L2hos->syswait("$PSTOIMG -type $IMAGE_TYPE " 4244 . ($DEBUG ? '-debug ' : '-quiet ' ) 4245 . ($TMPDIR ? "-tmp $TMPDIR " : '' ) 4246 . (($DISCARD_PS) ? "-discard " : '' ) 4247 . (($INTERLACE) ? "-interlace " : '' ) 4248 . ((($ANTI_ALIAS_TEXT||($aalias))&&(!($aalias =~ /no/)))? 4249 "-antialias -depth 1 " :'') 4250 . ((($exscale)&&($exscale != 1)&& 4251 !($ANTI_ALIAS_TEXT &&($LATEX_COLOR)))? 4252 "-shoreup $exscale " :'') 4253 . (($scale ne 1) ? "-scale $scale " : '' ) 4254 . (($custom_size) ? "-geometry $custom_size " : '' ) 4255 . $croparg 4256# . (($name =~ /(equation|eqnarray)/) ? "-rightjustify $lwidth " : '') 4257# . (($name =~ /displaymath/) ? "-center $lwidth " : '') 4258 . (($name =~ /inline|indisplay/ && (!($custom_size))&&$depth{$name}!= 0) ? 4259 do {$val=($height{$name}-$depth{$name})/($height{$name}+$depth{$name}); 4260 "-topjustify x$val "} : '') 4261 . ((($TRANSPARENT_FIGURES||($trans)) 4262 &&(!($trans =~ /no/))) ? "-transparent " : '') 4263 . (($WHITE_BACKGROUND && !$TRANSPARENT_FIGURES) ? "-white " : '' ) 4264 . "-out ${PREFIX}$img $psname.ps") 4265 ) #|| !(print "\nWriting image: ${PREFIX}$img")) 4266 && print "\nError while converting image\n"; 4267 } 4268 if (! -r "${PREFIX}$img") { 4269 &write_warnings("\nFailed to convert image $psname.ps") 4270 } else { } #L2hos->Unlink("$psname.ps") unless $DEBUG } 4271 &open_dbm_database if $DJGPP; 4272 } 4273 } 4274 print "\nextracted $name as $page_num\n" if ($VERBOSITY > 1); 4275 &embed_image("${PREFIX}$img", $name, $external, $alt, $thumbnail, $map, 4276 $align, $usemap, $exscale, $exstr); 4277} 4278 4279sub extract_parameters { 4280 local($contents) = @_; 4281 local($_, $scale, $external, $thumbnail, $map, $psimage, $align, 4282 $usemap, $flip, $aalias, $trans, $pagecolor, $alt, $exscale, 4283 $cdepth, $htmlparams); 4284 4285 #remove the \htmlimage commands and arguments before... 4286 $contents =~ s/$htmlimage_rx/$_ = $2;''/ego; 4287 $contents =~ s/$htmlimage_pr_rx/$_ .= $2;''/ego; 4288 4289 # code adapted from original idea by Stephen Gildea: 4290 # If the document specifies the ALT tag explicitly 4291 # with \htmlimage{alt=some text} then use it. 4292 s!alt=([^,]+)!$alt = $1; 4293 $alt =~ s/^\s+|\s+$//g; $alt =~ s/"//g; 4294 $alt="ALT=\"$alt\""; 4295 ''!ie; 4296 4297 if (!$alt) { 4298 #...catching all the code for the ALT text. 4299 local($keep_gt)=1; 4300 $alt = &flatten_math($contents); undef $keep_gt; 4301 #RRM: too long strings upset the DBM. Truncate to <= 165 chars. 4302 if ( length($alt) > 163 ) { 4303 local($start,$end); 4304 $start = substr($alt,0,80); 4305 $end = substr($alt,length($alt)-80,80); 4306 $alt = join('',$start,"...\n ...",$end); 4307 } 4308 s/ALT\s*=\"([\w\W]*)\"/$alt=$1;''/ie; 4309 if ($alt) { 4310 if ($alt =~ /\#/) { 4311 $alt =~ s/^(\\vbox\{)?\#[A-Za-z]*\s*//; 4312 $alt =~ s/\n?\#[A-Za-z]*\s*\}?$//s; 4313 if ($alt =~ /\#/) { $alt = $` . " ... " }; 4314 } 4315 $alt =~ s/\`\`/\\lq\\lq /g; $alt =~ s/\`/\\lq /g; 4316 $alt =~ s/(^\s*|\s*$)//mg; 4317 $alt = "ALT=\"$alt\"" if ($alt); 4318 } else { $alt = 'ALT="image"' } 4319 } 4320 4321 $psimage++ if ($contents =~ /\.ps/); 4322# $contents =~ s/\s//g; # Remove spaces Why ? 4323 s/extrascale=([\.\d]*)/$exscale=$1;''/ie; 4324 s/\bscale=([\.\d]*)/$scale=$1;''/ie; 4325 s/(^|,\s*)external/$external=1;''/ie; 4326 s/(^|,\s*)((no)?_?anti)alias(_?(text))?/$aalias = $2.$4;''/ie; 4327 s/(^|,\s*)((no)?_?trans)parent/$trans = $2;''/ie; 4328 s/thumbnail=([\.\d]*)/$thumbnail=$1;''/ie; 4329 s/usemap=([^\s,]+)/$usemap=$1;''/ie; 4330 s/map=([^\s,]+)/;$map=$1;''/ie; 4331 s/align=([^\s,]+)/$align=$1;''/ie; 4332 s/flip=([^\s,]+)/$flip=$1;''/ie; 4333 s/color_?(depth)?=([^\s,]+)/$cdepth=$2;''/ie; 4334 ($scale,$external,$thumbnail,$map,$psimage,$align 4335 ,$usemap,$flip,$aalias,$trans,$exscale,$alt,$_); 4336} 4337 4338 4339# RRM: Put the raw \TeX code into the ALT tag 4340# replacing artificial environments and awkward characters 4341sub flatten_math { 4342 local ($_) = @_; 4343 $_ = &revert_to_raw_tex($_); 4344 s/[ \t]+/ /g; 4345 # MRO: replaced $* with /m 4346 s/$tex2html_wrap_rx//gm; 4347 s/(\\begin\s*\{[^\}]*\})(\s*(\[[^]]*\]))?[ \t]*/$1$3/gm; 4348 s/(\\end\{[^\}]*\})\n?/$1/gm; 4349 s/>(\w)?/($1)?"\\gt $1":"\\gt"/eg unless ($keep_gt); # replace > by \gt 4350 s/\\\|(\w)?/($1)?"\\Vert $1":"\\Vert"/eg; # replace \| by \Vert 4351 s/\|(\w)?/($1)?"\\vert $1":"\\vert"/eg; # replace | by \vert 4352 s/\\\\/\\\\ /g; # insert space after \\ 4353 s/\\"/\\uml /g; # screen umlaut accents... 4354 s/"/\'\'/g; # replace " by '' 4355 s/\\\#/\\char93 /g; # replace \# by \char93 else caching fails 4356# s/"(\w)?/($1)?"\\rq\\rq $1":"\'\'"/eg; # replace " by \rq\rq 4357# s/\&\\uml /\\\"/g; # ...reinstate umlauts 4358 $_; 4359} 4360 4361sub scaled_image_size { 4362 local($exscale,$_) = @_; 4363 local($width,$height) = ('',''); 4364 /WIDTH=\"?(\d*)\"?\s*HEIGHT=\"?(\d*)\"?$/o; 4365 $width=int($1/$exscale + .5); 4366 $height=int($2/$exscale + .5); 4367 "WIDTH=\"$width\" HEIGHT=\"$height\"" 4368} 4369 4370sub process_in_latex { 4371 # This is just a wrapper for process_undefined_environment. 4372 # @[0] = contents 4373 $global{'max_id'}++; 4374 &process_undefined_environment('tex2html_wrap',$global{'max_id'},$_[0]); 4375} 4376 4377# MRO: cp deprecated, replaced by L2hos->Copy 4378 4379# Marcus Hennecke 6/3/96 4380# MRO: test for existance 4381sub copy_file { 4382 local($file, $ext) = @_; 4383 $file = &fulltexpath("$FILE.$ext"); 4384 if(-r $file) { 4385 print "\nNote: Copying '$file' for image generation\n" 4386 if($VERBOSITY > 2); 4387 L2hos->Copy($file, ".$dd${PREFIX}images.$ext"); 4388 } 4389} 4390 4391sub rename_image_files { 4392 local($_, $old_name, $prefix); 4393 if ($PREFIX) { 4394 foreach (<${PREFIX}*img*.$IMAGE_TYPE>) { 4395 $old_name = $_; 4396 s/\.$IMAGE_TYPE$/\.old/o; 4397 L2hos->Rename($old_name, $_); 4398 } 4399 } 4400 else { 4401 foreach (<img*.$IMAGE_TYPE>) { 4402 $old_name = $_; 4403 s/\.$IMAGE_TYPE$/\.old/o; 4404 L2hos->Rename($old_name, $_); 4405 } 4406 foreach (<Timg*.$IMAGE_TYPE>) { 4407 $old_name = $_; 4408 s/\.$IMAGE_TYPE$/\.old/o; 4409 L2hos->Rename($old_name, $_); 4410 } 4411 } 4412} 4413 4414 4415############################ Processing Commands ########################## 4416 4417sub ignore_translate_commands { 4418 local ($_) = @_; 4419# print "\nTranslating commands ..."; 4420 4421 local(@processedC); 4422 &replace_strange_accents; 4423 local($before, $contents, $br_id, $after, $pattern, $end_cmd_rx); 4424 s/$begin_cmd_rx/&replace_macro_expansion($`, $1, $&, $')/eg; 4425} 4426 4427sub replace_macro_expansion { 4428 push(@processedC,$_[1]); 4429 $end_cmd_rx = &make_end_cmd_rx($_[2]); 4430 $pattern = $_[3]; 4431 $_ = join('',$_[3],$_[4]); 4432 $after = $_[4]; 4433 if (($before)&&(!($before =~ /$begin_cmd_rx/))) { 4434 push(@processedC,$before); 4435 $_ = join('',$pattern,$after); $before = ''; 4436 } 4437 local($end_cmd_rx) = &make_end_cmd_rx($br_id); 4438 4439} 4440 4441sub translate_aux_commands { 4442 s/^(.*)$/&translate_commands($1)/s; 4443} 4444 4445sub translate_commands { 4446 local ($_) = @_; 4447# print "\nTranslating commands ..."; 4448 4449 local(@processedC); 4450 &replace_strange_accents; 4451 for (;;) { # For each opening bracket ... 4452 last unless ($_ =~ /$begin_cmd_rx/); 4453 local($before, $contents, $br_id, $after, $pattern); 4454 ($before, $br_id, $after, $pattern) = ($`, $1, $', $&); 4455 if (($before)&&(!($before =~ /$begin_cmd_rx/))) { 4456 push(@processedC,$before); 4457 $_ = join('',$pattern,$after); $before = ''; 4458 } 4459 local($end_cmd_rx) = &make_end_cmd_rx($br_id); 4460 if ($after =~ /$end_cmd_rx/) { # ... find the the matching closing one 4461 $NESTING_LEVEL++; 4462 ($contents, $after) = ($`, $'); 4463 do { 4464 local(@save_open_tags) = @$open_tags_R; 4465 local($open_tags_R) = [ @save_open_tags ]; 4466 print STDOUT "\nIN::{$br_id}" if ($VERBOSITY > 4); 4467 print STDOUT "\n:$contents\n" if ($VERBOSITY > 7); 4468 undef $_; 4469 $contents = &translate_commands($contents) 4470 if ($contents =~ /$match_br_rx/o); 4471 # Modifies $contents 4472 &process_command($single_cmd_rx,$contents) 4473 if ($contents =~ /\\/o); 4474 4475 $contents .= &balance_tags(); 4476 }; 4477 4478 print STDOUT "\nOUT: {$br_id}" if ($VERBOSITY > 4); 4479 print STDOUT "\n:$contents\n" if ($VERBOSITY > 7); 4480 # THIS MARKS THE OPEN-CLOSE DELIMITERS AS PROCESSED 4481 $_ = join("", $before,"$OP$br_id$CP", $contents,"$OP$br_id$CP", $after); 4482 $NESTING_LEVEL--; 4483 } 4484 else { 4485 $pattern = &escape_rx_chars($pattern); 4486 s/$pattern//; 4487 print "\nCannot find matching bracket for $br_id" unless $AUX_FILE; 4488 } 4489 last unless ($_ =~ /$begin_cmd_rx/o); 4490 } 4491 $_ = join('',@processedC) . $_; 4492 # Now do any top level commands that are not inside any brackets 4493 # MODIFIES $_ 4494 print $_ if ($VERBOSITY > 8); 4495 &process_command($single_cmd_rx,$_); 4496} 4497 4498#RRM: based on earlier work of Marcus Hennecke 4499# makes sure the $open_tags_R at the end of an environment 4500# is the same as @save_open_tags from the start, 4501# ensuring that the HTML page indeed has balanced tags 4502sub balance_tags { 4503 local($tag_cmd, $tags, $save_tags, $open_tags, @reopen_tags); 4504 $save_tags = join(',',@save_open_tags) if (@save_open_tags); 4505 $open_tags = join(',',@$open_tags_R) if (@$open_tags_R); 4506 if ($open_tags eq $save_tags) { return(); } 4507 if ($save_tags =~ s/^$open_tags//) { 4508 @reopen_tags = split (',',$'); 4509 } else { 4510 @reopen_tags = @save_open_tags; 4511 while (@$open_tags_R) { 4512 $tag_cmd = pop (@$open_tags_R); 4513 print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2; 4514 $declarations{$tag_cmd} =~ m|</.*$|; 4515 $tags .= $& unless ($` =~ /^<>$/); 4516 $open_tags = join(',',@$open_tags_R) if (@$open_tags_R); 4517 last if ( $save_tags =~ s/^$open_tags/ 4518 @reopen_tags = split (',',$');''/e); 4519 } 4520 } 4521 while (@reopen_tags) { 4522 $tag_cmd = shift @reopen_tags; 4523 if ($tag_cmd) { 4524 push (@$open_tags_R, $tag_cmd) if ($tag_cmd); 4525 print STDOUT "\n<$tag_cmd>" if $VERBOSITY > 2; 4526 $declarations{$tag_cmd} =~ m|</.*$|; 4527 $tags .= $` unless ($` =~ /^<>$/); 4528 } 4529 } 4530 $tags; 4531} 4532 4533sub close_all_tags { 4534 return() if (!@$open_tags_R); 4535 local($tags,$tag_cmd); 4536 while (@$open_tags_R) { 4537 $tag_cmd = pop (@$open_tags_R); 4538 print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2; 4539 $declarations{$tag_cmd} =~ m|</.*$|; 4540 $tags .= $& unless ($` =~ /^<>$/); 4541 } 4542 $tags; 4543} 4544 4545sub preserve_open_tags { 4546 local(@save_open_tags) = @$open_tags_R; 4547 local($open_tags_R) = [ @save_open_tags ]; 4548 # provides the markup to close and reopen the current tags 4549 (&close_all_tags(), &balance_tags()); 4550} 4551 4552sub preserve_open_block_tags { 4553 local($tag_cmd,$tags_open,$tags_close,$pre,$post,@tags); 4554 while (@$open_tags_R) { 4555 $tag_cmd = pop (@$open_tags_R); 4556 print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2; 4557 $declarations{$tag_cmd} =~ m|</.*$|; 4558 ($pre,$post) = ($`,$&); 4559 if ($post =~ /$block_close_rx/) { 4560 # put it back and exit 4561 push(@$open_tags_R,$tag_cmd); 4562 last; 4563 } else { 4564 # leave it closed, collecting tags for it 4565 $tags_close .= $post; 4566 $tags_open = $pre . $tags_open; 4567 unshift(@tags,$tag_cmd); 4568 } 4569 } 4570 ($tags_close , $tags_open, @tags); 4571} 4572 4573sub minimize_open_tags { 4574 local($this_tag, $close_only) = @_; 4575 local($pre,$post,$decl); 4576 $decl = $declarations{$this_tag}; 4577 if ($decl) { 4578 # if it is a declaration, get the corresponding tags... 4579 $decl =~ m|</.*$|; 4580 ($pre,$post) = ($`,$&) unless ($` =~ /^<>$/); 4581 if (!@$open_tags_R) { # when nothing else is open... 4582 # pushing the style, when appropriate 4583 push (@$open_tags_R, $this_tag) 4584 unless ($close_only ||($post =~ /$block_close_rx/)); 4585 print STDOUT "\n<$this_tag>" if $VERBOSITY > 2; 4586 # and return the tags 4587 return($pre,$post) unless ($USING_STYLES); 4588 local($env_id) = '' if ($env_id =~/^\w+$/); 4589 $pre =~ s/>$/ $env_id>/ if ($env_id); 4590 return($pre,$post); 4591 } 4592 } else { # ...else record the argument as $pre 4593 $pre = $this_tag unless $close_only; 4594 } 4595 local($env_id) = '' if ($env_id =~/^\w+$/); 4596 $pre =~ s/>$/ ID="$env_id">/ if ($USING_STYLES &&($env_id)); 4597 4598 # return the tags, if nothing is already open 4599 if (!@$open_tags_R) { 4600 return($pre,$post); 4601 } 4602# elsif ($close_only) { push (@$open_tags_R, $this_tag) } 4603 4604 local($tags,$tag_cmd,$tag_open); 4605 local($closures,$reopens,@tags); 4606 local($tag_close,$tag_open); 4607 local($size_cmd,$size_open); 4608 local($font_cmd,$font_open); 4609 local($fontwt_cmd,$fontwt_open); 4610 local($color_cmd,$color_open); 4611 if ($decl) { 4612 if ($this_tag =~ /$sizechange_rx/) { 4613 $size_cmd = $this_tag; 4614 } else { 4615 if ($this_tag =~ /$fontchange_rx/) { 4616 $font_cmd = $this_tag } 4617 if ($this_tag =~ /$fontweight_rx/) { 4618 $fontwt_cmd = $this_tag } 4619 } 4620 } 4621 while (@$open_tags_R) { 4622 ($tag_close,$tag_open) = ('',''); 4623 $tag_cmd = pop (@$open_tags_R); 4624 print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2; 4625 $declarations{$tag_cmd} =~ m|</.*$|; 4626 ($tag_close,$tag_open) = ($&,$`) unless ($` =~ /<>/); 4627 $closures .= $tag_close; 4628 4629 if ((!$size_cmd)&&($tag_cmd =~ /$sizechange_rx/)) { 4630 $size_cmd = $tag_cmd; 4631 $size_open = $tag_open; 4632 } 4633 elsif ((!$font_cmd)&&($tag_cmd =~ /$fontchange_rx/)) { 4634 $font_cmd = $tag_cmd; 4635 $font_open = $tag_open; 4636 } 4637 elsif ((!$fontwt_cmd)&&($tag_cmd =~ /$fontweight_rx/)) { 4638 $fontwt_cmd = $tag_cmd; 4639 $fontwt_open = $tag_open; 4640 } 4641 elsif ((!$color_cmd)&&($tag_cmd =~ /$colorchange_rx/)) { 4642 $color_cmd = $tag_cmd; 4643 $color_open = $tag_open; 4644 } 4645 elsif ($tag_cmd =~ 4646 /$sizechange_rx|$fontchange_rx|$fontweight_rx|$colorchange_rx/) { 4647 } else { 4648 unshift (@tags, $tag_cmd); 4649 print STDOUT "\n<<$tag_cmd>" if $VERBOSITY > 2; 4650 $reopens = $tag_open . $reopens; 4651 } 4652 } 4653 if ($USING_STYLES) { 4654 local($TAG) = "DIV"; 4655 if ($pre =~ /^<(DIV|SPAN|PRE)/) { $TAG = $1 }; 4656 if (($pre =~ /^<$TAG/)&&($env_id =~ /^\s+(CLASS|ID)/)) { 4657 $pre =~ s/<$TAG/<$TAG$env_id/; 4658 } elsif ($pre =~ /<P>/) { 4659 $TAG = 'P'; 4660 } else { 4661 } 4662# $post .= "</$TAG>"; 4663 } 4664 push (@$open_tags_R, @tags); 4665 $tags .= $pre if ($pre && $post =~ /$block_close_rx/); 4666 if ($font_cmd && !($font_cmd eq $this_tag)) { 4667 push (@$open_tags_R,$font_cmd); 4668 print STDOUT "\n<$font_cmd>" if $VERBOSITY > 2; 4669 $tags .= $font_open; 4670 } 4671 if ($fontwt_cmd && !($fontwt_cmd eq $this_tag)) { 4672 push (@$open_tags_R,$fontwt_cmd); 4673 print STDOUT "\n<$fontwt_cmd>" if $VERBOSITY > 2; 4674 $tags .= $fontwt_open; 4675 } 4676 if ($size_cmd && !($size_cmd eq $this_tag)) { 4677 push (@$open_tags_R,$size_cmd); 4678 print STDOUT "\n<$size_cmd>" if $VERBOSITY > 2; 4679 $tags .= $size_open; 4680 } 4681 if ($color_cmd && !($color_cmd eq $this_tag)) { 4682 push (@$open_tags_R,$color_cmd); 4683 print STDOUT "\n<$color_cmd>" if $VERBOSITY > 2; 4684 $tags .= $color_open; 4685 } 4686 $tags .= $pre unless ($pre && $post =~ /$block_close_rx/); 4687 push (@$open_tags_R, $this_tag) 4688 if ($decl &&!($post =~ /$block_close_rx|$all_close_rx/)); 4689 print STDOUT "\n<$this_tag>" if $VERBOSITY > 2; 4690 ($closures.$reopens.$tags , $post ); 4691} 4692 4693 4694sub declared_env { 4695 local($decl, $_, $deferred) = @_; 4696 local($after_cell,$pre,$post); 4697 local($decls) = $declarations{$decl}; 4698 $decls =~ m|</.*$|; 4699 ($pre,$post) = ($`,$&); 4700 if ($USING_STYLES) { 4701 $env_style{$decl} = " " unless ($env_style{$decl}); 4702 $pre =~ s/>$/$env_id>/ if ($env_id); 4703 } 4704 local($closing_tag) = 1 if ($pre =~ /^<>$/); 4705 $pre = $post = '' if $closing_tag; 4706 local($closures,$reopens); 4707 4708 local(@save_open_tags) = @$open_tags_R 4709 unless ($closing_tag || $deferred); 4710 local($open_tags_R) = [ @save_open_tags ] 4711 unless ($closing_tag || $deferred ); 4712 4713 if ($post =~ /$block_close_rx/) { 4714 local($last_tag) = pop (@$open_tags_R); 4715 local($ldecl) = $declarations{$last_tag}; 4716 if ($ldecl =~ m|</.*$|) { $ldecl = $& } 4717 if (($last_tag)&&!($ldecl =~ /$block_close_rx/)) { 4718 # need to close tags, for re-opening inside 4719 push (@$open_tags_R, $last_tag); 4720 ($closures,$reopens) = &preserve_open_tags(); 4721 $pre = join('', $closures, "\n", $pre, $reopens); 4722 $post = join('', $closures, $post, $reopens); 4723 } elsif ($last_tag) { 4724 $pre = "\n".$pre; 4725 push (@$open_tags_R, $last_tag); 4726 undef $ldecl; 4727 } else { 4728 } 4729 4730 if ($deferred) { 4731 if (defined $ldecl) { 4732 print STDOUT "\n<<$decl>" if $VERBOSITY > 2; 4733 unshift(@$open_tags_R, $decl); 4734 } else { 4735 print STDOUT "\n<$decl>" if $VERBOSITY > 2; 4736 push(@$open_tags_R, $decl); 4737 } 4738 return ( $pre . $_ ); 4739 } else { 4740 if (defined $ldecl) { 4741 print STDOUT "\n<<$decl>" if $VERBOSITY > 2; 4742 unshift(@$open_tags_R, $decl); 4743 } else { 4744 print STDOUT "\n<$decl>" if $VERBOSITY > 2; 4745 push(@$open_tags_R, $decl); 4746 } 4747 } 4748 } elsif ($post =~/$all_close_rx/) { 4749 ($closures,$reopens) = &preserve_open_tags(); 4750 ($pre,$post) = &minimize_open_tags($decl,1); 4751 $pre = join('', $closures, $pre); 4752 } elsif ($closing_tag) { 4753 $prev_open = $pre; 4754 ($pre,$post) = &minimize_open_tags($decl,1); 4755 $pre =~ s/<\/?>//g; $post =~ s/<\/?>//; 4756 } else { 4757 ($pre,$post) = &minimize_open_tags($decl); 4758 } 4759 $_ =~ s/^\s+//s; #RRM:28/4/99 remove spaces at the beginning 4760 $_ = &translate_environments($_); 4761 $_ = &translate_commands($_) if (/\\/); 4762 if ($post =~ /$block_close_rx/) { 4763 s/^\n?/\n/o; 4764 if (defined $ldecl) { 4765 $post = &close_all_tags(); 4766 } else { 4767 $post = "\n"; 4768 } 4769 } elsif ($post =~/$all_close_rx/) { 4770 } else { $post = '' }; 4771 4772 join('', $pre, $_, $post 4773 , ($closing_tag ? '' : &balance_tags()) ); 4774} 4775 4776sub do_cmd_centering{&declared_env('center',$_[0],$tex2html_deferred)} 4777sub do_cmd_raggedright{&declared_env('flushleft',$_[0],$tex2html_deferred)} 4778sub do_cmd_raggedleft{&declared_env('flushright',$_[0],$tex2html_deferred)} 4779 4780sub do_env_verse { &declared_env('verse',@_) } 4781sub do_env_quote { &declared_env('quote', @_) } 4782sub do_env_quotation { &declared_env('quote', @_) } 4783sub do_env_tex2html_preform { &declared_env('preform', @_) } 4784sub do_env_tex2html_ord { &declared_env('ord', @_) } 4785sub do_env_tex2html_unord { &declared_env('unord', @_) } 4786sub do_env_tex2html_desc { &declared_env('desc', @_) } 4787 4788 4789# Modifies $contents 4790sub process_command { 4791 # MRO: modified to use $_[1] 4792 # local ($cmd_rx, *ref_contents) = @_; 4793 local ($cmd_rx) = @_; 4794 local($ref_before, $cmd , $pc_after); 4795 local($cmd_sub, $cmd_msub, $cmd_trans, $mathentity); 4796 local (@open_font_tags,@open_size_tags); 4797 $_[1] = &convert_iso_latin_chars($_[1]) 4798 unless (($cmd =~ /(Make)?([Uu]pp|[Ll]ow)ercase/)|| 4799 ((!$cmd)&&($_[1] =~ /^\\(Make)?([Uu]pp|[Ll]ow)ercase/s))); 4800 4801 local(@ref_processed); 4802 for (;;) { # Do NOT use the o option 4803 last unless ($_[1] =~ /$cmd_rx/ ); 4804 print "."; 4805 #JCL(jcl-del) - use new regexp form which handles white space 4806 ($ref_before, $cmd, $pc_after) = ($`, $1.$2, $4.$'); 4807 push(@ref_processed,$ref_before); 4808#print "\nAFTER:$1.$2:".$4."\n" if ($cmd_rx eq $single_cmd_rx); 4809 print STDOUT "$cmd" if ($VERBOSITY > 2); 4810 print STDOUT "\nIN: $_[1]\n" if ($VERBOSITY > 6); 4811 # 4812 if ( $cmd = &normalize($cmd,$pc_after) ) { 4813 ($cmd_sub, $cmd_msub, $cmd_trans, $mathentity) = 4814 ("do_cmd_$cmd", "do_math_cmd_$cmd" 4815 , $declarations{$cmd}, $mathentities{$cmd}); 4816 if ($new_command{$cmd}||$renew_command{$cmd}) { 4817 # e.g. some \the$counter 4818 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 4819 &make_unique($body) if ($body =~ /$O/); 4820 if ($argn) { 4821 do { 4822 local($before) = ''; 4823 local($_) = "\\$cmd ".$pc_after; 4824 # &substitute_newcmd may need what comes after the $cmd 4825 # from the value of $after 4826 #RRM: maybe best to pass it as a parameter ? 4827 my $keep_after = $after; 4828 $after = $pc_after; 4829 $pc_after = &substitute_newcmd; # may change $after 4830 $pc_after =~ s/\\\@#\@\@/\\/o ; 4831 $pc_after .= $after; 4832 $after = $keep_after; 4833 } 4834 } else { 4835 $pc_after = $body . $pc_after; 4836 } 4837 } elsif (defined &$cmd_sub) { 4838 # $ref_before may also be modified ... 4839 if ($cmd =~ /$sizechange_rx/o) { 4840 $pc_after = &$cmd_sub($pc_after, $open_tags_R); 4841 } else { 4842 $pc_after = &$cmd_sub($pc_after, $open_tags_R); 4843 }; 4844 } elsif ((defined &$cmd_msub)&&!$NO_SIMPLE_MATH) { 4845#print "\nMCMD:$cmd_msub : "; 4846 # $ref_before may also be modified ... 4847 $pc_after = &$cmd_msub($pc_after, $open_tags_R); 4848 if ( !$math_mode ) { 4849 $pc_after = "<MATH>" . $pc_after . "</MATH>"; 4850 ++$commands_outside_math{$cmd}; 4851 }; 4852 } elsif ($cmd_trans) { # One to one transform 4853#print "\nCMD-DECL: $inside_tabular : $cmd_trans". join(',',@$open_tags_R); 4854 if ($inside_tabular) { 4855 push (@ref_processed , "\\$cmd ") 4856 } else { 4857 $cmd_trans =~ m|</.*$|; 4858 $pc_after = $` . $pc_after unless ($` =~ /^<>/); 4859 push(@$open_tags_R, $cmd) 4860 if ($cmd =~ /$fontchange_rx|$fontweight_rx|$sizechange_rx/o); 4861 } 4862 } elsif ($mathentity) { 4863#print "\nM-ENT:$mathentity : "; 4864 if ( $math_mode ) { 4865 $pc_after = "&$mathentity#$cmd;" . $pc_after; 4866 } elsif ($NO_SIMPLE_MATH) { 4867 $pc_after = "&$mathentity#$cmd;" . $pc_after; 4868# ++$commands_outside_math{$cmd}; 4869 } else { 4870 $pc_after = "<MATH>&$mathentity#$cmd;</MATH>" . $pc_after; 4871 ++$commands_outside_math{$cmd}; 4872 } 4873 } elsif ($ignore{$cmd}) { # Ignored command 4874 print "\nignoring \\$cmd" if $VERBOSITY > 5; 4875 $pc_after = join('', " ", $pc_after) if ($cmd eq " "); # catches `\ ' 4876 $pc_after = join(''," ", $pc_after) 4877 if (($cmd eq ',')&&($pc_after =~ /^\-/s)&&($ref_before =~/\-$/s)); 4878 } elsif ($cmd =~ /^the(.+)$/){ 4879 $counter = $1; 4880 local($tmp)="do_cmd_$cmd"; 4881 if (defined &$tmp) { # Counter 4882 $pc_after = &do_cmd_thecounter($pc_after); 4883 } else { 4884 if (defined $failed) { 4885 $failed = 1; 4886# $ref_before .= "$cmd"; 4887 push(@ref_processed,$cmd); # $ref_before .= "$cmd"; 4888 } else { &declare_unknown_cmd($cmd) } 4889# $ref_before .= "$cmd" if ($failed); 4890 } 4891 } elsif ($cmd eq "\n") { push(@ref_processed," "); # $ref_before .= " "; 4892 } else { 4893 # Do not add if reading an auxiliary file 4894 if (defined $failed) { 4895 $failed = 1; 4896 } else { &declare_unknown_cmd($cmd) } 4897 } 4898 } else { 4899 # &normalize should have already handled it adequately 4900 # '\ ' (space) gets thru to here. Perhaps some others too ? 4901# print "\n ?? This should not happen: \\$cmd ??\n"; 4902 } 4903# $_[1] = join('', $ref_before, $pc_after); 4904 $_[1] = $pc_after; 4905 print STDOUT "\n-> $ref_before\n" if ($VERBOSITY > 6); 4906 } 4907 $_[1] = join('',@ref_processed).$_[1]; 4908} 4909 4910sub declare_unknown_cmd { 4911 local($this_cmd) = @_; 4912 local($tmp) = "wrap_cmd_$cmd"; 4913 do { ++$unknown_commands{$cmd}; 4914 print STDOUT "\n*** Unknown command[1]: \\$cmd *** \n" 4915 if ($VERBOSITY > 2); 4916 } unless ($AUX_FILE||(defined &$tmp)||($image_switch_rx=~/\b\Q$cmd\E\b/)); 4917} 4918 4919 4920# This makes images from the code for math-entities, 4921# when $NO_SIMPLE_MATH is set and the math extension is loaded. 4922# 4923sub replace_math_constructions { 4924 local($math_mode) = @_; 4925 &make_math_box_images($math_mode) if (/<BOX>/); 4926 &make_math_entity_images($math_mode) if (/\&\w+#\w+;/); 4927} 4928 4929sub make_math_box_images { 4930 local($math_mode) = @_; 4931 local($pre,$this,$post,$tmp) = ('','',''); 4932 local($slevel,$blevel) = 0; 4933 4934 while (/<BOX>/) { 4935 $pre .= $`; $tmp = $`; $this = ''; $post = $'; 4936 # compute the super/sub-scripting level for each entity 4937 $tmp =~ s/<(\/?)SU[BP]>/ 4938 if ($1) { $slevel--} else { $slevel++};''/eog; 4939 4940 $tmp = $post; 4941 if ($tmp =~ /<(\/?)BOX>/o ) { 4942 if ($1) { $this = $`; $post = $' } 4943 else { $failed = 1 } # nested box, too complicated ! 4944 } else { 4945 &write_warnings("\nLost end of a <BOX> ?"); 4946 $failed = 1; 4947 } 4948 last if ($failed); 4949 4950 ($this,$_) = &process_box_in_latex( 4951 $math_mode, $slevel, $this, $post); 4952 $_ =~ s/^\s*//; # remove any leading spaces 4953 $pre .= $this ."\001"; 4954 } 4955 return if ($failed); 4956 $_ = $pre . $_; 4957} 4958 4959sub make_math_entity_images { 4960 local($math_mode) = @_; 4961 local($pre,$this,$post,$tmp) = ('','',''); 4962 local($slevel) = 0; 4963 # compute the super/sub-scripting level for each entity 4964 while (/\&\w+#(\w+);/) { 4965 $pre .= $`; $tmp = $`; $this = $1; $post = $'; 4966 $tmp =~ s/<(\/?)SU[BP]>/ 4967 if ($1) { $slevel--} else { $slevel++};''/eog; 4968 ($this,$_) = &process_entity_in_latex( 4969 $math_mode, $slevel, $this, $post); 4970 $_ =~ s/^\s*//; # remove any leading spaces 4971 $pre .= $this ."\001"; 4972 } 4973 $_ = $pre . $_; 4974} 4975 4976 4977#RRM: Revert a math-entity to create image using LaTeX, together with 4978# any super/sub-scripts (possibly nested or with \limits ). 4979# Must also get the correct \display/text/(script)script style. 4980# 4981sub process_entity_in_latex { 4982 local($mode,$level,$entity,$after) = @_; 4983 local($math_style,$supsub,$rest) = ('','',''); 4984 $level++ if ($mode =~/box/); # for top/bottom of inline fractions, etc. 4985 4986 if ($level) { 4987 $math_style = "\\". (($level > 1) ? "script" : "")."scriptstyle" 4988 } else { 4989 $math_style = "\\displaystyle" unless ($mode =~ /inline/); 4990 } 4991 while ($after =~ s/^\s*((\\limits|\&limits;)?\s*<SU(P|B)>)\s*/$supsub .= $1;''/eo) { 4992 local($slevel) = 1; 4993 local($aftersupb) = ''; 4994 while ($slevel) { 4995 $after =~ s/(<(\/)SU(B|P)>)/($2)? $slevel-- : $slevel++;''/oe; 4996 $supsub .= $`.$&; 4997 $aftersupb = $'; 4998 } 4999 $after = $aftersupb; 5000 } 5001 5002 local($latex_code) = "\$$math_style\\$entity$supsub\$"; 5003 5004 $global{'max_id'}++; 5005 ( &process_undefined_environment('tex2html_wrap_inline' 5006 ,$global{'max_id'}, $latex_code ) , $after); 5007} 5008 5009sub process_box_in_latex { 5010 local($mode,$level,$inside,$after) = @_; 5011 local($math_style,$which,$pre,$post,$tmp) = ('','',"\{","\}"); 5012 5013 if ($level) { 5014 $math_style = "\\". (($level > 1) ? "script" : "")."scriptstyle" 5015 } else { 5016 $math_style = "\\displaystyle" unless ($mode =~ /inline/); 5017 } 5018 5019 if ($inside =~ /<((LEFT)|(RIGHT))>/ ) { 5020 $pre = "\\left"; $post = "\\right"; 5021 if ($2) { 5022 $tmp = $`; $inside = $'; 5023 $pre .= (($tmp) ? $tmp : ".") . "\{"; 5024 if ( $inside =~ /<RIGHT>/ ) { 5025 $tmp = $'; 5026 $inside = $`; 5027 $post = "\}". (($tmp) ? $tmp : "."); 5028 } 5029 } else { 5030 $pre .= ".\{"; $tmp = $'; $inside = $`; 5031 $post = "\}". (($tmp) ? $tmp : "."); 5032 } 5033 } 5034 if ( $inside =~ /<((OVER)|(ATOP)|(CHOOSE))>/ ) { 5035 $pre .= $`; 5036 $post = $' . $post ; 5037 if ($2) { $which = "over " } 5038 elsif ($3) { $which = "atop " } 5039 elsif ($4) { $which = "atopwithdelims\(\)" } 5040 } 5041 5042 local($latex_code) = join('', "\$" , $math_style , " ", $pre 5043 , (($which)? "\\$which" : "") , $post , "\$" ); 5044 5045 if ($after =~ s/<SUP ALIGN=\"CENTER\">([^<]*)<\/SUP>/ 5046 $tmp =$1;''/eo ) { 5047 $latex_code = join('', "\\stackrel" , $latex_code 5048 , "\{" , $tmp , "\}" ); 5049 } 5050 5051 $global{'max_id'}++; 5052 ( &process_undefined_environment('tex2html_wrap_inline' 5053 ,$global{'max_id'}, $latex_code ) , $after); 5054} 5055 5056####################### Processing Meta Commands ############################ 5057# This is a specialised version of process_command above. 5058# The special commands (newcommand, newenvironment etc.) 5059# must be processed before translating their arguments, 5060# and before we cut up the document into sections 5061# (there might be sectioning commands in the new definitions etc.). 5062# \newtheorem commands are treated during normal processing by 5063# generating code for the environments they define. 5064 5065sub substitute_meta_cmds { 5066 local ($next_def); 5067 local ($cmd, $arg, $argn, $opt, $body, $before, $xafter); 5068 local ($new_cmd_no_delim_rx, $new_cmd_rx, $new_env_rx, $new_cmd_or_env_rx); 5069 local ($new_end_env_rx); 5070 &tokenize($meta_cmd_rx); #JCL(jcl-del) - put delimiter after meta command 5071 print "\nProcessing macros ..." if (%new_command || %new_environment); 5072 # First complete any replacement left-over from the previous part. 5073 if ($UNFINISHED_ENV) { 5074 s/$UNFINISHED_ENV/$REPLACE_END_ENV/; 5075 $UNFINISHED_ENV = ''; 5076 $REPLACE_END_ENV = ''; 5077 } 5078 5079 local(@processed); 5080 local($processed, $before, $after)=('', '', $_); 5081 while ($after =~ /$meta_cmd_rx$EOL/o) { # ... and uses the delimiter 5082 ($cmd, $after) = ($1.$2, $'); 5083 $before .= $`; 5084# $next_def = ''; 5085 if (!($before =~ /$meta_cmd_rx$EOL/)) { 5086 push(@processed, $before); $before = ''; 5087 } 5088 5089 print ","; 5090# $next_def = "\\$cmd" unless (($cmd =~ /renewcommand/)); 5091 local($cmd_sub) = "get_body_$cmd"; 5092 if (defined &$cmd_sub) { 5093# $processed = &$cmd_sub(*after); 5094 $processed = &$cmd_sub(\$after); 5095# if ($processed) { $after = $before . $processed; } 5096# $next_def = '' 5097# if (($PREAMBLE > 1)&&($cmd =~ /(re)?newcommand/)); 5098# &add_to_preamble($cmd, $next_def) 5099# unless ($next_def =~ /^\s*$/); 5100### new style of handling meta-commands 5101 if ($processed) { push(@processed, "\\".$processed) } 5102 } 5103 elsif ($before) { 5104 # this shouldn't happen !! 5105 print STDERR "\nCannot handle \\$cmd , since there is no $cmd_sub "; 5106 $after = $before . $cmd . $after; 5107 $before = ''; 5108 } else { 5109 push(@processed, "\\$cmd ") if $cmd; 5110 } 5111 } 5112 print "\nmeta-commands: ". (0+@processed) ." found " 5113 if ((@processed)&&($VERBOSITY > 1)); 5114 $_ = join('',@processed, $after); undef @processed; 5115 if ($PREAMBLE) { 5116 # MRO: replaced $* with /m 5117 s/((\n$comment_mark\d*)+\n)//gm; 5118 s/(\\par\b\s*\n?)+/\\par\n/gm; 5119 s/(\\par\b\n?)+/\\par\n/gm; 5120 } 5121 5122 # hard-code the new-command replacements for these 5123 $new_command{'begingroup'} = "0:!:\\begin<<0>>tex2html_begingroup<<0>>:!:}"; 5124 $new_command{'endgroup'} = "0:!:\\end<<0>>tex2html_begingroup<<0>>:!:}"; 5125 $new_command{'bgroup'} = "0:!:\\begin<<0>>tex2html_bgroup<<0>>:!:}"; 5126 $new_command{'egroup'} = "0:!:\\end<<0>>tex2html_bgroup<<0>>:!:}"; 5127 5128 # All the definitions have now moved to the $preamble and their bodies 5129 # are stored in %new_command and %new_environment 5130 # 5131 # Now substitute the new commands and environments: 5132 # (must do them all together because of cross definitions) 5133 $new_cmd_rx = &make_new_cmd_rx(keys %new_command); 5134 $new_cmd_no_delim_rx = &make_new_cmd_no_delim_rx(keys %new_command); 5135 $new_env_rx = &make_new_env_rx; 5136 $new_end_env_rx = &make_new_end_env_rx; 5137# $new_cnt_rx = &make_new_cnt_rx(keys %new_counter); 5138 $new_cmd_or_env_rx = join("|", $new_cmd_no_delim_rx." ", $new_env_rx); 5139# $new_cmd_or_env_rx = join("|", $new_cmd_no_delim_rx." ", $new_env_rx, " ".$new_cnt_rx); 5140 $new_cmd_or_env_rx =~ s/^ \||\|$//; 5141 5142 print STDOUT "\nnew commands:\n" if ($VERBOSITY > 2); 5143 while (($cmd, $body) = each %new_command) { 5144 unless ($expanded{"CMD$cmd"}++) { 5145 print STDOUT ".$cmd " if ($VERBOSITY > 2); 5146 $new_command{$cmd} = &expand_body; 5147 print STDOUT " ".$new_command{$cmd}."\n" if ($VERBOSITY > 4); 5148 &write_mydb("new_command", $cmd, $new_command{$cmd}); 5149 } 5150 } 5151 5152 print STDOUT "\nnew environments:\n" if ($VERBOSITY > 2); 5153 while (($cmd, $body) = each %new_environment) { 5154 unless ($expanded{"ENV$cmd"}++) { 5155 print STDOUT ".$cmd" if ($VERBOSITY > 2); 5156 $new_environment{$cmd} = &expand_body; 5157 &write_mydb("new_environment", $cmd, $new_environment{$cmd}); 5158 } 5159 } 5160 5161 print STDOUT "\nnew counters and dependencies:\n" if ($VERBOSITY > 2); 5162 &clear_mydb("dependent") if ($DEBUG); #avoids appending to a previous version 5163 while (($cmd, $body) = each %dependent) { 5164 print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2); 5165 &write_mydb("dependent", $cmd, $dependent{$cmd}); 5166 } 5167 &clear_mydb("img_style") if ($DEBUG); #avoids appending to a previous version 5168 while (($cmd, $body) = each %img_style) { 5169 &write_mydb("img_style", $cmd, $img_style{$cmd}); 5170 } 5171 5172 &clear_mydb("depends_on") if ($DEBUG); #avoids appending to a previous version 5173 while (($cmd, $body) = each %depends_on) { 5174 print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2); 5175 &write_mydb("depends_on", $cmd, $depends_on{$cmd}); 5176 } 5177 5178 5179 &clear_mydb("styleID") if ($DEBUG); #avoids appending to a previous version 5180 while (($cmd, $body) = each %styleID) { 5181 &write_mydb("styleID", $cmd, $styleID{$cmd}); 5182 } 5183 5184 &clear_mydb("env_style") if ($DEBUG); #avoids appending to a previous version 5185 while (($cmd, $body) = each %env_style) { 5186 &write_mydb("env_style", $cmd, $env_style{$cmd}); 5187 } 5188 &clear_mydb("txt_style") if ($DEBUG); #avoids appending to a previous version 5189 while (($cmd, $body) = each %txt_style) { 5190 &write_mydb("txt_style", $cmd, $txt_style{$cmd}); 5191 } 5192 5193 print STDOUT "\ntheorem counters:\n" if ($VERBOSITY > 2); 5194 &clear_mydb("new_theorem") if ($DEBUG); #avoids appending to a previous version 5195 while (($cmd, $body) = each %new_theorem) { 5196 print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2); 5197 &write_mydb("new_theorem", $cmd, $new_theorem{$cmd}); 5198 } 5199 5200 5201 print "+"; 5202 if (length($new_env_rx)) { 5203 local(@pieces); 5204 print STDOUT "\nsubstituting new environments: $new_env_rx\n" if ($VERBOSITY > 3); 5205# while (/\n?$new_env_rx/ && (($before, $cmd, $after) = ($`, $2, $'))) { 5206 while (/$new_env_rx/ && (($before, $cmd, $after) = ($`, $2, $'))) { 5207 print STDOUT ","; 5208 print STDOUT "{$cmd}" if ($VERBOSITY > 1); 5209 if (!($before =~ /$new_env_rx/)) { 5210 push (@pieces, $before); $before = ''; print "{}"; 5211 } 5212 $_ = join('',$before, &substitute_newenv); 5213 } 5214 print "\n ".(0+@pieces). " new environments replaced\n" if (@pieces); 5215 $_ = join('', @pieces, $_); undef @pieces; 5216 } 5217 5218 5219 print "+"; 5220 if (length($new_cmd_rx)) { 5221 print STDOUT "\ntokenizing: $new_cmd_rx\n" if ($VERBOSITY > 2); 5222 &tokenize($new_cmd_rx); # Put delimiter after the new commands 5223 5224 # and use the delimiter. 5225 print STDOUT "\nsubstituting new commands: $new_cmd_rx\n" if ($VERBOSITY > 2); 5226 print STDOUT "\ninitial size: ".length($after) if ($VERBOSITY > 1); 5227 # store processed pieces in an array 5228 local($this_cmd, @pieces); 5229 # speed-up processing of long files by splitting into smaller segments 5230 # but don't split within the preamble, else \newenvironment may break 5231 local($pre_segment,@segments); &make_sections_rx; 5232 local($within_preamble,$this_section) = 1 if ($PREAMBLE>1); 5233 while (/$sections_rx/) { 5234 $pre_segment .= $`; $_ = $'; $this_section = $&; 5235 do { 5236 push(@segments,$pre_segment); 5237 $pre_segment = ''; 5238 } unless ($within_preamble); 5239 $within_preamble = 0 if ($within_preamble && ($pre_segment =~ 5240 /\\(startdocument|begin\s*($O\d+${C})\s*document\s*\2)/)); 5241 $pre_segment .= $this_section; 5242 } 5243 push(@segments,$pre_segment.$_); 5244 local($replacements,$seg) ; $before = ''; # count the segments 5245 local($within_preamble) = 1 if ($PREAMBLE>1); 5246 foreach $after (@segments) { 5247 while ($after =~ /(\\(expandafter|noexpand)\b\s*)?$new_cmd_no_delim_rx\b\s?/) { 5248 ($before, $xafter, $cmd, $after) = ($`, $2, $3, $'); 5249 $within_preamble = 0 5250 if ($before =~ /\\(startdocument|begin\s*($O\d+${C})\s*document\s*\2)/); 5251 push(@pieces, $before); 5252 print "."; ++$replacements; 5253 print STDOUT "$cmd" if ($VERBOSITY > 2); 5254 if ($xafter =~ /no/) { $this_cmd = "\\\@#\@\@".$cmd } 5255 elsif (($xafter =~ /after/)&&($after =~ /^\s*\\/)) { 5256 local($delayed) = $cmd; 5257 local($nextcmd); 5258 $after =~ s/^\s*\\([a-zA-Z]+|.)/$nextcmd = $1;''/eo; 5259 ($cmd,$nextcmd) = ($nextcmd, "do_cmd_$nextcmd"); 5260 if (defined &$nextcmd) { $after = &$nextcmd($after); } 5261 elsif ($new_command{$cmd}) { 5262 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 5263 &make_unique($body) if ($body =~ /$O/); 5264 if ($argn) { 5265 do { 5266 local($before) = ''; 5267 $after = join('',&substitute_newcmd, $after); 5268 $after =~ s/\\\@#\@\@/\\/o ; 5269 }; 5270 } else { $after = $body . $after; } 5271 } else { print "\nUNKNOWN COMMAND: $cmd "; } 5272 $cmd = $delayed; 5273 if ($new_command{$cmd}) { 5274 if ($renew_command{$cmd}) { 5275# # must wrap it in a deferred environment 5276# $this_cmd = join('', &make_deferred_wrapper(1) 5277# ,"\\$cmd".(($cmd =~ /\w$/)? " ":'') 5278# , &make_deferred_wrapper(0)); 5279# push(@pieces, $this_cmd); $this_cmd = ''; 5280 push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":'')); 5281 $this_cmd = ''; 5282 } elsif ($provide_command{$cmd}&&$within_preamble) { 5283 # leave it alone 5284 push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":'')); 5285 $this_cmd = ''; 5286 } else { 5287 # do the substitution 5288 $this_cmd = &substitute_newcmd; 5289 } 5290 } 5291 } elsif ($renew_command{$cmd}) { 5292 # leave it alone 5293 push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":'')); 5294 $this_cmd = ''; 5295 } elsif (($provide_command{$cmd})&&($within_preamble)) { 5296 # leave it alone 5297 push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":'')); 5298 $this_cmd = ''; 5299 } else { 5300 # do the substitution 5301 $this_cmd = &substitute_newcmd if ($new_command{$cmd}); 5302 } 5303 if ($this_cmd =~ /(\\(expandafter|noexpand)\s*)?$new_cmd_no_delim_rx\b\s?/) 5304 { $after = $this_cmd . $after } 5305 elsif ($this_cmd) { push(@pieces, $this_cmd) } 5306 } 5307 push(@pieces, $after); 5308 } 5309 print " $replacements new-command replacements\n" 5310 if (($VERBOSITY>1) && $replacements); 5311 # recombine the processed pieces 5312 $_ = join('', @pieces); undef @pieces; 5313 print STDOUT ", resulting size: ".length($_)." " if ($VERBOSITY > 1); 5314 $_ =~ s/\\\@#\@\@/\\/go; 5315 } 5316 5317 print STDOUT "\n *** substituting metacommands done ***\n" if ($VERBOSITY > 3); 5318} 5319 5320sub insert_command_expansion { 5321 ($xafter, $cmd) = @_; 5322# push(@pieces, $_[1]); 5323 print ".$cmd"; 5324 print STDOUT "$_[3]" if ($VERBOSITY > 2); 5325# $xafter = $_[2]; 5326# $cmd = $_[3]; 5327 if ($xafter =~ /no/) { $this_cmd = "\\\@#\@\@".$cmd } 5328 elsif (($xafter =~ /after/)&&($after =~ /^\s*\\/)) { 5329 local($delayed,$nextcmd) = ($_[3],''); 5330 5331 $after =~ s/^\s*\\([a-zA-Z]+|.)/$nextcmd = $1;''/eo; 5332 ($cmd,$nextcmd) = ($nextcmd, "do_cmd_$nextcmd"); 5333 if (defined &$nextcmd) { $after = &$nextcmd($after); } 5334 elsif ($new_command{$cmd}) { 5335 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 5336 &make_unique($body) if ($body =~ /$O/); 5337 if ($argn) { 5338 do { 5339 local($before) = ''; 5340 $after = join('',&substitute_newcmd, $after); 5341 $after =~ s/\\\@#\@\@/\\/o ; 5342 }; 5343 } else { $after = $body . $after; } 5344 } else { print "\nUNKNOWN COMMAND: $cmd "; } 5345 $cmd = $delayed; 5346 $this_cmd = &substitute_newcmd if ($new_command{$cmd}); 5347 } else { 5348 $this_cmd = &substitute_newcmd if ($new_command{$cmd}); 5349 } 5350# if ($this_cmd =~ /(\\(expandafter|noexpand)\s*)?$new_cmd_no_delim_rx\s?/){ 5351# $after = $this_cmd . $after 5352# } else { push(@pieces, $this_cmd); } 5353 $this_cmd; 5354} 5355 5356 5357sub expand_body { 5358 return unless length($new_cmd_or_env_rx); 5359 local($_) = $body; 5360 local($cmd,$saveafter,$avoid_looping); 5361 # Uses $before, $body, $arg, etc. of the caller, but not $cmd. 5362 # Uses $new_cmd_rx (resp. $new_cmd_no_delim_rx) and $new_env_rx 5363 # set in the caller, of which one might be empty. 5364 5365 # Puts delimiter after the new commands ... 5366 &tokenize($new_cmd_rx) if length($new_cmd_rx); 5367 5368 while (/$new_cmd_or_env_rx/) { 5369 # $new_cmd_rx binds $1, and $new_env_rx binds $3. 5370 ($before,$cmd,$after,$saveafter) = ($`,$1.$3,$',$'); 5371 if (length($new_command{$cmd})) { # We have a command 5372 # this tokenizes again 5373 local($replace) = &substitute_newcmd; # sets $_, changes $after 5374 if (!($replace)) { 5375 # protect name of unexpanded macro 5376 $_ = join('', $before ,"\\@#@@", $cmd, $saveafter ); 5377 } else { 5378 $_ = join('', $before , $replace, $after ); 5379 } 5380 } elsif (length($new_environment{$cmd})) { 5381 $_ = join('',$before, &substitute_newenv); 5382 } 5383 last if $avoid_looping; 5384 } 5385 # remove protection from unreplaced macro names 5386 s/\\\@#\@\@/\\/go; 5387 5388 # remove trivial comments 5389 s/(\\\w+)$comment_mark\d*\n[ \t]*/$1 /go; 5390 s/$comment_mark\d*\n[ \t]*//go; 5391# s/($O\d+$C)?($comment_mark\n)[ \t]*/($1 ? $1.$2 : '')/eg; 5392 5393 $_; 5394} 5395 5396 5397sub substitute_newcmd { 5398 # Modifies $after in the caller 5399 # Get the body from the new_command array 5400 local($tmp,$cnt,$saved, $arg, $isword) = ('',0,$cmd); 5401 local($argn, $_, $opt) = split(/:!:/, $new_command{$cmd}); 5402 $avoid_looping = 1 if ($new_command{$cmd} =~ /\\$cmd\b/); 5403 5404 &tokenize($new_cmd_rx); # must do it again for newly inserted cmd bodies 5405 print STDOUT "\nNEW:$cmd:$_" if ($VERBOSITY > 5); 5406 foreach $i (1..$argn) { 5407 $arg = $isword = ''; 5408 if ($i == 1 && $opt ne '}') { 5409 $arg = ($after =~ s/$optional_arg_rx//o) ? $1 : $opt; 5410 } 5411 else { 5412 # Get the next argument, if not in braces, get next character 5413 #RRM: allow also for processed braces, in case substitution 5414 # was delayed; e.g. by \renewcommand 5415 if (!(($after =~ s/$next_pair_rx/$arg = $2;''/e) 5416 ||($after =~ s/$next_pair_pr_rx/$arg = $2;''/e))) { 5417 $after =~ s/^\s*(\\[a-zA-Z]+|.)/$arg = $1;''/e; 5418 } 5419 if ($arg eq '#') { 5420 &write_warnings("\nSubstitution of arg to $cmd delayed."); 5421 $_ = "\\\@#\@\@$saved"; 5422 return (); 5423 }; 5424 } 5425 $arg =~ s/(^|\G|[^\\])\\\#/$1$hash_mark/gs; 5426 $arg =~ s/\#/$param_mark/gs; 5427 5428 #RRM: Substitute the arguments in the body one at a time 5429 # else multiple instances would fail in &make_unique 5430 5431 # First protect ## parameters in TeX-like substitutions 5432 # suggested by Dirk Pleiter (Berlin) 5433 s/((^|[^\\])(\\\\)*)\#\#$i/$1$protected_hash/gs; 5434 $tmp = $_; 5435 $cnt = $tmp =~ s/\#$i//g ; 5436 $isword = 1 if ($arg =~ /^\w/); 5437 if ($cnt > 1 ) { 5438 $tmp = $_; 5439 while ($cnt > 1) { 5440 if ( s/(\\\w+)?\#$i/(($1&&$isword)? $1.' ': '').$arg/e) { 5441 &make_unique($_) if ($arg =~ /$O/ ); 5442 &make_unique_p($_) if ($arg =~ /$OP/ ); 5443 } 5444 $cnt--; 5445 } 5446 $tmp = $_; 5447 } 5448# s/(\\\w+)?\#$i/(($1&&$isword)? $1.' ': '').$arg/e ; 5449 s/(\\\w+)?\#$i/$1.(($1&&$isword)? ' ': '').$arg/e ; 5450 print "\n *** substitution: $arg \nfor \#$i in \\$cmd did not take ***\n" 5451 if (/\#$i/); 5452 &write_warnings("incomplete substitution in a \\$cmd command:\n$_") if (/\#$i/); 5453 s/$protected_hash/\#$i/g; 5454 } 5455 s/$param_mark/\#/g; 5456 s/$hash_mark/\\\#/g; 5457 s/(\\\w+)$/$1 /s; 5458 5459 # Make the body unique (give unique id's to the brackets), 5460 # translate, and return it 5461 &make_unique($_); 5462 if ($avoid_looping) { 5463 s/\\$cmd\b/\\csname $cmd\\endcsname/g; 5464 print STDERR "\n *** possible looping with new-command \\$cmd ***\n"; 5465 &write_warnings("\npossible looping with new-command \\$cmd "); 5466 } 5467 print STDOUT "\nOUT:$cmd:$_" if ($VERBOSITY > 5); 5468 5469# Insert a space to prevent letters from clashing together with a 5470# letter command. Consider this: 5471# New command substitution is restricted to commands introduced by 5472# \newcommand etc. (so-called meta commands), but it is not done 5473# for already defined commands, eg. \large. 5474# But new command, as well as new environment, substitution is done 5475# prior to any other substitution. 5476# So \newcommand{\this}{...} {\large\this b} will get expanded the 5477# following way: 5478# 1. \newcommand{\this}{...} 5479# is handled by &substitute_meta_cmds, it gets the definition 5480# of \this and stores it within a table, %new_command. 5481# After all new commands are recognized, &expand_body is called 5482# to expand one command body from each other. That's O(n*n)! 5483# 2. A regular expression $new_cmd_rx is built containing a pattern 5484# that matches all occurrences of a properly delimited \this 5485# macro. When matching, ensuing white space gets lost. 5486# (But only for letter commands, see also &make_new_cmd_rx.) 5487# Another regular expression called $new_cmd_no_delim_rx is built 5488# which matches exact the \this, and would also match the prefix 5489# of \thisx. 5490# 3. The *whole* text is tokenized using $new_cmd_rx, with separates 5491# \this from the ensuing text by one white space. 5492# 4. Then $new_cmd_no_delim_rx together with the delimiting space 5493# is used to substitute \this with its body. 5494# 5. The following situations may occur: 5495# a) ... is some text (no macros) => {\large<text>yyy} 5496# Then we must prevent that the text clashes into \large. 5497# This is only dangerous when <text> begins with a letter. 5498# b) ... contains another, not expanded new command. 5499# This happens during &expand_body. 5500# In this case, make sure to &tokenize the body before giving 5501# the result to the caller. Also take care that leading letters 5502# of the body cannot clash into \large. 5503# e) ... contains a macro not known as new command: 5504# Make sure that the macro cannot clash with the ensuing yyy. 5505# f) ... is empty: 5506# Make sure that \large cannot clash with yyy. 5507# 6. We prevent clashing by inserting a delimiting blank. 5508# Out of the scetched situation, there are three conditions to 5509# take care of: 5510# a) empty body, left a letter command, right a letter => blank 5511# b) body starts with letter, left a letter command => blank 5512# c) body ends with letter command, right a letter => blank 5513# d) else => no blank, clash all together, it will work. 5514# 7. With this rules, the expansion should work quite well, 5515# concerning letter/non-letter commands and white space 5516# handling. 5517# 8. Deficiencies: 5518# 8.1 Consider \this<CR>that. It's handled this way: 5519# a) The \this swallows the <CR> in LaTeX, but what LaTeX2HTML does 5520# is to &tokenize the expression into \this <CR>that. 5521# b) If ... is some text, it results in <text><CR>that. 5522# c) If ... is a macro (or command, or control sequence, these 5523# terms are often mixed up, but effectively mean the same), 5524# then if the macro later takes at least one argument, the <CR> 5525# might get swallowed, this depends on the grace of $next_pair_rx 5526# resp. $next_pair_pr_rx. 5527# If the macro takes no arguments, the <CR> remains in the text. 5528# d) If ... ends in another new command, the problem repeats. 5529# 8.2 The new commands are substituted in a very insensitive way. 5530# If \this occurs within an environment which sees \this 5531# totally different, there's no chance to substitute \this in 5532# a different way. 5533# 8.3 In relation to 8.2 a similar problem arises when the meta 5534# command, or several meta commands redefining \this, occur 5535# amongst several \this macros. 5536# 8.4 In raw TeX like environments it is not possible to revert the 5537# expansion of \this, but \this probably *must* occur in its 5538# raw form. 5539 5540# Handle the cases as depicted in the description of new command 5541# substitution. 5542 local($befdel,$aftdel); 5543 $befdel = ' ' 5544 if ($before=~/(^|[^\\])\\[a-zA-Z]+$/ && /^$/ && $after=~/^[a-zA-Z]/) || 5545 ($before=~/(^|[^\\])\\[a-zA-Z]+$/ && /^[a-zA-Z]/); 5546 $aftdel = ' ' 5547 if /(^|[^\\])\\[a-zA-Z]+$/s && $after=~/^[a-zA-Z]/; 5548 join('', $befdel, $_, $aftdel); 5549} 5550 5551#RRM: use this to test whether a specific command is substituting correctly 5552sub trace_cmd { 5553 local($this) = @_; 5554 if ($cmd eq $this) { print "\n$1=>$id:$2::"} 5555} 5556 5557# Make the text unique (give unique id's to the brackets). 5558# The text shouldn't contain processed brackets. 5559sub make_unique { 5560 # MRO: Change to references $_[0] 5561 # local(*_) = @_; 5562 my $id = $global{'max_id'}; 5563 # MRO: replaced $* by /m 5564 # this looks quite funny but is optimized 5565 1 while($_[0] =~ s/$O(\d+)$C([\w\W]*)$O\1$C/$id++;"\000$id $2\000$id "/geom); 5566 $_[0] =~ s/\000(\d+) /$O$1$C/gom; 5567 $global{'max_id'} = $id; 5568} 5569 5570#RRM: this shouldn't be needed, but just in case... 5571sub make_unique_p { 5572 # MRO: Change to references $_[0] 5573 my $id = $global{'max_id'}; 5574 # MRO: replaced $* by /m 5575 # this looks quite funny but is optimized 5576 1 while($_[0] =~ s/$OP(\d+)$CP([\w\W]*)$OP\1$CP/$id++;"\000$id $2\000$id "/geom); 5577 $_[0] =~ s/\000(\d+) /$OP$1$CP/gom; 5578 $global{'max_id'} = $id; 5579} 5580 5581 5582sub substitute_newenv { 5583 # Modifies $cmd and $after in the caller 5584 # Get the body from the new_environment array 5585 local($argn, $begdef, $enddef, $opt) = split(/:!:/, $new_environment{$cmd}); 5586 local($arg,$new_def_rx,$tmp,$cnt); 5587 5588 # Note that latex allows argument substitution only in the 5589 # \begin part of the new definition 5590 foreach $i (1..$argn) { # Process the arguments 5591 if (($i == 1) && ($opt ne '}')) { 5592 $after =~ s/$optional_arg_rx/$arg = $1;''/eo; 5593 $arg = $opt unless $arg; 5594 } 5595 else { 5596 $after =~ s/$next_pair_rx/$arg = $2;''/eo; 5597 } 5598 $arg =~ s/(^|[^\\])\\\#/$1$hash_mark/g; 5599 $arg =~ s/\#/$param_mark/g; 5600 5601 #RRM: multiple instances can fail later in &make_unique 5602# s/\#$i/$arg/g; # Substitute the arguments in the body 5603 #RRM: ...so do one at a time and &make_unique_p 5604 $tmp = $begdef; 5605 $cnt = $tmp =~ s/\#$i//g ; 5606 if ($cnt > 1) { 5607 $tmp = $begdef; 5608 while ($cnt > 1) { 5609 if ( $begdef =~ s/\#$i/$arg/) { 5610 &make_unique($begdef) if ($arg =~ /$O/ ); 5611 &make_unique_p($begdef) if ($arg =~ /$OP/ ); 5612 } 5613 $cnt--; 5614 } 5615 $tmp = $_; 5616 } 5617 $begdef =~ s/\#$i/$arg/ ; 5618 print "\n *** substitution: $arg \nfor \#$i in {$cmd} did not take ***\n" 5619 if ($begdef =~ /\#$i/); 5620 &write_warnings("incomplete substitution in a {$cmd} environment:\n$begdef") 5621 if ($begdef =~ /\#$i/); 5622 } 5623 $begdef =~ s/$param_mark/\#/g; 5624 $begdef =~ s/$hash_mark/\\\#/g; 5625 $begdef =~ s/(\\\w+)$/$1 /s; 5626 5627 # Make the body unique (Give unique id's to the brackets), 5628 # translate, and return it 5629#RRM: when are these needed ? 5630# $_ = &revert_to_raw_tex($_); 5631# &pre_process; 5632 5633 &make_unique($begdef); # Make bracket IDs unique 5634 print STDOUT "\nBEGIN:$cmd:$begdef" if ($VERBOSITY > 4); 5635 5636 # Now substitute the \end part: 5637#RRM: when are these needed ? 5638# $_ = &revert_to_raw_tex($enddef); 5639# &pre_process; 5640 5641 &make_unique($enddef); # Make bracket IDs unique 5642 print STDOUT "\nEND:$cmd:$enddef" if (($enddef)&&($VERBOSITY > 4)); 5643 $enddef =~ s/(\\\w+)$/$1 /s; 5644 5645 local($new_end_def_rx) = &make_end_env_rx($cmd); 5646 if (($enddef)&&!($after =~ s/\n?$new_end_def_rx/$enddef/ )) { 5647 $UNFINISHED_ENV = $new_end_def_rx; 5648 $REPLACE_END_ENV = $enddef; 5649 }; 5650 join('',$begdef,$after); 5651} 5652 5653sub substitute_pars { 5654 s/((\%|$comment_mark\d*)|.)(\r*\n[ \t]*){2,}[ \t]*/$1\n\\par \n/og; 5655# s/((\%|$comment_mark\d*)|\d|.)[\r\n\015]{2,}/print "\nPAR:".$`.$&;"$1\n\\par \n"/egs; 5656} 5657 5658sub do_cmd_end { #RRM: catches the end of any unclosed environments 5659 local($_) = @_; 5660 &missing_braces unless ( 5661 (s/$next_pair_pr_rx//o)||(s/$next_pair_rx//o)); 5662 s/^\n//; 5663 $_; 5664} 5665 5666# Removes the definition from the input string, 5667# adds to the preamble unless it is part of the preamble already 5668# and stores the body in %new_command; 5669sub get_body_newcommand { 5670 local($newed, $n_after) = &process_body_newcommand(0,@_); 5671 (($PREAMBLE)? "newed".$newed : ''); 5672} 5673 5674sub process_body_newcommand { 5675# local($renewed,*_) = @_; 5676 local($renewed,$after_R) = @_; 5677 local($_) = $$after_R; 5678 local($no_change) = $_; 5679 local($argn,$newcmd,$cmd_br,$body,$body_br,$tmp,$tmp1,$opt,$pat); 5680 local($new_cmd) = 'command'; 5681 if ($renewed =~ /provide/||$renewed == 2) { 5682 # $newcmd = &missing_braces unless ( 5683 ($newcmd,$pat) = &get_next(1) unless ( 5684 (s/$next_pair_pr_rx/$pat=$&;$newcmd=$2;''/e) 5685 ||(s/$next_pair_rx/$pat=$&;$newcmd=$2;''/e)); 5686 if (!$pat) { 5687 local($br_id) = ++$global{'max_id'}; 5688 $pat = "$O$br_id$C".$newcmd."$O$br_id$C"; 5689 } 5690 } else { 5691 ($newcmd,$pat) = &get_next(1); # Get command name 5692 } 5693 $pat =~ s/\\//; $new_cmd .= $pat; 5694 $newcmd =~ s/^\s*\\//; 5695 ($argn,$pat) = &get_next(0); # Get optional no. of args 5696 $argn = 0 unless $argn; $new_cmd .= $pat if $argn; 5697 local($cmd) = $newcmd; 5698 5699 # Get the body of the code and store it with the name and number of args 5700 # UNLESS THE COMMAND IS ALREADY DEFINED 5701 # ...in which case $ALLOW_REDEFINE must also have been set. # RRM 5702 # (This is the mechanism with which raw html can be ignored in a Latex document 5703 # but be recognised as such by the translator). 5704 $opt = '}'; # Flag for no optional arg 5705 local($bodyA) = ''; 5706 if (/^\[/) { 5707 ($opt,$pat) = &get_next(0); 5708 $new_cmd .= $pat; 5709 $bodyA .= "\n".'($dummy, $pat) = &get_next_optional_argument;' . 5710 "\n". '$args .= $pat;'; 5711 } 5712 local($nargs) = $argn; 5713 while ($nargs > 0) { $nargs--; 5714 $bodyA .= 5715 "\n".'$args .= $`.$& if ((s/$next_pair_pr_rx//o)||(s/$next_pair_rx//o));'; 5716 } 5717 if ($renewed =~ /provide/||$renewed == 2 ) { 5718 $body = &missing_braces unless ( 5719 (s/$next_pair_pr_rx/$pat=$&;$body=$2;''/e) 5720 ||(s/$next_pair_rx/$pat=$&;$body=$2;''/e)); 5721 $new_cmd .= $pat; 5722 } else { 5723 ($body,$pat) = &get_next(4); #get the body 5724 $new_cmd .= $pat; 5725 } 5726 5727 local($thisone); 5728# $thisone = 1 if ($cmd =~ /div|vec/); # for debugging 5729 5730 $tmp = "do_cmd_$cmd"; 5731 local($wtmp) = "wrap_cmd_$cmd"; 5732 if ((defined &$tmp)||(defined &$wtmp)){ 5733 # command already exists, so \providecommand does nothing 5734 # but may still be needed in images.tex 5735 $$after_R = $_; 5736 return ($new_cmd) if ($renewed =~ /provide/); 5737 5738 print "\n*** redefining \\$cmd ***\n"; 5739 &write_warnings("\nredefining command \\$cmd "); 5740 if (!$ALLOW_REDEFINE) { 5741 print "*** overriding previous meaning ***\n"; 5742 &write_warnings("\nprevious meaning of \\$cmd will be lost"); 5743 } 5744# local($code) = "undef \&$tmp"; eval ($code); 5745# if ($@) {print "\n*** undef \&$cmd failed \n"} 5746 if ((!$PREAMBLE)||($renewed>1)) { 5747 $new_command{$cmd} = join(':!:',$argn,$body,$opt); 5748# local($code) = "sub $tmp\{\&replace_new_command(\"$cmd\");\}"; 5749# eval $code; 5750# print STDERR "\n*** sub do_cmd_$cmd failed:\nPERL: $@\n" if ($@); 5751# &replace_new_command($cmd); 5752 } 5753 5754 $renew_command{$cmd} = 1; 5755 &write_mydb("renew_command", $cmd, $renew_command{$cmd}); 5756 local($padding) = " "; 5757 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 5758 # Generate a new subroutine 5759 local($codeA) = "sub wrap_cmd_$cmd {" . "\n" 5760 .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";' 5761 . $bodyA 5762 . (($thisone)? "\nprint \"\\nwrap $cmd:\".\$args.\"\\n\";" : '') 5763 . "\n".'(&make_deferred_wrapper(1).$cmd.' 5764 . "\"$padding\"".'.$args.&make_deferred_wrapper(0),$_)}' 5765 . "\n"; 5766 print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging 5767 eval $codeA; 5768 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 5769 $raw_arg_cmds{$cmd} = 1; 5770 5771 } elsif (($ALLOW_REDEFINE)&&($PREAMBLE < 2)) { 5772 print "\n*** redefining \\$cmd ***\n"; 5773 &write_warnings("\ncommand \\$cmd had no previous definition") 5774 if (!($new_command{$cmd})); 5775 } 5776 if ($renewed && ($PREAMBLE > 1) &&($new_command{$cmd})) { 5777 $raw_arg_cmds{$cmd} = 1 ; 5778 $renew_command{$cmd} = 1; 5779 local($padding) = " "; 5780 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 5781 # Generate a new subroutine 5782 local($codeA) = "sub wrap_cmd_$cmd {" . "\n" 5783 .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";' 5784 . $bodyA 5785 . (($thisone)? "\nprint \"\\nwrap $cmd:\".\$args.\"\\n\";" : '') 5786 . "\n".'(&make_deferred_wrapper(1).$cmd.' 5787 . "\"$padding\"".'.$args.&make_deferred_wrapper(0),$_)}' 5788 . "\n"; 5789 print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging 5790 eval $codeA; 5791 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 5792 5793 &write_mydb("renew_command", $cmd, $renew_command{$cmd}); 5794 } elsif ($renewed) { 5795 $new_command{$cmd} = join(':!:',$argn,$body,$opt); 5796 } else { 5797 $new_command{$cmd} = join(':!:',$argn,$body,$opt) 5798 unless (($PREAMBLE > 1)&&($renew_command{$cmd})); 5799 } 5800 5801 local($this_cmd); 5802 $this_cmd = join('' 5803 , "command{\\$cmd}" 5804 , ($argn ? "[$argn]" :'') 5805 , (($opt =~ /^}$/) ? '' : "[$opt]" ) 5806 , "{", $body , "}" ); 5807 $this_cmd = &revert_to_raw_tex($this_cmd); 5808 if ($renewed) { 5809 if ($renewed=~/provide/){ 5810 $provide_command{$cmd} = 1; 5811 &write_mydb("provide_command", $cmd, $provide_command{$cmd}); 5812# } else { 5813# print "\n ** marking $cmd as renewed **"; 5814# $renew_command{$cmd} = 1; 5815 }; 5816 if ((!$PREAMBLE)&&($renewed>1)) { 5817# local($this_cmd) = join('' 5818# , "\n\\renewcommand{\\$cmd}" 5819# , ($argn ? "[$argn]" :'') 5820# , (($opt =~ /^}$/) ? '' : "[$opt]" ) 5821# , "{", $body , "}\n" ); 5822# $latex_body .= &revert_to_raw_tex($this_cmd); 5823 $latex_body .= "\n\\renew". $this_cmd."\n"; 5824 } else { 5825## &add_to_preamble('command',"\\" . $this_cmd); 5826 } 5827 } else { 5828 &add_to_preamble('command',"\\new" . $this_cmd) 5829 unless ($PREAMBLE); 5830 } 5831 undef $body; 5832 if ($renewed == 2) { 5833 # there is no output to return 5834 $$after_R = $_; 5835 return(); 5836 } 5837 5838 if (!$PREAMBLE) { 5839 $$after_R = $_; 5840 return ($new_cmd) if ($renewed); 5841# $cmd_br =~ s/\\//; 5842# ( join ('', &make_deferred_wrapper(1) 5843# , "\\". ($renewed ? (($renewed =~ /provide/)? 'provid' : 'renew') 5844# : 'new')."edcommand" 5845# , $cmd_br , ($argn ? "[$argn]" :'') 5846# , ( ($opt =~ /^\}$/ ) ? '' : "[$opt]" ) , $body_br 5847# , &make_deferred_wrapper(0)) , $_ ); 5848 $new_cmd = join('', "command{\\$cmd}" 5849 , ($argn ? "[$argn]" :'') 5850 , (($opt =~ /^\}$/) ? '' : "[$opt]" ) 5851 , "{", $body , "}" ); 5852 $new_cmd = &revert_to_raw_tex($new_cmd); 5853 &add_to_preamble('command', "\\provide".$new_cmd ); 5854 $$after_R = $_; 5855 return(); 5856 } 5857 $new_cmd =~ s/\\$cmd([\d\W]|$)/$cmd$1/s; 5858 $$after_R = $_; 5859 $new_cmd; 5860} 5861 5862sub replace_new_command { 5863 local($cmd) = @_; 5864 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 5865 do { ### local($_) = $body; 5866 &make_unique($body); 5867 } if ($body =~ /$O/); 5868 $body =~ s/(^|[^\\])\~/$1\\nobreakspace /g; 5869 if ($argn) { 5870 do { 5871 local($before) = ''; 5872 local($after) = "\\$cmd ".$_; 5873 $after = &substitute_newcmd; # may change $after 5874 $after =~ s/\\\@#\@\@/\\/o ; 5875 }; 5876 } elsif ($body =~ /\\/) { 5877 $body = &translate_commands($body); # ??? 5878 $_ = $body . $_; 5879 } else { $_ = $body . $_; } 5880 $_; 5881} 5882 5883sub get_body_let { 5884# local(*_) = @_; 5885 local($_) = @_; 5886 local($cmd,$body,$replace,$tmp,$pat); 5887 ($cmd,$body) = &get_next_tex_cmd; 5888 s/^\s*=?\s*/$body .= $&;''/e; 5889 ($replace,$pat) = &get_next_tex_cmd; 5890# return() if ($replace eq $cmd); 5891 $body .= $pat; 5892 $body = &revert_to_raw_tex($body); 5893 &add_to_preamble('', "\\let ".$body ); 5894 $_[0] = $_; 5895 if (($replace eq $cmd)||($cmd="\\")||($cmd =~/(style|size)$/)) { 5896 "let ".$body 5897 } else { 5898 $new_command{$cmd} = join(':!:','',"\\$replace ",'}'); 5899 ''; 5900 } 5901} 5902 5903 5904# do not remove the \renewcommand code, since it may be needed 5905# within images. Instead replace it with \renewedcommand; 5906# This will be reverted in &revert_to_raw_tex 5907sub get_body_renewcommand { 5908 local($ALLOW_REDEFINE) = 1; 5909 local($renew, $n_after) = &process_body_newcommand(1,@_); 5910 ($renew ? 'renewed' . $renew : ''); 5911} 5912 5913sub do_cmd_renewedcommand { 5914 local($_) = @_; 5915 local($ALLOW_REDEFINE) = 1; 5916 &process_body_newcommand(2,\$_); 5917 $_ ; 5918} 5919 5920sub get_body_providecommand { 5921 local($provide, $n_after) = &process_body_newcommand('provide',@_); 5922 (($PREAMBLE && $provide) ? 'provided'.$provide : ''); 5923} 5924 5925sub do_cmd_providedcommand{ &do_cmd_renewedcommand(@_) } 5926 5927sub get_body_DeclareRobustCommand { 5928 local($provide, $n_after) = &process_body_newcommand('provide',@_); 5929 (($PREAMBLE && $provide) ? 'provided'.$provide : ''); 5930} 5931 5932sub get_body_DeclareMathOperator { 5933 local($after_R) = @_; 5934 local($_) = $$after_R; 5935 my $star; 5936 s/^\\DeclareMathOperator\s*(\*|star)/$star = $1;''/s; 5937 my ($mcmd,$patA) = &get_next(1); 5938 my ($mop,$patB) = &get_next(1); 5939 if ($star) { 5940 $patA .= "${O}0$C\\mathop${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_; 5941 } else { 5942 $patA .= "${O}0$C${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_; 5943 } 5944 local($provide, $n_after) = &process_body_newcommand('provide',\$patA); 5945 $$after_R = $patA; 5946 (($PREAMBLE && $provide) ? 'provided'.$provide : ''); 5947} 5948 5949sub get_body_DeclareMathOperatorstar { 5950 local($after_R) = @_; 5951 local($_) = $$after_R; 5952 my $star; 5953 s/^\\DeclareMathOperator\s*(\*|star)/$star = $1;''/s; 5954 my ($mcmd,$patA) = &get_next(1); 5955 my ($mop,$patB) = &get_next(1); 5956 $patA .= "${O}0$C\\mathop${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_; 5957 local($provide, $n_after) = &process_body_newcommand('provide',\$patA); 5958 $$after_R = $patA; 5959 (($PREAMBLE && $provide) ? 'provided'.$provide : ''); 5960} 5961 5962 5963# Removes the definition from the input string, adds to the preamble 5964# and stores the body in %new_environment; 5965sub get_body_newenvironment { 5966 local($newed,$after) = &process_body_newenvironment(0,@_); 5967 ( $PREAMBLE ? "newed".$newed : ''); 5968} 5969 5970sub process_body_newenvironment { 5971# local($renew,*_) = @_; 5972 local($renew,$after_R) = @_; 5973 local($_) = $$after_R; 5974 local($no_change) = $_; 5975 local($argn,$env,$begin,$end,$tmp,$opt,$pat); 5976 local($new_env) = 'environment'; 5977 if ($renew == 2) { 5978 $env = &missing_braces unless ( 5979 (s/$next_pair_pr_rx/$pat=$&;$env=$2;''/e) 5980 ||(s/$next_pair_rx/$pat=$&;$env=$2;''/e)); 5981 $new_env .= $pat; 5982 } else { 5983 ($env,$pat) = &get_next(1); # Get the environment name 5984 $env =~ s/^\s*\\//; $new_env .= $pat; 5985 } 5986 ($argn,$pat) = &get_next(0); # Get optional no. of args 5987 $argn = 0 unless $argn; $new_env .= $pat if $argn; 5988 5989 # Get the body of the code and store it with the name and number of args 5990 # UNLESS THE COMMAND IS ALREADY DEFINED (see get_body_newcommand) 5991 # ...in which case $ALLOW_REDEFINE must also have been set. # RRM 5992 $opt = '}'; # Flag for no optional arg 5993 if (/^\[/) { 5994 ($opt,$pat) = &get_next(0); 5995 $new_env .= $pat; 5996 } 5997 $tmp = "do_env_$env"; 5998 5999 if ($renewed == 2 ) { 6000 $begin = &missing_braces unless ( 6001 (s/$next_pair_pr_rx/$pat=$&;$begin=$2;''/e) 6002 ||(s/$next_pair_rx/$pat=$&;$begin=$2;''/e)); 6003 $new_env .= $pat; 6004 $end = &missing_braces unless ( 6005 (s/$next_pair_pr_rx/$pat=$&;$end=$2;''/e) 6006 ||(s/$next_pair_rx/$pat=$&;$end=$2;''/e)); 6007 $new_env .= $pat; 6008 } else { 6009 ($begin,$pat) = &get_next(1); $new_env .= $pat; 6010 ($end,$pat) = &get_next(1); $new_env .= $pat; 6011 } 6012 if ((defined &$tmp)&&($ALLOW_REDEFINE)) { 6013 print STDOUT "\n*** redefining environment {$env} ***\n"; 6014 &write_warnings("\nredefined environment {$env} "); 6015 } 6016 $new_environment{$env} = join(':!:', $argn, $begin, $end, $opt) 6017 unless ((defined &$tmp)&&(! $ALLOW_REDEFINE)); 6018 6019 if (!$PREAMBLE) { 6020 $new_env = join ('', 6021 , "environment{$env}" 6022 , ($argn ? "[$argn]" : '') 6023 , (($opt ne '}')? "[$opt]" : '') 6024 , "{$begin}{$end}" 6025 ); 6026 &revert_to_raw_tex($new_env); 6027 if ($renew == 2) { 6028 $latex_body .= "\n\\".($renew ? 're':'').'new'.$new_env."\n"; 6029 } else { 6030 &add_to_preamble ('environment' 6031 , "\\".($renew ? 're':'').'new'.$new_env ); 6032 } 6033 $$after_R = $_; 6034 return(); 6035 } 6036 if ($new_env =~ /$sections_rx/) { 6037 $new_env = join('', $`,'\csname ',$2,'\endcsname',$3,$'); 6038 } 6039 $new_env =~ s/$par_rx/\\par /g; 6040 $$after_R = $_; 6041 $new_env; 6042} 6043 6044sub get_body_renewenvironment { 6045 local($ALLOW_REDEFINE) = 1; 6046 local($renewed, $after) = &process_body_newenvironment(1,@_); 6047 'renewed'.$renewed; 6048} 6049 6050sub do_cmd_renewedenvironment { 6051 local($ALLOW_REDEFINE) = 1; 6052 local($_) = @_; 6053 &process_body_newenvironment(2,\$_); 6054 $_; 6055} 6056 6057# Instead of substituting as with newcommand and newenvironment, 6058# or generating code to handle each new theorem environment, 6059# it now does nothing. This forces theorem environments to be passed 6060# to latex. Although it would be possible to handle theorem 6061# formatting in HTML as it was done previously it is impossible 6062# to keep the theorem counters in step with other counters (e.g. equations) 6063# to which only latex has access to. Sad... 6064sub get_body_newtheorem { 6065# local(*_) = @_; 6066 local($after_R) = @_; 6067 local($_) = $$after_R; 6068 my ($orig, $body) = ($_, ''); 6069 my ($title, $env, $ctr, $within, $cmd, $tmp, $begin, $end, $pat); 6070 my ($new_thm) = 'theorem'; 6071 # Just chop off the arguments and append to $next_def 6072 ($env,$pat) = &get_next(1); $new_thm .= $pat; 6073 ($ctr,$pat) = &get_next(0); $new_thm .= $pat; 6074 ($title,$pat) = &get_next(1); $new_thm .= $pat; 6075 ($within,$pat) = &get_next(0); $new_thm .= $pat; 6076 6077 #check the style parameters 6078 my ($hfont,$bfont,$thm_style); 6079 my ($before_thm) = join('',@processed); 6080 my ($which,$cmds); 6081 while ($before_thm =~ /$theorem_cmd_rx/) { 6082 $which = $1; 6083 $before_thm = $'; 6084 $before_thm =~ s/$next_pair_rx/$cmds = $2;''/e; 6085 $cmds =~ s/\\/\|/g; # escape any backslash 6086 if ($which =~ /style/) { $thm_style = $cmds } 6087 elsif ($which =~ /header/) { $hfont = $cmds } 6088 elsif ($which =~ /body/) { $bfont = $cmds } 6089 } 6090 $hfont = '['.$hfont.']'; 6091 $bfont = '['.$bfont.']'; 6092 $thm_style = '['.$thm_style.']'; 6093 undef $before_thm; 6094 6095 if (!($ctr)) { 6096 # define the new counter 6097 $ctr = $env; 6098 do { 6099### local($_) = "\\arabic<<1>>$ctr<<1>>"; 6100### $_ = join('',"\\the$within", "." , $_) if ($within); 6101 $body = "\\arabic<<1>>$ctr<<1>>"; 6102 $body = join('',"\\the$within", "." , $body) if ($within); 6103 &make_unique($body); 6104 $cmd = "the$ctr"; 6105 $tmp = "do_cmd_$cmd"; 6106 do { 6107 $new_command{$cmd} = join(':!:',0,$body,'}') 6108 } unless (defined &$tmp); 6109 &write_mydb("new_command", $cmd, $new_command{$cmd}); 6110 eval "sub do_cmd_$cmd {\n" 6111 . 'local($_,$ot) = @_;'."\n" 6112 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'."\n" 6113 . '&translate_commands(' . "\"$body\"" . ");\n}\n"; 6114 print STDERR "\n*** sub $tmp failed:\n$@\n" if ($@); 6115 $raw_arg_cmds{$cmd} = 1; 6116 undef $body; 6117 }; 6118 &do_body_newcounter($ctr); 6119 } else { 6120 do { 6121### local($_) = "\\arabic<<1>>$ctr<<1>>"; 6122 $body = "\\arabic<<1>>$ctr<<1>>"; 6123 &make_unique($body); 6124 $cmd = "the$env"; 6125 $tmp = "do_cmd_$cmd"; 6126 do { 6127 $new_command{$cmd} = join(':!:',0,$body,'}') 6128 } unless (defined &$tmp); 6129 &write_mydb("new_command", $cmd, $new_command{$cmd}); 6130 eval "sub do_cmd_$cmd {\n" 6131 . 'local($_,$ot) = @_;' 6132 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;' 6133 . '&translate_commands(' . "\"$body\"" . ");\n}\n"; 6134 print STDERR "\n*** sub $tmp failed:\n$@\n" if ($@); 6135 $raw_arg_cmds{$cmd} = 1; 6136 undef $body; 6137 }; 6138 } 6139 6140 # record the counter dependency 6141 &addto_dependents($within,$ctr) if ($within); 6142 6143 # save the text-label in the %new_theorem hash 6144 $new_theorem{$env} = $title; 6145 6146 # define a new environment 6147 my ($id) = ++$global{'max_id'}; 6148 $begin = "\\begin<<$id>>theorem_type<<$id>>" 6149 . "[$env][$ctr][$within]$thm_style$hfont$bfont\n"; 6150 $id = ++$global{'max_id'}; 6151 $end = "\\end<<$id>>theorem_type<<$id>>\n"; 6152 $tmp = "do_env_$env"; 6153 if ((defined &$tmp)&&($ALLOW_REDEFINE)) { 6154 print STDOUT "\n*** redefining theorem environment {$env} ***\n"; 6155 } 6156 $new_environment{$env} = join(':!:', '', $begin, $end, '') 6157 unless ((defined &$tmp)&&(! $ALLOW_REDEFINE)); 6158 6159 if (!$PREAMBLE) { 6160 my ($new_cmd) = join('' 6161 , 'theorem{}' ); 6162 &add_to_preamble('theorem', "\\new".$new_cmd ); 6163 $$after_R = $_; 6164 return(); 6165 } 6166 $$after_R = $_; 6167 'newed'.$new_thm; 6168} 6169 6170sub do_cmd_theoremstyle { 6171 local($_) = @_; 6172 local($thm_type); 6173 $thm_type = &missing_braces unless ( 6174 (s/$next_pair_pr_rx/$thm_type=$2;''/e) 6175 ||(s/$next_pair_rx/$thm_type=$2;''/e)); 6176# $THM_STYLE = $thm_type; 6177 $_; 6178} 6179sub do_cmd_theoremheaderfont { 6180 local($_) = @_; 6181 local($thm_type); 6182 $thm_type = &missing_braces unless ( 6183 (s/$next_pair_pr_rx/$thm_type=$2;''/e) 6184 ||(s/$next_pair_rx/$thm_type=$2;''/e)); 6185# $THM_HFONT = $thm_type; 6186 $_; 6187} 6188sub do_cmd_theorembodyfont { 6189 local($_) = @_; 6190 local($thm_type); 6191 $thm_type = &missing_braces unless ( 6192 (s/$next_pair_pr_rx/$thm_type=$2;''/e) 6193 ||(s/$next_pair_rx/$thm_type=$2;''/e)); 6194# $THM_BFONT = $thm_type; 6195 $_; 6196} 6197 6198sub do_env_theorem_type { 6199 local($_) = @_; 6200 local($dum,$env,$ctr,$within, $label, $name, $title, $text, $index); 6201 ($env, $dum) = &get_next_optional_argument; 6202 ($ctr, $dum) = &get_next_optional_argument; 6203 ($within, $dum) = &get_next_optional_argument; 6204 6205 local($thm_num, $thm_style); 6206 # defaults for plain theorem-style 6207 my ($hfont,$bfont) = ('',''); 6208 6209 ($thm_style, $dum) = &get_next_optional_argument; 6210 ($hfont, $dum) = &get_next_optional_argument; 6211 $hfont =~ s/\|/\\/og; 6212 ($bfont, $dum) = &get_next_optional_argument; 6213 $bfont =~ s/\|/\\/og; 6214 6215 # the pre-defined alternative theorem-styles 6216 if ($thm_style =~ /definition/) { 6217 $bfont = '\normalfont' unless $bfont; 6218 } elsif ($thm_style =~ /remark/) { 6219 $hfont = '\itshape' unless $hfont; 6220 $bfont = '\normalfont' unless $bfont; 6221 } 6222 6223 # defaults for plain theorem-style 6224 $hfont = '\bfseries' unless $hfont; 6225 $bfont = '\itshape' unless $bfont; 6226 6227 ($name, $dum) = &get_next_optional_argument; 6228 $name = &translate_environments("${O}0$C".$name."${O}0$C") if $name; 6229 $name = &translate_commands($name) if ($name =~ /\\/); 6230 6231 $index = $section_commands{$ctr}; 6232 if ($index) { 6233 # environment actually starts a new (sub-)section 6234 $curr_sec_id[$index]++; 6235 local($this) = &translate_commands("\\the$ctr"); 6236 local($hash) = &sanitize($name." $this"); 6237 local($section_tag) = join('', @curr_sec_id); 6238 $encoded_section_number{$hash} = join($;, $section_tag); 6239 &reset_dependents($ctr) if ($dependent{$ctr}); 6240 $thm_num = &translate_commands("\\the$ctr"); 6241 $thm_num =~ s/(\w)\.(\.\w)/$1$2/g; 6242 6243 # construct the sectioning title from the counter values 6244 $title = join( '', $new_theorem{$env}, " " 6245 , &translate_commands("\\the$ctr") ); 6246 $toc_section_info{join(' ',@curr_sec_id)} = \ 6247 "$current_depth$delim$CURRENT_FILE$delim$title" 6248 if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 6249 $section_info{join(' ',@curr_sec_id)} = \ 6250 "$current_depth$delim$CURRENT_FILE$delim$title$delim"; 6251 $title = join('',"<A NAME=\"SECTION$section_tag\"><B>" 6252 , $title , "</B></A>" ); 6253 } else { 6254 if ($ctr) { 6255 print STDOUT "\nSTP:$ctr:+1" if ($VERBOSITY > 3); 6256 $global{$ctr}++; 6257 print STDOUT "=".$global{$ctr}." " if ($VERBOSITY > 3); 6258 &reset_dependents($ctr) if ($dependent{$ctr}); 6259 $thm_num = "\\the$ctr "; 6260 } else { $thm_num = ''; } 6261 6262 # construct the full title from the counter values 6263 $title = $new_theorem{$env}; 6264 if (($thm_style =~ /margin/)&&($HTML_VERSION > 2.1)) { 6265 # don't use the number yet 6266 } elsif ($thm_style =~ /change/) { 6267 $title = join(' ', $thm_num, "\\space", $title) 6268 } else { 6269 $title = join(' ', $title, "\\space", $thm_num); 6270 } 6271 6272 if ($hfont) { 6273 $title = join('',$O,++$global{'max_id'},$C,$hfont," " 6274 , $title, $O,++$global{'max_id'},$C); 6275 $title = &translate_environments($title); 6276 $title = &translate_commands($title); 6277 } else { 6278 $title = join('',"<B>",&translate_commands($title),"</B>"); 6279 } 6280 $title =~ s/(\w)\.(\.\w)/$1$2/g; 6281 } 6282 # extract any name or label that may occur at the start 6283 s/^\s*(\\label(($O|$OP)\d+($C|$CP))([^<]*)\2)?\s*(\(([^\)]*)\))?/ 6284 $label=$1; $text=$5; $name=$7 if ($7); ''/eo; 6285 if ($label) { 6286 $label = &anchor_label($text,$CURRENT_FILE,''); 6287 $label =~ s/$anchor_mark/$title/; 6288 $title = $label; 6289 } 6290 if ($name) { 6291 $name =~ s/^\s*|\s*$//g; 6292 $name = join('', " (", $name, ") ") if $name; 6293 } 6294 local($attribs, $border); 6295 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 6296 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 6297 6298 $_ = join('', $O,++$global{'max_id'},$C, $bfont 6299 , " ", $_ ,$O,++$global{'max_id'},$C) if ($bfont); 6300 6301 my($cmd) = 'do_thm_'.$env; 6302 if (defined &$cmd) { 6303 $_ = &$cmd($ctr, $title, $_); 6304 } else { 6305 $_ = &translate_environments($_); 6306 $_ = &translate_commands($_); 6307 } 6308 6309 if ($thm_style =~ /margin/) { 6310 local($valign); 6311 $valign = ($NETSCAPE_HTML ? ' VALIGN="BASELINE"':''); 6312 if ($hfont) { 6313 $thm_num = join('',$O,++$global{'max_id'},$C,$hfont," " 6314 , $thm_num, $O,++$global{'max_id'},$C); 6315 $thm_num = &translate_environments($thm_num); 6316 $thm_num = &translate_commands($thm_num); 6317 } else { 6318 $thm_num = join('',"<B>",&translate_commands($thm_num),"</B>"); 6319 } 6320 $thm_num =~ s/(\w)\.(\.\w)/$1$2/g; 6321 6322 # code copied from &make_table 6323 local($Tattribs); 6324 if ($attribs) { 6325 if (!($attribs =~ /=/)) { 6326 $Tattribs = &parse_valuesonly($attribs,"TABLE"); 6327 } else { 6328 $Tattribs = &parse_keyvalues($attribs,"TABLE"); 6329 } 6330 $Tattribs = ' '.$Tattribs if ($Tattribs); 6331 } 6332 $_ = join ('', "\n<P><DIV$env_id><TABLE" 6333 , (($border) ? " BORDER=\"$border\"" : '') 6334 , $Tattribs , ">\n<TR VALIGN=\"TOP\">" 6335 , "<TD$valign>", &translate_commands($thm_num) 6336 , "</TD>\n<TD>", $title, $name 6337 , (($thm_style =~ /break/)? "\n<BR>":" \ \n") 6338 , $_ , "\n</TD></TR></TABLE></DIV>"); 6339 } else { 6340 $_ = join('', "<P><DIV$env_id>" 6341 , $title, $name 6342 , (($thm_style =~ /break/)? "\n<BR>":" \ \n") 6343 , $_ 6344 ,"</DIV><P></P>\n"); 6345 if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 6346 &make_table( $border, $attribs, '', '', '', $_ ) 6347 } else { $_ } 6348 } 6349} 6350 6351# Modifies $_ in the caller and as a side-effect it modifies $next_def 6352# which is local to substitute_meta_cmds 6353sub get_next { 6354 local($what) = @_; 6355 local($next, $pat, $tmp); 6356 if ($what == 1) { 6357 ($next, $tmp, $pat) = &get_next_argument; 6358 } 6359 elsif ($what == 2) { 6360 ($next, $pat) = &get_next_tex_cmd; 6361 } 6362 elsif ($what == 3) { 6363 ($next, $pat) = &get_next_def_arg; 6364 } 6365 elsif ($what == 4) { 6366 ($next, $tmp, $pat) = &get_next_argument; 6367 } 6368 else { 6369 ($next, $pat) = &get_next_optional_argument; 6370 } 6371 do { 6372 $next_def .= &revert_to_raw_tex($pat) if $pat; 6373 } unless ($renewed); # don't add \renewcommand to preamble 6374# $next =~ s/(^\s*)|(\s*$)//g unless ($what == 4); #don't lose white space on body 6375 $next =~ s/(^\s*)|(\s*$)//g unless ($what =~ /[14]/); #retain white space in body 6376 ($next, $pat); 6377} 6378 6379# The following get_next_<something> ARE ALL DESTRUCTIVE. 6380sub get_next_argument { 6381 local($next, $br_id, $pat); 6382 if (!(s/$next_pair_rx/$br_id=$1;$next=$2;$pat=$&;''/seo)) { 6383 print " *** Could not find argument for command \\$cmd ***\n"; 6384 print "$_\n"; 6385 }; 6386 ($next, $br_id, $pat); 6387} 6388 6389sub get_next_pair_or_char_pr { 6390 local($next, $br_id, $pat, $epat); 6391 if ( /^\{([^\}]*)\}/o && (! $`)) { 6392 ($next, $pat) = ($1, $&); 6393 } elsif ( (/^\s*([^\s\\<])/o && (! $`))) { 6394 ($next, $pat) = ($1, $&); 6395 } elsif ( /$next_pair_pr_rx/o && (! $`)) { 6396 ($next, $br_id, $pat) = ($2, $1, $&); 6397 }; 6398 $epat = &escape_rx_chars($pat); 6399 s/$epat// if $pat; 6400 ($next, $br_id, $pat); 6401} 6402 6403sub get_next_optional_argument { 6404 local($next, $pat); 6405 s/$optional_arg_rx/$next=$1;$pat=$&;''/eo 6406 if (/\s*[[]/ && (! $`)); # if the first character is a [ 6407 #remove trailing spaces and/or comments 6408 s/^($comment_mark(\d+\n?)?|$EOL)//gos; 6409 6410 # if nested inside {}s we need to get more tokens 6411 if ($pat) { 6412 # check for \item, indicating something has gone wrong 6413 if ($pat =~ /\\item\b/ ) { 6414 print "\n*** optional argument badly formed:\n" . $pat . "\n\n"; 6415 $_ = $pat . $_; 6416 return('',''); 6417 } 6418 # check for being nested inside {}s 6419 local($found) = $pat; 6420 while ($found =~ s/$O(\d+)$C[\s\S]*$O\1$C//g) { 6421 if ($found =~ /$O(\d+)$C/) { 6422 local($br_id) = $1; 6423 if (s/$O$br_id$C//) { 6424 $found .= $`.$&; 6425 $pat .= "]".$`.$&; 6426 $next .= "]".$`.$&; 6427 $_ = $'; 6428 s/^([^]]*)\]/$next.=$1;$pat.=$&;''/e; 6429 $found .= $&; 6430 } else { last } # give up if no closing brace 6431 } 6432 } 6433 } else { 6434 s/^\s*\[\]/$pat=$&;''/e; # This is not picked by $optional_arg_rx 6435 } 6436 ($next, $pat); 6437} 6438 6439#JCL(jcl-del) - use new form of $single_cmd_rx. 6440sub get_next_tex_cmd { 6441 local($next, $pat); 6442 s/^\s*\=?\s*$single_cmd_rx/$4/; 6443 ($next, $pat) = ($1.$2,"\\".$1.$2); 6444} 6445 6446sub get_next_def_arg { 6447 local($next, $pat); 6448 6449 # Sets is_simple_def for caller. Start by turning it off, then 6450 # turn it on if we find one of the "simple" patterns. 6451 6452 # This has got to be hit-or-miss to an extent, given the 6453 # thoroughly incestuous relationship between the TeX macroprocessor 6454 # ('mouth') and typesetting back-end ('stomach'). Anything which 6455 # even does catcode hacking is going to lose BAD. 6456 6457 s/^\s*//so; # Remove whitespace 6458 6459 $is_simple_def = 0; 6460 6461 # no arguments 6462 6463 if (/^$O/ && (! $`)) { $next=0; $pat=''; $is_simple_def=1; } 6464 6465 # 'simple' arguments 6466 6467 if (! $is_simple_def && /$tex_def_arg_rx/o && (! $`)) { 6468 s/$tex_def_arg_rx/$next=$1; $pat=$&; $is_simple_def=1; $2/seo; } 6469 6470 # MESSY arguments 6471 6472 if (! $is_simple_def) { 6473 print "Arguments to $cmd are too complex ...\n"; 6474 print "It will not be processed unless used in another environment\n"; 6475 print "which is passed to LaTeX whole for processing.\n"; 6476 6477 s/^[^<]*(<[^<]+)*<</$next=''; $pat=$&; $O/seo; 6478 } 6479 6480 $pat =~ s/$O$//so; 6481 6482 ($next, $pat); 6483} 6484 6485#### Key-value parsing added by RRM 6486# 6487# This cleans-up the key-value pairs for a given tag, 6488# by removing unnecessary spaces and commas, inserting quotes 6489# around the value and puts a preceding space. 6490# The key becomes upper-case, while the value becomes lower-case. 6491# If specific `tags' are provided, then checking is done to verify 6492# that the keys and values are valid for these tags, eliminating 6493# any that are not; unmatched keys or values are handled as well. 6494# If no tags are provided, then just a list of pairs is returned. 6495# 6496sub parse_keyvalues { 6497 local($_,@tags) = @_; 6498 local($key,$KEY,$attribs,$atts,%attributes)=('','','',''); 6499 6500 # beware active " in german 6501 local($is_german); 6502 if (s/\"/'/g) { 6503 $is_german=1; 6504 s/(^|[\s,=])(\&\#\d\d\d;)/$1'$2/g 6505 } 6506 local($saved) = &revert_to_raw_tex(&translate_commands($_)); 6507 print "\nATTRIBS: $saved\n" if ($VERBOSITY > 6); 6508 6509 $saved =~ s/$percent_mark/%/g; 6510 $saved =~ s/((^|[\s,=])')\\\W\{(\w)}/$1$3/g 6511 if $is_german; #unwanted accents, from active " 6512 if (@tags) { 6513 foreach $tag (@tags) { 6514 $_ = $saved; 6515 local($name)= $tag."_attribs"; 6516 $taglist = $$name; 6517 $name .= "_rx_list"; 6518 $taglist .= $$name; 6519 $taglist =~ s/,,/,/; 6520# s/(^|,)\s*([a-zA-Z]+)\s*\=\s*"?([\#\%\w\d]+)"?\s*/$attributes{$2}="$3";''/eg; 6521# s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([#%\w\d]*))\s*/ 6522# s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([#%&@;:+-\/\w\d]*))\s*/ 6523 s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([^<>,=\s]*))\s*/ 6524 $attributes{$2}=($4?$4:($5?$5:$6));' '/eg; 6525 foreach $key (keys %attributes){ 6526 $KEY = $key; 6527 $KEY =~ tr/a-z/A-Z/; 6528 if ($taglist =~ /,$KEY,/i) { 6529 local($keyname) = $tag."__".$KEY; 6530 local($keyvalues) = ''; 6531 if ($$keyname) { 6532 $keyvalues = $$keyname; 6533 $atts = $attributes{$key}; 6534 if ($keyvalues =~ /\,$atts\,/i ) { 6535# $atts =~ tr/A-Z/a-z/; 6536 $attribs .= " $KEY=\"$atts\""; 6537 print "\n$KEY=$atts " if ($VERBOSITY > 3); 6538 } else { &invalid_tag($tag,$KEY,$atts); } 6539 } else { # test for a regular expression 6540 $keyname = $keyname."_rx"; 6541 if ($$keyname) { 6542 $keyvalues = $$keyname; 6543 $atts = $attributes{$key}; 6544 if ($atts =~ /$keyvalues/) { 6545# $atts =~ tr/A-Z/a-z/; 6546 $attribs .= " $KEY=\"$atts\""; 6547 print "\n$KEY=$atts " if ($VERBOSITY > 3); 6548 } else { &invalid_tag($tag,$KEY,$atts) } 6549 } else { 6550 $atts = $attributes{$key}; 6551# $atts =~ tr/A-Z/a-z/; 6552 $attribs .= " $KEY=\"$atts\""; 6553 print "\n$KEY=$atts " if ($VERBOSITY > 3); 6554 } 6555 } 6556 } else { 6557 print "\n$key not in $taglist for $tag" if ($VERBOSITY > 3); 6558 } 6559 } 6560 } 6561 s/(^|\s,)\'([^\s,]*)\'(\s|$)/$1$2 /g if $is_german; 6562 $attribs .= &parse_valuesonly($_,@tags); 6563 } else { 6564 # with no tags provided, just list the key-value pairs 6565 $_ = $saved; 6566 s/\s*(\w+)\s*=\s*\"?(\w+)\"?\s*,?/$attributes{$1}=$2;''/eg; 6567 foreach $key (keys %attributes){ 6568 $KEY = $key; 6569 $KEY =~ tr/a-z/A-Z/; 6570 $atts = $attributes{$key}; 6571 $atts =~ tr/A-Z/a-z/; 6572 $attribs .= " $KEY=\"$atts\""; 6573 } 6574 } 6575 $attribs; 6576} 6577 6578sub invalid_tag { 6579 local($tag,$key,$value) = @_; 6580 &write_warnings("$key=$value is an invalid value in the <$tag> tag\n"); 6581} 6582 6583# RRM 6584# This creates key-value pairs from values only, 6585# by checking whether the data matches any key to the provided tags. 6586# Only the first match found is retained. 6587# Attributes with no values are also recognised here. 6588# 6589sub parse_valuesonly { 6590 local($values,@tags) = @_; 6591 local($i,$tag,$key,$KEY,$attribs,$atts)=(0,'','','','',''); 6592 local($saved) = &revert_to_raw_tex(&translate_commands($values)); 6593 $saved =~ s/$percent_mark/%/g; 6594 foreach $tag (@tags) { 6595 local($name)= $tag."_attribs"; 6596 $taglist = $$name; 6597 $values = $saved; 6598 $values =~ s/\s*\"?([^,\s\"]+)\"?\s*,?/$i++;$attributes{$i}=$1;''/eg; 6599 local($j) = 0; 6600 while ($j < $i) { 6601 $j++; 6602 $key = $attributes{$j}; 6603 if ($taglist =~ /,$key,/i) { 6604 $KEY = $key; 6605 $KEY =~ tr/a-z/A-Z/; 6606 $attribs .= " $KEY"; 6607 print " $KEY" if ($VERBOSITY > 3); 6608 } else { 6609 $atts = $attributes{$j}; 6610 $key = &find_attribute($key,$tag); 6611 if ($key) { 6612 $KEY = $key; 6613 $KEY =~ tr/a-z/A-Z/; 6614 $atts =~ tr/A-Z/a-z/; 6615 $attribs .= " $KEY=\"$atts\""; 6616 print " $KEY = $atts" if ($VERBOSITY > 3); 6617 } else { } 6618 } 6619 } 6620 } 6621 $attribs; 6622} 6623 6624# RRM 6625# Extracts key-value pairs using a supplied (comma-separated) list. 6626# When no list is given, it checks for a pre-defined list for the tag. 6627# 6628sub extract_attributes { 6629 local($tag,$taglist,$_) = @_; 6630 local($key,$attribs,$unused,%attributes); 6631 if (! ($taglist)) { 6632 local($name) = "$tag"."_attribs"; 6633 if ($$name) { $taglist = $$name } 6634 } 6635 s/\s*(\w+)\s*=\s*\"?(\w+)\"?\s*,?/$attributes{$1}=$2;''/eg; 6636 foreach $key (keys %attributes){ 6637 if ($taglist =~ /\,$key\,/) { 6638 $attribs .= " $key=\"$attributes{$key}\""; 6639 &write_warnings("valid attribute $key for $tag\n"); 6640 } else { 6641 &write_warnings("unknown attribute $key for $tag\n"); 6642 $unused .= " $key=\"$attributes{$key}\""; 6643 } 6644 } 6645 ($attribs,$unused); 6646} 6647 6648# RRM 6649# Finds the attribute of a given tag, for which a given value is valid. 6650# Requires variables: <tag>_<key> to be a comma-separated list of keys. 6651# So far it cannot recognise data-types, only names. 6652# 6653sub find_attribute { 6654 local($key,$attrib,$tag) = ('',@_); 6655 local($name) = $tag."_attribs"; 6656 local($attrib_list)=$$name; 6657 if ($attrib_list) { 6658 $attrib_list =~ s/^\,//o; 6659 $attrib_list =~ s/\,$//o; 6660 local(@keys) = split(',',$attrib_list); 6661 local($attrib_vals) = ''; 6662 foreach $key (@keys) { 6663 $name = $tag."__".$key; 6664 $attrib_vals = $$name; 6665 return ($key) if ($attrib_vals =~ /\,$attrib\,/i ); 6666 } 6667 } 6668 $name = $tag."_attribs_rx_list"; 6669 $attrib_list=$$name; 6670 if (!($attrib_list)) { return(); } 6671 $attrib_list =~ s/^\,//o; 6672 $attrib_list =~ s/\,$//o; 6673 @keys = split(',',$attrib_list); 6674 foreach $key (@keys) { 6675 next if ($attribs =~ / $key=/); 6676 $name = $tag."__".$key."_rx"; 6677 $attrib_vals = $$name; 6678 if ( $attrib =~ /^$attrib_vals$/ ) { 6679 return ($key); 6680 } 6681 } 6682 0; 6683} 6684 6685# in case \HTML is defined differently in packages 6686sub do_cmd_HTML { &do_cmd_HTMLcode(@_) } 6687 6688sub do_cmd_HTMLcode { 6689 local($_) = @_; 6690 local($tag,$attribs,$dum); 6691 local($attribs, $dum) = &get_next_optional_argument; 6692 $tag = &missing_braces unless ( 6693 (s/$next_pair_pr_rx/$tag = $2;''/eo) 6694 ||(s/$next_pair_rx/$tag = $2;''/eo)); 6695 $tag = &translate_commands($tag) if ($tag =~ /\\/); 6696 if (! $tag) { 6697 print "*** no tag given with \\HTML command, ignoring it"; 6698 return($_); 6699 } 6700 local($afterHTML) = $_; 6701 local($value,$TAGattribs,$etag); 6702 if (defined $unclosed_tags_list{$tag}) { 6703 } elsif (defined $closed_tags_list{$tag}) { 6704 $value = &missing_braces unless ( 6705 (s/$next_pair_pr_rx/$value = $2;''/eo) 6706 ||(s/$next_pair_rx/$value = $2;''/eo)); 6707 $etag = "</$tag>"; 6708 $afterHTML = $_; 6709 } else { 6710 print "\n*** <$tag> is not a valid tag for HTML $HTML_VERSION"; 6711 print "\n rejecting: \\HTML".(($attribs)? "[$attribs]" : '')."{$tag}"; 6712 return $_ ; 6713 } 6714 if ($dum) { 6715 $attribs = &translate_commands($attribs) if ($attribs=~/\\/); 6716 if ($attribs) { 6717 if (!($attribs =~ /=/)) { 6718 $TAGattribs = &parse_valuesonly($attribs,$tag); 6719 } else { 6720 $TAGattribs = &parse_keyvalues($attribs,$tag); 6721 } 6722 } 6723 } else { } # default if no [...] 6724 local($needed) = join(',' 6725 , $closed_tags_list{$tag},$unclosed_tags_list{$tag}); 6726 $needed =~ s/,,/,/g; $needed =~ s/^,|,$//g; 6727 if ($TAGattribs) { 6728 if ($needed) { 6729 $needed =~ s/,,/,/g; 6730 local($this, @needed); 6731 (@needed) = split(',',$needed); 6732 foreach $this (@needed) { 6733 next unless ($this); 6734 next if ($TAGattribs =~ /\b$this\b/); 6735 print "\n*** attribute $this required for <$tag> ***"; 6736 print "\n rejecting: \\HTML".(($attribs)? "[$attribs]" : '')."{$tag}"; 6737 return($value.$afterHTML); 6738 } 6739 } 6740 $value = &translate_environments($value); 6741 $value = &translate_commands($value) if ($value =~ /\\/); 6742 $_ = join('', "<$tag", $TAGattribs, ">", $value, $etag); 6743 } elsif ($needed) { 6744 print STDOUT "\n*** attributes $needed are required for <$tag> ***"; 6745 return($value.$after); 6746 } elsif ($value) { 6747 $value = &translate_environments($value); 6748 $value = &translate_commands($value) if ($value =~ /\\/); 6749 $_ = join('', "<$tag>", $value, $etag); 6750 } else { 6751 $_ = join('', "<$tag>", $etag); 6752 } 6753 $_.$afterHTML; 6754} 6755 6756sub do_cmd_HTMLget { 6757 local($_) = @_; 6758 local($which,$value,$hash,$dummy); 6759 local($hash, $dummy) = &get_next_optional_argument; 6760 $which = &missing_braces unless ( 6761 (s/$next_pair_pr_rx/$which = $2;''/eo) 6762 ||(s/$next_pair_rx/$which = $2;''/eo)); 6763 if ($hash) { 6764 local($tmp) = "\%$hash"; 6765 if (eval "defined \%{$hash}") { $! = ''; 6766 $value = ${$hash}{'$which'}; 6767 } else { print "\nhash: \%$hash not defined" } 6768 } elsif ($which) { 6769 $value = ${$which}; 6770 } 6771 $value.$_; 6772} 6773 6774sub do_cmd_HTMLset { 6775 local($_) = @_; 6776 local($which,$value,$hash,$dummy); 6777 local($hash, $dummy) = &get_next_optional_argument; 6778 $which = &missing_braces unless ( 6779 (s/$next_pair_pr_rx/$which = $2;''/eo) 6780 ||(s/$next_pair_rx/$which = $2;''/eo)); 6781 $value = &missing_braces unless ( 6782 (s/$next_pair_pr_rx/$value = $2;''/eo) 6783 ||(s/$next_pair_rx/$value = $2;''/eo)); 6784 if ($hash) { 6785 local($tmp) = "\%$hash"; 6786 if (eval "defined \%{$hash}") { $! = ''; 6787# eval "\$$hash{'$which'} = \"$value\";"; 6788 ${$hash}{'$which'} = $value; 6789 print "\nHTMLset failed: $! " if ($!); 6790 } else { print "\nhash: \%$hash not defined" } 6791 } elsif ($which) { $! = ''; 6792 eval "\${$which} = \"$value\";"; 6793 print "\nHTMLset failed: $! " if ($!); 6794 } 6795 $_; 6796} 6797 6798sub do_cmd_HTMLsetenv { &do_cmd_HTMLset(@_) } 6799 6800#### 6801 6802 6803# Appends $next_def to the preamble if it is not already there. 6804sub add_to_preamble { 6805 local($type, $next_def) = @_; 6806 local($name); 6807 if ($type =~ /def|include|special|graphicspath/) { 6808 local($pat) = &escape_rx_chars ($next_def); 6809# $preamble .= $next_def . "\n" unless ($preamble =~ /$pat/); 6810 push(@preamble, $pat); 6811 } 6812 elsif ($type =~ /command|environment|theorem|counter/) { 6813 push(@preamble, $next_def ); 6814 } 6815 else { 6816 ($name) = $next_def =~ /$marker\s*({[^}]+})/; # matches type{name} 6817 $name = &escape_rx_chars($name); 6818# $preamble .= $next_def . "\n" unless ($preamble =~ /$marker\s*$name/); 6819 push(@preamble, $name ); 6820 } 6821} 6822 6823sub make_latex{ 6824# This is the environment in which to process constructs that cannot be 6825# translated to HTML. 6826# The environment tex2html_wrap will be wrapped around any shorthand 6827# environments (e.g. $, \(, \[). 6828# The tex2html_wrap environment will be treated as an unrecognised 6829# evironment by the translator and its contents (i.e. the 'shorthand' 6830# environment) will be passed to latex for processing as usual. 6831 local($contents) = @_; 6832 local($preamble) = $preamble; 6833 local($aux_preamble) = $aux_preamble; 6834 while ($preamble =~ s/^(\@.*\n)/$prelatex .= $1;''/e) {} 6835 print "\nPRE-LATEX: $prelatex" if (($prelatex)&&($VERBOSITY > 1)); 6836 6837 %newed_commands = 6838 ( 'newedcommand' , 'newcommand' 6839 , 'renewedcommand' , 'renewcommand' 6840 , 'providedcommand' , 'providecommand' 6841 , 'newedenvironment' , 'newenvironment' 6842 , 'newedboolean' , 'newboolean' 6843 , 'newedcounter' , 'newcounter' 6844 , 'newedtheorem' , 'newtheorem' 6845 , 'newedfont' , 'newfont' , 'newedif', 'newif' 6846 ); 6847 6848 6849 # Make the @ character a normal letter ... 6850 $preamble =~ s/\\par([^A-Za-z]|$)/\n$1/g; 6851 $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n/; 6852 $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n\\RequirePackage{ifthen}\n/ 6853 unless ($preamble =~/\{ifthen\}/); 6854# $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n\\makeatletter/; 6855 # ... and make it special again after the preamble 6856 # remove the \begin/\end for tex2html_nowrap and tex2html_deferred environments 6857 $preamble =~s/\\(begin|end)\s*\{(tex2html_(nowrap|deferred|nomath|preform)[_a-z]*|imagesonly)\}//g; 6858 $preamble =~s/\n?\s?<tex2html_(end)?file>\#[^#]*\#//mg; 6859 6860 $preamble = "\\documentclass\{article\}%\n\\usepackage{html}\n\\usepackage[dvips]{color}\n" 6861 unless ($preamble); 6862 if (($LATEX_DUMP)&&(!($preamble =~ /\\usepackage\{ldump\}/))) { 6863 # MRO: replaced $* with /m 6864 $preamble =~ s/(\\document(class|style)[^\n]*\n)/$1\\usepackage\{ldump\}\n/m; 6865 } 6866 if ($preamble =~ /pstricks/) { 6867 if ($LOAD_LATEX_COLOR) { 6868 $LOAD_LATEX_COLOR =~ s/\{color\}/\{pstcol\}/ ; 6869 } else { 6870 $LOAD_LATEX_COLOR = "\n\\usepackage[dvips]{pstcol}\n"; 6871 } 6872 } else { 6873 $LOAD_LATEX_COLOR = "\n\\usepackage[dvips]{color}"; 6874 } 6875 $LATEX_COLOR = "\\pagecolor[gray]{.85}\\nobreak " unless $LATEX_COLOR; 6876 if ($preamble =~ /(^|\s*[^%])\s*\\documentstyle/) { 6877 # \usepackage is invalid in LaTeX 2.09 and LaTeX-2e compatibility mode 6878 $LATEX_COLOR = ''; $LOAD_LATEX_COLOR = ''; 6879 # ... so is \providecommand 6880 $preamble =~ s/\\documentstyle[^{]*{[^}]*}\n?/ 6881 $&."\n\\let\\providecommand\\newcommand\n"/eo; 6882 } 6883 6884 $preamble .= $LOAD_LATEX_COLOR."\n" unless ($preamble =~ /[,\{]color[,\}]/); 6885 $preamble .= "\n\n".$LATEX_COLOR."\n" unless ($preamble =~ /\\pagecolor/); 6886 do { 6887 if ($ISOLATIN_CHARS) { $INPUTENC = $INPUTENC || 'latin1' }; 6888 $preamble .= "\n\\usepackage[".$INPUTENC."]\{inputenc\}\n"; 6889 } unless ($preamble =~ /\\inputenc/); 6890 6891 $aux_preamble = '' unless (($aux_preamble)&&($contents =~ /\\(hyper)?(ref|cite)/)); 6892 6893 $preamble =~ s/\\((provide|(re)?new)ed(command|counter|if|theorem|environment|font))\b/ 6894 "%\n\\".$newed_commands{$1}/eg; 6895 $preamble =~ s/(\\(re)?newcommand)\s*(\{(\\?)(\}|[^\}]+)\})/ 6896 $1.(($4)? $3 : "{\\".$5.'}' )/eg; 6897 6898 $preamble =~s/$verbatim_mark(imagesonly)(\d+)#/$verbatim{$2}/eg; # for images.tex only 6899 6900# local($key); 6901# foreach $key (keys %newed_commands) { 6902# $preamble .= "\n\\let\\$key\\".$newed_commands{$key} 6903# } 6904 $preamble .= "\n"; 6905 6906 local($paperwidth) = ''; 6907 if ($PAPERSIZE) { $paperwidth = &adjust_textwidth($PAPERSIZE); } 6908 else { $paperwidth = &adjust_textwidth("a5"); } 6909 local($kern) = ($EXTRA_IMAGE_SCALE ? $EXTRA_IMAGE_SCALE/2 : ".5" ); 6910 $kern = $kern * $MATH_SCALE_FACTOR; 6911 $prelatex . ($DEBUG ? "\\nonstopmode" : "\\batchmode") . 6912 "\n$preamble\n\n\\makeatletter\n$aux_preamble\n" . 6913 "\\makeatletter\n\\count\@=\\the\\catcode`\\_ \\catcode`\\_=8 \n" . 6914 "\\newenvironment{tex2html_wrap}{}{}%\n" . 6915 "\\catcode`\\<=12\\catcode`\\_=\\count\@\n" . 6916 "\\newcommand{\\providedcommand}[1]{\\expandafter\\providecommand\\csname #1\\endcsname}%\n" . 6917 "\\newcommand{\\renewedcommand}[1]{\\expandafter\\providecommand\\csname #1\\endcsname{}%\n" . 6918 " \\expandafter\\renewcommand\\csname #1\\endcsname}%\n" . 6919 "\\newcommand{\\newedenvironment}[1]{\\newenvironment{#1}{}{}\\renewenvironment{#1}}%\n" . 6920 "\\let\\newedcommand\\renewedcommand\n" . 6921 "\\let\\renewedenvironment\\newedenvironment\n" . 6922 "\\makeatother\n" . 6923 "\\let\\mathon=\$\n\\let\\mathoff=\$\n" . 6924 "\\ifx\\AtBeginDocument\\undefined \\newcommand{\\AtBeginDocument}[1]{}\\fi\n" . 6925 "\\newbox\\sizebox\n" . "$paperwidth" . 6926 "\\newwrite\\lthtmlwrite\n" . "\\makeatletter\n" . 6927 "\\let\\realnormalsize=\\normalsize\n\\global\\topskip=2sp\n\\def\\preveqno{}" . 6928 "\\let\\real\@float=\\\@float \\let\\realend\@float=\\end\@float\n" . 6929 "\\def\\\@float{\\let\\\@savefreelist\\\@freelist\\real\@float}\n" . 6930# "\\def\\\@float{\\\@dbflt}\n" . 6931 "\\def\\liih\@math{\\ifmmode\$\\else\\bad\@math\\fi}\n" . 6932 "\\def\\end\@float{\\realend\@float\\global\\let\\\@freelist\\\@savefreelist}\n" . 6933 "\\let\\real\@dbflt=\\\@dbflt \\let\\end\@dblfloat=\\end\@float\n" . 6934 "\\let\\\@largefloatcheck=\\relax\n" . 6935 "\\let\\if\@boxedmulticols=\\iftrue\n" . 6936 "\\def\\\@dbflt{\\let\\\@savefreelist\\\@freelist\\real\@dbflt}\n" . 6937 "\\def\\adjustnormalsize{\\def\\normalsize{\\mathsurround=0pt \\realnormalsize\n" . 6938 " \\parindent=0pt\\abovedisplayskip=0pt\\belowdisplayskip=0pt}%\n" . 6939 " \\def\\phantompar{\\csname par\\endcsname}\\normalsize}%\n" . 6940 "\\def\\lthtmltypeout#1{{\\let\\protect\\string \\immediate\\write\\lthtmlwrite{#1}}}%\n" . 6941 "\\newcommand\\lthtmlhboxmathA{\\adjustnormalsize\\setbox\\sizebox=\\hbox\\bgroup\\kern.05em }%\n" . 6942 "\\newcommand\\lthtmlhboxmathB{\\adjustnormalsize\\setbox\\sizebox=\\hbox to\\hsize\\bgroup\\hfill }%\n" . 6943 "\\newcommand\\lthtmlvboxmathA{\\adjustnormalsize\\setbox\\sizebox=\\vbox\\bgroup %\n". 6944 " \\let\\ifinner=\\iffalse \\let\\)\\liih\@math }%\n" . 6945 "\\newcommand\\lthtmlboxmathZ{\\\@next\\next\\\@currlist{}{\\def\\next{\\voidb\@x}}%\n" . 6946# " \\expandafter\\box\\next\\edef\\next{\\egroup\\def\\noexpand\\thiseqn{\\theequation}}\\next}%\n" . 6947 " \\expandafter\\box\\next\\egroup}%\n" . 6948 "\\newcommand\\lthtmlmathtype[1]{\\gdef\\lthtmlmathenv{#1}}%\n" . 6949 "\\newcommand\\lthtmllogmath{\\dimen0\\ht\\sizebox \\advance\\dimen0\\dp\\sizebox\n" . 6950 " \\ifdim\\dimen0>.95\\vsize\n" . " \\lthtmltypeout{%\n" . 6951 "*** image for \\lthtmlmathenv\\space is too tall at \\the\\dimen0, reducing to .95 vsize ***}%\n" . 6952 " \\ht\\sizebox.95\\vsize \\dp\\sizebox\\z\@ \\fi\n" . " \\lthtmltypeout{l2hSize %\n" . 6953 ":\\lthtmlmathenv:\\the\\ht\\sizebox::\\the\\dp\\sizebox::\\the\\wd\\sizebox.\\preveqno}}%\n" . 6954 "\\newcommand\\lthtmlfigureA[1]{\\let\\\@savefreelist\\\@freelist 6955 \\lthtmlmathtype{#1}\\lthtmlvboxmathA}%\n" . 6956 "\\newcommand\\lthtmlpictureA{\\bgroup\\catcode`\\_=8 \\lthtmlpictureB}%\n" . 6957 "\\newcommand\\lthtmlpictureB[1]{\\lthtmlmathtype{#1}\\egroup 6958 \\let\\\@savefreelist\\\@freelist \\lthtmlhboxmathB}%\n" . 6959 "\\newcommand\\lthtmlpictureZ[1]{\\hfill\\lthtmlfigureZ}%\n" . 6960 "\\newcommand\\lthtmlfigureZ{\\lthtmlboxmathZ\\lthtmllogmath\\copy\\sizebox 6961 \\global\\let\\\@freelist\\\@savefreelist}%\n" . 6962 "\\newcommand\\lthtmldisplayA{\\bgroup\\catcode`\\_=8 \\lthtmldisplayAi}%\n" . 6963 "\\newcommand\\lthtmldisplayAi[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlvboxmathA}%\n" . 6964 "\\newcommand\\lthtmldisplayB[1]{\\edef\\preveqno{(\\theequation)}%\n" . 6965 " \\lthtmldisplayA{#1}\\let\\\@eqnnum\\relax}%\n" . 6966 "\\newcommand\\lthtmldisplayZ{\\lthtmlboxmathZ\\lthtmllogmath\\lthtmlsetmath}%\n" . 6967 "\\newcommand\\lthtmlinlinemathA{\\bgroup\\catcode`\\_=8 \\lthtmlinlinemathB}\n" . 6968 "\\newcommand\\lthtmlinlinemathB[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlhboxmathA\n" . 6969 " \\vrule height1.5ex width0pt }%\n" . 6970 "\\newcommand\\lthtmlinlineA{\\bgroup\\catcode`\\_=8 \\lthtmlinlineB}%\n" . 6971 "\\newcommand\\lthtmlinlineB[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlhboxmathA}%\n" . 6972 "\\newcommand\\lthtmlinlineZ{\\egroup\\expandafter\\ifdim\\dp\\sizebox>0pt %\n" . 6973 " \\expandafter\\centerinlinemath\\fi\\lthtmllogmath\\lthtmlsetinline}\n" . 6974 "\\newcommand\\lthtmlinlinemathZ{\\egroup\\expandafter\\ifdim\\dp\\sizebox>0pt %\n" . 6975 " \\expandafter\\centerinlinemath\\fi\\lthtmllogmath\\lthtmlsetmath}\n" . 6976 "\\newcommand\\lthtmlindisplaymathZ{\\egroup %\n" . 6977 " \\centerinlinemath\\lthtmllogmath\\lthtmlsetmath}\n" . 6978 "\\def\\lthtmlsetinline{\\hbox{\\vrule width.1em \\vtop{\\vbox{%\n" . 6979 " \\kern.1em\\copy\\sizebox}\\ifdim\\dp\\sizebox>0pt\\kern.1em\\else\\kern.3pt\\fi\n" . 6980 " \\ifdim\\hsize>\\wd\\sizebox \\hrule depth1pt\\fi}}}\n" . 6981 "\\def\\lthtmlsetmath{\\hbox{\\vrule width.1em\\kern-.05em\\vtop{\\vbox{%\n" . 6982 " \\kern.1em\\kern$kern pt\\hbox{\\hglue.17em\\copy\\sizebox\\hglue$kern pt}}\\kern.3pt%\n" . 6983 " \\ifdim\\dp\\sizebox>0pt\\kern.1em\\fi \\kern$kern pt%\n" . 6984 " \\ifdim\\hsize>\\wd\\sizebox \\hrule depth1pt\\fi}}}\n" . 6985 "\\def\\centerinlinemath{%\n" . 6986 " \\dimen1=\\ifdim\\ht\\sizebox<\\dp\\sizebox \\dp\\sizebox\\else\\ht\\sizebox\\fi\n" . 6987 " \\advance\\dimen1by.5pt \\vrule width0pt height\\dimen1 depth\\dimen1 \n". 6988 " \\dp\\sizebox=\\dimen1\\ht\\sizebox=\\dimen1\\relax}\n\n" . 6989 "\\def\\lthtmlcheckvsize{\\ifdim\\ht\\sizebox<\\vsize \n" . 6990 " \\ifdim\\wd\\sizebox<\\hsize\\expandafter\\hfill\\fi \\expandafter\\vfill\n" . 6991 " \\else\\expandafter\\vss\\fi}%\n" . 6992 "\\providecommand{\\selectlanguage}[1]{}%\n" . 6993# "\\def\\\@enddocumenthook{\\ifnum\\count0>1 \\ifvoid\\\@cclv\\penalty-\\\@MM\\fi\\fi}\n" . 6994 "\\makeatletter \\tracingstats = 1 \n" 6995 . ($itrans_loaded ? $itrans_tex_mod : '') 6996 . $LaTeXmacros . "\n" # macros defined in extension files 6997# "\\usepackage{lthimages}\n" . 6998 . (($LATEX_DUMP)? "\\latexdump\n" : '') 6999 . "\n\\begin{document}\n" . 7000 "\\pagestyle{empty}\\thispagestyle{empty}\\lthtmltypeout{}%\n" . 7001 "\\lthtmltypeout{latex2htmlLength hsize=\\the\\hsize}\\lthtmltypeout{}%\n" . 7002 "\\lthtmltypeout{latex2htmlLength vsize=\\the\\vsize}\\lthtmltypeout{}%\n" . 7003 "\\lthtmltypeout{latex2htmlLength hoffset=\\the\\hoffset}\\lthtmltypeout{}%\n" . 7004 "\\lthtmltypeout{latex2htmlLength voffset=\\the\\voffset}\\lthtmltypeout{}%\n" . 7005 "\\lthtmltypeout{latex2htmlLength topmargin=\\the\\topmargin}\\lthtmltypeout{}%\n" . 7006 "\\lthtmltypeout{latex2htmlLength topskip=\\the\\topskip}\\lthtmltypeout{}%\n" . 7007 "\\lthtmltypeout{latex2htmlLength headheight=\\the\\headheight}\\lthtmltypeout{}%\n" . 7008 "\\lthtmltypeout{latex2htmlLength headsep=\\the\\headsep}\\lthtmltypeout{}%\n" . 7009 "\\lthtmltypeout{latex2htmlLength parskip=\\the\\parskip}\\lthtmltypeout{}%\n" . 7010 "\\lthtmltypeout{latex2htmlLength oddsidemargin=\\the\\oddsidemargin}\\lthtmltypeout{}%\n" . 7011 "\\makeatletter\n" . 7012 "\\if\@twoside\\lthtmltypeout{latex2htmlLength evensidemargin=\\the\\evensidemargin}%\n" . 7013 "\\else\\lthtmltypeout{latex2htmlLength evensidemargin=\\the\\oddsidemargin}\\fi%\n" . 7014 "\\lthtmltypeout{}%\n" . 7015 "\\makeatother\n\\setcounter{page}{1}\n\\onecolumn\n\n% !!! IMAGES START HERE !!!\n\n" 7016 . "$contents\n" 7017# "\\clearpage\n" . 7018 . "\\end{document}"; 7019} 7020 7021sub adjust_textwidth { 7022 local($_) = @_; 7023 local($width,$length) = ('',''); 7024 if (/a4/) {$width = 595; $length= 842; } 7025 elsif (/letter/) {$width = 612; $length= 792; } 7026 elsif (/legal/) {$width = 612; $length= 1008; } 7027 elsif (/note/) {$width = 540; $length= 720; } 7028 elsif (/b5/) {$width = 501; $length= 709; } 7029 elsif (/a5/) {$width = 421; $length= 595; } 7030 elsif (/a6/) {$width = 297; $length= 421; } 7031 elsif (/a7/) {$width = 210; $length= 297; } 7032 elsif (/a8/) {$width = 148; $length= 210; } 7033 elsif (/a9/) {$width = 105; $length= 148; } 7034 elsif (/a10/) {$width = 74; $length= 105; } 7035 elsif (/b4/) {$width = 709; $length= 1002; } 7036 elsif (/a3/) {$width = 842; $length= 1190; } 7037 elsif (/b3/) {$width = 1002; $length= 1418; } 7038 elsif (/a2/) {$width = 1190; $length= 1684; } 7039 elsif (/b2/) {$width = 1418; $length= 2004; } 7040 elsif (/a1/) {$width = 1684; $length= 2380; } 7041 elsif (/b1/) {$width = 2004; $length= 2836; } 7042 elsif (/a0/) {$width = 2380; $length= 3368; } 7043 elsif (/b0/) {$width = 2836; $length= 4013; } 7044 else { 7045 &write_warnings("\nPAPERSIZE: $_ unknown, using LaTeX's size."); 7046 return(); 7047 } 7048 if ($width > 500) { $width = $width - 144; $length = $length - 288; } 7049 elsif ($width > 250) { $width = $width - 72; $length = $length - 144; } 7050 elsif ($width > 125) { $width = $width - 36; $length = $length - 72; } 7051# "\\setlength{\\oddsidemargin}{0pt}\n" . 7052# "\\setlength{\\evensidemargin}{0pt}\n" . 7053# "\\setlength{\\parskip}{0pt}\\setlength{\\topskip}{0pt}\n" . 7054 "\\setlength{\\hoffset}{0pt}\\setlength{\\voffset}{0pt}\n" . 7055 "\\addtolength{\\textheight}{\\footskip}\\setlength{\\footskip}{0pt}\n" . 7056 "\\addtolength{\\textheight}{\\topmargin}\\setlength{\\topmargin}{0pt}\n" . 7057 "\\addtolength{\\textheight}{\\headheight}\\setlength{\\headheight}{0pt}\n" . 7058 "\\addtolength{\\textheight}{\\headsep}\\setlength{\\headsep}{0pt}\n" . 7059 "\\setlength{\\textwidth}{${width}pt}\n" 7060 . (($length > 500) ? "\\setlength{\\textheight}{${length}pt}\n" : '') 7061} 7062 7063# Given the depth of the current sectioning declaration and the current 7064# section numbers it returns the new section numbers. 7065# It increments the $depth-ieth element of the @curr_sec_id list and 7066# 0's the elements after the $depth-ieth element. 7067sub new_level { 7068 local($depth, @curr_sec_id) = @_; 7069 $depth = $section_commands{$outermost_level} unless $depth; 7070 local($i) = 0; 7071 grep( do { if ($i == $depth) {$_++ ;} 7072 elsif ($i > $depth) {$_ = 0 ;}; 7073 $i++; 7074 0; 7075 }, 7076 @curr_sec_id); 7077 @curr_sec_id; 7078} 7079 7080sub make_head_and_body { 7081 local($title,$body,$before_body) = @_; 7082 local($DTDcomment) = ''; 7083 local($version,$isolanguage) = ($HTML_VERSION, 'EN'); 7084 local(%isolanguages) = ( 'english', 'EN' , 'USenglish', 'EN-US' 7085 , 'original', 'EN' , 'german' , 'DE' 7086 , 'austrian', 'DE-AT', 'french' , 'FR' 7087 , 'spanish', 'ES' 7088 , %isolanguages ); 7089# $isolanguage = $isolanguages{$default_language}; # DTD is in EN 7090 $isolanguage = 'EN' unless $isolanguage; 7091#JCL(jcl-tcl) 7092# clean title as necessary 7093# the first words ... is a kludge, but reasonable (or not?) 7094#RRM: why bother? --- as long as it is pure text. 7095 $title = &purify($title,1); 7096 eval("\$title = ". $default_title ) unless ($title); 7097# $title = &get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES); 7098 7099 # allow user-modification of the <TITLE> tag; thanks Dan Young 7100 if (defined &custom_TITLE_hook) { 7101 $title = &custom_TITLE_hook($title, $toc_sec_title); 7102 } 7103 7104 if ($DOCTYPE =~ /\/\/[\w\.]+\s*$/) { # language spec included 7105 $DTDcomment = '<!DOCTYPE HTML PUBLIC "'. $DOCTYPE .'"'; 7106 } else { 7107 $DTDcomment = '<!DOCTYPE HTML PUBLIC "'. $DOCTYPE .'//' 7108 . ($ISO_LANGUAGE ? $ISO_LANGUAGE : $isolanguage) . '"' 7109 } 7110 $DTDcomment .= ($PUBLIC_REF ? "\n \"".$PUBLIC_REF.'"' : '' ) . '>'."\n"; 7111 7112 $STYLESHEET = $FILE.".css" unless defined($STYLESHEET); 7113 7114 my ($this_charset) = $charset; 7115 if ($USE_UTF) { $charset = $utf8_str; $NO_UTF = ''; } 7116 if (!$charset && $CHARSET) { 7117 $this_charset = $CHARSET; 7118 $this_charset =~ s/_/\-/go; 7119 } 7120 if ($NO_UTF && $charset =~/utf/) { 7121 $this_charset = $PREV_CHARSET||$CHARSET; 7122 $this_charset =~ s/_/\-/go; 7123 } 7124 7125 join("\n", (($DOCTYPE)? $DTDcomment : '' ) 7126 ,"<!--Converted with LaTeX2HTML $TEX2HTMLVERSION" 7127 , "original version by: Nikos Drakos, CBLU, University of Leeds" 7128 , "* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan" 7129 , "* with significant contributions from:" 7130 , " Jens Lippmann, Marek Rouchal, Martin Wilck and others" 7131 . " -->\n<HTML>\n<HEAD>\n<TITLE>".$title."</TITLE>" 7132 , &meta_information($title) 7133 , ($CHARSET && $HTML_VERSION ge "2.1" ? 7134 "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=$this_charset\">" 7135 : "" ) 7136 , $LATEX2HTML_META 7137 , ($BASE ? "<BASE HREF=\"$BASE\">" : "" ) 7138 , $STYLESHEET_CASCADE 7139 , ($STYLESHEET ? "<LINK REL=\"STYLESHEET\" HREF=\"$STYLESHEET\">" : '' ) 7140 , $more_links_mark 7141 , "</HEAD>" , ($before_body? $before_body : '') 7142 , "<BODY $body>", ''); 7143} 7144 7145 7146sub style_sheet { 7147 local($env,$id,$style); 7148 #AXR: don't overwrite existing .css 7149 #MRO: This is supposed to be $FILE.css, no? 7150 #RRM: only by default, others can be specified as well, via $EXTERNAL_STYLESHEET 7151 #return if (-f $EXTERNAL_STYLESHEET); 7152 return if (-r "$FILE.css" && -s _ && !$REFRESH_STYLES ); 7153 7154 unless(open(STYLESHEET, ">$FILE.css")) { 7155 print "\nError: Cannot write '$FILE.css': $!\n"; 7156 return; 7157 } 7158 if ( -f $EXTERNAL_STYLESHEET ) { 7159 if(open(EXT_STYLES, "<$EXTERNAL_STYLESHEET")) { 7160 while (<EXT_STYLES>) { print STYLESHEET $_; } 7161 close(EXT_STYLES); 7162 } else { 7163 print "\nError: Cannot read '$EXTERNAL_STYLESHEET': $!\n"; 7164 } 7165 } else { 7166 print STYLESHEET <<"EOF" 7167/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ 7168.MATH { font-family: \"Century Schoolbook\", serif; } 7169.MATH I { font-family: \"Century Schoolbook\", serif; font-style: italic } 7170.BOLDMATH { font-family: \"Century Schoolbook\", serif; font-weight: bold } 7171 7172/* implement both fixed-size and relative sizes */ 7173SMALL.XTINY { font-size : xx-small } 7174SMALL.TINY { font-size : x-small } 7175SMALL.SCRIPTSIZE { font-size : smaller } 7176SMALL.FOOTNOTESIZE { font-size : small } 7177SMALL.SMALL { } 7178BIG.LARGE { } 7179BIG.XLARGE { font-size : large } 7180BIG.XXLARGE { font-size : x-large } 7181BIG.HUGE { font-size : larger } 7182BIG.XHUGE { font-size : xx-large } 7183 7184/* heading styles */ 7185H1 { } 7186H2 { } 7187H3 { } 7188H4 { } 7189H5 { } 7190 7191/* mathematics styles */ 7192DIV.displaymath { } /* math displays */ 7193TD.eqno { } /* equation-number cells */ 7194 7195 7196/* document-specific styles come next */ 7197EOF 7198 } 7199 print "\n *** Adding document-specific styles *** "; 7200 while (($env,$style) = each %env_style) { 7201 if ($env =~ /\./) { 7202 $env =~ s/\.$//; 7203 print STYLESHEET "$env\t\t{ $style }\n"; 7204 } elsif ($env =~ /inline|^(text|math)?((tt|rm|sf)(family)?|(up|it|sl|sc)(shape)?|(bf|md)(series)?|normal(font)?)$/) { 7205 print STYLESHEET "SPAN.$env\t\t{ $style }\n"; 7206 } elsif ($env =~ /\./) { 7207 print STYLESHEET "$env\t\t{ $style }\n"; 7208 } elsif ($env =~ /^(preform|\w*[Vv]erbatim(star)?)$/) { 7209 print STYLESHEET "PRE.$env\t\t{ $style }\n"; 7210 } elsif ($env =~ /figure|table|tabular|equation|$array_env_rx/) { 7211 print STYLESHEET "TABLE.$env\t\t{ $style }\n"; 7212 } else { 7213 print STYLESHEET "DIV.$env\t\t{ $style }\n"; 7214 } 7215 } 7216 while (($env,$style) = each %txt_style) { 7217 print STYLESHEET "SPAN.$env\t\t{ $style }\n"; 7218 } 7219 while (($env,$style) = each %img_style) { 7220 print STYLESHEET "IMG.$env\t\t{ $style }\n"; 7221 } 7222 7223 my ($style); 7224 foreach $id (sort(keys %styleID)) { 7225 $style = $styleID{$id}; 7226 $style =~ s/font-(color)/$1/; 7227 print STYLESHEET "\#$id\t\t{ $style }\n" 7228 if ($styleID{$id} ne ''); 7229 } 7230 close(STYLESHEET); 7231} 7232 7233sub clear_styleID { 7234 return unless ($USING_STYLES); 7235 local($env_id,$id) = ("grp", @_); 7236 undef $styleID{$env_id} if ($id =~ /^\d+$/); 7237} 7238 7239sub make_address { 7240 local($addr) = &make_real_address(@_); 7241 $addr .= "\n</BODY>\n</HTML>\n"; 7242 &lowercase_tags($addr) if $LOWER_CASE_TAGS; 7243 $addr; 7244} 7245 7246sub make_real_address { 7247 local($addr) = $ADDRESS; 7248 if ((defined &custom_address)&&($addr)) { 7249 &custom_address($addr) 7250 } elsif ($addr) { 7251 "<ADDRESS>\n$addr\n</ADDRESS>"; 7252 } else { '' } 7253} 7254 7255sub purify_caption { 7256 local($_) = @_; 7257 local($text) = &recover_image_code($_); 7258 $text =~ s/\\protect|ALT\=|%EQNO:\d+//g; 7259 $text =~ s/[\\\#\'\"\`]//g; 7260 $text; 7261} 7262 7263sub recover_image_code { 7264 local($key) = @_; 7265 local($text) = $img_params{$key}; 7266 if (!$text) { 7267 if ($text = $id_map{$key}) { 7268 if ($orig_name_map{$text}) { 7269 $text = $img_params{$orig_name_map{$text}} 7270 } 7271 } elsif ($cached_env_img{$key}) { 7272 $text = $img_params{$cached_env_img{$key}}; 7273 } 7274 if ($text =~ /\#*ALT="([^"]+)"(>|#)/s) { $text = $1 } 7275 } 7276 $text =~ s/\\protect|%EQNO:\d+//g; 7277 $text =~ s/&(gt|lt|amp|quot);/&special_html_inv($1)/eg; 7278 $text; 7279} 7280 7281sub encode_title { 7282 local($_) = @_; 7283 $_ = &encode($_); 7284 while (/(<[^<>]*>)/o) {s/$1//g}; # Remove HTML tags 7285 s/#[^#]*#//g; # Remove #-delimited markers 7286 $_; 7287} 7288 7289# Encodes the contents of enviroments that are passed to latex. The code 7290# is then used as key to a hash table pointing to the URL of the resulting 7291# picture. 7292sub encode { 7293 local($_) = @_; 7294 # Remove invocation-specific stuff 7295 1 while(s/\\(begin|end)\s*(($O|$OP)\d+($C|$CP))?|{?tex2html_(wrap|nowrap|deferred|)(_\w+)?}?(\2)?//go); 7296 $_ = &revert_to_raw_tex($_); 7297 s/\\protect//g; # remove redundant \protect macros 7298 #$_ = pack("u*", $_); # uuencode 7299 s/\\\$/dollar/g; # replace funnies, may cause problems in a hash key 7300 s/\//slash/g; # replace funnies, may cause problems in a hash key 7301 s/\$|\/|\\//g; # remove funnies, may cause problems in a hash key 7302 s/\s*|\n//g; # Remove spaces and newlines 7303 s/^(.{80}).*(.{80})$/$1$2/; # truncate to avoid DBM problems 7304 $_; 7305} 7306 7307 7308##################### Hypertext Section Links ######################## 7309sub post_process { 7310 # Put hyperlinks between sections, add HTML headers and addresses, 7311 # do cross references and citations. 7312 # Uses the %section_info array created in sub translate. 7313 # Binds the global variables 7314 # $PREVIOUS, $PREVIOUS_TITLE 7315 # $NEXT, $NEXT_TITLE 7316 # $UP, $UP_TITLE 7317 # $CONTENTS, $CONTENTS_TITLE 7318 # $INDEX, $INDEX_TITLE 7319 # $NEXT_GROUP, $NEXT_GROUP_TITLE 7320 # $PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE 7321 # Converting to and from lists and strings is very inefficient. 7322 # Maybe proper lists of lists should be used (or wait for Perl5?) 7323 # JKR: Now using top_navigation and bot_navigation instead of navigation 7324 local($_, $key, $depth, $file, $title, $header, @link, @old_link, 7325 $top_navigation, $bot_navigation, @keys, 7326 @tmp_keys, $flag, $child_links, $body, $more_links); 7327 7328 @tmp_keys = @keys = sort numerically keys %section_info; 7329 print "\nDoing section links ..."; 7330 while (@tmp_keys) { 7331 $key = shift @tmp_keys; 7332 next if ($MULTIPLE_FILES &&!($key =~ /^$THIS_FILE/)); 7333 print "."; 7334 $more_links = ""; 7335 ($depth, $file, $title, $body) = split($delim,$section_info{$key}); 7336 print STDOUT "\n$key $file $title $body" if ($VERBOSITY > 3); 7337 next if ($body =~ /external/); 7338 $PREVIOUS = $PREVIOUS_TITLE = $NEXT = $NEXT_TITLE = $UP = $UP_TITLE 7339 = $CONTENTS = $CONTENTS_TITLE = $INDEX = $INDEX_TITLE 7340 = $NEXT_GROUP = $NEXT_GROUP_TITLE 7341 = $PREVIOUS_GROUP = $PREVIOUS_GROUP_TITLE 7342 = $_ = $top_navigation = $bot_navigation = undef; 7343 &add_link_tag('previous',$file); 7344 @link = split(' ',$key); 7345 ($PREVIOUS, $PREVIOUS_TITLE) = 7346 &add_link($previous_page_visible_mark,$file,@old_link); 7347 @old_link = @link; 7348 unless ($done{$file}) { 7349 ++$link[$depth]; 7350# if ($MULTIPLE_FILES && !$depth && $multiple_toc ) { 7351# local($save_depth) = $link[$depth]; 7352# $link[$depth] = 1; 7353# ($NEXT_GROUP, $NEXT_GROUP_TITLE) = 7354# &add_link($next_visible_mark, $file, @link); 7355# &add_link_tag('next', $file, @link); 7356# $link[$depth] = $save_depth; 7357# } else { 7358 ($NEXT_GROUP, $NEXT_GROUP_TITLE) = 7359 &add_link($next_visible_mark, $file, @link); 7360 &add_link_tag('next', $file, @link); 7361# } 7362 7363 $link[$depth]--;$link[$depth]--; 7364 if ($MULTIPLE_FILES && !$depth ) { 7365 } else { 7366 ($PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE) = 7367 &add_link($previous_visible_mark, $file,@link); 7368 &add_link_tag('previous', $file,@link); 7369 } 7370 7371 $link[$depth] = 0; 7372 ($UP, $UP_TITLE) = 7373 &add_link($up_visible_mark, $file, @link); 7374 &add_link_tag('up', $file, @link); 7375 7376 if ($CONTENTS_IN_NAVIGATION) { 7377 ($CONTENTS, $CONTENTS_LINK) = 7378 &add_special_link($contents_visible_mark, $tocfile, $file); 7379 &add_link_tag('contents', $file, $delim.$tocfile); 7380 } 7381 7382 if ($INDEX_IN_NAVIGATION) { 7383 ($INDEX, $INDEX_LINK) = 7384 &add_special_link($index_visible_mark, $idxfile, $file); 7385 &add_link_tag('index', $file, $delim.$idxfile,); 7386 } 7387 7388 @link = split(' ',$tmp_keys[0]); 7389 # the required `next' link may be several sub-sections along 7390 local($nextdepth,$nextfile,$nextkey,$nexttitle,$nextbody)= 7391 ($depth,$file,$key,'',''); 7392 $nextkey = shift @tmp_keys; 7393 ($nextdepth, $nextfile,$nexttitle,$nextbody) = split($delim,$section_info{$nextkey}); 7394 if (($nextdepth<$MAX_SPLIT_DEPTH)&&(!($nextbody=~/external/))) { 7395 ($NEXT, $NEXT_TITLE) = 7396 &add_link($next_page_visible_mark, $file, @link); 7397 &add_link_tag('next', $file, @link); 7398 } else { 7399 ($NEXT, $NEXT_TITLE) = ('',''); 7400 $nextfile = $file; 7401 } 7402 if ((!$NEXT || $NEXT =~ /next_page_inactive_visible_mark/)&&(@tmp_keys)) { 7403 # the required `next' link may be several sub-sections along 7404 while ((@tmp_keys)&&(($MAX_SPLIT_DEPTH < $nextdepth+1)||($nextfile eq $file))) { 7405 $nextkey = shift @tmp_keys; 7406 ($nextdepth, $nextfile,$nexttitle,$nextbody) = split($delim,$section_info{$nextkey}); 7407 if ($nextbody =~ /external/) { 7408 $nextfile = $file; 7409 next; 7410 }; 7411 print ","; 7412 print STDOUT "\n $nextkey" if ($VERBOSITY > 3); 7413 } 7414 @link = split(' ',$nextkey); 7415 if (($nextkey)&&($nextdepth<$MAX_SPLIT_DEPTH)) { 7416 ($NEXT, $NEXT_TITLE) = 7417 &add_link($next_page_visible_mark, $file, @link); 7418 &add_link_tag('next', $file, @link); 7419 } else { 7420 ($NEXT, $NEXT_TITLE) = ($NEXT_GROUP, $NEXT_GROUP_TITLE); 7421 $NEXT =~ s/next_page_(inactive_)?visible_mark/next_page_$1visible_mark/; 7422 ($PREVIOUS, $PREVIOUS_TITLE) = ($PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE); 7423 $PREVIOUS =~ s/previous_(inactive_)?visible_mark/previous_page_$1visible_mark/; 7424 } 7425 } 7426 unshift (@tmp_keys,$nextkey) if ($nextkey); 7427# 7428 $top_navigation = (defined(&top_navigation_panel) ? 7429 &top_navigation_panel : &navigation_panel) 7430 unless $NO_NAVIGATION; 7431 $bot_navigation = (defined(&bot_navigation_panel) ? 7432 &bot_navigation_panel : &navigation_panel) 7433 unless $NO_NAVIGATION; 7434 local($end_navigation) = "\n<!--End of Navigation Panel-->\n"; 7435 if ($USING_STYLES) { 7436 $top_navigation = "\n".'<DIV CLASS="navigation">' . $top_navigation 7437 if $top_navigation; 7438 $bot_navigation = "\n".'<DIV CLASS="navigation">' . $bot_navigation 7439 if $bot_navigation; 7440 $end_navigation = '</DIV>' . $end_navigation; 7441 $env_style{'navigation'} = " "; 7442 } 7443 7444 $header = &make_head_and_body($title, $body); 7445 $header = join('', $header, $top_navigation, $end_navigation) if ($top_navigation); 7446 7447 local($this_file) = $file; 7448 if ($MULTIPLE_FILES && $ROOTED) { 7449 if ($this_file =~ /\Q$dd\E([^$dd$dd]+)$/) { $this_file = $1 } 7450 } 7451 &slurp_input($this_file); 7452 open(OUTFILE, ">$this_file") 7453 || die "\nError: Cannot write file '$this_file': $!\n"; 7454 7455 if (($INDEX) && ($SHORT_INDEX) && ($SEGMENT eq 1)) { 7456 &make_index_segment($title,$file); } 7457 7458 local($child_star,$child_links); 7459 local($CURRENT_FILE) = $this_file; # ensure $CURRENT_FILE is set correctly 7460 if (/$childlinks_on_mark\#(\d)\#/) { $child_star = $1 } 7461 $child_links = &add_child_links('',$file, $depth, $child_star,$key, @keys) 7462 unless (/$childlinks_null_mark\#(\d)\#/); 7463 if (($child_links)&&(!/$childlinks_mark/)&&($MAX_SPLIT_DEPTH > 1)) { 7464 if ($depth < $MAX_SPLIT_DEPTH -1) { 7465 $_ = join('', $header, $_, &child_line(), $childlinks_mark, "\#0\#" ); 7466 } else { 7467 $_ = join('', $header, "\n$childlinks_mark\#0\#", &upper_child_line(), $_ ); 7468 } 7469 } else { 7470 $_ = join('', $header, $_ ); 7471 } 7472 $flag = (($BOTTOM_NAVIGATION || &auto_navigation) && $bot_navigation); 7473 $_ .= $bot_navigation . $end_navigation if ($flag &&($bot_navigation)); 7474 $_ .= &child_line() unless $flag; 7475 print STDOUT "\n *** replace markers *** " if ($VERBOSITY > 1); 7476 &replace_markers; 7477 print STDOUT "\n *** post-post-process *** " if ($VERBOSITY > 1); 7478 &post_post_process if (defined &post_post_process); 7479 &adjust_encoding; 7480 print OUTFILE $_; 7481 print OUTFILE &make_address; 7482 close OUTFILE; 7483 $done{$file}++; 7484 } 7485 } 7486 &post_process_footnotes if ($footfile); 7487} 7488 7489sub adjust_encoding { 7490 &convert_to_utf8($_) if ($USE_UTF); 7491 &lowercase_tags($_) if $LOWER_CASE_TAGS; 7492} 7493 7494sub post_replace_markers { 7495 # MRO: replaced $* with /m 7496 # clean up starts and ends of P, BR and DIV tags 7497 s/(<\/?(P|BR|DIV)>)\s*(\w)/$1\n$3/gom unless ($file eq $citefile); 7498 s/([^\s])(<(BR|DIV))/$1\n$2/gom unless ($file eq $citefile); 7499 local($keep,$after); 7500 7501 # anchor images when otherwise there is an invisible-anchor 7502# s/(<A[^>]*>)\&\#160;<\/A>\s?(<(P|DIV)[^>]*>)\s*(<IMG[^>]*>)\s*(<\/(P|DIV)>)/ 7503 s/(<A[^>]*>)($anchor_mark|$anchor_invisible_mark)<\/A>\s?(<(P|DIV)[^>]*>)\s*(<IMG[^>]*>)\s*(<\/(P|DIV)>)/ 7504 do{ $keep="$3$1$5<\/A>"; 7505 $after = $6; 7506 join('',$keep, &after_punct_break($after), $after); 7507 } /egom; 7508 7509 # absorb named anchor (e.g. from index-entry) into preceding or following anchor 7510# s/(<A NAME=\"[^\"]+\")>\ <\/A>\s*\b?<A( HREF=\"[^\"]+\">)/$1$2/gom; 7511# s/(<A HREF=\"[^\"]+\")(>\s*\b?([^<]+|<([^>\/]+|\/[^>A]+)>\s*)*<\/A>)\s*\b?<A( NAME=\"[^\"]+\")>\ <\/A>/$1$5$2/gom; 7512 7513 # clean up empty table cells 7514 s/(<TD[^>]*>)\s*(<\/TD>)/<TD>$2/gom; 7515 7516 # clean up list items (only desirable in the bibliography ?) 7517 # s/\n<P>(<DT[^>]*>)/\n<P><\/P>\n$1/gom; 7518 7519 # remove blank lines and comment-markers 7520# s/\n\n/\n/g; # no, cause this kills intended ones in verbatims 7521 s/$comment_mark(\d+\n?)?//gm; 7522 s/\"/"/gm; # replace " entities 7523 7524 # italic \LaTeX looks bad 7525 s:<(I|EM)>(($Laname|$AmSname)?$TeXname)</\1>:$2:gm; 7526} 7527 7528sub lowercase_tags { 7529 # MRO: modified to use $_[0] 7530 # local(*stream) = @_; 7531 my ($tags,$attribs); 7532 $_[0] =~ s!<(/?\w+)( [^>]*)?>! 7533 $tags = $1; $attribs = $2; 7534 $attribs =~ s/ ([\w\d-]+)(=| |$)/' '.lc($1).$2/eg; 7535 join('', '<', lc($tags) , $attribs , '>')!eg; 7536} 7537 7538sub after_punct_break { 7539 # MRO: modified to use $_[0] 7540 # local(*stream) = @_; 7541# $stream =~ s/^([ \t]*)([,;\.\)\!\"\'\?])[ \t]*(\n)?/(($2)? "$2" : "$1")."\n"/em; 7542# $stream; 7543 $_[0] =~ s/^([ \t]*)([,;\.\)\!\"\'\?\>]|\>)[ \t]*(\n)?//em; 7544 ($2 ? $2 : $1)."\n"; 7545} 7546 7547sub make_index_segment { 7548 local($title,$file)= @_ ; 7549#JCL(jcl-tcl) 7550# s/<[^>]*>//g; 7551# 7552 $index_segment{$PREFIX} = "$title"; 7553 if (!($ref_files{"segment"."$PREFIX"} eq "$file")) { 7554 $ref_files{"segment"."$PREFIX"} = "$file"; 7555 $changed = 1 7556 } 7557 $SEGMENT = 2; 7558} 7559 7560 7561sub add_link { 7562 # Returns a pair (iconic link, textual link) 7563 local($icon, $current_file, @link) = @_; 7564 local($dummy, $file, $title, $lbody) = split($delim,$section_info{join(' ',@link)}); 7565 if ($lbody =~ /external/) { return ('','') }; 7566 7567# local($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)}); 7568 7569 if ($MULTIPLE_FILES && $ROOTED && $file) { 7570 if (!($DESTDIR =~ /\Q$FIXEDDIR\E[$dd$dd]?$/)) { $file = "..$dd$file" } 7571 } 7572# if ($title && ($file ne $current_file || $icon ne $up_visible_mark)) { 7573 if ($title && ($file ne $current_file)) { 7574 #RRM: allow user-customisation of the link-text; thanks Dan Young 7575 if (defined &custom_link_hook ) { 7576 $title = &custom_link_hook($title,$toc_section_info{join(' ',@link)}); 7577 } else { 7578 $title = &purify($title); 7579 $title = &get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES); 7580 } 7581 return ("\n".&make_href($file, $icon), &make_href($file, "$title")) 7582 } 7583# elsif ($icon eq $up_visible_mark && $file eq $current_file && $EXTERNAL_UP_LINK) { 7584 elsif ($icon eq $up_visible_mark && $EXTERNAL_UP_LINK) { 7585 return ("\n".&make_href($EXTERNAL_UP_LINK, $icon), 7586 &make_href($EXTERNAL_UP_LINK, "$EXTERNAL_UP_TITLE")) 7587 } 7588 elsif (($icon eq $previous_visible_mark || $icon eq $previous_page_visible_mark) 7589 && $EXTERNAL_PREV_LINK && $EXTERNAL_PREV_TITLE) { 7590 return ("\n".&make_href($EXTERNAL_PREV_LINK, $icon), 7591 &make_href($EXTERNAL_PREV_LINK, "$EXTERNAL_PREV_TITLE")) 7592 } 7593 elsif (($icon eq $next_visible_mark || $icon eq $next_page_visible_mark) 7594 && $EXTERNAL_DOWN_LINK && $EXTERNAL_DOWN_TITLE) { 7595 return ("\n".&make_href($EXTERNAL_DOWN_LINK, $icon), 7596 &make_href($EXTERNAL_DOWN_LINK, "$EXTERNAL_DOWN_TITLE")) 7597 } 7598 (&inactive_img($icon), ""); 7599} 7600 7601sub add_special_link { &add_real_special_link(@_) } 7602sub add_real_special_link { 7603 local($icon, $file, $current_file) = @_; 7604 local($text); 7605 if ($icon eq $contents_visible_mark) { $text = $toc_title } 7606 elsif ($icon eq $index_visible_mark) { $text = $idx_title } 7607 elsif ($icon eq $biblio_visible_mark) { $text = $bib_title } 7608 (($file && ($file ne $current_file)) ? 7609 ("\n" . &make_href($file, $icon), 7610 ($text ? " ". &make_href($file, $text) : undef)) 7611 : ( undef, undef )) 7612} 7613 7614#RRM: add <LINK ...> tag to the HTML head. 7615# suggested by Marcus Hennecke 7616# 7617sub add_link_tag { 7618 local($rel, $currentfile, @link ) = @_; 7619# local($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)}); 7620 local($dummy, $file, $title) = split($delim,$section_info{join(' ',@link)}); 7621 ($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)}) 7622 unless ($title); 7623 7624 if ($MULTIPLE_FILES && $ROOTED && $file) { 7625 if (!($DESTDIR =~ /\Q$FIXEDDIR\E[$dd$dd]?$/)) { $file = "..$dd$file" } 7626 } 7627 if ($file && !($file eq $currentfile) && (!$NO_NAVIGATION)) { 7628 #RRM: allow user-customisation of the REL attribute 7629 if (defined &custom_REL_hook ) { 7630 $rel = &custom_REL_hook($rel,$toc_section_info{join(' ',@link)}); 7631 } 7632 $more_links .= "\n<LINK REL=\"$rel\" HREF=\"$file\">"; 7633 } 7634} 7635 7636sub remove_markers { 7637# modifies $_ 7638 s/$lof_mark//go; 7639 s/$lot_mark//go; 7640 &remove_bbl_marks; 7641 s/$toc_mark//go; 7642 s/$idx_mark//go; 7643 &remove_cross_ref_marks; 7644 &remove_external_ref_marks; 7645 &remove_cite_marks; 7646 &remove_file_marks; 7647# sensitive markers 7648 &remove_image_marks; 7649 &remove_icon_marks; 7650 &remove_verbatim_marks; 7651 &remove_verb_marks; 7652 &remove_child_marks; 7653# uncaught markers 7654 s/$percent_mark/%/go; 7655 s/$ampersand_mark/\&/go; 7656 s/$comment_mark\s*(\d+\n?)?//sgo; 7657 s/$caption_mark//go; 7658 s/<tex2html[^>]*>//g; 7659 s/$OP\d+\$CP//g; 7660 $_; 7661} 7662 7663sub replace_markers { 7664 &find_quote_ligatures; 7665 &replace_general_markers; 7666 &text_cleanup; 7667 # Must NOT clean the ~'s out of the navigation icons (in panel or text), 7668 # and must not interfere with verbatim-like environments 7669 &replace_sensitive_markers; 7670 &replace_init_file_mark if (/$init_file_mark/); 7671 &replace_file_marks; 7672 &post_replace_markers; 7673} 7674 7675sub replace_general_markers { 7676 if (defined &replace_infopage_hook) {&replace_infopage_hook if (/$info_page_mark/);} 7677 else { &replace_infopage if (/$info_page_mark/); } 7678 if (defined &add_idx_hook) {&add_idx_hook if (/$idx_mark/);} 7679 else {&add_idx if (/$idx_mark/);} 7680 7681 if ($segment_figure_captions) { 7682# s/$lof_mark/<UL>$segment_figure_captions<\/UL>/o 7683# } else { s/$lof_mark/<UL>$figure_captions<\/UL>/o } 7684 s/$lof_mark/$segment_figure_captions/o 7685 } else { s/$lof_mark/$figure_captions/o } 7686 if ($segment_table_captions) { 7687# s/$lot_mark/<UL>$segment_table_captions<\/UL>/o 7688# } else { s/$lot_mark/<UL>$table_captions<\/UL>/o } 7689 s/$lot_mark/$segment_table_captions/o 7690 } else { s/$lot_mark/$table_captions/o } 7691 &replace_morelinks(); 7692 if (defined &replace_citations_hook) {&replace_citations_hook if /$bbl_mark/;} 7693 else {&replace_bbl_marks if /$bbl_mark/;} 7694 if (defined &add_toc_hook) {&add_toc_hook if (/$toc_mark/);} 7695 else {&add_toc if (/$toc_mark/);} 7696 if (defined &add_childs_hook) {&add_childs_hook if (/$childlinks_on_mark/);} 7697 else {&add_childlinks if (/$childlinks_on_mark/);} 7698 &remove_child_marks; 7699 7700 if (defined &replace_cross_references_hook) {&replace_cross_references_hook;} 7701 else {&replace_cross_ref_marks if /$cross_ref_mark||$cross_ref_visible_mark/;} 7702 if (defined &replace_external_references_hook) {&replace_external_references_hook;} 7703 else {&replace_external_ref_marks if /$external_ref_mark/;} 7704 if (defined &replace_cite_references_hook) {&replace_cite_references_hook;} 7705 else { &replace_cite_marks if /$cite_mark/; } 7706 if (defined &replace_user_references) { 7707 &replace_user_references if /$user_ref_mark/; } 7708} 7709 7710sub replace_sensitive_markers { 7711 if (defined &replace_images_hook) {&replace_images_hook;} 7712 else {&replace_image_marks if /$image_mark/;} 7713 if (defined &replace_icons_hook) {&replace_icons_hook;} 7714 else {&replace_icon_marks if /$icon_mark_rx/;} 7715 if (defined &replace_verbatim_hook) {&replace_verbatim_hook;} 7716 else {&replace_verbatim_marks if /$verbatim_mark/;} 7717 if (defined &replace_verb_hook) {&replace_verb_hook;} 7718 else {&replace_verb_marks if /$verb_mark|$verbstar_mark/;} 7719 s/;SPMdollar;/\$/g; s/;SPMtilde;/\~/g; s/;SPMpct;/\%/g; 7720 s/;SPM/\&/go; 7721 s/$percent_mark/%/go; 7722 s/$ampersand_mark/\&/go; 7723 #JKR: Turn encoded ~ back to normal 7724 s/~/~/go; 7725} 7726 7727sub find_quote_ligatures { 7728 my $ent; 7729 7730# guillemets, governed by $NO_FRENCH_QUOTES 7731 do { 7732 $ent = &iso_map('laquo', "", 1); 7733 if ($NO_UTF && !$USE_UTF && $ent=~/\&\#(\d+);/) { 7734 $ent='' if ($1 > 255); 7735 } 7736 s/((\&|;SPM)lt;){2}/$ent/ogs if $ent; 7737 $ent = &iso_map('raquo', "", 1) if ($ent); 7738 s/((\&|;SPM)gt;){2}/$ent/ogs if $ent; 7739 # single guillemot chars cannot be easily implemented this way 7740 # finding an approp regexp is work for the future 7741 } unless ($NO_FRENCH_QUOTES); 7742 7743 $ent = &iso_map("gg", "", 1); 7744 s/;SPMgg;/($ent ? $ent : '>>')/eg unless ($USE_NAMED_ENTITIES); 7745 $ent = &iso_map("ll", "", 1); 7746 s/;SPMll;/($ent ? $ent : '<<')/eg unless ($USE_NAMED_ENTITIES); 7747 7748 my $ldquo, $rdquo; 7749# "curly" quotes, governed by $USE_CURLY_QUOTES. 7750 do { 7751 $ldquo = &iso_map("ldquo", "", 1); 7752 if ($NO_UTF && !$USE_UTF && $ldquo =~ /\&\#(\d+);/) { 7753 $ldquo = '' if ($1 > 255); 7754 } 7755 s/``/$ldquo/ogs if ($ldquo); 7756 $rdquo = &iso_map("rdquo", "", 1) if ($ldquo); 7757 s/''/$rdquo/ogs if ($rdquo); 7758 7759 # single curly quotes cannot be easily implemented this way 7760 # finding an approp regexp is work for the future 7761 } if ($USE_CURLY_QUOTES); 7762 7763# "german" quotes, governed by $NO_GERMAN_QUOTES. 7764 do { 7765 $ent = &iso_map('bdquo', "", 1); 7766 if ($NO_UTF && !$USE_UTF && $ent =~ /\&\#(\d+);/) { 7767 $ent = '' if ($1 > 255); 7768 } 7769 s/,,/$ent/eg if $ent; 7770 7771 # closing upper quotes are not properly displayed in browsers 7772 s/($ent[\w\s\&\#;']+)$ldquo/$1``/og 7773 if ($USE_CURLY_QUOTES && $ldquo && $ent); 7774 } unless ($NO_GERMAN_QUOTES); 7775} 7776 7777sub add_childlinks { 7778 local($before, $after, $star); 7779 while (/$childlinks_on_mark\#(\d)\#/) { 7780 $star = $1; 7781 $before = $`; 7782 $after = $'; 7783 $before =~ s/\n\s*$//; 7784 $_ = join('', $before, "\n", $child_links, $after); 7785 } 7786} 7787 7788sub replace_infopage { 7789 local($INFO)=1 if !(defined $INFO); 7790 if ($INFO == 1) { 7791 local($title); 7792 if ((defined &do_cmd_infopagename)||$new_command{'infopagename'}) { 7793 local($br_id)=++$global{'max_id'}; 7794 $title = &translate_environments("$O$br_id$C\\infopagename$O$br_id$C"); 7795 } else { $title = $info_title } 7796 if ($MAX_SPLIT_DEPTH <= $section_commands{$outermost_level}) { 7797 $_ =~ s/(<HR[^>]*>\s*)?$info_title_mark/ 7798 ($1? $1 : "\n<HR>")."\n<H2>$title<\/H2>"/eog; 7799 } else { 7800 $_ =~ s/$info_title_mark/"\n<H2>$title<\/H2>"/eog; 7801 } 7802 } 7803 while (/$info_page_mark/o) { 7804 $_ = join('', $`, &do_cmd_textohtmlinfopage, $'); 7805 } 7806} 7807 7808sub replace_init_file_mark { 7809 local($init_file, $init_contents, $info_line)=($INIT_FILE,'',''); 7810 if (-f $init_file) { 7811 } elsif (-f "$orig_cwd$dd$init_file") { 7812 $init_file = $orig_cwd.$dd.$init_file; 7813 } else { 7814 s/$init_file_mark//g; 7815 return(); 7816 } 7817 if(open(INIT, "<$init_file")) { 7818 foreach $info_line (<INIT>) { 7819 $info_line =~ s/[<>"&]/'&'.$html_special_entities{$&}.';'/eg; 7820 $init_contents .= $info_line; 7821 } 7822 close INIT; 7823 } else { 7824 print "\nError: Cannot read '$init_file': $!\n"; 7825 } 7826 s/$init_file_mark/\n<BLOCKQUOTE><PRE>\n$init_contents\n<\/PRE><\/BLOCKQUOTE>\n/g; 7827} 7828 7829sub replace_morelinks { 7830 $_ =~ s/$more_links_mark/$more_links/e; 7831} 7832 7833# This code is extremely inefficient. At least the subtrees should be 7834# filtered according to $MAX_LINK_DEPTH before going into the 7835# inner loops. 7836# RRM: revamped parts, for $TOC_STARS, fixing some errors. 7837# 7838sub add_child_links { &add_real_child_links(@_) } 7839sub add_real_child_links { 7840 local($exclude, $base_file, $depth, $star, $current_key, @keys) = @_; 7841 local $min_depth = $section_commands{$outermost_level} - 1; 7842 return ('') if ((!$exclude)&&(!$LEAF_LINKS)&&($depth >= $MAX_SPLIT_DEPTH)); 7843 if ((!$depth)&&($outermost_level)) { $depth = $min_depth } 7844 7845 local($_, $child_rx, @subtree, $next, %open, @roottree); 7846 local($first, $what, $pre, $change_key, $list_class); 7847 $childlinks_start = "<!--Table of Child-Links-->"; 7848 $childlinks_end = "<!--End of Table of Child-Links-->\n"; 7849 $child_rx = $current_key; 7850 $child_rx =~ s/( 0)*$//; # Remove trailing 0's 7851 if ((!$exclude)&&($depth < $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH -1 ) 7852# &&($depth >= $MAX_SPLIT_DEPTH-1)) { 7853 &&($depth > $min_depth)) { 7854 if ((defined &do_cmd_childlinksname)||$new_command{'childlinksname'}) { 7855 local($br_id)=++$global{'max_id'}; 7856 $what = &translate_environments("$O$br_id$C\\childlinksname$O$br_id$C"); 7857 } else { 7858 $what = "<strong>$child_name</strong>"; 7859 } 7860 $list_class = ' CLASS="ChildLinks"' if ($USING_STYLES); 7861 $first = "$childlinks_start\n<A NAME=\"CHILD_LINKS\">$what<\/A>\n"; 7862 } elsif ($exclude) { 7863 # remove any surrounding braces 7864 $exclude =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g; 7865 # Table-of-Contents 7866 $list_class = ' CLASS="TofC"' if ($USING_STYLES); 7867 $childlinks_start = "\n<!--Table of Contents-->\n"; 7868 $childlinks_end = "<!--End of Table of Contents-->"; 7869 $first = "$childlinks_start"; 7870 } else { 7871 $list_class = ' CLASS="ChildLinks"' if ($USING_STYLES); 7872 $first = "$childlinks_start\n" 7873 . ($star ? '':"<A NAME=\"CHILD_LINKS\">$anchor_mark<\/A>\n"); 7874 } 7875 my $startlist, $endlist; 7876 $startlist = "<UL$list_class>" unless $CHILD_NOLIST; 7877 $endlist = '</UL>' unless $CHILD_NOLIST; 7878 my $alt_item = '<BR> <BR>'."\n"; 7879 my $outer_item = ($CHILD_NOLIST ? $alt_item : '<LI>'); 7880 my $inner_item = '<LI>'; 7881 my $inner_end = '</UL><BR>'; 7882 7883 # collect the relevant keys... 7884 foreach $next (@keys) { 7885 if ($MULTIPLE_FILES && $exclude) { 7886 # ...all but with this document as the root 7887 if ($next =~ /^$THIS_FILE /) { 7888# # make current document the root 7889# $change_key = '0 '.$'; 7890 push(@roottree,$next); 7891 print "\n$next : m-root" if ($VERBOSITY > 3); 7892 } else { 7893 push(@subtree,$next); 7894 print "\n$next : m-sub" if ($VERBOSITY > 3); 7895 } 7896 } elsif (($next =~ /^$child_rx /)&&($next ne $current_key)) { 7897 # ...which start as $current_key 7898 push(@subtree,$next); 7899 print "\n$next : sub $child_rx" if ($VERBOSITY > 3); 7900 } else { 7901 print "\n$next : out $current_key" if ($VERBOSITY > 3); 7902 } 7903 } 7904 if (@subtree) { @subtree = sort numerically @subtree; } 7905 if (@roottree) { 7906 @roottree = sort numerically @roottree; 7907 @subtree = ( @roottree, @subtree ); 7908 } 7909 # @subtree now contains the subtree rooted at the current node 7910 7911 local($countUL); #counter to ensure correct tag matching 7912 my $root_file, $href; 7913 if (@subtree) { 7914 local($next_depth, $file, $title, $sec_title, $star, $ldepth,$this_file, $prev_file); 7915 $ldepth = $depth; 7916 $prev_file = $base_file; 7917# @subtree = sort numerically @subtree; 7918 foreach $next (@subtree) { 7919 $title = ''; 7920 if ($exclude) { 7921 # making TOC 7922 ($next_depth, $file, $sec_title) = 7923 split($delim,$section_info{$next}); 7924 ($next_depth, $file, $title, $star) = 7925 split($delim,$toc_section_info{$next}); 7926 # use the %section_info title, in case there are images 7927 $title = $sec_title if ($sec_title =~ /image_mark>\#/); 7928 } else { 7929 # making mini-TOC i.e. the child-links tables 7930 $star = ''; 7931 ($next_depth, $file, $title) = 7932 split($delim,$section_info{$next}); 7933 } 7934 $root_file = $file unless $root_file; 7935 if ($root_file && $root_file =~ /_mn\./) { $root_file=$` }; 7936 # remove any surrounding braces 7937 $title =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g; 7938 next if ($exclude && $title =~ /^$exclude$/); 7939 if (!$title) { 7940 ($next_depth, $file, $title, $star) = 7941 split($delim,$toc_section_info{$next}); 7942 } 7943 $this_file = $file; 7944 $title = "\n".$title if !($title =~/^\n/); 7945 next if ( $exclude &&( # doing Table-of-Contents 7946 ( $TOC_DEPTH &&($next_depth > $TOC_DEPTH)) # and too deep 7947 ||($star && !$TOC_STARS ) )); # or no starred sections 7948 $file = "" if (!$MAX_SPLIT_DEPTH); # Martin Wilck 7949 next if ($exclude && !$MULTIPLE_FILES &&($title =~ /^\s*$exclude\s*$/)); 7950 next if (!$exclude && $next_depth > $MAX_LINK_DEPTH + $depth); 7951 print "\n$next :" if ($VERBOSITY > 3); 7952 if ($this_file =~ /^(\Q$prev_file\E|\Q$base_file\E)$/) { 7953 $file .= join('', "#SECTION", split(' ', $next)); 7954 } else { $prev_file = $file } 7955 7956 if (!$next_depth && $MULTIPLE_FILES) { ++$next_depth } 7957 local($num_open) = (split('/',%open))[0]; 7958 if ((($next_depth > $ldepth)||$first) 7959 && ((split('/',%open))[0] < $MAX_LINK_DEPTH + $depth ) 7960 ) { 7961 # start a new <UL> list 7962 if ($first) { 7963 $_ = "$first\n$startlist\n"; $countUL++; 7964 local $i = 1; 7965 while ($i <= $ldepth) { 7966 $open{$i}=0; $i++ 7967 } 7968 $first = ''; # include NAME tag first time only 7969 while ($i < $next_depth) { 7970 $open{$i}=1; $i++; 7971 $_ .= ($countUL >1 ? $inner_item : $outer_item)."<UL>\n"; 7972 $countUL++; 7973 } 7974 } else { 7975 $_ .= "<UL>\n"; $countUL++; 7976 } 7977 $ldepth = $next_depth; 7978 $open{$ldepth}++; 7979 # append item to this list 7980 print " yes " if ($VERBOSITY > 3); 7981 if (defined &add_frame_child_links) { 7982 $href = &make_href($file,$title); 7983 if ($href =~ s/($root_file)_mn/$1_ct/) { 7984 $href =~ s/(target=")main(")/$1contents$2/i; 7985 }; 7986 $_ .= ($countUL >1 ? $inner_item : $outer_item) 7987 . $href . "\n"; 7988 } else { 7989 $_ .= ($countUL >1 ? $inner_item : $outer_item) 7990 . &make_href($file,$title) . "\n"; 7991 } 7992 } 7993 elsif (($next_depth)&&($next_depth <= $ldepth) 7994 &&((split('/',%open))[0] <= $MAX_LINK_DEPTH + $depth ) 7995 ) { 7996 # append item to existing <UL> list 7997 while (($next_depth < $ldepth) && %open ) { 7998 # ...closing-off any nested <UL> lists 7999 if ($open{$ldepth}) { 8000 if (!(defined $open{$next_depth})) { 8001 $open{$next_depth}++; 8002 } else { 8003 $_ .= ($countUL==2 ? $inner_end : '</UL>')."\n"; 8004 $countUL--; 8005 } 8006 delete $open{$ldepth}; 8007 }; 8008 $ldepth--; 8009 } 8010 $ldepth = $next_depth; 8011 print " yes" if ($VERBOSITY > 3); 8012 if (defined &add_frame_child_links) { 8013 $href = &make_href($file,$title); 8014 if ($href =~ s/($root_file)_mn/$1_ct/) { 8015 $href =~ s/(target=")main(")/$1contents$2/i; 8016 }; 8017 $_ .= ($countUL >1 ? $inner_item : $outer_item) 8018 . $href . "\n"; 8019 } else { 8020 $_ .= ($countUL >1 ? $inner_item : $outer_item) 8021 . &make_href($file,$title) . "\n"; 8022 } 8023 } else { 8024 # ignore items that are deeper than $MAX_LINK_DEPTH 8025 print " no" if ($VERBOSITY > 3); 8026 } 8027 } 8028 8029 if (%open) { 8030 # close-off any remaining <UL> lists 8031 $countUL-- if $CHILD_NOLIST; 8032 local $cnt = (split('/',%open))[0]; 8033 local $i = $cnt; 8034 while ($i > $depth) { 8035 if ($open{$i}) { 8036 $_ .= '</UL>' if $countUL; 8037 $countUL--; 8038 delete $open{$i}; 8039 } 8040 $i--; 8041 } 8042 } 8043 } 8044 # just in case the count is wrong 8045 $countUL-- if ($CHILD_NOLIST && $countUL > 0); 8046 $countUL = '' if ($countUL < 0); 8047 while ($countUL) { $_ .= '</UL>'; $countUL-- } 8048 ($_ ? join('', $_, "\n$childlinks_end") : ''); 8049} 8050 8051sub child_line {($CHILDLINE) ? "$CHILDLINE" : "<BR>\n<HR>";} 8052sub upper_child_line { "<HR>\n"; } 8053 8054sub adjust_root_keys { 8055 return() unless ($MULTIPLE_FILES && $ROOTED); 8056 local($next,$change_key,$current_rx); 8057 local(@keys) = (keys %toc_section_info); 8058 8059 local($current_key) = join(' ',@curr_sec_id); 8060 $current_key =~ /^(\d+ )/; 8061 $current_rx = $1; 8062 return() unless $current_rx; 8063 8064 # alter the keys which start as $current_key 8065 foreach $next (@keys) { 8066 if ($next =~ /^$current_rx/) { 8067 # make current document the root 8068 $change_key = '0 '.$'; 8069 $toc_section_info{$change_key} = $toc_section_info{$next}; 8070 $section_info{$change_key} = $section_info{$next}; 8071# if (!($next eq $current_key)) { 8072# $toc_section_info{$next} = $section_info{$next} = ''; 8073# } 8074 } 8075 } 8076} 8077 8078sub top_page { 8079 local($file, @navigation_panel) = @_; 8080 # It is the top page if there is a link to itself 8081 join('', @navigation_panel) =~ /$file/; 8082} 8083 8084# Sets global variable $AUX_FILE 8085sub process_aux_file { 8086 local(@exts) = ('aux'); 8087 push(@exts, 'lof') if (/\\listoffigures/s); 8088 push(@exts, 'lot') if (/\\listoftables/s); 8089 local($_, $status); # To protect caller from &process_ext_file 8090 $AUX_FILE = 1; 8091 foreach $auxfile (@exts) { 8092 $status = &process_ext_file($auxfile); 8093 if ($auxfile eq "aux" && ! $status) { 8094 print "\nCannot open $FILE.aux $!\n"; 8095 &write_warnings("\nThe $FILE.aux file was not found," . 8096 " so sections will not be numbered \nand cross-references " 8097 . "will be shown as icons.\n"); 8098 } 8099 } 8100 $AUX_FILE = 0; 8101} 8102 8103sub do_cmd_htmlurl { 8104 local($_) = @_; 8105 local($url); 8106 $url = &missing_braces unless ( 8107 (s/$next_pair_pr_rx/$br_id=$1;$url=$2;''/e) 8108 ||(s/$next_pair_rx/$br_id=$1;$url=$2;''/e)); 8109 $url =~ s/\\(html)?url\s*($O|$OP)([^<]*)\2/$3/; 8110 $url =~ s/\\?~/;SPMtilde;/og; 8111 join('','<TT>', &make_href($url,$url), '</TT>', $_); 8112} 8113sub do_cmd_url { &do_cmd_htmlurl(@_) } 8114 8115sub make_href { &make_real_href(@_) } 8116sub make_real_href { 8117 local($link, $text) = @_; 8118 $href_name++; 8119 my $htarget = ''; 8120 $htarget = ' target="'.$target.'"' 8121 if (($target)&&($HTML_VERSION > 3.2)); 8122 #HWS: Nested anchors not allowed. 8123 $text =~ s/<A .*><\/A>//go; 8124 #JKR: ~ is handled different - ~ is turned to ~ later. 8125 #$link =~ s/~/$percent_mark . "7E"/geo; 8126 if ($text eq $link) { $text =~ s/~/~/g; } 8127 $link =~ s/~/~/g; 8128 # catch \url or \htmlurl 8129 $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/; 8130 $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:; 8131 # this should not be here; else TOC, List of Figs, etc. fail: 8132 # $link =~ s/^\Q$CURRENT_FILE\E(\#)/$1/ unless ($SEGMENT||$SEGMENTED); 8133 $text = &simplify($text); 8134 "<A NAME=\"tex2html$href_name\"$htarget\n HREF=\"$link\">$text</A>"; 8135} 8136 8137sub make_href_noexpand { # clean 8138 my ($link, $name, $text) = @_; 8139 do {$name = "tex2html". $href_name++} unless $name; 8140 #HWS: Nested anchors not allowed. 8141 $text =~ s/<A .*><\/A>//go; 8142 #JKR: ~ is handled different - ~ is turned to ~ later. 8143 #$link =~ s/~/$percent_mark . "7E"/geo; 8144 if ($text eq $link) { $text =~ s/~/~/g; } 8145 $link =~ s/~/~/g; 8146 # catch \url or \htmlurl 8147 $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/; 8148 $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:; 8149 "<A NAME=\"$name\"\n HREF=\"$link\">$text</A>"; 8150} 8151 8152sub make_named_href { 8153 local($name, $link, $text) = @_; 8154 $text =~ s/<A .*><\/A>//go; 8155 $text = &simplify($text); 8156 if ($text eq $link) { $text =~ s/~/~/g; } 8157 $link =~ s/~/~/g; 8158 # catch \url or \htmlurl 8159 $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/; 8160 $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:; 8161 if (!($name)) {"<A\n HREF=\"$link\">$text</A>";} 8162 elsif ($text =~ /^\w/) {"<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";} 8163 else {"<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";} 8164} 8165 8166sub make_section_heading { 8167 local($text, $level, $anchors) = @_; 8168 local($elevel) = $level; $elevel =~ s/^(\w+)\s.*$/$1/; 8169 local($section_tag) = join('', @curr_sec_id); 8170 local($align,$pre_anchors); 8171 8172 # separate any invisible anchors or alignment, if this has not already been done 8173 if (!($anchors)){ ($anchors,$text) = &extract_anchors($text) } 8174 else { 8175 $anchors =~ s/(ALIGN=\"\w*\")/$align = " $1";''/e; 8176 $align = '' if ($HTML_VERSION < 2.2); 8177 $anchors = &translate_commands($anchors) if ($anchors =~ /\\/); 8178 } 8179 8180 # strip off remains of bracketings 8181 $text =~ s/$OP\d+$CP//g; 8182 if (!($text)) { 8183 # anchor to a single `.' only 8184 $text = "<A NAME=\"SECTION$section_tag\">.</A>$anchors\n"; 8185 } elsif ($anchors) { 8186# # put anchors immediately after, except if title is too long 8187# if ((length($text)<60 )&&(!($align)||($align =~/left/))) { 8188# $text = "<A NAME=\"SECTION$section_tag\">$text</A>\n" . $anchors; 8189 # ...put anchors preceding the title, on a separate when left-aligned 8190# } else { 8191 $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A>$anchors" 8192 . (!($align)||($align =~ /left/i ) ? "<BR>" : "") . "\n". $text; 8193# } 8194 } elsif (!($text =~ /<A[^\w]/io)) { 8195 # no embedded anchors, so anchor it all 8196 $text = "<A NAME=\"SECTION$section_tag\">\n" . $text . "</A>"; 8197 } else { 8198 # there are embedded anchors; these cannot be nested 8199 local ($tmp) = $text; 8200 $tmp =~ s/<//o ; # find 1st < 8201 if ($`) { # anchor text before the first < 8202# $text = "<A NAME=\"SECTION$section_tag\">\n" . $` . "</A>\n<" . $'; 8203 $text = "<A NAME=\"SECTION$section_tag\">\n" . $` . "</A>"; 8204 $pre_anchors = "<" . $'; 8205 if ($pre_anchors =~ /^(<A NAME=\"[^\"]+>${anchor_invisible_mark}<\/A>\s*)+$/) { 8206 $pre_anchors .= "\n" 8207 } else { $text .= $pre_anchors; $pre_anchors = '' } 8208 } else { 8209 # $text starts with a tag 8210 local($after,$tmp) = ($',''); 8211 if ( $after =~ /^A[^\w]/i ) { 8212 # it is an anchor already, so need a separate line 8213 $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A><BR>\n$text"; 8214 } else { 8215 # Is it a tag enclosing the anchor ? 8216 $after =~ s/^(\w)*[\s|>]/$tmp = $1;''/eo; 8217 if ($after =~ /<A.*<\/$tmp>/) { 8218 # it encloses an anchor, so use anchor_mark + break 8219 $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A><BR>\n$text"; 8220 } else { 8221 # take up to the anchor 8222 $text =~ s/^(.*)<A([^\w])/"<A NAME=\"SECTION$section_tag\">$1<A$2"/oe; 8223 } 8224 } 8225 } 8226 } 8227 "$pre_anchors\n<$level$align>$text\n<\/$elevel>"; 8228} 8229 8230sub do_cmd_captionstar { &process_cmd_caption(1, @_) } 8231sub do_cmd_caption { &process_cmd_caption('', @_) } 8232sub process_cmd_caption { 8233 local($noLOTentry, $_) = @_; 8234 local($text,$opt,$br_id, $contents); 8235 local($opt) = &get_next_optional_argument; 8236 $text = &missing_braces unless ( 8237 (s/$next_pair_pr_rx/$br_id=$1;$text=$2;''/e) 8238 ||(s/$next_pair_rx/$br_id=$1;$text=$2;''/e)); 8239 8240 # put it in $contents, so &extract_captions can find it 8241 local($contents) = join('','\caption', ($opt ? "[$opt]" : '') 8242 , "$O$br_id$C" , $text , "$O$br_id$C"); 8243 8244 # $cap_env is set by the surrounding figure/table 8245 &extract_captions($cap_env); 8246 $contents.$_; 8247} 8248 8249sub extract_captions { 8250 # Uses and modifies $contents and $cap_anchors, defined in translate_environments 8251 # and modifies $figure_captions, $table_captions, $before and $after 8252 # MRO: no effect! local($env,*cap_width) = @_; 8253 local($env) = @_; 8254 local(%captions, %optional_captions, $key, $caption, $optional_caption, 8255 $item, $type, $list, $extra_list, $number, @tmp, $br_id, $_); 8256 # associate the br_id of the caption with the argument of the caption 8257 $contents =~ s/$caption_rx(\n)?/do { 8258 $key = $9; $caption = $10; $optional_caption = $3; 8259 $key = &filter_caption_key($key) if (defined &filter_caption_key); 8260 $optional_captions{$key} = $optional_caption||$caption; 8261 $captions{$key} = $10; ''}/ego; 8262# $captions{$9} = $10; $caption_mark }/ego; 8263 $key = $caption = $optional_caption = ''; 8264 8265 #catch any \captionwidth settings that may remain 8266 $contents =~ s/$caption_width_rx(\n)?/&translate_commands($&);''/eo; 8267 8268# $after = join("","<P>",$after) if ($&); 8269# $before .= "</P>" if ($&); 8270 #JKR: Replaced "Figure" and "Table" with variables (see latex2html.config too). 8271 if ($env eq 'figure') { 8272 if ((defined &do_cmd_figurename)||$new_command{'figurename'}){ 8273 $br_id = ++$global{'max_id'}; 8274 $type = &translate_environments("$O$br_id$C\\figurename$O$br_id$C") 8275 unless ($noLOFentry); 8276 } else { $type = $fig_name } 8277 $list = "\$figure_captions"; 8278# $extra_list = "\$segment_figure_captions" if ($figure_table_captions); 8279 $extra_list = "\$segment_figure_captions" if ($segment_figure_captions); 8280 } 8281 elsif ($env =~ /table/) { 8282 if ((defined &do_cmd_tablename)||$new_command{'tablename'}) { 8283 $br_id = ++$global{'max_id'}; 8284 $type = &translate_environments("$O$br_id$C\\tablename$O$br_id$C") 8285 unless ($noLOTentry); 8286 } else { $type = $tab_name } 8287 $list = "\$table_captions"; 8288 $extra_list = "\$segment_table_captions" if ($segment_table_captions); 8289 } 8290 8291# $captions = ""; 8292 $cap_anchors = ""; 8293 local($this); 8294 foreach $key (sort {$a <=> $b;} keys %captions){ # Sort numerically 8295 $this = $captions{$key}; 8296 $this =~ s/\\label\s*($O\d+$C)[^<]+\1//g; # remove \label commands 8297 local($br_id) = ++$global{'max_id'}; 8298 local($open_tags_R) = []; # locally, initially no style 8299 $caption = &translate_commands( 8300 &translate_environments("$O$br_id$C$this$O$br_id$C")); 8301 8302 # same again for the optional caption 8303 $this = $optional_captions{$key}; 8304 $this =~ s/\\label\s*($O\d+$C)[^<]+\1//g; # remove \label commands 8305 local($open_tags_R) = []; local($br_id) = ++$global{'max_id'}; 8306 $this = &translate_environments("$O$br_id$C$this$O$br_id$C"); 8307 $optional_caption = &translate_commands($this); 8308 8309 $cap_anchors .= "<A NAME=\"$key\">$anchor_mark</A>"; 8310 $_ = $optional_caption || $caption; 8311 8312 8313 # split at embedded anchor or citation marker 8314 local($pre_anchor,$post_anchor) = ('',''); 8315 if (/\s*(<A\W|\#[^#]*\#<tex2html_cite_[^>]*>)/){ 8316 $pre_anchor = "$`"; 8317 $post_anchor = "$&$'"; 8318 $pre_anchor = $anchor_invisible_mark 8319 unless (($pre_anchor)||($SHOW_SECTION_NUMBERS)); 8320 } else { 8321 $pre_anchor = "$_"; 8322 } 8323 8324#JCL(jcl-tcl) 8325## &text_cleanup; 8326## $_ = &encode_title($_); 8327## s/ //g; # HWS - LaTeX changes ~ in its .aux files 8328# $_ = &sanitize($_); 8329## 8330# $_ = &revert_to_raw_tex($_); 8331 8332 #replace image-markers by the image params 8333 s/$image_mark\#([^\#]+)\#/&purify_caption($1)/e; 8334 8335 local($checking_caption, $cap_key) = (1, $_); 8336 $cap_key = &simplify($cap_key); 8337 $cap_key = &sanitize($cap_key); 8338 @tmp = split(/$;/, eval ("\$encoded_$env" . "_number{\$cap_key}")); 8339 $number = shift(@tmp); 8340 $number = "" if ($number eq "-1"); 8341 8342 if (!$number) { 8343 $cap_key = &revert_to_raw_tex($cap_key); 8344 @tmp = split(/$;/ 8345 , eval ("\$encoded_$env" . "_number{\$cap_key}")); 8346 $number = shift(@tmp); 8347 $number = "" if ($number eq "-1"); 8348 } 8349 8350 #resolve any embedded cross-references first 8351 $checking_caption = ''; 8352 $_ = &simplify($_); 8353 $_ = &sanitize($_); 8354 8355 8356# @tmp = split(/$;/, eval ("\$encoded_$env" . "_number{\$_}")); 8357# $number = shift(@tmp); 8358# $number = "" if ($number eq "-1"); 8359 8360 &write_warnings(qq|\nNo number for "$_"|) if (! $number); 8361 eval("\$encoded_$env" . "_number{\$_} = join(\$;, \@tmp)"); 8362 8363 $item = join( '', ($SHOW_SECTION_NUMBERS ? $number."\. " : '') 8364 , &make_href("$CURRENT_FILE#$key", $pre_anchor) 8365 , $post_anchor); 8366 undef $_; 8367 undef @tmp; 8368 8369 $captions = join("", ($captions ? $captions."\n<BR>\n" : '') 8370 , "<STRONG>$type" , ($number ? " $number:" : ":") 8371 , "</STRONG>\n$caption" , (($captions) ? "\n" : "" )); 8372 8373 do { 8374 eval "$extra_list .= \"\n<LI>\" .\$item" if ($extra_list); 8375 eval "$list .= \"\n<LI>\" .\$item" } 8376 unless ( $noLOTentry || $noLOFentry); 8377# eval("print \"\nCAPTIONS:\".$extra_list.\n\""); 8378 } 8379} 8380 8381 8382# This processes \label commands found in environments that will 8383# be handed over to Latex. Sets the table %symbolic_labels 8384sub do_labels { 8385 local($context,$new_context) = @_; 8386 local($label); 8387 # MRO: replaced $* by /m 8388 $context =~ s/\s*$labels_rx/do { 8389 $label = &do_labels_helper($2); 8390 $new_context = &anchor_label($label,$CURRENT_FILE,$new_context);""}/geom; 8391 $new_context; 8392} 8393 8394sub extract_labels { 8395 local($_) = @_; 8396 local($label,$anchors); 8397 # MRO: replaced $* by /m 8398 while (s/[ \t]*$labels_rx//om) { 8399 $label = &do_labels_helper($2); 8400 $anchors .= &anchor_label($label,$CURRENT_FILE,''); 8401 } 8402 ($_, $anchors); 8403} 8404 8405# This should be done inside the substitution but it doesn't work ... 8406sub do_labels_helper { 8407 local($_) = @_; 8408 s/$label_rx/_/g; # replace non-alphanumeric characters 8409 $symbolic_labels{$_} = $latex_labels{$_}; # May be empty; 8410 $_; 8411} 8412 8413sub convert_to_description_list { 8414 # MRO: modified to use $_[1] 8415 # local($which, *list) = @_; 8416 my $which = $_[0]; 8417 $_[1] =~ s!(</A>\s*)<[OU]L([^>]*)>!$1<DD><DL$2>!ig; 8418 $_[1] =~ s!<(/?)[OU]L([^>]*)>!$1? "<$1DL$2>":"<DL$2>"!eig; 8419 $_[1] =~ s!(</?)LI>!$1D$which>!ig; 8420# $_[1] =~ s/^\s*<DD>//; 8421} 8422 8423sub add_toc { &add_real_toc(@_) } 8424sub add_real_toc { 8425 local($temp1, $temp2); 8426 print "\nDoing table of contents ..."; 8427 local(@keys) = keys %toc_section_info; 8428 @keys = sort numerically @keys; 8429 $temp1 = $MAX_LINK_DEPTH; $temp2 = $MAX_SPLIT_DEPTH; 8430 $MAX_SPLIT_DEPTH = $MAX_LINK_DEPTH = 1000; 8431 #JKR: Here was a "Contents" - replaced it with $toc_title 8432 local($base_key) = $keys[0]; 8433 if ($MULTIPLE_FILES) { 8434 $base_key = $THIS_FILE; 8435 } 8436 local($title); 8437 if ((defined &do_cmd_contentsname)||$new_command{'contentsname'}) { 8438 local($br_id)=++$global{'max_id'}; 8439 $title = &translate_environments("$O$br_id$C\\contentsname$O$br_id$C"); 8440 } else { $title = $toc_title } 8441 local($toc,$on_first_page) = ('',''); 8442 $on_first_page = $CURRENT_FILE 8443 unless ($MAX_SPLIT_DEPTH && $MAX_SPLIT_DEPTH <1000); 8444 $toc = &add_child_links($title,$on_first_page,'',1,$keys[0],@keys); 8445 &convert_to_description_list('T',$toc) if ($use_description_list); 8446 s/$toc_mark/$toc/; 8447 $MAX_LINK_DEPTH = $temp1; $MAX_SPLIT_DEPTH = $temp2; 8448} 8449 8450# Assign ref value, but postpone naming the label 8451sub make_half_href { 8452 local($link) = $_[0]; 8453 $href_name++; 8454 "<A NAME=\"tex2html$href_name\"\n HREF=\"$link\">"; 8455} 8456 8457 8458# Redefined in makeidx.perl 8459sub add_idx { 8460 local($sidx_style, $eidx_style) =('<STRONG>','</STRONG>'); 8461 if ($INDEX_STYLES) { 8462 if ($INDEX_STYLES =~/,/) { 8463 local(@styles) = split(/\s*,\s*/,$INDEX_STYLES); 8464 $sidx_style = join('','<', join('><',@styles) ,'>'); 8465 $eidx_style = join('','</', join('></',reverse(@styles)) ,'>'); 8466 } else { 8467 $sidx_style = join('','<', $INDEX_STYLES,'>'); 8468 $eidx_style = join('','</', $INDEX_STYLES,'>'); 8469 } 8470 } 8471 &add_real_idx(@_) 8472} 8473sub add_real_idx { 8474 print "\nDoing the index ..."; 8475 local($key, $str, @keys, $index, $level, $count, 8476 @previous, @current); 8477 @keys = keys %index; 8478 @keys = sort keysort @keys; 8479 $level = 0; 8480 foreach $key (@keys) { 8481 @current = split(/!/, $key); 8482 $count = 0; 8483 while ($current[$count] eq $previous[$count]) { 8484 $count++; 8485 } 8486 while ($count > $level) { 8487 $index .= "\n<DL COMPACT>"; 8488 $level++; 8489 } 8490 while ($count < $level) { 8491 $index .= "\n</DL>"; 8492 $level--; 8493 } 8494 foreach $term (@current[$count .. $#current-1]) { 8495 # need to "step in" a little 8496# $index .= "<DT>" . $term . "\n<DL COMPACT>"; 8497 $index .= "\n<DT>$sidx_style" . $term . "$eidx_style\n<DD><DL COMPACT>"; 8498 $level++; 8499 } 8500 $str = $current[$#current]; 8501 $str =~ s/\#\#\#\d+$//o; # Remove the unique id's 8502 $index .= $index{$key} . 8503 # If it's the same string don't start a new line 8504 (&index_key_eq(join('',@current), join('',@previous)) ? 8505 ", $sidx_style" . $cross_ref_visible_mark . "$eidx_style</A>\n" : 8506 "<DT>$sidx_style" . $str . "$eidx_style</A>\n"); 8507 @previous = @current; 8508 } 8509 while ($count < $level) { 8510 $index .= "\n</DL>"; 8511 $level--; 8512 } 8513 $index = '<DD>'.$index unless ($index =~ /^\s*<D(T|D)>/); 8514 8515 $index =~ s/(<A [^>]*>)(<D(T|D)>)/$2$1/g; 8516 8517# s/$idx_mark/<DL COMPACT>$index<\/DL>/o; 8518 s/$idx_mark/$preindex\n<DL COMPACT>\n$index<\/DL>\n/o; 8519} 8520 8521sub keysort { 8522 local($x, $y) = ($a,$b); 8523 $x = &clean_key($x); 8524 $y = &clean_key($y); 8525# "\L$x" cmp "\L$y"; # changed sort-rules, by M Ernst. 8526 # Put alphabetic characters after symbols; already downcased 8527 $x =~ s/^([a-z])/~~~$1/; 8528 $y =~ s/^([a-z])/~~~$1/; 8529 $x cmp $y; 8530} 8531 8532sub index_key_eq { 8533 local($a,$b) = @_; 8534 $a = &clean_key($a); 8535 $b = &clean_key($b); 8536 $a eq $b; 8537} 8538 8539sub clean_key { 8540 local ($_) = @_; 8541 tr/A-Z/a-z/; 8542 s/\s+/ /g; # squeeze white space and newlines into space 8543 s/ (\W)/$1/g; # make foo( ), foo () and foo(), or <TT>foo</TT> 8544 ; # and <TT>foo </TT> to be equal 8545 s/$O\d+$C//go; # Get rid of bracket id's 8546 s/$OP\d+$CP//go; # Get rid of processed bracket id's 8547 s/\#\#\#\d+$//o; # Remove the unique id 8548 $_; 8549} 8550 8551 8552sub make_footnotes { 8553 # Uses $footnotes defined in translate and set in do_cmd_footnote 8554 # Also uses $footfile 8555 local($_) = "\n<DL>$footnotes\n<\/DL>"; 8556 $footnotes = ""; # else they get used 8557 local($title); 8558 if ((defined &do_cmd_footnotename)||$new_command{'footnotename'}) { 8559 local($br_id)=++$global{'max_id'}; 8560 $title = &translate_environments("$O$br_id$C\\footnotename$O$br_id$C"); 8561 } else { 8562 $foot_title = "Footnotes" unless $foot_title; 8563 $title = $foot_title; 8564 } 8565 print "\nDoing footnotes ..."; 8566#JCL(jcl-tcl) 8567# If the footnotes go into a separate file: see &make_file. 8568 if ($footfile) { 8569 $toc_sec_title = $title; 8570 &make_file($footfile, $title, $FOOT_COLOR); # Modifies $_; 8571 $_ = ""; 8572 } else { 8573 $footnotes = ""; # else they get re-used 8574 $_ = join ('', '<BR><HR><H4>', $title, '</H4>', $_ ); 8575 } 8576 $_; 8577} 8578 8579sub post_process_footnotes { 8580 &slurp_input($footfile); 8581 open(OUT, ">$footfile") || die "Cannot write file '$footfile': $!\n"; 8582 &replace_markers; 8583 &post_post_process if (defined &post_post_process); 8584 &adjust_encoding; 8585 print OUT $_; 8586 close OUT; 8587} 8588 8589sub make_file { 8590 # Uses and modifies $_ defined in the caller 8591 local($filename, $title, $layout) = @_; 8592 $layout = $BODYTEXT unless $layout; 8593 $_ = join('',&make_head_and_body($title,$layout), $_ 8594 , (($filename =~ /^\Q$footfile\E$/) ? '' : &make_address ) 8595 , (($filename =~ /^\Q$footfile\E$/) ? "\n</BODY>\n</HTML>\n" : '') 8596 ); 8597 &replace_markers unless ($filename eq $footfile); 8598 8599 unless(open(FILE,">$filename")) { 8600 print "\nError: Cannot write '$filename': $!\n"; 8601 return; 8602 } 8603 print FILE $_; 8604 close(FILE); 8605} 8606 8607sub add_to_body { 8608 local($attrib, $value) = @_; 8609 local($body) = $BODYTEXT; 8610 if ($body =~ s/\Q$attrib\E\s*=\s*"[^"]*"/$attrib="$value"/) { 8611 } else { 8612 $body .= " $attrib=\"$value\""; $body =~ s/\s{2,}/ /g; 8613 } 8614 $BODYTEXT = $body if $body; 8615} 8616 8617sub replace_verbatim_marks { 8618 # Modifies $_ 8619 my($tmp); 8620 s/$math_verbatim_rx/&make_comment('MATH', $verbatim{$1})/eg; 8621 s/$mathend_verbatim_rx/&make_comment('MATHEND', '')/eg; 8622# s/$verbatim_mark(verbatim\*?)(\d+)#/<PRE>\n$verbatim{$2}\n<\/PRE>/go; 8623## s/$verbatim_mark(\w*[vV]erbatim\*?)(\d+)#/\n$verbatim{$2}\n/go; 8624 s!$verbatim_mark(\w*[vV]erbatim\*?|tex2html_code)(\d+)#\n?!$tmp=$verbatim{$2}; 8625 $tmp.(($tmp =~/\n\s*$/s)? '':"\n")!eg; 8626# "\n".$tmp.(($tmp =~/\n\s*$/s)? '':"\n")!eg; 8627# s/$verbatim_mark(rawhtml)(\d+)#/$verbatim{$2}/eg; # Raw HTML 8628 s/$verbatim_mark(imagesonly)(\d+)#//eg; # imagesonly is *not* replaced 8629 # Raw HTML, but replacements may have protected characters 8630 s/$verbatim_mark(rawhtml)(\d+)#/&unprotect_raw_html($verbatim{$2})/eg; 8631 s/$verbatim_mark$keepcomments_rx(\d+)#/$verbatim{$2}/ego; # Raw TeX 8632 s/$unfinished_mark$keepcomments_rx(\d+)#/$verbatim{$2}/ego; # Raw TeX 8633} 8634 8635# TeX's special characters may have been escaped with a '\'; remove it. 8636sub unprotect_raw_html { 8637 local($raw) = @_; 8638 $raw =~ s/\\($latex_specials_rx|~|\^|@)/$1/g; 8639 $raw; 8640} 8641 8642# remove file-markers; special packages may redefine &replace_file_marks 8643sub remove_file_marks { 8644 s/<(DD|LI)>\n?($file_mark|$endfile_mark)\#.*\#\n<\/\1>(\n|(<))/$4/gm; 8645 s/($file_mark|$endfile_mark)\#.*\#(\n|(<))/$3/gm; 8646} 8647sub replace_file_marks { &remove_file_marks } 8648 8649sub remove_verbatim_marks { 8650 # Modifies $_ 8651 s/($math_verbatim_rx|$mathend_verbatim_rx)//go; 8652# s/$verbatim_mark(verbatim\*?)(\d+)#//go; 8653 s/$verbatim_mark(\w*[Vv]erbatim\w*\*?)(\d+)#//go; 8654 s/$verbatim_mark(rawhtml|imagesonly)(\d+)#//go; 8655 s/$verbatim_mark$keepcomments_rx(\d+)#//go; 8656 s/$unfinished_mark$keepcomments_rx(\d+)#//go; 8657} 8658 8659sub replace_verb_marks { 8660 # Modifies $_ 8661 s/(?:$verb_mark|$verbstar_mark)(\d+)$verb_mark/ 8662 $code = $verb{$1}; 8663 $code = &replace_comments($code) if ($code =~ m:$comment_mark:); 8664 "<code>$code<\/code>"/ego; 8665} 8666 8667sub replace_comments{ 8668 local($_) = @_; 8669 $_ =~ s/$comment_mark(\d+)\n?/$verbatim{$1}/go; 8670 $_ =~ s/$comment_mark\d*\n/%\n/go; 8671 $_; 8672} 8673 8674sub remove_verb_marks { 8675 # Modifies $_ 8676 s/($verb_mark|$verbstar_mark)(\d+)$verb_mark//go; 8677} 8678 8679# This is used by revert_to_raw_tex 8680sub revert_verbatim_marks { 8681 # Modifies $_ 8682# s/$verbatim_mark(verbatim)(\d+)#/\\begin{verbatim}$verbatim{$2}\\end{verbatim}\n/go; 8683 s/$verbatim_mark(\w*[Vv]erbatim)(\d+)#/\\begin{$1}\n$verbatim{$2}\\end{$1}\n/go; 8684 s/$verbatim_mark(rawhtml)(\d+)#/\\begin{rawhtml}\n$verbatim{$2}\\end{rawhtml}\n/go; 8685 s/$verbatim_mark(imagesonly|tex2html_code)(\d+)#\n?/$verbatim{$2}/go; 8686 s/$verbatim_mark$image_env_rx(\d+)#/\\begin{$1}\n$verbatim{$2}\\end{$1}\n/go; 8687 s/($math_verbatim_rx|$mathend_verbatim_rx)//go; 8688} 8689 8690sub revert_verb_marks { 8691 # Modifies $_ 8692 s/$verbstar_mark(\d+)$verb_mark/\\verb*$verb_delim{$1}$verb{$1}$verb_delim{$1}/go; 8693 s/$verb_mark(\d+)$verb_mark/\\verb$verb_delim{$1}$verb{$1}$verb_delim{$1}/go; 8694} 8695 8696sub replace_cross_ref_marks { 8697 # Modifies $_ 8698 local($label,$id,$ref_label,$ref_mark,$after,$name); 8699 local($invis) = "<tex2html_anchor_invisible_mark></A>"; 8700# s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark/ 8701 s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark<\/A>(\s*<A( NAME=\"\d+)\">$invis)?/ 8702 do {($label,$id) = ($1,$2); $name = $4; 8703 $ref_label = $external_labels{$label} unless 8704 ($ref_label = $ref_files{$label}); 8705 print "\nXLINK<: $label : $id :$name " if ($VERBOSITY > 3); 8706 $ref_label = '' if ($ref_label eq $CURRENT_FILE); 8707 $ref_mark = &get_ref_mark($label,$id); 8708 &extend_ref if ($name); $name = ''; 8709 print "\nXLINK: $label : $ref_label : $ref_mark " if ($VERBOSITY > 3); 8710 '"' . "$ref_label#$label" . "\">" . $ref_mark . "<\/A>" 8711 }/geo; 8712 8713 # This is for pagerefs which cannot have symbolic labels ??? 8714# s/$cross_ref_mark#(\w+)#\w+>/ 8715 s/$cross_ref_mark#([^#]+)#[^>]+>/ 8716 do {$label = $1; 8717 $ref_label = $external_labels{$label} unless 8718 ($ref_label = $ref_files{$label}); 8719 $ref_label = '' if ($ref_label eq $CURRENT_FILE); 8720 print "\nXLINKP: $label : $ref_label" if ($VERBOSITY > 3); 8721 '"' . "$ref_files{$label}#$label" . "\">" 8722 }/geo; 8723} 8724 8725#RRM: this simply absorbs the name from the invisible anchor following, 8726# when the anchor itself is not already named. 8727sub extend_ref { 8728 if ($ref_label !=~ /NAME=/) { $label .= "\"\n".$name } 8729} 8730 8731sub remove_cross_ref_marks { 8732 # Modifies $_ 8733# s/$cross_ref_mark#(\w+)#(\w+)>$cross_ref_mark/ 8734 s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark/ 8735 print "\nLOST XREF: $1 : $2" if ($VERBOSITY > 3);''/ego; 8736# s/$cross_ref_mark#(\w+)#\w+>//go; 8737 s/$cross_ref_mark#([^#]+)#[^#>]+>//go; 8738} 8739 8740sub replace_external_ref_marks { 8741 # Modifies $_ 8742 local($label, $link); 8743# s/$external_ref_mark#(\w+)#(\w+)>$external_ref_mark/ 8744 s/$external_ref_mark#([^#]+)#([^>]+)>$external_ref_mark/ 8745 do {($label,$id) = ($1,$2); 8746 $link = $external_labels{$label}; 8747 print "\nLINK: $label : $link" if ($VERBOSITY > 3); 8748 '"'. "$link#$label" . "\">\n" 8749 . &get_ref_mark("userdefined$label",$id) 8750 } 8751 /geo; 8752} 8753 8754sub remove_external_ref_marks { 8755 # Modifies $_ 8756# s/$external_ref_mark#(\w+)#(\w+)>$external_ref_mark/ 8757 s/$external_ref_mark#([^#]+)#([^>]+)>$external_ref_mark/ 8758 print "\nLOST LINK: $1 : $2" if ($VERBOSITY > 3);''/ego; 8759} 8760 8761sub get_ref_mark { 8762 local($label,$id) = @_; 8763 ( ( $SHOW_SECTION_NUMBERS && $symbolic_labels{"$label$id"}) || 8764 $latex_labels{"userdefined$label$id"} || 8765 $symbolic_labels{"$label$id"} || 8766 $latex_labels{$label} || 8767 $external_latex_labels{$label} || 8768 $cross_ref_visible_mark ); 8769} 8770 8771sub replace_bbl_marks { 8772 # Modifies $_ 8773 s/$bbl_mark#([^#]+)#/$citations{$1}/go; 8774} 8775 8776sub remove_bbl_marks { 8777 # Modifies $_ 8778 s/$bbl_mark#([^#]+)#//go; 8779} 8780 8781sub replace_image_marks { 8782 # Modifies $_ 8783 s/$image_mark#([^#]+)#([\.,;:\)\]])?(\001)?([ \t]*\n?)(\001)?/ 8784 "$id_map{$1}$2$4"/ego; 8785# "$id_map{$1}$2".(($4)?"\n":'')/ego; 8786} 8787 8788sub remove_image_marks { 8789 # Modifies $_ 8790 s/$image_mark#([^#]+)#//go; 8791} 8792 8793sub replace_icon_marks { 8794 # Modifies $_ 8795 if ($HTML_VERSION < 2.2 ) { 8796 local($icon); 8797 s/$icon_mark_rx/$icon = &img_tag($1); 8798 $icon =~ s| BORDER="?\d+"?||;$icon/ego; 8799 } else { 8800 s/$icon_mark_rx/&img_tag($1)/ego; 8801 } 8802} 8803 8804sub remove_icon_marks { 8805 # Modifies $_ 8806 s/$icon_mark_rx//go; 8807} 8808 8809sub replace_cite_marks { 8810 local($key,$label,$text,$file); 8811 # Modifies $_ 8812 # Uses $citefile set by the thebibliography environment 8813 local($citefile) = $citefile; 8814 $citefile =~ s/\#.*$//; 8815 8816 s/#([^#]+)#$cite_mark#([^#]+)#((($OP\d+$CP)|[^#])*)#$cite_mark#/ 8817 $text = $3; $label= $1; $file=''; 8818 $text = $cite_info{$1} unless $text; 8819 if ($checking_caption){ 8820 "$label" 8821 } elsif ($citefiles{$2}){ 8822 $file = $citefiles{$2}; $file =~ s:\#.*$::; 8823 &make_named_href('', "$file#$label","$text"); 8824 } elsif ($PREAMBLE) { 8825 $text || "\#!$1!\#" ; 8826 } elsif ($simplifying) { 8827 $text 8828 } else { 8829 &write_warnings("\nno reference for citation: $1"); 8830 "\#!$1!\#" 8831 }/sge ; 8832 # 8833 #RRM: Associate the cite_key with $citefile , for use by other segments. 8834 if ($citefile) { 8835 local($cite_key, $cite_ref); 8836 while (($cite_key, $cite_ref) = each %cite_info) { 8837 if ($ref_files{'cite_'."$cite_key"} ne $citefile) { 8838 $ref_files{'cite_'."$cite_key"} = $citefile; 8839 $changed = 1; } 8840 } 8841 } 8842} 8843 8844sub remove_cite_marks { 8845 # Modifies $_ 8846 s/#([^#]+)#$cite_mark#([^#]+)#([^#]*)#$cite_mark#//go; 8847} 8848 8849sub remove_anchors { 8850# modifies $_ 8851 s/<A[^>]*>//g; 8852 s/<\/A>//g; 8853} 8854 8855 8856# We need two matching keys to determine section/figure/etc. numbers. 8857# The "keys" are the name of the section/figure/etc. and its 8858# equivalent in the .aux file (also carrying the number we desire). 8859# But both keys might have been translated slightly different, 8860# depending on the usage of math, labels, special characters such 8861# as umlauts, or simply spacing! 8862# 8863# This routine tries to squeeze the HTML translated keys such 8864# that they match (hopefully very often). -- JCL 8865# 8866sub sanitize { 8867 local($_,$mode) = @_; 8868 &remove_markers; 8869 &remove_anchors; 8870 &text_cleanup; 8871 s/(\&|;SPM)nbsp;//g; # HWS - LaTeX changes ~ in its .aux files 8872 #strip unwanted HTML constructs 8873 s/<\/?(P|BR|H)[^>]*>//g; 8874 s/\s+//g; #collapse white space 8875 $_; 8876} 8877 8878# This one removes any HTML markup, so that pure 8879# plain text remains. (perhaps with <SUP>/<SUB> tags) 8880# As the result will be part of the HTML file, it will be 8881# &text_cleanup'd later together with its context. 8882# 8883sub purify { 8884 local($_,$strict) = @_; 8885 &remove_markers; 8886 #strip unwanted HTML constructs 8887# s/<[^>]*>/ /g; 8888 s/<(\/?SU[BP])>/>$1>/g unless ($strict); # keep sup/subscripts ... 8889 s/<[^>]*>//g; # remove all other tags 8890 s/>(\/?SU[BP])>/<$1>/g unless ($strict); # ...reinsert them 8891 s/^\s+|\001//g; s/\s\s+/ /g; #collapse white space 8892 $_; 8893} 8894 8895# This one is not as strict as &sanitize. 8896# It is chosen to strip section names etc. a bit from 8897# constructs so that it better fits a table of contents, 8898# label files, etc. 8899# As the result will be part of the HTML file, it will be 8900# &text_cleanup'd later together with its context. 8901# 8902sub simplify { 8903 local($_) = @_; 8904 local($simplifying) = 1; 8905 s/$tex2html_envs_rx//g; 8906 if (/\\/) { 8907 local($USING_STYLES) = 0; 8908 $_ = &translate_commands($_); 8909 undef $USING_STYLES; 8910 } 8911 &replace_external_ref_marks if /$external_ref_mark/; 8912 &replace_cross_ref_marks if /$cross_ref_mark||$cross_ref_visible_mark/; 8913 &replace_cite_marks if /$cite_mark/; 8914 # strip unwanted HTML constructs 8915# s/<\/?H[^>]*>/ /g; 8916 s/<\/?(H)[^>]*>//g; 8917 s/<\#\d+\#>//g; 8918 s/^\s+//; 8919 $_; 8920} 8921 8922#RRM: This extracts $anchor_mark portions from a given chunk of text, 8923# so they can be positioned separately by the calling subroutine. 8924# added for v97.2: 8925# search within the immediately following text also; so that 8926# \index and \label after section-headings work as expected. 8927# 8928sub extract_anchors { 8929 local($search_text, $start_only) = @_; 8930 local($anchors) = ''; 8931 local($untranslated_anchors) = ''; 8932 8933 do { 8934 while ($search_text =~ s/<A[^>]*>($anchor_mark|$anchor_invisible_mark)<\/A>//) { 8935 $anchors .= $&; 8936 } 8937 } unless ($start_only); 8938 8939 $search_text =~ s/\s*(\\protect)?\\(label|index|markright|markboth\s*(($O|$OP)\d+($C|$CP))[^<]*\3)\s*(($O|$OP)\d+($C|$CP))[^<]*\6/ 8940 $anchors .= $&;''/eg unless ($start_only); 8941 8942 while ( s/^\s*<A[^>]*>($anchor_mark|$anchor_invisible_mark)<\/A>//m) { 8943 $untranslated_anchors .= $&; 8944 } 8945 while ( s/^\s*(\\protect)?\\(label|index|markright|markboth\s*(($O|$OP)\d+($C|$CP))[^<]*\3)\s*(($O|$OP)\d+($C|$CP))[^<]*\6//) { 8946 $untranslated_anchors .= $&; 8947 } 8948 if ($TITLE||$start_only) { 8949 $anchors .= &translate_commands($untranslated_anchors); 8950 $untranslated_anchors = ''; 8951 } 8952 ($anchors.$untranslated_anchors,$search_text); 8953} 8954 8955# This routine must be called once on the text only, 8956# else it will "eat up" sensitive constructs. 8957sub text_cleanup { 8958 # MRO: replaced $* with /m 8959 s/(\s*\n){3,}/\n\n/gom; # Replace consecutive blank lines with one 8960 s/<(\/?)P>\s*(\w)/<$1P>\n$2/gom; # clean up paragraph starts and ends 8961 s/$O\d+$C//go; # Get rid of bracket id's 8962 s/$OP\d+$CP//go; # Get rid of processed bracket id's 8963 s/(<!)?--?(>)?/(length($1) || length($2)) ? "$1--$2" : "-"/ge; 8964 # Spacing commands 8965 s/\\( |$)/ /go; 8966 #JKR: There should be no more comments in the source now. 8967 #s/([^\\]?)%/$1/go; # Remove the comment character 8968 # Cannot treat \, as a command because , is a delimiter ... 8969 s/\\,/ /go; 8970 # Replace tilde's with non-breaking spaces 8971 s/ *~/ /g; 8972 8973 ### DANGEROUS ?? ### 8974 # remove redundant (not <P></P>) empty tags, incl. with attributes 8975 s/\n?<([^PD >][^>]*)>\s*<\/\1>//g; 8976 s/\n?<([^PD >][^>]*)>\s*<\/\1>//g; 8977 # remove redundant empty tags (not </P><P> or <TD> or <TH>) 8978 s/<\/(TT|[^PTH][A-Z]+)><\1>//g; 8979 s/<([^PD ]+)(\s[^>]*)?>\n*<\/\1>//g; 8980 8981 8982#JCL(jcl-hex) 8983# Replace ^^ special chars (according to p.47 of the TeX book) 8984# Useful when coming from the .aux file (german umlauts, etc.) 8985 s/\^\^([^0-9a-f])/chr((64+ord($1))&127)/ge; 8986 s/\^\^([0-9a-f][0-9a-f])/chr(hex($1))/ge; 8987} 8988 8989# This is useful for getting words from a title which are not cluttered 8990# with tex2html markers or HTML constructs 8991sub extract_pure_text { 8992 local($mode) = @_; 8993 &text_cleanup; # Remove marking brackets 8994# 8995# HWS <hswan@perc.Arco.com>: Conditionally doing the following 8996# permits equations in section headings. 8997# 8998 if ($mode eq "strict") { 8999 s/$image_mark#[^#]*#//g; # Remove image marker 9000 s/$bbl_mark#[^#]*#//g; # Remove citations marker 9001 s/<tex2html_percent_mark>/%/g; # BMcM: Retain % signs... 9002 s/<tex2html_ampersand_mark>/\&/g; 9003 s/tex2html[\w\d]*//g; # Remove other markers 9004 } 9005 9006# 9007# HWS <hswan@perc.Arco.com>: Replace next statement with the following two 9008# to permit symbolic links and images to appear in section headings. 9009 9010# s/<[^>]*>//go; # Remove HTML constructs 9011 s/$OP[^#]*$CP//go; # Remove <# * #> constructs 9012 s/<\s*>//go; # Remove embedded whitespace 9013} 9014 9015############################ Misc #################################### 9016 9017# MRO: Print standardized header 9018sub banner { 9019 print <<"EOF"; 9020This is LaTeX2HTML Version $TEX2HTMLVERSION 9021by Nikos Drakos, Computer Based Learning Unit, University of Leeds. 9022 9023EOF 9024} 9025 9026# MRO: Extract usage information from POD 9027sub usage { 9028 my $start = 0; 9029 my $usage = 'Usage: '; 9030 my $indent = ''; 9031 9032 print (@_, "\n") if @_; 9033 9034#if @texlive@ 9035 my $perldoc = "perldoc"; 9036#else 9037 my $perldoc = "@PERLSCRIPTDIR@${dd}perldoc"; 9038#fi 9039 my $script = $SCRIPT || $0; 9040 open(PIPE, "$perldoc -t $script |") 9041 || die "Fatal: can't open pipe: $!"; 9042 while (<PIPE>) { 9043 if (/^\s*$/) { 9044 next; 9045 } elsif (/^SYNOPSIS/) { 9046 $start = 1; 9047 } elsif (/^\w/) { 9048 $start = 0; 9049 } elsif ($start == 1) { 9050 ($indent) = /^(\s*)/; 9051 s/^$indent/$usage/; 9052 $usage =~ s/./ /g; 9053 $start = 2; 9054 print $_; 9055 } elsif ($start == 2) { 9056 s/^$indent/$usage/; 9057 print $_; 9058 } 9059 } 9060 close PIPE; 9061 1; 9062} 9063 9064# The bibliographic references, the appendices, the lists of figures and tables 9065# etc. must appear in the contents table at the same level as the outermost 9066# sectioning command. This subroutine finds what is the outermost level and 9067# sets the above to the same level; 9068sub set_depth_levels { 9069 # Sets $outermost_level 9070 local($level); 9071 # scan the document body, not the preamble, for use of sectioning commands 9072 my ($contents) = $_; 9073 if ($contents =~ /\\begin\s*((?:$O|$OP)\d+(?:$C|$CP))document\1|\\startdocument/s) { 9074 $contents = $'; 9075 } 9076 #RRM: do not alter user-set value for $MAX_SPLIT_DEPTH 9077 foreach $level ("part", "chapter", "section", "subsection", 9078 "subsubsection", "paragraph") { 9079 last if (($outermost_level) = $contents =~ /\\($level)$delimiter_rx/); 9080 last if (($outermost_level) = $contents =~ /\\endsegment\s*\[\s*($level)\s*\]/s); 9081 if ($contents =~ /\\segment\s*($O\d+$C)[^<]+\1\s*($O\d+$C)\s*($level)\s*\2/s) 9082 { $outermost_level = $3; last }; 9083 } 9084 $level = ($outermost_level ? $section_commands{$outermost_level} : 9085 do {$outermost_level = 'section'; 3;}); 9086 9087 #RRM: but calculate value for $MAX_SPLIT_DEPTH when a $REL_DEPTH was given 9088 if ($REL_DEPTH && $MAX_SPLIT_DEPTH) { 9089 $MAX_SPLIT_DEPTH = $level + $MAX_SPLIT_DEPTH; 9090 } elsif (!($MAX_SPLIT_DEPTH)) { $MAX_SPLIT_DEPTH = 1 }; 9091 9092 %unnumbered_section_commands = ( 9093 'tableofcontents', $level 9094 , 'listoffigures', $level 9095 , 'listoftables', $level 9096 , 'bibliography', $level 9097 , 'textohtmlindex', $level 9098 , %unnumbered_section_commands 9099 ); 9100 9101 %section_commands = ( 9102 %unnumbered_section_commands 9103 , %section_commands 9104 ); 9105} 9106 9107# Now ignores accents which cannot be translated to ISO-LATIN-1 characters 9108# Also replaces ?' and !' .... 9109sub replace_strange_accents { 9110 &real_replace_strange_accents(@_); # if ($CHARSET =~ /8859[_\-]1$/); 9111} 9112sub real_replace_strange_accents { 9113 # Modifies $_; 9114 s/\?`/&iso_map("iquest", "")/geo; 9115 s/!`/&iso_map("iexcl", "")/geo; 9116 s/\\\^\\i /&iso_map("icirc", "")/geo; 9117 my ($charset) = "${CHARSET}_character_map_inv"; 9118 $charset =~ s/-/_/g; 9119 # convert upper 8-bit characters 9120 if (%$charset &&($CHARSET =~ /8859[_\-]1$/)) { 9121 s/([\200-\377])/ 9122 $tmp = $$charset{'&#'.ord($1).';'}; 9123 &mark_string($tmp) if ($tmp =~ m!\{!); 9124 &translate_commands($tmp) 9125 /egos 9126 } 9127}; 9128 9129# Creates a new directory or reuses old, perhaps after deleting its contents 9130sub new_dir { 9131 local($this_dir,$mode) = @_; 9132 local(@files)=(); 9133 $this_dir = '.' unless $this_dir; 9134 $this_dir =~ s/[$dd$dd]+$//o; 9135 local($print_dir) = $this_dir.$dd; 9136 (!$mode && mkdir($this_dir, 0755)) || 9137 do { 9138 print "\nCannot create directory $print_dir: $!" unless ($mode); 9139 if ($REUSE) { 9140 print ", reusing it.\n" unless ($mode); 9141 &reuse($this_dir,$print_dir); 9142 } else { 9143 print "\n" unless ($mode); 9144 while (! ($answer =~ /^[dqr]$/)) { 9145 if ($mode) { 9146 $answer = $mode; 9147 } else { 9148 print "(r) Reuse the images in the old directory OR\n" 9149 . (($this_dir eq '.') ? 9150 "(d) *** DELETE *** the images in $print_dir OR\n" 9151 : "(d) *** DELETE *** THE CONTENTS OF $print_dir OR\n" ) 9152 . "(q) Quit ?\n:"; 9153 $answer = scalar(<STDIN>); 9154 }; 9155 if ($answer =~ /^d$/) { 9156 @files = (); 9157 if(opendir(DIR,$this_dir)) { 9158 @files = readdir DIR; 9159 closedir DIR; 9160 } else { 9161 print "\nError: Cannot read dir '$this_dir': $!\n"; 9162 } 9163 foreach (@files) { 9164 next if /^\.+$/; 9165 if (-d "$this_dir$dd$_") { 9166 &new_dir("$this_dir$dd$_",'d'); 9167 } elsif ($this_dir eq '.') { 9168 L2hos->Unlink($_) if (/\.(pl|gif|png)$/) 9169 } else { 9170 L2hos->Unlink("$this_dir$dd$_"); 9171 }; 9172 } 9173 return(1) if ($this_dir eq '.'); 9174 if($mode) { 9175 rmdir($this_dir); 9176 rmdir($print_dir); 9177 } 9178 if (!$mode) { &new_dir($this_dir,'r')}; 9179 return(1); 9180 } elsif ($answer =~ /^q$/) { 9181 die "Bye!\n"; 9182 } elsif ($answer =~ /^r$/) { 9183 &reuse($this_dir,$print_dir); 9184 return(1); 9185 } else {print "Please answer r d or q!\n";}; 9186 } 9187 }; 9188 }; 9189 1; 9190} 9191 9192sub reuse { 9193 local($this_dir,$print_dir) = @_; 9194 $print_dir = $this_dir.$dd unless ($print_dir); 9195 if (-f "$this_dir$dd${PREFIX}images.pl") { 9196 print STDOUT "Reusing directory $print_dir:\n"; 9197 local($key); 9198 require("$this_dir$dd${PREFIX}images.pl"); 9199 } 9200} 9201 9202 9203# JCL(jcl-del) - use $CD rather than a space as delimiter. 9204# The commands might take white space, or not, depending on 9205# their definition. Eg. \relax takes white space, because it's a 9206# letter command, but \/ won't. 9207# TeX seems to have an internal separator: If \x is " x", 9208# and \y is "y", then \expandafter\y \x expands to "y x", TeX 9209# hasn't gobbled the space, meaning that spaces are gobbled once 9210# when the \y token is consumed, but then never again after \y. 9211# 9212# The actions below ensure to insert exactly one space after 9213# the command name. # what happens to `\ ' ? 9214# The substition is done twice to handle \one\delimits\another 9215# cases. 9216# The internal shortcut $CD is then turned into the single 9217# space we desire. 9218# 9219sub tokenize { 9220 # Modifies $_; 9221 local($rx) = @_; 9222 # $rx must be specially constructed, see &make_new_cmd_rx. 9223 if (length($rx)) { 9224 # $1: non-letter cmd, or $2: letter cmd 9225 s/$rx/\\$1$2$CD$4/g; 9226 s/$rx/\\$1$2$CD$4/g; 9227 s/$CD+/ /g; # puts space after each command name 9228 } 9229} 9230 9231# When part of the input text contains special perl characters and the text 9232# is to be used as a pattern then these specials must be escaped. 9233sub escape_rx_chars { 9234 my($rx) = @_; # must use a copy of the string 9235 $rx =~ s:([\\(){}[\]\^\$*+?.|]):\\$1:g; $rx; } 9236 9237# Does not do much but may need it later ... 9238# The document environment has to be removed because it spans 9239# more than one sections (the translator can only deal with 9240# environments wholly contained with sections). 9241 9242# (Does a little more now ... the end of the preamble is now marked 9243# with an internally-generated command which causes all output 9244# erroneously generated from unrecognized commands in the preamble 9245# to vanish --- rst). 9246 9247sub remove_document_env { 9248# s/\\begin$match_br_rx[d]ocument$match_br_rx/\\latextohtmlditchpreceding /o; 9249 if (/\\begin\s*${match_br_rx}document$match_br_rx/) { 9250 s/\\begin\s*$match_br_rx[d]ocument$match_br_rx/\\latextohtmlditchpreceding / 9251 } 9252# s/\\end$match_br_rx[d]ocument$match_br_rx(.|\n)*//o; 9253 if (/\\end\s*${match_br_rx}document$match_br_rx/) { $_ = $` } 9254} 9255 9256# And here's the code to handle the marker ... 9257 9258sub do_cmd_latextohtmlditchpreceding { 9259 local($_) = @_; 9260 $ref_before = ''; 9261 $_; 9262} 9263 9264print "\n"; # flushes a cache? This helps, for some unknown reason!! 9265 9266sub do_AtBeginDocument{ 9267 local($_) = @_; 9268 eval $AtBeginDocument_hook; 9269 $_; 9270} 9271 9272sub cleanup { 9273 local($explicit) = @_; 9274 return unless $explicit || !$DEBUG; 9275 9276 if (opendir(DIR, '.')) { 9277 while (defined($_ = readdir(DIR))) { 9278 L2hos->Unlink($_) 9279 if /\.ppm$/ || /^${PREFIX}images\.dvi$/ || /^(TMP[-._]|$$\_(image)?)/; 9280 } 9281 closedir (DIR); 9282 } 9283 9284 L2hos->Unlink("WARNINGS") if ($explicit &&(-f "WARNINGS")); 9285 9286 if ($TMPDIR && opendir(DIR, $TMPDIR)) { 9287 local(@files) = grep(!/^\.\.?$/,readdir(DIR)); 9288 local($busy); 9289 foreach (@files) { 9290 $busy .= $_." " unless (L2hos->Unlink("$TMPDIR$dd$_")); 9291 } 9292 closedir (DIR); 9293 if ($busy) { 9294 print "\n\nFiles: $busy are still in use.\n\n" if ($DEBUG); 9295 } else { 9296 &write_warnings("\n\n Couldn't remove $TMPDIR : $!") 9297 unless (rmdir $TMPDIR); 9298 } 9299 } 9300 if (opendir(DIR, $TMP_)) { 9301 local(@files) = grep(!/^\.\.?$/,readdir(DIR)); 9302 $busy = ''; 9303 foreach (@files) { 9304 $busy .= "$_ " unless (L2hos->Unlink("$TMP_$dd$_")); 9305 } 9306 closedir (DIR); 9307 local($full_dir) = L2hos->Make_directory_absolute($TMP_); 9308 if ($busy) { 9309 print "\n\nFiles: $busy in $full_dir are still in use.\n\n" 9310 if ($DEBUG); 9311 } else { 9312 &write_warnings("\n\nCouldn't remove directory '$full_dir': $!") 9313 unless (rmdir $full_dir); 9314 } 9315 } 9316} 9317 9318sub handler { 9319 print "\nLaTeX2HTML shutting down.\n"; 9320 kill ('INT', $child_pid) if ($child_pid); 9321 &close_dbm_database; 9322 &cleanup(); 9323 exit(-1); 9324} 9325 9326# Given a filename or a directory it returns the file and the full pathname 9327# relative to the current directory. 9328sub get_full_path { 9329 local($file) = @_; 9330 local($path,$dir); 9331 if (-d $file) { # $file is a directory 9332 $path = L2hos->Make_directory_absolute($file); 9333 $file = ''; 9334 9335# JCL(jcl-dir) 9336 } elsif ($file =~ s|\Q$dd\E([^$dd$dd]*)$||o ) { 9337 $path = $file; 9338 $file = $1; 9339 $path = L2hos->Make_directory_absolute($path); 9340 9341#RRM: check within $TEXINPUTS directories 9342 } elsif (!($TEXINPUTS =~ /^\.$envkey$/)) { 9343 #check along directories in the $TEXINPUTS variable 9344 foreach $dir (split(/$envkey/,$TEXINPUTS)) { 9345 $dir =~ s/[$dd$dd]$//o; 9346 if (-f $dir.$dd.$file) { 9347 $path = L2hos->Make_directory_absolute($dir); 9348 last; 9349 } 9350 } 9351 } else { 9352 $path = L2hos->Cwd(); 9353 } 9354 ($path, $file); 9355} 9356 9357 9358# Given a directory name in either relative or absolute form, returns 9359# the absolute form. 9360# Note: The argument *must* be a directory name. 9361# The whole function has been moved to override.pm 9362 9363 9364 9365# Given a relative filename from the directory in which the original 9366# latex document lives, it tries to expand it to the full pathname. 9367sub fulltexpath { 9368 # Uses $texfilepath defined in sub driver 9369 local($file) = @_; 9370 $file =~ s/\s//g; 9371 $file = "$texfilepath$dd$file" 9372 unless (L2hos->is_absolute_path($file)); 9373 $file; 9374} 9375 9376#RRM Extended to allow customised filenames, set $CUSTOM_TITLES 9377# or long title from the section-name, set $LONG_TITLES 9378# 9379sub make_name { 9380 local($sec_name, $packed_curr_sec_id) = @_; 9381 local($title,$making_name,$saved) = ('',1,''); 9382 if ($LONG_TITLES) { 9383 $saved = $_; 9384 &process_command($sections_rx, $_) if /^$sections_rx/; 9385 $title = &make_long_title($TITLE) 9386 unless ((! $TITLE) || ($TITLE eq $default_title)); 9387 $_ = $saved; 9388 } elsif ($CUSTOM_TITLES) { 9389 $saved = $_; 9390 &process_command($sections_rx, $_) if /^$sections_rx/; 9391 $title = &custom_title_hook($TITLE) 9392 unless ((! $TITLE) || ($TITLE eq $default_title)); 9393 $_ = $saved; 9394 } 9395 if ($title) { 9396 #ensure no more than 32 characters, including .html extension 9397 $title =~ s/^(.{1,27}).*$/$1/; 9398 ++$OUT_NODE; 9399 join("", ${PREFIX}, $title, $EXTN); 9400 } else { 9401 # Remove 0's from the end of $packed_curr_sec_id 9402 $packed_curr_sec_id =~ s/(_0)*$//; 9403 $packed_curr_sec_id =~ s/^\d+$//o; # Top level file 9404 join("",($packed_curr_sec_id ? 9405 "${PREFIX}$NODE_NAME". ++$OUT_NODE : $sec_name), $EXTN); 9406 } 9407} 9408 9409#RRM: redefine this subroutine, to create customised file-names 9410# based upon the actual section title. 9411# The default is empty, so reverts to: node1, node2, ... 9412# 9413sub custom_title_hook { 9414 local($_)= @_; 9415 ""; 9416} 9417 9418 9419sub make_long_title { 9420 local($_)= @_; 9421 local($num_words) = $LONG_TITLES; 9422 #RRM: scan twice for short words, due to the $4 overlap 9423 # Cannot use \b , else words break at accented letters 9424 $_ =~ s/(^|\s)\s*($GENERIC_WORDS)(\'|(\s))/$4/ig; 9425 $_ =~ s/(^|\s)\s*($GENERIC_WORDS)(\'|(\s))/$4/ig; 9426 #remove leading numbering, unless that's all there is. 9427 local($sec_num); 9428 if (!(/^\d+(\.\d*)*\s*$/)&&(s/^\s*(\d+(\.\d*)*)\s*/$sec_num=$1;''/e)) 9429 { $num_words-- }; 9430 &remove_markers; s/<[^>]*>//g; #remove tags 9431 #revert entities, etc. to TeX-form... 9432 s/([\200-\377])/"\&#".ord($1).";"/eg; 9433 $_ = &revert_to_raw_tex($_); 9434 9435 # get $LONG_TITLES number of words from what remains 9436 $_ = &get_first_words($_, $num_words) if ($num_words); 9437 # ...and cleanup accents, spaces and punctuation 9438 $_ = join('', ($SHOW_SECTION_NUMBERS ? $sec_num : ''), $_); 9439 s/\\\W\{?|\}//g; s/\s/_/g; s/\W/_/g; s/__+/_/g; s/_+$//; 9440 $_; 9441} 9442 9443 9444sub make_first_key { 9445 local($_); 9446 $_ = ('0 ' x keys %section_commands); 9447 s/^0/$THIS_FILE/ if ($MULTIPLE_FILES); 9448 chop; 9449 $_; 9450} 9451 9452# This copies the preamble into the variable $preamble. 9453# It also sets the LaTeX font size, if $FONT_SIZE is set. 9454sub add_preamble_head { 9455 $preamble = join("\n", $preamble, @preamble); 9456 $preamble = &revert_to_raw_tex($preamble); 9457 $preamble = join ("\n", &revert_to_raw_tex(/$preamble_rx/o), 9458 $preamble); 9459 local($savedRS) = $/; undef $/; 9460 # MRO: replaced $* with /m 9461 $preamble =~ /(\\document(style|class))\s*(\[[^]]*\])?\s*\{/sm; 9462 local($before,$after) = ($`.$1, '{'.$'); 9463 $/ = $savedRS; 9464 local ($options) = $3; 9465 if ($FONT_SIZE) { 9466 $options =~ s/(1\dpt)\b//; 9467 $options =~ s/(\[|\])//g; 9468 $options = "[$FONT_SIZE".($options ? ",$options" : '').']'; 9469 $preamble = join('', $before, $options, $after ); 9470 &write_mydb_simple("preamble", $preamble); 9471 @preamble = split(/\n/, $preamble); 9472 $LATEX_FONT_SIZE = $FONT_SIZE; 9473 } 9474 if (($options =~ /(1\dpt)\b/)&&(!$LATEX_FONT_SIZE)) { 9475 $LATEX_FONT_SIZE = $1; 9476 } 9477 #RRM: need to know the font-size before the .aux file is read 9478 $LATEX_FONT_SIZE = '10pt' unless ($LATEX_FONT_SIZE); 9479} 9480 9481# It is necessary to filter some parts of the document back to raw 9482# tex before passing them to latex for processing. 9483sub revert_to_raw_tex { 9484 local($_) = @_; 9485 local($character_map) = ""; 9486 if ( $CHARSET && $HTML_VERSION ge "2.1" ) { 9487 $character_map = $CHARSET; 9488 $character_map =~ tr/-/_/; } 9489 while (s/$O\s*\d+\s*$C/\{/o) { s/$&/\}/;} 9490 while (s/$O\s*\d+\s*$C/\{/o) { s/$&/\}/;} #repeat this. 9491 # The same for processed markers ... 9492 while ( s/$OP\s*\d+\s*$CP/\{/o ) { s/$&/\}/; } 9493 while ( s/$OP\s*\d+\s*$CP/\{/o ) { s/$&/\}/;} #repeat this. 9494 9495 s/<BR>/\\\\/g; # restores the \\ from \parbox's 9496 9497 # revert any math-entities 9498 s/\&\w+#(\w+);/\\$1/g; 9499 s/\&limits;/\\limits/g; 9500 s/\\underscore/\\_/g; 9501 s/\\circflex/\\^/g; 9502 s/\\space/\\ /g; 9503 s/;SPMthinsp;/\\,/g; 9504 s/;SPMnegsp;/\\!/g; 9505 s/;SPMsp;/\\:/g; 9506 s/;SPMthicksp;/\\;/g; 9507 s/;SPMgg;/\\gg /g; 9508 s/;SPMll;/\\ll /g; 9509 s/;SPMquot;/"/g; 9510 9511 # revert any super/sub-scripts 9512 s/<SUP>/\^\{/g; 9513 s/<SUB>/\_\{/g; 9514 s/<\/SU(B|P)>/\}/g; 9515 9516 9517# #revert common character entities ?? 9518# s/\/\\/g; 9519 9520# # revert special marks 9521# s/$percent_mark/\\%/go; 9522## s/$comment_mark(\d+)\n/%$comments{$1}\n/go; 9523 local($tmp,$tmp2); 9524# s/$comment_mark(\d+)\n/$tmp=$verbatim{$1};chomp($tmp);$tmp."\n"/ego; 9525 s/$comment_mark(\d+)(\n|$|(\$))/$tmp=$verbatim{$1};$tmp2 = $3; 9526 ($tmp=~m!^\%!s ? '':'%').$tmp.(($tmp=~ m!\n\s*$!s)?'':"\n").$tmp2/sego; 9527 s/${verbatim_mark}tex2html_code(\d+)\#/$verbatim{$1}/go; 9528 s/^($file_mark|$endfile_mark).*\#\n//gmo; 9529 s/$comment_mark(\d*)\s*\n/%\n/go; 9530 s/$dol_mark/\$/go; 9531 s/$caption_mark//go; 9532 9533 # From &pre_process. 9534 # MRO: replaced $* with /m 9535 s/\\\\[ \t]*(\n)?/\\\\$1/gm; 9536 9537 # revert any array-cell delimiters 9538 s/$array_col_mark/\&/g; 9539 s/$array_row_mark/\\\\/g; 9540 s/$array_text_mark/\\text/g; 9541 s/$array_mbox_mark/\\mbox/g; 9542 9543 # Replace any verbatim and image markers ... 9544 &revert_verbatim_marks; 9545 &revert_verb_marks; 9546 9547 9548# &replace_image_marks; 9549 s/$image_mark\#([^\#]+)\#/&recover_image_code($1)/eg; 9550 9551 # remove artificial environments and commands 9552 9553 s/(\n*)\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_b(egin)?group\3\n?/ 9554 ($1? "\n":'')."\\".($6? $2:(($2 =~ m|end|)? 'e':'b'))."group\n" 9555 /gem; 9556 s/\\(begin|end)(\{|(($O|$OP)\d+($C|$CP|\})))(tex2html|verbatim)_code(\}|\3)\n?//gm; 9557 9558 #take care not to concatenate \<cmd> with following letters 9559 local($tmp); 9560 s/(\\\w+)?$tex2html_wrap_rx([^\\\n])?/$tmp=$2; 9561 ((($tmp eq 'end')&&($1)&&!($5)&&($6))? "$1 $6":"$1$5$6")/egs; 9562 undef $tmp; 9563 s/\s*\\newedcommand\s*{/"%\n\\providecommand{\\"/gem; 9564 s/\\newedcommand\s*{/\\providecommand{\\/gom; 9565# s/(\n*)\\renewedcommand{/($1? "\n":'')."\\renewcommand{\\"/geo; 9566 s/\s*\\providedcommand\s*{/"%\n\\providecommand{\\"/gem; 9567# s/\\providedcommand{/\\providecommand{\\/go; 9568 s/\\renewedenvironment\s*/\\renewenvironment/gom; 9569 s/\\newedboolean\s*{/\\newboolean{/gom; 9570 s/\\newedcounter\s*{/\\newcounter{/gom; 9571 s/\\newedtheorem\s*{/\\newtheorem{/gom; 9572 s/\\xystar/\\xy\*/gom; # the * has a special meaning in Xy-pic 9573 9574 #fix-up the star'd environment names 9575 s/(\\(begin|end)(($O|$OP)\d+($C|$CP))[^<]*)star\3/$1\*$3/gm; 9576 s/(\\(begin|end)\{[^\}]*)star\}/$1\*\}/gm; 9577 s/\\(begin|end)\{[^\}]*begin(group)\}/\\$1$2/gm; 9578 s/\\(b|e)(egin|end)\{[^\}]*b(group)\}/\\$1$3/gm; 9579 9580 s/(\\(\w+)TeX)/($language_translations{$2}? "\\selectlanguage{$2}": $1)/egom; 9581 9582 if ($PREPROCESS_IMAGES) { 9583 while (/$pre_processor_env_rx/m) { 9584 $done .= $`; $pre_env = $5; $which =$1; $_ = $'; 9585 if (($which =~ /begin/)&&($pre_env =~ /indica/)) { 9586 ($indic, $dum) = &get_next_optional_argument; 9587 $done .= "\#$indic"; 9588 } elsif (($which =~ /begin/)&&($pre_env =~ /itrans/)) { 9589 ($indic, $dum) = &get_next_optional_argument; 9590 $done .= "\#$indic"; 9591 } elsif (($which =~ /end/)&&($pre_env =~ /indica/)) { 9592 $done .= '\#NIL'; 9593 } elsif (($which =~ /end/)&&($pre_env =~ /itrans/)) { 9594 $done .= "\#end$indic"; 9595 } elsif ($which =~ /begin/) { 9596 $done .= (($which =~ /end/)? $end_preprocessor{$pre_env} 9597 : $begin_preprocessor{$pre_env} ) 9598 } 9599 $_ = $done . $_; 9600 } 9601 } 9602 s/\\ITRANSinfo\{(\w+)\}\{([^}]*)\}/\#$1=$2/gm if $itrans_loaded; 9603 9604 s/\n{3,}/\n\n/gm; # remove multiple (3+) new-lines 9605 s/^\n+$//gs; # ...especially if that is all there is! 9606 if ($PREAMBLE) { 9607 s/$comment_mark(\d+\n?)?//g; 9608# $preamble =~ s/\\par\n?/\n/g; 9609 s/\\par\b/\n/g; 9610 s/^\s*$//g; #remove blank lines in the preamble 9611 }; 9612 9613 s/($html_specials_inv_rx)/$html_specials_inv{$1}/geo; 9614 # revert entities to TeX code, except if in {rawhtml} environments 9615 if (!($env =~ /rawhtml/)) { 9616 s/$character_entity_rx/( $character_map ? 9617 eval "\$${character_map}_character_map_inv\{\"$1\"\}" : 9618 $iso_8859_1_character_map_inv{$1} || 9619 $iso_10646_character_map_inv{$1})/geo; 9620 s/$named_entity_rx/( $character_map ? 9621 eval "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$1'}}" : 9622 $iso_8859_1_character_map_inv{$iso_8859_1_character_map{$1}} || 9623 $iso_10646_character_map_inv{$iso_10646_character_map{$1}})/geo; 9624 9625 } else { 9626 #RRM: check for invalid named entities in {rawhtml} environments 9627 s/($named_entity_rx)/&write_warnings( 9628 "An unknown named entity ($1) appears in the source text.") unless ( 9629 $character_map && eval 9630 "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$2'}}"); 9631 ";SPM$2;"/ego; 9632 } 9633 9634 #RRM: check for numbered character entity out-of-range 9635 if ($HTML_VERSION < 4.0) { 9636 s/$character_entity_rx/&write_warnings( 9637 "An invalid character entity ($1) appears in the source text.") 9638 if ($2 > 255); 9639 $1/ego; } 9640 9641 #RRM: check for invalid named entities outside {rawhtml} environments 9642 # --- these should have been caught already, but check again 9643 s/$named_entity_rx/&write_warnings( 9644 "An unknown named entity ($1) appears in the source text.") unless ( 9645 $character_map && eval 9646 "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$1'}}"); 9647 $1/ego; 9648 9649 &revert_to_raw_tex_hook if (defined &revert_to_raw_tex_hook); 9650 $_; 9651} 9652 9653sub next_wrapper { 9654 local($dollar) = @_; 9655 local($_,$id); 9656 $wrap_toggle = (($wrap_toggle eq 'end') ? 'begin' : 'end'); 9657 $id = ++$global{'max_id'}; 9658 $_ = "\\$wrap_toggle$O$id$C"."tex2html_wrap$O$id$C"; 9659 $_ = (($wrap_toggle eq 'end') ? $dollar.$_ : $_.$dollar); 9660 $_; 9661} 9662 9663sub make_wrapper { 9664 &make_any_wrapper($_[0], '', "tex2html_wrap"); 9665} 9666 9667sub make_nowrapper { 9668 &make_any_wrapper($_[0], 1, "tex2html_nowrap"); 9669} 9670 9671sub make_inline_wrapper { 9672 &make_any_wrapper($_[0], '', "tex2html_wrap_inline"); 9673} 9674 9675sub make_deferred_wrapper { 9676 &make_any_wrapper($_[0], 1, "tex2html_deferred"); 9677} 9678 9679sub make_nomath_wrapper { 9680 &make_any_wrapper($_[0], '', "tex2html_nomath_inline"); 9681} 9682 9683sub make_any_wrapper { 9684 local($toggle,$break,$kind) = @_; 9685 local($max_id) = ++$global{'max_id'}; 9686 '\\'. (($toggle) ? 'begin' : 'end') 9687 . "$O$max_id$C"."$kind$O$max_id$C" 9688 . (($toggle || !$break) ? '' : ''); 9689} 9690 9691sub get_last_word { 9692 # Returns the last word in multi-line strings 9693 local($_) = @_; 9694 local ($word,$lastbit,$which); 9695#JCL(jcl-tcl) 9696# also remove anchors and other awkward HTML markup 9697# &extract_pure_text("strict"); 9698## $_ = &purify($_); ## No. what if it is a verbatim string or image? 9699# 9700# while (/\s(\S+)\s*$/g) { $word = $lastbit = $1;} 9701 9702 if (!$_ && (defined $keep)) { 9703 # inside mathematics ! 9704 $_ = $keep . $pre ; 9705 } 9706 if (!$_ && $ref_before) { $_ = $ref_before; } 9707 elsif (!$_) { 9708 # get it from last thing before the current environment 9709 $which = $#processedE; 9710 $_ = $processedE[$which]; 9711 } 9712 9713 while (/((($O|$OP)\d+($C|$CP))[.\n]*\2|\s(\S+))\s*$/g) 9714 { $word = $lastbit = $1 } 9715 if (($lastbit =~ s/\$\s*$//)||(defined $keep)) { 9716 local($br_idA) = ++$global{'max_id'}; 9717 local($br_idB) = ++$global{'max_id'}; 9718 $lastbit = join('', "\\begin $O$br_idA${C}tex2html_wrap_inline$O$br_idA$C\$" 9719 , $lastbit, "\$\\end $O$br_idB${C}tex2html_wrap_inline$O$br_idB$C"); 9720 $lastbit = &translate_environments($lastbit); 9721 $lastbit = &translate_commands($lastbit); 9722 return ($lastbit); 9723 } 9724 if ($lastbit =~ s/($O|$OP)\d+($C|$CP)//g) { return ($lastbit); } 9725 elsif ($lastbit eq '') { return ($_) } 9726 9727 local($pre_bit); 9728 if ($lastbit =~/>([^>]*)$/) { 9729 $word = $1; $pre_bit = $`.'>'; 9730 if ($pre_bit =~ /($verb_mark|$verbstar_mark)$/) { 9731 $word = $lastbit; 9732 } elsif ($pre_bit =~ /<\w+_mark>$/) { 9733 $word = $& . $word; 9734 } elsif (!($word)) { 9735 if ($lastbit =~ s/<([^\/][^>]*)>$//o) 9736 { $word=$1; $pre_bit = $`; } 9737 elsif ($lastbit =~ s/>([^<]*)<\/[^>]*>//o) 9738 { $word=$1; $pre_bit = $`.'>' } 9739 else { $word = ";SPMnbsp;"; } 9740 } 9741# if ($pre_bit =~ /<\w+_mark>$/) { $word = $& . $word } 9742 } else { $word = $lastbit }; 9743 $word; 9744} 9745 9746#JCL(jcl-tcl) 9747# changed completely 9748# 9749# We take the first real words specified by $min from the string. 9750# Allow for simple HTML constructs like <I>...</I> (but not <H*> 9751# or <P*> and the like), math, or images to remain in the result, 9752# not counting as words. 9753# Take care that eg. <I>...</I> grouping tags are not broken. 9754# This is achieved by lifting the markup, removing superfluous 9755# words, re-inserting the markup, and throw empty markup away. 9756# In later versions images could be modified such that they become 9757# thumbnail sized. 9758# 9759# rawhtml or verbatim environments might introduce lots of awkward 9760# stuff, but yet we leave the according tex2html markers in. 9761# 9762sub get_first_words { 9763 local($_, $min) = @_; 9764 local($words,$i); 9765 local($id,%markup); 9766 #no limit if $min is negative 9767 $min = 1000 if ($min < 0); 9768 9769 &remove_anchors; 9770 #strip unwanted HTML constructs 9771 s/<\/?(P|BR|H)[^>]*>/ /g; 9772 #remove leading white space and \001 characters 9773 s/^\s+|\001//g; 9774 #lift html markup, numbered for recovery 9775 s/(<[^>]*>(#[^#]*#)?)/$markup{++$id}=$1; "\000$id\000"/ge; 9776 9777 foreach (split /\s+|\-{3,}/) { 9778 # count words (incl. HTML markup as part of the word) 9779 ++$i; 9780# $words .= $_ . " " if (/\000/ || ($i <= $min)); 9781 $words .= $_ . " " if ($i <= $min); 9782 } 9783 $_ = $words; 9784 chop; 9785 9786 #re-insert markup 9787 s/\000(\d+)\000/$markup{$1}/g; 9788 # remove empty markup 9789 # it's normalized, because generated by LaTeX2HTML only 9790 s/<([A-Z]+)[^>]*>\s*<\/\1>\s*//g; 9791 $_; 9792} 9793 9794sub replace_word { 9795 # Replaces the LAST occurrence of $old with $new in $str; 9796 local($str, $old, $new) = @_; 9797 substr($str,rindex($str,$old),length($old)) = $new; 9798 $str; 9799} 9800 9801# Returns the recognised sectioning commands as a string of alternatives 9802# for use in regular expressions; 9803sub get_current_sections { 9804 local($_, $key); 9805 foreach $key (keys %section_commands) { 9806 if ($key =~ /star/) { 9807 $_ = $key . "|" . $_} 9808 else { 9809 $_ .= "$key" . '[*]?|'; 9810 } 9811 } 9812 chop; # Remove the last "|". 9813 $_; 9814} 9815 9816sub numerically { 9817 local(@x) = split(' ',$a); 9818 local(@y) = split(' ',$b); 9819 local($i, $result); 9820 for($i=0;$i<$#x;$i++) { 9821 last if ($result = ($x[$i] <=> $y[$i])); 9822 } 9823 $result 9824} 9825 9826# Assumes that the files to be sorted are of the form 9827# <NAME><NUMBER> 9828sub file_sort { 9829 local($i,$j) = ($a,$b); 9830 $i =~ s/^[^\d]*(\d+)$/$1/; 9831 $j =~ s/^[^\d]*(\d+)$/$1/; 9832 $i <=> $j 9833} 9834 9835# If a normalized command name exists, return it. 9836sub normalize { 9837 # MRO: modified to use $_[1] 9838 # local($cmd,*after) = @_; 9839 my $cmd =$_[0]; 9840 my $ncmd; 9841 # Escaped special LaTeX characters 9842 if ($cmd =~ /^($latex_specials_rx)/) { 9843# $cmd =~ s/&(.*)$/&$1/o; 9844 $cmd =~ s/&(.*)$/$ampersand_mark$1/o; 9845 $cmd =~ s/%/$percent_mark/o; 9846 $_[1] = join('', $cmd, $_[1]); 9847 $cmd = ""} 9848 elsif ($ncmd = $normalize{$cmd}) { 9849 $ncmd; 9850 } 9851 else { 9852 $cmd =~ s/[*]$/star/; 9853 $cmd =~ s/\@/_at_/g; 9854 $cmd; 9855 } 9856} 9857 9858sub normalize_sections { 9859 my $dummy = ''; 9860 # MRO: s/$sections_rx/'\\' . &normalize($1.$2,*after) . $4/ge; 9861 s/$sections_rx/'\\' . &normalize($1.$2,$dummy) . $4/ge; 9862} 9863 9864sub embed_image { 9865 my ($url,$name,$external,$altst,$thumbnail,$map,$align, 9866 $usemap,$exscale,$exstr) = @_; 9867 my $imgID = ''; 9868 my $urlimg = $url; 9869 my $ismap = $map ? " ISMAP" : ''; 9870 print "\nembedding $url for $name, with $altst\n" if ($VERBOSITY > 1); 9871 9872 if (! ($NO_IMAGES || $PS_IMAGES)) { 9873 # for over-scaled GIFs with pre-determined sizes # RRM 11-9-96 9874 my $size; 9875 if (($width{$name})&&(($exscale)||($EXTRA_IMAGE_SCALE))) { 9876 $exscale = $EXTRA_IMAGE_SCALE unless ($exscale); 9877 if ($name =~ /inline|indisplay|entity|equation|math|eqn|makeimage/){ 9878 ($size, $imgID) = &get_image_size($url, $exscale); 9879 } else { 9880 ($size, $imgID) = &get_image_size($url,''); 9881 } 9882 } else { 9883 ($size,$imgID) = &get_image_size($url,''); 9884 } 9885 $image_size{$url} = $size 9886 unless ((! $size) || ($size eq "WIDTH=\"0\" HEIGHT=\"0\"")); 9887 $url = &find_unique($url); 9888 } 9889 9890 $urlimg = $url; 9891 $urlimg =~ s/\.$IMAGE_TYPE$/.html/ if ($map); 9892 if ($exstr =~ s/align\s*=\s*(\"?)(\w+)\1($|\s|,)//io) { $align = $2; } 9893 my $usersize = ''; 9894 if ($exstr =~ s/width\s*=\s*(\"?)([^\s,]+)\1($|\s|,)//io) { 9895 my ($pxs,$len) = &convert_length($2); 9896 $usersize = " WIDTH=\"$pxs\""; 9897 } 9898 if ($exstr =~ s/height\s*=\s*(\"?)([^\s,]+)\1($|\s|,)//io) { 9899 my ($pxs,$len) = &convert_length($2); 9900 $usersize .= " HEIGHT=\"$pxs\""; 9901 } 9902 9903 my $border = ''; 9904 $border = "\" BORDER=\"0" 9905 unless (($HTML_VERSION < 2.2 )||($exstr =~ /BORDER/i)); 9906 9907 my $aalign; 9908 if (($name =~ /figure|table|displaymath\d+|eqnarraystar/)&&(!$align)) { 9909 } elsif ($name =~ /displaymath_/) { 9910 $aalign = "MIDDLE".$border; 9911 } elsif (($name =~ /(equation|eqnarray)($|\d)/)&&(!$align)) { 9912 if ($HTML_VERSION >= 3.2) { 9913 $aalign = ($EQN_TAGS eq "L") ? "RIGHT" : "LEFT"; 9914 } 9915 } elsif ($name =~ /inline|display|entity|xy|diagram/ && $depth{$name} != 0) { 9916 $aalign = "MIDDLE".$border; 9917 } elsif ($name =~ /inpar/m) { 9918 $aalign = "TOP".$border; 9919 } else { $aalign = "BOTTOM".$border } 9920 9921 $aalign = "\U$align" if $align; 9922 my $ausemp = $usemap ? "\UUSEMAP=$usemap" : ''; 9923 9924 #append any extra valid options 9925 $ismap .= &parse_keyvalues ($exstr, ("IMG")) if ($exstr); 9926 9927 $altst = '' if ($ismap =~ /(^|\s+)ALT\s*=/); 9928 if ($altst) { 9929 if ($altst =~ /\s*ALT="?([^\"]+)"?\s*/io) { $altst=$1 } 9930 $altst =~ s/[<>"&]/'&'.$html_special_entities{$&}.';'/eg; 9931 $altst = "\n ALT=\"$altst\""; 9932 } 9933 9934 my ($extern_image_mark,$imagesize); 9935 if ($thumbnail) { 9936 print "\nmaking thumbnail" if ($VERBOSITY > 1); 9937 if (($image_size{$thumbnail}) = &get_image_size($thumbnail,'')) { 9938 $thumbnail = &find_unique($thumbnail); 9939 $imagesize = " ".$image_size{$thumbnail}; 9940 if ($HTML_VERSION < 2.2 ) { 9941 # put the WIDTH/HEIGHT information into the ALT string 9942 # first removing the quotes 9943 my ($noquotes) = $imagesize; 9944 $noquotes =~ s/\"//g; 9945 $altst =~ s/"$/\% $noquotes "/m; 9946 $imagesize = ''; 9947 } 9948 $extern_image_mark = join('',"<IMG" 9949 , "\n$imagesize" 9950 , (($aalign) ? " ALIGN=\"$aalign\"" : '') 9951 , ("$aalign$imagesize" ? "\n" : '' ) 9952 , " SRC=\"$thumbnail\"$altst>"); 9953 } 9954 $extern_image_mark =~ s/\s?BORDER="?\d+"?// 9955 unless ($exstr =~ /BORDER/i); 9956 } else { 9957 # MRO: dubious (&extern_image_mark takes only one arg) 9958 $extern_image_mark = &extern_image_mark($IMAGE_TYPE,$altst); 9959 } 9960 9961 my ($anch1,$anch2) = ('',''); 9962 my $result; 9963 if ($external || $thumbnail || $EXTERNAL_IMAGES) { 9964 if ( $extern_image_mark ) { 9965 $result = &make_href_noexpand($urlimg, $name , $extern_image_mark); 9966 &save_image_map($url, $urlimg, $map, $name, $altst, $ausemp) if $map; 9967 } 9968 } else { 9969 if ($map) { 9970 $anch1 = "<A HREF=\"$map\">"; 9971 $anch2 = "</A>"; 9972 } 9973# if ($aalign eq "CENTER") { 9974# if ($HTML_VERSION eq "2.0") { 9975# $anch1 .= "\n<P ALIGN=\"CENTER\">"; 9976# $anch2 .= "</P>"; 9977# } else { 9978# $anch1 .= "\n<DIV ALIGN=\"CENTER\">"; 9979# $anch2 .= "</DIV>"; 9980# } 9981# } 9982 9983 $imagesize = $image_size{$url}; 9984 $imagesize = $usersize if (($usersize)&&($HTML_VERSION > 2.1 )); 9985 if ($HTML_VERSION < 2.2 ) { 9986 # put the WIDTH/HEIGHT information into the ALT string 9987 # first removing the quotes 9988 my ($noquotes) = $imagesize; 9989 $noquotes =~ s/\"//g; 9990 $altst =~ s/"$/\% $noquotes "/m; 9991 } 9992 9993 # include a stylesheet entry for each included image 9994 if ($USING_STYLES && $SCALABLE_IMAGES &&(!$imgID)) { 9995 if ($url =~ /($dd|^)([^$dd$dd]+)\.$IMAGE_TYPE$/) { 9996 my $img_name = $2; 9997 $imgID = $img_name . ($img_name =~ /img/ ? '' : $IMAGE_TYPE); 9998 $img_style{"$imgID"} = ' ' unless $img_style{"$imgID"}; 9999 $imgID = join('', ' CLASS="', $imgID, '"') if $imgID; 10000 } 10001 } 10002 10003 ### MEH Add width and height to IMG 10004 ### Patched by <hswan@perc.Arco.com>: Fixed \htmladdimg 10005 if ( $imagesize || $name eq "external image" || $NO_IMAGES || $PS_IMAGES) { 10006 $imagesize = '' if ($HTML_VERSION < 2.2 ); 10007 if ($border =~ s/^"//) { $border .= '"' }; 10008 $result = join('' 10009 , "<IMG$imgID" 10010 , "\n", ($imagesize ? " $imagesize" : '') 10011 , (($aalign)? " ALIGN=\"$aalign\"" : $border) 10012 , $ismap ); 10013 if ($ausemp) { $result .= " $ausemp" } 10014 $result .= "\n" unless (($result =~ /\n *$/m)|| !$imagesize); 10015 $result .= " SRC=\"$url\""; 10016 if ($altst) { $result .= $altst } 10017 $result .= ">"; 10018 } 10019 } 10020 join('',$anch1, $result, $anch2); 10021} 10022 10023# MRO: added PNG support 10024sub get_image_size { # clean 10025 my ($imagefile, $scale) = @_; 10026 10027 $scale = '' if ($scale == 1); 10028 my ($imgID,$size) = ('',''); 10029 if (open(IMAGE, "<$imagefile")) { 10030 my ($buffer,$magic,$dummy,$width,$height) = ('','','',0,0); 10031 binmode(IMAGE); # not harmful un UNIX 10032 if ($IMAGE_TYPE =~ /gif/) { 10033 read(IMAGE,$buffer,10); 10034 ($magic,$width,$height) = unpack('a6vv',$buffer); 10035 # is this image sane? 10036 unless($magic =~ /^GIF8[79]a$/ && ($width * $height) > 0) { 10037 $width = $height = 0; 10038 } 10039 } 10040 elsif ($IMAGE_TYPE =~ /png/) { 10041 read(IMAGE,$buffer,24); 10042 ($magic,$dummy,$width,$height) = unpack('a4a12NN',$buffer); 10043 unless($magic eq "\x89PNG" && ($width * $height) > 0) { 10044 $width = $height = 0; 10045 } 10046 } 10047 close(IMAGE); 10048 10049 # adjust for non-trivial $scale factor. 10050 my ($img_w,$img_h) = ($width,$height); 10051 if ($scale && ($width * $height) > 0) { 10052 $img_w = int($width / $scale + .5); 10053 $img_h = int($height / $scale + .5); 10054 } 10055 $size = qq{WIDTH="$img_w" HEIGHT="$img_h"}; 10056 10057 # allow height/width to be stored in the stylesheet 10058 my ($img_name,$imgID); 10059 if ($SCALABLE_IMAGES && $USING_STYLES) { 10060 if ($imagefile =~ /(^|[$dd$dd])([^$dd$dd]+)\.(\Q$IMAGE_TYPE\E|old)$/o) { 10061 $img_name = $2; 10062 $imgID = $img_name . ($img_name =~ /img/ ? '' : $IMAGE_TYPE); 10063 } 10064 if ($imgID) { 10065 $width = $width/$LATEX_FONT_SIZE/$MATH_SCALE_FACTOR; 10066 $height = 1.8 * $height/$LATEX_FONT_SIZE/$MATH_SCALE_FACTOR; 10067 # How wide is an em in the most likely browser font ? 10068 if ($scale) { 10069 # How high is an ex in the most likely browser font ? 10070 $width = $width/$scale; $height = $height/$scale; 10071 } 10072 $width = int(100*$width + .5)/100; 10073 $height = int(100*$height + .5)/100; 10074 $img_style{$imgID} = qq(width:${width}em ; height:${height}ex ); 10075 #join('','width:',$width,'em ; height:',$height,'ex '); 10076 $imgID = qq{ CLASS="$imgID"}; 10077 } 10078 } 10079 } 10080 ($size, $imgID); 10081} 10082 10083sub find_unique { # clean 10084 my ($image1) = @_; 10085 local($/) = undef; # slurp in complete files 10086 10087 my $imagedata; 10088 if(open(IMG1,"<$image1")) { 10089 binmode(IMG1); # needed with .png under DOS 10090 $imagedata = <IMG1>; 10091 close(IMG1); 10092 } else { 10093 print "\nError: Cannot read '$image1': $!\n" 10094 unless ($image1 =~ /^\s*$HTTP_start/i); 10095 return $image1; 10096 } 10097 10098 my ($image2,$result); 10099 foreach $image2 (keys(%image_size)) { 10100 if ( $image1 ne $image2 && 10101 $image_size{$image1} eq $image_size{$image2} ) { 10102 if(open(IMG2,$image2)) { 10103 binmode(IMG2); # needed with .png under DOS 10104 $result = ($imagedata eq <IMG2>); 10105 close(IMG2); 10106 } else { 10107 print "\nWarning: Cannot read '$image2': $!\n" 10108 unless ($image2 =~ /^\s*$HTTP_start/i); 10109 } 10110# 10111# If we've found a match, rename the new image to a temporary one. 10112# Then try to link the new name to the old image. 10113# If the link fails, restore the temporary image. 10114# 10115 if ( $result ) { 10116 my $tmp = "temporary.$IMAGE_TYPE"; 10117 L2hos->Unlink($tmp); 10118 L2hos->Rename($image1, $tmp); 10119 if (L2hos->Link($image2, $image1)) { 10120 L2hos->Unlink($tmp); 10121 } else { 10122 L2hos->Rename($tmp, $image1); 10123 } 10124 return $image1; 10125 } 10126 } 10127 } 10128 $image1; 10129} 10130 10131sub save_image_map { # clean 10132 my ($url, $urlimg, $map, $name, $altst, $ausemp) = @_; 10133 unless(open(IMAGE_MAP, ">$urlimg")) { 10134 print "\nError: Cannot write '$urlimg': $!\n"; 10135 return; 10136 } 10137 ### HWS Pass server map unchanged from user 10138 print IMAGE_MAP "<HTML>\n<BODY>\n<A HREF=\"$map\">\n"; 10139 print IMAGE_MAP "<IMG\n SRC=\"$url\" ISMAP $ausemp $altst> </A>"; 10140 print IMAGE_MAP "</BODY>\n</HTML>\n"; 10141 close IMAGE_MAP; 10142} 10143 10144# Subroutine used mainly to rename an old image file about to recycled. 10145# But for active image maps, we must edit the auxiliary HTML file to point 10146# to the newly renames image. 10147sub rename_html { 10148 local ($from, $to) = @_; 10149 local ($from_prefix, $to_prefix, $suffix); 10150 ($from_prefix, $suffix) = split(/\./, $from); 10151 ($to_prefix, $suffix) = split(/\./, $to); 10152 if ($EXTN =~ /$suffix$/) { 10153 if (open(FROM, "<$from") && open(HTMP, ">HTML_tmp")) { 10154 while (<FROM>) { 10155 s/$from_prefix\.$IMAGE_TYPE/$to_prefix.$IMAGE_TYPE/g; 10156 print HTMP; 10157 } 10158 close (FROM); 10159 close (HTMP); 10160 L2hos->Rename ("HTML_tmp", $to); 10161 L2hos->Unlink($from) unless ($from eq $to); 10162 } 10163 else { 10164 &write_warnings("File $from is missing!\n"); 10165 } 10166 } 10167 L2hos->Rename("$from_prefix.old", "$to_prefix.$IMAGE_TYPE"); 10168 $to; 10169} 10170 10171sub save_captions_in_file { 10172 local ($type, $_) = @_; 10173 if ($_) { 10174 s/^\n//om; 10175 &replace_markers; 10176 &add_dir_to_href if ($DESTDIR); 10177 if(open(CAPTIONS, ">${PREFIX}$type.pl")) { 10178 print CAPTIONS $_; 10179 close (CAPTIONS); 10180 } else { 10181 print "\nError: Cannot write '${PREFIX}$type.pl': $!\n"; 10182 } 10183 } 10184} 10185 10186sub add_dir_to_href { 10187 $_ =~ s/'/\\'/g; 10188 $_ =~ s/(<LI><A )(NAME\=\"tex2html\d+\")?\s*(HREF=\")/$1$3\'.\$dir.\'/og; 10189 $_ = join('', "\'", $_, "\'\n"); 10190} 10191 10192sub save_array_in_file { 10193 local ($type, $array_name, $append, %array) = @_; 10194 local ($uutxt,$file,$prefix,$suffix,$done_file,$depth,$title); 10195 $prefix = $suffix = ""; 10196 my $filespec = ($append ? '>>' : '>') . "${PREFIX}$type.pl"; 10197 $prefix = q("$URL/" . ) 10198 if ($type eq "labels") && !($array_name eq "external\_latex\_labels"); 10199 $suffix = " unless (\$$array_name\{\$key\})" 10200 if (($type =~ /(sections|contents)/)||($array_name eq "printable\_key")); 10201 if ((%array)||($type eq "labels")) { 10202 print "\nSAVE_ARRAY:$array_name in FILE: ${PREFIX}$type.pl" 10203 if ($VERBOSITY > 1); 10204 unless(open(FILE,$filespec)) { 10205 print "\nError: Cannot write '${PREFIX}$type.pl': $!\n"; 10206 return; 10207 } 10208 if (($array_name eq "sub\_index") || ($array_name eq "printable\_key")) { 10209 print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n"; 10210 print FILE "# Printable index-keys from $array_name array.\n\n"; 10211 } elsif ($array_name eq "index\_labels") { 10212 print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n"; 10213 print FILE "# labels from $array_name array.\n\n"; 10214 } elsif ($array_name eq "index\_segment") { 10215 print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n"; 10216 print FILE "# segment identifier from $array_name array.\n\n"; 10217 } elsif ($array_name eq "external\_latex\_labels") { 10218 print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n"; 10219 print FILE "# labels from $array_name array.\n\n"; 10220 } else { 10221 print FILE "# LaTeX2HTML $TEX2HTMLVERSION\n"; 10222 print FILE "# Associate $type original text with physical files.\n\n"; 10223 } 10224 while (($uutxt,$file) = each %array) { 10225 $uutxt =~ s|/|\\/|g; 10226 $uutxt =~ s|\\\\/|\\/|g; 10227 10228 if (!($array_name =~/images/)&&($file =~ /</)) { 10229 do { local $_ = $file; 10230 &replace_markers; 10231 $file = $_; undef $_; 10232 $file =~ s/(\G|[^q])[\\\|]\|/$1\\Vert/sg; 10233 $file =~ s/(\G|[^q])\|/$1\\vert/sg; 10234 }; 10235 } 10236 10237 local ($nosave); 10238 if ($MULTIPLE_FILES && $ROOTED && 10239 $type =~ /(sections|contents)/) { 10240 #RRM: save from $THIS_FILE only 10241 if ( $uutxt =~ /^$THIS_FILE /) { 10242 #RRM: save from $THIS_FILE only 10243 $nosave = '' 10244 } else { $nosave = 1 } 10245 } else { 10246 #RRM: suppress info from other segments 10247 $nosave = $noresave{$uutxt}; 10248 } 10249 10250 if (!$nosave && ($file ne '')) { 10251 print FILE "\n\$key = q/$uutxt/;\n"; 10252 10253 $file =~ s/\|/\\\|/g; # RRM: escape any occurrences of | 10254 $file =~ s/\\\\\|/\\\|/g; # unless already escaped as \| 10255 $file =~ s|\\\\|\\\\\\\\|g; 10256 $file =~ s/(SRC=")($HTTP_start)?/$1.($2 ? '' :"|.\"\$dir\".q|").$2/seg; 10257# 10258# 10259# added code for $dir with segmented docs; RRM 15/3/96 10260# 10261 if ($type eq "contents") { 10262 ($depth, $done_file) = split($delim, $file, 2 ); 10263 next if ($depth > $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 10264 print FILE 10265 "\$$array_name\{\$key\} = '$depth$delim'.\"\$dir\".q|$done_file|$suffix; \n"; 10266 10267 } elsif ($type eq "sections") { 10268 ($depth, $done_file) = split($delim, $file, 2 ); 10269 next if ($depth > $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 10270 print FILE 10271 "\$$array_name\{\$key\} = '$depth$delim'.\"\$dir\".q|$done_file|$suffix; \n"; 10272 10273 } elsif ($type eq "internals") { 10274 print FILE 10275 "\$$array_name\{\$key\} = \"\$dir\".q|$file|$suffix; \n"; 10276 10277 } elsif ($array_name eq "sub_index") { 10278 print FILE 10279 "\$$array_name\{\$key\} .= q|$file|$suffix; \n"; 10280 10281 } elsif ($array_name eq "index") { 10282 local($tmp_file) = ''; 10283 ($depth, $done_file) = split('HREF=\"', $file, 2 ); 10284 if ($done_file) { 10285 while ($done_file) { 10286 $depth =~ s/\s*$/ / if ($depth); 10287 $tmp_file .= "q|${depth}HREF=\"|.\"\$dir\"."; 10288 ($depth, $done_file) = split('HREF=\"', $done_file, 2 ); 10289 } 10290 print FILE 10291 "\$$array_name\{\$key\} .= ${tmp_file}q|$depth|$suffix; \n"; 10292 10293 } else { 10294 print FILE 10295 "\$$array_name\{\$key\} .= q|$file|$suffix; \n"; 10296 } 10297 } elsif ($array_name eq "printable_key") { 10298 print FILE 10299 "\$$array_name\{\$key\} = q|$file|$suffix; \n"; 10300 10301 } else { 10302 print FILE 10303 "\$$array_name\{\$key\} = ${prefix}q|$file|$suffix; \n"; 10304 } 10305 10306 if ($type =~ /(figure|table|images)/) {} else { 10307 print FILE "\$noresave\{\$key\} = \"\$nosave\";\n"; 10308 } 10309 10310 if ($type eq "sections") { 10311 ($depth, $done_file, $title) = split($delim, $file); 10312 print FILE "\$done\{\"\$\{dir\}$done_file\"\} = 1;\n"; 10313 } 10314 } 10315 } 10316 print FILE "\n1;\n\n" unless ( $array_name =~ /index/ ); 10317 close (FILE); 10318 } else { 10319 print "\nSAVE_FILE:$array_name: ${PREFIX}$type.pl EMPTY " if ($VERBOSITY > 1); 10320 } 10321} 10322 10323# returns true if $AUTO_NAVIGATION is on and there are more words in $_ 10324# than $WORDS_IN_PAGE 10325sub auto_navigation { 10326 # Uses $_; 10327 local(@tmp) = split(/\W*\s+\W*/, $_); 10328 ($AUTO_NAVIGATION && ( (scalar @tmp) > $WORDS_IN_PAGE)); 10329} 10330 10331# Returns true if $f1 is newer than $f2 10332sub newer { 10333 ($f1,$f2) = @_; 10334 local(@f1s) = stat($f1); 10335 local(@f2s) = stat($f2); 10336 ($f1s[9] > $f2s[9]); 10337}; 10338 10339sub iso_map { 10340 local($char, $kind, $quiet) = @_; 10341 my($character_map,$enc); 10342 local ($this); 10343 10344 if ( $CHARSET && $HTML_VERSION ge "2.1" ) { 10345 # see if it is a character in the charset 10346 $character_map = ((($charset =~ /utf/)&&!$NO_UTF)? 10347 'iso_10646' : $CHARSET ); 10348 $character_map =~ tr/-/_/; 10349 eval "\$enc = \$${character_map}_character_map\{\"$char$kind\"\}"; 10350 print "\n no support for $CHARSET: $@ " if ($@); 10351 } 10352 if ($USE_ENTITY_NAMES && $enc) { return(";SPM$char$kind;") } 10353 10354 if ($enc) { 10355 $enc =~ /^\&\#(\d{3});$/; 10356 # maybe convert it to an 8-bit character 10357 if ($NO_UTF && !$USE_UTF && ($1<=255)) { $enc = chr($1) } 10358# elsif (!$USE_UTF &&($1>127)&&($1<160)) { $enc = chr($1) } 10359 elsif ($character_map !~ /^iso_(8859_1|10646)/) { 10360 # get its latin1 or unicode entity encoding 10361 $enc = $iso_8859_1_character_map{"$char$kind"} 10362 ||$iso_8859_1A_character_map{"$char$kind"} 10363 ||$iso_10646_character_map{"$char$kind"} 10364 } 10365 } else { 10366 # get its latin1 or unicode entity encoding, if available 10367 $enc = $iso_8859_1_character_map{"$char$kind"} 10368 ||$iso_8859_1A_character_map{"$char$kind"} 10369 ||$iso_10646_character_map{"$char$kind"}; 10370 } 10371 10372 if ($enc) { 10373 $ISOLATIN_CHARS = 1; $enc; 10374 } elsif (!$image_made{"$char$kind"}) { 10375 print "\ncouldn't convert character $char$kind into available encodings" 10376 if (!quiet &&($VERBOSITY > 1)); 10377 &write_warnings( 10378 "couldn't convert character $char$kind into available encodings" 10379 . ($ACCENT_IMAGES ? ', using image' : '')) unless ($quiet); 10380 $image_made{"$char$kind"} = 1; 10381 ''; 10382 } else {''} 10383} 10384 10385sub titles_language { 10386 local($_) = @_; 10387 local($lang) = $_ . "_titles"; 10388 if (defined(&$lang)) { &$lang } 10389 else { 10390 &english_titles; 10391 &write_warnings( 10392 "\nThere is currently no support for the $tmp language." . 10393 "\nSee the file $CONFIG_FILE for examples on how to add it\n\n"); 10394 } 10395} 10396 10397sub translate_titles { 10398 $toc_title = &translate_commands($toc_title) if ($toc_title =~ /\\/); 10399 $lof_title = &translate_commands($lof_title) if ($lof_title =~ /\\/); 10400 $lot_title = &translate_commands($lot_title) if ($lot_title =~ /\\/); 10401 $idx_title = &translate_commands($idx_title) if ($idx_title =~ /\\/); 10402 $ref_title = &translate_commands($ref_title) if ($ref_title =~ /\\/); 10403 $bib_title = &translate_commands($bib_title) if ($bib_title =~ /\\/); 10404 $abs_title = &translate_commands($abs_title) if ($abs_title =~ /\\/); 10405 $app_title = &translate_commands($app_title) if ($app_title =~ /\\/); 10406 $pre_title = &translate_commands($pre_title) if ($pre_title =~ /\\/); 10407 $foot_title = &translate_commands($foot_title) if ($foot_title =~ /\\/); 10408 $fig_name = &translate_commands($fig_name) if ($fig_name =~ /\\/); 10409 $tab_name = &translate_commands($tab_name) if ($tab_name =~ /\\/); 10410 $prf_name = &translate_commands($prf_name) if ($prf_name =~ /\\/); 10411 $page_name = &translate_commands($page_name) if ($page_name =~ /\\/); 10412 $child_name = &translate_commands($child_name) if ($child_name =~ /\\/); 10413 $info_title = &translate_commands($info_title) if ($info_title =~ /\\/); 10414 $part_name = &translate_commands($part_name) if ($part_name =~ /\\/); 10415 $chapter_name = &translate_commands($chapter_name) 10416 if ($chapter_name =~ /\\/); 10417 $section_name = &translate_commands($section_name) 10418 if ($section_name =~ /\\/); 10419 $subsection_name = &translate_commands($subsection_name) 10420 if ($subsection_name =~ /\\/); 10421 $subsubsection_name = &translate_commands($subsubsection_name) 10422 if ($subsubsection_name =~ /\\/); 10423 $paragraph_name = &translate_commands($paragraph_name) 10424 if ($paragraph_name =~ /\\/); 10425 $see_name = &translate_commands($see_name) if ($see_name =~ /\\/); 10426 $also_name = &translate_commands($also_name) if ($also_name =~ /\\/); 10427 $next_name = &translate_commands($next_name) if ($next_name =~ /\\/); 10428 $prev_name = &translate_commands($prev_name) if ($prev_name =~ /\\/); 10429 $up_name = &translate_commands($up_name) if ($up_name =~ /\\/); 10430 $group_name = &translate_commands($group_name) if ($group_name =~ /\\/); 10431 $encl_name = &translate_commands($encl_name) if ($encl_name =~ /\\/); 10432 $headto_name = &translate_commands($headto_name) if ($headto_name =~ /\\/); 10433 $cc_name = &translate_commands($cc_name) if ($cc_name =~ /\\/); 10434 $default_title = &translate_commands($default_title) 10435 if ($default_title =~ /\\/); 10436} 10437####################### Code Generation Subroutines ############################ 10438# This takes a string of commands followed by optional or compulsory 10439# argument markers and generates a subroutine for each command that will 10440# ignore the command and its arguments. 10441# The commands are separated by newlines and have the format: 10442## <cmd_name>#{}# []# {}# [] etc. 10443# {} marks a compulsory argument and [] an optional one. 10444sub ignore_commands { 10445 local($_) = @_; 10446 foreach (/.*\n?/g) { 10447 s/\n//g; 10448 # For each line 10449 local($cmd, @args) = split('\s*#\s*',$_); 10450 next unless $cmd; 10451 $cmd =~ s/ //; 10452 ++$ignore{$cmd}; 10453 local ($body, $code, $thisone) = ("", ""); 10454 10455 # alter the pattern here to debug particular commands 10456 $thisone = 1 if ($cmd =~ /let/); 10457 10458 if (@args) { 10459 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 10460 # Replace the argument markers with appropriate patterns 10461 foreach $arg (@args) { 10462 print "\nARG: $arg" if ($thisone); 10463 if ($arg =~ /\{\}/) { 10464 $body .= 'local($cmd) = '."\"$cmd\"".";\n"; 10465 $body .= '$args .= &missing_braces'."\n ".'unless ('; 10466 $body .= '(s/$next_pair_pr_rx/$args .= $2;\'\'/eo)'."\n"; 10467 $body .= ' ||(s/$next_pair_rx/$args .= $2;\'\'/eo));'."\n"; 10468 print "\nAFTER:$'" if (($thisone)&&($')); 10469 $body .= $' if ($'); 10470 } elsif ($arg =~ /\[\]/) { 10471 $body .= '($dummy, $pat) = &get_next_optional_argument;' 10472 . '$args .= $pat;'."\n"; 10473 print "\nAFTER:$'" if (($thisone)&&($')); 10474 $body .= $' if ($'); 10475 } elsif ($arg =~ /^\s*\\/) { 10476 $body .= '($dummy, $pat) = &get_next_tex_cmd;' 10477 . '$args .= $pat;'."\n"; 10478 print "\nAFTER:$'" if (($thisone)&&($')); 10479 $body .= $' if ($'); 10480 } elsif ($arg =~ /<<\s*([^>]*)[\b\s]*>>/) { 10481 local($endcmd, $after) = ($1,$'); 10482 $after =~ s/(^\s*|\s*$)//g; 10483 $endcmd = &escape_rx_chars($endcmd); 10484 $body .= 'if (/'.$endcmd.'/o) { $args .= $`; $_ = $\' };'."\n"; 10485 print "\nAFTER:$after" if (($thisone)&&($after)); 10486 $body .= "$after" if ($after); 10487 } else { 10488 print "\nAFTER:$'" if (($thisone)&&($arg)); 10489 $body .= $arg ; 10490 } 10491 } 10492 # Generate a new subroutine 10493# $code = "sub do_cmd_$cmd {\n".'local($_) = @_;'. join('',@args) .'$_}'; 10494 $code = "sub do_cmd_$cmd {\n" 10495 . 'local($_,$ot) = @_; ' 10496 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R; ' 10497 . 'local($args); ' 10498 . "\n" . $body . (($body)? ";\n" : '') 10499 . (($thisone)? "print \"\\n$cmd:\".\$args.\"\\n\";\n" : '') 10500 . (($arg)? $arg : '$_') . "}"; 10501 print STDOUT "\n$code\n" if ($thisone); # for error-checking 10502 eval ($code); # unless ($thisone); 10503 print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@); 10504 } else { 10505 $code = "sub do_cmd_$cmd {\n".'$_[0]}'; 10506 print "\n$code\n" if ($thisone); # for error-checking 10507 eval ($code); # unless ($thisone); 10508 print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@); 10509 } 10510 } 10511} 10512 10513 10514sub ignore_numeric_argument { 10515 # Chop this off 10516 #RRM: 2001/11/8: beware of taking too much, when <num> <num> 10517 local($num) = '(^|width|height|plus|minus)\s*[+-]?[\d\.]+(cm|em|ex|in|pc|pt|mm)?\s*'; 10518 do { s/^\s*=?\s*//so; s/^($num)*//so } unless (/^(\s*\<\<\d+\>\>|$)/); 10519} 10520 10521sub get_numeric_argument { 10522 my ($num_rx,$num) = ('',''); 10523 # Collect the numeric part 10524 #RRM: 2001/11/8: beware of taking too much, when <num> <num> 10525 $num_rx = '(^|width|height|plus|minus)\s*[+-]?[\d\.]+(cm|em|ex|in|pc|pt|mm)?\s*'; 10526 do { s/^\s*=?\s*//so; s/($num_rx)*/$num=$&;''/soe } unless (/^(\s*\<\<\d+\>\>|$)/); 10527 $num; 10528} 10529 10530sub process_in_latex_helper { 10531 local($ctr,$val,$cmd) = @_; 10532 ($ASCII_MODE ? "[$cmd]" : 10533 &process_in_latex("\\setcounter{$ctr}{$val}\\$cmd")) 10534} 10535 10536sub do_cmd_catcode { 10537 local($_) = @_; 10538 s/^\s*[^=]+(=?\s*\d+\s|\\active)\s?//; 10539 $_; 10540} 10541 10542sub do_cmd_string { 10543 local($_) = @_; 10544 local($tok); 10545 s/^\s*(\\([a-zA-Z]+|.)|[&;]\w+;(#\w+;)?|.)/$tok=$1;''/e; 10546 if ($2) {$tok = "\\$2"}; 10547 "$tok".$_ 10548} 10549 10550sub do_cmd_boldmath { 10551 local($_) = @_; 10552 $BOLD_MATH = 1; 10553 $_; 10554} 10555 10556sub do_cmd_unboldmath { 10557 local($_) = @_; 10558 $BOLD_MATH = 0; 10559 $_; 10560} 10561 10562sub do_cmd_lq { 10563 local($_) = @_ ; 10564 local($lquote); 10565 # check for double quotes 10566 if (s/^\s*\\lq(\b|$|[^A-Za-z])/$1/) { 10567 $lquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? '``' 10568 : &do_leftquotes($_)); 10569 } else { 10570 $lquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? '`' 10571 : &do_leftquote($_)); 10572 } 10573 $lquote . $_; 10574} 10575 10576sub do_leftquote { 10577 # MRO: use $_[0] : local(*_) = @_; 10578 local($quote,$lquo) = ('',($HTML_VERSION<5)? '‘' : ';SPMlsquo;'); 10579 # select whole quotation, if \lq matches \rq 10580 if ($_[0] =~ /^(.*)((\\rq\\rq|'')*)(\\rq)/) { 10581 $quote = $1.$2; $_[0] = $'; 10582 local($rquo) = &do_rightquote(); 10583 &process_quote($lquo,$quote,$rquo); 10584 } else { $lquo; } 10585} 10586 10587sub do_leftquotes { 10588 # MRO: use $_[0] : local(*_) = @_; 10589 local($quote,$lquo) = ('',($HTML_VERSION<5)? '“' : ';SPMldquo;'); 10590 # select whole quotation, if \lq\lq matches \rq\rq or '' 10591 if ($_[0] =~ /^(.*)(\\rq\\rq|'')/) { 10592 $quote = $1; $_[0] = $'; 10593 local($rquo) = &do_rightquotes(); 10594 &process_quote($lquo,$quote,$rquo); 10595 } else { $lquo; } 10596} 10597 10598# RRM: By default this just concatenates the strings; e.g. ` <quote> ' 10599# This can be overridden in a html-version file 10600sub process_quote { join ('', @_) } 10601 10602sub do_cmd_rq { 10603 local($_) = @_ ; 10604 local($rquote); 10605 if ($_ =~ s/^\s*\\rq\b//) { 10606 $rquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? "''" 10607 : &do_rightquotes()); 10608 } else { 10609 $rquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? "'" 10610 : &do_rightquote()); 10611 } 10612 $rquote . $_; 10613} 10614 10615sub do_rightquote { (($HTML_VERSION < 5)? '’' : ';SPMrsquo;') } 10616sub do_rightquotes { (($HTML_VERSION < 5)? '”' : ';SPMrdquo;') } 10617 10618sub do_cmd_parbox { 10619 local($_) = @_; 10620 local($args, $contents, $dum, $pat); 10621 ($dum,$pat) = &get_next_optional_argument; # discard this 10622 ($dum,$pat) = &get_next_optional_argument; # discard this 10623 ($dum,$pat) = &get_next_optional_argument; # discard this 10624 $args .= $pat if ($pat); 10625 $pat = &missing_braces unless ( 10626 (s/$next_pair_pr_rx/$pat=$2;''/eom) 10627 ||(s/$next_pair_rx/$pat=$2;''/eom)); 10628 $args .= "{".$`.$pat."}"; 10629 $contents = &missing_braces unless ( 10630 (s/$next_pair_pr_rx/$contents=$2;''/eom) 10631 ||(s/$next_pair_rx/$contents=$2;''/eom)); 10632 $args .= "{".$`.$contents."}"; 10633 if ($NO_PARBOX_IMAGES) { 10634 $contents = join ('', &do_cmd_par(), $contents, '</P>' ); 10635 } else { 10636 $contents = &process_math_in_latex('','text',0,"\\parbox$args") 10637 if ($contents); 10638 } 10639 $contents . $_; 10640} 10641 10642 10643sub do_cmd_mbox { 10644 local($_) = @_; 10645 local($text,$after)=('',''); 10646 $text = &missing_braces unless ( 10647 (s/$next_pair_pr_rx/$text = $2;''/eo) 10648 ||(s/$next_pair_rx/$text = $2;''/eo)); 10649 $after = $_; 10650 10651 # incomplete macro replacement 10652 if ($text =~ /(^|[^\\<])#\d/) { return($after) } 10653 10654 if ($text =~ /(tex2html_wrap_inline|\$$OP(\d+)$CP$OP\2$CP\$|\$$O(\d+)$C$O\2$C\$)/) { 10655 if ($text =~ 10656 /$image_mark#([^#]+)#([\.,;:\)\]])?(\001)?([ \t]*\n?)(\001)?/) { 10657 local($mbefore, $mtext, $mafter) = ($`, $&, $'); 10658 $mbefore = &translate_commands($mbefore) if ($mbefore =~ /\\/); 10659 $mafter = &translate_commands($mafter) if ($mafter =~ /\\/); 10660 join('', $mbefore, $mtext, $mafter, $after); 10661 } else { 10662 join ('', &process_math_in_latex('','','',"\\hbox{$text}"), $after ) 10663 } 10664 } else { 10665 $text = &translate_environments($text); 10666 $text = &translate_commands($text); 10667 join('', $text, $after); 10668 } 10669} 10670 10671 10672 10673# *Generates* subroutines to handle each of the declarations 10674# like \em, \quote etc., in case they appear with the begin-end 10675# syntax. 10676sub generate_declaration_subs { 10677 local($key, $val, $pre, $post, $code ); 10678 print "\n *** processing declarations ***\n"; 10679 while ( ($key, $val) = each %declarations) { 10680 if ($val) { 10681 ($pre,$post) = ('',''); 10682 $val =~ m|</.*$|; 10683 do {$pre = $`; $post = $& } unless ($` =~ /^<>/); 10684 $pre =~ s/"/\\"/g; $post =~ s/"/\\"/g; 10685 $code = "sub do_env_$key {" 10686# . 'local($_) = @_;' . "\n" 10687# . 'push(@$open_tags_R, $key);'. "\n" 10688# . '$_ = &translate_environments($_);'. "\n" 10689# . '$_ = &translate_commands($_);'. "\n" 10690# . "join('',\"$pre\",\"\\n\"," .'$_' .",\"$post\");\n};"; 10691 . '&declared_env('.$key.',@_)};'; 10692 eval $code; 10693 if ($@) {print "\n *** $key ". $@ }; 10694 } 10695 } 10696} 10697 10698# *Generates* subroutines to handle each of the sectioning commands. 10699sub generate_sectioning_subs { 10700 local($key, $val, $cmd, $body); 10701 while ( ($key, $val) = each %standard_section_headings) { 10702 $numbered_section{$key} = 0; 10703 eval "sub do_cmd_$key {" 10704 . 'local($after,$ot) = @_;' 10705 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;' 10706 . '&reset_dependents('. $key . ');' 10707 . '&do_cmd_section_helper('.$val.','.$key.');}'; 10708 print STDERR "\n*** sub do_cmd_$key failed:\n$@\n" if ($@); 10709 # Now define the *-form of the same commands. The difference is that the 10710 # $key is not passed as an argument. 10711 eval "sub do_cmd_$key" . "star {" 10712 . 'local($after,$ot) = @_;' 10713 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;' 10714 . '&do_cmd_section_helper(' . $val . ');}'; 10715 print STDERR "\n*** sub do_cmd_${key}star failed:\n$@\n" if ($@); 10716 # Now define the macro \the$key 10717 &process_commands_wrap_deferred("the$key \# {}\n"); 10718### local($_) = "<<1>>$key<<1>>"; 10719 $body = "<<1>>$key<<1>>"; 10720 &make_unique($body); 10721 $cmd = "the$key"; 10722 eval "sub do_cmd_$cmd {" 10723 . 'local($after,$ot) = @_;' 10724 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;' 10725 . '&do_cmd_arabic(' . "\"$body\"" . ").\$after;};"; 10726 print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@); 10727 $raw_arg_cmds{$cmd} = 1; 10728 } 10729 &addto_dependents('chapter','section'); 10730 &addto_dependents('section','subsection'); 10731 &addto_dependents('subsection','subsubsection'); 10732 &addto_dependents('subsubsection','paragraph'); 10733 &addto_dependents('paragraph','subparagraph'); 10734} 10735 10736sub addto_dependents { 10737 local($ctr, $dep) = @_; 10738 local($tmp, $depends); 10739 if ($depends = $depends_on{$dep}) { 10740 &remove_dependency($depends, $dep) } 10741 $depends_on{$dep} = $ctr; 10742 10743 $tmp = $dependent{$ctr}; 10744 if ($tmp) { 10745 $dependent{$ctr} = join($delim, $tmp, $dep); 10746 } else { $dependent{$ctr} = $dep } 10747} 10748 10749sub remove_dependency { 10750 local($ctr, $dep) = @_; 10751 local(@tmp, $tmp, $dtmp); 10752 print "\nremoving dependency of counter {$dep} from {$ctr}\n"; 10753 foreach $dtmp (split($delim, $dependent{$ctr})) { 10754 push(@tmp, $dtmp) unless ($dtmp =~ /$dep/); 10755 } 10756 $dependent{$ctr} = join($delim, @tmp); 10757} 10758 10759 10760# Uses $after which is defined in the caller (the caller is a generated subroutine) 10761# Also uses @curr_sec_id 10762# 10763#JCL(jcl-tcl) (changed almost everything) 10764# 10765sub do_cmd_section_helper { 10766 local($H,$key) = @_; 10767 local($section_number, $titletext, $title_key, @tmp, $align, $dummy); 10768 local($anchors,$pre,$run_title,$_) = ('', "\n", '', $after); 10769 local($open_tags_R) = []; 10770 10771 # if we have a $key the current section is not of the *-form, so we need 10772 # to update the counters. 10773 &do_cmd_stepcounter("${O}0$C$key${O}0$C") 10774# if ($key && !$making_name); 10775# if ($key && !($unnumbered_section_commands{$key}) && !$making_name); 10776 if ($key && !($unnumbered_section_commands{$key})); 10777# $latex_body .= "\\stepcounter{$key}\n" if $key; 10778# &reset_dependents($key) if ($dependent{$key}); 10779 10780 local($br_id); 10781# if ($USING_STYLES) { 10782# $txt_style{"H$H.$key"} = " " unless $txt_style{"H$H.$key"}; 10783# $H .= " CLASS=\"$key\"; 10784# }; 10785 10786 local ($align, $dummy)=&get_next_optional_argument; 10787 if (($align =~/^(left|right|center)$/i)&&($HTML_VERSION > 2.0)) { 10788 $align = "ALIGN=\"$1\""; 10789 } elsif ($align) { 10790 # data was meant to be a running-head ! 10791 $br_id = ++$global{'max_id'}; 10792 $run_title = &translate_environments("$O$br_id$C$align$O$br_id$C"); 10793 $run_title = &translate_commands($run_title) if ($run_title =~ /\\/); 10794 $run_title =~ s/($O|$OP)\d+($C|$CP)//g; 10795 $align = ''; 10796 } else { 10797 } 10798 $titletext = &missing_braces 10799 unless s/$next_pair_rx/$titletext=$2;''/eo; 10800 $br_id = ++$global{'max_id'}; 10801 $titletext = &translate_environments("$O$br_id$C$titletext$O$br_id$C"); 10802 10803 $title_key = $run_title || $titletext; 10804 $title_key =~ s/$image_mark\#([^\#]+)\#(\\space)?/&purify_caption($1)/e; 10805 # This should reduce to the same information as contained in the .aux file. 10806 $title_key = &sanitize(&simplify($title_key)); 10807 10808 # RRM: collect all anchors from \label and \index commands 10809 ($anchors,$titletext) = &extract_anchors($titletext); 10810 local($saved_title) = $titletext; 10811 do { 10812 # to ensure a style ID is not saved and re-used in (mini-)TOCs 10813 local($USING_STYLES) = 0; 10814 $titletext = &translate_environments($titletext); 10815 $titletext = &translate_commands($titletext) 10816 if ($titletext =~/\\/); 10817 }; 10818 # but the style ID can be used for the title on the HTML page 10819 if (!($titletext eq $saved_title)) { 10820 $saved_title = &translate_environments($saved_title); 10821 $saved_title = &translate_commands($saved_title) 10822 if ($saved_title =~/\\/); 10823 $saved_title = &simplify($saved_title); 10824 } 10825 local($closures) = &close_all_tags(); 10826 $saved_title .= $closures; 10827 $title_text .= $closures; 10828 10829 # This is the LaTeX section number read from the $FILE.aux file 10830 @tmp = split(/$;/,$encoded_section_number{$title_key}); 10831 $section_number = shift(@tmp); 10832 $section_number = "" if ($section_number eq "-1"); 10833 $encoded_section_number{$title_key} = join($;, @tmp) 10834# unless (defined $title); 10835 unless ($title); 10836 10837 # need to check also &{wrap_cmd_... also, if \renewcommand has been used; 10838 # thanks Bruce Miller 10839 local($thehead,$whead) = ("do_cmd_the$key","wrap_cmd_the$key"); 10840# $thehead = ((defined &$thehead)? 10841# &translate_commands("\\the$key") : ''); 10842 $thehead = ((defined &$thehead)||(defined &$whead) 10843 ? &translate_commands("\\the$key") : ''); 10844 $thehead .= $SECNUM_PUNCT 10845 if ($SECNUM_PUNCT &&($thehead)&& !($thehead =~ /\./)); 10846 $section_number = $thehead if (($thehead)&&($SHOW_SECTION_NUMBERS)); 10847 10848 #JKR: Don't prepend whitespace 10849 if ($section_number) { 10850 $titletext = "$section_number " . $titletext; 10851 $saved_title = "$section_number " . $saved_title; 10852 $run_title = "$section_number " . $run_title if $run_title; 10853 } 10854 10855# $toc_sec_title = $titletext; 10856# $toc_sec_title = &purify($titletext); 10857 $toc_sec_title = &simplify($titletext); 10858 $titletext = &simplify($titletext); 10859# $TITLE = &purify($titletext); 10860 local($after) = $_; 10861 do { 10862 local($_) = $titletext; &remove_anchors; 10863 if ($run_title) { 10864 $TITLE = $run_title; 10865 } elsif ($_) { 10866 $TITLE = $_ 10867 } else { $TITLE = '.' }; 10868 }; 10869 $global{$key}-- if ($key && $making_name); 10870 return ($TITLE) if (defined $title); 10871 10872 #RRM: no preceding \n when this is the first section-head on the page. 10873 if (! $key || $key < $MAX_SPLIT_DEPTH) { $pre = '' }; 10874 if ( defined &make_pre_title) { 10875 $pre = &make_pre_title($saved_title, $H); 10876 } 10877 10878 undef $open_tags_R; 10879 $open_tags_R = [ @save_open_tags ]; 10880 10881 join('', $pre, &make_section_heading($saved_title, $H, $align.$anchors) 10882 , $open_all, $_); 10883} 10884 10885sub do_cmd_documentclass { 10886 local($_) = @_; 10887 local ($docclass)=(''); 10888 local ($cloptions,$dum)=&get_next_optional_argument; 10889 $docclass = &missing_braces unless ( 10890 (s/$next_pair_pr_rx/$docclass = $2;''/eo) 10891 ||(s/$next_pair_rx/$docclass = $2;''/eo)); 10892 local($rest) = $'; 10893 &do_require_package($docclass); 10894 if (! $styles_loaded{$docclass}) { 10895 &no_implementation("document class",$docclass); 10896 } else { 10897 if($cloptions =~ /\S+/) { # are there any options? 10898 &do_package_options($docclass,$cloptions); 10899 } 10900 } 10901 $rest; 10902} 10903sub do_cmd_documentstyle { &do_cmd_documentclass($_[0]); } 10904 10905sub do_cmd_usepackage { 10906 local($_) = @_; 10907 # RRM: allow lists of packages and options 10908 local ($package, $packages)=('',''); 10909 local ($options,$dum)=&get_next_optional_argument; 10910 $packages = &missing_braces unless ( 10911 (s/$next_pair_pr_rx/$packages = $2;''/eo) 10912 ||(s/$next_pair_rx/$packages = $2;''/eo)); 10913 local($rest) = $_; 10914 # MRO: The files should have already been loaded by 10915 # TMP_styles, but we better make it sure. 10916 foreach $package (split (',',$packages)) { # allow multiple packages 10917 $package =~ s/\s|\%|$comment_mark\d*//g; # remove whitespace 10918 $package =~ s/\W/_/g; # replace non-alphanumerics 10919 &do_require_package($package); 10920 if (! $styles_loaded{$package}) { 10921 &no_implementation("package",$package); 10922 } else { 10923 if($options =~ /\S+/) { # are there any options? 10924 &do_package_options($package,$options); 10925 } 10926 } 10927 } 10928 $rest; 10929} 10930 10931 10932sub no_implementation { 10933 local($what,$which)= @_; 10934 print STDERR "\nWarning: No implementation found for $what: $which"; 10935} 10936 10937sub do_cmd_RequirePackage { 10938 local($_)= @_; 10939 local($file); 10940 local($options,$dum)=&get_next_optional_argument; 10941 $file = &missing_braces unless ( 10942 (s/$next_pair_pr_rx/$file = $2;''/eo) 10943 ||(s/$next_pair_rx/$file = $2;''/eo)); 10944 local($rest) = $_; 10945 $file =~ s/^[\s\t\n]*//o; 10946 $file =~ s/[\s\t\n]*$//o; 10947 # load the package, unless that has already been done 10948 &do_require_package($file) unless ($styles_loaded{$file}); 10949 # process any options 10950 if (! $styles_loaded{$file}) { 10951 &no_implementation("style",$file); 10952 } else { 10953 # process any options 10954 &do_package_options($file,$options) if ($options); 10955 } 10956 $_ = $rest; 10957 # ignore trailing optional argument 10958 local($date,$dum)=&get_next_optional_argument; 10959 $_; 10960} 10961 10962sub do_cmd_PassOptionsToPackage { 10963 local($_) = @_; 10964 local($options,$file); 10965 $options = &missing_braces unless ( 10966 (s/$next_pair_pr_rx/$options = $2;''/eo) 10967 ||(s/$next_pair_rx/$options = $2;''/eo)); 10968 $file = &missing_braces unless ( 10969 (s/$next_pair_pr_rx/$file = $2;''/eo) 10970 ||(s/$next_pair_rx/$file = $2;''/eo)); 10971 $passedOptions{$file} = $options; 10972 $_; 10973} 10974sub do_cmd_PassOptionsToClass{ &do_cmd_PassOptionsToPackage(@_)} 10975 10976sub do_package_options { 10977 local($package,$options)=@_; 10978 local($option); 10979 if ($passedOptions{$package}) { $options = $passedOptions{$package}.'.'.$options }; 10980 foreach $option (split (',',$options)) { 10981 $option =~ s/^[\s\t\n]*//o; 10982 $option =~ s/[\s\t\n]*$//o; 10983 $option =~ s/\W/_/g; # replace non-alphanumerics 10984 next unless ($option); 10985 if (!($styles_loaded{$package."_$option"})) { 10986 &do_require_packageoption($package."_$option"); 10987 if (!($styles_loaded{$package."_$option"})) { 10988 &no_implementation("option","\`$option\' for \`$package\' package\n"); 10989 } 10990 } 10991 } 10992 $rest; 10993} 10994 10995sub do_class_options { 10996 local($class,$options)=@_; 10997 local($option); 10998 if ($passedOptions{$class}) { $options = $passedOptions{$class}.'.'.$options }; 10999 foreach $option (split (',',$options)) { 11000 $option =~ s/^[\s\t\n]*//o; 11001 $option =~ s/[\s\t\n]*$//o; 11002 $option =~ s/\W/_/g; # replace non-alphanumerics 11003 next unless ($option); 11004 &do_require_package($option); 11005 if (!($styles_loaded{$class."_$option"})) { 11006 &do_require_packageoption($class."_$option"); 11007 if (!($styles_loaded{$class."_$option"})) { 11008 &no_implementation("option","\`$option\' for document-class \`$class\'\n"); 11009 } 11010 } 11011 } 11012 $rest; 11013} 11014 11015sub do_require_package { 11016 local($file)= @_; 11017 local($dir); 11018 #RRM: make common ps/eps-packages use epsfig.perl 11019 $file = 'epsfig' if ($file =~ /^(psfig|epsf)$/); 11020 11021 if ($file =~ /^graphicx$/) { 11022 # work-around the CVS repository bug: use graphixx , not graphicx 11023 foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) { 11024 if (-f "$dir${dd}graphixx.perl") { 11025 $file = 'graphixx'; 11026 last; 11027 } 11028 } 11029 } 11030 11031 11032 if (! $styles_loaded{$file}) { 11033 # look for a file named ${file}.perl 11034 # MRO: use $texfilepath instead of `..' 11035 if ((-f "$texfilepath$dd${file}.perl") && ! $styles_loaded{$file}){ 11036 print STDOUT "\nPackage: loading $texfilepath$dd${file}.perl"; 11037 require("$texfilepath$dd${file}.perl"); 11038 $styles_loaded{$file} = 1; 11039 } else { 11040 foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) { 11041 if ((-f "$dir$dd${file}.perl") && ! $styles_loaded{$file}){ 11042 print STDOUT "\nPackage: loading $dir$dd${file}.perl"; 11043 require("$dir$dd${file}.perl"); 11044 $styles_loaded{$file} = 1; 11045 last; 11046 } 11047 } 11048 } 11049 } 11050} 11051 11052sub do_require_extension { 11053 local($file)= @_; 11054 local($dir); 11055 11056 if (! $styles_loaded{$file}) { 11057 # look for a file named ${file}.pl 11058 # MRO: use $texfilepath instead of `..' 11059 if (-f "$texfilepath$dd${file}.pl") { 11060 print STDOUT "\nExtension: loading $texfilepath$dd${file}.pl"; 11061 require("$texfilepath$dd${file}.pl"); 11062 ++$styles_loaded{$file}; 11063 $NO_UTF = 1 if (($file =~ /latin/)&&($charset =~/utf/)); 11064 } else { 11065 foreach $dir (split(/$envkey/,$LATEX2HTMLVERSIONS)) { 11066 if (-f "$dir$dd${file}.pl"){ 11067 print STDOUT "\nExtension: loading $dir$dd${file}.pl"; 11068 require("$dir$dd${file}.pl"); 11069 ++$styles_loaded{$file}; 11070 $NO_UTF = 1 if (($file =~ /latin/)&&($charset =~/utf/)); 11071 last; 11072 } 11073 } 11074 } 11075 } else { 11076 if (($file =~ /latin|hebrew/)&&($charset =~/utf|10646/) 11077 && $loading_extensions) { 11078 $NO_UTF = 1; 11079 $USE_UTF = 0; 11080 print STDOUT "\n\n ...producing $CHARSET output\n"; 11081 $charset = $CHARSET; 11082 } 11083 } 11084} 11085 11086sub do_require_packageoption { 11087 local($option)= @_; 11088 local($do_option); 11089 # first look for a file named ${option}.perl 11090 &do_require_package($option) unless ($styles_loaded{$option}); 11091 # next look for a subroutine named do_$option 11092 $do_option = "do_$option"; 11093 if (!($styles_loaded{$option}) && defined(&$do_option)) { 11094 &$do_option(); 11095 $styles_loaded{$option} = 1; 11096 } 11097} 11098 11099############################ Environments ################################ 11100 11101# This is a dummy environment used to synchronise the expansion 11102# of order-sensitive macros. 11103sub do_env_tex2html_deferred { 11104 local($_) = @_; 11105 local($tex2html_deferred) = 1; 11106 $_ = &process_command($single_cmd_rx,$_); 11107} 11108 11109# catch wrapped commands that need not have been 11110sub do_env_tex2html_nomath_inline { 11111 local($_) = @_; 11112 s/^\s+|\s+$//gs; 11113 my($cmd) = $_; 11114 if ($cmd=~s/^\\([a-zA-Z]+)//s) { $cmd = $1 }; 11115 return (&translate_commands($_)) if ($raw_arg_cmds{$cmd}<1); 11116 &process_undefined_environment($env, $id, $_); 11117} 11118 11119# The following list environment subroutines still do not handle 11120# correctly the case where the list counters are modified (e.g. \alph{enumi}) 11121# and the cases where user defined bullets are mixed with the default ones. 11122# e.g. \begin{enumerate} \item[(1)] one \item two \end{enumerate} will 11123# not produce the same bullets as in the dvi output. 11124sub do_env_itemize { 11125 local($_) = @_; 11126 $itemize_level++; 11127 #RRM - catch nested lists 11128 &protect_useritems($_); 11129 $_ = &translate_environments($_); 11130 11131 local($bullet,$bulletx)=(' ',''); 11132 SWITCH: { 11133 if ($itemize_level==1) { $bulletx = "\\bullet"; last SWITCH; } 11134 if ($itemize_level==2) { $bulletx = "\\mathbf{\\circ}"; last SWITCH; } 11135 if ($itemize_level==3) { $bulletx = "\\mathbf{\\ast}"; last SWITCH; } 11136 } 11137 $itemize_level--; 11138 11139 if (/\s*$item_description_rx/) { 11140 # Contains user defined optional labels 11141 $bulletx = &do_cmd_mbox("${O}1$C\$$bulletx\$${O}1$C") if $bulletx; 11142 &do_env_description($_, " COMPACT", $bullet.$bulletx) 11143 } else { &list_helper($_,'UL'); } 11144} 11145 11146sub do_env_enumerate { 11147 local($_) = @_; 11148# Reiner Miericke provided the main code; integrated by RRM: 14/1/97 11149# works currently only with 'enumerate' and derived environments 11150# explicit styled labels are computed for each \item 11151# ultimately the environment is done as: &do_env_description($_, " COMPACT") 11152 ++$enum_level; 11153 local(%enum) = %enum; # to allow local changes 11154# Reiner: \begin{enumerate}[<standard_label>] 11155 local($standard_label) = ""; 11156 local(@label_fields); 11157 local($label_func, $preitems, $enum_type); 11158 local($rlevel) = &froman($enum_level); # e.g. 3 => iii 11159 11160 # \begin{enumerate}[$standard_label] 11161 if (s/^$standard_label_rx//s) { # multiline on/off ? 11162 # standard label should be used later to modify 11163 # entries in %enum 11164 $standard_label = $1; # save the standard label 11165# s/^$standard_label_rx//; # and cut it off 11166 $standard_label =~ s/([\\\[\]\(\)])/\\$1/g; # protect special chars 11167 11168 # Search for [aAiI1] which is not between a pair of { } 11169 # Other cases like "\theenumi" are not handled 11170 @label_fields = $standard_label =~ /$enum_label_rx/; 11171 if (($standard_label =~ /^[aAiI1]$/)&&(not(/item\s*\[/))) { 11172 $enum_type = ' TYPE="'.$standard_label.'"'; 11173 $standard_label = ''; 11174 } else { 11175 $label_func = $enum_label_funcs{$label_fields[$#label_fields-1]} . 11176 "(\'enum" . $rlevel . "\')"; 11177 $enum{'theenum' . $rlevel} = "\&$label_func"; 11178# local($thislabel) = "\&$label_func"; 11179# do { local($_) = $thislabel; &make_unique($_); 11180# $enum{'theenum' . $rlevel} = $_; }; 11181 $standard_label = 11182 "\"$label_fields[0]\" . eval(\$enum{\"theenum$rlevel\"})" 11183 . ".\"$label_fields[$#label_fields]\""; 11184 $enum{'labelenum' . $rlevel} = $standard_label; 11185 } 11186 } elsif (s/^((.|\n)+?)\\item/$preitems=$1;"\\item"/es) { 11187 my $pre_preitems; local($cmd); $label_part; 11188 my $num_styles = join('|', values %enum_label_funcs ); 11189 while ($preitems =~ 11190 /\s*\\renew(ed)?command\s*(($O|$OP)\d+($C|$CP))\\?((label|the)enum(\w+))\s*\2/) { 11191 # this catches one \renewcommand{\labelenum}{....} 11192 $pre_preitems .= $`; $preitems = $'; $cmd = $5; 11193 &missing_braces unless ( 11194 ($preitems=~s/$next_pair_pr_rx\s*/$label_part=$2;''/oe) 11195 ||($preitems=~s/$next_pair_rx\s*/$label_part=$2;''/oe)); 11196 $cmd =~ s/^label/the/; 11197 $label_part=~s/\\($num_styles)\s*(($O|$OP)\d+($C|$CP))(\w+)\2/".\&$1\(\'$5\'\)."/g; 11198 $label_part = '"'.$label_part.'"'; 11199 $enum{$cmd} = $label_part; 11200 } 11201 $standard_label = 11202 "\"$label_fields[0]\" . eval(\$enum{\"theenum$rlevel\"})" 11203 . ".\"$label_fields[$#label_fields]\"" if ($cmd); 11204 $_ = $pre_preitems . $preitems . $_ if ($pre_preitems||$preitems); 11205 } else { 11206 @enum_default_type = ('A', '1', 'a', 'i', 'A') unless (@enum_default_type); 11207 $enum_type = $enum_level%4; 11208 $enum_type = ' Type="'.@enum_default_type[$enum_type].'"'; 11209 } 11210 11211 # enclose contents of user-defined labels within a group, 11212 # in case of style-change commands, which could bleed outside the label. 11213 &protect_useritems($_); 11214 $_ = &translate_environments($_); #catch nested lists 11215 11216 local($enum_result); 11217 if (($standard_label)||(/\\item\[/)) { 11218 # split it into items 11219 @items = split(/\\item\b/,$_); 11220 # save anything (non-blank) before the items actually start 11221 $preitems = shift(@items); 11222 $preitems =~ s/^\s*$//; 11223 local($enum_label); 11224 # prepend each item with an item label: \item => \item[<label>] 11225 foreach $item (@items) { 11226# unless ( $item =~ /^\s*$/ ) { # first line may be empty 11227 $enum{"enum" . $rlevel}++; # increase enumi 11228 $enum_label = eval("$enum{'labelenum' . $rlevel}"); 11229 # insert a label, removing preceding space, BUT... 11230 # do NOT handle items with existing labels 11231 $item =~ s/^\s*//; 11232 if ($item =~ s/^\s*\[([^]]*)\]//) { 11233 $enum{"enum" . $rlevel}--; 11234 $enum_label = "$1"; 11235 local($processed) = ($enum_label =~/$OP/); 11236 $enum_label = join('',($processed ? "<#0#>" : "<<0>>") 11237 ,$enum_label ,($processed ? "<#0#>" : "<<0>>")) 11238 if ($enum_label =~ /\\/); 11239 if ($processed) { &make_unique_p($enum_label) } 11240 elsif ($enum_label =~ /$O/) { &make_unique($enum_label) }; 11241 $item = "[${enum_label}]".$item; 11242 } else { 11243 local($processed) = ($enum_label =~/$OP/); 11244 $enum_label = join('',($processed ? "<#0#>" : "<<0>>") 11245 ,$enum_label ,($processed ? "<#0#>" : "<<0>>")) 11246 if ($enum_label =~ /\\/); 11247 if ($processed) { &make_unique_p($enum_label) } 11248 elsif ($enum_label =~ /$O/) { &make_unique($enum_label) }; 11249 $item = "[$enum_label\]$item"; 11250 $enum_label =~ s/\.$//; 11251 } 11252 if ($standard_label) { 11253 $item =~ s/(\\labelitem$rlevel|$standard_label)/$enum_label/g 11254 } else { 11255 $item =~ s/(\\labelitem$rlevel)/$enum_label/g 11256 } 11257 }; 11258 $_ = join("\\item ", $preitems, @items); 11259 11260 # Original, but $enum_result 11261 $enum_result = &do_env_description($_, " COMPACT"); 11262 } else { 11263 $enum_result = &list_helper($_, "OL$enum_type", '', ''); 11264 } 11265 11266 #clean-up and revert the $enum_level 11267 $enum{"enum" . $rlevel} = 0; 11268 $enum{"enum" . &froman($enum_level)} = 0; 11269 --$enum_level; 11270 $enum_result; 11271} 11272 11273sub do_env_list { 11274 local ($_) = @_; 11275 local ($list_type,$labels,$lengths) = ('UL','',''); 11276 11277 $labels = &missing_braces unless ( # get the label specifier 11278 (s/$next_pair_pr_rx/$labels=$2;''/e) 11279 ||(s/$next_pair_rx/$labels=$2;''/e)); 11280 11281 $lengths = &missing_braces unless ( # get the length declarations 11282 (s/$next_pair_pr_rx/$lengths=$2;''/e) 11283 ||(s/$next_pair_rx/$lengths=$2;''/e)); 11284 # switch to enumerated style if they include a \usecounter. 11285 $list_type = 'OL' if $lengths =~ /\\usecounter/; 11286 11287 /\\item\b/; local($preitems) = $`; 11288 $_ =~ s/^\Q$preamble//s if ($preitems); 11289 $preitems =~s/^\s*|\s*$//g; 11290 if ($preitems) { 11291 $preitems = &translate_environments($preitems); 11292 $preitems = &translate_commands($preitems) if ($preitems =~ /\\/); 11293# &write_warnings("\nDiscarding: $preitems before 1st item in list") 11294# if ($preitems); 11295 } 11296 11297 #RRM - catch nested lists 11298 #RRM unfortunately any uses of the \\usecounter within \item s 11299 # may be broken --- sigh. 11300 &protect_useritems($_); 11301 $_ = &translate_environments($_); 11302 11303 if (($list_type =~ /OL/)&&($labels)) { 11304 local($br_ida,$br_idb,$label,$aft); 11305 $br_ida = ++$global{'max_id'}; 11306 $lengths =~ s/\\usecounter((($O|$OP)\d+($C|$CP))[^<]+\2)/ 11307 &make_nowrapper(1)."\\stepcounter$1".&make_nowrapper(0)/e; 11308 $labels = "$O$br_ida$C$lengths$O$br_ida$C".$labels; 11309 11310# s/\\item\b\s*([^\[])/do { 11311# $label = $labels; $aft = $1; 11312# $br_id = ++$global{'max_id'}; 11313# $label = &translate_environments( 11314# "$O$br_id$C$label$O$br_id$C"); 11315# join('',"\\item\[" , $label, "\]$aft" ); 11316# }/eg; 11317# $labels =''; 11318 } 11319 11320 if (($labels)||(/\\item\[/)) { 11321 $_ = &list_helper($_, 'DL', $labels, $lengths) 11322 } else { 11323 $_ = &list_helper($_, $list_type, '', $lengths) 11324 } 11325 $_; 11326} 11327 11328sub do_env_trivlist { 11329 local($_) = @_; 11330 local($compact,$item_sep,$pre_items) = ' COMPACT'; 11331 &protect_useritems($_); 11332 11333 # assume no styles initially for this list 11334 local($close_tags,$reopens) = &close_all_tags(); 11335 local($open_tags_R) = []; 11336 local(@save_open_tags) = (); 11337 11338 # include \label anchors from [...] items 11339 s/$item_description_rx\s*($labels_rx8)?\s*/ 11340 (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."\n"/eg; 11341 # remove unwanted space before \item s 11342 s/[ \t]*\\item\b/\\item/g; 11343 11344 local($this_item,$br_id) = ('',''); 11345 local($this_sitem,$this_eitem) = ("\n<P>","</P>\n",''); 11346 11347 # assume no sub-lists, else... why use {trivlist} ? 11348 # extract up to the 1st \item 11349 local(@items) = split(/\\item\b/, $_); 11350 $pre_items = shift @items; 11351 $_ = ''; 11352 while (@items) { 11353 $br_id = ++$global{'max_id'}; 11354 $this_item = shift @items; 11355 $this_item = &translate_environments( 11356 "$O$br_id$C".$pre_items.$this_item."$O$br_id$C" ); 11357 if ($this_item =~ /\\/) { 11358 $this_item = &translate_commands($this_item); 11359 $_ .= join('' , $this_sitem 11360 , $this_item 11361 # , $this_eitem 11362 ) 11363 } else { $_ .= $this_sitem . $this_item } 11364 } 11365 11366 $_ = &translate_environments($_); 11367 $_ = &translate_commands($_); 11368 11369 join('' , $close_tags , $_ , $reopens); 11370 11371} 11372 11373# enclose the contents of any user-defined labels within a group, 11374# else any style-change commands may bleed outside the label. 11375sub protect_useritems { 11376 # MRO: use $_[0] instead: local(*_) = @_; 11377 local($preitems, $thisitem); 11378 $_[0] =~ s/^$par_rx\s*//s; # discard any \par before 1st item 11379 11380 # locate \item with optional argument 11381 local($saveRS) = $/; undef $/; 11382 local(@preitems); 11383 # allow one level of nested [] 11384 # MRO: Caution! We have a double-wildcarded RX here, this may cause 11385 # trouble. Should be re-coded. 11386 $_[0] =~ s/\\item[\s\r]*(\b(\[(([^\[\]]|\[[^]]*\])*)\])?|[^a-zA-Z\s])/ 11387 $thisitem = " $1"; 11388 if ($2) { 11389 $br_id = ++$global{'max_id'}; 11390 $thisitem = '['.$O.$br_id.$C.$3.$O.$br_id.$C.']'; 11391 }; 11392 "\\item".$thisitem 11393 /egm; 11394 11395 $/ = $saveRS; 11396 $_[0] = join(@preitems, $_[0]); 11397} 11398 11399sub do_env_description { 11400 local($_, $compact, $bullet) = @_; 11401 #RRM - catch nested lists 11402 &protect_useritems($_); 11403 $_ = &translate_environments($_) unless ($bullet); 11404 11405 # MRO: replaced $* with /m 11406 $compact = "" unless $compact; 11407 if ($compact) { # itemize/enumerate with optional labels 11408 s/\n?$item_description_rx\s*($labels_rx8)?\s*/"\n<\/DD>\n<DT>". 11409 (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."<\/DT>\n<DD>"/egm; 11410 } else { 11411 s/\n?$item_description_rx\s*($labels_rx8)?\s*/"\n<\/DD>\n<DT>". 11412 (($9)? "<A NAME=\"$9\"><STRONG>$1<\/STRONG><\/A>" 11413 : "<STRONG>$1<\/STRONG>") ."<\/DT>\n<DD>"/egm; 11414 } 11415 # and just in case the description is empty ... 11416#JCL(jcl-del) - $delimiter_rx -> ^$letters 11417 s/\n?\\item\b\s*([^$letters\\]|)\s*/\n<\/DD>\n<DT>$bullet<\/DT>\n<DD>$1/gm; 11418 s/^\s+//m; 11419 11420 $_ = '<DD>'.$_ unless ($_ =~ s/^\s*<\/D(T|D)>\n?//s); 11421 $_ =~ s/\n$//s; 11422 "<DL$compact>\n$_\n</DD>\n</DL>"; 11423} 11424 11425sub list_helper { 11426 local($_, $tag, $labels, $lengths) = @_; 11427 local($item_sep,$pre_items,$compact,$etag,$ctag); 11428 $ctag = $tag; $ctag =~ s/^(.*)\s.*$/$1/; 11429 11430 # assume no styles initially for this list 11431 local($close_tags,$reopens) = &close_all_tags(); 11432 local($open_tags_R) = []; 11433 local(@save_open_tags) = (); 11434 11435# #RRM: cannot have anything before the first <LI> 11436# local($savedRS) = $/; $/=''; 11437# $_ =~ /\\item[\b\r]/s; 11438# if ($`) { 11439# $preitems = $`; $_ = $&.$'; 11440# $preitems =~ s/<P( [^>]*)?>//g; 11441# $close_tags .= "\n".$preitems if $preitems; 11442# } 11443# $/ = $savedRS; 11444# 11445 11446 if (($tag =~ /DL/)&&$labels) { 11447 local($label,$aft,$br_id); 11448 s/\\item\b[\s\r]*([^\[])/do { 11449 $label = $labels; $aft = $1; 11450 $br_id = ++$global{'max_id'}; 11451 $label = &translate_environments( 11452 "$O$br_id$C$label$O$br_id$C"); 11453 join('',"\\item\[" , $label, "\]$aft" ); 11454 }/egm; 11455 } 11456 11457 # This deals with \item[xxx] ... 11458 if ($tag =~ /DL/) { 11459 $compact = ' COMPACT'; 11460 # include \label anchors in the <DT> part 11461 # and $pre_item tags in the <DD> part: 11462 if ($labels && $lengths) { 11463 $item_sep = "\n</DD>\n<DT>"; 11464 } else { 11465 $item_sep = ($labels ? "<DT>$labels\n" : '') ."</DT>\n<DD>"; 11466 } 11467 $etag = "\n</DD>"; 11468 s/$item_description_rx[\r\s]*($labels_rx8)?[\r\s]*/"<DT>" . 11469 (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."\n<DD>"/egm; 11470 } else { 11471 $item_sep = "\n</LI>\n<LI>"; 11472 $etag = "\n</LI>"; 11473 } 11474 11475 # remove unwanted space before \item s 11476 s/[ \t]*\\item\b/\\item/gm; 11477 11478 #JCL(jcl-del) - $delimiter_rx -> ^$letters 11479 s/\n?\\item\b[\r\s]*/$item_sep/egm; 11480 11481 #RRM: cannot have anything before the first <LI> 11482 local($savedRS) = $/; $/=''; 11483 $_ =~ /\Q$item_sep\E|<DT>|<LI>/s; 11484 #RRM: ...try putting it before the list-open tag 11485 if ($`) { 11486 $preitems = $`; $_ = $&.$'; 11487 $preitems =~ s/<P( [^>]*)?>//gm; 11488 $close_tags .= "\n".$preitems if $preitems; 11489 } 11490 $_ =~ s/^\s*<\/[^>]+>\s*//s; 11491 11492 # remove \n from end of the last item 11493 $_ =~ s/\n$//s; 11494 $/ = $savedRS; 11495 11496 join('' , $close_tags , "\n<$tag$compact>\n" 11497 , $_ , "$etag\n</$ctag>" , $reopens); 11498} 11499 11500 11501# RRM: A figure environment generates a picture UNLESS it contains a 11502# {makeimage} sub-environment; in which case it creates a <DIV> 11503# inside which the contents are interpreted as much as is possible. 11504# When there are captions, this modifies $before . 11505sub do_env_figure { 11506 local($_) = @_; 11507 local($halign, $anchors) = ('CENTER',''); 11508 local ($border, $attribs ); 11509 local($cap_width) = $cap_width; 11510 my ($opt, $dummy) = &get_next_optional_argument; 11511 11512 my $abovedisplay_space = $ABOVE_DISPLAY_SPACE||"<P></P>\n"; 11513 my $belowdisplay_space = $BELOW_DISPLAY_SPACE||"<P></P>\n"; 11514 11515 ($_,$anchors) = &extract_labels($_); # extract labels 11516 # Try to establish the alignment 11517 if (/^(\[[^\]]*])?\s*\\begin\s*<<\d*>>(\w*)<<\d*>>|\\(\w*)line/) { 11518 $halign = $2.$3; 11519 if ($halign =~ /right/i) { $halign = 'RIGHT' } 11520 elsif ($halign =~ /left/i) { $halign = 'LEFT' } 11521 elsif ($halign =~ /center/i) { $halign = 'CENTER' } 11522 else { $halign = 'CENTER' } 11523 } 11524 11525 # allow caption-alignment to be variable 11526 local($cap_align); 11527 if ($FIGURE_CAPTION_ALIGN =~ /^(TOP|BOTTOM|LEFT|RIGHT)/i) { 11528 $cap_align = join('', ' ALIGN="', $&, $','"')}; 11529 11530 local($cap_env, $captions,$has_minipage) = ('figure',''); 11531 if ((/\\begin\s*($O\d+$C)\s*(makeimage|minipage)\s*\1|\\docode/)|| 11532 (/\\includegraphics/&&(!/$htmlborder_rx|$htmlborder_pr_rx|\\htmlimage/))){ 11533 $has_minipage = ($2 =~ /minipage/sg ); 11534 $_ = &translate_environments($_); 11535 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11536 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11537 do { local($contents) = $_; 11538 &extract_captions($cap_env); $_ = $contents; 11539 } if (/\\caption/); 11540 $_ = &translate_commands($_); 11541 while ($_ =~ s/(^\s*<BR>\s*|\s*<BR>\s*$)//sg){}; # remove unneeded breaks 11542 } else { 11543 do { local($contents) = $_; 11544 # MRO: no effect: &extract_captions($cap_env, *cap_width); $_ = $contents; 11545 &extract_captions($cap_env); $_ = $contents; 11546 } if (/\\caption/); 11547 # Generate picture of the whole environment 11548 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11549 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11550 $_ = &process_undefined_environment($env, $id, $_); 11551 $_ = &post_latex_do_env_figure($_); 11552 $_ =~ s/\s*<BR>\s*$//g; 11553 } 11554 11555 if ($captions) { 11556 # MRO: replaced $* with /m 11557 $captions =~ s/^\n//m; 11558 $captions =~ s/\n$//m; 11559 } 11560 s/$caption_mark//g; 11561 11562 local($close_tags) = &close_all_tags; 11563 $_ .= $close_tags; 11564 11565 # place all the pieces inside a TABLE, if available 11566 if ($HTML_VERSION > 2.1) { 11567 if ($captions) { 11568 local($pxs,$len) = &convert_length($cap_width,$MATH_SCALE_FACTOR) 11569 if $cap_width; 11570 local($table) = "<TABLE$env_id"; # WIDTH="65%"'; 11571 $table .= " WIDTH=\"$pxs\"" if ($pxs); 11572 if ($border) { $table .= " BORDER=\"$border\"" } # no checking !! 11573 $table .= ">"; 11574 s/^\s*|\s*$//g; 11575 join ('' 11576 , $above_display_space 11577 , "\n<DIV", ($halign ? " ALIGN=\"$halign\"" :'') 11578 , '>', $anchors , $cap_anchors 11579 , "\n$table\n<CAPTION", $cap_align, '>' 11580 , $captions , "</CAPTION>\n<TR><TD>" 11581 , ($cap_width ? '</TD><TD>' : '') 11582 , $_ , '</TD>' 11583 , ($cap_width ? '<TD></TD>' : '') 11584 , "</TR>\n</TABLE>\n</DIV>\n" 11585 , $below_display_space 11586 ) 11587 } elsif ($halign) { 11588 if ($border||($attributes)||$env_id) { 11589 &make_table( $border, $attribs, $anchors, '', $halign, $_ ); 11590 } else { 11591 join ('' 11592 , $above_display_space 11593 , "\n<DIV ALIGN=\"$halign\">\n" 11594 , ($anchors ? "\n<P>$anchors</P>" : '') 11595 , $_ 11596 , "\n</DIV>" 11597 , $below_display_space 11598 ) 11599 } 11600 } else { 11601 if ($border||($attributes)||$env_id) { 11602 join ('' 11603 , $above_display_space 11604 , "\n<DIV", ($halign ? " ALIGN=\"$halign\"":'') 11605 , '>' 11606 , &make_table( $border, $attribs, $anchors, '', $halign, $_ ) 11607 , "\n</DIV><BR" 11608 , (($HTML_VERSION > 3.1)? " CLEAR=\"ALL\"" :'') 11609 , '>' 11610 , $below_display_space 11611 ); 11612 } else { 11613 join ('' 11614 , $above_display_space 11615 , "\n<DIV", ($halign ? " ALIGN=\"$halign\"":'') 11616 , ">$anchors\n" , $_ , "\n</DIV><BR" 11617 , (($HTML_VERSION > 3.1)? " CLEAR=\"ALL\"" :'') 11618 , '>' 11619 , $below_display_space 11620 ); 11621 } 11622 } 11623 } else { 11624 # MRO: replaced $* with /m 11625 s/^\n//m; 11626 s/\n$//m; 11627 if ($captions) { 11628 join('', "\n<BR>\n", (($anchors) ? "$anchors" : '') 11629 , "$cap_anchors\n$captions\n<BR>" 11630 , "\n<P", ($halign ? " ALIGN=\"$halign\"":'') 11631 , '>', $_ , "\n</P>"); 11632 } elsif ($halign) { 11633 join ('', "<BR>\n$anchors", $_ , "\n<BR>" ) 11634 } else { 11635 join('', "<BR>\n<P", ($halign ? " ALIGN=\"$halign\"":'') 11636 , ">$anchors\n" , $_ , "\n</P><BR>"); 11637 } 11638 } 11639} 11640 11641sub do_env_figurestar { &do_env_figure(@_) } 11642 11643sub do_env_table { 11644 local($_) = @_; 11645 local($halign, $anchors) = ('',''); 11646 local ( $border, $attribs ); 11647 &get_next_optional_argument; 11648 11649 # Try to establish the alignment 11650 if (/^(\[[^\]]*])?\s*\\begin\s*<<\d*>>(\w*)<<\d*>>|\\(\w*)line/) { 11651 $halign = $2.$3; 11652 if ($halign =~ /right/i) { $halign = 'RIGHT' } 11653 elsif ($halign =~ /left/i) { $halign = 'LEFT' } 11654 elsif ($halign =~ /center/i) { $halign = 'CENTER' } 11655 else { $halign = '' } 11656 } 11657 11658 local($cap_env, $captions) = ('table',''); 11659 11660 # allow caption-alignment to be variable 11661 local($cap_align); 11662 if ($TABLE_CAPTION_ALIGN =~ /^(TOP|BOTTOM|LEFT|RIGHT)/i) { 11663 $cap_align = join('', ' ALIGN="', $&, $','"')}; 11664 11665 if ((/\\(begin|end)\s*($O\d+$C)\s*makeimage\s*\2/)|| 11666 ($HTML_VERSION > 2.0 && ( 11667 /\\begin\s*($O\d+$C)\s*((super)?tabular|longtable)\s*\1/))) { 11668 $_ = &translate_environments($_); 11669 ($_,$anchors) = &extract_labels($_); # extract labels 11670 do { local($contents) = $_; 11671 &extract_captions($cap_env); $_ = $contents; 11672 } if (/\\caption/); 11673 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11674 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11675 $_ = &translate_commands($_); 11676 while ($_ =~ s/(^\s*<BR>\s*|\s*<BR>\s*$)//g){}; 11677 } else { 11678 # Make an image of the whole environment. 11679 ($_,$anchors) = &extract_labels($_); # extract labels 11680 do { local($contents) = $_; 11681 &extract_captions($cap_env); $_ = $contents; 11682 } if (/\\caption/); 11683 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11684 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11685 $_ = &process_undefined_environment($env, $id, $_); 11686 $_ = &post_latex_do_env_table($_); 11687 $_ =~ s/\s*<BR>\s*$//g; 11688 } 11689 11690 if ($captions) { 11691 # MRO: replaced $* with /m 11692 $captions =~ s/^\n//m; 11693 $captions =~ s/\n$//m; 11694 } 11695 s/$caption_mark//g; 11696 11697 local($close_tags) = &close_all_tags; 11698 $_ .= $close_tags; 11699 11700 # when $captions remain place all the pieces inside a TABLE, if available 11701 if ($HTML_VERSION > 2.1) { 11702 if ($captions) { 11703 $halign = 'CENTER' unless $halign; 11704 local($table) = '<TABLE'; 11705 if ($border) { $table .= " BORDER=\"$border\"" } # no checking !! 11706 $table .= ">"; 11707 join ('', "<BR><P></P>\n<DIV$env_id ALIGN=\"$halign\">" 11708 , "$anchors$cap_anchors\n$table\n<CAPTION", $cap_align, '>' 11709 , $captions , "</CAPTION>\n<TR><TD>" 11710 , $_ , "</TD></TR>\n</TABLE>\n</DIV><P></P><BR>" ) 11711 } elsif ($halign) { 11712 if ($halign) { 11713 # MRO: replaced $* with /m 11714 s/^\s*(<(P|DIV)$env_id ALIGN=\"\w+[^>]+>)/$1$anchors/m 11715 if ($anchors); 11716 join('', "<BR>", $_, "\n<BR>" ) 11717 } else { 11718 join ('', "<BR>\n$anchors", $_ , "\n<BR>" ) 11719 } 11720 } else { 11721 join ('', "<BR><P></P>\n<DIV$env_id ALIGN=\"CENTER\">$anchors\n", $_ , "\n</DIV><BR>" ) 11722 } 11723 } else { 11724 # MRO: replaced $* with /m 11725 s/^\n//m; 11726 s/\n$//m; 11727 if ($captions) { 11728 join('', "<BR>\n", (($anchors) ? "$anchors" : ''), "$cap_anchors\n$captions\n<BR>" 11729 , "\n<P ALIGN=\"$halign\">", $_, "\n</P><BR>"); 11730 } elsif ($halign) { 11731 join ('', "<BR><P></P>\n$anchors", $_ , "\n<P></P>" ) 11732 } else { 11733 join('', "<BR>\n<P ALIGN=\"CENTER\">$anchors\n", $_, "\n</P><BR>"); 11734 } 11735 } 11736} 11737 11738sub do_env_tablestar { &do_env_table(@_) } 11739 11740# RRM: A makeimage environment generates a picture of its entire contents, 11741# UNLESS it is empty. 11742# 11743sub do_env_makeimage { 11744 local($_) = @_; 11745 local($attribs, $border); 11746 s/^\s*//; 11747 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11748 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11749 if (/^((\\begin\s*(($O|$OP)\d+($C|$CP))tex2html_deferred\3)?\\par(\\end(($O|$OP)\d+($C|$CP))tex2html_deferred\7)?\%?\s*\n)+$/s) { return("\n<BR>\n") } 11750 if (/^(\s\%?\n)+$/s) { return() } 11751 $_ = &process_undefined_environment($env, $id, $_); 11752 if (($border||($attributes))&&($HTML_VERSION > 2.1 )) 11753 { $_ = &make_table( $border, $attribs, '', '', '', $_ ) } 11754 $_ . ((!$_=~/^\s*$/)? "\n<BR>\n" :''); 11755} 11756 11757sub do_env_abstract { &make_abstract($_[0]) } 11758 11759sub do_env_minipage { 11760 local($_) = @_; 11761 &get_next_optional_argument; 11762 local($width); 11763 $width = &missing_braces unless ( 11764 (s/$next_pair_pr_rx/$width=$2;''/e) 11765 ||(s/$next_pair_rx/$width=$2;''/e)); 11766 local($pxs,$len) = &convert_length($width,$MATH_SCALE_FACTOR) if $width; 11767 $width = " WIDTH=\"$pxs\""; 11768 11769 local ( %mpfootnotes, $mpfootnotes ) unless ($MINIPAGE); 11770 local ( $border, $attribs, $footfile); 11771 $global{'mpfootnote'} = 0 unless ($MINIPAGE); 11772 $MINIPAGE++; 11773 print "\n *** doing minipage *** " if ($VERBOSITY > 1); 11774 local($open_tags_R) = [ @$open_tags_R ]; 11775 local($close_tags,$reopens) = &close_all_tags(); 11776 local(@save_open_tags) = @$open_tags_R; 11777 11778 local($minipage_caption) if $cap_env; 11779 if ($cap_env &&($HTML_VERSION>2.1)) { 11780 do { 11781 local($captions); 11782 local($contents) = $_; 11783 &extract_captions($cap_env) if ($_ =~ /\\caption/m); 11784 $minipage_caption = $captions; 11785 $_ = $contents; 11786 undef $contents; undef $captions; 11787 }; 11788 } 11789 11790 if (s/^\s*$htmlborder_rx//so) { 11791 $attribs = $2; $border = (($4)? "$4" : 1) 11792 } elsif (s/^\s*$htmlborder_pr_rx//so) { 11793 $attribs = $2; $border = (($4)? "$4" : 1) 11794 } 11795 if (/^\s*\\/) { 11796 local($tmp) = ++$global{'max_id'}; 11797 $_ = $O.$tmp.$C.$_.$O.$tmp.$C 11798 } 11799 $_ = &translate_environments($_); 11800 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11801 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11802 $_ = &translate_commands($_); 11803 $MINIPAGE--; $MINIPAGE='' if ($MINIPAGE==0); 11804 11805 $_ .= &balance_tags(); 11806 $attribs .= $width unless ($attribs =~ /WIDTH/i); 11807# if (($border||$attribs)&&$MINIPAGE&&($HTML_VERSION>2.1)) { 11808 if (($border||$attribs||$env_id)&&$MINIPAGE&&($HTML_VERSION>2.1)) { 11809 $_ = &make_table( $border, $attribs, '', '', '', $_ ); 11810 } elsif ($MINIPAGE) { 11811 $_ = join ('', '<BR><HR>', $_ , '<BR><HR><BR>' ); 11812 } elsif (($border||($attribs)||$minipage_caption)&&($HTML_VERSION > 2.1 )) { 11813 $mpfootnotes = '<DL>'.$mpfootnotes.'</DL>' if $mpfootnotes; 11814 $_ = &make_table( $border, $attribs, '', $mpfootnotes, '', $_ ); 11815 $_ = join('','<BR><HR' 11816 , (($HTML_VERSION > 3.0)? ' WIDTH="50\%" ALIGN="CENTER"' : '') 11817 , '>', $_ , '<BR><HR' 11818 , (($HTML_VERSION > 3.0)? ' WIDTH="50\%" ALIGN="CENTER"' : '') 11819 , '><BR>') unless ($border||$attribs||$mpfootnotes); 11820 } else { 11821 $global{'mpfootnote'} = 0; 11822 if ($mpfootnotes) { 11823 $mpfootnotes = '<DD>'.$mpfootnotes unless ($mpfootnotes =~ /^\s*<D(T|D)>/); 11824 $_ = join('','<BR><HR>', $_ , '<BR><HR' 11825 , (($HTML_VERSION > 3.0)? ' WIDTH="200" ALIGN="LEFT"' : '') 11826 , '><DL>', $mpfootnotes , '</DL><HR><BR' 11827 , (($HTML_VERSION > 3.0)? ' CLEAR="all"' : '') 11828 , '>' ); 11829 } else { 11830 $_ = join ('', '<BR><HR><P></P>', $_ , '<BR><HR><BR>' ); 11831 } 11832 } 11833 join('', $close_tags, $_, $reopens); 11834} 11835 11836if (($HTML_VERSION > 2.1)&&($HTML_VERSION < 4.0)) { 11837 $TABLE_attribs = ",ALIGN,"; 11838 $TABLE__ALIGN = ",left,right,center,"; 11839 $TABLE_attribs_rx_list = ",CELLPADDING,BORDER,WIDTH,CELLSPACING,"; 11840 $TABLE__WIDTH_rx = "\^\\d+%?"; 11841 $TABLE__BORDER_rx = $TABLE__CELLSPACING_rx = $TABLE__CELLPADDING_rx = "\^\\d+"; 11842} 11843 11844sub make_table { 11845 local($border, $attribs, $anchors, $extra_cell, $halign, $_) = @_; 11846 local($table,$caption,$div,$end,$Tattribs); 11847 $caption = join('',"<CAPTION$cap_align>" 11848 , $minipage_caption 11849 ,'</CAPTION>') if ($minipage_caption); 11850 $end = "</TD></TR>\n</TABLE>"; 11851 $table = join('', "<TABLE$env_id" 11852 , ((($caption)&&!($attribs =~/WIDTH/i)) ? " WIDTH=\"100\%\"" : '') 11853 , ((($border)&&!($attribs =~/BORDER/i)) ? " BORDER=\"$border\"" : '') 11854 ); 11855 if ($attribs) { 11856 if (!($attribs =~ /=/)) { 11857 $Tattribs = &parse_valuesonly($attribs,"TABLE"); 11858 } else { 11859 $Tattribs = &parse_keyvalues($attribs,"TABLE"); 11860 } 11861 $table .= " $Tattribs" if ($Tattribs); 11862 } 11863 print STDOUT "\nTABLE: $table>" if ($VERBOSITY >2 ); 11864 $table .= ">".$caption."\n<TR><TD>"; 11865 if ($extra_cell) { 11866 local($sep) = "</TD></TR>\n<TR ALIGN=\"LEFT\">\n<TD>"; 11867 join ('', $div, $anchors, $table, $_ , $sep, $extra_cell, $end ); 11868 } else { 11869 join ('', $div, $anchors, $table, $_ , $end ); 11870 } 11871} 11872 11873sub do_cmd_etalchar { 11874 local($_) = @_; 11875 my $etalchar; 11876 $etalchar = &missing_braces unless ( 11877 (s/$next_pair_pr_rx/$etalchar = $2;''/eo) 11878 ||(s/$next_pair_rx/$etalchar = $2;''/eo)); 11879 $etalchar = &translate_commands($etalchar) if ($etalchar =~ /\\/); 11880 if ($HTML_VERSION < 3.0) { 11881 $etalchar = &process_in_latex("\$^\{$etalchar\}\$"); 11882 } else { 11883 $etalchar = '<SUP>'.$etalchar.'</SUP>'; 11884 } 11885 $etalchar . $_ 11886} 11887 11888sub do_env_thebibliography { 11889 # Sets $citefile and $citations defined in translate 11890 local($_) = @_; 11891 $bibitem_counter = 0; 11892 $citefile = $CURRENT_FILE; 11893 $citefiles{$bbl_nr} = $citefile; 11894 local($dummy,$title); 11895 $dummy = &missing_braces unless ( 11896 (s/$next_pair_pr_rx/$dummy=$2;''/e) 11897 ||(s/$next_pair_rx/$dummy=$2;''/e)); 11898 # MRO: replaced $* with /m 11899 s/^\s*$//gm; # Remove empty lines (otherwise will have paragraphs!) 11900 s/^\s*//m; 11901 11902 # Replace non-breaking spaces, particularly in author names. 11903# s/([^\\])~/$1 /g; # Replace non-breaking spaces. 11904 11905 $_ = &translate_environments($_); 11906 $_ = &translate_commands($_); 11907 11908 # RRM: collect all anchors from initial \label and \index commands 11909 local($anchors) = &extract_anchors('',1); 11910 $_ = '<DD>'.$_ unless ($_ =~ /^\s*<D(T|D)>/); 11911 $citations = join('',"<DL COMPACT>", $_, "</DL>"); 11912 $citations{$bbl_nr} = $citations; 11913 local($br_id); 11914 if ((defined &do_cmd_bibname)||$new_command{'bibname'}) { 11915 $br_id=++$global{'max_id'}; 11916 $title = &translate_environments("$O$br_id$C\\bibname$O$br_id$C"); 11917 } else { $title = $bib_title } 11918 if (! $title ) { 11919 if ((defined &do_cmd_refname)||$new_command{'refname'}) { 11920 $br_id=++$global{'max_id'}; 11921 $title = &translate_environments("$O$br_id$C\\refname$O$br_id$C"); 11922 } else { $title = $ref_name } 11923 } 11924 local($closures,$reopens) = &preserve_open_tags(); 11925 $toc_sec_title = $title ; 11926 local $bib_head = $section_headings{'bibliography'}; 11927 $_ = join('', $closures 11928 , &make_section_heading($title, $bib_head, $anchors) 11929 , "$bbl_mark#$bbl_nr#" , $reopens ); 11930 $bbl_nr++ if $bbl_cnt > 1; 11931 $_ =~ s/;SPMnbsp;/ /g; # replace non-breaking spaces with real ones 11932 $_; 11933} 11934 11935# IGNORE - We construct our own index 11936sub do_env_theindex { "" } 11937 11938# This is defined in html.sty 11939sub do_env_comment { "" } 11940 11941 11942sub do_env_equation{ 11943 local($_)=@_; 11944 local($attribs, $border, $no_num); 11945 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11946 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11947 if (/\\nonumber/) { 11948 $no_num = 1; 11949 $_ = &process_undefined_environment($env,$id,$_); 11950 } else { 11951 $latex_body .= join('', "\n\\setcounter{equation}{" 11952 , $global{'eqn_number'}, "}\n"); 11953 11954 #include equation-number into the key, with HTML 2.0 11955# $_ = join("\n", "%EQNO:".$global{'eqn_number'}, $_) 11956 $_ .= "%EQNO:".$global{'eqn_number'}."\n" if ($HTML_VERSION < 2.2); 11957 11958 $_ = &process_undefined_environment($env,$id,$_); 11959 $global{'eqn_number'}++; 11960 local($save) = $_; 11961 $_ = join('', $save, &post_latex_do_env_equation($eqno_prefix)); 11962 } 11963 if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 11964 join('',"<BR>\n<DIV$env_id ALIGN=\"CENTER\">\n" 11965 , &make_table( $border, $attribs, '', '', '', $_ ) 11966 , "\n<BR CLEAR=\"ALL\">"); 11967 } elsif ($HTML_VERSION < 2.2 ) { 11968 join('', "\n<P>", $_ , "\n<BR></P>" ) 11969 } elsif ($HTML_VERSION > 2.1 ) { 11970 join('', "\n<P ALIGN=" 11971 , ((!$no_num &&($EQN_TAGS =~ /L/))? 11972 '"LEFT"':($no_num ?'"CENTER"':'"RIGHT"')) 11973 , '>', $_ , "\n<BR></P>" ) 11974 } else { $_ } 11975} 11976 11977sub do_env_eqnarray{ 11978 local($_)=@_; 11979 local($attribs, $border, $no_num); 11980 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11981 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11982 local($contents) = $_; 11983# $_ = join("\n", "%EQNO:".$global{'eqn_number'}, $_) 11984# if ($HTML_VERSION < 3.2); #include equation-number into the key. 11985 $_ .= "%EQNO:".$global{'eqn_number'}."\n" if ($HTML_VERSION < 2.2); 11986 $_ = &process_undefined_environment($env,$id,$_); 11987 $_ .= &post_latex_do_env_eqnarray($eqno_prefix,$contents); 11988 if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 11989 join('',"<BR>\n<DIV ALIGN=\"CENTER\">\n" 11990 , &make_table( $border, $attribs, '', '', '', $_ ) 11991 , "\n<BR CLEAR=\"ALL\">"); 11992 } elsif ($HTML_VERSION < 2.2 ) { 11993 join('', "\n<P>", $_ , "\n<BR></P>" ) 11994 } elsif ($HTML_VERSION > 3.1 ) { 11995 join('',"<BR>\n<DIV ALIGN=\"CENTER\">\n", $_ 11996 , "\n</DIV><BR CLEAR=\"ALL\">" ); 11997 } else { 11998 join('', "\n<P ALIGN=" 11999 , (($EQN_TAGS =~ /L/)? '"LEFT"' : '"RIGHT"') 12000 , '>' , $_ , "\n<BR></P>" ) 12001 } 12002} 12003 12004#RRM: these are needed with later versions, when {eqnarray} 12005# environments are split into <TABLE> cells. 12006 12007sub protect_array_envs { 12008 local($_) = @_; 12009 local($cnt, $arraybit, $thisbit, $which) = (0,'','',''); 12010 # MRO: replaced $* with /m 12011 while (/\\(begin|end)\s*(<(<|#)\d+(#|>)>)($sub_array_env_rx)(\*|star)?\2/m ) { 12012 $thisbit = $` . $&; $_ = $'; $which = $1; 12013 do { 12014 # mark rows/columns in nested arrays 12015 $thisbit =~ s/;SPMamp;/$array_col_mark/g; 12016 $thisbit =~ s/\\\\/$array_row_mark/g; 12017 $thisbit =~ s/\\text/$array_text_mark/g; 12018 $thisbit =~ s/\\mbox/$array_mbox_mark/g; 12019 } if ($cnt > 0); 12020 $arraybit .= $thisbit; 12021 if ($which =~ /begin/) {$cnt++} else {$cnt--}; 12022 } 12023 $_ = $arraybit . $_; 12024 12025 local($presub,$thisstack) = ''; 12026 for (;;) { 12027 # find \\s needing protection within \substack commands 12028 # a while-loop is simpler syntax, but uses longer strings 12029 if ( /(\\substack\s*(<(<|#)\d+(#|>)>)(.|\n)*)\\\\((.|\n)*\2)/m ) { 12030 $presub .= $`; $thisstack =$1.${array_row_mark}.$6; $_ = $'; 12031 # convert all \\s in the \substack 12032 $thisstack =~ s/\\\\/${array_row_mark}/og; 12033 $presub .= $thisstack; 12034 } else { last } 12035 } 12036 $_ = $presub . $_ if ($presub); 12037 $_; 12038} 12039 12040sub revert_array_envs { 12041 local($array_contents) = @_; 12042 $array_contents =~ s/$array_col_mark/$html_specials{'&'}/go; 12043 $array_contents =~ s/$array_row_mark/\\\\/go; 12044 $array_contents =~ s/$array_text_mark/\\text/go; 12045 $array_contents =~ s/$array_mbox_mark/\\mbox/go; 12046 $array_contents; 12047} 12048 12049 12050 12051sub do_env_tabbing { 12052 local($_) = @_; 12053 local($attribs, $border); 12054 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 12055 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 12056 $_ = &tabbing_helper($_); 12057 if (/$image_mark/) { 12058 local($tab_warning) = 12059 "*** Images are not strictly valid within HTML <pre> tags\n" 12060 . "Please change your use of {tabbing} to a {tabular} environment.\n\n"; 12061 &write_warnings("\n".$tab_warning); 12062 print "\n\n **** invalid tabbing environment ***\n"; 12063 print $tab_warning; 12064 } 12065 if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 12066 join('',"<BR>\n<DIV$env_id ALIGN=\"CENTER\">\n" 12067 , &make_table( $border, $attribs, '', '', '', $_ ) 12068 , "\n</DIV><BR CLEAR=\"ALL\">"); 12069 } else { $_ } 12070} 12071 12072sub tabbing_helper { 12073 local($_) = @_; 12074 s/\\=\s*//go; # cannot alter the tab-stops 12075 s/\t/ /g; # convert any tabs to spaces 12076 # MRO: replaced $* with /m 12077 s/(^|\n)[^\n]*\\kill *\n/\n/gm; 12078 s/( )? *\n/$1/gm; # retain at most 1 space for a \n 12079 # replace \\ by \n ... , ignoring any trailing space 12080# s/\\\\ */\n/gm; 12081 # ...but make sure successive \\ do not generate a <P> tag 12082# s/\n( *)?\n/\n \n/gm; 12083 s/\\\>//go; 12084 s/(^| *([^\\]))\\[>]/$2\t\t/go; 12085 s/([^\\])\\>/$1\t\t/go; 12086 s/\n$//; s/^\n//; # strip off leading/trailing \n 12087 local($inside_tabbing) = 1; 12088 $_ = &translate_commands(&translate_environments($_)); 12089 "<PRE><TT>\n$_\n</TT></PRE>"; 12090} 12091 12092################# Post Processing Latex Generated Images ################ 12093 12094# A subroutine of the form post_latex_do_env_<ENV> can be used to 12095# format images that have come back from latex 12096 12097# Do nothing (avoid the paragraph breaks) 12098sub post_latex_do_env_figure { $_[0] } 12099sub post_latex_do_env_figurestar { &post_latex_do_env_figure(@_) } 12100 12101sub post_latex_do_env_table { $_[0] } 12102sub post_latex_do_env_tablestar { &post_latex_do_env_table(@_) } 12103 12104sub post_latex_do_env_equation { 12105 local($prefix) = @_; 12106 $global{'eqn_number'}+=1; 12107 # include equation number at the side of the image -- HTML 3.2 12108 if ($HTML_VERSION >= 3.2){ 12109 join('',"<P ALIGN=\"" , (($EQN_TAGS eq "L") ? "left" : "right") 12110 , "\">$EQNO_START" , $prefix 12111 , &translate_commands('\theequation') 12112 , "$EQNO_END</P>\n<BR CLEAR=\"all\">" ); 12113 # </P> creates unwanted space in some browsers, but others need it. 12114 } else { "" } 12115} 12116 12117sub do_cmd_theequation { 12118 if ($USING_STYLES) { 12119 $txt_style{'eqn-number'} = " " unless ($txt_style{'eqn-number'}); 12120 join('', "<SPAN CLASS=\"eqn-number\">" 12121 ,&get_counter_value('eqn_number'),"</SPAN>", $_[0]); 12122 } else { join('',&get_counter_value('eqn_number'), $_[0]); } 12123} 12124 12125sub post_latex_do_env_eqnarray { 12126 local($prefix,$body) = @_; 12127 local($num_string,$line,@lines) = ''; 12128 local($side) = (($EQN_TAGS eq "L") ? "\"left\"" : "\"right\"" ); 12129 # MRO: replaced $* with /m 12130 @lines = split(/\\\\\\\\/m, $body); 12131 $line = pop(@lines); 12132 if (!($line=~/^\s*$/)&&!($line =~/\\nonumber/)) { 12133 $global{'eqn_number'}++; 12134 $num_string .= join('', "<BR><BR>\n" , $EQNO_START , $prefix 12135 , &translate_commands('\theequation') 12136 , $EQNO_END); 12137 } 12138 foreach $line (@lines) { 12139 next if ($line=~/^\s*$/); 12140 $num_string .= "\n<BR>". (($MATH_SCALE_FACTOR > 1.3)? '<BR>' : '') 12141 . "<BR CLEAR=$side>"; 12142 if (!($line =~/\\(nonumber|(no)?tag)/)) { 12143 $global{'eqn_number'}+=1; 12144 $num_string .= join('', $EQNO_START , $prefix 12145 , &translate_commands('\theequation') 12146 , $EQNO_END); 12147 } 12148 } 12149 # include equation numbers at the side of the image -- HTML 3.2 12150 if ($HTML_VERSION >= 3.2){ 12151 "<P ALIGN=\"" . (($EQN_TAGS eq "L") ? "left" : "right") 12152 . "\">" . (($DISP_SCALE_FACTOR >= 1.2 ) ? '<BIG>' : '') 12153 . ${num_string} 12154 . (($DISP_SCALE_FACTOR >= 1.2 ) ? '</BIG>' : '') 12155 . "</P>\n<BR CLEAR=\"all\">" 12156 # </P> creates unwanted space in some browsers, but others need it. 12157 } else { "" }; 12158} 12159 12160sub post_latex_do_env_eqnarraystar { 12161 local($_) = @_; 12162 if (($HTML_VERSION >= 3.2)&&(!$NO_SIMPLE_MATH)){ 12163 join('', "<BR>\n<DIV ALIGN=\"CENTER\">\n" 12164 , $_ , "\n<BR CLEAR=\"ALL\">\n<P>"); 12165 } elsif (($HTML_VERSION >= 2.2)&&(!$NO_SIMPLE_MATH)) { 12166 join('', "\n<BR><P ALIGN=\"CENTER\">\n", $_ , "\n<BR></P>\n<P>"); 12167 } else { 12168 join('', "\n<BR><P>\n", $_ , "\n<BR></P>\n<P>"); 12169 } 12170} 12171 12172############################ Grouping ################################### 12173 12174sub do_cmd_begingroup { $latex_body .= "\n\\begingroup\n"; $_[0] } 12175sub do_cmd_endgroup { $latex_body .= "\\endgroup\n\n"; $_[0] } 12176sub do_cmd_bgroup { $latex_body .= "\n\\bgroup\n"; $_[0] } 12177sub do_cmd_egroup { $latex_body .= "\\egroup\n\n"; $_[0] } 12178 12179sub do_env_tex2html_begingroup { 12180 local($_) = @_; 12181 $latex_body .= "\\begingroup "; 12182 $_ = &translate_environments($_); 12183 $_ = &translate_commands($_); 12184 $latex_body .= "\\endgroup\n"; 12185 $_; 12186} 12187 12188sub do_env_tex2html_bgroup { 12189 local($_) = @_; 12190 $latex_body .= "\\bgroup "; 12191 $_ = &translate_environments($_); 12192 $_ = &translate_commands($_); 12193 $latex_body .= "\\egroup\n"; 12194 $_; 12195} 12196 12197 12198############################ Commands ################################### 12199 12200# Capitalizes what follows the \sc declaration 12201# *** POTENTIAL ERROR **** 12202# (This is NOT the correct meaning of \sc in the cases when it 12203# is followed by another declaration (e.g. \em). 12204# The scope of \sc should be limited to the next occurence of a 12205# declaration. 12206#sub do_cmd_sc { 12207# local($_) = @_; 12208# local(@words) = split(" "); 12209# Capitalize the words which are not commands and do not contain any markers 12210# grep (do {tr/a-z/A-Z/ unless /(^\\)|(tex2html)/}, @words); 12211# grep (do {s/([a-z]+)/<small>\U$1\E<\/small>/g unless /(^\\)|(tex2html)/}, @words); 12212# join(" ", @words); 12213#} 12214sub do_cmd_sc { &process_smallcaps(@_) } 12215sub do_cmd_scshape { &do_cmd_sc(@_) } 12216 12217# This is supposed to put the font back into roman. 12218# Since there is no HTML equivalent for reverting 12219# to roman we keep track of the open font tags in 12220# the current context and close them. 12221# *** POTENTIAL ERROR ****# 12222# This will produce incorrect results in the exceptional 12223# case where \rm is followed by another context 12224# containing font tags of the type we are trying to close 12225# e.g. {a \bf b \rm c {\bf d} e} will produce 12226# a <b> b </b> c <b> d e</b> 12227# i.e. it should move closing tags from the end 12228sub do_cmd_rm { # clean 12229 my ($str, $ot) = @_; 12230 $ot = $open_tags_R unless(defined $ot); 12231 return("<\#rm\#>".$str) if ($inside_tabular); 12232 12233 my ($size,$color,$tags); 12234 while (@$ot) { 12235 my $next = pop (@$ot); 12236 print STDOUT "\n</$next>" if $VERBOSITY > 2; 12237 if ($next =~ /$sizechange_rx/) { 12238 $size = $next unless ($size); 12239 } 12240# if ($next =~ /$colorchange_rx/) { 12241# $color = $next unless ($color); 12242# } 12243 $declarations{$next} =~ m|</.*$|; 12244 $tags .= $& unless ($` =~ /^<>/); 12245 } 12246 if ($size) { 12247 $declarations{$size} =~ m|</.*$|; 12248 $tags .= $` unless ($` =~ /^<>/); 12249 push (@$ot,$size); 12250 print STDOUT "\n<$size>" if $VERBOSITY > 2; 12251 } 12252 $tags.$str; 12253} 12254 12255sub do_cmd_rmfamily{ &do_cmd_rm(@_) } 12256 12257sub do_cmd_textrm { 12258 local($_) = @_; 12259 local($text,$br_id)=('','0'); 12260 $text = &missing_braces unless ( 12261 (s/$next_pair_pr_rx/$text=$2;$br_id=$1;''/eo) 12262 ||(s/$next_pair_rx/$text=$2;$br_id=$1;''/eo)); 12263 join ('' , 12264 &translate_environments("$O$br_id$C\\rm $text$O$br_id$C") 12265 , $_ ); 12266} 12267 12268sub do_cmd_emph { 12269 local($_) = @_; 12270 local($ifstyle,$join_tags) = ('',join(',',@$open_tags_R)); 12271 $join_tags =~ s/(^|,)(text)?(it|rm|normalfont)/$if_style=$3;''/eg; 12272 if ($if_style =~ /it/) { 12273 ($ifstyle,$join_tags) = ('',join(',',@$open_tags_R)); 12274 $join_tags =~ s/(^|,)(text)?(bf|rm|normalfont)/$if_style=$3;''/eg; 12275 if ($if_style =~ /bf/) { &do_cmd_textrm(@_) } 12276 else { &do_cmd_textbf(@_) } 12277 } else { &do_cmd_textit(@_) } 12278} 12279 12280#RRM: These cope with declared commands for which one cannot 12281# simply open a HTML single tag. 12282# The do_cmd_... gets found before the $declaration . 12283 12284sub do_cmd_upshape{&declared_env('upshape',$_[0],$tex2html_deferred)} 12285sub do_cmd_mdseries{&declared_env('mdseries',$_[0],$tex2html_deferred)} 12286sub do_cmd_normalfont{&declared_env('normalfont',$_[0],$tex2html_deferred)} 12287 12288 12289# This is supposed to put the font back into normalsize. 12290# Since there is no HTML equivalent for reverting 12291# to normalsize we keep track of the open size tags in 12292# the current context and close them. 12293sub do_cmd_normalsize { # clean 12294 my ($str, $ot) = @_; 12295 $ot = $open_tags_R unless(defined $ot); 12296 12297 my ($font,$fontwt,$closures,$reopens,@tags); 12298 12299 while (@$ot) { 12300 my $next = pop @$ot; 12301 $declarations{$next} =~ m|</.*$|; 12302 my ($pre,$post) = ($`,$&); 12303 if ($post =~ /$block_close_rx|$all_close_rx/ ) { 12304 push (@$ot, $next); 12305 last; 12306 } 12307 $closures .= $post unless ($pre =~ /^<>/); 12308 print STDOUT "\n</$next>" if $VERBOSITY > 2; 12309 12310 if ($next =~ /$fontchange_rx/) { 12311 $font = $next unless ($font); 12312 } elsif ($next =~ /$fontweight_rx/) { 12313 $fontwt = $next unless ($fontwt); 12314 } elsif ($next =~ /$sizechange_rx/) { 12315 # discard it 12316 } else { 12317 unshift (@tags, $next); 12318 print STDOUT "\n<<$next>" if $VERBOSITY > 2; 12319 $reopens .= $pre unless ($pre =~ /^<>/); 12320 } 12321 } 12322 push (@$ot, @tags); 12323 if ($font) { 12324 $declarations{$font} =~ m|</.*$|; 12325 $reopens .= $` unless ($` =~ /^<>/); 12326 push (@$ot,$font); 12327 print STDOUT "\n<$font>" if $VERBOSITY > 2; 12328 } 12329 if ($fontwt) { 12330 $declarations{$fontwt} =~ m|</.*$|; 12331 $reopens .= $` unless ($` =~ /^<>/); 12332 push (@$ot,$fontwt); 12333 print STDOUT "\n<$fontwt>" if $VERBOSITY > 2; 12334 } 12335 join('', $closures, $reopens, $str); 12336} 12337 12338 12339 12340#JCL(jcl-tcl) 12341# changed everything 12342# 12343sub do_cmd_title { 12344 local($_) = @_; 12345 &get_next_optional_argument; 12346 local($making_title,$next) = (1,''); 12347 $next = &missing_braces unless ( 12348 (s/$next_pair_pr_rx/$next = $2;''/eo) 12349 ||(s/$next_pair_rx/$next = $2;''/eo)); 12350 $t_title = &translate_environments($next); 12351 $t_title = &translate_commands($t_title); 12352# $toc_sec_title = &simplify(&translate_commands($next)); 12353 $toc_sec_title = &purify(&translate_commands($next)); 12354 $TITLE = (($toc_sec_title)? $toc_sec_title : $default_title) 12355 unless ($TITLE && !($TITLE =~ /^($default_title|\Q$FILE\E)$/)); 12356# $TITLE = &purify($TITLE); 12357 12358 #RRM: remove superscripts inserted due to \thanks 12359 $TITLE =~ s/<A[^>]*><SUP>\d+<\/SUP><\/A>/$1/g; 12360 $_; 12361} 12362 12363sub do_cmd_author { 12364 local($_) = @_; 12365 &get_next_optional_argument; 12366 my $next; 12367 $next = &missing_braces unless ( 12368 (s/$next_pair_pr_rx/$next = $2;''/seo) 12369 ||(s/$next_pair_rx/$next = $2;''/seo)); 12370 local($after) = $_; 12371 if ($next =~ /\\and/) { 12372 my @author_list = split(/\s*\\and\s*/, $next); 12373 my $t_author, $t_affil, $t_address; 12374 foreach (@author_list) { 12375 $t_author = &translate_environments($_); 12376 $t_author =~ s/\s+/ /g; 12377 $t_author = &simplify(&translate_commands($t_author)); 12378 ($t_author,$t_affil,$t_address) = split (/\s*<BR>s*/, $t_author); 12379 push @authors, $t_author; 12380 push @affils, $t_affil; 12381 push @addresses, $t_address; 12382 } 12383 } else { 12384 $_ = &translate_environments($next); 12385 $next = &translate_commands($_); 12386 ($t_author) = &simplify($next); 12387 ($t_author,$t_affil,$t_address) = split (/\s*<BR>s*/, $t_author); 12388 push @authors, $t_author; 12389 push @affils, $t_affil if $t_affil; 12390 push @addresses, $t_address if $t_address; 12391 } 12392 $after; 12393} 12394 12395sub do_cmd_address { 12396 local($_) = @_; 12397 &get_next_optional_argument; 12398 local($next); 12399 $next = &missing_braces unless ( 12400 (s/$next_pair_pr_rx/$next = $&;''/eo) 12401 ||(s/$next_pair_rx/$next = $&;''/eo)); 12402 ($t_address) = &simplify(&translate_commands($next)); 12403 push @addresses, $t_address; 12404 $_; 12405} 12406 12407sub do_cmd_institute { 12408 local($_) = @_; 12409 &get_next_optional_argument; 12410 local($next); 12411 $next = &missing_braces unless ( 12412 (s/$next_pair_pr_rx/$next = $&;''/eo) 12413 ||(s/$next_pair_rx/$next = $&;''/eo)); 12414 ($t_institute) = &simplify(&translate_commands($next)); 12415 push @affils, $t_institute; 12416 $_; 12417} 12418 12419sub do_cmd_dedicatory { 12420 local($_) = @_; 12421 &get_next_optional_argument; 12422 local($next); 12423 $next = &missing_braces unless ( 12424 (s/$next_pair_pr_rx/$next = $&;''/eo) 12425 ||(s/$next_pair_rx/$next = $&;''/eo)); 12426 ($t_affil) = &simplify(&translate_commands($next)); 12427 push @affils, $t_affil; 12428 $_; 12429} 12430 12431sub do_cmd_email { 12432 local($_) = @_; 12433 local($next,$target)=('','notarget'); 12434 $next = &missing_braces unless ( 12435 (s/$next_pair_pr_rx/$next = $2;''/eo) 12436 ||(s/$next_pair_rx/$next = $2;''/eo)); 12437 local($mail) = &translate_commands($next); 12438 ($t_email) = &make_href("mailto:$mail","$mail"); 12439 push @emails, $t_email; 12440 $_; 12441} 12442 12443sub do_cmd_authorURL { 12444 local($_) = @_; 12445 local($next); 12446 $next = &missing_braces unless ( 12447 (s/$next_pair_pr_rx/$next = $2;''/eo) 12448 ||(s/$next_pair_rx/$next = $2;''/eo)); 12449 ($t_authorURL) = &translate_commands($next); 12450 push @authorURLs, $t_authorURL; 12451 $_; 12452} 12453 12454sub do_cmd_date { 12455 local($_) = @_; 12456 local($next); 12457 $next = &missing_braces unless ( 12458 (s/$next_pair_pr_rx/$next = $&;''/eo) 12459 ||(s/$next_pair_rx/$next = $&;''/eo)); 12460 ($t_date) = &translate_commands($next); 12461 $_; 12462} 12463 12464sub make_multipleauthors_title { 12465 local($alignc, $alignl) = (@_); 12466 local($t_author,$t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL) 12467 = ('','','','','','',''); 12468 local ($t_title,$auth_cnt) = ('',0); 12469 if ($MULTIPLE_AUTHOR_TABLE) { 12470 $t_title = '<TABLE' .($USING_STYLES? ' CLASS="author_info_table"' : '') 12471 .' WIDTH="90%" ALIGN="CENTER" CELLSPACING=15>' 12472 ."\n<TR VALIGN=\"top\">"; 12473 } 12474 foreach $t_author (@authors) { 12475 $t_affil = shift @affils; 12476 $t_institute = ''; # shift @institutes; 12477 $t_address = shift @addresses; 12478 $t_email = shift @emails; 12479 $t_authorURL = shift @authorURLs; 12480 if ($MULTIPLE_AUTHOR_TABLE) { 12481 if ($auth_cnt == $MAX_AUTHOR_COLS) { 12482 $t_title .= join("\n", '</TR><TR>', ''); 12483 $auth_cnt -= $MAX_AUTHOR_COLS; 12484 } 12485 $t_title .= join("\n" 12486 , '<TD>' 12487 , &make_singleauthor_title($alignc, $alignl ,$t_author 12488 , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL) 12489 , '</TD>' ); 12490 ++$auth_cnt; 12491 } else { 12492 $t_title .= &make_singleauthor_title($alignc, $alignl ,$t_author 12493 , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL); 12494 } 12495 } 12496 if ($MULTIPLE_AUTHOR_TABLE) { 12497 $t_title .= "\n</TR></TABLE>\n"; 12498 } 12499 $t_title; 12500} 12501 12502sub do_cmd_maketitle { 12503 local($_) = @_; 12504 local($the_title) = ''; 12505 local($alignc, $alignl); 12506 if ($HTML_VERSION > 2.1) { 12507 $alignc = " ALIGN=\"CENTER\""; 12508 $alignl = " ALIGN=\"LEFT\""; 12509 $alignl = $alignc if ($MULTIPLE_AUTHOR_TABLE); 12510 } 12511 if ($t_title) { 12512 $the_title .= "<H1$alignc>$t_title</H1>"; 12513 } else { &write_warnings("\nThis document has no title."); } 12514 if (($#authors >= 1)||$MULTIPLE_AUTHOR_TABLE) { 12515 $the_title .= &make_multipleauthors_title($alignc,$alignl); 12516 if ($t_date&&!($t_date=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12517 $the_title .= "\n<P$alignc><STRONG>$t_date</STRONG></P>";} 12518 } else { 12519 $the_title .= &make_singleauthor_title($alignc,$alignl ,$t_author 12520 , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL); 12521 } 12522 $the_title . $_ ; 12523} 12524 12525sub make_singleauthor_title { 12526 local($alignc, $alignl , $t_author 12527 , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL) = (@_); 12528 my $t_title = ''; 12529 my ($s_author_info, $e_author_info) = ('<DIV','</DIV>'); 12530 $s_author_info .= ($USING_STYLES ? ' CLASS="author_info"' : '').'>'; 12531 12532 if ($t_author) { 12533 if ($t_authorURL) { 12534 local($href) = &translate_commands($t_authorURL); 12535 $href = &make_named_href('author' 12536 , $href, "<STRONG>${t_author}</STRONG>"); 12537 $t_title .= "\n<P$alignc>$href</P>"; 12538 } else { 12539 $t_title .= "\n<P$alignc><STRONG>$t_author</STRONG></P>"; 12540 } 12541 } else { &write_warnings("\nThere is no author for this document."); } 12542 12543 if ($t_institute&&!($t_institute=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12544 $t_title .= "\n<P$alignc><SMALL>$t_institute</SMALL></P>";} 12545 if ($t_affil&&!($t_affil=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12546 $t_title .= "\n<P$alignc><I>$t_affil</I></P>";} 12547 if ($t_date&&!($t_date=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12548 $t_title .= "\n<P$alignc><STRONG>$t_date</STRONG></P>";} 12549 if ($t_address&&!($t_address=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12550 $t_title .= "\n<P$alignl><SMALL>$t_address</SMALL></P>"; 12551 } # else { $t_title .= "\n<P$alignl>"} 12552 if ($t_email&&!($t_email=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12553 $t_title .= "\n<P$alignl><SMALL>$t_email</SMALL></P>"; 12554 } # else { $t_title .= "</P>" } 12555 join("\n", $s_author_info, $t_title, $e_author_info); 12556} 12557 12558sub do_cmd_abstract { 12559 local($_) = @_; 12560 local($abstract); 12561 $abstract = &missing_braces unless ( 12562 (s/$next_pair_pr_rx/$abstract = $&;''/eo) 12563 ||(s/$next_pair_rx/$abstract = $&;''/eo)); 12564 join('', &make_abstract($abstract), $_); 12565} 12566 12567sub make_abstract { 12568 local($_) = @_; 12569 # HWS Removed emphasis (hard to read) 12570 $_ = &translate_environments($_); 12571 $_ = &translate_commands($_); 12572 local($title); 12573 if ((defined &do_cmd_abstractname)||$new_command{'abstractname'}) { 12574 local($br_id)=++$global{'max_id'}; 12575 $title = &translate_environments("$O$br_id$C\\abstractname$O$br_id$C"); 12576 } else { $title = $abs_title } 12577 local($env_id) = " CLASS=\"ABSTRACT\"" if ($USING_STYLES); 12578 join('',"\n<H3>", $title, ":</H3>\n" 12579 , (($HTML_VERSION > 3)? "<DIV$env_id>" : "<P>"), $_ 12580 , (($HTML_VERSION > 3)? "</DIV>" : "</P>"), "\n<P>"); 12581} 12582 12583sub set_default_language { 12584 # MRO: local($lang,*_) = @_; 12585 my $lang = shift; 12586 push(@language_stack, $default_language); 12587 $default_language = $lang; 12588 $_[0] .= '\popHtmlLanguage'; 12589} 12590 12591sub do_cmd_popHtmlLanguage { 12592 $default_language = pop(@language_stack); 12593 $_[0]; 12594} 12595 12596sub do_cmd_today { 12597 local($lang); 12598 if ($PREAMBLE) { 12599 $lang = $TITLES_LANGUAGE || $default_language ; 12600 } else { 12601 $lang = $current_language || $default_language ; 12602 } 12603 local($today) = $lang . '_today'; 12604 if (defined &$today) { join('', eval "&$today()", $_[0]) } 12605 else { join('', &default_today(), $_[0]) } 12606} 12607 12608sub default_today { 12609 #JKR: Make it more similar to LaTeX 12610 ## AYS: moved french-case to styles/french.perl 12611 my $today = &get_date(); 12612 12613 $today =~ s|(\d+)/0?(\d+)/|$Month[$1] $2, |; 12614 join('',$today,$_[0]); 12615} 12616 12617sub do_cmd_textbackslash { join('','\', $_[0]);} 12618sub do_cmd_textbar { join('','|', $_[0]);} 12619sub do_cmd_textless { join('',';SPMlt;', $_[0]);} 12620sub do_cmd_textgreater { join('',';SPMgt;', $_[0]);} 12621sub do_cmd_textasciicircum { join('','^', $_[0]);} 12622sub do_cmd_textasciitilde { join('','~', $_[0]);} 12623sub do_cmd_textquoteleft { join('','`', $_[0]);} 12624sub do_cmd_textquoteright { join('',''', $_[0]);} 12625 12626sub do_cmd_textcompwordmark { join('','', $_[0]);} 12627sub do_cmd_texttrademark { join('','<SUP><SMALL>TM</SMALL></SUP>', $_[0]);} 12628 12629sub do_cmd_textsubscript { &make_text_supsubscript('SUB',$_[0]);} 12630sub do_cmd_textsuperscript { &make_text_supsubscript('SUP',$_[0]);} 12631 12632sub make_text_supsubscript { 12633 local ($supsub, $_) = (@_); 12634 my $arg = ''; 12635 $arg = &missing_braces unless ( 12636 (s/$next_pair_pr_rx/$arg = $&;''/eo) 12637 ||(s/$next_pair_rx/$arg = $&;''/eo)); 12638 $arg = &translate_commands($arg) if ($arg =~ m!\\!); 12639 join('', "<$supsub>", $arg, "</$supsub>", $_); 12640} 12641 12642sub do_cmd_textcircled { 12643 local ($_) = (@_); 12644 my $arg = ''; 12645 $arg = &missing_braces unless ( 12646 (s/$next_pair_pr_rx/$arg = $&;''/eo) 12647 ||(s/$next_pair_rx/$arg = $&;''/eo)); 12648 my $after = $_; 12649 join('', &process_undefined_environment("tex2html_nomath_inline" 12650 , ++$global{'max_id'} 12651 , "\\vbox{\\kern3pt\\textcircled{$arg}}" ) 12652 , $after ); 12653} 12654 12655# these can be overridded in charset (.pl) extension files: 12656sub do_cmd_textemdash { join('','---', $_[0]);} 12657sub do_cmd_textendash { join('','--', $_[0]);} 12658#sub do_cmd_exclamdown { join('','', $_[0]);} 12659#sub do_cmd_questiondown { join('','', $_[0]);} 12660sub do_cmd_textquotedblleft { join('',"``", $_[0]);} 12661sub do_cmd_textquotedblright { join('',"''", $_[0]);} 12662sub do_cmd_textbullet { join('','*', $_[0]);} 12663sub do_cmd_textvisiblespace { join('','_', $_[0]);} 12664 12665sub do_cmd_ldots { 12666 join('',(($math_mode&&$USE_ENTITY_NAMES) ? ";SPMldots;" : "..."),$_[0]); 12667} 12668 12669sub do_cmd_dots { 12670 join('',(($math_mode&&$USE_ENTITY_NAMES) ? ";SPMldots;" : "..."),$_[0]); 12671} 12672 12673sub do_cmd_hrule { 12674 local($_) = @_; 12675 &ignore_numeric_argument; 12676 #JKR: No need for <BR> 12677 local($pre,$post) = &minimize_open_tags('<HR>'); 12678 join('',$pre,$_); 12679} 12680 12681#sub do_cmd_hrulefill { 12682# "<HR ALIGN=\"right\">\n<BR CLEAR=\"right\">"; 12683#} 12684 12685sub do_cmd_linebreak { 12686 local($num,$dum) = &get_next_optional_argument; 12687 if (($num)&&($num<4)) { return $_[0] } 12688 join('',"<BR>", $_[0]); 12689} 12690 12691sub do_cmd_pagebreak { 12692 local($_) = @_; 12693 local($num,$dum) = &get_next_optional_argument; 12694 if (($num)&&($num<4)) { return($_) } 12695 elsif (/^ *\n *\n/) { 12696 local($after) = $'; 12697 local($pre,$post) = &minimize_open_tags("<BR>\n<P>"); 12698 join('',$pre, $') 12699 } else { $_ } 12700} 12701 12702 12703sub do_cmd_newline { join('',"<BR>", $_[0]); } 12704# this allows for forced newlines in tables, etc. 12705sub do_cmd_endgraf { join('',"<BR>", $_[0]); } 12706 12707sub do_cmd_space { join(''," ",$_[0]); } 12708sub do_cmd_enspace { join('',"\ ",$_[0]); } 12709sub do_cmd_quad { join('',"\ "x4,$_[0]); } 12710sub do_cmd_qquad { join('',"\ "x8,$_[0]); } 12711 12712sub do_cmd_par { 12713 local ($_) = @_; 12714 my ($pre,$post) = &preserve_open_tags(); 12715 my ($spar, $lcode) = ("\n<P", ''); 12716 if (($USING_STYLES) &&(!($default_language eq $TITLES_LANGUAGE))) { 12717 $lcode = &get_current_language(); 12718 $spar .= $lcode if $lcode; 12719 } 12720 join('', $pre, $spar, ">\n",$post,$_); 12721} 12722 12723sub do_cmd_medskip { 12724 local ($_) = @_; 12725 local($pre,$post) = &preserve_open_tags(); 12726 join('',$pre,"\n<P><BR>\n",$post,$_); 12727} 12728 12729sub do_cmd_smallskip { 12730 local ($_) = @_; 12731 local($pre,$post) = &preserve_open_tags(); 12732 join('',$pre,"\n<P></P>\n",$post,$_); 12733} 12734 12735sub do_cmd_bigskip { 12736 local ($_) = @_; 12737 local($pre,$post) = &preserve_open_tags(); 12738 join('',$pre,"\n<P><P><BR>\n",$post,$_); 12739} 12740 12741# MEH: Where does the slash command come from? 12742# sub do_cmd_slash { 12743# join('',"/",$_[0]); 12744#} 12745sub do_cmd_esc_slash { $_[0]; } 12746sub do_cmd_esc_hash { "\#". $_[0]; } 12747sub do_cmd_esc_dollar { "\$". $_[0]; } 12748sub do_cmd__at_ { $_[0]; } 12749sub do_cmd_lbrace { "\{". $_[0]; } 12750sub do_cmd_rbrace { "\}". $_[0]; } 12751sub do_cmd_Vert { "||". $_[0]; } 12752sub do_cmd_backslash { "\\". $_[0]; } 12753 12754#RRM: for subscripts outside math-mode 12755# e.g. in Chemical formulae 12756sub do_cmd__sub { 12757 local($_) = @_; 12758 local($next); 12759 $next = &missing_braces unless ( 12760 (s/$next_pair_pr_rx/$next = $2;''/e) 12761 ||(s/$next_pair_rx/$next = $2;''/e)); 12762 join('',"<SUB>",$next,"</SUB>",$_); 12763} 12764 12765#JCL(jcl-del) - the next two ones must only have local effect. 12766# Yet, we don't have a mechanism to revert such changes after 12767# a group has closed. 12768# 12769sub do_cmd_makeatletter { 12770 $letters =~ s/@//; 12771 $letters .= '@'; 12772 &make_letter_sensitive_rx; 12773 $_[0]; 12774} 12775 12776sub do_cmd_makeatother { 12777 $letters =~ s/@//; 12778 &make_letter_sensitive_rx; 12779 $_[0]; 12780} 12781 12782 12783################## Commands to be processed by Latex ################# 12784# 12785# The following commands are passed to Latex for processing. 12786# They cannot be processed at the same time as normal commands 12787# because their arguments must be left untouched by the translator. 12788# (Normally the arguments of a command are translated before the 12789# command itself). 12790# 12791# In fact, it's worse: it is not correct to process these 12792# commands after we process environments, because some of them 12793# (for instance, \parbox) may contain unknown or wrapped 12794# environments. If math mode occurs in a parbox, the 12795# translate_environments routine should *not* process it, lest 12796# we encounter the lossage outlined above. 12797# 12798# On the other hand, it is not correct to process these commands 12799# *before* we process environments, or figures containing 12800# parboxes, etc., will be mishandled. 12801# 12802# RRM: (added for V97.1) 12803# \parbox now uses the _wrap_deferred mechanism, and has a do_cmd_parbox 12804# subroutine defined. This means that environments where parboxes are 12805# common (.g. within table cells), can detect the \parbox command and 12806# adjust the processing accordingly. 12807# 12808# So, the only way to handle these commands is to wrap them up 12809# in null environments, as for math mode, and let translate_environments 12810# (which can handle nesting) figure out which is the outermost. 12811# 12812# Incidentally, we might as well make these things easier to configure... 12813 12814sub process_commands_in_tex { 12815 local($_) = @_; 12816 local($arg,$tmp); 12817 foreach (/.*\n?/g) { 12818 chop; 12819 # For each line 12820 local($cmd, @args) = split('#',$_); 12821 next unless $cmd; 12822 $cmd =~ s/ //g; 12823 12824 # skip if a proper implementation already exists 12825 $tmp = "do_cmd_$cmd"; 12826 next if (defined &$tmp); 12827 12828 # Build routine body ... 12829 local ($body, $code, $thisone) = ("", ""); 12830 12831 # alter the pattern here to debug particular commands 12832# $thisone = 1 if ($cmd =~ /mathbb/); 12833 12834 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 12835 foreach $arg (@args) { 12836 print "\nARG: $arg" if ($thisone); 12837 print "\nARG: $next_pair_rx" if ($thisone); 12838 if ($arg =~ /\{\}/) { 12839# RRM: the $` is surely wrong, allowing no error-checking. 12840# Use <<...>> for specific patterns 12841# $body .= '$args .= "$`$&" if s/$next_pair_rx//o;'."\n"; 12842 $body .= '$args .= join("","{", &missing_braces, "}") unless ('."\n"; 12843 $body .= ' (s/$next_pair_pr_rx/$args.=$`.$&;""/es)'."\n"; 12844 $body .= ' ||(s/$next_pair_rx/$args.=$`.$&;""/es));'."\n"; 12845 print "\nAFTER:$'" if (($thisone)&&($')); 12846 $body .= $' if ($'); 12847 } elsif ($arg =~ /\[\]/) { 12848 $body .= '($dummy, $pat) = &get_next_optional_argument;' 12849 . '$args .= $pat;'."\n"; 12850 print "\nAFTER:$'" if (($thisone)&&($')); 12851 $body .= $' if ($'); 12852 } elsif ($arg =~ /^\s*\\/) { 12853 $body .= '($dummy, $pat) = &get_next_tex_cmd;' 12854 . '$args .= $pat;'."\n"; 12855 print "\nAFTER:$'" if (($thisone)&&($')); 12856 $body .= $' if ($'); 12857 } elsif ($arg =~ /<<\s*/) { 12858 $arg = $'; 12859 if ($arg =~ /\s*>>/) { 12860 # MRO: replaced $* with /m 12861 $body .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n" 12862# $body .= '$args .= "$`$&" if (/\\\\'.$`.'/);' . "\n" 12863 . "\$_ = \$\';\n"; 12864 print "\nAFTER:$'" if (($thisone)&&($')); 12865 $body .= $' if ($'); 12866 } else { $body .= $arg ; } 12867 } else { 12868 print "\nAFTER:$'" if (($thisone)&&($arg)); 12869 $body .= $arg ; 12870 } 12871 } 12872 12873 # Generate a new subroutine 12874 local($padding) = " "; 12875 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 12876 $code = "sub wrap_cmd_$cmd {" . "\n" 12877 . 'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";' . "\n" 12878 . $body 12879 . (($thisone)? "print STDERR \"\\n$cmd:\".\$args.\"\\n\";\n" : '') 12880 . '(&make_wrapper(1).$cmd' 12881 . ($padding ? '"'.$padding.'"' : '') 12882 . '.$args.&make_wrapper(0), $_)}' 12883 . "\n"; 12884 print "\nWRAP_CMD: $code " if ($thisone); # for debugging 12885 eval $code; # unless ($thisone); 12886 print STDERR "\n*** sub wrap_cmd_$cmd failed: $@" if ($@); 12887 12888 # And make sure the main loop will catch it ... 12889# $raw_arg_cmds{$cmd} = 1; 12890 ++$raw_arg_cmds{$cmd}; 12891 } 12892} 12893 12894sub process_commands_nowrap_in_tex { 12895 local($_) = @_; 12896 local($arg); 12897 foreach (/.*\n?/g) { 12898 chop; 12899 local($cmd, @args) = split('#',$_); 12900 next unless $cmd; 12901 $cmd =~ s/ //g; 12902 # Build routine body ... 12903 local ($bodyA, $codeA, $bodyB, $codeB, $thisone) = ("", "", "", ""); 12904 12905 # alter the pattern here to debug particular commands 12906# $thisone = 1 if ($cmd =~ /epsf/); 12907 12908 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 12909 foreach $arg (@args) { 12910 print "\nARG: $arg" if ($thisone); 12911 if ($arg =~ /\{\}/) { 12912# $bodyA .= '$args .= "$`"."$&" if (s/$any_next_pair_rx//);'."\n"; 12913 $bodyA .= 'if (s/$next_pair_rx//s){$args.="$`"."$&"; $_='."\$'};\n"; 12914 $bodyB .= '$args .= &missing_braces'."\n unless ("; 12915 $bodyB .= '(s/$any_next_pair_pr_rx/$args.=$`.$&;\'\'/eo)'."\n"; 12916 $bodyB .= ' ||(s/$any_next_pair_rx/$args.=$`.$&;\'\'/eo));'."\n"; 12917 print "\nAFTER:$'" if (($thisone)&&($')); 12918# $bodyA .= $'.";\n" if ($'); 12919 $bodyB .= $'.";\n" if ($'); 12920 } elsif ($arg =~ /\[\]/) { 12921 $bodyA .= '($dummy, $pat) = &get_next_optional_argument;' 12922 . '$args .= $pat;'."\n"; 12923 print "\nAFTER:$'" if (($thisone)&&($')); 12924# $bodyA .= $'.";\n" if ($'); 12925 $bodyB .= $'.";\n" if ($'); 12926 } elsif ($arg =~ /^\s*\\/) { 12927 $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;' 12928 . '$args .= $pat;'."\n"; 12929 $bodyB .= '($dummy, $pat) = &get_next_tex_cmd;' 12930 . '$args .= $pat;'."\n"; 12931 print "\nAFTER:$'" if (($thisone)&&($')); 12932 $bodyA .= $'.";\n" if ($'); 12933 $bodyB .= $'.";\n" if ($'); 12934 } elsif ($arg =~ /<<\s*/) { 12935 $arg = $'; 12936 if ($arg =~ /\s*>>/) { 12937 # MRO: replaced $* with /m 12938 $bodyA .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n" 12939# $bodyA .= '$args .= $`.$& if (/\\\\'.$`.'/);' . "\n" 12940 . "\$_ = \$\';\n"; 12941 $bodyB .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n" 12942 . "\$_ = \$\';\n"; 12943 print "\nAFTER:$'" if (($thisone)&&($')); 12944# $bodyA .= $'.";\n" if ($'); 12945 $bodyB .= $'.";\n" if ($'); 12946 } else { 12947 print "\nAFTER:$arg" if (($thisone)&&($arg)); 12948# $bodyA .= $arg.";\n" if ($arg); 12949 $bodyB .= $arg.";\n" if ($arg); 12950 } 12951 } else { 12952 print "\nAFTER:$arg" if (($thisone)&&($arg)); 12953 $bodyA .= '$args .= '.$arg.";\n" if ($'); 12954 $bodyB .= $arg.";\n" if ($'); 12955 } 12956 } 12957 local($padding) = " "; 12958 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 12959 # Generate 2 new subroutines 12960 $codeA = "sub wrap_cmd_$cmd {" . "\n" 12961 .'local($cmd, $_) = @_; local($args, $dummy, $pat) = "";'."\n" 12962 . $bodyA 12963 . (($thisone)? "print \"\\nwrap $cmd:\\n\".\$args.\"\\n\";\n" : '') 12964 . '(&make_nowrapper(1)."\n".$cmd.'."\"$padding\"" 12965 . '.$args.&make_nowrapper(0)," ".$_)}' 12966 ."\n"; 12967 print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging 12968 eval $codeA; 12969 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 12970 $codeB = "do_cmd_$cmd"; 12971 do { 12972 $bodyB = '"";' if !($bodyB); 12973 $codeB = "sub do_cmd_$cmd {" . "\n" 12974 . 'local($_,$ot) = @_;'."\n" 12975 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'."\n" 12976 . 'local($cmd,$args,$dummy,$pat)=("'.$cmd.'","","","");'."\n" 12977 . $bodyB 12978 . (($thisone)? "print \"\\ndo $cmd:\".\$args.\"\\n\";\n" : '') 12979# . '$latex_body.="\\n".&revert_to_raw_tex("'."\\\\$cmd$padding".'$args")."\\n\\n";' 12980 . "\$_;}\n"; 12981 print STDOUT "\nDO_CMD: $codeB " if ($thisone); # for debugging 12982 eval $codeB; 12983 print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@); 12984 } unless (defined &$codeB ); 12985 12986 # And make sure the main loop will catch it ... 12987# $raw_arg_cmds{$cmd} = 1; 12988 ++$raw_arg_cmds{$cmd}; 12989 } 12990} 12991 12992sub process_commands_wrap_deferred { 12993 local($_) = @_; 12994 local($arg,$thisone); 12995 foreach (/.*\n?/g) { 12996 chop; 12997 local($cmd, @args) = split('#',$_); 12998 next unless $cmd; 12999 $cmd =~ s/ //g; 13000 # Build routine body ... 13001 local ($bodyA, $codeA, $bodyB, $codeB, $after, $thisone); 13002 13003 # alter the pattern here to debug particular commands 13004# $thisone = 1 if ($cmd =~ /selectlanguage/); 13005 13006 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 13007 foreach $arg (@args) { 13008 print "\nARG: $arg" if ($thisone); 13009 if ($arg =~ /\{\}/) { 13010# $bodyA .= '$args .= "$`$&" if (s/$any_next_pair_rx//o);'; 13011 $bodyA .= '$args .= "$`$&" if (s/$next_pair_rx//so);'; 13012 $after = $'; 13013 print "\nAFTER:$'" if (($thisone)&&($')); 13014 } elsif ($arg =~ /\[\]/) { 13015 $bodyA .= '($dummy, $pat) = &get_next_optional_argument;' . 13016 "\n". '$args .= $pat;'; 13017 $after = $'; 13018 print "\nAFTER:$'" if (($thisone)&&($')); 13019 } elsif ($arg =~ /^\s*\\/) { 13020 $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;' 13021 . '$args .= $pat;'."\n"; 13022 print "\nAFTER:$'" if (($thisone)&&($')); 13023 $bodyA .= $'.";\n" if ($'); 13024 } elsif (/<<\s*([^>]*)[\b\s]*>>/) { 13025 local($endcmd, $afterthis) = ($1,$'); 13026 $afterthis =~ s/(^\s*|\s*$)//g; 13027 $endcmd =~ s/\\/\\\\/g; 13028 $bodyA .= "\n". 'if (/'.$endcmd.'/) { $args .= $`.$& ; $_ = $\' };'; 13029 $after .= $afterthis if ($afterthis); 13030 print "\nAFTER:$'" if (($thisone)&&($')); 13031 } else { 13032 print "\nAFTER:$arg" if (($thisone)&&($arg)); 13033 $bodyB .= $arg.";\n" ; $after = '' 13034 } 13035 $after =~ s/(^\s*|\s*$)//g if ($after); 13036 $bodyB .= $after . ";" if ($after); 13037 $bodyA .= "\$args .= ".$after . ";" if ($after); 13038 } 13039 local($padding) = " "; 13040 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 13041 # Generate 2 new subroutines 13042 $codeA = "sub wrap_cmd_$cmd {" . "\n" 13043 .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'."\n" 13044 . $bodyA #. ($bodyA ? "\n" : '') 13045 . (($thisone)? ";print \"\\nwrap $cmd:\".\$args.\"\\n\";\n" : '') 13046 .'(&make_deferred_wrapper(1).$cmd.'.$padding 13047 .'$args.&make_deferred_wrapper(0),$_)}' 13048 ."\n"; 13049 print STDERR "\nWRAP_CMD: $codeA " if ($thisone); # for debugging 13050 eval $codeA; 13051 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 13052 13053 #RRM: currently these commands only go to LaTeX or access counters. 13054 # They could be implemented more generally, as below with do_dcmd_$cmd 13055 # requiring replacement to be performed before evaluation. 13056 $codeB = "sub do_dcmd_$cmd {" . "\n" 13057 .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";'."\n" 13058 . $bodyA . "\n" 13059 . (($thisone)? ";print \"\\ndo_def $cmd:\".\$args.\"\\n\";\n" : '') 13060 . $bodyB . "}" . "\n"; 13061 print "\nDEF_CMD: $codeB " if ($thisone); # for debugging 13062 local($tmp) = "do_cmd_$cmd"; 13063 eval $codeB unless (defined &$tmp); 13064 print STDERR "\n\n*** sub do_dcmd_$cmd failed: $@\n" if ($@); 13065 13066 # And make sure the main loop will catch it ... 13067# $raw_arg_cmds{$cmd} = 1; 13068 ++$raw_arg_cmds{$cmd}; 13069 } 13070} 13071 13072sub process_commands_inline_in_tex { 13073 local($_) = @_; 13074 foreach (/.*\n?/g) { 13075 chop; 13076 local($cmd, @args) = split('#',$_); 13077 next unless $cmd; 13078 $cmd =~ s/ //g; 13079 # Build routine body ... 13080 local ($body, $code, $thisone) = ("", ""); 13081 13082 # uncomment and alter the pattern here to debug particular commands 13083# $thisone = 1 if ($cmd =~ /L/); 13084 13085 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 13086 foreach (@args) { 13087 print "\nARG: $_" if ($thisone); 13088 if (/\{\}/) { 13089# $body .= '$args .= $`.$& if (/$any_next_pair_rx/);' . "\n" 13090# . "\$_ = \$\';\n"; 13091 $body .= '$args .= $`.$& if (s/$next_pair_rx//s);' . "\n" 13092 } elsif (/\[\]/) { 13093 $body .= 'local($dummy, $pat) = &get_next_optional_argument;' . 13094 "\n". '$args .= $pat;'; 13095 } elsif ($arg =~ /^\s*\\/) { 13096 $body .= '($dummy, $pat) = &get_next_tex_cmd;' 13097 . '$args .= $pat;'."\n"; 13098 print "\nAFTER:$'" if (($thisone)&&($')); 13099 $body .= $'.";\n" if ($'); 13100 } elsif (/<<\s*/) { 13101 $_ = $'; 13102 if (/\s*>>/) { 13103 # MRO: replaced $* with /m 13104 $body .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n" 13105 . "\$_ = \$\';\n" 13106 } else { $body .= $_.";\n" ; } 13107 } else { $body .= $_.";\n" ; } 13108 } 13109 local($padding) = " "; 13110 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 13111 # Generate a new subroutine 13112 my $itype = ($cmd =~ /^f.*box$/ ? 'inline' : 'nomath'); 13113 $code = "sub wrap_cmd_$cmd {" . "\n" 13114 .'local($cmd, $_) = @_; local ($args) = "";' . "\n" 13115 . $body . "\n" 13116 . (($thisone)? ";print \"\\ndo $cmd:\".\$args.\"\\n\";\n" : '') 13117 .'(&make_'.$itype.'_wrapper(1).$cmd.$padding.$args.' 13118 . '&make_'.$itype.'_wrapper(0),$_)}' 13119 ."\n"; 13120 print "\nWRAP_CMD:$raw_arg_cmds{$cmd}: $code " 13121 if ($thisone); # for debugging 13122 eval $code; 13123 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 13124 # And make sure the main loop will catch it ... 13125# $raw_arg_cmds{$cmd} = 1; 13126 ++$raw_arg_cmds{$cmd}; 13127 } 13128} 13129 13130 13131# Invoked before actual translation; wraps these commands in 13132# tex2html_wrap environments, so that they are properly passed to 13133# TeX in &translate_environments ... 13134# JCL(jcl-del) - new usage of $raw_arg_cmd_rx 13135sub wrap_raw_arg_cmds { 13136 local ($processed_text, $cmd, $wrapper, $wrap, $after); 13137 print "\nwrapping raw arg commands " if ($VERBOSITY>1); 13138 local($seg, $par_wrap, $teststar, @processed); 13139# local(@segments) = split(/\\par\b/,$_); 13140# foreach (@segments) { 13141# $par_wrap = join('',&make_deferred_wrapper(1), "\\par" 13142# , &make_deferred_wrapper(0)); 13143# push(@processed, $par_wrap ) if ($seg); ++$seg; 13144 if (%renew_command) { 13145 local($key); 13146 foreach $key (keys %renew_command) { 13147 $raw_arg_cmds{$key} = 1; 13148 $raw_arg_cmd_rx =~ s/^(\(\)\\\\\()/$1$key\|/; 13149 } 13150 } 13151 print "\n" if (/$raw_arg_cmd_rx/); 13152 13153 # MRO: replaced $* with /m 13154 while (/$raw_arg_cmd_rx/m) { 13155 local($star); 13156 push (@processed, $`); print "\@"; 13157 $after = $'; 13158 #JCL(jcl-del) - status of starred raw arg cmds yet unclear 13159 ($cmd, $star) = ($1.$2,$4); 13160 if ($star eq '*') { $star = 'star';} 13161 else { $after = $star.$after; $star = ''; } 13162 $wrapper = "wrap_cmd_$cmd"; $teststar = $wrapper.'star'; 13163 if ($star && defined &$teststar) { $wrapper = $teststar; $star = '*'; } 13164 # MRO: make {\bf**} work 13165 elsif($star) { $after = '*'.$after; $star = '' } 13166 print "\nWRAPPED: $cmd as $wrapper" if ($VERBOSITY > 5); 13167 13168 # ensure that the result is separated from following words... 13169 my $padding = ($after =~ /^[a-zA-Z]/s)? ($cmd =~ /\W$/ ? '':' '):''; 13170 13171 if ($raw_arg_cmds{$cmd} && defined &$wrapper) { 13172 ($wrap, $_) = &$wrapper("\\$cmd$star", $padding . $after); 13173 # ...but don't leave an unwanted space at the beginning 13174 $_ =~ s/^ //s if($padding && $wrap !~ /\w$/m 13175 && (length($_) == length($after)+1) ); 13176 push (@processed, $wrap); 13177 } elsif ($raw_arg_cmds{$cmd}) { 13178 print STDERR "\n*** $wrapper not defined, cannot wrap \\$cmd"; 13179 &write_warnings("\n*** $wrapper not defined, cannot wrap \\$cmd "); 13180 push (@processed, "\\$cmd$padding"); 13181 $_ = $after; 13182 } else { 13183 push (@processed, "\\$cmd$padding"); 13184 $_ = $after; 13185 } 13186 last unless ($after =~ /\\/); 13187 } 13188 13189 # recombine the pieces 13190 $_ = join('',@processed, $_); 13191} 13192 13193######################################################################### 13194 13195# To make a table of contents, list of figures and list of tables commands 13196# create a link to corresponding files which do not yet exist. 13197# The binding of the file variable in each case acts as a flag 13198# for creating the actual file at the end, after all the information 13199# has been gathered. 13200 13201sub do_cmd_tableofcontents { &do_real_tableofcontents(@_) } 13202sub do_real_tableofcontents { 13203# local($_) = @_; 13204 if ((defined &do_cmd_contentsname)||$new_command{'contentsname'}) { 13205 local($br_id)=++$global{'max_id'}; 13206 $TITLE = &translate_environments("$O$br_id$C\\contentsname$O$br_id$C"); 13207 } else { $TITLE = $toc_title } 13208 $toc_sec_title = $TITLE; 13209 $tocfile = $CURRENT_FILE; # sets $tocfile this globally 13210 local $toc_head = $section_headings{'tableofcontents'}; 13211 if ($toc_style) { 13212 $toc_head .= " CLASS=\"$toc_style\""; 13213 $env_style{"$toc_head.$toc_style"} = " " 13214 unless ($env_style{"$toc_head.$toc_style"}); 13215 } 13216 local($closures,$reopens) = &preserve_open_tags(); 13217 join('', "<BR>\n", $closures 13218 , &make_section_heading($TITLE, $toc_head), $toc_mark 13219 , $reopens, @_[0]); 13220} 13221sub do_cmd_listoffigures { 13222 local($_) = @_; 13223 local($list_type) = ($SHOW_SECTION_NUMBERS ? 'UL' : 'OL' ); 13224 if ((defined &do_cmd_listfigurename)||$new_command{'listfigurename'}) { 13225 local($br_id)=++$global{'max_id'}; 13226 $TITLE = &translate_environments("$O$br_id$C\\listfigurename$O$br_id$C"); 13227 } else { $TITLE = $lof_title } 13228 $toc_sec_title = $TITLE; 13229 $loffile = $CURRENT_FILE; # sets $loffile this globally 13230 local $lof_head = $section_headings{'listoffigures'}; 13231 local($closures,$reopens) = &preserve_open_tags(); 13232 join('', "<BR>\n", $closures 13233 , &make_section_heading($TITLE, $lof_head) 13234 , "<$list_type>", $lof_mark, "</$list_type>" 13235 , $reopens, $_); 13236} 13237sub do_cmd_listoftables { 13238 local($_) = @_; 13239 local($list_type) = ($SHOW_SECTION_NUMBERS ? 'UL' : 'OL' ); 13240 if ((defined &do_cmd_listtablename)||$new_command{'listtablename'}) { 13241 local($br_id)=++$global{'max_id'}; 13242 $TITLE = &translate_environments("$O$br_id$C\\listtablename$O$br_id$C"); 13243 } else { $TITLE = $lot_title } 13244 $toc_sec_title = $TITLE; 13245 $lotfile = $CURRENT_FILE; # sets $lotfile this globally 13246 local $lot_head = $section_headings{'listoftables'}; 13247 local($closures,$reopens) = &preserve_open_tags(); 13248 join('', "<BR>\n", $closures 13249 , &make_section_heading($TITLE, $lot_head) 13250 , "<$list_type>", $lot_mark, "</$list_type>" 13251 , $reopens, $_); 13252} 13253 13254# Indicator for where to put the CHILD_LINKS table. 13255sub do_cmd_tableofchildlinks { 13256 local($_) = @_; 13257 local($thismark) = $childlinks_mark; 13258 local($option,$dum) = &get_next_optional_argument; 13259 $thismark = &check_childlinks_option($option) if ($option); 13260 local($pre,$post) = &minimize_open_tags("$thismark\#0\#"); 13261 join('', "<BR>", $pre, $_); 13262} 13263 13264# leave out the preceding <BR> 13265sub do_cmd_tableofchildlinksstar { 13266 local($_) = @_; 13267 local($thismark) = $childlinks_mark; 13268 local($option,$dum) = &get_next_optional_argument; 13269 $thismark = &check_childlinks_option($option) if ($option); 13270 local($pre,$post) = &minimize_open_tags("$thismark\#1\#"); 13271 join('', $pre, $_); 13272} 13273 13274sub check_childlinks_option { 13275 local($option) = @_; 13276 if ($option =~ /none/i) { 13277 $childlinks_mark = $childlinks_null_mark; 13278 $childlinks_null_mark } 13279 elsif ($option =~ /off/i) { $childlinks_null_mark } 13280 elsif ($option =~ /all/i) { 13281 $childlinks_mark = $childlinks_on_mark; 13282 $childlinks_on_mark } 13283 elsif ($option =~ /on/i) { $childlinks_on_mark } 13284} 13285 13286sub remove_child_marks { 13287 # Modifies $_ 13288 s/($childlinks_on_mark|$childlinks_null_mark)\#\d\#//go; 13289} 13290 13291 13292sub do_cmd_htmlinfo { 13293 local($_) = @_; 13294 local($option,$dum) = &get_next_optional_argument; 13295 if ($option =~ /^(off|none)/i) { $INFO = 0; return ($_) } 13296 local($pre,$post) = &minimize_open_tags($info_title_mark.$info_page_mark); 13297 join('', "<BR>", $pre, $_); 13298} 13299sub do_cmd_htmlinfostar { 13300 local($_) = @_; 13301 local($option,$dum) = &get_next_optional_argument; 13302 if ($option =~ /^(off|none)/i) { $INFO = 0; return ($_) } 13303 local($pre,$post) = &minimize_open_tags($info_page_mark); 13304 join('', $pre, $_); 13305} 13306 13307# $idx_mark will be replaced with the real index at the end 13308sub do_cmd_textohtmlindex { 13309 local($_) = @_; 13310 if ((defined &do_cmd_indexname )||$new_command{'indexname'}) { 13311 local($br_id)=++$global{'max_id'}; 13312 $TITLE = &translate_environments("$O$br_id$C\\indexname$O$br_id$C"); 13313 } else { $TITLE = $idx_title } 13314 $toc_sec_title = $TITLE; 13315 $idxfile = $CURRENT_FILE; 13316 if (%index_labels) { &make_index_labels(); } 13317 if (($SHORT_INDEX) && (%index_segment)) { &make_preindex(); } 13318 else { $preindex = ''; } 13319 local $idx_head = $section_headings{'textohtmlindex'}; 13320 local($heading) = join('' 13321 , &make_section_heading($TITLE, $idx_head) 13322 , $idx_mark ); 13323 local($pre,$post) = &minimize_open_tags($heading); 13324 join('',"<BR>\n" , $pre, $_); 13325} 13326 13327#RRM: added 17 May 1996 13328# allows labels within the printable key of index-entries, 13329# when using makeidx.perl 13330sub make_index_labels { 13331 local($key, @keys); 13332 @keys = keys %index_labels; 13333 foreach $key (@keys) { 13334 if (($ref_files{$key}) && !($ref_files{$key} eq "$idxfile")) { 13335 local($tmp) = $ref_files{$key}; 13336 &write_warnings("\nmultiple label $key , target in $idxfile masks $tmp "); 13337 } 13338 $ref_files{$key} .= "$idxfile"; 13339 } 13340} 13341#RRM: added 17 May 1996 13342# constructs a legend for the SHORT_INDEX, with segments 13343# when using makeidx.perl 13344sub make_preindex { &make_real_preindex } 13345sub make_real_preindex { 13346 local($key, @keys, $head, $body); 13347 $head = "<HR>\n<H4>Legend:</H4>\n<DL COMPACT>"; 13348 @keys = keys %index_segment; 13349 foreach $key (@keys) { 13350 local($tmp) = "segment$key"; 13351 $tmp = $ref_files{$tmp}; 13352 $body .= "\n<DT>$key<DD>".&make_named_href('',$tmp,$index_segment{$key}); 13353# $body .= "\n<DT>$key<DD>".&make_named_href('', 13354# $tmp."\#CHILD\_LINKS",$index_segment{$key}) 13355# unless ($CHILD_STAR); 13356 } 13357 $preindex = join('', $head, $body, "\n</DL>") if ($body); 13358} 13359 13360sub do_cmd_printindex { &do_real_printindex(@_); } 13361sub do_real_printindex { 13362 local($_) = @_; 13363 local($which) = &get_next_optional_argument; 13364 $idx_name = $index_names{$which} 13365 if ($which && $index_names{$which}); 13366 @_; 13367} 13368 13369sub do_cmd_newindex { 13370 local($_) = @_; 13371 local($dum,$key,$title); 13372 $key = &missing_braces unless ( 13373 (s/$next_pair_pr_rx/$key=$2;''/eo) 13374 ||(s/$next_pair_rx/$key=$2;''/eo)); 13375 $dum = &missing_braces unless ( 13376 (s/$next_pair_pr_rx/$dum=$2;''/eo) 13377 ||(s/$next_pair_rx/$dum=$2;''/eo)); 13378 $dum = &missing_braces unless ( 13379 (s/$next_pair_pr_rx/$dum=$2;''/eo) 13380 ||(s/$next_pair_rx/$dum=$2;''/eo)); 13381 $title = &missing_braces unless ( 13382 (s/$next_pair_pr_rx/$title=$2;''/eo) 13383 ||(s/$next_pair_rx/$title=$2;''/eo)); 13384 $index_names{$key} = $title if ($key && $title); 13385 @_; 13386} 13387 13388# FOOTNOTES , also within Mini-page environments 13389# allow easy way to override and inherit; e.g. for frames 13390 13391sub do_cmd_footnotestar { &do_real_cmd_footnote(@_) } 13392sub do_cmd_footnote { &do_real_cmd_footnote(@_) } 13393sub do_real_cmd_footnote { 13394 local($_) = @_; 13395 local($cnt,$marker,$smark,$emark)=('', $footnote_mark); 13396 local($mark,$dum) = &get_next_optional_argument; 13397 local($anchor_name); 13398 13399 $footfile = "${PREFIX}$FOOT_FILENAME$EXTN" 13400 unless ($footfile||$MINIPAGE||$NO_FOOTNODE); 13401 13402 if ($mark) { 13403 $cnt = $mark; 13404 if ($MINIPAGE) { $global{'mpfootnote'} = $cnt } 13405 else { $global{'footnote'} = $cnt } 13406 } else { 13407 $cnt = (($MINIPAGE)? ++$global{'mpfootnote'} : ++$global{'footnote'}); 13408 } 13409 local($br_id, $footnote)=(++$global{'max_id'},''); 13410 $footnote = &missing_braces unless ( 13411 (s/$next_pair_pr_rx/${br_id}=$1; $footnote=$2;''/eo) 13412 ||(s/$next_pair_rx/${br_id}=$1; $footnote=$2;''/eo)); 13413 $br_id = "mp".$br_id if ($MINIPAGE); 13414 $marker = &get_footnote_mark($MINIPAGE); 13415 local($last_word) = &get_last_word(); 13416 local($href) = &make_href("$footfile#foot$br_id",$marker); 13417 if ($href =~ /NAME="([^"]*)"/) { $anchor_name=$1 } 13418 $last_word .= $marker unless ($anchor_name); 13419 &process_footnote($footnote,$cnt,$br_id,$last_word,$mark 13420 ,($MINIPAGE? $marker : '') 13421 ,($MINIPAGE? '' : "$marker:$anchor_name") ); 13422 # this may not work if there is a <BASE> tag and !($file) !!! # 13423# join('',&make_href("$file#foot$br_id",$marker),$_); 13424 $href . $_ 13425} 13426 13427sub process_image_footnote { 13428 # MRO: modified to use $_[0] 13429 # local(*math) = @_; 13430 local($in_image, $keep, $pre, $this_anchor, $out, $foot_counters_recorded, @foot_anchors) = (1,'',''); 13431 local($image_contents) = $_[0]; 13432 $image_contents =~ s/\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_\w+\2//go; 13433 $image_contents =~ s!(\\footnote(mark\b\s*(\[[^\]]*\])?|\s*(\[[^\]]*\])?\s*(($O|$OP)\d+($C|$CP))(.*)\5))! 13434 $keep = $`; $out = '\footnotemark '.$3.$4; 13435 #MRO: $*=1; local($saveRS) = $/; $/=''; 13436 if ($8) { 13437 $this_anchor = &do_cmd_footnote($2); 13438 } else { 13439 $this_anchor = &do_cmd_footnotemark($3); 13440 } 13441 #MRO: $*=0; $/ = $saveRS; 13442 $foot_counters_recorded = 1; 13443 push(@foot_anchors, $this_anchor); 13444 $out!oesg; 13445 $_[0] = $image_contents; 13446 @foot_anchors; 13447} 13448 13449sub do_cmd_thanks { &do_cmd_footnote(@_); } 13450 13451sub get_footnote_mark { 13452 local($mini) = @_; 13453 return($footnote_mark) if ($HTML_VERSION < 3.0 ); 13454 local($cmd,$tmp,@tmp,$marker); 13455 $cmd = "the". (($mini)? 'mp' : '') . "footnote"; 13456 if ($new_command{$cmd}) { 13457 $tmp = "do_cmd_$cmd"; 13458 @tmp = split (':!:', $new_command{$cmd}); 13459 pop @tmp; $tmp = pop @tmp; 13460 if ($tmp =~ /$O/) { 13461### local($_) = &translate_commands($tmp); 13462 $marker = &translate_commands(&translate_environments($tmp)); 13463 &make_unique($marker); 13464### $marker = $_; 13465 } else { $marker = &translate_commands(&translate_environments($tmp)); } 13466 } elsif ($mini) { 13467 $marker = &translate_commands('\thempfootnote'); 13468 } elsif ((defined &do_cmd_thefootnote)||$new_command{'thefootnote'}) { 13469 local($br_id)=++$global{'max_id'}; 13470 $marker = &translate_environments("$O$br_id$C\\thefootnote$O$br_id$C"); 13471 } else { $marker = $footnote_mark; } 13472 join('','<SUP>',$marker,'</SUP>'); 13473} 13474 13475sub make_numbered_footnotes { 13476 eval "sub do_cmd_thefootnote {\&numbered_footnotes}" } 13477sub numbered_footnotes { &do_cmd_arabic('<<0>>footnote<<0>>');} 13478 13479# default numbering style for minipage notes 13480sub do_cmd_thempfootnote { &do_cmd_arabic('<<0>>mpfootnote<<0>>'); } 13481 13482sub do_cmd_footnotemark { &do_real_cmd_footnotemark(@_) } 13483sub do_real_cmd_footnotemark { 13484 local($_) = @_; 13485 local($br_id, $footnote,$marker,$mpnote,$tmp,$smark,$emark); 13486 # Don't use ()'s for the optional argument! 13487 local($mark,$dum) = &get_next_optional_argument; 13488 local ($cnt,$text_known) = ('',''); 13489 if ($mark) { 13490 $cnt = (($mark =~ /\\/)? &translate_commands($mark) : $mark); 13491 if (($MINIPAGE)&&($mpfootnotes{$cnt})) { 13492 $mpnote = 1; 13493 $br_id = $mpfootnotes{$cnt}; 13494 $text_known = 1; 13495 } else { 13496 $global{'footnote'} = $cnt; 13497 local($tmp) = $footnotes{$cnt}; 13498 if ($tmp) { 13499 $br_id = $tmp; 13500 $text_known = 1; 13501 } else { $footnotes{$cnt} = $br_id } 13502 } 13503 } else { 13504 $cnt = ++$global{'footnote'}; 13505 $text_known = 1 if ($footnotes{$cnt}); 13506 } 13507 if ($text_known) { 13508 $br_id = ($MINIPAGE ? $mpfootnotes{$cnt} : $footnotes{$cnt}); 13509 $marker = &get_footnote_mark($mpnote); 13510 return (join('', &make_href("$footfile#foot$br_id",$marker),$_)); 13511 } 13512 13513 local($last_word) = &get_last_word() unless ($mpnote); 13514 13515 # Try to find a \footnotetext further on. 13516 do { 13517 if (s/\\footnotetext\s*\[\s*$cnt\s*]*\]\s*$any_next_pair_pr_rx//o) { 13518 ($br_id, $footnote) = ($2, $3); 13519 } else { 13520 $br_id = "fnm$cnt"; 13521 $footnotes{$cnt} = $br_id; 13522 } 13523 } unless ($br_id); 13524 13525 $marker = &get_footnote_mark($mpnote); 13526 $last_word .= $marker unless ($marker =~ /$footnote_mark/ ); 13527 if ($footnote) { 13528 # found a \footnotetext further on 13529 &process_footnote($footnote,$cnt,$br_id,$last_word,$mark); 13530 join('',&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_); 13531 } elsif ($br_id =~ /fnm/) { 13532 # no \footnotetext yet, so make the entry in $footnotes 13533 &process_footnote('',$cnt,$br_id,$last_word,$mark); 13534 # this may not work if there is a <BASE> tag and !($footfile) !!! # 13535 join('',&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_); 13536 } elsif ($br_id) { 13537 # \footnotetext already processed 13538 if ($mpnote) { 13539 $mpfootnotes =~ s/(=\"$br_id\">...)(<\/A>)/$1$last_word$3/ 13540 if ($last_word); 13541 # this may not work if there is a <BASE> tag !!! # 13542 join('',&make_named_href("foot$br_id","#$br_id",$marker),$_); 13543 } else { 13544 $footnotes =~ s/(=\"$br_id\">...)(<\/A>)/$1$last_word$3/; 13545 # this may not work if there is a <BASE> tag and !($footfile) !!! # 13546 join('' 13547 ,&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_); 13548 } 13549 } else { 13550 print "\nCannot find \\footnotetext for \\footnotemark $cnt"; 13551 # this may not work if there is a <BASE> tag and !($footfile) !!! # 13552 join('',&make_named_href("foot$br_id","$footfile",$marker),$_); 13553 } 13554} 13555 13556# Under normal circumstances this is never executed. Any commands \footnotetext 13557# should have been processed when the corresponding \footnotemark was 13558# encountered. It is possible however that when processing pieces of text 13559# out of context (e.g. \footnotemarks in figure and table captions) 13560# the pair of commands gets separated. Until this is fixed properly, 13561# this command just puts the footnote in the footnote file in the hope 13562# that its context will be obvious .... 13563sub do_cmd_footnotetext { 13564 local($_) = @_; 13565 local($mark,$dum) = &get_next_optional_argument; 13566 local($br_id, $footnote, $prev, $key)=(1,'','',''); 13567 $footnote = &missing_braces unless ( 13568 (s/$next_pair_pr_rx/($br_id,$footnote)=($1,$2);''/eo) 13569 ||(s/$next_pair_rx/($br_id,$footnote)=($1,$2);''/eo)); 13570 13571 $mark = $global{'footnote'} unless $mark; 13572 $prev = $footnotes{$mark}; 13573 if ($prev) { 13574 $prev = ($MINIPAGE ? 'mp' : '') . $prev; 13575 # first prepare the footnote-text 13576 $footnote = &translate_environments("${OP}$br_id$CP$footnote${OP}$br_id$CP") 13577 if ($footnote); 13578 $footnote = &translate_commands($footnote) if ($footnote =~ /\\/); 13579 13580 # now merge it onto the Footnotes page 13581 $footnotes =~ s/(=\"$prev\">\.\.\.)(.*<\/A>)(<\/DT>\n<DD>)\n/ 13582 $1.'<html_this_mark>'.$3.$footnote/e; 13583 local($this_mark) = $2; 13584 $this_mark =~ s|(<SUP>)(?:<#\d+#>)?(\d+)(?:<#\d+#>)?(<\/SUP>)(<\/A>)$| 13585 "$4<A\n HREF=\"$CURRENT_FILE\#foot$prev\">$1$2$3$4"|e; 13586 $footnotes =~ s/<html_this_mark>/$this_mark/; 13587 } else { 13588 &process_footnote($footnote,$mark,$br_id,'','') if $footnote; 13589 } 13590 $_; 13591} 13592 13593 13594sub process_footnote { 13595 # Uses $before 13596 # Sets $footfile defined in translate 13597 # Modifies $footnotes defined in translate 13598 local($footnote, $cnt, $br_id, $last_word, $mark, $mini, $same_page) = @_; 13599 local($target) = $target; 13600 13601 # first prepare the footnote-text 13602 local($br_idd, $fcnt); $br_id =~ /\D*(\d+)/; $br_idd = $1; 13603 $footnote = &translate_environments("$O$br_idd$C$footnote$O$br_idd$C") 13604 if ($footnote); 13605 $footnote = &translate_commands($footnote) if ($footnote =~ /\\/); 13606 13607 local($space,$sfoot_style,$efoot_style) = ("\n",'',''); 13608 if ((!$NO_FOOTNODE)&&(!$mini)&&(!$target)) { 13609 $footfile = "${PREFIX}$FOOT_FILENAME$EXTN"; 13610 $space = ".\n" x 30; 13611 $space = "\n<PRE>$space</PRE>"; 13612 } elsif ($target) { 13613 $target = $frame_body_name 13614 if (($frame_body_name)&&($target eq $frame_foot_name)); 13615 $sfoot_style = '<SMALL>'; 13616 $efoot_style = '</SMALL>'; 13617 } 13618 13619 if ($mark) { 13620 if ($mini) { 13621 $cnt = $mpfootnotes{$mark}; 13622 if ($in_image) { 13623 $fcnt = $global{'mpfootnote'}; --$fcnt if $fcnt; 13624 $latex_body .= '\setcounter{mpfootnote}{'.($fcnt||"0")."}\n" 13625 unless ($foot_counters_recorded); 13626 } 13627 } else { 13628 $cnt = $footnotes{$mark}; 13629 if ($in_image) { 13630 $fcnt = $global{'footnote'}; --$fcnt if $fcnt; 13631 $latex_body .= '\setcounter{footnote}{'.($fcnt||"0")."}\n" 13632 unless ($foot_counters_recorded); 13633 } 13634 } 13635 if ($cnt) { 13636 &write_warnings("\nredefined target for footnote $mark" ) 13637 unless ( $cnt eq $br_id ) 13638 } 13639 if ($mini) { $mpfootnotes{$mark} = "$br_id" } 13640 elsif ($br_id =~ /fnm\d+/) { 13641 $mark = "$footnotes{$cnt}"; 13642 $footnotes{$cnt} = "$br_id"; 13643# $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">..." 13644 $footnotes .= "\n<DT>$sfoot_style<A NAME=\"$br_id\">..." 13645 . $last_word . "</A>$efoot_style</DT>\n<DD>\n" 13646 . $space . "\n</DD>"; 13647 return; 13648 } else { $footnotes{$mark} = "$br_id" } 13649 } else { 13650 if ($mini) { 13651 $mpfootnotes{$cnt} = "$br_id"; 13652 if ($in_image) { 13653 $fcnt = $global{'mpfootnote'}; --$fcnt if $fcnt; 13654 $latex_body .= '\setcounter{mpfootnote}{'.($fcnt||"0")."}\n" 13655 unless ($foot_counters_recorded); 13656 } 13657 } else { 13658 $footnotes{$cnt} = "$br_id"; 13659 if ($in_image) { 13660 $fcnt = $global{'footnote'}; --$fcnt if $fcnt; 13661 $latex_body .= '\setcounter{footnote}{'.($fcnt||"0")."}\n" 13662 unless ($foot_counters_recorded); 13663 } 13664 } 13665 } 13666 13667 # catch a \footnotemark *after* the \footnotetext 13668 if ((!$footnote)&&($last_word)&&(!$mini)) { 13669# $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">..." 13670 $footnotes .= "\n<DT>$sfoot_style<A NAME=\"$br_id\">..." 13671 . $last_word 13672 . "</A>$efoot_style</DT>\n<DD>\n" . $space . "\n</DD>"; 13673 13674 } elsif ($mini) { 13675 if ($HTML_VERSION < 3.0) { $mini .= "." } 13676 $mpfootnotes .= "\n<DD>$sfoot_style<A NAME=\"foot$br_id\">$mini</A> " . 13677 $footnote . $efoot_style . "\n</DD>\n"; 13678 } elsif ($same_page) { 13679 local($link,$text); 13680 $same_page =~ s/:/$text=$`;$link=$';''/e; 13681 $same_page = &make_named_href("","$CURRENT_FILE\#$link",$text) if($link); 13682 $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">...$last_word</A>" 13683 . $same_page . $efoot_style . "</DT>\n<DD>" . $sfoot_style 13684 . $footnote . $efoot_style . "\n". $space . "\n</DD>"; 13685 } else { 13686 $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">...$last_word</A>" 13687 . $efoot_style . "</DT>\n<DD>" . $sfoot_style 13688 . $footnote . "$efoot_style\n" . $space . "\n</DD>"; 13689 } 13690} 13691 13692 13693sub do_cmd_appendix { 13694 $latex_body .= "\\appendix\n"; 13695 if ($section_commands{$outermost_level} == 3) { 13696 $global{'section'} = 0; 13697 &reset_dependents('section'); 13698 eval "sub do_cmd_thesection{ &do_cmd_the_appendix(3,\@_) }"; 13699 } else { 13700 $global{'chapter'} = 0; 13701 &reset_dependents('chapter'); 13702 eval "sub do_cmd_thechapter{ &do_cmd_the_appendix(2,\@_) }"; 13703 } 13704 $_[0]; 13705} 13706 13707sub do_cmd_the_appendix { 13708 local($val,$level) = (0,$_[0]); 13709 if ($level == 3) { $val=$global{'section'} } 13710 elsif ($level == 2) { $val=$global{'chapter'} } 13711 join('', &fAlph($val), '.', $_[1]); 13712} 13713 13714sub do_cmd_appendixname { $app_title . $_[0] } 13715sub do_cmd_abstractname { $abs_title . $_[0] } 13716sub do_cmd_keywordsname { $key_title . $_[0] } 13717sub do_cmd_subjclassname { $sbj_title . $_[0] } 13718sub do_cmd_indexname { $idx_title . $_[0] } 13719sub do_cmd_contentsname { $toc_title . $_[0] } 13720sub do_cmd_datename { $date_name . $_[0] } 13721sub do_cmd_refname { $ref_title . $_[0] } 13722sub do_cmd_bibname { $bib_title . $_[0] } 13723sub do_cmd_figurename { $fig_name . $_[0] } 13724sub do_cmd_listfigurename { $lof_title . $_[0] } 13725sub do_cmd_tablename { $tab_name . $_[0] } 13726sub do_cmd_listtablename { $lot_title . $_[0] } 13727sub do_cmd_partname { $part_name . $_[0] } 13728sub do_cmd_chaptername { $chapter_name . $_[0] } 13729sub do_cmd_sectionname { $section_name . $_[0] } 13730sub do_cmd_subsectionname { $subsection_name . $_[0] } 13731sub do_cmd_subsubsectionname { $subsubsection_name . $_[0] } 13732sub do_cmd_paragraphname { $paragraph_name . $_[0] } 13733sub do_cmd_thmname { $thm_title . $_[0] } 13734sub do_cmd_proofname { $prf_name . $_[0] } 13735sub do_cmd_footnotename { $foot_title . $_[0] } 13736sub do_cmd_childlinksname { '<STRONG>'.$child_name.'</STRONG>'. $_[0] } 13737sub do_cmd_infopagename { $info_title . $_[0] } 13738 13739 13740sub do_cmd_ref { 13741 local($_) = @_; 13742 &process_ref($cross_ref_mark,$cross_ref_mark); 13743} 13744 13745sub do_cmd_eqref { 13746 local($_) = @_; 13747 join('','(',&process_ref($cross_ref_mark,$cross_ref_mark,'',')')); 13748} 13749 13750sub do_cmd_pageref { 13751 local($_) = @_; 13752 &process_ref($cross_ref_mark,$cross_ref_visible_mark); 13753} 13754 13755# This is used by external style files ... 13756sub process_ref { 13757 local($ref_mark, $visible_mark, $use_label, $after_label) = @_; 13758 $use_label = &balance_inner_tags($use_label) 13759 if $use_label =~ (/<\/([A-Z]+)>($math_verbatim_rx.*)<\1>/); 13760 $use_label = &translate_environments($use_label); 13761 $use_label = &simplify(&translate_commands($use_label)) 13762 if ($use_label =~ /\\/ ); 13763 local($label,$id); 13764 local($pretag) = &get_next_optional_argument; 13765 $pretag = &translate_commands($pretag) if ($pretag =~ /\\/); 13766 $label = &missing_braces unless ( 13767 (s/$next_pair_pr_rx/($id, $label) = ($1, $2);''/eo) 13768 ||(s/$next_pair_rx/($id, $label) = ($1, $2);''/eo)); 13769 if ($label) { 13770 $label =~ s/<[^>]*>//go ; #RRM: Remove any HTML tags 13771 $label =~ s/$label_rx/_/g; # replace non alphanumeric characters 13772 13773 $symbolic_labels{"$pretag$label$id"} = $use_label if ($use_label); 13774 if (($symbolic_labels{$pretag.$label})&&!($use_label)) { 13775 $use_label = $symbolic_labels{$pretag.$label} 13776 } 13777# if (!($use_label eq $label)) { 13778# $symbolic_labels{"$label$id"} = $use_label; 13779# }; 13780 # if $use_label is empty then $label is used as the cross_ref_mark 13781 # elseif $use_label is a string then $use_label is used 13782 # else the usual mark will be used 13783 $use_label = ( (!$use_label && $label) || $use_label); 13784 13785 print "\nLINK: $ref_mark\#$label\#$id :$use_label:" if ($VERBOSITY > 3); 13786 # The quotes around the HREF are inserted later 13787 join('',"<A HREF=$ref_mark#$label#$id>$visible_mark<\/A>",$after_label, $_); 13788 } 13789 else { 13790 print "Cannot find label argument after <$last_word>\n" if $last_word; 13791 $after_label . $_; 13792 } 13793} 13794 13795#RRM: This removes unbalanced tags, due to closures for math inside 13796# the label-text for an <A> anchor. 13797sub balance_inner_tags { 13798 local($text) = @_; 13799 return($text) unless ($text =~ /<\/([A-Z]+)>(\s*$math_verbatim_rx.*)(<\1( [^>]*)?>)/); 13800 local($beforeT,$afterT,$tag,$math_verb,$stag) = ($`,$',$1,$2,$3); 13801 if (!($beforeT =~ /<$tag>/)) { 13802 $text = join('', $beforeT, $math_verb, $afterT); 13803 return (&balance_inner_tags($text)); 13804 } 13805 local(@pieces) = split (/<$tag>/, $beforeT ); 13806 $beforeT = shift (@pieces); 13807 local($cnt,$this) = (0,''); 13808 while (@pieces) { 13809 $this = shift @pieces; 13810 $cnt++; 13811 $beforeT .= "<$tag>".$this; 13812 $cnt = $cnt - ($this =~ /<\/$tag>/g); 13813 } 13814 if ($cnt) { 13815 $beforeT .= "<\/$tag>" . $math_verb . $stag; 13816 $text = $beforeT . $afterT; 13817 } else { 13818 $beforeT .= $math_verb; 13819 $text = join('', $beforeT, $math_verb, $afterT); 13820 return (&balance_inner_tags($text)); 13821 } 13822 $text; 13823} 13824 13825# Uses $CURRENT_FILE defined in translate 13826sub do_cmd_label { 13827 local($_) = @_; 13828 local($label); 13829 $label = &missing_braces unless ( 13830 (s/$next_pair_pr_rx\n?/$label = $2;''/eo) 13831 ||(s/$next_pair_rx\n?/$label = $2;''/eo)); 13832 &anchor_label($label,$CURRENT_FILE,$_); 13833} 13834 13835# This subroutine is also used to process labels in undefined environments 13836sub anchor_label { &real_anchor_label(@_) } 13837sub real_anchor_label { 13838 # Modifies entries in %ref_files defined in translate 13839 local($label,$filename,$context) = @_; 13840 $label =~ s/<[^>]*>//go; #RRM: Remove any HTML tags 13841 $label =~ s/$label_rx/_/g; # replace non alphanumeric characters 13842 # Associate the label with the current file 13843 if ($ref_files{$label} ne $filename) { 13844 $ref_files{$label} = $filename; 13845 $noresave{$label} = 0; $changed = 1; } 13846 print "<LABEL: $label>" if ($VERBOSITY > 3); 13847 join('',"<A NAME=\"$label\">$anchor_mark</A>",$context); 13848} 13849 13850sub do_cmd_cite { 13851 local($_) = @_; 13852 &process_cite('',''); 13853} 13854 13855 13856# This just creates a link from a label (yet to be determined) to the 13857# cite_key in the citation file. 13858sub process_cite { &process_real_cite(@_) } 13859sub process_real_cite { 13860 local($mode,$text) = @_; 13861 my $has_text = (($text)? 1 : 0); 13862# local($target) = 'contents';print "\nCITE:$text"; 13863 # process the text from \htmlcite or \hypercite 13864 if ($has_text) { 13865 $text = &balance_inner_tags($text) 13866 if $use_label =~ (/<\/([A-Z]+)>($math_verbatim_rx.*)<\1>/); 13867 $text = &translate_environments($text); 13868 $text = &simplify(&translate_commands($text)) 13869 if ($use_label =~ /\\/ ); 13870 } 13871 13872 my $label, $cite_key, $pretag, @cite_keys; 13873 local($optional_text,$dummy) = &get_next_optional_argument; 13874 if ($mode =~ /external/) { 13875# $target = ''; 13876 $pretag = $optional_text; $optional_text = ''; 13877 $pretag = &translate_commands($pretag) if ($pretag =~ /\\/); 13878 } else { 13879 $optional_text = ", $optional_text" if $optional_text; 13880 } 13881 s/^\s*\\space//o; # Hack - \space is inserted in .aux 13882 s/$next_pair_pr_rx//o||s/$next_pair_rx//o; 13883 if (!($cite_key = $2)) { 13884 print "\n *** Cannot find citation argument\n"; 13885 return ($_); 13886 } 13887 @cite_keys = (split(/,/,$cite_key)); 13888 my ($citations, $join) = ('',','); 13889 $join = '' if ($text); 13890 foreach $cite_key (@cite_keys) { 13891 $cite_key =~ s/(^\s+|\s+$)//g; 13892 $cite_key =~ s/(^\s+|\s+$)//g; 13893 # RRM: if the URL and printable-key are known already, then use them... 13894 $cite_key =~ s/$label_rx/_/g; 13895 $label = $cite_key; 13896 if ($mode eq "nocite") { 13897 # nothing more to do, no citations 13898 } elsif ( ($SEGMENT) && ($cite_info{$cite_key}) 13899 && ($ref_files{"cite_$cite_key"}) ) { 13900 $join = "," unless ($text); 13901 $text = $cite_info{$cite_key} unless ($text); 13902 $citations .= join('', $join 13903 , &make_named_href($label,$ref_files{'cite_'."$cite_key"},$text)); 13904 } elsif (($mode eq "external")&&($external_labels{$pretag."cite_$cite_key"})) { 13905 $join = "," unless ($text); 13906 $text = $cross_ref_visible_mark unless ($text); 13907 $citations .= join('', $join 13908 , &make_named_href($label 13909 , $external_labels{$pretag.'cite_'."$cite_key"}."\#$label" 13910 , $text) 13911 ); 13912 } elsif ($mode eq 'external') { 13913 $join = "," unless ($text); 13914 &write_warnings("\nExternal reference missing for citation: $pretag$cite_key"); 13915 $citations .= "$text$join#!$pretag$cite_key!#"; 13916 } else { 13917 $join = "," unless ($text); 13918 #Replace the key... 13919 $citations .= "$join#$cite_key#$cite_mark#$bbl_nr#$text#$cite_mark#"; 13920 } 13921 $text = ''; 13922 } 13923 $citations =~ s/^\s*,\s*//; 13924 if ($has_text) { join('', $citations, $optional_text, $_) } 13925 else { join('', "[", $citations, $optional_text, "]", $_) } 13926} 13927 13928sub do_cmd_index { &do_real_index(@_) } 13929sub do_real_index { 13930 local($_) = @_; 13931 local($br_id, $str); 13932 local($idx_option) = &get_next_optional_argument; 13933 $str = &missing_braces unless ( 13934 (s/$next_pair_pr_rx/($br_id, $str) = ($1, $2);''/eo) 13935 ||(s/$next_pair_rx/($br_id, $str) = ($1, $2);''/eo)); 13936 join('',&make_index_entry($br_id,$str),$_); 13937} 13938sub do_cmd_indexstar { &do_cmd_index(@_) } 13939 13940# RRM: \bibcite supplies info via the .aux file; necessary with segmented docs. 13941sub do_cmd_bibcite { 13942 local($_) = @_; 13943 local($br_id, $cite_key,$print_key); 13944 $cite_key = &missing_braces unless ( 13945 (s/$next_pair_pr_rx/($br_id, $cite_key) = ($1, $2);''/eo) 13946 ||(s/$next_pair_rx/($br_id, $cite_key) = ($1, $2);''/eo)); 13947 $print_key = &missing_braces unless ( 13948 (s/$next_pair_pr_rx/($br_id, $print_key) = ($1, $2);''/eo) 13949 ||(s/$next_pair_rx/($br_id, $print_key) = ($1, $2);''/eo)); 13950 $cite_key =~ s/$label_rx/_/g; 13951 $cite_info{$cite_key} = $print_key; 13952 $_; 13953} 13954 13955# This command will only be encountered inside a thebibliography environment. 13956sub do_cmd_bibitem { &do_real_bibitem($CURRENT_FILE, @_) } 13957sub do_real_bibitem { 13958 local($thisfile, $_) = @_; 13959 # The square brackets may contain the label to be printed 13960 local($label, $dummy) = &get_next_optional_argument; 13961 # Support for the "named" bibliography style 13962 if ($label) { 13963 $label =~ s/\\protect//g; 13964 $label = &translate_commands($label) if ($label =~ /\\/); 13965 } 13966 local($cite_key); 13967 $cite_key = &missing_braces unless ( 13968 ( s/$next_pair_pr_rx/$cite_key=$2;''/e ) 13969 ||( s/$next_pair_rx/$cite_key=$2;''/e )); 13970 13971 $cite_key =~ s/$label_rx/_/g; 13972 $label = $cite_info{$cite_key} unless $label; # read from .aux file 13973 $label = ++$bibitem_counter unless $label; # Numerical labels 13974 13975 if ($cite_key) { 13976 # Associate the cite_key with the printed label. 13977 # The printed label will be substituted back into the document later. 13978 $cite_info{$cite_key} = &translate_commands($label); 13979 if (!($ref_files{'cite_'."$cite_key"} eq $thisfile)) { 13980 $ref_files{'cite_'."$cite_key"} = $thisfile; 13981 $changed = 1; } 13982 13983 #RRM: apply any special styles, as defined below 13984 $label = &bibitem_style($label) if (defined &bibitem_style); 13985 # Create an anchor around the citation 13986 join('',"<P></P><DT><A NAME=\"$cite_key\">$label</A>\n<DD>", $_); 13987 13988 } else { 13989 print "Cannot find bibitem labels: $label\n"; 13990 13991 #RRM: apply any special styles, as defined below 13992 $label = &bibitem_style($label) if (defined &bibitem_style); 13993 join('',"<P></P><DT>$label\n<DD>", $_); # AFEB added this line 13994 } 13995} 13996 13997#RRM: override this with a personal style, defined in .latex2html-init 13998#sub bibitem_style { join('','<STRONG>',$_[0],'</STRONG>') } 13999sub bibitem_style { 14000 return ($_[0]) unless $BIBITEM_STYLE; 14001 local($text) = join('' 14002 ,"${O}0$C",$BIBITEM_STYLE,"${O}1$C", @_, "${O}1$C","${O}0$C"); 14003 $text = &translate_environments($text); 14004 &translate_commands($text); 14005} 14006 14007sub do_cmd_newblock { 14008 "<BR>".$_[0] 14009} 14010 14011# This just reads in the $FILE.bbl file if it is available and appends 14012# it to the items that are still to be processed. 14013# The $FILE.bbl should contain a thebibliography environment which will 14014# cause its contents to be processed later in the appropriate way. 14015# (Note that it might be possible for both the \bibliography command and 14016# the thebibliography environment to be present as the former may have been 14017# added by the translator as a sectioning command. In this case (both present) 14018# the $citefile would have already been set by the thebibliography environment) 14019 14020sub do_cmd_bibliography { &do_real_bibliography($CURRENT_FILE, @_) } 14021sub do_real_bibliography { 14022 local($thisfile, $after) = @_; 14023 if ((defined &do_cmd_bibname)||$new_command{'bibname'}) { 14024 local($br_id)=++$global{'max_id'}; 14025 $TITLE = &translate_environments("$O$br_id$C\\bibname$O$br_id$C"); 14026 } else { $TITLE = $bib_title } 14027 $toc_sec_title = $TITLE; 14028 return($_[0]) if ($making_name); 14029 local($bibfile); 14030 $bibfile = &missing_braces unless ( 14031 ($after =~ s/$next_pair_rx/$bibfile=$2;''/eo)|| 14032 ($after =~ s/$next_pair_rx_rx/$bibfile=$2;''/eo)); 14033 14034 do { 14035 unless ($citefile) { 14036 $citefile = $thisfile; 14037 if (&process_ext_file("bbl")) { # *** BINDS $_ as a side effect *** 14038 $after = join('',$_,$after);} 14039 else { 14040 print "\nCannot open $FILE.bbl $!\n"; 14041 &write_warnings("\nThe bibliography file was not found."); 14042 $after = join('',"\n<H2>No References!</H2>", $after); 14043 } 14044 } 14045 print "\n"; 14046 } if $bibfile; 14047 $after; 14048} 14049 14050# allow for customised info-pages, for different languages 14051sub do_cmd_textohtmlinfopage { 14052 local($_) = @_; 14053 local($linfo) = $TITLES_LANGUAGE . '_infopage'; 14054 if (defined &$linfo) { eval "&$linfo"; } 14055 else { &default_textohtmlinfopage } 14056} 14057 14058sub default_textohtmlinfopage { 14059 local($_) = @_; 14060 local($argv) = $argv; 14061 if (-f "../$argv") { $argv = &make_href ("../$argv", $argv, ); } 14062 $_ = ($INFO && $INFO =~ /^\d+$/ 14063 ? join('', $close_all 14064 , "<STRONG>$t_title</STRONG><P>\nThis document was generated using the\n" 14065 , "<A HREF=\"$TEX2HTMLADDRESS\"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A>" 14066 , " translator Version $TEX2HTMLVERSION\n" 14067 , "<P>Copyright © 1993, 1994, 1995, 1996,\n" 14068 , "Nikos Drakos, \n" 14069 , "Computer Based Learning Unit, University of Leeds.\n" 14070 , "<BR>Copyright © 1997, 1998, 1999,\n" 14071 , "<A HREF=\"$AUTHORADDRESS2\">Ross Moore</A>, \n" 14072 , "Mathematics Department, Macquarie University, Sydney.\n" 14073 , "<P>The command line arguments were: <BR>\n " 14074 , "<STRONG>latex2html</STRONG> <TT>$argv</TT>\n" 14075 , (($SHOW_INIT_FILE && ($INIT_FILE ne ''))? 14076 "\n<P>with initialization from: <TT>$INIT_FILE</TT>\n$init_file_mark\n" :'') 14077 , "<P>The translation was initiated by $address_data[0] on $address_data[1]" 14078 , $open_all, $_) 14079 : join('', $close_all, "$INFO\n", $open_all, $_)); 14080 $_; 14081} 14082 14083 14084# Try to translate LaTeX vertical space in a number of <BR>'s. 14085# Eg. 1cm results in one + two extra <BR>'s. 14086# To help the browser rendering is quite ugly, but why not. 14087# 14088sub get_vspace { 14089 local($_) = @_; 14090 local($vh) = 0; 14091 14092 return("<BR>") if /-/; 14093 14094 $vh = int($1 * $vspace_12pt{$2} + 0.5) 14095 if (/([0-9.]+)\s*([a-z]+)/); 14096 join('',"<BR>","\n<BR>" x $vh); 14097} 14098 14099sub do_cmd_vskip { 14100 local($_) = @_; 14101 &ignore_numeric_argument; 14102 join('',&get_vspace($1),$_); 14103} 14104 14105sub do_cmd_break { 14106 local($_) = @_; 14107 join('',"<BR>",$_); 14108} 14109 14110sub do_cmd_vspace { 14111 local($_) = @_; 14112 local($how_much); 14113 $how_much = &missing_braces unless ( 14114 (s/$next_pair_pr_rx/$how_much = $2;''/e) 14115 ||(s/$next_pair_rx/$how_much = $2;''/e)); 14116 join('',&get_vspace($how_much),$_); 14117} 14118 14119sub do_cmd_vspacestar { 14120 &do_cmd_vspace; 14121} 14122 14123sub do_cmd_d_backslash { 14124 local($_) = @_; 14125 14126 # Eat space from &pre_process. 14127 # We could also modifiy $single_cmd_rx and %normalize, but why not here. 14128 s/^ \*?//; 14129 local($spc,$dum)=&get_next_optional_argument; 14130 # If the [...] occurs on the next line, then it is *not* an argument to \\ . 14131 # MRO: replaced $* with /m 14132 if ($dum =~ /\n/m) { 14133 $spc = $`; 14134 $spc =~ s/\s//gm; 14135 $_ = $'.$_ 14136 } 14137 join('',(($spc)? &get_vspace($spc): "\n<BR>"),$_); 14138} 14139 14140 14141################## Commands used in the $FILE.aux file ####################### 14142 14143sub do_cmd_jobname { $FILE . $_[0] } 14144 14145# This is used in $FILE.aux 14146sub do_cmd_newlabel { 14147 local($_) = @_; 14148 local($label,$val,$tmp); 14149 $label = &missing_braces unless ( 14150 (s/$next_pair_pr_rx/$label = $2;''/eo) 14151 ||(s/$next_pair_rx/$label = $2;''/eo)); 14152 $tmp = &missing_braces unless ( 14153 (s/$next_pair_pr_rx/$tmp=$2;''/eo) 14154 ||(s/$next_pair_rx/$tmp=$2;''/eo)); 14155 $val = &missing_braces unless ( 14156 ($tmp =~ s/$next_pair_pr_rx/$val=$2;''/eo) 14157 ||($tmp =~ s/$next_pair_rx/$val=$2;''/eo)); 14158 $val =~ s/(^\s+|\s+$)//gs; 14159 $label =~ s/$label_rx/_/g; # Replace non alphanumeric characters 14160 $latex_labels{$label} = $val; 14161 &do_labels_helper($label); 14162 $_; 14163} 14164sub do_cmd_oldnewlabel { &do_cmd_newlabel(@_) } 14165 14166# 14167# Sets %encoded_(section|figure|table)_number, which maps encoded 14168# section titles to LaTeX numbers 14169# .= \$number . \"$;\""; 14170sub do_cmd_oldcontentsline { &do_cmd_contentsline(@_) } 14171sub do_cmd_contentsline { 14172 local($_) = @_; 14173 local($arg,$after,$title,$number,$hash,$stype,$page); 14174 # The form of the expression is: 14175 # \contentsline{SECTION} {... {SECTION_NUMBER} TITLE}{PAGE} 14176 $stype = &missing_braces unless ( 14177 (s/$next_pair_pr_rx/$stype = $2;''/e) 14178 ||(s/$next_pair_rx/$stype = $2;''/e)); 14179 $arg = &missing_braces unless ( 14180 (s/$next_pair_pr_rx/$arg = $2;''/e) 14181 ||(s/$next_pair_rx/$arg = $2;''/e)); 14182 $page = &missing_braces unless ( 14183 (s/$next_pair_pr_rx/$page = $2;''/e) 14184 ||(s/$next_pair_rx/$page = $2;''/e)); 14185 14186# s/$any_next_pair_pr_rx/$stype = $2;''/eo; # Chop off {SECTION} 14187# s/$any_next_pair_pr_rx/$arg = $2;''/eo; # Get {... {SECTION_NUMBER} TITLE} 14188# s/$any_next_pair_pr_rx/$page = $2;''/eo; # Get page number 14189 $hash = $stype if (($stype =~ /^(figure|table)$/)||($SHOW_SECTION_NUMBERS)); 14190 $hash =~ s/(sub)*(section|chapter|part)/section/; 14191 $after = $_; 14192 if ($hash) { 14193 if ($arg =~ /^$OP/) { 14194 $number = &missing_braces unless ( 14195 ($arg =~ s/$next_pair_pr_rx/$number = $2;''/eo) 14196 ||($arg =~ s/$next_pair_rx/$number = $2;''/eo)); 14197 } 14198 if ($stype eq "part") { 14199 while ($arg =~ s/$next_pair_pr_rx//o) {}; 14200 $number =~ tr/a-z/A-Z/; 14201 $number = "Part $number:"} 14202 # This cause problem when picking figure numbers... 14203 # while ($tmp =~ s/$next_pair_pr_rx//o) {}; 14204 $number = -1 unless $number; 14205#JCL(jcl-tcl) 14206## $_ = $arg; 14207# $title = &sanitize($arg); 14208## &text_cleanup; 14209## $title = &encode_title($_); 14210## 14211 #remove surrounding brace-numbering 14212 $arg =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g; 14213 $arg =~ s/\\footnote(mark|text)?//g; 14214 # \caption arguments should have had environments translated already 14215 $arg = &translate_environments($arg) if ($arg =~ /\\begin/); 14216 #replace image-markers by the image params 14217 $arg =~ s/$image_mark\#([^\#]+)\#/&purify_caption($1)/e; 14218 14219 #RRM: resolve any embedded cross-references first 14220 local($checking_caption) = 1; 14221 $title = &simplify($arg); 14222 $title = &sanitize($title); 14223 $checking_caption = ''; 14224 eval "\$encoded_${hash}_number{\$title} .= \$number . \"$;\""; 14225 } 14226 $after; 14227} 14228 14229# 14230# Before normalizing this was \@input. Used in .aux files. 14231# 14232sub do_cmd__at_input { 14233 local ($_) = @_; 14234 local ($file, $after); 14235 $file = &missing_braces unless ( 14236 (s/$next_pair_pr_rx/$file=$2;''/eo) 14237 ||(s/$next_pair_rx/$file=$2;''/eo)); 14238 local($prefix, $suffix) = split(/\./, $file); 14239 $after = $_; 14240 local($EXTERNAL_FILE) = $prefix; 14241 &process_ext_file($suffix); 14242 $after; 14243} 14244 14245 14246########################### Counter Commands ################################# 14247# Removes the definition from the input string, adds to the preamble 14248# and stores the body in %new_counter; 14249sub get_body_newcounter { 14250# local(*_) = @_; 14251 local($after_R) = @_; 14252 local($_) = $$after_R; 14253 local($within,$ctr,$cmd,$tmp,$body,$pat); 14254 local($new_ctr) = 'counter'; 14255 ($ctr,$pat) = &get_next(1); # Get counter name 14256 &write_warnings ("\n*** LaTeX Error: backslash found in counter-name: $ctr") 14257 if ($pat =~ s/\\//); 14258 $ctr =~ s/^\s*\\//; 14259 $new_ctr .= $pat; 14260 14261 ($within,$pat) = &get_next(0); # Get optional within, currently ignored 14262 &addto_dependents($within,$ctr); 14263 $new_ctr .= $pat; 14264 do { 14265### local($_) = "\\arabic<<1>>$ctr<<1>>"; 14266 $body = "\\arabic<<1>>$ctr<<1>>"; 14267 &make_unique($body); 14268 $cmd = "the$ctr"; 14269 $tmp = "do_cmd_$cmd"; 14270 $new_command{$cmd} = join(':!:',0,$body,'}') unless (defined &$tmp); 14271 &write_mydb("new_command", $cmd, $new_command{$cmd}); 14272 undef $body; 14273 }; 14274 &do_body_newcounter($ctr); 14275 14276 $$after_R = $_; 14277 if (!$PREAMBLE) { 14278 my $new_cmd = join('' 14279 , "counter{$ctr}", ($within ? "[$within]" : '') ); 14280 &add_to_preamble('counter','\\new'.$new_cmd); 14281 return (); 14282 } 14283 'newed'.$new_ctr; 14284} 14285 14286sub do_body_newcounter { 14287 local($ctr) = @_; 14288 $latex_body .= &revert_to_raw_tex("\\newcounter{$ctr}\n") 14289 unless ($preamble =~ /\\new(counter|theorem){$ctr}/); 14290 $global{$ctr} = 0; 14291 &process_commands_wrap_deferred("the$ctr "); 14292 $_; 14293} 14294 14295 14296#RRM: This doesn't work properly yet. 14297# The new booleans need to be stored for use in all partitions. 14298# \if... \else \fi is not yet implemented. 14299 14300sub get_body_newboolean { 14301# local(*_) = @_; 14302 local($after_R) = @_; 14303 local($_) = $$after_R; 14304 my $bool; 14305 $bool = &missing_braces unless ( 14306 (s/$next_pair_pr_rx/$bool=$2;''/e) 14307 ||(s/$next_pair_rx/$bool=$2;''/e)); 14308 $bool = &process_body_newif('',$bool); 14309 $$after_R = $_; 14310 'newed'.$bool; 14311} 14312 14313sub get_body_newif { 14314# local(*_) = @_; 14315 local($after_R) = @_; 14316 local($_) = $$after_R; 14317 local($bool); 14318 if (!(s/^\s*\\if([a-zA-Z]+)//)) { 14319 $$after_R = $_; 14320 return(); 14321 } 14322 $bool = $1; 14323 $$after_R = $_; 14324 join('','newed', &process_body_newif('', $bool)); 14325} 14326 14327 14328sub process_body_newif { 14329 local($texif, $bool) = @_; 14330 local($body,$ifbool,$cmd,$tmp,$pat); 14331 14332# ($bool,$pat) = &get_next(1); # Get boolean name 14333 14334# # change the brace-type around the command-name 14335# $pat =~ s/$O/$OP/; $pat =~ s/$C/$CP/; $new_cmd .= $pat; 14336 14337 $ifbool = "if".$bool; 14338 $global{$ifbool} = 0; 14339 14340 do { 14341 $body = "\$global{'$ifbool'} = 1;"; 14342 $cmd = $bool."true"; 14343 $code = "sub do_cmd_$cmd { ".$body." \$_[0];}"; 14344 eval $code; 14345 print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@); 14346 $raw_arg_cmds{$cmd} = 1; 14347 14348 $body = "\$global{$ifbool} = 0;"; 14349 $cmd = $bool."false"; 14350 $code = "sub do_cmd_$cmd { ".$body." \$_[0];}"; 14351 eval $code; 14352 print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@); 14353 $raw_arg_cmds{$cmd} = 1; 14354 14355 undef $body; 14356 }; 14357 &process_commands_wrap_deferred("${bool}true\n${bool}false\nif$bool\n"); 14358 14359# $latex_body .= &revert_to_raw_tex("\\newif\\$ifbool\n") 14360# unless ($preamble =~ /\\newif\s*\\$ifbool/); 14361 14362 if (!$PREAMBLE) { 14363 local($new_cmd) = "boolean{\\$bool}"; 14364 &add_to_preamble ('newif', "\\new$new_cmd" ); 14365 return (); 14366 } 14367 local($br_id) = ++$global{'max_id'}; 14368 'boolean'."$O$br_id$C$bool$O$br_id$C"; 14369} 14370 14371 14372sub do_cmd_value { 14373 local($_) = @_; 14374 local($ctr,$val); 14375 $ctr = &missing_braces 14376 unless ((s/$next_pair_pr_rx/$ctr = $2;''/eo) 14377 ||(s/$next_pair_rx/$ctr = $2;''/eo)); 14378 $val = &get_counter_value($ctr); 14379 if ($val) { $val.$_ } 14380 else { join(''," 0",$_) } 14381} 14382 14383sub do_cmd_boolean { 14384 local($_) = @_; 14385 local($bool,$val); 14386 $bool = &missing_braces 14387 unless ((s/$next_pair_pr_rx/$bool = $2;''/eo) 14388 ||(s/$next_pair_rx/$bool = $2;''/eo)); 14389 $val = &get_boolean_value($bool); 14390 if ($val) { $val.$_ } 14391 else { "0".$_ } 14392} 14393 14394sub get_counter_value { 14395 local($ctr) = @_; 14396 local($val,$index); 14397 $ctr = 'eqn_number' if ($ctr eq "equation"); 14398 $index = $section_commands{$ctr}; 14399 14400 if (defined $global{$ctr}) { $val= $global{$ctr}; } 14401 elsif (($SEGMENT)&&($index)) { 14402 $val = $segment_sec_id[$index] 14403# if ($index) { 14404# if ($SEGMENT) { $val = $segment_sec_id[$index] } 14405# else { $val = $curr_sec_id[$index] } 14406 } else { 14407 &write_warnings ("\ncounter $ctr not defined"); 14408 $val= 0; 14409 } 14410 print "\nVAL:$ctr: $val " if ($VERBOSITY > 3); 14411 $val; 14412} 14413 14414sub get_boolean_value { 14415 local($bool) = @_; 14416 local($val,$index); 14417 if (defined $global{$bool}) { $val= $global{$bool} } 14418 else { 14419 &write_warnings ("boolean $bool not defined\n"); 14420 $val="0"; 14421 } 14422 print "\nBOOL:$bool: $val " if ($VERBOSITY > 3); 14423 $val; 14424} 14425 14426sub do_cmd_addtocounter { 14427 local($_) = @_; 14428 local($ctr,$num,$index); 14429 $ctr = &missing_braces 14430 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14431 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14432 $num = &missing_braces 14433 unless ((s/$next_pair_rx/$num = $2;''/eo) 14434 ||(s/$next_pair_pr_rx/$num = $2;''/eo)); 14435 14436 $num = &translate_commands($num) if ($num =~ /\\/); 14437 if ($num !~ /^\s*(\+|-)?\d+\s*$/) { 14438 print STDERR "\n*** cannot set counter $ctr to $num ***\n"; 14439 return($_); 14440 } 14441 14442 $latex_body .= &revert_to_raw_tex("\\addtocounter{$ctr}{$num}\n"); 14443 $index = $section_commands{$ctr}; 14444 14445 if (defined $global{$ctr}) { $global{$ctr} += $num } 14446 elsif ($index) { 14447 if ($SEGMENT) { $segment_sec_id[$index] += $num } 14448 else { $curr_sec_id[$index] += $num } 14449 $global{$ctr} += $num; 14450 } elsif ($ctr eq "equation") { 14451 $global{'eqn_number'} += $num 14452 } else { $global{$ctr} += $num }; 14453 print "\nADD:$ctr:+$num= ". $global{$ctr}." " if ($VERBOSITY > 3); 14454# &reset_dependents($ctr) if ($dependent{$ctr}); 14455 $_; 14456} 14457 14458sub do_cmd_setcounter { 14459 local($_) = @_; 14460 local($ctr,$num,$index,$sctr); 14461 $ctr = &missing_braces 14462 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14463 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14464 $num = &missing_braces 14465 unless ((s/$next_pair_rx/$num = $2;''/eo) 14466 ||(s/$next_pair_pr_rx/$num = $2;''/eo)); 14467 14468 $num = &translate_commands($num) if ($num =~ /\\/); 14469 if ($num !~ /^\s*(\+|-)?\d+\s*$/) { 14470 print STDERR "\n*** cannot set counter $ctr to $num ***\n"; 14471 return($_); 14472 } 14473 if ($ctr =~ /^l/) { 14474 $sctr = $'; 14475 $ctr = $sctr if $section_commands{$sctr}; 14476 } 14477 if (! $AUX_FILE && !($ctr =~ /page/ )) { 14478 $latex_body .= &revert_to_raw_tex("\\setcounter{$ctr}{$num}\n"); 14479 $index = $section_commands{$ctr}; 14480 if ($index) { 14481 if ($curr_sec_id[$index] <= $num ) { 14482 $curr_sec_id[$index] = $num 14483 } else { 14484 print "\nignoring \\setcounter{$ctr}{$num} currently at ",$curr_sec_id[$index] ; 14485 &write_warnings(join('',"\n\\setcounter{$ctr}{$num} ignored," 14486 ," cannot reduce from ",$curr_sec_id[$index])); 14487 } 14488 $global{$ctr} = $num; 14489 } elsif ($ctr eq "equation") {$global{'eqn_number'} = $num } 14490 else { $global{$ctr} = $num }; 14491 } 14492 print "\nSET:$ctr: = $num" if ($VERBOSITY > 3); 14493# &reset_dependents($ctr) if ($dependent{$ctr}); 14494 $_; 14495} 14496 14497sub do_cmd_setlength { 14498 local($_) = @_; 14499 local($dimen,$value,$index,$sctr); 14500 $dimen = &missing_braces 14501 unless ((s/$next_pair_rx/$dimen = $2;''/eo) 14502 ||(s/$next_pair_pr_rx/$dimen = $2;''/eo)); 14503 $value = &missing_braces 14504 unless ((s/$next_pair_rx/$value = $2;''/eo) 14505 ||(s/$next_pair_pr_rx/$value = $2;''/eo)); 14506 14507 # recognise specific length-parameters 14508 if ($dimen =~ /captionwidth/) { 14509 local($pxs,$len) = &convert_length($value, $MATH_SCALE_FACTOR); 14510 $cap_width = $pxs if ($pxs &&($dimen =~ /captionwidth/)); 14511 } 14512 if ((! $AUX_FILE)&&(! $PREAMBLE)) { 14513 $latex_body .= &revert_to_raw_tex("\\setlength{$dimen}{$value}\n"); 14514 print "\nSETLENGTH:$dimen = $value" if ($VERBOSITY > 3); 14515 } 14516 $_; 14517} 14518 14519sub do_cmd_setboolean { 14520 local($_) = @_; 14521 local($bool,$val); 14522 $bool = &missing_braces 14523 unless ((s/$next_pair_rx/$bool = $2;''/eo) 14524 ||(s/$next_pair_pr_rx/$bool = $2;''/eo)); 14525 $val = &missing_braces 14526 unless ((s/$next_pair_rx/$val = $2;''/eo) 14527 ||(s/$next_pair_pr_rx/$val = $2;''/eo)); 14528 if (! $AUX_FILE) { 14529 $latex_body .= &revert_to_raw_tex("\\setboolean{$bool}{$val}\n"); 14530 $global{"if$bool"} = (($val = ~/true/) ? 1 : 0); 14531 print "\nSETBOOL:$bool = $val" if ($VERBOSITY > 3); 14532 } 14533 $_; 14534} 14535 14536sub do_cmd_endsegment { 14537 local($_) = @_; 14538 local($ctr,$dum) = &get_next_optional_argument; 14539 local($index,$steps) = ('',1); 14540# $steps = &missing_braces unless ( 14541# (s/$next_pair_pr_rx/$steps = $2;''/e) 14542# ||(s/$next_pair_rx/$steps = $2;''/e)); 14543 $index = $section_commands{$ctr} if $ctr; 14544# if ($index) { $curr_sec_id[$index] += $steps } 14545# if ($index) { ($after_segment,$after_seg_num) = ($index,$steps) } 14546 if ($index) { ($after_segment,$after_seg_num) = ($index,1) } 14547 $_; 14548} 14549 14550sub do_cmd_stepcounter { 14551 local($_) = @_; 14552 local($ctr,$index); 14553 $ctr = &missing_braces 14554 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14555 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14556 if (! $AUX_FILE) { 14557 $latex_body .= &revert_to_raw_tex("\\stepcounter{$ctr}\n"); 14558 $index = $section_commands{$ctr}; 14559 if ($index) { 14560# if ($SEGMENT) { $segment_sec_id[$index] += 1 } 14561# else { $curr_sec_id[$index] += 1 } 14562 $global{$ctr} += 1; 14563 } elsif ($ctr eq "equation") { $global{'eqn_number'} += 1 } 14564 else { $global{$ctr} += 1 }; 14565 } 14566 print "\nSTP:$ctr:+1" if ($VERBOSITY > 3); 14567 &reset_dependents($ctr) if ($dependent{$ctr}); 14568 $_; 14569} 14570 14571#RRM: dependent counters are stored as a comma-separated list 14572# in the %dependent hash. 14573sub reset_dependents { 14574 local($ctr) = @_; 14575 local($dep,$subdep,%dependents); 14576 @dependents = (split($delim, $dependent{$ctr})); 14577 print "\n" if (($VERBOSITY > 3)&&(@dependents)); 14578 while (@dependents) { 14579 $dep = pop(@dependents); 14580 print "RESET $dep to 0\n" if ($VERBOSITY > 3); 14581 if ($global{$dep}) { $global{$dep} = 0 } 14582 elsif ($dep =~ /equation/) { $global{'eqn_number'} = 0 } 14583 if ($dependent{$dep}) { 14584 push(@dependents,split($delim,$dependent{$dep})); 14585 } 14586 } 14587} 14588 14589sub do_cmd_numberwithin { 14590 local($_) = @_; 14591 local($ctr,$within); 14592 $ctr = &missing_braces 14593 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14594 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14595 $within = &missing_braces 14596 unless ((s/$next_pair_rx/$within = $2;''/eo) 14597 ||(s/$next_pair_pr_rx/$within = $2;''/eo)); 14598 14599 # record the counter dependency 14600 &addto_dependents($within,$ctr) if ($within); 14601 local($newsub) = "sub do_cmd_the$ctr {" 14602 . "\$global{'max_id'}++;\n" 14603# . "local(\$super)=\&do_cmd_the$within();\n" 14604 . "local(\$super)=\&translate_commands('\\the$within');\n" 14605 . "\$super .= '.' unless (\$super =~/\\.\$/);\n" 14606 . "\$super .\&do_cmd_value('<<'.\$global{'max_id'}.'>>" 14607 . $ctr . "<<'.\$global{'max_id'}.'>>')}\n"; 14608 eval $newsub; 14609 print " *** sub do_cmd_the$ctr unchanged *** $@ " if ($@); 14610 $_; 14611} 14612 14613sub do_cmd_refstepcounter { 14614 local($_) = @_; 14615 local($ctr); 14616 $ctr = &missing_braces 14617 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14618 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14619 if (! $AUX_FILE) { 14620 $latex_body .= &revert_to_raw_tex("\\refstepcounter{$ctr}\n"); 14621 $index = $section_commands{$ctr}; 14622 if (defined $global{$ctr}) { $global{$ctr} += 1 } 14623 elsif ($index) { 14624 if ($SEGMENT) { $segment_sec_id[$index] += 1 } 14625 else { $curr_sec_id[$index] += 1 } 14626 } elsif ($ctr eq "equation") { $global{'eqn_number'} += 1 } 14627 else { $global{$ctr} += 1 }; 14628 } 14629 print "\nSTP: $ctr : +1" if ($VERBOSITY > 3); 14630 &reset_dependents($ctr) if ($dependent{$ctr}); 14631 $_; 14632} 14633 14634sub read_counter_value { 14635 local($_) = @_; 14636 local($ctr,$br_id,$val); 14637 $ctr = &missing_braces 14638 unless ((s/$next_pair_pr_rx/$br_id = $1; $ctr = $2;''/eo) 14639 ||(s/$next_pair_rx/$br_id = $1; $ctr = $2;''/eo)); 14640 $val = &get_counter_value($ctr); 14641 ($ctr, $val, $br_id, $_) 14642} 14643 14644sub styled_number_text { 14645 local($num_style, $val, $txtID) = @_; 14646 if ($USING_STYLES) { 14647 $txt_style{$num_style} = " " unless ($txt_style{$num_style}); 14648 join('',"<SPAN CLASS=\"$num_style\">", $val, "</SPAN>", $_); 14649 } else { $val.$_ } 14650} 14651 14652sub do_cmd_arabic { 14653 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14654 $val = ($val ? &farabic($val) : "0"); 14655 &styled_number_text('arabic', $val, $id); 14656} 14657 14658sub do_cmd_roman { 14659 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14660 if ($val < 0 ) { $val = join('',"-",&froman(-$val)); } 14661 elsif ($val) { $val = &froman($val) } 14662 else { $val = "0"; } 14663 &styled_number_text('roman', $val, $id); 14664} 14665 14666sub do_cmd_Roman { 14667 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14668 if ($val < 0 ) { $val = join('',"-",&fRoman(-$val)); } 14669 elsif ($val) { $val = &fRoman($val) } 14670 else { $val = "0"; } 14671 &styled_number_text('Roman', $val, $id); 14672} 14673 14674sub do_cmd_alph { 14675 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14676 if ($val < 0 ) { $val = join('',"-",&falph(-$val)); } 14677 elsif ($val) { $val = &falph($val) } 14678 else { $val = "0"; } 14679 &styled_number_text('alph', $val, $id); 14680} 14681 14682sub do_cmd_Alph { 14683 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14684 if ($val < 0 ) { $val = join('',"-",&fAlph(-$val)); } 14685 elsif ($val) { $val = &fAlph($val) } 14686 else { $val = "0"; } 14687 &styled_number_text('Alph', $val, $id); 14688} 14689 14690 14691sub do_cmd_fnsymbol { 14692 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14693 $val = &process_in_latex_helper($ctr, $val, "fnsymbol{$ctr}"); 14694 &styled_number_text('Alph', $val, $id); 14695} 14696 14697 14698 14699# This is a general command for getting counter values; 14700# e.g. for section-numbers. 14701 14702sub do_cmd_thecounter { 14703 local($_) = @_; 14704 # Uses $counter bound by the caller 14705 local($val) = &get_counter_value($counter); 14706 $val = &process_in_latex_helper($counter,$val,"the$counter"); 14707 &styled_number_text($counter, $val, ''); 14708# join('',&process_in_latex_helper($counter,$val,"the$counter"),$_[0]); 14709} 14710 14711 14712################# Special Naming Macros ################################## 14713 14714sub do_cmd_LaTeX { 14715 local($_) = @_; 14716 if ($USING_STYLES) { 14717 $env_style{'LaTeX'} = ' ' unless ($env_style{'LaTeX'}); 14718 $env_style{'logo-LaTeX'} = ' ' unless ($env_style{'logo-LaTeX'}); 14719 join('',"<SPAN CLASS=\"logo,LaTeX\">",$Laname, $TeXname,"</SPAN>",$_); 14720 } else { join('',$Laname, $TeXname, $_); } 14721} 14722 14723sub do_cmd_LaTeXe { 14724 local($_) = @_; 14725 if ($USING_STYLES) { 14726 $env_style{'LaTeX2e'} = ' ' unless ($env_style{'LaTeX2e'}); 14727 $env_style{'logo-LaTeX2e'} = ' ' unless ($env_style{'logo-LaTeX2e'}); 14728 join('',"<SPAN CLASS=\"logo,LaTeX2e\">" 14729 ,$Laname, $TeXname,'2<SUB>e</SUB>',"</SPAN>",$_); 14730 } else { join('',$Laname,$TeXname 14731 ,(($HTML_VERSION >= 3.0)? '2<SUB>e</SUB>':'2e'),$_); 14732 } 14733} 14734 14735sub do_cmd_latextohtml { 14736 local($_) = @_; 14737 if ($USING_STYLES) { 14738 $env_style{'LaTeX2HTML'} = ' ' unless ($env_style{'LaTeX2HTML'}); 14739 $env_style{'logo-LaTeX2HTML'} = ' ' unless ($env_style{'logo-LaTeX2HTML'}); 14740 join('',"<SPAN CLASS=\"logo,LaTeX2HTML\">" 14741 ,$Laname, $TeXname,"2<TT>HTML</TT>","</SPAN>",$_); 14742 } else { join('',$Laname,$TeXname,"2<TT>HTML</TT>",$_);} 14743} 14744 14745sub do_cmd_TeX { 14746 local($_) = @_; 14747 if ($USING_STYLES) { 14748 $env_style{'logo-TeX'} = ' ' unless ($env_style{'logo-TeX'}); 14749 join('',"<SPAN CLASS=\"logo-TeX\">",$TeXname,"</SPAN>",$_); 14750 } else { join('',$TeXname, $_);} 14751} 14752 14753sub do_cmd_MF { 14754 local($_) = @_; 14755 if ($USING_STYLES) { 14756 $env_style{'logo-Metafont'} = ' ' unless ($env_style{'logo-Metafont'}); 14757 join('',"<SPAN CLASS=\"logo-Metafont\">",$MFname,"</SPAN>",$_); 14758 } else { join('', $MFname, $_);} 14759} 14760 14761sub do_cmd_Xy { 14762 local($_) = @_; 14763 if ($USING_STYLES) { 14764 $env_style{'logo-Xy-pic'} = ' ' unless ($env_style{'logo-Xy-pic'}); 14765 join('',"<SPAN CLASS=\"logo-Xy-pic\">",$Xyname,"</SPAN>",$_); 14766 } else { join('',$Xyname, $_);} 14767} 14768 14769sub do_cmd_AmS { 14770 local($_) = @_; 14771 if ($USING_STYLES) { 14772 $env_style{'logo-AMS'} = ' ' unless ($env_style{'logo-AMS'}); 14773 join('',"<SPAN CLASS=\"logo-AMS\">",$AmSname,"</SPAN>",$_); 14774 } else { join('',$AmSname, $_);} 14775} 14776 14777sub do_cmd_AmSTeX { 14778 local($_) = @_; 14779 if ($USING_STYLES) { 14780 $env_style{'logo-AMS'} = ' ' unless ($env_style{'logo-AMS'}); 14781 join('',"<SPAN CLASS=\"logo-AMS\">",$AmSname,"-$TeXname","</SPAN>",$_); 14782 } else { join('',$AmSname, "-", $TeXname, $_);} 14783} 14784 14785sub do_cmd_char { 14786 local($_) = @_; 14787# some special characters are already turned into l2h internal 14788# representation. 14789# Get its represention from the table and use it like as regexp form. 14790 local($spmquot) = &escape_rx_chars($html_specials{'"'}); 14791# Get all internal special char representations as implied during 14792# preprocessing. 14793 local($spmrx) = join("\000",values %html_specials); 14794# escape regexp special chars (not really necessary yet, but why not) 14795 $spmrx = &escape_rx_chars($spmrx); #~ s:([\\(){}[\]\^\$*+?.|]):\\$1:g; 14796 $spmrx =~ s/\000/|/g; 14797 $spmrx = "(.)" unless $spmrx =~ s/(.+)/($1|.)/; 14798 14799 s/^[ \t]*(\d{1,3})[ \t]*/&#$1;/ && 14800 return($_); 14801 14802 s/^[ \t]*\'(\d{1,3})[ \t]*/"&#".oct($1).";"/e && 14803 return($_); 14804 14805 s/^[ \t]*$spmquot(\d{1,2})[ \t]*/"&#".hex($1).";"/e && 14806 return($_); 14807 14808# This is a kludge to work together with german.perl. Brrr. 14809 s/^[ \t]*\'\'(\d{1,2})[ \t]*/"&#".hex($1).";"/e && 14810 return($_); 14811# If l2h's special char marker represents more than one character, 14812# it's already in the &#xxx; form. Else convert the single character 14813# into &#xxx; with the ord() command. 14814 s/^[ \t]*\`\\?$spmrx[ \t]*/ 14815 (length($html_specials_inv{$1}) > 1 ? 14816 $html_specials_inv{$1} : "&#".ord($html_specials_inv{$1}||$1).";")/e && 14817 return($_); 14818 &write_warnings(join('', 14819 "Could not find character number in \\char", 14820 (/\n/ ? $` : $_), " etc.\n")); 14821 $_; 14822} 14823 14824 14825sub do_cmd_symbol { 14826 local($_) = @_; 14827 local($char); 14828 $char = &missing_braces 14829 unless ((s/$next_pair_pr_rx/$char = $2;''/eo) 14830 ||(s/$next_pair_rx/$char = $2;''/eo)); 14831 join('',&do_cmd_char($char),$_); 14832} 14833 14834################# Accent and Special Symbols ################################## 14835 14836# Generate code for the accents handling commands that are never 14837# applied to i or j. 14838# MEH: Now all accents are safe for dotless i or j 14839# MEH: Math accents supported as well 14840sub generate_accent_commands { 14841 local($accent,$accent_cmd); 14842 local(%accents) = ("c", "cedil", "pc", "cedil", "d", "bdot", "b", "b", 14843 "tilde", "tilde", "dot", "dot", "bar", "macr", 14844 "hat", "circ", "u", "breve", "v", "caron", 14845 "H", "dblac", "t", "t", "grave", "grave", 14846 "acute", "acute", "ddot", "uml", "check", "caron", 14847 "breve", "breve", "vec", "vec", 14848 "k", "ogon", "r", "ring"); 14849 foreach $accent (keys(%accents)) { 14850 $accent_cmd = "sub do_cmd_$accent {" . 'local($_) = @_;' . 14851 "&accent_safe_for_ij('$accents{$accent}','$accent');" . '$_}'; 14852 eval $accent_cmd; 14853 $accent_cmd = "do_cmd_$accent"; 14854 print STDERR "\n*** sub do_cmd_$accent failed:\nPERL: $@\n" if ($@); 14855 } 14856} 14857 14858# These handle accents, taking care of the dotless i's and j's that 14859# may follow (even though accented j's are not part of any alphabet 14860# that I know). 14861# 14862# Note that many forms of accents over dotless i's and j's are 14863# handled: 14864# "\^\i rest" 14865# "\^\i 14866# rest" 14867# "\^{\i}rest" 14868# "\^\i{}rest" 14869# They all produce "îrest". 14870# MEH: now also handles 14871# "\^{}rest" 14872# "\^,rest" 14873# and many more 14874 14875sub accent_safe_for_ij { 14876 local($type,$acc_cmd) = @_; 14877 local($arg, $first_char,$ij_cmd); 14878 #print STDOUT "\nACCENT: $type <$_>\n" ; 14879 s/^[ \t]*\n?[ \t]*(\S)/$1/; # Remove whitespace 14880 if (s/^\\([ij])([^a-zA-Z]|$)/$2/) { 14881 # Accent of this form: "\^\i rest" or "\^\i{}rest" 14882 ($arg) = $1; $ij_cmd = "\\$1"; 14883 s/^[ \t]+//o; # Get rid of whitespaces after \i 14884 if (substr($_, 0, 2) =~ /[\n\r][^\n\r]/) { 14885 $_ = substr($_, 1); # Get rid of 1 newline after \i 14886 } 14887 } else { 14888 # Accent of this form: "\^{\i}rest" or not an accent on i nor j 14889 ($arg) = &get_next_pair_or_char_pr; 14890 } 14891 $arg =~ s/([^\s\\<])/$first_char = $1; ''/eo; 14892# print STDOUT "\nACCENT1 type:$type arg:|${arg}| first_char: |$first_char| $ij_cmd 14893# , $ACCENT_IMAGES\n"; 14894 14895 local($aafter) = $_; 14896 local($iso) = &iso_map($first_char,$type); 14897 if ($iso) { $_ = join('', $iso, $arg, $aafter) } 14898 elsif ((!($ACCENT_IMAGES))&&(!($ij_cmd))) { 14899 local($err_string) = 14900 "\nNo available accent for $first_char$type , using just \"$first_char$arg\""; 14901 print $err_string if ($DEBUG||$VERBOSITY > 1); 14902 &write_warnings("\n ...set \$ACCENT_IMAGES to get an image "); 14903 $_ = join('', $first_char, $arg, $aafter) } 14904 else { 14905 print ", making image of accent: $first_char$type " if ($VERBOSITY > 1); 14906 $_ = join('', &mbox_accent($acc_cmd, $first_char, $ij_cmd) , $arg, $aafter) 14907 } 14908} 14909 14910sub mbox_accent { 14911 local($type, $char, $ij_cmd) = @_; 14912 if (length($type) > 1 ) { 14913 if ($text_accent{$type}) { 14914 $type = $text_accent{$type}; 14915 } elsif ($type =~ /^(math)?accent/) { 14916 } else { 14917 print "\n unrecognised accent $type for `$char' "; 14918 return $char; 14919 } 14920 } 14921 local(@styles); 14922 local($cmd,$style,$bstyle,$estyle) = ('','','',''); 14923 local(@styles) = split(',',$ACCENT_IMAGES); 14924 foreach $style (@styles) { 14925 $style =~ s/(^\s*\\|\s*)//g; 14926 $cmd = "do_cmd_$style"; 14927 if (defined &$cmd) { 14928 $bstyle .= "\\$style\{" ; 14929 $estyle .= "\}"; 14930 } else { 14931 &write_warnings("\nunrecognized style \\$style for accented characters"); 14932 } 14933 } 14934 if (!($bstyle)) { 14935 $bstyle = "\{"; 14936 $estyle = "\}"; 14937 } elsif ($bstyle =~ /textit|itshape/) { 14938 $bstyle = '\raise.5pt\hbox{' . $bstyle ; 14939 $estyle .= "\}"; 14940 } 14941 $char = $ij_cmd if ($ij_cmd); 14942 print STDOUT "\nACCENT: $type, $char" if ($VERBOSITY > 2); 14943 local($afterkern); # serifs extend too far on some letters... 14944 $afterkern = "\\kern.05em" if (($char =~ /m|n/)||($type=~/[Hv]/)); 14945 # ...or the accent is wider than the letter, so pad it out a bit 14946 $afterkern = "\\kern.15em" if ($char =~ /i|l/); #||($type=~/v/)); 14947 14948 &process_undefined_environment("tex2html_accent_inline" 14949 , ++$global{'max_id'}, "${bstyle}\\${type}\{$char\\/\}$estyle$afterkern"); 14950} 14951 14952# MEH: Actually tries to find a dotless i or j 14953sub do_cmd_i { join('',&iso_map('i', 'nodot') || 'i', $_[0]) } 14954sub do_cmd_j { join('',&iso_map('j', 'nodot') || 'j', $_[0]) } 14955 14956sub do_cmd_accent { 14957 local($_) = @_; 14958 local($number); 14959 if (s/\s*(\d+)\s*//o) {$number = $1} 14960 elsif (s/\s*&SMPquot;(\d)(\d)\s*//o) { $number = $1*16 + $2 } 14961 elsif (s/\s*\'(\d)(\d)(\d)\s*//o) { $number = $1*64 + $2*8 + $3 } 14962 else { s/\s*(\W\w+)([\s\W])/$2/o; $number = $1 } 14963 local($type) = $accent_type{uc($number)}; 14964 #print STDOUT "\ndo_cmd_accent: $number ($type) |$_|\n"; 14965 if (! $type) { 14966 &write_warnings("Accent number $number is unknown.\n"); 14967 return $_; 14968 } 14969 &accent_safe_for_ij($type , 'accent$number' ); 14970 $_; 14971} 14972 14973sub do_cmd_ae { join('', &iso_map("ae", "lig"), $_[0]);} 14974sub do_cmd_AE { join('', &iso_map("AE", "lig"), $_[0]);} 14975sub do_cmd_aa { join('', &iso_map("a", "ring"), $_[0]);} 14976sub do_cmd_AA { join('', &iso_map("A", "ring"), $_[0]);} 14977sub do_cmd_o { join('', &iso_map("o", "slash"), $_[0]);} 14978sub do_cmd_O { join('', &iso_map("O", "slash"), $_[0]);} 14979sub do_cmd_ss { join('', &iso_map("sz", "lig"), $_[0]);} 14980sub do_cmd_DH { join('', &iso_map("ETH", ""), $_[0]);} 14981sub do_cmd_dh { join('', &iso_map("eth", ""), $_[0]);} 14982sub do_cmd_TH { join('', &iso_map("THORN", ""), $_[0]);} 14983sub do_cmd_th { join('', &iso_map("thorn", ""), $_[0]);} 14984 14985sub do_cmd_pounds { join('', &iso_map("pounds", ""), $_[0]);} 14986sub do_cmd_S { join('', &iso_map("S", ""), $_[0]);} 14987sub do_cmd_copyright { join('', &iso_map("copyright", ""), $_[0]);} 14988sub do_cmd_P { join('', &iso_map("P", ""), $_[0]);} 14989 14990 14991sub brackets { ($OP, $CP);} 14992 14993sub get_date { 14994 local($format,$order) = @_; 14995 local(@lt) = localtime; 14996 local($d,$m,$y) = @lt[3,4,5]; 14997 if ($format =~ /ISO/) { 14998 sprintf("%4d-%02d-%02d", 1900+$y, $m+1, $d); 14999 } elsif ($format) { 15000 if ($order) { eval "sprintf(".$format.",".$order.")"; } 15001 else { sprintf($format, $d, $m+1, 1900+$y); } 15002 } else { sprintf("%d/%d/%d", $m+1, $d, 1900+$y); } 15003} 15004 15005sub address_data { 15006 local($user, $date, $_); 15007 local($format,$order) = @_; 15008 # Get author, (email address) and current date. 15009 ($user = L2hos->fullname()) =~ s/,.*//; 15010 ($user, &get_date($format,$order)); 15011} 15012 15013 15014#################################### LaTeX2e ################################## 15015 15016sub missing_braces { 15017# local($cmd) = @_; 15018 local($next, $revert, $thisline); 15019 local($this_cmd) = $cmd; 15020 $this_cmd =~ s/^\\// unless ($cmd eq "\\"); 15021 &write_warnings("\n? brace missing for \\$this_cmd"); 15022 if (/^[\s%]*([^\n]*)\n/ ) { 15023 $thisline = &revert_to_raw_tex($1) 15024 } else { 15025 $thisline = &revert_to_raw_tex($_); 15026 } 15027 print "\n\n*** no brace for \\$this_cmd , before:\n$thisline"; 15028 s/^\s*//; 15029 if ($_ =~ s/$next_token_rx//) { $next = $& }; 15030 $next =~ s/$comment_mark(\d+\n?)?//g; 15031# $next = &translate_commands($next) if ($next =~ /^\\/); 15032 if ($next =~ /^\\(\W|\d|[a-zA-z]*\b)/) { 15033 $revert = $next = "\\".$1; 15034 } elsif ($next =~ /\W/) { 15035 $revert = &revert_to_raw_tex($next); 15036 } else { $revert = $next }; 15037 print "\n*** using \"$revert\" as the argument instead; is this correct? ***\n\n"; 15038 $next; 15039} 15040 15041#RRM: 15042# &styled_text_chunk provides an interface for pieces of styled text, 15043# within a single paragraph. The visual markup can be obtained through either 15044# 1. link to a stylesheet (CSS) 15045# 2. direct markup placed into the output 15046# 3. calling another function to process the text 15047# 15048# parameters (in order): 15049# $def_tag : markup tag to be used, unless $USING_STYLES or no $property given, 15050# attributes can be included, only 1st word is used for closing-tag; 15051# $prefix : prefix for the Unique ID identifier, defaults to 'txt' 15052# OR contains CLASS= identifier when $property is empty(see below); 15053# $type : general type of the style-sheet information 15054# $class : specific type of the style-sheet information 15055# $property : value to be set, applicable to the $type & $class 15056# $alt_proc : name of procedure to use, if $USING_STYLES == 0, and no $def_tag 15057# $_ : current data-stream 15058# $open_tags_R : current open-tags (not used in this procedure) 15059 15060sub styled_text_chunk { 15061 local($def_tag, $prefix, $type, $class, $property, $alt_proc, $_, 15062 $ot) = @_; 15063 local($open_tags_R) = defined $ot ? $ot : $open_tags_R; 15064 local($text, $env_id, $def_end); 15065 local($span_tag) = 'SPAN'; 15066 $text = &missing_braces 15067 unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo) 15068 || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo)); 15069 $text = &balance_inner_tags($text); 15070 15071 #start from no open tags 15072 local(@save_open_tags) = (); 15073 local($open_tags_R) = []; 15074 15075# local($decl); 15076# if ($prefix =~ /CLASS="(\w+)"/ ) { 15077# $decl=$1; 15078# push (@$open_tags_R, $decl); 15079# } 15080# push (@$open_tags_R, $color_env) if $color_env; 15081 if (!$inside_math) { 15082 $text = &translate_environments($text); 15083 $text = &translate_commands($text) if ($text =~ /\\/); 15084 $text .= &balance_tags; 15085 } 15086 15087 if (($USING_STYLES)&&($env_id =~ /^\d+$/)&&($property)) { 15088 $prefix = 'txt' unless ($prefix); 15089 $env_id = $prefix.$env_id; 15090 $styleID{$env_id} = join('',"$type", ($class ? "-$class" : '') 15091 ,": ", $property,"; "); 15092 return(join('',"<$span_tag ID=\"$env_id\">",$text,"<\/$span_tag>", $_)); 15093 } 15094 15095 if (($USING_STYLES)&&($prefix =~ /($span_tag )?CLASS=\"(\w+)\"/o)) { 15096 local($span_class) = $2; 15097 $def_tag = (($1)? $1 : $span_tag." "); 15098 $txt_style{$span_class} = "$type: $class " 15099 unless ($txt_style{$span_class}); 15100 return(join('',"<$def_tag CLASS=\"$span_class\">" 15101 , $text,"<\/$span_tag>", $_)); 15102 } 15103 15104 if (($def_tag) && (!$USING_STYLES)) { 15105 $def_tag =~ s/^($span_tag)?CLASS=\"(\w+)\"$// ; 15106 } 15107 15108 if ($def_tag =~ /^(\w+)/) { 15109 $def_end = $1; 15110 return(join('',"<$def_tag>",$text,"<\/$def_end>", $_)); 15111 } 15112 15113 return (join('', eval ("&$alt_proc(\$text)") , $_)) if (defined "&$alt_proc"); 15114 15115 &write_warnings( 15116 "\ncannot honour request for $type-$class:$property style at br$env_id"); 15117 join('', $text, $_); 15118} 15119 15120sub multi_styled_text_chunk { 15121 local($def_tag, $prefix, $type, $class, $property, $_, $ot) = @_; 15122 local($open_tags_R) = defined $ot ? $ot : $open_tags_R; 15123 $prefix = 'txt' unless ($prefix); 15124 my(@def_tags) = split(',',$def_tag); 15125 my(@types) = split(',',$type); 15126 my(@classes) = split(',',$class); 15127 my(@properties) = split(',',$property); 15128 $text = &missing_braces 15129 unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo) 15130 || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo)); 15131 if (($USING_STYLES)&&($env_id =~ /^\d+$/)&&($property)) { 15132 # $1 contains the bracket-id 15133 $env_id = $prefix.$env_id; 15134 while (@properties) { 15135 $class = shift @classes; 15136 $property = shift @properties; 15137 $styleID{$env_id} .= join('' 15138 , shift @types, 15139 , ($class ? "-".$class : '') 15140 , ($property ? " : $property" : ''), " ; "); 15141 $styleID{$env_id} .= "\n\t\t " if (@properties); 15142 } 15143 } 15144 join('',"<SPAN ID=\"$env_id\">",$text,"<\/SPAN>", $_); 15145} 15146 15147#RRM: 15148# This one takes care of commands with argument that really should be 15149# environments; e.g. \centerline, \rightline, etc. 15150# Note that styles are inherited also from the existing @$open_tags_R. 15151# 15152sub styled_text_block { 15153 local($def_tag, $attrib, $value, $class, $_, $ot) = @_; 15154 local($open_tags_R) = defined $ot ? $ot : $open_tags_R; 15155 local($text, $env_id, $attribs); 15156 if ($attribs =~ /,/ ) { 15157 local(@attribs) = split(',',$attrib); 15158 local(@values) = split(',',$value); 15159 while (@attribs) { 15160 $attribs .= join('', " " , shift @attribs 15161 ,"=\"" , shift @values, "\"") } 15162 } elsif($value) { 15163 $attribs = join(''," ",$attrib,"=\"",$value,"\"") 15164 } else { $attribs = " " . $attrib } 15165 15166 local(@save_open_tags) = @$open_tags_R; 15167 local($closures) = &close_all_tags(); 15168 local($reopens)=&balance_tags(); 15169 $text = &missing_braces 15170 unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo) 15171 || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo)); 15172 if (($USING_STYLES)&&($env_id =~ /^\d+$/)) { 15173 $env_id = ++$global{'max_id'}; 15174 $env_id = "par".$env_id; 15175 $styleID{$env_id} = " "; 15176 $env_style{$class} = " " if (($class)&&!($env_style{$class})); 15177 $class = " CLASS=\"$class\"" if ($class); 15178 $env_id = " ID=\"$env_id\""; 15179 } else { $class = ''; $env_id = '' }; 15180 15181 $text = &translate_environments($text); 15182 $text = &translate_commands($text); 15183 15184 local($closuresA)=&close_all_tags(); 15185 local($reopensA) = &balance_tags(); 15186 $text =~ s/^\n?/\n/o; 15187 join('', $closures 15188 , "<$def_tag$class$env_id$attribs>" 15189 , $reopens, $text, $closuresA 15190 , "</$def_tag>\n", $reopensA, $_); 15191} 15192 15193 15194# this gives a separate ID for each instance 15195#sub do_cmd_textbf { &styled_text_chunk('B','','font','weight' 15196# ,'bold', '', @_); } 15197# 15198# this uses a single CLASS for all instances 15199sub do_cmd_textbf { &styled_text_chunk('B','CLASS="textbf"' 15200 ,'font-weight','bold', '', '', @_); } 15201 15202 15203# this gives a separate ID for each instance 15204sub do_cmd_texttt { &styled_text_chunk('TT','','font','','', '', @_); } 15205 15206# this uses a single CLASS for all instances 15207#sub do_cmd_textit { &styled_text_chunk('TT','CLASS="textit"' 15208# ,'font-family','monospace', '', '', @_); } 15209# 15210# this gives a separate ID for each instance 15211#sub do_cmd_textit { &styled_text_chunk('I','','font','style' 15212# ,'italic', '', @_); } 15213# 15214# this uses a single CLASS for all instances 15215sub do_cmd_textit { &styled_text_chunk('I','CLASS="textit"' 15216 ,'font-style','italic', '', '', @_); } 15217 15218 15219 15220# this gives a separate ID for each instance 15221#sub do_cmd_textsl { &styled_text_chunk('I','','font','style' 15222# ,'oblique', '', @_); } 15223# 15224# this uses a single CLASS for all instances 15225#sub do_cmd_textsl { &styled_text_chunk('I','CLASS="textsl"' 15226# ,'font-style','oblique', '', '', @_); } 15227# 15228# ... NS4 implements Italic, not oblique 15229sub do_cmd_textsl { &styled_text_chunk('I','CLASS="textsl"' 15230 ,'font-style','italic', '', '', @_); } 15231 15232 15233# this gives a separate ID for each instance 15234#sub do_cmd_textsf { &styled_text_chunk('I','','font','family' 15235# ,'sans-serif', '', @_); } 15236# 15237# this uses a single CLASS for all instances 15238#sub do_cmd_textsf { &styled_text_chunk('I','CLASS="textsf"' 15239# ,'font-family','sans-serif', '', '', @_); } 15240# 15241# ... NS4 doesn't implement sans-serif 15242sub do_cmd_textsf { &styled_text_chunk('I','CLASS="textsf"' 15243 ,'font-style','italic', '', '', @_); } 15244 15245 15246#sub do_cmd_textsc { 15247# local($_) = @_; 15248# local($text, $next, $scstr, $before, $special); 15249# $text = &missing_braces 15250# unless ((s/$next_pair_pr_rx/$text = $2;''/eo) 15251# || (s/$next_pair_rx/$text = $2;''/eo)); 15252# join('', &process_smallcaps($text), $_); 15253#} 15254 15255sub lowercase_entity { 15256 local($char) = @_; 15257 local($exent); 15258 if ($exent = $low_entities{$char}) { "\&#$exent;" } 15259 elsif ($exent = $extra_small_caps{$char}) { $exent } 15260 else { "\&#$char;" } 15261} 15262 15263sub process_smallcaps { 15264 local($text) = @_; 15265 local($next, $scstr, $scbef, $special, $char); 15266 # is this enough for \sc and \scshape ? 15267 $text = &translate_environments($text); 15268 15269 # MRO: replaced $* with /m 15270 while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;|<[^>]+>)+/m ) { 15271 $scbef = $`; $special = $&; $text = $'; 15272 while ( $scbef =~ /(&#\d+;|[a-z$sclower])+[a-z\W\d$sclower]*/m) { 15273 $scstr .= $`; $scbef = $'; 15274 $next = $&; 15275 $next =~ s/&#(\d+);/&lowercase_entity($1)/egm; 15276 eval "\$next =~ $scextra" if ($scextra); 15277 eval "\$next =~ tr/a-z$sclower/A-Z$scupper/"; 15278 $scstr .= "<SMALL>" . $next ."<\/SMALL>"; 15279 } 15280 $scstr .= $scbef . $special; 15281 } 15282 if ($text) { 15283 while ( $text =~ /(&#\d+;|[a-z$sclower])+[a-z\W\d$sclower]*/m) { 15284 $scstr .= $`; $text = $'; 15285 $next = $&; 15286 $next =~ s/&#(\d+);/&lowercase_entity($1)/egm; 15287 eval "\$next =~ $scextra" if ($scextra); 15288 eval "\$next =~ tr/a-z$sclower/A-Z$scupper/"; 15289 $scstr .= "<SMALL>" . $next ."<\/SMALL>"; 15290 } 15291 $scstr .= $text; 15292 } 15293 $scstr; 15294} 15295 15296# this gives a separate ID for each instance 15297#sub do_cmd_textsc { &styled_text_chunk('','','font','variant' 15298# ,'small-caps', 'process_smallcaps', @_); } 15299# 15300# this uses a single CLASS for all instances 15301#sub do_cmd_textsc { &styled_text_chunk('', 'CLASS="textsc"' 15302# ,'font-variant','small-caps','', 'process_smallcaps', @_); } 15303# 15304# ...but NS 4.03 doesn't implement small-caps !!! 15305sub do_cmd_textsc { &styled_text_chunk('','' 15306 ,'font-variant','small-caps','', 'process_smallcaps', @_); } 15307 15308 15309#sub do_cmd_emph { &styled_text_chunk('EM','em','font','variant','','', @_); } 15310 15311 15312# this gives a separate ID for each instance 15313#sub do_cmd_underline { &styled_text_chunk('U','','text','decoration','underline','', @_); } 15314 15315# this uses a single CLASS for all instances 15316sub do_cmd_underline { &styled_text_chunk('U','CLASS="underline"' 15317 ,'text-decoration','underline','','', @_); } 15318sub do_cmd_underbar { &do_cmd_underline(@_) } 15319 15320 15321# this gives a separate ID for each instance 15322#sub do_cmd_strikeout { &styled_text_chunk('STRIKE','' 15323# ,'text','decoration','line-through','', @_); } 15324 15325# this uses a single CLASS for all instances 15326sub do_cmd_strikeout { &styled_text_chunk('STRIKE','CLASS="strikeout"', 15327 'text-decoration','line-through','','', @_); } 15328 15329 15330sub do_cmd_uppercase { 15331 local($_) = @_; 15332 local($text,$next,$done,$special,$after); 15333 $text = &missing_braces unless ( 15334 (s/$next_pair_pr_rx/$text = $2;''/eo) 15335 ||(s/$next_pair_rx/$text = $2;''/eo)); 15336 $after = $_; 15337 while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;)/ ) { 15338 $next = $`; 15339 $special = $&; 15340 $text = $'; 15341 $next =~ tr /a-z/A-Z/ if ($next); 15342 $done .= $next . $special; 15343 } 15344 $text =~ tr /a-z/A-Z/ if ($text); 15345 $done .= $text; 15346 $done = &convert_iso_latin_chars($done) if ($done); 15347 join('',$done,$after); 15348} 15349 15350sub do_cmd_lowercase { 15351 local($_) = @_; 15352 local($text,$next,$done,$special,$after); 15353 $text = &missing_braces 15354 unless ((s/$next_pair_pr_rx/$text = $2;''/seo) 15355 || (s/$next_pair_rx/$text = $2;''/seo)); 15356 $after = $_; 15357 while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;)/ ) { 15358 $next = $`; 15359 $special = $&; 15360 $text = $'; 15361 $next =~ tr /A-Z/a-z/ if ($next); 15362 $done .= $next . $special; 15363 } 15364 $text =~ tr /A-Z/a-z/ if ($text); 15365 $done .= $text; 15366 $done = &convert_iso_latin_chars($done) if ($done); 15367 join('',$done,$after); 15368} 15369 15370sub do_cmd_MakeUppercase { &do_cmd_uppercase(@_) } 15371sub do_cmd_MakeLowercase { &do_cmd_lowercase(@_) } 15372 15373 15374 15375sub do_cmd_ensuremath { 15376 local($_) = @_; 15377 local ($id, $value); 15378 $value = &missing_braces unless ( 15379 (s/$next_pair_pr_rx/$value=$2;''/eo) 15380 ||(s/$next_pair_rx/$value=$2;''/eo)); 15381 join('', &simple_math_env($value), $'); 15382} 15383 15384# 15385# This is mainly for \special{header=PostScript_Prologue}, 15386# and \graphicspath{path} which occur OUTSIDE of an environment 15387# passed to TeX. \special's INSIDE such environments are, of 15388# course, left alone. 15389 15390sub do_cmd_special { 15391 local($_) = @_; 15392 local ($id, $value); 15393 $value = &missing_braces unless ( 15394 (s/$next_pair_pr_rx/$value=$2;''/eo) 15395 ||(s/$next_pair_rx/$value=$2;''/eo)); 15396 local($special_cmd) = &revert_to_raw_tex($value); 15397 &add_to_preamble($cmd,"\\$cmd\{$special_cmd\}"); 15398 $_; 15399} 15400 15401 15402########################## Input and Include commands ######################### 15403 15404sub do_cmd_input { 15405 local($_) = @_; 15406 local($file,$output); 15407 (s/\s*(.*)\s*\n/$file =$1;''/s) unless ( 15408 (s/$next_pair_pr_rx/$file=$2;''/eo) 15409 ||(s/$next_pair_rx/$file=$2;''/eo)); 15410 local($after) = $_; 15411 $file = &revert_to_raw_tex("\\input{$file}\n") if $file; 15412 if ($PREAMBLE) { &add_to_preamble('include',$file)} 15413 elsif (!($file=~/^\s*$/)) { 15414 $output = &process_undefined_environment('center' 15415 , ++$global{'max_id'},"\\vbox{$file}"); 15416 } 15417 $output.$after; 15418} 15419 15420sub do_cmd_include { 15421 local($_) = @_; 15422 local($file,$output); 15423 $file = &missing_braces unless ( 15424 (s/$next_pair_pr_rx/$file=$2;''/eo) 15425 ||(s/$next_pair_rx/$file=$2;''/eo)); 15426 local($after) = $_; 15427 $file = &revert_to_raw_tex("\\include{$file}\n") if $file; 15428 if ($PREAMBLE) { &add_to_preamble('include',$file)} 15429 else { 15430 $output = &process_undefined_environment('figure' 15431 , ++$global{'max_id'},"\\vbox{$file}"); 15432 } 15433 $output.$after; 15434} 15435 15436########################## Messages ######################### 15437 15438sub do_cmd_message { 15439 local($_) = @_; 15440 local($message); 15441 $message = &missing_braces unless ( 15442 (s/$next_pair_pr_rx/$message=$2;''/eo) 15443 ||(s/$next_pair_rx/$message=$2;''/eo)); 15444 local($after) = $_; 15445 $message = &translate_commands($message); 15446 $message =~ s/$comment_mark(\d+)//og; 15447 print STDOUT "\n*** $message ***\n"; 15448 $after; 15449} 15450 15451sub do_cmd_typeout { 15452 print STDOUT "\n"; 15453 local($_) = &do_cmd_message(@_); 15454 print STDOUT "\n"; 15455 $_; 15456} 15457 15458sub do_cmd_expandafter { 15459 local($_) = @_; 15460 print "\nEXPANDAFTER: " if ($VERBOSITY >3); 15461 return($_) unless (s/^\s*(\\\w+)\s*\\//o); 15462 print " delaying $1 " if ($VERBOSITY >3); 15463 local($delay,$cmd) = ($1,''); 15464 s/^(\w+|\W)/$cmd=$1;''/eo; 15465 local($nextcmd) = "do_cmd_$cmd"; 15466 if (defined &$nextcmd) { $_ = &$nextcmd($_) } 15467 elsif ($new_command{$cmd}) { 15468 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 15469 do { ### local($_) = $body; 15470 &make_unique($body); 15471 } if ($body =~ /$O/); 15472 if ($argn) { 15473 do { 15474 local($before) = ''; 15475 local($after) = "\\$cmd ".$_; 15476 $after = &substitute_newcmd; # may change $after 15477 $after =~ s/\\\@#\@\@/\\/o unless ($after); 15478 }; 15479 } else { $_ = $body . $_; } 15480 } else { print "\nUNKNOWN COMMAND: $cmd "; } 15481 15482 # now put the delayed function back for processing 15483 join('',$delay, " ", $_); 15484} 15485 15486sub do_cmd_tracingall { 15487 print "\nTRACING:\n$ref_contents\n$after\n"; 15488 $VERBOSITY = 8; ""; } 15489 15490sub do_cmd_htmltracenv { &do_cmd_htmltracing } 15491 15492sub do_cmd_htmltracing { 15493 local($_) = @_; 15494 local($value); 15495 $value = &missing_braces 15496 unless ((s/$next_pair_rx/$value = $2;''/eo) 15497 ||(s/$next_pair_pr_rx/$value = $2;''/eo)); 15498 if ($value =~ /^\s*(\d+)\s*$/) { 15499 $VERBOSITY = $1; 15500 if ($VERBOSITY) { 15501 print "\n\n *** setting trace-level to $VERBOSITY ***\n"; 15502 } else { 15503 print "\n\n *** cancelling all tracing ***\n\n"; 15504 } 15505 } else { 15506 &write_warnings("argument to \\htmltracing must be a number"); 15507 } 15508 $_ ; 15509} 15510 15511 15512############################ Initialization #################################### 15513 15514sub initialise { 15515 ############################ Global variables ############################### 15516 $PREAMBLE = 2; # 1 while translating preamble, 0 while translating body 15517 $NESTING_LEVEL = undef; #counter for TeX group nesting level 15518 $OUT_NODE = 0; # Used in making filenames of HTML nodes unique 15519 $eqno_prefix = ''; # default prefix on equation numbers 15520 ($O , $C, $OP, $CP) = ('<<' , '>>', '<#', '#>'); # Open/Close Markers 15521 $href_name = 0; # Used in the HREF NAME= field 15522 $wrap_toggle = 'end'; 15523 $delim = '%:%'; # Delimits items of sectioning information 15524 # stored in a string 15525 15526 $LATEX2HTML_META = '<META NAME="Generator" CONTENT="LaTeX2HTML v'.$TEX2HTMLV_SHORT.'">' 15527 . "\n<META HTTP-EQUIV=\"Content-Style-Type\" CONTENT=\"text/css\">" 15528 unless ($LATEX2HTML_META); 15529 15530 $TeXname = (($HTML_VERSION ge "3.0")? "T<SMALL>E</SMALL>X" : "TeX"); 15531 $Laname = (($HTML_VERSION ge "3.0")? "L<SUP><SMALL>A</SMALL></SUP>" : "La"); 15532 $MFname = (($HTML_VERSION ge "3.0")? "M<SMALL>ETAFONT</SMALL>" : "Metafont"); 15533 $Xyname = (($HTML_VERSION ge "3.0")? "X<SUB><BIG>Y</BIG></SUB>" : "Xy"); 15534 $AmSname = (($HTML_VERSION ge "3.0")? "A<SUB><BIG>M</BIG></SUB>S" : "AmS"); 15535 15536 $EQN_TAGS = "R" unless ($EQN_TAGS); 15537 $EQNO_START = "("; 15538 $EQNO_END = ")"; 15539 15540 $AtBeginDocument_hook = "\$AtBeginDocument_hook\=\'\'; " 15541 unless $AtBeginDocument_hook; 15542 $cross_ref_mark = '<tex2html_cr_mark>'; 15543 $external_ref_mark = '<tex2html_ext_cr_mark>'; 15544 $cite_mark = '<tex2html_cite_mark>'; 15545 $hash_mark = '<tex2html_hash_mark>'; 15546 $protected_hash = '<tex2html_protected_hash>'; 15547 $param_mark = '<tex2html_param_mark>'; 15548 $bbl_mark = '<tex2html_bbl_mark>'; 15549 $toc_mark = '<tex2html_toc_mark>'; 15550 $lof_mark = '<tex2html_lof_mark>'; 15551 $lot_mark = '<tex2html_lot_mark>'; 15552 $info_page_mark = '<tex2html_info_page_mark>'; 15553 $info_title_mark = '<tex2html_info_title_mark>'; 15554 $init_file_mark = '<tex2html_init_file_mark>'; 15555 $childlinks_on_mark = '<tex2html_childlinks_mark>'; 15556 $childlinks_null_mark = '<tex2html_childlinks_null_mark>'; 15557 $childlinks_mark = $childlinks_on_mark; 15558 $more_links_mark = '<tex2html_morelinks_mark>'; 15559 $idx_mark = '<tex2html_idx_mark>'; 15560 $verbatim_mark = '<tex2html_verbatim_mark>'; 15561 $unfinished_mark = '<tex2html_unfinished_mark>'; 15562 $verb_mark = '<tex2html_verb_mark>'; 15563 $verbstar_mark = '<tex2html_verbstar_mark>'; 15564 $image_mark = '<tex2html_image_mark>'; 15565 $mydb_mark = '<tex2html_mydb_mark>'; 15566 $percent_mark = '<tex2html_percent_mark>'; 15567 $ampersand_mark = '<tex2html_ampersand_mark>'; 15568 $dol_mark = '<tex2html_lone_dollar>'; 15569 $comment_mark = '<tex2html_comment_mark>'; 15570 $caption_mark = '<tex2html_caption_mark>'; 15571 $array_col_mark = '<tex2html_col_mark>'; 15572 $array_row_mark = '<tex2html_row_mark>'; 15573 $array_text_mark = '<tex2html_text_mark>'; 15574 $array_mbox_mark = '<tex2html_mbox_mark>'; 15575 15576 $bibitem_counter = 0; 15577 $undef_mark = '<tex2html_undef_mark>'; 15578 $file_mark = '<tex2html_file>'; 15579 $endfile_mark = '<tex2html_endfile>'; 15580 15581 # This defines textual markers for all the icons 15582 # e.g. $up_visible_mark = '<tex2html_up_visible_mark>'; 15583 # They will be replaced with the real icons at the very end. 15584 foreach $icon (keys %icons) {eval "\$$icon = '<tex2html_$icon>'"}; 15585 15586 # Make sure $HTML_VERSION is in the right range and in the right format. 15587# $HTML_VERSION =~ /[\d.]*/; 15588# $HTML_VERSION = 0.0 + $&; 15589# $HTML_VERSION = 2 if ( $HTML_VERSION < 2 ); 15590# $HTML_VERSION = 9 if ( $HTML_VERSION > 9 ); 15591# $HTML_VERSION = sprintf("%3.1f",$HTML_VERSION); 15592 15593 &banner(); 15594 print "Revised and extended by:" 15595 . "\n Marcus Hennecke, Ross Moore, Herb Swan and others\n"; 15596 15597 # Collect HTML options and figure out HTML version 15598 $HTML_OPTIONS = '' unless ($HTML_OPTIONS); 15599 $HTML_VERSION =~ s/^html|\s+//g; 15600 local(@HTML_VERSION) = split(/,/, $HTML_VERSION); 15601 foreach ( @HTML_VERSION ) { 15602 if (/^[\d\.]+$/) { 15603 # Make sure $HTML_VERSION is in the right range and in the right format. 15604 $HTML_VERSION = 0.0 + $_; 15605 $HTML_VERSION = 2 if ( $HTML_VERSION < 2 ); 15606 $HTML_VERSION = 9 if ( $HTML_VERSION > 9 ); 15607 $HTML_VERSION = sprintf("%3.1f",$HTML_VERSION); 15608 } else { 15609 $HTML_OPTIONS .= "$_,"; 15610 } 15611 } 15612 $HTML_OPTIONS =~ s/\W$//; # remove any trailing punctuation 15613 15614 print "...producing markup for HTML version $HTML_VERSION "; 15615 print ($HTML_OPTIONS ? "with $HTML_OPTIONS extensions\n\n\n" : "\n\n\n"); 15616 15617 # load the character defs for latin-1, but don't set the charset yet 15618 &do_require_extension('latin1'); 15619 $charset = $CHARSET = $PREV_CHARSET = ''; 15620 15621 if ($HTML_VERSION =~ /(2.0|3.0|3.2|4.0|4.1)/) { 15622 # Require the version specific file 15623 do { $_ = "$LATEX2HTMLVERSIONS${dd}html$1.pl"; 15624 if (!(-f $_)) { s/(\d).(\d.pl)$/$1_$2/ }; 15625 if (!(-f $_)) { s/(\d)_(\d.pl)$/$1-$2/ }; 15626 require $_ || die "\n*** Could not load $_ ***\n"; 15627 print "\nHTML version: loading $_\n"; 15628 } unless ($HTML_VERSION =~ /2.0/); 15629 $DOCTYPE = "-//".(($HTML_VERSION eq "2.0")? "IETF" : "W3C") 15630 . "//DTD HTML $HTML_VERSION" 15631 .(($HTML_VERSION eq "3.2")? " Final" : "") 15632 .(($HTML_VERSION eq "4.0")? " Transitional" : ""); 15633 15634 if ($HTML_OPTIONS) { 15635 local($ext); 15636 local($loading_extensions) = 1; 15637 # Require the option specific files 15638 @HTML_VERSION = split(/,/, $HTML_OPTIONS); 15639 foreach $ext ( @HTML_VERSION ) { 15640 &do_require_extension($ext); 15641# do { 15642# print "\nLoading $LATEX2HTMLVERSIONS$dd$ext.pl"; 15643# require "$LATEX2HTMLVERSIONS$dd$ext.pl"; 15644# } if (-f "$LATEX2HTMLVERSIONS$dd$ext.pl"); 15645 } 15646 undef $loading_extensions; 15647 } 15648 } else { 15649 print "\n You specified an invalid version: $HTML_VERSION\n" 15650 . "In future please request extensions by name:\n" 15651 . " i18n table math frame latin1 unicode etc.\n"; 15652 15653 # Require all necessary version specific files 15654 foreach ( sort <$LATEX2HTMLVERSIONS${dd}html[1-9].[0-9].pl> ) { 15655 last if ( $_ gt "$LATEX2HTMLVERSIONS${dd}html$HTML_VERSION.pl" ); 15656 do { print "\nloading $_" if ($DEBUG); 15657 require $_; } unless ( 15658 ($NO_SIMPLE_MATH)&&($_ eq "$LATEX2HTMLVERSIONS${dd}html3.1.pl")); 15659 }; 15660 $STRICT_HTML = 0; 15661 } 15662 15663 # packages automatically implemented, or clearly irrelevant 15664 %styles_loaded = 15665 ( 'theorem' , 1 , 'enumerate', 1 , 'a4paper' , 1 , 'b5paper' , 1 15666 , '10pt' , 1 , '11pt' , 1 , '12pt' , 1 15667 , %styles_loaded ); 15668 15669 15670 %declarations = 15671 ('em' , '<EM></EM>', 15672 'it' , '<I></I>', 15673 'bf' , '<B></B>', 15674 'tt' , '<TT></TT>', 15675 'sl' , '<I></I>', # Oops! 15676 'sf' , '<I></I>', # Oops! 15677 'rm' , '<></>', 15678 'rmfamily' ,'<></>', # see $fontchange_rx 15679 'normalfont' ,'<></>', # see $fontweight_rx and $fontchange_rx 15680 'mdseries' ,'<></>', # see $fontweight_rx 15681 'upshape' ,'<></>', # see $fontchange_rx 15682 'itshape' , '<I></I>', 15683 'bfseries' , '<B></B>', 15684 'ttfamily' , '<TT></TT>', 15685 'slshape' , '<I></I>', # Oops! 15686 'sffamily' , '<I></I>', # Oops! 15687## 'scshape' , '<I></I>', # Oops! 15688# 'boldmath' , '<B></B>', 15689# 'quote', '<BLOCKQUOTE></BLOCKQUOTE>', 15690# 'quotation', '<BLOCKQUOTE></BLOCKQUOTE>', 15691 %declarations # Just in case someone extends it in the init file 15692 ); 15693 15694 15695%declarations = ( 15696 'tiny', '<FONT SIZE="-2"></FONT>', 15697 'Tiny', '<FONT SIZE="-2"></FONT>', 15698 'scriptsize', '<FONT SIZE="-2"></FONT>', 15699 'small', '<FONT SIZE="-1"></FONT>', 15700 'Small', '<FONT SIZE="-1"></FONT>', 15701 'SMALL', '<FONT SIZE="-1"></FONT>', 15702 'smaller', '<SMALL></SMALL>', 15703 'footnotesize', '<FONT SIZE="-1"></FONT>', 15704 'larger', '<BIG></BIG>', 15705 'large', '<FONT SIZE="+1"></FONT>', 15706 'Large', '<FONT SIZE="+2"></FONT>', 15707 'LARGE', '<FONT SIZE="+2"></FONT>', 15708 'huge', '<FONT SIZE="+3"></FONT>', 15709 'Huge', '<FONT SIZE="+4"></FONT>', 15710# 'centering', '<DIV ALIGN="CENTER"></DIV>', 15711# 'center', '<DIV ALIGN="CENTER"></DIV>', 15712# 'flushleft', '<DIV ALIGN="LEFT"></DIV>', 15713# 'raggedright', '<DIV ALIGN="LEFT"></DIV>', 15714# 'flushright', '<DIV ALIGN="RIGHT"></DIV>', 15715# 'raggedleft', '<DIV ALIGN="RIGHT"></DIV>', 15716 %declarations 15717 ) if ($HTML_VERSION > 2.0 ); 15718 15719# no alignment in HTML 2.0 15720#%declarations = ( 15721# 'centering', '<P ALIGN="CENTER"></P>', 15722# 'center', '<P ALIGN="CENTER"></P>', 15723# 'flushleft', '<P ALIGN="LEFT"></P>', 15724# 'raggedright', '<P ALIGN="LEFT"></P>', 15725# 'flushright', '<P ALIGN="RIGHT"></P>', 15726# 'raggedleft', '<P ALIGN="RIGHT"></P>', 15727 15728%declarations = ( 15729# 'centering', '<P></P>', 15730 'center', '<P></P>', 15731 'flushleft', '<P></P>', 15732 'raggedright', '<P></P>', 15733 'flushright', '<P></P>', 15734 'raggedleft', '<P></P>', 15735 'quote', '<BLOCKQUOTE></BLOCKQUOTE>', 15736 'quotation', '<BLOCKQUOTE></BLOCKQUOTE>', 15737 'verse', '<BLOCKQUOTE></BLOCKQUOTE>', 15738 'preform', '<PRE></PRE>', 15739 'unord', '<UL></UL>', 15740 'ord', '<OL></OL>', 15741 'desc', '<DL></DL>', 15742 'list', '', 15743 'par', '<P></P>' 15744 ) if ($HTML_VERSION == 2.0 ); 15745 15746 &generate_declaration_subs; # Generate code to handle declarations 15747 15748 # ...but these block-level divisions must be handled differently... 15749%declarations = ( 15750 'quote', '<BLOCKQUOTE></BLOCKQUOTE>', 15751 'quotation', '<BLOCKQUOTE></BLOCKQUOTE>', 15752 'verse', '<BLOCKQUOTE></BLOCKQUOTE>', 15753 'preform', '<PRE></PRE>', 15754 'unord', '<UL></UL>', 15755 'ord', '<OL></OL>', 15756 'desc', '<DL></DL>', 15757# 'list', '<DIV></DIV>', 15758 'par', '<P></P>', 15759 'samepage', '', 15760# 'centering', '<DIV ALIGN="CENTER"></DIV>', 15761 'center', '<DIV ALIGN="CENTER"></DIV>', 15762 'flushleft', '<DIV ALIGN="LEFT"></DIV>', 15763 'raggedright', '<DIV ALIGN="LEFT"></DIV>', 15764 'flushright', '<DIV ALIGN="RIGHT"></DIV>', 15765 'raggedleft', '<DIV ALIGN="RIGHT"></DIV>', 15766 %declarations 15767 ) if ($HTML_VERSION > 2.0 ); 15768 15769 15770 %section_commands = 15771 ('partstar' , '1' , 'chapterstar', '2', 'sectionstar', '3' 15772 , 'subsectionstar', '4', 'subsubsectionstar', '5', 'paragraphstar' 15773 , '6', 'subparagraphstar', '7' 15774 , 'part' , '1' , 'chapter', '2', 'section', '3','subsection', '4' 15775 , 'subsubsection', '5', 'paragraph', '6', 'subparagraph', '7' 15776 , 'slidehead', '3', %section_commands); 15777 # The tableofcontents, listoffigures, listoftables, bibliography and 15778 # textohtmlindex are set after determining what is the outermost level 15779 # in sub set_depth_levels. Appendix is implemented as a command. 15780 15781 %standard_section_headings = 15782 ('part' , 'H1' , 'chapter' , 'H1', 'section', 'H1', 'subsection', 'H2' 15783 , 'subsubsection', 'H3', 'paragraph', 'H4', 'subparagraph', 'H5' 15784 , %standard_section_headings ); 15785 15786 # Generates code to handle sectioning commands 15787 # for those sections which take an argument. 15788 &generate_sectioning_subs; 15789 15790 %section_headings = 15791 ('partstar' , 'H1' , 'chapterstar' , 'H1', 'sectionstar', 'H1' 15792 , 'subsectionstar', 'H2', 'subsubsectionstar', 'H3', 'paragraphstar' 15793 , 'H4', 'subparagraphstar', 'H5', %section_headings); 15794 15795 # These need their own custom code but are treated as sectioning commands 15796 %section_headings = 15797 ('tableofcontents', 'H2', 'listoffigures', 'H2', 'listoftables', 'H2' 15798 , 'bibliography', 'H2', 'textohtmlindex', 'H2' 15799 , %standard_section_headings 15800 , %section_headings); 15801 15802 &generate_accent_commands; # Code to handle accent commands 15803 15804 # These are replaced as soon as the text is read in. 15805 %html_specials = ( '<', ';SPMlt;' 15806 , '>', ';SPMgt;' 15807 , '&', ';SPMamp;' 15808# , '``', '\lq\lq ' # probably not a good idea 15809# , "''", '\rq\rq ', # probably not a good idea 15810 , '"', ';SPMquot;' 15811 ); 15812 15813 %html_specials = ( %html_specials 15814 , '``', ';SPMldquo;', "''", ';SPMrdquo;' 15815 ) if ($HTML_VERSION >= 5 ); 15816 15817 # This mapping is needed in sub revert_to_raw_tex 15818 # before passing stuff to latex for processing. 15819 %html_specials_inv = ( 15820 ';SPMlt;' ,'<' 15821 , ';SPMgt;','>' 15822 , ';SPMamp;','&' 15823 , ';SPMquot;','"' 15824 , ';SPMldquo;','``' 15825 , ';SPMrdquo;',"''" 15826 , ';SPMdollar;', '$' # for alltt 15827 , ';SPMpct;', '%' 15828 , ';SPMtilde;', '~' 15829 ); 15830 15831 # normalsize vertical dimension factors for 12pt (1.0 <=> <BR>) 15832 %vspace_12pt = ('ex', 1.0, 'em', 1.0, 'pt', 0.1, 'pc', 1.0, 15833 'in', 6.0, 'bp', 0.1, 'cm', 2.3, 'mm', 0.2, 'dd', 0.1, 15834 'cc', 1.0, 'sp', 0.0); 15835 15836 # For some commands such as \\, \, etc it is not possible to define 15837 # perl subroutines because perl does not allow some non-ascii characters 15838 # in subroutine names. So we define a table and a subroutine to relate 15839 # such commands to ascii names. 15840 %normalize = ('\\', 'd_backslash' 15841 , '/', 'esc_slash', "`", 'grave' 15842 , "'", 'acute', "^", 'hat', '"', 'ddot' 15843 , '~', 'tilde', '.', 'dot', '=', 'bar' 15844 , '{', 'lbrace' , '}', 'rbrace', '|', 'Vert' 15845 , '#', 'esc_hash', '$', 'esc_dollar' 15846 ); 15847 15848 %text_accent = ( 'cedil','c', 'bdot','d', 'b','b' , 'tilde','~' 15849 , 'circ' ,'^', 'hat','^', 'check','v' , 'caron','v' 15850 , 'acute','\'' , 'grave','`' , 'dot','.' , 'breve','u' 15851 , 'ddot','"' , 'uml','"' , 'bar','=','macr','=' 15852 , 'dblacc','H' , 't','t' , 'ogon','k' , 'ring','r' 15853 ); 15854 15855 # %languages_translations holds for each known language the 15856 # appropriate translation function. The function is called in 15857 # slurp_input. 15858 # The translation functions subtitute LaTeX macros 15859 # with ISO-LATIN-1 character references 15860 %language_translations = ( 15861 'english', 'english_translation' 15862 , 'USenglish', 'english_translation' 15863 , 'original', 'english_translation' 15864 , 'german', 'german_translation' 15865 , 'austrian', 'german_translation' 15866 , 'finnish', 'finnish_translation' 15867 , 'french', 'french_translation' 15868 , 'spanish', 'spanish_translation' 15869 , 'swedish', 'swedish_translation' 15870 , 'turkish', 'turkish_translation' 15871 ); 15872 15873# Reiner: 15874# $standard_label_rx = 15875# "\\s*[[]\\s*(((\$any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]"; 15876# $enum_label_rx = "^((({[^{}]*})|([^{}]))*)([aAiI1])(.*)"; 15877# $enum_level = 0; # level for enumerate (1-4, i-iv) 15878 %enum = ( 15879 'enumi', 0, # counter for level 1 15880 'enumii', 0, # counter for level 2 15881 'enumiii', 0, 15882 'enumiv', 0, 15883 'theenumi', "&arabic('enumi')", # eval($enum{"theenumi"}) 15884 'theenumii', "&alph('enumii')", 15885 'theenumiii', "&roman('enumiii')", 15886 'theenumiv', "&Alph('enumiv')", 15887 # e.g. eval("$enum{'labelenumi'}") 15888 'labelenumi', 'eval($enum{"theenumi"}) . "."', 15889 'labelenumii', '"(" . eval($enum{"theenumii"}) . ")"', 15890 'labelenumiii', 'eval($enum{"theenumiii"}) . "."', 15891 'labelenumiv', 'eval($enum{"theenumiv"}) . "."' 15892 ); 15893 15894 %RomanI = ( '1',"I",'2',"II",'3',"III",'4',"IV" 15895 ,'5',"V",'6',"VI",'7',"VII", '8',"VIII",'9',"IX"); 15896 %RomanX = ( '1',"X",'2',"XX",'3',"XXX",'4',"XL" 15897 ,'5',"L",'6',"LX",'7',"LXX", '8',"LXXX",'9',"XC"); 15898 %RomanC = ( '1',"C",'2',"CC",'3',"CCC",'4',"CD" 15899 ,'5',"D",'6',"DC",'7',"DCC", '8',"DCCC",'9',"CM"); 15900 %RomanM = ( '1',"M",'2',"MM",'3',"MMM",'4',"MH" 15901 ,'5',"H",'6',"HM",'7',"HMM",'8',"HMMM"); 15902 15903 %enum_label_funcs = ( 15904 "a", "alph", "A", "Alph", "i", "roman", "I", "Roman", "1", "arabic" ); 15905 15906sub farabic{ 15907 local($_)=@_; 15908 $_; 15909} 15910sub arabic{ 15911 local($_)=@_; 15912 eval($enum{$_}); 15913} 15914 15915sub falph{ 15916 local($num)=@_; 15917# chr($num+64); 15918 substr(" abcdefghijklmnopqrstuvwxyz",$num,1) 15919} 15920sub alph{ 15921 local($num)=@_; 15922 &falph(eval($enum{$num})); 15923} 15924sub fAlph{ 15925 local($num)=@_; 15926# chr($num+32); 15927 substr(" ABCDEFGHIJKLMNOPQRSTUVWXYZ",$num,1) 15928} 15929sub Alph{ 15930 local($num)=@_; 15931 &falph(eval($enum{$num})); 15932} 15933 15934sub Roman{ 15935 local($num)=@_; 15936 &fRoman(eval($enum{$num})); 15937} 15938sub fRoman{ 15939 local($num)=@_; 15940 local($RmI)= $num%10; ($RmI) = (($RmI) ? $RomanI{"$RmI"} : '' ); 15941 $num = $num/10; local($RmX)= $num%10; ($RmX) = (($RmX) ? $RomanX{"$RmX"} : '' ); 15942 $num = $num/10; local($RmC)= $num%10; ($RmC) = (($RmC) ? $RomanC{"$RmC"} : '' ); 15943 $num = $num/10; local($RmM)= $num%10; ($RmM) = (($RmM) ? $RomanM{"$RmM"} : '' ); 15944 "$RmM" . "$RmC" . "$RmX" . "$RmI"; 15945} 15946sub froman{ 15947 local($_)=@_; 15948 $_ = &fRoman($_); 15949 $_ =~ tr/A-Z/a-z/; 15950 $_; 15951} 15952sub roman{ 15953 local($num)=@_; 15954 &froman(eval($enum{$num})); 15955} 15956 15957 15958 %unitscale = ("in",72,"pt",72.27/72,"pc",12,"mm",72/25.4,"cm",72/2.54 15959 ,"\\hsize",100,"\\vsize",100 15960 ,"\\textwidth",100,"\\textheight",100 15961 ,"\\pagewidth",100,"\\linewidth",100 15962 ); 15963 %units = ("in","in","pt","pt","pc","pi","mm","mm","cm","cm" 15964 ,"\\hsize","%","\\vsize","%","\\textwidth","%","\\textheight","%"); 15965 15966sub convert_length { # clean 15967 my ($this,$scale) = @_; 15968 $scale = 1 unless $scale; 15969 my ($pxs,$len,$full); 15970 if ( $this =~ /([\d.]*)\s*(in|pt|pc|mm|cm|\\[hv]size|\\\w+(width|height))?/ ) { 15971 $len = ($1 ? $1 : 1); $full = $2; 15972 if ($full &&($full =~ /\\([hv]size|\w+(width|height))/)) { $scale = 1;}; 15973 $pxs = (($full) ? int($len * $unitscale{$full}*$scale + 0.5) 15974 : int($len*$scale + .5) ); 15975 if ( $full =~ /\\([hv]size|\w+(width|height))/) { $pxs .= '%';}; 15976 }; 15977 ($pxs,$len); 15978} 15979 15980 15981 15982 15983 # Inclusion in this list will cause a command or an environment to be ignored. 15984 # This is suitable for commands without arguments and for environments. 15985 # If however a do_env|cmd_<env|cmd> exists then it will be used. 15986 %ignore = ('sloppypar', 1, 'document', 1, 'newblock', 1, 15987 ',', 1, '@', 1, ' ', 1, '-', 1, 15988 'sloppy', 1, 15989 'hyphen', 1, 'titlepage', 1, 'htmlonly', 1, 15990 'flushleft', 1, 'flushright', 1, 'slide', 1, 15991 'tiny', 1, 'Tiny', 1, 'scriptsize', 1, 'footnotesize', 1, 15992 'small', 1, 'normalsize', 1, 'large', 1, 'Large', 1, 15993 'LARGE', 1, 'huge', 1, 'Huge', 1, 15994 %ignore); 15995 15996 # Specify commands with arguments that should be ignored. 15997 # Arbitrary code can be placed between the arguments 15998 # to be executed while processing the command. 15999 # 16000# Note that some commands MAY HAVE ARGUMENTS WHICH SHOULD BE LEFT AS TEXT 16001 # EVEN THOUGH THE COMMAND IS IGNORED (e.g. hbox, center, etc) 16002 16003&ignore_commands( <<_IGNORED_CMDS_); 16004NeedsTeXFormat # {} # [] 16005ProvidesClass # {} # [] 16006ProvidesFile # {} # [] 16007ProvidesPackage # {} # [] 16008abovedisplayskip # &ignore_numeric_argument 16009abovedisplayshortskip # &ignore_numeric_argument 16010addcontentsline # {} # {} # {} 16011addtocontents # {} # {} 16012addvspace # {} # &ignore_numeric_argument 16013and 16014and # \$_ = join(''," - ",\$_) 16015backmatter 16016baselineskip # &ignore_numeric_argument 16017belowdisplayskip # &ignore_numeric_argument 16018belowdisplayshortskip # &ignore_numeric_argument 16019bibdata 16020bibliographystyle # {} 16021bibstyle # {} 16022bigskipamount # &ignore_numeric_argument 16023smallskipamount # &ignore_numeric_argument 16024medskipamount # &ignore_numeric_argument 16025center 16026citation # {} 16027citeauthoryear 16028clearpage 16029cline # {} 16030#documentclass # [] # {} 16031#documentstyle # [] # {} 16032#end # {} 16033enlargethispage # {} 16034evensidemargin # &ignore_numeric_argument 16035filecontents 16036filbreak 16037fil 16038fill 16039flushbottom 16040fontsize # {} # {} 16041footheight # &ignore_numeric_argument 16042footskip # &ignore_numeric_argument 16043frontmatter 16044fussy 16045global 16046goodbreak 16047hbox 16048headheight # &ignore_numeric_argument 16049headsep # &ignore_numeric_argument 16050hfil 16051hfill 16052hfuzz # &ignore_numeric_argument 16053hline 16054hspace # {} # \$_ = join(''," ",\$_) 16055hspacestar # {} # \$_ = join(''," ",\$_) 16056html 16057ifcase 16058ignorespaces 16059indent 16060itemindent # &ignore_numeric_argument 16061itemsep # &ignore_numeric_argument 16062labelsep # &ignore_numeric_argument 16063labelwidth # &ignore_numeric_argument 16064leavevmode 16065leftmargin # &ignore_numeric_argument 16066listparindent # &ignore_numeric_argument 16067lower # &ignore_numeric_argument 16068long 16069mainmatter 16070makebox # [] # [] 16071makeindex 16072marginpar # {} 16073marginparsep # &ignore_numeric_argument 16074marginparwidth # &ignore_numeric_argument 16075markboth # {} # {} 16076markright # {} 16077mathord 16078mathbin 16079mathindent # &ignore_numeric_argument 16080mathrel 16081mathop 16082mathtt 16083#mdseries 16084newpage 16085#newedboolean # {} 16086#newedcommand # {} # [] # [] # {} 16087#newedcounter # {} # [] 16088#newedenvironment # {} # [] # [] # {} # {} 16089#newedtheorem # {} # [] # {} # [] 16090#providedcommand # {} # [] # [] # {} 16091#renewedcommand # {} # [] # [] # {} 16092#renewedenvironment # {} # [] # [] # {} # {} 16093nobreakspace # \$_ = join('',";SPMnbsp;",\$_) 16094nonbreakingspace # \$_ = join('',";SPMnbsp;",\$_) 16095noalign 16096nobreak 16097nocite # {} 16098noindent 16099nolinebreak# [] 16100nopagebreak #[] 16101normalmarginpar 16102numberline 16103oddsidemargin # &ignore_numeric_argument 16104omit 16105onecolumn 16106outer 16107pagenumbering #{} 16108pagestyle # {} 16109parindent # &ignore_numeric_argument 16110parsep # &ignore_numeric_argument 16111parskip # &ignore_numeric_argument 16112partopsep # &ignore_numeric_argument 16113penalty # &ignore_numeric_argument 16114phantom # {} 16115protect 16116raggedright 16117raggedbottom 16118raise # &ignore_numeric_argument 16119raisebox # {} # [] # [] 16120relax 16121reversemarginpar 16122rightmargin # &ignore_numeric_argument 16123#rmfamily 16124rule # [] # {} # {} 16125samepage 16126selectfont 16127startdocument # \$SEGMENT=1;\$SEGMENTED=1; \$_ 16128strut 16129suppressfloats # [] 16130textheight # &ignore_numeric_argument 16131textwidth # &ignore_numeric_argument 16132textnormal 16133#textrm 16134textup 16135theorempreskipamount # &ignore_numeric_argument 16136theorempostskipamount # &ignore_numeric_argument 16137thispagestyle # {} 16138topmargin # &ignore_numeric_argument 16139topsep # &ignore_numeric_argument 16140topskip # &ignore_numeric_argument 16141twocolumn 16142unskip 16143#upshape 16144vfil 16145vfill 16146vfilll 16147vline 16148_IGNORED_CMDS_ 16149 16150 # Commands which need to be passed, ALONG WITH THEIR ARGUMENTS, to TeX. 16151 # Note that this means that the arguments should *not* be translated, 16152 # This is handled by wrapping the commands in the dummy tex2html_wrap 16153 # environment before translation begins ... 16154 16155 # Also it can be used to specify environments which may be defined 16156 # using do_env_* but whose contents will be passed to LaTeX and 16157 # therefore should not be translated. 16158 # Note that this code squeezes spaces out of the args of psfig; 16159 16160 16161 # Images are cropped to the minimum bounding-box for these... 16162 16163&process_commands_in_tex (<<_RAW_ARG_CMDS_); 16164psfig # {} # \$args =~ s/ //g; 16165usebox # {} 16166framebox # [] # [] # {} 16167_RAW_ARG_CMDS_ 16168 16169 # ... but these are set in a box to measure height/depth 16170 # so that white space can be preserved in the images. 16171 16172&process_commands_inline_in_tex (<<_RAW_ARG_CMDS_); 16173#etalchar # {} \$args =~ s/(.*)/\$\^\{\$1\}\\\$/o; 16174fbox # {} 16175#frac # [] # {} # {} 16176dag 16177ddag 16178l 16179L 16180oe 16181OE 16182textexclamdown 16183textquestiondown 16184textregistered 16185textperiodcentered 16186#textcircled # {} 16187#raisebox # {} # [] # [] # {} 16188_RAW_ARG_CMDS_ 16189 16190 16191 16192# These are handled by wrapping the commands in the dummy tex2html_nowrap 16193# environment before translation begins. This environment will be 16194# stripped off later, when the commands are put into images.tex ... 16195 16196&process_commands_nowrap_in_tex (<<_RAW_ARG_NOWRAP_CMDS_); 16197#begingroup 16198#endgroup 16199#bgroup 16200#egroup 16201errorstopmode 16202nonstopmode 16203scrollmode 16204batchmode 16205psfigurepath # {} 16206pssilent 16207psdraft 16208psfull 16209thinlines 16210thicklines 16211linethickness # {} 16212hyphenation # {} 16213hyphenchar # \\ # &get_numeric_argument 16214hyphenpenalty # &get_numeric_argument 16215#let # \\ # <<\\(\\W|\\w+)>> 16216newedboolean # {} 16217newedcommand # {} # [] # [] # {} 16218newedcounter # {} # [] 16219newedenvironment # {} # [] # [] # {} # {} 16220newedtheorem # {} # [] # {} # [] 16221#providedcommand # {} # [] # [] # {} 16222#renewedcommand # {} # [] # [] # {} 16223#renewedenvironment # {} # [] # [] # {} # {} 16224DeclareMathAlphabet # {} # {} # {} # {} # {} 16225SetMathAlphabet # {} # {} # {} # {} # {} # {} 16226DeclareMathSizes # {} # {} # {} # {} 16227DeclareMathVersion # {} 16228DeclareSymbolFont # {} # {} # {} # {} # {} 16229DeclareSymbolFontAlphabet # {} # {} 16230DeclareMathSymbol # {} # {} # {} # {} 16231SetSymbolFont # {} # {} # {} # {} # {} # {} 16232DeclareFontShape # {} # {} # {} # {} # {} # {} 16233DeclareFontFamily # {} # {} # {} 16234DeclareFontEncoding # {} # {} # {} 16235DeclareFontSubstitution # {} # {} # {} # {} 16236mathversion # {} 16237#newfont # {} # {} 16238#normalfont 16239#rmfamily 16240#mdseries 16241newlength # {} 16242setlength # {} # {} 16243addtolength # {} # {} 16244settowidth # {}# {} 16245settoheight # {} # {} 16246settodepth # {} # {} 16247newsavebox # {} 16248savebox # {} # [] # {} 16249sbox # {} # {} 16250setbox # {} 16251TagsOnLeft # \$EQN_TAGS = \"L\" if \$PREAMBLE; 16252TagsOnRight # \$EQN_TAGS = \"R\" if \$PREAMBLE; 16253_RAW_ARG_NOWRAP_CMDS_ 16254 16255 16256&process_commands_wrap_deferred (<<_RAW_ARG_DEFERRED_CMDS_); 16257alph # {} 16258Alph # {} 16259arabic # {} 16260author # [] # {} 16261boldmath 16262unboldmath 16263captionstar # [] # {} 16264caption # [] # {} 16265#endsegment # [] 16266#segment # [] # {} # {} # {} 16267fnsymbol # {} 16268footnote # [] # {} 16269footnotemark # [] 16270footnotetext # [] # {} 16271#thanks # {} 16272roman # {} 16273Roman # {} 16274#mbox # {} 16275parbox # [] # [] # [] # {} # {} 16276#selectlanguage # [] # {} 16277setcounter # {} # {} 16278addtocounter # {} # {} 16279stepcounter # {} 16280refstepcounter # {} 16281value # {} 16282par 16283hrule # &ignore_numeric_argument 16284linebreak # [] 16285pagebreak # [] 16286newfont # {} # {} 16287smallskip 16288medskip 16289bigskip 16290centering 16291raggedright 16292raggedleft 16293itshape 16294#textit # {} 16295upshape 16296slshape 16297#scshape 16298rmfamily 16299sffamily 16300ttfamily 16301mdseries 16302bfseries 16303#textbf # {} 16304em 16305normalfont 16306it 16307rm 16308sl 16309bf 16310tt 16311sf 16312Tiny 16313tiny 16314scriptsize 16315footnotesize 16316small 16317Small 16318SMALL 16319normalsize 16320large 16321Large 16322LARGE 16323huge 16324Huge 16325lowercase # {} 16326uppercase # {} 16327MakeLowercase # {} 16328MakeUppercase # {} 16329htmlinfo # [] 16330htmlinfostar # [] 16331tableofchildlinks # [] 16332tableofchildlinksstar # [] 16333tableofcontents 16334listoffigures 16335listoftables 16336thepart 16337thepage 16338thechapter 16339thesection 16340thesubsection 16341thesubsubsection 16342theparagraph 16343thesubparagraph 16344theequation 16345htmltracenv # {} 16346HTMLsetenv # [] # {} # {} 16347#newedboolean # {} 16348#newedcounter # {} # [] 16349#newedcommand # {} # [] # [] # {} 16350#newedtheorem # {} # [] # {} # [] 16351#newedenvironment # {} # [] # [] # {} # {} 16352providedcommand # {} # [] # [] # {} 16353renewedcommand # {} # [] # [] # {} 16354renewedenvironment # {} # [] # [] # {} # {} 16355url # {} 16356htmlurl # {} 16357latextohtml 16358TeX 16359LaTeX 16360LaTeXe 16361LaTeXiii 16362Xy 16363MF 16364AmS 16365AmSTeX 16366textcircled # {} 16367_RAW_ARG_DEFERRED_CMDS_ 16368 16369 16370#rrm 16371# implement the XBit-Hack for Apache servers, to handle 16372# Server-Side Includes (SSIs) with .html filename extension 16373# 16374sub check_htaccess { 16375 my $access_file = '.htaccess'; 16376 my $has_access = ''; 16377 local $_; 16378 print "\nChecking for .htaccess file"; 16379 if (-f $access_file) { 16380 print STDOUT " ... found"; 16381 open(HTACCESS, "<$access_file"); 16382 while (<HTACCESS>) { 16383 if (/^\s*XBitHack\s*on\s*$/) { 16384 print STDOUT " with XBitHack on"; 16385 $has_access =1; last; 16386 }; 16387 } 16388 print STDOUT "\n"; 16389 close HTACCESS; 16390 return() if $has_access; 16391 open (HTACCESS, ">>$access_file"); 16392 &write_warnings("appended to .htaccess in $DESTDIR"); 16393 } else { 16394 open (HTACCESS, ">$access_file"); 16395 chmod 0644, $access_file; 16396 &write_warnings("created .htaccess file in $DESTDIR"); 16397 } 16398 print HTACCESS "\nXBitHack on\n"; 16399 close HTACCESS; 16400} 16401 16402# This maps the HTML mnemonic names for the ISO-LATIN-1 character references 16403# to their numeric values. When converting latex specials characters to 16404# ISO-LATIN-1 equivalents I use the numeric values because this makes any 16405# conversion back to latex (using revert_raw_tex) more reliable (in case 16406# the text contains "&mnemonic_name"). Errors may occur if an environment 16407# passed to latex (e.g. a table) contains the numeric values of character 16408# references. 16409 16410# RRM: removed this portion; load from latin1.pl instead 16411#&do_require_extension('latin1'); 16412 16413sub make_isolatin1_rx { 16414 local($list) = &escape_rx_chars(join($CD,(values %iso_8859_1_character_map_inv))); 16415 $list =~ s/$CD/|/g; 16416 $isolatin1_rx = "($list)"; 16417} 16418 16419 16420 ################### Frequently used regular expressions ################### 16421 # $1 : preamble 16422 16423 $preamble_rx = "(^[\\s\\S]*)(\\\\begin\\s*$O\\d+$C\\s*document\\s*$O\\d+$C|\\\\startdocument)"; 16424 16425 # \d (number) should sometimes also be a delimiter but this causes 16426 # problems with command names that are allowed to contain numbers (eg tex2html) 16427 # \d is a delimiter with commands which take numeric arguments? 16428 # JCL: I can't see that. \tex2html is also no valid LaTeX (or TeX). 16429 # It is parsed \tex 2html, and \tex may take 2html as argument, but this 16430 # is invalid LaTeX. \d must be treated as delimiter. 16431 16432# JCL(jcl-del) - Characters to be treated as letters, everything else 16433# is a delimiter. 16434 # internal LaTeX command separator, shouldn't be equal to $; 16435 $CD = "\001"; 16436 &make_cmd_spc_rx; # determines space to follow a letter command 16437#old $delimiters = '\'\\s[\\]\\\\<>(=).,#;:~\/!-'; 16438 $letters = 'a-zA-Z'; 16439 $delimiter_rx = "([^$letters])"; 16440# 16441 16442 # liberalized environment names (white space, optional arg, interpunctuation signs etc.) 16443 # $1 : br_id, $2 : <environment> 16444 $begin_env_rx="(\\\\protect)?\\\\begin\\s*(\\[([^\\]]*)])?$O(\\d+)$C\\s*([^'[\\]\\\\#~]+)\\s*$O\\4$C"; 16445 $begin_env_pr_rx="(\\\\protect)?\\\\begin\\s*(\\[([^\\]]*)])?$OP(\\d+)$CP\\s*([^'[\\]\\\\#~]+)\\s*$OP\\4$CP"; 16446 16447 $mbox_rx = "\\\\mbox\\s*"; 16448 16449 $match_br_rx = "\\s*$O\\d+$C\\s*"; 16450 16451 $opt_arg_rx = "\\s*\\[([^\\]]*)\\]\\s*"; # Cannot handle nested []s! 16452 $optional_arg_rx = "^\\s*\\[([^]]*)\\]"; # Cannot handle nested []s! 16453 16454 $block_close_rx = "^<\\/(DIV|P|BLOCKQUOTE)>\$"; 16455 $all_close_rx = "^<\\/(BODY|PRE|OL|UL|DL|FORM|ADDRESS)>\$"; 16456 16457 # Matches a pair of matching brackets 16458 # $1 : br_id 16459 # $2 : contents 16460 $next_pair_rx = "^[\\s%]*$O(\\d+)$C([\\s\\S]*)$O\\1$C($comment_mark\\d*\\n?)?"; 16461 16462 # will comments be a problem after these ??? 16463 $any_next_pair_rx = "$O(\\d+)$C([\\s\\S]*)$O\\1$C"; 16464 $any_next_pair_rx4 = "$O(\\d+)$C([\\s\\S]*)$O\\4$C"; 16465 $any_next_pair_pr_rx4 = "$OP(\\d+)$CP([\\s\\S]*)$OP\\4$CP"; 16466 $any_next_pair_rx5 = "$O(\\d+)$C([\\s\\S]*)$O\\5$C"; 16467 $any_next_pair_rx6 = "$O(\\d+)$C([\\s\\S]*)$O\\6$C"; 16468 16469 # used for labels in {enumerate} environments 16470 $standard_label_rx = 16471 "\\s*[[]\\s*((($any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]"; 16472 $enum_label_rx = "^((({[^{}]*})|([^{}]))*)([aAiI1])(.*)"; 16473 $enum_level = 0; # level for enumerate (1-4, i-iv) 16474 16475 16476 # Matches the \ensuremath command 16477 $enspair = "\\\\ensuremath\\s*" . $any_next_pair_rx; 16478# $enspair = "\\\\ensuremath\\s*$O(\\d+)$C([\\s\\S]*[\\\\\$&]+[\\s\\S]*)$O\\1$C"; 16479 16480 # Matches math comments, from math.pl 16481 $math_verbatim_rx = "$verbatim_mark#math(\\d+)#"; 16482 $mathend_verbatim_rx = "$verbatim_mark#mathend([^#]*)#"; 16483 16484 # Matches math array environments 16485 $array_env_rx = "array|cases|\\w*matrix"; 16486 16487 # initially empty; has a value in HTML 3.2 and 4.0 16488 $math_class = '' unless ($math_class); 16489 $eqno_class = '' unless ($eqno_class); 16490 16491 # Matches to end-of-line and subsequent spaces 16492 $EOL = "[ \\t]*\\n?"; 16493 16494 # Matches wrapped \par command 16495 $par_rx = "\\n?\\\\begin(($O|$OP)\\d+($C|$CP))tex2html_deferred\\1\\\\par\\s\*" 16496 . "\\\\end(($O|$OP)\\d+($C|$CP))tex2html_deferred\\4\\n?"; 16497 16498 # $1 : br_id 16499 $begin_cmd_rx = "$O(\\d+)$C"; 16500 16501 # $1 : image filename prefix 16502 $img_rx = "(\\w*T?img\\d+)"; 16503 16504 # $1 : largest argument number 16505 $tex_def_arg_rx = "^[#0-9]*#([0-9])($O|$OP)"; 16506 16507 # only some non-alphanumerics are allowed in labels, Why? 16508 $label_rx = "[^\\w\.\\\-\\\+\\\:]"; 16509 16510#JCL(jcl-del) - new face, see also &do_cmd_makeatletter et.al. 16511# $cmd_delims = q|-#,.~/\'`^"=\$%&_{}@|; # Commands which are also delimiters! 16512# $single_cmd_atletter_rx = "\\\\([a-zA-Z\\\@]+\\*?|[$cmd_delims]|\\\\)"; 16513# $single_cmd_atother_rx = "\\\\([a-zA-Z]+\\*?|[$cmd_delims]|\\\\)"; 16514 # $1 : declaration or command or newline (\\) 16515 &make_single_cmd_rx; 16516# 16517 16518 # $1 : description in a list environment 16519 $item_description_rx = 16520# "\\\\item\\s*[[]\\s*((($any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]"; 16521 "\\\\item\\s*[[]\\s*((($any_next_pair_pr_rx4)|([[][^]]*[]])|[^]])*)[]]"; 16522 16523 $fontchange_rx = 'rm|em|it|sl|sf|tt|sc|upshape|normalfont'; 16524 $fontweight_rx = 'bf|mdseries|normalfont'; 16525 $colorchange_rx = "(text)?color\\s*(\#\\w{6})?"; 16526 $sizechange_rx = 'tiny|Tiny|scriptsize|footnotesize|small|Small|SMALL' . 16527 '|normalsize|large|Large|LARGE|huge|Huge'; 16528 16529# $image_switch_rx = "makeimage"; 16530 $image_switch_rx = "makeimage|scshape|sc"; 16531 $env_switch_rx = "writetolatex"; 16532 $raw_arg_cmds{'font'} = 1; 16533 16534 # Matches the \caption command 16535 # $1 : br_id 16536 # $2 : contents 16537 $caption_suffixes = "lof|lot"; 16538# $caption_rx = "\\\\caption\\s*([[]\\s*((($any_next_pair_rx5)|([[][^]]*[]])|[^]])*)[]])?$O(\\d+)$C([\\s\\S]*)$O\\8$C$EOL"; 16539 16540 $caption_rx = "\\\\(top|bottom|table)?caption\\s*\\\*?\\s*([[]\\s*((($any_next_pair_rx6)|([[][^]]*[]])|[^]])*)[]])?$O(\\d+)$C([\\s\\S]*)$O\\9$C$EOL"; 16541 $caption_width_rx = "\\\\setlength\\s*(($O|$OP)\\d+($C|$CP))\\\\captionwidth\\1\\s*(($O|$OP)\\d+($C|$CP))([^>]*)\\4"; 16542 16543 # Matches the \htmlimage command 16544 # $1 : br_id 16545 # $2 : contents 16546 $htmlimage_rx = "\\\\htmlimage\\s*$O(\\d+)$C([\\s\\S]*)$O\\1$C$EOL"; 16547 $htmlimage_pr_rx = "\\\\htmlimage\\s*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP$EOL"; 16548 16549 # Matches the \htmlborder command 16550 # $1 : optional argument... 16551 # $2 : ...contents i.e. extra attributes 16552 # $3 : br_id 16553 # $4 : contents i.e. width 16554 $htmlborder_rx = "\\\\htmlborder\\s*(\\[([^]]*)\\])?\\s*$O(\\d+)$C(\\d*)$O\\3$C$EOL"; 16555 $htmlborder_pr_rx = "\\\\htmlborder\\s*(\\[([^]]*)\\])?\\s*$OP(\\d+)$CP(\\d*)$OP\\3$CP$EOL"; 16556 16557 # Matches a pair of matching brackets 16558 # USING PROCESSED DELIMITERS; 16559 # (the delimiters are processed during command translation) 16560 # $1 : br_id 16561 # $2 : contents 16562# $next_pair_pr_rx = "^[\\s%]*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP"; 16563 $next_pair_pr_rx = "^[\\s%]*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP($comment_mark\\d*\\n?)?"; 16564 $any_next_pair_pr_rx = "$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP($comment_mark\\d*\\n?)?"; 16565 $next_token_rx = "^[\\s%]*(\\\\[A-Za-z]+|\\\\[^a-zA-Z]|.)"; 16566 16567 $HTTP_start = 'http:'; 16568 16569 # This will be used to recognise escaped special characters as such 16570 # and not as commands 16571 $latex_specials_rx = '[\$]|&|%|#|{|}|_'; 16572 $html_escape_chars = '<>&'; 16573 16574 # This is used in sub revert_to_raw_tex before handing text to be processed 16575 # by latex. 16576 $html_specials_inv_rx = join("|", keys %html_specials_inv); 16577 16578 # These are used for direct replacements in/from ALT=... strings 16579 %html_special_entities = ('<','lt','>','gt','"','quot','&','amp'); 16580 %html_spec_entities_inv = ('lt','<','gt','>','quot','"','amp','&'); 16581 16582 # This is also used in sub revert_to_raw_tex 16583 $character_entity_rx = '(&#(\d+);)'; 16584 $named_entity_rx = '&(\w+);'; 16585 16586 #commands for altering theorem-styles 16587 $theorem_cmd_rx = 'theorem(style|(header|body)font)'; 16588 16589 16590 # Matches a \begin or \end {tex2html_wrap}. Also used by revert_to_raw_tex 16591 $tex2html_wrap_rx = '\\\\(begin|end)\\s*\{\\s*(tex2html_(wrap|nowrap|deferred|nomath|preform|\\w*_inline)[_a-z]*|makeimage)\\s*\}'."($EOL)"; 16592 $tex2html_deferred_rx = '\\\\(begin|end)(<<\\d+>>)tex2html_deferred\\2'; 16593 $tex2html_deferred_rx2 = '\\\\(begin|end)(<<\\d+>>)tex2html_deferred\\4'; 16594 $tex2html_envs_rx = "\\\\(begin|end)\\s*(($O|$OP)\\d+($C|$CP))\\s*(tex2html_(wrap|nowrap|deferred|nomath|preform|\w+_inline)[_a-z]*||makeimage)\\s*\\2"; 16595 16596 # The first empty parenthese pair is for non-letter commands. 16597 # $2: meta command, $4: delimiter (may be empty) ignore the *-version distinction 16598# $meta_cmd_rx = "()\\\\(providecommand|renewcommand|renewenvironment|newcommand|newenvironment|newtheorem|newcounter|newboolean|newif|let)(([^$letters$cmd_spc])|$cmd_spcs_rx)"; 16599 $meta_cmd_rx = "()\\\\(providecommand|renewcommand|renewenvironment|newcommand|newenvironment|newtheorem|newcounter|newboolean|newif|DeclareRobustCommand|DeclareMathOperator\\*?)\\\*?(([^$letters$cmd_spc])|$cmd_spcs_rx)"; 16600 16601 &make_counters_rx; 16602 16603 # Matches a label command and its argument 16604 $labels_rx = "\\\\label\\s*$O(\\d+)$C([\\s\\S]*)$O\\1$C$EOL"; 16605 $labels_rx8 = "\\\\label\\s*$O(\\d+)$C([\\s\\S]*)$O\\8$C$EOL"; 16606 16607 # Matches environments that should not be touched during the translation 16608# $verbatim_env_rx = "\\s*{(verbatim|rawhtml|LVerbatim)[*]?}"; 16609 $verbatim_env_rx = "\\s*(\\w*[Vv]erbatim|rawhtml|imagesonly|tex2html_code)[*]?"; 16610 $image_env_rx = "\\s*(picture|xy|diagram)[*]?"; 16611 $keepcomments_rx = "\\s*(picture|makeimage|xy|diagram)[*]?"; 16612 16613 # names of different math environment types 16614 $display_env_rx = "displaymath|makeimage|eqnarray|equation"; 16615 $inline_env_rx = "inline|indisplay|entity|xy|diagram"; 16616 $sub_array_env_rx = "array|(small|\\w)\?matrix|tabular|cases"; 16617 16618 # Matches environments needing pre-processing for images 16619 $pre_processor_env_rx = "\\\\(begin|end)\\s*(($O|$OP|\{)\\d+($C|$CP|\}))pre_(\\w+)\\2"; 16620 16621 # Matches icon markers 16622 $icon_mark_rx = "<tex2html_(" . join("|", keys %icons) . ")>"; 16623 16624 $start_time = time; 16625 print STDOUT join(" ", "Starting at", $start_time, "seconds\n") 16626 if ($TIMING||$DEBUG||($VERBOSITY>2)); 16627 16628} # end of &initialise 16629 16630# Frequently used regular expressions with arguments 16631sub make_end_env_rx { 16632 local($env) = @_; 16633 $env = &escape_rx_chars($env); 16634 "\\\\end\\s*$O(\\d+)$C\\s*$env\\s*$O\\1$C".$EOL; 16635} 16636 16637sub make_begin_end_env_rx { 16638 local($env) = @_; 16639 $env = &escape_rx_chars($env); 16640 "\\\\(begin|end)\\s*$O(\\d+)$C\\s*$env\\s*$O\\3$C(\\s*\$)?"; 16641} 16642 16643sub make_end_cmd_rx { 16644 local($br_id) = @_; 16645 "$O$br_id$C"; 16646} 16647 16648#JCL(jcl-del) - see also &tokenize. 16649# Arrange commands into a regexp for tokenisation. 16650# Any letter command will gobble spaces, but avoids to match 16651# on ensuing letters (\foo won't match on \foox). 16652# Any non-letter command retains spaces and matches always 16653# by itself (\| matches \|... regardless of ...). 16654# 16655# This all is a huge kludge. The commands names should stay fix, 16656# regardless of changing catcodes. If we have \makeatletter, 16657# and LaTeX2HTML marks \@foo, then \@foo will be expanded 16658# properly before \makeatother, but does weird things on \@foo 16659# after \makeatother (\@foo in LaTeX is then \@ and foo, which 16660# isn't recognized as such). 16661# The reason is that the text to match the command \@foo 16662# in LaTeX mustn't be \@foo at all, because any text in LaTeX 16663# is also attributed with the category codes. 16664# 16665# But at least we have proper parsing of letter and non-letter 16666# commands as long as catcoding won't upset LaTeX2HTML too much. 16667# 16668sub make_new_cmd_rx { 16669 return("") if $#_ < 0; # empty regexp if list is empty! 16670 16671 # We have a subtle treatment of ambivalent commands like 16672 # \@foo in situations depicted above! 16673 # Get every command that contains no letters ... 16674 local($nonlettercmds) = 16675 &escape_rx_chars(join($CD, grep(!/[$letters]/,@_))); 16676 # and every command that contains a letter 16677 local($lettercmds) = 16678 &escape_rx_chars(join($CD, grep(/[$letters]/,@_))); 16679 16680 if (%renew_command) { 16681 local($renew); 16682 foreach $renew (keys %renew_command) { 16683 $lettercmds =~ s/(^|$CD)$renew//; } 16684 $lettercmds =~ s/^$CD$//; 16685 } 16686 16687 # replace the temporary $CD delimiter (this enables eg. \| command) 16688 $nonlettercmds =~ s/$CD/|/g; 16689 $lettercmds =~ s/$CD/|/g; 16690 16691 # In case we have no non-letter commands, insert empty parentheses 16692 # to align match strings. 16693 # 16694 $nonlettercmds =~ s/^\||\|$//g; 16695 $lettercmds =~ s/^\||\|$//g; 16696 local($rx) = (length($nonlettercmds) ? "\\\\($nonlettercmds)" : ""); 16697 if (length($lettercmds)) { 16698 $rx .= ( length($rx) ? "|" : "()" ); 16699 $rx .= "\\\\($lettercmds)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)"; 16700 } 16701 # $1: non-letter cmd, $2: letter cmd, $4: delimiter 16702 # Eg. \\(\@|...|\+)|\\(abc|...|xyz)(([^a-zA-Z \t])|[ \t]+) 16703 # $1 and $2 are guaranteed to alternate, $4 may be empty. 16704 $rx; 16705} 16706 16707# Build a simple regexp to use after tokenisation for 16708# faster translation. 16709sub make_new_cmd_no_delim_rx { 16710 return("") if $#_ < 0; # empty regexp if list is empty! 16711 # Get every command that contains no letters ... 16712 local($_) = &escape_rx_chars(join($CD, @_)); 16713 s/$CD/|/g; 16714 16715 join('',"\\\\(",$_,")"); 16716} 16717 16718 16719#JCL(jcl-del) - new face: w/o arg (was 'begin' only), escapes env names 16720sub make_new_env_rx { 16721 local($envs) = &escape_rx_chars(join($CD, keys %new_environment)); 16722 $envs =~ s/$CD/|/g; 16723 length($envs) ? "\\\\begin\\s*$O(\\d+)$C\\s*($envs)\\s*$O\\1$C\\s*" : ""; 16724} 16725 16726sub make_new_end_env_rx { 16727 local($envs) = &escape_rx_chars(join($CD, keys %new_environment)); 16728 $envs =~ s/$CD/|/g; 16729 length($envs) ? "\\\\end\\s*$O(\\d+)$C\\s*($envs)\\s*$O\\1$C\\s*" : ""; 16730} 16731 16732#JCL(jcl-del) - $delimiter_rx -> ^$letters 16733# don't care for $cmd_spc_rx; space after sectioning commands 16734# is unlikely and I don't want to try too much new things 16735# 16736sub make_sections_rx { 16737 local($section_alts) = &get_current_sections; 16738 # $section_alts includes the *-forms of sectioning commands 16739 $sections_rx = "()\\\\($section_alts)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)"; 16740# $sections_rx = "()\\\\($section_alts)([^$letters])"; 16741} 16742 16743sub make_order_sensitive_rx { 16744 local(@theorem_alts, $theorem_alts); 16745 @theorem_alts = ($preamble =~ /\\newtheorem\s*{([^\s}]+)}/og); 16746 $theorem_alts = join('|',@theorem_alts); 16747# 16748# HWS: Added kludge to require counters to be more than 2 characters long 16749# in order to be flagged as order-sensitive. This will permit equations 16750# with \theta to remain order-insensitive. Also permit \alpha and 16751# the eqnarray* environment to remain order-insensitive. 16752# 16753 $order_sensitive_rx = 16754# "(equation|eqnarray[^*]|\\\\caption|\\\\ref|\\\\the[a-z]{2,2}[a-z]|\\\\stepcounter" . 16755 "(\\\\caption|\\\\ref|\\\\the[a-z]{2,2}[a-z]|\\\\stepcounter" . 16756 "|\\\\arabic|\\\\roman|\\\\Roman|\\\\alph[^a]|\\\\Alph|\\\\fnsymbol)"; 16757 $order_sensitive_rx =~ s/\)/|$theorem_alts)/ if $theorem_alts; 16758} 16759 16760sub make_language_rx { 16761 local($language_alts) = join("|", keys %language_translations); 16762# $setlanguage_rx = "\\\\se(lec)?tlanguage\\s*{\\\\?($language_alts)}"; 16763 $setlanguage_rx = "\\\\setlanguage\\s*{\\\\?($language_alts)}"; 16764 $language_rx = "\\\\($language_alts)TeX"; 16765 $case_change_rx = "(\\\\(expandafter|noexpand)\s*)?\\\\((Make)?([Uu]pp|[Ll]ow)ercase)\s*"; 16766} 16767 16768sub addto_languages { 16769 local($lang) = @_; 16770 local($trans) = "main'".$lang.'_translation'; 16771 if (defined &$trans) { 16772 $language_translations {$lang} = $lang.'_translation'; 16773 } 16774} 16775 16776# JCL(jcl-del) - new rexexp type 16777sub make_raw_arg_cmd_rx { 16778 # $1 or $2 : commands to be processed in latex (with arguments untouched) 16779 # $4 : delimiter 16780 $raw_arg_cmd_rx = &make_new_cmd_rx(keys %raw_arg_cmds); 16781 $raw_arg_cmd_rx; 16782} 16783 16784# There are probably more. 16785# Interferences not checked out yet, thus in makeat... only. 16786sub make_letter_sensitive_rx { 16787 $delimiter_rx = "([^$letters])"; 16788 &make_sections_rx; 16789 &make_single_cmd_rx; 16790 &make_counters_rx; 16791} 16792 16793#JCL(jcl-del) - this could eat one optional newline, too. 16794# But this might result in large lines... anyway, it *should* be 16795# handled. A possible solution would be to convert adjacent newlines 16796# into \par's in preprocessing. 16797sub make_cmd_spc_rx { 16798 $cmd_spc = " \\t"; 16799 $cmd_spc_rx = "[ \\t]*"; # zero or more 16800 $cmd_spcs_rx = "[ \\t]+"; # one or more 16801} 16802 16803sub make_single_cmd_rx { 16804 $single_cmd_rx = "\\\\([^$letters])|\\\\([$letters]+\\*?)(([^$letters$cmd_spc])|$cmd_spcs_rx|\n|\$)"; 16805} 16806 16807sub make_counters_rx { 16808 # Matches counter commands - these are caught early and are appended to the 16809 # file that is passed to latex. 16810#JCL(jcl-del) - $delimiter_rx -> ^$letters 16811 $counters_rx = "()\\\\(newcounter|addtocounter|setcounter|refstepcounter|stepcounter|arabic|roman|Roman|alph|Alph|fnsymbol)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)"; 16812} 16813 16814 16815# Creates an anchor for its argument and saves the information in 16816# the array %index; 16817# In the index the word will use the beginning of the title of 16818# the current section (instead of the usual pagenumber). 16819# The argument to the \index command is IGNORED (as in latex) 16820sub make_index_entry { &make_real_index_entry(@_) } 16821sub make_real_index_entry { 16822 local($br_id,$str) = @_; 16823 local($this_file) = $CURRENT_FILE; 16824 $TITLE = $saved_title if (($saved_title)&&(!($TITLE)||($TITLE eq $default_title))); 16825 # Save the reference 16826 $str = "$str###" . ++$global{'max_id'}; # Make unique 16827 $index{$str} .= &make_half_href($this_file."#$br_id"); 16828 "<A NAME=\"$br_id\">$anchor_invisible_mark<\/A>"; 16829} 16830 16831sub image_message { # clean 16832 print <<"EOF"; 16833 16834To resolve the image conversion problems please consult 16835the "Troubleshooting" section of your local User Manual 16836or read it online at 16837 http://www-texdev.ics.mq.edu.au/l2h/docs/manual/ 16838 16839EOF 16840} 16841 16842sub image_cache_message { # clean 16843 print <<"EOF"; 16844 16845If you are having problems displaying the correct images with Mosaic, 16846try selecting "Flush Image Cache" from "Options" in the menu-bar 16847and then reload the HTML file. 16848EOF 16849} 16850 16851__DATA__ 16852 16853# start of POD documentation 16854 16855=head1 NAME 16856 16857latex2html - Translate LaTeX files to HTML (HyperText Markup Language) 16858 16859=head1 SYNOPSIS 16860 16861B<latex2html> S<[ B<-help> | B<-h> ]> S<[ B<-version> | B<-V> ]> 16862 16863B<latex2html> S<[ B<-split> I<num> ]> 16864S<[ B<-link> I<num> ]> 16865S<[ B<-toc_depth> I<num> ]> 16866S<[ B<->(B<no>)B<toc_stars> ]> 16867S<[ B<->(B<no>)B<short_extn> ]> 16868S<[ B<-iso_language> I<lang> ]> 16869S<[ B<->(B<no>)B<validate> ]> 16870S<[ B<->(B<no>)B<latex> ]> 16871S<[ B<->(B<no>)B<djgpp> ]> 16872S<[ B<->(B<no>)B<fork> ]> 16873S<[ B<->(B<no>)B<external_images> ]> 16874S<[ B<->(B<no>)B<ascii_mode> ]> 16875S<[ B<->(B<no>)B<lcase_tags> ]> 16876S<[ B<->(B<no>)B<ps_images> ]> 16877S<[ B<-font_size> I<size> ]> 16878S<[ B<->(B<no>)B<tex_defs> ]> 16879S<[ B<->(B<no>)B<navigation> ]> 16880S<[ B<->(B<no>)B<top_navigation> ]> 16881S<[ B<->(B<no>)B<buttom_navigation> ]> 16882S<[ B<->(B<no>)B<auto_navigation> ]> 16883S<[ B<->(B<no>)B<index_in_navigation> ]> 16884S<[ B<->(B<no>)B<contents_in_navigation> ]> 16885S<[ B<->(B<no>)B<next_page_in_navigation> ]> 16886S<[ B<->(B<no>)B<previous_page_in_navigation> ]> 16887S<[ B<->(B<no>)B<footnode> ]> 16888S<[ B<->(B<no>)B<numbered_footnotes> ]> 16889S<[ B<-prefix> I<output_filename_prefix> ]> 16890S<[ B<->(B<no>)B<auto_prefix> ]> 16891S<[ B<-long_titles> I<num> ]> 16892S<[ B<->(B<no>)B<custom_titles> ]> 16893S<[ B<-title>|B<-t> I<top_page_title> ]> 16894S<[ B<->(B<no>)B<rooted> ]> 16895S<[ B<-rootdir> I<output_directory> ]> 16896S<[ B<-dir> I<output_directory> ]> 16897S<[ B<-mkdir> ]> 16898S<[ B<-address> I<author_address> | B<-noaddress> ]> 16899S<[ B<->(B<no>)B<subdir> ]> 16900S<[ B<-info> I<0> | I<1> | I<string> ]> 16901S<[ B<->(B<no>)B<auto_link> ]> 16902S<[ B<-reuse> I<num> | B<-noreuse> ]> 16903S<[ B<->(B<no>)B<antialias_text> ]> 16904S<[ B<->(B<no>)B<antialias> ]> 16905S<[ B<->(B<no>)B<transparent> ]> 16906S<[ B<->(B<no>)B<white> ]> 16907S<[ B<->(B<no>)B<discard> ]> 16908S<[ B<-image_type> I<type> ]> 16909S<[ B<->(B<no>)B<images> ]> 16910S<[ B<-accent_images> I<type> | B<-noaccent_images> ]> 16911S<[ B<-style> I<style> ]> 16912S<[ B<->(B<no>)B<parbox_images> ]> 16913S<[ B<->(B<no>)B<math> ]> 16914S<[ B<->(B<no>)B<math_parsing> ]> 16915S<[ B<->(B<no>)B<latin> ]> 16916S<[ B<->(B<no>)B<entities> ]> 16917S<[ B<->(B<no>)B<local_icons> ]> 16918S<[ B<->(B<no>)B<scalable_fonts> ]> 16919S<[ B<->(B<no>)B<images_only> ]> 16920S<[ B<->(B<no>)B<show_section_numbers> ]> 16921S<[ B<->(B<no>)B<show_init> ]> 16922S<[ B<-init_file> I<Perl_file> ]> 16923S<[ B<-up_url> I<up_URL> ]> 16924S<[ B<-up_title> I<up_title> ]> 16925S<[ B<-down_url> I<down_URL> ]> 16926S<[ B<-down_title> I<down_title> ]> 16927S<[ B<-prev_url> I<prev_URL> ]> 16928S<[ B<-prev_title> I<prev_title> ]> 16929S<[ B<-index> I<index_URL> ]> 16930S<[ B<-biblio> I<biblio_URL> ]> 16931S<[ B<-contents> I<toc_URL> ]> 16932S<[ B<-external_file> I<external_aux_file> ]> 16933S<[ B<->(B<no>)B<short_index> ]> 16934S<[ B<->(B<no>)B<unsegment> ]> 16935S<[ B<->(B<no>)B<debug> ]> 16936S<[ B<-tmp> I<path> ]> 16937S<[ B<->(B<no>)B<ldump> ]> 16938S<[ B<->(B<no>)B<timing> ]> 16939S<[ B<-verbosity> I<num> ]> 16940S<[ B<-html_version> I<num> ]> 16941S<[ B<->(B<no>)B<strict> ]> 16942I<file.tex> S<[ I<file2.tex> ... ]> 16943 16944=head1 DESCRIPTION 16945 16946I<LaTeX2HTML> is a Perl program that translates LaTeX source files into 16947HTML. For each source file given as an argument the translator will create 16948a directory containing the corresponding HTML files. 16949 16950=head1 OPTIONS 16951 16952Many options can be specified in a true/false manner. This is indicated by 16953I<(no)>, e.g. to enable passing unknown environments to LaTeX, say "-latex", 16954to disable the feature say "-nolatex" or "-no_latex" (portability mode). 16955 16956=over 4 16957 16958=item B<-help> | B<-h> 16959 16960Print this online manual and exit. 16961 16962=item B<-version> | B<-V> 16963 16964Print the LaTeX2HTML release and version information and exit. 16965 16966=item B<-split> I<num> 16967 16968Stop making separate files at this depth (say "-split 0" for one huge HTML 16969file). 16970 16971=item B<-link> I<num> 16972 16973Stop showing child nodes at this depth. 16974 16975=item B<-toc_depth> I<num> 16976 16977MISSING_DESCRIPTION 16978 16979=item B<->(B<no>)B<toc_stars> 16980 16981MISSING_DESCRIPTION 16982 16983=item B<->(B<no>)B<short_extn> 16984 16985If this is set all HTML file will have extension C<.htm> instead of 16986C<.html>. This is helpful when shipping the document to PC systems. 16987 16988=item B<-iso_language> I<lang> 16989 16990MISSING_DESCRIPTION 16991 16992=item B<->(B<no>)B<validate> 16993 16994When this is set true, the HTML validator specified in F<l2hconf.pm> 16995will run. 16996 16997=item B<->(B<no>)B<latex> 16998 16999Pass unknown environments to LaTeX. This is the default. 17000 17001=item B<->(B<no>)B<djgpp> 17002 17003Specify this switch if you are running DJGPP on DOS and need to avoid 17004running out of filehandles. 17005 17006=item B<->(B<no>)B<fork> 17007 17008Enable/disable forking. The default is reasonable for this platform. 17009 17010=item B<->(B<no>)B<external_images> 17011 17012If set, leave the images outside the document. 17013 17014=item B<->(B<no>)B<ascii_mode> 17015 17016This is different from B<-noimages>. 17017If this is set, B<LaTeX2HTML> will show textual tags rather than 17018images, both in navigation panel and text (Eg. C<[Up]> instead the up 17019icon). 17020You could use this feature to create simple text from your 17021document, eg. with 'Save as... Text' from B<Netscape> or with 17022B<lynx -dump>. 17023 17024=item B<->(B<no>)B<lcase_tags> 17025 17026writes out HTML tag names using lowercase letters, rather than uppercase. 17027 17028=item B<->(B<no>)B<ps_images> 17029 17030If set, use links to external postscript images rather than inlined bitmaps. 17031 17032=item B<-font_size> I<size> 17033 17034To set the point size of LaTeX-generated GIF files, specify the desired 17035value (i.e., C<10pt>, C<11pt>, C<12pt>, etc.). 17036The default is to use the point size of the original LaTeX document. 17037This value will be magnified by I<$FIGURE_SCALE_FACTOR> and 17038I<$MATH_SCALE_FACTOR> defined in F<l2hconf.pm>. 17039 17040=item B<->(B<no>)B<tex_defs> 17041 17042Enable interpretation of raw TeX commands (default). 17043Note: There are many variations of C<\def> that B<LaTeX2HTML> cannot process 17044correctly! 17045 17046=item B<->(B<no>)B<navigation> 17047 17048Put a navigation panel at the top of each page (default). 17049 17050=item B<->(B<no>)B<top_navigation> 17051 17052Enables navigation links at the top of each page (default). 17053 17054=item B<->(B<no>)B<buttom_navigation> 17055 17056Enables navigation links at the buttom of each page. 17057 17058=item B<->(B<no>)B<auto_navigation> 17059 17060Put navigation links at the top of each page. If the page exceeds 17061I<$WORDS_IN_PAGE> number of words then put one at the bottom of the page. 17062 17063=item B<->(B<no>)B<index_in_navigation> 17064 17065Put a link to the index page in the navigation panel. 17066 17067=item B<->(B<no>)B<contents_in_navigation> 17068 17069Put a link to the table of contents in the navigation panel. 17070 17071=item B<->(B<no>)B<next_page_in_navigation> 17072 17073Put a link to the next logical page in the navigation panel. 17074 17075=item B<->(B<no>)B<previous_page_in_navigation> 17076 17077Put a link to the previous logical page in the navigation panel. 17078 17079=item B<->(B<no>)B<footnode> 17080 17081Puts all footnotes onto a separate HTML page, called F<footnode.html>, 17082rather than at the bottom of the page where they are referenced. 17083 17084=item B<->(B<no>)B<numbered_footnotes> 17085 17086If true, you will get every footnote applied with a subsequent number, else 17087with a generic hyperlink icon. 17088 17089=item B<-prefix> I<output_filename_prefix> 17090 17091Set the output file prefix, prepended to all C<.html>, C<.gif> and C<.pl> 17092files. See also B<-auto_prefix>. 17093 17094=item B<->(B<no>)B<auto_prefix> 17095 17096Set this to automatically insert the equivalent of B<-prefix >C<basename->", 17097where "basename" is the base name of the file being translated. 17098 17099=item B<-long_titles> I<num> 17100 17101MISSING_DESCRIPTION 17102 17103=item B<->(B<no>)B<custom_titles> 17104 17105MISSING_DESCRIPTION 17106 17107=item B<-title>|B<-t> I<top_page_title> 17108 17109The title (displayed in the browser's title bar) the document shall get. 17110 17111=item B<->(B<no>)B<rooted> 17112 17113MISSING_DESCRIPTION 17114 17115=item B<-rootdir> I<output_directory> 17116 17117MISSING_DESCRIPTION 17118 17119=item B<-dir> I<output_directory> 17120 17121Put the result in this directory instead of parallel to the LaTeX file, 17122provided the directory exists, or B<-mkdir> is specified. 17123 17124=item B<-mkdir> 17125 17126Allow directory specified with B<-dir> to be created if necessary. 17127 17128=item B<-address> I<author_address> | B<-noaddress> 17129 17130Supply your own string if you don't like the default 17131"E<lt>NameE<gt> E<lt>DateE<gt>". B<-noaddress> suppresses the 17132generation of an address footer. 17133 17134=item B<->(B<no>)B<subdir> 17135 17136If set (default), B<LaTeX2HTML> creates (or reuses) another file directory. 17137When false, the generated HTML files will be placed in the current 17138directory. 17139 17140=item B<-info> I<0> | I<1> | I<string> 17141 17142=item B<-noinfo> 17143 17144If 0 is specified (or B<-noinfo> is used), do not generate an I<"About this 17145document..."> section. If 1 is specified (default), the standard info page is 17146generated. If a custom string is given, it is used as the info page. 17147 17148=item B<->(B<no>)B<auto_link> 17149 17150MISSING_DESCRIPTION 17151 17152=item B<-reuse> I<num> | B<-noreuse> 17153 17154If false, do not reuse or recycle identical images generated in previous 17155runs. If the html subdirectory already exists, start the interactive session. 17156If I<num> is nonzero, do recycle them and switch off the interactive session. 17157If 1, only recycle images generated from previous runs. 17158If 2, recycle images from the current and previous runs (default). 17159 17160=item B<->(B<no>)B<antialias_text> 17161 17162Use anti-aliasing in the generation of images of typeset material; 17163e.g. mathematics and text, e.g. in tables and {makeimage} environments. 17164 17165=item B<->(B<no>)B<antialias> 17166 17167Use anti-aliasing in the generation of images of figures. This usually 17168results in "sharper" bitmap images. 17169 17170=item B<->(B<no>)B<transparent> 17171 17172If this is set to false then any inlined images generated from "figure" 17173environments will NOT be transparent. 17174 17175=item B<->(B<no>)B<white> 17176 17177This sets the background of generated images to white for anti-aliasing. 17178 17179=item B<->(B<no>)B<discard> 17180 17181if true, the PostScript file created for each generated image 17182is discarded immediately after its image has been rendered and saved in the 17183required graphics format. This can lead to significant savings in disk-space, 17184when there are a lot of images, since otherwise these files are not discarded 17185until the end of all processing. 17186 17187=item B<-image_type> I<type> 17188 17189Specify the type of bitmap images to be generated. Depending on your setup, 17190B<LaTeX2HTML> can generate B<gif> or B<png> images. Note: Gif images have 17191certain legal restrictions, as their generation involves an algorithm 17192patented by Unisys. 17193 17194=item B<->(B<no>)B<images> 17195 17196If false, B<LaTeX2HTML> will not attempt to produce any inlined images. 17197The missing images can be generated "off-line" by restarting B<LaTeX2HTML> 17198with B<-images_only>. 17199 17200=item B<-accent_images> I<type> | B<-noaccent_images> 17201 17202MISSING_DESCRIPTION 17203 17204=item B<-style> I<style> 17205 17206MISSING_DESCRIPTION 17207 17208=item B<->(B<no>)B<parbox_images> 17209 17210MISSING_DESCRIPTION 17211 17212=item B<->(B<no>)B<math> 17213 17214By default the special MATH extensions are not used 17215since they do not conform with the HTML 3.2 standard. 17216 17217=item B<->(B<no>)B<math_parsing> 17218 17219MISSING_DESCRIPTION 17220 17221=item B<->(B<no>)B<latin> 17222 17223MISSING_DESCRIPTION 17224 17225=item B<->(B<no>)B<entities> 17226 17227MISSING_DESCRIPTION 17228 17229=item B<->(B<no>)B<local_icons> 17230 17231Set this if you want to copy the navigation icons to each document directory 17232so that the document directory is self-contained and can be dropped into 17233another server tree without further actions. 17234 17235=item B<->(B<no>)B<scalable_fonts> 17236 17237MISSING_DESCRIPTION 17238 17239=item B<->(B<no>)B<images_only> 17240 17241When true, B<LaTeX2HTML> will only try to convert the inlined images in the 17242file F<images.tex> which should have been generated automatically during 17243previous runs. This is very useful for correcting "bad LaTeX" in this file. 17244 17245=item B<->(B<no>)B<show_section_numbers> 17246 17247When this is set true, the section numbers are shown. The section numbers 17248should then match those that would have been produced by LaTeX. 17249The correct section numbers are obtained from the $FILE.aux file generated 17250by LaTeX. 17251Hiding the section numbers encourages use of particular sections 17252as standalone documents. In this case the cross reference to a section 17253is shown using the default symbol rather than the section number. 17254 17255=item B<->(B<no>)B<show_init> 17256 17257MISSING_DESCRIPTION 17258 17259=item B<-init_file> I<Perl_file> 17260 17261MISSING_DESCRIPTION 17262 17263=item B<-up_url> I<up_URL>, B<-up_title> I<up_title> 17264 17265=item B<-down_url> I<down_URL>, B<-down_title> I<down_title> 17266 17267=item B<-prev_url> I<prev_URL>, B<-prev_title> I<prev_title> 17268 17269=item B<-index> I<index_URL>, 17270 17271=item B<-contents> I<toc_URL> 17272 17273=item B<-biblio> I<biblio_URL> 17274 17275If both of the listed two options are set then the "Up" ("Previous" etc.) 17276button of the navigation panel in the first node/page of a converted 17277document will point to I<up_URL> etc. I<up_title> should be set 17278to some text which describes this external link. 17279Similarly you might use these options to link external documents 17280to your navigation panel. 17281 17282=item B<-external_file> I<external_aux_file> 17283 17284MISSING_DESCRIPTION 17285 17286=item B<->(B<no>)B<short_index> 17287 17288If this is set then B<makeidx.perl> will construct codified names 17289for the text of index references. 17290 17291=item B<->(B<no>)B<unsegment> 17292 17293Use this to translate a segmented document as if it were not 17294segmented. 17295 17296=item B<->(B<no>)B<debug> 17297 17298If this is set then intermediate files are left for later inspection and 17299a lot of diagnostic output is produced. This output may be useful when 17300searching for problems and/or submitting bug reports to the developers. 17301Temporary files include F<$$_images.tex> and F<$$_images.log> created during 17302image conversion. Caution: Intermediate files can be I<enormous>! 17303 17304=item B<-tmp> I<path> 17305 17306Path for temporary files. This should be a local, fast filesystem because it is heavily used during image generation. The default is set in F<l2hconf.pm>. 17307 17308=item B<->(B<no>)B<ldump> 17309 17310This will cause LaTeX2HTML to produce a LaTeX dump of images.tex which is read 17311in on subsequent runs and speeds up startup time of LaTeX on the images.tex 17312translation. This actually consumes additional time on the first run, but pays 17313off on subsequent runs. The dump file will need about 1 Meg of disk space. 17314 17315=item B<->(B<no>)B<timing> 17316 17317MISSING_DESCRIPTION 17318 17319=item B<-verbosity> I<num> 17320 17321The amount of message information printed to the screen during processing 17322by B<LaTeX2HTML> is controlled by this setting. 17323By increasing this value, more information is displayed. 17324Here is the type of extra information that is shown at each level: 17325 17326 0 no extra information 17327 1 section types and titles 17328 2 environment 17329 3 command names 17330 4 links, labels and internal sectioning codes 17331 17332=item B<-html_version> I<list> 17333 17334Which HTML version should be generated. Currently available are: 17335C<2.0>, C<3.0>, C<3.2>, C<4.0>. Some additional options that may be 17336added are: C<math> (parse mathematics), C<i18n> (?), 17337C<table> (generate tables), C<frame> (generate frames), 17338C<latin1>...C<latin9> (use ISO-Latin-x encoding), 17339C<unicode> (generate unicode characters). Separate the options with ',', 17340e.g. C<4.0,math,frame>. 17341 17342=item B<->(B<no>)B<strict> 17343 17344MISSING_DESCRIPTION 17345 17346=back 17347 17348=head1 FILES 17349 17350=over 4 17351 17352=item F<$LATEX2HTMLPLATDIR/l2hconf.pm> 17353 17354This file holds the global defaults and configuration settings for 17355B<LaTeX2HTML>. 17356 17357=item F<$HOME/.latex2html-init> 17358 17359=item F<./.latex2html-init> 17360 17361These files may contain settings that override the global defaults, just 17362like specifying command line switches. 17363 17364=back 17365 17366=head1 ENVIRONMENT 17367 17368=over 4 17369 17370=item LATEX2HTMLDIR 17371 17372Path where LaTeX2HTML library files are found. On this installation 17373LATEX2HTMLDIR is F<@LATEX2HTMLDIR@> 17374 17375=item PERL5LIB 17376 17377Set by the B<latex2html> program to find perl modules. 17378 17379=item L2HCONFIG 17380 17381An alternative configuration filename. The standard configuration file 17382is F<$LATEX2HTMLPLATDIR/l2hconf.pm>. You may specify a sole filename (searched 17383for in F<$LATEX2HTMLPLATDIR> (and F<$PERL5LIB>) or a complete path. 17384 17385=item L2HINIT_NAME 17386 17387The standard user-specific configuration filename is F<.latex2html-init>. 17388This environment variable will override this name. 17389 17390=item HOME 17391 17392Evaluated if the system does not know about "home" directories (like 17393DOS, WinXX, OS/2, ...) to determine the path to F<$L2HINIT_NAME>. 17394 17395=item TEXE_DONT_INCLUDE, TEXE_DO_INCLUDE 17396 17397Used internally for communication with B<texexpand>. 17398 17399=item TEXINPUTS 17400 17401Used to find TeX includes of all sorts. 17402 17403=back 17404 17405=head1 PROBLEMS 17406 17407For information on various problems and remedies see the WWW online 17408documentation or the documents available in the distribution. 17409An online bug reporting form and various archives are available at 17410F<http://www.latex2html.org/> 17411 17412There is a mailing list for discussing B<LaTeX2HTML>: C<latex2html@tug.org> 17413 17414=head1 AUTHOR 17415 17416Nikos Drakos, Computer Based Learning Unit, University of Leeds 17417E<lt>nikos@cbl.leeds.ac.ukE<gt>. Several people have contributed 17418suggestions, ideas, solutions, support and encouragement. 17419 17420The B<pstoimg> script was written by Marek Rouchal 17421E<lt>marek@saftsack.fs.uni-bayreuth.deE<gt> 17422as a generalisation of the B<pstogif> utility to allow graphic formats 17423other than GIF to be created. Various options and enhancements have 17424been added by Ross Moore. 17425Some of the code is based upon the pstoppm.ps postscript program 17426originally written by Phillip Conrad (Perfect Byte, Inc.) 17427and modified by L. Peter Deutsch (Aladdin Enterprises). 17428 17429=head1 SEE ALSO 17430 17431See the WWW online documentation or the F<$LATEX2HTMLDIR/doc/manual.ps> 17432file for more detailed information and examples. 17433 17434L<pstoing>, L<texexpand> 17435 17436=cut 17437 17438