11cc83814Sespie#!/usr/local/bin/perl -w 21cc83814Sespie 31cc83814Sespie# Generate a short man page from --help and --version output. 43fb98d4aSespie# Copyright � 1997, 1998, 1999, 2000 Free Software Foundation, Inc. 51cc83814Sespie 61cc83814Sespie# This program is free software; you can redistribute it and/or modify 71cc83814Sespie# it under the terms of the GNU General Public License as published by 81cc83814Sespie# the Free Software Foundation; either version 2, or (at your option) 91cc83814Sespie# any later version. 101cc83814Sespie 111cc83814Sespie# This program is distributed in the hope that it will be useful, 121cc83814Sespie# but WITHOUT ANY WARRANTY; without even the implied warranty of 131cc83814Sespie# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141cc83814Sespie# GNU General Public License for more details. 151cc83814Sespie 161cc83814Sespie# You should have received a copy of the GNU General Public License 171cc83814Sespie# along with this program; if not, write to the Free Software Foundation, 181cc83814Sespie# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 191cc83814Sespie 201cc83814Sespie# Written by Brendan O'Dea <bod@compusol.com.au> 213fb98d4aSespie# Available from ftp://ftp.gnu.org/gnu/help2man/ 221cc83814Sespie 231cc83814Sespieuse 5.004; 241cc83814Sespieuse strict; 251cc83814Sespieuse Getopt::Long; 261cc83814Sespieuse Text::Tabs qw(expand); 271cc83814Sespieuse POSIX qw(strftime setlocale LC_TIME); 281cc83814Sespie 291cc83814Sespiemy $this_program = 'help2man'; 303fb98d4aSespiemy $this_version = '1.24'; 311cc83814Sespiemy $version_info = <<EOT; 323fb98d4aSespieGNU $this_program $this_version 331cc83814Sespie 343fb98d4aSespieCopyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. 351cc83814SespieThis is free software; see the source for copying conditions. There is NO 361cc83814Sespiewarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 371cc83814Sespie 381cc83814SespieWritten by Brendan O'Dea <bod\@compusol.com.au> 391cc83814SespieEOT 401cc83814Sespie 411cc83814Sespiemy $help_info = <<EOT; 421cc83814Sespie`$this_program' generates a man page out of `--help' and `--version' output. 431cc83814Sespie 441cc83814SespieUsage: $this_program [OPTION]... EXECUTABLE 451cc83814Sespie 461cc83814Sespie -n, --name=STRING use `STRING' as the description for the NAME paragraph 471cc83814Sespie -s, --section=SECTION use `SECTION' as the section for the man page 481cc83814Sespie -i, --include=FILE include material from `FILE' 491cc83814Sespie -I, --opt-include=FILE include material from `FILE' if it exists 501cc83814Sespie -o, --output=FILE send output to `FILE' 511cc83814Sespie -N, --no-info suppress pointer to Texinfo manual 521cc83814Sespie --help print this help, then exit 533fb98d4aSespie --version print version number, then exit 541cc83814Sespie 551cc83814SespieEXECUTABLE should accept `--help' and `--version' options. 563fb98d4aSespie 573fb98d4aSespieReport bugs to <bug-help2man\@gnu.org>. 581cc83814SespieEOT 591cc83814Sespie 601cc83814Sespiemy $section = 1; 613fb98d4aSespiemy ($opt_name, @opt_include, $opt_output, $opt_no_info); 623fb98d4aSespiemy %opt_def = ( 633fb98d4aSespie 'n|name=s' => \$opt_name, 643fb98d4aSespie 's|section=s' => \$section, 653fb98d4aSespie 'i|include=s' => sub { push @opt_include, [ pop, 1 ] }, 663fb98d4aSespie 'I|opt-include=s' => sub { push @opt_include, [ pop, 0 ] }, 673fb98d4aSespie 'o|output=s' => \$opt_output, 683fb98d4aSespie 'N|no-info' => \$opt_no_info, 693fb98d4aSespie); 701cc83814Sespie 711cc83814Sespie# Parse options. 721cc83814SespieGetopt::Long::config('bundling'); 733fb98d4aSespieGetOptions (%opt_def, 741cc83814Sespie help => sub { print $help_info; exit }, 751cc83814Sespie version => sub { print $version_info; exit }, 761cc83814Sespie) or die $help_info; 771cc83814Sespie 781cc83814Sespiedie $help_info unless @ARGV == 1; 791cc83814Sespie 801cc83814Sespiemy %include = (); 813fb98d4aSespiemy %append = (); 823fb98d4aSespiemy @include = (); # retain order given in include file 833fb98d4aSespie 843fb98d4aSespie# Provide replacement `quote-regex' operator for pre-5.005. 853fb98d4aSespieBEGIN { eval q(sub qr { '' =~ $_[0]; $_[0] }) if $] < 5.005 } 861cc83814Sespie 871cc83814Sespie# Process include file (if given). Format is: 881cc83814Sespie# 891cc83814Sespie# [section name] 901cc83814Sespie# verbatim text 913fb98d4aSespie# 923fb98d4aSespie# or 933fb98d4aSespie# 943fb98d4aSespie# /pattern/ 953fb98d4aSespie# verbatim text 963fb98d4aSespie# 971cc83814Sespie 983fb98d4aSespiewhile (@opt_include) 991cc83814Sespie{ 1003fb98d4aSespie my ($inc, $required) = @{shift @opt_include}; 1013fb98d4aSespie 1023fb98d4aSespie next unless -f $inc or $required; 1033fb98d4aSespie die "$this_program: can't open `$inc' ($!)\n" 1043fb98d4aSespie unless open INC, $inc; 1053fb98d4aSespie 1063fb98d4aSespie my $key; 1073fb98d4aSespie my $hash = \%include; 1081cc83814Sespie 1091cc83814Sespie while (<INC>) 1101cc83814Sespie { 1113fb98d4aSespie # [section] 1121cc83814Sespie if (/^\[([^]]+)\]/) 1131cc83814Sespie { 1143fb98d4aSespie $key = uc $1; 1153fb98d4aSespie $key =~ s/^\s+//; 1163fb98d4aSespie $key =~ s/\s+$//; 1173fb98d4aSespie $hash = \%include; 1183fb98d4aSespie push @include, $key unless $include{$key}; 1191cc83814Sespie next; 1201cc83814Sespie } 1211cc83814Sespie 1223fb98d4aSespie # /pattern/ 1233fb98d4aSespie if (m!^/(.*)/([ims]*)!) 1243fb98d4aSespie { 1253fb98d4aSespie my $pat = $2 ? "(?$2)$1" : $1; 1261cc83814Sespie 1273fb98d4aSespie # Check pattern. 1283fb98d4aSespie eval { $key = qr($pat) }; 1293fb98d4aSespie if ($@) 1303fb98d4aSespie { 1313fb98d4aSespie $@ =~ s/ at .*? line \d.*//; 1323fb98d4aSespie die "$inc:$.:$@"; 1333fb98d4aSespie } 1343fb98d4aSespie 1353fb98d4aSespie $hash = \%append; 1363fb98d4aSespie next; 1373fb98d4aSespie } 1383fb98d4aSespie 1393fb98d4aSespie # Check for options before the first section--anything else is 1403fb98d4aSespie # silently ignored, allowing the first for comments and 1413fb98d4aSespie # revision info. 1423fb98d4aSespie unless ($key) 1433fb98d4aSespie { 1443fb98d4aSespie # handle options 1453fb98d4aSespie if (/^-/) 1463fb98d4aSespie { 1473fb98d4aSespie local @ARGV = split; 1483fb98d4aSespie GetOptions %opt_def; 1493fb98d4aSespie } 1503fb98d4aSespie 1513fb98d4aSespie next; 1523fb98d4aSespie } 1533fb98d4aSespie 1543fb98d4aSespie $hash->{$key} ||= ''; 1553fb98d4aSespie $hash->{$key} .= $_; 1561cc83814Sespie } 1571cc83814Sespie 1581cc83814Sespie close INC; 1591cc83814Sespie 1603fb98d4aSespie die "$this_program: no valid information found in `$inc'\n" 1613fb98d4aSespie unless $key; 1623fb98d4aSespie} 1631cc83814Sespie 1641cc83814Sespie# Compress trailing blank lines. 1653fb98d4aSespiefor my $hash (\(%include, %append)) 1661cc83814Sespie{ 1673fb98d4aSespie for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ } 1681cc83814Sespie} 1691cc83814Sespie 170*c0141d96Sderaadt# Turn off localisation of executable's output. 1711cc83814Sespie@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; 1721cc83814Sespie 1733fb98d4aSespie# Turn off localisation of date (for strftime). 1741cc83814Sespiesetlocale LC_TIME, 'C'; 1751cc83814Sespie 1763fb98d4aSespie# Grab help and version info from executable. 1773fb98d4aSespiemy ($help_text, $version_text) = map { 1783fb98d4aSespie join '', map { s/ +$//; expand $_ } `$ARGV[0] --$_ 2>/dev/null` 1793fb98d4aSespie or die "$this_program: can't get `--$_' info from $ARGV[0]\n" 1803fb98d4aSespie} qw(help version); 1811cc83814Sespie 1821cc83814Sespiemy $date = strftime "%B %Y", localtime; 1831cc83814Sespie(my $program = $ARGV[0]) =~ s!.*/!!; 1841cc83814Sespiemy $package = $program; 1851cc83814Sespiemy $version; 1861cc83814Sespie 1871cc83814Sespieif ($opt_output) 1881cc83814Sespie{ 1891cc83814Sespie unlink $opt_output 1901cc83814Sespie or die "$this_program: can't unlink $opt_output ($!)\n" 1911cc83814Sespie if -e $opt_output; 1921cc83814Sespie 1931cc83814Sespie open STDOUT, ">$opt_output" 1941cc83814Sespie or die "$this_program: can't create $opt_output ($!)\n"; 1951cc83814Sespie} 1961cc83814Sespie 1971cc83814Sespie# The first line of the --version information is assumed to be in one 1981cc83814Sespie# of the following formats: 1991cc83814Sespie# 2001cc83814Sespie# <version> 2011cc83814Sespie# <program> <version> 2021cc83814Sespie# {GNU,Free} <program> <version> 2031cc83814Sespie# <program> ({GNU,Free} <package>) <version> 2041cc83814Sespie# <program> - {GNU,Free} <package> <version> 2051cc83814Sespie# 2061cc83814Sespie# and seperated from any copyright/author details by a blank line. 2071cc83814Sespie 2083fb98d4aSespie($_, $version_text) = split /\n+/, $version_text, 2; 2091cc83814Sespie 2101cc83814Sespieif (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or 2111cc83814Sespie /^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/) 2121cc83814Sespie{ 2131cc83814Sespie $program = $1; 2141cc83814Sespie $package = $2; 2151cc83814Sespie $version = $3; 2161cc83814Sespie} 2171cc83814Sespieelsif (/^((?:GNU|Free) +)?(\S+) +(.*)/) 2181cc83814Sespie{ 2191cc83814Sespie $program = $2; 2201cc83814Sespie $package = $1 ? "$1$2" : $2; 2211cc83814Sespie $version = $3; 2221cc83814Sespie} 2231cc83814Sespieelse 2241cc83814Sespie{ 2251cc83814Sespie $version = $_; 2261cc83814Sespie} 2271cc83814Sespie 2281cc83814Sespie$program =~ s!.*/!!; 2291cc83814Sespie 2303fb98d4aSespie# No info for `info' itself. 2311cc83814Sespie$opt_no_info = 1 if $program eq 'info'; 2321cc83814Sespie 2333fb98d4aSespie# --name overrides --include contents. 2343fb98d4aSespie$include{NAME} = "$program \\- $opt_name\n" if $opt_name; 2351cc83814Sespie 2363fb98d4aSespie# Default (useless) NAME paragraph. 2373fb98d4aSespie$include{NAME} ||= "$program \\- manual page for $program $version\n"; 2381cc83814Sespie 2391cc83814Sespie# Man pages traditionally have the page title in caps. 2401cc83814Sespiemy $PROGRAM = uc $program; 2411cc83814Sespie 2423fb98d4aSespie# Extract usage clause(s) [if any] for SYNOPSIS. 2433fb98d4aSespieif ($help_text =~ s/^Usage:( +(\S+))(.*)((?:\n(?: {6}\1| *or: +\S).*)*)//m) 2443fb98d4aSespie{ 2453fb98d4aSespie my @syn = $2 . $3; 2461cc83814Sespie 2473fb98d4aSespie if ($_ = $4) 2483fb98d4aSespie { 2493fb98d4aSespie s/^\n//; 2503fb98d4aSespie for (split /\n/) { s/^ *(or: +)?//; push @syn, $_ } 2513fb98d4aSespie } 2523fb98d4aSespie 2533fb98d4aSespie my $synopsis = ''; 2543fb98d4aSespie for (@syn) 2553fb98d4aSespie { 2563fb98d4aSespie $synopsis .= ".br\n" if $synopsis; 2573fb98d4aSespie s!^\S*/!!; 2583fb98d4aSespie s/^(\S+) *//; 2593fb98d4aSespie $synopsis .= ".B $1\n"; 2603fb98d4aSespie s/\s+$//; 2613fb98d4aSespie s/(([][]|\.\.+)+)/\\fR$1\\fI/g; 2623fb98d4aSespie s/^/\\fI/ unless s/^\\fR//; 2633fb98d4aSespie $_ .= '\fR'; 2643fb98d4aSespie s/(\\fI)( *)/$2$1/g; 2653fb98d4aSespie s/\\fI\\fR//g; 2663fb98d4aSespie s/^\\fR//; 2673fb98d4aSespie s/\\fI$//; 2683fb98d4aSespie s/^\./\\&./; 2693fb98d4aSespie 2703fb98d4aSespie $synopsis .= "$_\n"; 2713fb98d4aSespie } 2723fb98d4aSespie 2733fb98d4aSespie $include{SYNOPSIS} ||= $synopsis; 2743fb98d4aSespie} 2753fb98d4aSespie 2763fb98d4aSespie# Process text, initial section is DESCRIPTION. 2773fb98d4aSespiemy $sect = 'DESCRIPTION'; 2783fb98d4aSespie$_ = "$help_text\n\n$version_text"; 2793fb98d4aSespie 2803fb98d4aSespie# Normalise paragraph breaks. 2813fb98d4aSespies/^\n+//; 2823fb98d4aSespies/\n*$/\n/; 2833fb98d4aSespies/\n\n+/\n\n/g; 2843fb98d4aSespie 2853fb98d4aSespie# Temporarily exchange leading dots, apostrophes and backslashes for 2863fb98d4aSespie# tokens. 2873fb98d4aSespies/^\./\x80/mg; 2883fb98d4aSespies/^'/\x81/mg; 2893fb98d4aSespies/\\/\x82/g; 2903fb98d4aSespie 2913fb98d4aSespie# Start a new paragraph (if required) for these. 2923fb98d4aSespies/([^\n])\n(Report +bugs|Email +bug +reports +to|Written +by)/$1\n\n$2/g; 2931cc83814Sespie 2941cc83814Sespiesub convert_option; 2951cc83814Sespie 2963fb98d4aSespiewhile (length) 2971cc83814Sespie{ 2983fb98d4aSespie # Convert some standard paragraph names. 2993fb98d4aSespie if (s/^(Options|Examples): *\n//) 3001cc83814Sespie { 3013fb98d4aSespie $sect = uc $1; 3021cc83814Sespie next; 3031cc83814Sespie } 3041cc83814Sespie 3053fb98d4aSespie # Copyright section 3063fb98d4aSespie if (/^Copyright +[(\xa9]/) 3071cc83814Sespie { 3083fb98d4aSespie $sect = 'COPYRIGHT'; 3093fb98d4aSespie $include{$sect} ||= ''; 3103fb98d4aSespie $include{$sect} .= ".PP\n" if $include{$sect}; 3113fb98d4aSespie 3123fb98d4aSespie my $copy; 3133fb98d4aSespie ($copy, $_) = split /\n\n/, $_, 2; 3143fb98d4aSespie 3153fb98d4aSespie for ($copy) 3163fb98d4aSespie { 3173fb98d4aSespie # Add back newline 3183fb98d4aSespie s/\n*$/\n/; 3193fb98d4aSespie 3203fb98d4aSespie # Convert iso9959-1 copyright symbol or (c) to nroff 3213fb98d4aSespie # character. 3223fb98d4aSespie s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg; 3233fb98d4aSespie 3243fb98d4aSespie # Insert line breaks before additional copyright messages 3253fb98d4aSespie # and the disclaimer. 3263fb98d4aSespie s/(.)\n(Copyright |This +is +free +software)/$1\n.br\n$2/g; 3273fb98d4aSespie 3283fb98d4aSespie # Join hyphenated lines. 3293fb98d4aSespie s/([A-Za-z])-\n */$1/g; 3303fb98d4aSespie } 3313fb98d4aSespie 3323fb98d4aSespie $include{$sect} .= $copy; 3333fb98d4aSespie $_ ||= ''; 3343fb98d4aSespie next; 3351cc83814Sespie } 3361cc83814Sespie 3371cc83814Sespie # Catch bug report text. 3383fb98d4aSespie if (/^(Report +bugs|Email +bug +reports +to) /) 3391cc83814Sespie { 3403fb98d4aSespie $sect = 'REPORTING BUGS'; 3413fb98d4aSespie } 3423fb98d4aSespie 3433fb98d4aSespie # Author section. 3443fb98d4aSespie elsif (/^Written +by/) 3453fb98d4aSespie { 3463fb98d4aSespie $sect = 'AUTHOR'; 3473fb98d4aSespie } 3483fb98d4aSespie 3493fb98d4aSespie # Examples, indicated by an indented leading $, % or > are 3503fb98d4aSespie # rendered in a constant width font. 3513fb98d4aSespie if (/^( +)([\$\%>] )\S/) 3523fb98d4aSespie { 3533fb98d4aSespie my $indent = $1; 3543fb98d4aSespie my $prefix = $2; 3553fb98d4aSespie my $break = '.IP'; 3563fb98d4aSespie $include{$sect} ||= ''; 3573fb98d4aSespie while (s/^$indent\Q$prefix\E(\S.*)\n*//) 3583fb98d4aSespie { 3593fb98d4aSespie $include{$sect} .= "$break\n\\f(CW$prefix$1\\fR\n"; 3603fb98d4aSespie $break = '.br'; 3613fb98d4aSespie } 3623fb98d4aSespie 3631cc83814Sespie next; 3641cc83814Sespie } 3651cc83814Sespie 3663fb98d4aSespie my $matched = ''; 3673fb98d4aSespie $include{$sect} ||= ''; 3683fb98d4aSespie 3693fb98d4aSespie # Sub-sections have a trailing colon and the second line indented. 3703fb98d4aSespie if (s/^(\S.*:) *\n / /) 3711cc83814Sespie { 3723fb98d4aSespie $matched .= $& if %append; 3733fb98d4aSespie $include{$sect} .= qq(.SS "$1"\n); 3741cc83814Sespie } 3751cc83814Sespie 3761cc83814Sespie my $indent = 0; 3773fb98d4aSespie my $content = ''; 3781cc83814Sespie 3793fb98d4aSespie # Option with description. 3803fb98d4aSespie if (s/^( {1,10}([+-]\S.*?))(?:( +)|\n( {20,}))(\S.*)\n//) 3811cc83814Sespie { 3823fb98d4aSespie $matched .= $& if %append; 3833fb98d4aSespie $indent = length ($4 || "$1$3"); 3843fb98d4aSespie $content = ".TP\n\x83$2\n\x83$5\n"; 3853fb98d4aSespie unless ($4) 3863fb98d4aSespie { 3873fb98d4aSespie # Indent may be different on second line. 3883fb98d4aSespie $indent = length $& if /^ {20,}/; 3893fb98d4aSespie } 3901cc83814Sespie } 3911cc83814Sespie 3923fb98d4aSespie # Option without description. 3933fb98d4aSespie elsif (s/^ {1,10}([+-]\S.*)\n//) 3941cc83814Sespie { 3953fb98d4aSespie $matched .= $& if %append; 3963fb98d4aSespie $content = ".HP\n\x83$1\n"; 3973fb98d4aSespie $indent = 80; # not continued 3981cc83814Sespie } 3991cc83814Sespie 4003fb98d4aSespie # Indented paragraph with tag. 4013fb98d4aSespie elsif (s/^( +(\S.*?) +)(\S.*)\n//) 4023fb98d4aSespie { 4033fb98d4aSespie $matched .= $& if %append; 4043fb98d4aSespie $indent = length $1; 4053fb98d4aSespie $content = ".TP\n\x83$2\n\x83$3\n"; 4063fb98d4aSespie } 4073fb98d4aSespie 4083fb98d4aSespie # Indented paragraph. 4093fb98d4aSespie elsif (s/^( +)(\S.*)\n//) 4103fb98d4aSespie { 4113fb98d4aSespie $matched .= $& if %append; 4123fb98d4aSespie $indent = length $1; 4133fb98d4aSespie $content = ".IP\n\x83$2\n"; 4143fb98d4aSespie } 4153fb98d4aSespie 4163fb98d4aSespie # Left justified paragraph. 4171cc83814Sespie else 4181cc83814Sespie { 4193fb98d4aSespie s/(.*)\n//; 4203fb98d4aSespie $matched .= $& if %append; 4213fb98d4aSespie $content = ".PP\n" if $include{$sect}; 4223fb98d4aSespie $content .= "$1\n"; 4231cc83814Sespie } 4241cc83814Sespie 4253fb98d4aSespie # Append continuations. 4263fb98d4aSespie while (s/^ {$indent}(\S.*)\n//) 4273fb98d4aSespie { 4283fb98d4aSespie $matched .= $& if %append; 4293fb98d4aSespie $content .= "\x83$1\n" 4301cc83814Sespie } 4311cc83814Sespie 4323fb98d4aSespie # Move to next paragraph. 4333fb98d4aSespie s/^\n+//; 4341cc83814Sespie 4353fb98d4aSespie for ($content) 4363fb98d4aSespie { 4373fb98d4aSespie # Leading dot and apostrophe protection. 4383fb98d4aSespie s/\x83\./\x80/g; 4393fb98d4aSespie s/\x83'/\x81/g; 4403fb98d4aSespie s/\x83//g; 4411cc83814Sespie 4421cc83814Sespie # Convert options. 4431cc83814Sespie s/(^| )(-[][\w=-]+)/$1 . convert_option $2/mge; 4441cc83814Sespie } 4451cc83814Sespie 4463fb98d4aSespie # Check if matched paragraph contains /pat/. 4473fb98d4aSespie if (%append) 4481cc83814Sespie { 4493fb98d4aSespie for my $pat (keys %append) 4503fb98d4aSespie { 4513fb98d4aSespie if ($matched =~ $pat) 4523fb98d4aSespie { 4533fb98d4aSespie $content .= ".PP\n" unless $append{$pat} =~ /^\./; 4543fb98d4aSespie $content .= $append{$pat}; 4553fb98d4aSespie } 4563fb98d4aSespie } 4573fb98d4aSespie } 4583fb98d4aSespie 4593fb98d4aSespie $include{$sect} .= $content; 4601cc83814Sespie} 4611cc83814Sespie 4621cc83814Sespie# Refer to the real documentation. 4633fb98d4aSespieunless ($opt_no_info) 4641cc83814Sespie{ 4653fb98d4aSespie $sect = 'SEE ALSO'; 4663fb98d4aSespie $include{$sect} ||= ''; 4673fb98d4aSespie $include{$sect} .= ".PP\n" if $include{$sect}; 4683fb98d4aSespie $include{$sect} .= <<EOT; 4691cc83814SespieThe full documentation for 4701cc83814Sespie.B $program 4711cc83814Sespieis maintained as a Texinfo manual. If the 4721cc83814Sespie.B info 4731cc83814Sespieand 4741cc83814Sespie.B $program 4751cc83814Sespieprograms are properly installed at your site, the command 4761cc83814Sespie.IP 4771cc83814Sespie.B info $program 4781cc83814Sespie.PP 4791cc83814Sespieshould give you access to the complete manual. 4801cc83814SespieEOT 4811cc83814Sespie} 4821cc83814Sespie 4833fb98d4aSespie# Output header. 4843fb98d4aSespieprint <<EOT; 4853fb98d4aSespie.\\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version. 4863fb98d4aSespie.TH $PROGRAM "$section" "$date" "$package $version" FSF 4873fb98d4aSespieEOT 4883fb98d4aSespie 4893fb98d4aSespie# Section ordering. 4903fb98d4aSespiemy @pre = qw(NAME SYNOPSIS DESCRIPTION OPTIONS EXAMPLES); 4913fb98d4aSespiemy @post = ('AUTHOR', 'REPORTING BUGS', 'COPYRIGHT', 'SEE ALSO'); 4923fb98d4aSespiemy $filter = join '|', @pre, @post; 4933fb98d4aSespie 4943fb98d4aSespie# Output content. 4953fb98d4aSespiefor (@pre, (grep ! /^($filter)$/o, @include), @post) 4961cc83814Sespie{ 4973fb98d4aSespie if ($include{$_}) 4983fb98d4aSespie { 4993fb98d4aSespie my $quote = /\W/ ? '"' : ''; 5003fb98d4aSespie print ".SH $quote$_$quote\n"; 5011cc83814Sespie 5023fb98d4aSespie for ($include{$_}) 5033fb98d4aSespie { 5043fb98d4aSespie # Replace leading dot, apostrophe and backslash tokens. 5053fb98d4aSespie s/\x80/\\&./g; 5063fb98d4aSespie s/\x81/\\&'/g; 5073fb98d4aSespie s/\x82/\\e/g; 5083fb98d4aSespie print; 5093fb98d4aSespie } 5103fb98d4aSespie } 5111cc83814Sespie} 5121cc83814Sespie 5131cc83814Sespieexit; 5141cc83814Sespie 5151cc83814Sespie# Convert option dashes to \- to stop nroff from hyphenating 'em, and 5161cc83814Sespie# embolden. Option arguments get italicised. 5171cc83814Sespiesub convert_option 5181cc83814Sespie{ 5193fb98d4aSespie local $_ = '\fB' . shift; 5201cc83814Sespie 5213fb98d4aSespie s/-/\\-/g; 5223fb98d4aSespie unless (s/\[=(.*)\]$/\\fR[=\\fI$1\\fR]/) 5231cc83814Sespie { 5243fb98d4aSespie s/=(.)/\\fR=\\fI$1/; 5253fb98d4aSespie s/ (.)/ \\fI$1/; 5263fb98d4aSespie $_ .= '\fR'; 5271cc83814Sespie } 5281cc83814Sespie 5293fb98d4aSespie $_; 5301cc83814Sespie} 531