diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .x-update-copyright | 3 | ||||
-rw-r--r-- | cfg.mk | 10 | ||||
-rw-r--r-- | man/help2man.diff | 32 | ||||
-rwxr-xr-x | man/help2man.in (renamed from man/help2man) | 432 | ||||
-rw-r--r-- | man/local.mk | 10 |
6 files changed, 323 insertions, 165 deletions
diff --git a/.gitignore b/.gitignore index 558577d23..b03f62011 100644 --- a/.gitignore +++ b/.gitignore @@ -134,6 +134,7 @@ /m4/xsize.m4 /maint.mk /man/*.1 +/man/help2man /po/*.gmo /po/*.po /po/.gitignore diff --git a/.x-update-copyright b/.x-update-copyright new file mode 100644 index 000000000..47cb0f4e5 --- /dev/null +++ b/.x-update-copyright @@ -0,0 +1,3 @@ +COPYING +man/help2man\.diff +man/help2man\.in @@ -221,11 +221,13 @@ sc_prohibit-gl-attributes: # Look for lines longer than 80 characters, except omit: # - program-generated long lines in diff headers, +# - the original help2man script copied from upstream, # - tests involving long checksum lines, and # - the 'pr' test cases. LINE_LEN_MAX = 80 FILTER_LONG_LINES = \ /^[^:]*\.diff:[^:]*:@@ / d; \ + \|^[^:]*man/help2man\.in:| d; \ \|^[^:]*tests/misc/sha[0-9]*sum.*\.pl[-:]| d; \ \|^[^:]*tests/pr/|{ \|^[^:]*tests/pr/pr-tests:| !d; }; sc_long_lines: @@ -566,10 +568,10 @@ update-copyright-env = \ # List syntax-check exemptions. exclude_file_name_regexp--sc_space_tab = \ - ^(tests/pr/|tests/misc/nl\.sh$$|gl/.*\.diff$$) + ^(tests/pr/|tests/misc/nl\.sh$$|gl/.*\.diff$$|man/help2man\.diff$$) exclude_file_name_regexp--sc_bindtextdomain = \ ^(gl/.*|lib/euidaccess-stat|src/make-prime-list)\.c$$ -exclude_file_name_regexp--sc_trailing_blank = ^tests/pr/ +exclude_file_name_regexp--sc_trailing_blank = ^(tests/pr/|man/help2man.diff) exclude_file_name_regexp--sc_system_h_headers = \ ^src/((system|copy)\.h|libstdbuf\.c|make-prime-list\.c)$$ @@ -579,7 +581,7 @@ exclude_file_name_regexp--sc_require_config_h_first = \ exclude_file_name_regexp--sc_require_config_h = \ $(exclude_file_name_regexp--sc_require_config_h_first) -exclude_file_name_regexp--sc_po_check = ^gl/ +exclude_file_name_regexp--sc_po_check = ^(gl/|man/help2man\.in) exclude_file_name_regexp--sc_prohibit_always-defined_macros = \ ^src/(seq|remove)\.c$$ exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = ^tests/pr/ @@ -599,7 +601,7 @@ exclude_file_name_regexp--sc_useless_cpp_parens = $(_ll) exclude_file_name_regexp--sc_long_lines = $(_ll) exclude_file_name_regexp--sc_space_before_open_paren = $(_ll) -tbi_1 = ^tests/pr/|(^gl/lib/reg.*\.c\.diff|\.mk|^man/help2man)$$ +tbi_1 = ^tests/pr/|(^gl/lib/reg.*\.c\.diff|\.mk|^man/help2man\.(in|diff))$$ tbi_2 = ^scripts/git-hooks/(pre-commit|pre-applypatch|applypatch-msg)$$ tbi_3 = (GNU)?[Mm]akefile(\.am)?$$|$(_ll) exclude_file_name_regexp--sc_prohibit_tab_based_indentation = \ diff --git a/man/help2man.diff b/man/help2man.diff new file mode 100644 index 000000000..017f4dc5b --- /dev/null +++ b/man/help2man.diff @@ -0,0 +1,32 @@ +--- man/help2man-orig ++++ man/help2man 2013-08-01 02:37:57.771389937 +0200 +@@ -435,6 +435,7 @@ + my $PAT_FILES = _('Files'); + my $PAT_EXAMPLES = _('Examples'); + my $PAT_FREE_SOFTWARE = _('This +is +free +software'); ++my $PAT_INFO = _('For +complete +documentation'); + + # Start a new paragraph (if required) for these. + s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR) /$1\n\n$2 /og; +@@ -467,6 +468,12 @@ + next; + } + ++ # Skip any texinfo reference as that's handled separately ++ if (s/($PAT_INFO).*\n//o) ++ { ++ next; ++ } ++ + # Copyright section + if (/^Copyright /) + { +@@ -645,7 +652,7 @@ + .B %s + programs are properly installed at your site, the command + .IP +-.B info %s ++.B info coreutils \(aq%s invocation\(aq + .PP + should give you access to the complete manual. + EOT diff --git a/man/help2man b/man/help2man.in index 8e83f355d..79f686cd7 100755 --- a/man/help2man +++ b/man/help2man.in @@ -1,12 +1,13 @@ #!/usr/bin/perl -w # Generate a short man page from --help and --version output. -# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, +# 2010, 2011, 2012, 2013 Free Software Foundation, Inc. -# This program is free software: you can redistribute it and/or modify +# 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. +# the Free Software Foundation; either version 3, 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 @@ -14,65 +15,72 @@ # 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 <http://www.gnu.org/licenses/>. +# along with this program; if not, see <http://www.gnu.org/licenses/>. # Written by Brendan O'Dea <bod@debian.org> # Available from ftp://ftp.gnu.org/gnu/help2man/ -use 5.005; +use 5.008; use strict; use Getopt::Long; use Text::Tabs qw(expand); use POSIX qw(strftime setlocale LC_ALL); -use locale; +use Locale::gettext; +use Encode qw(decode encode); +use I18N::Langinfo qw(langinfo CODESET); my $this_program = 'help2man'; -my $this_version = '1.35'; +my $this_version = '1.43.3'; +my $encoding; -my $have_gettext; -BEGIN { - eval { - require Locale::gettext; - Locale::gettext->import (qw(gettext textdomain)); - $have_gettext = 1; - }; - - unless ($have_gettext) - { - *gettext = sub { $_[0] }; - *textdomain = sub {}; - } -} - -sub _ { gettext @_ } -sub N_ { $_[0] } - -textdomain $this_program; { + my $gettext = Locale::gettext->domain($this_program); + sub _ { $gettext->get($_[0]) } + my ($user_locale) = grep defined && length, (map $ENV{$_}, qw(LANGUAGE LC_ALL LC_MESSAGES LANG)), 'C'; + my $user_encoding = langinfo CODESET; + + # Set localisation of date and executable's output. + sub configure_locale + { + delete @ENV{qw(LANGUAGE LC_MESSAGES LANG)}; + setlocale LC_ALL, $ENV{LC_ALL} = shift || 'C'; + $encoding = langinfo CODESET; + } + + sub dec { $encoding ? decode $encoding, $_[0] : $_[0] } + sub enc { $encoding ? encode $encoding, $_[0] : $_[0] } + sub enc_user { encode $user_encoding, $_[0] } sub kark # die with message formatted in the invoking user's locale { setlocale LC_ALL, $user_locale; - my $fmt = gettext shift; - die +(sprintf $fmt, @_), "\n"; + my $fmt = $gettext->get(shift); + my $errmsg = enc_user sprintf $fmt, @_; + die $errmsg, "\n"; } } -my $version_info = sprintf _(<<'EOT'), $this_program, $this_version; +sub N_ { $_[0] } + +sub program_basename; +sub get_option_value; +sub convert_option; + +my $version_info = enc_user sprintf _(<<'EOT'), $this_program, $this_version; GNU %s %s -Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software -Foundation, Inc. +Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2010, +2011, 2012, 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by Brendan O'Dea <bod@debian.org> EOT -my $help_info = sprintf _(<<'EOT'), $this_program, $this_program; -'%s' generates a man page out of '--help' and '--version' output. +my $help_info = enc_user sprintf _(<<'EOT'), $this_program, $this_program; +`%s' generates a man page out of `--help' and `--version' output. Usage: %s [OPTION]... EXECUTABLE @@ -81,19 +89,22 @@ Usage: %s [OPTION]... EXECUTABLE -m, --manual=TEXT name of manual (User Commands, ...) -S, --source=TEXT source of program (FSF, Debian, ...) -L, --locale=STRING select locale (default "C") - -i, --include=FILE include material from 'FILE' - -I, --opt-include=FILE include material from 'FILE' if it exists - -o, --output=FILE send output to 'FILE' + -i, --include=FILE include material from `FILE' + -I, --opt-include=FILE include material from `FILE' if it exists + -o, --output=FILE send output to `FILE' -p, --info-page=TEXT name of Texinfo manual -N, --no-info suppress pointer to Texinfo manual + -l, --libtool exclude the `lt-' from the program name --help print this help, then exit --version print version number, then exit -EXECUTABLE should accept '--help' and '--version' options although -alternatives may be specified using: +EXECUTABLE should accept `--help' and `--version' options and produce output on +stdout although alternatives may be specified using: -h, --help-option=STRING help option string -v, --version-option=STRING version option string + --version-string=STRING version string + --no-discard-stderr include stderr when parsing option output Report bugs to <bug-help2man@gnu.org>. EOT @@ -101,55 +112,65 @@ EOT my $section = 1; my $manual = ''; my $source = ''; -my $locale = 'C'; my $help_option = '--help'; my $version_option = '--version'; -my ($opt_name, @opt_include, $opt_output, $opt_info, $opt_no_info); +my $discard_stderr = 1; +my ($opt_name, @opt_include, $opt_output, $opt_info, $opt_no_info, $opt_libtool, + $version_text); my %opt_def = ( 'n|name=s' => \$opt_name, 's|section=s' => \$section, 'm|manual=s' => \$manual, 'S|source=s' => \$source, - 'L|locale=s' => \$locale, + 'L|locale=s' => sub { configure_locale pop }, 'i|include=s' => sub { push @opt_include, [ pop, 1 ] }, 'I|opt-include=s' => sub { push @opt_include, [ pop, 0 ] }, 'o|output=s' => \$opt_output, 'p|info-page=s' => \$opt_info, 'N|no-info' => \$opt_no_info, + 'l|libtool' => \$opt_libtool, + 'help' => sub { print $help_info; exit }, + 'version' => sub { print $version_info; exit }, 'h|help-option=s' => \$help_option, 'v|version-option=s' => \$version_option, + 'version-string=s' => \$version_text, + 'discard-stderr!' => \$discard_stderr, ); # Parse options. Getopt::Long::config('bundling'); -GetOptions (%opt_def, - help => sub { print $help_info; exit }, - version => sub { print $version_info; exit }, -) or die $help_info; +die $help_info unless GetOptions %opt_def and @ARGV == 1; -die $help_info unless @ARGV == 1; - -die "$this_program: no locale support (Locale::gettext required)\n" - unless $locale eq 'C' or $have_gettext; - -# Set localization of date and executable's output. -delete @ENV{qw(LANGUAGE LC_MESSAGES LANG)}; -setlocale LC_ALL, $ENV{LC_ALL} = $locale; +configure_locale unless $encoding; my %include = (); +my %replace = (); my %append = (); +my %append_match = (); my @include = (); # retain order given in include file # Process include file (if given). Format is: # -# [section name] -# verbatim text +# Optional initial text, ignored. May include lines starting with `-' +# which are processed as options. +# +# [section] +# Verbatim text to be included in the named section. By default at +# the start, but in the case of `name' and `synopsis' the content +# will replace the autogenerated contents. +# +# [<section] +# Verbatim text to be inserted at the start of the named section. +# +# [=section] +# Verbatim text to replace the named section. # -# or +# [>section] +# Verbatim text to be appended to the end of the named section. # # /pattern/ -# verbatim text +# Verbatim text for inclusion below a paragraph matching `pattern'. # while (@opt_include) @@ -157,27 +178,49 @@ while (@opt_include) my ($inc, $required) = @{shift @opt_include}; next unless -f $inc or $required; - kark N_("%s: can't open '%s' (%s)"), $this_program, $inc, $! + kark N_("%s: can't open `%s' (%s)"), $this_program, $inc, $! unless open INC, $inc; my $key; - my $hash = \%include; + my $hash; while (<INC>) { + # Convert input to internal Perl format, so that multibyte + # sequences are treated as single characters. + $_ = dec $_; + # [section] - if (/^\[([^]]+)\]/) + if (/^\[([^]]+)\]\s*$/) { $key = uc $1; $key =~ s/^\s+//; $key =~ s/\s+$//; $hash = \%include; - push @include, $key unless $include{$key}; + # Handle explicit [<section], [=section] and [>section] + if ($key =~ s/^([<>=])\s*//) + { + if ($1 eq '>') { $hash = \%append; } + elsif ($1 eq '=') { $hash = \%replace; } + } + # NAME/SYNOPSIS replace by default + elsif ($key eq _('NAME') or $key eq _('SYNOPSIS')) + { + $hash = \%replace; + } + else + { + $hash = \%include; + } + + push @include, $key + unless $include{$key} or $replace{$key} or $append{$key}; + next; } # /pattern/ - if (m!^/(.*)/([ims]*)!) + if (m!^/(.*)/([ims]*)\s*$!) { my $pat = $2 ? "(?$2)$1" : $1; @@ -189,7 +232,7 @@ while (@opt_include) die "$inc:$.:$@"; } - $hash = \%append; + $hash = \%append_match; next; } @@ -208,31 +251,31 @@ while (@opt_include) next; } - $hash->{$key} ||= ''; $hash->{$key} .= $_; } close INC; - kark N_("%s: no valid information found in '%s'"), $this_program, $inc + kark N_("%s: no valid information found in `%s'"), $this_program, $inc unless $key; } # Compress trailing blank lines. -for my $hash (\(%include, %append)) +for my $hash (\(%include, %replace, %append, %append_match)) { for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ } } # Grab help and version info from executable. -my ($help_text, $version_text) = map { - join '', map { s/ +$//; expand $_ } `$ARGV[0] $_ 2>/dev/null` - or kark N_("%s: can't get '%s' info from %s"), $this_program, - $_, $ARGV[0] -} $help_option, $version_option; - -my $date = strftime "%B %Y", localtime; -(my $program = $ARGV[0]) =~ s!.*/!!; +my $help_text = get_option_value $ARGV[0], $help_option; +$version_text ||= get_option_value $ARGV[0], $version_option; + +# Translators: the following message is a strftime(3) format string, which in +# the English version expands to the month as a word and the full year. It +# is used on the footer of the generated manual pages. If in doubt, you may +# just use %x as the value (which should be the full locale-specific date). +my $date = enc strftime _("%B %Y"), localtime; +my $program = program_basename $ARGV[0]; my $package = $program; my $version; @@ -256,19 +299,19 @@ if ($opt_output) # # and separated from any copyright/author details by a blank line. -($_, $version_text) = split /\n+/, $version_text, 2; +($_, $version_text) = ((split /\n+/, $version_text, 2), ''); if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or /^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/) { - $program = $1; + $program = program_basename $1; $package = $2; $version = $3; } elsif (/^((?:GNU|Free) +)?(\S+) +(.*)/) { - $program = $2; - $package = $1 ? "$1$2" : $2; + $program = program_basename $2; + $package = $1 ? "$1$program" : $program; $version = $3; } else @@ -276,18 +319,21 @@ else $version = $_; } -$program =~ s!.*/!!; - -# No info for 'info' itself. +# No info for `info' itself. $opt_no_info = 1 if $program eq 'info'; -for ($include{_('NAME')}) +if ($opt_name) { - if ($opt_name) # --name overrides --include contents. - { - $_ = "$program \\- $opt_name\n"; - } - elsif ($_) # Use first name given as $program + # --name overrides --include contents. + $replace{_('NAME')} = "$program \\- $opt_name\n"; +} + +# Translators: "NAME", "SYNOPSIS" and other one or two word strings in all +# upper case are manual page section headings. The man(1) manual page in your +# language, if available should provide the conventional translations. +for ($replace{_('NAME')} || ($include{_('NAME')} ||= '')) +{ + if ($_) # Use first name given as $program { $program = $1 if /^([^\s,]+)(?:,?\s*[^\s,\\-]+)*\s+\\?-/; } @@ -307,19 +353,22 @@ unless ($manual) { for ($section) { - if (/^(1[Mm]|8)/) { $manual = _('System Administration Utilities') } - elsif (/^6/) { $manual = _('Games') } - else { $manual = _('User Commands') } + if (/^(1[Mm]|8)/) { $manual = enc _('System Administration Utilities') } + elsif (/^6/) { $manual = enc _('Games') } + else { $manual = enc _('User Commands') } } } # Extract usage clause(s) [if any] for SYNOPSIS. +# Translators: "Usage" and "or" here are patterns (regular expressions) which +# are used to match the usage synopsis in program output. An example from cp +# (GNU coreutils) which contains both strings: +# Usage: cp [OPTION]... [-T] SOURCE DEST +# or: cp [OPTION]... SOURCE... DIRECTORY +# or: cp [OPTION]... -t DIRECTORY SOURCE... my $PAT_USAGE = _('Usage'); my $PAT_USAGE_CONT = _('or'); -if ($help_text =~ s/^($PAT_USAGE): - ([ ]+(\S+)) - (.*) - ((?:\n(?:[ ]{6}\1|[ ]*($PAT_USAGE_CONT):[ ]+\S).*)*)//omx) +if ($help_text =~ s/^($PAT_USAGE):( +(\S+))(.*)((?:\n(?: {6}\1| *($PAT_USAGE_CONT): +\S).*)*)//om) { my @syn = $3 . $4; @@ -334,6 +383,7 @@ if ($help_text =~ s/^($PAT_USAGE): { $synopsis .= ".br\n" if $synopsis; s!^\S*/!!; + s/^lt-// if $opt_libtool; s/^(\S+) *//; $synopsis .= ".B $1\n"; s/\s+$//; @@ -349,7 +399,7 @@ if ($help_text =~ s/^($PAT_USAGE): $synopsis .= "$_\n"; } - $include{_('SYNOPSIS')} ||= $synopsis; + $include{_('SYNOPSIS')} .= $synopsis; } # Process text, initial section is DESCRIPTION. @@ -370,17 +420,28 @@ s/^\./\x80/mg; s/^'/\x81/mg; s/\\/\x82/g; -my $PAT_BUGS = _('Report +(?:\w+ +)?bugs|Email +bug +reports +to'); -my $PAT_AUTHOR = _('Written +by'); -my $PAT_OPTIONS = _('Options'); -my $PAT_EXAMPLES = _('Examples'); -my $PAT_FREE_SOFTWARE = _('This +is +free +software'); -my $PAT_INFO = _('For +complete +documentation'); +# Translators: patterns are used to match common program output. In the source +# these strings are all of the form of "my $PAT_something = _('...');" and are +# regular expressions. If there is more than one commonly used string, you +# may separate alternatives with "|". Spaces in these expressions are written +# as " +" to indicate that more than one space may be matched. The string +# "(?:[\\w-]+ +)?" in the bug reporting pattern is used to indicate an +# optional word, so that either "Report bugs" or "Report _program_ bugs" will +# be matched. +my $PAT_BUGS = _('Report +(?:[\w-]+ +)?bugs|Email +bug +reports +to'); +my $PAT_AUTHOR = _('Written +by'); +my $PAT_OPTIONS = _('Options'); +my $PAT_ENVIRONMENT = _('Environment'); +my $PAT_FILES = _('Files'); +my $PAT_EXAMPLES = _('Examples'); +my $PAT_FREE_SOFTWARE = _('This +is +free +software'); # Start a new paragraph (if required) for these. -s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR)/$1\n\n$2/og; +s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR) /$1\n\n$2 /og; -sub convert_option; +# Convert iso-8859-1 copyright symbol or (c) to nroff +# character. +s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg; while (length) { @@ -390,48 +451,30 @@ while (length) $sect = _('OPTIONS'); next; } - elsif (s/^($PAT_EXAMPLES): *\n//o) + if (s/^($PAT_ENVIRONMENT): *\n//o) { - $sect = _('EXAMPLES'); + $sect = _('ENVIRONMENT'); next; } - # Skip any texinfo reference as that's handled separately - if (s/($PAT_INFO).*\n//o) + if (s/^($PAT_FILES): *\n//o) { + $sect = _('FILES'); + next; + } + elsif (s/^($PAT_EXAMPLES): *\n//o) + { + $sect = _('EXAMPLES'); next; } # Copyright section - if (/^Copyright +[(\xa9]/) + if (/^Copyright /) { $sect = _('COPYRIGHT'); - $include{$sect} ||= ''; - $include{$sect} .= ".PP\n" if $include{$sect}; - - my $copy; - ($copy, $_) = split /\n\n/, $_, 2; - - for ($copy) - { - # Add back newline - s/\n*$/\n/; - - # Convert iso9959-1 copyright symbol or (c) to nroff - # character. - s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg; - - # Insert line breaks before additional copyright messages - # and the disclaimer. - s/(.)\n(Copyright |$PAT_FREE_SOFTWARE)/$1\n.br\n$2/og; - } - - $include{$sect} .= $copy; - $_ ||= ''; - next; } - # Catch bug report text. - if (/^($PAT_BUGS) /o) + # Bug reporting section. + elsif (/^($PAT_BUGS) /o) { $sect = _('REPORTING BUGS'); } @@ -449,7 +492,6 @@ while (length) my $indent = $1; my $prefix = $2; my $break = '.IP'; - $include{$sect} ||= ''; while (s/^$indent\Q$prefix\E(\S.*)\n*//) { $include{$sect} .= "$break\n\\f(CW$prefix$1\\fR\n"; @@ -460,12 +502,11 @@ while (length) } my $matched = ''; - $include{$sect} ||= ''; # Sub-sections have a trailing colon and the second line indented. if (s/^(\S.*:) *\n / /) { - $matched .= $& if %append; + $matched .= $& if %append_match; $include{$sect} .= qq(.SS "$1"\n); } @@ -475,7 +516,7 @@ while (length) # Option with description. if (s/^( {1,10}([+-]\S.*?))(?:( +(?!-))|\n( {20,}))(\S.*)\n//) { - $matched .= $& if %append; + $matched .= $& if %append_match; $indent = length ($4 || "$1$3"); $content = ".TP\n\x84$2\n\x84$5\n"; unless ($4) @@ -488,7 +529,7 @@ while (length) # Option without description. elsif (s/^ {1,10}([+-]\S.*)\n//) { - $matched .= $& if %append; + $matched .= $& if %append_match; $content = ".HP\n\x84$1\n"; $indent = 80; # not continued } @@ -496,7 +537,7 @@ while (length) # Indented paragraph with tag. elsif (s/^( +(\S.*?) +)(\S.*)\n//) { - $matched .= $& if %append; + $matched .= $& if %append_match; $indent = length $1; $content = ".TP\n\x84$2\n\x84$3\n"; } @@ -504,7 +545,7 @@ while (length) # Indented paragraph. elsif (s/^( +)(\S.*)\n//) { - $matched .= $& if %append; + $matched .= $& if %append_match; $indent = length $1; $content = ".IP\n\x84$2\n"; } @@ -513,7 +554,7 @@ while (length) else { s/(.*)\n//; - $matched .= $& if %append; + $matched .= $& if %append_match; $content = ".PP\n" if $include{$sect}; $content .= "$1\n"; } @@ -521,8 +562,8 @@ while (length) # Append continuations. while ($indent ? s/^ {$indent}(\S.*)\n// : s/^(\S.*)\n//) { - $matched .= $& if %append; - $content .= "\x84$1\n" + $matched .= $& if %append_match; + $content .= "\x84$1\n"; } # Move to next paragraph. @@ -535,22 +576,52 @@ while (length) s/\x84'/\x81/g; s/\x84//g; - # Convert options. - s/(^| |\()(-[][\w=-]+)/$1 . convert_option $2/mge; + # Examples should be verbatim. + unless ($sect eq _('EXAMPLES')) + { + # Convert options. + s/(^|[ (])(-[][\w=-]+)/$1 . convert_option $2/mge; + + # Italicise filenames: /a/b, $VAR/c/d, ~/e/f + s! + (^|[ (]) # space/punctuation before + ( + (?:\$\w+|~)? # leading variable, or tilde + (?:/\w(?:[\w.-]*\w)?)+ # path components + ) + ($|[ ,;.)]) # space/punctuation after + !$1\\fI$2\\fP$3!xmg; + } - # Escape remaining hyphens + # Escape remaining hyphens. s/-/\x83/g; + + if ($sect eq _('COPYRIGHT')) + { + # Insert line breaks before additional copyright messages + # and the disclaimer. + s/\n(Copyright |$PAT_FREE_SOFTWARE)/\n.br\n$1/og; + } + elsif ($sect eq _('REPORTING BUGS')) + { + # Handle multi-line bug reporting sections of the form: + # + # Report <program> bugs to <addr> + # GNU <package> home page: <url> + # ... + s/\n([[:upper:]])/\n.br\n$1/g; + } } # Check if matched paragraph contains /pat/. - if (%append) + if (%append_match) { - for my $pat (keys %append) + for my $pat (keys %append_match) { if ($matched =~ $pat) { - $content .= ".PP\n" unless $append{$pat} =~ /^\./; - $content .= $append{$pat}; + $content .= ".PP\n" unless $append_match{$pat} =~ /^\./; + $content .= $append_match{$pat}; } } } @@ -564,7 +635,6 @@ unless ($opt_no_info) my $info_page = $opt_info || $program; $sect = _('SEE ALSO'); - $include{$sect} ||= ''; $include{$sect} .= ".PP\n" if $include{$sect}; $include{$sect} .= sprintf _(<<'EOT'), $program, $program, $info_page; The full documentation for @@ -575,12 +645,24 @@ and .B %s programs are properly installed at your site, the command .IP -.B info coreutils \(aq%s invocation\(aq +.B info %s .PP should give you access to the complete manual. EOT } +# Append additional text. +while (my ($sect, $text) = each %append) +{ + $include{$sect} .= $append{$sect}; +} + +# Replace sections. +while (my ($sect, $text) = each %replace) +{ + $include{$sect} = $replace{$sect}; +} + # Output header. print <<EOT; .\\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version. @@ -589,7 +671,7 @@ EOT # Section ordering. my @pre = (_('NAME'), _('SYNOPSIS'), _('DESCRIPTION'), _('OPTIONS'), - _('EXAMPLES')); + _('ENVIRONMENT'), _('FILES'), _('EXAMPLES')); my @post = (_('AUTHOR'), _('REPORTING BUGS'), _('COPYRIGHT'), _('SEE ALSO')); my $filter = join '|', @pre, @post; @@ -599,9 +681,8 @@ for my $sect (@pre, (grep ! /^($filter)$/o, @include), @post) { if ($include{$sect}) { - my $lsect = gettext $sect; - my $quote = $lsect =~ /\W/ ? '"' : ''; - print ".SH $quote$lsect$quote\n"; + my $quote = $sect =~ /\W/ ? '"' : ''; + print enc ".SH $quote$sect$quote\n"; for ($include{$sect}) { @@ -615,10 +696,7 @@ for my $sect (@pre, (grep ! /^($filter)$/o, @include), @post) # Convert some latin1 chars to troff equivalents s/\xa0/\\ /g; # non-breaking space - $sect eq 'REPORTING BUGS' - and s/\n(.)/\n.br\n$1/g; - - print; + print enc $_; } } } @@ -628,6 +706,38 @@ close STDOUT or kark N_("%s: error writing to %s (%s)"), $this_program, exit; +# Get program basename, and strip libtool "lt-" prefix if required. +sub program_basename +{ + local $_ = shift; + s!.*/!!; + s/^lt-// if $opt_libtool; + $_; +} + +# Call program with given option and return results. +sub get_option_value +{ + my ($prog, $opt) = @_; + my $stderr = $discard_stderr ? '/dev/null' : '&1'; + my $value = join '', + map { s/ +$//; expand $_ } + map { dec $_ } + `$prog $opt 2>$stderr`; + + unless ($value) + { + my $err = N_("%s: can't get `%s' info from %s%s"); + my $extra = $discard_stderr + ? "\n" . N_("Try `--no-discard-stderr' if option outputs to stderr") + : ''; + + kark $err, $this_program, $opt, $prog, $extra; + } + + $value; +} + # Convert option dashes to \- to stop nroff from hyphenating 'em, and # embolden. Option arguments get italicised. sub convert_option diff --git a/man/local.mk b/man/local.mk index 53debad46..d967d1636 100644 --- a/man/local.mk +++ b/man/local.mk @@ -50,6 +50,9 @@ distclean-local: # Dependencies common to all man pages. Updated below. mandeps = +# Depend on the help2man script. +mandeps += man/help2man + # Depend on this to get version number changes. mandeps += .version @@ -59,6 +62,13 @@ mandeps += $(top_srcdir)/src/system.h $(ALL_MANS): $(mandeps) +# Create help2man from the upstream version and out patch. +man/help2man: man/help2man.in man/help2man.diff + $(AM_V_GEN)cp man/help2man.in man/help2man.tmp \ + && VERSION_CONTROL=none patch man/help2man.tmp < man/help2man.diff \ + && chmod a+x man/help2man.tmp \ + && mv man/help2man.tmp man/help2man + # Most prog.1 man pages depend on src/prog. List the exceptions: # Note that dir and vdir are exceptions only if you consider the name # of the .c file upon which they depend: ls.c. |