1#!@HAVE_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.in,v 1.2 2000/04/08 12:20:05 danny 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.61'; 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 # 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.inig 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.in,v 1.2 2000/04/08 12:20:05 danny 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# -debug 107# debugging: 0 -- no debugging, other values: see beginning of texi2html 108$T2H_DEBUG = 0; 109 110# -doctype 111# document type which is specified in header of html files 112$T2H_DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'; 113 114# -check 115# if set, only check files and give the list of all things that may be 116# Texinfo commands 117$T2H_CHECK = 0; 118 119# -expand 120# if set to "tex" (or, "info") expand @iftex and @tex (or, @ifinfo) sections 121# else, neither expand @iftex, @tex, nor @ifinfo sections 122$T2H_EXPAND = "info"; 123 124# - glossary 125#if set, uses section named `Footnotes' for glossary 126$T2H_USE_GLOSSARY = 0; 127 128# -invisible 129# if set, use $T2H_INVISIBLE_MARK to create invisible destination 130# anchors for index links (you can for instance use the invisible.xbm 131# file shipped with this program). This is a workaround for a known 132# bug of many WWW browsers, including netscape. 133# For me, it works fine without it -- on the contrary: if there, it 134# inserts space between headers and start of text (obachman 3/99) 135$T2H_INVISIBLE_MARK = ''; 136# $T2H_INVISIBLE_MARK = ' '; 137 138# -iso 139# if set, ISO8879 characters are used for special symbols (like copyright, etc) 140$T2H_USE_ISO = 0; 141 142# -I 143# list directories where @include files are searched for (besides the 144# directory of the doc file) additional '-I' args add to this list 145@T2H_INCLUDE_DIRS = ("."); 146 147# -top_file 148# uses file of this name for top-level file 149# extension is manipulated appropriately, if nessecary 150$T2H_TOP_FILE = "index.html"; 151 152# -menu 153# if set, show the Texinfo menus 154$T2H_SHOW_MENU = 1; 155 156# -number 157# if set, number sections, show sections ins menu 158$T2H_NUMBER_SECTIONS = 1; 159 160# -split section|chapter|none 161# if set to 'section' (resp. 'chapter') create one html file per (sub)section 162# (resp. chapter) and separate pages for Top, ToC, Overview, Index, 163# Glossary, About. 164# otherwise, create monolithic html file which contains whole document 165#$T2H_SPLIT = 'section'; 166$T2H_SPLIT = undef; 167 168# -section_navigation|-no-section_navigation 169# if set, then navigation panels are printed at the beginning of each section 170# and, possibly at the end (depending on whether or not there were more than 171# $T2H_WORDS_IN_PAGE words on page 172# This is most useful if yopu do not want to have section navigation 173# on -split chapter 174$T2H_SECTION_NAVIGATION = 1; 175 176# -subdir 177# if set put result files in this directory 178# if not set result files are put into current directory 179#$T2H_SUBDIR = 'html'; 180$T2H_SUBDIR = undef; 181 182# -short_extn 183# If this is set all HTML file will have extension ".htm" instead of 184# ".html". This is helpful when shipping the document to PC systems. 185$T2H_SHORTEXTN = 0; 186 187# -prefix 188# Set the output file prefix, prepended to all .html, .gif and .pl files. 189# By default, this is the basename of the document 190$T2H_PREFIX = ''; 191 192# -o filename 193# If set, generate monolithic document output html into $filename 194$T2H_OUT = ''; 195 196# -short_ref 197#if set cross-references are given without section numbers 198$T2H_SHORT_REF = 0; 199 200# -idx_sum 201# if value matches argument of @printindex, (say, $what) then file 202# $docu_name_$what.idx is created which contains lines of the form 203# $key\t$ref 204# sorted alphabetically with lines where $key 205$T2H_IDX_SUMMARY = ''; 206 207# -verbose 208# if set, chatter about what we are doing 209$T2H_VERBOSE = 0; 210 211# -lang 212# For page titles use $T2H_WORDS->{$T2H_LANG}->{...} as title. 213# To add a new language, supply list of titles (see $T2H_WORDS below). 214$T2H_LANG = 'english'; 215 216# -l2h 217# if set, uses latex2html for generation of math content 218$T2H_L2H = 0; 219 220###################### 221# The following options are only relevant if $T2H_L2H is set 222# 223# -l2h_l2h 224# name/location of latex2html progam 225$T2H_L2H_L2H = "latex2html"; 226 227# -l2h_skip 228# if set, skips actual call to latex2htm tries to reuse previously generated 229# content, instead 230$T2H_L2H_SKIP = 0; 231 232# -l2h_tmp 233# if set, l2h uses this directory for temporarary files. The path 234# leading to this directory may not contain a dot (i.e., a "."), 235# otherwise, l2h will fail 236$T2H_L2H_TMP = ''; 237 238# -l2h_keep 239# if set, keeps intermediate files (they all have the prefix $doc_l2h_) 240# of l2h for later reuse 241$T2H_L2H_KEEP = 1; 242 243############################################################################## 244# 245# The following can only be set in the init file 246# 247############################################################################## 248 249# if set, center @image by default 250# otherwise, do not center by default 251$T2H_CENTER_IMAGE = 1; 252 253# used as identation for block enclosing command @example, etc 254# If not empty, must be enclosed in <td></td> 255$T2H_EXAMPLE_INDENT_CELL = '<td> </td>'; 256# same as abov, only for @small 257$T2H_SMALL_EXAMPLE_INDENT_CELL = '<td> </td>'; 258# font size for @small 259$T2H_SMALL_FONT_SIZE = '-1'; 260 261 262######################################################################## 263# Language dependencies: 264# To add a new language extend T2H_WORDS hash and create $T2H_<...>_WORDS hash 265# To redefine one word, simply do: 266# $T2H_WORDS->{<language>}->{<word>} = 'whatever' in your personal init file. 267# 268$T2H_ENGLISH_WORDS = 269{ 270 # titles of pages 271 'ToC_Title' => 'Table of Contents', 272 'Overview_Title' => 'Short Table of Contents', 273 'Index_Title' => 'Index', 274 'About_Title' => 'About this document', 275 'Footnotes_Title' => 'Footnotes', 276 'See' => 'See', 277 'see' => 'see', 278 'section' => 'section', 279# If necessary, we could extend this as follows: 280# # text for buttons 281# 'Top_Button' => 'Top', 282# 'ToC_Button' => 'Contents', 283# 'Overview_Button' => 'Overview', 284# 'Index_button' => 'Index', 285# 'Back_Button' => 'Back', 286# 'FastBack_Button' => 'FastBack', 287# 'Prev_Button' => 'Prev', 288# 'Up_Button' => 'Up', 289# 'Next_Button' => 'Next', 290# 'Forward_Button' =>'Forward', 291# 'FastWorward_Button' => 'FastForward', 292# 'First_Button' => 'First', 293# 'Last_Button' => 'Last', 294# 'About_Button' => 'About' 295}; 296 297$T2H_GERMAN_WORDS = 298{ 299 'ToC_Title' => 'Inhaltsverzeichniss', 300 'Overview_Title' => 'Kurzes Inhaltsverzeichniss', 301 'Index_Title' => 'Index', 302 'About_Title' => 'Über dieses Dokument', 303 'Footnotes_Title' => 'Fußnoten', 304 'See' => 'Siehe', 305 'see' => 'siehe', 306 'section' => 'Abschnitt', 307}; 308 309$T2H_WORDS = 310{ 311 'english' => $T2H_ENGLISH_WORDS, 312 'german' => $T2H_GERMAN_WORDS 313}; 314 315######################################################################## 316# Control of Page layout: 317# You can make changes of the Page layout at two levels: 318# 1.) For small changes, it is often enough to change the value of 319# some global string/hash/array variables 320# 2.) For larger changes, reimplement one of the T2H_DEFAULT_<fnc>* routines, 321# give them another name, and assign them to the respective 322# $T2H_<fnc> variable. 323 324# As a general interface, the hashes T2H_HREF, T2H_NAME, T2H_NODE hold 325# href, html-name, node-name of 326# This -- current section (resp. html page) 327# Top -- top page ($T2H_TOP_FILE) 328# Contents -- Table of contents 329# Overview -- Short table of contents 330# Index -- Index page 331# About -- page which explain "navigation buttons" 332# First -- first node 333# Last -- last node 334# 335# Whether or not the following hash values are set, depends on the context 336# (all values are w.r.t. 'This' section) 337# Next -- next node of texinfo 338# Prev -- previous node of texinfo 339# Up -- up node of texinfo 340# Forward -- next node in reading order 341# Back -- previous node in reading order 342# FastForward -- if leave node, up and next, else next node 343# FastBackward-- if leave node, up and prev, else prev node 344# 345# Furthermore, the following global variabels are set: 346# $T2H_THISDOC{title} -- title as set by @setttile 347# $T2H_THISDOC{fulltitle} -- full title as set by @title... 348# $T2H_THISDOC{subtitle} -- subtitle as set by @subtitle 349# $T2H_THISDOC{author} -- author as set by @author 350# 351# and pointer to arrays of lines which need to be printed by t2h_print_lines 352# $T2H_OVERVIEW -- lines of short table of contents 353# $T2H_TOC -- lines of table of contents 354# $T2H_TOP -- lines of Top texinfo node 355# $T2H_THIS_SECTION -- lines of 'This' section 356 357# 358# There are the following subs which control the layout: 359# 360$T2H_print_section = \&T2H_DEFAULT_print_section; 361$T2H_print_Top_header = \&T2H_DEFAULT_print_Top_header; 362$T2H_print_Top_footer = \&T2H_DEFAULT_print_Top_footer; 363$T2H_print_Top = \&T2H_DEFAULT_print_Top; 364$T2H_print_Toc = \&T2H_DEFAULT_print_Toc; 365$T2H_print_Overview = \&T2H_DEFAULT_print_Overview; 366$T2H_print_Footnotes = \&T2H_DEFAULT_print_Footnotes; 367$T2H_print_About = \&T2H_DEFAULT_print_About; 368$T2H_print_misc_header = \&T2H_DEFAULT_print_misc_header; 369$T2H_print_misc_footer = \&T2H_DEFAULT_print_misc_footer; 370$T2H_print_misc = \&T2H_DEFAULT_print_misc; 371$T2H_print_chapter_header = \&T2H_DEFAULT_print_chapter_header; 372$T2H_print_chapter_footer = \&T2H_DEFAULT_print_chapter_footer; 373$T2H_print_page_head = \&T2H_DEFAULT_print_page_head; 374$T2H_print_page_foot = \&T2H_DEFAULT_print_page_foot; 375$T2H_print_head_navigation = \&T2H_DEFAULT_print_head_navigation; 376$T2H_print_foot_navigation = \&T2H_DEFAULT_print_foot_navigation; 377$T2H_button_icon_img = \&T2H_DEFAULT_button_icon_img; 378$T2H_print_navigation = \&T2H_DEFAULT_print_navigation; 379$T2H_about_body = \&T2H_DEFAULT_about_body; 380 381######################################################################## 382# Layout for html for every sections 383# 384sub T2H_DEFAULT_print_section 385{ 386 my $fh = shift; 387 local $T2H_BUTTONS = \@T2H_SECTION_BUTTONS; 388 &$T2H_print_head_navigation($fh) if $T2H_SECTION_NAVIGATION; 389 my $nw = t2h_print_lines($fh); 390 if ($T2H_SPLIT eq 'section' && $T2H_SECTION_NAVIGATION) 391 { 392 &$T2H_print_foot_navigation($fh, $nw); 393 } 394 else 395 { 396 print $fh '<HR SIZE="6">' . "\n"; 397 } 398} 399 400################################################################### 401# Layout of top-page I recommend that you use @ifnothtml, @ifhtml, 402# @html within the Top texinfo node to specify content of top-level 403# page. 404# 405# If you enclose everything in @ifnothtml, then title, subtitle, 406# author and overview is printed 407# T2H_HREF of Next, Prev, Up, Forward, Back are not defined 408# if $T2H_SPLIT then Top page is in its own html file 409sub T2H_DEFAULT_print_Top_header 410{ 411 &$T2H_print_page_head(@_) if $T2H_SPLIT; 412 t2h_print_label(@_); # this needs to be called, otherwise no label set 413 &$T2H_print_head_navigation(@_); 414} 415sub T2H_DEFAULT_print_Top_footer 416{ 417 &$T2H_print_foot_navigation(@_); 418 &$T2H_print_page_foot(@_) if $T2H_SPLIT; 419} 420sub T2H_DEFAULT_print_Top 421{ 422 my $fh = shift; 423 424 # for redefining navigation buttons use: 425 # local $T2H_BUTTONS = [...]; 426 # as it is, 'Top', 'Contents', 'Index', 'About' are printed 427 local $T2H_BUTTONS = \@T2H_MISC_BUTTONS; 428 &$T2H_print_Top_header($fh); 429 if ($T2H_THIS_SECTION) 430 { 431 # if top-level node has content, then print it 432 t2h_print_lines($fh, $T2H_THIS_SECTION) 433 } 434 else 435 { 436 # top-level node is fully enclosed in @ifnothtml 437 # print fulltitle, subtitle, author, Overview 438 print $fh 439 "<CENTER>\n<H1>" . 440 join("</H1>\n<H1>", split(/\n/, $T2H_THISDOC{fulltitle})) . 441 "</H1>\n"; 442 print $fh "<H2>$T2H_THISDOC{subtitle}</H2>\n" if $T2H_THISDOC{subtitle}; 443 print $fh "$T2H_THISDOC{author}\n" if $T2H_THISDOC{author}; 444 print $fh <<EOT; 445</CENTER> 446<HR> 447<P></P> 448<H2> Overview: </H2> 449<BLOCKQUOTE> 450EOT 451 t2h_print_lines($fh, $T2H_OVERVIEW); 452 print $fh "</BLOCKQUOTE>\n"; 453 } 454 &$T2H_print_Top_footer($fh); 455} 456 457################################################################### 458# Layout of Toc, Overview, and Footnotes pages 459# By default, we use "normal" layout 460# T2H_HREF of Next, Prev, Up, Forward, Back, etc are not defined 461# use: local $T2H_BUTTONS = [...] to redefine navigation buttons 462sub T2H_DEFAULT_print_Toc 463{ 464 return &$T2H_print_misc(@_); 465} 466sub T2H_DEFAULT_print_Overview 467{ 468 return &$T2H_print_misc(@_); 469} 470sub T2H_DEFAULT_print_Footnotes 471{ 472 return &$T2H_print_misc(@_); 473} 474sub T2H_DEFAULT_print_About 475{ 476 return &$T2H_print_misc(@_); 477} 478 479sub T2H_DEFAULT_print_misc_header 480{ 481 &$T2H_print_page_head(@_) if $T2H_SPLIT; 482 # this needs to be called, otherwise, no labels are set 483 t2h_print_label(@_); 484 &$T2H_print_head_navigation(@_); 485} 486sub T2H_DEFAULT_print_misc_footer 487{ 488 &$T2H_print_foot_navigation(@_); 489 &$T2H_print_page_foot(@_) if $T2H_SPLIT; 490} 491sub T2H_DEFAULT_print_misc 492{ 493 my $fh = shift; 494 local $T2H_BUTTONS = \@T2H_MISC_BUTTONS; 495 &$T2H_print_misc_header($fh); 496 print $fh "<H1>$T2H_NAME{This}</H1>\n"; 497 t2h_print_lines($fh); 498 &$T2H_print_misc_footer($fh); 499} 500 501################################################################### 502# chapter_header and chapter_footer are only called if 503# T2H_SPLIT eq 'chapter' 504# chapter_header: after print_page_header, before print_section 505# chapter_footer: after print_section of last section, before print_page_footer 506# 507# If you want to get rid of navigation stuff after each section, 508# redefine print_section such that it does not call print_navigation, 509# and put print_navigation into print_chapter_header 510@T2H_CHAPTER_BUTTONS = 511 ( 512 'FastBack', 'FastForward', ' ', 513 ' ', ' ', ' ', ' ', 514 'Top', 'Contents', 'Index', 'About', 515 ); 516 517sub T2H_DEFAULT_print_chapter_header 518{ 519 # nothing to do there, by default 520 if (! $T2H_SECTION_NAVIGATION) 521 { 522 my $fh = shift; 523 local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS; 524 &$T2H_print_navigation($fh); 525 print $fh "\n<HR SIZE=2>\n"; 526 } 527} 528 529sub T2H_DEFAULT_print_chapter_footer 530{ 531 local $T2H_BUTTONS = \@T2H_CHAPTER_BUTTONS; 532 &$T2H_print_navigation(@_); 533} 534################################################################### 535# Layout of standard header and footer 536# 537 538# Set the default body text, inserted between <BODY ... > 539$T2H_BODYTEXT = 'LANG="EN" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"'; 540# text inserted after <BODY ...> 541$T2H_AFTER_BODY_OPEN = ''; 542#text inserted before </BODY> 543$T2H_PRE_BODY_CLOSE = ''; 544# this is used in footer 545$T2H_ADDRESS = "by <I>$T2H_USER</I> " if $T2H_USER; 546$T2H_ADDRESS .= "on <I>$T2H_TODAY</I>"; 547# this is added inside <HEAD></HEAD> after <TITLE> and some META NAME stuff 548# can be used for <style> <script>, <meta> tags 549$T2H_EXTRA_HEAD = ''; 550 551sub T2H_DEFAULT_print_page_head 552{ 553 my $fh = shift; 554 my $longtitle = "$T2H_THISDOC{title}: $T2H_NAME{This}"; 555 print $fh <<EOT; 556$T2H_DOCTYPE 557<!-- Created on $T2H_TODAY by $THISPROG --> 558<!-- 559$T2H_AUTHORS 560--> 561<HTML> 562<HEAD> 563<TITLE>$longtitle</TITLE> 564 565<META NAME="description" CONTENT="$longtitle"> 566<META NAME="keywords" CONTENT="$longtitle"> 567<META NAME="resource-type" CONTENT="document"> 568<META NAME="distribution" CONTENT="global"> 569<META NAME="Generator" CONTENT="$THISPROG"> 570$T2H_EXTRA_HEAD 571</HEAD> 572 573<BODY $T2H_BODYTEXT> 574$T2H_AFTER_BODY_OPEN 575EOT 576} 577 578sub T2H_DEFAULT_print_page_foot 579{ 580 my $fh = shift; 581 print $fh <<EOT; 582<BR> 583<FONT SIZE="-1"> 584This document was generated 585$T2H_ADDRESS 586using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A> 587$T2H_PRE_BODY_CLOSE 588</BODY> 589</HTML> 590EOT 591} 592 593################################################################### 594# Layout of navigation panel 595 596# if this is set, then a vertical navigation panel is used 597$T2H_VERTICAL_HEAD_NAVIGATION = 0; 598sub T2H_DEFAULT_print_head_navigation 599{ 600 my $fh = shift; 601 if ($T2H_VERTICAL_HEAD_NAVIGATION) 602 { 603 print $fh <<EOT; 604<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"> 605<TR VALIGN="TOP"> 606<TD ALIGN="LEFT"> 607EOT 608 } 609 &$T2H_print_navigation($fh, $T2H_VERTICAL_HEAD_NAVIGATION); 610 if ($T2H_VERTICAL_HEAD_NAVIGATION) 611 { 612 print $fh <<EOT; 613</TD> 614<TD ALIGN="LEFT"> 615EOT 616 } 617 elsif ($T2H_SPLIT eq 'section') 618 { 619 print $fh "<HR SIZE=1>\n"; 620 } 621} 622 623# Specifies the minimum page length required before a navigation panel 624# is placed at the bottom of a page (the default is that of latex2html) 625# T2H_THIS_WORDS_IN_PAGE holds number of words of current page 626$T2H_WORDS_IN_PAGE = 300; 627sub T2H_DEFAULT_print_foot_navigation 628{ 629 my $fh = shift; 630 my $nwords = shift; 631 if ($T2H_VERTICAL_HEAD_NAVIGATION) 632 { 633 print $fh <<EOT; 634</TD> 635</TR> 636</TABLE> 637EOT 638 } 639 print $fh "<HR SIZE=1>\n"; 640 &$T2H_print_navigation($fh) if ($nwords >= $T2H_WORDS_IN_PAGE) 641} 642 643###################################################################### 644# navigation panel 645# 646# specify in this array which "buttons" should appear in which order 647# in the navigation panel for sections; use ' ' for empty buttons (space) 648@T2H_SECTION_BUTTONS = 649 ( 650 'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward', 651 ' ', ' ', ' ', ' ', 652 'Top', 'Contents', 'Index', 'About', 653 ); 654 655# buttons for misc stuff 656@T2H_MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About'); 657 658# insert here name of icon images for buttons 659# Icons are used, if $T2H_ICONS and resp. value are set 660%T2H_ACTIVE_ICONS = 661 ( 662 'Top', '', 663 'Contents', '', 664 'Overview', '', 665 'Index', '', 666 'Back', '', 667 'FastBack', '', 668 'Prev', '', 669 'Up', '', 670 'Next', '', 671 'Forward', '', 672 'FastForward', '', 673 'About' , '', 674 'First', '', 675 'Last', '', 676 ' ', '' 677 ); 678 679# insert here name of icon images for these, if button is inactive 680%T2H_PASSIVE_ICONS = 681 ( 682 'Top', '', 683 'Contents', '', 684 'Overview', '', 685 'Index', '', 686 'Back', '', 687 'FastBack', '', 688 'Prev', '', 689 'Up', '', 690 'Next', '', 691 'Forward', '', 692 'FastForward', '', 693 'About', '', 694 'First', '', 695 'Last', '', 696 ); 697 698# how to create IMG tag 699sub T2H_DEFAULT_button_icon_img 700{ 701 my $button = shift; 702 my $icon = shift; 703 my $name = shift; 704 return qq{<IMG SRC="$icon" BORDER="0" ALT="$button: $name" ALIGN="MIDDLE">}; 705} 706 707# Names of text as alternative for icons 708%T2H_NAVIGATION_TEXT = 709 ( 710 'Top', 'Top', 711 'Contents', 'Contents', 712 'Overview', 'Overview', 713 'Index', 'Index', 714 ' ', ' ', 715 'Back', ' < ', 716 'FastBack', ' << ', 717 'Prev', 'Prev', 718 'Up', ' Up ', 719 'Next', 'Next', 720 'Forward', ' > ', 721 'FastForward', ' >> ', 722 'About', ' ? ', 723 'First', ' |< ', 724 'Last', ' >| ' 725 ); 726 727sub T2H_DEFAULT_print_navigation 728{ 729 my $fh = shift; 730 my $vertical = shift; 731 my $spacing = 1; 732 print $fh "<TABLE CELLPADDING=$spacing CELLSPACING=$spacing BORDER=0>\n"; 733 734 print $fh "<TR>" unless $vertical; 735 for $button (@$T2H_BUTTONS) 736 { 737 print $fh qq{<TR VALIGN="TOP" ALIGN="LEFT">\n} if $vertical; 738 print $fh qq{<TD VALIGN="MIDDLE" ALIGN="LEFT">}; 739 740 if (ref($button) eq 'CODE') 741 { 742 &$button($fh, $vertical); 743 } 744 elsif ($button eq ' ') 745 { # handle space button 746 print $fh 747 $T2H_ICONS && $T2H_ACTIVE_ICONS{' '} ? 748 &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{' '}) : 749 $T2H_NAVIGATION_TEXT{' '}; 750 next; 751 } 752 elsif ($T2H_HREF{$button}) 753 { # button is active 754 print $fh 755 $T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? # use icon ? 756 t2h_anchor('', $T2H_HREF{$button}, # yes 757 &$T2H_button_icon_img($button, 758 $T2H_ACTIVE_ICONS{$button}, 759 $T2H_NAME{$button})) 760 : # use text 761 "[" . 762 t2h_anchor('', $T2H_HREF{$button}, $T2H_NAVIGATION_TEXT{$button}) . 763 "]"; 764 } 765 else 766 { # button is passive 767 print $fh 768 $T2H_ICONS && $T2H_PASSIVE_ICONS{$button} ? 769 &$T2H_button_icon_img($button, 770 $T2H_PASSIVE_ICONS{$button}, 771 $T2H_NAME{$button}) : 772 773 "[" . $T2H_NAVIGATION_TEXT{$button} . "]"; 774 } 775 print $fh "</TD>\n"; 776 print $fh "</TR>\n" if $vertical; 777 } 778 print $fh "</TR>" unless $vertical; 779 print $fh "</TABLE>\n"; 780} 781 782###################################################################### 783# About page 784# 785 786# T2H_PRE_ABOUT might be a function 787$T2H_PRE_ABOUT = <<EOT; 788This document was generated $T2H_ADDRESS 789using <A HREF="$T2H_HOMEPAGE"><I>texi2html</I></A> 790<P></P> 791EOT 792$T2H_AFTER_ABOUT = ''; 793 794sub T2H_DEFAULT_about_body 795{ 796 my $about; 797 if (ref($T2H_PRE_ABOUT) eq 'CODE') 798 { 799 $about = &$T2H_PRE_ABOUT(); 800 } 801 else 802 { 803 $about = $T2H_PRE_ABOUT; 804 } 805 $about .= <<EOT; 806The buttons in the navigation panels have the following meaning: 807<P></P> 808<table border = "1"> 809<TR> 810<TH> Button </TH> 811<TH> Name </TH> 812<TH> Go to </TH> 813<TH> From 1.2.3 go to</TH> 814</TR> 815EOT 816 817 for $button (@T2H_SECTION_BUTTONS) 818 { 819 next if $button eq ' ' || ref($button) eq 'CODE'; 820 $about .= <<EOT; 821<TR> 822<TD ALIGN="CENTER"> 823EOT 824 $about .= 825 ($T2H_ICONS && $T2H_ACTIVE_ICONS{$button} ? 826 &$T2H_button_icon_img($button, $T2H_ACTIVE_ICONS{$button}) : 827 " [" . $T2H_NAVIGATION_TEXT{$button} . "] "); 828 $about .= <<EOT; 829</TD> 830<TD ALIGN="CENTER"> 831$button 832</TD> 833<TD> 834$T2H_BUTTONS_GOTO{$button} 835</TD> 836<TD> 837$T2H_BUTTONS_EXAMPLE{$button} 838</TD> 839</TR> 840EOT 841 } 842 843 $about .= <<EOT; 844</TABLE> 845<P></P> 846where the <STRONG> Example </STRONG> assumes that the current position 847is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of 848the following structure: 849<UL> 850<LI> 1. Section One </LI> 851<UL> 852<LI>1.1 Subsection One-One</LI> 853<UL> 854<LI> ... </LI> 855</UL> 856<LI>1.2 Subsection One-Two</LI> 857<UL> 858<LI>1.2.1 Subsubsection One-Two-One 859</LI><LI>1.2.2 Subsubsection One-Two-Two 860</LI><LI>1.2.3 Subsubsection One-Two-Three <STRONG> 861<== Current Position </STRONG> 862</LI><LI>1.2.4 Subsubsection One-Two-Four 863</LI></UL> 864<LI>1.3 Subsection One-Three</LI> 865<UL> 866<LI> ... </LI> 867</UL> 868<LI>1.4 Subsection One-Four</LI> 869</UL> 870</UL> 871$T2H_AFTER_ABOUT 872EOT 873 return $about; 874} 875 876 877%T2H_BUTTONS_GOTO = 878 ( 879 'Top', 'cover (top) of document', 880 'Contents', 'table of contents', 881 'Overview', 'short table of contents', 882 'Index', 'concept index', 883 'Back', 'previous section in reading order', 884 'FastBack', 'previous or up-and-previous section ', 885 'Prev', 'previous section same level', 886 'Up', 'up section', 887 'Next', 'next section same level', 888 'Forward', 'next section in reading order', 889 'FastForward', 'next or up-and-next section', 890 'About' , 'this page', 891 'First', 'first section in reading order', 892 'Last', 'last section in reading order', 893 ); 894 895%T2H_BUTTONS_EXAMPLE = 896( 897 'Top', ' ', 898 'Contents', ' ', 899 'Overview', ' ', 900 'Index', ' ', 901 'Back', '1.2.2', 902 'FastBack', '1.1', 903 'Prev', '1.2.2', 904 'Up', '1.2', 905 'Next', '1.2.4', 906 'Forward', '1.2.4', 907 'FastForward', '1.3', 908 'About', ' ', 909 'First', '1.', 910 'Last', '1.2.4', 911); 912 913 914###################################################################### 915# from here on, its l2h init stuff 916# 917 918## initialization for latex2html as for Singular manual generation 919## obachman 3/99 920 921# 922# Options controlling Titles, File-Names, Tracing and Sectioning 923# 924$TITLE = ''; 925 926$SHORTEXTN = 0; 927 928$LONG_TITLES = 0; 929 930$DESTDIR = ''; # should be overwritten by cmd-line argument 931 932$NO_SUBDIR = 0;# should be overwritten by cmd-line argument 933 934$PREFIX = ''; # should be overwritten by cmd-line argument 935 936$AUTO_PREFIX = 0; # this is needed, so that prefix settings are used 937 938$AUTO_LINK = 0; 939 940$SPLIT = 0; 941 942$MAX_LINK_DEPTH = 0; 943 944$TMP = ''; # should be overwritten by cmd-line argument 945 946$DEBUG = 0; 947 948$VERBOSE = 1; 949 950# 951# Options controlling Extensions and Special Features 952# 953$HTML_VERSION = "3.2"; 954 955$TEXDEFS = 1; # we absolutely need that 956 957$EXTERNAL_FILE = ''; 958 959$SCALABLE_FONTS = 1; 960 961$NO_SIMPLE_MATH = 1; 962 963$LOCAL_ICONS = 1; 964 965$SHORT_INDEX = 0; 966 967$NO_FOOTNODE = 1; 968 969$ADDRESS = ''; 970 971$INFO = ''; 972 973# 974# Switches controlling Image Generation 975# 976$ASCII_MODE = 0; 977 978$NOLATEX = 0; 979 980$EXTERNAL_IMAGES = 0; 981 982$PS_IMAGES = 0; 983 984$NO_IMAGES = 0; 985 986$IMAGES_ONLY = 0; 987 988$REUSE = 2; 989 990$ANTI_ALIAS = 1; 991 992$ANTI_ALIAS_TEXT = 1; 993 994# 995#Switches controlling Navigation Panels 996# 997$NO_NAVIGATION = 1; 998$ADDRESS = ''; 999$INFO = 0; # 0 = do not make a "About this document..." section 1000 1001# 1002#Switches for Linking to other documents 1003# 1004# actuall -- we don't care 1005 1006$MAX_SPLIT_DEPTH = 0; # Stop making separate files at this depth 1007 1008$MAX_LINK_DEPTH = 0; # Stop showing child nodes at this depth 1009 1010$NOLATEX = 0; # 1 = do not pass unknown environments to Latex 1011 1012$EXTERNAL_IMAGES = 0; # 1 = leave the images outside the document 1013 1014$ASCII_MODE = 0; # 1 = do not use any icons or internal images 1015 1016# 1 = use links to external postscript images rather than inlined bitmap 1017# images. 1018$PS_IMAGES = 0; 1019$SHOW_SECTION_NUMBERS = 0; 1020 1021### Other global variables ############################################### 1022$CHILDLINE = ""; 1023 1024# This is the line width measured in pixels and it is used to right justify 1025# equations and equation arrays; 1026$LINE_WIDTH = 500; 1027 1028# Used in conjunction with AUTO_NAVIGATION 1029$WORDS_IN_PAGE = 300; 1030 1031# Affects ONLY the way accents are processed 1032$default_language = 'english'; 1033 1034# The value of this variable determines how many words to use in each 1035# title that is added to the navigation panel (see below) 1036# 1037$WORDS_IN_NAVIGATION_PANEL_TITLES = 0; 1038 1039# This number will determine the size of the equations, special characters, 1040# and anything which will be converted into an inlined image 1041# *except* "image generating environments" such as "figure", "table" 1042# or "minipage". 1043# Effective values are those greater than 0. 1044# Sensible values are between 0.1 - 4. 1045$MATH_SCALE_FACTOR = 1.5; 1046 1047# This number will determine the size of 1048# image generating environments such as "figure", "table" or "minipage". 1049# Effective values are those greater than 0. 1050# Sensible values are between 0.1 - 4. 1051$FIGURE_SCALE_FACTOR = 1.6; 1052 1053 1054# If both of the following two variables are set then the "Up" button 1055# of the navigation panel in the first node/page of a converted document 1056# will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set 1057# to some text which describes this external link. 1058$EXTERNAL_UP_LINK = ""; 1059$EXTERNAL_UP_TITLE = ""; 1060 1061# If this is set then the resulting HTML will look marginally better if viewed 1062# with Netscape. 1063$NETSCAPE_HTML = 1; 1064 1065# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0" 1066# Paper sizes has no effect other than in the time it takes to create inlined 1067# images and in whether large images can be created at all ie 1068# - larger paper sizes *MAY* help with large image problems 1069# - smaller paper sizes are quicker to handle 1070$PAPERSIZE = "a4"; 1071 1072# Replace "english" with another language in order to tell LaTeX2HTML that you 1073# want some generated section titles (eg "Table of Contents" or "References") 1074# to appear in a different language. Currently only "english" and "french" 1075# is supported but it is very easy to add your own. See the example in the 1076# file "latex2html.config" 1077$TITLES_LANGUAGE = "english"; 1078 10791; # This must be the last non-comment line 1080 1081# End File texi2html.init 1082###################################################################### 1083 1084require "$ENV{T2H_HOME}/texi2html.init" 1085 if ($0 =~ /\.pl$/ && 1086 -e "$ENV{T2H_HOME}/texi2html.init" && -r "$ENV{T2H_HOME}/texi2html.init"); 1087 1088#+++############################################################################ 1089# # 1090# Constants # 1091# # 1092#---############################################################################ 1093 1094$DEBUG_TOC = 1; 1095$DEBUG_INDEX = 2; 1096$DEBUG_BIB = 4; 1097$DEBUG_GLOSS = 8; 1098$DEBUG_DEF = 16; 1099$DEBUG_HTML = 32; 1100$DEBUG_USER = 64; 1101$DEBUG_L2H = 128; 1102 1103 1104$BIBRE = '\[[\w\/-]+\]'; # RE for a bibliography reference 1105$FILERE = '[\/\w.+-]+'; # RE for a file name 1106$VARRE = '[^\s\{\}]+'; # RE for a variable name 1107$NODERE = '[^,:]+'; # RE for a node name 1108$NODESRE = '[^:]+'; # RE for a list of node names 1109 1110$ERROR = "***"; # prefix for errors 1111$WARN = "**"; # prefix for warnings 1112 1113 # program home page 1114$PROTECTTAG = "_ThisIsProtected_"; # tag to recognize protected sections 1115 1116$CHAPTEREND = "<!-- End chapter -->\n"; # to know where a chpater ends 1117$SECTIONEND = "<!-- End section -->\n"; # to know where section ends 1118$TOPEND = "<!-- End top -->\n"; # to know where top ends 1119 1120 1121 1122# 1123# pre-defined indices 1124# 1125%predefined_index = ( 1126 'cp', 'c', 1127 'fn', 'f', 1128 'vr', 'v', 1129 'ky', 'k', 1130 'pg', 'p', 1131 'tp', 't', 1132 ); 1133 1134# 1135# valid indices 1136# 1137%valid_index = ( 1138 'c', 1, 1139 'f', 1, 1140 'v', 1, 1141 'k', 1, 1142 'p', 1, 1143 't', 1, 1144 ); 1145 1146# 1147# texinfo section names to level 1148# 1149%sec2level = ( 1150 'top', 0, 1151 'chapter', 1, 1152 'unnumbered', 1, 1153 'majorheading', 1, 1154 'chapheading', 1, 1155 'appendix', 1, 1156 'section', 2, 1157 'unnumberedsec', 2, 1158 'heading', 2, 1159 'appendixsec', 2, 1160 'appendixsection', 2, 1161 'subsection', 3, 1162 'unnumberedsubsec', 3, 1163 'subheading', 3, 1164 'appendixsubsec', 3, 1165 'subsubsection', 4, 1166 'unnumberedsubsubsec', 4, 1167 'subsubheading', 4, 1168 'appendixsubsubsec', 4, 1169 ); 1170 1171# 1172# accent map, TeX command to ISO name 1173# 1174%accent_map = ( 1175 '"', 'uml', 1176 '~', 'tilde', 1177 '^', 'circ', 1178 '`', 'grave', 1179 '\'', 'acute', 1180 ); 1181 1182# 1183# texinfo "simple things" (@foo) to HTML ones 1184# 1185%simple_map = ( 1186 # cf. makeinfo.c 1187 "*", "<BR>", # HTML+ 1188 " ", " ", 1189 "\t", " ", 1190 "-", "­", # soft hyphen 1191 "\n", "\n", 1192 "|", "", 1193 'tab', '<\/TD><TD>', 1194 # spacing commands 1195 ":", "", 1196 "!", "!", 1197 "?", "?", 1198 ".", ".", 1199 "-", "", 1200 ); 1201 1202# 1203# texinfo "things" (@foo{}) to HTML ones 1204# 1205%things_map = ( 1206 'TeX', 'TeX', 1207 'br', '<P>', # paragraph break 1208 'bullet', '*', 1209 'copyright', '(C)', 1210 'dots', '<small>...<\/small>', 1211 'enddots', '<small>....<\/small>', 1212 'equiv', '==', 1213 'error', 'error-->', 1214 'expansion', '==>', 1215 'minus', '-', 1216 'point', '-!-', 1217 'print', '-|', 1218 'result', '=>', 1219 'today', $T2H_TODAY, 1220 'aa', 'å', 1221 'AA', 'Å', 1222 'ae', 'æ', 1223 'oe', 'œ', 1224 'AE', 'Æ', 1225 'OE', 'Œ', 1226 'o', 'ø', 1227 'O', 'Ø', 1228 'ss', 'ß', 1229 'l', '\/l', 1230 'L', '\/L', 1231 'exclamdown', '¡', 1232 'questiondown', '¿', 1233 'pounds', '£' 1234 ); 1235 1236# 1237# texinfo styles (@foo{bar}) to HTML ones 1238# 1239%style_map = ( 1240 'acronym', '&do_acronym', 1241 'asis', '', 1242 'b', 'B', 1243 'cite', 'CITE', 1244 'code', 'CODE', 1245 'command', 'CODE', 1246 'ctrl', '&do_ctrl', # special case 1247 'dfn', 'EM', # DFN tag is illegal in the standard 1248 'dmn', '', # useless 1249 'email', '&do_email', # insert a clickable email address 1250 'emph', 'EM', 1251 'env', 'CODE', 1252 'file', '"TT', # will put quotes, cf. &apply_style 1253 'i', 'I', 1254 'kbd', 'KBD', 1255 'key', 'KBD', 1256 'math', '&do_math', 1257 'option', '"SAMP', # will put quotes, cf. &apply_style 1258 'r', '', # unsupported 1259 'samp', '"SAMP', # will put quotes, cf. &apply_style 1260 'sc', '&do_sc', # special case 1261 'strong', 'STRONG', 1262 't', 'TT', 1263 'titlefont', '', # useless 1264 'uref', '&do_uref', # insert a clickable URL 1265 'url', '&do_url', # insert a clickable URL 1266 'var', 'VAR', 1267 'w', '', # unsupported 1268 'H', '&do_accent', 1269 'dotaccent', '&do_accent', 1270 'ringaccent','&do_accent', 1271 'tieaccent', '&do_accent', 1272 'u','&do_accent', 1273 'ubaraccent','&do_accent', 1274 'udotaccent','&do_accent', 1275 'v', '&do_accent', 1276 ',', '&do_accent', 1277 'dotless', '&do_accent' 1278 ); 1279 1280# 1281# texinfo format (@foo/@end foo) to HTML ones 1282# 1283%format_map = ( 1284 'quotation', 'BLOCKQUOTE', 1285 # lists 1286 'itemize', 'UL', 1287 'enumerate', 'OL', 1288 # poorly supported 1289 'flushleft', 'PRE', 1290 'flushright', 'PRE', 1291 ); 1292 1293# 1294# an eval of these $complex_format_map->{what}->[0] yields beginning 1295# an eval of these $complex_format_map->{what}->[1] yieleds end 1296$complex_format_map = 1297{ 1298 example => 1299 [ 1300 q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td><pre>"}, 1301 q{'</pre></td></tr></table>'} 1302 ], 1303 smallexample => 1304 [ 1305 q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre>"}, 1306 q{'</FONT></pre></td></tr></table>'} 1307 ], 1308 display => 1309 [ 1310 q{"<TABLE><tr>$T2H_EXAMPLE_INDENT_CELL<td><pre " . 'style="font-family: serif">'}, 1311 q{'</pre></td></tr></table>'} 1312 ], 1313 smalldisplay => 1314 [ 1315 q{"<TABLE><tr>$T2H_SMALL_EXAMPLE_INDENT_CELL<td><FONT SIZE=$T2H_SMALL_FONT_SIZE><pre " . 'style="font-family: serif">'}, 1316 q{'</pre></FONT></td></tr></table>'} 1317 ] 1318}; 1319 1320$complex_format_map->{lisp} = $complex_format_map->{example}; 1321$complex_format_map->{smalllisp} = $complex_format_map->{smallexample}; 1322$complex_format_map->{format} = $complex_format_map->{display}; 1323$complex_format_map->{smallformat} = $complex_format_map->{smalldisplay}; 1324 1325# 1326# texinfo definition shortcuts to real ones 1327# 1328%def_map = ( 1329 # basic commands 1330 'deffn', 0, 1331 'defvr', 0, 1332 'deftypefn', 0, 1333 'deftypevr', 0, 1334 'defcv', 0, 1335 'defop', 0, 1336 'deftp', 0, 1337 # basic x commands 1338 'deffnx', 0, 1339 'defvrx', 0, 1340 'deftypefnx', 0, 1341 'deftypevrx', 0, 1342 'defcvx', 0, 1343 'defopx', 0, 1344 'deftpx', 0, 1345 # shortcuts 1346 'defun', 'deffn Function', 1347 'defmac', 'deffn Macro', 1348 'defspec', 'deffn {Special Form}', 1349 'defvar', 'defvr Variable', 1350 'defopt', 'defvr {User Option}', 1351 'deftypefun', 'deftypefn Function', 1352 'deftypevar', 'deftypevr Variable', 1353 'defivar', 'defcv {Instance Variable}', 1354 'defmethod', 'defop Method', 1355 # x shortcuts 1356 'defunx', 'deffnx Function', 1357 'defmacx', 'deffnx Macro', 1358 'defspecx', 'deffnx {Special Form}', 1359 'defvarx', 'defvrx Variable', 1360 'defoptx', 'defvrx {User Option}', 1361 'deftypefunx', 'deftypefnx Function', 1362 'deftypevarx', 'deftypevrx Variable', 1363 'defivarx', 'defcvx {Instance Variable}', 1364 'defmethodx', 'defopx Method', 1365 ); 1366 1367# 1368# things to skip 1369# 1370%to_skip = ( 1371 # comments 1372 'c', 1, 1373 'comment', 1, 1374 'ifnotinfo', 1, 1375 'ifnottex', 1, 1376 'ifhtml', 1, 1377 'end ifhtml', 1, 1378 'end ifnotinfo', 1, 1379 'end ifnottex', 1, 1380 # useless 1381 'detailmenu', 1, 1382 'direntry', 1, 1383 'contents', 1, 1384 'shortcontents', 1, 1385 'summarycontents', 1, 1386 'footnotestyle', 1, 1387 'end ifclear', 1, 1388 'end ifset', 1, 1389 'titlepage', 1, 1390 'end titlepage', 1, 1391 # unsupported commands (formatting) 1392 'afourpaper', 1, 1393 'cropmarks', 1, 1394 'finalout', 1, 1395 'headings', 1, 1396 'sp', 1, 1397 'need', 1, 1398 'page', 1, 1399 'setchapternewpage', 1, 1400 'everyheading', 1, 1401 'everyfooting', 1, 1402 'evenheading', 1, 1403 'evenfooting', 1, 1404 'oddheading', 1, 1405 'oddfooting', 1, 1406 'smallbook', 1, 1407 'vskip', 1, 1408 'filbreak', 1, 1409 'paragraphindent', 1, 1410 # unsupported formats 1411 'cartouche', 1, 1412 'end cartouche', 1, 1413 'group', 1, 1414 'end group', 1, 1415 ); 1416 1417#+++############################################################################ 1418# # 1419# Argument parsing, initialisation # 1420# # 1421#---############################################################################ 1422 1423# 1424# flush stdout and stderr after every write 1425# 1426select(STDERR); 1427$| = 1; 1428select(STDOUT); 1429$| = 1; 1430 1431%value = (); # hold texinfo variables, see also -D 1432 1433$use_bibliography = 1; 1434$use_acc = 1; 1435$usage = <<EOT; 1436This is $THISPROG 1437To convert a Texinfo file to HMTL: $0 [options] file 1438 where options can be: 1439 -expand [info,tex] : expand info/tex sections 1440 -glossary : handle a glossary 1441 -invisible <name> : use <name> as an invisible anchor 1442 -D<name> : define <name> as if with \@set 1443 -I <dir> : search also for files in <dir> 1444 -init_file <file> : use <file> for texi2html and latex2html initialization 1445 -index_file <file> : use <file> as index file 1446 -menu : handle menus 1447 -monolithic : cancels out -split option 1448 -l2h : use latex2html for \@math, \@tex, and \@sc 1449 -l2h_latex2html <prog> : use <prog> as latex2html program 1450 (default: 'latex2html') 1451 -l2h_tmp <dir> : use <dir> as temp dir for latex2html 1452 -l2h_clean : remove temporary files generated by l2h extension 1453 -l2h_skip : skip latex2html run (needs temporary files) 1454 -number : number sections 1455 -o file : output into monlithic <file> 1456 -section_navigation : use navigation panel for section 1457 -no-section_navigation : do not use navigation panel for sections 1458 -split section|chapter : split on section or chapter 1459 -split_{node|chapter} : split on section or chapter 1460 -short_ref : cross references without section numbers 1461 -subdir dir : put HTML files into subdir <dir> 1462 (default 'html') 1463 -usage, --help : display these usage instructions and exit immediately 1464 -verbose : verbose output 1465 -version, --version : display version number and exit immediately 1466To check converted files: $0 -check [-verbose] files 1467EOT 1468# Not currently usaged 1469# -sidx : index jump label to top of section 1470 1471my $home = $ENV{HOME}; 1472defined($home) or $home = ''; 1473foreach $i ('/usr/local/etc/texi2htmlrc', "$home/.texi2htmlrc") { 1474 if (-f $i) { 1475 print "# reading initialization file from $i\n" 1476 if ($T2H_VERBOSE); 1477 require($i); 1478 } 1479} 1480 1481while (@ARGV && $ARGV[0] =~ /^-/) { 1482 $_ = shift(@ARGV); 1483 if (/^-acc$/) { $use_acc = 1; next; } 1484 if (/^-D(.+)?$/) { $value{$1 || shift(@ARGV)} = 1; next; } 1485 if (/^-d(?:ebug)?(\d+)?$/) { $T2H_DEBUG = $1 || shift(@ARGV); next; } 1486 if (/^-doctype$/) { $T2H_DOCTYPE = shift(@ARGV); next; } 1487 if (/^-c(?:heck)?$/) { $T2H_CHECK = 1; next; } 1488 if (/^-e(?:xpand)?$/) { $T2H_EXPAND = shift(@ARGV); next; } 1489 if (/^-g(?:lossary)?$/) { $T2H_USE_GLOSSARY = 1; next; } 1490 if (/^-id(?:x_sum)?$/) { $T2H_IDX_SUMMARY = shift(@ARGV); next; } 1491 if (/^-i(?:nvisible)?$/) { $T2H_INVISIBLE_MARK = shift(@ARGV); next; } 1492 if (/^-I(.+)?$/) { push(@T2H_INCLUDE_DIRS, $1 || shift(@ARGV)); next; } 1493 if (/^-iso$/) { $T2H_USE_ISO = 1; next; } 1494 if (/^-init_file$/) 1495 { 1496 $init_file = shift(@ARGV); 1497 if (-f $init_file) 1498 { 1499 print "# reading initialization file from $init_file\n" 1500 if ($T2H_VERBOSE); 1501 require($init_file); 1502 } 1503 else 1504 { 1505 print "$ERROR Error: can't read init file $int_file\n"; 1506 $init_file = ''; 1507 } 1508 next; 1509 } 1510 if (/^-l(ang)?$/) { $T2H_LANG = shift(@ARGV); next;} 1511 if (/^-l2h$/) { $T2H_L2H = 1; next; } 1512 if (/^-l2h_l2h$/) { $T2H_L2H_L2H = shift(@ARGV); next; } 1513 if (/^-l2h_skip$/) { $T2H_L2H_SKIP= 1; next; } 1514 if (/^-l2h_tmp$/) { $T2H_L2H_TMP = shift(@ARGV); next; } 1515 if (/^-l2h_clean$/) { $T2H_L2H_CLEAN= 1; next; } 1516 if (/^-m(?:enu)?$/) { $T2H_SHOW_MENU = 1; next; } 1517 if (/^-nu(?:mber)?$/) { $T2H_NUMBER_SECTIONS = 1; next; } 1518 if (/^-o(?:ut_file)?$/) { $T2H_OUT = shift (@ARGV); 1519 undef $T2H_SPLIT; next;} 1520 if (/^-p(?:refix)?$/) { $T2H_PREFIX = shift(@ARGV); next; } 1521 if (/^-su(?:bdir)?$/) { $T2H_SUBDIR = shift(@ARGV); next; } 1522 if (/^-short_e(?:xtn)?$/) { $T2H_SHORTEXTN = 1; next; } 1523 if (/^-short_r(?:ef)?$/) { $T2H_SHORT_REF = 1; next; } 1524 # The following is because we want to remain compatible with 1525 # texi2html versions 1.5x and earlier while also allowing 1526 # `-s(plit)? (n(ode)?|c(hapter)?)' which 1.60beta used. It's 1527 # important to remain compatible with 1.5x because many build 1528 # scripts use its syntax. If anything, the 1.60beta syntax could 1529 # be dropped. 1530 if (/^-mono(?:lith(?:ic)?)?$/) { $T2H_SPLIT = undef; next; } 1531 if (/^-s(?:plit)?(_?)(n(?:ode)?|c(?:hapter)?)?$/) { 1532 if ($2 =~ /^n/) { 1533 # 1.5x syntax. 1534 $T2H_SPLIT = 'node'; 1535 } elsif (("$1$2" eq '') && ($ARGV[0] =~ /^(?:no|none|node|section|chapter)$/i)) { 1536 # 1.60beta syntax. 1537 $T2H_SPLIT = shift(@ARGV); 1538 } else { 1539 # 1.5x syntax. 1540 $T2H_SPLIT = 'chapter'; 1541 } 1542 next; 1543 } 1544 if (/^-t(?:op_file)?$/) { $T2H_TOP_FILE = shift (@ARGV); next;} 1545 if (/^-v(?:erbose)?$/) { $T2H_VERBOSE = 1; next; } 1546 if (/^-no_v(?:erbose)?$/) { $T2H_VERBOSE = 0; next; } 1547 if (/^-section_navigation$/) { $T2H_SECTION_NAVIGATION = 1; next; } 1548 if (/^-no-section_navigation$/) { undef $T2H_SECTION_NAVIGATION; next; } 1549 if (/^--?vers(?:ion)?$/) { print "$THISPROG\n"; exit;} 1550 if (/^-(?:usage|-help)/) { print "$usage"; exit; } 1551 die "Unknown option: $_\n$usage"; 1552} 1553if ($T2H_CHECK) { 1554 die "Need file to check\n$usage" unless @ARGV > 0; 1555 ✓ 1556 exit; 1557} 1558 1559if ($T2H_EXPAND eq 'info') 1560{ 1561 $to_skip{'ifinfo'} = 1; 1562 $to_skip{'end ifinfo'} = 1; 1563} 1564elsif ($T2H_EXPAND eq 'tex') 1565{ 1566 $to_skip{'iftex'} = 1; 1567 $to_skip{'end iftex'} = 1; 1568 1569} 1570 1571$T2H_INVISIBLE_MARK = '<IMG SRC="invisible.xbm">' if $T2H_INVISIBLE_MARK eq 'xbm'; 1572 1573# 1574# file name buisness 1575# 1576die "Need exactly one file to translate\n$usage" unless @ARGV == 1; 1577$docu = shift(@ARGV); 1578if ($docu =~ /.*\//) { 1579 chop($docu_dir = $&); 1580 $docu_name = $'; 1581} else { 1582 $docu_dir = '.'; 1583 $docu_name = $docu; 1584} 1585unshift(@T2H_INCLUDE_DIRS, $docu_dir); 1586$docu_name =~ s/\.te?x(i|info)?$//; # basename of the document 1587$docu_name = $T2H_PREFIX if ($T2H_PREFIX); 1588 1589# subdir 1590if ($T2H_SUBDIR && ! $T2H_OUT) 1591{ 1592 $T2H_SUBDIR =~ s|/*$||; 1593 unless (-d "$T2H_SUBDIR" && -w "$T2H_SUBDIR") 1594 { 1595 if ( mkdir($T2H_SUBDIR, oct(755))) 1596 { 1597 print "# created directory $T2H_SUBDIR\n" if ($T2H_VERBOSE); 1598 } 1599 else 1600 { 1601 warn "$ERROR can't create directory $T2H_SUBDIR. Put results into current directory\n"; 1602 $T2H_SUBDIR = ''; 1603 } 1604 } 1605} 1606 1607if ($T2H_SUBDIR && ! $T2H_OUT) 1608{ 1609 $docu_rdir = "$T2H_SUBDIR/"; 1610 print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); 1611} 1612else 1613{ 1614 if ($T2H_OUT && $T2H_OUT =~ m|(.*)/|) 1615 { 1616 $docu_rdir = "$1/"; 1617 print "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); 1618 } 1619 else 1620 { 1621 print "# putting result files into current directory \n" if ($T2H_VERBOSE); 1622 $docu_rdir = ''; 1623 } 1624} 1625 1626# extension 1627if ($T2H_SHORTEXTN) 1628{ 1629 $docu_ext = "htm"; 1630} 1631else 1632{ 1633 $docu_ext = "html"; 1634} 1635if ($T2H_TOP_FILE =~ /\..*$/) 1636{ 1637 $T2H_TOP_FILE = $`.".$docu_ext"; 1638} 1639else 1640{ 1641 $T2H_TOP_FILE .= ".$docu_ext"; 1642} 1643 1644# result files 1645if (! $T2H_OUT && ($T2H_SPLIT =~ /section/i || $T2H_SPLIT =~ /node/i)) 1646{ 1647 $T2H_SPLIT = 'section'; 1648} 1649elsif (! $T2H_OUT && $T2H_SPLIT =~ /chapter/i) 1650{ 1651 $T2H_SPLIT = 'chapter' 1652} 1653else 1654{ 1655 undef $T2H_SPLIT; 1656} 1657 1658$docu_doc = "$docu_name.$docu_ext"; # document's contents 1659$docu_doc_file = "$docu_rdir$docu_doc"; 1660if ($T2H_SPLIT) 1661{ 1662 $docu_toc = "${docu_name}_toc.$docu_ext"; # document's table of contents 1663 $docu_stoc = "${docu_name}_ovr.$docu_ext"; # document's short toc 1664 $docu_foot = "${docu_name}_fot.$docu_ext"; # document's footnotes 1665 $docu_about = "${docu_name}_abt.$docu_ext"; # about this document 1666 $docu_top = $T2H_TOP_FILE; 1667} 1668else 1669{ 1670 if ($T2H_OUT) 1671 { 1672 $docu_doc = $T2H_OUT; 1673 $docu_doc =~ s|.*/||; 1674 } 1675 $docu_toc = $docu_foot = $docu_stoc = $docu_about = $docu_top = $docu_doc; 1676} 1677 1678$docu_toc_file = "$docu_rdir$docu_toc"; 1679$docu_stoc_file = "$docu_rdir$docu_stoc"; 1680$docu_foot_file = "$docu_rdir$docu_foot"; 1681$docu_about_file = "$docu_rdir$docu_about"; 1682$docu_top_file = "$docu_rdir$docu_top"; 1683 1684# 1685# variables 1686# 1687$value{'html'} = 1; # predefine html (the output format) 1688$value{'texi2html'} = $THISVERSION; # predefine texi2html (the translator) 1689# _foo: internal to track @foo 1690foreach ('_author', '_title', '_subtitle', 1691 '_settitle', '_setfilename') { 1692 $value{$_} = ''; # prevent -w warnings 1693} 1694%node2sec = (); # node to section name 1695%sec2node = (); # section to node name 1696%sec2number = (); # section to number 1697%number2sec = (); # number to section 1698%idx2node = (); # index keys to node 1699%node2href = (); # node to HREF 1700%node2next = (); # node to next 1701%node2prev = (); # node to prev 1702%node2up = (); # node to up 1703%bib2href = (); # bibliography reference to HREF 1704%gloss2href = (); # glossary term to HREF 1705@sections = (); # list of sections 1706%tag2pro = (); # protected sections 1707 1708# 1709# initial indexes 1710# 1711$bib_num = 0; 1712$foot_num = 0; 1713$gloss_num = 0; 1714$idx_num = 0; 1715$sec_num = 0; 1716$doc_num = 0; 1717$html_num = 0; 1718 1719# 1720# can I use ISO8879 characters? (HTML+) 1721# 1722if ($T2H_USE_ISO) { 1723 $things_map{'bullet'} = "•"; 1724 $things_map{'copyright'} = "©"; 1725 $things_map{'dots'} = "…"; 1726 $things_map{'equiv'} = "≡"; 1727 $things_map{'expansion'} = "→"; 1728 $things_map{'point'} = "∗"; 1729 $things_map{'result'} = "⇒"; 1730} 1731 1732# 1733# read texi2html extensions (if any) 1734# 1735$extensions = 'texi2html.ext'; # extensions in working directory 1736if (-f $extensions) { 1737 print "# reading extensions from $extensions\n" if $T2H_VERBOSE; 1738 require($extensions); 1739} 1740($progdir = $0) =~ s/[^\/]+$//; 1741if ($progdir && ($progdir ne './')) { 1742 $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory 1743 if (-f $extensions) { 1744 print "# reading extensions from $extensions\n" if $T2H_VERBOSE; 1745 require($extensions); 1746 } 1747} 1748 1749 1750# 1751# Check Language 1752# 1753if (! exists $T2H_WORDS->{$T2H_LANG}) 1754{ 1755 warn "$ERROR: Language specs for '$T2H_LANG' do not exists. Reverting to 'english'\n"; 1756 $T2H_LANG = 'english' 1757} 1758print "# reading from $docu\n" if $T2H_VERBOSE; 1759 1760######################################################################### 1761# 1762# latex2html stuff 1763# 1764# latex2html conversions consist of three stages: 1765# 1) ToLatex: Put "latex" code into a latex file 1766# 2) ToHtml: Use latex2html to generate corresponding html code and images 1767# 3) FromHtml: Extract generated code and images from latex2html run 1768# 1769 1770########################## 1771# default settings 1772# 1773 1774# defaults for files and names 1775 1776sub l2h_Init 1777{ 1778 local($root) = @_; 1779 1780 return 0 unless ($root); 1781 1782 $l2h_name = "${root}_l2h"; 1783 1784 $l2h_latex_file = "$docu_rdir${l2h_name}.tex"; 1785 $l2h_cache_file = "${docu_rdir}l2h_cache.pm"; 1786 $T2H_L2H_L2H = "latex2html" unless ($T2H_L2H_L2H); 1787 1788 # destination dir -- generated images are put there, should be the same 1789 # as dir of enclosing html document -- 1790 $l2h_html_file = "$docu_rdir${l2h_name}.html"; 1791 $l2h_prefix = "${l2h_name}_"; 1792 return 1; 1793} 1794 1795 1796########################## 1797# 1798# First stage: Generation of Latex file 1799# Initialize with: l2h_InitToLatex 1800# Add content with: l2h_ToLatex($text) --> HTML placeholder comment 1801# Finish with: l2h_FinishToLatex 1802# 1803 1804$l2h_latex_preample = <<EOT; 1805% This document was automatically generated by the l2h extenstion of texi2html 1806% DO NOT EDIT !!! 1807\\documentclass{article} 1808\\usepackage{html} 1809\\begin{document} 1810EOT 1811 1812$l2h_latex_closing = <<EOT; 1813\\end{document} 1814EOT 1815 1816# return used latex 1, if l2h could be initalized properly, 0 otherwise 1817sub l2h_InitToLatex 1818{ 1819 %l2h_to_latex = (); 1820 unless ($T2H_L2H_SKIP) 1821 { 1822 unless (open(L2H_LATEX, ">$l2h_latex_file")) 1823 { 1824 warn "$ERROR Error l2h: Can't open latex file '$latex_file' for writing\n"; 1825 return 0; 1826 } 1827 print "# l2h: use ${l2h_latex_file} as latex file\n" if ($T2H_VERBOSE); 1828 print L2H_LATEX $l2h_latex_preample; 1829 } 1830 # open database for caching 1831 l2h_InitCache(); 1832 $l2h_latex_count = 0; 1833 $l2h_to_latex_count = 0; 1834 $l2h_cached_count = 0; 1835 return 1; 1836} 1837 1838# print text (1st arg) into latex file (if not already there), return 1839# HTML commentary which can be later on replaced by the latex2html 1840# generated text 1841sub l2h_ToLatex 1842{ 1843 my($text) = @_; 1844 my($count); 1845 1846 $l2h_to_latex_count++; 1847 $text =~ s/(\s*)$//; 1848 1849 # try whether we can cache it 1850 my $cached_text = l2h_FromCache($text); 1851 if ($cached_text) 1852 { 1853 $l2h_cached_count++; 1854 return $cached_text; 1855 } 1856 1857 # try whether we have text already on things to do 1858 unless ($count = $l2h_to_latex{$text}) 1859 { 1860 $count = $l2h_latex_count; 1861 $l2h_latex_count++; 1862 $l2h_to_latex{$text} = $count; 1863 $l2h_to_latex[$count] = $text; 1864 unless ($T2H_L2H_SKIP) 1865 { 1866 print L2H_LATEX "\\begin{rawhtml}\n"; 1867 print L2H_LATEX "<!-- l2h_begin ${l2h_name} ${count} -->\n"; 1868 print L2H_LATEX "\\end{rawhtml}\n"; 1869 1870 print L2H_LATEX "$text\n"; 1871 1872 print L2H_LATEX "\\begin{rawhtml}\n"; 1873 print L2H_LATEX "<!-- l2h_end ${l2h_name} ${count} -->\n"; 1874 print L2H_LATEX "\\end{rawhtml}\n"; 1875 } 1876 } 1877 return "<!-- l2h_replace ${l2h_name} ${count} -->"; 1878} 1879 1880# print closing into latex file and close it 1881sub l2h_FinishToLatex 1882{ 1883 local ($reused); 1884 1885 $reused = $l2h_to_latex_count - $l2h_latex_count - $l2h_cached_count; 1886 unless ($T2H_L2H_SKIP) 1887 { 1888 print L2H_LATEX $l2h_latex_closing; 1889 close(L2H_LATEX); 1890 } 1891 print "# l2h: finished to latex ($l2h_cached_count cached, $reused reused, $l2h_latex_count contents)\n" if ($T2H_VERBOSE); 1892 unless ($l2h_latex_count) 1893 { 1894 l2h_Finish(); 1895 return 0; 1896 } 1897 return 1; 1898} 1899 1900################################### 1901# Second stage: Use latex2html to generate corresponding html code and images 1902# 1903# l2h_ToHtml([$l2h_latex_file, [$l2h_html_dir]]): 1904# Call latex2html on $l2h_latex_file 1905# Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir 1906# Return 1, on success 1907# 0, otherwise 1908# 1909sub l2h_ToHtml 1910{ 1911 local($call, $ext, $root, $dotbug); 1912 1913 if ($T2H_L2H_SKIP) 1914 { 1915 print "# l2h: skipping latex2html run\n" if ($T2H_VERBOSE); 1916 return 1; 1917 } 1918 1919 # Check for dot in directory where dvips will work 1920 if ($T2H_L2H_TMP) 1921 { 1922 if ($T2H_L2H_TMP =~ /\./) 1923 { 1924 warn "$ERROR Warning l2h: l2h_tmp dir contains a dot. Use /tmp, instead\n"; 1925 $dotbug = 1; 1926 } 1927 } 1928 else 1929 { 1930 if (&getcwd =~ /\./) 1931 { 1932 warn "$ERROR Warning l2h: current dir contains a dot. Use /tmp as l2h_tmp dir \n"; 1933 $dotbug = 1; 1934 } 1935 } 1936 # fix it, if necessary and hope that it works 1937 $T2H_L2H_TMP = "/tmp" if ($dotbug); 1938 1939 $call = $T2H_L2H_L2H; 1940 # use init file, if specified 1941 $call = $call . " -init_file " . $init_file if ($init_file && -f $init_file); 1942 # set output dir 1943 $call .= ($docu_rdir ? " -dir $docu_rdir" : " -no_subdir"); 1944 # use l2h_tmp, if specified 1945 $call = $call . " -tmp $T2H_L2H_TMP" if ($T2H_L2H_TMP); 1946 # options we want to be sure of 1947 $call = $call ." -address 0 -info 0 -split 0 -no_navigation -no_auto_link"; 1948 $call = $call ." -prefix ${l2h_prefix} $l2h_latex_file"; 1949 1950 print "# l2h: executing '$call'\n" if ($T2H_VERBOSE); 1951 if (system($call)) 1952 { 1953 warn "l2h ***Error: '${call}' did not succeed\n"; 1954 return 0; 1955 } 1956 else 1957 { 1958 print "# l2h: latex2html finished successfully\n" if ($T2H_VERBOSE); 1959 return 1; 1960 } 1961} 1962 1963# this is directly pasted over from latex2html 1964sub getcwd { 1965 local($_) = `pwd`; 1966 1967 die "'pwd' failed (out of memory?)\n" 1968 unless length; 1969 chop; 1970 $_; 1971} 1972 1973 1974########################## 1975# Third stage: Extract generated contents from latex2html run 1976# Initialize with: l2h_InitFromHtml 1977# open $l2h_html_file for reading 1978# reads in contents into array indexed by numbers 1979# return 1, on success -- 0, otherwise 1980# Extract Html code with: l2h_FromHtml($text) 1981# replaces in $text all previosuly inserted comments by generated html code 1982# returns (possibly changed) $text 1983# Finish with: l2h_FinishFromHtml 1984# closes $l2h_html_dir/$l2h_name.".$docu_ext" 1985 1986sub l2h_InitFromHtml 1987{ 1988 local($h_line, $h_content, $count, %l2h_img); 1989 1990 if (! open(L2H_HTML, "<${l2h_html_file}")) 1991 { 1992 print "$ERROR Error l2h: Can't open ${l2h_html_file} for reading\n"; 1993 return 0; 1994 } 1995 print "# l2h: use ${l2h_html_file} as html file\n" if ($T2H_VERBOSE); 1996 1997 $l2h_html_count = 0; 1998 1999 while ($h_line = <L2H_HTML>) 2000 { 2001 if ($h_line =~ /^<!-- l2h_begin $l2h_name ([0-9]+) -->/) 2002 { 2003 $count = $1; 2004 $h_content = ""; 2005 while ($h_line = <L2H_HTML>) 2006 { 2007 if ($h_line =~ /^<!-- l2h_end $l2h_name $count -->/) 2008 { 2009 chomp $h_content; 2010 chomp $h_content; 2011 $l2h_html_count++; 2012 $h_content = l2h_ToCache($count, $h_content); 2013 $l2h_from_html[$count] = $h_content; 2014 $h_content = ''; 2015 last; 2016 } 2017 $h_content = $h_content.$h_line; 2018 } 2019 if ($hcontent) 2020 { 2021 print "$ERROR Warning l2h: l2h_end $l2h_name $count not found\n" 2022 if ($T2H_VERBOSE); 2023 close(L2H_HTML); 2024 return 0; 2025 } 2026 } 2027 } 2028 print "# l2h: Got $l2h_html_count of $l2h_latex_count html contents\n" 2029 if ($T2H_VERBOSE); 2030 2031 close(L2H_HTML); 2032 return 1; 2033} 2034 2035sub l2h_FromHtml 2036{ 2037 local($text) = @_; 2038 local($done, $to_do, $count); 2039 2040 $to_do = $text; 2041 2042 while ($to_do =~ /([^\000]*)<!-- l2h_replace $l2h_name ([0-9]+) -->([^\000]*)/) 2043 { 2044 $to_do = $1; 2045 $count = $2; 2046 $done = $3.$done; 2047 2048 $done = "<!-- l2h_end $l2h_name $count -->".$done 2049 if ($T2H_DEBUG & $DEBUG_L2H); 2050 2051 $done = &l2h_ExtractFromHtml($count) . $done; 2052 2053 $done = "<!-- l2h_begin $l2h_name $count -->".$done 2054 if ($T2H_DEBUG & $DEBUG_L2H); 2055 } 2056 return $to_do.$done; 2057} 2058 2059 2060sub l2h_ExtractFromHtml 2061{ 2062 local($count) = @_; 2063 2064 return $l2h_from_html[$count] if ($l2h_from_html[$count]); 2065 2066 if ($count >= 0 && $count < $l2h_latex_count) 2067 { 2068 # now we are in trouble 2069 local($l_l2h, $_); 2070 2071 $l2h_extract_error++; 2072 print "$ERROR l2h: can't extract content $count from html\n" 2073 if ($T2H_VERBOSE); 2074 # try simple (ordinary) substition (without l2h) 2075 $l_l2h = $T2H_L2H; 2076 $T2H_L2H = 0; 2077 $_ = $l2h_to_latex{$count}; 2078 $_ = &substitute_style($_); 2079 &unprotect_texi; 2080 $_ = "<!-- l2h: ". __LINE__ . " use texi2html -->" . $_ 2081 if ($T2H_DEBUG & $DEBUG_L2H); 2082 $T2H_L2H = $l_l2h; 2083 return $_; 2084 } 2085 else 2086 { 2087 # now we have been incorrectly called 2088 $l2h_range_error++; 2089 print "$ERROR l2h: Request of $count content which is out of valide range [0,$l2h_latex_count)\n"; 2090 return "<!-- l2h: ". __LINE__ . " out of range count $count -->" 2091 if ($T2H_DEBUG & $DEBUG_L2H); 2092 return "<!-- l2h: out of range count $count -->"; 2093 } 2094} 2095 2096sub l2h_FinishFromHtml 2097{ 2098 if ($T2H_VERBOSE) 2099 { 2100 if ($l2h_extract_error + $l2h_range_error) 2101 { 2102 print "# l2h: finished from html ($l2h_extract_error extract and $l2h_range_error errors)\n"; 2103 } 2104 else 2105 { 2106 print "# l2h: finished from html (no errors)\n"; 2107 } 2108 } 2109} 2110 2111sub l2h_Finish 2112{ 2113 l2h_StoreCache(); 2114 if ($T2H_L2H_CLEAN) 2115 { 2116 print "# l2h: removing temporary files generated by l2h extension\n" 2117 if $T2H_VERBOSE; 2118 while (<"$docu_rdir$l2h_name"*>) 2119 { 2120 unlink $_; 2121 } 2122 } 2123 print "# l2h: Finished\n" if $T2H_VERBOSE; 2124 return 1; 2125} 2126 2127############################## 2128# stuff for l2h caching 2129# 2130 2131# I tried doing this with a dbm data base, but it did not store all 2132# keys/values. Hence, I did as latex2html does it 2133sub l2h_InitCache 2134{ 2135 if (-r "$l2h_cache_file") 2136 { 2137 my $rdo = do "$l2h_cache_file"; 2138 warn("$ERROR l2h Error: could not load $docu_rdir$l2h_cache_file: $@\n") 2139 unless ($rdo); 2140 } 2141} 2142 2143sub l2h_StoreCache 2144{ 2145 return unless $l2h_latex_count; 2146 2147 my ($key, $value); 2148 open(FH, ">$l2h_cache_file") || return warn"$ERROR l2h Error: could not open $docu_rdir$l2h_cache_file for writing: $!\n"; 2149 2150 2151 while (($key, $value) = each %l2h_cache) 2152 { 2153 # escape stuff 2154 $key =~ s|/|\\/|g; 2155 $key =~ s|\\\\/|\\/|g; 2156 # weird, a \ at the end of the key results in an error 2157 # maybe this also broke the dbm database stuff 2158 $key =~ s|\\$|\\\\|; 2159 $value =~ s/\|/\\\|/g; 2160 $value =~ s/\\\\\|/\\\|/g; 2161 $value =~ s|\\\\|\\\\\\\\|g; 2162 print FH "\n\$l2h_cache_key = q/$key/;\n"; 2163 print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n"; 2164 } 2165 print FH "1;"; 2166 close(FH); 2167} 2168 2169# return cached html, if it exists for text, and if all pictures 2170# are there, as well 2171sub l2h_FromCache 2172{ 2173 my $text = shift; 2174 my $cached = $l2h_cache{$text}; 2175 if ($cached) 2176 { 2177 while ($cached =~ m/SRC="(.*?)"/g) 2178 { 2179 unless (-e "$docu_rdir$1") 2180 { 2181 return undef; 2182 } 2183 } 2184 return $cached; 2185 } 2186 return undef; 2187} 2188 2189# insert generated html into cache, move away images, 2190# return transformed html 2191$maximage = 1; 2192sub l2h_ToCache 2193{ 2194 my $count = shift; 2195 my $content = shift; 2196 my @images = ($content =~ /SRC="(.*?)"/g); 2197 my ($src, $dest); 2198 2199 for $src (@images) 2200 { 2201 $dest = $l2h_img{$src}; 2202 unless ($dest) 2203 { 2204 my $ext; 2205 if ($src =~ /.*\.(.*)$/ && $1 ne $docu_ext) 2206 { 2207 $ext = $1; 2208 } 2209 else 2210 { 2211 warn "$ERROR: L2h image $src has invalid extension\n"; 2212 next; 2213 } 2214 while (-e "$docu_rdir${docu_name}_$maximage.$ext") { $maximage++;} 2215 $dest = "${docu_name}_$maximage.$ext"; 2216 system("cp -f $docu_rdir$src $docu_rdir$dest"); 2217 $l2h_img{$src} = $dest; 2218 unlink "$docu_rdir$src" unless ($DEBUG & DEBUG_L2H); 2219 } 2220 $content =~ s/$src/$dest/g; 2221 } 2222 $l2h_cache{$l2h_to_latex[$count]} = $content; 2223 return $content; 2224} 2225 2226 2227#+++############################################################################ 2228# # 2229# Pass 1: read source, handle command, variable, simple substitution # 2230# # 2231#---############################################################################ 2232 2233@lines = (); # whole document 2234@toc_lines = (); # table of contents 2235@stoc_lines = (); # table of contents 2236$curlevel = 0; # current level in TOC 2237$node = ''; # current node name 2238$node_next = ''; # current node next name 2239$node_prev = ''; # current node prev name 2240$node_up = ''; # current node up name 2241$in_table = 0; # am I inside a table 2242$table_type = ''; # type of table ('', 'f', 'v', 'multi') 2243@tables = (); # nested table support 2244$in_bibliography = 0; # am I inside a bibliography 2245$in_glossary = 0; # am I inside a glossary 2246$in_top = 0; # am I inside the top node 2247$has_top = 0; # did I see a top node? 2248$has_top_command = 0; # did I see @top for automatic pointers? 2249$in_pre = 0; # am I inside a preformatted section 2250$in_list = 0; # am I inside a list 2251$in_html = 0; # am I inside an HTML section 2252$first_line = 1; # is it the first line 2253$dont_html = 0; # don't protect HTML on this line 2254$deferred_ref = ''; # deferred reference for indexes 2255@html_stack = (); # HTML elements stack 2256$html_element = ''; # current HTML element 2257&html_reset; 2258%macros = (); # macros 2259 2260# init l2h 2261$T2H_L2H = &l2h_Init($docu_name) if ($T2H_L2H); 2262$T2H_L2H = &l2h_InitToLatex if ($T2H_L2H); 2263 2264# build code for simple substitutions 2265# the maps used (%simple_map and %things_map) MUST be aware of this 2266# watch out for regexps, / and escaped characters! 2267$subst_code = ''; 2268foreach (keys(%simple_map)) { 2269 ($re = $_) =~ s/(\W)/\\$1/g; # protect regexp chars 2270 $subst_code .= "s/\\\@$re/$simple_map{$_}/g;\n"; 2271} 2272foreach (keys(%things_map)) { 2273 $subst_code .= "s/\\\@$_\\{\\}/$things_map{$_}/g;\n"; 2274} 2275if ($use_acc) { 2276 # accentuated characters 2277 foreach (keys(%accent_map)) { 2278 if ($_ eq "`") { 2279 $subst_code .= "s/$;3"; 2280 } elsif ($_ eq "'") { 2281 $subst_code .= "s/$;4"; 2282 } else { 2283 $subst_code .= "s/\\\@\\$_"; 2284 } 2285 $subst_code .= "([a-z])/&\${1}$accent_map{$_};/gi;\n"; 2286 } 2287} 2288eval("sub simple_substitutions { $subst_code }"); 2289 2290&init_input; 2291INPUT_LINE: while ($_ = &next_line) { 2292 # 2293 # remove \input on the first lines only 2294 # 2295 if ($first_line) { 2296 next if /^\\input/; 2297 $first_line = 0; 2298 } 2299 # non-@ substitutions cf. texinfmt.el 2300 # 2301 # parse texinfo tags 2302 # 2303 $tag = ''; 2304 $end_tag = ''; 2305 if (/^\s*\@end\s+(\w+)\b/) { 2306 $end_tag = $1; 2307 } elsif (/^\s*\@(\w+)\b/) { 2308 $tag = $1; 2309 } 2310 # 2311 # handle @html / @end html 2312 # 2313 if ($in_html) { 2314 if ($end_tag eq 'html') { 2315 $in_html = 0; 2316 } else { 2317 $tag2pro{$in_html} .= $_; 2318 } 2319 next; 2320 } elsif ($tag eq 'html') { 2321 $in_html = $PROTECTTAG . ++$html_num; 2322 push(@lines, $in_html); 2323 next; 2324 } 2325 2326 # 2327 # try to remove inlined comments 2328 # syntax from tex-mode.el comment-start-skip 2329 # 2330 s/((^|[^\@])(\@\@)*)\@c(omment | |\{|$).*/$1/; 2331 2332# Sometimes I use @c right at the end of a line ( to suppress the line feed ) 2333# s/((^|[^\@])(\@\@)*)\@c(omment)?$/$1/; 2334# s/((^|[^\@])(\@\@)*)\@c(omment)? .*/$1/; 2335# s/(.*)\@c{.*?}(.*)/$1$2/; 2336# s/(.*)\@comment{.*?}(.*)/$1$2/; 2337# s/^(.*)\@c /$1/; 2338# s/^(.*)\@comment /$1/; 2339 2340 ############################################################# 2341 # macro substitution 2342 while (/\@(\w+)/g) 2343 { 2344 if (exists($macros->{$1})) 2345 { 2346 my $before = $`; 2347 my $name = $1; 2348 my $after = $'; 2349 my @args; 2350 if ($after =~ /^\s*{(.*?)}(.*)/) 2351 { 2352 @args = split(/\s*,\s*/, $1); 2353 $after = $2; 2354 } 2355 my $macrobody = $macros->{$name}->{Body}; 2356 for ($i=0; $i<=$#args; $i++) 2357 { 2358 $macrobody =~ s|\\$macros->{$name}->{Args}->[$i]\\|$args[$i]|g; 2359 } 2360 $macrobody =~ s|\\\\|\\|g; 2361 $_ = $before . $macrobody . $after; 2362 unshift @input_spool, map {$_ = $_."\n"} split(/\n/, $_); 2363 next INPUT_LINE; 2364 } 2365 } # 2366 2367 2368 # 2369 # try to skip the line 2370 # 2371 if ($end_tag) { 2372 next if $to_skip{"end $end_tag"}; 2373 } elsif ($tag) { 2374 next if $to_skip{$tag}; 2375 last if $tag eq 'bye'; 2376 } 2377 if ($in_top) { 2378 # parsing the top node 2379 if ($tag eq 'node' || $tag eq 'include' || 2380 ($sec2level{$tag} && $tag !~ /unnumbered/ && $tag !~ /heading/)) 2381 { 2382 # no more in top 2383 $in_top = 0; 2384 push(@lines, $TOPEND); 2385 } 2386 } 2387 unless ($in_pre) { 2388 s/``/\"/g; 2389 s/''/\"/g; 2390 s/([\w ])---([\w ])/$1--$2/g; 2391 } 2392 # 2393 # analyze the tag 2394 # 2395 if ($tag) { 2396 # skip lines 2397 &skip_until($tag), next if $tag eq 'ignore'; 2398 &skip_until($tag), next if $tag eq 'ifnothtml'; 2399 if ($tag eq 'ifinfo') 2400 { 2401 &skip_until($tag), next unless $T2H_EXPAND eq 'info'; 2402 } 2403 if ($tag eq 'iftex') 2404 { 2405 &skip_until($tag), next unless $T2H_EXPAND eq 'tex'; 2406 } 2407 if ($tag eq 'tex') 2408 { 2409 # add to latex2html file 2410 if ($T2H_EXPAND eq 'tex' && $T2H_L2H && ! $in_pre) 2411 { 2412 # add space to the end -- tex(i2dvi) does this, as well 2413 push(@lines, &l2h_ToLatex(&string_until($tag) . " ")); 2414 } 2415 else 2416 { 2417 &skip_until($tag); 2418 } 2419 next; 2420 } 2421 # handle special tables 2422 if ($tag =~ /^(|f|v|multi)table$/) { 2423 $table_type = $1; 2424 $tag = 'table'; 2425 } 2426 # special cases 2427 if ($tag eq 'top' || ($tag eq 'node' && /^\@node\s+top\s*,/i)) { 2428 $in_top = 1; 2429 $has_top = 1; 2430 $has_top_command = 1 if $tag eq 'top'; 2431 @lines = (); # ignore all lines before top (title page garbage) 2432 next; 2433 } elsif ($tag eq 'node') { 2434 if ($in_top) 2435 { 2436 $in_top = 0; 2437 push(@lines, $TOPEND); 2438 } 2439 warn "$ERROR Bad node line: $_" unless $_ =~ /^\@node\s$NODESRE$/o; 2440 $_ = &protect_html($_); # if node contains '&' for instance 2441 s/^\@node\s+//; 2442 ($node, $node_next, $node_prev, $node_up) = split(/,/); 2443 &normalise_node($node); 2444 &normalise_node($node_next); 2445 &normalise_node($node_prev); 2446 &normalise_node($node_up); 2447 next; 2448 } elsif ($tag eq 'include') { 2449 if (/^\@include\s+($FILERE)\s*$/o) { 2450 $file = LocateIncludeFile($1); 2451 if ($file && -e $file) { 2452 &open($file); 2453 print "# including $file\n" if $T2H_VERBOSE; 2454 } else { 2455 warn "$ERROR Can't find $file, skipping"; 2456 } 2457 } else { 2458 warn "$ERROR Bad include line: $_"; 2459 } 2460 next; 2461 } elsif ($tag eq 'ifclear') { 2462 if (/^\@ifclear\s+($VARRE)\s*$/o) { 2463 next unless defined($value{$1}); 2464 &skip_until($tag); 2465 } else { 2466 warn "$ERROR Bad ifclear line: $_"; 2467 } 2468 next; 2469 } elsif ($tag eq 'ifset') { 2470 if (/^\@ifset\s+($VARRE)\s*$/o) { 2471 next if defined($value{$1}); 2472 &skip_until($tag); 2473 } else { 2474 warn "$ERROR Bad ifset line: $_"; 2475 } 2476 next; 2477 } elsif ($tag eq 'menu') { 2478 unless ($T2H_SHOW_MENU) { 2479 &skip_until($tag); 2480 next; 2481 } 2482 &html_push_if($tag); 2483 push(@lines, &html_debug('', __LINE__)); 2484 } elsif ($format_map{$tag}) { 2485 $in_pre = 1 if $format_map{$tag} eq 'PRE'; 2486 &html_push_if($format_map{$tag}); 2487 push(@lines, &html_debug('', __LINE__)); 2488 $in_list++ if $format_map{$tag} eq 'UL' || $format_map{$tag} eq 'OL' ; 2489# push(@lines, &debug("<BLOCKQUOTE>\n", __LINE__)) 2490# if $tag =~ /example/i; 2491 # sunshine@sunshineco.com: <PRE>bla</PRE> looks better than 2492 # <PRE>\nbla</PRE> (at least on NeXTstep browser 2493 push(@lines, &debug("<$format_map{$tag}>" . 2494 ($in_pre ? '' : "\n"), __LINE__)); 2495 next; 2496 } 2497 elsif (exists $complex_format_map->{$tag}) 2498 { 2499 my $start = eval $complex_format_map->{$tag}->[0]; 2500 if ($@) 2501 { 2502 print "$ERROR: eval of complex_format_map->{$tag}->[0] $complex_format_map->{$tag}->[0]: $@"; 2503 $start = '<pre>' 2504 } 2505 $in_pre = 1 if $start =~ /<pre/; 2506 push(@lines, html_debug($start. ($in_pre ? '' : "\n"), __LINE__)); 2507 next; 2508 } elsif ($tag eq 'table') { 2509 # anorland@hem2.passagen.se 2510 # if (/^\s*\@(|f|v|multi)table\s+\@(\w+)/) { 2511 if (/^\s*\@(|f|v|multi)table\s+\@(\w+)|(\{[^\}]*\})/) { 2512 $in_table = $2; 2513 unshift(@tables, join($;, $table_type, $in_table)); 2514 if ($table_type eq "multi") { 2515 # don't use borders -- gets confused by empty cells 2516 push(@lines, &debug("<TABLE>\n", __LINE__)); 2517 &html_push_if('TABLE'); 2518 } else { 2519 push(@lines, &debug("<DL COMPACT>\n", __LINE__)); 2520 &html_push_if('DL'); 2521 } 2522 push(@lines, &html_debug('', __LINE__)); 2523 } else { 2524 warn "$ERROR Bad table line: $_"; 2525 } 2526 next; 2527 } elsif ($tag eq 'synindex' || $tag eq 'syncodeindex') { 2528 if (/^\@$tag\s+(\w)\w\s+(\w)\w\s*$/) { 2529 eval("*${1}index = *${2}index"); 2530 } else { 2531 warn "$ERROR Bad syn*index line: $_"; 2532 } 2533 next; 2534 } elsif ($tag eq 'sp') { 2535 push(@lines, &debug("<P>\n", __LINE__)); 2536 next; 2537 } elsif ($tag eq 'center') { 2538 push(@lines, &debug("<center>\n", __LINE__)); 2539 s/\@center//; 2540 } elsif ($tag eq 'setref') { 2541 &protect_html; # if setref contains '&' for instance 2542 if (/^\@$tag\s*{($NODERE)}\s*$/) { 2543 $setref = $1; 2544 $setref =~ s/\s+/ /g; # normalize 2545 $setref =~ s/ $//; 2546 $node2sec{$setref} = $name; 2547 $sec2node{$name} = $setref; 2548 $node2href{$setref} = "$docu_doc#$docid"; 2549 } else { 2550 warn "$ERROR Bad setref line: $_"; 2551 } 2552 next; 2553 } elsif ($tag eq 'defindex' || $tag eq 'defcodeindex') { 2554 if (/^\@$tag\s+(\w\w)\s*$/) { 2555 $valid_index{$1} = 1; 2556 } else { 2557 warn "$ERROR Bad defindex line: $_"; 2558 } 2559 next; 2560 } elsif ($tag eq 'lowersections') { 2561 local ($sec, $level); 2562 while (($sec, $level) = each %sec2level) { 2563 $sec2level{$sec} = $level + 1; 2564 } 2565 next; 2566 } elsif ($tag eq 'raisesections') { 2567 local ($sec, $level); 2568 while (($sec, $level) = each %sec2level) { 2569 $sec2level{$sec} = $level - 1; 2570 } 2571 next; 2572 } 2573 elsif ($tag eq 'macro' || $tag eq 'rmacro') 2574 { 2575 if (/^\@$tag\s*(\w+)\s*(.*)/) 2576 { 2577 my $name = $1; 2578 my @args; 2579 @args = split(/\s*,\s*/ , $1) 2580 if ($2 =~ /^\s*{(.*)}\s*/); 2581 2582 $macros->{$name}->{Args} = \@args; 2583 $macros->{$name}->{Body} = ''; 2584 while (($_ = &next_line) !~ /\@end $tag/) 2585 { 2586 $macros->{$name}->{Body} .= $_; 2587 } 2588 chomp $macros->{$name}->{Body}; 2589 } 2590 else 2591 { 2592 warn "$ERROR: Bad macro defintion $_" 2593 } 2594 next; 2595 } 2596 elsif ($tag eq 'unmacro') 2597 { 2598 delete $macros->{$1} if (/^\@unmacro\s*(\w+)/); 2599 } 2600 elsif (defined($def_map{$tag})) { 2601 if ($def_map{$tag}) { 2602 s/^\@$tag\s+//; 2603 $tag = $def_map{$tag}; 2604 $_ = "\@$tag $_"; 2605 $tag =~ s/\s.*//; 2606 } 2607 } elsif (defined($user_sub{$tag})) { 2608 s/^\@$tag\s+//; 2609 $sub = $user_sub{$tag}; 2610 print "# user $tag = $sub, arg: $_" if $T2H_DEBUG & $DEBUG_USER; 2611 if (defined(&$sub)) { 2612 chop($_); 2613 &$sub($_); 2614 } else { 2615 warn "$ERROR Bad user sub for $tag: $sub\n"; 2616 } 2617 next; 2618 } 2619 if (defined($def_map{$tag})) { 2620 s/^\@$tag\s+//; 2621 if ($tag =~ /x$/) { 2622 # extra definition line 2623 $tag = $`; 2624 $is_extra = 1; 2625 } else { 2626 $is_extra = 0; 2627 } 2628 while (/\{([^\{\}]*)\}/) { 2629 # this is a {} construct 2630 ($before, $contents, $after) = ($`, $1, $'); 2631 # protect spaces 2632 $contents =~ s/\s+/$;9/g; 2633 # restore $_ protecting {} 2634 $_ = "$before$;7$contents$;8$after"; 2635 } 2636 @args = split(/\s+/, &protect_html($_)); 2637 foreach (@args) { 2638 s/$;9/ /g; # unprotect spaces 2639 s/$;7/\{/g; # ... { 2640 s/$;8/\}/g; # ... } 2641 } 2642 $type = shift(@args); 2643 $type =~ s/^\{(.*)\}$/$1/; 2644 print "# def ($tag): {$type} ", join(', ', @args), "\n" 2645 if $T2H_DEBUG & $DEBUG_DEF; 2646 $type .= ':'; # it's nicer like this 2647 my $name = shift(@args); 2648 $name =~ s/^\{(.*)\}$/$1/; 2649 if ($is_extra) { 2650 $_ = &debug("<DT>", __LINE__); 2651 } else { 2652 $_ = &debug("<DL>\n<DT>", __LINE__); 2653 } 2654 if ($tag eq 'deffn' || $tag eq 'defvr' || $tag eq 'deftp') { 2655 $_ .= "<U>$type</U> <B>$name</B>"; 2656 $_ .= " <I>@args</I>" if @args; 2657 } elsif ($tag eq 'deftypefn' || $tag eq 'deftypevr' 2658 || $tag eq 'defcv' || $tag eq 'defop') { 2659 $ftype = $name; 2660 $name = shift(@args); 2661 $name =~ s/^\{(.*)\}$/$1/; 2662 $_ .= "<U>$type</U> $ftype <B>$name</B>"; 2663 $_ .= " <I>@args</I>" if @args; 2664 } else { 2665 warn "$ERROR Unknown definition type: $tag\n"; 2666 $_ .= "<U>$type</U> <B>$name</B>"; 2667 $_ .= " <I>@args</I>" if @args; 2668 } 2669 $_ .= &debug("\n<DD>", __LINE__); 2670 $name = &unprotect_html($name); 2671 if ($tag eq 'deffn' || $tag eq 'deftypefn') { 2672 unshift(@input_spool, "\@findex $name\n"); 2673 } elsif ($tag eq 'defop') { 2674 unshift(@input_spool, "\@findex $name on $ftype\n"); 2675 } elsif ($tag eq 'defvr' || $tag eq 'deftypevr' || $tag eq 'defcv') { 2676 unshift(@input_spool, "\@vindex $name\n"); 2677 } else { 2678 unshift(@input_spool, "\@tindex $name\n"); 2679 } 2680 $dont_html = 1; 2681 } 2682 } elsif ($end_tag) { 2683 if ($format_map{$end_tag}) { 2684 $in_pre = 0 if $format_map{$end_tag} eq 'PRE'; 2685 $in_list-- if $format_map{$end_tag} eq 'UL' || $format_map{$end_tag} eq 'OL' ; 2686 &html_pop_if('LI', 'P'); 2687 &html_pop_if(); 2688 push(@lines, &debug("</$format_map{$end_tag}>\n", __LINE__)); 2689 push(@lines, &html_debug('', __LINE__)); 2690 } 2691 elsif (exists $complex_format_map->{$end_tag}) 2692 { 2693 my $end = eval $complex_format_map->{$end_tag}->[1]; 2694 if ($@) 2695 { 2696 print "$ERROR: eval of complex_format_map->{$end_tag}->[1] $complex_format_map->{$end_tag}->[0]: $@"; 2697 $end = '</pre>' 2698 } 2699 $in_pre = 0 if $end =~ m|</pre>|; 2700 push(@lines, html_debug($end, __LINE__)); 2701 } elsif ($end_tag =~ /^(|f|v|multi)table$/) { 2702 unless (@tables) { 2703 warn "$ERROR \@end $end_tag without \@*table\n"; 2704 next; 2705 } 2706 ($table_type, $in_table) = split($;, shift(@tables)); 2707 unless ($1 eq $table_type) { 2708 warn "$ERROR \@end $end_tag without matching \@$end_tag\n"; 2709 next; 2710 } 2711 if ($table_type eq "multi") { 2712 push(@lines, "</TR></TABLE>\n"); 2713 &html_pop_if('TR'); 2714 } else { 2715 push(@lines, "</DL>\n"); 2716 &html_pop_if('DD'); 2717 } 2718 &html_pop_if(); 2719 if (@tables) { 2720 ($table_type, $in_table) = split($;, $tables[0]); 2721 } else { 2722 $in_table = 0; 2723 } 2724 } elsif (defined($def_map{$end_tag})) { 2725 push(@lines, &debug("</DL>\n", __LINE__)); 2726 } elsif ($end_tag eq 'menu') { 2727 &html_pop_if(); 2728 push(@lines, $_); # must keep it for pass 2 2729 } 2730 next; 2731 } 2732 ############################################################# 2733 # anchor insertion 2734 while (/\@anchor\s*\{(.*?)\}/) 2735 { 2736 $_ = $`.$'; 2737 my $anchor = $1; 2738 $anchor = &normalise_node($anchor); 2739 push @lines, &html_debug("<A NAME=\"$anchor\"></A>\n"); 2740 $node2href{$anchor} = "$docu_doc#$anchor"; 2741 next INPUT_LINE if $_ = /^\s*$/; 2742 } 2743 2744 # 2745 # protect texi and HTML things 2746 &protect_texi; 2747 $_ = &protect_html($_) unless $dont_html; 2748 $dont_html = 0; 2749 # substitution (unsupported things) 2750 s/^\@exdent\s+//g; 2751 s/\@noindent\s+//g; 2752 s/\@refill\s+//g; 2753 # other substitutions 2754 &simple_substitutions; 2755 s/\@value\{($VARRE)\}/$value{$1}/eg; 2756 s/\@footnote\{/\@footnote$docu_doc\{/g; # mark footnotes, cf. pass 4 2757 # 2758 # analyze the tag again 2759 # 2760 if ($tag) { 2761 if (defined($sec2level{$tag}) && $sec2level{$tag} > 0) { 2762 if (/^\@$tag\s+(.+)$/) { 2763 $name = $1; 2764 $name = &normalise_node($name); 2765 $level = $sec2level{$tag}; 2766 if ($tag =~ /heading$/ || $in_top){ 2767 push(@lines, &html_debug('', __LINE__)); 2768 $_ = &debug("<H$level>$name</H$level>\n", __LINE__); 2769 &html_push_if('body'); 2770 print "# heading, section $name, level $level\n" 2771 if $T2H_DEBUG & $DEBUG_TOC; 2772 } 2773# this `else' seems to cause problems if there is a chapheading section and 2774# -split node is used. In this case, the split gets forgotten. 2775 else 2776 { 2777 $node = $name unless $node; 2778 unless (/^unnumbered/) 2779 { 2780 my $number = &update_sec_num($tag, $level); 2781 $name = $number. ' ' . $name if $T2H_NUMBER_SECTIONS; 2782 $sec2number{$name} = $number; 2783 $number2sec{$number} = $name; 2784 } 2785 if (defined($toplevel)) 2786 { 2787 push @lines, ($level==$toplevel ? $CHAPTEREND : $SECTIONEND); 2788 } 2789 else 2790 { 2791 # first time we see a "section" 2792 unless ($level == 1) 2793 { 2794 warn "$WARN The first section found is not of level 1: $_"; 2795 } 2796 $toplevel = $level; 2797 } 2798 push(@sections, $name); 2799 next_doc() if ($T2H_SPLIT eq 'section' || 2800 $T2H_SPLIT && $level == $toplevel); 2801 $sec_num++; 2802 $docid = "SEC$sec_num"; 2803 $tocid = "TOC$sec_num"; 2804 # check biblio and glossary 2805 $in_bibliography = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*bibliography$/i); 2806 $in_glossary = ($name =~ /^([A-Z]|\d+)?(\.\d+)*\s*glossary$/i); 2807 # check node 2808 if ($node2sec{$node}) { 2809 warn "$ERROR Duplicate node found: $node\n"; 2810 } else { 2811 $section = $name; 2812 $node2sec{$node} = $name; 2813 warn "$ERROR Duplicate section found: $name\n" 2814 if ($sec2node{$name}); 2815 $sec2node{$name} = $node; 2816 $node2href{$node} = "$docu_doc#$docid"; 2817 $node2next{$node} = $node_next; 2818 $node2prev{$node} = $node_prev; 2819 $node2up{$node} = $node_up; 2820 print "# node $node, section $name, level $level\n" 2821 if $T2H_DEBUG & $DEBUG_TOC; 2822 } 2823 $node = ''; 2824 $node_next = ''; 2825 $node_prev = ''; 2826 $node_next = ''; 2827 # update TOC 2828 while ($level > $curlevel) { 2829 $curlevel++; 2830 push(@toc_lines, "<UL>\n"); 2831 } 2832 while ($level < $curlevel) { 2833 $curlevel--; 2834 push(@toc_lines, "</UL>\n"); 2835 } 2836 $_ = &t2h_anchor($tocid, "$docu_doc#$docid", $name, 1); 2837 $_ = &substitute_style($_); 2838 push(@stoc_lines, "$_<BR>\n") if ($level == 1); 2839 push(@toc_lines, "<LI>" . $_ ."</LI>"); 2840 # update DOC 2841 push(@lines, &html_debug('', __LINE__)); 2842 &html_reset; 2843 # $_ = "<H$level>".&t2h_anchor($docid, '', $name)."</H$level>\n"; 2844 $_ = "<H$level> $name </H$level>\n<!--docid::${docid}::-->\n"; 2845 2846 $_ = &debug($_, __LINE__); 2847 push(@lines, &html_debug('', __LINE__)); 2848 } 2849 # update DOC 2850 foreach $line (split(/\n+/, $_)) { 2851 push(@lines, "$line\n"); 2852 } 2853 next; 2854 } else { 2855 warn "$ERROR Bad section line: $_"; 2856 } 2857 } else { 2858 # track variables 2859 $value{$1} = Unprotect_texi($2), next if /^\@set\s+($VARRE)\s+(.*)$/o; 2860 delete $value{$1}, next if /^\@clear\s+($VARRE)\s*$/o; 2861 # store things 2862 $value{'_setfilename'} = Unprotect_texi($1), next if /^\@setfilename\s+(.*)$/; 2863 $value{'_settitle'} = Unprotect_texi($1), next if /^\@settitle\s+(.*)$/; 2864 $value{'_author'} .= Unprotect_texi($1)."\n", next if /^\@author\s+(.*)$/; 2865 $value{'_subtitle'} .= Unprotect_texi($1)."\n", next if /^\@subtitle\s+(.*)$/; 2866 $value{'_title'} .= Unprotect_texi($1)."\n", next if /^\@title\s+(.*)$/; 2867 # index 2868 if (/^\@(..?)index\s+/) { 2869 unless ($valid_index{$1}) { 2870 warn "$ERROR Undefined index command: $_"; 2871 next; 2872 } 2873 $index = $1 . 'index'; 2874 $what = &substitute_style($'); 2875 $what =~ s/\s+$//; 2876 # check whether last pushed line was header 2877 if ($lines[$#lines] =~ /^<!--docid::(.+)::-->$/) 2878 { 2879 $id = $1; 2880 } 2881 else 2882 { 2883 $id = 'IDX' . ++$idx_num; 2884 } 2885 print "# found $index for '$what' id $id\n" 2886 if $T2H_DEBUG & $DEBUG_INDEX; 2887 eval(<<EOC); 2888 if (defined(\$$index\{\$what\})) { 2889 \$$index\{\$what\} .= "$;$;$docu_doc#$id$;$section"; 2890 } else { 2891 \$$index\{\$what\} = "$docu_doc#$id$;$section"; 2892 } 2893EOC 2894 2895 # 2896 # dirty hack to see if I can put an invisible anchor... 2897 # 2898 if ($id =~ /^IDX/) 2899 { 2900 if ($html_element eq 'DL' || 2901 $html_element eq 'UL' || 2902 $html_element eq 'OL' ) 2903 { 2904 $deferred_ref .= &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre) . " "; 2905 } 2906 elsif ($html_element eq 'body') 2907 { 2908 push(@lines, &debug("<P>\n", __LINE__)); 2909 push(@lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre)); 2910 &html_push('P'); 2911 } 2912 else 2913 { 2914 push(@lines, &t2h_anchor($id, '', $T2H_INVISIBLE_MARK, !$in_pre)); 2915 } 2916 } 2917 next; 2918 } 2919 # list item 2920 if (/^\s*\@itemx?\s+/) { 2921 $what = $'; 2922 $what =~ s/\s+$//; 2923 if ($in_bibliography && $use_bibliography) { 2924 if ($what =~ /^$BIBRE$/o) { 2925 $id = 'BIB' . ++$bib_num; 2926 $bib2href{$what} = "$docu_doc#$id"; 2927 print "# found bibliography for '$what' id $id\n" 2928 if $T2H_DEBUG & $DEBUG_BIB; 2929 $what = &t2h_anchor($id, '', $what); 2930 } 2931 } elsif ($in_glossary && $T2H_USE_GLOSSARY) { 2932 $id = 'GLOSS' . ++$gloss_num; 2933 $entry = $what; 2934 $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; 2935 $gloss2href{$entry} = "$docu_doc#$id"; 2936 print "# found glossary for '$entry' id $id\n" 2937 if $T2H_DEBUG & $DEBUG_GLOSS; 2938 $what = &t2h_anchor($id, '', $what); 2939 } 2940 &html_pop_if('P'); 2941 if ($html_element eq 'DL' || $html_element eq 'DD') { 2942 if ($things_map{$in_table} && !$what) { 2943 # special case to allow @table @bullet for instance 2944 push(@lines, &debug("<DT>$things_map{$in_table}\n", __LINE__)); 2945 } else { 2946 push(@lines, &debug("<DT>\@$in_table\{$what\}\n", __LINE__)); 2947 } 2948 push(@lines, "<DD>"); 2949 &html_push('DD') unless $html_element eq 'DD'; 2950 if ($table_type) { # add also an index 2951 unshift(@input_spool, "\@${table_type}index $what\n"); 2952 } 2953 } elsif ($html_element eq 'TABLE') { 2954 push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__)); 2955 &html_push('TR'); 2956 } elsif ($html_element eq 'TR') { 2957 push(@lines, &debug("</TR>\n", __LINE__)); 2958 push(@lines, &debug("<TR><TD>$what</TD>\n", __LINE__)); 2959 } else { 2960 push(@lines, &debug("<LI>$what\n", __LINE__)); 2961 &html_push('LI') unless $html_element eq 'LI'; 2962 } 2963 push(@lines, &html_debug('', __LINE__)); 2964 if ($deferred_ref) { 2965 push(@lines, &debug("$deferred_ref\n", __LINE__)); 2966 $deferred_ref = ''; 2967 } 2968 next; 2969 } elsif (/^\@tab\s+(.*)$/) { 2970 push(@lines, "<TD>$1</TD>\n"); 2971 next; 2972 } 2973 } 2974 } 2975 # paragraph separator 2976 if ($_ eq "\n") { 2977 next if $#lines >= 0 && $lines[$#lines] eq "\n"; 2978 if ($html_element eq 'P') { 2979 push (@lines, &debug("</P><P>\n", __LINE__)); 2980 } 2981# else 2982# { 2983# push(@lines, "<P></P>\n"); 2984# $_ = &debug("<P></P>\n", __LINE__); 2985# } 2986 elsif ($html_element eq 'body' || $html_element eq 'BLOCKQUOTE' || $html_element eq 'DD' || $html_element eq 'LI') 2987 { 2988 &html_push('P'); 2989 push(@lines, &debug("<P>\n", __LINE__)); 2990 } 2991 } 2992 # otherwise 2993 push(@lines, $_); 2994 2995 push(@lines, &debug("</center>\n", __LINE__)) if ($tag eq 'center'); 2996} 2997 2998# finish TOC 2999$level = 0; 3000while ($level < $curlevel) { 3001 $curlevel--; 3002 push(@toc_lines, "</UL>\n"); 3003} 3004 3005print "# end of pass 1\n" if $T2H_VERBOSE; 3006 3007#+++############################################################################ 3008# # 3009# Pass 2/3: handle style, menu, index, cross-reference # 3010# # 3011#---############################################################################ 3012 3013@lines2 = (); # whole document (2nd pass) 3014@lines3 = (); # whole document (3rd pass) 3015$in_menu = 0; # am I inside a menu 3016 3017while (@lines) { 3018 $_ = shift(@lines); 3019 # 3020 # special case (protected sections) 3021 # 3022 if (/^$PROTECTTAG/o) { 3023 push(@lines2, $_); 3024 next; 3025 } 3026 # 3027 # menu 3028 # 3029 if (/^\@menu\b/) 3030 { 3031 $in_menu = 1; 3032 $in_menu_listing = 1; 3033 $T2H_NUMBER_SECTIONS ? 3034 push(@lines2, &debug("<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0> \n", __LINE__)) : 3035 push(@lines2, &debug("<UL>\n", __LINE__)); 3036 next; 3037 } 3038 if (/^\@end\s+menu\b/) 3039 { 3040 $in_menu = 0; 3041 $T2H_NUMBER_SECTIONS ? 3042 push(@lines2, &debug("</TABLE></BLOCKQUOTE>\n", __LINE__)) : 3043 push(@lines2, &debug("</UL>\n", __LINE__)); 3044 next; 3045 } 3046 if ($in_menu) { 3047 if (/^\*\s+($NODERE)::/o) { 3048 if (! $in_menu_listing) 3049 { 3050 $in_menu_listing = 1; 3051 $T2H_NUMBER_SECTIONS ? 3052 push(@lines2, &debug("<TABLE BORDER=0 CELLSPACING=0>\n", __LINE__)) : 3053 push(@lines2, &debug("<UL>\n", __LINE__)); 3054 } 3055 $descr = $'; 3056 chop($descr); 3057 &menu_entry($1, $1, $descr); 3058 } elsif (/^\*\s+(.+):\s+([^\t,\.\n]+)[\t,\.\n]/) { 3059 if (! $in_menu_listing) 3060 { 3061 $in_menu_listing = 1; 3062 $T2H_NUMBER_SECTIONS ? 3063 push(@lines2, &debug("<TABLE BORDER=0 CELLSPACING=0>\n", __LINE__)) : 3064 push(@lines2, &debug("<UL>\n", __LINE__)); 3065 } 3066 $descr = $'; 3067 chop($descr); 3068 &menu_entry($1, $2, $descr); 3069 } elsif (/^\*/) { 3070 warn "$ERROR Bad menu line: $_"; 3071 } else { # description continued? 3072 if ($in_menu_listing) 3073 { 3074 $in_menu_listing = 0; 3075 $T2H_NUMBER_SECTIONS ? 3076 push(@lines2, &debug("</TABLE>\n", __LINE__)) : 3077 push(@lines2, &debug("</UL>\n", __LINE__)); 3078 } 3079 # should be like verbatim -- preseve spaces, etc 3080 s/ /\ /g; 3081 $_ .= "<br>\n"; 3082 push(@lines2, $_); 3083 } 3084 next; 3085 } 3086 # 3087 # printindex 3088 # 3089 # obachman: replace ^\@printindex by \@printindex, otherwise 3090 # generation in debug mode fails 3091 if (/\@printindex\s+(\w\w)\b/) { 3092 local($index, *ary, @keys, $key, $letter, $last_letter, @refs, $fhidx); 3093 if ($predefined_index{$1}) { 3094 $index = $predefined_index{$1} . 'index'; 3095 } else { 3096 $index = $1 . 'index'; 3097 } 3098 # check for index summary 3099 $letter = $1; 3100 if ($letter =~ /$T2H_IDX_SUMMARY/) 3101 { 3102 open(FHIDX, "> $docu_rdir$docu_name" . "_$letter.idx") 3103 || die "Can't open > $docu_rdir$docu_name" . "_$letter.idx for writing: $!\n"; 3104 $fhidx = \*FHIDX; 3105 print "# writing index summary in $docu_rdir$docu_name" . "_$letter.idx..." if $T2H_VERBOSE; 3106 } 3107 eval("*ary = *$index"); 3108 @keys = keys(%ary); 3109 foreach $key (@keys) { 3110 $_ = $key; 3111 1 while s/<(\w+)>\`(.*)\'<\/\1>/$2/; # remove HTML tags with quotes 3112 1 while s/<(\w+)>(.*)<\/\1>/$2/; # remove HTML tags 3113 $_ = &unprotect_html($_); 3114 &unprotect_texi; 3115 tr/A-Z/a-z/; # lowercase 3116 $key2alpha{$key} = $_; 3117 print "# index $key sorted as $_\n" 3118 if $key ne $_ && $T2H_DEBUG & $DEBUG_INDEX; 3119 } 3120 push(@lines2, "<H3>Jump to:</H3>\n"); 3121 $last_letter = undef; 3122 foreach $key (sort byalpha @keys) { 3123 $letter = substr($key2alpha{$key}, 0, 1); 3124 $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;; 3125 if (!defined($last_letter) || $letter ne $last_letter) { 3126 push(@lines2, " \n") if defined($last_letter); 3127 push(@lines2, "<BR>\n") if ($letter eq 'a'); 3128 push(@lines2, "<A HREF=\"#$index\_$letter\">" . &protect_html(uc($letter)) . "</A>\n"); 3129 $last_letter = $letter; 3130 } 3131 } 3132 push(@lines2, "<P></P><P></P>\n"); 3133 push(@lines2, "<TABLE border=0>\n"); 3134 push(@lines2, "<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> $T2H_WORDS->{$T2H_LANG}->{'section'}</TH></TR>\n"); 3135 $last_letter = undef; 3136 foreach $key (sort byalpha @keys) { 3137 $letter = substr($key2alpha{$key}, 0, 1); 3138 $letter = substr($key2alpha{$key}, 0, 2) if $letter eq $;; 3139 if (!defined($last_letter) || $letter ne $last_letter) { 3140 push (@lines2, "<TR><TD COLSPAN=3> <HR></TD></TR>\n"); 3141 push(@lines2, "<TR><TH><A NAME=\"$index\_$letter\">" . &protect_html(uc($letter)) . "</A>\n"); 3142 push(@lines2, "</TH><TD></TD><TD></TD></TR>\n"); 3143 $last_letter = $letter; 3144 } 3145 foreach (split(/$;$;/, $ary{$key})) { 3146 my ($idx, $section) = split(/$;/, $_); 3147 push(@lines2, 3148 "<TR><TD></TD><TD>" . 3149 &t2h_anchor('', $idx, $key, 0) . 3150 "</TD><TD>" . 3151 &t2h_anchor('', &sec_href($section), $section, 0) . 3152 "</TD></TR>\n"); 3153 3154 } 3155 if ($fhidx) 3156 { 3157 ($letter) = split(/$;/, $ary{$key}); 3158 $key = unprotect_html($key); 3159 print $fhidx "$key\t$letter\n"; 3160 } 3161 } 3162 if ($fhidx) 3163 { 3164 print "\n" if $T2H_VERBOSE; 3165 close($fhidx); 3166 } 3167 push (@lines2, "</TABLE>\n"); 3168 next; 3169 } 3170 # 3171 # simple style substitutions 3172 # 3173 $_ = &substitute_style($_); 3174 # 3175 # xref 3176 # 3177 while (/\@(x|px|info|)ref\{([^{}]+)(\}?)/) { 3178 # note: Texinfo may accept other characters 3179 ($type, $nodes, $full) = ($1, $2, $3); 3180 ($before, $after) = ($`, $'); 3181 if (! $full && $after) { 3182 warn "$ERROR Bad xref (no ending } on line): $_"; 3183 $_ = "$before$;0${type}ref\{$nodes$after"; 3184 next; # while xref 3185 } 3186 if ($type eq 'x') { 3187 $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} "; 3188 } elsif ($type eq 'px') { 3189 $type = "$T2H_WORDS->{$T2H_LANG}->{'see'} "; 3190 } elsif ($type eq 'info') { 3191 $type = "$T2H_WORDS->{$T2H_LANG}->{'See'} Info"; 3192 } else { 3193 $type = ''; 3194 } 3195 unless ($full) { 3196 $next = shift(@lines); 3197 $next = &substitute_style($next); 3198 chop($nodes); # remove final newline 3199 if ($next =~ /\}/) { # split on 2 lines 3200 $nodes .= " $`"; 3201 $after = $'; 3202 } else { 3203 $nodes .= " $next"; 3204 $next = shift(@lines); 3205 $next = &substitute_style($next); 3206 chop($nodes); 3207 if ($next =~ /\}/) { # split on 3 lines 3208 $nodes .= " $`"; 3209 $after = $'; 3210 } else { 3211 warn "$ERROR Bad xref (no ending }): $_"; 3212 $_ = "$before$;0xref\{$nodes$after"; 3213 unshift(@lines, $next); 3214 next; # while xref 3215 } 3216 } 3217 } 3218 $nodes =~ s/\s+/ /g; # remove useless spaces 3219 @args = split(/\s*,\s*/, $nodes); 3220 $node = $args[0]; # the node is always the first arg 3221 $node = &normalise_node($node); 3222 $sec = $node2sec{$node}; 3223 $href = $node2href{$node}; 3224 if (@args == 5) { # reference to another manual 3225 $sec = $args[2] || $node; 3226 $man = $args[4] || $args[3]; 3227 $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} `$sec' in \@cite{$man}$after"; 3228 } elsif ($type =~ /Info/) { # inforef 3229 warn "$ERROR Wrong number of arguments: $_" unless @args == 3; 3230 ($nn, $_, $in) = @args; 3231 $_ = "${before}${type} file `$in', node `$nn'$after"; 3232 } elsif ($sec && $href && ! $T2H_SHORT_REF) { 3233 $_ = "${before}${type}$T2H_WORDS->{$T2H_LANG}->{'section'} " . 3234 &t2h_anchor('', $href, $sec) . $after; 3235 } 3236 elsif ($href) 3237 { 3238 $_ = "${before}${type} " . &t2h_anchor('', $href, $node) . $after; 3239 } 3240 else { 3241 warn "$ERROR Undefined node ($node): $_"; 3242 $_ = "$before$;0xref{$nodes}$after"; 3243 } 3244 } 3245 3246 # replace images 3247 s[\@image\s*{(.+?)}] 3248 { 3249 my @args = split (/\s*,\s*/, $1); 3250 my $base = $args[0]; 3251 my $image = 3252 LocateIncludeFile("$base.png") || 3253 LocateIncludeFile("$base.jpg") || 3254 LocateIncludeFile("$base.gif"); 3255 warn "$ERROR no image file for $base: $_" unless ($image && -e $image); 3256 "<IMG SRC=\"$image\" ALT=\"$base\">"; 3257 ($T2H_CENTER_IMAGE ? 3258 "<CENTER><IMG SRC=\"$image\" ALT=\"$base\"></CENTER>" : 3259 "<IMG SRC=\"$image\" ALT=\"$base\">"); 3260 }eg; 3261 3262 # 3263 # try to guess bibliography references or glossary terms 3264 # 3265 unless (/^<H\d><A NAME=\"SEC\d/) { 3266 if ($use_bibliography) { 3267 $done = ''; 3268 while (/$BIBRE/o) { 3269 ($pre, $what, $post) = ($`, $&, $'); 3270 $href = $bib2href{$what}; 3271 if (defined($href) && $post !~ /^[^<]*<\/A>/) { 3272 $done .= $pre . &t2h_anchor('', $href, $what); 3273 } else { 3274 $done .= "$pre$what"; 3275 } 3276 $_ = $post; 3277 } 3278 $_ = $done . $_; 3279 } 3280 if ($T2H_USE_GLOSSARY) { 3281 $done = ''; 3282 while (/\b\w+\b/) { 3283 ($pre, $what, $post) = ($`, $&, $'); 3284 $entry = $what; 3285 $entry =~ tr/A-Z/a-z/ unless $entry =~ /^[A-Z\s]+$/; 3286 $href = $gloss2href{$entry}; 3287 if (defined($href) && $post !~ /^[^<]*<\/A>/) { 3288 $done .= $pre . &t2h_anchor('', $href, $what); 3289 } else { 3290 $done .= "$pre$what"; 3291 } 3292 $_ = $post; 3293 } 3294 $_ = $done . $_; 3295 } 3296 } 3297 # otherwise 3298 push(@lines2, $_); 3299} 3300print "# end of pass 2\n" if $T2H_VERBOSE; 3301 3302# 3303# split style substitutions 3304# 3305while (@lines2) { 3306 $_ = shift(@lines2); 3307 # 3308 # special case (protected sections) 3309 # 3310 if (/^$PROTECTTAG/o) { 3311 push(@lines3, $_); 3312 next; 3313 } 3314 # 3315 # split style substitutions 3316 # 3317 $old = ''; 3318 while ($old ne $_) { 3319 $old = $_; 3320 if (/\@(\w+)\{/) { 3321 ($before, $style, $after) = ($`, $1, $'); 3322 if (defined($style_map{$style})) { 3323 $_ = $after; 3324 $text = ''; 3325 $after = ''; 3326 $failed = 1; 3327 while (@lines2) { 3328 if (/\}/) { 3329 $text .= $`; 3330 $after = $'; 3331 $failed = 0; 3332 last; 3333 } else { 3334 $text .= $_; 3335 $_ = shift(@lines2); 3336 } 3337 } 3338 if ($failed) { 3339 die "* Bad syntax (\@$style) after: $before\n"; 3340 } else { 3341 $text = &apply_style($style, $text); 3342 $_ = "$before$text$after"; 3343 } 3344 } 3345 } 3346 } 3347 # otherwise 3348 push(@lines3, $_); 3349} 3350print "# end of pass 3\n" if $T2H_VERBOSE; 3351 3352#+++############################################################################ 3353# # 3354# Pass 4: foot notes, final cleanup # 3355# # 3356#---############################################################################ 3357 3358@foot_lines = (); # footnotes 3359@doc_lines = (); # final document 3360$end_of_para = 0; # true if last line is <P> 3361 3362while (@lines3) { 3363 $_ = shift(@lines3); 3364 # 3365 # special case (protected sections) 3366 # 3367 if (/^$PROTECTTAG/o) { 3368 push(@doc_lines, $_); 3369 $end_of_para = 0; 3370 next; 3371 } 3372 # 3373 # footnotes 3374 # 3375 while (/\@footnote([^\{\s]+)\{/) { 3376 ($before, $d, $after) = ($`, $1, $'); 3377 $_ = $after; 3378 $text = ''; 3379 $after = ''; 3380 $failed = 1; 3381 while (@lines3) { 3382 if (/\}/) { 3383 $text .= $`; 3384 $after = $'; 3385 $failed = 0; 3386 last; 3387 } else { 3388 $text .= $_; 3389 $_ = shift(@lines3); 3390 } 3391 } 3392 if ($failed) { 3393 die "* Bad syntax (\@footnote) after: $before\n"; 3394 } else { 3395 $foot_num++; 3396 $docid = "DOCF$foot_num"; 3397 $footid = "FOOT$foot_num"; 3398 $foot = "($foot_num)"; 3399 push(@foot_lines, "<H3>" . &t2h_anchor($footid, "$d#$docid", $foot) . "</H3>\n"); 3400 $text = "<P>$text" unless $text =~ /^\s*<P>/; 3401 push(@foot_lines, "$text\n"); 3402 $_ = $before . &t2h_anchor($docid, "$docu_foot#$footid", $foot) . $after; 3403 } 3404 } 3405 # 3406 # remove unnecessary <P> 3407 # 3408 if (/^\s*<P>\s*$/) { 3409 next if $end_of_para++; 3410 } else { 3411 $end_of_para = 0; 3412 } 3413 # otherwise 3414 push(@doc_lines, $_); 3415} 3416 3417print "# end of pass 4\n" if $T2H_VERBOSE; 3418 3419#+++############################################################################ 3420# # 3421# Pass 5: print things # 3422# # 3423#---############################################################################ 3424 3425$T2H_L2H = &l2h_FinishToLatex if ($T2H_L2H); 3426$T2H_L2H = &l2h_ToHtml if ($T2H_L2H); 3427$T2H_L2H = &l2h_InitFromHtml if ($T2H_L2H); 3428 3429# fix node2up, node2prev, node2next, if desired 3430if ($has_top_command) 3431{ 3432 for $section (keys %sec2number) 3433 { 3434 $node = $sec2node{$section}; 3435 $node2up{$node} = Sec2UpNode($section) unless $node2up{$node}; 3436 $node2prev{$node} = Sec2PrevNode($section) unless $node2prev{$node}; 3437 $node2next{$node} = Sec2NextNode($section) unless $node2next{$node}; 3438 } 3439} 3440 3441# prepare %T2H_THISDOC 3442$T2H_THISDOC{fulltitle} = $value{'_title'} || $value{'_settitle'} || "Untitled Document"; 3443$T2H_THISDOC{title} = $value{'_settitle'} || $T2H_THISDOC{fulltitle}; 3444$T2H_THISDOC{author} = $value{'_author'}; 3445$T2H_THISDOC{subtitle} = $value{'_subtitle'}; 3446for $key (keys %T2H_THISDOC) 3447{ 3448 $_ = &substitute_style($T2H_THISDOC{$key}); 3449 &unprotect_texi; 3450 s/\s*$//; 3451 $T2H_THISDOC{$key} = $_; 3452} 3453 3454# if no sections, then simply print docuemnt as is 3455unless (@sections) 3456{ 3457 print "# Writing content into $docu_top_file \n" if $T2H_VERBOSE; 3458 open(FILE, "> $docu_top_file") 3459 || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; 3460 3461 &$T2H_print_page_head(\*FILE); 3462 $T2H_THIS_SECTION = \@doc_lines; 3463 t2h_print_lines(\*FILE); 3464 &$T2H_print_foot_navigation(\*FILE); 3465 &$T2H_print_page_foot(\*FILE); 3466 close(FILE); 3467 goto Finish; 3468} 3469 3470# initialize $T2H_HREF, $T2H_NAME 3471%T2H_HREF = 3472 ( 3473 'First' , sec_href($sections[0]), 3474 'Last', sec_href($sections[$#sections]), 3475 'About', $docu_about. '#SEC_About', 3476 ); 3477 3478# prepare TOC, OVERVIEW, TOP 3479$T2H_TOC = \@toc_lines; 3480$T2H_OVERVIEW = \@stoc_lines; 3481if ($has_top) 3482{ 3483 while (1) 3484 { 3485 $_ = shift @doc_lines; 3486 last if /$TOPEND/; 3487 push @$T2H_TOP, $_; 3488 } 3489 $T2H_HREF{'Top'} = $docu_top . '#SEC_Top'; 3490} 3491else 3492{ 3493 $T2H_HREF{'Top'} = $T2H_HREF{First}; 3494} 3495 3496$node2href{Top} = $T2H_HREF{Top}; 3497$T2H_HREF{Contents} = $docu_toc.'#SEC_Contents' if @toc_lines; 3498$T2H_HREF{Overview} = $docu_stoc.'#SEC_OVERVIEW' if @stoc_lines; 3499$T2H_HREF{Index} = $node2href{'Index'}; 3500 3501%T2H_NAME = 3502 ( 3503 'First', clean_name($sec2node{$sections[0]}), 3504 'Last', clean_name($sec2node{$sections[$#sections]}), 3505 'About', $T2H_WORDS->{$T2H_LANG}->{'About_Title'}, 3506 'Contents', $T2H_WORDS->{$T2H_LANG}->{'ToC_Title'}, 3507 'Overview', $T2H_WORDS->{$T2H_LANG}->{'Overview_Title'}, 3508 'Index' , '', 3509 'Top', '' 3510 ); 3511 3512############################################################################# 3513# print Top 3514# 3515open(FILE, "> $docu_top_file") 3516 || die "$ERROR: Can't open $docu_top_file for writing: $!\n"; 3517&$T2H_print_page_head(\*FILE) unless ($T2H_SPLIT); 3518 3519if ($has_top) 3520{ 3521 print "# Creating Top in $docu_top_file ...\n" if $T2H_VERBOSE; 3522 $T2H_THIS_SECTION = $T2H_TOP; 3523 $T2H_HREF{This} = $T2H_HREF{Top}; 3524 $T2H_NAME{This} = $T2H_NAME{Top}; 3525 &$T2H_print_Top(\*FILE); 3526} 3527 3528close(FILE) if $T2H_SPLIT; 3529 3530############################################################################# 3531# Print sections 3532# 3533$T2H_NODE{Forward} = $sec2node{$sections[0]}; 3534$T2H_NAME{Forward} = &clean_name($sec2node{$sections[0]}); 3535$T2H_HREF{Forward} = sec_href($sections[0]); 3536$T2H_NODE{This} = 'Top'; 3537$T2H_NAME{This} = $T2H_NAME{Top}; 3538$T2H_HREF{This} = $T2H_HREF{Top}; 3539if ($T2H_SPLIT) 3540{ 3541 print "# writing " . scalar(@sections) . 3542 " sections in $docu_rdir$docu_name"."_[1.." . 3543 ($T2H_SPLIT eq 'section' ? scalar(@sections) : scalar(@$T2H_OVERVIEW) ) . 3544 "]" 3545 if $T2H_VERBOSE; 3546 $previous = ($T2H_SPLIT eq 'chapter' ? $CHAPTEREND : $SECTIONEND); 3547 undef $FH; 3548 $doc_num = 0; 3549} 3550else 3551{ 3552 print "# writing " . scalar(@sections) . " sections in $docu_top_file ..." 3553 if $T2H_VERBOSE; 3554 $FH = \*FILE; 3555 $previous = ''; 3556} 3557 3558$counter = 0; 3559# loop through sections 3560while ($section = shift(@sections)) 3561{ 3562 if ($T2H_SPLIT && ($T2H_SPLIT eq 'section' || $previous eq $CHAPTEREND)) 3563 { # open new page 3564 if ($FH) 3565 { 3566 #close previous page 3567 &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; 3568 &$T2H_print_page_foot($FH); 3569 close($FH); 3570 undef $FH; 3571 } 3572 &next_doc; 3573 } 3574 $T2H_NAME{Back} = $T2H_NAME{This}; 3575 $T2H_HREF{Back} = $T2H_HREF{This}; 3576 $T2H_NODE{Back} = $T2H_NODE{This}; 3577 $T2H_NAME{This} = $T2H_NAME{Forward}; 3578 $T2H_HREF{This} = $T2H_HREF{Forward}; 3579 $T2H_NODE{This} = $T2H_NODE{Forward}; 3580 if ($sections[0]) 3581 { 3582 $T2H_NODE{Forward} = $sec2node{$sections[0]}; 3583 $T2H_NAME{Forward} = &clean_name($T2H_NODE{Forward}); 3584 $T2H_HREF{Forward} = sec_href($sections[0]); 3585 } 3586 else 3587 { 3588 undef $T2H_HREF{Forward}, $T2H_NODE{Forward}, $T2H_NAME{Forward}; 3589 } 3590 3591 $node = $node2up{$T2H_NODE{This}}; 3592 $T2H_HREF{Up} = $node2href{$node}; 3593 if ($T2H_HREF{Up} eq $T2H_HREF{This} || ! $T2H_HREF{Up}) 3594 { 3595 $T2H_NAME{Up} = $T2H_NAME{Top}; 3596 $T2H_HREF{Up} = $T2H_HREF{Top}; 3597 $T2H_NODE{Up} = 'Up'; 3598 } 3599 else 3600 { 3601 $T2H_NAME{Up} = &clean_name($node); 3602 $T2H_NODE{Up} = $node; 3603 } 3604 3605 $node = $T2H_NODE{This}; 3606 $node = $node2prev{$node}; 3607 $T2H_NAME{Prev} = &clean_name($node); 3608 $T2H_HREF{Prev} = $node2href{$node}; 3609 $T2H_NODE{Prev} = $node; 3610 3611 $node = $T2H_NODE{This}; 3612 if ($node2up{$node} && $node2up{$node} ne 'Top'&& 3613 ($node2prev{$node} eq $T2H_NODE{Back} || ! $node2prev{$node})) 3614 { 3615 $node = $node2up{$node}; 3616 while ($node && $node ne $node2up{$node} && ! $node2prev{$node}) 3617 { 3618 $node = $node2up{$node}; 3619 } 3620 $node = $node2prev{$node} 3621 unless $node2up{$node} eq 'Top' || ! $node2up{$node}; 3622 } 3623 else 3624 { 3625 $node = $node2prev{$node}; 3626 } 3627 $T2H_NAME{FastBack} = &clean_name($node); 3628 $T2H_HREF{FastBack} = $node2href{$node}; 3629 $T2H_NODE{FastBack} = $node; 3630 3631 $node = $T2H_NODE{This}; 3632 $node = $node2next{$node}; 3633 $T2H_NAME{Next} = &clean_name($node); 3634 $T2H_HREF{Next} = $node2href{$node}; 3635 $T2H_NODE{Next} = $node; 3636 3637 $node = $T2H_NODE{This}; 3638 if ($node2up{$node} && $node2up{$node} ne 'Top'&& 3639 ($node2next{$node} eq $T2H_NODE{Forward} || ! $node2next{$node})) 3640 { 3641 $node = $node2up{$node}; 3642 while ($node && $node ne $node2up{$node} && ! $node2next{$node}) 3643 { 3644 $node = $node2up{$node}; 3645 } 3646 } 3647 $node = $node2next{$node}; 3648 $T2H_NAME{FastForward} = &clean_name($node); 3649 $T2H_HREF{FastForward} = $node2href{$node}; 3650 $T2H_NODE{FastForward} = $node; 3651 3652 if (! defined($FH)) 3653 { 3654 open(FILE, "> $docu_rdir$docu_doc") || 3655 die "$ERROR: Can't open $docu_rdir$docu_doc for writing: $!\n"; 3656 $FH = \*FILE; 3657 &$T2H_print_page_head($FH); 3658 t2h_print_label($FH); 3659 &$T2H_print_chapter_header($FH) if $T2H_SPLIT eq 'chapter'; 3660 } 3661 else 3662 { 3663 t2h_print_label($FH); 3664 } 3665 3666 $T2H_THIS_SECTION = []; 3667 while (@doc_lines) { 3668 $_ = shift(@doc_lines); 3669 last if ($_ eq $SECTIONEND || $_ eq $CHAPTEREND); 3670 push(@$T2H_THIS_SECTION, $_); 3671 } 3672 $previous = $_; 3673 &$T2H_print_section($FH); 3674 3675 if ($T2H_VERBOSE) 3676 { 3677 $counter++; 3678 print "." if $counter =~ /00$/; 3679 } 3680} 3681if ($T2H_SPLIT) 3682{ 3683 &$T2H_print_chapter_footer($FH) if $T2H_SPLIT eq 'chapter'; 3684 &$T2H_print_page_foot($FH); 3685 close($FH); 3686} 3687print "\n" if $T2H_VERBOSE; 3688 3689############################################################################# 3690# Print ToC, Overview, Footnotes 3691# 3692undef $T2H_HREF{Prev}; 3693undef $T2H_HREF{Next}; 3694undef $T2H_HREF{Back}; 3695undef $T2H_HREF{Forward}; 3696undef $T2H_HREF{Up}; 3697 3698if (@foot_lines) 3699{ 3700 print "# writing Footnotes in $docu_foot_file...\n" if $T2H_VERBOSE; 3701 open (FILE, "> $docu_foot_file") || die "$ERROR: Can't open $docu_foot_file for writing: $!\n" 3702 if $T2H_SPLIT; 3703 $T2H_HREF{This} = $docu_foot; 3704 $T2H_NAME{This} = $T2H_WORDS->{$T2H_LANG}->{'Footnotes_Title'}; 3705 $T2H_THIS_SECTION = \@foot_lines; 3706 &$T2H_print_Footnotes(\*FILE); 3707 close(FILE) if $T2H_SPLIT; 3708} 3709 3710if (@toc_lines) 3711{ 3712 print "# writing Toc in $docu_toc_file...\n" if $T2H_VERBOSE; 3713 open (FILE, "> $docu_toc_file") || die "$ERROR: Can't open $docu_toc_file for writing: $!\n" 3714 if $T2H_SPLIT; 3715 $T2H_HREF{This} = $T2H_HREF{Contents}; 3716 $T2H_NAME{This} = $T2H_NAME{Contents}; 3717 $T2H_THIS_SECTION = \@toc_lines; 3718 &$T2H_print_Toc(\*FILE); 3719 close(FILE) if $T2H_SPLIT; 3720} 3721 3722if (@stoc_lines) 3723{ 3724 print "# writing Overview in $docu_stoc_file...\n" if $T2H_VERBOSE; 3725 open (FILE, "> $docu_stoc_file") || die "$ERROR: Can't open $docu_stoc_file for writing: $!\n" 3726 if $T2H_SPLIT; 3727 3728 $T2H_HREF{This} = $T2H_HREF{Overview}; 3729 $T2H_NAME{This} = $T2H_NAME{Overview}; 3730 $T2H_THIS_SECTION = \@stoc_lines; 3731 &$T2H_print_Overview(\*FILE); 3732 close(FILE) if $T2H_SPLIT; 3733} 3734 3735if ($about_body = &$T2H_about_body()) 3736{ 3737 print "# writing About in $docu_about_file...\n" if $T2H_VERBOSE; 3738 open (FILE, "> $docu_about_file") || die "$ERROR: Can't open $docu_about_file for writing: $!\n" 3739 if $T2H_SPLIT; 3740 3741 $T2H_HREF{This} = $T2H_HREF{About}; 3742 $T2H_NAME{This} = $T2H_NAME{About}; 3743 $T2H_THIS_SECTION = [$about_body]; 3744 &$T2H_print_About(\*FILE); 3745 close(FILE) if $T2H_SPLIT; 3746} 3747 3748unless ($T2H_SPLIT) 3749{ 3750 &$T2H_print_page_foot(\*FILE); 3751 close (FILE); 3752} 3753 3754Finish: 3755&l2h_FinishFromHtml if ($T2H_L2H); 3756&l2h_Finish if($T2H_L2H); 3757print "# that's all folks\n" if $T2H_VERBOSE; 3758 3759exit(0); 3760 3761#+++############################################################################ 3762# # 3763# Low level functions # 3764# # 3765#---############################################################################ 3766 3767sub LocateIncludeFile 3768{ 3769 my $file = shift; 3770 my $dir; 3771 3772 return $file if (-e $file && -r $file); 3773 foreach $dir (@T2H_INCLUDE_DIRS) 3774 { 3775 return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file"); 3776 } 3777 return undef; 3778} 3779 3780sub clean_name 3781{ 3782 local ($_); 3783 $_ = &remove_style($_[0]); 3784 &unprotect_texi; 3785 return $_; 3786} 3787 3788sub update_sec_num { 3789 local($name, $level) = @_; 3790 my $ret; 3791 3792 $level--; # here we start at 0 3793 if ($name =~ /^appendix/ || @appendix_sec_num) { 3794 # appendix style 3795 if (@appendix_sec_num) { 3796 &incr_sec_num($level, @appendix_sec_num); 3797 } else { 3798 @appendix_sec_num = ('A', 0, 0, 0); 3799 } 3800 $ret = join('.', @appendix_sec_num[0..$level]); 3801 } else { 3802 # normal style 3803 if (@normal_sec_num) 3804 { 3805 &incr_sec_num($level, @normal_sec_num); 3806 } 3807 else 3808 { 3809 @normal_sec_num = (1, 0, 0, 0); 3810 } 3811 $ret = join('.', @normal_sec_num[0..$level]); 3812 } 3813 3814 $ret .= "." if $level == 0; 3815 return $ret; 3816} 3817 3818sub incr_sec_num { 3819 local($level, $l); 3820 $level = shift(@_); 3821 $_[$level]++; 3822 foreach $l ($level+1 .. 3) { 3823 $_[$l] = 0; 3824 } 3825} 3826 3827sub Sec2UpNode 3828{ 3829 my $sec = shift; 3830 my $num = $sec2number{$sec}; 3831 3832 return '' unless $num; 3833 return 'Top' unless $num =~ /\.\d+/; 3834 $num =~ s/\.[^\.]*$//; 3835 $num = $num . '.' unless $num =~ /\./; 3836 return $sec2node{$number2sec{$num}}; 3837} 3838 3839sub Sec2PrevNode 3840{ 3841 my $sec = shift; 3842 my $num = $sec2number{$sec}; 3843 my ($i, $post); 3844 3845 if ($num =~ /(\w+)(\.$|$)/) 3846 { 3847 $num = $`; 3848 $i = $1; 3849 $post = $2; 3850 if ($i eq 'A') 3851 { 3852 $i = $normal_sec_num[0]; 3853 } 3854 elsif ($i ne '1') 3855 { 3856 $i--; 3857 } 3858 else 3859 { 3860 return ''; 3861 } 3862 return $sec2node{$number2sec{$num . $i . $post}} 3863 } 3864 return ''; 3865} 3866 3867sub Sec2NextNode 3868{ 3869 my $sec = shift; 3870 my $num = $sec2number{$sec}; 3871 my $i; 3872 3873 if ($num =~ /(\w+)(\.$|$)/) 3874 { 3875 $num = $`; 3876 $i = $1; 3877 $post = $2; 3878 if ($post eq '.' && $i eq $normal_sec_num[0]) 3879 { 3880 $i = 'A'; 3881 } 3882 else 3883 { 3884 $i++; 3885 } 3886 return $sec2node{$number2sec{$num . $i . $post}} 3887 } 3888 return ''; 3889} 3890 3891sub check { 3892 local($_, %seen, %context, $before, $match, $after); 3893 3894 while (<>) { 3895 if (/\@(\*|\.|\:|\@|\{|\})/) { 3896 $seen{$&}++; 3897 $context{$&} .= "> $_" if $T2H_VERBOSE; 3898 $_ = "$`XX$'"; 3899 redo; 3900 } 3901 if (/\@(\w+)/) { 3902 ($before, $match, $after) = ($`, $&, $'); 3903 if ($before =~ /\b[\w-]+$/ && $after =~ /^[\w-.]*\b/) { # e-mail address 3904 $seen{'e-mail address'}++; 3905 $context{'e-mail address'} .= "> $_" if $T2H_VERBOSE; 3906 } else { 3907 $seen{$match}++; 3908 $context{$match} .= "> $_" if $T2H_VERBOSE; 3909 } 3910 $match =~ s/^\@/X/; 3911 $_ = "$before$match$after"; 3912 redo; 3913 } 3914 } 3915 3916 foreach (sort(keys(%seen))) { 3917 if ($T2H_VERBOSE) { 3918 print "$_\n"; 3919 print $context{$_}; 3920 } else { 3921 print "$_ ($seen{$_})\n"; 3922 } 3923 } 3924} 3925 3926sub open { 3927 local($name) = @_; 3928 3929 ++$fh_name; 3930 if (open($fh_name, $name)) { 3931 unshift(@fhs, $fh_name); 3932 } else { 3933 warn "$ERROR Can't read file $name: $!\n"; 3934 } 3935} 3936 3937sub init_input { 3938 @fhs = (); # hold the file handles to read 3939 @input_spool = (); # spooled lines to read 3940 $fh_name = 'FH000'; 3941 &open($docu); 3942} 3943 3944sub next_line { 3945 local($fh, $line); 3946 3947 if (@input_spool) { 3948 $line = shift(@input_spool); 3949 return($line); 3950 } 3951 while (@fhs) { 3952 $fh = $fhs[0]; 3953 $line = <$fh>; 3954 return($line) if $line; 3955 close($fh); 3956 shift(@fhs); 3957 } 3958 return(undef); 3959} 3960 3961# used in pass 1, use &next_line 3962sub skip_until { 3963 local($tag) = @_; 3964 local($_); 3965 3966 while ($_ = &next_line) { 3967 return if /^\@end\s+$tag\s*$/; 3968 } 3969 die "* Failed to find '$tag' after: " . $lines[$#lines]; 3970} 3971 3972# used in pass 1 for l2h use &next_line 3973sub string_until { 3974 local($tag) = @_; 3975 local($_, $string); 3976 3977 while ($_ = &next_line) { 3978 return $string if /^\@end\s+$tag\s*$/; 3979# $_ =~ s/hbox/mbox/g; 3980 $string = $string.$_; 3981 } 3982 die "* Failed to find '$tag' after: " . $lines[$#lines]; 3983} 3984 3985# 3986# HTML stacking to have a better HTML output 3987# 3988 3989sub html_reset { 3990 @html_stack = ('html'); 3991 $html_element = 'body'; 3992} 3993 3994sub html_push { 3995 local($what) = @_; 3996 push(@html_stack, $html_element); 3997 $html_element = $what; 3998} 3999 4000sub html_push_if { 4001 local($what) = @_; 4002 push(@html_stack, $html_element) 4003 if ($html_element && $html_element ne 'P'); 4004 $html_element = $what; 4005} 4006 4007sub html_pop { 4008 $html_element = pop(@html_stack); 4009} 4010 4011sub html_pop_if { 4012 local($elt); 4013 4014 if (@_) { 4015 foreach $elt (@_) { 4016 if ($elt eq $html_element) { 4017 $html_element = pop(@html_stack) if @html_stack; 4018 last; 4019 } 4020 } 4021 } else { 4022 $html_element = pop(@html_stack) if @html_stack; 4023 } 4024} 4025 4026sub html_debug { 4027 local($what, $line) = @_; 4028 if ($T2H_DEBUG & $DEBUG_HTML) 4029 { 4030 $what = "\n" unless $what; 4031 return("<!-- $line @html_stack, $html_element -->$what") 4032 } 4033 return($what); 4034} 4035 4036# to debug the output... 4037sub debug { 4038 local($what, $line) = @_; 4039 return("<!-- $line -->$what") 4040 if $T2H_DEBUG & $DEBUG_HTML; 4041 return($what); 4042} 4043 4044sub normalise_node { 4045 local $_ = $_[0]; 4046 s/\s+/ /g; 4047 s/ $//; 4048 s/^ //; 4049 &protect_texi; 4050 &protect_html; 4051 $_ = substitute_style($_); 4052 $_[0] = $_; 4053} 4054 4055sub menu_entry { 4056 local($entry, $node, $descr) = @_; 4057 local($href); 4058 4059 &normalise_node($node); 4060 $href = $node2href{$node}; 4061 if ($href) { 4062 $descr =~ s/^\s+//; 4063 if ($T2H_NUMBER_SECTIONS) 4064 { 4065 $entry = $node2sec{$entry} if ! $descr && $node2sec{$entry}; 4066 push(@lines2, 4067 '<TR><TD ALIGN="left">' . 4068 &t2h_anchor('', $href, $entry) . 4069 '</TD><TD ALIGN="left">' . $descr . "</TD><TR>\n"); 4070 } 4071 else 4072 { 4073 push(@lines2, "<LI>" . &t2h_anchor('', $href, $entry) . ": $descr\n"); 4074 } 4075 } else { 4076 warn "$ERROR Undefined node ($node): $_"; 4077 } 4078} 4079 4080sub do_ctrl { "^$_[0]" } 4081 4082sub do_email { 4083 local($addr, $text) = split(/,\s*/, $_[0]); 4084 4085 $text = $addr unless $text; 4086 &t2h_anchor('', "mailto:$addr", $text); 4087} 4088 4089sub do_sc 4090{ 4091 # l2h does this much better 4092 return &l2h_ToLatex("{\\sc ".&unprotect_html($_[0])."}") if ($T2H_L2H); 4093 return "\U$_[0]\E"; 4094} 4095 4096sub do_math 4097{ 4098 return &l2h_ToLatex("\$".&unprotect_html($_[0])."\$") if ($T2H_L2H); 4099 return "<EM>".$text."</EM>"; 4100} 4101 4102sub do_uref { 4103 local($url, $text, $only_text) = split(/,\s*/, $_[0]); 4104 4105 $text = $only_text if $only_text; 4106 $text = $url unless $text; 4107 &t2h_anchor('', $url, $text); 4108} 4109 4110sub do_url { &t2h_anchor('', $_[0], $_[0]) } 4111 4112sub do_acronym 4113{ 4114 return '<FONT SIZE="-1">' . $_[0] . '</FONT>'; 4115} 4116 4117sub do_accent 4118{ 4119 return "&$_[0]acute;" if $_[1] eq 'H'; 4120 return "$_[0]." if $_[1] eq 'dotaccent'; 4121 return "$_[0]*" if $_[1] eq 'ringaccent'; 4122 return "$_[0]".'[' if $_[1] eq 'tieaccent'; 4123 return "$_[0]".'(' if $_[1] eq 'u'; 4124 return "$_[0]_" if $_[1] eq 'ubaraccent'; 4125 return ".$_[0]" if $_[1] eq 'udotaccent'; 4126 return "$_[0]<" if $_[1] eq 'v'; 4127 return "$_[0]," if $_[1] eq ','; 4128 return "$_[0]" if $_[1] eq 'dotless'; 4129 return undef; 4130} 4131 4132sub apply_style { 4133 local($texi_style, $text) = @_; 4134 local($style); 4135 4136 $style = $style_map{$texi_style}; 4137 if (defined($style)) { # known style 4138 if ($style =~ /^\"/) { # add quotes 4139 $style = $'; 4140 $text = "\`$text\'"; 4141 } 4142 if ($style =~ /^\&/) { # custom 4143 $style = $'; 4144 $text = &$style($text, $texi_style); 4145 } elsif ($style) { # good style 4146 $text = "<$style>$text</$style>"; 4147 } else { # no style 4148 } 4149 } else { # unknown style 4150 $text = undef; 4151 } 4152 return($text); 4153} 4154 4155# remove Texinfo styles 4156sub remove_style { 4157 local($_) = @_; 4158 s/\@\w+{([^\{\}]+)}/$1/g; 4159 return($_); 4160} 4161 4162sub substitute_style { 4163 local($_) = @_; 4164 local($changed, $done, $style, $text); 4165 4166 &simple_substitutions; 4167 $changed = 1; 4168 while ($changed) { 4169 $changed = 0; 4170 $done = ''; 4171 while (/\@(\w+)\{([^\{\}]+)\}/ || /\@(,)\{([^\{\}]+)\}/) { 4172 $text = &apply_style($1, $2); 4173 if ($text) { 4174 $_ = "$`$text$'"; 4175 $changed = 1; 4176 } else { 4177 $done .= "$`\@$1"; 4178 $_ = "{$2}$'"; 4179 } 4180 } 4181 $_ = $done . $_; 4182 } 4183 return($_); 4184} 4185 4186sub t2h_anchor { 4187 local($name, $href, $text, $newline) = @_; 4188 local($result); 4189 4190 $result = "<A"; 4191 $result .= " NAME=\"$name\"" if $name; 4192 $result .= " HREF=\"$href\"" if $href; 4193 $result .= ">$text</A>"; 4194 $result .= "\n" if $newline; 4195 return($result); 4196} 4197 4198sub pretty_date { 4199 local(@MoY, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); 4200 4201 @MoY = ('January', 'February', 'March', 'April', 'May', 'June', 4202 'July', 'August', 'September', 'October', 'November', 'December'); 4203 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); 4204 $year += ($year < 70) ? 2000 : 1900; 4205 # obachman: Let's do it as the Americans do 4206 return("$MoY[$mon], $mday $year"); 4207} 4208 4209sub doc_href { 4210 local($num) = @_; 4211 4212 return("${docu_name}_$num.$docu_ext"); 4213} 4214 4215sub sec_href 4216{ 4217 return $node2href{$sec2node{$_[0]}}; 4218} 4219 4220sub next_doc { 4221 $docu_doc = &doc_href(++$doc_num); 4222} 4223 4224sub t2h_print_lines { 4225 my ($fh, $lines) = @_; 4226 local($_); 4227 $lines = $T2H_THIS_SECTION unless $lines; 4228 my $cnt = 0; 4229 for (@$lines) 4230 { 4231 $_ = l2h_FromHtml($_) if ($T2H_L2H); 4232 if (/^$PROTECTTAG/o) { 4233 $_ = $tag2pro{$_}; 4234 } else { 4235 &unprotect_texi; 4236 } 4237 print $fh $_; 4238 $cnt += split(/\W*\s+\W*/); 4239 } 4240 return $cnt; 4241} 4242 4243sub protect_texi { 4244 # protect @ { } ` ' 4245 s/\@\@/$;0/go; 4246 s/\@\{/$;1/go; 4247 s/\@\}/$;2/go; 4248 s/\@\`/$;3/go; 4249 s/\@\'/$;4/go; 4250} 4251 4252sub protect_html { 4253 local($what) = @_; 4254 # protect & < > 4255 $what =~ s/\&/\&\#38;/g; 4256 $what =~ s/\</\&\#60;/g; 4257 $what =~ s/\>/\&\#62;/g; 4258 # restore anything in quotes 4259 # this fixes my problem where I had: 4260 # < IMG SRC="leftarrow.gif" ALT="<--" > but what if I wanted < in my ALT text ?? 4261 # maybe byte stuffing or some other technique should be used. 4262 $what =~ s/\"([^\&]+)\&\#60;(.*)\"/"$1<$2"/g; 4263 $what =~ s/\"([^\&]+)\&\#62;(.*)\"/"$1>$2"/g; 4264 $what =~ s/\"([^\&]+)\&\#38;(.*)\"/"$1&$2"/g; 4265 # but recognize some HTML things 4266 $what =~ s/\&\#60;\/A\&\#62;/<\/A>/g; # </A> 4267 $what =~ s/\&\#60;A ([^\&]+)\&\#62;/<A $1>/g; # <A [^&]+> 4268 $what =~ s/\&\#60;IMG ([^\&]+)\&\#62;/<IMG $1>/g; # <IMG [^&]+> 4269 return($what); 4270} 4271 4272sub unprotect_texi { 4273 s/$;0/\@/go; 4274 s/$;1/\{/go; 4275 s/$;2/\}/go; 4276 s/$;3/\`/go; 4277 s/$;4/\'/go; 4278} 4279 4280sub Unprotect_texi 4281{ 4282 local $_ = shift; 4283 &unprotect_texi; 4284 return($_); 4285} 4286 4287sub unprotect_html { 4288 local($what) = @_; 4289 $what =~ s/\&\#38;/\&/g; 4290 $what =~ s/\&\#60;/\</g; 4291 $what =~ s/\&\#62;/\>/g; 4292 return($what); 4293} 4294 4295sub byalpha { 4296 $key2alpha{$a} cmp $key2alpha{$b}; 4297} 4298 4299sub t2h_print_label 4300{ 4301 my $fh = shift; 4302 my $href = shift || $T2H_HREF{This}; 4303 $href =~ s/.*#(.*)$/$1/; 4304 print $fh qq{<A NAME="$href"></A>\n}; 4305} 4306 4307############################################################################## 4308 4309 # These next few lines are legal in both Perl and nroff. 4310 4311.00 ; # finish .ig 4312 4313'di \" finish diversion--previous line must be blank 4314.nr nl 0-1 \" fake up transition to first page again 4315.nr % 0 \" start at page 1 4316'; __END__ ############# From here on it's a standard manual page ############ 4317.so /usr/local/man/man1/texi2html.1 4318