1#!/usr/bin/perl -- 2# perl 3'di '; 4'ig 00 '; 5#+############################################################################## 6# 7# *** THIS PROGRAM WAS MODIFIED FOR PROCESSING THE GAMBIT MANUAL *** 8# 9# The original file can be found here 10# 11# http://nongnu.askapache.com/texi2html/texi2html-1.82.tar.gz 12# 13# The lines that were modified contain the comment "###GAMBIT###". 14# 15#-############################################################################## 16#+############################################################################## 17# 18# texi2html: Program to transform Texinfo documents to HTML 19# 20# Copyright (C) 1999-2005 Patrice Dumas <dumas@centre-cired.fr>, 21# Derek Price <derek@ximbiot.com>, 22# Adrian Aichner <adrian@xemacs.org>, 23# & others. 24# 25# This program is free software; you can redistribute it and/or modify 26# it under the terms of the GNU General Public License as published by 27# the Free Software Foundation; either version 2 of the License, or 28# (at your option) any later version. 29# 30# This program is distributed in the hope that it will be useful, 31# but WITHOUT ANY WARRANTY; without even the implied warranty of 32# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33# GNU General Public License for more details. 34# 35# You should have received a copy of the GNU General Public License 36# along with this program; if not, write to the Free Software 37# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 38# 02110-1301 USA 39# 40#-############################################################################## 41# The man page for this program is included at the end of this file and can be 42# viewed using the command 'nroff -man texi2html'. 43 44# for POSIX::setlocale and File::Spec 45require 5.00405; 46# Perl pragma to restrict unsafe constructs 47use strict; 48# used in case of tests, to revert to "C" locale. 49use POSIX qw(setlocale LC_ALL LC_CTYPE); 50# used to obtain the name of the current working directory 51use Cwd; 52# Used to find the parent directory of this script. 53use File::Basename; 54# used to find a relative path back to the current working directory 55use File::Spec; 56 57# 58# According to 59# larry.jones@sdrc.com (Larry Jones) 60# this pragma is not present in perl5.004_02: 61# 62# Perl pragma to control optional warnings 63# use warnings; 64 65#++########################################################################## 66# 67# NOTE FOR DEBUGGING THIS SCRIPT: 68# You can run 'perl texi2html.pl' directly, provided you have the script 69# in the same directory with, or the environment variable T2H_HOME set to 70# the directory containing, the texi2html.init, T2h_i18n.pm, translations.pl, 71# l2h.init, & T2h_l2h.pm files 72# 73#--########################################################################## 74my $T2H_HOME = defined $ENV{T2H_HOME} ? $ENV{T2H_HOME} : dirname $0; 75if ($0 =~ /\.pl$/) 76{ 77 # Issue a warning in debugging mode if $T2H_HOME is set but isn't 78 # accessible. 79 if (!-e $T2H_HOME) 80 { warn "T2H_HOME ($T2H_HOME) does not exist."; } 81 elsif (!-d $T2H_HOME) 82 { warn "T2H_HOME ($T2H_HOME) is not a directory."; } 83 elsif (!-x $T2H_HOME) 84 { warn "T2H_HOME ($T2H_HOME) is not accessible."; } 85} 86 87# CVS version: 88# $Id: texi2html.pl,v 1.255 2009/01/05 11:44:48 pertusus Exp $ 89 90# Homepage: 91my $T2H_HOMEPAGE = "http://www.nongnu.org/texi2html/"; 92 93# Authors (appears in comments): 94my $T2H_AUTHORS = <<EOT; 95texi2html was written by: 96 Lionel Cons <Lionel.Cons\@cern.ch> (original author) 97 Karl Berry <karl\@freefriends.org> 98 Olaf Bachmann <obachman\@mathematik.uni-kl.de> 99 and many others. 100Maintained by: Many creative people. 101Send bugs and suggestions to <texi2html-bug\@nongnu.org> 102EOT 103 104# Version: set in configure.in 105my $THISVERSION = '1.82'; 106my $THISPROG = "texi2html $THISVERSION"; # program name and version 107 108#+++######################################################################## 109# # 110# Paths and file names # 111# # 112#---######################################################################## 113 114# set by configure, prefix for the sysconfdir and so on 115my $prefix = '/usr/local'; 116my $datarootdir = '${prefix}/share'; 117my $sysconfdir; 118my $pkgdatadir; 119my $datadir; 120 121# We need to eval as $prefix has to be expanded. However when we haven't 122# run configure @sysconfdir will be expanded as an array, thus we verify 123# whether configure was run or not 124if ('${prefix}/etc' ne '@' . 'sysconfdir@') 125{ 126 $sysconfdir = eval '"${prefix}/etc"'; 127} 128else 129{ 130 $sysconfdir = "/usr/local/etc"; 131} 132 133if ('${datarootdir}' ne '@' . 'datadir@') 134{ 135 $pkgdatadir = eval '"${datarootdir}/texi2html"'; 136 $datadir = eval '"${datarootdir}"'; 137} 138else 139{ 140 $pkgdatadir = "/usr/local/share/texi2html"; 141 $datadir = "/usr/local/share"; 142} 143 144my $i18n_dir = 'i18n'; # name of the directory containing the per language files 145my $conf_file_name = 'Config' ; 146my $texinfo_htmlxref = 'htmlxref.cnf'; 147 148my $target_prefix = "t_h"; 149 150# directories for texi2html init files 151my @texi2html_config_dirs = ('./'); 152push @texi2html_config_dirs, "$ENV{'HOME'}/.texi2html/" if (defined($ENV{'HOME'})); 153push @texi2html_config_dirs, "$sysconfdir/texi2html/" if (defined($sysconfdir)); 154push @texi2html_config_dirs, "$pkgdatadir" if (defined($pkgdatadir)); 155 156# directories for texinfo configuration files 157my @texinfo_config_dirs = ('./.texinfo/'); 158push @texinfo_config_dirs, "$ENV{'HOME'}/.texinfo/" if (defined($ENV{'HOME'})); 159push @texinfo_config_dirs, "$sysconfdir/texinfo/" if (defined($sysconfdir)); 160push @texinfo_config_dirs, "$datadir/texinfo/" if (defined($datadir)); 161 162 163#+++######################################################################## 164# # 165# Constants # 166# # 167#---######################################################################## 168 169my $DEBUG_MENU = 1; 170my $DEBUG_INDEX = 2; 171my $DEBUG_TEXI = 4; 172my $DEBUG_MACROS = 8; 173my $DEBUG_FORMATS = 16; 174my $DEBUG_ELEMENTS = 32; 175my $DEBUG_USER = 64; 176my $DEBUG_L2H = 128; 177 178my $ERROR = "***"; # prefix for errors 179my $WARN = "**"; # prefix for warnings 180 181my $VARRE = '[\w\-]+'; # RE for a variable name 182my $NODERE = '[^:]+'; # RE for node names 183 184my $MAX_LEVEL = 4; 185my $MIN_LEVEL = 1; 186 187#+++########################################################################### 188# # 189# Initialization # 190# Some declarations, some functions that are GPL and therefore cannot be in # 191# texi2html.init, some functions that are not to be customized. # 192# Pasted content of File $(srcdir)/texi2html.init: Default initializations # 193# # 194#---########################################################################### 195 196{ 197package Texi2HTML::Config; 198 199 200sub load($) 201{ 202 my $file = shift; 203 eval { require($file) ;}; 204 if ($@ ne '') 205 { 206 print STDERR "error loading $file: $@\n"; 207 return 0; 208 } 209 return 1; 210} 211 212# customization options variables 213 214use vars qw( 215$DEBUG 216$PREFIX 217$VERBOSE 218$SUBDIR 219$IDX_SUMMARY 220$SPLIT 221$SHORT_REF 222@EXPAND 223$EXPAND 224$TOP 225$DOCTYPE 226$FRAMESET_DOCTYPE 227$ERROR_LIMIT 228$CHECK 229$TEST 230$DUMP_TEXI 231$MACRO_EXPAND 232$USE_GLOSSARY 233$INVISIBLE_MARK 234$USE_ISO 235$TOP_FILE 236$TOC_FILE 237$FRAMES 238$SHOW_MENU 239$NUMBER_SECTIONS 240$USE_NODES 241$USE_SECTIONS 242$USE_NODE_TARGET 243$USE_UNICODE 244$USE_UNIDECODE 245$TRANSLITERATE_NODE 246$NODE_FILES 247$NODE_NAME_IN_MENU 248$AVOID_MENU_REDUNDANCY 249$SECTION_NAVIGATION 250$MONOLITHIC 251$SHORTEXTN 252$EXTENSION 253$OUT 254$NOVALIDATE 255$DEF_TABLE 256$LANG 257$DO_CONTENTS 258$DO_SCONTENTS 259$SEPARATED_FOOTNOTES 260$TOC_LINKS 261$L2H 262$L2H_L2H 263$L2H_SKIP 264$L2H_TMP 265$L2H_CLEAN 266$L2H_FILE 267$L2H_HTML_VERSION 268$EXTERNAL_DIR 269@INCLUDE_DIRS 270@PREPEND_DIRS 271@CONF_DIRS 272$IGNORE_PREAMBLE_TEXT 273@CSS_FILES 274@CSS_REFS 275$INLINE_CONTENTS 276$INLINE_INSERTCOPYING 277); 278 279# customization variables 280# ENCODING is deprecated 281use vars qw( 282$ENCODING 283 284$ENCODING_NAME 285$DOCUMENT_ENCODING 286$OUT_ENCODING 287$IN_ENCODING 288$DEFAULT_ENCODING 289$MENU_PRE_STYLE 290$MENU_PRE_COMPLEX_FORMAT 291$CENTER_IMAGE 292$EXAMPLE_INDENT_CELL 293$SMALL_EXAMPLE_INDENT_CELL 294$SMALL_FONT_SIZE 295$SMALL_RULE 296$DEFAULT_RULE 297$MIDDLE_RULE 298$BIG_RULE 299$TOP_HEADING 300$INDEX_CHAPTER 301$SPLIT_INDEX 302$HREF_DIR_INSTEAD_FILE 303$USE_MENU_DIRECTIONS 304$USE_UP_FOR_ADJACENT_NODES 305$AFTER_BODY_OPEN 306$PRE_BODY_CLOSE 307$EXTRA_HEAD 308$VERTICAL_HEAD_NAVIGATION 309$WORDS_IN_PAGE 310$ICONS 311$UNNUMBERED_SYMBOL_IN_MENU 312$SIMPLE_MENU 313$MENU_SYMBOL 314$USE_ACCESSKEY 315$USE_REL_REV 316$USE_LINKS 317$OPEN_QUOTE_SYMBOL 318$CLOSE_QUOTE_SYMBOL 319$NO_BULLET_LIST_STYLE 320$NO_BULLET_LIST_ATTRIBUTE 321$TOP_NODE_FILE 322$TOP_NODE_UP 323$NODE_FILE_EXTENSION 324$BEFORE_OVERVIEW 325$AFTER_OVERVIEW 326$BEFORE_TOC_LINES 327$AFTER_TOC_LINES 328$NEW_CROSSREF_STYLE 329$TOP_HEADING_AT_BEGINNING 330$USER 331$USE_NUMERIC_ENTITY 332$USE_SETFILENAME 333$SEPARATE_DESCRIPTION 334$IGNORE_BEFORE_SETFILENAME 335$OVERVIEW_LINK_TO_TOC 336$COMPLETE_IMAGE_PATHS 337$DATE 338%ACTIVE_ICONS 339%NAVIGATION_TEXT 340%PASSIVE_ICONS 341%BUTTONS_NAME 342%BUTTONS_GOTO 343%BUTTONS_EXAMPLE 344%BUTTONS_ACCESSKEY 345%BUTTONS_REL 346@CHAPTER_BUTTONS 347@MISC_BUTTONS 348@SECTION_BUTTONS 349@SECTION_FOOTER_BUTTONS 350@NODE_FOOTER_BUTTONS 351@LINKS_BUTTONS 352@IMAGE_EXTENSIONS 353); 354 355# customization variables which may be guessed in the script 356#our $ADDRESS; 357use vars qw( 358$BODYTEXT 359$CSS_LINES 360$DOCUMENT_DESCRIPTION 361$EXTERNAL_CROSSREF_SPLIT 362); 363 364# I18n 365use vars qw( 366$I 367$LANGUAGES 368); 369 370# customizable subroutines references 371use vars qw( 372$print_section 373$one_section 374$end_section 375$print_Top_header 376$print_Top_footer 377$print_Top 378$print_Toc 379$print_Overview 380$print_Footnotes 381$print_About 382$print_misc_header 383$print_misc_footer 384$print_misc 385$print_section_header 386$print_section_footer 387$print_chapter_header 388$print_chapter_footer 389$print_element_header 390$print_page_head 391$print_page_foot 392$print_head_navigation 393$print_foot_navigation 394$button_icon_img 395$print_navigation 396$about_body 397$print_frame 398$print_toc_frame 399$toc_body 400$titlepage 401$insertcopying 402$css_lines 403$print_redirection_page 404$translate_names 405$init_out 406$finish_out 407$node_file_name 408$element_file_name 409$node_target_name 410$element_target_name 411$placed_target_file_name 412$inline_contents 413$program_string 414 415$preserve_misc_command 416$protect_text 417$anchor 418$anchor_label 419$element_label 420$misc_element_label 421$def_item 422$def 423$menu 424$menu_command 425$menu_link 426$menu_description 427$menu_comment 428$simple_menu_link 429$ref_beginning 430$info_ref 431$book_ref 432$external_href 433$external_ref 434$internal_ref 435$table_item 436$table_line 437$row 438$cell 439$list_item 440$comment 441$def_line 442$def_line_no_texi 443$heading_no_texi 444$raw 445$raw_no_texi 446$heading 447$element_heading 448$paragraph 449$preformatted 450$foot_line_and_ref 451$foot_section 452$address 453$image 454$image_files 455$index_entry_label 456$index_entry 457$index_entry_command 458$index_letter 459$print_index 460$printindex 461$index_summary 462$summary_letter 463$complex_format 464$cartouche 465$sp 466$definition_category 467$definition_index_entry 468$table_list 469$copying_comment 470$documentdescription 471$index_summary_file_entry 472$index_summary_file_end 473$index_summary_file_begin 474$style 475$format 476$normal_text 477$empty_line 478$unknown 479$unknown_style 480$float 481$caption_shortcaption 482$caption_shortcaption_command 483$listoffloats 484$listoffloats_entry 485$listoffloats_caption 486$listoffloats_float_style 487$listoffloats_style 488$acronym_like 489$quotation 490$quotation_prepend_text 491$paragraph_style_command 492$heading_texi 493$index_element_heading_texi 494$format_list_item_texi 495$begin_format_texi 496$begin_style_texi 497$begin_paragraph_texi 498$tab_item_texi 499$colon_command 500$simple_command 501$thing_command 502$begin_special_region 503$end_special_region 504 505$PRE_ABOUT 506$AFTER_ABOUT 507); 508 509# hash which entries might be redefined by the user 510use vars qw( 511$complex_format_map 512%accent_map 513%def_map 514%format_map 515%simple_map 516%simple_map_pre 517%simple_map_texi 518%simple_map_math 519%simple_map_pre_math 520%simple_map_texi_math 521%style_map 522%style_map_pre 523%style_map_texi 524%simple_format_simple_map_texi 525%simple_format_style_map_texi 526%simple_format_texi_map 527%command_type 528%paragraph_style 529%stop_paragraph_command 530%format_code_style 531%region_formats_kept 532%texi_formats_map 533%things_map 534%pre_map 535%texi_map 536%unicode_map 537%unicode_diacritical 538%transliterate_map 539%transliterate_accent_map 540%no_transliterate_map 541%ascii_character_map 542%ascii_simple_map 543%ascii_things_map 544%numeric_entity_map 545%perl_charset_to_html 546%misc_pages_targets 547%iso_symbols 548%misc_command 549%no_paragraph_commands 550%css_map 551%format_in_paragraph 552%special_list_commands 553%accent_letters 554%unicode_accents 555%special_accents 556%inter_item_commands 557$def_always_delimiters 558$def_in_type_delimiters 559$def_argument_separator_delimiters 560%colon_command_punctuation_characters 561@command_handler_init 562@command_handler_process 563@command_handler_finish 564%command_handler 565%special_style 566); 567 568# subject to change 569use vars qw( 570%makeinfo_encoding_to_map 571%makeinfo_unicode_to_eight_bit 572%eight_bit_to_unicode 573%t2h_encoding_aliases 574); 575 576# needed in this namespace for translations 577$I = \&Texi2HTML::I18n::get_string; 578 579# 580# Function refs covered by the GPL as part of the texi2html.pl original 581# code. As such they cannot appear in texi2html.init which is public 582# domain (at least the things coded by me, and, if I'm not wrong also the 583# things coded by Olaf -- Pat). 584# 585 586$toc_body = \&T2H_GPL_toc_body; 587$style = \&T2H_GPL_style; 588$format = \&T2H_GPL_format; 589$printindex = \&t2h_GPL_default_printindex; 590$summary_letter = \&t2h_default_summary_letter; 591 592sub T2H_GPL_toc_body($) 593{ 594 my $elements_list = shift; 595 return unless ($Texi2HTML::THISDOC{'DO_CONTENTS'} or 596 $Texi2HTML::THISDOC{'DO_SCONTENTS'} or $FRAMES); 597 my $current_level = 0; 598 my $ul_style = $NUMBER_SECTIONS ? $NO_BULLET_LIST_ATTRIBUTE : ''; 599 foreach my $element (@$elements_list) 600 { 601 next if ($element->{'top'}); 602 my $ind = ' ' x $current_level; 603 my $level = $element->{'toc_level'}; 604 print STDERR "Bug no toc_level for ($element) $element->{'texi'}\n" if (!defined ($level)); 605 if ($level > $current_level) 606 { 607 while ($level > $current_level) 608 { 609 $current_level++; 610 my $ln = "\n$ind<ul${ul_style}>\n"; 611 $ind = ' ' x $current_level; 612 push(@{$Texi2HTML::TOC_LINES}, $ln); 613 } 614 } 615 elsif ($level < $current_level) 616 { 617 while ($level < $current_level) 618 { 619 $current_level--; 620 $ind = ' ' x $current_level; 621 my $line = "</li>\n$ind</ul>"; 622 $line .= "</li>" if ($level == $current_level); 623 push(@{$Texi2HTML::TOC_LINES}, "$line\n"); 624 625 } 626 } 627 else 628 { 629 push(@{$Texi2HTML::TOC_LINES}, "</li>\n"); 630 } 631 # if there is more than one toc, in different files, the toc in 632 # the file different from $Texi2HTML::THISDOC{'toc_file'} may have 633 # wrong links, that is links that point to the same file and are 634 # therefore empty, although the section isn't in the current file, 635 # since it is in $Texi2HTML::THISDOC{'toc_file'}. 636 my $dest_for_toc = $element->{'file'}; 637 my $dest_for_stoc = $element->{'file'}; 638 my $dest_target_for_stoc = $element->{'target'}; 639 if ($Texi2HTML::Config::OVERVIEW_LINK_TO_TOC) 640 { 641 $dest_for_stoc = $Texi2HTML::THISDOC{'toc_file'}; 642 $dest_target_for_stoc = $element->{'tocid'}; 643 } 644 $dest_for_toc = '' if ($dest_for_toc eq $Texi2HTML::THISDOC{'toc_file'}); 645 $dest_for_stoc = '' if ($dest_for_stoc eq $Texi2HTML::THISDOC{'stoc_file'}); 646 my $text = $element->{'text'}; 647 #$text = $element->{'name'} unless ($NUMBER_SECTIONS); 648 my $toc_entry = "<li>" . &$anchor ($element->{'tocid'}, "$dest_for_toc#$element->{'target'}",$text); 649 my $stoc_entry = "<li>" . &$anchor ($element->{'stocid'}, "$dest_for_stoc#$dest_target_for_stoc",$text); 650 push (@{$Texi2HTML::TOC_LINES}, $ind . $toc_entry); 651 push(@{$Texi2HTML::OVERVIEW}, $stoc_entry. "</li>\n") if ($level == 1); 652 } 653 while (0 < $current_level) 654 { 655 $current_level--; 656 my $ind = ' ' x $current_level; 657 push(@{$Texi2HTML::TOC_LINES}, "</li>\n$ind</ul>\n"); 658 } 659 @{$Texi2HTML::TOC_LINES} = () unless ($Texi2HTML::THISDOC{'DO_CONTENTS'}); 660 if (@{$Texi2HTML::TOC_LINES}) 661 { 662 unshift @{$Texi2HTML::TOC_LINES}, $BEFORE_TOC_LINES; 663 push @{$Texi2HTML::TOC_LINES}, $AFTER_TOC_LINES; 664 } 665 @{$Texi2HTML::OVERVIEW} = () unless ($Texi2HTML::THISDOC{'DO_SCONTENTS'} or $FRAMES); 666 if (@{$Texi2HTML::OVERVIEW}) 667 { 668 unshift @{$Texi2HTML::OVERVIEW}, "<ul${ul_style}>\n"; 669 push @{$Texi2HTML::OVERVIEW}, "</ul>\n"; 670 unshift @{$Texi2HTML::OVERVIEW}, $BEFORE_OVERVIEW; 671 push @{$Texi2HTML::OVERVIEW}, $AFTER_OVERVIEW; 672 } 673} 674 675sub T2H_GPL_style($$$$$$$$$) 676{ # known style 677 my $style = shift; 678 my $command = shift; 679 my $text = shift; 680 my $args = shift; 681 my $no_close = shift; 682 my $no_open = shift; 683 my $line_nr = shift; 684 my $state = shift; 685 my $style_stack = shift; 686 687 my $do_quotes = 0; 688 my $use_attribute = 0; 689 my $use_begin_end = 0; 690 if (ref($style) eq 'HASH') 691 { 692 #print STDERR "GPL_STYLE $command ($style)\n"; 693 #print STDERR " @$args\n"; 694 if (ref($style->{'args'}) ne 'ARRAY') 695 { 696 print STDERR "BUG: args not an array for command `$command'\n"; 697 } 698 $do_quotes = $style->{'quote'}; 699 if ((@{$style->{'args'}} == 1) and defined($style->{'attribute'})) 700 { 701 $style = $style->{'attribute'}; 702 $use_attribute = 1; 703 $text = $args->[0]; 704 } 705 elsif (defined($style->{'function'})) 706 { 707 $text = &{$style->{'function'}}($command, $args, $style_stack, $state, $line_nr); 708 } 709 } 710 else 711 { 712 if ($style =~ s/^\"//) 713 { # add quotes 714 $do_quotes = 1; 715 } 716 if ($style =~ s/^\&//) 717 { # custom 718 $style = 'Texi2HTML::Config::' . $style; 719 eval "\$text = &$style(\$text, \$command, \$style_stack)"; 720 } 721 elsif ($style ne '') 722 { 723 $use_attribute = 1; 724 } 725 else 726 { # no style 727 } 728 } 729 if ($use_attribute) 730 { # good style 731 my $attribute_text = ''; 732 if ($style =~ /^(\w+)(\s+.*)/) 733 { 734 $style = $1; 735 $attribute_text = $2; 736 } 737# $text = "<${style}$attribute_text>$text</$style>" ; 738 $text = "<${style}$attribute_text>" . "$text" if (!$no_open); 739 $text .= "</$style>" if (!$no_close); 740 if ($do_quotes) 741 { 742 $text = $OPEN_QUOTE_SYMBOL . "$text" if (!$no_open); 743 $text .= $CLOSE_QUOTE_SYMBOL if (!$no_close); 744 } 745 } 746 if (ref($style) eq 'HASH') 747 { 748 if (defined($style->{'begin'}) and !$no_open) 749 { 750 $text = $style->{'begin'} . $text; 751 } 752 if (defined($style->{'end'}) and !$no_close) 753 { 754 $text = $text . $style->{'end'}; 755 } 756 } 757 if ($do_quotes and !$use_attribute) 758 { 759 $text = $OPEN_QUOTE_SYMBOL . "$text" if (!$no_open); 760 $text .= $CLOSE_QUOTE_SYMBOL if (!$no_close); 761 } 762 return $text; 763} 764 765sub T2H_GPL_format($$$) 766{ 767 my $tag = shift; 768 my $element = shift; 769 my $text = shift; 770 return '' if (!defined($element) or ($text !~ /\S/)); 771 return $text if ($element eq ''); 772 my $attribute_text = ''; 773 if ($element =~ /^(\w+)(\s+.*)/) 774 { 775 $element = $1; 776 $attribute_text = $2; 777 } 778 return "<${element}$attribute_text>\n" . $text. "</$element>\n"; 779} 780 781my $t2h_default_file_number; 782my $t2h_default_index_page_nr; 783#my %t2h_default_element_indices; 784my %t2h_default_index_letters_hash; 785my %t2h_default_index_letters_array; 786my %t2h_default_seen_files; 787my $t2h_default_element_split_printindices; 788my %t2h_default_split_files; 789 790# FIXME call it where indices are split in main program 791sub t2h_default_init_split_indices () 792{ 793 #print STDERR "Do splitting of index letters, once.\n"; 794 795 push @command_handler_process, \&t2h_default_index_rearrange_directions; 796 %t2h_default_index_letters_hash = (); 797 %t2h_default_index_letters_array = (); 798 %t2h_default_seen_files = (); 799 %t2h_default_split_files = (); 800 $t2h_default_element_split_printindices = undef; 801 $t2h_default_index_page_nr = 0; 802 $t2h_default_file_number = 0; 803 804 foreach my $index_name (keys %{$Texi2HTML::THISDOC{'indices'}}) 805 { 806 #print STDERR "Gathering and sorting $index_name letters\n"; 807 foreach my $key (keys %{$Texi2HTML::THISDOC{'indices'}->{$index_name}->[0]->{'entries'}}) 808 { 809 my $letter = uc(substr($key, 0, 1)); 810 $t2h_default_index_letters_hash{$index_name}->{$letter}->{$key} = $Texi2HTML::THISDOC{'indices'}->{$index_name}->[0]->{'entries'}->{$key}; 811 } 812 813 my $entries_count = 0; 814 my @letters = (); 815 # use cmp if only letters or only symbols, otherwise symbols before 816 # letters 817 foreach my $letter (sort { 818 ((($a =~ /^[[:alpha:]]/ and $b =~ /^[[:alpha:]]/) or 819 ($a !~ /^[[:alpha:]]/ and $b !~ /^[[:alpha:]]/)) && $a cmp $b) 820 || ($a =~ /^[[:alpha:]]/ && 1) || -1 } (keys(%{$t2h_default_index_letters_hash{$index_name}}))) 821 { 822 my $letter_entry = {'letter' => $letter }; 823 foreach my $key (sort {uc($a) cmp uc($b)} (keys(%{$t2h_default_index_letters_hash{$index_name}->{$letter}}))) 824 { 825 push @{$letter_entry->{'entries'}}, $t2h_default_index_letters_hash{$index_name}->{$letter}->{$key}; 826 } 827 push @letters, $letter_entry; 828 $entries_count += scalar(@{$letter_entry->{'entries'}}); 829 #if ($SPLIT and $SPLIT_INDEX and $entries_count >= $SPLIT_INDEX) 830 # FIXME this is not right, above is right 831 # Don't split if document is not split 832 if ($SPLIT and $SPLIT_INDEX and $entries_count > $SPLIT_INDEX) 833 { 834 push @{$t2h_default_index_letters_array{$index_name}}, [ @letters ]; 835 @letters = (); 836 $entries_count = 0; 837 } 838 } 839 push @{$t2h_default_index_letters_array{$index_name}}, [ @letters ] if (scalar(@letters)); 840 } 841} 842 843sub t2h_default_associate_index_element($$$$) 844{ 845 my $element = shift; 846 my $is_top = shift; 847 my $docu_name = shift; 848 my $use_node_file = shift; 849 850 my ($file, $default_element_file); 851 852 if ($SPLIT) 853 { 854 # respect the default splitting 855 $default_element_file = $element->{'file'}; 856 if ($t2h_default_seen_files{$default_element_file}) 857 { 858 $file = $t2h_default_seen_files{$default_element_file}; 859 } 860 else 861 { 862 if ($is_top eq 'top') 863 { 864 $file = $default_element_file; 865 } 866 else 867 { 868 $file = "${docu_name}_$t2h_default_file_number"; 869 $file .= '.' . $Texi2HTML::THISDOC{'extension'} if 870 (defined($Texi2HTML::THISDOC{'extension'})); 871 } 872 $t2h_default_file_number++; 873 $t2h_default_seen_files{$default_element_file} = $file; 874 } 875 } 876 my $modify_file = ($SPLIT and (!$use_node_file or $t2h_default_split_files{$default_element_file})); 877 $element->{'file'} = $file if ($modify_file); 878 879 my $current_element = $element; 880 #print STDERR "Doing printindices for $element $element->{'texi'}, file $file (@{$element->{'place'}})\n"; 881 882 my @places = @{$element->{'place'}}; 883 @{$element->{'place'}} = (); 884 885 foreach my $place (@places) 886 { 887 unless ($place->{'command'} and $place->{'command'} eq 'printindex') 888 { 889#print STDERR "HHHHHHHHH ($element->{'texi'}) place: $place->{'texi'}, current: $current_element->{'texi'}, $current_element->{'file'}\n"; 890 push @{$current_element->{'place'}}, $place; 891 $place->{'file'} = $current_element->{'file'}; 892 $place->{'element_ref'} = $current_element if ($place->{'element_ref'} and $current_element ne $element); 893 next; 894 } 895 my $printindex = $place; 896 my $index_name = $printindex->{'name'}; 897 #print STDERR "Associate letters in $element->{'texi'} for $index_name\n"; 898 my @letter_groups = (); 899 # empty index 900 next if (!exists($t2h_default_index_letters_array{$index_name})); 901 my @letters_split = @{$t2h_default_index_letters_array{$index_name}}; 902 903 # index is not split 904 if (scalar(@letters_split) eq 1) 905 { 906 push @{$letter_groups[0]->{'letters'}}, @{$letters_split[0]}; 907 } 908 # the element is at the level of splitting, then we split according to 909 # INDEX_SPLIT 910 elsif (!$element->{'top'} and $SPLIT and (($SPLIT eq 'node') or (defined($element->{'level'}) and $element->{'level'} <= $Texi2HTML::THISDOC{'split_level'}))) 911 { 912 $t2h_default_split_files{$default_element_file} = 1; 913 foreach my $letters_split (@letters_split) 914 { 915 push @letter_groups, {'letters' => [@$letters_split]}; 916 } 917 } 918 else 919 { # we 'unsplit' index split if not located where document is indeed split 920 #print STDERR "UNSPLIT $element->{'texi'}, $index_name\n"; 921 foreach my $letters_split (@letters_split) 922 { 923 push @{$letter_groups[0]->{'letters'}}, @$letters_split; 924 } 925 } 926 $letter_groups[0]->{'element'} = $current_element; 927 # may only happen if SPLIT 928 if (scalar(@letter_groups) > 1) 929 { # this weird construct is there because the element use as a key is 930 # converted to a string by perl, losing its meaning as a reference, 931 # the reference must be recorded explicitly 932 $t2h_default_element_split_printindices->{$element}->{'element'} = $element; 933 push @{$t2h_default_element_split_printindices->{$element}->{'printindices'}}, $printindex; 934 #print STDERR "Pushing $element, $element->{'texi'}, $printindex\n"; 935 foreach my $split_group (@letter_groups) 936 { 937 my $first_letter = $split_group->{'letters'}->[0]->{'letter'}; 938 my $last_letter = $split_group->{'letters'}->[-1]->{'letter'}; 939 if (!$split_group->{'element'}) 940 { 941 #construct new element name 942 my $letters_heading; 943 if ($last_letter ne $first_letter) 944 { 945 $letters_heading = &$normal_text("$first_letter -- $last_letter"); 946 } 947 else 948 { 949 $letters_heading = &$normal_text("$first_letter"); 950 } 951 my ($name, $simple); 952 my $texi = "ADDED ELEMENT $element->{'texi'}: $letters_heading"; 953 if (!defined($element->{'text'})) 954 { 955 my $element_heading_texi = &$heading_texi($element->{'tag'}, $element->{'texi'}, $element->{'number'}); 956 957 my $heading_texi = &$index_element_heading_texi( 958 $element_heading_texi, 959 $element->{'tag'}, 960 $element->{'texi'}, 961 $element->{'number'}, 962 $first_letter, $last_letter); 963 $name = main::substitute_line($heading_texi); 964 $simple = main::simple_format(undef,undef,$heading_texi); 965 } 966 else 967 { # should never happen 968 $name = "$element->{'text'}: $letters_heading"; 969 $simple = "$element->{'simple_format'}: $letters_heading"; 970 } 971 972 #file and id 973 my $relative_file = $Texi2HTML::THISDOC{'file_base_name'} . '_' . $t2h_default_file_number; 974 $t2h_default_file_number++; 975 $relative_file .= '.' . $Texi2HTML::THISDOC{'extension'} if 976 (defined($Texi2HTML::THISDOC{'extension'})); 977 my $id = "index_split-$t2h_default_index_page_nr"; 978 $t2h_default_index_page_nr++; 979 980 my $new_element = { 'file' => $relative_file, 'id' => $id, 'target' => $id, 'text' => $name, 'texi' => $texi, 'seen' => 1, 'simple_format' => $simple }; 981 982 $split_group->{'element'} = $new_element; 983 $current_element = $new_element; 984 #print STDERR "Added $new_element->{'file'} for $new_element->{'texi'} ($first_letter:$last_letter)\n"; 985 } 986 else 987 { # this is the first index split, it is still associated with the element 988 #print STDERR "No file added for ($first_letter:$last_letter)\n"; 989 } 990 } 991 $t2h_default_seen_files{$default_element_file} = $current_element->{'file'}; 992 } 993 else 994 { 995 push @{$current_element->{'place'}}, $place; 996 } 997 $printindex->{'split_groups'} = \@letter_groups; 998 #print STDERR "$index_name processed for $element, $element->{'texi'} (@{$printindex->{'split_groups'}})\n"; 999 } 1000 1001 return $file if ($modify_file); 1002 return undef; 1003} 1004 1005sub t2h_default_index_rearrange_directions() 1006{ 1007 return if (!defined($t2h_default_element_split_printindices)); 1008 foreach my $element_string (keys(%$t2h_default_element_split_printindices)) 1009 { 1010 my $element = $t2h_default_element_split_printindices->{$element_string}->{'element'}; 1011 my $current_element = $element; 1012 #print STDERR " E Processing $element_string,$current_element $current_element->{'texi'}\n"; 1013 foreach my $printindex (@{$t2h_default_element_split_printindices->{$element_string}->{'printindices'}}) 1014 { 1015 #print STDERR " I Processing $printindex $printindex->{'name'} (@{$printindex->{'split_groups'}})\n"; 1016 foreach my $split_group (@{$printindex->{'split_groups'}}) 1017 { 1018 my $first_letter = $split_group->{'letters'}->[0]->{'letter'}; 1019 my $last_letter = $split_group->{'letters'}->[-1]->{'letter'}; 1020 1021 my $new_element = $split_group->{'element'}; 1022 next if ($current_element eq $new_element); 1023 #print STDERR " G Processing ($first_letter:$last_letter) in $element->{'texi'}, index $printindex->{'name'}: $new_element->{'texi'}\n"; 1024 $new_element->{'This'} = $new_element; 1025 if ($current_element->{'Forward'}) 1026 { 1027 $current_element->{'Forward'}->{'Back'} = $new_element; 1028 $new_element->{'Forward'} = $current_element->{'Forward'}; 1029 } 1030 $current_element->{'Forward'} = $new_element; 1031 $new_element->{'Back'} = $current_element; 1032 if ($current_element->{'Following'}) 1033 { 1034#print STDERR "F: C($current_element): $current_element->{'texi'}, N($new_element): $new_element->{'texi'} -- C->F: $current_element->{'Following'}->{'texi'}\n"; 1035 $new_element->{'Following'} = $current_element->{'Following'}; 1036 $current_element->{'Following'} = $new_element; 1037 } 1038 foreach my $key ('FastForward', 'FastBack', 'Up', 'tag_level', 'tag', 1039 'level', 'node') 1040 { 1041 $new_element->{$key} = $element->{$key} if (defined($element->{$key})); 1042 } 1043 $current_element = $new_element; 1044 } 1045 } 1046 } 1047} 1048 1049# not needed to initialize it for a document, since it is reset 1050# in index_summary 1051my $t2h_symbol_indices = 0; 1052 1053# format a letter appearing in a summary for an index. The letter links to 1054# the place where the index elements beginning with this letter are (called 1055# a letter entry). 1056# 1057# arguments: 1058# letter 1059# file where the target letter entry is 1060# identifier for the target letter entry 1061 1062# This should better be in texi2html.init, but $t2h_symbol_indices 1063# has to be in the same file scope than printindeex. 1064sub t2h_default_summary_letter($$$$$$$) 1065{ 1066 my $letter = shift; 1067 my $file = shift; 1068 my $default_identifier = shift; 1069 my $index_element_id = shift; 1070 my $number = shift; 1071 my $index_element = shift; 1072 my $index_name = shift; 1073 1074 my $is_symbol = $letter !~ /^[A-Za-z]/; 1075 my $identifier = $default_identifier; 1076 1077 if ($NEW_CROSSREF_STYLE) 1078 { 1079 if ($is_symbol) 1080 { 1081 $t2h_symbol_indices++; 1082 $identifier = $index_element_id . "_${index_name}_symbol-$t2h_symbol_indices"; 1083 } 1084 else 1085 { 1086 $identifier = $index_element_id . "_${index_name}_letter-${letter}"; 1087 } 1088 } 1089 my $result = &$anchor('', $file . '#' . $identifier, '<b>' . &$protect_text($letter) . '</b>', 'class="summary-letter"'); 1090 return $result unless ($NEW_CROSSREF_STYLE); 1091 return ($result, $identifier, $is_symbol); 1092} 1093 1094# this replaces do_index_page 1095# args should be: 1096# index_name 1097sub t2h_GPL_default_printindex($) 1098{ 1099 my $index_name = shift; 1100 1101 my %letter_entries; 1102 my $identifier_index_nr = 0; 1103 # could be cross verified with argument 1104 my $printindex = shift @{$Texi2HTML::THISDOC{'printindices'}}; 1105 if ($printindex->{'name'} ne $index_name) 1106 { 1107 print STDERR "BUG: THISDOC{'printindices'} $printindex->{'name'} ne $index_name\n"; 1108 } 1109#print STDERR "Doing printindex $index_name\n"; 1110 return '' if (! defined($printindex->{'split_groups'})); 1111 my @split_letters = @{$printindex->{'split_groups'}}; 1112 1113 return '' if (!scalar(@split_letters)); 1114 1115 foreach my $split_group (@split_letters) 1116 { 1117 #do summmary 1118 my @non_alpha = (); 1119 my @alpha = (); 1120 my $file = $split_group->{'element'}->{'file'}; 1121 # letter_id could be done once for all instead of for each split_group 1122 # and outside of t2h_default_summary_letter (or t2h_default_summary_letter 1123 # could be simplified and inlined 1124 my %letter_id; 1125 foreach my $summary_split_group (@split_letters) 1126 { 1127 foreach my $letter_entry (@{$summary_split_group->{'letters'}}) 1128 { 1129 my $letter = $letter_entry->{'letter'}; 1130 #my $letter = $letter_entry; 1131 my $dest_file = ''; 1132 $dest_file = $summary_split_group->{'element'}->{'file'} 1133 if ($summary_split_group ne $split_group); 1134 my $index_element_id = $summary_split_group->{'element'}->{'id'}; 1135 my $default_identifier = $index_element_id . "_$identifier_index_nr"; 1136 $identifier_index_nr++; 1137 my ($result, $identifier, $is_symbol) = 1138 &$summary_letter($letter, $dest_file, $default_identifier, $index_element_id, '', '', $index_name); 1139 $identifier = $default_identifier if (!defined($identifier)); 1140 $letter_id{$letter} = $identifier; 1141 $is_symbol = $letter !~ /^[A-Za-z]/ if (!defined($is_symbol)); 1142 1143 if ($is_symbol) 1144 { 1145 push @non_alpha, $result; 1146 } 1147 else 1148 { 1149 push @alpha, $result; 1150 } 1151 } 1152 } 1153 my $summary = &$index_summary(\@alpha, \@non_alpha); 1154 1155 # reset symbols numbering 1156 $t2h_symbol_indices = 0; 1157 1158 my $letters_text = ''; 1159 foreach my $letter_entry (@{$split_group->{'letters'}}) 1160 { 1161 my $letter = $letter_entry->{'letter'}; 1162 my $entries_text = ''; 1163 #foreach my $entry (@{$letter_entries{$letter}->{'entries'}}) 1164 foreach my $index_entry_ref (@{$letter_entry->{'entries'}}) 1165 { 1166 #my $entry_infos = main::get_index_entry_infos($index_entry, $split_group->{'element'}); 1167 #my ($text_href, $entry, $element_href, $element_text, $entry_file, $element_file, $entry_target, $entry_element_target) = @$entry_infos; 1168 my ($text_href, $entry_file, $element_file, $entry_target, 1169 $entry_element_target, $formatted_entry, $element_href, $entry_element_text) 1170 = main::get_index_entry_infos($index_entry_ref, $split_group->{'element'}); 1171 $entries_text .= &$index_entry ($text_href, $formatted_entry, $element_href, $entry_element_text, $entry_file, $element_file, $entry_target, $entry_element_target); 1172 } 1173 $letters_text .= &$index_letter ($letter, $letter_id{$letter}, $entries_text) 1174 } 1175 my $index_text = &$print_index($letters_text, $index_name); 1176 $split_group->{'text'} = $summary . $index_text . $summary; 1177# print STDERR " ---> $index_name @{$split_group->{'letters'}} 1178# * elt: $split_group->{'element'}->{'id'}, $split_group->{'element'}->{'file'}, $split_group->{'element'}->{'name'} 1179# * directions: B: $split_group->{'element'}->{'Back'}->{'name'}, F: $split_group->{'element'}->{'Forward'}->{'name'}, FB: $split_group->{'element'}->{'FastBack'}->{'name'}, FF: $split_group->{'element'}->{'FastForward'}->{'name'} 1180# * text 1181# 1182#$split_group->{'text'} 1183# 1184#"; 1185 } 1186 my $current_page = shift @split_letters; 1187 if (!scalar(@split_letters)) 1188 { 1189 return $current_page->{'text'}; 1190 } 1191 1192 while (1) 1193 { 1194 # print the index letters 1195 push @{$Texi2HTML::THIS_SECTION}, $current_page->{'text'}; 1196 1197 $current_page = shift @split_letters; 1198 last if (!defined($current_page)); 1199 1200 # end the previous element 1201 main::finish_element ($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT, $Texi2HTML::THIS_ELEMENT->{'Forward'}, 0); 1202 1203 # do the new element beginning 1204 $Texi2HTML::THIS_ELEMENT = $current_page->{'element'}; 1205 main::do_element_directions($Texi2HTML::THIS_ELEMENT); 1206 main::open_out_file($current_page->{'element'}->{'file'}); 1207 &$print_page_head($Texi2HTML::THISDOC{'FH'}); 1208 &$print_chapter_header($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT) if $Texi2HTML::Config::SPLIT eq 'chapter'; 1209 &$print_section_header($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT) if $Texi2HTML::Config::SPLIT eq 'section'; 1210 1211 @{$Texi2HTML::THIS_SECTION} = &$element_label($Texi2HTML::THIS_ELEMENT->{'id'}, $Texi2HTML::THIS_ELEMENT, undef, undef); 1212 push @{$Texi2HTML::THIS_SECTION}, &$print_element_header(1, 0); 1213 push @{$Texi2HTML::THIS_SECTION}, &$heading($Texi2HTML::THIS_ELEMENT); 1214 } 1215 return ''; 1216} 1217# leave this within comments, and keep the require statement 1218# This way, you can directly run texi2html.pl, if 1219# $T2H_HOME/texi2html.init exists. 1220 1221# @INIT@ 1222# -*-perl-*- 1223###################################################################### 1224# File: texi2html.init 1225# 1226# Default values for command-line arguments and for various customizable 1227# procedures are set in this file. 1228# 1229# A copy of this file is pasted into the beginning of texi2html by 1230# running './configure'. 1231# 1232# Copy this file, rename it and make changes to it, if you like. 1233# Afterwards, load the file with command-line 1234# option -init-file <your_init_file> 1235# 1236# $Id: texi2html.init,v 1.173 2009/01/01 22:35:10 pertusus Exp $ 1237 1238###################################################################### 1239# The following variables can also be set by command-line options 1240# 1241# 1242# The default values are set in this file, texi2html.init and the content 1243# of this file is included at the beginning of the texi2html script file. 1244# Those values may be overrided by values set in $sysconfdir/texi2htmlrc 1245# and then by values set in $HOME/texi2htmlrc. 1246# 1247# command line switches may override these values, and values set in files 1248# specified by -init-file are also taken into account. 1249# values set in these files overwrite values set by the command-line 1250# options appearing before -init-file and might still be overwritten by 1251# command-line arguments following the -init-file option. 1252 1253# -debug 1254# The integer value specifies what kind of debugging output is generated. 1255$DEBUG = 0; 1256 1257# -doctype 1258# The value is the 'SystemLiteral' which identifies the canonical DTD 1259# for the document. 1260# Definition: The SystemLiteral is called the entity's system 1261# identifier. It is a URI, which may be used to retrieve the entity. 1262# See http://www.xml.com/axml/target.html#NT-ExternalID 1263$DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">'; 1264 1265# -frameset-doctype 1266# When frames are used, this SystemLiteral identifies the DTD used for 1267# the file containing the frame description. 1268$FRAMESET_DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html401/frameset.dtd">'; 1269 1270# -test 1271# If this value is true, some variables which should be dynamically generated 1272# (the date, the user running texi2html, the version of texi2html) are set to 1273# fix and given values. This is usefull in case the resulting manual is 1274# compared with a reference. For example this is used in the tests of test.sh. 1275$TEST = 0; 1276 1277# -dump-texi 1278# This value is usefull for debugging purposes. The result of the first pass is 1279# put in <document name>.passtexi, the result of the second pass is put in 1280# <document name>.passfirst. 1281$DUMP_TEXI = 0; 1282 1283# -expand 1284# the @EXPAND array contains the expanded section names. 1285@EXPAND = ('html'); 1286 1287# -invisible 1288# This seems obsolete and is not used anywhere. 1289# This was a workaround for a known bug of many WWW browsers, including 1290# netscape. This was used to create invisible destination in anchors. 1291$INVISIBLE_MARK = ''; 1292# $INVISIBLE_MARK = ' '; 1293 1294# -iso 1295# if this value is true, ISO8859 characters are used for special symbols 1296# (like copyright, etc). 1297$USE_ISO = 1; 1298 1299# -I 1300# add a directory to the list of directories where @include files are 1301# searched for (besides the directory of the file). additional '-I' 1302# args are appended to this list. 1303# (APA: Don't implicitely search ., to conform with the docs!) 1304# my @INCLUDE_DIRS = ("."); 1305@INCLUDE_DIRS = (); 1306 1307# -P 1308# prepend a directory to the list of directories where @include files are 1309# searched for before the directory of the file. additional '-P' 1310# args are prepended to this list. 1311@PREPEND_DIRS = (); 1312 1313# --conf-dir 1314# append to the files searched for init files. 1315@CONF_DIRS = (); 1316 1317# -top-file 1318# This file name is used for the top-level file. 1319# The extension is set appropriately, if necessary. 1320# If empty, <basename of document>.html is used. 1321# Typically, you would set this to "index.html". 1322$TOP_FILE = ''; 1323 1324# -toc-file 1325# This file name is used for the table of contents. The 1326# extension is set appropriately, if necessary. 1327# If empty, <basename of document>_toc.html is used. 1328$TOC_FILE = ''; 1329 1330# -frames 1331# if the value is true, HTML 4.0 "frames" are used. 1332# A file describing the frame layout is generated, together with a file 1333# with the short table of contents. 1334$FRAMES = 0; 1335 1336# -menu | -nomenu 1337# if the value is true the Texinfo menus are shown. 1338$SHOW_MENU = 1; 1339 1340# -number | -nonumber 1341# if this is set the sections are numbered, and section names and numbers 1342# are used in references and menus (instead of node names). 1343$NUMBER_SECTIONS = 1; 1344 1345# -use-nodes 1346# if this is set the nodes are used as sectionning elements. 1347# Otherwise the nodes are incorporated in sections. 1348#$USE_NODES = 0; 1349$USE_NODES = undef; 1350 1351$USE_SECTIONS = 1; 1352 1353# -node-files 1354# if this is set one file per node is generated, which can be a target for 1355# cross manual references. 1356$NODE_FILES = 0; 1357 1358# -split section|chapter|node|none 1359# if $SPLIT is set to 'section' (resp. 'chapter') one html file per section 1360# (resp. chapter) is generated. If $SPLIT is set to 'node' one html file per 1361# node or sectionning element is generated. In all these cases separate pages 1362# for Top, Table of content (Toc), Overview and About are generated. 1363# Otherwise a monolithic html file that contains the whole document is 1364# created. 1365#$SPLIT = 'section'; 1366$SPLIT = ''; 1367 1368# -sec-nav|-nosec-nav 1369# if this is set then navigation panels are printed at the beginning of each 1370# section. 1371# If the document is split at nodes then navigation panels are 1372# printed at the end if there were more than $WORDS_IN_PAGE words on page. 1373# 1374# Navigation panels are always printed at the beginning of output files. 1375# 1376# This is most useful if you do not want to have section navigation 1377# with -split chapter. There will be chapter navigation panel at the 1378# beginning and at the end of chapters anyway. 1379$SECTION_NAVIGATION = 1; 1380 1381# -separated-footnotes 1382# if this is set footnotes are on a separated page. Otherwise they are at 1383# the end of each file (if the document is split). 1384$SEPARATED_FOOTNOTES = 1; 1385 1386# -toc-links 1387# if this is set, links from headings to toc entries are created. 1388$TOC_LINKS = 0; 1389 1390# -subdir 1391# If this is set, then put result files into the specified directory. 1392# If not set, then result files are put into the current directory. 1393#$SUBDIR = 'html'; 1394$SUBDIR = ''; 1395 1396# -short-extn 1397# If this is set, then all HTML files will have extension ".htm" instead of 1398# ".html". This is helpful when shipping the document to DOS-based systems. 1399$SHORTEXTN = 0; 1400 1401# -prefix 1402# This set the output file prefix, prepended to all .html, .gif and .pl files. 1403# By default, this is the basename of the document. 1404$PREFIX = ''; 1405 1406# -o filename 1407# If this is set a monolithic document is outputted into $filename. 1408$OUT = ''; 1409 1410# -no-validate 1411# suppress node cross-reference validation 1412$NOVALIDATE = 0; 1413 1414# -short-ref 1415# if this is set cross-references are given without section numbers. 1416$SHORT_REF = ''; 1417 1418# -idx-sum 1419# if value is set, then for each @printindex <index name> 1420# <document name>_<index name>.idx is created which contains lines of the form 1421# key ref sorted alphabetically (case matters). 1422$IDX_SUMMARY = 0; 1423 1424# -def-table 1425# If this is set a table construction for @def.... instead of definition 1426# lists. 1427# (New Option: 27.07.2000 Karl Heinz Marbaise) 1428$DEF_TABLE = 0; 1429 1430# -verbose 1431# if this is set chatter about what we are doing. 1432$VERBOSE = ''; 1433 1434# -lang 1435# use &$I('my string') if you want to have translations of 'my string' 1436# and provide the translations in $LANGUAGES->{$LANG} with 'my string' 1437# as key. 1438# To add a new language use ISO 639 language codes (see e.g. perl module 1439# Locale-Codes-1.02 for definitions). Supply translations in the 1440# $LANGUAGES hash and put it in a file with $LANG as name in an i18n 1441# directory. 1442# This is used for the initial language, it is overriden during 1443# document processing if there is a @documentlanguage. 1444# It is ignored if the language is passed on the command line. 1445$LANG = 'en'; 1446 1447# -ignore-preamble-text 1448# If this is set the text before @node and sectionning commands is ignored. 1449$IGNORE_PREAMBLE_TEXT = 0; 1450 1451# -html-xref-prefix 1452# base directory for external manuals. 1453#$EXTERNAL_DIR = '../'; 1454$EXTERNAL_DIR = undef; 1455 1456# -l2h 1457# if this is set, latex2html is used for generation of math content. 1458$L2H = ''; 1459 1460# -transliterate-file-names 1461# transliterate node names for external refs (and internal if NODE_FILES) 1462$TRANSLITERATE_NODE = 1; 1463 1464# --error-limit 1465# quit after NUM errors (default 1000). 1466$ERROR_LIMIT = 1000; 1467 1468# -monolithic 1469# output only one file including ToC. It only makes sense when not split 1470$MONOLITHIC = 1; 1471 1472# -css-include 1473# All the specified css files are used. More precisely the @import sections 1474# are added to the beginning of the CSS_LINES the remaining is added at 1475# the end of the CSS_LINES (after the css rules generated by texi2html). 1476# cf texinfo manual for more info. 1477# - means STDIN 1478@CSS_FILES = (); 1479 1480# -css-ref 1481# the specified url are used as stylesheet links 1482@CSS_REFS = (); 1483 1484###################### 1485# The following options are only relevant if $L2H is set 1486# 1487# -l2h-l2h 1488# name/location of latex2html program 1489$L2H_L2H = "latex2html"; 1490 1491# -l2h-skip 1492# If this is set the actual call to latex2html is skipped. The previously 1493# generated content is reused, instead. 1494$L2H_SKIP = ''; 1495 1496# -l2h-tmp 1497# If this is set l2h uses the specified directory for temporary files. The path 1498# leading to this directory may not contain a dot (i.e., a "."); 1499# otherwise, l2h will fail. 1500$L2H_TMP = ''; 1501 1502# -l2h-file 1503# If set, l2h uses the file as latex2html init file 1504$L2H_FILE = 'l2h.init'; 1505 1506# -l2h-clean 1507# if this is set the intermediate files generated by texi2html in relation with 1508# latex2html are cleaned (they all have the prefix <document name>_l2h_). 1509$L2H_CLEAN = 1; 1510 1511############################################################################## 1512# 1513# The following can only be set in the init file 1514# 1515############################################################################## 1516 1517# If true do table of contents even if there is no @content 1518$DO_CONTENTS = undef; 1519 1520# If true do short table of contents even if there is no @shortcontent 1521$DO_SCONTENTS = undef; 1522 1523# if set, output the contents where the command is located 1524$INLINE_CONTENTS = 0; 1525 1526# if this variable is true, numeric entities are used when there is no 1527# corresponding textual entity. 1528$USE_NUMERIC_ENTITY = 1; 1529 1530# if set, the image files are completed to be relative from the 1531# document directory, to the source manual directory and then to 1532# the image 1533$COMPLETE_IMAGE_PATHS = 0; 1534 1535# if this variable is true, @setfilename is used if found to determine the 1536# out file name 1537$USE_SETFILENAME = 0; 1538 1539# if true, begin outputting at @setfilename, if this command is present. 1540$IGNORE_BEFORE_SETFILENAME = 1; 1541 1542# if true the link in Overview link to the corresponding Toc entry. 1543$OVERVIEW_LINK_TO_TOC = 0; 1544 1545# if set always separate description and menu link, even in 1546# preformatted environment 1547$SEPARATE_DESCRIPTION = 0; 1548 1549# if set, then use node names in menu entries, instead of section names 1550$NODE_NAME_IN_MENU = 0; 1551 1552# if set, use node anchors for sections targets 1553$USE_NODE_TARGET = 1; 1554 1555# new style for crossrefs 1556$NEW_CROSSREF_STYLE = 1; 1557 1558# top heading is always at the beginning of the element. 1559$TOP_HEADING_AT_BEGINNING = 1; 1560 1561# if set and menu entry equals menu description, then do not print 1562# menu description. 1563# Likewise, if node name equals entry name, do not print entry name. 1564$AVOID_MENU_REDUNDANCY = 1; 1565 1566# if set, center @image by default 1567# otherwise, do not center by default 1568# Deprecated and not used anymore 1569$CENTER_IMAGE = 1; 1570 1571# used as identation for block enclosing command @example, etc 1572# If not empty, must be enclosed in <td></td> 1573$EXAMPLE_INDENT_CELL = '<td> </td>'; 1574 1575# same as above, only for @small 1576$SMALL_EXAMPLE_INDENT_CELL = '<td> </td>'; 1577 1578# font size for @small 1579$SMALL_FONT_SIZE = '-1'; 1580 1581# horizontal rules 1582$SMALL_RULE = '<hr size="1">'; 1583$DEFAULT_RULE = '<hr>'; 1584$MIDDLE_RULE = '<hr size="2">'; 1585$BIG_RULE = '<hr size="6">'; 1586 1587# if non-empty, and no @..heading appeared in Top node, then 1588# use this as header for top node/section, otherwise use value of 1589# @settitle or @shorttitle (in that order) 1590$TOP_HEADING = ''; 1591 1592# if set, use this chapter for 'Index' button, else 1593# use first chapter with @printindex 1594$INDEX_CHAPTER = ''; 1595 1596# if set and $SPLIT is set, then split index pages at the next letter 1597# after they have more than that many entries 1598$SPLIT_INDEX = 100; 1599 1600# symbol put at the beginning of nodes entry in menu (and optionnaly of 1601# unnumbered in menus, see next variable) 1602$MENU_SYMBOL = '•'; 1603#$MENU_SYMBOL = '*'; 1604 1605$SIMPLE_MENU = 0; 1606 1607$OPEN_QUOTE_SYMBOL = "\`"; 1608$CLOSE_QUOTE_SYMBOL = "'"; 1609 1610# if true put a $MENU_SYMBOL before unnumbered in menus 1611$UNNUMBERED_SYMBOL_IN_MENU = 0; 1612 1613# extension for nodes files when NODE_FILES is true 1614$NODE_FILE_EXTENSION = 'html'; 1615 1616# extension 1617$EXTENSION = 'html'; 1618 1619# file name used for Top node when NODE_FILES is true 1620$TOP_NODE_FILE = 'index'; 1621 1622# node name used for Top node when automatic node directions are used 1623$TOP_NODE_UP = '(dir)'; 1624 1625# this controls the pre style for menus 1626$MENU_PRE_STYLE = 'font-family: serif'; 1627 1628# on bug-texinfo is has been said the the style is not code_style 1629# for menus (except for the node name). 1630# this controls the menu preformatted format 1631# FIXME this is not dynamic, so change in MENU_PRE_STYLE is not taken 1632# into account. 1633$MENU_PRE_COMPLEX_FORMAT = { 1634 'pre_style' => $MENU_PRE_STYLE, 1635 'class' => 'menu-preformatted', 1636# 'style' => 'code' 1637 }; 1638 1639# This controls the ul style for toc 1640$NO_BULLET_LIST_STYLE = 'list-style: none'; 1641$NO_BULLET_LIST_ATTRIBUTE = ' class="toc"'; 1642 1643# These lines are inserted before and after the shortcontents 1644$BEFORE_OVERVIEW = "<div class=\"shortcontents\">\n"; 1645$AFTER_OVERVIEW = "</div>\n"; 1646 1647# These lines are inserted before and after the contents 1648$BEFORE_TOC_LINES = "<div class=\"contents\">\n"; 1649$AFTER_TOC_LINES = "</div>\n"; 1650 1651# if set (e.g., to index.html) replace hrefs to this file 1652# (i.e., to index.html) by ./ 1653# Obsolete. Worked around a bug that is fixed now. 1654$HREF_DIR_INSTEAD_FILE = ''; 1655 1656# text inserted after <body ...> 1657$AFTER_BODY_OPEN = ''; 1658 1659# text inserted before </body>, this will be automatically inside <p></p> 1660$PRE_BODY_CLOSE = ''; 1661 1662# this is added inside <head></head> after <title> and some <meta name> 1663# stuff, it can be used for eg. <style>, <script>, <meta> etc. tags. 1664$EXTRA_HEAD = ''; 1665 1666# Specifies the minimum page length required before a navigation panel 1667# is placed at the bottom of a page 1668# FIXME this is not true: 1669# THIS_WORDS_IN_PAGE holds number of words of current page 1670$WORDS_IN_PAGE = 300; 1671 1672# if this is set a vertical navigation panel is used. 1673$VERTICAL_HEAD_NAVIGATION = 0; 1674 1675# html version for latex2html 1676$L2H_HTML_VERSION = "4.0"; 1677 1678# use the information given by menus to complete the node directions 1679$USE_MENU_DIRECTIONS = 1; 1680 1681# try up sections to complete the node directions 1682$USE_UP_FOR_ADJACENT_NODES = 1; 1683 1684# use accesskey in hrefs 1685$USE_ACCESSKEY = 0; 1686 1687# use rel= and rev= in hrefs. Currently only rel is used 1688$USE_REL_REV = 0; 1689 1690# generate <link> elements in head 1691$USE_LINKS = 0; 1692 1693# specify in this array which "buttons" should appear in which order 1694# in the navigation panel for sections; use ' ' for empty buttons (space) 1695@SECTION_BUTTONS = 1696 ( 1697 'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward', 1698 ' ', ' ', ' ', ' ', 1699 'Top', 'Contents', 'Index', 'About', 1700 ); 1701 1702# buttons for misc stuff 1703@MISC_BUTTONS = ('Top', 'Contents', 'Index', 'About'); 1704 1705# buttons for chapter file footers 1706# (and headers but only if SECTION_NAVIGATION is false) 1707@CHAPTER_BUTTONS = 1708 ( 1709 'FastBack', 'FastForward', ' ', 1710 ' ', ' ', ' ', ' ', 1711 'Top', 'Contents', 'Index', 'About', 1712 ); 1713 1714# buttons for section file footers 1715@SECTION_FOOTER_BUTTONS = 1716 ( 1717 'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward' 1718 ); 1719 1720@NODE_FOOTER_BUTTONS = 1721 ( 1722 'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward', 1723 ' ', ' ', ' ', ' ', 1724 'Top', 'Contents', 'Index', 'About', 1725# 'Back', 'Forward', ' ', 'FastBack', 'Up', 'FastForward' 1726 ); 1727 1728@LINKS_BUTTONS = 1729 ( 1730 'Top', 'Index', 'Contents', 'About', 'Up', 'NextFile', 'PrevFile' 1731 ); 1732 1733$ICONS = 0; 1734 1735# insert here name of icon images for buttons 1736# Icons are used, if $ICONS and resp. value are set 1737%ACTIVE_ICONS = 1738 ( 1739 'Top', '', 1740 'Contents', '', 1741 'Overview', '', 1742 'Index', '', 1743 'This', '', 1744 'Back', '', 1745 'FastBack', '', 1746 'Prev', '', 1747 'Up', '', 1748 'Next', '', 1749 'NodeUp', '', 1750 'NodeNext', '', 1751 'NodePrev', '', 1752 'Following', '', 1753 'Forward', '', 1754 'FastForward', '', 1755 'About' , '', 1756 'First', '', 1757 'Last', '', 1758 'NextFile', '', 1759 'PrevFile', '', 1760 ' ', '', 1761 ); 1762 1763# insert here name of icon images for these, if button is inactive 1764%PASSIVE_ICONS = 1765 ( 1766 'Top', '', 1767 'Contents', '', 1768 'Overview', '', 1769 'Index', '', 1770 'This', '', 1771 'Back', '', 1772 'FastBack', '', 1773 'Prev', '', 1774 'Up', '', 1775 'Next', '', 1776 'NodeUp', '', 1777 'NodeNext', '', 1778 'NodePrev', '', 1779 'Following', '', 1780 'Forward', '', 1781 'FastForward', '', 1782 'About', '', 1783 'First', '', 1784 'Last', '', 1785 'NextFile', '', 1786 'PrevFile', '', 1787 ); 1788 1789@IMAGE_EXTENSIONS = ('png','jpg','jpeg','gif'); 1790#, 'txt'); 1791 1792 1793%misc_pages_targets = ( 1794 'Overview' => 'SEC_Overview', 1795 'Contents' => 'SEC_Contents', 1796 'Footnotes' => 'SEC_Foot', 1797 'About' => 'SEC_About' 1798); 1799 1800$init_out = \&t2h_default_init_out; 1801$finish_out = \&t2h_default_finish_out; 1802 1803$translate_names = \&t2h_default_translate_names; 1804 1805sub t2h_default_translate_names() 1806{ 1807# Names of text as alternative for icons 1808# FIXME maybe get those in simple_format? 1809 %NAVIGATION_TEXT = 1810 ( 1811 'Top', &$I('Top'), 1812 'Contents', &$I('Contents'), 1813 'Overview', &$I('Overview'), 1814 'Index', &$I('Index'), 1815 ' ', ' ', 1816 'This', &$I('current'), 1817 'Back', ' < ', 1818 'FastBack', ' << ', 1819 'Prev', &$I('Prev'), 1820 'Up', &$I(' Up '), 1821 'Next', &$I('Next'), 1822 'NodeUp', &$I('Node up'), 1823 'NodeNext', &$I('Next node'), 1824 'NodePrev', &$I('Previous node'), 1825 'Following', &$I('Following node'), 1826 'Forward', ' > ', 1827 'FastForward', ' >> ', 1828 'About', ' ? ', 1829 'First', ' |< ', 1830 'Last', ' >| ', 1831 'NextFile', &$I('Next file'), 1832 'PrevFile', &$I('Previous file'), 1833 ); 1834 1835 %BUTTONS_GOTO = 1836 ( 1837 'Top', &$I('Cover (top) of document'), 1838 'Contents', &$I('Table of contents'), 1839 'Overview', &$I('Short table of contents'), 1840 'Index', &$I('Index'), 1841 'This', &$I('Current section'), 1842 'Back', &$I('Previous section in reading order'), 1843 'FastBack', &$I('Beginning of this chapter or previous chapter'), 1844 'Prev', &$I('Previous section on same level'), 1845 'Up', &$I('Up section'), 1846 'Next', &$I('Next section on same level'), 1847 'NodeUp', &$I('Up node'), 1848 'NodeNext', &$I('Next node'), 1849 'NodePrev', &$I('Previous node'), 1850 'Following', &$I('Node following in node reading order'), 1851 'Forward', &$I('Next section in reading order'), 1852 'FastForward', &$I('Next chapter'), 1853 'About' , &$I('About (help)'), 1854 'First', &$I('First section in reading order'), 1855 'Last', &$I('Last section in reading order'), 1856 'NextFile', &$I('Forward section in next file'), 1857 'PrevFile', &$I('Back section in previous file'), 1858 ); 1859 1860 %BUTTONS_NAME = 1861 ( 1862 'Top', &$I('Top'), 1863 'Contents', &$I('Contents'), 1864 'Overview', &$I('Overview'), 1865 'Index', &$I('Index'), 1866 ' ', ' ', 1867 'This', &$I('This'), 1868 'Back', &$I('Back'), 1869 'FastBack', &$I('FastBack'), 1870 'Prev', &$I('Prev'), 1871 'Up', &$I('Up'), 1872 'Next', &$I('Next'), 1873 'NodeUp', &$I('NodeUp'), 1874 'NodeNext', &$I('NodeNext'), 1875 'NodePrev', &$I('NodePrev'), 1876 'Following', &$I('Following'), 1877 'Forward', &$I('Forward'), 1878 'FastForward', &$I('FastForward'), 1879 'About', &$I('About'), 1880 'First', &$I('First'), 1881 'Last', &$I('Last'), 1882 'NextFile', &$I('NextFile'), 1883 'PrevFile', &$I('PrevFile'), 1884 ); 1885 1886 %BUTTONS_ACCESSKEY = 1887 ( 1888 'Top', '', 1889 'Contents', '', 1890 'Overview', '', 1891 'Index', '', 1892 'This', '', 1893 'Back', 'p', 1894 'FastBack', '', 1895 'Prev', 'p', 1896 'Up', 'u', 1897 'Next', 'n', 1898 'NodeUp', 'u', 1899 'NodeNext', 'n', 1900 'NodePrev', 'p', 1901 'Following', '', 1902 'Forward', 'n', 1903 'FastForward', '', 1904 'About' , '', 1905 'First', '', 1906 'Last', '', 1907 'NextFile', '', 1908 'PrevFile', '', 1909 ); 1910 1911# see http://www.w3.org/TR/REC-html40/types.html#type-links 1912 %BUTTONS_REL = 1913 ( 1914 'Top', 'start', 1915 'Contents', 'contents', 1916 'Overview', '', 1917 'Index', 'index', 1918 'This', '', 1919 'Back', 'previous', 1920 'FastBack', '', 1921 'Prev', 'previous', 1922 'Up', 'up', 1923 'Next', 'next', 1924 'NodeUp', 'up', 1925 'NodeNext', 'next', 1926 'NodePrev', 'previous', 1927 'Following', '', 1928 'Forward', 'next', 1929 'FastForward', '', 1930 'About' , 'help', 1931 'First', '', 1932 'Last', '', 1933 'NextFile', 'next', 1934 'PrevFile', 'previous', 1935 ); 1936 1937} 1938 1939# is used in main program for dumping texi too. 1940sub t2h_default_set_out_encoding() 1941{ 1942 # these variables are used for the corresponding 1943 # $Texi2HTML::THISDOC{'*_ENCODING'} to keep code shorter 1944 my ($out_encoding, $encoding_name, $document_encoding); 1945 1946 if (defined($DOCUMENT_ENCODING)) 1947 { 1948 $document_encoding = $DOCUMENT_ENCODING; 1949 } 1950 elsif (defined($Texi2HTML::THISDOC{'documentencoding'})) 1951 { 1952 $document_encoding = $Texi2HTML::THISDOC{'documentencoding'}; 1953 } 1954 1955 if (defined($OUT_ENCODING)) 1956 { 1957 $out_encoding = $OUT_ENCODING; 1958 } 1959 1960 if (defined($ENCODING_NAME)) 1961 { 1962 $encoding_name = $ENCODING_NAME; 1963 } 1964 1965 if (!defined($out_encoding) and (defined($encoding_name))) 1966 { 1967 $out_encoding = main::encoding_alias ($encoding_name); 1968 $out_encoding = $encoding_name if (!defined($out_encoding)); 1969 } 1970 if (!defined($out_encoding) and (defined($Texi2HTML::THISDOC{'IN_ENCODING'}))) 1971 { 1972 $out_encoding = $Texi2HTML::THISDOC{'IN_ENCODING'}; 1973 } 1974 if (!defined($out_encoding) and (defined($document_encoding))) 1975 { 1976 $out_encoding = main::encoding_alias ($document_encoding); 1977 $out_encoding = $document_encoding if (!defined($out_encoding)); 1978 } 1979 1980 if (!defined($encoding_name)) 1981 { 1982 if (defined($out_encoding) and defined($perl_charset_to_html{$out_encoding})) 1983 { 1984 $encoding_name = $perl_charset_to_html{$out_encoding}; 1985 } 1986 elsif (defined($Texi2HTML::THISDOC{'IN_ENCODING'}) and defined($perl_charset_to_html{$Texi2HTML::THISDOC{'IN_ENCODING'}})) 1987 { 1988 $encoding_name = $perl_charset_to_html{$Texi2HTML::THISDOC{'IN_ENCODING'}}; 1989 } 1990 elsif (defined($document_encoding) and defined($perl_charset_to_html{$document_encoding})) 1991 { 1992 $encoding_name = $perl_charset_to_html{$document_encoding}; 1993 } 1994 elsif (defined($out_encoding)) 1995 { 1996 $encoding_name = $out_encoding; 1997 } 1998 elsif (defined($Texi2HTML::THISDOC{'IN_ENCODING'})) 1999 { 2000 $encoding_name = $Texi2HTML::THISDOC{'IN_ENCODING'}; 2001 } 2002 elsif (defined($document_encoding)) 2003 { 2004 $encoding_name = $document_encoding; 2005 } 2006 elsif (defined($perl_charset_to_html{$DEFAULT_ENCODING})) 2007 { 2008 $encoding_name = $perl_charset_to_html{$DEFAULT_ENCODING}; 2009 } 2010 else 2011 { 2012 $encoding_name = 'us-ascii'; 2013 } 2014 } 2015 2016 $Texi2HTML::THISDOC{'OUT_ENCODING'} = $out_encoding; 2017 $Texi2HTML::THISDOC{'ENCODING_NAME'} = $encoding_name; 2018 $Texi2HTML::THISDOC{'DOCUMENT_ENCODING'} = $document_encoding; 2019 2020 $out_encoding = 'UNDEF' if (!defined($out_encoding)); 2021 my $in_encoding = $Texi2HTML::THISDOC{'IN_ENCODING'}; 2022 $in_encoding = 'UNDEF' if (!defined($in_encoding)); 2023 $document_encoding = 'UNDEF' if (!defined($document_encoding)); 2024 print STDERR "# Encodings: doc $document_encoding, in $in_encoding out $out_encoding, name $encoding_name\n" if ($VERBOSE); 2025} 2026 2027my @t2h_default_multitable_stack; 2028# We have to do this dynamically because of internationalization and because 2029# in body $LANG could be used. 2030sub t2h_default_init_out() 2031{ 2032 @t2h_default_multitable_stack = (); 2033 &$translate_names; 2034 # Set the default body text, inserted between <body ... > 2035 if (defined($BODYTEXT)) 2036 { 2037 $Texi2HTML::THISDOC{'BODYTEXT'} = $BODYTEXT; 2038 } 2039 else 2040 { 2041 $Texi2HTML::THISDOC{'BODYTEXT'} = 'lang="' . $Texi2HTML::THISDOC{'current_lang'} . '" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000"'; 2042 } 2043 if (!defined($EXTERNAL_CROSSREF_SPLIT)) 2044 { 2045 if ($SPLIT) 2046 { 2047 $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = 1; 2048 } 2049 else 2050 { 2051 $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = 0; 2052 } 2053 } 2054 else 2055 { 2056 $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} = $EXTERNAL_CROSSREF_SPLIT; 2057 } 2058 2059 t2h_default_set_out_encoding(); 2060 2061 # not in code_style, according to post on bug-texinfo 2062 if ($SIMPLE_MENU) 2063 { 2064 foreach my $format ('menu', 'detailmenu') 2065 { 2066 if (!defined($complex_format_map->{$format})) 2067 { 2068 $complex_format_map->{$format} = { 'begin' => q{''} , 'end' => q{''}, 2069 'pre_style' => "$MENU_PRE_STYLE", 'class' => 'menu-preformatted', 2070# 'style' => 'code' 2071 }; 2072 } 2073 } 2074 #$SEPARATE_DESCRIPTION = 1; 2075 #$format_map{'menu_comment'} = '' if (!defined($format_map{'menu_comment'})); 2076 } 2077 elsif (!defined($format_map{'menu_comment'}) and !defined($complex_format_map->{'menu_comment'})) 2078 { 2079 $complex_format_map->{'menu_comment'} = 2080 { 2081 'begin' => q{"<tr><th colspan=\"3\" align=\"left\" valign=\"top\">"}, 2082 'end' => q{"</th></tr>"}, 'pre_style' => "$MENU_PRE_STYLE", 'class' => 'menu-comment', 2083# 'style' => 'code' 2084 } 2085 } 2086 # obsolete 2087 #return $OUT_ENCODING; 2088}; 2089 2090sub t2h_default_finish_out() 2091{ 2092} 2093 2094####################################################################### 2095# 2096# Values guessed if not set here. The value used is in 2097# $Texi2HTML::THISDOC{'VARNAME'} 2098# 2099####################################################################### 2100 2101$BODYTEXT = undef; 2102 2103# default used in init_out for the setting of the ENCODING_NAME variable 2104$DEFAULT_ENCODING = 'utf8'; 2105 2106# In file encoding. The @documentencoding allows autodetection of 2107# that variable. 2108$DOCUMENT_ENCODING = undef; 2109 2110# In file encoding, understandable by perl. Set according to DOCUMENT_ENCODING 2111$IN_ENCODING = undef; 2112 2113# Formatted document encoding name. If undef, set in init_out based on 2114# $OUT_ENCODING or $DOCUMENT_ENCODING if they are defined 2115$ENCODING_NAME = undef; 2116 2117# Out files encoding, understandable by perl. If undef, set in init_out 2118# using $ENCODING_NAME or $IN_ENCODING if they are defined 2119$OUT_ENCODING = undef; 2120 2121# Used to set $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'}. 2122# if undef set to @documentdescription. If there is no @documentdescription, 2123# set in page_head. 2124$DOCUMENT_DESCRIPTION = undef; 2125 2126# if undef $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'} set 1 if SPLIT, 2127# to 0 otherwise 2128$EXTERNAL_CROSSREF_SPLIT = undef; 2129 2130$USER = undef; 2131$DATE = undef; 2132 2133 2134######################################################################## 2135# Control of Page layout: 2136# You can make changes of the Page layout at two levels: 2137# 1.) For small changes, it is often enough to change the value of 2138# some global string/hash/array variables 2139# 2.) For larger changes, reimplement one of the T2H_DEFAULT_<fnc>* routines, 2140# give them another name, and assign them to the respective 2141# $<fnc> variable. 2142 2143# As a general interface, the hashes Texi2HTML::HREF, Texi2HTML::NAME, Texi2HTML::NODE, Texi2HTML::NO_TEXI, Texi2HTML::SIMPLE_TEXT hold 2144# href, html-name, node-name, name after removal of texi commands of 2145# This -- current section (resp. html page) 2146# Top -- top element 2147# Contents -- Table of contents element 2148# Overview -- Short table of contents element 2149# Index -- Index page element 2150# About -- page which explain "navigation buttons" element 2151# First -- first node element 2152# Last -- last node element 2153# 2154# Whether or not the following hash values are set, depends on the context 2155# (all values are w.r.t. 'This' section) 2156# Next -- next element of texinfo 2157# Prev -- previous element of texinfo 2158# NodeUp -- up node of texinfo 2159# Following -- following node in node reading order, taking menu into account 2160# Forward -- next node in reading order 2161# Back -- previous node in reading order 2162# Up -- parent given by sectionning commands 2163# FastForward -- if leave node, up and next, else next node 2164# FastBackward-- if leave node, up and prev, else prev node 2165# 2166# Furthermore, the following global variabels are set: 2167# $Texi2HTML::THISDOC{title} -- title as set by @title... 2168# $Texi2HTML::THISDOC{title_no_texi} -- title without texi (without html elements) 2169# $Texi2HTML::THISDOC{title_texi} -- title with texinfo @-commands 2170# $Texi2HTML::THISDOC{fulltitle} -- full title as set by @title... 2171# $Texi2HTML::THISDOC{subtitle} -- subtitle as set by @subtitle 2172# $Texi2HTML::THISDOC{author} -- author as set by @author 2173# $Texi2HTML::THISDOC{copying_comment} -- text of @copying and @end copying in comment 2174# 2175# $Texi2HTML::THISDOC{program} -- name and version of texi2html 2176# $Texi2HTML::THISDOC{program_homepage} -- homepage for texi2html 2177# $Texi2HTML::THISDOC{program_authors} -- authors of texi2html 2178# $Texi2HTML::THISDOC{today} -- date formatted with pretty_date 2179# $Texi2HTML::THISDOC{toc_file} -- table of contents file 2180# $Texi2HTML::THISDOC{file_base_name} -- base name of the texinfo manual file 2181# $Texi2HTML::THISDOC{input_file_name} -- name of the texinfo manual file 2182# $Texi2HTML::THISDOC{destination_directory} 2183 # -- directory for the resulting files 2184# $Texi2HTML::THISDOC{user} -- user running the script 2185# $Texi2HTML::THISDOC{css_import_lines} -- ref on @import lines in css files 2186# $Texi2HTML::THISDOC{css_lines} -- ref on css rules lines 2187# other $Texi2HTML::THISDOC keys corresponds with texinfo commands, the value 2188# being the command arg, for the following commands: 2189# kbdinputstyle, paragraphindent, setchapternewpage, headings, footnotestyle, 2190# exampleindent, firstparagraphindent, everyheading, everyfooting, 2191# evenheading, evenfooting, oddheading, oddfooting 2192# 2193# and pointer to arrays of lines which need to be printed by main::print_lines 2194# $Texi2HTML::THIS_SECTION -- lines of 'This' section 2195# $Texi2HTML::OVERVIEW -- lines of short table of contents 2196# $Texi2HTML::TOC_LINES -- lines of table of contents 2197# $Texi2HTML::TITLEPAGE -- lines of title page 2198# 2199# $Texi2HTML::THIS_ELEMENT holds the element reference. 2200 2201# 2202# There are the following subs which control the layout: 2203# 2204$print_section = \&T2H_DEFAULT_print_section; 2205$end_section = \&T2H_DEFAULT_end_section; 2206$one_section = \&T2H_DEFAULT_one_section; 2207$print_Top_header = \&T2H_DEFAULT_print_Top_header; 2208$print_Top_footer = \&T2H_DEFAULT_print_Top_footer; 2209$print_Top = \&T2H_DEFAULT_print_Top; 2210$print_Toc = \&T2H_DEFAULT_print_Toc; 2211$print_Overview = \&T2H_DEFAULT_print_Overview; 2212$print_Footnotes = \&T2H_DEFAULT_print_Footnotes; 2213$print_About = \&T2H_DEFAULT_print_About; 2214$print_misc_header = \&T2H_DEFAULT_print_misc_header; 2215$print_misc_footer = \&T2H_DEFAULT_print_misc_footer; 2216$print_misc = \&T2H_DEFAULT_print_misc; 2217$print_section_footer = \&T2H_DEFAULT_print_section_footer; 2218$print_chapter_header = \&T2H_DEFAULT_print_chapter_header; 2219$print_section_header = \&T2H_DEFAULT_print_section_header; 2220$print_element_header = \&T2H_DEFAULT_print_element_header; 2221$print_chapter_footer = \&T2H_DEFAULT_print_chapter_footer; 2222$print_page_head = \&T2H_DEFAULT_print_page_head; 2223$print_page_foot = \&T2H_DEFAULT_print_page_foot; 2224$print_head_navigation = \&T2H_DEFAULT_print_head_navigation; 2225$print_foot_navigation = \&T2H_DEFAULT_print_foot_navigation; 2226$button_icon_img = \&T2H_DEFAULT_button_icon_img; 2227$print_navigation = \&T2H_DEFAULT_print_navigation; 2228$about_body = \&T2H_DEFAULT_about_body; 2229$print_frame = \&T2H_DEFAULT_print_frame; 2230$print_toc_frame = \&T2H_DEFAULT_print_toc_frame; 2231#$toc_body = \&T2H_DEFAULT_toc_body; 2232$titlepage = \&T2H_DEFAULT_titlepage; 2233$css_lines = \&T2H_DEFAULT_css_lines; 2234$print_redirection_page = \&T2H_DEFAULT_print_redirection_page; 2235$node_file_name = \&T2H_DEFAULT_node_file_name; 2236$inline_contents = \&T2H_DEFAULT_inline_contents; 2237$program_string = \&T2H_DEFAULT_program_string; 2238 2239######################################################################## 2240# Layout for html for every sections 2241# 2242 2243sub T2H_DEFAULT_print_element_header 2244{ 2245 my $first_in_page = shift; 2246 my $previous_is_top = shift; 2247 my $buttons = \@SECTION_BUTTONS; 2248 2249 if (($first_in_page or $previous_is_top) and $SECTION_NAVIGATION) 2250 { 2251 return &$print_head_navigation(undef, $buttons); 2252 } 2253 else 2254 { # got to do this here, as it isn't done in print_head_navigation 2255 return &$print_navigation($buttons) if ($SECTION_NAVIGATION or $SPLIT eq 'node'); 2256 } 2257} 2258 2259sub T2H_DEFAULT_print_section 2260{ 2261 my $fh = shift; 2262 my $first_in_page = shift; 2263 my $previous_is_top = shift; 2264 my $element = shift; 2265 my $buttons = \@SECTION_BUTTONS; 2266 2267 my $nw = main::print_lines($fh); 2268 if (defined $SPLIT 2269 and (($SPLIT eq 'node') && $SECTION_NAVIGATION)) 2270 { 2271 my $buttons = \@NODE_FOOTER_BUTTONS; 2272 &$print_foot_navigation($fh, $buttons, $SMALL_RULE, 2273 (!defined($WORDS_IN_PAGE) or (defined ($nw) and $nw >= $WORDS_IN_PAGE)), 2274 $element); 2275# print $fh "$SMALL_RULE\n"; 2276# &$print_navigation($buttons) if (!defined($WORDS_IN_PAGE) or (defined ($nw) 2277# and $nw >= $WORDS_IN_PAGE)); 2278 } 2279} 2280 2281sub T2H_DEFAULT_one_section($$) 2282{ 2283 my $fh = shift; 2284 my $element = shift; 2285 main::print_lines($fh); 2286 print $fh "$SMALL_RULE\n"; 2287 &$print_page_foot($fh); 2288} 2289 2290################################################################### 2291# Layout of top-page I recommend that you use @ifnothtml, @ifhtml, 2292# @html within the Top texinfo node to specify content of top-level 2293# page. 2294# 2295# If you enclose everything in @ifnothtml, then title, subtitle, 2296# author and overview is printed 2297# Texi2HTML::HREF of Next, Prev, Up, Forward, Back are not defined 2298# if $T2H_SPLIT then Top page is in its own html file 2299sub T2H_DEFAULT_print_Top_header($$) 2300{ 2301 my $fh = shift; 2302 my $do_page_head = shift; 2303 &$print_page_head($fh) if ($do_page_head); 2304} 2305sub T2H_DEFAULT_print_Top_footer($$$) 2306{ 2307 my $fh = shift; 2308 my $end_page = shift; 2309 my $element = shift; 2310 my $buttons = \@MISC_BUTTONS; 2311 &$print_foot_navigation($fh, $buttons, $SMALL_RULE, 2312 ($end_page and ($SECTION_NAVIGATION or ($SPLIT and $SPLIT ne 'node'))), $element); 2313# &$print_foot_navigation($fh); 2314# print $fh "$SMALL_RULE\n"; 2315 if ($end_page) 2316 { 2317# &$print_navigation($fh, $buttons); 2318 &$print_page_foot($fh); 2319 } 2320} 2321 2322sub T2H_DEFAULT_print_Top($$$) 2323{ 2324 my $fh = shift; 2325 my $has_top_heading = shift; 2326 my $element = shift; 2327 2328 # for redefining navigation buttons use: 2329 # my $buttons = [...]; 2330 # as it is, 'Top', 'Contents', 'Index', 'About' are printed 2331 my $buttons = \@MISC_BUTTONS; 2332 2333 my $nw; 2334 # a dirty hack. A section is considered to be empty if there are 2 2335 # lines or less in it. Indeed, this catches the sectionning command like 2336 # @top and the @node. 2337 if (scalar(@$Texi2HTML::THIS_SECTION) > 2) 2338 { 2339 # if top-level node has content 2340 $nw = main::print_lines($fh, $Texi2HTML::THIS_SECTION); 2341 } 2342 else 2343 { 2344 # top-level node is fully enclosed in @ifnothtml 2345 # print fulltitle, subtitle, author, Overview or table of contents 2346 # redo the titlepage with the actual state 2347 my ($titlepage_text, $titlepage_no_texi, $titlepage_simple_format) = main::do_special_region_lines('titlepage',$Texi2HTML::THISDOC{'state'}); 2348 2349 &$titlepage([],$titlepage_text, $titlepage_no_texi, $titlepage_simple_format); 2350 # only print the header and node label 2351 print $fh $Texi2HTML::THIS_SECTION->[0]; 2352 print $fh $Texi2HTML::TITLEPAGE; 2353 if (@{$Texi2HTML::OVERVIEW} and !$Texi2HTML::THISDOC{'setshortcontentsaftertitlepage'}) 2354 { 2355 print $fh '<h2> ' . $Texi2HTML::NAME{'Overview'} . "</h2>\n" . "<blockquote\n"; 2356 my $nw = main::print_lines($fh, $Texi2HTML::OVERVIEW); 2357 print $fh "</blockquote>\n"; 2358 } 2359 elsif (@{$Texi2HTML::TOC_LINES} and !$Texi2HTML::THISDOC{'setcontentsaftertitlepage'}) 2360 { 2361 print $fh '<h1> ' . $Texi2HTML::NAME{'Contents'} . "</h1>\n"; 2362 my $nw = main::print_lines($fh, $Texi2HTML::TOC_LINES); 2363 } 2364 } 2365} 2366 2367################################################################### 2368# Layout of Toc, Overview, and Footnotes pages 2369# By default, we use "normal" layout 2370# Texi2HTML::HREF of Next, Prev, Up, Forward, Back, etc are not defined 2371# use: my $buttons = [...] to redefine navigation buttons 2372sub T2H_DEFAULT_print_Toc 2373{ 2374 return &$print_misc(@_); 2375} 2376sub T2H_DEFAULT_print_Overview 2377{ 2378 return &$print_misc(@_); 2379} 2380sub T2H_DEFAULT_print_Footnotes 2381{ 2382 return &$print_misc(@_); 2383} 2384sub T2H_DEFAULT_print_About 2385{ 2386 # if there is no section navigation and it is not split, the 2387 # navigation information is useless 2388 return &$print_misc(@_) if ($SPLIT or $SECTION_NAVIGATION); 2389} 2390 2391sub T2H_DEFAULT_print_misc_header 2392{ 2393 my $fh = shift; 2394 my $buttons = shift; 2395 my $new_file = shift; 2396 my $misc_page = shift; 2397 &$print_page_head($fh) if ($new_file); 2398 print $fh "".&$misc_element_label($misc_pages_targets{$misc_page}, $misc_page); 2399 &$print_head_navigation($fh, $buttons) if ($new_file or $SECTION_NAVIGATION); 2400} 2401 2402sub T2H_DEFAULT_print_misc_footer 2403{ 2404 my $fh = shift; 2405 my $buttons = shift; 2406 my $new_file = shift; 2407 &$print_foot_navigation($fh, $buttons, $SMALL_RULE, 2408 ($new_file and ($SECTION_NAVIGATION or ($SPLIT and $SPLIT ne 'node'))), undef); 2409# print $fh "$SMALL_RULE\n"; 2410 if ($new_file) 2411 { 2412# &$print_navigation($fh, $buttons);# if ($SPLIT ne 'node'); 2413 &$print_page_foot($fh); 2414 } 2415} 2416 2417sub T2H_DEFAULT_print_misc 2418{ 2419 my $fh = shift; 2420 my $new_file = shift; 2421 my $misc_page = shift; 2422 my $buttons = \@MISC_BUTTONS; 2423 &$print_misc_header($fh, $buttons, $new_file, $misc_page); 2424 print $fh "<h1>$Texi2HTML::NAME{This}</h1>\n"; 2425 main::print_lines($fh); 2426 &$print_misc_footer($fh, $buttons, $new_file); 2427} 2428################################################################## 2429# section_footer is only called if SPLIT eq 'section' 2430# section_footer: after print_section of last section, before print_page_foot 2431# 2432 2433sub T2H_DEFAULT_print_section_footer 2434{ 2435 my $fh = shift; 2436 my $element = shift; 2437 my $buttons = \@SECTION_FOOTER_BUTTONS; 2438 &$print_foot_navigation($fh, $buttons, $BIG_RULE, 1, $element); 2439# &$end_section ($fh, 1, $element); 2440# &$print_navigation($fh, $buttons); 2441} 2442 2443################################################################### 2444# chapter_header and chapter_footer are only called if 2445# SPLIT eq 'chapter' 2446# chapter_header: after print_page_head, before print_section 2447# chapter_footer: after print_section of last section, before print_page_foot 2448# 2449# If you want to get rid of navigation stuff after each section, 2450# redefine print_section such that it does not call print_navigation, 2451# and put print_navigation into print_chapter_header 2452sub T2H_DEFAULT_print_chapter_header 2453{ 2454 my $fh = shift; 2455 my $element = shift; 2456 # nothing to do there, by default, the navigation panel 2457 # is the section navigation panel 2458 if (! $SECTION_NAVIGATION) 2459 { # in this case print_navigation is called here. 2460 my $buttons = \@CHAPTER_BUTTONS; 2461 &$print_head_navigation($fh, $buttons); 2462 print $fh "\n$MIDDLE_RULE\n" unless ($VERTICAL_HEAD_NAVIGATION); 2463 } 2464} 2465 2466sub T2H_DEFAULT_print_chapter_footer 2467{ 2468 my $fh = shift; 2469 my $element = shift; 2470 my $buttons = \@CHAPTER_BUTTONS; 2471 &$print_foot_navigation($fh, $buttons, $BIG_RULE, 1, $element); 2472# print $fh "$BIG_RULE\n"; 2473# &$print_navigation($fh, $buttons); 2474} 2475 2476sub T2H_DEFAULT_print_section_header 2477{ 2478 # nothing to do there, by default 2479 if (! $SECTION_NAVIGATION) 2480 { # in this case print_navigation is called here. 2481 my $fh = shift; 2482 my $buttons = \@SECTION_BUTTONS; 2483 &$print_head_navigation($fh, $buttons); 2484 } 2485} 2486 2487 2488################################################################### 2489# Layout of standard header and footer 2490# 2491 2492sub T2H_DEFAULT_print_page_head($) 2493{ 2494 my $fh = shift; 2495 my $longtitle = "$Texi2HTML::THISDOC{'fulltitle_simple_format'}"; 2496 $longtitle .= ": $Texi2HTML::SIMPLE_TEXT{'This'}" if (defined ($Texi2HTML::SIMPLE_TEXT{'This'}) and ($Texi2HTML::SIMPLE_TEXT{'This'} !~ /^\s*$/) and $SPLIT); 2497 my $description = $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'}; 2498 $description = $longtitle if (!defined($description)); 2499 $description = "<meta name=\"description\" content=\"$description\">" if 2500 ($description ne ''); 2501 my $encoding = ''; 2502 $encoding = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$Texi2HTML::THISDOC{'ENCODING_NAME'}\">" if (defined($Texi2HTML::THISDOC{'ENCODING_NAME'}) and ($Texi2HTML::THISDOC{'ENCODING_NAME'} ne '')); 2503 my $links = ''; 2504 if ($USE_LINKS) 2505 { 2506 foreach my $link (@LINKS_BUTTONS) 2507 { 2508#print STDERR "$link!!$Texi2HTML::HREF{$link}\n"; 2509 if (defined($Texi2HTML::HREF{$link}) and $Texi2HTML::HREF{$link} ne '') 2510 { 2511 my $title = ''; 2512 $title = " title=\"$Texi2HTML::SIMPLE_TEXT{$link}\"" if (defined($Texi2HTML::SIMPLE_TEXT{$link})); 2513 my $rel = ''; 2514 $rel = " rel=\"$BUTTONS_REL{$link}\"" if (defined($BUTTONS_REL{$link})); 2515 $links .= "<link href=\"$Texi2HTML::HREF{$link}\"${rel}${title}>\n"; 2516 } 2517 } 2518 } 2519 2520 print $fh <<EOT; 2521$DOCTYPE 2522<html> 2523$Texi2HTML::THISDOC{'copying_comment'}<!-- Created on $Texi2HTML::THISDOC{today} by $Texi2HTML::THISDOC{program} 2524$Texi2HTML::THISDOC{program_authors}--> 2525<head> 2526<title>$longtitle</title> 2527 2528$description 2529<meta name="keywords" content="$longtitle"> 2530<meta name="resource-type" content="document"> 2531<meta name="distribution" content="global"> 2532<meta name="Generator" content="$Texi2HTML::THISDOC{program}"> 2533$encoding 2534${links}$Texi2HTML::THISDOC{'CSS_LINES'} 2535$EXTRA_HEAD 2536</head> 2537 2538<body $Texi2HTML::THISDOC{'BODYTEXT'}> 2539$AFTER_BODY_OPEN 2540EOT 2541} 2542 2543sub T2H_DEFAULT_program_string() 2544{ 2545 my $user = $Texi2HTML::THISDOC{'user'}; 2546 my $date = $Texi2HTML::THISDOC{'today'}; 2547 $user = '' if (!defined($user)); 2548 $date = '' if (!defined($date)); 2549 if (($user ne '') and ($date ne '')) 2550 { 2551 return &$I('This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.', { 2552 'user' => $user, 'date' => $date, 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' => $Texi2HTML::THISDOC{'program'} }, {'duplicate'=>1}); 2553 } 2554 elsif ($user ne '') 2555 { 2556 return &$I('This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.', { 2557 'user' => $user, 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' => $Texi2HTML::THISDOC{'program'} }, {'duplicate'=>1}); 2558 } 2559 elsif ($date ne '') 2560 { 2561 return &$I('This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.', { 2562 'date' => $date, 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' => $Texi2HTML::THISDOC{'program'} },{'duplicate'=>1}); 2563 } 2564 return &$I('This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.', { 2565 'program_homepage' => $Texi2HTML::THISDOC{'program_homepage'}, 'program' 2566=> $Texi2HTML::THISDOC{'program'} },{'duplicate'=>1}); 2567} 2568 2569sub T2H_DEFAULT_end_section($$$) 2570{ 2571 my $fh = shift; 2572 my $misc_and_section_separation = shift; 2573 my $element = shift; 2574 #&$print_foot_navigation($fh) if ($end_foot_navigation); 2575 #print $fh "$BIG_RULE\n"; 2576 if ($misc_and_section_separation) 2577 { 2578 &$print_foot_navigation($fh, undef, $BIG_RULE, 0, $element); 2579 } 2580 else 2581 { 2582 print $fh "$BIG_RULE\n"; 2583 } 2584} 2585 2586sub T2H_DEFAULT_print_page_foot($) 2587{ 2588 my $fh = shift; 2589 my $program_string = &$program_string(); 2590 print $fh <<EOT; 2591<p> 2592 <font size="-1"> 2593 $program_string 2594 </font> 2595 <br> 2596$PRE_BODY_CLOSE 2597</p> 2598</body> 2599</html> 2600EOT 2601} 2602 2603################################################################### 2604# Layout of navigation panel 2605 2606sub T2H_DEFAULT_print_head_navigation($$) 2607{ 2608 my $fh = shift; 2609 my $buttons = shift; 2610 2611 my $result = ''; 2612 if ($VERTICAL_HEAD_NAVIGATION) 2613 { 2614 $result .= <<EOT; 2615<table border="0" cellpadding="0" cellspacing="0"> 2616<tr valign="top"> 2617<td align="left"> 2618EOT 2619 } 2620 $result .= &$print_navigation($buttons, $VERTICAL_HEAD_NAVIGATION); 2621 if ($VERTICAL_HEAD_NAVIGATION) 2622 { 2623 $result .= <<EOT; 2624</td> 2625<td align="left"> 2626EOT 2627 } 2628 elsif (defined $SPLIT 2629 and ($SPLIT eq 'node')) 2630 { 2631 $result .= "$SMALL_RULE\n"; 2632 } 2633 2634 print $fh $result if (defined($fh)); 2635 return $result; 2636} 2637 2638sub T2H_DEFAULT_print_foot_navigation 2639{ 2640 my $fh = shift; 2641 my $buttons = shift; 2642 my $rule = shift; 2643 my $print_navigation_panel = shift; 2644 my $element = shift; 2645 2646 $rule = '' if (!defined($rule)); 2647 $print_navigation_panel = 1 if (!defined($print_navigation_panel) 2648 and defined($buttons)); 2649 2650 if ($VERTICAL_HEAD_NAVIGATION) 2651 { 2652 print $fh <<EOT; 2653</td> 2654</tr> 2655</table> 2656EOT 2657 } 2658 print $fh "$rule\n" if ($rule ne ''); 2659 print $fh "".&$print_navigation($buttons) if ($print_navigation_panel); 2660} 2661 2662###################################################################### 2663# navigation panel 2664# 2665# how to create IMG tag 2666sub T2H_DEFAULT_button_icon_img 2667{ 2668 my $button = shift; 2669 my $icon = shift; 2670 my $name = shift; 2671 return '' if (!defined($icon)); 2672 $button = "" if (!defined ($button)); 2673 $name = '' if (!defined($name)); 2674 my $alt = ''; 2675 if ($name ne '') 2676 { 2677 if ($button ne '') 2678 { 2679 $alt = "$button: $name"; 2680 } 2681 else 2682 { 2683 $alt = $name; 2684 } 2685 } 2686 else 2687 { 2688 $alt = $button; 2689 } 2690 return qq{<img src="$icon" border="0" alt="$alt" align="middle">}; 2691} 2692 2693sub T2H_DEFAULT_print_navigation 2694{ 2695 my $buttons = shift; 2696 my $vertical = shift; 2697 2698 my $result = ''; 2699 $result .= '<table cellpadding="1" cellspacing="1" border="0">'."\n"; 2700 $result .= "<tr>" unless $vertical; 2701 for my $button (@$buttons) 2702 { 2703 $result .= qq{<tr valign="top" align="left">\n} if $vertical; 2704 $result .= qq{<td valign="middle" align="left">}; 2705 2706 if (ref($button) eq 'CODE') 2707 { 2708 $result .= &$button($vertical); 2709 } 2710 elsif (ref($button) eq 'SCALAR') 2711 { 2712 $result .= "$$button" if defined($$button); 2713 } 2714 elsif (ref($button) eq 'ARRAY') 2715 { 2716 my $text = $button->[1]; 2717 my $button_href = $button->[0]; 2718 # verify that $button_href is simple text and text is a reference 2719 if (defined($button_href) and !ref($button_href) 2720 and defined($text) and (ref($text) eq 'SCALAR') and defined($$text)) 2721 { # use given text 2722 if ($Texi2HTML::HREF{$button_href}) 2723 { 2724 my $anchor_attributes = ''; 2725 if ($USE_ACCESSKEY and (defined($BUTTONS_ACCESSKEY{$button_href})) and ($BUTTONS_ACCESSKEY{$button_href} ne '')) 2726 { 2727 $anchor_attributes = "accesskey=\"$BUTTONS_ACCESSKEY{$button_href}\""; 2728 } 2729 if ($USE_REL_REV and (defined($BUTTONS_REL{$button_href})) and ($BUTTONS_REL{$button_href} ne '')) 2730 { 2731 $anchor_attributes .= " rel=\"$BUTTONS_REL{$button_href}\""; 2732 } 2733 $result .= "" . 2734 &$anchor('', 2735 $Texi2HTML::HREF{$button_href}, 2736 $$text, 2737 $anchor_attributes 2738 ) 2739 ; 2740 } 2741 else 2742 { 2743 $result .= $$text; 2744 } 2745 } 2746 } 2747 elsif ($button eq ' ') 2748 { # handle space button 2749 $result .= 2750 ($ICONS && $ACTIVE_ICONS{' '}) ? 2751 &$button_icon_img($BUTTONS_NAME{$button}, $ACTIVE_ICONS{' '}) : 2752 $NAVIGATION_TEXT{' '}; 2753 #next; 2754 } 2755 elsif ($Texi2HTML::HREF{$button}) 2756 { # button is active 2757 my $btitle = $BUTTONS_GOTO{$button} ? 2758 'title="' . $BUTTONS_GOTO{$button} . '"' : ''; 2759 if ($USE_ACCESSKEY and (defined($BUTTONS_ACCESSKEY{$button})) and ($BUTTONS_ACCESSKEY{$button} ne '')) 2760 { 2761 $btitle .= " accesskey=\"$BUTTONS_ACCESSKEY{$button}\""; 2762 } 2763 if ($USE_REL_REV and (defined($BUTTONS_REL{$button})) and ($BUTTONS_REL{$button} ne '')) 2764 { 2765 $btitle .= " rel=\"$BUTTONS_REL{$button}\""; 2766 } 2767 if ($ICONS && $ACTIVE_ICONS{$button}) 2768 { # use icon 2769 $result .= '' . 2770 &$anchor('', 2771 $Texi2HTML::HREF{$button}, 2772 &$button_icon_img($BUTTONS_NAME{$button}, 2773 $ACTIVE_ICONS{$button}, 2774 $Texi2HTML::SIMPLE_TEXT{$button}), 2775 $btitle 2776 ); 2777 } 2778 else 2779 { # use text 2780 $result .= 2781 '[' . 2782 &$anchor('', 2783 $Texi2HTML::HREF{$button}, 2784 $NAVIGATION_TEXT{$button}, 2785 $btitle 2786 ) . 2787 ']'; 2788 } 2789 } 2790 else 2791 { # button is passive 2792 $result .= 2793 $ICONS && $PASSIVE_ICONS{$button} ? 2794 &$button_icon_img($BUTTONS_NAME{$button}, 2795 $PASSIVE_ICONS{$button}, 2796 $Texi2HTML::SIMPLE_TEXT{$button}) : 2797 2798 "[" . $NAVIGATION_TEXT{$button} . "]"; 2799 } 2800 $result .= "</td>\n"; 2801 $result .= "</tr>\n" if $vertical; 2802 } 2803 $result .= "</tr>" unless $vertical; 2804 $result .= "</table>\n"; 2805 return $result; 2806} 2807 2808###################################################################### 2809# Frames: this is from "Richard Y. Kim" <ryk@coho.net> 2810# Should be improved to be more conforming to other _print* functions 2811# toc_file and main_file passed as args are relative to the texinfo manual 2812# location, and therefore are not used. 2813 2814sub T2H_DEFAULT_print_frame 2815{ 2816 my $fh = shift; 2817 my $toc_file = shift; 2818 my $main_file = shift; 2819 $main_file = $Texi2HTML::THISDOC{'filename'}->{'top'}; 2820 $toc_file = $Texi2HTML::THISDOC{'filename'}->{'toc_frame'}; 2821 print $fh <<EOT; 2822$FRAMESET_DOCTYPE 2823<html> 2824<head><title>$Texi2HTML::THISDOC{'fulltitle'}</title></head> 2825<frameset cols="140,*"> 2826 <frame name="toc" src="$toc_file"> 2827 <frame name="main" src="$main_file"> 2828</frameset> 2829</html> 2830EOT 2831} 2832 2833sub T2H_DEFAULT_print_toc_frame 2834{ 2835 my $fh = shift; 2836 my $stoc_lines = shift; 2837 &$print_page_head($fh); 2838 print $fh <<EOT; 2839<h2>Content</h2> 2840EOT 2841 print $fh map {s/\bhref=/target="main" href=/; $_;} @$stoc_lines; 2842 print $fh "</body></html>\n"; 2843} 2844 2845# This subroutine is intended to fill @Texi2HTML::TOC_LINES and 2846# @Texi2HTML::OVERVIEW with the table of contents and short table of 2847# contents. 2848# 2849# arguments: 2850# ref on an array containing all the elements 2851 2852# each element is a reference on a hash. The following keys might be of 2853# use: 2854# 'top': true if this is the top element 2855# 'toc_level': level of the element in the table of content. Highest level 2856# is 1 for the @top element and for chapters, appendix and so on, 2857# 2 for section, unnumberedsec and so on... 2858# 'tocid': label used for reference linking to the element in table of 2859# contents 2860# 'file': the file containing the element, usefull to do href to that file 2861# in case the document is split. 2862# 'text': text of the element, with section number 2863# 'text_nonumber': text of the element, without section number 2864 2865# Relevant configuration variables are: 2866# $NUMBER_SECTIONS 2867# $NO_BULLET_LIST_ATTRIBUTE: usefull in case a list is used 2868# $FRAMES: @Texi2HTML::OVERVIEW is used in one of the frames. 2869# $BEFORE_OVERVIEW 2870# $AFTER_OVERVIEW 2871# $BEFORE_TOC_LINES 2872# $AFTER_TOC_LINES 2873# $DO_CONTENTS 2874# $DO_SCONTENTS 2875 2876sub T2H_DEFAULT_toc_body($) 2877{ 2878} 2879 2880sub T2H_DEFAULT_inline_contents($$$) 2881{ 2882 my $fh = shift; 2883 my $command = shift; 2884 my $element = shift; 2885 my $name; 2886 my $lines; 2887 2888 my $result = undef; 2889 2890 if ($command eq 'contents') 2891 { 2892 $name = $Texi2HTML::NAME{'Contents'}; 2893 $lines = $Texi2HTML::TOC_LINES; 2894 } 2895 else 2896 { 2897 $name = $Texi2HTML::NAME{'Overview'}; 2898 $lines = $Texi2HTML::OVERVIEW; 2899 } 2900 if (@{$lines}) 2901 { 2902 $result = [ "".&$anchor($element->{'id'})."\n", 2903 "<h1>$name</h1>\n" ]; 2904 push @$result, @$lines; 2905 } 2906 2907 return $result; 2908} 2909 2910sub T2H_DEFAULT_css_lines ($$) 2911{ 2912 my $import_lines = shift; 2913 my $rule_lines = shift; 2914# return if (defined($CSS_LINES) or (!@$rule_lines and !@$import_lines and (! keys(%css_map)))); 2915 if (defined($CSS_LINES)) 2916 { # if predefined, use CSS_LINES. 2917 $Texi2HTML::THISDOC{'CSS_LINES'} = $CSS_LINES; 2918 return; 2919 } 2920 return if (!@$rule_lines and !@$import_lines and (! keys(%css_map))); 2921 my $css_lines = "<style type=\"text/css\">\n<!--\n"; 2922 $css_lines .= join('',@$import_lines) . "\n" if (@$import_lines); 2923 foreach my $css_rule (sort(keys(%css_map))) 2924 { 2925 next unless ($css_map{$css_rule}); 2926 $css_lines .= "$css_rule {$css_map{$css_rule}}\n"; 2927 } 2928 $css_lines .= join('',@$rule_lines) . "\n" if (@$rule_lines); 2929 $css_lines .= "-->\n</style>\n"; 2930 foreach my $ref (@CSS_REFS) 2931 { 2932 $css_lines .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$ref\">\n"; 2933 } 2934 $Texi2HTML::THISDOC{'CSS_LINES'} = $css_lines; 2935} 2936 2937###################################################################### 2938# About page 2939# 2940 2941# PRE_ABOUT can be a function reference or a scalar. 2942# Note that if it is a scalar, T2H_InitGlobals has not been called, 2943# and all global variables like $ADDRESS are not available. 2944$PRE_ABOUT = sub 2945{ 2946 return ' ' . &$program_string() . "\n"; 2947}; 2948 2949# If customizing $AFTER_ABOUT, be sure to put the content inside <p></p>. 2950$AFTER_ABOUT = ''; 2951 2952%BUTTONS_EXAMPLE = 2953 ( 2954 'Top', ' ', 2955 'Contents', ' ', 2956 'Overview', ' ', 2957 'Index', ' ', 2958 'This', '1.2.3', 2959 'Back', '1.2.2', 2960 'FastBack', '1', 2961 'Prev', '1.2.2', 2962 'Up', '1.2', 2963 'Next', '1.2.4', 2964 'NodeUp', '1.2', 2965 'NodeNext', '1.2.4', 2966 'NodePrev', '1.2.2', 2967 'Following', '1.2.4', 2968 'Forward', '1.2.4', 2969 'FastForward', '2', 2970 'About', ' ', 2971 'First', '1.', 2972 'Last', '1.2.4', 2973 'NextFile', ' ', 2974 'PrevFile', ' ', 2975 ); 2976 2977sub T2H_DEFAULT_about_body 2978{ 2979 my $about = "<p>\n"; 2980 if (ref($PRE_ABOUT) eq 'CODE') 2981 { 2982 $about .= &$PRE_ABOUT(); 2983 } 2984 else 2985 { 2986 $about .= $PRE_ABOUT; 2987 } 2988 $about .= <<EOT; 2989</p> 2990<p> 2991EOT 2992 $about .= &$I(' The buttons in the navigation panels have the following meaning:') . "\n"; 2993 $about .= <<EOT; 2994</p> 2995<table border="1"> 2996 <tr> 2997EOT 2998 $about .= ' <th> ' . &$I('Button') . " </th>\n" . 2999' <th> ' . &$I('Name') . " </th>\n" . 3000' <th> ' . &$I('Go to') . " </th>\n" . 3001' <th> ' . &$I('From 1.2.3 go to') . "</th>\n" . " </tr>\n"; 3002 3003 for my $button (@SECTION_BUTTONS) 3004 { 3005 next if $button eq ' ' || ref($button) eq 'CODE' || ref($button) eq 'SCALAR' || ref($button) eq 'ARRAY'; 3006 $about .= " <tr>\n <td align=\"center\">"; 3007 $about .= 3008 ($ICONS && $ACTIVE_ICONS{$button} ? 3009 &$button_icon_img($BUTTONS_NAME{$button}, $ACTIVE_ICONS{$button}) : 3010 ' [' . $NAVIGATION_TEXT{$button} . '] '); 3011 $about .= "</td>\n"; 3012 $about .= <<EOT; 3013 <td align="center">$BUTTONS_NAME{$button}</td> 3014 <td>$BUTTONS_GOTO{$button}</td> 3015 <td>$BUTTONS_EXAMPLE{$button}</td> 3016 </tr> 3017EOT 3018 } 3019 3020 $about .= <<EOT; 3021</table> 3022 3023<p> 3024EOT 3025 $about .= &$I(' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:') . "\n"; 3026 3027# where the <strong> Example </strong> assumes that the current position 3028# is at <strong> Subsubsection One-Two-Three </strong> of a document of 3029# the following structure: 3030 $about .= <<EOT; 3031</p> 3032 3033<ul> 3034EOT 3035 $about .= ' <li> 1. ' . &$I('Section One') . "\n" . 3036" <ul>\n" . 3037' <li>1.1 ' . &$I('Subsection One-One') . "\n"; 3038 $about .= <<EOT; 3039 <ul> 3040 <li>...</li> 3041 </ul> 3042 </li> 3043EOT 3044 $about .= ' <li>1.2 ' . &$I('Subsection One-Two') . "\n" . 3045" <ul>\n" . 3046' <li>1.2.1 ' . &$I('Subsubsection One-Two-One') . "</li>\n" . 3047' <li>1.2.2 ' . &$I('Subsubsection One-Two-Two') . "</li>\n" . 3048' <li>1.2.3 ' . &$I('Subsubsection One-Two-Three') . " \n" 3049. 3050' <strong><== ' . &$I('Current Position') . " </strong></li>\n" . 3051' <li>1.2.4 ' . &$I('Subsubsection One-Two-Four') . "</li>\n" . 3052" </ul>\n" . 3053" </li>\n" . 3054' <li>1.3 ' . &$I('Subsection One-Three') . "\n"; 3055 $about .= <<EOT; 3056 <ul> 3057 <li>...</li> 3058 </ul> 3059 </li> 3060EOT 3061 $about .= ' <li>1.4 ' . &$I('Subsection One-Four') . "</li>\n"; 3062 $about .= <<EOT; 3063 </ul> 3064 </li> 3065</ul> 3066$AFTER_ABOUT 3067EOT 3068 return $about; 3069} 3070 3071# return value is currently ignored 3072sub T2H_DEFAULT_titlepage($$$$) 3073{ 3074 my $titlepage_lines = shift; 3075 my $titlepage_text = shift; 3076 my $titlepage_no_texi = shift; 3077 my $titlepage_simple_format = shift; 3078 3079 my $result = ''; 3080 my $title = ''; 3081 $title = $Texi2HTML::THISDOC{'title'} if (defined($Texi2HTML::THISDOC{'title'}) and $Texi2HTML::THISDOC{'title'} !~ /^\s*$/); 3082 if ($title ne '' 3083 or @{$Texi2HTML::THISDOC{'subtitles'}} 3084 or @{$Texi2HTML::THISDOC{'authors'}}) 3085 { 3086 $result = "<div align=\"center\">\n"; 3087 if ($title ne '') 3088 { 3089 $result .= '<h1>' . $title . "</h1>\n"; 3090 } 3091 foreach my $subtitle (@{$Texi2HTML::THISDOC{'subtitles'}}) 3092 { 3093 $result .= '<h2>' . $subtitle . "</h2>\n"; 3094 } 3095 foreach my $author (@{$Texi2HTML::THISDOC{'authors'}}) 3096 { 3097 $result .= '<strong> ' . $author . " </strong><br>\n"; 3098 } 3099 $result .= "</div>\n$DEFAULT_RULE\n"; 3100 } 3101 3102 $Texi2HTML::TITLEPAGE = $titlepage_text; 3103 3104 $Texi2HTML::TITLEPAGE = $result . $Texi2HTML::TITLEPAGE; 3105 3106 if ($Texi2HTML::THISDOC{'setcontentsaftertitlepage'} and (defined($Texi2HTML::THISDOC{'inline_contents'}->{'contents'})) and @{$Texi2HTML::THISDOC{'inline_contents'}->{'contents'}}) 3107 { 3108 foreach my $line(@{$Texi2HTML::THISDOC{'inline_contents'}->{'contents'}}) 3109 { 3110 $Texi2HTML::TITLEPAGE .= $line; 3111 } 3112 $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n"; 3113 } 3114 if ($Texi2HTML::THISDOC{'setshortcontentsaftertitlepage'} and (defined($Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'})) and @{$Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'}}) 3115 { 3116 foreach my $line(@{$Texi2HTML::THISDOC{'inline_contents'}->{'shortcontents'}}) 3117 { 3118 $Texi2HTML::TITLEPAGE .= $line; 3119 } 3120 $Texi2HTML::TITLEPAGE .= "$DEFAULT_RULE\n"; 3121 } 3122 return $Texi2HTML::TITLEPAGE; 3123} 3124 3125# FIXME Honor DOCUMENT_DESCRIPTION? 3126sub T2H_DEFAULT_print_redirection_page($) 3127{ 3128 my $fh = shift; 3129 my $longtitle = "$Texi2HTML::THISDOC{'fulltitle_simple_format'}"; 3130 $longtitle .= ": $Texi2HTML::SIMPLE_TEXT{'This'}" if exists $Texi2HTML::SIMPLE_TEXT{'This'}; 3131 my $description = $longtitle; 3132 my $encoding = ''; 3133 $encoding = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$Texi2HTML::THISDOC{'ENCODING_NAME'}\">" if (defined($Texi2HTML::THISDOC{'ENCODING_NAME'}) and ($Texi2HTML::THISDOC{'ENCODING_NAME'} ne '')); 3134 my $href = &$anchor('', $Texi2HTML::HREF{'This'}, $Texi2HTML::NAME{'This'}); 3135 my $string = &$I('The node you are looking for is at %{href}.', 3136 { 'href' => $href }); 3137 print $fh <<EOT; 3138$DOCTYPE 3139<html> 3140<!-- Created on $Texi2HTML::THISDOC{'today'} by $Texi2HTML::THISDOC{'program'} --> 3141<!-- 3142$Texi2HTML::THISDOC{'program_authors'} 3143--> 3144<head> 3145<title>$longtitle</title> 3146 3147<meta name="description" content="$description"> 3148<meta name="keywords" content="$longtitle"> 3149<meta name="resource-type" content="document"> 3150<meta name="distribution" content="global"> 3151<meta name="Generator" content="$Texi2HTML::THISDOC{program}"> 3152$encoding 3153$Texi2HTML::THISDOC{'CSS_LINES'} 3154<meta http-equiv="Refresh" content="2; url=$Texi2HTML::HREF{'This'}"> 3155$EXTRA_HEAD 3156</head> 3157 3158<body $Texi2HTML::THISDOC{'BODYTEXT'}> 3159$AFTER_BODY_OPEN 3160<p>$string</p> 3161</body> 3162EOT 3163} 3164 3165sub T2H_DEFAULT_node_file_name($$) 3166{ 3167 my $node = shift; 3168 my $type = shift; 3169 return undef if ($node->{'external_node'} 3170 or ($type eq 'top' and !$NEW_CROSSREF_STYLE)); 3171 my $node_file_base; 3172 if ($type eq 'top' and defined($TOP_NODE_FILE)) 3173 { 3174 $node_file_base = $TOP_NODE_FILE; 3175 } 3176 elsif ($NEW_CROSSREF_STYLE) 3177 { 3178 if ($TRANSLITERATE_NODE) 3179 { 3180 $node_file_base = $node->{'cross_manual_file'}; 3181 } 3182 else 3183 { 3184 $node_file_base = $node->{'cross_manual_target'}; 3185 } 3186 } 3187 else 3188 { 3189 $node_file_base = main::remove_texi($node->{'texi'}); 3190 $node_file_base =~ s/[^\w\.\-]/-/g; 3191 } 3192 if (defined($NODE_FILE_EXTENSION) and $NODE_FILE_EXTENSION ne '') 3193 { 3194 return ($node_file_base . ".$NODE_FILE_EXTENSION"); 3195 } 3196 return $node_file_base; 3197} 3198 3199######################################################################## 3200# Control of formatting: 3201# 1.) For some changes, it is often enough to change the value of 3202# some global map. It might necessitate building a little 3203# function along with the change in hash, if the change is the use 3204# of another function (in style_map). 3205# 2.) For other changes, reimplement one of the t2h_default_<fnc>* routines, 3206# give them another name, and assign them to the respective 3207# $<fnc> variable (below). 3208 3209 3210# 3211# This hash should have keys corresponding with the nonletter command accent 3212# whose following character is considered to be the argument 3213# This hash associates an accent macro to the ISO name for the accent if any. 3214# The customary use of this map is to find the ISO name appearing in html 3215# entity (like é) associated with a texinfo accent macro. 3216# 3217# The keys of the hash are 3218# ": umlaut 3219# ~: tilda accent 3220# ^: circumflex accent 3221# `: grave accent 3222# ': acute accent 3223# =: macron accent 3224%accent_map = ( 3225 '"', 'uml', 3226 '~', 'tilde', 3227 '^', 'circ', 3228 '`', 'grave', 3229 "'", 'acute', 3230 ",", 'cedil', 3231 '=', '', 3232 'ringaccent', 'ring', 3233 'H', '', 3234 'dotaccent', '', 3235 'u', '', 3236 'ubaraccent', '', 3237 'udotaccent', '', 3238 'v', '', 3239 'ogonek', 'ogon', 3240 ); 3241 3242# 3243# texinfo "simple things" (@foo) to HTML ones 3244# 3245%simple_map = ( 3246 '*', "<br>", # HTML+ 3247 ' ', ' ', 3248 "\t", ' ', 3249 "\n", ' ', 3250 # "­" or "­" could also be possible for @-, but it seems 3251 # that some browser will consider this as an always visible hyphen mark 3252 # which is not what we want (see http://www.cs.tut.fi/~jkorpela/shy.html) 3253 '-', '', # hyphenation hint 3254 '|', '', # used in formatting commands @evenfooting and friends 3255 '/', '', 3256 # spacing commands 3257 ':', '', 3258 '!', '!', 3259 '?', '?', 3260 '.', '.', 3261 '@', '@', 3262 '}', '}', 3263 '{', '{', 3264 ); 3265 3266# this map is used in preformatted text 3267%simple_map_pre = %simple_map; 3268$simple_map_pre{'*'} = "\n"; 3269 3270# maps for the math specific commands 3271%simple_map_math = ( 3272 '\\', '\\' 3273 ); 3274 3275%simple_map_pre_math = %simple_map_math; 3276%simple_map_texi_math = %simple_map_math; 3277 3278%colon_command_punctuation_characters = ( 3279 '.' => '.', 3280 ':' => ':', 3281 '?' => '?', 3282 '!' => '!' 3283); 3284 3285# 3286# texinfo "things" (@foo{}) to HTML ones 3287# 3288%things_map = ( 3289 'TeX' => 'TeX', 3290 'LaTeX' => 'LaTeX', 3291# pertusus: unknown by makeinfo, not in texinfo manual (@* is the right thing) 3292# 'br', '<br>', # paragraph break 3293 'bullet' => '*', 3294# #'copyright' => '(C)', 3295 'copyright' => '©', 3296 'registeredsymbol' => '®', 3297 'dots' => '<small class="dots">...</small>', 3298 'enddots' => '<small class="enddots">...</small>', 3299 'equiv' => '==', 3300# FIXME i18n 3301 'error' => 'error-->', 3302 'expansion' => '==>', 3303 'arrow' => '->', 3304 'minus' => '-', 3305 'point' => '-!-', 3306 'print' => '-|', 3307 'result' => '=>', 3308 # set in code using the language 3309 # 'today', &pretty_date, 3310 'today' => '', 3311 'aa' => 'å', 3312 'AA' => 'Å', 3313 'ae' => 'æ', 3314 'oe' => 'œ', #pertusus: also œ. œ not in html 3.2 3315 'AE' => 'Æ', 3316 'OE' => 'Œ', #pertusus: also Œ. Œ not in html 3.2 3317 'o' => 'ø', 3318 'O' => 'Ø', 3319 'ss' => 'ß', 3320 'l' => 'ł', 3321 'L' => 'Ł', 3322 'exclamdown' => '¡', 3323 'questiondown' => '¿', 3324 'pounds' => '£', 3325 'ordf' => 'ª', 3326 'ordm' => 'º', 3327 'comma' => ',', 3328 'euro' => '€', 3329 'geq' => '≥', 3330 'leq' => '≤', 3331 'tie' => ' ', 3332 'textdegree' => '°', 3333 'quotedblleft' => '“', 3334 'quotedblright' => '”', 3335 'quoteleft' => '‘', 3336 'quoteright' => '’', 3337 'quotedblbase' => '„', 3338 'quotesinglbase' => '‚', 3339 'guillemetleft' => '«', 3340 'guillemetright' => '»', 3341 'guillemotleft' => '«', 3342 'guillemotright' => '»', 3343 'guilsinglleft' => '‹', 3344 'guilsinglright' => '›', 3345 ); 3346 3347# This map is used in preformatted environments 3348%pre_map = %things_map; 3349$pre_map{'dots'} = '...'; 3350$pre_map{'enddots'} = '...'; 3351#$pre_map{'br'} = "\n"; 3352 3353%ascii_things_map = ( 3354 'TeX' => 'TeX', 3355 'LaTeX' => 'LaTeX', 3356 'bullet' => '*', 3357 'copyright' => '(C)', 3358 'registeredsymbol' => '(R)', 3359 'dots' => '...', 3360 'enddots' => '...', 3361 'equiv' => '==', 3362# FIXME i18n 3363 'error' => 'error-->', 3364 'expansion' => '==>', 3365 'arrow' => '->', 3366 'minus' => '-', 3367 'point' => '-!-', 3368 'print' => '-|', 3369 'result' => '=>', 3370 'today' => '', 3371 'aa' => 'aa', 3372 'AA' => 'AA', 3373 'ae' => 'ae', 3374 'oe' => 'oe', 3375 'AE' => 'AE', 3376 'OE' => 'OE', 3377 'o' => '/o', 3378 'O' => '/O', 3379 'ss' => 'ss', 3380 'l' => '/l', 3381 'L' => '/L', 3382 'exclamdown' => '?', 3383 'questiondown' => '!', 3384 'pounds' => '#', 3385 'ordf' => 'a', 3386 'ordm' => 'o', 3387 'comma' => ',', 3388 'euro' => 'Euro', 3389 'geq' => '>=', 3390 'leq' => '<=', 3391 'tie' => ' ', 3392 'textdegree' => 'o', 3393 'quotedblleft' => '``', 3394 'quotedblright' => "''", 3395 'quoteleft' => '`', 3396 'quoteright' => "'", 3397 'quotedblbase' => ',,', 3398 'quotesinglbase' => ',', 3399 'guillemetleft' => '<<', 3400 'guillemetright' => '>>', 3401 'guillemotleft' => '<<', 3402 'guillemotright' => '>>', 3403 'guilsinglleft' => '<', 3404 'guilsinglright' => '>', 3405); 3406 3407# ascii representation of @-commands 3408%ascii_simple_map = ( 3409 '*', "\n", 3410 ' ', ' ', 3411 "\t", ' ', 3412 "\n", ' ', 3413 '-', '', # hyphenation hint 3414 '|', '', # used in formatting commands @evenfooting and friends 3415 '/', '', 3416 ':', '', 3417 '!', '!', 3418 '?', '?', 3419 '.', '.', 3420 '@', '@', 3421 '}', '}', 3422 '{', '{', 3423); 3424 3425# 3426# This map is used when texi elements are removed and replaced 3427# by simple text 3428# 3429%simple_map_texi = %ascii_simple_map; 3430 3431 3432# text replacing macros when texi commands are removed and plain text is 3433# produced 3434%texi_map = ( 3435 'TeX', 'TeX', 3436 'LaTeX', 'LaTeX', 3437 'bullet', '*', 3438 'copyright', 'C', 3439 'registeredsymbol', 'R', 3440 'dots', '...', 3441 'enddots', '...', 3442 'equiv', '==', 3443 'error', 'error-->', 3444 'expansion', '==>', 3445 'arrow', '->', 3446 'minus', '-', 3447 'point', '-!-', 3448 'print', '-|', 3449 'result', '=>', 3450 'today' => '', 3451 'aa', 'aa', 3452 'AA', 'AA', 3453 'ae', 'ae', 3454 'oe', 'oe', 3455 'AE', 'AE', 3456 'OE', 'OE', 3457 'o', 'o', 3458 'O', 'O', 3459 'ss', 'ss', 3460 'l', 'l', 3461 'L', 'L', 3462 'exclamdown', '! upside-down', 3463 #'exclamdown', '¡', 3464 'questiondown', '? upside-down', 3465 #'questiondown', '¿', 3466 'pounds', 'pound sterling', 3467 #'pounds', '£' 3468 'ordf' => 'a', 3469 'ordm' => 'o', 3470 'comma' => ',', 3471 'euro' => 'Euro', 3472 'geq' => '>=', 3473 'leq' => '<=', 3474 'tie' => ' ', 3475 'textdegree' => 'o', 3476 'quotedblleft' => '``', 3477 'quotedblright' => "''", 3478 'quoteleft' => '`', 3479 'quoteright' => "'", 3480 'quotedblbase' => ',,', 3481 'quotesinglbase' => ',', 3482 'guillemetleft' => '<<', 3483 'guillemetright' => '>>', 3484 'guillemotleft' => '<<', 3485 'guillemotright' => '>>', 3486 'guilsinglleft' => '<', 3487 'guilsinglright' => '>', 3488 ); 3489 3490# taken from 3491#Latin extended additionnal 3492#http://www.alanwood.net/unicode/latin_extended_additional.html 3493#C1 Controls and Latin-1 Supplement 3494#http://www.alanwood.net/unicode/latin_1_supplement.html 3495#Latin Extended-A 3496#http://www.alanwood.net/unicode/latin_extended_a.html 3497#Latin Extended-B 3498#http://www.alanwood.net/unicode/latin_extended_b.html 3499#dotless i: 0131 3500 3501#http://www.alanwood.net/unicode/arrows.html 21** 3502#http://www.alanwood.net/unicode/general_punctuation.html 20** 3503#http://www.alanwood.net/unicode/mathematical_operators.html 22** 3504 3505%unicode_map = ( 3506 'bullet' => '2022', 3507 'copyright' => '00A9', 3508 'registeredsymbol' => '00AE', 3509 'dots' => '2026', 3510 'enddots' => '', 3511 'equiv' => '2261', 3512 'error' => '', 3513 'expansion' => '2192', 3514 'arrow' => '2192', 3515 'minus' => '2212', # in mathematical operators 3516# 'minus' => '002D', # in latin1 3517 'point' => '2605', 3518 'print' => '22A3', 3519 'result' => '21D2', 3520 'today' => '', 3521 'aa' => '00E5', 3522 'AA' => '00C5', 3523 'ae' => '00E6', 3524 'oe' => '0153', 3525 'AE' => '00C6', 3526 'OE' => '0152', 3527 'o' => '00F8', 3528 'O' => '00D8', 3529 'ss' => '00DF', 3530 'l' => '0142', 3531 'L' => '0141', 3532 'exclamdown' => '00A1', 3533 'questiondown' => '00BF', 3534 'pounds' => '00A3', 3535 'ordf' => '00AA', 3536 'ordm' => '00BA', 3537 'comma' => '002C', 3538 'euro' => '20AC', 3539 'geq' => '2265', 3540 'leq' => '2264', 3541 'tie' => '', 3542# 'tie' => '0020', 3543 'textdegree' => '00B0', 3544 'quotedblleft' => '201C', 3545 'quotedblright' => '201D', 3546 'quoteleft' => '2018', 3547 'quoteright' => '2019', 3548 'quotedblbase' => '201E', 3549 'quotesinglbase' => '201A', 3550 'guillemetleft' => '00AB', 3551 'guillemetright' => '00BB', 3552 'guillemotleft' => '00AB', 3553 'guillemotright' => '00BB', 3554 'guilsinglleft' => '2039', 3555 'guilsinglright' => '203A', 3556 ); 3557 3558%makeinfo_encoding_to_map = ( 3559 "iso-8859-1", 'iso8859_1', 3560 "iso-8859-2", 'iso8859_2', 3561 "iso-8859-15", 'iso8859_15', 3562 "koi8-r", 'koi8', 3563 "koi8-u", 'koi8', 3564); 3565 3566foreach my $encoding (keys(%makeinfo_encoding_to_map)) 3567{ 3568 $t2h_encoding_aliases{$encoding} = $encoding; 3569 $t2h_encoding_aliases{$makeinfo_encoding_to_map{$encoding}} = $encoding; 3570} 3571 3572# cut and pasted from eigth_bit_makeinfo_maps.pl, in turn generated with 3573# ./parse_8bit_makeinfo_maps.pl 3574 3575%makeinfo_unicode_to_eight_bit = ( 3576 'iso8859_1' => { 3577 '00A0' => 'A0', 3578 '00A1' => 'A1', 3579 '00A2' => 'A2', 3580 '00A3' => 'A3', 3581 '00A4' => 'A4', 3582 '00A5' => 'A5', 3583 '00A6' => 'A6', 3584 '00A7' => 'A7', 3585 '00A8' => 'A8', 3586 '00A9' => 'A9', 3587 '00AA' => 'AA', 3588 '00AB' => 'AB', 3589 '00AC' => 'AC', 3590 '00AD' => 'AD', 3591 '00AE' => 'AE', 3592 '00AF' => 'AF', 3593 '00B0' => 'B0', 3594 '00B1' => 'B1', 3595 '00B2' => 'B2', 3596 '00B3' => 'B3', 3597 '00B4' => 'B4', 3598 '00B5' => 'B5', 3599 '00B6' => 'B6', 3600 '00B7' => 'B7', 3601 '00B8' => 'B8', 3602 '00B9' => 'B9', 3603 '00BA' => 'BA', 3604 '00BB' => 'BB', 3605 '00BC' => 'BC', 3606 '00BD' => 'BD', 3607 '00BE' => 'BE', 3608 '00BF' => 'BF', 3609 '00C0' => 'C0', 3610 '00C1' => 'C1', 3611 '00C2' => 'C2', 3612 '00C3' => 'C3', 3613 '00C4' => 'C4', 3614 '00C5' => 'C5', 3615 '00C6' => 'C6', 3616 '00C7' => 'C7', 3617 '00C7' => 'C7', 3618 '00C8' => 'C8', 3619 '00C9' => 'C9', 3620 '00CA' => 'CA', 3621 '00CB' => 'CB', 3622 '00CC' => 'CC', 3623 '00CD' => 'CD', 3624 '00CE' => 'CE', 3625 '00CF' => 'CF', 3626 '00D0' => 'D0', 3627 '00D1' => 'D1', 3628 '00D2' => 'D2', 3629 '00D3' => 'D3', 3630 '00D4' => 'D4', 3631 '00D5' => 'D5', 3632 '00D6' => 'D6', 3633 '00D7' => 'D7', 3634 '00D8' => 'D8', 3635 '00D9' => 'D9', 3636 '00DA' => 'DA', 3637 '00DB' => 'DB', 3638 '00DC' => 'DC', 3639 '00DD' => 'DD', 3640 '00DE' => 'DE', 3641 '00DF' => 'DF', 3642 '00E0' => 'E0', 3643 '00E1' => 'E1', 3644 '00E2' => 'E2', 3645 '00E3' => 'E3', 3646 '00E4' => 'E4', 3647 '00E5' => 'E5', 3648 '00E6' => 'E6', 3649 '00E7' => 'E7', 3650 '00E8' => 'E8', 3651 '00E9' => 'E9', 3652 '00EA' => 'EA', 3653 '00EB' => 'EB', 3654 '00EC' => 'EC', 3655 '00ED' => 'ED', 3656 '00EE' => 'EE', 3657 '00EF' => 'EF', 3658 '00F0' => 'F0', 3659 '00F1' => 'F1', 3660 '00F2' => 'F2', 3661 '00F3' => 'F3', 3662 '00F4' => 'F4', 3663 '00F5' => 'F5', 3664 '00F6' => 'F6', 3665 '00F7' => 'F7', 3666 '00F8' => 'F8', 3667 '00F9' => 'F9', 3668 '00FA' => 'FA', 3669 '00FB' => 'FB', 3670 '00FC' => 'FC', 3671 '00FD' => 'FD', 3672 '00FE' => 'FE', 3673 '00FF' => 'FF', 3674 }, 3675 'iso8859_15' => { 3676 '00A0' => 'A0', 3677 '00A1' => 'A1', 3678 '00A2' => 'A2', 3679 '00A3' => 'A3', 3680 '20AC' => 'A4', 3681 '00A5' => 'A5', 3682 '0160' => 'A6', 3683 '00A7' => 'A7', 3684 '0161' => 'A8', 3685 '00A9' => 'A9', 3686 '00AA' => 'AA', 3687 '00AB' => 'AB', 3688 '00AC' => 'AC', 3689 '00AD' => 'AD', 3690 '00AE' => 'AE', 3691 '00AF' => 'AF', 3692 '00B0' => 'B0', 3693 '00B1' => 'B1', 3694 '00B2' => 'B2', 3695 '00B3' => 'B3', 3696 '017D' => 'B4', 3697 '00B5' => 'B5', 3698 '00B6' => 'B6', 3699 '00B7' => 'B7', 3700 '017E' => 'B8', 3701 '00B9' => 'B9', 3702 '00BA' => 'BA', 3703 '00BB' => 'BB', 3704 '0152' => 'BC', 3705 '0153' => 'BD', 3706 '0178' => 'BE', 3707 '00BF' => 'BF', 3708 '00C0' => 'C0', 3709 '00C1' => 'C1', 3710 '00C2' => 'C2', 3711 '00C3' => 'C3', 3712 '00C4' => 'C4', 3713 '00C5' => 'C5', 3714 '00C6' => 'C6', 3715 '00C7' => 'C7', 3716 '00C8' => 'C8', 3717 '00C9' => 'C9', 3718 '00CA' => 'CA', 3719 '00CB' => 'CB', 3720 '00CC' => 'CC', 3721 '00CD' => 'CD', 3722 '00CE' => 'CE', 3723 '00CF' => 'CF', 3724 '00D0' => 'D0', 3725 '00D1' => 'D1', 3726 '00D2' => 'D2', 3727 '00D3' => 'D3', 3728 '00D4' => 'D4', 3729 '00D5' => 'D5', 3730 '00D6' => 'D6', 3731 '00D7' => 'D7', 3732 '00D8' => 'D8', 3733 '00D9' => 'D9', 3734 '00DA' => 'DA', 3735 '00DB' => 'DB', 3736 '00DC' => 'DC', 3737 '00DD' => 'DD', 3738 '00DE' => 'DE', 3739 '00DF' => 'DF', 3740 '00E0' => 'E0', 3741 '00E1' => 'E1', 3742 '00E2' => 'E2', 3743 '00E3' => 'E3', 3744 '00E4' => 'E4', 3745 '00E5' => 'E5', 3746 '00E6' => 'E6', 3747 '00E7' => 'E7', 3748 '00E8' => 'E8', 3749 '00E9' => 'E9', 3750 '00EA' => 'EA', 3751 '00EB' => 'EB', 3752 '00EC' => 'EC', 3753 '00ED' => 'ED', 3754 '00EE' => 'EE', 3755 '00EF' => 'EF', 3756 '00F0' => 'F0', 3757 '00F1' => 'F1', 3758 '00F2' => 'F2', 3759 '00F3' => 'F3', 3760 '00F4' => 'F4', 3761 '00F5' => 'F5', 3762 '00F6' => 'F6', 3763 '00F7' => 'F7', 3764 '00F8' => 'F8', 3765 '00F9' => 'F9', 3766 '00FA' => 'FA', 3767 '00FB' => 'FB', 3768 '00FC' => 'FC', 3769 '00FD' => 'FD', 3770 '00FE' => 'FE', 3771 '00FF' => 'FF', 3772 }, 3773 'iso8859_2' => { 3774 '00A0' => 'A0', 3775 '0104' => 'A1', 3776 '02D8' => 'A2', 3777 '0141' => 'A3', 3778 '00A4' => 'A4', 3779 '013D' => 'A5', 3780 '015A' => 'A6', 3781 '00A7' => 'A7', 3782 '00A8' => 'A8', 3783 '015E' => 'AA', 3784 '0164' => 'AB', 3785 '0179' => 'AC', 3786 '00AD' => 'AD', 3787 '017D' => 'AE', 3788 '017B' => 'AF', 3789 '00B0' => 'B0', 3790 '0105' => 'B1', 3791 '02DB' => 'B2', 3792 '0142' => 'B3', 3793 '00B4' => 'B4', 3794 '013E' => 'B5', 3795 '015B' => 'B6', 3796 '02C7' => 'B7', 3797 '00B8' => 'B8', 3798 '0161' => 'B9', 3799 '015F' => 'BA', 3800 '0165' => 'BB', 3801 '017A' => 'BC', 3802 '02DD' => 'BD', 3803 '017E' => 'BE', 3804 '017C' => 'BF', 3805 '0154' => 'C0', 3806 '00C1' => 'C1', 3807 '00C2' => 'C2', 3808 '0102' => 'C3', 3809 '00C4' => 'C4', 3810 '0139' => 'C5', 3811 '0106' => 'C6', 3812 '00C7' => 'C7', 3813 '010C' => 'C8', 3814 '00C9' => 'C9', 3815 '0118' => 'CA', 3816 '00CB' => 'CB', 3817 '011A' => 'CC', 3818 '00CD' => 'CD', 3819 '00CE' => 'CE', 3820 '010E' => 'CF', 3821 '0110' => 'D0', 3822 '0143' => 'D1', 3823 '0147' => 'D2', 3824 '00D3' => 'D3', 3825 '00D4' => 'D4', 3826 '0150' => 'D5', 3827 '00D6' => 'D6', 3828 '00D7' => 'D7', 3829 '0158' => 'D8', 3830 '016E' => 'D9', 3831 '00DA' => 'DA', 3832 '0170' => 'DB', 3833 '00DC' => 'DC', 3834 '00DD' => 'DD', 3835 '0162' => 'DE', 3836 '00DF' => 'DF', 3837 '0155' => 'E0', 3838 '00E1' => 'E1', 3839 '00E2' => 'E2', 3840 '0103' => 'E3', 3841 '00E4' => 'E4', 3842 '013A' => 'E5', 3843 '0107' => 'E6', 3844 '00E7' => 'E7', 3845 '010D' => 'E8', 3846 '00E9' => 'E9', 3847 '0119' => 'EA', 3848 '00EB' => 'EB', 3849 '011B' => 'EC', 3850 '00ED' => 'ED', 3851 '00EE' => 'EE', 3852 '010F' => 'EF', 3853 '0111' => 'F0', 3854 '0144' => 'F1', 3855 '0148' => 'F2', 3856 '00F3' => 'F3', 3857 '00F4' => 'F4', 3858 '0151' => 'F5', 3859 '00F6' => 'F6', 3860 '00F7' => 'F7', 3861 '0159' => 'F8', 3862 '016F' => 'F9', 3863 '00FA' => 'FA', 3864 '0171' => 'FB', 3865 '00FC' => 'FC', 3866 '00FD' => 'FD', 3867 '0163' => 'FE', 3868 '02D9' => 'FF', 3869 }, 3870 'koi8' => { 3871 '0415' => 'A3', 3872 '0454' => 'A4', 3873 '0456' => 'A6', 3874 '0457' => 'A7', 3875 '04D7' => 'B3', 3876 '0404' => 'B4', 3877 '0406' => 'B6', 3878 '0407' => 'B7', 3879 '042E' => 'C0', 3880 '0430' => 'C1', 3881 '0431' => 'C2', 3882 '0446' => 'C3', 3883 '0434' => 'C4', 3884 '0435' => 'C5', 3885 '0444' => 'C6', 3886 '0433' => 'C7', 3887 '0445' => 'C8', 3888 '0438' => 'C9', 3889 '0439' => 'CA', 3890 '043A' => 'CB', 3891 '043B' => 'CC', 3892 '043C' => 'CD', 3893 '043D' => 'CE', 3894 '043E' => 'CF', 3895 '043F' => 'D0', 3896 '044F' => 'D1', 3897 '0440' => 'D2', 3898 '0441' => 'D3', 3899 '0442' => 'D4', 3900 '0443' => 'D5', 3901 '0436' => 'D6', 3902 '0432' => 'D7', 3903 '044C' => 'D8', 3904 '044B' => 'D9', 3905 '0437' => 'DA', 3906 '0448' => 'DB', 3907 '044D' => 'DC', 3908 '0449' => 'DD', 3909 '0447' => 'DE', 3910 '044A' => 'DF', 3911 '042D' => 'E0', 3912 '0410' => 'E1', 3913 '0411' => 'E2', 3914 '0426' => 'E3', 3915 '0414' => 'E4', 3916 '0415' => 'E5', 3917 '0424' => 'E6', 3918 '0413' => 'E7', 3919 '0425' => 'E8', 3920 '0418' => 'E9', 3921 '0419' => 'EA', 3922 '041A' => 'EB', 3923 '041B' => 'EC', 3924 '041C' => 'ED', 3925 '041D' => 'EE', 3926 '041E' => 'EF', 3927 '041F' => 'F0', 3928 '042F' => 'F1', 3929 '0420' => 'F2', 3930 '0421' => 'F3', 3931 '0422' => 'F4', 3932 '0423' => 'F5', 3933 '0416' => 'F6', 3934 '0412' => 'F7', 3935 '042C' => 'F8', 3936 '042B' => 'F9', 3937 '0417' => 'FA', 3938 '0428' => 'FB', 3939 '042D' => 'FC', 3940 '0429' => 'FD', 3941 '0427' => 'FE', 3942 '042A' => 'FF', 3943 }, 3944); 3945 3946%eight_bit_to_unicode = (); 3947foreach my $encoding (keys(%makeinfo_encoding_to_map)) 3948{ 3949 my $unicode_to_eight = $makeinfo_unicode_to_eight_bit{$makeinfo_encoding_to_map{$encoding}}; 3950#print STDERR "$encoding, $makeinfo_encoding_to_map{$encoding}, $unicode_to_eight\n"; 3951 foreach my $utf8_key (keys(%{$unicode_to_eight})) 3952 { 3953 $eight_bit_to_unicode{$encoding}->{$unicode_to_eight->{$utf8_key}} = 3954 $utf8_key; 3955 } 3956} 3957 3958my %makeinfo_transliterate_map = ( 3959 '0416' => 'ZH', 3960 '0447' => 'ch', 3961 '00EB' => 'e', 3962 '0414' => 'D', 3963 '0159' => 'r', 3964 '00E6' => 'ae', 3965 '042B' => 'Y', 3966 '00FA' => 'u', 3967 '043B' => 'l', 3968 '00DE' => 'TH', 3969 '00D9' => 'U', 3970 '00C4' => 'A', 3971 '0148' => 'n', 3972 '00F6' => 'o', 3973 '0434' => 'd', 3974 '041E' => 'O', 3975 '041B' => 'L', 3976 '044B' => 'y', 3977 '0107' => 'c', 3978 '0415' => 'E', 3979 '00C1' => 'A', 3980 '00D3' => 'O', 3981 '00DB' => 'U', 3982 '016E' => 'U', 3983 '013A' => 'l', 3984 '017B' => 'Z', 3985 '00F1' => 'n', 3986 '0428' => 'SH', 3987 '0153' => 'oe', 3988 '00F4' => 'o', 3989 '0144' => 'n', 3990 '0404' => 'IE', 3991 '0427' => 'CH', 3992 '0162' => 'T', 3993 '017A' => 'z', 3994 '0448' => 'sh', 3995 '0436' => 'zh', 3996 '00F9' => 'u', 3997 '0406' => 'I', 3998 '0103' => 'a', 3999 '0422' => 'T', 4000 '0160' => 'S', 4001 '0165' => 't', 4002 '017E' => 'z', 4003 '00F0' => 'd', 4004 '043E' => 'o', 4005 '043D' => 'n', 4006 '013E' => 'l', 4007 '0412' => 'V', 4008 '0111' => 'd', 4009 '0155' => 's', 4010 '017C' => 'z', 4011 '00CE' => 'I', 4012 '042D' => 'E', 4013 '00C8' => 'E', 4014 '00F8' => 'oe', 4015 '00F2' => 'o', 4016 '00FF' => 'y', 4017 '0420' => 'R', 4018 '0119' => 'e', 4019 '00D2' => 'O', 4020 '043C' => 'm', 4021 '00D0' => 'DH', 4022 '0179' => 'Z', 4023 '0110' => 'D', 4024 '043F' => 'p', 4025 '0170' => 'U', 4026 '011A' => 'E', 4027 '010C' => 'C', 4028 '015A' => 'S', 4029 '0433' => 'g', 4030 '00E1' => 'a', 4031 '010D' => 'c', 4032 '00CC' => 'I', 4033 '016F' => 'u', 4034 '0457' => 'yi', 4035 '00C2' => 'A', 4036 '0438' => 'i', 4037 '00E3' => 'a', 4038 '0435' => 'e', 4039 '0440' => 'r', 4040 '042A' => 'W', 4041 '0431' => 'b', 4042 '00EE' => 'i', 4043 '0150' => 'O', 4044 '00E8' => 'e', 4045 '0418' => 'I', 4046 '00CF' => 'I', 4047 '015F' => 's', 4048 '0142' => 'l', 4049 '0147' => 'N', 4050 '00DF' => 'ss', 4051 '00E5' => 'aa', 4052 '00C3' => 'A', 4053 '0106' => 'C', 4054 '0141' => 'L', 4055 '0164' => 'T', 4056 '017D' => 'Z', 4057 '00EC' => 'i', 4058 '041C' => 'M', 4059 '00C9' => 'E', 4060 '00E0' => 'a', 4061 '043A' => 'k', 4062 '00F5' => 'o', 4063 '042C' => 'X', 4064 '0449' => 'shch', 4065 '0444' => 'f', 4066 '0139' => 'L', 4067 '0158' => 'R', 4068 '00F3' => 'o', 4069 '00FB' => 'u', 4070 '0424' => 'F', 4071 '0446' => 'c', 4072 '0423' => 'U', 4073 '0442' => 't', 4074 '00FD' => 'y', 4075 '0102' => 'A', 4076 '0104' => 'A', 4077 '00CB' => 'E', 4078 '0426' => 'C', 4079 '00CD' => 'I', 4080 '0437' => 'z', 4081 '0178' => 'y', 4082 '00D4' => 'O', 4083 '044D' => 'e', 4084 '0432' => 'v', 4085 '013D' => 'L', 4086 '0163' => 't', 4087 '0456' => 'i', 4088 '011B' => 'e', 4089 '044F' => 'ya', 4090 '0429' => 'SHCH', 4091 '0411' => 'B', 4092 '044A' => 'w', 4093 '00C6' => 'AE', 4094 '041D' => 'N', 4095 '00DA' => 'U', 4096 '00C0' => 'A', 4097 '0152' => 'OE', 4098 '00DD' => 'Y', 4099 '0154' => 'R', 4100 '00E9' => 'e', 4101 '00D5' => 'O', 4102 '041F' => 'P', 4103 '0161' => 's', 4104 '0430' => 'a', 4105 '0445' => 'h', 4106 '00E2' => 'a', 4107 '00D6' => 'O', 4108 '0407' => 'YI', 4109 '00CA' => 'E', 4110 '0439' => 'i', 4111 '0171' => 'u', 4112 '00DC' => 'U', 4113 '042F' => 'YA', 4114 '0425' => 'H', 4115 '00FE' => 'th', 4116 '00D1' => 'N', 4117 '044C' => 'x', 4118 '010F' => 'd', 4119 '0410' => 'A', 4120 '0443' => 'u', 4121 '00EF' => 'i', 4122 '0105' => 'a', 4123 '00EA' => 'e', 4124 '00E4' => 'a', 4125 '015E' => 'S', 4126 '0417' => 'Z', 4127 '00ED' => 'i', 4128 '00FC' => 'u', 4129 '04D7' => 'IO', 4130 '00D8' => 'OE', 4131 '0419' => 'I', 4132 '0421' => 'S', 4133 '0143' => 'N', 4134 '010E' => 'D', 4135 '0413' => 'G', 4136 '015B' => 's', 4137 '0151' => 'o', 4138 '00E7' => 'c', 4139 '00C5' => 'AA', 4140 '0441' => 's', 4141 '0118' => 'E', 4142 '00C7' => 'C', 4143 '041A' => 'K', 4144 '0454' => 'ie', 4145 '042E' => 'yu', 4146); 4147 4148 4149%transliterate_map = ( 4150 '00C5' => 'AA', 4151 '00E5' => 'aa', 4152 '00D8' => 'OE', 4153 '00F8' => 'oe', 4154 '00E6' => 'ae', 4155 '0153' => 'oe', 4156 '00C6' => 'AE', 4157 '0152' => 'OE', 4158 '00DF' => 'ss', 4159 '0141' => 'L', 4160 '0142' => 'l', 4161 '00D0' => 'DH', 4162 '0415' => 'E', 4163 '0435' => 'e', 4164 '0426' => 'C', 4165 '042A' => 'W', 4166 '044A' => 'w', 4167 '042C' => 'X', 4168 '044C' => 'x', 4169 '042E' => 'yu', 4170 '042F' => 'YA', 4171 '044F' => 'ya', 4172 '0433' => 'g', 4173 '0446' => 'c', 4174 '04D7' => 'IO', 4175 '00DD' => 'Y', # unidecode gets this wrong ? 4176 ); 4177 4178foreach my $symbol(keys(%unicode_map)) 4179{ 4180 if ($unicode_map{$symbol} ne '' and !exists($transliterate_map{$symbol})) 4181 { 4182 $no_transliterate_map{$unicode_map{$symbol}} = 1; 4183 } 4184} 4185 4186%ascii_character_map = ( 4187 ' ' => '0020', 4188 '!' => '0021', 4189 '"' => '0022', 4190 '#' => '0023', 4191 '$' => '0024', 4192 '%' => '0025', 4193 '&' => '0026', 4194 "'" => '0027', 4195 '(' => '0028', 4196 ')' => '0029', 4197 '*' => '002A', 4198 '+' => '002B', 4199 ',' => '002C', 4200 '-' => '002D', 4201 '.' => '002E', 4202 '/' => '002F', 4203 ':' => '003A', 4204 ';' => '003B', 4205 '<' => '003C', 4206 '=' => '003D', 4207 '>' => '003E', 4208 '?' => '003F', 4209 '@' => '0040', 4210 '[' => '005B', 4211 '\\' => '005C', 4212 ']' => '005D', 4213 '^' => '005E', 4214 '_' => '005F', 4215 '`' => '0060', 4216 '{' => '007B', 4217 '|' => '007C', 4218 '}' => '007D', 4219 '~' => '007E', 4220); 4221 4222%perl_charset_to_html = ( 4223 'utf8' => 'utf-8', 4224 'utf-8-strict' => 'utf-8', 4225 'ascii' => 'us-ascii', 4226); 4227 4228%t2h_encoding_aliases = ( 4229 'latin1' => 'iso-8859-1', 4230); 4231 4232foreach my $perl_charset (keys(%perl_charset_to_html)) 4233{ 4234 $t2h_encoding_aliases{$perl_charset} = $perl_charset_to_html{$perl_charset}; 4235 $t2h_encoding_aliases{$perl_charset_to_html{$perl_charset}} = $perl_charset_to_html{$perl_charset}; 4236} 4237 4238# symbols used for the commands if $USE_ISO is true. 4239%iso_symbols = ( 4240 'equiv' => '≡', 4241 'dots' => '…', 4242 'bullet' => '•', 4243 'result' => '⇒', 4244 'expansion' => '→', 4245 'arrow' => '→', 4246 'point' => '∗', 4247 "'" => '’', 4248 '`' => '‘', 4249 ); 4250 4251%stop_paragraph_command = ( 4252 'titlefont' => 1, 4253 'insertcopying' => 1 4254); 4255 4256# on bug-texinfo verified that code_style shouldn't be used for anything 4257# else than node. 4258# anyway it doesn't make sense since the section name normally formatted 4259# is used 4260#%format_code_style = ( 4261# 'menu_name' => 1, 4262# 'menu_description' => 1 4263#); 4264 4265# not used currently for html, but used in chm.init 4266%numeric_entity_map = (); 4267 4268foreach my $symbol (keys(%unicode_map)) 4269{ 4270 if ($symbol ne '') 4271 { 4272 $numeric_entity_map{$symbol} = '&#' . hex($unicode_map{$symbol}) . ';'; 4273 } 4274} 4275 4276# When the value begins with & the function with that name is used to do the 4277# html. The first argument is the text enclosed within {}, the second is the 4278# style name (which is also the key of the hash) 4279# 4280# Otherwithe the value is the html element used to enclose the text, and if 4281# there is a " the resulting text is also enclosed within `' 4282my %old_style_map = ( 4283 'acronym', '', 4284 'asis', '', 4285 'b', 'b', 4286 'cite', 'cite', 4287 'clicksequence', '', 4288 'code', 'code', 4289 'command', 'code', 4290 'ctrl', '&default_ctrl', 4291 'dfn', 'em', 4292 'dmn', '', 4293 'email', '&default_email', 4294 'emph', 'em', 4295 'env', 'code', 4296 'file', '"tt', 4297 'i', 'i', 4298 'kbd', 'kbd', 4299 'key', 'kbd', 4300 'math', 'em', 4301 'option', '"samp', 4302 'r', '', 4303 'samp', '"samp', 4304 'sc', '&default_sc', 4305 'strong', 'strong', 4306 't', 'tt', 4307 'uref', '&default_uref', 4308 'url', '&default_url', 4309 'var', 'var', 4310 'verb', 'tt', 4311 'titlefont', '&default_titlefont', 4312 'w', '', 4313 ); 4314 4315# default is {'args' => ['normal'], 'attribute' => ''}, 4316%style_map = ( 4317 'asis', {}, 4318 'b', {'attribute' => 'b'}, 4319 'cite', {'attribute' => 'cite'}, 4320 'clicksequence', {}, 4321 'click', {'function' => \&t2h_default_click_normal}, 4322 'code', {'args' => ['code'], 'attribute' => 'code'}, 4323 'command', {'args' => ['code'], 'attribute' => 'code'}, 4324 'ctrl', {'function' => \&t2h_default_ctrl,'type' => 'simple_style'}, 4325 'dfn', {'attribute' => 'em'}, 4326 'dmn', {}, 4327 'email', {'args' => ['code', 'normal'], 4328 'function' => \&t2h_default_email, 4329 'type' => 'simple_style'}, 4330 #'email', {'args' => ['normal', 'normal'], 4331 # 'function' => \&t2h_default_email}, 4332 'emph', {'attribute' => 'em'}, 4333 'env', {'args' => ['code'], 'attribute' => 'code'}, 4334 'file', {'args' => ['code'], 'attribute' => 'tt', 'quote' => '"'}, 4335 'i', {'attribute' => 'i'}, 4336 'slanted', {'attribute' => 'i'}, 4337 'sansserif', {'attribute' => 'span class="sansserif"'}, 4338 'kbd', {'args' => ['code'], 'attribute' => 'kbd'}, 4339 'key', {'args' => ['code'], 'begin' => '<', 'end' => '>'}, 4340 'math', {'function' => \&t2h_default_math, 'args' => ['math'] }, 4341 'option', {'args' => ['code'], 'attribute' => 'samp', 'quote' => '"'}, 4342 'r', {'attribute' => 'span class="roman"'}, 4343 'samp', {'args' => ['code'], 'attribute' => 'samp', 'quote' => '"'}, 4344# 'sc', {'function' => \&t2h_default_sc}, 4345 'sc', {'attribute' => 'small'}, 4346 'strong', {'attribute' => 'strong'}, 4347 't', {'attribute' => 'tt'}, 4348 'uref', {'function' => \&t2h_default_uref, 4349 'args' => ['code', 'normal', 'normal'], 4350 'type' => 'simple_style' }, 4351 #'uref', {'function' => \&t2h_default_uref, 4352 # 'args' => ['normal', 'normal', 'normal']}, 4353 'url', {'function' => \&t2h_default_uref, 4354 'args' => ['code', 'normal', 'normal'], 4355 'type' => 'simple_style'}, 4356 'indicateurl', {'args' => ['code'], 'begin' => '<<code>', 'end' => '</code>>','type' => 'simple_style'}, 4357 'var', {'attribute' => 'var'}, 4358 'verb', {'args' => ['code'], 'attribute' => 'tt'}, 4359 'titlefont', {'function' => \&t2h_default_titlefont, 4360 'type' => 'simple_style'}, 4361 'w', {'type' => 'simple_style'}, 4362 'hyphenation', {'function' => \&t2h_default_hyphenation, 'args' => ['keep']}, 4363 ); 4364 4365%command_type = (); 4366 4367foreach my $style (keys(%style_map)) 4368{ 4369 if (exists($style_map{$style}->{'type'})) 4370 { 4371 $command_type{$style} = $style_map{$style}->{'type'}; 4372 } 4373 else 4374 { 4375 $command_type{$style} = 'style'; 4376 } 4377} 4378 4379%unicode_diacritical = ( 4380 'H' => '030B', 4381 'ringaccent' => '030A', 4382 "'" => '0301', 4383 'v' => '030C', 4384 ',' => '0327', 4385 '^' => '0302', 4386 'dotaccent' => '0307', 4387 '`' => '0300', 4388 '=' => '0304', 4389 '~' => '0303', 4390 '"' => '0308', 4391 'udotaccent' => '0323', 4392 'ubaraccent' => '0332', 4393 'u' => '0306', 4394 'tieaccent' => '0361', 4395 'ogonek' => '0328' 4396); 4397 4398%unicode_accents = ( 4399 'dotaccent' => { # dot above 4400 'A' => '0226', #C moz-1.2 4401 'a' => '0227', #c moz-1.2 4402 'B' => '1E02', 4403 'b' => '1E03', 4404 'C' => '010A', 4405 'c' => '010B', 4406 'D' => '1E0A', 4407 'd' => '1E0B', 4408 'E' => '0116', 4409 'e' => '0117', 4410 'F' => '1E1E', 4411 'f' => '1E1F', 4412 'G' => '0120', 4413 'g' => '0121', 4414 'H' => '1E22', 4415 'h' => '1E23', 4416 'i' => '0069', 4417 'I' => '0130', 4418 'N' => '1E44', 4419 'n' => '1E45', 4420 'O' => '022E', #Y moz-1.2 4421 'o' => '022F', #v moz-1.2 4422 'P' => '1E56', 4423 'p' => '1E57', 4424 'R' => '1E58', 4425 'r' => '1E59', 4426 'S' => '1E60', 4427 's' => '1E61', 4428 'T' => '1E6A', 4429 't' => '1E6B', 4430 'W' => '1E86', 4431 'w' => '1E87', 4432 'X' => '1E8A', 4433 'x' => '1E8B', 4434 'Y' => '1E8E', 4435 'y' => '1E8F', 4436 'Z' => '017B', 4437 'z' => '017C', 4438 }, 4439 'udotaccent' => { # dot below 4440 'A' => '1EA0', 4441 'a' => '1EA1', 4442 'B' => '1E04', 4443 'b' => '1E05', 4444 'D' => '1E0C', 4445 'd' => '1E0D', 4446 'E' => '1EB8', 4447 'e' => '1EB9', 4448 'H' => '1E24', 4449 'h' => '1E25', 4450 'I' => '1ECA', 4451 'i' => '1ECB', 4452 'K' => '1E32', 4453 'k' => '1E33', 4454 'L' => '1E36', 4455 'l' => '1E37', 4456 'M' => '1E42', 4457 'm' => '1E43', 4458 'N' => '1E46', 4459 'n' => '1E47', 4460 'O' => '1ECC', 4461 'o' => '1ECD', 4462 'R' => '1E5A', 4463 'r' => '1E5B', 4464 'S' => '1E62', 4465 's' => '1E63', 4466 'T' => '1E6C', 4467 't' => '1E6D', 4468 'U' => '1EE4', 4469 'u' => '1EE5', 4470 'V' => '1E7E', 4471 'v' => '1E7F', 4472 'W' => '1E88', 4473 'w' => '1E89', 4474 'Y' => '1EF4', 4475 'y' => '1EF5', 4476 'Z' => '1E92', 4477 'z' => '1E93', 4478 }, 4479 'ubaraccent' => { # line below 4480 'B' => '1E06', 4481 'b' => '1E07', 4482 'D' => '1E0E', 4483 'd' => '1E0F', 4484 'h' => '1E96', 4485 'K' => '1E34', 4486 'k' => '1E35', 4487 'L' => '1E3A', 4488 'l' => '1E3B', 4489 'N' => '1E48', 4490 'n' => '1E49', 4491 'R' => '1E5E', 4492 'r' => '1E5F', 4493 'T' => '1E6E', 4494 't' => '1E6F', 4495 'Z' => '1E94', 4496 'z' => '1E95', 4497 }, 4498 ',' => { # cedilla 4499 'C' => '00C7', 4500 'c' => '00E7', 4501 'D' => '1E10', 4502 'd' => '1E11', 4503 'E' => '0228', #C moz-1.2 4504 'e' => '0229', #c moz-1.2 4505 'G' => '0122', 4506 'g' => '0123', 4507 'H' => '1E28', 4508 'h' => '1E29', 4509 'K' => '0136', 4510 'k' => '0137', 4511 'L' => '013B', 4512 'l' => '013C', 4513 'N' => '0145', 4514 'n' => '0146', 4515 'R' => '0156', 4516 'r' => '0157', 4517 'S' => '015E', 4518 's' => '015F', 4519 'T' => '0162', 4520 't' => '0163', 4521 }, 4522 '=' => { # macron 4523 'A' => '0100', 4524 'a' => '0101', 4525 'E' => '0112', 4526 'e' => '0113', 4527 'I' => '012A', 4528 'i' => '012B', 4529 'G' => '1E20', 4530 'g' => '1E21', 4531 'O' => '014C', 4532 'o' => '014D', 4533 'U' => '016A', 4534 'u' => '016B', 4535 'Y' => '0232', #? moz-1.2 4536 'y' => '0233', #? moz-1.2 4537 }, 4538 '"' => { # diaeresis 4539 'A' => '00C4', 4540 'a' => '00E4', 4541 'E' => '00CB', 4542 'e' => '00EB', 4543 'H' => '1E26', 4544 'h' => '1E27', 4545 'I' => '00CF', 4546 'i' => '00EF', 4547 'O' => '00D6', 4548 'o' => '00F6', 4549 't' => '1E97', 4550 'U' => '00DC', 4551 'u' => '00FC', 4552 'W' => '1E84', 4553 'w' => '1E85', 4554 'X' => '1E8C', 4555 'x' => '1E8D', 4556 'y' => '00FF', 4557 'Y' => '0178', 4558 }, 4559 'u' => { # breve 4560 'A' => '0102', 4561 'a' => '0103', 4562 'E' => '0114', 4563 'e' => '0115', 4564 'G' => '011E', 4565 'g' => '011F', 4566 'I' => '012C', 4567 'i' => '012D', 4568 'O' => '014E', 4569 'o' => '014F', 4570 'U' => '016C', 4571 'u' => '016D', 4572 }, 4573 "'" => { # acute 4574 'A' => '00C1', 4575 'a' => '00E1', 4576 'C' => '0106', 4577 'c' => '0107', 4578 'E' => '00C9', 4579 'e' => '00E9', 4580 'G' => '01F4', 4581 'g' => '01F5', 4582 'I' => '00CD', 4583 'i' => '00ED', 4584 'K' => '1E30', 4585 'k' => '1E31', 4586 'L' => '0139', 4587 'l' => '013A', 4588 'M' => '1E3E', 4589 'm' => '1E3F', 4590 'N' => '0143', 4591 'n' => '0144', 4592 'O' => '00D3', 4593 'o' => '00F3', 4594 'P' => '1E54', 4595 'p' => '1E55', 4596 'R' => '0154', 4597 'r' => '0155', 4598 'S' => '015A', 4599 's' => '015B', 4600 'U' => '00DA', 4601 'u' => '00FA', 4602 'W' => '1E82', 4603 'w' => '1E83', 4604 'Y' => '00DD', 4605 'y' => '00FD', 4606 'Z' => '0179', 4607 'z' => '018A', 4608 }, 4609 '~' => { # tilde 4610 'A' => '00C3', 4611 'a' => '00E3', 4612 'E' => '1EBC', 4613 'e' => '1EBD', 4614 'I' => '0128', 4615 'i' => '0129', 4616 'N' => '00D1', 4617 'n' => '00F1', 4618 'O' => '00D5', 4619 'o' => '00F5', 4620 'U' => '0168', 4621 'u' => '0169', 4622 'V' => '1E7C', 4623 'v' => '1E7D', 4624 'Y' => '1EF8', 4625 'y' => '1EF9', 4626 }, 4627 '`' => { # grave 4628 'A' => '00C0', 4629 'a' => '00E0', 4630 'E' => '00C8', 4631 'e' => '00E8', 4632 'I' => '00CC', 4633 'i' => '00EC', 4634 'N' => '01F8', 4635 'n' => '01F9', 4636 'O' => '00D2', 4637 'o' => '00F2', 4638 'U' => '00D9', 4639 'u' => '00F9', 4640 'W' => '1E80', 4641 'w' => '1E81', 4642 'Y' => '1EF2', 4643 'y' => '1EF3', 4644 }, 4645 '^' => { # circumflex 4646 'A' => '00C2', 4647 'a' => '00E2', 4648 'C' => '0108', 4649 'c' => '0109', 4650 'E' => '00CA', 4651 'e' => '00EA', 4652 'G' => '011C', 4653 'g' => '011D', 4654 'H' => '0124', 4655 'h' => '0125', 4656 'I' => '00CE', 4657 'i' => '00EE', 4658 'J' => '0134', 4659 'j' => '0135', 4660 'O' => '00D4', 4661 'o' => '00F4', 4662 'S' => '015C', 4663 's' => '015D', 4664 'U' => '00DB', 4665 'u' => '00FB', 4666 'W' => '0174', 4667 'w' => '0175', 4668 'Y' => '0176', 4669 'y' => '0177', 4670 'Z' => '1E90', 4671 'z' => '1E91', 4672 }, 4673 'ringaccent' => { # ring 4674 'A' => '00C5', 4675 'a' => '00E5', 4676 'U' => '016E', 4677 'u' => '016F', 4678 'w' => '1E98', 4679 'y' => '1E99', 4680 }, 4681 'v' => { # caron 4682 'A' => '01CD', 4683 'a' => '01CE', 4684 'C' => '010C', 4685 'c' => '010D', 4686 'D' => '010E', 4687 'd' => '010F', 4688 'E' => '011A', 4689 'e' => '011B', 4690 'G' => '01E6', 4691 'g' => '01E7', 4692 'H' => '021E', #K with moz-1.2 4693 'h' => '021F', #k with moz-1.2 4694 'I' => '01CF', 4695 'i' => '01D0', 4696 'K' => '01E8', 4697 'k' => '01E9', 4698 'L' => '013D', #L' with moz-1.2 4699 'l' => '013E', #l' with moz-1.2 4700 'N' => '0147', 4701 'n' => '0148', 4702 'O' => '01D1', 4703 'o' => '01D2', 4704 'R' => '0158', 4705 'r' => '0159', 4706 'S' => '0160', 4707 's' => '0161', 4708 'T' => '0164', 4709 't' => '0165', 4710 'U' => '01D3', 4711 'u' => '01D4', 4712 'Z' => '017D', 4713 'z' => '017E', 4714 }, 4715 'H' => { # double acute 4716 'O' => '0150', 4717 'o' => '0151', 4718 'U' => '0170', 4719 'u' => '0171', 4720 }, 4721 'ogonek' => { 4722 'A' => '0104', 4723 'a' => '0105', 4724 'E' => '0118', 4725 'e' => '0119', 4726 'I' => '012E', 4727 'i' => '012F', 4728 'U' => '0172', 4729 'u' => '0173', 4730 'O' => '01EA', 4731 'o' => '01EB', 4732 }, 4733); 4734 4735%transliterate_accent_map = (); 4736foreach my $command (keys(%unicode_accents)) 4737{ 4738 foreach my $letter(keys (%{$unicode_accents{$command}})) 4739 { 4740 $transliterate_accent_map{$unicode_accents{$command}->{$letter}} 4741 = $letter 4742 unless (exists($transliterate_map{$unicode_accents{$command}->{$letter}})); 4743 } 4744} 4745 4746%special_accents = ( 4747 'ringaccent' => 'aA', 4748 "'" => 'aeiouyAEIOUY', 4749 ',' => 'cC', 4750 '^' => 'aeiouAEIOU', 4751 '`' => 'aeiouAEIOU', 4752 '~' => 'nNaoAO', 4753 '"' => 'aeiouyAEIOU', 4754# according to http://www2.lib.virginia.edu/small/vhp/download/ISO.txt 4755# however this doesn't seems to work in firefox 4756# 'ogonek' => 'aeiuAEIU', 4757); 4758 4759foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents)) 4760{ 4761 $style_map{$accent_command} = { 'function' => \&t2h_default_accent }; 4762 $old_style_map{$accent_command} = '&default_accent'; 4763 $style_map_texi{$accent_command} = { 'function' => \&t2h_default_ascii_accent }; 4764} 4765 4766sub default_accent($$) 4767{ 4768 my $text = shift; 4769 my $accent = shift; 4770 return "&${text}$accent_map{$accent};" if (defined($accent_map{$accent}) and defined($special_accents{$accent}) and ($text =~ /^[$special_accents{$accent}]$/)); 4771 return '&' . $text . 'ring;' if (($accent eq 'ringaccent') and (defined($special_accents{$accent})) and ($text =~ /^[$special_accents{$accent}]$/)); 4772 return $text . '<' if ($accent eq 'v'); 4773 return ascii_accents($text, $accent); 4774} 4775 4776sub t2h_default_accent($$) 4777{ 4778 my $accent = shift; 4779 my $args = shift; 4780 4781 my $text = $args->[0]; 4782 4783 return "&${text}$accent_map{$accent};" if (defined($accent_map{$accent}) and defined($special_accents{$accent}) and ($text =~ /^[$special_accents{$accent}]$/)); 4784 return '&' . $text . 'ring;' if (($accent eq 'ringaccent') and (defined($special_accents{$accent})) and ($text =~ /^[$special_accents{$accent}]$/)); 4785 return $text . '<' if ($accent eq 'v'); 4786# FIXME here there could be a conversion to the character in the right 4787# encoding, like 4788# if ($USE_UNICODE and defined($OUT_ENCODING) and $OUT_ENCODING ne '' 4789# and exists($unicode_accents{$accent}) and exists($unicode_accents{$accent}->{$text})) 4790# { 4791# my $encoded_char = Encode::encode($OUT_ENCODING, chr(hex($unicode_map{$thing})), Encode::FB_QUIET); 4792# return $encoded_char if ($encoded_char ne ''); 4793# } 4794 if ($USE_NUMERIC_ENTITY) 4795 { 4796 if (exists($unicode_accents{$accent}) and exists($unicode_accents{$accent}->{$text})) 4797 { 4798 return ('&#' . hex($unicode_accents{$accent}->{$text}) . ';'); 4799 } 4800 } 4801 return ascii_accents($text, $accent); 4802} 4803 4804sub ascii_accents($$) 4805{ 4806 my $text = shift; 4807 my $accent = shift; 4808 return $text if ($accent eq 'dotless'); 4809 return $text . "''" if ($accent eq 'H'); 4810 return $text . '.' if ($accent eq 'dotaccent'); 4811 return $text . '*' if ($accent eq 'ringaccent'); 4812 return $text . '[' if ($accent eq 'tieaccent'); 4813 return $text . '(' if ($accent eq 'u'); 4814 return $text . '_' if ($accent eq 'ubaraccent'); 4815 return '.' . $text if ($accent eq 'udotaccent'); 4816 return $text . '<' if ($accent eq 'v'); 4817 return $text . ';' if ($accent eq 'ogonek'); 4818 return $text . $accent if (defined($accent_map{$accent})); 4819} 4820 4821sub default_sc($$) 4822{ 4823 return '<small>' . uc($_[0]) . '</small>'; 4824} 4825 4826# now unused, upcasing is done in normal_text 4827sub t2h_default_sc($$$) 4828{ 4829 shift; 4830 my $args = shift; 4831 return '<small>' . uc($args->[0]) . '</small>'; 4832} 4833 4834sub default_ctrl($$) 4835{ 4836 return "^$_[0]"; 4837} 4838 4839# obsolete, no warning, but noop 4840sub t2h_default_ctrl($$$) 4841{ 4842 shift; 4843 my $args = shift; 4844 #return "^$args->[0]"; 4845 return "$args->[0]"; 4846} 4847 4848sub default_sc_pre($$) 4849{ 4850 return uc($_[0]); 4851} 4852 4853# now unused, upcasing is done in normal_text 4854sub t2h_default_sc_pre($$$) 4855{ 4856 shift; 4857 my $args = shift; 4858 return uc($args->[0]); 4859} 4860 4861sub default_titlefont($$) 4862{ 4863 return "<h1 class=\"titlefont\">$_[0]</h1>" if ($_[0] =~ /\S/); 4864 return ''; 4865} 4866 4867# Avoid adding h1 if the text is empty 4868sub t2h_default_titlefont($$$) 4869{ 4870 shift; 4871 my $args = shift; 4872 return "<h1 class=\"titlefont\">$args->[0]</h1>" if ($args->[0] =~ /\S/); 4873 return ''; 4874} 4875 4876# At some point in time (before 4.7?) according to the texinfo 4877# manual, url shouldn't lead to a link but rather be formatted 4878# like text. It is now what indicateurl do, url is the same that 4879# uref with one arg. If we did like makeinfo did it would have been 4880#sub url($$) 4881#{ 4882# return '<<code>' . $_[0] . '</code>>'; 4883#} 4884# 4885# This is unused, t2h_default_uref is used instead 4886sub t2h_default_url ($$) 4887{ 4888 shift; 4889 my $args = shift; 4890 my $url = shift @$args; 4891 #$url =~ s/\s*$//; 4892 #$url =~ s/^\s*//; 4893 $url = main::normalise_space($url); 4894 return '' unless ($url =~ /\S/); 4895 return &$anchor('', $url, $url); 4896} 4897 4898sub default_url ($$) 4899{ 4900 my $url = shift; 4901 my $command = shift; 4902 $url =~ s/\s*$//; 4903 $url =~ s/^\s*//; 4904 return '' unless ($url =~ /\S/); 4905 return &$anchor('', $url, $url); 4906} 4907 4908sub default_uref($$) 4909{ 4910 my $arg = shift; 4911 my $command = shift; 4912 my ($url, $text, $replacement); 4913 ($url, $text, $replacement) = split /,\s*/, $arg; 4914 $url =~ s/\s*$//; 4915 $url =~ s/^\s*//; 4916 $text = $replacement if (defined($replacement)); 4917 $text = $url unless ($text); 4918 return $text if ($url eq ''); 4919 return &$anchor('', $url, $text); 4920} 4921 4922sub t2h_default_uref($$) 4923{ 4924 shift; 4925 my $args = shift; 4926 my $url = shift @$args; 4927 my $text = shift @$args; 4928 my $replacement = shift @$args; 4929 #$url =~ s/\s*$//; 4930 #$url =~ s/^\s*//; 4931 $url = main::normalise_space($url); 4932 $replacement = '' if (!defined($replacement)); 4933 $replacement = main::normalise_space($replacement); 4934 $text = '' if (!defined($text)); 4935 $text = main::normalise_space($text); 4936 $text = $replacement if ($replacement ne ''); 4937 $text = $url unless ($text ne ''); 4938 return $text if ($url eq ''); 4939 return &$anchor('', $url, $text); 4940} 4941 4942sub t2h_default_math($$) 4943{ 4944 shift; 4945 my $args = shift; 4946 my $text = shift @$args; 4947#print STDERR "t2h_default_math $text\n"; 4948 $text =~ s/[{}]//g; 4949# $text =~ s/\@\\/\\/g; 4950 return "<em>$text</em>"; 4951} 4952 4953sub default_email($$) 4954{ 4955 my $arg = shift; 4956 my $command = shift; 4957 my ($mail, $text); 4958 ($mail, $text) = split /,\s*/, $arg; 4959 $mail =~ s/\s*$//; 4960 $mail =~ s/^\s*//; 4961 $text = $mail unless ($text); 4962 return $text if ($mail eq ''); 4963 return &$anchor('', "mailto:$mail", $text); 4964} 4965 4966sub t2h_default_email($$) 4967{ 4968 my $command = shift; 4969 my $args = shift; 4970 my $mail = shift @$args; 4971 my $text = shift @$args; 4972 $mail = main::normalise_space($mail); 4973 #$mail =~ s/\s*$//; 4974 #$mail =~ s/^\s*//; 4975 $text = $mail unless (defined($text) and ($text ne '')); 4976 $text = main::normalise_space($text); 4977 return $text if ($mail eq ''); 4978 return &$anchor('', "mailto:$mail", $text); 4979} 4980 4981sub t2h_default_click_normal($$$) 4982{ 4983 return t2h_default_click('normal', @_); 4984} 4985 4986sub t2h_default_click_pre($$$) 4987{ 4988 return t2h_default_click('pre', @_); 4989} 4990 4991sub t2h_default_click_texi($$$) 4992{ 4993 return t2h_default_click('texi', @_); 4994} 4995 4996sub t2h_default_click($$$$$) 4997{ 4998 my $context = shift; 4999 my $command = shift; 5000 my $args = shift; 5001 my $arg = shift @$args; 5002 my $cmd = $Texi2HTML::THISDOC{'clickstyle'}; 5003 $cmd = 'arrow' if (!defined($cmd) or ($cmd eq '')); 5004 5005 my $hash = \%things_map; 5006 if ($context eq 'pre') 5007 { 5008 $hash = \%pre_map; 5009 } 5010 elsif ($context eq 'texi') 5011 { 5012 $hash = \%texi_map; 5013 } 5014 return $hash->{$cmd} . $arg if (exists($hash->{$cmd})); 5015 return $arg; 5016} 5017 5018sub t2h_default_hyphenation($$) 5019{ 5020 my $command = shift; 5021 my $args = shift; 5022 my $text = shift @$args; 5023 $text =~ s/^\s*//; 5024 $text =~ s/\s*$//; 5025 my @list = split /\s+/, $text; 5026 foreach my $entry (@list) 5027 { 5028 my $word = $entry; 5029 $word =~ s/-//g; 5030 $Texi2HTML::THISDOC{'hyphenation'}->{$word} = $entry; 5031 } 5032} 5033 5034sub t2h_default_ascii_accent($$$$) 5035{ 5036 my $accent = shift; 5037 my $args = shift; 5038 5039 my $text = $args->[0]; 5040 return ascii_accents($text, $accent); 5041} 5042 5043sub t2h_default_no_texi_email 5044{ 5045 my $command = shift; 5046 my $args = shift; 5047 my $mail = shift @$args; 5048 my $text = shift @$args; 5049 $mail = main::normalise_space($mail); 5050 #$mail =~ s/\s*$//; 5051 #$mail =~ s/^\s*//; 5052 return $text if (defined($text) and ($text ne '')); 5053 return $mail; 5054} 5055 5056sub t2h_default_no_texi_image($$$$) 5057{ 5058 my $command = shift; 5059 my $args = shift; 5060 #my $text = $args->[0]; 5061 #$text = main::normalise_space($text); 5062 #my @args = split (/\s*,\s*/, $text); 5063 my $file = $args->[0]; 5064 $file =~ s/^\s*//; 5065 $file =~ s/\s*$//; 5066 return main::substitute_line($file, {'remove_texi' => 1, 'code_style' => 1}); 5067} 5068 5069sub t2h_default_no_texi_acronym_like($$) 5070{ 5071 my $command = shift; 5072 my $args = shift; 5073 my $acronym_texi = $args->[0]; 5074 return (main::remove_texi($acronym_texi)); 5075} 5076 5077sub t2h_remove_command($$$$) 5078{ 5079 return ''; 5080} 5081 5082# This is used for style in preformatted sections 5083my %old_style_map_pre = %old_style_map; 5084$old_style_map_pre{'sc'} = '&default_sc_pre'; 5085$old_style_map_pre{'titlefont'} = ''; 5086 5087foreach my $command (keys(%style_map)) 5088{ 5089 $style_map_pre{$command} = {}; 5090 $style_map_texi{$command} = {} if (!exists($style_map_texi{$command})); 5091 $style_map_texi{$command}->{'args'} = $style_map{$command}->{'args'} 5092 if (exists($style_map{$command}->{'args'})); 5093 #print STDERR "COMMAND $command"; 5094 5095 foreach my $key (keys(%{$style_map{$command}})) 5096 { 5097 $style_map_pre{$command}->{$key} = $style_map{$command}->{$key}; 5098 } 5099} 5100 5101#$style_map_pre{'sc'}->{'function'} = \&t2h_default_sc_pre; 5102$style_map_pre{'sc'} = {}; 5103$style_map_pre{'titlefont'} = {}; 5104$style_map_pre{'click'}->{'function'} = \&t2h_default_click_pre; 5105 5106#$style_map_texi{'sc'}->{'function'} = \&t2h_default_sc_pre; 5107$style_map_texi{'sc'} = {}; 5108$style_map_texi{'email'}->{'function'} = \&t2h_default_no_texi_email; 5109$style_map_texi{'click'}->{'function'} = \&t2h_default_click_texi; 5110 5111####### special styles. You shouldn't need to change them 5112%special_style = ( 5113 #'xref' => ['keep','normal','normal','keep','normal'], 5114 'xref' => { 'args' => ['keep','keep','keep','keep','keep'], 5115 'function' => \&main::do_xref }, 5116 'ref' => { 'args' => ['keep','keep','keep','keep','keep'], 5117 'function' => \&main::do_xref }, 5118 'pxref' => { 'args' => ['keep','keep','keep','keep','keep'], 5119 'function' => \&main::do_xref }, 5120 'inforef' => { 'args' => ['keep','keep','keep'], 5121 'function' => \&main::do_xref }, 5122 'image' => { 'args' => ['keep','keep','keep','keep','keep'], 'function' => \&main::do_image }, 5123 'anchor' => { 'args' => ['keep'], 'function' => \&main::do_anchor_label }, 5124 'footnote' => { 'args' => ['keep'], 'function' => \&main::do_footnote }, 5125 'shortcaption' => { 'args' => ['keep'], 'function' => \&main::do_caption_shortcaption }, 5126 'caption' => { 'args' => ['keep'], 'function' => \&main::do_caption_shortcaption }, 5127 'acronym', {'args' => ['keep','keep'], 'function' => \&main::do_acronym_like}, 5128 'abbr', {'args' => ['keep','keep'], 'function' => \&main::do_acronym_like}, 5129); 5130 5131# @image is replaced by the first arg in strings 5132$style_map_texi{'image'} = { 'args' => ['keep','keep','keep','keep','keep'], 5133 'function' => \&t2h_default_no_texi_image }; 5134 5135$style_map_texi{'acronym'} = { 'args' => ['keep','keep'], 5136 'function' => \&t2h_default_no_texi_acronym_like }; 5137$style_map_texi{'abbr'} = { 'args' => ['keep','keep'], 5138 'function' => \&t2h_default_no_texi_acronym_like }; 5139 5140foreach my $special (keys(%special_style)) 5141{ 5142 $style_map{$special} = $special_style{$special} 5143 unless (defined($style_map{$special})); 5144 $style_map_pre{$special} = $special_style{$special} 5145 unless (defined($style_map_pre{$special})); 5146 $style_map_texi{$special} = { 'args' => ['keep'], 5147 'function' => \&t2h_remove_command } 5148 unless (defined($style_map_texi{$special})); 5149} 5150####### end special styles. 5151 5152 5153#foreach my $command (keys(%style_map)) 5154#{ 5155# print STDERR "STYLE_MAP_TEXI $command($style_map_texi{$command}) "; 5156# print STDERR "ARGS $style_map_texi{$command}->{'args'} " if (defined($style_map_texi{$command}->{'args'})); 5157# print STDERR "FUN $style_map_texi{$command}->{'function'} " if (defined($style_map_texi{$command}->{'function'})); 5158# print STDERR "\n"; 5159#} 5160 5161# uncomment to use the old interface 5162#%style_map = %old_style_map; 5163#%style_map_pre = %old_style_map_pre; 5164 5165%simple_format_simple_map_texi = %simple_map_pre; 5166%simple_format_texi_map = %pre_map; 5167%simple_format_style_map_texi = (); 5168 5169foreach my $command (keys(%style_map_texi)) 5170{ 5171 #$simple_format_style_map_texi{$command} = {}; 5172 foreach my $key (keys (%{$style_map_texi{$command}})) 5173 { 5174 #print STDERR "$command, $key, $style_map_texi{$command}->{$key}\n"; 5175 $simple_format_style_map_texi{$command}->{$key} = 5176 $style_map_texi{$command}->{$key}; 5177 } 5178 $simple_format_style_map_texi{$command} = {} if (!defined($simple_format_style_map_texi{$command})); 5179} 5180 5181foreach my $accent_command ('tieaccent', 'dotless', keys(%unicode_accents)) 5182{ 5183# $simple_format_style_map_texi{$accent_command}->{'args'} = ['normal']; 5184 $simple_format_style_map_texi{$accent_command}->{'function'} = \&t2h_default_accent; 5185} 5186 5187# regions expanded or not depending on the value of this hash. 5188# @EXPAND sets entries in this hash, and you should better use 5189# @EXPAND unless you know what you are doing. 5190%texi_formats_map = ( 5191 'iftex' => 0, 5192 'ignore' => 0, 5193 'menu' => 0, 5194 'ifplaintext' => 0, 5195 'ifinfo' => 0, 5196 'ifxml' => 0, 5197 'ifhtml' => 0, 5198 'ifdocbook' => 0, 5199 'html' => 0, 5200 'tex' => 0, 5201 'xml' => 0, 5202 'docbook' => 0, 5203 'titlepage' => 1, 5204 'documentdescription' => 1, 5205 'copying' => 1, 5206 'ifnothtml' => 1, 5207 'ifnottex' => 1, 5208 'ifnotplaintext' => 1, 5209 'ifnotinfo' => 1, 5210 'ifnotxml' => 1, 5211 'ifnotdocbook' => 1, 5212 'direntry' => 0, 5213 'verbatim' => 'raw', 5214 'ifclear' => 'value', 5215 'ifset' => 'value' , 5216 ); 5217 5218%format_map = ( 5219# 'quotation' => 'blockquote', 5220 # lists 5221# 'itemize' => 'ul', 5222 'enumerate' => 'ol', 5223# 'multitable' => 'table', 5224 'table' => 'dl compact="compact"', 5225 'vtable' => 'dl compact="compact"', 5226 'ftable' => 'dl compact="compact"', 5227 'group' => '', 5228# 'detailmenu' => '', 5229 ); 5230 5231%special_list_commands = ( 5232 'table' => {}, 5233 'vtable' => {}, 5234 'ftable' => {}, 5235 'itemize' => { 'bullet' => '' } 5236 ); 5237 5238%inter_item_commands = ( 5239 'c' => 1, 5240 'comment' => 1, 5241 'cindex' => 1 5242); 5243# 5244# texinfo format to align attribute of paragraphs 5245# 5246 5247%paragraph_style = ( 5248 'center' => 'center', 5249 'flushleft' => 'left', 5250 'flushright' => 'right', 5251 ); 5252 5253# an eval of these $complex_format_map->{what}->{'begin'} yields beginning 5254# an eval of these $complex_format_map->{what}->{'end'} yields end 5255# $EXAMPLE_INDENT_CELL and SMALL_EXAMPLE_INDENT_CELL can be usefull here 5256$complex_format_map = 5257{ 5258 'example' => 5259 { 5260 'begin' => q{"<table><tr>$EXAMPLE_INDENT_CELL<td>"}, 5261 'end' => q{"</td></tr></table>\n"}, 5262 'style' => 'code', 5263 }, 5264 'smallexample' => 5265 { 5266 'begin' => q{"<table><tr>$SMALL_EXAMPLE_INDENT_CELL<td>"}, 5267 'end' => q{"</td></tr></table>\n"}, 5268 'style' => 'code', 5269 }, 5270 'display' => 5271 { 5272 'begin' => q{"<table><tr>$EXAMPLE_INDENT_CELL<td>"}, 5273 'end' => q{"</td></tr></table>\n"}, 5274 }, 5275 'smalldisplay' => 5276 { 5277 'begin' => q{"<table><tr>$SMALL_EXAMPLE_INDENT_CELL<td>"}, 5278 'end' => q{"</td></tr></table>\n"}, 5279 } 5280}; 5281 5282# format shouldn't narrow the margins 5283 5284$complex_format_map->{'lisp'} = $complex_format_map->{'example'}; 5285$complex_format_map->{'smalllisp'} = $complex_format_map->{'smallexample'}; 5286$complex_format_map->{'format'} = $complex_format_map->{'display'}; 5287$complex_format_map->{'smallformat'} = $complex_format_map->{'smalldisplay'}; 5288 5289%def_map = ( 5290 # basic commands 5291 'deffn', [ 'f', 'category', 'name', 'arg' ], 5292 'defvr', [ 'v', 'category', 'name' ], 5293 'deftypefn', [ 'f', 'category', 'type', 'name', 'argtype' ], 5294 'deftypeop', [ 'f', 'category', 'class' , 'type', 'name', 'argtype' ], 5295 'deftypevr', [ 'v', 'category', 'type', 'name' ], 5296 'defcv', [ 'v', 'category', 'class' , 'name' ], 5297 'deftypecv', [ 'v', 'category', 'class' , 'type', 'name' ], 5298 'defop', [ 'f', 'category', 'class' , 'name', 'arg' ], 5299 'deftp', [ 't', 'category', 'name', 'argtype' ], 5300 # shortcuts 5301 # FIXME i18n 5302 'defun', 'deffn Function', 5303 'defmac', 'deffn Macro', 5304 'defspec', 'deffn {Special Form}', 5305 'defvar', 'defvr Variable', 5306 'defopt', 'defvr {User Option}', 5307 'deftypefun', 'deftypefn {Function}', 5308 'deftypevar', 'deftypevr Variable', 5309 'defivar', 'defcv {Instance Variable}', 5310 'deftypeivar', 'deftypecv {Instance Variable}', 5311 'defmethod', 'defop Method', 5312 'deftypemethod', 'deftypeop Method', 5313 ); 5314 5315$def_always_delimiters = "()[]"; 5316$def_in_type_delimiters = ",;"; 5317$def_argument_separator_delimiters = "()[],"; 5318 5319# basic x commands 5320foreach my $key (keys(%def_map)) 5321{ 5322 $def_map{$key . 'x'} = $def_map{$key}; 5323} 5324 5325# 5326# miscalleneous commands 5327# 5328# Depending on the value, the command arg or spaces following the command 5329# are handled differently: 5330# 5331# the value is a reference on a hash. 5332# the hash keys are 5333# 'arg' if the value is 'line' then the remaining of the line is the arg 5334# if it is a number it is the number of args (separated by spaces) 5335# 'skip' if the value is 'line' then the remaining of the line is skipped 5336# if the value is 'space' space but no newline is skipped 5337# if the value is 'whitespace' space is skipped 5338# if the value is 'linewhitespace' space is skipped if there are 5339# only spaces remaining on the line 5340# if the value is 'linespace' space but no newline is skipped if 5341# there are only spaces remaining on the line 5342# 'keep' if true the args and the macro are kept, otherwise the macro 5343# args and skipped stuffs are removed 5344%misc_command = ( 5345 'bye' => {'skip' => 'line'}, # no arg 5346 # set, clear 5347 'set' => {'skip' => 'line'}, # special arg 5348 'clear' => {'skip' => 'line'}, # special arg 5349 # comments 5350 'comment' => {'arg' => 'line'}, 5351 'c' => {'arg' => 'line'}, 5352 5353 # not needed for formatting 5354 'raisesections' => {'skip' => 'line'}, # no arg 5355 'lowersections' => {'skip' => 'line'}, # no arg 5356 'contents' => {}, # no arg 5357 'shortcontents' => {}, # no arg 5358 'summarycontents'=> {}, # no arg 5359 'setcontentsaftertitlepage' => {}, # no arg 5360 'setshortcontentsaftertitlepage' => {}, # no arg 5361# 'detailmenu' => {'skip' => 'whitespace'}, # no arg 5362# 'end detailmenu' => {'skip' => 'whitespace'}, # no arg 5363 'clickstyle' => {'skip' => 'line'}, # arg should be an @-command 5364 # in preamble 5365 'novalidate' => {}, # no arg 5366 'dircategory'=> {'arg' => 'line'}, # line. Position with regard 5367 # with direntry is significant 5368 'pagesizes' => {'skip' => 'line', 'arg' => 'line'}, # can have 2 args 5369 # or one? 200mm,150mm 11.5in 5370 'finalout' => {}, # no arg 5371 'paragraphindent' => {'skip' => 'line', 'arg' => 1}, # arg none asis 5372 # or a number and forbids anything else on the line 5373 'firstparagraphindent' => {'skip' => 'line', 'arg' => 1}, # none insert 5374 'frenchspacing' => {'arg' => 1}, # on off 5375 'fonttextsize' => {'arg' => 1}, # 10 11 5376 'allowcodebreaks' => {'arg' => 1}, # false or true 5377 'exampleindent' => {'skip' => 'line', 'arg' => 1}, # asis or a number 5378 'footnotestyle'=> {'skip' => 'line', 'arg' => 1}, # end and separate 5379 # and nothing else on the line 5380 'afourpaper' => {'skip' => 'line'}, # no arg 5381 'afivepaper' => {'skip' => 'line'}, # no arg 5382 'afourlatex' => {'skip' => 'line'}, # no arg 5383 'afourwide' => {'skip' => 'line'}, # no arg 5384 'headings'=> {'skip' => 'line', 'arg' => 1}, 5385 #off on single double singleafter doubleafter 5386 # interacts with setchapternewpage 5387 'setchapternewpage' => {'skip' => 'line', 'arg' => 1}, # off on odd 5388 'everyheading' => {'arg' => 'line'}, 5389 'everyfooting' => {'arg' => 'line'}, 5390 'evenheading' => {'arg' => 'line'}, 5391 'evenfooting' => {'arg' => 'line'}, 5392 'oddheading' => {'arg' => 'line'}, 5393 'oddfooting' => {'arg' => 'line'}, 5394 'smallbook' => {'skip' => 'line'}, # no arg 5395 'setfilename' => {'arg' => 'line'}, 5396 #'shorttitle' => {'arg' => 'line', 'texi' => 1}, 5397 #'shorttitlepage' => {'arg' => 'line', 'texi' => 1}, 5398 #'settitle' => {'arg' => 'line', 'texi' => 1}, 5399 #'author' => {'arg' => 'line', 'texi' => 1}, 5400 #'subtitle' => {'arg' => 'line', 'texi' => 1}, 5401 #'title' => {'arg' => 'line', 'texi' => 1}, 5402 'shorttitle' => {'arg' => 'line'}, 5403 'shorttitlepage' => {'arg' => 'line'}, 5404 'settitle' => {'arg' => 'line'}, 5405 'author' => {'arg' => 'line'}, 5406 'subtitle' => {'arg' => 'line'}, 5407 'title' => {'arg' => 'line'}, 5408 'syncodeindex' => {'skip' => 'linespace', 'arg' => 2}, 5409 # args are index identifiers 5410 'synindex' => {'skip' => 'linespace', 'arg' => 2}, 5411 'defindex' => {'skip' => 'line', 'arg' => 1}, # one identifier arg 5412 'defcodeindex' => {'skip' => 'line', 'arg' => 1}, # one identifier arg 5413 'documentlanguage' => {'skip' => 'whitespace', 'arg' => 1}, 5414 # language code arg 5415 'kbdinputstyle' => {'skip' => 'whitespace', 'arg' => 1}, # code 5416 #example distinct 5417 'everyheadingmarks' => {'skip' => 'whitespace', 'arg' => 1}, # top bottom 5418 #makeinfo ignore line 5419 'everyfootingmarks' => {'skip' => 'whitespace', 'arg' => 1}, 5420 'evenheadingmarks' => {'skip' => 'whitespace', 'arg' => 1}, 5421 'oddheadingmarks' => {'skip' => 'whitespace', 'arg' => 1}, 5422 'evenfootingmarks' => {'skip' => 'whitespace', 'arg' => 1}, 5423 'oddfootingmarks' => {'skip' => 'whitespace', 'arg' => 1}, 5424 'sp' => {'skip' => 'whitespace', 'arg' => 1}, # no arg 5425 # at the end of line or a numerical arg 5426 # formatting 5427 'page' => {}, # no arg (pagebreak) 5428 'refill' => {}, # no arg (obsolete, to be ignored) 5429 'noindent' => {'skip' => 'whitespace'}, # no arg 5430 'indent' => {'skip' => 'whitespace'}, 5431 'need' => {'skip' => 'line', 'arg' => 1}, # one numerical/real arg 5432 'exdent' => {'skip' => 'space'}, 5433 # not valid for info (should be in @iftex) 5434 'vskip' => {'arg' => 'line'}, # arg line in TeX 5435 'cropmarks' => {}, # no arg 5436 # miscalleneous 5437 'verbatiminclude'=> {'skip' => 'line'}, 5438 'documentencoding' => {'arg' => 1}, # makeinfo ignore the whole line 5439 # ??? 5440 'filbreak' => {}, 5441 # obsolete @-commands 5442 'quote-arg' => {}, 5443 'allow-recursion' => {}, 5444 ); 5445my %misc_command_old = ( 5446 # not needed for formatting 5447 'raisesections', 'line', # no arg 5448 'lowersections', 'line', # no arg 5449 'contents', 1, # no arg 5450 'shortcontents', 1, # no arg 5451 'summarycontents', 1, # no arg 5452 'detailmenu', 'whitespace', # no arg 5453 'end detailmenu', 'whitespace', # no arg 5454 #'end detailmenu', 1, # no arg 5455 'novalidate', 1, # no arg 5456 'bye', 'line', # no arg 5457 # comments 5458 'comment', 'line', 5459 'c', 'line', 5460 # in preamble 5461 'dircategory', 'line', # line. Position with regard with direntry is 5462 # significant 5463 'pagesizes', 'line arg2', # can have 2 args 5464 'finalout', 1, # no arg 5465 'paragraphindent', 'line arg1', # in fact accepts only none asis 5466 # or a number and forbids anything else on the line 5467 'firstparagraphindent', 'line arg1', # in fact accepts only none insert 5468 'exampleindent', 'line arg1', # in fact accepts only asis or a number 5469 'footnotestyle', 'line arg1', # in fact accepts only end and separate 5470 # and nothing else on the line 5471 'afourpaper', 'line', # no arg 5472 'afourlatex', 'line', # no arg 5473 'afourwide', 'line', # no arg 5474 'headings', 'line', # one arg, possibilities are 5475 #off on single double singleafter doubleafter 5476 # interacts with setchapternewpage 5477 'setchapternewpage', 'line', # no arg 5478 'everyheading', 'line', 5479 'everyfooting', 'line', 5480 'evenheading', 'line', 5481 'evenfooting', 'line', 5482 'oddheading', 'line', 5483 'oddfooting', 'line', 5484 'smallbook', 'line', # no arg 5485 'setfilename', 'line', 5486 'shorttitle', 'linetexi', 5487 'shorttitlepage', 'linetexi', 5488 'settitle', 'linetexi', 5489 'author', 'linetexi', 5490 'subtitle', 'linetexi', 5491 'title','linetexi', 5492 'syncodeindex','linespace arg2', # args are 5493 'synindex','linespace arg2', 5494 'defindex', 'line arg1', # one identifier arg 5495 'defcodeindex', 'line arg1', # one identifier arg 5496 'documentlanguage', 'whitespace arg1', # one language code arg 5497 'kbdinputstyle', 'whitespace arg1', # one arg within 5498 #code example distnct 5499 'sp', 'whitespace arg1', # no arg at the en of line or a numerical arg 5500 # formatting 5501 'page', 1, # no arg (pagebreak) 5502 'refill', 1, # no arg (obsolete, to be ignored)) 5503 'noindent', 'space', # no arg 5504 'need', 'line arg1', # one numerical/real arg 5505 'exdent', 'space', 5506 # not valid for info (should be in @iftex) 5507 'vskip', 'line', # arg line in TeX 5508 'cropmarks', 1, # no arg 5509 # miscalleneous 5510 'verbatiminclude', 'line', 5511 'documentencoding', 'arg1', 5512 # ??? 5513 'filbreak', 1, 5514 ); 5515 5516%format_in_paragraph = ( 5517 'html' => 1, 5518); 5519# map mapping css specification to style 5520 5521%css_map = 5522 ( 5523 'ul.toc' => "$NO_BULLET_LIST_STYLE", 5524 'pre.menu-comment' => "$MENU_PRE_STYLE", 5525 'pre.menu-preformatted' => "$MENU_PRE_STYLE", 5526 'a.summary-letter' => 'text-decoration: none', 5527 'a:link' => 'color: #0000e0', ###GAMBIT### added 5528 'a:visited' => 'color: #0000e0', ###GAMBIT### added 5529 'blockquote.smallquotation' => 'font-size: smaller', 5530# 'pre.display' => 'font-family: inherit', 5531# 'pre.smalldisplay' => 'font-family: inherit; font-size: smaller', 5532 'pre.display' => 'font-family: serif', 5533 'pre.smalldisplay' => 'font-family: serif; font-size: smaller', 5534 'pre.smallexample' => 'font-size: smaller', 5535 'span.sansserif' => 'font-family:sans-serif; font-weight:normal;', 5536 'span.roman' => 'font-family:serif; font-weight:normal;' 5537 ); 5538 5539$css_map{'pre.format'} = $css_map{'pre.display'}; 5540$css_map{'pre.smallformat'} = $css_map{'pre.smalldisplay'}; 5541$css_map{'pre.smalllisp'} = $css_map{'pre.smallexample'}; 5542 5543# The command_handler arrays are for commands formatted externally. 5544# The function references in @command_handler_init are called 5545# before the second pass, before the @-commands text collection. 5546# Those in @command_handler_process are called between the second pass 5547# and the third pass, after collection of @-commands text and before their 5548# expansion. 5549# Those in @command_handler_process are called after the third pass, 5550# after the document generation. 5551@command_handler_init = (); 5552@command_handler_process = (); 5553@command_handler_finish = (); 5554 5555# the keys of %command_handler are @-command names and the value 5556# is a hash reference with the following keys: 5557# 'init' function reference used to collect the @-command text 5558# 'expand' function reference used when expanding the @-command text 5559%command_handler = (); 5560 5561 5562# formatting functions 5563 5564$anchor = \&t2h_default_anchor; 5565$def_item = \&t2h_default_def_item; 5566$def = \&t2h_default_def; 5567$menu_command = \&t2h_default_menu_command; 5568$menu_link = \&t2h_default_menu_link; 5569#$menu_comment = \&t2h_default_menu_comment; 5570$menu_description = \&t2h_default_menu_description; 5571#$simple_menu_link = \&t2h_default_simple_menu_link; 5572$external_ref = \&t2h_default_external_ref; 5573$external_href = \&t2h_default_external_href; 5574$internal_ref = \&t2h_default_internal_ref; 5575$table_item = \&t2h_default_table_item; 5576$table_line = \&t2h_default_table_line; 5577$table_list = \&t2h_default_table_list; 5578$row = \&t2h_default_row; 5579$cell = \&t2h_default_cell; 5580$list_item = \&t2h_default_list_item; 5581$comment = \&t2h_default_comment; 5582$def_line = \&t2h_default_def_line; 5583$def_line_no_texi = \&t2h_default_def_line_no_texi; 5584$raw = \&t2h_default_raw; 5585$raw_no_texi = \&t2h_default_raw_no_texi; 5586$heading = \&t2h_default_heading; 5587$element_heading = \&t2h_default_element_heading; 5588$heading_no_texi = \&t2h_default_heading_no_texi; 5589$paragraph = \&t2h_default_paragraph; 5590$preformatted = \&t2h_default_preformatted; 5591$foot_line_and_ref = \&t2h_default_foot_line_and_ref; 5592$foot_section = \&t2h_default_foot_section; 5593$image_files = \&t2h_default_image_files; 5594$image = \&t2h_default_image; 5595$address = \&t2h_default_address; 5596$index_entry_label = \&t2h_default_index_entry_label; 5597$index_summary = \&t2h_default_index_summary; 5598#$summary_letter = \&t2h_default_summary_letter; 5599$index_entry = \&t2h_default_index_entry; 5600$index_entry_command = \&t2h_default_index_entry_command; 5601$index_letter = \&t2h_default_index_letter; 5602#$printindex = \&t2h_default_printindex; 5603$print_index = \&t2h_default_print_index; 5604$protect_text = \&t2h_default_protect_text; 5605$normal_text = \&t2h_default_normal_text; 5606$complex_format = \&t2h_default_complex_format; 5607$cartouche = \&t2h_default_cartouche; 5608$sp = \&t2h_default_sp; 5609$definition_category = \&t2h_default_definition_category; 5610$definition_index_entry = \&t2h_default_definition_index_entry; 5611$copying_comment = \&t2h_default_copying_comment; 5612$documentdescription = \&t2h_default_documentdescription; 5613$index_summary_file_entry = \&t2h_default_index_summary_file_entry; 5614$index_summary_file_end = \&t2h_default_index_summary_file_end; 5615$index_summary_file_begin = \&t2h_default_index_summary_file_begin; 5616$empty_line = \&t2h_default_empty_line; 5617$unknown = \&t2h_default_unknown; 5618$unknown_style = \&t2h_default_unknown_style; 5619$caption_shortcaption = \&t2h_default_caption_shortcaption; 5620$caption_shortcaption_command = \&t2h_default_caption_shortcaption_command; 5621$float = \&t2h_default_float; 5622$listoffloats = \&t2h_default_listoffloats; 5623$listoffloats_entry = \&t2h_default_listoffloats_entry; 5624$listoffloats_caption = \&t2h_default_listoffloats_caption; 5625$listoffloats_float_style = \&t2h_default_listoffloats_float_style; 5626$listoffloats_style = \&t2h_default_listoffloats_style; 5627$acronym_like = \&t2h_default_acronym_like; 5628$quotation = \&t2h_default_quotation; 5629$quotation_prepend_text = \&t2h_default_quotation_prepend_text; 5630$paragraph_style_command = \&t2h_default_paragraph_style_command; 5631$heading_texi = \&t2h_default_heading_texi; 5632$index_element_heading_texi = \&t2h_default_index_element_heading_texi; 5633$element_label = \&t2h_default_element_label; 5634$misc_element_label = \&t2h_default_misc_element_label; 5635$anchor_label = \&t2h_default_anchor_label; 5636$preserve_misc_command = \&t2h_default_preserve_misc_command; 5637$format_list_item_texi = \&t2h_default_format_list_item_texi; 5638$begin_format_texi = \&t2h_default_begin_format_texi; 5639$tab_item_texi = \&t2h_default_tab_item_texi; 5640$insertcopying = \&t2h_default_insertcopying; 5641$colon_command = \&t2h_default_colon_command; 5642$simple_command = \&t2h_default_simple_command; 5643$thing_command = \&t2h_default_thing_command; 5644 5645# return the line after preserving things according to misc_command map. 5646# You should not change it. It is here, nevertheless, to be used 5647# in other function references if needed. 5648sub t2h_default_preserve_misc_command($$) 5649{ 5650 my $line = shift; 5651 my $macro = shift; 5652 my $text = ''; 5653 my $args = []; 5654 my $skip_spec = ''; 5655 my $arg_spec = ''; 5656 5657#print STDERR "HHHHHHHHH $line $macro\n"; 5658 $skip_spec = $misc_command{$macro}->{'skip'} 5659 if (defined($misc_command{$macro}->{'skip'})); 5660 $arg_spec = $misc_command{$macro}->{'arg'} 5661 if (defined($misc_command{$macro}->{'arg'})); 5662 5663 if ($arg_spec eq 'line') 5664 { 5665 $text .= $line; 5666 $args = [ $line ]; 5667 $line = ''; 5668 } 5669 elsif ($arg_spec) 5670 { 5671 my $arg_nr = $misc_command{$macro}->{'arg'}; 5672 while ($arg_nr) 5673 { 5674 $line =~ s/(\s+\S*)//o; 5675 my $argument = $1; 5676 if (defined($argument)) 5677 { 5678 $text .= $argument; 5679 push @$args, $argument; 5680 } 5681 $arg_nr--; 5682 } 5683 } 5684 5685 if ($macro eq 'bye') 5686 { 5687 $line = ''; 5688 $text = "\n"; 5689 } 5690 elsif ($skip_spec eq 'linespace') 5691 { 5692 if ($line =~ /^\s*$/o) 5693 { 5694 $line =~ s/([ \t]*)//o; 5695 $text .= $1; 5696 } 5697 } 5698 elsif ($skip_spec eq 'linewhitespace') 5699 { 5700 if ($line =~ /^\s*$/o) 5701 { 5702 $text .= $line; 5703 $line = ''; 5704 } 5705 } 5706 elsif ($skip_spec eq 'line') 5707 { 5708 $text .= $line; 5709 $line = ''; 5710 } 5711 elsif ($skip_spec eq 'whitespace') 5712 { 5713 $line =~ s/(\s*)//o; 5714 $text .= $1; 5715 } 5716 elsif ($skip_spec eq 'space') 5717 { 5718 $line =~ s/([ \t]*)//o; 5719 $text .= $1; 5720 } 5721 $line = '' if (!defined($line)); 5722 return ($line, $text, $args); 5723} 5724 5725sub t2h_default_simple_command($$$$) 5726{ 5727 my $command = shift; 5728 my $in_preformatted = shift; 5729 my $line_nr = shift; 5730 my $state = shift; 5731 5732 if ($in_preformatted) 5733 { 5734 return $simple_map_pre{$command}; 5735 } 5736 else 5737 { 5738 return $simple_map{$command}; 5739 } 5740} 5741 5742sub t2h_default_thing_command($$$$$) 5743{ 5744 my $command = shift; 5745 my $text = shift; 5746 my $in_preformatted = shift; 5747 my $line_nr = shift; 5748 my $state = shift; 5749 5750 my $result; 5751 if ($in_preformatted) 5752 { 5753 $result = $pre_map{$command}; 5754 } 5755 else 5756 { 5757 $result = $things_map{$command}; 5758 } 5759 return $result . $text; 5760} 5761 5762# this is called each time a format begins. Here it is used to keep a 5763# record of the multitables to have a faithful count of the cell nr. 5764sub t2h_default_begin_format_texi($$$) 5765{ 5766 my $command = shift; 5767 my $line = shift; 5768 my $state = shift; 5769 5770 # first array element is the number of cell in a row 5771 # second is the number of paragraphs in a cell 5772 push (@t2h_default_multitable_stack, [-1,-1]) if ($command eq 'multitable'); 5773 5774 return $line; 5775} 5776 5777# This function is called whenever a complex format is processed 5778# 5779# arguments: 5780# name of the format 5781# text appearing inside the format 5782# 5783# an eval of $complex_format->{format name}->{'begin'} should lead to the 5784# beginning of the complex format, an eval of 5785# $complex_format->{format name}->{'end'} should lead to the end of the 5786# complex format. 5787sub t2h_default_complex_format($$) 5788{ 5789 my $name = shift; 5790 my $text = shift; 5791 return '' if ($text eq ''); 5792 my $beginning = eval "$complex_format_map->{$name}->{'begin'}"; 5793 if ($@ ne '') 5794 { 5795 print STDERR "$ERROR Evaluation of $complex_format_map->{$name}->{'begin'}: $@"; 5796 $beginning = ''; 5797 5798 } 5799 my $end = eval "$complex_format_map->{$name}->{'end'}"; 5800 if ($@ ne '') 5801 { 5802 print STDERR "$ERROR Evaluation of $complex_format_map->{$name}->{'end'}: $@"; 5803 $end = ''; 5804 5805 } 5806 return $beginning . $text . $end; 5807} 5808 5809sub t2h_default_empty_line($$) 5810{ 5811 my $text = shift; 5812 my $state = shift; 5813 #ignore the line if it just follows a deff 5814 return '' if ($state->{'deff_line'}); 5815 return $text; 5816} 5817 5818sub t2h_default_unknown($$$$$) 5819{ 5820 my $macro = shift; 5821 my $line = shift; 5822 my $pass = shift; 5823 my $stack = shift; 5824 my $state = shift; 5825 5826 my ($result_line, $result, $result_text, $message); 5827 return ($line, 0, undef, undef); 5828} 5829 5830sub t2h_default_unknown_style($$$$) 5831{ 5832 my $command = shift; 5833 my $text = shift; 5834 my $state = shift; 5835 5836 my ($result, $result_text, $message); 5837 return (0, undef, undef); 5838} 5839 5840sub t2h_default_caption_shortcaption($) 5841{ 5842 my $float = shift; 5843 my $caption_lines; 5844 my $shortcaption_lines; 5845 my $style = $float->{'style_texi'}; 5846 if (defined($float->{'nr'})) 5847 { 5848 my $nr = $float->{'nr'}; 5849 if ($style ne '') 5850 { 5851 $style = &$I('%{style} %{number}', { 'style' => $style, 'number' => $nr}); 5852 } 5853 else 5854 { 5855 $style = $nr; 5856 } 5857 } 5858 5859 if (defined($float->{'caption_texi'})) 5860 { 5861 @$caption_lines = @{$float->{'caption_texi'}}; 5862 if (defined($style)) 5863 { 5864 $caption_lines->[0] = '@strong{' . &$I('%{style}: %{caption_first_line}', { 'style' => $style, 'caption_first_line' => $caption_lines->[0] }); 5865 } 5866 else 5867 { 5868 $caption_lines->[0] = '@strong{' . $caption_lines->[0]; 5869 } 5870 push @$caption_lines, "}\n"; 5871 } 5872 elsif (defined($style)) 5873 { 5874 $caption_lines->[0] = '@strong{' . $style . '}' . "\n"; 5875 } 5876 if (defined($float->{'shortcaption_texi'})) 5877 { 5878 @$shortcaption_lines = @{$float->{'shortcaption_texi'}}; 5879 if (defined($style)) 5880 { 5881 $shortcaption_lines->[0] = '@strong{' . &$I('%{style}: %{shortcaption_first_line}', { 'style' => $style, 'shortcaption_first_line' => $shortcaption_lines->[0] }); 5882 } 5883 else 5884 { 5885 $shortcaption_lines->[0] = '@strong{' . $shortcaption_lines->[0]; 5886 } 5887 push @$shortcaption_lines, "}\n"; 5888 } 5889 elsif (defined($style)) 5890 { 5891 $shortcaption_lines->[0] = '@strong{' . $style . '}' . "\n"; 5892 } 5893 return ($caption_lines, $shortcaption_lines); 5894} 5895 5896# everything is done in &$float 5897sub t2h_default_caption_shortcaption_command($$$$) 5898{ 5899 my $command = shift; 5900 my $text = shift; 5901 my $texi_lines = shift; 5902 my $float_element = shift; 5903 return ''; 5904} 5905 5906sub t2h_default_float($$$$$) 5907{ 5908 my $text = shift; 5909 my $float = shift; 5910 my $caption = shift; 5911 my $shortcaption = shift; 5912 5913 my $label = ''; 5914 if (exists($float->{'id'})) 5915 { 5916 $label = &$anchor($float->{'id'}); 5917 } 5918 my $caption_text = ''; 5919 5920 if (defined($float->{'caption_texi'})) 5921 { 5922 $caption_text = $caption; 5923 } 5924 elsif (defined($float->{'shortcaption_texi'})) 5925 { 5926 $caption_text = $shortcaption; 5927 } 5928 elsif (defined($caption)) 5929 { 5930 $caption_text = $caption; 5931 } 5932 5933 return '<div class="float">' . "$label\n" . $text . '</div>' . $caption_text; 5934} 5935 5936sub t2h_default_listoffloats_style($) 5937{ 5938 my $style_texi = shift; 5939 return ($style_texi); 5940} 5941 5942sub t2h_default_listoffloats_float_style($$) 5943{ 5944 my $style_texi = shift; 5945 my $float = shift; 5946 5947 my $style = $float->{'style_texi'}; 5948 if (defined($float->{'nr'})) 5949 { 5950 my $nr = $float->{'nr'}; 5951 if ($style ne '') 5952 { 5953 $style = &$I('%{style} %{number}', { 'style' => $style, 'number' => $nr}); 5954 } 5955 else 5956 { 5957 $style = $nr; 5958 } 5959 } 5960 return $style; 5961} 5962 5963sub t2h_default_listoffloats_caption($) 5964{ 5965 my $float = shift; 5966 if (defined($float->{'shortcaption_texi'})) 5967 { 5968 return [ @{$float->{'shortcaption_texi'}} ]; 5969 } 5970 elsif (defined($float->{'caption_texi'})) 5971 { 5972 return [ @{$float->{'caption_texi'}} ]; 5973 } 5974 return [ ]; 5975} 5976 5977sub t2h_default_listoffloats_entry($$$$) 5978{ 5979 my $style_texi = shift; 5980 my $float = shift; 5981 my $float_style = shift; 5982 my $caption = shift; 5983 my $href = shift; 5984 5985 return '<dt>' . &$anchor('', $href, $float_style) . '</dt><dd>' . $caption 5986. '</dd>' . "\n"; 5987} 5988 5989sub t2h_default_listoffloats($$$) 5990{ 5991 my $style_texi = shift; 5992 my $style = shift; 5993 my $float_entries = shift; 5994 5995 my $result = "<dl class=\"listoffloats\">\n" ; 5996 foreach my $float_entry (@$float_entries) 5997 { 5998 $result .= $float_entry; 5999 } 6000 return $result . "</dl>\n"; 6001} 6002 6003sub t2h_default_insertcopying($$$) 6004{ 6005 my $text = shift; 6006 my $comment = shift; 6007 my $simple_text = shift; 6008 return $text; 6009} 6010 6011# This function is used to protect characters which are special in html 6012# in inline text: &, ", <, and >. 6013# 6014# argument: 6015# text to be protected 6016sub t2h_default_protect_text($) 6017{ 6018 my $text = shift; 6019 $text =~ s/&/&/g; 6020 $text =~ s/</</g; 6021 $text =~ s/>/>/g; 6022 $text =~ s/\"/"/g; 6023 return $text; 6024} 6025 6026sub in_cmd($$) 6027{ 6028 my $style_stack = shift; 6029 my $command = shift; 6030 my $result = 0; 6031 if ($style_stack and scalar(@{$style_stack})) 6032 { 6033 my $level = $#$style_stack; 6034 #print STDERR ":::$level ::@{$style_stack}\n"; 6035 while ($level >= 0) 6036 { 6037 if ($style_stack->[$level] eq $command) 6038 { 6039 $result = 1; 6040 last; 6041 } 6042 $level--; 6043 } 6044 } 6045 return $result; 6046} 6047# 6048# 6049 6050sub in_small_caps($) 6051{ 6052 my $style_stack = shift; 6053 my $in_sc = 0; 6054 if ($style_stack and scalar(@{$style_stack})) 6055 { 6056 my $level = $#$style_stack; 6057 #print STDERR ":::$level ::@{$style_stack}\n"; 6058 while ($level >= 0) 6059 { 6060 if ($style_stack->[$level] eq 'sc') 6061 { 6062 $in_sc = 1; 6063 last; 6064 } 6065 $level--; 6066 } 6067 } 6068 return $in_sc; 6069} 6070# 6071# 6072sub t2h_default_normal_text($$$$$$;$) 6073{ 6074 my $text = shift; 6075 my $in_raw_text = shift; # remove_texi 6076 my $in_preformatted = shift; 6077 my $in_code = shift; 6078 my $in_simple = shift; 6079 my $style_stack = shift; 6080 my $state = shift; 6081 $text = uc($text) if (in_cmd($style_stack, 'sc')); 6082 $text = &$protect_text($text) unless($in_raw_text); 6083 if (! $in_code and !$in_preformatted) 6084 { 6085 if ($USE_ISO and !$in_raw_text) 6086 { 6087 $text =~ s/---/\&mdash\;/g; 6088 $text =~ s/--/\&ndash\;/g; 6089 $text =~ s/``/\&ldquo\;/g; 6090 $text =~ s/''/\&rdquo\;/g; 6091 if (! $in_simple) 6092 { # lquot and rquot don't seem to be accepted in title. 6093 $text =~ s/'/$iso_symbols{"'"}/g if (defined ($iso_symbols{"'"})); 6094 $text =~ s/`/$iso_symbols{'`'}/g if (defined ($iso_symbols{'`'})); 6095 } 6096 } 6097 else 6098 { 6099 if ($in_raw_text) #FIXME really do that ? It is done by makeinfo 6100 { 6101 $text =~ s/``/"/g; 6102 $text =~ s/''/"/g; 6103 } 6104 else 6105 { 6106 $text =~ s/``/"/g; 6107 $text =~ s/''/"/g; 6108 # to be like texinfo 6109 #$text =~ s/'/\&rsquo\;/g; 6110 #$text =~ s/`/\&lsquo\;/g; 6111 } 6112 # temporary reuse '' to store --- !.... 6113 # FIXME won't '---' be handled wrongly? 6114 # FIXME really do that in raw text? 6115 $text =~ s/---/''/g; 6116 $text =~ s/--/-/g; 6117 $text =~ s/''/--/g; 6118 } 6119 } 6120 else 6121 { 6122 # to be like texinfo 6123# my $special_code = 0; 6124# $special_code = 1 if (in_cmd($style_stack, 'code') or 6125# in_cmd($style_stack, 'example') or in_cmd($style_stack, 'verbatim')); 6126# $text =~ s/'/\&rsquo\;/g unless ($special_code and exists($main::value{'txicodequoteundirected'})); 6127# $text =~ s/`/\&lsquo\;/g unless ($special_code and exists($main::value{'txicodequotebacktick'})); 6128 } 6129 return $text; 6130} 6131 6132# This function produces an anchor 6133# 6134# arguments: 6135# $name : anchor name 6136# $href : anchor href 6137# text : text displayed 6138# extra_attribs : added to anchor attributes list 6139sub t2h_default_anchor($;$$$) 6140{ 6141 my $name = shift; 6142 my $href = shift; 6143 my $text = shift; 6144 my $attributes = shift; 6145#print STDERR "!$name!$href!$text!$attributes!\n"; 6146 if (!defined($attributes) or ($attributes !~ /\S/)) 6147 { 6148 $attributes = ''; 6149 } 6150 else 6151 { 6152 $attributes = ' ' . $attributes; 6153 } 6154 $name = '' if (!defined($name) or ($name !~ /\S/)); 6155 $href = '' if (!defined($href) or ($href !~ /\S/)); 6156 $text = '' if (!defined($text)); 6157 return $text if (($name eq '') and ($href eq '')); 6158 $name = "name=\"$name\"" if ($name ne ''); 6159 $href = "href=\"$href\"" if ($href ne ''); 6160 $href = ' ' . $href if (($name ne '') and ($href ne '')); 6161#print STDERR "!!!$name!$href!$text!$attributes!\n"; 6162 return "<a ${name}${href}${attributes}>$text</a>"; 6163} 6164 6165# This function is used to format the text associated with a @deff/@end deff 6166# 6167# argument: 6168# text 6169# 6170# $DEF_TABLE should be used to distinguish between @def formatted as table 6171# and as definition lists. 6172sub t2h_default_def_item($$) 6173{ 6174 my $text = shift; 6175 my $only_inter_item_commands = shift; 6176 if ($text =~ /\S/) 6177 { 6178 if (! $DEF_TABLE) 6179 { 6180 return '<dd>' . $text . '</dd>';# unless $only_inter_item_commands; 6181 #return $text; # invalid without dd in ul 6182 } 6183 else 6184 { 6185# return '<tr><td colspan="2">' . $text . '</td></tr>'; ###GAMBIT### 6186 return $text; 6187 } 6188 } 6189 return ''; 6190} 6191 6192sub t2h_default_definition_category($$$$) 6193{ 6194 my $name = shift; 6195 my $class = shift; 6196 my $style = shift; 6197 my $command = shift; 6198 return ($name) if (!defined($class) or $class =~ /^\s*$/); 6199 if ($style eq 'f') 6200 { 6201 return &$I('%{name} on %{class}', { 'name' => $name, 'class' => $class }); 6202 } 6203 elsif ($style eq 'v') 6204 { 6205 return &$I('%{name} of %{class}', { 'name' => $name, 'class' => $class }); 6206 } 6207 else 6208 { 6209 return $name; 6210 } 6211} 6212 6213sub t2h_default_definition_index_entry($$$$) 6214{ 6215 my $name = shift; 6216 my $class = shift; 6217 my $style = shift; 6218 my $command = shift; 6219 return ($name) if (!defined($class) or $class =~ /^\s*$/); 6220 if ($style eq 'f') 6221 { 6222 return &$I('%{name} on %{class}', { 'name' => $name, 'class' => $class }); 6223 } 6224 elsif ($style eq 'v' and $command ne 'defcv') 6225 { 6226 return &$I('%{name} of %{class}', { 'name' => $name, 'class' => $class }); 6227 } 6228 else 6229 { 6230 return $name; 6231 } 6232} 6233 6234# format the container for the @deffn line and text 6235# 6236# argument 6237# text of the whole @def, line and associated text. 6238# 6239# $DEF_TABLE should be used. 6240sub t2h_default_def($) 6241{ 6242 my $text = shift; 6243 if ($text =~ /\S/) 6244 { 6245 if (! $DEF_TABLE) 6246 { 6247 return "<dl>\n" . $text . "</dl>\n"; 6248 } 6249 else 6250 { 6251# return "<table width=\"100%\">\n" . $text . "</table>\n"; ###GAMBIT### move table to each definition 6252 return $text . "\n"; 6253 } 6254 } 6255 return ''; 6256 6257} 6258 6259# tracks menu entry index 6260my $menu_entry_index; 6261 6262# a whole menu 6263# 6264# argument: 6265# the whole menu text (entries and menu comments) 6266# 6267# argument: 6268# whole menu text. 6269sub t2h_default_menu_command($$$) 6270{ 6271 my $format = shift; 6272 my $text = shift; 6273 my $in_preformatted = shift; 6274 6275 $menu_entry_index=0; 6276 6277 my $begin_row = ''; 6278 my $end_row = ''; 6279 if ($in_preformatted) 6280 { 6281 $begin_row = '<tr><td>'; 6282 $end_row = '</td></tr>'; 6283 } 6284 if ($text =~ /\S/) 6285 { 6286 return $text if ($format eq 'detailmenu'); 6287 return "<table class=\"menu\" border=\"0\" cellspacing=\"0\">${begin_row}\n" 6288 . $text . "${end_row}</table>\n"; 6289 } 6290} 6291 6292# obsolete 6293# a simple menu entry ref in case we aren't in a standard menu context 6294#sub t2h_default_simple_menu_link($$$$$$$) 6295#{ 6296# my $entry = shift; 6297# my $preformatted = shift; 6298# my $href = shift; 6299# my $node = shift; 6300# my $title = shift; 6301# my $ending = shift; 6302# my $has_title = shift; 6303# $title = '' unless($has_title); 6304# $ending = '' if (!defined($ending)); 6305# if (($entry eq '') or $NODE_NAME_IN_MENU or $preformatted) 6306# { 6307# $title .= ':' if ($title ne ''); 6308# $entry = "$MENU_SYMBOL$title$node"; 6309# } 6310# $menu_entry_index++; 6311# my $accesskey; 6312# $accesskey = "accesskey=\"$menu_entry_index\"" if ($USE_ACCESSKEY and ($menu_entry_index < 10)); 6313# $entry = &$anchor('', $href, $entry, $accesskey) if ($href); 6314# $entry .= $ending if ($preformatted); 6315# $entry .= ' ' unless $preformatted; 6316# return $entry; 6317#} 6318 6319# formats a menu entry link pointing to a node or section 6320# 6321# arguments: 6322# the entry text 6323# the state, a hash reference holding informations about the context, with a 6324# usefull entry, 'preformatted', true if we are in a preformatted format 6325# (a format keeping space between words). In that case a function 6326# of the main program, main::do_preformatted($text, $state) might 6327# be used to format the text with the current format style. 6328# href is optionnal. It is the reference to the section or the node anchor 6329# which should be used to make the link (typically it is the argument 6330# of a href= attribute in a <a> element). 6331sub t2h_default_menu_link($$$$$$$$) 6332{ 6333 my $entry = shift; 6334 my $state = shift; 6335 my $href = shift; 6336 my $node = shift; 6337 my $title = shift; 6338 my $ending = shift; 6339 my $has_title = shift; 6340 my $command_stack = shift; 6341 my $preformatted = shift; 6342 6343 my $in_commands = 0; 6344 $in_commands = 1 if ($command_stack->[-1] and $command_stack->[-1] ne 'menu' and $command_stack->[-1] ne 'detailmenu'); 6345 6346 $title = '' unless ($has_title); 6347#print STDERR "MENU_LINK($in_commands)($state->{'preformatted'})\n"; 6348 if (($entry eq '') or $NODE_NAME_IN_MENU or $preformatted) 6349 { 6350 $title .= ':' if ($title ne ''); 6351 $entry = "$MENU_SYMBOL$title$node"; 6352 } 6353 $menu_entry_index++; 6354 my $accesskey; 6355 $accesskey = "accesskey=\"$menu_entry_index\"" if ($USE_ACCESSKEY and ($menu_entry_index < 10)); 6356 $entry = &$anchor ('', $href, $entry, $accesskey) if (defined($href)); 6357 6358 return $entry.$ending if ($preformatted); 6359 return $entry .' ' if ($in_commands); 6360 return "<tr><td align=\"left\" valign=\"top\">$entry</td><td> </td>"; 6361} 6362 6363sub simplify_text($) 6364{ 6365 my $text = shift; 6366 $text =~ s/[^\w]//og; 6367 return $text; 6368} 6369 6370# formats a menu entry description, ie the text appearing after the node 6371# specification in a menu entry an spanning until there is another 6372# menu entry, an empty line or some text at the very beginning of the line 6373# (we consider that text at the beginning of the line begins a menu comment) 6374# 6375# arguments: 6376# the description text 6377# the state. See menu_entry. 6378# the heading of the element associated with the node. 6379sub t2h_default_menu_description($$$$) 6380{ 6381 my $text = shift; 6382 my $state = shift; 6383 my $element_text = shift; 6384 my $command_stack = shift; 6385 my $preformatted = shift; 6386 6387 my $in_commands = 0; 6388 $in_commands = 1 if ($command_stack->[-1] and $command_stack->[-1] ne 'menu' and $command_stack->[-1] ne 'detailmenu'); 6389 return $text if ($preformatted or $in_commands); 6390 # FIXME: the following is better-looking. 6391 #return $text."<br>" if ($in_commands and !$state->{'preformatted'}); 6392 if ($AVOID_MENU_REDUNDANCY) 6393 { 6394 $text = '' if (simplify_text($element_text) eq simplify_text($text)); 6395 } 6396 return "<td align=\"left\" valign=\"top\">$text</td></tr>\n"; 6397} 6398 6399# a menu comment (between menu lines, obsolete) 6400# formats the container of a menu comment. A menu comment is any text 6401# appearing between menu lines, either separated by an empty line from 6402# the preceding menu entry, or a text beginning at the first character 6403# of the line (text not at the very beginning of the line is considered to 6404# be the continuation of a menu entry description text). 6405# 6406# The text itself is considered to be in a preformatted environment 6407# with name 'menu-commment' and with style $MENU_PRE_STYLE. 6408# 6409# argument 6410# text contained in the menu comment. 6411#sub t2h_default_menu_comment($) 6412#{ 6413# my $text = shift; 6414# return $text if ($SIMPLE_MENU); 6415# if ($text =~ /\S/) 6416# { 6417# return "<tr><th colspan=\"3\" align=\"left\" valign=\"top\">$text</th></tr>"; 6418# } 6419# return ''; 6420#} 6421 6422# Construct a href to an external source of information. 6423# node is the node with texinfo @-commands 6424# node_id is the node transliterated and transformed as explained in the 6425# texinfo manual 6426# node_xhtml_id is the node transformed such that it is unique and can 6427# be used to make an html cross ref as explained in the texinfo manual 6428# file is the file in '(file)node' 6429sub t2h_default_external_href($$$) 6430{ 6431 my $node = shift; 6432 my $node_id = shift; 6433 my $node_xhtml_id = shift; 6434 my $file = shift; 6435 $file = '' if (!defined($file)); 6436 my $default_target_split = $Texi2HTML::THISDOC{'EXTERNAL_CROSSREF_SPLIT'}; 6437 my $target_split; 6438 my $target_mono; 6439 my $href_split; 6440 my $href_mono; 6441 if ($file ne '') 6442 { 6443 if ($NEW_CROSSREF_STYLE) 6444 { 6445 $file =~ s/\.[^\.]*$//; 6446 $file =~ s/^.*\///; 6447 my $href; 6448 if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file})) 6449 { 6450 if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file}->{'split'})) 6451 { 6452 $target_split = 1; 6453 $href_split = $Texi2HTML::THISDOC{'htmlxref'}->{$file}->{'split'}->{'href'}; 6454 } 6455 if (exists($Texi2HTML::THISDOC{'htmlxref'}->{$file}->{'mono'})) 6456 { 6457 $target_mono = 1; 6458 $href_mono = $Texi2HTML::THISDOC{'htmlxref'}->{$file}->{'mono'}->{'href'}; 6459 } 6460 } 6461 6462 if ((not $target_mono) and (not $target_split)) 6463 { # nothing specified for that manual, use default 6464 $target_split = $default_target_split; 6465 } 6466 elsif ($target_split and $target_mono) 6467 { # depends on the splitting of the manual 6468 $target_split = $SPLIT; 6469 } 6470 elsif ($target_mono) 6471 { # only mono specified 6472 $target_split = 0; 6473 } 6474 6475 if ($target_split) 6476 { 6477 if (defined($href_split)) 6478 { 6479 $file = "$href_split"; 6480 } 6481 elsif (defined($EXTERNAL_DIR)) 6482 { 6483 $file = "$EXTERNAL_DIR/$file"; 6484 } 6485 elsif ($SPLIT) 6486 { 6487 $file = "../$file"; 6488 } 6489 $file .= "/"; 6490 } 6491 else 6492 {# target not split 6493 if (defined($href_mono)) 6494 { 6495 $file = "$href_mono"; 6496 } 6497 else 6498 { 6499 if (defined($EXTERNAL_DIR)) 6500 { 6501 $file = "$EXTERNAL_DIR/$file"; 6502 } 6503 elsif ($SPLIT) 6504 { 6505 $file = "../$file"; 6506 } 6507 $file .= "." . $NODE_FILE_EXTENSION; 6508 } 6509 } 6510 } 6511 else 6512 { 6513 $file .= "/"; 6514 if (defined($EXTERNAL_DIR)) 6515 { 6516 $file = $EXTERNAL_DIR . $file; 6517 } 6518 else 6519 { 6520 $file = '../' . $file; 6521 } 6522 } 6523 } 6524 else 6525 { 6526 $target_split = $default_target_split; 6527 } 6528 if ($node eq '') 6529 { 6530 if ($NEW_CROSSREF_STYLE) 6531 { 6532 if ($target_split) 6533 { 6534 return $file . $TOP_NODE_FILE . '.' . $NODE_FILE_EXTENSION . '#Top'; 6535 # or ? 6536 #return $file . '#Top'; 6537 } 6538 else 6539 { 6540 return $file . '#Top'; 6541 } 6542 } 6543 else 6544 { 6545 return $file; 6546 } 6547 } 6548 my $target; 6549 if ($NEW_CROSSREF_STYLE) 6550 { 6551 $node = $node_id; 6552 $target = $node_xhtml_id; 6553 } 6554 else 6555 { 6556 $node = main::remove_texi($node); 6557 $node =~ s/[^\w\.\-]/-/g; 6558 } 6559 my $file_basename = $node; 6560 $file_basename = $TOP_NODE_FILE if ($node =~ /^top$/i); 6561 if ($NEW_CROSSREF_STYLE) 6562 { 6563 if ($target_split) 6564 { 6565 return $file . $file_basename . ".$NODE_FILE_EXTENSION" . '#' . $target; 6566 } 6567 else 6568 { 6569 return $file . '#' . $target; 6570 } 6571 } 6572 else 6573 { 6574 return $file . $file_basename . ".$NODE_FILE_EXTENSION"; 6575 } 6576} 6577 6578# format a reference external to the generated manual. This produces a full 6579# reference with introductive words and the reference itself. 6580# 6581# arguments: 6582# type of the reference: xref (reference at the beginning of a sentence), 6583# pxref (reference in a parenthesis), 6584# section in the book. This might be undef. 6585# book name. 6586# node and file name formatted according to the convention used in info 6587# '(file)node' and no node means the Top node. 6588# href linking to the html page containing the referenced node. A typical 6589# use for this href is a href attribute in an <a> element 6590# an optionnal cross reference name 6591sub t2h_default_external_ref($$$$$$$$) 6592{ 6593 my $type = shift; 6594 my $section = shift; 6595 my $book = shift; 6596 my $file_node = shift; 6597 my $href = shift; 6598 my $cross_ref = shift; 6599 my $args_texi = shift; 6600 my $formatted_args = shift; 6601 6602 $file_node = "$cross_ref: $file_node" if (($file_node ne '') and ($cross_ref ne '')); 6603 $file_node = &$anchor('', $href, $file_node) if ($file_node ne ''); 6604 6605 # Yes, this is ugly, but this helps internationalization 6606 if ($type eq 'pxref') 6607 { 6608 if (($book ne '') and ($file_node ne '')) 6609 { 6610 return &$I('see %{node_file_href} section `%{section}\' in @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne ''); 6611 return &$I('see %{node_file_href} @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book },{'duplicate'=>1}); 6612 } 6613 elsif ($book ne '') 6614 { 6615 return &$I('see section `%{section}\' in @cite{%{book}}', { 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne ''); 6616 return &$I('see @cite{%{book}}', { 'book' => $book },{'duplicate'=>1}); 6617 } 6618 elsif ($file_node ne '') 6619 { 6620 return &$I('see %{node_file_href}', { 'node_file_href' => $file_node },{'duplicate'=>1}); 6621 } 6622 } 6623 if ($type eq 'xref' or $type eq 'inforef') 6624 { 6625 if (($book ne '') and ($file_node ne '')) 6626 { 6627 return &$I('See %{node_file_href} section `%{section}\' in @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne ''); 6628 return &$I('See %{node_file_href} @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book },{'duplicate'=>1}); 6629 } 6630 elsif ($book ne '') 6631 { 6632 return &$I('See section `%{section}\' in @cite{%{book}}', { 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne ''); 6633 return &$I('See @cite{%{book}}', { 'book' => $book },{'duplicate'=>1}); 6634 } 6635 elsif ($file_node ne '') 6636 { 6637 return &$I('See %{node_file_href}', { 'node_file_href' => $file_node },{'duplicate'=>1}); 6638 } 6639 } 6640 if ($type eq 'ref') 6641 { 6642 if (($book ne '') and ($file_node ne '')) 6643 { 6644 return &$I('%{node_file_href} section `%{section}\' in @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne ''); 6645 return &$I('%{node_file_href} @cite{%{book}}', { 'node_file_href' => $file_node, 'book' => $book },{'duplicate'=>1}); 6646 } 6647 elsif ($book ne '') 6648 { 6649 return &$I('section `%{section}\' in @cite{%{book}}', { 'book' => $book, 'section' => $section },{'duplicate'=>1}) if ($section ne ''); 6650 return &$I('@cite{%{book}}', { 'book' => $book },{'duplicate'=>1}); 6651 } 6652 elsif ($file_node ne '') 6653 { 6654 return &$I('%{node_file_href}', { 'node_file_href' => $file_node },{'duplicate'=>1}); 6655 } 6656 } 6657 return ''; 6658} 6659 6660# format a reference to a node or a section in the generated manual. This 6661# produces a full reference with introductive words and the reference itself. 6662# 6663# arguments: 6664# type of the reference: xref (reference at the beginning of a sentence), 6665# pxref (reference in a parenthesis), 6666# href linking to the html page containing the node or the section. A typical 6667# use for this href is a href attribute in an <a> element 6668# short name for this reference 6669# name for this reference 6670# boolean true if the reference is a reference to a section 6671# 6672# $SHORT_REF should be used. 6673sub t2h_default_internal_ref($$$$$$$) 6674{ 6675 my $type = shift; 6676 my $href = shift; 6677 my $short_name = shift; 6678 my $name = shift; 6679 my $is_section = shift; 6680 my $args_texi = shift; 6681 my $formatted_args = shift; 6682 6683 if (! $SHORT_REF) 6684 { 6685 $name = &$anchor('', $href, $name); 6686 if ($type eq 'pxref') 6687 { 6688 return &$I('see section %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}) if ($is_section); 6689 return &$I('see %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); 6690 } 6691 elsif ($type eq 'xref' or $type eq 'inforef') 6692 { 6693 return &$I('See section %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}) if ($is_section); 6694 return &$I('See %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); 6695 } 6696 elsif ($type eq 'ref') 6697 { 6698 return &$I('%{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); 6699 } 6700 } 6701 else 6702 { 6703 $name = &$anchor('', $href, $short_name); 6704 if ($type eq 'pxref') 6705 { 6706 return &$I('see %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); 6707 } 6708 elsif ($type eq 'xref' or $type eq 'inforef') 6709 { 6710 return &$I('See %{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); 6711 } 6712 elsif ($type eq 'ref') 6713 { 6714 return &$I('%{reference_name}', { 'reference_name' => $name },{'duplicate'=>1}); 6715 } 6716 } 6717 return ''; 6718} 6719 6720sub teletyped_in_stack($) 6721{ 6722 my $stack = shift; 6723 foreach my $element(reverse(@$stack)) 6724 { 6725 return 1 if ($complex_format_map->{$element} and 6726 $complex_format_map->{$element}->{'style'} and 6727 $complex_format_map->{$element}->{'style'} eq 'code'); 6728 } 6729 return 0; 6730} 6731 6732# text after @item in table, vtable and ftable 6733sub t2h_default_table_item($$$$$$$$$) 6734{ 6735 my $text = shift; 6736 my $index_label = shift; 6737 my $format = shift; 6738 my $command = shift; 6739 my $formatted_command = shift; 6740 my $style_stack = shift; 6741 my $text_formatted = shift; 6742 my $text_formatted_leading_spaces = shift; 6743 my $text_formatted_trailing_spaces = shift; 6744 my $item_cmd = shift; 6745 6746 #print STDERR "-> $format (@$style_stack)\n"; 6747 if (defined($text_formatted) and !exists $special_list_commands{$format}->{$command}) 6748 { 6749 $text = $text_formatted_leading_spaces . $text_formatted .$text_formatted_trailing_spaces; 6750 } 6751 $formatted_command = '' if (!defined($formatted_command) or 6752 exists($special_list_commands{$format}->{$command})); 6753 if (teletyped_in_stack($style_stack)) 6754 { 6755 $text .= '</tt>'; 6756 $formatted_command = '<tt>' . $formatted_command; 6757 } 6758 $text .= "\n" . $index_label if (defined($index_label)); 6759 return '<dt>' . $formatted_command . $text . '</dt>' . "\n"; 6760} 6761 6762# format text on the line following the @item line (in table, vtable and ftable) 6763sub t2h_default_table_line($$$) 6764{ 6765 my $text = shift; 6766 my $only_inter_item_commands = shift; 6767 my $before_items = shift; 6768 6769 $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); 6770 6771 if ($text =~ /\S/) 6772 { 6773 return '<dd>' . $text . '</dd>' . "\n";# unless ($only_inter_item_commands); 6774 #return $text; # invalid without dd in ul 6775 } 6776 return ''; 6777} 6778 6779#my $cell_nr = -1; 6780 6781# row in multitable 6782sub t2h_default_row($$$$$$$$) 6783{ 6784 my $text = shift; 6785 my $macro = shift; 6786 my $columnfractions = shift; 6787 my $prototype_row = shift; 6788 my $prototype_lengths = shift; 6789 my $column_number = shift; 6790 my $only_inter_item_commands = shift; 6791 my $before_items = shift; 6792 6793 $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); 6794 6795 # this is used to keep the cell number 6796 $t2h_default_multitable_stack[-1]->[0] = -1; 6797 6798 if ($text =~ /\S/) 6799 { 6800 if ($macro eq 'headitem') 6801 { 6802 return '<thead><tr>' . $text . '</tr></thead>' . "\n"; 6803 } 6804 return '<tr>' . $text . '</tr>' . "\n"; 6805 } 6806 return ''; 6807} 6808 6809# cell in multitable 6810sub t2h_default_cell($$$$$$$$) 6811{ 6812 my $text = shift; 6813 my $row_macro = shift; 6814 my $columnfractions = shift; 6815 my $prototype_row = shift; 6816 my $prototype_lengths = shift; 6817 my $column_number = shift; 6818 my $only_inter_item_commands = shift; 6819 my $before_items = shift; 6820 6821 $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); 6822 6823 $t2h_default_multitable_stack[-1]->[0]++; 6824 my $cell_nr = $t2h_default_multitable_stack[-1]->[0]; 6825 my $fractions = ''; 6826 6827 if (defined($columnfractions) and (ref($columnfractions) eq 'ARRAY') 6828 and exists($columnfractions->[$cell_nr])) 6829 { 6830 my $fraction = sprintf('%d', 100*$columnfractions->[$cell_nr]); 6831 $fractions = " width=\"$fraction%\""; 6832 } 6833 6834 # in constructs like 6835 # @strong{ 6836 # @multitable .... 6837 # } 6838 # the space won't be removed since the <strong> is put before the space. 6839 $text =~ s/^\s*//; 6840 $text =~ s/\s*$//; 6841 6842 if ($row_macro eq 'headitem') 6843 { 6844 return "<th${fractions}>" . $text . '</th>'; 6845 } 6846 return "<td${fractions}>" . $text . '</td>'; 6847} 6848 6849sub t2h_default_format_list_item_texi($$$$) 6850{ 6851 my $format = shift; 6852 my $line = shift; 6853 my $prepended = shift; 6854 my $command = shift; 6855 6856 my $result_line; 6857 my $open_command = 0; 6858 6859 if (defined($prepended) and $prepended ne '') 6860 { 6861 $result_line = $prepended . ' ' . $line; 6862 } 6863 $open_command = 1 if (defined($command)); 6864 return ($result_line, $open_command); 6865} 6866 6867 6868# format an item in a list 6869# 6870# argument: 6871# text of the item 6872# format of the list (itemize or enumerate) 6873# command passed as argument to the format 6874# formatted_command leading command formatted, if it is a thing command 6875sub t2h_default_list_item($$$$$$$$$$$) 6876{ 6877 my $text = shift; 6878 my $format = shift; 6879 my $command = shift; 6880 my $formatted_command = shift; 6881 my $item_nr = shift; 6882 my $enumerate_style = shift; 6883 my $number = shift; 6884 my $prepended = shift; 6885 my $prepended_formatted = shift; 6886 my $only_inter_item_commands = shift; 6887 my $before_items = shift; 6888 6889 $only_inter_item_commands = '' if (!defined($only_inter_item_commands)); 6890 6891 $formatted_command = '' if (!defined($formatted_command) or 6892 exists($special_list_commands{$format}->{$command})); 6893 my $prepend = ''; 6894# if (defined($prepended) and $prepended ne '') 6895# { 6896# $prepend = $prepended; 6897# } 6898# elsif ($formatted_command ne '') 6899 if ($formatted_command ne '') 6900 { 6901 $prepend = $formatted_command; 6902 } 6903 if ($text =~ /\S/) 6904 { 6905 return '<li>' . $prepend . $text . '</li>'; 6906 } 6907 return ''; 6908} 6909 6910sub t2h_default_table_list($$$$$$$$$) 6911{ 6912 my $format_command = shift; 6913 my $text = shift; 6914 my $command = shift; 6915 my $formatted_command = shift; 6916# enumerate 6917 my $item_nr = shift; 6918 my $enumerate_style = shift; 6919# itemize 6920 my $prepended = shift; 6921 my $prepended_formatted = shift; 6922# multitable 6923 my $columnfractions = shift; 6924 my $prototype_row = shift; 6925 my $prototype_lengths = shift; 6926 my $column_number = shift; 6927# my $number = shift; 6928 $formatted_command = '' if (!defined($formatted_command) or 6929 exists($special_list_commands{$format}->{$command})); 6930 if ($format_command eq 'itemize') 6931 { 6932 return "<ul>\n" . $text . "</ul>\n" if (($command eq 'bullet') or (($command eq '') and ($prepended eq ''))); 6933 return "<ul$NO_BULLET_LIST_ATTRIBUTE>\n" . $text . "</ul>\n"; 6934 } 6935 elsif ($format_command eq 'multitable') 6936 { 6937 pop @t2h_default_multitable_stack; 6938 return &$format('multitable', 'table', $text); 6939 } 6940} 6941 6942# an html comment 6943sub t2h_default_comment($) 6944{ 6945 my $text = shift; 6946 $text =~ s/--+/-/go; 6947 return '<!-- ' . $text . ' -->' . "\n"; 6948} 6949 6950sub t2h_collect_styles($) 6951{ 6952 my $cmd_stack = shift; 6953 my @result = (); 6954 foreach my $style (reverse(@$cmd_stack)) 6955 { 6956# last unless (defined($command_type{$style}) and $command_type{$style} eq 'style'); 6957 push @result, $style if (defined($command_type{$style}) and $command_type{$style} eq 'style'); 6958 } 6959 return @result; 6960} 6961 6962sub t2h_get_attribute($;$) 6963{ 6964 my $command = shift; 6965 my $map_ref = shift; 6966 $map_ref = \%style_map if (!defined($map_ref)); 6967 return '' unless (defined($map_ref->{$command})); 6968 if ((ref($map_ref->{$command}) eq 'HASH') 6969 and exists($map_ref->{$command}->{'attribute'})) 6970 { 6971 return $map_ref->{$command}->{'attribute'}; 6972 } 6973 elsif ($map_ref->{$command} !~ /^&/) 6974 { 6975 my $attribute = $map_ref->{$command}; 6976 $attribute =~ s/^\"//; 6977 return $attribute; 6978 } 6979 return ''; 6980} 6981 6982sub t2h_begin_style($$;$) 6983{ 6984 my $command = shift; 6985 my $text = shift; 6986 my $map_ref = shift; 6987 my $attribute = t2h_get_attribute($command,$map_ref); 6988 $attribute = "<$attribute>" if ($attribute ne ''); 6989 return $attribute.$text; 6990} 6991 6992sub t2h_end_style($$;$) 6993{ 6994 my $command = shift; 6995 my $text = shift; 6996 my $map_ref = shift; 6997 my $attribute = t2h_get_attribute($command,$map_ref); 6998 if ($attribute =~ /^(\w+)/) 6999 { 7000 $attribute = $1; 7001 } 7002 $attribute = "</$attribute>" if ($attribute ne ''); 7003 return $text.$attribute; 7004} 7005 7006# a paragraph 7007# arguments: 7008# $text of the paragraph 7009# $align for the alignement 7010# $indent for the indent style (indent or noindent) 7011# The following is usefull if the paragraph is in an itemize. 7012# $paragraph_command is the leading formatting command (like @minus) 7013# $paragraph_command_formatted is the leading formatting command formatted 7014# $paragraph_number is a reference on the number of paragraphs appearing 7015# in the format. The value should be increased if a paragraph is done 7016# $format is the format name (@itemize) 7017sub t2h_default_paragraph($$$$$$$$$$$$) 7018{ 7019 my $text = shift; 7020 my $align = shift; 7021 my $indent = shift; 7022 my $paragraph_command = shift; 7023 my $paragraph_command_formatted = shift; 7024 my $paragraph_number = shift; 7025 my $format = shift; 7026 my $item_nr = shift; 7027 my $enumerate_style = shift; 7028 my $number = shift; 7029 my $command_stack_at_end = shift; 7030 my $command_stack_at_begin = shift; 7031#print STDERR "format: $format\n" if (defined($format)); 7032#print STDERR "paragraph @$command_stack_at_end; @$command_stack_at_begin\n"; 7033 $paragraph_command_formatted = '' if (!defined($paragraph_command_formatted) or 7034 exists($special_list_commands{$format}->{$paragraph_command})); 7035 return '' if ($text =~ /^\s*$/); 7036 7037 foreach my $style(t2h_collect_styles($command_stack_at_begin)) 7038 { 7039 $text = t2h_begin_style($style, $text); 7040 } 7041 foreach my $style(t2h_collect_styles($command_stack_at_end)) 7042 { 7043 $text = t2h_end_style($style, $text); 7044 } 7045 7046 if (defined($paragraph_number) and defined($$paragraph_number)) 7047 { 7048 $$paragraph_number++; 7049 return $text if (($format eq 'itemize' or $format eq 'enumerate') and 7050 ($$paragraph_number == 1)); 7051 } 7052 7053 my $top_stack = ''; 7054 $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin)); 7055 if ($top_stack eq 'multitable') 7056 { 7057 $t2h_default_multitable_stack[-1]->[1]++; 7058 if ($t2h_default_multitable_stack[-1]->[1] == 0) 7059 { 7060 return $text; 7061 } 7062 } 7063 7064 my $open = '<p>'; 7065 if ($align) 7066 { 7067 $open = "<p align=\"$paragraph_style{$align}\">"; 7068 } 7069 return $open.$text.'</p>'; 7070} 7071 7072# a preformatted region 7073# arguments: 7074# $text of the preformatted region 7075# $pre_style css style 7076# $class identifier for the preformatted region (example, menu-comment) 7077# The following is usefull if the preformatted is in an itemize. 7078# $leading_command is the leading formatting command (like @minus) 7079# $leading_command_formatted is the leading formatting command formatted 7080# $preformatted_number is a reference on the number of preformatteds appearing 7081# in the format. The value should be increased if a preformatted is done 7082sub t2h_default_preformatted($$$$$$$$$$$$) 7083{ 7084 my $text = shift; 7085 my $pre_style = shift; 7086 my $class = shift; 7087 my $leading_command = shift; 7088 my $leading_command_formatted = shift; 7089 my $preformatted_number = shift; 7090 my $format = shift; 7091 my $item_nr = shift; 7092 my $enumerate_style = shift; 7093 my $number = shift; 7094 my $command_stack_at_end = shift; 7095 my $command_stack_at_begin = shift; 7096 7097#print STDERR "preformatted @$command_stack_at_end; @$command_stack_at_begin\n"; 7098 return '' if ($text eq ''); 7099 $leading_command_formatted = '' if (!defined($leading_command_formatted) or 7100 exists($special_list_commands{$format}->{$leading_command})); 7101 if (defined($preformatted_number) and defined($$preformatted_number)) 7102 { 7103 $$preformatted_number++; 7104 } 7105 my $top_stack = ''; 7106 $top_stack = $command_stack_at_begin->[-1] if (scalar (@$command_stack_at_begin)); 7107 if ($top_stack eq 'multitable') 7108 { 7109 $text =~ s/^\s*//; 7110 $text =~ s/\s*$//; 7111 } 7112 7113 foreach my $style(t2h_collect_styles($command_stack_at_begin)) 7114 { 7115 $text = t2h_begin_style($style, $text, \%style_map_pre); 7116 } 7117 foreach my $style(t2h_collect_styles($command_stack_at_end)) 7118 { 7119 $text = t2h_end_style($style, $text, \%style_map_pre); 7120 } 7121 return "<pre class=\"$class\">".$text."</pre>"; 7122} 7123 7124# This function formats a heading for an element 7125# 7126# argument: 7127# an element. It is a hash reference for a node or a sectionning command. 7128# it may be the wrong one in case of headings. 7129# The interesting keys are: 7130# 'text': the heading text 7131# 'text_nonumber': the heading text without section number 7132# 'node': true if it is a node 7133# 'level': level of the element. 0 for @top, 1 for chapter, heading, 7134# appendix..., 2 for section and so on... 7135# 'tag_level': the sectionning element name, raisesections and lowersections 7136# taken into account 7137sub t2h_default_element_heading($$$$$$$$$$$$) 7138{ 7139 my $element = shift; 7140 my $command = shift; 7141 my $texi_line = shift; 7142 my $line = shift; 7143 my $in_preformatted = shift; 7144 my $one_section = shift; 7145 my $element_heading = shift; 7146 my $first_in_page = shift; 7147 my $is_top = shift; 7148 my $previous_is_top = shift; 7149 my $command_line = shift; 7150 my $element_id = shift; 7151 my $new_element = shift; 7152#print STDERR ":::::::: $element $command i_p $in_preformatted o_s $one_section e_h $element_heading f_p $first_in_page i_t $is_top p_i_t $previous_is_top id $element_id new $new_element\n"; 7153 7154 my $result = &$element_label($element_id, $element, $command, $command_line); 7155 if ($new_element and !$one_section) 7156 { 7157 if (!$element->{'element_ref'}->{'top'}) 7158 { 7159 #return $result if (defined($command) and $command eq 'node' and !$element_heading); 7160 $result .= &$print_element_header($first_in_page, $previous_is_top); 7161 } 7162 else 7163 { 7164 $result .= &$print_head_navigation(undef, \@MISC_BUTTONS) if ($SPLIT or $SECTION_NAVIGATION); 7165 } 7166 } 7167 7168 return $result if (!$element_heading); 7169 return $result. &$heading($element, $command, $texi_line, $line, $in_preformatted, $one_section, $element_heading); 7170} 7171 7172sub t2h_default_heading($$$$$;$$) 7173{ 7174 my $element = shift; 7175 my $command = shift; 7176 my $texi_line = shift; 7177 my $line = shift; 7178 my $in_preformatted = shift; 7179 my $one_section = shift; 7180 my $element_heading = shift; 7181 7182 my $level = 3; 7183 if (!$element->{'node'}) 7184 { 7185 $level = $element->{'level'}; 7186 } 7187 my $text = $element->{'text'}; 7188 my $class = $element->{'tag_level'}; 7189 $class = 'unnumbered' if ($class eq 'top'); 7190 my $align = ''; 7191 $align = ' align="center"' if ($element->{'tag'} eq 'centerchap'); 7192 if ($element->{'top'}) 7193 { 7194 return '' if ($element->{'titlefont'}); 7195 $level = 1; 7196 $text = $Texi2HTML::NAME{'Top'}; 7197 $class = 'settitle' unless ($one_section); 7198 } 7199 # when it is a heading, the element is irrelevant, so the command and the 7200 # line are used... 7201 if (defined($command) and $command =~ /heading/) 7202 { 7203 $level = $main::sec2level{$command} if (defined($main::sec2level{$command})); 7204 if (defined($line)) 7205 { 7206 $text = $line; 7207 # this isn't done in main program in that case... 7208 chomp ($text); 7209 $text =~ s/^\s*//; 7210 } 7211 $class = $command; 7212 } 7213 elsif (defined($element->{'tocid'}) and $TOC_LINKS) 7214 { 7215 $text = &$anchor ('', "$Texi2HTML::THISDOC{'toc_file'}#$element->{'tocid'}", $text); 7216 } 7217 $level = 1 if ($level == 0); 7218 return '' if ($text !~ /\S/); 7219 if (!$in_preformatted) 7220 { 7221 return "<h$level class=\"$class\"$align>$text</h$level>\n"; 7222 } 7223 else 7224 { 7225 return "<strong>$text</strong>\n"; 7226 } 7227} 7228 7229sub t2h_default_heading_no_texi($$$) 7230{ 7231 my $element = shift; 7232 my $command = shift; 7233 my $line = shift; 7234 return main::remove_texi($line); 7235} 7236 7237# formatting of raw regions 7238# if L2H is true another mechanism is used for tex 7239sub t2h_default_raw($$) 7240{ 7241 my $style = shift; 7242 my $text = shift; 7243 if ($style eq 'verbatim' or $style eq 'tex') 7244 { 7245 return "<pre class=\"$style\">" . &$protect_text($text) . '</pre>'; 7246 } 7247 elsif ($style eq 'html') 7248 { 7249 chomp ($text); 7250 return $text; 7251 } 7252 else 7253 { 7254 main::echo_warn ("Raw style $style not handled"); 7255 return &$protect_text($text); 7256 } 7257} 7258 7259# raw environment when removing texi (in comments) 7260sub t2h_default_raw_no_texi($$) 7261{ 7262 my $style = shift; 7263 my $text = shift; 7264 return $text; 7265} 7266 7267# This function formats a footnote reference and the footnote text associated 7268# with a given footnote. 7269# The footnote reference is the text appearing in the main document pointing 7270# to the footnote text. 7271# 7272# arguments: 7273# absolute number of the footnote (in the document) 7274# relative number of the footnote (in the page) 7275# identifier for the footnote 7276# identifier for the footnote reference in the main document 7277# main document file 7278# footnote text file 7279# array with the footnote text lines 7280# the state. See menu entry. 7281# 7282# returns: 7283# reference on an array containing the footnote text lines which should 7284# have been updated 7285# the text for the reference pointing on the footnote text 7286sub t2h_default_foot_line_and_ref($$$$$$$$$) 7287{ 7288 my $number_in_doc = shift; 7289 my $number_in_page = shift; 7290 my $footnote_id = shift; 7291 my $place_id = shift; 7292 my $document_file = shift; 7293 my $footnote_file = shift; 7294 my $lines = shift; 7295 my $document_state = shift; 7296 7297 if ($document_file eq $footnote_file) 7298 { 7299 $document_file = $footnote_file = ''; 7300 } 7301 unshift (@$lines, '<h3>' . 7302 &$anchor($footnote_id, $document_file . "#$place_id", 7303 "($number_in_doc)") 7304 . "</h3>\n"); 7305 # this is a bit obscure, this allows to add an anchor only if formatted 7306 # as part of the document. 7307 $place_id = '' if ($document_state->{'outside_document'} or $document_state->{'multiple_pass'}); 7308 return ($lines, &$anchor($place_id, $footnote_file . "#$footnote_id", 7309 "($number_in_doc)")); 7310} 7311 7312# formats a group of footnotes. 7313# 7314# argument: 7315# array reference on the footnotes texts lines 7316# 7317# returns an array reference on the group of footnotes lines 7318sub t2h_default_foot_section($) 7319{ 7320 my $lines = shift; 7321 unshift (@$lines, "<div class=\"footnote\">\n" ,"$DEFAULT_RULE\n", "<h3>" . &$I('Footnotes') . "</h3>\n"); 7322 push (@$lines, "</div>\n"); 7323 return $lines; 7324} 7325 7326sub t2h_default_image_files($$$$) 7327{ 7328 my $base = shift; 7329 my $extension = shift; 7330 my $texi_base = shift; 7331 my $texi_extension = shift; 7332 my @files = (); 7333 return @files if (!defined($base) or ($base eq '')); 7334 if (defined($extension) and ($extension ne '')) 7335 { 7336 push @files,["$base.$extension", "$texi_base.$texi_extension"]; 7337 } 7338 foreach my $ext (@IMAGE_EXTENSIONS) 7339 { 7340 push @files,["$base.$ext", "$texi_base.$ext"]; 7341 } 7342 return @files; 7343} 7344 7345# format an image 7346# 7347# arguments: 7348# image file name with path 7349# image basename 7350# a boolean true if we are in a preformatted format 7351# image file name without path 7352# alt text 7353# width 7354# height 7355# raw alt 7356# extension 7357# path to working dir 7358# path to file relative from working dir 7359sub t2h_default_image($$$$$$$$$$$$$$$$) 7360{ 7361 my $file = shift; 7362 my $base = shift; 7363 my $preformatted = shift; 7364 my $file_name = shift; 7365 my $alt = shift; 7366 my $width = shift; 7367 my $height = shift; 7368 my $raw_alt = shift; 7369 my $extension = shift; 7370 my $working_dir = shift; 7371 my $file_path = shift; 7372 my $in_paragraph = shift; 7373 my $file_locations = shift; 7374 my $base_simple_format = shift; 7375 my $extension_simple_format = shift; 7376 my $file_name_simple_format = shift; 7377 7378 if (!defined($file_path) or $file_path eq '') 7379 { 7380 if (defined($extension) and $extension ne '') 7381 { 7382 $file = "$base.$extension"; 7383 } 7384 else 7385 { 7386 $file = "$base.jpg"; 7387 } 7388 main::echo_warn ("no image file for $base, (using $file)"); 7389 } 7390 elsif (! $COMPLETE_IMAGE_PATHS) 7391 { 7392 $file = $file_name; 7393 } 7394 $alt = &$protect_text($base) if (!defined($alt) or ($alt eq '')); 7395 return "[ $alt ]" if ($preformatted); 7396 # it is possible that $file_name is more correct as it allows the user 7397 # to chose the relative path. 7398 $file = &$protect_text($file); 7399 return "<img src=\"$file\" alt=\"$alt\">"; 7400} 7401 7402# address put in footer describing when was generated and who did the manual 7403sub t2h_default_address($$) 7404{ 7405 my $user = shift; 7406 my $date = shift; 7407 $user = '' if (!defined($user)); 7408 $date = '' if (!defined($date)); 7409 if (($user ne '') and ($date ne '')) 7410 { 7411 return &$I('by @emph{%{user}} on @emph{%{date}}', { 'user' => $user, 7412 'date' => $date }); 7413 } 7414 elsif ($user ne '') 7415 { 7416 return &$I('by @emph{%{user}}', { 'user' => $user }); 7417 } 7418 elsif ($date ne '') 7419 { 7420 return &$I('on @emph{%{date}}', { 'date' => $date }); 7421 } 7422 return ''; 7423} 7424 7425# format a target in the main document for an index entry. 7426# 7427# arguments: 7428# target identifier 7429# boolean true if in preformatted format 7430# FIXME document the remaining 7431sub t2h_default_index_entry_label($$$$$) 7432{ 7433 my $identifier = shift; 7434 my $preformatted = shift; 7435 my $entry = shift; 7436 my $index_name = shift; 7437 my $index_command = shift; 7438 my $texi_entry = shift; 7439 my $formatted_entry = shift; 7440 7441 return '' if (!defined($identifier) or ($identifier !~ /\S/)); 7442 my $label = &$anchor($identifier); 7443 return $label . "\n" if (!$preformatted); 7444 return $label; 7445} 7446 7447sub t2h_default_index_entry_command($$$$$) 7448{ 7449 my $command = shift; 7450 my $index_name = shift; 7451 my $label = shift; 7452 my $entry_texi = shift; 7453 my $entry_formatted = shift; 7454 7455 return $label; 7456} 7457 7458###GAMBIT### added this function 7459sub escape_spaces($) 7460{ 7461 my $text = shift; 7462 my $result = ''; 7463 while ($text ne '') 7464 { 7465 if ($text =~ s/^(.)//o) 7466 { 7467 my $char = $1; 7468 if ($char eq ' ') 7469 { 7470 $result .= "_"; 7471 } 7472 else 7473 { 7474 $result .= "$char"; 7475 } 7476 } 7477 } 7478 return $result; 7479} 7480 7481###GAMBIT### added this function 7482sub escape_url($) 7483{ 7484 my $text = shift; 7485 my $result = ''; 7486 while ($text ne '') 7487 { 7488 if ($text =~ s/^(.)//o) 7489 { 7490 my $char = $1; 7491 if ($char eq '#') 7492 { 7493 $result .= "%E2%99%AF"; 7494 } 7495 elsif ($char eq '%') 7496 { 7497 $result .= "%25"; 7498 } 7499 elsif ($char eq '*') 7500 { 7501 $result .= "%2A"; 7502 } 7503 elsif ($char eq '+') 7504 { 7505 $result .= "%2B"; 7506 } 7507 elsif ($char eq '<') 7508 { 7509 $result .= "%3C"; 7510 } 7511 elsif ($char eq '>') 7512 { 7513 $result .= "%3E"; 7514 } 7515 else 7516 { 7517 $result .= "$char"; 7518 } 7519 } 7520 } 7521 return $result; 7522} 7523 7524# process definition commands line @deffn for example 7525sub t2h_default_def_line($$$$$$$$$$$$$$$$) 7526{ 7527 my $category_prepared = shift; 7528 my $name = shift; 7529 my $type = shift; 7530 my $arguments = shift; 7531 my $index_label = shift; 7532 my $arguments_array = shift; 7533 my $arguments_type_array = shift; 7534 my $unformatted_arguments_array = shift; 7535 my $command = shift; 7536 my $class_name = shift; 7537 my $category = shift; 7538 my $class = shift; 7539 my $style = shift; 7540 my $original_command = shift; 7541 7542 $index_label = '' if (!defined($index_label)); 7543 chomp($index_label); 7544 $category_prepared = '' if (!defined($category_prepared) or ($category_prepared =~ /^\s*$/)); 7545 $name = '' if (!defined($name) or ($name =~ /^\s*$/)); 7546 $type = '' if (!defined($type) or $type =~ /^\s*$/); 7547 if (!defined($arguments) or $arguments =~ /^\s*$/) 7548 { 7549 $arguments = ''; 7550 } 7551 else 7552 { 7553 chomp ($arguments); 7554 $arguments = '<i>' . $arguments . '</i>'; 7555 } 7556 my $type_name = ''; 7557 $type_name = " $type" if ($type ne ''); 7558 $type_name .= " <code>(</code>"; ###GAMBIT### added 7559# $type_name .= ' <b>' . $name . '</b>' if ($name ne ''); ###GAMBIT### removed 7560 7561 ###GAMBIT### added the following code to assign an anchor to each definition 7562 my $name2 = $name; 7563 $name2 =~ s/</</g; 7564 $name2 =~ s/>/>/g; 7565 my $anchor1_name = escape_url(escape_spaces('Definition of ' . $name2)); 7566 my $anchor2_name = escape_url(escape_spaces(ucfirst($category) . ' ' . $name2)); 7567 my $anchor1 = '<a name="' . $anchor1_name . '"></a>'; 7568 my $anchor2 = '<a name="' . $anchor2_name . '"></a>'; 7569 my $labels = ''; 7570 7571 ###GAMBIT### added the following if to have manual refer to the wiki and the wiki refer to the manual 7572 if ($Texi2HTML::THISDOC{'title_texi'} eq 'wiki documentation') 7573 { 7574 #print STDERR "wiki\n"; 7575 $type_name .= '<code><b><a href="http://www.iro.umontreal.ca/~gambit/doc/gambit-c.html#' . $anchor1_name . '">' . $name . '</a></b></code>' if ($name ne ''); 7576 } 7577 else 7578 { 7579 #print STDERR "manual\n"; 7580 $type_name .= '<code><b><a href="http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php?title=Documentation:' . $anchor2_name . '">' . $name . '</a></b></code>' if ($name ne ''); 7581 $labels = $anchor1 . $anchor2 . $index_label; 7582 } 7583 7584 $type_name .= $arguments; 7585 $type_name .= "<code>)</code>"; ###GAMBIT### added 7586 if (! $DEF_TABLE) 7587 { 7588 return '<dt>'. $index_label. '<u>' . $category_prepared . ':</u>' . $type_name . "</dt>\n"; 7589 } 7590 else 7591 { 7592 7593# return "<tr><td align=\"left\">" . $type_name . ###GAMBIT### removed 7594# "</td><td align=\"right\">" . $category_prepared . $index_label . "</td></tr>\n"; ###GAMBIT### 7595 return $labels . "<table width=\"100%\"><tr><td align=\"left\">" . $type_name . ###GAMBIT### added to move index label to front 7596 "</td><td align=\"right\">" . $category_prepared . "</td></tr></table>\n"; ###GAMBIT### 7597 } 7598} 7599 7600# process definition commands line @deffn for example while removing texi 7601# commands 7602sub t2h_default_def_line_no_texi($$$$$) 7603{ 7604 my $category = shift; 7605 my $name = shift; 7606 my $type = shift; 7607 my $arguments = shift; 7608 $name = '' if (!defined($name) or ($name =~ /^\s*$/)); 7609 $type = '' if (!defined($type) or $type =~ /^\s*$/); 7610 if (!defined($arguments) or $arguments =~ /^\s*$/) 7611 { 7612 $arguments = ''; 7613 } 7614 my $type_name = ''; 7615 $type_name = " $type" if ($type ne ''); 7616 $type_name .= ' ' . $name if ($name ne ''); 7617 $type_name .= $arguments; 7618 if (! $DEF_TABLE) 7619 { 7620 return $category . ':' . $type_name . "\n"; 7621 } 7622 else 7623 { 7624 7625 return $type_name . " " . $category . "\n"; 7626 } 7627} 7628 7629# a cartouche 7630sub t2h_default_cartouche($$) 7631{ 7632 my $text = shift; 7633 7634 if ($text =~ /\S/) 7635 { 7636 return "<table class=\"cartouche\" border=\"1\"><tr><td>\n" . $text . "</td></tr></table>\n"; 7637 } 7638 return ''; 7639} 7640 7641# key: 7642# origin_href: 7643# entry: 7644# texi entry: 7645# element_href: 7646# element_text: 7647sub t2h_default_index_summary_file_entry ($$$$$$$$$) 7648{ 7649 my $index_name = shift; 7650 my $key = shift; 7651 my $origin_href = shift; 7652 my $entry = shift; 7653 my $texi_entry = shift; 7654 my $element_href = shift; 7655 my $element_text = shift; 7656 my $is_printed = shift; 7657 my $manual_name = shift; 7658 7659 print IDXFILE "key: $key\n origin_href: $origin_href\n entry: $entry\n" 7660 . " texi_entry: $texi_entry\n" 7661 . " element_href: $element_href\n element_text: $element_text\n"; 7662} 7663 7664sub t2h_default_index_summary_file_begin($$$) 7665{ 7666 my $name = shift; 7667 my $is_printed = shift; 7668 my $manual_name = shift; 7669 7670 open(IDXFILE, ">$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'file_base_name'}" . "_$name.idx") 7671 || die "Can't open >$Texi2HTML::THISDOC{'destination_directory'}$Texi2HTML::THISDOC{'file_base_name'}" . "_$name.idx for writing: $!\n"; 7672} 7673 7674sub t2h_default_index_summary_file_end($$$) 7675{ 7676 my $name = shift; 7677 my $is_printed = shift; 7678 my $manual_name = shift; 7679 7680 close (IDXFILE); 7681} 7682 7683sub t2h_default_sp($$) 7684{ 7685 my $number = shift; 7686 my $preformatted = shift; 7687 return "<br>\n" x $number if (!$preformatted); 7688 return "\n" x $number; 7689} 7690 7691sub t2h_default_acronym_like($$$$$$) 7692{ 7693 my $command = shift; 7694 my $acronym_texi = shift; 7695 my $acronym_text = shift; 7696 my $with_explanation = shift; 7697 my $explanation_lines = shift; 7698 my $explanation_text = shift; 7699 my $explanation_simply_formatted = shift; 7700 7701 my $attribute = $command; 7702 my $opening = "<$attribute>"; 7703 if (defined($explanation_simply_formatted)) 7704 { 7705 $opening = "<$attribute title=\"$explanation_simply_formatted\">"; 7706 } 7707 if ($with_explanation) 7708 { 7709 return &$I('%{acronym_like} (%{explanation})', {'acronym_like' => $opening . $acronym_text . "</$attribute>", 'explanation' => $explanation_text},{'duplicate'=>1}) 7710 } 7711 else 7712 { 7713 return $opening . $acronym_text . "</$attribute>"; 7714 } 7715} 7716 7717sub t2h_default_quotation_prepend_text($$) 7718{ 7719 my $command = shift; 7720 my $text = shift; 7721 return undef if (!defined($text) or $text =~ /^$/); 7722 $text =~ s/^\s*//; 7723# FIXME if there is a @ protecting the end of line the result is 7724# @b{some text @:} 7725# It is likely not to be what was intended 7726 chomp($text); 7727 return &$I('@b{%{quotation_arg}:} ', {'quotation_arg' => $text}, {'keep_texi' => 1}); 7728} 7729 7730sub t2h_default_quotation($$$$) 7731{ 7732 my $command = shift; 7733 my $text = shift; 7734 my $argument_text = shift; 7735 my $argument_text_texi = shift; 7736 my $class_text = ''; 7737 $class_text = " class=\"$command\"" if ($command ne 'quotation'); 7738 return "<blockquote$class_text>" . $text . "</blockquote>\n"; 7739} 7740 7741# format the text within a paragraph style format, 7742# 7743# argument: 7744# format name 7745# text within the format 7746sub t2h_default_paragraph_style_command($$) 7747{ 7748 my $format = shift; 7749 my $text = shift; 7750 return $text; 7751} 7752 7753# format a whole index 7754# 7755# argument: 7756# index text 7757# index name 7758sub t2h_default_print_index($$) 7759{ 7760 my $text = shift; 7761 my $name = shift; 7762 return '' if (!defined($text)); 7763 return "<table border=\"0\" class=\"index-$name\">\n" . 7764 "<tr><td></td><th align=\"left\">" . &$I('Index Entry') . "</th><th align=\"left\"> " . &$I('Section') . "</th></tr>\n" 7765 . "<tr><td colspan=\"3\"> $DEFAULT_RULE</td></tr>\n" . $text . 7766 "</table>\n"; 7767} 7768 7769# format a letter entry in an index page. The letter entry contains 7770# the index entries for the words beginning with that letter. It is 7771# a target for links pointing from the summary of the index. 7772# 7773# arguments: 7774# the letter 7775# identifier for the letter entry. This should be used to make the target 7776# identifier 7777# text of the index entries 7778sub t2h_default_index_letter($$$) 7779{ 7780 my $letter = shift; 7781 my $id = shift; 7782 my $text = shift; 7783 return '<tr><th>' . &$anchor($id,'',&$protect_text($letter)) . 7784 "</th><td></td><td></td></tr>\n" . $text . 7785 "<tr><td colspan=\"3\"> $DEFAULT_RULE</td></tr>\n"; 7786} 7787 7788# format an index entry (in a letter entry). 7789# 7790# arguments: 7791# href to the main text, linking to the place where the index entry appears 7792# entry text 7793# href to the main text, linking to the section or node where the index 7794# entry appears 7795# section or node heading 7796sub t2h_default_index_entry($$$$$$$$) 7797{ 7798 my $text_href = shift; 7799 my $entry = shift; 7800 my $element_href = shift; 7801 my $element_text = shift; 7802 my $entry_file = shift; 7803 my $current_element_file = shift; 7804 my $entry_target = shift; 7805 my $entry_element_target = shift; 7806 7807 return '<tr><td></td><td valign="top">' . &$anchor('', $text_href, $entry) 7808 . '</td><td valign="top">' . &$anchor('', $element_href, $element_text) 7809 . "</td></tr>\n"; 7810} 7811 7812 7813sub t2h_default_copying_comment($$$$) 7814{ 7815 my $copying_lines = shift; 7816 my $copying_text = shift; 7817 my $copying_no_texi = shift; 7818 my $copying_simple_text = shift; 7819 return '' if ($copying_no_texi eq ''); 7820 my $text = &$comment($copying_no_texi); 7821 return $text; 7822} 7823 7824# return value is currently ignored 7825sub t2h_default_documentdescription($$$$) 7826{ 7827 my $decription_lines = shift; 7828 my $description_text = shift; 7829 my $description_no_texi = shift; 7830 my $description_simple_text = shift; 7831 7832 if (defined($DOCUMENT_DESCRIPTION)) 7833 { 7834 $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = $DOCUMENT_DESCRIPTION; 7835 return $DOCUMENT_DESCRIPTION; 7836 } 7837 7838 #return '' if ($description_no_texi eq ''); 7839 #my @documentdescription = split (/\n/, $description_no_texi); 7840 if ($description_simple_text eq '') 7841 { 7842 $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = undef; 7843 return undef; 7844 } 7845 my @documentdescription = split (/\n/, $description_simple_text); 7846 my $document_description = shift @documentdescription; 7847 chomp $document_description; 7848 foreach my $line (@documentdescription) 7849 { 7850 chomp $line; 7851 $document_description .= ' ' . $line; 7852 } 7853 $Texi2HTML::THISDOC{'DOCUMENT_DESCRIPTION'} = $document_description; 7854 return $document_description; 7855} 7856 7857# format an index summary. This is a list of letters linking to the letter 7858# entries. 7859# 7860# arguments: 7861# array reference containing the formatted alphabetical letters 7862# array reference containing the formatted non lphabetical letters 7863sub t2h_default_index_summary($$) 7864{ 7865 my $alpha = shift; 7866 my $nonalpha = shift; 7867 7868 my $join = ''; 7869 my $nonalpha_text = ''; 7870 my $alpha_text = ''; 7871 $join = " \n<br>\n" if (@$nonalpha and @$alpha); 7872 if (@$nonalpha) 7873 { 7874 $nonalpha_text = join("\n \n", @$nonalpha) . "\n"; 7875 } 7876 if (@$alpha) 7877 { 7878 $alpha_text = join("\n \n", @$alpha) . "\n \n"; 7879 } 7880 return "<table><tr><th valign=\"top\">" . &$I('Jump to') .": </th><td>" . 7881 $nonalpha_text . $join . $alpha_text . "</td></tr></table>\n"; 7882} 7883 7884# return the heading with number texinfo text 7885# also called for nodes. 7886sub t2h_default_heading_texi($$$) 7887{ 7888 my $tag = shift; 7889 my $texi = shift; 7890 my $number = shift; 7891 $texi =~ s/\s*$//; 7892 $texi =~ s/^\s*//; 7893 return "$number $texi" if ($NUMBER_SECTIONS and defined($number) and ($number !~ /^\s*$/)) ; 7894 return $texi; 7895} 7896 7897# return the heading texinfo text for split index sections 7898sub t2h_default_index_element_heading_texi($$$) 7899{ # FIXME i18n 7900 my $heading_texi = shift; 7901 my $tag = shift; 7902 my $texi = shift; 7903 my $number = shift; 7904 my $first_letter = shift; 7905 my $last_letter = shift; 7906 return "$heading_texi: $first_letter -- $last_letter" if ($last_letter ne $first_letter); 7907 return "$heading_texi: $first_letter"; 7908} 7909 7910sub t2h_default_element_label($$$$) 7911{ 7912 my $id = shift; 7913 my $element = shift; 7914 my $command = shift; 7915 my $line = shift; 7916 7917 return &$anchor($id) . "\n"; 7918} 7919 7920sub t2h_default_misc_element_label($$) 7921{ 7922 my $id = shift; 7923 my $misc_page_name = shift; 7924 return &$anchor($id) . "\n"; 7925} 7926 7927sub t2h_default_anchor_label($$$) 7928{ 7929 my $id = shift; 7930 my $anchor_text = shift; 7931 my $anchor_reference = shift; 7932 return &$anchor($id); 7933} 7934 7935sub t2h_default_colon_command($) 7936{ 7937 my $punctuation_character = shift; 7938 return $colon_command_punctuation_characters{$punctuation_character} if defined($colon_command_punctuation_characters{$punctuation_character}); 7939 return $punctuation_character; 7940} 7941 7942sub t2h_default_tab_item_texi($$$$$$) 7943{ 7944 my $comand = shift; 7945 my $commands_stack = shift; 7946 my $state = shift; 7947 my $stack = shift; 7948 my $line = shift; 7949 my $line_nr = shift; 7950 7951 if (defined($commands_stack) and @$commands_stack and $commands_stack->[-1] eq 'multitable' and @t2h_default_multitable_stack) 7952 { 7953 $t2h_default_multitable_stack[-1]->[1] = -1; 7954 } 7955 return undef; 7956} 7957 79581; 7959 7960require "$T2H_HOME/texi2html.init" 7961 if ($0 =~ /\.pl$/ && 7962 -e "$T2H_HOME/texi2html.init" && -r "$T2H_HOME/texi2html.init"); 7963 7964my $translation_file = 'translations.pl'; # file containing all the translations 7965my $T2H_OBSOLETE_STRINGS; 7966 7967# leave this within comments, and keep the require statement 7968# This way, you can directly run texi2html.pl, 7969# if $T2H_HOME/translations.pl exists. 7970# 7971# @T2H_TRANSLATIONS_FILE@ 7972$LANGUAGES->{'de'} = { 7973 ' The buttons in the navigation panels have the following meaning:' => ' Die Links in der Navigationsleiste haben die folgende Bedeutung: ', 7974 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' wobei das @strong{ Beispiel } annimmt, dass die aktuelle Position bei @strong{ Unterabschnitt 1-2-3 } in einem Dokument mit folgender Struktur liegt:', 7975 ' Up ' => ' Nach oben ', 7976 '%{acronym_like} (%{explanation})' => '%{acronym_like} (%{explanation})', 7977 '%{month} %{day}, %{year}' => '%{day}. %{month} %{year}', 7978 '%{name} of %{class}' => '', 7979 '%{name} on %{class}' => '', 7980 '%{node_file_href}' => '', 7981 '%{node_file_href} @cite{%{book}}' => '', 7982 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '%{node_file_href} in Abschnitt `%{section}\' in @cite{%{book}}', 7983 '%{reference_name}' => '%{reference_name}', 7984 '%{style} %{number}' => '%{style} %{number}', 7985 '%{style}: %{caption_first_line}' => '%{style}: %{caption_first_line}', 7986 '%{style}: %{shortcaption_first_line}' => '%{style}: %{shortcaption_first_line}', 7987 '@b{%{quotation_arg}:} ' => '@b{%{quotation_arg}:} ', 7988 '@cite{%{book}}' => '@cite{%{book}}', 7989 'About' => '@"Uber', 7990 'About (help)' => '@"Uber (Hilfe)', 7991 'About This Document' => '@"Uber dieses Dokument', 7992 'April' => 'April', 7993 'August' => 'August', 7994 'Back' => 'Zur@"uck', 7995 'Back section in previous file' => '', 7996 'Beginning of this chapter or previous chapter' => 'Anfang dieses oder des letzten Kapitels', 7997 'Button' => '', 7998 'Contents' => 'Inhalt', 7999 'Cover (top) of document' => 'Titelseite des Dokuments', 8000 'Current Position' => 'Aktuelle Position', 8001 'Current section' => 'Aktueller Abschnitt', 8002 'December' => 'Dezember', 8003 'FastBack' => '', 8004 'FastForward' => '', 8005 'February' => 'Februar', 8006 'First' => '', 8007 'First section in reading order' => 'Erster Abschnitt in Lesereihenfolge', 8008 'Following' => '', 8009 'Following node' => 'N@"achster Knoten', 8010 'Footnotes' => 'Fu@ss{}noten', 8011 'Forward' => 'Nach vorne', 8012 'Forward section in next file' => '', 8013 'From 1.2.3 go to' => 'Von 1.2.3 gehe zu', 8014 'Go to' => 'Gehe zu', 8015 'Index' => 'Index', 8016 'Index Entry' => 'Indexeintrag', 8017 'January' => 'Januar', 8018 'July' => 'Juli', 8019 'Jump to' => 'Springe zu', 8020 'June' => 'Juni', 8021 'Last' => '', 8022 'Last section in reading order' => 'Letzter Abschnitt in Lesereihenfolge', 8023 'March' => 'M@"arz', 8024 'May' => 'Mai', 8025 'Menu:' => 'Auswahl:', 8026 'Name' => 'Name', 8027 'Next' => '', 8028 'Next chapter' => 'N@"achstes Kapitel', 8029 'Next file' => '', 8030 'Next node' => 'N@"achster Knoten', 8031 'Next section in reading order' => 'N@"achster Abschnitt in Lesereihenfolge', 8032 'Next section on same level' => 'N@"achster Abschitt derselben Ebene', 8033 'NextFile' => '', 8034 'Node following in node reading order' => 'N@"achster Abschnitt in Lesereihenfolge', 8035 'Node up' => 'Knoten nach oben', 8036 'NodeNext' => '', 8037 'NodePrev' => '', 8038 'NodeUp' => '', 8039 'November' => 'November', 8040 'October' => 'Oktober', 8041 'Overview' => '@"Ubersicht', 8042 'Overview:' => '@"Ubersicht:', 8043 'Prev' => '', 8044 'PrevFile' => '', 8045 'Previous file' => '', 8046 'Previous node' => 'Voriger Knoten', 8047 'Previous section in reading order' => 'Voriger Abschnitt in Lesereihenfolge', 8048 'Previous section on same level' => 'Voriger Abschnitt derselben Ebene', 8049 'Section' => 'Abschnitt', 8050 'Section One' => 'Abschnitt 1', 8051 'See %{node_file_href}' => 'Siehe %{node_file_href}', 8052 'See %{node_file_href} @cite{%{book}}' => 'Siehe %{node_file_href} @cite{%{book}}', 8053 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'Siehe %{node_file_href} in Abschnitt `%{section}\' in @cite{%{book}}', 8054 'See %{reference_name}' => '', 8055 'See @cite{%{book}}' => '', 8056 'See section %{reference_name}' => '', 8057 'See section `%{section}\' in @cite{%{book}}' => 'Siehe Abschnitt `%{section}\' in @cite{%{book}}', 8058 'September' => 'September', 8059 'Short Table of Contents' => 'Kurzes Inhaltsverzeichnis', 8060 'Short table of contents' => 'Kurzes Inhaltsverzeichnis', 8061 'Subsection One-Four' => 'Unterabschnitt 1-4', 8062 'Subsection One-One' => 'Unterabschnitt 1-1', 8063 'Subsection One-Three' => 'Unterabschnitt 1-3', 8064 'Subsection One-Two' => 'Unterabschnitt 1-2', 8065 'Subsubsection One-Two-Four' => 'Unterabschnitt 1-2-4', 8066 'Subsubsection One-Two-One' => 'Unterabschnitt 1-2-1', 8067 'Subsubsection One-Two-Three' => 'Unterabschnitt 1-2-3', 8068 'Subsubsection One-Two-Two' => 'Unterabschnitt 1-2-2', 8069 'T2H_today' => '', 8070 'Table of Contents' => 'Inhaltsverzeichnis', 8071 'Table of contents' => 'Inhaltsverzeichnis', 8072 'The node you are looking for is at %{href}.' => 'Der Knoten, den Sie sehen, befindet sich bei %{href}', 8073 'This' => '', 8074 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Dieses Dokument wurde erzeugt von @emph{%{user}} am @emph{%{date}} durch @uref{%{program_homepage}, @emph{%{program}}}.', 8075 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Dieses Dokument wurde erzeugt von @emph{%{user}} durch @uref{%{program_homepage}, @emph{%{program}}}.', 8076 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => 'Dieses Dokument wurde erzeugt am @i{%{date}} durch @uref{%{program_homepage}, @i{%{program}}}.', 8077 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Dieses Dokument wurde erzeugt durch @uref{%{program_homepage}, @emph{%{program}}}.', 8078 'Top' => 'Anfang', 8079 'Untitled Document' => 'Unbenanntes Dokumen', 8080 'Up' => 'Nach oben', 8081 'Up node' => 'Knoten nach oben', 8082 'Up section' => 'Abschnitt nach oben', 8083 'by @emph{%{user}}' => 'von @emph{%{user}}', 8084 'by @emph{%{user}} on @emph{%{date}}' => 'von @emph{%{user}} am @emph{%{date}}', 8085 'current' => '', 8086 'on @emph{%{date}}' => 'am @emph{%{date}}', 8087 'section `%{section}\' in @cite{%{book}}' => 'Abschnitt `%{section}\' in @cite{%{book}}', 8088 'see %{node_file_href}' => 'siehe %{node_file_href}', 8089 'see %{node_file_href} @cite{%{book}}' => 'siehe %{node_file_href} @cite{%{book}}', 8090 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'siehe %{node_file_href} im Abschnitt `%{section}\' in @cite{%{book}}', 8091 'see %{reference_name}' => 'siehe %{reference_name}', 8092 'see @cite{%{book}}' => 'siehe @cite{%{book}}', 8093 'see section %{reference_name}' => 'siehe Abschnitt %{reference_name}', 8094 'see section `%{section}\' in @cite{%{book}}' => 'siehe Abschnitt `%{section}\' in @cite{%{book}}', 8095 'unknown' => 'unbekannt' 8096 }; 8097 8098$T2H_OBSOLETE_STRINGS->{'de'} = { 8099 'See' => 'Siehe', 8100 'section' => 'Abschnitt', 8101 'see' => 'siehe' 8102 }; 8103 8104 8105$LANGUAGES->{'en'} = { 8106 ' The buttons in the navigation panels have the following meaning:' => '', 8107 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => '', 8108 ' Up ' => '', 8109 '%{acronym_like} (%{explanation})' => '', 8110 '%{month} %{day}, %{year}' => '', 8111 '%{name} of %{class}' => '', 8112 '%{name} on %{class}' => '', 8113 '%{node_file_href}' => '', 8114 '%{node_file_href} @cite{%{book}}' => '', 8115 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8116 '%{reference_name}' => '', 8117 '%{style} %{number}' => '', 8118 '%{style}: %{caption_first_line}' => '', 8119 '%{style}: %{shortcaption_first_line}' => '', 8120 '@b{%{quotation_arg}:} ' => '', 8121 '@cite{%{book}}' => '', 8122 'About' => '', 8123 'About (help)' => '', 8124 'About This Document' => '', 8125 'April' => '', 8126 'August' => '', 8127 'Back' => '', 8128 'Back section in previous file' => '', 8129 'Beginning of this chapter or previous chapter' => '', 8130 'Button' => '', 8131 'Contents' => '', 8132 'Cover (top) of document' => '', 8133 'Current Position' => '', 8134 'Current section' => '', 8135 'December' => '', 8136 'FastBack' => '', 8137 'FastForward' => '', 8138 'February' => '', 8139 'First' => '', 8140 'First section in reading order' => '', 8141 'Following' => '', 8142 'Following node' => '', 8143 'Footnotes' => '', 8144 'Forward' => '', 8145 'Forward section in next file' => '', 8146 'From 1.2.3 go to' => '', 8147 'Go to' => '', 8148 'Index' => '', 8149 'Index Entry' => '', 8150 'January' => '', 8151 'July' => '', 8152 'Jump to' => '', 8153 'June' => '', 8154 'Last' => '', 8155 'Last section in reading order' => '', 8156 'March' => '', 8157 'May' => '', 8158 'Menu:' => '', 8159 'Name' => '', 8160 'Next' => '', 8161 'Next chapter' => '', 8162 'Next file' => '', 8163 'Next node' => '', 8164 'Next section in reading order' => '', 8165 'Next section on same level' => '', 8166 'NextFile' => '', 8167 'Node following in node reading order' => '', 8168 'Node up' => '', 8169 'NodeNext' => '', 8170 'NodePrev' => '', 8171 'NodeUp' => '', 8172 'November' => '', 8173 'October' => '', 8174 'Overview' => '', 8175 'Overview:' => '', 8176 'Prev' => '', 8177 'PrevFile' => '', 8178 'Previous file' => '', 8179 'Previous node' => '', 8180 'Previous section in reading order' => '', 8181 'Previous section on same level' => '', 8182 'Section' => '', 8183 'Section One' => '', 8184 'See %{node_file_href}' => '', 8185 'See %{node_file_href} @cite{%{book}}' => '', 8186 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8187 'See %{reference_name}' => '', 8188 'See @cite{%{book}}' => '', 8189 'See section %{reference_name}' => '', 8190 'See section `%{section}\' in @cite{%{book}}' => '', 8191 'September' => '', 8192 'Short Table of Contents' => '', 8193 'Short table of contents' => '', 8194 'Subsection One-Four' => '', 8195 'Subsection One-One' => '', 8196 'Subsection One-Three' => '', 8197 'Subsection One-Two' => '', 8198 'Subsubsection One-Two-Four' => '', 8199 'Subsubsection One-Two-One' => '', 8200 'Subsubsection One-Two-Three' => '', 8201 'Subsubsection One-Two-Two' => '', 8202 'T2H_today' => '%s, %d %d', 8203 'Table of Contents' => '', 8204 'Table of contents' => '', 8205 'The node you are looking for is at %{href}.' => '', 8206 'This' => '', 8207 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8208 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8209 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => '', 8210 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8211 'Top' => '', 8212 'Untitled Document' => '', 8213 'Up' => '', 8214 'Up node' => '', 8215 'Up section' => '', 8216 'by @emph{%{user}}' => '', 8217 'by @emph{%{user}} on @emph{%{date}}' => '', 8218 'current' => '', 8219 'on @emph{%{date}}' => '', 8220 'section `%{section}\' in @cite{%{book}}' => '', 8221 'see %{node_file_href}' => '', 8222 'see %{node_file_href} @cite{%{book}}' => '', 8223 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8224 'see %{reference_name}' => '', 8225 'see @cite{%{book}}' => '', 8226 'see section %{reference_name}' => '', 8227 'see section `%{section}\' in @cite{%{book}}' => '', 8228 'unknown' => '' 8229 }; 8230 8231$T2H_OBSOLETE_STRINGS->{'en'} = {}; 8232 8233 8234$LANGUAGES->{'es'} = { 8235 ' The buttons in the navigation panels have the following meaning:' => ' Los botones de los paneles de navegaci@\'on tienen el significado siguiente:', 8236 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' donde el @strong{ Ejemplo } supone que la posición actual está en la @strong{ Sub-subsecci@\'on uno-dos-tres } de un documento de la estructura siguiente:', 8237 ' Up ' => ' Subir ', 8238 '%{acronym_like} (%{explanation})' => '', 8239 '%{month} %{day}, %{year}' => 'el %{day} %{month} %{year}', 8240 '%{name} of %{class}' => '%{name} de %{class}', 8241 '%{name} on %{class}' => '%{name} en %{class}', 8242 '%{node_file_href}' => '', 8243 '%{node_file_href} @cite{%{book}}' => '', 8244 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '%{node_file_href} secci@\'on `%{section}\' en @cite{%{book}}', 8245 '%{reference_name}' => '', 8246 '%{style} %{number}' => '', 8247 '%{style}: %{caption_first_line}' => '', 8248 '%{style}: %{shortcaption_first_line}' => '', 8249 '@b{%{quotation_arg}:} ' => '', 8250 '@cite{%{book}}' => '', 8251 'About' => 'Acerca de', 8252 'About (help)' => 'Acerca de (p@\'agina de ayuda)', 8253 'About This Document' => 'Acerca de este documento', 8254 'April' => 'abril', 8255 'August' => 'agosto', 8256 'Back' => 'Atr@\'as', 8257 'Back section in previous file' => 'Retroceder secci@\'on en el archivo anterior', 8258 'Beginning of this chapter or previous chapter' => 'Inicio de este cap@\'itulo o cap@\'itulo anterior', 8259 'Button' => 'Bot@\'on', 8260 'Contents' => '@\'Indice general', 8261 'Cover (top) of document' => 'Portada del documento', 8262 'Current Position' => 'Posici@\'on actual', 8263 'Current section' => 'Secci@\'on actual', 8264 'December' => 'diciembre', 8265 'FastBack' => 'Retroceso r@\'apido', 8266 'FastForward' => 'Avance r@\'apido', 8267 'February' => 'febrero', 8268 'First' => 'Primero', 8269 'First section in reading order' => 'Primera secci@\'on en orden de lectura', 8270 'Following' => 'Siguiente', 8271 'Following node' => 'Nodo siguiente', 8272 'Footnotes' => 'Notas el pie', 8273 'Forward' => 'Adelante', 8274 'Forward section in next file' => 'Avanzar secci@\'on en el pr@\'oximo archivo', 8275 'From 1.2.3 go to' => 'Desde 1.2.3 ir a', 8276 'Go to' => 'Ir a', 8277 'Index' => '@\'Indice', 8278 'Index Entry' => 'Entrada de @\'indice', 8279 'January' => 'enero', 8280 'July' => 'julio', 8281 'Jump to' => 'Saltar a', 8282 'June' => 'junio', 8283 'Last' => '@\'Ultimo', 8284 'Last section in reading order' => '@\'Ultima secci@\'on en orden de lectura', 8285 'March' => 'marzo', 8286 'May' => 'mayo', 8287 'Menu:' => 'Men@\'u:', 8288 'Name' => 'Nombre', 8289 'Next' => 'Siguiente', 8290 'Next chapter' => 'Cap@\'itulo siguiente', 8291 'Next file' => 'Archivo siguiente', 8292 'Next node' => 'Nodo siguiente', 8293 'Next section in reading order' => 'Secci@\'on siguiente en orden de lectura', 8294 'Next section on same level' => 'Secci@\'on siguiente en el mismo nivel', 8295 'NextFile' => 'ArchivoSiguiente', 8296 'Node following in node reading order' => 'Nodo siguiente en orden de lectura de nodos', 8297 'Node up' => 'Subir nodo', 8298 'NodeNext' => 'NodoSiguiente', 8299 'NodePrev' => 'NodoAnterior', 8300 'NodeUp' => 'SubirNodo', 8301 'November' => 'noviembre', 8302 'October' => 'octubre', 8303 'Overview' => 'Panor@\'amica', 8304 'Overview:' => 'Panor@\'amica:', 8305 'Prev' => 'Ant', 8306 'PrevFile' => 'ArchivoAnt', 8307 'Previous file' => 'Archivo anterior', 8308 'Previous node' => 'Nodo anterior', 8309 'Previous section in reading order' => 'Secci@\'on anterior en orden de lectura', 8310 'Previous section on same level' => 'Secci@\'on anterior en el mismo nivel', 8311 'Section' => 'Secci@\'on', 8312 'Section One' => 'Secci@\'on Uno', 8313 'See %{node_file_href}' => 'V@\'ease %{node_file_href}', 8314 'See %{node_file_href} @cite{%{book}}' => 'V@\'ease %{node_file_href} @cite{%{book}}', 8315 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'V@\'ease %{node_file_href} secci@\'on `%{section}\' en @cite{%{book}}', 8316 'See %{reference_name}' => 'V@\'ease %{reference_name}', 8317 'See @cite{%{book}}' => 'V@\'ease @cite{%{book}}', 8318 'See section %{reference_name}' => 'V@\'ease la secci@\'on %{reference_name}', 8319 'See section `%{section}\' in @cite{%{book}}' => 'V@\'ease la secci@\'on `%{section}\' en @cite{%{book}}', 8320 'September' => 'septiembre', 8321 'Short Table of Contents' => 'Resumen del Contenido', 8322 'Short table of contents' => 'Resumen del contenido', 8323 'Subsection One-Four' => 'Subsecci@\'on uno-cuatro', 8324 'Subsection One-One' => 'Subsecci@\'on uno-uno', 8325 'Subsection One-Three' => 'Subsecci@\'on uno-tres', 8326 'Subsection One-Two' => 'Subsecci@\'on uno-dos', 8327 'Subsubsection One-Two-Four' => 'Sub-subsecci@\'on uno-dos-cuatro', 8328 'Subsubsection One-Two-One' => 'Sub-subsecci@\'on uno-dos-uno', 8329 'Subsubsection One-Two-Three' => 'Sub-subsecci@\'on uno-dos-tres', 8330 'Subsubsection One-Two-Two' => 'Sub-subsecci@\'on uno-dos-dos', 8331 'T2H_today' => '%2$d %1$s %3$d', 8332 'Table of Contents' => '@\'{@dotless{I}}ndice General', 8333 'Table of contents' => '@\'{@dotless{I}}ndice general', 8334 'The node you are looking for is at %{href}.' => 'El nodo que busca se encuentra en %{href}.', 8335 'This' => 'Este', 8336 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Este documento ha sido generado por @emph{%{user}} el @emph{%{date}} utilizando @uref{%{program_homepage}, @emph{%{program}}}.', 8337 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Este documento ha sido generado por @emph{%{user}} utilizando @uref{%{program_homepage}, @emph{%{program}}}.', 8338 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => 'Este documento se generó el @i{%{date}} utilizando @uref{%{program_homepage}, @i{%{program}}}.', 8339 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Este documento se generó utilizando @uref{%{program_homepage}, @emph{%{program}}}.', 8340 'Top' => 'Arriba', 8341 'Untitled Document' => 'Documento sin t@\'itulo', 8342 'Up' => 'Subir', 8343 'Up node' => 'Subir nodo', 8344 'Up section' => 'Subir secci@\'on', 8345 'by @emph{%{user}}' => 'por @emph{%{user}', 8346 'by @emph{%{user}} on @emph{%{date}}' => 'por @emph{%{user}} el @emph{%{date}}', 8347 'current' => 'actual', 8348 'on @emph{%{date}}' => 'el @emph{%{date}}', 8349 'section `%{section}\' in @cite{%{book}}' => 'secci@\'on `%{section}\' en @cite{%{book}}', 8350 'see %{node_file_href}' => 'v@\'ease %{node_file_href}', 8351 'see %{node_file_href} @cite{%{book}}' => 'v@\'ease %{node_file_href} @cite{%{book}}', 8352 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'v@\'ease %{node_file_href} secci@\'on `%{section}\' en @cite{%{book}}', 8353 'see %{reference_name}' => 'v@\'ease %{reference_name}', 8354 'see @cite{%{book}}' => 'v@\'ease @cite{%{book}}', 8355 'see section %{reference_name}' => 'v@\'ease la secci@\'on %{reference_name}', 8356 'see section `%{section}\' in @cite{%{book}}' => 'v@\'ease la secci@\'on `%{section}\' en @cite{%{book}}', 8357 'unknown' => 'desconocido' 8358 }; 8359 8360$T2H_OBSOLETE_STRINGS->{'es'} = { 8361 'See' => 'V@\'ease', 8362 'section' => 'secci@\'on', 8363 'see' => 'v@\'ease' 8364 }; 8365 8366 8367$LANGUAGES->{'fr'} = { 8368 ' The buttons in the navigation panels have the following meaning:' => ' Les boutons de navigation ont la signification suivante :', 8369 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' Dans cet exemple on est @`a @strong{ Sous sous section un-deux-trois } dans un document dont la structure est :', 8370 ' Up ' => 'Plus haut', 8371 '%{acronym_like} (%{explanation})' => '', 8372 '%{month} %{day}, %{year}' => 'le %{day} %{month} %{year}', 8373 '%{name} of %{class}' => '%{name} de %{class}', 8374 '%{name} on %{class}' => '%{name} de %{class}', 8375 '%{node_file_href}' => '', 8376 '%{node_file_href} @cite{%{book}}' => '', 8377 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '%{node_file_href} section `%{section}\' dans @cite{%{book}}', 8378 '%{reference_name}' => '', 8379 '%{style} %{number}' => '', 8380 '%{style}: %{caption_first_line}' => '', 8381 '%{style}: %{shortcaption_first_line}' => '', 8382 '@b{%{quotation_arg}:} ' => '', 8383 '@cite{%{book}}' => '', 8384 'About' => 'A propos', 8385 'About (help)' => 'A propos (page d\'aide)', 8386 'About This Document' => 'A propos de ce document', 8387 'April' => 'avril', 8388 'August' => 'ao@^ut', 8389 'Back' => 'Retour', 8390 'Back section in previous file' => '', 8391 'Beginning of this chapter or previous chapter' => 'D@\'ebut de ce chapitre ou chapitre pr@\'ec@\'edent', 8392 'Button' => 'Bouton', 8393 'Contents' => 'Table des mati@`eres', 8394 'Cover (top) of document' => 'Couverture (top) du document', 8395 'Current Position' => 'Position', 8396 'Current section' => 'Section actuelle', 8397 'December' => 'd@\'ecembre', 8398 'FastBack' => 'RetourRapide', 8399 'FastForward' => 'AvanceRapide', 8400 'February' => 'f@\'evrier', 8401 'First' => 'Premier', 8402 'First section in reading order' => 'Premi@`e section dans l\'ordre de lecture', 8403 'Following' => 'Suivant', 8404 'Following node' => 'N@oe{}ud suivant', 8405 'Footnotes' => 'Notes de bas de page', 8406 'Forward' => 'Avant', 8407 'Forward section in next file' => '', 8408 'From 1.2.3 go to' => 'Depuis 1.2.3 aller @`a', 8409 'Go to' => 'Aller @`a', 8410 'Index' => 'Index', 8411 'Index Entry' => 'Entr@\'ee d\'index', 8412 'January' => 'janvier', 8413 'July' => 'juillet', 8414 'Jump to' => 'Aller @`a', 8415 'June' => 'juin', 8416 'Last' => 'Dernier', 8417 'Last section in reading order' => 'Derni@`ere section dans l\'ordre de lecture', 8418 'March' => 'mars', 8419 'May' => 'mai', 8420 'Menu:' => 'Menu@ :', 8421 'Name' => 'Nom', 8422 'Next' => 'Suivant', 8423 'Next chapter' => 'Chapitre suivant', 8424 'Next file' => 'Fichier suivant', 8425 'Next node' => 'N@oe{}ud suivant', 8426 'Next section in reading order' => 'Section suivante dans l\'ordre de lecture', 8427 'Next section on same level' => 'Section suivante au m@^eme niveau', 8428 'NextFile' => 'FichierSuivant', 8429 'Node following in node reading order' => 'N@oe{}ud suivant dans l\'ordre de lecture', 8430 'Node up' => 'N@oe{}ud au dessus', 8431 'NodeNext' => 'N@oe{}udSuivant', 8432 'NodePrev' => 'N@oe{}udPr@\'ec@\'edent', 8433 'NodeUp' => 'N@oe{}udMonter', 8434 'November' => 'novembre', 8435 'October' => 'octobre', 8436 'Overview' => 'Vue d\'ensemble', 8437 'Overview:' => 'Vue d\'ensemble@ :', 8438 'Prev' => 'Pr@\'ec@\'edent', 8439 'PrevFile' => '', 8440 'Previous file' => 'Fichier pr@\'ec@\'edent', 8441 'Previous node' => 'N@oe{}ud pr@\'ec@\'edent', 8442 'Previous section in reading order' => 'Section pr@\'ec@\'edente dans l\'ordre de lecture', 8443 'Previous section on same level' => 'Section pr@\'ec@\'edente au m@^eme niveau', 8444 'Section' => '', 8445 'Section One' => 'Section un', 8446 'See %{node_file_href}' => 'Voir %{node_file_href}', 8447 'See %{node_file_href} @cite{%{book}}' => 'Voir %{node_file_href} @cite{%{book}}', 8448 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'Voir %{node_file_href} section `%{section}\' dans @cite{%{book}}', 8449 'See %{reference_name}' => 'Voir %{reference_name}', 8450 'See @cite{%{book}}' => 'Voir @cite{%{book}}', 8451 'See section %{reference_name}' => 'Voir la section %{reference_name}', 8452 'See section `%{section}\' in @cite{%{book}}' => 'Voir la section `%{section}\' dans @cite{%{book}}', 8453 'September' => 'septembre', 8454 'Short Table of Contents' => 'R@\'esum@\'e du contenu', 8455 'Short table of contents' => 'R@\'esum@\'e du contenu', 8456 'Subsection One-Four' => 'Sous section un-quatre', 8457 'Subsection One-One' => 'Sous section un-un', 8458 'Subsection One-Three' => 'Sous section un-trois', 8459 'Subsection One-Two' => 'Sous section un-deux', 8460 'Subsubsection One-Two-Four' => 'Sous sous section un-deux-quatre', 8461 'Subsubsection One-Two-One' => 'Sous sous section un-deux-un', 8462 'Subsubsection One-Two-Three' => 'Sous sous section un-deux-trois', 8463 'Subsubsection One-Two-Two' => 'Sous sous section un-deux-deux', 8464 'T2H_today' => '%2$d %1$s %3$d', 8465 'Table of Contents' => 'Table des mati@`eres', 8466 'Table of contents' => 'Table des mati@`eres', 8467 'The node you are looking for is at %{href}.' => 'Le n@oe{}ud que vous recherchez est ici@ : %{href}.', 8468 'This' => 'Ici', 8469 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e le @emph{%{date}} par @emph{%{user}} en utilisant @uref{%{program_homepage}, @emph{%{program}}}.', 8470 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e par @emph{%{user}} en utilisant @uref{%{program_homepage}, @emph{%{program}}}.', 8471 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e le @emph{%{date}} en utilisant @uref{%{program_homepage}, @emph{%{program}}}', 8472 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e en utilisant @uref{%{program_homepage}, @emph{%{program}}}.', 8473 'Top' => 'Racine', 8474 'Untitled Document' => 'Document sans titre', 8475 'Up' => 'Monter', 8476 'Up node' => 'N@oe{}ud au dessus', 8477 'Up section' => 'Section sup@\'erieure', 8478 'by @emph{%{user}}' => 'par @emph{%{user}}', 8479 'by @emph{%{user}} on @emph{%{date}}' => 'par @emph{%{user}} le @emph{%{date}}', 8480 'current' => 'courante', 8481 'on @emph{%{date}}' => 'le @emph{%{date}}', 8482 'section `%{section}\' in @cite{%{book}}' => 'section `%{section}\' dans @cite{%{book}}', 8483 'see %{node_file_href}' => 'voir %{node_file_href}', 8484 'see %{node_file_href} @cite{%{book}}' => 'voir %{node_file_href} @cite{%{book}}', 8485 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'voir %{node_file_href} section `%{section}\' dans @cite{%{book}}', 8486 'see %{reference_name}' => 'voir %{reference_name}', 8487 'see @cite{%{book}}' => 'voir @cite{%{book}}', 8488 'see section %{reference_name}' => 'voir la section %{reference_name}', 8489 'see section `%{section}\' in @cite{%{book}}' => 'voir la section `%{section}\' dans @cite{{book}}', 8490 'unknown' => 'inconnu' 8491 }; 8492 8493$T2H_OBSOLETE_STRINGS->{'fr'} = { 8494 ' This document was generated %{who_and_when_generated} using %{program_homepage_href}.' => ' Ce document a été généré %{who_and_when_generated} en utilisant %{program_homepage_href}.', 8495 ' where the <strong> Example </strong> assumes that the current position is at <strong> Subsubsection One-Two-Three </strong> of a document of the following structure:' => ' Dans cet exemple on est à <strong> Sous section un-deux-trois </strong> dans un document dont la structure est :', 8496 '%{node_file_href} section `%{section}\' in <cite>%{book}</cite>' => '%{node_file_href} section `%{section}\' dans <cite>%{book}</cite>', 8497 'See' => 'Voir', 8498 'See %{node_file_href} <cite>%{book}</cite>' => 'Voir %{node_file_href} <cite>%{book}</cite>', 8499 'See %{node_file_href} section `%{section}\' in <cite>%{book}</cite>' => 'Voir %{node_file_href} section `%{section}\' dans <cite>%{book}</cite>', 8500 'See <cite>%{book}</cite>' => 'Voir <cite>%{book}</cite>', 8501 'See section `%{section}\' in <cite>%{book}</cite>' => 'Voir la section `%{section}\' dans <cite>%{book}</cite>', 8502 'This document was generated by <i>%{user}</i> on <i>%{date}</i> using %{program_homepage_href}.' => 'Ce document a été généré par <i>%{user}</i> <i>%{date}</i> en utilisant %{program_homepage_href}.', 8503 'This document was generated by <i>%{user}</i> using %{program_homepage_href}.' => 'Ce document a été généré par <i>%{user}</i> en utilisant %{program_homepage_href}.', 8504 'This document was generated by @emph{%{user}} on @emph{%{date}} using %{program_homepage_href}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e par @emph{%{user}} @emph{%{date}} en utilisant %{program_homepage_href}.', 8505 'This document was generated by @emph{%{user}} using %{program_homepage_href}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e par @emph{%{user}} en utilisant %{program_homepage_href}.', 8506 'This document was generated on <i>%{date}</i> using %{program_homepage_href}.' => 'Ce document a été généré <i>%{date}</i> en utilisant %{program_homepage_href}.', 8507 'This document was generated on @emph{%{date}} using %{program_homepage_href}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e @emph{%{date}} en utilisant %{program_homepage_href}.', 8508 'This document was generated on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e @emph{%{date}} en utilisant @uref{%{program_homepage}, @emph{%{program}}}.', 8509 'This document was generated using %{program_homepage_href}.' => 'Ce document a @\'et@\'e g@\'en@\'er@\'e en utilisant %{program_homepage_href}.', 8510 'about (help)' => '@`a propos (page d\'aide)', 8511 'about (this page)' => 'a propos (cette page)', 8512 'beginning of this chapter or previous chapter' => 'd@\'ebut de ce chapitre ou chapitre pr@\'ec@\'edent', 8513 'by <i>%{user}</i>' => 'par <i>%{user}</i>', 8514 'by <i>%{user}</i> on <i>%{date}</i>' => 'par <i>%{user}</i> <i>%{date}</i>', 8515 'concept index' => 'index', 8516 'cover (top) of document' => 'couverture (top) du document', 8517 'current section' => 'section actuelle', 8518 'first section in reading order' => 'premi@`e section dans l\'ordre de lecture', 8519 'following node' => 'node suivant', 8520 'index' => 'index', 8521 'last section in reading order' => 'derni@`ere section dans l\'ordre de lecture', 8522 'next chapter' => 'chapitre suivant', 8523 'next node' => 'node suivant', 8524 'next section in reading order' => 'section suivante dans l\'ordre de lecture', 8525 'next section on same level' => 'section suivante au m@^eme niveau', 8526 'node following in node reading order' => 'node suivant dans l\'ordre des nodes', 8527 'node up' => 'node au dessus', 8528 'on <i>%{date}</i>' => '<i>%{date}</i>', 8529 'previous node' => 'node pr@\'ec@\'edent', 8530 'previous section in reading order' => 'section pr@\'ec@\'edente dans l\'ordre de lecture', 8531 'previous section on same level' => 'section pr@\'ec@\'edente au m@^eme niveau', 8532 'section' => 'section', 8533 'section `%{section}\' in <cite>%{book}</cite>' => 'section `%{section}\' dans <cite>%{book}</cite>', 8534 'see' => 'voir', 8535 'see %{node_file_href} <cite>%{book}</cite>' => 'voir %{node_file_href} <cite>%{book}</cite>', 8536 'see %{node_file_href} section `%{section}\' in <cite>%{book}</cite>' => 'voir %{node_file_href} section `%{section}\' dans <cite>%{book}</cite>', 8537 'see <cite>%{book}</cite>' => 'voir <cite>%{book}</cite>', 8538 'see section `%{section}\' in <cite>%{book}</cite>' => 'voir la section `%{section}\' dans <cite>%{book}</cite>', 8539 'short table of contents' => 'table des mati@`eres r@\'esum@\'ee', 8540 'table of contents' => 'table des mati@`eres', 8541 'up node' => 'node au dessus', 8542 'up section' => 'section sup@\'erieure' 8543 }; 8544 8545 8546$LANGUAGES->{'ja'} = { 8547 ' The buttons in the navigation panels have the following meaning:' => 'ナビゲーションパネル中のボタンには以下の意味があります。', 8548 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => '@strong{例}では、以下に示す構造を持つ文書の@strong{1.2.3項}を現在位置に仮定しています。', 8549 ' Up ' => '上', 8550 '%{acronym_like} (%{explanation})' => '', 8551 '%{month} %{day}, %{year}' => '%{year}年%{month}月%{day}日', 8552 '%{name} of %{class}' => '', 8553 '%{name} on %{class}' => '', 8554 '%{node_file_href}' => '', 8555 '%{node_file_href} @cite{%{book}}' => '', 8556 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8557 '%{reference_name}' => '', 8558 '%{style} %{number}' => '', 8559 '%{style}: %{caption_first_line}' => '', 8560 '%{style}: %{shortcaption_first_line}' => '', 8561 '@b{%{quotation_arg}:} ' => '', 8562 '@cite{%{book}}' => '', 8563 'About' => '', 8564 'About (help)' => '', 8565 'About This Document' => 'この文書について', 8566 'April' => '4月', 8567 'August' => '8月', 8568 'Back' => '', 8569 'Back section in previous file' => '', 8570 'Beginning of this chapter or previous chapter' => '', 8571 'Button' => 'ボタン', 8572 'Contents' => '目次', 8573 'Cover (top) of document' => '', 8574 'Current Position' => '現在位置', 8575 'Current section' => '', 8576 'December' => '12月', 8577 'FastBack' => '', 8578 'FastForward' => '', 8579 'February' => '2月', 8580 'First' => '', 8581 'First section in reading order' => '', 8582 'Following' => '', 8583 'Following node' => '', 8584 'Footnotes' => '脚注', 8585 'Forward' => '', 8586 'Forward section in next file' => '', 8587 'From 1.2.3 go to' => '1.2.3項からの移動先', 8588 'Go to' => '移動先', 8589 'Index' => '見出し', 8590 'Index Entry' => '見出し一覧', 8591 'January' => '1月', 8592 'July' => '7月', 8593 'Jump to' => '移動', 8594 'June' => '6月', 8595 'Last' => '', 8596 'Last section in reading order' => '', 8597 'March' => '3月', 8598 'May' => '5月', 8599 'Menu:' => 'メニュー', 8600 'Name' => '名称', 8601 'Next' => '次', 8602 'Next chapter' => '', 8603 'Next file' => '', 8604 'Next node' => '', 8605 'Next section in reading order' => '', 8606 'Next section on same level' => '', 8607 'NextFile' => '', 8608 'Node following in node reading order' => '', 8609 'Node up' => '', 8610 'NodeNext' => '', 8611 'NodePrev' => '', 8612 'NodeUp' => '', 8613 'November' => '11月', 8614 'October' => '10月', 8615 'Overview' => '概要', 8616 'Overview:' => '概要:', 8617 'Prev' => '前', 8618 'PrevFile' => '', 8619 'Previous file' => '', 8620 'Previous node' => '', 8621 'Previous section in reading order' => '', 8622 'Previous section on same level' => '', 8623 'Section' => '項', 8624 'Section One' => '第1項', 8625 'See %{node_file_href}' => '', 8626 'See %{node_file_href} @cite{%{book}}' => '', 8627 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8628 'See %{reference_name}' => '', 8629 'See @cite{%{book}}' => '', 8630 'See section %{reference_name}' => '', 8631 'See section `%{section}\' in @cite{%{book}}' => '', 8632 'September' => '9月', 8633 'Short Table of Contents' => '簡略化した目次', 8634 'Short table of contents' => '', 8635 'Subsection One-Four' => '第1.4項', 8636 'Subsection One-One' => '第1.1項', 8637 'Subsection One-Three' => '第1.3項', 8638 'Subsection One-Two' => '第1.2項', 8639 'Subsubsection One-Two-Four' => '第1.2.4項', 8640 'Subsubsection One-Two-One' => '第1.2.1項', 8641 'Subsubsection One-Two-Three' => '第1.2.3項', 8642 'Subsubsection One-Two-Two' => '第1.2.2項', 8643 'T2H_today' => '%s, %d %d', 8644 'Table of Contents' => '目次', 8645 'Table of contents' => '', 8646 'The node you are looking for is at %{href}.' => '', 8647 'This' => '', 8648 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'この文書は@emph{%{user}}によって@emph{%{date}}に@uref{%{program_homepage}, @emph{%{program}}}を用いて生成されました。', 8649 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'この文書は@emph{%{user}}によって@uref{%{program_homepage}, @emph{%{program}}}を用いて生成されました。', 8650 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => 'この文書は@emph{%{date}}に@uref{%{program_homepage}, @emph{%{program}}}を用いて生成されました。', 8651 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => 'この文書は@uref{%{program_homepage}, @emph{%{program}}}を用いて生成されました。', 8652 'Top' => '冒頭', 8653 'Untitled Document' => '無題の文書', 8654 'Up' => '', 8655 'Up node' => '', 8656 'Up section' => '', 8657 'by @emph{%{user}}' => '@emph{%{user}}', 8658 'by @emph{%{user}} on @emph{%{date}}' => '@emph{%{user}}, @emph{%{date}', 8659 'current' => '現在位置', 8660 'on @emph{%{date}}' => '@emph{%{date}}', 8661 'section `%{section}\' in @cite{%{book}}' => '@cite{%{book}}の `%{section}\' ', 8662 'see %{node_file_href}' => '%{node_file_href}参照', 8663 'see %{node_file_href} @cite{%{book}}' => '%{node_file_href} @cite{%{book}}参照', 8664 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8665 'see %{reference_name}' => '', 8666 'see @cite{%{book}}' => '', 8667 'see section %{reference_name}' => '', 8668 'see section `%{section}\' in @cite{%{book}}' => '', 8669 'unknown' => '不明' 8670 }; 8671 8672$T2H_OBSOLETE_STRINGS->{'ja'} = { 8673 'about (help)' => '使用法 (ヘルプ)', 8674 'beginning of this chapter or previous chapter' => 'この章または前の章の冒頭', 8675 'cover (top) of document' => '文書の表紙 (トップ)', 8676 'current section' => '現在の節', 8677 'first section in reading order' => '文書順で前の項', 8678 'following node' => '次の節', 8679 'index' => '見出し', 8680 'last section in reading order' => '文書順で最後の項', 8681 'next chapter' => '次の章', 8682 'next node' => '次の節', 8683 'next section in reading order' => '文書順で次の項', 8684 'next section on same level' => '同じ階層にある次の項', 8685 'node following in node reading order' => '文書順で次の節', 8686 'node up' => '上の節へ', 8687 'previous node' => '前の節', 8688 'previous section in reading order' => '文書順で前の節', 8689 'previous section on same level' => '同じ階層にある前の項', 8690 'short table of contents' => '簡略化した目次', 8691 'table of contents' => '文書の目次', 8692 'up node' => '上の節', 8693 'up section' => '上の項' 8694 }; 8695 8696 8697$LANGUAGES->{'nl'} = { 8698 ' The buttons in the navigation panels have the following meaning:' => '', 8699 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => '', 8700 ' Up ' => '', 8701 '%{acronym_like} (%{explanation})' => '', 8702 '%{month} %{day}, %{year}' => '', 8703 '%{name} of %{class}' => '', 8704 '%{name} on %{class}' => '', 8705 '%{node_file_href}' => '', 8706 '%{node_file_href} @cite{%{book}}' => '', 8707 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8708 '%{reference_name}' => '', 8709 '%{style} %{number}' => '', 8710 '%{style}: %{caption_first_line}' => '', 8711 '%{style}: %{shortcaption_first_line}' => '', 8712 '@b{%{quotation_arg}:} ' => '', 8713 '@cite{%{book}}' => '', 8714 'About' => '', 8715 'About (help)' => '', 8716 'About This Document' => 'No translation available!', 8717 'April' => 'April', 8718 'August' => 'Augustus', 8719 'Back' => '', 8720 'Back section in previous file' => '', 8721 'Beginning of this chapter or previous chapter' => '', 8722 'Button' => '', 8723 'Contents' => '', 8724 'Cover (top) of document' => '', 8725 'Current Position' => '', 8726 'Current section' => '', 8727 'December' => 'December', 8728 'FastBack' => '', 8729 'FastForward' => '', 8730 'February' => 'Februari', 8731 'First' => '', 8732 'First section in reading order' => '', 8733 'Following' => '', 8734 'Following node' => '', 8735 'Footnotes' => 'No translation available!', 8736 'Forward' => '', 8737 'Forward section in next file' => '', 8738 'From 1.2.3 go to' => '', 8739 'Go to' => '', 8740 'Index' => 'Index', 8741 'Index Entry' => '', 8742 'January' => 'Januari', 8743 'July' => 'Juli', 8744 'Jump to' => '', 8745 'June' => 'Juni', 8746 'Last' => '', 8747 'Last section in reading order' => '', 8748 'March' => 'Maart', 8749 'May' => 'Mei', 8750 'Menu:' => '', 8751 'Name' => '', 8752 'Next' => '', 8753 'Next chapter' => '', 8754 'Next file' => '', 8755 'Next node' => '', 8756 'Next section in reading order' => '', 8757 'Next section on same level' => '', 8758 'NextFile' => '', 8759 'Node following in node reading order' => '', 8760 'Node up' => '', 8761 'NodeNext' => '', 8762 'NodePrev' => '', 8763 'NodeUp' => '', 8764 'November' => 'November', 8765 'October' => 'Oktober', 8766 'Overview' => '', 8767 'Overview:' => '', 8768 'Prev' => '', 8769 'PrevFile' => '', 8770 'Previous file' => '', 8771 'Previous node' => '', 8772 'Previous section in reading order' => '', 8773 'Previous section on same level' => '', 8774 'Section' => '', 8775 'Section One' => '', 8776 'See %{node_file_href}' => '', 8777 'See %{node_file_href} @cite{%{book}}' => '', 8778 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8779 'See %{reference_name}' => '', 8780 'See @cite{%{book}}' => '', 8781 'See section %{reference_name}' => '', 8782 'See section `%{section}\' in @cite{%{book}}' => '', 8783 'September' => 'September', 8784 'Short Table of Contents' => 'Korte inhoudsopgave', 8785 'Short table of contents' => '', 8786 'Subsection One-Four' => '', 8787 'Subsection One-One' => '', 8788 'Subsection One-Three' => '', 8789 'Subsection One-Two' => '', 8790 'Subsubsection One-Two-Four' => '', 8791 'Subsubsection One-Two-One' => '', 8792 'Subsubsection One-Two-Three' => '', 8793 'Subsubsection One-Two-Two' => '', 8794 'T2H_today' => '', 8795 'Table of Contents' => 'Inhoudsopgave', 8796 'Table of contents' => '', 8797 'The node you are looking for is at %{href}.' => '', 8798 'This' => '', 8799 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8800 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8801 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => '', 8802 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8803 'Top' => '', 8804 'Untitled Document' => '', 8805 'Up' => '', 8806 'Up node' => '', 8807 'Up section' => '', 8808 'by @emph{%{user}}' => '', 8809 'by @emph{%{user}} on @emph{%{date}}' => '', 8810 'current' => '', 8811 'on @emph{%{date}}' => '', 8812 'section `%{section}\' in @cite{%{book}}' => '', 8813 'see %{node_file_href}' => '', 8814 'see %{node_file_href} @cite{%{book}}' => '', 8815 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8816 'see %{reference_name}' => '', 8817 'see @cite{%{book}}' => '', 8818 'see section %{reference_name}' => '', 8819 'see section `%{section}\' in @cite{%{book}}' => '', 8820 'unknown' => '' 8821 }; 8822 8823$T2H_OBSOLETE_STRINGS->{'nl'} = { 8824 'See' => 'Zie', 8825 'section' => 'sectie', 8826 'see' => 'zie' 8827 }; 8828 8829 8830$LANGUAGES->{'no'} = { 8831 ' The buttons in the navigation panels have the following meaning:' => '', 8832 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => '', 8833 ' Up ' => '', 8834 '%{acronym_like} (%{explanation})' => '', 8835 '%{month} %{day}, %{year}' => '', 8836 '%{name} of %{class}' => '', 8837 '%{name} on %{class}' => '', 8838 '%{node_file_href}' => '', 8839 '%{node_file_href} @cite{%{book}}' => '', 8840 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8841 '%{reference_name}' => '', 8842 '%{style} %{number}' => '', 8843 '%{style}: %{caption_first_line}' => '', 8844 '%{style}: %{shortcaption_first_line}' => '', 8845 '@b{%{quotation_arg}:} ' => '', 8846 '@cite{%{book}}' => '', 8847 'About' => '', 8848 'About (help)' => '', 8849 'About This Document' => 'No translation available!', 8850 'April' => 'april', 8851 'August' => 'august', 8852 'Back' => '', 8853 'Back section in previous file' => '', 8854 'Beginning of this chapter or previous chapter' => '', 8855 'Button' => '', 8856 'Contents' => '', 8857 'Cover (top) of document' => '', 8858 'Current Position' => '', 8859 'Current section' => '', 8860 'December' => 'desember', 8861 'FastBack' => '', 8862 'FastForward' => '', 8863 'February' => 'februar', 8864 'First' => '', 8865 'First section in reading order' => '', 8866 'Following' => '', 8867 'Following node' => '', 8868 'Footnotes' => 'No translation available!', 8869 'Forward' => '', 8870 'Forward section in next file' => '', 8871 'From 1.2.3 go to' => '', 8872 'Go to' => '', 8873 'Index' => 'Indeks', 8874 'Index Entry' => '', 8875 'January' => 'januar', 8876 'July' => 'juli', 8877 'Jump to' => '', 8878 'June' => 'juni', 8879 'Last' => '', 8880 'Last section in reading order' => '', 8881 'March' => 'mars', 8882 'May' => 'mai', 8883 'Menu:' => '', 8884 'Name' => '', 8885 'Next' => '', 8886 'Next chapter' => '', 8887 'Next file' => '', 8888 'Next node' => '', 8889 'Next section in reading order' => '', 8890 'Next section on same level' => '', 8891 'NextFile' => '', 8892 'Node following in node reading order' => '', 8893 'Node up' => '', 8894 'NodeNext' => '', 8895 'NodePrev' => '', 8896 'NodeUp' => '', 8897 'November' => 'november', 8898 'October' => 'oktober', 8899 'Overview' => '', 8900 'Overview:' => '', 8901 'Prev' => '', 8902 'PrevFile' => '', 8903 'Previous file' => '', 8904 'Previous node' => '', 8905 'Previous section in reading order' => '', 8906 'Previous section on same level' => '', 8907 'Section' => '', 8908 'Section One' => '', 8909 'See %{node_file_href}' => '', 8910 'See %{node_file_href} @cite{%{book}}' => '', 8911 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8912 'See %{reference_name}' => '', 8913 'See @cite{%{book}}' => '', 8914 'See section %{reference_name}' => '', 8915 'See section `%{section}\' in @cite{%{book}}' => '', 8916 'September' => 'september', 8917 'Short Table of Contents' => 'Kort innholdsfortegnelse', 8918 'Short table of contents' => '', 8919 'Subsection One-Four' => '', 8920 'Subsection One-One' => '', 8921 'Subsection One-Three' => '', 8922 'Subsection One-Two' => '', 8923 'Subsubsection One-Two-Four' => '', 8924 'Subsubsection One-Two-One' => '', 8925 'Subsubsection One-Two-Three' => '', 8926 'Subsubsection One-Two-Two' => '', 8927 'T2H_today' => '', 8928 'Table of Contents' => 'Innholdsfortegnelse', 8929 'Table of contents' => '', 8930 'The node you are looking for is at %{href}.' => '', 8931 'This' => '', 8932 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8933 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8934 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => '', 8935 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => '', 8936 'Top' => '', 8937 'Untitled Document' => '', 8938 'Up' => '', 8939 'Up node' => '', 8940 'Up section' => '', 8941 'by @emph{%{user}}' => '', 8942 'by @emph{%{user}} on @emph{%{date}}' => '', 8943 'current' => '', 8944 'on @emph{%{date}}' => '', 8945 'section `%{section}\' in @cite{%{book}}' => '', 8946 'see %{node_file_href}' => '', 8947 'see %{node_file_href} @cite{%{book}}' => '', 8948 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => '', 8949 'see %{reference_name}' => '', 8950 'see @cite{%{book}}' => '', 8951 'see section %{reference_name}' => '', 8952 'see section `%{section}\' in @cite{%{book}}' => '', 8953 'unknown' => '' 8954 }; 8955 8956$T2H_OBSOLETE_STRINGS->{'no'} = { 8957 'See' => 'Se', 8958 'section' => 'avsnitt', 8959 'see' => 'se' 8960 }; 8961 8962 8963$LANGUAGES->{'pt'} = { 8964 ' The buttons in the navigation panels have the following meaning:' => ' Os bot@~oes nos pain@\'eis de navega@,{c}@~ao possuem os seguintes significados:', 8965 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' onde o @strong{ Exemplo } assume que a posi@,{c}@~ao atual localiza-se em @strong{ Subsub@,{c}@~ao Um-Dois-Tr@^es } de um documento com a seguinte estrutura:', 8966 ' Up ' => ' Acima ', 8967 '%{acronym_like} (%{explanation})' => '', 8968 '%{month} %{day}, %{year}' => '%{day} de %{month} de %{year}', 8969 '%{name} of %{class}' => '%{name} da %{class}', 8970 '%{name} on %{class}' => '%{name} na %{class}', 8971 '%{node_file_href}' => '', 8972 '%{node_file_href} @cite{%{book}}' => '', 8973 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '%{node_file_href} se@,{c}@~ao `%{section}\' em @cite{%{book}}', 8974 '%{reference_name}' => '', 8975 '%{style} %{number}' => '', 8976 '%{style}: %{caption_first_line}' => '', 8977 '%{style}: %{shortcaption_first_line}' => '', 8978 '@b{%{quotation_arg}:} ' => '', 8979 '@cite{%{book}}' => '', 8980 'About' => 'Sobre', 8981 'About (help)' => 'Sobre (ajuda)', 8982 'About This Document' => 'Sobre Esse Documento', 8983 'April' => 'Abril', 8984 'August' => 'Agosto', 8985 'Back' => 'Volta', 8986 'Back section in previous file' => '', 8987 'Beginning of this chapter or previous chapter' => 'Come@,{c}o desse cap@\'itulo ou cap@\'itulo anterior', 8988 'Button' => 'Bot@~ao', 8989 'Contents' => 'Conte@\'udo', 8990 'Cover (top) of document' => 'In@\'icio (topo) do documento', 8991 'Current Position' => 'Posi@,{c}@~ao Atual', 8992 'Current section' => 'Se@,{c}@~ao atual', 8993 'December' => 'Dezembro', 8994 'FastBack' => 'Voltar R@\'apido', 8995 'FastForward' => 'Avan@,{c}ar R@\'apido', 8996 'February' => 'Fevereiro', 8997 'First' => 'Primeiro', 8998 'First section in reading order' => 'Primeira se@,{c}@~ao na ordem de leitura', 8999 'Following' => 'Seguinte', 9000 'Following node' => 'Nodo seguinte', 9001 'Footnotes' => 'Notas de Rodap@\'e', 9002 'Forward' => 'Avan@,{c}ar', 9003 'Forward section in next file' => '', 9004 'From 1.2.3 go to' => 'De 1.2.3 v@\'a para', 9005 'Go to' => 'V@\'a para', 9006 'Index' => '@\'Indice', 9007 'Index Entry' => 'Entrada de @\'Indice', 9008 'January' => 'Janeiro', 9009 'July' => 'Julho', 9010 'Jump to' => 'Pular para', 9011 'June' => 'Junho', 9012 'Last' => '@\'Ultimo', 9013 'Last section in reading order' => '@\'Ultima se@,{c}@~ao na ordem de leitura', 9014 'March' => 'Mar@,{c}o', 9015 'May' => 'Maio', 9016 'Menu:' => '', 9017 'Name' => 'Nome', 9018 'Next' => 'Pr@\'oximo', 9019 'Next chapter' => 'Pr@\'oximo cap@\'itulo', 9020 'Next file' => '', 9021 'Next node' => 'Pr@\'oximo nodo', 9022 'Next section in reading order' => 'Pr@\'oxima se@,{c}@~ao na ordem de leitura', 9023 'Next section on same level' => 'Pr@\'oxima se@,{c}@~ao no mesmo n@\'ivel', 9024 'NextFile' => '', 9025 'Node following in node reading order' => 'Nodo seguinte na ordem de leitura de nodos', 9026 'Node up' => 'Nodo acima', 9027 'NodeNext' => 'Pr@\'oximo Nodo', 9028 'NodePrev' => 'Nodo Anterior', 9029 'NodeUp' => 'Nodo Acima', 9030 'November' => 'Novembro', 9031 'October' => 'Outubro', 9032 'Overview' => 'Vis@~ao geral', 9033 'Overview:' => 'Vis@~ao geral:', 9034 'Prev' => 'Pr@\'evio', 9035 'PrevFile' => '', 9036 'Previous file' => '', 9037 'Previous node' => 'Nodo anterior', 9038 'Previous section in reading order' => 'Se@,{c}@~ao anterior na ordem de leitura', 9039 'Previous section on same level' => 'Se@,{c}@~ao anterior no mesmo n@\'ivel', 9040 'Section' => 'Se@,{c}@~ao', 9041 'Section One' => 'Se@,{c}@~ao Um', 9042 'See %{node_file_href}' => 'Veja %{node_file_href}', 9043 'See %{node_file_href} @cite{%{book}}' => 'Veja %{node_file_href} @cite{%{book}}', 9044 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'Veja %{node_file_href} se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9045 'See %{reference_name}' => 'Veja %{reference_name}', 9046 'See @cite{%{book}}' => 'Veja @cite{%{book}}', 9047 'See section %{reference_name}' => 'Veja se@,{c}@~ao %{reference_name}', 9048 'See section `%{section}\' in @cite{%{book}}' => 'Veja se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9049 'September' => 'Setembro', 9050 'Short Table of Contents' => 'Breve Sum@\'ario', 9051 'Short table of contents' => 'Breve sum@\'ario', 9052 'Subsection One-Four' => 'Subse@,{c}@~ao Um-Quatro', 9053 'Subsection One-One' => 'Subse@,{c}@~ao Um-Um', 9054 'Subsection One-Three' => 'Subse@,{c}@~ao Um-Tr@^es', 9055 'Subsection One-Two' => 'Subse@,{c}@~ao Um-Dois', 9056 'Subsubsection One-Two-Four' => 'Subse@,{c}@~ao Um-Dois-Quatro', 9057 'Subsubsection One-Two-One' => 'Subse@,{c}@~ao Um-Dois-Um', 9058 'Subsubsection One-Two-Three' => 'Subse@,{c}@~ao Um-Dois-Tr@^es', 9059 'Subsubsection One-Two-Two' => 'Subse@,{c}@~ao Um-Dois-Dois', 9060 'T2H_today' => '', 9061 'Table of Contents' => 'Sum@\'ario', 9062 'Table of contents' => 'Sum@\'ario', 9063 'The node you are looking for is at %{href}.' => 'O nodo que vo@^e est@\'a olhando est@\'a em %{href}.', 9064 'This' => 'Esse', 9065 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Esse documento foi gereado por @emph{%{user}} em @emph{%{date}} usando @uref{%{program_homepage}, @emph{%{program}}}.', 9066 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Esse documento foi gerado por @emph{%{user}} usando @uref{%{program_homepage}, @emph{%{program}}}.', 9067 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => 'Esse documento foi gerado em @i{%{date}} usando @uref{%{program_homepage}, @i{%{program}}}.', 9068 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Esse documento foi gerado usando @uref{%{program_homepage}, @emph{%{program}}}.', 9069 'Top' => 'Topo', 9070 'Untitled Document' => 'Documento Sem Nome', 9071 'Up' => 'Acima', 9072 'Up node' => 'Nodo acima', 9073 'Up section' => 'Se@,{c}@~ao acima', 9074 'by @emph{%{user}}' => 'por @emph{%{user}}', 9075 'by @emph{%{user}} on @emph{%{date}}' => 'por @emph{%{user}} em @emph{%{date}}', 9076 'current' => 'atual', 9077 'on @emph{%{date}}' => 'em @emph{%{date}}', 9078 'section `%{section}\' in @cite{%{book}}' => 'se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9079 'see %{node_file_href}' => 'veja %{node_file_href}', 9080 'see %{node_file_href} @cite{%{book}}' => 'veja %{node_file_href} @cite{%{book}}', 9081 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'veja %{node_file_href} se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9082 'see %{reference_name}' => 'veja %{reference_name}', 9083 'see @cite{%{book}}' => 'veja @cite{%{book}}', 9084 'see section %{reference_name}' => 'veja se@,{c}@~ao %{reference_name}', 9085 'see section `%{section}\' in @cite{%{book}}' => 'veja se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9086 'unknown' => 'desconhecido' 9087 }; 9088 9089$T2H_OBSOLETE_STRINGS->{'pt'} = { 9090 'See' => 'Veja', 9091 'about (help)' => 'sobre (ajuda)', 9092 'beginning of this chapter or previous chapter' => 'come@,{c}o desse cap@\'itulo ou cap@\'itulo anterior', 9093 'cover (top) of document' => 'in@\'icio (topo) do documento', 9094 'current section' => 'se@,{c}@~ao atual', 9095 'first section in reading order' => 'primeira se@,{c}@~ao na ordem de leitura', 9096 'following node' => 'nodo seguinte', 9097 'index' => '@\'indice', 9098 'last section in reading order' => '@\'ultima se@,{c}@~ao na ordem de leitura', 9099 'next chapter' => 'pr@\'oximo cap@\'itulo', 9100 'next node' => 'pr@\'oximo nodo', 9101 'next section in reading order' => 'pr@\'oxima se@,{c}@~ao na ordem de leitura', 9102 'next section on same level' => 'pr@\'oxima se@,{c}@~ao no mesmo n@\'ivel', 9103 'node following in node reading order' => 'nodo seguinte na ordem de leitura de nodos', 9104 'node up' => 'nodo acima', 9105 'previous node' => 'nodo anterior', 9106 'previous section in reading order' => 'se@,{c}@~ao anterior na ordem de leitura', 9107 'previous section on same level' => 'se@,{c}@~ao anterior no mesmo n@\'ivel', 9108 'section' => 'Se@,{c}@~ao', 9109 'see' => 'veja', 9110 'short table of contents' => 'breve sum@\'ario', 9111 'table of contents' => 'sum@\'ario', 9112 'up node' => 'nodo acima', 9113 'up section' => 'se@,{c}@~ao acima' 9114 }; 9115 9116 9117$LANGUAGES->{'pt_BR'} = { 9118 ' The buttons in the navigation panels have the following meaning:' => ' Os bot@~oes nos pain@\'eis de navega@,{c}@~ao possuem os seguintes significados:', 9119 ' where the @strong{ Example } assumes that the current position is at @strong{ Subsubsection One-Two-Three } of a document of the following structure:' => ' onde o @strong{ Exemplo } assume que a posi@,{c}@~ao atual localiza-se em @strong{ Subsub@,{c}@~ao Um-Dois-Tr@^es } de um documento com a seguinte estrutura:', 9120 ' Up ' => ' Acima ', 9121 '%{acronym_like} (%{explanation})' => '', 9122 '%{month} %{day}, %{year}' => '%{day} de %{month} de %{year}', 9123 '%{name} of %{class}' => '%{name} da %{class}', 9124 '%{name} on %{class}' => '%{name} na %{class}', 9125 '%{node_file_href}' => '', 9126 '%{node_file_href} @cite{%{book}}' => '', 9127 '%{node_file_href} section `%{section}\' in @cite{%{book}}' => '%{node_file_href} se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9128 '%{reference_name}' => '', 9129 '%{style} %{number}' => '', 9130 '%{style}: %{caption_first_line}' => '', 9131 '%{style}: %{shortcaption_first_line}' => '', 9132 '@b{%{quotation_arg}:} ' => '', 9133 '@cite{%{book}}' => '', 9134 'About' => 'Sobre', 9135 'About (help)' => 'Sobre (ajuda)', 9136 'About This Document' => 'Sobre Esse Documento', 9137 'April' => 'Abril', 9138 'August' => 'Agosto', 9139 'Back' => 'Volta', 9140 'Back section in previous file' => '', 9141 'Beginning of this chapter or previous chapter' => 'Come@,{c}o desse cap@\'itulo ou cap@\'itulo anterior', 9142 'Button' => 'Bot@~ao', 9143 'Contents' => 'Conte@\'udo', 9144 'Cover (top) of document' => 'In@\'icio (topo) do documento', 9145 'Current Position' => 'Posi@,{c}@~ao Atual', 9146 'Current section' => 'Se@,{c}@~ao atual', 9147 'December' => 'Dezembro', 9148 'FastBack' => 'Voltar R@\'apido', 9149 'FastForward' => 'Avan@,{c}ar R@\'apido', 9150 'February' => 'Fevereiro', 9151 'First' => 'Primeiro', 9152 'First section in reading order' => 'Primeira se@,{c}@~ao na ordem de leitura', 9153 'Following' => 'Seguinte', 9154 'Following node' => 'Nodo seguinte', 9155 'Footnotes' => 'Notas de Rodap@\'e', 9156 'Forward' => 'Avan@,{c}ar', 9157 'Forward section in next file' => '', 9158 'From 1.2.3 go to' => 'De 1.2.3 v@\'a para', 9159 'Go to' => 'V@\'a para', 9160 'Index' => '@\'Indice', 9161 'Index Entry' => 'Entrada de @\'Indice', 9162 'January' => 'Janeiro', 9163 'July' => 'Julho', 9164 'Jump to' => 'Pular para', 9165 'June' => 'Junho', 9166 'Last' => '@\'Ultimo', 9167 'Last section in reading order' => '@\'Ultima se@,{c}@~ao na ordem de leitura', 9168 'March' => 'Mar@,{c}o', 9169 'May' => 'Maio', 9170 'Menu:' => '', 9171 'Name' => 'Nome', 9172 'Next' => 'Pr@\'oximo', 9173 'Next chapter' => 'Pr@\'oximo cap@\'itulo', 9174 'Next file' => '', 9175 'Next node' => 'Pr@\'oximo nodo', 9176 'Next section in reading order' => 'Pr@\'oxima se@,{c}@~ao na ordem de leitura', 9177 'Next section on same level' => 'Pr@\'oxima se@,{c}@~ao no mesmo n@\'ivel', 9178 'NextFile' => '', 9179 'Node following in node reading order' => 'Nodo seguinte na ordem de leitura de nodos', 9180 'Node up' => 'Nodo acima', 9181 'NodeNext' => 'Pr@\'oximo Nodo', 9182 'NodePrev' => 'Nodo Anterior', 9183 'NodeUp' => 'Nodo Acima', 9184 'November' => 'Novembro', 9185 'October' => 'Outubro', 9186 'Overview' => 'Vis@~ao geral', 9187 'Overview:' => 'Vis@~ao geral:', 9188 'Prev' => 'Pr@\'evio', 9189 'PrevFile' => '', 9190 'Previous file' => '', 9191 'Previous node' => 'Nodo anterior', 9192 'Previous section in reading order' => 'Se@,{c}@~ao anterior na ordem de leitura', 9193 'Previous section on same level' => 'Se@,{c}@~ao anterior no mesmo n@\'ivel', 9194 'Section' => 'Se@,{c}@~ao', 9195 'Section One' => 'Se@,{c}@~ao Um', 9196 'See %{node_file_href}' => 'Veja %{node_file_href}', 9197 'See %{node_file_href} @cite{%{book}}' => 'Veja %{node_file_href} @cite{%{book}}', 9198 'See %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'Veja %{node_file_href} se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9199 'See %{reference_name}' => 'Veja %{reference_name}', 9200 'See @cite{%{book}}' => 'Veja @cite{%{book}}', 9201 'See section %{reference_name}' => 'Veja se@,{c}@~ao %{reference_name}', 9202 'See section `%{section}\' in @cite{%{book}}' => 'Veja se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9203 'September' => 'Setembro', 9204 'Short Table of Contents' => 'Breve Sum@\'ario', 9205 'Short table of contents' => 'Breve sum@\'ario', 9206 'Subsection One-Four' => 'Subse@,{c}@~ao Um-Quatro', 9207 'Subsection One-One' => 'Subse@,{c}@~ao Um-Um', 9208 'Subsection One-Three' => 'Subse@,{c}@~ao Um-Tr@^es', 9209 'Subsection One-Two' => 'Subse@,{c}@~ao Um-Dois', 9210 'Subsubsection One-Two-Four' => 'Subse@,{c}@~ao Um-Dois-Quatro', 9211 'Subsubsection One-Two-One' => 'Subse@,{c}@~ao Um-Dois-Um', 9212 'Subsubsection One-Two-Three' => 'Subse@,{c}@~ao Um-Dois-Tr@^es', 9213 'Subsubsection One-Two-Two' => 'Subse@,{c}@~ao Um-Dois-Dois', 9214 'T2H_today' => '', 9215 'Table of Contents' => 'Sum@\'ario', 9216 'Table of contents' => 'Sum@\'ario', 9217 'The node you are looking for is at %{href}.' => 'O nodo que vo@^e est@\'a olhando est@\'a em %{href}.', 9218 'This' => 'Esse', 9219 'This document was generated by @emph{%{user}} on @emph{%{date}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Esse documento foi gereado por @emph{%{user}} em @emph{%{date}} usando @uref{%{program_homepage}, @emph{%{program}}}.', 9220 'This document was generated by @emph{%{user}} using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Esse documento foi gerado por @emph{%{user}} usando @uref{%{program_homepage}, @emph{%{program}}}.', 9221 'This document was generated on @i{%{date}} using @uref{%{program_homepage}, @i{%{program}}}.' => 'Esse documento foi gerado em @i{%{date}} usando @uref{%{program_homepage}, @i{%{program}}}.', 9222 'This document was generated using @uref{%{program_homepage}, @emph{%{program}}}.' => 'Esse documento foi gerado usando @uref{%{program_homepage}, @emph{%{program}}}.', 9223 'Top' => 'Topo', 9224 'Untitled Document' => 'Documento Sem Nome', 9225 'Up' => 'Acima', 9226 'Up node' => 'Nodo acima', 9227 'Up section' => 'Se@,{c}@~ao acima', 9228 'by @emph{%{user}}' => 'por @emph{%{user}}', 9229 'by @emph{%{user}} on @emph{%{date}}' => 'por @emph{%{user}} em @emph{%{date}}', 9230 'current' => 'atual', 9231 'on @emph{%{date}}' => 'em @emph{%{date}}', 9232 'section `%{section}\' in @cite{%{book}}' => 'se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9233 'see %{node_file_href}' => 'veja %{node_file_href}', 9234 'see %{node_file_href} @cite{%{book}}' => 'veja %{node_file_href} @cite{%{book}}', 9235 'see %{node_file_href} section `%{section}\' in @cite{%{book}}' => 'veja %{node_file_href} se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9236 'see %{reference_name}' => 'veja %{reference_name}', 9237 'see @cite{%{book}}' => 'veja @cite{%{book}}', 9238 'see section %{reference_name}' => 'veja se@,{c}@~ao %{reference_name}', 9239 'see section `%{section}\' in @cite{%{book}}' => 'veja se@,{c}@~ao `%{section}\' em @cite{%{book}}', 9240 'unknown' => 'desconhecido' 9241 }; 9242 9243$T2H_OBSOLETE_STRINGS->{'pt_BR'} = { 9244 'See' => 'Veja', 9245 'about (help)' => 'sobre (ajuda)', 9246 'beginning of this chapter or previous chapter' => 'come@,{c}o desse cap@\'itulo ou cap@\'itulo anterior', 9247 'cover (top) of document' => 'in@\'icio (topo) do documento', 9248 'current section' => 'se@,{c}@~ao atual', 9249 'first section in reading order' => 'primeira se@,{c}@~ao na ordem de leitura', 9250 'following node' => 'nodo seguinte', 9251 'index' => '@\'indice', 9252 'last section in reading order' => '@\'ultima se@,{c}@~ao na ordem de leitura', 9253 'next chapter' => 'pr@\'oximo cap@\'itulo', 9254 'next node' => 'pr@\'oximo nodo', 9255 'next section in reading order' => 'pr@\'oxima se@,{c}@~ao na ordem de leitura', 9256 'next section on same level' => 'pr@\'oxima se@,{c}@~ao no mesmo n@\'ivel', 9257 'node following in node reading order' => 'nodo seguinte na ordem de leitura de nodos', 9258 'node up' => 'nodo acima', 9259 'previous node' => 'nodo anterior', 9260 'previous section in reading order' => 'se@,{c}@~ao anterior na ordem de leitura', 9261 'previous section on same level' => 'se@,{c}@~ao anterior no mesmo n@\'ivel', 9262 'section' => 'Se@,{c}@~ao', 9263 'see' => 'veja', 9264 'short table of contents' => 'breve sum@\'ario', 9265 'table of contents' => 'sum@\'ario', 9266 'up node' => 'nodo acima', 9267 'up section' => 'se@,{c}@~ao acima' 9268 }; 9269 9270 9271 9272require "$T2H_HOME/$translation_file" 9273 if ($0 =~ /\.pl$/ && 9274 -e "$T2H_HOME/$translation_file" && -r "$T2H_HOME/$translation_file"); 9275 9276# 9277# Some functions used to override normal formatting functions in specific 9278# cases. The user shouldn't want to change them, but can use them. 9279# 9280 9281# used to utf8 encode the result 9282sub t2h_utf8_accent($$$) 9283{ 9284 my $accent = shift; 9285 my $args = shift; 9286 my $style_stack = shift; 9287 9288 my $text = $args->[0]; 9289 #print STDERR "$accent\[".scalar(@$style_stack) ."\] (@$style_stack)\n"; 9290 9291 # special handling of @dotless{i} 9292 if ($accent eq 'dotless') 9293 { 9294 if (($text eq 'i') and (!defined($style_stack->[-1]) or (!defined($unicode_accents{$style_stack->[-1]})) or ($style_stack->[-1] eq 'tieaccent'))) 9295 { 9296 return "\x{0131}"; 9297 } 9298 #return "\x{}" if ($text eq 'j'); # not found ! 9299 return $text; 9300 } 9301 9302 # FIXME \x{0131}\x{0308} for @dotless{i} @" doesn't lead to NFC 00ef. 9303 return Unicode::Normalize::NFC($text . chr(hex($unicode_diacritical{$accent}))) 9304 if (defined($unicode_diacritical{$accent})); 9305 return ascii_accents($text, $accent); 9306} 9307 9308sub t2h_utf8_normal_text($$$$$) 9309{ 9310 my $text = shift; 9311 my $in_raw_text = shift; 9312 my $in_preformatted = shift; 9313 my $in_code = shift; 9314 my $in_simple = shift; 9315 my $style_stack = shift; 9316 9317 $text = &$protect_text($text) unless($in_raw_text); 9318 $text = uc($text) if (in_small_caps($style_stack)); 9319 9320 if (!$in_code and !$in_preformatted) 9321 { 9322 $text =~ s/---/\x{2014}/g; 9323 $text =~ s/--/\x{2013}/g; 9324 $text =~ s/``/\x{201C}/g; 9325 $text =~ s/''/\x{201D}/g; 9326 } 9327 return Unicode::Normalize::NFC($text); 9328} 9329 9330# these are unlikely to be used by users, as they are essentially 9331# used to follow the html external refs specification in texinfo 9332sub t2h_cross_manual_normal_text($$$$$) 9333{ 9334 my $text = shift; 9335 my $in_raw_text = shift; 9336 my $in_preformatted = shift; 9337 my $in_code =shift; 9338 my $in_simple =shift; 9339 my $style_stack = shift; 9340 9341 $text = uc($text) if (in_small_caps($style_stack)); 9342 return $text if ($USE_UNICODE); 9343 return t2h_no_unicode_cross_manual_normal_text($text, 0); 9344} 9345 9346sub t2h_cross_manual_normal_text_transliterate($$$$$) 9347{ 9348 my $text = shift; 9349 my $in_raw_text = shift; 9350 my $in_preformatted = shift; 9351 my $in_code =shift; 9352 my $in_simple =shift; 9353 my $style_stack = shift; 9354 9355 $text = uc($text) if (in_small_caps($style_stack)); 9356 return $text if ($USE_UNICODE); 9357 return t2h_no_unicode_cross_manual_normal_text($text, 1); 9358} 9359 9360sub t2h_no_unicode_cross_manual_normal_text($$) 9361{ 9362 # if there is no unicode support, we do all the transformations here 9363 my $text = shift; 9364 my $transliterate = shift; 9365 my $result = ''; 9366 9367 my $encoding = $Texi2HTML::THISDOC{'DOCUMENT_ENCODING'}; 9368 if (defined($encoding) and exists($t2h_encoding_aliases{$encoding})) 9369 { 9370 $encoding = $t2h_encoding_aliases{$encoding}; 9371 } 9372 9373 while ($text ne '') 9374 { 9375 if ($text =~ s/^([A-Za-z0-9]+)//o) 9376 { 9377 $result .= $1; 9378 } 9379 elsif ($text =~ s/^ //o) 9380 { 9381 $result .= '-'; 9382 } 9383 elsif ($text =~ s/^(.)//o) 9384 { 9385 if (exists($ascii_character_map{$1})) 9386 { 9387 $result .= '_' . lc($ascii_character_map{$1}); 9388 } 9389 else 9390 { 9391 my $character = $1; 9392 my $charcode = uc(sprintf("%02x",ord($1))); 9393 my $done = 0; 9394 if (defined($encoding) and exists($eight_bit_to_unicode{$encoding}) 9395 and exists($eight_bit_to_unicode{$encoding}->{$charcode})) 9396 { 9397 $done = 1; 9398 my $unicode_point = $eight_bit_to_unicode{$encoding}->{$charcode}; 9399 if (!$transliterate) 9400 { 9401 $result .= '_' . lc($unicode_point); 9402 } 9403 elsif (exists($transliterate_map{$unicode_point})) 9404 { 9405 $result .= $transliterate_map{$unicode_point}; 9406 } 9407 elsif (exists($unicode_diacritical{$unicode_point})) 9408 { 9409 $result .= ''; 9410 } 9411 else 9412 { 9413 $done = 0; 9414 } 9415 } 9416 9417 if (!$done) 9418 { # wild guess that work for latin1, and thus, should fail 9419 $result .= '_' . '00' . lc($charcode); 9420 } 9421 } 9422 } 9423 else 9424 { 9425 echo_error("Bug: unknown character in cross ref (likely in infinite loop)"); 9426 } 9427 } 9428 9429 return $result; 9430} 9431 9432sub t2h_nounicode_cross_manual_accent($$$) 9433{ 9434 my $accent = shift; 9435 my $args = shift; 9436 my $style_stack = shift; 9437 9438 my $text = $args->[0]; 9439 9440 if ($accent eq 'dotless') 9441 { 9442 if (($text eq 'i') and (!defined($style_stack->[-1]) or (!defined($unicode_accents{$style_stack->[-1]})) or ($style_stack->[-1] eq 'tieaccent'))) 9443 { 9444 return "_0131"; 9445 } 9446 #return "\x{}" if ($text eq 'j'); # not found ! 9447 return $text; 9448 } 9449 return '_' . lc($unicode_accents{$accent}->{$text}) 9450 if (defined($unicode_accents{$accent}->{$text})); 9451 return ($text . '_' . lc($unicode_diacritical{$accent})) 9452 if (defined($unicode_diacritical{$accent})); 9453 return ascii_accents($text, $accent); 9454} 9455 9456sub t2h_transliterate_cross_manual_accent($$) 9457{ 9458 my $accent = shift; 9459 my $args = shift; 9460 9461 my $text = $args->[0]; 9462 9463 if (exists($unicode_accents{$accent}->{$text}) and 9464 exists ($transliterate_map{$unicode_accents{$accent}->{$text}})) 9465 { 9466 return $transliterate_map{$unicode_accents{$accent}->{$text}}; 9467 } 9468 return $text; 9469} 9470 9471 9472} # end package Texi2HTML::Config 9473 9474use vars qw( 9475%value 9476%alias 9477); 9478 9479# variables which might be redefined by the user but aren't likely to be 9480# they seem to be in the main namespace 9481use vars qw( 9482%index_names 9483%index_prefix_to_name 9484%predefined_index 9485%valid_index 9486%reference_sec2level 9487%code_style_map 9488%forbidden_index_name 9489); 9490 9491# Some global variables are set in the script, and used in the subroutines 9492# they are in the Texi2HTML namespace, thus prefixed with Texi2HTML::. 9493# see texi2html.init for details. 9494 9495#+++############################################################################ 9496# # 9497# Pasted content of File $(srcdir)/MySimple.pm: Command-line processing # 9498# # 9499#---############################################################################ 9500 9501# leave this within comments, and keep the require statement 9502# This way, you can directly run texi2html.pl, if $T2H_HOME/MySimple.pm 9503# exists. 9504 9505# @MYSIMPLE@ 9506package Getopt::MySimple; 9507 9508# Name: 9509# Getopt::MySimple. 9510# 9511# Documentation: 9512# POD-style (incomplete) documentation is in file MySimple.pod 9513# 9514# Tabs: 9515# 4 spaces || die. 9516# 9517# Author: 9518# Ron Savage rpsavage@ozemail.com.au. 9519# 1.00 19-Aug-97 Initial version. 9520# 1.10 13-Oct-97 Add arrays of switches (eg '=s@'). 9521# 1.20 3-Dec-97 Add 'Help' on a per-switch basis. 9522# 1.30 11-Dec-97 Change 'Help' to 'verbose'. Make all hash keys lowercase. 9523# 1.40 10-Nov-98 Change width of help report. Restructure tests. 9524# 1-Jul-00 Modifications for Texi2html 9525 9526# -------------------------------------------------------------------------- 9527# Locally modified by obachman (Display type instead of env, order by cmp) 9528# $Id: MySimple.pm,v 1.6 2008/11/26 19:09:01 pertusus Exp $ 9529 9530# use strict; 9531# no strict 'refs'; 9532 9533use vars qw(@EXPORT @EXPORT_OK @ISA); 9534use vars qw($fieldWidth $opt $VERSION); 9535 9536use Exporter(); 9537use Getopt::Long; 9538 9539@ISA = qw(Exporter); 9540@EXPORT = qw(); 9541@EXPORT_OK = qw($opt); # An alias for $self -> {'opt'}. 9542 9543# -------------------------------------------------------------------------- 9544 9545$fieldWidth = 20; 9546$VERSION = '1.41'; 9547 9548# -------------------------------------------------------------------------- 9549 9550sub byOrder 9551{ 9552 my($self) = @_; 9553 9554 return uc($a) cmp (uc($b)); 9555} 9556 9557# -------------------------------------------------------------------------- 9558 9559sub dumpOptions 9560{ 9561 my($self) = @_; 9562 9563 print 'Option', ' ' x ($fieldWidth - length('Option') ), "Value\n"; 9564 9565 for (sort byOrder keys(%{$self -> {'opt'} }) ) 9566 { 9567 print "-$_", ' ' x ($fieldWidth - (1 + length) ), "${$self->{'opt'} }{$_}\n"; 9568 } 9569 9570 print "\n"; 9571 9572} # End of dumpOptions. 9573 9574# -------------------------------------------------------------------------- 9575# Return: 9576# 0 -> Error. 9577# 1 -> Ok. 9578 9579sub getOptions 9580{ 9581 push(@_, 0) if ($#_ == 2); # Default for $ignoreCase is 0. 9582 push(@_, 1) if ($#_ == 3); # Default for $helpThenExit is 1. 9583 9584 my($self, $default, $helpText, $versionText, 9585 $helpThenExit, $versionThenExit, $ignoreCase) = @_; 9586 9587 $helpThenExit = 1 unless (defined($helpThenExit)); 9588 $versionThenExit = 1 unless (defined($versionThenExit)); 9589 $ignoreCase = 0 unless (defined($ignoreCase)); 9590 9591 $self -> {'default'} = $default; 9592 $self -> {'helpText'} = $helpText; 9593 $self -> {'versionText'} = $versionText; 9594 $Getopt::Long::ignorecase = $ignoreCase; 9595 9596 unless (defined($self -> {'default'}{'help'})) 9597 { 9598 $self -> {'default'}{'help'} = 9599 { 9600 type => ':i', 9601 default => '', 9602 linkage => sub {$self->helpOptions($_[1]); sleep 5;exit (0) if $helpThenExit;}, 9603 verbose => "print help and exit" 9604 }; 9605 } 9606 9607 unless (defined($self -> {'default'}{'version'})) 9608 { 9609 $self -> {'default'}{'version'} = 9610 { 9611 type => '', 9612 default => '', 9613 linkage => sub {print $self->{'versionText'}; exit (0) if $versionThenExit;}, 9614 verbose => "print version and exit" 9615 }; 9616 } 9617 9618 for (keys(%{$self -> {'default'} }) ) 9619 { 9620 next unless (ref(${$self -> {'default'} }{$_}) eq 'HASH'); 9621 my $type = ${$self -> {'default'} }{$_}{'type'}; 9622 push(@{$self -> {'type'} }, "$_$type"); 9623 $self->{'opt'}->{$_} = ${$self -> {'default'} }{$_}{'linkage'} 9624 if ${$self -> {'default'} }{$_}{'linkage'}; 9625 } 9626 9627 my($result) = &GetOptions($self -> {'opt'}, @{$self -> {'type'} }); 9628 9629 return $result unless $result; 9630 9631 for (keys(%{$self -> {'default'} }) ) 9632 { 9633 if (! defined(${$self -> {'opt'} }{$_})) #{ 9634 { 9635 ${$self -> {'opt'} }{$_} = ${$self -> {'default'} }{$_}{'default'}; 9636 } 9637 } 9638 9639 $result; 9640} # End of getOptions. 9641 9642# -------------------------------------------------------------------------- 9643 9644sub helpOptions 9645{ 9646 my($self) = shift; 9647 my($noHelp) = shift; 9648 $noHelp = 0 unless $noHelp; 9649 my($optwidth, $typewidth, $defaultwidth, $maxlinewidth, $valind, $valwidth) 9650 = (10, 5, 9, 78, 4, 11); 9651 9652 print "$self->{'helpText'}" if ($self -> {'helpText'}); 9653 9654 print ' Option', ' ' x ($optwidth - length('Option') -1 ), 9655 'Type', ' ' x ($typewidth - length('Type') + 1), 9656 'Default', ' ' x ($defaultwidth - length('Default') ), 9657 "Description\n"; 9658 9659 for (sort byOrder keys(%{$self -> {'default'} }) ) 9660 { 9661 my($line, $help, $option, $val); 9662 $option = $_; 9663 next if ${$self->{'default'} }{$_}{'noHelp'} && ${$self->{'default'} }{$_}{'noHelp'} > $noHelp; 9664 #$line = " -$_" . ' ' x ($optwidth - (2 + length) ) . 9665 # "${$self->{'default'} }{$_}{'type'} ". 9666 # ' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) )); 9667 $line = " --$_" . "${$self->{'default'} }{$_}{'type'}". 9668 ' ' x ($typewidth - (1+length(${$self -> {'default'} }{$_}{'type'}) )); 9669 9670 $val = ${$self->{'default'} }{$_}{'linkage'}; 9671 if ($val) 9672 { 9673 if ((ref($val) eq 'SCALAR') and (defined($$val))) 9674 { 9675 $val = $$val; 9676 } 9677 else 9678 { 9679 $val = ''; 9680 } 9681 } 9682 elsif (defined(${$self->{'default'} }{$_}{'default'})) 9683 { 9684 $val = ${$self->{'default'} }{$_}{'default'}; 9685 } 9686 else 9687 { 9688 $val = ''; 9689 } 9690 $line .= "$val "; 9691 $line .= ' ' x ($optwidth + $typewidth + $defaultwidth + 1 - length($line)); 9692 9693 if (defined(${$self -> {'default'} }{$_}{'verbose'}) && 9694 ${$self -> {'default'} }{$_}{'verbose'} ne '') 9695 { 9696 $help = "${$self->{'default'} }{$_}{'verbose'}"; 9697 } 9698 else 9699 { 9700 $help = ' '; 9701 } 9702 if ((length("$line") + length($help)) < $maxlinewidth) 9703 { 9704 print $line , $help, "\n"; 9705 } 9706 else 9707 { 9708 print $line, "\n", ' ' x $valind, $help, "\n"; 9709 } 9710 for $val (sort byOrder keys(%{${$self->{'default'}}{$option}{'values'}})) 9711 { 9712 print ' ' x ($valind + 2); 9713 print $val, ' ', ' ' x ($valwidth - length($val) - 2); 9714 print ${$self->{'default'}}{$option}{'values'}{$val}, "\n"; 9715 } 9716 } 9717 9718 print <<EOT; 9719Note: 'Options' may be abbreviated. -- prefix may be replaced by a single -. 9720'Type' specifications mean: 9721 <none>| ! no argument: variable is set to 1 on -foo (or, to 0 on -nofoo) 9722 =s | :s mandatory (or, optional) string argument 9723 =i | :i mandatory (or, optional) integer argument 9724EOT 9725} # End of helpOptions. 9726 9727#------------------------------------------------------------------- 9728 9729sub new 9730{ 9731 my($class) = @_; 9732 my($self) = {}; 9733 $self -> {'default'} = {}; 9734 $self -> {'helpText'} = ''; 9735 $self -> {'opt'} = {}; 9736 $opt = $self -> {'opt'}; # An alias for $self -> {'opt'}. 9737 $self -> {'type'} = (); 9738 9739 return bless $self, $class; 9740 9741} # End of new. 9742 9743# -------------------------------------------------------------------------- 9744 97451; 9746 9747# End MySimple.pm 9748 9749require "$T2H_HOME/MySimple.pm" 9750 if ($0 =~ /\.pl$/ && 9751 -e "$T2H_HOME/MySimple.pm" && -r "$T2H_HOME/MySimple.pm"); 9752 9753#+++######################################################################## 9754# # 9755# Pasted content of File $(srcdir)/T2h_i18n.pm: Internationalisation # 9756# # 9757#---######################################################################## 9758 9759# leave this within comments, and keep the require statement 9760# This way, you can directly run texi2html.pl, if $T2H_HOME/T2h_i18n.pm 9761# exists. 9762 9763# @T2H_I18N@ 9764#+############################################################################## 9765# 9766# T2h_i18n.pm: Internationalization for texi2html 9767# 9768# Copyright (C) 1999-2005 Patrice Dumas <dumas@centre-cired.fr>, 9769# Derek Price <derek@ximbiot.com>, 9770# Adrian Aichner <adrian@xemacs.org>, 9771# & others. 9772# 9773# This program is free software; you can redistribute it and/or modify 9774# it under the terms of the GNU General Public License as published by 9775# the Free Software Foundation; either version 2 of the License, or 9776# (at your option) any later version. 9777# 9778# This program is distributed in the hope that it will be useful, 9779# but WITHOUT ANY WARRANTY; without even the implied warranty of 9780# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9781# GNU General Public License for more details. 9782# 9783# You should have received a copy of the GNU General Public License 9784# along with this program; if not, write to the Free Software 9785# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 9786# 9787#-############################################################################## 9788 9789# This requires perl version 5 or higher 9790require 5.0; 9791 9792package Texi2HTML::I18n; 9793 9794use strict; 9795 9796use vars qw( 9797@ISA 9798@EXPORT 9799); 9800 9801use Exporter; 9802@ISA = qw(Exporter); 9803@EXPORT = qw(pretty_date); 9804 9805my $language; 9806my $i18n_dir = 'i18n'; # name of the directory containing the per language files 9807#my $translation_file = 'translations.pl'; # file containing all the translations 9808#my @known_languages = ('de', 'nl', 'es', 'no', 'pt', 'fr'); # The supported 9809 # languages 9810 9811######################################################################## 9812# Language dependencies: 9813# To add a new language extend the WORDS hash and create $T2H_<...>_WORDS hash 9814# To redefine one word, simply do: 9815# $T2h_i18n::T2H_LANGUAGES->{<language>}->{<word>} = 'whatever' in your personal init file. 9816# 9817 9818# Those hashes are obsolete but retained here for reference 9819 9820my $T2H_WORDS_EN = 9821{ 9822 # titles of pages 9823 #'Table of Contents' => 'Table of Contents', 9824 #'Short Table of Contents' => 'Short Table of Contents', 9825 #'Index' => 'Index', 9826 #'About This Document' => 'About This Document', 9827 #'Footnotes' => 'Footnotes', 9828 #'See' => 'See', 9829 #'see' => 'see', 9830 #'section' => 'section', 9831 'About This Document' => '', 9832 'Table of Contents' => '', 9833 'Short Table of Contents', => '', 9834 'Index' => '', 9835 'Footnotes' => '', 9836 'See' => '', 9837 'see' => '', 9838 'section' => '', 9839 'Top' => '', 9840 'Untitled Document' => '', 9841 # If necessary, we could extend this as follows: 9842 # # text for buttons 9843 # 'Top_Button' => 'Top', 9844 # 'ToC_Button' => 'Contents', 9845 # 'Overview_Button' => 'Overview', 9846 # 'Index_button' => 'Index', 9847 # 'Back_Button' => 'Back', 9848 # 'FastBack_Button' => 'FastBack', 9849 # 'Prev_Button' => 'Prev', 9850 # 'Up_Button' => 'Up', 9851 # 'Next_Button' => 'Next', 9852 # 'Forward_Button' =>'Forward', 9853 # 'FastWorward_Button' => 'FastForward', 9854 # 'First_Button' => 'First', 9855 # 'Last_Button' => 'Last', 9856 # 'About_Button' => 'About' 9857 'January' => '', 9858 'February' => '', 9859 'March' => '', 9860 'April' => '', 9861 'May' => '', 9862 'June' => '', 9863 'July' => '', 9864 'August' => '', 9865 'September' => '', 9866 'October' => '', 9867 'November' => '', 9868 'December' => '', 9869 'T2H_today' => '%s, %d %d', 9870}; 9871 9872my $T2H_WORDS_DE = 9873{ 9874 'Table of Contents' => 'Inhaltsverzeichniss', 9875 'Short Table of Contents' => 'Kurzes Inhaltsverzeichniss', 9876 'Index' => 'Index', 9877 'About This Document' => 'Über dieses Dokument', 9878 'Footnotes' => 'Fußnoten', 9879 'See' => 'Siehe', 9880 'see' => 'siehe', 9881 'section' => 'Abschnitt', 9882 'January' => 'Januar', 9883 'February' => 'Februar', 9884 'March' => 'März', 9885 'April' => 'April', 9886 'May' => 'Mai', 9887 'June' => 'Juni', 9888 'July' => 'Juli', 9889 'August' => 'August', 9890 'September' => 'September', 9891 'October' => 'Oktober', 9892 'November' => 'November', 9893 'December' => 'Dezember', 9894}; 9895 9896my $T2H_WORDS_NL = 9897{ 9898 'Table of Contents' => 'Inhoudsopgave', 9899 'Short Table of Contents' => 'Korte inhoudsopgave', 9900 'Index' => 'Index', #Not sure ;-) 9901 'About This Document' => 'No translation available!', #No translation available! 9902 'Footnotes' => 'No translation available!', #No translation available! 9903 'See' => 'Zie', 9904 'see' => 'zie', 9905 'section' => 'sectie', 9906 'January' => 'Januari', 9907 'February' => 'Februari', 9908 'March' => 'Maart', 9909 'April' => 'April', 9910 'May' => 'Mei', 9911 'June' => 'Juni', 9912 'July' => 'Juli', 9913 'August' => 'Augustus', 9914 'September' => 'September', 9915 'October' => 'Oktober', 9916 'November' => 'November', 9917 'December' => 'December', 9918}; 9919 9920my $T2H_WORDS_ES = 9921{ 9922 'Table of Contents' => 'índice General', 9923 'Short Table of Contents' => 'Resumen del Contenido', 9924 'Index' => 'Index', #Not sure ;-) 9925 'About This Document' => 'No translation available!', #No translation available! 9926 'Footnotes' => 'Fußnoten', 9927 'See' => 'Véase', 9928 'see' => 'véase', 9929 'section' => 'sección', 9930 'January' => 'enero', 9931 'February' => 'febrero', 9932 'March' => 'marzo', 9933 'April' => 'abril', 9934 'May' => 'mayo', 9935 'June' => 'junio', 9936 'July' => 'julio', 9937 'August' => 'agosto', 9938 'September' => 'septiembre', 9939 'October' => 'octubre', 9940 'November' => 'noviembre', 9941 'December' => 'diciembre', 9942}; 9943 9944my $T2H_WORDS_NO = 9945{ 9946 'Table of Contents' => 'Innholdsfortegnelse', 9947 'Short Table of Contents' => 'Kort innholdsfortegnelse', 9948 'Index' => 'Indeks', #Not sure ;-) 9949 'About This Document' => 'No translation available!', #No translation available! 9950 'Footnotes' => 'No translation available!', 9951 'See' => 'Se', 9952 'see' => 'se', 9953 'section' => 'avsnitt', 9954 'January' => 'januar', 9955 'February' => 'februar', 9956 'March' => 'mars', 9957 'April' => 'april', 9958 'May' => 'mai', 9959 'June' => 'juni', 9960 'July' => 'juli', 9961 'August' => 'august', 9962 'September' => 'september', 9963 'October' => 'oktober', 9964 'November' => 'november', 9965 'December' => 'desember', 9966}; 9967 9968my $T2H_WORDS_PT = 9969{ 9970 'Table of Contents' => 'Sumário', 9971 'Short Table of Contents' => 'Breve Sumário', 9972 'Index' => 'Índice', #Not sure ;-) 9973 'About This Document' => 'No translation available!', #No translation available! 9974 'Footnotes' => 'No translation available!', 9975 'See' => 'Veja', 9976 'see' => 'veja', 9977 'section' => 'Seção', 9978 'January' => 'Janeiro', 9979 'February' => 'Fevereiro', 9980 'March' => 'Março', 9981 'April' => 'Abril', 9982 'May' => 'Maio', 9983 'June' => 'Junho', 9984 'July' => 'Julho', 9985 'August' => 'Agosto', 9986 'September' => 'Setembro', 9987 'October' => 'Outubro', 9988 'November' => 'Novembro', 9989 'December' => 'Dezembro', 9990}; 9991 9992my $T2H_WORDS_FR = 9993{ 9994 'Table of Contents' => 'Table des matières', 9995 'Short Table of Contents' => 'Résumée du contenu', 9996 'Index' => 'Index', 9997 'About This Document' => 'A propos de ce document', 9998 'Footnotes' => 'Notes de bas de page', 9999 'See' => 'Voir', 10000 'see' => 'voir', 10001 'section' => 'section', 10002 'January' => 'Janvier', 10003 'February' => 'Février', 10004 'March' => 'Mars', 10005 'April' => 'Avril', 10006 'May' => 'Mai', 10007 'June' => 'Juin', 10008 'July' => 'Juillet', 10009 'August' => 'Août', 10010 'September' => 'Septembre', 10011 'October' => 'Octobre', 10012 'November' => 'Novembre', 10013 'December' => 'Décembre', 10014 'T2H_today' => 'le %2$d %1$s %3$d' 10015}; 10016 10017#$T2H_LANGUAGES = 10018#{ 10019# 'en' => $T2H_WORDS_EN, 10020# 'de' => $T2H_WORDS_DE, 10021# 'nl' => $T2H_WORDS_NL, 10022# 'es' => $T2H_WORDS_ES, 10023# 'no' => $T2H_WORDS_NO, 10024# 'pt' => $T2H_WORDS_PT, 10025# 'fr' => $T2H_WORDS_FR, 10026#}; 10027 10028sub set_language($) 10029{ 10030 my $lang = shift; 10031 if (defined($lang) && exists($Texi2HTML::Config::LANGUAGES->{$lang}) && defined($Texi2HTML::Config::LANGUAGES->{$lang})) 10032 { 10033 $language = $lang; 10034 return 1; 10035 } 10036 else 10037 { 10038 return 0; 10039 } 10040} 10041 10042sub get_language() 10043{ 10044 return $language; 10045} 10046 10047my @MONTH_NAMES = 10048 ( 10049 'January', 'February', 'March', 'April', 'May', 10050 'June', 'July', 'August', 'September', 'October', 10051 'November', 'December' 10052 ); 10053 10054my $I = \&get_string; 10055 10056sub pretty_date($) 10057{ 10058 my $lang = shift; 10059 my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); 10060 10061 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); 10062 $year += ($year < 70) ? 2000 : 1900; 10063 # obachman: Let's do it as the Americans do 10064 #return($MONTH_NAMES->{$lang}[$mon] . ", " . $mday . " " . $year); 10065 #return(sprintf(&$I('T2H_today'), (get_string($MONTH_NAMES[$mon]), $mday, $year))); 10066 return &$I('%{month} %{day}, %{year}', { 'month' => get_string($MONTH_NAMES[$mon]), 10067 'day' => $mday, 'year' => $year }); 10068} 10069 10070my $error_no_en = 0; 10071 10072my %missing_strings; 10073 10074# arguments should already be converted 10075sub get_string($;$$) 10076{ 10077 my $string = shift; 10078 my $arguments = shift; 10079 my $state = shift; 10080 # if duplicate is passed, it means that we are in the text and so should 10081 # use the main state 10082 if (defined($state) and $state->{'duplicate'} and defined($Texi2HTML::THISDOC{'state'})) 10083 { 10084 $state = main::duplicate_formatting_state($Texi2HTML::THISDOC{'state'}); 10085 } 10086 10087 my $T2H_LANGUAGES = $Texi2HTML::Config::LANGUAGES; 10088 if (! exists($T2H_LANGUAGES->{'en'})) 10089 { 10090 unless($error_no_en) 10091 { 10092 print STDERR "i18n: no LANGUAGES->{'en'} hash\n"; 10093 $error_no_en = 1; 10094 } 10095 } 10096 else 10097 { 10098 unless (exists ($T2H_LANGUAGES->{'en'}->{$string})) 10099 { 10100 unless (exists($missing_strings{$string})) 10101 { 10102 print STDERR "i18n: missing string $string\n"; 10103 $missing_strings{$string} = 1; 10104 } 10105 } 10106 if (defined ($T2H_LANGUAGES->{$language}->{$string}) and 10107 ($T2H_LANGUAGES->{$language}->{$string} ne '')) 10108 { 10109 $string = $T2H_LANGUAGES->{$language}->{$string}; 10110 } 10111 elsif (defined ($T2H_LANGUAGES->{'en'}->{$string}) and 10112 ($T2H_LANGUAGES->{'en'}->{$string} ne '')) 10113 { 10114 $string = $T2H_LANGUAGES->{'en'}->{$string}; 10115 } 10116 } 10117 return main::substitute_line($string, $state) unless (defined($arguments) or !keys(%$arguments)); 10118 # if there are arguments, we must protect the %{arg} constructs before 10119 # doing substitute_line. So there is a first pass here to change %{arg} 10120 # to %@{arg@} 10121 my $result = ''; 10122 if (!$state->{'keep_texi'}) 10123 { 10124 while ($string) 10125 { 10126 if ($string =~ s/^([^%]*)%//) 10127 { 10128 $result .= $1 if (defined($1)); 10129 $result .= '%'; 10130 if ($string =~ s/^%//) 10131 { 10132 $result .= '%'; 10133 } 10134 elsif ($string =~ /^\{(\w+)\}/ and exists($arguments->{$1})) 10135 { 10136 $string =~ s/^\{(\w+)\}//; 10137 $result .= "\@\{$1\@\}"; 10138 } 10139 else 10140 { 10141 $result .= '%'; 10142 } 10143 next; 10144 } 10145 else 10146 { 10147 $result .= $string; 10148 last; 10149 } 10150 } 10151 # the arguments are not already there. But the @-commands in the 10152 # strings are substituted. 10153 $string = main::substitute_line($result, $state); 10154 } 10155 # now we substitute the arguments 10156 $result = ''; 10157 while ($string) 10158 { 10159 if ($string =~ s/^([^%]*)%//) 10160 { 10161 $result .= $1 if (defined($1)); 10162 if ($string =~ s/^%//) 10163 { 10164 $result .= '%'; 10165 } 10166 elsif ($string =~ /^\{(\w+)\}/ and exists($arguments->{$1})) 10167 { 10168 $string =~ s/^\{(\w+)\}//; 10169 $result .= $arguments->{$1}; 10170 } 10171 else 10172 { 10173 $result .= '%'; 10174 } 10175 next; 10176 } 10177 else 10178 { 10179 $result .= $string; 10180 last; 10181 } 10182 } 10183 return $result; 10184} 10185 101861; 10187require "$T2H_HOME/T2h_i18n.pm" 10188 if ($0 =~ /\.pl$/ && 10189 -e "$T2H_HOME/T2h_i18n.pm" && -r "$T2H_HOME/T2h_i18n.pm"); 10190 10191 10192######################################################################### 10193# 10194# latex2html code 10195# 10196#---###################################################################### 10197 10198{ 10199# leave this within comments, and keep the require statement 10200# This way, you can directly run texi2html.pl, if $ENV{T2H_HOME}/T2h_l2h.pm 10201# exists. 10202 10203# @T2H_L2H@ 10204#+############################################################################## 10205# 10206# T2h_l2h.pm: interface to LaTeX2HTML 10207# 10208# Copyright (C) 1999-2005 Patrice Dumas <dumas@centre-cired.fr>, 10209# Derek Price <derek@ximbiot.com>, 10210# Adrian Aichner <adrian@xemacs.org>, 10211# & others. 10212# 10213# This program is free software; you can redistribute it and/or modify 10214# it under the terms of the GNU General Public License as published by 10215# the Free Software Foundation; either version 2 of the License, or 10216# (at your option) any later version. 10217# 10218# This program is distributed in the hope that it will be useful, 10219# but WITHOUT ANY WARRANTY; without even the implied warranty of 10220# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10221# GNU General Public License for more details. 10222# 10223# You should have received a copy of the GNU General Public License 10224# along with this program; if not, write to the Free Software 10225# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 10226# 02110-1301 USA 10227# 10228#-############################################################################## 10229 10230require 5.0; 10231use strict; 10232 10233package Texi2HTML::LaTeX2HTML; 10234use Cwd; 10235 10236 10237# latex2html conversions consist of three stages: 10238# 1) ToLatex: Put "latex" code into a latex file 10239# 2) ToHtml: Use latex2html to generate corresponding html code and images 10240# 3) FromHtml: Extract generated code and images from latex2html run 10241# 10242 10243# init l2h defaults for files and names 10244 10245# global variable used for caching 10246use vars qw( 10247 %l2h_cache 10248 ); 10249 10250my ($l2h_name, $l2h_latex_file, $l2h_cache_file, $l2h_html_file, $l2h_prefix); 10251 10252# holds the status of latex2html operations. If 0 it means that there was 10253# an error 10254my $status = 0; 10255 10256my $debug; 10257my $verbose; 10258my $docu_rdir; 10259my $docu_name; 10260my $docu_ext; 10261my $ERROR = '***'; 10262 10263# init_from_html 10264my $extract_error_count; 10265my $invalid_counter_count; 10266 10267# change_image_file_names 10268my %l2h_img; # associate src file to destination file 10269 # such that files are not copied twice 10270my $image_count; 10271 10272# do_tex 10273my $html_output_count = 0; # html text outputed in html result file 10274 10275########################## 10276# 10277# First stage: Generation of Latex file 10278# Initialize with: init 10279# Add content with: to_latex ($text) --> HTML placeholder comment 10280# Finish with: finish_to_latex 10281# 10282 10283my $l2h_latex_preamble = <<EOT; 10284% This document was automatically generated by the l2h extenstion of texi2html 10285% DO NOT EDIT !!! 10286\\documentclass{article} 10287\\usepackage{html} 10288\\begin{document} 10289EOT 10290 10291my $l2h_latex_closing = <<EOT; 10292\\end{document} 10293EOT 10294 10295my %l2h_to_latex = (); # associate a latex text with the index in the 10296 # html result array. 10297my @l2h_to_latex = (); # array used to associate the index with 10298 # the original latex text. 10299my $latex_count = 0; # number of latex texts really stored 10300my $latex_converted_count = 0; # number of latex texts passed through latex2html 10301my $to_latex_count = 0; # total number of latex texts processed 10302my $cached_count = 0; # number of cached latex texts 10303%l2h_cache = (); # the cache hash. Associate latex text with 10304 # html from the previous run 10305my @l2h_from_html; # array of resulting html 10306 10307my %global_count = (); # associate a command name and the 10308 # corresponding counter to the index in the 10309 # html result array 10310 10311# set $status to 1, if l2h could be initalized properly, to 0 otherwise 10312sub init() 10313{ 10314 10315 %l2h_to_latex = (); # associate a latex text with the index in the 10316 # html result array. 10317 @l2h_to_latex = (); # array used to associate the index with 10318 # the original latex text. 10319 $latex_count = 0; # number of latex texts really stored 10320 $latex_converted_count = 0; # number of latex texts passed through latex2html 10321 $to_latex_count = 0; # total number of latex texts processed 10322 $cached_count = 0; # number of cached latex texts 10323 %l2h_cache = (); # the cache hash. Associate latex text with 10324 # html from the previous run 10325 @l2h_from_html = (); # array of resulting html 10326 10327 %global_count = (); # associate a command name and the 10328 # corresponding counter to the index in the 10329 # html result array 10330 $extract_error_count = 0; 10331 $invalid_counter_count = 0; 10332 %l2h_img = (); # associate src file to destination file 10333 # such that files are not copied twice 10334 $image_count = 1; 10335 10336 $html_output_count = 0; # html text outputed in html result file 10337 $status = 0; 10338 10339 $docu_name = $Texi2HTML::THISDOC{'file_base_name'}; 10340 $docu_rdir = $Texi2HTML::THISDOC{'destination_directory'}; 10341 $docu_rdir = '' if (!defined($docu_rdir)); 10342 $docu_ext = $Texi2HTML::THISDOC{'extension'}; 10343 $l2h_name = "${docu_name}_l2h"; 10344 $l2h_latex_file = "$docu_rdir${l2h_name}.tex"; 10345 $l2h_cache_file = "${docu_rdir}${docu_name}-l2h_cache.pm"; 10346 # destination dir -- generated images are put there, should be the same 10347 # as dir of enclosing html document -- 10348 $l2h_html_file = "$docu_rdir${l2h_name}.html"; 10349 $l2h_prefix = "${l2h_name}_"; 10350 $debug = $Texi2HTML::THISDOC{'debug_l2h'}; 10351 $verbose = $Texi2HTML::Config::VERBOSE; 10352 10353 unless ($Texi2HTML::Config::L2H_SKIP) 10354 { 10355 unless (open(L2H_LATEX, ">$l2h_latex_file")) 10356 { 10357 warn "$ERROR l2h: Can't open latex file '$l2h_latex_file' for writing: $!\n"; 10358 $status = 0; 10359 return; 10360 } 10361 warn "# l2h: use ${l2h_latex_file} as latex file\n" if ($verbose); 10362 print L2H_LATEX $l2h_latex_preamble; 10363 } 10364 # open the database that holds cached text 10365 init_cache(); 10366 $status = 1; 10367} 10368 10369 10370# print text (2nd arg) into latex file (if not already there nor in cache) 10371# which can be later on replaced by the latex2html generated text. 10372# 10373sub to_latex($$$) 10374{ 10375 my $command = shift; 10376 my $text = shift; 10377 my $counter = shift; 10378 if ($command eq 'tex') 10379 { 10380 $text .= ' '; 10381 } 10382 elsif ($command eq 'math') 10383 { 10384 $text = "\$".$text."\$"; 10385 } 10386 $to_latex_count++; 10387 $text =~ s/(\s*)$//; 10388 # try whether we have text already on things to do 10389 my $count = $l2h_to_latex{$text}; 10390 unless ($count) 10391 { 10392 $latex_count++; 10393 $count = $latex_count; 10394 # try whether we can get it from cache 10395 my $cached_text = from_cache($text); 10396 if (defined($cached_text)) 10397 { 10398 $cached_count++; 10399 # put the cached result in the html result array 10400 $l2h_from_html[$count] = $cached_text; 10401 } 10402 else 10403 { 10404 $latex_converted_count++; 10405 unless ($Texi2HTML::Config::L2H_SKIP) 10406 { 10407 print L2H_LATEX "\\begin{rawhtml}\n"; 10408 print L2H_LATEX "<!-- l2h_begin $l2h_name $count -->\n"; 10409 print L2H_LATEX "\\end{rawhtml}\n"; 10410 10411 print L2H_LATEX "$text\n"; 10412 10413 print L2H_LATEX "\\begin{rawhtml}\n"; 10414 print L2H_LATEX "<!-- l2h_end $l2h_name $count -->\n"; 10415 print L2H_LATEX "\\end{rawhtml}\n"; 10416 } 10417 } 10418 $l2h_to_latex[$count] = $text; 10419 $l2h_to_latex{$text} = $count; 10420 } 10421 $global_count{"${command}_$counter"} = $count; 10422 return 1; 10423} 10424 10425# print closing into latex file and close it 10426sub finish_to_latex() 10427{ 10428 my $reused = $to_latex_count - $latex_converted_count - $cached_count; 10429 unless ($Texi2HTML::Config::L2H_SKIP) 10430 { 10431 print L2H_LATEX $l2h_latex_closing; 10432 close (L2H_LATEX); 10433 } 10434 warn "# l2h: finished to latex ($cached_count cached, $reused reused, $latex_converted_count to process)\n" if ($verbose); 10435 unless ($latex_count) 10436 { 10437 # no @tex nor @math 10438 finish(); 10439 return 0; 10440 } 10441 return 1; 10442} 10443 10444################################### 10445# Second stage: Use latex2html to generate corresponding html code and images 10446# 10447# to_html([$l2h_latex_file, [$l2h_html_dir]]): 10448# Call latex2html on $l2h_latex_file 10449# Put images (prefixed with $l2h_name."_") and html file(s) in $l2h_html_dir 10450# Return 1, on success 10451# 0, otherwise 10452# 10453sub to_html() 10454{ 10455 my ($call, $dotbug); 10456 # when there are no tex constructs to convert (happens in case everything 10457 # comes from the cache), there is no latex2html run 10458 if ($Texi2HTML::Config::L2H_SKIP or ($latex_converted_count == 0)) 10459 { 10460 warn "# l2h: skipping latex2html run\n" if ($verbose); 10461 return 1; 10462 } 10463 # Check for dot in directory where dvips will work 10464 if ($Texi2HTML::Config::L2H_TMP) 10465 { 10466 if ($Texi2HTML::Config::L2H_TMP =~ /\./) 10467 { 10468 warn "$ERROR Warning l2h: l2h_tmp dir contains a dot. Use /tmp, instead\n"; 10469 $dotbug = 1; 10470 } 10471 } 10472 else 10473 { 10474 if (cwd() =~ /\./) 10475 { 10476 warn "$ERROR Warning l2h: current dir contains a dot. Use /tmp as l2h_tmp dir \n"; 10477 $dotbug = 1; 10478 } 10479 } 10480 # fix it, if necessary and hope that it works 10481 $Texi2HTML::Config::L2H_TMP = "/tmp" if ($dotbug); 10482 10483 $call = $Texi2HTML::Config::L2H_L2H; 10484 # use init file, if specified 10485 my $init_file = main::locate_init_file($Texi2HTML::Config::L2H_FILE); 10486 $call = $call . " -init_file " . $init_file if ($init_file); 10487 # set output dir 10488 $call .= (($docu_rdir ne '') ? " -dir $docu_rdir" : " -no_subdir"); 10489 # use l2h_tmp, if specified 10490 $call .= " -tmp $Texi2HTML::Config::L2H_TMP" 10491 if (defined($Texi2HTML::Config::L2H_TMP) and $Texi2HTML::Config::L2H_TMP ne ''); 10492 # use a given html version if specified 10493 $call .= " -html_version $Texi2HTML::Config::L2H_HTML_VERSION" 10494 if (defined($Texi2HTML::Config::L2H_HTML_VERSION) and $Texi2HTML::Config::L2H_HTML_VERSION ne ''); 10495 # options we want to be sure of 10496 $call .= " -address 0 -info 0 -split 0 -no_navigation -no_auto_link"; 10497 $call .= " -prefix $l2h_prefix $l2h_latex_file"; 10498 10499 warn "# l2h: executing '$call'\n" if ($verbose); 10500 if (system($call)) 10501 { 10502 warn "$ERROR l2h: '${call}' did not succeed\n"; 10503 return 0; 10504 } 10505 else 10506 { 10507 warn "# l2h: latex2html finished successfully\n" if ($verbose); 10508 return 1; 10509 } 10510} 10511 10512########################## 10513# Third stage: Extract generated contents from latex2html run 10514# Initialize with: init_from_html 10515# open $l2h_html_file for reading 10516# reads in contents into array indexed by numbers 10517# return 1, on success -- 0, otherwise 10518# Finish with: finish 10519# closes $l2h_html_dir/$l2h_name.".$docu_ext" 10520 10521# the images generated by latex2html have names like ${docu_name}_l2h_img?.png 10522# they are copied to ${docu_name}_?.png, and html is changed accordingly. 10523 10524# %l2h_img; # associate src file to destination file 10525 # such that files are not copied twice 10526sub change_image_file_names($) 10527{ 10528 my $content = shift; 10529 my @images = ($content =~ /SRC="(.*?)"/g); 10530 my ($src, $dest); 10531 10532 for $src (@images) 10533 { 10534 $dest = $l2h_img{$src}; 10535 unless ($dest) 10536 { 10537 my $ext = ''; 10538 if ($src =~ /.*\.(.*)$/ && $1 ne $docu_ext) 10539 { 10540 $ext = ".$1"; 10541 } 10542 else 10543 { # FIXME what is that check about? 10544 warn "$ERROR: L2h image $src has invalid extension\n"; 10545 next; 10546 } 10547 while (-e "$docu_rdir${docu_name}_${image_count}$ext") 10548 { 10549 $image_count++; 10550 } 10551 $dest = "${docu_name}_${image_count}$ext"; 10552# FIXME this isn't portable. + error condition not checked. 10553 system("cp -f $docu_rdir$src $docu_rdir$dest"); 10554 $l2h_img{$src} = $dest; 10555# FIXME error condition not checked 10556 unlink "$docu_rdir$src" unless ($debug); 10557 } 10558 $content =~ s/SRC="$src"/SRC="$dest"/g; 10559 } 10560 return $content; 10561} 10562 10563sub init_from_html() 10564{ 10565 # when there are no tex constructs to convert (happens in case everything 10566 # comes from the cache), the html file that was generated by previous 10567 # latex2html runs isn't reused. 10568 if ($latex_converted_count == 0) 10569 { 10570 return 1; 10571 } 10572 10573 if (! open(L2H_HTML, "<$l2h_html_file")) 10574 { 10575 warn "$ERROR l2h: Can't open $l2h_html_file for reading\n"; 10576 return 0; 10577 } 10578 warn "# l2h: use $l2h_html_file as html file\n" if ($verbose); 10579 10580 my $html_converted_count = 0; # number of html resulting texts 10581 # retrieved in the file 10582 10583 my ($count, $h_line); 10584 while ($h_line = <L2H_HTML>) 10585 { 10586 if ($h_line =~ /^<!-- l2h_begin $l2h_name ([0-9]+) -->/) 10587 { 10588 $count = $1; 10589 my $h_content = ''; 10590 my $h_end_found = 0; 10591 while ($h_line = <L2H_HTML>) 10592 { 10593 if ($h_line =~ /^<!-- l2h_end $l2h_name $count -->/) 10594 { 10595 $h_end_found = 1; 10596 chomp $h_content; 10597 chomp $h_content; 10598 $html_converted_count++; 10599 # transform image file names and copy image files 10600 $h_content = change_image_file_names($h_content); 10601 # store result in the html result array 10602 $l2h_from_html[$count] = $h_content; 10603 # also add the result in cache hash 10604 $l2h_cache{$l2h_to_latex[$count]} = $h_content; 10605 last; 10606 } 10607 $h_content = $h_content.$h_line; 10608 } 10609 unless ($h_end_found) 10610 { # couldn't found the closing comment. Certainly a bug. 10611 warn "$ERROR l2h(BUG): l2h_end $l2h_name $count not found\n"; 10612 close(L2H_HTML); 10613 return 0; 10614 } 10615 } 10616 } 10617 10618 # Not the same number of converted elements and retrieved elements 10619 if ($latex_converted_count != $html_converted_count) 10620 { 10621 warn "$ERROR l2h(BUG): waiting for $latex_converted_count elements found $html_converted_count\n"; 10622 } 10623 10624 warn "# l2h: Got $html_converted_count of $latex_count html contents\n" 10625 if ($verbose); 10626 10627 close(L2H_HTML); 10628 return 1; 10629} 10630 10631# $html_output_count = 0; # html text outputed in html result file 10632 10633# called each time a construct handled by latex2html is encountered, should 10634# output the corresponding html 10635sub do_tex($$$$) 10636{ 10637 my $style = shift; 10638 my $counter = shift; 10639 my $state = shift; 10640 my $count = $global_count{"${style}_$counter"}; 10641 ################################## begin debug section (incorrect counts) 10642 if (!defined($count)) 10643 { 10644 # counter is undefined 10645 $invalid_counter_count++; 10646 warn "$ERROR l2h(BUG): undefined count for ${style}_$counter\n"; 10647 return ("<!-- l2h: ". __LINE__ . " undef count for ${style}_$counter -->") 10648 if ($debug); 10649 return ''; 10650 } 10651 elsif(($count <= 0) or ($count > $latex_count)) 10652 { 10653 # counter out of range 10654 $invalid_counter_count++; 10655 warn "$ERROR l2h(BUG): Request of $count content which is out of valide range [0,$latex_count)\n"; 10656 return ("<!-- l2h: ". __LINE__ . " out of range count $count -->") 10657 if ($debug); 10658 return ''; 10659 } 10660 ################################## end debug section (incorrect counts) 10661 10662 # this seems to be a valid counter 10663 my $result = ''; 10664 $result = "<!-- l2h_begin $l2h_name $count -->" if ($debug); 10665 if (defined($l2h_from_html[$count])) 10666 { 10667 $html_output_count++; 10668 # maybe we could also have something if simple_format 10669 # with Texi2HTML::Config::protect_text, once simple_format 10670 # may happen for anything else than lines 10671 if ($state->{'remove_texi'}) 10672 {# don't protect anything 10673 $result .= $l2h_to_latex[$count]; 10674 } 10675 else 10676 { 10677 $result .= $l2h_from_html[$count]; 10678 } 10679 } 10680 else 10681 { 10682 # if the result is not in @l2h_from_html, there is an error somewhere. 10683 $extract_error_count++; 10684 warn "$ERROR l2h(BUG): can't extract content $count from html\n"; 10685 # try simple (ordinary) substitution (without l2h) 10686 $result .= "<!-- l2h: ". __LINE__ . " use texi2html -->" if ($debug); 10687 $result .= main::substitute_text({}, undef, $l2h_to_latex[$count]); 10688 } 10689 $result .= "<!-- l2h_end $l2h_name $count -->" if ($debug); 10690 return $result; 10691} 10692 10693# store results in the cache and remove temporary files. 10694sub finish() 10695{ 10696 return unless($status); 10697 if ($verbose) 10698 { 10699 if ($extract_error_count + $invalid_counter_count) 10700 { 10701 warn "# l2h: finished from html ($extract_error_count extract and $invalid_counter_count invalid counter errors)\n"; 10702 } 10703 else 10704 { 10705 warn "# l2h: finished from html (no error)\n"; 10706 } 10707 if ($html_output_count != $latex_converted_count) 10708 { # this may happen if @-commands are collected at some places 10709 # but @-command at those places are not expanded later. For 10710 # example @math on @multitable lines. 10711 warn "# l2h: $html_output_count html outputed for $latex_converted_count converted\n"; 10712 } 10713 } 10714 store_cache(); 10715 if ($Texi2HTML::Config::L2H_CLEAN) 10716 { 10717 local ($_); 10718 warn "# l2h: removing temporary files generated by l2h extension\n" 10719 if $verbose; 10720 while (<"$docu_rdir$l2h_name"*>) 10721 { 10722# FIXME error condition not checked 10723 unlink $_; 10724 } 10725 } 10726 warn "# l2h: Finished\n" if $verbose; 10727 return 1; 10728} 10729 10730# the driver of end of first pass, second pass and beginning of third pass 10731# 10732sub latex2html() 10733{ 10734 return unless($status); 10735 return unless ($status = finish_to_latex()); 10736 return unless ($status = to_html()); 10737 return unless ($status = init_from_html()); 10738} 10739 10740 10741############################## 10742# stuff for l2h caching 10743# 10744 10745# I tried doing this with a dbm data base, but it did not store all 10746# keys/values. Hence, I did as latex2html does it 10747sub init_cache 10748{ 10749 if (-r "$l2h_cache_file") 10750 { 10751 my $rdo = do "$l2h_cache_file"; 10752 warn("$ERROR l2h Error: could not load $docu_rdir$l2h_cache_file: $@\n") 10753 unless ($rdo); 10754 } 10755} 10756 10757# store all the text obtained through latex2html 10758sub store_cache 10759{ 10760 return unless $latex_count; 10761 my ($key, $value); 10762 unless (open(FH, ">$l2h_cache_file")) 10763 { 10764 warn "$ERROR l2h Error: could not open $docu_rdir$l2h_cache_file for writing: $!\n"; 10765 return; 10766 } 10767 while (($key, $value) = each %l2h_cache) 10768 { 10769 # escape stuff 10770 $key =~ s|/|\\/|g; 10771 $key =~ s|\\\\/|\\/|g; 10772 # weird, a \ at the end of the key results in an error 10773 # maybe this also broke the dbm database stuff 10774 $key =~ s|\\$|\\\\|; 10775 $value =~ s/\|/\\\|/go; 10776 $value =~ s/\\\\\|/\\\|/go; 10777 $value =~ s|\\\\|\\\\\\\\|g; 10778 print FH "\n\$l2h_cache_key = q/$key/;\n"; 10779 print FH "\$l2h_cache{\$l2h_cache_key} = q|$value|;\n"; 10780 } 10781 print FH "1;"; 10782 close (FH); 10783} 10784 10785# return cached html, if it exists for text, and if all pictures 10786# are there, as well 10787sub from_cache($) 10788{ 10789 my $text = shift; 10790 my $cached = $l2h_cache{$text}; 10791 if (defined($cached)) 10792 { 10793 while ($cached =~ m/SRC="(.*?)"/g) 10794 { 10795 unless (-e "$docu_rdir$1") 10796 { 10797 return undef; 10798 } 10799 } 10800 return $cached; 10801 } 10802 return undef; 10803} 10804 108051; 10806 10807require "$T2H_HOME/T2h_l2h.pm" 10808 if ($0 =~ /\.pl$/ && 10809 -e "$T2H_HOME/T2h_l2h.pm" && -r "$T2H_HOME/T2h_l2h.pm"); 10810 10811} 10812 10813{ 10814package Texi2HTML::LaTeX2HTML::Config; 10815 10816# latex2html variables 10817# These variables are not used. They are here for information only, and 10818# an example of config file for latex2html file is included. 10819my $ADDRESS; 10820my $ANTI_ALIAS; 10821my $ANTI_ALIAS_TEXT; 10822my $ASCII_MODE; 10823my $AUTO_LINK; 10824my $AUTO_PREFIX; 10825my $CHILDLINE; 10826my $DEBUG; 10827my $DESTDIR; 10828my $DVIPS; 10829my $ERROR; 10830my $EXTERNAL_FILE; 10831my $EXTERNAL_IMAGES; 10832my $EXTERNAL_UP_LINK; 10833my $EXTERNAL_UP_TITLE; 10834my $FIGURE_SCALE_FACTOR; 10835my $HTML_VERSION; 10836my $IMAGES_ONLY; 10837my $INFO; 10838my $LINE_WIDTH; 10839my $LOCAL_ICONS; 10840my $LONG_TITLES; 10841my $MATH_SCALE_FACTOR; 10842my $MAX_LINK_DEPTH; 10843my $MAX_SPLIT_DEPTH; 10844my $NETSCAPE_HTML; 10845my $NOLATEX; 10846my $NO_FOOTNODE; 10847my $NO_IMAGES; 10848my $NO_NAVIGATION; 10849my $NO_SIMPLE_MATH; 10850my $NO_SUBDIR; 10851my $PAPERSIZE; 10852my $PREFIX; 10853my $PS_IMAGES; 10854my $REUSE; 10855my $SCALABLE_FONTS; 10856my $SHORTEXTN; 10857my $SHORT_INDEX; 10858my $SHOW_SECTION_NUMBERS; 10859my $SPLIT; 10860my $TEXDEFS; 10861my $TITLE; 10862my $TITLES_LANGUAGE; 10863my $TMP; 10864my $VERBOSE; 10865my $WORDS_IN_NAVIGATION_PANEL_TITLES; 10866my $WORDS_IN_PAGE; 10867 10868# @T2H_L2H_INIT@ 10869 10870###################################################################### 10871# from here on, its l2h init stuff 10872# 10873 10874## initialization for latex2html as for Singular manual generation 10875## obachman 3/99 10876 10877# 10878# Options controlling Titles, File-Names, Tracing and Sectioning 10879# 10880$TITLE = ''; 10881 10882$SHORTEXTN = 0; 10883 10884$LONG_TITLES = 0; 10885 10886#$DESTDIR = ''; 10887 10888$NO_SUBDIR = 1; 10889 10890#$PREFIX = ''; 10891 10892$AUTO_PREFIX = 0; 10893 10894$AUTO_LINK = 0; 10895 10896$SPLIT = 0; 10897 10898$MAX_LINK_DEPTH = 0; 10899 10900#$TMP = ''; 10901 10902$DEBUG = 0; 10903 10904$VERBOSE = 1; 10905 10906# 10907# Options controlling Extensions and Special Features 10908# 10909#$HTML_VERSION = "3.2"; # set by command line 10910 10911$TEXDEFS = 1; # we absolutely need that 10912 10913$EXTERNAL_FILE = ''; 10914 10915$SCALABLE_FONTS = 1; 10916 10917$NO_SIMPLE_MATH = 1; 10918 10919$LOCAL_ICONS = 1; 10920 10921$SHORT_INDEX = 0; 10922 10923$NO_FOOTNODE = 1; 10924 10925$ADDRESS = ''; 10926 10927$INFO = ''; 10928 10929# 10930# Switches controlling Image Generation 10931# 10932$ASCII_MODE = 0; 10933 10934$NOLATEX = 0; 10935 10936$EXTERNAL_IMAGES = 0; 10937 10938$PS_IMAGES = 0; 10939 10940$NO_IMAGES = 0; 10941 10942$IMAGES_ONLY = 0; 10943 10944$REUSE = 2; 10945 10946$ANTI_ALIAS = 1; 10947 10948$ANTI_ALIAS_TEXT = 1; 10949 10950# 10951#Switches controlling Navigation Panels 10952# 10953$NO_NAVIGATION = 1; 10954$ADDRESS = ''; 10955$INFO = 0; # 0 = do not make a "About this document..." section 10956 10957# 10958#Switches for Linking to other documents 10959# 10960# currently -- we don't care 10961 10962$MAX_SPLIT_DEPTH = 0; # Stop making separate files at this depth 10963 10964$MAX_LINK_DEPTH = 0; # Stop showing child nodes at this depth 10965 10966$NOLATEX = 0; # 1 = do not pass unknown environments to Latex 10967 10968$EXTERNAL_IMAGES = 0; # 1 = leave the images outside the document 10969 10970$ASCII_MODE = 0; # 1 = do not use any icons or internal images 10971 10972# 1 = use links to external postscript images rather than inlined bitmap 10973# images. 10974$PS_IMAGES = 0; 10975$SHOW_SECTION_NUMBERS = 0; 10976 10977### Other global variables ############################################### 10978 10979# put dvips stderr on stdout since latex2html is alread very verbose 10980$DVIPS = "$DVIPS ".' 2>&1'; 10981 10982$CHILDLINE = ""; 10983 10984# This is the line width measured in pixels and it is used to right justify 10985# equations and equation arrays; 10986$LINE_WIDTH = 500; 10987 10988# Used in conjunction with AUTO_NAVIGATION 10989$WORDS_IN_PAGE = 300; 10990 10991# The value of this variable determines how many words to use in each 10992# title that is added to the navigation panel (see below) 10993# 10994$WORDS_IN_NAVIGATION_PANEL_TITLES = 0; 10995 10996# This number will determine the size of the equations, special characters, 10997# and anything which will be converted into an inlined image 10998# *except* "image generating environments" such as "figure", "table" 10999# or "minipage". 11000# Effective values are those greater than 0. 11001# Sensible values are between 0.1 - 4. 11002$MATH_SCALE_FACTOR = 1.5; 11003 11004# This number will determine the size of 11005# image generating environments such as "figure", "table" or "minipage". 11006# Effective values are those greater than 0. 11007# Sensible values are between 0.1 - 4. 11008$FIGURE_SCALE_FACTOR = 1.6; 11009 11010 11011# If both of the following two variables are set then the "Up" button 11012# of the navigation panel in the first node/page of a converted document 11013# will point to $EXTERNAL_UP_LINK. $EXTERNAL_UP_TITLE should be set 11014# to some text which describes this external link. 11015$EXTERNAL_UP_LINK = ""; 11016$EXTERNAL_UP_TITLE = ""; 11017 11018# If this is set then the resulting HTML will look marginally better if viewed 11019# with Netscape. 11020$NETSCAPE_HTML = 1; 11021 11022# Valid paper sizes are "letter", "legal", "a4","a3","a2" and "a0" 11023# Paper sizes has no effect other than in the time it takes to create inlined 11024# images and in whether large images can be created at all ie 11025# - larger paper sizes *MAY* help with large image problems 11026# - smaller paper sizes are quicker to handle 11027$PAPERSIZE = "a4"; 11028 11029# Replace "english" with another language in order to tell LaTeX2HTML that you 11030# want some generated section titles (eg "Table of Contents" or "References") 11031# to appear in a different language. Currently only "english" and "french" 11032# is supported but it is very easy to add your own. See the example in the 11033# file "latex2html.config" 11034$TITLES_LANGUAGE = "english"; 11035 110361; # This must be the last non-comment line 11037 11038# End File l2h.init 11039###################################################################### 11040 11041} 11042 11043package main; 11044 11045# 11046# flush stdout and stderr after every write 11047# 11048select(STDERR); 11049$| = 1; 11050select(STDOUT); 11051$| = 1; 11052 11053my $I = \&Texi2HTML::I18n::get_string; 11054 11055######################################################################## 11056# 11057# Global variable initialization 11058# 11059######################################################################## 11060# 11061# pre-defined indices 11062# 11063 11064%index_prefix_to_name = (); 11065 11066%index_names = 11067( 11068 'cp' => { 'prefix' => ['cp','c']}, 11069 'fn' => { 'prefix' => ['fn', 'f'], code => 1}, 11070 'vr' => { 'prefix' => ['vr', 'v'], code => 1}, 11071 'ky' => { 'prefix' => ['ky', 'k'], code => 1}, 11072 'pg' => { 'prefix' => ['pg', 'p'], code => 1}, 11073 'tp' => { 'prefix' => ['tp', 't'], code => 1} 11074); 11075 11076foreach my $name(keys(%index_names)) 11077{ 11078 foreach my $prefix (@{$index_names{$name}->{'prefix'}}) 11079 { 11080 $forbidden_index_name{$prefix} = 1; 11081 $index_prefix_to_name{$prefix} = $name; 11082 } 11083} 11084 11085foreach my $other_forbidden_index_name ('info','ps','pdf','htm', 11086 'log','aux','dvi','texi','txi','texinfo','tex','bib') 11087{ 11088 $forbidden_index_name{$other_forbidden_index_name} = 1; 11089} 11090 11091# commands with ---, -- '' and `` preserved 11092# usefull with the old interface 11093 11094%code_style_map = ( 11095 'code' => 1, 11096 'command' => 1, 11097 'env' => 1, 11098 'file' => 1, 11099 'kbd' => 1, 11100 'option' => 1, 11101 'samp' => 1, 11102 'verb' => 1, 11103); 11104 11105my @element_directions = ('Up', 'Forward', 'Back', 'Next', 'Prev', 11106'SectionNext', 'SectionPrev', 'SectionUp', 'FastForward', 'FastBack', 11107'This', 'NodeUp', 'NodePrev', 'NodeNext', 'Following', 'NextFile', 'PrevFile', 11108'ToplevelNext', 'ToplevelPrev'); 11109$::simple_map_ref = \%Texi2HTML::Config::simple_map; 11110$::simple_map_pre_ref = \%Texi2HTML::Config::simple_map_pre; 11111$::simple_map_texi_ref = \%Texi2HTML::Config::simple_map_texi; 11112$::style_map_ref = \%Texi2HTML::Config::style_map; 11113$::style_map_pre_ref = \%Texi2HTML::Config::style_map_pre; 11114$::style_map_texi_ref = \%Texi2HTML::Config::style_map_texi; 11115$::things_map_ref = \%Texi2HTML::Config::things_map; 11116$::pre_map_ref = \%Texi2HTML::Config::pre_map; 11117$::texi_map_ref = \%Texi2HTML::Config::texi_map; 11118 11119#print STDERR "MAPS: $::simple_map_ref $::simple_map_pre_ref $::simple_map_texi_ref $::style_map_ref $::style_map_pre_ref $::style_map_texi_ref $::things_map_ref $::pre_map_ref $::texi_map_ref\n"; 11120 11121# delete from hash if we are using the new interface 11122foreach my $code (keys(%code_style_map)) 11123{ 11124 delete ($code_style_map{$code}) 11125 if (ref($::style_map_ref->{$code}) eq 'HASH'); 11126} 11127 11128# no paragraph in these commands 11129my %no_paragraph_macro = ( 11130 'xref' => 1, 11131 'ref' => 1, 11132 'pxref' => 1, 11133 'inforef' => 1, 11134 'anchor' => 1, 11135); 11136 11137 11138# 11139# texinfo section names to level 11140# 11141my %reference_sec2level = ( 11142 'top', 0, 11143 'chapter', 1, 11144 'unnumbered', 1, 11145 'chapheading', 1, 11146 'appendix', 1, 11147 'section', 2, 11148 'unnumberedsec', 2, 11149 'heading', 2, 11150 'appendixsec', 2, 11151 'subsection', 3, 11152 'unnumberedsubsec', 3, 11153 'subheading', 3, 11154 'appendixsubsec', 3, 11155 'subsubsection', 4, 11156 'unnumberedsubsubsec', 4, 11157 'subsubheading', 4, 11158 'appendixsubsubsec', 4, 11159 ); 11160 11161# the reverse mapping. There is an entry for each sectionning command. 11162# The value is a ref on an array containing at each index the corresponding 11163# sectionning command name. 11164my %level2sec; 11165{ 11166 my $sections = [ ]; 11167 my $appendices = [ ]; 11168 my $unnumbered = [ ]; 11169 my $headings = [ ]; 11170 foreach my $command (keys (%reference_sec2level)) 11171 { 11172 if ($command =~ /^appendix/) 11173 { 11174 $level2sec{$command} = $appendices; 11175 } 11176 elsif ($command =~ /^unnumbered/ or $command eq 'top') 11177 { 11178 $level2sec{$command} = $unnumbered; 11179 } 11180 elsif ($command =~ /section$/ or $command eq 'chapter') 11181 { 11182 $level2sec{$command} = $sections; 11183 } 11184 else 11185 { 11186 $level2sec{$command} = $headings; 11187 } 11188 $level2sec{$command}->[$reference_sec2level{$command}] = $command; 11189 } 11190} 11191 11192# this are synonyms 11193$reference_sec2level{'appendixsection'} = 2; 11194# sec2level{'majorheading'} is also 1 and not 0 11195$reference_sec2level{'majorheading'} = 1; 11196$reference_sec2level{'chapheading'} = 1; 11197$reference_sec2level{'centerchap'} = 1; 11198 11199 11200sub set_no_line_macro($$) 11201{ 11202 my $macro = shift; 11203 my $value = shift; 11204 $Texi2HTML::Config::no_paragraph_commands{$macro} = $value 11205 unless defined($Texi2HTML::Config::no_paragraph_commands{$macro}); 11206} 11207 11208# those macros aren't considered as beginning a paragraph 11209foreach my $no_line_macro ('alias', 'macro', 'unmacro', 'rmacro', 11210 'titlefont', 'include', 'copying', 'end copying', 'tab', 'item', 11211 'itemx', '*', 'float', 'end float', 'caption', 'shortcaption', 'cindex', 11212 'image') 11213{ 11214 set_no_line_macro($no_line_macro, 1); 11215} 11216 11217foreach my $key (keys(%Texi2HTML::Config::misc_command), keys(%reference_sec2level)) 11218{ 11219 set_no_line_macro($key, 1); 11220} 11221 11222# a hash associating a format @thing / @end thing with the type of the format 11223# 'complex_format' 'simple_format' 'deff' 'list' 'menu' 'paragraph_format' 11224my %format_type = (); 11225 11226foreach my $simple_format (keys(%Texi2HTML::Config::format_map)) 11227{ 11228 $format_type{$simple_format} = 'simple_format'; 11229} 11230foreach my $paragraph_style (keys(%Texi2HTML::Config::paragraph_style)) 11231{ 11232 $format_type{$paragraph_style} = 'paragraph_format'; 11233} 11234foreach my $complex_format (keys(%$Texi2HTML::Config::complex_format_map)) 11235{ 11236 $format_type{$complex_format} = 'complex_format'; 11237} 11238foreach my $table (('table', 'ftable', 'vtable')) 11239{ 11240 $format_type{$table} = 'table'; 11241} 11242$format_type{'multitable'} = 'multitable'; 11243foreach my $def_format (keys(%Texi2HTML::Config::def_map)) 11244{ 11245 $format_type{$def_format} = 'deff'; 11246} 11247$format_type{'itemize'} = 'list'; 11248$format_type{'enumerate'} = 'list'; 11249 11250$format_type{'menu'} = 'menu'; 11251$format_type{'detailmenu'} = 'menu'; 11252 11253$format_type{'cartouche'} = 'cartouche'; 11254 11255$format_type{'float'} = 'float'; 11256 11257$format_type{'quotation'} = 'quotation'; 11258$format_type{'smallquotation'} = 'quotation'; 11259 11260$format_type{'group'} = 'group'; 11261 11262$format_type{'titlepage'} = 'region'; 11263$format_type{'copying'} = 'region'; 11264$format_type{'documentdescription'} = 'region'; 11265 11266foreach my $key (keys(%format_type)) 11267{ 11268 set_no_line_macro($key, 1); 11269 set_no_line_macro("end $key", 1); 11270} 11271 11272foreach my $macro (keys(%Texi2HTML::Config::format_in_paragraph)) 11273{ 11274 set_no_line_macro($macro, 1); 11275 set_no_line_macro("end $macro", 1); 11276} 11277 11278# fake format at the bottom of the stack 11279$format_type{'noformat'} = ''; 11280 11281# fake formats are formats used internally within other formats 11282# we associate them with a real format, for the error messages 11283my %fake_format = ( 11284 'line' => 'table', 11285 'term' => 'table', 11286 'item' => 'list or table', 11287 'row' => 'multitable row', 11288 'cell' => 'multitable cell', 11289 'deff_item' => 'definition command', 11290 'menu_comment' => 'menu', 11291 'menu_description' => 'menu', 11292 ); 11293 11294foreach my $key (keys(%fake_format)) 11295{ 11296 $format_type{$key} = 'fake'; 11297} 11298 11299# raw formats which are expanded especially 11300my @raw_regions = ('html', 'verbatim', 'tex', 'xml', 'docbook'); 11301 11302# The css formats are associated with complex format commands, and associated 11303# with the 'pre_style' key 11304foreach my $complex_format (keys(%$Texi2HTML::Config::complex_format_map)) 11305{ 11306 next if (defined($Texi2HTML::Config::complex_format_map->{$complex_format}->{'pre_style'})); 11307 $Texi2HTML::Config::complex_format_map->{$complex_format}->{'pre_style'} = ''; 11308 $Texi2HTML::Config::complex_format_map->{$complex_format}->{'pre_style'} = $Texi2HTML::Config::css_map{"pre.$complex_format"} if (exists($Texi2HTML::Config::css_map{"pre.$complex_format"})); 11309} 11310 11311#+++############################################################################ 11312# # 11313# Argument parsing, initialisation # 11314# # 11315#---############################################################################ 11316 11317my $T2H_USER; # user running the script 11318 11319# shorthand for Texi2HTML::Config::VERBOSE 11320my $T2H_VERBOSE; 11321my $T2H_DEBUG; 11322 11323sub echo_warn($;$); 11324#print STDERR "" . &$I('test i18n: \' , \a \\ %% %{unknown}a %known % %{known} \\', { 'known' => 'a known string', 'no' => 'nope'}); exit 0; 11325 11326# file: file name to locate. It can be a file path. 11327# all_files: if true collect all the files with that name, otherwise stop 11328# at first match. 11329# directories: a reference on a array containing a list of directories to 11330# search the file in. default is 11331# @Texi2HTML::Config::CONF_DIRS, @texi2html_config_dirs. 11332sub locate_init_file($;$$) 11333{ 11334 my $file = shift; 11335 my $all_files = shift; 11336 my $directories = shift; 11337 11338 $directories = [ @Texi2HTML::Config::CONF_DIRS, @texi2html_config_dirs ] if !defined($directories); 11339 11340 if ($file =~ /^\//) 11341 { 11342 return $file if (-e $file and -r $file); 11343 } 11344 else 11345 { 11346 my @files; 11347 foreach my $dir (@$directories) 11348 { 11349 next unless (-d "$dir"); 11350 if ($all_files) 11351 { 11352 push (@files, "$dir/$file") if (-e "$dir/$file" and -r "$dir/$file"); 11353 } 11354 else 11355 { 11356 return "$dir/$file" if (-e "$dir/$file" and -r "$dir/$file"); 11357 } 11358 } 11359 return @files if ($all_files); 11360 } 11361 return undef; 11362} 11363 11364# called on -init-file 11365sub load_init_file 11366{ 11367 # First argument is option 11368 shift; 11369 # second argument is value of options 11370 my $init_file = shift; 11371 my $file; 11372 if ($file = locate_init_file($init_file)) 11373 { 11374 print STDERR "# reading initialization file from $file\n" 11375 if ($T2H_VERBOSE); 11376 # require the file in the Texi2HTML::Config namespace 11377 return (Texi2HTML::Config::load($file)); 11378 } 11379 else 11380 { 11381 print STDERR "$ERROR Error: can't read init file $init_file\n"; 11382 return 0; 11383 } 11384} 11385 11386sub set_date() 11387{ 11388 if (!$Texi2HTML::Config::TEST) 11389 { 11390 print STDERR "# Setting date in $Texi2HTML::THISDOC{'current_lang'}\n" if ($T2H_DEBUG); 11391 $Texi2HTML::THISDOC{'today'} = Texi2HTML::I18n::pretty_date($Texi2HTML::THISDOC{'current_lang'}); # like "20 September 1993"; 11392 } 11393 else 11394 { 11395 $Texi2HTML::THISDOC{'today'} = 'a sunny day'; 11396 } 11397 $Texi2HTML::THISDOC{'today'} = $Texi2HTML::Config::DATE 11398 if (defined($Texi2HTML::Config::DATE)); 11399 $::things_map_ref->{'today'} = $Texi2HTML::THISDOC{'today'}; 11400 $::pre_map_ref->{'today'} = $Texi2HTML::THISDOC{'today'}; 11401 $::texi_map_ref->{'today'} = $Texi2HTML::THISDOC{'today'}; 11402} 11403 11404# 11405# called on -lang, and when a @documentlanguage appears 11406sub set_document_language ($;$$$) 11407{ 11408 my $lang = shift; 11409 my $from_command_line = shift; 11410 my $silent = shift; 11411 my $line_nr = shift; 11412 11413 my @langs = ($lang); 11414 11415 my $main_lang; 11416 if ($lang =~ /^([a-z]+)_([A-Z]+)/) 11417 { 11418 $main_lang = $1; 11419 push @langs, $main_lang; 11420 } 11421 11422 my @files = locate_init_file("$i18n_dir/$lang", 1); 11423 if (! scalar(@files) and defined($main_lang)) 11424 { 11425 @files = locate_init_file("$i18n_dir/$main_lang", 1); 11426 } 11427 11428 foreach my $file (@files) 11429 { 11430 Texi2HTML::Config::load($file); 11431 } 11432 foreach my $language (@langs) 11433 { 11434 if (Texi2HTML::I18n::set_language($language)) 11435 { 11436 print STDERR "# using '$language' as document language\n" if ($T2H_VERBOSE); 11437 $Texi2HTML::THISDOC{'current_lang'} = $language; 11438 # when processing the command line everything isn't already 11439 # set, so we cannot set the date. It is done as soon as possible 11440 # after arguments parsing and initializations, for a file. 11441 if ($from_command_line) 11442 { 11443 $Texi2HTML::GLOBAL{'current_lang'} = $language; 11444 } 11445 else 11446 { 11447 set_date(); 11448 } 11449 return 1; 11450 } 11451 } 11452 11453 echo_error ("Language specs for '$lang' do not exists. Reverting to '$Texi2HTML::THISDOC{'current_lang'}'", $line_nr) unless ($silent); 11454 return 0; 11455} 11456 11457# used to manage expanded sections from the command line 11458sub set_expansion($$) 11459{ 11460 my $region = shift; 11461 my $set = shift; 11462 $set = 1 if (!defined($set)); 11463 if ($set) 11464 { 11465 push (@Texi2HTML::Config::EXPAND, $region) unless (grep {$_ eq $region} @Texi2HTML::Config::EXPAND); 11466 } 11467 else 11468 { 11469 @Texi2HTML::Config::EXPAND = grep {$_ ne $region} @Texi2HTML::Config::EXPAND; 11470 } 11471} 11472 11473# manage footnote style 11474sub set_footnote_style($$) 11475{ 11476 if ($_[1] eq 'separate') 11477 { 11478 $Texi2HTML::Config::SEPARATED_FOOTNOTES = 1; 11479 } 11480 elsif ($_[1] eq 'end') 11481 { 11482 $Texi2HTML::Config::SEPARATED_FOOTNOTES = 0; 11483 } 11484 else 11485 { 11486 echo_error ('Bad argument for --footnote-style'); 11487 } 11488} 11489 11490 11491# find the encoding alias. 11492# with encoding support (USE_UNICODE), may return undef if no alias was found 11493sub encoding_alias($) 11494{ 11495 my $encoding = shift; 11496 return $encoding if (!defined($encoding) or $encoding eq ''); 11497 if ($Texi2HTML::Config::USE_UNICODE) 11498 { 11499 if (! Encode::resolve_alias($encoding)) 11500 { 11501 echo_warn("Encoding name unknown: $encoding"); 11502 return undef; 11503 } 11504 print STDERR "# Using encoding " . Encode::resolve_alias($encoding) . "\n" 11505 if ($T2H_VERBOSE); 11506 return Encode::resolve_alias($encoding); 11507 } 11508 else 11509 { 11510 #echo_warn("No alias searched for encoding"); 11511 if (exists($Texi2HTML::Config::t2h_encoding_aliases{$encoding})) 11512 { 11513 $encoding = $Texi2HTML::Config::t2h_encoding_aliases{$encoding}; 11514 echo_warn ("Document encoding is utf8, but there is no unicode support") if ($encoding eq 'utf-8'); 11515 return $encoding; 11516 } 11517 echo_warn("Encoding certainly poorly supported"); 11518 return $encoding; 11519 } 11520} 11521 11522 11523my %nodes; # nodes hash. The key is the texi node name 11524my %cross_reference_nodes; # normalized node names arrays 11525 11526# 11527# %value hold texinfo variables, see also -D, -U, @set and @clear. 11528# we predefine html (the output format) and texi2html (the translator) 11529# it is initialized with %value_initial at the beginning of the 11530# document parsing and filled and emptied as @set and @clear are 11531# encountered 11532my %value_initial = 11533 ( 11534 'html' => 1, 11535 'texi2html' => $THISVERSION, 11536 ); 11537 11538# 11539# _foo: internal variables to track @foo 11540# 11541foreach my $key ('_author', '_title', '_subtitle', '_shorttitlepage', 11542 '_settitle', '_setfilename', '_titlefont') 11543{ 11544 $value_initial{$key} = ''; # prevent -w warnings 11545} 11546 11547 11548sub unicode_to_protected($) 11549{ 11550 my $text = shift; 11551 my $result = ''; 11552 while ($text ne '') 11553 { 11554 if ($text =~ s/^([A-Za-z0-9]+)//o) 11555 { 11556 $result .= $1; 11557 } 11558 elsif ($text =~ s/^ //o) 11559 { 11560 $result .= '-'; 11561 } 11562 elsif ($text =~ s/^(.)//o) 11563 { 11564 my $char = $1; 11565 if (exists($Texi2HTML::Config::ascii_character_map{$char})) 11566 { 11567 $result .= '_' . lc($Texi2HTML::Config::ascii_character_map{$char}); 11568 } 11569 else 11570 { 11571 if (ord($char) <= hex(0xFFFF)) 11572 { 11573 $result .= '_' . lc(sprintf("%04x",ord($char))); 11574 } 11575 else 11576 { 11577 $result .= '__' . lc(sprintf("%06x",ord($char))); 11578 } 11579 } 11580 } 11581 else 11582 { 11583 print STDERR "Bug: unknown character in a cross ref (likely in infinite loop)\n"; 11584 print STDERR "Text: !!$text!!\n"; 11585 sleep 1; 11586 } 11587 } 11588 return $result; 11589} 11590 11591sub unicode_to_transliterate($) 11592{ 11593 my $text = shift; 11594 my $result = ''; 11595 while ($text ne '') 11596 { 11597 if ($text =~ s/^([A-Za-z0-9 ]+)//o) 11598 { 11599 $result .= $1; 11600 } 11601 elsif ($text =~ s/^(.)//o) 11602 { 11603 my $char = $1; 11604 if (exists($Texi2HTML::Config::ascii_character_map{$char})) 11605 { 11606 $result .= $char; 11607 } 11608 elsif (ord($char) <= hex(0xFFFF) and exists($Texi2HTML::Config::transliterate_map{uc(sprintf("%04x",ord($char)))})) 11609 { 11610 $result .= $Texi2HTML::Config::transliterate_map{uc(sprintf("%04x",ord($char)))}; 11611 } 11612 elsif (ord($char) <= hex(0xFFFF) and exists($Texi2HTML::Config::unicode_diacritical{uc(sprintf("%04x",ord($char)))})) 11613 { 11614 $result .= ''; 11615 } 11616 # in this case, we want to avoid calling unidecode, as we are sure 11617 # that there is no useful transliteration of the unicode character 11618 # instead we want to keep it as is. 11619 # This is the case, for example, for @exclamdown, is corresponds 11620 # with x00a1, but unidecode transliterates it to a !, we want 11621 # to avoid that and keep x00a1. 11622 elsif (ord($char) <= hex(0xFFFF) and exists($Texi2HTML::Config::no_transliterate_map{uc(sprintf("%04x",ord($char)))})) 11623 { 11624 $result .= $char; 11625 } 11626 else 11627 { 11628 if ($Texi2HTML::Config::USE_UNIDECODE) 11629 { 11630 $result .= unidecode($char); 11631 } 11632 else 11633 { 11634 $result .= $char; 11635 } 11636 } 11637 } 11638 else 11639 { 11640 print STDERR "Bug: unknown character in cross ref transliteration (likely in infinite loop)\n"; 11641 sleep 1; 11642 } 11643 } 11644 return $result; 11645} 11646 11647# T2H_OPTIONS is a hash whose keys are the (long) names of valid 11648# command-line options and whose values are a hash with the following keys: 11649# type ==> one of !|=i|:i|=s|:s (see Getopt::Long for more info) 11650# linkage ==> ref to scalar, array, or subroutine (see Getopt::Long for more info) 11651# verbose ==> short description of option (displayed by -h) 11652# noHelp ==> if 1 -> for "not so important options": only print description on -h 1 11653# 2 -> for obsolete options: only print description on -h 2 11654my $T2H_OPTIONS; 11655$T2H_OPTIONS -> {'debug'} = 11656{ 11657 type => '=i', 11658 linkage => \$Texi2HTML::Config::DEBUG, 11659 verbose => 'output HTML with debuging information', 11660}; 11661 11662$T2H_OPTIONS -> {'doctype'} = 11663{ 11664 type => '=s', 11665 linkage => \$Texi2HTML::Config::DOCTYPE, 11666 verbose => 'document type which is output in header of HTML files', 11667 noHelp => 1 11668}; 11669 11670$T2H_OPTIONS -> {'frameset-doctype'} = 11671{ 11672 type => '=s', 11673 linkage => \$Texi2HTML::Config::FRAMESET_DOCTYPE, 11674 verbose => 'document type for HTML frameset documents', 11675 noHelp => 1 11676}; 11677 11678$T2H_OPTIONS -> {'test'} = 11679{ 11680 type => '!', 11681 linkage => \$Texi2HTML::Config::TEST, 11682 verbose => 'use predefined information to avoid differences with reference files', 11683 noHelp => 1 11684}; 11685 11686$T2H_OPTIONS -> {'dump-texi'} = 11687{ 11688 type => '!', 11689 linkage => \$Texi2HTML::Config::DUMP_TEXI, 11690 verbose => 'dump the output of first pass into a file with extension passfirst and exit', 11691 noHelp => 1 11692}; 11693 11694$T2H_OPTIONS -> {'E'} = 11695{ 11696 type => '=s', 11697 linkage => \$Texi2HTML::Config::MACRO_EXPAND, 11698 verbose => 'output macro expanded source in <file>', 11699 noHelp => 2 11700}; 11701 11702$T2H_OPTIONS -> {'macro-expand'} = 11703{ 11704 type => '=s', 11705 linkage => \$Texi2HTML::Config::MACRO_EXPAND, 11706 verbose => 'output macro expanded source in <file>', 11707}; 11708 11709$T2H_OPTIONS -> {'expand'} = 11710{ 11711 type => '=s', 11712 linkage => sub {set_expansion($_[1], 1);}, 11713 verbose => 'Expand info|tex|none section of texinfo source', 11714 noHelp => 1, 11715}; 11716 11717$T2H_OPTIONS -> {'no-expand'} = 11718{ 11719 type => '=s', 11720 linkage => sub {set_expansion ($_[1], 0);}, 11721 verbose => 'Don\'t expand the given section of texinfo source', 11722}; 11723 11724$T2H_OPTIONS -> {'noexpand'} = 11725{ 11726 type => '=s', 11727 linkage => $T2H_OPTIONS->{'no-expand'}->{'linkage'}, 11728 verbose => $T2H_OPTIONS->{'no-expand'}->{'verbose'}, 11729 noHelp => 1, 11730}; 11731 11732$T2H_OPTIONS -> {'ifhtml'} = 11733{ 11734 type => '!', 11735 linkage => sub { set_expansion('html', $_[1]); }, 11736 verbose => "expand ifhtml and html sections", 11737}; 11738 11739$T2H_OPTIONS -> {'ifinfo'} = 11740{ 11741 type => '!', 11742 linkage => sub { set_expansion('info', $_[1]); }, 11743 verbose => "expand ifinfo", 11744}; 11745 11746$T2H_OPTIONS -> {'ifxml'} = 11747{ 11748 type => '!', 11749 linkage => sub { set_expansion('xml', $_[1]); }, 11750 verbose => "expand ifxml and xml sections", 11751}; 11752 11753$T2H_OPTIONS -> {'ifdocbook'} = 11754{ 11755 type => '!', 11756 linkage => sub { set_expansion('docbook', $_[1]); }, 11757 verbose => "expand ifdocbook and docbook sections", 11758}; 11759 11760$T2H_OPTIONS -> {'iftex'} = 11761{ 11762 type => '!', 11763 linkage => sub { set_expansion('tex', $_[1]); }, 11764 verbose => "expand iftex and tex sections", 11765}; 11766 11767$T2H_OPTIONS -> {'ifplaintext'} = 11768{ 11769 type => '!', 11770 linkage => sub { set_expansion('plaintext', $_[1]); }, 11771 verbose => "expand ifplaintext sections", 11772}; 11773 11774# actually a noop, since it is not used anywhere 11775$T2H_OPTIONS -> {'invisible'} = 11776{ 11777 type => '=s', 11778 linkage => \$Texi2HTML::Config::INVISIBLE_MARK, 11779 verbose => 'use text in invisble anchor', 11780 noHelp => 2, 11781}; 11782 11783$T2H_OPTIONS -> {'iso'} = 11784{ 11785 type => 'iso', 11786 linkage => \$Texi2HTML::Config::USE_ISO, 11787 verbose => 'if set, ISO8859 characters are used for special symbols (like copyright, etc)', 11788 noHelp => 1, 11789}; 11790 11791$T2H_OPTIONS -> {'I'} = 11792{ 11793 type => '=s', 11794 linkage => \@Texi2HTML::Config::INCLUDE_DIRS, 11795 verbose => 'append $s to the @include search path', 11796}; 11797 11798$T2H_OPTIONS -> {'conf-dir'} = 11799{ 11800 type => '=s', 11801 linkage => \@Texi2HTML::Config::CONF_DIRS, 11802 verbose => 'append $s to the init file directories', 11803}; 11804 11805$T2H_OPTIONS -> {'P'} = 11806{ 11807 type => '=s', 11808 linkage => sub {unshift (@Texi2HTML::Config::PREPEND_DIRS, $_[1]);}, 11809 verbose => 'prepend $s to the @include search path', 11810}; 11811 11812$T2H_OPTIONS -> {'top-file'} = 11813{ 11814 type => '=s', 11815 linkage => \$Texi2HTML::Config::TOP_FILE, 11816 verbose => 'use $s as top file, instead of <docname>.html', 11817}; 11818 11819$T2H_OPTIONS -> {'toc-file'} = 11820{ 11821 type => '=s', 11822 linkage => \$Texi2HTML::Config::TOC_FILE, 11823 verbose => 'use $s as ToC file, instead of <docname>_toc.html', 11824}; 11825 11826$T2H_OPTIONS -> {'frames'} = 11827{ 11828 type => '!', 11829 linkage => \$Texi2HTML::Config::FRAMES, 11830 verbose => 'output files which use HTML 4.0 frames (experimental)', 11831 noHelp => 1, 11832}; 11833 11834$T2H_OPTIONS -> {'menu'} = 11835{ 11836 type => '!', 11837 linkage => \$Texi2HTML::Config::SHOW_MENU, 11838 verbose => 'output Texinfo menus', 11839}; 11840 11841$T2H_OPTIONS -> {'number-sections'} = 11842{ 11843 type => '!', 11844 linkage => \$Texi2HTML::Config::NUMBER_SECTIONS, 11845 verbose => 'use numbered sections', 11846}; 11847 11848$T2H_OPTIONS -> {'use-nodes'} = 11849{ 11850 type => '!', 11851 linkage => \$Texi2HTML::Config::USE_NODES, 11852 verbose => 'use nodes for sectionning', 11853}; 11854 11855$T2H_OPTIONS -> {'node-files'} = 11856{ 11857 type => '!', 11858 linkage => \$Texi2HTML::Config::NODE_FILES, 11859 verbose => 'produce one file per node for cross references' 11860}; 11861 11862$T2H_OPTIONS -> {'footnote-style'} = 11863{ 11864 type => '=s', 11865 linkage => sub {set_footnote_style ($_[0], $_[1]);}, 11866 verbose => 'output footnotes separate|end', 11867}; 11868 11869$T2H_OPTIONS -> {'toc-links'} = 11870{ 11871 type => '!', 11872 linkage => \$Texi2HTML::Config::TOC_LINKS, 11873 verbose => 'create links from headings to toc entries' 11874}; 11875 11876$T2H_OPTIONS -> {'split'} = 11877{ 11878 type => '=s', 11879 linkage => \$Texi2HTML::Config::SPLIT, 11880 verbose => 'split document on section|chapter|node else no splitting', 11881}; 11882 11883$T2H_OPTIONS -> {'no-split'} = 11884{ 11885 type => '!', 11886 linkage => sub {$Texi2HTML::Config::SPLIT = '';}, 11887 verbose => 'no splitting of document', 11888 noHelp => 1, 11889}; 11890 11891$T2H_OPTIONS -> {'header'} = 11892{ 11893 type => '!', 11894 linkage => \$Texi2HTML::Config::SECTION_NAVIGATION, 11895 verbose => 'output navigation headers for each section', 11896}; 11897 11898$T2H_OPTIONS -> {'subdir'} = 11899{ 11900 type => '=s', 11901 linkage => \$Texi2HTML::Config::SUBDIR, 11902 verbose => 'put files in directory $s, not $cwd', 11903 noHelp => 1, 11904}; 11905 11906$T2H_OPTIONS -> {'short-ext'} = 11907{ 11908 type => '!', 11909 linkage => \$Texi2HTML::Config::SHORTEXTN, 11910 verbose => 'use "htm" extension for output HTML files', 11911}; 11912 11913$T2H_OPTIONS -> {'prefix'} = 11914{ 11915 type => '=s', 11916 linkage => \$Texi2HTML::Config::PREFIX, 11917 verbose => 'use as prefix for output files, instead of <docname>', 11918}; 11919 11920$T2H_OPTIONS -> {'o'} = 11921{ 11922 type => '=s', 11923 linkage => \$Texi2HTML::Config::OUT, 11924 verbose => 'output goes to $s (directory if split)', 11925 noHelp => 2, 11926}; 11927 11928$T2H_OPTIONS -> {'output'} = 11929{ 11930 type => '=s', 11931 linkage => \$Texi2HTML::Config::OUT, 11932 verbose => 'output goes to $s (directory if split)', 11933}; 11934 11935$T2H_OPTIONS -> {'no-validate'} = 11936{ 11937 type => '!', 11938 linkage => \$Texi2HTML::Config::NOVALIDATE, 11939 verbose => 'suppress node cross-reference validation', 11940}; 11941 11942$T2H_OPTIONS -> {'short-ref'} = 11943{ 11944 type => '!', 11945 linkage => \$Texi2HTML::Config::SHORT_REF, 11946 verbose => 'if set, references are without section numbers', 11947}; 11948 11949$T2H_OPTIONS -> {'idx-sum'} = 11950{ 11951 type => '!', 11952 linkage => \$Texi2HTML::Config::IDX_SUMMARY, 11953 verbose => 'if set, also output index summary', 11954 noHelp => 1, 11955}; 11956 11957$T2H_OPTIONS -> {'def-table'} = 11958{ 11959 type => '!', 11960 linkage => \$Texi2HTML::Config::DEF_TABLE, 11961 verbose => 'if set, \@def.. are converted using tables.', 11962 noHelp => 1, 11963}; 11964 11965# disambiguate verbose and version, like makeinfo does 11966$T2H_OPTIONS -> {'v'} = 11967{ 11968 type => '!', 11969 linkage=> \$Texi2HTML::Config::VERBOSE, 11970 verbose => 'print progress info to stdout', 11971 noHelp => 2, 11972}; 11973 11974$T2H_OPTIONS -> {'verbose'} = 11975{ 11976 type => '!', 11977 linkage=> \$Texi2HTML::Config::VERBOSE, 11978 verbose => 'print progress info to stdout', 11979}; 11980 11981$T2H_OPTIONS -> {'document-language'} = 11982{ 11983 type => '=s', 11984 linkage => sub {set_document_language($_[1], 1)}, 11985 verbose => 'use $s as document language', 11986}; 11987 11988$T2H_OPTIONS -> {'ignore-preamble-text'} = 11989{ 11990 type => '!', 11991 linkage => \$Texi2HTML::Config::IGNORE_PREAMBLE_TEXT, 11992 verbose => 'if set, ignore the text before @node and sectionning commands', 11993 noHelp => 1, 11994}; 11995 11996$T2H_OPTIONS -> {'html-xref-prefix'} = 11997{ 11998 type => '=s', 11999 linkage => \$Texi2HTML::Config::EXTERNAL_DIR, 12000 verbose => '$s is the base dir for external manual references', 12001 noHelp => 1, 12002}; 12003 12004$T2H_OPTIONS -> {'l2h'} = 12005{ 12006 type => '!', 12007 linkage => \$Texi2HTML::Config::L2H, 12008 verbose => 'if set, uses latex2html for @math and @tex', 12009}; 12010 12011$T2H_OPTIONS -> {'l2h-l2h'} = 12012{ 12013 type => '=s', 12014 linkage => \$Texi2HTML::Config::L2H_L2H, 12015 verbose => 'program to use for latex2html translation', 12016 noHelp => 1, 12017}; 12018 12019$T2H_OPTIONS -> {'l2h-skip'} = 12020{ 12021 type => '!', 12022 linkage => \$Texi2HTML::Config::L2H_SKIP, 12023 verbose => 'if set, tries to reuse previously latex2html output', 12024 noHelp => 1, 12025}; 12026 12027$T2H_OPTIONS -> {'l2h-tmp'} = 12028{ 12029 type => '=s', 12030 linkage => \$Texi2HTML::Config::L2H_TMP, 12031 verbose => 'if set, uses $s as temporary latex2html directory', 12032 noHelp => 1, 12033}; 12034 12035$T2H_OPTIONS -> {'l2h-file'} = 12036{ 12037 type => '=s', 12038 linkage => \$Texi2HTML::Config::L2H_FILE, 12039 verbose => 'if set, uses $s as latex2html init file', 12040 noHelp => 1, 12041}; 12042 12043 12044$T2H_OPTIONS -> {'l2h-clean'} = 12045{ 12046 type => '!', 12047 linkage => \$Texi2HTML::Config::L2H_CLEAN, 12048 verbose => 'if set, do not keep intermediate latex2html files for later reuse', 12049 noHelp => 1, 12050}; 12051 12052$T2H_OPTIONS -> {'D'} = 12053{ 12054 type => '=s', 12055 linkage => sub {$value_initial{$_[1]} = 1;}, 12056 verbose => 'equivalent to Texinfo "@set $s 1"', 12057 noHelp => 1, 12058}; 12059 12060$T2H_OPTIONS -> {'U'} = 12061{ 12062 type => '=s', 12063 linkage => sub {delete $value_initial{$_[1]};}, 12064 verbose => 'equivalent to Texinfo "@clear $s"', 12065 noHelp => 1, 12066}; 12067 12068$T2H_OPTIONS -> {'init-file'} = 12069{ 12070 type => '=s', 12071 linkage => \&load_init_file, 12072 verbose => 'load init file $s' 12073}; 12074 12075$T2H_OPTIONS -> {'css-include'} = 12076{ 12077 type => '=s', 12078 linkage => \@Texi2HTML::Config::CSS_FILES, 12079 verbose => 'use css file $s' 12080}; 12081 12082$T2H_OPTIONS -> {'css-ref'} = 12083{ 12084 type => '=s', 12085 linkage => \@Texi2HTML::Config::CSS_REFS, 12086 verbose => 'generate reference to the CSS URL $s' 12087}; 12088 12089$T2H_OPTIONS -> {'transliterate-file-names'} = 12090{ 12091 type => '!', 12092 linkage=> \$Texi2HTML::Config::TRANSLITERATE_NODE, 12093 verbose => 'produce file names in ASCII transliteration', 12094}; 12095 12096$T2H_OPTIONS -> {'error-limit'} = 12097{ 12098 type => '=i', 12099 linkage => \$Texi2HTML::Config::ERROR_LIMIT, 12100 verbose => 'quit after NUM errors (default 1000).', 12101}; 12102 12103$T2H_OPTIONS -> {'monolithic'} = 12104{ 12105 type => '!', 12106 linkage => \$Texi2HTML::Config::MONOLITHIC, 12107 verbose => 'output only one file including ToC, About...', 12108 noHelp => 1 12109}; 12110## 12111## obsolete cmd line options 12112## 12113my $T2H_OBSOLETE_OPTIONS; 12114 12115$T2H_OBSOLETE_OPTIONS -> {'out-file'} = 12116{ 12117 type => '=s', 12118 linkage => sub {$Texi2HTML::Config::OUT = $_[1]; $Texi2HTML::Config::SPLIT = '';}, 12119 verbose => 'if set, all HTML output goes into file $s, obsoleted by "-output" with different semantics', 12120 noHelp => 2 12121}; 12122 12123$T2H_OBSOLETE_OPTIONS -> {'lang'} = 12124{ 12125 type => '=s', 12126 linkage => sub {set_document_language($_[1], 1)}, 12127 verbose => 'obsolete, use "--document-language" instead', 12128 noHelp => 2 12129}; 12130 12131$T2H_OBSOLETE_OPTIONS -> {'number'} = 12132{ 12133 type => '!', 12134 linkage => \$Texi2HTML::Config::NUMBER_SECTIONS, 12135 verbose => 'obsolete, use "--number-sections" instead', 12136 noHelp => 2 12137}; 12138 12139 12140$T2H_OBSOLETE_OPTIONS -> {'separated-footnotes'} = 12141{ 12142 type => '!', 12143 linkage => \$Texi2HTML::Config::SEPARATED_FOOTNOTES, 12144 verbose => 'obsolete, use "--footnote-style" instead', 12145 noHelp => 2 12146}; 12147 12148$T2H_OBSOLETE_OPTIONS -> {'Verbose'} = 12149{ 12150 type => '!', 12151 linkage=> \$Texi2HTML::Config::VERBOSE, 12152 verbose => 'obsolete, use "--verbose" instead', 12153 noHelp => 2 12154}; 12155 12156 12157$T2H_OBSOLETE_OPTIONS -> {init_file} = 12158{ 12159 type => '=s', 12160 linkage => \&load_init_file, 12161 verbose => 'obsolete, use "-init-file" instead', 12162 noHelp => 2 12163}; 12164 12165$T2H_OBSOLETE_OPTIONS -> {l2h_clean} = 12166{ 12167 type => '!', 12168 linkage => \$Texi2HTML::Config::L2H_CLEAN, 12169 verbose => 'obsolete, use "-l2h-clean" instead', 12170 noHelp => 2, 12171}; 12172 12173$T2H_OBSOLETE_OPTIONS -> {l2h_l2h} = 12174{ 12175 type => '=s', 12176 linkage => \$Texi2HTML::Config::L2H_L2H, 12177 verbose => 'obsolete, use "-l2h-l2h" instead', 12178 noHelp => 2 12179}; 12180 12181$T2H_OBSOLETE_OPTIONS -> {l2h_skip} = 12182{ 12183 type => '!', 12184 linkage => \$Texi2HTML::Config::L2H_SKIP, 12185 verbose => 'obsolete, use "-l2h-skip" instead', 12186 noHelp => 2 12187}; 12188 12189$T2H_OBSOLETE_OPTIONS -> {l2h_tmp} = 12190{ 12191 type => '=s', 12192 linkage => \$Texi2HTML::Config::L2H_TMP, 12193 verbose => 'obsolete, use "-l2h-tmp" instead', 12194 noHelp => 2 12195}; 12196 12197$T2H_OBSOLETE_OPTIONS -> {out_file} = 12198{ 12199 type => '=s', 12200 linkage => sub {$Texi2HTML::Config::OUT = $_[1]; $Texi2HTML::Config::SPLIT = '';}, 12201 verbose => 'obsolete, use "-out-file" instead', 12202 noHelp => 2 12203}; 12204 12205$T2H_OBSOLETE_OPTIONS -> {short_ref} = 12206{ 12207 type => '!', 12208 linkage => \$Texi2HTML::Config::SHORT_REF, 12209 verbose => 'obsolete, use "-short-ref" instead', 12210 noHelp => 2 12211}; 12212 12213$T2H_OBSOLETE_OPTIONS -> {idx_sum} = 12214{ 12215 type => '!', 12216 linkage => \$Texi2HTML::Config::IDX_SUMMARY, 12217 verbose => 'obsolete, use "-idx-sum" instead', 12218 noHelp => 2 12219}; 12220 12221$T2H_OBSOLETE_OPTIONS -> {def_table} = 12222{ 12223 type => '!', 12224 linkage => \$Texi2HTML::Config::DEF_TABLE, 12225 verbose => 'obsolete, use "-def-table" instead', 12226 noHelp => 2 12227}; 12228 12229$T2H_OBSOLETE_OPTIONS -> {short_ext} = 12230{ 12231 type => '!', 12232 linkage => \$Texi2HTML::Config::SHORTEXTN, 12233 verbose => 'obsolete, use "-short-ext" instead', 12234 noHelp => 2 12235}; 12236 12237$T2H_OBSOLETE_OPTIONS -> {sec_nav} = 12238{ 12239 type => '!', 12240 linkage => \$Texi2HTML::Config::SECTION_NAVIGATION, 12241 verbose => 'obsolete, use "-header" instead', 12242 noHelp => 2 12243}; 12244 12245$T2H_OBSOLETE_OPTIONS -> {'sec-nav'} = 12246{ 12247 type => '!', 12248 linkage => \$Texi2HTML::Config::SECTION_NAVIGATION, 12249 verbose => 'obsolete, use "--header" instead', 12250 noHelp => 2 12251}; 12252 12253$T2H_OBSOLETE_OPTIONS -> {top_file} = 12254{ 12255 type => '=s', 12256 linkage => \$Texi2HTML::Config::TOP_FILE, 12257 verbose => 'obsolete, use "-top-file" instead', 12258 noHelp => 2 12259}; 12260 12261$T2H_OBSOLETE_OPTIONS -> {toc_file} = 12262{ 12263 type => '=s', 12264 linkage => \$Texi2HTML::Config::TOC_FILE, 12265 verbose => 'obsolete, use "-toc-file" instead', 12266 noHelp => 2 12267}; 12268 12269$T2H_OBSOLETE_OPTIONS -> {glossary} = 12270{ 12271 type => '!', 12272 linkage => \$Texi2HTML::Config::USE_GLOSSARY, 12273 verbose => "this does nothing", 12274 noHelp => 2, 12275}; 12276 12277$T2H_OBSOLETE_OPTIONS -> {check} = 12278{ 12279 type => '!', 12280 linkage => sub {exit 0;}, 12281 verbose => "exit without doing anything", 12282 noHelp => 2, 12283}; 12284 12285$T2H_OBSOLETE_OPTIONS -> {dump_texi} = 12286{ 12287 type => '!', 12288 linkage => \$Texi2HTML::Config::DUMP_TEXI, 12289 verbose => 'obsolete, use "-dump-texi" instead', 12290 noHelp => 1 12291}; 12292 12293$T2H_OBSOLETE_OPTIONS -> {frameset_doctype} = 12294{ 12295 type => '=s', 12296 linkage => \$Texi2HTML::Config::FRAMESET_DOCTYPE, 12297 verbose => 'obsolete, use "-frameset-doctype" instead', 12298 noHelp => 2 12299}; 12300 12301$T2H_OBSOLETE_OPTIONS -> {'no-section_navigation'} = 12302{ 12303 type => '!', 12304 linkage => sub {$Texi2HTML::Config::SECTION_NAVIGATION = 0;}, 12305 verbose => 'obsolete, use -nosec_nav', 12306 noHelp => 2, 12307}; 12308my $use_acc; # not used 12309$T2H_OBSOLETE_OPTIONS -> {use_acc} = 12310{ 12311 type => '!', 12312 linkage => \$use_acc, 12313 verbose => 'obsolete, set to true unconditionnaly', 12314 noHelp => 2 12315}; 12316$T2H_OBSOLETE_OPTIONS -> {expandinfo} = 12317{ 12318 type => '!', 12319 linkage => sub {push @Texi2HTML::Config::EXPAND, 'info';}, 12320 verbose => 'obsolete, use "-expand info" instead', 12321 noHelp => 2, 12322}; 12323$T2H_OBSOLETE_OPTIONS -> {expandtex} = 12324{ 12325 type => '!', 12326 linkage => sub {push @Texi2HTML::Config::EXPAND, 'tex';}, 12327 verbose => 'obsolete, use "-expand tex" instead', 12328 noHelp => 2, 12329}; 12330$T2H_OBSOLETE_OPTIONS -> {split_node} = 12331{ 12332 type => '!', 12333 linkage => sub{$Texi2HTML::Config::SPLIT = 'section';}, 12334 verbose => 'obsolete, use "-split section" instead', 12335 noHelp => 2, 12336}; 12337$T2H_OBSOLETE_OPTIONS -> {split_chapter} = 12338{ 12339 type => '!', 12340 linkage => sub{$Texi2HTML::Config::SPLIT = 'chapter';}, 12341 verbose => 'obsolete, use "-split chapter" instead', 12342 noHelp => 2, 12343}; 12344$T2H_OBSOLETE_OPTIONS -> {no_verbose} = 12345{ 12346 type => '!', 12347 linkage => sub {$Texi2HTML::Config::VERBOSE = 0;}, 12348 verbose => 'obsolete, use -noverbose instead', 12349 noHelp => 2, 12350}; 12351$T2H_OBSOLETE_OPTIONS -> {output_file} = 12352{ 12353 type => '=s', 12354 linkage => sub {$Texi2HTML::Config::OUT = $_[1]; $Texi2HTML::Config::SPLIT = '';}, 12355 verbose => 'obsolete, use --out-file instead', 12356 noHelp => 2 12357}; 12358 12359$T2H_OBSOLETE_OPTIONS -> {section_navigation} = 12360{ 12361 type => '!', 12362 linkage => \$Texi2HTML::Config::SECTION_NAVIGATION, 12363 verbose => 'obsolete, use --sec-nav instead', 12364 noHelp => 2, 12365}; 12366 12367$T2H_OBSOLETE_OPTIONS -> {verbose} = 12368{ 12369 type => '!', 12370 linkage=> \$Texi2HTML::Config::VERBOSE, 12371 verbose => 'obsolete, use -Verbose instead', 12372 noHelp => 2 12373}; 12374 12375# read initialzation from $sysconfdir/texi2htmlrc or $HOME/.texi2htmlrc 12376# (this is obsolete) 12377my @rc_files = (); 12378push @rc_files, "$sysconfdir/texi2htmlrc" if defined($sysconfdir); 12379push @rc_files, "$ENV{'HOME'}/.texi2htmlrc" if (defined($ENV{HOME})); 12380foreach my $i (@rc_files) 12381{ 12382 if (-e $i and -r $i) 12383 { 12384 print STDERR "# reading initialization file from $i\n" 12385 if ($T2H_VERBOSE); 12386 print STDERR "Reading config from $i is obsolete, use texi2html/$conf_file_name instead\n"; 12387 Texi2HTML::Config::load($i); 12388 } 12389} 12390 12391# read initialization files 12392foreach my $file (locate_init_file($conf_file_name, 1)) 12393{ 12394 print STDERR "# reading initialization file from $file\n" if ($T2H_VERBOSE); 12395 Texi2HTML::Config::load($file); 12396} 12397 12398 12399#+++############################################################################ 12400# # 12401# parse command-line options 12402# # 12403#---############################################################################ 12404 12405 12406my $T2H_USAGE_TEXT = <<EOT; 12407Usage: texi2html [OPTIONS] TEXINFO-FILE 12408Translates Texinfo source documentation to HTML. 12409EOT 12410my $T2H_FAILURE_TEXT = <<EOT; 12411Try 'texi2html --help' for usage instructions. 12412EOT 12413 12414my $options = new Getopt::MySimple; 12415 12416$T2H_OPTIONS -> {'help'} = 12417{ 12418 type => ':i', 12419 default => '', 12420 linkage => sub {$options->helpOptions($_[1]); 12421 print "\nSend bugs and suggestions to <texi2html-bug\@nongnu.org>\n"; 12422 exit (0);}, 12423 verbose => "print help and exit" 12424}; 12425 12426# this avoids getOptions defining twice 'help' and 'version'. 12427$T2H_OBSOLETE_OPTIONS->{'help'} = 0; 12428$T2H_OBSOLETE_OPTIONS->{'version'} = 0; 12429$T2H_OBSOLETE_OPTIONS->{'verbose'} = 0; 12430 12431# this is more compatible with makeinfo. But it changes how command lines 12432# are parsed, for example -init file.init dodesn't work anymore. 12433#Getopt::Long::Configure ("gnu_getopt"); 12434 12435# some older version of GetOpt::Long don't have 12436# Getopt::Long::Configure("pass_through") 12437eval {Getopt::Long::Configure("pass_through");}; 12438my $Configure_failed = $@ && <<EOT; 12439**WARNING: Parsing of obsolete command-line options could have failed. 12440 Consider to use only documented command-line options (run 12441 'texi2html --help 2' for a complete list) or upgrade to perl 12442 version 5.005 or higher. 12443EOT 12444if (! $options->getOptions($T2H_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n")) 12445{ 12446 print STDERR "$Configure_failed" if $Configure_failed; 12447 die $T2H_FAILURE_TEXT; 12448} 12449if (@ARGV > 1) 12450{ 12451 eval {Getopt::Long::Configure("no_pass_through");}; 12452 if (! $options->getOptions($T2H_OBSOLETE_OPTIONS, $T2H_USAGE_TEXT, "$THISVERSION\n")) 12453 { 12454 print STDERR "$Configure_failed" if $Configure_failed; 12455 die $T2H_FAILURE_TEXT; 12456 } 12457} 12458 12459# $T2H_DEBUG and $T2H_VERBOSE are shorthands 12460$T2H_DEBUG = $Texi2HTML::Config::DEBUG; 12461$T2H_VERBOSE = $Texi2HTML::Config::VERBOSE; 12462 12463# 12464# read texi2html extensions (if any) 12465# It is obsolete (obsoleted by -init-file). we keep it for backward 12466# compatibility. 12467my $extensions = 'texi2html.ext'; # extensions in working directory 12468if (-f $extensions) 12469{ 12470 print STDERR "# reading extensions from $extensions\n" if $T2H_VERBOSE; 12471 require($extensions); 12472} 12473my $progdir; 12474($progdir = $0) =~ s/[^\/]+$//; 12475if ($progdir && ($progdir ne './')) 12476{ 12477 $extensions = "${progdir}texi2html.ext"; # extensions in texi2html directory 12478 if (-f $extensions) 12479 { 12480 print STDERR "# reading extensions from $extensions\n" if $T2H_VERBOSE; 12481 require($extensions); 12482 } 12483} 12484 12485 12486#+++############################################################################ 12487# # 12488# evaluation of cmd line options 12489# # 12490#---############################################################################ 12491 12492# set the default 'args' entry to normal for each style hash (and each command 12493# within) 12494my $name_index = -1; 12495my @hash_names = ('style_map', 'style_map_pre', 'style_map_texi', 'simple_format_style_map_texi'); 12496foreach my $hash (\%Texi2HTML::Config::style_map, \%Texi2HTML::Config::style_map_pre, \%Texi2HTML::Config::style_map_texi, \%Texi2HTML::Config::simple_format_style_map_texi) 12497{ 12498 $name_index++; 12499 my $name = $hash_names[$name_index]; # name associated with hash ref 12500 foreach my $style (keys(%{$hash})) 12501 { 12502 next unless (ref($hash->{$style}) eq 'HASH'); 12503 $hash->{$style}->{'args'} = ['normal'] if (!exists($hash->{$style}->{'args'})); 12504 die "Bug: args not defined, but existing, for $style in $name" if (!defined($hash->{$style}->{'args'})); 12505#print STDERR "DEFAULT($name, $hash) add normal as arg for $style ($hash->{$style}), $hash->{$style}->{'args'}\n"; 12506 } 12507} 12508 12509my (%cross_ref_simple_map_texi, %cross_ref_style_map_texi, 12510 %cross_ref_texi_map, %cross_transliterate_style_map_texi, 12511 %cross_transliterate_texi_map); 12512 12513# setup hashes used for html manual cross references in texinfo 12514%cross_ref_texi_map = %Texi2HTML::Config::texi_map; 12515 12516$cross_ref_texi_map{'enddots'} = '...'; 12517 12518%cross_ref_simple_map_texi = %Texi2HTML::Config::simple_map_texi; 12519 12520%cross_transliterate_texi_map = %cross_ref_texi_map; 12521 12522foreach my $command (keys(%Texi2HTML::Config::style_map_texi)) 12523{ 12524 $cross_ref_style_map_texi{$command} = {}; 12525 $cross_transliterate_style_map_texi{$command} = {}; 12526 foreach my $key (keys (%{$Texi2HTML::Config::style_map_texi{$command}})) 12527 { 12528#print STDERR "$command, $key, $style_map_texi{$command}->{$key}\n"; 12529 $cross_ref_style_map_texi{$command}->{$key} = 12530 $Texi2HTML::Config::style_map_texi{$command}->{$key}; 12531 $cross_transliterate_style_map_texi{$command}->{$key} = 12532 $Texi2HTML::Config::style_map_texi{$command}->{$key}; 12533 } 12534} 12535 12536$cross_ref_simple_map_texi{"\n"} = ' '; 12537$cross_ref_simple_map_texi{"*"} = ' '; 12538 12539 12540# Fill in the %style_type hash, a hash associating style @-comand with 12541# the type, 'accent', real 'style', simple' style, or 'special'. 12542# 'simple_style' styles don't extend accross lines. 12543my %style_type = (); 12544my @simple_styles = ('ctrl', 'w', 'url','uref','indicateurl','email', 12545 'titlefont'); 12546foreach my $style (keys(%Texi2HTML::Config::style_map)) 12547{ 12548 if (exists $Texi2HTML::Config::command_type{$style}) 12549 { 12550 $style_type{$style} = $Texi2HTML::Config::command_type{$style}; 12551 next; 12552 } 12553 if (ref($Texi2HTML::Config::style_map{$style} eq 'HASH')) 12554 { 12555 $style_type{$style} = $Texi2HTML::Config::style_map{$style}->{'type'} 12556 if (exists($Texi2HTML::Config::style_map{$style}->{'type'})); 12557 } 12558 else 12559 { 12560 $style_type{$style} = 'simple_style' if (grep {$_ eq $style} @simple_styles); 12561 } 12562 $style_type{$style} = 'style' unless (defined($style_type{$style})); 12563} 12564 12565foreach my $accent (keys(%Texi2HTML::Config::unicode_accents), 'tieaccent', 'dotless') 12566{ 12567 if (exists $Texi2HTML::Config::command_type{$accent}) 12568 { 12569 $style_type{$accent} = $Texi2HTML::Config::command_type{$accent}; 12570 next; 12571 } 12572 $style_type{$accent} = 'accent'; 12573} 12574 12575 12576 12577 12578foreach my $special ('footnote', 'ref', 'xref', 'pxref', 'inforef', 'anchor', 'image', 'hyphenation') 12579{ 12580 if (exists $Texi2HTML::Config::command_type{$special}) 12581 { 12582 $style_type{$special} = $Texi2HTML::Config::command_type{$special}; 12583 next; 12584 } 12585 $style_type{$special} = 'special'; 12586} 12587 12588# retro compatibility for $Texi2HTML::Config::EXPAND 12589push (@Texi2HTML::Config::EXPAND, $Texi2HTML::Config::EXPAND) if ($Texi2HTML::Config::EXPAND); 12590 12591# correct %Texi2HTML::Config::texi_formats_map based on command line and init 12592# variables 12593$Texi2HTML::Config::texi_formats_map{'menu'} = 1 if ($Texi2HTML::Config::SHOW_MENU); 12594 12595foreach my $expanded (@Texi2HTML::Config::EXPAND) 12596{ 12597 $Texi2HTML::Config::texi_formats_map{"if$expanded"} = 1 if (exists($Texi2HTML::Config::texi_formats_map{"if$expanded"})); 12598 next unless (exists($Texi2HTML::Config::texi_formats_map{$expanded})); 12599 if (grep {$_ eq $expanded} @raw_regions) 12600 { 12601 $Texi2HTML::Config::texi_formats_map{$expanded} = 'raw'; 12602 } 12603 else 12604 { 12605 $Texi2HTML::Config::texi_formats_map{$expanded} = 1; 12606 } 12607} 12608 12609foreach my $key (keys(%Texi2HTML::Config::texi_formats_map)) 12610{ 12611 unless ($Texi2HTML::Config::texi_formats_map{$key} eq 'raw') 12612 { 12613 set_no_line_macro($key, 1); 12614 set_no_line_macro("end $key", 1); 12615 } 12616} 12617 12618# handle ifnot regions 12619foreach my $region (keys (%Texi2HTML::Config::texi_formats_map)) 12620{ 12621 next if ($region =~ /^ifnot/); 12622 if ($Texi2HTML::Config::texi_formats_map{$region} and $region =~ /^if(\w+)$/) 12623 { 12624 $Texi2HTML::Config::texi_formats_map{"ifnot$1"} = 0; 12625 } 12626} 12627 12628if ($T2H_VERBOSE) 12629{ 12630 print STDERR "# Expanded: "; 12631 foreach my $text_macro (keys(%Texi2HTML::Config::texi_formats_map)) 12632 { 12633 print STDERR "$text_macro " if ($Texi2HTML::Config::texi_formats_map{$text_macro}); 12634 } 12635 print STDERR "\n"; 12636} 12637 12638# This is kept in that file although it is html formatting as it seems to 12639# be rather obsolete 12640$Texi2HTML::Config::INVISIBLE_MARK = '<img src="invisible.xbm" alt="">' if $Texi2HTML::Config::INVISIBLE_MARK eq 'xbm'; 12641 12642$T2H_DEBUG |= $DEBUG_TEXI if ($Texi2HTML::Config::DUMP_TEXI); 12643 12644# no user provided USE_UNICODE, use configure provided 12645if (!defined($Texi2HTML::Config::USE_UNICODE)) 12646{ 12647 $Texi2HTML::Config::USE_UNICODE = '1'; 12648} 12649 12650# no user provided nor configured, run time test 12651if ($Texi2HTML::Config::USE_UNICODE eq '@' .'USE_UNICODE@') 12652{ 12653 $Texi2HTML::Config::USE_UNICODE = 1; 12654 eval { 12655 require Encode; 12656 require Unicode::Normalize; 12657 Encode->import('encode'); 12658 }; 12659 $Texi2HTML::Config::USE_UNICODE = 0 if ($@); 12660} 12661elsif ($Texi2HTML::Config::USE_UNICODE) 12662{# user provided or set by configure 12663 require Encode; 12664 require Unicode::Normalize; 12665 Encode->import('encode'); 12666} 12667 12668# no user provided USE_UNIDECODE, use configure provided 12669if (!defined($Texi2HTML::Config::USE_UNIDECODE)) 12670{ 12671 $Texi2HTML::Config::USE_UNIDECODE = '0'; 12672} 12673 12674# no user provided nor configured, run time test 12675if ($Texi2HTML::Config::USE_UNIDECODE eq '@' .'USE_UNIDECODE@') 12676{ 12677 $Texi2HTML::Config::USE_UNIDECODE = 1; 12678 eval { 12679 require Text::Unidecode; 12680 Text::Unidecode->import('unidecode'); 12681 }; 12682 $Texi2HTML::Config::USE_UNIDECODE = 0 if ($@); 12683} 12684elsif ($Texi2HTML::Config::USE_UNIDECODE) 12685{# user provided or set by configure 12686 require Text::Unidecode; 12687 Text::Unidecode->import('unidecode'); 12688} 12689 12690print STDERR "# USE_UNICODE $Texi2HTML::Config::USE_UNICODE, USE_UNIDECODE $Texi2HTML::Config::USE_UNIDECODE \n" 12691 if ($T2H_VERBOSE); 12692 12693# Construct hashes used for cross references generation 12694# Do it now as the user may have changed $USE_UNICODE 12695 12696foreach my $key (keys(%Texi2HTML::Config::unicode_map)) 12697{ 12698 if ($Texi2HTML::Config::unicode_map{$key} ne '') 12699 { 12700 if ($Texi2HTML::Config::USE_UNICODE) 12701 { 12702 $cross_ref_texi_map{$key} = chr(hex($Texi2HTML::Config::unicode_map{$key})); 12703 # cross_transliterate_texi_map is only used if USE_UNICODE or 12704 # USE_UNIDECODE is unset and TRANSLITERATE_NODE is set 12705 if (exists ($Texi2HTML::Config::transliterate_map{$Texi2HTML::Config::unicode_map{$key}})) 12706 { 12707 $cross_transliterate_texi_map{$key} = $Texi2HTML::Config::transliterate_map{$Texi2HTML::Config::unicode_map{$key}}; 12708 } 12709 else 12710 { 12711 $cross_transliterate_texi_map{$key} = chr(hex($Texi2HTML::Config::unicode_map{$key})); 12712 } 12713 } 12714 else 12715 { 12716 $cross_ref_texi_map{$key} = '_' . lc($Texi2HTML::Config::unicode_map{$key}); 12717 # cross_transliterate_texi_map is only used if USE_UNICODE or 12718 # USE_UNIDECODE is unset and TRANSLITERATE_NODE is set 12719 if (exists ($Texi2HTML::Config::transliterate_map{$Texi2HTML::Config::unicode_map{$key}})) 12720 { 12721 $cross_transliterate_texi_map{$key} = $Texi2HTML::Config::transliterate_map{$Texi2HTML::Config::unicode_map{$key}}; 12722 } 12723 else 12724 { 12725 $cross_transliterate_texi_map{$key} = '_' . lc($Texi2HTML::Config::unicode_map{$key}); 12726 } 12727 } 12728 } 12729} 12730#if ($Texi2HTML::Config::USE_UNICODE and $Texi2HTML::Config::TRANSLITERATE_NODE 12731if ($Texi2HTML::Config::TRANSLITERATE_NODE and ( 12732 ($Texi2HTML::Config::USE_UNICODE and ! $Texi2HTML::Config::USE_UNIDECODE) 12733 or !$Texi2HTML::Config::USE_UNICODE)) 12734{ 12735 foreach my $key (keys (%Texi2HTML::Config::transliterate_accent_map)) 12736 { 12737 $Texi2HTML::Config::transliterate_map{$key} = $Texi2HTML::Config::transliterate_accent_map{$key}; 12738 } 12739} 12740 12741foreach my $key (keys(%cross_ref_style_map_texi)) 12742{ 12743 if ($style_type{$key} eq 'accent' 12744 and (ref($cross_ref_style_map_texi{$key}) eq 'HASH')) 12745 { 12746 if ($Texi2HTML::Config::USE_UNICODE) 12747 { 12748 $cross_ref_style_map_texi{$key}->{'function'} = \&Texi2HTML::Config::t2h_utf8_accent; 12749 } 12750 else 12751 { 12752 $cross_ref_style_map_texi{$key}->{'function'} = \&Texi2HTML::Config::t2h_nounicode_cross_manual_accent; 12753 } 12754 # this is only used if TRANSLITERATE_NODE is set and USE_UNICODE 12755 # or USE_UNIDECODE is not set 12756 $cross_transliterate_style_map_texi{$key}->{'function'} = \&Texi2HTML::Config::t2h_transliterate_cross_manual_accent; 12757 } 12758} 12759 12760if ($Texi2HTML::Config::L2H) 12761{ 12762 push @Texi2HTML::Config::command_handler_init, \&Texi2HTML::LaTeX2HTML::init; 12763 push @Texi2HTML::Config::command_handler_process, \&Texi2HTML::LaTeX2HTML::latex2html; 12764 push @Texi2HTML::Config::command_handler_finish, \&Texi2HTML::LaTeX2HTML::finish; 12765 $Texi2HTML::Config::command_handler{'math'} = 12766 { 'init' => \&Texi2HTML::LaTeX2HTML::to_latex, 12767 'expand' => \&Texi2HTML::LaTeX2HTML::do_tex 12768 }; 12769 $Texi2HTML::Config::command_handler{'tex'} = 12770 { 'init' => \&Texi2HTML::LaTeX2HTML::to_latex, 12771 'expand' => \&Texi2HTML::LaTeX2HTML::do_tex 12772 }; 12773} 12774 12775if (defined($Texi2HTML::Config::DO_CONTENTS)) 12776{ 12777 $Texi2HTML::GLOBAL{'DO_CONTENTS'} = $Texi2HTML::Config::DO_CONTENTS; 12778} 12779if (defined($Texi2HTML::Config::DO_SCONTENTS)) 12780{ 12781 $Texi2HTML::GLOBAL{'DO_SCONTENTS'} = $Texi2HTML::Config::DO_SCONTENTS; 12782} 12783 12784# FIXME encoding for first file or all files? 12785if (defined($Texi2HTML::Config::IN_ENCODING)) 12786{ 12787 $Texi2HTML::GLOBAL{'IN_ENCODING'} = $Texi2HTML::Config::IN_ENCODING; 12788} 12789 12790if (defined($Texi2HTML::Config::DOCUMENT_ENCODING)) 12791{ 12792 $Texi2HTML::GLOBAL{'DOCUMENT_ENCODING'} = $Texi2HTML::Config::DOCUMENT_ENCODING; 12793} 12794 12795# Backward compatibility for deprecated $Texi2HTML::Config::ENCODING 12796$Texi2HTML::Config::ENCODING_NAME = $Texi2HTML::Config::ENCODING 12797 if (!defined($Texi2HTML::Config::ENCODING_NAME) and defined($Texi2HTML::Config::ENCODING)); 12798 12799# APA: There's got to be a better way: 12800if ($Texi2HTML::Config::TEST) 12801{ 12802 # to generate files similar to reference ones to be able to check for 12803 # real changes we use these dummy values if -test is given 12804 $T2H_USER = 'a tester'; 12805 $THISPROG = 'texi2html'; 12806 setlocale( LC_ALL, "C" ); 12807} 12808else 12809{ 12810 # the eval prevents this from breaking on system which do not have 12811 # a proper getpwuid implemented 12812 eval { ($T2H_USER = (getpwuid ($<))[6]) =~ s/,.*//;}; # Who am i 12813 # APA: Provide Windows NT workaround until getpwuid gets 12814 # implemented there. 12815 $T2H_USER = $ENV{'USERNAME'} unless (defined($T2H_USER)); 12816} 12817$T2H_USER = &$I('unknown') unless (defined($T2H_USER)); 12818 12819 12820$Texi2HTML::GLOBAL{'debug_l2h'} = 1 if ($T2H_DEBUG & $DEBUG_L2H); 12821 12822# 12823# can I use ISO8859 characters? (HTML+) 12824# 12825if ($Texi2HTML::Config::USE_ISO) 12826{ 12827 foreach my $thing (keys(%Texi2HTML::Config::iso_symbols)) 12828 { 12829 next unless exists ($::things_map_ref->{$thing}); 12830 $::things_map_ref->{$thing} = $Texi2HTML::Config::iso_symbols{$thing}; 12831 $::pre_map_ref->{$thing} = $Texi2HTML::Config::iso_symbols{$thing}; 12832 $Texi2HTML::Config::simple_format_texi_map{$thing} = $Texi2HTML::Config::iso_symbols{$thing}; 12833 } 12834 # we don't override the user defined quote, but beware that this works 12835 # only if the hardcoded defaults, '`' and "'" match with the defaults 12836 # in the default init file 12837 $Texi2HTML::Config::OPEN_QUOTE_SYMBOL = $Texi2HTML::Config::iso_symbols{'`'} 12838 if (exists($Texi2HTML::Config::iso_symbols{'`'}) and ($Texi2HTML::Config::OPEN_QUOTE_SYMBOL eq '`')); 12839 $Texi2HTML::Config::CLOSE_QUOTE_SYMBOL = $Texi2HTML::Config::iso_symbols{"'"} 12840 if (exists($Texi2HTML::Config::iso_symbols{"'"}) and ($Texi2HTML::Config::CLOSE_QUOTE_SYMBOL eq "'")); 12841} 12842 12843# parse texinfo cnf file for external manual specifications. This was 12844# discussed on texinfo list but not in makeinfo for now. 12845my @texinfo_htmlxref_files = locate_init_file ($texinfo_htmlxref, 1, \@texinfo_config_dirs); 12846foreach my $file (@texinfo_htmlxref_files) 12847{ 12848 print STDERR "html refs config file: $file\n" if ($T2H_DEBUG); 12849 unless (open (HTMLXREF, $file)) 12850 { 12851 warn "Cannot open html refs config file ${file}: $!"; 12852 next; 12853 } 12854 while (my $hline = <HTMLXREF>) 12855 { 12856 my $line = $hline; 12857 $hline =~ s/[#]\s.*//; 12858 $hline =~ s/^\s*//; 12859 next if $hline =~ /^\s*$/; 12860 my @htmlxref = split /\s+/, $hline; 12861 my $manual = shift @htmlxref; 12862 my $split_or_mono = shift @htmlxref; 12863 if (!defined($split_or_mono) or ($split_or_mono ne 'split' and $split_or_mono ne 'mono')) 12864 { 12865 echo_warn("Bad line in $file: $line"); 12866 next; 12867 } 12868 my $href = shift @htmlxref; 12869 next if (exists($Texi2HTML::GLOBAL{'htmlxref'}->{$manual}->{$split_or_mono}) and exists($Texi2HTML::GLOBAL{'htmlxref'}->{$manual}->{$split_or_mono}->{'href'})); 12870 12871 if (defined($href)) 12872 { 12873 $href =~ s/\/*$// if ($split_or_mono eq 'split'); 12874 $Texi2HTML::GLOBAL{'htmlxref'}->{$manual}->{$split_or_mono}->{'href'} = $href; 12875 } 12876 else 12877 { 12878 $Texi2HTML::GLOBAL{'htmlxref'}->{$manual}->{$split_or_mono} = {}; 12879 } 12880 } 12881 close (HTMLXREF); 12882} 12883 12884if ($T2H_DEBUG) 12885{ 12886 foreach my $manual (keys(%{$Texi2HTML::GLOBAL{'htmlxref'}})) 12887 { 12888 foreach my $split ('split', 'mono') 12889 { 12890 my $href = 'NO'; 12891 next unless (exists($Texi2HTML::GLOBAL{'htmlxref'}->{$manual}->{$split})); 12892 $href = $Texi2HTML::GLOBAL{'htmlxref'}->{$manual}->{$split}->{'href'} if 12893 exists($Texi2HTML::GLOBAL{'htmlxref'}->{$manual}->{$split}->{'href'}); 12894 print STDERR "$manual: $split, href: $href\n"; 12895 } 12896 } 12897} 12898 12899# resulting files splitting 12900if ($Texi2HTML::Config::SPLIT =~ /section/i) 12901{ 12902 $Texi2HTML::Config::SPLIT = 'section'; 12903} 12904elsif ($Texi2HTML::Config::SPLIT =~ /node/i) 12905{ 12906 $Texi2HTML::Config::SPLIT = 'node'; 12907} 12908elsif ($Texi2HTML::Config::SPLIT =~ /chapter/i) 12909{ 12910 $Texi2HTML::Config::SPLIT = 'chapter'; 12911} 12912else 12913{ 12914 $Texi2HTML::Config::SPLIT = ''; 12915} 12916 12917$Texi2HTML::Config::SPLIT_INDEX = 0 unless $Texi2HTML::Config::SPLIT; 12918 12919# Something like backward compatibility 12920if ($Texi2HTML::Config::SPLIT and defined($Texi2HTML::Config::SUBDIR) 12921 and ($Texi2HTML::Config::SUBDIR ne '') and 12922 (!defined($Texi2HTML::Config::OUT) or ($Texi2HTML::Config::OUT eq ''))) 12923{ 12924 $Texi2HTML::Config::OUT = $Texi2HTML::Config::SUBDIR; 12925} 12926 12927die "output to STDOUT and split or frames incompatible\n" 12928 if (($Texi2HTML::Config::SPLIT or $Texi2HTML::Config::FRAMES) and ($Texi2HTML::Config::OUT eq '-')); 12929 12930if ($Texi2HTML::Config::SPLIT and ($Texi2HTML::Config::OUT eq '.')) 12931{# This is to avoid trouble with latex2html 12932 $Texi2HTML::Config::OUT = ''; 12933} 12934 12935my @include_dirs_orig = @Texi2HTML::Config::INCLUDE_DIRS; 12936 12937# extension 12938$Texi2HTML::GLOBAL{'extension'} = $Texi2HTML::Config::EXTENSION; 12939if ($Texi2HTML::Config::SHORTEXTN) 12940{ 12941 $Texi2HTML::GLOBAL{'extension'} = "htm"; 12942} 12943 12944# 12945# file name business 12946# 12947 12948my $docu_dir; # directory of the document 12949my $docu_name; # basename of the document 12950my $docu_rdir; # directory for the output 12951my $docu_toc; # document's table of contents 12952my $docu_stoc; # document's short toc 12953my $docu_foot; # document's footnotes 12954my $docu_about; # about this document 12955my $docu_top; # document top 12956my $docu_doc; # document (or document top of split) 12957my $docu_frame; # main frame file 12958my $docu_toc_frame; # toc frame file 12959my $path_to_working_dir; # relative path leading to the working 12960 # directory from the document directory 12961my $docu_doc_file; 12962my $docu_toc_file; 12963my $docu_stoc_file; 12964my $docu_foot_file; 12965my $docu_about_file; 12966my $docu_top_file; 12967my $docu_frame_file; 12968my $docu_toc_frame_file; 12969 12970sub set_docu_names($$) 12971{ 12972 my $docu_base_name = shift; 12973 my $file_nr = shift; 12974 if ($docu_base_name =~ /(.*\/)/) 12975 { 12976 $docu_dir = $1; 12977 chop($docu_dir); 12978 $docu_name = $docu_base_name; 12979 $docu_name =~ s/.*\///; 12980 } 12981 else 12982 { 12983 $docu_dir = '.'; 12984 $docu_name = $docu_base_name; 12985 } 12986 12987 @Texi2HTML::Config::INCLUDE_DIRS = @include_dirs_orig; 12988 unshift(@Texi2HTML::Config::INCLUDE_DIRS, $docu_dir); 12989 unshift(@Texi2HTML::Config::INCLUDE_DIRS, @Texi2HTML::Config::PREPEND_DIRS); 12990# AAAA 12991 $docu_name = $Texi2HTML::Config::PREFIX if ($Texi2HTML::Config::PREFIX 12992 and ($file_nr == 0)); 12993 12994# subdir 12995 $docu_rdir = ''; 12996 12997 if ($Texi2HTML::Config::SPLIT) 12998 { 12999 if (defined($Texi2HTML::Config::OUT) and ($file_nr == 0)) 13000 { 13001 $docu_rdir = $Texi2HTML::Config::OUT; 13002 } 13003 else 13004 { 13005 $docu_rdir = $docu_name; 13006 } 13007 if ($docu_rdir ne '') 13008 { 13009 $docu_rdir =~ s|/*$||; 13010 $docu_rdir .= '/'; 13011 } 13012 } 13013 else 13014 { 13015 my $out_file; 13016# AAAA 13017 # even if the out file is not set by OUT, in case it is not the first 13018 # file, the out directory is still used 13019 if (defined($Texi2HTML::Config::OUT) and $Texi2HTML::Config::OUT ne '') 13020 { 13021 $out_file = $Texi2HTML::Config::OUT; 13022 } 13023 else 13024 { 13025 $out_file = $docu_name; 13026 } 13027 13028 if ($out_file =~ m|(.*)/|) 13029 {# there is a leading directories 13030 $docu_rdir = "$1/"; 13031 } 13032 } 13033 13034 if ($docu_rdir ne '') 13035 { 13036 unless (-d $docu_rdir) 13037 { 13038 if ( mkdir($docu_rdir, oct(755))) 13039 { 13040 print STDERR "# created directory $docu_rdir\n" if ($T2H_VERBOSE); 13041 } 13042 else 13043 { 13044 die "$ERROR can't create directory $docu_rdir\n"; 13045 } 13046 } 13047 print STDERR "# putting result files into directory $docu_rdir\n" if ($T2H_VERBOSE); 13048 } 13049 else 13050 { 13051 print STDERR "# putting result files into current directory \n" if ($T2H_VERBOSE); 13052 } 13053 # We don't use "./" as $docu_rdir when $docu_rdir is the current directory 13054 # because it is problematic for latex2html. To test writability with -w, 13055 # however we need a real directory. 13056 my $result_rdir = $docu_rdir; 13057 $result_rdir = "." if ($docu_rdir eq ''); 13058 unless (-w $result_rdir) 13059 { 13060 $docu_rdir = 'current directory' if ($docu_rdir eq ''); 13061 die "$ERROR $docu_rdir not writable\n"; 13062 } 13063 13064 # relative path leading to the working directory from the document directory 13065 $path_to_working_dir = $docu_rdir; 13066 if ($docu_rdir ne '') 13067 { 13068 my $cwd = cwd; 13069 my $docu_path = $docu_rdir; 13070 $docu_path = $cwd . '/' . $docu_path unless ($docu_path =~ /^\//); 13071 my @result = (); 13072 # this code simplify the paths. The cwd is absolute, while in the 13073 # document path there may be some .., a .. is removed with the 13074 # previous path element, such that something like 13075 # /cwd/directory/../somewhere/ 13076 # leads to 13077 # /cwd/somewhere/ 13078 # with directory/.. removed 13079 foreach my $element (split /\//, File::Spec->canonpath($docu_path)) 13080 { 13081 if ($element eq '') 13082 { 13083 push @result, ''; 13084 } 13085 elsif ($element eq '..') 13086 { 13087 if (@result and ($result[-1] eq '')) 13088 { 13089 print STDERR "Too much .. in absolute file name\n"; 13090 } 13091 elsif (@result and ($result[-1] ne '..')) 13092 { 13093 pop @result; 13094 } 13095 else 13096 { 13097 push @result, $element; 13098 } 13099 } 13100 else 13101 { 13102 push @result, $element; 13103 } 13104 } 13105 $path_to_working_dir = File::Spec->abs2rel($cwd, join ('/', @result)); 13106 # this should not be needed given what canonpath does 13107 $path_to_working_dir =~ s:/*$::; 13108 $path_to_working_dir .= '/' unless($path_to_working_dir eq ''); 13109 } 13110 13111 my $docu_ext = $Texi2HTML::THISDOC{'extension'}; 13112 # out_dir is undocummented, should never be used, use destination_directory 13113 $Texi2HTML::THISDOC{'out_dir'} = $docu_rdir; 13114 13115 $Texi2HTML::THISDOC{'destination_directory'} = $docu_rdir; 13116 $Texi2HTML::THISDOC{'file_base_name'} = $docu_name; 13117 13118 $docu_doc = $docu_name . (defined($docu_ext) ? ".$docu_ext" : ""); # document's contents 13119 if ($Texi2HTML::Config::SPLIT) 13120 { 13121# AAAA 13122 if (defined($Texi2HTML::Config::TOP_FILE) and ($Texi2HTML::Config::TOP_FILE ne '') and ($file_nr == 0)) 13123 { 13124 $docu_top = $Texi2HTML::Config::TOP_FILE; 13125 } 13126 else 13127 { 13128 $docu_top = $docu_doc; 13129 } 13130 } 13131 else 13132 { 13133# AAAA 13134 if (defined($Texi2HTML::Config::OUT) and ($file_nr == 0)) 13135 { 13136 my $out_file = $Texi2HTML::Config::OUT; 13137 $out_file =~ s|.*/||; 13138 $docu_doc = $out_file if ($out_file !~ /^\s*$/); 13139 } 13140 if (defined $Texi2HTML::Config::element_file_name) 13141 { 13142 my $docu_doc_set = &$Texi2HTML::Config::element_file_name 13143 (undef, "doc", $docu_name); 13144 $docu_doc = $docu_doc_set if (defined($docu_doc_set)); 13145 } 13146 $docu_top = $docu_doc; 13147 } 13148 13149 if ($Texi2HTML::Config::SPLIT or !$Texi2HTML::Config::MONOLITHIC) 13150 { 13151 if (defined $Texi2HTML::Config::element_file_name) 13152 { 13153 $docu_toc = &$Texi2HTML::Config::element_file_name 13154 (undef, "toc", $docu_name); 13155 $docu_stoc = &$Texi2HTML::Config::element_file_name 13156 (undef, "stoc", $docu_name); 13157 $docu_foot = &$Texi2HTML::Config::element_file_name 13158 (undef, "foot", $docu_name); 13159 $docu_about = &$Texi2HTML::Config::element_file_name 13160 (undef, "about", $docu_name); 13161 # $docu_top may be overwritten later. 13162 } 13163 if (!defined($docu_toc)) 13164 { 13165 my $default_toc = "${docu_name}_toc"; 13166 $default_toc .= ".$docu_ext" if (defined($docu_ext)); 13167# AAAA 13168 if (defined($Texi2HTML::Config::TOC_FILE) and ($Texi2HTML::Config::TOC_FILE ne '') and ($file_nr == 0)) 13169 { 13170 $docu_toc = $Texi2HTML::Config::TOC_FILE; 13171 } 13172 else 13173 { 13174 $docu_toc = $default_toc; 13175 } 13176 } 13177 if (!defined($docu_stoc)) 13178 { 13179 $docu_stoc = "${docu_name}_ovr"; 13180 $docu_stoc .= ".$docu_ext" if (defined($docu_ext)); 13181 } 13182 if (!defined($docu_foot)) 13183 { 13184 $docu_foot = "${docu_name}_fot"; 13185 $docu_foot .= ".$docu_ext" if (defined($docu_ext)); 13186 } 13187 if (!defined($docu_about)) 13188 { 13189 $docu_about = "${docu_name}_abt"; 13190 $docu_about .= ".$docu_ext" if (defined($docu_ext)); 13191 } 13192 } 13193 else 13194 { 13195 $docu_toc = $docu_foot = $docu_stoc = $docu_about = $docu_doc; 13196 } 13197 13198 # Note that file extension has already been added here. 13199 if ($Texi2HTML::Config::FRAMES) 13200 { 13201 if (defined $Texi2HTML::Config::element_file_name) 13202 { 13203 $docu_frame = &$Texi2HTML::Config::element_file_name 13204 (undef, "frame", $docu_name); 13205 $docu_toc_frame = &$Texi2HTML::Config::element_file_name 13206 (undef, "toc_frame", $docu_name); 13207 } 13208 } 13209 13210 if (!defined($docu_frame)) 13211 { 13212 $docu_frame = "${docu_name}_frame"; 13213 $docu_frame .= ".$docu_ext" if (defined($docu_ext)); 13214 } 13215 if (!defined($docu_toc_frame)) 13216 { 13217 $docu_toc_frame = "${docu_name}_toc_frame"; 13218 $docu_toc_frame .= ".$docu_ext" if (defined($docu_ext)); 13219 } 13220 13221 if ($T2H_VERBOSE) 13222 { 13223 print STDERR "# Files and directories:\n"; 13224 print STDERR "# rdir($docu_rdir) path_to_working_dir($path_to_working_dir)\n"; 13225 print STDERR "# doc($docu_doc) top($docu_top) toc($docu_toc) stoc($docu_stoc)\n"; 13226 print STDERR "# foot($docu_foot) about($docu_about) frame($docu_toc) toc_frame($docu_toc_frame)\n"; 13227 } 13228 13229 $docu_doc_file = "$docu_rdir$docu_doc"; 13230 $docu_toc_file = "$docu_rdir$docu_toc"; 13231 $docu_stoc_file = "$docu_rdir$docu_stoc"; 13232 $docu_foot_file = "$docu_rdir$docu_foot"; 13233 $docu_about_file = "$docu_rdir$docu_about"; 13234 $docu_top_file = "$docu_rdir$docu_top"; 13235 $docu_frame_file = "$docu_rdir$docu_frame"; 13236 $docu_toc_frame_file = "$docu_rdir$docu_toc_frame"; 13237 13238# For use in init files 13239 $Texi2HTML::THISDOC{'filename'}->{'top'} = $docu_top; 13240 $Texi2HTML::THISDOC{'filename'}->{'foot'} = $docu_foot; 13241 $Texi2HTML::THISDOC{'filename'}->{'stoc'} = $docu_stoc; 13242 $Texi2HTML::THISDOC{'filename'}->{'about'} = $docu_about; 13243 $Texi2HTML::THISDOC{'filename'}->{'toc'} = $docu_toc; 13244# FIXME document that 13245 $Texi2HTML::THISDOC{'filename'}->{'toc_frame'} = $docu_toc_frame; 13246 $Texi2HTML::THISDOC{'filename'}->{'frame'} = $docu_frame; 13247} 13248 13249# 13250# Common initializations 13251# 13252 13253sub texinfo_initialization($) 13254{ 13255 my $pass = shift; 13256 13257 # All the initialization used the last @documentlanguage found during 13258 # pass_structure. Now we reset it, if it is not set on the command line 13259 # such that the @documentlanguage macros are used when they arrive 13260 13261 # FIXME ask on bug-texinfo 13262 if (!$Texi2HTML::GLOBAL{'current_lang'}) 13263 { 13264 set_document_language($Texi2HTML::Config::LANG) if defined($Texi2HTML::Config::LANG); 13265 # $LANG isn't known 13266 set_document_language('en') unless ($Texi2HTML::THISDOC{'current_lang'}); 13267 } 13268 # reset the @set/@clear values 13269 %value = %value_initial; 13270# set_special_names(); 13271 foreach my $init_mac ('everyheading', 'everyfooting', 'evenheading', 13272 'evenfooting', 'oddheading', 'oddfooting', 'headings', 13273 'allowcodebreaks', 'frenchspacing', 'exampleindent', 13274 'firstparagraphindent', 'paragraphindent', 'clickstyle') 13275 { 13276 $Texi2HTML::THISDOC{$init_mac} = undef; 13277 delete $Texi2HTML::THISDOC{$init_mac}; 13278 } 13279} 13280 13281#+++########################################################################### 13282# # 13283# Pass texi: read source, handle variable, ignored text, # 13284# # 13285#---########################################################################### 13286 13287my @fhs = (); # hold the file handles to read 13288#my @lines = (); # whole document 13289#my @lines_numbers = (); # line number, originating file associated with 13290 # whole document 13291my $macros = undef; # macros. reference on a hash 13292my %info_enclose = (); # macros defined with definfoenclose 13293my @floats = (); # floats list 13294my %floats = (); # floats by style 13295 13296sub initialise_state_texi($) 13297{ 13298 my $state = shift; 13299 $state->{'texi'} = 1; # for substitute_text and close_stack: 13300 # 1 if pass_texi/scan_texi is to be used 13301 $state->{'macro_inside'} = 0 unless(defined($state->{'macro_inside'})); 13302 $state->{'ifvalue_inside'} = 0 unless(defined($state->{'ifvalue_inside'})); 13303 $state->{'arg_expansion'} = 0 unless(defined($state->{'arg_expansion'})); 13304} 13305 13306 13307sub pass_texi($) 13308{ 13309 my $input_file_name = shift; 13310 #my $texi_line_number = { 'file_name' => '', 'line_nr' => 0, 'macro' => '' }; 13311 13312 my @lines = (); # whole document 13313 my @lines_numbers = (); # line number, originating file associated with 13314 # whole document 13315 my @first_lines = (); 13316 my $first_lines = 1; # is it the first lines 13317 my $state = {}; 13318 # holds the informations about the context 13319 # to pass it down to the functions 13320 initialise_state_texi($state); 13321 my $texi_line_number; 13322 ($texi_line_number, $state->{'input_spool'}) = 13323 open_file($input_file_name, ''); 13324 my @stack; 13325 my $text; 13326 my $cline; 13327 INPUT_LINE: while (1) 13328 { 13329 ($cline, $state->{'input_spool'}) = next_line($texi_line_number); 13330 last if (!defined($cline)); 13331 # 13332 # remove the lines preceding \input or an @-command 13333 # 13334 if ($first_lines) 13335 { 13336 if ($cline =~ /^\\input/) 13337 { 13338 push @first_lines, $cline; 13339 $first_lines = 0; 13340 next; 13341 } 13342 if ($cline =~ /^\s*\@/) 13343 { 13344 $first_lines = 0; 13345 } 13346 else 13347 { 13348 push @first_lines, $cline; 13349 next; 13350 } 13351 } 13352 #print STDERR "PASS_TEXI($texi_line_number->{'line_nr'})$cline"; 13353 my $chomped_line = $cline; 13354 if (scan_texi ($cline, \$text, \@stack, $state, $texi_line_number) and chomp($chomped_line)) 13355 { 13356 #print STDERR "==> new page (line_nr $texi_line_number->{'line_nr'},$texi_line_number->{'file_name'},$texi_line_number->{'macro'})\n"; 13357 push (@lines_numbers, { 'file_name' => $texi_line_number->{'file_name'}, 13358 'line_nr' => $texi_line_number->{'line_nr'}, 13359 'macro' => $texi_line_number->{'macro'} }); 13360 } 13361 #dump_stack (\$text, \@stack, $state); 13362 if ($state->{'bye'}) 13363 { 13364 #dump_stack(\$text, \@stack, $state); 13365 # close stack after bye 13366 #print STDERR "close stack after bye\n"; 13367 close_stack_texi_structure(\$text, \@stack, $state, $texi_line_number); 13368 #dump_stack(\$text, \@stack, $state); 13369 } 13370 next if (@stack); 13371 $cline = $text; 13372 $text = ''; 13373 if (!defined($cline)) 13374 {# FIXME: remove the error message if it is reported too often 13375 print STDERR "# \$cline undefined after scan_texi. This may be a bug, or not.\n"; 13376 print STDERR "# Report (with texinfo file) if you want, otherwise ignore that message.\n"; 13377 next unless ($state->{'bye'}); 13378 } 13379 push @lines, split_lines($cline); 13380 last if ($state->{'bye'}); 13381 } 13382 # close stack at the end of pass texi 13383 #print STDERR "close stack at the end of pass texi\n"; 13384 close_stack_texi_structure(\$text, \@stack, $state, $texi_line_number); 13385 push @lines, split_lines($text); 13386 print STDERR "# end of pass texi\n" if $T2H_VERBOSE; 13387 return (\@lines, \@first_lines, \@lines_numbers); 13388} 13389 13390#+++########################################################################### 13391# # 13392# Pass structure: parse document structure # 13393# # 13394#---########################################################################### 13395 13396sub initialise_state_structure($) 13397{ 13398 my $state = shift; 13399 $state->{'structure'} = 1; # for substitute_text and close_stack: 13400 # 1 if pass_structure/scan_structure is 13401 # to be used 13402 $state->{'menu'} = 0; # number of opened menus 13403 $state->{'detailmenu'} = 0; # number of opened detailed menus 13404 $state->{'sectionning_base'} = 0; # current base sectionning level 13405 $state->{'table_stack'} = [ "no table" ]; # a stack of opened tables/lists 13406 # seems to be only debug 13407 if (exists($state->{'region_lines'}) and !defined($state->{'region_lines'})) 13408 { 13409 delete ($state->{'region_lines'}); 13410 print STDERR "Bug: state->{'region_lines'} exists but undef.\n"; 13411 } 13412} 13413# This is a virtual element for things appearing before @node and 13414# sectionning commands 13415my $element_before_anything; 13416 13417# 13418# initial counters. Global variables for pass_structure. 13419# 13420my $document_idx_num; 13421my $document_sec_num; 13422my $document_head_num; 13423my $document_anchor_num; 13424 13425# section to level hash not taking into account raise and lower sections 13426my %sec2level; 13427# initial state for the special regions. 13428my %region_initial_state; 13429my %region_lines; 13430 13431# This is a place for index entries, anchors and so on appearing in 13432# copying or documentdescription 13433my $no_element_associated_place; 13434 13435 13436my @nodes_list; # nodes in document reading order 13437 # each member is a reference on a hash 13438my @sections_list; # sections in reading order 13439 # each member is a reference on a hash 13440my @all_elements; # sectionning elements (nodes and sections) 13441 # in reading order. Each member is a reference 13442 # on a hash which also appears in %nodes, 13443 # @sections_list @nodes_list, @elements_list 13444my @elements_list; # all the resulting elements in document order 13445my %sections; # sections hash. The key is the section number 13446my %headings; # headings hash. The key is the heading number 13447my $section_top; # @top section 13448my $element_top; # Top element 13449my $node_top; # Top node 13450my $node_first; # First node 13451my $element_index; # element with first index 13452my $element_chapter_index; # chapter with first index 13453my $element_first; # first element 13454my $element_last; # last element 13455my %special_commands; # hash for the commands specially handled 13456 # by the user 13457 13458# element for content and shortcontent if on a separate page 13459my %content_element; 13460 13461# common code for headings and sections 13462sub new_section_heading($$$) 13463{ 13464 my $command = shift; 13465 my $name = shift; 13466 my $state = shift; 13467 $name = normalise_space($name); 13468 $name = '' if (!defined($name)); 13469 # no increase if in @copying and the like. Also no increase if it is top 13470 # since top has number 0. 13471 my $docid; 13472 my $num; 13473 13474 my $section_ref = { 'texi' => $name, 13475 'level' => $sec2level{$command}, 13476 'tag' => $command, 13477 }; 13478 return $section_ref; 13479} 13480 13481sub scan_node_line($) 13482{ 13483 my $node_line = shift; 13484 $node_line =~ s/^\@node\s+//; 13485 $node_line =~ s/\s*$//; 13486 13487 my @command_stack; 13488 my @results; 13489 my $node_arg = ''; 13490 while (1) 13491 { 13492 if ($node_line =~ s/^([^{},@]*)\@(["'~\@\}\{,\.!\?\s\*\-\^`=:\|\/\\])//o or $node_line =~ s/^([^{}@,]*)\@([a-zA-Z][\w-]*)([\s\{\}\@])/$3/o or $node_line =~ s/^([^{},@]*)\@([a-zA-Z][\w-]*)$//o) 13493 { 13494 $node_arg .= $1; 13495 my $macro = $2; 13496 $node_arg .= "\@$macro"; 13497 $macro = $alias{$macro} if (exists($alias{$macro})); 13498 if ($node_line =~ s/^{//) 13499 { 13500 push @command_stack, $macro; 13501 $node_arg .= '{'; 13502 } 13503 13504 } 13505 elsif ($node_line =~ s/^([^{},]*)([{}])//o) 13506 { 13507 $node_arg .= $1 . $2; 13508 my $brace = $2; 13509 if (@command_stack) 13510 { 13511 pop @command_stack; 13512 } 13513 } 13514 elsif ($node_line =~ s/^([^,]*)[,]//o) 13515 { 13516 $node_arg .= $1; 13517 if (@command_stack) 13518 { 13519 $node_arg .= ','; 13520 } 13521 else 13522 { 13523 push @results, normalise_node($node_arg); 13524 $node_arg = ''; 13525 } 13526 } 13527 else 13528 { 13529 $node_arg .= $node_line; 13530 push @results, normalise_node($node_arg); 13531 return @results; 13532 } 13533 } 13534} 13535 13536sub pass_structure($$) 13537{ 13538 my $texi_lines = shift; 13539 my $lines_numbers = shift; 13540 13541 my @doc_lines; # whole document 13542 my @doc_numbers; # whole document line numbers and file names 13543 13544 my $state = {}; 13545 # holds the informations about the context 13546 # to pass it down to the functions 13547 initialise_state_structure($state); 13548 $state->{'element'} = $element_before_anything; 13549 $state->{'place'} = $element_before_anything->{'place'}; 13550 my @stack; 13551 my $text; 13552 my $line_nr; 13553 13554 while (@$texi_lines or $state->{'in_deff_line'}) 13555 { 13556 my $cline = shift @$texi_lines; 13557 my $chomped_line = $cline; 13558 if (@$texi_lines and !chomp($chomped_line)) 13559 { 13560 $texi_lines->[0] = $cline . $texi_lines->[0]; 13561 next; 13562 } 13563 if ($state->{'in_deff_line'}) 13564 { # line stored in $state->{'in_deff_line'} was protected by @ 13565 # and can be concatenated with the next line 13566 if (defined($cline)) 13567 { 13568 $cline = $state->{'in_deff_line'} . $cline; 13569 } 13570 else 13571 {# end of line protected at the very end of the file 13572 $cline = $state->{'in_deff_line'}; 13573 } 13574 delete $state->{'in_deff_line'}; 13575 } 13576 $line_nr = shift (@$lines_numbers); 13577 #print STDERR "PASS_STRUCTURE: $cline"; 13578 if (!$state->{'raw'} and !$state->{'verb'}) 13579 { 13580 my $tag = ''; 13581 if ($cline =~ /^\s*\@(\w+)\b/) 13582 { 13583 $tag = $1; 13584 } 13585 13586 # 13587 # analyze the tag 13588 # 13589 if ($tag and $tag eq 'node' or (defined($sec2level{$tag}) and ($tag !~ /heading/)) or $tag eq 'printindex' or ($tag eq 'insertcopying' and $Texi2HTML::Config::INLINE_INSERTCOPYING)) 13590 { 13591 my @added_lines = ($cline); 13592 my @added_numbers = ($line_nr); 13593 if ($tag eq 'node' or defined($sec2level{$tag})) 13594 {# in pass structure node shouldn't appear in formats 13595 close_stack_texi_structure(\$text, \@stack, $state, $line_nr); 13596 if (exists($state->{'region_lines'})) 13597 { 13598 push @{$region_lines{$state->{'region_lines'}->{'format'}}}, split_lines($text); 13599 push @doc_lines, split_lines($text) if ($Texi2HTML::Config::region_formats_kept{$state->{'region_lines'}->{'format'}}); 13600 $state->{'region_lines'}->{'number'} = 0; 13601 close_region($state); 13602 } 13603 else 13604 { 13605 push @doc_lines, split_lines($text); 13606 } 13607 $text = ''; 13608 } 13609 if ($tag eq 'node') 13610 { 13611 my $node_ref; 13612 my $auto_directions; 13613 my @node_res = scan_node_line($cline); 13614 $auto_directions = 1 if (scalar(@node_res) == 1); 13615 my ($node, $node_next, $node_prev, $node_up) = @node_res; 13616 if (defined($node) and ($node ne '')) 13617 { 13618 if (exists($nodes{$node}) and defined($nodes{$node}) 13619 and $nodes{$node}->{'seen'}) 13620 { 13621 echo_error ("Duplicate node found: $node", $line_nr); 13622 next; 13623 } 13624 else 13625 { 13626 if (exists($nodes{$node}) and defined($nodes{$node})) 13627 { # node appeared in a menu 13628 $node_ref = $nodes{$node}; 13629 } 13630 else 13631 { 13632 my $first; 13633 $first = 1 if (!defined($node_ref)); 13634 $node_ref = {}; 13635 $node_first = $node_ref if ($first); 13636 $nodes{$node} = $node_ref; 13637 } 13638 $node_ref->{'node'} = 1; 13639 $node_ref->{'tag'} = 'node'; 13640 $node_ref->{'tag_level'} = 'node'; 13641 $node_ref->{'texi'} = $node; 13642 $node_ref->{'seen'} = 1; 13643 $node_ref->{'automatic_directions'} = $auto_directions; 13644 $node_ref->{'place'} = []; 13645 $node_ref->{'current_place'} = []; 13646 merge_element_before_anything($node_ref); 13647 $node_ref->{'index_names'} = []; 13648 $state->{'place'} = $node_ref->{'current_place'}; 13649 $state->{'element'} = $node_ref; 13650 $state->{'node_ref'} = $node_ref; 13651 # makeinfo treats differently case variants of 13652 # top in nodes and anchors and in refs commands and 13653 # refs from nodes. 13654 if ($node =~ /^top$/i) 13655 { 13656 if (!defined($node_top)) 13657 { 13658 $node_top = $node_ref; 13659 $node_top->{'texi'} = 'Top'; 13660 delete $nodes{$node}; 13661 $nodes{$node_top->{'texi'}} = $node_ref; 13662 } 13663 else 13664 { # All the refs are going to point to the first Top 13665 echo_warn ("Top node already exists", $line_nr); 13666 #warn "$WARN Top node already exists\n"; 13667 } 13668 } 13669 unless (@nodes_list) 13670 { 13671 $node_ref->{'first'} = 1; 13672 } 13673 push (@nodes_list, $node_ref); 13674 push @all_elements, $node_ref; 13675 } 13676 } 13677 else 13678 { 13679 echo_error ("Node is undefined: $cline (eg. \@node NODE-NAME, NEXT, PREVIOUS, UP)", $line_nr); 13680 next; 13681 } 13682 13683 if (defined($node_next) and ($node_next ne '')) 13684 { 13685 $node_ref->{'node_next'} = $node_next; 13686 } 13687 if (defined($node_prev) and ($node_prev ne '')) 13688 { 13689 $node_ref->{'node_prev'} = $node_prev; 13690 } 13691 if (defined($node_up) and ($node_up ne '')) 13692 { 13693 $node_ref->{'node_up'} = $node_up; 13694 } 13695 } 13696 elsif (defined($sec2level{$tag})) 13697 { # section 13698 if ($cline =~ /^\@$tag\s*(.*)$/) 13699 { 13700 my $name = $1; 13701 my $section_ref = new_section_heading($tag, $name, $state); 13702 $document_sec_num++ if($tag ne 'top'); 13703 13704 $section_ref->{'sec_num'} = $document_sec_num; 13705 $section_ref->{'id'} = "SEC$document_sec_num"; 13706 $section_ref->{'seen'} = 1; 13707 $section_ref->{'index_names'} = []; 13708 $section_ref->{'current_place'} = []; 13709 $section_ref->{'place'} = []; 13710 $section_ref->{'section'} = 1; 13711 13712 if ($tag eq 'top') 13713 { 13714 $section_ref->{'top'} = 1; 13715 $section_ref->{'number'} = ''; 13716 $section_ref->{'id'} = "SEC_Top"; 13717 $section_ref->{'sec_num'} = 0; 13718 $sections{0} = $section_ref; 13719 $section_top = $section_ref; 13720 } 13721 else 13722 { 13723 $sections{$section_ref->{'sec_num'}} = $section_ref; 13724 } 13725 merge_element_before_anything($section_ref); 13726 if ($state->{'node_ref'}) 13727 { 13728 $section_ref->{'node_ref'} = $state->{'node_ref'}; 13729 push @{$state->{'node_ref'}->{'sections'}}, $section_ref; 13730 } 13731 if ($state->{'node_ref'} and !exists($state->{'node_ref'}->{'with_section'})) 13732 { 13733 my $node_ref = $state->{'node_ref'}; 13734 $section_ref->{'with_node'} = $node_ref; 13735 $section_ref->{'titlefont'} = $node_ref->{'titlefont'}; 13736 $node_ref->{'with_section'} = $section_ref; 13737 $node_ref->{'top'} = 1 if ($tag eq 'top'); 13738 } 13739 if (! $name and $section_ref->{'level'}) 13740 { 13741 echo_warn ("$tag without name", $line_nr); 13742 } 13743 push @sections_list, $section_ref; 13744 push @all_elements, $section_ref; 13745 $state->{'element'} = $section_ref; 13746 $state->{'place'} = $section_ref->{'current_place'}; 13747 ################# debug 13748 my $node_ref = "NO NODE"; 13749 my $node_texi =''; 13750 if ($state->{'node_ref'}) 13751 { 13752 $node_ref = $state->{'node_ref'}; 13753 $node_texi = $state->{'node_ref'}->{'texi'}; 13754 } 13755 print STDERR "# pass_structure node($node_ref)$node_texi, tag \@$tag($section_ref->{'level'}) ref $section_ref, num,id $section_ref->{'sec_num'},$section_ref->{'id'}\n $name\n" 13756 if $T2H_DEBUG & $DEBUG_ELEMENTS; 13757 ################# end debug 13758 } 13759 } 13760 elsif ($cline =~ /^\@printindex\s+(\w+)/) 13761 { 13762 unless (@all_elements) 13763 { 13764 echo_warn ("Printindex before document beginning: \@printindex $1", $line_nr); 13765 next; 13766 } 13767 my $index_name = $1; 13768 # $element_index is the first element with index 13769 $element_index = $all_elements[-1] unless (defined($element_index)); 13770 # associate the index to the element 13771 my $printindex = { 'element' => $all_elements[-1], 'name' => $index_name, 'command' => 'printindex' }; 13772 push @{$state->{'place'}}, $printindex; 13773 push @{$Texi2HTML::THISDOC{'indices'}->{$index_name}}, $printindex; 13774 push @{$Texi2HTML::THISDOC{'printindices'}}, $printindex; 13775 } 13776 elsif ($cline =~ /^\@insertcopying\s*/) 13777 { 13778 @added_lines = @{$region_lines{'copying'}}; 13779 @added_numbers = (); 13780 my $copying_line_nr = 0; 13781 foreach my $line_added (@added_lines) 13782 { 13783 $copying_line_nr++; 13784 push @added_numbers, { 'file_name' => '', 'macro' => 'copying', 'line_nr' => $copying_line_nr }; 13785 } 13786 unshift (@$texi_lines, @added_lines); 13787 unshift (@$lines_numbers, @added_numbers); 13788 next; 13789 } 13790 if (exists($state->{'region_lines'})) 13791 { 13792 push @{$region_lines{$state->{'region_lines'}->{'format'}}}, @added_lines; 13793 if ($Texi2HTML::Config::region_formats_kept{$state->{'region_lines'}->{'format'}}) 13794 { 13795 push @doc_lines, @added_lines; 13796 push @doc_numbers, @added_numbers; 13797 } 13798 } 13799 else 13800 { 13801 push @doc_lines, @added_lines; 13802 push @doc_numbers, @added_numbers; 13803 } 13804 next; 13805 } 13806 } 13807 if (scan_structure ($cline, \$text, \@stack, $state, $line_nr) and (!exists($state->{'region_lines'}) or $Texi2HTML::Config::region_formats_kept{$state->{'region_lines'}->{'format'}})) 13808 { 13809 push (@doc_numbers, $line_nr); 13810 } 13811 next if (scalar(@stack) or $state->{'in_deff_line'}); 13812 $cline = $text; 13813 $text = ''; 13814 next if (!defined($cline)); 13815 if ($state->{'region_lines'}) 13816 { 13817 # the first line is like @copying, it is not put in the region 13818 # lines 13819 push @{$region_lines{$state->{'region_lines'}->{'format'}}}, split_lines($cline) unless ($state->{'region_lines'}->{'first_line'}); 13820 delete $state->{'region_lines'}->{'first_line'}; 13821 push @doc_lines, split_lines($cline) if ($Texi2HTML::Config::region_formats_kept{$state->{'region_lines'}->{'format'}}); 13822 } 13823 else 13824 { 13825 push @doc_lines, split_lines($cline); 13826 } 13827 } 13828 if (@stack) 13829 {# close stack at the end of pass structure 13830 close_stack_texi_structure(\$text, \@stack, $state, $line_nr); 13831 if ($text) 13832 { 13833 if (exists($state->{'region_lines'})) 13834 { 13835 push @{$region_lines{$state->{'region_lines'}->{'format'}}}, 13836 split_lines($text); 13837 push @doc_lines, split_lines($text) if ($Texi2HTML::Config::region_formats_kept{$state->{'region_lines'}->{'format'}}); 13838 } 13839 else 13840 { 13841 push @doc_lines, split_lines($text); 13842 } 13843 } 13844 } 13845 echo_warn ("At end of document, $state->{'region_lines'}->{'number'} $state->{'region_lines'}->{'format'} not closed") if (exists($state->{'region_lines'})); 13846 print STDERR "# end of pass structure\n" if $T2H_VERBOSE; 13847 # To remove once they are handled 13848 #print STDERR "No node nor section, texi2html won't be able to place things rightly\n" if ($element_before_anything->{'place'} and @{$element_before_anything->{'place'}}); 13849 return (\@doc_lines, \@doc_numbers); 13850} 13851 13852# split line at end of line and put each resulting line in an array 13853# FIXME there must be a more perlish way to do it... Not a big deal 13854# as long as it work 13855sub split_lines($) 13856{ 13857 my $line = shift; 13858 my @result = (); 13859 return @result if (!defined($line)); 13860 my $i = 0; 13861 while ($line ne '') 13862 { 13863 $result[$i] = ''; 13864 $line =~ s/^(.*)//; 13865 $result[$i] .= $1; 13866 $result[$i] .= "\n" if ($line =~ s/^\n//); 13867 #print STDERR "$i: $result[$i]"; 13868 $i++; 13869 } 13870 return @result; 13871} 13872 13873# handle @documentlanguage 13874sub do_documentlanguage($$$$) 13875{ 13876 my $macro = shift; 13877 my $line = shift; 13878 my $silent = shift; 13879 my $line_nr = shift; 13880 my $return_value = 0; 13881 if ($line =~ /\s+(\w+)/) 13882 { 13883 my $lang = $1; 13884 if (!$Texi2HTML::GLOBAL{'current_lang'} && $lang) 13885 { 13886 $return_value = set_document_language($lang, 0, $silent, $line_nr); 13887 # warning, this is not the language of the document but the one that 13888 # appear in the texinfo. It could have been different 13889 # if $Texi2HTML::GLOBAL{'current_lang'} was set and not 13890 # taken into account in the if 13891 $Texi2HTML::THISDOC{$macro} = $lang; 13892 } 13893 } 13894 return $return_value; 13895} 13896 13897# actions that should be done in more than one pass. In fact most are not 13898# to be done in pass_texi. The $pass argument is the number of the pass, 13899# 0 for pass_texi, 1 for pass_structure, 2 for pass_text 13900sub common_misc_commands($$$$) 13901{ 13902 my $macro = shift; 13903 my $line = shift; 13904 my $pass = shift; 13905 my $line_nr = shift; 13906 13907 # track variables 13908 if ($macro eq 'set') 13909 { 13910 if ($line =~ /^(\s+)($VARRE)(\s+)(.*)$/) 13911 { 13912 $value{$2} = $4; 13913 } 13914 else 13915 { 13916 echo_warn ("Missing argument for \@$macro", $line_nr) if (!$pass); 13917 } 13918 } 13919 elsif ($macro eq 'clear') 13920 { 13921 if ($line =~ /^(\s+)($VARRE)/) 13922 { 13923 delete $value{$2}; 13924 } 13925 else 13926 { 13927 echo_warn ("Missing argument for \@$macro", $line_nr) if (!$pass); 13928 } 13929 } 13930 elsif ($macro eq 'clickstyle') 13931 { 13932 if ($line =~ /^\s+@([^\s\{\}\@]+)/) 13933 { 13934 $Texi2HTML::THISDOC{$macro} = $1; 13935 } 13936 else 13937 { 13938 echo_error ("\@$macro should only accept a macro as argument", $line_nr) if ($pass == 1); 13939 } 13940 } 13941 if ($pass) 13942 { # these commands are only taken into account here in pass_structure 1 13943 # and pass_text 2 13944 if ($macro eq 'setfilename') 13945 { 13946 my $filename = $line; 13947 $filename =~ s/^\s*//; 13948 $filename =~ s/\s*$//; 13949 if ($filename ne '') 13950 { 13951 $filename = substitute_line($filename, {'code_style' => 1, 'remove_texi' => 1}); 13952 #$filename = substitute_line($filename, {'code_style' => 1}); 13953 $Texi2HTML::THISDOC{$macro} = $filename; 13954 $value{"_$macro"} = $filename if ($pass == 1); 13955 } 13956 } 13957 elsif ($macro eq 'paragraphindent') 13958 { 13959 if ($line =~ /\s+([0-9]+)/) 13960 { 13961 $Texi2HTML::THISDOC{$macro} = $1; 13962 } 13963 elsif (($line =~ /\s+(none)[^\w\-]/) or ($line =~ /\s+(asis)[^\w\-]/)) 13964 { 13965 $Texi2HTML::THISDOC{$macro} = $1; 13966 } 13967 else 13968 { 13969 echo_error ("Bad \@$macro", $line_nr) if ($pass == 1); 13970 } 13971 } 13972 elsif ($macro eq 'firstparagraphindent') 13973 { 13974 if (($line =~ /\s+(none)[^\w\-]/) or ($line =~ /\s+(insert)[^\w\-]/)) 13975 { 13976 $Texi2HTML::THISDOC{$macro} = $1; 13977 } 13978 else 13979 { 13980 echo_error ("Bad \@$macro", $line_nr) if ($pass == 1); 13981 } 13982 } 13983 elsif ($macro eq 'exampleindent') 13984 { 13985 if ($line =~ /^\s+([0-9]+)/) 13986 { 13987 $Texi2HTML::THISDOC{$macro} = $1; 13988 } 13989 elsif ($line =~ /^\s+(asis)[^\w\-]/) 13990 { 13991 $Texi2HTML::THISDOC{$macro} = $1; 13992 } 13993 else 13994 { 13995 echo_error ("Bad \@$macro", $line_nr) if ($pass == 1); 13996 } 13997 } 13998 elsif ($macro eq 'frenchspacing') 13999 { 14000 if (($line =~ /^\s+(on)[^\w\-]/) or ($line =~ /^\s+(off)[^\w\-]/)) 14001 { 14002 $Texi2HTML::THISDOC{$macro} = $1; 14003 } 14004 else 14005 { 14006 echo_error ("Bad \@$macro", $line_nr) if ($pass == 1); 14007 } 14008 } 14009 elsif (grep {$macro eq $_} ('everyheading', 'everyfooting', 14010 'evenheading', 'evenfooting', 'oddheading', 'oddfooting')) 14011 { # FIXME have a _texi and without texi, and without texi, 14012 # and expand rightly @this*? And use @| to separate, and give 14013 # an array for user consumption? This should be done for each new 14014 # chapter, section, and page. What is a page is not necessarily 14015 # well defined in html, however... 14016 # @thisfile is the @include file. Shoule be in $line_nr. 14017 my $arg = $line; 14018 $arg =~ s/^\s+//; 14019 $Texi2HTML::THISDOC{$macro} = $arg; 14020 } 14021 elsif ($macro eq 'allowcodebreaks') 14022 { 14023 if (($line =~ /^\s+(true)[^\w\-]/) or ($line =~ /^\s+(false)[^\w\-]/)) 14024 { 14025 $Texi2HTML::THISDOC{$macro} = $1; 14026 } 14027 else 14028 { 14029 echo_error ("Bad \@$macro", $line_nr) if ($pass == 1); 14030 } 14031 } 14032 elsif ($macro eq 'headings') 14033 { 14034 my $valid_arg = 0; 14035 foreach my $possible_arg (('off','on','single','double', 14036 'singleafter','doubleafter')) 14037 { 14038 if ($line =~ /^\s+($possible_arg)[^\w\-]/) 14039 { 14040 $valid_arg = 1; 14041 $Texi2HTML::THISDOC{$macro} = $possible_arg; 14042 last; 14043 } 14044 } 14045 unless ($valid_arg) 14046 { 14047 echo_error ("Bad \@$macro", $line_nr) if ($pass == 1); 14048 } 14049 } 14050 elsif ($macro eq 'documentlanguage') 14051 { 14052 if (do_documentlanguage($macro, $line, $pass -1, $line_nr)) 14053 { 14054 &$Texi2HTML::Config::translate_names(); 14055 set_special_names(); 14056 } 14057 } 14058 } 14059} 14060 14061sub misc_command_texi($$$$) 14062{ 14063 my $line = shift; 14064 my $macro = shift; 14065 my $state = shift; 14066 my $line_nr = shift; 14067 my $text; 14068 my $args; 14069 14070 if (!$state->{'ignored'} and !$state->{'arg_expansion'}) 14071 { 14072 if ($macro eq 'documentencoding') 14073 { 14074 #my $encoding = ''; 14075 if ($line =~ /(\s+)([0-9\w\-]+)/) 14076 { 14077 my $encoding = $2; 14078 #$Texi2HTML::Config::DOCUMENT_ENCODING = $encoding; 14079 $Texi2HTML::THISDOC{'documentencoding'} = $encoding; 14080 $Texi2HTML::THISDOC{'DOCUMENT_ENCODING'} = $Texi2HTML::THISDOC{'documentencoding'} unless (defined($Texi2HTML::Config::DOCUMENT_ENCODING)); 14081 my $from_encoding; 14082 if (!defined($Texi2HTML::Config::IN_ENCODING)) 14083 { 14084 $from_encoding = encoding_alias($encoding); 14085 $Texi2HTML::THISDOC{'IN_ENCODING'} = $from_encoding 14086 if (defined($from_encoding)); 14087 } 14088 #$Texi2HTML::Config::IN_ENCODING = $from_encoding if 14089 # defined($from_encoding); 14090 if (defined($from_encoding) and $Texi2HTML::Config::USE_UNICODE) 14091 { 14092 foreach my $file (@fhs) 14093 { 14094 binmode($file->{'fh'}, ":encoding($from_encoding)"); 14095 } 14096 } 14097 } 14098 } 14099 else 14100 { 14101 if ($macro eq 'setfilename' and $Texi2HTML::Config::USE_SETFILENAME) 14102 { 14103 my $filename = $line; 14104 $filename =~ s/^\s*//; 14105 $filename =~ s/\s*$//; 14106 #$filename = substitute_line($filename, {'code_style' => 1}); 14107 $filename = substitute_line($filename, {'code_style' => 1, 'remove_texi' => 1}); 14108 # remove extension 14109 $filename =~ s/\.[^\.]*$//; 14110 init_with_file_name ($filename) if ($filename ne ''); 14111 } 14112 # in reality, do only set, clear and clickstyle. 14113 # though we should never go there for clickstyle... 14114 common_misc_commands($macro, $line, 0, $line_nr); 14115 } 14116 } 14117 14118 ($text, $line, $args) = &$Texi2HTML::Config::preserve_misc_command($line, $macro); 14119 return ($text, $line); 14120} 14121 14122# initial kdb styles 14123my $kept_kdb_style; 14124my $kept_kdb_pre_style; 14125# novalidate seen? 14126my $novalidate; 14127 14128# handle misc commands and misc command args 14129sub misc_command_structure($$$$) 14130{ 14131 my $line = shift; 14132 my $macro = shift; 14133 my $state = shift; 14134 my $line_nr = shift; 14135 my $text; 14136 my $args; 14137 14138 if ($macro eq 'lowersections') 14139 { 14140 my ($sec, $level); 14141 while (($sec, $level) = each %sec2level) 14142 { 14143 $sec2level{$sec} = $level + 1; 14144 } 14145 $state->{'sectionning_base'}--; 14146 } 14147 elsif ($macro eq 'raisesections') 14148 { 14149 my ($sec, $level); 14150 while (($sec, $level) = each %sec2level) 14151 { 14152 $sec2level{$sec} = $level - 1; 14153 } 14154 $state->{'sectionning_base'}++; 14155 } 14156 elsif (($macro eq 'contents') or ($macro eq 'summarycontents') or ($macro eq 'shortcontents')) 14157 { 14158 if ($macro eq 'contents') 14159 { 14160 $Texi2HTML::THISDOC{'DO_CONTENTS'} = 1 unless (defined($Texi2HTML::Config::DO_CONTENTS)); 14161 $Texi2HTML::THISDOC{$macro} = 1; 14162 } 14163 else 14164 { 14165 $macro = 'shortcontents'; 14166 $Texi2HTML::THISDOC{'DO_SCONTENTS'} = 1 unless (defined($Texi2HTML::Config::DO_SCONTENTS)); 14167 $Texi2HTML::THISDOC{$macro} = 1; 14168 } 14169 push @{$state->{'place'}}, $content_element{$macro}; 14170 } 14171 elsif ($macro eq 'novalidate') 14172 { 14173 $novalidate = 1; 14174 $Texi2HTML::THISDOC{$macro} = 1; 14175 } 14176 elsif (grep {$_ eq $macro} ('settitle','shorttitlepage','title') 14177 and ($line =~ /^\s+(.*)$/)) 14178 { 14179 my $arg = $1; 14180 chomp($arg); 14181 $value{"_$macro"} = $arg; 14182 # backward compatibility 14183 if ($macro eq 'title') 14184 { 14185 $Texi2HTML::THISDOC{"${macro}s_texi"} = [ $arg ]; 14186 $Texi2HTML::THISDOC{"${macro}s"} = [ $arg ]; 14187 } 14188 } 14189 elsif (grep {$_ eq $macro} ('author','subtitle') 14190 and ($line =~ /^\s+(.*)$/)) 14191 { 14192 my $arg = $1; 14193 $value{"_$macro"} .= $arg."\n"; 14194 chomp($arg); 14195 push @{$Texi2HTML::THISDOC{"${macro}s_texi"}}, $arg; 14196 push @{$Texi2HTML::THISDOC{"${macro}s"}}, $arg; 14197 } 14198 elsif ($macro eq 'synindex' || $macro eq 'syncodeindex') 14199 { 14200 if ($line =~ /^\s+(\w+)\s+(\w+)/) 14201 { 14202 my $index_from = $1; 14203 my $index_to = $2; 14204 echo_error ("unknown from index name $index_from in \@$macro", $line_nr) 14205 unless $index_names{$index_from}; 14206 echo_error ("unknown to index name $index_to in \@$macro", $line_nr) 14207 unless $index_names{$index_to}; 14208 if ($index_names{$index_from} and $index_names{$index_to}) 14209 { 14210 if ($macro eq 'syncodeindex') 14211 { 14212 $index_names{$index_to}->{'associated_indices_code'}->{$index_from} = 1; 14213 } 14214 else 14215 { 14216 $index_names{$index_to}->{'associated_indices'}->{$index_from} = 1; 14217 } 14218 push @{$Texi2HTML::THISDOC{$macro}}, [$index_from,$index_to]; 14219 } 14220 } 14221 else 14222 { 14223 echo_error ("Bad $macro line: $line", $line_nr); 14224 } 14225 } 14226 elsif ($macro eq 'defindex' || $macro eq 'defcodeindex') 14227 { 14228 if ($line =~ /^\s+(\w+)\s*$/) 14229 { 14230 my $name = $1; 14231 if ($forbidden_index_name{$name}) 14232 { 14233 echo_error("Reserved index name $name", $line_nr); 14234 } 14235 else 14236 { 14237 @{$index_names{$name}->{'prefix'}} = ($name); 14238 $index_names{$name}->{'code'} = 1 if $macro eq 'defcodeindex'; 14239 $index_prefix_to_name{$name} = $name; 14240 push @{$Texi2HTML::THISDOC{$macro}}, $name; 14241 } 14242 } 14243 else 14244 {# makeinfo don't warn and even accepts index with empty name 14245 # and index with numbers only. I reported it on the mailing list 14246 # this should be fixed in future makeinfo versions. 14247 echo_error ("Bad $macro line: $line", $line_nr); 14248 } 14249 } 14250 elsif ($macro eq 'kbdinputstyle') 14251 {# makeinfo ignores that with --html. I reported it and it should be 14252 # fixed in future makeinfo releases 14253 14254 # FIXME it should be dynamically defined in pass 2 14255 if ($line =~ /\s+([a-z]+)/) 14256 { 14257 if ($1 eq 'code') 14258 { 14259 $::style_map_ref->{'kbd'} = $::style_map_ref->{'code'}; 14260 $::style_map_pre_ref->{'kbd'} = $::style_map_pre_ref->{'code'}; 14261 $Texi2HTML::THISDOC{$macro} = $1; 14262 } 14263 elsif ($1 eq 'example') 14264 { 14265 $::style_map_pre_ref->{'kbd'} = $::style_map_pre_ref->{'code'}; 14266 $Texi2HTML::THISDOC{$macro} = $1; 14267 } 14268 elsif ($1 eq 'distinct') 14269 { 14270 $Texi2HTML::THISDOC{$macro} = $1; 14271 $::style_map_ref->{'kbd'} = $kept_kdb_style; 14272 $::style_map_pre_ref->{'kbd'} = $kept_kdb_pre_style; 14273 } 14274 else 14275 { 14276 echo_error ("Unknown argument for \@$macro: $1", $line_nr); 14277 } 14278 } 14279 else 14280 { 14281 echo_error ("Bad \@$macro", $line_nr); 14282 } 14283 } 14284 elsif (grep {$_ eq $macro} ('everyheadingmarks','everyfootingmarks', 14285 'evenheadingmarks','oddheadingmarks','evenfootingmarks','oddfootingmarks')) 14286 { 14287 if (($line =~ /^\s+(top)[^\w\-]/) or ($line =~ /^\s+(bottom)[^\w\-]/)) 14288 { 14289 $Texi2HTML::THISDOC{$macro} = $1; 14290 } 14291 else 14292 { 14293 echo_error ("Bad \@$macro", $line_nr); 14294 } 14295 } 14296 elsif ($macro eq 'fonttextsize') 14297 { 14298 if (($line =~ /^\s+(10)[^\w\-]/) or ($line =~ /^\s+(11)[^\w\-]/)) 14299 { 14300 $Texi2HTML::THISDOC{$macro} = $1; 14301 } 14302 else 14303 { 14304 echo_error ("Bad \@$macro", $line_nr); 14305 } 14306 } 14307 elsif ($macro eq 'pagesizes') 14308 { 14309 if ($line =~ /^\s+(.*)\s*$/) 14310 { 14311 $Texi2HTML::THISDOC{$macro} = $1; 14312 } 14313 } 14314 elsif ($macro eq 'footnotestyle') 14315 { 14316 if (($line =~ /^\s+(end)[^\w\-]/) or ($line =~ /^\s+(separate)[^\w\-]/)) 14317 { 14318 $Texi2HTML::THISDOC{$macro} = $1; 14319 } 14320 else 14321 { 14322 echo_error ("Bad \@$macro", $line_nr); 14323 } 14324 } 14325 elsif ($macro eq 'setchapternewpage') 14326 { 14327 if (($line =~ /^\s+(on)[^\w\-]/) or ($line =~ /^\s+(off)[^\w\-]/) 14328 or ($line =~ /^\s+(odd)[^\w\-]/)) 14329 { 14330 $Texi2HTML::THISDOC{$macro} = $1; 14331 } 14332 else 14333 { 14334 echo_error ("Bad \@$macro", $line_nr); 14335 } 14336 } 14337 elsif ($macro eq 'setcontentsaftertitlepage' or $macro eq 'setshortcontentsaftertitlepage') 14338 { 14339 $Texi2HTML::THISDOC{$macro} = 1; 14340 my $tag = 'contents'; 14341 $tag = 'shortcontents' if ($macro ne 'setcontentsaftertitlepage'); 14342 $content_element{$tag}->{'aftertitlepage'} = 1; 14343 } 14344 elsif ($macro eq 'need') 14345 { # only a warning 14346 unless (($line =~ /^\s+([0-9]+(\.[0-9]*)?)[^\w\-]/) or 14347 ($line =~ /^\s+(\.[0-9]+)[^\w\-]/)) 14348 { 14349 echo_warn ("Bad \@$macro", $line_nr); 14350 } 14351 } 14352 else 14353 { 14354 common_misc_commands($macro, $line, 1, $line_nr); 14355 } 14356 14357 ($text, $line, $args) = &$Texi2HTML::Config::preserve_misc_command($line, $macro); 14358 return ($text, $line); 14359} 14360 14361sub set_special_names() 14362{ 14363 $Texi2HTML::NAME{'About'} = &$I('About This Document'); 14364 $Texi2HTML::NAME{'Contents'} = &$I('Table of Contents'); 14365 $Texi2HTML::NAME{'Overview'} = &$I('Short Table of Contents'); 14366 $Texi2HTML::NAME{'Footnotes'} = &$I('Footnotes'); 14367 $Texi2HTML::NO_TEXI{'About'} = &$I('About This Document', {}, {'remove_texi' => 1} ); 14368 $Texi2HTML::NO_TEXI{'Contents'} = &$I('Table of Contents', {}, {'remove_texi' => 1} ); 14369 $Texi2HTML::NO_TEXI{'Overview'} = &$I('Short Table of Contents', {}, {'remove_texi' => 1} ); 14370 $Texi2HTML::NO_TEXI{'Footnotes'} = &$I('Footnotes', {}, {'remove_texi' => 1} ); 14371 $Texi2HTML::SIMPLE_TEXT{'About'} = &$I('About This Document', {}, {'simple_format' => 1}); 14372 $Texi2HTML::SIMPLE_TEXT{'Contents'} = &$I('Table of Contents',{}, {'simple_format' => 1}); 14373 $Texi2HTML::SIMPLE_TEXT{'Overview'} = &$I('Short Table of Contents', {}, {'simple_format' => 1}); 14374 $Texi2HTML::SIMPLE_TEXT{'Footnotes'} = &$I('Footnotes', {},{'simple_format' => 1}); 14375} 14376 14377# return the line after removing things according to misc_command map. 14378# if the skipped macro has an effect it is done here 14379# this is used during pass_text 14380sub misc_command_text($$$$$$) 14381{ 14382 my $line = shift; 14383 my $macro = shift; 14384 my $stack = shift; 14385 my $state = shift; 14386 my $text = shift; 14387 my $line_nr = shift; 14388 my ($skipped, $remaining, $args); 14389 14390 # The strange condition associated with 'keep_texi' is 14391 # there because for an argument appearing on an @itemize 14392 # line (we're in 'check_item'), meant to be prepended to an 14393 # @item we don't want to keep @c or @comment as otherwise it 14394 # eats the @item line. Other commands could do that too but 14395 # then the user deserves what he gets. 14396 if ($state->{'keep_texi'} and 14397 (!$state->{'check_item'} or ($macro ne 'c' and $macro ne 'comment'))) 14398 { 14399 ($remaining, $skipped, $args) = &$Texi2HTML::Config::preserve_misc_command($line, $macro); 14400 add_prev($text, $stack, "\@$macro". $skipped); 14401 return $remaining; 14402 } 14403 14404 # if it is true the command args are kept so the user can modify how 14405 # they are skipped and handle them as unknown @-commands 14406 my $keep = $Texi2HTML::Config::misc_command{$macro}->{'keep'}; 14407 14408 if ($macro eq 'sp') 14409 { 14410 my $sp_number; 14411 if ($line =~ /^\s+(\d+)\s/) 14412 { 14413 $sp_number = $1; 14414 } 14415 elsif ($line =~ /(\s*)$/) 14416 { 14417 $sp_number = ''; 14418 } 14419 else 14420 { 14421 echo_error ("\@$macro needs a numeric arg or no arg", $line_nr); 14422 } 14423 $sp_number = 1 if ($sp_number eq ''); 14424 if (!$state->{'remove_texi'}) 14425 { 14426 add_prev($text, $stack, &$Texi2HTML::Config::sp($sp_number, $state->{'preformatted'})); 14427 } 14428 } 14429 elsif($macro eq 'verbatiminclude' and !$keep) 14430 { 14431 if ($line =~ /\s+(.+)/) 14432 { 14433 my $arg = $1; 14434 my $file = locate_include_file(substitute_line($arg, {'code_style' => 1})); 14435 if (defined($file)) 14436 { 14437 if (!open(VERBINCLUDE, $file)) 14438 { 14439 echo_warn ("Can't read file $file: $!",$line_nr); 14440 } 14441 else 14442 { 14443 my $verb_text = ''; 14444 while (my $line = <VERBINCLUDE>) 14445 { 14446 $verb_text .= $line; 14447 } 14448 14449 if ($state->{'remove_texi'}) 14450 { 14451 add_prev ($text, $stack, &$Texi2HTML::Config::raw_no_texi('verbatim', $verb_text)); 14452 } 14453 else 14454 { 14455 add_prev($text, $stack, &$Texi2HTML::Config::raw('verbatim', $verb_text)); 14456 } 14457 close VERBINCLUDE; 14458 } 14459 } 14460 else 14461 { 14462 echo_error ("Can't find $arg, skipping", $line_nr); 14463 } 14464 } 14465 else 14466 { 14467 echo_error ("Bad \@$macro line: $line", $line_nr); 14468 } 14469 } 14470 elsif ($macro eq 'indent' or $macro eq 'noindent') 14471 { 14472 $state->{'paragraph_indent'} = $macro; 14473 } 14474 else 14475 { 14476 common_misc_commands($macro, $line, 2, $line_nr); 14477 } 14478 14479 ($remaining, $skipped, $args) = &$Texi2HTML::Config::preserve_misc_command($line, $macro); 14480#print STDERR "ZZZZZZZZZZZ r $remaining ZZ a @$args ZZZZ s `$skipped'\n" if ($keep); 14481 return ($skipped.$remaining) if ($keep); 14482 return $remaining if ($remaining ne ''); 14483 return undef; 14484} 14485 14486# merge the things appearing before the first @node or sectionning command 14487# (held by element_before_anything) with the current element 14488# do that only once. 14489sub merge_element_before_anything($) 14490{ 14491 my $element = shift; 14492 if (exists($element_before_anything->{'place'})) 14493 { 14494 $element->{'current_place'} = $element_before_anything->{'place'}; 14495 delete $element_before_anything->{'place'}; 14496 foreach my $placed_thing (@{$element->{'current_place'}}) 14497 { 14498 $placed_thing->{'element'} = $element if (exists($placed_thing->{'element'})); 14499 } 14500 } 14501 # this is certainly redundant with the above condition, but cleaner 14502 # that way 14503 if (exists($element_before_anything->{'titlefont'})) 14504 { 14505 $element->{'titlefont'} = $element_before_anything->{'titlefont'}; 14506 delete $element_before_anything->{'titlefont'}; 14507 } 14508} 14509 14510# find menu_prev, menu_up... for a node in menu 14511sub menu_entry_texi($$$) 14512{ 14513 my $node = shift; 14514 my $state = shift; 14515 my $line_nr = shift; 14516 my $node_menu_ref = {}; 14517 if (exists($nodes{$node})) 14518 { 14519 $node_menu_ref = $nodes{$node}; 14520 } 14521 else 14522 { 14523 $nodes{$node} = $node_menu_ref; 14524 $node_menu_ref->{'texi'} = $node; 14525 $node_menu_ref->{'external_node'} = 1 if ($node =~ /^\(.+\)/); 14526 } 14527 return if ($state->{'detailmenu'}); 14528 if ($state->{'node_ref'}) 14529 { 14530 $node_menu_ref->{'menu_up'} = $state->{'node_ref'}; 14531 $node_menu_ref->{'menu_up_hash'}->{$state->{'node_ref'}->{'texi'}} = 1; 14532 } 14533 else 14534 { 14535 echo_warn ("menu entry without previous node: $node", $line_nr) unless ($node =~ /\(.+\)/); 14536 } 14537 if ($state->{'prev_menu_node'}) 14538 { 14539 $node_menu_ref->{'menu_prev'} = $state->{'prev_menu_node'}; 14540 $state->{'prev_menu_node'}->{'menu_next'} = $node_menu_ref; 14541 } 14542 elsif ($state->{'node_ref'} and !$state->{'node_ref'}->{'menu_child'}) 14543 { 14544 $state->{'node_ref'}->{'menu_child'} = $node_menu_ref; 14545 } 14546 $state->{'prev_menu_node'} = $node_menu_ref; 14547} 14548 14549sub prepare_indices() 14550{ 14551 foreach my $index_name (keys(%{$Texi2HTML::THISDOC{'indices'}})) 14552 { 14553 #my ($pages, $entries) = get_index($index_name, undef, 1); 14554 #my $entries = get_index($index_name, undef, 1); 14555 my $entries = get_index($index_name); 14556 foreach my $printindex (@{$Texi2HTML::THISDOC{'indices'}->{$index_name}}) 14557 { 14558 $printindex->{'entries'} = $entries; 14559 } 14560 } 14561 Texi2HTML::Config::t2h_default_init_split_indices(); 14562} 14563 14564my @index_labels; # array corresponding with @?index commands 14565 # constructed during pass_structure, used to 14566 # put labels in pass_text 14567 14568# This function is used to construct link names from node names as 14569# specified for texinfo 14570sub cross_manual_links() 14571{ 14572 print STDERR "# Doing ".scalar(keys(%nodes))." cross manual links ". 14573 scalar(@index_labels). "index entries\n" 14574 if ($T2H_DEBUG); 14575 my $normal_text_kept = $Texi2HTML::Config::normal_text; 14576 $::simple_map_texi_ref = \%cross_ref_simple_map_texi; 14577 $::style_map_texi_ref = \%cross_ref_style_map_texi; 14578 $::texi_map_ref = \%cross_ref_texi_map; 14579 $Texi2HTML::Config::normal_text = \&Texi2HTML::Config::t2h_cross_manual_normal_text; 14580 14581 foreach my $key (keys(%nodes)) 14582 { 14583 my $node = $nodes{$key}; 14584 #print STDERR "CROSS_MANUAL:$key,$node\n"; 14585 if (!defined($node->{'texi'})) 14586 { 14587 ###################### debug section 14588 foreach my $key (keys(%$node)) 14589 { 14590 #print STDERR "$key:$node->{$key}!!!\n"; 14591 } 14592 ###################### end debug section 14593 } 14594 else 14595 { 14596 $node->{'cross_manual_target'} = remove_texi($node->{'texi'}); 14597 if ($Texi2HTML::Config::USE_UNICODE) 14598 { 14599 $node->{'cross_manual_target'} = Unicode::Normalize::NFC($node->{'cross_manual_target'}); 14600 if ($Texi2HTML::Config::TRANSLITERATE_NODE and $Texi2HTML::Config::USE_UNIDECODE) 14601 { 14602 $node->{'cross_manual_file'} = 14603 unicode_to_protected(unicode_to_transliterate($node->{'cross_manual_target'})); 14604 } 14605 $node->{'cross_manual_target'} = 14606 unicode_to_protected($node->{'cross_manual_target'}); 14607 } 14608#print STDERR "CROSS_MANUAL_TARGET $node->{'cross_manual_target'}\n"; 14609 unless ($node->{'external_node'}) 14610 { 14611 if (exists($cross_reference_nodes{$node->{'cross_manual_target'}})) 14612 { 14613 my $other_node_array = $cross_reference_nodes{$node->{'cross_manual_target'}}; 14614 my $node_seen; 14615 foreach my $other_node (@{$other_node_array}) 14616 { # find the first node seen for the error message 14617 $node_seen = $other_node; 14618 last if ($nodes{$other_node}->{'seen'}) 14619 } 14620 echo_error("Node equivalent with `$node->{'texi'}' already used `$node_seen'"); 14621 push @{$other_node_array}, $node->{'texi'}; 14622 } 14623 else 14624 { 14625 push @{$cross_reference_nodes{$node->{'cross_manual_target'}}}, $node->{'texi'}; 14626 } 14627 } 14628 } 14629 } 14630 14631 14632 if ($Texi2HTML::Config::TRANSLITERATE_NODE and 14633 (!$Texi2HTML::Config::USE_UNICODE or !$Texi2HTML::Config::USE_UNIDECODE)) 14634 { 14635 $::style_map_texi_ref = \%cross_transliterate_style_map_texi; 14636 $::texi_map_ref = \%cross_transliterate_texi_map; 14637 $Texi2HTML::Config::normal_text = \&Texi2HTML::Config::t2h_cross_manual_normal_text_transliterate if (!$Texi2HTML::Config::USE_UNICODE); 14638 14639 foreach my $key (keys(%nodes)) 14640 { 14641 my $node = $nodes{$key}; 14642 if (defined($node->{'texi'})) 14643 { 14644 $node->{'cross_manual_file'} = remove_texi($node->{'texi'}); 14645 $node->{'cross_manual_file'} = unicode_to_protected(unicode_to_transliterate($node->{'cross_manual_file'})) if ($Texi2HTML::Config::USE_UNICODE); 14646 } 14647 } 14648 14649 foreach my $entry (@index_labels, values(%sections), values(%headings)) 14650 { 14651 $entry->{'cross'} = remove_texi($entry->{'texi'}); 14652 $entry->{'cross'} = unicode_to_protected(unicode_to_transliterate($entry->{'cross'})) if ($Texi2HTML::Config::USE_UNICODE); 14653 } 14654 } 14655 else 14656 { 14657 foreach my $entry (@index_labels, values(%sections), values(%headings)) 14658 { 14659 $entry->{'cross'} = remove_texi($entry->{'texi'}); 14660 if ($Texi2HTML::Config::USE_UNICODE) 14661 { 14662 $entry->{'cross'} = Unicode::Normalize::NFC($entry->{'cross'}); 14663 if ($Texi2HTML::Config::TRANSLITERATE_NODE and $Texi2HTML::Config::USE_UNIDECODE) # USE_UNIDECODE is redundant 14664 { 14665 $entry->{'cross'} = 14666 unicode_to_protected(unicode_to_transliterate($entry->{'cross'})); 14667 } 14668 else 14669 { 14670 $entry->{'cross'} = 14671 unicode_to_protected($entry->{'cross'}); 14672 } 14673 } 14674 } 14675 } 14676 14677 $Texi2HTML::Config::normal_text = $normal_text_kept; 14678 $::simple_map_texi_ref = \%Texi2HTML::Config::simple_map_texi; 14679 $::style_map_texi_ref = \%Texi2HTML::Config::style_map_texi; 14680 $::texi_map_ref = \%Texi2HTML::Config::texi_map; 14681} 14682 14683# This function is used to construct a link name from a node name as 14684# specified for texinfo 14685sub cross_manual_line($;$) 14686{ 14687 my $text = shift; 14688 my $transliterate = shift; 14689#print STDERR "cross_manual_line $text\n"; 14690#print STDERR "remove_texi text ". remove_texi($text)."\n\n\n"; 14691 $::simple_map_texi_ref = \%cross_ref_simple_map_texi; 14692 $::style_map_texi_ref = \%cross_ref_style_map_texi; 14693 $::texi_map_ref = \%cross_ref_texi_map; 14694 my $normal_text_kept = $Texi2HTML::Config::normal_text; 14695 $Texi2HTML::Config::normal_text = \&Texi2HTML::Config::t2h_cross_manual_normal_text; 14696 14697 my ($cross_ref_target, $cross_ref_file); 14698 if ($Texi2HTML::Config::USE_UNICODE) 14699 { 14700 $cross_ref_target = Unicode::Normalize::NFC(remove_texi($text)); 14701 if ($transliterate and $Texi2HTML::Config::USE_UNIDECODE) 14702 { 14703 $cross_ref_file = 14704 unicode_to_protected(unicode_to_transliterate($cross_ref_target)); 14705 } 14706 $cross_ref_target = unicode_to_protected($cross_ref_target); 14707 } 14708 else 14709 { 14710 $cross_ref_target = remove_texi($text); 14711 } 14712 14713 if ($transliterate and 14714 (!$Texi2HTML::Config::USE_UNICODE or !$Texi2HTML::Config::USE_UNIDECODE)) 14715 { 14716 $::style_map_texi_ref = \%cross_transliterate_style_map_texi; 14717 $::texi_map_ref = \%cross_transliterate_texi_map; 14718 $Texi2HTML::Config::normal_text = \&Texi2HTML::Config::t2h_cross_manual_normal_text_transliterate if (!$Texi2HTML::Config::USE_UNICODE); 14719 $cross_ref_file = remove_texi($text); 14720 $cross_ref_file = unicode_to_protected(unicode_to_transliterate($cross_ref_file)) 14721 if ($Texi2HTML::Config::USE_UNICODE); 14722 } 14723 14724 $Texi2HTML::Config::normal_text = $normal_text_kept; 14725 $::simple_map_texi_ref = \%Texi2HTML::Config::simple_map_texi; 14726 $::style_map_texi_ref = \%Texi2HTML::Config::style_map_texi; 14727 $::texi_map_ref = \%Texi2HTML::Config::texi_map; 14728#print STDERR "\n\ncross_ref $cross_ref\n"; 14729 unless ($transliterate) 14730 { 14731 return $cross_ref_target; 14732 } 14733# print STDERR "$text|$cross_ref_target|$cross_ref_file\n"; 14734 return ($cross_ref_target, $cross_ref_file); 14735} 14736 14737sub equivalent_nodes($) 14738{ 14739 my $name = shift; 14740#print STDERR "equivalent_nodes $name\n"; 14741 my $node = normalise_node($name); 14742 $name = cross_manual_line($node); 14743 my @equivalent_nodes = (); 14744 if (exists($cross_reference_nodes{$name})) 14745 { 14746 @equivalent_nodes = grep {$_ ne $node} @{$cross_reference_nodes{$name}}; 14747 } 14748 return @equivalent_nodes; 14749} 14750 14751sub do_place_target_file($$$) 14752{ 14753 my $place = shift; 14754 my $element = shift; 14755 my $context = shift; 14756 14757 $place->{'file'} = $element->{'file'} unless defined($place->{'file'}); 14758 $place->{'target'} = $element->{'target'} unless defined($place->{'target'}); 14759# $place->{'doc_nr'} = $element->{'doc_nr'} unless defined($place->{'doc_nr'}); 14760 if (defined($Texi2HTML::Config::placed_target_file_name)) 14761 { 14762 my ($target, $id, $file) = &$Texi2HTML::Config::placed_target_file_name($place,$element,$place->{'target'}, $place->{'id'}, $place->{'file'},$context); 14763 $place->{'target'} = $target if (defined($target)); 14764 $place->{'file'} = $file if (defined($file)); 14765 $place->{'id'} = $id if (defined($id)); 14766 } 14767} 14768 14769sub do_node_target_file($$) 14770{ 14771 my $node = shift; 14772 my $type_of_node = shift; 14773 my $node_file = &$Texi2HTML::Config::node_file_name($node,$type_of_node); 14774 $node->{'node_file'} = $node_file if (defined($node_file)); 14775 if (defined($Texi2HTML::Config::node_target_name)) 14776 { 14777 my ($target,$id) = &$Texi2HTML::Config::node_target_name($node,$node->{'target'},$node->{'id'}, $type_of_node); 14778 $node->{'target'} = $target if (defined($target)); 14779 $node->{'id'} = $id if (defined($id)); 14780 } 14781} 14782 14783sub do_element_targets($;$) 14784{ 14785 my $element = shift; 14786 my $use_node_file = shift; 14787 my $is_top = ''; 14788 $is_top = "top" if ($element->{'top'} or (defined($element->{'with_node'}) and $element->{'with_node'} eq $element_top)); 14789 my $file_index_split = Texi2HTML::Config::t2h_default_associate_index_element($element, $is_top, $docu_name, $use_node_file); 14790 $element->{'file'} = $file_index_split if (defined($file_index_split)); 14791 if (defined($Texi2HTML::Config::element_file_name)) 14792 { 14793 my $previous_file_name = $element->{'file'}; 14794 my $filename = 14795 &$Texi2HTML::Config::element_file_name ($element, $is_top, $docu_name); 14796 if (defined($filename)) 14797 { 14798 foreach my $place (@{$element->{'place'}}) 14799 { 14800 $place->{'file'} = $filename if (defined($place->{'file'}) and ($place->{'file'} eq $previous_file_name)); 14801 } 14802 $element->{'file'} = $filename; 14803 } 14804 } 14805 print STDERR "file !defined for element $element->{'texi'}\n" if (!defined($element->{'file'})); 14806 if (defined($Texi2HTML::Config::element_target_name)) 14807 { 14808 my ($target,$id) = &$Texi2HTML::Config::element_target_name($element, $element->{'target'}, $element->{'id'}); 14809 $element->{'target'} = $target if (defined($target)); 14810 $element->{'id'} = $id if (defined($id)); 14811 } 14812 foreach my $place(@{$element->{'place'}}) 14813 { 14814 do_place_target_file($place, $element, ''); 14815 } 14816} 14817 14818sub add_t2h_element($$$) 14819{ 14820 my $element = shift; 14821 my $elements_list = shift; 14822 my $prev_element = shift; 14823 14824 push @$elements_list, $element; 14825 $element->{'element_ref'} = $element; 14826 $element->{'this'} = $element; 14827 14828 if (defined($prev_element)) 14829 { 14830 $element->{'back'} = $prev_element; 14831 $prev_element->{'forward'} = $element; 14832 } 14833 push @{$element->{'place'}}, $element; 14834 push @{$element->{'place'}}, @{$element->{'current_place'}}; 14835 return $element; 14836} 14837 14838sub add_t2h_dependent_element ($$) 14839{ 14840 my $element = shift; 14841 my $element_ref = shift; 14842 $element->{'element_ref'} = $element_ref; 14843 $element_index = $element_ref if ($element_index and ($element_index eq $element)); 14844 push @{$element_ref->{'place'}}, $element; 14845 push @{$element_ref->{'place'}}, @{$element->{'current_place'}}; 14846} 14847 14848my %files = (); # keys are files. This is used to avoid reusing an already 14849 # used file name 14850my %empty_indices = (); # value is true for an index name key if the index 14851 # is empty 14852my %printed_indices = (); # value is true for an index name not empty and 14853 # printed 14854# This is a virtual element used to have the right hrefs for index entries 14855# and anchors in footnotes. 14856my $footnote_element; 14857 14858# find next, prev, up, back, forward, fastback, fastforward 14859# find element id and file 14860# split index pages 14861# associate placed items (items which have links to them) with the right 14862# file and id 14863# associate nodes with sections 14864sub rearrange_elements() 14865{ 14866 print STDERR "# find sections levels and toplevel\n" 14867 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 14868 14869 my $toplevel = 4; 14870 # correct level if raisesections or lowersections overflowed 14871 # and find toplevel level 14872 # use %sections and %headings to modify also the headings 14873 foreach my $section (values(%sections), values(%headings)) 14874 { 14875 my $level = $section->{'level'}; 14876 if ($level > $MAX_LEVEL) 14877 { 14878 $section->{'level'} = $MAX_LEVEL; 14879 } 14880 elsif ($level < $MIN_LEVEL and !$section->{'top'}) 14881 { 14882 $section->{'level'} = $MIN_LEVEL; 14883 } 14884 else 14885 { 14886 $section->{'level'} = $level; 14887 } 14888 $section->{'toc_level'} = $section->{'level'}; 14889 # This is for top 14890 $section->{'toc_level'} = $MIN_LEVEL if ($section->{'level'} < $MIN_LEVEL); 14891 # find the new tag corresponding with the level of the section 14892 if ($section->{'tag'} !~ /heading/ and ($level ne $reference_sec2level{$section->{'tag'}})) 14893 { 14894 $section->{'tag_level'} = $level2sec{$section->{'tag'}}->[$section->{'level'}]; 14895 } 14896 else 14897 { 14898 $section->{'tag_level'} = $section->{'tag'}; 14899 } 14900 $toplevel = $section->{'level'} if (($section->{'level'} < $toplevel) and ($section->{'level'} > 0 and ($section->{'tag'} !~ /heading/))); 14901 print STDERR "# section level $level: $section->{'texi'}\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 14902 } 14903 14904 print STDERR "# find sections structure, construct section numbers (toplevel=$toplevel)\n" 14905 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 14906 my $in_appendix = 0; 14907 # these arrays have an element per sectionning level. 14908 my @previous_numbers = (); # holds the number of the previous sections 14909 # at the same and upper levels 14910 my @previous_sections = (); # holds the ref of the previous sections 14911 my $previous_toplevel; 14912 14913 foreach my $section (@sections_list) 14914 { 14915 ########################### debug 14916 print STDERR "BUG: node or section_ref defined for section $section->{'texi'}\n" 14917 if (exists($section->{'node'}) or exists($section->{'section_ref'})); 14918 ########################### end debug 14919 # associate with first node if it is a section appearing before 14920 # the first node 14921 $section->{'node_ref'} = $nodes_list[0] if ($nodes_list[0] and !$section->{'node_ref'}); 14922 print STDERR "Bug level undef for ($section) $section->{'texi'}\n" if (!defined($section->{'level'})); 14923 # we track the toplevel next and previous because there is no 14924 # strict child parent relationship between chapters and top. Indeed 14925 # a chapter may appear before @top, it may be better to consider them 14926 # on the same toplevel. 14927 if ($section->{'level'} <= $toplevel) 14928 { 14929 $section->{'toplevel'} = 1; 14930 if (defined($previous_toplevel)) 14931 { 14932 $previous_toplevel->{'toplevelnext'} = $section; 14933 $section->{'toplevelprev'} = $previous_toplevel; 14934 } 14935 $previous_toplevel = $section; 14936 if (defined($section_top) and $section ne $section_top) 14937 { 14938 $section->{'sectionup'} = $section_top; 14939 } 14940 } 14941 # undef things under that section level 14942 my $section_level = $section->{'level'}; 14943 # if it is the top element, the previous chapter is not wiped out 14944 $section_level++ if ($section->{'tag'} eq 'top'); 14945 for (my $level = $section_level + 1; $level < $MAX_LEVEL + 1 ; $level++) 14946 { 14947 $previous_numbers[$level] = undef unless ($section->{'tag'} =~ /unnumbered/); 14948 $previous_sections[$level] = undef; 14949 } 14950 my $number_set; 14951 # find number at the current level 14952 if ($section->{'tag'} =~ /appendix/ and !$in_appendix) 14953 { 14954 $previous_numbers[$toplevel] = 'A'; 14955 $in_appendix = 1; 14956 $number_set = 1 if ($section->{'level'} <= $toplevel); 14957 } 14958 if (!defined($previous_numbers[$section->{'level'}]) and !$number_set) 14959 { 14960 if ($section->{'tag'} =~ /unnumbered/) 14961 { 14962 $previous_numbers[$section->{'level'}] = undef; 14963 } 14964 else 14965 { 14966 $previous_numbers[$section->{'level'}] = 1; 14967 } 14968 } 14969 elsif ($section->{'tag'} !~ /unnumbered/ and !$number_set) 14970 { 14971 $previous_numbers[$section->{'level'}]++; 14972 } 14973 # construct the section number 14974 $section->{'number'} = ''; 14975 14976 unless ($section->{'tag'} =~ /unnumbered/ or $section->{'tag'} eq 'top') 14977 { 14978 my $level = $section->{'level'}; 14979 while ($level > $toplevel) 14980 { 14981 my $number = $previous_numbers[$level]; 14982 $number = 0 if (!defined($number)); 14983 if ($section->{'number'}) 14984 { 14985 $section->{'number'} = "$number.$section->{'number'}"; 14986 } 14987 else 14988 { 14989 $section->{'number'} = $number; 14990 } 14991 $level--; 14992 } 14993 my $toplevel_number = $previous_numbers[$toplevel]; 14994 $toplevel_number = 0 if (!defined($toplevel_number)); 14995 $section->{'number'} = "$toplevel_number.$section->{'number'}"; 14996 } 14997 # find the previous section 14998 if (defined($previous_sections[$section->{'level'}])) 14999 { 15000 my $prev_section = $previous_sections[$section->{'level'}]; 15001 $section->{'sectionprev'} = $prev_section; 15002 $prev_section->{'sectionnext'} = $section; 15003 } 15004 # find the up section 15005 my $level = $section->{'level'} - 1; 15006 while (!defined($previous_sections[$level]) and ($level >= 0)) 15007 { 15008 $level--; 15009 } 15010 if ($level >= 0) 15011 { 15012 $section->{'sectionup'} = $previous_sections[$level]; 15013 # 'child' is the first child 15014 $section->{'sectionup'}->{'child'} = $section unless ($section->{'sectionprev'}); 15015 push @{$section->{'sectionup'}->{'section_childs'}}, $section; 15016 } 15017 $previous_sections[$section->{'level'}] = $section; 15018 # This is what is used in the .init file. 15019 $section->{'up'} = $section->{'sectionup'}; 15020 # Not used but documented. 15021 $section->{'next'} = $section->{'sectionnext'}; 15022 $section->{'prev'} = $section->{'sectionprev'}; 15023 15024 ############################# debug 15025 my $up = "NO_UP"; 15026 $up = $section->{'sectionup'} if (defined($section->{'sectionup'})); 15027 print STDERR "# numbering section ($section->{'level'}): $section->{'number'}: (up: $up) $section->{'texi'}\n" 15028 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15029 ############################# end debug 15030 } 15031 15032 # at that point there are still some node structures that are not 15033 # in %nodes, (the external nodes, and unknown nodes in case 15034 # novalidate is true) so we cannot find the id. The consequence is that 15035 # some node equivalent with another node may not be catched during 15036 # that pass. We mark the nodes that have directions for unreferenced 15037 # nodes and make a second pass for these nodes afterwards. 15038 my @nodes_with_unknown_directions = (); 15039 15040 my %node_directions = ( 15041 'node_prev' => 'nodeprev', 15042 'node_next' => 'nodenext', 15043 'node_up' => 'nodeup'); 15044 # handle nodes 15045 # the node_prev... are texinfo strings, find the associated node references 15046 print STDERR "# Resolve nodes directions\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15047 foreach my $node (@nodes_list) 15048 { 15049 foreach my $direction (keys(%node_directions)) 15050 { 15051 if (defined($node->{$direction})) 15052 { 15053 if ($nodes{$node->{$direction}} and $nodes{$node->{$direction}}->{'seen'}) 15054 { 15055 $node->{$node_directions{$direction}} = $nodes{$node->{$direction}}; 15056 } 15057 elsif (($node->{$direction} =~ /^\(.*\)/) or $novalidate) 15058 { # ref to an external node 15059 if (exists($nodes{$node->{$direction}})) 15060 { 15061 $node->{$node_directions{$direction}} = $nodes{$node->{$direction}}; 15062 } 15063 else 15064 { 15065 # FIXME if {'seen'} this is a node appearing in the 15066 # document and a node like `(file)node'. What to 15067 # do then ? 15068 my $node_ref = { 'texi' => $node->{$direction} }; 15069 $node_ref->{'external_node'} = 1 if ($node->{$direction} =~ /^\(.*\)/); 15070 $nodes{$node->{$direction}} = $node_ref; 15071 $node->{$node_directions{$direction}} = $node_ref; 15072 } 15073 } 15074 else 15075 { 15076 push @nodes_with_unknown_directions, $node; 15077 } 15078 } 15079 } 15080 } 15081 15082 # Find cross manual links as explained on the texinfo mailing list 15083 # The specification is such that cross manual links formatting should 15084 # be insensitive to the manual split 15085 cross_manual_links(); 15086 15087 # Now it is possible to find the unknown directions that are equivalent 15088 # (have same node id) than an existing node 15089 foreach my $node (@nodes_with_unknown_directions) 15090 { 15091 foreach my $direction (keys(%node_directions)) 15092 { 15093 if (defined($node->{$direction}) and !$node->{$node_directions{$direction}}) 15094 { 15095 echo_warn ("$direction `$node->{$direction}' for `$node->{'texi'}' not found"); 15096 my @equivalent_nodes = equivalent_nodes($node->{$direction}); 15097 my $node_seen; 15098 foreach my $equivalent_node (@equivalent_nodes) 15099 { 15100 if ($nodes{$equivalent_node}->{'seen'}) 15101 { 15102 $node_seen = $equivalent_node; 15103 last; 15104 } 15105 } 15106 if (defined($node_seen)) 15107 { 15108 echo_warn (" ---> but equivalent node `$node_seen' found"); 15109 $node->{$node_directions{$direction}} = $nodes{$node_seen}; 15110 } 15111 } 15112 } 15113 } 15114 15115 # nodes are attached to the section preceding them if not already 15116 # associated with a section 15117 my $current_section = $sections_list[0]; 15118 foreach my $element (@all_elements) 15119 { 15120 if ($element->{'node'}) 15121 { 15122 if ($element->{'with_section'}) 15123 { # the node is associated with a section 15124 $element->{'section_ref'} = $element->{'with_section'}; 15125 } 15126 elsif (defined($current_section)) 15127 {# node appearing after a section, but not before another section, 15128 # or appearing before any section 15129 $element->{'section_ref'} = $current_section; 15130 push @{$current_section->{'node_childs'}}, $element; 15131 } 15132 } 15133 else 15134 { 15135 $current_section = $element; 15136 } 15137 } 15138 15139 print STDERR "# Complete nodes next prev and up based on menus and sections\n" 15140 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15141 # set the default id based on the node number 15142 my $node_nr = 1; 15143 # find the node* directions 15144 # find the directions corresponding with sections 15145 # and set 'up' for the node 15146 foreach my $node (@nodes_list) 15147 { 15148 # first a warning if the node and the equivalent nodes don't 15149 # appear in menus 15150 if (!$node->{'first'} and !$node->{'top'} and !$node->{'menu_up'} and ($node->{'texi'} !~ /^top$/i) and $Texi2HTML::Config::SHOW_MENU) 15151 { 15152 my @equivalent_nodes = equivalent_nodes($node->{'texi'}); 15153 my $found = 0; 15154 foreach my $equivalent_node (@equivalent_nodes) 15155 { 15156 if ($nodes{$equivalent_node}->{'first'} or $nodes{$equivalent_node}->{'menu_up'}) 15157 { 15158 $found = 1; 15159 last; 15160 } 15161 } 15162 unless ($found) 15163 { 15164 warn "$WARN `$node->{'texi'}' doesn't appear in menus\n"; 15165 } 15166 } 15167 15168 # use values deduced from menus to complete missing up, next, prev 15169 # or from sectionning commands if automatic sectionning 15170 if (!$node->{'nodeup'}) 15171 { 15172 if (defined($node_top) and ($node eq $node_top)) 15173 { # Top node has a special up, which is (dir) by default 15174 my $top_nodeup = $Texi2HTML::Config::TOP_NODE_UP; 15175 if (exists($nodes{$top_nodeup})) 15176 { 15177 $node->{'nodeup'} = $nodes{$top_nodeup}; 15178 } 15179 else 15180 { 15181 my $node_ref = { 'texi' => $top_nodeup }; 15182 $node_ref->{'external_node'} = 1; 15183 $nodes{$top_nodeup} = $node_ref; 15184 $node->{'nodeup'} = $node_ref; 15185 } 15186 } 15187 elsif ($node->{'automatic_directions'} and $node->{'with_section'}) 15188 { 15189 if (defined($node->{'with_section'}->{'sectionup'})) 15190 { 15191 $node->{'nodeup'} = get_node($node->{'with_section'}->{'sectionup'}); 15192 } 15193 elsif ($node->{'with_section'}->{'toplevel'} and defined($section_top) and ($node->{'with_section'} ne $section_top)) 15194 { 15195 $node->{'nodeup'} = get_node($section_top); 15196 } 15197 } 15198 print STDERR "# Deducing from section node_up $node->{'nodeup'}->{'texi'} for $node->{'texi'}\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS and defined($node->{'nodeup'})); 15199 } 15200 15201 if (!$node->{'nodeup'} and $node->{'menu_up'} and $Texi2HTML::Config::USE_MENU_DIRECTIONS) 15202 { # makeinfo don't do that 15203 $node->{'nodeup'} = $node->{'menu_up'}; 15204 print STDERR "# Deducing from menu node_up $node->{'menu_up'}->{'texi'} for $node->{'texi'}\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15205 } 15206 15207 if ($node->{'nodeup'} and !$node->{'nodeup'}->{'external_node'}) 15208 { 15209 # We detect when the up node has no menu entry for that node, as 15210 # there may be infinite loops when finding following node (see below) 15211 unless (defined($node->{'menu_up_hash'}) and ($node->{'menu_up_hash'}->{$node->{'nodeup'}->{'texi'}})) 15212 { 15213 print STDERR "$WARN `$node->{'nodeup'}->{'texi'}' is up for `$node->{'texi'}', but has no menu entry for this node\n" if ($Texi2HTML::Config::SHOW_MENU); 15214 push @{$node->{'up_not_in_menu'}}, $node->{'nodeup'}->{'texi'}; 15215 } 15216 } 15217 15218 # Find next node if not already found 15219 if ($node->{'nodenext'}) {} 15220 elsif ($node->{'texi'} eq 'Top') 15221 { # special case as said in the texinfo manual 15222 if ($node->{'menu_child'}) 15223 { 15224 $node->{'nodenext'} = $node->{'menu_child'}; 15225 $node->{'menu_child'}->{'nodeprev'} = $node; 15226 } 15227 } 15228 elsif ($node->{'automatic_directions'} and defined($node->{'with_section'})) 15229 { 15230 my $next; 15231 my $section = $node->{'with_section'}; 15232 if (defined($section->{'sectionnext'})) 15233 { 15234 $next = get_node($section->{'sectionnext'}); 15235 if (defined($next) and $Texi2HTML::Config::SHOW_MENU) 15236 { 15237 echo_warn ("No node following `$node->{'texi'}' in menu, but `$next->{'texi'}' follows in sectionning") if (!defined($node->{'menu_next'})); 15238 echo_warn ("Node following `$node->{'texi'}' in menu `$node->{'menu_next'}->{'texi'}' and in sectionning `$next->{'texi'}' differ") 15239 if (defined($node->{'menu_next'}) and $next ne $node->{'menu_next'}); 15240 } 15241 } 15242 elsif ($Texi2HTML::Config::USE_UP_FOR_ADJACENT_NODES) 15243 { # makeinfo don't do that 15244 while (defined($section->{'sectionup'}) and !defined($section->{'sectionnext'})) 15245 { 15246 $section = $section->{'sectionup'}; 15247 } 15248 if (defined($section->{'sectionnext'})) 15249 { 15250 $next = get_node($section->{'sectionnext'}); 15251 } 15252 } 15253 $node->{'nodenext'} = $next; 15254 } 15255 # next we try menus. makeinfo don't do that 15256 if (!defined($node->{'nodenext'}) and $node->{'menu_next'} 15257 and $Texi2HTML::Config::USE_MENU_DIRECTIONS) 15258 { 15259 $node->{'nodenext'} = $node->{'menu_next'}; 15260 } 15261 # Find prev node 15262 if (!$node->{'nodeprev'} and $node->{'automatic_directions'}) 15263 { 15264 if (defined($node->{'with_section'})) 15265 { 15266 my $section = $node->{'with_section'}; 15267 if (defined($section->{'sectionprev'})) 15268 { 15269 $node->{'nodeprev'} = get_node($section->{'sectionprev'}); 15270 } 15271 elsif ($Texi2HTML::Config::USE_UP_FOR_ADJACENT_NODES and defined($section->{'sectionup'})) 15272 { # makeinfo don't do that 15273 $node->{'nodeprev'} = get_node($section->{'sectionup'}); 15274 } 15275 } 15276 } 15277 # next we try menus. makeinfo don't do that 15278 if (!defined($node->{'nodeprev'}) and $node->{'menu_prev'} and $Texi2HTML::Config::USE_MENU_DIRECTIONS) 15279 { 15280 $node->{'nodeprev'} = $node->{'menu_prev'}; 15281 } 15282 # the prev node is the parent node 15283 elsif (!defined($node->{'nodeprev'}) and $node->{'menu_up'} and $Texi2HTML::Config::USE_MENU_DIRECTIONS) 15284 { 15285 $node->{'nodeprev'} = $node->{'menu_up'}; 15286 } 15287 15288 # the following node is the node following in node reading order 15289 # it is thus first the child, else the next, else the next following 15290 # the up 15291 if ($node->{'menu_child'}) 15292 { 15293 $node->{'following'} = $node->{'menu_child'}; 15294 } 15295 elsif ($node->{'automatic_directions'} and defined($node->{'with_section'}) and defined($node->{'with_section'}->{'child'})) 15296 { 15297 $node->{'following'} = get_node($node->{'with_section'}->{'child'}); 15298 } 15299 elsif (defined($node->{'nodenext'})) 15300 { 15301 $node->{'following'} = $node->{'nodenext'}; 15302 } 15303 else 15304 { 15305 my $up = $node->{'nodeup'}; 15306 # in order to avoid infinite recursion in case the up node is the 15307 # node itself we use the up node as following when there isn't 15308 # a correct menu structure, here and also below. 15309 $node->{'following'} = $up if (defined($up) and grep {$_ eq $up->{'texi'}} @{$node->{'up_not_in_menu'}}); 15310 while ((!defined($node->{'following'})) and (defined($up))) 15311 { 15312 if (($node_top) and ($up eq $node_top)) 15313 { # if we are at Top, Top is following 15314 $node->{'following'} = $node_top; 15315 $up = undef; 15316 } 15317 if (defined($up->{'nodenext'})) 15318 { 15319 $node->{'following'} = $up->{'nodenext'}; 15320 } 15321 elsif (defined($up->{'nodeup'})) 15322 { 15323 if (! grep { $_ eq $up->{'nodeup'}->{'texi'} } @{$node->{'up_not_in_menu'}}) 15324 { 15325 $up = $up->{'nodeup'}; 15326 } 15327 else 15328 { # in that case we can go into a infinite loop 15329 $node->{'following'} = $up->{'nodeup'}; 15330 } 15331 } 15332 else 15333 { 15334 $up = undef; 15335 } 15336 } 15337 } 15338 # FIXME with_section or node_ref? with with_section, as it is now 15339 # it is only done for the node associated with the section, with 15340 # section_ref it will be done for all the nodes after the section but 15341 # not associated with another section (as it was before) 15342 if (defined($node->{'with_section'})) 15343 { 15344 my $section = $node->{'with_section'}; 15345 foreach my $direction ('sectionnext', 'sectionprev', 'sectionup') 15346 { 15347 $node->{$direction} = $section->{$direction} 15348 if (defined($section->{$direction})); 15349 } 15350 # FIXME the following is wrong now, since it is only done for 15351 # the node->with_section. If done for node->section_ref it 15352 # could be true. 15353 # this is a node appearing within a section but not associated 15354 # with that section. We consider that it is below that section. 15355 $node->{'sectionup'} = $section 15356 if (grep {$node eq $_} @{$section->{'node_childs'}}); 15357 } 15358 # 'up' is used in .init files. Maybe should go away. 15359 if (defined($node->{'sectionup'})) 15360 { 15361 $node->{'up'} = $node->{'sectionup'}; 15362 } 15363 elsif (defined($node->{'nodeup'}) and 15364 (!$node_top or ($node ne $node_top))) 15365 { 15366 $node->{'up'} = $node->{'nodeup'}; 15367 } 15368 # 'next' not used but documented. 15369 if (defined($node->{'sectionnext'})) 15370 { 15371 $node->{'next'} = $node->{'sectionnext'}; 15372 } 15373 if (defined($node->{'sectionprev'})) 15374 { 15375 $node->{'prev'} = $node->{'sectionprev'}; 15376 } 15377 15378 # default id for nodes. Should be overriden later. 15379 $node->{'id'} = 'NOD' . $node_nr; 15380 $node_nr++; 15381 } 15382 15383 # do node directions for sections 15384 # FIXME: really do that? 15385 foreach my $section (@sections_list) 15386 { 15387 # If the element is not a node, then all the node directions are copied 15388 # if there is an associated node 15389 if (defined($section->{'with_node'})) 15390 { 15391 $section->{'nodenext'} = $section->{'with_node'}->{'nodenext'}; 15392 $section->{'nodeprev'} = $section->{'with_node'}->{'nodeprev'}; 15393 $section->{'menu_next'} = $section->{'with_node'}->{'menu_next'}; 15394 $section->{'menu_prev'} = $section->{'with_node'}->{'menu_prev'}; 15395 $section->{'menu_child'} = $section->{'with_node'}->{'menu_child'}; 15396 $section->{'menu_up'} = $section->{'with_node'}->{'menu_up'}; 15397 $section->{'nodeup'} = $section->{'with_node'}->{'nodeup'}; 15398 $section->{'following'} = $section->{'with_node'}->{'following'}; 15399 } 15400 else 15401 { # the section has no node associated. Find the node directions using 15402 # sections 15403 if (defined($section->{'toplevelnext'})) 15404 { 15405 $section->{'nodenext'} = get_node($section->{'toplevelnext'}); 15406 } 15407 elsif (defined($section->{'sectionnext'})) 15408 { 15409 $section->{'nodenext'} = get_node($section->{'sectionnext'}); 15410 } 15411 if (defined($section->{'toplevelprev'})) 15412 { 15413 $section->{'nodeprev'} = get_node($section->{'toplevelprev'}); 15414 } 15415 elsif (defined($section->{'sectionprev'})) 15416 { 15417 $section->{'nodeprev'} = get_node($section->{'sectionprev'}); 15418 } 15419 if (defined($section->{'sectionup'})) 15420 { 15421 $section->{'nodeup'} = get_node($section->{'sectionup'}); 15422 } 15423 15424 if ($section->{'child'}) 15425 { 15426 $section->{'following'} = get_node($section->{'child'}); 15427 } 15428 elsif ($section->{'toplevelnext'}) 15429 { 15430 $section->{'following'} = get_node($section->{'toplevelnext'}); 15431 } 15432 elsif ($section->{'sectionnext'}) 15433 { 15434 $section->{'following'} = get_node($section->{'sectionnext'}); 15435 } 15436 elsif ($section->{'sectionup'}) 15437 { 15438 my $up = $section; 15439 while ($up->{'sectionup'} and !$section->{'following'}) 15440 { 15441 print STDERR "# Going up, searching next section from $up->{'texi'}\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15442 die "BUG: $up->{'texi'} is up for itself\n" if ($up eq $up->{'sectionup'}); 15443 $up = $up->{'sectionup'}; 15444 if ($up->{'sectionnext'}) 15445 { 15446 $section->{'following'} = get_node ($up->{'sectionnext'}); 15447 } 15448 } 15449 } 15450 } 15451 } 15452 my $only_nodes = 0; 15453 my $only_sections = 0; 15454 15455 # for legibility 15456 my $use_nodes = $Texi2HTML::Config::USE_NODES; 15457 my $use_sections = $Texi2HTML::Config::USE_SECTIONS; 15458 15459 $only_nodes = 1 if ( 15460 (!scalar(@sections_list) and 15461 ($use_nodes or (!$use_sections and !defined($use_nodes)))) 15462 or ($use_nodes and !$use_sections) 15463 ); 15464 $only_sections = 1 if (!$only_nodes and !$use_nodes and ($use_sections or !defined($use_sections))); 15465 #print STDERR "only_nodes: $only_nodes, only_sections $only_sections\n"; 15466 15467 my $prev_element; 15468 print STDERR "# Build the elements list\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15469 foreach my $element (@all_elements) 15470 { 15471 if ($element->{'node'}) 15472 { 15473 if (!$only_nodes and $node_top and $element eq $node_top and !$section_top and !$node_top->{'with_section'}) 15474 { # special case for the top node if it isn't associated with 15475 # a section. 15476 # FIXME Config variable 15477 print STDERR "# Top not associated with a section\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15478 $node_top->{'top_as_section'} = 1; 15479 $node_top->{'section_ref'} = $node_top; 15480 $prev_element = add_t2h_element($element, \@elements_list, $prev_element); 15481 } 15482 elsif ($element->{'section_ref'} and ($only_sections or (!$only_nodes and $element->{'with_section'}))) 15483 { 15484 add_t2h_dependent_element ($element, $element->{'section_ref'}); 15485 $element->{'toc_level'} = $element->{'section_ref'}->{'toc_level'}; 15486 } 15487 elsif (!$only_sections) 15488 { 15489 $prev_element = add_t2h_element($element, \@elements_list, $prev_element); 15490 if ($element->{'section_ref'}) 15491 { # may happen if $only_nodes 15492 $element->{'toc_level'} = $element->{'section_ref'}->{'toc_level'}; 15493 } 15494 } 15495 else # $only_section and !$section_ref. This should only 15496 # happen when there are no sections 15497 # in that case it is possible that the node_top is an 15498 # element, so it is associated with this one. Maybe it 15499 # may happen that the node_top is not an element, not sure 15500 # what would be the consequence ni that case. 15501 { 15502 if ($node_top) 15503 { 15504 add_t2h_dependent_element ($element, $node_top); 15505 } 15506 else 15507 { 15508 #print STDERR "node $element->{'texi'} not associated with an element\n"; 15509 } 15510 } 15511 # FIXME use Texi2HTML::Config::NODE_TOC_LEVEL? 15512 $element->{'toc_level'} = $MIN_LEVEL if (!defined($element->{'toc_level'})); 15513 } 15514 else 15515 { 15516 if ($element->{'node_ref'} and $only_nodes) 15517 { 15518 add_t2h_dependent_element ($element, $element->{'node_ref'}); 15519 } 15520 elsif (!$only_nodes) 15521 { 15522 $prev_element = add_t2h_element($element, \@elements_list, $prev_element); 15523 } 15524 } 15525 } 15526 15527 # find texi2html specific directions and elements that are not texinfo 15528 # language features. 15529 # 15530 # Maybe Config hooks should be used at that point (up to index 15531 # preparation) 15532 # 15533 # find first, last and top elements 15534 if (@elements_list) 15535 { 15536 $element_first = $elements_list[0]; 15537 print STDERR "# element first: $element_first->{'texi'}\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15538 # It is the last element before indices split, which may add new 15539 # elements 15540 $element_last = $elements_list[-1]; 15541 } 15542 else 15543 { 15544 print STDERR "# \@elements_list is empty\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15545 } 15546 print STDERR "# top node: $node_top->{'texi'}\n" if (defined($node_top) and 15547 ($T2H_DEBUG & $DEBUG_ELEMENTS)); 15548 if (defined($section_top)) 15549 { 15550 # element top is the element with @top. 15551 $element_top = $section_top; 15552 } 15553 elsif (defined($node_top)) 15554 { 15555 # If the top node is associated with a section it is the top_element 15556 # otherwise element top may be the top node 15557 $element_top = $node_top; 15558 } 15559 elsif (defined($element_first)) 15560 { 15561 # If there is no @top section no top node the first node is the top element 15562 $element_top = $element_first; 15563 } 15564 15565 if (defined($element_top)) 15566 { 15567 $element_top->{'top'} = 1 if ($element_top->{'node'}); 15568 print STDERR "# element top: $element_top->{'texi'}\n" if ($element_top and 15569 ($T2H_DEBUG & $DEBUG_ELEMENTS)); 15570 } 15571 15572 print STDERR "# find fastback and fastforward\n" 15573 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15574 foreach my $element (@elements_list) 15575 { 15576 my $up = get_top($element); 15577 # this is a node not associated with a section 15578 $up = get_top($element->{'section_ref'}) if (!defined($up) and $element->{'node'} and $element->{'section_ref'}); 15579 next unless (defined($up)); 15580 # take the opportunity to set the first chapter with index 15581 $element_chapter_index = $up if ($element_index and ($element_index eq $element)); 15582 # fastforward is the next element on same level than the upper parent 15583 # element. 15584 if (exists ($up->{'toplevelnext'})) 15585 { 15586 $element->{'fastforward'} = $up->{'toplevelnext'} 15587 } 15588 # if the element isn't at the highest level, fastback is the 15589 # highest parent element 15590 if ($up and ($up ne $element)) 15591 { 15592 $element->{'fastback'} = $up; 15593 } 15594 elsif ($element->{'toplevel'}) 15595 { 15596 # the element is a top level element, we adjust the next 15597 # toplevel element fastback 15598 $element->{'fastforward'}->{'fastback'} = $element if ($element->{'fastforward'}); 15599 } 15600 } 15601 15602 foreach my $element (@elements_list) 15603 { 15604 # FIXME: certainly wrong. Indeed this causes the section associated 15605 # with the @node Top to be up for a @chapter, even if it is a 15606 # @chapter and not @top. It could even be up and, say, a @section! 15607 if ($element->{'toplevel'} and ($element ne $element_top)) 15608 { 15609 $element->{'up'} = $element_top; 15610 } 15611 } 15612 15613 # set 'reference_element' which is used each time there is a cross ref 15614 # to that node. 15615 # It is the section associated with the node if there are only sections 15616 # FIXME with only_nodes there should certainly be a corresponding 15617 # reference_element set. 15618 # also should certainly be done above 15619 if ($only_sections) 15620 { 15621 foreach my $node(@nodes_list) 15622 { 15623 if ($node->{'with_section'}) 15624 { 15625 $node->{'reference_element'} = $node->{'with_section'}; 15626 } 15627 } 15628 } 15629 15630 # do human readable id 15631 print STDERR "# find float id\n" 15632 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15633 foreach my $float (@floats) 15634 { 15635 $float->{'style_id'} = cross_manual_line(normalise_space($float->{'style_texi'})); 15636 my $float_style = { }; 15637 if (exists($floats{$float->{'style_id'}})) 15638 { 15639 $float_style = $floats{$float->{'style_id'}}; 15640 } 15641 else 15642 { 15643 $floats{$float->{'style_id'}} = $float_style; 15644 } 15645 push @{$float_style->{'floats'}}, $float; 15646 $float->{'absolute_nr'} = scalar(@{$float_style->{'floats'}}); 15647 my $up = get_top($float->{'element'}); 15648 if (defined($up) and (!defined($float_style->{'current_chapter'}) or ($up->{'texi'} ne $float_style->{'current_chapter'}))) 15649 { 15650 $float_style->{'current_chapter'} = $up->{'texi'}; 15651 $float_style->{'nr_in_chapter'} = 1; 15652 } 15653 else 15654 { 15655 $float_style->{'nr_in_chapter'}++; 15656 } 15657 if (defined($up) and $up->{'number'} ne '') 15658 { 15659 $float->{'chapter_nr'} = $up->{'number'}; 15660 $float->{'nr'} = $float->{'chapter_nr'} . $float_style->{'nr_in_chapter'}; 15661 } 15662 else 15663 { 15664 $float->{'nr'} = $float->{'absolute_nr'}; 15665 } 15666 } 15667 15668 print STDERR "# do human-readable index entries id\n" 15669 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15670 if ($Texi2HTML::Config::NEW_CROSSREF_STYLE) 15671 { 15672 foreach my $index_entry (@index_labels) 15673 { 15674 my $index_id = "index-" . $index_entry->{'cross'}; 15675 my $index = 1; 15676 # $index > 0 should prevent integer overflow, hopefully 15677 while (exists($cross_reference_nodes{$index_id}) and $index > 0) 15678 { 15679 $index_id = "index-" . $index_entry->{'cross'} . "-" .$index; 15680 $index++; 15681 } 15682 $index_entry->{'id'} = $index_id; 15683 $index_entry->{'target'} = $index_id; 15684 my $texi_entry = "index-".$index_entry->{'texi'}; 15685 $texi_entry .= "-".$index if ($index > 1); 15686 push @{$cross_reference_nodes{$index_id}}, $texi_entry; 15687 } 15688 } 15689 15690 15691 if ($Texi2HTML::Config::NEW_CROSSREF_STYLE) 15692 { 15693 foreach my $key (keys(%nodes)) 15694 { 15695 my $node = $nodes{$key}; 15696 next if ($node->{'external_node'}); 15697 $node->{'id'} = node_to_id($node->{'cross_manual_target'}); 15698 # FIXME if NEW_CROSSREF_STYLE false is it done for anchors? 15699 $node->{'target'} = $node->{'id'}; 15700 } 15701 } 15702 15703 # use %sections and %headings to modify also the headings 15704 foreach my $section (values(%sections), values(%headings)) 15705 { 15706 if ($Texi2HTML::Config::NEW_CROSSREF_STYLE and ($section->{'cross'} =~ /\S/)) 15707 { 15708 my $section_cross = $section->{'cross'}; 15709 if (defined($section->{'region'})) 15710 { # for headings appearing in special regions like @copying... 15711 $section_cross = "${target_prefix}-$section->{'region'}_$section_cross"; 15712 } 15713 $section->{'cross_manual_target'} = $section_cross; 15714 15715 my $index = 1; 15716 # $index > 0 should prevent integer overflow, hopefully 15717 while (exists($cross_reference_nodes{$section->{'cross_manual_target'}}) and $index > 0) 15718 { 15719 $section->{'cross_manual_target'} = $section_cross . "-" .$index; 15720 $index++; 15721 } 15722 my $texi_entry = $section->{'texi'}; 15723 $texi_entry .= "-".$index if ($index > 1); 15724 push @{$cross_reference_nodes{$section->{'cross_manual_target'}}}, $texi_entry; 15725 $section->{'id'} = node_to_id($section->{'cross_manual_target'}); 15726 } 15727 if ($Texi2HTML::Config::USE_NODE_TARGET and $section->{'with_node'}) 15728 { 15729 $section->{'target'} = $section->{'with_node'}->{'target'}; 15730 } 15731 else 15732 { 15733 $section->{'target'} = $section->{'id'}; 15734 } 15735 } 15736 15737 # construct human readable tocid 15738 foreach my $section (values(%sections)) 15739 { 15740 if ($Texi2HTML::Config::NEW_CROSSREF_STYLE and ($section->{'cross'} =~ /\S/)) 15741 { 15742 foreach my $toc_id (['tocid','toc'], ['stocid', 'stoc']) 15743 { 15744 my $id_string = $toc_id->[0]; 15745 my $prefix_string = $toc_id->[1]; 15746 my $cross_string = '-' . $section->{'cross_manual_target'}; 15747 $section->{$id_string} = $prefix_string . $cross_string; 15748 my $index = 1; 15749 # $index > 0 should prevent integer overflow, hopefully 15750 while (exists($cross_reference_nodes{$section->{$id_string}}) and $index > 0) 15751 { 15752 $section->{$id_string} = $prefix_string . "-" .$index .$cross_string; 15753 $index++; 15754 } 15755 my $texi_entry = $prefix_string.'-'.$section->{'texi'}; 15756 $texi_entry = $prefix_string .'-'.$index.'-'.$section->{'texi'} if ($index > 1); 15757 push @{$cross_reference_nodes{$section->{$id_string}}}, $texi_entry; 15758 } 15759 } 15760 } 15761 if (!$Texi2HTML::Config::NEW_CROSSREF_STYLE) 15762 { 15763 my $tocnr = 1; 15764 foreach my $element (@elements_list) 15765 { 15766 $element->{'tocid'} = 'TOC' . $tocnr; 15767 $tocnr++; 15768 } 15769 } 15770 15771 # Set file names 15772 # Find node file names and file names for nodes considered as elements 15773 my $node_as_top; 15774 if ($node_top) 15775 { 15776 $node_as_top = $node_top; 15777 } 15778 elsif ($element_top->{'with_node'}) 15779 { 15780 $node_as_top = $element_top->{'with_node'}; 15781 } 15782 else 15783 { 15784 $node_as_top = $node_first; 15785 } 15786 if ($node_as_top) 15787 { 15788 do_node_target_file($node_as_top, 'top'); 15789 } 15790 foreach my $key (keys(%nodes)) 15791 { 15792 my $node = $nodes{$key}; 15793 next if (defined($node_as_top) and ($node eq $node_as_top)); 15794 do_node_target_file($node,''); 15795 } 15796 15797 print STDERR "# split and set files\n" 15798 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15799 # find document nr and document file for sections and nodes. 15800 # Split according to Texi2HTML::Config::SPLIT. 15801 # find file and id for placed elements (anchors, index entries, headings) 15802 if ($Texi2HTML::Config::SPLIT) 15803 { 15804 $Texi2HTML::THISDOC{'split_level'} = $toplevel; 15805 my $doc_nr = -1; 15806 if ($Texi2HTML::Config::SPLIT eq 'section') 15807 { 15808 $Texi2HTML::THISDOC{'split_level'} = 2 if ($toplevel <= 2); 15809 } 15810 my $previous_file; 15811 foreach my $element (@elements_list) 15812 { 15813 print STDERR "# Splitting ($Texi2HTML::Config::SPLIT:$Texi2HTML::THISDOC{'split_level'}) $element->{'texi'}\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15814 my $new_file = 0; 15815 if ( 15816 ($Texi2HTML::Config::SPLIT eq 'node') or 15817 ( 15818 defined($element->{'level'}) and ($element->{'level'} <= $Texi2HTML::THISDOC{'split_level'}) 15819 ) 15820 ) 15821 { 15822 $new_file = 1; 15823 $doc_nr++; 15824 } 15825 $doc_nr = 0 if ($doc_nr < 0); # happens if first elements are nodes 15826 $element->{'doc_nr'} = $doc_nr; 15827 my $is_top = ''; 15828 $element->{'file'} = "${docu_name}_$doc_nr" 15829 . (defined($Texi2HTML::THISDOC{'extension'}) ? ".$Texi2HTML::THISDOC{'extension'}" : ''); 15830 my $use_node_file = 0; 15831 if ($element->{'top'} or (defined($element->{'with_node'}) and $element->{'with_node'} eq $element_top)) 15832 { # the top elements 15833 $is_top = "top"; 15834 $element->{'file'} = $docu_top; 15835 } 15836 elsif ($Texi2HTML::Config::NODE_FILES) 15837 { 15838 $use_node_file = 1; 15839 if ($new_file) 15840 { 15841 my $node = get_node($element) unless(exists($element->{'with_node'}) 15842 and $element->{'with_node'}->{'element_added'}); 15843 if ($node and defined($node->{'node_file'})) 15844 { 15845 $element->{'file'} = $node->{'node_file'}; 15846 } 15847 $previous_file = $element->{'file'}; 15848 } 15849 elsif($previous_file) 15850 { 15851 $element->{'file'} = $previous_file; 15852 } 15853 } 15854 do_element_targets($element, $use_node_file); 15855 print STDERR "# add_file($use_node_file) $element->{'file'} for $element->{'texi'}\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15856 add_file($element->{'file'}); 15857 } 15858 } 15859 else 15860 { # not split 15861 add_file($docu_doc); 15862 foreach my $element(@elements_list) 15863 { 15864 $element->{'file'} = $docu_doc; 15865 $element->{'doc_nr'} = 0; 15866 do_element_targets($element); 15867 } 15868 } 15869 # 'pathological' cases. No texinfo sectionning element at all or no 15870 # texi2html sectionning elements 15871 if (!@elements_list) 15872 { 15873 if (@all_elements) 15874 { 15875 foreach my $element (@all_elements) 15876 { 15877 #print STDERR "# no \@elements_list. Processing $element->{'texi'}\n"; 15878 $element->{'file'} = $docu_doc; 15879 $element->{'doc_nr'} = 0; 15880 push @{$element->{'place'}}, @{$element->{'current_place'}}; 15881 do_element_targets($element); 15882 } 15883 } 15884 else 15885 { 15886 $element_before_anything->{'file'} = $docu_doc; 15887 $element_before_anything->{'doc_nr'} = 0; 15888 do_element_targets($element_before_anything); 15889 } 15890 } 15891 # correct the id and file for the things placed in footnotes 15892 foreach my $place(@{$footnote_element->{'place'}}) 15893 { 15894 do_place_target_file ($place, $footnote_element, 'footnotes'); 15895 } 15896 # if setcontentsaftertitlepage is set, the contents should be associated 15897 # with the titlepage. That's wat is done there. 15898 push @$no_element_associated_place, $content_element{'contents'} 15899 if ($Texi2HTML::THISDOC{'DO_CONTENTS'} and $Texi2HTML::THISDOC{'setcontentsaftertitlepage'}); 15900 push @$no_element_associated_place, $content_element{'shortcontents'} 15901 if ($Texi2HTML::THISDOC{'DO_SCONTENTS'} and $Texi2HTML::THISDOC{'setshortcontentsaftertitlepage'}); 15902 # correct the id and file for the things placed in regions (copying...) 15903 foreach my $place(@$no_element_associated_place) 15904 { 15905#print STDERR "entry $place->{'entry'} texi $place->{'texi'}\n"; 15906 $place->{'element'} = $element_top if (exists($place->{'element'})); 15907 do_place_target_file ($place, $element_top, 'no_associated_element'); 15908 } 15909 foreach my $content_type(keys(%content_element)) 15910 { 15911 # with set*aftertitlepage, there will always be a href to Contents 15912 # or Overview pointing to the top element, even if there is no 15913 # titlepage outputed. 15914 if ((!defined($content_element{$content_type}->{'file'})) and $Texi2HTML::Config::INLINE_CONTENTS) 15915 { 15916 print STDERR "# No content $content_type\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15917 $content_element{$content_type} = undef; 15918 } 15919 } 15920 my ($toc_file, $stoc_file); 15921 $toc_file = $docu_toc; 15922 $stoc_file = $docu_stoc; 15923 if ($Texi2HTML::Config::INLINE_CONTENTS) 15924 { 15925 $toc_file = $content_element{'contents'}->{'file'} if (defined($content_element{'contents'})); 15926 $stoc_file = $content_element{'shortcontents'}->{'file'} if (defined($content_element{'shortcontents'})); 15927 } 15928 $Texi2HTML::THISDOC{'toc_file'} = $toc_file; 15929 $Texi2HTML::THISDOC{'stoc_file'} = $stoc_file; 15930 15931 print STDERR "# find NextFile and PrevFile\n" 15932 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 15933 foreach my $element (@elements_list) 15934 { 15935 my $current_element = $element; 15936 my $file = $current_element->{'file'}; 15937 my $previous_file; 15938 while ($current_element->{'back'}) 15939 { 15940#print STDERR "Back $current_element->{'texi'}\n"; 15941 $current_element = $current_element->{'back'}; 15942 if ($current_element->{'file'} ne $file) 15943 { 15944 $previous_file = $current_element->{'file'}; 15945 last; 15946 } 15947 } 15948 if (defined($previous_file)) 15949 { 15950 while ($current_element->{'back'}) 15951 { 15952 if ($current_element->{'back'}->{'file'} ne $previous_file) 15953 { 15954 last; 15955 } 15956 $current_element = $current_element->{'back'}; 15957 } 15958 $element->{'prevfile'} = $current_element; 15959 } 15960 15961 $current_element = $element; 15962 while ($current_element->{'forward'}) 15963 { 15964#print STDERR "Fwd $current_element->{'texi'}\n"; 15965 $current_element = $current_element->{'forward'}; 15966 if ($current_element->{'file'} ne $file) 15967 { 15968 $element->{'nextfile'} = $current_element; 15969 } 15970 } 15971 } 15972 # convert directions in direction with first letter in all caps, to be 15973 # consistent with the convention used in the .init file. 15974 foreach my $element (@elements_list) 15975 { 15976 foreach my $direction (@element_directions) 15977 { 15978 my $direction_no_caps = $direction; 15979 $direction_no_caps =~ tr/A-Z/a-z/; 15980 $element->{$direction} = $element->{$direction_no_caps}; 15981 } 15982 } 15983 15984 ########################### debug prints 15985 foreach my $file (keys(%files)) 15986 { 15987 last unless ($T2H_DEBUG & $DEBUG_ELEMENTS); 15988 print STDERR "$file: counter $files{$file}->{'counter'}\n"; 15989 } 15990 my $output_elements = \@elements_list; 15991 if (!scalar(@elements_list) and ($T2H_DEBUG & $DEBUG_ELEMENTS)) 15992 { 15993 print STDERR "No elements_list, no texi2html elements\n"; 15994 $output_elements = \@all_elements; 15995 } 15996 foreach my $element ((@$output_elements, $footnote_element)) 15997 { 15998 last unless ($T2H_DEBUG & $DEBUG_ELEMENTS); 15999 my $is_toplevel = 'not toplevel'; 16000 $is_toplevel = 'toplevel' if ($element->{'toplevel'}); 16001 print STDERR "$element "; 16002 if ($element->{'node'}) 16003 { 16004 print STDERR "node($element->{'id'}, toc_level $element->{'toc_level'}, $is_toplevel, doc_nr $element->{'doc_nr'}($element->{'file'})) $element->{'texi'}:\n"; 16005 print STDERR " section_ref: $element->{'section_ref'}->{'texi'}\n" if (defined($element->{'section_ref'})); 16006 print STDERR " with_section: $element->{'with_section'}->{'texi'}\n" if (defined($element->{'with_section'})); 16007 } 16008 elsif ($element->{'footnote'}) 16009 { 16010 print STDERR "footnotes($element->{'id'}, file $element->{'file'})\n"; 16011 } 16012 else 16013 { 16014 my $number = "UNNUMBERED"; 16015 $number = $element->{'number'} if ($element->{'number'}); 16016 print STDERR "$number ($element->{'id'}, $is_toplevel, level $element->{'level'}-$element->{'toc_level'}, doc_nr $element->{'doc_nr'}($element->{'file'})) $element->{'texi'}:\n"; 16017 print STDERR " with_node: $element->{'with_node'}->{'texi'}\n" if (defined($element->{'with_node'})); 16018 print STDERR " node_ref: $element->{'node_ref'}->{'texi'}\n" if (defined($element->{'node_ref'})); 16019 } 16020 16021 if (!$element->{'footnote'}) 16022 { 16023 if (!defined($files{$element->{'file'}})) 16024 { 16025 die "Bug: files{\$element->{'file'}} undef element $element->{'texi'}, file $element->{'file'}."; 16026 } 16027 print STDERR " file: $element->{'file'} $files{$element->{'file'}}, counter $files{$element->{'file'}}->{'counter'}\n"; 16028 } 16029 print STDERR " TOP($toplevel) " if ($element->{'top'}); 16030 print STDERR " u: $element->{'up'}->{'texi'}\n" if (defined($element->{'up'})); 16031 print STDERR " ch: $element->{'child'}->{'texi'}\n" if (defined($element->{'child'})); 16032 print STDERR " fb: $element->{'fastback'}->{'texi'}\n" if (defined($element->{'fastback'})); 16033 print STDERR " b: $element->{'back'}->{'texi'}\n" if (defined($element->{'back'})); 16034 print STDERR " p: $element->{'prev'}->{'texi'}\n" if (defined($element->{'prev'})); 16035 print STDERR " u: $element->{'sectionup'}->{'texi'}\n" if (defined($element->{'sectionup'})); 16036 print STDERR " n: $element->{'sectionnext'}->{'texi'}\n" if (defined($element->{'sectionnext'})); 16037 print STDERR " t_n: $element->{'toplevelnext'}->{'texi'}\n" if (defined($element->{'toplevelnext'})); 16038 print STDERR " t_p: $element->{'toplevelprev'}->{'texi'}\n" if (defined($element->{'toplevelprev'})); 16039 print STDERR " n_u: $element->{'nodeup'}->{'texi'}\n" if (defined($element->{'nodeup'})); 16040 print STDERR " f: $element->{'forward'}->{'texi'}\n" if (defined($element->{'forward'})); 16041 print STDERR " follow: $element->{'following'}->{'texi'}\n" if (defined($element->{'following'})); 16042 print STDERR " m_p: $element->{'menu_prev'}->{'texi'}\n" if (defined($element->{'menu_prev'})); 16043 print STDERR " m_n: $element->{'menu_next'}->{'texi'}\n" if (defined($element->{'menu_next'})); 16044 print STDERR " m_u: $element->{'menu_up'}->{'texi'}\n" if (defined($element->{'menu_up'})); 16045 print STDERR " m_ch: $element->{'menu_child'}->{'texi'}\n" if (defined($element->{'menu_child'})); 16046 print STDERR " ff: $element->{'fastforward'}->{'texi'}\n" if (defined($element->{'fastforward'})); 16047 print STDERR " n_f: $element->{'nextfile'}->{'texi'}\n" if (defined($element->{'nextfile'})); 16048 print STDERR " p_f: $element->{'prevfile'}->{'texi'}\n" if (defined($element->{'prevfile'})); 16049 my $section_childs = ''; 16050 if (defined($element->{'section_childs'})) 16051 { 16052 foreach my $child (@{$element->{'section_childs'}}) 16053 { 16054 $section_childs .= "$child->{'texi'}|"; 16055 } 16056 } 16057 print STDERR " s_chs: $section_childs\n" if ($section_childs ne ''); 16058 my $node_childs = ''; 16059 if (defined($element->{'node_childs'})) 16060 { 16061 foreach my $child (@{$element->{'node_childs'}}) 16062 { 16063 $node_childs .= "$child->{'texi'}|"; 16064 } 16065 } 16066 print STDERR " n_chs: $node_childs\n" if ($node_childs ne ''); 16067 16068 if (defined($element->{'menu_up_hash'})) 16069 { 16070 print STDERR " parent nodes:\n"; 16071 foreach my $menu_up (keys%{$element->{'menu_up_hash'}}) 16072 { 16073 print STDERR " $menu_up ($element->{'menu_up_hash'}->{$menu_up})\n"; 16074 } 16075 } 16076 print STDERR " places: $element->{'place'}\n"; 16077 foreach my $place(@{$element->{'place'}}) 16078 { 16079 if (!$place->{'entry'} and !$place->{'float'} and !$place->{'texi'} and !$place->{'contents'} and !$place->{'shortcontents'} and (!defined($place->{'command'} or $place->{'command'} ne 'printindex'))) 16080 { 16081 print STDERR "BUG: unknown placed stuff ========\n"; 16082 foreach my $key (keys(%$place)) 16083 { 16084 print STDERR "$key: $place->{$key}\n"; 16085 } 16086 print STDERR "==================================\n"; 16087 } 16088 elsif ($place->{'entry'}) 16089 { 16090 print STDERR " index($place): $place->{'entry'} ($place->{'id'}, $place->{'file'})\n"; 16091 } 16092 elsif ($place->{'anchor'}) 16093 { 16094 print STDERR " anchor: $place->{'texi'} ($place->{'id'}, $place->{'file'})\n"; 16095 } 16096 elsif ($place->{'float'}) 16097 { 16098 if (defined($place->{'texi'})) 16099 { 16100 print STDERR " float($place): $place->{'texi'} ($place->{'id'}, $place->{'file'})\n"; 16101 } 16102 else 16103 { 16104 print STDERR " float($place): NO LABEL ($place->{'id'}, $place->{'file'})\n"; 16105 } 16106 } 16107 elsif ($place->{'contents'}) 16108 { 16109 print STDERR " contents\n"; 16110 } 16111 elsif ($place->{'shortcontents'}) 16112 { 16113 print STDERR " shortcontents\n"; 16114 } 16115 elsif (defined($place->{'command'}) and $place->{'command'} eq 'printindex') 16116 { 16117 print STDERR " printindex $place->{'name'}\n"; 16118 } 16119 else 16120 { 16121 print STDERR " heading: $place->{'texi'} ($place->{'id'}, $place->{'file'})\n"; 16122 } 16123 } 16124 } 16125 ########################### end debug prints 16126} 16127 16128sub add_file($) 16129{ 16130 my $file = shift; 16131 if ($files{$file}) 16132 { 16133 $files{$file}->{'counter'}++; 16134 } 16135 else 16136 { 16137 $files{$file} = { 16138 #'type' => 'section', 16139 'counter' => 1, 16140 'relative_foot_num' => 0, 16141 'foot_lines' => [] 16142 }; 16143 } 16144} 16145 16146# find parent element which is a top element, or a node within the top section 16147sub get_top($) 16148{ 16149 my $element = shift; 16150 my $up = $element; 16151 while (!$up->{'toplevel'} and !$up->{'top'}) 16152 { 16153 $up = $up->{'sectionup'}; 16154 if (!defined($up)) 16155 { 16156 # If there is no section, it is normal not to have toplevel element, 16157 # and it is also the case if there is a low level element before 16158 # a top level element 16159 return undef; 16160 } 16161 } 16162 return $up; 16163} 16164 16165sub get_node($) 16166{ 16167 my $element = shift; 16168 return undef if (!defined($element)); 16169 return $element if ($element->{'node'}); 16170 return $element->{'with_node'} if ($element->{'with_node'}); 16171 return $element; 16172} 16173 16174sub do_section_names($$) 16175{ 16176 my $number = shift; 16177 my $section = shift; 16178 #$section->{'name'} = substitute_line($section->{'texi'}); 16179 my $texi = &$Texi2HTML::Config::heading_texi($section->{'tag'}, $section->{'texi'}, $section->{'number'}); 16180 $section->{'text'} = substitute_line($texi); 16181 $section->{'text_nonumber'} = substitute_line($section->{'texi'}); 16182 # backward compatibility 16183 $section->{'name'} = $section->{'text_nonumber'}; 16184 $section->{'no_texi'} = remove_texi($texi); 16185 $section->{'simple_format'} = simple_format(undef,undef,$texi); 16186 $section->{'heading_texi'} = $texi; 16187} 16188 16189# get the html names from the texi for all elements 16190sub do_names() 16191{ 16192 print STDERR "# Doing ". scalar(keys(%nodes)) . " nodes, ". 16193 scalar(keys(%sections)) . " sections, " . 16194 scalar(keys(%headings)) . " headings in ". $#elements_list . 16195 " elements\n" if ($T2H_DEBUG); 16196 # for nodes and anchors we haven't any state defined 16197 # This seems right, however, as we don't want @refs or @footnotes 16198 # or @anchors within nodes, section commands or anchors. 16199 foreach my $node (keys(%nodes)) 16200 { 16201 my $texi = &$Texi2HTML::Config::heading_texi($nodes{$node}->{'tag'}, 16202 $nodes{$node}->{'texi'}, undef); 16203 $nodes{$node}->{'text'} = substitute_line ($texi, {'code_style' => 1}); 16204 $nodes{$node}->{'text_nonumber'} = $nodes{$node}->{'text'}; 16205 # backward compatibility -> maybe used to have the name without code_style ? 16206 $nodes{$node}->{'name'} = substitute_line($texi); 16207 $nodes{$node}->{'no_texi'} = remove_texi($texi); 16208 $nodes{$node}->{'simple_format'} = simple_format(undef, undef, $texi); 16209 $nodes{$node}->{'heading_texi'} = $texi; 16210 # FIXME : what to do if $nodes{$node}->{'external_node'} and 16211 # $nodes{$node}->{'seen'} 16212 } 16213 foreach my $number (keys(%sections)) 16214 { 16215 do_section_names($number, $sections{$number}); 16216 } 16217 foreach my $number (keys(%headings)) 16218 { 16219 do_section_names($number, $headings{$number}); 16220 } 16221 print STDERR "# Names done\n" if ($T2H_DEBUG); 16222} 16223 16224 16225#+++############################################################################ 16226# # 16227# Stuff related to Index generation # 16228# # 16229#---############################################################################ 16230 16231my $index_entries; # ref on a hash for the index entries 16232 16233# called during pass_structure 16234sub enter_index_entry($$$$$$$) 16235{ 16236 my $prefix = shift; 16237 my $line_nr = shift; 16238 my $entry = shift; 16239 my $place = shift; 16240 my $element = shift; 16241 my $command = shift; 16242 my $region = shift; 16243 unless ($index_prefix_to_name{$prefix}) 16244 { 16245 echo_error ("Undefined index command: ${prefix}index", $line_nr); 16246 $entry = ''; 16247 } 16248 if (!exists($element->{'tag'}) and !$element->{'footnote'}) 16249 { 16250 echo_warn ("Index entry before document: \@${prefix}index $entry", $line_nr); 16251 } 16252 #print STDERR "($region) $key" if $region; 16253 $entry =~ s/\s+$//; 16254 $entry =~ s/^\s*//; 16255 # The $key is mostly usefull for alphabetical sorting. 16256 # beware that an entry beginning with a format will lead to an empty 16257 # key, but with some texi. 16258 # FIXME this should be done later, during formatting. 16259 my $key = remove_texi($entry); 16260 my $id; 16261 16262 my $index_entry_hidden = (($place eq $no_element_associated_place) or $region); 16263 # don't add a specific index target if after a section or the index 16264 # entry is in @copying or the like 16265 unless ($index_entry_hidden) 16266 { 16267 $id = 'IDX' . ++$document_idx_num; 16268 } 16269 my $target = $id; 16270 # entry will later be in @code for code-like index entry. texi stays 16271 # the same. 16272 my $index_entry = { 16273 'entry' => $entry, 16274 'key' => $key, 16275 'texi' => $entry, 16276 'element' => $element, 16277 'prefix' => $prefix, 16278 'id' => $id, 16279 'target' => $target, 16280 'command' => $command, 16281 }; 16282 16283 print STDERR "# enter \@$command ${prefix}index($key) [$entry] with id $id ($index_entry)\n" 16284 if ($T2H_DEBUG & $DEBUG_INDEX); 16285 if ($entry =~ /^\s*$/) 16286 { 16287 # makeinfo doesn't warn, but texi2dvi breaks. 16288 echo_warn("Empty index entry for \@$command",$line_nr); 16289 # don't add the index entry to the list of index entries used for index 16290 # entry formatting,if the index entry appears in a region like copying 16291 push @index_labels, $index_entry unless $index_entry_hidden; 16292 return; 16293 } 16294 while (exists $index_entries->{$prefix}->{$key}) 16295 { 16296 $key .= ' '; 16297 } 16298 $index_entries->{$prefix}->{$key} = $index_entry; 16299 push @$place, $index_entry; 16300 # don't add the index entry to the list of index entries used for index 16301 # entry formatting,if the index entry appears in a region like copying 16302 push @index_labels, $index_entry unless ($index_entry_hidden); 16303} 16304 16305# sort according to cmp if both $a and $b are alphabetical or non alphabetical, 16306# otherwise the alphabetical is ranked first 16307sub by_alpha 16308{ 16309 if ($a =~ /^[A-Za-z]/) 16310 { 16311 if ($b =~ /^[A-Za-z]/) 16312 { 16313 return lc($a) cmp lc($b); 16314 } 16315 else 16316 { 16317 return 1; 16318 } 16319 } 16320 elsif ($b =~ /^[A-Za-z]/) 16321 { 16322 return -1; 16323 } 16324 else 16325 { 16326 return lc($a) cmp lc($b); 16327 } 16328} 16329 16330my %indices; # hash of indices names containing 16331 #[ $pages, $entries ] (page indices and 16332 # raw index entries) 16333 16334# return the page and the entries. Cache the result in %indices. 16335sub get_index($;$$) 16336{ 16337 my $index_name = shift; 16338 my $line_nr = shift; 16339 my $no_warn = shift; 16340 16341 #return (@{$indices{$index_name}}) if ($indices{$index_name}); 16342 return ($indices{$index_name}) if ($indices{$index_name}); 16343 16344 unless (exists($index_names{$index_name})) 16345 { 16346 echo_error ("Bad index name: $index_name", $line_nr) unless ($no_warn); 16347 return; 16348 } 16349 # add the index name itself to the index names searched for index 16350 # prefixes. Only those found associated by synindex or syncodeindex are 16351 # already there (unless this code has already been called). 16352 if ($index_names{$index_name}->{'code'}) 16353 { 16354 $index_names{$index_name}->{'associated_indices_code'}->{$index_name} = 1; 16355 } 16356 else 16357 { 16358 $index_names{$index_name}->{'associated_indices'}->{$index_name} = 1; 16359 } 16360 16361 # find all the index names associated with the prefixes and then 16362 # all the entries associated with each prefix 16363 my $entries = {}; 16364 foreach my $associated_indice(keys %{$index_names{$index_name}->{'associated_indices'}}) 16365 { 16366 foreach my $prefix(@{$index_names{$associated_indice}->{'prefix'}}) 16367 { 16368 foreach my $key (keys %{$index_entries->{$prefix}}) 16369 { 16370 $entries->{$key} = $index_entries->{$prefix}->{$key}; 16371 } 16372 } 16373 } 16374 16375 foreach my $associated_indice (keys %{$index_names{$index_name}->{'associated_indices_code'}}) 16376 { 16377 unless (exists ($index_names{$index_name}->{'associated_indices'}->{$associated_indice})) 16378 { 16379 foreach my $prefix (@{$index_names{$associated_indice}->{'prefix'}}) 16380 { 16381 foreach my $key (keys (%{$index_entries->{$prefix}})) 16382 { 16383 $entries->{$key} = $index_entries->{$prefix}->{$key}; 16384 # use @code for code style index entry 16385 $entries->{$key}->{'entry'} = "\@code{$entries->{$key}->{entry}}"; 16386 } 16387 } 16388 } 16389 } 16390 16391 return unless %$entries; 16392 $indices{$index_name} = $entries; 16393 return $entries; 16394} 16395 16396# these variables are global, so great care should be taken with 16397# state->{'multiple_state'}, ->{'region'}, ->{'region_pass'} and 16398# {'outside_document'}. 16399my $global_head_num = 0; # heading index. it is global for the main doc, 16400 # and taken from the state if in multiple_pass. 16401my $global_foot_num = 0; 16402my $global_relative_foot_num = 0; 16403my @foot_lines = (); # footnotes 16404my $copying_comment = ''; # comment constructed from text between 16405 # @copying and @end copying with licence 16406my %acronyms_like = (); # acronyms or similar commands associated texts 16407 # the key are the commands, the values are 16408 # hash references associating shorthands to 16409 # texts. 16410 16411sub fill_state($) 16412{ 16413 my $state = shift; 16414 $state->{'preformatted'} = 0 unless exists($state->{'preformatted'}); 16415 $state->{'code_style'} = 0 unless exists($state->{'code_style'}); 16416 $state->{'math_style'} = 0 unless exists($state->{'math_style'}); 16417 $state->{'keep_texi'} = 0 unless exists($state->{'keep_texi'}); 16418 $state->{'keep_nr'} = 0 unless exists($state->{'keep_nr'}); 16419 $state->{'detailmenu'} = 0 unless exists($state->{'detailmenu'}); # number of opened detailed menus 16420 $state->{'sec_num'} = 0 unless exists($state->{'sec_num'}); 16421 $state->{'paragraph_style'} = [ '' ] unless exists($state->{'paragraph_style'}); 16422 $state->{'preformatted_stack'} = [ '' ] unless exists($state->{'preformatted_stack'}); 16423 $state->{'menu'} = 0 unless exists($state->{'menu'}); 16424 $state->{'command_stack'} = [] unless exists($state->{'command_stack'}); 16425 $state->{'quotation_stack'} = [] unless exists($state->{'quotation_stack'}); 16426 # if there is no $state->{'element'} the first element is used 16427 if ((!$state->{'element'} or $state->{'element'}->{'before_anything'}) and (@elements_list)) 16428 { 16429 $state->{'element'} = $elements_list[0]; 16430 } 16431 $state->{'element'} = {'file' => $docu_doc, 'texi' => 'VIRTUAL ELEMENT'} if (!$state->{'element'}); 16432 #$state->{'element'} = $elements_list[0] unless ((!@elements_list) or (exists($state->{'element'}) and !$state->{'element'}->{'before_anything'})); 16433} 16434 16435sub do_element_directions ($) 16436{ 16437 my $this_element = shift; 16438 #print STDERR "Doing hrefs for $this_element->{'texi'} First "; 16439 $Texi2HTML::HREF{'First'} = href($element_first, $this_element->{'file'}); 16440 #print STDERR "Last "; 16441 $Texi2HTML::HREF{'Last'} = href($element_last, $this_element->{'file'}); 16442 #print STDERR "Index "; 16443 $Texi2HTML::HREF{'Index'} = href($element_chapter_index, $this_element->{'file'}) if (defined($element_chapter_index)); 16444 #print STDERR "Top "; 16445 $Texi2HTML::HREF{'Top'} = href($element_top, $this_element->{'file'}); 16446 if ($Texi2HTML::Config::INLINE_CONTENTS) 16447 { 16448 $Texi2HTML::HREF{'Contents'} = href($content_element{'contents'}, $this_element->{'file'}); 16449 $Texi2HTML::HREF{'Overview'} = href($content_element{'shortcontents'}, $this_element->{'file'}); 16450 } 16451 else 16452 { 16453 $Texi2HTML::HREF{'Contents'} = file_target_href($Texi2HTML::THISDOC{'toc_file'}, $this_element->{'file'}, $content_element{'contents'}->{'target'}) if (@{$Texi2HTML::TOC_LINES} and defined($content_element{'contents'})); 16454 $Texi2HTML::HREF{'Overview'} = file_target_href($Texi2HTML::THISDOC{'stoc_file'}, $this_element->{'file'}, $content_element{'shortcontents'}->{'target'}) if (@{$Texi2HTML::OVERVIEW} and defined($content_element{'shortcontents'})); 16455 } 16456 if ($Texi2HTML::THISDOC{'do_about'}) 16457 { 16458 $Texi2HTML::HREF{'About'} = file_target_href($docu_about, $this_element->{'file'}, $Texi2HTML::Config::misc_pages_targets{'About'}); 16459 } 16460 $Texi2HTML::HREF{'Footnotes'} = file_target_href($docu_foot, $this_element->{'file'}, $Texi2HTML::Config::misc_pages_targets{'Footnotes'}); 16461 foreach my $direction (@element_directions) 16462 { 16463 my $elem = $this_element->{$direction}; 16464 $Texi2HTML::NODE{$direction} = undef; 16465 $Texi2HTML::HREF{$direction} = undef; 16466 $Texi2HTML::NAME{$direction} = undef; 16467 #print STDERR "$direction \n"; 16468 next unless (defined($elem)); 16469 if ($elem->{'node'} or $elem->{'external_node'} or !$elem->{'seen'}) 16470 { 16471 $Texi2HTML::NODE{$direction} = $elem->{'text'}; 16472 } 16473 elsif ($elem->{'with_node'}) 16474 { 16475 $Texi2HTML::NODE{$direction} = $elem->{'with_node'}->{'text'}; 16476 } 16477 if (!$elem->{'seen'}) 16478 { 16479 $Texi2HTML::HREF{$direction} = do_external_href($elem->{'texi'}); 16480 } 16481 else 16482 { 16483 $Texi2HTML::HREF{$direction} = href($elem, $this_element->{'file'}); 16484 } 16485 $Texi2HTML::NAME{$direction} = $elem->{'text'}; 16486 $Texi2HTML::NO_TEXI{$direction} = $elem->{'no_texi'}; 16487 $Texi2HTML::SIMPLE_TEXT{$direction} = $elem->{'simple_format'}; 16488 #print STDERR "$direction ($this_element->{'texi'}): \n NO_TEXI: $Texi2HTML::NO_TEXI{$direction}\n NAME $Texi2HTML::NAME{$direction}\n NODE $Texi2HTML::NODE{$direction}\n HREF $Texi2HTML::HREF{$direction}\n\n"; 16489 } 16490 #print STDERR "\nDone hrefs for $this_element->{'texi'}\n"; 16491} 16492 16493sub open_out_file($) 16494{ 16495 my $new_file = shift; 16496 my $do_page_head = 0; 16497 if ($files{$new_file}->{'filehandle'}) 16498 { 16499 $Texi2HTML::THISDOC{'FH'} = $files{$new_file}->{'filehandle'}; 16500 } 16501 else 16502 { 16503 $Texi2HTML::THISDOC{'FH'} = open_out("$docu_rdir$new_file"); 16504#print STDERR "OPEN $docu_rdir$file, $Texi2HTML::THISDOC{'FH'}". scalar($Texi2HTML::THISDOC{'FH'})."\n"; 16505 $files{$new_file}->{'filehandle'} = $Texi2HTML::THISDOC{'FH'}; 16506 $do_page_head = 1; 16507 } 16508 return $do_page_head; 16509} 16510 16511sub pass_text($$) 16512{ 16513 my $doc_lines = shift; 16514 my $doc_numbers = shift; 16515 my %state; 16516 fill_state(\%state); 16517 my @stack; 16518 my $text; 16519 my $doc_nr; 16520 my $in_doc = 0; 16521 my @text =(); 16522 my $one_section = 1 if (@elements_list <= 1); 16523 16524 push_state(\%state); 16525 16526 set_special_names(); 16527 # We set titlefont only if the titlefont appeared in the top element 16528 if (defined($element_top->{'titlefont'})) 16529 { 16530 $value{'_titlefont'} = $element_top->{'titlefont'}; 16531 } 16532 16533 # prepare %Texi2HTML::THISDOC 16534 $Texi2HTML::THISDOC{'command_stack'} = $state{'command_stack'}; 16535 16536# $Texi2HTML::THISDOC{'settitle_texi'} = $value{'_settitle'}; 16537 $Texi2HTML::THISDOC{'fulltitle_texi'} = ''; 16538 $Texi2HTML::THISDOC{'title_texi'} = ''; 16539 foreach my $possible_fulltitle (('_settitle', '_title', '_shorttitlepage', '_titlefont')) 16540 { 16541 if ($value{$possible_fulltitle} ne '') 16542 { 16543 $Texi2HTML::THISDOC{'fulltitle_texi'} = $value{$possible_fulltitle}; 16544 last; 16545 } 16546 } 16547# foreach my $possible_title_texi ($value{'_settitle'}, $Texi2HTML::THISDOC{'fulltitle_texi'}) 16548# { 16549# if ($possible_title_texi ne '') 16550# { 16551# $Texi2HTML::THISDOC{'title_texi'} = $possible_title_texi; 16552# last; 16553# } 16554# } 16555 16556# $Texi2HTML::THISDOC{'fulltitle_texi'} = $value{'_title'} || $value{'_settitle'} || $value{'_shorttitlepage'} || $value{'_titlefont'}; 16557# $Texi2HTML::THISDOC{'title_texi'} = $value{'_title'} || $value{'_settitle'} || $value{'_shorttitlepage'} || $value{'_titlefont'}; 16558 foreach my $texi_cmd (('shorttitlepage', 'settitle', 'author', 'title', 16559 'titlefont', 'subtitle')) 16560 { 16561 $Texi2HTML::THISDOC{$texi_cmd . '_texi'} = $value{'_' . $texi_cmd}; 16562 } 16563 foreach my $doc_thing (('shorttitlepage', 'settitle', 'author', 16564 'titlefont', 'subtitle', 'title', 'fulltitle')) 16565 { 16566 my $thing_texi = $Texi2HTML::THISDOC{$doc_thing . '_texi'}; 16567 $Texi2HTML::THISDOC{$doc_thing} = substitute_line($thing_texi); 16568 $Texi2HTML::THISDOC{$doc_thing . '_no_texi'} = 16569 remove_texi($thing_texi); 16570 $Texi2HTML::THISDOC{$doc_thing . '_simple_format'} = 16571 simple_format(undef, undef, $thing_texi); 16572 } 16573 16574 # find Top name 16575 my $element_top_text = ''; 16576 my $top_no_texi = ''; 16577 my $top_simple_format = ''; 16578 my $top_name; 16579 if ($element_top and $element_top->{'text'} and (!$node_top or ($element_top ne $node_top))) 16580 { 16581 $element_top_text = $element_top->{'text'}; 16582 $top_no_texi = $element_top->{'no_texi'}; 16583 $top_simple_format = $element_top->{'simple_format'}; 16584 } 16585 foreach my $possible_top_name ($Texi2HTML::Config::TOP_HEADING, 16586 $element_top_text, $Texi2HTML::THISDOC{'fulltitle'}, 16587 #$Texi2HTML::THISDOC{'shorttitle'}, 16588 &$I('Top')) 16589 { 16590 if (defined($possible_top_name) and $possible_top_name ne '') 16591 { 16592 $top_name = $possible_top_name; 16593 last; 16594 } 16595 } 16596 foreach my $possible_top_no_texi ($Texi2HTML::Config::TOP_HEADING, 16597 $top_no_texi, $Texi2HTML::THISDOC{'fulltitle_no_texi'}, 16598 #$Texi2HTML::THISDOC{'shorttitle_no_texi'}, 16599 &$I('Top',{},{'remove_texi' => 1})) 16600 { 16601 if (defined($possible_top_no_texi) and $possible_top_no_texi ne '') 16602 { 16603 $top_no_texi = $possible_top_no_texi; 16604 last; 16605 } 16606 } 16607 16608 foreach my $possible_top_simple_format ($top_simple_format, 16609 $Texi2HTML::THISDOC{'fulltitle_simple_format'}, 16610 #$Texi2HTML::THISDOC{'shorttitle_simple_format'}, 16611 &$I('Top',{}, {'simple_format' => 1})) 16612 { 16613 if (defined($possible_top_simple_format) and $possible_top_simple_format ne '') 16614 { 16615 $top_simple_format = $possible_top_simple_format; 16616 last; 16617 } 16618 } 16619 16620 16621# my $top_name = $Texi2HTML::Config::TOP_HEADING || $element_top_text || $Texi2HTML::THISDOC{'title'} || $Texi2HTML::THISDOC{'shorttitle'} || &$I('Top'); 16622 16623 if ($Texi2HTML::THISDOC{'fulltitle_texi'} eq '') 16624 { 16625 $Texi2HTML::THISDOC{'fulltitle_texi'} = &$I('Untitled Document',{}, 16626 {'keep_texi' => 1}); 16627 } 16628 #$Texi2HTML::THISDOC{'title_texi'} = $Texi2HTML::THISDOC{'settitle_texi'}; 16629 #$Texi2HTML::THISDOC{'title_texi'} = $Texi2HTML::THISDOC{'fulltitle_texi'} 16630 # if ($Texi2HTML::THISDOC{'title_texi'} eq ''); 16631 16632 foreach my $doc_thing (('fulltitle')) # title 16633 { 16634 my $thing_texi = $Texi2HTML::THISDOC{$doc_thing . '_texi'}; 16635 $Texi2HTML::THISDOC{$doc_thing} = substitute_line($thing_texi); 16636 $Texi2HTML::THISDOC{$doc_thing . '_no_texi'} = 16637 remove_texi($thing_texi); 16638 $Texi2HTML::THISDOC{$doc_thing . '_simple_format'} = 16639 simple_format(undef, undef, $thing_texi); 16640 } 16641 16642 $Texi2HTML::THISDOC{'program'} = $THISPROG; 16643 $Texi2HTML::THISDOC{'program_homepage'} = $T2H_HOMEPAGE; 16644 $Texi2HTML::THISDOC{'program_authors'} = $T2H_AUTHORS; 16645 $Texi2HTML::THISDOC{'user'} = $T2H_USER; 16646 $Texi2HTML::THISDOC{'user'} = $Texi2HTML::Config::USER if (defined($Texi2HTML::Config::USER)); 16647 $Texi2HTML::THISDOC{'authors'} = [] if (!defined($Texi2HTML::THISDOC{'authors'})); 16648 $Texi2HTML::THISDOC{'subtitles'} = [] if (!defined($Texi2HTML::THISDOC{'subtitles'})); 16649 # backward compatibility, titles should go away 16650 $Texi2HTML::THISDOC{'titles'} = [] if (!defined($Texi2HTML::THISDOC{'titles'})); 16651 foreach my $command (('authors', 'subtitles', 'titles')) 16652 { 16653 my $i; 16654 for ($i = 0; $i < $#{$Texi2HTML::THISDOC{$command}} + 1; $i++) 16655 { 16656 chomp ($Texi2HTML::THISDOC{$command}->[$i]); 16657 $Texi2HTML::THISDOC{$command}->[$i] = substitute_line($Texi2HTML::THISDOC{$command}->[$i]); 16658 #print STDERR "$command:$i: $Texi2HTML::THISDOC{$command}->[$i]\n"; 16659 } 16660 } 16661 16662 $Texi2HTML::THISDOC{'do_about'} = 1 unless (defined($Texi2HTML::THISDOC{'do_about'}) or $one_section or (not $Texi2HTML::Config::SPLIT and not $Texi2HTML::Config::SECTION_NAVIGATION)); 16663 16664 $Texi2HTML::NAME{'First'} = $element_first->{'text'}; 16665 $Texi2HTML::NAME{'Last'} = $element_last->{'text'}; 16666 $Texi2HTML::NAME{'Top'} = $top_name; 16667 $Texi2HTML::NAME{'Index'} = $element_chapter_index->{'text'} if (defined($element_chapter_index)); 16668 $Texi2HTML::NAME{'Index'} = $Texi2HTML::Config::INDEX_CHAPTER if ($Texi2HTML::Config::INDEX_CHAPTER ne ''); 16669 16670 $Texi2HTML::NO_TEXI{'First'} = $element_first->{'no_texi'}; 16671 $Texi2HTML::NO_TEXI{'Last'} = $element_last->{'no_texi'}; 16672 $Texi2HTML::NO_TEXI{'Top'} = $top_no_texi; 16673 $Texi2HTML::NO_TEXI{'Index'} = $element_chapter_index->{'no_texi'} if (defined($element_chapter_index)); 16674 $Texi2HTML::SIMPLE_TEXT{'First'} = $element_first->{'simple_format'}; 16675 $Texi2HTML::SIMPLE_TEXT{'Last'} = $element_last->{'simple_format'}; 16676 $Texi2HTML::SIMPLE_TEXT{'Top'} = $top_simple_format; 16677 $Texi2HTML::SIMPLE_TEXT{'Index'} = $element_chapter_index->{'simple_format'} if (defined($element_chapter_index)); 16678 16679 # FIXME we do the regions formatting here, even if they never appear. 16680 # so we should be very carefull to take into accout 'outside_document' to 16681 # avoid messing with information that has to be set in the main document. 16682 # also the error messages will appear even though the corresponding 16683 # texinfo is never used. 16684 my ($region_text, $region_no_texi, $region_simple_format); 16685 ($region_text, $region_no_texi, $region_simple_format) = do_special_region_lines('documentdescription'); 16686 &$Texi2HTML::Config::documentdescription($region_lines{'documentdescription'},$region_text, $region_no_texi, $region_simple_format); 16687 16688 # do copyright notice inserted in comment at the beginning of the files 16689 ($region_text, $region_no_texi, $region_simple_format) = do_special_region_lines('copying'); 16690 $copying_comment = &$Texi2HTML::Config::copying_comment($region_lines{'copying'}, $region_text, $region_no_texi, $region_simple_format); 16691 16692 $Texi2HTML::THISDOC{'copying_comment'} = $copying_comment; 16693 # must be after toc_body, but before titlepage 16694 foreach my $command ('contents', 'shortcontents') 16695 { 16696 next if (!defined($content_element{$command})); 16697 my $toc_lines = &$Texi2HTML::Config::inline_contents(undef, $command, $content_element{$command}); 16698 @{$Texi2HTML::THISDOC{'inline_contents'}->{$command}} = @$toc_lines if (defined($toc_lines)); 16699 } 16700 16701 ($region_text, $region_no_texi, $region_simple_format) = do_special_region_lines('titlepage'); 16702 16703 &$Texi2HTML::Config::titlepage($region_lines{'titlepage'}, $region_text, $region_no_texi, $region_simple_format); 16704 16705 &$Texi2HTML::Config::init_out(); 16706 16707 ############################################################################ 16708 # print frame and frame toc file 16709 # 16710 if ( $Texi2HTML::Config::FRAMES ) 16711 { 16712 my $FH = open_out($docu_frame_file); 16713 print STDERR "# Creating frame in $docu_frame_file ...\n" if $T2H_VERBOSE; 16714 &$Texi2HTML::Config::print_frame($FH, $docu_toc_frame_file, $docu_top_file); 16715 close_out($FH, $docu_frame_file); 16716 16717 $FH = open_out($docu_toc_frame_file); 16718 print STDERR "# Creating toc frame in $docu_frame_file ...\n" if $T2H_VERBOSE; 16719 &$Texi2HTML::Config::print_toc_frame($FH, $Texi2HTML::OVERVIEW); 16720 close_out($FH, $docu_toc_frame_file); 16721 } 16722 16723 texinfo_initialization(2); 16724 16725 16726 ############################################################################ 16727 # Start processing the document 16728 # 16729 16730 #my $FH; 16731 my $line_nr; 16732 my $current_file; 16733 my $first_section = 0; # 1 if it is the first section of a page 16734 my $previous_is_top = 0; # 1 if it is the element following the top element 16735 16736 my $cline; 16737 # this is true for the state that goes through the document 16738 $state{'inside_document'} = 1; 16739 while (@$doc_lines) 16740 { 16741 $cline = shift @$doc_lines; 16742 my $chomped_line = $cline; 16743 if (!chomp($chomped_line) and @$doc_lines) 16744 { # if the line has no end of line it is concatenated with the next 16745 $doc_lines->[0] = $cline . $doc_lines->[0]; 16746 next; 16747 } 16748 $line_nr = shift (@$doc_numbers); 16749 #print STDERR "$line_nr->{'file_name'}($line_nr->{'macro'},$line_nr->{'line_nr'}) $cline" if ($line_nr); 16750 #print STDERR "PASS_TEXT: $cline"; 16751 #dump_stack(\$text, \@stack, \%state); 16752 16753 # make sure the current state from here is $Texi2HTML::THIS_ELEMENT 16754 # in case it was set by the user. 16755 $state{'element'} = $Texi2HTML::THIS_ELEMENT if (defined($Texi2HTML::THIS_ELEMENT)); 16756 if (!$state{'raw'} and !$state{'verb'}) 16757 { 16758 my $tag = ''; 16759 $tag = $1 if ($cline =~ /^\@(\w+)/); 16760 if ($tag eq 'setfilename' and $Texi2HTML::Config::IGNORE_BEFORE_SETFILENAME) 16761 { 16762 @{$Texi2HTML::THIS_SECTION} = (); 16763 } 16764 16765 if (($tag eq 'node') or (defined($sec2level{$tag}) and ($tag !~ /heading/))) 16766 { 16767 if (@stack or (defined($text) and $text ne '')) 16768 {# in pass text node and section shouldn't appear in formats 16769 #print STDERR "close_stack before \@$tag\n"; 16770 #print STDERR "text!$text%" if (! @stack); 16771 close_stack(\$text, \@stack, \%state, $line_nr); 16772 push @{$Texi2HTML::THIS_SECTION}, $text; 16773 $text = ''; 16774 } 16775 $state{'sec_num'}++ if ($sec2level{$tag} and ($tag ne 'top')); 16776 my $new_element; 16777 my $current_element; 16778 16779 # handle node and structuring elements 16780 $current_element = shift (@all_elements); 16781 ########################## begin debug section 16782 if ($current_element->{'node'}) 16783 { 16784 print STDERR 'NODE ' . "$current_element->{'texi'}($current_element->{'file'})" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 16785 print STDERR "($current_element->{'section_ref'}->{'texi'})" if ($current_element->{'section_ref'} and ($T2H_DEBUG & $DEBUG_ELEMENTS)); 16786 } 16787 else 16788 { 16789 print STDERR 'SECTION ' . $current_element->{'texi'} if ($T2H_DEBUG & $DEBUG_ELEMENTS); 16790 } 16791 print STDERR ": $cline" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 16792 ########################## end debug section 16793 16794 # The element begins a new section if there is no previous 16795 # or the reference element is not the same 16796 #if (!$Texi2HTML::THIS_ELEMENT or (defined($current_element->{'element_ref'}) and $current_element->{'element_ref'} ne $Texi2HTML::THIS_ELEMENT)) 16797 if (defined($current_element->{'element_ref'}) and (!$Texi2HTML::THIS_ELEMENT or ($current_element->{'element_ref'} ne $Texi2HTML::THIS_ELEMENT))) 16798 { 16799 $new_element = $current_element->{'element_ref'}; 16800 16801 ########################### debug 16802 my $old = 'NO_OLD'; 16803 $old = $Texi2HTML::THIS_ELEMENT->{'texi'} if (defined($Texi2HTML::THIS_ELEMENT)); 16804 print STDERR "NEW: $new_element->{'texi'}, OLD: $old\n" if ($T2H_DEBUG & $DEBUG_ELEMENTS); 16805 # print the element that just finished 16806 ########################### end debug 16807 if ($Texi2HTML::THIS_ELEMENT) 16808 { 16809 finish_element($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT, $new_element, $first_section); 16810 $first_section = 0; 16811 $previous_is_top = 0 if (!$Texi2HTML::THIS_ELEMENT->{'top'}); 16812 @{$Texi2HTML::THIS_SECTION} = (); 16813 } 16814 else 16815 { 16816 print STDERR "# Writing elements:" if ($T2H_VERBOSE); 16817 if ($Texi2HTML::Config::IGNORE_PREAMBLE_TEXT) 16818 { 16819 @{$Texi2HTML::THIS_SECTION} = (); 16820 } 16821 # remove empty for the first document lines 16822 shift @{$Texi2HTML::THIS_SECTION} while (@{$Texi2HTML::THIS_SECTION} and ($Texi2HTML::THIS_SECTION->[0] =~ /^\s*$/)); 16823 } 16824 # begin new element 16825 #my $previous_file; 16826 #$previous_file = $Texi2HTML::THIS_ELEMENT->{'file'} if (defined($Texi2HTML::THIS_ELEMENT)); 16827 $Texi2HTML::THIS_ELEMENT = $new_element; 16828 $state{'element'} = $Texi2HTML::THIS_ELEMENT; 16829 16830 do_element_directions($Texi2HTML::THIS_ELEMENT); 16831 $files{$Texi2HTML::THIS_ELEMENT->{'file'}}->{'counter'}--; 16832 #if (!defined($previous_file) or ($Texi2HTML::THIS_ELEMENT->{'file'} ne $previous_file)) 16833 if (!defined($current_file) or ($Texi2HTML::THIS_ELEMENT->{'file'} ne $current_file)) 16834 { 16835 $current_file = $Texi2HTML::THIS_ELEMENT->{'file'}; 16836 print STDERR "\n" if ($T2H_VERBOSE and !$T2H_DEBUG); 16837 print STDERR "# Writing to $docu_rdir$current_file " if $T2H_VERBOSE; 16838 my $do_page_head = open_out_file($current_file); 16839 if ($Texi2HTML::THIS_ELEMENT->{'top'}) 16840 { 16841 &$Texi2HTML::Config::print_Top_header($Texi2HTML::THISDOC{'FH'}, $do_page_head); 16842 $previous_is_top = 1; 16843 } 16844 else 16845 { 16846 &$Texi2HTML::Config::print_page_head($Texi2HTML::THISDOC{'FH'}) if ($do_page_head); 16847 &$Texi2HTML::Config::print_chapter_header($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT) if $Texi2HTML::Config::SPLIT eq 'chapter'; 16848 &$Texi2HTML::Config::print_section_header($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT) if $Texi2HTML::Config::SPLIT eq 'section'; 16849 } 16850 $first_section = 1; 16851 } 16852 print STDERR "." if ($T2H_VERBOSE); 16853 print STDERR "\n" if ($T2H_DEBUG); 16854 } 16855 16856 my $cmd_line = $cline; 16857 $cmd_line =~ s/\@$tag\s*//; 16858 my $heading_formatted = &$Texi2HTML::Config::element_heading($current_element, $tag, $cmd_line, substitute_line($cmd_line), undef, $one_section, $current_element->{'this'}, $first_section, $current_element->{'top'}, $previous_is_top, $cline, $current_element->{'id'}, $new_element); 16859 push @{$Texi2HTML::THIS_SECTION}, $heading_formatted if (defined($heading_formatted) and ($heading_formatted ne '')); 16860 next; 16861 } 16862 elsif ($tag eq 'printindex') 16863 { 16864 $cline =~ s/\s+(\w+)\s*//; 16865 my $name = $1; 16866 close_paragraph(\$text, \@stack, \%state); 16867 if (!@stack) 16868 { 16869 push @{$Texi2HTML::THIS_SECTION}, $text; 16870 $text = ''; 16871 } 16872 add_prev(\$text, \@stack, &$Texi2HTML::Config::printindex($name)); 16873 if (!@stack) 16874 { 16875 push @{$Texi2HTML::THIS_SECTION}, $text; 16876 $text = ''; 16877 } 16878 begin_paragraph (\@stack, \%state) if ($state{'preformatted'}); 16879 next; 16880 } 16881 elsif (($tag eq 'contents') or ($tag eq 'summarycontents') or ($tag eq 'shortcontents')) 16882 { 16883 my $element_tag = $tag; 16884 $element_tag = 'shortcontents' if ($element_tag ne 'contents'); 16885 # at that point the content_element is defined for sure since 16886 # we already saw the tag 16887 if ($Texi2HTML::Config::INLINE_CONTENTS and !$content_element{$element_tag}->{'aftertitlepage'}) 16888 { 16889 if (@stack or (defined($text) and $text ne '')) 16890 {# in pass text contents shouldn't appear in formats 16891 close_stack(\$text, \@stack, \%state, $line_nr); 16892 push @{$Texi2HTML::THIS_SECTION}, $text; 16893 $text = ''; 16894 } 16895 my $toc_lines = &$Texi2HTML::Config::inline_contents($Texi2HTML::THISDOC{'FH'}, $tag, $content_element{$element_tag}); 16896 push (@{$Texi2HTML::THIS_SECTION}, @$toc_lines) if (defined($toc_lines)) ; 16897 } 16898 next unless (exists($Texi2HTML::Config::misc_command{$tag}) and $Texi2HTML::Config::misc_command{$tag}->{'keep'}); 16899 } 16900 } 16901 scan_line($cline, \$text, \@stack, \%state, $line_nr); 16902 #print STDERR "after scan_line: $cline"; 16903 #dump_stack(\$text, \@stack, \%state); 16904 next if (@stack); 16905 if ($text ne '' ) 16906 { 16907 push @{$Texi2HTML::THIS_SECTION}, $text; 16908 $text = ''; 16909 } 16910 } 16911 if (@stack) 16912 {# close stack at the end of pass text 16913 close_stack(\$text, \@stack, \%state, $line_nr); 16914 } 16915 if (defined($text)) 16916 { 16917 push @{$Texi2HTML::THIS_SECTION}, $text; 16918 } 16919 print STDERR "\n" if ($T2H_VERBOSE); 16920 16921 # if no sections, then simply print document as is 16922 if ($one_section) 16923 { 16924 # may happen if there are 0 sections 16925 if (! defined($Texi2HTML::THISDOC{'FH'})) 16926 { 16927 open_out_file($docu_doc); 16928 &$Texi2HTML::Config::print_page_head($Texi2HTML::THISDOC{'FH'}); 16929 } 16930 if (@foot_lines) 16931 { 16932 &$Texi2HTML::Config::foot_section (\@foot_lines); 16933 push @{$Texi2HTML::THIS_SECTION}, @foot_lines; 16934 } 16935 print STDERR "# Write the section $Texi2HTML::THIS_ELEMENT->{'texi'}\n" if ($T2H_VERBOSE); 16936 &$Texi2HTML::Config::one_section($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT); 16937 close_out($Texi2HTML::THISDOC{'FH'}); 16938 # no misc element is done 16939 return; 16940 } 16941 16942 finish_element ($Texi2HTML::THISDOC{'FH'}, $Texi2HTML::THIS_ELEMENT, undef, $first_section); 16943 16944 ############################################################################ 16945 # Print ToC, Overview, Footnotes 16946 # 16947 foreach my $direction (@element_directions) 16948 { 16949 $Texi2HTML::HREF{$direction} = undef; 16950 delete $Texi2HTML::HREF{$direction}; 16951 # it is better to undef in case the references to these hash entries 16952 # are used, as if deleted, the 16953 # references are still refering to the old, undeleted element 16954 # (we could do both) 16955 $Texi2HTML::NAME{$direction} = undef; 16956 $Texi2HTML::NO_TEXI{$direction} = undef; 16957 $Texi2HTML::SIMPLE_TEXT{$direction} = undef; 16958 $Texi2HTML::NODE{$direction} = undef; 16959 16960 $Texi2HTML::THIS_ELEMENT = undef; 16961 } 16962 my $about_body; 16963 $about_body = &$Texi2HTML::Config::about_body(); 16964 # @foot_lines is emptied in finish_element if SEPARATED_FOOTNOTES 16965 my %misc_page_infos = ( 16966 'Footnotes' => { 'file' => $docu_foot_file, 16967 'relative_file' => $docu_foot, 16968 'process' => $Texi2HTML::Config::print_Footnotes, 16969 'section' => \@foot_lines }, 16970 'Contents' => { 'file' => $docu_toc_file, 16971 'relative_file' => $docu_toc, 16972 'process' => $Texi2HTML::Config::print_Toc, 16973 'section' => $Texi2HTML::TOC_LINES }, 16974 'Overview' => { 'file' => $docu_stoc_file, 16975 'relative_file' => $docu_stoc, 16976 'process' => $Texi2HTML::Config::print_Overview, 16977 'section' => $Texi2HTML::OVERVIEW }, 16978 'About' => { 'file' => $docu_about_file, 16979 'relative_file' => $docu_about, 16980 'process' => $Texi2HTML::Config::print_About, 16981 'section' => [$about_body] } 16982 ); 16983 $misc_page_infos{'Footnotes'}->{'do'} = 1 if (@foot_lines); 16984 $misc_page_infos{'Contents'}->{'do'} = 1 if 16985 (@{$Texi2HTML::TOC_LINES} and !$Texi2HTML::Config::INLINE_CONTENTS); 16986 $misc_page_infos{'Overview'}->{'do'} = 1 if 16987 (@{$Texi2HTML::OVERVIEW} and !$Texi2HTML::Config::INLINE_CONTENTS); 16988 #FIXME: ... and $Texi2HTML::THISDOC{'do_about'}) ? 16989 $misc_page_infos{'About'}->{'do'} = 1 if ($about_body); 16990 16991 foreach my $misc_page('Footnotes', 'Contents', 'Overview', 'About') 16992 { 16993 next unless ($misc_page_infos{$misc_page}->{'do'}); 16994 my $file = $misc_page_infos{$misc_page}->{'file'}; 16995 my $relative_file = $misc_page_infos{$misc_page}->{'relative_file'}; 16996 print STDERR "# writing $misc_page in $file\n" if $T2H_VERBOSE; 16997 my $saved_FH; 16998 my $open_new = 0; 16999 if ($relative_file ne $docu_doc) 17000 { 17001 $saved_FH = $Texi2HTML::THISDOC{'FH'}; 17002 # FIXME the file may have the same name than another file. Use 17003 # open_out_file? 17004 $Texi2HTML::THISDOC{'FH'} = open_out ($file); 17005 print STDERR "# Opening $file for $misc_page\n" if $T2H_VERBOSE; 17006 $open_new = 1; 17007 } 17008 else 17009 { 17010 print STDERR "# writing $misc_page in current file\n" if $T2H_VERBOSE; 17011 } 17012 foreach my $href_page (keys(%misc_page_infos)) 17013 { 17014 $Texi2HTML::HREF{$href_page} = file_target_href( 17015 $misc_page_infos{$href_page}->{'relative_file'}, $relative_file, 17016 $Texi2HTML::Config::misc_pages_targets{$href_page}) 17017 if ($misc_page_infos{$href_page}->{'do'}); 17018 } 17019 #print STDERR "Doing hrefs for $misc_page First "; 17020 $Texi2HTML::HREF{'First'} = href($element_first, $relative_file); 17021 #print STDERR "Last "; 17022 $Texi2HTML::HREF{'Last'} = href($element_last, $relative_file); 17023 #print STDERR "Index "; 17024 $Texi2HTML::HREF{'Index'} = href($element_chapter_index, $relative_file) if (defined($element_chapter_index)); 17025 #print STDERR "Top "; 17026 $Texi2HTML::HREF{'Top'} = href($element_top, $relative_file); 17027 if ($Texi2HTML::Config::INLINE_CONTENTS) 17028 { 17029 $Texi2HTML::HREF{'Contents'} = href($content_element{'contents'}, $relative_file); 17030 $Texi2HTML::HREF{'Overview'} = href($content_element{'shortcontents'}, $relative_file); 17031 } 17032 $Texi2HTML::HREF{$misc_page} = '#' . $Texi2HTML::Config::misc_pages_targets{$misc_page}; 17033 $Texi2HTML::HREF{'This'} = $Texi2HTML::HREF{$misc_page}; 17034 $Texi2HTML::NAME{'This'} = $Texi2HTML::NAME{$misc_page}; 17035 $Texi2HTML::NO_TEXI{'This'} = $Texi2HTML::NO_TEXI{$misc_page}; 17036 $Texi2HTML::SIMPLE_TEXT{'This'} = $Texi2HTML::SIMPLE_TEXT{$misc_page}; 17037 $Texi2HTML::THIS_SECTION = $misc_page_infos{$misc_page}->{'section'} 17038 if defined($misc_page_infos{$misc_page}->{'section'}); 17039 &{$misc_page_infos{$misc_page}->{'process'}}($Texi2HTML::THISDOC{'FH'}, $open_new, $misc_page); 17040 17041 if ($open_new) 17042 { 17043 close_out($Texi2HTML::THISDOC{'FH'}, $file); 17044 $Texi2HTML::THISDOC{'FH'} = $saved_FH; 17045 } 17046 } 17047 17048 unless ($Texi2HTML::Config::SPLIT) 17049 { 17050 &$Texi2HTML::Config::print_page_foot($Texi2HTML::THISDOC{'FH'}); 17051 close_out ($Texi2HTML::THISDOC{'FH'}); 17052 } 17053 pop_state(); 17054} 17055 17056# print section, close file if needed. 17057sub finish_element($$$$) 17058{ 17059 my $FH = shift; 17060 my $element = shift; 17061 my $new_element = shift; 17062 my $first_section = shift; 17063#print STDERR "FINISH_ELEMENT($FH)($element->{'texi'})[$element->{'file'}] counter $files{$element->{'file'}}->{'counter'}\n"; 17064 17065 # handle foot notes 17066 if ($Texi2HTML::Config::SPLIT and scalar(@foot_lines) 17067 and !$Texi2HTML::Config::SEPARATED_FOOTNOTES 17068 and (! $new_element or 17069 ($element and ($new_element->{'file'} ne $element->{'file'}))) 17070 ) 17071 { 17072 if ($files{$element->{'file'}}->{'counter'}) 17073 {# there are other elements in that page we are not on its foot 17074 $files{$element->{'file'}}->{'relative_foot_num'} 17075 = $global_relative_foot_num; 17076 push @{$files{$element->{'file'}}->{'foot_lines'}}, 17077 @foot_lines; 17078 } 17079 else 17080 {# we output the footnotes as we are at the file end 17081 unshift @foot_lines, @{$files{$element->{'file'}}->{'foot_lines'}}; 17082 &$Texi2HTML::Config::foot_section (\@foot_lines); 17083 push @{$Texi2HTML::THIS_SECTION}, @foot_lines; 17084 } 17085 if ($new_element) 17086 { 17087 $global_relative_foot_num = 17088 $files{$new_element->{'file'}}->{'relative_foot_num'}; 17089 } 17090 @foot_lines = (); 17091 } 17092 if ($element->{'top'}) 17093 { 17094 my $top_file = $docu_top_file; 17095 #print STDERR "TOP $element->{'texi'}, @{$Texi2HTML::THIS_SECTION}\n"; 17096 print STDERR "# Doing element top\n" 17097 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17098 print STDERR "[Top]" if ($T2H_VERBOSE); 17099 $Texi2HTML::HREF{'Top'} = href($element_top, $element->{'file'}); 17100 &$Texi2HTML::Config::print_Top($FH, $element->{'titlefont'}, $element); 17101 my $end_page = 0; 17102 if ($Texi2HTML::Config::SPLIT) 17103 { 17104 if (!$files{$element->{'file'}}->{'counter'}) 17105 { 17106 $end_page = 1; 17107 } 17108 } 17109 &$Texi2HTML::Config::print_Top_footer($FH, $end_page, $element); 17110 close_out($FH, $top_file) if ($end_page); 17111 } 17112 else 17113 { 17114 print STDERR "# do element $element->{'texi'}\n" 17115 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17116 &$Texi2HTML::Config::print_section($FH, $first_section, 0, $element); 17117 ################# debug 17118 my $new_elem_file = 'NO ELEM'; 17119 $new_elem_file = $new_element->{'file'} if (defined($new_element)); 17120 print STDERR "# FILES new: $new_elem_file old: $element->{'file'}\n" 17121 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17122 ################# end debug 17123 if (defined($new_element) and ($new_element->{'file'} ne $element->{'file'})) 17124 { 17125 print STDERR "# End of section with change in file\n" 17126 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17127 if (!$files{$element->{'file'}}->{'counter'}) 17128 { 17129 &$Texi2HTML::Config::print_chapter_footer($FH, $element) if ($Texi2HTML::Config::SPLIT eq 'chapter'); 17130 &$Texi2HTML::Config::print_section_footer($FH, $element) if ($Texi2HTML::Config::SPLIT eq 'section'); 17131 print STDERR "# Close file after $element->{'texi'}\n" 17132 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17133 &$Texi2HTML::Config::print_page_foot($FH); 17134 close_out($FH); 17135 } 17136 else 17137 { 17138 print STDERR "# Counter $files{$element->{'file'}}->{'counter'} ne 0, file $element->{'file'}\n" 17139 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17140 } 17141 } 17142 elsif (!defined($new_element)) 17143 { 17144 print STDERR "# End of last section\n" 17145 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17146 if ($Texi2HTML::Config::SPLIT) 17147 { # end of last splitted section 17148 &$Texi2HTML::Config::print_chapter_footer($FH, $element) if ($Texi2HTML::Config::SPLIT eq 'chapter'); 17149 &$Texi2HTML::Config::print_section_footer($FH, $element) if ($Texi2HTML::Config::SPLIT eq 'section'); 17150 &$Texi2HTML::Config::print_page_foot($FH); 17151 close_out($FH); 17152 } 17153 else 17154 { # end of last unsplit section 17155 &$Texi2HTML::Config::end_section($FH, 1, $element); 17156 } 17157 } 17158 elsif ($new_element->{'top'}) 17159 { 17160 print STDERR "# Section followed by Top\n" 17161 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17162 &$Texi2HTML::Config::end_section($FH, 1, $element); 17163 } 17164 else 17165 { # end of section followed by another one 17166 print STDERR "# Section followed by another one\n" 17167 if ($T2H_DEBUG & $DEBUG_ELEMENTS); 17168 &$Texi2HTML::Config::end_section($FH, 0, $element); 17169 } 17170 } 17171} 17172 17173# write to files with name the node name for cross manual references. 17174sub do_node_files() 17175{ 17176 foreach my $key (keys(%nodes)) 17177 { 17178 my $node = $nodes{$key}; 17179 next unless ($node->{'node_file'}); 17180 my $redirection_file = $docu_doc; 17181 $redirection_file = $node->{'file'} if ($Texi2HTML::Config::SPLIT); 17182 if (!$redirection_file) 17183 { 17184 print STDERR "Bug: file for redirection for `$node->{'texi'}' don't exist\n" unless ($novalidate or !$node->{'seen'}); 17185 next; 17186 } 17187 next if ($redirection_file eq $node->{'node_file'}); 17188 my $file = "${docu_rdir}$node->{'node_file'}"; 17189 $Texi2HTML::NODE{'This'} = $node->{'text'}; 17190 $Texi2HTML::NO_TEXI{'This'} = $node->{'no_texi'}; 17191 $Texi2HTML::SIMPLE_TEXT{'This'} = $node->{'simple_format'}; 17192 $Texi2HTML::NAME{'This'} = $node->{'text'}; 17193 $Texi2HTML::HREF{'This'} = "$node->{'file'}#$node->{'id'}"; 17194 my $NODEFILE = open_out ($file); 17195 &$Texi2HTML::Config::print_redirection_page ($NODEFILE); 17196 close $NODEFILE || die "$ERROR: Can't close $file: $!\n"; 17197 } 17198} 17199 17200#+++############################################################################ 17201# # 17202# Low level functions # 17203# # 17204#---############################################################################ 17205 17206sub locate_include_file($) 17207{ 17208 my $file = shift; 17209 17210 # APA: Don't implicitely search ., to conform with the docs! 17211 # return $file if (-e $file && -r $file); 17212 foreach my $dir (@Texi2HTML::Config::INCLUDE_DIRS) 17213 { 17214 return "$dir/$file" if (-e "$dir/$file" && -r "$dir/$file"); 17215 } 17216 return undef; 17217} 17218 17219sub open_file($$) 17220{ 17221 my $name = shift; 17222# my $line_number = shift; 17223 my $macro = shift; 17224 17225 my $line_number; 17226 my $input_spool; 17227 17228 local *FH; 17229 if (open(*FH, "<$name")) 17230 { 17231 if (defined($Texi2HTML::THISDOC{'IN_ENCODING'}) and $Texi2HTML::Config::USE_UNICODE) 17232 { 17233 binmode(*FH, ":encoding($Texi2HTML::THISDOC{'IN_ENCODING'})"); 17234 } 17235 my $file = { 'fh' => *FH, 17236 'input_spool' => { 'spool' => [], 17237 'macro' => '' }, 17238 'name' => $name, 17239 'line_nr' => 0 }; 17240 unshift(@fhs, $file); 17241 $input_spool = $file->{'input_spool'}; 17242 $line_number->{'file_name'} = $name; 17243 $line_number->{'line_nr'} = 1; 17244 $line_number->{'macro'} = $macro; 17245 } 17246 else 17247 { 17248 warn "$ERROR Can't read file $name: $!\n"; 17249 } 17250 return ($line_number, $input_spool); 17251} 17252 17253sub open_out($) 17254{ 17255 my $file = shift; 17256 local *FILE; 17257#print STDERR "open_out $file $Texi2HTML::THISDOC{'OUT_ENCODING'}\n"; 17258 if ($file eq '-') 17259 { 17260 binmode(STDOUT, ":encoding($Texi2HTML::THISDOC{'OUT_ENCODING'})") if (defined($Texi2HTML::THISDOC{'OUT_ENCODING'}) and $Texi2HTML::Config::USE_UNICODE); 17261 return \*STDOUT; 17262 } 17263 17264 unless (open(FILE, ">$file")) 17265 { 17266 die "$ERROR Can't open $file for writing: $!\n"; 17267 } 17268 if (defined($Texi2HTML::THISDOC{'OUT_ENCODING'}) and $Texi2HTML::Config::USE_UNICODE) 17269 { 17270 if ($Texi2HTML::THISDOC{'OUT_ENCODING'} eq 'utf8' or $Texi2HTML::THISDOC{'OUT_ENCODING'} eq 'utf-8-strict') 17271 { 17272 binmode(FILE, ':utf8'); 17273 } 17274 else 17275 { 17276 binmode(FILE, ':bytes'); 17277 } 17278 binmode(FILE, ":encoding($Texi2HTML::THISDOC{'OUT_ENCODING'})"); 17279 } 17280 return *FILE; 17281} 17282 17283# FIXME not used when split 17284sub close_out($;$) 17285{ 17286 my $FH = shift; 17287 my $file = shift; 17288 $file = '' if (!defined($file)); 17289 return if ($file eq '-'); 17290#print STDERR "close_out $file\n"; 17291 close ($FH) || die "$ERROR: Error occurred when closing $file: $!\n"; 17292} 17293 17294sub next_line($$) 17295{ 17296 my $line_number = shift; 17297 my $input_spool; 17298 while (@fhs) 17299 { 17300 my $file = $fhs[0]; 17301 $line_number->{'file_name'} = $file->{'name'}; 17302 $input_spool = $file->{'input_spool'}; 17303 if (@{$input_spool->{'spool'}}) 17304 { 17305 $line_number->{'macro'} = $file->{'input_spool'}->{'macro'}; 17306 $line_number->{'line_nr'} = $file->{'line_nr'}; 17307 my $line = shift(@{$input_spool->{'spool'}}); 17308 print STDERR "# unspooling $line" if ($T2H_DEBUG & $DEBUG_MACROS); 17309 return($line, $input_spool); 17310 } 17311 else 17312 { 17313 $file->{'input_spool'}->{'macro'} = ''; 17314 $line_number->{'macro'} = ''; 17315 } 17316 my $fh = $file->{'fh'}; 17317 no strict "refs"; 17318 my $line = <$fh>; 17319 use strict "refs"; 17320 my $chomped_line = $line; 17321 $file->{'line_nr'}++ if (defined($line) and chomp($chomped_line)); 17322 $line_number->{'line_nr'} = $file->{'line_nr'}; 17323 return($line, $input_spool) if (defined($line)); 17324 no strict "refs"; 17325 close($fh); 17326 use strict "refs"; 17327 shift(@fhs); 17328 } 17329 return(undef, $input_spool); 17330} 17331 17332# echo a warning 17333sub echo_warn($;$) 17334{ 17335 my $text = shift; 17336 chomp ($text); 17337 my $line_number = shift; 17338 warn "$WARN $text " . format_line_number($line_number) . "\n"; 17339} 17340 17341my $error_nrs = 0; 17342sub echo_error($;$) 17343{ 17344 my $text = shift; 17345 chomp ($text); 17346 my $line_number = shift; 17347 warn "$ERROR $text " . format_line_number($line_number) . "\n"; 17348 $error_nrs ++; 17349 die "Max error number exceeded\n" if ($error_nrs >= $Texi2HTML::Config::ERROR_LIMIT); 17350} 17351 17352sub format_line_number($) 17353{ 17354 my $line_number = shift; 17355 my $macro_text = ''; 17356 #$line_number = undef; 17357 return '' unless (defined($line_number)); 17358 $macro_text = " in \@$line_number->{'macro'}" if ($line_number->{'macro'} ne ''); 17359 my $file_text = '('; 17360 $file_text = "(in $line_number->{'file_name'} " if ($line_number->{'file_name'} ne $Texi2HTML::THISDOC{'input_file_name'}); 17361 return "${file_text}l. $line_number->{'line_nr'}" . $macro_text . ')'; 17362} 17363 17364# to debug, dump the result of pass_texi and pass_structure in a file 17365sub dump_texi($$;$$) 17366{ 17367 my $lines = shift; 17368 my $pass = shift; 17369 my $numbers = shift; 17370 my $file = shift; 17371 $file = "$docu_rdir$docu_name" . ".pass$pass" if (!defined($file)); 17372 my $FH = open_out($file); 17373 print STDERR "# Dump texi\n" if ($T2H_VERBOSE); 17374 my $index = 0; 17375 foreach my $line (@$lines) 17376 { 17377 my $number_information = ''; 17378 my $chomped_line = $line; 17379 # if defined, it means that an output of the file is asked for 17380 if (defined($numbers)) 17381 { 17382 my $basefile = $numbers->[$index]->{'file_name'}; 17383 $basefile = 'no file' if (!defined($basefile)); 17384 $basefile =~ s|.*/||; 17385 my $macro_name = $numbers->[$index]->{'macro'}; 17386 $macro_name = '' if (!defined($macro_name)); 17387 my $line_number = $numbers->[$index]->{'line_nr'}; 17388 $line_number = '' if (!defined($line_number)); 17389 $number_information = "${basefile}($macro_name,$line_number) "; 17390 } 17391 print $FH "${number_information}$line"; 17392 $index++ if (chomp($chomped_line)); 17393 } 17394 close_out ($FH, $file); 17395} 17396 17397 17398# return next tag on the line 17399sub next_tag($) 17400{ 17401 my $line = shift; 17402 # macro_regexp 17403 if ($line =~ /^\s*\@(["'~\@\}\{,\.!\?\s\*\-\^`=:\|\/\\])/o or $line =~ /^\s*\@([a-zA-Z][\w-]*)([\s\{\}\@])/ or $line =~ /^\s*\@([a-zA-Z][\w-]*)$/) 17404 { 17405 return ($1); 17406 } 17407 return ''; 17408} 17409 17410sub next_end_tag($) 17411{ 17412 my $line = shift; 17413 if ($line =~ /^\s*\@end\s+([a-zA-Z][\w-]*)/) 17414 { 17415 return $1; 17416 } 17417 return ''; 17418} 17419 17420sub next_tag_or_end_tag($) 17421{ 17422 my $line = shift; 17423 my $next_tag = next_tag($line); 17424 return $next_tag if (defined($next_tag) and $next_tag ne ''); 17425 return next_end_tag($line); 17426} 17427 17428sub top_stack($;$) 17429{ 17430 my $stack = shift; 17431 my $ignore_para = shift; 17432 17433 my $index = scalar (@$stack); 17434 return undef unless ($index); 17435 17436 return $stack->[-1] unless ($ignore_para); 17437 if ($ignore_para == 1) 17438 { 17439 if (exists($stack->[-1]->{'format'}) and ($stack->[-1]->{'format'} eq 'paragraph' or $stack->[-1]->{'format'} eq 'preformatted')) 17440 { 17441 if (exists($stack->[-2])) 17442 { 17443 return $stack->[-2]; 17444 } 17445 else 17446 { 17447 return undef; 17448 } 17449 } 17450 else 17451 { 17452 return $stack->[-1]; 17453 } 17454 } 17455 else 17456 { 17457 while ($index and 17458 ( 17459 (exists($stack->[$index-1]->{'format'}) 17460 and ($stack->[$index-1]->{'format'} eq 'paragraph' or $stack->[$index-1]->{'format'} eq 'preformatted')) 17461 or (exists($stack->[$index-1]->{'style'})) 17462 )) 17463 { 17464 $index--; 17465 } 17466 } 17467 return undef unless ($index); 17468 return $stack->[$index-1]; 17469} 17470 17471# return the next element with balanced {} 17472sub next_bracketed($$;$) 17473{ 17474 my $line = shift; 17475 my $line_nr = shift; 17476 my $report = shift; 17477 my $opened_braces = 0; 17478 my $result = ''; 17479 my $spaces; 17480#print STDERR "next_bracketed $line"; 17481 if ($line =~ /^(\s*)$/) 17482 { 17483 return ('','',$1); 17484 } 17485 while ($line !~ /^\s*$/) 17486 { 17487#print STDERR "next_bracketed($opened_braces): $result !!! $line"; 17488 if (!$opened_braces) 17489 { # beginning of item 17490 $line =~ s/^(\s*)//; 17491 $spaces = $1; 17492 #if ($line =~ s/^([^\{\}\s]+)//) 17493 if ($line =~ s/^([^\{\}]+?)(\s+)/$2/ or $line =~ s/^([^\{\}]+?)$//) 17494 { 17495 $result = $1; 17496 $result =~ s/\s*$//; 17497 return ($result, $line, $spaces); 17498 } 17499 elsif ($line =~ s/^([^\{\}]+?)([\{\}])/$2/) 17500 { 17501 $result = $1; 17502 } 17503 } 17504 elsif($line =~ s/^([^\{\}]+)//) 17505 { 17506 $result .= $1; 17507 } 17508 if ($line =~ s/^([\{\}])//) 17509 { 17510 my $brace = $1; 17511 $opened_braces++ if ($brace eq '{'); 17512 $opened_braces-- if ($brace eq '}'); 17513 17514 if ($opened_braces < 0) 17515 { 17516 echo_error("too much '}' in specification", $line_nr) if ($report); 17517 $opened_braces = 0; 17518 #next; 17519 } 17520 $result .= $brace; 17521 return ($result, $line, $spaces) if ($opened_braces == 0); 17522 } 17523 } 17524 if ($opened_braces) 17525 { 17526 echo_error("'{' not closed in specification", $line_nr) if ($report); 17527 return ($result, '', $spaces); 17528 #return ($result . ( '}' x $opened_braces), '', $spaces); 17529 } 17530 print STDERR "BUG: at the end of next_bracketed\n"; 17531 return undef; 17532} 17533 17534# def prams are also split at @-commands if not in brackets 17535sub next_def_param($$;$) 17536{ 17537 my $line = shift; 17538 my $line_nr = shift; 17539 my $report = shift; 17540 my ($item, $spaces); 17541 ($item, $line, $spaces) = next_bracketed($line, $line_nr, $report); 17542 return ($item, $line, $spaces) if (!defined($item)); 17543 if ($item =~ /^\{/) 17544 { 17545 $item =~ s/^\{(.*)\}$/$1/; 17546 } 17547 else 17548 { 17549 my $delimeter_quoted = quotemeta($Texi2HTML::Config::def_argument_separator_delimiters); 17550 if ($item =~ s/^([^\@$delimeter_quoted]+)//) 17551 { 17552 $line = $item . $line; 17553 $item = $1; 17554 } 17555 elsif ($item =~ s/^([$delimeter_quoted])//) 17556 { 17557 $line = $item . $line; 17558 $item = $1; 17559 } 17560 elsif ($item =~ s/^(\@[^\@\{]+)(\@)/$2/) 17561 { 17562 $line = $item . $line; 17563 $item = $1; 17564 } 17565 } 17566 return ($item, $line, $spaces); 17567} 17568 17569# do a href using file and id and taking care of ommitting file if it is 17570# the same 17571# element: structuring element to point to 17572# file: current file 17573sub href($$;$) 17574{ 17575 my $element = shift; 17576 my $file = shift; 17577 my $line_nr = shift; 17578 return '' unless defined($element); 17579 my $href = ''; 17580 echo_error("Bug: $element->{'texi'}, target undef", $line_nr) if (!defined($element->{'target'})); 17581 echo_error("Bug: $element->{'texi'}, file undef", $line_nr) if (!defined($element->{'file'})); 17582 echo_error("Bug: file undef in href", $line_nr) if (!defined($file)); 17583#foreach my $key (keys(%{$element})) 17584#{ 17585# my $value = 'UNDEF'; $value = $element->{$key} if defined($element->{$key}); 17586# print STDERR "$key: $value\n"; 17587#}print STDERR "\n"; 17588 $href .= $element->{'file'} if (defined($element->{'file'}) and $file ne $element->{'file'}); 17589 $href .= "#$element->{'target'}" if (defined($element->{'target'})); 17590 return $href; 17591} 17592 17593sub file_target_href($$$) 17594{ 17595 my $dest_file = shift; 17596 my $orig_file = shift; 17597 my $target = shift; 17598 my $href = ''; 17599 $href .= $dest_file if (defined($dest_file) and ($dest_file ne $orig_file)); 17600 $href .= "#$target" if (defined($target)); 17601 return $href; 17602} 17603 17604sub normalise_space($) 17605{ 17606 return undef unless (defined ($_[0])); 17607 my $text = shift; 17608 $text =~ s/\s+/ /go; 17609 $text =~ s/ $//; 17610 $text =~ s/^ //; 17611 return $text; 17612} 17613 17614sub normalise_node($) 17615{ 17616 return undef unless (defined ($_[0])); 17617 my $text = shift; 17618 $text = normalise_space($text); 17619 $text =~ s/^top$/Top/i; 17620 return $text; 17621} 17622 17623sub do_anchor_label($$$$) 17624{ 17625 my $command = shift; 17626 #my $anchor = shift; 17627 my $args = shift; 17628 my $anchor = $args->[0]; 17629 my $style_stack = shift; 17630 my $state = shift; 17631 my $line_nr = shift; 17632 17633 # FIXME anchor may appear twice when outside document and first time 17634 # it appears in the document 17635 return '' if (($state->{'region'} and $state->{'multiple_pass'} > 0) or $state->{'remove_texi'}); 17636 $anchor = normalise_node($anchor); 17637 if (!exists($nodes{$anchor}) or !defined($nodes{$anchor}->{'id'})) 17638 { 17639 print STDERR "Bug: unknown anchor `$anchor'\n"; 17640 } 17641 return &$Texi2HTML::Config::anchor_label($nodes{$anchor}->{'id'}, $anchor, $nodes{$anchor}); 17642} 17643 17644sub get_format_command($) 17645{ 17646 my $format = shift; 17647 my $command = ''; 17648 my $format_name = ''; 17649 my $term = 0; 17650 my $item_nr; 17651 my $paragraph_number; 17652 my $enumerate_type; 17653 my $number; 17654 17655 $command = $format->{'command'} if (defined($format->{'command'})); 17656 $format_name = $format->{'format'} if (defined($format->{'format'})); 17657 17658 return ($format_name,$command,\$format->{'paragraph_number'},$term, 17659 $format->{'item_nr'}, $format->{'spec'}, $format->{'number'}, 17660 $format->{'stack_at_beginning'}, $format->{'command_opened'}); 17661} 17662 17663sub do_paragraph($$;$) 17664{ 17665 my $text = shift; 17666 my $state = shift; 17667 my $stack = shift; 17668 17669 if (!defined ($state->{'paragraph_context'})) 17670 { 17671 echo_error ("paragraph_context undef"); 17672 dump_stack (undef, $stack, $state); 17673 } 17674 17675 my ($format, $paragraph_command, $paragraph_number, $term, $item_nr, 17676 $enumerate_type, $number,$stack_at_beginning, $command_opened) 17677 = get_format_command ($state->{'paragraph_context'}); 17678 delete $state->{'paragraph_context'}; 17679 17680 my $indent_style = ''; 17681 if (exists($state->{'paragraph_indent'})) 17682 { 17683 $indent_style = $state->{'paragraph_indent'}; 17684 $state->{'paragraph_indent'} = undef; 17685 delete $state->{'paragraph_indent'}; 17686 } 17687 my $paragraph_command_formatted; 17688 $state->{'paragraph_nr'}--; 17689 (print STDERR "Bug text undef in do_paragraph", return '') unless defined($text); 17690 my $align = ''; 17691 $align = $state->{'paragraph_style'}->[-1] if ($state->{'paragraph_style'}->[-1]); 17692 17693 if (exists($::style_map_ref->{$paragraph_command}) and 17694 !exists($Texi2HTML::Config::special_list_commands{$format}->{$paragraph_command}) and $command_opened) 17695 { 17696 if ($format eq 'itemize') 17697 { 17698 chomp ($text); 17699 $text = do_simple($paragraph_command, $text, $state, [$text]); 17700 $text = $text . "\n"; 17701 } 17702 } 17703 elsif (exists($::things_map_ref->{$paragraph_command})) 17704 { 17705 $paragraph_command_formatted = do_simple($paragraph_command, '', $state); 17706 } 17707 return &$Texi2HTML::Config::paragraph($text, $align, $indent_style, $paragraph_command, $paragraph_command_formatted, $paragraph_number, $format, $item_nr, $enumerate_type, $number,$state->{'command_stack'},$stack_at_beginning); 17708} 17709 17710sub do_preformatted($$;$) 17711{ 17712 my $text = shift; 17713 my $state = shift; 17714 my $stack = shift; 17715 17716 if (!defined ($state->{'preformatted_context'})) 17717 { 17718 echo_error ("preformatted_context undef"); 17719 dump_stack (undef, $stack, $state); 17720 } 17721 17722 my ($format, $leading_command, $preformatted_number, $term, $item_nr, 17723 $enumerate_type, $number,$stack_at_beginning, $command_opened) 17724 = get_format_command($state->{'preformatted_context'}); 17725 delete ($state->{'preformatted_context'}); 17726 my $leading_command_formatted; 17727 my $pre_style = ''; 17728 my $class = ''; 17729 $pre_style = $state->{'preformatted_stack'}->[-1]->{'pre_style'} if ($state->{'preformatted_stack'}->[-1]->{'pre_style'}); 17730 $class = $state->{'preformatted_stack'}->[-1]->{'class'}; 17731 print STDERR "BUG: !state->{'preformatted_stack'}->[-1]->{'class'}\n" unless ($class); 17732 if (exists($::style_map_ref->{$leading_command}) and 17733 !exists($Texi2HTML::Config::special_list_commands{$format}->{$leading_command}) and ($style_type{$leading_command} eq 'style')) 17734 { 17735 $text = do_simple($leading_command, $text, $state,[$text]) if ($format eq 'itemize'); 17736 } 17737 elsif (exists($::things_map_ref->{$leading_command})) 17738 { 17739 $leading_command_formatted = do_simple($leading_command, '', $state); 17740 } 17741 return &$Texi2HTML::Config::preformatted($text, $pre_style, $class, $leading_command, $leading_command_formatted, $preformatted_number, $format, $item_nr, $enumerate_type, $number,$state->{'command_stack'},$stack_at_beginning); 17742} 17743 17744sub do_external_href($) 17745{ 17746 # node_id is a unique node identifier with only letters, digits, - and _ 17747 # node_xhtml_id is almost the same, but xhtml id can only begin with 17748 # letters, so a prefix has to be appended 17749 my $texi_node = shift; 17750 my $file = ''; 17751 my $node_file = ''; 17752 my $node_id = ''; 17753 my $node_xhtml_id = ''; 17754 17755#print STDERR "do_external_href $texi_node\n"; 17756 17757 if ($texi_node =~ s/^\((.+?)\)//) 17758 { 17759 $file = $1; 17760 } 17761 $texi_node = normalise_node($texi_node); 17762 if ($texi_node ne '') 17763 { 17764 if (exists($nodes{$texi_node}) and ($nodes{$texi_node}->{'cross_manual_target'})) 17765 { 17766 $node_id = $nodes{$texi_node}->{'cross_manual_target'}; 17767 if ($Texi2HTML::Config::TRANSLITERATE_NODE) 17768 { 17769 $node_file = $nodes{$texi_node}->{'cross_manual_file'}; 17770 } 17771 } 17772 else 17773 { 17774 if ($Texi2HTML::Config::TRANSLITERATE_NODE) 17775 { 17776 ($node_id, $node_file) = cross_manual_line($texi_node,1); 17777 } 17778 else 17779 { 17780 $node_id = cross_manual_line($texi_node); 17781 } 17782 } 17783 $node_xhtml_id = node_to_id($node_id); 17784 $node_file = $node_id unless ($Texi2HTML::Config::TRANSLITERATE_NODE); 17785 } 17786 return &$Texi2HTML::Config::external_href($texi_node, $node_file, 17787 $node_xhtml_id, $file); 17788} 17789 17790# transform node for cross ref name to id suitable for xhtml: an xhtml id 17791# must begin with a letter. 17792sub node_to_id($) 17793{ 17794 my $cross_ref_node_name = shift; 17795 $cross_ref_node_name =~ s/^([0-9_])/g_t$1/; 17796 return $cross_ref_node_name; 17797} 17798 17799# return an empty string if the command is not a index command, the prefix 17800# if it is one 17801sub index_command_prefix($) 17802{ 17803 my $command = shift; 17804 return $1 if ($command =~ /^(\w+?)index/ and ($1 ne 'print') and ($1 ne 'syncode') and ($1 ne 'syn') and ($1 ne 'def') and ($1 ne 'defcode')); 17805 return ''; 17806} 17807 17808# return 1 if the following tag shouldn't begin a line 17809sub no_line($) 17810{ 17811 my $line = shift; 17812 my $next_tag = next_tag($line); 17813 return 1 if (($line =~ /^\s*$/) or $Texi2HTML::Config::no_paragraph_commands{$next_tag} or 17814 ($Texi2HTML::Config::no_paragraph_commands{'cindex'} and (index_command_prefix($next_tag) ne '')) or 17815 (($line =~ /^\@end\s+(\w+)/) and $Texi2HTML::Config::no_paragraph_commands{"end $1"})); 17816 return 0; 17817} 17818 17819sub no_paragraph($$) 17820{ 17821 my $state = shift; 17822 my $line = shift; 17823 return ($state->{'paragraph_context'} or $state->{'preformatted'} or $state->{'remove_texi'} or no_line($line) or $state->{'no_paragraph'}); 17824} 17825 17826# We restart the preformatted format which was stopped 17827# by the format if in preformatted, and start a paragraph 17828# for the text following the end of the format, if needed 17829sub begin_paragraph_after_command($$$$) 17830{ 17831 my $state = shift; 17832 my $stack = shift; 17833 my $command = shift; 17834 my $text_following = shift; 17835 17836 #if (($state->{'preformatted'} 17837 # and !$Texi2HTML::Config::format_in_paragraph{$command}) 17838 if ($state->{'preformatted'} 17839 or (!no_paragraph($state,$text_following))) 17840 { 17841 begin_paragraph($stack, $state); 17842 } 17843} 17844 17845# handle raw formatting, ignored regions... 17846sub do_text_macro($$$$$) 17847{ 17848 my $type = shift; 17849 my $line = shift; 17850 my $state = shift; 17851 my $stack = shift; 17852 my $line_nr = shift; 17853 my $value; 17854 #print STDERR "do_text_macro $type\n"; 17855 17856 if ($Texi2HTML::Config::texi_formats_map{$type} eq 'raw') 17857 { 17858 $state->{'raw'} = $type; 17859 #print STDERR "RAW\n"; 17860 if ($state->{'raw'}) 17861 { 17862 push @$stack, { 'style' => $type, 'text' => '' }; 17863 } 17864 } 17865 elsif ($Texi2HTML::Config::texi_formats_map{$type} eq 'value') 17866 { 17867 if (($line =~ s/(\s+)($VARRE)$//) or ($line =~ s/(\s+)($VARRE)(\s)//)) 17868 { 17869 $value = $1 . $2; 17870 $value .= $3 if defined($3); 17871 if ($state->{'ignored'}) 17872 { 17873 if ($type eq $state->{'ignored'}) 17874 { 17875 $state->{'ifvalue_inside'}++; 17876 } 17877 # if 'ignored' we don't care about the command as long as 17878 # the nesting is correct 17879 return ($line,''); 17880 } 17881 my $open_ifvalue = 0; 17882 if ($type eq 'ifclear') 17883 { 17884 if (defined($value{$2})) 17885 { 17886 $open_ifvalue = 1; 17887 } 17888 else 17889 { 17890 push @{$state->{'text_macro_stack'}}, $type; 17891 } 17892 } 17893 elsif ($type eq 'ifset') 17894 { 17895 unless (defined($value{$2})) 17896 { 17897 $open_ifvalue = 1; 17898 } 17899 else 17900 { 17901 push @{$state->{'text_macro_stack'}}, $type; 17902 } 17903 } 17904 if ($open_ifvalue) 17905 { 17906 $state->{'ignored'} = $type; 17907 $state->{'ifvalue'} = $type; 17908 $state->{'ifvalue_inside'} = 1; 17909 # We add at the top of the stack to be able to close all 17910 # opened comands when closing the ifset/ifclear (and ignore 17911 # everything that is in those commands) 17912 push @$stack, { 'style' => 'ifvalue', 'text' => '' }; 17913 } 17914 } 17915 else 17916 { # we accept a lone @ifset or @ifclear if it is inside an 17917 if ($type eq $state->{'ifvalue'}) 17918 { 17919 $state->{'ifvalue_inside'}++; 17920 return ($line,''); 17921 } 17922 echo_error ("Bad $type line: $line", $line_nr) unless ($state->{'ignored'}); 17923 } 17924 } 17925 elsif (not $Texi2HTML::Config::texi_formats_map{$type}) 17926 { # ignored text 17927 $state->{'ignored'} = $type; 17928 #print STDERR "IGNORED\n"; 17929 } 17930 else 17931 { 17932 push @{$state->{'text_macro_stack'}}, $type unless($state->{'ignored'}) ; 17933 } 17934 my $text = "\@$type"; 17935 $text .= $value if defined($value); 17936 return ($line, $text); 17937} 17938 17939# do regions handled specially, currently only tex, going through latex2html 17940sub init_special($$) 17941{ 17942 my $style = shift; 17943 my $text = shift; 17944 if (defined($Texi2HTML::Config::command_handler{$style}) and 17945 defined($Texi2HTML::Config::command_handler{$style}->{'init'})) 17946 { 17947 $special_commands{$style}->{'count'} = 0 if (!defined($special_commands{$style})); 17948 if ($Texi2HTML::Config::command_handler{$style}->{'init'}($style,$text, 17949 $special_commands{$style}->{'count'} +1)) 17950 { 17951 $special_commands{$style}->{'count'}++; 17952 return "\@special_${style}_".$special_commands{$style}->{'count'}."{}"; 17953 } 17954 return ''; 17955 } 17956} 17957 17958# FIXME we cannot go through the commands too 'often'. The error messages 17959# are duplicated and global stuff is changed. 17960# -> identify what is global 17961# -> use local state 17962sub do_special_region_lines($;$) 17963{ 17964 my $region = shift; 17965 my $state = shift; 17966 17967 # this case covers something like 17968 # @copying 17969 # @insertcopying 17970 # @end copying 17971 if (defined($state) and exists($state->{'region'}) and ($region eq $state->{'region'})) 17972 { 17973 echo_error("Recursively expanding region $region in $state->{'region'}"); 17974 return ('','', ''); 17975 17976 } 17977 17978 print STDERR "# do_special_region_lines for region $region ($region_initial_state{$region}->{'multiple_pass'}, region_initial_state{$region}->{'region_pass'})" if ($T2H_DEBUG); 17979 if (!defined($state)) 17980 { 17981 fill_state($state); 17982 $state->{'outside_document'} = 1; 17983 print STDERR " outside document\n" if ($T2H_DEBUG); 17984 } 17985 elsif (!$state->{'outside_document'}) 17986 { 17987 $region_initial_state{$region}->{'multiple_pass'}++; 17988 print STDERR " multiple pass $region_initial_state{$region}->{'multiple_pass'}\n" if ($T2H_DEBUG); 17989 } 17990 else 17991 { 17992 print STDERR " in $state->{'region'}, outside document\n" if ($T2H_DEBUG); 17993 } 17994 17995 return ('','','') unless @{$region_lines{$region}}; 17996 my $new_state = duplicate_formatting_state($state); 17997 foreach my $key (keys(%{$region_initial_state{$region}})) 17998 { 17999 $new_state->{$key} = $region_initial_state{$region}->{$key}; 18000 } 18001 &$Texi2HTML::Config::begin_special_region($region,$new_state,$region_lines{$region}) 18002 if (defined($Texi2HTML::Config::begin_special_region)); 18003 my $text = substitute_text($new_state, undef, @{$region_lines{$region}}); 18004 $text = &$Texi2HTML::Config::end_special_region($region,$new_state,$text) 18005 if (defined($Texi2HTML::Config::end_special_region)); 18006 18007 $region_initial_state{$region}->{'region_pass'}++; 18008 18009 my $remove_texi_state = duplicate_formatting_state($state); 18010 $remove_texi_state->{'remove_texi'} = 1; 18011 foreach my $key (keys(%{$region_initial_state{$region}})) 18012 { 18013 $remove_texi_state->{$key} = $region_initial_state{$region}->{$key}; 18014 } 18015 &$Texi2HTML::Config::begin_special_region($region,$remove_texi_state,$region_lines{$region}) 18016 if (defined($Texi2HTML::Config::begin_special_region)); 18017 print STDERR "# remove texi\n" if ($T2H_DEBUG); 18018 my $removed_texi = substitute_text($remove_texi_state, undef, @{$region_lines{$region}}); 18019 $removed_texi = &$Texi2HTML::Config::end_special_region($region,$remove_texi_state, $removed_texi) 18020 if (defined($Texi2HTML::Config::end_special_region)); 18021 $region_initial_state{$region}->{'region_pass'}++; 18022 18023 my $simple_format_state = duplicate_formatting_state($state); 18024 foreach my $key (keys(%{$region_initial_state{$region}})) 18025 { 18026 $simple_format_state->{$key} = $region_initial_state{$region}->{$key}; 18027 } 18028 18029 &$Texi2HTML::Config::begin_special_region($region,$simple_format_state,$region_lines{$region}) 18030 if (defined($Texi2HTML::Config::begin_special_region)); 18031 print STDERR "# simple format\n" if ($T2H_DEBUG); 18032 my $simple_format = simple_format($simple_format_state, undef, @{$region_lines{$region}}); 18033 $simple_format = &$Texi2HTML::Config::end_special_region($region,$simple_format_state, $simple_format) 18034 if (defined($Texi2HTML::Config::end_special_region)); 18035 $region_initial_state{$region}->{'region_pass'}++; 18036 18037 return ($text, $removed_texi, $simple_format); 18038} 18039 18040sub do_insertcopying($) 18041{ 18042 my $state = shift; 18043 my ($text, $comment, $simple_formatted) = do_special_region_lines('copying', $state); 18044 return &$Texi2HTML::Config::insertcopying($text, $comment, $simple_formatted); 18045} 18046 18047sub get_deff_index($$$) 18048{ 18049 my $tag = shift; 18050 my $line = shift; 18051 my $line_nr = shift; 18052 18053 $tag =~ s/x$//; 18054 my ($command, $style, $category, $name, $type, $class, $arguments, $args_array, $args_type_array); 18055 ($command, $style, $category, $name, $type, $class, $arguments, $args_array, $args_type_array) = parse_def($tag, $line, $line_nr, 1); 18056 $name = &$Texi2HTML::Config::definition_index_entry($name, $class, $style, $command); 18057 return ($style, '') if (!defined($name) or ($name =~ /^\s*$/)); 18058 return ($style, $name, $arguments); 18059} 18060 18061sub parse_def($$$;$) 18062{ 18063 my $command = shift; 18064 my $line = shift; 18065 my $line_nr = shift; 18066 my $report = shift; 18067 18068 my $format = $command; 18069 18070 if (!ref ($Texi2HTML::Config::def_map{$command})) 18071 { 18072 # substitute shortcuts for definition commands 18073 my $substituted = $Texi2HTML::Config::def_map{$command}; 18074 $substituted =~ s/(\w+)//; 18075 $format = $1; 18076 $line = $substituted . $line; 18077 } 18078#print STDERR "PARSE_DEF($command,$format) $line"; 18079 my ($category, $name, $type, $class, $arguments); 18080 my @arguments = (); 18081 my @args = @{$Texi2HTML::Config::def_map{$format}}; 18082 my $style = shift @args; 18083 my @arg_types = (); 18084 while (@args and $args[0] ne 'arg' and $args[0] ne 'argtype') 18085 { 18086 my $arg = shift @args; 18087 # backward compatibility, it was possible to have a { in front. 18088 $arg =~ s/^\{//; 18089 my ($item, $spaces); 18090 ($item, $line, $spaces) = next_def_param($line, $line_nr, $report); 18091 last if (!defined($item)); 18092 #$item =~ s/^\{(.*)\}$/$1/ if ($item =~ /^\{/); 18093 if ($arg eq 'category') 18094 { 18095 $category = $item; 18096 } 18097 elsif ($arg eq 'name') 18098 { 18099 $name = $item; 18100 } 18101 elsif ($arg eq 'type') 18102 { 18103 $type = $item; 18104 } 18105 elsif ($arg eq 'class') 18106 { 18107 $class = $item; 18108 } 18109 push @arg_types, $arg; 18110 push @arguments, $item; 18111 } 18112 my $line_remaining = $line; 18113 $line = ''; 18114 my $arg_and_type = 1; 18115 foreach my $arg (@args) 18116 { 18117 if ($arg eq 'arg') 18118 { 18119 $arg_and_type = 0; 18120 last; 18121 } 18122 elsif ($arg eq 'argtype') 18123 { 18124 last; 18125 } 18126 } 18127 18128 my $always_delimiter_quoted = quotemeta($Texi2HTML::Config::def_always_delimiters); 18129 my $in_type_delimiter_quoted = quotemeta($Texi2HTML::Config::def_in_type_delimiters); 18130 my $after_type = 0; 18131 while ($line_remaining !~ /^\s*$/) 18132 { 18133 my ($item, $spaces); 18134 ($item, $line_remaining,$spaces) = next_def_param($line_remaining, $line_nr); 18135 if ($item =~ /^([$always_delimiter_quoted])/ or (!$arg_and_type and $item =~ /^([$in_type_delimiter_quoted].*)/)) 18136 { 18137 $item = $1; 18138 push @arg_types, 'delimiter'; 18139 $after_type = 0; 18140 } 18141 elsif (!$arg_and_type or $item =~ /^\@/ or $after_type) 18142 { 18143 push @arg_types, 'param'; 18144 $after_type = 0; 18145 } 18146 elsif ($item =~ /^([$in_type_delimiter_quoted])/) 18147 { 18148 push @arg_types, 'delimiter'; 18149 } 18150 else 18151 { 18152 push @arg_types, 'paramtype'; 18153 $after_type = 1; 18154 } 18155 18156 #$item =~ s/^\{(.*)\}$/$1/ if ($item =~ /^\{/); 18157 $line .= $spaces . $item; 18158 push @arguments, $spaces .$item; 18159 } 18160#print STDERR "PARSE_DEF (style $style, category $category, name $name, type $type, class $class, line $line)\n"; 18161 return ($format, $style, $category, $name, $type, $class, $line, \@arguments, \@arg_types); 18162} 18163 18164sub begin_paragraph($$) 18165{ 18166 my $stack = shift; 18167 my $state = shift; 18168 18169 my $command = { }; 18170 my $top_format = top_format($stack); 18171 if (defined($top_format)) 18172 { 18173 $command = $top_format; 18174 } 18175 $command->{'stack_at_beginning'} = [ @{$state->{'command_stack'}} ]; 18176 my $paragraph_or_preformatted = 'paragraph'; 18177 if ($state->{'preformatted'}) 18178 { 18179 $paragraph_or_preformatted = 'preformatted'; 18180 $state->{'preformatted_context'} = $command; 18181 } 18182 else 18183 { 18184 $state->{'paragraph_context'} = $command; 18185 $state->{'paragraph_nr'}++; 18186 } 18187 push @$stack, {'format' => $paragraph_or_preformatted, 'text' => '' }; 18188 # FIXME give line, and modify line? 18189 &$Texi2HTML::Config::begin_paragraph_texi($paragraph_or_preformatted, 18190 $state->{'paragraph_macros'}, $command, $state, $stack) 18191 if (defined($Texi2HTML::Config::begin_paragraph_texi)); 18192 # if there are macros which weren't closed when the previous 18193 # paragraph was closed we reopen them here 18194 push @$stack, @{$state->{'paragraph_macros'}} if $state->{'paragraph_macros'}; 18195 delete $state->{'paragraph_macros'}; 18196} 18197 18198sub parse_format_command($$) 18199{ 18200 my $line = shift; 18201 my $tag = shift; 18202 my $command = ''; 18203 # macro_regexp 18204 if ($line =~ /^\s*\@([A-Za-z][\w-]*)(\{\})?$/ or $line =~ /^\s*\@([A-Za-z][\w-]*)(\{\})?\s/) 18205 { 18206 my $macro = $1; 18207 $macro = $alias{$macro} if (exists($alias{$macro})); 18208 if ($::things_map_ref->{$macro} or defined($::style_map_ref->{$macro})) 18209 { 18210 # macro_regexp 18211 $line =~ s/^\s*\@([A-Za-z][\w-]*)(\{\})?\s*//; 18212 $command = $1; 18213 } 18214 } 18215 return ('', $command) if ($line =~ /^\s*$/); 18216 chomp $line; 18217 $line = substitute_text ({'keep_nr' => 1, 'keep_texi' => 1, 'check_item' => $tag}, undef, $line); 18218 return ($line, $command); 18219} 18220 18221sub parse_enumerate($) 18222{ 18223 my $line = shift; 18224 my $spec; 18225 if ($line =~ /^\s*(\w)\b/ and ($1 ne '_')) 18226 { 18227 $spec = $1; 18228 $line =~ s/^\s*(\w)\s*//; 18229 } 18230 return ($line, $spec); 18231} 18232 18233sub parse_multitable($$) 18234{ 18235 my $line = shift; 18236 my $line_nr = shift; 18237 # first find the table width 18238 my $table_width = 0; 18239 my $fractions; 18240 my $elements; 18241 if ($line =~ s/^\s+\@columnfractions\s+//) 18242 { 18243 @$fractions = split /\s+/, $line; 18244 $table_width = scalar(@$fractions); 18245 foreach my $fraction (@$fractions) 18246 { 18247 unless ($fraction =~ /^(\d*\.\d+)|(\d+)\.?$/) 18248 { 18249 echo_error ("column fraction not a number: $fraction", $line_nr); 18250 #warn "$ERROR column fraction not a number: $fraction"; 18251 } 18252 } 18253 } 18254 else 18255 { 18256 my $element; 18257 my $line_orig = $line; 18258 while ($line !~ /^\s*$/) 18259 { 18260 my $spaces; 18261 ($element, $line, $spaces) = next_bracketed($line, $line_nr, 1); 18262 if ($element =~ /^\{/) 18263 { 18264 $table_width++; 18265 $element =~ s/^\{//; 18266 $element =~ s/\}\s*$//; 18267 push @$elements, $element; 18268 } 18269 else 18270 { 18271 echo_warn ("garbage in multitable specification: $element", $line_nr); 18272 } 18273 } 18274 } 18275 return ($table_width, $fractions, $elements); 18276} 18277 18278sub end_format($$$$$) 18279{ 18280 my $text = shift; 18281 my $stack = shift; 18282 my $state = shift; 18283 my $format = shift; 18284 my $line_nr = shift; 18285 #print STDERR "END FORMAT $format ".format_line_number($line_nr)."\n"; 18286 #dump_stack($text, $stack, $state); 18287 #sleep 1; 18288 if ($format_type{$format} eq 'menu') 18289 { 18290 $state->{$format}--; 18291 if ($state->{$format} < 0) 18292 { # FIXME currently happens, see invalid/not_closed_in_menu.texi 18293 echo_error("Too many menu closed", $line_nr); 18294 #print STDERR "Bug, $format counter negative: $state->{$format}\n"; 18295 #dump_stack($text, $stack, $state); 18296 #exit 1; 18297 $state->{$format} = 0; 18298 } 18299 close_menu_comment($text, $stack, $state, $line_nr); 18300 } 18301 18302 if ($format_type{$format} eq 'list') 18303 { # those functions return if they detect an inapropriate context 18304 add_item($text, $stack, $state, $line_nr); # handle lists 18305 } 18306 elsif ($format eq 'multitable') 18307 { 18308 add_row($text, $stack, $state, $line_nr); # handle multitable 18309 } 18310 elsif ($format_type{$format} eq 'table') 18311 { 18312 add_term($text, $stack, $state, $line_nr); # handle table 18313 add_line($text, $stack, $state, $line_nr); # handle table 18314 } 18315 18316 #print STDERR "END_FORMAT\n"; 18317 #dump_stack($text, $stack, $state); 18318 18319 # set to 1 if there is a mismatch between the closed format and format 18320 # opened before 18321 my $format_mismatch = 0; 18322 # set to 1 in normal menu context after an end menu or detailmenu 18323 my $begin_menu_comment_after_end_format = 0; 18324 18325 my $format_ref = pop @$stack; 18326 18327 ######################### debug 18328 if (!defined($format_ref->{'text'})) 18329 { 18330 push @$stack, $format_ref; 18331 print STDERR "Bug: text undef in end_format $format\n"; 18332 dump_stack($text, $stack, $state); 18333 pop @$stack; 18334 } 18335 ######################### end debug 18336 18337 if ($region_lines{$format}) 18338 { 18339 ######################### debug 18340 if ($format ne $state->{'region_lines'}->{'format'}) 18341 { 18342 echo_warn ("Bug: mismatched region `$format' ne `$state->{'region_lines'}->{'format'}'"); 18343 } 18344 ######################### end debug 18345 $state->{'region_lines'}->{'number'}--; 18346 if ($state->{'region_lines'}->{'number'} == 0) 18347 { 18348 close_region($state); 18349 } 18350 } 18351 if (defined($Texi2HTML::Config::def_map{$format})) 18352 { 18353 close_stack($text, $stack, $state, $line_nr, 'deff_item') 18354 unless ($format_ref->{'format'} eq 'deff_item'); 18355 add_prev($text, $stack, &$Texi2HTML::Config::def_item($format_ref->{'text'}, $format_ref->{'only_inter_commands'})); 18356 $format_ref = pop @$stack; # pop deff 18357 ######################################### debug 18358 if (!defined($format_ref->{'format'}) or !defined($Texi2HTML::Config::def_map{$format_ref->{'format'}})) 18359 { 18360 print STDERR "Bug: not a def* under deff_item\n"; 18361 push (@$stack, $format_ref); 18362 dump_stack($text, $stack, $state); 18363 pop @$stack; 18364 } 18365 ######################################### end debug 18366 elsif ($format_ref->{'format'} ne $format) 18367 { 18368 $format_mismatch = 1; 18369 echo_warn ("Waiting for \@end $format_ref->{'format'}, found \@end $format", $line_nr); 18370 } 18371 add_prev($text, $stack, &$Texi2HTML::Config::def($format_ref->{'text'})); 18372 } 18373 elsif ($format_type{$format} eq 'cartouche') 18374 { 18375 add_prev($text, $stack, &$Texi2HTML::Config::cartouche($format_ref->{'text'},$state->{'command_stack'})); 18376 } 18377 elsif ($format eq 'float') 18378 { 18379 unless (defined($state->{'float'})) 18380 { 18381 print STDERR "Bug: state->{'float'} not defined in float\n"; 18382 next; 18383 } 18384 my ($caption_lines, $shortcaption_lines) = &$Texi2HTML::Config::caption_shortcaption($state->{'float'}); 18385 my ($caption_text, $shortcaption_text); 18386 my $caption_state = duplicate_formatting_state($state); 18387 push @{$caption_state->{'command_stack'}}, 'caption'; 18388 $caption_text = substitute_text($caption_state, undef, @$caption_lines) if (defined($caption_lines)); 18389 my $shortcaption_state = duplicate_formatting_state($state); 18390 push @{$shortcaption_state->{'command_stack'}}, 'shortcaption'; 18391 $shortcaption_text = substitute_text($shortcaption_state,undef, @$shortcaption_lines) if (defined($shortcaption_lines)); 18392 add_prev($text, $stack, &$Texi2HTML::Config::float($format_ref->{'text'}, $state->{'float'}, $caption_text, $shortcaption_text)); 18393 delete $state->{'float'}; 18394 } 18395 elsif (exists ($Texi2HTML::Config::complex_format_map->{$format})) 18396 { 18397 $state->{'preformatted'}--; 18398 pop @{$state->{'preformatted_stack'}}; 18399 # debug 18400 if (!defined($Texi2HTML::Config::complex_format_map->{$format_ref->{'format'}}->{'begin'})) 18401 { 18402 print STDERR "Bug undef $format_ref->{'format'}" . "->{'begin'} (for $format...)\n"; 18403 dump_stack ($text, $stack, $state); 18404 } 18405 if ($fake_format{$format_ref->{'format'}} and $format_ref->{'text'} =~ /^\s*$/) 18406 { 18407 # discard empty fake formats 18408 } 18409 #print STDERR "before $format\n"; 18410 #dump_stack ($text, $stack, $state); 18411 else 18412 { 18413 add_prev($text, $stack, &$Texi2HTML::Config::complex_format($format_ref->{'format'}, $format_ref->{'text'})); 18414 } 18415 #print STDERR "after $format\n"; 18416 #dump_stack ($text, $stack, $state); 18417 } 18418 elsif ($format_type{$format} eq 'table' or $format_type{$format} eq 'list' or $format eq 'multitable') 18419 { 18420 #print STDERR "CLOSE $format ($format_ref->{'format'})\n$format_ref->{'text'}\n"; 18421 #dump_stack($text, $stack, $state); 18422 if ($format_ref->{'format'} ne $format) 18423 { # for example vtable closing a table. Cannot be known 18424 # before if in a cell 18425 $format_mismatch = 1; 18426 echo_warn ("Waiting for \@end $format_ref->{'format'}, found \@end $format ", $line_nr); 18427 } 18428 if ($Texi2HTML::Config::format_map{$format}) 18429 { # table or list has a simple format 18430 add_prev($text, $stack, end_simple_format($format_ref->{'format'}, $format_ref->{'text'}, $state)); 18431 } 18432 else 18433 { # table or list handler defined by the user 18434 add_prev($text, $stack, &$Texi2HTML::Config::table_list($format_ref->{'format'}, $format_ref->{'text'}, $format_ref->{'command'}, $format_ref->{'formatted_command'}, $format_ref->{'item_nr'}, $format_ref->{'spec'}, $format_ref->{'prepended'}, $format_ref->{'prepended_formatted'}, $format_ref->{'columnfractions'}, $format_ref->{'prototype_row'}, $format_ref->{'prototype_lengths'}, $format_ref->{'max_columns'})); 18435 } 18436 } 18437 elsif ($format_type{$format} eq 'quotation') 18438 { 18439 my $quotation_args = pop @{$state->{'quotation_stack'}}; 18440 #add_prev($text, $stack, &$Texi2HTML::Config::quotation($format_ref->{'text'}, $quotation_args->{'text'}, $quotation_args->{'style_texi'}, $quotation_args->{'style_id'})); 18441 add_prev($text, $stack, &$Texi2HTML::Config::quotation($format, $format_ref->{'text'}, $quotation_args->{'text'}, $quotation_args->{'text_texi'})); 18442 } 18443 elsif ($Texi2HTML::Config::paragraph_style{$format}) 18444 { 18445 if ($state->{'paragraph_style'}->[-1] eq $format) 18446 { 18447 pop @{$state->{'paragraph_style'}}; 18448 } 18449 if ($fake_format{$format_ref->{'format'}} and $format_ref->{'text'} =~ /^\s*$/) 18450 { 18451 # discard empty fake formats 18452 } 18453 else 18454 { 18455 add_prev($text, $stack, &$Texi2HTML::Config::paragraph_style_command($format_ref->{'format'},$format_ref->{'text'})); 18456 } 18457 } 18458 elsif (exists($Texi2HTML::Config::format_map{$format})) 18459 { 18460 if ($fake_format{$format_ref->{'format'}} and $format_ref->{'text'} =~ /^\s*$/) 18461 { 18462 # discard empty fake formats 18463 } 18464 else 18465 { 18466 add_prev($text, $stack, end_simple_format($format_ref->{'format'}, $format_ref->{'text'}, $state)); 18467 } 18468 } 18469 elsif ($format_type{$format} eq 'menu') 18470 { 18471 # it should be short-circuited if $Texi2HTML::Config::SIMPLE_MENU 18472 if ($state->{'preformatted'}) 18473 { 18474 # remove the fake complex style 18475 $state->{'preformatted'}--; 18476 pop @{$state->{'preformatted_stack'}}; 18477 } 18478 18479 # backward compatibility with 1.78 18480 if (defined($Texi2HTML::Config::menu)) 18481 { 18482 if ($format eq 'menu') 18483 { 18484 add_prev($text, $stack, &$Texi2HTML::Config::menu($format_ref->{'text'})); 18485 } 18486 else # detailmenu 18487 { 18488 add_prev($text, $stack, $format_ref->{'text'}); 18489 } 18490 } 18491 else 18492 { 18493 add_prev($text, $stack, &$Texi2HTML::Config::menu_command($format, $format_ref->{'text'}, $state->{'preformatted'})); 18494 } 18495 $begin_menu_comment_after_end_format = 1; 18496 } 18497 else 18498 { 18499 echo_warn("Unknown format $format", $line_nr); 18500 } 18501 18502 # fake formats are not on the command_stack 18503 return 1 if ($fake_format{$format_ref->{'format'}}); 18504 # special case for center as it is at the bottom of the stack 18505 my $removed_from_stack; 18506 if ($format eq 'center') 18507 { 18508 $removed_from_stack = shift @{$state->{'command_stack'}}; 18509 } 18510 else 18511 { 18512 $removed_from_stack = pop @{$state->{'command_stack'}}; 18513 } 18514 if ($removed_from_stack ne $format and !$format_mismatch) 18515 { 18516 #echo_error ("Bug: removed_from_stack $removed_from_stack ne format $format", $line_nr); 18517 # it may not be a bug. Consider, for example a @code{in code 18518 # @end cartouche 18519 # The @code is closed when the paragraph is closed by 18520 # @end cartouche but not really closed since it might have been 18521 # a multiple paragraph @code. So it is not removed from 18522 # command_stack but still have disapeared from the stack! 18523 echo_error("Closing format $format, got $removed_from_stack", $line_nr); 18524 } 18525 if ($begin_menu_comment_after_end_format and $state->{'menu'}) 18526 { 18527 begin_format($text, $stack, $state, 'menu_comment', '', $line_nr); 18528 return 0; 18529 } 18530 return 1; 18531} 18532 18533sub push_complex_format_style($$$) 18534{ 18535 my $command = shift; 18536 my $complex_format = shift; 18537 my $state = shift; 18538 my $class = $command; 18539 $class = $complex_format->{'class'} if (defined($complex_format->{'class'})); 18540 my $format_style = {'pre_style' =>$complex_format->{'pre_style'}, 'class' => $class, 'command' => $command }; 18541 if (defined($complex_format->{'style'})) 18542 { 18543 $format_style->{'style'} = $complex_format->{'style'}; 18544 } 18545 else 18546 { 18547 if ($state->{'preformatted'} and defined($state->{'preformatted_stack'}->[-1]->{'style'})) 18548 { 18549 $format_style->{'style'} = $state->{'preformatted_stack'}->[-1]->{'style'}; 18550 } 18551 my $index = scalar(@{$state->{'preformatted_stack'}}) -1; 18552 # since preformatted styles are not nested, the preformatted format 18553 # of the first format with style has to be used 18554 if ($index > 0) 18555 { 18556 while ($index) 18557 { 18558 if ($state->{'preformatted_stack'}->[$index]->{'style'}) 18559 { 18560 $format_style->{'class'} = $state->{'preformatted_stack'}->[$index]->{'class'} if (defined($state->{'preformatted_stack'}->[$index]->{'class'})); 18561 last; 18562 } 18563 $index--; 18564 } 18565 } 18566 } 18567 $state->{'preformatted'}++; 18568 push @{$state->{'preformatted_stack'}}, $format_style; 18569} 18570 18571sub prepare_state_multiple_pass($$) 18572{ 18573 my $command = shift; 18574 my $state = shift; 18575 my $return_state = { 18576 'multiple_pass' => 1, 18577 'region_pass' => 1, 18578 'element' => $state->{'element'}, 18579 }; 18580 if (defined($command)) 18581 { 18582 $return_state->{'region'} = $command; 18583 $return_state->{'command_stack'} = ["$command"]; 18584 } 18585 return $return_state; 18586} 18587 18588sub begin_format($$$$$$); 18589 18590sub begin_format($$$$$$) 18591{ 18592 my $text = shift; 18593 my $stack = shift; 18594 my $state = shift; 18595 my $macro = shift; 18596 my $line = shift; 18597 my $line_nr = shift; 18598 #print STDERR "BEGIN FORMAT $macro".format_line_number($line_nr)."\n"; 18599 18600 18601 if ($format_type{$macro} eq 'menu') 18602 { 18603 if ($state->{'menu'}) 18604 { 18605 # there should not be any paragraph/preformatted to close 18606 # if the comment or the description were closed since they 18607 # close it 18608 if (! close_menu_comment($text, $stack, $state, $line_nr) 18609 and !close_menu_description($text, $stack, $state, $line_nr)) 18610 { 18611 close_paragraph($text, $stack, $state, $line_nr); 18612 } 18613 } 18614 else 18615 { 18616 close_paragraph($text, $stack, $state, $line_nr); 18617 } 18618 $state->{$macro}++; 18619 } 18620 else 18621 { 18622 close_paragraph($text, $stack, $state, $line_nr); 18623 } 18624 18625 $line = &$Texi2HTML::Config::begin_format_texi($macro, $line, $state) 18626 unless($fake_format{$macro}); 18627 18628 push (@{$state->{'command_stack'}}, $macro) unless ($fake_format{$macro}); 18629 if ($region_lines{$macro}) 18630 { 18631 open_region($macro,$state); 18632 } 18633 # A deff like macro 18634 if (defined($Texi2HTML::Config::def_map{$macro})) 18635 { 18636 my $top_format = top_format($stack); 18637 if (defined($top_format) and ("$top_format->{'format'}x" eq $macro)) 18638 { 18639 # this is a matching @DEFx command. 18640 # the @DEFx macro has been put at the top of the 18641 # command_stack, although there is no real format opening 18642 pop @{$state->{'command_stack'}}; 18643 $macro =~ s/x$//o; 18644 my $deff_item = pop @$stack; 18645 if ($deff_item->{'text'} !~ /s^\*$/) 18646 { 18647 add_prev($text, $stack, 18648 &$Texi2HTML::Config::def_item($deff_item->{'text'}, $deff_item->{'only_inter_commands'})); 18649 } 18650 #print STDERR "DEFx $macro\n"; 18651 } 18652 else 18653 { 18654 # a new @def. 18655 $macro =~ s/x$//o; 18656 # we remove what is on the stack and put it back, 18657 # to make sure that it is the form without x. 18658 pop @{$state->{'command_stack'}}; 18659 push @{$state->{'command_stack'}}, $macro; 18660 #print STDERR "DEF begin $macro\n"; 18661 $top_format = { 'format' => $macro, 'text' => '' }; 18662 push @$stack, $top_format; 18663 } 18664 #print STDERR "BEGIN_DEFF $macro\n"; 18665 #dump_stack ($text, $stack, $state); 18666 18667 my ($command, $style, $category, $name, $type, $class, $args_array, $args_type_array); 18668 ($command, $style, $category, $name, $type, $class, $line, $args_array, $args_type_array) = parse_def($macro, $line, $line_nr); 18669 #print STDERR "AFTER parse_def $line"; 18670 my @formatted_args = (); 18671 my $arguments = ''; 18672 my %formatted_arguments = (); 18673 my @types = @$args_type_array; 18674 foreach my $arg (@$args_array) 18675 { 18676 my $type = shift @types; 18677 my $substitution_state = duplicate_formatting_state($state); 18678 $substitution_state->{'code_style'}++; 18679 push @formatted_args, substitute_line($arg, $substitution_state, $line_nr); 18680 if (grep {$_ eq $type} ('param', 'paramtype', 'delimiter')) 18681 { 18682 $arguments .= $formatted_args[-1]; 18683 } 18684 else 18685 { 18686 $formatted_arguments{$type} = $formatted_args[-1]; 18687 } 18688 18689 #if (grep {$_ eq $type} ('param', 'paramtype', 'delimiter')) 18690 #{ 18691 # if ($arg =~ /^\s*\@/) 18692 # { 18693 # push @formatted_args, substitute_line($arg, $substitution_state, $line_nr); 18694 # } 18695 # else 18696 # { 18697 # $substitution_state->{'code_style'}++; 18698 # push @formatted_args, substitute_line($arg, $substitution_state, $line_nr); 18699 # } 18700 # $arguments .= $formatted_args[-1]; 18701 #} 18702 #else 18703 #{ 18704 # push @formatted_args, substitute_line($arg, $substitution_state, $line_nr); 18705 # $formatted_arguments{$type} = $formatted_args[-1]; 18706 #} 18707 } 18708 $name = $formatted_arguments{'name'}; 18709 $category = $formatted_arguments{'category'}; 18710 $type = $formatted_arguments{'type'}; 18711 $class = $formatted_arguments{'class'}; 18712 18713 $name = '' if (!defined($name)); 18714 $category = '' if (!defined($category)); 18715 18716 my $class_category = &$Texi2HTML::Config::definition_category($category, $class, $style, $command); 18717 my $class_name = &$Texi2HTML::Config::definition_index_entry($name, $class, $style, $command); 18718 my ($index_entry, $index_label) = do_index_entry_label($macro, $state,$line_nr); 18719 add_prev($text, $stack, &$Texi2HTML::Config::def_line($class_category, $name, $type, $arguments, $index_label, \@formatted_args, $args_type_array, $args_array, $command, $class_name, $category, $class, $style, $macro)); 18720 $line = ''; 18721 push @$stack, { 'format' => 'deff_item', 'text' => '', 'only_inter_commands' => 1, 'format_ref' => $top_format}; 18722 begin_paragraph_after_command($state, $stack, $macro, $line); 18723 } 18724 elsif (exists ($Texi2HTML::Config::complex_format_map->{$macro})) 18725 { # handle menu if SIMPLE_MENU. see texi2html.init 18726 my $complex_format = $Texi2HTML::Config::complex_format_map->{$macro}; 18727 my $format = { 'format' => $macro, 'text' => '', 'pre_style' => $complex_format->{'pre_style'} }; 18728 push_complex_format_style($macro, $complex_format, $state); 18729 push @$stack, $format; 18730 18731 begin_paragraph($stack, $state); 18732 } 18733 elsif ($Texi2HTML::Config::paragraph_style{$macro}) 18734 { 18735 push (@$stack, { 'format' => $macro, 'text' => '' }); 18736 begin_paragraph_after_command($state,$stack,$macro,$line); 18737 push @{$state->{'paragraph_style'}}, $macro; 18738 if ($macro eq 'center') 18739 { 18740 # @center may be in a weird state with regard with 18741 # nesting, so we put it on the bottom of the stack 18742 pop @{$state->{'command_stack'}}; 18743 unshift @{$state->{'command_stack'}}, $macro; 18744 # for similar reasons, we may have a bad stack nesting 18745 # which results in } after a closing. 18746 # The following isn't really true anymore, I think: for example 18747 # @center @samp{something @center end of samp} 18748 # resulted to samp being kept in the 'command_stack' 18749 18750 } 18751 } 18752 elsif ($format_type{$macro} eq 'list' or $format_type{$macro} eq 'table' or $macro eq 'multitable') 18753 { 18754 my $format; 18755 #print STDERR "LIST_TABLE $macro\n"; 18756 #dump_stack($text, $stack, $state); 18757 if ($macro eq 'itemize' or $format_type{$macro} eq 'table') 18758 { 18759 my $command; 18760 my $prepended; 18761 ($prepended, $command) = parse_format_command($line,$macro); 18762 $command = 'asis' if (($command eq '') and ($macro ne 'itemize')); 18763 my $prepended_formatted; 18764 $prepended_formatted = substitute_line($prepended, prepare_state_multiple_pass('item', $state)) if (defined($prepended)); 18765 $format = { 'format' => $macro, 'text' => '', 'command' => $command, 'prepended' => $prepended, 'prepended_formatted' => $prepended_formatted }; 18766 $line = ''; 18767 } 18768 elsif ($macro eq 'enumerate') 18769 { 18770 my $spec; 18771 ($line, $spec) = parse_enumerate ($line); 18772 $spec = 1 if (!defined($spec)); 18773 $format = { 'format' => $macro, 'text' => '', 'spec' => $spec, 'item_nr' => 0 }; 18774 } 18775 elsif ($macro eq 'multitable') 18776 { 18777 my ($max_columns, $fractions, $prototype_row) = parse_multitable ($line, $line_nr); 18778 if (!$max_columns) 18779 { 18780 echo_warn ("empty multitable", $line_nr); 18781 $max_columns = 0; 18782 } 18783 my @prototype_lengths = (); 18784 if (defined($prototype_row)) 18785 { 18786 foreach my $prototype (@$prototype_row) 18787 { 18788 push @prototype_lengths, 2+length(substitute_line($prototype, prepare_state_multiple_pass('columnfractions', $state))); 18789 } 18790 } 18791 $format = { 'format' => $macro, 'text' => '', 'max_columns' => $max_columns, 'columnfractions' => $fractions, 'prototype_row' => $prototype_row, 'prototype_lengths' => \@prototype_lengths, 'cell' => 1 }; 18792 } 18793 $format->{'first'} = 1; 18794 $format->{'paragraph_number'} = 0; 18795 push @$stack, $format; 18796 if ($format_type{$macro} eq 'table') 18797 { 18798 push @$stack, { 'format' => 'line', 'text' => '', 'format_ref' => $format, 'only_inter_commands' => 1}; 18799 } 18800 elsif ($macro eq 'multitable') 18801 { 18802 push @$stack, { 'format' => 'row', 'text' => '', 'format_ref' => $format, 'item_cmd' => $macro }; 18803 push @$stack, { 'format' => 'cell', 'text' => '', 'format_ref' => $format, 'only_inter_commands' => 1}; 18804 } 18805 if ($format_type{$macro} eq 'list') 18806 { 18807 push @$stack, { 'format' => 'item', 'text' => '', 'format_ref' => $format, 'only_inter_commands' => 1}; 18808 } 18809 begin_paragraph_after_command($state,$stack,$macro,$line) 18810 if ($macro ne 'multitable'); 18811 return '' unless ($macro eq 'enumerate'); 18812 } 18813 elsif ($macro eq 'float' or $format_type{$macro} eq 'quotation') 18814 { 18815 push @$stack, {'format' => $macro, 'text' => '' }; 18816 if ($macro eq 'float') 18817 { 18818 open_cmd_line($stack, $state, ['keep','keep'], \&do_float_line); 18819 } 18820 elsif ($format_type{$macro} eq 'quotation') 18821 { 18822 open_cmd_line($stack, $state, ['keep'], \&do_quotation_line); 18823 } 18824 #dump_stack($text, $stack, $state); 18825 #next; 18826 } 18827 # keep this one at the end as there are some other formats 18828 # which are also in format_map 18829 elsif (defined($Texi2HTML::Config::format_map{$macro}) or ($format_type{$macro} eq 'cartouche')) 18830 { 18831 push @$stack, { 'format' => $macro, 'text' => '' }; 18832 $state->{'code_style'}++ if ($Texi2HTML::Config::format_code_style{$macro}); 18833 begin_paragraph_after_command($state,$stack,$macro,$line); 18834 } 18835 elsif ($format_type{$macro} eq 'menu') 18836 { 18837 # if $Texi2HTML::Config::SIMPLE_MENU we won't get there 18838 # as the menu is a complex format in that case, so it 18839 # is handled above 18840 push @$stack, { 'format' => $macro, 'text' => '' }; 18841 if ($state->{'preformatted'}) 18842 { 18843 # add a fake complex style in order to have a given pre style 18844 # FIXME check 'style' on bug-texinfo 18845 push_complex_format_style('menu', 18846 $Texi2HTML::Config::MENU_PRE_COMPLEX_FORMAT 18847# { 18848# 'pre_style' => $Texi2HTML::Config::MENU_PRE_STYLE, 18849# 'class' => 'menu-preformatted', 18850## 'style' => 'code' 18851# } 18852 , $state); 18853 begin_paragraph_after_command($state,$stack,$macro,$line); 18854 } 18855 else 18856 { 18857 begin_format($text, $stack, $state, 'menu_comment', $line, $line_nr); 18858 } 18859 } 18860 return $line; 18861} 18862 18863sub do_text($;$) 18864{ 18865 my $text = shift; 18866 my $state = shift; 18867 return $text if ($state->{'keep_texi'}); 18868 my $remove_texi = 1 if ($state->{'remove_texi'} and !$state->{'simple_format'}); 18869 my $preformatted_style = 0; 18870 if ($state->{'preformatted'}) 18871 { 18872 $preformatted_style = $state->{'preformatted_stack'}->[-1]->{'style'}; 18873 } 18874 return (&$Texi2HTML::Config::normal_text($text, $remove_texi, $preformatted_style, $state->{'code_style'},$state->{'simple_format'},$state->{'command_stack'}, $state)); 18875} 18876 18877sub end_simple_format($$$) 18878{ 18879 my $command = shift; 18880 my $text = shift; 18881 my $state = shift; 18882 18883 my $element = $Texi2HTML::Config::format_map{$command}; 18884 18885 my $result = &$Texi2HTML::Config::format($command, $element, $text); 18886 $state->{'code_style'}-- if ($Texi2HTML::Config::format_code_style{$command}); 18887 return $result; 18888} 18889 18890# only get there if not in SIMPLE_MENU and not in preformatted and 18891# right in @menu 18892sub close_menu_comment($$$$) 18893{ 18894 my $text = shift; 18895 my $stack = shift; 18896 my $state = shift; 18897 my $line_nr = shift; 18898 18899 my $top_format = top_stack($stack,2); 18900 if (defined($top_format->{'format'}) and $top_format->{'format'} eq 'menu_comment') 18901 { # this is needed to avoid empty menu-comments <tr>...<pre></pre> 18902 abort_empty_preformatted($stack, $state); 18903 18904 close_paragraph($text, $stack, $state, $line_nr); 18905 end_format($text, $stack, $state, 'menu_comment', $line_nr); 18906 return 1; 18907 } 18908} 18909 18910# never get there if in $SIMPLE_MENU 18911# the last arg is used only if in description and an empty line may 18912# stop it and begin a menu_comment 18913sub close_menu_description($$$$;$) 18914{ 18915 my $text = shift; 18916 my $stack = shift; 18917 my $state = shift; 18918 my $line_nr = shift; 18919 my $line = shift; 18920 18921 my $top_format = top_stack($stack,1); 18922 if (!$state->{'preformatted'}) 18923 { 18924 $top_format = top_stack($stack); 18925 } 18926 18927 if (defined($top_format->{'format'}) and $top_format->{'format'} eq 'menu_description' and (!defined($line) or $line =~ /^\s*$/) ) 18928 { 18929 close_paragraph($text, $stack, $state, $line_nr) if ($state->{'preformatted'}); 18930 my $descr = pop(@$stack); 18931 add_prev($text, $stack, do_menu_description($descr, $state)); 18932 print STDERR "# close_menu: close description\n" if ($T2H_DEBUG & $DEBUG_MENU); 18933 $state->{'code_style'}-- if ($Texi2HTML::Config::format_code_style{'menu_description'}); 18934 return 1; 18935 } 18936} 18937 18938# Format menu link 18939# FIXME also pass node and name? 18940sub do_menu_link($$$) 18941{ 18942 my $state = shift; 18943 my $line_nr = shift; 18944 my $menu_entry = shift; 18945# my $menu_entry = $state->{'menu_entry'}; 18946 my $file = $state->{'element'}->{'file'}; 18947 my $node_name = normalise_node($menu_entry->{'node'}); 18948 # normalise_node is used in fact to determine if name is empty. 18949 # It is not passed down to the function reference. 18950 my $name = normalise_node($menu_entry->{'name'}); 18951 18952 my $node_substitution_state = duplicate_formatting_state($state); 18953 my $name_substitution_state = duplicate_formatting_state($state); 18954 # normalise_node is not used, so that spaces are kept, like makeinfo. 18955 # also code_style is used, like makeinfo. 18956 $node_substitution_state->{'code_style'} = 1; 18957 $name_substitution_state->{'code_style'} = 1 if ($Texi2HTML::Config::format_code_style{'menu_name'}); 18958 my $node_formatted = substitute_line($menu_entry->{'node'}, $node_substitution_state, $line_nr); 18959 my $name_formatted; 18960 my $has_name = 0; 18961 if (defined($name) and $name ne '') 18962 { 18963 $name_formatted = substitute_line($menu_entry->{'name'}, $name_substitution_state, $line_nr); 18964 $has_name = 1; 18965 } 18966 else 18967 { 18968 $name_formatted = substitute_line($menu_entry->{'node'}, $name_substitution_state); 18969 } 18970 18971 my $entry = ''; 18972 my $href; 18973 my $element = $nodes{$node_name}; 18974 18975 # menu points to an unknown node 18976 if (!$element->{'seen'}) 18977 { 18978 if ($menu_entry->{'node'} =~ /^\s*\(.*\)/o or $novalidate) 18979 { 18980 # menu entry points to another info manual or invalid nodes 18981 # and novalidate is set 18982 #$href = $nodes{$node_name}->{'file'}; 18983 $href = do_external_href($node_name); 18984 } 18985 else 18986 { 18987 echo_error ("Unknown node in menu entry `$node_name'", $line_nr); 18988 # try to find an equivalent node 18989 my @equivalent_nodes = equivalent_nodes($node_name); 18990 my $node_seen; 18991 foreach my $equivalent_node (@equivalent_nodes) 18992 { 18993 if ($nodes{$equivalent_node}->{'seen'}) 18994 { 18995 $node_seen = $equivalent_node; 18996 last; 18997 } 18998 } 18999 if (defined($node_seen)) 19000 { 19001 echo_warn (" ---> but equivalent node `$node_seen' found"); 19002 $element = $nodes{$node_seen}; 19003 } 19004 } 19005 } 19006 19007 # the original node or an equivalent node was seen 19008 if ($element->{'seen'}) 19009 { 19010 if ($element->{'reference_element'}) 19011 { 19012 $element = $element->{'reference_element'}; 19013 } 19014 19015 #print STDERR "SUBHREF in menu for `$element->{'texi'}'\n"; 19016 $href = href($element, $file, $line_nr); 19017 if (! $element->{'node'}) 19018 { 19019 $entry = $element->{'text'}; # this is the section/node name 19020 $entry = "$Texi2HTML::Config::MENU_SYMBOL $entry" if (($entry ne '') and (!defined($element->{'number'}) or ($element->{'number'} =~ /^\s*$/)) and $Texi2HTML::Config::UNNUMBERED_SYMBOL_IN_MENU); 19021 } 19022 } 19023 # save the element used for the href for the description 19024 $menu_entry->{'menu_reference_element'} = $element; 19025 19026 return &$Texi2HTML::Config::menu_link($entry, $state, $href, $node_formatted, $name_formatted, $menu_entry->{'ending'}, $has_name, $state->{'command_stack'}, $state->{'preformatted'}); 19027} 19028 19029sub do_menu_description($$) 19030{ 19031 my $descr = shift; 19032 my $state = shift; 19033 my $text = $descr->{'text'}; 19034 my $menu_entry = $descr->{'menu_entry'}; 19035 19036 my $element = $menu_entry->{'menu_reference_element'}; 19037 19038 return &$Texi2HTML::Config::menu_description($text, duplicate_formatting_state($state),$element->{'text_nonumber'}, $state->{'command_stack'}, $state->{'preformatted'}); 19039} 19040 19041sub do_xref($$$$) 19042{ 19043 my $macro = shift; 19044 my $args = shift; 19045 my $style_stack = shift; 19046 my $state = shift; 19047 my $line_nr = shift; 19048 19049 my $result = ''; 19050 my @args = @$args; 19051 19052 my $j; 19053 for ($j = 0; $j <= $#$args; $j++) 19054 { 19055 $args[$j] = normalise_space($args[$j]); 19056 # print STDERR " ($j)$args[$j]\n"; 19057 } 19058 #print STDERR "DO_XREF: $macro\n"; 19059 if ($macro eq 'inforef') 19060 { 19061 if ((@args < 1) or $args[0] eq '') 19062 { 19063 echo_error ("First argument to \@$macro may not be empty", $line_nr); 19064 return ''; 19065 } 19066 } 19067 19068 #print STDERR "XREF: (@args)\n"; 19069 my $i; 19070 my $new_state = duplicate_formatting_state($state); 19071 $new_state->{'keep_texi'} = 0; 19072 $new_state->{'keep_nr'} = 0; 19073 19074 my $remove_texi = $new_state->{'remove_texi'}; 19075 19076 my @formatted_args; 19077 for ($i = 0; $i < 5; $i++) 19078 { 19079 $args[$i] = '' if (!defined($args[$i])); 19080 my $in_file_style; 19081 $in_file_style = 1 if ($i == 2 and $macro eq 'inforef' or $i == 3 and $macro ne 'inforef'); 19082 $new_state->{'code_style'}++ if ($in_file_style or $i == 0); 19083 $new_state->{'remove_texi'} = 1 if ($in_file_style); 19084 $formatted_args[$i] = substitute_line($args[$i], $new_state, $line_nr); 19085 $new_state->{'code_style'}-- if ($in_file_style or $i == 0); 19086 $new_state->{'remove_texi'} = $remove_texi if ($in_file_style); 19087 } 19088 19089 my $node_texi = $args[0]; 19090 $node_texi = normalise_node($node_texi); 19091 19092 my ($file_texi, $file); 19093 if ($macro eq 'inforef') 19094 { 19095 $file_texi = $args[2]; 19096 $file = $formatted_args[2]; 19097 } 19098 else 19099 { 19100 $file_texi = $args[3]; 19101 $file = $formatted_args[3]; 19102 } 19103 19104 # can be an argument or extracted from the node name 19105 my $file_arg_or_node_texi = $file_texi; 19106 my $file_arg_or_node = $file; 19107 19108 my $node_name; 19109 # the file in parenthesis is removed from node_without_file_texi if needed 19110 my $node_without_file_texi = $node_texi; 19111 # node with file, like (file)node 19112 my $node_and_file_texi; 19113 # the file in parenthesis present with the node 19114 my ($file_of_node_texi, $file_of_node); 19115 if ($node_without_file_texi =~ s/^\(([^\)]+)\)\s*//) 19116 { 19117 $file_of_node_texi = $1; 19118 $file_of_node = substitute_line($file_of_node_texi, $new_state); 19119 $node_name = substitute_line($node_without_file_texi, $new_state); 19120 $file_arg_or_node_texi = $file_of_node_texi if ($file_arg_or_node_texi eq ''); 19121 $file_arg_or_node = $file_of_node if ($file_arg_or_node eq ''); 19122 # the file argument takes precedence 19123 $node_and_file_texi = "($file_arg_or_node_texi)$node_without_file_texi"; 19124 } 19125 else 19126 { 19127 $node_name = $formatted_args[0]; 19128 if (defined ($file_texi) and $file_texi ne '') 19129 { 19130 $node_and_file_texi = "($file_texi)$node_texi"; 19131 } 19132 } 19133 19134 my $node_and_file; 19135 if (defined($node_and_file_texi)) 19136 { 19137 $node_and_file = substitute_line($node_and_file_texi, $new_state); 19138 } 19139 else 19140 { 19141 $node_and_file_texi = $node_texi; 19142 $node_and_file = $node_name; 19143 } 19144 19145 my $cross_ref_texi = $args[1]; 19146 my $cross_ref = $formatted_args[1]; 19147 19148 my ($manual_texi, $section_texi, $manual, $section); 19149 if ($macro ne 'inforef') 19150 { 19151 $manual_texi = $args[4]; 19152 $section_texi = $args[2]; 19153 $manual = $formatted_args[4]; 19154 $section = $formatted_args[2]; 19155 } 19156 else 19157 { 19158 $manual = $section = ''; 19159 } 19160 19161 #print STDERR "XREF: (@args)\n"; 19162 19163 if (($macro eq 'inforef') or ($file_arg_or_node_texi ne '') or ($manual_texi ne '')) 19164 {# external ref 19165 my $href = ''; 19166 if ($file_arg_or_node_texi ne '') 19167 { 19168 $href = do_external_href($node_and_file_texi); 19169 } 19170 else 19171 { 19172 $node_and_file = ''; 19173 } 19174 my $section_or_node = ''; 19175 if ($manual ne '') 19176 { 19177 $section_or_node = $node_name; 19178 if ($section ne '') 19179 { 19180 $section_or_node = $section; 19181 } 19182 } 19183 $result = &$Texi2HTML::Config::external_ref($macro, $section_or_node, $manual, $node_and_file, $href, $cross_ref, \@args, \@formatted_args); 19184 } 19185 else 19186 { 19187 my $element = $nodes{$node_without_file_texi}; 19188 if ($element and $element->{'seen'}) 19189 { 19190 if ($element->{'reference_element'}) 19191 { 19192 $element = $element->{'reference_element'}; 19193 } 19194 my $file = ''; 19195 if (defined($state->{'element'})) 19196 { 19197 $file = $state->{'element'}->{'file'}; 19198 } 19199 else 19200 { 19201 echo_warn ("\@$macro not in text (in anchor, node, section...)", $line_nr); 19202 # if Texi2HTML::Config::SPLIT the file is '' which ensures 19203 # a href with the file name. if ! Texi2HTML::Config::SPLIT 19204 # the 2 file will be the same thus there won't be the file name 19205 $file = $element->{'file'} unless ($Texi2HTML::Config::SPLIT); 19206 } 19207 #print STDERR "SUBHREF in ref to node `$node_texi'"; 19208 my $href = href($element, $file, $line_nr); 19209 my $section_or_cross_ref = $section; 19210 $section_or_cross_ref = $cross_ref if ($section eq ''); 19211 my $name = $section_or_cross_ref; 19212 my $short_name = $section_or_cross_ref; 19213 if ($section_or_cross_ref eq '') 19214 { 19215 # FIXME maybe one should use 'text' instead of 'text_nonumber' 19216 # However the real fix would be to have an internal_ref call 19217 # with more informations 19218 $name = $element->{'text_nonumber'}; 19219 $short_name = $node_name; 19220 } 19221 $result = &$Texi2HTML::Config::internal_ref ($macro, $href, $short_name, $name, $element->{'section'}, \@args, \@formatted_args); 19222 } 19223 else 19224 { 19225 if (($node_texi eq '') or !$novalidate) 19226 { 19227 echo_error ("Undefined node `$node_texi' in \@$macro", $line_nr); 19228 my $text = ''; 19229 for (my $i = 0; $i < @$args -1; $i++) 19230 { 19231 $text .= $args->[$i] .','; 19232 } 19233 $text .= $args->[-1]; 19234 $result = "\@$macro"."{${text}}"; 19235 } 19236 else 19237 { 19238 $result = &$Texi2HTML::Config::external_ref($macro, '', '', $node_name, do_external_href($node_texi), $cross_ref, \@args, \@formatted_args); 19239 } 19240 } 19241 } 19242 return $result; 19243} 19244 19245sub do_acronym_like($$$$$) 19246{ 19247 my $command = shift; 19248 my $args = shift; 19249 my $acronym_texi = shift @$args; 19250 my $explanation = shift @$args; 19251 my $style_stack = shift; 19252 my $state = shift; 19253 my $line_nr = shift; 19254 19255 my $explanation_lines; 19256 my $explanation_text; 19257 my $explanation_simple_format; 19258 19259 if (defined($explanation)) 19260 { 19261 $explanation =~ s/^\s*//; 19262 $explanation =~ s/\s*$//; 19263 $explanation = undef if ($explanation eq ''); 19264 } 19265 $acronym_texi =~ s/^\s*//; 19266 $acronym_texi =~ s/\s*$//; 19267 19268 return '' if ($acronym_texi eq ''); 19269 19270 my $with_explanation = 0; 19271 my $normalized_text = cross_manual_line(normalise_node($acronym_texi)); 19272 if (defined($explanation)) 19273 { 19274 $with_explanation = 1; 19275 $acronyms_like{$command}->{$normalized_text} = $explanation; 19276 } 19277 elsif (exists($acronyms_like{$command}->{$normalized_text})) 19278 { 19279 $explanation = $acronyms_like{$command}->{$normalized_text}; 19280 } 19281 19282 if (defined($explanation)) 19283 { 19284 @$explanation_lines = map {$_ = $_."\n"} split (/\n/, $explanation); 19285 my $text = ''; 19286 foreach my $line(@$explanation_lines) 19287 { 19288 $line .= ' ' if (chomp ($line)); 19289 $text .= $line 19290 } 19291 $text =~ s/ $//; 19292 $explanation_simple_format = simple_format($state, undef, $text); 19293 $explanation_text = substitute_line($text, duplicate_formatting_state($state), $line_nr); 19294 } 19295 return &$Texi2HTML::Config::acronym_like($command, $acronym_texi, substitute_line($acronym_texi, duplicate_formatting_state($state), $line_nr), 19296 $with_explanation, $explanation_lines, $explanation_text, $explanation_simple_format); 19297} 19298 19299sub do_caption_shortcaption($$$$$) 19300{ 19301 my $command = shift; 19302 my $args = shift; 19303 my $text_texi = $args->[0]; 19304 my $style_stack = shift; 19305 my $state = shift; 19306 my $line_nr = shift; 19307 19308 if (!exists($state->{'float'})) 19309 { 19310#dump_stack(\"", [], $state); 19311 echo_error("\@$command outside of float", $line_nr); 19312 return ''; 19313 } 19314 my $float = $state->{'float'}; 19315 my @texi_lines = map {$_ = $_."\n"} split (/\n/, $text_texi); 19316 $float->{"${command}_texi"} = \@texi_lines; 19317 return &$Texi2HTML::Config::caption_shortcaption_command($command, 19318 substitute_text(prepare_state_multiple_pass($command, $state) , undef, @texi_lines), \@texi_lines, $float); 19319} 19320 19321# function called when a @float is encountered. Don't do any output 19322# but prepare $state->{'float'} 19323sub do_float_line($$$$$) 19324{ 19325 my $command = shift; 19326 my $args = shift; 19327 my $style_stack = shift; 19328 my $state = shift; 19329 my $line_nr = shift; 19330 19331 my @args = @$args; 19332 my $style_texi = shift @args; 19333 my $label_texi = shift @args; 19334 19335 $style_texi = undef if (defined($style_texi) and $style_texi=~/^\s*$/); 19336 $label_texi = undef if (defined($label_texi) and $label_texi=~/^\s*$/); 19337 if (defined($label_texi)) 19338 { # the float is considered as a node as it may be a target for refs. 19339 # it was entered as a node in the pass_structure and the float 19340 # line was parsed at that time 19341 $state->{'float'} = $nodes{normalise_node($label_texi)}; 19342 #print STDERR "float: $state->{'float'}, $state->{'float'}->{'texi'}\n"; 19343 } 19344 else 19345 { # a float without label. It can't be the target for refs. 19346 $state->{'float'} = { 'float' => 1 }; 19347 if (defined($style_texi)) 19348 { 19349 $state->{'float'}->{'style_texi'} = normalise_space($style_texi); 19350 $state->{'float'}->{'style_id'} = 19351 cross_manual_line($state->{'float'}->{'style_texi'}); 19352 } 19353 #print STDERR "float: (no label) $state->{'float'}\n"; 19354 } 19355 $state->{'float'}->{'style'} = substitute_line($state->{'float'}->{'style_texi'}, undef, $line_nr); 19356# $state->{'cmd_line'} = 0; 19357 return ''; 19358} 19359 19360sub do_quotation_line($$$$$) 19361{ 19362 my $command = shift; 19363 my $args = shift; 19364 my @args = @$args; 19365 my $text_texi = shift @args; 19366 my $style_stack = shift; 19367 my $state = shift; 19368 my $line_nr = shift; 19369 my $text; 19370 19371 $text_texi = undef if (defined($text_texi) and $text_texi=~/^\s*$/); 19372 if (defined($text_texi)) 19373 { 19374 $text = substitute_line($text_texi, duplicate_formatting_state($state), $line_nr); 19375 $text =~ s/\s*$//; 19376 } 19377 my $quotation_args = { 'text' => $text, 'text_texi' => $text_texi }; 19378 push @{$state->{'quotation_stack'}}, $quotation_args; 19379 $state->{'prepend_text'} = &$Texi2HTML::Config::quotation_prepend_text($command, $text_texi); 19380# $state->{'cmd_line'} = 0; 19381 return ''; 19382} 19383 19384sub do_footnote($$$$) 19385{ 19386 my $command = shift; 19387 my $args = shift; 19388 my $text = $args->[0]; 19389 my $style_stack = shift; 19390 my $doc_state = shift; 19391 my $line_nr = shift; 19392 19393 $text .= "\n"; 19394 19395#print STDERR "FOOTNOTE($global_foot_num, $doc_state->{'outside_document'} or $doc_state->{'multiple_pass'}) $text"; 19396 my $foot_state = duplicate_state($doc_state); 19397 fill_state($foot_state); 19398 push @{$foot_state->{'command_stack'}}, 'footnote'; 19399 19400 push_state($foot_state); 19401 19402 my ($foot_num, $relative_foot_num); 19403 if (!$foot_state->{'region'}) 19404 { 19405 $foot_num = \$global_foot_num; 19406 $relative_foot_num = \$global_relative_foot_num; 19407 } 19408 else 19409 { 19410 $foot_num = \$doc_state->{'foot_num'}; 19411 $relative_foot_num = \$doc_state->{'relative_foot_num'}; 19412 } 19413 $$foot_num++; 19414 $$relative_foot_num++; 19415 19416 my $docid = "DOCF$$foot_num"; 19417 my $footid = "FOOT$$foot_num"; 19418 if ($doc_state->{'region'}) 19419 { 19420 $docid = $target_prefix . $doc_state->{'region'} . "_$docid"; 19421 $footid = $target_prefix . $doc_state->{'region'} . "_$footid"; 19422 } 19423 my $from_file = $docu_doc; 19424 if ($doc_state->{'element'}) 19425 { 19426 $from_file = $doc_state->{'element'}->{'file'}; 19427 } 19428 19429 if ($Texi2HTML::Config::SEPARATED_FOOTNOTES) 19430 { 19431 $foot_state->{'element'} = $footnote_element; 19432 } 19433 19434 $foot_state->{'footnote_number_in_doc'} = $$foot_num; 19435 $foot_state->{'footnote_number_in_page'} = $$relative_foot_num; 19436 $foot_state->{'footnote_footnote_id'} = $footid; 19437 $foot_state->{'footnote_place_id'} = $docid; 19438 $foot_state->{'footnote_document_file'} = $from_file; 19439 $foot_state->{'footnote_footnote_file'} = $foot_state->{'element'}->{'file'}; 19440 $foot_state->{'footnote_document_state'} = $doc_state; 19441 19442 # FIXME use split_lines ? It seems to work like it is now ? 19443 my @lines = substitute_text($foot_state, undef, map {$_ = $_."\n"} split (/\n/, $text)); 19444 my ($foot_lines, $foot_label) = &$Texi2HTML::Config::foot_line_and_ref($$foot_num, 19445 $$relative_foot_num, $footid, $docid, $from_file, $foot_state->{'element'}->{'file'}, \@lines, $doc_state); 19446 if ($doc_state->{'outside_document'} or ($doc_state->{'region'} and $doc_state->{'multiple_pass'} > 0)) 19447 { 19448#print STDERR "multiple_pass $doc_state->{'multiple_pass'}, 'outside_document' $doc_state->{'outside_document'}\n"; 19449#print STDERR "REGION FOOTNOTE($$foot_num): $doc_state->{'region'} ($doc_state->{'region_pass'})\n"; 19450 $region_initial_state{$doc_state->{'region'}}->{'footnotes'}->{$$foot_num}->{$doc_state->{'region_pass'}} = $foot_lines; 19451 } 19452 else 19453 { 19454#print STDERR "GLOBAL FOOTNOTE($$foot_num)\n"; 19455 push(@foot_lines, @{$foot_lines}); 19456 } 19457 pop_state(); 19458 return $foot_label; 19459} 19460 19461sub do_image($$$$$) 19462{ 19463 # replace images 19464 my $command = shift; 19465 my $args = shift; 19466 my $style_stack = shift; 19467 my $state = shift; 19468 my $line_nr = shift; 19469 my @args; 19470 foreach my $arg (@$args) 19471 { 19472 $arg =~ s/^\s*//; 19473 $arg =~ s/\s*$//; 19474 push @args, $arg; 19475 } 19476 #my $base = substitute_line($args[0], {'code_style' => 1}); 19477 my $base = substitute_line($args[0], {'code_style' => 1, 'remove_texi' => 1}); 19478 my $base_simple = substitute_line($args[0], {'simple_format' => 1, 'code_style' => 1}); 19479 if ($base eq '') 19480 { 19481 echo_error ("no file argument for \@image", $line_nr); 19482 return ''; 19483 } 19484 $args[4] = '' if (!defined($args[4])); 19485 $args[3] = '' if (!defined($args[3])); 19486 my $image; 19487 #my $extension = substitute_line($args[4], {'code_style' => 1}); 19488 my $extension = substitute_line($args[4], {'code_style' => 1, 'remove_texi' => 1}); 19489 my $extension_simple = substitute_line($args[4], {'simple_format' => 1, 'code_style' => 1}); 19490 my ($file_name, $image_name, $simple_file_name); 19491 my @file_locations; 19492 my @file_names = &$Texi2HTML::Config::image_files($base,$extension,$args[0],$args[4]); 19493# $image = locate_include_file("$base.$args[4]") if ($args[4] ne ''); 19494 foreach my $file (@file_names) 19495 { 19496 my $simple_file = substitute_line($file->[1], {'simple_format' => 1, 'code_style' => 1}); 19497 if ($image = locate_include_file($file->[0])) 19498 { 19499 if (!defined($file_name)) 19500 { 19501 $file_name = $file->[0]; 19502 $image_name = $image; 19503 $simple_file_name = $simple_file; 19504 } 19505 push @file_locations, [$file, $image, $simple_file]; 19506 } 19507 else 19508 { 19509 push @file_locations, [$file, undef, $simple_file]; 19510 } 19511 } 19512 $image_name = '' if (!defined($image_name)); 19513 $simple_file_name = '' if (!defined($simple_file_name)); 19514 19515 my $alt; 19516 if ($args[3] =~ /\S/) 19517 { 19518 $alt = substitute_line($args[3], {'simple_format' => 1}, $line_nr); 19519 } 19520 return &$Texi2HTML::Config::image($path_to_working_dir . $image_name, 19521 $base, 19522 $state->{'preformatted'}, $file_name, $alt, $args[1], $args[2], 19523 $args[3], $extension, $path_to_working_dir, $image_name, 19524 $state->{'paragraph_context'}, \@file_locations, $base_simple, 19525 $extension_simple, $simple_file_name); 19526} 19527 19528# usefull if we want to duplicate only the global state, nothing related with 19529# formatting 19530sub duplicate_state($) 19531{ 19532 my $state = shift; 19533 my $new_state = { 'element' => $state->{'element'}, 19534 'multiple_pass' => $state->{'multiple_pass'}, 19535 'region_pass' => $state->{'region_pass'}, 19536 'region' => $state->{'region'}, 19537 'sec_num' => $state->{'sec_num'}, 19538 'outside_document' => $state->{'outside_document'}, 19539 'inside_document' => $state->{'inside_document'}, 19540 'duplicated' => 1 19541 }; 19542 return $new_state; 19543} 19544 19545# duplicate global and formatting state. 19546sub duplicate_formatting_state($) 19547{ 19548 my $state = shift; 19549 my $new_state = duplicate_state($state); 19550 19551 # Things passed here should be things that are not emptied/set to 0 by 19552 # any command. Also they shouldn't need anything to be on the 19553 # stack. This rules out paragraphs, for example. 19554 foreach my $format_key ('preformatted', 'code_style', 'keep_texi', 19555 'keep_nr', 'preformatted_stack') 19556 { 19557 $new_state->{$format_key} = $state->{$format_key}; 19558 } 19559# this is needed for preformatted 19560 my $command_stack = $state->{'command_stack'}; 19561 $command_stack = [] if (!defined($command_stack)); 19562 $new_state->{'command_stack'} = [ @$command_stack ]; 19563 $new_state->{'preformatted_context'} = {'stack_at_beginning' => [ @$command_stack ]}; 19564 $new_state->{'code_style'} = 0 if (!defined($new_state->{'code_style'})); 19565 return $new_state; 19566} 19567 19568sub expand_macro($$$$$) 19569{ 19570 my $name = shift; 19571 my $args = shift; 19572 my $end_line = shift; 19573 my $line_nr = shift; 19574 my $state = shift; 19575 19576 # we dont expand macros when in ignored environment. 19577 return if ($state->{'ignored'}); 19578 19579 die "Bug end_line not defined" if (!defined($end_line)); 19580 19581 my $index = 0; 19582 foreach my $arg (@$args) 19583 { # expand @macros in arguments. It is complicated because we must be 19584 # carefull not to expand macros in @ignore section or the like, and 19585 # still keep every single piece of text (including the @ignore macros). 19586 $args->[$index] = substitute_text({'texi' => 1, 'arg_expansion' => 1}, undef, split_lines($arg)); 19587 $index++; 19588 } 19589 # retrieve the macro definition 19590 my $macrobody = $macros->{$name}->{'body'}; 19591 my $formal_args = $macros->{$name}->{'args'}; 19592 my $args_index = $macros->{$name}->{'args_index'}; 19593 19594 my $i; 19595 for ($i=0; $i<=$#$formal_args; $i++) 19596 { 19597 $args->[$i] = "" unless (defined($args->[$i])); 19598 print STDERR "# arg($i): $args->[$i]\n" if ($T2H_DEBUG & $DEBUG_MACROS); 19599 } 19600 echo_error ("too much arguments for macro $name", $line_nr) if (defined($args->[$i + 1])); 19601 my $result = ''; 19602 while ($macrobody ne '') 19603 { 19604 if ($macrobody =~ s/^([^\\]*)\\//o) 19605 { 19606 $result .= $1 if defined($1); 19607 if ($macrobody =~ s/^\\//) 19608 { 19609 $result .= '\\'; 19610 } 19611 elsif ($macrobody =~ s/^(\@end\sr?macro)$// or $macrobody =~ s/^(\@end\sr?macro\s)// or $macrobody =~ s/^(\@r?macro\s+\w+\s*.*)//) 19612 { # \ protect @end macro 19613 $result .= $1; 19614 } 19615 elsif ($macrobody =~ s/^([^\\]*)\\//) 19616 { 19617 my $arg = $1; 19618 if (defined($args_index->{$arg})) 19619 { 19620 $result .= $args->[$args_index->{$arg}]; 19621 } 19622 else 19623 { 19624 warn "$ERROR \\ not followed by \\ or an arg but by $arg in macro\n"; 19625 $result .= '\\' . $arg; 19626 } 19627 } 19628 next; 19629 } 19630 $result .= $macrobody; 19631 last; 19632 } 19633 my @result = split(/^/m, $result); 19634 # for a completly empty macro, $result = '', and the split leads 19635 # to an empty array, so add back an empty string 19636 @result = ('') if (!scalar(@result)); 19637 # Add the result of the macro expansion back to the input_spool. 19638 # Set the macro name if in the outer macro 19639 if ($state->{'arg_expansion'}) 19640 { # in that case we are in substitute_text for an arg 19641 unshift @{$state->{'spool'}}, (@result, $end_line); 19642 } 19643 else 19644 { 19645 #$result[-1].=$end_line; 19646#foreach my $res (@result) 19647#{ 19648# print STDERR "RESULT:$res"; 19649#} 19650#print STDERR "#########end->$end_line"; 19651 my $last_line = $result[-1]; 19652 if (chomp($last_line)) 19653 { 19654 push @result, $end_line; 19655 } 19656 else 19657 { 19658 $result[-1] .= $end_line; 19659 } 19660 unshift @{$state->{'input_spool'}->{'spool'}}, (@result); #, $end_line); 19661 $state->{'input_spool'}->{'macro'} = $name if ($state->{'input_spool'}->{'macro'} eq ''); 19662 } 19663 if ($T2H_DEBUG & $DEBUG_MACROS) 19664 { 19665 print STDERR "# macro expansion result:\n"; 19666 #print STDERR "$first_line"; 19667 foreach my $line (@result) 19668 { 19669 print STDERR "$line"; 19670 } 19671 print STDERR "# macro expansion result end\n"; 19672 } 19673} 19674 19675sub do_index_summary_file($$) 19676{ 19677 my $name = shift; 19678 my $docu_name = shift; 19679 my $entries = get_index($name); 19680 &$Texi2HTML::Config::index_summary_file_begin ($name, $printed_indices{$name}, $docu_name); 19681 print STDERR "# writing $name index summary for $docu_name\n" if $T2H_VERBOSE; 19682 19683 foreach my $key (sort keys %$entries) 19684 { 19685 my $entry = $entries->{$key}; 19686 my $indexed_element = $entry->{'element'}; 19687 my $entry_element = $indexed_element; 19688 $entry_element = $entry_element->{'element_ref'} if (defined($entry_element->{'element_ref'})); 19689 my $origin_href = $entry->{'file'}; 19690 #print STDERR "$entry $entry->{'entry'}, real elem $indexed_element->{'texi'}, section $entry_element->{'texi'}, real $indexed_element->{'file'}, entry file $entry->{'file'}\n"; 19691 if ($entry->{'target'}) 19692 { 19693 $origin_href .= '#' . $entry->{'target'}; 19694 } 19695 else 19696 { 19697 $origin_href .= '#' . $indexed_element->{'target'}; 19698 } 19699 &$Texi2HTML::Config::index_summary_file_entry ($name, 19700 $key, $origin_href, 19701 substitute_line($entry->{'entry'}), $entry->{'entry'}, 19702 href($entry_element, ''), 19703 $entry_element->{'text'}, 19704 $printed_indices{$name}, 19705 $docu_name); 19706 } 19707 &$Texi2HTML::Config::index_summary_file_end ($name, $printed_indices{$name}, $docu_name); 19708} 19709 19710sub get_index_entry_infos($$;$) 19711{ 19712 my $entry = shift; 19713 my $element = shift; 19714 my $line_nr = shift; 19715 my $indexed_element = $entry->{'element'}; 19716 my $entry_element = $indexed_element; 19717 # we always use the associated element_ref, instead of the original 19718 # element 19719 $entry_element = $entry_element->{'element_ref'} if (defined($entry_element->{'element_ref'})); 19720 my $origin_href = ''; 19721 print STDERR "BUG: entry->{'file'} not defined for `$entry->{'entry'}'\n" 19722 if (!defined($entry->{'file'})); 19723 print STDERR "BUG: element->{'file'} not defined for `$entry->{'entry'}', `$element->{'texi'}'\n" 19724 if (!defined($element->{'file'})); 19725 $origin_href = $entry->{'file'} if ($entry->{'file'} ne $element->{'file'}); 19726#print STDERR "$entry $entry->{'entry'}, real elem $indexed_element->{'texi'}, section $entry_element->{'texi'}, real $indexed_element->{'file'}, entry file $entry->{'file'}\n"; 19727 if (defined($entry->{'target'})) 19728 { 19729 $origin_href .= '#' . $entry->{'target'}; 19730 } 19731 else 19732 { # this means that the index entry is in a special region like @copying... 19733 $origin_href .= '#' . $indexed_element->{'target'}; 19734 } 19735 #print STDERR "SUBHREF in index entry `$entry->{'entry'}' for `$entry_element->{'texi'}'\n"; 19736 return ($origin_href, 19737 $entry->{'file'}, 19738 $element->{'file'}, 19739 $entry->{'target'}, 19740 $indexed_element->{'target'}, 19741 substitute_line($entry->{'entry'}), 19742 href($entry_element, $element->{'file'}, $line_nr), 19743 $entry_element->{'text'}); 19744} 19745 19746# remove texi commands, replacing with what seems adequate. see simple_map_texi 19747# and texi_map. 19748# Doesn't protect html 19749sub remove_texi(@) 19750{ 19751 return substitute_text ({ 'remove_texi' => 1}, undef, @_); 19752} 19753 19754# Same as remove texi but protect text and use special maps for @-commands 19755sub simple_format($$@) 19756{ 19757 my $state = shift; 19758 my $line_nr = shift; 19759 if (!defined($state)) 19760 { 19761 $state = {}; 19762 } 19763 else 19764 { 19765 $state = duplicate_formatting_state($state); 19766 } 19767 $state->{'remove_texi'} = 1; 19768 $state->{'simple_format'} = 1; 19769 $::simple_map_texi_ref = \%Texi2HTML::Config::simple_format_simple_map_texi; 19770 $::style_map_texi_ref = \%Texi2HTML::Config::simple_format_style_map_texi; 19771 $::texi_map_ref = \%Texi2HTML::Config::simple_format_texi_map; 19772 my $text = substitute_text($state, $line_nr, @_); 19773 $::simple_map_texi_ref = \%Texi2HTML::Config::simple_map_texi; 19774 $::style_map_texi_ref = \%Texi2HTML::Config::style_map_texi; 19775 $::texi_map_ref = \%Texi2HTML::Config::texi_map; 19776 return $text; 19777} 19778 19779sub enter_table_index_entry($$$$) 19780{ 19781 my $text = shift; 19782 my $stack = shift; 19783 my $state = shift; 19784 my $line_nr = shift; 19785 if ($state->{'item'} and ($state->{'table_stack'}->[-1] =~ /^(v|f)table$/)) 19786 { 19787 my $index = $1; 19788 my $macro = $state->{'item'}; 19789 delete $state->{'item'}; 19790 close_stack($text, $stack, $state, $line_nr, 'index_item'); 19791 my $item = pop @$stack; 19792 my $element = $state->{'element'}; 19793 $element = $state->{'node_ref'} unless ($element); 19794 enter_index_entry($index, $line_nr, $item->{'text'}, 19795 $state->{'place'}, $element, $state->{'table_stack'}->[-1], $state->{'region'}); 19796 add_prev($text, $stack, "\@$macro" . $item->{'text'}); 19797 } 19798} 19799 19800sub scan_texi($$$$;$) 19801{ 19802 my $line = shift; 19803 my $text = shift; 19804 my $stack = shift; 19805 my $state = shift; 19806 my $line_nr = shift; 19807 19808 die "stack not an array ref" unless (ref($stack) eq "ARRAY"); 19809 my $cline = $line; 19810 19811 while(1) 19812 { 19813 # scan_texi 19814 #print STDERR "WHILE:$cline"; 19815 #print STDERR "ARG_EXPANSION: $state->{'arg_expansion'}\n" if ($state->{'arg_expansion'}); 19816 #dump_stack($text, $stack, $state); 19817 #print STDERR "ifvalue_inside $state->{'ifvalue_inside'}\n"; 19818 19819 19820 # first we handle special cases: 19821 # macro definition: $state->{'macro_inside'} 19822 # macro arguments: $state->{'macro_name'} 19823 # raw format: $state->{'raw'} 19824 # @verb: $state->{'verb'} 19825 # ignored: $state->{'ignored'} 19826 # and then the remaining text/macros. 19827 19828 # in macro definition 19829 if ($state->{'macro_inside'}) 19830 { 19831 if ($cline =~ s/^([^\\\@]*\\)//) 19832 {# protected character or @end macro 19833 $state->{'macro'}->{'body'} .= $1 unless ($state->{'ignored'}); 19834 if ($cline =~ s/^\\//) 19835 { 19836 $state->{'macro'}->{'body'} .= '\\' unless ($state->{'ignored'}); 19837 next; 19838 } 19839 # I believe it is correct, although makeinfo don't do that. 19840 elsif ($cline =~ s/^(\@end\sr?macro)$//o or $cline =~ s/^(\@end\sr?macro\s)//o 19841 or $cline =~ s/^(\@r?macro\s+\w+\s*.*)//o) 19842 { 19843 $state->{'macro'}->{'body'} .= $1 unless ($state->{'ignored'}); 19844 next; 19845 } 19846 } 19847 #if ($cline =~ s/^(.*?)\@end\sr?macro$//o or $cline =~ s/^(.*?)\@end\sr?macro\s+//o) 19848 if ($cline =~ s/^(\@end\sr?macro)$//o or $cline =~ s/^(\@end\sr?macro\s+)//o) 19849 { 19850 $state->{'macro_inside'}--; 19851 next if ($state->{'ignored'}); 19852 if ($state->{'macro_inside'}) 19853 { 19854 $state->{'macro'}->{'body'} .= $1; 19855 next; 19856 } 19857 chomp $state->{'macro'}->{'body'}; 19858 print STDERR "# end macro def. Body:\n$state->{'macro'}->{'body'}" 19859 if ($T2H_DEBUG & $DEBUG_MACROS); 19860 delete $state->{'macro'}; 19861 return if ($cline =~ /^\s*$/); 19862 next; 19863 } 19864 elsif($cline =~ /^(\@r?macro\s+\w+\s*.*)/) 19865 { 19866 $state->{'macro'}->{'body'} .= $cline unless ($state->{'ignored'}); 19867 $state->{'macro_inside'}++; 19868 return; 19869 } 19870 elsif ($cline =~ s/^\@(.)//) 19871 { 19872 $state->{'macro'}->{'body'} .= '@' . $1 unless ($state->{'ignored'}); 19873 next; 19874 } 19875 elsif ($cline =~ s/^\@//) 19876 { 19877 $state->{'macro'}->{'body'} .= '@' unless ($state->{'ignored'}); 19878 next; 19879 } 19880 else 19881 { 19882 $cline =~ s/([^\@\\]*)//; 19883 if ($state->{'ignored'}) 19884 { 19885 return if ($cline =~ /^$/); 19886 next; 19887 } 19888 $state->{'macro'}->{'body'} .= $1 if (defined($1)); 19889 if ($cline =~ /^$/) 19890 { 19891 $state->{'macro'}->{'body'} .= $cline; 19892 return; 19893 } 19894 next; 19895 } 19896 } 19897 # in macro arguments parsing/expansion. Here \ { } and , if this is a 19898 # multi args macro have a signification, the remaining is passed 19899 # unmodified 19900 if (defined($state->{'macro_name'})) 19901 { 19902 my $special_chars = quotemeta ('\{}'); 19903 my $multi_args = 0; 19904 my $formal_args = $macros->{$state->{'macro_name'}}->{'args'}; 19905 $multi_args = 1 if ($#$formal_args >= 1); 19906 $special_chars .= quotemeta(',') if ($multi_args); 19907 if ($state->{'macro_args'}->[-1] eq '') 19908 {# remove space at the very beginning 19909 $cline =~ s/^\s*//o; 19910 } 19911 if ($cline =~ s/^([^$special_chars]*)([$special_chars])//) 19912 { 19913 $state->{'macro_args'}->[-1] .= $1 if defined($1); 19914 # \ protects any character in macro arguments 19915 if ($2 eq '\\') 19916 { 19917 print STDERR "# macro call: protected char\n" if ($T2H_DEBUG & $DEBUG_MACROS); 19918 if ($cline =~ s/^(.)//) 19919 { 19920 $state->{'macro_args'}->[-1] .= $1; 19921 } 19922 else 19923 { 19924 $state->{'macro_args'}->[-1] .= '\\'; 19925 } 19926 } 19927 elsif ($2 eq ',') 19928 { # in texinfo 4.8.90 a comma in braces is protected 19929 if ($state->{'macro_depth'} > 1) 19930 { 19931 $state->{'macro_args'}->[-1] .= ','; 19932 } 19933 else 19934 { # separate args 19935 print STDERR "# macro call: new arg\n" if ($T2H_DEBUG & $DEBUG_MACROS); 19936 $cline =~ s/^\s*//o; 19937 push @{$state->{'macro_args'}}, ''; 19938 } 19939 } 19940 elsif ($2 eq '}') 19941 { # balanced } ends the macro call, otherwise it is in the arg 19942 $state->{'macro_depth'}--; 19943 if ($state->{'macro_depth'} == 0) 19944 { 19945#print STDERR "BEFORE: $cline"; 19946 print STDERR "# expanding macro $state->{'macro_name'}\n" if ($T2H_DEBUG & $DEBUG_MACROS); 19947 $cline = expand_macro($state->{'macro_name'}, $state->{'macro_args'}, $cline, $line_nr, $state); 19948 delete $state->{'macro_name'}; 19949 delete $state->{'macro_depth'}; 19950 delete $state->{'macro_args'}; 19951#print STDERR "AFTER: $cline"; 19952 return; 19953 } 19954 else 19955 { 19956 print STDERR "# macro call: closing }\n" if ($T2H_DEBUG & $DEBUG_MACROS); 19957 add_text('}', \$state->{'macro_args'}->[-1]); 19958 } 19959 } 19960 elsif ($2 eq '{') 19961 { 19962 print STDERR "# macro call: opening {\n" if ($T2H_DEBUG & $DEBUG_MACROS); 19963 $state->{'macro_depth'}++; 19964 add_text('{', \$state->{'macro_args'}->[-1]); 19965 } 19966 next; 19967 } 19968 print STDERR "# macro call: end of line\n" if ($T2H_DEBUG & $DEBUG_MACROS); 19969 $state->{'macro_args'}->[-1] .= $cline; 19970 return; 19971 } 19972 # in a raw format, verbatim, tex or html 19973 if ($state->{'raw'}) 19974 { 19975 my $tag = $state->{'raw'}; 19976 19977 # debugging 19978 if (! @$stack or ($stack->[-1]->{'style'} ne $tag)) 19979 { 19980 print STDERR "Bug: raw or special: $tag but not on top of stack\n"; 19981 print STDERR "line: $cline"; 19982 dump_stack($text, $stack, $state); 19983 exit 1; 19984 } 19985 19986 # macro_regexp 19987 if ($cline =~ /^(.*?)\@end\s([a-zA-Z][\w-]*)/o and ($2 eq $tag)) 19988 { 19989 $cline =~ s/^(.*?)(\@end\s$tag)//; 19990 # we add it even if 'ignored', it'll be discarded when there is 19991 # the @end 19992 add_prev ($text, $stack, $1); 19993 my $end = $2; 19994 my $style = pop @$stack; 19995 if ($style->{'text'} !~ /^\s*$/ or $state->{'arg_expansion'}) 19996 # FIXME if 'arg_expansion' and also 'ignored' is true, 19997 # theoretically we should keep 19998 # what is in the raw format however 19999 # it will be removed later anyway 20000 {# ARG_EXPANSION 20001 add_prev ($text, $stack, $style->{'text'} . $end) unless ($state->{'ignored'}); 20002 delete $state->{'raw'}; 20003 } 20004 next; 20005 } 20006 else 20007 {# we add it even if 'ignored', it'll be discarded when there is 20008 # the @end 20009 add_prev ($text, $stack, $cline); 20010 last; 20011 } 20012 } 20013 20014 # in a @verb{ .. } macro 20015 if (defined($state->{'verb'})) 20016 { 20017 #dump_stack($text, $stack, $state); 20018 my $char = quotemeta($state->{'verb'}); 20019 #print STDERR "VERB $char\n"; 20020 if ($cline =~ s/^(.*?)$char\}/\}/) 20021 {# we add it even if 'ignored', it'll be discarded when closing 20022 add_prev($text, $stack, $1 . $state->{'verb'}); 20023 $stack->[-1]->{'text'} = $state->{'verb'} . $stack->[-1]->{'text'}; 20024 delete $state->{'verb'}; 20025 next; 20026 } 20027 else 20028 {# we add it even if 'ignored', it'll be discarded when closing 20029 add_prev($text, $stack, $cline); 20030 last; 20031 } 20032 } 20033 # In ignored region 20034 if ($state->{'ignored'}) 20035 { 20036 #print STDERR "IGNORED(ifvalue($state->{'ifvalue_inside'})): $state->{'ignored'}\n"; 20037 if ($cline =~ /^.*?\@end(\s+)([a-zA-Z]\w+)/) 20038 { 20039 if ($2 eq $state->{'ignored'}) 20040 { 20041 $cline =~ s/^(.*?\@end)(\s+)([a-zA-Z]\w+)//; 20042 my $end_ignore = $1.$2.$3; 20043 if (($state->{'ifvalue_inside'}) and $state->{'ignored'} eq $state->{'ifvalue'}) 20044 { 20045 if ($state->{'ifvalue_inside'} == 1) 20046 {# closing still opened @-commands with braces 20047 pop (@$stack) while (@$stack and $stack->[-1]->{'style'} ne 'ifvalue') 20048 } 20049 pop (@$stack); 20050 $state->{'ifvalue_inside'}--; 20051 } 20052 $state->{'ignored'} = undef; 20053 delete $state->{'ignored'}; 20054 # We are stil in the ignored ifset or ifclear section 20055 $state->{'ignored'} = $state->{'ifvalue'} if ($state->{'ifvalue_inside'}); 20056 #dump_stack($text, $stack, $state); 20057 # MACRO_ARG => keep ignored text 20058 if ($state->{'arg_expansion'}) 20059 {# this may not be very usefull as it'll be remove later 20060 add_prev ($text, $stack, $end_ignore); 20061 next; 20062 } 20063 return if ($cline =~ /^\s*$/o); 20064 next; 20065 } 20066 } 20067 add_prev ($text, $stack, $cline) if ($state->{'arg_expansion'}); 20068 # we could theoretically continue for ignored commands other 20069 # than ifset or ifclear, however it isn't usefull. 20070 return unless ($state->{'ifvalue_inside'} and ($state->{'ignored'} eq $state->{'ifvalue'})); 20071 } 20072 20073 20074 # an @end tag 20075 # macro_regexp 20076 if ($cline =~ s/^([^{}@]*)\@end(\s+)([a-zA-Z][\w-]*)//) 20077 { 20078 my $leading_text = $1; 20079 my $space = $2; 20080 my $end_tag = $3; 20081 # when 'ignored' we don't open environments that aren't associated 20082 # with ignored regions, so we don't need to close them. 20083 next if ($state->{'ignored'});# ARG_EXPANSION 20084 add_prev($text, $stack, $leading_text); 20085 if (defined($state->{'text_macro_stack'}) 20086 and @{$state->{'text_macro_stack'}} 20087 and ($end_tag eq $state->{'text_macro_stack'}->[-1])) 20088 { 20089 pop @{$state->{'text_macro_stack'}}; 20090 # we keep menu and titlepage for the following pass 20091 if ((($end_tag eq 'menu') and $Texi2HTML::Config::texi_formats_map{'menu'}) or ($region_lines{$end_tag}) or $state->{'arg_expansion'}) 20092 { 20093 add_prev($text, $stack, "\@end${space}$end_tag"); 20094 } 20095 else 20096 { 20097 #print STDERR "End $end_tag\n"; 20098 #dump_stack($text, $stack, $state); 20099 return if ($cline =~ /^\s*$/); 20100 } 20101 } 20102 elsif ($Texi2HTML::Config::texi_formats_map{$end_tag}) 20103 { 20104 echo_error ("\@end $end_tag without corresponding element", $line_nr); 20105 } 20106 else 20107 {# ARG_EXPANSION 20108 add_prev($text, $stack, "\@end${space}$end_tag"); 20109 } 20110 next; 20111 } 20112 # macro_regexp 20113 elsif ($cline =~ s/^([^{}@]*)\@(["'~\@\}\{,\.!\?\s\*\-\^`=:\|\/\\])//o or $cline =~ s/^([^{}@]*)\@([a-zA-Z][\w-]*)([\s\{\}\@])/$3/o or $cline =~ s/^([^{}@]*)\@([a-zA-Z][\w-]*)$//o) 20114 {# ARG_EXPANSION 20115 add_prev($text, $stack, $1) unless $state->{'ignored'}; 20116 my $macro = $2; 20117 # FIXME: if it is an alias, it is substituted below, in the 20118 # diverse add_prev and output of \@$macro. Maybe it could be 20119 # kept and only substituted in the last passes? 20120 $macro = $alias{$macro} if (exists($alias{$macro})); 20121 #print STDERR "MACRO $macro\n"; 20122 # handle skipped @-commands 20123 $state->{'bye'} = 1 if ($macro eq 'bye' and !$state->{'ignored'} and !$state->{'arg_expansion'}); 20124 # 'ignored' and 'arg_expansion' are handled in misc_command_texi 20125 # these are the commands in which the @value and @macro 20126 # and @-commands in general should not be expanded 20127 if (defined($Texi2HTML::Config::misc_command{$macro}) and 20128 ($macro eq 'c' or $macro eq 'comment' or $macro eq 'set' 20129 or $macro eq 'clear' or $macro eq 'bye')) 20130 { 20131 ($cline, $line) = misc_command_texi($cline, $macro, $state, 20132 $line_nr); 20133 add_prev ($text, $stack, "\@$macro" . $line) unless $state->{'ignored'}; 20134 } 20135 elsif ($macro eq 'setfilename' or $macro eq 'documentencoding' 20136 or $macro eq 'definfoenclose' or $macro eq 'include') 20137 { # special commands whose arguments will have @macro and 20138 # @value expanded, and that are processed in this pass 20139 if ($state->{'ignored'}) 20140 { 20141 $cline = ''; 20142 } 20143 elsif ($state->{'arg_expansion'}) 20144 { 20145 add_prev($text, $stack, "\@$macro" . $cline); 20146 return; 20147 } 20148 else 20149 { 20150 $cline =~ s/^(\s+)//; 20151 my $space = $1; 20152 # not sure if it happpens at end of line, or with 20153 # special char following the @-command or only at end of file 20154 $space = '' if (!defined($space)); 20155 if (!$state->{'line_command'}) 20156 { 20157 #print STDERR "LINE_COMMAND Start line_command $macro, cline $cline"; 20158 $state->{'line_command'} = $macro; 20159 push @$stack, { 'line_command' => $macro, 'text' => $space }; 20160 } 20161 else 20162 {# FIXME warn/error? or just discard? 20163 add_prev($text, $stack, "\@$macro" . $space); 20164 } 20165 } 20166 } 20167 # pertusus: it seems that value substitution are performed after 20168 # macro argument expansions: if we have 20169 # @set comma , 20170 # and a call to a macro @macro {arg1 @value{comma} arg2} 20171 # the macro arg is arg1 , arg2 and the comma don't separate 20172 # args. Likewise it seems that the @value are not expanded 20173 # in macro definitions 20174 20175 elsif ($macro =~ /^r?macro$/) 20176 { #FIXME what to do if 'arg_expansion' is true (ie within another 20177 # macro call arguments? 20178 if ($cline =~ /^\s+(\w[\w-]*)\s*(.*)/) 20179 { 20180 my $name = $1; 20181 unless ($state->{'ignored'}) 20182 { 20183 if (exists($macros->{$name})) 20184 { 20185 echo_warn ("macro `$name' already defined " . 20186 format_line_number($macros->{$name}->{'line_nr'}) . " redefined", $line_nr); 20187 } 20188 20189 } 20190 $state->{'macro_inside'} = 1; 20191 next if ($state->{'ignored'}); 20192 # if in 'arg_expansion' we really want to take into account 20193 # that we are in an ignored ifclear. 20194 my @args = (); 20195 @args = split(/\s*,\s*/ , $1) 20196 if ($2 =~ /^\s*{\s*(.*?)\s*}\s*/); 20197 # keep the context information of the definition 20198 $macros->{$name}->{'line_nr'} = { 'file_name' => $line_nr->{'file_name'}, 20199 'line_nr' => $line_nr->{'line_nr'}, 'macro' => $line_nr->{'macro'} } if (defined($line_nr)); 20200 $macros->{$name}->{'args'} = \@args; 20201 my $arg_index = 0; 20202 my $debug_msg = ''; 20203 foreach my $arg (@args) 20204 { # when expanding macros, the argument index is retrieved 20205 # with args_index 20206 $macros->{$name}->{'args_index'}->{$arg} = $arg_index; 20207 $debug_msg .= "$arg($arg_index) "; 20208 $arg_index++; 20209 } 20210 $macros->{$name}->{'body'} = ''; 20211 $state->{'macro'} = $macros->{$name}; 20212 print STDERR "# macro def $name: $debug_msg\n" 20213 if ($T2H_DEBUG & $DEBUG_MACROS); 20214 } 20215 else 20216 {# it means we have a macro without a name 20217 echo_error ("Macro definition without macro name $cline", $line_nr) 20218 unless ($state->{'ignored'}); 20219 } 20220 return; 20221 } 20222 elsif (defined($Texi2HTML::Config::texi_formats_map{$macro})) 20223 { 20224 my $tag; 20225 ($cline, $tag) = do_text_macro($macro, $cline, $state, $stack, $line_nr); 20226 # if it is a raw formatting command or a menu command 20227 # we must keep it for later, unless we are in an 'ignored'. 20228 # if in 'arg_expansion' we keep everything. 20229 my $macro_kept; 20230 if ((($state->{'raw'} or (($macro eq 'menu') and $Texi2HTML::Config::texi_formats_map{'menu'}) or (exists($region_lines{$macro}))) and !$state->{'ignored'}) or $state->{'arg_expansion'}) 20231 { 20232 add_prev($text, $stack, $tag); 20233 $macro_kept = 1; 20234 } 20235 #dump_stack ($text, $stack, $state); 20236 next if $macro_kept; 20237 return if ($cline =~ /^\s*$/); 20238 } 20239# elsif ($macro eq 'definfoenclose') 20240# { 20241# die "Not here definfoenclose expansion"; 20242# # FIXME if 'ignored' or 'arg_expansion' maybe we could parse 20243# # the args anyway and don't take away the whole line? 20244# 20245# # as in the makeinfo doc 'definfoenclose' may override 20246# # texinfo @-commands like @i. It is what we do here. 20247# if ($state->{'arg_expansion'}) 20248# { 20249# add_prev($text, $stack, "\@$macro" . $cline); 20250# return; 20251# } 20252# return if ($state->{'ignored'}); 20253# if ($cline =~ s/^\s+([a-z]+)\s*,\s*([^\s]+)\s*,\s*([^\s]+)//) 20254# { 20255# $info_enclose{$1} = [ $2, $3 ]; 20256# } 20257# else 20258# { 20259# echo_error("Bad \@$macro", $line_nr); 20260# } 20261# return if ($cline =~ /^\s*$/); 20262# $cline =~ s/^\s*//; 20263# } 20264# elsif ($macro eq 'include') 20265# { 20266# die "Not here include expansion"; 20267# if ($state->{'arg_expansion'}) 20268# { 20269# add_prev($text, $stack, "\@$macro" . $cline); 20270# return; 20271# } 20272# return if ($state->{'ignored'}); 20273# #if (s/^\s+([\/\w.+-]+)//o) 20274# if ($cline =~ s/^(\s+)(.*)//o) 20275# { 20276# my $file_name = $2; 20277# $file_name =~ s/\s*$//; 20278# my $file = locate_include_file($file_name); 20279# if (defined($file)) 20280# { 20281# open_file($file, $line_nr); 20282# print STDERR "# including $file\n" if $T2H_VERBOSE; 20283# } 20284# else 20285# { 20286# echo_error ("Can't find $file_name, skipping", $line_nr); 20287# } 20288# } 20289# else 20290# { 20291# echo_error ("Bad include line: $cline", $line_nr); 20292# return; 20293# } 20294# return; 20295# } 20296 elsif ($macro eq 'value') 20297 { 20298 if ($cline =~ s/^{($VARRE)}//) 20299 { 20300 my $value = $1; 20301 if ($state->{'arg_expansion'}) 20302 { 20303 add_prev($text, $stack, "\@$macro" .'{'. $value .'}'); 20304 next; 20305 } 20306 next if ($state->{'ignored'}); 20307 my $expansion = "No value for $value"; 20308 $expansion = $value{$value} if (defined($value{$value})); 20309 $cline = $expansion . $cline; 20310 } 20311 else 20312 { 20313 if ($state->{'arg_expansion'}) 20314 { 20315 add_prev($text, $stack, "\@$macro"); 20316 next; 20317 } 20318 next if ($state->{'ignored'}); 20319 echo_error ("bad \@value macro", $line_nr); 20320 } 20321 } 20322 elsif ($macro eq 'unmacro') 20323 { #FIXME with 'arg_expansion' should it be passed unmodified ? 20324 if ($state->{'ignored'}) 20325 { 20326 $cline =~ s/^\s+(\w+)//; 20327 } 20328 else 20329 { 20330 delete $macros->{$1} if ($cline =~ s/^\s+(\w+)//); 20331 } 20332 return if ($cline =~ /^\s*$/); 20333 $cline =~ s/^\s*//; 20334 } 20335 elsif ($macro eq 'alias') 20336 { # FIXME what to do with 'arg_expansion' ? 20337 if ($cline =~ s/(\s+)([a-zA-Z][\w-]*)(\s*=\s*)([a-zA-Z][\w-]*)(\s*)//) 20338 { 20339 if ($state->{'arg_expansion'}) 20340 { 20341 my $line = "\@$macro" . $1.$2.$3.$4; 20342 $line .= $5 if (defined($4)); 20343 add_prev($text, $stack, $line); 20344 next; 20345 } 20346 next if $state->{'ignored'}; 20347 $alias{$2} = $4; 20348 } 20349 else 20350 { 20351 echo_error ("bad \@alias line", $line_nr); 20352 } 20353 } 20354 elsif (exists($macros->{$macro})) 20355 {# it must be before the handling of {, otherwise it is considered 20356 # to be regular texinfo @-command. Maybe it could be placed higher 20357 # if we want user defined macros to override texinfo @-commands 20358 20359 # in 'ignored' we parse macro defined args anyway as it removes 20360 # some text, but we don't expand the macro 20361 20362 my $ref = $macros->{$macro}->{'args'}; 20363 # we remove any space/new line before the argument 20364 if ($cline =~ s/^\s*{\s*//) 20365 { # the macro has args 20366 $state->{'macro_args'} = [ "" ]; 20367 $state->{'macro_name'} = $macro; 20368 $state->{'macro_depth'} = 1; 20369 } 20370 elsif (($#$ref >= 1) or ($#$ref <0)) 20371 { # no brace -> no arg 20372 $cline = expand_macro ($macro, [], $cline, $line_nr, $state); 20373 return; 20374 } 20375 else 20376 { # macro with one arg on the line 20377 chomp $cline; 20378 $cline = expand_macro ($macro, [$cline], "\n", $line_nr, $state); 20379 return; 20380 } 20381 } 20382 elsif ($cline =~ s/^{//) 20383 {# we add nested commands in a stack. verb is also on the stack 20384 # but handled specifically. 20385 # we add it the comands even in 'ignored' as their result is 20386 # discarded when the closing brace appear, or the ifset or 20387 # iclear is closed. 20388 if ($macro eq 'verb') 20389 { 20390 if ($cline =~ /^$/) 20391 { 20392 echo_error ("without associated character", $line_nr); 20393 #warn "$ERROR verb at end of line"; 20394 } 20395 else 20396 { 20397 $cline =~ s/^(.)//; 20398 $state->{'verb'} = $1; 20399 } 20400 } 20401 push (@$stack, { 'style' => $macro, 'text' => '' }); 20402 } 20403 else 20404 { 20405 $cline = do_unknown(0, $macro, $cline, $text, $stack, $state, $line_nr); 20406 } 20407 next; 20408 } 20409 #elsif(s/^([^{}@]*)\@(.)//o) 20410 elsif($cline =~ s/^([^{}@]*)\@([^\s\}\{\@]*)//o) 20411 {# ARG_EXPANSION 20412 # No need to warn here for @ followed by a character that 20413 # is not in any @-command and it is done later 20414 add_prev($text, $stack, $1) unless($state->{'ignored'}); 20415 $cline = do_unknown(0, $2, $cline, $text, $stack, $state, $line_nr); 20416 next; 20417 } 20418 elsif ($cline =~ s/^([^{}]*)([{}])//o) 20419 { 20420 # in ignored section we cannot be sure that there is an @-command 20421 # already opened so we must discard the text. 20422 # ARG_EXPANSION 20423 add_prev($text, $stack, $1) unless($state->{'ignored'}); 20424 if ($2 eq '{') 20425 { 20426 # this empty style is for a lone brace. 20427 # we add it even in 'ignored' as it is discarded when the closing 20428 # brace appear, or the ifset or iclear is closed. 20429 push @$stack, { 'style' => '', 'text' => '' }; 20430 } 20431 else 20432 { 20433 if (@$stack) 20434 { 20435 my $style = pop @$stack; 20436 my $result; 20437 if (($style->{'style'} ne '') and exists($info_enclose{$style->{'style'}}) and !$state->{'arg_expansion'}) 20438 { 20439 $result = $info_enclose{$style->{'style'}}->[0] . $style->{'text'} . $info_enclose{$style->{'style'}}->[1]; 20440 } 20441 elsif ($style->{'style'} ne '') 20442 { 20443 $result = '@' . $style->{'style'} . '{' . $style->{'text'} . '}'; 20444 } 20445 else 20446 { 20447 $result = '{' . $style->{'text'}; 20448 # don't close { if we are closing stack as we are not 20449 # sure this is a { ... } construct. i.e. we are 20450 # not sure that the user properly closed the matching 20451 # brace, so we don't close it ourselves 20452 $result .= '}' unless ($state->{'close_stack'} or $state->{'arg_expansion'}); 20453 } 20454 if ($state->{'ignored'}) 20455 {# ARG_EXPANSION 20456 print STDERR "# Popped `$style->{'style'}' in ifset/ifclear\n" if ($T2H_DEBUG); 20457 next; 20458 } 20459 add_prev ($text, $stack, $result); 20460 #print STDERR "MACRO end $style->{'style'} remaining: $cline"; 20461 next; 20462 } 20463 else 20464 {# ARG_EXPANSION 20465 # we warn in the last pass that there is a } without open 20466 add_prev ($text, $stack, '}') unless($state->{'ignored'}); 20467 } 20468 } 20469 } 20470 else 20471 {# ARG_EXPANSION 20472 #print STDERR "END_LINE $cline"; 20473 add_prev($text, $stack, $cline) unless($state->{'ignored'}); 20474 if ($state->{'line_command'}) 20475 { 20476 if (!scalar(@$stack)) 20477 { 20478 print STDERR "BUG: empty state for $state->{'line_command'}\n"; 20479 return; 20480 delete $state->{'line_command'}; 20481 } 20482 while (!defined($stack->[-1]->{'line_command'})) 20483 { 20484 my $top = pop @$stack; 20485 # defer this to later? 20486 echo_error ("unclosed command in \@$state->{'line_command'}: $top->{'style'}"); 20487 add_prev($text, $stack, "\@$top->{'style'}".'{'.$top->{'text'}.'}'); 20488 } 20489 my $command = pop @$stack; 20490 ###################### debug 20491 if (!defined($command) or !defined($command->{'text'}) or 20492 !defined($command->{'line_command'}) or ($command->{'line_command'} ne $state->{'line_command'})) 20493 { 20494 print STDERR "BUG: messed $state->{'line_command'} stack\n"; 20495 delete $state->{'line_command'}; 20496 return; 20497 } 20498 ###################### end debug 20499 else 20500 { 20501 delete $state->{'line_command'}; 20502 my $macro = $command->{'line_command'}; 20503 # definfoenclose and include are not kept 20504 if ($macro eq 'definfoenclose') 20505 { 20506 # FIXME if 'ignored' or 'arg_expansion' maybe we could parse 20507 # the args anyway and don't take away the whole line? 20508 20509 # as in the makeinfo doc 'definfoenclose' may override 20510 # texinfo @-commands like @i. It is what we do here. 20511 if ($command->{'text'} =~ s/^\s+([a-z]+)\s*,\s*([^\s]+)\s*,\s*([^\s]+)//) 20512 { 20513 $info_enclose{$1} = [ $2, $3 ]; 20514 } 20515 else 20516 { 20517 echo_error("Bad \@$macro", $line_nr); 20518#print STDERR "arg: $command->{'text'}\n"; 20519 } 20520 # ignore everything else on the line 20521 return;# if ($cline =~ /^\s*$/); 20522 #$cline =~ s/^\s*//; 20523 } 20524 elsif ($macro eq 'include') 20525 { 20526 #if (s/^\s+([\/\w.+-]+)//o) 20527 if ($command->{'text'} =~ s/^(\s+)(.*)//o) 20528 { 20529 my $file_name = $2; 20530 $file_name =~ s/\s*$//; 20531 #$file_name = substitute_line($file_name, {'code_style' => 1}); 20532 $file_name = substitute_line($file_name, {'code_style' => 1, 'remove_texi' => 1}); 20533 my $file = locate_include_file($file_name); 20534 if (defined($file)) 20535 { 20536 my ($line_nr_file, $input_spool_file) = open_file($file, $line_nr->{'macro'}); 20537 ($line_nr, $state->{'input_spool'}) = ($line_nr_file, $input_spool_file) if (defined($line_nr_file)); 20538 print STDERR "# including $file\n" if $T2H_VERBOSE; 20539 } 20540 else 20541 { 20542 echo_error ("Can't find $file_name, skipping", $line_nr); 20543 } 20544 } 20545 else 20546 { 20547 echo_error ("Bad include line: $command->{'text'}", $line_nr); 20548 } 20549 return; 20550 } 20551 else 20552 { # these are kept (setfilename and documentencoding) 20553 ($cline, $line) = misc_command_texi($command->{'text'}, 20554 $macro, $state, $line_nr); 20555 add_prev ($text, $stack, "\@$macro" . $line); 20556 next; 20557 } 20558 } 20559 } 20560 last; 20561 } 20562 } 20563 return undef if ($state->{'ignored'}); 20564 return 1; 20565} # end scan_texi 20566 20567sub close_structure_command($$$$) 20568{ 20569 my $cmd_ref = shift; 20570 my $state = shift; 20571 my $unclosed_commands = shift; 20572 my $line_nr = shift; 20573 my $result; 20574 20575 if ($cmd_ref->{'style'} eq 'anchor') 20576 { 20577 my $anchor = $cmd_ref->{'text'}; 20578 $anchor = normalise_node($anchor); 20579 if ($nodes{$anchor}) 20580 { 20581 echo_error ("Duplicate node for anchor found: $anchor", $line_nr); 20582 return ''; 20583 } 20584 $document_anchor_num++; 20585 $nodes{$anchor} = { 'anchor' => 1, 'seen' => 1, 'texi' => $anchor, 'id' => 'ANC' . $document_anchor_num}; 20586 push @{$state->{'place'}}, $nodes{$anchor}; 20587 } 20588 elsif ($cmd_ref->{'style'} eq 'footnote') 20589 { 20590 if ($Texi2HTML::Config::SEPARATED_FOOTNOTES) 20591 { 20592 $state->{'element'} = $state->{'footnote_element'}; 20593 $state->{'place'} = $state->{'footnote_place'}; 20594 } 20595 } 20596 elsif ($cmd_ref->{'style'} eq 'caption' or $cmd_ref->{'style'} 20597 eq 'shortcaption' and $state->{'float'}) 20598 { 20599 my @texi_lines = map {$_ = $_."\n"} split (/\n/, $cmd_ref->{'text'}); 20600 $state->{'float'}->{$cmd_ref->{'style'} . "_texi"} = \@texi_lines; 20601 } 20602 if (($cmd_ref->{'style'} eq 'titlefont') and ($cmd_ref->{'text'} =~ /\S/)) 20603 { 20604 $state->{'element'}->{'titlefont'} = $cmd_ref->{'text'} unless ((exists($state->{'region'}) and ($state->{'region'} eq 'titlepage')) or defined($state->{'element'}->{'titlefont'})) ; 20605 } 20606 if (defined($Texi2HTML::Config::command_handler{$cmd_ref->{'style'}})) 20607 { 20608 $result = init_special($cmd_ref->{'style'},$cmd_ref->{'text'}); 20609 if ($unclosed_commands) 20610 { 20611 $result .= "\n"; # the end of line is eaten by init_special 20612 echo_error("Closing specially handled \@-command $cmd_ref->{'style'}",$line_nr); 20613 } 20614 } 20615 elsif ($cmd_ref->{'style'}) 20616 { 20617 $result = '@' . $cmd_ref->{'style'} . '{' . $cmd_ref->{'text'}; 20618 $result .= '}' unless ($unclosed_commands); 20619 } 20620 else 20621 { 20622 $result = '{' . $cmd_ref->{'text'}; 20623 # don't close { if we are closing stack as we are not 20624 # sure this is a licit { ... } construct. 20625 $result .= '}' unless ($unclosed_commands); 20626 } 20627 return $result; 20628} 20629 20630sub scan_structure($$$$;$) 20631{ 20632 my $line = shift; 20633 my $text = shift; 20634 my $stack = shift; 20635 my $state = shift; 20636 my $line_nr = shift; 20637 20638 die "stack not an array ref" unless (ref($stack) eq "ARRAY"); 20639 my $cline = $line; 20640 #print STDERR "SCAN_STRUCTURE: $line"; 20641 #dump_stack ($text, $stack, $state); 20642 if (!$state->{'raw'} and (!exists($state->{'region_lines'}))) 20643 { 20644 if (!$state->{'verb'} and $state->{'menu'} and $cline =~ /^\*/o) 20645 { 20646 # new menu entry 20647 my $menu_line = $cline; 20648 my $node; 20649 if ($cline =~ /^\*\s+($NODERE)::/) 20650 { 20651 $node = $1; 20652 } 20653 elsif ($cline =~ /^\*\s+([^:]+):\s*([^\t,\n]*?)([\t,\n]|\.\s)/) 20654 { 20655 #$name = $1; 20656 $node = $2; 20657 } 20658 if ($node) 20659 { 20660 menu_entry_texi(normalise_node($node), $state, $line_nr); 20661 } 20662 } 20663 } 20664 20665 while(1) 20666 { 20667 # scan structure 20668 #print STDERR "WHILE (s):$cline"; 20669 #dump_stack($text, $stack, $state); 20670 20671 # as texinfo 4.5 20672 # verbatim might begin at another position than beginning 20673 # of line, and end verbatim might too. To end a verbatim section 20674 # @end verbatim must have exactly one space between end and verbatim 20675 # things following end verbatim are not ignored. 20676 # 20677 # html might begin at another position than beginning 20678 # of line, but @end html must begin the line, and have 20679 # exactly one space. Things following end html are ignored. 20680 # tex and ignore works like html 20681 # 20682 # ifnothtml might begin at another position than beginning 20683 # of line, and @end ifnothtml might too, there might be more 20684 # than one space between @end and ifnothtml but nothing more on 20685 # the line. 20686 # @end itemize, @end ftable works like @end ifnothtml. 20687 # except that @item on the same line than @end vtable doesn't work 20688 # 20689 # text right after the itemize before an item is displayed. 20690 # @item might be somewhere in a line. 20691 # strangely @item on the same line than @end vtable doesn't work 20692 # there should be nothing else than a command following @itemize... 20693 # 20694 # see more examples in formatting directory 20695 20696 if ($state->{'raw'}) 20697 { 20698 my $tag = $state->{'raw'}; 20699 ################# debug 20700 if (! @$stack or ($stack->[-1]->{'style'} ne $tag)) 20701 { 20702 print STDERR "Bug: raw or special: $tag but not on top of stack\n"; 20703 print STDERR "line: $cline"; 20704 dump_stack($text, $stack, $state); 20705 exit 1; 20706 } 20707 ################# end debug 20708 # macro_regexp 20709 if ($cline =~ /^(.*?)\@end\s([a-zA-Z][\w-]*)/o and ($2 eq $tag)) 20710 { 20711 $cline =~ s/^(.*?)\@end\s$tag//; 20712 add_prev ($text, $stack, $1); 20713 delete $state->{'raw'}; 20714 my $style = pop @$stack; 20715 if (defined($Texi2HTML::Config::command_handler{$tag})) 20716 { # replace the special region by what init_special give 20717 if ($style->{'text'} !~ /^\s*$/) 20718 { 20719 add_prev ($text, $stack, init_special($style->{'style'}, $style->{'text'})); 20720 } 20721 20722 } 20723 else 20724 { 20725 add_prev ($text, $stack, $style->{'text'} . "\@end $tag"); 20726 } 20727 next; 20728 } 20729 else 20730 { 20731 add_prev ($text, $stack, $cline); 20732 return if (defined($Texi2HTML::Config::command_handler{$tag})); 20733 last; 20734 } 20735 } 20736 20737 if (defined($state->{'verb'})) 20738 { 20739 my $char = quotemeta($state->{'verb'}); 20740 if ($cline =~ s/^(.*?)$char\}/\}/) 20741 { 20742 add_prev($text, $stack, $1 . $state->{'verb'}); 20743 $stack->[-1]->{'text'} = $state->{'verb'} . $stack->[-1]->{'text'}; 20744 delete $state->{'verb'}; 20745 next; 20746 } 20747 else 20748 { 20749 add_prev($text, $stack, $cline); 20750 last; 20751 } 20752 } 20753 20754 # macro_regexp 20755 if ($cline =~ s/^([^{}@]*)\@end\s+([a-zA-Z][\w-]*)//) 20756 { 20757 add_prev($text, $stack, $1); 20758 my $end_tag = $2; 20759 #print STDERR "END STRUCTURE $end_tag\n"; 20760 $state->{'detailmenu'}-- if ($end_tag eq 'detailmenu' and $state->{'detailmenu'}); 20761 if (defined($state->{'text_macro_stack'}) 20762 and @{$state->{'text_macro_stack'}} 20763 and ($end_tag eq $state->{'text_macro_stack'}->[-1])) 20764 { 20765 pop @{$state->{'text_macro_stack'}}; 20766 if (exists($region_lines{$end_tag})) 20767 { # end a region_line macro, like documentdescription, copying 20768 print STDERR "Bug: end_tag $end_tag ne $state->{'region_lines'}->{'format'}\n" 20769 if ($end_tag ne $state->{'region_lines'}->{'format'}); 20770 print STDERR "Bug: end_tag $end_tag ne $state->{'region'}\n" 20771 if ($end_tag ne $state->{'region'}); 20772 $state->{'region_lines'}->{'number'}--; 20773 if ($state->{'region_lines'}->{'number'} == 0) 20774 { 20775 close_region($state); 20776 } 20777 #dump_stack($text, $stack, $state); 20778 } 20779 if ($end_tag eq 'menu' or $Texi2HTML::Config::region_formats_kept{$end_tag}) 20780 { 20781 add_prev($text, $stack, "\@end $end_tag"); 20782 } 20783 else 20784 { 20785 #print STDERR "End $end_tag\n"; 20786 #dump_stack($text, $stack, $state); 20787 return if ($cline =~ /^\s*$/); 20788 } 20789 $state->{'menu'}-- if ($end_tag eq 'menu'); 20790 } 20791 elsif ($Texi2HTML::Config::texi_formats_map{$end_tag}) 20792 { 20793 echo_error ("\@end $end_tag without corresponding element", $line_nr); 20794 #dump_stack($text, $stack, $state); 20795 } 20796 else 20797 { 20798 if ($end_tag eq 'float' and $state->{'float'}) 20799 { 20800 delete $state->{'float'}; 20801 } 20802 elsif ($end_tag eq $state->{'table_stack'}->[-1]) 20803 { 20804 enter_table_index_entry($text, $stack, $state, $line_nr); 20805 pop @{$state->{'table_stack'}}; 20806 } 20807 #add end tag 20808 add_prev($text, $stack, "\@end $end_tag"); 20809 } 20810 next; 20811 } 20812 #elsif ($cline =~ s/^([^{}@]*)\@([a-zA-Z]\w*|["'~\@\}\{,\.!\?\s\*\-\^`=:\/])//o) 20813 # macro_regexp 20814 elsif ($cline =~ s/^([^{}@]*)\@(["'~\@\}\{,\.!\?\s\*\-\^`=:\|\/\\])//o or $cline =~ s/^([^{}@]*)\@([a-zA-Z][\w-]*)([\s\{\}\@])/$3/o or $cline =~ s/^([^{}@]*)\@([a-zA-Z][\w-]*)$//o) 20815 { 20816 add_prev($text, $stack, $1); 20817 my $macro = $2; 20818 #print STDERR "MACRO $macro\n"; 20819 $macro = $alias{$macro} if (exists($alias{$macro})); 20820 if (defined($Texi2HTML::Config::misc_command{$macro})) 20821 { 20822 my $line; 20823 ($cline, $line) = misc_command_structure($cline, $macro, $state, 20824 $line_nr); 20825 add_prev ($text, $stack, "\@$macro".$line); 20826 next; 20827 } 20828 elsif ($macro eq 'detailmenu') 20829 { 20830 add_prev ($text, $stack, "\@$macro" . $cline); 20831 $state->{'detailmenu'}++; 20832 last; 20833 } 20834 elsif ($sec2level{$macro}) 20835 { 20836 if ($cline =~ /^\s*(.*)$/) 20837 { 20838 my $name = $1; 20839 my $heading_ref = new_section_heading($macro, $name, $state); 20840 #if ($state->{'place'} eq $no_element_associated_place) 20841 if (exists($state->{'region_lines'}) and $state->{'region_lines'}->{'format'}) 20842 { 20843 my $region = $state->{'region_lines'}->{'format'}; 20844 $state->{'region_lines'}->{'head_num'}++; 20845 my $num = $state->{'region_lines'}->{'head_num'}; 20846 $heading_ref->{'id'} = "${target_prefix}${region}_HEAD$num"; 20847 $heading_ref->{'sec_num'} = "${region}_$num"; 20848 $heading_ref->{'region'} = $region; 20849 $heading_ref->{'region_head_num'} = $num; 20850 } 20851 else 20852 { 20853 $document_head_num++; 20854 $heading_ref->{'id'} = "HEAD$document_head_num"; 20855 $heading_ref->{'sec_num'} = $document_head_num; 20856 } 20857 # this is only used when there is a index entry after the 20858 # heading 20859 $heading_ref->{'target'} = $heading_ref->{'id'}; 20860 $heading_ref->{'heading'} = 1; 20861 $heading_ref->{'tag_level'} = $macro; 20862 $heading_ref->{'number'} = ''; 20863 20864 $state->{'element'} = $heading_ref; 20865 push @{$state->{'place'}}, $heading_ref; 20866 $headings{$heading_ref->{'sec_num'}} = $heading_ref; 20867 } 20868 add_prev ($text, $stack, "\@$macro" . $cline); 20869 last; 20870 } 20871 elsif (index_command_prefix($macro) ne '') 20872 { # if we are already in a (v|f)table the construct is quite 20873 # wrong 20874 # FIXME should it be discarded? 20875 # if ($state->{'item'}) 20876 # { 20877 # echo_error("ignored \@$macro already in an \@$state->{'item'} entry", $line_nr); 20878 # next; 20879 # } 20880 my $index_prefix = index_command_prefix($macro); 20881 my $key = $cline; 20882 $key =~ s/^\s*//; 20883 enter_index_entry($index_prefix, $line_nr, $key, $state->{'place'}, $state->{'element'}, $macro, $state->{'region'}); 20884 add_prev ($text, $stack, "\@$macro" . $cline); 20885 last; 20886 } 20887 elsif (defined($Texi2HTML::Config::texi_formats_map{$macro})) 20888 { 20889 my $macro_kept; 20890 #print STDERR "TEXT_MACRO: $macro\n"; 20891 if ($Texi2HTML::Config::texi_formats_map{$macro} eq 'raw') 20892 { 20893 $state->{'raw'} = $macro; 20894 #print STDERR "RAW\n"; 20895 } 20896 elsif ($macro eq 'menu') 20897 { 20898 $state->{'menu'}++; 20899 delete ($state->{'prev_menu_node'}); 20900 push @{$state->{'text_macro_stack'}}, $macro; 20901 #print STDERR "MENU (text_macro_stack: @{$state->{'text_macro_stack'}})\n"; 20902 } 20903 elsif (exists($region_lines{$macro})) 20904 { 20905 if (exists($state->{'region_lines'}) and ($state->{'region_lines'}->{'format'} ne $macro)) 20906 { 20907 echo_error("\@$macro not allowed within $state->{'region_lines'}->{'format'}", $line_nr); 20908 next; 20909 } 20910 open_region ($macro, $state); 20911 if ($Texi2HTML::Config::region_formats_kept{$macro}) 20912 { 20913 add_prev($text, $stack, "\@$macro"); 20914 $macro_kept = 1; 20915 $state->{'region_lines'}->{'first_line'} = 1; 20916 } 20917 push @{$state->{'text_macro_stack'}}, $macro; 20918 } 20919 # if it is a raw formatting command or a menu command 20920 # we must keep it for later 20921 if (($state->{'raw'} and (!defined($Texi2HTML::Config::command_handler{$macro}))) or ($macro eq 'menu')) 20922 { 20923 add_prev($text, $stack, "\@$macro"); 20924 $macro_kept = 1; 20925 } 20926 if ($state->{'raw'}) 20927 { 20928 push @$stack, { 'style' => $macro, 'text' => '' }; 20929 } 20930 next if $macro_kept; 20931 #dump_stack ($text, $stack, $state); 20932 return if ($cline =~ /^\s*$/); 20933 } 20934 elsif ($macro eq 'float') 20935 { 20936 my ($style_texi, $label_texi) = split(/,/, $cline); 20937 $style_texi = normalise_space($style_texi); 20938 $label_texi = undef if (defined($label_texi) and ($label_texi =~ /^\s*$/)); 20939 if (defined($label_texi)) 20940 { # The float may be a target for refs if it has a label 20941 $label_texi = normalise_node($label_texi); 20942 if (exists($nodes{$label_texi}) and defined($nodes{$label_texi}) 20943 and $nodes{$label_texi}->{'seen'}) 20944 { 20945 echo_error ("Duplicate label found: $label_texi", $line_nr); 20946 while ($cline =~ /,/) 20947 { 20948 $cline =~ s/,.*$//; 20949 } 20950 } 20951 else 20952 { 20953 my $float = { }; 20954 if (exists($nodes{$label_texi}) and defined($nodes{$label_texi})) 20955 { # float appeared in a menu 20956 $float = $nodes{$label_texi}; 20957 } 20958 else 20959 { 20960 $nodes{$label_texi} = $float; 20961 } 20962 $float->{'float'} = 1; 20963 $float->{'tag'} = 'float'; 20964 $float->{'texi'} = $label_texi; 20965 $float->{'seen'} = 1; 20966 $float->{'id'} = $label_texi; 20967 $float->{'target'} = $label_texi; 20968#print STDERR "FLOAT: $float $float->{'texi'}, place $state->{'place'}\n"; 20969 push @{$state->{'place'}}, $float; 20970 $float->{'element'} = $state->{'element'}; 20971 $state->{'float'} = $float; 20972 $float->{'style_texi'} = $style_texi; 20973 push @floats, $float; 20974 } 20975 } 20976 add_prev($text, $stack, "\@$macro" . $cline); 20977 last; 20978 } 20979 elsif (defined($Texi2HTML::Config::def_map{$macro})) 20980 { 20981 # @ may protect end of line in @def. We reconstruct lines here. 20982 # in the texinfo manual is said that spaces after @ collapse 20983 if ($cline =~ /(\@+)\s*$/) 20984 { 20985 my $at_at_end_of_line = $1; 20986 if ((length($at_at_end_of_line) % 2) == 1) 20987 { 20988 #print STDERR "Line continue $cline"; 20989 my $def_line = $cline; 20990 $def_line =~ s/\@\s*$//; 20991 chomp($def_line); 20992 $state->{'in_deff_line'} = "\@$macro" .$def_line; 20993 return; 20994 } 20995 } 20996 #We must enter the index entries 20997 my ($prefix, $entry, $argument) = get_deff_index($macro, $cline, $line_nr); 20998 # use deffn instead of deffnx for @-command record 20999 # associated with index entry 21000 my $idx_macro = $macro; 21001 $idx_macro =~ s/x$//; 21002 enter_index_entry($prefix, $line_nr, $entry, $state->{'place'}, 21003 $state->{'element'}, $idx_macro, $state->{'region'}) if ($prefix); 21004 $cline =~ s/(.*)//; 21005 add_prev($text, $stack, "\@$macro" . $1); 21006 # the text is discarded but we must handle correctly bad 21007 # texinfo with 2 @def-like commands on the same line 21008 substitute_text({'structure' => 1, 'place' => $state->{'place'} },undef, $argument); 21009 } 21010 elsif ($macro =~ /^itemx?$/) 21011 { 21012 enter_table_index_entry($text, $stack, $state, $line_nr); 21013 if ($state->{'table_stack'}->[-1] =~ /^(v|f)table$/) 21014 { 21015 $state->{'item'} = $macro; 21016 push @$stack, { 'format' => 'index_item', 'text' => '' }; 21017 } 21018 else 21019 { 21020 add_prev($text, $stack, "\@$macro"); 21021 } 21022 } 21023 elsif ($format_type{$macro} and ($format_type{$macro} eq 'table' or $format_type{$macro} eq 'list' or $macro eq 'multitable')) 21024 { # We must enter the index entries of (v|f)table thus we track 21025 # in which table we are 21026 push @{$state->{'table_stack'}}, $macro; 21027 add_prev($text, $stack, "\@$macro"); 21028 } 21029 elsif ($cline =~ s/^{//) 21030 { 21031 if ($macro eq 'verb') 21032 { 21033 if ($cline =~ /^$/) 21034 { 21035 # We already warned in pass texi 21036 #warn "$ERROR verb at end of line"; 21037 } 21038 else 21039 { 21040 $cline =~ s/^(.)//; 21041 $state->{'verb'} = $1; 21042 } 21043 } 21044 elsif ($macro eq 'footnote' and $Texi2HTML::Config::SEPARATED_FOOTNOTES) 21045 { 21046 $state->{'footnote_element'} = $state->{'element'}; 21047 $state->{'footnote_place'} = $state->{'place'}; 21048 $state->{'element'} = $footnote_element; 21049 $state->{'place'} = $footnote_element->{'place'}; 21050 } 21051 push (@$stack, { 'style' => $macro, 'text' => '' }); 21052 } 21053 else 21054 { 21055 $cline = do_unknown (1, $macro, $cline, $text, $stack, $state, $line_nr); 21056 } 21057 next; 21058 } 21059 #elsif($cline =~ s/^([^{}@]*)\@(.)//o) 21060 elsif($cline =~ s/^([^{}@]*)\@([^\s\}\{\@]*)//o) 21061 { 21062 add_prev($text, $stack, $1); 21063 $cline = do_unknown (1, $2, $cline, $text, $stack, $state, $line_nr); 21064 next; 21065 } 21066 elsif ($cline =~ s/^([^{}]*)([{}])//o) 21067 { 21068 add_prev($text, $stack, $1); 21069 if ($2 eq '{') 21070 { 21071 push @$stack, { 'style' => '', 'text' => '' }; 21072 } 21073 else 21074 { 21075 if (@$stack) 21076 { 21077 my $style = pop @$stack; 21078 my $result; 21079 add_prev ($text, $stack, close_structure_command($style, 21080 $state, 0, $line_nr)); 21081 next; 21082 } 21083 else 21084 { 21085 # We warn in the last pass 21086 add_prev ($text, $stack, '}'); 21087 } 21088 } 21089 } 21090 else 21091 { 21092 #print STDERR "END_LINE $cline"; 21093 add_prev($text, $stack, $cline); 21094 enter_table_index_entry($text, $stack, $state, $line_nr); 21095 last; 21096 } 21097 } 21098 return 1; 21099} # end scan_structure 21100 21101sub close_style_command($$$$$) 21102{ 21103 my $text = shift; 21104 my $stack = shift; 21105 my $state = shift; 21106 my $line_nr = shift; 21107 my $line = shift; 21108 21109 my $style = pop @$stack; 21110 my $command = $style->{'style'}; 21111 my $result; 21112 if (!defined($command)) 21113 { 21114 print STDERR "Bug: empty style in pass_text\n"; 21115 return ($result, $command); 21116 } 21117 if (ref($::style_map_ref->{$command}) eq 'HASH') 21118 { 21119 push (@{$style->{'args'}}, $style->{'text'}); 21120 $style->{'fulltext'} .= $style->{'text'}; 21121 #my $number = 0; 21122 #foreach my $arg(@{$style->{'args'}}) 21123 #{ 21124 #print STDERR " $number: $arg\n"; 21125 # $number++; 21126 #} 21127 $style->{'text'} = $style->{'fulltext'}; 21128 $state->{'keep_texi'} = 0 if ( 21129 ($::style_map_ref->{$command}->{'args'}->[$style->{'arg_nr'}] eq 'keep') 21130 and ($state->{'keep_nr'} == 1)); 21131 } 21132 $state->{'no_paragraph'}-- if ($no_paragraph_macro{$command}); 21133 $style->{'no_close'} = 1 if ($state->{'no_close'}); 21134 if ($::style_map_ref->{$command} and (defined($style_type{$command})) and ((!$style->{'no_close'} and ($style_type{$command} eq 'style')) or ($style_type{$command} eq 'accent'))) 21135 { 21136 my $style_command = pop @{$state->{'command_stack'}}; 21137 ############################ debug 21138 if ($style_command ne $command) 21139 { 21140 print STDERR "Bug: $style_command on 'command_stack', not $command\n"; 21141 push @$stack, $style; 21142 push @{$state->{'command_stack'}}, $style_command; 21143 print STDERR "Stacks before pop top:\n"; 21144 dump_stack($text, $stack, $state); 21145 pop @$stack; 21146 } 21147 ############################ end debug 21148 } 21149 if ($state->{'keep_texi'}) 21150 { # don't expand @-commands in anchor, refs... 21151 close_arg ($command, $style->{'arg_nr'}, $state); 21152 $result = '@' . $command . '{' . $style->{'text'} . '}'; 21153 } 21154 else 21155 { 21156 $result = do_simple($command, $style->{'text'}, $state, $style->{'args'}, $line_nr, $style->{'no_open'}, $style->{'no_close'}); 21157 if ($state->{'code_style'} < 0) 21158 { 21159 echo_error ("Bug: negative code_style: $state->{'code_style'}, line:$line", $line_nr); 21160 } 21161 if ($state->{'math_style'} < 0) 21162 { 21163 echo_error ("Bug: negative math_style: $state->{'math_style'}, line:$line", $line_nr); 21164 } 21165 } 21166 return ($result, $command); 21167} 21168 21169sub top_stack_is_menu($) 21170{ 21171 my $stack = shift; 21172 my $top_stack = top_stack($stack, 1); 21173 return 0 if (!$format_type{$top_stack->{'format'}} or $format_type{$top_stack->{'format'}} ne 'menu'); 21174 return 1; 21175} 21176 21177sub scan_line($$$$;$) 21178{ 21179 my $original_line = shift; 21180 my $text = shift; 21181 my $stack = shift; 21182 my $state = shift; 21183 my $line_nr = shift; 21184 21185 die "stack not an array ref" unless (ref($stack) eq "ARRAY"); 21186 my $cline = $original_line; 21187 #print STDERR "SCAN_LINE (@{$state->{'command_stack'}})".format_line_number($line_nr).": $original_line"; 21188 #dump_stack($text, $stack, $state ); 21189 my $new_menu_entry; # true if there is a new menu entry 21190# my $menu_description_in_format; # true if we are in a menu description 21191# # but in another format section (@table....) 21192 21193 # this can happen currently with quotations 21194 if (defined($state->{'prepend_text'})) 21195 { 21196 $cline = $state->{'prepend_text'} . $cline; 21197 $state->{'prepend_text'} = undef; 21198 delete $state->{'prepend_text'}; 21199 } 21200 21201 # end of lines are really protected only for @def* 21202 # this cannot happen anymore, because the lines are concatenated 21203 # in pass_structure 21204 unless ($state->{'end_of_line_protected'}) # and $in_some_format) 21205 { 21206 if (!$state->{'raw'} and !$state->{'verb'} and $state->{'menu'}) 21207 { # new menu entry 21208 my ($node, $name, $ending); 21209 if ($cline =~ s/^\*(\s+$NODERE)(::)//o) 21210 { 21211 $node = $1; 21212 $ending = $2; 21213 } 21214 elsif ($cline =~ s/^\*(\s+[^:]+):(\s*[^\t,\n]*?)(([\t,\n])|((\.)(\s)))//o) 21215 { 21216 $name = $1; 21217 $node = $2; 21218 $ending = $4; 21219 $ending = $6 if (!$ending); 21220 $cline = $7.$cline if (defined($7)); 21221 } 21222 if ($node) 21223 { 21224 print STDERR "# Potential menu entry: $node\n" if ($T2H_DEBUG & $DEBUG_MENU); 21225 $new_menu_entry = 1; 21226 my $menu_entry = { 'name' => $name, 'node' => $node, 'ending' => $ending }; 21227 # in SIMPLE_MENU case we don't begin a description, description is 21228 # just some normal (preformatted) text 21229 if ($Texi2HTML::Config::SIMPLE_MENU) 21230 { 21231 add_prev ($text, $stack, do_menu_link($state, $line_nr, $menu_entry)); 21232 #dump_stack($text, $stack, $state); 21233 } 21234 else 21235 { 21236 # close description and comment, if they are opened. 21237 if (!close_menu_comment($text, $stack, $state, $line_nr) 21238 and !close_menu_description($text, $stack, $state, $line_nr) 21239 and $state->{'preformatted'}) 21240 { 21241 close_paragraph($text, $stack, $state, $line_nr); 21242 } 21243 print STDERR "# New menu entry: $node\n" if ($T2H_DEBUG & $DEBUG_MENU); 21244 my $fusionned_description = 0; 21245 # fusionned looks better in preformatted. But some formats 21246 # want to always distinguish link and description 21247 if ($Texi2HTML::Config::SEPARATE_DESCRIPTION or !$state->{'preformatted'}) 21248 { 21249 add_prev ($text, $stack, do_menu_link($state, $line_nr, $menu_entry)); 21250 } 21251 else 21252 { 21253 $fusionned_description = 1; 21254 } 21255 push @$stack, {'format' => 'menu_description', 'text' => '', 'menu_entry' => $menu_entry, 'fusionned_description' => $fusionned_description}; 21256 $state->{'code_style'}++ if ($Texi2HTML::Config::format_code_style{'menu_description'}); 21257 if ($fusionned_description) 21258 { 21259 begin_paragraph($stack, $state) if $state->{'preformatted'}; 21260 add_prev ($text, $stack, do_menu_link($state, $line_nr, $menu_entry)); 21261 } 21262 } 21263 } 21264 # we may be in a menu entry description, we close it 21265 # if there is an empty line, so the last arg is $cline 21266 if (!$new_menu_entry and close_menu_description($text, $stack, $state, $line_nr, $cline)) 21267 { 21268 if ($state->{'preformatted'}) 21269 { 21270 begin_paragraph($stack, $state); 21271 } 21272 else 21273 { 21274 # only start a menu_comment if right in menu and not in 21275 # an en format below a menu because if not right 21276 # in a menu we have no way to distinguish a menu_comment 21277 # and some normal text in the format. 21278 # also it is not started in preformatted environment 21279 begin_format($text, $stack, $state, 'menu_comment', $cline, $line_nr) if ($stack->[-1]->{'format'} and $format_type{$stack->[-1]->{'format'}} and $format_type{$stack->[-1]->{'format'}} eq 'menu'); 21280 } 21281 } 21282 } 21283 my $top_stack = top_stack($stack); 21284 if (($top_stack->{'format'} and $top_stack->{'format'} eq 'menu_description') or $state->{'raw'} or $state->{'preformatted'} or $state->{'no_paragraph'} or $state->{'keep_texi'} or $state->{'remove_texi'}) 21285 { # empty lines are left unmodified in these contexts. 21286 # it is also possible to be in preformatted within a menu_description 21287 if ($cline =~ /^\s*$/) 21288 { 21289 add_prev($text, $stack, do_text($cline,$state)); 21290 return; 21291 } 21292 } 21293 else 21294 { 21295 if ($cline =~ /^\s*$/) 21296 { 21297 if ($state->{'paragraph_context'}) 21298 { # An empty line ends a paragraph 21299 close_paragraph($text, $stack, $state, $line_nr); 21300 } 21301 add_prev($text, $stack, &$Texi2HTML::Config::empty_line($cline,$state)); 21302 return 1; 21303 } 21304 else 21305 { 21306 if (!no_paragraph($state,$cline)) 21307 { # open a paragraph, unless the line begins with a macro that 21308 # shouldn't trigger a paragraph opening 21309 begin_paragraph($stack, $state); 21310 } 21311 } 21312 } 21313 # we flag specially deff_item and table line that contain only 21314 # inter_item_command, which typically is be @c, @comment, @*index, such 21315 # that the formatter can treat those specifically. 21316 my $top_format = top_stack($stack,2); 21317 if ($top_format->{'only_inter_commands'} and !$state->{'keep_texi'}) 21318 { 21319 my $real_format = $top_format->{'format_ref'}->{'format'}; 21320 my $next_tag = next_tag($cline); 21321 $next_tag = '' if (!defined($next_tag)); 21322 my $next_end_tag = next_end_tag($cline); 21323 $next_end_tag = '' if (!defined($next_end_tag)); 21324#print STDERR "$top_format->{'format'} $next_tag, end $next_end_tag :::$cline"; 21325 delete $top_format->{'only_inter_commands'} unless 21326 ( 21327 $Texi2HTML::Config::inter_item_commands{$next_tag} or 21328 (index_command_prefix($next_tag) ne '' and $Texi2HTML::Config::inter_item_commands{'cindex'}) or 21329 ($top_format->{'format'} eq 'deff_item' and "${real_format}x" eq $next_tag) or 21330 ($top_format->{'format'} ne 'deff_item' and $next_tag =~ /^itemx?$/) or 21331 ( $next_end_tag eq $real_format ) 21332 ); 21333 #print STDERR "STILL $top_format->{'only_inter_commands'}\n" if ($top_format->{'only_inter_commands'}); 21334 } 21335 } 21336 delete $state->{'end_of_line_protected'} 21337 if ($state->{'end_of_line_protected'}); 21338 21339 while(1) 21340 { 21341 # scan_line 21342 #print STDERR "WHILE (l): $cline|"; 21343 # dump_stack($text, $stack, $state); 21344 # we're in a raw format (html, tex if !L2H, verbatim) 21345 if (defined($state->{'raw'})) 21346 { 21347 (dump_stack($text, $stack, $state), die "Bug for raw ($state->{'raw'})") if (! @$stack or ! ($stack->[-1]->{'style'} eq $state->{'raw'})); 21348 # macro_regexp 21349 if ($cline =~ /^(.*?)\@end\s([a-zA-Z][\w-]*)/o and ($2 eq $state->{'raw'})) 21350 # don't protect html, it is done by Texi2HTML::Config::raw if needed 21351 { 21352 $cline =~ s/^(.*?)\@end\s$state->{'raw'}//; 21353 print STDERR "# end raw $state->{'raw'}\n" if ($T2H_DEBUG & $DEBUG_FORMATS); 21354 add_prev ($text, $stack, $1); 21355 my $style = pop @$stack; 21356 if ($style->{'text'} !~ /^\s*$/) 21357 { 21358 if ($state->{'keep_texi'}) 21359 { 21360 add_prev ($text, $stack, $style->{'text'} . "\@end $state->{'raw'}"); 21361 } 21362 elsif ($state->{'remove_texi'}) 21363 { 21364 add_prev ($text, $stack, &$Texi2HTML::Config::raw_no_texi($style->{'style'}, $style->{'text'})); 21365 } 21366 else 21367 { 21368 add_prev($text, $stack, &$Texi2HTML::Config::raw($style->{'style'}, $style->{'text'})); 21369 } 21370 } 21371 if (!$state->{'keep_texi'} and !$state->{'remove_texi'}) 21372 { 21373 # reopen preformatted if it was interrupted by the raw format 21374 # if raw format is html the preformatted wasn't interrupted 21375 begin_paragraph($stack, $state) if ($state->{'preformatted'} and (!$Texi2HTML::Config::format_in_paragraph{$state->{'raw'}})); 21376 delete $state->{'raw'}; 21377 return if ($cline =~ /^\s*$/); 21378 } 21379 delete $state->{'raw'}; 21380 next; 21381 } 21382 else 21383 { 21384 print STDERR "#within raw $state->{'raw'}:$cline" if ($T2H_DEBUG & $DEBUG_FORMATS); 21385 add_prev ($text, $stack, $cline); 21386 last; 21387 } 21388 } 21389 21390 # we are within a @verb 21391 if (defined($state->{'verb'})) 21392 { 21393 my $char = quotemeta($state->{'verb'}); 21394 if ($cline =~ s/^(.*?)$char\}/\}/) 21395 { 21396 if ($state->{'keep_texi'}) 21397 { 21398 add_prev($text, $stack, $1 . $state->{'verb'}); 21399 $stack->[-1]->{'text'} = $state->{'verb'} . $stack->[-1]->{'text'}; 21400 } 21401 else 21402 { 21403 add_prev($text, $stack, do_text($1, $state)); 21404 } 21405 delete $state->{'verb'}; 21406 next; 21407 } 21408 else 21409 { 21410 add_prev($text, $stack, $cline); 21411 last; 21412 } 21413 } 21414 21415 # a special case for @ followed by an end of line in deff 21416 # FIXME this is similar with makeinfo, but shouldn't that 21417 # be done for @floats and @quotations too? and @item, @center? 21418 # this piece of code is required, to avoid the 'cmd_line' to be 21419 # closed below 21420 # this cannot happen anymore, because the lines are concatenated 21421 # in pass_structure 21422 if ($state->{'end_of_line_protected'})# and in some format 21423 { 21424 print STDERR "Bug: 'end_of_line_protected' with text following: $cline\n" 21425 unless $cline =~ /^$/; 21426 return; 21427 } 21428 21429 # We handle now the end tags 21430 # macro_regexp 21431 if ($state->{'keep_texi'} and $cline =~ s/^([^{}@]*)\@end\s+([a-zA-Z][\w-]*)//) 21432 { 21433 my $end_tag = $2; 21434 add_prev($text, $stack, $1 . "\@end $end_tag"); 21435 next; 21436 } 21437 # macro_regexp 21438 elsif ($state->{'remove_texi'} and $cline =~ s/^([^{}@]*)\@end\s+([a-zA-Z][\w-]*)//) 21439 { 21440 add_prev($text, $stack, $1); 21441 next; 21442 } 21443 # macro_regexp 21444 #if (s/^([^{}@,]*)\@end\s+([a-zA-Z][\w-]*)\s//o or s/^([^{}@,]*)\@end\s+([a-zA-Z][\w-]*)$//o) 21445 if ($cline =~ s/^([^{}@,]*)\@end\s+([a-zA-Z][\w-]*)//o) 21446 { 21447 add_prev($text, $stack, do_text($1, $state)); 21448 my $end_tag = $2; 21449 #print STDERR "END_MACRO $end_tag\n"; 21450 #dump_stack ($text, $stack, $state); 21451 21452 # First we test if the stack is not empty. 21453 # Then we test if the end tag is a format tag. 21454 # We then close paragraphs and preformatted at top of the stack. 21455 # We handle the end tag (even when it was not the tag which appears 21456 # on the top of the stack; in that case we close anything 21457 # until that element) 21458 my $top_stack = top_stack($stack); 21459 if (!$top_stack) 21460 { 21461 echo_error ("\@end $end_tag without corresponding opening", $line_nr); 21462 add_prev($text, $stack, "\@end $end_tag"); 21463 next; 21464 } 21465 21466 if (!$format_type{$end_tag}) 21467 { 21468 echo_warn ("Unknown \@end $end_tag", $line_nr); 21469 #warn "$ERROR Unknown \@end $end_tag\n"; 21470 add_prev($text, $stack, "\@end $end_tag"); 21471 next; 21472 } 21473 if (!close_menu_description($text, $stack, $state, $line_nr)) 21474 { 21475 close_paragraph($text, $stack, $state, $line_nr); 21476 } 21477 21478 $top_stack = top_stack($stack); 21479 if (!$top_stack or (!defined($top_stack->{'format'}))) 21480 { 21481 echo_error ("\@end $end_tag without corresponding opening element", $line_nr); 21482 add_prev($text, $stack, "\@end $end_tag"); 21483 dump_stack ($text, $stack, $state) if ($T2H_DEBUG); 21484 next; 21485 } 21486 # Warn if the format on top of stack is not compatible with the 21487 # end tag, and find the end tag. 21488 unless ( 21489 ($top_stack->{'format'} eq $end_tag) 21490 or 21491 ( 21492 $format_type{$end_tag} eq 'menu' and 21493 $top_stack->{'format'} eq 'menu_comment' 21494 ) or 21495 ( 21496 $end_tag eq 'multitable' and $top_stack->{'format'} eq 'cell' 21497 ) or 21498 ( 21499 $format_type{$end_tag} eq 'list' and $top_stack->{'format'} eq 'item' 21500 ) or 21501 ( 21502 $format_type{$end_tag} eq 'table' 21503 and 21504 ($top_stack->{'format'} eq 'term' or $top_stack->{'format'} eq 'line') 21505 ) or 21506 ( 21507 defined($Texi2HTML::Config::def_map{$end_tag}) and 21508 $top_stack->{'format'} eq 'deff_item' 21509 ) 21510 ) 21511 { 21512 # this is not the right format. We try to close other 21513 # formats to find the format we are searching for. 21514 # First we close paragraphs, as with a wrong $end_format 21515 # they may not be closed properly. 21516 21517 #print STDERR " MISMATCH got $top_stack->{'format'} waited \@end $end_tag($top_stack->{'format'})\n"; 21518 #dump_stack ($text, $stack, $state); 21519 close_paragraph($text, $stack, $state, $line_nr); 21520 $top_stack = top_stack($stack); 21521 if (!$top_stack or (!defined($top_stack->{'format'}))) 21522 { 21523 echo_error ("\@end $end_tag without corresponding opening element", $line_nr); 21524 add_prev($text, $stack, "\@end $end_tag"); 21525 # at that point the dump_stack is not very useful, since 21526 # close_paragraph above may hide interesting info 21527 dump_stack ($text, $stack, $state) if ($T2H_DEBUG); 21528 next; 21529 } 21530 my $waited_format = $top_stack->{'format'}; 21531 $waited_format = $fake_format{$top_stack->{'format'}} if ($format_type{$top_stack->{'format'}} eq 'fake'); 21532 echo_error ("waiting for end of $waited_format, found \@end $end_tag", $line_nr); 21533 #dump_stack ($text, $stack, $state); 21534 close_stack($text, $stack, $state, $line_nr, $end_tag); 21535 # FIXME this is too complex 21536 # an empty preformatted may appear when closing things as 21537 # when closed, formats reopen the preformatted environment 21538 # in case there is some text following, but we know it isn't 21539 # the case here, thus we can close paragraphs. 21540 close_paragraph($text, $stack, $state); 21541 my $new_top_stack = top_stack($stack); 21542 next unless ($new_top_stack and defined($new_top_stack->{'format'}) and (($new_top_stack->{'format'} eq $end_tag) 21543 or (($format_type{$new_top_stack->{'format'}} eq 'fake') and ($fake_format{$new_top_stack->{'format'}} eq $format_type{$end_tag})))); 21544 } 21545 # We should now be able to handle the format 21546 if (defined($format_type{$end_tag})) 21547 {# remove the space or new line following the @end command 21548 $cline =~ s/\s//; 21549 if (end_format($text, $stack, $state, $end_tag, $line_nr)) 21550 { # if end_format is false, paragraph is already begun 21551 begin_paragraph_after_command($state,$stack,$end_tag,$cline); 21552 } 21553 } 21554 next; 21555 } 21556 # This is a macro 21557 #elsif (s/^([^{}@]*)\@([a-zA-Z]\w*|["'~\@\}\{,\.!\?\s\*\-\^`=:\/])//o) 21558 # macro_regexp 21559 elsif ($cline =~ s/^([^{},@]*)\@(["'~\@\}\{,\.!\?\s\*\-\^`=:\|\/\\])//o or $cline =~ s/^([^{}@,]*)\@([a-zA-Z][\w-]*)([\s\{\}\@])/$3/o or $cline =~ s/^([^{},@]*)\@([a-zA-Z][\w-]*)$//o) 21560 { 21561 my $before_macro = $1; 21562 my $macro = $2; 21563 $macro = $alias{$macro} if (exists($alias{$macro})); 21564 my $punct; 21565 if (!$state->{'keep_texi'} and $macro eq ':' and $before_macro =~ /(.)$/ and $Texi2HTML::Config::colon_command_punctuation_characters{$1}) 21566 { 21567 $before_macro =~ s/(.)$//; 21568 $punct = $1; 21569 } 21570 add_prev($text, $stack, do_text($before_macro, $state)); 21571 add_prev($text, $stack, &$Texi2HTML::Config::colon_command($punct)) if (defined($punct)); 21572 #print STDERR "MACRO $macro\n"; 21573 #print STDERR "LINE $cline"; 21574 #dump_stack ($text, $stack, $state); 21575 21576 close_paragraph($text, $stack, $state, $line_nr, 1) if ($Texi2HTML::Config::stop_paragraph_command{$macro} and !$state->{'keep_texi'}); 21577 21578 if (defined($Texi2HTML::Config::misc_command{$macro})) 21579 { 21580 # Handle the misc command 21581 $cline = misc_command_text($cline, $macro, $stack, $state, $text, $line_nr); 21582 return unless (defined($cline)); 21583 unless ($Texi2HTML::Config::misc_command{$macro}->{'keep'}) 21584 { 21585 begin_paragraph($stack, $state) if 21586 (!no_paragraph($state,$cline)); 21587 next; 21588 } 21589 } 21590 if ($macro eq 'listoffloats') 21591 { 21592 if ($state->{'keep_texi'}) 21593 { 21594 if ($cline =~ s/(.*)//o) 21595 { 21596 add_prev($text, $stack, "\@$macro" . $1); 21597 } 21598 next; 21599 } 21600 return undef if ($state->{'remove_texi'}); 21601 21602 if ($cline =~ s/^(\s+)(.*)//o) 21603 { 21604 my $arg = $2; 21605 my $style_id = cross_manual_line(normalise_space($arg)); 21606 my $style = substitute_line (&$Texi2HTML::Config::listoffloats_style($arg)); 21607 if (exists ($floats{$style_id})) 21608 { 21609 close_paragraph($text, $stack, $state, $line_nr); 21610 my @listoffloats_entries = (); 21611 foreach my $float (@{$floats{$style_id}->{'floats'}}) 21612 { 21613 my $float_style = substitute_line(&$Texi2HTML::Config::listoffloats_float_style($arg, $float)); 21614 my $caption_lines = &$Texi2HTML::Config::listoffloats_caption($float); 21615 # we set 'multiple_pass', 'region' and 21616 # 'region_pass'such that index entries 21617 # and anchors are not handled one more time; 21618 # the caption has already been formatted, 21619 # and these have been handled at the right place 21620 # FIXME footnotes? 21621 my $caption = substitute_text(prepare_state_multiple_pass($macro, $state), undef, @$caption_lines); 21622 push @listoffloats_entries, &$Texi2HTML::Config::listoffloats_entry($arg, $float, $float_style, $caption, href($float, $state->{'element'}->{'file'}, $line_nr)); 21623 } 21624 add_prev($text, $stack, &$Texi2HTML::Config::listoffloats($arg, $style, \@listoffloats_entries)); 21625 } 21626 else 21627 { 21628 echo_warn ("Unknown float style $arg", $line_nr); 21629 } 21630 } 21631 else 21632 { 21633 echo_error ("Bad \@$macro line: $cline", $line_nr); 21634 } 21635 return undef; 21636 } 21637 # This is a @macroname{...} construct. We add it on top of stack 21638 # It will be handled when we encounter the '}' 21639 # There is a special case for def macros as @deffn{def} is licit 21640 if (!$Texi2HTML::Config::def_map{$macro} and $cline =~ s/^{//) #} 21641 { 21642 if ($macro eq 'verb') 21643 { 21644 if ($cline =~ /^$/) 21645 { 21646 # Allready warned 21647 #warn "$ERROR verb at end of line"; 21648 } 21649 else 21650 { 21651 $cline =~ s/^(.)//; 21652 $state->{'verb'} = $1; 21653 } 21654 } 21655 # currently if remove_texi and anchor/ref/footnote 21656 # the text within the command is ignored 21657 # see t2h_remove_command in texi2html.init 21658 push (@$stack, { 'style' => $macro, 'text' => '', 'arg_nr' => 0 }); 21659 $state->{'no_paragraph'}++ if ($no_paragraph_macro{$macro}); 21660 open_arg($macro, 0, $state); 21661 my $real_style_command = 0; 21662 if (defined($style_type{$macro}) and (($style_type{$macro} eq 'style') or ($style_type{$macro} eq 'accent'))) 21663 { 21664 push (@{$state->{'command_stack'}}, $macro); 21665 $real_style_command = 1; 21666 #print STDERR "# Stacked $macro (@{$state->{'command_stack'}})\n" if ($T2H_DEBUG); 21667 } 21668 # FIXME give line, and modify line? 21669 &$Texi2HTML::Config::begin_style_texi($macro, $state, $stack, $real_style_command) 21670 if (defined($Texi2HTML::Config::begin_style_texi) 21671 and !($state->{'keep_texi'} or $state->{'remove_texi'})); 21672 next; 21673 } 21674 21675 # special case if we are checking itemize line. In that case 21676 # we want to make sure that there is no @item on the @itemize 21677 # line, otherwise it will be added on the front of another @item, 21678 # leading to an infinite loop... 21679 21680 if ($state->{'check_item'} and ($macro =~ /^itemx?$/ or $macro eq 'headitem')) 21681 { 21682 echo_error("\@$macro on \@$state->{'check_item'} line", $line_nr); 21683 next; 21684 } 21685 21686 # if we're keeping texi unmodified we can do it now 21687 if ($state->{'keep_texi'}) 21688 { 21689 # We treat specially formats accepting {} on command line 21690 if ($macro eq 'multitable' or defined($Texi2HTML::Config::def_map{$macro}) or defined($sec2level{$macro})) 21691 { 21692 add_prev($text, $stack, "\@$macro" . $cline); 21693 $cline = ''; 21694 next; 21695 } 21696 # @ at the end of line may protect the end of line even when 21697 # keeping texi 21698 # FIXME: with deff handled differently, now this is unused. 21699 # in any case it should only be done in specific contexts 21700 # if ($macro eq "\n") 21701 # { 21702 # $state->{'end_of_line_protected'} = 1; 21703 # #print STDERR "PROTECTING END OF LINE\n"; 21704 # } 21705 21706 add_prev($text, $stack, "\@$macro"); 21707 if ($Texi2HTML::Config::texi_formats_map{$macro} and $Texi2HTML::Config::texi_formats_map{$macro} eq 'raw') 21708 { 21709 $state->{'raw'} = $macro; 21710 push (@$stack, {'style' => $macro, 'text' => ''}); 21711 } 21712 next; 21713 } 21714 21715 # If we are removing texi, the following macros are not removed 21716 # as is but modified. So they are collected first, as if we were 21717 # in normal text 21718 21719 # a raw macro beginning 21720 if ($Texi2HTML::Config::texi_formats_map{$macro} and $Texi2HTML::Config::texi_formats_map{$macro} eq 'raw') 21721 { 21722 if (!$Texi2HTML::Config::format_in_paragraph{$macro}) 21723 { # close paragraph before verbatim (and tex if !L2H) 21724 close_paragraph($text, $stack, $state, $line_nr); 21725 } 21726 $state->{'raw'} = $macro; 21727 push (@$stack, {'style' => $macro, 'text' => ''}); 21728 return if ($cline =~ /^\s*$/); 21729 next; 21730 } 21731 my $simple_macro = 1; 21732 # An accent macro 21733 if (exists($Texi2HTML::Config::accent_map{$macro})) 21734 { 21735 # the command itself is not in the command stack, since with 21736 # braces, it is already popped when do_simple is called 21737 #push (@{$state->{'command_stack'}}, $macro); 21738 $cline =~ s/^\s*// if ($macro =~ /^[a-zA-Z]/); 21739 if ($cline =~ s/^(\S)//o) 21740 { 21741 add_prev($text, $stack, do_simple($macro, $1, $state, [ $1 ], $line_nr)); 21742 } 21743 else 21744 { # The accent is at end of line 21745 add_prev($text, $stack, do_text($macro, $state)); 21746 } 21747 #pop @{$state->{'command_stack'}}; 21748 } 21749 # an @-command which should be like @command{}. We handle it... 21750 elsif ($::things_map_ref->{$macro}) 21751 { 21752 echo_warn ("$macro requires {}", $line_nr); 21753 add_prev($text, $stack, do_simple($macro, '', $state)); 21754 } 21755 # an @-command like @command 21756 elsif (defined($::simple_map_ref->{$macro})) 21757 { 21758 add_prev($text, $stack, do_simple($macro, '', $state)); 21759 } 21760 else 21761 { 21762 $simple_macro = 0; 21763 } 21764 if ($simple_macro) 21765 {# if the macro didn't triggered a paragraph start it might now 21766 begin_paragraph($stack, $state) if 21767 ($Texi2HTML::Config::no_paragraph_commands{$macro} and !no_paragraph($state,$cline)); 21768 next; 21769 } 21770 # the following macros are modified or ignored if we are 21771 # removing texi, and they are not handled like macros in normal text 21772 if ($state->{'remove_texi'}) 21773 { 21774 # handle specially some macros 21775 if ((index_command_prefix($macro) ne '') or 21776 ($macro eq 'itemize') or 21777 ($format_type{$macro} and ($format_type{$macro} eq 'table' or $format_type{$macro} eq 'quotation')) 21778 or ($macro eq 'multitable')) 21779 { 21780 return; 21781 } 21782 elsif ($macro eq 'enumerate') 21783 { 21784 my $spec; 21785 ($cline, $spec) = parse_enumerate ($cline); 21786 return if ($cline =~ /^\s*$/); 21787 next; 21788 } 21789 elsif (defined($Texi2HTML::Config::def_map{$macro})) 21790 { 21791 my ($command, $style, $category, $name, $type, $class, $arguments, $args_array); 21792 ($command, $style, $category, $name, $type, $class, $arguments, $args_array) = parse_def($macro, $cline, $line_nr); 21793 # FIXME -- --- ''... lead to simple text in texi2html 21794 # while they are kept as is in html coments by makeinfo 21795 $category = remove_texi($category) if (defined($category)); 21796 $name = remove_texi($name) if (defined($name)); 21797 $type = remove_texi($type) if (defined($type)); 21798 $class = remove_texi($class) if (defined($class)); 21799 $arguments = remove_texi($arguments) if (defined($arguments)); 21800 chomp($arguments); 21801 add_prev($text, $stack, &$Texi2HTML::Config::def_line_no_texi($category, $name, $type, $arguments)); 21802 return; 21803 } 21804 elsif (defined($sec2level{$macro})) 21805 { #FIXME there is certainly more intelligent stuff to do 21806 my $num; 21807 if ($state->{'region'}) 21808 { 21809 $state->{'head_num'}++; 21810 $num = "$state->{'region'}_$state->{'head_num'}"; 21811 } 21812 else 21813 { 21814# $global_head_num++; 21815 $num = $global_head_num; 21816 } 21817 my $heading_element = $headings{$num}; 21818 add_prev($text, $stack, &$Texi2HTML::Config::heading_no_texi($heading_element, $macro, $cline)); 21819 return; 21820 } 21821 21822 # ignore other macros 21823 next; 21824 } 21825 21826 # handle the other macros, we are in the context of normal text 21827 if (defined($sec2level{$macro})) 21828 { 21829 #dump_stack($text, $stack, $state); 21830 my $num; 21831 if ($state->{'region'}) 21832 { 21833 $state->{'head_num'}++; 21834 $num = "$state->{'region'}_$state->{'head_num'}"; 21835 #$num = $state->{'head_num'}; 21836 } 21837 else 21838 { 21839 $global_head_num++; 21840 $num = $global_head_num; 21841 } 21842 my $heading_element = $headings{$num}; 21843 add_prev($text, $stack, &$Texi2HTML::Config::element_label($heading_element->{'id'}, $heading_element, $macro, $cline)); 21844 add_prev($text, $stack, &$Texi2HTML::Config::heading($heading_element, $macro, $cline, substitute_line($cline), $state->{'preformatted'})); 21845 return; 21846 } 21847 21848 if (index_command_prefix($macro) ne '') 21849 { 21850 my $index_name = index_command_prefix($macro); 21851 $cline =~ s/^\s*//; 21852 my $entry_texi = $cline; 21853 chomp($entry_texi); 21854 $entry_texi =~ s/\s*$//; 21855 # FIXME multiple_pass? 21856 my $entry_text = substitute_line($entry_texi, prepare_state_multiple_pass($macro, $state)); 21857 my ($index_entry, $index_label) = do_index_entry_label($macro,$state,$line_nr); 21858 21859 if (defined($index_entry)) 21860 { 21861 echo_warn ("(bug?) Index out of sync `$index_entry->{'texi'}' ne `$entry_texi'", $line_nr) if ($index_entry->{'texi'} ne $entry_texi); 21862 } 21863 add_prev($text, $stack, &$Texi2HTML::Config::index_entry_command($macro, $index_name, $index_label, $entry_texi, $entry_text)); 21864 # it eats the end of line and therefore don't start 21865 # table entries nor close @center. These should be stopped 21866 # on the next line, though. 21867 return; 21868 } 21869 if ($macro eq 'insertcopying') 21870 { 21871 #close_paragraph($text, $stack, $state, $line_nr); 21872 add_prev($text, $stack, do_insertcopying($state)); 21873 # reopen a preformatted format if it was interrupted by the macro 21874 begin_paragraph ($stack, $state) if ($state->{'preformatted'}); 21875 return; 21876 } 21877 if ($macro =~ /^itemx?$/o or ($macro eq 'headitem')) 21878 { 21879 #print STDERR "ITEM: $cline"; 21880 #dump_stack($text, $stack, $state); 21881 abort_empty_preformatted($stack, $state); 21882 # FIXME let the user be able not to close the paragraph 21883 close_paragraph($text, $stack, $state, $line_nr); 21884 21885 if (defined($Texi2HTML::Config::tab_item_texi)) 21886 { 21887 my $resline = &$Texi2HTML::Config::tab_item_texi($macro, $state->{'command_stack'}, $stack, $state, $cline, $line_nr); 21888 $cline = $resline if (defined($resline)); 21889 } 21890 #print STDERR "ITEM after close para: $cline"; 21891 #dump_stack($text, $stack, $state); 21892 # these functions return the format if in the right context 21893 my $format; 21894 if ($format = add_item($text, $stack, $state, $line_nr)) 21895 { # handle lists 21896 push (@$stack, { 'format' => 'item', 'text' => '', 'format_ref' => $format }); 21897 begin_paragraph($stack, $state) unless (!$state->{'preformatted'} and no_line($cline)); 21898#print STDERR "BEGIN ITEM $format->{'format'}\n"; 21899#dump_stack($text, $stack, $state); 21900 } 21901 elsif ($format = add_term($text, $stack, $state, $line_nr)) 21902 {# handle table @item term and restart another one 21903 push (@$stack, { 'format' => 'term', 'text' => '', 'format_ref' => $format }); 21904 #$state->{'no_paragraph'}++; 21905 } 21906 elsif ($format = add_line($text, $stack, $state, $line_nr)) 21907 {# close table text and erstart a term 21908 push (@$stack, { 'format' => 'term', 'text' => '', 'format_ref' => $format }); 21909 #$state->{'no_paragraph'}++; 21910 } 21911 if ($format) 21912 { 21913 my ($line, $open_command) = &$Texi2HTML::Config::format_list_item_texi($format->{'format'}, $cline, $format->{'prepended'}, $format->{'command'}); 21914 $cline = $line if (defined($line)); 21915 if ($open_command) 21916 { 21917 open_arg($format->{'command'},0, $state); 21918 $format->{'command_opened'} = 1; 21919 } 21920 $format->{'item_cmd'} = $macro; 21921 next; 21922 } 21923 $format = add_row ($text, $stack, $state, $line_nr); # handle multitable 21924 if (!$format) 21925 { 21926 echo_warn ("\@$macro outside of table or list", $line_nr); 21927 } 21928 else 21929 { 21930 push @$stack, {'format' => 'row', 'text' => '', 'item_cmd' => $macro, 'format_ref' => $format }; 21931 push @$stack, {'format' => 'cell', 'text' => '', 'format_ref' => $format}; 21932 $format->{'cell'} = 1; 21933 if ($format->{'max_columns'}) 21934 { 21935 begin_paragraph_after_command($state,$stack,$macro,$cline); 21936 } 21937 else 21938 { 21939 echo_warn ("\@$macro in empty multitable", $line_nr); 21940 } 21941 } 21942 next; 21943 } 21944 21945 if ($macro eq 'tab') 21946 { 21947 abort_empty_preformatted($stack, $state); 21948 # FIXME let the user be able not to close the paragraph? 21949 close_paragraph($text, $stack, $state, $line_nr); 21950 21951 if (defined($Texi2HTML::Config::tab_item_texi)) 21952 { 21953 my $resline = &$Texi2HTML::Config::tab_item_texi($macro, $state->{'command_stack'}, $stack, $state, $cline, $line_nr); 21954 $cline = $resline if (defined($resline)); 21955 } 21956 my $format = add_cell ($text, $stack, $state); 21957 if (!$format) 21958 { 21959 echo_warn ("\@$macro outside of multitable", $line_nr); 21960 } 21961 else 21962 { 21963 push @$stack, {'format' => 'cell', 'text' => '', 'format_ref' => $format}; 21964 if (!$format->{'max_columns'}) 21965 { 21966 echo_warn ("\@$macro in empty multitable", $line_nr); 21967 } 21968 elsif ($format->{'cell'} > $format->{'max_columns'}) 21969 { 21970 echo_warn ("too much \@$macro (multitable has only $format->{'max_columns'} column(s))", $line_nr); 21971 } 21972 } 21973 begin_paragraph_after_command($state,$stack,$macro,$cline); 21974 next; 21975 } 21976 # Macro opening a format (table, list, deff, example...) 21977 if ($format_type{$macro} and ($format_type{$macro} ne 'fake')) 21978 { 21979 $cline = begin_format($text, $stack, $state, $macro, $cline, $line_nr); 21980 # we keep the end of line for @center, and for formats 21981 # that have cmd_line opened and need to see the end of line 21982 next if (($macro eq 'center') or 21983 (defined($Texi2HTML::Config::def_map{$macro})) 21984 or ($macro eq 'float') or ($format_type{$macro} eq 'quotation')); 21985 return if ($cline =~ /^\s*$/); 21986 next; 21987 } 21988 $cline = do_unknown (2, $macro, $cline, $text, $stack, $state, $line_nr); 21989 next; 21990 } 21991 elsif($cline =~ s/^([^{}@,]*)\@([^\s\}\{\@]*)//o) 21992 { # A macro with a character which shouldn't appear in macro name 21993 add_prev($text, $stack, do_text($1, $state)); 21994 $cline = do_unknown (2, $2, $cline, $text, $stack, $state, $line_nr); 21995 next; 21996 } 21997 # a brace, or an end of line and 'cmd_line' is on the top 21998 # of the stack 21999 elsif ($cline =~ s/^([^{},]*)([{}])//o or (@$stack and 22000 defined($stack->[-1]->{'style'}) and 22001 ($stack->[-1]->{'style'} eq 'cmd_line') and $cline =~ /^([^{},]*)$/o)) 22002 { 22003 my $leading_text = $1; 22004 my $brace = $2; 22005 add_prev($text, $stack, do_text($leading_text, $state)); 22006 if (defined($brace) and ($brace eq '{')) #'}' 22007 { 22008 add_prev($text, $stack, do_text('{',$state)); #} 22009 if ($state->{'math_style'}) 22010 { 22011 $state->{'math_brace'}++; 22012 } 22013 else 22014 { 22015 unless ($state->{'keep_texi'} or $state->{'remove_texi'}) 22016 { 22017 echo_error ("'{' without macro. Before: $cline", $line_nr); 22018 } 22019 } 22020 } 22021 elsif (defined($brace) and ($brace eq '}') and 22022 (!@$stack or (!defined($stack->[-1]->{'style'})) 22023 # with a non empty stack, but with 'cmd_line' as first item on 22024 # the stack there should not be a } 22025 or ($stack->[-1]->{'style'} eq 'cmd_line')) 22026 # braces are allowed in math 22027 or $state->{'math_brace'}) 22028 { 22029 if ($state->{'keep_texi'}) 22030 { 22031 add_prev($text, $stack, '}'); 22032 } 22033 elsif($state->{'math_style'} and $state->{'math_brace'}) 22034 { 22035 add_prev($text, $stack, do_text('}',$state)); 22036 $state->{'math_brace'}--; 22037 } 22038 else 22039 { 22040 echo_error("'}' without opening '{' before: $cline", $line_nr); 22041 #dump_stack($text, $stack, $state); 22042 } 22043 } 22044 else 22045 { # A @-command{ ...} is closed 22046 my ($result, $command) = close_style_command($text, $stack, $state, $line_nr, $cline); 22047 add_prev($text, $stack, $result); 22048 if ($command eq 'cmd_line') 22049 { 22050 if ($state->{'preformatted'}) 22051 { # inconditionally begin a preformatted section if needed 22052 begin_paragraph($stack, $state); 22053 } 22054 $state->{'no_paragraph'}--; 22055 return; 22056 } 22057 elsif ($Texi2HTML::Config::no_paragraph_commands{$command} 22058 and !$state->{'keep_texi'} and !no_paragraph($state,$cline)) 22059 { 22060 begin_paragraph($stack, $state); 22061 } 22062 } 22063 } 22064 elsif ($cline =~ s/^([^,]*)[,]//o) 22065 { 22066 add_prev($text, $stack, do_text($1, $state)); 22067 if (@$stack and defined($stack->[-1]->{'style'}) 22068 and (ref($::style_map_ref->{$stack->[-1]->{'style'}}) eq 'HASH')) 22069 { 22070 my $macro = $stack->[-1]->{'style'}; 22071 my $style_args = $::style_map_ref->{$macro}->{'args'}; 22072 if (defined($style_args->[$stack->[-1]->{'arg_nr'} + 1])) 22073 { 22074 push (@{$stack->[-1]->{'args'}}, $stack->[-1]->{'text'}); 22075 $stack->[-1]->{'fulltext'} .= $stack->[-1]->{'text'} . do_text(',', $state); 22076 $stack->[-1]->{'text'} = ''; 22077 close_arg ($macro, $stack->[-1]->{'arg_nr'}, $state); 22078 $stack->[-1]->{'arg_nr'}++; 22079 open_arg ($macro, $stack->[-1]->{'arg_nr'}, $state); 22080 next; 22081 } 22082 } 22083 add_prev($text, $stack, do_text(',', $state)); 22084 } 22085 else 22086 { # no macro nor '}', but normal text 22087 add_prev($text, $stack, do_text($cline, $state)); 22088 # @center/line term is closed at the end of line. When a 22089 # @-command which 22090 # keeps the texi as is happens on the @center line, the @center 22091 # is closed at the end of line appearing after the @-command 22092 # closing (for example @ref, @footnote). 22093 last if ($state->{'keep_texi'}); 22094 #print STDERR "END LINE:$cline!!!\n"; 22095 #dump_stack($text, $stack, $state); 22096 my $maybe_format_to_close = 1; 22097 my $in_table; 22098 while ($maybe_format_to_close) 22099 { 22100 $maybe_format_to_close = 0; 22101 my $top_format = top_stack($stack, 1); 22102 # the stack cannot easily be used, because there may be 22103 # opened commands in paragraphs if the center is in a 22104 # style command, like 22105 # @b{ 22106 # bold 22107 # 22108 # @center centered bold 22109 # 22110 # } 22111 # 22112 # Therefore $state->{'paragraph_style'}->[-1] is used. 22113 # 22114 # The close_stack until 'center' is needed because 22115 # of constructs like 22116 # 22117 # @center something @table 22118 # 22119 # In that case what would be removed from the stack after 22120 # paragraph closing wold not be the @center. Such construct 22121 # is certainly incorrect, though. 22122 # 22123 # when 'closing_center' is true we don't retry to close 22124 # the @center line. 22125 if ($state->{'paragraph_style'}->[-1] eq 'center' 22126 and !$state->{'closing_center'} and !$state->{'keep_texi'}) 22127 { 22128 $state->{'closing_center'} = 1; 22129 close_paragraph($text, $stack, $state, $line_nr); 22130 close_stack($text, $stack, $state, $line_nr, 'center'); 22131 delete $state->{'closing_center'}; 22132 my $center = pop @$stack; 22133 add_prev($text, $stack, &$Texi2HTML::Config::paragraph_style_command('center',$center->{'text'})); 22134 my $top_paragraph_style = pop @{$state->{'paragraph_style'}}; 22135 22136 # center is at the bottom of the comand_stack because it 22137 # may be nested in many way 22138 my $bottom_command_stack = shift @{$state->{'command_stack'}}; 22139 print STDERR "Bug: closing center, top_paragraph_style: $top_paragraph_style, bottom_command_stack: $bottom_command_stack.\n" 22140 if ($bottom_command_stack ne 'center' or $top_paragraph_style ne 'center'); 22141 $maybe_format_to_close = 1; 22142 next; 22143 } 22144 22145 # @item line is closed by end of line. In general there should 22146 # not be a paragraph in a term. However it may currently 22147 # happen in construct like 22148 # 22149 # @table @asis 22150 # @item @cindex index entry 22151 # some text still in term, and in paragraph 22152 # Not in term anymore 22153 # .... 22154 # 22155 if (defined($top_format->{'format'}) and $top_format->{'format'} eq 'term') 22156 { 22157 close_paragraph($text, $stack, $state, $line_nr) 22158 if ($state->{'paragraph_context'}); 22159 $in_table = add_term($text, $stack, $state, $line_nr); 22160 if ($in_table) 22161 { 22162 $maybe_format_to_close = 1; 22163 next; 22164 } 22165 } 22166 } 22167 if ($in_table) 22168 { 22169 push (@$stack, { 'format' => 'line', 'text' => '', 'only_inter_commands' => 1, 'format_ref' => $in_table }); 22170 begin_paragraph($stack, $state) if ($state->{'preformatted'}); 22171 } 22172 last; 22173 } 22174 } 22175 return 1; 22176} # end scan_line 22177 22178sub open_arg($$$) 22179{ 22180 my $macro = shift; 22181 my $arg_nr = shift; 22182 my $state = shift; 22183 if (ref($::style_map_ref->{$macro}) eq 'HASH') 22184 { 22185 my $arg = $::style_map_ref->{$macro}->{'args'}->[$arg_nr]; 22186 if ($arg eq 'keep') 22187 { 22188 $state->{'keep_nr'}++; 22189 $state->{'keep_texi'} = 1; 22190 } 22191 elsif (!$state->{'keep_texi'}) 22192 { 22193 if ($arg eq 'code') 22194 { 22195 $state->{'code_style'}++; 22196 } 22197 elsif ($arg eq 'math') 22198 { 22199 $state->{'math_style'}++; 22200 if ($state->{'math_style'} == 1) 22201 { 22202 $state->{'math_brace'} = 0; 22203 # FIXME quick hack to define @\ in @math 22204 $::simple_map_ref->{'\\'} = $Texi2HTML::Config::simple_map_math{'\\'}; 22205 $::simple_map_pre_ref->{'\\'} = $Texi2HTML::Config::simple_map_pre_math{'\\'}; 22206 $::simple_map_texi_ref->{'\\'} = $Texi2HTML::Config::simple_map_texi_math{'\\'}; 22207 } 22208 } 22209 } 22210 } 22211 elsif ($code_style_map{$macro} and !$state->{'keep_texi'}) 22212 { 22213 $state->{'code_style'}++; 22214 } 22215} 22216 22217sub close_arg($$$) 22218{ 22219 my $macro = shift; 22220 my $arg_nr = shift; 22221 my $state = shift; 22222 if (ref($::style_map_ref->{$macro}) eq 'HASH') 22223 { 22224 my $arg = $::style_map_ref->{$macro}->{'args'}->[$arg_nr]; 22225 if ($arg eq 'keep') 22226 { 22227 $state->{'keep_nr'}--; 22228 $state->{'keep_texi'} = 0 if ($state->{'keep_nr'} == 0); 22229 } 22230 elsif (!$state->{'keep_texi'}) 22231 { 22232 if ($arg eq 'code') 22233 { 22234 $state->{'code_style'}--; 22235 } 22236 elsif ($arg eq 'math') 22237 { 22238 $state->{'math_style'}--; 22239 if ($state->{'math_style'} == 0) 22240 { 22241 delete $::simple_map_ref->{'\\'}; 22242 delete $::simple_map_pre_ref->{'\\'}; 22243 delete $::simple_map_texi_ref->{'\\'}; 22244 } 22245 } 22246 } 22247#print STDERR "c $arg_nr $macro $arg $state->{'code_style'}\n"; 22248 } 22249 elsif ($code_style_map{$macro} and !$state->{'keep_texi'}) 22250 { 22251 $state->{'code_style'}--; 22252 } 22253} 22254 22255# add a special style on the top of the stack. This is used for commands 22256# that extend until the end of the line. Also add an entry in the @-command 22257# hashes for this fakes style. 22258sub open_cmd_line($$$$) 22259{ 22260 my $stack = shift; 22261 my $state = shift; 22262 my $args = shift; 22263 my $function = shift; 22264 push @$stack, {'style' => 'cmd_line', 'text' => '', 'arg_nr' => 0}; 22265 foreach my $hash (\%Texi2HTML::Config::style_map, \%Texi2HTML::Config::style_map_pre, \%Texi2HTML::Config::style_map_texi, \%Texi2HTML::Config::simple_format_style_map_texi) 22266 { 22267 $hash->{'cmd_line'}->{'args'} = $args; 22268 $hash->{'cmd_line'}->{'function'} = $function; 22269 } 22270 $state->{'no_paragraph'}++; 22271# $state->{'cmd_line'} = 1; 22272 open_arg ('cmd_line', 0, $state); 22273} 22274 22275# finish @item line in @*table 22276sub add_term($$$$) 22277{ 22278 my $text = shift; 22279 my $stack = shift; 22280 my $state = shift; 22281 my $line_nr = shift; 22282 22283 my $top_format = top_stack($stack); 22284 # FIXME: if there is a style on the stack, the closing of the term is 22285 # postpopned until the next end of line without opened @-command. 22286 # It is demonstrated in formatting/tables.texi. 22287 # to avoid that we should search deeper in the stack and close until 22288 # the term (what was done before) 22289 return unless (defined($top_format->{'format'}) and $top_format->{'format'} eq 'term'); 22290 22291 #print STDERR "ADD_TERM\n"; 22292 22293 my $term = pop @$stack; 22294 my $format = $stack->[-1]; 22295 $format->{'paragraph_number'} = 0; 22296 my $formatted_command; 22297 my $leading_spaces; 22298 my $trailing_spaces; 22299 my $term_formatted; 22300 chomp ($term->{'text'}); 22301 if (exists($::style_map_ref->{$format->{'command'}}) and ($style_type{$format->{'command'}} eq 'style')) 22302# and 22303# !exists($Texi2HTML::Config::special_list_commands{$format->{'format'}}->{$format->{'command'}}) and ($style_type{$format->{'command'}} eq 'style')) 22304 { 22305 $leading_spaces = ''; 22306 $trailing_spaces = ''; 22307 $term_formatted = $term->{'text'}; 22308 $term_formatted =~ s/^(\s*)//o; 22309 $leading_spaces = $1 if (defined($1)); 22310 $term_formatted =~ s/(\s*)$//o; 22311 $trailing_spaces = $1 if (defined($1)); 22312 unless ($format->{'command_opened'}) 22313 { 22314 open_arg($format->{'command'}, 0, $state); 22315 } 22316 $term_formatted = do_simple($format->{'command'}, $term_formatted, $state, [$term_formatted]); 22317# $term->{'text'} = $leading_spaces. $term->{'text'} .$trailing_spaces; 22318 } 22319 elsif (exists($::things_map_ref->{$format->{'command'}})) 22320 { 22321 $formatted_command = do_simple($format->{'command'}, '', $state); 22322 $format->{'formatted_command'} = $formatted_command; 22323 } 22324 my $index_label; 22325 if ($format->{'format'} =~ /^(f|v)/o) 22326 { 22327 my $index_entry; 22328 ($index_entry, $index_label) = do_index_entry_label($format->{'format'}, $state,$line_nr); 22329 print STDERR "Bug: no index entry for $term->{'text'}" unless defined($index_label); 22330 } 22331 add_prev($text, $stack, &$Texi2HTML::Config::table_item($term->{'text'}, $index_label,$format->{'format'},$format->{'command'}, $formatted_command,$state->{'command_stack'}, $term_formatted, $leading_spaces, $trailing_spaces, $format->{'item_cmd'})); 22332 #$state->{'no_paragraph'}--; 22333 return $format; 22334} 22335 22336sub add_row($$$$) 22337{ 22338 my $text = shift; 22339 my $stack = shift; 22340 my $state = shift; 22341 my $line_nr = shift; 22342 22343 my $top_format = top_stack($stack); 22344 # @center a @item 22345 # will lead to row not being closed since a close paragraph doesn't 22346 # end the center. 22347 return unless (defined($top_format->{'format'}) and $top_format->{'format'} eq 'cell'); 22348 my $cell = $top_format; 22349 my $format = $stack->[-3]; 22350 print STDERR "Bug under row cell row not a multitable\n" if (!defined($format->{'format'}) or $format->{'format'} ne 'multitable'); 22351 # print STDERR "ADD_ROW\n"; 22352 # dump_stack($text, $stack, $state); 22353 22354 my $empty_first; 22355 if ($format->{'first'} and $format->{'cell'} == 1 and $stack->[-1]->{'text'} =~ /^\s*$/) 22356 { 22357 $empty_first = 1; 22358 } 22359 if ($format->{'cell'} > $format->{'max_columns'} or $empty_first) 22360 { 22361 my $cell = pop @$stack; 22362 print STDERR "Bug: not a cell ($cell->{'format'}) in multitable\n" if ($cell->{'format'} ne 'cell'); 22363 } 22364 else 22365 { 22366 add_cell($text, $stack, $state); 22367 } 22368 my $row = pop @$stack; 22369 print STDERR "Bug: not a row ($row->{'format'}) in multitable\n" if ($row->{'format'} ne 'row'); 22370 if ($format->{'max_columns'} and !$empty_first) 22371 { 22372 # FIXME have the cell count in row and not in table. table could have 22373 # the whole structure, but cell count doesn't make much sense 22374 add_prev($text, $stack, &$Texi2HTML::Config::row($row->{'text'}, $row->{'item_cmd'}, $format->{'columnfractions'}, $format->{'prototype_row'}, $format->{'prototype_lengths'}, $format->{'max_columns'}, $cell->{'only_inter_commands'}, $format->{'first'})); 22375 } 22376 22377 $format->{'first'} = 0 if ($format->{'first'}); 22378 22379 return $format; 22380} 22381 22382# FIXME remove and merge, too much double checks and code 22383sub add_cell($$$$) 22384{ 22385 my $text = shift; 22386 my $stack = shift; 22387 my $state = shift; 22388 my $line_nr = shift; 22389 my $top_format = top_stack($stack); 22390 22391 return unless (defined($top_format) and $top_format->{'format'} eq 'cell'); 22392 22393 my $cell = pop @$stack; 22394 my $row = top_stack($stack); 22395 print STDERR "Bug: top_stack of cell not a row\n" if (!defined($row->{'format'}) or ($row->{'format'} ne 'row')); 22396 my $format = $stack->[-2]; 22397 print STDERR "Bug under cell row not a multitable\n" if (!defined($format->{'format'}) or $format->{'format'} ne 'multitable'); 22398 if ($format->{'cell'} <= $format->{'max_columns'}) 22399 { 22400 add_prev($text, $stack, &$Texi2HTML::Config::cell($cell->{'text'}, $row->{'item_cmd'}, $format->{'columnfractions'}, $format->{'prototype_row'}, $format->{'prototype_lengths'}, $format->{'max_columns'}, $cell->{'only_inter_commands'}, $format->{'first'})); 22401 } 22402 $format->{'cell'}++; 22403 return $format; 22404} 22405 22406sub add_line($$$$) 22407{ 22408 my $text = shift; 22409 my $stack = shift; 22410 my $state = shift; 22411 my $line_nr = shift; 22412 my $top_stack = top_stack($stack); 22413 22414 # if there is something like 22415 # @center centered @item new item 22416 # the item isn't opened since it is in @center, and center isn't closed 22417 # by an @item appearing here (unlike a paragraph). 22418 # the error message is '@item outside of table or list'. 22419 # texi2dvi also has issue, but makeinfo is happy, however it 22420 # produces bad nesting. 22421 return unless(defined($top_stack->{'format'}) and $top_stack->{'format'} eq 'line'); 22422 #print STDERR "ADD_LINE\n"; 22423 #dump_stack($text, $stack, $state); 22424 22425 my $line = pop @$stack; 22426 my $format = $stack->[-1]; 22427 $format->{'paragraph_number'} = 0; 22428 if ($format->{'first'}) 22429 { 22430 $format->{'first'} = 0; 22431 # we must have <dd> or <dt> following <dl> thus we do a 22432 # &$Texi2HTML::Config::table_line here too, although it could have 22433 # been a normal paragraph. 22434 add_prev($text, $stack, &$Texi2HTML::Config::table_line($line->{'text'}, $line->{'only_inter_commands'}, 1)) if ($line->{'text'} =~ /\S/o); 22435 } 22436 else 22437 { 22438 add_prev($text, $stack, &$Texi2HTML::Config::table_line($line->{'text'}, $line->{'only_inter_commands'}, 0)); 22439 } 22440 return $format; 22441} 22442 22443# finish @enumerate or @itemize @item 22444sub add_item($$$$) 22445{ 22446 my $text = shift; 22447 my $stack = shift; 22448 my $state = shift; 22449 my $line_nr = shift; 22450 22451 my $top_stack = top_stack($stack); 22452 22453 return unless (defined($top_stack->{'format'}) and $top_stack->{'format'} eq 'item'); 22454 #print STDERR "ADD_ITEM: \n"; 22455 #dump_stack($text, $stack, $state); 22456 # as in pre the end of line are kept, we must explicitely abort empty 22457 # preformatted, close_stack doesn't do that. 22458 my $item = pop @$stack; 22459 my $format = $stack->[-1]; 22460 22461 $format->{'paragraph_number'} = 0; 22462 if ($format->{'format'} eq 'enumerate') 22463 { 22464 $format->{'number'} = ''; 22465 my $spec = $format->{'spec'}; 22466 $format->{'item_nr'}++; 22467 if ($spec =~ /^[0-9]$/) 22468 { 22469 $format->{'number'} = $spec + $format->{'item_nr'} - 1; 22470 } 22471 else 22472 { 22473 my $base_letter = ord('a'); 22474 $base_letter = ord('A') if (ucfirst($spec) eq $spec); 22475 22476 my @letter_ords = decompose(ord($spec) - $base_letter + $format->{'item_nr'} - 1, 26); 22477 foreach my $ord (@letter_ords) 22478 {# FIXME we go directly to 'ba' after 'z', and not 'aa' 22479 #because 'ba' is 1,0 and 'aa' is 0,0. 22480 $format->{'number'} = chr($base_letter + $ord) . $format->{'number'}; 22481 } 22482 } 22483 } 22484 22485 #dump_stack ($text, $stack, $state); 22486 # the element following ol or ul must be li. Thus even though there 22487 # is no @item we put a normal item. 22488 # don't do an item if it is the first and it is empty 22489 if (!$format->{'first'} or ($item->{'text'} =~ /\S/o)) 22490 { 22491 my $formatted_command; 22492 if (defined($format->{'command'}) and exists($::things_map_ref->{$format->{'command'}})) 22493 { 22494 $formatted_command = do_simple($format->{'command'}, '', $state); 22495 $format->{'formatted_command'} = $formatted_command; 22496 } 22497 #chomp($item->{'text'}); 22498 add_prev($text, $stack, &$Texi2HTML::Config::list_item($item->{'text'},$format->{'format'},$format->{'command'}, $formatted_command, $format->{'item_nr'}, $format->{'spec'}, $format->{'number'}, $format->{'prepended'}, $format->{'prepended_formatted'}, $item->{'only_inter_commands'}, $format->{'first'})); 22499 } 22500 if ($format->{'first'}) 22501 { 22502 $format->{'first'} = 0; 22503 } 22504 22505 return $format; 22506} 22507 22508# format ``simple'' macros, that is macros without arg or style macros 22509sub do_simple($$$;$$$$) 22510{ 22511 my $macro = shift; 22512 my $text = shift; 22513 my $state = shift; 22514 my $args = shift; 22515 my $line_nr = shift; 22516 my $no_open = shift; 22517 my $no_close = shift; 22518 22519 my $arg_nr = 0; 22520 $arg_nr = @$args - 1 if (defined($args)); 22521 22522#print STDERR "DO_SIMPLE $macro ".format_line_number($line_nr)." $args $arg_nr (@$args)\n" if (defined($args)); 22523 if (defined($::simple_map_ref->{$macro})) 22524 { 22525 # \n may in certain circumstances, protect end of lines 22526 # FIXME this cannot happen anymore, because the lines are concatenated 22527 # in pass_structure 22528 # if ($macro eq "\n") 22529 # { 22530 # $state->{'end_of_line_protected'} = 1; 22531 # #print STDERR "PROTECTING END OF LINE\n"; 22532 # } 22533 if ($state->{'keep_texi'}) 22534 { 22535 return "\@$macro"; 22536 } 22537 elsif ($state->{'remove_texi'}) 22538 { 22539#print STDERR "DO_SIMPLE remove_texi $macro\n"; 22540 return $::simple_map_texi_ref->{$macro}; 22541 } 22542 else 22543 { 22544 return &$Texi2HTML::Config::simple_command($macro, $state->{'preformatted'}, $line_nr, $state); 22545 } 22546 } 22547 if (defined($::things_map_ref->{$macro})) 22548 { 22549 my $result; 22550 if ($state->{'keep_texi'}) 22551 { 22552 return "\@$macro" . '{}'.$text; 22553 } 22554 elsif ($state->{'remove_texi'}) 22555 { 22556 return $::texi_map_ref->{$macro}.$text; 22557#print STDERR "DO_SIMPLE remove_texi texi_map $macro\n"; 22558 } 22559 else 22560 { 22561 return &$Texi2HTML::Config::thing_command($macro, $text, $state->{'preformatted'}, $line_nr, $state); 22562 } 22563 } 22564 elsif (defined($::style_map_ref->{$macro})) 22565 { 22566 if ($state->{'keep_texi'}) 22567 { 22568 return "\@$macro" . '{' . $text . '}'; 22569 } 22570 else 22571 { 22572 my $style; 22573 my $result; 22574 if ($state->{'remove_texi'}) 22575 { 22576#print STDERR "REMOVE $macro, $style_map_texi_ref->{$macro}, fun $style_map_texi_ref->{$macro}->{'function'} remove cmd " . \&Texi2HTML::Config::t2h_remove_command . " ascii acc " . \&t2h_default_ascii_accent; 22577 $style = $::style_map_texi_ref->{$macro}; 22578 } 22579 elsif ($state->{'preformatted'}) 22580 { 22581 $style = $::style_map_pre_ref->{$macro}; 22582 } 22583 else 22584 { 22585 $style = $::style_map_ref->{$macro}; 22586 } 22587 if (defined($style)) 22588 { # known style 22589 $result = &$Texi2HTML::Config::style($style, $macro, $text, $args, $no_close, $no_open, $line_nr, $state, $state->{'command_stack'}); 22590 } 22591 if (!$no_close) 22592 { 22593 close_arg($macro,$arg_nr, $state); 22594 } 22595 return $result; 22596 } 22597 } 22598 elsif ($macro =~ /^special_(\w+)_(\d+)$/o) 22599 { 22600 my $style = $1; 22601 my $count = $2; 22602 print STDERR "Bug? text in \@$macro not empty.\n" if ($text ne ''); 22603 if ($state->{'keep_texi'}) 22604 {# text should be empty 22605 return "\@$macro" . '{' . $text . '}'; 22606 } 22607 if (defined($Texi2HTML::Config::command_handler{$style}) and 22608 defined($Texi2HTML::Config::command_handler{$style}->{'expand'})) 22609 { 22610 my $struct_count = 1+ $special_commands{$style}->{'max'} - $special_commands{$style}->{'count'}; 22611 if (($count != $struct_count) and $T2H_DEBUG) 22612 { 22613 print STDERR "count $count in \@special $style and structure $struct_count differ\n"; 22614 } 22615 $special_commands{$style}->{'count'}--; 22616 } 22617 my $result = $Texi2HTML::Config::command_handler{$style}->{'expand'} 22618 ($style,$count,$state,$text); 22619 $result = '' if (!defined($result)); 22620 return $result; 22621 } 22622 # Unknown macro 22623 my $result = ''; 22624 my ($done, $result_text, $message) = &$Texi2HTML::Config::unknown_style($macro, $text,$state); 22625 if ($done) 22626 { 22627 echo_warn($message, $line_nr) if (defined($message)); 22628 if (defined($result_text)) 22629 { 22630 $result = $result_text; 22631 } 22632 } 22633 else 22634 { 22635 unless ($no_open) 22636 { # we warn only if no_open is true, i.e. it is the first time we 22637 # close the macro for a multiline macro 22638 echo_warn ("Unknown command with braces `\@$macro'", $line_nr); 22639 $result = do_text("\@$macro") . "{"; 22640 } 22641 $result .= $text; 22642 $result .= '}' unless ($no_close); 22643 } 22644 return $result; 22645} 22646 22647sub do_unknown($$$$$$$) 22648{ 22649 my $pass = shift; 22650 my $macro = shift; 22651 my $line = shift; 22652 my $text = shift; 22653 my $stack = shift; 22654 my $state = shift; 22655 my $line_nr = shift; 22656 #print STDERR "do_unknown[$pass]($macro) ::: $line"; 22657 22658 my ($result_line, $result, $result_text, $message) = &$Texi2HTML::Config::unknown($macro, $line, $pass, $stack,$state); 22659 if ($result) 22660 { 22661 add_prev ($text, $stack, $result_text) if (defined($result_text)); 22662 echo_warn($message, $line_nr) if (defined($message)); 22663 # if $state->{'preformatted'}, assume that the preformatted is 22664 # already opened. Otherwise we may end up opening one each time 22665 # there is an unknown command. 22666 begin_paragraph_after_command($state, $stack, $macro, $result_line) 22667 if (!$state->{'preformatted'}); 22668 return $result_line; 22669 } 22670 elsif ($pass == 2) 22671 { 22672 echo_warn ("Unknown command `\@$macro' (left as is)", $line_nr); 22673 add_prev ($text, $stack, do_text("\@$macro")); 22674 return $line; 22675 } 22676 elsif ($pass == 1) 22677 { 22678 add_prev ($text, $stack, "\@$macro"); 22679 return $line; 22680 } 22681 elsif ($pass == 0) 22682 { 22683 add_prev ($text, $stack, "\@$macro") unless($state->{'ignored'}); 22684 return $line; 22685 } 22686} 22687 22688# used only during @macro processing 22689sub add_text($@) 22690{ 22691 my $string = shift; 22692 22693 return if (!defined($string)); 22694 foreach my $scalar_ref (@_) 22695 { 22696 next unless defined($scalar_ref); 22697 if (!defined($$scalar_ref)) 22698 { 22699 $$scalar_ref = $string; 22700 } 22701 else 22702 { 22703 $$scalar_ref .= $string; 22704 } 22705 return; 22706 } 22707} 22708 22709sub add_prev ($$$) 22710{ 22711 my $text = shift; 22712 my $stack = shift; 22713 my $string = shift; 22714 22715 unless (defined($text) and ref($text) eq "SCALAR") 22716 { 22717 die "text not a SCALAR ref: " . ref($text) . ""; 22718 } 22719 #if (!defined($stack) or (ref($stack) ne "ARRAY")) 22720 #{ 22721 # $string = $stack; 22722 # $stack = []; 22723 #} 22724 22725 return if (!defined($string)); 22726 if (@$stack) 22727 { 22728 $stack->[-1]->{'text'} .= $string; 22729 return; 22730 } 22731 22732 if (!defined($$text)) 22733 { 22734 $$text = $string; 22735 } 22736 else 22737 { 22738 $$text .= $string; 22739 } 22740} 22741 22742sub close_stack_texi_structure($$$$) 22743{ 22744 my $text = shift; 22745 my $stack = shift; 22746 my $state = shift; 22747 my $line_nr = shift; 22748 22749 return undef unless (@$stack or $state->{'raw'} or $state->{'macro'} or $state->{'macro_name'} or $state->{'ignored'}); 22750 22751 #print STDERR "close_stack_texi_structure\n"; 22752 #dump_stack ($text, $stack, $state); 22753 my $stack_level = $#$stack + 1; 22754 my $string = ''; 22755 22756 if ($state->{'ignored'}) 22757 { 22758 $string .= "\@end $state->{'ignored'} "; 22759 echo_warn ("closing $state->{'ignored'}", $line_nr); 22760 } 22761 if ($state->{'texi'}) 22762 { 22763 if ($state->{'macro'}) 22764 { 22765 $string .= "\@end macro "; 22766 echo_warn ("closing macro", $line_nr); 22767 } 22768 elsif ($state->{'macro_name'}) 22769 { 22770 $string .= ('}' x $state->{'macro_depth'}) . " "; 22771 echo_warn ("closing $state->{'macro_name'} ($state->{'macro_depth'} braces missing)", $line_nr); 22772 } 22773 elsif ($state->{'verb'}) 22774 { 22775 echo_warn ("closing \@verb", $line_nr); 22776 $string .= $state->{'verb'} . '}'; 22777 } 22778 elsif ($state->{'raw'}) 22779 { 22780 echo_warn ("closing \@$state->{'raw'} raw format", $line_nr); 22781 $string .= "\@end $state->{'raw'}"; 22782 } 22783 if ($string ne '') 22784 { 22785 #print STDERR "close_stack scan_texi ($string)\n"; 22786 scan_texi ($string, $text, $stack, $state, $line_nr); 22787 $string = ''; 22788 } 22789 } 22790 elsif ($state->{'verb'}) 22791 { 22792 $string .= $state->{'verb'}; 22793 } 22794 22795 while ($stack_level--) 22796 { 22797 my $stack_text = $stack->[$stack_level]->{'text'}; 22798 $stack_text = '' if (!defined($stack_text)); 22799 if ($stack->[$stack_level]->{'format'}) 22800 { 22801 my $format = $stack->[$stack_level]->{'format'}; 22802 if ($format eq 'index_item') 22803 { 22804 enter_table_index_entry($text, $stack, $state, $line_nr); 22805 next; 22806 } 22807 elsif (!defined($format_type{$format}) or ($format_type{$format} ne 'fake')) 22808 { 22809 $stack_text = "\@$format\n" . $stack_text; 22810 } 22811 } 22812 elsif (defined($stack->[$stack_level]->{'style'})) 22813 { 22814 if ($state->{'structure'}) 22815 { 22816 $stack_text = close_structure_command($stack->[$stack_level], 22817 $state,1,$line_nr) 22818 } 22819 else 22820 { 22821 my $style = $stack->[$stack_level]->{'style'}; 22822 if ($style ne '') 22823 { 22824 $stack_text = "\@$style\{" . $stack_text; 22825 } 22826 else 22827 {# this is a lone opened brace. We readd it there. 22828 $stack_text = "\{" . $stack_text; 22829 } 22830 } 22831 } 22832 pop @$stack; 22833 add_prev($text, $stack, $stack_text); 22834 } 22835 $stack = [ ]; 22836 22837 $state->{'close_stack'} = 1; 22838 if ($string ne '') 22839 { 22840 if ($state->{'texi'}) 22841 { 22842 #print STDERR "scan_texi in close_stack ($string)\n"; 22843 scan_texi($string, $text, $stack, $state, $line_nr); 22844 } 22845 elsif ($state->{'structure'}) 22846 { 22847 #print STDERR "scan_structure in close_stack ($string)\n"; 22848 scan_structure($string, $text, $stack, $state, $line_nr); 22849 } 22850 } 22851 delete $state->{'close_stack'}; 22852} 22853 22854sub open_region($$) 22855{ 22856 my $command = shift; 22857 my $state = shift; 22858 if (!exists($state->{'region_lines'})) 22859 { 22860 $state->{'region_lines'}->{'format'} = $command; 22861 $state->{'region_lines'}->{'number'} = 1; 22862 $state->{'region_lines'}->{'kept_place'} = $state->{'place'}; 22863 $state->{'place'} = $no_element_associated_place; 22864 $state->{'region'} = $command; 22865 $state->{'multiple_pass'}++; 22866 $state->{'region_pass'} = 1; 22867 } 22868 else 22869 { 22870 $state->{'region_lines'}->{'number'}++; 22871 } 22872} 22873 22874# close region like @insertcopying, titlepage... 22875# restore $state and delete the structure 22876sub close_region($) 22877{ 22878 my $state = shift; 22879 $state->{'place'} = $state->{'region_lines'}->{'kept_place'}; 22880 $state->{'multiple_pass'}--; 22881 delete $state->{'region_lines'}->{'number'}; 22882 delete $state->{'region_lines'}->{'format'}; 22883 delete $state->{'region_lines'}->{'kept_place'}; 22884 delete $state->{'region_lines'}; 22885 delete $state->{'region'}; 22886 delete $state->{'region_pass'}; 22887} 22888 22889# close the stack, closing @-commands and formats left open. 22890# if a $format is given if $format is encountered the closing stops 22891sub close_stack($$$$;$) 22892{ 22893 my $text = shift; 22894 my $stack = shift; 22895 my $state = shift; 22896 my $line_nr = shift; 22897 my $format = shift; 22898 22899 #print STDERR "sub_close_stack\n"; 22900 return unless (@$stack); 22901 22902 my $stack_level = $#$stack + 1; 22903 22904 #debugging 22905 #my $print_format = 'NO FORMAT'; 22906 #$print_format = $format if ($format); 22907 #print STDERR "Close_stack: format $print_format\n"; 22908 22909 while ($stack_level--) 22910 { 22911 if ($stack->[$stack_level]->{'format'}) 22912 { 22913 my $stack_format = $stack->[$stack_level]->{'format'}; 22914 last if (defined($format) and $stack_format eq $format); 22915 # We silently close paragraphs, preformatted sections and fake formats 22916 if ($stack_format eq 'paragraph') 22917 { 22918 my $paragraph = pop @$stack; 22919 add_prev ($text, $stack, do_paragraph($paragraph->{'text'}, $state, $stack)); 22920 } 22921 elsif ($stack_format eq 'preformatted') 22922 { 22923 my $paragraph = pop @$stack; 22924 add_prev ($text, $stack, do_preformatted($paragraph->{'text'}, $state, $stack)); 22925 } 22926 else 22927 { 22928 if ($fake_format{$stack_format}) 22929 { 22930 warn "# Closing a fake format `$stack_format'\n" if ($T2H_VERBOSE); 22931 } 22932 elsif ($stack_format ne 'center') 22933 { # we don't warn for center 22934 echo_error ("closing `$stack_format'", $line_nr); 22935 #dump_stack ($text, $stack, $state); 22936 } 22937 if ($state->{'keep_texi'}) 22938 { 22939 add_prev($text, $stack, "\@end $stack_format"); 22940 } 22941 elsif (!$state->{'remove_texi'}) 22942 { 22943 end_format($text, $stack, $state, $stack_format, $line_nr) 22944 unless ($format_type{$stack_format} eq 'fake'); 22945 } 22946 } 22947 } 22948 else 22949 { 22950 my $style = $stack->[$stack_level]->{'style'}; 22951 ########################## debug 22952 if (!defined($style)) 22953 { 22954 print STDERR "Bug: style not defined, on stack\n"; 22955 dump_stack ($text, $stack, $state); # bug 22956 } 22957 ########################## end debug 22958 echo_warn ("closing \@-command $style", $line_nr) if ($style); 22959 my ($result, $command) = close_style_command($text, $stack, $state, $line_nr, ''); 22960 add_prev($text, $stack, $result) if (defined($result)); 22961 } 22962 } 22963} 22964 22965# given a stack and a list of formats, return true if the stack contains 22966# these formats, first on top 22967sub stack_order($@) 22968{ 22969 my $stack = shift; 22970 my $stack_level = $#$stack + 1; 22971 while (@_) 22972 { 22973 my $format = shift; 22974 while ($stack_level--) 22975 { 22976 if ($stack->[$stack_level]->{'format'}) 22977 { 22978 if ($stack->[$stack_level]->{'format'} eq $format) 22979 { 22980 $format = undef; 22981 last; 22982 } 22983 else 22984 { 22985 return 0; 22986 } 22987 } 22988 } 22989 return 0 if ($format); 22990 } 22991 return 1; 22992} 22993 22994sub top_format($) 22995{ 22996 my $stack = shift; 22997 my $stack_level = $#$stack + 1; 22998 while ($stack_level--) 22999 { 23000 if ($stack->[$stack_level]->{'format'} and !$fake_format{$stack->[$stack_level]->{'format'}}) 23001 { 23002 return $stack->[$stack_level]; 23003 } 23004 } 23005 return undef; 23006} 23007 23008sub close_paragraph($$$;$$) 23009{ 23010 my $text = shift; 23011 my $stack = shift; 23012 my $state = shift; 23013 my $line_nr = shift; 23014 my $no_preformatted_closing = shift; 23015 #print STDERR "CLOSE_PARAGRAPH\n"; 23016 #dump_stack($text, $stack, $state); 23017 23018 # close until the first format, 23019 # duplicate stack of styles not closed 23020 my $new_stack; 23021 my $stack_level = $#$stack + 1; 23022 23023 while ($stack_level--) 23024 { 23025 last if ($stack->[$stack_level]->{'format'}); 23026 my $style = $stack->[$stack_level]->{'style'}; 23027 # FIXME images, footnotes, xrefs, anchors? 23028 # seems that it is not possible, as 23029 # close_paragraph shouldn't be called with keep_texi 23030 # and when the arguments are expanded, there is a 23031 # substitute_line or similar with a new stack. 23032 23033 # the !exists($style_type{$style}) condition catches the unknown 23034 # @-commands: by default they are considered as style commands 23035 if (!exists($style_type{$style}) or $style_type{$style} eq 'style') 23036 { 23037 unshift @$new_stack, { 'style' => $style, 'text' => '', 'no_open' => 1, 'arg_nr' => 0 }; 23038 } 23039 elsif (($style_type{$style} eq 'simple_style') or ($style_type{$style} eq 'accent')) 23040 { 23041 } 23042 else 23043 { 23044 print STDERR "BUG: special $style while closing paragraph\n"; 23045 } 23046 $state->{'no_close'} = 1; 23047 my ($result, $command) = close_style_command($text, $stack, $state, $line_nr, ''); 23048 add_prev($text, $stack, $result) if (defined($result)); 23049 delete $state->{'no_close'}; 23050 } 23051 23052 if (!$state->{'paragraph_context'} and !$state->{'preformatted'} and defined($new_stack) and scalar(@$new_stack)) 23053 { # in that case the $new_stack isn't recorded in $state->{'paragraph_macros'} 23054 # and therefore, it is lost 23055 print STDERR "BUG: closing paragraph, but not in paragraph/preformatted, and new_stack not empty ".format_line_number($line_nr)."\n"; 23056 dump_stack($text, $stack, $state); 23057 } 23058 my $top_stack = top_stack($stack); 23059 if ($top_stack and !defined($top_stack->{'format'})) 23060 { #debug 23061 print STDERR "Bug: no format on top stack\n"; 23062 dump_stack($text, $stack, $state); 23063 } 23064 if ($top_stack and ($top_stack->{'format'} eq 'paragraph')) 23065 { 23066 my $paragraph = pop @$stack; 23067 add_prev($text, $stack, do_paragraph($paragraph->{'text'}, $state, $stack)); 23068 $state->{'paragraph_macros'} = $new_stack; 23069 return 1; 23070 } 23071 elsif ($top_stack and ($top_stack->{'format'} eq 'preformatted') and !$no_preformatted_closing) 23072 { 23073 my $paragraph = pop @$stack; 23074 add_prev($text, $stack, do_preformatted($paragraph->{'text'}, $state, $stack)); 23075 $state->{'paragraph_macros'} = $new_stack; 23076 return 1; 23077 } 23078 return; 23079} 23080 23081sub abort_empty_preformatted($$) 23082{ 23083 my $stack = shift; 23084 my $state = shift; 23085 if (@$stack and $stack->[-1]->{'format'} 23086 and ($stack->[-1]->{'format'} eq 'preformatted') 23087 and ($stack->[-1]->{'text'} !~ /\S/)) 23088 { 23089 pop @$stack; 23090 } 23091} 23092 23093# for debugging 23094sub dump_stack($$$) 23095{ 23096 my $text = shift; 23097 my $stack = shift; 23098 my $state = shift; 23099 23100 if (defined($$text)) 23101 { 23102 print STDERR "text: $$text\n"; 23103 } 23104 else 23105 { 23106 print STDERR "text: UNDEF\n"; 23107 } 23108 my $in_remove = 0; 23109 my $in_simple_format = 0; 23110 my $in_keep = 0; 23111 $in_keep = 1 if ($state->{'keep_texi'}); 23112 if (!$in_keep) 23113 { 23114 $in_simple_format = 1 if ($state->{'simple_format'}); 23115 $in_remove = 1 if ($state->{'remove_texi'} and !$in_simple_format); 23116 } 23117 print STDERR "state(k${in_keep}s${in_simple_format}r${in_remove}): "; 23118 foreach my $key (keys(%$state)) 23119 { 23120 my $value = 'UNDEF'; 23121 $value = $state->{$key} if (defined($state->{$key})); 23122 print STDERR "$key: $value " if (!ref($value)); 23123 } 23124 print STDERR "\n"; 23125 my $stack_level = $#$stack + 1; 23126 while ($stack_level--) 23127 { 23128 print STDERR " $stack_level-> "; 23129 foreach my $key (keys(%{$stack->[$stack_level]})) 23130 { 23131 my $value = 'UNDEF'; 23132 $value = $stack->[$stack_level]->{$key} if 23133 (defined($stack->[$stack_level]->{$key})); 23134 print STDERR "$key: $value "; 23135 } 23136 print STDERR "\n"; 23137 } 23138 if (defined($state->{'command_stack'})) 23139 { 23140 print STDERR "command_stack: "; 23141 foreach my $style (@{$state->{'command_stack'}}) 23142 { 23143 print STDERR "($style) "; 23144 } 23145 print STDERR "\n"; 23146 } 23147 if (defined($state->{'region_lines'})) 23148 { 23149 print STDERR "region_lines($state->{'region_lines'}->{'number'}): $state->{'region_lines'}->{'format'}\n"; 23150 } 23151 if (defined($state->{'paragraph_macros'})) 23152 { 23153 print STDERR "paragraph_macros: "; 23154 foreach my $style (@{$state->{'paragraph_macros'}}) 23155 { 23156 print STDERR "($style->{'style'})"; 23157 } 23158 print STDERR "\n"; 23159 } 23160 if (defined($state->{'preformatted_stack'})) 23161 { 23162 print STDERR "preformatted_stack: "; 23163 foreach my $preformatted_style (@{$state->{'preformatted_stack'}}) 23164 { 23165 if ($preformatted_style eq '') 23166 { 23167 print STDERR "."; 23168 next; 23169 } 23170 my $pre_style = ''; 23171 $pre_style = $preformatted_style->{'pre_style'} if (exists $preformatted_style->{'pre_style'}); 23172 my $class = ''; 23173 $class = $preformatted_style->{'class'} if (exists $preformatted_style->{'class'}); 23174 my $style = ''; 23175 $style = $preformatted_style->{'style'} if (exists $preformatted_style->{'style'}); 23176 print STDERR "($pre_style, $class,$style)"; 23177 } 23178 print STDERR "\n"; 23179 } 23180 if (defined($state->{'text_macro_stack'}) and @{$state->{'text_macro_stack'}}) 23181 { 23182 print STDERR "text_macro_stack: (@{$state->{'text_macro_stack'}})\n"; 23183 } 23184} 23185 23186# for debugging 23187sub print_elements($) 23188{ 23189 my $elements = shift; 23190 foreach my $elem(@$elements) 23191 { 23192 if ($elem->{'node'}) 23193 { 23194 print STDERR "node-> $elem "; 23195 } 23196 else 23197 { 23198 print STDERR "chap=> $elem "; 23199 } 23200 foreach my $key (keys(%$elem)) 23201 { 23202 my $value = "UNDEF"; 23203 $value = $elem->{$key} if (defined($elem->{$key})); 23204 print STDERR "$key: $value "; 23205 } 23206 print STDERR "\n"; 23207 } 23208} 23209 23210my @states_stack = (); 23211 23212sub push_state($) 23213{ 23214 my $new_state = shift; 23215 push @states_stack, $new_state; 23216 $Texi2HTML::THISDOC{'state'} = $new_state; 23217} 23218 23219sub pop_state() 23220{ 23221 pop @states_stack; 23222 if (@states_stack) 23223 { 23224 $Texi2HTML::THISDOC{'state'} = $states_stack[-1]; 23225 } 23226 else 23227 { 23228 $Texi2HTML::THISDOC{'state'} = undef; 23229 } 23230} 23231 23232sub substitute_line($;$$) 23233{ 23234 my $line = shift; 23235 my $state = shift; 23236 my $line_nr = shift; 23237 $state = {} if (!defined($state)); 23238 $state->{'no_paragraph'} = 1; 23239 # this is usefull when called from &$I, and also for image files 23240 return simple_format($state, $line_nr, $line) if ($state->{'simple_format'}); 23241 return substitute_text($state, $line_nr, $line); 23242} 23243 23244sub substitute_text($$@) 23245{ 23246 my $state = shift; 23247 my $line_nr = shift; 23248 my @stack = (); 23249 my $text = ''; 23250 my $result = ''; 23251 if ($state->{'structure'}) 23252 { 23253 initialise_state_structure($state); 23254 } 23255 elsif ($state->{'texi'}) 23256 { # only in arg_expansion 23257 initialise_state_texi($state); 23258 } 23259 else 23260 { 23261#print STDERR "FILL_STATE substitute_text ($state->{'preformatted'}): @_\n"; 23262 fill_state($state); 23263 } 23264 $state->{'spool'} = []; 23265 #print STDERR "SUBST_TEXT begin\n"; 23266 push_state($state); 23267 23268 while (@_ or @{$state->{'spool'}} or $state->{'in_deff_line'}) 23269 { 23270 my $line; 23271 if (@{$state->{'spool'}}) 23272 { 23273 $line = shift @{$state->{'spool'}}; 23274 } 23275 else 23276 { 23277 $line = shift @_; 23278 } 23279 if ($state->{'in_deff_line'}) 23280 { 23281 if (defined($line)) 23282 { 23283 $line = $state->{'in_deff_line'} . $line; 23284 } 23285 else 23286 { 23287 $line = $state->{'in_deff_line'}; 23288 } 23289 delete $state->{'in_deff_line'}; 23290 } 23291 else 23292 { 23293 next unless (defined($line)); 23294 } 23295 #{ my $p_line = $line; chomp($p_line); print STDERR "SUBST_TEXT $p_line\n"; } 23296 if ($state->{'structure'}) 23297 { 23298 scan_structure ($line, \$text, \@stack, $state); 23299 } 23300 elsif ($state->{'texi'}) 23301 { 23302 scan_texi ($line, \$text, \@stack, $state); 23303 } 23304 else 23305 { 23306 scan_line($line, \$text, \@stack, $state, $line_nr); 23307 } 23308 next if (@stack); 23309 $result .= $text; 23310 $text = ''; 23311 } 23312 # FIXME could we have the line number ? 23313 # close stack in substitute_text 23314 if ($state->{'texi'} or $state->{'structure'}) 23315 { 23316 close_stack_texi_structure(\$text, \@stack, $state, undef); 23317 } 23318 else 23319 { 23320 close_stack(\$text, \@stack, $state, $line_nr); 23321 } 23322 #print STDERR "SUBST_TEXT end\n"; 23323 pop_state(); 23324 return $result . $text; 23325} 23326 23327sub print_lines($;$) 23328{ 23329 my ($fh, $lines) = @_; 23330 $lines = $Texi2HTML::THIS_SECTION unless $lines; 23331 my @cnt; 23332 my $cnt; 23333 for my $line (@$lines) 23334 { 23335 print $fh $line; 23336 if (defined($Texi2HTML::Config::WORDS_IN_PAGE) and ($Texi2HTML::Config::SPLIT eq 'node')) 23337 { 23338 @cnt = split(/\W*\s+\W*/, $line); 23339 $cnt += scalar(@cnt); 23340 } 23341 } 23342 return $cnt; 23343} 23344 23345sub do_index_entry_label($$$) 23346{ 23347 my $command = shift; 23348 my $state = shift; 23349 my $line_nr = shift; 23350 # index entries are not entered in special regions 23351 return (undef,'') if ($state->{'region'}); 23352# return '' if ($state->{'multiple_pass'} or $state->{'outside_document'}); 23353 my $entry = shift @index_labels; 23354 if (!defined($entry)) 23355 { 23356 echo_warn ("Not enough index entries !", $line_nr); 23357 return (undef,''); 23358 } 23359 if ($command ne $entry->{'command'}) 23360 { 23361 # happens with bad texinfo with a line like 23362 # @deffn func aaaa args @defvr c--ategory d--efvr_name 23363 echo_warn ("Waiting for index cmd \@$entry->{'command'}, got \@$command", $line_nr); 23364 } 23365 23366 print STDERR "(index $command) [$entry->{'entry'}] $entry->{'id'}\n" 23367 if ($T2H_DEBUG & $DEBUG_INDEX); 23368 return ($entry, &$Texi2HTML::Config::index_entry_label ($entry->{'id'}, $state->{'preformatted'}, substitute_line($entry->{'entry'}, prepare_state_multiple_pass("${command}_index", $state)), 23369 $index_prefix_to_name{$entry->{'prefix'}}, 23370 $command, $entry->{'texi'}, substitute_line($entry->{'texi'}, prepare_state_multiple_pass("${command}_index", $state)))); 23371} 23372 23373# decompose a decimal number on a given base. The algorithm looks like 23374# the division with growing powers (division suivant les puissances 23375# croissantes) ? 23376sub decompose($$) 23377{ 23378 my $number = shift; 23379 my $base = shift; 23380 my @result = (); 23381 23382 return (0) if ($number == 0); 23383 my $power = 1; 23384 my $remaining = $number; 23385 23386 while ($remaining) 23387 { 23388 my $factor = $remaining % ($base ** $power); 23389 $remaining -= $factor; 23390 push (@result, $factor / ($base ** ($power - 1))); 23391 $power++; 23392 } 23393 return @result; 23394} 23395 23396# process a css file 23397sub process_css_file ($$) 23398{ 23399 my $fh =shift; 23400 my $file = shift; 23401 my $in_rules = 0; 23402 my $in_comment = 0; 23403 my $in_import = 0; 23404 my $in_string = 0; 23405 my $rules = []; 23406 my $imports = []; 23407 while (my $line = <$fh>) 23408 { 23409 #print STDERR "Line: $line"; 23410 if ($in_rules) 23411 { 23412 push @$rules, $line; 23413 next; 23414 } 23415 my $text = ''; 23416 while (1) 23417 { 23418 #sleep 1; 23419 #print STDERR "${text}!in_comment $in_comment in_rules $in_rules in_import $in_import in_string $in_string: $line"; 23420 if ($in_comment) 23421 { 23422 if ($line =~ s/^(.*?\*\/)//) 23423 { 23424 $text .= $1; 23425 $in_comment = 0; 23426 } 23427 else 23428 { 23429 push @$imports, $text . $line; 23430 last; 23431 } 23432 } 23433 elsif (!$in_string and $line =~ s/^\///) 23434 { # what do '\' do here ? 23435 if ($line =~ s/^\*//) 23436 { 23437 $text .= '/*'; 23438 $in_comment = 1; 23439 } 23440 else 23441 { 23442 push (@$imports, $text. "\n") if ($text ne ''); 23443 push (@$rules, '/' . $line); 23444 $in_rules = 1; 23445 last; 23446 } 23447 } 23448 elsif (!$in_string and $in_import and $line =~ s/^([\"\'])//) 23449 { # strings outside of import start rules 23450 $text .= "$1"; 23451 $in_string = quotemeta("$1"); 23452 } 23453 elsif ($in_string and $line =~ s/^(\\$in_string)//) 23454 { 23455 $text .= $1; 23456 } 23457 elsif ($in_string and $line =~ s/^($in_string)//) 23458 { 23459 $text .= $1; 23460 $in_string = 0; 23461 } 23462 elsif ((! $in_string and !$in_import) and ($line =~ s/^([\\]?\@import)$// or $line =~ s/^([\\]?\@import\s+)//)) 23463 { 23464 $text .= $1; 23465 $in_import = 1; 23466 } 23467 elsif (!$in_string and $in_import and $line =~ s/^\;//) 23468 { 23469 $text .= ';'; 23470 $in_import = 0; 23471 } 23472 elsif (($in_import or $in_string) and $line =~ s/^(.)//) 23473 { 23474 $text .= $1; 23475 } 23476 elsif (!$in_import and $line =~ s/^([^\s])//) 23477 { 23478 push (@$imports, $text. "\n") if ($text ne ''); 23479 push (@$rules, $1 . $line); 23480 $in_rules = 1; 23481 last; 23482 } 23483 elsif ($line =~ s/^(\s)//) 23484 { 23485 $text .= $1; 23486 } 23487 elsif ($line eq '') 23488 { 23489 push (@$imports, $text); 23490 last; 23491 } 23492 } 23493 } 23494 warn "$WARN string not closed in css file $file\n" if ($in_string); 23495 warn "$WARN comment not closed in css file $file\n" if ($in_comment); 23496 warn "$WARN \@import not finished in css file $file\n" if ($in_import and !$in_comment and !$in_string); 23497 return ($imports, $rules); 23498} 23499 23500sub collect_all_css_files() 23501{ 23502 my @css_import_lines; 23503 my @css_rule_lines; 23504 23505 # process css files 23506 foreach my $file (@Texi2HTML::Config::CSS_FILES) 23507 { 23508 my $css_file_fh; 23509 my $css_file; 23510 if ($file eq '-') 23511 { 23512 $css_file_fh = \*STDIN; 23513 $css_file = '-'; 23514 } 23515 else 23516 { 23517 $css_file = locate_include_file ($file); 23518 unless (defined($css_file)) 23519 { 23520 warn "css file $file not found\n"; 23521 next; 23522 } 23523 unless (open (CSSFILE, "$css_file")) 23524 { 23525 warn "Cannot open ${css_file}: $!"; 23526 next; 23527 } 23528 $css_file_fh = \*CSSFILE; 23529 } 23530 my ($import_lines, $rules_lines); 23531 ($import_lines, $rules_lines) = process_css_file ($css_file_fh, $css_file); 23532 push @css_import_lines, @$import_lines; 23533 push @css_rule_lines, @$rules_lines; 23534 } 23535 23536 23537 if ($T2H_DEBUG & $DEBUG_USER) 23538 { 23539 if (@css_import_lines) 23540 { 23541 print STDERR "# css import lines\n"; 23542 foreach my $line (@css_import_lines) 23543 { 23544 print STDERR "$line"; 23545 } 23546 } 23547 if (@css_rule_lines) 23548 { 23549 print STDERR "# css rule lines\n"; 23550 foreach my $line (@css_rule_lines) 23551 { 23552 print STDERR "$line"; 23553 } 23554 } 23555 } 23556 return (\@css_import_lines, \@css_rule_lines); 23557} 23558 23559sub init_with_file_name($) 23560{ 23561 my $base_file = shift; 23562 set_docu_names($base_file, $Texi2HTML::THISDOC{'input_file_number'}); 23563 23564 foreach my $handler(@Texi2HTML::Config::command_handler_init) 23565 { 23566 &$handler; 23567 } 23568} 23569 23570 23571####################################################################### 23572# 23573# Main processing, process all the files given on the command line 23574# 23575####################################################################### 23576 23577die "$0: missing file argument.\n$T2H_FAILURE_TEXT" unless (scalar(@ARGV) >= 1); 23578 23579my $file_number = 0; 23580# main processing 23581while(@ARGV) 23582{ 23583 my $input_file_name = shift(@ARGV); 23584 23585 %Texi2HTML::THISDOC = (); 23586 $Texi2HTML::THIS_ELEMENT = undef; 23587 23588 foreach my $global_key (keys(%Texi2HTML::GLOBAL)) 23589 { 23590 $Texi2HTML::THISDOC{$global_key} = $Texi2HTML::GLOBAL{$global_key}; 23591 } 23592 23593 set_date() if ($Texi2HTML::GLOBAL{'current_lang'}); 23594 23595 $Texi2HTML::THISDOC{'input_file_name'} = $input_file_name; 23596 $Texi2HTML::THISDOC{'input_file_number'} = $file_number; 23597 23598 my $input_file_base = $input_file_name; 23599 $input_file_base =~ s/\.te?x(i|info)?$//; 23600 23601 @{$Texi2HTML::TOC_LINES} = (); # table of contents 23602 @{$Texi2HTML::OVERVIEW} = (); # short table of contents 23603 # this could be done here, but perl warns that 23604 # `"Texi2HTML::TITLEPAGE" used only once' and it is reset in 23605 # &$Texi2HTML::Config::titlepage anyway 23606 # $Texi2HTML::TITLEPAGE = undef; 23607 @{$Texi2HTML::THIS_SECTION} = (); 23608 23609 # the reference to these hashes may be used before this point (for example 23610 # see makeinfo.init), so they should be kept as is and the values undef 23611 # but the key should not be deleted because the ref is on the key. 23612 foreach my $hash (\%Texi2HTML::HREF, \%Texi2HTML::NAME, \%Texi2HTML::NODE, 23613 \%Texi2HTML::NO_TEXI, \%Texi2HTML::SIMPLE_TEXT) 23614 { 23615 foreach my $key (keys(%$hash)) 23616 { 23617 $hash->{$key} = undef; 23618 } 23619 } 23620 23621 $docu_dir = undef; # directory of the document 23622 $docu_name = undef; # basename of the document 23623 $docu_rdir = undef; # directory for the output 23624 $docu_toc = undef; # document's table of contents 23625 $docu_stoc = undef; # document's short toc 23626 $docu_foot = undef; # document's footnotes 23627 $docu_about = undef; # about this document 23628 $docu_top = undef; # document top 23629 $docu_doc = undef; # document (or document top of split) 23630 $docu_frame = undef; # main frame file 23631 $docu_toc_frame = undef; # toc frame file 23632 $path_to_working_dir = undef; # relative path leading to the working 23633 # directory from the document directory 23634 $docu_doc_file = undef; 23635 $docu_toc_file = undef; 23636 $docu_stoc_file = undef; 23637 $docu_foot_file = undef; 23638 $docu_about_file = undef; 23639 $docu_top_file = undef; 23640 $docu_frame_file = undef; 23641 $docu_toc_frame_file = undef; 23642 23643 if (!$Texi2HTML::Config::USE_SETFILENAME) 23644 { 23645 init_with_file_name ($input_file_base); 23646 } 23647 23648 # FIXME when to do that? 23649 ($Texi2HTML::THISDOC{'css_import_lines'}, $Texi2HTML::THISDOC{'css_lines'}) 23650 = collect_all_css_files(); 23651 23652 %region_lines = ( 23653 'titlepage' => [ ], 23654 'documentdescription' => [ ], 23655 'copying' => [ ], 23656 ); 23657 23658 texinfo_initialization(0); 23659 23660 print STDERR "# reading from $input_file_name\n" if $T2H_VERBOSE; 23661 23662 @fhs = (); # hold the file handles to read 23663 23664 $macros = undef; # macros. reference on a hash 23665 %info_enclose = (); # macros defined with definfoenclose 23666 @floats = (); # floats list 23667 %floats = (); # floats by style 23668 %nodes = (); # nodes hash. The key is the texi node name 23669 %cross_reference_nodes = (); # normalized node names arrays 23670 23671 23672 my ($texi_lines, $first_texi_lines, $lines_numbers) 23673 = pass_texi($input_file_name); 23674 23675 if ($Texi2HTML::Config::USE_SETFILENAME and !defined($docu_name)) 23676 { 23677 init_with_file_name ($input_file_base); 23678 } 23679 23680 Texi2HTML::Config::t2h_default_set_out_encoding(); 23681 dump_texi($texi_lines, 'texi', $lines_numbers) if ($T2H_DEBUG & $DEBUG_TEXI); 23682 if (defined($Texi2HTML::Config::MACRO_EXPAND)) 23683 { 23684 my @texi_lines = (@$first_texi_lines, @$texi_lines); 23685 dump_texi(\@texi_lines, '', undef, $Texi2HTML::Config::MACRO_EXPAND); 23686 } 23687 23688 %content_element = 23689 ( 23690 'contents' => { 'id' => $Texi2HTML::Config::misc_pages_targets{'Contents'}, 23691 'target' => $Texi2HTML::Config::misc_pages_targets{'Contents'}, 23692 'contents' => 1, 'texi' => '_contents' }, 23693 'shortcontents' => { 23694 'id' => $Texi2HTML::Config::misc_pages_targets{'Overview'}, 23695 'target' => $Texi2HTML::Config::misc_pages_targets{'Overview'}, 23696 'shortcontents' => 1, 'texi' => '_shortcontents' }, 23697 ); 23698 23699 %sec2level = %reference_sec2level; 23700 23701 $element_before_anything = 23702 { 23703 'before_anything' => 1, 23704 'place' => [], 23705 'texi' => 'VIRTUAL ELEMENT BEFORE ANYTHING', 23706 }; 23707 23708 23709 $footnote_element = 23710 { 23711 'id' => $Texi2HTML::Config::misc_pages_targets{'Footnotes'}, 23712 'target' => $Texi2HTML::Config::misc_pages_targets{'Footnotes'}, 23713 'file' => $docu_foot, 23714 'footnote' => 1, 23715 'place' => [], 23716 }; 23717 23718 %region_initial_state = ( 23719 'titlepage' => { }, 23720 'documentdescription' => { }, 23721 'copying' => { }, 23722 ); 23723 23724# to determine if a command has to be processed the following are interesting 23725# (and can be faked): 23726# 'region': the name of the special region we are processing 23727# 'region_pass': the number of passes in that specific region (both outside 23728# of the main document, and in the main document) 23729# 'multiple_pass': the number of pass in the formatting of the region in the 23730# main document 23731# 'outside_document': set to 1 if outside of the main document formatting 23732 foreach my $key (keys(%region_initial_state)) 23733 { 23734 $region_initial_state{$key}->{'multiple_pass'} = -1; 23735 $region_initial_state{$key}->{'region_pass'} = 0; 23736 $region_initial_state{$key}->{'num_head'} = 0; 23737 $region_initial_state{$key}->{'foot_num'} = 0; 23738 $region_initial_state{$key}->{'relative_foot_num'} = 0; 23739 $region_initial_state{$key}->{'region'} = $key; 23740 } 23741 23742 texinfo_initialization(1); 23743 23744 23745 $no_element_associated_place = []; 23746 23747 $document_idx_num = 0; 23748 $document_sec_num = 0; 23749 $document_head_num = 0; 23750 $document_anchor_num = 0; 23751 23752 $novalidate = $Texi2HTML::Config::NOVALIDATE; # @novalidate appeared 23753 23754 @nodes_list = (); # nodes in document reading order 23755 # each member is a reference on a hash 23756 @sections_list = (); # sections in reading order 23757 # each member is a reference on a hash 23758 @all_elements = (); # sectionning elements (nodes and sections) 23759 # in reading order. Each member is a reference 23760 # on a hash which also appears in %nodes, 23761 # @sections_list @nodes_list, @elements_list 23762 @elements_list = (); # all the resulting elements in document order 23763 %sections = (); # sections hash. The key is the section number 23764 %headings = (); # headings hash. The key is the heading number 23765 $section_top = undef; # @top section 23766 $element_top = undef; # Top element 23767 $node_top = undef; # Top node 23768 $node_first = undef; # First node 23769 $element_index = undef; # element with first index 23770 $element_chapter_index = undef; # chapter with first index 23771 $element_first = undef; # first element 23772 $element_last = undef; # last element 23773 %special_commands = (); # hash for the commands specially handled 23774 # by the user 23775 23776 @index_labels = (); # array corresponding with @?index commands 23777 # constructed during pass_texi, used to 23778 # put labels in pass_text 23779 $index_entries = undef; 23780 23781 # original kdb styles used if @kbdinputstyle distinct 23782 $kept_kdb_style = $::style_map_ref->{'kbd'}; 23783 $kept_kdb_pre_style = $::style_map_pre_ref->{'kbd'}; 23784 23785 my ($doc_lines, $doc_numbers) = pass_structure($texi_lines, $lines_numbers); 23786 if ($T2H_DEBUG & $DEBUG_TEXI) 23787 { 23788 dump_texi($doc_lines, 'first', $doc_numbers); 23789 if (defined($Texi2HTML::Config::MACRO_EXPAND and $Texi2HTML::Config::DUMP_TEXI)) 23790 { 23791 unshift (@$doc_lines, @$first_texi_lines); 23792 push (@$doc_lines, "\@bye\n"); 23793 dump_texi($doc_lines, '', undef, $Texi2HTML::Config::MACRO_EXPAND . ".first"); 23794 } 23795 } 23796 next if ($Texi2HTML::Config::DUMP_TEXI or defined($Texi2HTML::Config::MACRO_EXPAND)); 23797 23798 foreach my $style (keys(%special_commands)) 23799 { 23800 $special_commands{$style}->{'max'} = $special_commands{$style}->{'count'}; 23801 } 23802 23803 %files = (); # keys are files. This is used to avoid reusing an already 23804 # used file name 23805 %empty_indices = (); # value is true for an index name key if the index 23806 # is empty 23807 %printed_indices = (); # value is true for an index name not empty and 23808 # printed 23809 %indices = (); # hash of indices names containing 23810 #[ $pages, $entries ] (page indices and 23811 # raw index entries) 23812 prepare_indices(); 23813 rearrange_elements(); 23814 do_names(); 23815 23816#Texi2HTML::LaTeX2HTML::latex2html(); 23817 foreach my $handler(@Texi2HTML::Config::command_handler_process) 23818 { 23819 &$handler; 23820 } 23821 23822# maybe do that later to have more elements ready? 23823 &$Texi2HTML::Config::toc_body(\@elements_list); 23824 23825 &$Texi2HTML::Config::css_lines($Texi2HTML::THISDOC{'css_import_lines'}, 23826 $Texi2HTML::THISDOC{'css_lines'}); 23827 23828 23829 $global_head_num = 0; # heading index. it is global for the main doc, 23830 # and taken from the state if in multiple_pass. 23831 $global_foot_num = 0; 23832 $global_relative_foot_num = 0; 23833 @foot_lines = (); # footnotes 23834 $copying_comment = ''; # comment constructed from text between 23835 # @copying and @end copying with licence 23836 %acronyms_like = (); # acronyms or similar commands associated texts 23837 # the key are the commands, the values are 23838 # hash references associating shorthands to 23839 # texts. 23840 @states_stack = (); 23841 23842 pass_text($doc_lines, $doc_numbers); 23843 print STDERR "BUG: " . scalar(@index_labels) . " index entries pending\n" 23844 if (scalar(@index_labels)); 23845 foreach my $special (keys(%special_commands)) 23846 { 23847 my $count = $special_commands{$special}->{'count'}; 23848 if (($count != 0) and $T2H_VERBOSE) 23849 { 23850 echo_warn ("$count special \@$special were not processed.\n"); 23851 } 23852 } 23853 if ($Texi2HTML::Config::IDX_SUMMARY) 23854 { 23855 foreach my $entry (keys(%index_names)) 23856 { 23857 do_index_summary_file($entry, $docu_name) unless ($empty_indices{$entry}); 23858 } 23859 } 23860 do_node_files() if ($Texi2HTML::Config::NODE_FILES); 23861#l2h_FinishFromHtml() if ($Texi2HTML::Config::L2H); 23862#l2h_Finish() if($Texi2HTML::Config::L2H); 23863#Texi2HTML::LaTeX2HTML::finish(); 23864 foreach my $handler(@Texi2HTML::Config::command_handler_finish) 23865 { 23866 &$handler; 23867 } 23868 &$Texi2HTML::Config::finish_out(); 23869 23870 print STDERR "# File ($file_number) $input_file_name processed\n" if $T2H_VERBOSE; 23871 $file_number++; 23872} 23873print STDERR "# that's all folks\n" if $T2H_VERBOSE; 23874exit(0); 23875 23876 23877############################################################################## 23878 23879# These next few lines are legal in both Perl and nroff. 23880 23881.00 ; # finish .ig 23882 23883'di \" finish diversion--previous line must be blank 23884.nr nl 0-1 \" fake up transition to first page again 23885.nr % 0 \" start at page 1 23886'; __END__ ############# From here on it's a standard manual page ############ 23887 .so ${datarootdir}/man/man1/texi2html.1 23888