X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=buildscripts%2Fhelp2man.pl;h=9cb09c4859921da605d4303b1fe44e2dedc7c015;hb=03302c2f0fec2ccf1484b1ab316f90d4c17b786d;hp=d50592dec70fed4dc499745e3883fe64e56b2a7b;hpb=29d1ad412ee48aa7a3a1666c7ab7af8fd2e2b1bf;p=lilypond.git diff --git a/buildscripts/help2man.pl b/buildscripts/help2man.pl old mode 100755 new mode 100644 index d50592dec7..9cb09c4859 --- a/buildscripts/help2man.pl +++ b/buildscripts/help2man.pl @@ -1,7 +1,8 @@ -#!/usr/local/bin/perl -w +#!@PERL@ -w # Generate a short man page from --help and --version output. -# Copyright © 1997, 98, 99 Free Software Foundation, Inc. +# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 @@ -17,127 +18,181 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# Written by Brendan O'Dea +# Written by Brendan O'Dea +# Available from ftp://ftp.gnu.org/gnu/help2man/ -use 5.004; +use 5.005; use strict; use Getopt::Long; use Text::Tabs qw(expand); use POSIX qw(strftime setlocale LC_TIME); my $this_program = 'help2man'; -my $this_version = '1.012'; +my $this_version = '1.28'; my $version_info = < +Written by Brendan O'Dea EOT my $help_info = <. EOT my $section = 1; -my ($include, $opt_name, $opt_include, $opt_output, $opt_no_info); +my $manual = ''; +my $source = ''; +my $help_option = '--help'; +my $version_option = '--version'; +my ($opt_name, @opt_include, $opt_output, $opt_info, $opt_no_info); + +my %opt_def = ( + 'n|name=s' => \$opt_name, + 's|section=s' => \$section, + 'm|manual=s' => \$manual, + 'S|source=s' => \$source, + '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, + 'h|help-option=s' => \$help_option, + 'v|version-option=s' => \$version_option, +); # Parse options. Getopt::Long::config('bundling'); -GetOptions ( - 'n|name=s' => \$opt_name, - 's|section=s' => \$section, - 'i|include=s' => \$include, - 'I|opt-include=s' => \$opt_include, - 'o|output=s' => \$opt_output, - 'N|no-info' => \$opt_no_info, - help => sub { print $help_info; exit }, - version => sub { print $version_info; exit }, +GetOptions (%opt_def, + help => sub { print $help_info; exit }, + version => sub { print $version_info; exit }, ) or die $help_info; die $help_info unless @ARGV == 1; my %include = (); -my @include = (); # to retain order +my %append = (); +my @include = (); # retain order given in include file # Process include file (if given). Format is: # -# [section name] -# verbatim text +# [section name] +# verbatim text +# +# or +# +# /pattern/ +# verbatim text +# -if ($include or $opt_include) +while (@opt_include) { - if (open INC, $include || $opt_include) + my ($inc, $required) = @{shift @opt_include}; + + next unless -f $inc or $required; + die "$this_program: can't open `$inc' ($!)\n" + unless open INC, $inc; + + my $key; + my $hash = \%include; + + while () { - my $sect; + # [section] + if (/^\[([^]]+)\]/) + { + $key = uc $1; + $key =~ s/^\s+//; + $key =~ s/\s+$//; + $hash = \%include; + push @include, $key unless $include{$key}; + next; + } - while () + # /pattern/ + if (m!^/(.*)/([ims]*)!) { - if (/^\[([^]]+)\]/) + my $pat = $2 ? "(?$2)$1" : $1; + + # Check pattern. + eval { $key = qr($pat) }; + if ($@) { - $sect = uc $1; - $sect =~ s/^\s+//; - $sect =~ s/\s+$//; - next; + $@ =~ s/ at .*? line \d.*//; + die "$inc:$.:$@"; } - # Silently ignore anything before the first - # section--allows for comments and revision info. - next unless $sect; - - push @include, $sect unless $include{$sect}; - $include{$sect} ||= ''; - $include{$sect} .= $_; + $hash = \%append; + next; } - close INC; - - die "$this_program: no valid information found in `$include'\n" - unless %include; - - # Compress trailing blank lines. - for (keys %include) + # Check for options before the first section--anything else is + # silently ignored, allowing the first for comments and + # revision info. + unless ($key) { - $include{$_} =~ s/\n+$//; - $include{$_} .= "\n" unless /^NAME$/; + # handle options + if (/^-/) + { + local @ARGV = split; + GetOptions %opt_def; + } + + next; } + + $hash->{$key} ||= ''; + $hash->{$key} .= $_; } - else - { - die "$this_program: can't open `$include' ($!)\n" if $include; - } + + close INC; + + die "$this_program: no valid information found in `$inc'\n" + unless $key; } -# Turn off localisation of executable's ouput. +# Compress trailing blank lines. +for my $hash (\(%include, %append)) +{ + for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ } +} + +# Turn off localisation of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; -# Turn off localisation of date (for strftime) +# Turn off localisation of date (for strftime). setlocale LC_TIME, 'C'; -# Expand tabs, strip trailing spaces and break into paragraphs -sub paragraphs { split /\n\n+/, join '', expand @_ } - -# Grab help and version paragraphs from executable -my @help = paragraphs `$ARGV[0] --help 2>/dev/null` - or die "$this_program: can't get `--help' info from $ARGV[0]\n"; - -my @version = paragraphs `$ARGV[0] --version 2>/dev/null` - or die "$this_program: can't get `--version' info from $ARGV[0]\n"; +# Grab help and version info from executable. +my ($help_text, $version_text) = map { + join '', map { s/ +$//; expand $_ } `$ARGV[0] $_ 2>/dev/null` + or die "$this_program: can't get `$_' info from $ARGV[0]\n" +} $help_option, $version_option; my $date = strftime "%B %Y", localtime; (my $program = $ARGV[0]) =~ s!.*/!!; @@ -165,7 +220,7 @@ if ($opt_output) # # and seperated from any copyright/author details by a blank line. -$_ = shift @version; +($_, $version_text) = split /\n+/, $version_text, 2; if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or /^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/) @@ -187,160 +242,259 @@ else $program =~ s!.*/!!; -# no info for `info' itself +# No info for `info' itself. $opt_no_info = 1 if $program eq 'info'; -# --name overrides --include contents -$include{NAME} = "$program \\- $opt_name" if $opt_name; +# --name overrides --include contents. +$include{NAME} = "$program \\- $opt_name\n" if $opt_name; -# Default (useless) NAME paragraph -$include{NAME} ||= "$program \\- manual page for $program $version"; +# Default (useless) NAME paragraph. +$include{NAME} ||= "$program \\- manual page for $program $version\n"; # Man pages traditionally have the page title in caps. my $PROGRAM = uc $program; -# Header. -print < are + # rendered in a constant width font. + if (/^( +)([\$\%>] )\S/) { - print qq(.SH "REPORTING BUGS"\n$_\n); - $break = ''; + 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"; + $break = '.br'; + } + next; } - # Option subsections have second line indented. - if (s/^(\S.*)\n / /) + my $matched = ''; + $include{$sect} ||= ''; + + # Sub-sections have a trailing colon and the second line indented. + if (s/^(\S.*:) *\n / /) { - print qq(.SS "$1"\n); - $break = ''; + $matched .= $& if %append; + $include{$sect} .= qq(.SS "$1"\n); } - my $output = ''; - while (length) - { - my $indent = 0; + my $indent = 0; + my $content = ''; - # Tagged paragraph - if (s/^( +(\S.*?) +)(\S.*)\n?//) + # Option with description. + if (s/^( {1,10}([+-]\S.*?))(?:( +(?!-))|\n( {20,}))(\S.*)\n//) + { + $matched .= $& if %append; + $indent = length ($4 || "$1$3"); + $content = ".TP\n\x83$2\n\x83$5\n"; + unless ($4) { - $indent = length $1; - $output .= ".TP\n$2\n$3\n"; - $break = 1; + # Indent may be different on second line. + $indent = length $& if /^ {20,}/; } + } - # Indented paragraph - elsif (s/^( +)(\S.*)\n?//) - { - $indent = length $1; - $output .= ".IP\n$2\n"; - $break = 1; - } + # Option without description. + elsif (s/^ {1,10}([+-]\S.*)\n//) + { + $matched .= $& if %append; + $content = ".HP\n\x83$1\n"; + $indent = 80; # not continued + } - # Left justified paragraph - else - { - s/(.*)\n?//; - $output .= ".PP\n" if $break; - $output .= "$1\n"; - $break = 1; - } + # Indented paragraph with tag. + elsif (s/^( +(\S.*?) +)(\S.*)\n//) + { + $matched .= $& if %append; + $indent = length $1; + $content = ".TP\n\x83$2\n\x83$3\n"; + } - # Continuations - $output .= "$1\n" while s/^ {$indent}(\S.*)\n?//; + # Indented paragraph. + elsif (s/^( +)(\S.*)\n//) + { + $matched .= $& if %append; + $indent = length $1; + $content = ".IP\n\x83$2\n"; } - $_ = $output; + # Left justified paragraph. + else + { + s/(.*)\n//; + $matched .= $& if %append; + $content = ".PP\n" if $include{$sect}; + $content .= "$1\n"; + } - # Convert options. - s/(^| )(-[][\w=-]+)/$1 . convert_option $2/mge; - print; -} + # Append continuations. + while (s/^ {$indent}(\S.*)\n//) + { + $matched .= $& if %append; + $content .= "\x83$1\n" + } -# Print any include items other than the ones we have already dealt -# with. -for (@include) -{ - print qq(.SH "$_"\n$include{$_}) - unless /^(NAME|SYNOPSIS|DESCRIPTION|SEE ALSO)$/; + # Move to next paragraph. + s/^\n+//; + + for ($content) + { + # Leading dot and apostrophe protection. + s/\x83\./\x80/g; + s/\x83'/\x81/g; + s/\x83//g; + + # Convert options. + s/(^| )(-[][\w=-]+)/$1 . convert_option $2/mge; + } + + # Check if matched paragraph contains /pat/. + if (%append) + { + for my $pat (keys %append) + { + if ($matched =~ $pat) + { + $content .= ".PP\n" unless $append{$pat} =~ /^\./; + $content .= $append{$pat}; + } + } + } + + $include{$sect} .= $content; } # Refer to the real documentation. -if ($include{'SEE ALSO'} or !$opt_no_info) +unless ($opt_no_info) { - print qq(.SH "SEE ALSO"\n); - print $include{'SEE ALSO'}, ".PP\n" if $include{'SEE ALSO'}; + my $info_page = $opt_info || $program; - print <