perl 5.003_07: pod/perlvar.pod
[p5sagit/p5-mst-13.2.git] / pod / pod2man.PL
CommitLineData
4633a7c4 1#!/usr/local/bin/perl
2
3use Config;
4use File::Basename qw(&basename &dirname);
5
6# List explicitly here the variables you want Configure to
7# generate. Metaconfig only looks for shell variables, so you
8# have to mention them as if they were shell variables, not
9# %Config entries. Thus you write
10# $startperl
11# to ensure Configure will look for $Config{startperl}.
12
13# This forces PL files to create target in same directory as PL file.
14# This is so that make depend always knows where to find PL derivatives.
15chdir(dirname($0));
16($file = basename($0)) =~ s/\.PL$//;
17$file =~ s/\.pl$//
f360dba1 18 if ($^O eq 'VMS' or $^O eq 'os2'); # "case-forgiving"
4633a7c4 19
20open OUT,">$file" or die "Can't create $file: $!";
21
22print "Extracting $file (with variable substitutions)\n";
23
24# In this section, perl variables will be expanded during extraction.
25# You can use $Config{...} to use Configure variables.
26
27print OUT <<"!GROK!THIS!";
28$Config{'startperl'}
5d94fbed 29!GROK!THIS!
30
4633a7c4 31# In the following, perl variables are not expanded during extraction.
32
33print OUT <<'!NO!SUBS!';
cb1a09d0 34eval 'exec perl -S $0 "$@"'
35 if 0;
36
37=head1 NAME
38
39pod2man - translate embedded Perl pod directives into man pages
40
41=head1 SYNOPSIS
42
43B<pod2man>
44[ B<--section=>I<manext> ]
45[ B<--release=>I<relpatch> ]
46[ B<--center=>I<string> ]
47[ B<--date=>I<string> ]
48[ B<--fixed=>I<font> ]
49[ B<--official> ]
50I<inputfile>
51
52=head1 DESCRIPTION
53
54B<pod2man> converts its input file containing embedded pod directives (see
55L<perlpod>) into nroff source suitable for viewing with nroff(1) or
56troff(1) using the man(7) macro set.
57
58Besides the obvious pod conversions, B<pod2man> also takes care of
59func(), func(n), and simple variable references like $foo or @bar so
60you don't have to use code escapes for them; complex expressions like
61C<$fred{'stuff'}> will still need to be escaped, though. Other nagging
62little roffish things that it catches include translating the minus in
63something like foo-bar, making a long dash--like this--into a real em
64dash, fixing up "paired quotes", putting a little space after the
65parens in something like func(), making C++ and PI look right, making
66double underbars have a little tiny space between them, making ALLCAPS
67a teeny bit smaller in troff(1), and escaping backslashes so you don't
68have to.
69
70=head1 OPTIONS
71
72=over 8
73
74=item center
75
76Set the centered header to a specific string. The default is
77"User Contributed Perl Documentation", unless the C<--official> flag is
78given, in which case the default is "Perl Programmers Reference Guide".
79
80=item date
81
82Set the left-hand footer string to this value. By default,
83the modification date of the input file will be used.
84
85=item fixed
86
87The fixed font to use for code refs. Defaults to CW.
88
89=item official
90
91Set the default header to indicate that this page is of
92the standard release in case C<--center> is not given.
93
94=item release
95
96Set the centered footer. By default, this is the current
97perl release.
98
99=item section
100
101Set the section for the C<.TH> macro. The standard conventions on
102sections are to use 1 for user commands, 2 for system calls, 3 for
103functions, 4 for devices, 5 for file formats, 6 for games, 7 for
104miscellaneous information, and 8 for administrator commands. This works
105best if you put your Perl man pages in a separate tree, like
106F</usr/local/perl/man/>. By default, section 1 will be used
107unless the file ends in F<.pm> in which case section 3 will be selected.
108
109=back
110
111=head1 Anatomy of a Proper Man Page
112
113For those not sure of the proper layout of a man page, here's
114an example of the skeleton of a proper man page. Head of the
115major headers should be setout as a C<=head1> directive, and
116are historically written in the rather startling ALL UPPER CASE
117format, although this is not mandatory.
118Minor headers may be included using C<=head2>, and are
119typically in mixed case.
120
121=over 10
122
123=item NAME
124
125Mandatory section; should be a comma-separated list of programs or
126functions documented by this podpage, such as:
127
128 foo, bar - programs to do something
129
130=item SYNOPSIS
131
132A short usage summary for programs and functions, which
133may someday be deemed mandatory.
134
135=item DESCRIPTION
136
137Long drawn out discussion of the program. It's a good idea to break this
138up into subsections using the C<=head2> directives, like
139
140 =head2 A Sample Subection
141
142 =head2 Yet Another Sample Subection
143
144=item OPTIONS
145
146Some people make this separate from the description.
147
148=item RETURN VALUE
149
150What the program or function returns if successful.
151
152=item ERRORS
153
154Exceptions, return codes, exit stati, and errno settings.
155
156=item EXAMPLES
157
158Give some example uses of the program.
159
160=item ENVIRONMENT
161
162Envariables this program might care about.
163
164=item FILES
165
166All files used by the program. You should probably use the FE<lt>E<gt>
167for these.
168
169=item SEE ALSO
170
171Other man pages to check out, like man(1), man(7), makewhatis(8), or catman(8).
172
173=item NOTES
174
175Miscellaneous commentary.
176
177=item CAVEATS
178
179Things to take special care with; sometimes called WARNINGS.
180
181=item DIAGNOSTICS
182
183All possible messages the program can print out--and
184what they mean.
185
186=item BUGS
187
188Things that are broken or just don't work quite right.
189
190=item RESTRICTIONS
191
192Bugs you don't plan to fix :-)
193
194=item AUTHOR
195
196Who wrote it (or AUTHORS if multiple).
197
198=item HISTORY
199
200Programs derived from other sources sometimes have this, or
e52f39a2 201you might keep a modification log here.
cb1a09d0 202
203=back
204
205=head1 EXAMPLES
206
207 pod2man program > program.1
208 pod2man some_module.pm > /usr/perl/man/man3/some_module.3
209 pod2man --section=7 note.pod > note.7
210
211=head1 DIAGNOSTICS
212
213The following diagnostics are generated by B<pod2man>. Items
214marked "(W)" are non-fatal, whereas the "(F)" errors will cause
215B<pod2man> to immediately exit with a non-zero status.
216
217=over 4
218
219=item bad option in paragraph %d of %s: ``%s'' should be [%s]<%s>
220
221(W) If you start include an option, you should set it off
222as bold, italic, or code.
223
224=item can't open %s: %s
225
226(F) The input file wasn't available for the given reason.
227
cb1a09d0 228=item Improper man page - no dash in NAME header in paragraph %d of %s
229
230(W) The NAME header did not have an isolated dash in it. This is
231considered important.
232
233=item Invalid man page - no NAME line in %s
234
235(F) You did not include a NAME header, which is essential.
236
237=item roff font should be 1 or 2 chars, not `%s' (F)
238
239(F) The font specified with the C<--fixed> option was not
240a one- or two-digit roff font.
241
242=item %s is missing required section: %s
243
244(W) Required sections include NAME, DESCRIPTION, and if you're
245using a section starting with a 3, also a SYNOPSIS. Actually,
246not having a NAME is a fatal.
247
248=item Unknown escape: %s in %s
249
250(W) An unknown HTML entity (probably for an 8-bit character) was given via
e52f39a2 251a C<EE<lt>E<gt>> directive. Besides amp, lt, gt, and quot, recognized
cb1a09d0 252entities are Aacute, aacute, Acirc, acirc, AElig, aelig, Agrave, agrave,
253Aring, aring, Atilde, atilde, Auml, auml, Ccedil, ccedil, Eacute, eacute,
254Ecirc, ecirc, Egrave, egrave, ETH, eth, Euml, euml, Iacute, iacute, Icirc,
255icirc, Igrave, igrave, Iuml, iuml, Ntilde, ntilde, Oacute, oacute, Ocirc,
256ocirc, Ograve, ograve, Oslash, oslash, Otilde, otilde, Ouml, ouml, szlig,
257THORN, thorn, Uacute, uacute, Ucirc, ucirc, Ugrave, ugrave, Uuml, uuml,
258Yacute, yacute, and yuml.
259
260=item Unmatched =back
261
262(W) You have a C<=back> without a corresponding C<=over>.
263
264=item Unrecognized pod directive: %s
265
266(W) You specified a pod directive that isn't in the known list of
267C<=head1>, C<=head2>, C<=item>, C<=over>, C<=back>, or C<=cut>.
268
269
270=back
271
272=head1 NOTES
273
274If you would like to print out a lot of man page continuously, you
275probably want to set the C and D registers to set contiguous page
e52f39a2 276numbering and even/odd paging, at least on some versions of man(7).
cb1a09d0 277Settting the F register will get you some additional experimental
278indexing:
279
280 troff -man -rC1 -rD1 -rF1 perl.1 perldata.1 perlsyn.1 ...
281
282The indexing merely outputs messages via C<.tm> for each
283major page, section, subsection, item, and any C<XE<lt>E<gt>>
284directives.
285
286
287=head1 RESTRICTIONS
288
3dd51965 289None at this time.
cb1a09d0 290
291=head1 BUGS
292
293The =over and =back directives don't really work right. They
294take absolute positions instead of offsets, don't nest well, and
295making people count is suboptimal in any event.
296
297=head1 AUTHORS
298
299Original prototype by Larry Wall, but so massively hacked over by
300Tom Christiansen such that Larry probably doesn't recognize it anymore.
301
302=cut
a0d0e21e 303
304$/ = "";
305$cutting = 1;
306
3dd51965 307# We try first to get the version number from a local binary, in case we're
308# running an installed version of Perl to produce documentation from an
309# uninstalled newer version's pod files.
310if ($^O ne 'plan9') {
311 ($version,$patch) =
312 `\PATH=.:..:\$PATH; perl -v` =~ /version (\d\.\d{3})(?:_(\d{2}))?/;
313}
314# No luck; we'll just go with the running Perl's version
315($version,$patch) = $] =~ /^(.{5})(\d{2})?/ unless $version;
cb1a09d0 316$DEF_RELEASE = "perl $version";
317$DEF_RELEASE .= ", patch $patch" if $patch;
318
319
320sub makedate {
321 my $secs = shift;
322 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($secs);
323 my $mname = (qw{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec})[$mon];
324 return "$mday/$mname/$year";
a0d0e21e 325}
326
cb1a09d0 327use Getopt::Long;
328
329$DEF_SECTION = 1;
330$DEF_CENTER = "User Contributed Perl Documentation";
331$STD_CENTER = "Perl Programmers Reference Guide";
332$DEF_FIXED = 'CW';
333
334sub usage {
335 warn "$0: @_\n" if @_;
336 die <<EOF;
337usage: $0 [options] podpage
338Options are:
339 --section=manext (default "$DEF_SECTION")
340 --release=relpatch (default "$DEF_RELEASE")
341 --center=string (default "$DEF_CENTER")
342 --date=string (default "$DEF_DATE")
343 --fixed=font (default "$DEF_FIXED")
344 --official (default NOT)
345EOF
346}
347
348$uok = GetOptions( qw(
349 section=s
350 release=s
351 center=s
352 date=s
353 fixed=s
354 official
355 help));
356
357$DEF_DATE = makedate((stat($ARGV[0]))[9] || time());
358
359usage("Usage error!") unless $uok;
360usage() if $opt_help;
361usage("Need one and only one podpage argument") unless @ARGV == 1;
362
363$section = $opt_section || ($ARGV[0] =~ /\.pm$/ ? 3 : $DEF_SECTION);
364$RP = $opt_release || $DEF_RELEASE;
365$center = $opt_center || ($opt_official ? $STD_CENTER : $DEF_CENTER);
366
367$CFont = $opt_fixed || $DEF_FIXED;
368
a0d0e21e 369if (length($CFont) == 2) {
370 $CFont_embed = "\\f($CFont";
cb1a09d0 371}
a0d0e21e 372elsif (length($CFont) == 1) {
373 $CFont_embed = "\\f$CFont";
cb1a09d0 374}
a0d0e21e 375else {
cb1a09d0 376 die "roff font should be 1 or 2 chars, not `$CFont_embed'";
377}
378
379$section = $opt_section || $DEF_SECTION;
380$date = $opt_date || $DEF_DATE;
381
382for (qw{NAME DESCRIPTION}) {
383# for (qw{NAME DESCRIPTION AUTHOR}) {
384 $wanna_see{$_}++;
385}
386$wanna_see{SYNOPSIS}++ if $section =~ /^3/;
387
a0d0e21e 388
cb1a09d0 389$name = @ARGV ? $ARGV[0] : "<STDIN>";
390$Filename = $name;
391$name = uc($name) if $section =~ /^1/;
9430eed9 392$name =~ s/\.[^.]*$//;
e52f39a2 393$name =~ s(/)(::)g; # translate Getopt/Long to Getopt::Long, etc.
a0d0e21e 394
cb1a09d0 395if ($name ne 'something') {
396 FCHECK: {
397 open(F, "< $ARGV[0]") || die "can't open $ARGV[0]: $!";
398 while (<F>) {
f360dba1 399 next unless /^=\b/;
cb1a09d0 400 if (/^=head1\s+NAME\s*$/) { # an /m would forgive mistakes
401 $_ = <F>;
402 unless (/\s*-+\s+/) {
403 $oops++;
f360dba1 404 warn "$0: Improper man page - no dash in NAME header in paragraph $. of $ARGV[0]\n"
cb1a09d0 405 }
84dc3c4d 406 %namedesc = split /\s+-+\s+/;
cb1a09d0 407 last FCHECK;
408 }
f360dba1 409 next if /^=cut\b/; # DB_File and Net::Ping have =cut before NAME
410 die "$0: Invalid man page - 1st pod line is not NAME in $ARGV[0]\n";
cb1a09d0 411 }
f360dba1 412 die "$0: Invalid man page - no documentation in $ARGV[0]\n";
cb1a09d0 413 }
414 close F;
415}
416
a0d0e21e 417print <<"END";
418.rn '' }`
419''' \$RCSfile\$\$Revision\$\$Date\$
cb1a09d0 420'''
a0d0e21e 421''' \$Log\$
cb1a09d0 422'''
a0d0e21e 423.de Sh
424.br
425.if t .Sp
426.ne 5
427.PP
428\\fB\\\\\$1\\fR
429.PP
430..
431.de Sp
432.if t .sp .5v
433.if n .sp
434..
435.de Ip
436.br
437.ie \\\\n(.\$>=3 .ne \\\\\$3
438.el .ne 3
439.IP "\\\\\$1" \\\\\$2
440..
441.de Vb
442.ft $CFont
443.nf
444.ne \\\\\$1
445..
446.de Ve
447.ft R
448
449.fi
450..
451'''
452'''
453''' Set up \\*(-- to give an unbreakable dash;
454''' string Tr holds user defined translation string.
455''' Bell System Logo is used as a dummy character.
456'''
457.tr \\(*W-|\\(bv\\*(Tr
458.ie n \\{\\
459.ds -- \\(*W-
cb1a09d0 460.ds PI pi
a0d0e21e 461.if (\\n(.H=4u)&(1m=24u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-12u'-\\" diablo 10 pitch
462.if (\\n(.H=4u)&(1m=20u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-8u'-\\" diablo 12 pitch
463.ds L" ""
464.ds R" ""
465.ds L' '
466.ds R' '
467'br\\}
468.el\\{\\
469.ds -- \\(em\\|
470.tr \\*(Tr
471.ds L" ``
472.ds R" ''
473.ds L' `
474.ds R' '
cb1a09d0 475.ds PI \\(*p
a0d0e21e 476'br\\}
cb1a09d0 477END
478
479print <<'END';
480.\" If the F register is turned on, we'll generate
481.\" index entries out stderr for the following things:
482.\" TH Title
483.\" SH Header
484.\" Sh Subsection
485.\" Ip Item
486.\" X<> Xref (embedded
487.\" Of course, you have to process the output yourself
488.\" in some meaninful fashion.
489.if \nF \{
490.de IX
491.tm Index:\\$1\t\\n%\t"\\$2"
492..
493.nr % 0
494.rr F
495.\}
496END
497
498print <<"END";
499.TH $name $section "$RP" "$date" "$center"
500.IX Title "$name $section"
a0d0e21e 501.UC
502END
503
cb1a09d0 504while (($name, $desc) = each %namedesc) {
505 for ($name, $desc) { s/^\s+//; s/\s+$//; }
506 print qq(.IX Name "$name - $desc"\n);
507}
508
a0d0e21e 509print <<'END';
cb1a09d0 510.if n .hy 0
a0d0e21e 511.if n .na
512.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
513.de CQ \" put $1 in typewriter font
514END
515print ".ft $CFont\n";
516print <<'END';
517'if n "\c
748a9306 518'if t \\&\\$1\c
519'if n \\&\\$1\c
a0d0e21e 520'if n \&"
748a9306 521\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
a0d0e21e 522'.ft R
523..
524.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
525. \" AM - accent mark definitions
9430eed9 526.bd B 3
a0d0e21e 527. \" fudge factors for nroff and troff
528.if n \{\
529. ds #H 0
530. ds #V .8m
531. ds #F .3m
532. ds #[ \f1
533. ds #] \fP
534.\}
535.if t \{\
748a9306 536. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
a0d0e21e 537. ds #V .6m
538. ds #F 0
539. ds #[ \&
540. ds #] \&
541.\}
542. \" simple accents for nroff and troff
543.if n \{\
544. ds ' \&
545. ds ` \&
546. ds ^ \&
547. ds , \&
548. ds ~ ~
549. ds ? ?
550. ds ! !
cb1a09d0 551. ds /
552. ds q
a0d0e21e 553.\}
554.if t \{\
748a9306 555. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
556. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
557. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
558. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
559. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
a0d0e21e 560. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
561. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
748a9306 562. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
a0d0e21e 563. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
564.\}
565. \" troff and (daisy-wheel) nroff accents
748a9306 566.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
a0d0e21e 567.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
748a9306 568.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
569.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
570.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
a0d0e21e 571.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
748a9306 572.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
a0d0e21e 573.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
748a9306 574.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
a0d0e21e 575.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
576.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
577.ds ae a\h'-(\w'a'u*4/10)'e
578.ds Ae A\h'-(\w'A'u*4/10)'E
579.ds oe o\h'-(\w'o'u*4/10)'e
580.ds Oe O\h'-(\w'O'u*4/10)'E
581. \" corrections for vroff
748a9306 582.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
583.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
a0d0e21e 584. \" for low resolution devices (crt and lpr)
585.if \n(.H>23 .if \n(.V>19 \
586\{\
587. ds : e
588. ds 8 ss
589. ds v \h'-1'\o'\(aa\(ga'
590. ds _ \h'-1'^
591. ds . \h'-1'.
592. ds 3 3
593. ds o a
594. ds d- d\h'-1'\(ga
595. ds D- D\h'-1'\(hy
596. ds th \o'bp'
597. ds Th \o'LP'
598. ds ae ae
599. ds Ae AE
600. ds oe oe
601. ds Oe OE
602.\}
603.rm #[ #] #H #V #F C
604END
605
606$indent = 0;
607
608while (<>) {
609 if ($cutting) {
610 next unless /^=/;
611 $cutting = 0;
612 }
613 chomp;
614
615 # Translate verbatim paragraph
616
617 if (/^\s/) {
618 @lines = split(/\n/);
619 for (@lines) {
620 1 while s
621 {^( [^\t]* ) \t ( \t* ) }
622 { $1 . ' ' x (8 - (length($1)%8) + 8 * (length($2))) }ex;
623 s/\\/\\e/g;
624 s/\A/\\&/s;
625 }
626 $lines = @lines;
627 makespace() unless $verbatim++;
628 print ".Vb $lines\n";
629 print join("\n", @lines), "\n";
630 print ".Ve\n";
631 $needspace = 0;
632 next;
633 }
634
635 $verbatim = 0;
636
637 # check for things that'll hosed our noremap scheme; affects $_
638 init_noremap();
639
640 if (!/^=item/) {
641
642 # trofficate backslashes; must do it before what happens below
643 s/\\/noremap('\\e')/ge;
644
cb1a09d0 645 # first hide the escapes in case we need to
a0d0e21e 646 # intuit something and get it wrong due to fmting
647
648 s/([A-Z]<[^<>]*>)/noremap($1)/ge;
649
650 # func() is a reference to a perl function
651 s{
652 \b
653 (
654 [:\w]+ \(\)
655 )
656 } {I<$1>}gx;
657
658 # func(n) is a reference to a man page
659 s{
660 (\w+)
661 (
662 \(
663 [^\s,\051]+
664 \)
665 )
666 } {I<$1>\\|$2}gx;
667
668 # convert simple variable references
748a9306 669 s/(\s+)([\$\@%][\w:]+)/${1}C<$2>/g;
a0d0e21e 670
671 if (m{ (
672 [\-\w]+
673 \(
674 [^\051]*?
675 [\@\$,]
676 [^\051]*?
677 \)
678 )
cb1a09d0 679 }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/)
a0d0e21e 680 {
cb1a09d0 681 warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [LCI]<$1>\n";
682 $oops++;
683 }
a0d0e21e 684
685 while (/(-[a-zA-Z])\b/g && $` !~ /[\w\-]$/) {
cb1a09d0 686 warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [CB]<$1>\n";
687 $oops++;
688 }
a0d0e21e 689
690 # put it back so we get the <> processed again;
691 clear_noremap(0); # 0 means leave the E's
692
693 } else {
694 # trofficate backslashes
695 s/\\/noremap('\\e')/ge;
696
cb1a09d0 697 }
a0d0e21e 698
699 # need to hide E<> first; they're processed in clear_noremap
700 s/(E<[^<>]+>)/noremap($1)/ge;
701
702
703 $maxnest = 10;
704 while ($maxnest-- && /[A-Z]</) {
705
706 # can't do C font here
707 s/([BI])<([^<>]*)>/font($1) . $2 . font('R')/eg;
708
709 # files and filelike refs in italics
710 s/F<([^<>]*)>/I<$1>/g;
711
712 # no break -- usually we want C<> for this
713 s/S<([^<>]*)>/nobreak($1)/eg;
714
cb1a09d0 715 # LREF: a manpage(3f)
a0d0e21e 716 s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the I<$1>$2 manpage:g;
717
718 # LREF: an =item on another manpage
719 s{
720 L<
721 ([^/]+)
722 /
723 (
724 [:\w]+
725 (\(\))?
726 )
727 >
728 } {the C<$2> entry in the I<$1> manpage}gx;
729
730 # LREF: an =item on this manpage
731 s{
732 ((?:
733 L<
734 /
735 (
736 [:\w]+
737 (\(\))?
738 )
739 >
740 (,?\s+(and\s+)?)?
741 )+)
742 } { internal_lrefs($1) }gex;
743
744 # LREF: a =head2 (head1?), maybe on a manpage, maybe right here
745 # the "func" can disambiguate
746 s{
747 L<
748 (?:
cb1a09d0 749 ([a-zA-Z]\S+?) /
a0d0e21e 750 )?
751 "?(.*?)"?
752 >
753 }{
754 do {
755 $1 # if no $1, assume it means on this page.
756 ? "the section on I<$2> in the I<$1> manpage"
757 : "the section on I<$2>"
cb1a09d0 758 }
e52f39a2 759 }gesx; # s in case it goes over multiple lines, so . matches \n
a0d0e21e 760
761 s/Z<>/\\&/g;
762
763 # comes last because not subject to reprocessing
764 s/C<([^<>]*)>/noremap("${CFont_embed}${1}\\fR")/eg;
765 }
766
767 if (s/^=//) {
768 $needspace = 0; # Assume this.
769
770 s/\n/ /g;
771
772 ($Cmd, $_) = split(' ', $_, 2);
773
774 if (defined $_) {
775 &escapes;
776 s/"/""/g;
777 }
778
779 clear_noremap(1);
780
781 if ($Cmd eq 'cut') {
782 $cutting = 1;
783 }
784 elsif ($Cmd eq 'head1') {
cb1a09d0 785 s/\s+$//;
786 delete $wanna_see{$_} if exists $wanna_see{$_};
787 print qq{.SH "$_"\n};
788 print qq{.IX Header "$_"\n};
a0d0e21e 789 }
790 elsif ($Cmd eq 'head2') {
cb1a09d0 791 print qq{.Sh "$_"\n};
792 print qq{.IX Subsection "$_"\n};
a0d0e21e 793 }
794 elsif ($Cmd eq 'over') {
795 push(@indent,$indent);
cb1a09d0 796 $indent += ($_ + 0) || 5;
a0d0e21e 797 }
798 elsif ($Cmd eq 'back') {
799 $indent = pop(@indent);
f360dba1 800 warn "$0: Unmatched =back in paragraph $. of $ARGV\n" unless defined $indent;
a0d0e21e 801 $needspace = 1;
802 }
803 elsif ($Cmd eq 'item') {
804 s/^\*( |$)/\\(bu$1/g;
805 print STDOUT qq{.Ip "$_" $indent\n};
cb1a09d0 806 print qq{.IX Item "$_"\n};
a0d0e21e 807 }
cb1a09d0 808 elsif ($Cmd eq 'pod') {
809 # this is just a comment
810 }
a0d0e21e 811 else {
f360dba1 812 warn "$0: Unrecognized pod directive in paragraph $. of $ARGV: $Cmd\n";
a0d0e21e 813 }
814 }
815 else {
816 if ($needspace) {
817 &makespace;
818 }
819 &escapes;
820 clear_noremap(1);
821 print $_, "\n";
822 $needspace = 1;
823 }
824}
825
826print <<"END";
827
828.rn }` ''
829END
830
cb1a09d0 831if (%wanna_see) {
832 @missing = keys %wanna_see;
833 warn "$0: $Filename is missing required section"
834 . (@missing > 1 && "s")
835 . ": @missing\n";
836 $oops++;
837}
838
839exit;
840#exit ($oops != 0);
841
a0d0e21e 842#########################################################################
843
844sub nobreak {
845 my $string = shift;
846 $string =~ s/ /\\ /g;
847 $string;
848}
849
850sub escapes {
851
cb1a09d0 852 s/X<(.*?)>/mkindex($1)/ge;
853
a0d0e21e 854 # translate the minus in foo-bar into foo\-bar for roff
855 s/([^0-9a-z-])-([^-])/$1\\-$2/g;
856
857 # make -- into the string version \*(-- (defined above)
858 s/\b--\b/\\*(--/g;
859 s/"--([^"])/"\\*(--$1/g; # should be a better way
860 s/([^"])--"/$1\\*(--"/g;
861
862 # fix up quotes; this is somewhat tricky
863 if (!/""/) {
864 s/(^|\s)(['"])/noremap("$1\\*(L$2")/ge;
865 s/(['"])($|[\-\s,;\\!?.])/noremap("\\*(R$1$2")/ge;
866 }
867
868 #s/(?!")(?:.)--(?!")(?:.)/\\*(--/g;
869 #s/(?:(?!")(?:.)--(?:"))|(?:(?:")--(?!")(?:.))/\\*(--/g;
cb1a09d0 870
a0d0e21e 871
872 # make sure that func() keeps a bit a space tween the parens
873 ### s/\b\(\)/\\|()/g;
874 ### s/\b\(\)/(\\|)/g;
875
876 # make C++ into \*C+, which is a squinched version (defined above)
877 s/\bC\+\+/\\*(C+/g;
878
879 # make double underbars have a little tiny space between them
880 s/__/_\\|_/g;
881
cb1a09d0 882 # PI goes to \*(PI (defined above)
a0d0e21e 883 s/\bPI\b/noremap('\\*(PI')/ge;
884
885 # make all caps a teeny bit smaller, but don't muck with embedded code literals
886 my $hidCFont = font('C');
887 if ($Cmd !~ /^head1/) { # SH already makes smaller
888 # /g isn't enough; 1 while or we'll be off
889
890# 1 while s{
891# (?!$hidCFont)(..|^.|^)
892# \b
893# (
894# [A-Z][\/A-Z+:\-\d_$.]+
895# )
896# (s?)
897# \b
898# } {$1\\s-1$2\\s0}gmox;
899
900 1 while s{
901 (?!$hidCFont)(..|^.|^)
902 (
903 \b[A-Z]{2,}[\/A-Z+:\-\d_\$]*\b
904 )
cb1a09d0 905 } {
a0d0e21e 906 $1 . noremap( '\\s-1' . $2 . '\\s0' )
907 }egmox;
908
909 }
910}
911
912# make troff just be normal, but make small nroff get quoted
913# decided to just put the quotes in the text; sigh;
914sub ccvt {
915 local($_,$prev) = @_;
916 if ( /^\W+$/ && !/^\$./ ) {
917 ($prev && "\n") . noremap(qq{.CQ $_ \n\\&});
918 # what about $" ?
919 } else {
920 noremap(qq{${CFont_embed}$_\\fR});
cb1a09d0 921 }
a0d0e21e 922 noremap(qq{.CQ "$_" \n\\&});
cb1a09d0 923}
a0d0e21e 924
925sub makespace {
926 if ($indent) {
927 print ".Sp\n";
928 }
929 else {
930 print ".PP\n";
931 }
932}
933
cb1a09d0 934sub mkindex {
935 my ($entry) = @_;
936 my @entries = split m:\s*/\s*:, $entry;
937 print ".IX Xref ";
938 for $entry (@entries) {
939 print qq("$entry" );
940 }
941 print "\n";
942 return '';
943}
944
a0d0e21e 945sub font {
946 local($font) = shift;
947 return '\\f' . noremap($font);
cb1a09d0 948}
a0d0e21e 949
950sub noremap {
951 local($thing_to_hide) = shift;
952 $thing_to_hide =~ tr/\000-\177/\200-\377/;
953 return $thing_to_hide;
cb1a09d0 954}
a0d0e21e 955
956sub init_noremap {
3dd51965 957 # escape high bit characters in input stream
958 s/([\200-\377])/"E<".ord($1).">"/ge;
cb1a09d0 959}
a0d0e21e 960
961sub clear_noremap {
962 my $ready_to_print = $_[0];
963
964 tr/\200-\377/\000-\177/;
965
966 # trofficate backslashes
967 # s/(?!\\e)(?:..|^.|^)\\/\\e/g;
968
969 # now for the E<>s, which have been hidden until now
970 # otherwise the interative \w<> processing would have
971 # been hosed by the E<gt>
972 s {
3dd51965 973 E<
974 (
975 ( \d + )
976 | ( [A-Za-z]+ )
977 )
a0d0e21e 978 >
cb1a09d0 979 } {
3dd51965 980 do {
981 defined $2
982 ? chr($2)
983 :
984 exists $HTML_Escapes{$3}
985 ? do { $HTML_Escapes{$3} }
a0d0e21e 986 : do {
f360dba1 987 warn "$0: Unknown escape in paragraph $. of $ARGV: ``$&''\n";
a0d0e21e 988 "E<$1>";
cb1a09d0 989 }
990 }
a0d0e21e 991 }egx if $ready_to_print;
cb1a09d0 992}
a0d0e21e 993
994sub internal_lrefs {
995 local($_) = shift;
996
997 s{L</([^>]+)>}{$1}g;
998 my(@items) = split( /(?:,?\s+(?:and\s+)?)/ );
999 my $retstr = "the ";
1000 my $i;
1001 for ($i = 0; $i <= $#items; $i++) {
1002 $retstr .= "C<$items[$i]>";
1003 $retstr .= ", " if @items > 2 && $i != $#items;
1004 $retstr .= " and " if $i+2 == @items;
cb1a09d0 1005 }
a0d0e21e 1006
1007 $retstr .= " entr" . ( @items > 1 ? "ies" : "y" )
e52f39a2 1008 . " elsewhere in this document "; # terminal space to avoid words running together (pattern used strips terminal spaces)
a0d0e21e 1009
1010 return $retstr;
1011
cb1a09d0 1012}
a0d0e21e 1013
1014BEGIN {
1015%HTML_Escapes = (
1016 'amp' => '&', # ampersand
1017 'lt' => '<', # left chevron, less-than
1018 'gt' => '>', # right chevron, greater-than
1019 'quot' => '"', # double quote
1020
1021 "Aacute" => "A\\*'", # capital A, acute accent
1022 "aacute" => "a\\*'", # small a, acute accent
1023 "Acirc" => "A\\*^", # capital A, circumflex accent
1024 "acirc" => "a\\*^", # small a, circumflex accent
1025 "AElig" => '\*(AE', # capital AE diphthong (ligature)
1026 "aelig" => '\*(ae', # small ae diphthong (ligature)
1027 "Agrave" => "A\\*`", # capital A, grave accent
1028 "agrave" => "A\\*`", # small a, grave accent
1029 "Aring" => 'A\\*o', # capital A, ring
1030 "aring" => 'a\\*o', # small a, ring
1031 "Atilde" => 'A\\*~', # capital A, tilde
1032 "atilde" => 'a\\*~', # small a, tilde
1033 "Auml" => 'A\\*:', # capital A, dieresis or umlaut mark
1034 "auml" => 'a\\*:', # small a, dieresis or umlaut mark
1035 "Ccedil" => 'C\\*,', # capital C, cedilla
1036 "ccedil" => 'c\\*,', # small c, cedilla
1037 "Eacute" => "E\\*'", # capital E, acute accent
1038 "eacute" => "e\\*'", # small e, acute accent
1039 "Ecirc" => "E\\*^", # capital E, circumflex accent
1040 "ecirc" => "e\\*^", # small e, circumflex accent
1041 "Egrave" => "E\\*`", # capital E, grave accent
1042 "egrave" => "e\\*`", # small e, grave accent
1043 "ETH" => '\\*(D-', # capital Eth, Icelandic
1044 "eth" => '\\*(d-', # small eth, Icelandic
1045 "Euml" => "E\\*:", # capital E, dieresis or umlaut mark
1046 "euml" => "e\\*:", # small e, dieresis or umlaut mark
1047 "Iacute" => "I\\*'", # capital I, acute accent
1048 "iacute" => "i\\*'", # small i, acute accent
1049 "Icirc" => "I\\*^", # capital I, circumflex accent
1050 "icirc" => "i\\*^", # small i, circumflex accent
1051 "Igrave" => "I\\*`", # capital I, grave accent
1052 "igrave" => "i\\*`", # small i, grave accent
1053 "Iuml" => "I\\*:", # capital I, dieresis or umlaut mark
1054 "iuml" => "i\\*:", # small i, dieresis or umlaut mark
1055 "Ntilde" => 'N\*~', # capital N, tilde
1056 "ntilde" => 'n\*~', # small n, tilde
1057 "Oacute" => "O\\*'", # capital O, acute accent
1058 "oacute" => "o\\*'", # small o, acute accent
1059 "Ocirc" => "O\\*^", # capital O, circumflex accent
1060 "ocirc" => "o\\*^", # small o, circumflex accent
1061 "Ograve" => "O\\*`", # capital O, grave accent
1062 "ograve" => "o\\*`", # small o, grave accent
1063 "Oslash" => "O\\*/", # capital O, slash
1064 "oslash" => "o\\*/", # small o, slash
1065 "Otilde" => "O\\*~", # capital O, tilde
1066 "otilde" => "o\\*~", # small o, tilde
1067 "Ouml" => "O\\*:", # capital O, dieresis or umlaut mark
1068 "ouml" => "o\\*:", # small o, dieresis or umlaut mark
1069 "szlig" => '\*8', # small sharp s, German (sz ligature)
1070 "THORN" => '\\*(Th', # capital THORN, Icelandic
1071 "thorn" => '\\*(th',, # small thorn, Icelandic
1072 "Uacute" => "U\\*'", # capital U, acute accent
1073 "uacute" => "u\\*'", # small u, acute accent
1074 "Ucirc" => "U\\*^", # capital U, circumflex accent
1075 "ucirc" => "u\\*^", # small u, circumflex accent
1076 "Ugrave" => "U\\*`", # capital U, grave accent
1077 "ugrave" => "u\\*`", # small u, grave accent
1078 "Uuml" => "U\\*:", # capital U, dieresis or umlaut mark
1079 "uuml" => "u\\*:", # small u, dieresis or umlaut mark
1080 "Yacute" => "Y\\*'", # capital Y, acute accent
1081 "yacute" => "y\\*'", # small y, acute accent
1082 "yuml" => "y\\*:", # small y, dieresis or umlaut mark
1083);
1084}
cb1a09d0 1085
5d94fbed 1086!NO!SUBS!
4633a7c4 1087
1088close OUT or die "Can't close $file: $!";
1089chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
1090exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';