1#! /usr/bin/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 73BEGIN { 74 # print "scanning for l2hdir\n"; 75 if($ENV{'LATEX2HTMLDIR'}) { 76 $LATEX2HTMLDIR = $ENV{'LATEX2HTMLDIR'}; 77 } else { 78 $ENV{'LATEX2HTMLDIR'} = $LATEX2HTMLDIR = '/home/bsbuild/dev/org-release/bacula-docs-11.0.5/latex2html'; 79 } 80 81 if($ENV{'LATEX2HTMLPLATDIR'}) { 82 $LATEX2HTMLPLATDIR = $ENV{'LATEX2HTMLPLATDIR'}; 83 } else { 84 $LATEX2HTMLPLATDIR = '/home/bsbuild/dev/org-release/bacula-docs-11.0.5/latex2html'||$LATEX2HTMLDIR; 85 $ENV{'LATEX2HTMLPLATDIR'} = $LATEX2HTMLPLATDIR; 86 } 87 if(-d $LATEX2HTMLPLATDIR) { 88 push(@INC,$LATEX2HTMLPLATDIR); 89 } 90 91 if(-d $LATEX2HTMLDIR) { 92 push(@INC,$LATEX2HTMLDIR); 93 } else { 94 die qq{Fatal: Directory "$LATEX2HTMLDIR" does not exist.\n}; 95 } 96} 97 98use L2hos; # Operating system dependent routines 99 100# $^W = 1; # turn on warnings 101 102my $RELEASE = '2016'; 103my ($REVISION) = q$Revision: 1.71 $ =~ /:\s*(\S+)/; 104 105# The key, which delimts expressions defined in the environment 106# depends on the operating system. 107$envkey = L2hos->pathd(); 108 109# $dd is the directory delimiter character 110$dd = L2hos->dd(); 111 112# make sure the $LATEX2HTMLDIR is on the search-path for forked processes 113if($ENV{'PERL5LIB'}) { 114 $ENV{'PERL5LIB'} .= "$envkey$LATEX2HTMLDIR" 115 unless($ENV{'PERL5LIB'} =~ m|\Q$LATEX2HTMLDIR\E|o); 116} else { 117 $ENV{'PERL5LIB'} = $LATEX2HTMLDIR; 118} 119 120# Local configuration, read at runtime 121# Read the $CONFIG_FILE (usually l2hconf.pm ) 122if($ENV{'L2HCONFIG'}) { 123 require $ENV{'L2HCONFIG'} || 124 die "Fatal (require $ENV{'L2HCONFIG'}): $!"; 125} else { 126 eval 'use l2hconf'; 127 if($@) { 128 die "Fatal (use l2hconf): $@\n"; 129 } 130} 131 132# MRO: Changed this to global value in config/config.pl 133# change these whenever you do a patch to this program and then 134# name the resulting patch file accordingly 135# $TVERSION = "2016"; 136#$TPATCHLEVEL = " beta"; 137#$TPATCHLEVEL = " release"; 138#$RELDATE = "(March 30, 1999)"; 139#$TEX2HTMLV_SHORT = $TVERSION . $TPATCHLEVEL; 140 141$TEX2HTMLV_SHORT = $RELEASE; 142$TEX2HTMLVERSION = "$TEX2HTMLV_SHORT ($REVISION)"; 143$TEX2HTMLADDRESS = "http://www.latex2html.org/"; 144$AUTHORADDRESS = "http://cbl.leeds.ac.uk/nikos/personal.html"; 145#$AUTHORADDRESS2 = "http://www-math.mpce.mq.edu.au/%7Eross/"; 146$AUTHORADDRESS2 = "http://www.maths.mq.edu.au/~ross/"; 147 148# Set $HOME to what the system considers the home directory 149$HOME = L2hos->home(); 150push(@INC,$HOME); 151 152# flush stdout with every print -- gives better feedback during 153# long computations 154$| = 1; 155 156# set Perl's subscript separator to LaTeX's illegal character. 157# (quite defensive but why not) 158$; = "\000"; 159 160# No arguments!! 161unless(@ARGV) { 162 die "Error: No files to process!\n"; 163} 164 165# Image prefix 166$IMAGE_PREFIX = '_image'; 167 168# Partition prefix 169$PARTITION_PREFIX = 'part_' unless $PARTITION_PREFIX; 170 171# Author address 172@address_data = &address_data('ISO'); 173$ADDRESS = "$address_data[0]\n$address_data[1]"; 174 175# ensure non-zero defaults 176$MAX_SPLIT_DEPTH = 4 unless ($MAX_SPLIT_DEPTH); 177$MAX_LINK_DEPTH = 4 unless ($MAX_LINK_DEPTH); 178$TOC_DEPTH = 4 unless ($TOC_DEPTH); 179 180# A global value may already be set in the $CONFIG_FILE 181$INIT_FILE_NAME = $ENV{'L2HINIT_NAME'} || '.latex2html-init' 182 unless $INIT_FILE_NAME; 183 184# Read the $HOME/$INIT_FILE_NAME if one is found 185if (-f "$HOME$dd$INIT_FILE_NAME" && -r _) { 186 print "Note: Loading $HOME$dd$INIT_FILE_NAME\n"; 187 require("$HOME$dd$INIT_FILE_NAME"); 188 $INIT_FILE = "$HOME$dd$INIT_FILE_NAME"; 189 # _MRO_TODO_: Introduce a version to be checked? 190 die "Error: You have an out-of-date " . $HOME . 191 "$dd$INIT_FILE_NAME file.\nPlease update or delete it.\n" 192 if ($DESTDIR eq '.'); 193} 194 195# Read the $INIT_FILE_NAME file if one is found in current directory 196if ( L2hos->Cwd() ne $HOME && -f ".$dd$INIT_FILE_NAME" && -r _) { 197 print "Note: Loading .$dd$INIT_FILE_NAME\n"; 198 require(".$dd$INIT_FILE_NAME"); 199 $INIT_FILE = "$INIT_FILE_NAME"; 200} 201die "Error: '.' is an incorrect setting for DESTDIR.\n" . 202 "Please check your $INIT_FILE_NAME file.\n" 203 if ($DESTDIR eq '.'); 204 205# User home substitutions 206$LATEX2HTMLSTYLES =~ s/~([$dd$dd$envkey]|$)/$HOME$1/go; 207# the next line fails utterly on non-UNIX systems 208$LATEX2HTMLSTYLES =~ s/~([^$dd$dd$envkey]+)/L2hos->home($1)/geo; 209 210#absolutise the paths 211$LATEX2HTMLSTYLES = join($envkey, 212 map(L2hos->Make_directory_absolute($_), 213 split(/$envkey/o, $LATEX2HTMLSTYLES))); 214 215#HWS: That was the last reference to HOME. Now set HOME to $LATEX2HTMLDIR, 216# to enable dvips to see that version of .dvipsrc! But only if we 217# have DVIPS_MODE not set - yes - this is a horrible nasty kludge 218# MRO: The file has to be updated by configure _MRO_TODO_ 219 220if ($PK_GENERATION && ! $DVIPS_MODE) { 221 $ENV{HOME} = $LATEX2HTMLDIR; 222 delete $ENV{PRINTER}; # Overrides .dvipsrc 223} 224 225# language of the DTD specified in the <DOCTYPE...> tag 226$ISO_LANGUAGE = 'EN' unless $ISO_LANGUAGE; 227 228# Save the command line arguments, quote where necessary 229$argv = join(' ', map {/[\s#*!\$%]/ ? "'$_'" : $_ } @ARGV); 230 231# Pre-process the command line for backward compatibility 232foreach(@ARGV) { 233 s/^--?no_/-no/; # replace e.g. no_fork by nofork 234 # s/^[+](\d+)$/$1/; # remove + in front of integers 235} 236 237# Process command line options 238my %opt; 239unless(GetOptions(\%opt, # all non-linked options go into %opt 240 # option linkage (optional) 241 'help|h', 242 'version|V', 243 'split=s', 244 'link=s', 245 'toc_depth=i', \$TOC_DEPTH, 246 'toc_stars!', \$TOC_STARS, 247 'short_extn!', \$SHORTEXTN, 248 'iso_language=s', \$ISO_LANGUAGE, 249 'validate!', \$HTML_VALIDATE, 250 'latex!', 251 'djgpp!', \$DJGPP, 252 'fork!', \$CAN_FORK, 253 'external_images!', \$EXTERNAL_IMAGES, 254 'ascii_mode!', \$ASCII_MODE, 255 'lcase_tags!', \$LOWER_CASE_TAGS, 256 'ps_images!', \$PS_IMAGES, 257 'font_size=s', \$FONT_SIZE, 258 'tex_defs!', \$TEXDEFS, 259 'navigation!', 260 'top_navigation!', \$TOP_NAVIGATION, 261 'bottom_navigation!', \$BOTTOM_NAVIGATION, 262 'auto_navigation!', \$AUTO_NAVIGATION, 263 'index_in_navigation!', \$INDEX_IN_NAVIGATION, 264 'contents_in_navigation!', \$CONTENTS_IN_NAVIGATION, 265 'next_page_in_navigation!', \$NEXT_PAGE_IN_NAVIGATION, 266 'previous_page_in_navigation!', \$PREVIOUS_PAGE_IN_NAVIGATION, 267 'footnode!', 268 'numbered_footnotes!', \$NUMBERED_FOOTNOTES, 269 'prefix=s', \$PREFIX, 270 'auto_prefix!', \$AUTO_PREFIX, 271 'long_titles=i', \$LONG_TITLES, 272 'custom_titles!', \$CUSTOM_TITLES, 273 'title|t=s', \$TITLE, 274 'rooted!', \$ROOTED, 275 'rootdir=s', 276 'dir=s', \$FIXEDDIR, 277 'mkdir', \$MKDIR, 278 'address=s', \$ADDRESS, 279 'noaddress', 280 'subdir!', 281 'info=s', \$INFO, 282 'noinfo', 283 'auto_link!', 284 'reuse=i', \$REUSE, 285 'noreuse', 286 'antialias_text!', \$ANTI_ALIAS_TEXT, 287 'antialias!', \$ANTI_ALIAS, 288 'transparent!', \$TRANSPARENT_FIGURES, 289 'white!', \$WHITE_BACKGROUND, 290 'discard!', \$DISCARD_PS, 291 'image_type=s', \$IMAGE_TYPE, 292 'images!', 293 'accent_images=s', \$ACCENT_IMAGES, 294 'noaccent_images', 295 'style=s', \$STYLESHEET, 296 'parbox_images!', 297 'math!', 298 'math_parsing!', 299 'latin!', 300 'entities!', \$USE_ENTITY_NAMES, 301 'local_icons!', \$LOCAL_ICONS, 302 'scalable_fonts!', \$SCALABLE_FONTS, 303 'images_only!', \$IMAGES_ONLY, 304 'show_section_numbers!',\$SHOW_SECTION_NUMBERS, 305 'show_init!', \$SHOW_INIT_FILE, 306 'init_file=s', \$INIT_FILE, 307 'up_url=s', \$EXTERNAL_UP_LINK, 308 'up_title=s', \$EXTERNAL_UP_TITLE, 309 'down_url=s', \$EXTERNAL_DOWN_LINK, 310 'down_title=s', \$EXTERNAL_DOWN_TITLE, 311 'prev_url=s', \$EXTERNAL_PREV_LINK, 312 'prev_title=s', \$EXTERNAL_PREV_TITLE, 313 'index=s', \$EXTERNAL_INDEX, 314 'biblio=s', \$EXTERNAL_BIBLIO, 315 'contents=s', \$EXTERNAL_CONTENTS, 316 'external_file=s', \$EXTERNAL_FILE, 317 'short_index!', \$SHORT_INDEX, 318 'unsegment!', \$UNSEGMENT, 319 'debug!', \$DEBUG, 320 'tmp=s', \$TMP, 321 'ldump!', \$LATEX_DUMP, 322 'timing!', \$TIMING, 323 'verbosity=i', \$VERBOSITY, 324 'html_version=s', \$HTML_VERSION, 325 'strict!', \$STRICT_HTML, 326 'xbit!', \$XBIT_HACK, 327 'ssi!', \$ALLOW_SSI, 328 'php!', \$ALLOW_PHP, 329 'test_mode!' # undocumented switch 330 )) { 331 &usage(); 332 exit 1; 333} 334 335# interpret options, check option consistency 336if(defined $opt{'split'}) { 337 if ($opt{'split'} =~ /^(\+?)(\d+)$/) { 338 $MAX_SPLIT_DEPTH = $2; 339 if ($1) { $MAX_SPLIT_DEPTH *= -1; $REL_DEPTH = 1; } 340 } else { 341 &usage; 342 die "Error: Unrecognised value for -split: $opt{'split'}\n"; 343 } 344} 345if(defined $opt{'link'}) { 346 if ($opt{'link'} =~ /^(\+?)(\d+)$/) { 347 $MAX_LINK_DEPTH = $2; 348 if ($1) { $MAX_LINK_DEPTH *= -1 } 349 } else { 350 &usage; 351 die "Error: Unrecognised value for -link: $opt{'link'}\n"; 352 } 353} 354unless ($ISO_LANGUAGE =~ /^[A-Z.]+$/) { 355 die "Error: Language (-iso_language) must be uppercase and dots only: $ISO_LANGUAGE\n"; 356} 357if ($HTML_VALIDATE && !$HTML_VALIDATOR) { 358 die "Error: Need a HTML_VALIDATOR when -validate is specified.\n"; 359} 360&set_if_false($NOLATEX,$opt{latex}); # negate the option... 361if ($ASCII_MODE || $PS_IMAGES) { 362 $EXTERNAL_IMAGES = 1; 363} 364if ($FONT_SIZE && $FONT_SIZE !~ /^\d+pt$/) { 365 die "Error: Font size (-font_size) must end with 'pt': $FONT_SIZE\n" 366} 367&set_if_false($NO_NAVIGATION,$opt{navigation}); 368&set_if_false($NO_FOOTNODE,$opt{footnode}); 369if (defined $TITLE && !length($TITLE)) { 370 die "Error: Empty title (-title).\n"; 371} 372if ($opt{rootdir}) { 373 $ROOTED = 1; 374 $FIXEDDIR = $opt{rootdir}; 375} 376if ($FIXEDDIR && !-d $FIXEDDIR) { 377 if ($MKDIR) { 378 print "\n *** creating directory: $FIXEDDIR "; 379 die "Failed: $!\n" unless (mkdir($FIXEDDIR, 0755)); 380 # _TODO_ use File::Path to create a series of directories 381 } else { 382 &usage; 383 die "Error: Specified directory (-rootdir, -dir) does not exist.\n"; 384 } 385} 386&set_if_false($NO_SUBDIR, $opt{subdir}); 387&set_if_false($NO_AUTO_LINK, $opt{auto_link}); 388if ($opt{noreuse}) { 389 $REUSE = 0; 390} 391unless(grep(/^\Q$IMAGE_TYPE\E$/o, @IMAGE_TYPES)) { 392 die <<"EOF"; 393Error: No such image type '$IMAGE_TYPE'. 394 This installation supports (first is default): @IMAGE_TYPES 395EOF 396} 397&set_if_false($NO_IMAGES, $opt{images}); 398if ($opt{noaccent_images}) { 399 $ACCENT_IMAGES = ''; 400} 401if($opt{noaddress}) { 402 $ADDRESS = ''; 403} 404if($opt{noinfo}) { 405 $INFO = 0; 406} 407if($ACCENT_IMAGES && $ACCENT_IMAGES !~ /^[a-zA-Z,]+$/) { 408 die "Error: Single word or comma-list of style words needed for -accent_images, not: $_\n"; 409} 410&set_if_false($NO_PARBOX_IMAGES, $opt{parbox_images}); 411&set_if_false($NO_SIMPLE_MATH, $opt{math}); 412if (defined $opt{math_parsing}) { 413 $NO_MATH_PARSING = !$opt{math_parsing}; 414 $NO_SIMPLE_MATH = !$opt{math_parsing} unless(defined $opt{math}); 415} 416&set_if_false($NO_ISOLATIN, $opt{latin}); 417if ($INIT_FILE) { 418 if (-f $INIT_FILE && -r _) { 419 print "Note: Initialising with file: $INIT_FILE\n" 420 if ($DEBUG || $VERBOSITY); 421 require($INIT_FILE); 422 } else { 423 die "Error: Could not find file (-init_file): $INIT_FILE\n"; 424 } 425} 426foreach($EXTERNAL_UP_LINK, $EXTERNAL_DOWN_LINK, $EXTERNAL_PREV_LINK, 427 $EXTERNAL_INDEX, $EXTERNAL_BIBLIO, $EXTERNAL_CONTENTS) { 428 $_ ||= ''; # initialize 429 s/~/~/g; # protect `~' 430} 431if($TMP && !(-d $TMP && -w _)) { 432 die "Error: '$TMP' not usable as temporary directory.\n"; 433} 434if ($opt{help}) { 435 L2hos->perldoc($SCRIPT); 436 exit 0; 437} 438if ($opt{version}) { 439 &banner(); 440 exit 0; 441} 442if ($opt{test_mode}) { 443 $TITLE = 'LaTeX2HTML Test Document'; 444 $TEXEXPAND = "$PERL /home/bsbuild/dev/org-release/bacula-docs-11.0.5/latex2html-2016${dd}texexpand"; 445 $PSTOIMG = "$PERL /home/bsbuild/dev/org-release/bacula-docs-11.0.5/latex2html-2016${dd}pstoimg"; 446 $ICONSERVER = L2hos->path2URL("/home/bsbuild/dev/org-release/bacula-docs-11.0.5/latex2html-2016${dd}icons"); 447 $TEST_MODE = 1; 448 $RGBCOLORFILE = "/home/bsbuild/dev/org-release/bacula-docs-11.0.5/latex2html-2016${dd}styles${dd}rgb.txt"; 449 $CRAYOLAFILE = "/home/bsbuild/dev/org-release/bacula-docs-11.0.5/latex2html-2016${dd}styles${dd}crayola.txt"; 450} 451if($DEBUG) { 452 # make the OS-dependent functions more chatty, too 453 $L2hos::Verbose = 1; 454} 455 456undef %opt; # not needed any more 457 458 459$FIXEDDIR = $FIXEDDIR || $DESTDIR || ''; # for backward compatibility 460 461if ($EXTERNAL_UP_TITLE xor $EXTERNAL_UP_LINK) { 462 warn "Warning (-up_url, -up_title): Need to specify both a parent URL and a parent title!\n"; 463 $EXTERNAL_UP_TITLE = $EXTERNAL_UP_LINK = ""; 464} 465 466if ($EXTERNAL_DOWN_TITLE xor $EXTERNAL_DOWN_LINK) { 467 warn "Warning (-down_url, -down_title): Need to specify both a parent URL and a parent title!\n"; 468 $EXTERNAL_DOWN_TITLE = $EXTERNAL_DOWN_LINK = ""; 469} 470 471# $NO_NAVIGATION = 1 unless $MAX_SPLIT_DEPTH; # Martin Wilck 472 473if ($MAX_SPLIT_DEPTH && $MAX_SPLIT_DEPTH < 0) { 474 $MAX_SPLIT_DEPTH *= -1; $REL_DEPTH = 1; 475} 476if ($MAX_LINK_DEPTH && $MAX_LINK_DEPTH < 0) { 477 $MAX_LINK_DEPTH *= -1; $LEAF_LINKS = 1; 478} 479 480$FOOT_FILENAME = 'footnode' unless ($FOOT_FILENAME); 481$NO_FOOTNODE = 1 unless ($MAX_SPLIT_DEPTH || $NO_FOOTNODE); 482$NO_SPLIT = 1 unless $MAX_SPLIT_DEPTH; # _MRO_TODO_: is this needed at all? 483$SEGMENT = $SEGMENTED = 0; 484$NO_MATH_MARKUP = 1; 485 486# specify the filename extension to use with the generated HTML files 487if ($SHORTEXTN) { $EXTN = ".htm"; } # for HTML files on CDROM 488elsif ($ALLOW_PHP) { $EXTN = ".php"; } # has PHP dynamic includes 489 # with server-side includes (SSI) : 490elsif ($ALLOW_SSI && !$XBIT_HACK) { $EXTN = ".shtml"; } 491 # ordinary names, valid also for SSI with XBit hack : 492else { $EXTN = ".html"; } 493 494$NODE_NAME = 'node' unless (defined $NODE_NAME); 495 496# space for temporary files 497# different to the $TMPDIR for image-generation 498# MRO: No directory should end with $dd! 499$TMP_ = "TMP"; 500 501$TMP_PREFIX = "l2h" unless ($TMP_PREFIX); 502 503# This can be set to 1 when using a version of dvips that is safe 504# from the "dot-in-name" bug. 505# _TODO_ this should be determined by configure 506$DVIPS_SAFE = 1; 507 508$CHARSET = $charset || 'iso-8859-1'; 509 510#################################################################### 511# 512# If possible, use icons of the same type as generated images 513# 514if ($IMAGE_TYPE && %{"icons_$IMAGE_TYPE"}) { 515 %icons = %{"icons_$IMAGE_TYPE"}; 516} 517 518#################################################################### 519# 520# Figure out what options we need to pass to DVIPS and store that in 521# the $DVIPSOPT variable. Also, scaling is taken care of at the 522# dvips level if PK_GENERATION is set to 1, so adjust SCALE_FACTORs 523# accordingly. 524# 525if ($SCALABLE_FONTS) { 526 $PK_GENERATION = 0; 527 $DVIPS_MODE = ''; 528} 529 530if ($PK_GENERATION) { 531 if ($MATH_SCALE_FACTOR <= 0) { $MATH_SCALE_FACTOR = 2; } 532 if ($FIGURE_SCALE_FACTOR <= 0) { $FIGURE_SCALE_FACTOR = 2; } 533 my $saveMSF = $MATH_SCALE_FACTOR; 534 my $saveFSF = $FIGURE_SCALE_FACTOR; 535 my $desired_dpi = int($MATH_SCALE_FACTOR*75); 536 $FIGURE_SCALE_FACTOR = ($METAFONT_DPI / 72) * 537 ($FIGURE_SCALE_FACTOR / $MATH_SCALE_FACTOR) ; 538 $MATH_SCALE_FACTOR = $METAFONT_DPI / 72; 539 $dvi_mag = int(1000 * $desired_dpi / $METAFONT_DPI); 540 if ($dvi_mag > 1000) { 541 &write_warnings( 542 "WARNING: Your SCALE FACTOR is too large for PK_GENERATION.\n" . 543 " See $CONFIG_FILE for more information.\n"); 544 } 545 546 # RRM: over-sized scaling, using dvi-magnification 547 if ($EXTRA_IMAGE_SCALE) { 548 print "\n *** Images at $EXTRA_IMAGE_SCALE times resolution of displayed size ***\n"; 549 $desired_dpi = int($EXTRA_IMAGE_SCALE * $desired_dpi+.5); 550 print " desired_dpi = $desired_dpi METAFONT_DPI = $METAFONT_DPI\n" 551 if $DEBUG; 552 $dvi_mag = int(1000 * $desired_dpi / $METAFONT_DPI); 553 $MATH_SCALE_FACTOR = $saveMSF; 554 $FIGURE_SCALE_FACTOR = $saveFSF; 555 } 556 # no space after "-y", "-D", "-e" --- required by DVIPS under DOS ! 557 my $mode_switch = "-mode $DVIPS_MODE" if $DVIPS_MODE; 558 $DVIPSOPT .= " -y$dvi_mag -D$METAFONT_DPI $mode_switch -e5 "; 559} else { # no PK_GENERATION 560# if ($EXTRA_IMAGE_SCALE) { 561# &write_warnings( 562# "the \$EXTRA_IMAGE_SCALE feature requires either \$PK_GENERATION=1" 563# . " or the '-scalable_fonts' option"); 564# $EXTRA_IMAGE_SCALE = ''; 565# } 566 # MRO: shifted to l2hconf 567 #$DVIPSOPT .= ' -M'; 568} # end PK_GENERATION 569 570# The mapping from numbers to accents. 571# These are required to process the \accent command, which is found in 572# tables of contents whenever there is an accented character in a 573# caption or section title. Processing the \accent command makes 574# $encoded_*_number work properly (see &extract_captions) with 575# captions that contain accented characters. 576# I got the numbers from the plain.tex file, version 3.141. 577 578# Missing entries should be looked up by a native speaker. 579# Have a look at generate_accent_commands and $iso_8859_1_character_map. 580 581# MEH: added more accent types 582# MRO: only uppercase needed! 583%accent_type = ( 584 '18' => 'grave', # \` 585 '19' => 'acute', # `' 586 '20' => 'caron', # \v 587 '21' => 'breve', # \u 588 '22' => 'macr', # \= 589 '23' => 'ring', # 590 '24' => 'cedil', # \c 591 '94' => 'circ', # \^ 592 '95' => 'dot', # \. 593 '7D' => 'dblac', # \H 594 '7E' => 'tilde', # \~ 595 '7F' => 'uml', # \" 596); 597 598&driver; 599exit 0; # clean exit, no errors 600 601############################ Subroutines ################################## 602# Philippe Chauvat - 03-feb-2017 603sub extract_external_references { 604 local($bmanual) = @_ ; 605 # 606 # Philippe Chauvat - 08-mar-2017 607 # write the labels found into the current documents 608 # 609 my $bxrefile = join('','../../','html-external-references.sed') ; 610 my $birefile = join('','../../','html-internal-references.sed') ; 611 open EFH, ">" . $bxrefile or die "$!: Unable to create $bxrefile\n" ; 612 open IFH, ">" . $birefile or die "$!: Unable to create $birefile\n" ; 613 foreach my $k (keys %ref_files) { 614 print EFH join('','s|',$bmanual,'/__TO_BE_REPLACED_WITH_HTML_FILENAME__#',$k,'|',$bmanual,'/',$ref_files{$k},'#',$k,"|\n") ; 615 print IFH join('','s|__TO_BE_REPLACED_WITH_HTML_FILENAME__#',$k,'|',$ref_files{$k},'#',$k,"|\n") ; 616# print FH join('','s|',$bmanual,'/__TO_BE_REPLACED_WITH_HTML_FILENAME__#',$k,'|',$bmanual,'/',$ref_files{$k},'#',$bmanual,'-',$k,"|\n") ; 617 } 618 close EFH ; 619 close IFH ; 620} 621 622sub pre_pre_process { 623 # 624 # We need this to handle acronyms 625 %bacronyms = () ; 626} 627 628#check that $TMP is writable, if so create a subdirectory 629sub make_tmp_dir { 630 &close_dbm_database if $DJGPP; # to save file-handles 631 632 # determine a suitable temporary path 633 # 634 $TMPDIR = ''; 635 my @tmp_try = (); 636 push(@tmp_try, $TMP) if($TMP); 637 push(@tmp_try, "$DESTDIR$dd$TMP_") if($TMP_); 638 push(@tmp_try, $DESTDIR) if($DESTDIR); 639 push(@tmp_try, L2hos->Cwd()); 640 641 my $try; 642 TempTry: foreach $try (@tmp_try) { 643 next unless(-d $try && -w _); 644 my $tmp = "$try$dd$TMP_PREFIX$$"; 645 if(mkdir($tmp,0755)) { 646 $TMPDIR=$tmp; 647 last TempTry; 648 } else { 649 warn "Warning: Cannot create temporary directory '$tmp': $!\n"; 650 } 651 } 652 653 $dvips_warning = <<"EOF"; 654 655Warning: There is a '.' in \$TMPDIR, $DVIPS will probably fail. 656Set \$TMP to use a /tmp directory, or rename the working directory. 657EOF 658 die ($dvips_warning . "\n\$TMPDIR=$TMPDIR ***\n\n") 659 if ($TMPDIR =~ /\./ && $DVIPS =~ /dvips/ && !$DVIPS_SAFE); 660 661 &open_dbm_database if $DJGPP; 662} 663 664# MRO: set first parameter to the opposite of the second if second parameter is defined 665sub set_if_false { 666 $_[0] = !$_[1] if(defined $_[1]); 667} 668 669sub check_for_dots { 670 local($file) = @_; 671 if ($file =~ /\.[^.]*\./ && !$DVIPS_SAFE) { 672 die "\n\n\n *** Fatal Error --- but easy to fix ***\n" 673 . "\nCannot have '.' in file-name prefix, else dvips fails on images" 674 . "\nChange the name from $file and try again.\n\n"; 675 } 676} 677 678# Process each file ... 679sub driver { 680 local($FILE, $orig_cwd, %unknown_commands, %dependent, %depends_on 681 , %styleID, %env_style, $bbl_cnt, $dbg, %numbered_section); 682 # MRO: $texfilepath has to be global! 683 local(%styles_loaded); 684 $orig_cwd = L2hos->Cwd(); 685 686 print "\n *** initialise *** " if ($VERBOSITY > 1); 687 &initialise; # Initialise some global variables 688 689 print "\n *** check modes *** " if ($VERBOSITY > 1); 690 &ascii_mode if $ASCII_MODE; # Must come after initialization 691 &titles_language($TITLES_LANGUAGE); 692 &make_numbered_footnotes if ($NUMBERED_FOOTNOTES); 693 $dbg = $DEBUG ? "-debug" : ""; 694 $dbg .= (($VERBOSITY>2) ? " -verbose" : ""); 695 696 #use the same hashes for all files in a batch 697 local(%cached_env_img, %id_map, %symbolic_labels, %latex_labels) 698 if ($FIXEDDIR && $NO_SUBDIR); 699 700 local($MULTIPLE_FILES,$THIS_FILE); 701 $MULTIPLE_FILES = 1+$#ARGV if $ROOTED; 702 print "\n *** $MULTIPLE_FILES file".($MULTIPLE_FILES ? 's: ' : ': ') 703 . join(',',@ARGV) . " *** " if ($VERBOSITY > 1); 704 705 local(%section_info, %toc_section_info, %cite_info, %ref_files); 706 707 foreach $FILE (@ARGV) { 708 &check_for_dots($FILE) unless $DVIPS_SAFE; 709 ++$THIS_FILE if $MULTIPLE_FILES; 710 do { 711 %section_info = (); 712 %toc_section_info = (); 713 %cite_info = (); 714 %ref_files = (); 715 } unless $MULTIPLE_FILES; 716 local($bbl_nr) = 1; 717 718 # The number of reused images and those in images.tex 719 local($global_page_num) = (0) unless($FIXEDDIR && $NO_SUBDIR); 720 # The number of images in images.tex 721 local($new_page_num) = (0); # unless($FIXEDDIR && $NO_SUBDIR); 722 local($pid, $sections_rx, 723 , $outermost_level, %latex_body, $latex_body 724 , %encoded_section_number 725 , %verbatim, %new_command, %new_environment 726 , %provide_command, %renew_command, %new_theorem 727 , $preamble, $aux_preamble, $prelatex, @preamble); 728 729 # must retain these when all files are in the same directory 730 # else the images.pl and labels.pl files get clobbered 731 unless ($FIXEDDIR && $NO_SUBDIR) { 732 print "\nResetting image-cache" if ($#ARGV); 733 local(%cached_env_img, %id_map, %symbolic_labels, %latex_labels) 734 } 735 736## AYS: Allow extension other than .tex and make it optional 737 ($EXT = $FILE) =~ s/.*\.([^\.]*)$/$1/; 738 if ( $EXT eq $FILE ) { 739 $EXT = "tex"; 740 $FILE =~ s/$/.tex/; 741 } 742 743 #RRM: allow user-customisation, dependent on file-name 744 # e.g. add directories to $TEXINPUTS named for the file 745 # --- idea due to Fred Drake <fdrake@acm.org> 746 &custom_driver_hook($FILE) if (defined &custom_driver_hook); 747 748# JCL(jcl-dir) 749# We need absolute paths for TEXINPUTS here, because 750# we change the directory 751 if ($orig_cwd eq $texfilepath) { 752 &deal_with_texinputs($orig_cwd); 753 } else { 754 &deal_with_texinputs($orig_cwd, $texfilepath); 755 } 756 757 ($texfilepath, $FILE) = &get_full_path($FILE); 758 $texfilepath = '.' unless($texfilepath); 759 760 die "Cannot read $texfilepath$dd$FILE \n" 761 unless (-f "$texfilepath$dd$FILE"); 762 763 764# Tell texexpand which files we *don't* want to look at. 765 $ENV{'TEXE_DONT_INCLUDE'} = $DONT_INCLUDE if $DONT_INCLUDE; 766# Tell texexpand which files we *do* want to look at, e.g. 767# home-brew style files 768 $ENV{'TEXE_DO_INCLUDE'} = $DO_INCLUDE if $DO_INCLUDE; 769 770 $FILE =~ s/\.[^\.]*$//; ## AYS 771 $DESTDIR = ''; # start at empty 772 if ($FIXEDDIR) { 773 $DESTDIR = $FIXEDDIR unless ($FIXEDDIR eq '.'); 774 if (($ROOTED)&&!($texfilepath eq $orig_cwd)) { 775 $DESTDIR .= $dd . $FILE unless $NO_SUBDIR; 776 }; 777 } elsif ($texfilepath eq $orig_cwd) { 778 $DESTDIR = ($NO_SUBDIR ? '.' : $FILE); 779 } else { 780 $DESTDIR = $ROOTED ? '.' : $texfilepath; 781 $DESTDIR .= $dd . $FILE unless $NO_SUBDIR; 782 } 783 $PREFIX = "$FILE-" if $AUTO_PREFIX; 784 785 print "\nOPENING $texfilepath$dd$FILE.$EXT \n"; ## AYS 786 787 next unless (&new_dir($DESTDIR,'')); 788 # establish absolute path to $DESTDIR 789 $DESTDIR = L2hos->Make_directory_absolute($DESTDIR); 790 &make_tmp_dir; 791 print "\nNote: Working directory is $DESTDIR\n"; 792 print "Note: Images will be generated in $TMPDIR\n\n"; 793 794# Need to clean up a bit in case there's garbage left 795# from former runs. 796 if ($DESTDIR) { chdir($DESTDIR) || die "$!\n"; } 797 if (opendir (TMP,$TMP_)) { 798 foreach (readdir TMP) { 799 L2hos->Unlink("TMP_$dd$_") unless (/^\.\.?$/); 800 } 801 closedir TMP; 802 } 803 &cleanup(1); 804 unless(-d $TMP_) { 805 mkdir($TMP_, 0755) || 806 die "Cannot create directory '$TMP_': $!\n"; 807 } 808 chdir($orig_cwd); 809 810# RRM 14/5/98 moved this to occur earlier 811## JCL(jcl-dir) 812## We need absolute paths for TEXINPUTS here, because 813## we change the directory 814# if ($orig_cwd eq $texfilepath) { 815# &deal_with_texinputs($orig_cwd); 816# } else { 817# &deal_with_texinputs($orig_cwd, $texfilepath); 818# } 819 820 821# This needs $DESTDIR to have been created ... 822 print " *** calling `texexpand' ***" if ($VERBOSITY > 1); 823 local($unseg) = ($UNSEGMENT ? "-unsegment " : ""); 824 825# does DOS need to check these here ? 826# die "File $TEXEXPAND does not exist or is not executable\n" 827# unless (-x $TEXEXPAND); 828 L2hos->syswait("$TEXEXPAND $dbg -auto_exclude $unseg" 829 . "-save_styles \"$DESTDIR$dd$TMP_${dd}styles\" " 830 . ($TEXINPUTS ? "-texinputs \"$TEXINPUTS\" " : '' ) 831 . (($VERBOSITY >2) ? "-verbose " : '' ) 832 . "-out \"$DESTDIR$dd$TMP_$dd$FILE\" " 833 . "\"$texfilepath$dd$FILE.$EXT\"") 834 && die " texexpand failed: $!\n"; 835 print STDOUT "\n *** `texexpand' done ***\n" if ($VERBOSITY > 1); 836 837 chdir($DESTDIR) if $DESTDIR; 838 $SIG{'INT'} = 'handler'; 839 840 &open_dbm_database; 841 &initialise_sections; 842 print STDOUT "\n *** database open ***\n" if ($VERBOSITY > 1); 843 844 if ($IMAGES_ONLY) { 845 &make_off_line_images; 846 } else { 847 &rename_image_files; 848 &load_style_file_translations; 849 &make_language_rx; 850 &make_raw_arg_cmd_rx; 851# &make_isolatin1_rx unless ($NO_ISOLATIN); 852 &translate_titles; 853 &make_sections_rx; 854 print "\nReading ..."; 855 if ($SHORT_FILENAME) { 856 L2hos->Rename ("$TMP_$dd$FILE" ,"$TMP_$dd$SHORT_FILENAME" ); 857 &slurp_input_and_partition_and_pre_process( 858 "$TMP_$dd$SHORT_FILENAME"); 859 } else { 860 &slurp_input_and_partition_and_pre_process("$TMP_$dd$FILE"); 861 } 862 &add_preamble_head; 863 # Create a regular expressions 864 &set_depth_levels; 865 &make_sections_rx; 866 &make_order_sensitive_rx; 867 &add_document_info_page if ($INFO && !(/\\htmlinfo/)); 868 &add_bbl_and_idx_dummy_commands; 869 &translate; # Destructive! 870 } 871 &extract_external_references($FILE) ; 872 &style_sheet; 873 &close_dbm_database; 874 &cleanup(); 875 876#JCL: read warnings from file to $warnings 877 local($warnings) = &get_warnings; 878 print "\n\n*********** WARNINGS *********** \n$warnings" 879 if ($warnings || $NO_IMAGES || $IMAGES_ONLY); 880 &image_cache_message if ($NO_IMAGES || $IMAGES_ONLY); 881 &image_message if ($warnings =~ /Failed to convert/io); 882 undef $warnings; 883 884# JCL - generate directory index entry. 885# Yet, a hard link, cause Perl lacks symlink() on some systems. 886 do { 887 print "PCT: EXTN: $EXTN\n" if ($VERBOSITY > 5) ; 888 local($EXTN) = $EXTN; 889 $EXTN =~ s/_\w+(\.html?)/$1/ if ($frame_main_name); 890 print "PCT: EXTN: $EXTN\n" if ($VERBOSITY > 5) ; 891 local($from,$to) = (eval($LINKPOINT),eval($LINKNAME)); 892 print "PCT: from: $from / to: $to\n" if ($VERBOSITY > 5) ; 893 if (length($from) && length($to) && ($from ne $to)) { 894 #frames may have altered $EXTN 895 $from =~ s/$frame_main_name(\.html?)/$1/ if ($frame_main_name); 896 $to =~ s/$frame_main_name(\.html?)/$1/ if ($frame_main_name); 897 print "PCT: from: $from / to: $to\n" if ($VERBOSITY > 5) ; 898 L2hos->Unlink($to); 899 L2hos->Link($from,$to); 900 } 901 } unless ($NO_AUTO_LINK || !($LINKPOINT) || !($LINKNAME)); 902 903 &html_validate if ($HTML_VALIDATE && $HTML_VALIDATOR); 904 905# Go back to the source directory 906 chdir($orig_cwd); 907 $TEST_MODE = $DESTDIR if($TEST_MODE); # save path 908 $DESTDIR = ''; 909 $OUT_NODE = 0 unless $FIXEDDIR; 910 $STYLESHEET = '' if ($STYLESHEET =~ /^\Q$FILE./); 911 } 912 print "\nUnknown commands: ". join(" ",keys %unknown_commands) 913 if %unknown_commands; 914###MEH -- math support 915 print "\nMath commands outside math: " . 916 join(" ",keys %commands_outside_math) . 917 "\n Output may look weird or may be faulty!\n" 918 if %commands_outside_math; 919 print "\nDone.\n"; 920 if($TEST_MODE) { 921 $TEST_MODE =~ s:[$dd$dd]+$::; 922 print "\nTo view the results, point your browser at:\n", 923 L2hos->path2URL(L2hos->Make_directory_absolute($TEST_MODE).$dd. 924 "index$EXTN"),"\n"; 925 } 926 $end_time = time; 927 $total_time = $end_time - $start_time; 928 print STDOUT join(' ',"Timing:",$total_time,"seconds\n") 929 if ($TIMING||$DEBUG||($VERBOSITY > 2)); 930 $_; 931} 932 933sub open_dbm_database { 934 # These are DBM (unix DataBase Management) arrays which are actually 935 # stored in external files. They are used for communication between 936 # the main process and forked child processes; 937 print STDOUT "\n"; # this mysteriously prevents a core dump ! 938 939 dbmopen(%verb, "$TMP_${dd}verb",0755); 940# dbmopen(%verbatim, "$TMP_${dd}verbatim",0755); 941 dbmopen(%verb_delim, "$TMP_${dd}verb_delim",0755); 942 dbmopen(%expanded,"$TMP_${dd}expanded",0755); 943# Holds max_id, verb_counter, verbatim_counter, eqn_number 944 dbmopen(%global, "$TMP_${dd}global",0755); 945# Hold style sheet information 946 dbmopen(%env_style, "$TMP_${dd}envstyles",0755); 947 dbmopen(%txt_style, "$TMP_${dd}txtstyles",0755); 948 dbmopen(%styleID, "$TMP_${dd}styleIDs",0755); 949 950# These next two are used during off-line image conversion 951# %new_id_map maps image id's to page_numbers of the images in images.tex 952# %image_params maps image_ids to conversion parameters for that image 953 dbmopen(%new_id_map, "$TMP_${dd}ID_MAP",0755); 954 dbmopen(%img_params, "$TMP_${dd}IMG_PARAMS",0755); 955 dbmopen(%orig_name_map, "$TMP_${dd}ORIG_MAP",0755); 956 957 $global{'max_id'} = ($global{'max_id'} | 0); 958 &read_mydb(\%verbatim, "verbatim"); 959 $global{'verb_counter'} = ($global{'verb_counter'} | 0); 960 $global{'verbatim_counter'} = ($global{'verbatim_counter'} | 0); 961 962 &read_mydb(\%new_command, "new_command"); 963 &read_mydb(\%renew_command, "renew_command"); 964 &read_mydb(\%provide_command, "provide_command"); 965 &read_mydb(\%new_theorem, "new_theorem"); 966 &read_mydb(\%new_environment, "new_environment"); 967 &read_mydb(\%dependent, "dependent"); 968# &read_mydb(\%env_style, "env_style"); 969# &read_mydb(\%styleID, "styleID"); 970 # MRO: Why should we use read_mydb instead of catfile? 971 $preamble = &catfile(&_dbname("preamble"),1) || ''; 972 $prelatex = &catfile(&_dbname("prelatex"),1) || ''; 973 $aux_preamble = &catfile(&_dbname("aux_preamble"),1) || ''; 974 &restore_critical_variables; 975} 976 977sub close_dbm_database { 978 &save_critical_variables; 979 dbmclose(%verb); undef %verb; 980# dbmclose(%verbatim); undef %verbatim; 981 dbmclose(%verb_delim); undef %verb_delim; 982 dbmclose(%expanded); undef %expanded; 983 dbmclose(%global); undef %global; 984 dbmclose(%env_style); undef %env_style; 985 dbmclose(%style_id); undef %style_id; 986 dbmclose(%new_id_map); undef %new_id_map; 987 dbmclose(%img_params); undef %img_params; 988 dbmclose(%orig_name_map); undef %orig_name_map; 989 dbmclose(%txt_style); undef %txt_style; 990 dbmclose(%styleID); undef %styleID; 991} 992 993sub clear_images_dbm_database { 994 # <Added calls to dbmclose dprhws> 995 # %new_id_map will be used by the off-line image conversion process 996 # 997 dbmclose(%new_id_map); 998 dbmclose(%img_params); 999 dbmclose(%orig_name_map); 1000 undef %new_id_map; 1001 undef %img_params; 1002 undef %orig_name_map; 1003 dbmopen(%new_id_map, "$TMP_${dd}ID_MAP",0755); 1004 dbmopen(%img_params, "$TMP_${dd}IMG_PARAMS",0755); 1005 dbmopen(%orig_name_map, "$TMP_${dd}ORIG_MAP",0755); 1006} 1007 1008sub initialise_sections { 1009 local($key); 1010 foreach $key (keys %numbered_section) { 1011 $global{$key} = $numbered_section{$key}} 1012} 1013 1014sub save_critical_variables { 1015 $global{'math_markup'} = $NO_MATH_MARKUP; 1016 $global{'charset'} = $CHARSET; 1017 $global{'charenc'} = $charset; 1018 $global{'language'} = $default_language; 1019 $global{'isolatin'} = $ISOLATIN_CHARS; 1020 $global{'unicode'} = $UNICODE_CHARS; 1021 if ($UNFINISHED_ENV) { 1022 $global{'unfinished_env'} = $UNFINISHED_ENV; 1023 $global{'replace_end_env'} = $REPLACE_END_ENV; 1024 } 1025 $global{'unfinished_comment'} = $UNFINISHED_COMMENT; 1026 if (@UNMATCHED_OPENING) { 1027 $global{'unmatched'} = join(',',@UNMATCHED_OPENING); 1028 } 1029} 1030 1031sub restore_critical_variables { 1032 $NO_MATH_MARKUP = ($global{'math_markup'}| 1033 (defined $NO_MATH_MARKUP ? $NO_MATH_MARKUP:1)); 1034 $CHARSET = ($global{'charset'}| $CHARSET); 1035 $charset = ($global{'charenc'}| $charset); 1036 $default_language = ($global{'language'}| 1037 (defined $default_language ? $default_language:'english')); 1038 $ISOLATIN_CHARS = ($global{'isolatin'}| 1039 (defined $ISOLATIN_CHARS ? $ISOLATIN_CHARS:0)); 1040 $UNICODE_CHARS = ($global{'unicode'}| 1041 (defined $UNICODE_CHARS ? $UNICODE_CHARS:0)); 1042 if ($global{'unfinished_env'}) { 1043 $UNFINISHED_ENV = $global{'unfinished_env'}; 1044 $REPLACE_END_ENV = $global{'replace_end_env'}; 1045 } 1046 $UNFINISHED_COMMENT = $global{'unfinished_comment'}; 1047 if ($global{'unmatched'}) { 1048 @UNMATCHED_OPENING = split(',',$global{'unmatched'}); 1049 } 1050 1051 # undef any renewed-commands... 1052 # so the new defs are read from %new_command 1053 local($cmd,$key,$code); 1054 foreach $key (keys %renew_command) { 1055 $cmd = "do_cmd_$key"; 1056 $code = "undef \&$cmd"; eval($code) if (defined &$cmd); 1057 if ($@) { print "\nundef \&do_cmd_$cmd failed"} 1058 } 1059} 1060 1061#JCL: The warnings should have been handled within the DBM database. 1062# Unfortunately if the contents of an array are more than ~900 (system 1063# dependent) chars long then dbm cannot handle it and gives error messages. 1064sub write_warnings { #clean 1065 my ($str) = @_; 1066 $str .= "\n" unless($str =~ /\n$/); 1067 print STDOUT "\n *** Warning: $str\n" if ($VERBOSITY > 1); 1068 my $warnings = ''; 1069 if(-f 'WARNINGS') { 1070 $warnings = &catfile('WARNINGS') || ''; 1071 } 1072 return () if ($warnings =~ /\Q$str\E/); 1073 if(open(OUT,">>WARNINGS")) { 1074 print OUT $str; 1075 close OUT; 1076 } else { 1077 print "\nError: Cannot append to 'WARNINGS': $!\n"; 1078 } 1079} 1080 1081sub get_warnings { 1082 return &catfile('WARNINGS',1) || ''; 1083} 1084 1085sub analyze_bacronyms { 1086 local($_) = @_ ; 1087 print "PCT: analyze_bacronyms: $_\n" if ($VERBOSITY > 12) ; 1088 # 1089 # 1090 my $bcontents = &translate_environments($_) ; 1091 print "PCT: analyze_bacronyms: content: $bcontents\n" if ($VERBOSITY > 15) ; 1092 my @keys = sort { $a cmp $b } keys %bacronyms; 1093 foreach $bkey ( @keys ) { 1094 print STDOUT "Key = $bkey - Value = " . $bacronyms{$bkey}{'value'} . "\n" if ($VERBOSITY > 10) ; 1095 } 1096} 1097 1098# MRO: Standardizing 1099sub catfile { 1100 my ($file,$ignore) = @_; 1101 unless(open(CATFILE,"<$file")) { 1102 print "\nError: Cannot read '$file': $!\n" 1103 unless($ignore); 1104 return undef; 1105 } 1106 local($/) = undef; # slurp in whole file 1107 my $contents = <CATFILE>; 1108 close(CATFILE); 1109 # 1110 # This is a hack... a bad one to locate bacronyms earlier 1111 if ($contents =~ /bacronyms\.tex/) { 1112 my $bcontents = $contents ; 1113 &analyze_bacronyms($bcontents) ; 1114 } 1115 $contents; 1116} 1117 1118 1119sub html_validate { 1120 my ($extn) = $EXTN; 1121 if ($EXTN !~ /^\.html?$/i) { 1122 $extn =~ s/^[^\.]*(\.html?)$/$1/; 1123 } 1124 print "\n *** Validating ***\n"; 1125 my @htmls = glob("*$extn"); 1126 my $file; 1127 foreach $file (@htmls) { 1128 system("$HTML_VALIDATOR $file"); 1129 } 1130} 1131 1132sub lost_argument { 1133 local($cmd) = @_; 1134 &write_warnings("\nincomplete argument to command: \\$cmd"); 1135} 1136 1137 1138# These subroutines should have been handled within the DBM database. 1139# Unfortunately if the contents of an array are more than ~900 (system 1140# dependent) chars long then dbm cannot handle it and gives error messages. 1141# So here we save and then read the contents explicitly. 1142sub write_mydb { 1143 my ($db, $key, $str) = @_; 1144 &write_mydb_simple($db, "\n$mydb_mark#$key#$str"); 1145} 1146 1147# generate the DB file name from the DB name 1148sub _dbname { 1149 "$TMP_$dd$_[0]"; 1150} 1151 1152sub write_mydb_simple { 1153 my ($db, $str) = @_; 1154 my $file = &_dbname($db); 1155 if(open(DB,">>$file")) { 1156 print DB $str; 1157 close DB; 1158 } else { 1159 print "\nError: Cannot append to '$file': $!\n"; 1160 } 1161} 1162 1163sub clear_mydb { 1164 my ($db) = @_; 1165 my $file = &_dbname($db); 1166 if(open(DB,">$file")) { 1167 close DB; 1168 } else { 1169 print "\nError: Cannot clear '$file': $!\n"; 1170 } 1171} 1172 1173# Assumes the existence of a DB file which contains 1174# sequences of e.g. verbatim counters and verbatim contents. 1175sub read_mydb { 1176 my ($dbref,$name) = @_; 1177 my $contents = &catfile(&_dbname($name),1); 1178 return '' unless(defined $contents); 1179 my @tmp = split(/\n$mydb_mark#([^#]*)#/, $contents); 1180 my $i = 1; # Ignore the first element at 0 1181 print "\nDBM: $name open..." if ($VERBOSITY > 2); 1182 while ($i < scalar(@tmp)) { 1183 my $tmp1 = $tmp[$i]; 1184 my $tmp2 = $tmp[++$i]; 1185 $$dbref{$tmp1} = defined $tmp2 ? $tmp2 : ''; 1186 ++$i; 1187 }; 1188 $contents; 1189} 1190 1191 1192# Reads in a latex generated file (e.g. .bbl or .aux) 1193# It returns success or failure 1194# ****** and binds $_ in the caller as a side-effect ****** 1195sub process_ext_file { 1196 local($ext) = @_; 1197 local($found, $extfile,$dum,$texpath); 1198 $extfile = $EXTERNAL_FILE||$FILE; 1199 local($file) = &fulltexpath("$extfile.$ext"); 1200 $found = 0; 1201 &write_warnings( 1202 "\n$extfile.$EXT is newer than $extfile.$ext: Please rerun latex" . ## AYS 1203 (($ext =~ /bbl/) ? " and bibtex.\n" : ".\n")) 1204 if ( ($found = (-f $file)) && 1205 &newer(&fulltexpath("$extfile.$EXT"), $file)); ## AYS 1206 if ((!$found)&&($extfile =~ /\.$EXT$/)) { 1207 $file = &fulltexpath("$extfile"); 1208 &write_warnings( 1209 "\n$extfile is newer than $extfile: Please rerun latex" . ## AYS 1210 (($ext =~ /bbl/) ? " and bibtex.\n" : ".\n")) 1211 if ( ($found = (-f $file)) && 1212 &newer(&fulltexpath("$extfile"), $file)); ## AYS 1213 } 1214 1215 # check in other directories on the $TEXINPUTS paths 1216 if (!$found) { 1217 foreach $texpath (split /$envkey/, $TEXINPUTS ) { 1218 $file = "$texpath$dd$extfile.$ext"; 1219 last if ($found = (-f $file)); 1220 } 1221 } 1222 if ( $found ) { 1223 print "\nReading $ext file: $file ..."; 1224 # must allow @ within control-sequence names 1225 $dum = &do_cmd_makeatletter(); 1226 &slurp_input($file); 1227 if ($ext =~ /bbl/) { 1228 # remove the \newcommand{\etalchar}{...} since not needed 1229 s/^\\newcommand\{\\etalchar\}[^\n\r]*[\n\r]+//s; 1230 } 1231 &pre_process; 1232 &substitute_meta_cmds if (%new_command || %new_environment); 1233 if ($ext eq "aux") { 1234 my $latex_pathname = L2hos->path2latex($file); 1235 $aux_preamble .= 1236 "\\AtBeginDocument{\\makeatletter\n\\input $latex_pathname\n\\makeatother\n}\n"; 1237 local(@extlines) = split ("\n", $_); 1238 print " translating ".(0+@extlines). " lines " if ($VERBOSITY >1); 1239 local($eline,$skip_to); #$_ = ''; 1240 foreach $eline (@extlines) { 1241 if ($skip_to) { next unless ($eline =~ s/$O$skip_to$C//) } 1242 $skip_to = ''; 1243 # skip lines added for pdfTeX/hyperref compatibility 1244 next if ($eline =~ /^\\(ifx|else|fi|global \\let|gdef|AtEndDocument|let )/); 1245 # remove \index and \label commands, else invalid links may result 1246 $eline =~ s/\\(index|label)\s*($O\d+$C).*\2//g; 1247 if ($eline =~ /\\(old)?contentsline/) { 1248 do { local($_,$save_AUX) = ($eline,$AUX_FILE); 1249 $AUX_FILE = 0; 1250 &wrap_shorthand_environments; 1251 #footnote markers upset the numbering 1252 s/\\footnote(mark|text)?//g; 1253 $eline = &translate_environments($_); 1254 $AUX_FILE = $save_AUX; 1255 undef $_ }; 1256 } elsif ($eline =~ s/^\\\@input//) { 1257 &do_cmd__at_input($eline); 1258 $eline = ''; 1259 } elsif ($eline =~ s/^\\\@setckpt$O(\d+)$C//) { 1260 $skip_to = $1; next; 1261 } 1262# $eline =~ s/$image_mark#([^#]+)#/print "\nIMAGE:",$img_params{$1},"\n";''/e; 1263# $_ .= &translate_commands(&translate_environments($eline)); 1264 $_ .= &translate_commands($eline) if $eline; 1265 } 1266 undef @extlines; 1267 } elsif ($ext =~ /$caption_suffixes/) { 1268 local(@extlines) = split ("\n", $_); 1269 print " translating ".(0+@extlines). " lines "if ($VERBOSITY >1); 1270 local($eline); $_ = ''; 1271 foreach $eline (@extlines) { 1272 # remove \index and \label commands, else invalid links may result 1273 $eline =~ s/\\(index|label)\s*($O\d+$C).*\2//gso; 1274 if ($eline =~ /\\(old)?contentsline/) { 1275 do { local($_,$save_PREAMBLE) = ($eline,$PREAMBLE); 1276 $PREAMBLE = 0; 1277 &wrap_shorthand_environments; 1278 $eline = &translate_environments($_); 1279 $PREAMBLE = $save_PREAMBLE; 1280 undef $_ }; 1281 } 1282 $_ .= &translate_commands($eline); 1283 } 1284 undef @extlines; 1285 } else { 1286 print " wrapping " if ($VERBOSITY >1); 1287 &wrap_shorthand_environments; 1288 $_ = &translate_commands(&translate_environments($_)); 1289 print " translating " if ($VERBOSITY >1); 1290 } 1291 print "\n processed size: ".length($_)."\n" if($VERBOSITY>1); 1292 $dum = &do_cmd_makeatother(); 1293 } else { 1294 print "\n*** Could not find file: $file ***\n" if ($DEBUG) 1295 }; 1296 $found; 1297} 1298 1299sub deal_with_texinputs { 1300# The dot precedes all, this let's local files override always. 1301# The dirs we want are given as parameter list. 1302 if(!$TEXINPUTS) { $TEXINPUTS = '.' } 1303 elsif ($TEXINPUTS =~ /^$envkey/) { 1304 $TEXINPUTS = '.'.$TEXINPUTS 1305 }; 1306 if ($ROOTED) {$TEXINPUTS .= "$envkey$FIXEDDIR"} 1307 $TEXINPUTS = &absolutize_path($TEXINPUTS); 1308 $ENV{'TEXINPUTS'} = join($envkey,".",@_,$TEXINPUTS,$ENV{'TEXINPUTS'}); 1309 $TEXINPUTS = $ENV{'TEXINPUTS'} ; 1310 print "deal_with_texinputs: " . $ENV{'TEXINPUTS'} . "\n" ; 1311} 1312 1313# provided by Fred Drake 1314sub absolutize_path { 1315 my ($path) = @_; 1316 my $npath = ''; 1317 foreach $dir (split /$envkey/o, $path) { 1318 $npath .= L2hos->Make_directory_absolute($dir) . $envkey; 1319 } 1320 $npath =~ s/$envkey$//; 1321 $npath; 1322} 1323 1324sub add_document_info_page { 1325 # Uses $outermost_level 1326 # Nasty race conditions if the next two are done in parallel 1327 local($X) = ++$global{'max_id'}; 1328 local($Y) = ++$global{'max_id'}; 1329 ###MEH -- changed for math support: no underscores in commandnames 1330 $_ = join('', $_ 1331 , (($MAX_SPLIT_DEPTH <= $section_commands{$outermost_level})? 1332 "\n<HR>\n" : '') 1333 , "\\$outermost_level", "*" 1334 , "$O$X$C$O$Y$C\\infopagename$O$Y$C$O$X$C\n", 1335 , " \\textohtmlinfopage"); 1336} 1337 1338 1339# For each style file name in TMP_styles (generated by texexpand) look for a 1340# perl file in $LATEX2HTMLDIR/styles and load it. 1341sub load_style_file_translations { 1342 local($_, $style, $options, $dir); 1343 print "\n"; 1344 if ($TEXDEFS) { 1345 foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) { 1346 if (-f ($_ = "$dir${dd}texdefs.perl")) { 1347 print "\nLoading $_..."; 1348 require ($_); 1349 $styles_loaded{'texdefs'} = 1; 1350 last; 1351 } 1352 } 1353 } 1354 1355 # packages automatically implemented 1356 local($auto_styles) = $AUTO_STYLES; 1357 $auto_styles .= 'array|' if ($HTML_VERSION > 3.1); 1358 $auto_styles .= 'tabularx|' if ($HTML_VERSION > 3.1); 1359 $auto_styles .= 'theorem|'; 1360 1361 # these are not packages, but can appear as if class-options 1362 $auto_styles .= 'psamsfonts|'; 1363 $auto_styles .= 'noamsfonts|'; 1364 1365 $auto_styles =~ s/\|$//; 1366 1367 if(open(STYLES, "<$TMP_${dd}styles")) { 1368 while(<STYLES>) { 1369 if(s/^\s*(\S+)\s*(.*)$/$style = $1; $options = $2;/eo) { 1370 &do_require_package($style); 1371 $_ = $DONT_INCLUDE; 1372 s/:/|/g; 1373 &write_warnings(join('',"No implementation found for style ",$style,"\n")) 1374 unless ($styles_loaded{$style} || $style =~ /^($_)$/ 1375 || $style =~ /$auto_styles/); 1376 1377 # MRO: Process options for packages 1378 &do_package_options($style,$options) if($options); 1379 } 1380 } 1381 close(STYLES); 1382 } else { 1383 print "\nError: Cannot read '$TMP_${dd}styles': $!\n"; 1384 } 1385} 1386 1387################## Weird Special case ################## 1388 1389# The new texexpand can be told to leave in \input and \include 1390# commands which contain code that the translator should simply pass 1391# to latex, such as the psfig stuff. These should still be seen by 1392# TeX, so we add them to the preamble ... 1393 1394sub do_include_lines { 1395 while (s/$include_line_rx//o) { 1396 local($include_line) = &revert_to_raw_tex($&); 1397 &add_to_preamble ('include', $include_line); 1398 } 1399} 1400 1401########################## Preprocessing ############################ 1402 1403# JCL(jcl-verb) 1404# The \verb declaration and the verbatim environment contain simulated 1405# typed text and should not be processed. Characters such as $,\,{,and } 1406# loose their special meanings and should not be considered when marking 1407# brackets etc. To achieve this \verb declarations and the contents of 1408# verbatim environments are replaced by markers. At the end the original 1409# text is put back into the document. 1410# The markers for verb and verbatim are different so that these commands 1411# can be restored to what the raw input was just in case they need to 1412# be passed to latex. 1413 1414sub pre_process { 1415 # Modifies $_; 1416 #JKR: We need support for some special environments. 1417 # This has to be here, because they might contain 1418 # structuring commands like \section etc. 1419 local(%comments); 1420 print "PCT: pre_process: before: $_ \n" if ($VERBOSITY > 5) ; 1421 &pre_pre_process if (defined &pre_pre_process); 1422 print "PCT: pre_process: after: $_ \n" if ($VERBOSITY > 5) ; 1423 s/\\\\/\\\\ /go; # Makes it unnecessary to look for escaped cmds 1424 &replace_html_special_chars; 1425 # Remove fake environment which should be invisible to LaTeX2HTML. 1426 s/\001//m; 1427 s/[%]end\s*{latexonly}/\001/gom; 1428 s/[%]begin\s*{latexonly}([^\001]*)\001/%/gos; 1429 s/\001//m; 1430 1431 &preprocess_alltt if defined(&preprocess_alltt); 1432 1433 $KEEP_FILE_MARKERS = 1; 1434 if ($KEEP_FILE_MARKERS) { 1435# if (s/%%% TEXEXPAND: \w+ FILE( MARKER)? (\S*).*/ 1436# '<tex2html_'.($1?'':'end').'file>'.qq|#$2#|."\n"/em) { 1437# $_ = "<tex2html_file>#$2#\n". $_ }; 1438 #RRM: ignore \n at end of included file, else \par may result 1439 if (s/(\n{1,2})?%%% TEXEXPAND: \w+ FILE( MARKER)? (\S*).*\n?/ 1440 ($2?$1:"\n").'<tex2html_'.($2?'':'end').'file>'.qq|#$3#|."\n"/em) { 1441 $_ = "<tex2html_file>#$3#\n". $_ }; 1442 } else { 1443 s/%%% TEXEXPAND[^\n]*\n//gm; 1444 } 1445 1446 # Move all LaTeX comments into a local list 1447 s/([ \t]*(^|\G|[^\\]))(%.*(\n[ \t]*|$))/print "%"; 1448 $comments{++$global{'verbatim_counter'}} = "$3"; 1449 &write_mydb("verbatim", $global{'verbatim_counter'}, $3); 1450 "$1$comment_mark".$global{'verbatim_counter'}."\n"/mge; 1451 # Remove the htmlonly-environment 1452 s/\\begin\s*{htmlonly}\s*\n?//gom; 1453 s/\\end\s*{htmlonly}\s*\n?//gom; 1454 # Remove enviroments which should be invisible to LaTeX2HTML. 1455 s/\n[^%\n]*\\end\s*\{latexonly\}\s*\n?/\001/gom; 1456 s/((^|\n)[^%\n]*)\\begin\s*\{latexonly\}([^\001]*)\001/$1/gom; 1457 s/\\end\s*\{comment\}\s*\n?/\001/gom; 1458 s/\\begin\s*\{comment\}([^\001]*)\001//gom; 1459 1460 # this used to be earlier, but that can create problems with comments 1461 &wrap_other_environments if (%other_environments); 1462 1463# s/\\\\/\\\\ /go; # Makes it unnecessary to look for escaped cmds 1464 local($next, $esc_del); 1465 &normalize_language_changes; 1466 # Patches by #JKR, #EI#, #JCL(jcl-verb) 1467 1468 #protect \verb|\begin/end....| parts, for LaTeX documentation 1469 s/(\\verb\*?(.))\\(begin|end)/$1\003$3/g; 1470 1471 local(@processedV); 1472 local($opt, $style_info,$before, $contents, $after, $env); 1473 while (($UNFINISHED_COMMENT)|| 1474 (/\\begin\s*($opt_arg_rx)?\s*\{($verbatim_env_rx|$keepcomments_rx)\}/o)) { 1475 ($opt, $style_info) = ($1,$2); 1476 $before=$contents=$after=$env=''; 1477 if ($UNFINISHED_COMMENT) { 1478 $UNFINISHED_COMMENT =~ s/([^:]*)::(\d+)/$env=$1;$after=$_; 1479 $before = join("",$unfinished_mark,$env,$2,"#");''/e; 1480 print "\nfound the lost \\end{$env}\n"; 1481 } 1482 #RRM: can we avoid copying long strings here ? 1483 # maybe this loop can be an s/.../../s with (.*?) 1484 # 1485 ($before, $after, $env) = ($`, $', $3) unless ($env); 1486 if (!($before =~ 1487 /\\begin(\s*\[[^\]]*\]\s*)?\{($verbatim_env_rx|$keepcomments_rx)\}/)) { 1488 push(@processedV,$before); 1489 print "'";$before = ''; 1490 } 1491 if ($after =~ /\s*\\end\{$env[*]?\}/) { # Must NOT use the s///o option!!! 1492 ($contents, $after) = ($`, $'); 1493 $contents =~ s/^\n+/\n/s; 1494# $contents =~ s/\n+$//s; 1495 1496 # re-insert comments 1497 $contents =~ s/$comment_mark(\d+)\n?/$comments{$1}/g; 1498# $contents =~ s/$comment_mark(\d+)/$verbatim{$1}/g; 1499 1500 # revert '\\ ' -> '\\' only once 1501 if ($env =~ /rawhtml|$keepcomments_rx/i) { 1502 $contents = &revert_to_raw_tex($contents); 1503 } else { 1504 $contents =~ s/([^\\](?:\\\\)*\\)([$html_escape_chars])/$1.&special($2)/geos; 1505 $contents =~ s/\\\\ /\\\\/go; 1506 } 1507 1508 if ($env =~/$keepcomments_rx/) { 1509 $verbatim{++$global{'verbatim_counter'}} = "$contents"; 1510 } else { 1511 &write_mydb("verbatim", ++$global{'verbatim_counter'}, $contents); 1512 } 1513# $verbatim{$global{'verbatim_counter'}} = "$contents" if ($env =~/$keepcomments_rx/); 1514# $verbatim{$global{'verbatim_counter'}} = "$contents"; 1515 1516 if ($env =~ /rawhtml|$keepcomments_rx/i) { 1517 if ($before) { 1518 $after = join("",$verbatim_mark,$env 1519 ,$global{'verbatim_counter'},"#",$after); 1520 } else { 1521 push (@processedV, join("",$verbatim_mark,$env 1522 ,$global{'verbatim_counter'},"#")); 1523 } 1524 } elsif ($env =~ /tex2html_code/) { 1525 if ($before) { 1526 $after = join("","\\begin", $opt, "\{verbatim_code\}" 1527 , $verbatim_mark,$env 1528 , $global{'verbatim_counter'},"#" 1529 , "\\end\{verbatim_code\}",$after); 1530 } else { 1531 push (@processedV 1532 , join("","\\begin", $opt, "\{verbatim_code\}" 1533 , $verbatim_mark,$env 1534 , $global{'verbatim_counter'},"#" 1535 , "\\end\{verbatim_code\}")); 1536 } 1537 } else { 1538 if ($before) { 1539 $after = join("","\\begin", $opt, "\{tex2html_preform\}" 1540 , $verbatim_mark,$env 1541 , $global{'verbatim_counter'},"#" 1542 , "\\end\{tex2html_preform\}",$after); 1543 } else { 1544 push (@processedV 1545 , join("","\\begin", $opt, "\{tex2html_preform\}" 1546 , $verbatim_mark,$env 1547 , $global{'verbatim_counter'},"#" 1548 , "\\end\{tex2html_preform\}" )); 1549 } 1550 } 1551 } else { 1552 print "Cannot find \\end{$env}\n"; 1553 $after =~ s/$comment_mark(\d+)\n?/$comments{$1}/g; 1554# $after =~ s/$comment_mark(\d+)/$verbatim{$1}/g; 1555 if ($env =~ /rawhtml|$keepcomments_rx/i) { 1556 $after = &revert_to_raw_tex($contents); 1557 } else { 1558 $after =~ s/([^\\](?:\\\\)*\\)([$html_escape_chars])/$1.&special($2)/geos; 1559 $after =~ s/\\\\ /\\\\/go; 1560 } 1561 if ($env =~/$keepcomments_rx/) { 1562 $verbatim{++$global{'verbatim_counter'}} = "$after"; 1563 } else { 1564 &write_mydb("verbatim", ++$global{'verbatim_counter'}, $after ); 1565 } 1566 $after = join("",$unfinished_mark,$env 1567 ,$global{'verbatim_counter'},"#"); 1568 } 1569 $_ = join("",$before,$after); 1570 } 1571 print STDOUT "\nsensitive environments found: ".(int(0+@processedV/2))." " 1572 if((@processedV)&&($VERBOSITY > 1)); 1573 $_ = join('',@processedV, $_); undef @processedV; 1574 1575 #restore \verb|\begin/end....| parts, for LaTeX documentation 1576# $_ =~ s/(\\verb\W*?)\003(begin|end)/$1\\$2/g; 1577 $_ =~ s/(\\verb(;SPM\w+;|\W*?))\003(begin|end)/$1\\$3/g; 1578 1579 # Now do the \verb declarations 1580 # Patches by: #JKR, #EI#, #JCL(jcl-verb) 1581 # Tag \verb command and legal opening delimiter with unique number. 1582 # Replace tagged ones and its contents with $verb_mark & id number if the 1583 # closing delimiter can be found. After no more \verb's are to tag, revert 1584 # tagged one's to the original pattern. 1585 local($del,$contents,$verb_rerun); 1586 local($id) = $global{'verb_counter'}; 1587 # must tag only one alternation per loop 1588 ##RRM: can this be speeded up using a list ?? 1589 my $vbmark = $verb_mark; 1590 while (s/\\verb(\t*\*\t*)(\S)/"<verb$1".++$id.">$2"/e || 1591 s/\\verb()(\;SPM\w+\;|[^a-zA-Z*\s])/"<verb$1".++$id.">$2"/e || 1592 s/\\verb(\t\t*)([^*\s])/"<verb$1".++$id.">$2"/e) { 1593 1594 $del = $2; 1595 #RRM: retain knowledge of whether \verb* or \verb 1596 $vb_mark = ($1 =~/^\s*\*/? $verbstar_mark : $verb_mark); 1597 $esc_del = &escape_rx_chars($del); 1598 $esc_del = '' if (length($del) > 2); 1599 1600 # try to find closing delimiter and substitute the complete 1601 # statement with $verb_mark or $verbstar_mark 1602# s/(<verb[^\d>]*$id>[\Q$del\E])([^$esc_del\n]*)([\Q$del\E]|$comment_mark(\d+)\n?)/ 1603 s/(<verb[^\d>]*$id>\Q$del\E)([^$esc_del\n]*?)(\Q$del\E|$comment_mark(\d+)\n?)/ 1604 $contents=$2; 1605 if ($4) { $verb_rerun = 1; 1606 join('', "\\verb$del", $contents, $comments{$4}) 1607 } else { 1608 $contents =~ s|\\\\ |\\\\|g; 1609 $contents =~ s|\n| |g; 1610 $verb{$id}=$contents; 1611 $verb_delim{$id}=$del; 1612 join('',$vb_mark,$id,$verb_mark) 1613 } 1614 /e; 1615 } 1616 $global{'verb_counter'} = $id; 1617 # revert changes to fake verb statements 1618 s/<verb([^\d>]*)\d+>/\\verb$1/g; 1619 1620 #JKR: the comments include the linebreak and the following whitespace 1621# s/([^\\]|^)(%.*\n[ \t]*)+/$1/gom; # Remove Comments but not % which may be meaningful 1622 s/((^|\n)$comment_mark(\d+))+//gom; # Remove comment markers on new lines, but *not* the trailing \n 1623 s/(\\\w+|(\W?))($comment_mark\d*\n?)/($2)? $2.$3:($1? $1.' ':'')/egm; # Remove comment markers, not after braces 1624# s/(\W?)($comment_mark\d*\n?)/($1)? $1.$2:''/egm; # Remove comment markers, not after braces 1625 # Remove comment markers, but *not* the trailing \n 1626# HWS: Correctly remove multiple %%'s. 1627# 1628 s/\\%/\002/gm; 1629# s/(%.*\n[ \t]*)//gm; 1630 s/(%[^\n]*\n)[ \t]*/$comment_mark\n/gm; 1631 1632 s/\002/\\%/gm; 1633 1634 local($tmp1,$tmp2); 1635 s/^$unfinished_mark$keepcomments_rx(\d+)#\n?$verbatim_mark$keepcomments_rx(\d+)#/ 1636 $verbatim{$4}."\n\\end{$1}"/egm; # Raw TeX 1637 s/$verbatim_mark$keepcomments_rx(\d+)#/ 1638 $tmp1 = $1; 1639 $tmp2 = &protect_after_comments($verbatim{$2}); 1640 $tmp2 =~ s!\n$!!s; 1641 join ('', "\\begin{$tmp1}" 1642 , $tmp2 1643 , "\n\\end{$tmp1}" 1644 )/egm; # Raw TeX 1645 s/$unfinished_mark$keepcomments_rx(\d+)#/$UNFINISHED_COMMENT="$1::$2"; 1646 "\\begin{$1}\n".$verbatim{$2}/egm; # Raw TeX 1647 1648 $KEEP_FILE_MARKERS = 1; 1649 if ($KEEP_FILE_MARKERS) { 1650 s/%%% TEXEXPAND: \w+ FILE( MARKER) (\S*).*\n/ 1651 '<tex2html_'.($1?'':'end').'file>'.qq|#.$2#\n|/gem; 1652 } else { 1653 s/%%% TEXEXPAND[^\n]*\n//gm; 1654 } 1655 1656 &mark_string($_); 1657 1658 1659 # attempt to remove the \html \latex and \latexhtml commands 1660 s/\\latex\s*($O\d+$C)(.*)\1//gm; 1661 s/\\latexhtml\s*($O\d+$C)(.*)\1\s*($O\d+$C)(.*)\3/$4/sg; 1662 s/\\html\s*($O\d+$C)(.*)\1/$2/sg; 1663 s/\\html\s*($O\d+$C)//gm; 1664 1665# &make_unique($_); 1666} 1667 1668# RRM: When comments are retained, then ensure that they are benign 1669# by removing \s and escaping braces, 1670# so that environments/bracing cannot become unbalanced. 1671sub protect_after_comments { 1672 my ($verb_text) = @_; 1673# $verb_text =~ s/\%(.*)/'%'.&protect_helper($1)/eg; 1674 $verb_text =~ s/(^|[^\\])(\\\\)*\%(.*)/$1.$2.'%'.&protect_helper($3)/emg; 1675 $verb_text; 1676} 1677 1678sub protect_helper { 1679 my ($text) = @_; 1680 $text =~ s/\\/ /g; 1681 $text =~ s/(\{|\})/\\$1/g; 1682 $text; 1683} 1684 1685# 1686# Philippe Chauvat - 18-jan-2017 1687# This is the orginal version of make_comment 1688sub old_make_comment { 1689 local($type,$_) = @_; 1690 $_ =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg; 1691 $_ = &revert_to_raw_tex($_); s/^\n+//m; 1692 $_ =~ s/\\(index|label)\s*\{.*\}//sg; 1693 s/\-\-/- -/g; s/\-\-/- -/g; # cannot have -- inside a comment 1694 $_ = join('', '<!-- ', $type , "\n ", $_ , "\n -->" ); 1695 $verbatim{++$global{'verbatim_counter'}} = $_; 1696 &write_mydb('verbatim', $global{'verbatim_counter'}, $_ ); 1697 join('', $verbatim_mark, 'verbatim' , $global{'verbatim_counter'},'#') 1698} 1699# 1700# The changes made below are related to the way the content is handled 1701# Instead of making a comment, we define a <span></span> with class and id 1702# Making the right CSS (mainly: display: none or something else) will 1703# make the result just fine. 1704sub make_comment { 1705 local($type,$_) = @_; 1706 local ($bclassname,$bid) ; 1707 $_ =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg; 1708 $_ = &revert_to_raw_tex($_); s/^\n+//m; 1709 if ($type eq "MATH") { 1710 $_ =~ s/^\$// ; s/\$$// ; 1711 $_ =~ s/\\//g ; 1712 } 1713 $_ =~ s/\\(index|label)\s*\{.*\}//sg; 1714 $bclassname = "bhide_" . lc($type) ; 1715 $bid = "bhide_" . $global{'verbatim_counter'} . "_" . lc($type) ; 1716 $_ = join('', "\n",'<span class="',$bclassname,'" id="',$bid,'">', $_ , "</span>" ); 1717 $verbatim{++$global{'verbatim_counter'}} = $_; 1718 &write_mydb('verbatim', $global{'verbatim_counter'}, $_ ); 1719 join('', $verbatim_mark, 'verbatim' , $global{'verbatim_counter'},'#') 1720} 1721 1722sub wrap_other_environments { 1723 local($key, $env, $start, $end, $opt_env, $opt_start); 1724 foreach $key (keys %other_environments) { 1725 # skip bogus entries 1726 next unless ($env = $other_environments{$key}); 1727 $key =~ s/:/($start,$end)=($`,$');':'/e; 1728 1729 if (($end =~ /^\#$/m) && ($start =~ /^\#/m)) { 1730 # catch Indica pre-processor language switches 1731 $opt_start = $'; 1732 if ($env =~ s/\[(\w*)\]//o) { 1733 $opt_env = join('','[', ($1 ? $1 : $opt_start ), ']'); 1734 } 1735 local($next); 1736 while ($_ =~ /$start\b/) { 1737 push(@pre_wrapped, $`, "\\begin\{pre_$env\}", $opt_env ); 1738 $_=$'; 1739 if (/(\n*)$end/) { 1740 push(@pre_wrapped, $`.$1,"\\end\{pre_$env\}$1"); 1741 $_ = $'; 1742 if (!(s/^N(IL)?//o)) {$_ = '#'.$_ } 1743 } else { 1744 print "\n *** unclosed $start...$end chunk ***\n"; 1745 last; 1746 } 1747 } 1748 $_ = join('', @pre_wrapped, $_); 1749 undef @pre_wrapped; 1750 1751 } elsif (($end=~/^\n$/) && ($start =~ /^\#/)) { 1752 # catch ITRANS pre-processor language info; $env = 'nowrap'; 1753 local($ilang) = $start; $ilang =~ s/^\#//m; 1754 s/$start\s*\=([^<\n%]*)\s*($comment_mark\d*|\n|%)/\\begin\{tex2html_$env\}\\ITRANSinfo\{$ilang\}\{$1\}\n\\end\{tex2html_$env\}$2/g; 1755 1756 } elsif (!$end &&($start =~ /^\#/m)) { 1757 # catch Indica pre-processor input-mode switches 1758 s/$start(.*)\n/\\begin\{tex2html_$env\}$&\\end\{tex2html_$env\}\n/g; 1759 1760 } elsif (($start eq $end)&&(length($start) == 1)) { 1761 $start =~ s/(\W)/\\$1/; $end = $start; 1762 s/([^$end])$start([^$end]+)$end/$1\\begin\{pre_$env\}$2\\end\{pre_$env\}/mg; 1763 } elsif ($start eq $end) { 1764 if (!($start =~ /\#\#/)) { 1765 $start =~ s/(\W)/\\$1/g; $end = $start; } 1766 local (@pre_wrapped); 1767 local($opt); $opt = '[indian]' if ($start =~ /^\#\#$/m); 1768 while ($_ =~ /$start/s) { 1769 push(@pre_wrapped, $` , "\\begin\{pre_$env\}$opt"); 1770 $_=$'; 1771 if (/$end/s) { 1772 push(@pre_wrapped, $`, "\\end\{pre_$env\}"); 1773 $_ = $'; 1774 } else { 1775 print "\n *** unclosed $start...$end chunk ***\n"; 1776 last; 1777 } 1778 } 1779 $_ = join('', @pre_wrapped, $_); 1780 undef @pre_wrapped; 1781 } elsif ($start && ($env =~ /itrans/)) { 1782 # ITRANS is of this form 1783 local($indic); if($start =~ /\#(\w+)$/m) {$indic = $1} 1784 #include the language-name as an optional parameter 1785 s/$start\b/\\begin\{pre_$env\}\[$indic\]/sg; 1786 s/$end\b/\\end\{pre_$env\}/sg; 1787 } elsif (($start)&&($end)) { 1788 s/$start\b/\\begin\{pre_$env\}/sg; 1789 s/$end\b/\\end\{pre_$env\}/sg; 1790 } 1791 } 1792 $_; 1793} 1794 1795#################### Marking Matching Brackets ###################### 1796 1797# Reads the entire input file and performs pre_processing operations 1798# on it before returning it as a single string. The pre_processing is 1799# done on separate chunks of the input file by separate Unix processes 1800# as determined by LaTeX \input commands, in order to reduce the memory 1801# requirements of LaTeX2HTML. 1802sub slurp_input_and_partition_and_pre_process { 1803 local($file) = @_; 1804 local(%string, @files, $pos); 1805 local ($count) = 1; 1806 1807 unless(open(SINPUT,"<$file")) { 1808 die "\nError: Cannot read '$file': $!\n"; 1809 } 1810 local(@file_string); 1811 print STDOUT "$file" if ($VERBOSITY >1); 1812 while (<SINPUT>) { 1813 if (/TEXEXPAND: INCLUDED FILE MARKER (\S*)/) { 1814 # Forking seems to screw up the rest of the input stream 1815 # We save the current position ... 1816 $pos = tell SINPUT; 1817 print STDOUT " fork at offset $pos " if ($VERBOSITY >1); 1818 $string{'STRING'} = join('',@file_string); @file_string = (); 1819 &write_string_out($count); 1820 delete $string{'STRING'}; 1821 # ... so that we can return to it 1822 seek(SINPUT, $pos, 0); 1823 print STDOUT "\nDoing $1 "; 1824 ++$count} 1825 else { 1826# $string{'STRING'} .= $_ 1827 push(@file_string,$_); 1828 } 1829 } 1830 $string{'STRING'} = join('',@file_string); @file_string = (); 1831 &write_string_out($count); 1832 delete $string{'STRING'}; 1833 close SINPUT; 1834 @files = (); 1835 if(opendir(DIR, $TMP_)) { 1836 @files = sort grep(/^\Q$PARTITION_PREFIX\E\d+/, readdir(DIR)); 1837 closedir(DIR); 1838 } 1839 1840 unless(@files) { 1841 die "\nFailed to read in document parts.\n". 1842 "Look up section Globbing in the troubleshooting manual.\n"; 1843 } 1844 1845 $count = 0; 1846 foreach $file (@files) { 1847 print STDOUT "\nappending file: $TMP_$dd$file " if ($VERBOSITY > 1); 1848 $_ .= (&catfile("$TMP_$dd$file") || ''); 1849 print STDOUT "\ntotal length: ".length($_)." characters\n" if ($VERBOSITY > 1); 1850 } 1851 die "\nFailed to read in document parts (out of memory?).\n" 1852 unless length($_); 1853 print STDOUT "\ntotal length: ".length($_)." characters\n" if ($VERBOSITY > 1); 1854} 1855 1856sub write_string_out { 1857 local($count) = @_; 1858 if ($count < 10) {$count = '00'.$count} 1859 elsif ($count < 100) {$count = '0'.$count} 1860 local($pid); 1861 # All open unflushed streams are inherited by the child. If this is 1862 # not set then the parent will *not* wait 1863 $| = 1; 1864 # fork returns 0 to the child and PID to the parent 1865 &write_mydb_simple("prelatex", $prelatex); 1866 &close_dbm_database; 1867 unless ($CAN_FORK) { 1868 &do_write_string_out; 1869 } else { 1870 unless ($pid = fork) { 1871 &do_write_string_out; 1872 exit 0; 1873 }; 1874 waitpid($pid,0); 1875 } 1876 &open_dbm_database; 1877} 1878 1879sub do_write_string_out { 1880 local($_); 1881 close (SINPUT) if($CAN_FORK); 1882 &open_dbm_database; 1883 $_ = delete $string{'STRING'}; 1884 # locate blank-lines, for paragraphs. 1885 # Replace verbatim environments etc. 1886 &pre_process; 1887 # locate the blank lines for \par s 1888 &substitute_pars; 1889 # Handle newcommand, newenvironment, newcounter ... 1890 &substitute_meta_cmds; 1891 &wrap_shorthand_environments; 1892 print STDOUT "\n *** End-of-partition ***" if ($VERBOSITY > 1); 1893 if(open(OUT, ">$TMP_$dd$PARTITION_PREFIX$count")) { 1894 print OUT $_; 1895 close(OUT); 1896 } else { 1897 print "\nError: Cannot write '$TMP_$dd$PARTITION_PREFIX$count': $!\n"; 1898 } 1899 print STDOUT $_ if ($VERBOSITY > 9); 1900 $preamble = join("\n",$preamble,@preamble); # undef @preamble; 1901 &write_mydb_simple("preamble", $preamble); 1902 # this was done earlier; it should not be repeated 1903 #&write_mydb_simple("prelatex", $prelatex); 1904 &write_mydb_simple("aux_preamble", $aux_preamble); 1905 &close_dbm_database; 1906} 1907 1908# Reads the entire input file into a 1909# single string. 1910sub slurp_input { 1911 local($file) = @_; 1912 local(%string); 1913 if(open(INPUT,"<$file")) { 1914 local(@file_string); 1915 while (<INPUT>) { 1916 push(@file_string, $_ ); 1917 } 1918 $string{'STRING'} = join('',@file_string); 1919 close INPUT; 1920 undef @file_string; 1921 } else { 1922 print "\nError: Cannot read '$file': $!\n"; 1923 } 1924 $_ = delete $string{'STRING'}; # Blow it away and return the result 1925} 1926 1927# MRO: make them more efficient 1928sub special { 1929 $html_specials{$_[0]} || $_[0]; 1930} 1931 1932sub special_inv { 1933 $html_specials_inv{$_[0]} || $_[0]; 1934} 1935 1936sub special_html { 1937 $html_special_entities{$_[0]} || $_[0]; 1938} 1939 1940sub special_html_inv { 1941 $html_spec_entities_inv{$_[0]} || $_[0]; 1942} 1943 1944# Mark each matching opening and closing bracket with a unique id. 1945sub mark_string { 1946 # local (*_) = @_; # Modifies $_ in the caller; 1947 # -> MRO: changed to $_[0] (same effect) 1948 # MRO: removed deprecated $*, replaced by option /m 1949 $_[0] =~ s/(^|[^\\])\\\{/$1tex2html_escaped_opening_bracket/gom; 1950 $_[0] =~ s/(^|[^\\])\\\{/$1tex2html_escaped_opening_bracket/gom; # repeat this 1951 $_[0] =~ s/(^|[^\\])\\\}/$1tex2html_escaped_closing_bracket/gom; 1952 $_[0] =~ s/(^|[^\\])\\\}/$1tex2html_escaped_closing_bracket/gom; # repeat this 1953 my $id = $global{'max_id'}; 1954 my $prev_id = $id; 1955 # mark all balanced braces 1956 # MRO: This should in fact mark all of them as the hierarchy is 1957 # processed inside-out. 1958 1 while($_[0] =~ s/\{([^{}]*)\}/join("",$O,++$id,$C,$1,$O,$id,$C)/geo); 1959 # What follows seems esoteric... 1960 my @processedB = (); 1961 # Take one opening brace at a time 1962 while ($_[0] =~ /\{/) { 1963 my ($before,$after) = ($`,$'); 1964 my $change = 0; 1965 while (@UNMATCHED_OPENING && $before =~ /\}/) { 1966 my $this = pop(@UNMATCHED_OPENING); 1967 print "\n *** matching brace \#$this found ***\n"; 1968 $before =~ s/\}/join("",$O,$this,$C)/eo; 1969 $change = 1; 1970 } 1971 $_[0] = join('',$before,"\{",$after) if($change); 1972 # MRO: mark one opening brace 1973 if($_[0] =~ s/^([^{]*)\{/push(@processedB,$1);join('',$O,++$id,$C)/eos) { 1974 $before=''; $after=$'; 1975 } 1976 if ($after =~ /\}/) { 1977 $after =~ s/\}/join("",$O,$id,$C)/eo; 1978 $_[0] = join('',$before,$O,$id,$C,$after); 1979 } else { 1980 print "\n *** opening brace \#$id is unmatched ***\n"; 1981 $after =~ /^(.+\n)(.+\n)?/; 1982 print " preceding: $after \n"; 1983 push (@UNMATCHED_OPENING,$id); 1984 } 1985 } 1986 $_[0] = join('',@processedB,$_[0]); undef(@processedB); 1987 print STDOUT "\nInfo: bracketings found: ", $id - $prev_id,"\n" 1988 if ($VERBOSITY > 1); 1989 # process remaining closing braces 1990 while (@UNMATCHED_OPENING && $_[0] =~ /\}/) { 1991 my $this = pop(@UNMATCHED_OPENING); 1992 print "\n *** matching brace \#$this found ***\n"; 1993 $_[0] =~ s/\}/join("",$O,$this,$C)/eo; 1994 } 1995 1996 while ($_[0] =~ /\}/) { 1997 print "\n *** there was an unmatched closing \} "; 1998 my ($beforeline,$prevline,$afterline) = ($`, $`.$& , $'); 1999 $prevline =~ /\n([^\n]+)\}$/m; 2000 if ($1) { 2001 print "at the end of:\n" . $1 . "\}\n\n"; 2002 } else { 2003 $afterline =~ /^([^\n]+)\n/m; 2004 if ($1) { 2005 print "at the start of:\n\}" . $1 ."\n\n"; 2006 } else { 2007 $prevline =~ /\n([^\n]+)\n\}$/m; 2008 print "on a line by itself after:\n" . $1 . "\n\}\n\n"; 2009 } 2010 } 2011 $_[0] = $beforeline . $afterline; 2012 } 2013 $global{'max_id'} = $id; 2014 2015 # restore escaped braces 2016 $_[0] =~ s/tex2html_escaped_opening_bracket/\\\{/go; 2017 $_[0] =~ s/tex2html_escaped_closing_bracket/\\\}/go; 2018} 2019 2020sub replace_html_special_chars { 2021 # Replaces html special characters with markers unless preceded by "\" 2022 s/([^\\])(<|>|&|\"|``|'')/&special($1).&special($2)/geom; 2023 # MUST DO IT AGAIN JUST IN CASE THERE ARE CONSECUTIVE HTML SPECIALS 2024 s/([^\\])(<|>|&|\"|``|'')/&special($1).&special($2)/geom; 2025 s/^(<|>|&|\"|``|'')/&special($1)/geom; 2026} 2027 2028# used in \verbatiminput only: $html_escape_chars = '<>&'; 2029sub replace_all_html_special_chars { s/([$html_escape_chars])/&special($1)/geom; } 2030 2031# The bibliography and the index should be treated as separate sections 2032# in their own HTML files. The \bibliography{} command acts as a sectioning command 2033# that has the desired effect. But when the bibliography is constructed 2034# manually using the thebibliography environment, or when using the 2035# theindex environment it is not possible to use the normal sectioning 2036# mechanism. This subroutine inserts a \bibliography{} or a dummy 2037# \textohtmlindex command just before the appropriate environments 2038# to force sectioning. 2039sub add_bbl_and_idx_dummy_commands { 2040 local($id) = $global{'max_id'}; 2041 2042 s/([\\]begin\s*$O\d+$C\s*thebibliography)/$bbl_cnt++; $1/eg; 2043 ## if ($bbl_cnt == 1) { 2044 s/([\\]begin\s*$O\d+$C\s*thebibliography)/$id++; "\\bibliography$O$id$C$O$id$C $1"/geo; 2045 #} 2046 $global{'max_id'} = $id; 2047 s/([\\]begin\s*$O\d+$C\s*theindex)/\\textohtmlindex $1/o; 2048 s/[\\]printindex/\\textohtmlindex /o; 2049 &lib_add_bbl_and_idx_dummy_commands() if defined(&lib_add_bbl_and_idx_dummy_commands); 2050} 2051 2052 2053# Uses and modifies $default_language 2054# This would be straight-forward except when there are 2055# \MakeUppercase, \MakeLowercase or \uppercase , \lowercase commands 2056# present in the source. The cases have to be adjusted before the 2057# ISO-character code is set; e.g. with "z --> "Z in german.perl 2058# 2059sub convert_iso_latin_chars { 2060 local($_) = @_; 2061 local($next_language, $pattern); 2062 local($xafter, $before, $after, $funct, $level, $delim); 2063 local(@case_processed); 2064 while (/$case_change_rx/) { 2065 $xafter = $2; 2066# $before .= $`; 2067 push(@case_processed, $`); 2068 $funct = $3; 2069 $after = ''; 2070 $_ = $'; 2071 if ($xafter =~ /noexpand/) { $before .= "\\$funct"; next; } 2072 2073 s/^[\s%]*(.)/$delim=$1;''/eo; 2074 if ($delim =~ /{/ ) { 2075 # brackets not yet numbered... 2076# $before .= $funct . $delim; 2077 push(@case_processed, $funct . $delim); 2078 $level = 1; 2079 $after = $delim; 2080 while (($level)&&($_)&&(/[\{\}]/)) { 2081 $after .= $` . $&; 2082 $_ = $'; 2083 if ( "$&" eq "\{" ) {$level++} 2084 elsif ( "$&" eq "\}" ) { $level-- } 2085 else { print $_ } 2086 print "$level"; 2087 } 2088# $before .= $after; 2089 push(@case_processed, $after); 2090 } elsif ($delim eq "<") { 2091 # brackets numbered, but maybe not processed... 2092 s/((<|#)(\d+)(>|#)>).*\1//; 2093 $after .= $delim . $&; 2094 $_ = $'; 2095 print STDOUT "\n<$2$funct$4>" if ($VERBOSITY > 2); 2096 $funct =~ s/^\\//o; 2097 local($cmd) = "do_cmd_$funct"; 2098 $after = &$cmd($after); 2099# $before .= $after; 2100 push(@case_processed, $after); 2101 } elsif (($xafter)&&($delim eq "\\")) { 2102 # preceded by \expandafter ... 2103 # ...so expand the following macro first 2104 $funct =~ s/^\\//o; 2105 local($case_change) = $funct; 2106 s/^(\w+|\W)/$funct=$1;''/eo; 2107 local($cmd) = $funct; 2108 local($thiscmd) = "do_cmd_$funct"; 2109 if (defined &$thiscmd) { $_ = &$thiscmd($_) } 2110 elsif ($new_command{$funct}) { 2111 local($argn, $body, $opt) = split(/:!:/, $new_command{$funct}); 2112 do { ### local($_) = $body; 2113 &make_unique($body); 2114 } if ($body =~ /$O/); 2115 if ($argn) { 2116 do { 2117 local($before) = ''; 2118 local($after) = "\\$funct ".$_; 2119 $after = &substitute_newcmd; # may change $after 2120 $after =~ s/\\\@#\@\@/\\/o ; 2121 } 2122 } else { $_ = $body . $_; } 2123 } else { print "\nUNKNOWN COMMAND: $cmd "; } 2124 2125 $cmd = $case_change; 2126 $case_change = "do_cmd_$cmd"; 2127 if (defined &$case_change) { $_ = &$case_change($_) } 2128 } else { 2129 # this should not happen, but just in case... 2130 $funct =~ s/^\\//o; 2131 local($cmd) = "do_cmd_$funct"; 2132 print STDOUT "\n\n<$delim$funct>" if ($VERBOSITY > 2); 2133 $_ = join('', $delim , $_ ); 2134 if (defined &$cmd) { $_ = &$cmd($_) } 2135 } 2136 } 2137# $_ = join('', $before, $_) if ($before); 2138 $_ = join('', @case_processed, $_) if (@case_processed); 2139 2140 # ...now do the conversions 2141 ($before, $after, $funct) = ('','',''); 2142 @case_processed = (); 2143 if (/$language_rx/o) { 2144 ($next_language, $pattern, $before, $after) = (($2||$1), $&, $`, $'); 2145 $before = &convert_iso_latin_chars($before) if ($before); 2146# push(@case_processed, $pattern, $before); 2147 local($br_id) = ++$global{'max_id'}; 2148 $pattern = join('' , '\selectlanguage', $O.$br_id.$C 2149 , (($pattern =~ /original/) ? $TITLES_LANGUAGE : $next_language ) 2150 , $O.$br_id.$C ); 2151 push(@case_processed, $before, $pattern); 2152 push(@language_stack, $default_language); 2153 $default_language = $next_language; 2154 $_ = &convert_iso_latin_chars($after); 2155 $default_language = pop @language_stack; 2156 } else { 2157 $funct = $language_translations{$default_language}; 2158 (defined(&$funct) ? $_ = &$funct($_) : 2159 do { &write_warnings( 2160 "\nCould not find translation function for $default_language.\n\n") 2161 } 2162 ); 2163 if ($USE_UTF ||(!$NO_UTF &&(%unicode_table)&&length(%unicode_table)>2)) { 2164 &convert_to_unicode($_)}; 2165 } 2166 $_ = join('', @case_processed, $_); undef(@case_processed); 2167 $_; 2168} 2169 2170# May need to add something here later 2171sub english_translation { $_[0] } 2172 2173# This replaces \setlanguage{\language} with \languageTeX 2174# This makes the identification of language chunks easier. 2175sub normalize_language_changes { 2176 s/$setlanguage_rx/\\$2TeX/gs; 2177} 2178 2179sub get_current_language { 2180 return () if ($default_language eq $TITLES_LANGUAGE); 2181 local($lang,$lstyle) = ' LANG="'; 2182 $lang_code = $iso_languages{$default_language}; 2183 if (%styled_languages) { 2184 $lstyle = $styled_languages{$default_language}; 2185 $lstyle = '" CLASS="'.$lstyle if $lstyle; 2186 } 2187 ($lang_code ? $lang.$lang_code.$lstyle.'"' : ''); 2188} 2189 2190%styled_languages = (); 2191 2192sub do_cmd_htmllanguagestyle { 2193 local($_) = @_; 2194 local($class) = &get_next_optional_argument; 2195 local($lang) = &missing_braces unless ( 2196 (s/$next_pair_pr_rx/$lang=$2;''/e) 2197 ||(s/$next_pair_rx/$lang=$2;''/e)); 2198 return ($_) unless $lang; 2199 local($class) = $iso_languages{$lang} unless $class; 2200 if ($USING_STYLES && $class) { 2201 print "\nStyling language: $lang = \"$class\" "; 2202 $styled_languages{"$lang"} = $class; 2203 } 2204 $_; 2205} 2206 2207# General translation mechanism: 2208# 2209# 2210# The main program latex2html calls texexpand with the document name 2211# in order to expand some of its \input and \include statements, here 2212# also called 'merging', and to write a list of sensitized style, class, 2213# input, or include file names. 2214# When texexpand has finished, all is contained in one file, TMP_foo. 2215# (assumed foo.tex is the name of the document to translate). 2216# 2217# In this version, texexpand cares for following environments 2218# that may span include files / section boundaries: 2219# (For a more technical description, see texexpand.) 2220# a) \begin{comment} 2221# b) %begin{comment} 2222# c) \begin{any} introduced with \excludecomment 2223# d) %begin{any} 2224# e) \begin{verbatim} 2225# f) \begin{latexonly} 2226# g) %begin{latexonly} 2227# 2228# a)-d) cause texexpand to drop its contents, it will not show up in the 2229# output file. You can use this to 'comment out' a bunch of files, say. 2230# 2231# e)-g) prevent texexpand from expanding input files, but the environment 2232# content goes fully into the output file. 2233# 2234# Together with each merging of \input etc. there are so-called %%%texexpand 2235# markers accompanying the boundary. 2236# 2237# When latex2html reads in the output file, it uses these markers to write 2238# each part to a separate file, and process them further. 2239# 2240# 2241# If you have, for example: 2242# 2243# a) preample 2244# b) \begin{document} 2245# c) text 2246# d) \input{chapter} 2247# e) more text 2248# f) \end{document} 2249# 2250# you end up in two parts, part 1 is a)-c), part 2 is the rest. 2251# Regardless of environments spanning input files or sections. 2252# 2253# 2254# What now starts is meta command substitution: 2255# Therefore, latex2html forks a child process on the first part and waits 2256# until it finished, then forks another on the next part and so forth 2257# (see also &slurp_input_and_partition_and_preprocess). 2258# 2259# Here's what each child is doing: 2260# Each child process reads the new commands translated so far by the previous 2261# child from the TMP_global DBM database. 2262# After &pre_processing, it substitutes the meta commands (\newcommand, \def, 2263# and the like) it finds, and adds the freshly retrieved new commands to the 2264# list so far. 2265# This is done *only on its part* of the document; this saves upwards of memory. 2266# Finally, it writes its list of new commands (synopsis and bodies) to the 2267# DBM database, and exits. 2268# After the last child finished, latex2html reads in all parts and 2269# concatenates them. 2270# 2271# 2272# So, at this point in time (start of &translate), it again has the complete 2273# document, but now preprocessed and with new commands substituted. 2274# This has several disadvantages: an amount of commands is substituted (in 2275# TeX lingo, expanded) earlier than the rest. 2276# This causes trouble if commands really must get expanded at the point 2277# in time they show up. 2278# 2279# 2280# Then, still in &translate, latex2html uses the list of section commands to 2281# split the complete document into chunks. 2282# The chunks are not written to files yet. They are retained in the @sections 2283# list, but each chunk is handled separately. 2284# latex2html puts the current chunk to $_ and processes it with 2285# &translate_environments etc., then fetches the next chunk, and so on. 2286# This prevents environments that span section boundaries from getting 2287# translated, because \begin and \end cannot find one another, to say it this 2288# way. 2289# 2290# 2291# After the chunk is translated to HTML, it is written to a file. 2292# When all chunks are done, latex2html rereads each file to get cross 2293# references right, replace image markers with the image file names, and 2294# writes index and bibliography. 2295# 2296# 2297sub translate { 2298 &normalize_sections; # Deal with the *-form of sectioning commands 2299 2300 2301 # Split the input into sections, keeping the preamble together 2302 # Due to the regular expression, each split will create 5 more entries. 2303 # Entry 1 and 2: non-letter/letter sectioning command, 2304 # entry 4: the delimiter (may be empty) 2305 # entry 5: the text. 2306 local($pre_section, @sections); 2307 if (/\\(startdocument|begin\s*($O\d+$C)\s*document\s*\2)/) { 2308 $pre_section = $`.$&; $_ = $'; 2309 } 2310 @sections = split(/$sections_rx/, $_); 2311 $sections[0] = $pre_section.$sections[0] if ($pre_section); 2312 undef $pre_section; 2313 local($sections) = int(scalar(@sections) / 5); 2314 2315 # Initialises $curr_sec_id to a list of 0's equal to 2316 # the number of sectioning commands. 2317 local(@curr_sec_id) = split(' ', &make_first_key); 2318 local(@segment_sec_id) = @curr_sec_id; 2319 local($i, $j, $current_depth) = (0,0,0); 2320 local($curr_sec) = $SHORT_FILENAME||$FILE; 2321 local($top_sec) = ($SEGMENT ? '' : 'top of '); 2322# local(%section_info, %toc_section_info, $CURRENT_FILE, %cite_info, %ref_files); 2323 local($CURRENT_FILE); 2324 # These filenames may be set when translating the corresponding commands. 2325 local($tocfile, $loffile, $lotfile, $footfile, $citefile, $idxfile, 2326 $figure_captions, $table_captions, $footnotes, $citations, %font_size, %index, 2327 %done, $t_title, $t_author, $t_date, $t_address, $t_affil, $changed); 2328 local(@authors,@affils,@addresses,@emails,@authorURLs); 2329 local(%index_labels, %index_segment, $preindex, %footnotes, %citefiles); 2330 local($segment_table_captions, $segment_figure_captions); 2331 local($dir,$nosave) = ('',''); 2332 local($del,$close_all,$open_all,$toc_sec_title,$multiple_toc); 2333 local($open_tags_R) = []; 2334 local(@save_open_tags)= (); 2335 local(@language_stack) = (); 2336 push (@language_stack, $default_language); 2337 2338# $LATEX_FONT_SIZE = '10pt' unless ($LATEX_FONT_SIZE); 2339 &process_aux_file 2340 if $SHOW_SECTION_NUMBERS || /\\(caption|(html|hyper)?((eq)?ref|cite))/; 2341 2342 require ("${PREFIX}internals.pl") if (-f "${PREFIX}internals.pl"); 2343#JCL(jcl-del) 2344 &make_single_cmd_rx; 2345# 2346 $tocfile = $EXTERNAL_CONTENTS; 2347 $idxfile = $EXTERNAL_INDEX; 2348 $citefile = $EXTERNAL_BIBLIO; $citefile =~ s/#.*$//; 2349 $citefiles{1} = $citefile if ($citefile); 2350 print "\nTranslating ..."; 2351 2352 while ($i <= @sections) { 2353 undef $_; 2354 $_ = $sections[$i]; 2355 s/^[\s]*//; # Remove initial blank lines 2356 2357 # The section command was removed when splitting ... 2358 s/^/\\$curr_sec$del/ if ($i > 0); # ... so put it back 2359 if ($current_depth < $MAX_SPLIT_DEPTH) { 2360 if (($footnotes)&&($NO_FOOTNODE)&&( $current_depth < $MAX_SPLIT_DEPTH)) { 2361 local($thesenotes) = &make_footnotes ; 2362 print OUTPUT $thesenotes; 2363 } 2364 $CURRENT_FILE = &make_name($curr_sec, join('_',@curr_sec_id)); 2365 2366 open(OUTPUT, ">$CURRENT_FILE") 2367 || die "Cannot write '$CURRENT_FILE': $!\n"; 2368 if ($XBIT_HACK) { # use Apache's XBit hack 2369 chmod 0744, $CURRENT_FILE; 2370 &check_htaccess; 2371 } else { 2372 chmod 0644, $CURRENT_FILE; 2373 } 2374 2375 if ($MULTIPLE_FILES && $ROOTED) { 2376 if ($DESTDIR =~ /^\Q$FIXEDDIR\E[$dd$dd]?([^$dd$dd]+)/) 2377 { $CURRENT_FILE = "$1$dd$CURRENT_FILE" }; 2378 } 2379 } 2380 &remove_document_env; 2381# &wrap_shorthand_environments; #RRM Is this needed ? 2382 print STDOUT "\n" if ($VERBOSITY); 2383 print STDOUT "\n" if ($VERBOSITY > 2); 2384 print $i/5,"/$sections"; 2385 print ":$top_sec$curr_sec:" if ($VERBOSITY); 2386 2387 # Must do this early ... It also sets $TITLE 2388 &process_command($sections_rx, $_) if (/^$sections_rx/); 2389 # reset tags saved from the previous section 2390 $open_tags_R = [ @save_open_tags ]; 2391 @save_open_tags = (); 2392 2393 local($curr_sec_tex); 2394 if ((! $TITLE) || ($TITLE eq $default_title)) { 2395 eval '$TITLE = '.$default_title; 2396 $TITLE = $default_title if $@; 2397 $curr_sec_tex = ($top_sec ? '' : 2398 join('', '"', &revert_to_raw_tex($curr_sec), '"')); 2399 print STDOUT "$curr_sec_tex for $CURRENT_FILE\n" if ($VERBOSITY); 2400 } else { 2401 local($tmp) = &purify($TITLE,1); 2402 $tmp = &revert_to_raw_tex($tmp); 2403 print STDOUT "\"$tmp\" for $CURRENT_FILE\n" if ($VERBOSITY); 2404 } 2405 2406 if (/\\(latextohtmlditchpreceding|startdocument)/m) { 2407 local($after) = $'; 2408 local($before) = $`.$&; 2409 $SEGMENT = 1 if ($1 =~ /startdocument/); 2410 print STDOUT "\n *** translating preamble ***\n" if ($VERBOSITY); 2411 $_ = &translate_preamble($before); 2412 s/\n\n//g; s/<BR>//g; # remove redundant blank lines and breaks 2413# 2414# &process_aux_file if $AUX_FILE_NEEDED; 2415# 2416 print STDOUT "\n *** preamble done ***\n" if ($VERBOSITY); 2417 $PREAMBLE = 0; 2418 $NESTING_LEVEL=0; 2419 &do_AtBeginDocument; 2420 $after =~ s/^\s*//m; 2421 print STDOUT (($VERBOSITY >2)? "\n*** Translating environments ***" : ";"); 2422 $after = &translate_environments($after); 2423 print STDOUT (($VERBOSITY >2)? "\n*** Translating commands ***" : ";"); 2424 $_ .= &translate_commands($after); 2425# $_ = &translate_commands($after); 2426 } else { 2427 &do_AtBeginDocument; 2428 $PREAMBLE = 0; 2429 $NESTING_LEVEL=0; 2430 print STDOUT (($VERBOSITY >2)? "\n*** Translating environments ***" : ";"); 2431 $_ = &translate_environments($_); 2432 print STDOUT (($VERBOSITY >2)? "\n*** Translating commands ***" : ";"); 2433 $_ = &translate_commands($_); 2434 } 2435 2436 # close any tags that remain open 2437 if (@$open_tags_R) { 2438 ($close_all,$open_all) = &preserve_open_tags(); 2439 $_ .= $close_all; 2440 @save_open_tags = @$open_tags_R; $open_tags_R = []; 2441 } else { ($close_all,$open_all) = ('','') } 2442 2443 print STDOUT (($VERBOSITY >2)? "\n*** Translations done ***" : "\n"); 2444# if (($footnotes)&&($NO_FOOTNODE)&&( $current_depth < $MAX_SPLIT_DEPTH)) { 2445# $_ .= &make_footnotes 2446# } 2447 print OUTPUT $_; 2448 2449 # Associate each id with the depth, the filename and the title 2450 ###MEH -- starred sections don't show up in TOC ... 2451 # RRM: ...unless $TOC_STARS is set 2452# $toc_sec_title = &simplify($toc_sec_title); 2453 $toc_sec_title = &purify($toc_sec_title);# if $SEGMENT; 2454 $toc_sec_title = &purify($TITLE) unless ($toc_sec_title); 2455 2456 if ($TOC_STARS) { 2457 $toc_section_info{join(' ',@curr_sec_id)} = 2458 "$current_depth$delim$CURRENT_FILE$delim$toc_sec_title" 2459# if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 2460 if ($current_depth <= $TOC_DEPTH); 2461 } else { 2462 $toc_section_info{join(' ',@curr_sec_id)} = 2463 "$current_depth$delim$CURRENT_FILE$delim$toc_sec_title" 2464 . ($curr_sec =~ /star$/ ? "$delim<tex2html_star_mark>" : "") 2465# if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 2466 if ($current_depth <= $TOC_DEPTH); 2467 } 2468 2469 # include $BODYTEXT in the section_info, when starting a new page 2470 $section_info{join(' ',@curr_sec_id)} = 2471 "$current_depth$delim$CURRENT_FILE$delim$TITLE$delim" 2472 . (($current_depth < $MAX_SPLIT_DEPTH)? $BODYTEXT: ""); 2473 2474 # Get type of section (see also the split above) 2475 $curr_sec = $sections[$i+1].$sections[$i+2]; 2476 $del = $sections[$i+4]; 2477 2478 # Get the depth of the current section; 2479# $curr_sec = $outermost_level unless $curr_sec; 2480 $current_depth = $section_commands{$curr_sec}; 2481 if ($after_segment) { 2482 $current_depth = $after_segment; 2483 $curr_sec_id[$after_segment] += $after_seg_num; 2484 ($after_segment,$after_seg_num) = ('',''); 2485 for($j=1+$current_depth; $j <= $#curr_sec_id; $j++) { 2486 $curr_sec_id[$j] = 0; 2487 } 2488 } 2489 if ($SEGMENT||$SEGMENTED) { 2490 for($j=1; $j <= $#curr_sec_id; $j++) { 2491 $curr_sec_id[$j] += $segment_sec_id[$j]; 2492 $segment_sec_id[$j] = 0; 2493 } 2494 }; 2495 2496 2497 # this may alter the section-keys 2498 $multiple_toc = 1 if ($MULTIPLE_FILES && $ROOTED && (/$toc_mark/)); 2499 2500 2501 #RRM : Should this be done here, or in \stepcounter ? 2502 @curr_sec_id = &new_level($current_depth, @curr_sec_id); 2503 2504 $toc_sec_title = $TITLE = $top_sec = ''; 2505 $i+=5; #skip to next text section 2506 } 2507 $open_tags_R = []; 2508 $open_all = ''; 2509 2510 $_ = undef; 2511 $_ = &make_footnotes if ($footnotes); 2512 $CURRENT_FILE = ''; 2513 print OUTPUT; 2514 close OUTPUT; 2515 2516 2517# # this may alter the section-keys 2518# &adjust_root_keys if $multiple_toc; 2519 2520 if ($PREPROCESS_IMAGES) { &preprocess_images } 2521 else { &make_image_file } 2522 print STDOUT "\n *** making images ***" if ($VERBOSITY > 1); 2523 &make_images; 2524 2525 # Link sections, add head/body/address do cross-refs etc 2526 print STDOUT "\n *** post-process ***" if ($VERBOSITY > 1); 2527 &post_process; 2528 2529 if (defined &document_post_post_process) { 2530 #BRM: extra document-wide post-processing 2531 print STDOUT "\n *** post-processing Document ***" if ($VERBOSITY > 1); 2532 &document_post_post_process(); 2533 } 2534 2535 print STDOUT "\n *** post-processed ***" if ($VERBOSITY > 1); 2536 ©_icons if $LOCAL_ICONS; 2537 if ($SEGMENT || $DEBUG || $SEGMENTED) { 2538 &save_captions_in_file("figure", $figure_captions) if $figure_captions; 2539 &save_captions_in_file("table", $table_captions) if $table_captions; 2540# &save_array_in_file ("captions", "figure_captions", 0, %figure_captions) if %figure_captions; 2541# &save_array_in_file ("captions", "table_captions", 0, %table_captions) if %table_captions; 2542 &save_array_in_file ("index", "index", 0, %index); 2543 &save_array_in_file ("sections", "section_info", 0, %section_info); 2544 &save_array_in_file ("contents", "toc_section_info", 0,%toc_section_info); 2545 &save_array_in_file ("index", "sub_index", 1, %sub_index) if %sub_index; 2546 &save_array_in_file ("index", "index_labels", 1, %index_labels) if %index_labels; 2547 &save_array_in_file ("index", "index_segment", 1, %index_segment) if %index_segment; 2548 &save_array_in_file ("index", "printable_key", 1, %printable_key) 2549 if (%printable_key || %index_segment); 2550 } 2551 elsif ($MULTIPLE_FILES && $ROOTED) { 2552 &save_array_in_file ("sections", "section_info", 0, %section_info); 2553 &save_array_in_file ("contents", "toc_section_info", 0, %toc_section_info); 2554 } 2555 &save_array_in_file ("internals", "ref_files", 0, %ref_files) if $changed; 2556 &save_array_in_file ("labels", "external_labels", 0, %ref_files); 2557 &save_array_in_file ("labels", "external_latex_labels", 1, %latex_labels); 2558 &save_array_in_file ("images", "cached_env_img", 0, %cached_env_img); 2559} 2560 2561# RRM: 2562sub translate_preamble { 2563 local($_) = @_; 2564 $PREAMBLE = 1; 2565 $NESTING_LEVEL=0; #counter for TeX group nesting level 2566 # remove some artificially inserted constructions 2567 s/\n${tex2html_deferred_rx}\\par\s*${tex2html_deferred_rx2}\n/\n/gm; 2568 s/\\newedcommand(<<\d+>>)([A-Za-z]+|[^A-Za-z])\1(\[\d+\])?(\[[^]]*\])?(<<\d+>>)[\w\W\n]*\5($comment_mark\d*)?//gm; 2569 s/\n{2,}/\n/ogm; 2570 2571 if (/\\htmlhead/) { 2572 print STDOUT "\nPREAMBLE: discarding...\n$`" if ($VERBOSITY > 4); 2573 local($after) = $&.$'; 2574 # translate segment preamble preceding \htmlhead 2575 &translate_commands(&translate_environments($`)); 2576 # translate \htmlhead and rest of preamble 2577 $_=&translate_commands(&translate_environments($after)); 2578 print STDOUT "\nPREAMBLE: retaining...\n$_" if ($VERBOSITY > 4); 2579 } else { 2580 # translate only preamble here (metacommands etc.) 2581 # there should be no textual results, if so, discard them 2582 &translate_commands(&translate_environments($_)); 2583 print STDOUT "\nPREAMBLE: discarding...\n$_" if ($VERBOSITY > 4); 2584 $_=""; 2585 }; 2586 $_ = &do_AtBeginDocument($_); 2587 if (! $SEGMENT) { $_ = ''} # segmented documents have a heading already 2588 $_; 2589} 2590 2591############################ Processing Environments ########################## 2592 2593sub wrap_shorthand_environments { 2594 # This wraps a dummy environment around environments that do not use 2595 # the begin-end convention. The wrapper will force them to be 2596 # evaluated by Latex rather than them being translated. 2597 # Wrap a dummy environment around matching TMPs. 2598 # s/^\$\$|([^\\])\$\$/{$1.&next_wrapper('tex2html_double_dollar')}/ge; 2599 # Wrap a dummy environment around matching $s. 2600 # s/^\$|([^\\])\$/{$1.&next_wrapper('$')}/ge; 2601 # s/tex2html_double_dollar/\$\$/go; 2602 # Do \(s and \[s 2603 # 2604 local($wrapper) = "tex2html_wrap_inline"; # \ensuremath wrapper 2605 print STDOUT "\n *** wrapping environments ***\n" if ($VERBOSITY > 3); 2606 2607 # MRO: replaced $* with /m 2608 print STDOUT "\\(" if ($VERBOSITY > 3); 2609 s/(^\\[(])|([^\\])(\\[(])/{$2.&make_any_wrapper(1,'',$wrapper).$1.$3}/geom; 2610 print STDOUT "\\)" if ($VERBOSITY > 3); 2611 s/(^\\[)]|[^\\]\\[)])/{$1.&make_any_wrapper(0,'',$wrapper)}/geom; 2612 2613 print STDOUT "\\[" if ($VERBOSITY > 3); 2614 s/(^\\[[])|([^\\])(\\[[])/{$2.&make_any_wrapper(1,1,"displaymath")}/geom; 2615 print STDOUT "\\]" if ($VERBOSITY > 3); 2616 s/(^\\[\]])|([^\\])(\\[\]])/{$2.&make_any_wrapper(0,1,"displaymath")}/geom; 2617 2618 print STDOUT "\$" if ($VERBOSITY > 3); 2619 s/$enspair/print "\$"; 2620 {&make_any_wrapper(1,'',$wrapper).$&.&make_any_wrapper(0,'',$wrapper)}/geom; 2621 2622 $double_dol_rx = '(^|[^\\\\])\\$\\$'; 2623 $single_dol_rx = '(^|[^\\\\])\\$'; 2624 print STDOUT "\$" if ($VERBOSITY > 3); 2625 2626 local($dollars_remain) = 0; 2627 $_ = &wrap_math_environment; 2628 $_ = &wrap_raw_arg_cmds; 2629} 2630 2631sub wrap_math_environment { 2632 2633 # This wraps math-type environments 2634 # The trick here is that the opening brace is the same as the close, 2635 # but they *can* still nest, in cases like this: 2636 # 2637 # $ outer stuff ... \hbox{ ... $ inner stuff $ ... } ... $ 2638 # 2639 # Note that the inner pair of $'s is nested within a group. So, to 2640 # handle these cases correctly, we need to make sure that the outer 2641 # brace-level is the same as the inner. --- rst 2642 #tex2html_wrap 2643 # And yet another problem: there is a scungy local idiom to do 2644 # this: $\_$ for a boldfaced underscore. xmosaic can't display the 2645 # resulting itty-bitty bitmap, for some reason; even if it could, it 2646 # would probably come out as an overbar because of the floating- 2647 # baseline problem. So, we have to special case this. --- rst again. 2648 2649 local ($processed_text, @processed_text, $before, $end_rx, $delim, $ifclosed); 2650 local ($underscore_match_rx) = "^\\s*\\\\\\_\\s*\\\$"; 2651 local ($wrapper); 2652 print STDOUT "\nwrap math:" if ($VERBOSITY > 3); 2653 2654 #find braced dollars, in tabular-specs 2655 while (/((($O|$OP)\d+($C|$CP))\s*)\$(\s*\2)/) { 2656 push (@processed_text, $`, $1.$dol_mark.$5); 2657 $_ = $'; 2658 } 2659 $_ = join('',@processed_text, $_) if (@processed_text); 2660 undef @processed_text; 2661 2662 $dollars_remain = 0; 2663 while (/$single_dol_rx/) { 2664 $processed_text .= $`.$1; 2665 $_ = $'; 2666 $wrapper = "tex2html_wrap_inline"; 2667 $end_rx = $single_dol_rx; # Default, unless we begin with $$. 2668 $delim = "\$"; 2669 2670 if (/^\$/ && (! $`)) { 2671 s/^\$//; 2672 $end_rx = $double_dol_rx; 2673 $delim = ""; # Cannot say "\$\$" inside displaymath 2674 $wrapper = "displaymath"; 2675 2676 } elsif (/$underscore_match_rx/ && (! $`)) { 2677 2678 # Special case for $\_$ ... 2679 2680 s/$underscore_match_rx//; 2681 $processed_text .= '\\_'; 2682 next; 2683 } 2684 2685 # Have an opening $ or $$. Find matching close, at same bracket level 2686# $processed_text .= &make_any_wrapper(1,'',$wrapper).$delim; 2687 2688 print STDOUT "\$" if ($VERBOSITY > 3); 2689 $ifclosed = 0; 2690 local($thismath); 2691 while (/$end_rx/) { 2692 # Forget the $$ if we are going to replace it with "displaymath" 2693 $before = $` . (($wrapper eq "displaymath")? "$1" : $&); 2694 last if ($before =~ /\\(sub)*(item|section|chapter|part|paragraph)(star)?\b/); 2695 $thismath .= $before; 2696 $_ = $'; 2697 s/^( [^\n])/\\space$1/s; #make sure a trailing space doesn't get lost. 2698 2699 # Found dollar sign inside open subgroup ... now see if it's 2700 # at the same brace-level ... 2701 2702 local ($losing, $br_rx) = (0, ''); 2703 print STDOUT "\$" if ($VERBOSITY > 3); 2704 while ($before =~ /$begin_cmd_rx/) { 2705 $br_rx = &make_end_cmd_rx($1); $before = $'; 2706 2707 if ($before =~ /$br_rx/) { $before = $'; } 2708 else { $losing = 1; last; } 2709 } 2710 do { $ifclosed = 1; last } unless $losing; 2711 2712 # It wasn't ... find the matching close brace farther on; then 2713 # keep going. 2714 2715 /$br_rx/; 2716 2717 $thismath .= $`.$&; 2718 2719 #RRM: may now contain unprocessed $s e.g. $\mbox{...$...$...}$ 2720 # the &do_cmd_mbox uses this specially to force an image 2721 # ...but there may be other situations; e.g. \hbox 2722 # so set a flag: 2723 $dollars_remain = 1; 2724 2725 $_ = $'; 2726 } 2727 2728 # Got to the end. Whew! 2729 if ($ifclosed) { 2730 # also process any nested math 2731 while (($dollars_remain)&&($delim eq "\$")) { 2732 local($saved) = $_; 2733 $thismath =~ s/\$$//; 2734 $_ = $thismath; 2735 $thismath = &wrap_math_environment; 2736 $thismath .= "\$"; 2737 $_ = $saved; 2738 } 2739 $processed_text .= &make_any_wrapper(1,'',$wrapper) . $delim 2740 . $thismath . &make_any_wrapper(0,'',$wrapper); 2741 } else { 2742 print STDERR "\n\n *** Error: unclosed math or extra `\$', before:\n$thismath\n\n"; 2743# # remove a $ to try to recover as much as possible. 2744# $thismath =~ s/([^\\]\\\\|[^\\])\$/$1\%\%/; 2745# $_ = $thismath . $_; $thismath = ""; 2746 print "\n$thismath\n\n\n$_\n\n\n"; die; 2747 2748 } 2749 } 2750 $processed_text . $_; 2751} 2752 2753sub translate_environments { 2754 local ($_) = @_; 2755 local($tmp, $capenv); 2756 print "\nPCT: Translating environments ...\n" if ($VERBOSITY > 20) ; 2757 local($after, @processedE); 2758 local ($contents, $before, $br_id, $env, $pattern); 2759 for (;;) { 2760# last unless (/$begin_env_rx/o); 2761 last unless (/$begin_env_rx|$begin_cmd_rx|\\(selectlanguage)/o); 2762# local ($contents, $before, $br_id, $env, $pattern); 2763 local($this_env, $opt_arg, $style_info); 2764 $contents = ''; 2765 # $1,$2 : optional argument/text --- stylesheet info 2766 # $3 : br_id (at the beginning of an environment name) 2767 # $4 : environment name 2768 # $5 : br_id of open-brace, when $3 == $4 == ''; 2769 # $6 : \selectlanguage{...} 2770 if ($7) { 2771 push(@processedE,$`); 2772 $_ = $'; 2773 if (defined &do_cmd_selectlanguage) { 2774 $_ = &do_cmd_selectlanguage($_); 2775 } else { 2776 local($cmd) = $7; 2777 $pattern = &missing_braces unless ( 2778 s/$next_pair_rx/$pattern = $2;''/e); 2779 local($trans) = $pattern.'_translation'; 2780 if (defined &$trans) { 2781 &set_default_language($pattern,$_); 2782 } 2783 undef $cmd; undef $trans; 2784 } 2785 next; 2786 } elsif ($4) { 2787 ($before, $opt_arg, $style_info, $br_id 2788 , $env, $after, $pattern) = ($`, $2, $3, $4, $5, $', $&); 2789 if (($before)&& (!($before =~ /$begin_env_rx|$begin_cmd_rx/))) { 2790 push(@processedE,$before); 2791 $_ = $pattern . $after; $before = ''; 2792 } 2793 } else { 2794 ($before, $br_id, $env, $after, $pattern) = ($`, $6, 'group', $', $&); 2795 if (($before)&& (!($before =~ /$begin_env_rx|$begin_cmd_rx/))) { 2796 push(@processedE,$before); 2797 $_ = $pattern . $after; $before = ''; 2798 } 2799 local($end_cmd_rx) = &make_end_cmd_rx($br_id); 2800 if ($after =~ /$end_cmd_rx/) { 2801 # ... find the the matching closing one 2802 $NESTING_LEVEL++; 2803 ($contents, $after) = ($`, $'); 2804 $contents = &process_group_env($contents); 2805 print STDOUT "\nOUT: {$br_id} ".length($contents) if ($VERBOSITY > 3); 2806 print STDOUT "\n:$contents\n" if ($VERBOSITY > 7); 2807 # THIS MARKS THE OPEN-CLOSE DELIMITERS AS PROCESSED 2808 $_ = join("", $before,"$OP$br_id$CP", $contents,"$OP$br_id$CP", $after); 2809 $NESTING_LEVEL--; 2810 } else { 2811 $pattern = &escape_rx_chars($pattern); 2812 s/$pattern//; 2813 print "\nCannot find matching bracket for $br_id"; 2814 $_ = join("", $before,"$OP$br_id$CP", $after); 2815 } 2816 next; 2817 } 2818 $contents = undef; 2819 local($defenv) = $env =~ /deferred/; 2820# local($color_env); 2821 local($color_env) 2822 unless ($env =~ /tabular|longtable|in(line|display)|math/); 2823 local($closures,$reopens); 2824 local(@save_open_tags) = @$open_tags_R unless ($defenv); 2825 local($open_tags_R) = [ @save_open_tags ] unless ($defenv); 2826 local(@saved_tags) if ($env =~ /tabular|longtable/); 2827 if ($env =~ /tabular|longtable|makeimage|in(line|display)/) { 2828 @save_open_tags = @$open_tags_R; 2829 $open_tags_R = [ @save_open_tags ]; 2830 # check for color 2831 local($color_test) = join(',',@$open_tags_R); 2832 if ($color_test =~ /(color\{[^}]*\})/g ) { 2833 $color_env = $1; 2834 } # else { $color_env = '' } 2835 2836 if ($env =~ /tabular|longtable|makeimage/) { 2837 # close to the surrounding block-type tag 2838 ($closures,$reopens,@saved_tags) = &preserve_open_block_tags(); 2839 @save_open_tags = @$open_tags_R; 2840 $open_tags_R = [ @save_open_tags ]; 2841 if ($color_env) { 2842 $color_test = join(',',@saved_tags); 2843 if ($color_test =~ /(color\{[^}]*\})/g ) { 2844 $color_env = $1; 2845 } 2846 } 2847 } elsif ($env =~ /in(line|display)/) { 2848 $closures = &close_all_tags() if ((&defined_env($env)) 2849 &&!($defenv)&&!($env=~/inline/)&&(!$declarations{$env})); 2850 if ($color_env) { 2851 $color_test = $declarations{$color_env}; 2852 $color_test =~ s/<\/.*$//; 2853 $closures .= "\n$color_test"; 2854 push (@$open_tags_R , $color_env); 2855 } 2856 } 2857 } elsif ($env =~ /alltt|tex2html_wrap/) { 2858 # alltt is constructed as paragraphs, not with <PRE> 2859 # tex2html_wrap creates an image, which is at text-level 2860 } else { 2861 $closures = &close_all_tags() if ((&defined_env($env)) 2862 &&!($defenv)&&(!$declarations{$env}) ); 2863 } 2864 # Sets $contents and modifies $after 2865 if (&find_end_env($env,$contents,$after)) { 2866 print STDOUT "\nIN-A {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2867 &process_command($counters_rx, $before) 2868 if ($before =~ /$counters_rx/); 2869 # This may modify $before and $after 2870 # Modifies $contents 2871#RRM: the do_env_... subroutines handle when to translate sub-environments 2872# $contents = &translate_environments($contents) if 2873## ((!$defenv) && (&defined_env($env)) && (! $raw_arg_cmds{$env}) 2874## && (!$declarations{$env}) 2875# ((&defined_env($env)) && (! $raw_arg_cmds{$env}) 2876# && (!($env =~ /latexonly|enumerate|figure|table|makeimage|wrap_inline/)) 2877# && ((! $NO_SIMPLE_MATH)||(!($env =~ /wrap/))) 2878# && (!($env =~ /(math|wrap|equation|eqnarray|makeimage|minipage|tabular)/) ) 2879# ); 2880 if ($opt_arg) { 2881 print "PCT: translate_environment: opt_arg\n" if ($VERBOSITY > 10) ; 2882 &process_environment(1, $env, $br_id, $style_info); # alters $contents 2883 } else { 2884 print "PCT: translate_environment: NO opt_arg\n" if ($VERBOSITY > 10) ; 2885 &process_environment(0, $env, $br_id, ''); 2886 } 2887 undef $_; 2888 print STDOUT "\nOUT-A {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2889 #JCL(jcl-env) - insert the $O$br_id$C stuff to handle environment grouping 2890 if (!($contents eq '')) { 2891 $after =~ s/^\n//o if ($defenv); 2892 $this_env = join("", $before, $closures 2893 , $contents 2894 , ($defenv ? '': &balance_tags()) 2895 , $reopens ); $_ = $after; 2896 } else { 2897 $this_env = join("", $before , $closures 2898 , ($defenv ? '': &balance_tags()) 2899 , $reopens ); $_ = $after; 2900 }; 2901 ### Evan Welsh <welsh@epcc.ed.ac.uk> added the next 24 lines ## 2902 } elsif (&defined_env($env)) { 2903 print STDOUT "\nIN-B {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2904 # If I specify a function for the environment then it 2905 # calls it with the contents truncated at the next section. 2906 # It assumes I know what I'm doing and doesn't give a 2907 # deferred warning. 2908 $contents = $after; 2909 if ($opt_arg) { 2910 $contents = &process_environment(1, $env, $br_id, $style_info); 2911 } else { 2912 $contents = &process_environment(0, $env, $br_id, ''); 2913 } 2914 print STDOUT "\nOUT-B {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2915 $this_env = join("", $before, $closures ,$contents, $reopens); 2916 2917 # there should not be anything left over 2918# $_ = $after; 2919 $_ = ''; 2920 } elsif ($ignore{$env}) { 2921 print STDOUT "\nIGNORED {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2922 # If I specify that the environment should be ignored then 2923 # it is but I get a deferred warning. 2924 $this_env = join("", $before , $closures , &balance_tags() 2925 , $contents, $reopens ); 2926 $_ = $after; 2927 &write_warnings("\n\\end{$env} not found (ignored).\n"); 2928 } elsif ($raw_arg_cmds{$env}) { 2929 print "\nIN-C {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2930 # If I specify that the environment should be passed to tex 2931 # then it is with the environment truncated at the next 2932 # section and I get a deferred warning. 2933 2934 $contents = $after; 2935 if ($opt_arg) { 2936 $contents = &process_environment(1, $env, $br_id, $style_info); 2937 } else { 2938 $contents = &process_environment(0, $env, $br_id, ''); 2939 } 2940 print STDOUT "\nOUT-C {$env $br_id}\n$contents\n" if ($VERBOSITY > 4); 2941 $this_env = join("", $before, $closures 2942 , $contents, &balance_tags(), $reopens ); 2943 $_=''; 2944 &write_warnings( 2945 "\n\\end{$env $br_id} not found (truncated at next section boundary).\n"); 2946 } else { 2947 $pattern = &escape_rx_chars($pattern); 2948 s/$pattern/$closures/; 2949 print "\nCannot find \\end{$env $br_id}\n"; 2950 $_ .= join('', &balance_tags(), $reopens) unless ($defenv); 2951 } 2952 if ($this_env =~ /$begin_env_rx|$begin_cmd_rx/) { 2953 $_ = $this_env . $_; 2954 } else { push (@processedE, $this_env) } 2955 } 2956 $_ = join('',@processedE) . $_; 2957 $tmp = $_; undef $_; 2958 &process_command($counters_rx, $tmp) if ($tmp =~ /$counters_rx/); 2959 $_ = $tmp; undef $tmp; 2960 $_ 2961} 2962 2963sub find_end_env { 2964 # MRO: find_end_env($env,$contents,$rest) 2965 #local ($env, *ref_contents, *rest) = @_; 2966 my $env = $_[0]; 2967 my $be_rx = &make_begin_end_env_rx($env); 2968 my $count = 1; 2969 2970 while ($_[2] =~ /($be_rx)(\n?)/s) { # $rest 2971 $_[1] .= $`; # $contents 2972 2973 if ($2 eq "begin") { ++$count } 2974 else { --$count }; 2975 2976 #include any final \n at an {end} only 2977 $_[2] = (($2 eq 'end')? $5 : '') . $'; # $rest 2978 last if $count == 0; 2979 2980 $_[1] .= $1; # $contents 2981 } 2982 2983 if ($count != 0) { 2984 $_[2] = join('', $_[1], $_[2]); # $rest = join('', $contents, $rest); 2985 $_[1] = ''; # $contents 2986 return(0) 2987 } else { return(1) } 2988} 2989 2990 2991sub process_group_env { 2992 local($contents) = @_; 2993 local(@save_open_tags) = @$open_tags_R; 2994 local($open_tags_R) = [ @save_open_tags ]; 2995 print STDOUT "\nIN::{group $br_id}" if ($VERBOSITY > 4); 2996 print STDOUT "\n:$contents\n" if ($VERBOSITY > 6); 2997 2998 # need to catch explicit local font-changes 2999 local(%font_size) = %font_size if (/\\font\b/); 3000 3001 # record class/id info for a style-sheet entry 3002 local($env_id, $tmp, $etmp); 3003 if (($USING_STYLES) && !$PREAMBLE ) { $env_id = $br_id; } 3004# $env_id = "grp$br_id"; 3005# $styleID{$env_id} = " "; 3006# $env_id = " ID=\"$env_id\""; 3007# } 3008 3009 undef $_; 3010 $contents =~ s/^\s*$par_rx\s*//s; # don't start with a \par 3011 if ($contents =~ /^\s*\\($image_switch_rx)\b\s*/s) { 3012 # catch TeX-like environments: {\fontcmd ... } 3013 local($image_style) = $1; 3014 if ($USING_STYLES) { 3015 $env_style{$image_style} = " " unless ($env_style{$image_style}); 3016 } 3017 local($switch_cmd) = "do_cmd_${image_style}"; 3018 if (defined &$switch_cmd ) { 3019 eval "\$contents = \&${switch_cmd}(\$')"; 3020 print "\n*** &$switch_cmd didn't work: $@\n$contents\n\n" if ($@); 3021 } elsif ($contents =~ /$par_rx/) { 3022 # split into separate image for each paragraph 3023 local($par_style,$this_par_img) = ''; 3024 local(@par_pieces) = split($par_rx, $contents); 3025 local($this_par,$par_style,$par_comment); 3026 $contents = ''; 3027 while (@par_pieces) { 3028 $this_par = shift @par_pieces; 3029 if ($this_par =~ /^\s*\\($image_switch_rx)\b/s) { 3030 $image_style = $1; 3031 $par_style = 'P.'.$1; 3032 $env_style{$par_style} = " " unless ($env_style{$par_style}); 3033 } 3034# no comment: source is usually too highly encoded to be meaningful 3035# $par_comment = &make_comment($image_style,$this_par); 3036 $this_par_img = &process_in_latex("\{".$this_par."\}"); 3037 $contents .= join('' #,"\n", $par_comment 3038 , "\n<P" 3039 , (($USING_STYLES && $image_style)? " CLASS=\"$image_style\"" :'') 3040 ,">", $this_par_img 3041 , "</P>\n"); 3042 if (@par_pieces) { 3043 # discard the pieces from matching $par_rx 3044 $dum = shift @par_pieces; 3045 $dum = shift @par_pieces; 3046 $dum = shift @par_pieces; 3047 $dum = shift @par_pieces; 3048 $dum = shift @par_pieces; 3049 $dum = shift @par_pieces; 3050# $contents .= "\n</P>\n<P>"; 3051 } 3052 } 3053 } else { 3054 $contents = &process_undefined_environment("tex2html_accent_inline" 3055 , ++$global{'max_id'},"\{".$contents."\}"); 3056 } 3057 } elsif ($contents =~ /^\s*\\(html)?url\b($O\d+$C)[^<]*\2\s*/) { 3058 # do nothing 3059 $contents = &translate_environments($contents); 3060 $contents = &translate_commands($contents); 3061 } elsif (($env_switch_rx)&&($contents =~ s/^(\s*)\\($env_switch_rx)\b//s)) { 3062 # write directly into images.tex, protected by \begingroup...\endgroup 3063 local($prespace, $cmd, $tmp) = ($1,$2,"do_cmd_$2"); 3064 $latex_body .= "\n\\begingroup "; 3065 if (defined &$tmp) { 3066 eval("\$contents = &do_cmd_$cmd(\$contents)"); 3067 } 3068 $contents = &translate_environments($contents); 3069 $contents = &translate_commands($contents); 3070 undef $tmp; undef $cmd; 3071 $contents .= "\n\\endgroup "; 3072 } elsif ($contents =~ /^\s*\\([a-zA-Z]+)\b/s) { 3073 local($after_cmd) = $'; 3074 local($cmd) = $1; $tmp = "do_cmd_$cmd"; $etmp = "do_env_$cmd"; 3075 if (($cmd =~/^(rm(family)?|normalsize)$/) 3076 ||($declarations{$cmd}&&(defined &$tmp))) { 3077 do{ 3078 local(@save_open_tags) = @$open_tags_R; 3079 eval "\$contents = \&$tmp(\$after_cmd);"; 3080 print "\n*** eval &$tmp failed: $@\n$contents\n\n" if ($@); 3081 $contents .= &balance_tags(); 3082 }; 3083 } elsif ($declarations{$cmd}&&(defined &$etmp)) { 3084 eval "\$contents = \&$etmp(\$after_cmd);"; 3085 } else { 3086 $contents = &translate_environments($contents); 3087 $contents = &translate_commands($contents) 3088 if ($contents =~ /$match_br_rx/o); 3089 # Modifies $contents 3090 &process_command($single_cmd_rx,$contents) if ($contents =~ /\\/o); 3091 } 3092 undef $cmd; undef $tmp; undef $etmp; 3093 } else { 3094 $contents = &translate_environments($contents); 3095 $contents = &translate_commands($contents) 3096 if ($contents =~ /$match_br_rx/o); 3097 # Modifies $contents 3098 &process_command($single_cmd_rx,$contents) 3099 if ($contents =~ /\\/o); 3100 } 3101 $contents . &balance_tags(); 3102} 3103 3104# MODIFIES $contents 3105sub process_environment { 3106 local($opt, $env, $id, $styles) = @_; 3107 print "PCT: process_environment: begin $opt, $env, $id, $styles\n" if ($VERBOSITY > 20) ; 3108 local($envS) = $env; $envS =~ s/\*\s*$/star/; 3109 local($env_sub,$border,$attribs,$env_id) = ("do_env_$envS",'','',''); 3110 local($original) = $contents; 3111 3112 if ($env =~ /tex2html_deferred/ ) { 3113 print "PCT: process_environment: tex2html_deferred\n" if ($VERBOSITY > 20) ; 3114 $contents = &do_env_tex2html_deferred($contents); 3115 return ($contents); 3116 } 3117 $env_id = &read_style_info($opt, $env, $id, $styles) 3118 if (($USING_STYLES)&&($opt)); 3119 3120 if (&defined_env($env)) { 3121 print "PCT: process_environment: env defined: $env\n" if ($VERBOSITY > 20) ; 3122 print STDOUT ","; 3123 print STDOUT "{$env $id}" if ($VERBOSITY > 1); 3124 # $env_sub =~ s/\*$/star/; 3125 print "PCT: process_environment: env sub: " . $env_sub . "\n" if ($VERBOSITY > 20) ; 3126 $contents = &$env_sub($contents); 3127 3128 } elsif ($env =~ /tex2html_nowrap/) { 3129 #pass it on directly for LaTeX, via images.tex 3130 print "PCT: process_environment: tex2html_nowrap\n" if ($VERBOSITY > 20) ; 3131 $contents = &process_undefined_environment($env, $id, $contents); 3132 return ($contents); 3133 3134# elsif (&special_env) { # &special_env modifies $contents 3135 } else { 3136 print "PCT: process_environment: else\n" if ($VERBOSITY > 20) ; 3137 local($no_special_chars) = 0; 3138 local($failed) = 0; 3139 local($has_special_chars) = 0; 3140 &special_env; # modifies $contents 3141 print STDOUT "\n<MATH $env$id $contents>" if ($VERBOSITY > 3); 3142 if ($failed || $has_special_chars) { 3143 $contents = $original; 3144 $failed = 1; 3145 print STDOUT " !failed!\n" if ($VERBOSITY > 3); 3146 } 3147 } 3148 if (($contents) && ($contents eq $original)) { 3149 print "PCT: process_environment: content...\n" if ($VERBOSITY > 20) ; 3150 if ($ignore{$env}) { return(''); } 3151 # Generate picture 3152 if ($contents =~ s/$htmlborder_rx//o) { 3153 $attribs = $2; $border = (($4)? "$4" : 1) 3154 } elsif ($contents =~ s/$htmlborder_pr_rx//o) { 3155 $attribs = $2; $border = (($4)? "$4" : 1) 3156 } 3157 $contents = &process_undefined_environment($env, $id, $contents); 3158 $env_sub = "post_latex_$env_sub"; # i.e. post_latex_do_env_ENV 3159 if ( defined &$env_sub) { 3160 $contents = &$env_sub($contents); 3161 } elsif (($border||($attributes))&&($HTML_VERSION > 2.1)) { 3162 $contents = &make_table($border,$attribs,'','','',$contents); 3163 } else { 3164 $contents = join('',"<BR>\n",$contents,"\n<BR>") 3165 unless (!($contents)||($inner_math)||($env =~ 3166 /^(tex2html_wrap|tex2html_nowrap|\w*math|eq\w*n)/o )); 3167 } 3168 } 3169 print "PCT: process_environment: contents: $contents\n" if ($VERBOSITY > 20) ; 3170 $contents; 3171} 3172 3173 3174#RRM: This reads the style information contained in the optional argument 3175# to the \begin command. It is stored to be recovered later as an entry 3176# within the automatically-generated style-sheet, if $USING_STYLES is set. 3177# Syntax for this info is: 3178# <style names> ; <extra style-info> 3179 3180sub read_style_info { 3181 local($opt, $envS, $id, $styles) = @_; 3182 return() unless (($opt)&&($USING_STYLES)); 3183 # allow macro-expansion within the style-info 3184 $opt = &translate_commands($opt) if ($opt =~ /\\/); 3185 3186 # record class/id info for a style-sheet entry 3187 local($style_names, $style_extra, $env_id)=(''," ",''); 3188 if ($opt) { 3189 # if there is a `;' then <names> ; <extra> 3190 if ($styles =~ /^\s*([^\|]*)\|\s*(.*)$/) { 3191 $style_names = $1; $style_extra = $2; 3192 if ($style_names =~ /[=:;]/) { 3193 # cannot be <names>, so is <extra> 3194 $style_extra = $style_names.$style_extra; 3195 $style_names = ''; 3196 } 3197 } elsif ($styles =~ /[\=\:]/) { 3198 # cannot be <names>, so is <extras> 3199 $style_extra = $styles; 3200 } else { $style_names = $styles } 3201 $style_extra =~ s/\s*[=:]\s*/ : /go; 3202 $style_extra =~ s/([\w,\-]+)\s+([\w,\-]+)/$1 ; $2/go; 3203 $style_extra =~ s/\s*,\s*/ /go; 3204 3205 if ($style_names) { 3206 local($sname); 3207 local(@names) = split ( /\s+/ , $style_names ); 3208 # ensure a style-sheet entry for each new name 3209 foreach $sname (@names) { 3210 $env_style{$sname} = " " 3211 unless (($env_style{$sname})||($sname =~ /^\s*$/)); 3212 } 3213 } 3214 } 3215 # remove uninformative part of internally-defined env names 3216 $envS =~ s/tex2html_(\w+_)?(\w+)/$2/; $envS =~ s/preform/pre/; 3217 $env_id = $envS.$id; 3218 $styleID{$env_id} = $style_extra unless ($PREAMBLE); 3219 3220 if ($style_names) { $envS = "$style_names" } 3221 elsif (($envS =~ /^pre$/)&& 3222 (/^\\begin.*preform($O|$OP)\d+($C|$CP)$verbatim_mark(\w*[vV]erbatim)(\*?)/)) 3223 { $envS = $3.($4 ? 'star' : '') }; 3224 $env_style{$envS} = " " unless (($style_names)||($env_style{$envS})); 3225 $env_id = " ID=\"$env_id\"".(($envS) ? " CLASS=\"$envS\"" : ''); 3226 return($env_id); 3227} 3228 3229# RRM: This provides the mechanism to save style information in %env_style 3230# using LaTeX macros \htmlsetstyle and \htmladdtostyle 3231# 3232sub process_htmlstyles { 3233 local($mode, $_) = @_; 3234 local($pre_tags) = &get_next_optional_argument; 3235 local($class) = &missing_braces unless ( 3236 (s/$next_pair_pr_rx/$class = $2;''/e) 3237 ||(s/$next_pair_rx/$class = $2;''/e)); 3238 local($sinfo) = &missing_braces unless ( 3239 (s/$next_pair_pr_rx/$sinfo = $2;''/e) 3240 ||(s/$next_pair_rx/$sinfo = $2;''/e)); 3241 return ($_) unless ($class||$pre_tags); 3242 3243 $class = $pre_tags.($class ?'.':'').$class; 3244 $sinfo =~ s/\s*[:=]\s*/ : /g; 3245 $sinfo =~ s/\s*,\s*/ /g; 3246 if ($mode =~ /add/) { 3247 $sinfo = '; '.$sinfo if ($env_style{$class}); 3248 $env_style{$class} .= $sinfo; 3249 } else { $env_style{$class} = $sinfo } 3250 $_; 3251} 3252sub do_cmd_htmlsetstyle { &process_htmlstyles('set',@_) } 3253sub do_cmd_htmladdtostyle { &process_htmlstyles('add',@_) } 3254 3255 3256# The $<$, $>$, $|$ and $=>$, etc strings are replaced with their textual 3257# equivalents instead of passing them on to latex for processing in math-mode. 3258# This will not be necessary when the mechanism for passing environments 3259# to Latex is improved. 3260# RETURNS SUCCESS OR FAILURE 3261sub special_env { 3262 # Modifies $contents in its caller 3263 local($next)=''; 3264 local ($allow) = $HTML_VERSION ge '3.0' ? 3265 "[^#\$%&~\\\\\{\}]|\\limits" : "[^^#\$%&~_\\\\\{\}]"; 3266 #JKR: Use italics instead of bold #HWS: Generalize to include more symbols. 3267# $contents =~ s/^\$(\s*($html_specials_inv_rx|$allow)*\s*)\$(.)?/ 3268# $next=$3;&simple_math_env($1).(($next =~ m|\w|)? " ":'').$next/ige; 3269 $contents =~ s/^\$(\s*($html_specials_inv_rx|$allow)*\s*)\$$/ 3270 &simple_math_env($1)." "/ige; 3271 if ($contents =~ /\&\w*;/) { $has_math_chars=1 } 3272 if ($contents =~ /;SPM([a-zA-Z]+);/) { $has_special_chars=1 }; 3273} 3274 3275# Translate simple math environments into italic. 3276# Only letters should become italic; symbols should stay non-italic. 3277sub simple_math_env { 3278 local($mathcontents) = @_; 3279 if ($mathcontents eq '') { return("$mathcontents"); } 3280 elsif ($NO_SIMPLE_MATH) { # always make an image 3281 $failed = 1; return($mathcontents); 3282 } elsif ($mathcontents =~ /\\/) { # any macro kills "simple-math" 3283 local($save_math) = $mathcontents; 3284 local(@text_only) = (); 3285 while ((!$failed)&&($mathcontents =~ 3286 /\\((boldsymbol|bm)|(math|text)(bf|rm|it|tt)|times|[{}@#^_])(\b|[^A-Za-z]|$)/)) { 3287 # ...except when only simple styles 3288 push (@text_only, $`, ("$2$4" ? "\\simplemath".($4 ? $4 :"bf") :"\\$1") ); 3289 $mathcontents = $5.$'; 3290 $failed = 1 if ($` =~ /\\/); 3291 } 3292 $failed = 1 if ($mathcontents =~ /\\/); 3293 return($save_math) if $failed; 3294 $mathcontents = join('',@text_only,$mathcontents); 3295 } 3296 # Is there a problem here, with nested super/subscripts ? 3297 # Yes, so do each pattern-match for bracketings within a while-loop 3298 while ($mathcontents =~ s/\^$any_next_pair_rx/<SUP>$2<\/SUP>/go){}; 3299 while ($mathcontents =~ s/\^$any_next_pair_pr_rx/<SUP>$2<\/SUP>/go){}; 3300 while ($mathcontents =~ s/_$any_next_pair_rx/<SUB>$2<\/SUB>/g){}; 3301 while ($mathcontents =~ s/_$any_next_pair_pr_rx/<SUB>$2<\/SUB>/g){}; 3302 3303 $mathcontents =~ s/\^(\\[a-zA-Z]+|.)/<SUP>$1<\/SUP>/g; 3304 $mathcontents =~ s/_(\\[a-zA-Z]+|.)/<SUB>$1<\/SUB>/g; 3305 $mathcontents =~ s/(^|\s|[,;:'\?\.\[\]\(\)\+\-\=\!>]|[^\\<]\/|\d)(<(I|TT|B)>)?([a-zA-Z]([a-zA-Z ]*[a-zA-Z])?)(<\/\3>)?/ 3306 $1.(($2)? $2 :'<I>').$4.(($6)? $6 : '<\/I>')/eig; 3307 3308 $mathcontents =~ s/\\times($|\b|[^A-Za-z])/ x $1/g; 3309 $mathcontents =~ s/\\times($|\b|[^A-Za-z])/ x $1/g; 3310 $mathcontents =~ s/\\\\/<BR>\n/g; 3311 $mathcontents =~ s/\\\\/<BR>\n/g; 3312 $mathcontents =~ s/\\([,;])/ /g; 3313 $mathcontents =~ s/\\(\W)/$1/g; 3314 $mathcontents =~ s/ {2,}/ /g; 3315 3316 # any simple style changes remove enclosed <I> tags 3317 $mathcontents = &translate_commands($mathcontents) 3318 if ($mathcontents =~ /\\/); 3319 3320 $mathcontents =~ s/<I><\/(SUB|SUP)>/<\/$1><I>/g; 3321 $mathcontents =~ s/<(SUB|SUP)><\/I>/<\/I><$1>/g; 3322 $mathcontents =~ s/;<I>SPM([a-zA-Z]+)<\/I>;/;SPM$1;/go; 3323 $mathcontents =~ s/<(\/?)<I>(SUB|SUP|I|B|TT)<\/I>>/<$1$2>/g; 3324 $mathcontents =~ s/<\/(B|I|TT)><\1>//g; 3325 $mathcontents; 3326} 3327 3328sub do_cmd_simplemathrm { 3329 local ($_) = @_; 3330 local($text); 3331 $text = &missing_braces unless ( 3332 (s/$next_pair_pr_rx/$text = $2;''/e) 3333 ||(s/$next_pair_rx/$text = $2;''/e)); 3334 $text =~ s/<\/?I>//g; 3335 join('', $text, $_) 3336} 3337sub do_cmd_simplemathbf { 3338 local ($_) = @_; 3339 local($text); 3340 $text = &missing_braces unless ( 3341 (s/$next_pair_pr_rx/$text = $2;''/e) 3342 ||(s/$next_pair_rx/$text = $2;''/e)); 3343 $text =~ s/<\/?I>//g; 3344 join('','<B>', $text, '</B>', $_) 3345} 3346sub do_cmd_simplemathtt { 3347 local ($_) = @_; 3348 local($text); 3349 $text = &missing_braces unless ( 3350 (s/$next_pair_pr_rx/$text = $2;''/e) 3351 ||(s/$next_pair_rx/$text = $2;''/e)); 3352 $text =~ s/<\/?I>//g; 3353 join('','<TT>', $text, '</TT>', $_) 3354} 3355 3356sub process_math_in_latex { 3357 local($mode,$style,$level,$math) = @_; 3358 local(@anchors); 3359 if ($level) { 3360 $style = (($level > 1) ? "script" : "") . "script"; 3361 } elsif (! $style) { 3362 $style = (($mode =~/display|equation/)? "display" : "") 3363 } 3364 $style = "\\${style}style" if ($style); 3365 3366 # &process_undefined_environment changes $_ , so save it. 3367 local($after) = $_; 3368 3369 # the 'unless' catches nested AMS-aligned environments 3370 $mode = "tex2html_wrap_" . 3371 (($mode =~/display|equation|eqnarray/) ? 'indisplay' : 'inline') 3372 unless ($mode =~ /^equationstar/ && $outer_math =~ /^equationstar/); 3373 3374 $global{'max_id'}++; 3375 $math =~ s/\\(\n|$)/\\ $1/g; # catch \ at end of line or string 3376 $math =~ s/^\s*((\\!|;SPMnegsp;)\s*)*//g; # remove neg-space at start of string 3377 if ($mode =~ /tex2html_wrap_/ ) { 3378 $math = &process_undefined_environment( $mode 3379 , $global{'max_id'}, join('', "\$$style ", $math, "\$")); 3380 } else { 3381 # some AMS environments must be within {equation} not {displaymath} 3382 $math =~ s/displaymath/equation*/ 3383 if ($math =~ /\\begin\{(x+|fl)*align/); 3384 $math = &process_undefined_environment($mode, $global{'max_id'}, $math); 3385 } 3386 $math .= "\n" if ($math =~ /$comment_mark\s*\d+$/s); 3387 $_ = $after; 3388 # the delimiter \001 inhibits an unwanted \n at image-replacement 3389 $math . ($math =~ /$image_mark/? "\001" : ''); 3390} 3391 3392#RRM: Explicit font switches need images. Use the image_switch mechanism. 3393sub do_cmd_font { 3394 local($_) = @_; 3395 local($fontinfo,$fontname,$size) = ('','','10pt'); 3396 s/\s*\\(\w+)\s*=?\s*(.*)(\n|$)/$fontname=$1;$fontinfo=$2;''/eo; 3397 $image_switch_rx .= "|$fontname"; 3398 3399 if ($fontinfo =~ /([.\d]+\s*(true)?(pt|mm|cm))/ ) { $size = $1 } 3400 elsif ( $fontinfo =~ /[a-zA-Z]+(\d+)\b/ ) { $size = $1.'pt' } 3401 if ( $fontinfo =~ /(scaled|at)\s*\\?(.+)/) { $size .= " scaled $1" } 3402 $font_size{$fontname} = $size; 3403 $_; 3404} 3405sub wrap_cmd_font { 3406 local($cmd, $_) = @_; 3407 local ($args, $dummy, $pat) = ""; 3408 if (/\n/) { $args .= $`.$& ; $_ = $' } else {$args = $_; $_ = ''}; 3409 (&make_deferred_wrapper(1).$cmd.$padding.$args.&make_deferred_wrapper(0),$_) 3410} 3411 3412sub do_cmd_newfont { 3413 local($_) = @_; 3414 local($fontinfo,$fontname,$size) = ('','','10pt'); 3415 $fontname = &missing_braces unless ( 3416 (s/$next_pair_pr_rx/$fontname=$2;''/eo) 3417 ||(s/$next_pair_rx/$fontname=$2;''/eo)); 3418 $fontname=~ s/^\s*\\|\s*$//g; 3419 $image_switch_rx .= "|$fontname"; 3420 3421 $fontinfo = &missing_braces unless ( 3422 (s/$next_pair_pr_rx/$fontinfo=$2;''/eo) 3423 ||(s/$next_pair_rx/$fontinfo=$2;''/eo)); 3424 if ($fontinfo =~ /([.\d]+\s*(true)?(pt|mm|cm))/ ) { $size = $1 } 3425 elsif ( $fontinfo =~ /[a-zA-Z]+(\d+)\b/ ) { $size = $1.'pt' } 3426 if ( $fontinfo =~ /(scaled|at)\s*\\?(.+)/) { $size .= " scaled $1" } 3427 $font_size{$fontname} = $size; 3428 $_; 3429} 3430 3431sub defined_env { 3432 local($env) = @_; 3433 $env =~ s/\*$/star/; 3434 local($env_sub) = ("do_env_$env"); 3435 # The test using declarations should not be necessary but 'defined' 3436 # doesn't seem to recognise subroutines generated dynamically using 'eval'. 3437 # Remember that each entry in $declarations generates a dynamic prodedure ... 3438 ((defined &$env_sub) || ($declarations{$env})); 3439} 3440 3441# RRM: utility to add style information to stored image-parameters 3442# currently only (math) scaling info is included; 3443# current color, etc. could also be added here. 3444sub addto_encoding { 3445 local($env, $contents) = @_; 3446# $contents =~ s/(\\(begin|end)\s*)?<<\d*>>|\n//g; # RRM: remove env delimiters 3447 $contents =~ s/(\\(begin|end)\s*(<<\d*>>))|\n//g; # RRM: remove env delimiters 3448 # append scaling information for environments using it 3449 if (($MATH_SCALE_FACTOR) 3450 &&(($contents =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/) 3451 ||($env =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/)) 3452 ) { $contents .= ";MSF=$MATH_SCALE_FACTOR" } 3453 3454 if ($LATEX_FONT_SIZE =~ /([\d\.]+)pt/) { 3455 local($fsize) = $1; 3456 $contents .= ";LFS=$fsize" unless ($fsize ==10); 3457 } 3458 3459 if (($EXTRA_IMAGE_SCALE) 3460 &&(($contents =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/) 3461 ||($env =~ /makeimage|inline|indisplay|entity|displaymath|eqnarray|equation|xy|diagram/)) 3462 ) { $contents .= ";EIS=$EXTRA_IMAGE_SCALE" } 3463 3464 if (($DISP_SCALE_FACTOR) 3465 &&(($contents =~ /indisplay|displaymath|eqnarray|equation/) 3466 ||($env =~ /indisplay|displaymath|eqnarray|equation/)) 3467 &&!(($contents =~ /makeimage/)||($env =~ /makeimage/)) 3468 ) { $contents .= ";DSF=$DISP_SCALE_FACTOR" } 3469 3470 if (($EQN_TAGS) 3471 &&(($env =~ /eqnarray($|[^_\*])|equation/) 3472 ||($contents =~ /eqnarray($|[^_\*])|equation/)) 3473 &&!(($contents =~ /makeimage/)||($env =~ /makeimage/)) 3474 ) { $contents .= ";TAGS=$EQN_TAGS" } 3475 3476 if (($FIGURE_SCALE_FACTOR) 3477 &&!(($contents =~ /makeimage/)||($env =~ /makeimage/)) 3478 &&(($contents =~ /figure/)||($env =~ /figure/)) 3479 ) { $contents .= ";FSF=$FIGURE_SCALE_FACTOR"} 3480 3481 if (($ANTI_ALIAS) 3482 &&(($contents =~ /figure/)||($env =~ /figure/)) 3483 &&!(($contents =~ /makeimage/)||($env =~ /makeimage/)) 3484 ) { $contents .= ";AAF" } 3485 elsif ($ANTI_ALIAS_TEXT) { $contents .= ";AAT" } 3486 if (!$TRANSPARENT_FIGURES) { $contents .= ";NTR" } 3487 3488 $contents; 3489} 3490 3491sub process_undefined_environment { 3492 local($env, $id, $contents) = @_; 3493 if ($env =~ s/\*{2,}/*/) { print "\n*** $_[0] has too many \*s ***"}; 3494 3495 local($name,$cached,$raw_contents,$uucontents) = ("$env$id"); 3496 $name =~ s/\*/star/; 3497 local($oldimg,$size,$fullcontents,$imgID); 3498 return if ($AUX_FILE); 3499 3500 # catch \footnotemark within an image, especially if in math 3501 local(@foot_anchors,$foot_anchor); 3502 local($im_footnote,$im_mpfootnote) = ($global{'footnote'},$global{'mpfootnote'}); 3503 @foot_anchors = &process_image_footnote($contents) 3504 if ($contents =~ /\\footnote(mark)?\b/s); 3505 if ((@foot_anchors)&&($eqno)) { 3506 # append the markers to the equation-numbers 3507 $eqno .= join(' ', ' ', @foot_anchors); 3508 @foot_anchors = (); 3509 } 3510 3511 print STDOUT "\nUNDEF-IN {$env $id}:\n$contents\n" if ($VERBOSITY > 4); 3512 #RRM - LaTeX commands wrapped with this environment go directly into images.tex. 3513 if ($env =~ /tex2html_nowrap|^lrbox$/){ # leave off the wrapper, do not cache 3514 # totally ignore if in preamble... 3515 # ...since it will be put into images.tex anyway!! 3516 if (!($PREAMBLE)) { 3517 $contents =~ s/^\n+|\n+$/\n/g; 3518 local($lcontents) = join('', "\\begin{$env}", $contents , "\\end{$env}" ); 3519 $lcontents =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg; 3520 print STDOUT "pre-LATEX {$env}:\n$lcontents\n" if ($VERBOSITY > 3); 3521 $raw_contents = &revert_to_raw_tex($lcontents); 3522 print STDOUT "LATEX {$env}:\n$raw_contents\n" if ($VERBOSITY > 3); 3523 $latex_body .= "\n$raw_contents"."%\n\n" ; 3524 } 3525 return("") if ($env =~ /^lrbox/); 3526 # ignore enclosed environments; e.g. in \settolength commands 3527# $contents = &translate_environments($contents); # ignore environments 3528# $contents = &translate_commands($contents); 3529 # ...but apply any Perl settings that may be defined 3530 $contents = &process_command($single_cmd_rx,$contents); 3531 print STDOUT "\nOUT {$env $id}:\n$contents\n" if ($VERBOSITY > 4); 3532 return(""); 3533 } 3534 # catch pre-processor environments 3535 if ($PREPROCESS_IMAGES) { 3536 local($pre_env,$which, $done, $indic); 3537 while ($contents =~ /$pre_processor_env_rx/) { 3538 $done .= $`; $pre_env = $5; $which =$1; $contents = $'; 3539 if (($which =~ /begin/)&&($pre_env =~ /indica/)) { 3540 if ($contents =~ s/^\[(\w+)]//o) { $done .= '#'.$1 } 3541 } elsif (($which =~ /end/)&&($pre_env =~ /indica/)) { 3542 $done .= '#NIL'; 3543 } elsif (($which =~ /begin/)&&($pre_env =~ /itrans/)) { 3544 if ($contents =~ s/^\[(\w+)]/$indic=$1;''/e) 3545 { $done .= "\#$indic" } 3546 } elsif (($which =~ /end/)&&($pre_env =~ /itrans/)) { 3547 $done .= "\#end$indic"; 3548 } elsif ($which =~ /begin/) { 3549 $done .= (($which =~ /end/)? $end_preprocessor{$pre_env} 3550 : $begin_preprocessor{$pre_env} ) 3551 } 3552 } 3553 $contents = $done . $contents; 3554 } 3555 $fullcontents = $contents; # save for later \label search. 3556 # MRO: replaced $* with /m 3557 $contents =~ s/\n?$labels_rx(\%([^\n]+$|$EOL))?/\n/gm; 3558 3559 local($tmp) = $contents; 3560 $tmp =~ s/^((\\par|\%)?\s*\n)+$//g; 3561 return( &do_labels($fullcontents, "\ ") ) unless $tmp; 3562 3563 # just a comment as the contents of a cell in a math-display 3564 if ($tmp =~ /\$\\(display|text|(script)+)style\s*$comment_mark\d+\s*\$$/) 3565 { return ( &do_labels($fullcontents, "\ ") ) }; 3566 3567 $contents = "\n% latex2html id marker $id\n$contents" if 3568 (!$PREAMBLE &&($contents =~ /$order_sensitive_rx/) 3569 &&(!($env =~ /makeimage/))); 3570 3571 $env =~ s/displaymath/equation*/ 3572 if ($contents =~ /\\begin\{(x+|fl)*align/); 3573 #RRM: include the inline-color, when applicable 3574 $contents = join('' 3575 , (($inner_math =~ /in(display|line)/) ? '$' : '') 3576 , "\\begin{$env}" 3577 , ($color_env ? "\\bgroup\\$color_env" : '') 3578 , $contents , ($color_env ? "\\egroup" : '') 3579 , "\\end{$env}" 3580 , (($inner_math =~ /in(display|line)/) ? '$' : '') 3581 ) if ($contents); 3582 3583 # append to the name of special environments found within math 3584 if ($inner_math) { 3585 local($ext) = $inner_math; 3586 if ($inner_math =~ /(display|line)/){ $ext = 'in'.$1;}; 3587 $name =~ s/(\d+)$/_$ext$1/; 3588 } 3589 3590 if (!($latex_body{$name} = $contents)) { 3591 print "\n *** code for $name is too long ***\n"} 3592 if ($contents =~ /$htmlimage_rx/) { 3593 $uucontents = &special_encoding($env,$2,$contents); 3594 } elsif ($contents =~ /$htmlimage_pr_rx/) { 3595 $uucontents = &special_encoding($env,$2,$contents); 3596 } else { 3597 $uucontents = &encode(&addto_encoding($env,$contents)); 3598 } 3599 $cached = $cached_env_img{$uucontents}; 3600 print STDOUT "\nCACHED: $uucontents:\n$cached\n" if ($VERBOSITY > 4); 3601 if ($NOLATEX) { 3602 $id_map{$name} = "[$name]"; 3603 } elsif (defined ($_ = $cached)) { # Is it in our cache? 3604 # Have we already used it? 3605 if (($oldimg) = /SRC="$PREFIX$img_rx\.$IMAGE_TYPE"/o) { 3606 # No, check its size 3607 local($eis) = 1; 3608 # Does it have extra scaling ? 3609 if ($uucontents =~ /EIS=(.*);/) { $eis = $1 } 3610 ($size, $imgID) = &get_image_size("$PREFIX$oldimg.old", $eis); 3611 # Does it have extra scaling ? 3612# if ($uucontents =~ /EIS=(.*);/) { 3613# local($eis) = $1; local($w,$h); 3614# # quotes will not be there with HTML 2.0 3615# $size =~ s/(WIDTH=\")(\d*)(\".*HEIGHT=\")(\d*)\"/ 3616# $w = int($2\/$eis + .5); $h=int($4\/$eis + .5); 3617# "$1$w$3$h\""/e ; # insert the re-scaled size 3618# } 3619 # quotes will not be there with HTML 2.0 3620 $size =~ s/\"//g if ($HTML_VERSION < 2.2); 3621 if ($size && /\s$size\s/) { 3622 # Size is OK; recycle it! 3623 ++$global_page_num; 3624 $_ = $cached ; # ...perhaps restoring the desired size. 3625 s/(${PREFIX}T?img)\d+\.($IMAGE_TYPE|html)/ 3626 &rename_html($&,"$1$global_page_num.$2")/geo; 3627 } else { 3628 if ($env =~ /equation/) { &extract_eqno($name,$cached) } 3629 $_ = ""; # The old Image has wrong size! 3630 undef($cached); # (or it doesn't exist) 3631 } 3632 } 3633 s/(IMG\n)/$1$imgID/ if $imgID; 3634 3635 s/$PREFIX$img_rx\.new/$PREFIX$1.$IMAGE_TYPE/go; # Point to the actual image file(s) 3636 $id_map{$name} = $_; 3637 s/$PREFIX$img_rx\.$IMAGE_TYPE/$PREFIX$1.new/go; # But remember them as used. 3638 $cached_env_img{$uucontents} = $_; 3639 } 3640 3641 if (! defined($cached)) { # Must generate it anew. 3642 &clear_images_dbm_database 3643 unless ($new_page_num ||($NO_SUBDIR && $FIXEDDIR)); 3644 $new_id_map{$name} = $id_map{$name} = ++$global_page_num . "#" . 3645 ++$new_page_num; 3646 $orig_name_map{$id_map{$name}} = $name; 3647 $cached_env_img{$uucontents} = $id_map{$name} if ($REUSE == 2); 3648 3649 #RRM: this (old) code frequently crashes NDBM, so do it in 2 steps 3650# $img_params{$name} = join('#', &extract_parameters($contents)); 3651 local(@params) = &extract_parameters($contents); 3652 $img_params{$name} = join('#',@params); undef $params; 3653 print "\nIMAGE_PARAMS $name: ".$img_params{$name} if ($VERBOSITY > 3); 3654 3655 $contents =~ s/\\(index|label)\s*(($O|$OP)\d+($C|$CP)).*\2//sg; 3656 print STDOUT "\nLATEX {$env}:\n$contents" if ($VERBOSITY > 3); 3657 $raw_contents = &revert_to_raw_tex($contents) unless ($contents =~ /^\s*$/) ; 3658 $raw_contents =~ s/\\pagebreak|\\newpage|\\clearpage/\\\\/go; 3659 print STDOUT "\nLATEX {$env}:\n$raw_contents\n" if ($VERBOSITY > 3); 3660 local($box_type) = ''; 3661 if ($raw_contents =~ /\\special\s*\{/) { 3662 $tex_specials{$name} = "1"; 3663 &write_warnings("\nenvironment $name contains \\special commands"); 3664 print STDOUT "\n *** environment $name contains \\special commands ***\n" 3665 if ($VERBOSITY); 3666 } elsif (($env =~ /$inline_env_rx/)||($inner_math =~ /in(line|display)/)) { 3667 # crop to the marks only... or shave a bit off the bottom 3668 if (($env =~ /tex2html_[^w]/)||$inner_math) { 3669 # e.g. accents, indic but not wrap 3670 $crop{$name} = "bl"; 3671 $box_type = "i"; 3672 } else { 3673 # ...or shave a bit off the bottom as well 3674 $crop{$name} = "bls"; 3675 $box_type = "h"; 3676 } 3677 } elsif (($env =~ /(eqnarray|equation)(\*|star)/)||($inner_math)) { 3678 # crop to minimum size... 3679 $crop{$name} = "blrl"; 3680 $box_type = "v"; 3681 } elsif ($env =~ /(picture|tex2html_wrap)(\*|star)?/) { 3682 # crop hbox to minimum size... 3683 $crop{$name} = ""; 3684 $box_type = "p"; 3685 } elsif ($env =~ /$display_env_rx/) { 3686 # crop vbox to minimum size... 3687 $crop{$name} = "blrl" ; 3688 if ($env =~ /(equation|eqnarray)((s)?$|\d)/) { 3689 # ... unless equation numbers are included ... 3690 if ($3) { # AMS {subequations} 3691 $global{'eqn_number'}=$prev_eqn_number if $prev_eqn_number; 3692 --$global{'eqn_number'}; 3693 } 3694 $raw_contents = join('' , 3695 (($eqno{$name}||$global{'eqn_number'})? 3696 &set_equation_counter($eqno{$name}) : '') 3697 , $raw_contents); 3698 $crop{$name} = "bl" ; 3699 } elsif ($HTML_VERSION < 2.2) { 3700 # ... HTML 2.0 cannot align images, so keep the full typeset width 3701 $crop{$name} = "bl" ; 3702 } 3703 $box_type = "v"; 3704 } 3705 3706 #RRM: include the TeX-code for the appropriate type of box. 3707 eval "\$raw_contents = \&make_$box_type"."box($name, \$raw_contents);"; 3708 3709 # JCL(jcl-pag) - remember html text if debug is set. 3710 local($_); 3711 if ($DEBUG) { 3712 $_ = $contents; 3713 s/\n/ /g; 3714 $_ = &revert_to_raw_tex($_); 3715 # incomplete or long commented code can break pre-processors 3716 if ($PREPROCESS_IMAGES) { 3717 $_ = ((/^(\\\w+)?\{[^\\\}\<]*\}?/)? $& : '').'...' ; 3718 $_ = '{ ... }' if ( length($_) > 100); 3719 } elsif ( length($_) > 200) { 3720 $_ = join('',substr($_,0,200),"...\}"); 3721 } 3722 s/\\(begin|end)/$1/g; s/[\000-\020]//g; 3723 $_ = join('',"% contents=",$_,"\n"); 3724 } 3725 $raw_contents = '\setcounter{equation}{'.$prev_eqn_number."}\n".$raw_contents 3726 if ($env =~ /subequations/); 3727 3728# JCL(jcl-pag) - build the page entries for images.tex: Each page is embraced to 3729# let most statements have only local effect. Each page must compile into a 3730# single dvi page to get proper image translation. Hence the invisible glue to 3731# get *at least* one page (raw_contents alone might not wield glue), and 3732# sufficing page length to get *exactly* one page. 3733# 3734 $latex_body .= "{\\newpage\\clearpage\n$_" . 3735# "$raw_contents\\hfill\\vglue1pt\\vfill}\n\n"; 3736# "$raw_contents\\hfill\\vss}\n\n" if ($raw_contents); 3737# "$raw_contents\\hfill\\lthtmlcheckvsize\\clearpage}\n\n" if ($raw_contents); 3738 "$raw_contents\\lthtmlcheckvsize\\clearpage}\n\n" if ($raw_contents); 3739 } 3740 print STDOUT "\nIMAGE_CODE:{$env $id}:\n$raw_contents\n" if ($VERBOSITY > 4); 3741 3742 # Anchor the labels and put a marker in the text; 3743 local($img) = &do_labels($fullcontents,"$image_mark#$name#"); 3744 print STDOUT "\nUNDEF_OUT {$env $id}:\n$img\n" if ($VERBOSITY > 4); 3745 return($img) unless (@foot_anchors); 3746 3747 # use the image as source to the 1st footnote, unless it is already an anchor. 3748 if ($img =~ /<\/?A>/) { 3749 join(' ', $img, @foot_anchors); 3750 } elsif ($#foot_anchors ==0) { 3751 $foot_anchor = shift @foot_anchors; 3752 $foot_anchor =~ s/<SUP>.*<\/SUP>/$img/; 3753# join(' ', $foot_anchor, @foot_anchors); 3754 $foot_anchor; 3755 } else { 3756 join(' ', $img, @foot_anchors); 3757 } 3758} 3759 3760sub special_encoding { # locally sets $EXTRA_IMAGE_SCALE 3761 local($env,$_,$contents) = @_; 3762 local($exscale) = /extrascale=([\.\d]*)/; 3763 local($EXTRA_IMAGE_SCALE) = $exscale if ($exscale); 3764 &encode(&addto_encoding($env,$contents)); 3765} 3766 3767 3768sub extract_eqno{ 3769 local($name,$contents) = @_; 3770 if ($contents =~ /<P ALIGN="\w+">\(([^<>])\)<\/P>$/) { 3771 if (($eqno{$name})&&!($eqno{$name} eq $1)) { 3772 &write_warnings("\nequation number for $name may be wrong.")}; 3773 $eqno{$name}="$1"; 3774 } 3775} 3776sub set_equation_counter{ 3777 if ( $global{'eqn_number'}) { 3778 "\\setcounter{equation}{". $global{'eqn_number'} ."}\n" 3779 } else { "\\setcounter{equation}{0}\n" } 3780} 3781 3782# RRM: 3 different types of boxing, for image environments. 3783 3784# general environments --- crops to width & height 3785sub make_box { 3786 local($id,$contents) = @_; 3787 "\\lthtmlfigureA{". $id ."}%\n". $contents ."%\n\\lthtmlfigureZ\n"; 3788} 3789 3790# inline math --- horizontal mode, captures height/depth + \mathsurround 3791sub make_hbox { 3792 local($id,$contents) = @_; 3793 if ($id =~ /indisplay/) { 3794 "\\lthtmlinlinemathA{". $id ."}%\n". $contents ."%\n\\lthtmlindisplaymathZ\n"; 3795 } else { 3796 "\\lthtmlinlinemathA{". $id ."}%\n". $contents ."%\n\\lthtmlinlinemathZ\n"; 3797 } 3798} 3799 3800# inline text-image (e.g. accents) --- horizontal mode, captures height/depth 3801sub make_ibox { 3802 local($id,$contents) = @_; 3803 "\\lthtmlinlineA{". $id ."}%\n". $contents ."%\n\\lthtmlinlineZ\n"; 3804} 3805 3806# centered images (e.g. picture environments) --- horizontal mode 3807sub make_pbox { 3808 local($id,$contents) = @_; 3809 "\\lthtmlpictureA{". $id ."}%\n". $contents ."%\n\\lthtmlpictureZ\n"; 3810} 3811 3812# displayed math --- vertical mode, captures height/depth + page-width 3813sub make_vbox { 3814 local($id,$contents) = @_; 3815 if (($HTML_VERSION >=3.2)&&($id =~/(equation|eqnarray)($|\d)/) &&! $failed ) { 3816 if ($contents =~ s/^\\setcounter\{equation\}\{\d+\}/$&%\n\\lthtmldisplayB\{$id\}%/) 3817 { $contents ."%\n\\lthtmldisplayZ\n" } 3818 else { "\\lthtmldisplayB{$id}%\n". $contents ."%\n\\lthtmldisplayZ\n" } 3819 } else { "\\lthtmldisplayA{$id}%\n". $contents ."%\n\\lthtmldisplayZ\n"} 3820} 3821 3822sub preprocess_images { 3823 do { 3824 print "\nWriting image.pre file ...\n"; 3825 open(ENV,">.$dd${PREFIX}images.pre") 3826 || die "\nCannot write '${PREFIX}images.pre': $!\n"; 3827 print ENV &make_latex($latex_body); 3828 print ENV "\n"; 3829 close ENV; 3830 ©_file($FILE, "bbl"); 3831 ©_file($FILE, "aux"); 3832 local($num_cmds, $cnt, $this, @cmds); 3833 @cmds = (split ('\n', $preprocessor_cmds)); 3834 $this_cmd = $num_cmds = 1+$#cmds; 3835 $cnt = $num_cmds; $preprocessor_cmds = ''; 3836 while (@cmds) { 3837 $this_cmd = shift @cmds; last unless ($this_cmd); 3838 $this_cmd =~ s/.pre /.tex$cnt / if(($cnt)&&($cnt < $num_cmds)); 3839 $cnt--; $this_cmd .= $cnt if ($cnt); 3840 $preprocessor_cmds .= $this_cmd."\n"; 3841 L2hos->syswait($this_cmd); 3842 } 3843 # save pre-processor commands in a file: preproc 3844 open(CMDS,">.$dd${PREFIX}preproc") 3845 || die "\nCannot write '${PREFIX}preproc': $!\n"; 3846 print CMDS $preprocessor_cmds ; 3847 close CMDS; 3848 3849 } if ((%latex_body) && ($latex_body =~ /newpage/)); 3850} 3851sub make_image_file { 3852 do { 3853 print "\nWriting image file ...\n"; 3854 open(ENV,">.$dd${PREFIX}images.tex") 3855 || die "\nCannot write '${PREFIX}images.tex': $!\n"; 3856 print ENV &make_latex($latex_body); 3857 print ENV "\n"; 3858 close ENV; 3859 ©_file($FILE, "bbl"); 3860 ©_file($FILE, "aux"); 3861 } if ((%latex_body) && ($latex_body =~ /newpage/)); 3862} 3863 3864sub make_latex_images{ 3865 &close_dbm_database if $DJGPP; 3866 local($dd) = $dd; $dd = '/' if ($dd eq "\\"); 3867 local($latex_call) = "$LATEX .$dd${PREFIX}images.tex"; 3868 print "$latex_call\n" if (($DEBUG)||($VERBOSITY > 1)); 3869 L2hos->syswait($latex_call); 3870 &open_dbm_database if $DJGPP; 3871} 3872 3873sub make_off_line_images { 3874 local($name, $page_num); 3875 if (!$NOLATEX && -f ".${dd}${PREFIX}images.tex") { 3876 &make_tmp_dir; # sets $TMPDIR and $DESTDIR 3877 $IMAGE_PREFIX =~ s/^_//o if ($TMPDIR); 3878 3879 &make_latex_images(); 3880 3881 print "\nGenerating postscript images using dvips ...\n"; 3882 &process_log_file(".$dd${PREFIX}images.log"); # Get eqn size info 3883 unless ($LaTeXERROR) { 3884 local($dvips_call) = 3885 "$DVIPS -S1 -i $DVIPSOPT -o$TMPDIR$dd${IMAGE_PREFIX} .${dd}${PREFIX}images.dvi"; 3886 print "$dvips_call\n" if (($DEBUG)||($VERBOSITY > 1)); 3887 3888 &close_dbm_database if $DJGPP; 3889 L2hos->syswait($dvips_call) && print "Error: $!\n"; 3890 undef $dvips_call; 3891 &open_dbm_database if $DJGPP; 3892 3893 # add suffix .ps to the file-names for each image 3894 if(opendir(DIR, $TMPDIR || '.')) { 3895 # use list-context instead; thanks De-Wei Yin <yin@asc.on.ca> 3896 my (@ALL_IMAGE_FILES) = grep /^$IMAGE_PREFIX\d+$/o, readdir(DIR); 3897 foreach (@ALL_IMAGE_FILES) { 3898 L2hos->Rename("$TMPDIR$dd$_", "$TMPDIR$dd$_.ps"); 3899 } 3900 closedir(DIR); 3901 } else { 3902 print "\nError: Cannot read dir '$TMPDIR': $!\n"; 3903 } 3904 } 3905 } 3906 if ($LaTeXERROR) { 3907 print "\n\n*** LaTeXERROR\n"; return(); 3908 } 3909 3910 while ( ($name, $page_num) = each %new_id_map) { 3911 # Extract the page, convert and save it 3912 &extract_image($page_num,$orig_name_map{$page_num}); 3913 } 3914} 3915 3916# Generate images for unknown environments, equations etc, and replace 3917# the markers in the main text with them. 3918# - $cached_env_img maps encoded contents to image URL's 3919# - $id_map maps $env$id to page numbers in the generated latex file and after 3920# the images are generated, maps page numbers to image URL's 3921# - $page_map maps page_numbers to image URL's (temporary map); 3922# Uses global variables $id_map and $cached_env_img, 3923# $new_page_num and $latex_body 3924 3925 3926sub make_images { 3927 local($name, $contents, $raw_contents, $uucontents, $page_num, 3928 $uucontents, %page_map, $img); 3929 # It is necessary to run LaTeX this early because we need the log file 3930 # which contains information used to determine equation alignment 3931 if ( $latex_body =~ /newpage/) { 3932 print "\n"; 3933 if ($LATEX_DUMP) { 3934 # dump a pre-compiled format 3935 if (!(-f "${PREFIX}images.fmt")) { 3936 print "$INILATEX ./${PREFIX}images.tex\n" 3937 if (($DEBUG)||($VERBOSITY > 1)); 3938 print "dumping ${PREFIX}images.fmt\n" 3939 unless ( L2hos->syswait("$INILATEX ./${PREFIX}images.tex")); 3940 } 3941 local ($img_fmt) = (-f "${PREFIX}images.fmt"); 3942 if ($img_fmt) { 3943 # use the pre-compiled format 3944 print "$TEX \"&./${PREFIX}images\" ./${PREFIX}images.tex\n" 3945 if (($DEBUG)||($VERBOSITY > 1)); 3946 L2hos->syswait("$TEX \"&./${PREFIX}images\" ./${PREFIX}images.tex"); 3947 } elsif (-f "${PREFIX}images.dvi") { 3948 print "${PREFIX}images.fmt failed, proceeding anyway\n"; 3949 } else { 3950 print "${PREFIX}images.fmt failed, trying without it\n"; 3951 print "$LATEX ./${PREFIX}images.tex\n" 3952 if (($DEBUG)||($VERBOSITY > 1)); 3953 L2hos->syswait("$LATEX ./${PREFIX}images.tex"); 3954 } 3955 } else { &make_latex_images() } 3956# local($latex_call) = "$LATEX .$dd${PREFIX}images.tex"; 3957# print "$latex_call\n" if (($DEBUG)||($VERBOSITY > 1)); 3958# L2hos->syswait("$latex_call"); 3959## print "$LATEX ./${PREFIX}images.tex\n" if (($DEBUG)||($VERBOSITY > 1)); 3960## L2hos->syswait("$LATEX ./${PREFIX}images.tex"); 3961## } 3962 $LaTeXERROR = 0; 3963 &process_log_file("./${PREFIX}images.log"); # Get image size info 3964 } 3965 if ($NO_IMAGES) { 3966 my $img = "image.$IMAGE_TYPE"; 3967 my $img_path = "$LATEX2HTMLDIR${dd}icons$dd$img"; 3968 L2hos->Copy($img_path, ".$dd$img") 3969 if(-e $img_path && !-e $img); 3970 } 3971 elsif ((!$NOLATEX) && ($latex_body =~ /newpage/) && !($LaTeXERROR)) { 3972 print "\nGenerating postscript images using dvips ...\n"; 3973 &make_tmp_dir; # sets $TMPDIR and $DESTDIR 3974 $IMAGE_PREFIX =~ s/^_//o if ($TMPDIR); 3975 3976 local($dvips_call) = 3977 "$DVIPS -S1 -i $DVIPSOPT -o$TMPDIR$dd$IMAGE_PREFIX .${dd}${PREFIX}images.dvi\n"; 3978 print $dvips_call if (($DEBUG)||($VERBOSITY > 1)); 3979 3980 if ((($PREFIX=~/\./)||($TMPDIR=~/\./)) && not($DVIPS_SAFE)) { 3981 print " *** There is a '.' in $TMPDIR or $PREFIX filename;\n" 3982 . " dvips will fail, so image-generation is aborted ***\n"; 3983 } else { 3984 &close_dbm_database if $DJGPP; 3985 L2hos->syswait($dvips_call) && print "Error: $!\n"; 3986 &open_dbm_database if $DJGPP; 3987 } 3988 3989 # append .ps suffix to the filenames 3990 if(opendir(DIR, $TMPDIR || '.')) { 3991 # use list-context instead; thanks De-Wei Yin <yin@asc.on.ca> 3992 my @ALL_IMAGE_FILES = grep /^$IMAGE_PREFIX\d+$/o, readdir(DIR); 3993 foreach (@ALL_IMAGE_FILES) { 3994 L2hos->Rename("$TMPDIR$dd$_", "$TMPDIR$dd$_.ps"); 3995 } 3996 closedir(DIR); 3997 } else { 3998 print "\nError: Cannot read dir '$TMPDIR': $!\n"; 3999 } 4000 } 4001 do {print "\n\n*** LaTeXERROR"; return()} if ($LaTeXERROR); 4002 return() if ($LaTeXERROR); # empty .dvi file 4003 L2hos->Unlink(".$dd${PREFIX}images.dvi") unless $DEBUG; 4004 4005 print "\n *** updating image cache\n" if ($VERBOSITY > 1); 4006 while ( ($uucontents, $_) = each %cached_env_img) { 4007 delete $cached_env_img{$uucontents} 4008 if ((/$PREFIX$img_rx\.$IMAGE_TYPE/o)&&!($DESTDIR&&$NO_SUBDIR)); 4009 $cached_env_img{$uucontents} = $_ 4010 if (s/$PREFIX$img_rx\.new/$PREFIX$1.$IMAGE_TYPE/go); 4011 } 4012 print "\n *** removing unnecessary images ***\n" if ($VERBOSITY > 1); 4013 while ( ($name, $page_num) = each %id_map) { 4014 $contents = $latex_body{$name}; 4015 if ($page_num =~ /^\d+\#\d+$/) { # If it is a page number 4016 do { # Extract the page, convert and save it 4017 $img = &extract_image($page_num,$orig_name_map{$page_num}); 4018 if ($contents =~ /$htmlimage_rx/) { 4019 $uucontents = &special_encoding($env,$2,$contents); 4020 } elsif ($contents =~ /$htmlimage_pr_rx/) { 4021 $uucontents = &special_encoding($env,$2,$contents); 4022 } else { 4023 $uucontents = &encode(&addto_encoding($contents,$contents)); 4024 } 4025 if (($HTML_VERSION >=3.2)||!($contents=~/$order_sensitive_rx/)){ 4026 $cached_env_img{$uucontents} = $img; 4027 } else { 4028 # Blow it away so it is not saved for next time 4029 delete $cached_env_img{$uucontents}; 4030 print "\nimage $name not recycled, contents may change (e.g. numbering)"; 4031 } 4032 $page_map{$page_num} = $img; 4033 } unless ($img = $page_map{$page_num}); # unless we've just done it 4034 $id_map{$name} = $img; 4035 } else { 4036 $img = $page_num; # it is already available from previous runs 4037 } 4038 print STDOUT " *** image done ***\n" if ($VERBOSITY > 2); 4039 } 4040 &write_warnings( 4041 "\nOne of the images is more than one page long.\n". 4042 "This may cause the rest of the images to get out of sync.\n\n") 4043 if (-f sprintf("%s%.3d%s", $IMAGE_PREFIX, ++$new_page_num, ".ps")); 4044 print "\n *** no more images ***\n" if ($VERBOSITY > 1); 4045 # MRO: The following cleanup seems to be incorrect: The DBM is 4046 # still open at this stage, this causes a lot of unlink errors 4047 # 4048 #do { &cleanup; print "\n *** clean ***\n" if ($VERBOSITY > 1);} 4049 # unless $DJGPP; 4050} 4051 4052# MRO: This copies the navigation icons from the distribution directory 4053# or an alternative specified in $ALTERNATIVE_ICONS 4054# to the document directory. 4055 4056sub copy_icons { 4057 local($icon,$_); 4058 print "\nCopying navigation icons ..."; 4059 foreach (keys %used_icons) { 4060 # each entry ends in gif or png 4061 if ($ALTERNATIVE_ICONS) { 4062 L2hos->Copy("$ALTERNATIVE_ICONS$dd$_", ".$dd$_") 4063 if (-e "$ALTERNATIVE_ICONS$dd$_" && !-e $_); 4064 } elsif (/(gif|png)$/) { 4065 L2hos->Copy("$LATEX2HTMLDIR${dd}icons$dd$_", ".$dd$_") 4066 if (-e "$LATEX2HTMLDIR${dd}icons$dd$_" && !-e $_); 4067 } 4068 } 4069} 4070 4071sub process_log_file { 4072 local($logfile) = @_; 4073 local($name,$before,$lengthsfound); 4074 local($TeXpt)= 72/72.27; 4075 local($image_counter); 4076 open(LOG, "<$logfile") || die "\nCannot read logfile '$logfile': $!\n"; 4077 while (<LOG>) { 4078 if (/Overfull/) { $before .= $_ } 4079 elsif (/latex2htmlLength ([a-zA-Z]+)=(\-?[\d\.]+)pt/) { 4080 ${$1} = 0.0+$2; $lengthsfound = 1; 4081 } elsif (/latex2htmlSize|l2hSize/) { 4082 /:([^:]*):/; 4083 $name = $1; $name =~ s/\*//g; 4084 ++$image_counter; 4085 s/:([0-9.]*)pt/$height{$name} = $1*$TeXpt;''/e; 4086 s/::([0-9.]*)pt/$depth{$name} = $1*$TeXpt;''/e; 4087 s/::([0-9.]*)pt/$width{$name} = $1*$TeXpt;''/e; 4088 s/\((.*)\)/$eqno{$name} = 1+$1;''/e; 4089 if ($before) { 4090 local($tmp); 4091 if ($before =~ /hbox\s*\((\d+\.?\d*)pt/) { 4092 $width{$name} = $width{$name}+$1*$TeXpt; 4093 } 4094 if ($before =~ /vbox\s*\((\d+\.?\d*)pt/) { 4095 $height{$name} = $height{$name}+$1*$TeXpt; 4096 } 4097 $before = ''; 4098 } 4099 } 4100 $LaTeXERROR = 1 if (/^No pages of output./); 4101 } 4102 4103 if ($LaTeXERROR) { 4104 print STDERR "\n\n *** LaTeX produced no output ***\n" 4105 . " *** no new images can be created\n" 4106 . " *** Examine the images.log file.\n\n"; 4107 return; 4108 } 4109 print STDOUT "\n *** processing $image_counter images ***\n"; 4110 print STDOUT "\n *** LATEX LOG OK. ***\n" if ($VERBOSITY > 1); 4111 4112 if ($lengthsfound) { 4113 $ODD_HMARGIN = $hoffset + $oddsidemargin; 4114 $EVEN_HMARGIN = $hoffset + $evensidemargin; 4115 $VMARGIN = $voffset + $topmargin + $headheight + $headsep; 4116 if ($dvi_mag >0 && $dvi_mag != 1000) { 4117 $ODD_HMARGIN = int($dvi_mag /1000 * $ODD_HMARGIN); 4118 $EVEN_HMARGIN = int($dvi_mag /1000 * $EVEN_HMARGIN); 4119 $VMARGIN = int($dvi_mag /1000 * $VMARGIN); 4120 } 4121 } else { 4122 $ODD_HMARGIN = 0; 4123 $EVEN_HMARGIN = 0; 4124 $VMARGIN = 0; 4125 } 4126 $ODD_HMARGIN = int($ODD_HMARGIN*$TeXpt + 72.5); 4127 $EVEN_HMARGIN = int($EVEN_HMARGIN*$TeXpt + 72.5); 4128 $VMARGIN = int($VMARGIN*$TeXpt + 72.5); 4129 close(LOG); 4130} 4131 4132sub extract_image { # clean 4133 my ($page_num,$name) = @_; 4134 4135 # The followin come out of %img_params 4136 my ($scale, $external, $thumbnail, $map, $psimage, $align, $usemap, 4137 $flip, $aalias, $trans, $exscale, $alt, $exstr); 4138 4139 my ($lwidth, $val) = (0, ''); 4140 my ($custom_size,$color_depth,$height,$width,$croparg); 4141 4142 print STDOUT "\nextracting $name as $page_num\n" if ($VERBOSITY > 1); 4143 # $global_num identifies this image in the original source file 4144 # $new_num identifies this image in images.tex 4145 my ($global_num, $new_num) = split(/#/, $page_num); 4146 $name =~ s/\*/star/; 4147 my ($env,$basename,$img) = ($name,"img$global_num",''); 4148 $env =~ s/\d+$//; 4149 $psname = sprintf("%s%.3d", "$TMPDIR$dd$IMAGE_PREFIX", $new_num); 4150 if ( $EXTERNAL_IMAGES && $PS_IMAGES ) { 4151 $img = "$basename.ps"; 4152 L2hos->Copy("$psname.ps", "${PREFIX}$img"); 4153 } else { 4154 $img = "$basename.$IMAGE_TYPE"; 4155 ($scale, $external, $thumbnail, $map, $psimage, $align, $usemap, 4156 $flip, $aalias, $trans, $exscale, $alt, $exstr) = 4157 split('#', $img_params{$name}); 4158 $lwidth = ($align =~ s/nojustify/middle/) ? 0 : $LINE_WIDTH; 4159 $alt = "ALT=\"$name\"" unless $alt; 4160 $exscale = $EXTRA_IMAGE_SCALE unless($exscale); 4161 if ($NO_IMAGES) { 4162 L2hos->Symlink("image.$IMAGE_TYPE", "${PREFIX}$img"); 4163 if ($thumbnail) { 4164 L2hos->Symlink("image.$IMAGE_TYPE", "${PREFIX}T$img"); 4165 $thumbnail = "${PREFIX}T$img"; 4166 } 4167 } else { 4168 # RRM: deal with size data 4169 if ($width{$name} < 0) { 4170 if ($exscale && $PK_GENERATION) { 4171 $height = int( 4172 $exscale*$height{$name}+ 4173 $exscale*$depth{$name} +.5); 4174 $width = int($exscale*$width{$name}-.5); 4175 } else { 4176 $height = int($height{$name}+$depth{$name}+.5); 4177 $width = int($width{$name}-.5); 4178 } 4179 $custom_size = "${width}x$height"; 4180 } elsif ($width{$name}) { 4181 if ($exscale && $PK_GENERATION) { 4182 $height = int( $height{$name} * $exscale + 4183 $depth{$name} * $exscale +.5); 4184 $width = int($width{$name} * $exscale +.5); 4185 } else { 4186 $height = int($height{$name}+$depth{$name}+.5); 4187 $width = int($width{$name}+.5); 4188 } 4189 $custom_size = "${width}x$height"; 4190 } else { 4191 $custom_size = ''; 4192 } 4193 # MRO: add first overall crop 4194 $croparg = '-crop a' . ($crop{$name} || '') . ' '; 4195 $page_num =~ s/^\d+#//o; 4196 $custom_size .= " -margins " 4197 . (($page_num % 2) ? $ODD_HMARGIN:$EVEN_HMARGIN) 4198 . ",$VMARGIN" if ($custom_size); 4199 4200 #RRM: \special commands may place ink outside the expected bounds: 4201 $custom_size = '' if ($tex_specials{$name}); 4202 4203 # MRO: Patches for image conversion with pstoimg 4204 # RRM: ...with modifications and fixes 4205 L2hos->Unlink("${PREFIX}$img"); 4206 &close_dbm_database if $DJGPP; 4207 print "Converting image #$new_num\n"; 4208 4209 if ( ($name =~ /figure/) || $psimage || $scale || $thumbnail) { 4210 $scale = $FIGURE_SCALE_FACTOR unless ($scale); 4211 print "\nFIGURE: $name scaled $scale $aalias\n" if ($VERBOSITY > 2); 4212 (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE " 4213 . ($DEBUG ? '-debug ' : '-quiet ' ) 4214 . ($TMPDIR ? "-tmp $TMPDIR " : '' ) 4215 . (($DISCARD_PS && !$thumbnail && !$psimage)? "-discard " :'') 4216 . (($INTERLACE) ? "-interlace " : '' ) 4217 . (((($ANTI_ALIAS)||($aalias))&&($aalias !~ /no|text/))? "-antialias ":'') 4218 . (($ANTI_ALIAS_TEXT||(($aalias =~/text/)&&($aalias !~/no/)))? 4219 "-aaliastext ":'') 4220 . (($custom_size) ? "-geometry $custom_size ": '' ) 4221 . $croparg 4222 . ($color_depth || '') 4223 . (($flip) ? "-flip $flip " : '' ) 4224 . (($scale > 0) ? "-scale $scale " : '' ) 4225 . (((($TRANSPARENT_FIGURES && ($env =~ /figure/o))||($trans)) 4226 &&(!($trans =~ /no/))) ? "-transparent " : '') 4227 . (($WHITE_BACKGROUND) ? "-white " : '' ) 4228 . "-out ${PREFIX}$img $psname.ps" 4229 ) ) # ||!(print "\nWriting image: ${PREFIX}$img")) 4230 && print "\nError while converting image: $!\n"; 4231 4232 if ($thumbnail) { # $thumbnail contains the reduction factor 4233 L2hos->Unlink("${PREFIX}T$img"); 4234 print "\nIMAGE thumbnail: $name" if ($VERBOSITY > 2); 4235 (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE " 4236 . ($DEBUG ? '-debug ' : '-quiet ' ) 4237 . ($TMPDIR ? "-tmp $TMPDIR " : '' ) 4238 . (($DISCARD_PS && !$psimage) ? "-discard " : '' ) 4239 . (($INTERLACE) ? "-interlace " : '' ) 4240 . ((($ANTI_ALIAS||($aalias))&&(!($aalias =~/no/)))? "-antialias " :'') 4241 . (($ANTI_ALIAS_TEXT||(($aalias =~/text/)&&($aalias !~/no/)))? 4242 "-aaliastext ":'') 4243 . (($custom_size) ? "-geometry $custom_size " : '' ) 4244 . ($color_depth || '') 4245 . (($flip) ? "-flip $flip " : '' ) 4246 . (($thumbnail > 0) ? "-scale $thumbnail " : '' ) 4247 . ((($trans)&&(!($trans =~ /no/))) ? "-transparent " : '') 4248 . (($WHITE_BACKGROUND) ? "-white " : '' ) 4249 . "-out ${PREFIX}T$img $psname.ps" 4250 ) ) # ||!(print "\nWriting image: ${PREFIX}T$img")) 4251 && print "\nError while converting thumbnail: $!\n"; 4252 $thumbnail = "${PREFIX}T$img"; 4253 } 4254 } elsif (($exscale &&(!$PK_GENERATION))&&($width{$name})) { 4255 my $under = ''; 4256 my $mathscale = ($MATH_SCALE_FACTOR > 0) ? $MATH_SCALE_FACTOR : 1; 4257 if (($DISP_SCALE_FACTOR > 0) && 4258 ( $name =~ /equation|eqnarray|display/)) 4259 { $mathscale *= $DISP_SCALE_FACTOR; }; 4260 if ($scale) { 4261 $scale *= $exscale if ($name =~ /makeimage|tab/); 4262 } else { 4263 $scale = $mathscale*$exscale; 4264 $under = "d" if (($name =~/inline|indisplay/)&&($depth{$name})); 4265 } 4266 print "\nIMAGE: $name scaled by $scale \n" if ($VERBOSITY > 2); 4267 (L2hos->syswait( "$PSTOIMG -type $IMAGE_TYPE " 4268 . ($DEBUG ? '-debug ' : '-quiet ' ) 4269 . ($TMPDIR ? "-tmp $TMPDIR " : '' ) 4270 . (($DISCARD_PS)? "-discard " : '' ) 4271 . (($INTERLACE)? "-interlace " : '' ) 4272 . ((($ANTI_ALIAS_TEXT||($aalias))&&($aalias !=~/no/))? 4273 "-antialias -depth 1 " :'') 4274 . (($custom_size)? "-geometry $custom_size " : '' ) 4275 . $croparg 4276 . (($scale != 1)? "-scale $scale " : '' ) 4277 . ((($exscale)&&($exscale != 1)&& 4278 !($ANTI_ALIAS_TEXT &&($LATEX_COLOR)))? 4279 "-shoreup $exscale$under " :'') 4280 . ((($TRANSPARENT_FIGURES ||($trans)) 4281 &&(!($trans =~ /no/)))? "-transparent " : '') 4282 . (($WHITE_BACKGROUND && !$TRANSPARENT_FIGURES) ? "-white " : '' ) 4283 . "-out ${PREFIX}$img $psname.ps" 4284 ) ) # ||!(print "\nWriting image: ${PREFIX}$img")) 4285 && print "\nError while converting image: $!\n"; 4286 } else { 4287 print "\nIMAGE: $name\n" if ($VERBOSITY > 2); 4288 my $under = ''; 4289 my $mathscale = ($MATH_SCALE_FACTOR > 0) ? $MATH_SCALE_FACTOR : 1; 4290 if (($DISP_SCALE_FACTOR > 0) && 4291 ( $name =~ /equation|eqnarray|display/)) 4292 { $mathscale *= $DISP_SCALE_FACTOR; }; 4293 if (($scale)&&($exscale)) { 4294 $scale *= $exscale if ($name =~ /makeimage|tab/); 4295 } elsif ($scale) { 4296 } elsif (($mathscale)&&($exscale)) { 4297 $scale = $mathscale*$exscale; 4298 $under = "d" if (($name =~/inline|indisplay/)&&($depth{$name})); 4299 } elsif ($mathscale) { $scale = $mathscale; } 4300 4301 (L2hos->syswait("$PSTOIMG -type $IMAGE_TYPE " 4302 . ($DEBUG ? '-debug ' : '-quiet ' ) 4303 . ($TMPDIR ? "-tmp $TMPDIR " : '' ) 4304 . (($DISCARD_PS) ? "-discard " : '' ) 4305 . (($INTERLACE) ? "-interlace " : '' ) 4306 . ((($ANTI_ALIAS_TEXT||($aalias))&&(!($aalias =~ /no/)))? 4307 "-antialias -depth 1 " :'') 4308 . ((($exscale)&&($exscale != 1)&& 4309 !($ANTI_ALIAS_TEXT &&($LATEX_COLOR)))? 4310 "-shoreup $exscale " :'') 4311 . (($scale ne 1) ? "-scale $scale " : '' ) 4312 . (($custom_size) ? "-geometry $custom_size " : '' ) 4313 . $croparg 4314# . (($name =~ /(equation|eqnarray)/) ? "-rightjustify $lwidth " : '') 4315# . (($name =~ /displaymath/) ? "-center $lwidth " : '') 4316 . (($name =~ /inline|indisplay/ && (!($custom_size))&&$depth{$name}!= 0) ? 4317 do {$val=($height{$name}-$depth{$name})/($height{$name}+$depth{$name}); 4318 "-topjustify x$val "} : '') 4319 . ((($TRANSPARENT_FIGURES||($trans)) 4320 &&(!($trans =~ /no/))) ? "-transparent " : '') 4321 . (($WHITE_BACKGROUND && !$TRANSPARENT_FIGURES) ? "-white " : '' ) 4322 . "-out ${PREFIX}$img $psname.ps") 4323 ) #|| !(print "\nWriting image: ${PREFIX}$img")) 4324 && print "\nError while converting image\n"; 4325 } 4326 if (! -r "${PREFIX}$img") { 4327 &write_warnings("\nFailed to convert image $psname.ps") 4328 } else { } #L2hos->Unlink("$psname.ps") unless $DEBUG } 4329 &open_dbm_database if $DJGPP; 4330 } 4331 } 4332 print "\nextracted $name as $page_num\n" if ($VERBOSITY > 1); 4333 &embed_image("${PREFIX}$img", $name, $external, $alt, $thumbnail, $map, 4334 $align, $usemap, $exscale, $exstr); 4335} 4336 4337sub extract_parameters { 4338 local($contents) = @_; 4339 local($_, $scale, $external, $thumbnail, $map, $psimage, $align, 4340 $usemap, $flip, $aalias, $trans, $pagecolor, $alt, $exscale, 4341 $cdepth, $htmlparams); 4342 4343 #remove the \htmlimage commands and arguments before... 4344 $contents =~ s/$htmlimage_rx/$_ = $2;''/ego; 4345 $contents =~ s/$htmlimage_pr_rx/$_ .= $2;''/ego; 4346 4347 # code adapted from original idea by Stephen Gildea: 4348 # If the document specifies the ALT tag explicitly 4349 # with \htmlimage{alt=some text} then use it. 4350 s!alt=([^,]+)!$alt = $1; 4351 $alt =~ s/^\s+|\s+$//g; $alt =~ s/"//g; 4352 $alt="ALT=\"$alt\""; 4353 ''!ie; 4354 4355 if (!$alt) { 4356 #...catching all the code for the ALT text. 4357 local($keep_gt)=1; 4358 $alt = &flatten_math($contents); undef $keep_gt; 4359 #RRM: too long strings upset the DBM. Truncate to <= 165 chars. 4360 if ( length($alt) > 163 ) { 4361 local($start,$end); 4362 $start = substr($alt,0,80); 4363 $end = substr($alt,length($alt)-80,80); 4364 $alt = join('',$start,"...\n ...",$end); 4365 } 4366 s/ALT\s*=\"([\w\W]*)\"/$alt=$1;''/ie; 4367 if ($alt) { 4368 if ($alt =~ /\#/) { 4369 $alt =~ s/^(\\vbox\{)?\#[A-Za-z]*\s*//; 4370 $alt =~ s/\n?\#[A-Za-z]*\s*\}?$//s; 4371 if ($alt =~ /\#/) { $alt = $` . " ... " }; 4372 } 4373 $alt =~ s/\`\`/\\lq\\lq /g; $alt =~ s/\`/\\lq /g; 4374 $alt =~ s/(^\s*|\s*$)//mg; 4375 $alt = "ALT=\"$alt\"" if ($alt); 4376 } else { $alt = 'ALT="image"' } 4377 } 4378 4379 $psimage++ if ($contents =~ /\.ps/); 4380# $contents =~ s/\s//g; # Remove spaces Why ? 4381 s/extrascale=([\.\d]*)/$exscale=$1;''/ie; 4382 s/\bscale=([\.\d]*)/$scale=$1;''/ie; 4383 s/(^|,\s*)external/$external=1;''/ie; 4384 s/(^|,\s*)((no)?_?anti)alias(_?(text))?/$aalias = $2.$4;''/ie; 4385 s/(^|,\s*)((no)?_?trans)parent/$trans = $2;''/ie; 4386 s/thumbnail=([\.\d]*)/$thumbnail=$1;''/ie; 4387 s/usemap=([^\s,]+)/$usemap=$1;''/ie; 4388 s/map=([^\s,]+)/;$map=$1;''/ie; 4389 s/align=([^\s,]+)/$align=$1;''/ie; 4390 s/flip=([^\s,]+)/$flip=$1;''/ie; 4391 s/color_?(depth)?=([^\s,]+)/$cdepth=$2;''/ie; 4392 ($scale,$external,$thumbnail,$map,$psimage,$align 4393 ,$usemap,$flip,$aalias,$trans,$exscale,$alt,$_); 4394} 4395 4396 4397# RRM: Put the raw \TeX code into the ALT tag 4398# replacing artificial environments and awkward characters 4399sub flatten_math { 4400 local ($_) = @_; 4401 $_ = &revert_to_raw_tex($_); 4402 s/[ \t]+/ /g; 4403 # MRO: replaced $* with /m 4404 s/$tex2html_wrap_rx//gm; 4405 s/(\\begin\s*\{[^\}]*\})(\s*(\[[^]]*\]))?[ \t]*/$1$3/gm; 4406 s/(\\end\{[^\}]*\})\n?/$1/gm; 4407 s/>(\w)?/($1)?"\\gt $1":"\\gt"/eg unless ($keep_gt); # replace > by \gt 4408 s/\\\|(\w)?/($1)?"\\Vert $1":"\\Vert"/eg; # replace \| by \Vert 4409 s/\|(\w)?/($1)?"\\vert $1":"\\vert"/eg; # replace | by \vert 4410 s/\\\\/\\\\ /g; # insert space after \\ 4411 s/\\"/\\uml /g; # screen umlaut accents... 4412 s/"/\'\'/g; # replace " by '' 4413 s/\\\#/\\char93 /g; # replace \# by \char93 else caching fails 4414# s/"(\w)?/($1)?"\\rq\\rq $1":"\'\'"/eg; # replace " by \rq\rq 4415# s/\&\\uml /\\\"/g; # ...reinstate umlauts 4416 $_; 4417} 4418 4419sub scaled_image_size { 4420 local($exscale,$_) = @_; 4421 local($width,$height) = ('',''); 4422 /WIDTH=\"?(\d*)\"?\s*HEIGHT=\"?(\d*)\"?$/o; 4423 $width=int($1/$exscale + .5); 4424 $height=int($2/$exscale + .5); 4425 "WIDTH=\"$width\" HEIGHT=\"$height\"" 4426} 4427 4428sub process_in_latex { 4429 # This is just a wrapper for process_undefined_environment. 4430 # @[0] = contents 4431 $global{'max_id'}++; 4432 &process_undefined_environment('tex2html_wrap',$global{'max_id'},$_[0]); 4433} 4434 4435# MRO: cp deprecated, replaced by L2hos->Copy 4436 4437# Marcus Hennecke 6/3/96 4438# MRO: test for existance 4439sub copy_file { 4440 local($file, $ext) = @_; 4441 $file = &fulltexpath("$FILE.$ext"); 4442 if(-r $file) { 4443 print "\nNote: Copying '$file' for image generation\n" 4444 if($VERBOSITY > 2); 4445 L2hos->Copy($file, ".$dd${PREFIX}images.$ext"); 4446 } 4447} 4448 4449sub rename_image_files { 4450 local($_, $old_name, $prefix); 4451 if ($PREFIX) { 4452 foreach (<${PREFIX}*img*.$IMAGE_TYPE>) { 4453 $old_name = $_; 4454 s/\.$IMAGE_TYPE$/\.old/o; 4455 L2hos->Rename($old_name, $_); 4456 } 4457 } 4458 else { 4459 foreach (<img*.$IMAGE_TYPE>) { 4460 $old_name = $_; 4461 s/\.$IMAGE_TYPE$/\.old/o; 4462 L2hos->Rename($old_name, $_); 4463 } 4464 foreach (<Timg*.$IMAGE_TYPE>) { 4465 $old_name = $_; 4466 s/\.$IMAGE_TYPE$/\.old/o; 4467 L2hos->Rename($old_name, $_); 4468 } 4469 } 4470} 4471 4472 4473############################ Processing Commands ########################## 4474 4475sub ignore_translate_commands { 4476 local ($_) = @_; 4477# print "\nTranslating commands ..."; 4478 4479 local(@processedC); 4480 &replace_strange_accents; 4481 local($before, $contents, $br_id, $after, $pattern, $end_cmd_rx); 4482 s/$begin_cmd_rx/&replace_macro_expansion($`, $1, $&, $')/eg; 4483} 4484 4485sub replace_macro_expansion { 4486 push(@processedC,$_[1]); 4487 $end_cmd_rx = &make_end_cmd_rx($_[2]); 4488 $pattern = $_[3]; 4489 $_ = join('',$_[3],$_[4]); 4490 $after = $_[4]; 4491 if (($before)&&(!($before =~ /$begin_cmd_rx/))) { 4492 push(@processedC,$before); 4493 $_ = join('',$pattern,$after); $before = ''; 4494 } 4495 local($end_cmd_rx) = &make_end_cmd_rx($br_id); 4496 4497} 4498 4499sub translate_aux_commands { 4500 s/^(.*)$/&translate_commands($1)/s; 4501} 4502 4503sub translate_commands { 4504 local ($_) = @_; 4505# print "\nTranslating commands ..."; 4506 4507 local(@processedC); 4508 &replace_strange_accents; 4509 for (;;) { # For each opening bracket ... 4510 last unless ($_ =~ /$begin_cmd_rx/); 4511 local($before, $contents, $br_id, $after, $pattern); 4512 ($before, $br_id, $after, $pattern) = ($`, $1, $', $&); 4513 if (($before)&&(!($before =~ /$begin_cmd_rx/))) { 4514 push(@processedC,$before); 4515 $_ = join('',$pattern,$after); $before = ''; 4516 } 4517 local($end_cmd_rx) = &make_end_cmd_rx($br_id); 4518 if ($after =~ /$end_cmd_rx/) { # ... find the the matching closing one 4519 $NESTING_LEVEL++; 4520 ($contents, $after) = ($`, $'); 4521 do { 4522 local(@save_open_tags) = @$open_tags_R; 4523 local($open_tags_R) = [ @save_open_tags ]; 4524 print STDOUT "\nIN::{$br_id}" if ($VERBOSITY > 4); 4525 print STDOUT "\n:$contents\n" if ($VERBOSITY > 7); 4526 undef $_; 4527 $contents = &translate_commands($contents) 4528 if ($contents =~ /$match_br_rx/o); 4529 # Modifies $contents 4530 &process_command($single_cmd_rx,$contents) 4531 if ($contents =~ /\\/o); 4532 4533 $contents .= &balance_tags(); 4534 }; 4535 4536 print STDOUT "\nOUT: {$br_id}" if ($VERBOSITY > 4); 4537 print STDOUT "\n:$contents\n" if ($VERBOSITY > 7); 4538 # THIS MARKS THE OPEN-CLOSE DELIMITERS AS PROCESSED 4539 $_ = join("", $before,"$OP$br_id$CP", $contents,"$OP$br_id$CP", $after); 4540 $NESTING_LEVEL--; 4541 } 4542 else { 4543 $pattern = &escape_rx_chars($pattern); 4544 s/$pattern//; 4545 print "\nCannot find matching bracket for $br_id" unless $AUX_FILE; 4546 } 4547 last unless ($_ =~ /$begin_cmd_rx/o); 4548 } 4549 $_ = join('',@processedC) . $_; 4550 # Now do any top level commands that are not inside any brackets 4551 # MODIFIES $_ 4552 print "$_\n" if ($VERBOSITY > 8); 4553 &process_command($single_cmd_rx,$_); 4554} 4555 4556#RRM: based on earlier work of Marcus Hennecke 4557# makes sure the $open_tags_R at the end of an environment 4558# is the same as @save_open_tags from the start, 4559# ensuring that the HTML page indeed has balanced tags 4560sub balance_tags { 4561 local($tag_cmd, $tags, $save_tags, $open_tags, @reopen_tags); 4562 $save_tags = join(',',@save_open_tags) if (@save_open_tags); 4563 $open_tags = join(',',@$open_tags_R) if (@$open_tags_R); 4564 if ($open_tags eq $save_tags) { return(); } 4565 if ($save_tags =~ s/^$open_tags//) { 4566 @reopen_tags = split (',',$'); 4567 } else { 4568 @reopen_tags = @save_open_tags; 4569 while (@$open_tags_R) { 4570 $tag_cmd = pop (@$open_tags_R); 4571 print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2; 4572 $declarations{$tag_cmd} =~ m|</.*$|; 4573 $tags .= $& unless ($` =~ /^<>$/); 4574 $open_tags = join(',',@$open_tags_R) if (@$open_tags_R); 4575 last if ( $save_tags =~ s/^$open_tags/ 4576 @reopen_tags = split (',',$');''/e); 4577 } 4578 } 4579 while (@reopen_tags) { 4580 $tag_cmd = shift @reopen_tags; 4581 if ($tag_cmd) { 4582 push (@$open_tags_R, $tag_cmd) if ($tag_cmd); 4583 print STDOUT "\n<$tag_cmd>" if $VERBOSITY > 2; 4584 $declarations{$tag_cmd} =~ m|</.*$|; 4585 $tags .= $` unless ($` =~ /^<>$/); 4586 } 4587 } 4588 $tags; 4589} 4590 4591sub close_all_tags { 4592 return() if (!@$open_tags_R); 4593 local($tags,$tag_cmd); 4594 while (@$open_tags_R) { 4595 $tag_cmd = pop (@$open_tags_R); 4596 print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2; 4597 $declarations{$tag_cmd} =~ m|</.*$|; 4598 $tags .= $& unless ($` =~ /^<>$/); 4599 } 4600 $tags; 4601} 4602 4603sub preserve_open_tags { 4604 local(@save_open_tags) = @$open_tags_R; 4605 local($open_tags_R) = [ @save_open_tags ]; 4606 # provides the markup to close and reopen the current tags 4607 (&close_all_tags(), &balance_tags()); 4608} 4609 4610sub preserve_open_block_tags { 4611 local($tag_cmd,$tags_open,$tags_close,$pre,$post,@tags); 4612 while (@$open_tags_R) { 4613 $tag_cmd = pop (@$open_tags_R); 4614 print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2; 4615 $declarations{$tag_cmd} =~ m|</.*$|; 4616 ($pre,$post) = ($`,$&); 4617 if ($post =~ /$block_close_rx/) { 4618 # put it back and exit 4619 push(@$open_tags_R,$tag_cmd); 4620 last; 4621 } else { 4622 # leave it closed, collecting tags for it 4623 $tags_close .= $post; 4624 $tags_open = $pre . $tags_open; 4625 unshift(@tags,$tag_cmd); 4626 } 4627 } 4628 ($tags_close , $tags_open, @tags); 4629} 4630 4631sub minimize_open_tags { 4632 local($this_tag, $close_only) = @_; 4633 local($pre,$post,$decl); 4634 $decl = $declarations{$this_tag}; 4635 if ($decl) { 4636 # if it is a declaration, get the corresponding tags... 4637 $decl =~ m|</.*$|; 4638 ($pre,$post) = ($`,$&) unless ($` =~ /^<>$/); 4639 if (!@$open_tags_R) { # when nothing else is open... 4640 # pushing the style, when appropriate 4641 push (@$open_tags_R, $this_tag) 4642 unless ($close_only ||($post =~ /$block_close_rx/)); 4643 print STDOUT "\n<$this_tag>" if $VERBOSITY > 2; 4644 # and return the tags 4645 return($pre,$post) unless ($USING_STYLES); 4646 local($env_id) = '' if ($env_id =~/^\w+$/); 4647 $pre =~ s/>$/ $env_id>/ if ($env_id); 4648 return($pre,$post); 4649 } 4650 } else { # ...else record the argument as $pre 4651 $pre = $this_tag unless $close_only; 4652 } 4653 local($env_id) = '' if ($env_id =~/^\w+$/); 4654 $pre =~ s/>$/ ID="$env_id">/ if ($USING_STYLES &&($env_id)); 4655 4656 # return the tags, if nothing is already open 4657 if (!@$open_tags_R) { 4658 return($pre,$post); 4659 } 4660# elsif ($close_only) { push (@$open_tags_R, $this_tag) } 4661 4662 local($tags,$tag_cmd,$tag_open); 4663 local($closures,$reopens,@tags); 4664 local($tag_close,$tag_open); 4665 local($size_cmd,$size_open); 4666 local($font_cmd,$font_open); 4667 local($fontwt_cmd,$fontwt_open); 4668 local($color_cmd,$color_open); 4669 if ($decl) { 4670 if ($this_tag =~ /$sizechange_rx/) { 4671 $size_cmd = $this_tag; 4672 } else { 4673 if ($this_tag =~ /$fontchange_rx/) { 4674 $font_cmd = $this_tag } 4675 if ($this_tag =~ /$fontweight_rx/) { 4676 $fontwt_cmd = $this_tag } 4677 } 4678 } 4679 while (@$open_tags_R) { 4680 ($tag_close,$tag_open) = ('',''); 4681 $tag_cmd = pop (@$open_tags_R); 4682 print STDOUT "\n</$tag_cmd>" if $VERBOSITY > 2; 4683 $declarations{$tag_cmd} =~ m|</.*$|; 4684 ($tag_close,$tag_open) = ($&,$`) unless ($` =~ /<>/); 4685 $closures .= $tag_close; 4686 4687 if ((!$size_cmd)&&($tag_cmd =~ /$sizechange_rx/)) { 4688 $size_cmd = $tag_cmd; 4689 $size_open = $tag_open; 4690 } 4691 elsif ((!$font_cmd)&&($tag_cmd =~ /$fontchange_rx/)) { 4692 $font_cmd = $tag_cmd; 4693 $font_open = $tag_open; 4694 } 4695 elsif ((!$fontwt_cmd)&&($tag_cmd =~ /$fontweight_rx/)) { 4696 $fontwt_cmd = $tag_cmd; 4697 $fontwt_open = $tag_open; 4698 } 4699 elsif ((!$color_cmd)&&($tag_cmd =~ /$colorchange_rx/)) { 4700 $color_cmd = $tag_cmd; 4701 $color_open = $tag_open; 4702 } 4703 elsif ($tag_cmd =~ 4704 /$sizechange_rx|$fontchange_rx|$fontweight_rx|$colorchange_rx/) { 4705 } else { 4706 unshift (@tags, $tag_cmd); 4707 print STDOUT "\n<<$tag_cmd>" if $VERBOSITY > 2; 4708 $reopens = $tag_open . $reopens; 4709 } 4710 } 4711 if ($USING_STYLES) { 4712 local($TAG) = "DIV"; 4713 if ($pre =~ /^<(DIV|SPAN|PRE)/) { $TAG = $1 }; 4714 if (($pre =~ /^<$TAG/)&&($env_id =~ /^\s+(CLASS|ID)/)) { 4715 $pre =~ s/<$TAG/<$TAG$env_id/; 4716 } elsif ($pre =~ /<P>/) { 4717 $TAG = 'P'; 4718 } else { 4719 } 4720# $post .= "</$TAG>"; 4721 } 4722 push (@$open_tags_R, @tags); 4723 $tags .= $pre if ($pre && $post =~ /$block_close_rx/); 4724 if ($font_cmd && !($font_cmd eq $this_tag)) { 4725 push (@$open_tags_R,$font_cmd); 4726 print STDOUT "\n<$font_cmd>" if $VERBOSITY > 2; 4727 $tags .= $font_open; 4728 } 4729 if ($fontwt_cmd && !($fontwt_cmd eq $this_tag)) { 4730 push (@$open_tags_R,$fontwt_cmd); 4731 print STDOUT "\n<$fontwt_cmd>" if $VERBOSITY > 2; 4732 $tags .= $fontwt_open; 4733 } 4734 if ($size_cmd && !($size_cmd eq $this_tag)) { 4735 push (@$open_tags_R,$size_cmd); 4736 print STDOUT "\n<$size_cmd>" if $VERBOSITY > 2; 4737 $tags .= $size_open; 4738 } 4739 if ($color_cmd && !($color_cmd eq $this_tag)) { 4740 push (@$open_tags_R,$color_cmd); 4741 print STDOUT "\n<$color_cmd>" if $VERBOSITY > 2; 4742 $tags .= $color_open; 4743 } 4744 $tags .= $pre unless ($pre && $post =~ /$block_close_rx/); 4745 push (@$open_tags_R, $this_tag) 4746 if ($decl &&!($post =~ /$block_close_rx|$all_close_rx/)); 4747 print STDOUT "\n<$this_tag>" if $VERBOSITY > 2; 4748 ($closures.$reopens.$tags , $post ); 4749} 4750 4751 4752sub declared_env { 4753 local($decl, $_, $deferred) = @_; 4754 local($after_cell,$pre,$post); 4755 local($decls) = $declarations{$decl}; 4756 $decls =~ m|</.*$|; 4757 ($pre,$post) = ($`,$&); 4758 if ($USING_STYLES) { 4759 $env_style{$decl} = " " unless ($env_style{$decl}); 4760 $pre =~ s/>$/$env_id>/ if ($env_id); 4761 } 4762 local($closing_tag) = 1 if ($pre =~ /^<>$/); 4763 $pre = $post = '' if $closing_tag; 4764 local($closures,$reopens); 4765 4766 local(@save_open_tags) = @$open_tags_R 4767 unless ($closing_tag || $deferred); 4768 local($open_tags_R) = [ @save_open_tags ] 4769 unless ($closing_tag || $deferred ); 4770 4771 if ($post =~ /$block_close_rx/) { 4772 local($last_tag) = pop (@$open_tags_R); 4773 local($ldecl) = $declarations{$last_tag}; 4774 if ($ldecl =~ m|</.*$|) { $ldecl = $& } 4775 if (($last_tag)&&!($ldecl =~ /$block_close_rx/)) { 4776 # need to close tags, for re-opening inside 4777 push (@$open_tags_R, $last_tag); 4778 ($closures,$reopens) = &preserve_open_tags(); 4779 $pre = join('', $closures, "\n", $pre, $reopens); 4780 $post = join('', $closures, $post, $reopens); 4781 } elsif ($last_tag) { 4782 $pre = "\n".$pre; 4783 push (@$open_tags_R, $last_tag); 4784 undef $ldecl; 4785 } else { 4786 } 4787 4788 if ($deferred) { 4789 if (defined $ldecl) { 4790 print STDOUT "\n<<$decl>" if $VERBOSITY > 2; 4791 unshift(@$open_tags_R, $decl); 4792 } else { 4793 print STDOUT "\n<$decl>" if $VERBOSITY > 2; 4794 push(@$open_tags_R, $decl); 4795 } 4796 return ( $pre . $_ ); 4797 } else { 4798 if (defined $ldecl) { 4799 print STDOUT "\n<<$decl>" if $VERBOSITY > 2; 4800 unshift(@$open_tags_R, $decl); 4801 } else { 4802 print STDOUT "\n<$decl>" if $VERBOSITY > 2; 4803 push(@$open_tags_R, $decl); 4804 } 4805 } 4806 } elsif ($post =~/$all_close_rx/) { 4807 ($closures,$reopens) = &preserve_open_tags(); 4808 ($pre,$post) = &minimize_open_tags($decl,1); 4809 $pre = join('', $closures, $pre); 4810 } elsif ($closing_tag) { 4811 $prev_open = $pre; 4812 ($pre,$post) = &minimize_open_tags($decl,1); 4813 $pre =~ s/<\/?>//g; $post =~ s/<\/?>//; 4814 } else { 4815 ($pre,$post) = &minimize_open_tags($decl); 4816 } 4817 $_ =~ s/^\s+//s; #RRM:28/4/99 remove spaces at the beginning 4818 $_ = &translate_environments($_); 4819 $_ = &translate_commands($_) if (/\\/); 4820 if ($post =~ /$block_close_rx/) { 4821 s/^\n?/\n/o; 4822 if (defined $ldecl) { 4823 $post = &close_all_tags(); 4824 } else { 4825 $post = "\n"; 4826 } 4827 } elsif ($post =~/$all_close_rx/) { 4828 } else { $post = '' }; 4829 4830 join('', $pre, $_, $post 4831 , ($closing_tag ? '' : &balance_tags()) ); 4832} 4833 4834sub do_cmd_centering{&declared_env('center',$_[0],$tex2html_deferred)} 4835sub do_cmd_raggedright{&declared_env('flushleft',$_[0],$tex2html_deferred)} 4836sub do_cmd_raggedleft{&declared_env('flushright',$_[0],$tex2html_deferred)} 4837 4838sub do_env_verse { &declared_env('verse',@_) } 4839sub do_env_center { &declared_env('center',@_) } 4840sub do_env_quote { &declared_env('quote', @_) } 4841sub do_env_quotation { &declared_env('quote', @_) } 4842sub do_env_tex2html_preform { &declared_env('preform', @_) } 4843sub do_env_tex2html_ord { &declared_env('ord', @_) } 4844sub do_env_tex2html_unord { &declared_env('unord', @_) } 4845sub do_env_tex2html_desc { &declared_env('desc', @_) } 4846 4847 4848# Modifies $contents 4849sub process_command { 4850 # MRO: modified to use $_[1] 4851 # local ($cmd_rx, *ref_contents) = @_; 4852 local ($cmd_rx) = @_; 4853 local($ref_before, $cmd , $pc_after); 4854 local($cmd_sub, $cmd_msub, $cmd_trans, $mathentity); 4855 local (@open_font_tags,@open_size_tags); 4856 $_[1] = &convert_iso_latin_chars($_[1]) 4857 unless (($cmd =~ /(Make)?([Uu]pp|[Ll]ow)ercase/)|| 4858 ((!$cmd)&&($_[1] =~ /^\\(Make)?([Uu]pp|[Ll]ow)ercase/s))); 4859 4860 local(@ref_processed); 4861 for (;;) { # Do NOT use the o option 4862 last unless ($_[1] =~ /$cmd_rx/ ); 4863 print "."; 4864 #JCL(jcl-del) - use new regexp form which handles white space 4865 ($ref_before, $cmd, $pc_after) = ($`, $1.$2, $4.$'); 4866 push(@ref_processed,$ref_before); 4867#print "\nAFTER:$1.$2:".$4."\n" if ($cmd_rx eq $single_cmd_rx); 4868 print STDOUT "$cmd" if ($VERBOSITY > 2); 4869 print STDOUT "\nIN: $_[1]\n" if ($VERBOSITY > 6); 4870 # 4871 if ( $cmd = &normalize($cmd,$pc_after) ) { 4872 print "PCT: process_command: cmd: $cmd\n" if ($VERBOSITY > 10) ; 4873 ($cmd_sub, $cmd_msub, $cmd_trans, $mathentity) = 4874 ("do_cmd_$cmd", "do_math_cmd_$cmd" 4875 , $declarations{$cmd}, $mathentities{$cmd}); 4876 if ($new_command{$cmd}||$renew_command{$cmd}) { 4877 # e.g. some \the$counter 4878 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 4879 &make_unique($body) if ($body =~ /$O/); 4880 if ($argn) { 4881 do { 4882 local($before) = ''; 4883 local($_) = "\\$cmd ".$pc_after; 4884 # &substitute_newcmd may need what comes after the $cmd 4885 # from the value of $after 4886 #RRM: maybe best to pass it as a parameter ? 4887 my $keep_after = $after; 4888 $after = $pc_after; 4889 $pc_after = &substitute_newcmd; # may change $after 4890 $pc_after =~ s/\\\@#\@\@/\\/o ; 4891 $pc_after .= $after; 4892 $after = $keep_after; 4893 } 4894 } else { 4895 $pc_after = $body . $pc_after; 4896 } 4897 } elsif (defined &$cmd_sub) { 4898 # $ref_before may also be modified ... 4899 if ($cmd =~ /$sizechange_rx/o) { 4900 $pc_after = &$cmd_sub($pc_after, $open_tags_R); 4901 } else { 4902 $pc_after = &$cmd_sub($pc_after, $open_tags_R); 4903 }; 4904 } elsif ((defined &$cmd_msub)&&!$NO_SIMPLE_MATH) { 4905#print "\nMCMD:$cmd_msub : "; 4906 # $ref_before may also be modified ... 4907 $pc_after = &$cmd_msub($pc_after, $open_tags_R); 4908 if ( !$math_mode ) { 4909 $pc_after = "<MATH>" . $pc_after . "</MATH>"; 4910 ++$commands_outside_math{$cmd}; 4911 }; 4912 } elsif ($cmd_trans) { # One to one transform 4913#print "\nCMD-DECL: $inside_tabular : $cmd_trans". join(',',@$open_tags_R); 4914 if ($inside_tabular) { 4915 push (@ref_processed , "\\$cmd ") 4916 } else { 4917 $cmd_trans =~ m|</.*$|; 4918 $pc_after = $` . $pc_after unless ($` =~ /^<>/); 4919 push(@$open_tags_R, $cmd) 4920 if ($cmd =~ /$fontchange_rx|$fontweight_rx|$sizechange_rx/o); 4921 } 4922 } elsif ($mathentity) { 4923#print "\nM-ENT:$mathentity : "; 4924 if ( $math_mode ) { 4925 $pc_after = "&$mathentity#$cmd;" . $pc_after; 4926 } elsif ($NO_SIMPLE_MATH) { 4927 $pc_after = "&$mathentity#$cmd;" . $pc_after; 4928# ++$commands_outside_math{$cmd}; 4929 } else { 4930 $pc_after = "<MATH>&$mathentity#$cmd;</MATH>" . $pc_after; 4931 ++$commands_outside_math{$cmd}; 4932 } 4933 } elsif ($ignore{$cmd}) { # Ignored command 4934 print "\nignoring \\$cmd" if $VERBOSITY > 5; 4935 $pc_after = join('', " ", $pc_after) if ($cmd eq " "); # catches `\ ' 4936 $pc_after = join(''," ", $pc_after) 4937 if (($cmd eq ',')&&($pc_after =~ /^\-/s)&&($ref_before =~/\-$/s)); 4938 } elsif ($cmd =~ /^the(.+)$/){ 4939 $counter = $1; 4940 local($tmp)="do_cmd_$cmd"; 4941 if (defined &$tmp) { # Counter 4942 $pc_after = &do_cmd_thecounter($pc_after); 4943 } else { 4944 if (defined $failed) { 4945 $failed = 1; 4946# $ref_before .= "$cmd"; 4947 push(@ref_processed,$cmd); # $ref_before .= "$cmd"; 4948 } 4949 else { 4950 print "PCT: process_command: before unknow command (a) with $_\n" if ($VERBOSITY > 10) ; 4951 &declare_unknown_cmd($cmd) ; 4952 } 4953# $ref_before .= "$cmd" if ($failed); 4954 } 4955 } elsif ($cmd eq "\n") { push(@ref_processed," "); # $ref_before .= " "; 4956 } else { 4957 # Do not add if reading an auxiliary file 4958 if (defined $failed) { 4959 $failed = 1; 4960 } 4961 else { 4962 print "PCT: process_command: before unknow command (b) with $_\n" if ($VERBOSITY > 10) ; 4963 &declare_unknown_cmd($cmd) ; 4964 } 4965 } 4966 } else { 4967 # &normalize should have already handled it adequately 4968 # '\ ' (space) gets thru to here. Perhaps some others too ? 4969# print "\n ?? This should not happen: \\$cmd ??\n"; 4970 } 4971# $_[1] = join('', $ref_before, $pc_after); 4972 $_[1] = $pc_after; 4973 print STDOUT "\n-> $ref_before\n" if ($VERBOSITY > 6); 4974 } 4975 $_[1] = join('',@ref_processed).$_[1]; 4976} 4977 4978sub declare_unknown_cmd { 4979 local($this_cmd) = @_; 4980 local($tmp) = "wrap_cmd_$cmd"; 4981 do { ++$unknown_commands{$cmd}; 4982 print STDOUT "\n*** Unknown command[1]: \\$cmd *** \n" 4983 if ($VERBOSITY > 2); 4984 } unless ($AUX_FILE||(defined &$tmp)||($image_switch_rx=~/\b\Q$cmd\E\b/)); 4985} 4986 4987 4988# This makes images from the code for math-entities, 4989# when $NO_SIMPLE_MATH is set and the math extension is loaded. 4990# 4991sub replace_math_constructions { 4992 local($math_mode) = @_; 4993 &make_math_box_images($math_mode) if (/<BOX>/); 4994 &make_math_entity_images($math_mode) if (/\&\w+#\w+;/); 4995} 4996 4997sub make_math_box_images { 4998 local($math_mode) = @_; 4999 local($pre,$this,$post,$tmp) = ('','',''); 5000 local($slevel,$blevel) = 0; 5001 5002 while (/<BOX>/) { 5003 $pre .= $`; $tmp = $`; $this = ''; $post = $'; 5004 # compute the super/sub-scripting level for each entity 5005 $tmp =~ s/<(\/?)SU[BP]>/ 5006 if ($1) { $slevel--} else { $slevel++};''/eog; 5007 5008 $tmp = $post; 5009 if ($tmp =~ /<(\/?)BOX>/o ) { 5010 if ($1) { $this = $`; $post = $' } 5011 else { $failed = 1 } # nested box, too complicated ! 5012 } else { 5013 &write_warnings("\nLost end of a <BOX> ?"); 5014 $failed = 1; 5015 } 5016 last if ($failed); 5017 5018 ($this,$_) = &process_box_in_latex( 5019 $math_mode, $slevel, $this, $post); 5020 $_ =~ s/^\s*//; # remove any leading spaces 5021 $pre .= $this ."\001"; 5022 } 5023 return if ($failed); 5024 $_ = $pre . $_; 5025} 5026 5027sub make_math_entity_images { 5028 local($math_mode) = @_; 5029 local($pre,$this,$post,$tmp) = ('','',''); 5030 local($slevel) = 0; 5031 # compute the super/sub-scripting level for each entity 5032 while (/\&\w+#(\w+);/) { 5033 $pre .= $`; $tmp = $`; $this = $1; $post = $'; 5034 $tmp =~ s/<(\/?)SU[BP]>/ 5035 if ($1) { $slevel--} else { $slevel++};''/eog; 5036 ($this,$_) = &process_entity_in_latex( 5037 $math_mode, $slevel, $this, $post); 5038 $_ =~ s/^\s*//; # remove any leading spaces 5039 $pre .= $this ."\001"; 5040 } 5041 $_ = $pre . $_; 5042} 5043 5044 5045#RRM: Revert a math-entity to create image using LaTeX, together with 5046# any super/sub-scripts (possibly nested or with \limits ). 5047# Must also get the correct \display/text/(script)script style. 5048# 5049sub process_entity_in_latex { 5050 local($mode,$level,$entity,$after) = @_; 5051 local($math_style,$supsub,$rest) = ('','',''); 5052 $level++ if ($mode =~/box/); # for top/bottom of inline fractions, etc. 5053 5054 if ($level) { 5055 $math_style = "\\". (($level > 1) ? "script" : "")."scriptstyle" 5056 } else { 5057 $math_style = "\\displaystyle" unless ($mode =~ /inline/); 5058 } 5059 while ($after =~ s/^\s*((\\limits|\&limits;)?\s*<SU(P|B)>)\s*/$supsub .= $1;''/eo) { 5060 local($slevel) = 1; 5061 local($aftersupb) = ''; 5062 while ($slevel) { 5063 $after =~ s/(<(\/)SU(B|P)>)/($2)? $slevel-- : $slevel++;''/oe; 5064 $supsub .= $`.$&; 5065 $aftersupb = $'; 5066 } 5067 $after = $aftersupb; 5068 } 5069 5070 local($latex_code) = "\$$math_style\\$entity$supsub\$"; 5071 5072 $global{'max_id'}++; 5073 ( &process_undefined_environment('tex2html_wrap_inline' 5074 ,$global{'max_id'}, $latex_code ) , $after); 5075} 5076 5077sub process_box_in_latex { 5078 local($mode,$level,$inside,$after) = @_; 5079 local($math_style,$which,$pre,$post,$tmp) = ('','',"\{","\}"); 5080 5081 if ($level) { 5082 $math_style = "\\". (($level > 1) ? "script" : "")."scriptstyle" 5083 } else { 5084 $math_style = "\\displaystyle" unless ($mode =~ /inline/); 5085 } 5086 5087 if ($inside =~ /<((LEFT)|(RIGHT))>/ ) { 5088 $pre = "\\left"; $post = "\\right"; 5089 if ($2) { 5090 $tmp = $`; $inside = $'; 5091 $pre .= (($tmp) ? $tmp : ".") . "\{"; 5092 if ( $inside =~ /<RIGHT>/ ) { 5093 $tmp = $'; 5094 $inside = $`; 5095 $post = "\}". (($tmp) ? $tmp : "."); 5096 } 5097 } else { 5098 $pre .= ".\{"; $tmp = $'; $inside = $`; 5099 $post = "\}". (($tmp) ? $tmp : "."); 5100 } 5101 } 5102 if ( $inside =~ /<((OVER)|(ATOP)|(CHOOSE))>/ ) { 5103 $pre .= $`; 5104 $post = $' . $post ; 5105 if ($2) { $which = "over " } 5106 elsif ($3) { $which = "atop " } 5107 elsif ($4) { $which = "atopwithdelims\(\)" } 5108 } 5109 5110 local($latex_code) = join('', "\$" , $math_style , " ", $pre 5111 , (($which)? "\\$which" : "") , $post , "\$" ); 5112 5113 if ($after =~ s/<SUP ALIGN=\"CENTER\">([^<]*)<\/SUP>/ 5114 $tmp =$1;''/eo ) { 5115 $latex_code = join('', "\\stackrel" , $latex_code 5116 , "\{" , $tmp , "\}" ); 5117 } 5118 5119 $global{'max_id'}++; 5120 ( &process_undefined_environment('tex2html_wrap_inline' 5121 ,$global{'max_id'}, $latex_code ) , $after); 5122} 5123 5124####################### Processing Meta Commands ############################ 5125# This is a specialised version of process_command above. 5126# The special commands (newcommand, newenvironment etc.) 5127# must be processed before translating their arguments, 5128# and before we cut up the document into sections 5129# (there might be sectioning commands in the new definitions etc.). 5130# \newtheorem commands are treated during normal processing by 5131# generating code for the environments they define. 5132 5133sub substitute_meta_cmds { 5134 local ($next_def); 5135 local ($cmd, $arg, $argn, $opt, $body, $before, $xafter); 5136 local ($new_cmd_no_delim_rx, $new_cmd_rx, $new_env_rx, $new_cmd_or_env_rx); 5137 local ($new_end_env_rx); 5138 &tokenize($meta_cmd_rx); #JCL(jcl-del) - put delimiter after meta command 5139 print "\nProcessing macros ..." if (%new_command || %new_environment); 5140 # First complete any replacement left-over from the previous part. 5141 if ($UNFINISHED_ENV) { 5142 s/$UNFINISHED_ENV/$REPLACE_END_ENV/; 5143 $UNFINISHED_ENV = ''; 5144 $REPLACE_END_ENV = ''; 5145 } 5146 5147 local(@processed); 5148 local($processed, $before, $after)=('', '', $_); 5149 while ($after =~ /$meta_cmd_rx$EOL/o) { # ... and uses the delimiter 5150 ($cmd, $after) = ($1.$2, $'); 5151 $before .= $`; 5152# $next_def = ''; 5153 if (!($before =~ /$meta_cmd_rx$EOL/)) { 5154 push(@processed, $before); $before = ''; 5155 } 5156 5157 print ","; 5158# $next_def = "\\$cmd" unless (($cmd =~ /renewcommand/)); 5159 local($cmd_sub) = "get_body_$cmd"; 5160 if (defined &$cmd_sub) { 5161# $processed = &$cmd_sub(*after); 5162 $processed = &$cmd_sub(\$after); 5163# if ($processed) { $after = $before . $processed; } 5164# $next_def = '' 5165# if (($PREAMBLE > 1)&&($cmd =~ /(re)?newcommand/)); 5166# &add_to_preamble($cmd, $next_def) 5167# unless ($next_def =~ /^\s*$/); 5168### new style of handling meta-commands 5169 if ($processed) { push(@processed, "\\".$processed) } 5170 } 5171 elsif ($before) { 5172 # this shouldn't happen !! 5173 print STDERR "\nCannot handle \\$cmd , since there is no $cmd_sub "; 5174 $after = $before . $cmd . $after; 5175 $before = ''; 5176 } else { 5177 push(@processed, "\\$cmd ") if $cmd; 5178 } 5179 } 5180 print "\nmeta-commands: ". (0+@processed) ." found " 5181 if ((@processed)&&($VERBOSITY > 1)); 5182 $_ = join('',@processed, $after); undef @processed; 5183 if ($PREAMBLE) { 5184 # MRO: replaced $* with /m 5185 s/((\n$comment_mark\d*)+\n)//gm; 5186 s/(\\par\b\s*\n?)+/\\par\n/gm; 5187 s/(\\par\b\n?)+/\\par\n/gm; 5188 } 5189 5190 # hard-code the new-command replacements for these 5191 $new_command{'begingroup'} = "0:!:\\begin<<0>>tex2html_begingroup<<0>>:!:}"; 5192 $new_command{'endgroup'} = "0:!:\\end<<0>>tex2html_begingroup<<0>>:!:}"; 5193 $new_command{'bgroup'} = "0:!:\\begin<<0>>tex2html_bgroup<<0>>:!:}"; 5194 $new_command{'egroup'} = "0:!:\\end<<0>>tex2html_bgroup<<0>>:!:}"; 5195 5196 # All the definitions have now moved to the $preamble and their bodies 5197 # are stored in %new_command and %new_environment 5198 # 5199 # Now substitute the new commands and environments: 5200 # (must do them all together because of cross definitions) 5201 $new_cmd_rx = &make_new_cmd_rx(keys %new_command); 5202 $new_cmd_no_delim_rx = &make_new_cmd_no_delim_rx(keys %new_command); 5203 $new_env_rx = &make_new_env_rx; 5204 $new_end_env_rx = &make_new_end_env_rx; 5205# $new_cnt_rx = &make_new_cnt_rx(keys %new_counter); 5206 $new_cmd_or_env_rx = join("|", $new_cmd_no_delim_rx." ", $new_env_rx); 5207# $new_cmd_or_env_rx = join("|", $new_cmd_no_delim_rx." ", $new_env_rx, " ".$new_cnt_rx); 5208 $new_cmd_or_env_rx =~ s/^ \||\|$//; 5209 5210 print STDOUT "\nnew commands:\n" if ($VERBOSITY > 2); 5211 while (($cmd, $body) = each %new_command) { 5212 unless ($expanded{"CMD$cmd"}++) { 5213 print STDOUT ".$cmd " if ($VERBOSITY > 2); 5214 $new_command{$cmd} = &expand_body; 5215 print STDOUT " ".$new_command{$cmd}."\n" if ($VERBOSITY > 4); 5216 &write_mydb("new_command", $cmd, $new_command{$cmd}); 5217 } 5218 } 5219 5220 print STDOUT "\nnew environments:\n" if ($VERBOSITY > 2); 5221 while (($cmd, $body) = each %new_environment) { 5222 unless ($expanded{"ENV$cmd"}++) { 5223 print STDOUT ".$cmd" if ($VERBOSITY > 2); 5224 $new_environment{$cmd} = &expand_body; 5225 &write_mydb("new_environment", $cmd, $new_environment{$cmd}); 5226 } 5227 } 5228 5229 print STDOUT "\nnew counters and dependencies:\n" if ($VERBOSITY > 2); 5230 &clear_mydb("dependent") if ($DEBUG); #avoids appending to a previous version 5231 while (($cmd, $body) = each %dependent) { 5232 print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2); 5233 &write_mydb("dependent", $cmd, $dependent{$cmd}); 5234 } 5235 &clear_mydb("img_style") if ($DEBUG); #avoids appending to a previous version 5236 while (($cmd, $body) = each %img_style) { 5237 &write_mydb("img_style", $cmd, $img_style{$cmd}); 5238 } 5239 5240 &clear_mydb("depends_on") if ($DEBUG); #avoids appending to a previous version 5241 while (($cmd, $body) = each %depends_on) { 5242 print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2); 5243 &write_mydb("depends_on", $cmd, $depends_on{$cmd}); 5244 } 5245 5246 5247 &clear_mydb("styleID") if ($DEBUG); #avoids appending to a previous version 5248 while (($cmd, $body) = each %styleID) { 5249 &write_mydb("styleID", $cmd, $styleID{$cmd}); 5250 } 5251 5252 &clear_mydb("env_style") if ($DEBUG); #avoids appending to a previous version 5253 while (($cmd, $body) = each %env_style) { 5254 &write_mydb("env_style", $cmd, $env_style{$cmd}); 5255 } 5256 &clear_mydb("txt_style") if ($DEBUG); #avoids appending to a previous version 5257 while (($cmd, $body) = each %txt_style) { 5258 &write_mydb("txt_style", $cmd, $txt_style{$cmd}); 5259 } 5260 5261 print STDOUT "\ntheorem counters:\n" if ($VERBOSITY > 2); 5262 &clear_mydb("new_theorem") if ($DEBUG); #avoids appending to a previous version 5263 while (($cmd, $body) = each %new_theorem) { 5264 print STDOUT ".($cmd,$body)" if ($VERBOSITY > 2); 5265 &write_mydb("new_theorem", $cmd, $new_theorem{$cmd}); 5266 } 5267 5268 5269 print "+"; 5270 if (length($new_env_rx)) { 5271 local(@pieces); 5272 print STDOUT "\nsubstituting new environments: $new_env_rx\n" if ($VERBOSITY > 3); 5273# while (/\n?$new_env_rx/ && (($before, $cmd, $after) = ($`, $2, $'))) { 5274 while (/$new_env_rx/ && (($before, $cmd, $after) = ($`, $2, $'))) { 5275 print STDOUT ","; 5276 print STDOUT "{$cmd}" if ($VERBOSITY > 1); 5277 if (!($before =~ /$new_env_rx/)) { 5278 push (@pieces, $before); $before = ''; print "{}"; 5279 } 5280 $_ = join('',$before, &substitute_newenv); 5281 } 5282 print "\n ".(0+@pieces). " new environments replaced\n" if (@pieces); 5283 $_ = join('', @pieces, $_); undef @pieces; 5284 } 5285 5286 5287 print "+"; 5288 if (length($new_cmd_rx)) { 5289 print STDOUT "\ntokenizing: $new_cmd_rx\n" if ($VERBOSITY > 2); 5290 &tokenize($new_cmd_rx); # Put delimiter after the new commands 5291 5292 # and use the delimiter. 5293 print STDOUT "\nsubstituting new commands: $new_cmd_rx\n" if ($VERBOSITY > 2); 5294 print STDOUT "\ninitial size: ".length($after) if ($VERBOSITY > 1); 5295 # store processed pieces in an array 5296 local($this_cmd, @pieces); 5297 # speed-up processing of long files by splitting into smaller segments 5298 # but don't split within the preamble, else \newenvironment may break 5299 local($pre_segment,@segments); &make_sections_rx; 5300 local($within_preamble,$this_section) = 1 if ($PREAMBLE>1); 5301 while (/$sections_rx/) { 5302 $pre_segment .= $`; $_ = $'; $this_section = $&; 5303 do { 5304 push(@segments,$pre_segment); 5305 $pre_segment = ''; 5306 } unless ($within_preamble); 5307 $within_preamble = 0 if ($within_preamble && ($pre_segment =~ 5308 /\\(startdocument|begin\s*($O\d+${C})\s*document\s*\2)/)); 5309 $pre_segment .= $this_section; 5310 } 5311 push(@segments,$pre_segment.$_); 5312 local($replacements,$seg) ; $before = ''; # count the segments 5313 local($within_preamble) = 1 if ($PREAMBLE>1); 5314 foreach $after (@segments) { 5315 while ($after =~ /(\\(expandafter|noexpand)\b\s*)?$new_cmd_no_delim_rx\b\s?/) { 5316 ($before, $xafter, $cmd, $after) = ($`, $2, $3, $'); 5317 $within_preamble = 0 5318 if ($before =~ /\\(startdocument|begin\s*($O\d+${C})\s*document\s*\2)/); 5319 push(@pieces, $before); 5320 print "."; ++$replacements; 5321 print STDOUT "$cmd" if ($VERBOSITY > 2); 5322 if ($xafter =~ /no/) { $this_cmd = "\\\@#\@\@".$cmd } 5323 elsif (($xafter =~ /after/)&&($after =~ /^\s*\\/)) { 5324 local($delayed) = $cmd; 5325 local($nextcmd); 5326 $after =~ s/^\s*\\([a-zA-Z]+|.)/$nextcmd = $1;''/eo; 5327 ($cmd,$nextcmd) = ($nextcmd, "do_cmd_$nextcmd"); 5328 if (defined &$nextcmd) { $after = &$nextcmd($after); } 5329 elsif ($new_command{$cmd}) { 5330 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 5331 &make_unique($body) if ($body =~ /$O/); 5332 if ($argn) { 5333 do { 5334 local($before) = ''; 5335 $after = join('',&substitute_newcmd, $after); 5336 $after =~ s/\\\@#\@\@/\\/o ; 5337 }; 5338 } else { $after = $body . $after; } 5339 } else { print "\nUNKNOWN COMMAND: $cmd "; } 5340 $cmd = $delayed; 5341 if ($new_command{$cmd}) { 5342 if ($renew_command{$cmd}) { 5343# # must wrap it in a deferred environment 5344# $this_cmd = join('', &make_deferred_wrapper(1) 5345# ,"\\$cmd".(($cmd =~ /\w$/)? " ":'') 5346# , &make_deferred_wrapper(0)); 5347# push(@pieces, $this_cmd); $this_cmd = ''; 5348 push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":'')); 5349 $this_cmd = ''; 5350 } elsif ($provide_command{$cmd}&&$within_preamble) { 5351 # leave it alone 5352 push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":'')); 5353 $this_cmd = ''; 5354 } else { 5355 # do the substitution 5356 $this_cmd = &substitute_newcmd; 5357 } 5358 } 5359 } elsif ($renew_command{$cmd}) { 5360 # leave it alone 5361 push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":'')); 5362 $this_cmd = ''; 5363 } elsif (($provide_command{$cmd})&&($within_preamble)) { 5364 # leave it alone 5365 push(@pieces, "\\$cmd".(($cmd =~ /\w$/)? " ":'')); 5366 $this_cmd = ''; 5367 } else { 5368 # do the substitution 5369 $this_cmd = &substitute_newcmd if ($new_command{$cmd}); 5370 } 5371 if ($this_cmd =~ /(\\(expandafter|noexpand)\s*)?$new_cmd_no_delim_rx\b\s?/) 5372 { $after = $this_cmd . $after } 5373 elsif ($this_cmd) { push(@pieces, $this_cmd) } 5374 } 5375 push(@pieces, $after); 5376 } 5377 print " $replacements new-command replacements\n" 5378 if (($VERBOSITY>1) && $replacements); 5379 # recombine the processed pieces 5380 $_ = join('', @pieces); undef @pieces; 5381 print STDOUT ", resulting size: ".length($_)." " if ($VERBOSITY > 1); 5382 $_ =~ s/\\\@#\@\@/\\/go; 5383 } 5384 5385 print STDOUT "\n *** substituting metacommands done ***\n" if ($VERBOSITY > 3); 5386} 5387 5388sub insert_command_expansion { 5389 ($xafter, $cmd) = @_; 5390# push(@pieces, $_[1]); 5391 print ".$cmd"; 5392 print STDOUT "$_[3]" if ($VERBOSITY > 2); 5393# $xafter = $_[2]; 5394# $cmd = $_[3]; 5395 if ($xafter =~ /no/) { $this_cmd = "\\\@#\@\@".$cmd } 5396 elsif (($xafter =~ /after/)&&($after =~ /^\s*\\/)) { 5397 local($delayed,$nextcmd) = ($_[3],''); 5398 5399 $after =~ s/^\s*\\([a-zA-Z]+|.)/$nextcmd = $1;''/eo; 5400 ($cmd,$nextcmd) = ($nextcmd, "do_cmd_$nextcmd"); 5401 if (defined &$nextcmd) { $after = &$nextcmd($after); } 5402 elsif ($new_command{$cmd}) { 5403 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 5404 &make_unique($body) if ($body =~ /$O/); 5405 if ($argn) { 5406 do { 5407 local($before) = ''; 5408 $after = join('',&substitute_newcmd, $after); 5409 $after =~ s/\\\@#\@\@/\\/o ; 5410 }; 5411 } else { $after = $body . $after; } 5412 } else { print "\nUNKNOWN COMMAND: $cmd "; } 5413 $cmd = $delayed; 5414 $this_cmd = &substitute_newcmd if ($new_command{$cmd}); 5415 } else { 5416 $this_cmd = &substitute_newcmd if ($new_command{$cmd}); 5417 } 5418# if ($this_cmd =~ /(\\(expandafter|noexpand)\s*)?$new_cmd_no_delim_rx\s?/){ 5419# $after = $this_cmd . $after 5420# } else { push(@pieces, $this_cmd); } 5421 $this_cmd; 5422} 5423 5424 5425sub expand_body { 5426 return unless length($new_cmd_or_env_rx); 5427 local($_) = $body; 5428 local($cmd,$saveafter,$avoid_looping); 5429 # Uses $before, $body, $arg, etc. of the caller, but not $cmd. 5430 # Uses $new_cmd_rx (resp. $new_cmd_no_delim_rx) and $new_env_rx 5431 # set in the caller, of which one might be empty. 5432 5433 # Puts delimiter after the new commands ... 5434 &tokenize($new_cmd_rx) if length($new_cmd_rx); 5435 5436 while (/$new_cmd_or_env_rx/) { 5437 # $new_cmd_rx binds $1, and $new_env_rx binds $3. 5438 ($before,$cmd,$after,$saveafter) = ($`,$1.$3,$',$'); 5439 if (length($new_command{$cmd})) { # We have a command 5440 # this tokenizes again 5441 local($replace) = &substitute_newcmd; # sets $_, changes $after 5442 if (!($replace)) { 5443 # protect name of unexpanded macro 5444 $_ = join('', $before ,"\\@#@@", $cmd, $saveafter ); 5445 } else { 5446 $_ = join('', $before , $replace, $after ); 5447 } 5448 } elsif (length($new_environment{$cmd})) { 5449 $_ = join('',$before, &substitute_newenv); 5450 } 5451 last if $avoid_looping; 5452 } 5453 # remove protection from unreplaced macro names 5454 s/\\\@#\@\@/\\/go; 5455 5456 # remove trivial comments 5457 s/(\\\w+)$comment_mark\d*\n[ \t]*/$1 /go; 5458 s/$comment_mark\d*\n[ \t]*//go; 5459# s/($O\d+$C)?($comment_mark\n)[ \t]*/($1 ? $1.$2 : '')/eg; 5460 5461 $_; 5462} 5463 5464 5465sub substitute_newcmd { 5466 # Modifies $after in the caller 5467 # Get the body from the new_command array 5468 local($tmp,$cnt,$saved, $arg, $isword) = ('',0,$cmd); 5469 local($argn, $_, $opt) = split(/:!:/, $new_command{$cmd}); 5470 $avoid_looping = 1 if ($new_command{$cmd} =~ /\\$cmd\b/); 5471 5472 &tokenize($new_cmd_rx); # must do it again for newly inserted cmd bodies 5473 print STDOUT "\nNEW:$cmd:$_" if ($VERBOSITY > 5); 5474 foreach $i (1..$argn) { 5475 $arg = $isword = ''; 5476 if ($i == 1 && $opt ne '}') { 5477 $arg = ($after =~ s/$optional_arg_rx//o) ? $1 : $opt; 5478 } 5479 else { 5480 # Get the next argument, if not in braces, get next character 5481 #RRM: allow also for processed braces, in case substitution 5482 # was delayed; e.g. by \renewcommand 5483 if (!(($after =~ s/$next_pair_rx/$arg = $2;''/e) 5484 ||($after =~ s/$next_pair_pr_rx/$arg = $2;''/e))) { 5485 $after =~ s/^\s*(\\[a-zA-Z]+|.)/$arg = $1;''/e; 5486 } 5487 if ($arg eq '#') { 5488 &write_warnings("\nSubstitution of arg to $cmd delayed."); 5489 $_ = "\\\@#\@\@$saved"; 5490 return (); 5491 }; 5492 } 5493 $arg =~ s/(^|\G|[^\\])\\\#/$1$hash_mark/gs; 5494 $arg =~ s/\#/$param_mark/gs; 5495 5496 #RRM: Substitute the arguments in the body one at a time 5497 # else multiple instances would fail in &make_unique 5498 5499 # First protect ## parameters in TeX-like substitutions 5500 # suggested by Dirk Pleiter (Berlin) 5501 s/((^|[^\\])(\\\\)*)\#\#$i/$1$protected_hash/gs; 5502 $tmp = $_; 5503 $cnt = $tmp =~ s/\#$i//g ; 5504 $isword = 1 if ($arg =~ /^\w/); 5505 if ($cnt > 1 ) { 5506 $tmp = $_; 5507 while ($cnt > 1) { 5508 if ( s/(\\\w+)?\#$i/(($1&&$isword)? $1.' ': '').$arg/e) { 5509 &make_unique($_) if ($arg =~ /$O/ ); 5510 &make_unique_p($_) if ($arg =~ /$OP/ ); 5511 } 5512 $cnt--; 5513 } 5514 $tmp = $_; 5515 } 5516# s/(\\\w+)?\#$i/(($1&&$isword)? $1.' ': '').$arg/e ; 5517 s/(\\\w+)?\#$i/$1.(($1&&$isword)? ' ': '').$arg/e ; 5518 print "\n *** substitution: $arg \nfor \#$i in \\$cmd did not take ***\n" 5519 if (/\#$i/); 5520 &write_warnings("incomplete substitution in a \\$cmd command:\n$_") if (/\#$i/); 5521 s/$protected_hash/\#$i/g; 5522 } 5523 s/$param_mark/\#/g; 5524 s/$hash_mark/\\\#/g; 5525 s/(\\\w+)$/$1 /s; 5526 5527 # Make the body unique (give unique id's to the brackets), 5528 # translate, and return it 5529 &make_unique($_); 5530 if ($avoid_looping) { 5531 s/\\$cmd\b/\\csname $cmd\\endcsname/g; 5532 print STDERR "\n *** possible looping with new-command \\$cmd ***\n"; 5533 &write_warnings("\npossible looping with new-command \\$cmd "); 5534 } 5535 print STDOUT "\nOUT:$cmd:$_" if ($VERBOSITY > 5); 5536 5537# Insert a space to prevent letters from clashing together with a 5538# letter command. Consider this: 5539# New command substitution is restricted to commands introduced by 5540# \newcommand etc. (so-called meta commands), but it is not done 5541# for already defined commands, eg. \large. 5542# But new command, as well as new environment, substitution is done 5543# prior to any other substitution. 5544# So \newcommand{\this}{...} {\large\this b} will get expanded the 5545# following way: 5546# 1. \newcommand{\this}{...} 5547# is handled by &substitute_meta_cmds, it gets the definition 5548# of \this and stores it within a table, %new_command. 5549# After all new commands are recognized, &expand_body is called 5550# to expand one command body from each other. That's O(n*n)! 5551# 2. A regular expression $new_cmd_rx is built containing a pattern 5552# that matches all occurrences of a properly delimited \this 5553# macro. When matching, ensuing white space gets lost. 5554# (But only for letter commands, see also &make_new_cmd_rx.) 5555# Another regular expression called $new_cmd_no_delim_rx is built 5556# which matches exact the \this, and would also match the prefix 5557# of \thisx. 5558# 3. The *whole* text is tokenized using $new_cmd_rx, with separates 5559# \this from the ensuing text by one white space. 5560# 4. Then $new_cmd_no_delim_rx together with the delimiting space 5561# is used to substitute \this with its body. 5562# 5. The following situations may occur: 5563# a) ... is some text (no macros) => {\large<text>yyy} 5564# Then we must prevent that the text clashes into \large. 5565# This is only dangerous when <text> begins with a letter. 5566# b) ... contains another, not expanded new command. 5567# This happens during &expand_body. 5568# In this case, make sure to &tokenize the body before giving 5569# the result to the caller. Also take care that leading letters 5570# of the body cannot clash into \large. 5571# e) ... contains a macro not known as new command: 5572# Make sure that the macro cannot clash with the ensuing yyy. 5573# f) ... is empty: 5574# Make sure that \large cannot clash with yyy. 5575# 6. We prevent clashing by inserting a delimiting blank. 5576# Out of the scetched situation, there are three conditions to 5577# take care of: 5578# a) empty body, left a letter command, right a letter => blank 5579# b) body starts with letter, left a letter command => blank 5580# c) body ends with letter command, right a letter => blank 5581# d) else => no blank, clash all together, it will work. 5582# 7. With this rules, the expansion should work quite well, 5583# concerning letter/non-letter commands and white space 5584# handling. 5585# 8. Deficiencies: 5586# 8.1 Consider \this<CR>that. It's handled this way: 5587# a) The \this swallows the <CR> in LaTeX, but what LaTeX2HTML does 5588# is to &tokenize the expression into \this <CR>that. 5589# b) If ... is some text, it results in <text><CR>that. 5590# c) If ... is a macro (or command, or control sequence, these 5591# terms are often mixed up, but effectively mean the same), 5592# then if the macro later takes at least one argument, the <CR> 5593# might get swallowed, this depends on the grace of $next_pair_rx 5594# resp. $next_pair_pr_rx. 5595# If the macro takes no arguments, the <CR> remains in the text. 5596# d) If ... ends in another new command, the problem repeats. 5597# 8.2 The new commands are substituted in a very insensitive way. 5598# If \this occurs within an environment which sees \this 5599# totally different, there's no chance to substitute \this in 5600# a different way. 5601# 8.3 In relation to 8.2 a similar problem arises when the meta 5602# command, or several meta commands redefining \this, occur 5603# amongst several \this macros. 5604# 8.4 In raw TeX like environments it is not possible to revert the 5605# expansion of \this, but \this probably *must* occur in its 5606# raw form. 5607 5608# Handle the cases as depicted in the description of new command 5609# substitution. 5610 local($befdel,$aftdel); 5611 $befdel = ' ' 5612 if ($before=~/(^|[^\\])\\[a-zA-Z]+$/ && /^$/ && $after=~/^[a-zA-Z]/) || 5613 ($before=~/(^|[^\\])\\[a-zA-Z]+$/ && /^[a-zA-Z]/); 5614 $aftdel = ' ' 5615 if /(^|[^\\])\\[a-zA-Z]+$/s && $after=~/^[a-zA-Z]/; 5616 join('', $befdel, $_, $aftdel); 5617} 5618 5619#RRM: use this to test whether a specific command is substituting correctly 5620sub trace_cmd { 5621 local($this) = @_; 5622 if ($cmd eq $this) { print "\n$1=>$id:$2::"} 5623} 5624 5625# Make the text unique (give unique id's to the brackets). 5626# The text shouldn't contain processed brackets. 5627sub make_unique { 5628 # MRO: Change to references $_[0] 5629 # local(*_) = @_; 5630 my $id = $global{'max_id'}; 5631 # MRO: replaced $* by /m 5632 # this looks quite funny but is optimized 5633 1 while($_[0] =~ s/$O(\d+)$C([\w\W]*)$O\1$C/$id++;"\000$id $2\000$id "/geom); 5634 $_[0] =~ s/\000(\d+) /$O$1$C/gom; 5635 $global{'max_id'} = $id; 5636} 5637 5638#RRM: this shouldn't be needed, but just in case... 5639sub make_unique_p { 5640 # MRO: Change to references $_[0] 5641 my $id = $global{'max_id'}; 5642 # MRO: replaced $* by /m 5643 # this looks quite funny but is optimized 5644 1 while($_[0] =~ s/$OP(\d+)$CP([\w\W]*)$OP\1$CP/$id++;"\000$id $2\000$id "/geom); 5645 $_[0] =~ s/\000(\d+) /$OP$1$CP/gom; 5646 $global{'max_id'} = $id; 5647} 5648 5649 5650sub substitute_newenv { 5651 # Modifies $cmd and $after in the caller 5652 # Get the body from the new_environment array 5653 local($argn, $begdef, $enddef, $opt) = split(/:!:/, $new_environment{$cmd}); 5654 local($arg,$new_def_rx,$tmp,$cnt); 5655 5656 # Note that latex allows argument substitution only in the 5657 # \begin part of the new definition 5658 foreach $i (1..$argn) { # Process the arguments 5659 if (($i == 1) && ($opt ne '}')) { 5660 $after =~ s/$optional_arg_rx/$arg = $1;''/eo; 5661 $arg = $opt unless $arg; 5662 } 5663 else { 5664 $after =~ s/$next_pair_rx/$arg = $2;''/eo; 5665 } 5666 $arg =~ s/(^|[^\\])\\\#/$1$hash_mark/g; 5667 $arg =~ s/\#/$param_mark/g; 5668 5669 #RRM: multiple instances can fail later in &make_unique 5670# s/\#$i/$arg/g; # Substitute the arguments in the body 5671 #RRM: ...so do one at a time and &make_unique_p 5672 $tmp = $begdef; 5673 $cnt = $tmp =~ s/\#$i//g ; 5674 if ($cnt > 1) { 5675 $tmp = $begdef; 5676 while ($cnt > 1) { 5677 if ( $begdef =~ s/\#$i/$arg/) { 5678 &make_unique($begdef) if ($arg =~ /$O/ ); 5679 &make_unique_p($begdef) if ($arg =~ /$OP/ ); 5680 } 5681 $cnt--; 5682 } 5683 $tmp = $_; 5684 } 5685 $begdef =~ s/\#$i/$arg/ ; 5686 print "\n *** substitution: $arg \nfor \#$i in {$cmd} did not take ***\n" 5687 if ($begdef =~ /\#$i/); 5688 &write_warnings("incomplete substitution in a {$cmd} environment:\n$begdef") 5689 if ($begdef =~ /\#$i/); 5690 } 5691 $begdef =~ s/$param_mark/\#/g; 5692 $begdef =~ s/$hash_mark/\\\#/g; 5693 $begdef =~ s/(\\\w+)$/$1 /s; 5694 5695 # Make the body unique (Give unique id's to the brackets), 5696 # translate, and return it 5697#RRM: when are these needed ? 5698# $_ = &revert_to_raw_tex($_); 5699# &pre_process; 5700 5701 &make_unique($begdef); # Make bracket IDs unique 5702 print STDOUT "\nBEGIN:$cmd:$begdef" if ($VERBOSITY > 4); 5703 5704 # Now substitute the \end part: 5705#RRM: when are these needed ? 5706# $_ = &revert_to_raw_tex($enddef); 5707# &pre_process; 5708 5709 &make_unique($enddef); # Make bracket IDs unique 5710 print STDOUT "\nEND:$cmd:$enddef" if (($enddef)&&($VERBOSITY > 4)); 5711 $enddef =~ s/(\\\w+)$/$1 /s; 5712 5713 local($new_end_def_rx) = &make_end_env_rx($cmd); 5714 if (($enddef)&&!($after =~ s/\n?$new_end_def_rx/$enddef/ )) { 5715 $UNFINISHED_ENV = $new_end_def_rx; 5716 $REPLACE_END_ENV = $enddef; 5717 }; 5718 join('',$begdef,$after); 5719} 5720 5721sub substitute_pars { 5722 s/((\%|$comment_mark\d*)|.)(\r*\n[ \t]*){2,}[ \t]*/$1\n\\par \n/og; 5723# s/((\%|$comment_mark\d*)|\d|.)[\r\n\015]{2,}/print "\nPAR:".$`.$&;"$1\n\\par \n"/egs; 5724} 5725 5726sub do_cmd_end { #RRM: catches the end of any unclosed environments 5727 local($_) = @_; 5728 &missing_braces unless ( 5729 (s/$next_pair_pr_rx//o)||(s/$next_pair_rx//o)); 5730 s/^\n//; 5731 $_; 5732} 5733 5734# Removes the definition from the input string, 5735# adds to the preamble unless it is part of the preamble already 5736# and stores the body in %new_command; 5737sub get_body_newcommand { 5738 local($newed, $n_after) = &process_body_newcommand(0,@_); 5739 (($PREAMBLE)? "newed".$newed : ''); 5740} 5741 5742sub process_body_newcommand { 5743# local($renewed,*_) = @_; 5744 local($renewed,$after_R) = @_; 5745 local($_) = $$after_R; 5746 local($no_change) = $_; 5747 local($argn,$newcmd,$cmd_br,$body,$body_br,$tmp,$tmp1,$opt,$pat); 5748 local($new_cmd) = 'command'; 5749 if ($renewed =~ /provide/||$renewed == 2) { 5750 # $newcmd = &missing_braces unless ( 5751 ($newcmd,$pat) = &get_next(1) unless ( 5752 (s/$next_pair_pr_rx/$pat=$&;$newcmd=$2;''/e) 5753 ||(s/$next_pair_rx/$pat=$&;$newcmd=$2;''/e)); 5754 if (!$pat) { 5755 local($br_id) = ++$global{'max_id'}; 5756 $pat = "$O$br_id$C".$newcmd."$O$br_id$C"; 5757 } 5758 } else { 5759 ($newcmd,$pat) = &get_next(1); # Get command name 5760 } 5761 $pat =~ s/\\//; $new_cmd .= $pat; 5762 $newcmd =~ s/^\s*\\//; 5763 ($argn,$pat) = &get_next(0); # Get optional no. of args 5764 $argn = 0 unless $argn; $new_cmd .= $pat if $argn; 5765 local($cmd) = $newcmd; 5766 5767 # Get the body of the code and store it with the name and number of args 5768 # UNLESS THE COMMAND IS ALREADY DEFINED 5769 # ...in which case $ALLOW_REDEFINE must also have been set. # RRM 5770 # (This is the mechanism with which raw html can be ignored in a Latex document 5771 # but be recognised as such by the translator). 5772 $opt = '}'; # Flag for no optional arg 5773 local($bodyA) = ''; 5774 if (/^\[/) { 5775 ($opt,$pat) = &get_next(0); 5776 $new_cmd .= $pat; 5777 $bodyA .= "\n".'($dummy, $pat) = &get_next_optional_argument;' . 5778 "\n". '$args .= $pat;'; 5779 } 5780 local($nargs) = $argn; 5781 while ($nargs > 0) { $nargs--; 5782 $bodyA .= 5783 "\n".'$args .= $`.$& if ((s/$next_pair_pr_rx//o)||(s/$next_pair_rx//o));'; 5784 } 5785 if ($renewed =~ /provide/||$renewed == 2 ) { 5786 $body = &missing_braces unless ( 5787 (s/$next_pair_pr_rx/$pat=$&;$body=$2;''/e) 5788 ||(s/$next_pair_rx/$pat=$&;$body=$2;''/e)); 5789 $new_cmd .= $pat; 5790 } else { 5791 ($body,$pat) = &get_next(4); #get the body 5792 $new_cmd .= $pat; 5793 } 5794 5795 local($thisone); 5796# $thisone = 1 if ($cmd =~ /div|vec/); # for debugging 5797 5798 $tmp = "do_cmd_$cmd"; 5799 local($wtmp) = "wrap_cmd_$cmd"; 5800 if ((defined &$tmp)||(defined &$wtmp)){ 5801 # command already exists, so \providecommand does nothing 5802 # but may still be needed in images.tex 5803 $$after_R = $_; 5804 return ($new_cmd) if ($renewed =~ /provide/); 5805 5806 print "\n*** redefining \\$cmd ***\n"; 5807 &write_warnings("\nredefining command \\$cmd "); 5808 if (!$ALLOW_REDEFINE) { 5809 print "*** overriding previous meaning ***\n"; 5810 &write_warnings("\nprevious meaning of \\$cmd will be lost"); 5811 } 5812# local($code) = "undef \&$tmp"; eval ($code); 5813# if ($@) {print "\n*** undef \&$cmd failed \n"} 5814 if ((!$PREAMBLE)||($renewed>1)) { 5815 $new_command{$cmd} = join(':!:',$argn,$body,$opt); 5816# local($code) = "sub $tmp\{\&replace_new_command(\"$cmd\");\}"; 5817# eval $code; 5818# print STDERR "\n*** sub do_cmd_$cmd failed:\nPERL: $@\n" if ($@); 5819# &replace_new_command($cmd); 5820 } 5821 5822 $renew_command{$cmd} = 1; 5823 &write_mydb("renew_command", $cmd, $renew_command{$cmd}); 5824 local($padding) = " "; 5825 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 5826 # Generate a new subroutine 5827 local($codeA) = "sub wrap_cmd_$cmd {" . "\n" 5828 .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";' 5829 . $bodyA 5830 . (($thisone)? "\nprint \"\\nwrap $cmd:\".\$args.\"\\n\";" : '') 5831 . "\n".'(&make_deferred_wrapper(1).$cmd.' 5832 . "\"$padding\"".'.$args.&make_deferred_wrapper(0),$_)}' 5833 . "\n"; 5834 print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging 5835 eval $codeA; 5836 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 5837 $raw_arg_cmds{$cmd} = 1; 5838 5839 } elsif (($ALLOW_REDEFINE)&&($PREAMBLE < 2)) { 5840 print "\n*** redefining \\$cmd ***\n"; 5841 &write_warnings("\ncommand \\$cmd had no previous definition") 5842 if (!($new_command{$cmd})); 5843 } 5844 if ($renewed && ($PREAMBLE > 1) &&($new_command{$cmd})) { 5845 $raw_arg_cmds{$cmd} = 1 ; 5846 $renew_command{$cmd} = 1; 5847 local($padding) = " "; 5848 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 5849 # Generate a new subroutine 5850 local($codeA) = "sub wrap_cmd_$cmd {" . "\n" 5851 .'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";' 5852 . $bodyA 5853 . (($thisone)? "\nprint \"\\nwrap $cmd:\".\$args.\"\\n\";" : '') 5854 . "\n".'(&make_deferred_wrapper(1).$cmd.' 5855 . "\"$padding\"".'.$args.&make_deferred_wrapper(0),$_)}' 5856 . "\n"; 5857 print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging 5858 eval $codeA; 5859 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 5860 5861 &write_mydb("renew_command", $cmd, $renew_command{$cmd}); 5862 } elsif ($renewed) { 5863 $new_command{$cmd} = join(':!:',$argn,$body,$opt); 5864 } else { 5865 $new_command{$cmd} = join(':!:',$argn,$body,$opt) 5866 unless (($PREAMBLE > 1)&&($renew_command{$cmd})); 5867 } 5868 5869 local($this_cmd); 5870 $this_cmd = join('' 5871 , "command{\\$cmd}" 5872 , ($argn ? "[$argn]" :'') 5873 , (($opt =~ /^}$/) ? '' : "[$opt]" ) 5874 , "{", $body , "}" ); 5875 $this_cmd = &revert_to_raw_tex($this_cmd); 5876 if ($renewed) { 5877 if ($renewed=~/provide/){ 5878 $provide_command{$cmd} = 1; 5879 &write_mydb("provide_command", $cmd, $provide_command{$cmd}); 5880# } else { 5881# print "\n ** marking $cmd as renewed **"; 5882# $renew_command{$cmd} = 1; 5883 }; 5884 if ((!$PREAMBLE)&&($renewed>1)) { 5885# local($this_cmd) = join('' 5886# , "\n\\renewcommand{\\$cmd}" 5887# , ($argn ? "[$argn]" :'') 5888# , (($opt =~ /^}$/) ? '' : "[$opt]" ) 5889# , "{", $body , "}\n" ); 5890# $latex_body .= &revert_to_raw_tex($this_cmd); 5891 $latex_body .= "\n\\renew". $this_cmd."\n"; 5892 } else { 5893## &add_to_preamble('command',"\\" . $this_cmd); 5894 } 5895 } else { 5896 &add_to_preamble('command',"\\new" . $this_cmd) 5897 unless ($PREAMBLE); 5898 } 5899 undef $body; 5900 if ($renewed == 2) { 5901 # there is no output to return 5902 $$after_R = $_; 5903 return(); 5904 } 5905 5906 if (!$PREAMBLE) { 5907 $$after_R = $_; 5908 return ($new_cmd) if ($renewed); 5909# $cmd_br =~ s/\\//; 5910# ( join ('', &make_deferred_wrapper(1) 5911# , "\\". ($renewed ? (($renewed =~ /provide/)? 'provid' : 'renew') 5912# : 'new')."edcommand" 5913# , $cmd_br , ($argn ? "[$argn]" :'') 5914# , ( ($opt =~ /^\}$/ ) ? '' : "[$opt]" ) , $body_br 5915# , &make_deferred_wrapper(0)) , $_ ); 5916 $new_cmd = join('', "command{\\$cmd}" 5917 , ($argn ? "[$argn]" :'') 5918 , (($opt =~ /^\}$/) ? '' : "[$opt]" ) 5919 , "{", $body , "}" ); 5920 $new_cmd = &revert_to_raw_tex($new_cmd); 5921 &add_to_preamble('command', "\\provide".$new_cmd ); 5922 $$after_R = $_; 5923 return(); 5924 } 5925 $new_cmd =~ s/\\$cmd([\d\W]|$)/$cmd$1/s; 5926 $$after_R = $_; 5927 $new_cmd; 5928} 5929 5930sub replace_new_command { 5931 local($cmd) = @_; 5932 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 5933 do { ### local($_) = $body; 5934 &make_unique($body); 5935 } if ($body =~ /$O/); 5936 $body =~ s/(^|[^\\])\~/$1\\nobreakspace /g; 5937 if ($argn) { 5938 do { 5939 local($before) = ''; 5940 local($after) = "\\$cmd ".$_; 5941 $after = &substitute_newcmd; # may change $after 5942 $after =~ s/\\\@#\@\@/\\/o ; 5943 }; 5944 } elsif ($body =~ /\\/) { 5945 $body = &translate_commands($body); # ??? 5946 $_ = $body . $_; 5947 } else { $_ = $body . $_; } 5948 $_; 5949} 5950 5951sub get_body_let { 5952# local(*_) = @_; 5953 local($_) = @_; 5954 local($cmd,$body,$replace,$tmp,$pat); 5955 ($cmd,$body) = &get_next_tex_cmd; 5956 s/^\s*=?\s*/$body .= $&;''/e; 5957 ($replace,$pat) = &get_next_tex_cmd; 5958# return() if ($replace eq $cmd); 5959 $body .= $pat; 5960 $body = &revert_to_raw_tex($body); 5961 &add_to_preamble('', "\\let ".$body ); 5962 $_[0] = $_; 5963 if (($replace eq $cmd)||($cmd="\\")||($cmd =~/(style|size)$/)) { 5964 "let ".$body 5965 } else { 5966 $new_command{$cmd} = join(':!:','',"\\$replace ",'}'); 5967 ''; 5968 } 5969} 5970 5971 5972# do not remove the \renewcommand code, since it may be needed 5973# within images. Instead replace it with \renewedcommand; 5974# This will be reverted in &revert_to_raw_tex 5975sub get_body_renewcommand { 5976 local($ALLOW_REDEFINE) = 1; 5977 local($renew, $n_after) = &process_body_newcommand(1,@_); 5978 ($renew ? 'renewed' . $renew : ''); 5979} 5980 5981sub do_cmd_renewedcommand { 5982 local($_) = @_; 5983 local($ALLOW_REDEFINE) = 1; 5984 &process_body_newcommand(2,\$_); 5985 $_ ; 5986} 5987 5988sub get_body_providecommand { 5989 local($provide, $n_after) = &process_body_newcommand('provide',@_); 5990 (($PREAMBLE && $provide) ? 'provided'.$provide : ''); 5991} 5992 5993sub do_cmd_providedcommand{ &do_cmd_renewedcommand(@_) } 5994 5995sub get_body_DeclareRobustCommand { 5996 local($provide, $n_after) = &process_body_newcommand('provide',@_); 5997 (($PREAMBLE && $provide) ? 'provided'.$provide : ''); 5998} 5999 6000sub get_body_DeclareMathOperator { 6001 local($after_R) = @_; 6002 local($_) = $$after_R; 6003 my $star; 6004 s/^\\DeclareMathOperator\s*(\*|star)/$star = $1;''/s; 6005 my ($mcmd,$patA) = &get_next(1); 6006 my ($mop,$patB) = &get_next(1); 6007 if ($star) { 6008 $patA .= "${O}0$C\\mathop${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_; 6009 } else { 6010 $patA .= "${O}0$C${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_; 6011 } 6012 local($provide, $n_after) = &process_body_newcommand('provide',\$patA); 6013 $$after_R = $patA; 6014 (($PREAMBLE && $provide) ? 'provided'.$provide : ''); 6015} 6016 6017sub get_body_DeclareMathOperatorstar { 6018 local($after_R) = @_; 6019 local($_) = $$after_R; 6020 my $star; 6021 s/^\\DeclareMathOperator\s*(\*|star)/$star = $1;''/s; 6022 my ($mcmd,$patA) = &get_next(1); 6023 my ($mop,$patB) = &get_next(1); 6024 $patA .= "${O}0$C\\mathop${O}1$C\\mathrm${patB}${O}1$C${O}0$C".$_; 6025 local($provide, $n_after) = &process_body_newcommand('provide',\$patA); 6026 $$after_R = $patA; 6027 (($PREAMBLE && $provide) ? 'provided'.$provide : ''); 6028} 6029 6030 6031# Removes the definition from the input string, adds to the preamble 6032# and stores the body in %new_environment; 6033sub get_body_newenvironment { 6034 local($newed,$after) = &process_body_newenvironment(0,@_); 6035 ( $PREAMBLE ? "newed".$newed : ''); 6036} 6037 6038sub process_body_newenvironment { 6039# local($renew,*_) = @_; 6040 local($renew,$after_R) = @_; 6041 local($_) = $$after_R; 6042 local($no_change) = $_; 6043 local($argn,$env,$begin,$end,$tmp,$opt,$pat); 6044 local($new_env) = 'environment'; 6045 if ($renew == 2) { 6046 $env = &missing_braces unless ( 6047 (s/$next_pair_pr_rx/$pat=$&;$env=$2;''/e) 6048 ||(s/$next_pair_rx/$pat=$&;$env=$2;''/e)); 6049 $new_env .= $pat; 6050 } else { 6051 ($env,$pat) = &get_next(1); # Get the environment name 6052 $env =~ s/^\s*\\//; $new_env .= $pat; 6053 } 6054 ($argn,$pat) = &get_next(0); # Get optional no. of args 6055 $argn = 0 unless $argn; $new_env .= $pat if $argn; 6056 6057 # Get the body of the code and store it with the name and number of args 6058 # UNLESS THE COMMAND IS ALREADY DEFINED (see get_body_newcommand) 6059 # ...in which case $ALLOW_REDEFINE must also have been set. # RRM 6060 $opt = '}'; # Flag for no optional arg 6061 if (/^\[/) { 6062 ($opt,$pat) = &get_next(0); 6063 $new_env .= $pat; 6064 } 6065 $tmp = "do_env_$env"; 6066 6067 if ($renewed == 2 ) { 6068 $begin = &missing_braces unless ( 6069 (s/$next_pair_pr_rx/$pat=$&;$begin=$2;''/e) 6070 ||(s/$next_pair_rx/$pat=$&;$begin=$2;''/e)); 6071 $new_env .= $pat; 6072 $end = &missing_braces unless ( 6073 (s/$next_pair_pr_rx/$pat=$&;$end=$2;''/e) 6074 ||(s/$next_pair_rx/$pat=$&;$end=$2;''/e)); 6075 $new_env .= $pat; 6076 } else { 6077 ($begin,$pat) = &get_next(1); $new_env .= $pat; 6078 ($end,$pat) = &get_next(1); $new_env .= $pat; 6079 } 6080 if ((defined &$tmp)&&($ALLOW_REDEFINE)) { 6081 print STDOUT "\n*** redefining environment {$env} ***\n"; 6082 &write_warnings("\nredefined environment {$env} "); 6083 } 6084 $new_environment{$env} = join(':!:', $argn, $begin, $end, $opt) 6085 unless ((defined &$tmp)&&(! $ALLOW_REDEFINE)); 6086 6087 if (!$PREAMBLE) { 6088 $new_env = join ('', 6089 , "environment{$env}" 6090 , ($argn ? "[$argn]" : '') 6091 , (($opt ne '}')? "[$opt]" : '') 6092 , "{$begin}{$end}" 6093 ); 6094 &revert_to_raw_tex($new_env); 6095 if ($renew == 2) { 6096 $latex_body .= "\n\\".($renew ? 're':'').'new'.$new_env."\n"; 6097 } else { 6098 &add_to_preamble ('environment' 6099 , "\\".($renew ? 're':'').'new'.$new_env ); 6100 } 6101 $$after_R = $_; 6102 return(); 6103 } 6104 if ($new_env =~ /$sections_rx/) { 6105 $new_env = join('', $`,'\csname ',$2,'\endcsname',$3,$'); 6106 } 6107 $new_env =~ s/$par_rx/\\par /g; 6108 $$after_R = $_; 6109 $new_env; 6110} 6111 6112sub get_body_renewenvironment { 6113 local($ALLOW_REDEFINE) = 1; 6114 local($renewed, $after) = &process_body_newenvironment(1,@_); 6115 'renewed'.$renewed; 6116} 6117 6118sub do_cmd_renewedenvironment { 6119 local($ALLOW_REDEFINE) = 1; 6120 local($_) = @_; 6121 &process_body_newenvironment(2,\$_); 6122 $_; 6123} 6124 6125# Instead of substituting as with newcommand and newenvironment, 6126# or generating code to handle each new theorem environment, 6127# it now does nothing. This forces theorem environments to be passed 6128# to latex. Although it would be possible to handle theorem 6129# formatting in HTML as it was done previously it is impossible 6130# to keep the theorem counters in step with other counters (e.g. equations) 6131# to which only latex has access to. Sad... 6132sub get_body_newtheorem { 6133# local(*_) = @_; 6134 local($after_R) = @_; 6135 local($_) = $$after_R; 6136 my ($orig, $body) = ($_, ''); 6137 my ($title, $env, $ctr, $within, $cmd, $tmp, $begin, $end, $pat); 6138 my ($new_thm) = 'theorem'; 6139 # Just chop off the arguments and append to $next_def 6140 ($env,$pat) = &get_next(1); $new_thm .= $pat; 6141 ($ctr,$pat) = &get_next(0); $new_thm .= $pat; 6142 ($title,$pat) = &get_next(1); $new_thm .= $pat; 6143 ($within,$pat) = &get_next(0); $new_thm .= $pat; 6144 6145 #check the style parameters 6146 my ($hfont,$bfont,$thm_style); 6147 my ($before_thm) = join('',@processed); 6148 my ($which,$cmds); 6149 while ($before_thm =~ /$theorem_cmd_rx/) { 6150 $which = $1; 6151 $before_thm = $'; 6152 $before_thm =~ s/$next_pair_rx/$cmds = $2;''/e; 6153 $cmds =~ s/\\/\|/g; # escape any backslash 6154 if ($which =~ /style/) { $thm_style = $cmds } 6155 elsif ($which =~ /header/) { $hfont = $cmds } 6156 elsif ($which =~ /body/) { $bfont = $cmds } 6157 } 6158 $hfont = '['.$hfont.']'; 6159 $bfont = '['.$bfont.']'; 6160 $thm_style = '['.$thm_style.']'; 6161 undef $before_thm; 6162 6163 if (!($ctr)) { 6164 # define the new counter 6165 $ctr = $env; 6166 do { 6167### local($_) = "\\arabic<<1>>$ctr<<1>>"; 6168### $_ = join('',"\\the$within", "." , $_) if ($within); 6169 $body = "\\arabic<<1>>$ctr<<1>>"; 6170 $body = join('',"\\the$within", "." , $body) if ($within); 6171 &make_unique($body); 6172 $cmd = "the$ctr"; 6173 $tmp = "do_cmd_$cmd"; 6174 do { 6175 $new_command{$cmd} = join(':!:',0,$body,'}') 6176 } unless (defined &$tmp); 6177 &write_mydb("new_command", $cmd, $new_command{$cmd}); 6178 eval "sub do_cmd_$cmd {\n" 6179 . 'local($_,$ot) = @_;'."\n" 6180 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'."\n" 6181 . '&translate_commands(' . "\"$body\"" . ");\n}\n"; 6182 print STDERR "\n*** sub $tmp failed:\n$@\n" if ($@); 6183 $raw_arg_cmds{$cmd} = 1; 6184 undef $body; 6185 }; 6186 &do_body_newcounter($ctr); 6187 } else { 6188 do { 6189### local($_) = "\\arabic<<1>>$ctr<<1>>"; 6190 $body = "\\arabic<<1>>$ctr<<1>>"; 6191 &make_unique($body); 6192 $cmd = "the$env"; 6193 $tmp = "do_cmd_$cmd"; 6194 do { 6195 $new_command{$cmd} = join(':!:',0,$body,'}') 6196 } unless (defined &$tmp); 6197 &write_mydb("new_command", $cmd, $new_command{$cmd}); 6198 eval "sub do_cmd_$cmd {\n" 6199 . 'local($_,$ot) = @_;' 6200 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;' 6201 . '&translate_commands(' . "\"$body\"" . ");\n}\n"; 6202 print STDERR "\n*** sub $tmp failed:\n$@\n" if ($@); 6203 $raw_arg_cmds{$cmd} = 1; 6204 undef $body; 6205 }; 6206 } 6207 6208 # record the counter dependency 6209 &addto_dependents($within,$ctr) if ($within); 6210 6211 # save the text-label in the %new_theorem hash 6212 $new_theorem{$env} = $title; 6213 6214 # define a new environment 6215 my ($id) = ++$global{'max_id'}; 6216 $begin = "\\begin<<$id>>theorem_type<<$id>>" 6217 . "[$env][$ctr][$within]$thm_style$hfont$bfont\n"; 6218 $id = ++$global{'max_id'}; 6219 $end = "\\end<<$id>>theorem_type<<$id>>\n"; 6220 $tmp = "do_env_$env"; 6221 if ((defined &$tmp)&&($ALLOW_REDEFINE)) { 6222 print STDOUT "\n*** redefining theorem environment {$env} ***\n"; 6223 } 6224 $new_environment{$env} = join(':!:', '', $begin, $end, '') 6225 unless ((defined &$tmp)&&(! $ALLOW_REDEFINE)); 6226 6227 if (!$PREAMBLE) { 6228 my ($new_cmd) = join('' 6229 , 'theorem{}' ); 6230 &add_to_preamble('theorem', "\\new".$new_cmd ); 6231 $$after_R = $_; 6232 return(); 6233 } 6234 $$after_R = $_; 6235 'newed'.$new_thm; 6236} 6237 6238sub do_cmd_theoremstyle { 6239 local($_) = @_; 6240 local($thm_type); 6241 $thm_type = &missing_braces unless ( 6242 (s/$next_pair_pr_rx/$thm_type=$2;''/e) 6243 ||(s/$next_pair_rx/$thm_type=$2;''/e)); 6244# $THM_STYLE = $thm_type; 6245 $_; 6246} 6247sub do_cmd_theoremheaderfont { 6248 local($_) = @_; 6249 local($thm_type); 6250 $thm_type = &missing_braces unless ( 6251 (s/$next_pair_pr_rx/$thm_type=$2;''/e) 6252 ||(s/$next_pair_rx/$thm_type=$2;''/e)); 6253# $THM_HFONT = $thm_type; 6254 $_; 6255} 6256sub do_cmd_theorembodyfont { 6257 local($_) = @_; 6258 local($thm_type); 6259 $thm_type = &missing_braces unless ( 6260 (s/$next_pair_pr_rx/$thm_type=$2;''/e) 6261 ||(s/$next_pair_rx/$thm_type=$2;''/e)); 6262# $THM_BFONT = $thm_type; 6263 $_; 6264} 6265 6266sub do_env_theorem_type { 6267 local($_) = @_; 6268 local($dum,$env,$ctr,$within, $label, $name, $title, $text, $index); 6269 ($env, $dum) = &get_next_optional_argument; 6270 ($ctr, $dum) = &get_next_optional_argument; 6271 ($within, $dum) = &get_next_optional_argument; 6272 6273 local($thm_num, $thm_style); 6274 # defaults for plain theorem-style 6275 my ($hfont,$bfont) = ('',''); 6276 6277 ($thm_style, $dum) = &get_next_optional_argument; 6278 ($hfont, $dum) = &get_next_optional_argument; 6279 $hfont =~ s/\|/\\/og; 6280 ($bfont, $dum) = &get_next_optional_argument; 6281 $bfont =~ s/\|/\\/og; 6282 6283 # the pre-defined alternative theorem-styles 6284 if ($thm_style =~ /definition/) { 6285 $bfont = '\normalfont' unless $bfont; 6286 } elsif ($thm_style =~ /remark/) { 6287 $hfont = '\itshape' unless $hfont; 6288 $bfont = '\normalfont' unless $bfont; 6289 } 6290 6291 # defaults for plain theorem-style 6292 $hfont = '\bfseries' unless $hfont; 6293 $bfont = '\itshape' unless $bfont; 6294 6295 ($name, $dum) = &get_next_optional_argument; 6296 $name = &translate_environments("${O}0$C".$name."${O}0$C") if $name; 6297 $name = &translate_commands($name) if ($name =~ /\\/); 6298 6299 $index = $section_commands{$ctr}; 6300 if ($index) { 6301 # environment actually starts a new (sub-)section 6302 $curr_sec_id[$index]++; 6303 local($this) = &translate_commands("\\the$ctr"); 6304 local($hash) = &sanitize($name." $this"); 6305 local($section_tag) = join('', @curr_sec_id); 6306 $encoded_section_number{$hash} = join($;, $section_tag); 6307 &reset_dependents($ctr) if ($dependent{$ctr}); 6308 $thm_num = &translate_commands("\\the$ctr"); 6309 $thm_num =~ s/(\w)\.(\.\w)/$1$2/g; 6310 6311 # construct the sectioning title from the counter values 6312 $title = join( '', $new_theorem{$env}, " " 6313 , &translate_commands("\\the$ctr") ); 6314 $toc_section_info{join(' ',@curr_sec_id)} = \ 6315 "$current_depth$delim$CURRENT_FILE$delim$title" 6316 if ($current_depth <= $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 6317 $section_info{join(' ',@curr_sec_id)} = \ 6318 "$current_depth$delim$CURRENT_FILE$delim$title$delim"; 6319 $title = join('',"<A NAME=\"SECTION$section_tag\"><B>" 6320 , $title , "</B></A>" ); 6321 } else { 6322 if ($ctr) { 6323 print STDOUT "\nSTP:$ctr:+1" if ($VERBOSITY > 3); 6324 $global{$ctr}++; 6325 print STDOUT "=".$global{$ctr}." " if ($VERBOSITY > 3); 6326 &reset_dependents($ctr) if ($dependent{$ctr}); 6327 $thm_num = "\\the$ctr "; 6328 } else { $thm_num = ''; } 6329 6330 # construct the full title from the counter values 6331 $title = $new_theorem{$env}; 6332 if (($thm_style =~ /margin/)&&($HTML_VERSION > 2.1)) { 6333 # don't use the number yet 6334 } elsif ($thm_style =~ /change/) { 6335 $title = join(' ', $thm_num, "\\space", $title) 6336 } else { 6337 $title = join(' ', $title, "\\space", $thm_num); 6338 } 6339 6340 if ($hfont) { 6341 $title = join('',$O,++$global{'max_id'},$C,$hfont," " 6342 , $title, $O,++$global{'max_id'},$C); 6343 $title = &translate_environments($title); 6344 $title = &translate_commands($title); 6345 } else { 6346 $title = join('',"<B>",&translate_commands($title),"</B>"); 6347 } 6348 $title =~ s/(\w)\.(\.\w)/$1$2/g; 6349 } 6350 # extract any name or label that may occur at the start 6351 s/^\s*(\\label(($O|$OP)\d+($C|$CP))([^<]*)\2)?\s*(\(([^\)]*)\))?/ 6352 $label=$1; $text=$5; $name=$7 if ($7); ''/eo; 6353 if ($label) { 6354 $label = &anchor_label($text,$CURRENT_FILE,''); 6355 $label =~ s/$anchor_mark/$title/; 6356 $title = $label; 6357 } 6358 if ($name) { 6359 $name =~ s/^\s*|\s*$//g; 6360 $name = join('', " (", $name, ") ") if $name; 6361 } 6362 local($attribs, $border); 6363 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 6364 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 6365 6366 $_ = join('', $O,++$global{'max_id'},$C, $bfont 6367 , " ", $_ ,$O,++$global{'max_id'},$C) if ($bfont); 6368 6369 my($cmd) = 'do_thm_'.$env; 6370 if (defined &$cmd) { 6371 $_ = &$cmd($ctr, $title, $_); 6372 } else { 6373 $_ = &translate_environments($_); 6374 $_ = &translate_commands($_); 6375 } 6376 6377 if ($thm_style =~ /margin/) { 6378 local($valign); 6379 $valign = ($NETSCAPE_HTML ? ' VALIGN="BASELINE"':''); 6380 if ($hfont) { 6381 $thm_num = join('',$O,++$global{'max_id'},$C,$hfont," " 6382 , $thm_num, $O,++$global{'max_id'},$C); 6383 $thm_num = &translate_environments($thm_num); 6384 $thm_num = &translate_commands($thm_num); 6385 } else { 6386 $thm_num = join('',"<B>",&translate_commands($thm_num),"</B>"); 6387 } 6388 $thm_num =~ s/(\w)\.(\.\w)/$1$2/g; 6389 6390 # code copied from &make_table 6391 local($Tattribs); 6392 if ($attribs) { 6393 if (!($attribs =~ /=/)) { 6394 $Tattribs = &parse_valuesonly($attribs,"TABLE"); 6395 } else { 6396 $Tattribs = &parse_keyvalues($attribs,"TABLE"); 6397 } 6398 $Tattribs = ' '.$Tattribs if ($Tattribs); 6399 } 6400 $_ = join ('', "\n<P><DIV$env_id><TABLE" 6401 , (($border) ? " BORDER=\"$border\"" : '') 6402 , $Tattribs , ">\n<TR VALIGN=\"TOP\">" 6403 , "<TD$valign>", &translate_commands($thm_num) 6404 , "</TD>\n<TD>", $title, $name 6405 , (($thm_style =~ /break/)? "\n<BR>":" \ \n") 6406 , $_ , "\n</TD></TR></TABLE></DIV>"); 6407 } else { 6408 $_ = join('', "<P><DIV$env_id>" 6409 , $title, $name 6410 , (($thm_style =~ /break/)? "\n<BR>":" \ \n") 6411 , $_ 6412 ,"</DIV><P></P>\n"); 6413 if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 6414 &make_table( $border, $attribs, '', '', '', $_ ) 6415 } else { $_ } 6416 } 6417} 6418 6419# Modifies $_ in the caller and as a side-effect it modifies $next_def 6420# which is local to substitute_meta_cmds 6421sub get_next { 6422 local($what) = @_; 6423 local($next, $pat, $tmp); 6424 if ($what == 1) { 6425 ($next, $tmp, $pat) = &get_next_argument; 6426 } 6427 elsif ($what == 2) { 6428 ($next, $pat) = &get_next_tex_cmd; 6429 } 6430 elsif ($what == 3) { 6431 ($next, $pat) = &get_next_def_arg; 6432 } 6433 elsif ($what == 4) { 6434 ($next, $tmp, $pat) = &get_next_argument; 6435 } 6436 else { 6437 ($next, $pat) = &get_next_optional_argument; 6438 } 6439 do { 6440 $next_def .= &revert_to_raw_tex($pat) if $pat; 6441 } unless ($renewed); # don't add \renewcommand to preamble 6442# $next =~ s/(^\s*)|(\s*$)//g unless ($what == 4); #don't lose white space on body 6443 $next =~ s/(^\s*)|(\s*$)//g unless ($what =~ /[14]/); #retain white space in body 6444 ($next, $pat); 6445} 6446 6447# The following get_next_<something> ARE ALL DESTRUCTIVE. 6448sub get_next_argument { 6449 local($next, $br_id, $pat); 6450 if (!(s/$next_pair_rx/$br_id=$1;$next=$2;$pat=$&;''/seo)) { 6451 print " *** Could not find argument for command \\$cmd ***\n"; 6452 print "$_\n"; 6453 }; 6454 ($next, $br_id, $pat); 6455} 6456 6457sub get_next_pair_or_char_pr { 6458 local($next, $br_id, $pat, $epat); 6459 if ( /^\{([^\}]*)\}/o && (! $`)) { 6460 ($next, $pat) = ($1, $&); 6461 } elsif ( (/^\s*([^\s\\<])/o && (! $`))) { 6462 ($next, $pat) = ($1, $&); 6463 } elsif ( /$next_pair_pr_rx/o && (! $`)) { 6464 ($next, $br_id, $pat) = ($2, $1, $&); 6465 }; 6466 $epat = &escape_rx_chars($pat); 6467 s/$epat// if $pat; 6468 ($next, $br_id, $pat); 6469} 6470 6471sub get_next_optional_argument { 6472 local($next, $pat); 6473 s/$optional_arg_rx/$next=$1;$pat=$&;''/eo 6474 if (/\s*[[]/ && (! $`)); # if the first character is a [ 6475 #remove trailing spaces and/or comments 6476 s/^($comment_mark(\d+\n?)?|$EOL)//gos; 6477 6478 # if nested inside {}s we need to get more tokens 6479 if ($pat) { 6480 # check for \item, indicating something has gone wrong 6481 if ($pat =~ /\\item\b/ ) { 6482 print "\n*** optional argument badly formed:\n" . $pat . "\n\n"; 6483 $_ = $pat . $_; 6484 return('',''); 6485 } 6486 # check for being nested inside {}s 6487 local($found) = $pat; 6488 while ($found =~ s/$O(\d+)$C[\s\S]*$O\1$C//g) { 6489 if ($found =~ /$O(\d+)$C/) { 6490 local($br_id) = $1; 6491 if (s/$O$br_id$C//) { 6492 $found .= $`.$&; 6493 $pat .= "]".$`.$&; 6494 $next .= "]".$`.$&; 6495 $_ = $'; 6496 s/^([^]]*)\]/$next.=$1;$pat.=$&;''/e; 6497 $found .= $&; 6498 } else { last } # give up if no closing brace 6499 } 6500 } 6501 } else { 6502 s/^\s*\[\]/$pat=$&;''/e; # This is not picked by $optional_arg_rx 6503 } 6504 ($next, $pat); 6505} 6506 6507#JCL(jcl-del) - use new form of $single_cmd_rx. 6508sub get_next_tex_cmd { 6509 local($next, $pat); 6510 s/^\s*\=?\s*$single_cmd_rx/$4/; 6511 ($next, $pat) = ($1.$2,"\\".$1.$2); 6512} 6513 6514sub get_next_def_arg { 6515 local($next, $pat); 6516 6517 # Sets is_simple_def for caller. Start by turning it off, then 6518 # turn it on if we find one of the "simple" patterns. 6519 6520 # This has got to be hit-or-miss to an extent, given the 6521 # thoroughly incestuous relationship between the TeX macroprocessor 6522 # ('mouth') and typesetting back-end ('stomach'). Anything which 6523 # even does catcode hacking is going to lose BAD. 6524 6525 s/^\s*//so; # Remove whitespace 6526 6527 $is_simple_def = 0; 6528 6529 # no arguments 6530 6531 if (/^$O/ && (! $`)) { $next=0; $pat=''; $is_simple_def=1; } 6532 6533 # 'simple' arguments 6534 6535 if (! $is_simple_def && /$tex_def_arg_rx/o && (! $`)) { 6536 s/$tex_def_arg_rx/$next=$1; $pat=$&; $is_simple_def=1; $2/seo; } 6537 6538 # MESSY arguments 6539 6540 if (! $is_simple_def) { 6541 print "Arguments to $cmd are too complex ...\n"; 6542 print "It will not be processed unless used in another environment\n"; 6543 print "which is passed to LaTeX whole for processing.\n"; 6544 6545 s/^[^<]*(<[^<]+)*<</$next=''; $pat=$&; $O/seo; 6546 } 6547 6548 $pat =~ s/$O$//so; 6549 6550 ($next, $pat); 6551} 6552 6553#### Key-value parsing added by RRM 6554# 6555# This cleans-up the key-value pairs for a given tag, 6556# by removing unnecessary spaces and commas, inserting quotes 6557# around the value and puts a preceding space. 6558# The key becomes upper-case, while the value becomes lower-case. 6559# If specific `tags' are provided, then checking is done to verify 6560# that the keys and values are valid for these tags, eliminating 6561# any that are not; unmatched keys or values are handled as well. 6562# If no tags are provided, then just a list of pairs is returned. 6563# 6564sub parse_keyvalues { 6565 local($_,@tags) = @_; 6566 local($key,$KEY,$attribs,$atts,%attributes)=('','','',''); 6567 6568 # beware active " in german 6569 local($is_german); 6570 if (s/\"/'/g) { 6571 $is_german=1; 6572 s/(^|[\s,=])(\&\#\d\d\d;)/$1'$2/g 6573 } 6574 local($saved) = &revert_to_raw_tex(&translate_commands($_)); 6575 print "\nATTRIBS: $saved\n" if ($VERBOSITY > 6); 6576 6577 $saved =~ s/$percent_mark/%/g; 6578 $saved =~ s/((^|[\s,=])')\\\W\{(\w)\}/$1$3/g 6579 if $is_german; #unwanted accents, from active " 6580 if (@tags) { 6581 foreach $tag (@tags) { 6582 $_ = $saved; 6583 local($name)= $tag."_attribs"; 6584 $taglist = $$name; 6585 $name .= "_rx_list"; 6586 $taglist .= $$name; 6587 $taglist =~ s/,,/,/; 6588# s/(^|,)\s*([a-zA-Z]+)\s*\=\s*"?([\#\%\w\d]+)"?\s*/$attributes{$2}="$3";''/eg; 6589# s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([#%\w\d]*))\s*/ 6590# s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([#%&@;:+-\/\w\d]*))\s*/ 6591 s/(^|,)\s*([a-zA-Z]+)\s*\=\s*(\"([^"]*)\"|\'([^\']*)\'|([^<>,=\s]*))\s*/ 6592 $attributes{$2}=($4?$4:($5?$5:$6));' '/eg; 6593 foreach $key (keys %attributes){ 6594 $KEY = $key; 6595 $KEY =~ tr/a-z/A-Z/; 6596 if ($taglist =~ /,$KEY,/i) { 6597 local($keyname) = $tag."__".$KEY; 6598 local($keyvalues) = ''; 6599 if ($$keyname) { 6600 $keyvalues = $$keyname; 6601 $atts = $attributes{$key}; 6602 if ($keyvalues =~ /\,$atts\,/i ) { 6603# $atts =~ tr/A-Z/a-z/; 6604 $attribs .= " $KEY=\"$atts\""; 6605 print "\n$KEY=$atts " if ($VERBOSITY > 3); 6606 } else { &invalid_tag($tag,$KEY,$atts); } 6607 } else { # test for a regular expression 6608 $keyname = $keyname."_rx"; 6609 if ($$keyname) { 6610 $keyvalues = $$keyname; 6611 $atts = $attributes{$key}; 6612 if ($atts =~ /$keyvalues/) { 6613# $atts =~ tr/A-Z/a-z/; 6614 $attribs .= " $KEY=\"$atts\""; 6615 print "\n$KEY=$atts " if ($VERBOSITY > 3); 6616 } else { &invalid_tag($tag,$KEY,$atts) } 6617 } else { 6618 $atts = $attributes{$key}; 6619# $atts =~ tr/A-Z/a-z/; 6620 $attribs .= " $KEY=\"$atts\""; 6621 print "\n$KEY=$atts " if ($VERBOSITY > 3); 6622 } 6623 } 6624 } else { 6625 print "\n$key not in $taglist for $tag" if ($VERBOSITY > 3); 6626 } 6627 } 6628 } 6629 s/(^|\s,)\'([^\s,]*)\'(\s|$)/$1$2 /g if $is_german; 6630 $attribs .= &parse_valuesonly($_,@tags); 6631 } else { 6632 # with no tags provided, just list the key-value pairs 6633 $_ = $saved; 6634 s/\s*(\w+)\s*=\s*\"?(\w+)\"?\s*,?/$attributes{$1}=$2;''/eg; 6635 foreach $key (keys %attributes){ 6636 $KEY = $key; 6637 $KEY =~ tr/a-z/A-Z/; 6638 $atts = $attributes{$key}; 6639 $atts =~ tr/A-Z/a-z/; 6640 $attribs .= " $KEY=\"$atts\""; 6641 } 6642 } 6643 $attribs; 6644} 6645 6646sub invalid_tag { 6647 local($tag,$key,$value) = @_; 6648 &write_warnings("$key=$value is an invalid value in the <$tag> tag\n"); 6649} 6650 6651# RRM 6652# This creates key-value pairs from values only, 6653# by checking whether the data matches any key to the provided tags. 6654# Only the first match found is retained. 6655# Attributes with no values are also recognised here. 6656# 6657sub parse_valuesonly { 6658 local($values,@tags) = @_; 6659 local($i,$tag,$key,$KEY,$attribs,$atts)=(0,'','','','',''); 6660 local($saved) = &revert_to_raw_tex(&translate_commands($values)); 6661 $saved =~ s/$percent_mark/%/g; 6662 foreach $tag (@tags) { 6663 local($name)= $tag."_attribs"; 6664 $taglist = $$name; 6665 $values = $saved; 6666 $values =~ s/\s*\"?([^,\s\"]+)\"?\s*,?/$i++;$attributes{$i}=$1;''/eg; 6667 local($j) = 0; 6668 while ($j < $i) { 6669 $j++; 6670 $key = $attributes{$j}; 6671 if ($taglist =~ /,$key,/i) { 6672 $KEY = $key; 6673 $KEY =~ tr/a-z/A-Z/; 6674 $attribs .= " $KEY"; 6675 print " $KEY" if ($VERBOSITY > 3); 6676 } else { 6677 $atts = $attributes{$j}; 6678 $key = &find_attribute($key,$tag); 6679 if ($key) { 6680 $KEY = $key; 6681 $KEY =~ tr/a-z/A-Z/; 6682 $atts =~ tr/A-Z/a-z/; 6683 $attribs .= " $KEY=\"$atts\""; 6684 print " $KEY = $atts" if ($VERBOSITY > 3); 6685 } else { } 6686 } 6687 } 6688 } 6689 $attribs; 6690} 6691 6692# RRM 6693# Extracts key-value pairs using a supplied (comma-separated) list. 6694# When no list is given, it checks for a pre-defined list for the tag. 6695# 6696sub extract_attributes { 6697 local($tag,$taglist,$_) = @_; 6698 local($key,$attribs,$unused,%attributes); 6699 if (! ($taglist)) { 6700 local($name) = "$tag"."_attribs"; 6701 if ($$name) { $taglist = $$name } 6702 } 6703 s/\s*(\w+)\s*=\s*\"?(\w+)\"?\s*,?/$attributes{$1}=$2;''/eg; 6704 foreach $key (keys %attributes){ 6705 if ($taglist =~ /\,$key\,/) { 6706 $attribs .= " $key=\"$attributes{$key}\""; 6707 &write_warnings("valid attribute $key for $tag\n"); 6708 } else { 6709 &write_warnings("unknown attribute $key for $tag\n"); 6710 $unused .= " $key=\"$attributes{$key}\""; 6711 } 6712 } 6713 ($attribs,$unused); 6714} 6715 6716# RRM 6717# Finds the attribute of a given tag, for which a given value is valid. 6718# Requires variables: <tag>_<key> to be a comma-separated list of keys. 6719# So far it cannot recognise data-types, only names. 6720# 6721sub find_attribute { 6722 local($key,$attrib,$tag) = ('',@_); 6723 local($name) = $tag."_attribs"; 6724 local($attrib_list)=$$name; 6725 if ($attrib_list) { 6726 $attrib_list =~ s/^\,//o; 6727 $attrib_list =~ s/\,$//o; 6728 local(@keys) = split(',',$attrib_list); 6729 local($attrib_vals) = ''; 6730 foreach $key (@keys) { 6731 $name = $tag."__".$key; 6732 $attrib_vals = $$name; 6733 return ($key) if ($attrib_vals =~ /\,$attrib\,/i ); 6734 } 6735 } 6736 $name = $tag."_attribs_rx_list"; 6737 $attrib_list=$$name; 6738 if (!($attrib_list)) { return(); } 6739 $attrib_list =~ s/^\,//o; 6740 $attrib_list =~ s/\,$//o; 6741 @keys = split(',',$attrib_list); 6742 foreach $key (@keys) { 6743 next if ($attribs =~ / $key=/); 6744 $name = $tag."__".$key."_rx"; 6745 $attrib_vals = $$name; 6746 if ( $attrib =~ /^$attrib_vals$/ ) { 6747 return ($key); 6748 } 6749 } 6750 0; 6751} 6752 6753# in case \HTML is defined differently in packages 6754sub do_cmd_HTML { &do_cmd_HTMLcode(@_) } 6755 6756sub do_cmd_HTMLcode { 6757 local($_) = @_; 6758 local($tag,$attribs,$dum); 6759 local($attribs, $dum) = &get_next_optional_argument; 6760 $tag = &missing_braces unless ( 6761 (s/$next_pair_pr_rx/$tag = $2;''/eo) 6762 ||(s/$next_pair_rx/$tag = $2;''/eo)); 6763 $tag = &translate_commands($tag) if ($tag =~ /\\/); 6764 if (! $tag) { 6765 print "*** no tag given with \\HTML command, ignoring it"; 6766 return($_); 6767 } 6768 local($afterHTML) = $_; 6769 local($value,$TAGattribs,$etag); 6770 if (defined $unclosed_tags_list{$tag}) { 6771 } elsif (defined $closed_tags_list{$tag}) { 6772 $value = &missing_braces unless ( 6773 (s/$next_pair_pr_rx/$value = $2;''/eo) 6774 ||(s/$next_pair_rx/$value = $2;''/eo)); 6775 $etag = "</$tag>"; 6776 $afterHTML = $_; 6777 } else { 6778 print "\n*** <$tag> is not a valid tag for HTML $HTML_VERSION"; 6779 print "\n rejecting: \\HTML".(($attribs)? "[$attribs]" : '')."{$tag}"; 6780 return $_ ; 6781 } 6782 if ($dum) { 6783 $attribs = &translate_commands($attribs) if ($attribs=~/\\/); 6784 if ($attribs) { 6785 if (!($attribs =~ /=/)) { 6786 $TAGattribs = &parse_valuesonly($attribs,$tag); 6787 } else { 6788 $TAGattribs = &parse_keyvalues($attribs,$tag); 6789 } 6790 } 6791 } else { } # default if no [...] 6792 local($needed) = join(',' 6793 , $closed_tags_list{$tag},$unclosed_tags_list{$tag}); 6794 $needed =~ s/,,/,/g; $needed =~ s/^,|,$//g; 6795 if ($TAGattribs) { 6796 if ($needed) { 6797 $needed =~ s/,,/,/g; 6798 local($this, @needed); 6799 (@needed) = split(',',$needed); 6800 foreach $this (@needed) { 6801 next unless ($this); 6802 next if ($TAGattribs =~ /\b$this\b/); 6803 print "\n*** attribute $this required for <$tag> ***"; 6804 print "\n rejecting: \\HTML".(($attribs)? "[$attribs]" : '')."{$tag}"; 6805 return($value.$afterHTML); 6806 } 6807 } 6808 $value = &translate_environments($value); 6809 $value = &translate_commands($value) if ($value =~ /\\/); 6810 $_ = join('', "<$tag", $TAGattribs, ">", $value, $etag); 6811 } elsif ($needed) { 6812 print STDOUT "\n*** attributes $needed are required for <$tag> ***"; 6813 return($value.$after); 6814 } elsif ($value) { 6815 $value = &translate_environments($value); 6816 $value = &translate_commands($value) if ($value =~ /\\/); 6817 $_ = join('', "<$tag>", $value, $etag); 6818 } else { 6819 $_ = join('', "<$tag>", $etag); 6820 } 6821 $_.$afterHTML; 6822} 6823 6824sub do_cmd_HTMLget { 6825 local($_) = @_; 6826 local($which,$value,$hash,$dummy); 6827 local($hash, $dummy) = &get_next_optional_argument; 6828 $which = &missing_braces unless ( 6829 (s/$next_pair_pr_rx/$which = $2;''/eo) 6830 ||(s/$next_pair_rx/$which = $2;''/eo)); 6831 if ($hash) { 6832 local($tmp) = "\%$hash"; 6833 if (eval "defined \%{$hash}") { $! = ''; 6834 $value = ${$hash}{'$which'}; 6835 } else { print "\nhash: \%$hash not defined" } 6836 } elsif ($which) { 6837 $value = ${$which}; 6838 } 6839 $value.$_; 6840} 6841 6842sub do_cmd_HTMLset { 6843 local($_) = @_; 6844 local($which,$value,$hash,$dummy); 6845 local($hash, $dummy) = &get_next_optional_argument; 6846 $which = &missing_braces unless ( 6847 (s/$next_pair_pr_rx/$which = $2;''/eo) 6848 ||(s/$next_pair_rx/$which = $2;''/eo)); 6849 $value = &missing_braces unless ( 6850 (s/$next_pair_pr_rx/$value = $2;''/eo) 6851 ||(s/$next_pair_rx/$value = $2;''/eo)); 6852 if ($hash) { 6853 local($tmp) = "\%$hash"; 6854 if (eval "defined \%{$hash}") { $! = ''; 6855# eval "\$$hash{'$which'} = \"$value\";"; 6856 ${$hash}{'$which'} = $value; 6857 print "\nHTMLset failed: $! " if ($!); 6858 } else { print "\nhash: \%$hash not defined" } 6859 } elsif ($which) { $! = ''; 6860 eval "\${$which} = \"$value\";"; 6861 print "\nHTMLset failed: $! " if ($!); 6862 } 6863 $_; 6864} 6865 6866sub do_cmd_HTMLsetenv { &do_cmd_HTMLset(@_) } 6867 6868#### 6869 6870 6871# Appends $next_def to the preamble if it is not already there. 6872sub add_to_preamble { 6873 local($type, $next_def) = @_; 6874 local($name); 6875 if ($type =~ /def|include|special|graphicspath/) { 6876 local($pat) = &escape_rx_chars ($next_def); 6877# $preamble .= $next_def . "\n" unless ($preamble =~ /$pat/); 6878 push(@preamble, $pat); 6879 } 6880 elsif ($type =~ /command|environment|theorem|counter/) { 6881 push(@preamble, $next_def ); 6882 } 6883 else { 6884 ($name) = $next_def =~ /$marker\s*({[^}]+})/; # matches type{name} 6885 $name = &escape_rx_chars($name); 6886# $preamble .= $next_def . "\n" unless ($preamble =~ /$marker\s*$name/); 6887 push(@preamble, $name ); 6888 } 6889} 6890 6891sub make_latex{ 6892# This is the environment in which to process constructs that cannot be 6893# translated to HTML. 6894# The environment tex2html_wrap will be wrapped around any shorthand 6895# environments (e.g. $, \(, \[). 6896# The tex2html_wrap environment will be treated as an unrecognised 6897# evironment by the translator and its contents (i.e. the 'shorthand' 6898# environment) will be passed to latex for processing as usual. 6899 local($contents) = @_; 6900 local($preamble) = $preamble; 6901 local($aux_preamble) = $aux_preamble; 6902 while ($preamble =~ s/^(\@.*\n)/$prelatex .= $1;''/e) {} 6903 print "\nPRE-LATEX: $prelatex" if (($prelatex)&&($VERBOSITY > 1)); 6904 6905 %newed_commands = 6906 ( 'newedcommand' , 'newcommand' 6907 , 'renewedcommand' , 'renewcommand' 6908 , 'providedcommand' , 'providecommand' 6909 , 'newedenvironment' , 'newenvironment' 6910 , 'newedboolean' , 'newboolean' 6911 , 'newedcounter' , 'newcounter' 6912 , 'newedtheorem' , 'newtheorem' 6913 , 'newedfont' , 'newfont' , 'newedif', 'newif' 6914 ); 6915 6916 6917 # Make the @ character a normal letter ... 6918 $preamble =~ s/\\par([^A-Za-z]|$)/\n$1/g; 6919 $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n/; 6920 $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n\\RequirePackage{ifthen}\n/ 6921 unless ($preamble =~/\{ifthen\}/); 6922# $preamble =~ s/(\\document(class|style)(\[[^\]]+\])?\{\w+\})/$1\n\\makeatletter/; 6923 # ... and make it special again after the preamble 6924 # remove the \begin/\end for tex2html_nowrap and tex2html_deferred environments 6925 $preamble =~s/\\(begin|end)\s*\{(tex2html_(nowrap|deferred|nomath|preform)[_a-z]*|imagesonly)\}//g; 6926 $preamble =~s/\n?\s?<tex2html_(end)?file>\#[^#]*\#//mg; 6927 6928 $preamble = "\\documentclass\{article\}%\n\\usepackage{html}\n\\usepackage[dvips]{color}\n" 6929 unless ($preamble); 6930 if (($LATEX_DUMP)&&(!($preamble =~ /\\usepackage\{ldump\}/))) { 6931 # MRO: replaced $* with /m 6932 $preamble =~ s/(\\document(class|style)[^\n]*\n)/$1\\usepackage\{ldump\}\n/m; 6933 } 6934 if ($preamble =~ /pstricks/) { 6935 if ($LOAD_LATEX_COLOR) { 6936 $LOAD_LATEX_COLOR =~ s/\{color\}/\{pstcol\}/ ; 6937 } else { 6938 $LOAD_LATEX_COLOR = "\n\\usepackage[dvips]{pstcol}\n"; 6939 } 6940 } else { 6941 $LOAD_LATEX_COLOR = "\n\\usepackage[dvips]{color}"; 6942 } 6943 $LATEX_COLOR = "\\pagecolor[gray]{.85}\\nobreak " unless $LATEX_COLOR; 6944 if ($preamble =~ /(^|\s*[^%])\s*\\documentstyle/) { 6945 # \usepackage is invalid in LaTeX 2.09 and LaTeX-2e compatibility mode 6946 $LATEX_COLOR = ''; $LOAD_LATEX_COLOR = ''; 6947 # ... so is \providecommand 6948 $preamble =~ s/\\documentstyle[^{]*\{[^}]*\}\n?/ 6949 $&."\n\\let\\providecommand\\newcommand\n"/eo; 6950 } 6951 6952 $preamble .= $LOAD_LATEX_COLOR."\n" unless ($preamble =~ /[,\{]color[,\}]/); 6953 $preamble .= "\n\n".$LATEX_COLOR."\n" unless ($preamble =~ /\\pagecolor/); 6954 do { 6955 if ($ISOLATIN_CHARS) { $INPUTENC = $INPUTENC || 'latin1' }; 6956 $preamble .= "\n\\usepackage[".$INPUTENC."]\{inputenc\}\n"; 6957 } unless ($preamble =~ /\\inputenc/); 6958 6959 $aux_preamble = '' unless (($aux_preamble)&&($contents =~ /\\(hyper)?(ref|cite)/)); 6960 6961 $preamble =~ s/\\((provide|(re)?new)ed(command|counter|if|theorem|environment|font))\b/ 6962 "%\n\\".$newed_commands{$1}/eg; 6963 $preamble =~ s/(\\(re)?newcommand)\s*(\{(\\?)(\}|[^\}]+)\})/ 6964 $1.(($4)? $3 : "{\\".$5.'}' )/eg; 6965 6966 $preamble =~s/$verbatim_mark(imagesonly)(\d+)#/$verbatim{$2}/eg; # for images.tex only 6967 6968# local($key); 6969# foreach $key (keys %newed_commands) { 6970# $preamble .= "\n\\let\\$key\\".$newed_commands{$key} 6971# } 6972 $preamble .= "\n"; 6973 6974 local($paperwidth) = ''; 6975 if ($PAPERSIZE) { $paperwidth = &adjust_textwidth($PAPERSIZE); } 6976 else { $paperwidth = &adjust_textwidth("a5"); } 6977 local($kern) = ($EXTRA_IMAGE_SCALE ? $EXTRA_IMAGE_SCALE/2 : ".5" ); 6978 $kern = $kern * $MATH_SCALE_FACTOR; 6979 $prelatex . ($DEBUG ? "\\nonstopmode" : "\\batchmode") . 6980 "\n$preamble\n\n\\makeatletter\n$aux_preamble\n" . 6981 "\\makeatletter\n\\count\@=\\the\\catcode`\\_ \\catcode`\\_=8 \n" . 6982 "\\newenvironment{tex2html_wrap}{}{}%\n" . 6983 "\\catcode`\\<=12\\catcode`\\_=\\count\@\n" . 6984 "\\newcommand{\\providedcommand}[1]{\\expandafter\\providecommand\\csname #1\\endcsname}%\n" . 6985 "\\newcommand{\\renewedcommand}[1]{\\expandafter\\providecommand\\csname #1\\endcsname{}%\n" . 6986 " \\expandafter\\renewcommand\\csname #1\\endcsname}%\n" . 6987 "\\newcommand{\\newedenvironment}[1]{\\newenvironment{#1}{}{}\\renewenvironment{#1}}%\n" . 6988 "\\let\\newedcommand\\renewedcommand\n" . 6989 "\\let\\renewedenvironment\\newedenvironment\n" . 6990 "\\makeatother\n" . 6991 "\\let\\mathon=\$\n\\let\\mathoff=\$\n" . 6992 "\\ifx\\AtBeginDocument\\undefined \\newcommand{\\AtBeginDocument}[1]{}\\fi\n" . 6993 "\\newbox\\sizebox\n" . "$paperwidth" . 6994 "\\newwrite\\lthtmlwrite\n" . "\\makeatletter\n" . 6995 "\\let\\realnormalsize=\\normalsize\n\\global\\topskip=2sp\n\\def\\preveqno{}" . 6996 "\\let\\real\@float=\\\@float \\let\\realend\@float=\\end\@float\n" . 6997 "\\def\\\@float{\\let\\\@savefreelist\\\@freelist\\real\@float}\n" . 6998# "\\def\\\@float{\\\@dbflt}\n" . 6999 "\\def\\liih\@math{\\ifmmode\$\\else\\bad\@math\\fi}\n" . 7000 "\\def\\end\@float{\\realend\@float\\global\\let\\\@freelist\\\@savefreelist}\n" . 7001 "\\let\\real\@dbflt=\\\@dbflt \\let\\end\@dblfloat=\\end\@float\n" . 7002 "\\let\\\@largefloatcheck=\\relax\n" . 7003 "\\let\\if\@boxedmulticols=\\iftrue\n" . 7004 "\\def\\\@dbflt{\\let\\\@savefreelist\\\@freelist\\real\@dbflt}\n" . 7005 "\\def\\adjustnormalsize{\\def\\normalsize{\\mathsurround=0pt \\realnormalsize\n" . 7006 " \\parindent=0pt\\abovedisplayskip=0pt\\belowdisplayskip=0pt}%\n" . 7007 " \\def\\phantompar{\\csname par\\endcsname}\\normalsize}%\n" . 7008 "\\def\\lthtmltypeout#1{{\\let\\protect\\string \\immediate\\write\\lthtmlwrite{#1}}}%\n" . 7009 "\\newcommand\\lthtmlhboxmathA{\\adjustnormalsize\\setbox\\sizebox=\\hbox\\bgroup\\kern.05em }%\n" . 7010 "\\newcommand\\lthtmlhboxmathB{\\adjustnormalsize\\setbox\\sizebox=\\hbox to\\hsize\\bgroup\\hfill }%\n" . 7011 "\\newcommand\\lthtmlvboxmathA{\\adjustnormalsize\\setbox\\sizebox=\\vbox\\bgroup %\n". 7012 " \\let\\ifinner=\\iffalse \\let\\)\\liih\@math }%\n" . 7013 "\\newcommand\\lthtmlboxmathZ{\\\@next\\next\\\@currlist{}{\\def\\next{\\voidb\@x}}%\n" . 7014# " \\expandafter\\box\\next\\edef\\next{\\egroup\\def\\noexpand\\thiseqn{\\theequation}}\\next}%\n" . 7015 " \\expandafter\\box\\next\\egroup}%\n" . 7016 "\\newcommand\\lthtmlmathtype[1]{\\gdef\\lthtmlmathenv{#1}}%\n" . 7017 "\\newcommand\\lthtmllogmath{\\dimen0\\ht\\sizebox \\advance\\dimen0\\dp\\sizebox\n" . 7018 " \\ifdim\\dimen0>.95\\vsize\n" . " \\lthtmltypeout{%\n" . 7019 "*** image for \\lthtmlmathenv\\space is too tall at \\the\\dimen0, reducing to .95 vsize ***}%\n" . 7020 " \\ht\\sizebox.95\\vsize \\dp\\sizebox\\z\@ \\fi\n" . " \\lthtmltypeout{l2hSize %\n" . 7021 ":\\lthtmlmathenv:\\the\\ht\\sizebox::\\the\\dp\\sizebox::\\the\\wd\\sizebox.\\preveqno}}%\n" . 7022 "\\newcommand\\lthtmlfigureA[1]{\\let\\\@savefreelist\\\@freelist 7023 \\lthtmlmathtype{#1}\\lthtmlvboxmathA}%\n" . 7024 "\\newcommand\\lthtmlpictureA{\\bgroup\\catcode`\\_=8 \\lthtmlpictureB}%\n" . 7025 "\\newcommand\\lthtmlpictureB[1]{\\lthtmlmathtype{#1}\\egroup 7026 \\let\\\@savefreelist\\\@freelist \\lthtmlhboxmathB}%\n" . 7027 "\\newcommand\\lthtmlpictureZ[1]{\\hfill\\lthtmlfigureZ}%\n" . 7028 "\\newcommand\\lthtmlfigureZ{\\lthtmlboxmathZ\\lthtmllogmath\\copy\\sizebox 7029 \\global\\let\\\@freelist\\\@savefreelist}%\n" . 7030 "\\newcommand\\lthtmldisplayA{\\bgroup\\catcode`\\_=8 \\lthtmldisplayAi}%\n" . 7031 "\\newcommand\\lthtmldisplayAi[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlvboxmathA}%\n" . 7032 "\\newcommand\\lthtmldisplayB[1]{\\edef\\preveqno{(\\theequation)}%\n" . 7033 " \\lthtmldisplayA{#1}\\let\\\@eqnnum\\relax}%\n" . 7034 "\\newcommand\\lthtmldisplayZ{\\lthtmlboxmathZ\\lthtmllogmath\\lthtmlsetmath}%\n" . 7035 "\\newcommand\\lthtmlinlinemathA{\\bgroup\\catcode`\\_=8 \\lthtmlinlinemathB}\n" . 7036 "\\newcommand\\lthtmlinlinemathB[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlhboxmathA\n" . 7037 " \\vrule height1.5ex width0pt }%\n" . 7038 "\\newcommand\\lthtmlinlineA{\\bgroup\\catcode`\\_=8 \\lthtmlinlineB}%\n" . 7039 "\\newcommand\\lthtmlinlineB[1]{\\lthtmlmathtype{#1}\\egroup\\lthtmlhboxmathA}%\n" . 7040 "\\newcommand\\lthtmlinlineZ{\\egroup\\expandafter\\ifdim\\dp\\sizebox>0pt %\n" . 7041 " \\expandafter\\centerinlinemath\\fi\\lthtmllogmath\\lthtmlsetinline}\n" . 7042 "\\newcommand\\lthtmlinlinemathZ{\\egroup\\expandafter\\ifdim\\dp\\sizebox>0pt %\n" . 7043 " \\expandafter\\centerinlinemath\\fi\\lthtmllogmath\\lthtmlsetmath}\n" . 7044 "\\newcommand\\lthtmlindisplaymathZ{\\egroup %\n" . 7045 " \\centerinlinemath\\lthtmllogmath\\lthtmlsetmath}\n" . 7046 "\\def\\lthtmlsetinline{\\hbox{\\vrule width.1em \\vtop{\\vbox{%\n" . 7047 " \\kern.1em\\copy\\sizebox}\\ifdim\\dp\\sizebox>0pt\\kern.1em\\else\\kern.3pt\\fi\n" . 7048 " \\ifdim\\hsize>\\wd\\sizebox \\hrule depth1pt\\fi}}}\n" . 7049 "\\def\\lthtmlsetmath{\\hbox{\\vrule width.1em\\kern-.05em\\vtop{\\vbox{%\n" . 7050 " \\kern.1em\\kern$kern pt\\hbox{\\hglue.17em\\copy\\sizebox\\hglue$kern pt}}\\kern.3pt%\n" . 7051 " \\ifdim\\dp\\sizebox>0pt\\kern.1em\\fi \\kern$kern pt%\n" . 7052 " \\ifdim\\hsize>\\wd\\sizebox \\hrule depth1pt\\fi}}}\n" . 7053 "\\def\\centerinlinemath{%\n" . 7054 " \\dimen1=\\ifdim\\ht\\sizebox<\\dp\\sizebox \\dp\\sizebox\\else\\ht\\sizebox\\fi\n" . 7055 " \\advance\\dimen1by.5pt \\vrule width0pt height\\dimen1 depth\\dimen1 \n". 7056 " \\dp\\sizebox=\\dimen1\\ht\\sizebox=\\dimen1\\relax}\n\n" . 7057 "\\def\\lthtmlcheckvsize{\\ifdim\\ht\\sizebox<\\vsize \n" . 7058 " \\ifdim\\wd\\sizebox<\\hsize\\expandafter\\hfill\\fi \\expandafter\\vfill\n" . 7059 " \\else\\expandafter\\vss\\fi}%\n" . 7060 "\\providecommand{\\selectlanguage}[1]{}%\n" . 7061# "\\def\\\@enddocumenthook{\\ifnum\\count0>1 \\ifvoid\\\@cclv\\penalty-\\\@MM\\fi\\fi}\n" . 7062 "\\makeatletter \\tracingstats = 1 \n" 7063 . ($itrans_loaded ? $itrans_tex_mod : '') 7064 . $LaTeXmacros . "\n" # macros defined in extension files 7065# "\\usepackage{lthimages}\n" . 7066 . (($LATEX_DUMP)? "\\latexdump\n" : '') 7067 . "\n\\begin{document}\n" . 7068 "\\pagestyle{empty}\\thispagestyle{empty}\\lthtmltypeout{}%\n" . 7069 "\\lthtmltypeout{latex2htmlLength hsize=\\the\\hsize}\\lthtmltypeout{}%\n" . 7070 "\\lthtmltypeout{latex2htmlLength vsize=\\the\\vsize}\\lthtmltypeout{}%\n" . 7071 "\\lthtmltypeout{latex2htmlLength hoffset=\\the\\hoffset}\\lthtmltypeout{}%\n" . 7072 "\\lthtmltypeout{latex2htmlLength voffset=\\the\\voffset}\\lthtmltypeout{}%\n" . 7073 "\\lthtmltypeout{latex2htmlLength topmargin=\\the\\topmargin}\\lthtmltypeout{}%\n" . 7074 "\\lthtmltypeout{latex2htmlLength topskip=\\the\\topskip}\\lthtmltypeout{}%\n" . 7075 "\\lthtmltypeout{latex2htmlLength headheight=\\the\\headheight}\\lthtmltypeout{}%\n" . 7076 "\\lthtmltypeout{latex2htmlLength headsep=\\the\\headsep}\\lthtmltypeout{}%\n" . 7077 "\\lthtmltypeout{latex2htmlLength parskip=\\the\\parskip}\\lthtmltypeout{}%\n" . 7078 "\\lthtmltypeout{latex2htmlLength oddsidemargin=\\the\\oddsidemargin}\\lthtmltypeout{}%\n" . 7079 "\\makeatletter\n" . 7080 "\\if\@twoside\\lthtmltypeout{latex2htmlLength evensidemargin=\\the\\evensidemargin}%\n" . 7081 "\\else\\lthtmltypeout{latex2htmlLength evensidemargin=\\the\\oddsidemargin}\\fi%\n" . 7082 "\\lthtmltypeout{}%\n" . 7083 "\\makeatother\n\\setcounter{page}{1}\n\\onecolumn\n\n% !!! IMAGES START HERE !!!\n\n" 7084 . "$contents\n" 7085# "\\clearpage\n" . 7086 . "\\end{document}"; 7087} 7088 7089sub adjust_textwidth { 7090 local($_) = @_; 7091 local($width,$length) = ('',''); 7092 if (/a4/) {$width = 595; $length= 842; } 7093 elsif (/letter/) {$width = 612; $length= 792; } 7094 elsif (/legal/) {$width = 612; $length= 1008; } 7095 elsif (/note/) {$width = 540; $length= 720; } 7096 elsif (/b5/) {$width = 501; $length= 709; } 7097 elsif (/a5/) {$width = 421; $length= 595; } 7098 elsif (/a6/) {$width = 297; $length= 421; } 7099 elsif (/a7/) {$width = 210; $length= 297; } 7100 elsif (/a8/) {$width = 148; $length= 210; } 7101 elsif (/a9/) {$width = 105; $length= 148; } 7102 elsif (/a10/) {$width = 74; $length= 105; } 7103 elsif (/b4/) {$width = 709; $length= 1002; } 7104 elsif (/a3/) {$width = 842; $length= 1190; } 7105 elsif (/b3/) {$width = 1002; $length= 1418; } 7106 elsif (/a2/) {$width = 1190; $length= 1684; } 7107 elsif (/b2/) {$width = 1418; $length= 2004; } 7108 elsif (/a1/) {$width = 1684; $length= 2380; } 7109 elsif (/b1/) {$width = 2004; $length= 2836; } 7110 elsif (/a0/) {$width = 2380; $length= 3368; } 7111 elsif (/b0/) {$width = 2836; $length= 4013; } 7112 else { 7113 &write_warnings("\nPAPERSIZE: $_ unknown, using LaTeX's size."); 7114 return(); 7115 } 7116 if ($width > 500) { $width = $width - 144; $length = $length - 288; } 7117 elsif ($width > 250) { $width = $width - 72; $length = $length - 144; } 7118 elsif ($width > 125) { $width = $width - 36; $length = $length - 72; } 7119# "\\setlength{\\oddsidemargin}{0pt}\n" . 7120# "\\setlength{\\evensidemargin}{0pt}\n" . 7121# "\\setlength{\\parskip}{0pt}\\setlength{\\topskip}{0pt}\n" . 7122 "\\setlength{\\hoffset}{0pt}\\setlength{\\voffset}{0pt}\n" . 7123 "\\addtolength{\\textheight}{\\footskip}\\setlength{\\footskip}{0pt}\n" . 7124 "\\addtolength{\\textheight}{\\topmargin}\\setlength{\\topmargin}{0pt}\n" . 7125 "\\addtolength{\\textheight}{\\headheight}\\setlength{\\headheight}{0pt}\n" . 7126 "\\addtolength{\\textheight}{\\headsep}\\setlength{\\headsep}{0pt}\n" . 7127 "\\setlength{\\textwidth}{${width}pt}\n" 7128 . (($length > 500) ? "\\setlength{\\textheight}{${length}pt}\n" : '') 7129} 7130 7131# Given the depth of the current sectioning declaration and the current 7132# section numbers it returns the new section numbers. 7133# It increments the $depth-ieth element of the @curr_sec_id list and 7134# 0's the elements after the $depth-ieth element. 7135sub new_level { 7136 local($depth, @curr_sec_id) = @_; 7137 $depth = $section_commands{$outermost_level} unless $depth; 7138 local($i) = 0; 7139 grep( do { if ($i == $depth) {$_++ ;} 7140 elsif ($i > $depth) {$_ = 0 ;}; 7141 $i++; 7142 0; 7143 }, 7144 @curr_sec_id); 7145 @curr_sec_id; 7146} 7147 7148sub make_head_and_body { 7149 local($title,$body,$before_body) = @_; 7150 local($DTDcomment) = ''; 7151 local($version,$isolanguage) = ($HTML_VERSION, 'EN'); 7152 local(%isolanguages) = ( 'english', 'EN' , 'USenglish', 'EN-US' 7153 , 'original', 'EN' , 'german' , 'DE' 7154 , 'austrian', 'DE-AT', 'french' , 'FR' 7155 , 'spanish', 'ES' 7156 , %isolanguages ); 7157# $isolanguage = $isolanguages{$default_language}; # DTD is in EN 7158 $isolanguage = 'EN' unless $isolanguage; 7159#JCL(jcl-tcl) 7160# clean title as necessary 7161# the first words ... is a kludge, but reasonable (or not?) 7162#RRM: why bother? --- as long as it is pure text. 7163 $title = &purify($title,1); 7164 eval("\$title = ". $default_title ) unless ($title); 7165# $title = &get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES); 7166 7167 # allow user-modification of the <TITLE> tag; thanks Dan Young 7168 if (defined &custom_TITLE_hook) { 7169 $title = &custom_TITLE_hook($title, $toc_sec_title); 7170 } 7171 7172 if ($DOCTYPE =~ /\/\/[\w\.]+\s*$/) { # language spec included 7173 $DTDcomment = '<!DOCTYPE HTML PUBLIC "'. $DOCTYPE .'"'; 7174 } else { 7175 $DTDcomment = '<!DOCTYPE HTML PUBLIC "'. $DOCTYPE .'//' 7176 . ($ISO_LANGUAGE ? $ISO_LANGUAGE : $isolanguage) . '"' 7177 } 7178 $DTDcomment .= ($PUBLIC_REF ? "\n \"".$PUBLIC_REF.'"' : '' ) . '>'."\n"; 7179 7180 $STYLESHEET = $FILE.".css" unless defined($STYLESHEET); 7181 7182 my ($this_charset) = $charset; 7183 if ($USE_UTF) { $charset = $utf8_str; $NO_UTF = ''; } 7184 if (!$charset && $CHARSET) { 7185 $this_charset = $CHARSET; 7186 $this_charset =~ s/_/\-/go; 7187 } 7188 if ($NO_UTF && $charset =~/utf/) { 7189 $this_charset = $PREV_CHARSET||$CHARSET; 7190 $this_charset =~ s/_/\-/go; 7191 } 7192 7193 join("\n", (($DOCTYPE)? $DTDcomment : '' ) 7194 ,"<!--Converted with LaTeX2HTML $TEX2HTMLVERSION" 7195 , "original version by: Nikos Drakos, CBLU, University of Leeds" 7196 , "* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan" 7197 , "* with significant contributions from:" 7198 , " Jens Lippmann, Marek Rouchal, Martin Wilck and others" 7199 . " -->\n<HTML>\n<HEAD>\n<TITLE>".$title."</TITLE>" 7200 , &meta_information($title) 7201 , ($CHARSET && $HTML_VERSION ge "2.1" ? 7202 "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=$this_charset\">" 7203 : "" ) 7204 , $LATEX2HTML_META 7205 , ($BASE ? "<BASE HREF=\"$BASE\">" : "" ) 7206 , $STYLESHEET_CASCADE 7207 , ($STYLESHEET ? "<LINK REL=\"STYLESHEET\" HREF=\"$STYLESHEET\">" : '' ) 7208 , $more_links_mark 7209 , "</HEAD>" , ($before_body? $before_body : '') 7210 , "<BODY $body>", ''); 7211} 7212 7213 7214sub style_sheet { 7215 local($env,$id,$style); 7216 #AXR: don't overwrite existing .css 7217 #MRO: This is supposed to be $FILE.css, no? 7218 #RRM: only by default, others can be specified as well, via $EXTERNAL_STYLESHEET 7219 #return if (-f $EXTERNAL_STYLESHEET); 7220 return if (-r "$FILE.css" && -s _ && !$REFRESH_STYLES ); 7221 7222 unless(open(STYLESHEET, ">$FILE.css")) { 7223 print "\nError: Cannot write '$FILE.css': $!\n"; 7224 return; 7225 } 7226 if ( -f $EXTERNAL_STYLESHEET ) { 7227 if(open(EXT_STYLES, "<$EXTERNAL_STYLESHEET")) { 7228 while (<EXT_STYLES>) { print STYLESHEET $_; } 7229 close(EXT_STYLES); 7230 } else { 7231 print "\nError: Cannot read '$EXTERNAL_STYLESHEET': $!\n"; 7232 } 7233 } else { 7234 print STYLESHEET <<"EOF" 7235/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ 7236.MATH { font-family: \"Century Schoolbook\", serif; } 7237.MATH I { font-family: \"Century Schoolbook\", serif; font-style: italic } 7238.BOLDMATH { font-family: \"Century Schoolbook\", serif; font-weight: bold } 7239 7240/* implement both fixed-size and relative sizes */ 7241SMALL.XTINY { font-size : xx-small } 7242SMALL.TINY { font-size : x-small } 7243SMALL.SCRIPTSIZE { font-size : smaller } 7244SMALL.FOOTNOTESIZE { font-size : small } 7245SMALL.SMALL { } 7246BIG.LARGE { } 7247BIG.XLARGE { font-size : large } 7248BIG.XXLARGE { font-size : x-large } 7249BIG.HUGE { font-size : larger } 7250BIG.XHUGE { font-size : xx-large } 7251 7252/* heading styles */ 7253H1 { } 7254H2 { } 7255H3 { } 7256H4 { } 7257H5 { } 7258 7259/* mathematics styles */ 7260DIV.displaymath { } /* math displays */ 7261TD.eqno { } /* equation-number cells */ 7262 7263 7264/* document-specific styles come next */ 7265EOF 7266 } 7267 print "\n *** Adding document-specific styles *** "; 7268 while (($env,$style) = each %env_style) { 7269 if ($env =~ /\./) { 7270 $env =~ s/\.$//; 7271 print STYLESHEET "$env\t\t{ $style }\n"; 7272 } elsif ($env =~ /inline|^(text|math)?((tt|rm|sf)(family)?|(up|it|sl|sc)(shape)?|(bf|md)(series)?|normal(font)?)$/) { 7273 print STYLESHEET "SPAN.$env\t\t{ $style }\n"; 7274 } elsif ($env =~ /\./) { 7275 print STYLESHEET "$env\t\t{ $style }\n"; 7276 } elsif ($env =~ /^(preform|\w*[Vv]erbatim(star)?)$/) { 7277 print STYLESHEET "PRE.$env\t\t{ $style }\n"; 7278 } elsif ($env =~ /figure|table|tabular|equation|$array_env_rx/) { 7279 print STYLESHEET "TABLE.$env\t\t{ $style }\n"; 7280 } else { 7281 print STYLESHEET "DIV.$env\t\t{ $style }\n"; 7282 } 7283 } 7284 while (($env,$style) = each %txt_style) { 7285 print STYLESHEET "SPAN.$env\t\t{ $style }\n"; 7286 } 7287 while (($env,$style) = each %img_style) { 7288 print STYLESHEET "IMG.$env\t\t{ $style }\n"; 7289 } 7290 7291 my ($style); 7292 foreach $id (sort(keys %styleID)) { 7293 $style = $styleID{$id}; 7294 $style =~ s/font-(color)/$1/; 7295 print STYLESHEET "\#$id\t\t{ $style }\n" 7296 if ($styleID{$id} ne ''); 7297 } 7298 close(STYLESHEET); 7299} 7300 7301sub clear_styleID { 7302 return unless ($USING_STYLES); 7303 local($env_id,$id) = ("grp", @_); 7304 undef $styleID{$env_id} if ($id =~ /^\d+$/); 7305} 7306 7307sub make_address { 7308 local($addr) = &make_real_address(@_); 7309 $addr .= "\n</BODY>\n</HTML>\n"; 7310 &lowercase_tags($addr) if $LOWER_CASE_TAGS; 7311 $addr; 7312} 7313 7314sub make_real_address { 7315 local($addr) = $ADDRESS; 7316 if ((defined &custom_address)&&($addr)) { 7317 &custom_address($addr) 7318 } elsif ($addr) { 7319 "<ADDRESS>\n$addr\n</ADDRESS>"; 7320 } else { '' } 7321} 7322 7323sub purify_caption { 7324 local($_) = @_; 7325 local($text) = &recover_image_code($_); 7326 $text =~ s/\\protect|ALT\=|%EQNO:\d+//g; 7327 $text =~ s/[\\\#\'\"\`]//g; 7328 $text; 7329} 7330 7331sub recover_image_code { 7332 local($key) = @_; 7333 local($text) = $img_params{$key}; 7334 if (!$text) { 7335 if ($text = $id_map{$key}) { 7336 if ($orig_name_map{$text}) { 7337 $text = $img_params{$orig_name_map{$text}} 7338 } 7339 } elsif ($cached_env_img{$key}) { 7340 $text = $img_params{$cached_env_img{$key}}; 7341 } 7342 if ($text =~ /\#*ALT="([^"]+)"(>|#)/s) { $text = $1 } 7343 } 7344 $text =~ s/\\protect|%EQNO:\d+//g; 7345 $text =~ s/&(gt|lt|amp|quot);/&special_html_inv($1)/eg; 7346 $text; 7347} 7348 7349sub encode_title { 7350 local($_) = @_; 7351 $_ = &encode($_); 7352 while (/(<[^<>]*>)/o) {s/$1//g}; # Remove HTML tags 7353 s/#[^#]*#//g; # Remove #-delimited markers 7354 $_; 7355} 7356 7357# Encodes the contents of enviroments that are passed to latex. The code 7358# is then used as key to a hash table pointing to the URL of the resulting 7359# picture. 7360sub encode { 7361 local($_) = @_; 7362 # Remove invocation-specific stuff 7363 1 while(s/\\(begin|end)\s*(($O|$OP)\d+($C|$CP))?|{?tex2html_(wrap|nowrap|deferred|)(_\w+)?}?(\2)?//go); 7364 $_ = &revert_to_raw_tex($_); 7365 s/\\protect//g; # remove redundant \protect macros 7366 #$_ = pack("u*", $_); # uuencode 7367 s/\\\$/dollar/g; # replace funnies, may cause problems in a hash key 7368 s/\//slash/g; # replace funnies, may cause problems in a hash key 7369 s/\$|\/|\\//g; # remove funnies, may cause problems in a hash key 7370 s/\s*|\n//g; # Remove spaces and newlines 7371 s/^(.{80}).*(.{80})$/$1$2/; # truncate to avoid DBM problems 7372 $_; 7373} 7374 7375 7376##################### Hypertext Section Links ######################## 7377sub post_process { 7378 # Put hyperlinks between sections, add HTML headers and addresses, 7379 # do cross references and citations. 7380 # Uses the %section_info array created in sub translate. 7381 # Binds the global variables 7382 # $PREVIOUS, $PREVIOUS_TITLE 7383 # $NEXT, $NEXT_TITLE 7384 # $UP, $UP_TITLE 7385 # $CONTENTS, $CONTENTS_TITLE 7386 # $INDEX, $INDEX_TITLE 7387 # $NEXT_GROUP, $NEXT_GROUP_TITLE 7388 # $PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE 7389 # Converting to and from lists and strings is very inefficient. 7390 # Maybe proper lists of lists should be used (or wait for Perl5?) 7391 # JKR: Now using top_navigation and bot_navigation instead of navigation 7392 local($_, $key, $depth, $file, $title, $header, @link, @old_link, 7393 $top_navigation, $bot_navigation, @keys, 7394 @tmp_keys, $flag, $child_links, $body, $more_links); 7395 7396 @tmp_keys = @keys = sort numerically keys %section_info; 7397 print "\nDoing section links ..."; 7398 while (@tmp_keys) { 7399 $key = shift @tmp_keys; 7400 next if ($MULTIPLE_FILES &&!($key =~ /^$THIS_FILE/)); 7401 print "."; 7402 $more_links = ""; 7403 ($depth, $file, $title, $body) = split($delim,$section_info{$key}); 7404 print STDOUT "\n$key $file $title $body" if ($VERBOSITY > 3); 7405 next if ($body =~ /external/); 7406 $PREVIOUS = $PREVIOUS_TITLE = $NEXT = $NEXT_TITLE = $UP = $UP_TITLE 7407 = $CONTENTS = $CONTENTS_TITLE = $INDEX = $INDEX_TITLE 7408 = $NEXT_GROUP = $NEXT_GROUP_TITLE 7409 = $PREVIOUS_GROUP = $PREVIOUS_GROUP_TITLE 7410 = $_ = $top_navigation = $bot_navigation = undef; 7411 &add_link_tag('previous',$file); 7412 @link = split(' ',$key); 7413 ($PREVIOUS, $PREVIOUS_TITLE) = 7414 &add_link($previous_page_visible_mark,$file,@old_link); 7415 @old_link = @link; 7416 unless ($done{$file}) { 7417 ++$link[$depth]; 7418# if ($MULTIPLE_FILES && !$depth && $multiple_toc ) { 7419# local($save_depth) = $link[$depth]; 7420# $link[$depth] = 1; 7421# ($NEXT_GROUP, $NEXT_GROUP_TITLE) = 7422# &add_link($next_visible_mark, $file, @link); 7423# &add_link_tag('next', $file, @link); 7424# $link[$depth] = $save_depth; 7425# } else { 7426 ($NEXT_GROUP, $NEXT_GROUP_TITLE) = 7427 &add_link($next_visible_mark, $file, @link); 7428 &add_link_tag('next', $file, @link); 7429# } 7430 7431 $link[$depth]--;$link[$depth]--; 7432 if ($MULTIPLE_FILES && !$depth ) { 7433 } else { 7434 ($PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE) = 7435 &add_link($previous_visible_mark, $file,@link); 7436 &add_link_tag('previous', $file,@link); 7437 } 7438 7439 $link[$depth] = 0; 7440 ($UP, $UP_TITLE) = 7441 &add_link($up_visible_mark, $file, @link); 7442 &add_link_tag('up', $file, @link); 7443 7444 if ($CONTENTS_IN_NAVIGATION) { 7445 ($CONTENTS, $CONTENTS_LINK) = 7446 &add_special_link($contents_visible_mark, $tocfile, $file); 7447 &add_link_tag('contents', $file, $delim.$tocfile); 7448 } 7449 7450 if ($INDEX_IN_NAVIGATION) { 7451 ($INDEX, $INDEX_LINK) = 7452 &add_special_link($index_visible_mark, $idxfile, $file); 7453 &add_link_tag('index', $file, $delim.$idxfile,); 7454 } 7455 7456 @link = split(' ',$tmp_keys[0]); 7457 # the required `next' link may be several sub-sections along 7458 local($nextdepth,$nextfile,$nextkey,$nexttitle,$nextbody)= 7459 ($depth,$file,$key,'',''); 7460 $nextkey = shift @tmp_keys; 7461 ($nextdepth, $nextfile,$nexttitle,$nextbody) = split($delim,$section_info{$nextkey}); 7462 if (($nextdepth<$MAX_SPLIT_DEPTH)&&(!($nextbody=~/external/))) { 7463 ($NEXT, $NEXT_TITLE) = 7464 &add_link($next_page_visible_mark, $file, @link); 7465 &add_link_tag('next', $file, @link); 7466 } else { 7467 ($NEXT, $NEXT_TITLE) = ('',''); 7468 $nextfile = $file; 7469 } 7470 if ((!$NEXT || $NEXT =~ /next_page_inactive_visible_mark/)&&(@tmp_keys)) { 7471 # the required `next' link may be several sub-sections along 7472 while ((@tmp_keys)&&(($MAX_SPLIT_DEPTH < $nextdepth+1)||($nextfile eq $file))) { 7473 $nextkey = shift @tmp_keys; 7474 ($nextdepth, $nextfile,$nexttitle,$nextbody) = split($delim,$section_info{$nextkey}); 7475 if ($nextbody =~ /external/) { 7476 $nextfile = $file; 7477 next; 7478 }; 7479 print ","; 7480 print STDOUT "\n $nextkey" if ($VERBOSITY > 3); 7481 } 7482 @link = split(' ',$nextkey); 7483 if (($nextkey)&&($nextdepth<$MAX_SPLIT_DEPTH)) { 7484 ($NEXT, $NEXT_TITLE) = 7485 &add_link($next_page_visible_mark, $file, @link); 7486 &add_link_tag('next', $file, @link); 7487 } else { 7488 ($NEXT, $NEXT_TITLE) = ($NEXT_GROUP, $NEXT_GROUP_TITLE); 7489 $NEXT =~ s/next_page_(inactive_)?visible_mark/next_page_$1visible_mark/; 7490 ($PREVIOUS, $PREVIOUS_TITLE) = ($PREVIOUS_GROUP, $PREVIOUS_GROUP_TITLE); 7491 $PREVIOUS =~ s/previous_(inactive_)?visible_mark/previous_page_$1visible_mark/; 7492 } 7493 } 7494 unshift (@tmp_keys,$nextkey) if ($nextkey); 7495# 7496 $top_navigation = (defined(&top_navigation_panel) ? 7497 &top_navigation_panel : &navigation_panel) 7498 unless $NO_NAVIGATION; 7499 $bot_navigation = (defined(&bot_navigation_panel) ? 7500 &bot_navigation_panel : &navigation_panel) 7501 unless $NO_NAVIGATION; 7502 local($end_navigation) = "\n<!--End of Navigation Panel-->\n"; 7503 if ($USING_STYLES) { 7504 $top_navigation = "\n".'<DIV CLASS="navigation">' . $top_navigation 7505 if $top_navigation; 7506 $bot_navigation = "\n".'<DIV CLASS="navigation">' . $bot_navigation 7507 if $bot_navigation; 7508 $end_navigation = '</DIV>' . $end_navigation; 7509 $env_style{'navigation'} = " "; 7510 } 7511 7512 $header = &make_head_and_body($title, $body); 7513 $header = join('', $header, $top_navigation, $end_navigation) if ($top_navigation); 7514 7515 local($this_file) = $file; 7516 if ($MULTIPLE_FILES && $ROOTED) { 7517 if ($this_file =~ /\Q$dd\E([^$dd$dd]+)$/) { $this_file = $1 } 7518 } 7519 &slurp_input($this_file); 7520 open(OUTFILE, ">$this_file") 7521 || die "\nError: Cannot write file '$this_file': $!\n"; 7522 7523 if (($INDEX) && ($SHORT_INDEX) && ($SEGMENT eq 1)) { 7524 &make_index_segment($title,$file); } 7525 7526 local($child_star,$child_links); 7527 local($CURRENT_FILE) = $this_file; # ensure $CURRENT_FILE is set correctly 7528 if (/$childlinks_on_mark\#(\d)\#/) { $child_star = $1 } 7529 $child_links = &add_child_links('',$file, $depth, $child_star,$key, @keys) 7530 unless (/$childlinks_null_mark\#(\d)\#/); 7531 if (($child_links)&&(!/$childlinks_mark/)&&($MAX_SPLIT_DEPTH > 1)) { 7532 if ($depth < $MAX_SPLIT_DEPTH -1) { 7533 $_ = join('', $header, $_, &child_line(), $childlinks_mark, "\#0\#" ); 7534 } else { 7535 $_ = join('', $header, "\n$childlinks_mark\#0\#", &upper_child_line(), $_ ); 7536 } 7537 } else { 7538 $_ = join('', $header, $_ ); 7539 } 7540 $flag = (($BOTTOM_NAVIGATION || &auto_navigation) && $bot_navigation); 7541 $_ .= $bot_navigation . $end_navigation if ($flag &&($bot_navigation)); 7542 $_ .= &child_line() unless $flag; 7543 print STDOUT "\n *** replace markers *** " if ($VERBOSITY > 1); 7544 &replace_markers; 7545 print STDOUT "\n *** post-post-process *** " if ($VERBOSITY > 1); 7546 &post_post_process if (defined &post_post_process); 7547 &adjust_encoding; 7548 print OUTFILE $_; 7549 print OUTFILE &make_address; 7550 close OUTFILE; 7551 $done{$file}++; 7552 } 7553 } 7554 &post_process_footnotes if ($footfile); 7555} 7556 7557sub adjust_encoding { 7558 &convert_to_utf8($_) if ($USE_UTF); 7559 &lowercase_tags($_) if $LOWER_CASE_TAGS; 7560} 7561 7562sub post_replace_markers { 7563 # MRO: replaced $* with /m 7564 # clean up starts and ends of P, BR and DIV tags 7565 s/(<\/?(P|BR|DIV)>)\s*(\w)/$1\n$3/gom unless ($file eq $citefile); 7566 s/([^\s])(<(BR|DIV))/$1\n$2/gom unless ($file eq $citefile); 7567 local($keep,$after); 7568 7569 # anchor images when otherwise there is an invisible-anchor 7570# s/(<A[^>]*>)\&\#160;<\/A>\s?(<(P|DIV)[^>]*>)\s*(<IMG[^>]*>)\s*(<\/(P|DIV)>)/ 7571 s/(<A[^>]*>)($anchor_mark|$anchor_invisible_mark)<\/A>\s?(<(P|DIV)[^>]*>)\s*(<IMG[^>]*>)\s*(<\/(P|DIV)>)/ 7572 do{ $keep="$3$1$5<\/A>"; 7573 $after = $6; 7574 join('',$keep, &after_punct_break($after), $after); 7575 } /egom; 7576 7577 # absorb named anchor (e.g. from index-entry) into preceding or following anchor 7578# s/(<A NAME=\"[^\"]+\")>\ <\/A>\s*\b?<A( HREF=\"[^\"]+\">)/$1$2/gom; 7579# s/(<A HREF=\"[^\"]+\")(>\s*\b?([^<]+|<([^>\/]+|\/[^>A]+)>\s*)*<\/A>)\s*\b?<A( NAME=\"[^\"]+\")>\ <\/A>/$1$5$2/gom; 7580 7581 # clean up empty table cells 7582 s/(<TD[^>]*>)\s*(<\/TD>)/<TD>$2/gom; 7583 7584 # clean up list items (only desirable in the bibliography ?) 7585 # s/\n<P>(<DT[^>]*>)/\n<P><\/P>\n$1/gom; 7586 7587 # remove blank lines and comment-markers 7588# s/\n\n/\n/g; # no, cause this kills intended ones in verbatims 7589 s/$comment_mark(\d+\n?)?//gm; 7590 s/\"/"/gm; # replace " entities 7591 7592 # italic \LaTeX looks bad 7593 s:<(I|EM)>(($Laname|$AmSname)?$TeXname)</\1>:$2:gm; 7594} 7595 7596sub lowercase_tags { 7597 # MRO: modified to use $_[0] 7598 # local(*stream) = @_; 7599 my ($tags,$attribs); 7600 $_[0] =~ s!<(/?\w+)( [^>]*)?>! 7601 $tags = $1; $attribs = $2; 7602 $attribs =~ s/ ([\w\d-]+)(=| |$)/' '.lc($1).$2/eg; 7603 join('', '<', lc($tags) , $attribs , '>')!eg; 7604} 7605 7606sub after_punct_break { 7607 # MRO: modified to use $_[0] 7608 # local(*stream) = @_; 7609# $stream =~ s/^([ \t]*)([,;\.\)\!\"\'\?])[ \t]*(\n)?/(($2)? "$2" : "$1")."\n"/em; 7610# $stream; 7611 $_[0] =~ s/^([ \t]*)([,;\.\)\!\"\'\?\>]|\>)[ \t]*(\n)?//em; 7612 ($2 ? $2 : $1)."\n"; 7613} 7614 7615sub make_index_segment { 7616 local($title,$file)= @_ ; 7617#JCL(jcl-tcl) 7618# s/<[^>]*>//g; 7619# 7620 $index_segment{$PREFIX} = "$title"; 7621 if (!($ref_files{"segment"."$PREFIX"} eq "$file")) { 7622 $ref_files{"segment"."$PREFIX"} = "$file"; 7623 $changed = 1 7624 } 7625 $SEGMENT = 2; 7626} 7627 7628 7629sub add_link { 7630 # Returns a pair (iconic link, textual link) 7631 local($icon, $current_file, @link) = @_; 7632 local($dummy, $file, $title, $lbody) = split($delim,$section_info{join(' ',@link)}); 7633 if ($lbody =~ /external/) { return ('','') }; 7634 7635# local($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)}); 7636 7637 if ($MULTIPLE_FILES && $ROOTED && $file) { 7638 if (!($DESTDIR =~ /\Q$FIXEDDIR\E[$dd$dd]?$/)) { $file = "..$dd$file" } 7639 } 7640# if ($title && ($file ne $current_file || $icon ne $up_visible_mark)) { 7641 if ($title && ($file ne $current_file)) { 7642 #RRM: allow user-customisation of the link-text; thanks Dan Young 7643 if (defined &custom_link_hook ) { 7644 $title = &custom_link_hook($title,$toc_section_info{join(' ',@link)}); 7645 } else { 7646 $title = &purify($title); 7647 $title = &get_first_words($title, $WORDS_IN_NAVIGATION_PANEL_TITLES); 7648 } 7649 return ("\n".&make_href($file, $icon), &make_href($file, "$title")) 7650 } 7651# elsif ($icon eq $up_visible_mark && $file eq $current_file && $EXTERNAL_UP_LINK) { 7652 elsif ($icon eq $up_visible_mark && $EXTERNAL_UP_LINK) { 7653 return ("\n".&make_href($EXTERNAL_UP_LINK, $icon), 7654 &make_href($EXTERNAL_UP_LINK, "$EXTERNAL_UP_TITLE")) 7655 } 7656 elsif (($icon eq $previous_visible_mark || $icon eq $previous_page_visible_mark) 7657 && $EXTERNAL_PREV_LINK && $EXTERNAL_PREV_TITLE) { 7658 return ("\n".&make_href($EXTERNAL_PREV_LINK, $icon), 7659 &make_href($EXTERNAL_PREV_LINK, "$EXTERNAL_PREV_TITLE")) 7660 } 7661 elsif (($icon eq $next_visible_mark || $icon eq $next_page_visible_mark) 7662 && $EXTERNAL_DOWN_LINK && $EXTERNAL_DOWN_TITLE) { 7663 return ("\n".&make_href($EXTERNAL_DOWN_LINK, $icon), 7664 &make_href($EXTERNAL_DOWN_LINK, "$EXTERNAL_DOWN_TITLE")) 7665 } 7666 (&inactive_img($icon), ""); 7667} 7668 7669sub add_special_link { &add_real_special_link(@_) } 7670sub add_real_special_link { 7671 local($icon, $file, $current_file) = @_; 7672 local($text); 7673 if ($icon eq $contents_visible_mark) { $text = $toc_title } 7674 elsif ($icon eq $index_visible_mark) { $text = $idx_title } 7675 elsif ($icon eq $biblio_visible_mark) { $text = $bib_title } 7676 (($file && ($file ne $current_file)) ? 7677 ("\n" . &make_href($file, $icon), 7678 ($text ? " ". &make_href($file, $text) : undef)) 7679 : ( undef, undef )) 7680} 7681 7682#RRM: add <LINK ...> tag to the HTML head. 7683# suggested by Marcus Hennecke 7684# 7685sub add_link_tag { 7686 local($rel, $currentfile, @link ) = @_; 7687# local($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)}); 7688 local($dummy, $file, $title) = split($delim,$section_info{join(' ',@link)}); 7689 ($dummy, $file, $title) = split($delim,$toc_section_info{join(' ',@link)}) 7690 unless ($title); 7691 7692 if ($MULTIPLE_FILES && $ROOTED && $file) { 7693 if (!($DESTDIR =~ /\Q$FIXEDDIR\E[$dd$dd]?$/)) { $file = "..$dd$file" } 7694 } 7695 if ($file && !($file eq $currentfile) && (!$NO_NAVIGATION)) { 7696 #RRM: allow user-customisation of the REL attribute 7697 if (defined &custom_REL_hook ) { 7698 $rel = &custom_REL_hook($rel,$toc_section_info{join(' ',@link)}); 7699 } 7700 $more_links .= "\n<LINK REL=\"$rel\" HREF=\"$file\">"; 7701 } 7702} 7703 7704sub remove_markers { 7705# modifies $_ 7706 s/$lof_mark//go; 7707 s/$lot_mark//go; 7708 &remove_bbl_marks; 7709 s/$toc_mark//go; 7710 s/$idx_mark//go; 7711 &remove_cross_ref_marks; 7712 &remove_external_ref_marks; 7713 &remove_cite_marks; 7714 &remove_file_marks; 7715# sensitive markers 7716 &remove_image_marks; 7717 &remove_icon_marks; 7718 &remove_verbatim_marks; 7719 &remove_verb_marks; 7720 &remove_child_marks; 7721# uncaught markers 7722 s/$percent_mark/%/go; 7723 s/$ampersand_mark/\&/go; 7724 s/$comment_mark\s*(\d+\n?)?//sgo; 7725 s/$caption_mark//go; 7726 s/<tex2html[^>]*>//g; 7727 s/$OP\d+\$CP//g; 7728 $_; 7729} 7730 7731sub replace_markers { 7732 &find_quote_ligatures; 7733 &replace_general_markers; 7734 &text_cleanup; 7735 # Must NOT clean the ~'s out of the navigation icons (in panel or text), 7736 # and must not interfere with verbatim-like environments 7737 &replace_sensitive_markers; 7738 &replace_init_file_mark if (/$init_file_mark/); 7739 &replace_file_marks; 7740 &post_replace_markers; 7741} 7742 7743sub replace_general_markers { 7744 if (defined &replace_infopage_hook) {&replace_infopage_hook if (/$info_page_mark/);} 7745 else { &replace_infopage if (/$info_page_mark/); } 7746 if (defined &add_idx_hook) {&add_idx_hook if (/$idx_mark/);} 7747 else {&add_idx if (/$idx_mark/);} 7748 7749 if ($segment_figure_captions) { 7750# s/$lof_mark/<UL>$segment_figure_captions<\/UL>/o 7751# } else { s/$lof_mark/<UL>$figure_captions<\/UL>/o } 7752 s/$lof_mark/$segment_figure_captions/o 7753 } else { s/$lof_mark/$figure_captions/o } 7754 if ($segment_table_captions) { 7755# s/$lot_mark/<UL>$segment_table_captions<\/UL>/o 7756# } else { s/$lot_mark/<UL>$table_captions<\/UL>/o } 7757 s/$lot_mark/$segment_table_captions/o 7758 } else { s/$lot_mark/$table_captions/o } 7759 &replace_morelinks(); 7760 if (defined &replace_citations_hook) {&replace_citations_hook if /$bbl_mark/;} 7761 else {&replace_bbl_marks if /$bbl_mark/;} 7762 if (defined &add_toc_hook) {&add_toc_hook if (/$toc_mark/);} 7763 else {&add_toc if (/$toc_mark/);} 7764 if (defined &add_childs_hook) {&add_childs_hook if (/$childlinks_on_mark/);} 7765 else {&add_childlinks if (/$childlinks_on_mark/);} 7766 &remove_child_marks; 7767 7768 if (defined &replace_cross_references_hook) {&replace_cross_references_hook;} 7769 else {&replace_cross_ref_marks if /$cross_ref_mark||$cross_ref_visible_mark/;} 7770 if (defined &replace_external_references_hook) {&replace_external_references_hook;} 7771 else {&replace_external_ref_marks if /$external_ref_mark/;} 7772 if (defined &replace_cite_references_hook) {&replace_cite_references_hook;} 7773 else { &replace_cite_marks if /$cite_mark/; } 7774 if (defined &replace_user_references) { 7775 &replace_user_references if /$user_ref_mark/; } 7776} 7777 7778sub replace_sensitive_markers { 7779 if (defined &replace_images_hook) {&replace_images_hook;} 7780 else {&replace_image_marks if /$image_mark/;} 7781 if (defined &replace_icons_hook) {&replace_icons_hook;} 7782 else {&replace_icon_marks if /$icon_mark_rx/;} 7783 if (defined &replace_verbatim_hook) {&replace_verbatim_hook;} 7784 else {&replace_verbatim_marks if /$verbatim_mark/;} 7785 if (defined &replace_verb_hook) {&replace_verb_hook;} 7786 else {&replace_verb_marks if /$verb_mark|$verbstar_mark/;} 7787 s/;SPMdollar;/\$/g; s/;SPMtilde;/\~/g; s/;SPMpct;/\%/g; 7788 s/;SPM/\&/go; 7789 s/$percent_mark/%/go; 7790 s/$ampersand_mark/\&/go; 7791 #JKR: Turn encoded ~ back to normal 7792 s/~/~/go; 7793} 7794 7795sub find_quote_ligatures { 7796 my $ent; 7797 7798# guillemets, governed by $NO_FRENCH_QUOTES 7799 do { 7800 $ent = &iso_map('laquo', "", 1); 7801 if ($NO_UTF && !$USE_UTF && $ent=~/\&\#(\d+);/) { 7802 $ent='' if ($1 > 255); 7803 } 7804 s/((\&|;SPM)lt;){2}/$ent/ogs if $ent; 7805 $ent = &iso_map('raquo', "", 1) if ($ent); 7806 s/((\&|;SPM)gt;){2}/$ent/ogs if $ent; 7807 # single guillemot chars cannot be easily implemented this way 7808 # finding an approp regexp is work for the future 7809 } unless ($NO_FRENCH_QUOTES); 7810 7811 $ent = &iso_map("gg", "", 1); 7812 s/;SPMgg;/($ent ? $ent : '>>')/eg unless ($USE_NAMED_ENTITIES); 7813 $ent = &iso_map("ll", "", 1); 7814 s/;SPMll;/($ent ? $ent : '<<')/eg unless ($USE_NAMED_ENTITIES); 7815 7816 my $ldquo, $rdquo; 7817# "curly" quotes, governed by $USE_CURLY_QUOTES. 7818 do { 7819 $ldquo = &iso_map("ldquo", "", 1); 7820 if ($NO_UTF && !$USE_UTF && $ldquo =~ /\&\#(\d+);/) { 7821 $ldquo = '' if ($1 > 255); 7822 } 7823 s/``/$ldquo/ogs if ($ldquo); 7824 $rdquo = &iso_map("rdquo", "", 1) if ($ldquo); 7825 s/''/$rdquo/ogs if ($rdquo); 7826 7827 # single curly quotes cannot be easily implemented this way 7828 # finding an approp regexp is work for the future 7829 } if ($USE_CURLY_QUOTES); 7830 7831# "german" quotes, governed by $NO_GERMAN_QUOTES. 7832 do { 7833 $ent = &iso_map('bdquo', "", 1); 7834 if ($NO_UTF && !$USE_UTF && $ent =~ /\&\#(\d+);/) { 7835 $ent = '' if ($1 > 255); 7836 } 7837 s/,,/$ent/eg if $ent; 7838 7839 # closing upper quotes are not properly displayed in browsers 7840 s/($ent[\w\s\&\#;']+)$ldquo/$1``/og 7841 if ($USE_CURLY_QUOTES && $ldquo && $ent); 7842 } unless ($NO_GERMAN_QUOTES); 7843} 7844 7845sub add_childlinks { 7846 local($before, $after, $star); 7847 while (/$childlinks_on_mark\#(\d)\#/) { 7848 $star = $1; 7849 $before = $`; 7850 $after = $'; 7851 $before =~ s/\n\s*$//; 7852 $_ = join('', $before, "\n", $child_links, $after); 7853 } 7854} 7855 7856sub replace_infopage { 7857 local($INFO)=1 if !(defined $INFO); 7858 if ($INFO == 1) { 7859 local($title); 7860 if ((defined &do_cmd_infopagename)||$new_command{'infopagename'}) { 7861 local($br_id)=++$global{'max_id'}; 7862 $title = &translate_environments("$O$br_id$C\\infopagename$O$br_id$C"); 7863 } else { $title = $info_title } 7864 if ($MAX_SPLIT_DEPTH <= $section_commands{$outermost_level}) { 7865 $_ =~ s/(<HR[^>]*>\s*)?$info_title_mark/ 7866 ($1? $1 : "\n<HR>")."\n<H2>$title<\/H2>"/eog; 7867 } else { 7868 $_ =~ s/$info_title_mark/"\n<H2>$title<\/H2>"/eog; 7869 } 7870 } 7871 while (/$info_page_mark/o) { 7872 $_ = join('', $`, &do_cmd_textohtmlinfopage, $'); 7873 } 7874} 7875 7876sub replace_init_file_mark { 7877 local($init_file, $init_contents, $info_line)=($INIT_FILE,'',''); 7878 if (-f $init_file) { 7879 } elsif (-f "$orig_cwd$dd$init_file") { 7880 $init_file = $orig_cwd.$dd.$init_file; 7881 } else { 7882 s/$init_file_mark//g; 7883 return(); 7884 } 7885 if(open(INIT, "<$init_file")) { 7886 foreach $info_line (<INIT>) { 7887 $info_line =~ s/[<>"&]/'&'.$html_special_entities{$&}.';'/eg; 7888 $init_contents .= $info_line; 7889 } 7890 close INIT; 7891 } else { 7892 print "\nError: Cannot read '$init_file': $!\n"; 7893 } 7894 s/$init_file_mark/\n<BLOCKQUOTE><PRE>\n$init_contents\n<\/PRE><\/BLOCKQUOTE>\n/g; 7895} 7896 7897sub replace_morelinks { 7898 $_ =~ s/$more_links_mark/$more_links/e; 7899} 7900 7901# This code is extremely inefficient. At least the subtrees should be 7902# filtered according to $MAX_LINK_DEPTH before going into the 7903# inner loops. 7904# RRM: revamped parts, for $TOC_STARS, fixing some errors. 7905# 7906sub add_child_links { &add_real_child_links(@_) } 7907sub add_real_child_links { 7908 local($exclude, $base_file, $depth, $star, $current_key, @keys) = @_; 7909 local $min_depth = $section_commands{$outermost_level} - 1; 7910 return ('') if ((!$exclude)&&(!$LEAF_LINKS)&&($depth >= $MAX_SPLIT_DEPTH)); 7911 if ((!$depth)&&($outermost_level)) { $depth = $min_depth } 7912 7913 local($_, $child_rx, @subtree, $next, %open, @roottree); 7914 local($first, $what, $pre, $change_key, $list_class); 7915 $childlinks_start = join('','<div id="table-of-contents">',"\n", 7916 '<!--Table of Child-Links-->',"\n") ; 7917 $childlinks_end = join('',"<!--End of Table of Child-Links-->","\n",'</div>',"\n") ; 7918 $child_rx = $current_key; 7919 $child_rx =~ s/( 0)*$//; # Remove trailing 0's 7920 if ((!$exclude)&&($depth < $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH -1 ) 7921 # &&($depth >= $MAX_SPLIT_DEPTH-1)) { 7922 &&($depth > $min_depth)) { 7923 if ((defined &do_cmd_childlinksname)||$new_command{'childlinksname'}) { 7924 local($br_id)=++$global{'max_id'}; 7925 $what = &translate_environments("$O$br_id$C\\childlinksname$O$br_id$C"); 7926 } else { 7927 $what = "<strong>$child_name</strong>"; 7928 } 7929 $list_class = ' CLASS="ChildLinks"' if ($USING_STYLES); 7930 $first = "$childlinks_start\n<A NAME=\"CHILD_LINKS\">$what<\/A>\n"; 7931 } elsif ($exclude) { 7932 # remove any surrounding braces 7933 $exclude =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g; 7934 # Table-of-Contents 7935 $list_class = ' CLASS="TofC"' if ($USING_STYLES); 7936 $childlinks_start = "\n<!--Table of Contents-->\n"; 7937 $childlinks_end = "<!--End of Table of Contents-->"; 7938 $first = "$childlinks_start"; 7939 } else { 7940 $list_class = ' CLASS="ChildLinks"' if ($USING_STYLES); 7941 $first = "$childlinks_start\n" 7942 . ($star ? '':"<A NAME=\"CHILD_LINKS\">$anchor_mark<\/A>\n"); 7943 } 7944 my $startlist, $endlist; 7945 $startlist = "<UL$list_class>" unless $CHILD_NOLIST; 7946 $endlist = '</UL>' unless $CHILD_NOLIST; 7947 my $alt_item = '<BR> <BR>'."\n"; 7948 my $outer_item = ($CHILD_NOLIST ? $alt_item : '<LI>'); 7949 my $inner_item = '<LI>'; 7950 my $inner_end = '</UL><BR>'; 7951 7952 # collect the relevant keys... 7953 foreach $next (@keys) { 7954 if ($MULTIPLE_FILES && $exclude) { 7955 # ...all but with this document as the root 7956 if ($next =~ /^$THIS_FILE /) { 7957# # make current document the root 7958# $change_key = '0 '.$'; 7959 push(@roottree,$next); 7960 print "\n$next : m-root" if ($VERBOSITY > 3); 7961 } else { 7962 push(@subtree,$next); 7963 print "\n$next : m-sub" if ($VERBOSITY > 3); 7964 } 7965 } elsif (($next =~ /^$child_rx /)&&($next ne $current_key)) { 7966 # ...which start as $current_key 7967 push(@subtree,$next); 7968 print "\n$next : sub $child_rx" if ($VERBOSITY > 3); 7969 } else { 7970 print "\n$next : out $current_key" if ($VERBOSITY > 3); 7971 } 7972 } 7973 if (@subtree) { @subtree = sort numerically @subtree; } 7974 if (@roottree) { 7975 @roottree = sort numerically @roottree; 7976 @subtree = ( @roottree, @subtree ); 7977 } 7978 # @subtree now contains the subtree rooted at the current node 7979 7980 local($countUL); #counter to ensure correct tag matching 7981 my $root_file, $href; 7982 if (@subtree) { 7983 local($next_depth, $file, $title, $sec_title, $star, $ldepth,$this_file, $prev_file); 7984 $ldepth = $depth; 7985 $prev_file = $base_file; 7986# @subtree = sort numerically @subtree; 7987 foreach $next (@subtree) { 7988 $title = ''; 7989 if ($exclude) { 7990 # making TOC 7991 ($next_depth, $file, $sec_title) = 7992 split($delim,$section_info{$next}); 7993 ($next_depth, $file, $title, $star) = 7994 split($delim,$toc_section_info{$next}); 7995 # use the %section_info title, in case there are images 7996 $title = $sec_title if ($sec_title =~ /image_mark>\#/); 7997 } else { 7998 # making mini-TOC i.e. the child-links tables 7999 $star = ''; 8000 ($next_depth, $file, $title) = 8001 split($delim,$section_info{$next}); 8002 } 8003 $root_file = $file unless $root_file; 8004 if ($root_file && $root_file =~ /_mn\./) { $root_file=$` }; 8005 # remove any surrounding braces 8006 $title =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g; 8007 next if ($exclude && $title =~ /^$exclude$/); 8008 if (!$title) { 8009 ($next_depth, $file, $title, $star) = 8010 split($delim,$toc_section_info{$next}); 8011 } 8012 $this_file = $file; 8013 $title = "\n".$title if !($title =~/^\n/); 8014 next if ( $exclude &&( # doing Table-of-Contents 8015 ( $TOC_DEPTH &&($next_depth > $TOC_DEPTH)) # and too deep 8016 ||($star && !$TOC_STARS ) )); # or no starred sections 8017 $file = "" if (!$MAX_SPLIT_DEPTH); # Martin Wilck 8018 next if ($exclude && !$MULTIPLE_FILES &&($title =~ /^\s*$exclude\s*$/)); 8019 next if (!$exclude && $next_depth > $MAX_LINK_DEPTH + $depth); 8020 print "\n$next :" if ($VERBOSITY > 3); 8021 if ($this_file =~ /^(\Q$prev_file\E|\Q$base_file\E)$/) { 8022 $file .= join('', "#SECTION", split(' ', $next)); 8023 } else { $prev_file = $file } 8024 8025 if (!$next_depth && $MULTIPLE_FILES) { ++$next_depth } 8026 local($num_open) = (split('/',%open))[0]; 8027 if ((($next_depth > $ldepth)||$first) 8028 && ((split('/',%open))[0] < $MAX_LINK_DEPTH + $depth ) 8029 ) { 8030 # start a new <UL> list 8031 if ($first) { 8032 $_ = "$first\n$startlist\n"; $countUL++; 8033 local $i = 1; 8034 while ($i <= $ldepth) { 8035 $open{$i}=0; $i++ 8036 } 8037 $first = ''; # include NAME tag first time only 8038 while ($i < $next_depth) { 8039 $open{$i}=1; $i++; 8040 $_ .= ($countUL >1 ? $inner_item : $outer_item)."<UL>\n"; 8041 $countUL++; 8042 } 8043 } else { 8044 $_ .= "<UL>\n"; $countUL++; 8045 } 8046 $ldepth = $next_depth; 8047 $open{$ldepth}++; 8048 # append item to this list 8049 print " yes " if ($VERBOSITY > 3); 8050 if (defined &add_frame_child_links) { 8051 $href = &make_href($file,$title); 8052 if ($href =~ s/($root_file)_mn/$1_ct/) { 8053 $href =~ s/(target=")main(")/$1contents$2/i; 8054 }; 8055 $_ .= ($countUL >1 ? $inner_item : $outer_item) 8056 . $href . "\n"; 8057 } else { 8058 $_ .= ($countUL >1 ? $inner_item : $outer_item) 8059 . &make_href($file,$title) . "\n"; 8060 } 8061 } 8062 elsif (($next_depth)&&($next_depth <= $ldepth) 8063 &&((split('/',%open))[0] <= $MAX_LINK_DEPTH + $depth ) 8064 ) { 8065 # append item to existing <UL> list 8066 while (($next_depth < $ldepth) && %open ) { 8067 # ...closing-off any nested <UL> lists 8068 if ($open{$ldepth}) { 8069 if (!(defined $open{$next_depth})) { 8070 $open{$next_depth}++; 8071 } else { 8072 $_ .= ($countUL==2 ? $inner_end : '</UL>')."\n"; 8073 $countUL--; 8074 } 8075 delete $open{$ldepth}; 8076 }; 8077 $ldepth--; 8078 } 8079 $ldepth = $next_depth; 8080 print " yes" if ($VERBOSITY > 3); 8081 if (defined &add_frame_child_links) { 8082 $href = &make_href($file,$title); 8083 if ($href =~ s/($root_file)_mn/$1_ct/) { 8084 $href =~ s/(target=")main(")/$1contents$2/i; 8085 }; 8086 $_ .= ($countUL >1 ? $inner_item : $outer_item) 8087 . $href . "\n"; 8088 } else { 8089 $_ .= ($countUL >1 ? $inner_item : $outer_item) 8090 . &make_href($file,$title) . "\n"; 8091 } 8092 } else { 8093 # ignore items that are deeper than $MAX_LINK_DEPTH 8094 print " no" if ($VERBOSITY > 3); 8095 } 8096 } 8097 8098 if (%open) { 8099 # close-off any remaining <UL> lists 8100 $countUL-- if $CHILD_NOLIST; 8101 local $cnt = (split('/',%open))[0]; 8102 local $i = $cnt; 8103 while ($i > $depth) { 8104 if ($open{$i}) { 8105 $_ .= '</UL>' if $countUL; 8106 $countUL--; 8107 delete $open{$i}; 8108 } 8109 $i--; 8110 } 8111 } 8112 } 8113 # just in case the count is wrong 8114 $countUL-- if ($CHILD_NOLIST && $countUL > 0); 8115 $countUL = '' if ($countUL < 0); 8116 while ($countUL) { $_ .= '</UL>'; $countUL-- } 8117 ($_ ? join('', $_, "\n$childlinks_end") : ''); 8118} 8119 8120sub child_line {($CHILDLINE) ? "$CHILDLINE" : "<BR>\n<HR>";} 8121sub upper_child_line { "<HR>\n"; } 8122 8123sub adjust_root_keys { 8124 return() unless ($MULTIPLE_FILES && $ROOTED); 8125 local($next,$change_key,$current_rx); 8126 local(@keys) = (keys %toc_section_info); 8127 8128 local($current_key) = join(' ',@curr_sec_id); 8129 $current_key =~ /^(\d+ )/; 8130 $current_rx = $1; 8131 return() unless $current_rx; 8132 8133 # alter the keys which start as $current_key 8134 foreach $next (@keys) { 8135 if ($next =~ /^$current_rx/) { 8136 # make current document the root 8137 $change_key = '0 '.$'; 8138 $toc_section_info{$change_key} = $toc_section_info{$next}; 8139 $section_info{$change_key} = $section_info{$next}; 8140# if (!($next eq $current_key)) { 8141# $toc_section_info{$next} = $section_info{$next} = ''; 8142# } 8143 } 8144 } 8145} 8146 8147sub top_page { 8148 local($file, @navigation_panel) = @_; 8149 # It is the top page if there is a link to itself 8150 join('', @navigation_panel) =~ /$file/; 8151} 8152 8153# Sets global variable $AUX_FILE 8154sub process_aux_file { 8155 local(@exts) = ('aux'); 8156 push(@exts, 'lof') if (/\\listoffigures/s); 8157 push(@exts, 'lot') if (/\\listoftables/s); 8158 local($_, $status); # To protect caller from &process_ext_file 8159 $AUX_FILE = 1; 8160 foreach $auxfile (@exts) { 8161 $status = &process_ext_file($auxfile); 8162 if ($auxfile eq "aux" && ! $status) { 8163 print "\nCannot open $FILE.aux $!\n"; 8164 &write_warnings("\nThe $FILE.aux file was not found," . 8165 " so sections will not be numbered \nand cross-references " 8166 . "will be shown as icons.\n"); 8167 } 8168 } 8169 $AUX_FILE = 0; 8170} 8171 8172sub do_cmd_htmlurl { 8173 local($_) = @_; 8174 local($url); 8175 $url = &missing_braces unless ( 8176 (s/$next_pair_pr_rx/$br_id=$1;$url=$2;''/e) 8177 ||(s/$next_pair_rx/$br_id=$1;$url=$2;''/e)); 8178 $url =~ s/\\(html)?url\s*($O|$OP)([^<]*)\2/$3/; 8179 $url =~ s/\\?~/;SPMtilde;/og; 8180 join('','<TT>', &make_href($url,$url), '</TT>', $_); 8181} 8182sub do_cmd_url { &do_cmd_htmlurl(@_) } 8183 8184sub make_href { &make_real_href(@_) } 8185sub make_real_href { 8186 local($link, $text) = @_; 8187 $href_name++; 8188 my $htarget = ''; 8189 $htarget = ' target="'.$target.'"' 8190 if (($target)&&($HTML_VERSION > 3.2)); 8191 #HWS: Nested anchors not allowed. 8192 $text =~ s/<A .*><\/A>//go; 8193 $text =~ s:<A [^>]*>([^<]+)</A>:$1:gi; 8194 #JKR: ~ is handled different - ~ is turned to ~ later. 8195 #$link =~ s/~/$percent_mark . "7E"/geo; 8196 if ($text eq $link) { $text =~ s/~/~/g; } 8197 $link =~ s/~/~/g; 8198 # catch \url or \htmlurl 8199 $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/; 8200 $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:; 8201 # this should not be here; else TOC, List of Figs, etc. fail: 8202 # $link =~ s/^\Q$CURRENT_FILE\E(\#)/$1/ unless ($SEGMENT||$SEGMENTED); 8203 $text = &simplify($text); 8204 "<A NAME=\"tex2html$href_name\"$htarget\n HREF=\"$link\">$text</A>"; 8205} 8206 8207sub make_href_noexpand { # clean 8208 my ($link, $name, $text) = @_; 8209 do {$name = "tex2html". $href_name++} unless $name; 8210 #HWS: Nested anchors not allowed. 8211 $text =~ s/<A .*><\/A>//go; 8212 #JKR: ~ is handled different - ~ is turned to ~ later. 8213 #$link =~ s/~/$percent_mark . "7E"/geo; 8214 if ($text eq $link) { $text =~ s/~/~/g; } 8215 $link =~ s/~/~/g; 8216 # catch \url or \htmlurl 8217 $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/; 8218 $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:; 8219 "<A NAME=\"$name\"\n HREF=\"$link\">$text</A>"; 8220} 8221 8222sub make_named_href { 8223 local($name, $link, $text) = @_; 8224 $text =~ s/<A .*><\/A>//go; 8225 $text = &simplify($text); 8226 if ($text eq $link) { $text =~ s/~/~/g; } 8227 $link =~ s/~/~/g; 8228 # catch \url or \htmlurl 8229 $link =~ s/\\(html)?url\s*(($O|$OP)\d+($C|$CP))([^<]*)\2/$5/; 8230 $link =~ s:(<TT>)?<A [^>]*>([^<]*)</A>(</TT>)?(([^<]*)|$):$2$4:; 8231 if (!($name)) {"<A\n HREF=\"$link\">$text</A>";} 8232 elsif ($text =~ /^\w/) {"<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";} 8233 else {"<A NAME=\"$name\"\n HREF=\"$link\">$text</A>";} 8234} 8235 8236sub make_section_heading { 8237 local($text, $level, $anchors) = @_; 8238 local($elevel) = $level; $elevel =~ s/^(\w+)\s.*$/$1/; 8239 local($section_tag) = join('', @curr_sec_id); 8240 local($align,$pre_anchors); 8241 8242 # separate any invisible anchors or alignment, if this has not already been done 8243 if (!($anchors)){ ($anchors,$text) = &extract_anchors($text) } 8244 else { 8245 $anchors =~ s/(ALIGN=\"\w*\")/$align = " $1";''/e; 8246 $align = '' if ($HTML_VERSION < 2.2); 8247 $anchors = &translate_commands($anchors) if ($anchors =~ /\\/); 8248 } 8249 8250 # strip off remains of bracketings 8251 $text =~ s/$OP\d+$CP//g; 8252 if (!($text)) { 8253 # anchor to a single `.' only 8254 $text = "<A NAME=\"SECTION$section_tag\">.</A>$anchors\n"; 8255 } elsif ($anchors) { 8256# # put anchors immediately after, except if title is too long 8257# if ((length($text)<60 )&&(!($align)||($align =~/left/))) { 8258# $text = "<A NAME=\"SECTION$section_tag\">$text</A>\n" . $anchors; 8259 # ...put anchors preceding the title, on a separate when left-aligned 8260# } else { 8261 $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A>$anchors" 8262 . (!($align)||($align =~ /left/i ) ? "<BR>" : "") . "\n". $text; 8263# } 8264 } elsif (!($text =~ /<A[^\w]/io)) { 8265 # no embedded anchors, so anchor it all 8266 $text = "<A NAME=\"SECTION$section_tag\">\n" . $text . "</A>"; 8267 } else { 8268 # there are embedded anchors; these cannot be nested 8269 local ($tmp) = $text; 8270 $tmp =~ s/<//o ; # find 1st < 8271 if ($`) { # anchor text before the first < 8272# $text = "<A NAME=\"SECTION$section_tag\">\n" . $` . "</A>\n<" . $'; 8273 $text = "<A NAME=\"SECTION$section_tag\">\n" . $` . "</A>"; 8274 $pre_anchors = "<" . $'; 8275 if ($pre_anchors =~ /^(<A NAME=\"[^\"]+>${anchor_invisible_mark}<\/A>\s*)+$/) { 8276 $pre_anchors .= "\n" 8277 } else { $text .= $pre_anchors; $pre_anchors = '' } 8278 } else { 8279 # $text starts with a tag 8280 local($after,$tmp) = ($',''); 8281 if ( $after =~ /^A[^\w]/i ) { 8282 # it is an anchor already, so need a separate line 8283 $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A><BR>\n$text"; 8284 } else { 8285 # Is it a tag enclosing the anchor ? 8286 $after =~ s/^(\w)*[\s|>]/$tmp = $1;''/eo; 8287 if ($after =~ /<A.*<\/$tmp>/) { 8288 # it encloses an anchor, so use anchor_mark + break 8289 $text = "<A NAME=\"SECTION$section_tag\">$anchor_invisible_mark</A><BR>\n$text"; 8290 } else { 8291 # take up to the anchor 8292 $text =~ s/^(.*)<A([^\w])/"<A NAME=\"SECTION$section_tag\">$1<A$2"/oe; 8293 } 8294 } 8295 } 8296 } 8297 "$pre_anchors\n<$level$align>$text\n<\/$elevel>"; 8298} 8299 8300sub do_cmd_captionstar { &process_cmd_caption(1, @_) } 8301sub do_cmd_caption { &process_cmd_caption('', @_) } 8302sub process_cmd_caption { 8303 local($noLOTentry, $_) = @_; 8304 local($text,$opt,$br_id, $contents); 8305 local($opt) = &get_next_optional_argument; 8306 $text = &missing_braces unless ( 8307 (s/$next_pair_pr_rx/$br_id=$1;$text=$2;''/e) 8308 ||(s/$next_pair_rx/$br_id=$1;$text=$2;''/e)); 8309 8310 # put it in $contents, so &extract_captions can find it 8311 local($contents) = join('','\caption', ($opt ? "[$opt]" : '') 8312 , "$O$br_id$C" , $text , "$O$br_id$C"); 8313 8314 # $cap_env is set by the surrounding figure/table 8315 &extract_captions($cap_env); 8316 $contents.$_; 8317} 8318 8319sub extract_captions { 8320 # Uses and modifies $contents and $cap_anchors, defined in translate_environments 8321 # and modifies $figure_captions, $table_captions, $before and $after 8322 # MRO: no effect! local($env,*cap_width) = @_; 8323 local($env) = @_; 8324 local(%captions, %optional_captions, $key, $caption, $optional_caption, 8325 $item, $type, $list, $extra_list, $number, @tmp, $br_id, $_, $bcaption); 8326 # associate the br_id of the caption with the argument of the caption 8327 $contents =~ s/$caption_rx(\n)?/do { 8328 $key = $9; $caption = $10; $optional_caption = $3; 8329 $key = &filter_caption_key($key) if (defined &filter_caption_key); 8330 $optional_captions{$key} = $optional_caption||$caption; 8331 print "PCT: nowhere captions: key: $key - caption: " . $captions{$key} ; "\n" if ($VERBOSITY > 10) ; 8332 $captions{$key} = $10; ''}/ego; 8333# $captions{$9} = $10; $caption_mark }/ego; 8334 $key = $caption = $optional_caption = ''; 8335 8336 #catch any \captionwidth settings that may remain 8337 $contents =~ s/$caption_width_rx(\n)?/&translate_commands($&);''/eo; 8338 8339# $after = join("","<P>",$after) if ($&); 8340# $before .= "</P>" if ($&); 8341 #JKR: Replaced "Figure" and "Table" with variables (see latex2html.config too). 8342 if ($env eq 'figure') { 8343 if ((defined &do_cmd_figurename)||$new_command{'figurename'}){ 8344 $br_id = ++$global{'max_id'}; 8345 $type = &translate_environments("$O$br_id$C\\figurename$O$br_id$C") 8346 unless ($noLOFentry); 8347 } else { $type = $fig_name } 8348 $list = "\$figure_captions"; 8349# $extra_list = "\$segment_figure_captions" if ($figure_table_captions); 8350 $extra_list = "\$segment_figure_captions" if ($segment_figure_captions); 8351 } 8352 elsif ($env =~ /table/) { 8353 print "PCT: extract_captions: table: $env\n" if ($VERBOSITY > 10) ; 8354 if ((defined &do_cmd_tablename)||$new_command{'tablename'}) { 8355 print "PCT: extract_captions: tablename...\n" if ($VERBOSITY > 10) ; 8356 $br_id = ++$global{'max_id'}; 8357 $type = &translate_environments("$O$br_id$C\\tablename$O$br_id$C") unless ($noLOTentry); 8358 } 8359 else { 8360 $type = $tab_name ; 8361 } 8362 $list = "\$table_captions"; 8363 $extra_list = "\$segment_table_captions" if ($segment_table_captions); 8364 print "PCT: extract_captions: tab_name: $tab_name - type: $type - list: $list et $table_captions - extra_list: $extra_list\n" if ($VERBOSITY > 10) ; 8365 } 8366 8367# $captions = ""; 8368 $cap_anchors = ""; 8369 local($this); 8370 foreach $key (sort {$a <=> $b;} keys %captions){ # Sort numerically 8371 $this = $captions{$key}; 8372 $this =~ s/\\label\s*($O\d+$C)[^<]+\1//g; # remove \label commands 8373 local($br_id) = ++$global{'max_id'}; 8374 local($open_tags_R) = []; # locally, initially no style 8375 $caption = &translate_commands(&translate_environments("$O$br_id$C$this$O$br_id$C")); 8376 8377 # same again for the optional caption 8378 $this = $optional_captions{$key}; 8379 $this =~ s/\\label\s*($O\d+$C)[^<]+\1//g; # remove \label commands 8380 local($open_tags_R) = []; local($br_id) = ++$global{'max_id'}; 8381 $this = &translate_environments("$O$br_id$C$this$O$br_id$C"); 8382 $optional_caption = &translate_commands($this); 8383 8384 $cap_anchors .= "<A NAME=\"$key\">$anchor_mark</A>"; 8385 $_ = $optional_caption || $caption; 8386 8387 8388 # split at embedded anchor or citation marker 8389 local($pre_anchor,$post_anchor) = ('',''); 8390 if (/\s*(<A\W|\#[^#]*\#<tex2html_cite_[^>]*>)/){ 8391 $pre_anchor = "$`"; 8392 $post_anchor = "$&$'"; 8393 $pre_anchor = $anchor_invisible_mark 8394 unless (($pre_anchor)||($SHOW_SECTION_NUMBERS)); 8395 } else { 8396 $pre_anchor = "$_"; 8397 } 8398 8399#JCL(jcl-tcl) 8400## &text_cleanup; 8401## $_ = &encode_title($_); 8402## s/ //g; # HWS - LaTeX changes ~ in its .aux files 8403# $_ = &sanitize($_); 8404## 8405# $_ = &revert_to_raw_tex($_); 8406 8407 #replace image-markers by the image params 8408 s/$image_mark\#([^\#]+)\#/&purify_caption($1)/e; 8409 8410 local($checking_caption, $cap_key) = (1, $_); 8411 $cap_key = &simplify($cap_key); 8412 $cap_key = &sanitize($cap_key); 8413 @tmp = split(/$;/, eval ("\$encoded_$env" . "_number{\$cap_key}")); 8414 $number = shift(@tmp); 8415 $number = "" if ($number eq "-1"); 8416 8417 if (!$number) { 8418 $cap_key = &revert_to_raw_tex($cap_key); 8419 @tmp = split(/$;/ 8420 , eval ("\$encoded_$env" . "_number{\$cap_key}")); 8421 $number = shift(@tmp); 8422 $number = "" if ($number eq "-1"); 8423 } 8424 8425 #resolve any embedded cross-references first 8426 $checking_caption = ''; 8427 $_ = &simplify($_); 8428 $_ = &sanitize($_); 8429 8430 8431# @tmp = split(/$;/, eval ("\$encoded_$env" . "_number{\$_}")); 8432# $number = shift(@tmp); 8433# $number = "" if ($number eq "-1"); 8434 8435 &write_warnings(qq|\nNo number for "$_"|) if (! $number); 8436 eval("\$encoded_$env" . "_number{\$_} = join(\$;, \@tmp)"); 8437 8438 $item = join( '', ($SHOW_SECTION_NUMBERS ? $number."\. " : '') 8439 , &make_href("$CURRENT_FILE#$key", $pre_anchor) 8440 , $post_anchor); 8441 undef $_; 8442 undef @tmp; 8443 8444 $bcaption = join("",($bcaption) ? $bcaption : '', $caption) ; 8445 $captions = join("", ($captions ? $captions."\n<BR>\n" : '') 8446 , "<STRONG>$type" , ($number ? " $number:" : ":") 8447 , "</STRONG>\n$caption" , (($captions) ? "\n" : "" )); 8448 8449 do { 8450 eval "$extra_list .= \"\n<LI>\" .\$item" if ($extra_list); 8451 eval "$list .= \"\n<LI>\" .\$item" 8452 } unless ( $noLOTentry || $noLOFentry); 8453 # eval("print \"\nCAPTIONS:\".$extra_list.\n\""); 8454 } 8455 $bcaption ; 8456} 8457 8458 8459# This processes \label commands found in environments that will 8460# be handed over to Latex. Sets the table %symbolic_labels 8461sub do_labels { 8462 local($context,$new_context) = @_; 8463 local($label); 8464 # MRO: replaced $* by /m 8465 $context =~ s/\s*$labels_rx/do { 8466 $label = &do_labels_helper($2); 8467 $new_context = &anchor_label($label,$CURRENT_FILE,$new_context);""}/geom; 8468 $new_context; 8469} 8470 8471sub extract_labels { 8472 local($_) = @_; 8473 local($label,$anchors); 8474 # MRO: replaced $* by /m 8475 while (s/[ \t]*$labels_rx//om) { 8476 $label = &do_labels_helper($2); 8477 $anchors .= &anchor_label($label,$CURRENT_FILE,''); 8478 } 8479 ($_, $anchors); 8480} 8481 8482# This should be done inside the substitution but it doesn't work ... 8483sub do_labels_helper { 8484 local($_) = @_; 8485 s/$label_rx/_/g; # replace non-alphanumeric characters 8486 $symbolic_labels{$_} = $latex_labels{$_}; # May be empty; 8487 $_; 8488} 8489 8490sub convert_to_description_list { 8491 # MRO: modified to use $_[1] 8492 # local($which, *list) = @_; 8493 my $which = $_[0]; 8494 $_[1] =~ s!(</A>\s*)<[OU]L([^>]*)>!$1<DD><DL$2>!ig; 8495 $_[1] =~ s!<(/?)[OU]L([^>]*)>!$1? "<$1DL$2>":"<DL$2>"!eig; 8496 $_[1] =~ s!(</?)LI>!$1D$which>!ig; 8497# $_[1] =~ s/^\s*<DD>//; 8498} 8499 8500sub add_toc { &add_real_toc(@_) } 8501sub add_real_toc { 8502 local($temp1, $temp2); 8503 print "\nDoing table of contents ..."; 8504 local(@keys) = keys %toc_section_info; 8505 @keys = sort numerically @keys; 8506 $temp1 = $MAX_LINK_DEPTH; $temp2 = $MAX_SPLIT_DEPTH; 8507 $MAX_SPLIT_DEPTH = $MAX_LINK_DEPTH = 1000; 8508 #JKR: Here was a "Contents" - replaced it with $toc_title 8509 local($base_key) = $keys[0]; 8510 if ($MULTIPLE_FILES) { 8511 $base_key = $THIS_FILE; 8512 } 8513 local($title); 8514 if ((defined &do_cmd_contentsname)||$new_command{'contentsname'}) { 8515 local($br_id)=++$global{'max_id'}; 8516 $title = &translate_environments("$O$br_id$C\\contentsname$O$br_id$C"); 8517 } else { $title = $toc_title } 8518 local($toc,$on_first_page) = ('',''); 8519 $on_first_page = $CURRENT_FILE 8520 unless ($MAX_SPLIT_DEPTH && $MAX_SPLIT_DEPTH <1000); 8521 $toc = &add_child_links($title,$on_first_page,'',1,$keys[0],@keys); 8522 &convert_to_description_list('T',$toc) if ($use_description_list); 8523 s/$toc_mark/$toc/; 8524 $MAX_LINK_DEPTH = $temp1; $MAX_SPLIT_DEPTH = $temp2; 8525} 8526 8527# Assign ref value, but postpone naming the label 8528sub make_half_href { 8529 local($link) = $_[0]; 8530 $href_name++; 8531 "<A NAME=\"tex2html$href_name\"\n HREF=\"$link\">"; 8532} 8533 8534 8535# Redefined in makeidx.perl 8536sub add_idx { 8537 local($sidx_style, $eidx_style) =('<STRONG>','</STRONG>'); 8538 if ($INDEX_STYLES) { 8539 if ($INDEX_STYLES =~/,/) { 8540 local(@styles) = split(/\s*,\s*/,$INDEX_STYLES); 8541 $sidx_style = join('','<', join('><',@styles) ,'>'); 8542 $eidx_style = join('','</', join('></',reverse(@styles)) ,'>'); 8543 } else { 8544 $sidx_style = join('','<', $INDEX_STYLES,'>'); 8545 $eidx_style = join('','</', $INDEX_STYLES,'>'); 8546 } 8547 } 8548 &add_real_idx(@_) 8549} 8550sub add_real_idx { 8551 print "\nDoing the index ..."; 8552 local($key, $str, @keys, $index, $level, $count, 8553 @previous, @current); 8554 @keys = keys %index; 8555 @keys = sort keysort @keys; 8556 $level = 0; 8557 foreach $key (@keys) { 8558 @current = split(/!/, $key); 8559 $count = 0; 8560 while ($current[$count] eq $previous[$count]) { 8561 $count++; 8562 } 8563 while ($count > $level) { 8564 $index .= "\n<DL COMPACT>"; 8565 $level++; 8566 } 8567 while ($count < $level) { 8568 $index .= "\n</DL>"; 8569 $level--; 8570 } 8571 foreach $term (@current[$count .. $#current-1]) { 8572 # need to "step in" a little 8573# $index .= "<DT>" . $term . "\n<DL COMPACT>"; 8574 $index .= "\n<DT>$sidx_style" . $term . "$eidx_style\n<DD><DL COMPACT>"; 8575 $level++; 8576 } 8577 $str = $current[$#current]; 8578 $str =~ s/\#\#\#\d+$//o; # Remove the unique id's 8579 $index .= $index{$key} . 8580 # If it's the same string don't start a new line 8581 (&index_key_eq(join('',@current), join('',@previous)) ? 8582 ", $sidx_style" . $cross_ref_visible_mark . "$eidx_style</A>\n" : 8583 "<DT>$sidx_style" . $str . "$eidx_style</A>\n"); 8584 @previous = @current; 8585 } 8586 while ($count < $level) { 8587 $index .= "\n</DL>"; 8588 $level--; 8589 } 8590 $index = '<DD>'.$index unless ($index =~ /^\s*<D(T|D)>/); 8591 8592 $index =~ s/(<A [^>]*>)(<D(T|D)>)/$2$1/g; 8593 8594# s/$idx_mark/<DL COMPACT>$index<\/DL>/o; 8595 s/$idx_mark/$preindex\n<DL COMPACT>\n$index<\/DL>\n/o; 8596} 8597 8598sub keysort { 8599 local($x, $y) = ($a,$b); 8600 $x = &clean_key($x); 8601 $y = &clean_key($y); 8602# "\L$x" cmp "\L$y"; # changed sort-rules, by M Ernst. 8603 # Put alphabetic characters after symbols; already downcased 8604 $x =~ s/^([a-z])/~~~$1/; 8605 $y =~ s/^([a-z])/~~~$1/; 8606 $x cmp $y; 8607} 8608 8609sub index_key_eq { 8610 local($a,$b) = @_; 8611 $a = &clean_key($a); 8612 $b = &clean_key($b); 8613 $a eq $b; 8614} 8615 8616sub clean_key { 8617 local ($_) = @_; 8618 tr/A-Z/a-z/; 8619 s/\s+/ /g; # squeeze white space and newlines into space 8620 s/ (\W)/$1/g; # make foo( ), foo () and foo(), or <TT>foo</TT> 8621 ; # and <TT>foo </TT> to be equal 8622 s/$O\d+$C//go; # Get rid of bracket id's 8623 s/$OP\d+$CP//go; # Get rid of processed bracket id's 8624 s/\#\#\#\d+$//o; # Remove the unique id 8625 $_; 8626} 8627 8628 8629sub make_footnotes { 8630 # Uses $footnotes defined in translate and set in do_cmd_footnote 8631 # Also uses $footfile 8632 local($_) = "\n<DL>$footnotes\n<\/DL>"; 8633 $footnotes = ""; # else they get used 8634 local($title); 8635 if ((defined &do_cmd_footnotename)||$new_command{'footnotename'}) { 8636 local($br_id)=++$global{'max_id'}; 8637 $title = &translate_environments("$O$br_id$C\\footnotename$O$br_id$C"); 8638 } else { 8639 $foot_title = "Footnotes" unless $foot_title; 8640 $title = $foot_title; 8641 } 8642 print "\nDoing footnotes ..."; 8643#JCL(jcl-tcl) 8644# If the footnotes go into a separate file: see &make_file. 8645 if ($footfile) { 8646 $toc_sec_title = $title; 8647 &make_file($footfile, $title, $FOOT_COLOR); # Modifies $_; 8648 $_ = ""; 8649 } else { 8650 $footnotes = ""; # else they get re-used 8651 $_ = join ('', '<BR><HR><H4>', $title, '</H4>', $_ ); 8652 } 8653 $_; 8654} 8655 8656sub post_process_footnotes { 8657 &slurp_input($footfile); 8658 open(OUT, ">$footfile") || die "Cannot write file '$footfile': $!\n"; 8659 &replace_markers; 8660 &post_post_process if (defined &post_post_process); 8661 &adjust_encoding; 8662 print OUT $_; 8663 close OUT; 8664} 8665 8666sub make_file { 8667 # Uses and modifies $_ defined in the caller 8668 local($filename, $title, $layout) = @_; 8669 $layout = $BODYTEXT unless $layout; 8670 $_ = join('',&make_head_and_body($title,$layout), $_ 8671 , (($filename =~ /^\Q$footfile\E$/) ? '' : &make_address ) 8672 , (($filename =~ /^\Q$footfile\E$/) ? "\n</BODY>\n</HTML>\n" : '') 8673 ); 8674 &replace_markers unless ($filename eq $footfile); 8675 8676 unless(open(FILE,">$filename")) { 8677 print "\nError: Cannot write '$filename': $!\n"; 8678 return; 8679 } 8680 print FILE $_; 8681 close(FILE); 8682} 8683 8684sub add_to_body { 8685 local($attrib, $value) = @_; 8686 local($body) = $BODYTEXT; 8687 if ($body =~ s/\Q$attrib\E\s*=\s*"[^"]*"/$attrib="$value"/) { 8688 } else { 8689 $body .= " $attrib=\"$value\""; $body =~ s/\s{2,}/ /g; 8690 } 8691 $BODYTEXT = $body if $body; 8692} 8693 8694sub replace_verbatim_marks { 8695 # Modifies $_ 8696 my($tmp); 8697 s/$math_verbatim_rx/&make_comment('MATH', $verbatim{$1})/eg; 8698 s/$mathend_verbatim_rx/&make_comment('MATHEND', '')/eg; 8699# s/$verbatim_mark(verbatim\*?)(\d+)#/<PRE>\n$verbatim{$2}\n<\/PRE>/go; 8700## s/$verbatim_mark(\w*[vV]erbatim\*?)(\d+)#/\n$verbatim{$2}\n/go; 8701 s!$verbatim_mark(\w*[vV]erbatim\*?|tex2html_code)(\d+)#\n?!$tmp=$verbatim{$2}; 8702 $tmp.(($tmp =~/\n\s*$/s)? '':"\n")!eg; 8703# "\n".$tmp.(($tmp =~/\n\s*$/s)? '':"\n")!eg; 8704# s/$verbatim_mark(rawhtml)(\d+)#/$verbatim{$2}/eg; # Raw HTML 8705 s/$verbatim_mark(imagesonly)(\d+)#//eg; # imagesonly is *not* replaced 8706 # Raw HTML, but replacements may have protected characters 8707 s/$verbatim_mark(rawhtml)(\d+)#/&unprotect_raw_html($verbatim{$2})/eg; 8708 s/$verbatim_mark$keepcomments_rx(\d+)#/$verbatim{$2}/ego; # Raw TeX 8709 s/$unfinished_mark$keepcomments_rx(\d+)#/$verbatim{$2}/ego; # Raw TeX 8710} 8711 8712# TeX's special characters may have been escaped with a '\'; remove it. 8713sub unprotect_raw_html { 8714 local($raw) = @_; 8715 $raw =~ s/\\($latex_specials_rx|~|\^|@)/$1/g; 8716 $raw; 8717} 8718 8719# remove file-markers; special packages may redefine &replace_file_marks 8720sub remove_file_marks { 8721 s/<(DD|LI)>\n?($file_mark|$endfile_mark)\#.*\#\n<\/\1>(\n|(<))/$4/gm; 8722 s/($file_mark|$endfile_mark)\#.*\#(\n|(<))/$3/gm; 8723} 8724sub replace_file_marks { &remove_file_marks } 8725 8726sub remove_verbatim_marks { 8727 # Modifies $_ 8728 s/($math_verbatim_rx|$mathend_verbatim_rx)//go; 8729# s/$verbatim_mark(verbatim\*?)(\d+)#//go; 8730 s/$verbatim_mark(\w*[Vv]erbatim\w*\*?)(\d+)#//go; 8731 s/$verbatim_mark(rawhtml|imagesonly)(\d+)#//go; 8732 s/$verbatim_mark$keepcomments_rx(\d+)#//go; 8733 s/$unfinished_mark$keepcomments_rx(\d+)#//go; 8734} 8735 8736sub replace_verb_marks { 8737 # Modifies $_ 8738 s/(?:$verb_mark|$verbstar_mark)(\d+)$verb_mark/ 8739 $code = $verb{$1}; 8740 $code = &replace_comments($code) if ($code =~ m:$comment_mark:); 8741 "<code>$code<\/code>"/ego; 8742} 8743 8744sub replace_comments{ 8745 local($_) = @_; 8746 $_ =~ s/$comment_mark(\d+)\n?/$verbatim{$1}/go; 8747 $_ =~ s/$comment_mark\d*\n/%\n/go; 8748 $_; 8749} 8750 8751sub remove_verb_marks { 8752 # Modifies $_ 8753 s/($verb_mark|$verbstar_mark)(\d+)$verb_mark//go; 8754} 8755 8756# This is used by revert_to_raw_tex 8757sub revert_verbatim_marks { 8758 # Modifies $_ 8759# s/$verbatim_mark(verbatim)(\d+)#/\\begin{verbatim}$verbatim{$2}\\end{verbatim}\n/go; 8760 s/$verbatim_mark(\w*[Vv]erbatim)(\d+)#/\\begin{$1}\n$verbatim{$2}\\end{$1}\n/go; 8761 s/$verbatim_mark(rawhtml)(\d+)#/\\begin{rawhtml}\n$verbatim{$2}\\end{rawhtml}\n/go; 8762 s/$verbatim_mark(imagesonly|tex2html_code)(\d+)#\n?/$verbatim{$2}/go; 8763 s/$verbatim_mark$image_env_rx(\d+)#/\\begin{$1}\n$verbatim{$2}\\end{$1}\n/go; 8764 s/($math_verbatim_rx|$mathend_verbatim_rx)//go; 8765} 8766 8767sub revert_verb_marks { 8768 # Modifies $_ 8769 s/$verbstar_mark(\d+)$verb_mark/\\verb*$verb_delim{$1}$verb{$1}$verb_delim{$1}/go; 8770 s/$verb_mark(\d+)$verb_mark/\\verb$verb_delim{$1}$verb{$1}$verb_delim{$1}/go; 8771} 8772 8773sub replace_cross_ref_marks { 8774 # Modifies $_ 8775 local($label,$id,$ref_label,$ref_mark,$after,$name); 8776 local($invis) = "<tex2html_anchor_invisible_mark></A>"; 8777# s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark/ 8778 s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark<\/A>(\s*<A( NAME=\"\d+)\">$invis)?/ 8779 do {($label,$id) = ($1,$2); $name = $4; 8780 $ref_label = $external_labels{$label} unless 8781 ($ref_label = $ref_files{$label}); 8782 print "\nXLINK<: $label : $id :$name " if ($VERBOSITY > 3); 8783 $ref_label = '' if ($ref_label eq $CURRENT_FILE); 8784 $ref_mark = &get_ref_mark($label,$id); 8785 &extend_ref if ($name); $name = ''; 8786 print "\nXLINK: $label : $ref_label : $ref_mark " if ($VERBOSITY > 3); 8787 '"' . "$ref_label#$label" . "\">" . $ref_mark . "<\/A>" 8788 }/geo; 8789 8790 # This is for pagerefs which cannot have symbolic labels ??? 8791# s/$cross_ref_mark#(\w+)#\w+>/ 8792 s/$cross_ref_mark#([^#]+)#[^>]+>/ 8793 do {$label = $1; 8794 $ref_label = $external_labels{$label} unless 8795 ($ref_label = $ref_files{$label}); 8796 $ref_label = '' if ($ref_label eq $CURRENT_FILE); 8797 print "\nXLINKP: $label : $ref_label" if ($VERBOSITY > 3); 8798 '"' . "$ref_files{$label}#$label" . "\">" 8799 }/geo; 8800} 8801 8802#RRM: this simply absorbs the name from the invisible anchor following, 8803# when the anchor itself is not already named. 8804sub extend_ref { 8805 if ($ref_label !=~ /NAME=/) { $label .= "\"\n".$name } 8806} 8807 8808sub remove_cross_ref_marks { 8809 # Modifies $_ 8810# s/$cross_ref_mark#(\w+)#(\w+)>$cross_ref_mark/ 8811 s/$cross_ref_mark#([^#]+)#([^>]+)>$cross_ref_mark/ 8812 print "\nLOST XREF: $1 : $2" if ($VERBOSITY > 3);''/ego; 8813# s/$cross_ref_mark#(\w+)#\w+>//go; 8814 s/$cross_ref_mark#([^#]+)#[^#>]+>//go; 8815} 8816 8817sub replace_external_ref_marks { 8818 # Modifies $_ 8819 local($label, $link); 8820# s/$external_ref_mark#(\w+)#(\w+)>$external_ref_mark/ 8821 s/$external_ref_mark#([^#]+)#([^>]+)>$external_ref_mark/ 8822 do {($label,$id) = ($1,$2); 8823 $link = $external_labels{$label}; 8824 print "\nLINK: $label : $link" if ($VERBOSITY > 3); 8825 '"'. "$link#$label" . "\">\n" 8826 . &get_ref_mark("userdefined$label",$id) 8827 } 8828 /geo; 8829} 8830 8831sub remove_external_ref_marks { 8832 # Modifies $_ 8833# s/$external_ref_mark#(\w+)#(\w+)>$external_ref_mark/ 8834 s/$external_ref_mark#([^#]+)#([^>]+)>$external_ref_mark/ 8835 print "\nLOST LINK: $1 : $2" if ($VERBOSITY > 3);''/ego; 8836} 8837 8838sub get_ref_mark { 8839 local($label,$id) = @_; 8840 ( ( $SHOW_SECTION_NUMBERS && $symbolic_labels{"$label$id"}) || 8841 $latex_labels{"userdefined$label$id"} || 8842 $symbolic_labels{"$label$id"} || 8843 $latex_labels{$label} || 8844 $external_latex_labels{$label} || 8845 $cross_ref_visible_mark ); 8846} 8847 8848sub replace_bbl_marks { 8849 # Modifies $_ 8850 s/$bbl_mark#([^#]+)#/$citations{$1}/go; 8851} 8852 8853sub remove_bbl_marks { 8854 # Modifies $_ 8855 s/$bbl_mark#([^#]+)#//go; 8856} 8857 8858sub replace_image_marks { 8859 # Modifies $_ 8860 s/$image_mark#([^#]+)#([\.,;:\)\]])?(\001)?([ \t]*\n?)(\001)?/ 8861 "$id_map{$1}$2$4"/ego; 8862# "$id_map{$1}$2".(($4)?"\n":'')/ego; 8863} 8864 8865sub remove_image_marks { 8866 # Modifies $_ 8867 s/$image_mark#([^#]+)#//go; 8868} 8869 8870sub replace_icon_marks { 8871 # Modifies $_ 8872 if ($HTML_VERSION < 2.2 ) { 8873 local($icon); 8874 s/$icon_mark_rx/$icon = &img_tag($1); 8875 $icon =~ s| BORDER="?\d+"?||;$icon/ego; 8876 } else { 8877 s/$icon_mark_rx/&img_tag($1)/ego; 8878 } 8879} 8880 8881sub remove_icon_marks { 8882 # Modifies $_ 8883 s/$icon_mark_rx//go; 8884} 8885 8886sub replace_cite_marks { 8887 local($key,$label,$text,$file); 8888 # Modifies $_ 8889 # Uses $citefile set by the thebibliography environment 8890 local($citefile) = $citefile; 8891 $citefile =~ s/\#.*$//; 8892 8893 s/#([^#]+)#$cite_mark#([^#]+)#((($OP\d+$CP)|[^#])*)#$cite_mark#/ 8894 $text = $3; $label= $1; $file=''; 8895 $text = $cite_info{$1} unless $text; 8896 if ($checking_caption){ 8897 "$label" 8898 } elsif ($citefiles{$2}){ 8899 $file = $citefiles{$2}; $file =~ s:\#.*$::; 8900 &make_named_href('', "$file#$label","$text"); 8901 } elsif ($PREAMBLE) { 8902 $text || "\#!$1!\#" ; 8903 } elsif ($simplifying) { 8904 $text 8905 } else { 8906 &write_warnings("\nno reference for citation: $1"); 8907 "\#!$1!\#" 8908 }/sge ; 8909 # 8910 #RRM: Associate the cite_key with $citefile , for use by other segments. 8911 if ($citefile) { 8912 local($cite_key, $cite_ref); 8913 while (($cite_key, $cite_ref) = each %cite_info) { 8914 if ($ref_files{'cite_'."$cite_key"} ne $citefile) { 8915 $ref_files{'cite_'."$cite_key"} = $citefile; 8916 $changed = 1; } 8917 } 8918 } 8919} 8920 8921sub remove_cite_marks { 8922 # Modifies $_ 8923 s/#([^#]+)#$cite_mark#([^#]+)#([^#]*)#$cite_mark#//go; 8924} 8925 8926sub remove_anchors { 8927# modifies $_ 8928 s/<A[^>]*>//g; 8929 s/<\/A>//g; 8930} 8931 8932 8933# We need two matching keys to determine section/figure/etc. numbers. 8934# The "keys" are the name of the section/figure/etc. and its 8935# equivalent in the .aux file (also carrying the number we desire). 8936# But both keys might have been translated slightly different, 8937# depending on the usage of math, labels, special characters such 8938# as umlauts, or simply spacing! 8939# 8940# This routine tries to squeeze the HTML translated keys such 8941# that they match (hopefully very often). -- JCL 8942# 8943sub sanitize { 8944 local($_,$mode) = @_; 8945 &remove_markers; 8946 &remove_anchors; 8947 &text_cleanup; 8948 s/(\&|;SPM)nbsp;//g; # HWS - LaTeX changes ~ in its .aux files 8949 #strip unwanted HTML constructs 8950 s/<\/?(P|BR|H)[^>]*>//g; 8951 s/\s+//g; #collapse white space 8952 $_; 8953} 8954 8955# This one removes any HTML markup, so that pure 8956# plain text remains. (perhaps with <SUP>/<SUB> tags) 8957# As the result will be part of the HTML file, it will be 8958# &text_cleanup'd later together with its context. 8959# 8960sub purify { 8961 local($_,$strict) = @_; 8962 &remove_markers; 8963 #strip unwanted HTML constructs 8964# s/<[^>]*>/ /g; 8965 s/<(\/?SU[BP])>/>$1>/g unless ($strict); # keep sup/subscripts ... 8966 s/<[^>]*>//g; # remove all other tags 8967 s/>(\/?SU[BP])>/<$1>/g unless ($strict); # ...reinsert them 8968 s/^\s+|\001//g; s/\s\s+/ /g; #collapse white space 8969 $_; 8970} 8971 8972# This one is not as strict as &sanitize. 8973# It is chosen to strip section names etc. a bit from 8974# constructs so that it better fits a table of contents, 8975# label files, etc. 8976# As the result will be part of the HTML file, it will be 8977# &text_cleanup'd later together with its context. 8978# 8979sub simplify { 8980 local($_) = @_; 8981 local($simplifying) = 1; 8982 s/$tex2html_envs_rx//g; 8983 if (/\\/) { 8984 local($USING_STYLES) = 0; 8985 $_ = &translate_commands($_); 8986 undef $USING_STYLES; 8987 } 8988 &replace_external_ref_marks if /$external_ref_mark/; 8989 &replace_cross_ref_marks if /$cross_ref_mark||$cross_ref_visible_mark/; 8990 &replace_cite_marks if /$cite_mark/; 8991 # strip unwanted HTML constructs 8992# s/<\/?H[^>]*>/ /g; 8993 s/<\/?(H)[^>]*>//g; 8994 s/<\#\d+\#>//g; 8995 s/^\s+//; 8996 $_; 8997} 8998 8999#RRM: This extracts $anchor_mark portions from a given chunk of text, 9000# so they can be positioned separately by the calling subroutine. 9001# added for v97.2: 9002# search within the immediately following text also; so that 9003# \index and \label after section-headings work as expected. 9004# 9005sub extract_anchors { 9006 local($search_text, $start_only) = @_; 9007 local($anchors) = ''; 9008 local($untranslated_anchors) = ''; 9009 9010 do { 9011 while ($search_text =~ s/<A[^>]*>($anchor_mark|$anchor_invisible_mark)<\/A>//) { 9012 $anchors .= $&; 9013 } 9014 } unless ($start_only); 9015 9016 $search_text =~ s/\s*(\\protect)?\\(label|index|markright|markboth\s*(($O|$OP)\d+($C|$CP))[^<]*\3)\s*(($O|$OP)\d+($C|$CP))[^<]*\6/ 9017 $anchors .= $&;''/eg unless ($start_only); 9018 9019 while ( s/^\s*<A[^>]*>($anchor_mark|$anchor_invisible_mark)<\/A>//m) { 9020 $untranslated_anchors .= $&; 9021 } 9022 while ( s/^\s*(\\protect)?\\(label|index|markright|markboth\s*(($O|$OP)\d+($C|$CP))[^<]*\3)\s*(($O|$OP)\d+($C|$CP))[^<]*\6//) { 9023 $untranslated_anchors .= $&; 9024 } 9025 if ($TITLE||$start_only) { 9026 $anchors .= &translate_commands($untranslated_anchors); 9027 $untranslated_anchors = ''; 9028 } 9029 ($anchors.$untranslated_anchors,$search_text); 9030} 9031 9032# This routine must be called once on the text only, 9033# else it will "eat up" sensitive constructs. 9034sub text_cleanup { 9035 # MRO: replaced $* with /m 9036 s/(\s*\n){3,}/\n\n/gom; # Replace consecutive blank lines with one 9037 s/<(\/?)P>\s*(\w)/<$1P>\n$2/gom; # clean up paragraph starts and ends 9038 s/$O\d+$C//go; # Get rid of bracket id's 9039 s/$OP\d+$CP//go; # Get rid of processed bracket id's 9040 s/(<!)?--?(>)?/(length($1) || length($2)) ? "$1--$2" : "-"/ge; 9041 # Spacing commands 9042 s/\\( |$)/ /go; 9043 #JKR: There should be no more comments in the source now. 9044 #s/([^\\]?)%/$1/go; # Remove the comment character 9045 # Cannot treat \, as a command because , is a delimiter ... 9046 s/\\,/ /go; 9047 # Replace tilde's with non-breaking spaces 9048 s/ *~/ /g; 9049 9050 ### DANGEROUS ?? ### 9051 # remove redundant (not <P></P>) empty tags, incl. with attributes 9052 s/\n?<([^PD >][^>]*)>\s*<\/\1>//g; 9053 s/\n?<([^PD >][^>]*)>\s*<\/\1>//g; 9054 # remove redundant empty tags (not </P><P> or <TD> or <TH>) 9055 s/<\/(TT|[^PTH][A-Z]+)><\1>//g; 9056 s/<([^PD ]+)(\s[^>]*)?>\n*<\/\1>//g; 9057 9058 9059#JCL(jcl-hex) 9060# Replace ^^ special chars (according to p.47 of the TeX book) 9061# Useful when coming from the .aux file (german umlauts, etc.) 9062 s/\^\^([^0-9a-f])/chr((64+ord($1))&127)/ge; 9063 s/\^\^([0-9a-f][0-9a-f])/chr(hex($1))/ge; 9064} 9065 9066# This is useful for getting words from a title which are not cluttered 9067# with tex2html markers or HTML constructs 9068sub extract_pure_text { 9069 local($mode) = @_; 9070 &text_cleanup; # Remove marking brackets 9071# 9072# HWS <hswan@perc.Arco.com>: Conditionally doing the following 9073# permits equations in section headings. 9074# 9075 if ($mode eq "strict") { 9076 s/$image_mark#[^#]*#//g; # Remove image marker 9077 s/$bbl_mark#[^#]*#//g; # Remove citations marker 9078 s/<tex2html_percent_mark>/%/g; # BMcM: Retain % signs... 9079 s/<tex2html_ampersand_mark>/\&/g; 9080 s/tex2html[\w\d]*//g; # Remove other markers 9081 } 9082 9083# 9084# HWS <hswan@perc.Arco.com>: Replace next statement with the following two 9085# to permit symbolic links and images to appear in section headings. 9086 9087# s/<[^>]*>//go; # Remove HTML constructs 9088 s/$OP[^#]*$CP//go; # Remove <# * #> constructs 9089 s/<\s*>//go; # Remove embedded whitespace 9090} 9091 9092############################ Misc #################################### 9093 9094# MRO: Print standardized header 9095sub banner { 9096 print <<"EOF"; 9097This is LaTeX2HTML Version $TEX2HTMLVERSION 9098by Nikos Drakos, Computer Based Learning Unit, University of Leeds. 9099 9100EOF 9101} 9102 9103# MRO: Extract usage information from POD 9104sub usage { 9105 my $start = 0; 9106 my $usage = 'Usage: '; 9107 my $indent = ''; 9108 9109 print (@_, "\n") if @_; 9110 9111 my $perldoc = "/usr/bin${dd}perldoc"; 9112 my $script = $SCRIPT || $0; 9113 open(PIPE, "$perldoc -t $script |") 9114 || die "Fatal: can't open pipe: $!"; 9115 while (<PIPE>) { 9116 if (/^\s*$/) { 9117 next; 9118 } elsif (/^SYNOPSIS/) { 9119 $start = 1; 9120 } elsif (/^\w/) { 9121 $start = 0; 9122 } elsif ($start == 1) { 9123 ($indent) = /^(\s*)/; 9124 s/^$indent/$usage/; 9125 $usage =~ s/./ /g; 9126 $start = 2; 9127 print $_; 9128 } elsif ($start == 2) { 9129 s/^$indent/$usage/; 9130 print $_; 9131 } 9132 } 9133 close PIPE; 9134 1; 9135} 9136 9137# The bibliographic references, the appendices, the lists of figures and tables 9138# etc. must appear in the contents table at the same level as the outermost 9139# sectioning command. This subroutine finds what is the outermost level and 9140# sets the above to the same level; 9141sub set_depth_levels { 9142 # Sets $outermost_level 9143 local($level); 9144 # scan the document body, not the preamble, for use of sectioning commands 9145 my ($contents) = $_; 9146 if ($contents =~ /\\begin\s*((?:$O|$OP)\d+(?:$C|$CP))document\1|\\startdocument/s) { 9147 $contents = $'; 9148 } 9149 #RRM: do not alter user-set value for $MAX_SPLIT_DEPTH 9150 foreach $level ("part", "chapter", "section", "subsection", 9151 "subsubsection", "paragraph") { 9152 last if (($outermost_level) = $contents =~ /\\($level)$delimiter_rx/); 9153 last if (($outermost_level) = $contents =~ /\\endsegment\s*\[\s*($level)\s*\]/s); 9154 if ($contents =~ /\\segment\s*($O\d+$C)[^<]+\1\s*($O\d+$C)\s*($level)\s*\2/s) 9155 { $outermost_level = $3; last }; 9156 } 9157 $level = ($outermost_level ? $section_commands{$outermost_level} : 9158 do {$outermost_level = 'section'; 3;}); 9159 9160 #RRM: but calculate value for $MAX_SPLIT_DEPTH when a $REL_DEPTH was given 9161 if ($REL_DEPTH && $MAX_SPLIT_DEPTH) { 9162 $MAX_SPLIT_DEPTH = $level + $MAX_SPLIT_DEPTH; 9163 } elsif (!($MAX_SPLIT_DEPTH)) { $MAX_SPLIT_DEPTH = 1 }; 9164 9165 %unnumbered_section_commands = ( 9166 'tableofcontents', $level 9167 , 'listoffigures', $level 9168 , 'listoftables', $level 9169 , 'bibliography', $level 9170 , 'textohtmlindex', $level 9171 , 'a', $level 9172 , %unnumbered_section_commands 9173 ); 9174 9175 %section_commands = ( 9176 %unnumbered_section_commands 9177 , %section_commands 9178 ); 9179} 9180 9181# Now ignores accents which cannot be translated to ISO-LATIN-1 characters 9182# Also replaces ?' and !' .... 9183sub replace_strange_accents { 9184 &real_replace_strange_accents(@_); # if ($CHARSET =~ /8859[_\-]1$/); 9185} 9186sub real_replace_strange_accents { 9187 # Modifies $_; 9188 s/\?`/&iso_map("iquest", "")/geo; 9189 s/!`/&iso_map("iexcl", "")/geo; 9190 s/\\\^\\i /&iso_map("icirc", "")/geo; 9191 my ($charset) = "${CHARSET}_character_map_inv"; 9192 $charset =~ s/-/_/g; 9193 # convert upper 8-bit characters 9194 if (%$charset &&($CHARSET =~ /8859[_\-]1$/)) { 9195 s/([\200-\377])/ 9196 $tmp = $$charset{'&#'.ord($1).';'}; 9197 &mark_string($tmp) if ($tmp =~ m!\{!); 9198 &translate_commands($tmp) 9199 /egos 9200 } 9201}; 9202 9203# Creates a new directory or reuses old, perhaps after deleting its contents 9204sub new_dir { 9205 local($this_dir,$mode) = @_; 9206 local(@files)=(); 9207 $this_dir = '.' unless $this_dir; 9208 $this_dir =~ s/[$dd$dd]+$//o; 9209 local($print_dir) = $this_dir.$dd; 9210 (!$mode && mkdir($this_dir, 0755)) || 9211 do { 9212 print "\nCannot create directory $print_dir: $!" unless ($mode); 9213 if ($REUSE) { 9214 print ", reusing it.\n" unless ($mode); 9215 &reuse($this_dir,$print_dir); 9216 } else { 9217 print "\n" unless ($mode); 9218 while (! ($answer =~ /^[dqr]$/)) { 9219 if ($mode) { 9220 $answer = $mode; 9221 } else { 9222 print "(r) Reuse the images in the old directory OR\n" 9223 . (($this_dir eq '.') ? 9224 "(d) *** DELETE *** the images in $print_dir OR\n" 9225 : "(d) *** DELETE *** THE CONTENTS OF $print_dir OR\n" ) 9226 . "(q) Quit ?\n:"; 9227 $answer = scalar(<STDIN>); 9228 }; 9229 if ($answer =~ /^d$/) { 9230 @files = (); 9231 if(opendir(DIR,$this_dir)) { 9232 @files = readdir DIR; 9233 closedir DIR; 9234 } else { 9235 print "\nError: Cannot read dir '$this_dir': $!\n"; 9236 } 9237 foreach (@files) { 9238 next if /^\.+$/; 9239 if (-d "$this_dir$dd$_") { 9240 &new_dir("$this_dir$dd$_",'d'); 9241 } elsif ($this_dir eq '.') { 9242 L2hos->Unlink($_) if (/\.(pl|gif|png)$/) 9243 } else { 9244 L2hos->Unlink("$this_dir$dd$_"); 9245 }; 9246 } 9247 return(1) if ($this_dir eq '.'); 9248 if($mode) { 9249 rmdir($this_dir); 9250 rmdir($print_dir); 9251 } 9252 if (!$mode) { &new_dir($this_dir,'r')}; 9253 return(1); 9254 } elsif ($answer =~ /^q$/) { 9255 die "Bye!\n"; 9256 } elsif ($answer =~ /^r$/) { 9257 &reuse($this_dir,$print_dir); 9258 return(1); 9259 } else {print "Please answer r d or q!\n";}; 9260 } 9261 }; 9262 }; 9263 1; 9264} 9265 9266sub reuse { 9267 local($this_dir,$print_dir) = @_; 9268 $print_dir = $this_dir.$dd unless ($print_dir); 9269 if (-f "$this_dir$dd${PREFIX}images.pl") { 9270 print STDOUT "Reusing directory $print_dir:\n"; 9271 local($key); 9272 require("$this_dir$dd${PREFIX}images.pl"); 9273 } 9274} 9275 9276 9277# JCL(jcl-del) - use $CD rather than a space as delimiter. 9278# The commands might take white space, or not, depending on 9279# their definition. Eg. \relax takes white space, because it's a 9280# letter command, but \/ won't. 9281# TeX seems to have an internal separator: If \x is " x", 9282# and \y is "y", then \expandafter\y \x expands to "y x", TeX 9283# hasn't gobbled the space, meaning that spaces are gobbled once 9284# when the \y token is consumed, but then never again after \y. 9285# 9286# The actions below ensure to insert exactly one space after 9287# the command name. # what happens to `\ ' ? 9288# The substition is done twice to handle \one\delimits\another 9289# cases. 9290# The internal shortcut $CD is then turned into the single 9291# space we desire. 9292# 9293sub tokenize { 9294 # Modifies $_; 9295 local($rx) = @_; 9296 # $rx must be specially constructed, see &make_new_cmd_rx. 9297 if (length($rx)) { 9298 # $1: non-letter cmd, or $2: letter cmd 9299 s/$rx/\\$1$2$CD$4/g; 9300 s/$rx/\\$1$2$CD$4/g; 9301 s/$CD+/ /g; # puts space after each command name 9302 } 9303} 9304 9305# When part of the input text contains special perl characters and the text 9306# is to be used as a pattern then these specials must be escaped. 9307sub escape_rx_chars { 9308 my($rx) = @_; # must use a copy of the string 9309 $rx =~ s:([\\(){}[\]\^\$*+?.|]):\\$1:g; $rx; } 9310 9311# Does not do much but may need it later ... 9312# The document environment has to be removed because it spans 9313# more than one sections (the translator can only deal with 9314# environments wholly contained with sections). 9315 9316# (Does a little more now ... the end of the preamble is now marked 9317# with an internally-generated command which causes all output 9318# erroneously generated from unrecognized commands in the preamble 9319# to vanish --- rst). 9320 9321sub remove_document_env { 9322# s/\\begin$match_br_rx[d]ocument$match_br_rx/\\latextohtmlditchpreceding /o; 9323 if (/\\begin\s*${match_br_rx}document$match_br_rx/) { 9324 s/\\begin\s*$match_br_rx[d]ocument$match_br_rx/\\latextohtmlditchpreceding / 9325 } 9326# s/\\end$match_br_rx[d]ocument$match_br_rx(.|\n)*//o; 9327 if (/\\end\s*${match_br_rx}document$match_br_rx/) { $_ = $` } 9328} 9329 9330# And here's the code to handle the marker ... 9331 9332sub do_cmd_latextohtmlditchpreceding { 9333 local($_) = @_; 9334 $ref_before = ''; 9335 $_; 9336} 9337 9338print "\n"; # flushes a cache? This helps, for some unknown reason!! 9339 9340sub do_AtBeginDocument{ 9341 local($_) = @_; 9342 eval $AtBeginDocument_hook; 9343 $_; 9344} 9345 9346sub cleanup { 9347 local($explicit) = @_; 9348 return unless $explicit || !$DEBUG; 9349 9350 if (opendir(DIR, '.')) { 9351 while (defined($_ = readdir(DIR))) { 9352 L2hos->Unlink($_) 9353 if /\.ppm$/ || /^${PREFIX}images\.dvi$/ || /^(TMP[-._]|$$\_(image)?)/; 9354 } 9355 closedir (DIR); 9356 } 9357 9358 L2hos->Unlink("WARNINGS") if ($explicit &&(-f "WARNINGS")); 9359 9360 if ($TMPDIR && opendir(DIR, $TMPDIR)) { 9361 local(@files) = grep(!/^\.\.?$/,readdir(DIR)); 9362 local($busy); 9363 foreach (@files) { 9364 $busy .= $_." " unless (L2hos->Unlink("$TMPDIR$dd$_")); 9365 } 9366 closedir (DIR); 9367 if ($busy) { 9368 print "\n\nFiles: $busy are still in use.\n\n" if ($DEBUG); 9369 } else { 9370 &write_warnings("\n\n Couldn't remove $TMPDIR : $!") 9371 unless (rmdir $TMPDIR); 9372 } 9373 } 9374 if (opendir(DIR, $TMP_)) { 9375 local(@files) = grep(!/^\.\.?$/,readdir(DIR)); 9376 $busy = ''; 9377 foreach (@files) { 9378 $busy .= "$_ " unless (L2hos->Unlink("$TMP_$dd$_")); 9379 } 9380 closedir (DIR); 9381 local($full_dir) = L2hos->Make_directory_absolute($TMP_); 9382 if ($busy) { 9383 print "\n\nFiles: $busy in $full_dir are still in use.\n\n" 9384 if ($DEBUG); 9385 } else { 9386 &write_warnings("\n\nCouldn't remove directory '$full_dir': $!") 9387 unless (rmdir $full_dir); 9388 } 9389 } 9390} 9391 9392sub handler { 9393 print "\nLaTeX2HTML shutting down.\n"; 9394 kill ('INT', $child_pid) if ($child_pid); 9395 &close_dbm_database; 9396 &cleanup(); 9397 exit(-1); 9398} 9399 9400# Given a filename or a directory it returns the file and the full pathname 9401# relative to the current directory. 9402sub get_full_path { 9403 local($file) = @_; 9404 local($path,$dir); 9405 if (-d $file) { # $file is a directory 9406 $path = L2hos->Make_directory_absolute($file); 9407 $file = ''; 9408 9409# JCL(jcl-dir) 9410 } elsif ($file =~ s|\Q$dd\E([^$dd$dd]*)$||o ) { 9411 $path = $file; 9412 $file = $1; 9413 $path = L2hos->Make_directory_absolute($path); 9414 9415#RRM: check within $TEXINPUTS directories 9416 } elsif (!($TEXINPUTS =~ /^\.$envkey$/)) { 9417 #check along directories in the $TEXINPUTS variable 9418 foreach $dir (split(/$envkey/,$TEXINPUTS)) { 9419 $dir =~ s/[$dd$dd]$//o; 9420 if (-f $dir.$dd.$file) { 9421 $path = L2hos->Make_directory_absolute($dir); 9422 last; 9423 } 9424 } 9425 } else { 9426 $path = L2hos->Cwd(); 9427 } 9428 ($path, $file); 9429} 9430 9431 9432# Given a directory name in either relative or absolute form, returns 9433# the absolute form. 9434# Note: The argument *must* be a directory name. 9435# The whole function has been moved to override.pm 9436 9437 9438 9439# Given a relative filename from the directory in which the original 9440# latex document lives, it tries to expand it to the full pathname. 9441sub fulltexpath { 9442 # Uses $texfilepath defined in sub driver 9443 local($file) = @_; 9444 $file =~ s/\s//g; 9445 $file = "$texfilepath$dd$file" 9446 unless (L2hos->is_absolute_path($file)); 9447 $file; 9448} 9449 9450#RRM Extended to allow customised filenames, set $CUSTOM_TITLES 9451# or long title from the section-name, set $LONG_TITLES 9452# 9453sub make_name { 9454 local($sec_name, $packed_curr_sec_id) = @_; 9455 local($title,$making_name,$saved) = ('',1,''); 9456 if ($LONG_TITLES) { 9457 $saved = $_; 9458 &process_command($sections_rx, $_) if /^$sections_rx/; 9459 $title = &make_long_title($TITLE) 9460 unless ((! $TITLE) || ($TITLE eq $default_title)); 9461 $_ = $saved; 9462 } elsif ($CUSTOM_TITLES) { 9463 $saved = $_; 9464 &process_command($sections_rx, $_) if /^$sections_rx/; 9465 $title = &custom_title_hook($TITLE) 9466 unless ((! $TITLE) || ($TITLE eq $default_title)); 9467 $_ = $saved; 9468 } 9469 if ($title) { 9470 #ensure no more than 32 characters, including .html extension 9471 $title =~ s/^(.{1,27}).*$/$1/; 9472 ++$OUT_NODE; 9473 join("", ${PREFIX}, $title, $EXTN); 9474 } else { 9475 # Remove 0's from the end of $packed_curr_sec_id 9476 $packed_curr_sec_id =~ s/(_0)*$//; 9477 $packed_curr_sec_id =~ s/^\d+$//o; # Top level file 9478 join("",($packed_curr_sec_id ? 9479 "${PREFIX}$NODE_NAME". ++$OUT_NODE : $sec_name), $EXTN); 9480 } 9481} 9482 9483#RRM: redefine this subroutine, to create customised file-names 9484# based upon the actual section title. 9485# The default is empty, so reverts to: node1, node2, ... 9486# 9487sub custom_title_hook { 9488 local($_)= @_; 9489 ""; 9490} 9491 9492 9493sub make_long_title { 9494 local($_)= @_; 9495 local($num_words) = $LONG_TITLES; 9496 #RRM: scan twice for short words, due to the $4 overlap 9497 # Cannot use \b , else words break at accented letters 9498 $_ =~ s/(^|\s)\s*($GENERIC_WORDS)(\'|(\s))/$4/ig; 9499 $_ =~ s/(^|\s)\s*($GENERIC_WORDS)(\'|(\s))/$4/ig; 9500 #remove leading numbering, unless that's all there is. 9501 local($sec_num); 9502 if (!(/^\d+(\.\d*)*\s*$/)&&(s/^\s*(\d+(\.\d*)*)\s*/$sec_num=$1;''/e)) 9503 { $num_words-- }; 9504 &remove_markers; s/<[^>]*>//g; #remove tags 9505 #revert entities, etc. to TeX-form... 9506 s/([\200-\377])/"\&#".ord($1).";"/eg; 9507 $_ = &revert_to_raw_tex($_); 9508 9509 # get $LONG_TITLES number of words from what remains 9510 $_ = &get_first_words($_, $num_words) if ($num_words); 9511 # ...and cleanup accents, spaces and punctuation 9512 $_ = join('', ($SHOW_SECTION_NUMBERS ? $sec_num : ''), $_); 9513 s/\\\W\{?|\}//g; s/\s/_/g; s/\W/_/g; s/__+/_/g; s/_+$//; 9514 $_; 9515} 9516 9517 9518sub make_first_key { 9519 local($_); 9520 $_ = ('0 ' x keys %section_commands); 9521 s/^0/$THIS_FILE/ if ($MULTIPLE_FILES); 9522 chop; 9523 $_; 9524} 9525 9526# This copies the preamble into the variable $preamble. 9527# It also sets the LaTeX font size, if $FONT_SIZE is set. 9528sub add_preamble_head { 9529 $preamble = join("\n", $preamble, @preamble); 9530 $preamble = &revert_to_raw_tex($preamble); 9531 $preamble = join ("\n", &revert_to_raw_tex(/$preamble_rx/o), 9532 $preamble); 9533 local($savedRS) = $/; undef $/; 9534 # MRO: replaced $* with /m 9535 $preamble =~ /(\\document(style|class))\s*(\[[^]]*\])?\s*\{/sm; 9536 local($before,$after) = ($`.$1, '{'.$'); 9537 $/ = $savedRS; 9538 local ($options) = $3; 9539 if ($FONT_SIZE) { 9540 $options =~ s/(1\dpt)\b//; 9541 $options =~ s/(\[|\])//g; 9542 $options = "[$FONT_SIZE".($options ? ",$options" : '').']'; 9543 $preamble = join('', $before, $options, $after ); 9544 &write_mydb_simple("preamble", $preamble); 9545 @preamble = split(/\n/, $preamble); 9546 $LATEX_FONT_SIZE = $FONT_SIZE; 9547 } 9548 if (($options =~ /(1\dpt)\b/)&&(!$LATEX_FONT_SIZE)) { 9549 $LATEX_FONT_SIZE = $1; 9550 } 9551 #RRM: need to know the font-size before the .aux file is read 9552 $LATEX_FONT_SIZE = '10pt' unless ($LATEX_FONT_SIZE); 9553} 9554 9555# It is necessary to filter some parts of the document back to raw 9556# tex before passing them to latex for processing. 9557sub revert_to_raw_tex { 9558 local($_) = @_; 9559 local($character_map) = ""; 9560 if ( $CHARSET && $HTML_VERSION ge "2.1" ) { 9561 $character_map = $CHARSET; 9562 $character_map =~ tr/-/_/; } 9563 while (s/$O\s*\d+\s*$C/\{/o) { s/$&/\}/;} 9564 while (s/$O\s*\d+\s*$C/\{/o) { s/$&/\}/;} #repeat this. 9565 # The same for processed markers ... 9566 while ( s/$OP\s*\d+\s*$CP/\{/o ) { s/$&/\}/; } 9567 while ( s/$OP\s*\d+\s*$CP/\{/o ) { s/$&/\}/;} #repeat this. 9568 9569 s/<BR>/\\\\/g; # restores the \\ from \parbox's 9570 9571 # revert any math-entities 9572 s/\&\w+#(\w+);/\\$1/g; 9573 s/\&limits;/\\limits/g; 9574 s/\\underscore/\\_/g; 9575 s/\\circflex/\\^/g; 9576 s/\\space/\\ /g; 9577 s/;SPMthinsp;/\\,/g; 9578 s/;SPMnegsp;/\\!/g; 9579 s/;SPMsp;/\\:/g; 9580 s/;SPMthicksp;/\\;/g; 9581 s/;SPMgg;/\\gg /g; 9582 s/;SPMll;/\\ll /g; 9583 s/;SPMquot;/"/g; 9584 9585 # revert any super/sub-scripts 9586 s/<SUP>/\^\{/g; 9587 s/<SUB>/\_\{/g; 9588 s/<\/SU(B|P)>/\}/g; 9589 9590 9591# #revert common character entities ?? 9592# s/\/\\/g; 9593 9594# # revert special marks 9595# s/$percent_mark/\\%/go; 9596## s/$comment_mark(\d+)\n/%$comments{$1}\n/go; 9597 local($tmp,$tmp2); 9598# s/$comment_mark(\d+)\n/$tmp=$verbatim{$1};chomp($tmp);$tmp."\n"/ego; 9599 s/$comment_mark(\d+)(\n|$|(\$))/$tmp=$verbatim{$1};$tmp2 = $3; 9600 ($tmp=~m!^\%!s ? '':'%').$tmp.(($tmp=~ m!\n\s*$!s)?'':"\n").$tmp2/sego; 9601 s/${verbatim_mark}tex2html_code(\d+)\#/$verbatim{$1}/go; 9602 s/^($file_mark|$endfile_mark).*\#\n//gmo; 9603 s/$comment_mark(\d*)\s*\n/%\n/go; 9604 s/$dol_mark/\$/go; 9605 s/$caption_mark//go; 9606 9607 # From &pre_process. 9608 # MRO: replaced $* with /m 9609 s/\\\\[ \t]*(\n)?/\\\\$1/gm; 9610 9611 # revert any array-cell delimiters 9612 s/$array_col_mark/\&/g; 9613 s/$array_row_mark/\\\\/g; 9614 s/$array_text_mark/\\text/g; 9615 s/$array_mbox_mark/\\mbox/g; 9616 9617 # Replace any verbatim and image markers ... 9618 &revert_verbatim_marks; 9619 &revert_verb_marks; 9620 9621 9622# &replace_image_marks; 9623 s/$image_mark\#([^\#]+)\#/&recover_image_code($1)/eg; 9624 9625 # remove artificial environments and commands 9626 9627 s/(\n*)\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_b(egin)?group\3\n?/ 9628 ($1? "\n":'')."\\".($6? $2:(($2 =~ m|end|)? 'e':'b'))."group\n" 9629 /gem; 9630 s/\\(begin|end)(\{|(($O|$OP)\d+($C|$CP|\})))(tex2html|verbatim)_code(\}|\3)\n?//gm; 9631 9632 #take care not to concatenate \<cmd> with following letters 9633 local($tmp); 9634 s/(\\\w+)?$tex2html_wrap_rx([^\\\n])?/$tmp=$2; 9635 ((($tmp eq 'end')&&($1)&&!($5)&&($6))? "$1 $6":"$1$5$6")/egs; 9636 undef $tmp; 9637 s/\s*\\newedcommand\s*{/"%\n\\providecommand{\\"/gem; 9638 s/\\newedcommand\s*{/\\providecommand{\\/gom; 9639# s/(\n*)\\renewedcommand{/($1? "\n":'')."\\renewcommand{\\"/geo; 9640 s/\s*\\providedcommand\s*{/"%\n\\providecommand{\\"/gem; 9641# s/\\providedcommand{/\\providecommand{\\/go; 9642 s/\\renewedenvironment\s*/\\renewenvironment/gom; 9643 s/\\newedboolean\s*{/\\newboolean{/gom; 9644 s/\\newedcounter\s*{/\\newcounter{/gom; 9645 s/\\newedtheorem\s*{/\\newtheorem{/gom; 9646 s/\\xystar/\\xy\*/gom; # the * has a special meaning in Xy-pic 9647 9648 #fix-up the star'd environment names 9649 s/(\\(begin|end)(($O|$OP)\d+($C|$CP))[^<]*)star\3/$1\*$3/gm; 9650 s/(\\(begin|end)\{[^\}]*)star\}/$1\*\}/gm; 9651 s/\\(begin|end)\{[^\}]*begin(group)\}/\\$1$2/gm; 9652 s/\\(b|e)(egin|end)\{[^\}]*b(group)\}/\\$1$3/gm; 9653 9654 s/(\\(\w+)TeX)/($language_translations{$2}? "\\selectlanguage{$2}": $1)/egom; 9655 9656 if ($PREPROCESS_IMAGES) { 9657 while (/$pre_processor_env_rx/m) { 9658 $done .= $`; $pre_env = $5; $which =$1; $_ = $'; 9659 if (($which =~ /begin/)&&($pre_env =~ /indica/)) { 9660 ($indic, $dum) = &get_next_optional_argument; 9661 $done .= "\#$indic"; 9662 } elsif (($which =~ /begin/)&&($pre_env =~ /itrans/)) { 9663 ($indic, $dum) = &get_next_optional_argument; 9664 $done .= "\#$indic"; 9665 } elsif (($which =~ /end/)&&($pre_env =~ /indica/)) { 9666 $done .= '\#NIL'; 9667 } elsif (($which =~ /end/)&&($pre_env =~ /itrans/)) { 9668 $done .= "\#end$indic"; 9669 } elsif ($which =~ /begin/) { 9670 $done .= (($which =~ /end/)? $end_preprocessor{$pre_env} 9671 : $begin_preprocessor{$pre_env} ) 9672 } 9673 $_ = $done . $_; 9674 } 9675 } 9676 s/\\ITRANSinfo\{(\w+)\}\{([^}]*)\}/\#$1=$2/gm if $itrans_loaded; 9677 9678 s/\n{3,}/\n\n/gm; # remove multiple (3+) new-lines 9679 s/^\n+$//gs; # ...especially if that is all there is! 9680 if ($PREAMBLE) { 9681 s/$comment_mark(\d+\n?)?//g; 9682# $preamble =~ s/\\par\n?/\n/g; 9683 s/\\par\b/\n/g; 9684 s/^\s*$//g; #remove blank lines in the preamble 9685 }; 9686 9687 s/($html_specials_inv_rx)/$html_specials_inv{$1}/geo; 9688 # revert entities to TeX code, except if in {rawhtml} environments 9689 if (!($env =~ /rawhtml/)) { 9690 s/$character_entity_rx/( $character_map ? 9691 eval "\$${character_map}_character_map_inv\{\"$1\"\}" : 9692 $iso_8859_1_character_map_inv{$1} || 9693 $iso_10646_character_map_inv{$1})/geo; 9694 s/$named_entity_rx/( $character_map ? 9695 eval "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$1'}}" : 9696 $iso_8859_1_character_map_inv{$iso_8859_1_character_map{$1}} || 9697 $iso_10646_character_map_inv{$iso_10646_character_map{$1}})/geo; 9698 9699 } else { 9700 #RRM: check for invalid named entities in {rawhtml} environments 9701 s/($named_entity_rx)/&write_warnings( 9702 "An unknown named entity ($1) appears in the source text.") unless ( 9703 $character_map && eval 9704 "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$2'}}"); 9705 ";SPM$2;"/ego; 9706 } 9707 9708 #RRM: check for numbered character entity out-of-range 9709 if ($HTML_VERSION < 4.0) { 9710 s/$character_entity_rx/&write_warnings( 9711 "An invalid character entity ($1) appears in the source text.") 9712 if ($2 > 255); 9713 $1/ego; } 9714 9715 #RRM: check for invalid named entities outside {rawhtml} environments 9716 # --- these should have been caught already, but check again 9717 s/$named_entity_rx/&write_warnings( 9718 "An unknown named entity ($1) appears in the source text.") unless ( 9719 $character_map && eval 9720 "\$${character_map}_character_map_inv\{\$${character_map}_character_map{'$1'}}"); 9721 $1/ego; 9722 9723 &revert_to_raw_tex_hook if (defined &revert_to_raw_tex_hook); 9724 $_; 9725} 9726 9727sub next_wrapper { 9728 local($dollar) = @_; 9729 local($_,$id); 9730 $wrap_toggle = (($wrap_toggle eq 'end') ? 'begin' : 'end'); 9731 $id = ++$global{'max_id'}; 9732 $_ = "\\$wrap_toggle$O$id$C"."tex2html_wrap$O$id$C"; 9733 $_ = (($wrap_toggle eq 'end') ? $dollar.$_ : $_.$dollar); 9734 $_; 9735} 9736 9737sub make_wrapper { 9738 &make_any_wrapper($_[0], '', "tex2html_wrap"); 9739} 9740 9741sub make_nowrapper { 9742 &make_any_wrapper($_[0], 1, "tex2html_nowrap"); 9743} 9744 9745sub make_inline_wrapper { 9746 &make_any_wrapper($_[0], '', "tex2html_wrap_inline"); 9747} 9748 9749sub make_deferred_wrapper { 9750 &make_any_wrapper($_[0], 1, "tex2html_deferred"); 9751} 9752 9753sub make_nomath_wrapper { 9754 &make_any_wrapper($_[0], '', "tex2html_nomath_inline"); 9755} 9756 9757sub make_any_wrapper { 9758 local($toggle,$break,$kind) = @_; 9759 local($max_id) = ++$global{'max_id'}; 9760 '\\'. (($toggle) ? 'begin' : 'end') 9761 . "$O$max_id$C"."$kind$O$max_id$C" 9762 . (($toggle || !$break) ? '' : ''); 9763} 9764 9765sub get_last_word { 9766 # Returns the last word in multi-line strings 9767 local($_) = @_; 9768 local ($word,$lastbit,$which); 9769#JCL(jcl-tcl) 9770# also remove anchors and other awkward HTML markup 9771# &extract_pure_text("strict"); 9772## $_ = &purify($_); ## No. what if it is a verbatim string or image? 9773# 9774# while (/\s(\S+)\s*$/g) { $word = $lastbit = $1;} 9775 9776 if (!$_ && (defined $keep)) { 9777 # inside mathematics ! 9778 $_ = $keep . $pre ; 9779 } 9780 if (!$_ && $ref_before) { $_ = $ref_before; } 9781 elsif (!$_) { 9782 # get it from last thing before the current environment 9783 $which = $#processedE; 9784 $_ = $processedE[$which]; 9785 } 9786 9787 while (/((($O|$OP)\d+($C|$CP))[.\n]*\2|\s(\S+))\s*$/g) 9788 { $word = $lastbit = $1 } 9789 if (($lastbit =~ s/\$\s*$//)||(defined $keep)) { 9790 local($br_idA) = ++$global{'max_id'}; 9791 local($br_idB) = ++$global{'max_id'}; 9792 $lastbit = join('', "\\begin $O$br_idA${C}tex2html_wrap_inline$O$br_idA$C\$" 9793 , $lastbit, "\$\\end $O$br_idB${C}tex2html_wrap_inline$O$br_idB$C"); 9794 $lastbit = &translate_environments($lastbit); 9795 $lastbit = &translate_commands($lastbit); 9796 return ($lastbit); 9797 } 9798 if ($lastbit =~ s/($O|$OP)\d+($C|$CP)//g) { return ($lastbit); } 9799 elsif ($lastbit eq '') { return ($_) } 9800 9801 local($pre_bit); 9802 if ($lastbit =~/>([^>]*)$/) { 9803 $word = $1; $pre_bit = $`.'>'; 9804 if ($pre_bit =~ /($verb_mark|$verbstar_mark)$/) { 9805 $word = $lastbit; 9806 } elsif ($pre_bit =~ /<\w+_mark>$/) { 9807 $word = $& . $word; 9808 } elsif (!($word)) { 9809 if ($lastbit =~ s/<([^\/][^>]*)>$//o) 9810 { $word=$1; $pre_bit = $`; } 9811 elsif ($lastbit =~ s/>([^<]*)<\/[^>]*>//o) 9812 { $word=$1; $pre_bit = $`.'>' } 9813 else { $word = ";SPMnbsp;"; } 9814 } 9815# if ($pre_bit =~ /<\w+_mark>$/) { $word = $& . $word } 9816 } else { $word = $lastbit }; 9817 $word; 9818} 9819 9820#JCL(jcl-tcl) 9821# changed completely 9822# 9823# We take the first real words specified by $min from the string. 9824# Allow for simple HTML constructs like <I>...</I> (but not <H*> 9825# or <P*> and the like), math, or images to remain in the result, 9826# not counting as words. 9827# Take care that eg. <I>...</I> grouping tags are not broken. 9828# This is achieved by lifting the markup, removing superfluous 9829# words, re-inserting the markup, and throw empty markup away. 9830# In later versions images could be modified such that they become 9831# thumbnail sized. 9832# 9833# rawhtml or verbatim environments might introduce lots of awkward 9834# stuff, but yet we leave the according tex2html markers in. 9835# 9836sub get_first_words { 9837 local($_, $min) = @_; 9838 local($words,$i); 9839 local($id,%markup); 9840 #no limit if $min is negative 9841 $min = 1000 if ($min < 0); 9842 9843 &remove_anchors; 9844 #strip unwanted HTML constructs 9845 s/<\/?(P|BR|H)[^>]*>/ /g; 9846 #remove leading white space and \001 characters 9847 s/^\s+|\001//g; 9848 #lift html markup, numbered for recovery 9849 s/(<[^>]*>(#[^#]*#)?)/$markup{++$id}=$1; "\000$id\000"/ge; 9850 9851 foreach (split /\s+|\-{3,}/) { 9852 # count words (incl. HTML markup as part of the word) 9853 ++$i; 9854# $words .= $_ . " " if (/\000/ || ($i <= $min)); 9855 $words .= $_ . " " if ($i <= $min); 9856 } 9857 $_ = $words; 9858 chop; 9859 9860 #re-insert markup 9861 s/\000(\d+)\000/$markup{$1}/g; 9862 # remove empty markup 9863 # it's normalized, because generated by LaTeX2HTML only 9864 s/<([A-Z]+)[^>]*>\s*<\/\1>\s*//g; 9865 $_; 9866} 9867 9868sub replace_word { 9869 # Replaces the LAST occurrence of $old with $new in $str; 9870 local($str, $old, $new) = @_; 9871 substr($str,rindex($str,$old),length($old)) = $new; 9872 $str; 9873} 9874 9875# Returns the recognised sectioning commands as a string of alternatives 9876# for use in regular expressions; 9877sub get_current_sections { 9878 local($_, $key); 9879 foreach $key (keys %section_commands) { 9880 if ($key =~ /star/) { 9881 $_ = $key . "|" . $_} 9882 else { 9883 $_ .= "$key" . '[*]?|'; 9884 } 9885 } 9886 chop; # Remove the last "|". 9887 $_; 9888} 9889 9890sub numerically { 9891 local(@x) = split(' ',$a); 9892 local(@y) = split(' ',$b); 9893 local($i, $result); 9894 for($i=0;$i<$#x;$i++) { 9895 last if ($result = ($x[$i] <=> $y[$i])); 9896 } 9897 $result 9898} 9899 9900# Assumes that the files to be sorted are of the form 9901# <NAME><NUMBER> 9902sub file_sort { 9903 local($i,$j) = ($a,$b); 9904 $i =~ s/^[^\d]*(\d+)$/$1/; 9905 $j =~ s/^[^\d]*(\d+)$/$1/; 9906 $i <=> $j 9907} 9908 9909# If a normalized command name exists, return it. 9910sub normalize { 9911 # MRO: modified to use $_[1] 9912 # local($cmd,*after) = @_; 9913 my $cmd =$_[0]; 9914 my $ncmd; 9915 # Escaped special LaTeX characters 9916 if ($cmd =~ /^($latex_specials_rx)/) { 9917# $cmd =~ s/&(.*)$/&$1/o; 9918 $cmd =~ s/&(.*)$/$ampersand_mark$1/o; 9919 $cmd =~ s/%/$percent_mark/o; 9920 $_[1] = join('', $cmd, $_[1]); 9921 $cmd = ""} 9922 elsif ($ncmd = $normalize{$cmd}) { 9923 $ncmd; 9924 } 9925 else { 9926 $cmd =~ s/[*]$/star/; 9927 $cmd =~ s/\@/_at_/g; 9928 $cmd; 9929 } 9930} 9931 9932sub normalize_sections { 9933 my $dummy = ''; 9934 # MRO: s/$sections_rx/'\\' . &normalize($1.$2,*after) . $4/ge; 9935 s/$sections_rx/'\\' . &normalize($1.$2,$dummy) . $4/ge; 9936} 9937 9938sub embed_image { 9939 my ($url,$name,$external,$altst,$thumbnail,$map,$align, 9940 $usemap,$exscale,$exstr) = @_; 9941 my $imgID = ''; 9942 my $urlimg = $url; 9943 my $ismap = $map ? " ISMAP" : ''; 9944 print "\nembedding $url for $name, with $altst\n" if ($VERBOSITY > 1); 9945 9946 if (! ($NO_IMAGES || $PS_IMAGES)) { 9947 # for over-scaled GIFs with pre-determined sizes # RRM 11-9-96 9948 my $size; 9949 if (($width{$name})&&(($exscale)||($EXTRA_IMAGE_SCALE))) { 9950 $exscale = $EXTRA_IMAGE_SCALE unless ($exscale); 9951 if ($name =~ /inline|indisplay|entity|equation|math|eqn|makeimage/){ 9952 ($size, $imgID) = &get_image_size($url, $exscale); 9953 } else { 9954 ($size, $imgID) = &get_image_size($url,''); 9955 } 9956 } else { 9957 ($size,$imgID) = &get_image_size($url,''); 9958 } 9959 $image_size{$url} = $size 9960 unless ((! $size) || ($size eq "WIDTH=\"0\" HEIGHT=\"0\"")); 9961 $url = &find_unique($url); 9962 } 9963 9964 $urlimg = $url; 9965 $urlimg =~ s/\.$IMAGE_TYPE$/.html/ if ($map); 9966 if ($exstr =~ s/align\s*=\s*(\"?)(\w+)\1($|\s|,)//io) { $align = $2; } 9967 my $usersize = ''; 9968 if ($exstr =~ s/width\s*=\s*(\"?)([^\s,]+)\1($|\s|,)//io) { 9969 my ($pxs,$len) = &convert_length($2); 9970 $usersize = " WIDTH=\"$pxs\""; 9971 } 9972 if ($exstr =~ s/height\s*=\s*(\"?)([^\s,]+)\1($|\s|,)//io) { 9973 my ($pxs,$len) = &convert_length($2); 9974 $usersize .= " HEIGHT=\"$pxs\""; 9975 } 9976 9977 my $border = ''; 9978 $border = "\" BORDER=\"0" 9979 unless (($HTML_VERSION < 2.2 )||($exstr =~ /BORDER/i)); 9980 9981 my $aalign; 9982 if (($name =~ /figure|table|displaymath\d+|eqnarraystar/)&&(!$align)) { 9983 } elsif ($name =~ /displaymath_/) { 9984 $aalign = "MIDDLE".$border; 9985 } elsif (($name =~ /(equation|eqnarray)($|\d)/)&&(!$align)) { 9986 if ($HTML_VERSION >= 3.2) { 9987 $aalign = ($EQN_TAGS eq "L") ? "RIGHT" : "LEFT"; 9988 } 9989 } elsif ($name =~ /inline|display|entity|xy|diagram/ && $depth{$name} != 0) { 9990 $aalign = "MIDDLE".$border; 9991 } elsif ($name =~ /inpar/m) { 9992 $aalign = "TOP".$border; 9993 } else { $aalign = "BOTTOM".$border } 9994 9995 $aalign = "\U$align" if $align; 9996 my $ausemp = $usemap ? "\UUSEMAP=$usemap" : ''; 9997 9998 #append any extra valid options 9999 $ismap .= &parse_keyvalues ($exstr, ("IMG")) if ($exstr); 10000 10001 $altst = '' if ($ismap =~ /(^|\s+)ALT\s*=/); 10002 if ($altst) { 10003 if ($altst =~ /\s*ALT="?([^\"]+)"?\s*/io) { $altst=$1 } 10004 $altst =~ s/[<>"&]/'&'.$html_special_entities{$&}.';'/eg; 10005 $altst = "\n ALT=\"$altst\""; 10006 } 10007 10008 my ($extern_image_mark,$imagesize); 10009 if ($thumbnail) { 10010 print "\nmaking thumbnail" if ($VERBOSITY > 1); 10011 if (($image_size{$thumbnail}) = &get_image_size($thumbnail,'')) { 10012 $thumbnail = &find_unique($thumbnail); 10013 $imagesize = " ".$image_size{$thumbnail}; 10014 if ($HTML_VERSION < 2.2 ) { 10015 # put the WIDTH/HEIGHT information into the ALT string 10016 # first removing the quotes 10017 my ($noquotes) = $imagesize; 10018 $noquotes =~ s/\"//g; 10019 $altst =~ s/"$/\% $noquotes "/m; 10020 $imagesize = ''; 10021 } 10022 $extern_image_mark = join('',"<IMG" 10023 , "\n$imagesize" 10024 , (($aalign) ? " ALIGN=\"$aalign\"" : '') 10025 , ("$aalign$imagesize" ? "\n" : '' ) 10026 , " SRC=\"$thumbnail\"$altst>"); 10027 } 10028 $extern_image_mark =~ s/\s?BORDER="?\d+"?// 10029 unless ($exstr =~ /BORDER/i); 10030 } else { 10031 # MRO: dubious (&extern_image_mark takes only one arg) 10032 $extern_image_mark = &extern_image_mark($IMAGE_TYPE,$altst); 10033 } 10034 10035 my ($anch1,$anch2) = ('',''); 10036 my $result; 10037 if ($external || $thumbnail || $EXTERNAL_IMAGES) { 10038 if ( $extern_image_mark ) { 10039 $result = &make_href_noexpand($urlimg, $name , $extern_image_mark); 10040 &save_image_map($url, $urlimg, $map, $name, $altst, $ausemp) if $map; 10041 } 10042 } else { 10043 if ($map) { 10044 $anch1 = "<A HREF=\"$map\">"; 10045 $anch2 = "</A>"; 10046 } 10047# if ($aalign eq "CENTER") { 10048# if ($HTML_VERSION eq "2.0") { 10049# $anch1 .= "\n<P ALIGN=\"CENTER\">"; 10050# $anch2 .= "</P>"; 10051# } else { 10052# $anch1 .= "\n<DIV ALIGN=\"CENTER\">"; 10053# $anch2 .= "</DIV>"; 10054# } 10055# } 10056 10057 $imagesize = $image_size{$url}; 10058 $imagesize = $usersize if (($usersize)&&($HTML_VERSION > 2.1 )); 10059 if ($HTML_VERSION < 2.2 ) { 10060 # put the WIDTH/HEIGHT information into the ALT string 10061 # first removing the quotes 10062 my ($noquotes) = $imagesize; 10063 $noquotes =~ s/\"//g; 10064 $altst =~ s/"$/\% $noquotes "/m; 10065 } 10066 10067 # include a stylesheet entry for each included image 10068 if ($USING_STYLES && $SCALABLE_IMAGES &&(!$imgID)) { 10069 if ($url =~ /($dd|^)([^$dd$dd]+)\.$IMAGE_TYPE$/) { 10070 my $img_name = $2; 10071 $imgID = $img_name . ($img_name =~ /img/ ? '' : $IMAGE_TYPE); 10072 $img_style{"$imgID"} = ' ' unless $img_style{"$imgID"}; 10073 $imgID = join('', ' CLASS="', $imgID, '"') if $imgID; 10074 } 10075 } 10076 10077 ### MEH Add width and height to IMG 10078 ### Patched by <hswan@perc.Arco.com>: Fixed \htmladdimg 10079 if ( $imagesize || $name eq "external image" || $NO_IMAGES || $PS_IMAGES) { 10080 $imagesize = '' if ($HTML_VERSION < 2.2 ); 10081 if ($border =~ s/^"//) { $border .= '"' }; 10082 $result = join('' 10083 , "<IMG$imgID" 10084 , "\n", ($imagesize ? " $imagesize" : '') 10085 , (($aalign)? " ALIGN=\"$aalign\"" : $border) 10086 , $ismap ); 10087 if ($ausemp) { $result .= " $ausemp" } 10088 $result .= "\n" unless (($result =~ /\n *$/m)|| !$imagesize); 10089 $result .= " SRC=\"$url\""; 10090 if ($altst) { $result .= $altst } 10091 $result .= ">"; 10092 } 10093 } 10094 join('',$anch1, $result, $anch2); 10095} 10096 10097# MRO: added PNG support 10098sub get_image_size { # clean 10099 my ($imagefile, $scale) = @_; 10100 10101 $scale = '' if ($scale == 1); 10102 my ($imgID,$size) = ('',''); 10103 if (open(IMAGE, "<$imagefile")) { 10104 my ($buffer,$magic,$dummy,$width,$height) = ('','','',0,0); 10105 binmode(IMAGE); # not harmful un UNIX 10106 if ($IMAGE_TYPE =~ /gif/) { 10107 read(IMAGE,$buffer,10); 10108 ($magic,$width,$height) = unpack('a6vv',$buffer); 10109 # is this image sane? 10110 unless($magic =~ /^GIF8[79]a$/ && ($width * $height) > 0) { 10111 $width = $height = 0; 10112 } 10113 } 10114 elsif ($IMAGE_TYPE =~ /png/) { 10115 read(IMAGE,$buffer,24); 10116 ($magic,$dummy,$width,$height) = unpack('a4a12NN',$buffer); 10117 unless($magic eq "\x89PNG" && ($width * $height) > 0) { 10118 $width = $height = 0; 10119 } 10120 } 10121 close(IMAGE); 10122 10123 # adjust for non-trivial $scale factor. 10124 my ($img_w,$img_h) = ($width,$height); 10125 if ($scale && ($width * $height) > 0) { 10126 $img_w = int($width / $scale + .5); 10127 $img_h = int($height / $scale + .5); 10128 } 10129 $size = qq{WIDTH="$img_w" HEIGHT="$img_h"}; 10130 10131 # allow height/width to be stored in the stylesheet 10132 my ($img_name,$imgID); 10133 if ($SCALABLE_IMAGES && $USING_STYLES) { 10134 if ($imagefile =~ /(^|[$dd$dd])([^$dd$dd]+)\.(\Q$IMAGE_TYPE\E|old)$/o) { 10135 $img_name = $2; 10136 $imgID = $img_name . ($img_name =~ /img/ ? '' : $IMAGE_TYPE); 10137 } 10138 if ($imgID) { 10139 $width = $width/$LATEX_FONT_SIZE/$MATH_SCALE_FACTOR; 10140 $height = 1.8 * $height/$LATEX_FONT_SIZE/$MATH_SCALE_FACTOR; 10141 # How wide is an em in the most likely browser font ? 10142 if ($scale) { 10143 # How high is an ex in the most likely browser font ? 10144 $width = $width/$scale; $height = $height/$scale; 10145 } 10146 $width = int(100*$width + .5)/100; 10147 $height = int(100*$height + .5)/100; 10148 $img_style{$imgID} = qq(width:${width}em ; height:${height}ex ); 10149 #join('','width:',$width,'em ; height:',$height,'ex '); 10150 $imgID = qq{ CLASS="$imgID"}; 10151 } 10152 } 10153 } 10154 ($size, $imgID); 10155} 10156 10157sub find_unique { # clean 10158 my ($image1) = @_; 10159 local($/) = undef; # slurp in complete files 10160 10161 my $imagedata; 10162 if(open(IMG1,"<$image1")) { 10163 binmode(IMG1); # needed with .png under DOS 10164 $imagedata = <IMG1>; 10165 close(IMG1); 10166 } else { 10167 print "\nError: Cannot read '$image1': $!\n" 10168 unless ($image1 =~ /^\s*$HTTP_start/i); 10169 return $image1; 10170 } 10171 10172 my ($image2,$result); 10173 foreach $image2 (keys(%image_size)) { 10174 if ( $image1 ne $image2 && 10175 $image_size{$image1} eq $image_size{$image2} ) { 10176 if(open(IMG2,$image2)) { 10177 binmode(IMG2); # needed with .png under DOS 10178 $result = ($imagedata eq <IMG2>); 10179 close(IMG2); 10180 } else { 10181 print "\nWarning: Cannot read '$image2': $!\n" 10182 unless ($image2 =~ /^\s*$HTTP_start/i); 10183 } 10184# 10185# If we've found a match, rename the new image to a temporary one. 10186# Then try to link the new name to the old image. 10187# If the link fails, restore the temporary image. 10188# 10189 if ( $result ) { 10190 my $tmp = "temporary.$IMAGE_TYPE"; 10191 L2hos->Unlink($tmp); 10192 L2hos->Rename($image1, $tmp); 10193 if (L2hos->Link($image2, $image1)) { 10194 L2hos->Unlink($tmp); 10195 } else { 10196 L2hos->Rename($tmp, $image1); 10197 } 10198 return $image1; 10199 } 10200 } 10201 } 10202 $image1; 10203} 10204 10205sub save_image_map { # clean 10206 my ($url, $urlimg, $map, $name, $altst, $ausemp) = @_; 10207 unless(open(IMAGE_MAP, ">$urlimg")) { 10208 print "\nError: Cannot write '$urlimg': $!\n"; 10209 return; 10210 } 10211 ### HWS Pass server map unchanged from user 10212 print IMAGE_MAP "<HTML>\n<BODY>\n<A HREF=\"$map\">\n"; 10213 print IMAGE_MAP "<IMG\n SRC=\"$url\" ISMAP $ausemp $altst> </A>"; 10214 print IMAGE_MAP "</BODY>\n</HTML>\n"; 10215 close IMAGE_MAP; 10216} 10217 10218# Subroutine used mainly to rename an old image file about to recycled. 10219# But for active image maps, we must edit the auxiliary HTML file to point 10220# to the newly renames image. 10221sub rename_html { 10222 local ($from, $to) = @_; 10223 local ($from_prefix, $to_prefix, $suffix); 10224 ($from_prefix, $suffix) = split(/\./, $from); 10225 ($to_prefix, $suffix) = split(/\./, $to); 10226 if ($EXTN =~ /$suffix$/) { 10227 if (open(FROM, "<$from") && open(HTMP, ">HTML_tmp")) { 10228 while (<FROM>) { 10229 s/$from_prefix\.$IMAGE_TYPE/$to_prefix.$IMAGE_TYPE/g; 10230 print HTMP; 10231 } 10232 close (FROM); 10233 close (HTMP); 10234 L2hos->Rename ("HTML_tmp", $to); 10235 L2hos->Unlink($from) unless ($from eq $to); 10236 } 10237 else { 10238 &write_warnings("File $from is missing!\n"); 10239 } 10240 } 10241 L2hos->Rename("$from_prefix.old", "$to_prefix.$IMAGE_TYPE"); 10242 $to; 10243} 10244 10245sub save_captions_in_file { 10246 local ($type, $_) = @_; 10247 if ($_) { 10248 s/^\n//om; 10249 &replace_markers; 10250 &add_dir_to_href if ($DESTDIR); 10251 if(open(CAPTIONS, ">${PREFIX}$type.pl")) { 10252 print CAPTIONS $_; 10253 close (CAPTIONS); 10254 } else { 10255 print "\nError: Cannot write '${PREFIX}$type.pl': $!\n"; 10256 } 10257 } 10258} 10259 10260sub add_dir_to_href { 10261 $_ =~ s/'/\\'/g; 10262 $_ =~ s/(<LI><A )(NAME\=\"tex2html\d+\")?\s*(HREF=\")/$1$3\'.\$dir.\'/og; 10263 $_ = join('', "\'", $_, "\'\n"); 10264} 10265 10266sub save_array_in_file { 10267 local ($type, $array_name, $append, %array) = @_; 10268 local ($uutxt,$file,$prefix,$suffix,$done_file,$depth,$title); 10269 $prefix = $suffix = ""; 10270 my $filespec = ($append ? '>>' : '>') . "${PREFIX}$type.pl"; 10271 $prefix = q("$URL/" . ) 10272 if ($type eq "labels") && !($array_name eq "external\_latex\_labels"); 10273 $suffix = " unless (\$$array_name\{\$key\})" 10274 if (($type =~ /(sections|contents)/)||($array_name eq "printable\_key")); 10275 if ((%array)||($type eq "labels")) { 10276 print "\nSAVE_ARRAY:$array_name in FILE: ${PREFIX}$type.pl" 10277 if ($VERBOSITY > 1); 10278 unless(open(FILE,$filespec)) { 10279 print "\nError: Cannot write '${PREFIX}$type.pl': $!\n"; 10280 return; 10281 } 10282 if (($array_name eq "sub\_index") || ($array_name eq "printable\_key")) { 10283 print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n"; 10284 print FILE "# Printable index-keys from $array_name array.\n\n"; 10285 } elsif ($array_name eq "index\_labels") { 10286 print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n"; 10287 print FILE "# labels from $array_name array.\n\n"; 10288 } elsif ($array_name eq "index\_segment") { 10289 print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n"; 10290 print FILE "# segment identifier from $array_name array.\n\n"; 10291 } elsif ($array_name eq "external\_latex\_labels") { 10292 print FILE "\n# LaTeX2HTML $TEX2HTMLVERSION\n"; 10293 print FILE "# labels from $array_name array.\n\n"; 10294 } else { 10295 print FILE "# LaTeX2HTML $TEX2HTMLVERSION\n"; 10296 print FILE "# Associate $type original text with physical files.\n\n"; 10297 } 10298 while (($uutxt,$file) = each %array) { 10299 $uutxt =~ s|/|\\/|g; 10300 $uutxt =~ s|\\\\/|\\/|g; 10301 10302 if (!($array_name =~/images/)&&($file =~ /</)) { 10303 do { local $_ = $file; 10304 &replace_markers; 10305 $file = $_; undef $_; 10306 $file =~ s/(\G|[^q])[\\\|]\|/$1\\Vert/sg; 10307 $file =~ s/(\G|[^q])\|/$1\\vert/sg; 10308 }; 10309 } 10310 10311 local ($nosave); 10312 if ($MULTIPLE_FILES && $ROOTED && 10313 $type =~ /(sections|contents)/) { 10314 #RRM: save from $THIS_FILE only 10315 if ( $uutxt =~ /^$THIS_FILE /) { 10316 #RRM: save from $THIS_FILE only 10317 $nosave = '' 10318 } else { $nosave = 1 } 10319 } else { 10320 #RRM: suppress info from other segments 10321 $nosave = $noresave{$uutxt}; 10322 } 10323 10324 if (!$nosave && ($file ne '')) { 10325 print FILE "\n\$key = q/$uutxt/;\n"; 10326 10327 $file =~ s/\|/\\\|/g; # RRM: escape any occurrences of | 10328 $file =~ s/\\\\\|/\\\|/g; # unless already escaped as \| 10329 $file =~ s|\\\\|\\\\\\\\|g; 10330 $file =~ s/(SRC=")($HTTP_start)?/$1.($2 ? '' :"|.\"\$dir\".q|").$2/seg; 10331# 10332# 10333# added code for $dir with segmented docs; RRM 15/3/96 10334# 10335 if ($type eq "contents") { 10336 ($depth, $done_file) = split($delim, $file, 2 ); 10337 next if ($depth > $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 10338 print FILE 10339 "\$$array_name\{\$key\} = '$depth$delim'.\"\$dir\".q|$done_file|$suffix; \n"; 10340 10341 } elsif ($type eq "sections") { 10342 ($depth, $done_file) = split($delim, $file, 2 ); 10343 next if ($depth > $MAX_SPLIT_DEPTH + $MAX_LINK_DEPTH); 10344 print FILE 10345 "\$$array_name\{\$key\} = '$depth$delim'.\"\$dir\".q|$done_file|$suffix; \n"; 10346 10347 } elsif ($type eq "internals") { 10348 print FILE 10349 "\$$array_name\{\$key\} = \"\$dir\".q|$file|$suffix; \n"; 10350 10351 } elsif ($array_name eq "sub_index") { 10352 print FILE 10353 "\$$array_name\{\$key\} .= q|$file|$suffix; \n"; 10354 10355 } elsif ($array_name eq "index") { 10356 local($tmp_file) = ''; 10357 ($depth, $done_file) = split('HREF=\"', $file, 2 ); 10358 if ($done_file) { 10359 while ($done_file) { 10360 $depth =~ s/\s*$/ / if ($depth); 10361 $tmp_file .= "q|${depth}HREF=\"|.\"\$dir\"."; 10362 ($depth, $done_file) = split('HREF=\"', $done_file, 2 ); 10363 } 10364 print FILE 10365 "\$$array_name\{\$key\} .= ${tmp_file}q|$depth|$suffix; \n"; 10366 10367 } else { 10368 print FILE 10369 "\$$array_name\{\$key\} .= q|$file|$suffix; \n"; 10370 } 10371 } elsif ($array_name eq "printable_key") { 10372 print FILE 10373 "\$$array_name\{\$key\} = q|$file|$suffix; \n"; 10374 10375 } else { 10376 print FILE 10377 "\$$array_name\{\$key\} = ${prefix}q|$file|$suffix; \n"; 10378 } 10379 10380 if ($type =~ /(figure|table|images)/) {} else { 10381 print FILE "\$noresave\{\$key\} = \"\$nosave\";\n"; 10382 } 10383 10384 if ($type eq "sections") { 10385 ($depth, $done_file, $title) = split($delim, $file); 10386 print FILE "\$done\{\"\$\{dir\}$done_file\"\} = 1;\n"; 10387 } 10388 } 10389 } 10390 print FILE "\n1;\n\n" unless ( $array_name =~ /index/ ); 10391 close (FILE); 10392 } else { 10393 print "\nSAVE_FILE:$array_name: ${PREFIX}$type.pl EMPTY " if ($VERBOSITY > 1); 10394 } 10395} 10396 10397# returns true if $AUTO_NAVIGATION is on and there are more words in $_ 10398# than $WORDS_IN_PAGE 10399sub auto_navigation { 10400 # Uses $_; 10401 local(@tmp) = split(/\W*\s+\W*/, $_); 10402 ($AUTO_NAVIGATION && ( (scalar @tmp) > $WORDS_IN_PAGE)); 10403} 10404 10405# Returns true if $f1 is newer than $f2 10406sub newer { 10407 ($f1,$f2) = @_; 10408 local(@f1s) = stat($f1); 10409 local(@f2s) = stat($f2); 10410 ($f1s[9] > $f2s[9]); 10411}; 10412 10413sub iso_map { 10414 local($char, $kind, $quiet) = @_; 10415 my($character_map,$enc); 10416 local ($this); 10417 10418 if ( $CHARSET && $HTML_VERSION ge "2.1" ) { 10419 # see if it is a character in the charset 10420 $character_map = ((($charset =~ /utf/)&&!$NO_UTF)? 10421 'iso_10646' : $CHARSET ); 10422 $character_map =~ tr/-/_/; 10423 eval "\$enc = \$${character_map}_character_map\{\"$char$kind\"\}"; 10424 print "\n no support for $CHARSET: $@ " if ($@); 10425 } 10426 if ($USE_ENTITY_NAMES && $enc) { return(";SPM$char$kind;") } 10427 10428 if ($enc) { 10429 $enc =~ /^\&\#(\d{3});$/; 10430 # maybe convert it to an 8-bit character 10431 if ($NO_UTF && !$USE_UTF && ($1<=255)) { $enc = chr($1) } 10432# elsif (!$USE_UTF &&($1>127)&&($1<160)) { $enc = chr($1) } 10433 elsif ($character_map !~ /^iso_(8859_1|10646)/) { 10434 # get its latin1 or unicode entity encoding 10435 $enc = $iso_8859_1_character_map{"$char$kind"} 10436 ||$iso_8859_1A_character_map{"$char$kind"} 10437 ||$iso_10646_character_map{"$char$kind"} 10438 } 10439 } else { 10440 # get its latin1 or unicode entity encoding, if available 10441 $enc = $iso_8859_1_character_map{"$char$kind"} 10442 ||$iso_8859_1A_character_map{"$char$kind"} 10443 ||$iso_10646_character_map{"$char$kind"}; 10444 } 10445 10446 if ($enc) { 10447 $ISOLATIN_CHARS = 1; $enc; 10448 } elsif (!$image_made{"$char$kind"}) { 10449 print "\ncouldn't convert character $char$kind into available encodings" 10450 if (!quiet &&($VERBOSITY > 1)); 10451 &write_warnings( 10452 "couldn't convert character $char$kind into available encodings" 10453 . ($ACCENT_IMAGES ? ', using image' : '')) unless ($quiet); 10454 $image_made{"$char$kind"} = 1; 10455 ''; 10456 } else {''} 10457} 10458 10459sub titles_language { 10460 local($_) = @_; 10461 local($lang) = $_ . "_titles"; 10462 if (defined(&$lang)) { &$lang } 10463 else { 10464 &english_titles; 10465 &write_warnings( 10466 "\nThere is currently no support for the $tmp language." . 10467 "\nSee the file $CONFIG_FILE for examples on how to add it\n\n"); 10468 } 10469} 10470 10471sub translate_titles { 10472 $toc_title = &translate_commands($toc_title) if ($toc_title =~ /\\/); 10473 $lof_title = &translate_commands($lof_title) if ($lof_title =~ /\\/); 10474 $lot_title = &translate_commands($lot_title) if ($lot_title =~ /\\/); 10475 $idx_title = &translate_commands($idx_title) if ($idx_title =~ /\\/); 10476 $ref_title = &translate_commands($ref_title) if ($ref_title =~ /\\/); 10477 $bib_title = &translate_commands($bib_title) if ($bib_title =~ /\\/); 10478 $abs_title = &translate_commands($abs_title) if ($abs_title =~ /\\/); 10479 $app_title = &translate_commands($app_title) if ($app_title =~ /\\/); 10480 $pre_title = &translate_commands($pre_title) if ($pre_title =~ /\\/); 10481 $foot_title = &translate_commands($foot_title) if ($foot_title =~ /\\/); 10482 $fig_name = &translate_commands($fig_name) if ($fig_name =~ /\\/); 10483 $tab_name = &translate_commands($tab_name) if ($tab_name =~ /\\/); 10484 $prf_name = &translate_commands($prf_name) if ($prf_name =~ /\\/); 10485 $page_name = &translate_commands($page_name) if ($page_name =~ /\\/); 10486 $child_name = &translate_commands($child_name) if ($child_name =~ /\\/); 10487 $info_title = &translate_commands($info_title) if ($info_title =~ /\\/); 10488 $part_name = &translate_commands($part_name) if ($part_name =~ /\\/); 10489 $chapter_name = &translate_commands($chapter_name) 10490 if ($chapter_name =~ /\\/); 10491 $section_name = &translate_commands($section_name) 10492 if ($section_name =~ /\\/); 10493 $subsection_name = &translate_commands($subsection_name) 10494 if ($subsection_name =~ /\\/); 10495 $subsubsection_name = &translate_commands($subsubsection_name) 10496 if ($subsubsection_name =~ /\\/); 10497 $paragraph_name = &translate_commands($paragraph_name) 10498 if ($paragraph_name =~ /\\/); 10499 $see_name = &translate_commands($see_name) if ($see_name =~ /\\/); 10500 $also_name = &translate_commands($also_name) if ($also_name =~ /\\/); 10501 $next_name = &translate_commands($next_name) if ($next_name =~ /\\/); 10502 $prev_name = &translate_commands($prev_name) if ($prev_name =~ /\\/); 10503 $up_name = &translate_commands($up_name) if ($up_name =~ /\\/); 10504 $group_name = &translate_commands($group_name) if ($group_name =~ /\\/); 10505 $encl_name = &translate_commands($encl_name) if ($encl_name =~ /\\/); 10506 $headto_name = &translate_commands($headto_name) if ($headto_name =~ /\\/); 10507 $cc_name = &translate_commands($cc_name) if ($cc_name =~ /\\/); 10508 $default_title = &translate_commands($default_title) 10509 if ($default_title =~ /\\/); 10510} 10511####################### Code Generation Subroutines ############################ 10512# This takes a string of commands followed by optional or compulsory 10513# argument markers and generates a subroutine for each command that will 10514# ignore the command and its arguments. 10515# The commands are separated by newlines and have the format: 10516## <cmd_name>#{}# []# {}# [] etc. 10517# {} marks a compulsory argument and [] an optional one. 10518sub ignore_commands { 10519 local($_) = @_; 10520 foreach (/.*\n?/g) { 10521 s/\n//g; 10522 # For each line 10523 local($cmd, @args) = split('\s*#\s*',$_); 10524 print "PCT: ignore_commands: cmd: $cmd\n" if ($VERBOSITY > 10) ; 10525 next unless $cmd; 10526 $cmd =~ s/ //; 10527 ++$ignore{$cmd}; 10528 local ($body, $code, $thisone) = ("", ""); 10529 10530 # alter the pattern here to debug particular commands 10531 $thisone = 1 if ($cmd =~ /let/); 10532 10533 if (@args) { 10534 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 10535 # Replace the argument markers with appropriate patterns 10536 foreach $arg (@args) { 10537 print "\nARG: $arg" if ($thisone); 10538 if ($arg =~ /\{\}/) { 10539 $body .= 'local($cmd) = '."\"$cmd\"".";\n"; 10540 $body .= '$args .= &missing_braces'."\n ".'unless ('; 10541 $body .= '(s/$next_pair_pr_rx/$args .= $2;\'\'/eo)'."\n"; 10542 $body .= ' ||(s/$next_pair_rx/$args .= $2;\'\'/eo));'."\n"; 10543 print "\nAFTER:$'" if (($thisone)&&($')); 10544 $body .= $' if ($'); 10545 } elsif ($arg =~ /\[\]/) { 10546 $body .= '($dummy, $pat) = &get_next_optional_argument;' 10547 . '$args .= $pat;'."\n"; 10548 print "\nAFTER:$'" if (($thisone)&&($')); 10549 $body .= $' if ($'); 10550 } elsif ($arg =~ /^\s*\\/) { 10551 $body .= '($dummy, $pat) = &get_next_tex_cmd;' 10552 . '$args .= $pat;'."\n"; 10553 print "\nAFTER:$'" if (($thisone)&&($')); 10554 $body .= $' if ($'); 10555 } elsif ($arg =~ /<<\s*([^>]*)[\b\s]*>>/) { 10556 local($endcmd, $after) = ($1,$'); 10557 $after =~ s/(^\s*|\s*$)//g; 10558 $endcmd = &escape_rx_chars($endcmd); 10559 $body .= join('','if (/',$endcmd,'/o) { $args .= $`; $_ = $',"'",'};',"\n") ; 10560 print "\nAFTER:$after" if (($thisone)&&($after)); 10561 $body .= "$after" if ($after); 10562 } 10563 else { 10564 print "\nAFTER:$'" if (($thisone)&&($arg)); 10565 $body .= $arg ; 10566 } 10567 } 10568 # Generate a new subroutine 10569 # $code = "sub do_cmd_$cmd {\n".'local($_) = @_;'. join('',@args) .'$_}'; 10570 $code = join('',"sub do_cmd_$cmd {\n", 10571 'local($_,$ot) = @_; ', 10572 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R; ', 10573 'local($args); ', 10574 "\n", 10575 $body, 10576 (($body)? ";\n" : ''), 10577 (($thisone)? "print \"\\n$cmd:\".\$args.\"\\n\";\n" : ''), 10578 (($arg)? $arg : '$_') . "}" 10579 ); 10580 print STDOUT "\n$code\n" if ($thisone); # for error-checking 10581 eval ($code); # unless ($thisone); 10582 print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@); 10583 } 10584 else { 10585 $code = "sub do_cmd_$cmd {\n".'$_[0]}'; 10586 print "\n$code\n" if ($thisone); # for error-checking 10587 eval ($code); # unless ($thisone); 10588 print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@); 10589 } 10590 } 10591} 10592 10593 10594sub ignore_numeric_argument { 10595 # Chop this off 10596 #RRM: 2001/11/8: beware of taking too much, when <num> <num> 10597 local($num) = '(^|width|height|plus|minus)\s*[+-]?[\d\.]+(cm|em|ex|in|pc|pt|mm)?\s*'; 10598 do { s/^\s*=?\s*//so; s/^($num)*//so } unless (/^(\s*\<\<\d+\>\>|$)/); 10599} 10600 10601sub get_numeric_argument { 10602 my ($num_rx,$num) = ('',''); 10603 # Collect the numeric part 10604 #RRM: 2001/11/8: beware of taking too much, when <num> <num> 10605 $num_rx = '(^|width|height|plus|minus)\s*[+-]?[\d\.]+(cm|em|ex|in|pc|pt|mm)?\s*'; 10606 do { s/^\s*=?\s*//so; s/($num_rx)*/$num=$&;''/soe } unless (/^(\s*\<\<\d+\>\>|$)/); 10607 $num; 10608} 10609 10610sub process_in_latex_helper { 10611 local($ctr,$val,$cmd) = @_; 10612 ($ASCII_MODE ? "[$cmd]" : 10613 &process_in_latex("\\setcounter{$ctr}{$val}\\$cmd")) 10614} 10615 10616sub do_cmd_catcode { 10617 local($_) = @_; 10618 s/^\s*[^=]+(=?\s*\d+\s|\\active)\s?//; 10619 $_; 10620} 10621 10622sub do_cmd_string { 10623 local($_) = @_; 10624 local($tok); 10625 s/^\s*(\\([a-zA-Z]+|.)|[&;]\w+;(#\w+;)?|.)/$tok=$1;''/e; 10626 if ($2) {$tok = "\\$2"}; 10627 "$tok".$_ 10628} 10629 10630sub do_cmd_boldmath { 10631 local($_) = @_; 10632 $BOLD_MATH = 1; 10633 $_; 10634} 10635 10636sub do_cmd_unboldmath { 10637 local($_) = @_; 10638 $BOLD_MATH = 0; 10639 $_; 10640} 10641 10642sub do_cmd_lq { 10643 local($_) = @_ ; 10644 local($lquote); 10645 # check for double quotes 10646 if (s/^\s*\\lq(\b|$|[^A-Za-z])/$1/) { 10647 $lquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? '``' 10648 : &do_leftquotes($_)); 10649 } else { 10650 $lquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? '`' 10651 : &do_leftquote($_)); 10652 } 10653 $lquote . $_; 10654 } 10655 10656sub do_leftquote { 10657 # MRO: use $_[0] : local(*_) = @_; 10658 local($quote,$lquo) = ('',($HTML_VERSION<5)? '‘' : ';SPMlsquo;'); 10659 # select whole quotation, if \lq matches \rq 10660 if ($_[0] =~ /^(.*)((\\rq\\rq|'')*)(\\rq)/) { 10661 $quote = $1.$2; $_[0] = $'; 10662 local($rquo) = &do_rightquote(); 10663 &process_quote($lquo,$quote,$rquo); 10664 } else { $lquo; } 10665} 10666 10667sub do_leftquotes { 10668 # MRO: use $_[0] : local(*_) = @_; 10669 local($quote,$lquo) = ('',($HTML_VERSION<5)? '“' : ';SPMldquo;'); 10670 # select whole quotation, if \lq\lq matches \rq\rq or '' 10671 if ($_[0] =~ /^(.*)(\\rq\\rq|'')/) { 10672 $quote = $1; $_[0] = $'; 10673 local($rquo) = &do_rightquotes(); 10674 &process_quote($lquo,$quote,$rquo); 10675 } else { $lquo; } 10676} 10677 10678# RRM: By default this just concatenates the strings; e.g. ` <quote> ' 10679# This can be overridden in a html-version file 10680sub process_quote { join ('', @_) } 10681 10682sub do_cmd_rq { 10683 local($_) = @_ ; 10684 local($rquote); 10685 if ($_ =~ s/^\s*\\rq\b//) { 10686 $rquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? "''" 10687 : &do_rightquotes()); 10688 } else { 10689 $rquote = ((($HTML_VERSION < 4)&&!($charset =~ /utf/)) ? "'" 10690 : &do_rightquote()); 10691 } 10692 $rquote . $_; 10693} 10694 10695sub do_rightquote { (($HTML_VERSION < 5)? '’' : ';SPMrsquo;') } 10696sub do_rightquotes { (($HTML_VERSION < 5)? '”' : ';SPMrdquo;') } 10697 10698sub do_cmd_parbox { 10699 local($_) = @_; 10700 local($args, $contents, $dum, $pat); 10701 ($dum,$pat) = &get_next_optional_argument; # discard this 10702 ($dum,$pat) = &get_next_optional_argument; # discard this 10703 ($dum,$pat) = &get_next_optional_argument; # discard this 10704 $args .= $pat if ($pat); 10705 $pat = &missing_braces unless ( 10706 (s/$next_pair_pr_rx/$pat=$2;''/eom) 10707 ||(s/$next_pair_rx/$pat=$2;''/eom)); 10708 $args .= "{".$`.$pat."}"; 10709 $contents = &missing_braces unless ( 10710 (s/$next_pair_pr_rx/$contents=$2;''/eom) 10711 ||(s/$next_pair_rx/$contents=$2;''/eom)); 10712 $args .= "{".$`.$contents."}"; 10713 if ($NO_PARBOX_IMAGES) { 10714 $contents = join ('', &do_cmd_par(), $contents, '</P>' ); 10715 } else { 10716 $contents = &process_math_in_latex('','text',0,"\\parbox$args") 10717 if ($contents); 10718 } 10719 $contents . $_; 10720} 10721 10722 10723sub do_cmd_mbox { 10724 local($_) = @_; 10725 local($text,$after)=('',''); 10726 $text = &missing_braces unless ( 10727 (s/$next_pair_pr_rx/$text = $2;''/eo) 10728 ||(s/$next_pair_rx/$text = $2;''/eo)); 10729 $after = $_; 10730 10731 # incomplete macro replacement 10732 if ($text =~ /(^|[^\\<])#\d/) { return($after) } 10733 10734 if ($text =~ /(tex2html_wrap_inline|\$$OP(\d+)$CP$OP\2$CP\$|\$$O(\d+)$C$O\2$C\$)/) { 10735 if ($text =~ 10736 /$image_mark#([^#]+)#([\.,;:\)\]])?(\001)?([ \t]*\n?)(\001)?/) { 10737 local($mbefore, $mtext, $mafter) = ($`, $&, $'); 10738 $mbefore = &translate_commands($mbefore) if ($mbefore =~ /\\/); 10739 $mafter = &translate_commands($mafter) if ($mafter =~ /\\/); 10740 join('', $mbefore, $mtext, $mafter, $after); 10741 } else { 10742 join ('', &process_math_in_latex('','','',"\\hbox{$text}"), $after ) 10743 } 10744 } else { 10745 $text = &translate_environments($text); 10746 $text = &translate_commands($text); 10747 join('', $text, $after); 10748 } 10749} 10750 10751 10752 10753# *Generates* subroutines to handle each of the declarations 10754# like \em, \quote etc., in case they appear with the begin-end 10755# syntax. 10756sub generate_declaration_subs { 10757 local($key, $val, $pre, $post, $code ); 10758 print "\n *** processing declarations ***\n"; 10759 while ( ($key, $val) = each %declarations) { 10760 if ($val) { 10761 ($pre,$post) = ('',''); 10762 $val =~ m|</.*$|; 10763 do {$pre = $`; $post = $& } unless ($` =~ /^<>/); 10764 $pre =~ s/"/\\"/g; $post =~ s/"/\\"/g; 10765 $code = "sub do_env_$key {" 10766# . 'local($_) = @_;' . "\n" 10767# . 'push(@$open_tags_R, $key);'. "\n" 10768# . '$_ = &translate_environments($_);'. "\n" 10769# . '$_ = &translate_commands($_);'. "\n" 10770# . "join('',\"$pre\",\"\\n\"," .'$_' .",\"$post\");\n};"; 10771 . '&declared_env('.$key.',@_)};'; 10772 eval $code; 10773 if ($@) {print "\n *** $key ". $@ }; 10774 } 10775 } 10776 } 10777 10778# *Generates* subroutines to handle each of the sectioning commands. 10779sub generate_sectioning_subs { 10780 local($key, $val, $cmd, $body); 10781 while ( ($key, $val) = each %standard_section_headings) { 10782 $numbered_section{$key} = 0; 10783 eval "sub do_cmd_$key {" 10784 . 'local($after,$ot) = @_;' 10785 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;' 10786 . '&reset_dependents('. $key . ');' 10787 . '&do_cmd_section_helper('.$val.','.$key.');}'; 10788 print STDERR "\n*** sub do_cmd_$key failed:\n$@\n" if ($@); 10789 # Now define the *-form of the same commands. The difference is that the 10790 # $key is not passed as an argument. 10791 eval "sub do_cmd_$key" . "star {" 10792 . 'local($after,$ot) = @_;' 10793 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;' 10794 . '&do_cmd_section_helper(' . $val . ');}'; 10795 print STDERR "\n*** sub do_cmd_${key}star failed:\n$@\n" if ($@); 10796 # Now define the macro \the$key 10797 &process_commands_wrap_deferred("the$key \# {}\n"); 10798### local($_) = "<<1>>$key<<1>>"; 10799 $body = "<<1>>$key<<1>>"; 10800 &make_unique($body); 10801 $cmd = "the$key"; 10802 eval "sub do_cmd_$cmd {" 10803 . 'local($after,$ot) = @_;' 10804 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;' 10805 . '&do_cmd_arabic(' . "\"$body\"" . ").\$after;};"; 10806 print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@); 10807 $raw_arg_cmds{$cmd} = 1; 10808 } 10809 &addto_dependents('chapter','section'); 10810 &addto_dependents('section','subsection'); 10811 &addto_dependents('subsection','subsubsection'); 10812 &addto_dependents('subsubsection','paragraph'); 10813 &addto_dependents('paragraph','subparagraph'); 10814} 10815 10816sub addto_dependents { 10817 local($ctr, $dep) = @_; 10818 local($tmp, $depends); 10819 if ($depends = $depends_on{$dep}) { 10820 &remove_dependency($depends, $dep) } 10821 $depends_on{$dep} = $ctr; 10822 10823 $tmp = $dependent{$ctr}; 10824 if ($tmp) { 10825 $dependent{$ctr} = join($delim, $tmp, $dep); 10826 } else { $dependent{$ctr} = $dep } 10827 } 10828 10829sub remove_dependency { 10830 local($ctr, $dep) = @_; 10831 local(@tmp, $tmp, $dtmp); 10832 print "\nremoving dependency of counter {$dep} from {$ctr}\n"; 10833 foreach $dtmp (split($delim, $dependent{$ctr})) { 10834 push(@tmp, $dtmp) unless ($dtmp =~ /$dep/); 10835 } 10836 $dependent{$ctr} = join($delim, @tmp); 10837} 10838 10839 10840# Uses $after which is defined in the caller (the caller is a generated subroutine) 10841# Also uses @curr_sec_id 10842# 10843#JCL(jcl-tcl) (changed almost everything) 10844# 10845sub do_cmd_section_helper { 10846 local($H,$key) = @_; 10847 local($section_number, $titletext, $title_key, @tmp, $align, $dummy); 10848 local($anchors,$pre,$run_title,$_) = ('', "\n", '', $after); 10849 local($open_tags_R) = []; 10850 10851 # if we have a $key the current section is not of the *-form, so we need 10852 # to update the counters. 10853 &do_cmd_stepcounter("${O}0$C$key${O}0$C") 10854 if ($key && !($unnumbered_section_commands{$key})); 10855 if ($key =~ /^paragraph/) { 10856 $H .=' class="bparagraph"' ; 10857 } 10858 if ($key =~ /^subparagraph/) { 10859 $H .=' class="bsubparagraph"' ; 10860 } 10861 local($br_id); 10862 local ($align, $dummy)=&get_next_optional_argument; 10863 if (($align =~/^(left|right|center)$/i)&&($HTML_VERSION > 2.0)) { 10864 $align = "ALIGN=\"$1\""; 10865 } elsif ($align) { 10866 # data was meant to be a running-head ! 10867 $br_id = ++$global{'max_id'}; 10868 $run_title = &translate_environments("$O$br_id$C$align$O$br_id$C"); 10869 $run_title = &translate_commands($run_title) if ($run_title =~ /\\/); 10870 $run_title =~ s/($O|$OP)\d+($C|$CP)//g; 10871 $align = ''; 10872 } else { 10873 } 10874 $titletext = &missing_braces 10875 unless s/$next_pair_rx/$titletext=$2;''/eo; 10876 $br_id = ++$global{'max_id'}; 10877 $titletext = &translate_environments("$O$br_id$C$titletext$O$br_id$C"); 10878 10879 $title_key = $run_title || $titletext; 10880 $title_key =~ s/$image_mark\#([^\#]+)\#(\\space)?/&purify_caption($1)/e; 10881 # This should reduce to the same information as contained in the .aux file. 10882 $title_key = &sanitize(&simplify($title_key)); 10883 10884 # RRM: collect all anchors from \label and \index commands 10885 ($anchors,$titletext) = &extract_anchors($titletext); 10886 local($saved_title) = $titletext; 10887 do { 10888 # to ensure a style ID is not saved and re-used in (mini-)TOCs 10889 local($USING_STYLES) = 0; 10890 $titletext = &translate_environments($titletext); 10891 $titletext = &translate_commands($titletext) 10892 if ($titletext =~/\\/); 10893 }; 10894 # but the style ID can be used for the title on the HTML page 10895 if (!($titletext eq $saved_title)) { 10896 $saved_title = &translate_environments($saved_title); 10897 $saved_title = &translate_commands($saved_title) 10898 if ($saved_title =~/\\/); 10899 $saved_title = &simplify($saved_title); 10900 } 10901 local($closures) = &close_all_tags(); 10902 $saved_title .= $closures; 10903 $title_text .= $closures; 10904 10905 # This is the LaTeX section number read from the $FILE.aux file 10906 @tmp = split(/$;/,$encoded_section_number{$title_key}); 10907 $section_number = shift(@tmp); 10908 $section_number = "" if ($section_number eq "-1"); 10909 $encoded_section_number{$title_key} = join($;, @tmp) 10910# unless (defined $title); 10911 unless ($title); 10912 10913 # need to check also &{wrap_cmd_... also, if \renewcommand has been used; 10914 # thanks Bruce Miller 10915 local($thehead,$whead) = ("do_cmd_the$key","wrap_cmd_the$key"); 10916 $thehead = ((defined &$thehead)||(defined &$whead) 10917 ? &translate_commands("\\the$key") : ''); 10918 $thehead .= $SECNUM_PUNCT 10919 if ($SECNUM_PUNCT &&($thehead)&& !($thehead =~ /\./)); 10920 $section_number = $thehead if (($thehead)&&($SHOW_SECTION_NUMBERS)); 10921 10922 #JKR: Don't prepend whitespace 10923 if ($section_number) { 10924 $titletext = "$section_number " . $titletext; 10925 $saved_title = "$section_number " . $saved_title; 10926 $run_title = "$section_number " . $run_title if $run_title; 10927 } 10928 10929# $toc_sec_title = $titletext; 10930# $toc_sec_title = &purify($titletext); 10931 $toc_sec_title = &simplify($titletext); 10932 $titletext = &simplify($titletext); 10933# $TITLE = &purify($titletext); 10934 local($after) = $_; 10935 do { 10936 local($_) = $titletext; &remove_anchors; 10937 if ($run_title) { 10938 $TITLE = $run_title; 10939 } elsif ($_) { 10940 $TITLE = $_ 10941 } else { $TITLE = '.' }; 10942 }; 10943 $global{$key}-- if ($key && $making_name); 10944 return ($TITLE) if (defined $title); 10945 10946 #RRM: no preceding \n when this is the first section-head on the page. 10947 if (! $key || $key < $MAX_SPLIT_DEPTH) { $pre = '' }; 10948 if ( defined &make_pre_title) { 10949 $pre = &make_pre_title($saved_title, $H); 10950 } 10951 10952 undef $open_tags_R; 10953 $open_tags_R = [ @save_open_tags ]; 10954 10955 join('', $pre, &make_section_heading($saved_title, $H, $align.$anchors) 10956 , $open_all, $_); 10957} 10958 10959sub do_cmd_documentclass { 10960 local($_) = @_; 10961 local ($docclass)=(''); 10962 local ($cloptions,$dum)=&get_next_optional_argument; 10963 $docclass = &missing_braces unless ( 10964 (s/$next_pair_pr_rx/$docclass = $2;''/eo) 10965 ||(s/$next_pair_rx/$docclass = $2;''/eo)); 10966 local($rest) = $'; 10967 &do_require_package($docclass); 10968 if (! $styles_loaded{$docclass}) { 10969 &no_implementation("document class",$docclass); 10970 } else { 10971 if($cloptions =~ /\S+/) { # are there any options? 10972 &do_package_options($docclass,$cloptions); 10973 } 10974 } 10975 $rest; 10976 } 10977sub do_cmd_documentstyle { &do_cmd_documentclass($_[0]); } 10978 10979sub do_cmd_usepackage { 10980 local($_) = @_; 10981 # RRM: allow lists of packages and options 10982 local ($package, $packages)=('',''); 10983 local ($options,$dum)=&get_next_optional_argument; 10984 $packages = &missing_braces unless ( 10985 (s/$next_pair_pr_rx/$packages = $2;''/eo) 10986 ||(s/$next_pair_rx/$packages = $2;''/eo)); 10987 local($rest) = $_; 10988 # MRO: The files should have already been loaded by 10989 # TMP_styles, but we better make it sure. 10990 foreach $package (split (',',$packages)) { # allow multiple packages 10991 $package =~ s/\s|\%|$comment_mark\d*//g; # remove whitespace 10992 $package =~ s/\W/_/g; # replace non-alphanumerics 10993 &do_require_package($package); 10994 if (! $styles_loaded{$package}) { 10995 &no_implementation("package",$package); 10996 } else { 10997 if($options =~ /\S+/) { # are there any options? 10998 &do_package_options($package,$options); 10999 } 11000 } 11001 } 11002 $rest; 11003} 11004 11005 11006sub no_implementation { 11007 local($what,$which)= @_; 11008 print STDERR "\nWarning: No implementation found for $what: $which\n"; 11009} 11010 11011sub do_cmd_RequirePackage { 11012 local($_)= @_; 11013 local($file); 11014 local($options,$dum)=&get_next_optional_argument; 11015 $file = &missing_braces unless ( 11016 (s/$next_pair_pr_rx/$file = $2;''/eo) 11017 ||(s/$next_pair_rx/$file = $2;''/eo)); 11018 local($rest) = $_; 11019 $file =~ s/^[\s\t\n]*//o; 11020 $file =~ s/[\s\t\n]*$//o; 11021 # load the package, unless that has already been done 11022 &do_require_package($file) unless ($styles_loaded{$file}); 11023 # process any options 11024 if (! $styles_loaded{$file}) { 11025 &no_implementation("style",$file); 11026 } else { 11027 # process any options 11028 &do_package_options($file,$options) if ($options); 11029 } 11030 $_ = $rest; 11031 # ignore trailing optional argument 11032 local($date,$dum)=&get_next_optional_argument; 11033 $_; 11034} 11035 11036sub do_cmd_PassOptionsToPackage { 11037 local($_) = @_; 11038 local($options,$file); 11039 $options = &missing_braces unless ( 11040 (s/$next_pair_pr_rx/$options = $2;''/eo) 11041 ||(s/$next_pair_rx/$options = $2;''/eo)); 11042 $file = &missing_braces unless ( 11043 (s/$next_pair_pr_rx/$file = $2;''/eo) 11044 ||(s/$next_pair_rx/$file = $2;''/eo)); 11045 $passedOptions{$file} = $options; 11046 $_; 11047} 11048sub do_cmd_PassOptionsToClass{ &do_cmd_PassOptionsToPackage(@_)} 11049 11050sub do_package_options { 11051 local($package,$options)=@_; 11052 local($option); 11053 if ($passedOptions{$package}) { $options = $passedOptions{$package}.'.'.$options }; 11054 foreach $option (split (',',$options)) { 11055 $option =~ s/^[\s\t\n]*//o; 11056 $option =~ s/[\s\t\n]*$//o; 11057 $option =~ s/\W/_/g; # replace non-alphanumerics 11058 next unless ($option); 11059 if (!($styles_loaded{$package."_$option"})) { 11060 &do_require_packageoption($package."_$option"); 11061 if (!($styles_loaded{$package."_$option"})) { 11062 &no_implementation("option","\`$option\' for \`$package\' package\n"); 11063 } 11064 } 11065 } 11066 $rest; 11067 } 11068 11069sub do_class_options { 11070 local($class,$options)=@_; 11071 local($option); 11072 if ($passedOptions{$class}) { $options = $passedOptions{$class}.'.'.$options }; 11073 foreach $option (split (',',$options)) { 11074 $option =~ s/^[\s\t\n]*//o; 11075 $option =~ s/[\s\t\n]*$//o; 11076 $option =~ s/\W/_/g; # replace non-alphanumerics 11077 next unless ($option); 11078 &do_require_package($option); 11079 if (!($styles_loaded{$class."_$option"})) { 11080 &do_require_packageoption($class."_$option"); 11081 if (!($styles_loaded{$class."_$option"})) { 11082 &no_implementation("option","\`$option\' for document-class \`$class\'\n"); 11083 } 11084 } 11085 } 11086 $rest; 11087} 11088 11089sub do_require_package { 11090 local($file)= @_; 11091 local($dir); 11092 #RRM: make common ps/eps-packages use epsfig.perl 11093 $file = 'epsfig' if ($file =~ /^(psfig|epsf)$/); 11094 11095 if ($file =~ /^graphicx$/) { 11096 # work-around the CVS repository bug: use graphixx , not graphicx 11097 foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) { 11098 if (-f "$dir${dd}graphixx.perl") { 11099 $file = 'graphixx'; 11100 last; 11101 } 11102 } 11103 } 11104 11105 11106 if (! $styles_loaded{$file}) { 11107 # look for a file named ${file}.perl 11108 # MRO: use $texfilepath instead of `..' 11109 if ((-f "$texfilepath$dd${file}.perl") && ! $styles_loaded{$file}){ 11110 print STDOUT "\nPackage: loading $texfilepath$dd${file}.perl"; 11111 require("$texfilepath$dd${file}.perl"); 11112 $styles_loaded{$file} = 1; 11113 } else { 11114 foreach $dir (split(/$envkey/,$LATEX2HTMLSTYLES)) { 11115 if ((-f "$dir$dd${file}.perl") && ! $styles_loaded{$file}){ 11116 print STDOUT "\nPackage: loading $dir$dd${file}.perl"; 11117 require("$dir$dd${file}.perl"); 11118 $styles_loaded{$file} = 1; 11119 last; 11120 } 11121 } 11122 } 11123 } 11124 } 11125 11126sub do_require_extension { 11127 local($file)= @_; 11128 local($dir); 11129 11130 if (! $styles_loaded{$file}) { 11131 # look for a file named ${file}.pl 11132 # MRO: use $texfilepath instead of `..' 11133 if (-f "$texfilepath$dd${file}.pl") { 11134 print STDOUT "\nExtension: loading $texfilepath$dd${file}.pl"; 11135 require("$texfilepath$dd${file}.pl"); 11136 ++$styles_loaded{$file}; 11137 $NO_UTF = 1 if (($file =~ /latin/)&&($charset =~/utf/)); 11138 } else { 11139 foreach $dir (split(/$envkey/,$LATEX2HTMLVERSIONS)) { 11140 if (-f "$dir$dd${file}.pl"){ 11141 print STDOUT "\nExtension: loading $dir$dd${file}.pl"; 11142 require("$dir$dd${file}.pl"); 11143 ++$styles_loaded{$file}; 11144 $NO_UTF = 1 if (($file =~ /latin/)&&($charset =~/utf/)); 11145 last; 11146 } 11147 } 11148 } 11149 } else { 11150 if (($file =~ /latin|hebrew/)&&($charset =~/utf|10646/) 11151 && $loading_extensions) { 11152 $NO_UTF = 1; 11153 $USE_UTF = 0; 11154 print STDOUT "\n\n ...producing $CHARSET output\n"; 11155 $charset = $CHARSET; 11156 } 11157 } 11158} 11159 11160sub do_require_packageoption { 11161 local($option)= @_; 11162 local($do_option); 11163 # first look for a file named ${option}.perl 11164 &do_require_package($option) unless ($styles_loaded{$option}); 11165 # next look for a subroutine named do_$option 11166 $do_option = "do_$option"; 11167 if (!($styles_loaded{$option}) && defined(&$do_option)) { 11168 &$do_option(); 11169 $styles_loaded{$option} = 1; 11170 } 11171} 11172 11173############################ Environments ################################ 11174 11175# This is a dummy environment used to synchronise the expansion 11176# of order-sensitive macros. 11177sub do_env_tex2html_deferred { 11178 local($_) = @_; 11179 local($tex2html_deferred) = 1; 11180 $_ = &process_command($single_cmd_rx,$_); 11181} 11182 11183# catch wrapped commands that need not have been 11184sub do_env_tex2html_nomath_inline { 11185 local($_) = @_; 11186 s/^\s+|\s+$//gs; 11187 my($cmd) = $_; 11188 if ($cmd=~s/^\\([a-zA-Z]+)//s) { $cmd = $1 }; 11189 return (&translate_commands($_)) if ($raw_arg_cmds{$cmd}<1); 11190 &process_undefined_environment($env, $id, $_); 11191} 11192 11193# The following list environment subroutines still do not handle 11194# correctly the case where the list counters are modified (e.g. \alph{enumi}) 11195# and the cases where user defined bullets are mixed with the default ones. 11196# e.g. \begin{enumerate} \item[(1)] one \item two \end{enumerate} will 11197# not produce the same bullets as in the dvi output. 11198sub do_env_itemize { 11199 local($_) = @_; 11200 $itemize_level++; 11201 #RRM - catch nested lists 11202 &protect_useritems($_); 11203 $_ = &translate_environments($_); 11204 11205 local($bullet,$bulletx)=(' ',''); 11206 SWITCH: { 11207 if ($itemize_level==1) { $bulletx = "\\bullet"; last SWITCH; } 11208 if ($itemize_level==2) { $bulletx = "\\mathbf{\\circ}"; last SWITCH; } 11209 if ($itemize_level==3) { $bulletx = "\\mathbf{\\ast}"; last SWITCH; } 11210 } 11211 $itemize_level--; 11212 11213 if (/\s*$item_description_rx/) { 11214 # Contains user defined optional labels 11215 $bulletx = &do_cmd_mbox("${O}1$C\$$bulletx\$${O}1$C") if $bulletx; 11216 &do_env_description($_, " COMPACT", $bullet.$bulletx) 11217 } else { &list_helper($_,'UL'); } 11218 } 11219 11220sub do_env_enumerate { 11221 local($_) = @_; 11222# Reiner Miericke provided the main code; integrated by RRM: 14/1/97 11223# works currently only with 'enumerate' and derived environments 11224# explicit styled labels are computed for each \item 11225# ultimately the environment is done as: &do_env_description($_, " COMPACT") 11226 ++$enum_level; 11227 local(%enum) = %enum; # to allow local changes 11228# Reiner: \begin{enumerate}[<standard_label>] 11229 local($standard_label) = ""; 11230 local(@label_fields); 11231 local($label_func, $preitems, $enum_type); 11232 local($rlevel) = &froman($enum_level); # e.g. 3 => iii 11233 11234 # \begin{enumerate}[$standard_label] 11235 if (s/^$standard_label_rx//s) { # multiline on/off ? 11236 # standard label should be used later to modify 11237 # entries in %enum 11238 $standard_label = $1; # save the standard label 11239# s/^$standard_label_rx//; # and cut it off 11240 $standard_label =~ s/([\\\[\]\(\)])/\\$1/g; # protect special chars 11241 11242 # Search for [aAiI1] which is not between a pair of { } 11243 # Other cases like "\theenumi" are not handled 11244 @label_fields = $standard_label =~ /$enum_label_rx/; 11245 if (($standard_label =~ /^[aAiI1]$/)&&(not(/item\s*\[/))) { 11246 $enum_type = ' TYPE="'.$standard_label.'"'; 11247 $standard_label = ''; 11248 } else { 11249 $label_func = $enum_label_funcs{$label_fields[$#label_fields-1]} . 11250 "(\'enum" . $rlevel . "\')"; 11251 $enum{'theenum' . $rlevel} = "\&$label_func"; 11252# local($thislabel) = "\&$label_func"; 11253# do { local($_) = $thislabel; &make_unique($_); 11254# $enum{'theenum' . $rlevel} = $_; }; 11255 $standard_label = 11256 "\"$label_fields[0]\" . eval(\$enum{\"theenum$rlevel\"})" 11257 . ".\"$label_fields[$#label_fields]\""; 11258 $enum{'labelenum' . $rlevel} = $standard_label; 11259 } 11260 } elsif (s/^((.|\n)+?)\\item/$preitems=$1;"\\item"/es) { 11261 my $pre_preitems; local($cmd); $label_part; 11262 my $num_styles = join('|', values %enum_label_funcs ); 11263 while ($preitems =~ 11264 /\s*\\renew(ed)?command\s*(($O|$OP)\d+($C|$CP))\\?((label|the)enum(\w+))\s*\2/) { 11265 # this catches one \renewcommand{\labelenum}{....} 11266 $pre_preitems .= $`; $preitems = $'; $cmd = $5; 11267 &missing_braces unless ( 11268 ($preitems=~s/$next_pair_pr_rx\s*/$label_part=$2;''/oe) 11269 ||($preitems=~s/$next_pair_rx\s*/$label_part=$2;''/oe)); 11270 $cmd =~ s/^label/the/; 11271 $label_part=~s/\\($num_styles)\s*(($O|$OP)\d+($C|$CP))(\w+)\2/".\&$1\(\'$5\'\)."/g; 11272 $label_part = '"'.$label_part.'"'; 11273 $enum{$cmd} = $label_part; 11274 } 11275 $standard_label = 11276 "\"$label_fields[0]\" . eval(\$enum{\"theenum$rlevel\"})" 11277 . ".\"$label_fields[$#label_fields]\"" if ($cmd); 11278 $_ = $pre_preitems . $preitems . $_ if ($pre_preitems||$preitems); 11279 } else { 11280 @enum_default_type = ('A', '1', 'a', 'i', 'A') unless (@enum_default_type); 11281 $enum_type = $enum_level%4; 11282 $enum_type = ' Type="'.@enum_default_type[$enum_type].'"'; 11283 } 11284 11285 # enclose contents of user-defined labels within a group, 11286 # in case of style-change commands, which could bleed outside the label. 11287 &protect_useritems($_); 11288 $_ = &translate_environments($_); #catch nested lists 11289 11290 local($enum_result); 11291 if (($standard_label)||(/\\item\[/)) { 11292 # split it into items 11293 @items = split(/\\item\b/,$_); 11294 # save anything (non-blank) before the items actually start 11295 $preitems = shift(@items); 11296 $preitems =~ s/^\s*$//; 11297 local($enum_label); 11298 # prepend each item with an item label: \item => \item[<label>] 11299 foreach $item (@items) { 11300# unless ( $item =~ /^\s*$/ ) { # first line may be empty 11301 $enum{"enum" . $rlevel}++; # increase enumi 11302 $enum_label = eval("$enum{'labelenum' . $rlevel}"); 11303 # insert a label, removing preceding space, BUT... 11304 # do NOT handle items with existing labels 11305 $item =~ s/^\s*//; 11306 if ($item =~ s/^\s*\[([^]]*)\]//) { 11307 $enum{"enum" . $rlevel}--; 11308 $enum_label = "$1"; 11309 local($processed) = ($enum_label =~/$OP/); 11310 $enum_label = join('',($processed ? "<#0#>" : "<<0>>") 11311 ,$enum_label ,($processed ? "<#0#>" : "<<0>>")) 11312 if ($enum_label =~ /\\/); 11313 if ($processed) { &make_unique_p($enum_label) } 11314 elsif ($enum_label =~ /$O/) { &make_unique($enum_label) }; 11315 $item = "[${enum_label}]".$item; 11316 } else { 11317 local($processed) = ($enum_label =~/$OP/); 11318 $enum_label = join('',($processed ? "<#0#>" : "<<0>>") 11319 ,$enum_label ,($processed ? "<#0#>" : "<<0>>")) 11320 if ($enum_label =~ /\\/); 11321 if ($processed) { &make_unique_p($enum_label) } 11322 elsif ($enum_label =~ /$O/) { &make_unique($enum_label) }; 11323 $item = "[$enum_label\]$item"; 11324 $enum_label =~ s/\.$//; 11325 } 11326 if ($standard_label) { 11327 $item =~ s/(\\labelitem$rlevel|$standard_label)/$enum_label/g 11328 } else { 11329 $item =~ s/(\\labelitem$rlevel)/$enum_label/g 11330 } 11331 }; 11332 $_ = join("\\item ", $preitems, @items); 11333 11334 # Original, but $enum_result 11335 $enum_result = &do_env_description($_, " COMPACT"); 11336 } else { 11337 $enum_result = &list_helper($_, "OL$enum_type", '', ''); 11338 } 11339 11340 #clean-up and revert the $enum_level 11341 $enum{"enum" . $rlevel} = 0; 11342 $enum{"enum" . &froman($enum_level)} = 0; 11343 --$enum_level; 11344 $enum_result; 11345 } 11346 11347sub do_env_list { 11348 local ($_) = @_; 11349 local ($list_type,$labels,$lengths) = ('UL','',''); 11350 11351 $labels = &missing_braces unless ( # get the label specifier 11352 (s/$next_pair_pr_rx/$labels=$2;''/e) 11353 ||(s/$next_pair_rx/$labels=$2;''/e)); 11354 11355 $lengths = &missing_braces unless ( # get the length declarations 11356 (s/$next_pair_pr_rx/$lengths=$2;''/e) 11357 ||(s/$next_pair_rx/$lengths=$2;''/e)); 11358 # switch to enumerated style if they include a \usecounter. 11359 $list_type = 'OL' if $lengths =~ /\\usecounter/; 11360 11361 /\\item\b/; local($preitems) = $`; 11362 $_ =~ s/^\Q$preamble//s if ($preitems); 11363 $preitems =~s/^\s*|\s*$//g; 11364 if ($preitems) { 11365 $preitems = &translate_environments($preitems); 11366 $preitems = &translate_commands($preitems) if ($preitems =~ /\\/); 11367# &write_warnings("\nDiscarding: $preitems before 1st item in list") 11368# if ($preitems); 11369 } 11370 11371 #RRM - catch nested lists 11372 #RRM unfortunately any uses of the \\usecounter within \item s 11373 # may be broken --- sigh. 11374 &protect_useritems($_); 11375 $_ = &translate_environments($_); 11376 11377 if (($list_type =~ /OL/)&&($labels)) { 11378 local($br_ida,$br_idb,$label,$aft); 11379 $br_ida = ++$global{'max_id'}; 11380 $lengths =~ s/\\usecounter((($O|$OP)\d+($C|$CP))[^<]+\2)/ 11381 &make_nowrapper(1)."\\stepcounter$1".&make_nowrapper(0)/e; 11382 $labels = "$O$br_ida$C$lengths$O$br_ida$C".$labels; 11383 11384# s/\\item\b\s*([^\[])/do { 11385# $label = $labels; $aft = $1; 11386# $br_id = ++$global{'max_id'}; 11387# $label = &translate_environments( 11388# "$O$br_id$C$label$O$br_id$C"); 11389# join('',"\\item\[" , $label, "\]$aft" ); 11390# }/eg; 11391# $labels =''; 11392 } 11393 11394 if (($labels)||(/\\item\[/)) { 11395 $_ = &list_helper($_, 'DL', $labels, $lengths) 11396 } else { 11397 $_ = &list_helper($_, $list_type, '', $lengths) 11398 } 11399 $_; 11400} 11401 11402sub do_env_trivlist { 11403 local($_) = @_; 11404 local($compact,$item_sep,$pre_items) = ' COMPACT'; 11405 &protect_useritems($_); 11406 11407 # assume no styles initially for this list 11408 local($close_tags,$reopens) = &close_all_tags(); 11409 local($open_tags_R) = []; 11410 local(@save_open_tags) = (); 11411 11412 # include \label anchors from [...] items 11413 s/$item_description_rx\s*($labels_rx8)?\s*/ 11414 (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."\n"/eg; 11415 # remove unwanted space before \item s 11416 s/[ \t]*\\item\b/\\item/g; 11417 11418 local($this_item,$br_id) = ('',''); 11419 local($this_sitem,$this_eitem) = ("\n<P>","</P>\n",''); 11420 11421 # assume no sub-lists, else... why use {trivlist} ? 11422 # extract up to the 1st \item 11423 local(@items) = split(/\\item\b/, $_); 11424 $pre_items = shift @items; 11425 $_ = ''; 11426 while (@items) { 11427 $br_id = ++$global{'max_id'}; 11428 $this_item = shift @items; 11429 $this_item = &translate_environments( 11430 "$O$br_id$C".$pre_items.$this_item."$O$br_id$C" ); 11431 if ($this_item =~ /\\/) { 11432 $this_item = &translate_commands($this_item); 11433 $_ .= join('' , $this_sitem 11434 , $this_item 11435 # , $this_eitem 11436 ) 11437 } else { $_ .= $this_sitem . $this_item } 11438 } 11439 11440 $_ = &translate_environments($_); 11441 $_ = &translate_commands($_); 11442 11443 join('' , $close_tags , $_ , $reopens); 11444 11445} 11446 11447# enclose the contents of any user-defined labels within a group, 11448# else any style-change commands may bleed outside the label. 11449sub protect_useritems { 11450 # MRO: use $_[0] instead: local(*_) = @_; 11451 local($preitems, $thisitem); 11452 $_[0] =~ s/^$par_rx\s*//s; # discard any \par before 1st item 11453 11454 # locate \item with optional argument 11455 local($saveRS) = $/; undef $/; 11456 local(@preitems); 11457 # allow one level of nested [] 11458 # MRO: Caution! We have a double-wildcarded RX here, this may cause 11459 # trouble. Should be re-coded. 11460 $_[0] =~ s/\\item[\s\r]*(\b(\[(([^\[\]]|\[[^]]*\])*)\])?|[^a-zA-Z\s])/ 11461 $thisitem = " $1"; 11462 if ($2) { 11463 $br_id = ++$global{'max_id'}; 11464 $thisitem = '['.$O.$br_id.$C.$3.$O.$br_id.$C.']'; 11465 }; 11466 "\\item".$thisitem 11467 /egm; 11468 11469 $/ = $saveRS; 11470 $_[0] = join(@preitems, $_[0]); 11471} 11472 11473sub do_env_description { 11474 local($_, $compact, $bullet) = @_; 11475 #RRM - catch nested lists 11476 &protect_useritems($_); 11477 $_ = &translate_environments($_) unless ($bullet); 11478 11479 # MRO: replaced $* with /m 11480 $compact = "" unless $compact; 11481 if ($compact) { # itemize/enumerate with optional labels 11482 s/\n?$item_description_rx\s*($labels_rx8)?\s*/"\n<\/DD>\n<DT>". 11483 (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."<\/DT>\n<DD>"/egm; 11484 } else { 11485 s/\n?$item_description_rx\s*($labels_rx8)?\s*/"\n<\/DD>\n<DT>". 11486 (($9)? "<A NAME=\"$9\"><STRONG>$1<\/STRONG><\/A>" 11487 : "<STRONG>$1<\/STRONG>") ."<\/DT>\n<DD>"/egm; 11488 } 11489 # and just in case the description is empty ... 11490#JCL(jcl-del) - $delimiter_rx -> ^$letters 11491 s/\n?\\item\b\s*([^$letters\\]|)\s*/\n<\/DD>\n<DT>$bullet<\/DT>\n<DD>$1/gm; 11492 s/^\s+//m; 11493 11494 $_ = '<DD>'.$_ unless ($_ =~ s/^\s*<\/D(T|D)>\n?//s); 11495 $_ =~ s/\n$//s; 11496 "<DL$compact>\n$_\n</DD>\n</DL>"; 11497} 11498 11499sub list_helper { 11500 local($_, $tag, $labels, $lengths) = @_; 11501 local($item_sep,$pre_items,$compact,$etag,$ctag); 11502 $ctag = $tag; $ctag =~ s/^(.*)\s.*$/$1/; 11503 11504 # assume no styles initially for this list 11505 local($close_tags,$reopens) = &close_all_tags(); 11506 local($open_tags_R) = []; 11507 local(@save_open_tags) = (); 11508 11509# #RRM: cannot have anything before the first <LI> 11510# local($savedRS) = $/; $/=''; 11511# $_ =~ /\\item[\b\r]/s; 11512# if ($`) { 11513# $preitems = $`; $_ = $&.$'; 11514# $preitems =~ s/<P( [^>]*)?>//g; 11515# $close_tags .= "\n".$preitems if $preitems; 11516# } 11517# $/ = $savedRS; 11518# 11519 11520 if (($tag =~ /DL/)&&$labels) { 11521 local($label,$aft,$br_id); 11522 s/\\item\b[\s\r]*([^\[])/do { 11523 $label = $labels; $aft = $1; 11524 $br_id = ++$global{'max_id'}; 11525 $label = &translate_environments( 11526 "$O$br_id$C$label$O$br_id$C"); 11527 join('',"\\item\[" , $label, "\]$aft" ); 11528 }/egm; 11529 } 11530 11531 # This deals with \item[xxx] ... 11532 if ($tag =~ /DL/) { 11533 $compact = ' COMPACT'; 11534 # include \label anchors in the <DT> part 11535 # and $pre_item tags in the <DD> part: 11536 if ($labels && $lengths) { 11537 $item_sep = "\n</DD>\n<DT>"; 11538 } else { 11539 $item_sep = ($labels ? "<DT>$labels\n" : '') ."</DT>\n<DD>"; 11540 } 11541 $etag = "\n</DD>"; 11542 s/$item_description_rx[\r\s]*($labels_rx8)?[\r\s]*/"<DT>" . 11543 (($9)? "<A NAME=\"$9\">$1<\/A>" : $1 ) ."\n<DD>"/egm; 11544 } else { 11545 $item_sep = "\n</LI>\n<LI>"; 11546 $etag = "\n</LI>"; 11547 } 11548 11549 # remove unwanted space before \item s 11550 s/[ \t]*\\item\b/\\item/gm; 11551 11552 #JCL(jcl-del) - $delimiter_rx -> ^$letters 11553 s/\n?\\item\b[\r\s]*/$item_sep/egm; 11554 11555 #RRM: cannot have anything before the first <LI> 11556 local($savedRS) = $/; $/=''; 11557 $_ =~ /\Q$item_sep\E|<DT>|<LI>/s; 11558 #RRM: ...try putting it before the list-open tag 11559 if ($`) { 11560 $preitems = $`; $_ = $&.$'; 11561 $preitems =~ s/<P( [^>]*)?>//gm; 11562 $close_tags .= "\n".$preitems if $preitems; 11563 } 11564 $_ =~ s/^\s*<\/[^>]+>\s*//s; 11565 11566 # remove \n from end of the last item 11567 $_ =~ s/\n$//s; 11568 $/ = $savedRS; 11569 11570 join('' , $close_tags , "\n<$tag$compact>\n" 11571 , $_ , "$etag\n</$ctag>" , $reopens); 11572 } 11573 11574 11575# RRM: A figure environment generates a picture UNLESS it contains a 11576# {makeimage} sub-environment; in which case it creates a <DIV> 11577# inside which the contents are interpreted as much as is possible. 11578# When there are captions, this modifies $before . 11579sub do_env_figure { 11580 local($_) = @_; 11581 local($halign, $anchors) = ('CENTER',''); 11582 local ($border, $attribs ); 11583 local($cap_width) = $cap_width; 11584 my ($opt, $dummy) = &get_next_optional_argument; 11585 11586 my $abovedisplay_space = $ABOVE_DISPLAY_SPACE||"<P></P>\n"; 11587 my $belowdisplay_space = $BELOW_DISPLAY_SPACE||"<P></P>\n"; 11588 11589 ($_,$anchors) = &extract_labels($_); # extract labels 11590 # Try to establish the alignment 11591 if (/^(\[[^\]]*])?\s*\\begin\s*<<\d*>>(\w*)<<\d*>>|\\(\w*)line/) { 11592 $halign = $2.$3; 11593 if ($halign =~ /right/i) { $halign = 'RIGHT' } 11594 elsif ($halign =~ /left/i) { $halign = 'LEFT' } 11595 elsif ($halign =~ /center/i) { $halign = 'CENTER' } 11596 else { $halign = 'CENTER' } 11597 } 11598 11599 # allow caption-alignment to be variable 11600 local($cap_align); 11601 if ($FIGURE_CAPTION_ALIGN =~ /^(TOP|BOTTOM|LEFT|RIGHT)/i) { 11602 $cap_align = join('', ' ALIGN="', $&, $','"')}; 11603 11604 local($cap_env, $captions,$has_minipage) = ('figure',''); 11605 if ((/\\begin\s*($O\d+$C)\s*(makeimage|minipage)\s*\1|\\docode/)|| 11606 (/\\includegraphics/&&(!/$htmlborder_rx|$htmlborder_pr_rx|\\htmlimage/))){ 11607 $has_minipage = ($2 =~ /minipage/sg ); 11608 $_ = &translate_environments($_); 11609 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11610 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11611 do { local($contents) = $_; 11612 &extract_captions($cap_env); $_ = $contents; 11613 } if (/\\caption/); 11614 $_ = &translate_commands($_); 11615 while ($_ =~ s/(^\s*<BR>\s*|\s*<BR>\s*$)//sg){}; # remove unneeded breaks 11616 } else { 11617 do { local($contents) = $_; 11618 # MRO: no effect: &extract_captions($cap_env, *cap_width); $_ = $contents; 11619 &extract_captions($cap_env); $_ = $contents; 11620 } if (/\\caption/); 11621 # Generate picture of the whole environment 11622 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11623 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11624 $_ = &process_undefined_environment($env, $id, $_); 11625 $_ = &post_latex_do_env_figure($_); 11626 $_ =~ s/\s*<BR>\s*$//g; 11627 } 11628 11629 if ($captions) { 11630 # MRO: replaced $* with /m 11631 $captions =~ s/^\n//m; 11632 $captions =~ s/\n$//m; 11633 } 11634 s/$caption_mark//g; 11635 11636 local($close_tags) = &close_all_tags; 11637 $_ .= $close_tags; 11638 11639 # place all the pieces inside a TABLE, if available 11640 if ($HTML_VERSION > 2.1) { 11641 if ($captions) { 11642 local($pxs,$len) = &convert_length($cap_width,$MATH_SCALE_FACTOR) 11643 if $cap_width; 11644 local($table) = "<TABLE$env_id"; # WIDTH="65%"'; 11645 $table .= " WIDTH=\"$pxs\"" if ($pxs); 11646 if ($border) { $table .= " BORDER=\"$border\"" } # no checking !! 11647 $table .= ">"; 11648 s/^\s*|\s*$//g; 11649 join ('' 11650 , $above_display_space 11651 , "\n<DIV", ($halign ? " ALIGN=\"$halign\"" :'') 11652 , '>', $anchors , $cap_anchors 11653 , "\n$table\n<CAPTION", $cap_align, '>' 11654 , $captions , "</CAPTION>\n<TR><TD>" 11655 , ($cap_width ? '</TD><TD>' : '') 11656 , $_ , '</TD>' 11657 , ($cap_width ? '<TD></TD>' : '') 11658 , "</TR>\n</TABLE>\n</DIV>\n" 11659 , $below_display_space 11660 ) 11661 } elsif ($halign) { 11662 if ($border||($attributes)||$env_id) { 11663 &make_table( $border, $attribs, $anchors, '', $halign, $_ ); 11664 } else { 11665 join ('' 11666 , $above_display_space 11667 , "\n<DIV ALIGN=\"$halign\">\n" 11668 , ($anchors ? "\n<P>$anchors</P>" : '') 11669 , $_ 11670 , "\n</DIV>" 11671 , $below_display_space 11672 ) 11673 } 11674 } else { 11675 if ($border||($attributes)||$env_id) { 11676 join ('' 11677 , $above_display_space 11678 , "\n<DIV", ($halign ? " ALIGN=\"$halign\"":'') 11679 , '>' 11680 , &make_table( $border, $attribs, $anchors, '', $halign, $_ ) 11681 , "\n</DIV><BR" 11682 , (($HTML_VERSION > 3.1)? " CLEAR=\"ALL\"" :'') 11683 , '>' 11684 , $below_display_space 11685 ); 11686 } else { 11687 join ('' 11688 , $above_display_space 11689 , "\n<DIV", ($halign ? " ALIGN=\"$halign\"":'') 11690 , ">$anchors\n" , $_ , "\n</DIV><BR" 11691 , (($HTML_VERSION > 3.1)? " CLEAR=\"ALL\"" :'') 11692 , '>' 11693 , $below_display_space 11694 ); 11695 } 11696 } 11697 } else { 11698 # MRO: replaced $* with /m 11699 s/^\n//m; 11700 s/\n$//m; 11701 if ($captions) { 11702 join('', "\n<BR>\n", (($anchors) ? "$anchors" : '') 11703 , "$cap_anchors\n$captions\n<BR>" 11704 , "\n<P", ($halign ? " ALIGN=\"$halign\"":'') 11705 , '>', $_ , "\n</P>"); 11706 } elsif ($halign) { 11707 join ('', "<BR>\n$anchors", $_ , "\n<BR>" ) 11708 } else { 11709 join('', "<BR>\n<P", ($halign ? " ALIGN=\"$halign\"":'') 11710 , ">$anchors\n" , $_ , "\n</P><BR>"); 11711 } 11712 } 11713} 11714 11715sub do_env_figurestar { &do_env_figure(@_) } 11716 11717sub do_env_table { 11718 local($_) = @_; 11719 local($halign, $anchors) = ('',''); 11720 local ( $border, $attribs ); 11721 &get_next_optional_argument; 11722 11723 # Try to establish the alignment 11724 if (/^(\[[^\]]*])?\s*\\begin\s*<<\d*>>(\w*)<<\d*>>|\\(\w*)line/) { 11725 $halign = $2.$3; 11726 if ($halign =~ /right/i) { $halign = 'RIGHT' } 11727 elsif ($halign =~ /left/i) { $halign = 'LEFT' } 11728 elsif ($halign =~ /center/i) { $halign = 'CENTER' } 11729 else { $halign = '' } 11730 } 11731 11732 local($cap_env, $captions) = ('table',''); 11733 11734 # allow caption-alignment to be variable 11735 local($cap_align); 11736 if ($TABLE_CAPTION_ALIGN =~ /^(TOP|BOTTOM|LEFT|RIGHT)/i) { 11737 $cap_align = join('', ' ALIGN="', $&, $','"')}; 11738 11739 if ((/\\(begin|end)\s*($O\d+$C)\s*makeimage\s*\2/)|| 11740 ($HTML_VERSION > 2.0 && ( 11741 /\\begin\s*($O\d+$C)\s*((super)?tabular|longtable)\s*\1/))) { 11742 $_ = &translate_environments($_); 11743 ($_,$anchors) = &extract_labels($_); # extract labels 11744 do { local($contents) = $_; 11745 &extract_captions($cap_env); $_ = $contents; 11746 } if (/\\caption/); 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 $_ = &translate_commands($_); 11750 while ($_ =~ s/(^\s*<BR>\s*|\s*<BR>\s*$)//g){}; 11751 } else { 11752 # Make an image of the whole environment. 11753 ($_,$anchors) = &extract_labels($_); # extract labels 11754 do { local($contents) = $_; 11755 &extract_captions($cap_env); $_ = $contents; 11756 } if (/\\caption/); 11757 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11758 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11759 $_ = &process_undefined_environment($env, $id, $_); 11760 $_ = &post_latex_do_env_table($_); 11761 $_ =~ s/\s*<BR>\s*$//g; 11762 } 11763 11764 if ($captions) { 11765 # MRO: replaced $* with /m 11766 $captions =~ s/^\n//m; 11767 $captions =~ s/\n$//m; 11768 } 11769 s/$caption_mark//g; 11770 11771 local($close_tags) = &close_all_tags; 11772 $_ .= $close_tags; 11773 11774 # when $captions remain place all the pieces inside a TABLE, if available 11775 if ($HTML_VERSION > 2.1) { 11776 if ($captions) { 11777 $halign = 'CENTER' unless $halign; 11778 local($table) = '<TABLE'; 11779 if ($border) { $table .= " BORDER=\"$border\"" } # no checking !! 11780 $table .= ">"; 11781 join ('', "<BR><P></P>\n<DIV$env_id ALIGN=\"$halign\">" 11782 , "$anchors$cap_anchors\n$table\n<CAPTION", $cap_align, '>' 11783 , $captions , "</CAPTION>\n<TR><TD>" 11784 , $_ , "</TD></TR>\n</TABLE>\n</DIV><P></P><BR>" ) 11785 } elsif ($halign) { 11786 if ($halign) { 11787 # MRO: replaced $* with /m 11788 s/^\s*(<(P|DIV)$env_id ALIGN=\"\w+[^>]+>)/$1$anchors/m 11789 if ($anchors); 11790 join('', "<BR>", $_, "\n<BR>" ) 11791 } else { 11792 join ('', "<BR>\n$anchors", $_ , "\n<BR>" ) 11793 } 11794 } else { 11795 join ('', "<BR><P></P>\n<DIV$env_id ALIGN=\"CENTER\">$anchors\n", $_ , "\n</DIV><BR>" ) 11796 } 11797 } else { 11798 # MRO: replaced $* with /m 11799 s/^\n//m; 11800 s/\n$//m; 11801 if ($captions) { 11802 join('', "<BR>\n", (($anchors) ? "$anchors" : ''), "$cap_anchors\n$captions\n<BR>" 11803 , "\n<P ALIGN=\"$halign\">", $_, "\n</P><BR>"); 11804 } elsif ($halign) { 11805 join ('', "<BR><P></P>\n$anchors", $_ , "\n<P></P>" ) 11806 } else { 11807 join('', "<BR>\n<P ALIGN=\"CENTER\">$anchors\n", $_, "\n</P><BR>"); 11808 } 11809 } 11810} 11811 11812sub do_env_tablestar { &do_env_table(@_) } 11813 11814# RRM: A makeimage environment generates a picture of its entire contents, 11815# UNLESS it is empty. 11816# 11817sub do_env_makeimage { 11818 local($_) = @_; 11819 local($attribs, $border); 11820 s/^\s*//; 11821 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11822 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11823 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") } 11824 if (/^(\s\%?\n)+$/s) { return() } 11825 $_ = &process_undefined_environment($env, $id, $_); 11826 if (($border||($attributes))&&($HTML_VERSION > 2.1 )) 11827 { $_ = &make_table( $border, $attribs, '', '', '', $_ ) } 11828 $_ . ((!$_=~/^\s*$/)? "\n<BR>\n" :''); 11829 } 11830 11831sub do_env_abstract { &make_abstract($_[0]) } 11832 11833sub do_env_minipage { 11834 local($_) = @_; 11835 &get_next_optional_argument; 11836 local($width); 11837 $width = &missing_braces unless ( 11838 (s/$next_pair_pr_rx/$width=$2;''/e) 11839 ||(s/$next_pair_rx/$width=$2;''/e)); 11840 local($pxs,$len) = &convert_length($width,$MATH_SCALE_FACTOR) if $width; 11841 $width = " WIDTH=\"$pxs\""; 11842 11843 local ( %mpfootnotes, $mpfootnotes ) unless ($MINIPAGE); 11844 local ( $border, $attribs, $footfile); 11845 $global{'mpfootnote'} = 0 unless ($MINIPAGE); 11846 $MINIPAGE++; 11847 print "\n *** doing minipage *** " if ($VERBOSITY > 1); 11848 local($open_tags_R) = [ @$open_tags_R ]; 11849 local($close_tags,$reopens) = &close_all_tags(); 11850 local(@save_open_tags) = @$open_tags_R; 11851 11852 local($minipage_caption) if $cap_env; 11853 if ($cap_env &&($HTML_VERSION>2.1)) { 11854 do { 11855 local($captions); 11856 local($contents) = $_; 11857 &extract_captions($cap_env) if ($_ =~ /\\caption/m); 11858 $minipage_caption = $captions; 11859 $_ = $contents; 11860 undef $contents; undef $captions; 11861 }; 11862 } 11863 11864 if (s/^\s*$htmlborder_rx//so) { 11865 $attribs = $2; $border = (($4)? "$4" : 1) 11866 } elsif (s/^\s*$htmlborder_pr_rx//so) { 11867 $attribs = $2; $border = (($4)? "$4" : 1) 11868 } 11869 if (/^\s*\\/) { 11870 local($tmp) = ++$global{'max_id'}; 11871 $_ = $O.$tmp.$C.$_.$O.$tmp.$C 11872 } 11873 $_ = &translate_environments($_); 11874 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11875 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 11876 $_ = &translate_commands($_); 11877 $MINIPAGE--; $MINIPAGE='' if ($MINIPAGE==0); 11878 11879 $_ .= &balance_tags(); 11880 $attribs .= $width unless ($attribs =~ /WIDTH/i); 11881# if (($border||$attribs)&&$MINIPAGE&&($HTML_VERSION>2.1)) { 11882 if (($border||$attribs||$env_id)&&$MINIPAGE&&($HTML_VERSION>2.1)) { 11883 $_ = &make_table( $border, $attribs, '', '', '', $_ ); 11884 } elsif ($MINIPAGE) { 11885 $_ = join ('', '<BR><HR>', $_ , '<BR><HR><BR>' ); 11886 } elsif (($border||($attribs)||$minipage_caption)&&($HTML_VERSION > 2.1 )) { 11887 $mpfootnotes = '<DL>'.$mpfootnotes.'</DL>' if $mpfootnotes; 11888 $_ = &make_table( $border, $attribs, '', $mpfootnotes, '', $_ ); 11889 $_ = join('','<BR><HR' 11890 , (($HTML_VERSION > 3.0)? ' WIDTH="50\%" ALIGN="CENTER"' : '') 11891 , '>', $_ , '<BR><HR' 11892 , (($HTML_VERSION > 3.0)? ' WIDTH="50\%" ALIGN="CENTER"' : '') 11893 , '><BR>') unless ($border||$attribs||$mpfootnotes); 11894 } else { 11895 $global{'mpfootnote'} = 0; 11896 if ($mpfootnotes) { 11897 $mpfootnotes = '<DD>'.$mpfootnotes unless ($mpfootnotes =~ /^\s*<D(T|D)>/); 11898 $_ = join('','<BR><HR>', $_ , '<BR><HR' 11899 , (($HTML_VERSION > 3.0)? ' WIDTH="200" ALIGN="LEFT"' : '') 11900 , '><DL>', $mpfootnotes , '</DL><HR><BR' 11901 , (($HTML_VERSION > 3.0)? ' CLEAR="all"' : '') 11902 , '>' ); 11903 } else { 11904 $_ = join ('', '<BR><HR><P></P>', $_ , '<BR><HR><BR>' ); 11905 } 11906 } 11907 join('', $close_tags, $_, $reopens); 11908} 11909 11910if (($HTML_VERSION > 2.1)&&($HTML_VERSION < 4.0)) { 11911 $TABLE_attribs = ",ALIGN,"; 11912 $TABLE__ALIGN = ",left,right,center,"; 11913 $TABLE_attribs_rx_list = ",CELLPADDING,BORDER,WIDTH,CELLSPACING,"; 11914 $TABLE__WIDTH_rx = "\^\\d+%?"; 11915 $TABLE__BORDER_rx = $TABLE__CELLSPACING_rx = $TABLE__CELLPADDING_rx = "\^\\d+"; 11916} 11917 11918sub make_table { 11919 local($border, $attribs, $anchors, $extra_cell, $halign, $_) = @_; 11920 local($table,$caption,$div,$end,$Tattribs); 11921 $caption = join('',"<CAPTION$cap_align>" 11922 , $minipage_caption 11923 ,'</CAPTION>') if ($minipage_caption); 11924 $end = "</TD></TR>\n</TABLE>"; 11925 $table = join('', "<TABLE$env_id" 11926 , ((($caption)&&!($attribs =~/WIDTH/i)) ? " WIDTH=\"100\%\"" : '') 11927 , ((($border)&&!($attribs =~/BORDER/i)) ? " BORDER=\"$border\"" : '') 11928 ); 11929 if ($attribs) { 11930 if (!($attribs =~ /=/)) { 11931 $Tattribs = &parse_valuesonly($attribs,"TABLE"); 11932 } else { 11933 $Tattribs = &parse_keyvalues($attribs,"TABLE"); 11934 } 11935 $table .= " $Tattribs" if ($Tattribs); 11936 } 11937 print STDOUT "\nTABLE: $table>" if ($VERBOSITY >2 ); 11938 $table .= ">".$caption."\n<TR><TD>"; 11939 if ($extra_cell) { 11940 local($sep) = "</TD></TR>\n<TR ALIGN=\"LEFT\">\n<TD>"; 11941 join ('', $div, $anchors, $table, $_ , $sep, $extra_cell, $end ); 11942 } else { 11943 join ('', $div, $anchors, $table, $_ , $end ); 11944 } 11945} 11946 11947sub do_cmd_etalchar { 11948 local($_) = @_; 11949 my $etalchar; 11950 $etalchar = &missing_braces unless ( 11951 (s/$next_pair_pr_rx/$etalchar = $2;''/eo) 11952 ||(s/$next_pair_rx/$etalchar = $2;''/eo)); 11953 $etalchar = &translate_commands($etalchar) if ($etalchar =~ /\\/); 11954 if ($HTML_VERSION < 3.0) { 11955 $etalchar = &process_in_latex("\$^\{$etalchar\}\$"); 11956 } else { 11957 $etalchar = '<SUP>'.$etalchar.'</SUP>'; 11958 } 11959 $etalchar . $_ 11960} 11961 11962sub do_env_thebibliography { 11963 # Sets $citefile and $citations defined in translate 11964 local($_) = @_; 11965 $bibitem_counter = 0; 11966 $citefile = $CURRENT_FILE; 11967 $citefiles{$bbl_nr} = $citefile; 11968 local($dummy,$title); 11969 $dummy = &missing_braces unless ( 11970 (s/$next_pair_pr_rx/$dummy=$2;''/e) 11971 ||(s/$next_pair_rx/$dummy=$2;''/e)); 11972 # MRO: replaced $* with /m 11973 s/^\s*$//gm; # Remove empty lines (otherwise will have paragraphs!) 11974 s/^\s*//m; 11975 11976 # Replace non-breaking spaces, particularly in author names. 11977# s/([^\\])~/$1 /g; # Replace non-breaking spaces. 11978 11979 $_ = &translate_environments($_); 11980 $_ = &translate_commands($_); 11981 11982 # RRM: collect all anchors from initial \label and \index commands 11983 local($anchors) = &extract_anchors('',1); 11984 $_ = '<DD>'.$_ unless ($_ =~ /^\s*<D(T|D)>/); 11985 $citations = join('',"<DL COMPACT>", $_, "</DL>"); 11986 $citations{$bbl_nr} = $citations; 11987 local($br_id); 11988 if ((defined &do_cmd_bibname)||$new_command{'bibname'}) { 11989 $br_id=++$global{'max_id'}; 11990 $title = &translate_environments("$O$br_id$C\\bibname$O$br_id$C"); 11991 } else { $title = $bib_title } 11992 if (! $title ) { 11993 if ((defined &do_cmd_refname)||$new_command{'refname'}) { 11994 $br_id=++$global{'max_id'}; 11995 $title = &translate_environments("$O$br_id$C\\refname$O$br_id$C"); 11996 } else { $title = $ref_name } 11997 } 11998 local($closures,$reopens) = &preserve_open_tags(); 11999 $toc_sec_title = $title ; 12000 local $bib_head = $section_headings{'bibliography'}; 12001 $_ = join('', $closures 12002 , &make_section_heading($title, $bib_head, $anchors) 12003 , "$bbl_mark#$bbl_nr#" , $reopens ); 12004 $bbl_nr++ if $bbl_cnt > 1; 12005 $_ =~ s/;SPMnbsp;/ /g; # replace non-breaking spaces with real ones 12006 $_; 12007} 12008# IGNORE - We construct our own index 12009sub do_env_theindex { "" } 12010 12011# This is defined in html.sty 12012sub do_env_comment { "" } 12013 12014 12015sub do_env_equation{ 12016 local($_)=@_; 12017 local($attribs, $border, $no_num); 12018 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 12019 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 12020 if (/\\nonumber/) { 12021 $no_num = 1; 12022 $_ = &process_undefined_environment($env,$id,$_); 12023 } else { 12024 $latex_body .= join('', "\n\\setcounter{equation}{" 12025 , $global{'eqn_number'}, "}\n"); 12026 12027 #include equation-number into the key, with HTML 2.0 12028# $_ = join("\n", "%EQNO:".$global{'eqn_number'}, $_) 12029 $_ .= "%EQNO:".$global{'eqn_number'}."\n" if ($HTML_VERSION < 2.2); 12030 12031 $_ = &process_undefined_environment($env,$id,$_); 12032 $global{'eqn_number'}++; 12033 local($save) = $_; 12034 $_ = join('', $save, &post_latex_do_env_equation($eqno_prefix)); 12035 } 12036 if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 12037 join('',"<BR>\n<DIV$env_id ALIGN=\"CENTER\">\n" 12038 , &make_table( $border, $attribs, '', '', '', $_ ) 12039 , "\n<BR CLEAR=\"ALL\">"); 12040 } elsif ($HTML_VERSION < 2.2 ) { 12041 join('', "\n<P>", $_ , "\n<BR></P>" ) 12042 } elsif ($HTML_VERSION > 2.1 ) { 12043 join('', "\n<P ALIGN=" 12044 , ((!$no_num &&($EQN_TAGS =~ /L/))? 12045 '"LEFT"':($no_num ?'"CENTER"':'"RIGHT"')) 12046 , '>', $_ , "\n<BR></P>" ) 12047 } else { $_ } 12048} 12049 12050sub do_env_eqnarray{ 12051 local($_)=@_; 12052 local($attribs, $border, $no_num); 12053 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 12054 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 12055 local($contents) = $_; 12056# $_ = join("\n", "%EQNO:".$global{'eqn_number'}, $_) 12057# if ($HTML_VERSION < 3.2); #include equation-number into the key. 12058 $_ .= "%EQNO:".$global{'eqn_number'}."\n" if ($HTML_VERSION < 2.2); 12059 $_ = &process_undefined_environment($env,$id,$_); 12060 $_ .= &post_latex_do_env_eqnarray($eqno_prefix,$contents); 12061 if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 12062 join('',"<BR>\n<DIV ALIGN=\"CENTER\">\n" 12063 , &make_table( $border, $attribs, '', '', '', $_ ) 12064 , "\n<BR CLEAR=\"ALL\">"); 12065 } elsif ($HTML_VERSION < 2.2 ) { 12066 join('', "\n<P>", $_ , "\n<BR></P>" ) 12067 } elsif ($HTML_VERSION > 3.1 ) { 12068 join('',"<BR>\n<DIV ALIGN=\"CENTER\">\n", $_ 12069 , "\n</DIV><BR CLEAR=\"ALL\">" ); 12070 } else { 12071 join('', "\n<P ALIGN=" 12072 , (($EQN_TAGS =~ /L/)? '"LEFT"' : '"RIGHT"') 12073 , '>' , $_ , "\n<BR></P>" ) 12074 } 12075} 12076 12077#RRM: these are needed with later versions, when {eqnarray} 12078# environments are split into <TABLE> cells. 12079 12080sub protect_array_envs { 12081 local($_) = @_; 12082 local($cnt, $arraybit, $thisbit, $which) = (0,'','',''); 12083 # MRO: replaced $* with /m 12084 while (/\\(begin|end)\s*(<(<|#)\d+(#|>)>)($sub_array_env_rx)(\*|star)?\2/m ) { 12085 $thisbit = $` . $&; $_ = $'; $which = $1; 12086 do { 12087 # mark rows/columns in nested arrays 12088 $thisbit =~ s/;SPMamp;/$array_col_mark/g; 12089 $thisbit =~ s/\\\\/$array_row_mark/g; 12090 $thisbit =~ s/\\text/$array_text_mark/g; 12091 $thisbit =~ s/\\mbox/$array_mbox_mark/g; 12092 } if ($cnt > 0); 12093 $arraybit .= $thisbit; 12094 if ($which =~ /begin/) {$cnt++} else {$cnt--}; 12095 } 12096 $_ = $arraybit . $_; 12097 12098 local($presub,$thisstack) = ''; 12099 for (;;) { 12100 # find \\s needing protection within \substack commands 12101 # a while-loop is simpler syntax, but uses longer strings 12102 if ( /(\\substack\s*(<(<|#)\d+(#|>)>)(.|\n)*)\\\\((.|\n)*\2)/m ) { 12103 $presub .= $`; $thisstack =$1.${array_row_mark}.$6; $_ = $'; 12104 # convert all \\s in the \substack 12105 $thisstack =~ s/\\\\/${array_row_mark}/og; 12106 $presub .= $thisstack; 12107 } else { last } 12108 } 12109 $_ = $presub . $_ if ($presub); 12110 $_; 12111} 12112 12113sub revert_array_envs { 12114 local($array_contents) = @_; 12115 $array_contents =~ s/$array_col_mark/$html_specials{'&'}/go; 12116 $array_contents =~ s/$array_row_mark/\\\\/go; 12117 $array_contents =~ s/$array_text_mark/\\text/go; 12118 $array_contents =~ s/$array_mbox_mark/\\mbox/go; 12119 $array_contents; 12120} 12121 12122 12123 12124sub do_env_tabbing { 12125 local($_) = @_; 12126 local($attribs, $border); 12127 if (s/$htmlborder_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 12128 elsif (s/$htmlborder_pr_rx//o) { $attribs = $2; $border = (($4)? "$4" : 1) } 12129 $_ = &tabbing_helper($_); 12130 if (/$image_mark/) { 12131 local($tab_warning) = 12132 "*** Images are not strictly valid within HTML <pre> tags\n" 12133 . "Please change your use of {tabbing} to a {tabular} environment.\n\n"; 12134 &write_warnings("\n".$tab_warning); 12135 print "\n\n **** invalid tabbing environment ***\n"; 12136 print $tab_warning; 12137 } 12138 if (($border||($attribs))&&($HTML_VERSION > 2.1 )) { 12139 join('',"<BR>\n<DIV$env_id ALIGN=\"CENTER\">\n" 12140 , &make_table( $border, $attribs, '', '', '', $_ ) 12141 , "\n</DIV><BR CLEAR=\"ALL\">"); 12142 } else { $_ } 12143} 12144 12145sub tabbing_helper { 12146 local($_) = @_; 12147 s/\\=\s*//go; # cannot alter the tab-stops 12148 s/\t/ /g; # convert any tabs to spaces 12149 # MRO: replaced $* with /m 12150 s/(^|\n)[^\n]*\\kill *\n/\n/gm; 12151 s/( )? *\n/$1/gm; # retain at most 1 space for a \n 12152 # replace \\ by \n ... , ignoring any trailing space 12153# s/\\\\ */\n/gm; 12154 # ...but make sure successive \\ do not generate a <P> tag 12155# s/\n( *)?\n/\n \n/gm; 12156 s/\\\>//go; 12157 s/(^| *([^\\]))\\[>]/$2\t\t/go; 12158 s/([^\\])\\>/$1\t\t/go; 12159 s/\n$//; s/^\n//; # strip off leading/trailing \n 12160 local($inside_tabbing) = 1; 12161 $_ = &translate_commands(&translate_environments($_)); 12162 "<PRE><TT>\n$_\n</TT></PRE>"; 12163 } 12164 12165################# Post Processing Latex Generated Images ################ 12166 12167# A subroutine of the form post_latex_do_env_<ENV> can be used to 12168# format images that have come back from latex 12169 12170# Do nothing (avoid the paragraph breaks) 12171sub post_latex_do_env_figure { $_[0] } 12172sub post_latex_do_env_figurestar { &post_latex_do_env_figure(@_) } 12173 12174sub post_latex_do_env_table { $_[0] } 12175sub post_latex_do_env_tablestar { &post_latex_do_env_table(@_) } 12176 12177sub post_latex_do_env_equation { 12178 local($prefix) = @_; 12179 $global{'eqn_number'}+=1; 12180 # include equation number at the side of the image -- HTML 3.2 12181 if ($HTML_VERSION >= 3.2){ 12182 join('',"<P ALIGN=\"" , (($EQN_TAGS eq "L") ? "left" : "right") 12183 , "\">$EQNO_START" , $prefix 12184 , &translate_commands('\theequation') 12185 , "$EQNO_END</P>\n<BR CLEAR=\"all\">" ); 12186 # </P> creates unwanted space in some browsers, but others need it. 12187 } else { "" } 12188} 12189 12190sub do_cmd_theequation { 12191 if ($USING_STYLES) { 12192 $txt_style{'eqn-number'} = " " unless ($txt_style{'eqn-number'}); 12193 join('', "<SPAN CLASS=\"eqn-number\">" 12194 ,&get_counter_value('eqn_number'),"</SPAN>", $_[0]); 12195 } else { join('',&get_counter_value('eqn_number'), $_[0]); } 12196} 12197 12198sub post_latex_do_env_eqnarray { 12199 local($prefix,$body) = @_; 12200 local($num_string,$line,@lines) = ''; 12201 local($side) = (($EQN_TAGS eq "L") ? "\"left\"" : "\"right\"" ); 12202 # MRO: replaced $* with /m 12203 @lines = split(/\\\\\\\\/m, $body); 12204 $line = pop(@lines); 12205 if (!($line=~/^\s*$/)&&!($line =~/\\nonumber/)) { 12206 $global{'eqn_number'}++; 12207 $num_string .= join('', "<BR><BR>\n" , $EQNO_START , $prefix 12208 , &translate_commands('\theequation') 12209 , $EQNO_END); 12210 } 12211 foreach $line (@lines) { 12212 next if ($line=~/^\s*$/); 12213 $num_string .= "\n<BR>". (($MATH_SCALE_FACTOR > 1.3)? '<BR>' : '') 12214 . "<BR CLEAR=$side>"; 12215 if (!($line =~/\\(nonumber|(no)?tag)/)) { 12216 $global{'eqn_number'}+=1; 12217 $num_string .= join('', $EQNO_START , $prefix 12218 , &translate_commands('\theequation') 12219 , $EQNO_END); 12220 } 12221 } 12222 # include equation numbers at the side of the image -- HTML 3.2 12223 if ($HTML_VERSION >= 3.2){ 12224 "<P ALIGN=\"" . (($EQN_TAGS eq "L") ? "left" : "right") 12225 . "\">" . (($DISP_SCALE_FACTOR >= 1.2 ) ? '<BIG>' : '') 12226 . ${num_string} 12227 . (($DISP_SCALE_FACTOR >= 1.2 ) ? '</BIG>' : '') 12228 . "</P>\n<BR CLEAR=\"all\">" 12229 # </P> creates unwanted space in some browsers, but others need it. 12230 } else { "" }; 12231} 12232 12233sub post_latex_do_env_eqnarraystar { 12234 local($_) = @_; 12235 if (($HTML_VERSION >= 3.2)&&(!$NO_SIMPLE_MATH)){ 12236 join('', "<BR>\n<DIV ALIGN=\"CENTER\">\n" 12237 , $_ , "\n<BR CLEAR=\"ALL\">\n<P>"); 12238 } elsif (($HTML_VERSION >= 2.2)&&(!$NO_SIMPLE_MATH)) { 12239 join('', "\n<BR><P ALIGN=\"CENTER\">\n", $_ , "\n<BR></P>\n<P>"); 12240 } else { 12241 join('', "\n<BR><P>\n", $_ , "\n<BR></P>\n<P>"); 12242 } 12243} 12244 12245############################ Grouping ################################### 12246 12247sub do_cmd_begingroup { $latex_body .= "\n\\begingroup\n"; $_[0] } 12248sub do_cmd_endgroup { $latex_body .= "\\endgroup\n\n"; $_[0] } 12249sub do_cmd_bgroup { $latex_body .= "\n\\bgroup\n"; $_[0] } 12250sub do_cmd_egroup { $latex_body .= "\\egroup\n\n"; $_[0] } 12251 12252sub do_env_tex2html_begingroup { 12253 local($_) = @_; 12254 $latex_body .= "\\begingroup "; 12255 $_ = &translate_environments($_); 12256 $_ = &translate_commands($_); 12257 $latex_body .= "\\endgroup\n"; 12258 $_; 12259} 12260 12261sub do_env_tex2html_bgroup { 12262 local($_) = @_; 12263 $latex_body .= "\\bgroup "; 12264 $_ = &translate_environments($_); 12265 $_ = &translate_commands($_); 12266 $latex_body .= "\\egroup\n"; 12267 $_; 12268 } 12269 12270 12271############################ Commands ################################### 12272 12273# Capitalizes what follows the \sc declaration 12274# *** POTENTIAL ERROR **** 12275# (This is NOT the correct meaning of \sc in the cases when it 12276# is followed by another declaration (e.g. \em). 12277# The scope of \sc should be limited to the next occurence of a 12278# declaration. 12279#sub do_cmd_sc { 12280# local($_) = @_; 12281# local(@words) = split(" "); 12282# Capitalize the words which are not commands and do not contain any markers 12283# grep (do {tr/a-z/A-Z/ unless /(^\\)|(tex2html)/}, @words); 12284# grep (do {s/([a-z]+)/<small>\U$1\E<\/small>/g unless /(^\\)|(tex2html)/}, @words); 12285# join(" ", @words); 12286#} 12287sub do_cmd_sc { &process_smallcaps(@_) } 12288sub do_cmd_scshape { &do_cmd_sc(@_) } 12289 12290# This is supposed to put the font back into roman. 12291# Since there is no HTML equivalent for reverting 12292# to roman we keep track of the open font tags in 12293# the current context and close them. 12294# *** POTENTIAL ERROR ****# 12295# This will produce incorrect results in the exceptional 12296# case where \rm is followed by another context 12297# containing font tags of the type we are trying to close 12298# e.g. {a \bf b \rm c {\bf d} e} will produce 12299# a <b> b </b> c <b> d e</b> 12300# i.e. it should move closing tags from the end 12301sub do_cmd_rm { # clean 12302 my ($str, $ot) = @_; 12303 $ot = $open_tags_R unless(defined $ot); 12304 return("<\#rm\#>".$str) if ($inside_tabular); 12305 12306 my ($size,$color,$tags); 12307 while (@$ot) { 12308 my $next = pop (@$ot); 12309 print STDOUT "\n</$next>" if $VERBOSITY > 2; 12310 if ($next =~ /$sizechange_rx/) { 12311 $size = $next unless ($size); 12312 } 12313# if ($next =~ /$colorchange_rx/) { 12314# $color = $next unless ($color); 12315# } 12316 $declarations{$next} =~ m|</.*$|; 12317 $tags .= $& unless ($` =~ /^<>/); 12318 } 12319 if ($size) { 12320 $declarations{$size} =~ m|</.*$|; 12321 $tags .= $` unless ($` =~ /^<>/); 12322 push (@$ot,$size); 12323 print STDOUT "\n<$size>" if $VERBOSITY > 2; 12324 } 12325 $tags.$str; 12326} 12327 12328sub do_cmd_rmfamily{ &do_cmd_rm(@_) } 12329 12330sub do_cmd_textrm { 12331 local($_) = @_; 12332 local($text,$br_id)=('','0'); 12333 $text = &missing_braces unless ( 12334 (s/$next_pair_pr_rx/$text=$2;$br_id=$1;''/eo) 12335 ||(s/$next_pair_rx/$text=$2;$br_id=$1;''/eo)); 12336 join ('' , 12337 &translate_environments("$O$br_id$C\\rm $text$O$br_id$C") 12338 , $_ ); 12339} 12340 12341sub do_cmd_emph { 12342 local($_) = @_; 12343 local($ifstyle,$join_tags) = ('',join(',',@$open_tags_R)); 12344 $join_tags =~ s/(^|,)(text)?(it|rm|normalfont)/$if_style=$3;''/eg; 12345 if ($if_style =~ /it/) { 12346 ($ifstyle,$join_tags) = ('',join(',',@$open_tags_R)); 12347 $join_tags =~ s/(^|,)(text)?(bf|rm|normalfont)/$if_style=$3;''/eg; 12348 if ($if_style =~ /bf/) { &do_cmd_textrm(@_) } 12349 else { &do_cmd_textbf(@_) } 12350 } else { &do_cmd_textit(@_) } 12351 } 12352 12353#RRM: These cope with declared commands for which one cannot 12354# simply open a HTML single tag. 12355# The do_cmd_... gets found before the $declaration . 12356 12357sub do_cmd_upshape{&declared_env('upshape',$_[0],$tex2html_deferred)} 12358sub do_cmd_mdseries{&declared_env('mdseries',$_[0],$tex2html_deferred)} 12359sub do_cmd_normalfont{&declared_env('normalfont',$_[0],$tex2html_deferred)} 12360 12361 12362# This is supposed to put the font back into normalsize. 12363# Since there is no HTML equivalent for reverting 12364# to normalsize we keep track of the open size tags in 12365# the current context and close them. 12366sub do_cmd_normalsize { # clean 12367 my ($str, $ot) = @_; 12368 $ot = $open_tags_R unless(defined $ot); 12369 12370 my ($font,$fontwt,$closures,$reopens,@tags); 12371 12372 while (@$ot) { 12373 my $next = pop @$ot; 12374 $declarations{$next} =~ m|</.*$|; 12375 my ($pre,$post) = ($`,$&); 12376 if ($post =~ /$block_close_rx|$all_close_rx/ ) { 12377 push (@$ot, $next); 12378 last; 12379 } 12380 $closures .= $post unless ($pre =~ /^<>/); 12381 print STDOUT "\n</$next>" if $VERBOSITY > 2; 12382 12383 if ($next =~ /$fontchange_rx/) { 12384 $font = $next unless ($font); 12385 } elsif ($next =~ /$fontweight_rx/) { 12386 $fontwt = $next unless ($fontwt); 12387 } elsif ($next =~ /$sizechange_rx/) { 12388 # discard it 12389 } else { 12390 unshift (@tags, $next); 12391 print STDOUT "\n<<$next>" if $VERBOSITY > 2; 12392 $reopens .= $pre unless ($pre =~ /^<>/); 12393 } 12394 } 12395 push (@$ot, @tags); 12396 if ($font) { 12397 $declarations{$font} =~ m|</.*$|; 12398 $reopens .= $` unless ($` =~ /^<>/); 12399 push (@$ot,$font); 12400 print STDOUT "\n<$font>" if $VERBOSITY > 2; 12401 } 12402 if ($fontwt) { 12403 $declarations{$fontwt} =~ m|</.*$|; 12404 $reopens .= $` unless ($` =~ /^<>/); 12405 push (@$ot,$fontwt); 12406 print STDOUT "\n<$fontwt>" if $VERBOSITY > 2; 12407 } 12408 join('', $closures, $reopens, $str); 12409 } 12410 12411 12412 12413#JCL(jcl-tcl) 12414# changed everything 12415# 12416sub do_cmd_title { 12417 local($_) = @_; 12418 &get_next_optional_argument; 12419 local($making_title,$next) = (1,''); 12420 $next = &missing_braces unless ( 12421 (s/$next_pair_pr_rx/$next = $2;''/eo) 12422 ||(s/$next_pair_rx/$next = $2;''/eo)); 12423 $t_title = &translate_environments($next); 12424 $t_title = &translate_commands($t_title); 12425# $toc_sec_title = &simplify(&translate_commands($next)); 12426 $toc_sec_title = &purify(&translate_commands($next)); 12427 $TITLE = (($toc_sec_title)? $toc_sec_title : $default_title) 12428 unless ($TITLE && !($TITLE =~ /^($default_title|\Q$FILE\E)$/)); 12429# $TITLE = &purify($TITLE); 12430 12431 #RRM: remove superscripts inserted due to \thanks 12432 $TITLE =~ s/<A[^>]*><SUP>\d+<\/SUP><\/A>/$1/g; 12433 $_; 12434} 12435 12436sub do_cmd_author { 12437 local($_) = @_; 12438 &get_next_optional_argument; 12439 my $next; 12440 $next = &missing_braces unless ( 12441 (s/$next_pair_pr_rx/$next = $2;''/seo) 12442 ||(s/$next_pair_rx/$next = $2;''/seo)); 12443 local($after) = $_; 12444 if ($next =~ /\\and/) { 12445 my @author_list = split(/\s*\\and\s*/, $next); 12446 my $t_author, $t_affil, $t_address; 12447 foreach (@author_list) { 12448 $t_author = &translate_environments($_); 12449 $t_author =~ s/\s+/ /g; 12450 $t_author = &simplify(&translate_commands($t_author)); 12451 ($t_author,$t_affil,$t_address) = split (/\s*<BR>s*/, $t_author); 12452 push @authors, $t_author; 12453 push @affils, $t_affil; 12454 push @addresses, $t_address; 12455 } 12456 } else { 12457 $_ = &translate_environments($next); 12458 $next = &translate_commands($_); 12459 ($t_author) = &simplify($next); 12460 ($t_author,$t_affil,$t_address) = split (/\s*<BR>s*/, $t_author); 12461 push @authors, $t_author; 12462 push @affils, $t_affil if $t_affil; 12463 push @addresses, $t_address if $t_address; 12464 } 12465 $after; 12466} 12467 12468sub do_cmd_address { 12469 local($_) = @_; 12470 &get_next_optional_argument; 12471 local($next); 12472 $next = &missing_braces unless ( 12473 (s/$next_pair_pr_rx/$next = $&;''/eo) 12474 ||(s/$next_pair_rx/$next = $&;''/eo)); 12475 ($t_address) = &simplify(&translate_commands($next)); 12476 push @addresses, $t_address; 12477 $_; 12478 } 12479 12480sub do_cmd_institute { 12481 local($_) = @_; 12482 &get_next_optional_argument; 12483 local($next); 12484 $next = &missing_braces unless ( 12485 (s/$next_pair_pr_rx/$next = $&;''/eo) 12486 ||(s/$next_pair_rx/$next = $&;''/eo)); 12487 ($t_institute) = &simplify(&translate_commands($next)); 12488 push @affils, $t_institute; 12489 $_; 12490} 12491 12492sub do_cmd_dedicatory { 12493 local($_) = @_; 12494 &get_next_optional_argument; 12495 local($next); 12496 $next = &missing_braces unless ( 12497 (s/$next_pair_pr_rx/$next = $&;''/eo) 12498 ||(s/$next_pair_rx/$next = $&;''/eo)); 12499 ($t_affil) = &simplify(&translate_commands($next)); 12500 push @affils, $t_affil; 12501 $_; 12502 } 12503 12504sub do_cmd_email { 12505 local($_) = @_; 12506 local($next,$target)=('','notarget'); 12507 $next = &missing_braces unless ( 12508 (s/$next_pair_pr_rx/$next = $2;''/eo) 12509 ||(s/$next_pair_rx/$next = $2;''/eo)); 12510 local($mail) = &translate_commands($next); 12511 ($t_email) = &make_href("mailto:$mail","$mail"); 12512 push @emails, $t_email; 12513 $_; 12514} 12515 12516sub do_cmd_authorURL { 12517 local($_) = @_; 12518 local($next); 12519 $next = &missing_braces unless ( 12520 (s/$next_pair_pr_rx/$next = $2;''/eo) 12521 ||(s/$next_pair_rx/$next = $2;''/eo)); 12522 ($t_authorURL) = &translate_commands($next); 12523 push @authorURLs, $t_authorURL; 12524 $_; 12525 } 12526 12527sub do_cmd_date { 12528 local($_) = @_; 12529 local($next); 12530 $next = &missing_braces unless ( 12531 (s/$next_pair_pr_rx/$next = $&;''/eo) 12532 ||(s/$next_pair_rx/$next = $&;''/eo)); 12533 ($t_date) = &translate_commands($next); 12534 $_; 12535} 12536 12537sub make_multipleauthors_title { 12538 local($alignc, $alignl) = (@_); 12539 local($t_author,$t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL) 12540 = ('','','','','','',''); 12541 local ($t_title,$auth_cnt) = ('',0); 12542 if ($MULTIPLE_AUTHOR_TABLE) { 12543 $t_title = '<TABLE' .($USING_STYLES? ' CLASS="author_info_table"' : '') 12544 .' WIDTH="90%" ALIGN="CENTER" CELLSPACING=15>' 12545 ."\n<TR VALIGN=\"top\">"; 12546 } 12547 foreach $t_author (@authors) { 12548 $t_affil = shift @affils; 12549 $t_institute = ''; # shift @institutes; 12550 $t_address = shift @addresses; 12551 $t_email = shift @emails; 12552 $t_authorURL = shift @authorURLs; 12553 if ($MULTIPLE_AUTHOR_TABLE) { 12554 if ($auth_cnt == $MAX_AUTHOR_COLS) { 12555 $t_title .= join("\n", '</TR><TR>', ''); 12556 $auth_cnt -= $MAX_AUTHOR_COLS; 12557 } 12558 $t_title .= join("\n" 12559 , '<TD>' 12560 , &make_singleauthor_title($alignc, $alignl ,$t_author 12561 , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL) 12562 , '</TD>' ); 12563 ++$auth_cnt; 12564 } else { 12565 $t_title .= &make_singleauthor_title($alignc, $alignl ,$t_author 12566 , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL); 12567 } 12568 } 12569 if ($MULTIPLE_AUTHOR_TABLE) { 12570 $t_title .= "\n</TR></TABLE>\n"; 12571 } 12572 $t_title; 12573 } 12574 12575sub do_cmd_maketitle { 12576 local($_) = @_; 12577 local($the_title) = ''; 12578 local($alignc, $alignl); 12579 if ($HTML_VERSION > 2.1) { 12580 $alignc = " ALIGN=\"CENTER\""; 12581 $alignl = " ALIGN=\"LEFT\""; 12582 $alignl = $alignc if ($MULTIPLE_AUTHOR_TABLE); 12583 } 12584 if ($t_title) { 12585 $the_title .= "<H1$alignc>$t_title</H1>"; 12586 } else { &write_warnings("\nThis document has no title."); } 12587 if (($#authors >= 1)||$MULTIPLE_AUTHOR_TABLE) { 12588 $the_title .= &make_multipleauthors_title($alignc,$alignl); 12589 if ($t_date&&!($t_date=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12590 $the_title .= "\n<P$alignc><STRONG>$t_date</STRONG></P>";} 12591 } else { 12592 $the_title .= &make_singleauthor_title($alignc,$alignl ,$t_author 12593 , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL); 12594 } 12595 $the_title . $_ ; 12596 } 12597 12598sub make_singleauthor_title { 12599 local($alignc, $alignl , $t_author 12600 , $t_affil,$t_institute,$t_date,$t_address,$t_email,$t_authorURL) = (@_); 12601 my $t_title = ''; 12602 my ($s_author_info, $e_author_info) = ('<DIV','</DIV>'); 12603 $s_author_info .= ($USING_STYLES ? ' CLASS="author_info"' : '').'>'; 12604 12605 if ($t_author) { 12606 if ($t_authorURL) { 12607 local($href) = &translate_commands($t_authorURL); 12608 $href = &make_named_href('author' 12609 , $href, "<STRONG>${t_author}</STRONG>"); 12610 $t_title .= "\n<P$alignc>$href</P>"; 12611 } else { 12612 $t_title .= "\n<P$alignc><STRONG>$t_author</STRONG></P>"; 12613 } 12614 } else { &write_warnings("\nThere is no author for this document."); } 12615 12616 if ($t_institute&&!($t_institute=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12617 $t_title .= "\n<P$alignc><SMALL>$t_institute</SMALL></P>";} 12618 if ($t_affil&&!($t_affil=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12619 $t_title .= "\n<P$alignc><I>$t_affil</I></P>";} 12620 if ($t_date&&!($t_date=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12621 $t_title .= "\n<P$alignc><STRONG>$t_date</STRONG></P>";} 12622 if ($t_address&&!($t_address=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12623 $t_title .= "\n<P$alignl><SMALL>$t_address</SMALL></P>"; 12624 } # else { $t_title .= "\n<P$alignl>"} 12625 if ($t_email&&!($t_email=~/^\s*(($O|$OP)\d+($C|$CP))\s*\1\s*$/)) { 12626 $t_title .= "\n<P$alignl><SMALL>$t_email</SMALL></P>"; 12627 } # else { $t_title .= "</P>" } 12628 join("\n", $s_author_info, $t_title, $e_author_info); 12629 } 12630 12631sub do_cmd_abstract { 12632 local($_) = @_; 12633 local($abstract); 12634 $abstract = &missing_braces unless ( 12635 (s/$next_pair_pr_rx/$abstract = $&;''/eo) 12636 ||(s/$next_pair_rx/$abstract = $&;''/eo)); 12637 join('', &make_abstract($abstract), $_); 12638} 12639 12640sub make_abstract { 12641 local($_) = @_; 12642 # HWS Removed emphasis (hard to read) 12643 $_ = &translate_environments($_); 12644 $_ = &translate_commands($_); 12645 local($title); 12646 if ((defined &do_cmd_abstractname)||$new_command{'abstractname'}) { 12647 local($br_id)=++$global{'max_id'}; 12648 $title = &translate_environments("$O$br_id$C\\abstractname$O$br_id$C"); 12649 } else { $title = $abs_title } 12650 local($env_id) = " CLASS=\"ABSTRACT\"" if ($USING_STYLES); 12651 join('',"\n<H3>", $title, ":</H3>\n" 12652 , (($HTML_VERSION > 3)? "<DIV$env_id>" : "<P>"), $_ 12653 , (($HTML_VERSION > 3)? "</DIV>" : "</P>"), "\n<P>"); 12654 } 12655 12656sub set_default_language { 12657 # MRO: local($lang,*_) = @_; 12658 my $lang = shift; 12659 push(@language_stack, $default_language); 12660 $default_language = $lang; 12661 $_[0] .= '\popHtmlLanguage'; 12662} 12663 12664sub do_cmd_popHtmlLanguage { 12665 $default_language = pop(@language_stack); 12666 $_[0]; 12667} 12668 12669sub do_cmd_today { 12670 local($lang); 12671 if ($PREAMBLE) { 12672 $lang = $TITLES_LANGUAGE || $default_language ; 12673 } else { 12674 $lang = $current_language || $default_language ; 12675 } 12676 local($today) = $lang . '_today'; 12677 if (defined &$today) { join('', eval "&$today()", $_[0]) } 12678 else { join('', &default_today(), $_[0]) } 12679 } 12680 12681sub default_today { 12682 #JKR: Make it more similar to LaTeX 12683 ## AYS: moved french-case to styles/french.perl 12684 my $today = &get_date(); 12685 12686 $today =~ s|(\d+)/0?(\d+)/|$Month[$1] $2, |; 12687 join('',$today,$_[0]); 12688 } 12689 12690sub do_cmd_textbackslash { join('','\', $_[0]);} 12691sub do_cmd_textbar { join('','|', $_[0]);} 12692sub do_cmd_textless { join('',';SPMlt;', $_[0]);} 12693sub do_cmd_textgreater { join('',';SPMgt;', $_[0]);} 12694sub do_cmd_textasciicircum { join('','^', $_[0]);} 12695sub do_cmd_textasciitilde { join('','~', $_[0]);} 12696sub do_cmd_textquoteleft { join('','`', $_[0]);} 12697sub do_cmd_textquoteright { join('',''', $_[0]);} 12698 12699sub do_cmd_textcompwordmark { join('','', $_[0]);} 12700sub do_cmd_texttrademark { join('','<SUP><SMALL>TM</SMALL></SUP>', $_[0]);} 12701 12702sub do_cmd_textsubscript { &make_text_supsubscript('SUB',$_[0]);} 12703sub do_cmd_textsuperscript { &make_text_supsubscript('SUP',$_[0]);} 12704 12705sub make_text_supsubscript { 12706 local ($supsub, $_) = (@_); 12707 my $arg = ''; 12708 $arg = &missing_braces unless ( 12709 (s/$next_pair_pr_rx/$arg = $&;''/eo) 12710 ||(s/$next_pair_rx/$arg = $&;''/eo)); 12711 $arg = &translate_commands($arg) if ($arg =~ m!\\!); 12712 join('', "<$supsub>", $arg, "</$supsub>", $_); 12713 } 12714 12715sub do_cmd_textcircled { 12716 local ($_) = (@_); 12717 my $arg = ''; 12718 $arg = &missing_braces unless ( 12719 (s/$next_pair_pr_rx/$arg = $&;''/eo) 12720 ||(s/$next_pair_rx/$arg = $&;''/eo)); 12721 my $after = $_; 12722 join('', &process_undefined_environment("tex2html_nomath_inline" 12723 , ++$global{'max_id'} 12724 , "\\vbox{\\kern3pt\\textcircled{$arg}}" ) 12725 , $after ); 12726 } 12727 12728# these can be overridded in charset (.pl) extension files: 12729sub do_cmd_textemdash { join('','---', $_[0]);} 12730sub do_cmd_textendash { join('','--', $_[0]);} 12731#sub do_cmd_exclamdown { join('','', $_[0]);} 12732#sub do_cmd_questiondown { join('','', $_[0]);} 12733sub do_cmd_textquotedblleft { join('',"``", $_[0]);} 12734sub do_cmd_textquotedblright { join('',"''", $_[0]);} 12735sub do_cmd_textbullet { join('','*', $_[0]);} 12736sub do_cmd_textvisiblespace { join('','_', $_[0]);} 12737 12738sub do_cmd_ldots { 12739 join('',(($math_mode&&$USE_ENTITY_NAMES) ? ";SPMldots;" : "..."),$_[0]); 12740} 12741 12742sub do_cmd_dots { 12743 join('',(($math_mode&&$USE_ENTITY_NAMES) ? ";SPMldots;" : "..."),$_[0]); 12744 } 12745 12746sub do_cmd_hrule { 12747 local($_) = @_; 12748 &ignore_numeric_argument; 12749 #JKR: No need for <BR> 12750 local($pre,$post) = &minimize_open_tags('<HR>'); 12751 join('',$pre,$_); 12752 } 12753 12754#sub do_cmd_hrulefill { 12755# "<HR ALIGN=\"right\">\n<BR CLEAR=\"right\">"; 12756#} 12757 12758sub do_cmd_linebreak { 12759 local($num,$dum) = &get_next_optional_argument; 12760 if (($num)&&($num<4)) { return $_[0] } 12761 join('',"<BR>", $_[0]); 12762 } 12763 12764sub do_cmd_pagebreak { 12765 local($_) = @_; 12766 local($num,$dum) = &get_next_optional_argument; 12767 if (($num)&&($num<4)) { return($_) } 12768 elsif (/^ *\n *\n/) { 12769 local($after) = $'; 12770 local($pre,$post) = &minimize_open_tags("<BR>\n<P>"); 12771 join('',$pre, $') 12772 } else { $_ } 12773 } 12774 12775 12776sub do_cmd_newline { join('',"<BR>", $_[0]); } 12777# this allows for forced newlines in tables, etc. 12778sub do_cmd_endgraf { join('',"<BR>", $_[0]); } 12779 12780sub do_cmd_space { join(''," ",$_[0]); } 12781sub do_cmd_enspace { join('',"\ ",$_[0]); } 12782sub do_cmd_quad { join('',"\ "x4,$_[0]); } 12783sub do_cmd_qquad { join('',"\ "x8,$_[0]); } 12784 12785sub do_cmd_par { 12786 local ($_) = @_; 12787 my ($pre,$post) = &preserve_open_tags(); 12788 my ($spar, $lcode) = ("\n<P", ''); 12789 if (($USING_STYLES) &&(!($default_language eq $TITLES_LANGUAGE))) { 12790 $lcode = &get_current_language(); 12791 $spar .= $lcode if $lcode; 12792 } 12793 join('', $pre, $spar, ">\n",$post,$_); 12794 } 12795 12796sub do_cmd_medskip { 12797 local ($_) = @_; 12798 local($pre,$post) = &preserve_open_tags(); 12799 join('',$pre,"\n<P><BR>\n",$post,$_); 12800 } 12801 12802sub do_cmd_smallskip { 12803 local ($_) = @_; 12804 local($pre,$post) = &preserve_open_tags(); 12805 join('',$pre,"\n<P></P>\n",$post,$_); 12806 } 12807 12808sub do_cmd_bigskip { 12809 local ($_) = @_; 12810 local($pre,$post) = &preserve_open_tags(); 12811 join('',$pre,"\n<P><P><BR>\n",$post,$_); 12812 } 12813 12814# MEH: Where does the slash command come from? 12815# sub do_cmd_slash { 12816# join('',"/",$_[0]); 12817#} 12818sub do_cmd_esc_slash { $_[0]; } 12819sub do_cmd_esc_hash { "\#". $_[0]; } 12820sub do_cmd_esc_dollar { "\$". $_[0]; } 12821sub do_cmd__at_ { $_[0]; } 12822sub do_cmd_lbrace { "\{". $_[0]; } 12823sub do_cmd_rbrace { "\}". $_[0]; } 12824sub do_cmd_Vert { "||". $_[0]; } 12825sub do_cmd_backslash { "\\". $_[0]; } 12826 12827#RRM: for subscripts outside math-mode 12828# e.g. in Chemical formulae 12829sub do_cmd__sub { 12830 local($_) = @_; 12831 local($next); 12832 $next = &missing_braces unless ( 12833 (s/$next_pair_pr_rx/$next = $2;''/e) 12834 ||(s/$next_pair_rx/$next = $2;''/e)); 12835 join('',"<SUB>",$next,"</SUB>",$_); 12836 } 12837 12838#JCL(jcl-del) - the next two ones must only have local effect. 12839# Yet, we don't have a mechanism to revert such changes after 12840# a group has closed. 12841# 12842sub do_cmd_makeatletter { 12843 $letters =~ s/@//; 12844 $letters .= '@'; 12845 &make_letter_sensitive_rx; 12846 $_[0]; 12847 } 12848 12849sub do_cmd_makeatother { 12850 $letters =~ s/@//; 12851 &make_letter_sensitive_rx; 12852 $_[0]; 12853 } 12854 12855 12856################## Commands to be processed by Latex ################# 12857# 12858# The following commands are passed to Latex for processing. 12859# They cannot be processed at the same time as normal commands 12860# because their arguments must be left untouched by the translator. 12861# (Normally the arguments of a command are translated before the 12862# command itself). 12863# 12864# In fact, it's worse: it is not correct to process these 12865# commands after we process environments, because some of them 12866# (for instance, \parbox) may contain unknown or wrapped 12867# environments. If math mode occurs in a parbox, the 12868# translate_environments routine should *not* process it, lest 12869# we encounter the lossage outlined above. 12870# 12871# On the other hand, it is not correct to process these commands 12872# *before* we process environments, or figures containing 12873# parboxes, etc., will be mishandled. 12874# 12875# RRM: (added for V97.1) 12876# \parbox now uses the _wrap_deferred mechanism, and has a do_cmd_parbox 12877# subroutine defined. This means that environments where parboxes are 12878# common (.g. within table cells), can detect the \parbox command and 12879# adjust the processing accordingly. 12880# 12881# So, the only way to handle these commands is to wrap them up 12882# in null environments, as for math mode, and let translate_environments 12883# (which can handle nesting) figure out which is the outermost. 12884# 12885# Incidentally, we might as well make these things easier to configure... 12886 12887sub process_commands_in_tex { 12888 local($_) = @_; 12889 local($arg,$tmp); 12890 foreach (/.*\n?/g) { 12891 chop; 12892 # For each line 12893 local($cmd, @args) = split('#',$_); 12894 print "PCT: process_commands_in_tex: cmd: $cmd - $_\n" if ($VERBOSITY > 10) ; 12895 next unless $cmd; 12896 $cmd =~ s/ //g; 12897 12898 # skip if a proper implementation already exists 12899 $tmp = "do_cmd_$cmd"; 12900 print "PCT: process_commands_in_tex: tmp: $tmp\n" if ($VERBOSITY > 10) ; 12901 next if (defined &$tmp); 12902 12903 # Build routine body ... 12904 local ($body, $code, $thisone) = ("", ""); 12905 12906 # alter the pattern here to debug particular commands 12907# $thisone = 1 if ($cmd =~ /mathbb/); 12908 12909 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 12910 foreach $arg (@args) { 12911 print "\nARG: $arg" if ($thisone); 12912 print "\nARG: $next_pair_rx" if ($thisone); 12913 if ($arg =~ /\{\}/) { 12914# RRM: the $` is surely wrong, allowing no error-checking. 12915# Use <<...>> for specific patterns 12916# $body .= '$args .= "$`$&" if s/$next_pair_rx//o;'."\n"; 12917 $body .= '$args .= join("","{", &missing_braces, "}") unless ('."\n"; 12918 $body .= ' (s/$next_pair_pr_rx/$args.=$`.$&;""/es)'."\n"; 12919 $body .= ' ||(s/$next_pair_rx/$args.=$`.$&;""/es));'."\n"; 12920 print "\nAFTER:$'" if (($thisone)&&($')); 12921 $body .= $' if ($'); 12922 } elsif ($arg =~ /\[\]/) { 12923 $body .= '($dummy, $pat) = &get_next_optional_argument;' 12924 . '$args .= $pat;'."\n"; 12925 print "\nAFTER:$'" if (($thisone)&&($')); 12926 $body .= $' if ($'); 12927 } elsif ($arg =~ /^\s*\\/) { 12928 $body .= '($dummy, $pat) = &get_next_tex_cmd;' 12929 . '$args .= $pat;'."\n"; 12930 print "\nAFTER:$'" if (($thisone)&&($')); 12931 $body .= $' if ($'); 12932 } elsif ($arg =~ /<<\s*/) { 12933 $arg = $'; 12934 if ($arg =~ /\s*>>/) { 12935 # MRO: replaced $* with /m 12936 $body .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n" 12937# $body .= '$args .= "$`$&" if (/\\\\'.$`.'/);' . "\n" 12938 . "\$_ = \$\';\n"; 12939 print "\nAFTER:$'" if (($thisone)&&($')); 12940 $body .= $' if ($'); 12941 } else { $body .= $arg ; } 12942 } else { 12943 print "\nAFTER:$'" if (($thisone)&&($arg)); 12944 $body .= $arg ; 12945 } 12946 } 12947 12948 # Generate a new subroutine 12949 local($padding) = " "; 12950 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 12951 $code = "sub wrap_cmd_$cmd {" . "\n" 12952 . 'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";' . "\n" 12953 . $body 12954 . (($thisone)? "print STDERR \"\\n$cmd:\".\$args.\"\\n\";\n" : '') 12955 . '(&make_wrapper(1).$cmd' 12956 . ($padding ? '"'.$padding.'"' : '') 12957 . '.$args.&make_wrapper(0), $_)}' 12958 . "\n"; 12959 print "\nWRAP_CMD: $code " if ($thisone); # for debugging 12960 eval $code; # unless ($thisone); 12961 print STDERR "\n*** sub wrap_cmd_$cmd failed: $@" if ($@); 12962 12963 # And make sure the main loop will catch it ... 12964# $raw_arg_cmds{$cmd} = 1; 12965 ++$raw_arg_cmds{$cmd}; 12966 } 12967 } 12968 12969sub process_commands_nowrap_in_tex { 12970 local($_) = @_; 12971 local($arg); 12972 foreach (/.*\n?/g) { 12973 chop; 12974 local($cmd, @args) = split('#',$_); 12975 next unless $cmd; 12976 $cmd =~ s/ //g; 12977 # Build routine body ... 12978 local ($bodyA, $codeA, $bodyB, $codeB, $thisone) = ("", "", "", ""); 12979 12980 # alter the pattern here to debug particular commands 12981# $thisone = 1 if ($cmd =~ /epsf/); 12982 12983 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 12984 foreach $arg (@args) { 12985 print "\nARG: $arg" if ($thisone); 12986 if ($arg =~ /\{\}/) { 12987# $bodyA .= '$args .= "$`"."$&" if (s/$any_next_pair_rx//);'."\n"; 12988 $bodyA .= 'if (s/$next_pair_rx//s){$args.="$`"."$&"; $_='."\$'};\n"; 12989 $bodyB .= '$args .= &missing_braces'."\n unless ("; 12990 $bodyB .= '(s/$any_next_pair_pr_rx/$args.=$`.$&;\'\'/eo)'."\n"; 12991 $bodyB .= ' ||(s/$any_next_pair_rx/$args.=$`.$&;\'\'/eo));'."\n"; 12992 print "\nAFTER:$'" if (($thisone)&&($')); 12993# $bodyA .= $'.";\n" if ($'); 12994 $bodyB .= $'.";\n" if ($'); 12995 } elsif ($arg =~ /\[\]/) { 12996 $bodyA .= '($dummy, $pat) = &get_next_optional_argument;' 12997 . '$args .= $pat;'."\n"; 12998 print "\nAFTER:$'" if (($thisone)&&($')); 12999# $bodyA .= $'.";\n" if ($'); 13000 $bodyB .= $'.";\n" if ($'); 13001 } elsif ($arg =~ /^\s*\\/) { 13002 $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;' 13003 . '$args .= $pat;'."\n"; 13004 $bodyB .= '($dummy, $pat) = &get_next_tex_cmd;' 13005 . '$args .= $pat;'."\n"; 13006 print "\nAFTER:$'" if (($thisone)&&($')); 13007 $bodyA .= $'.";\n" if ($'); 13008 $bodyB .= $'.";\n" if ($'); 13009 } elsif ($arg =~ /<<\s*/) { 13010 $arg = $'; 13011 if ($arg =~ /\s*>>/) { 13012 # MRO: replaced $* with /m 13013 $bodyA .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n" 13014# $bodyA .= '$args .= $`.$& if (/\\\\'.$`.'/);' . "\n" 13015 . "\$_ = \$\';\n"; 13016 $bodyB .= '$args .= "$`$&" if (/\\'.$`.'/m);' . "\n" 13017 . "\$_ = \$\';\n"; 13018 print "\nAFTER:$'" if (($thisone)&&($')); 13019# $bodyA .= $'.";\n" if ($'); 13020 $bodyB .= $'.";\n" if ($'); 13021 } else { 13022 print "\nAFTER:$arg" if (($thisone)&&($arg)); 13023# $bodyA .= $arg.";\n" if ($arg); 13024 $bodyB .= $arg.";\n" if ($arg); 13025 } 13026 } else { 13027 print "\nAFTER:$arg" if (($thisone)&&($arg)); 13028 $bodyA .= '$args .= '.$arg.";\n" if ($'); 13029 $bodyB .= $arg.";\n" if ($'); 13030 } 13031 } 13032 local($padding) = " "; 13033 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 13034 # Generate 2 new subroutines 13035 $codeA = "sub wrap_cmd_$cmd {" . "\n" 13036 .'local($cmd, $_) = @_; local($args, $dummy, $pat) = "";'."\n" 13037 . $bodyA 13038 . (($thisone)? "print \"\\nwrap $cmd:\\n\".\$args.\"\\n\";\n" : '') 13039 . '(&make_nowrapper(1)."\n".$cmd.'."\"$padding\"" 13040 . '.$args.&make_nowrapper(0)," ".$_)}' 13041 ."\n"; 13042 print "\nWRAP_CMD: $codeA " if ($thisone); # for debugging 13043 eval $codeA; 13044 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 13045 $codeB = "do_cmd_$cmd"; 13046 do { 13047 $bodyB = '"";' if !($bodyB); 13048 $codeB = "sub do_cmd_$cmd {" . "\n" 13049 . 'local($_,$ot) = @_;'."\n" 13050 . 'local($open_tags_R) = defined $ot ? $ot : $open_tags_R;'."\n" 13051 . 'local($cmd,$args,$dummy,$pat)=("'.$cmd.'","","","");'."\n" 13052 . $bodyB 13053 . (($thisone)? "print \"\\ndo $cmd:\".\$args.\"\\n\";\n" : '') 13054# . '$latex_body.="\\n".&revert_to_raw_tex("'."\\\\$cmd$padding".'$args")."\\n\\n";' 13055 . "\$_;}\n"; 13056 print STDOUT "\nDO_CMD: $codeB " if ($thisone); # for debugging 13057 eval $codeB; 13058 print STDERR "\n\n*** sub do_cmd_$cmd failed: $@\n" if ($@); 13059 } unless (defined &$codeB ); 13060 13061 # And make sure the main loop will catch it ... 13062# $raw_arg_cmds{$cmd} = 1; 13063 ++$raw_arg_cmds{$cmd}; 13064 } 13065} 13066 13067sub process_commands_wrap_deferred { 13068 local($_) = @_; 13069 local($arg,$thisone); 13070 foreach (/.*\n?/g) { 13071 chop; 13072 local($cmd, @args) = split('#',$_); 13073 print "PCT: process_commands_wrap_deferred: cmd: $cmd\n" if ($VERBOSITY > 10) ; 13074 next unless $cmd; 13075 $cmd =~ s/ //g; 13076 # Build routine body ... 13077 local ($bodyA, $codeA, $bodyB, $codeB, $after, $thisone); 13078 13079 # alter the pattern here to debug particular commands 13080 # $thisone = 1 if ($cmd =~ /selectlanguage/); 13081 13082 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 13083 foreach $arg (@args) { 13084 print "\nARG: $arg" if ($thisone); 13085 if ($arg =~ /\{\}/) { 13086 # $bodyA .= '$args .= "$`$&" if (s/$any_next_pair_rx//o);'; 13087 $bodyA .= '$args .= "$`$&" if (s/$next_pair_rx//so);'; 13088 $after = $'; 13089 print "\nAFTER:$'" if (($thisone)&&($')); 13090 } elsif ($arg =~ /\[\]/) { 13091 $bodyA .= '($dummy, $pat) = &get_next_optional_argument;' . 13092 "\n". '$args .= $pat;'; 13093 $after = $'; 13094 print "\nAFTER:$'" if (($thisone)&&($')); 13095 } elsif ($arg =~ /^\s*\\/) { 13096 $bodyA .= '($dummy, $pat) = &get_next_tex_cmd;' 13097 . '$args .= $pat;'."\n"; 13098 print "\nAFTER:$'" if (($thisone)&&($')); 13099 $bodyA .= $'.";\n" if ($'); 13100 } elsif (/<<\s*([^>]*)[\b\s]*>>/) { 13101 local($endcmd, $afterthis) = ($1,$'); 13102 $afterthis =~ s/(^\s*|\s*$)//g; 13103 $endcmd =~ s/\\/\\\\/g; 13104 $bodyA .= join('', 13105 "\n", 13106 'if (/', 13107 $endcmd, 13108 '/) { $args .= $`.$& ; $_ = $', 13109 "'", 13110 '};') ; 13111 $after .= $afterthis if ($afterthis); 13112 print "\nAFTER:$'" if (($thisone)&&($')); 13113 } else { 13114 print "\nAFTER:$arg" if (($thisone)&&($arg)); 13115 $bodyB .= $arg.";\n" ; $after = '' 13116 } 13117 $after =~ s/(^\s*|\s*$)//g if ($after); 13118 $bodyB .= $after . ";" if ($after); 13119 $bodyA .= "\$args .= ".$after . ";" if ($after); 13120 } 13121 local($padding) = " "; 13122 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 13123 # Generate 2 new subroutines 13124 $codeA = join('', 13125 "sub wrap_cmd_$cmd {", 13126 "\n", 13127 'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";', 13128 "\n", 13129 $bodyA, #. ($bodyA ? "\n" : '') 13130 (($thisone)? ";print \"\\nwrap $cmd:\".\$args.\"\\n\";\n" : ''), 13131 '(&make_deferred_wrapper(1).$cmd.', 13132 $padding, 13133 '$args.&make_deferred_wrapper(0),$_)}', 13134 "\n") ; 13135 print STDERR "\nWRAP_CMD: $codeA " if ($thisone); # for debugging 13136 eval $codeA; 13137 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 13138 13139 #RRM: currently these commands only go to LaTeX or access counters. 13140 # They could be implemented more generally, as below with do_dcmd_$cmd 13141 # requiring replacement to be performed before evaluation. 13142 $codeB = join('', 13143 "sub do_dcmd_$cmd {" . "\n", 13144 'local($cmd, $_) = @_; local ($args, $dummy, $pat) = "";', 13145 "\n", 13146 $bodyA, 13147 "\n", 13148 (($thisone)? ";print \"\\ndo_def $cmd:\".\$args.\"\\n\";\n" : ''), 13149 $bodyB, 13150 "}", 13151 "\n") ; 13152 print "\nDEF_CMD: $codeB " if ($thisone); # for debugging 13153 local($tmp) = "do_cmd_$cmd"; 13154 eval $codeB unless (defined &$tmp); 13155 print STDERR "\n\n*** sub do_dcmd_$cmd failed: $@\n" if ($@); 13156 13157 # And make sure the main loop will catch it ... 13158 # $raw_arg_cmds{$cmd} = 1; 13159 ++$raw_arg_cmds{$cmd}; 13160 } 13161} 13162 13163sub process_commands_inline_in_tex { 13164 local($_) = @_; 13165 foreach (/.*\n?/g) { 13166 chop; 13167 local($cmd, @args) = split('#',$_); 13168 next unless $cmd; 13169 $cmd =~ s/ //g; 13170 # Build routine body ... 13171 local ($body, $code, $thisone) = ("", ""); 13172 13173 # uncomment and alter the pattern here to debug particular commands 13174 # $thisone = 1 if ($cmd =~ /L/); 13175 13176 print "\n$cmd: ".scalar(@args)." arguments" if ($thisone); 13177 foreach (@args) { 13178 print "\nARG: $_" if ($thisone); 13179 if (/\{\}/) { 13180 # $body .= '$args .= $`.$& if (/$any_next_pair_rx/);' . "\n" 13181 # . "\$_ = \$\';\n"; 13182 $body .= '$args .= $`.$& if (s/$next_pair_rx//s);' . "\n" 13183 } elsif (/\[\]/) { 13184 $body .= join('', 13185 'local($dummy, $pat) = &get_next_optional_argument;', 13186 "\n", 13187 '$args .= $pat;') ; 13188 } elsif ($arg =~ /^\s*\\/) { 13189 $body .= join('', 13190 '($dummy, $pat) = &get_next_tex_cmd;', 13191 '$args .= $pat;', 13192 "\n") ; 13193 print "\nAFTER:$'" if (($thisone)&&($')); 13194 $body .= $'.";\n" if ($'); 13195 } elsif (/<<\s*/) { 13196 $_ = $'; 13197 if (/\s*>>/) { 13198 # MRO: replaced $* with /m 13199 $body .= join('','$args .= "$`$&" if (/\\', 13200 $`, 13201 '/m);', 13202 "\n", 13203 "\$_ = \$\';\n") ; 13204 } else { $body .= $_.";\n" ; } 13205 } else { $body .= $_.";\n" ; } 13206 } 13207 local($padding) = " "; 13208 $padding = '' if (($cmd =~ /\W$/)||(!$args)||($args =~ /^\W/)); 13209 # Generate a new subroutine 13210 my $itype = ($cmd =~ /^f.*box$/ ? 'inline' : 'nomath'); 13211 $code = join('', 13212 "sub wrap_cmd_$cmd {" . "\n", 13213 'local($cmd, $_) = @_; local ($args) = "";', 13214 "\n", 13215 $body, 13216 "\n", 13217 (($thisone)? ";print \"\\ndo $cmd:\".\$args.\"\\n\";\n" : ''), 13218 '(&make_'.$itype.'_wrapper(1).$cmd.$padding.$args.', 13219 '&make_'.$itype.'_wrapper(0),$_)}', 13220 "\n") ; 13221 print "\nWRAP_CMD:$raw_arg_cmds{$cmd}: $code " 13222 if ($thisone); # for debugging 13223 eval $code; 13224 print STDERR "\n\n*** sub wrap_cmd_$cmd failed: $@\n" if ($@); 13225 # And make sure the main loop will catch it ... 13226 # $raw_arg_cmds{$cmd} = 1; 13227 ++$raw_arg_cmds{$cmd}; 13228 } 13229} 13230 13231 13232# Invoked before actual translation; wraps these commands in 13233# tex2html_wrap environments, so that they are properly passed to 13234# TeX in &translate_environments ... 13235# JCL(jcl-del) - new usage of $raw_arg_cmd_rx 13236sub wrap_raw_arg_cmds { 13237 local ($processed_text, $cmd, $wrapper, $wrap, $after); 13238 print "\nwrapping raw arg commands " if ($VERBOSITY>1); 13239 local($seg, $par_wrap, $teststar, @processed); 13240 # local(@segments) = split(/\\par\b/,$_); 13241 # foreach (@segments) { 13242 # $par_wrap = join('',&make_deferred_wrapper(1), "\\par" 13243 # , &make_deferred_wrapper(0)); 13244 # push(@processed, $par_wrap ) if ($seg); ++$seg; 13245 if (%renew_command) { 13246 local($key); 13247 foreach $key (keys %renew_command) { 13248 $raw_arg_cmds{$key} = 1; 13249 $raw_arg_cmd_rx =~ s/^(\(\)\\\\\()/$1$key\|/; 13250 } 13251 } 13252 print "\n" if (/$raw_arg_cmd_rx/); 13253 13254 # MRO: replaced $* with /m 13255 while (/$raw_arg_cmd_rx/m) { 13256 local($star); 13257 push (@processed, $`); print "\@"; 13258 $after = $'; 13259 #JCL(jcl-del) - status of starred raw arg cmds yet unclear 13260 ($cmd, $star) = ($1.$2,$4); 13261 if ($star eq '*') { 13262 $star = 'star'; 13263 } 13264 else { 13265 $after = $star.$after; $star = ''; 13266 } 13267 $wrapper = "wrap_cmd_$cmd"; $teststar = $wrapper.'star'; 13268 if ($star && defined &$teststar) { $wrapper = $teststar; $star = '*'; } 13269 # MRO: make {\bf**} work 13270 elsif($star) { $after = '*'.$after; $star = '' } 13271 print "\nWRAPPED: $cmd as $wrapper" if ($VERBOSITY > 5); 13272 13273 # ensure that the result is separated from following words... 13274 my $padding = ($after =~ /^[a-zA-Z]/s)? ($cmd =~ /\W$/ ? '':' '):''; 13275 13276 if ($raw_arg_cmds{$cmd} && defined &$wrapper) { 13277 ($wrap, $_) = &$wrapper("\\$cmd$star", $padding . $after); 13278 # ...but don't leave an unwanted space at the beginning 13279 $_ =~ s/^ //s if($padding && $wrap !~ /\w$/m 13280 && (length($_) == length($after)+1) ); 13281 push (@processed, $wrap); 13282 } elsif ($raw_arg_cmds{$cmd}) { 13283 print STDERR "\n*** $wrapper not defined, cannot wrap \\$cmd"; 13284 &write_warnings("\n*** $wrapper not defined, cannot wrap \\$cmd "); 13285 push (@processed, "\\$cmd$padding"); 13286 $_ = $after; 13287 } else { 13288 push (@processed, "\\$cmd$padding"); 13289 $_ = $after; 13290 } 13291 last unless ($after =~ /\\/); 13292 } 13293 13294 # recombine the pieces 13295 $_ = join('',@processed, $_); 13296} 13297 13298######################################################################### 13299 13300# To make a table of contents, list of figures and list of tables commands 13301# create a link to corresponding files which do not yet exist. 13302# The binding of the file variable in each case acts as a flag 13303# for creating the actual file at the end, after all the information 13304# has been gathered. 13305 13306sub do_cmd_tableofcontents { } ; 13307#&do_real_tableofcontents(@_) } 13308sub do_real_tableofcontents { 13309 # local($_) = @_; 13310 if ((defined &do_cmd_contentsname)||$new_command{'contentsname'}) { 13311 local($br_id)=++$global{'max_id'}; 13312 $TITLE = &translate_environments("$O$br_id$C\\contentsname$O$br_id$C"); 13313 } 13314 else { 13315 $TITLE = $toc_title ; 13316 } 13317 $toc_sec_title = $TITLE; 13318 $tocfile = $CURRENT_FILE; # sets $tocfile this globally 13319 local $toc_head = $section_headings{'tableofcontents'}; 13320 if ($toc_style) { 13321 $toc_head .= " CLASS=\"$toc_style\""; 13322 $env_style{"$toc_head.$toc_style"} = " " 13323 unless ($env_style{"$toc_head.$toc_style"}); 13324 } 13325 local($closures,$reopens) = &preserve_open_tags(); 13326 join('', 13327 "<BR>\n", 13328 $closures, 13329 &make_section_heading($TITLE, $toc_head), 13330 $toc_mark, 13331 $reopens, 13332 @_[0]); 13333} 13334sub do_cmd_listoffigures { 13335 local($_) = @_; 13336 local($list_type) = ($SHOW_SECTION_NUMBERS ? 'UL' : 'OL' ); 13337 if ((defined &do_cmd_listfigurename)||$new_command{'listfigurename'}) { 13338 local($br_id)=++$global{'max_id'}; 13339 $TITLE = &translate_environments("$O$br_id$C\\listfigurename$O$br_id$C"); 13340 } else { $TITLE = $lof_title } 13341 $toc_sec_title = $TITLE; 13342 $loffile = $CURRENT_FILE; # sets $loffile this globally 13343 local $lof_head = $section_headings{'listoffigures'}; 13344 local($closures,$reopens) = &preserve_open_tags(); 13345 join('', 13346 "<BR>\n", 13347 $closures, 13348 &make_section_heading($TITLE, $lof_head), 13349 "<$list_type>", 13350 $lof_mark, 13351 "</$list_type>", 13352 $reopens, 13353 $_); 13354} 13355sub do_cmd_listoftables { 13356 local($_) = @_; 13357 local($list_type) = ($SHOW_SECTION_NUMBERS ? 'UL' : 'OL' ); 13358 if ((defined &do_cmd_listtablename)||$new_command{'listtablename'}) { 13359 local($br_id)=++$global{'max_id'}; 13360 $TITLE = &translate_environments("$O$br_id$C\\listtablename$O$br_id$C"); 13361 } else { $TITLE = $lot_title } 13362 $toc_sec_title = $TITLE; 13363 $lotfile = $CURRENT_FILE; # sets $lotfile this globally 13364 local $lot_head = $section_headings{'listoftables'}; 13365 local($closures,$reopens) = &preserve_open_tags(); 13366 join('', "<BR>\n", $closures 13367 , &make_section_heading($TITLE, $lot_head) 13368 , "<$list_type>", $lot_mark, "</$list_type>" 13369 , $reopens, $_); 13370} 13371 13372# Indicator for where to put the CHILD_LINKS table. 13373sub do_cmd_tableofchildlinks { 13374 local($_) = @_; 13375 local($thismark) = $childlinks_mark; 13376 local($option,$dum) = &get_next_optional_argument; 13377 $thismark = &check_childlinks_option($option) if ($option); 13378 local($pre,$post) = &minimize_open_tags("$thismark\#0\#"); 13379 join('', "<BR>", $pre, $_); 13380} 13381 13382# leave out the preceding <BR> 13383sub do_cmd_tableofchildlinksstar { 13384 local($_) = @_; 13385 local($thismark) = $childlinks_mark; 13386 local($option,$dum) = &get_next_optional_argument; 13387 $thismark = &check_childlinks_option($option) if ($option); 13388 local($pre,$post) = &minimize_open_tags("$thismark\#1\#"); 13389 join('', $pre, $_); 13390} 13391 13392sub check_childlinks_option { 13393 local($option) = @_; 13394 if ($option =~ /none/i) { 13395 $childlinks_mark = $childlinks_null_mark; 13396 $childlinks_null_mark } 13397 elsif ($option =~ /off/i) { $childlinks_null_mark } 13398 elsif ($option =~ /all/i) { 13399 $childlinks_mark = $childlinks_on_mark; 13400 $childlinks_on_mark } 13401 elsif ($option =~ /on/i) { $childlinks_on_mark } 13402} 13403 13404sub remove_child_marks { 13405 # Modifies $_ 13406 s/($childlinks_on_mark|$childlinks_null_mark)\#\d\#//go; 13407} 13408 13409 13410sub do_cmd_htmlinfo { 13411 local($_) = @_; 13412 local($option,$dum) = &get_next_optional_argument; 13413 if ($option =~ /^(off|none)/i) { $INFO = 0; return ($_) } 13414 local($pre,$post) = &minimize_open_tags($info_title_mark.$info_page_mark); 13415 join('', "<BR>", $pre, $_); 13416} 13417sub do_cmd_htmlinfostar { 13418 local($_) = @_; 13419 local($option,$dum) = &get_next_optional_argument; 13420 if ($option =~ /^(off|none)/i) { $INFO = 0; return ($_) } 13421 local($pre,$post) = &minimize_open_tags($info_page_mark); 13422 join('', $pre, $_); 13423} 13424 13425# $idx_mark will be replaced with the real index at the end 13426sub do_cmd_textohtmlindex { 13427 local($_) = @_; 13428 if ((defined &do_cmd_indexname )||$new_command{'indexname'}) { 13429 local($br_id)=++$global{'max_id'}; 13430 $TITLE = &translate_environments("$O$br_id$C\\indexname$O$br_id$C"); 13431 } else { $TITLE = $idx_title } 13432 $toc_sec_title = $TITLE; 13433 $idxfile = $CURRENT_FILE; 13434 if (%index_labels) { &make_index_labels(); } 13435 if (($SHORT_INDEX) && (%index_segment)) { &make_preindex(); } 13436 else { $preindex = ''; } 13437 local $idx_head = $section_headings{'textohtmlindex'}; 13438 local($heading) = join('' 13439 , &make_section_heading($TITLE, $idx_head) 13440 , $idx_mark ); 13441 local($pre,$post) = &minimize_open_tags($heading); 13442 join('',"<BR>\n" , $pre, $_); 13443} 13444 13445#RRM: added 17 May 1996 13446# allows labels within the printable key of index-entries, 13447# when using makeidx.perl 13448sub make_index_labels { 13449 local($key, @keys); 13450 @keys = keys %index_labels; 13451 foreach $key (@keys) { 13452 if (($ref_files{$key}) && !($ref_files{$key} eq "$idxfile")) { 13453 local($tmp) = $ref_files{$key}; 13454 &write_warnings("\nmultiple label $key , target in $idxfile masks $tmp "); 13455 } 13456 $ref_files{$key} .= "$idxfile"; 13457 } 13458} 13459#RRM: added 17 May 1996 13460# constructs a legend for the SHORT_INDEX, with segments 13461# when using makeidx.perl 13462sub make_preindex { &make_real_preindex } 13463sub make_real_preindex { 13464 local($key, @keys, $head, $body); 13465 $head = "<HR>\n<H4>Legend:</H4>\n<DL COMPACT>"; 13466 @keys = keys %index_segment; 13467 foreach $key (@keys) { 13468 local($tmp) = "segment$key"; 13469 $tmp = $ref_files{$tmp}; 13470 $body .= "\n<DT>$key<DD>".&make_named_href('',$tmp,$index_segment{$key}); 13471# $body .= "\n<DT>$key<DD>".&make_named_href('', 13472# $tmp."\#CHILD\_LINKS",$index_segment{$key}) 13473# unless ($CHILD_STAR); 13474 } 13475 $preindex = join('', $head, $body, "\n</DL>") if ($body); 13476} 13477 13478sub do_cmd_printindex { &do_real_printindex(@_); } 13479sub do_real_printindex { 13480 print "PCT: do_real_printindex\n" if ($VERBOSITY > 200) ; 13481 local($_) = @_; 13482 local($which) = &get_next_optional_argument; 13483 print "PCT: do_real_printindex: which: $which\n" if ($VERBOSITY > 200) ; 13484 $idx_name = $index_names{$which} 13485 if ($which && $index_names{$which}); 13486 @_; 13487} 13488 13489 sub do_cmd_newindex { 13490 local($_) = @_; 13491 local($dum,$key,$title); 13492 $key = &missing_braces unless ( 13493 (s/$next_pair_pr_rx/$key=$2;''/eo) 13494 ||(s/$next_pair_rx/$key=$2;''/eo)); 13495 $dum = &missing_braces unless ( 13496 (s/$next_pair_pr_rx/$dum=$2;''/eo) 13497 ||(s/$next_pair_rx/$dum=$2;''/eo)); 13498 $dum = &missing_braces unless ( 13499 (s/$next_pair_pr_rx/$dum=$2;''/eo) 13500 ||(s/$next_pair_rx/$dum=$2;''/eo)); 13501 $title = &missing_braces unless ( 13502 (s/$next_pair_pr_rx/$title=$2;''/eo) 13503 ||(s/$next_pair_rx/$title=$2;''/eo)); 13504 $index_names{$key} = $title if ($key && $title); 13505 @_; 13506} 13507 13508# FOOTNOTES , also within Mini-page environments 13509# allow easy way to override and inherit; e.g. for frames 13510 13511sub do_cmd_footnotestar { &do_real_cmd_footnote(@_) } 13512sub do_cmd_footnote { &do_real_cmd_footnote(@_) } 13513sub do_real_cmd_footnote { 13514 local($_) = @_; 13515 local($cnt,$marker,$smark,$emark)=('', $footnote_mark); 13516 local($mark,$dum) = &get_next_optional_argument; 13517 local($anchor_name); 13518 13519 $footfile = "${PREFIX}$FOOT_FILENAME$EXTN" 13520 unless ($footfile||$MINIPAGE||$NO_FOOTNODE); 13521 13522 if ($mark) { 13523 $cnt = $mark; 13524 if ($MINIPAGE) { $global{'mpfootnote'} = $cnt } 13525 else { $global{'footnote'} = $cnt } 13526 } else { 13527 $cnt = (($MINIPAGE)? ++$global{'mpfootnote'} : ++$global{'footnote'}); 13528 } 13529 local($br_id, $footnote)=(++$global{'max_id'},''); 13530 $footnote = &missing_braces unless ( 13531 (s/$next_pair_pr_rx/${br_id}=$1; $footnote=$2;''/eo) 13532 ||(s/$next_pair_rx/${br_id}=$1; $footnote=$2;''/eo)); 13533 $br_id = "mp".$br_id if ($MINIPAGE); 13534 $marker = &get_footnote_mark($MINIPAGE); 13535 local($last_word) = &get_last_word(); 13536 local($href) = &make_href("$footfile#foot$br_id",$marker); 13537 if ($href =~ /NAME="([^"]*)"/) { $anchor_name=$1 } 13538 $last_word .= $marker unless ($anchor_name); 13539 &process_footnote($footnote,$cnt,$br_id,$last_word,$mark 13540 ,($MINIPAGE? $marker : '') 13541 ,($MINIPAGE? '' : "$marker:$anchor_name") ); 13542 # this may not work if there is a <BASE> tag and !($file) !!! # 13543# join('',&make_href("$file#foot$br_id",$marker),$_); 13544 $href . $_ 13545 } 13546 13547sub process_image_footnote { 13548 # MRO: modified to use $_[0] 13549 # local(*math) = @_; 13550 local($in_image, $keep, $pre, $this_anchor, $out, $foot_counters_recorded, @foot_anchors) = (1,'',''); 13551 local($image_contents) = $_[0]; 13552 $image_contents =~ s/\\(begin|end)(($O|$OP)\d+($C|$CP))tex2html_\w+\2//go; 13553 $image_contents =~ s!(\\footnote(mark\b\s*(\[[^\]]*\])?|\s*(\[[^\]]*\])?\s*(($O|$OP)\d+($C|$CP))(.*)\5))! 13554 $keep = $`; $out = '\footnotemark '.$3.$4; 13555 #MRO: $*=1; local($saveRS) = $/; $/=''; 13556 if ($8) { 13557 $this_anchor = &do_cmd_footnote($2); 13558 } else { 13559 $this_anchor = &do_cmd_footnotemark($3); 13560 } 13561 #MRO: $*=0; $/ = $saveRS; 13562 $foot_counters_recorded = 1; 13563 push(@foot_anchors, $this_anchor); 13564 $out!oesg; 13565 $_[0] = $image_contents; 13566 @foot_anchors; 13567 } 13568 13569sub do_cmd_thanks { &do_cmd_footnote(@_); } 13570 13571sub get_footnote_mark { 13572 local($mini) = @_; 13573 return($footnote_mark) if ($HTML_VERSION < 3.0 ); 13574 local($cmd,$tmp,@tmp,$marker); 13575 $cmd = "the". (($mini)? 'mp' : '') . "footnote"; 13576 if ($new_command{$cmd}) { 13577 $tmp = "do_cmd_$cmd"; 13578 @tmp = split (':!:', $new_command{$cmd}); 13579 pop @tmp; $tmp = pop @tmp; 13580 if ($tmp =~ /$O/) { 13581### local($_) = &translate_commands($tmp); 13582 $marker = &translate_commands(&translate_environments($tmp)); 13583 &make_unique($marker); 13584### $marker = $_; 13585 } else { $marker = &translate_commands(&translate_environments($tmp)); } 13586 } elsif ($mini) { 13587 $marker = &translate_commands('\thempfootnote'); 13588 } elsif ((defined &do_cmd_thefootnote)||$new_command{'thefootnote'}) { 13589 local($br_id)=++$global{'max_id'}; 13590 $marker = &translate_environments("$O$br_id$C\\thefootnote$O$br_id$C"); 13591 } else { $marker = $footnote_mark; } 13592 join('','<SUP>',$marker,'</SUP>'); 13593 } 13594 13595sub make_numbered_footnotes { 13596 eval "sub do_cmd_thefootnote {\&numbered_footnotes}" } 13597sub numbered_footnotes { &do_cmd_arabic('<<0>>footnote<<0>>');} 13598 13599# default numbering style for minipage notes 13600sub do_cmd_thempfootnote { &do_cmd_arabic('<<0>>mpfootnote<<0>>'); } 13601 13602sub do_cmd_footnotemark { &do_real_cmd_footnotemark(@_) } 13603sub do_real_cmd_footnotemark { 13604 local($_) = @_; 13605 local($br_id, $footnote,$marker,$mpnote,$tmp,$smark,$emark); 13606 # Don't use ()'s for the optional argument! 13607 local($mark,$dum) = &get_next_optional_argument; 13608 local ($cnt,$text_known) = ('',''); 13609 if ($mark) { 13610 $cnt = (($mark =~ /\\/)? &translate_commands($mark) : $mark); 13611 if (($MINIPAGE)&&($mpfootnotes{$cnt})) { 13612 $mpnote = 1; 13613 $br_id = $mpfootnotes{$cnt}; 13614 $text_known = 1; 13615 } else { 13616 $global{'footnote'} = $cnt; 13617 local($tmp) = $footnotes{$cnt}; 13618 if ($tmp) { 13619 $br_id = $tmp; 13620 $text_known = 1; 13621 } else { $footnotes{$cnt} = $br_id } 13622 } 13623 } else { 13624 $cnt = ++$global{'footnote'}; 13625 $text_known = 1 if ($footnotes{$cnt}); 13626 } 13627 if ($text_known) { 13628 $br_id = ($MINIPAGE ? $mpfootnotes{$cnt} : $footnotes{$cnt}); 13629 $marker = &get_footnote_mark($mpnote); 13630 return (join('', &make_href("$footfile#foot$br_id",$marker),$_)); 13631 } 13632 13633 local($last_word) = &get_last_word() unless ($mpnote); 13634 13635 # Try to find a \footnotetext further on. 13636 do { 13637 if (s/\\footnotetext\s*\[\s*$cnt\s*]*\]\s*$any_next_pair_pr_rx//o) { 13638 ($br_id, $footnote) = ($2, $3); 13639 } else { 13640 $br_id = "fnm$cnt"; 13641 $footnotes{$cnt} = $br_id; 13642 } 13643 } unless ($br_id); 13644 13645 $marker = &get_footnote_mark($mpnote); 13646 $last_word .= $marker unless ($marker =~ /$footnote_mark/ ); 13647 if ($footnote) { 13648 # found a \footnotetext further on 13649 &process_footnote($footnote,$cnt,$br_id,$last_word,$mark); 13650 join('',&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_); 13651 } elsif ($br_id =~ /fnm/) { 13652 # no \footnotetext yet, so make the entry in $footnotes 13653 &process_footnote('',$cnt,$br_id,$last_word,$mark); 13654 # this may not work if there is a <BASE> tag and !($footfile) !!! # 13655 join('',&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_); 13656 } elsif ($br_id) { 13657 # \footnotetext already processed 13658 if ($mpnote) { 13659 $mpfootnotes =~ s/(=\"$br_id\">...)(<\/A>)/$1$last_word$3/ 13660 if ($last_word); 13661 # this may not work if there is a <BASE> tag !!! # 13662 join('',&make_named_href("foot$br_id","#$br_id",$marker),$_); 13663 } else { 13664 $footnotes =~ s/(=\"$br_id\">...)(<\/A>)/$1$last_word$3/; 13665 # this may not work if there is a <BASE> tag and !($footfile) !!! # 13666 join('' 13667 ,&make_named_href("foot$br_id","$footfile#$br_id",$marker),$_); 13668 } 13669 } else { 13670 print "\nCannot find \\footnotetext for \\footnotemark $cnt"; 13671 # this may not work if there is a <BASE> tag and !($footfile) !!! # 13672 join('',&make_named_href("foot$br_id","$footfile",$marker),$_); 13673 } 13674 } 13675 13676# Under normal circumstances this is never executed. Any commands \footnotetext 13677# should have been processed when the corresponding \footnotemark was 13678# encountered. It is possible however that when processing pieces of text 13679# out of context (e.g. \footnotemarks in figure and table captions) 13680# the pair of commands gets separated. Until this is fixed properly, 13681# this command just puts the footnote in the footnote file in the hope 13682# that its context will be obvious .... 13683sub do_cmd_footnotetext { 13684 local($_) = @_; 13685 local($mark,$dum) = &get_next_optional_argument; 13686 local($br_id, $footnote, $prev, $key)=(1,'','',''); 13687 $footnote = &missing_braces unless ( 13688 (s/$next_pair_pr_rx/($br_id,$footnote)=($1,$2);''/eo) 13689 ||(s/$next_pair_rx/($br_id,$footnote)=($1,$2);''/eo)); 13690 13691 $mark = $global{'footnote'} unless $mark; 13692 $prev = $footnotes{$mark}; 13693 if ($prev) { 13694 $prev = ($MINIPAGE ? 'mp' : '') . $prev; 13695 # first prepare the footnote-text 13696 $footnote = &translate_environments("${OP}$br_id$CP$footnote${OP}$br_id$CP") 13697 if ($footnote); 13698 $footnote = &translate_commands($footnote) if ($footnote =~ /\\/); 13699 13700 # now merge it onto the Footnotes page 13701 $footnotes =~ s/(=\"$prev\">\.\.\.)(.*<\/A>)(<\/DT>\n<DD>)\n/ 13702 $1.'<html_this_mark>'.$3.$footnote/e; 13703 local($this_mark) = $2; 13704 $this_mark =~ s|(<SUP>)(?:<#\d+#>)?(\d+)(?:<#\d+#>)?(<\/SUP>)(<\/A>)$| 13705 "$4<A\n HREF=\"$CURRENT_FILE\#foot$prev\">$1$2$3$4"|e; 13706 $footnotes =~ s/<html_this_mark>/$this_mark/; 13707 } else { 13708 &process_footnote($footnote,$mark,$br_id,'','') if $footnote; 13709 } 13710 $_; 13711 } 13712 13713 13714sub process_footnote { 13715 # Uses $before 13716 # Sets $footfile defined in translate 13717 # Modifies $footnotes defined in translate 13718 local($footnote, $cnt, $br_id, $last_word, $mark, $mini, $same_page) = @_; 13719 local($target) = $target; 13720 13721 # first prepare the footnote-text 13722 local($br_idd, $fcnt); $br_id =~ /\D*(\d+)/; $br_idd = $1; 13723 $footnote = &translate_environments("$O$br_idd$C$footnote$O$br_idd$C") 13724 if ($footnote); 13725 $footnote = &translate_commands($footnote) if ($footnote =~ /\\/); 13726 13727 local($space,$sfoot_style,$efoot_style) = ("\n",'',''); 13728 if ((!$NO_FOOTNODE)&&(!$mini)&&(!$target)) { 13729 $footfile = "${PREFIX}$FOOT_FILENAME$EXTN"; 13730 $space = ".\n" x 30; 13731 $space = "\n<PRE>$space</PRE>"; 13732 } elsif ($target) { 13733 $target = $frame_body_name 13734 if (($frame_body_name)&&($target eq $frame_foot_name)); 13735 $sfoot_style = '<SMALL>'; 13736 $efoot_style = '</SMALL>'; 13737 } 13738 13739 if ($mark) { 13740 if ($mini) { 13741 $cnt = $mpfootnotes{$mark}; 13742 if ($in_image) { 13743 $fcnt = $global{'mpfootnote'}; --$fcnt if $fcnt; 13744 $latex_body .= '\setcounter{mpfootnote}{'.($fcnt||"0")."}\n" 13745 unless ($foot_counters_recorded); 13746 } 13747 } else { 13748 $cnt = $footnotes{$mark}; 13749 if ($in_image) { 13750 $fcnt = $global{'footnote'}; --$fcnt if $fcnt; 13751 $latex_body .= '\setcounter{footnote}{'.($fcnt||"0")."}\n" 13752 unless ($foot_counters_recorded); 13753 } 13754 } 13755 if ($cnt) { 13756 &write_warnings("\nredefined target for footnote $mark" ) 13757 unless ( $cnt eq $br_id ) 13758 } 13759 if ($mini) { $mpfootnotes{$mark} = "$br_id" } 13760 elsif ($br_id =~ /fnm\d+/) { 13761 $mark = "$footnotes{$cnt}"; 13762 $footnotes{$cnt} = "$br_id"; 13763# $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">..." 13764 $footnotes .= "\n<DT>$sfoot_style<A NAME=\"$br_id\">..." 13765 . $last_word . "</A>$efoot_style</DT>\n<DD>\n" 13766 . $space . "\n</DD>"; 13767 return; 13768 } else { $footnotes{$mark} = "$br_id" } 13769 } else { 13770 if ($mini) { 13771 $mpfootnotes{$cnt} = "$br_id"; 13772 if ($in_image) { 13773 $fcnt = $global{'mpfootnote'}; --$fcnt if $fcnt; 13774 $latex_body .= '\setcounter{mpfootnote}{'.($fcnt||"0")."}\n" 13775 unless ($foot_counters_recorded); 13776 } 13777 } else { 13778 $footnotes{$cnt} = "$br_id"; 13779 if ($in_image) { 13780 $fcnt = $global{'footnote'}; --$fcnt if $fcnt; 13781 $latex_body .= '\setcounter{footnote}{'.($fcnt||"0")."}\n" 13782 unless ($foot_counters_recorded); 13783 } 13784 } 13785 } 13786 13787 # catch a \footnotemark *after* the \footnotetext 13788 if ((!$footnote)&&($last_word)&&(!$mini)) { 13789# $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">..." 13790 $footnotes .= "\n<DT>$sfoot_style<A NAME=\"$br_id\">..." 13791 . $last_word 13792 . "</A>$efoot_style</DT>\n<DD>\n" . $space . "\n</DD>"; 13793 13794 } elsif ($mini) { 13795 if ($HTML_VERSION < 3.0) { $mini .= "." } 13796 $mpfootnotes .= "\n<DD>$sfoot_style<A NAME=\"foot$br_id\">$mini</A> " . 13797 $footnote . $efoot_style . "\n</DD>\n"; 13798 } elsif ($same_page) { 13799 local($link,$text); 13800 $same_page =~ s/:/$text=$`;$link=$';''/e; 13801 $same_page = &make_named_href("","$CURRENT_FILE\#$link",$text) if($link); 13802 $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">...$last_word</A>" 13803 . $same_page . $efoot_style . "</DT>\n<DD>" . $sfoot_style 13804 . $footnote . $efoot_style . "\n". $space . "\n</DD>"; 13805 } else { 13806 $footnotes .= "\n<DT>$sfoot_style<A NAME=\"foot$br_id\">...$last_word</A>" 13807 . $efoot_style . "</DT>\n<DD>" . $sfoot_style 13808 . $footnote . "$efoot_style\n" . $space . "\n</DD>"; 13809 } 13810 } 13811 13812 13813sub do_cmd_appendix { 13814 $latex_body .= "\\appendix\n"; 13815 if ($section_commands{$outermost_level} == 3) { 13816 $global{'section'} = 0; 13817 &reset_dependents('section'); 13818 eval "sub do_cmd_thesection{ &do_cmd_the_appendix(3,\@_) }"; 13819 } else { 13820 $global{'chapter'} = 0; 13821 &reset_dependents('chapter'); 13822 eval "sub do_cmd_thechapter{ &do_cmd_the_appendix(2,\@_) }"; 13823 } 13824 $_[0]; 13825 } 13826 13827sub do_cmd_the_appendix { 13828 local($val,$level) = (0,$_[0]); 13829 if ($level == 3) { $val=$global{'section'} } 13830 elsif ($level == 2) { $val=$global{'chapter'} } 13831 join('', &fAlph($val), '.', $_[1]); 13832 } 13833 13834sub do_cmd_appendixname { $app_title . $_[0] } 13835sub do_cmd_abstractname { $abs_title . $_[0] } 13836sub do_cmd_keywordsname { $key_title . $_[0] } 13837sub do_cmd_subjclassname { $sbj_title . $_[0] } 13838sub do_cmd_indexname { $idx_title . $_[0] } 13839sub do_cmd_contentsname { $toc_title . $_[0] } 13840sub do_cmd_datename { $date_name . $_[0] } 13841sub do_cmd_refname { $ref_title . $_[0] } 13842sub do_cmd_bibname { $bib_title . $_[0] } 13843sub do_cmd_figurename { $fig_name . $_[0] } 13844sub do_cmd_listfigurename { $lof_title . $_[0] } 13845sub do_cmd_tablename { $tab_name . $_[0] } 13846sub do_cmd_listtablename { $lot_title . $_[0] } 13847sub do_cmd_partname { $part_name . $_[0] } 13848sub do_cmd_chaptername { $chapter_name . $_[0] } 13849sub do_cmd_sectionname { $section_name . $_[0] } 13850sub do_cmd_subsectionname { $subsection_name . $_[0] } 13851sub do_cmd_subsubsectionname { $subsubsection_name . $_[0] } 13852sub do_cmd_paragraphname { $paragraph_name . $_[0] } 13853sub do_cmd_thmname { $thm_title . $_[0] } 13854sub do_cmd_proofname { $prf_name . $_[0] } 13855sub do_cmd_footnotename { $foot_title . $_[0] } 13856sub do_cmd_childlinksname { '<STRONG>'.$child_name.'</STRONG>'. $_[0] } 13857sub do_cmd_infopagename { $info_title . $_[0] } 13858 13859 13860sub do_cmd_ref { 13861 local($_) = @_; 13862 &bprocess_ref('bilink',''); 13863 } 13864 13865sub do_cmd_eqref { 13866 local($_) = @_; 13867 join('','(',&process_ref($cross_ref_mark,$cross_ref_mark,'',')')); 13868 } 13869 13870sub do_cmd_pageref { 13871 local($_) = @_; 13872 &process_ref($cross_ref_mark,$cross_ref_visible_mark); 13873 } 13874 13875# This is used by external style files ... 13876sub process_ref { 13877 local($ref_mark, $visible_mark, $use_label, $after_label) = @_; 13878 $use_label = &balance_inner_tags($use_label) 13879 if $use_label =~ (/<\/([A-Z]+)>($math_verbatim_rx.*)<\1>/); 13880 $use_label = &translate_environments($use_label); 13881 $use_label = &simplify(&translate_commands($use_label)) 13882 if ($use_label =~ /\\/ ); 13883 local($label,$id); 13884 local($pretag) = &get_next_optional_argument; 13885 $pretag = &translate_commands($pretag) if ($pretag =~ /\\/); 13886 $label = &missing_braces unless ( 13887 (s/$next_pair_pr_rx/($id, $label) = ($1, $2);''/eo) 13888 ||(s/$next_pair_rx/($id, $label) = ($1, $2);''/eo)); 13889 if ($label) { 13890 $label =~ s/<[^>]*>//go ; #RRM: Remove any HTML tags 13891 $label =~ s/$label_rx/_/g; # replace non alphanumeric characters 13892 13893 $symbolic_labels{"$pretag$label$id"} = $use_label if ($use_label); 13894 if (($symbolic_labels{$pretag.$label})&&!($use_label)) { 13895 $use_label = $symbolic_labels{$pretag.$label} 13896 } 13897# if (!($use_label eq $label)) { 13898# $symbolic_labels{"$label$id"} = $use_label; 13899# }; 13900 # if $use_label is empty then $label is used as the cross_ref_mark 13901 # elseif $use_label is a string then $use_label is used 13902 # else the usual mark will be used 13903 $use_label = ( (!$use_label && $label) || $use_label); 13904 13905 print "\nLINK: $ref_mark\#$label\#$id :$use_label:" if ($VERBOSITY > 3); 13906 # The quotes around the HREF are inserted later 13907 join('',"<A HREF=$ref_mark#$label#$id>$visible_mark<\/A>",$after_label, $_); 13908 } 13909 else { 13910 print "Cannot find label argument after <$last_word>\n" if $last_word; 13911 $after_label . $_; 13912 } 13913 } 13914 13915#RRM: This removes unbalanced tags, due to closures for math inside 13916# the label-text for an <A> anchor. 13917sub balance_inner_tags { 13918 local($text) = @_; 13919 return($text) unless ($text =~ /<\/([A-Z]+)>(\s*$math_verbatim_rx.*)(<\1( [^>]*)?>)/); 13920 local($beforeT,$afterT,$tag,$math_verb,$stag) = ($`,$',$1,$2,$3); 13921 if (!($beforeT =~ /<$tag>/)) { 13922 $text = join('', $beforeT, $math_verb, $afterT); 13923 return (&balance_inner_tags($text)); 13924 } 13925 local(@pieces) = split (/<$tag>/, $beforeT ); 13926 $beforeT = shift (@pieces); 13927 local($cnt,$this) = (0,''); 13928 while (@pieces) { 13929 $this = shift @pieces; 13930 $cnt++; 13931 $beforeT .= "<$tag>".$this; 13932 $cnt = $cnt - ($this =~ /<\/$tag>/g); 13933 } 13934 if ($cnt) { 13935 $beforeT .= "<\/$tag>" . $math_verb . $stag; 13936 $text = $beforeT . $afterT; 13937 } else { 13938 $beforeT .= $math_verb; 13939 $text = join('', $beforeT, $math_verb, $afterT); 13940 return (&balance_inner_tags($text)); 13941 } 13942 $text; 13943 } 13944 13945# Uses $CURRENT_FILE defined in translate 13946sub do_cmd_label { 13947 local($_) = @_; 13948 local($label); 13949 $label = &missing_braces unless ( 13950 (s/$next_pair_pr_rx\n?/$label = $2;''/eo) 13951 ||(s/$next_pair_rx\n?/$label = $2;''/eo)); 13952 &anchor_label($label,$CURRENT_FILE,$_); 13953 } 13954 13955# This subroutine is also used to process labels in undefined environments 13956sub anchor_label { &real_anchor_label(@_) } 13957sub real_anchor_label { 13958 # Modifies entries in %ref_files defined in translate 13959 local($label,$filename,$context) = @_; 13960 $label =~ s/<[^>]*>//go; #RRM: Remove any HTML tags 13961 $label =~ s/$label_rx/_/g; # replace non alphanumeric characters 13962 # Associate the label with the current file 13963 if ($ref_files{$label} ne $filename) { 13964 $ref_files{$label} = $filename; 13965 $noresave{$label} = 0; $changed = 1; } 13966 print "<LABEL: $label>" if ($VERBOSITY > 3); 13967 join('',"<A NAME=\"$label\">$anchor_mark</A>",$context); 13968} 13969 13970sub do_cmd_cite { 13971 local($_) = @_; 13972 &process_cite('',''); 13973 } 13974 13975 13976# This just creates a link from a label (yet to be determined) to the 13977# cite_key in the citation file. 13978sub process_cite { &process_real_cite(@_) } 13979sub process_real_cite { 13980 local($mode,$text) = @_; 13981 my $has_text = (($text)? 1 : 0); 13982# local($target) = 'contents';print "\nCITE:$text"; 13983 # process the text from \htmlcite or \hypercite 13984 if ($has_text) { 13985 $text = &balance_inner_tags($text) 13986 if $use_label =~ (/<\/([A-Z]+)>($math_verbatim_rx.*)<\1>/); 13987 $text = &translate_environments($text); 13988 $text = &simplify(&translate_commands($text)) 13989 if ($use_label =~ /\\/ ); 13990 } 13991 13992 my $label, $cite_key, $pretag, @cite_keys; 13993 local($optional_text,$dummy) = &get_next_optional_argument; 13994 if ($mode =~ /external/) { 13995# $target = ''; 13996 $pretag = $optional_text; $optional_text = ''; 13997 $pretag = &translate_commands($pretag) if ($pretag =~ /\\/); 13998 } else { 13999 $optional_text = ", $optional_text" if $optional_text; 14000 } 14001 s/^\s*\\space//o; # Hack - \space is inserted in .aux 14002 s/$next_pair_pr_rx//o||s/$next_pair_rx//o; 14003 if (!($cite_key = $2)) { 14004 print "\n *** Cannot find citation argument\n"; 14005 return ($_); 14006 } 14007 @cite_keys = (split(/,/,$cite_key)); 14008 my ($citations, $join) = ('',','); 14009 $join = '' if ($text); 14010 foreach $cite_key (@cite_keys) { 14011 $cite_key =~ s/(^\s+|\s+$)//g; 14012 $cite_key =~ s/(^\s+|\s+$)//g; 14013 # RRM: if the URL and printable-key are known already, then use them... 14014 $cite_key =~ s/$label_rx/_/g; 14015 $label = $cite_key; 14016 if ($mode eq "nocite") { 14017 # nothing more to do, no citations 14018 } elsif ( ($SEGMENT) && ($cite_info{$cite_key}) 14019 && ($ref_files{"cite_$cite_key"}) ) { 14020 $join = "," unless ($text); 14021 $text = $cite_info{$cite_key} unless ($text); 14022 $citations .= join('', $join 14023 , &make_named_href($label,$ref_files{'cite_'."$cite_key"},$text)); 14024 } elsif (($mode eq "external")&&($external_labels{$pretag."cite_$cite_key"})) { 14025 $join = "," unless ($text); 14026 $text = $cross_ref_visible_mark unless ($text); 14027 $citations .= join('', $join 14028 , &make_named_href($label 14029 , $external_labels{$pretag.'cite_'."$cite_key"}."\#$label" 14030 , $text) 14031 ); 14032 } elsif ($mode eq 'external') { 14033 $join = "," unless ($text); 14034 &write_warnings("\nExternal reference missing for citation: $pretag$cite_key"); 14035 $citations .= "$text$join#!$pretag$cite_key!#"; 14036 } else { 14037 $join = "," unless ($text); 14038 #Replace the key... 14039 $citations .= "$join#$cite_key#$cite_mark#$bbl_nr#$text#$cite_mark#"; 14040 } 14041 $text = ''; 14042 } 14043 $citations =~ s/^\s*,\s*//; 14044 if ($has_text) { join('', $citations, $optional_text, $_) } 14045 else { join('', "[", $citations, $optional_text, "]", $_) } 14046 } 14047 14048sub do_cmd_index { &do_real_index(@_) } 14049sub do_real_index { 14050 local($_) = @_; 14051 local($br_id, $str); 14052 local($idx_option) = &get_next_optional_argument; 14053 $str = &missing_braces unless ( 14054 (s/$next_pair_pr_rx/($br_id, $str) = ($1, $2);''/eo) 14055 ||(s/$next_pair_rx/($br_id, $str) = ($1, $2);''/eo)); 14056 join('',&make_index_entry($br_id,$str),$_); 14057 } 14058sub do_cmd_indexstar { &do_cmd_index(@_) } 14059 14060# RRM: \bibcite supplies info via the .aux file; necessary with segmented docs. 14061sub do_cmd_bibcite { 14062 local($_) = @_; 14063 local($br_id, $cite_key,$print_key); 14064 $cite_key = &missing_braces unless ( 14065 (s/$next_pair_pr_rx/($br_id, $cite_key) = ($1, $2);''/eo) 14066 ||(s/$next_pair_rx/($br_id, $cite_key) = ($1, $2);''/eo)); 14067 $print_key = &missing_braces unless ( 14068 (s/$next_pair_pr_rx/($br_id, $print_key) = ($1, $2);''/eo) 14069 ||(s/$next_pair_rx/($br_id, $print_key) = ($1, $2);''/eo)); 14070 $cite_key =~ s/$label_rx/_/g; 14071 $cite_info{$cite_key} = $print_key; 14072 $_; 14073 } 14074 14075# This command will only be encountered inside a thebibliography environment. 14076sub do_cmd_bibitem { &do_real_bibitem($CURRENT_FILE, @_) } 14077sub do_real_bibitem { 14078 local($thisfile, $_) = @_; 14079 # The square brackets may contain the label to be printed 14080 local($label, $dummy) = &get_next_optional_argument; 14081 # Support for the "named" bibliography style 14082 if ($label) { 14083 $label =~ s/\\protect//g; 14084 $label = &translate_commands($label) if ($label =~ /\\/); 14085 } 14086 local($cite_key); 14087 $cite_key = &missing_braces unless ( 14088 ( s/$next_pair_pr_rx/$cite_key=$2;''/e ) 14089 ||( s/$next_pair_rx/$cite_key=$2;''/e )); 14090 14091 $cite_key =~ s/$label_rx/_/g; 14092 $label = $cite_info{$cite_key} unless $label; # read from .aux file 14093 $label = ++$bibitem_counter unless $label; # Numerical labels 14094 14095 if ($cite_key) { 14096 # Associate the cite_key with the printed label. 14097 # The printed label will be substituted back into the document later. 14098 $cite_info{$cite_key} = &translate_commands($label); 14099 if (!($ref_files{'cite_'."$cite_key"} eq $thisfile)) { 14100 $ref_files{'cite_'."$cite_key"} = $thisfile; 14101 $changed = 1; } 14102 14103 #RRM: apply any special styles, as defined below 14104 $label = &bibitem_style($label) if (defined &bibitem_style); 14105 # Create an anchor around the citation 14106 join('',"<P></P><DT><A NAME=\"$cite_key\">$label</A>\n<DD>", $_); 14107 14108 } else { 14109 print "Cannot find bibitem labels: $label\n"; 14110 14111 #RRM: apply any special styles, as defined below 14112 $label = &bibitem_style($label) if (defined &bibitem_style); 14113 join('',"<P></P><DT>$label\n<DD>", $_); # AFEB added this line 14114 } 14115 } 14116 14117#RRM: override this with a personal style, defined in .latex2html-init 14118#sub bibitem_style { join('','<STRONG>',$_[0],'</STRONG>') } 14119sub bibitem_style { 14120 return ($_[0]) unless $BIBITEM_STYLE; 14121 local($text) = join('' 14122 ,"${O}0$C",$BIBITEM_STYLE,"${O}1$C", @_, "${O}1$C","${O}0$C"); 14123 $text = &translate_environments($text); 14124 &translate_commands($text); 14125 } 14126 14127sub do_cmd_newblock { 14128 "<BR>".$_[0] 14129 } 14130 14131# This just reads in the $FILE.bbl file if it is available and appends 14132# it to the items that are still to be processed. 14133# The $FILE.bbl should contain a thebibliography environment which will 14134# cause its contents to be processed later in the appropriate way. 14135# (Note that it might be possible for both the \bibliography command and 14136# the thebibliography environment to be present as the former may have been 14137# added by the translator as a sectioning command. In this case (both present) 14138# the $citefile would have already been set by the thebibliography environment) 14139 14140sub do_cmd_bibliography { &do_real_bibliography($CURRENT_FILE, @_) } 14141sub do_real_bibliography { 14142 local($thisfile, $after) = @_; 14143 if ((defined &do_cmd_bibname)||$new_command{'bibname'}) { 14144 local($br_id)=++$global{'max_id'}; 14145 $TITLE = &translate_environments("$O$br_id$C\\bibname$O$br_id$C"); 14146 } else { $TITLE = $bib_title } 14147 $toc_sec_title = $TITLE; 14148 return($_[0]) if ($making_name); 14149 local($bibfile); 14150 $bibfile = &missing_braces unless ( 14151 ($after =~ s/$next_pair_rx/$bibfile=$2;''/eo)|| 14152 ($after =~ s/$next_pair_rx_rx/$bibfile=$2;''/eo)); 14153 14154 do { 14155 unless ($citefile) { 14156 $citefile = $thisfile; 14157 if (&process_ext_file("bbl")) { # *** BINDS $_ as a side effect *** 14158 $after = join('',$_,$after);} 14159 else { 14160 print "\nCannot open $FILE.bbl $!\n"; 14161 &write_warnings("\nThe bibliography file was not found."); 14162 $after = join('',"\n<H2>No References!</H2>", $after); 14163 } 14164 } 14165 print "\n"; 14166 } if $bibfile; 14167 $after; 14168 } 14169 14170# allow for customised info-pages, for different languages 14171sub do_cmd_textohtmlinfopage { 14172 local($_) = @_; 14173 local($linfo) = $TITLES_LANGUAGE . '_infopage'; 14174 if (defined &$linfo) { eval "&$linfo"; } 14175 else { &default_textohtmlinfopage } 14176 } 14177 14178sub default_textohtmlinfopage { 14179 local($_) = @_; 14180 local($argv) = $argv; 14181 if (-f "../$argv") { $argv = &make_href ("../$argv", $argv, ); } 14182 $_ = ($INFO && $INFO =~ /^\d+$/ 14183 ? join('', $close_all 14184 , "<STRONG>$t_title</STRONG><P>\nThis document was generated using the\n" 14185 , "<A HREF=\"$TEX2HTMLADDRESS\"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A>" 14186 , " translator Version $TEX2HTMLVERSION\n" 14187 , "<P>Copyright © 1993, 1994, 1995, 1996,\n" 14188 , "Nikos Drakos, \n" 14189 , "Computer Based Learning Unit, University of Leeds.\n" 14190 , "<BR>Copyright © 1997, 1998, 1999,\n" 14191 , "<A HREF=\"$AUTHORADDRESS2\">Ross Moore</A>, \n" 14192 , "Mathematics Department, Macquarie University, Sydney.\n" 14193 , "<P>The command line arguments were: <BR>\n " 14194 , "<STRONG>latex2html</STRONG> <TT>$argv</TT>\n" 14195 , (($SHOW_INIT_FILE && ($INIT_FILE ne ''))? 14196 "\n<P>with initialization from: <TT>$INIT_FILE</TT>\n$init_file_mark\n" :'') 14197 , "<P>The translation was initiated by $address_data[0] on $address_data[1]" 14198 , $open_all, $_) 14199 : join('', $close_all, "$INFO\n", $open_all, $_)); 14200 $_; 14201 } 14202 14203 14204# Try to translate LaTeX vertical space in a number of <BR>'s. 14205# Eg. 1cm results in one + two extra <BR>'s. 14206# To help the browser rendering is quite ugly, but why not. 14207# 14208sub get_vspace { 14209 local($_) = @_; 14210 local($vh) = 0; 14211 14212 return("<BR>") if /-/; 14213 14214 $vh = int($1 * $vspace_12pt{$2} + 0.5) 14215 if (/([0-9.]+)\s*([a-z]+)/); 14216 join('',"<BR>","\n<BR>" x $vh); 14217 } 14218 14219sub do_cmd_vskip { 14220 local($_) = @_; 14221 &ignore_numeric_argument; 14222 join('',&get_vspace($1),$_); 14223 } 14224 14225sub do_cmd_break { 14226 local($_) = @_; 14227 join('',"<BR>",$_); 14228 } 14229 14230sub do_cmd_vspace { 14231 local($_) = @_; 14232 local($how_much); 14233 $how_much = &missing_braces unless ( 14234 (s/$next_pair_pr_rx/$how_much = $2;''/e) 14235 ||(s/$next_pair_rx/$how_much = $2;''/e)); 14236 join('',&get_vspace($how_much),$_); 14237} 14238 14239sub do_cmd_vspacestar { 14240 &do_cmd_vspace; 14241} 14242 14243sub do_cmd_d_backslash { 14244 local($_) = @_; 14245 14246 # Eat space from &pre_process. 14247 # We could also modifiy $single_cmd_rx and %normalize, but why not here. 14248 s/^ \*?//; 14249 local($spc,$dum)=&get_next_optional_argument; 14250 # If the [...] occurs on the next line, then it is *not* an argument to \\ . 14251 # MRO: replaced $* with /m 14252 if ($dum =~ /\n/m) { 14253 $spc = $`; 14254 $spc =~ s/\s//gm; 14255 $_ = $'.$_ 14256 } 14257 join('',(($spc)? &get_vspace($spc): "\n<BR>"),$_); 14258 } 14259 14260 14261################## Commands used in the $FILE.aux file ####################### 14262 14263sub do_cmd_jobname { $FILE . $_[0] } 14264 14265# This is used in $FILE.aux 14266sub do_cmd_newlabel { 14267 local($_) = @_; 14268 local($label,$val,$tmp); 14269 $label = &missing_braces unless ( 14270 (s/$next_pair_pr_rx/$label = $2;''/eo) 14271 ||(s/$next_pair_rx/$label = $2;''/eo)); 14272 $tmp = &missing_braces unless ( 14273 (s/$next_pair_pr_rx/$tmp=$2;''/eo) 14274 ||(s/$next_pair_rx/$tmp=$2;''/eo)); 14275 $val = &missing_braces unless ( 14276 ($tmp =~ s/$next_pair_pr_rx/$val=$2;''/eo) 14277 ||($tmp =~ s/$next_pair_rx/$val=$2;''/eo)); 14278 $val =~ s/(^\s+|\s+$)//gs; 14279 $label =~ s/$label_rx/_/g; # Replace non alphanumeric characters 14280 $latex_labels{$label} = $val; 14281 &do_labels_helper($label); 14282 $_; 14283 } 14284sub do_cmd_oldnewlabel { &do_cmd_newlabel(@_) } 14285 14286# 14287# Sets %encoded_(section|figure|table)_number, which maps encoded 14288# section titles to LaTeX numbers 14289# .= \$number . \"$;\""; 14290sub do_cmd_oldcontentsline { &do_cmd_contentsline(@_) } 14291sub do_cmd_contentsline { 14292 local($_) = @_; 14293 local($arg,$after,$title,$number,$hash,$stype,$page); 14294 # The form of the expression is: 14295 # \contentsline{SECTION} {... {SECTION_NUMBER} TITLE}{PAGE} 14296 $stype = &missing_braces unless ( 14297 (s/$next_pair_pr_rx/$stype = $2;''/e) 14298 ||(s/$next_pair_rx/$stype = $2;''/e)); 14299 $arg = &missing_braces unless ( 14300 (s/$next_pair_pr_rx/$arg = $2;''/e) 14301 ||(s/$next_pair_rx/$arg = $2;''/e)); 14302 $page = &missing_braces unless ( 14303 (s/$next_pair_pr_rx/$page = $2;''/e) 14304 ||(s/$next_pair_rx/$page = $2;''/e)); 14305 14306# s/$any_next_pair_pr_rx/$stype = $2;''/eo; # Chop off {SECTION} 14307# s/$any_next_pair_pr_rx/$arg = $2;''/eo; # Get {... {SECTION_NUMBER} TITLE} 14308# s/$any_next_pair_pr_rx/$page = $2;''/eo; # Get page number 14309 $hash = $stype if (($stype =~ /^(figure|table)$/)||($SHOW_SECTION_NUMBERS)); 14310 $hash =~ s/(sub)*(section|chapter|part)/section/; 14311 $after = $_; 14312 if ($hash) { 14313 if ($arg =~ /^$OP/) { 14314 $number = &missing_braces unless ( 14315 ($arg =~ s/$next_pair_pr_rx/$number = $2;''/eo) 14316 ||($arg =~ s/$next_pair_rx/$number = $2;''/eo)); 14317 } 14318 if ($stype eq "part") { 14319 while ($arg =~ s/$next_pair_pr_rx//o) {}; 14320 $number =~ tr/a-z/A-Z/; 14321 $number = "Part $number:"} 14322 # This cause problem when picking figure numbers... 14323 # while ($tmp =~ s/$next_pair_pr_rx//o) {}; 14324 $number = -1 unless $number; 14325#JCL(jcl-tcl) 14326## $_ = $arg; 14327# $title = &sanitize($arg); 14328## &text_cleanup; 14329## $title = &encode_title($_); 14330## 14331 #remove surrounding brace-numbering 14332 $arg =~ s/^($O|$OP)\d+($C|$CP)|($O|$OP)\d+($C|$CP)$//g; 14333 $arg =~ s/\\footnote(mark|text)?//g; 14334 # \caption arguments should have had environments translated already 14335 $arg = &translate_environments($arg) if ($arg =~ /\\begin/); 14336 #replace image-markers by the image params 14337 $arg =~ s/$image_mark\#([^\#]+)\#/&purify_caption($1)/e; 14338 14339 #RRM: resolve any embedded cross-references first 14340 local($checking_caption) = 1; 14341 $title = &simplify($arg); 14342 $title = &sanitize($title); 14343 $checking_caption = ''; 14344 eval "\$encoded_${hash}_number{\$title} .= \$number . \"$;\""; 14345 } 14346 $after; 14347 } 14348 14349# 14350# Before normalizing this was \@input. Used in .aux files. 14351# 14352sub do_cmd__at_input { 14353 local ($_) = @_; 14354 local ($file, $after); 14355 $file = &missing_braces unless ( 14356 (s/$next_pair_pr_rx/$file=$2;''/eo) 14357 ||(s/$next_pair_rx/$file=$2;''/eo)); 14358 local($prefix, $suffix) = split(/\./, $file); 14359 $after = $_; 14360 local($EXTERNAL_FILE) = $prefix; 14361 &process_ext_file($suffix); 14362 $after; 14363 } 14364 14365 14366########################### Counter Commands ################################# 14367# Removes the definition from the input string, adds to the preamble 14368# and stores the body in %new_counter; 14369sub get_body_newcounter { 14370# local(*_) = @_; 14371 local($after_R) = @_; 14372 local($_) = $$after_R; 14373 local($within,$ctr,$cmd,$tmp,$body,$pat); 14374 local($new_ctr) = 'counter'; 14375 ($ctr,$pat) = &get_next(1); # Get counter name 14376 &write_warnings ("\n*** LaTeX Error: backslash found in counter-name: $ctr") 14377 if ($pat =~ s/\\//); 14378 $ctr =~ s/^\s*\\//; 14379 $new_ctr .= $pat; 14380 14381 ($within,$pat) = &get_next(0); # Get optional within, currently ignored 14382 &addto_dependents($within,$ctr); 14383 $new_ctr .= $pat; 14384 do { 14385### local($_) = "\\arabic<<1>>$ctr<<1>>"; 14386 $body = "\\arabic<<1>>$ctr<<1>>"; 14387 &make_unique($body); 14388 $cmd = "the$ctr"; 14389 $tmp = "do_cmd_$cmd"; 14390 $new_command{$cmd} = join(':!:',0,$body,'}') unless (defined &$tmp); 14391 &write_mydb("new_command", $cmd, $new_command{$cmd}); 14392 undef $body; 14393 }; 14394 &do_body_newcounter($ctr); 14395 14396 $$after_R = $_; 14397 if (!$PREAMBLE) { 14398 my $new_cmd = join('' 14399 , "counter{$ctr}", ($within ? "[$within]" : '') ); 14400 &add_to_preamble('counter','\\new'.$new_cmd); 14401 return (); 14402 } 14403 'newed'.$new_ctr; 14404 } 14405 14406sub do_body_newcounter { 14407 local($ctr) = @_; 14408 $latex_body .= &revert_to_raw_tex("\\newcounter{$ctr}\n") 14409 unless ($preamble =~ /\\new(counter|theorem){$ctr}/); 14410 $global{$ctr} = 0; 14411 &process_commands_wrap_deferred("the$ctr "); 14412 $_; 14413 } 14414 14415 14416#RRM: This doesn't work properly yet. 14417# The new booleans need to be stored for use in all partitions. 14418# \if... \else \fi is not yet implemented. 14419 14420sub get_body_newboolean { 14421# local(*_) = @_; 14422 local($after_R) = @_; 14423 local($_) = $$after_R; 14424 my $bool; 14425 $bool = &missing_braces unless ( 14426 (s/$next_pair_pr_rx/$bool=$2;''/e) 14427 ||(s/$next_pair_rx/$bool=$2;''/e)); 14428 $bool = &process_body_newif('',$bool); 14429 $$after_R = $_; 14430 'newed'.$bool; 14431 } 14432 14433sub get_body_newif { 14434# local(*_) = @_; 14435 local($after_R) = @_; 14436 local($_) = $$after_R; 14437 local($bool); 14438 if (!(s/^\s*\\if([a-zA-Z]+)//)) { 14439 $$after_R = $_; 14440 return(); 14441 } 14442 $bool = $1; 14443 $$after_R = $_; 14444 join('','newed', &process_body_newif('', $bool)); 14445 } 14446 14447 14448sub process_body_newif { 14449 local($texif, $bool) = @_; 14450 local($body,$ifbool,$cmd,$tmp,$pat); 14451 14452# ($bool,$pat) = &get_next(1); # Get boolean name 14453 14454# # change the brace-type around the command-name 14455# $pat =~ s/$O/$OP/; $pat =~ s/$C/$CP/; $new_cmd .= $pat; 14456 14457 $ifbool = "if".$bool; 14458 $global{$ifbool} = 0; 14459 14460 do { 14461 $body = "\$global{'$ifbool'} = 1;"; 14462 $cmd = $bool."true"; 14463 $code = "sub do_cmd_$cmd { ".$body." \$_[0];}"; 14464 eval $code; 14465 print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@); 14466 $raw_arg_cmds{$cmd} = 1; 14467 14468 $body = "\$global{$ifbool} = 0;"; 14469 $cmd = $bool."false"; 14470 $code = "sub do_cmd_$cmd { ".$body." \$_[0];}"; 14471 eval $code; 14472 print STDERR "\n*** sub do_cmd_$cmd failed:\n$@\n" if ($@); 14473 $raw_arg_cmds{$cmd} = 1; 14474 14475 undef $body; 14476 }; 14477 &process_commands_wrap_deferred("${bool}true\n${bool}false\nif$bool\n"); 14478 14479# $latex_body .= &revert_to_raw_tex("\\newif\\$ifbool\n") 14480# unless ($preamble =~ /\\newif\s*\\$ifbool/); 14481 14482 if (!$PREAMBLE) { 14483 local($new_cmd) = "boolean{\\$bool}"; 14484 &add_to_preamble ('newif', "\\new$new_cmd" ); 14485 return (); 14486 } 14487 local($br_id) = ++$global{'max_id'}; 14488 'boolean'."$O$br_id$C$bool$O$br_id$C"; 14489 } 14490 14491 14492sub do_cmd_value { 14493 local($_) = @_; 14494 local($ctr,$val); 14495 $ctr = &missing_braces 14496 unless ((s/$next_pair_pr_rx/$ctr = $2;''/eo) 14497 ||(s/$next_pair_rx/$ctr = $2;''/eo)); 14498 $val = &get_counter_value($ctr); 14499 if ($val) { $val.$_ } 14500 else { join(''," 0",$_) } 14501 } 14502 14503sub do_cmd_boolean { 14504 local($_) = @_; 14505 local($bool,$val); 14506 $bool = &missing_braces 14507 unless ((s/$next_pair_pr_rx/$bool = $2;''/eo) 14508 ||(s/$next_pair_rx/$bool = $2;''/eo)); 14509 $val = &get_boolean_value($bool); 14510 if ($val) { $val.$_ } 14511 else { "0".$_ } 14512 } 14513 14514sub get_counter_value { 14515 local($ctr) = @_; 14516 local($val,$index); 14517 $ctr = 'eqn_number' if ($ctr eq "equation"); 14518 $index = $section_commands{$ctr}; 14519 14520 if (defined $global{$ctr}) { $val= $global{$ctr}; } 14521 elsif (($SEGMENT)&&($index)) { 14522 $val = $segment_sec_id[$index] 14523# if ($index) { 14524# if ($SEGMENT) { $val = $segment_sec_id[$index] } 14525# else { $val = $curr_sec_id[$index] } 14526 } else { 14527 &write_warnings ("\ncounter $ctr not defined"); 14528 $val= 0; 14529 } 14530 print "\nVAL:$ctr: $val " if ($VERBOSITY > 3); 14531 $val; 14532 } 14533 14534sub get_boolean_value { 14535 local($bool) = @_; 14536 local($val,$index); 14537 if (defined $global{$bool}) { $val= $global{$bool} } 14538 else { 14539 &write_warnings ("boolean $bool not defined\n"); 14540 $val="0"; 14541 } 14542 print "\nBOOL:$bool: $val " if ($VERBOSITY > 3); 14543 $val; 14544 } 14545 14546sub do_cmd_addtocounter { 14547 local($_) = @_; 14548 local($ctr,$num,$index); 14549 $ctr = &missing_braces 14550 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14551 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14552 $num = &missing_braces 14553 unless ((s/$next_pair_rx/$num = $2;''/eo) 14554 ||(s/$next_pair_pr_rx/$num = $2;''/eo)); 14555 14556 $num = &translate_commands($num) if ($num =~ /\\/); 14557 if ($num !~ /^\s*(\+|-)?\d+\s*$/) { 14558 print STDERR "\n*** cannot set counter $ctr to $num ***\n"; 14559 return($_); 14560 } 14561 14562 $latex_body .= &revert_to_raw_tex("\\addtocounter{$ctr}{$num}\n"); 14563 print "PCT: do_cmd_addtocounter: index: $index\n" if ($VERBOSITY > 5) ; 14564 print "PCT: do_cmd_addtocounter: SEGMENT: $SEGMENT\n" if ($VERBOSITY > 5) ; 14565 print "PCT: do_cmd_addtocounter: section_commands: $section_commands\n" if ($VERBOSITY > 5) ; 14566 print "PCT: do_cmd_addtocounter: ctr: $ctr --- num: $num\n" if ($VERBOSITY > 5) ; 14567 print join('',"PCT: do_cmd_addtocounter: global:",$global{$ctr},"\n") if ($VERBOSITY > 5) ; 14568 $index = $section_commands{$ctr}; 14569 14570 if (defined $global{$ctr}) { 14571 $global{$ctr} += $num } 14572 elsif ($index) { 14573 if ($SEGMENT) { 14574 $segment_sec_id[$index] += $num 14575 } 14576 else { 14577 $curr_sec_id[$index] += $num 14578 } 14579 $global{$ctr} += $num; 14580 } 14581 elsif ($ctr eq "equation") { 14582 $global{'eqn_number'} += $num 14583 } 14584 else { 14585 $global{$ctr} += $num 14586 } 14587 print "\nADD:$ctr:+$num= ". $global{$ctr}." " if ($VERBOSITY > 3); 14588 $_; 14589 } 14590 14591sub do_cmd_setcounter { 14592 local($_) = @_; 14593 local($ctr,$num,$index,$sctr); 14594 $ctr = &missing_braces 14595 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14596 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14597 $num = &missing_braces 14598 unless ((s/$next_pair_rx/$num = $2;''/eo) 14599 ||(s/$next_pair_pr_rx/$num = $2;''/eo)); 14600 14601 $num = &translate_commands($num) if ($num =~ /\\/); 14602 if ($num !~ /^\s*(\+|-)?\d+\s*$/) { 14603 print STDERR "\n*** cannot set counter $ctr to $num ***\n"; 14604 return($_); 14605 } 14606 if ($ctr =~ /^l/) { 14607 $sctr = $'; 14608 $ctr = $sctr if $section_commands{$sctr}; 14609 } 14610 if (! $AUX_FILE && !($ctr =~ /page/ )) { 14611 $latex_body .= &revert_to_raw_tex("\\setcounter{$ctr}{$num}\n"); 14612 $index = $section_commands{$ctr}; 14613 if ($index) { 14614 if ($curr_sec_id[$index] <= $num ) { 14615 $curr_sec_id[$index] = $num 14616 } else { 14617 print "\nignoring \\setcounter{$ctr}{$num} currently at ",$curr_sec_id[$index] ; 14618 &write_warnings(join('',"\n\\setcounter{$ctr}{$num} ignored," 14619 ," cannot reduce from ",$curr_sec_id[$index])); 14620 } 14621 $global{$ctr} = $num; 14622 } elsif ($ctr eq "equation") {$global{'eqn_number'} = $num } 14623 else { $global{$ctr} = $num }; 14624 } 14625 print "\nSET:$ctr: = $num" if ($VERBOSITY > 3); 14626# &reset_dependents($ctr) if ($dependent{$ctr}); 14627 $_; 14628} 14629 14630sub do_cmd_setlength { 14631 local($_) = @_; 14632 local($dimen,$value,$index,$sctr); 14633 $dimen = &missing_braces 14634 unless ((s/$next_pair_rx/$dimen = $2;''/eo) 14635 ||(s/$next_pair_pr_rx/$dimen = $2;''/eo)); 14636 $value = &missing_braces 14637 unless ((s/$next_pair_rx/$value = $2;''/eo) 14638 ||(s/$next_pair_pr_rx/$value = $2;''/eo)); 14639 14640 # recognise specific length-parameters 14641 if ($dimen =~ /captionwidth/) { 14642 local($pxs,$len) = &convert_length($value, $MATH_SCALE_FACTOR); 14643 $cap_width = $pxs if ($pxs &&($dimen =~ /captionwidth/)); 14644 } 14645 if ((! $AUX_FILE)&&(! $PREAMBLE)) { 14646 $latex_body .= &revert_to_raw_tex("\\setlength{$dimen}{$value}\n"); 14647 print "\nSETLENGTH:$dimen = $value" if ($VERBOSITY > 3); 14648 } 14649 $_; 14650} 14651 14652 sub do_cmd_setboolean { 14653 local($_) = @_; 14654 local($bool,$val); 14655 $bool = &missing_braces 14656 unless ((s/$next_pair_rx/$bool = $2;''/eo) 14657 ||(s/$next_pair_pr_rx/$bool = $2;''/eo)); 14658 $val = &missing_braces 14659 unless ((s/$next_pair_rx/$val = $2;''/eo) 14660 ||(s/$next_pair_pr_rx/$val = $2;''/eo)); 14661 if (! $AUX_FILE) { 14662 $latex_body .= &revert_to_raw_tex("\\setboolean{$bool}{$val}\n"); 14663 $global{"if$bool"} = (($val = ~/true/) ? 1 : 0); 14664 print "\nSETBOOL:$bool = $val" if ($VERBOSITY > 3); 14665 } 14666 $_; 14667} 14668 14669sub do_cmd_endsegment { 14670 local($_) = @_; 14671 local($ctr,$dum) = &get_next_optional_argument; 14672 local($index,$steps) = ('',1); 14673# $steps = &missing_braces unless ( 14674# (s/$next_pair_pr_rx/$steps = $2;''/e) 14675# ||(s/$next_pair_rx/$steps = $2;''/e)); 14676 $index = $section_commands{$ctr} if $ctr; 14677# if ($index) { $curr_sec_id[$index] += $steps } 14678# if ($index) { ($after_segment,$after_seg_num) = ($index,$steps) } 14679 if ($index) { ($after_segment,$after_seg_num) = ($index,1) } 14680 $_; 14681} 14682 14683sub do_cmd_stepcounter { 14684 local($_) = @_; 14685 local($ctr,$index); 14686 $ctr = &missing_braces 14687 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14688 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14689 if (! $AUX_FILE) { 14690 $latex_body .= &revert_to_raw_tex("\\stepcounter{$ctr}\n"); 14691 $index = $section_commands{$ctr}; 14692 if ($index) { 14693# if ($SEGMENT) { $segment_sec_id[$index] += 1 } 14694# else { $curr_sec_id[$index] += 1 } 14695 $global{$ctr} += 1; 14696 } elsif ($ctr eq "equation") { $global{'eqn_number'} += 1 } 14697 else { $global{$ctr} += 1 }; 14698 } 14699 print "\nSTP:$ctr:+1" if ($VERBOSITY > 3); 14700 &reset_dependents($ctr) if ($dependent{$ctr}); 14701 $_; 14702} 14703 14704#RRM: dependent counters are stored as a comma-separated list 14705# in the %dependent hash. 14706sub reset_dependents { 14707 local($ctr) = @_; 14708 local($dep,$subdep,%dependents); 14709 @dependents = (split($delim, $dependent{$ctr})); 14710 print "\n" if (($VERBOSITY > 3)&&(@dependents)); 14711 while (@dependents) { 14712 $dep = pop(@dependents); 14713 print "RESET $dep to 0\n" if ($VERBOSITY > 3); 14714 if ($global{$dep}) { $global{$dep} = 0 } 14715 elsif ($dep =~ /equation/) { $global{'eqn_number'} = 0 } 14716 if ($dependent{$dep}) { 14717 push(@dependents,split($delim,$dependent{$dep})); 14718 } 14719 } 14720} 14721 14722sub do_cmd_numberwithin { 14723 local($_) = @_; 14724 local($ctr,$within); 14725 $ctr = &missing_braces 14726 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14727 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14728 $within = &missing_braces 14729 unless ((s/$next_pair_rx/$within = $2;''/eo) 14730 ||(s/$next_pair_pr_rx/$within = $2;''/eo)); 14731 14732 # record the counter dependency 14733 &addto_dependents($within,$ctr) if ($within); 14734 local($newsub) = "sub do_cmd_the$ctr {" 14735 . "\$global{'max_id'}++;\n" 14736# . "local(\$super)=\&do_cmd_the$within();\n" 14737 . "local(\$super)=\&translate_commands('\\the$within');\n" 14738 . "\$super .= '.' unless (\$super =~/\\.\$/);\n" 14739 . "\$super .\&do_cmd_value('<<'.\$global{'max_id'}.'>>" 14740 . $ctr . "<<'.\$global{'max_id'}.'>>')}\n"; 14741 eval $newsub; 14742 print " *** sub do_cmd_the$ctr unchanged *** $@ " if ($@); 14743 $_; 14744} 14745 14746sub do_cmd_refstepcounter { 14747 local($_) = @_; 14748 local($ctr); 14749 $ctr = &missing_braces 14750 unless ((s/$next_pair_rx/$ctr = $2;''/eo) 14751 ||(s/$next_pair_pr_rx/$ctr = $2;''/eo)); 14752 if (! $AUX_FILE) { 14753 $latex_body .= &revert_to_raw_tex("\\refstepcounter{$ctr}\n"); 14754 $index = $section_commands{$ctr}; 14755 if (defined $global{$ctr}) { $global{$ctr} += 1 } 14756 elsif ($index) { 14757 if ($SEGMENT) { $segment_sec_id[$index] += 1 } 14758 else { $curr_sec_id[$index] += 1 } 14759 } elsif ($ctr eq "equation") { $global{'eqn_number'} += 1 } 14760 else { $global{$ctr} += 1 }; 14761 } 14762 print "\nSTP: $ctr : +1" if ($VERBOSITY > 3); 14763 &reset_dependents($ctr) if ($dependent{$ctr}); 14764 $_; 14765} 14766 14767sub read_counter_value { 14768 local($_) = @_; 14769 local($ctr,$br_id,$val); 14770 $ctr = &missing_braces 14771 unless ((s/$next_pair_pr_rx/$br_id = $1; $ctr = $2;''/eo) 14772 ||(s/$next_pair_rx/$br_id = $1; $ctr = $2;''/eo)); 14773 $val = &get_counter_value($ctr); 14774 ($ctr, $val, $br_id, $_) 14775} 14776 14777sub styled_number_text { 14778 local($num_style, $val, $txtID) = @_; 14779 if ($USING_STYLES) { 14780 $txt_style{$num_style} = " " unless ($txt_style{$num_style}); 14781 join('',"<SPAN CLASS=\"$num_style\">", $val, "</SPAN>", $_); 14782 } else { $val.$_ } 14783} 14784 14785sub do_cmd_arabic { 14786 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14787 $val = ($val ? &farabic($val) : "0"); 14788 &styled_number_text('arabic', $val, $id); 14789} 14790 14791sub do_cmd_roman { 14792 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14793 if ($val < 0 ) { $val = join('',"-",&froman(-$val)); } 14794 elsif ($val) { $val = &froman($val) } 14795 else { $val = "0"; } 14796 &styled_number_text('roman', $val, $id); 14797} 14798 14799sub do_cmd_Roman { 14800 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14801 if ($val < 0 ) { $val = join('',"-",&fRoman(-$val)); } 14802 elsif ($val) { $val = &fRoman($val) } 14803 else { $val = "0"; } 14804 &styled_number_text('Roman', $val, $id); 14805} 14806 14807sub do_cmd_alph { 14808 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14809 if ($val < 0 ) { $val = join('',"-",&falph(-$val)); } 14810 elsif ($val) { $val = &falph($val) } 14811 else { $val = "0"; } 14812 &styled_number_text('alph', $val, $id); 14813} 14814 14815sub do_cmd_Alph { 14816 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14817 if ($val < 0 ) { $val = join('',"-",&fAlph(-$val)); } 14818 elsif ($val) { $val = &fAlph($val) } 14819 else { $val = "0"; } 14820 &styled_number_text('Alph', $val, $id); 14821} 14822 14823 14824sub do_cmd_fnsymbol { 14825 local($ctr, $val, $id, $_) = &read_counter_value($_[0]); 14826 $val = &process_in_latex_helper($ctr, $val, "fnsymbol{$ctr}"); 14827 &styled_number_text('Alph', $val, $id); 14828} 14829 14830 14831 14832# This is a general command for getting counter values; 14833# e.g. for section-numbers. 14834 14835sub do_cmd_thecounter { 14836 local($_) = @_; 14837 # Uses $counter bound by the caller 14838 local($val) = &get_counter_value($counter); 14839 $val = &process_in_latex_helper($counter,$val,"the$counter"); 14840 &styled_number_text($counter, $val, ''); 14841# join('',&process_in_latex_helper($counter,$val,"the$counter"),$_[0]); 14842} 14843 14844 14845################# Special Naming Macros ################################## 14846 14847sub do_cmd_LaTeX { 14848 local($_) = @_; 14849 if ($USING_STYLES) { 14850 $env_style{'LaTeX'} = ' ' unless ($env_style{'LaTeX'}); 14851 $env_style{'logo-LaTeX'} = ' ' unless ($env_style{'logo-LaTeX'}); 14852 join('',"<SPAN CLASS=\"logo,LaTeX\">",$Laname, $TeXname,"</SPAN>",$_); 14853 } else { join('',$Laname, $TeXname, $_); } 14854} 14855 14856sub do_cmd_LaTeXe { 14857 local($_) = @_; 14858 if ($USING_STYLES) { 14859 $env_style{'LaTeX2e'} = ' ' unless ($env_style{'LaTeX2e'}); 14860 $env_style{'logo-LaTeX2e'} = ' ' unless ($env_style{'logo-LaTeX2e'}); 14861 join('',"<SPAN CLASS=\"logo,LaTeX2e\">" 14862 ,$Laname, $TeXname,'2<SUB>e</SUB>',"</SPAN>",$_); 14863 } else { join('',$Laname,$TeXname 14864 ,(($HTML_VERSION >= 3.0)? '2<SUB>e</SUB>':'2e'),$_); 14865 } 14866} 14867 14868sub do_cmd_latextohtml { 14869 local($_) = @_; 14870 if ($USING_STYLES) { 14871 $env_style{'LaTeX2HTML'} = ' ' unless ($env_style{'LaTeX2HTML'}); 14872 $env_style{'logo-LaTeX2HTML'} = ' ' unless ($env_style{'logo-LaTeX2HTML'}); 14873 join('',"<SPAN CLASS=\"logo,LaTeX2HTML\">" 14874 ,$Laname, $TeXname,"2<TT>HTML</TT>","</SPAN>",$_); 14875 } else { join('',$Laname,$TeXname,"2<TT>HTML</TT>",$_);} 14876} 14877 14878sub do_cmd_TeX { 14879 local($_) = @_; 14880 if ($USING_STYLES) { 14881 $env_style{'logo-TeX'} = ' ' unless ($env_style{'logo-TeX'}); 14882 join('',"<SPAN CLASS=\"logo-TeX\">",$TeXname,"</SPAN>",$_); 14883 } else { join('',$TeXname, $_);} 14884} 14885 14886sub do_cmd_MF { 14887 local($_) = @_; 14888 if ($USING_STYLES) { 14889 $env_style{'logo-Metafont'} = ' ' unless ($env_style{'logo-Metafont'}); 14890 join('',"<SPAN CLASS=\"logo-Metafont\">",$MFname,"</SPAN>",$_); 14891 } else { join('', $MFname, $_);} 14892} 14893 14894sub do_cmd_Xy { 14895 local($_) = @_; 14896 if ($USING_STYLES) { 14897 $env_style{'logo-Xy-pic'} = ' ' unless ($env_style{'logo-Xy-pic'}); 14898 join('',"<SPAN CLASS=\"logo-Xy-pic\">",$Xyname,"</SPAN>",$_); 14899 } else { join('',$Xyname, $_);} 14900} 14901 14902sub do_cmd_AmS { 14903 local($_) = @_; 14904 if ($USING_STYLES) { 14905 $env_style{'logo-AMS'} = ' ' unless ($env_style{'logo-AMS'}); 14906 join('',"<SPAN CLASS=\"logo-AMS\">",$AmSname,"</SPAN>",$_); 14907 } else { join('',$AmSname, $_);} 14908} 14909 14910sub do_cmd_AmSTeX { 14911 local($_) = @_; 14912 if ($USING_STYLES) { 14913 $env_style{'logo-AMS'} = ' ' unless ($env_style{'logo-AMS'}); 14914 join('',"<SPAN CLASS=\"logo-AMS\">",$AmSname,"-$TeXname","</SPAN>",$_); 14915 } else { join('',$AmSname, "-", $TeXname, $_);} 14916} 14917 14918sub do_cmd_char { 14919 local($_) = @_; 14920# some special characters are already turned into l2h internal 14921# representation. 14922# Get its represention from the table and use it like as regexp form. 14923 local($spmquot) = &escape_rx_chars($html_specials{'"'}); 14924# Get all internal special char representations as implied during 14925# preprocessing. 14926 local($spmrx) = join("\000",values %html_specials); 14927# escape regexp special chars (not really necessary yet, but why not) 14928 $spmrx = &escape_rx_chars($spmrx); #~ s:([\\(){}[\]\^\$*+?.|]):\\$1:g; 14929 $spmrx =~ s/\000/|/g; 14930 $spmrx = "(.)" unless $spmrx =~ s/(.+)/($1|.)/; 14931 14932 s/^[ \t]*(\d{1,3})[ \t]*/&#$1;/ && 14933 return($_); 14934 14935 s/^[ \t]*\'(\d{1,3})[ \t]*/"&#".oct($1).";"/e && 14936 return($_); 14937 14938 s/^[ \t]*$spmquot(\d{1,2})[ \t]*/"&#".hex($1).";"/e && 14939 return($_); 14940 14941# This is a kludge to work together with german.perl. Brrr. 14942 s/^[ \t]*\'\'(\d{1,2})[ \t]*/"&#".hex($1).";"/e && 14943 return($_); 14944# If l2h's special char marker represents more than one character, 14945# it's already in the &#xxx; form. Else convert the single character 14946# into &#xxx; with the ord() command. 14947 s/^[ \t]*\`\\?$spmrx[ \t]*/ 14948 (length($html_specials_inv{$1}) > 1 ? 14949 $html_specials_inv{$1} : "&#".ord($html_specials_inv{$1}||$1).";")/e && 14950 return($_); 14951 &write_warnings(join('', 14952 "Could not find character number in \\char", 14953 (/\n/ ? $` : $_), " etc.\n")); 14954 $_; 14955} 14956 14957 14958sub do_cmd_symbol { 14959 local($_) = @_; 14960 local($char); 14961 $char = &missing_braces 14962 unless ((s/$next_pair_pr_rx/$char = $2;''/eo) 14963 ||(s/$next_pair_rx/$char = $2;''/eo)); 14964 join('',&do_cmd_char($char),$_); 14965} 14966 14967################# Accent and Special Symbols ################################## 14968 14969# Generate code for the accents handling commands that are never 14970# applied to i or j. 14971# MEH: Now all accents are safe for dotless i or j 14972# MEH: Math accents supported as well 14973sub generate_accent_commands { 14974 local($accent,$accent_cmd); 14975 local(%accents) = ("c", "cedil", "pc", "cedil", "d", "bdot", "b", "b", 14976 "tilde", "tilde", "dot", "dot", "bar", "macr", 14977 "hat", "circ", "u", "breve", "v", "caron", 14978 "H", "dblac", "t", "t", "grave", "grave", 14979 "acute", "acute", "ddot", "uml", "check", "caron", 14980 "breve", "breve", "vec", "vec", 14981 "k", "ogon", "r", "ring"); 14982 foreach $accent (keys(%accents)) { 14983 $accent_cmd = "sub do_cmd_$accent {" . 'local($_) = @_;' . 14984 "&accent_safe_for_ij('$accents{$accent}','$accent');" . '$_}'; 14985 eval $accent_cmd; 14986 $accent_cmd = "do_cmd_$accent"; 14987 print STDERR "\n*** sub do_cmd_$accent failed:\nPERL: $@\n" if ($@); 14988 } 14989} 14990 14991# These handle accents, taking care of the dotless i's and j's that 14992# may follow (even though accented j's are not part of any alphabet 14993# that I know). 14994# 14995# Note that many forms of accents over dotless i's and j's are 14996# handled: 14997# "\^\i rest" 14998# "\^\i 14999# rest" 15000# "\^{\i}rest" 15001# "\^\i{}rest" 15002# They all produce "îrest". 15003# MEH: now also handles 15004# "\^{}rest" 15005# "\^,rest" 15006# and many more 15007 15008sub accent_safe_for_ij { 15009 local($type,$acc_cmd) = @_; 15010 local($arg, $first_char,$ij_cmd); 15011 #print STDOUT "\nACCENT: $type <$_>\n" ; 15012 s/^[ \t]*\n?[ \t]*(\S)/$1/; # Remove whitespace 15013 if (s/^\\([ij])([^a-zA-Z]|$)/$2/) { 15014 # Accent of this form: "\^\i rest" or "\^\i{}rest" 15015 ($arg) = $1; $ij_cmd = "\\$1"; 15016 s/^[ \t]+//o; # Get rid of whitespaces after \i 15017 if (substr($_, 0, 2) =~ /[\n\r][^\n\r]/) { 15018 $_ = substr($_, 1); # Get rid of 1 newline after \i 15019 } 15020 } else { 15021 # Accent of this form: "\^{\i}rest" or not an accent on i nor j 15022 ($arg) = &get_next_pair_or_char_pr; 15023 } 15024 $arg =~ s/([^\s\\<])/$first_char = $1; ''/eo; 15025# print STDOUT "\nACCENT1 type:$type arg:|${arg}| first_char: |$first_char| $ij_cmd 15026# , $ACCENT_IMAGES\n"; 15027 15028 local($aafter) = $_; 15029 local($iso) = &iso_map($first_char,$type); 15030 if ($iso) { $_ = join('', $iso, $arg, $aafter) } 15031 elsif ((!($ACCENT_IMAGES))&&(!($ij_cmd))) { 15032 local($err_string) = 15033 "\nNo available accent for $first_char$type , using just \"$first_char$arg\""; 15034 print $err_string if ($DEBUG||$VERBOSITY > 1); 15035 &write_warnings("\n ...set \$ACCENT_IMAGES to get an image "); 15036 $_ = join('', $first_char, $arg, $aafter) } 15037 else { 15038 print ", making image of accent: $first_char$type " if ($VERBOSITY > 1); 15039 $_ = join('', &mbox_accent($acc_cmd, $first_char, $ij_cmd) , $arg, $aafter) 15040 } 15041} 15042 15043sub mbox_accent { 15044 local($type, $char, $ij_cmd) = @_; 15045 if (length($type) > 1 ) { 15046 if ($text_accent{$type}) { 15047 $type = $text_accent{$type}; 15048 } elsif ($type =~ /^(math)?accent/) { 15049 } else { 15050 print "\n unrecognised accent $type for `$char' "; 15051 return $char; 15052 } 15053 } 15054 local(@styles); 15055 local($cmd,$style,$bstyle,$estyle) = ('','','',''); 15056 local(@styles) = split(',',$ACCENT_IMAGES); 15057 foreach $style (@styles) { 15058 $style =~ s/(^\s*\\|\s*)//g; 15059 $cmd = "do_cmd_$style"; 15060 if (defined &$cmd) { 15061 $bstyle .= "\\$style\{" ; 15062 $estyle .= "\}"; 15063 } else { 15064 &write_warnings("\nunrecognized style \\$style for accented characters"); 15065 } 15066 } 15067 if (!($bstyle)) { 15068 $bstyle = "\{"; 15069 $estyle = "\}"; 15070 } elsif ($bstyle =~ /textit|itshape/) { 15071 $bstyle = '\raise.5pt\hbox{' . $bstyle ; 15072 $estyle .= "\}"; 15073 } 15074 $char = $ij_cmd if ($ij_cmd); 15075 print STDOUT "\nACCENT: $type, $char" if ($VERBOSITY > 2); 15076 local($afterkern); # serifs extend too far on some letters... 15077 $afterkern = "\\kern.05em" if (($char =~ /m|n/)||($type=~/[Hv]/)); 15078 # ...or the accent is wider than the letter, so pad it out a bit 15079 $afterkern = "\\kern.15em" if ($char =~ /i|l/); #||($type=~/v/)); 15080 15081 &process_undefined_environment("tex2html_accent_inline" 15082 , ++$global{'max_id'}, "${bstyle}\\${type}\{$char\\/\}$estyle$afterkern"); 15083} 15084 15085# MEH: Actually tries to find a dotless i or j 15086sub do_cmd_i { join('',&iso_map('i', 'nodot') || 'i', $_[0]) } 15087sub do_cmd_j { join('',&iso_map('j', 'nodot') || 'j', $_[0]) } 15088 15089sub do_cmd_accent { 15090 local($_) = @_; 15091 local($number); 15092 if (s/\s*(\d+)\s*//o) {$number = $1} 15093 elsif (s/\s*&SMPquot;(\d)(\d)\s*//o) { $number = $1*16 + $2 } 15094 elsif (s/\s*\'(\d)(\d)(\d)\s*//o) { $number = $1*64 + $2*8 + $3 } 15095 else { s/\s*(\W\w+)([\s\W])/$2/o; $number = $1 } 15096 local($type) = $accent_type{uc($number)}; 15097 #print STDOUT "\ndo_cmd_accent: $number ($type) |$_|\n"; 15098 if (! $type) { 15099 &write_warnings("Accent number $number is unknown.\n"); 15100 return $_; 15101 } 15102 &accent_safe_for_ij($type , 'accent$number' ); 15103 $_; 15104} 15105 15106sub do_cmd_ae { join('', &iso_map("ae", "lig"), $_[0]);} 15107sub do_cmd_AE { join('', &iso_map("AE", "lig"), $_[0]);} 15108sub do_cmd_aa { join('', &iso_map("a", "ring"), $_[0]);} 15109sub do_cmd_AA { join('', &iso_map("A", "ring"), $_[0]);} 15110sub do_cmd_o { join('', &iso_map("o", "slash"), $_[0]);} 15111sub do_cmd_O { join('', &iso_map("O", "slash"), $_[0]);} 15112sub do_cmd_ss { join('', &iso_map("sz", "lig"), $_[0]);} 15113sub do_cmd_DH { join('', &iso_map("ETH", ""), $_[0]);} 15114sub do_cmd_dh { join('', &iso_map("eth", ""), $_[0]);} 15115sub do_cmd_TH { join('', &iso_map("THORN", ""), $_[0]);} 15116sub do_cmd_th { join('', &iso_map("thorn", ""), $_[0]);} 15117 15118sub do_cmd_pounds { join('', &iso_map("pounds", ""), $_[0]);} 15119sub do_cmd_S { join('', &iso_map("S", ""), $_[0]);} 15120sub do_cmd_copyright { join('', &iso_map("copyright", ""), $_[0]);} 15121sub do_cmd_P { join('', &iso_map("P", ""), $_[0]);} 15122 15123 15124sub brackets { ($OP, $CP);} 15125 15126sub get_date { 15127 local($format,$order) = @_; 15128 local(@lt) = localtime; 15129 local($d,$m,$y) = @lt[3,4,5]; 15130 if ($format =~ /ISO/) { 15131 sprintf("%4d-%02d-%02d", 1900+$y, $m+1, $d); 15132 } elsif ($format) { 15133 if ($order) { eval "sprintf(".$format.",".$order.")"; } 15134 else { sprintf($format, $d, $m+1, 1900+$y); } 15135 } else { sprintf("%d/%d/%d", $m+1, $d, 1900+$y); } 15136} 15137 15138sub address_data { 15139 local($user, $date, $_); 15140 local($format,$order) = @_; 15141 # Get author, (email address) and current date. 15142 ($user = L2hos->fullname()) =~ s/,.*//; 15143 ($user, &get_date($format,$order)); 15144} 15145 15146 15147#################################### LaTeX2e ################################## 15148 15149sub missing_braces { 15150# local($cmd) = @_; 15151 local($next, $revert, $thisline); 15152 local($this_cmd) = $cmd; 15153 $this_cmd =~ s/^\\// unless ($cmd eq "\\"); 15154 &write_warnings("\n? brace missing for \\$this_cmd"); 15155 if (/^[\s%]*([^\n]*)\n/ ) { 15156 $thisline = &revert_to_raw_tex($1) 15157 } else { 15158 $thisline = &revert_to_raw_tex($_); 15159 } 15160 print "\n\n*** no brace for \\$this_cmd , before:\n$thisline"; 15161 s/^\s*//; 15162 if ($_ =~ s/$next_token_rx//) { $next = $& }; 15163 $next =~ s/$comment_mark(\d+\n?)?//g; 15164# $next = &translate_commands($next) if ($next =~ /^\\/); 15165 if ($next =~ /^\\(\W|\d|[a-zA-z]*\b)/) { 15166 $revert = $next = "\\".$1; 15167 } elsif ($next =~ /\W/) { 15168 $revert = &revert_to_raw_tex($next); 15169 } else { $revert = $next }; 15170 print "\n*** using \"$revert\" as the argument instead; is this correct? ***\n\n"; 15171 $next; 15172} 15173 15174#RRM: 15175# &styled_text_chunk provides an interface for pieces of styled text, 15176# within a single paragraph. The visual markup can be obtained through either 15177# 1. link to a stylesheet (CSS) 15178# 2. direct markup placed into the output 15179# 3. calling another function to process the text 15180# 15181# parameters (in order): 15182# $def_tag : markup tag to be used, unless $USING_STYLES or no $property given, 15183# attributes can be included, only 1st word is used for closing-tag; 15184# $prefix : prefix for the Unique ID identifier, defaults to 'txt' 15185# OR contains CLASS= identifier when $property is empty(see below); 15186# $type : general type of the style-sheet information 15187# $class : specific type of the style-sheet information 15188# $property : value to be set, applicable to the $type & $class 15189# $alt_proc : name of procedure to use, if $USING_STYLES == 0, and no $def_tag 15190# $_ : current data-stream 15191# $open_tags_R : current open-tags (not used in this procedure) 15192 15193 sub styled_text_chunk { 15194 local($def_tag, $prefix, $type, $class, $property, $alt_proc, $_, 15195 $ot) = @_; 15196 local($open_tags_R) = defined $ot ? $ot : $open_tags_R; 15197 local($text, $env_id, $def_end); 15198 local($span_tag) = 'SPAN'; 15199 print "PCT: styled_text_chunk: def_tag: $def_tag - prefix: $prefix - type: $type - class: $class - property: $property - alt_proc: $alt_proc - content: $_ - ot: $ot\n" if ($VERBOSITY > 10) ; 15200 $text = &missing_braces 15201 unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo) 15202 || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo)); 15203 $text = &balance_inner_tags($text); 15204 print "PCT: styled_text_chunk: text: $text (balance inner tags)\n" if ($VERBOSITY > 10) ; 15205 #start from no open tags 15206 local(@save_open_tags) = (); 15207 local($open_tags_R) = []; 15208 local($result) ; 15209# local($decl); 15210# if ($prefix =~ /CLASS="(\w+)"/ ) { 15211# $decl=$1; 15212# push (@$open_tags_R, $decl); 15213# } 15214# push (@$open_tags_R, $color_env) if $color_env; 15215 if (!$inside_math) { 15216 $text = &translate_environments($text); 15217 $text = &translate_commands($text) if ($text =~ /\\/); 15218 $text .= &balance_tags; 15219 print "PCT: styled_text_chunk: text: $text (balance tags)\n" if ($VERBOSITY > 10) ; 15220 } 15221 15222 if (($USING_STYLES)&&($env_id =~ /^\d+$/)&&($property)) { 15223 $prefix = 'txt' unless ($prefix); 15224 $env_id = $prefix.$env_id; 15225 $styleID{$env_id} = join('',"$type", ($class ? "-$class" : '') 15226 ,": ", $property,"; "); 15227 $result = join('',"<$span_tag ID=\"$env_id\">",$text,"<\/$span_tag>", $_) ; 15228 print "PCT: styled_text_chunk: prefix: $prefix - env_id: $env_id - return: $result\n" if ($VERBOSITY > 10) ; 15229 return $result ; 15230 } 15231 15232 if (($USING_STYLES)&&($prefix =~ /($span_tag )?CLASS=\"(\w+)\"/o)) { 15233 local($span_class) = $2; 15234 $def_tag = (($1)? $1 : $span_tag." "); 15235 $txt_style{$span_class} = "$type: $class " 15236 unless ($txt_style{$span_class}); 15237 $result = join('',"<$def_tag CLASS=\"$span_class\">", $text,"<\/$span_tag>", $_); 15238 print "PCT: styled_text_chunk: def_tag: $def_tag - return: $result\n" if ($VERBOSITY > 10) ; 15239 return $result ; 15240 } 15241 15242 if (($def_tag) && (!$USING_STYLES)) { 15243 $def_tag =~ s/^($span_tag)?CLASS=\"(\w+)\"$// ; 15244 } 15245 15246 if ($def_tag =~ /^(\w+)/) { 15247 $def_end = $1; 15248 $result = join('',"<$def_tag>",$text,"<\/$def_end>", $_) ; 15249 print "PCT: styled_text_chunk: def_end: $def_end - return: $result\n" if ($VERBOSITY > 10) ; 15250 return $result ; 15251 } 15252 print "PCT: styled_text_chunk: $text\n" if ($VERBOSITY > 10) ; 15253 $result = join('', eval ("&$alt_proc(\$text)") , $_) ; 15254 return $result if (defined "&$alt_proc"); 15255 15256 &write_warnings( 15257 "\ncannot honour request for $type-$class:$property style at br$env_id"); 15258 $result = join('', $text, $_); 15259 print "PCT: styled_text_chunk: NOT HONORED - return: $result\n" if ($VERBOSITY > 10) ; 15260 return $result ; 15261} 15262 15263 sub multi_styled_text_chunk { 15264 local($def_tag, $prefix, $type, $class, $property, $_, $ot) = @_; 15265 local($open_tags_R) = defined $ot ? $ot : $open_tags_R; 15266 $prefix = 'txt' unless ($prefix); 15267 my(@def_tags) = split(',',$def_tag); 15268 my(@types) = split(',',$type); 15269 my(@classes) = split(',',$class); 15270 my(@properties) = split(',',$property); 15271 $text = &missing_braces 15272 unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo) 15273 || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo)); 15274 if (($USING_STYLES)&&($env_id =~ /^\d+$/)&&($property)) { 15275 # $1 contains the bracket-id 15276 $env_id = $prefix.$env_id; 15277 while (@properties) { 15278 $class = shift @classes; 15279 $property = shift @properties; 15280 $styleID{$env_id} .= join('' 15281 , shift @types, 15282 , ($class ? "-".$class : '') 15283 , ($property ? " : $property" : ''), " ; "); 15284 $styleID{$env_id} .= "\n\t\t " if (@properties); 15285 } 15286 } 15287 join('',"<SPAN ID=\"$env_id\">",$text,"<\/SPAN>", $_); 15288} 15289 15290#RRM: 15291# This one takes care of commands with argument that really should be 15292# environments; e.g. \centerline, \rightline, etc. 15293# Note that styles are inherited also from the existing @$open_tags_R. 15294# 15295 sub styled_text_block { 15296 local($def_tag, $attrib, $value, $class, $_, $ot) = @_; 15297 local($open_tags_R) = defined $ot ? $ot : $open_tags_R; 15298 local($text, $env_id, $attribs); 15299 if ($attribs =~ /,/ ) { 15300 local(@attribs) = split(',',$attrib); 15301 local(@values) = split(',',$value); 15302 while (@attribs) { 15303 $attribs .= join('', " " , shift @attribs 15304 ,"=\"" , shift @values, "\"") } 15305 } elsif($value) { 15306 $attribs = join(''," ",$attrib,"=\"",$value,"\"") 15307 } else { $attribs = " " . $attrib } 15308 15309 local(@save_open_tags) = @$open_tags_R; 15310 local($closures) = &close_all_tags(); 15311 local($reopens)=&balance_tags(); 15312 $text = &missing_braces 15313 unless ((s/$next_pair_pr_rx/$text = $2; $env_id = $1;''/eo) 15314 || (s/$next_pair_rx/$text = $2; $env_id = $1;''/eo)); 15315 if (($USING_STYLES)&&($env_id =~ /^\d+$/)) { 15316 $env_id = ++$global{'max_id'}; 15317 $env_id = "par".$env_id; 15318 $styleID{$env_id} = " "; 15319 $env_style{$class} = " " if (($class)&&!($env_style{$class})); 15320 $class = " CLASS=\"$class\"" if ($class); 15321 $env_id = " ID=\"$env_id\""; 15322 } else { $class = ''; $env_id = '' }; 15323 15324 $text = &translate_environments($text); 15325 $text = &translate_commands($text); 15326 15327 local($closuresA)=&close_all_tags(); 15328 local($reopensA) = &balance_tags(); 15329 $text =~ s/^\n?/\n/o; 15330 join('', $closures 15331 , "<$def_tag$class$env_id$attribs>" 15332 , $reopens, $text, $closuresA 15333 , "</$def_tag>\n", $reopensA, $_); 15334 } 15335# bold 15336sub do_cmd_textbf { &styled_text_chunk('','','','','','bbf', @_); } 15337# typewriter 15338sub do_cmd_texttt { 15339 print "PCT: do_cmd_texttt\n" if ($VERBOSITY > 10) ; 15340 &styled_text_chunk('','','','','','btt',@_); 15341} 15342# italic 15343sub do_cmd_textit { &styled_text_chunk('','','','','','bit',@_); } 15344# slanted 15345sub do_cmd_textsl { &styled_text_chunk('','','','','','bsl',@_); } 15346# slanted also ? 15347sub do_cmd_textsf { &styled_text_chunk('','','','','','bsf',@_); } 15348 15349sub lowercase_entity { 15350 local($char) = @_; 15351 local($exent); 15352 if ($exent = $low_entities{$char}) { "\&#$exent;" } 15353 elsif ($exent = $extra_small_caps{$char}) { $exent } 15354 else { "\&#$char;" } 15355} 15356 15357sub process_smallcaps { 15358 local($text) = @_; 15359 local($next, $scstr, $scbef, $special, $char); 15360 # is this enough for \sc and \scshape ? 15361 $text = &translate_environments($text); 15362 15363 # MRO: replaced $* with /m 15364 while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;|<[^>]+>)+/m ) { 15365 $scbef = $`; $special = $&; $text = $'; 15366 while ( $scbef =~ /(&#\d+;|[a-z$sclower])+[a-z\W\d$sclower]*/m) { 15367 $scstr .= $`; $scbef = $'; 15368 $next = $&; 15369 $next =~ s/&#(\d+);/&lowercase_entity($1)/egm; 15370 eval "\$next =~ $scextra" if ($scextra); 15371 eval "\$next =~ tr/a-z$sclower/A-Z$scupper/"; 15372 $scstr .= "<SMALL>" . $next ."<\/SMALL>"; 15373 } 15374 $scstr .= $scbef . $special; 15375 } 15376 if ($text) { 15377 while ( $text =~ /(&#\d+;|[a-z$sclower])+[a-z\W\d$sclower]*/m) { 15378 $scstr .= $`; $text = $'; 15379 $next = $&; 15380 $next =~ s/&#(\d+);/&lowercase_entity($1)/egm; 15381 eval "\$next =~ $scextra" if ($scextra); 15382 eval "\$next =~ tr/a-z$sclower/A-Z$scupper/"; 15383 $scstr .= "<SMALL>" . $next ."<\/SMALL>"; 15384 } 15385 $scstr .= $text; 15386 } 15387 $scstr; 15388} 15389 15390# this gives a separate ID for each instance 15391#sub do_cmd_textsc { &styled_text_chunk('','','font','variant' 15392# ,'small-caps', 'process_smallcaps', @_); } 15393# 15394# this uses a single CLASS for all instances 15395#sub do_cmd_textsc { &styled_text_chunk('', 'CLASS="textsc"' 15396# ,'font-variant','small-caps','', 'process_smallcaps', @_); } 15397# 15398# ...but NS 4.03 doesn't implement small-caps !!! 15399sub do_cmd_textsc { &styled_text_chunk('','' 15400 ,'font-variant','small-caps','', 'process_smallcaps', @_); } 15401 15402 15403#sub do_cmd_emph { &styled_text_chunk('EM','em','font','variant','','', @_); } 15404 15405 15406# this gives a separate ID for each instance 15407#sub do_cmd_underline { &styled_text_chunk('U','','text','decoration','underline','', @_); } 15408 15409# this uses a single CLASS for all instances 15410sub do_cmd_underline { &styled_text_chunk('U','CLASS="underline"' 15411 ,'text-decoration','underline','','', @_); } 15412sub do_cmd_underbar { &do_cmd_underline(@_) } 15413 15414 15415# this gives a separate ID for each instance 15416#sub do_cmd_strikeout { &styled_text_chunk('STRIKE','' 15417# ,'text','decoration','line-through','', @_); } 15418 15419# this uses a single CLASS for all instances 15420sub do_cmd_strikeout { &styled_text_chunk('STRIKE','CLASS="strikeout"', 15421 'text-decoration','line-through','','', @_); } 15422 15423 15424sub do_cmd_uppercase { 15425 local($_) = @_; 15426 local($text,$next,$done,$special,$after); 15427 $text = &missing_braces unless ( 15428 (s/$next_pair_pr_rx/$text = $2;''/eo) 15429 ||(s/$next_pair_rx/$text = $2;''/eo)); 15430 $after = $_; 15431 while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;)/ ) { 15432 $next = $`; 15433 $special = $&; 15434 $text = $'; 15435 $next =~ tr /a-z/A-Z/ if ($next); 15436 $done .= $next . $special; 15437 } 15438 $text =~ tr /a-z/A-Z/ if ($text); 15439 $done .= $text; 15440 $done = &convert_iso_latin_chars($done) if ($done); 15441 join('',$done,$after); 15442} 15443 15444sub do_cmd_lowercase { 15445 local($_) = @_; 15446 local($text,$next,$done,$special,$after); 15447 $text = &missing_braces 15448 unless ((s/$next_pair_pr_rx/$text = $2;''/seo) 15449 || (s/$next_pair_rx/$text = $2;''/seo)); 15450 $after = $_; 15451 while ($text =~ /(\\[a-zA-Z]+|[&;]SPM\w+;)/ ) { 15452 $next = $`; 15453 $special = $&; 15454 $text = $'; 15455 $next =~ tr /A-Z/a-z/ if ($next); 15456 $done .= $next . $special; 15457 } 15458 $text =~ tr /A-Z/a-z/ if ($text); 15459 $done .= $text; 15460 $done = &convert_iso_latin_chars($done) if ($done); 15461 join('',$done,$after); 15462} 15463 15464sub do_cmd_MakeUppercase { &do_cmd_uppercase(@_) } 15465sub do_cmd_MakeLowercase { &do_cmd_lowercase(@_) } 15466 15467 15468 15469sub do_cmd_ensuremath { 15470 local($_) = @_; 15471 local ($id, $value); 15472 $value = &missing_braces unless ( 15473 (s/$next_pair_pr_rx/$value=$2;''/eo) 15474 ||(s/$next_pair_rx/$value=$2;''/eo)); 15475 join('', &simple_math_env($value), $'); 15476} 15477 15478# 15479# This is mainly for \special{header=PostScript_Prologue}, 15480# and \graphicspath{path} which occur OUTSIDE of an environment 15481# passed to TeX. \special's INSIDE such environments are, of 15482# course, left alone. 15483 15484sub do_cmd_special { 15485 local($_) = @_; 15486 local ($id, $value); 15487 $value = &missing_braces unless ( 15488 (s/$next_pair_pr_rx/$value=$2;''/eo) 15489 ||(s/$next_pair_rx/$value=$2;''/eo)); 15490 local($special_cmd) = &revert_to_raw_tex($value); 15491 &add_to_preamble($cmd,"\\$cmd\{$special_cmd\}"); 15492 $_; 15493} 15494 15495 15496########################## Input and Include commands ######################### 15497 15498sub do_cmd_input { 15499 local($_) = @_; 15500 local($file,$output); 15501 (s/\s*(.*)\s*\n/$file =$1;''/s) unless ( 15502 (s/$next_pair_pr_rx/$file=$2;''/eo) 15503 ||(s/$next_pair_rx/$file=$2;''/eo)); 15504 local($after) = $_; 15505 $file = &revert_to_raw_tex("\\input{$file}\n") if $file; 15506 if ($PREAMBLE) { &add_to_preamble('include',$file)} 15507 elsif (!($file=~/^\s*$/)) { 15508 $output = &process_undefined_environment('center' 15509 , ++$global{'max_id'},"\\vbox{$file}"); 15510 } 15511 $output.$after; 15512} 15513 15514sub do_cmd_include { 15515 local($_) = @_; 15516 local($file,$output); 15517 $file = &missing_braces unless ( 15518 (s/$next_pair_pr_rx/$file=$2;''/eo) 15519 ||(s/$next_pair_rx/$file=$2;''/eo)); 15520 local($after) = $_; 15521 $file = &revert_to_raw_tex("\\include{$file}\n") if $file; 15522 if ($PREAMBLE) { &add_to_preamble('include',$file)} 15523 else { 15524 $output = &process_undefined_environment('figure' 15525 , ++$global{'max_id'},"\\vbox{$file}"); 15526 } 15527 $output.$after; 15528} 15529 15530########################## Messages ######################### 15531 15532sub do_cmd_message { 15533 local($_) = @_; 15534 local($message); 15535 $message = &missing_braces unless ( 15536 (s/$next_pair_pr_rx/$message=$2;''/eo) 15537 ||(s/$next_pair_rx/$message=$2;''/eo)); 15538 local($after) = $_; 15539 $message = &translate_commands($message); 15540 $message =~ s/$comment_mark(\d+)//og; 15541 print STDOUT "\n*** $message ***\n"; 15542 $after; 15543} 15544 15545sub do_cmd_typeout { 15546 print STDOUT "\n"; 15547 local($_) = &do_cmd_message(@_); 15548 print STDOUT "\n"; 15549 $_; 15550} 15551 15552sub do_cmd_expandafter { 15553 local($_) = @_; 15554 print "\nEXPANDAFTER: " if ($VERBOSITY >3); 15555 return($_) unless (s/^\s*(\\\w+)\s*\\//o); 15556 print " delaying $1 " if ($VERBOSITY >3); 15557 local($delay,$cmd) = ($1,''); 15558 s/^(\w+|\W)/$cmd=$1;''/eo; 15559 local($nextcmd) = "do_cmd_$cmd"; 15560 if (defined &$nextcmd) { $_ = &$nextcmd($_) } 15561 elsif ($new_command{$cmd}) { 15562 local($argn, $body, $opt) = split(/:!:/, $new_command{$cmd}); 15563 do { ### local($_) = $body; 15564 &make_unique($body); 15565 } if ($body =~ /$O/); 15566 if ($argn) { 15567 do { 15568 local($before) = ''; 15569 local($after) = "\\$cmd ".$_; 15570 $after = &substitute_newcmd; # may change $after 15571 $after =~ s/\\\@#\@\@/\\/o unless ($after); 15572 }; 15573 } else { $_ = $body . $_; } 15574 } else { print "\nUNKNOWN COMMAND: $cmd "; } 15575 15576 # now put the delayed function back for processing 15577 join('',$delay, " ", $_); 15578} 15579 15580sub do_cmd_tracingall { 15581 print "\nTRACING:\n$ref_contents\n$after\n"; 15582 $VERBOSITY = 8; ""; } 15583 15584sub do_cmd_htmltracenv { &do_cmd_htmltracing } 15585 15586sub do_cmd_htmltracing { 15587 local($_) = @_; 15588 local($value); 15589 $value = &missing_braces 15590 unless ((s/$next_pair_rx/$value = $2;''/eo) 15591 ||(s/$next_pair_pr_rx/$value = $2;''/eo)); 15592 if ($value =~ /^\s*(\d+)\s*$/) { 15593 $VERBOSITY = $1; 15594 if ($VERBOSITY) { 15595 print "\n\n *** setting trace-level to $VERBOSITY ***\n"; 15596 } else { 15597 print "\n\n *** cancelling all tracing ***\n\n"; 15598 } 15599 } else { 15600 &write_warnings("argument to \\htmltracing must be a number"); 15601 } 15602 $_ ; 15603} 15604 15605 15606############################ Initialization #################################### 15607 15608sub initialise { 15609 ############################ Global variables ############################### 15610 $PREAMBLE = 2; # 1 while translating preamble, 0 while translating body 15611 $NESTING_LEVEL = undef; #counter for TeX group nesting level 15612 $OUT_NODE = 0; # Used in making filenames of HTML nodes unique 15613 $eqno_prefix = ''; # default prefix on equation numbers 15614 ($O , $C, $OP, $CP) = ('<<' , '>>', '<#', '#>'); # Open/Close Markers 15615 $href_name = 0; # Used in the HREF NAME= field 15616 $wrap_toggle = 'end'; 15617 $delim = '%:%'; # Delimits items of sectioning information 15618 # stored in a string 15619 15620 $LATEX2HTML_META = '<META NAME="Generator" CONTENT="LaTeX2HTML v'.$TEX2HTMLV_SHORT.'">' 15621 . "\n<META HTTP-EQUIV=\"Content-Style-Type\" CONTENT=\"text/css\">" 15622 unless ($LATEX2HTML_META); 15623 15624 $TeXname = (($HTML_VERSION ge "3.0")? "T<SMALL>E</SMALL>X" : "TeX"); 15625 $Laname = (($HTML_VERSION ge "3.0")? "L<SUP><SMALL>A</SMALL></SUP>" : "La"); 15626 $MFname = (($HTML_VERSION ge "3.0")? "M<SMALL>ETAFONT</SMALL>" : "Metafont"); 15627 $Xyname = (($HTML_VERSION ge "3.0")? "X<SUB><BIG>Y</BIG></SUB>" : "Xy"); 15628 $AmSname = (($HTML_VERSION ge "3.0")? "A<SUB><BIG>M</BIG></SUB>S" : "AmS"); 15629 15630 $EQN_TAGS = "R" unless ($EQN_TAGS); 15631 $EQNO_START = "("; 15632 $EQNO_END = ")"; 15633 15634 $AtBeginDocument_hook = "\$AtBeginDocument_hook\=\'\'; " 15635 unless $AtBeginDocument_hook; 15636 $cross_ref_mark = '<tex2html_cr_mark>'; 15637 $external_ref_mark = '<tex2html_ext_cr_mark>'; 15638 $cite_mark = '<tex2html_cite_mark>'; 15639 $hash_mark = '<tex2html_hash_mark>'; 15640 $protected_hash = '<tex2html_protected_hash>'; 15641 $param_mark = '<tex2html_param_mark>'; 15642 $bbl_mark = '<tex2html_bbl_mark>'; 15643 $toc_mark = '<tex2html_toc_mark>'; 15644 $lof_mark = '<tex2html_lof_mark>'; 15645 $lot_mark = '<tex2html_lot_mark>'; 15646 $info_page_mark = '<tex2html_info_page_mark>'; 15647 $info_title_mark = '<tex2html_info_title_mark>'; 15648 $init_file_mark = '<tex2html_init_file_mark>'; 15649 $childlinks_on_mark = '<tex2html_childlinks_mark>'; 15650 $childlinks_null_mark = '<tex2html_childlinks_null_mark>'; 15651 $childlinks_mark = $childlinks_on_mark; 15652 $more_links_mark = '<tex2html_morelinks_mark>'; 15653 $idx_mark = '<tex2html_idx_mark>'; 15654 $verbatim_mark = '<tex2html_verbatim_mark>'; 15655 $unfinished_mark = '<tex2html_unfinished_mark>'; 15656 $verb_mark = '<tex2html_verb_mark>'; 15657 $verbstar_mark = '<tex2html_verbstar_mark>'; 15658 $image_mark = '<tex2html_image_mark>'; 15659 $mydb_mark = '<tex2html_mydb_mark>'; 15660 $percent_mark = '<tex2html_percent_mark>'; 15661 $ampersand_mark = '<tex2html_ampersand_mark>'; 15662 $dol_mark = '<tex2html_lone_dollar>'; 15663 $comment_mark = '<tex2html_comment_mark>'; 15664 $caption_mark = '<tex2html_caption_mark>'; 15665 $array_col_mark = '<tex2html_col_mark>'; 15666 $array_row_mark = '<tex2html_row_mark>'; 15667 $array_text_mark = '<tex2html_text_mark>'; 15668 $array_mbox_mark = '<tex2html_mbox_mark>'; 15669 15670 $bibitem_counter = 0; 15671 $undef_mark = '<tex2html_undef_mark>'; 15672 $file_mark = '<tex2html_file>'; 15673 $endfile_mark = '<tex2html_endfile>'; 15674 15675 # This defines textual markers for all the icons 15676 # e.g. $up_visible_mark = '<tex2html_up_visible_mark>'; 15677 # They will be replaced with the real icons at the very end. 15678 foreach $icon (keys %icons) {eval "\$$icon = '<tex2html_$icon>'"}; 15679 15680 # Make sure $HTML_VERSION is in the right range and in the right format. 15681# $HTML_VERSION =~ /[\d.]*/; 15682# $HTML_VERSION = 0.0 + $&; 15683# $HTML_VERSION = 2 if ( $HTML_VERSION < 2 ); 15684# $HTML_VERSION = 9 if ( $HTML_VERSION > 9 ); 15685# $HTML_VERSION = sprintf("%3.1f",$HTML_VERSION); 15686 15687 &banner(); 15688 print "Revised and extended by:" 15689 . "\n Marcus Hennecke, Ross Moore, Herb Swan and others\n"; 15690 15691 # Collect HTML options and figure out HTML version 15692 $HTML_OPTIONS = '' unless ($HTML_OPTIONS); 15693 $HTML_VERSION =~ s/^html|\s+//g; 15694 local(@HTML_VERSION) = split(/,/, $HTML_VERSION); 15695 foreach ( @HTML_VERSION ) { 15696 if (/^[\d\.]+$/) { 15697 # Make sure $HTML_VERSION is in the right range and in the right format. 15698 $HTML_VERSION = 0.0 + $_; 15699 $HTML_VERSION = 2 if ( $HTML_VERSION < 2 ); 15700 $HTML_VERSION = 9 if ( $HTML_VERSION > 9 ); 15701 $HTML_VERSION = sprintf("%3.1f",$HTML_VERSION); 15702 } else { 15703 $HTML_OPTIONS .= "$_,"; 15704 } 15705 } 15706 $HTML_OPTIONS =~ s/\W$//; # remove any trailing punctuation 15707 15708 print "...producing markup for HTML version $HTML_VERSION "; 15709 print ($HTML_OPTIONS ? "with $HTML_OPTIONS extensions\n\n\n" : "\n\n\n"); 15710 15711 # load the character defs for latin-1, but don't set the charset yet 15712 &do_require_extension('latin1'); 15713 $charset = $CHARSET = $PREV_CHARSET = ''; 15714 15715 if ($HTML_VERSION =~ /(2.0|3.0|3.2|4.0|4.1)/) { 15716 # Require the version specific file 15717 do { $_ = "$LATEX2HTMLVERSIONS${dd}html$1.pl"; 15718 if (!(-f $_)) { s/(\d).(\d.pl)$/$1_$2/ }; 15719 if (!(-f $_)) { s/(\d)_(\d.pl)$/$1-$2/ }; 15720 require $_ || die "\n*** Could not load $_ ***\n"; 15721 print "\nHTML version: loading $_\n"; 15722 } unless ($HTML_VERSION =~ /2.0/); 15723 $DOCTYPE = "-//".(($HTML_VERSION eq "2.0")? "IETF" : "W3C") 15724 . "//DTD HTML $HTML_VERSION" 15725 .(($HTML_VERSION eq "3.2")? " Final" : "") 15726 .(($HTML_VERSION eq "4.0")? " Transitional" : ""); 15727 15728 if ($HTML_OPTIONS) { 15729 local($ext); 15730 local($loading_extensions) = 1; 15731 # Require the option specific files 15732 @HTML_VERSION = split(/,/, $HTML_OPTIONS); 15733 foreach $ext ( @HTML_VERSION ) { 15734 &do_require_extension($ext); 15735# do { 15736# print "\nLoading $LATEX2HTMLVERSIONS$dd$ext.pl"; 15737# require "$LATEX2HTMLVERSIONS$dd$ext.pl"; 15738# } if (-f "$LATEX2HTMLVERSIONS$dd$ext.pl"); 15739 } 15740 undef $loading_extensions; 15741 } 15742 } else { 15743 print "\n You specified an invalid version: $HTML_VERSION\n" 15744 . "In future please request extensions by name:\n" 15745 . " i18n table math frame latin1 unicode etc.\n"; 15746 15747 # Require all necessary version specific files 15748 foreach ( sort <$LATEX2HTMLVERSIONS${dd}html[1-9].[0-9].pl> ) { 15749 last if ( $_ gt "$LATEX2HTMLVERSIONS${dd}html$HTML_VERSION.pl" ); 15750 do { print "\nloading $_" if ($DEBUG); 15751 require $_; } unless ( 15752 ($NO_SIMPLE_MATH)&&($_ eq "$LATEX2HTMLVERSIONS${dd}html3.1.pl")); 15753 }; 15754 $STRICT_HTML = 0; 15755 } 15756 15757 # packages automatically implemented, or clearly irrelevant 15758 %styles_loaded = 15759 ( 'theorem' , 1 , 'enumerate', 1 , 'a4paper' , 1 , 'b5paper' , 1 15760 , '10pt' , 1 , '11pt' , 1 , '12pt' , 1 15761 , %styles_loaded ); 15762 15763 15764 %declarations = 15765 ('em' , '<EM></EM>', 15766 'it' , '<I></I>', 15767 'bf' , '<SPAN class="bbf"></SPAN>', 15768 'tt' , '<SPAN class="btt"></SPAN>', 15769 'sl' , '<I></I>', # Oops! 15770 'sf' , '<I></I>', # Oops! 15771 'rm' , '<></>', 15772 'rmfamily' ,'<></>', # see $fontchange_rx 15773 'normalfont' ,'<></>', # see $fontweight_rx and $fontchange_rx 15774 'mdseries' ,'<></>', # see $fontweight_rx 15775 'upshape' ,'<></>', # see $fontchange_rx 15776 'itshape' , '<I></I>', 15777 'bfseries' , '<B></B>', 15778 'ttfamily' , '<TT></TT>', 15779 'slshape' , '<I></I>', # Oops! 15780 'sffamily' , '<I></I>', # Oops! 15781## 'scshape' , '<I></I>', # Oops! 15782# 'boldmath' , '<B></B>', 15783# 'quote', '<BLOCKQUOTE></BLOCKQUOTE>', 15784# 'quotation', '<BLOCKQUOTE></BLOCKQUOTE>', 15785 %declarations # Just in case someone extends it in the init file 15786 ); 15787 15788 15789%declarations = ( 15790 'tiny', '<FONT SIZE="-2"></FONT>', 15791 'Tiny', '<FONT SIZE="-2"></FONT>', 15792 'scriptsize', '<FONT SIZE="-2"></FONT>', 15793 'small', '<FONT SIZE="-1"></FONT>', 15794 'Small', '<FONT SIZE="-1"></FONT>', 15795 'SMALL', '<FONT SIZE="-1"></FONT>', 15796 'smaller', '<SMALL></SMALL>', 15797 'footnotesize', '<FONT SIZE="-1"></FONT>', 15798 'larger', '<BIG></BIG>', 15799 'large', '<FONT SIZE="+1"></FONT>', 15800 'Large', '<FONT SIZE="+2"></FONT>', 15801 'LARGE', '<FONT SIZE="+2"></FONT>', 15802 'huge', '<FONT SIZE="+3"></FONT>', 15803 'Huge', '<FONT SIZE="+4"></FONT>', 15804# 'centering', '<DIV ALIGN="CENTER"></DIV>', 15805# 'center', '<DIV ALIGN="CENTER"></DIV>', 15806# 'flushleft', '<DIV ALIGN="LEFT"></DIV>', 15807# 'raggedright', '<DIV ALIGN="LEFT"></DIV>', 15808# 'flushright', '<DIV ALIGN="RIGHT"></DIV>', 15809# 'raggedleft', '<DIV ALIGN="RIGHT"></DIV>', 15810 %declarations 15811 ) if ($HTML_VERSION > 2.0 ); 15812 15813# no alignment in HTML 2.0 15814#%declarations = ( 15815# 'centering', '<P ALIGN="CENTER"></P>', 15816# 'center', '<P ALIGN="CENTER"></P>', 15817# 'flushleft', '<P ALIGN="LEFT"></P>', 15818# 'raggedright', '<P ALIGN="LEFT"></P>', 15819# 'flushright', '<P ALIGN="RIGHT"></P>', 15820# 'raggedleft', '<P ALIGN="RIGHT"></P>', 15821 15822%declarations = ( 15823# 'centering', '<P></P>', 15824 'center', '<P></P>', 15825 'flushleft', '<P></P>', 15826 'raggedright', '<P></P>', 15827 'flushright', '<P></P>', 15828 'raggedleft', '<P></P>', 15829 'quote', '<BLOCKQUOTE></BLOCKQUOTE>', 15830 'quotation', '<BLOCKQUOTE></BLOCKQUOTE>', 15831 'verse', '<BLOCKQUOTE></BLOCKQUOTE>', 15832 'preform', '<PRE></PRE>', 15833 'unord', '<UL></UL>', 15834 'ord', '<OL></OL>', 15835 'desc', '<DL></DL>', 15836 'list', '', 15837 'par', '<P></P>' 15838 ) if ($HTML_VERSION == 2.0 ); 15839 15840 &generate_declaration_subs; # Generate code to handle declarations 15841 15842 # ...but these block-level divisions must be handled differently... 15843%declarations = ( 15844 'quote', '<BLOCKQUOTE></BLOCKQUOTE>', 15845 'quotation', '<BLOCKQUOTE></BLOCKQUOTE>', 15846 'verse', '<BLOCKQUOTE></BLOCKQUOTE>', 15847 'preform', '<PRE></PRE>', 15848 'unord', '<UL></UL>', 15849 'ord', '<OL></OL>', 15850 'desc', '<DL></DL>', 15851# 'list', '<DIV></DIV>', 15852 'par', '<P></P>', 15853 'samepage', '', 15854# 'centering', '<DIV ALIGN="CENTER"></DIV>', 15855 'center', '<DIV ALIGN="CENTER"></DIV>', 15856 'flushleft', '<DIV ALIGN="LEFT"></DIV>', 15857 'raggedright', '<DIV ALIGN="LEFT"></DIV>', 15858 'flushright', '<DIV ALIGN="RIGHT"></DIV>', 15859 'raggedleft', '<DIV ALIGN="RIGHT"></DIV>', 15860 %declarations 15861 ) if ($HTML_VERSION > 2.0 ); 15862 15863 15864 %section_commands = 15865 ('partstar' , '1' , 'chapterstar', '2', 'sectionstar', '3' 15866 , 'subsectionstar', '4', 'subsubsectionstar', '5', 'paragraphstar' 15867 , '6', 'subparagraphstar', '7' 15868 , 'part' , '1' , 'chapter', '2', 'section', '3','subsection', '4' 15869 , 'subsubsection', '5', 'paragraph', '6', 'subparagraph', '7' 15870 , 'slidehead', '3', %section_commands); 15871 # The tableofcontents, listoffigures, listoftables, bibliography and 15872 # textohtmlindex are set after determining what is the outermost level 15873 # in sub set_depth_levels. Appendix is implemented as a command. 15874 15875 %standard_section_headings = 15876 ('part' , 'H1' , 'chapter' , 'H1', 'section', 'H2', 'subsection', 'H3' 15877 , 'subsubsection', 'H4', 'paragraph', 'H5', 'subparagraph', 'H6' 15878 , %standard_section_headings ); 15879 15880 # Generates code to handle sectioning commands 15881 # for those sections which take an argument. 15882 &generate_sectioning_subs; 15883 15884 %section_headings = 15885 ('partstar' , 'H1' , 'chapterstar' , 'H1', 'sectionstar', 'H2' 15886 , 'subsectionstar', 'H3', 'subsubsectionstar', 'H4', 'paragraphstar' 15887 , 'H5', 'subparagraphstar', 'H6', %section_headings); 15888 15889 # These need their own custom code but are treated as sectioning commands 15890 %section_headings = 15891 ('tableofcontents', 'H2', 'listoffigures', 'H2', 'listoftables', 'H2' 15892 , 'bibliography', 'H2', 'textohtmlindex', 'H2' 15893 , %standard_section_headings 15894 , %section_headings); 15895 15896 &generate_accent_commands; # Code to handle accent commands 15897 15898 # These are replaced as soon as the text is read in. 15899 %html_specials = ( '<', ';SPMlt;' 15900 , '>', ';SPMgt;' 15901 , '&', ';SPMamp;' 15902# , '``', '\lq\lq ' # probably not a good idea 15903# , "''", '\rq\rq ', # probably not a good idea 15904 , '"', ';SPMquot;' 15905 ); 15906 15907 %html_specials = ( %html_specials 15908 , '``', ';SPMldquo;', "''", ';SPMrdquo;' 15909 ) if ($HTML_VERSION >= 5 ); 15910 15911 # This mapping is needed in sub revert_to_raw_tex 15912 # before passing stuff to latex for processing. 15913 %html_specials_inv = ( 15914 ';SPMlt;' ,'<' 15915 , ';SPMgt;','>' 15916 , ';SPMamp;','&' 15917 , ';SPMquot;','"' 15918 , ';SPMldquo;','``' 15919 , ';SPMrdquo;',"''" 15920 , ';SPMdollar;', '$' # for alltt 15921 , ';SPMpct;', '%' 15922 , ';SPMtilde;', '~' 15923 ); 15924 15925 # normalsize vertical dimension factors for 12pt (1.0 <=> <BR>) 15926 %vspace_12pt = ('ex', 1.0, 'em', 1.0, 'pt', 0.1, 'pc', 1.0, 15927 'in', 6.0, 'bp', 0.1, 'cm', 2.3, 'mm', 0.2, 'dd', 0.1, 15928 'cc', 1.0, 'sp', 0.0); 15929 15930 # For some commands such as \\, \, etc it is not possible to define 15931 # perl subroutines because perl does not allow some non-ascii characters 15932 # in subroutine names. So we define a table and a subroutine to relate 15933 # such commands to ascii names. 15934 %normalize = ('\\', 'd_backslash' 15935 , '/', 'esc_slash', "`", 'grave' 15936 , "'", 'acute', "^", 'hat', '"', 'ddot' 15937 , '~', 'tilde', '.', 'dot', '=', 'bar' 15938 , '{', 'lbrace' , '}', 'rbrace', '|', 'Vert' 15939 , '#', 'esc_hash', '$', 'esc_dollar' 15940 ); 15941 15942 %text_accent = ( 'cedil','c', 'bdot','d', 'b','b' , 'tilde','~' 15943 , 'circ' ,'^', 'hat','^', 'check','v' , 'caron','v' 15944 , 'acute','\'' , 'grave','`' , 'dot','.' , 'breve','u' 15945 , 'ddot','"' , 'uml','"' , 'bar','=','macr','=' 15946 , 'dblacc','H' , 't','t' , 'ogon','k' , 'ring','r' 15947 ); 15948 15949 # %languages_translations holds for each known language the 15950 # appropriate translation function. The function is called in 15951 # slurp_input. 15952 # The translation functions subtitute LaTeX macros 15953 # with ISO-LATIN-1 character references 15954 %language_translations = ( 15955 'english', 'english_translation' 15956 , 'USenglish', 'english_translation' 15957 , 'original', 'english_translation' 15958 , 'german', 'german_translation' 15959 , 'austrian', 'german_translation' 15960 , 'finnish', 'finnish_translation' 15961 , 'french', 'french_translation' 15962 , 'spanish', 'spanish_translation' 15963 , 'swedish', 'swedish_translation' 15964 , 'turkish', 'turkish_translation' 15965 ); 15966 15967# Reiner: 15968# $standard_label_rx = 15969# "\\s*[[]\\s*(((\$any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]"; 15970# $enum_label_rx = "^((({[^{}]*})|([^{}]))*)([aAiI1])(.*)"; 15971# $enum_level = 0; # level for enumerate (1-4, i-iv) 15972 %enum = ( 15973 'enumi', 0, # counter for level 1 15974 'enumii', 0, # counter for level 2 15975 'enumiii', 0, 15976 'enumiv', 0, 15977 'theenumi', "&arabic('enumi')", # eval($enum{"theenumi"}) 15978 'theenumii', "&alph('enumii')", 15979 'theenumiii', "&roman('enumiii')", 15980 'theenumiv', "&Alph('enumiv')", 15981 # e.g. eval("$enum{'labelenumi'}") 15982 'labelenumi', 'eval($enum{"theenumi"}) . "."', 15983 'labelenumii', '"(" . eval($enum{"theenumii"}) . ")"', 15984 'labelenumiii', 'eval($enum{"theenumiii"}) . "."', 15985 'labelenumiv', 'eval($enum{"theenumiv"}) . "."' 15986 ); 15987 15988 %RomanI = ( '1',"I",'2',"II",'3',"III",'4',"IV" 15989 ,'5',"V",'6',"VI",'7',"VII", '8',"VIII",'9',"IX"); 15990 %RomanX = ( '1',"X",'2',"XX",'3',"XXX",'4',"XL" 15991 ,'5',"L",'6',"LX",'7',"LXX", '8',"LXXX",'9',"XC"); 15992 %RomanC = ( '1',"C",'2',"CC",'3',"CCC",'4',"CD" 15993 ,'5',"D",'6',"DC",'7',"DCC", '8',"DCCC",'9',"CM"); 15994 %RomanM = ( '1',"M",'2',"MM",'3',"MMM",'4',"MH" 15995 ,'5',"H",'6',"HM",'7',"HMM",'8',"HMMM"); 15996 15997 %enum_label_funcs = ( 15998 "a", "alph", "A", "Alph", "i", "roman", "I", "Roman", "1", "arabic" ); 15999 16000sub farabic{ 16001 local($_)=@_; 16002 $_; 16003} 16004sub arabic{ 16005 local($_)=@_; 16006 eval($enum{$_}); 16007} 16008 16009sub falph{ 16010 local($num)=@_; 16011# chr($num+64); 16012 substr(" abcdefghijklmnopqrstuvwxyz",$num,1) 16013} 16014sub alph{ 16015 local($num)=@_; 16016 &falph(eval($enum{$num})); 16017} 16018sub fAlph{ 16019 local($num)=@_; 16020# chr($num+32); 16021 substr(" ABCDEFGHIJKLMNOPQRSTUVWXYZ",$num,1) 16022} 16023sub Alph{ 16024 local($num)=@_; 16025 &falph(eval($enum{$num})); 16026} 16027 16028sub Roman{ 16029 local($num)=@_; 16030 &fRoman(eval($enum{$num})); 16031} 16032sub fRoman{ 16033 local($num)=@_; 16034 local($RmI)= $num%10; ($RmI) = (($RmI) ? $RomanI{"$RmI"} : '' ); 16035 $num = $num/10; local($RmX)= $num%10; ($RmX) = (($RmX) ? $RomanX{"$RmX"} : '' ); 16036 $num = $num/10; local($RmC)= $num%10; ($RmC) = (($RmC) ? $RomanC{"$RmC"} : '' ); 16037 $num = $num/10; local($RmM)= $num%10; ($RmM) = (($RmM) ? $RomanM{"$RmM"} : '' ); 16038 "$RmM" . "$RmC" . "$RmX" . "$RmI"; 16039} 16040sub froman{ 16041 local($_)=@_; 16042 $_ = &fRoman($_); 16043 $_ =~ tr/A-Z/a-z/; 16044 $_; 16045} 16046sub roman{ 16047 local($num)=@_; 16048 &froman(eval($enum{$num})); 16049} 16050 16051 16052 %unitscale = ("in",72,"pt",72.27/72,"pc",12,"mm",72/25.4,"cm",72/2.54 16053 ,"\\hsize",100,"\\vsize",100 16054 ,"\\textwidth",100,"\\textheight",100 16055 ,"\\pagewidth",100,"\\linewidth",100 16056 ); 16057 %units = ("in","in","pt","pt","pc","pi","mm","mm","cm","cm" 16058 ,"\\hsize","%","\\vsize","%","\\textwidth","%","\\textheight","%"); 16059 16060sub convert_length { # clean 16061 my ($this,$scale) = @_; 16062 $scale = 1 unless $scale; 16063 my ($pxs,$len,$full); 16064 if ( $this =~ /([\d.]*)\s*(in|pt|pc|mm|cm|\\[hv]size|\\\w+(width|height))?/ ) { 16065 $len = ($1 ? $1 : 1); $full = $2; 16066 if ($full &&($full =~ /\\([hv]size|\w+(width|height))/)) { $scale = 1;}; 16067 $pxs = (($full) ? int($len * $unitscale{$full}*$scale + 0.5) 16068 : int($len*$scale + .5) ); 16069 if ( $full =~ /\\([hv]size|\w+(width|height))/) { $pxs .= '%';}; 16070 }; 16071 ($pxs,$len); 16072} 16073 16074 16075 16076 16077 # Inclusion in this list will cause a command or an environment to be ignored. 16078 # This is suitable for commands without arguments and for environments. 16079 # If however a do_env|cmd_<env|cmd> exists then it will be used. 16080 %ignore = ('sloppypar', 1, 'document', 1, 'newblock', 1, 16081 ',', 1, '@', 1, ' ', 1, '-', 1, 16082 'sloppy', 1, 16083 'hyphen', 1, 'titlepage', 1, 'htmlonly', 1, 16084 'flushleft', 1, 'flushright', 1, 'slide', 1, 16085 'tiny', 1, 'Tiny', 1, 'scriptsize', 1, 'footnotesize', 1, 16086 'small', 1, 'normalsize', 1, 'large', 1, 'Large', 1, 16087 'LARGE', 1, 'huge', 1, 'Huge', 1, 16088 %ignore); 16089 16090 # Specify commands with arguments that should be ignored. 16091 # Arbitrary code can be placed between the arguments 16092 # to be executed while processing the command. 16093 # 16094# Note that some commands MAY HAVE ARGUMENTS WHICH SHOULD BE LEFT AS TEXT 16095 # EVEN THOUGH THE COMMAND IS IGNORED (e.g. hbox, center, etc) 16096 16097&ignore_commands( <<_IGNORED_CMDS_); 16098NeedsTeXFormat # {} # [] 16099ProvidesClass # {} # [] 16100ProvidesFile # {} # [] 16101ProvidesPackage # {} # [] 16102abovedisplayskip # &ignore_numeric_argument 16103abovedisplayshortskip # &ignore_numeric_argument 16104addcontentsline # {} # {} # {} 16105addtocontents # {} # {} 16106addvspace # {} # &ignore_numeric_argument 16107and 16108and # \$_ = join(''," - ",\$_) 16109backmatter 16110baselineskip # &ignore_numeric_argument 16111belowdisplayskip # &ignore_numeric_argument 16112belowdisplayshortskip # &ignore_numeric_argument 16113bibdata 16114bibliographystyle # {} 16115bibstyle # {} 16116bigskipamount # &ignore_numeric_argument 16117smallskipamount # &ignore_numeric_argument 16118medskipamount # &ignore_numeric_argument 16119center 16120citation # {} 16121citeauthoryear 16122clearpage 16123cline # {} 16124#documentclass # [] # {} 16125#documentstyle # [] # {} 16126#end # {} 16127enlargethispage # {} 16128evensidemargin # &ignore_numeric_argument 16129filecontents 16130filbreak 16131fil 16132fill 16133flushbottom 16134fontsize # {} # {} 16135footheight # &ignore_numeric_argument 16136footskip # &ignore_numeric_argument 16137frontmatter 16138fussy 16139global 16140goodbreak 16141hbox 16142headheight # &ignore_numeric_argument 16143headsep # &ignore_numeric_argument 16144hfil 16145hfill 16146hfuzz # &ignore_numeric_argument 16147hline 16148hspace # {} # \$_ = join(''," ",\$_) 16149hspacestar # {} # \$_ = join(''," ",\$_) 16150html 16151ifcase 16152ignorespaces 16153indent 16154itemindent # &ignore_numeric_argument 16155itemsep # &ignore_numeric_argument 16156labelsep # &ignore_numeric_argument 16157labelwidth # &ignore_numeric_argument 16158leavevmode 16159leftmargin # &ignore_numeric_argument 16160listparindent # &ignore_numeric_argument 16161lower # &ignore_numeric_argument 16162long 16163mainmatter 16164makebox # [] # [] 16165makeindex 16166marginpar # {} 16167marginparsep # &ignore_numeric_argument 16168marginparwidth # &ignore_numeric_argument 16169markboth # {} # {} 16170markright # {} 16171mathord 16172mathbin 16173mathindent # &ignore_numeric_argument 16174mathrel 16175mathop 16176mathtt 16177#mdseries 16178newpage 16179#newedboolean # {} 16180#newedcommand # {} # [] # [] # {} 16181#newedcounter # {} # [] 16182#newedenvironment # {} # [] # [] # {} # {} 16183#newedtheorem # {} # [] # {} # [] 16184#providedcommand # {} # [] # [] # {} 16185#renewedcommand # {} # [] # [] # {} 16186#renewedenvironment # {} # [] # [] # {} # {} 16187nobreakspace # \$_ = join('',";SPMnbsp;",\$_) 16188nonbreakingspace # \$_ = join('',";SPMnbsp;",\$_) 16189noalign 16190nobreak 16191nocite # {} 16192noindent 16193nolinebreak# [] 16194nopagebreak #[] 16195normalmarginpar 16196numberline 16197oddsidemargin # &ignore_numeric_argument 16198omit 16199onecolumn 16200outer 16201pagenumbering #{} 16202pagestyle # {} 16203parindent # &ignore_numeric_argument 16204parsep # &ignore_numeric_argument 16205parskip # &ignore_numeric_argument 16206partopsep # &ignore_numeric_argument 16207penalty # &ignore_numeric_argument 16208phantom # {} 16209protect 16210raggedright 16211raggedbottom 16212raise # &ignore_numeric_argument 16213raisebox # {} # [] # [] 16214relax 16215reversemarginpar 16216rightmargin # &ignore_numeric_argument 16217#rmfamily 16218rule # [] # {} # {} 16219samepage 16220selectfont 16221startdocument # \$SEGMENT=1;\$SEGMENTED=1; \$_ 16222strut 16223suppressfloats # [] 16224textheight # &ignore_numeric_argument 16225textwidth # &ignore_numeric_argument 16226textnormal 16227#textrm 16228textup 16229theorempreskipamount # &ignore_numeric_argument 16230theorempostskipamount # &ignore_numeric_argument 16231thispagestyle # {} 16232topmargin # &ignore_numeric_argument 16233topsep # &ignore_numeric_argument 16234topskip # &ignore_numeric_argument 16235twocolumn 16236unskip 16237#upshape 16238vfil 16239vfill 16240vfilll 16241vline 16242_IGNORED_CMDS_ 16243 16244 # Commands which need to be passed, ALONG WITH THEIR ARGUMENTS, to TeX. 16245 # Note that this means that the arguments should *not* be translated, 16246 # This is handled by wrapping the commands in the dummy tex2html_wrap 16247 # environment before translation begins ... 16248 16249 # Also it can be used to specify environments which may be defined 16250 # using do_env_* but whose contents will be passed to LaTeX and 16251 # therefore should not be translated. 16252 # Note that this code squeezes spaces out of the args of psfig; 16253 16254 16255 # Images are cropped to the minimum bounding-box for these... 16256 16257&process_commands_in_tex (<<_RAW_ARG_CMDS_); 16258psfig # {} # \$args =~ s/ //g; 16259usebox # {} 16260framebox # [] # [] # {} 16261_RAW_ARG_CMDS_ 16262 16263 # ... but these are set in a box to measure height/depth 16264 # so that white space can be preserved in the images. 16265 16266&process_commands_inline_in_tex (<<_RAW_ARG_CMDS_); 16267#etalchar # {} \$args =~ s/(.*)/\$\^\{\$1\}\\\$/o; 16268fbox # {} 16269#frac # [] # {} # {} 16270dag 16271ddag 16272l 16273L 16274oe 16275OE 16276textexclamdown 16277textquestiondown 16278textregistered 16279textperiodcentered 16280#textcircled # {} 16281#raisebox # {} # [] # [] # {} 16282_RAW_ARG_CMDS_ 16283 16284 16285 16286# These are handled by wrapping the commands in the dummy tex2html_nowrap 16287# environment before translation begins. This environment will be 16288# stripped off later, when the commands are put into images.tex ... 16289 16290&process_commands_nowrap_in_tex (<<_RAW_ARG_NOWRAP_CMDS_); 16291#begingroup 16292#endgroup 16293#bgroup 16294#egroup 16295errorstopmode 16296nonstopmode 16297scrollmode 16298batchmode 16299psfigurepath # {} 16300pssilent 16301psdraft 16302psfull 16303thinlines 16304thicklines 16305linethickness # {} 16306hyphenation # {} 16307hyphenchar # \\ # &get_numeric_argument 16308hyphenpenalty # &get_numeric_argument 16309#let # \\ # <<\\(\\W|\\w+)>> 16310newedboolean # {} 16311newedcommand # {} # [] # [] # {} 16312newedcounter # {} # [] 16313newedenvironment # {} # [] # [] # {} # {} 16314newedtheorem # {} # [] # {} # [] 16315#providedcommand # {} # [] # [] # {} 16316#renewedcommand # {} # [] # [] # {} 16317#renewedenvironment # {} # [] # [] # {} # {} 16318DeclareMathAlphabet # {} # {} # {} # {} # {} 16319SetMathAlphabet # {} # {} # {} # {} # {} # {} 16320DeclareMathSizes # {} # {} # {} # {} 16321DeclareMathVersion # {} 16322DeclareSymbolFont # {} # {} # {} # {} # {} 16323DeclareSymbolFontAlphabet # {} # {} 16324DeclareMathSymbol # {} # {} # {} # {} 16325SetSymbolFont # {} # {} # {} # {} # {} # {} 16326DeclareFontShape # {} # {} # {} # {} # {} # {} 16327DeclareFontFamily # {} # {} # {} 16328DeclareFontEncoding # {} # {} # {} 16329DeclareFontSubstitution # {} # {} # {} # {} 16330mathversion # {} 16331#newfont # {} # {} 16332#normalfont 16333#rmfamily 16334#mdseries 16335newlength # {} 16336setlength # {} # {} 16337addtolength # {} # {} 16338settowidth # {}# {} 16339settoheight # {} # {} 16340settodepth # {} # {} 16341newsavebox # {} 16342savebox # {} # [] # {} 16343sbox # {} # {} 16344setbox # {} 16345TagsOnLeft # \$EQN_TAGS = \"L\" if \$PREAMBLE; 16346TagsOnRight # \$EQN_TAGS = \"R\" if \$PREAMBLE; 16347_RAW_ARG_NOWRAP_CMDS_ 16348 16349 16350&process_commands_wrap_deferred (<<_RAW_ARG_DEFERRED_CMDS_); 16351alph # {} 16352Alph # {} 16353arabic # {} 16354author # [] # {} 16355boldmath 16356unboldmath 16357captionstar # [] # {} 16358caption # [] # {} 16359#endsegment # [] 16360#segment # [] # {} # {} # {} 16361fnsymbol # {} 16362footnote # [] # {} 16363footnotemark # [] 16364footnotetext # [] # {} 16365#thanks # {} 16366roman # {} 16367Roman # {} 16368#mbox # {} 16369parbox # [] # [] # [] # {} # {} 16370#selectlanguage # [] # {} 16371setcounter # {} # {} 16372addtocounter # {} # {} 16373stepcounter # {} 16374refstepcounter # {} 16375value # {} 16376par 16377hrule # &ignore_numeric_argument 16378linebreak # [] 16379pagebreak # [] 16380newfont # {} # {} 16381smallskip 16382medskip 16383bigskip 16384centering 16385raggedright 16386raggedleft 16387itshape 16388#textit # {} 16389upshape 16390slshape 16391#scshape 16392rmfamily 16393sffamily 16394ttfamily 16395mdseries 16396bfseries 16397#textbf # {} 16398em 16399normalfont 16400it 16401rm 16402sl 16403bf 16404tt 16405sf 16406Tiny 16407tiny 16408scriptsize 16409footnotesize 16410small 16411Small 16412SMALL 16413normalsize 16414large 16415Large 16416LARGE 16417huge 16418Huge 16419lowercase # {} 16420uppercase # {} 16421MakeLowercase # {} 16422MakeUppercase # {} 16423htmlinfo # [] 16424htmlinfostar # [] 16425tableofchildlinks # [] 16426tableofchildlinksstar # [] 16427tableofcontents 16428listoffigures 16429listoftables 16430thepart 16431thepage 16432thechapter 16433thesection 16434thesubsection 16435thesubsubsection 16436theparagraph 16437thesubparagraph 16438theequation 16439htmltracenv # {} 16440HTMLsetenv # [] # {} # {} 16441#newedboolean # {} 16442#newedcounter # {} # [] 16443#newedcommand # {} # [] # [] # {} 16444#newedtheorem # {} # [] # {} # [] 16445#newedenvironment # {} # [] # [] # {} # {} 16446providedcommand # {} # [] # [] # {} 16447renewedcommand # {} # [] # [] # {} 16448renewedenvironment # {} # [] # [] # {} # {} 16449url # {} 16450htmlurl # {} 16451latextohtml 16452TeX 16453LaTeX 16454LaTeXe 16455LaTeXiii 16456Xy 16457MF 16458AmS 16459AmSTeX 16460textcircled # {} 16461_RAW_ARG_DEFERRED_CMDS_ 16462 16463 16464#rrm 16465# implement the XBit-Hack for Apache servers, to handle 16466# Server-Side Includes (SSIs) with .html filename extension 16467# 16468sub check_htaccess { 16469 my $access_file = '.htaccess'; 16470 my $has_access = ''; 16471 local $_; 16472 print "\nChecking for .htaccess file"; 16473 if (-f $access_file) { 16474 print STDOUT " ... found"; 16475 open(HTACCESS, "<$access_file"); 16476 while (<HTACCESS>) { 16477 if (/^\s*XBitHack\s*on\s*$/) { 16478 print STDOUT " with XBitHack on"; 16479 $has_access =1; last; 16480 }; 16481 } 16482 print STDOUT "\n"; 16483 close HTACCESS; 16484 return() if $has_access; 16485 open (HTACCESS, ">>$access_file"); 16486 &write_warnings("appended to .htaccess in $DESTDIR"); 16487 } else { 16488 open (HTACCESS, ">$access_file"); 16489 chmod 0644, $access_file; 16490 &write_warnings("created .htaccess file in $DESTDIR"); 16491 } 16492 print HTACCESS "\nXBitHack on\n"; 16493 close HTACCESS; 16494} 16495 16496# This maps the HTML mnemonic names for the ISO-LATIN-1 character references 16497# to their numeric values. When converting latex specials characters to 16498# ISO-LATIN-1 equivalents I use the numeric values because this makes any 16499# conversion back to latex (using revert_raw_tex) more reliable (in case 16500# the text contains "&mnemonic_name"). Errors may occur if an environment 16501# passed to latex (e.g. a table) contains the numeric values of character 16502# references. 16503 16504# RRM: removed this portion; load from latin1.pl instead 16505#&do_require_extension('latin1'); 16506 16507sub make_isolatin1_rx { 16508 local($list) = &escape_rx_chars(join($CD,(values %iso_8859_1_character_map_inv))); 16509 $list =~ s/$CD/|/g; 16510 $isolatin1_rx = "($list)"; 16511} 16512 16513 16514 ################### Frequently used regular expressions ################### 16515 # $1 : preamble 16516 16517 $preamble_rx = "(^[\\s\\S]*)(\\\\begin\\s*$O\\d+$C\\s*document\\s*$O\\d+$C|\\\\startdocument)"; 16518 16519 # \d (number) should sometimes also be a delimiter but this causes 16520 # problems with command names that are allowed to contain numbers (eg tex2html) 16521 # \d is a delimiter with commands which take numeric arguments? 16522 # JCL: I can't see that. \tex2html is also no valid LaTeX (or TeX). 16523 # It is parsed \tex 2html, and \tex may take 2html as argument, but this 16524 # is invalid LaTeX. \d must be treated as delimiter. 16525 16526# JCL(jcl-del) - Characters to be treated as letters, everything else 16527# is a delimiter. 16528 # internal LaTeX command separator, shouldn't be equal to $; 16529 $CD = "\001"; 16530 &make_cmd_spc_rx; # determines space to follow a letter command 16531#old $delimiters = '\'\\s[\\]\\\\<>(=).,#;:~\/!-'; 16532 $letters = 'a-zA-Z'; 16533 $delimiter_rx = "([^$letters])"; 16534# 16535 16536 # liberalized environment names (white space, optional arg, interpunctuation signs etc.) 16537 # $1 : br_id, $2 : <environment> 16538 $begin_env_rx="(\\\\protect)?\\\\begin\\s*(\\[([^\\]]*)])?$O(\\d+)$C\\s*([^'[\\]\\\\#~]+)\\s*$O\\4$C"; 16539 $begin_env_pr_rx="(\\\\protect)?\\\\begin\\s*(\\[([^\\]]*)])?$OP(\\d+)$CP\\s*([^'[\\]\\\\#~]+)\\s*$OP\\4$CP"; 16540 16541 $mbox_rx = "\\\\mbox\\s*"; 16542 16543 $match_br_rx = "\\s*$O\\d+$C\\s*"; 16544 16545 $opt_arg_rx = "\\s*\\[([^\\]]*)\\]\\s*"; # Cannot handle nested []s! 16546 $optional_arg_rx = "^\\s*\\[([^]]*)\\]"; # Cannot handle nested []s! 16547 16548 $block_close_rx = "^<\\/(DIV|P|BLOCKQUOTE)>\$"; 16549 $all_close_rx = "^<\\/(BODY|PRE|OL|UL|DL|FORM|ADDRESS)>\$"; 16550 16551 # Matches a pair of matching brackets 16552 # $1 : br_id 16553 # $2 : contents 16554 $next_pair_rx = "^[\\s%]*$O(\\d+)$C([\\s\\S]*)$O\\1$C($comment_mark\\d*\\n?)?"; 16555 16556 # will comments be a problem after these ??? 16557 $any_next_pair_rx = "$O(\\d+)$C([\\s\\S]*)$O\\1$C"; 16558 $any_next_pair_rx4 = "$O(\\d+)$C([\\s\\S]*)$O\\4$C"; 16559 $any_next_pair_pr_rx4 = "$OP(\\d+)$CP([\\s\\S]*)$OP\\4$CP"; 16560 $any_next_pair_rx5 = "$O(\\d+)$C([\\s\\S]*)$O\\5$C"; 16561 $any_next_pair_rx6 = "$O(\\d+)$C([\\s\\S]*)$O\\6$C"; 16562 16563 # used for labels in {enumerate} environments 16564 $standard_label_rx = 16565 "\\s*[[]\\s*((($any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]"; 16566 $enum_label_rx = "^(((\{[^{}]*\})|([^{}]))*)([aAiI1])(.*)"; 16567 $enum_level = 0; # level for enumerate (1-4, i-iv) 16568 16569 16570 # Matches the \ensuremath command 16571 $enspair = "\\\\ensuremath\\s*" . $any_next_pair_rx; 16572# $enspair = "\\\\ensuremath\\s*$O(\\d+)$C([\\s\\S]*[\\\\\$&]+[\\s\\S]*)$O\\1$C"; 16573 16574 # Matches math comments, from math.pl 16575 $math_verbatim_rx = "$verbatim_mark#math(\\d+)#"; 16576 $mathend_verbatim_rx = "$verbatim_mark#mathend([^#]*)#"; 16577 16578 # Matches math array environments 16579 $array_env_rx = "array|cases|\\w*matrix"; 16580 16581 # initially empty; has a value in HTML 3.2 and 4.0 16582 $math_class = '' unless ($math_class); 16583 $eqno_class = '' unless ($eqno_class); 16584 16585 # Matches to end-of-line and subsequent spaces 16586 $EOL = "[ \\t]*\\n?"; 16587 16588 # Matches wrapped \par command 16589 $par_rx = "\\n?\\\\begin(($O|$OP)\\d+($C|$CP))tex2html_deferred\\1\\\\par\\s\*" 16590 . "\\\\end(($O|$OP)\\d+($C|$CP))tex2html_deferred\\4\\n?"; 16591 16592 # $1 : br_id 16593 $begin_cmd_rx = "$O(\\d+)$C"; 16594 16595 # $1 : image filename prefix 16596 $img_rx = "(\\w*T?img\\d+)"; 16597 16598 # $1 : largest argument number 16599 $tex_def_arg_rx = "^[#0-9]*#([0-9])($O|$OP)"; 16600 16601 # only some non-alphanumerics are allowed in labels, Why? 16602 $label_rx = "[^\\w\.\\\-\\\+\\\:]"; 16603 16604#JCL(jcl-del) - new face, see also &do_cmd_makeatletter et.al. 16605# $cmd_delims = q|-#,.~/\'`^"=\$%&_{}@|; # Commands which are also delimiters! 16606# $single_cmd_atletter_rx = "\\\\([a-zA-Z\\\@]+\\*?|[$cmd_delims]|\\\\)"; 16607# $single_cmd_atother_rx = "\\\\([a-zA-Z]+\\*?|[$cmd_delims]|\\\\)"; 16608 # $1 : declaration or command or newline (\\) 16609 &make_single_cmd_rx; 16610# 16611 16612 # $1 : description in a list environment 16613 $item_description_rx = 16614# "\\\\item\\s*[[]\\s*((($any_next_pair_rx4)|([[][^]]*[]])|[^]])*)[]]"; 16615 "\\\\item\\s*[[]\\s*((($any_next_pair_pr_rx4)|([[][^]]*[]])|[^]])*)[]]"; 16616 16617 $fontchange_rx = 'rm|em|it|sl|sf|tt|sc|upshape|normalfont'; 16618 $fontweight_rx = 'bf|mdseries|normalfont'; 16619 $colorchange_rx = "(text)?color\\s*(\#\\w{6})?"; 16620 $sizechange_rx = 'tiny|Tiny|scriptsize|footnotesize|small|Small|SMALL' . 16621 '|normalsize|large|Large|LARGE|huge|Huge'; 16622 16623# $image_switch_rx = "makeimage"; 16624 $image_switch_rx = "makeimage|scshape|sc"; 16625 $env_switch_rx = "writetolatex"; 16626 $raw_arg_cmds{'font'} = 1; 16627 16628 # Matches the \caption command 16629 # $1 : br_id 16630 # $2 : contents 16631 $caption_suffixes = "lof|lot"; 16632# $caption_rx = "\\\\caption\\s*([[]\\s*((($any_next_pair_rx5)|([[][^]]*[]])|[^]])*)[]])?$O(\\d+)$C([\\s\\S]*)$O\\8$C$EOL"; 16633 16634 $caption_rx = "\\\\(top|bottom|table)?caption\\s*\\\*?\\s*([[]\\s*((($any_next_pair_rx6)|([[][^]]*[]])|[^]])*)[]])?$O(\\d+)$C([\\s\\S]*)$O\\9$C$EOL"; 16635 $caption_width_rx = "\\\\setlength\\s*(($O|$OP)\\d+($C|$CP))\\\\captionwidth\\1\\s*(($O|$OP)\\d+($C|$CP))([^>]*)\\4"; 16636 16637 # Matches the \htmlimage command 16638 # $1 : br_id 16639 # $2 : contents 16640 $htmlimage_rx = "\\\\htmlimage\\s*$O(\\d+)$C([\\s\\S]*)$O\\1$C$EOL"; 16641 $htmlimage_pr_rx = "\\\\htmlimage\\s*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP$EOL"; 16642 16643 # Matches the \htmlborder command 16644 # $1 : optional argument... 16645 # $2 : ...contents i.e. extra attributes 16646 # $3 : br_id 16647 # $4 : contents i.e. width 16648 $htmlborder_rx = "\\\\htmlborder\\s*(\\[([^]]*)\\])?\\s*$O(\\d+)$C(\\d*)$O\\3$C$EOL"; 16649 $htmlborder_pr_rx = "\\\\htmlborder\\s*(\\[([^]]*)\\])?\\s*$OP(\\d+)$CP(\\d*)$OP\\3$CP$EOL"; 16650 16651 # Matches a pair of matching brackets 16652 # USING PROCESSED DELIMITERS; 16653 # (the delimiters are processed during command translation) 16654 # $1 : br_id 16655 # $2 : contents 16656# $next_pair_pr_rx = "^[\\s%]*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP"; 16657 $next_pair_pr_rx = "^[\\s%]*$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP($comment_mark\\d*\\n?)?"; 16658 $any_next_pair_pr_rx = "$OP(\\d+)$CP([\\s\\S]*)$OP\\1$CP($comment_mark\\d*\\n?)?"; 16659 $next_token_rx = "^[\\s%]*(\\\\[A-Za-z]+|\\\\[^a-zA-Z]|.)"; 16660 16661 $HTTP_start = 'http:'; 16662 16663 # This will be used to recognise escaped special characters as such 16664 # and not as commands 16665 $latex_specials_rx = '[\$]|&|%|#|{|}|_'; 16666 $html_escape_chars = '<>&'; 16667 16668 # This is used in sub revert_to_raw_tex before handing text to be processed 16669 # by latex. 16670 $html_specials_inv_rx = join("|", keys %html_specials_inv); 16671 16672 # These are used for direct replacements in/from ALT=... strings 16673 %html_special_entities = ('<','lt','>','gt','"','quot','&','amp'); 16674 %html_spec_entities_inv = ('lt','<','gt','>','quot','"','amp','&'); 16675 16676 # This is also used in sub revert_to_raw_tex 16677 $character_entity_rx = '(&#(\d+);)'; 16678 $named_entity_rx = '&(\w+);'; 16679 16680 #commands for altering theorem-styles 16681 $theorem_cmd_rx = 'theorem(style|(header|body)font)'; 16682 16683 16684 # Matches a \begin or \end {tex2html_wrap}. Also used by revert_to_raw_tex 16685 $tex2html_wrap_rx = '\\\\(begin|end)\\s*\{\\s*(tex2html_(wrap|nowrap|deferred|nomath|preform|\\w*_inline)[_a-z]*|makeimage)\\s*\}'."($EOL)"; 16686 $tex2html_deferred_rx = '\\\\(begin|end)(<<\\d+>>)tex2html_deferred\\2'; 16687 $tex2html_deferred_rx2 = '\\\\(begin|end)(<<\\d+>>)tex2html_deferred\\4'; 16688 $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"; 16689 16690 # The first empty parenthese pair is for non-letter commands. 16691 # $2: meta command, $4: delimiter (may be empty) ignore the *-version distinction 16692# $meta_cmd_rx = "()\\\\(providecommand|renewcommand|renewenvironment|newcommand|newenvironment|newtheorem|newcounter|newboolean|newif|let)(([^$letters$cmd_spc])|$cmd_spcs_rx)"; 16693 $meta_cmd_rx = "()\\\\(providecommand|renewcommand|renewenvironment|newcommand|newenvironment|newtheorem|newcounter|newboolean|newif|DeclareRobustCommand|DeclareMathOperator\\*?)\\\*?(([^$letters$cmd_spc])|$cmd_spcs_rx)"; 16694 16695 &make_counters_rx; 16696 16697 # Matches a label command and its argument 16698 $labels_rx = "\\\\label\\s*$O(\\d+)$C([\\s\\S]*)$O\\1$C$EOL"; 16699 $labels_rx8 = "\\\\label\\s*$O(\\d+)$C([\\s\\S]*)$O\\8$C$EOL"; 16700 16701 # Matches environments that should not be touched during the translation 16702# $verbatim_env_rx = "\\s*{(verbatim|rawhtml|LVerbatim)[*]?}"; 16703 $verbatim_env_rx = "\\s*(\\w*[Vv]erbatim|rawhtml|imagesonly|tex2html_code)[*]?"; 16704 $image_env_rx = "\\s*(picture|xy|diagram)[*]?"; 16705 $keepcomments_rx = "\\s*(picture|makeimage|xy|diagram)[*]?"; 16706 16707 # names of different math environment types 16708 $display_env_rx = "displaymath|makeimage|eqnarray|equation"; 16709 $inline_env_rx = "inline|indisplay|entity|xy|diagram"; 16710 $sub_array_env_rx = "array|(small|\\w)\?matrix|tabular|cases"; 16711 16712 # Matches environments needing pre-processing for images 16713 $pre_processor_env_rx = "\\\\(begin|end)\\s*(($O|$OP|\{)\\d+($C|$CP|\}))pre_(\\w+)\\2"; 16714 16715 # Matches icon markers 16716 $icon_mark_rx = "<tex2html_(" . join("|", keys %icons) . ")>"; 16717 16718 $start_time = time; 16719 print STDOUT join(" ", "Starting at", $start_time, "seconds\n") 16720 if ($TIMING||$DEBUG||($VERBOSITY>2)); 16721$bbalise_rx = join('',$OP,'(\\d+)',$CP) ; 16722$bdeferred_rx = join('',$bbalise_rx,'tex2html_deferred') ; 16723 16724} # end of &initialise 16725 16726# Frequently used regular expressions with arguments 16727sub make_end_env_rx { 16728 local($env) = @_; 16729 $env = &escape_rx_chars($env); 16730 "\\\\end\\s*$O(\\d+)$C\\s*$env\\s*$O\\1$C".$EOL; 16731} 16732 16733sub make_begin_end_env_rx { 16734 local($env) = @_; 16735 $env = &escape_rx_chars($env); 16736 "\\\\(begin|end)\\s*$O(\\d+)$C\\s*$env\\s*$O\\3$C(\\s*\$)?"; 16737} 16738 16739sub make_end_cmd_rx { 16740 local($br_id) = @_; 16741 "$O$br_id$C"; 16742} 16743 16744#JCL(jcl-del) - see also &tokenize. 16745# Arrange commands into a regexp for tokenisation. 16746# Any letter command will gobble spaces, but avoids to match 16747# on ensuing letters (\foo won't match on \foox). 16748# Any non-letter command retains spaces and matches always 16749# by itself (\| matches \|... regardless of ...). 16750# 16751# This all is a huge kludge. The commands names should stay fix, 16752# regardless of changing catcodes. If we have \makeatletter, 16753# and LaTeX2HTML marks \@foo, then \@foo will be expanded 16754# properly before \makeatother, but does weird things on \@foo 16755# after \makeatother (\@foo in LaTeX is then \@ and foo, which 16756# isn't recognized as such). 16757# The reason is that the text to match the command \@foo 16758# in LaTeX mustn't be \@foo at all, because any text in LaTeX 16759# is also attributed with the category codes. 16760# 16761# But at least we have proper parsing of letter and non-letter 16762# commands as long as catcoding won't upset LaTeX2HTML too much. 16763# 16764sub make_new_cmd_rx { 16765 return("") if $#_ < 0; # empty regexp if list is empty! 16766 16767 # We have a subtle treatment of ambivalent commands like 16768 # \@foo in situations depicted above! 16769 # Get every command that contains no letters ... 16770 local($nonlettercmds) = 16771 &escape_rx_chars(join($CD, grep(!/[$letters]/,@_))); 16772 # and every command that contains a letter 16773 local($lettercmds) = 16774 &escape_rx_chars(join($CD, grep(/[$letters]/,@_))); 16775 16776 if (%renew_command) { 16777 local($renew); 16778 foreach $renew (keys %renew_command) { 16779 $lettercmds =~ s/(^|$CD)$renew//; } 16780 $lettercmds =~ s/^$CD$//; 16781 } 16782 16783 # replace the temporary $CD delimiter (this enables eg. \| command) 16784 $nonlettercmds =~ s/$CD/|/g; 16785 $lettercmds =~ s/$CD/|/g; 16786 16787 # In case we have no non-letter commands, insert empty parentheses 16788 # to align match strings. 16789 # 16790 $nonlettercmds =~ s/^\||\|$//g; 16791 $lettercmds =~ s/^\||\|$//g; 16792 local($rx) = (length($nonlettercmds) ? "\\\\($nonlettercmds)" : ""); 16793 if (length($lettercmds)) { 16794 $rx .= ( length($rx) ? "|" : "()" ); 16795 $rx .= "\\\\($lettercmds)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)"; 16796 } 16797 # $1: non-letter cmd, $2: letter cmd, $4: delimiter 16798 # Eg. \\(\@|...|\+)|\\(abc|...|xyz)(([^a-zA-Z \t])|[ \t]+) 16799 # $1 and $2 are guaranteed to alternate, $4 may be empty. 16800 $rx; 16801} 16802 16803# Build a simple regexp to use after tokenisation for 16804# faster translation. 16805sub make_new_cmd_no_delim_rx { 16806 return("") if $#_ < 0; # empty regexp if list is empty! 16807 # Get every command that contains no letters ... 16808 local($_) = &escape_rx_chars(join($CD, @_)); 16809 s/$CD/|/g; 16810 16811 join('',"\\\\(",$_,")"); 16812} 16813 16814 16815#JCL(jcl-del) - new face: w/o arg (was 'begin' only), escapes env names 16816sub make_new_env_rx { 16817 local($envs) = &escape_rx_chars(join($CD, keys %new_environment)); 16818 $envs =~ s/$CD/|/g; 16819 length($envs) ? "\\\\begin\\s*$O(\\d+)$C\\s*($envs)\\s*$O\\1$C\\s*" : ""; 16820} 16821 16822sub make_new_end_env_rx { 16823 local($envs) = &escape_rx_chars(join($CD, keys %new_environment)); 16824 $envs =~ s/$CD/|/g; 16825 length($envs) ? "\\\\end\\s*$O(\\d+)$C\\s*($envs)\\s*$O\\1$C\\s*" : ""; 16826} 16827 16828#JCL(jcl-del) - $delimiter_rx -> ^$letters 16829# don't care for $cmd_spc_rx; space after sectioning commands 16830# is unlikely and I don't want to try too much new things 16831# 16832sub make_sections_rx { 16833 local($section_alts) = &get_current_sections; 16834 # $section_alts includes the *-forms of sectioning commands 16835 $sections_rx = "()\\\\($section_alts)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)"; 16836# $sections_rx = "()\\\\($section_alts)([^$letters])"; 16837} 16838 16839sub make_order_sensitive_rx { 16840 local(@theorem_alts, $theorem_alts); 16841 @theorem_alts = ($preamble =~ /\\newtheorem\s*{([^\s}]+)}/og); 16842 $theorem_alts = join('|',@theorem_alts); 16843# 16844# HWS: Added kludge to require counters to be more than 2 characters long 16845# in order to be flagged as order-sensitive. This will permit equations 16846# with \theta to remain order-insensitive. Also permit \alpha and 16847# the eqnarray* environment to remain order-insensitive. 16848# 16849 $order_sensitive_rx = 16850# "(equation|eqnarray[^*]|\\\\caption|\\\\ref|\\\\the[a-z]{2,2}[a-z]|\\\\stepcounter" . 16851 "(\\\\caption|\\\\ref|\\\\the[a-z]{2,2}[a-z]|\\\\stepcounter" . 16852 "|\\\\arabic|\\\\roman|\\\\Roman|\\\\alph[^a]|\\\\Alph|\\\\fnsymbol)"; 16853 $order_sensitive_rx =~ s/\)/|$theorem_alts)/ if $theorem_alts; 16854} 16855 16856sub make_language_rx { 16857 local($language_alts) = join("|", keys %language_translations); 16858# $setlanguage_rx = "\\\\se(lec)?tlanguage\\s*{\\\\?($language_alts)}"; 16859 $setlanguage_rx = "\\\\setlanguage\\s*{\\\\?($language_alts)}"; 16860 $language_rx = "\\\\($language_alts)TeX"; 16861 $case_change_rx = "(\\\\(expandafter|noexpand)\s*)?\\\\((Make)?([Uu]pp|[Ll]ow)ercase)\s*"; 16862} 16863 16864sub addto_languages { 16865 local($lang) = @_; 16866 local($trans) = "main'".$lang.'_translation'; 16867 if (defined &$trans) { 16868 $language_translations {$lang} = $lang.'_translation'; 16869 } 16870} 16871 16872# JCL(jcl-del) - new rexexp type 16873sub make_raw_arg_cmd_rx { 16874 # $1 or $2 : commands to be processed in latex (with arguments untouched) 16875 # $4 : delimiter 16876 $raw_arg_cmd_rx = &make_new_cmd_rx(keys %raw_arg_cmds); 16877 $raw_arg_cmd_rx; 16878} 16879 16880# There are probably more. 16881# Interferences not checked out yet, thus in makeat... only. 16882sub make_letter_sensitive_rx { 16883 $delimiter_rx = "([^$letters])"; 16884 &make_sections_rx; 16885 &make_single_cmd_rx; 16886 &make_counters_rx; 16887} 16888 16889#JCL(jcl-del) - this could eat one optional newline, too. 16890# But this might result in large lines... anyway, it *should* be 16891# handled. A possible solution would be to convert adjacent newlines 16892# into \par's in preprocessing. 16893sub make_cmd_spc_rx { 16894 $cmd_spc = " \\t"; 16895 $cmd_spc_rx = "[ \\t]*"; # zero or more 16896 $cmd_spcs_rx = "[ \\t]+"; # one or more 16897} 16898 16899sub make_single_cmd_rx { 16900 $single_cmd_rx = "\\\\([^$letters])|\\\\([$letters]+\\*?)(([^$letters$cmd_spc])|$cmd_spcs_rx|\n|\$)"; 16901} 16902 16903sub make_counters_rx { 16904 # Matches counter commands - these are caught early and are appended to the 16905 # file that is passed to latex. 16906#JCL(jcl-del) - $delimiter_rx -> ^$letters 16907 $counters_rx = "()\\\\(newcounter|addtocounter|setcounter|refstepcounter|stepcounter|arabic|roman|Roman|alph|Alph|fnsymbol)(([^$letters$cmd_spc])|$cmd_spcs_rx|\$)"; 16908} 16909 16910 16911# Creates an anchor for its argument and saves the information in 16912# the array %index; 16913# In the index the word will use the beginning of the title of 16914# the current section (instead of the usual pagenumber). 16915# The argument to the \index command is IGNORED (as in latex) 16916sub make_index_entry { &make_real_index_entry(@_) } 16917sub make_real_index_entry { 16918 local($br_id,$str) = @_; 16919 local($this_file) = $CURRENT_FILE; 16920 $TITLE = $saved_title if (($saved_title)&&(!($TITLE)||($TITLE eq $default_title))); 16921 # Save the reference 16922 $str = "$str###" . ++$global{'max_id'}; # Make unique 16923 $index{$str} .= &make_half_href($this_file."#$br_id"); 16924 "<A NAME=\"$br_id\">$anchor_invisible_mark<\/A>"; 16925} 16926 16927sub image_message { # clean 16928 print <<"EOF"; 16929 16930To resolve the image conversion problems please consult 16931the "Troubleshooting" section of your local User Manual 16932or read it online at 16933 http://www-texdev.ics.mq.edu.au/l2h/docs/manual/ 16934 16935EOF 16936} 16937 16938sub image_cache_message { # clean 16939 print <<"EOF"; 16940 16941If you are having problems displaying the correct images with Mosaic, 16942try selecting "Flush Image Cache" from "Options" in the menu-bar 16943and then reload the HTML file. 16944EOF 16945} 16946 16947__DATA__ 16948 16949# start of POD documentation 16950 16951=head1 NAME 16952 16953latex2html - Translate LaTeX files to HTML (HyperText Markup Language) 16954 16955=head1 SYNOPSIS 16956 16957B<latex2html> S<[ B<-help> | B<-h> ]> S<[ B<-version> | B<-V> ]> 16958 16959B<latex2html> S<[ B<-split> I<num> ]> 16960S<[ B<-link> I<num> ]> 16961S<[ B<-toc_depth> I<num> ]> 16962S<[ B<->(B<no>)B<toc_stars> ]> 16963S<[ B<->(B<no>)B<short_extn> ]> 16964S<[ B<-iso_language> I<lang> ]> 16965S<[ B<->(B<no>)B<validate> ]> 16966S<[ B<->(B<no>)B<latex> ]> 16967S<[ B<->(B<no>)B<djgpp> ]> 16968S<[ B<->(B<no>)B<fork> ]> 16969S<[ B<->(B<no>)B<external_images> ]> 16970S<[ B<->(B<no>)B<ascii_mode> ]> 16971S<[ B<->(B<no>)B<lcase_tags> ]> 16972S<[ B<->(B<no>)B<ps_images> ]> 16973S<[ B<-font_size> I<size> ]> 16974S<[ B<->(B<no>)B<tex_defs> ]> 16975S<[ B<->(B<no>)B<navigation> ]> 16976S<[ B<->(B<no>)B<top_navigation> ]> 16977S<[ B<->(B<no>)B<buttom_navigation> ]> 16978S<[ B<->(B<no>)B<auto_navigation> ]> 16979S<[ B<->(B<no>)B<index_in_navigation> ]> 16980S<[ B<->(B<no>)B<contents_in_navigation> ]> 16981S<[ B<->(B<no>)B<next_page_in_navigation> ]> 16982S<[ B<->(B<no>)B<previous_page_in_navigation> ]> 16983S<[ B<->(B<no>)B<footnode> ]> 16984S<[ B<->(B<no>)B<numbered_footnotes> ]> 16985S<[ B<-prefix> I<output_filename_prefix> ]> 16986S<[ B<->(B<no>)B<auto_prefix> ]> 16987S<[ B<-long_titles> I<num> ]> 16988S<[ B<->(B<no>)B<custom_titles> ]> 16989S<[ B<-title>|B<-t> I<top_page_title> ]> 16990S<[ B<->(B<no>)B<rooted> ]> 16991S<[ B<-rootdir> I<output_directory> ]> 16992S<[ B<-dir> I<output_directory> ]> 16993S<[ B<-mkdir> ]> 16994S<[ B<-address> I<author_address> | B<-noaddress> ]> 16995S<[ B<->(B<no>)B<subdir> ]> 16996S<[ B<-info> I<0> | I<1> | I<string> ]> 16997S<[ B<->(B<no>)B<auto_link> ]> 16998S<[ B<-reuse> I<num> | B<-noreuse> ]> 16999S<[ B<->(B<no>)B<antialias_text> ]> 17000S<[ B<->(B<no>)B<antialias> ]> 17001S<[ B<->(B<no>)B<transparent> ]> 17002S<[ B<->(B<no>)B<white> ]> 17003S<[ B<->(B<no>)B<discard> ]> 17004S<[ B<-image_type> I<type> ]> 17005S<[ B<->(B<no>)B<images> ]> 17006S<[ B<-accent_images> I<type> | B<-noaccent_images> ]> 17007S<[ B<-style> I<style> ]> 17008S<[ B<->(B<no>)B<parbox_images> ]> 17009S<[ B<->(B<no>)B<math> ]> 17010S<[ B<->(B<no>)B<math_parsing> ]> 17011S<[ B<->(B<no>)B<latin> ]> 17012S<[ B<->(B<no>)B<entities> ]> 17013S<[ B<->(B<no>)B<local_icons> ]> 17014S<[ B<->(B<no>)B<scalable_fonts> ]> 17015S<[ B<->(B<no>)B<images_only> ]> 17016S<[ B<->(B<no>)B<show_section_numbers> ]> 17017S<[ B<->(B<no>)B<show_init> ]> 17018S<[ B<-init_file> I<Perl_file> ]> 17019S<[ B<-up_url> I<up_URL> ]> 17020S<[ B<-up_title> I<up_title> ]> 17021S<[ B<-down_url> I<down_URL> ]> 17022S<[ B<-down_title> I<down_title> ]> 17023S<[ B<-prev_url> I<prev_URL> ]> 17024S<[ B<-prev_title> I<prev_title> ]> 17025S<[ B<-index> I<index_URL> ]> 17026S<[ B<-biblio> I<biblio_URL> ]> 17027S<[ B<-contents> I<toc_URL> ]> 17028S<[ B<-external_file> I<external_aux_file> ]> 17029S<[ B<->(B<no>)B<short_index> ]> 17030S<[ B<->(B<no>)B<unsegment> ]> 17031S<[ B<->(B<no>)B<debug> ]> 17032S<[ B<-tmp> I<path> ]> 17033S<[ B<->(B<no>)B<ldump> ]> 17034S<[ B<->(B<no>)B<timing> ]> 17035S<[ B<-verbosity> I<num> ]> 17036S<[ B<-html_version> I<num> ]> 17037S<[ B<->(B<no>)B<strict> ]> 17038I<file.tex> S<[ I<file2.tex> ... ]> 17039 17040=head1 DESCRIPTION 17041 17042I<LaTeX2HTML> is a Perl program that translates LaTeX source files into 17043HTML. For each source file given as an argument the translator will create 17044a directory containing the corresponding HTML files. 17045 17046=head1 OPTIONS 17047 17048Many options can be specified in a true/false manner. This is indicated by 17049I<(no)>, e.g. to enable passing unknown environments to LaTeX, say "-latex", 17050to disable the feature say "-nolatex" or "-no_latex" (portability mode). 17051 17052=over 4 17053 17054=item B<-help> | B<-h> 17055 17056Print this online manual and exit. 17057 17058=item B<-version> | B<-V> 17059 17060Print the LaTeX2HTML release and version information and exit. 17061 17062=item B<-split> I<num> 17063 17064Stop making separate files at this depth (say "-split 0" for one huge HTML 17065file). 17066 17067=item B<-link> I<num> 17068 17069Stop showing child nodes at this depth. 17070 17071=item B<-toc_depth> I<num> 17072 17073MISSING_DESCRIPTION 17074 17075=item B<->(B<no>)B<toc_stars> 17076 17077MISSING_DESCRIPTION 17078 17079=item B<->(B<no>)B<short_extn> 17080 17081If this is set all HTML file will have extension C<.htm> instead of 17082C<.html>. This is helpful when shipping the document to PC systems. 17083 17084=item B<-iso_language> I<lang> 17085 17086MISSING_DESCRIPTION 17087 17088=item B<->(B<no>)B<validate> 17089 17090When this is set true, the HTML validator specified in F<l2hconf.pm> 17091will run. 17092 17093=item B<->(B<no>)B<latex> 17094 17095Pass unknown environments to LaTeX. This is the default. 17096 17097=item B<->(B<no>)B<djgpp> 17098 17099Specify this switch if you are running DJGPP on DOS and need to avoid 17100running out of filehandles. 17101 17102=item B<->(B<no>)B<fork> 17103 17104Enable/disable forking. The default is reasonable for this platform. 17105 17106=item B<->(B<no>)B<external_images> 17107 17108If set, leave the images outside the document. 17109 17110=item B<->(B<no>)B<ascii_mode> 17111 17112This is different from B<-noimages>. 17113If this is set, B<LaTeX2HTML> will show textual tags rather than 17114images, both in navigation panel and text (Eg. C<[Up]> instead the up 17115icon). 17116You could use this feature to create simple text from your 17117document, eg. with 'Save as... Text' from B<Netscape> or with 17118B<lynx -dump>. 17119 17120=item B<->(B<no>)B<lcase_tags> 17121 17122writes out HTML tag names using lowercase letters, rather than uppercase. 17123 17124=item B<->(B<no>)B<ps_images> 17125 17126If set, use links to external postscript images rather than inlined bitmaps. 17127 17128=item B<-font_size> I<size> 17129 17130To set the point size of LaTeX-generated GIF files, specify the desired 17131value (i.e., C<10pt>, C<11pt>, C<12pt>, etc.). 17132The default is to use the point size of the original LaTeX document. 17133This value will be magnified by I<$FIGURE_SCALE_FACTOR> and 17134I<$MATH_SCALE_FACTOR> defined in F<l2hconf.pm>. 17135 17136=item B<->(B<no>)B<tex_defs> 17137 17138Enable interpretation of raw TeX commands (default). 17139Note: There are many variations of C<\def> that B<LaTeX2HTML> cannot process 17140correctly! 17141 17142=item B<->(B<no>)B<navigation> 17143 17144Put a navigation panel at the top of each page (default). 17145 17146=item B<->(B<no>)B<top_navigation> 17147 17148Enables navigation links at the top of each page (default). 17149 17150=item B<->(B<no>)B<buttom_navigation> 17151 17152Enables navigation links at the buttom of each page. 17153 17154=item B<->(B<no>)B<auto_navigation> 17155 17156Put navigation links at the top of each page. If the page exceeds 17157I<$WORDS_IN_PAGE> number of words then put one at the bottom of the page. 17158 17159=item B<->(B<no>)B<index_in_navigation> 17160 17161Put a link to the index page in the navigation panel. 17162 17163=item B<->(B<no>)B<contents_in_navigation> 17164 17165Put a link to the table of contents in the navigation panel. 17166 17167=item B<->(B<no>)B<next_page_in_navigation> 17168 17169Put a link to the next logical page in the navigation panel. 17170 17171=item B<->(B<no>)B<previous_page_in_navigation> 17172 17173Put a link to the previous logical page in the navigation panel. 17174 17175=item B<->(B<no>)B<footnode> 17176 17177Puts all footnotes onto a separate HTML page, called F<footnode.html>, 17178rather than at the bottom of the page where they are referenced. 17179 17180=item B<->(B<no>)B<numbered_footnotes> 17181 17182If true, you will get every footnote applied with a subsequent number, else 17183with a generic hyperlink icon. 17184 17185=item B<-prefix> I<output_filename_prefix> 17186 17187Set the output file prefix, prepended to all C<.html>, C<.gif> and C<.pl> 17188files. See also B<-auto_prefix>. 17189 17190=item B<->(B<no>)B<auto_prefix> 17191 17192Set this to automatically insert the equivalent of B<-prefix >C<basename->", 17193where "basename" is the base name of the file being translated. 17194 17195=item B<-long_titles> I<num> 17196 17197MISSING_DESCRIPTION 17198 17199=item B<->(B<no>)B<custom_titles> 17200 17201MISSING_DESCRIPTION 17202 17203=item B<-title>|B<-t> I<top_page_title> 17204 17205The title (displayed in the browser's title bar) the document shall get. 17206 17207=item B<->(B<no>)B<rooted> 17208 17209MISSING_DESCRIPTION 17210 17211=item B<-rootdir> I<output_directory> 17212 17213MISSING_DESCRIPTION 17214 17215=item B<-dir> I<output_directory> 17216 17217Put the result in this directory instead of parallel to the LaTeX file, 17218provided the directory exists, or B<-mkdir> is specified. 17219 17220=item B<-mkdir> 17221 17222Allow directory specified with B<-dir> to be created if necessary. 17223 17224=item B<-address> I<author_address> | B<-noaddress> 17225 17226Supply your own string if you don't like the default 17227"E<lt>NameE<gt> E<lt>DateE<gt>". B<-noaddress> suppresses the 17228generation of an address footer. 17229 17230=item B<->(B<no>)B<subdir> 17231 17232If set (default), B<LaTeX2HTML> creates (or reuses) another file directory. 17233When false, the generated HTML files will be placed in the current 17234directory. 17235 17236=item B<-info> I<0> | I<1> | I<string> 17237 17238=item B<-noinfo> 17239 17240If 0 is specified (or B<-noinfo> is used), do not generate an I<"About this 17241document..."> section. If 1 is specified (default), the standard info page is 17242generated. If a custom string is given, it is used as the info page. 17243 17244=item B<->(B<no>)B<auto_link> 17245 17246MISSING_DESCRIPTION 17247 17248=item B<-reuse> I<num> | B<-noreuse> 17249 17250If false, do not reuse or recycle identical images generated in previous 17251runs. If the html subdirectory already exists, start the interactive session. 17252If I<num> is nonzero, do recycle them and switch off the interactive session. 17253If 1, only recycle images generated from previous runs. 17254If 2, recycle images from the current and previous runs (default). 17255 17256=item B<->(B<no>)B<antialias_text> 17257 17258Use anti-aliasing in the generation of images of typeset material; 17259e.g. mathematics and text, e.g. in tables and {makeimage} environments. 17260 17261=item B<->(B<no>)B<antialias> 17262 17263Use anti-aliasing in the generation of images of figures. This usually 17264results in "sharper" bitmap images. 17265 17266=item B<->(B<no>)B<transparent> 17267 17268If this is set to false then any inlined images generated from "figure" 17269environments will NOT be transparent. 17270 17271=item B<->(B<no>)B<white> 17272 17273This sets the background of generated images to white for anti-aliasing. 17274 17275=item B<->(B<no>)B<discard> 17276 17277if true, the PostScript file created for each generated image 17278is discarded immediately after its image has been rendered and saved in the 17279required graphics format. This can lead to significant savings in disk-space, 17280when there are a lot of images, since otherwise these files are not discarded 17281until the end of all processing. 17282 17283=item B<-image_type> I<type> 17284 17285Specify the type of bitmap images to be generated. Depending on your setup, 17286B<LaTeX2HTML> can generate B<gif> or B<png> images. Note: Gif images have 17287certain legal restrictions, as their generation involves an algorithm 17288patented by Unisys. 17289 17290=item B<->(B<no>)B<images> 17291 17292If false, B<LaTeX2HTML> will not attempt to produce any inlined images. 17293The missing images can be generated "off-line" by restarting B<LaTeX2HTML> 17294with B<-images_only>. 17295 17296=item B<-accent_images> I<type> | B<-noaccent_images> 17297 17298MISSING_DESCRIPTION 17299 17300=item B<-style> I<style> 17301 17302MISSING_DESCRIPTION 17303 17304=item B<->(B<no>)B<parbox_images> 17305 17306MISSING_DESCRIPTION 17307 17308=item B<->(B<no>)B<math> 17309 17310By default the special MATH extensions are not used 17311since they do not conform with the HTML 3.2 standard. 17312 17313=item B<->(B<no>)B<math_parsing> 17314 17315MISSING_DESCRIPTION 17316 17317=item B<->(B<no>)B<latin> 17318 17319MISSING_DESCRIPTION 17320 17321=item B<->(B<no>)B<entities> 17322 17323MISSING_DESCRIPTION 17324 17325=item B<->(B<no>)B<local_icons> 17326 17327Set this if you want to copy the navigation icons to each document directory 17328so that the document directory is self-contained and can be dropped into 17329another server tree without further actions. 17330 17331=item B<->(B<no>)B<scalable_fonts> 17332 17333MISSING_DESCRIPTION 17334 17335=item B<->(B<no>)B<images_only> 17336 17337When true, B<LaTeX2HTML> will only try to convert the inlined images in the 17338file F<images.tex> which should have been generated automatically during 17339previous runs. This is very useful for correcting "bad LaTeX" in this file. 17340 17341=item B<->(B<no>)B<show_section_numbers> 17342 17343When this is set true, the section numbers are shown. The section numbers 17344should then match those that would have been produced by LaTeX. 17345The correct section numbers are obtained from the $FILE.aux file generated 17346by LaTeX. 17347Hiding the section numbers encourages use of particular sections 17348as standalone documents. In this case the cross reference to a section 17349is shown using the default symbol rather than the section number. 17350 17351=item B<->(B<no>)B<show_init> 17352 17353MISSING_DESCRIPTION 17354 17355=item B<-init_file> I<Perl_file> 17356 17357MISSING_DESCRIPTION 17358 17359=item B<-up_url> I<up_URL>, B<-up_title> I<up_title> 17360 17361=item B<-down_url> I<down_URL>, B<-down_title> I<down_title> 17362 17363=item B<-prev_url> I<prev_URL>, B<-prev_title> I<prev_title> 17364 17365=item B<-index> I<index_URL>, 17366 17367=item B<-contents> I<toc_URL> 17368 17369=item B<-biblio> I<biblio_URL> 17370 17371If both of the listed two options are set then the "Up" ("Previous" etc.) 17372button of the navigation panel in the first node/page of a converted 17373document will point to I<up_URL> etc. I<up_title> should be set 17374to some text which describes this external link. 17375Similarly you might use these options to link external documents 17376to your navigation panel. 17377 17378=item B<-external_file> I<external_aux_file> 17379 17380MISSING_DESCRIPTION 17381 17382=item B<->(B<no>)B<short_index> 17383 17384If this is set then B<makeidx.perl> will construct codified names 17385for the text of index references. 17386 17387=item B<->(B<no>)B<unsegment> 17388 17389Use this to translate a segmented document as if it were not 17390segmented. 17391 17392=item B<->(B<no>)B<debug> 17393 17394If this is set then intermediate files are left for later inspection and 17395a lot of diagnostic output is produced. This output may be useful when 17396searching for problems and/or submitting bug reports to the developers. 17397Temporary files include F<$$_images.tex> and F<$$_images.log> created during 17398image conversion. Caution: Intermediate files can be I<enormous>! 17399 17400=item B<-tmp> I<path> 17401 17402Path 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>. 17403 17404=item B<->(B<no>)B<ldump> 17405 17406This will cause LaTeX2HTML to produce a LaTeX dump of images.tex which is read 17407in on subsequent runs and speeds up startup time of LaTeX on the images.tex 17408translation. This actually consumes additional time on the first run, but pays 17409off on subsequent runs. The dump file will need about 1 Meg of disk space. 17410 17411=item B<->(B<no>)B<timing> 17412 17413MISSING_DESCRIPTION 17414 17415=item B<-verbosity> I<num> 17416 17417The amount of message information printed to the screen during processing 17418by B<LaTeX2HTML> is controlled by this setting. 17419By increasing this value, more information is displayed. 17420Here is the type of extra information that is shown at each level: 17421 17422 0 no extra information 17423 1 section types and titles 17424 2 environment 17425 3 command names 17426 4 links, labels and internal sectioning codes 17427 17428=item B<-html_version> I<list> 17429 17430Which HTML version should be generated. Currently available are: 17431C<2.0>, C<3.0>, C<3.2>, C<4.0>. Some additional options that may be 17432added are: C<math> (parse mathematics), C<i18n> (?), 17433C<table> (generate tables), C<frame> (generate frames), 17434C<latin1>...C<latin9> (use ISO-Latin-x encoding), 17435C<unicode> (generate unicode characters). Separate the options with ',', 17436e.g. C<4.0,math,frame>. 17437 17438=item B<->(B<no>)B<strict> 17439 17440MISSING_DESCRIPTION 17441 17442=back 17443 17444=head1 FILES 17445 17446=over 4 17447 17448=item F<$LATEX2HTMLPLATDIR/l2hconf.pm> 17449 17450This file holds the global defaults and configuration settings for 17451B<LaTeX2HTML>. 17452 17453=item F<$HOME/.latex2html-init> 17454 17455=item F<./.latex2html-init> 17456 17457These files may contain settings that override the global defaults, just 17458like specifying command line switches. 17459 17460=back 17461 17462=head1 ENVIRONMENT 17463 17464=over 4 17465 17466=item LATEX2HTMLDIR 17467 17468Path where LaTeX2HTML library files are found. On this installation 17469LATEX2HTMLDIR is F</home/bsbuild/dev/org-release/bacula-docs-11.0.5/latex2html> 17470 17471=item PERL5LIB 17472 17473Set by the B<latex2html> program to find perl modules. 17474 17475=item L2HCONFIG 17476 17477An alternative configuration filename. The standard configuration file 17478is F<$LATEX2HTMLPLATDIR/l2hconf.pm>. You may specify a sole filename (searched 17479for in F<$LATEX2HTMLPLATDIR> (and F<$PERL5LIB>) or a complete path. 17480 17481=item L2HINIT_NAME 17482 17483The standard user-specific configuration filename is F<.latex2html-init>. 17484This environment variable will override this name. 17485 17486=item HOME 17487 17488Evaluated if the system does not know about "home" directories (like 17489DOS, WinXX, OS/2, ...) to determine the path to F<$L2HINIT_NAME>. 17490 17491=item TEXE_DONT_INCLUDE, TEXE_DO_INCLUDE 17492 17493Used internally for communication with B<texexpand>. 17494 17495=item TEXINPUTS 17496 17497Used to find TeX includes of all sorts. 17498 17499=back 17500 17501=head1 PROBLEMS 17502 17503For information on various problems and remedies see the WWW online 17504documentation or the documents available in the distribution. 17505An online bug reporting form and various archives are available at 17506F<http://www.latex2html.org/> 17507 17508There is a mailing list for discussing B<LaTeX2HTML>: C<latex2html@tug.org> 17509 17510=head1 AUTHOR 17511 17512Nikos Drakos, Computer Based Learning Unit, University of Leeds 17513E<lt>nikos@cbl.leeds.ac.ukE<gt>. Several people have contributed 17514suggestions, ideas, solutions, support and encouragement. 17515 17516The B<pstoimg> script was written by Marek Rouchal 17517E<lt>marek@saftsack.fs.uni-bayreuth.deE<gt> 17518as a generalisation of the B<pstogif> utility to allow graphic formats 17519other than GIF to be created. Various options and enhancements have 17520been added by Ross Moore. 17521Some of the code is based upon the pstoppm.ps postscript program 17522originally written by Phillip Conrad (Perfect Byte, Inc.) 17523and modified by L. Peter Deutsch (Aladdin Enterprises). 17524 17525=head1 SEE ALSO 17526 17527See the WWW online documentation or the F<$LATEX2HTMLDIR/doc/manual.ps> 17528file for more detailed information and examples. 17529 17530L<pstoing>, L<texexpand> 17531 17532=cut 17533 17534