1#! /usr/bin/perl 2'di '; 3'ig 00 '; 4#+############################################################################## 5# 6# texi2html: Program to transform Texinfo documents to HTML 7# 8# Copyright (C) 1999, 2000 Free Software Foundation, Inc. 9# 10# This program is free software; you can redistribute it and/or modify 11# it under the terms of the GNU General Public License as published by 12# the Free Software Foundation; either version 2 of the License, or 13# (at your option) any later version. 14# 15# This program is distributed in the hope that it will be useful, 16# but WITHOUT ANY WARRANTY; without even the implied warranty of 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18# GNU General Public License for more details. 19# 20# You should have received a copy of the GNU General Public License 21# along with this program; if not, write to the Free Software 22# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23# 24#-############################################################################## 25 26# This requires perl version 5 or higher 27require 5.0; 28 29#++############################################################################## 30# 31# NOTE FOR DEBUGGING THIS SCRIPT: 32# You can run 'perl texi2html.pl' directly, provided you have 33# the environment variable T2H_HOME set to the directory containing 34# the texi2html.init file 35# 36#--############################################################################## 37 38# CVS version: 39# $Id: texi2html.pl,v 1.55 2000/07/27 14:39:41 obachman Exp $ 40 41# Homepage: 42$T2H_HOMEPAGE = <<EOT; 43http://www.mathematik.uni-kl.de/~obachman/Texi2html 44EOT 45 46# Authors: 47$T2H_AUTHORS = <<EOT; 48Written by: Lionel Cons <Lionel.Cons\@cern.ch> (original author) 49 Karl Berry <karl\@freefriends.org> 50 Olaf Bachmann <obachman\@mathematik.uni-kl.de> 51 and many others. 52Maintained by: Olaf Bachmann <obachman\@mathematik.uni-kl.de> 53Send bugs and suggestions to <texi2html\@mathematik.uni-kl.de> 54EOT 55 56# Version: set in configure.in 57$THISVERSION = '1.64'; 58$THISPROG = "texi2html $THISVERSION"; # program name and version 59 60# The man page for this program is included at the end of this file and can be 61# viewed using the command 'nroff -man texi2html'. 62 63# Identity: 64 65$T2H_TODAY = &pretty_date; # like "20 September 1993" 66# the eval prevents this from breaking on system which do not have 67# a proper getpwuid implemented 68eval { ($T2H_USER = (getpwuid ($<))[6]) =~ s/,.*//;}; # Who am i 69 70#+++############################################################################ 71# # 72# Initialization # 73# Pasted content of File $(srcdir)/texi2html.init: Default initializations # 74# # 75#---############################################################################ 76 77# leave this within comments, and keep the require statement 78# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init 79# exists. 80 81# 82# -*-perl-*- 83###################################################################### 84# File: texi2html.init 85# 86# Sets default values for command-line arguments and for various customizable 87# procedures 88# 89# A copy of this file is pasted into the beginning of texi2html by 90# 'make texi2html' 91# 92# Copy this file and make changes to it, if you like. 93# Afterwards, either, load it with command-line option -init_file <your_init_file> 94# 95# $Id: texi2html.init,v 1.34 2000/07/27 14:09:02 obachman Exp $ 96 97###################################################################### 98# stuff which can also be set by command-line options 99# 100# 101# Note: values set here, overwrite values set by the command-line 102# options before -init_file and might still be overwritten by 103# command-line arguments following the -init_file option 104# 105 106# T2H_OPTIONS is a hash whose keys are the (long) names of valid 107# command-line options and whose values are a hash with the following keys: 108# type ==> one of !|=i|:i|=s|:s (see GetOpt::Long for more info) 109# linkage ==> ref to scalar, array, or subroutine (see GetOpt::Long for more info) 110# verbose ==> short description of option (displayed by -h) 111# noHelp ==> if 1 -> for "not so important options": only print description on -h 1 112# 2 -> for obsolete options: only print description on -h 2 113 114$T2H_DEBUG = 0; 115$T2H_OPTIONS -> {debug} = 116{ 117 type => '=i', 118 linkage => \$main::T2H_DEBUG, 119 verbose => 'output HTML with debuging information', 120}; 121 122$T2H_DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'; 123$T2H_OPTIONS -> {doctype} = 124{ 125 type => '=s', 126 linkage => \$main::T2H_DOCTYPE, 127 verbose => 'document type which is output in header of HTML files', 128 noHelp => 1 129}; 130 131$T2H_CHECK = 0; 132$T2H_OPTIONS -> {check} = 133{ 134 type => '!', 135 linkage => \$main::T2H_CHECK, 136 verbose => 'if set, only check files and output all things that may be Texinfo commands', 137 noHelp => 1 138}; 139 140# -expand 141# if set to "tex" (or, "info") expand @iftex and @tex (or, @ifinfo) sections 142# else, neither expand @iftex, @tex, nor @ifinfo sections 143$T2H_EXPAND = "info"; 144$T2H_OPTIONS -> {expand} = 145{ 146 type => '=s', 147 linkage => \$T2H_EXPAND, 148 verbose => 'Expand info|tex|none section of texinfo source', 149}; 150 151# - glossary 152#if set, uses section named `Footnotes' for glossary 153$T2H_USE_GLOSSARY = 0; 154T2H_OPTIONS -> {glossary} = 155{ 156 type => '!', 157 linkage => \$T2H_USE_GLOSSARY, 158 verbose => "if set, uses section named `Footnotes' for glossary", 159 noHelp => 1, 160}; 161 162 163# -invisible 164# $T2H_INVISIBLE_MARK is the text used to create invisible destination 165# anchors for index links (you can for instance use the invisible.xbm 166# file shipped with this program). This is a workaround for a known 167# bug of many WWW browsers, including netscape. 168# For me, it works fine without it -- on the contrary: if there, it 169# inserts space between headers and start of text (obachman 3/99) 170$T2H_INVISIBLE_MARK = ''; 171# $T2H_INVISIBLE_MARK = ' '; 172$T2H_OPTIONS -> {invisible} = 173{ 174 type => '=s', 175 linkage => \$T2H_INVISIBLE_MARK, 176 verbose => 'use text in invisble anchot', 177 noHelp => 1, 178}; 179 180# -iso 181# if set, ISO8879 characters are used for special symbols (like copyright, etc) 182$T2H_USE_ISO = 0; 183$T2H_OPTIONS -> {iso} = 184{ 185 type => 'iso', 186 linkage => \$T2H_USE_ISO, 187 verbose => 'if set, ISO8879 characters are used for special symbols (like copyright, etc)', 188 noHelp => 1, 189}; 190 191# -I 192# list directories where @include files are searched for (besides the 193# directory of the doc file) additional '-I' args add to this list 194@T2H_INCLUDE_DIRS = ("."); 195$T2H_OPTIONS -> {I} = 196{ 197 type => '=s', 198 linkage => \@T2H_INCLUDE_DIRS, 199 verbose => 'append $s to the @include search path', 200}; 201 202# -top_file 203# uses file of this name for top-level file 204# extension is manipulated appropriately, if necessary. 205# If empty, <basename of document>.html is used 206# Typically, you would set this to "index.html". 207$T2H_TOP_FILE = ''; 208$T2H_OPTIONS -> {top_file} = 209{ 210 type => '=s', 211 linkage => \$T2H_TOP_FILE, 212 verbose => 'use $s as top file, instead of <docname>.html', 213}; 214 215 216# -toc_file 217# uses file of this name for table of contents file 218# extension is manipulated appropriately, if necessary. 219# If empty, <basename of document>_toc.html is used 220$T2H_TOC_FILE = ''; 221$T2H_OPTIONS -> {toc_file} = 222{ 223 type => '=s', 224 linkage => \$T2H_TOC_FILE, 225 verbose => 'use $s as ToC file, instead of <docname>_toc.html', 226}; 227 228# -frames 229# if set, output two additional files which use HTML 4.0 "frames". 230$T2H_FRAMES = 0; 231$T2H_OPTIONS -> {frames} = 232{ 233 type => '!', 234 linkage => \$T2H_FRAMES, 235 verbose => 'output files which use HTML 4.0 frames (experimental)', 236 noHelp => 1, 237}; 238 239 240# -menu | -nomenu 241# if set, show the Texinfo menus 242$T2H_SHOW_MENU = 1; 243$T2H_OPTIONS -> {menu} = 244{ 245 type => '!', 246 linkage => \$T2H_SHOW_MENU, 247 verbose => 'ouput Texinfo menus', 248}; 249 250# -number | -nonumber 251# if set, number sections and show section names and numbers in references 252# and menus 253$T2H_NUMBER_SECTIONS = 1; 254$T2H_OPTIONS -> {number} = 255{ 256 type => '!', 257 linkage => \$T2H_NUMBER_SECTIONS, 258 verbose => 'use numbered sections' 259}; 260 261# if set, and T2H_NUMBER_SECTIONS is set, then use node names in menu 262# entries, instead of section names 263$T2H_NODE_NAME_IN_MENU = 0; 264 265# if set and menu entry equals menu descr, then do not print menu descr. 266# Likewise, if node name equals entry name, do not print entry name. 267$T2H_AVOID_MENU_REDUNDANCY = 1; 268 269# -split section|chapter|none 270# if set to 'section' (resp. 'chapter') create one html file per (sub)section 271# (resp. chapter) and separate pages for Top, ToC, Overview, Index, 272# Glossary, About. 273# otherwise, create monolithic html file which contains whole document 274#$T2H_SPLIT = 'section'; 275$T2H_SPLIT = ''; 276$T2H_OPTIONS -> {split} = 277{ 278 type => '=s', 279 linkage => \$T2H_SPLIT, 280 verbose => 'split document on section|chapter else no splitting', 281}; 282 283# -section_navigation|-no-section_navigation 284# if set, then navigation panels are printed at the beginning of each section 285# and, possibly at the end (depending on whether or not there were more than 286# $T2H_WORDS_IN_PAGE words on page 287# This is most useful if you do not want to have section navigation 288# on -split chapter 289$T2H_SECTION_NAVIGATION = 1; 290$T2H_OPTIONS -> {sec_nav} = 291{ 292 type => '!', 293 linkage => \$T2H_SECTION_NAVIGATION, 294 verbose => 'output navigation panels for each section', 295}; 296 297# -subdir 298# if set put result files in this directory 299# if not set result files are put into current directory 300#$T2H_SUBDIR = 'html'; 301$T2H_SUBDIR = ''; 302$T2H_OPTIONS -> {subdir} = 303{ 304 type => '=s', 305 linkage => \$T2H_SUBDIR, 306 verbose => 'put HTML files in directory $s, instead of $cwd', 307}; 308 309# -short_extn 310# If this is set all HTML file will have extension ".htm" instead of 311# ".html". This is helpful when shipping the document to PC systems. 312$T2H_SHORTEXTN = 0; 313$T2H_OPTIONS -> {short_ext} = 314{ 315 type => '!', 316 linkage => \$T2H_SHORTEXTN, 317 verbose => 'use "htm" extension for output HTML files', 318}; 319 320 321# -prefix 322# Set the output file prefix, prepended to all .html, .gif and .pl files. 323# By default, this is the basename of the document 324$T2H_PREFIX = ''; 325$T2H_OPTIONS -> {prefix} = 326{ 327 type => '=s', 328 linkage => \$T2H_PREFIX, 329 verbose => 'use as prefix for output files, instead of <docname>', 330}; 331 332# -o filename 333# If set, generate monolithic document output html into $filename 334$T2H_OUT = ''; 335$T2H_OPTIONS -> {out_file} = 336{ 337 type => '=s', 338 linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';}, 339 verbose => 'if set, all HTML output goes into file $s', 340}; 341 342# -short_ref 343#if set cross-references are given without section numbers 344$T2H_SHORT_REF = ''; 345$T2H_OPTIONS -> {short_ref} = 346{ 347 type => '!', 348 linkage => \$T2H_SHORT_REF, 349 verbose => 'if set, references are without section numbers', 350}; 351 352# -idx_sum 353# if value is set, then for each @prinindex $what 354# $docu_name_$what.idx is created which contains lines of the form 355# $key\t$ref sorted alphabetically (case matters) 356$T2H_IDX_SUMMARY = 0; 357$T2H_OPTIONS -> {idx_sum} = 358{ 359 type => '!', 360 linkage => \$T2H_IDX_SUMMARY, 361 verbose => 'if set, also output index summary', 362 noHelp => 1, 363}; 364 365# -verbose 366# if set, chatter about what we are doing 367$T2H_VERBOSE = ''; 368$T2H_OPTIONS -> {Verbose} = 369{ 370 type => '!', 371 linkage => \$T2H_VERBOSE, 372 verbose => 'print progress info to stdout', 373}; 374 375# -lang 376# For page titles use $T2H_WORDS->{$T2H_LANG}->{...} as title. 377# To add a new language, supply list of titles (see $T2H_WORDS below). 378# and use ISO 639 language codes (see e.g. perl module Locale-Codes-1.02 379# for definitions) 380# Default's to 'en' if not set or no @documentlanguage is specified 381$T2H_LANG = ''; 382$T2H_OPTIONS -> {lang} = 383{ 384 type => '=s', 385 linkage => sub {SetDocumentLanguage($_[1])}, 386 verbose => 'use $s as document language (ISO 639 encoding)', 387}; 388 389# -l2h 390# if set, uses latex2html for generation of math content 391$T2H_L2H = ''; 392$T2H_OPTIONS -> {l2h} = 393{ 394 type => '!', 395 linkage => \$T2H_L2H, 396 verbose => 'if set, uses latex2html for @math and @tex', 397}; 398 399###################### 400# The following options are only relevant if $T2H_L2H is set 401# 402# -l2h_l2h 403# name/location of latex2html progam 404$T2H_L2H_L2H = "latex2html"; 405$T2H_OPTIONS -> {l2h_l2h} = 406{ 407 type => '=s', 408 linkage => \$T2H_L2H_L2H, 409 verbose => 'program to use for latex2html translation', 410 noHelp => 1, 411}; 412 413# -l2h_skip 414# if set, skips actual call to latex2html tries to reuse previously generated 415# content, instead 416$T2H_L2H_SKIP = ''; 417$T2H_OPTIONS -> {l2h_skip} = 418{ 419 type => '!', 420 linkage => \$T2H_L2H_SKIP, 421 verbose => 'if set, tries to reuse previously latex2html output', 422 noHelp => 1, 423}; 424 425# -l2h_tmp 426# if set, l2h uses this directory for temporarary files. The path 427# leading to this directory may not contain a dot (i.e., a "."), 428# otherwise, l2h will fail 429$T2H_L2H_TMP = ''; 430$T2H_OPTIONS -> {l2h_tmp} = 431{ 432 type => '=s', 433 linkage => \$T2H_L2H_TMP, 434 verbose => 'if set, uses $s as temporary latex2html directory', 435 noHelp => 1, 436}; 437 438# if set, cleans intermediate files (they all have the prefix $doc_l2h_) 439# of l2h 440$T2H_L2H_CLEAN = 1; 441$T2H_OPTIONS -> {l2h_clean} = 442{ 443 type => '!', 444 linkage => \$T2H_L2H_CLEAN, 445 verbose => 'if set, do not keep intermediate latex2html files for later reuse', 446 noHelp => 1, 447}; 448 449$T2H_OPTIONS -> {D} = 450{ 451 type => '=s', 452 linkage => sub {$main::value{@_[1]} = 1;}, 453 verbose => 'equivalent to Texinfo "@set $s 1"', 454 noHelp => 1, 455}; 456 457$T2H_OPTIONS -> {init_file} = 458{ 459 type => '=s', 460 linkage => \&LoadInitFile, 461 verbose => 'load init file $s' 462}; 463 464 465############################################################################## 466# 467# The following can only be set in the init file 468# 469############################################################################## 470 471# if set, center @image by default 472# otherwise, do not center by default 473$T2H_CENTER_IMAGE = 1; 474 475# used as identation for block enclosing command @example, etc 476# If not empty, must be enclosed in <td></td> 477$T2H_EXAMPLE_INDENT_CELL = '<td> </td>'; 478# same as above, only for @small 479$T2H_SMALL_EXAMPLE_INDENT_CELL = '<td> </td>'; 480# font size for @small 481$T2H_SMALL_FONT_SIZE = '-1'; 482 483# if non-empty, and no @..heading appeared in Top node, then 484# use this as header for top node/section, otherwise use value of 485# @settitle or @shorttitle (in that order) 486$T2H_TOP_HEADING = ''; 487 488# if set, use this chapter for 'Index' button, else 489# use first chapter whose name matches 'index' (case insensitive) 490$T2H_INDEX_CHAPTER = ''; 491 492# if set and $T2H_SPLIT is set, then split index pages at the next letter 493# after they have more than that many entries 494$T2H_SPLIT_INDEX = 100; 495 496# if set (e.g., to index.html) replace hrefs to this file 497# (i.e., to index.html) by ./ 498$T2H_HREF_DIR_INSTEAD_FILE = ''; 499 500######################################################################## 501# Language dependencies: 502# To add a new language extend T2H_WORDS hash and create $T2H_<...>_WORDS hash 503# To redefine one word, simply do: 504# $T2H_WORDS->{<language>}->{<word>} = 'whatever' in your personal init file. 505# 506$T2H_WORDS_EN = 507{ 508 # titles of pages 509 'ToC_Title' => 'Table of Contents', 510 'Overview_Title' => 'Short Table of Contents', 511 'Index_Title' => 'Index', 512 'About_Title' => 'About this document', 513 'Footnotes_Title' => 'Footnotes', 514 'See' => 'See', 515 'see' => 'see', 516 'section' => 'section', 517# If necessary, we could extend this as follows: 518# # text for buttons 519# 'Top_Button' => 'Top', 520# 'ToC_Button' => 'Contents', 521# 'Overview_Button' => 'Overview', 522# 'Index_button' => 'Index', 523# 'Back_Button' => 'Back', 524# 'FastBack_Button' => 'FastBack', 525# 'Prev_Button' => 'Prev', 526# 'Up_Button' => 'Up', 527# 'Next_Button' => 'Next', 528# 'Forward_Button' =>'Forward', 529# 'FastWorward_Button' => 'FastForward', 530# 'First_Button' => 'First', 531# 'Last_Button' => 'Last', 532# 'About_Button' => 'About' 533}; 534 535$T2H_WORD_DE = 536{ 537 'ToC_Title' => 'Inhaltsverzeichniss', 538 'Overview_Title' => 'Kurzes Inhaltsverzeichniss', 539 'Index_Title' => 'Index', 540 'About_Title' => 'Über dieses Dokument', 541 'Footnotes_Title' => 'Fußnoten', 542 'See' => 'Siehe', 543 'see' => 'siehe', 544 'section' => 'Abschnitt', 545}; 546 547$T2H_WORD_NL = 548{ 549 'ToC_Title' => 'Inhoudsopgave', 550 'Overview_Title' => 'Korte inhoudsopgave', 551 'Index_Title' => 'Index', #Not sure ;-) 552 'About_Title' => 'No translation available!', #No translation available! 553 'Footnotes_Title' => 'No translation available!', #No translation available! 554 'See' => 'Zie', 555 'see' => 'zie', 556 'section' => 'sectie', 557}; 558 559$T2H_WORD_ES = 560{ 561 'ToC_Title' => 'índice General', 562 'Overview_Title' => 'Resumen del Contenido', 563 'Index_Title' => 'Index', #Not sure ;-) 564 'About_Title' => 'No translation available!', #No translation available! 565 'Footnotes_Title' => 'Fußnoten', 566 'See' => 'Véase', 567 'see' => 'véase', 568 'section' => 'sección', 569}; 570 571$T2H_WORD_NO = 572{ 573 'ToC_Title' => 'Innholdsfortegnelse', 574 'Overview_Title' => 'Kort innholdsfortegnelse', 575 'Index_Title' => 'Indeks', #Not sure ;-) 576 'About_Title' => 'No translation available!', #No translation available! 577 'Footnotes_Title' => 'No translation available!', 578 'See' => 'Se', 579 'see' => 'se', 580 'section' => 'avsnitt', 581}; 582 583$T2H_WORD_PT = 584{ 585 'ToC_Title' => 'Sumário', 586 'Overview_Title' => 'Breve Sumário', 587 'Index_Title' => 'Índice', #Not sure ;-) 588 'About_Title' => 'No translation available!', #No translation available! 589 'Footnotes_Title' => 'No translation available!', 590 'See' => 'Veja', 591 'see' => 'veja', 592 'section' => 'Seção', 593}; 594 595$T2H_WORDS = 596{ 597 'en' => $T2H_WORDS_EN, 598 'de' => $T2H_WORDS_DE, 599 'nl' => $T2H_WORDS_NL, 600 'es' => $T2H_WORDS_ES, 601 'no' => $T2H_WORDS_NO, 602 'pt' => $T2H_WORDS_PT 603}; 604 605@MONTH_NAMES_EN = 606( 607 'January', 'February', 'March', 'April', 'May', 608 'June', 'July', 'August', 'September', 'October', 609 'November', 'December' 610); 611 612@MONTH_NAMES_DE = 613( 614 'Januar', 'Februar', 'März', 'April', 'Mai', 615 'Juni', 'Juli', 'August', 'September', 'Oktober', 616 'November', 'Dezember' 617); 618 619@MONTH_NAMES_NL = 620( 621 'Januari', 'Februari', 'Maart', 'April', 'Mei', 622 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 623 'November', 'December' 624); 625 626@MONTH_NAMES_ES = 627( 628 'enero', 'febrero', 'marzo', 'abril', 'mayo', 629 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 630 'noviembre', 'diciembre' 631); 632 633@MONTH_NAMES_NO = 634( 635 636 'januar', 'februar', 'mars', 'april', 'mai', 637 'juni', 'juli', 'august', 'september', 'oktober', 638 'november', 'desember' 639); 640 641@MONTH_NAMES_PT = 642( 643 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 644 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 645 'Novembro', 'Dezembro' 646); 647 648 649$MONTH_NAMES = 650{ 651 'en' => \@MONTH_NAMES_EN, 652 'de' => \@MONTH_NAMES_DE, 653 'es' => \@MONTH_NAMES_ES, 654 'nl' => \@MONTH_NAMES_NL, 655 'no' => \@MONTH_NAMES_NO, 656 'pt' => \@MONTH_NAMES_PT 657}; 658######################################################################## 659# Control of Page layout: 660# You can make changes of the Page layout at two levels: 661# 1.) For small changes, it is often enough to change the value of 662# some global string/hash/array variables 663# 2.) For larger changes, reimplement one of the T2H_DEFAULT_<fnc>* routines, 664# give them another name, and assign them to the respective 665# $T2H_<fnc> variable. 666 667# As a general interface, the hashes T2H_HREF, T2H_NAME, T2H_NODE hold 668# href, html-name, node-name of 669# This -- current section (resp. html page) 670# Top -- top page ($T2H_TOP_FILE) 671# Contents -- Table of contents 672# Overview -- Short table of contents 673# Index -- Index page 674# About -- page which explain "navigation buttons" 675# First -- first node 676# Last -- last node 677# 678# Whether or not the following hash values are set, depends on the context 679# (all values are w.r.t. 'This' section) 680# Next -- next node of texinfo 681# Prev -- previous node of texinfo 682# Up -- up node of texinfo 683# Forward -- next node in reading order 684# Back -- previous node in reading order 685# FastForward -- if leave node, up and next, else next node 686# FastBackward-- if leave node, up and prev, else prev node 687# 688# Furthermore, the following global variabels are set: 689# $T2H_THISDOC{title} -- title as set by @setttile 690# $T2H_THISDOC{fulltitle} -- full title as set by @title... 691# $T2H_THISDOC{subtitle} -- subtitle as set by @subtitle 692# $T2H_THISDOC{author} -- author as set by @author 693# 694# and pointer to arrays of lines which need to be printed by t2h_print_lines 695# $T2H_OVERVIEW -- lines of short table of contents 696# $T2H_TOC -- lines of table of contents 697# $T2H_TOP -- lines of Top texinfo node 698# $T2H_THIS_SECTION -- lines of 'This' section 699 700# 701# There are the following subs which control the layout: 702# 703$T2H_print_section = \&T2H_DEFAULT_print_section; 704$T2H_print_Top_header = \&T2H_DEFAULT_print_Top_header; 705$T2H_print_Top_footer = \&T2H_DEFAULT_print_Top_footer; 706$T2H_print_Top = \&T2H_DEFAULT_print_Top; 707$T2H_print_Toc = \&T2H_DEFAULT_print_Toc; 708$T2H_print_Overview = \&T2H_DEFAULT_print_Overview; 709$T2H_print_Footnotes = \&T2H_DEFAULT_print_Footnotes; 710$T2H_print_About = \&T2H_DEFAULT_print_About; 711$T2H_print_misc_header = \&T2H_DEFAULT_print_misc_header; 712$T2H_print_misc_footer = \&T2H_DEFAULT_print_misc_footer; 713$T2H_print_misc = \&T2H_DEFAULT_print_misc; 714$T2H_print_chapter_header = \&T2H_DEFAULT_print_chapter_header; 715$T2H_print_chapter_footer = \&T2H_DEFAULT_print_chapter_footer; 716$T2H_print_page_head = \&T2H_DEFAULT_print_page_head; 717$T2H_print_page_foot = \&T2H_DEFAULT_print_page_foot; 718$T2H_print_head_navigation = \&T2H_DEFAULT_print_head_navigation; 719$T2H_print_foot_navigation = \&T2H_DEFAULT_print_foot_navigation; 720$T2H_button_icon_img = \&T2H_DEFAULT_button_icon_img; 721$T2H_print_navigation = \&T2H_DEFAULT_print_navigation; 722$T2H_about_body = \&T2H_DEFAULT_about_body; 723$T2H_print_frame = \&T2H_DEFAULT_print_frame; 724$T2H_print_toc_frame = \&T2H_DEFAULT_print_toc_frame; 725 726######################################################################## 727# Layout for html for every sections 728# 729sub T2H_DEFAULT_print_section 730{ 731 my $fh = shift; 732 local $T2H_BUTTONS = \@T2H_SECTION_BUTTONS; 733 &$T2H_print_head_navigation($fh) if $T2H_SECTION_NAVIGATION; 734 my $nw = t2h_print_lines($fh); 735 if ($T2H_SPLIT eq 'section' && $T2H_SECTION_NAVIGATION) 736 { 737 &$T2H_print_foot_navigation($fh, $nw); 738 } 739 else 740 { 741 print $fh '<HR SIZE="6">' . "\n"; 742 } 743} 744 745################################################################### 746# Layout of top-page I recommend that you use @ifnothtml, @ifhtml, 747# @html within the Top texinfo node to specify content of top-level 748# page. 749# 750# If you enclose everything in @ifnothtml, then title, subtitle, 751# author and overview is printed 752# T2H_HREF of Next, Prev, Up, Forward, Back are not defined 753# if $T2H_SPLIT then Top page is in its own html file 754sub T2H_DEFAULT_print_Top_header 755{ 756 &$T2H_print_page_head(@_) if $T2H_SPLIT; 757 t2h_print_label(@_); # this needs to be called, otherwise no label set 758 &$T2H_print_head_navigation(@_); 759} 760sub T2H_DEFAULT_print_Top_footer 761{ 762 &$T2H_print_foot_navigation(@_); 763 &$T2H_print_page_foot(@_) if $T2H_SPLIT; 764} 765sub T2H_DEFAULT_print_Top 766{ 767 my $fh = shift; 768 769 # for redefining navigation buttons use: 770 # local $T2H_BUTTONS = [...]; 771 # as it is, 'Top', 'Contents', 'Index', 'About' are printed 772 local $T2H_BUTTONS = \@T2H_MISC_BUTTONS; 773 &$T2H_print_Top_header($fh); 774 if ($T2H_THIS_SECTION) 775 { 776 # if top-level node has content, then print it with extra header 777 print $fh "<H1>$T2H_NAME{Top}</H1>" 778 unless ($T2H_HAS_TOP_HEADING); 779 t2h_print_lines($fh, $T2H_THIS_SECTION) 780 } 781 else 782 { 783 # top-level node is fully enclosed in @ifnothtml 784 # print fulltitle, subtitle, author, Overview 785 print $fh 786 "<CENTER>\n<H1>" . 787 join("</H1>\n<H1>", split(/\n/, $T2H_THISDOC{fulltitle})) . 788 "</H1>\n"; 789 print $fh "<H2>$T2H_THISDOC{subtitle}</H2>\n" if $T2H_THISDOC{subtitle}; 790 print $fh "$T2H_THISDOC{author}\n" if $T2H_THISDOC{author}; 791 print $fh <<EOT; 792</CENTER> 793<HR> 794<P></P> 795<H2> Overview: </H2> 796<BLOCKQUOTE> 797EOT 798 t2h_print_lines($fh, $T2H_OVERVIEW); 799 print $fh "</BLOCKQUOTE>\n"; 800 } 801 &$T2H_print_Top_footer($fh); 802} 803 804################################################################### 805# Layout of Toc, Overview, and Footnotes pages 806# By default, we use "normal" layout 807# T2H_HREF of Next, Prev, Up, Forward, Back, etc are not defined 808# use: local $T2H_BUTTONS = [...] to redefine navigation buttons 809sub T2H_DEFAULT_print_Toc 810{ 811 return &$T2H_print_misc(@_); 812} 813sub T2H_DEFAULT_print_Overview 814{ 815 return &$T2H_print_misc(@_); 816} 817sub T2H_DEFAULT_print_Footnotes 818{ 819 return &$T2H_print_misc(@_); 820} 821sub T2H_DEFAULT_print_About 822{ 823 return &$T2H_print_misc(@_); 824} 825 826sub T2H_DEFAULT_print_misc_header 827{ 828 &$T2H_print_page_head(@_) if $T2H_SPLIT; 829 # this needs to be called, otherwise, no labels are set 830 t2h_print_label(@_); 831 &$T2H_print_head_navigation(@_); 832} 833sub T2H_DEFAULT_print_misc_footer 834{ 835 &$T2H_print_foot_navigation(@_); 836 &$T2H_print_page_foot(@_) if $T2H_SPLIT; 837} 838sub T2H_DEFAULT_print_misc 839{ 840 my $fh = shift; 841 local $T2H_BUTTONS = \@T2H_MISC_BUTTONS; 842 &$T2H_print_misc_header($fh); 843 print $fh "<H1>$T2H_NAME{This}</H1>\n"; 844 t2h_print_lines($fh); 845 &$T2H_print_misc_footer($fh); 846} 847 848################################################################### 849# chapter_header and chapter_footer are only called if 850# T2H_SPLIT eq 'chapter' 851# chapter_header: after print_page_header, before print_section 852# chapter_footer: after print_section of last section, before print_page_footer 853# 854# If you want to get rid of navigation stuff after each section, 855# redefine print_section such that it does not call print_navigation, 856# and put print_navigation into print_chapter_header 857@T2H_CHAPTER_BUTTONS = 858 ( 859 'FastBack', 'FastForward', ' ', 860 ' ', ' ', ' ', ' ', 861 'Top', 'Contents', 'Index', 'About', 862 ); 863 864sub T2H_DEFAULT_print_chapter_header 865{ 866 # nothing to do there, by default 867 if (! $T2H_SECTION_NAVIGATION) 868 { 869 my $fh = shift; 870 local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS; 871 &$T2H_print_navigation($fh); 872 print $fh "\n<HR SIZE=2>\n"; 873 } 874} 875 876sub T2H_DEFAULT_print_chapter_footer 877{ 878 local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS; 879 &$T2H_print_navigation(@_); 880} 881################################################################### 882$T2H_TODAY = &pretty_date; # like "20 September 1993" 883 884sub pretty_date { 885 local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); 886 887 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); 888 $year += ($year < 70) ? 2000 : 1900; 889 # obachman: Let's do it as the Americans do 890 return($MONTH_NAMES->{$T2H_LANG}[$mon] . ", " . $mday . " " . $year); 891} 892 893 894################################################################### 895# Layout of standard header and footer 896# 897 898# Set the default body text, inserted between <BODY ... > 899###$T2H_BODYTEXT = 'LANG="EN" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"'; 900$T2H_BODYTEXT = 'LANG="' . $T2H_LANG . '" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"'; 901# text inserted after <BODY ...> 902$T2H_AFTER_BODY_OPEN = ''; 903#text inserted before </BODY> 904$T2H_PRE_BODY_CLOSE = ''; 905# this is used in footer 906$T2H_ADDRESS = "by <I>$T2H_USER</I> " if $T2H_USER; 907$T2H_ADDRESS .= "on <I>$T2H_TODAY</I>"; 908# this is added inside <HEAD></HEAD> after <TITLE> and some META NAME stuff 909# can be used for <style> <script>, <meta> tags 910$T2H_EXTRA_HEAD = ''; 911 912sub T2H_DEFAULT_print_page_head 913{ 914 my $fh = shift; 915 my $longtitle = "$T2H_THISDOC{title}: $T2H_NAME{This}"; 916 print $fh <<EOT; 917<HTML> 918$T2H_DOCTYPE 919<!-- Created on $T2H_TODAY by $THISPROG --> 920<!-- 921$T2H_AUTHORS 922--> 923<HEAD> 924<TITLE>$longtitle</TITLE> 925 926<META NAME="description" CONTENT="$longtitle"> 927<META NAME="keywords" CONTENT="$longtitle"> 928<META NAME="resource-type" CONTENT="document"> 929<META NAME="distribution" CONTENT="global"> 930<META NAME="Generator" CONTENT="$THISPROG"> 931$T2H_EXTRA_HEAD 932</HEAD> 933 934<BODY $T2H_BODYTEXT> 935$T2H_AFTER_BODY_OPEN 936EOT 937} 938 939sub T2H_DEFAULT_print_page_foot 940{ 941 my $fh = shift; 942 print $fh <<EOT; 943<BR> 944<FONT SIZE="-1"> 945This document was generated 946$T2H_ADDRESS 947using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A> 948$T2H_PRE_BODY_CLOSE 949</BODY> 950</HTML> 951EOT 952} 953 954################################################################### 955# Layout of navigation panel 956 957# if this is set, then a vertical navigation panel is used 958$T2H_VERTICAL_HEAD_NAVIGATION = 0; 959sub T2H_DEFAULT_print_head_navigation 960{ 961 my $fh = shift; 962 if ($T2H_VERTICAL_HEAD_NAVIGATION) 963 { 964 print $fh <<EOT; 965<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"> 966<TR VALIGN="TOP"> 967<TD ALIGN="LEFT"> 968EOT 969 } 970 &$T2H_print_navigation($fh, $T2H_VERTICAL_HEAD_NAVIGATION); 971 if ($T2H_VERTICAL_HEAD_NAVIGATION) 972 { 973 print $fh <<EOT; 974</TD> 975<TD ALIGN="LEFT"> 976EOT 977 } 978 elsif ($T2H_SPLIT eq 'section') 979 { 980 print $fh "<HR SIZE=1>\n"; 981 } 982} 983 984# Specifies the minimum page length required before a navigation panel 985# is placed at the bottom of a page (the default is that of latex2html) 986# T2H_THIS_WORDS_IN_PAGE holds number of words of current page 987$T2H_WORDS_IN_PAGE = 300; 988sub T2H_DEFAULT_print_foot_navigation 989{ 990 my $fh = shift; 991 my $nwords = shift; 992 if ($T2H_VERTICAL_HEAD_NAVIGATION) 993 { 994 print $fh <<EOT; 995</TD> 996</TR> 997</TABLE> 998EOT 999 } 1000 print $fh "<HR SIZE=1>\n"; 1001 &$T2H_print_navigation($fh) if ($nwords >= $T2H_WORDS_IN_PAGE) 1002} 1003 1004###################################################################### 1005# navigation panel 1006# 1007# specify in this array which "buttons" should appear in which order 1008# in the navigation panel for sections; use ' ' for empty buttons (space) 1009@T2H_SECTION_BUTTONS = 1010 ( 1011 'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward', 1012 ' ', ' ', ' ', ' ', 1013 'Top', 'Contents', 'Index', 'About', 1014 ); 1015 1016# buttons for misc stuff 1017@T2H_MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About'); 1018 1019# insert here name of icon images for buttons 1020# Icons are used, if $T2H_ICONS and resp. value are set 1021%T2H_ACTIVE_ICONS = 1022 ( 1023 'Top', '', 1024 'Contents', '', 1025 'Overview', '', 1026 'Index', '', 1027 'Back', '', 1028 'FastBack', '', 1029 'Prev', '', 1030 'Up', '', 1031 'Next', '', 1032 'Forward', '', 1033 'FastForward', '', 1034 'About' , '', 1035 'First', '', 1036 'Last', '', 1037 ' ', '' 1038 ); 1039 1040# insert here name of icon images for these, if button is inactive 1041%T2H_PASSIVE_ICONS = 1042 ( 1043 'Top', '', 1044 'Contents', '', 1045 'Overview', '', 1046 'Index', '', 1047 'Back', '', 1048 'FastBack', '', 1049 'Prev', '', 1050 'Up', '', 1051 'Next', '', 1052 'Forward', '', 1053 'FastForward', '', 1054 'About', '', 1055 'First', '', 1056 'Last', '', 1057 ); 1058 1059# how to create IMG tag 1060sub T2H_DEFAULT_button_icon_img 1061{ 1062 my $button = shift; 1063 my $icon = shift; 1064 my $name = shift; 1065 return qq{<IMG SRC="$icon" BORDER="0" ALT="$button: $name" ALIGN="MIDDLE">}; 1066} 1067 1068# Names of text as alternative for icons 1069%T2H_NAVIGATION_TEXT = 1070 ( 1071 'Top', 'Top', 1072 'Contents', 'Contents', 1073 'Overview', 'Overview', 1074 'Index', 'Index', 1075 ' ', ' ', 1076 'Back', ' < ', 1077 'FastBack', ' << ', 1078 'Prev', 'Prev', 1079 'Up', ' Up ', 1080 'Next', 'Next', 1081 'Forward', ' > ', 1082 'FastForward', ' >> ', 1083 'About', ' ? ', 1084 'First', ' |< ', 1085 'Last', ' >| ' 1086 ); 1087 1088sub T2H_DEFAULT_print_navigation 1089{ 1090 my $fh = shift; 1091 my $vertical = shift; 1092 my $spacing = 1; 1093 print $fh "<TABLE CELLPADDING=$spacing CELLSPACING=$spacing BORDER=0>\n"; 1094 1095 print $fh "<TR>" unless $vertical; 1096 for $button (@$T2H_BUTTONS) 1097 { 1098 print $fh qq{<TR VALIGN="TOP" ALIGN="LEFT">\n} if $vertical; 1099 print $fh qq{<TD VALIGN="MIDDLE" ALIGN="LEFT">}; 1100 1101 if (ref($button) eq 'CODE') 1102 { 1103 &$button($fh, $vertical); 1104 } 1105 elsif ($button eq ' ') 1106 { # handle space button 1107 print $fh 1108 $T2H_ICONS && $T2H_ACTIVE_ICONS{' '} ? 1109 &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{' '}) : 1110 $T2H_NAVIGATION_TEXT{' '}; 1111 next; 1112 } 1113 elsif ($T2H_HREF{$button}) 1114 { # button is active 1115 print $fh 1116 $T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? # use icon ? 1117 t2h_anchor('', $T2H_HREF{$button}, # yes 1118 &$T2H_button_icon_img($button, 1119 $T2H_ACTIVE_ICONS{$button}, 1120 $T2H_NAME{$button})) 1121 : # use text 1122 "[" . 1123 t2h_anchor('', $T2H_HREF{$button}, $T2H_NAVIGATION_TEXT{$button}) . 1124 "]"; 1125 } 1126 else 1127 { # button is passive 1128 print $fh 1129 $T2H_ICONS && $T2H_PASSIVE_ICONS{$button} ? 1130 &$T2H_button_icon_img($button, 1131 $T2H_PASSIVE_ICONS{$button}, 1132 $T2H_NAME{$button}) : 1133 1134 "[" . $T2H_NAVIGATION_TEXT{$button} . "]"; 1135 } 1136 print $fh "</TD>\n"; 1137 print $fh "</TR>\n" if $vertical; 1138 } 1139 print $fh "</TR>" unless $vertical; 1140 print $fh "</TABLE>\n"; 1141} 1142 1143###################################################################### 1144# Frames: this is from "Richard Y. Kim" <ryk@coho.net> 1145# Should be improved to be more conforming to other _print* functions 1146 1147sub T2H_DEFAULT_print_frame 1148{ 1149 my $fh = shift; 1150 print $fh <<EOT; 1151<HTML> 1152<HEAD><TITLE>$T2H_THISDOC{title}</TITLE></HEAD> 1153<FRAMESET cols="140,*"> 1154 <FRAME name=toc src="$docu_toc_frame_file"> 1155 <FRAME name=main src="$docu_doc"> 1156</FRAMESET> 1157</HTML> 1158EOT 1159} 1160 1161sub T2H_DEFAULT_print_toc_frame 1162{ 1163 my $fh = shift; 1164 &$T2H_print_page_head($fh); 1165 print $fh <<EOT; 1166<H2>Content</H2> 1167EOT 1168 print $fh map {s/HREF=/target=\"main\" HREF=/; $_;} @stoc_lines; 1169 print $fh "</BODY></HTML>\n"; 1170} 1171 1172###################################################################### 1173# About page 1174# 1175 1176# T2H_PRE_ABOUT might be a function 1177$T2H_PRE_ABOUT = <<EOT; 1178This document was generated $T2H_ADDRESS 1179using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A> 1180<P></P> 1181EOT 1182$T2H_AFTER_ABOUT = ''; 1183 1184sub T2H_DEFAULT_about_body 1185{ 1186 my $about; 1187 if (ref($T2H_PRE_ABOUT) eq 'CODE') 1188 { 1189 $about = &$T2H_PRE_ABOUT(); 1190 } 1191 else 1192 { 1193 $about = $T2H_PRE_ABOUT; 1194 } 1195 $about .= <<EOT; 1196The buttons in the navigation panels have the following meaning: 1197<P></P> 1198<table border = "1"> 1199<TR> 1200<TH> Button </TH> 1201<TH> Name </TH> 1202<TH> Go to </TH> 1203<TH> From 1.2.3 go to</TH> 1204</TR> 1205EOT 1206 1207 for $button (@T2H_SECTION_BUTTONS) 1208 { 1209 next if $button eq ' ' || ref($button) eq 'CODE'; 1210 $about .= <<EOT; 1211<TR> 1212<TD ALIGN="CENTER"> 1213EOT 1214 $about .= 1215 ($T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? 1216 &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{$button}) : 1217 " [" . $T2H_NAVIGATION_TEXT{$button} . "] "); 1218 $about .= <<EOT; 1219</TD> 1220<TD ALIGN="CENTER"> 1221$button 1222</TD> 1223<TD> 1224$T2H_BUTTONS_GOTO{$button} 1225</TD> 1226<TD> 1227$T2H_BUTTONS_EXAMPLE{$button} 1228</TD> 1229</TR> 1230EOT 1231 } 1232 1233 $about .= <<EOT; 1234</TABLE> 1235<P></P> 1236where the <STRONG> Example </STRONG> assumes that the current position 1237is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of 1238the following structure: 1239<UL> 1240<LI> 1. Section One </LI> 1241<UL> 1242<LI>1.1 Subsection One-One</LI> 1243<UL> 1244<LI> ... </LI> 1245</UL> 1246<LI>1.2 Subsection One-Two</LI> 1247<UL> 1248<LI>1.2.1 Subsubsection One-Two-One 1249</LI><LI>1.2.2 Subsubsection One-Two-Two 1250</LI><LI>1.2.3 Subsubsection One-Two-Three <STRONG> 1251<== Current Position </STRONG> 1252</LI><LI>1.2.4 Subsubsection One-Two-Four 1253</LI></UL> 1254<LI>1.3 Subsection One-Three</LI> 1255<UL> 1256<LI> ... </LI> 1257</UL> 1258<LI>1.4 Subsection One-Four</LI> 1259</UL> 1260</UL> 1261$T2H_AFTER_ABOUT 1262EOT 1263 return $about; 1264} 1265 1266 1267%T2H_BUTTONS_GOTO = 1268 ( 1269 'Top', 'cover (top) of document', 1270 'Contents', 'table of contents', 1271 'Overview', 'short table of contents', 1272 'Index', 'concept index', 1273 'Back', 'previous section in reading order', 1274 'FastBack', 'previous or up-and-previous section ', 1275 'Prev', 'previous section same level', 1276 'Up', 'up section', 1277 'Next', 'next section same level', 1278 'Forward', 'next section in reading order', 1279 'FastForward', 'next or up-and-next section', 1280 'About' , 'this page', 1281 'First', 'first section in reading order', 1282 'Last', 'last section in reading order', 1283 ); 1284 1285%T2H_BUTTONS_EXAMPLE = 1286( 1287 'Top', ' ', 1288 'Contents', ' ', 1289 'Overview', ' ', 1290 'Index', ' ', 1291 'Back', '1.2.2', 1292 'FastBack', '1.1', 1293 'Prev', '1.2.2', 1294 'Up', '1.2', 1295 'Next', '1.2.4', 1296 'Forward', '1.2.4', 1297 'FastForward', '1.3', 1298 'About', ' ', 1299 'First', '1.', 1300 'Last', '1.2.4', 1301); 1302 1303 1304###################################################################### 1305# from here on, its l2h init stuff 1306# 1307 1308## initialization for latex2html as for Singular manual generation 1309## obachman 3/99 1310 1311# 1312# Options controlling Titles, File-Names, Tracing and Sectioning 1313# 1314$TITLE = ''; 1315 1316$SHORTEXTN = 0; 1317 1318$LONG_TITLES = 0; 1319 1320$DESTDIR = ''; # should be overwritten by cmd-line argument 1321 1322$NO_SUBDIR = 0;# should be overwritten by cmd-line argument 1323 1324$PREFIX = ''; # should be overwritten by cmd-line argument 1325 1326$AUTO_PREFIX = 0; # this is needed, so that prefix settings are used 1327 1328$AUTO_LINK = 0; 1329 1330$SPLIT = 0; 1331 1332$MAX_LINK_DEPTH = 0; 1333 1334$TMP = ''; # should be overwritten by cmd-line argument 1335 1336$DEBUG = 0; 1337 1338$VERBOSE = 1; 1339 1340# 1341# Options controlling Extensions and Special Features 1342# 1343$HTML_VERSION = "3.2"; 1344 1345$TEXDEFS = 1; # we absolutely need that 1346 1347$EXTERNAL_FILE = ''; 1348 1349$SCALABLE_FONTS = 1; 1350 1351$NO_SIMPLE_MATH = 1; 1352 1353$LOCAL_ICONS = 1; 1354 1355$SHORT_INDEX = 0; 1356 1357$NO_FOOTNODE = 1; 1358 1359$ADDRESS = ''; 1360 1361$INFO = ''; 1362 1363# 1364# Switches controlling Image Generation 1365# 1366$ASCII_MODE = 0; 1367 1368$NOLATEX = 0; 1369 1370$EXTERNAL_IMAGES = 0; 1371 1372$PS_IMAGES = 0; 1373 1374$NO_IMAGES = 0; 1375 1376$IMAGES_ONLY = 0; 1377 1378$REUSE = 2; 1379 1380$ANTI_ALIAS = 1; 1381 1382$ANTI_ALIAS_TEXT = 1; 1383 1384# 1385#Switches controlling Navigation Panels 1386# 1387$NO_NAVIGATION = 1; 1388$ADDRESS = ''; 1389$INFO = 0; # 0 = do not make a "About this document..." section 1390 1391# 1392#Switches for Linking to other documents 1393# 1394# actuall -- we don't care 1395 1396$MAX_SPLIT_DEPTH = 0; # Stop making separate files at this depth 1397 1398$MAX_LINK_DEPTH = 0; # Stop showing child nodes at this depth 1399 1400$NOLATEX = 0; # 1 = do not pass unknown environments to Latex 1401 1402$EXTERNAL_IMAGES = 0; # 1 = leave the images outside the document 1403 1404$ASCII_MODE = 0; # 1 = do not use any icons or internal images 1405 1406# 1 = use links to external postscript images rather than inlined bitmap 1407# images. 1408$PS_IMAGES = 0; 1409$SHOW_SECTION_NUMBERS = 0; 1410 1411### Other global variables ############################################### 1412$CHILDLINE = ""; 1413 1414# This is the line width measured in pixels and it is used to right justify 1415# equations and equation arrays; 1416$LINE_WIDTH = 500; 1417 1418# Used in conjunction with AUTO_NAVIGATION 1419$WORDS_IN_PAGE = 300; 1420 1421# Affects ONLY the way accents are processed 1422$default_language = 'english'; 1423 1424# The value of this variable determines how many words to use in each 1425# title that is added to the navigation panel (see below) 1426# 1427$WORDS_IN_NAVIGATION_PANEL_TITLES = 0; 1428 1429# This number will determine the size of the equations, special characters, 1430# and anything which will be converted into an inlined image 1431# *except* "image generating environments" such as "figure", "table" 1432# or "minipage". 1433# Effective values are those greater than 0. 1434# Sensible values are between 0.1 - 4. 1435$MATH_SCALE_FACTOR = 1.5; 1436 1437# This number will determine the size of 1438# image generating environments such as "figure", "table" or "minipage". 1439# Effective values are those greater than 0. 1440# Sensible values are between 0.1 - 4. 1441$FIGURE_SCALE_FACTOR = 1.6; 1442 1443 1444# If both of the following two variables are set then the "Up" button 1445# of the navigation panel in the first node/page of a converted document 1446# will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set 1447# to some text which describes this external link. 1448$EXTERNAL_UP_LINK = ""; 1449$EXTERNAL_UP_TITLE = ""; 1450 1451# If this is set then the resulting HTML will look marginally better if viewed 1452# with Netscape. 1453$NETSCAPE_HTML = 1; 1454 1455# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0" 1456# Paper sizes has no effect other than in the time it takes to create inlined 1457# images and in whether large images can be created at all ie 1458# - larger paper sizes *MAY* help with large image problems 1459# - smaller paper sizes are quicker to handle 1460$PAPERSIZE = "a4"; 1461 1462# Replace "english" with another language in order to tell LaTeX2HTML that you 1463# want some generated section titles (eg "Table of Contents" or "References") 1464# to appear in a different language. Currently only "english" and "french" 1465# is supported but it is very easy to add your own. See the example in the 1466# file "latex2html.config" 1467$TITLES_LANGUAGE = "english"; 1468 14691; # This must be the last non-comment line 1470 1471# End File texi2html.init 1472###################################################################### 1473 1474 1475require "$ENV{T2H_HOME}/texi2html.init" 1476 if ($0 =~ /\.pl$/ && 1477 -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init"); 1478 1479#+++############################################################################ 1480# # 1481# Initialization # 1482# Pasted content of File $(srcdir)/MySimple.pm: Command-line processing # 1483# # 1484#---############################################################################ 1485 1486# leave this within comments, and keep the require statement 1487# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/texi2html.init 1488# exists. 1489 1490# 1491package Getopt::MySimple; 1492 1493# Name: 1494# Getopt::MySimple. 1495# 1496# Documentation: 1497# POD-style (incomplete) documentation is in file MySimple.pod 1498# 1499# Tabs: 1500# 4 spaces || die. 1501# 1502# Author: 1503# Ron Savage rpsavage@ozemail.com.au. 1504# 1.00 19-Aug-97 Initial version. 1505# 1.10 13-Oct-97 Add arrays of switches (eg '=s@'). 1506# 1.20 3-Dec-97 Add 'Help' on a per-switch basis. 1507# 1.30 11-Dec-97 Change 'Help' to 'verbose'. Make all hash keys lowercase. 1508# 1.40 10-Nov-98 Change width of help report. Restructure tests. 1509# 1-Jul-00 Modifications for Texi2html 1510 1511# -------------------------------------------------------------------------- 1512# Locally modified by obachman (Display type instead of env, order by cmp) 1513# $Id: MySimple.pm,v 1.1 2000/07/03 08:44:13 obachman Exp $ 1514 1515# use strict; 1516# no strict 'refs'; 1517 1518use vars qw(@EXPORT @EXPORT_OK @ISA); 1519use vars qw($fieldWidth $opt $VERSION); 1520 1521use Exporter(); 1522use Getopt::Long; 1523 1524@ISA = qw(Exporter); 1525@EXPORT = qw(); 1526@EXPORT_OK = qw($opt); # An alias for $self -> {'opt'}. 1527 1528# -------------------------------------------------------------------------- 1529 1530$fieldWidth = 20; 1531$VERSION = '1.41'; 1532 1533# -------------------------------------------------------------------------- 1534 1535sub byOrder 1536{ 1537 my($self) = @_; 1538 1539 return uc($a) cmp (uc($b)); 1540} 1541 1542# -------------------------------------------------------------------------- 1543 1544sub dumpOptions 1545{ 1546 my($self) = @_; 1547 1548 print 'Option', ' ' x ($fieldWidth - length('Option') ), "Value\n"; 1549 1550 for (sort byOrder keys(%{$self -> {'opt'} }) ) 1551 { 1552 print "-$_", ' ' x ($fieldWidth - (1 + length) ), "${$self->{'opt'} }{$_}\n"; 1553 } 1554 1555 print "\n"; 1556 1557} # End of dumpOptions. 1558 1559# -------------------------------------------------------------------------- 1560# Return: 1561# 0 -> Error. 1562# 1 -> Ok. 1563 1564sub getOptions 1565{ 1566 push(@_, 0) if ($#_ == 2); # Default for $ignoreCase is 0. 1567 push(@_, 1) if ($#_ == 3); # Default for $helpThenExit is 1. 1568 1569 my($self, $default, $helpText, $versionText, 1570 $helpThenExit, $versionThenExit, $ignoreCase) = @_; 1571 1572 $helpThenExit = 1 unless (defined($helpThenExit)); 1573 $versionThenExit = 1 unless (defined($versionThenExit)); 1574 $ignoreCase = 0 unless (defined($ignoreCase)); 1575 1576 $self -> {'default'} = $default; 1577 $self -> {'helpText'} = $helpText; 1578 $self -> {'versionText'} = $versionText; 1579 $Getopt::Long::ignorecase = $ignoreCase; 1580 1581 unless (defined($self -> {'default'}{'help'})) 1582 { 1583 $self -> {'default'}{'help'} = 1584 { 1585 type => ':i', 1586 default => '', 1587 linkage => sub {$self->helpOptions($_[1]); exit (0) if $helpThenExit;}, 1588 verbose => "print help and exit" 1589 }; 1590 } 1591 1592 unless (defined($self -> {'default'}{'version'})) 1593 { 1594 $self -> {'default'}{'version'} = 1595 { 1596 type => '', 1597 default => '', 1598 linkage => sub {print $self->{'versionText'}; exit (0) if versionTheExit;}, 1599 verbose => "print version and exit" 1600 }; 1601 } 1602 1603 for (keys(%{$self -> {'default'} }) ) 1604 { 1605 my $type = ${$self -> {'default'} }{$_}{'type'}; 1606 push(@{$self -> {'type'} }, "$_$type"); 1607 $self->{'opt'}->{$_} = ${$self -> {'default'} }{$_}{'linkage'} 1608 if ${$self -> {'default'} }{$_}{'linkage'}; 1609 } 1610 1611 my($result) = &GetOptions($self -> {'opt'}, @{$self -> {'type'} }); 1612 1613 return $result unless $result; 1614 1615 for (keys(%{$self -> {'default'} }) ) 1616 { 1617 if (! defined(${$self -> {'opt'} }{$_})) #{ 1618 { 1619 ${$self -> {'opt'} }{$_} = ${$self -> {'default'} }{$_}{'default'}; 1620 } 1621 } 1622 1623 $result; 1624} # End of getOptions. 1625 1626# -------------------------------------------------------------------------- 1627 1628sub helpOptions 1629{ 1630 my($self) = shift; 1631 my($noHelp) = shift; 1632 $noHelp = 0 unless $noHelp; 1633 my($optwidth, $typewidth, $defaultwidth, $maxlinewidth, $valind, $valwidth) 1634 = (10, 5, 9, 78, 4, 11); 1635 1636 print "$self->{'helpText'}" if ($self -> {'helpText'}); 1637 1638 print ' Option', ' ' x ($optwidth - length('Option') -1 ), 1639 'Type', ' ' x ($typewidth - length('Type') + 1), 1640 'Default', ' ' x ($defaultwidth - length('Default') ), 1641 "Description\n"; 1642 1643 for (sort byOrder keys(%{$self -> {'default'} }) ) 1644 { 1645 my($line, $help, $option, $val); 1646 $option = $_; 1647 next if ${$self->{'default'} }{$_}{'noHelp'} && ${$self->{'default'} }{$_}{'noHelp'} > $noHelp; 1648 $line = " -$_ " . ' ' x ($optwidth - (2 + length) ) . 1649 "${$self->{'default'} }{$_}{'type'} ". 1650 ' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) )); 1651 1652 $val = ${$self->{'default'} }{$_}{'linkage'}; 1653 if ($val) 1654 { 1655 if (ref($val) eq 'SCALAR') 1656 { 1657 $val = $$val; 1658 } 1659 else 1660 { 1661 $val = ''; 1662 } 1663 } 1664 else 1665 { 1666 $val = ${$self->{'default'} }{$_}{'default'}; 1667 } 1668 $line .= "$val "; 1669 $line .= ' ' x ($optwidth + $typewidth + $defaultwidth + 1 - length($line)); 1670 1671 if (defined(${$self -> {'default'} }{$_}{'verbose'}) && 1672 ${$self -> {'default'} }{$_}{'verbose'} ne '') 1673 { 1674 $help = "${$self->{'default'} }{$_}{'verbose'}"; 1675 } 1676 else 1677 { 1678 $help = ' '; 1679 } 1680 if ((length("$line") + length($help)) < $maxlinewidth) 1681 { 1682 print $line , $help, "\n"; 1683 } 1684 else 1685 { 1686 print $line, "\n", ' ' x $valind, $help, "\n"; 1687 } 1688 for $val (sort byOrder keys(%{${$self->{'default'}}{$option}{'values'}})) 1689 { 1690 print ' ' x ($valind + 2); 1691 print $val, ' ', ' ' x ($valwidth - length($val) - 2); 1692 print ${$self->{'default'}}{$option}{'values'}{$val}, "\n"; 1693 } 1694 } 1695 1696 print <<EOT; 1697Note: 'Options' may be abbreviated. 'Type' specifications mean: 1698 <none>| ! no argument: variable is set to 1 on -foo (or, to 0 on -nofoo) 1699 =s | :s mandatory (or, optional) string argument 1700 =i | :i mandatory (or, optional) integer argument 1701EOT 1702} # End of helpOptions. 1703 1704#------------------------------------------------------------------- 1705 1706sub new 1707{ 1708 my($class) = @_; 1709 my($self) = {}; 1710 $self -> {'default'} = {}; 1711 $self -> {'helpText'} = ''; 1712 $self -> {'opt'} = {}; 1713 $opt = $self -> {'opt'}; # An alias for $self -> {'opt'}. 1714 $self -> {'type'} = (); 1715 1716 return bless $self, $class; 1717 1718} # End of new. 1719 1720# -------------------------------------------------------------------------- 1721 17221; 1723 1724# End MySimple.pm 1725 1726require "$ENV{T2H_HOME}/MySimple.pm" 1727 if ($0 =~ /\.pl$/ && 1728 -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init"); 1729 1730package main; 1731 1732#+++############################################################################ 1733# # 1734# Constants # 1735# # 1736#---############################################################################ 1737 1738$DEBUG_TOC = 1; 1739$DEBUG_INDEX = 2; 1740$DEBUG_BIB = 4; 1741$DEBUG_GLOSS = 8; 1742$DEBUG_DEF = 16; 1743$DEBUG_HTML = 32; 1744$DEBUG_USER = 64; 1745$DEBUG_L2H = 128; 1746 1747 1748$BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference 1749$FILERE = '[\/\w.+-]+'; # RE for a file name 1750$VARRE = '[^\s\{\}]+'; # RE for a variable name 1751$NODERE = '[^,:]+'; # RE for a node name 1752$NODESRE = '[^:]+'; # RE for a list of node names 1753 1754$ERROR = "***"; # prefix for errors 1755$WARN = "**"; # prefix for warnings 1756 1757 # program home page 1758$PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections 1759 1760$CHAPTEREND = "<!-- End chapter -->\n"; # to know where a chpater ends 1761$SECTIONEND = "<!-- End section -->\n"; # to know where section ends 1762$TOPEND = "<!-- End top -->\n"; # to know where top ends 1763 1764 1765 1766# 1767# pre-defined indices 1768# 1769$index_properties = 1770{ 1771 'c' => { name => 'cp'}, 1772 'f' => { name => 'fn', code => 1}, 1773 'v' => { name => 'vr', code => 1}, 1774 'k' => { name => 'ky', code => 1}, 1775 'p' => { name => 'pg', code => 1}, 1776 't' => { name => 'tp', code => 1} 1777}; 1778 1779 1780%predefined_index = ( 1781 'cp', 'c', 1782 'fn', 'f', 1783 'vr', 'v', 1784 'ky', 'k', 1785 'pg', 'p', 1786 'tp', 't', 1787 ); 1788 1789# 1790# valid indices 1791# 1792%valid_index = ( 1793 'c', 1, 1794 'f', 1, 1795 'v', 1, 1796 'k', 1, 1797 'p', 1, 1798 't', 1, 1799 ); 1800 1801# 1802# texinfo section names to level 1803# 1804%sec2level = ( 1805 'top', 0, 1806 'chapter', 1, 1807 'unnumbered', 1, 1808 'majorheading', 1, 1809 'chapheading', 1, 1810 'appendix', 1, 1811 'section', 2, 1812 'unnumberedsec', 2, 1813 'heading', 2, 1814 'appendixsec', 2, 1815 'appendixsection', 2, 1816 'subsection', 3, 1817 'unnumberedsubsec', 3, 1818 'subheading', 3, 1819 'appendixsubsec', 3, 1820 'subsubsection', 4, 1821 'unnumberedsubsubsec', 4, 1822 'subsubheading', 4, 1823 'appendixsubsubsec', 4, 1824 ); 1825 1826# 1827# accent map, TeX command to ISO name 1828# 1829%accent_map = ( 1830 '"', 'uml', 1831 '~', 'tilde', 1832 '^', 'circ', 1833 '`', 'grave', 1834 '\'', 'acute', 1835 ); 1836 1837# 1838# texinfo "simple things" (@foo) to HTML ones 1839# 1840%simple_map = ( 1841 # cf. makeinfo.c 1842 "*", "<BR>", # HTML+ 1843 " ", " ", 1844 "\t", " ", 1845 "-", "­", # soft hyphen 1846 "\n", "\n", 1847 "|", "", 1848 'tab', '<\/TD><TD>', 1849 # spacing commands 1850 ":", "", 1851 "!", "!", 1852 "?", "?", 1853 ".", ".", 1854 "-", "", 1855 ); 1856 1857# 1858# texinfo "things" (@foo{}) to HTML ones 1859# 1860%things_map = ( 1861 'TeX', 'TeX', 1862 'br', '<P>', # paragraph break 1863 'bullet', '*', 1864 'copyright', '(C)', 1865 'dots', '<small>...<\/small>', 1866 'enddots', '<small>....<\/small>', 1867 'equiv', '==', 1868 'error', 'error-->', 1869 'expansion', '==>', 1870 'minus', '-', 1871 'point', '-!-', 1872 'print', '-|', 1873 'result', '=>', 1874 'today', $T2H_TODAY, 1875 'aa', 'å', 1876 'AA', 'Å', 1877 'ae', 'æ', 1878 'oe', 'œ', 1879 'AE', 'Æ', 1880 'OE', 'Œ', 1881 'o', 'ø', 1882 'O', 'Ø', 1883 'ss', 'ß', 1884 'l', '\/l', 1885 'L', '\/L', 1886 'exclamdown', '¡', 1887 'questiondown', '¿', 1888 'pounds', '£' 1889 ); 1890 1891# 1892# texinfo styles (@foo{bar}) to HTML ones 1893# 1894%style_map = ( 1895 'acronym', '&do_acronym', 1896 'asis', '', 1897 'b', 'B', 1898 'cite', 'CITE', 1899 'code', 'CODE', 1900 'command', 'CODE', 1901 'ctrl', '&do_ctrl', # special case 1902 'dfn', 'EM', # DFN tag is illegal in the standard 1903 'dmn', '', # useless 1904 'email', '&do_email', # insert a clickable email address 1905 'emph', 'EM', 1906 'env', 'CODE', 1907 'file', '"TT', # will put quotes, cf. &apply_style 1908 'i', 'I', 1909 'kbd', 'KBD', 1910 'key', 'KBD', 1911 'math', '&do_math', 1912 'option', '"SAMP', # will put quotes, cf. &apply_style 1913 'r', '', # unsupported 1914 'samp', '"SAMP', # will put quotes, cf. &apply_style 1915 'sc', '&do_sc', # special case 1916 'strong', 'STRONG', 1917 't', 'TT', 1918 'titlefont', '', # useless 1919 'uref', '&do_uref', # insert a clickable URL 1920 'url', '&do_url', # insert a clickable URL 1921 'var', 'VAR', 1922 'w', '', # unsupported 1923 'H', '&do_accent', 1924 'dotaccent', '&do_accent', 1925 'ringaccent','&do_accent', 1926 'tieaccent', '&do_accent', 1927 'u','&do_accent', 1928 'ubaraccent','&do_accent', 1929 'udotaccent','&do_accent', 1930 'v', '&do_accent', 1931 ',', '&do_accent', 1932 'dotless', '&do_accent' 1933 ); 1934 1935# 1936# texinfo format (@foo/@end foo) to HTML ones 1937# 1938%format_map = ( 1939 'quotation', 'BLOCKQUOTE', 1940 # lists 1941 'itemize', 'UL', 1942 'enumerate', 'OL', 1943 # poorly supported 1944 'flushleft', 'PRE', 1945 'flushright', 'PRE', 1946 ); 1947 1948# 1949# an eval of these $complex_format_map->{what}->[0] yields beginning 1950# an eval of these $complex_format_map->{what}->[1] yieleds end 1951$complex_format_map = 1952{ 1953 example => 1954 [ 1955 q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td class=example><pre>"}, 1956 q{'</pre></td></tr></table>'} 1957 ], 1958 smallexample => 1959 [ 1960 q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td class=smallexample><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre>"}, 1961 q{'</FONT></pre></td></tr></table>'} 1962 ], 1963 display => 1964 [ 1965 q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td class=display><pre " . 'style="font-family: serif">'}, 1966 q{'</pre></td></tr></table>'} 1967 ], 1968 smalldisplay => 1969 [ 1970 q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td class=smalldisplay><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre " . 'style="font-family: serif">'}, 1971 q{'</pre></FONT></td></tr></table>'} 1972 ] 1973}; 1974 1975$complex_format_map->{lisp} = $complex_format_map->{example}; 1976$complex_format_map->{smalllisp} = $complex_format_map->{smallexample}; 1977$complex_format_map->{format} = $complex_format_map->{display}; 1978$complex_format_map->{smallformat} = $complex_format_map->{smalldisplay}; 1979 1980# 1981# texinfo definition shortcuts to real ones 1982# 1983%def_map = ( 1984 # basic commands 1985 'deffn', 0, 1986 'defvr', 0, 1987 'deftypefn', 0, 1988 'deftypevr', 0, 1989 'defcv', 0, 1990 'defop', 0, 1991 'deftp', 0, 1992 # basic x commands 1993 'deffnx', 0, 1994 'defvrx', 0, 1995 'deftypefnx', 0, 1996 'deftypevrx', 0, 1997 'defcvx', 0, 1998 'defopx', 0, 1999 'deftpx', 0, 2000 # shortcuts 2001 'defun', 'deffn Function', 2002 'defmac', 'deffn Macro', 2003 'defspec', 'deffn {Special Form}', 2004 'defvar', 'defvr Variable', 2005 'defopt', 'defvr {User Option}', 2006 'deftypefun', 'deftypefn Function', 2007 'deftypevar', 'deftypevr Variable', 2008 'defivar', 'defcv {Instance Variable}', 2009 'deftypeivar', 'defcv {Instance Variable}', # NEW: FIXME 2010 'defmethod', 'defop Method', 2011 'deftypemethod', 'defop Method', # NEW:FIXME 2012 # x shortcuts 2013 'defunx', 'deffnx Function', 2014 'defmacx', 'deffnx Macro', 2015 'defspecx', 'deffnx {Special Form}', 2016 'defvarx', 'defvrx Variable', 2017 'defoptx', 'defvrx {User Option}', 2018 'deftypefunx', 'deftypefnx Function', 2019 'deftypevarx', 'deftypevrx Variable', 2020 'defivarx', 'defcvx {Instance Variable}', 2021 'defmethodx', 'defopx Method', 2022 ); 2023 2024# 2025# things to skip 2026# 2027%to_skip = ( 2028 # comments 2029 'c', 1, 2030 'comment', 1, 2031 'ifnotinfo', 1, 2032 'ifnottex', 1, 2033 'ifhtml', 1, 2034 'end ifhtml', 1, 2035 'end ifnotinfo', 1, 2036 'end ifnottex', 1, 2037 # useless 2038 'detailmenu', 1, 2039 'direntry', 1, 2040 'contents', 1, 2041 'shortcontents', 1, 2042 'summarycontents', 1, 2043 'footnotestyle', 1, 2044 'end ifclear', 1, 2045 'end ifset', 1, 2046 'titlepage', 1, 2047 'end titlepage', 1, 2048 # unsupported commands (formatting) 2049 'afourpaper', 1, 2050 'cropmarks', 1, 2051 'finalout', 1, 2052 'headings', 1, 2053 'sp', 1, 2054 'need', 1, 2055 'page', 1, 2056 'setchapternewpage', 1, 2057 'everyheading', 1, 2058 'everyfooting', 1, 2059 'evenheading', 1, 2060 'evenfooting', 1, 2061 'oddheading', 1, 2062 'oddfooting', 1, 2063 'smallbook', 1, 2064 'vskip', 1, 2065 'filbreak', 1, 2066 'paragraphindent', 1, 2067 # unsupported formats 2068 'cartouche', 1, 2069 'end cartouche', 1, 2070 'group', 1, 2071 'end group', 1, 2072 ); 2073 2074#+++############################################################################ 2075# # 2076# Argument parsing, initialisation # 2077# # 2078#---############################################################################ 2079 2080# 2081# flush stdout and stderr after every write 2082# 2083select(STDERR); 2084$| = 1; 2085select(STDOUT); 2086$| = 1; 2087 2088 2089%value = (); # hold texinfo variables, see also -D 2090$use_bibliography = 1; 2091$use_acc = 1; 2092 2093# 2094# called on -init-file 2095sub LoadInitFile 2096{ 2097 my $init_file = shift; 2098 # second argument is value of options 2099 $init_file = shift; 2100 if (-f $init_file) 2101 { 2102 print "# reading initialization file from $init_file\n" 2103 if ($T2H_VERBOSE); 2104 require($init_file); 2105 } 2106 else 2107 { 2108 print "$ERROR Error: can't read init file $int_file\n"; 2109 $init_file = ''; 2110 } 2111} 2112 2113# 2114# called on -lang 2115sub SetDocumentLanguage 2116{ 2117 my $lang = shift; 2118 if (! exists($T2H_WORDS->{$lang})) 2119 { 2120 warn "$ERROR: Language specs for '$lang' do not exists. Reverting to '" . 2121 ($T2H_LANG ? T2H_LANG : "en") . "'\n"; 2122 } 2123 else 2124 { 2125 print "# using '$lang' as document language\n" if ($T2H_VERBOSE); 2126 $T2H_LANG = $lang; 2127 } 2128} 2129 2130## 2131## obsolete cmd line options 2132## 2133$T2H_OBSOLETE_OPTIONS -> {'no-section_navigation'} = 2134{ 2135 type => '!', 2136 linkage => sub {$main::T2H_SECTION_NAVIGATION = 0;}, 2137 verbose => 'obsolete, use -nosec_nav', 2138 noHelp => 2, 2139}; 2140$T2H_OBSOLETE_OPTIONS -> {use_acc} = 2141{ 2142 type => '!', 2143 linkage => \$use_acc, 2144 verbose => 'obsolete', 2145 noHelp => 2 2146}; 2147$T2H_OBSOLETE_OPTIONS -> {expandinfo} = 2148{ 2149 type => '!', 2150 linkage => sub {$main::T2H_EXPAND = 'info';}, 2151 verbose => 'obsolete, use "-expand info" instead', 2152 noHelp => 2, 2153}; 2154$T2H_OBSOLETE_OPTIONS -> {expandtex} = 2155{ 2156 type => '!', 2157 linkage => sub {$main::T2H_EXPAND = 'tex';}, 2158 verbose => 'obsolete, use "-expand tex" instead', 2159 noHelp => 2, 2160}; 2161$T2H_OBSOLETE_OPTIONS -> {monolithic} = 2162{ 2163 type => '!', 2164 linkage => sub {$main::T2H_SPLIT = '';}, 2165 verbose => 'obsolete, use "-split no" instead', 2166 noHelp => 2 2167}; 2168$T2H_OBSOLETE_OPTIONS -> {split_node} = 2169{ 2170 type => '!', 2171 linkage => sub{$main::T2H_SPLIT = 'section';}, 2172 verbose => 'obsolete, use "-split section" instead', 2173 noHelp => 2, 2174}; 2175$T2H_OBSOLETE_OPTIONS -> {split_chapter} = 2176{ 2177 type => '!', 2178 linkage => sub{$main::T2H_SPLIT = 'chapter';}, 2179 verbose => 'obsolete, use "-split chapter" instead', 2180 noHelp => 2, 2181}; 2182$T2H_OBSOLETE_OPTIONS -> {no_verbose} = 2183{ 2184 type => '!', 2185 linkage => sub {$main::T2H_VERBOSE = 0;}, 2186 verbose => 'obsolete, use -noverbose instead', 2187 noHelp => 2, 2188}; 2189$T2H_OBSOLETE_OPTIONS -> {output_file} = 2190{ 2191 type => '=s', 2192 linkage => sub {$main::T2H_OUT = @_[1]; $T2H_SPLIT = '';}, 2193 verbose => 'obsolete, use -out_file instead', 2194 noHelp => 2 2195}; 2196 2197$T2H_OBSOLETE_OPTIONS -> {section_navigation} = 2198{ 2199 type => '!', 2200 linkage => \$T2H_SECTION_NAVIGATION, 2201 verbose => 'obsolete, use -sec_nav instead', 2202 noHelp => 2, 2203}; 2204 2205$T2H_OBSOLETE_OPTIONS -> {verbose} = 2206{ 2207 type => '!', 2208 linkage => \$T2H_VERBOSE, 2209 verbose => 'obsolete, use -Verbose instead', 2210 noHelp => 2 2211}; 2212 2213# read initialzation from $sysconfdir/texi2htmlrc or $HOME/.texi2htmlrc 2214my $home = $ENV{HOME}; 2215defined($home) or $home = ''; 2216foreach $i ('/usr/local/etc/texi2htmlrc', "$home/.texi2htmlrc") { 2217 if (-f $i) { 2218 print "# reading initialization file from $i\n" 2219 if ($T2H_VERBOSE); 2220 require($i); 2221 } 2222} 2223 2224 2225#+++############################################################################ 2226# # 2227# parse command-line options 2228# # 2229#---############################################################################ 2230$T2H_USAGE_TEXT = <<EOT; 2231Usage: texi2html [OPTIONS] TEXINFO-FILE 2232Translates Texinfo source documentation to HTML. 2233EOT 2234$T2H_FAILURE_TEXT = <<EOT; 2235Try 'texi2html -help' for usage instructions. 2236EOT 2237$options = new Getopt::MySimple; 2238 2239# some older version of GetOpt::Long don't have 2240# Getopt::Long::Configure("pass_through") 2241eval {Getopt::Long::Configure("pass_through");}; 2242$Configure_failed = $@ && <<EOT; 2243**WARNING: Parsing of obsolete command-line options could have failed. 2244 Consider to use only documented command-line options (run 2245 'texi2html -help 2' for a complete list) or upgrade to perl 2246 version 5.005 or higher. 2247EOT 2248 2249if (! $options->getOptions($T2H_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n")) 2250{ 2251 print $Configure_failed if $Configure_failed; 2252 die $T2H_FAILURE_TEXT; 2253} 2254 2255if (@ARGV > 1) 2256{ 2257 eval {Getopt::Long::Configure("no_pass_through");}; 2258 if (! $options->getOptions($T2H_OBSOLETE_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n")) 2259 { 2260 print $Configure_failed if $Configure_failed; 2261 die $T2H_FAILURE_TEXT; 2262 } 2263} 2264 2265if ($T2H_CHECK) { 2266 die "Need file to check\n$T2H_FAILURE_TEXT" unless @ARGV > 0; 2267 ✓ 2268 exit; 2269} 2270 2271#+++############################################################################ 2272# # 2273# evaluation of cmd line options 2274# # 2275#---############################################################################ 2276 2277if ($T2H_EXPAND eq 'info') 2278{ 2279 $to_skip{'ifinfo'} = 1; 2280 $to_skip{'end ifinfo'} = 1; 2281} 2282elsif ($T2H_EXPAND eq 'tex') 2283{ 2284 $to_skip{'iftex'} = 1; 2285 $to_skip{'end iftex'} = 1; 2286 2287} 2288 2289$T2H_INVISIBLE_MARK = '<IMG SRC="invisible.xbm">' if $T2H_INVISIBLE_MARK eq 'xbm'; 2290 2291# 2292# file name buisness 2293# 2294die "Need exactly one file to translate\n$T2H_FAILURE_TEXT" unless @ARGV == 1; 2295$docu = shift(@ARGV); 2296if ($docu =~ /.*\//) { 2297 chop($docu_dir = $&); 2298 $docu_name = $'; 2299} else { 2300 $docu_dir = '.'; 2301 $docu_name = $docu; 2302} 2303unshift(@T2H_INCLUDE_DIRS, $docu_dir); 2304$docu_name =~ s/\.te?x(i|info)?$//; # basename of the document 2305$docu_name = $T2H_PREFIX if ($T2H_PREFIX); 2306 2307# subdir 2308if ($T2H_SUBDIR && ! $T2H_OUT) 2309{ 2310 $T2H_SUBDIR =~ s|/*$||; 2311 unless (-d "$T2H_SUBDIR" && -w "$T2H_SUBDIR") 2312 { 2313 if ( mkdir($T2H_SUBDIR, oct(755))) 2314 { 2315 print "# created directory $T2H_SUBDIR\n" if ($T2H_VERBOSE); 2316 } 2317 else 2318 { 2319 warn "$ERROR can't create directory $T2H_SUBDIR. Put results into current directory\n"; 2320 $T2H_SUBDIR = ''; 2321 } 2322 } 2323} 2324 2325if ($T2H_SUBDIR && ! $T2H_OUT) 2326{ 2327 $docu_rdir = "$T2H_SUBDIR/"; 2328 print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); 2329} 2330else 2331{ 2332 if ($T2H_OUT && $T2H_OUT =~ m|(.*)/|) 2333 { 2334 $docu_rdir = "$1/"; 2335 print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); 2336 } 2337 else 2338 { 2339 print "# putting result files into current directory \n" if ($T2H_VERBOSE); 2340 $docu_rdir = ''; 2341 } 2342} 2343 2344# extension 2345if ($T2H_SHORTEXTN) 2346{ 2347 $docu_ext = "htm"; 2348} 2349else 2350{ 2351 $docu_ext = "html"; 2352} 2353if ($T2H_TOP_FILE =~ /\..*$/) 2354{ 2355 $T2H_TOP_FILE = $`.".$docu_ext"; 2356} 2357 2358# result files 2359if (! $T2H_OUT && ($T2H_SPLIT =~ /section/i || $T2H_SPLIT =~ /node/i)) 2360{ 2361 $T2H_SPLIT = 'section'; 2362} 2363elsif (! $T2H_OUT && $T2H_SPLIT =~ /chapter/i) 2364{ 2365 $T2H_SPLIT = 'chapter' 2366} 2367else 2368{ 2369 undef $T2H_SPLIT; 2370} 2371 2372$docu_doc = "$docu_name.$docu_ext"; # document's contents 2373$docu_doc_file = "$docu_rdir$docu_doc"; 2374if ($T2H_SPLIT) 2375{ 2376 $docu_toc = $T2H_TOC_FILE || "${docu_name}_toc.$docu_ext"; # document's table of contents 2377 $docu_stoc = "${docu_name}_ovr.$docu_ext"; # document's short toc 2378 $docu_foot = "${docu_name}_fot.$docu_ext"; # document's footnotes 2379 $docu_about = "${docu_name}_abt.$docu_ext"; # about this document 2380 $docu_top = $T2H_TOP_FILE || $docu_doc; 2381} 2382else 2383{ 2384 if ($T2H_OUT) 2385 { 2386 $docu_doc = $T2H_OUT; 2387 $docu_doc =~ s|.*/||; 2388 } 2389 $docu_toc = $docu_foot = $docu_stoc = $docu_about = $docu_top = $docu_doc; 2390} 2391 2392$docu_toc_file = "$docu_rdir$docu_toc"; 2393$docu_stoc_file = "$docu_rdir$docu_stoc"; 2394$docu_foot_file = "$docu_rdir$docu_foot"; 2395$docu_about_file = "$docu_rdir$docu_about"; 2396$docu_top_file = "$docu_rdir$docu_top"; 2397 2398$docu_frame_file = "$docu_rdir${docu_name}_frame.$docu_ext"; 2399$docu_toc_frame_file = "$docu_rdir${docu_name}_toc_frame.$docu_ext"; 2400 2401# 2402# variables 2403# 2404$value{'html'} = 1; # predefine html (the output format) 2405$value{'texi2html'} = $THISVERSION; # predefine texi2html (the translator) 2406# _foo: internal to track @foo 2407foreach ('_author', '_title', '_subtitle', 2408 '_settitle', '_setfilename', '_shorttitle') { 2409 $value{$_} = ''; # prevent -w warnings 2410} 2411%node2sec = (); # node to section name 2412%sec2node = (); # section to node name 2413%sec2number = (); # section to number 2414%number2sec = (); # number to section 2415%idx2node = (); # index keys to node 2416%node2href = (); # node to HREF 2417%node2next = (); # node to next 2418%node2prev = (); # node to prev 2419%node2up = (); # node to up 2420%bib2href = (); # bibliography reference to HREF 2421%gloss2href = (); # glossary term to HREF 2422@sections = (); # list of sections 2423%tag2pro = (); # protected sections 2424 2425# 2426# initial indexes 2427# 2428$bib_num = 0; 2429$foot_num = 0; 2430$gloss_num = 0; 2431$idx_num = 0; 2432$sec_num = 0; 2433$doc_num = 0; 2434$html_num = 0; 2435 2436# 2437# can I use ISO8879 characters? (HTML+) 2438# 2439if ($T2H_USE_ISO) { 2440 $things_map{'bullet'} = "•"; 2441 $things_map{'copyright'} = "©"; 2442 $things_map{'dots'} = "…"; 2443 $things_map{'equiv'} = "≡"; 2444 $things_map{'expansion'} = "→"; 2445 $things_map{'point'} = "∗"; 2446 $things_map{'result'} = "⇒"; 2447} 2448 2449# 2450# read texi2html extensions (if any) 2451# 2452$extensions = 'texi2html.ext'; # extensions in working directory 2453if (-f $extensions) { 2454 print "# reading extensions from $extensions\n" if $T2H_VERBOSE; 2455 require($extensions); 2456} 2457($progdir = $0) =~ s/[^\/]+$//; 2458if ($progdir && ($progdir ne './')) { 2459 $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory 2460 if (-f $extensions) { 2461 print "# reading extensions from $extensions\n" if $T2H_VERBOSE; 2462 require($extensions); 2463 } 2464} 2465 2466 2467print "# reading from $docu\n" if $T2H_VERBOSE; 2468 2469######################################################################### 2470# 2471# latex2html stuff 2472# 2473# latex2html conversions consist of three stages: 2474# 1) ToLatex: Put "latex" code into a latex file 2475# 2) ToHtml: Use latex2html to generate corresponding html code and images 2476# 3) FromHtml: Extract generated code and images from latex2html run 2477# 2478 2479########################## 2480# default settings 2481# 2482 2483# defaults for files and names 2484 2485sub l2h_Init 2486{ 2487 local($root) = @_; 2488 2489 return 0 unless ($root); 2490 2491 $l2h_name = "${root}_l2h"; 2492 2493 $l2h_latex_file = "$docu_rdir${l2h_name}.tex"; 2494 $l2h_cache_file = "${docu_rdir}l2h_cache.pm"; 2495 $T2H_L2H_L2H = "latex2html" unless ($T2H_L2H_L2H); 2496 2497 # destination dir -- generated images are put there, should be the same 2498 # as dir of enclosing html document -- 2499 $l2h_html_file = "$docu_rdir${l2h_name}.html"; 2500 $l2h_prefix = "${l2h_name}_"; 2501 return 1; 2502} 2503 2504 2505########################## 2506# 2507# First stage: Generation of Latex file 2508# Initialize with: l2h_InitToLatex 2509# Add content with: l2h_ToLatex($text) --> HTML placeholder comment 2510# Finish with: l2h_FinishToLatex 2511# 2512 2513$l2h_latex_preample = <<EOT; 2514% This document was automatically generated by the l2h extenstion of texi2html 2515% DO NOT EDIT !!! 2516\\documentclass{article} 2517\\usepackage{html} 2518\\begin{document} 2519EOT 2520 2521$l2h_latex_closing = <<EOT; 2522\\end{document} 2523EOT 2524 2525# return used latex 1, if l2h could be initalized properly, 0 otherwise 2526sub l2h_InitToLatex 2527{ 2528 %l2h_to_latex = (); 2529 unless ($T2H_L2H_SKIP) 2530 { 2531 unless (open(L2H_LATEX, ">$l2h_latex_file")) 2532 { 2533 warn "$ERROR Error l2h: Can't open latex file '$latex_file' for writing\n"; 2534 return 0; 2535 } 2536 print "# l2h: use ${l2h_latex_file} as latex file\n" if ($T2H_VERBOSE); 2537 print L2H_LATEX $l2h_latex_preample; 2538 } 2539 # open database for caching 2540 l2h_InitCache(); 2541 $l2h_latex_count = 0; 2542 $l2h_to_latex_count = 0; 2543 $l2h_cached_count = 0; 2544 return 1; 2545} 2546 2547# print text (1st arg) into latex file (if not already there), return 2548# HTML commentary which can be later on replaced by the latex2html 2549# generated text 2550sub l2h_ToLatex 2551{ 2552 my($text) = @_; 2553 my($count); 2554 2555 $l2h_to_latex_count++; 2556 $text =~ s/(\s*)$//; 2557 2558 # try whether we can cache it 2559 my $cached_text = l2h_FromCache($text); 2560 if ($cached_text) 2561 { 2562 $l2h_cached_count++; 2563 return $cached_text; 2564 } 2565 2566 # try whether we have text already on things to do 2567 unless ($count = $l2h_to_latex{$text}) 2568 { 2569 $count = $l2h_latex_count; 2570 $l2h_latex_count++; 2571 $l2h_to_latex{$text} = $count; 2572 $l2h_to_latex[$count] = $text; 2573 unless ($T2H_L2H_SKIP) 2574 { 2575 print L2H_LATEX "\\begin{rawhtml}\n"; 2576 print L2H_LATEX "<!-- l2h_begin ${l2h_name} ${count} -->\n"; 2577 print L2H_LATEX "\\end{rawhtml}\n"; 2578 2579 print L2H_LATEX "$text\n"; 2580 2581 print L2H_LATEX "\\begin{rawhtml}\n"; 2582 print L2H_LATEX "<!-- l2h_end ${l2h_name} ${count} -->\n"; 2583 print L2H_LATEX "\\end{rawhtml}\n"; 2584 } 2585 } 2586 return "<!-- l2h_replace ${l2h_name} ${count} -->"; 2587} 2588 2589# print closing into latex file and close it 2590sub l2h_FinishToLatex 2591{ 2592 local ($reused); 2593 2594 $reused = $l2h_to_latex_count - $l2h_latex_count - $l2h_cached_count; 2595 unless ($T2H_L2H_SKIP) 2596 { 2597 print L2H_LATEX $l2h_latex_closing; 2598 close(L2H_LATEX); 2599 } 2600 print "# l2h: finished to latex ($l2h_cached_count cached, $reused reused, $l2h_latex_count contents)\n" if ($T2H_VERBOSE); 2601 unless ($l2h_latex_count) 2602 { 2603 l2h_Finish(); 2604 return 0; 2605 } 2606 return 1; 2607} 2608 2609################################### 2610# Second stage: Use latex2html to generate corresponding html code and images 2611# 2612# l2h_ToHtml([$l2h_latex_file, [$l2h_html_dir]]): 2613# Call latex2html on $l2h_latex_file 2614# Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir 2615# Return 1, on success 2616# 0, otherwise 2617# 2618sub l2h_ToHtml 2619{ 2620 local($call, $ext, $root, $dotbug); 2621 2622 if ($T2H_L2H_SKIP) 2623 { 2624 print "# l2h: skipping latex2html run\n" if ($T2H_VERBOSE); 2625 return 1; 2626 } 2627 2628 # Check for dot in directory where dvips will work 2629 if ($T2H_L2H_TMP) 2630 { 2631 if ($T2H_L2H_TMP =~ /\./) 2632 { 2633 warn "$ERROR Warning l2h: l2h_tmp dir contains a dot. Use /tmp, instead\n"; 2634 $dotbug = 1; 2635 } 2636 } 2637 else 2638 { 2639 if (&getcwd =~ /\./) 2640 { 2641 warn "$ERROR Warning l2h: current dir contains a dot. Use /tmp as l2h_tmp dir \n"; 2642 $dotbug = 1; 2643 } 2644 } 2645 # fix it, if necessary and hope that it works 2646 $T2H_L2H_TMP = "/tmp" if ($dotbug); 2647 2648 $call = $T2H_L2H_L2H; 2649 # use init file, if specified 2650 $call = $call . " -init_file " . $init_file if ($init_file && -f $init_file); 2651 # set output dir 2652 $call .= ($docu_rdir ? " -dir $docu_rdir" : " -no_subdir"); 2653 # use l2h_tmp, if specified 2654 $call = $call . " -tmp $T2H_L2H_TMP" if ($T2H_L2H_TMP); 2655 # options we want to be sure of 2656 $call = $call ." -address 0 -info 0 -split 0 -no_navigation -no_auto_link"; 2657 $call = $call ." -prefix ${l2h_prefix} $l2h_latex_file"; 2658 2659 print "# l2h: executing '$call'\n" if ($T2H_VERBOSE); 2660 if (system($call)) 2661 { 2662 warn "l2h ***Error: '${call}' did not succeed\n"; 2663 return 0; 2664 } 2665 else 2666 { 2667 print "# l2h: latex2html finished successfully\n" if ($T2H_VERBOSE); 2668 return 1; 2669 } 2670} 2671 2672# this is directly pasted over from latex2html 2673sub getcwd { 2674 local($_) = `pwd`; 2675 2676 die "'pwd' failed (out of memory?)\n" 2677 unless length; 2678 chop; 2679 $_; 2680} 2681 2682 2683########################## 2684# Third stage: Extract generated contents from latex2html run 2685# Initialize with: l2h_InitFromHtml 2686# open $l2h_html_file for reading 2687# reads in contents into array indexed by numbers 2688# return 1, on success -- 0, otherwise 2689# Extract Html code with: l2h_FromHtml($text) 2690# replaces in $text all previosuly inserted comments by generated html code 2691# returns (possibly changed) $text 2692# Finish with: l2h_FinishFromHtml 2693# closes $l2h_html_dir/$l2h_name.".$docu_ext" 2694 2695sub l2h_InitFromHtml 2696{ 2697 local($h_line, $h_content, $count, %l2h_img); 2698 2699 if (! open(L2H_HTML, "<${l2h_html_file}")) 2700 { 2701 print "$ERROR Error l2h: Can't open ${l2h_html_file} for reading\n"; 2702 return 0; 2703 } 2704 print "# l2h: use ${l2h_html_file} as html file\n" if ($T2H_VERBOSE); 2705 2706 $l2h_html_count = 0; 2707 2708 while ($h_line = <L2H_HTML>) 2709 { 2710 if ($h_line =~ /^<!-- l2h_begin $l2h_name ([0-9]+) -->/) 2711 { 2712 $count = $1; 2713 $h_content = ""; 2714 while ($h_line = <L2H_HTML>) 2715 { 2716 if ($h_line =~ /^<!-- l2h_end $l2h_name $count -->/) 2717 { 2718 chomp $h_content; 2719 chomp $h_content; 2720 $l2h_html_count++; 2721 $h_content = l2h_ToCache($count, $h_content); 2722 $l2h_from_html[$count] = $h_content; 2723 $h_content = ''; 2724 last; 2725 } 2726 $h_content = $h_content.$h_line; 2727 } 2728 if ($hcontent) 2729 { 2730 print "$ERROR Warning l2h: l2h_end $l2h_name $count not found\n" 2731 if ($T2H_VERBOSE); 2732 close(L2H_HTML); 2733 return 0; 2734 } 2735 } 2736 } 2737 print "# l2h: Got $l2h_html_count of $l2h_latex_count html contents\n" 2738 if ($T2H_VERBOSE); 2739 2740 close(L2H_HTML); 2741 return 1; 2742} 2743 2744sub l2h_FromHtml 2745{ 2746 local($text) = @_; 2747 local($done, $to_do, $count); 2748 2749 $to_do = $text; 2750 2751 while ($to_do =~ /([^\000]*)<!-- l2h_replace $l2h_name ([0-9]+) -->([^\000]*)/) 2752 { 2753 $to_do = $1; 2754 $count = $2; 2755 $done = $3.$done; 2756 2757 $done = "<!-- l2h_end $l2h_name $count -->".$done 2758 if ($T2H_DEBUG & $DEBUG_L2H); 2759 2760 $done = &l2h_ExtractFromHtml($count) . $done; 2761 2762 $done = "<!-- l2h_begin $l2h_name $count -->".$done 2763 if ($T2H_DEBUG & $DEBUG_L2H); 2764 } 2765 return $to_do.$done; 2766} 2767 2768 2769sub l2h_ExtractFromHtml 2770{ 2771 local($count) = @_; 2772 2773 return $l2h_from_html[$count] if ($l2h_from_html[$count]); 2774 2775 if ($count >= 0 && $count < $l2h_latex_count) 2776 { 2777 # now we are in trouble 2778 local($l_l2h, $_); 2779 2780 $l2h_extract_error++; 2781 print "$ERROR l2h: can't extract content $count from html\n" 2782 if ($T2H_VERBOSE); 2783 # try simple (ordinary) substition (without l2h) 2784 $l_l2h = $T2H_L2H; 2785 $T2H_L2H = 0; 2786 $_ = $l2h_to_latex{$count}; 2787 $_ = &substitute_style($_); 2788 &unprotect_texi; 2789 $_ = "<!-- l2h: ". __LINE__ . " use texi2html -->" . $_ 2790 if ($T2H_DEBUG & $DEBUG_L2H); 2791 $T2H_L2H = $l_l2h; 2792 return $_; 2793 } 2794 else 2795 { 2796 # now we have been incorrectly called 2797 $l2h_range_error++; 2798 print "$ERROR l2h: Request of $count content which is out of valide range [0,$l2h_latex_count)\n"; 2799 return "<!-- l2h: ". __LINE__ . " out of range count $count -->" 2800 if ($T2H_DEBUG & $DEBUG_L2H); 2801 return "<!-- l2h: out of range count $count -->"; 2802 } 2803} 2804 2805sub l2h_FinishFromHtml 2806{ 2807 if ($T2H_VERBOSE) 2808 { 2809 if ($l2h_extract_error + $l2h_range_error) 2810 { 2811 print "# l2h: finished from html ($l2h_extract_error extract and $l2h_range_error errors)\n"; 2812 } 2813 else 2814 { 2815 print "# l2h: finished from html (no errors)\n"; 2816 } 2817 } 2818} 2819 2820sub l2h_Finish 2821{ 2822 l2h_StoreCache(); 2823 if ($T2H_L2H_CLEAN) 2824 { 2825 print "# l2h: removing temporary files generated by l2h extension\n" 2826 if $T2H_VERBOSE; 2827 while (<"$docu_rdir$l2h_name"*>) 2828 { 2829 unlink $_; 2830 } 2831 } 2832 print "# l2h: Finished\n" if $T2H_VERBOSE; 2833 return 1; 2834} 2835 2836############################## 2837# stuff for l2h caching 2838# 2839 2840# I tried doing this with a dbm data base, but it did not store all 2841# keys/values. Hence, I did as latex2html does it 2842sub l2h_InitCache 2843{ 2844 if (-r "$l2h_cache_file") 2845 { 2846 my $rdo = do "$l2h_cache_file"; 2847 warn("$ERROR l2h Error: could not load $docu_rdir$l2h_cache_file: $@\n") 2848 unless ($rdo); 2849 } 2850} 2851 2852sub l2h_StoreCache 2853{ 2854 return unless $l2h_latex_count; 2855 2856 my ($key, $value); 2857 open(FH, ">$l2h_cache_file") || return warn"$ERROR l2h Error: could not open $docu_rdir$l2h_cache_file for writing: $!\n"; 2858 2859 2860 while (($key, $value) = each %l2h_cache) 2861 { 2862 # escape stuff 2863 $key =~ s|/|\\/|g; 2864 $key =~ s|\\\\/|\\/|g; 2865 # weird, a \ at the end of the key results in an error 2866 # maybe this also broke the dbm database stuff 2867 $key =~ s|\\$|\\\\|; 2868 $value =~ s/\|/\\\|/g; 2869 $value =~ s/\\\\\|/\\\|/g; 2870 $value =~ s|\\\\|\\\\\\\\|g; 2871 print FH "\n\$l2h_cache_key = q/$key/;\n"; 2872 print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n"; 2873 } 2874 print FH "1;"; 2875 close(FH); 2876} 2877 2878# return cached html, if it exists for text, and if all pictures 2879# are there, as well 2880sub l2h_FromCache 2881{ 2882 my $text = shift; 2883 my $cached = $l2h_cache{$text}; 2884 if ($cached) 2885 { 2886 while ($cached =~ m/SRC="(.*?)"/g) 2887 { 2888 unless (-e "$docu_rdir$1") 2889 { 2890 return undef; 2891 } 2892 } 2893 return $cached; 2894 } 2895 return undef; 2896} 2897 2898# insert generated html into cache, move away images, 2899# return transformed html 2900$maximage = 1; 2901sub l2h_ToCache 2902{ 2903 my $count = shift; 2904 my $content = shift; 2905 my @images = ($content =~ /SRC="(.*?)"/g); 2906 my ($src, $dest); 2907 2908 for $src (@images) 2909 { 2910 $dest = $l2h_img{$src}; 2911 unless ($dest) 2912 { 2913 my $ext; 2914 if ($src =~ /.*\.(.*)$/ && $1 ne $docu_ext) 2915 { 2916 $ext = $1; 2917 } 2918 else 2919 { 2920 warn "$ERROR: L2h image $src has invalid extension\n"; 2921 next; 2922 } 2923 while (-e "$docu_rdir${docu_name}_$maximage.$ext") { $maximage++;} 2924 $dest = "${docu_name}_$maximage.$ext"; 2925 system("cp -f $docu_rdir$src $docu_rdir$dest"); 2926 $l2h_img{$src} = $dest; 2927 unlink "$docu_rdir$src" unless ($DEBUG & DEBUG_L2H); 2928 } 2929 $content =~ s/$src/$dest/g; 2930 } 2931 $l2h_cache{$l2h_to_latex[$count]} = $content; 2932 return $content; 2933} 2934 2935 2936#+++############################################################################ 2937# # 2938# Pass 1: read source, handle command, variable, simple substitution # 2939# # 2940#---############################################################################ 2941 2942@lines = (); # whole document 2943@toc_lines = (); # table of contents 2944@stoc_lines = (); # table of contents 2945$curlevel = 0; # current level in TOC 2946$node = ''; # current node name 2947$node_next = ''; # current node next name 2948$node_prev = ''; # current node prev name 2949$node_up = ''; # current node up name 2950$in_table = 0; # am I inside a table 2951$table_type = ''; # type of table ('', 'f', 'v', 'multi') 2952@tables = (); # nested table support 2953$in_bibliography = 0; # am I inside a bibliography 2954$in_glossary = 0; # am I inside a glossary 2955$in_top = 0; # am I inside the top node 2956$has_top = 0; # did I see a top node? 2957$has_top_command = 0; # did I see @top for automatic pointers? 2958$in_pre = 0; # am I inside a preformatted section 2959$in_list = 0; # am I inside a list 2960$in_html = 0; # am I inside an HTML section 2961$first_line = 1; # is it the first line 2962$dont_html = 0; # don't protect HTML on this line 2963$deferred_ref = ''; # deferred reference for indexes 2964@html_stack = (); # HTML elements stack 2965$html_element = ''; # current HTML element 2966&html_reset; 2967%macros = (); # macros 2968 2969# init l2h 2970$T2H_L2H = &l2h_Init($docu_name) if ($T2H_L2H); 2971$T2H_L2H = &l2h_InitToLatex if ($T2H_L2H); 2972 2973# build code for simple substitutions 2974# the maps used (%simple_map and %things_map) MUST be aware of this 2975# watch out for regexps, / and escaped characters! 2976$subst_code = ''; 2977foreach (keys(%simple_map)) { 2978 ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars 2979 $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n"; 2980} 2981foreach (keys(%things_map)) { 2982 $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n"; 2983} 2984if ($use_acc) { 2985 # accentuated characters 2986 foreach (keys(%accent_map)) { 2987 if ($_ eq "`") { 2988 $subst_code .= "s/$;3"; 2989 } elsif ($_ eq "'") { 2990 $subst_code .= "s/$;4"; 2991 } else { 2992 $subst_code .= "s/\\\@\\$_"; 2993 } 2994 $subst_code .= "([a-z])/&\${1}$accent_map{$_};/gi;\n"; 2995 } 2996} 2997eval("sub simple_substitutions { $subst_code }"); 2998 2999&init_input; 3000INPUT_LINE: while ($_ = &next_line) { 3001 # 3002 # remove \input on the first lines only 3003 # 3004 if ($first_line) { 3005 next if /^\\input/; 3006 $first_line = 0; 3007 } 3008 # non-@ substitutions cf. texinfmt.el 3009 # 3010 # parse texinfo tags 3011 # 3012 $tag = ''; 3013 $end_tag = ''; 3014 if (/^\s*\@end\s+(\w+)\b/) { 3015 $end_tag = $1; 3016 } elsif (/^\s*\@(\w+)\b/) { 3017 $tag = $1; 3018 } 3019 # 3020 # handle @html / @end html 3021 # 3022 if ($in_html) { 3023 if ($end_tag eq 'html') { 3024 $in_html = 0; 3025 } else { 3026 $tag2pro{$in_html} .= $_; 3027 } 3028 next; 3029 } elsif ($tag eq 'html') { 3030 $in_html = $PROTECTTAG . ++$html_num; 3031 push(@lines, $in_html); 3032 next; 3033 } 3034 3035 # 3036 # try to remove inlined comments 3037 # syntax from tex-mode.el comment-start-skip 3038 # 3039 s/((^|[^\@])(\@\@)*)\@c(omment | |\{|$).*/$1/; 3040 3041# Sometimes I use @c right at the end of a line ( to suppress the line feed ) 3042# s/((^|[^\@])(\@\@)*)\@c(omment)?$/$1/; 3043# s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/; 3044# s/(.*)\@c{.*?}(.*)/$1$2/; 3045# s/(.*)\@comment{.*?}(.*)/$1$2/; 3046# s/^(.*)\@c /$1/; 3047# s/^(.*)\@comment /$1/; 3048 3049 ############################################################# 3050 # value substitution before macro expansion, so that 3051 # it works in macro arguments 3052 s/\@value{($VARRE)}/$value{$1}/eg; 3053 3054 ############################################################# 3055 # macro substitution 3056 while (/\@(\w+)/g) 3057 { 3058 if (exists($macros->{$1})) 3059 { 3060 my $before = $`; 3061 my $name = $1; 3062 my $after = $'; 3063 my @args; 3064 my $args; 3065 if ($after =~ /^\s*{(.*?[^\\])}(.*)/) 3066 { 3067 $args = $1; 3068 $after = $2; 3069 } 3070 elsif (@{$macros->{$name}->{Args}} == 1) 3071 { 3072 $args = $after; 3073 $args =~ s/^\s*//; 3074 $args =~ s/\s*$//; 3075 $after = ''; 3076 } 3077 $args =~ s|\\\\|\\|g; 3078 $args =~ s|\\{|{|g; 3079 $args =~ s|\\}|}|g; 3080 if (@{$macros->{$name}->{Args}} > 1) 3081 { 3082 $args =~ s/(^|[^\\]),/$1$;/g ; 3083 $args =~ s|\\,|,|g; 3084 @args = split(/$;\s*/, $args) if (@{$macros->{$name}->{Args}} > 1); 3085 } 3086 else 3087 { 3088 $args =~ s|\\,|,|g; 3089 @args = ($args); 3090 } 3091 my $macrobody = $macros->{$name}->{Body}; 3092 for ($i=0; $i<=$#args; $i++) 3093 { 3094 $macrobody =~ s|\\$macros->{$name}->{Args}->[$i]\\|$args[$i]|g; 3095 } 3096 $macrobody =~ s|\\\\|\\|g; 3097 $_ = $before . $macrobody . $after; 3098 unshift @input_spool, map {$_ = $_."\n"} split(/\n/, $_); 3099 next INPUT_LINE; 3100 } 3101 } # 3102 3103 3104 # 3105 # try to skip the line 3106 # 3107 if ($end_tag) { 3108 $in_titlepage = 0 if $end_tag eq 'titlepage'; 3109 next if $to_skip{"end $end_tag"}; 3110 } elsif ($tag) { 3111 $in_titlepage = 1 if $tag eq 'titlepage'; 3112 next if $to_skip{$tag}; 3113 last if $tag eq 'bye'; 3114 } 3115 if ($in_top) { 3116 # parsing the top node 3117 if ($tag eq 'node' || 3118 ($sec2level{$tag} && $tag !~ /unnumbered/ && $tag !~ /heading/)) 3119 { 3120 # no more in top 3121 $in_top = 0; 3122 push(@lines, $TOPEND); 3123 } 3124 } 3125 unless ($in_pre) { 3126 s/``/\"/g; 3127 s/''/\"/g; 3128 s/([\w ])---([\w ])/$1--$2/g; 3129 } 3130 # 3131 # analyze the tag 3132 # 3133 if ($tag) { 3134 # skip lines 3135 &skip_until($tag), next if $tag eq 'ignore'; 3136 &skip_until($tag), next if $tag eq 'ifnothtml'; 3137 if ($tag eq 'ifinfo') 3138 { 3139 &skip_until($tag), next unless $T2H_EXPAND eq 'info'; 3140 } 3141 if ($tag eq 'iftex') 3142 { 3143 &skip_until($tag), next unless $T2H_EXPAND eq 'tex'; 3144 } 3145 if ($tag eq 'tex') 3146 { 3147 # add to latex2html file 3148 if ($T2H_EXPAND eq 'tex' && $T2H_L2H && ! $in_pre) 3149 { 3150 # add space to the end -- tex(i2dvi) does this, as well 3151 push(@lines, &l2h_ToLatex(&string_until($tag) . " ")); 3152 } 3153 else 3154 { 3155 &skip_until($tag); 3156 } 3157 next; 3158 } 3159 if ($tag eq 'titlepage') 3160 { 3161 next; 3162 } 3163 # handle special tables 3164 if ($tag =~ /^(|f|v|multi)table$/) { 3165 $table_type = $1; 3166 $tag = 'table'; 3167 } 3168 # special cases 3169 if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) { 3170 $in_top = 1; 3171 $has_top = 1; 3172 $has_top_command = 1 if $tag eq 'top'; 3173 @lines = (); # ignore all lines before top (title page garbage) 3174 next; 3175 } elsif ($tag eq 'node') { 3176 if ($in_top) 3177 { 3178 $in_top = 0; 3179 push(@lines, $TOPEND); 3180 } 3181 warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o; 3182 # request of "Richard Y. Kim" <ryk@ap.com> 3183 s/^\@node\s+//; 3184 $_ = &protect_html($_); # if node contains '&' for instance 3185 ($node, $node_next, $node_prev, $node_up) = split(/,/); 3186 &normalise_node($node); 3187 &normalise_node($node_next); 3188 &normalise_node($node_prev); 3189 &normalise_node($node_up); 3190 $node =~ /\"/ ? 3191 push @lines, &html_debug("<A NAME='$node'></A>\n", __LINE__) : 3192 push @lines, &html_debug("<A NAME=\"$node\"></A>\n", __LINE__); 3193 next; 3194 } elsif ($tag eq 'include') { 3195 if (/^\@include\s+($FILERE)\s*$/o) { 3196 $file = LocateIncludeFile($1); 3197 if ($file && -e $file) { 3198 &open($file); 3199 print "# including $file\n" if $T2H_VERBOSE; 3200 } else { 3201 warn "$ERROR Can't find $1, skipping"; 3202 } 3203 } else { 3204 warn "$ERROR Bad include line: $_"; 3205 } 3206 next; 3207 } elsif ($tag eq 'ifclear') { 3208 if (/^\@ifclear\s+($VARRE)\s*$/o) { 3209 next unless defined($value{$1}); 3210 &skip_until($tag); 3211 } else { 3212 warn "$ERROR Bad ifclear line: $_"; 3213 } 3214 next; 3215 } elsif ($tag eq 'ifset') { 3216 if (/^\@ifset\s+($VARRE)\s*$/o) { 3217 next if defined($value{$1}); 3218 &skip_until($tag); 3219 } else { 3220 warn "$ERROR Bad ifset line: $_"; 3221 } 3222 next; 3223 } elsif ($tag eq 'menu') { 3224 unless ($T2H_SHOW_MENU) { 3225 &skip_until($tag); 3226 next; 3227 } 3228 &html_push_if($tag); 3229 push(@lines, &html_debug('', __LINE__)); 3230 } elsif ($format_map{$tag}) { 3231 $in_pre = 1 if $format_map{$tag} eq 'PRE'; 3232 &html_push_if($format_map{$tag}); 3233 push(@lines, &html_debug('', __LINE__)); 3234 $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ; 3235# push(@lines, &debug("<BLOCKQUOTE>\n", __LINE__)) 3236# if $tag =~ /example/i; 3237 # sunshine@sunshineco.com: <PRE>bla</PRE> looks better than 3238 # <PRE>\nbla</PRE> (at least on NeXTstep browser 3239 push(@lines, &debug("<$format_map{$tag}>" . 3240 ($in_pre ? '' : "\n"), __LINE__)); 3241 next; 3242 } 3243 elsif (exists $complex_format_map->{$tag}) 3244 { 3245 my $start = eval $complex_format_map->{$tag}->[0]; 3246 if ($@) 3247 { 3248 print "$ERROR: eval of complex_format_map->{$tag}->[0] $complex_format_map->{$tag}->[0]: $@"; 3249 $start = '<pre>' 3250 } 3251 $in_pre = 1 if $start =~ /<pre/; 3252 push(@lines, html_debug($start. ($in_pre ? '' : "\n"), __LINE__)); 3253 next; 3254 } elsif ($tag eq 'table') { 3255 # anorland@hem2.passagen.se 3256 # if (/^\s*\@(|f|v|multi)table\s+\@(\w+)/) { 3257 if (/^\s*\@(|f|v|multi)table\s+\@(\w+)|(\{[^\}]*\})/) { 3258 $in_table = $2; 3259 unshift(@tables, join($;, $table_type, $in_table)); 3260 if ($table_type eq "multi") { 3261 # don't use borders -- gets confused by empty cells 3262 push(@lines, &debug("<TABLE>\n", __LINE__)); 3263 &html_push_if('TABLE'); 3264 } else { 3265 push(@lines, &debug("<DL COMPACT>\n", __LINE__)); 3266 &html_push_if('DL'); 3267 } 3268 push(@lines, &html_debug('', __LINE__)); 3269 } else { 3270 warn "$ERROR Bad table line: $_"; 3271 } 3272 next; 3273 } 3274 elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') 3275 { 3276 if (/^\@$tag\s+(\w+)\s+(\w+)\s*$/) 3277 { 3278 my $from = $1; 3279 my $to = $2; 3280 my $prefix_from = IndexName2Prefix($from); 3281 my $prefix_to = IndexName2Prefix($to); 3282 3283 warn("$ERROR unknown from index name $from ind syn*index line: $_"), next 3284 unless $prefix_from; 3285 warn("$ERROR unknown to index name $to ind syn*index line: $_"), next 3286 unless $prefix_to; 3287 3288 if ($tag eq 'syncodeindex') 3289 { 3290 $index_properties->{$prefix_to}->{'from_code'}->{$prefix_from} = 1; 3291 } 3292 else 3293 { 3294 $index_properties->{$prefix_to}->{'from'}->{$prefix_from} = 1; 3295 } 3296 } 3297 else 3298 { 3299 warn "$ERROR Bad syn*index line: $_"; 3300 } 3301 next; 3302 } 3303 elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') 3304 { 3305 if (/^\@$tag\s+(\w+)\s*$/) 3306 { 3307 my $name = $1; 3308 $index_properties->{$name}->{name} = $name; 3309 $index_properties->{$name}->{code} = 1 if $tag eq 'defcodeindex'; 3310 } 3311 else 3312 { 3313 warn "$ERROR Bad defindex line: $_"; 3314 } 3315 next; 3316 } 3317 elsif (/^\@printindex/) 3318 { 3319 push (@lines, "<!--::${section}::-->$_"); 3320 next; 3321 } 3322 elsif ($tag eq 'sp') { 3323 push(@lines, &debug("<P>\n", __LINE__)); 3324 next; 3325 } elsif ($tag eq 'center') { 3326 push(@lines, &debug("<center>\n", __LINE__)); 3327 s/\@center//; 3328 } elsif ($tag eq 'setref') { 3329 &protect_html; # if setref contains '&' for instance 3330 if (/^\@$tag\s*{($NODERE)}\s*$/) { 3331 $setref = $1; 3332 $setref =~ s/\s+/ /g; # normalize 3333 $setref =~ s/ $//; 3334 $node2sec{$setref} = $name; 3335 $sec2node{$name} = $setref; 3336 $node2href{$setref} = "$docu_doc#$docid"; 3337 } else { 3338 warn "$ERROR Bad setref line: $_"; 3339 } 3340 next; 3341 } elsif ($tag eq 'lowersections') { 3342 local ($sec, $level); 3343 while (($sec, $level) = each %sec2level) { 3344 $sec2level{$sec} = $level + 1; 3345 } 3346 next; 3347 } elsif ($tag eq 'raisesections') { 3348 local ($sec, $level); 3349 while (($sec, $level) = each %sec2level) { 3350 $sec2level{$sec} = $level - 1; 3351 } 3352 next; 3353 } 3354 elsif ($tag eq 'macro' || $tag eq 'rmacro') 3355 { 3356 if (/^\@$tag\s*(\w+)\s*(.*)/) 3357 { 3358 my $name = $1; 3359 my @args; 3360 @args = split(/\s*,\s*/ , $1) 3361 if ($2 =~ /^\s*{(.*)}\s*/); 3362 3363 $macros->{$name}->{Args} = \@args; 3364 $macros->{$name}->{Body} = ''; 3365 while (($_ = &next_line) && $_ !~ /\@end $tag/) 3366 { 3367 $macros->{$name}->{Body} .= $_; 3368 } 3369 die "ERROR: No closing '\@end $tag' found for macro definition of '$name'\n" 3370 unless (/\@end $tag/); 3371 chomp $macros->{$name}->{Body}; 3372 } 3373 else 3374 { 3375 warn "$ERROR: Bad macro defintion $_" 3376 } 3377 next; 3378 } 3379 elsif ($tag eq 'unmacro') 3380 { 3381 delete $macros->{$1} if (/^\@unmacro\s*(\w+)/); 3382 next; 3383 } 3384 elsif ($tag eq 'documentlanguage') 3385 { 3386 SetDocumentLanguage($1) if (!$T2H_LANG && /documentlanguage\s*(\w+)/); 3387 } 3388 elsif (defined($def_map{$tag})) { 3389 if ($def_map{$tag}) { 3390 s/^\@$tag\s+//; 3391 $tag = $def_map{$tag}; 3392 $_ = "\@$tag $_"; 3393 $tag =~ s/\s.*//; 3394 } 3395 } elsif (defined($user_sub{$tag})) { 3396 s/^\@$tag\s+//; 3397 $sub = $user_sub{$tag}; 3398 print "# user $tag = $sub, arg: $_" if $T2H_DEBUG & $DEBUG_USER; 3399 if (defined(&$sub)) { 3400 chop($_); 3401 &$sub($_); 3402 } else { 3403 warn "$ERROR Bad user sub for $tag: $sub\n"; 3404 } 3405 next; 3406 } 3407 if (defined($def_map{$tag})) { 3408 s/^\@$tag\s+//; 3409 if ($tag =~ /x$/) { 3410 # extra definition line 3411 $tag = $`; 3412 $is_extra = 1; 3413 } else { 3414 $is_extra = 0; 3415 } 3416 while (/\{([^\{\}]*)\}/) { 3417 # this is a {} construct 3418 ($before, $contents, $after) = ($`, $1, $'); 3419 # protect spaces 3420 $contents =~ s/\s+/$;9/g; 3421 # restore $_ protecting {} 3422 $_ = "$before$;7$contents$;8$after"; 3423 } 3424 @args = split(/\s+/, &protect_html($_)); 3425 foreach (@args) { 3426 s/$;9/ /g; # unprotect spaces 3427 s/$;7/\{/g; # ... { 3428 s/$;8/\}/g; # ... } 3429 } 3430 $type = shift(@args); 3431 $type =~ s/^\{(.*)\}$/$1/; 3432 print "# def ($tag): {$type} ", join(', ', @args), "\n" 3433 if $T2H_DEBUG & $DEBUG_DEF; 3434 $type .= ':'; # it's nicer like this 3435 my $name = shift(@args); 3436 $name =~ s/^\{(.*)\}$/$1/; 3437 if ($is_extra) { 3438 $_ = &debug("<DT>", __LINE__); 3439 } else { 3440 $_ = &debug("<DL>\n<DT>", __LINE__); 3441 } 3442 if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') { 3443 $_ .= "<U>$type</U> <B>$name</B>"; 3444 $_ .= " <I>@args</I>" if @args; 3445 } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr' 3446 || $tag eq 'defcv' || $tag eq 'defop') { 3447 $ftype = $name; 3448 $name = shift(@args); 3449 $name =~ s/^\{(.*)\}$/$1/; 3450 $_ .= "<U>$type</U> $ftype <B>$name</B>"; 3451 $_ .= " <I>@args</I>" if @args; 3452 } else { 3453 warn "$ERROR Unknown definition type: $tag\n"; 3454 $_ .= "<U>$type</U> <B>$name</B>"; 3455 $_ .= " <I>@args</I>" if @args; 3456 } 3457 $_ .= &debug("\n<DD>", __LINE__); 3458 $name = &unprotect_html($name); 3459 if ($tag eq 'deffn' || $tag eq 'deftypefn') { 3460 EnterIndexEntry('f', $name, $docu_doc, $section, \@lines); 3461# unshift(@input_spool, "\@findex $name\n"); 3462 } elsif ($tag eq 'defop') { 3463 EnterIndexEntry('f', "$name on $ftype", $docu_doc, $section, \@lines); 3464# unshift(@input_spool, "\@findex $name on $ftype\n"); 3465 } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') { 3466 EnterIndexEntry('v', $name, $docu_doc, $section, \@lines); 3467# unshift(@input_spool, "\@vindex $name\n"); 3468 } else { 3469 EnterIndexEntry('t', $name, $docu_doc, $section, \@lines); 3470# unshift(@input_spool, "\@tindex $name\n"); 3471 } 3472 $dont_html = 1; 3473 } 3474 } elsif ($end_tag) { 3475 if ($format_map{$end_tag}) { 3476 $in_pre = 0 if $format_map{$end_tag} eq 'PRE'; 3477 $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ; 3478 &html_pop_if('P'); 3479 &html_pop_if('LI'); 3480 &html_pop_if(); 3481 push(@lines, &debug("</$format_map{$end_tag}>\n", __LINE__)); 3482 push(@lines, &html_debug('', __LINE__)); 3483 } 3484 elsif (exists $complex_format_map->{$end_tag}) 3485 { 3486 my $end = eval $complex_format_map->{$end_tag}->[1]; 3487 if ($@) 3488 { 3489 print "$ERROR: eval of complex_format_map->{$end_tag}->[1] $complex_format_map->{$end_tag}->[0]: $@"; 3490 $end = '</pre>' 3491 } 3492 $in_pre = 0 if $end =~ m|</pre>|; 3493 push(@lines, html_debug($end, __LINE__)); 3494 } elsif ($end_tag =~ /^(|f|v|multi)table$/) { 3495 unless (@tables) { 3496 warn "$ERROR \@end $end_tag without \@*table\n"; 3497 next; 3498 } 3499 &html_pop_if('P'); 3500 ($table_type, $in_table) = split($;, shift(@tables)); 3501 unless ($1 eq $table_type) { 3502 warn "$ERROR \@end $end_tag without matching \@$end_tag\n"; 3503 next; 3504 } 3505 if ($table_type eq "multi") { 3506 push(@lines, "</TR></TABLE>\n"); 3507 &html_pop_if('TR'); 3508 } else { 3509 push(@lines, "</DL>\n"); 3510 &html_pop_if('DD'); 3511 } 3512 &html_pop_if(); 3513 if (@tables) { 3514 ($table_type, $in_table) = split($;, $tables[0]); 3515 } else { 3516 $in_table = 0; 3517 } 3518 } elsif (defined($def_map{$end_tag})) { 3519 push(@lines, &debug("</DL>\n", __LINE__)); 3520 } elsif ($end_tag eq 'menu') { 3521 &html_pop_if(); 3522 push(@lines, $_); # must keep it for pass 2 3523 } 3524 next; 3525 } 3526 ############################################################# 3527 # anchor insertion 3528 while (/\@anchor\s*\{(.*?)\}/) 3529 { 3530 $_ = $`.$'; 3531 my $anchor = $1; 3532 $anchor = &normalise_node($anchor); 3533 push @lines, &html_debug("<A NAME=\"$anchor\"></A>\n"); 3534 $node2href{$anchor} = "$docu_doc#$anchor"; 3535 next INPUT_LINE if $_ =~ /^\s*$/; 3536 } 3537 3538 ############################################################# 3539 # index entry generation, after value substitutions 3540 if (/^\@(\w+?)index\s+/) 3541 { 3542 EnterIndexEntry($1, $', $docu_doc, $section, \@lines); 3543 next; 3544 } 3545 # 3546 # protect texi and HTML things 3547 &protect_texi; 3548 $_ = &protect_html($_) unless $dont_html; 3549 $dont_html = 0; 3550 # substitution (unsupported things) 3551 s/^\@exdent\s+//g; 3552 s/\@noindent\s+//g; 3553 s/\@refill\s+//g; 3554 # other substitutions 3555 &simple_substitutions; 3556 s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4 3557 # 3558 # analyze the tag again 3559 # 3560 if ($tag) { 3561 if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) { 3562 if (/^\@$tag\s+(.+)$/) { 3563 $name = $1; 3564 $name = &normalise_node($name); 3565 $level = $sec2level{$tag}; 3566 # check for index 3567 $first_index_chapter = $name 3568 if ($level == 1 && !$first_index_chapter && 3569 $name =~ /index/i); 3570 if ($in_top && /heading/){ 3571 $T2H_HAS_TOP_HEADING = 1; 3572 $_ = &debug("<H$level>$name</H$level>\n", __LINE__); 3573 &html_push_if('body'); 3574 print "# top heading, section $name, level $level\n" 3575 if $T2H_DEBUG & $DEBUG_TOC; 3576 } 3577 else 3578 { 3579 unless (/^\@\w*heading/) 3580 { 3581 unless (/^\@unnumbered/) 3582 { 3583 my $number = &update_sec_num($tag, $level); 3584 $name = $number. ' ' . $name if $T2H_NUMBER_SECTIONS; 3585 $sec2number{$name} = $number; 3586 $number2sec{$number} = $name; 3587 } 3588 if (defined($toplevel)) 3589 { 3590 push @lines, ($level==$toplevel ? $CHAPTEREND : $SECTIONEND); 3591 } 3592 else 3593 { 3594 # first time we see a "section" 3595 unless ($level == 1) 3596 { 3597 warn "$WARN The first section found is not of level 1: $_"; 3598 } 3599 $toplevel = $level; 3600 } 3601 push(@sections, $name); 3602 next_doc() if ($T2H_SPLIT eq 'section' || 3603 $T2H_SPLIT && $level == $toplevel); 3604 } 3605 $sec_num++; 3606 $docid = "SEC$sec_num"; 3607 $tocid = (/^\@\w*heading/ ? undef : "TOC$sec_num"); 3608 # check biblio and glossary 3609 $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i); 3610 $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i); 3611 # check node 3612 if ($node) 3613 { 3614 warn "$ERROR Duplicate node found: $node\n" 3615 if ($node2sec{$node}); 3616 } 3617 else 3618 { 3619 $name .= ' ' while ($node2sec{$name}); 3620 $node = $name; 3621 } 3622 $name .= ' ' while ($sec2node{$name}); 3623 $section = $name; 3624 $node2sec{$node} = $name; 3625 $sec2node{$name} = $node; 3626 $node2href{$node} = "$docu_doc#$docid"; 3627 $node2next{$node} = $node_next; 3628 $node2prev{$node} = $node_prev; 3629 $node2up{$node} = $node_up; 3630 print "# node $node, section $name, level $level\n" 3631 if $T2H_DEBUG & $DEBUG_TOC; 3632 3633 $node = ''; 3634 $node_next = ''; 3635 $node_prev = ''; 3636 $node_next = ''; 3637 if ($tocid) 3638 { 3639 # update TOC 3640 while ($level > $curlevel) { 3641 $curlevel++; 3642 push(@toc_lines, "<UL>\n"); 3643 } 3644 while ($level < $curlevel) { 3645 $curlevel--; 3646 push(@toc_lines, "</UL>\n"); 3647 } 3648 $_ = &t2h_anchor($tocid, "$docu_doc#$docid", $name, 1); 3649 $_ = &substitute_style($_); 3650 push(@stoc_lines, "$_<BR>\n") if ($level == 1); 3651 if ($T2H_NUMBER_SECTIONS) 3652 { 3653 push(@toc_lines, $_ . "<BR>\n") 3654 } 3655 else 3656 { 3657 push(@toc_lines, "<LI>" . $_ ."</LI>"); 3658 } 3659 } 3660 else 3661 { 3662 push(@lines, &html_debug("<A NAME=\"$docid\"></A>\n", 3663 __LINE__)); 3664 } 3665 # update DOC 3666 push(@lines, &html_debug('', __LINE__)); 3667 &html_reset; 3668 $_ = "<H$level> $name </H$level>\n<!--docid::${docid}::-->\n"; 3669 $_ = &debug($_, __LINE__); 3670 push(@lines, &html_debug('', __LINE__)); 3671 } 3672 # update DOC 3673 foreach $line (split(/\n+/, $_)) { 3674 push(@lines, "$line\n"); 3675 } 3676 next; 3677 } else { 3678 warn "$ERROR Bad section line: $_"; 3679 } 3680 } else { 3681 # track variables 3682 $value{$1} = Unprotect_texi($2), next if /^\@set\s+($VARRE)\s+(.*)$/o; 3683 delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o; 3684 # store things 3685 $value{'_shorttitle'} = Unprotect_texi($1), next if /^\@shorttitle\s+(.*)$/; 3686 $value{'_setfilename'} = Unprotect_texi($1), next if /^\@setfilename\s+(.*)$/; 3687 $value{'_settitle'} = Unprotect_texi($1), next if /^\@settitle\s+(.*)$/; 3688 $value{'_author'} .= Unprotect_texi($1)."\n", next if /^\@author\s+(.*)$/; 3689 $value{'_subtitle'} .= Unprotect_texi($1)."\n", next if /^\@subtitle\s+(.*)$/; 3690 $value{'_title'} .= Unprotect_texi($1)."\n", next if /^\@title\s+(.*)$/; 3691 3692 # list item 3693 if (/^\s*\@itemx?\s+/) { 3694 $what = $'; 3695 $what =~ s/\s+$//; 3696 if ($in_bibliography && $use_bibliography) { 3697 if ($what =~ /^$BIBRE$/o) { 3698 $id = 'BIB' . ++$bib_num; 3699 $bib2href{$what} = "$docu_doc#$id"; 3700 print "# found bibliography for '$what' id $id\n" 3701 if $T2H_DEBUG & $DEBUG_BIB; 3702 $what = &t2h_anchor($id, '', $what); 3703 } 3704 } elsif ($in_glossary && $T2H_USE_GLOSSARY) { 3705 $id = 'GLOSS' . ++$gloss_num; 3706 $entry = $what; 3707 $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; 3708 $gloss2href{$entry} = "$docu_doc#$id"; 3709 print "# found glossary for '$entry' id $id\n" 3710 if $T2H_DEBUG & $DEBUG_GLOSS; 3711 $what = &t2h_anchor($id, '', $what); 3712 } 3713 elsif ($in_table && ($table_type eq 'f' || $table_type eq 'v')) 3714 { 3715 EnterIndexEntry($table_type, $what, $docu_doc, $section, \@lines); 3716 } 3717 &html_pop_if('P'); 3718 if ($html_element eq 'DL' || $html_element eq 'DD') { 3719 if ($things_map{$in_table} && !$what) { 3720 # special case to allow @table @bullet for instance 3721 push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__)); 3722 } else { 3723 push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__)); 3724 } 3725 push(@lines, "<DD>"); 3726 &html_push('DD') unless $html_element eq 'DD'; 3727 if ($table_type) { # add also an index 3728 unshift(@input_spool, "\@${table_type}index $what\n"); 3729 } 3730 } elsif ($html_element eq 'TABLE') { 3731 push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__)); 3732 &html_push('TR'); 3733 } elsif ($html_element eq 'TR') { 3734 push(@lines, &debug("</TR>\n", __LINE__)); 3735 push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__)); 3736 } else { 3737 push(@lines, &debug("<LI>$what\n", __LINE__)); 3738 &html_push('LI') unless $html_element eq 'LI'; 3739 } 3740 push(@lines, &html_debug('', __LINE__)); 3741 if ($deferred_ref) { 3742 push(@lines, &debug("$deferred_ref\n", __LINE__)); 3743 $deferred_ref = ''; 3744 } 3745 next; 3746 } elsif (/^\@tab\s+(.*)$/) { 3747 push(@lines, "<TD>$1</TD>\n"); 3748 next; 3749 } 3750 } 3751 } 3752 # paragraph separator 3753 if ($_ eq "\n" && ! $in_pre) { 3754 next if $#lines >= 0 && $lines[$#lines] eq "\n"; 3755 if ($html_element eq 'P') { 3756 push (@lines, &debug("</P><P>\n", __LINE__)); 3757 } 3758# else 3759# { 3760# push(@lines, "<P></P>\n"); 3761# $_ = &debug("<P></P>\n", __LINE__); 3762# } 3763 elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE' || $html_element eq 'DD' || $html_element eq 'LI') 3764 { 3765 &html_push('P'); 3766 push(@lines, &debug("<P>\n", __LINE__)); 3767 } 3768 } 3769 # otherwise 3770 push(@lines, $_) unless $in_titlepage; 3771 push(@lines, &debug("</center>\n", __LINE__)) if ($tag eq 'center'); 3772} 3773 3774# finish TOC 3775$level = 0; 3776while ($level < $curlevel) { 3777 $curlevel--; 3778 push(@toc_lines, "</UL>\n"); 3779} 3780 3781print "# end of pass 1\n" if $T2H_VERBOSE; 3782 3783SetDocumentLanguage('en') unless ($T2H_LANG); 3784#+++############################################################################ 3785# # 3786# Stuff related to Index generation # 3787# # 3788#---############################################################################ 3789 3790sub EnterIndexEntry 3791{ 3792 my $prefix = shift; 3793 my $key = shift; 3794 my $docu_doc = shift; 3795 my $section = shift; 3796 my $lines = shift; 3797 local $_; 3798 3799 warn "$ERROR Undefined index command: $_", next 3800 unless (exists ($index_properties->{$prefix})); 3801 $key =~ s/\s+$//; 3802 $_ = $key; 3803 &protect_texi; 3804 $key = $_; 3805 $_ = &protect_html($_); 3806 my $html_key = substitute_style($_); 3807 my $id; 3808 $key = remove_style($key); 3809 $key = remove_things($key); 3810 $_ = $key; 3811 &unprotect_texi; 3812 $key = $_; 3813 while (exists $index->{$prefix}->{$key}) {$key .= ' '}; 3814 if ($lines->[$#lines] =~ /^<!--docid::(.+)::-->$/) 3815 { 3816 $id = $1; 3817 } 3818 else 3819 { 3820 $id = 'IDX' . ++$idx_num; 3821 push(@$lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre)); 3822 } 3823 $index->{$prefix}->{$key}->{html_key} = $html_key; 3824 $index->{$prefix}->{$key}->{section} = $section; 3825 $index->{$prefix}->{$key}->{href} = "$docu_doc#$id"; 3826 print "# found ${prefix}index for '$key' with id $id\n" 3827 if $T2H_DEBUG & $DEBUG_INDEX; 3828} 3829 3830sub IndexName2Prefix 3831{ 3832 my $name = shift; 3833 my $prefix; 3834 3835 for $prefix (keys %$index_properties) 3836 { 3837 return $prefix if ($index_properties->{$prefix}->{name} eq $name); 3838 } 3839 return undef; 3840} 3841 3842sub GetIndexEntries 3843{ 3844 my $normal = shift; 3845 my $code = shift; 3846 my ($entries, $prefix, $key) = ({}); 3847 3848 for $prefix (keys %$normal) 3849 { 3850 for $key (keys %{$index->{$prefix}}) 3851 { 3852 $entries->{$key} = {%{$index->{$prefix}->{$key}}}; 3853 } 3854 } 3855 3856 if (defined($code)) 3857 { 3858 for $prefix (keys %$code) 3859 { 3860 unless (exists $normal->{$keys}) 3861 { 3862 for $key (keys %{$index->{$prefix}}) 3863 { 3864 $entries->{$key} = {%{$index->{$prefix}->{$key}}}; 3865 $entries->{$key}->{html_key} = "<CODE>$entries->{$key}->{html_key}</CODE>"; 3866 } 3867 } 3868 } 3869 } 3870 return $entries; 3871} 3872 3873sub byAlpha 3874{ 3875 if ($a =~ /^[A-Za-z]/) 3876 { 3877 if ($b =~ /^[A-Za-z]/) 3878 { 3879 return lc($a) cmp lc($b); 3880 } 3881 else 3882 { 3883 return 1; 3884 } 3885 } 3886 elsif ($b =~ /^[A-Za-z]/) 3887 { 3888 return -1; 3889 } 3890 else 3891 { 3892 return lc($a) cmp lc($b); 3893 } 3894} 3895 3896sub GetIndexPages 3897{ 3898 my $entries = shift; 3899 my (@Letters, $key); 3900 my ($EntriesByLetter, $Pages, $page) = ({}, [], {}); 3901 my @keys = sort byAlpha keys %$entries; 3902 3903 for $key (@keys) 3904 { 3905 push @{$EntriesByLetter->{uc(substr($key,0, 1))}} , $entries->{$key}; 3906 } 3907 @Letters = sort byAlpha keys %$EntriesByLetter; 3908 3909 $T2H_SPLIT_INDEX = 0 unless ($T2H_SPLIT); 3910 3911 unless ($T2H_SPLIT_INDEX) 3912 { 3913 $page->{First} = $Letters[0]; 3914 $page->{Last} = $Letters[$#Letters]; 3915 $page->{Letters} = \@Letters; 3916 $page->{EntriesByLetter} = $EntriesByLetter; 3917 push @$Pages, $page; 3918 return $Pages; 3919 } 3920 3921 if ($T2H_SPLIT_INDEX =~ /^\d+$/) 3922 { 3923 my $i = 0; 3924 my ($prev_letter, $letter); 3925 $page->{First} = $Letters[0]; 3926 for $letter (@Letters) 3927 { 3928 if ($i > $T2H_SPLIT_INDEX) 3929 { 3930 $page->{Last} = $prev_letter; 3931 push @$Pages, {%$page}; 3932 $page->{Letters} = []; 3933 $page->{EntriesByLetter} = {}; 3934 $page->{First} = $letter; 3935 $i=0; 3936 } 3937 push @{$page->{Letters}}, $letter; 3938 $page->{EntriesByLetter}->{$letter} = [@{$EntriesByLetter->{$letter}}]; 3939 $i += scalar(@{$EntriesByLetter->{$letter}}); 3940 $prev_letter = $letter; 3941 } 3942 $page->{Last} = $Letters[$#Letters]; 3943 push @$Pages, {%$page}; 3944 } 3945 return $Pages; 3946} 3947 3948sub GetIndexSummary 3949{ 3950 my $first_page = shift; 3951 my $Pages = shift; 3952 my $name = shift; 3953 my ($page, $letter, $summary, $i, $l1, $l2, $l); 3954 3955 $i = 0; 3956 $summary = '<table><tr><th valign=top>Jump to: </th><td>'; 3957 3958 for $page ($first_page, @$Pages) 3959 { 3960 for $letter (@{$page->{Letters}}) 3961 { 3962 $l = t2h_anchor('', "$page->{href}#${name}_$letter", "<b>$letter</b>", 3963 0, 'style="text-decoration:none"') . "\n \n"; 3964 3965 if ($letter =~ /^[A-Za-z]/) 3966 { 3967 $l2 .= $l; 3968 } 3969 else 3970 { 3971 $l1 .= $l; 3972 } 3973 } 3974 } 3975 $summary .= $l1 . "<BR>\n" if ($l1); 3976 $summary .= $l2 . '</td></tr></table><br>'; 3977 return $summary; 3978} 3979 3980sub PrintIndexPage 3981{ 3982 my $lines = shift; 3983 my $summary = shift; 3984 my $page = shift; 3985 my $name = shift; 3986 3987 push @$lines, $summary; 3988 3989 push @$lines , <<EOT; 3990<P></P> 3991<TABLE border=0> 3992<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> Section</TH></TR> 3993<TR><TD COLSPAN=3> <HR></TD></TR> 3994EOT 3995 3996 for $letter (@{$page->{Letters}}) 3997 { 3998 push @$lines, "<TR><TH><A NAME=\"${name}_$letter\"></A>$letter</TH><TD></TD><TD></TD></TR>\n"; 3999 for $entry (@{$page->{EntriesByLetter}->{$letter}}) 4000 { 4001 push @$lines, 4002 "<TR><TD></TD><TD valign=top>" . 4003 t2h_anchor('', $entry->{href}, $entry->{html_key}) . 4004 "</TD><TD valign=top>" . 4005 t2h_anchor('', sec_href($entry->{section}), clean_name($entry->{section})) . 4006 "</TD></TR>\n"; 4007 } 4008 push @$lines, "<TR><TD COLSPAN=3> <HR></TD></TR>\n"; 4009 } 4010 push @$lines, "</TABLE><P></P>"; 4011 push @$lines, $summary; 4012} 4013 4014sub PrintIndex 4015{ 4016 my $lines = shift; 4017 my $name = shift; 4018 my $section = shift; 4019 $section = 'Top' unless $section; 4020 my $prefix = IndexName2Prefix($name); 4021 4022 warn ("$ERROR printindex: bad index name: $name"), return 4023 unless $prefix; 4024 4025 if ($index_properties->{$prefix}->{code}) 4026 { 4027 $index_properties->{$prefix}->{from_code}->{$prefix} = 1; 4028 } 4029 else 4030 { 4031 $index_properties->{$prefix}->{from}->{$prefix}= 1; 4032 } 4033 4034 my $Entries = GetIndexEntries($index_properties->{$prefix}->{from}, 4035 $index_properties->{$prefix}->{from_code}); 4036 return unless %$Entries; 4037 4038 if ($T2H_IDX_SUMMARY) 4039 { 4040 my $key; 4041 open(FHIDX, ">$docu_rdir$docu_name" . "_$name.idx") 4042 || die "Can't open > $docu_rdir$docu_name" . "_$name.idx for writing: $!\n"; 4043 print "# writing $name index summary in $docu_rdir$docu_name" . "_$name.idx...\n" if $T2H_VERBOSE; 4044 4045 for $key (sort keys %$Entries) 4046 { 4047 print FHIDX "$key\t$Entries->{$key}->{href}\n"; 4048 } 4049 } 4050 4051 my $Pages = GetIndexPages($Entries); 4052 my $page; 4053 my $first_page = shift @$Pages; 4054 my $sec_name = $section; 4055 # remove section number 4056 $sec_name =~ s/.*? // if $sec_name =~ /^([A-Z]|\d+)\./; 4057 4058 ($first_page->{href} = sec_href($section)) =~ s/\#.*$//; 4059 # Update tree structure of document 4060 if (@$Pages) 4061 { 4062 my $sec; 4063 my @after; 4064 4065 while (@sections && $sections[$#sections] ne $section) 4066 { 4067 unshift @after, pop @sections; 4068 } 4069 4070 for $page (@$Pages) 4071 { 4072 my $node = ($page->{First} ne $page->{Last} ? 4073 "$sec_name: $page->{First} -- $page->{Last}" : 4074 "$sec_name: $page->{First}"); 4075 push @sections, $node; 4076 $node2sec{$node} = $node; 4077 $sec2node{$node} = $node; 4078 $node2up{$node} = $section; 4079 $page->{href} = next_doc(); 4080 $page->{name} = $node; 4081 $node2href{$node} = $page->{href}; 4082 if ($prev_node) 4083 { 4084 $node2next{$prev_node} = $node; 4085 $node2prev{$node} = $prev_node; 4086 } 4087 $prev_node = $node; 4088 } 4089 push @sections, @after; 4090 } 4091 4092 my $summary = GetIndexSummary($first_page, $Pages, $name); 4093 PrintIndexPage($lines, $summary, $first_page, $name); 4094 for $page (@$Pages) 4095 { 4096 push @$lines, ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); 4097 push @$lines, "<H2 ALIGN=\"Left\">$page->{name}</H2>\n"; 4098 PrintIndexPage($lines, $summary, $page, $name); 4099 } 4100} 4101 4102 4103#+++############################################################################ 4104# # 4105# Pass 2/3: handle style, menu, index, cross-reference # 4106# # 4107#---############################################################################ 4108 4109@lines2 = (); # whole document (2nd pass) 4110@lines3 = (); # whole document (3rd pass) 4111$in_menu = 0; # am I inside a menu 4112 4113while (@lines) { 4114 $_ = shift(@lines); 4115 # 4116 # special case (protected sections) 4117 # 4118 if (/^$PROTECTTAG/o) { 4119 push(@lines2, $_); 4120 next; 4121 } 4122 # 4123 # menu 4124 # 4125 if (/^\@menu\b/) 4126 { 4127 $in_menu = 1; 4128 $in_menu_listing = 1; 4129 push(@lines2, &debug("<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0> \n", __LINE__)); 4130 next; 4131 } 4132 if (/^\@end\s+menu\b/) 4133 { 4134 if ($in_menu_listing) 4135 { 4136 push(@lines2, &debug("</TABLE></BLOCKQUOTE>\n", __LINE__)); 4137 } 4138 else 4139 { 4140 push(@lines2, &debug("</BLOCKQUOTE>\n", __LINE__)); 4141 } 4142 $in_menu = 0; 4143 $in_menu_listing = 0; 4144 next; 4145 } 4146 if ($in_menu) 4147 { 4148 my ($node, $name, $descr); 4149 if (/^\*\s+($NODERE)::/o) 4150 { 4151 $node = $1; 4152 $descr = $'; 4153 } 4154 elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) 4155 { 4156 $name = $1; 4157 $node = $2; 4158 $descr = $'; 4159 } 4160 elsif (/^\*/) 4161 { 4162 warn "$ERROR Bad menu line: $_"; 4163 } 4164 else 4165 { 4166 if ($in_menu_listing) 4167 { 4168 $in_menu_listing = 0; 4169 push(@lines2, &debug("</TABLE>\n", __LINE__)); 4170 } 4171 # should be like verbatim -- preseve spaces, etc 4172 s/ /\ /g; 4173 $_ .= "<br>\n"; 4174 push(@lines2, $_); 4175 } 4176 if ($node) 4177 { 4178 if (! $in_menu_listing) 4179 { 4180 $in_menu_listing = 1; 4181 push(@lines2, &debug("<TABLE BORDER=0 CELLSPACING=0>\n", __LINE__)); 4182 } 4183 # look for continuation 4184 while ($lines[0] =~ /^\s+\w+/) 4185 { 4186 $descr .= shift(@lines); 4187 } 4188 &menu_entry($node, $name, $descr); 4189 } 4190 next; 4191 } 4192 # 4193 # printindex 4194 # 4195 PrintIndex(\@lines2, $2, $1), next 4196 if (/^<!--::(.*)::-->\@printindex\s+(\w+)/); 4197 # 4198 # simple style substitutions 4199 # 4200 $_ = &substitute_style($_); 4201 # 4202 # xref 4203 # 4204 while (/\@(x|px|info|)ref{([^{}]+)(}?)/) { 4205 # note: Texinfo may accept other characters 4206 ($type, $nodes, $full) = ($1, $2, $3); 4207 ($before, $after) = ($`, $'); 4208 if (! $full && $after) { 4209 warn "$ERROR Bad xref (no ending } on line): $_"; 4210 $_ = "$before$;0${type}ref\{$nodes$after"; 4211 next; # while xref 4212 } 4213 if ($type eq 'x') { 4214 $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} "; 4215 } elsif ($type eq 'px') { 4216 $type = "$T2H_WORDS->{$T2H_LANG}->{'see'} "; 4217 } elsif ($type eq 'info') { 4218 $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} Info"; 4219 } else { 4220 $type = ''; 4221 } 4222 unless ($full) { 4223 $next = shift(@lines); 4224 $next = &substitute_style($next); 4225 chop($nodes); # remove final newline 4226 if ($next =~ /\}/) { # split on 2 lines 4227 $nodes .= " $`"; 4228 $after = $'; 4229 } else { 4230 $nodes .= " $next"; 4231 $next = shift(@lines); 4232 $next = &substitute_style($next); 4233 chop($nodes); 4234 if ($next =~ /\}/) { # split on 3 lines 4235 $nodes .= " $`"; 4236 $after = $'; 4237 } else { 4238 warn "$ERROR Bad xref (no ending }): $_"; 4239 $_ = "$before$;0xref\{$nodes$after"; 4240 unshift(@lines, $next); 4241 next; # while xref 4242 } 4243 } 4244 } 4245 $nodes =~ s/\s+/ /g; # remove useless spaces 4246 @args = split(/\s*,\s*/, $nodes); 4247 $node = $args[0]; # the node is always the first arg 4248 $node = &normalise_node($node); 4249 $sec = $args[2] || $args[1] || $node2sec{$node}; 4250 $href = $node2href{$node}; 4251 if (@args == 5) { # reference to another manual 4252 $sec = $args[2] || $node; 4253 $man = $args[4] || $args[3]; 4254 $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} `$sec' in \@cite{$man}$after"; 4255 } elsif ($type =~ /Info/) { # inforef 4256 warn "$ERROR Wrong number of arguments: $_" unless @args == 3; 4257 ($nn, $_, $in) = @args; 4258 $_ = "${before}${type} file `$in', node `$nn'$after"; 4259 } elsif ($sec && $href && ! $T2H_SHORT_REF) { 4260 $_ = "${before}${type}"; 4261 $_ .= "$T2H_WORDS->{$T2H_LANG}->{'section'} " if ${type}; 4262 $_ .= &t2h_anchor('', $href, $sec) . $after; 4263 } 4264 elsif ($href) 4265 { 4266 $_ = "${before}${type} " . 4267 &t2h_anchor('', $href, $args[2] || $args[1] || $node) . 4268 $after; 4269 } 4270 else { 4271 warn "$ERROR Undefined node ($node): $_"; 4272 $_ = "$before$;0xref{$nodes}$after"; 4273 } 4274 } 4275 4276 # replace images 4277 s[\@image\s*{(.+?)}] 4278 { 4279 my @args = split (/\s*,\s*/, $1); 4280 my $base = $args[0]; 4281 my $image = 4282 LocateIncludeFile("$base.png") || 4283 LocateIncludeFile("$base.jpg") || 4284 LocateIncludeFile("$base.gif"); 4285 warn "$ERROR no image file for $base: $_" unless ($image && -e $image); 4286 "<IMG SRC=\"$image\" ALT=\"$base\">"; 4287 ($T2H_CENTER_IMAGE ? 4288 "<CENTER><IMG SRC=\"$image\" ALT=\"$base\"></CENTER>" : 4289 "<IMG SRC=\"$image\" ALT=\"$base\">"); 4290 }eg; 4291 4292 # 4293 # try to guess bibliography references or glossary terms 4294 # 4295 unless (/^<H\d><A NAME=\"SEC\d/) { 4296 if ($use_bibliography) { 4297 $done = ''; 4298 while (/$BIBRE/o) { 4299 ($pre, $what, $post) = ($`, $&, $'); 4300 $href = $bib2href{$what}; 4301 if (defined($href) && $post !~ /^[^<]*<\/A>/) { 4302 $done .= $pre . &t2h_anchor('', $href, $what); 4303 } else { 4304 $done .= "$pre$what"; 4305 } 4306 $_ = $post; 4307 } 4308 $_ = $done . $_; 4309 } 4310 if ($T2H_USE_GLOSSARY) { 4311 $done = ''; 4312 while (/\b\w+\b/) { 4313 ($pre, $what, $post) = ($`, $&, $'); 4314 $entry = $what; 4315 $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; 4316 $href = $gloss2href{$entry}; 4317 if (defined($href) && $post !~ /^[^<]*<\/A>/) { 4318 $done .= $pre . &t2h_anchor('', $href, $what); 4319 } else { 4320 $done .= "$pre$what"; 4321 } 4322 $_ = $post; 4323 } 4324 $_ = $done . $_; 4325 } 4326 } 4327 # otherwise 4328 push(@lines2, $_); 4329} 4330print "# end of pass 2\n" if $T2H_VERBOSE; 4331 4332# 4333# split style substitutions 4334# 4335while (@lines2) { 4336 $_ = shift(@lines2); 4337 # 4338 # special case (protected sections) 4339 # 4340 if (/^$PROTECTTAG/o) { 4341 push(@lines3, $_); 4342 next; 4343 } 4344 # 4345 # split style substitutions 4346 # 4347 $old = ''; 4348 while ($old ne $_) { 4349 $old = $_; 4350 if (/\@(\w+)\{/) { 4351 ($before, $style, $after) = ($`, $1, $'); 4352 if (defined($style_map{$style})) { 4353 $_ = $after; 4354 $text = ''; 4355 $after = ''; 4356 $failed = 1; 4357 while (@lines2) { 4358 if (/\}/) { 4359 $text .= $`; 4360 $after = $'; 4361 $failed = 0; 4362 last; 4363 } else { 4364 $text .= $_; 4365 $_ = shift(@lines2); 4366 } 4367 } 4368 if ($failed) { 4369 die "* Bad syntax (\@$style) after: $before\n"; 4370 } else { 4371 $text = &apply_style($style, $text); 4372 $_ = "$before$text$after"; 4373 } 4374 } 4375 } 4376 } 4377 # otherwise 4378 push(@lines3, $_); 4379} 4380print "# end of pass 3\n" if $T2H_VERBOSE; 4381 4382#+++############################################################################ 4383# # 4384# Pass 4: foot notes, final cleanup # 4385# # 4386#---############################################################################ 4387 4388@foot_lines = (); # footnotes 4389@doc_lines = (); # final document 4390$end_of_para = 0; # true if last line is <P> 4391 4392while (@lines3) { 4393 $_ = shift(@lines3); 4394 # 4395 # special case (protected sections) 4396 # 4397 if (/^$PROTECTTAG/o) { 4398 push(@doc_lines, $_); 4399 $end_of_para = 0; 4400 next; 4401 } 4402 # 4403 # footnotes 4404 # 4405 while (/\@footnote([^\{\s]+)\{/) { 4406 ($before, $d, $after) = ($`, $1, $'); 4407 $_ = $after; 4408 $text = ''; 4409 $after = ''; 4410 $failed = 1; 4411 while (@lines3) { 4412 if (/\}/) { 4413 $text .= $`; 4414 $after = $'; 4415 $failed = 0; 4416 last; 4417 } else { 4418 $text .= $_; 4419 $_ = shift(@lines3); 4420 } 4421 } 4422 if ($failed) { 4423 die "* Bad syntax (\@footnote) after: $before\n"; 4424 } else { 4425 $foot_num++; 4426 $docid = "DOCF$foot_num"; 4427 $footid = "FOOT$foot_num"; 4428 $foot = "($foot_num)"; 4429 push(@foot_lines, "<H3>" . &t2h_anchor($footid, "$d#$docid", $foot) . "</H3>\n"); 4430 $text = "<P>$text" unless $text =~ /^\s*<P>/; 4431 push(@foot_lines, "$text\n"); 4432 $_ = $before . &t2h_anchor($docid, "$docu_foot#$footid", $foot) . $after; 4433 } 4434 } 4435 # 4436 # remove unnecessary <P> 4437 # 4438 if (/^\s*<P>\s*$/) { 4439 next if $end_of_para++; 4440 } else { 4441 $end_of_para = 0; 4442 } 4443 # otherwise 4444 push(@doc_lines, $_); 4445} 4446 4447print "# end of pass 4\n" if $T2H_VERBOSE; 4448 4449#+++############################################################################ 4450# # 4451# Pass 5: print things # 4452# # 4453#---############################################################################ 4454 4455$T2H_L2H = &l2h_FinishToLatex if ($T2H_L2H); 4456$T2H_L2H = &l2h_ToHtml if ($T2H_L2H); 4457$T2H_L2H = &l2h_InitFromHtml if ($T2H_L2H); 4458 4459# fix node2up, node2prev, node2next, if desired 4460if ($has_top_command) 4461{ 4462 for $section (keys %sec2number) 4463 { 4464 $node = $sec2node{$section}; 4465 $node2up{$node} = Sec2UpNode($section) unless $node2up{$node}; 4466 $node2prev{$node} = Sec2PrevNode($section) unless $node2prev{$node}; 4467 $node2next{$node} = Sec2NextNode($section) unless $node2next{$node}; 4468 } 4469} 4470 4471# prepare %T2H_THISDOC 4472$T2H_THISDOC{fulltitle} = $value{'_title'} || $value{'_settitle'} || "Untitled Document"; 4473$T2H_THISDOC{title} = $value{'_settitle'} || $T2H_THISDOC{fulltitle}; 4474$T2H_THISDOC{author} = $value{'_author'}; 4475$T2H_THISDOC{subtitle} = $value{'_subtitle'}; 4476$T2H_THISDOC{shorttitle} = $value{'_shorttitle'}; 4477for $key (keys %T2H_THISDOC) 4478{ 4479 $_ = &substitute_style($T2H_THISDOC{$key}); 4480 &unprotect_texi; 4481 s/\s*$//; 4482 $T2H_THISDOC{$key} = $_; 4483} 4484 4485# if no sections, then simply print document as is 4486unless (@sections) 4487{ 4488 print "# Writing content into $docu_top_file \n" if $T2H_VERBOSE; 4489 open(FILE, "> $docu_top_file") 4490 || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; 4491 4492 &$T2H_print_page_head(\*FILE); 4493 $T2H_THIS_SECTION = \@doc_lines; 4494 t2h_print_lines(\*FILE); 4495 &$T2H_print_foot_navigation(\*FILE); 4496 &$T2H_print_page_foot(\*FILE); 4497 close(FILE); 4498 goto Finish; 4499} 4500 4501# initialize $T2H_HREF, $T2H_NAME 4502%T2H_HREF = 4503 ( 4504 'First' , sec_href($sections[0]), 4505 'Last', sec_href($sections[$#sections]), 4506 'About', $docu_about. '#SEC_About', 4507 ); 4508 4509# prepare TOC, OVERVIEW, TOP 4510$T2H_TOC = \@toc_lines; 4511$T2H_OVERVIEW = \@stoc_lines; 4512if ($has_top) 4513{ 4514 while (1) 4515 { 4516 $_ = shift @doc_lines; 4517 last if /$TOPEND/; 4518 push @$T2H_TOP, $_; 4519 } 4520 $T2H_HREF{'Top'} = $docu_top . '#SEC_Top'; 4521} 4522else 4523{ 4524 $T2H_HREF{'Top'} = $T2H_HREF{First}; 4525} 4526 4527$node2href{Top} = $T2H_HREF{Top}; 4528$T2H_HREF{Contents} = $docu_toc.'#SEC_Contents' if @toc_lines; 4529$T2H_HREF{Overview} = $docu_stoc.'#SEC_OVERVIEW' if @stoc_lines; 4530 4531# settle on index 4532if ($T2H_INDEX_CHAPTER) 4533{ 4534 $T2H_HREF{Index} = $node2href{normalise_node($T2H_INDEX_CHAPTER)}; 4535 warn "$ERROR T2H_INDEX_CHAPTER '$T2H_INDEX_CHAPTER' not found\n" 4536 unless $T2H_HREF{Index}; 4537} 4538if (! $T2H_HREF{Index} && $first_index_chapter) 4539{ 4540 $T2H_INDEX_CHAPTER = $first_index_chapter; 4541 $T2H_HREF{Index} = $node2href{$T2H_INDEX_CHAPTER}; 4542} 4543 4544print "# Using '" . clean_name($T2H_INDEX_CHAPTER) . "' as index page\n" 4545 if ($T2H_VERBOSE && $T2H_HREF{Index}); 4546 4547%T2H_NAME = 4548 ( 4549 'First', clean_name($sec2node{$sections[0]}), 4550 'Last', clean_name($sec2node{$sections[$#sections]}), 4551 'About', $T2H_WORDS->{$T2H_LANG}->{'About_Title'}, 4552 'Contents', $T2H_WORDS->{$T2H_LANG}->{'ToC_Title'}, 4553 'Overview', $T2H_WORDS->{$T2H_LANG}->{'Overview_Title'}, 4554 'Index' , clean_name($T2H_INDEX_CHAPTER), 4555 'Top', clean_name($T2H_TOP_HEADING || $T2H_THISDOC{'title'} || $T2H_THISDOC{'shorttitle'}), 4556 ); 4557 4558############################################################################# 4559# print frame and frame toc file 4560# 4561if ( $T2H_FRAMES ) 4562{ 4563 open(FILE, "> $docu_frame_file") 4564 || die "$ERROR: Can't open $docu_frame_file for writing: $!\n"; 4565 print "# Creating frame in $docu_frame_file ...\n" if $T2H_VERBOSE; 4566 &$T2H_print_frame(\*FILE); 4567 close(FILE); 4568 4569 open(FILE, "> $docu_toc_frame_file") 4570 || die "$ERROR: Can't open $docu_toc_frame_file for writing: $!\n"; 4571 print "# Creating toc frame in $docu_frame_file ...\n" if $T2H_VERBOSE; 4572 &$T2H_print_toc_frame(\*FILE); 4573 close(FILE); 4574} 4575 4576 4577############################################################################# 4578# print Top 4579# 4580open(FILE, "> $docu_top_file") 4581 || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; 4582&$T2H_print_page_head(\*FILE) unless ($T2H_SPLIT); 4583 4584if ($has_top) 4585{ 4586 print "# Creating Top in $docu_top_file ...\n" if $T2H_VERBOSE; 4587 $T2H_THIS_SECTION = $T2H_TOP; 4588 $T2H_HREF{This} = $T2H_HREF{Top}; 4589 $T2H_NAME{This} = $T2H_NAME{Top}; 4590 &$T2H_print_Top(\*FILE); 4591} 4592 4593close(FILE) if $T2H_SPLIT; 4594 4595############################################################################# 4596# Print sections 4597# 4598$T2H_NODE{Forward} = $sec2node{$sections[0]}; 4599$T2H_NAME{Forward} = &clean_name($sec2node{$sections[0]}); 4600$T2H_HREF{Forward} = sec_href($sections[0]); 4601$T2H_NODE{This} = 'Top'; 4602$T2H_NAME{This} = $T2H_NAME{Top}; 4603$T2H_HREF{This} = $T2H_HREF{Top}; 4604if ($T2H_SPLIT) 4605{ 4606 print "# writing " . scalar(@sections) . 4607 " sections in $docu_rdir$docu_name"."_[1..$doc_num]" 4608 if $T2H_VERBOSE; 4609 $previous = ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); 4610 undef $FH; 4611 $doc_num = 0; 4612} 4613else 4614{ 4615 print "# writing " . scalar(@sections) . " sections in $docu_top_file ..." 4616 if $T2H_VERBOSE; 4617 $FH = \*FILE; 4618 $previous = ''; 4619} 4620 4621$counter = 0; 4622# loop through sections 4623while ($section = shift(@sections)) 4624{ 4625 if ($T2H_SPLIT && ($T2H_SPLIT eq 'section' || $previous eq $CHAPTEREND)) 4626 { 4627 if ($FH) 4628 { 4629 #close previous page 4630 &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; 4631 &$T2H_print_page_foot($FH); 4632 close($FH); 4633 undef $FH; 4634 } 4635 } 4636 $T2H_NAME{Back} = $T2H_NAME{This}; 4637 $T2H_HREF{Back} = $T2H_HREF{This}; 4638 $T2H_NODE{Back} = $T2H_NODE{This}; 4639 $T2H_NAME{This} = $T2H_NAME{Forward}; 4640 $T2H_HREF{This} = $T2H_HREF{Forward}; 4641 $T2H_NODE{This} = $T2H_NODE{Forward}; 4642 if ($sections[0]) 4643 { 4644 $T2H_NODE{Forward} = $sec2node{$sections[0]}; 4645 $T2H_NAME{Forward} = &clean_name($T2H_NODE{Forward}); 4646 $T2H_HREF{Forward} = sec_href($sections[0]); 4647 } 4648 else 4649 { 4650 undef $T2H_HREF{Forward}, $T2H_NODE{Forward}, $T2H_NAME{Forward}; 4651 } 4652 4653 $node = $node2up{$T2H_NODE{This}}; 4654 $T2H_HREF{Up} = $node2href{$node}; 4655 if ($T2H_HREF{Up} eq $T2H_HREF{This} || ! $T2H_HREF{Up}) 4656 { 4657 $T2H_NAME{Up} = $T2H_NAME{Top}; 4658 $T2H_HREF{Up} = $T2H_HREF{Top}; 4659 $T2H_NODE{Up} = 'Up'; 4660 } 4661 else 4662 { 4663 $T2H_NAME{Up} = &clean_name($node); 4664 $T2H_NODE{Up} = $node; 4665 } 4666 4667 $node = $T2H_NODE{This}; 4668 $node = $node2prev{$node}; 4669 $T2H_NAME{Prev} = &clean_name($node); 4670 $T2H_HREF{Prev} = $node2href{$node}; 4671 $T2H_NODE{Prev} = $node; 4672 4673 $node = $T2H_NODE{This}; 4674 if ($node2up{$node} && $node2up{$node} ne 'Top'&& 4675 ($node2prev{$node} eq $T2H_NODE{Back} || ! $node2prev{$node})) 4676 { 4677 $node = $node2up{$node}; 4678 while ($node && $node ne $node2up{$node} && ! $node2prev{$node}) 4679 { 4680 $node = $node2up{$node}; 4681 } 4682 $node = $node2prev{$node} 4683 unless $node2up{$node} eq 'Top' || ! $node2up{$node}; 4684 } 4685 else 4686 { 4687 $node = $node2prev{$node}; 4688 } 4689 $T2H_NAME{FastBack} = &clean_name($node); 4690 $T2H_HREF{FastBack} = $node2href{$node}; 4691 $T2H_NODE{FastBack} = $node; 4692 4693 $node = $T2H_NODE{This}; 4694 $node = $node2next{$node}; 4695 $T2H_NAME{Next} = &clean_name($node); 4696 $T2H_HREF{Next} = $node2href{$node}; 4697 $T2H_NODE{Next} = $node; 4698 4699 $node = $T2H_NODE{This}; 4700 if ($node2up{$node} && $node2up{$node} ne 'Top'&& 4701 ($node2next{$node} eq $T2H_NODE{Forward} || ! $node2next{$node})) 4702 { 4703 $node = $node2up{$node}; 4704 while ($node && $node ne $node2up{$node} && ! $node2next{$node}) 4705 { 4706 $node = $node2up{$node}; 4707 } 4708 } 4709 $node = $node2next{$node}; 4710 $T2H_NAME{FastForward} = &clean_name($node); 4711 $T2H_HREF{FastForward} = $node2href{$node}; 4712 $T2H_NODE{FastForward} = $node; 4713 4714 if (! defined($FH)) 4715 { 4716 my $file = $T2H_HREF{This}; 4717 $file =~ s/\#.*$//; 4718 open(FILE, "> $docu_rdir$file") || 4719 die "$ERROR: Can't open $docu_rdir$file for writing: $!\n"; 4720 $FH = \*FILE; 4721 &$T2H_print_page_head($FH); 4722 t2h_print_label($FH); 4723 &$T2H_print_chapter_header($FH) if $T2H_SPLIT eq 'chapter'; 4724 } 4725 else 4726 { 4727 t2h_print_label($FH); 4728 } 4729 4730 $T2H_THIS_SECTION = []; 4731 while (@doc_lines) { 4732 $_ = shift(@doc_lines); 4733 last if ($_ eq $SECTIONEND || $_ eq $CHAPTEREND); 4734 push(@$T2H_THIS_SECTION, $_); 4735 } 4736 $previous = $_; 4737 &$T2H_print_section($FH); 4738 4739 if ($T2H_VERBOSE) 4740 { 4741 $counter++; 4742 print "." if $counter =~ /00$/; 4743 } 4744} 4745if ($T2H_SPLIT) 4746{ 4747 &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; 4748 &$T2H_print_page_foot($FH); 4749 close($FH); 4750} 4751print "\n" if $T2H_VERBOSE; 4752 4753############################################################################# 4754# Print ToC, Overview, Footnotes 4755# 4756undef $T2H_HREF{Prev}; 4757undef $T2H_HREF{Next}; 4758undef $T2H_HREF{Back}; 4759undef $T2H_HREF{Forward}; 4760undef $T2H_HREF{Up}; 4761 4762if (@foot_lines) 4763{ 4764 print "# writing Footnotes in $docu_foot_file...\n" if $T2H_VERBOSE; 4765 open (FILE, "> $docu_foot_file") || die "$ERROR: Can't open $docu_foot_file for writing: $!\n" 4766 if $T2H_SPLIT; 4767 $T2H_HREF{This} = $docu_foot; 4768 $T2H_NAME{This} = $T2H_WORDS->{$T2H_LANG}->{'Footnotes_Title'}; 4769 $T2H_THIS_SECTION = \@foot_lines; 4770 &$T2H_print_Footnotes(\*FILE); 4771 close(FILE) if $T2H_SPLIT; 4772} 4773 4774if (@toc_lines) 4775{ 4776 print "# writing Toc in $docu_toc_file...\n" if $T2H_VERBOSE; 4777 open (FILE, "> $docu_toc_file") || die "$ERROR: Can't open $docu_toc_file for writing: $!\n" 4778 if $T2H_SPLIT; 4779 $T2H_HREF{This} = $T2H_HREF{Contents}; 4780 $T2H_NAME{This} = $T2H_NAME{Contents}; 4781 $T2H_THIS_SECTION = \@toc_lines; 4782 &$T2H_print_Toc(\*FILE); 4783 close(FILE) if $T2H_SPLIT; 4784} 4785 4786if (@stoc_lines) 4787{ 4788 print "# writing Overview in $docu_stoc_file...\n" if $T2H_VERBOSE; 4789 open (FILE, "> $docu_stoc_file") || die "$ERROR: Can't open $docu_stoc_file for writing: $!\n" 4790 if $T2H_SPLIT; 4791 4792 $T2H_HREF{This} = $T2H_HREF{Overview}; 4793 $T2H_NAME{This} = $T2H_NAME{Overview}; 4794 $T2H_THIS_SECTION = \@stoc_lines; 4795 unshift @$T2H_THIS_SECTION, "<BLOCKQUOTE>\n"; 4796 push @$T2H_THIS_SECTION, "\n</BLOCKQUOTE>\n"; 4797 &$T2H_print_Overview(\*FILE); 4798 close(FILE) if $T2H_SPLIT; 4799} 4800 4801if ($about_body = &$T2H_about_body()) 4802{ 4803 print "# writing About in $docu_about_file...\n" if $T2H_VERBOSE; 4804 open (FILE, "> $docu_about_file") || die "$ERROR: Can't open $docu_about_file for writing: $!\n" 4805 if $T2H_SPLIT; 4806 4807 $T2H_HREF{This} = $T2H_HREF{About}; 4808 $T2H_NAME{This} = $T2H_NAME{About}; 4809 $T2H_THIS_SECTION = [$about_body]; 4810 &$T2H_print_About(\*FILE); 4811 close(FILE) if $T2H_SPLIT; 4812} 4813 4814unless ($T2H_SPLIT) 4815{ 4816 &$T2H_print_page_foot(\*FILE); 4817 close (FILE); 4818} 4819 4820Finish: 4821&l2h_FinishFromHtml if ($T2H_L2H); 4822&l2h_Finish if($T2H_L2H); 4823print "# that's all folks\n" if $T2H_VERBOSE; 4824 4825exit(0); 4826 4827#+++############################################################################ 4828# # 4829# Low level functions # 4830# # 4831#---############################################################################ 4832 4833sub LocateIncludeFile 4834{ 4835 my $file = shift; 4836 my $dir; 4837 4838 return $file if (-e $file && -r $file); 4839 foreach $dir (@T2H_INCLUDE_DIRS) 4840 { 4841 return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file"); 4842 } 4843 return undef; 4844} 4845 4846sub clean_name 4847{ 4848 local ($_); 4849 $_ = &remove_style($_[0]); 4850 &unprotect_texi; 4851 return $_; 4852} 4853 4854sub update_sec_num { 4855 local($name, $level) = @_; 4856 my $ret; 4857 4858 $level--; # here we start at 0 4859 if ($name =~ /^appendix/ || defined(@appendix_sec_num)) { 4860 # appendix style 4861 if (defined(@appendix_sec_num)) { 4862 &incr_sec_num($level, @appendix_sec_num); 4863 } else { 4864 @appendix_sec_num = ('A', 0, 0, 0); 4865 } 4866 $ret = join('.', @appendix_sec_num[0..$level]); 4867 } else { 4868 # normal style 4869 if (defined(@normal_sec_num)) 4870 { 4871 &incr_sec_num($level, @normal_sec_num); 4872 } 4873 else 4874 { 4875 @normal_sec_num = (1, 0, 0, 0); 4876 } 4877 $ret = join('.', @normal_sec_num[0..$level]); 4878 } 4879 4880 $ret .= "." if $level == 0; 4881 return $ret; 4882} 4883 4884sub incr_sec_num { 4885 local($level, $l); 4886 $level = shift(@_); 4887 $_[$level]++; 4888 foreach $l ($level+1 .. 3) { 4889 $_[$l] = 0; 4890 } 4891} 4892 4893sub Sec2UpNode 4894{ 4895 my $sec = shift; 4896 my $num = $sec2number{$sec}; 4897 4898 return '' unless $num; 4899 return 'Top' unless $num =~ /\.\d+/; 4900 $num =~ s/\.[^\.]*$//; 4901 $num = $num . '.' unless $num =~ /\./; 4902 return $sec2node{$number2sec{$num}}; 4903} 4904 4905sub Sec2PrevNode 4906{ 4907 my $sec = shift; 4908 my $num = $sec2number{$sec}; 4909 my ($i, $post); 4910 4911 if ($num =~ /(\w+)(\.$|$)/) 4912 { 4913 $num = $`; 4914 $i = $1; 4915 $post = $2; 4916 if ($i eq 'A') 4917 { 4918 $i = $normal_sec_num[0]; 4919 } 4920 elsif ($i ne '1') 4921 { 4922 # unfortunately, -- operator is not magical 4923 $i = chr(ord($i) + 1); 4924 } 4925 else 4926 { 4927 return ''; 4928 } 4929 return $sec2node{$number2sec{$num . $i . $post}} 4930 } 4931 return ''; 4932} 4933 4934sub Sec2NextNode 4935{ 4936 my $sec = shift; 4937 my $num = $sec2number{$sec}; 4938 my $i; 4939 4940 if ($num =~ /(\w+)(\.$|$)/) 4941 { 4942 $num = $`; 4943 $i = $1; 4944 $post = $2; 4945 if ($post eq '.' && $i eq $normal_sec_num[0]) 4946 { 4947 $i = 'A'; 4948 } 4949 else 4950 { 4951 $i++; 4952 } 4953 return $sec2node{$number2sec{$num . $i . $post}} 4954 } 4955 return ''; 4956} 4957 4958sub check { 4959 local($_, %seen, %context, $before, $match, $after); 4960 4961 while (<>) { 4962 if (/\@(\*|\.|\:|\@|\{|\})/) { 4963 $seen{$&}++; 4964 $context{$&} .= "> $_" if $T2H_VERBOSE; 4965 $_ = "$`XX$'"; 4966 redo; 4967 } 4968 if (/\@(\w+)/) { 4969 ($before, $match, $after) = ($`, $&, $'); 4970 if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address 4971 $seen{'e-mail address'}++; 4972 $context{'e-mail address'} .= "> $_" if $T2H_VERBOSE; 4973 } else { 4974 $seen{$match}++; 4975 $context{$match} .= "> $_" if $T2H_VERBOSE; 4976 } 4977 $match =~ s/^\@/X/; 4978 $_ = "$before$match$after"; 4979 redo; 4980 } 4981 } 4982 4983 foreach (sort(keys(%seen))) { 4984 if ($T2H_VERBOSE) { 4985 print "$_\n"; 4986 print $context{$_}; 4987 } else { 4988 print "$_ ($seen{$_})\n"; 4989 } 4990 } 4991} 4992 4993sub open { 4994 local($name) = @_; 4995 4996 ++$fh_name; 4997 if (open($fh_name, $name)) { 4998 unshift(@fhs, $fh_name); 4999 } else { 5000 warn "$ERROR Can't read file $name: $!\n"; 5001 } 5002} 5003 5004sub init_input { 5005 @fhs = (); # hold the file handles to read 5006 @input_spool = (); # spooled lines to read 5007 $fh_name = 'FH000'; 5008 &open($docu); 5009} 5010 5011sub next_line { 5012 local($fh, $line); 5013 5014 if (@input_spool) { 5015 $line = shift(@input_spool); 5016 return($line); 5017 } 5018 while (@fhs) { 5019 $fh = $fhs[0]; 5020 $line = <$fh>; 5021 return($line) if $line; 5022 close($fh); 5023 shift(@fhs); 5024 } 5025 return(undef); 5026} 5027 5028# used in pass 1, use &next_line 5029sub skip_until { 5030 local($tag) = @_; 5031 local($_); 5032 5033 while ($_ = &next_line) { 5034 return if /^\@end\s+$tag\s*$/; 5035 } 5036 die "* Failed to find '$tag' after: " . $lines[$#lines]; 5037} 5038 5039# used in pass 1 for l2h use &next_line 5040sub string_until { 5041 local($tag) = @_; 5042 local($_, $string); 5043 5044 while ($_ = &next_line) { 5045 return $string if /^\@end\s+$tag\s*$/; 5046# $_ =~ s/hbox/mbox/g; 5047 $string = $string.$_; 5048 } 5049 die "* Failed to find '$tag' after: " . $lines[$#lines]; 5050} 5051 5052# 5053# HTML stacking to have a better HTML output 5054# 5055 5056sub html_reset { 5057 @html_stack = ('html'); 5058 $html_element = 'body'; 5059} 5060 5061sub html_push { 5062 local($what) = @_; 5063 push(@html_stack, $html_element); 5064 $html_element = $what; 5065} 5066 5067sub html_push_if { 5068 local($what) = @_; 5069 push(@html_stack, $html_element) 5070 if ($html_element && $html_element ne 'P'); 5071 $html_element = $what; 5072} 5073 5074sub html_pop { 5075 $html_element = pop(@html_stack); 5076} 5077 5078sub html_pop_if { 5079 local($elt); 5080 5081 if (@_) { 5082 foreach $elt (@_) { 5083 if ($elt eq $html_element) { 5084 $html_element = pop(@html_stack) if @html_stack; 5085 last; 5086 } 5087 } 5088 } else { 5089 $html_element = pop(@html_stack) if @html_stack; 5090 } 5091} 5092 5093sub html_debug { 5094 local($what, $line) = @_; 5095 if ($T2H_DEBUG & $DEBUG_HTML) 5096 { 5097 $what = "\n" unless $what; 5098 return("<!-- $line @html_stack, $html_element -->$what") 5099 } 5100 return($what); 5101} 5102 5103# to debug the output... 5104sub debug { 5105 local($what, $line) = @_; 5106 return("<!-- $line -->$what") 5107 if $T2H_DEBUG & $DEBUG_HTML; 5108 return($what); 5109} 5110 5111sub SimpleTexi2Html 5112{ 5113 local $_ = $_[0]; 5114 &protect_texi; 5115 &protect_html; 5116 $_ = substitute_style($_); 5117 $_[0] = $_; 5118} 5119 5120sub normalise_node { 5121 local $_ = $_[0]; 5122 s/\s+/ /g; 5123 s/ $//; 5124 s/^ //; 5125 &protect_texi; 5126 &protect_html; 5127 $_ = substitute_style($_); 5128 $_[0] = $_; 5129} 5130 5131sub menu_entry 5132{ 5133 my ($node, $name, $descr) = @_; 5134 my ($href, $entry); 5135 5136 &normalise_node($node); 5137 $href = $node2href{$node}; 5138 if ($href) 5139 { 5140 $descr =~ s/^\s+//; 5141 $descr =~ s/\s*$//; 5142 $descr = SimpleTexi2Html($descr); 5143 if ($T2H_NUMBER_SECTIONS && !$T2H_NODE_NAME_IN_MENU && $node2sec{$node}) 5144 { 5145 $entry = $node2sec{$node}; 5146 $name = ''; 5147 } 5148 else 5149 { 5150 &normalise_node($name); 5151 $entry = ($name && ($name ne $node || ! $T2H_AVOID_MENU_REDUNDANCY) 5152 ? "$name : $node" : $node); 5153 } 5154 5155 if ($T2H_AVOID_MENU_REDUNDANCY && $descr) 5156 { 5157 my $clean_entry = $entry; 5158 $clean_entry =~ s/^.*? // if ($clean_entry =~ /^([A-Z]|\d+)\.[\d\.]* /); 5159 $clean_entry =~ s/[^\w]//g; 5160 my $clean_descr = $descr; 5161 $clean_descr =~ s/[^\w]//g; 5162 $descr = '' if ($clean_entry eq $clean_descr) 5163 } 5164 push(@lines2,&debug('<TR><TD ALIGN="left" VALIGN="TOP">' . 5165 &t2h_anchor('', $href, $entry) . 5166 '</TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">' . 5167 $descr . 5168 "</TD></TR>\n", __LINE__)); 5169 } 5170 elsif ($node =~ /^\(.*\)\w+/) 5171 { 5172 push(@lines2,&debug('<TR><TD ALIGN="left" VALIGN="TOP">' . 5173 $entry . 5174 '</TD><TD ALIGN="left" VALIGN="TOP">' . $descr . 5175 "</TD></TR>\n", __LINE__)) 5176 } 5177 else 5178 { 5179 warn "$ERROR Undefined node of menu_entry ($node): $_"; 5180 } 5181} 5182 5183sub do_ctrl { "^$_[0]" } 5184 5185sub do_email { 5186 local($addr, $text) = split(/,\s*/, $_[0]); 5187 5188 $text = $addr unless $text; 5189 &t2h_anchor('', "mailto:$addr", $text); 5190} 5191 5192sub do_sc 5193{ 5194 # l2h does this much better 5195 return &l2h_ToLatex("{\\sc ".&unprotect_html($_[0])."}") if ($T2H_L2H); 5196 return "\U$_[0]\E"; 5197} 5198 5199sub do_math 5200{ 5201 return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H); 5202 return "<EM>".$text."</EM>"; 5203} 5204 5205sub do_uref { 5206 local($url, $text, $only_text) = split(/,\s*/, $_[0]); 5207 5208 $text = $only_text if $only_text; 5209 $text = $url unless $text; 5210 &t2h_anchor('', $url, $text); 5211} 5212 5213sub do_url { &t2h_anchor('', $_[0], $_[0]) } 5214 5215sub do_acronym 5216{ 5217 return '<FONT SIZE="-1">' . $_[0] . '</FONT>'; 5218} 5219 5220sub do_accent 5221{ 5222 return "&$_[0]acute;" if $_[1] eq 'H'; 5223 return "$_[0]." if $_[1] eq 'dotaccent'; 5224 return "$_[0]*" if $_[1] eq 'ringaccent'; 5225 return "$_[0]".'[' if $_[1] eq 'tieaccent'; 5226 return "$_[0]".'(' if $_[1] eq 'u'; 5227 return "$_[0]_" if $_[1] eq 'ubaraccent'; 5228 return ".$_[0]" if $_[1] eq 'udotaccent'; 5229 return "$_[0]<" if $_[1] eq 'v'; 5230 return "&$_[0]cedil;" if $_[1] eq ','; 5231 return "$_[0]" if $_[1] eq 'dotless'; 5232 return undef; 5233} 5234 5235sub apply_style { 5236 local($texi_style, $text) = @_; 5237 local($style); 5238 5239 $style = $style_map{$texi_style}; 5240 if (defined($style)) { # known style 5241 if ($style =~ /^\"/) { # add quotes 5242 $style = $'; 5243 $text = "\`$text\'"; 5244 } 5245 if ($style =~ /^\&/) { # custom 5246 $style = $'; 5247 $text = &$style($text, $texi_style); 5248 } elsif ($style) { # good style 5249 $text = "<$style>$text</$style>"; 5250 } else { # no style 5251 } 5252 } else { # unknown style 5253 $text = undef; 5254 } 5255 return($text); 5256} 5257 5258# remove Texinfo styles 5259sub remove_style { 5260 local($_) = @_; 5261 1 while(s/\@\w+{([^\{\}]+)}/$1/g); 5262 return($_); 5263} 5264 5265sub remove_things 5266{ 5267 local ($_) = @_; 5268 s|\@(\w+)\{\}|$1|g; 5269 return $_; 5270} 5271 5272sub substitute_style { 5273 local($_) = @_; 5274 local($changed, $done, $style, $text); 5275 5276 &simple_substitutions; 5277 $changed = 1; 5278 while ($changed) { 5279 $changed = 0; 5280 $done = ''; 5281 while (/\@(\w+){([^\{\}]+)}/ || /\@(,){([^\{\}]+)}/) { 5282 $text = &apply_style($1, $2); 5283 if ($text) { 5284 $_ = "$`$text$'"; 5285 $changed = 1; 5286 } else { 5287 $done .= "$`\@$1"; 5288 $_ = "{$2}$'"; 5289 } 5290 } 5291 $_ = $done . $_; 5292 } 5293 return($_); 5294} 5295 5296sub t2h_anchor { 5297 local($name, $href, $text, $newline, $extra_attribs) = @_; 5298 local($result); 5299 5300 $result = "<A"; 5301 $result .= " NAME=\"$name\"" if $name; 5302 if ($href) 5303 { 5304 $href =~ s|^$T2H_HREF_DIR_INSTEAD_FILE|./| 5305 if ($T2H_HREF_DIR_INSTEAD_FILE); 5306 $result .= ($href =~ /\"/ ? " HREF='$href'" : " HREF=\"$href\""); 5307 } 5308 $result .= " $extra_attribs" if $extra_attribs; 5309 $result .= ">$text</A>"; 5310 $result .= "\n" if $newline; 5311 return($result); 5312} 5313 5314sub pretty_date { 5315 local(@MoY, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); 5316 5317 @MoY = ('January', 'February', 'March', 'April', 'May', 'June', 5318 'July', 'August', 'September', 'October', 'November', 'December'); 5319 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); 5320 $year += ($year < 70) ? 2000 : 1900; 5321 # obachman: Let's do it as the Americans do 5322 return("$MoY[$mon], $mday $year"); 5323} 5324 5325sub doc_href { 5326 local($num) = @_; 5327 5328 return("${docu_name}_$num.$docu_ext"); 5329} 5330 5331sub sec_href 5332{ 5333 return $node2href{$sec2node{$_[0]}}; 5334} 5335 5336sub next_doc { 5337 $docu_doc = &doc_href(++$doc_num); 5338} 5339 5340sub t2h_print_lines { 5341 my ($fh, $lines) = @_; 5342 local($_); 5343 $lines = $T2H_THIS_SECTION unless $lines; 5344 my $cnt = 0; 5345 for (@$lines) 5346 { 5347 $_ = l2h_FromHtml($_) if ($T2H_L2H); 5348 if (/^$PROTECTTAG/o) { 5349 $_ = $tag2pro{$_}; 5350 } else { 5351 &unprotect_texi; 5352 } 5353 print $fh $_; 5354 $cnt += split(/\W*\s+\W*/); 5355 } 5356 return $cnt; 5357} 5358 5359sub protect_texi { 5360 # protect @ { } ` ' 5361 s/\@\@/$;0/go; 5362 s/\@\{/$;1/go; 5363 s/\@\}/$;2/go; 5364 s/\@\`/$;3/go; 5365 s/\@\'/$;4/go; 5366} 5367 5368sub protect_html { 5369 local($what) = @_; 5370 # protect & < > 5371 $what =~ s/\&/\&\#38;/g; 5372 $what =~ s/\</\&\#60;/g; 5373 $what =~ s/\>/\&\#62;/g; 5374 # restore anything in quotes 5375 # this fixes my problem where I had: 5376 # < IMG SRC="leftarrow.gif" ALT="<--" > but what if I wanted < in my ALT text ?? 5377 # maybe byte stuffing or some other technique should be used. 5378 $what =~ s/\"([^\&]+)\&\#60;(.*)\"/"$1<$2"/g; 5379 $what =~ s/\"([^\&]+)\&\#62;(.*)\"/"$1>$2"/g; 5380 $what =~ s/\"([^\&]+)\&\#38;(.*)\"/"$1&$2"/g; 5381 # but recognize some HTML things 5382 $what =~ s/\&\#60;\/A\&\#62;/<\/A>/g; # </A> 5383 $what =~ s/\&\#60;A ([^\&]+)\&\#62;/<A $1>/g; # <A [^&]+> 5384 $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;/<IMG $1>/g; # <IMG [^&]+> 5385 return($what); 5386} 5387 5388sub unprotect_texi { 5389 s/$;0/\@/go; 5390 s/$;1/\{/go; 5391 s/$;2/\}/go; 5392 s/$;3/\`/go; 5393 s/$;4/\'/go; 5394} 5395 5396sub Unprotect_texi 5397{ 5398 local $_ = shift; 5399 &unprotect_texi; 5400 return($_); 5401} 5402 5403sub unprotect_html { 5404 local($what) = @_; 5405 $what =~ s/\&\#38;/\&/g; 5406 $what =~ s/\&\#60;/\</g; 5407 $what =~ s/\&\#62;/\>/g; 5408 return($what); 5409} 5410 5411sub t2h_print_label 5412{ 5413 my $fh = shift; 5414 my $href = shift || $T2H_HREF{This}; 5415 $href =~ s/.*#(.*)$/$1/; 5416 print $fh qq{<A NAME="$href"></A>\n}; 5417} 5418 5419############################################################################## 5420 5421 # These next few lines are legal in both Perl and nroff. 5422 5423.00 ; # finish .ig 5424 5425'di \" finish diversion--previous line must be blank 5426.nr nl 0-1 \" fake up transition to first page again 5427.nr % 0 \" start at page 1 5428'; __END__ ############# From here on it's a standard manual page ############ 5429.so /usr/local/man/man1/texi2html.1 5430