#! /usr/bin/perl
# texi2any: Texinfo converter.
#
# Copyright 2010-2023 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License,
# or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# Original author: Patrice Dumas
# Parts (also from Patrice Dumas) come from texi2html.pl or texi2html.init.
# for POSIX::setlocale and File::Spec
require 5.00405;
use strict;
# Through rules in Makefile.am, directory paths set through configure are
# substituted directly in strings in the code, for example
# my $datadir = '/usr/share';
# We always use these strings as byte string, therefore we explicitly
# set no utf8 to be sure that strings in code will never be considered as
# character strings by Perl.
no utf8;
# to decode command line arguments
use Encode qw(decode encode find_encoding);
# for file names portability
use File::Spec;
# to determine the path separator and null file
use Config;
# for dirname and fileparse
use File::Basename;
#use Cwd;
use Getopt::Long qw(GetOptions);
# for carp
#use Carp;
# for dclone
use Storable;
Getopt::Long::Configure("gnu_getopt");
my ($real_command_name, $command_directory, $command_suffix);
# This big BEGIN block deals with finding modules and
# some dependencies that we ship
# * in source or
# * installed or
# * installed relative to the script
BEGIN
{
# emulate -w
$^W = 1;
($real_command_name, $command_directory, $command_suffix)
= fileparse($0, '.pl');
my $updir = File::Spec->updir();
# These are substituted by the Makefile to create "texi2any".
my $datadir = '/usr/share';
my $package = 'texinfo';
my $xsdir = '/usr/lib/texinfo';
if ($datadir eq '@' .'datadir@'
or defined($ENV{'TEXINFO_DEV_SOURCE'})
and $ENV{'TEXINFO_DEV_SOURCE'} ne '0')
{
# Use uninstalled modules
# To find Texinfo::ModulePath
if (defined($ENV{'top_builddir'})) {
unshift @INC, File::Spec->catdir($ENV{'top_builddir'}, 'tp');
} else {
unshift @INC, File::Spec->catdir($command_directory);
}
require Texinfo::ModulePath;
Texinfo::ModulePath::init(undef, undef, undef, 'updirs' => 1);
} else {
# Look for modules in their installed locations.
my $lib_dir = File::Spec->catdir($datadir, $package);
# look for package data in the installed location.
# actually the same as $pkgdatadir in main program below, but use
# another name to avoid confusion.
my $modules_pkgdatadir = $lib_dir;
# try to make package relocatable, will only work if
# standard relative paths are used
if (! -f File::Spec->catfile($lib_dir, 'Texinfo', 'Parser.pm')
and -f File::Spec->catfile($command_directory, $updir, 'share',
$package, 'Texinfo', 'Parser.pm')) {
$lib_dir = File::Spec->catdir($command_directory, $updir,
'share', $package);
$modules_pkgdatadir = File::Spec->catdir($command_directory, $updir,
'share', $package);
$xsdir = File::Spec->catdir($command_directory, $updir,
'lib', $package);
}
unshift @INC, $lib_dir;
require Texinfo::ModulePath;
Texinfo::ModulePath::init($lib_dir, $xsdir, $modules_pkgdatadir,
'installed' => 1);
}
} # end BEGIN
# This allows disabling use of XS modules when Texinfo is built.
BEGIN {
my $enable_xs = 'yes';
if ($enable_xs eq 'no') {
package Texinfo::XSLoader;
our $disable_XS;
$disable_XS = 1;
}
}
use Locale::Messages;
use Texinfo::Common;
use Texinfo::Config;
# determine the path separators
my $path_separator = $Config{'path_sep'};
$path_separator = ':' if (!defined($path_separator));
my $quoted_path_separator = quotemeta($path_separator);
# Paths and file names
my $curdir = File::Spec->curdir();
my $updir = File::Spec->updir();
# set by configure, prefix for the sysconfdir and so on
# This could be used in the eval
my $prefix = '/usr';
my $datarootdir;
my $sysconfdir;
my $pkgdatadir;
my $datadir;
my $fallback_prefix = File::Spec->catdir(File::Spec->rootdir(), 'usr', 'local');
# We need to eval as $prefix has to be expanded. However when we haven't
# run configure @sysconfdir will be expanded as an array, thus we verify
# whether configure was run or not
if ('/etc' ne '@' . 'sysconfdir@') {
$sysconfdir = eval '"/etc"';
} else {
$sysconfdir = File::Spec->catdir($fallback_prefix, 'etc');
}
if ('/usr/share' ne '@' . 'datarootdir@') {
$datarootdir = eval '"/usr/share"';
} else {
$datarootdir = File::Spec->catdir($fallback_prefix, 'share');
}
if ('/usr/share' ne '@' . 'datadir@' and 'texinfo' ne '@' . 'PACKAGE@') {
$datadir = eval '"/usr/share"';
my $package = 'texinfo';
$pkgdatadir = File::Spec->catdir($datadir, $package);
} else {
$datadir = File::Spec->catdir($fallback_prefix, 'share');
$pkgdatadir = File::Spec->catdir($datadir, 'texinfo');
}
my $extensions_dir;
if ($Texinfo::ModulePath::texinfo_uninstalled) {
$extensions_dir = File::Spec->catdir($Texinfo::ModulePath::top_srcdir,
'tp', 'ext');
} else {
$extensions_dir = File::Spec->catdir($Texinfo::ModulePath::pkgdatadir, 'ext');
}
my $internal_extension_dirs = [$extensions_dir];
# initial setup of messages internalisation framework
# work-around in case libintl-perl do not do it itself
# see http://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable
if ((defined($ENV{"LC_ALL"}) and $ENV{"LC_ALL"} =~ /^(C|POSIX)$/)
or (defined($ENV{"LANG"}) and $ENV{"LANG"} =~ /^(C|POSIX)$/)) {
delete $ENV{"LANGUAGE"} if defined($ENV{"LANGUAGE"});
}
#my $messages_textdomain = 'texinfo';
my $messages_textdomain = 'texinfo';
$messages_textdomain = 'texinfo' if ($messages_textdomain eq '@'.'PACKAGE@');
my $strings_textdomain = 'texinfo' . '_document';
$strings_textdomain = 'texinfo_document'
if ($strings_textdomain eq '@'.'PACKAGE@' . '_document');
# we want a reliable way to switch locale, so we don't use the system
# gettext.
Locale::Messages->select_package('gettext_pp');
if ($Texinfo::ModulePath::texinfo_uninstalled) {
my $locales_dir = File::Spec->catdir($Texinfo::ModulePath::builddir,
'LocaleData');
if (-d $locales_dir) {
Locale::Messages::bindtextdomain($strings_textdomain, $locales_dir);
} else {
warn "Locales dir for document strings not found\n";
}
} else {
Locale::Messages::bindtextdomain($strings_textdomain,
File::Spec->catdir($datadir, 'locale'));
}
# Note: this uses installed messages even when the program is uninstalled
Locale::Messages::bindtextdomain($messages_textdomain,
File::Spec->catdir($datadir, 'locale'));
# Set initial configuration
# Version setting is complicated, because we cope with
# * script with configure values substituted or not
# * script shipped as part of texinfo or as a standalone perl module
# (although standalone module infrastructure was removed in 2019)
# When the script could be shipped with perl modules independently from
# the remaining of Texinfo, $hardcoded_version was set to undef here
# by a sed one liner. The consequence is that configure.ac is not used
# to retrieve the version number, version came from Texinfo::Common in that
# case.
# Otherwise this is only used as a safety value, and should never be used
# in practice as a regexp extracts the version from configure.ac.
my $hardcoded_version = "0.00-hardcoded";
# Version set in configure.ac
my $configured_version = '7.1';
if ($configured_version eq '@' . 'PACKAGE_VERSION@') {
# if not configured, and $hardcoded_version is set search for the version
# in configure.ac
if (defined($hardcoded_version)) {
if (open (CONFIGURE,
"< ".File::Spec->catfile($Texinfo::ModulePath::top_srcdir,
'configure.ac'))) {
while () {
if (/^AC_INIT\(\[[^\]]+\]\s*,\s*\[([^\]]+)\]\s*,/) {
$configured_version = "$1+dev"; # +dev to distinguish from installed
last;
}
}
close (CONFIGURE);
}
# This should never be used, but is a safety value
$configured_version = $hardcoded_version if (!defined($configured_version));
} else {
# was used in the standalone perl module, as $hardcoded_version is undef
# and it should never be configured in that setup.
require Texinfo::Common;
$configured_version = $Texinfo::Common::VERSION;
}
}
# Compare the version of this file with the version of the modules
# it is using. If they are different, don't go any further. This
# can happen if multiple versions of texi2any are installed under a
# different names, e.g. with the --program-suffix option to 'configure'.
# The version in Common.pm is checked because that file has been present
# since Texinfo 5.0 (the first release with texi2any in Perl).
if ($configured_version ne $Texinfo::Common::VERSION
and $configured_version ne $Texinfo::Common::VERSION."+dev") {
warn "This is texi2any $configured_version but modules ".
"for texi2any $Texinfo::Common::VERSION found!\n";
die "Your installation of Texinfo is broken; aborting.\n";
}
my $configured_package = 'texinfo';
$configured_package = 'Texinfo' if ($configured_package eq '@' . 'PACKAGE@');
my $configured_name = 'GNU Texinfo';
$configured_name = $configured_package
if ($configured_name eq '@' .'PACKAGE_NAME@');
my $configured_name_version = "$configured_name $configured_version";
my $configured_url = 'https://www.gnu.org/software/texinfo/';
$configured_url = 'http://www.gnu.org/software/texinfo/'
if ($configured_url eq '@' .'PACKAGE_URL@');
my $texinfo_dtd_version = '7.1';
# $hardcoded_version is undef for a standalone perl module (standalone
# infrastructure was removed in 2019). The code is kept in case it becomes
# useful again, for a standalone perl module or in some specific cases.
if ($texinfo_dtd_version eq '@' . 'TEXINFO_DTD_VERSION@') {
$texinfo_dtd_version = undef;
if (defined($hardcoded_version)) {
if (open (CONFIGURE,
"< ".File::Spec->catfile($Texinfo::ModulePath::top_srcdir,
'configure.ac'))) {
while () {
if (/^TEXINFO_DTD_VERSION=([0-9]\S*)/) {
$texinfo_dtd_version = "$1";
last;
}
}
close (CONFIGURE);
}
}
}
# the encoding used to decode command line arguments, and also for
# file names encoding, perl is expecting sequences of bytes, not unicode
# code points.
my $locale_encoding;
eval 'require I18N::Langinfo';
if (!$@) {
$locale_encoding = I18N::Langinfo::langinfo(I18N::Langinfo::CODESET());
$locale_encoding = undef if ($locale_encoding eq '');
}
if (!defined($locale_encoding) and $^O eq 'MSWin32') {
eval 'require Win32::API';
if (!$@) {
Win32::API::More->Import("kernel32", "int GetACP()");
my $CP = GetACP();
if (defined($CP)) {
$locale_encoding = 'cp'.$CP;
}
}
}
# Used in case it is not hardcoded in configure and for standalone perl module
$texinfo_dtd_version = $configured_version
if (!defined($texinfo_dtd_version));
# options set in the main program.
my $main_program_set_options = {
'PACKAGE_VERSION' => $configured_version,
'PACKAGE' => $configured_package,
'PACKAGE_NAME' => $configured_name,
'PACKAGE_AND_VERSION' => $configured_name_version,
'PACKAGE_URL' => $configured_url,
'PROGRAM' => $real_command_name,
'TEXINFO_DTD_VERSION' => $texinfo_dtd_version,
'COMMAND_LINE_ENCODING' => $locale_encoding,
'MESSAGE_ENCODING' => $locale_encoding,
'LOCALE_ENCODING' => $locale_encoding
};
# In Windows, a character in file name is encoded according to the current
# codepage, and converted to/from UTF-16 in the filesystem. If a file name is
# not encoded in the current codepage, the file name will appear with erroneous
# characters when listing file names. Also the encoding and decoding to
# UTF-16 may fail, especially when the codepage is 8bit while the file name
# is encoded in a multibyte encoding.
# We assume that in Windows the file names are reencoded in the current
# codepage encoding to avoid those issues.
if ($^O eq 'MSWin32') {
$main_program_set_options->{'DOC_ENCODING_FOR_INPUT_FILE_NAME'} = 0;
}
# defaults for options relevant in the main program. Also used as
# defaults for all the converters.
my $main_program_default_options = {
%$main_program_set_options,
%Texinfo::Common::default_main_program_customization_options,
};
# determine configuration directories.
# used as part of binary strings
my $conf_file_name = 'texi2any-config.pm';
# directories for texinfo configuration files, used as part of binary strings.
my @language_config_dirs = File::Spec->catdir($curdir, '.texinfo');
push @language_config_dirs, File::Spec->catdir($ENV{'HOME'}, '.texinfo')
if (defined($ENV{'HOME'}));
push @language_config_dirs, File::Spec->catdir($sysconfdir, 'texinfo')
if (defined($sysconfdir));
push @language_config_dirs, File::Spec->catdir($datadir, 'texinfo')
if (defined($datadir));
my @texinfo_config_dirs = ($curdir, @language_config_dirs);
# these variables are used as part of binary strings.
my @program_config_dirs;
my @program_init_dirs;
my $program_name = 'texi2any';
@program_config_dirs = ($curdir, File::Spec->catdir($curdir, ".$program_name"));
push @program_config_dirs, File::Spec->catdir($ENV{'HOME'}, ".$program_name")
if (defined($ENV{'HOME'}));
push @program_config_dirs, File::Spec->catdir($sysconfdir, $program_name)
if (defined($sysconfdir));
push @program_config_dirs, File::Spec->catdir($datadir, $program_name)
if (defined($datadir));
@program_init_dirs = @program_config_dirs;
foreach my $texinfo_config_dir (@language_config_dirs) {
push @program_init_dirs, File::Spec->catdir($texinfo_config_dir, 'init');
}
# add texi2any extensions dir too, such as the init files there
# can also be loaded as regular init files.
push @program_init_dirs, $extensions_dir;
sub _decode_i18n_string($$)
{
my $string = shift;
my $encoding = shift;
return decode($encoding, $string);
}
sub _encode_message($)
{
my $text = shift;
my $encoding = get_conf('MESSAGE_ENCODING');
if (defined($encoding)) {
return encode($encoding, $text);
} else {
return $text;
}
}
sub document_warn($) {
return if (get_conf('NO_WARN'));
my $text = shift;
chomp ($text);
warn(_encode_message(
sprintf(__p("program name: warning: warning_message",
"%s: warning: %s")."\n", $real_command_name, $text)));
}
sub _decode_input($)
{
my $text = shift;
my $encoding = get_conf('COMMAND_LINE_ENCODING');
if (defined($encoding)) {
return decode($encoding, $text);
} else {
return $text;
}
}
# arguments are binary strings.
sub locate_and_load_init_file($$)
{
my $filename = shift;
my $directories = shift;
my $file = Texinfo::Common::locate_init_file($filename, $directories, 0);
if (defined($file)) {
# evaluate the code in the Texinfo::Config namespace
Texinfo::Config::GNUT_load_init_file($file);
} else {
document_warn(sprintf(__("could not read init file %s"),
_decode_input($filename)));
}
}
# arguments are binary strings.
# Init files that are used in texi2any, considered
# as internal extensions code.
sub locate_and_load_extension_file($$)
{
my $filename = shift;
my $directories = shift;
my $file = Texinfo::Common::locate_init_file($filename, $directories, 0);
if (defined($file)) {
# evaluate the code in the Texinfo::Config namespace
Texinfo::Config::GNUT_load_init_file($file);
} else {
die _encode_message(sprintf(__("could not read extension file %s"),
_decode_input($filename)));
}
}
sub set_from_cmdline($$) {
return &Texinfo::Config::GNUT_set_from_cmdline(@_);
}
sub set_main_program_default($$) {
return &Texinfo::Config::GNUT_set_main_program_default(@_);
}
sub get_conf($) {
return &Texinfo::Config::texinfo_get_conf(@_);
}
sub add_to_option_list($$) {
return &Texinfo::Config::texinfo_add_to_option_list(@_);
}
sub remove_from_option_list($$) {
return &Texinfo::Config::texinfo_remove_from_option_list(@_);
}
sub set_translations_encoding($)
{
my $translations_encoding = shift;
if (defined($translations_encoding)
and $translations_encoding ne 'us-ascii') {
my $Encode_encoding_object = find_encoding($translations_encoding);
my $perl_translations_encoding = $Encode_encoding_object->name();
Locale::Messages::bind_textdomain_codeset($messages_textdomain,
$translations_encoding);
if (defined($perl_translations_encoding)) {
Locale::Messages::bind_textdomain_filter($messages_textdomain,
\&_decode_i18n_string, $perl_translations_encoding);
}
}
}
# Setup customization and read customization files processed each time
# the program is run
# this associates the command line options to the arrays set during
# command line parsing.
my @css_files = ();
my @css_refs = ();
my @include_dirs = ();
my @expanded_formats = ();
# note that CSS_FILES and INCLUDE_DIRECTORIES are not decoded when
# read from the command line and should be binary strings
my $cmdline_options = { 'CSS_FILES' => \@css_files,
'CSS_REFS' => \@css_refs,
'INCLUDE_DIRECTORIES' => \@include_dirs,
'EXPANDED_FORMATS' => \@expanded_formats };
my $format = 'info';
# this is the format associated with the output format, which is replaced
# when the output format changes. It may also be removed if there is the
# corresponding --no-ifformat.
my $default_expanded_format = [ $format ];
my @conf_dirs = ();
my @prepend_dirs = ();
# The $cmdline_options passed to Texinfo::Config::GNUT_initialize_config
# are considered to be arrays in which items can be added or deleted both
# from the command line and from init files. $cmdline_options text values
# are set by GNUT_set_from_cmdline (aliased as set_from_cmdline) from the
# main program. $cmdline_options are also accessed in main program.
# $init_files_options are managed by Texinfo::Config, set by
# texinfo_set_from_init_file in init files.
#
# There is in addition $parser_options for parser related information
# that is not gathered otherwise.
# The configuration values are later on copied over to the parser if
# they are parser options.
my $parser_options = {'values' => {'txicommandconditionals' => 1}};
my $init_files_options = Texinfo::Config::GNUT_initialize_config(
$real_command_name, $main_program_default_options, $cmdline_options);
# Need to do that early for early messages
my $translations_encoding = get_conf('COMMAND_LINE_ENCODING');
set_translations_encoding($translations_encoding);
# read initialization files. Better to do that after
# Texinfo::Config::GNUT_initialize_config() in case loaded
# files replace default options.
foreach my $file (Texinfo::Common::locate_init_file($conf_file_name,
[ reverse(@program_config_dirs) ], 1)) {
Texinfo::Config::GNUT_load_init_file($file);
}
# reset translations encodings if COMMAND_LINE_ENCODING was reset
my $set_translations_encoding = get_conf('COMMAND_LINE_ENCODING');
if (defined($set_translations_encoding)
and (not defined($translations_encoding)
or $set_translations_encoding ne $translations_encoding)) {
$translations_encoding = $set_translations_encoding;
set_translations_encoding($translations_encoding);
}
# Parse command line
sub set_expansion($$) {
my $region = shift;
my $set = shift;
$set = 1 if (!defined($set));
if ($set) {
add_to_option_list('EXPANDED_FORMATS', [$region]);
} else {
remove_from_option_list('EXPANDED_FORMATS', [$region]);
@{$default_expanded_format}
= grep {$_ ne $region} @{$default_expanded_format};
}
}
my %possible_split = (
'chapter' => 1,
'section' => 1,
'node' => 1,
);
my $format_from_command_line = 0;
my %format_command_line_names = (
'xml' => 'texinfoxml',
);
my %formats_table = (
'info' => {
'nodes_tree' => 1,
'floats' => 1,
'module' => 'Texinfo::Convert::Info'
},
'plaintext' => {
'nodes_tree' => 1,
'floats' => 1,
'split' => 1,
'module' => 'Texinfo::Convert::Plaintext'
},
'html' => {
'nodes_tree' => 1,
'floats' => 1,
'split' => 1,
'internal_links' => 1,
'simple_menu' => 1,
'move_index_entries_after_items' => 1,
'relate_index_entries_to_table_items' => 1,
'no_warn_non_empty_parts' => 1,
'module' => 'Texinfo::Convert::HTML'
},
'latex' => {
'floats' => 1,
'internal_links' => 1,
'move_index_entries_after_items' => 1,
'no_warn_non_empty_parts' => 1,
'module' => 'Texinfo::Convert::LaTeX'
},
'texinfoxml' => {
'nodes_tree' => 1,
'module' => 'Texinfo::Convert::TexinfoXML',
'floats' => 1,
},
'texinfosxml' => {
'nodes_tree' => 1,
'module' => 'Texinfo::Convert::TexinfoSXML',
'floats' => 1,
},
'ixinsxml' => { # note that the Texinfo tree is converted to
# 'texinfosxml', but the conversion as a whole
# is 'ixinsxml', as Texinfo tree conversion is done
# from within Texinfo::Convert::IXINSXML
'nodes_tree' => 1,
'module' => 'Texinfo::Convert::IXINSXML',
'floats' => 1,
},
'docbook' => {
'move_index_entries_after_items' => 1,
'no_warn_non_empty_parts' => 1,
'module' => 'Texinfo::Convert::DocBook'
},
'epub3' => {
'converted_format' => 'html',
'init_file' => 'epub3.pm',
},
'pdf' => {
'texi2dvi_format' => 1,
},
'ps' => {
'texi2dvi_format' => 1,
},
'dvi' => {
'texi2dvi_format' => 1,
},
'dvipdf' => {
'texi2dvi_format' => 1,
},
'debugtree' => {
'split' => 1,
'module' => 'DebugTexinfo::DebugTree'
},
'textcontent' => {
'module' => 'Texinfo::Convert::TextContent'
},
'rawtext' => {
'module' => 'Texinfo::Convert::Text'
},
'plaintexinfo' => {
'module' => 'Texinfo::Convert::PlainTexinfo'
},
'parse' => {
},
'structure' => {
'nodes_tree' => 1,
'floats' => 1,
'split' => 1,
},
);
my $call_texi2dvi = 0;
my @texi2dvi_args = ();
# previous_format should be in argument if there is a possibility of error.
# as a fallback, the $format global variable is used.
sub set_format($;$$)
{
my $set_format = shift;
my $previous_format = shift;
$previous_format = $format if (!defined($previous_format));
my $do_not_override_command_line = shift;
my $new_format;
if ($format_command_line_names{$set_format}) {
$new_format = $format_command_line_names{$set_format};
} else {
$new_format = $set_format;
}
my $expanded_format = $set_format;
if (!$formats_table{$new_format}) {
document_warn(sprintf(__(
"ignoring unrecognized TEXINFO_OUTPUT_FORMAT value `%s'\n"),
$new_format));
$new_format = $previous_format;
} else {
if ($format_from_command_line and $do_not_override_command_line) {
$new_format = $previous_format;
} else {
if ($formats_table{$new_format}->{'texi2dvi_format'}) {
$call_texi2dvi = 1;
push @texi2dvi_args, '--'.$new_format;
$expanded_format = 'tex';
} elsif ($formats_table{$new_format}->{'converted_format'}) {
$expanded_format = $formats_table{$new_format}->{'converted_format'};
}
if ($Texinfo::Common::texinfo_output_formats{$expanded_format}) {
if ($expanded_format eq 'plaintext') {
$default_expanded_format = [$expanded_format, 'info'];
} else {
$default_expanded_format = [$expanded_format];
}
}
$format_from_command_line = 1
unless ($do_not_override_command_line);
}
}
return $new_format;
}
sub _get_converter_default($)
{
my $option = shift;
if (defined($Texinfo::Common::default_converter_command_line_options{$option})) {
return $Texinfo::Common::default_converter_command_line_options{$option};
} elsif (defined($Texinfo::Common::document_settable_multiple_at_commands{$option})) {
return $Texinfo::Common::document_settable_multiple_at_commands{$option};
} #elsif (defined(%Texinfo::Common::document_settable_unique_at_commands{$option})) {
# return $Texinfo::Common::document_settable_unique_at_commands{$option};
#}
return undef;
}
# translation related todo to be done when the string change anyway to
# avoid requiring translation
sub makeinfo_help()
{
# TODO: avoid \n in translated strings. Report from Benno Schulenberg
my $makeinfo_help =
sprintf(__("Usage: %s [OPTION]... TEXINFO-FILE...\n"),
$real_command_name . $command_suffix)
."\n".
__("Translate Texinfo source documentation to various other formats, by default
Info files suitable for reading online with Emacs or standalone GNU Info.
This program is commonly installed as both `makeinfo' and `texi2any';
the behavior is identical, and does not depend on the installed name.\n")
."\n";
# TODO: avoid \n in translated strings, split each option in a translatable
# string. Report from Benno Schulenberg
$makeinfo_help .= sprintf(__("General options:
--document-language=STR locale to use in translating Texinfo keywords
for the output document (default C).
--error-limit=NUM quit after NUM errors (default %d).
--force preserve output even if errors.
--help display this help and exit.
--no-validate suppress node cross-reference validation.
--no-warn suppress warnings (but not errors).
--conf-dir=DIR search also for initialization files in DIR.
--init-file=FILE load FILE to modify the default behavior.
-c, --set-customization-variable VAR=VAL set customization variable VAR
to value VAL.
-v, --verbose explain what is being done.
--version display version information and exit.\n"),
get_conf('ERROR_LIMIT'))
."\n";
$makeinfo_help .= __("Output format selection (default is to produce Info):")."\n"
.__(" --docbook output Docbook XML.")."\n"
.__(" --html output HTML.")."\n"
.__(" --epub3 output EPUB 3.")."\n"
.__(" --latex output LaTeX.")."\n"
.__(" --plaintext output plain text rather than Info.")."\n"
.__(" --xml output Texinfo XML.")."\n"
.__(" --dvi, --dvipdf, --ps, --pdf call texi2dvi to generate given output,
after checking validity of TEXINFO-FILE.")."\n"
."\n";
$makeinfo_help .= __("General output options:")."\n"
.__(
" -E, --macro-expand=FILE output macro-expanded source to FILE,
ignoring any \@setfilename.")."\n"
.__(
" --no-headers suppress node separators, Node: lines, and menus
from Info output (thus producing plain text)
or from HTML (thus producing shorter output).
Also, if producing Info, write to
standard output by default.")."\n"
.__(
" --no-split suppress any splitting of the output;
generate only one output file.")."\n"
.__(
" --[no-]number-sections output chapter and sectioning numbers;
default is on.")."\n"
.__(
" -o, --output=DEST output to DEST.
With split output, create DEST as a directory
and put the output files there.
With non-split output, if DEST is already
a directory or ends with a /,
put the output file there.
Otherwise, DEST names the output file.")."\n"
.__(
" --disable-encoding do not output accented and special characters
in Info and plain text output based on document
encoding.")."\n"
.__(
" --enable-encoding override --disable-encoding (default).")."\n"
."\n";
$makeinfo_help .= sprintf(__("Options for Info and plain text:")."\n"
.__(
" --fill-column=NUM break Info lines at NUM columns (default %d).")."\n"
.__(
" --footnote-style=STYLE output footnotes in Info according to STYLE:
`separate' to put them in their own node;
`end' to put them at the end of the node, in
which they are defined (this is the default).")."\n"
.__(
" --paragraph-indent=VAL indent Info paragraphs by VAL spaces (default %d).
If VAL is `none', do not indent; if VAL is
`asis', preserve existing indentation.")."\n"
.__(
" --split-size=NUM split Info files at size NUM (default %d).")."\n"
."\n",
_get_converter_default('FILLCOLUMN'),
_get_converter_default('paragraphindent'),
_get_converter_default('SPLIT_SIZE'))
."\n";
# TODO: avoid \n in translated strings, split each option in a translatable
# string. Report from Benno Schulenberg
$makeinfo_help .= __("Options for HTML:
--css-include=FILE include FILE in HTML