This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 5.003_06: pod/perlguts.pod
[perl5.git] / pod / pod2man.PL
CommitLineData
4633a7c4
LW
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
LW
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
AD
29!GROK!THIS!
30
4633a7c4
LW
31# In the following, perl variables are not expanded during extraction.
32
33print OUT <<'!NO!SUBS!';
cb1a09d0
AD
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
201you might keep a modification long here.
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
AD
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
251a C<E<lt>E<gt>> directive. Besides amp, lt, gt, and quot, recognized
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
276numbering and even/odd paging, at least one some versions of man(7).
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
AD
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
LW
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
AD
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
LW
325}
326
cb1a09d0
AD
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
LW
369if (length($CFont) == 2) {
370 $CFont_embed = "\\f($CFont";
cb1a09d0 371}
a0d0e21e
LW
372elsif (length($CFont) == 1) {
373 $CFont_embed = "\\f$CFont";
cb1a09d0 374}
a0d0e21e 375else {
cb1a09d0
AD
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
AD
389$name = @ARGV ? $ARGV[0] : "<STDIN>";
390$Filename = $name;
391$name = uc($name) if $section =~ /^1/;
9430eed9 392$name =~ s/\.[^.]*$//;
a0d0e21e 393
cb1a09d0
AD
394if ($name ne 'something') {
395 FCHECK: {
396 open(F, "< $ARGV[0]") || die "can't open $ARGV[0]: $!";
397 while (<F>) {
f360dba1 398 next unless /^=\b/;
cb1a09d0
AD
399 if (/^=head1\s+NAME\s*$/) { # an /m would forgive mistakes
400 $_ = <F>;
401 unless (/\s*-+\s+/) {
402 $oops++;
f360dba1 403 warn "$0: Improper man page - no dash in NAME header in paragraph $. of $ARGV[0]\n"
cb1a09d0 404 }
84dc3c4d 405 %namedesc = split /\s+-+\s+/;
cb1a09d0
AD
406 last FCHECK;
407 }
f360dba1 408 next if /^=cut\b/; # DB_File and Net::Ping have =cut before NAME
409 die "$0: Invalid man page - 1st pod line is not NAME in $ARGV[0]\n";
cb1a09d0 410 }
f360dba1 411 die "$0: Invalid man page - no documentation in $ARGV[0]\n";
cb1a09d0
AD
412 }
413 close F;
414}
415
a0d0e21e
LW
416print <<"END";
417.rn '' }`
418''' \$RCSfile\$\$Revision\$\$Date\$
cb1a09d0 419'''
a0d0e21e 420''' \$Log\$
cb1a09d0 421'''
a0d0e21e
LW
422.de Sh
423.br
424.if t .Sp
425.ne 5
426.PP
427\\fB\\\\\$1\\fR
428.PP
429..
430.de Sp
431.if t .sp .5v
432.if n .sp
433..
434.de Ip
435.br
436.ie \\\\n(.\$>=3 .ne \\\\\$3
437.el .ne 3
438.IP "\\\\\$1" \\\\\$2
439..
440.de Vb
441.ft $CFont
442.nf
443.ne \\\\\$1
444..
445.de Ve
446.ft R
447
448.fi
449..
450'''
451'''
452''' Set up \\*(-- to give an unbreakable dash;
453''' string Tr holds user defined translation string.
454''' Bell System Logo is used as a dummy character.
455'''
456.tr \\(*W-|\\(bv\\*(Tr
457.ie n \\{\\
458.ds -- \\(*W-
cb1a09d0 459.ds PI pi
a0d0e21e
LW
460.if (\\n(.H=4u)&(1m=24u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-12u'-\\" diablo 10 pitch
461.if (\\n(.H=4u)&(1m=20u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-8u'-\\" diablo 12 pitch
462.ds L" ""
463.ds R" ""
464.ds L' '
465.ds R' '
466'br\\}
467.el\\{\\
468.ds -- \\(em\\|
469.tr \\*(Tr
470.ds L" ``
471.ds R" ''
472.ds L' `
473.ds R' '
cb1a09d0 474.ds PI \\(*p
a0d0e21e 475'br\\}
cb1a09d0
AD
476END
477
478print <<'END';
479.\" If the F register is turned on, we'll generate
480.\" index entries out stderr for the following things:
481.\" TH Title
482.\" SH Header
483.\" Sh Subsection
484.\" Ip Item
485.\" X<> Xref (embedded
486.\" Of course, you have to process the output yourself
487.\" in some meaninful fashion.
488.if \nF \{
489.de IX
490.tm Index:\\$1\t\\n%\t"\\$2"
491..
492.nr % 0
493.rr F
494.\}
495END
496
497print <<"END";
498.TH $name $section "$RP" "$date" "$center"
499.IX Title "$name $section"
a0d0e21e
LW
500.UC
501END
502
cb1a09d0
AD
503while (($name, $desc) = each %namedesc) {
504 for ($name, $desc) { s/^\s+//; s/\s+$//; }
505 print qq(.IX Name "$name - $desc"\n);
506}
507
a0d0e21e 508print <<'END';
cb1a09d0 509.if n .hy 0
a0d0e21e
LW
510.if n .na
511.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
512.de CQ \" put $1 in typewriter font
513END
514print ".ft $CFont\n";
515print <<'END';
516'if n "\c
748a9306
LW
517'if t \\&\\$1\c
518'if n \\&\\$1\c
a0d0e21e 519'if n \&"
748a9306 520\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
a0d0e21e
LW
521'.ft R
522..
523.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
524. \" AM - accent mark definitions
9430eed9 525.bd B 3
a0d0e21e
LW
526. \" fudge factors for nroff and troff
527.if n \{\
528. ds #H 0
529. ds #V .8m
530. ds #F .3m
531. ds #[ \f1
532. ds #] \fP
533.\}
534.if t \{\
748a9306 535. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
a0d0e21e
LW
536. ds #V .6m
537. ds #F 0
538. ds #[ \&
539. ds #] \&
540.\}
541. \" simple accents for nroff and troff
542.if n \{\
543. ds ' \&
544. ds ` \&
545. ds ^ \&
546. ds , \&
547. ds ~ ~
548. ds ? ?
549. ds ! !
cb1a09d0
AD
550. ds /
551. ds q
a0d0e21e
LW
552.\}
553.if t \{\
748a9306
LW
554. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
555. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
556. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
557. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
558. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
a0d0e21e
LW
559. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
560. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
748a9306 561. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
a0d0e21e
LW
562. 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'
563.\}
564. \" troff and (daisy-wheel) nroff accents
748a9306 565.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
a0d0e21e 566.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
748a9306
LW
567.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
568.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
569.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
a0d0e21e 570.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
748a9306 571.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
a0d0e21e 572.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
748a9306 573.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
a0d0e21e
LW
574.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
575.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
576.ds ae a\h'-(\w'a'u*4/10)'e
577.ds Ae A\h'-(\w'A'u*4/10)'E
578.ds oe o\h'-(\w'o'u*4/10)'e
579.ds Oe O\h'-(\w'O'u*4/10)'E
580. \" corrections for vroff
748a9306
LW
581.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
582.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
a0d0e21e
LW
583. \" for low resolution devices (crt and lpr)
584.if \n(.H>23 .if \n(.V>19 \
585\{\
586. ds : e
587. ds 8 ss
588. ds v \h'-1'\o'\(aa\(ga'
589. ds _ \h'-1'^
590. ds . \h'-1'.
591. ds 3 3
592. ds o a
593. ds d- d\h'-1'\(ga
594. ds D- D\h'-1'\(hy
595. ds th \o'bp'
596. ds Th \o'LP'
597. ds ae ae
598. ds Ae AE
599. ds oe oe
600. ds Oe OE
601.\}
602.rm #[ #] #H #V #F C
603END
604
605$indent = 0;
606
607while (<>) {
608 if ($cutting) {
609 next unless /^=/;
610 $cutting = 0;
611 }
612 chomp;
613
614 # Translate verbatim paragraph
615
616 if (/^\s/) {
617 @lines = split(/\n/);
618 for (@lines) {
619 1 while s
620 {^( [^\t]* ) \t ( \t* ) }
621 { $1 . ' ' x (8 - (length($1)%8) + 8 * (length($2))) }ex;
622 s/\\/\\e/g;
623 s/\A/\\&/s;
624 }
625 $lines = @lines;
626 makespace() unless $verbatim++;
627 print ".Vb $lines\n";
628 print join("\n", @lines), "\n";
629 print ".Ve\n";
630 $needspace = 0;
631 next;
632 }
633
634 $verbatim = 0;
635
636 # check for things that'll hosed our noremap scheme; affects $_
637 init_noremap();
638
639 if (!/^=item/) {
640
641 # trofficate backslashes; must do it before what happens below
642 s/\\/noremap('\\e')/ge;
643
cb1a09d0 644 # first hide the escapes in case we need to
a0d0e21e
LW
645 # intuit something and get it wrong due to fmting
646
647 s/([A-Z]<[^<>]*>)/noremap($1)/ge;
648
649 # func() is a reference to a perl function
650 s{
651 \b
652 (
653 [:\w]+ \(\)
654 )
655 } {I<$1>}gx;
656
657 # func(n) is a reference to a man page
658 s{
659 (\w+)
660 (
661 \(
662 [^\s,\051]+
663 \)
664 )
665 } {I<$1>\\|$2}gx;
666
667 # convert simple variable references
748a9306 668 s/(\s+)([\$\@%][\w:]+)/${1}C<$2>/g;
a0d0e21e
LW
669
670 if (m{ (
671 [\-\w]+
672 \(
673 [^\051]*?
674 [\@\$,]
675 [^\051]*?
676 \)
677 )
cb1a09d0 678 }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/)
a0d0e21e 679 {
cb1a09d0
AD
680 warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [LCI]<$1>\n";
681 $oops++;
682 }
a0d0e21e
LW
683
684 while (/(-[a-zA-Z])\b/g && $` !~ /[\w\-]$/) {
cb1a09d0
AD
685 warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [CB]<$1>\n";
686 $oops++;
687 }
a0d0e21e
LW
688
689 # put it back so we get the <> processed again;
690 clear_noremap(0); # 0 means leave the E's
691
692 } else {
693 # trofficate backslashes
694 s/\\/noremap('\\e')/ge;
695
cb1a09d0 696 }
a0d0e21e
LW
697
698 # need to hide E<> first; they're processed in clear_noremap
699 s/(E<[^<>]+>)/noremap($1)/ge;
700
701
702 $maxnest = 10;
703 while ($maxnest-- && /[A-Z]</) {
704
705 # can't do C font here
706 s/([BI])<([^<>]*)>/font($1) . $2 . font('R')/eg;
707
708 # files and filelike refs in italics
709 s/F<([^<>]*)>/I<$1>/g;
710
711 # no break -- usually we want C<> for this
712 s/S<([^<>]*)>/nobreak($1)/eg;
713
cb1a09d0 714 # LREF: a manpage(3f)
a0d0e21e
LW
715 s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the I<$1>$2 manpage:g;
716
717 # LREF: an =item on another manpage
718 s{
719 L<
720 ([^/]+)
721 /
722 (
723 [:\w]+
724 (\(\))?
725 )
726 >
727 } {the C<$2> entry in the I<$1> manpage}gx;
728
729 # LREF: an =item on this manpage
730 s{
731 ((?:
732 L<
733 /
734 (
735 [:\w]+
736 (\(\))?
737 )
738 >
739 (,?\s+(and\s+)?)?
740 )+)
741 } { internal_lrefs($1) }gex;
742
743 # LREF: a =head2 (head1?), maybe on a manpage, maybe right here
744 # the "func" can disambiguate
745 s{
746 L<
747 (?:
cb1a09d0 748 ([a-zA-Z]\S+?) /
a0d0e21e
LW
749 )?
750 "?(.*?)"?
751 >
752 }{
753 do {
754 $1 # if no $1, assume it means on this page.
755 ? "the section on I<$2> in the I<$1> manpage"
756 : "the section on I<$2>"
cb1a09d0 757 }
a0d0e21e
LW
758 }gex;
759
760 s/Z<>/\\&/g;
761
762 # comes last because not subject to reprocessing
763 s/C<([^<>]*)>/noremap("${CFont_embed}${1}\\fR")/eg;
764 }
765
766 if (s/^=//) {
767 $needspace = 0; # Assume this.
768
769 s/\n/ /g;
770
771 ($Cmd, $_) = split(' ', $_, 2);
772
773 if (defined $_) {
774 &escapes;
775 s/"/""/g;
776 }
777
778 clear_noremap(1);
779
780 if ($Cmd eq 'cut') {
781 $cutting = 1;
782 }
783 elsif ($Cmd eq 'head1') {
cb1a09d0
AD
784 s/\s+$//;
785 delete $wanna_see{$_} if exists $wanna_see{$_};
786 print qq{.SH "$_"\n};
787 print qq{.IX Header "$_"\n};
a0d0e21e
LW
788 }
789 elsif ($Cmd eq 'head2') {
cb1a09d0
AD
790 print qq{.Sh "$_"\n};
791 print qq{.IX Subsection "$_"\n};
a0d0e21e
LW
792 }
793 elsif ($Cmd eq 'over') {
794 push(@indent,$indent);
cb1a09d0 795 $indent += ($_ + 0) || 5;
a0d0e21e
LW
796 }
797 elsif ($Cmd eq 'back') {
798 $indent = pop(@indent);
f360dba1 799 warn "$0: Unmatched =back in paragraph $. of $ARGV\n" unless defined $indent;
a0d0e21e
LW
800 $needspace = 1;
801 }
802 elsif ($Cmd eq 'item') {
803 s/^\*( |$)/\\(bu$1/g;
804 print STDOUT qq{.Ip "$_" $indent\n};
cb1a09d0 805 print qq{.IX Item "$_"\n};
a0d0e21e 806 }
cb1a09d0
AD
807 elsif ($Cmd eq 'pod') {
808 # this is just a comment
809 }
a0d0e21e 810 else {
f360dba1 811 warn "$0: Unrecognized pod directive in paragraph $. of $ARGV: $Cmd\n";
a0d0e21e
LW
812 }
813 }
814 else {
815 if ($needspace) {
816 &makespace;
817 }
818 &escapes;
819 clear_noremap(1);
820 print $_, "\n";
821 $needspace = 1;
822 }
823}
824
825print <<"END";
826
827.rn }` ''
828END
829
cb1a09d0
AD
830if (%wanna_see) {
831 @missing = keys %wanna_see;
832 warn "$0: $Filename is missing required section"
833 . (@missing > 1 && "s")
834 . ": @missing\n";
835 $oops++;
836}
837
838exit;
839#exit ($oops != 0);
840
a0d0e21e
LW
841#########################################################################
842
843sub nobreak {
844 my $string = shift;
845 $string =~ s/ /\\ /g;
846 $string;
847}
848
849sub escapes {
850
cb1a09d0
AD
851 s/X<(.*?)>/mkindex($1)/ge;
852
a0d0e21e
LW
853 # translate the minus in foo-bar into foo\-bar for roff
854 s/([^0-9a-z-])-([^-])/$1\\-$2/g;
855
856 # make -- into the string version \*(-- (defined above)
857 s/\b--\b/\\*(--/g;
858 s/"--([^"])/"\\*(--$1/g; # should be a better way
859 s/([^"])--"/$1\\*(--"/g;
860
861 # fix up quotes; this is somewhat tricky
862 if (!/""/) {
863 s/(^|\s)(['"])/noremap("$1\\*(L$2")/ge;
864 s/(['"])($|[\-\s,;\\!?.])/noremap("\\*(R$1$2")/ge;
865 }
866
867 #s/(?!")(?:.)--(?!")(?:.)/\\*(--/g;
868 #s/(?:(?!")(?:.)--(?:"))|(?:(?:")--(?!")(?:.))/\\*(--/g;
cb1a09d0 869
a0d0e21e
LW
870
871 # make sure that func() keeps a bit a space tween the parens
872 ### s/\b\(\)/\\|()/g;
873 ### s/\b\(\)/(\\|)/g;
874
875 # make C++ into \*C+, which is a squinched version (defined above)
876 s/\bC\+\+/\\*(C+/g;
877
878 # make double underbars have a little tiny space between them
879 s/__/_\\|_/g;
880
cb1a09d0 881 # PI goes to \*(PI (defined above)
a0d0e21e
LW
882 s/\bPI\b/noremap('\\*(PI')/ge;
883
884 # make all caps a teeny bit smaller, but don't muck with embedded code literals
885 my $hidCFont = font('C');
886 if ($Cmd !~ /^head1/) { # SH already makes smaller
887 # /g isn't enough; 1 while or we'll be off
888
889# 1 while s{
890# (?!$hidCFont)(..|^.|^)
891# \b
892# (
893# [A-Z][\/A-Z+:\-\d_$.]+
894# )
895# (s?)
896# \b
897# } {$1\\s-1$2\\s0}gmox;
898
899 1 while s{
900 (?!$hidCFont)(..|^.|^)
901 (
902 \b[A-Z]{2,}[\/A-Z+:\-\d_\$]*\b
903 )
cb1a09d0 904 } {
a0d0e21e
LW
905 $1 . noremap( '\\s-1' . $2 . '\\s0' )
906 }egmox;
907
908 }
909}
910
911# make troff just be normal, but make small nroff get quoted
912# decided to just put the quotes in the text; sigh;
913sub ccvt {
914 local($_,$prev) = @_;
915 if ( /^\W+$/ && !/^\$./ ) {
916 ($prev && "\n") . noremap(qq{.CQ $_ \n\\&});
917 # what about $" ?
918 } else {
919 noremap(qq{${CFont_embed}$_\\fR});
cb1a09d0 920 }
a0d0e21e 921 noremap(qq{.CQ "$_" \n\\&});
cb1a09d0 922}
a0d0e21e
LW
923
924sub makespace {
925 if ($indent) {
926 print ".Sp\n";
927 }
928 else {
929 print ".PP\n";
930 }
931}
932
cb1a09d0
AD
933sub mkindex {
934 my ($entry) = @_;
935 my @entries = split m:\s*/\s*:, $entry;
936 print ".IX Xref ";
937 for $entry (@entries) {
938 print qq("$entry" );
939 }
940 print "\n";
941 return '';
942}
943
a0d0e21e
LW
944sub font {
945 local($font) = shift;
946 return '\\f' . noremap($font);
cb1a09d0 947}
a0d0e21e
LW
948
949sub noremap {
950 local($thing_to_hide) = shift;
951 $thing_to_hide =~ tr/\000-\177/\200-\377/;
952 return $thing_to_hide;
cb1a09d0 953}
a0d0e21e
LW
954
955sub init_noremap {
3dd51965 956 # escape high bit characters in input stream
957 s/([\200-\377])/"E<".ord($1).">"/ge;
cb1a09d0 958}
a0d0e21e
LW
959
960sub clear_noremap {
961 my $ready_to_print = $_[0];
962
963 tr/\200-\377/\000-\177/;
964
965 # trofficate backslashes
966 # s/(?!\\e)(?:..|^.|^)\\/\\e/g;
967
968 # now for the E<>s, which have been hidden until now
969 # otherwise the interative \w<> processing would have
970 # been hosed by the E<gt>
971 s {
3dd51965 972 E<
973 (
974 ( \d + )
975 | ( [A-Za-z]+ )
976 )
a0d0e21e 977 >
cb1a09d0 978 } {
3dd51965 979 do {
980 defined $2
981 ? chr($2)
982 :
983 exists $HTML_Escapes{$3}
984 ? do { $HTML_Escapes{$3} }
a0d0e21e 985 : do {
f360dba1 986 warn "$0: Unknown escape in paragraph $. of $ARGV: ``$&''\n";
a0d0e21e 987 "E<$1>";
cb1a09d0
AD
988 }
989 }
a0d0e21e 990 }egx if $ready_to_print;
cb1a09d0 991}
a0d0e21e
LW
992
993sub internal_lrefs {
994 local($_) = shift;
995
996 s{L</([^>]+)>}{$1}g;
997 my(@items) = split( /(?:,?\s+(?:and\s+)?)/ );
998 my $retstr = "the ";
999 my $i;
1000 for ($i = 0; $i <= $#items; $i++) {
1001 $retstr .= "C<$items[$i]>";
1002 $retstr .= ", " if @items > 2 && $i != $#items;
1003 $retstr .= " and " if $i+2 == @items;
cb1a09d0 1004 }
a0d0e21e
LW
1005
1006 $retstr .= " entr" . ( @items > 1 ? "ies" : "y" )
1007 . " elsewhere in this document";
1008
1009 return $retstr;
1010
cb1a09d0 1011}
a0d0e21e
LW
1012
1013BEGIN {
1014%HTML_Escapes = (
1015 'amp' => '&', # ampersand
1016 'lt' => '<', # left chevron, less-than
1017 'gt' => '>', # right chevron, greater-than
1018 'quot' => '"', # double quote
1019
1020 "Aacute" => "A\\*'", # capital A, acute accent
1021 "aacute" => "a\\*'", # small a, acute accent
1022 "Acirc" => "A\\*^", # capital A, circumflex accent
1023 "acirc" => "a\\*^", # small a, circumflex accent
1024 "AElig" => '\*(AE', # capital AE diphthong (ligature)
1025 "aelig" => '\*(ae', # small ae diphthong (ligature)
1026 "Agrave" => "A\\*`", # capital A, grave accent
1027 "agrave" => "A\\*`", # small a, grave accent
1028 "Aring" => 'A\\*o', # capital A, ring
1029 "aring" => 'a\\*o', # small a, ring
1030 "Atilde" => 'A\\*~', # capital A, tilde
1031 "atilde" => 'a\\*~', # small a, tilde
1032 "Auml" => 'A\\*:', # capital A, dieresis or umlaut mark
1033 "auml" => 'a\\*:', # small a, dieresis or umlaut mark
1034 "Ccedil" => 'C\\*,', # capital C, cedilla
1035 "ccedil" => 'c\\*,', # small c, cedilla
1036 "Eacute" => "E\\*'", # capital E, acute accent
1037 "eacute" => "e\\*'", # small e, acute accent
1038 "Ecirc" => "E\\*^", # capital E, circumflex accent
1039 "ecirc" => "e\\*^", # small e, circumflex accent
1040 "Egrave" => "E\\*`", # capital E, grave accent
1041 "egrave" => "e\\*`", # small e, grave accent
1042 "ETH" => '\\*(D-', # capital Eth, Icelandic
1043 "eth" => '\\*(d-', # small eth, Icelandic
1044 "Euml" => "E\\*:", # capital E, dieresis or umlaut mark
1045 "euml" => "e\\*:", # small e, dieresis or umlaut mark
1046 "Iacute" => "I\\*'", # capital I, acute accent
1047 "iacute" => "i\\*'", # small i, acute accent
1048 "Icirc" => "I\\*^", # capital I, circumflex accent
1049 "icirc" => "i\\*^", # small i, circumflex accent
1050 "Igrave" => "I\\*`", # capital I, grave accent
1051 "igrave" => "i\\*`", # small i, grave accent
1052 "Iuml" => "I\\*:", # capital I, dieresis or umlaut mark
1053 "iuml" => "i\\*:", # small i, dieresis or umlaut mark
1054 "Ntilde" => 'N\*~', # capital N, tilde
1055 "ntilde" => 'n\*~', # small n, tilde
1056 "Oacute" => "O\\*'", # capital O, acute accent
1057 "oacute" => "o\\*'", # small o, acute accent
1058 "Ocirc" => "O\\*^", # capital O, circumflex accent
1059 "ocirc" => "o\\*^", # small o, circumflex accent
1060 "Ograve" => "O\\*`", # capital O, grave accent
1061 "ograve" => "o\\*`", # small o, grave accent
1062 "Oslash" => "O\\*/", # capital O, slash
1063 "oslash" => "o\\*/", # small o, slash
1064 "Otilde" => "O\\*~", # capital O, tilde
1065 "otilde" => "o\\*~", # small o, tilde
1066 "Ouml" => "O\\*:", # capital O, dieresis or umlaut mark
1067 "ouml" => "o\\*:", # small o, dieresis or umlaut mark
1068 "szlig" => '\*8', # small sharp s, German (sz ligature)
1069 "THORN" => '\\*(Th', # capital THORN, Icelandic
1070 "thorn" => '\\*(th',, # small thorn, Icelandic
1071 "Uacute" => "U\\*'", # capital U, acute accent
1072 "uacute" => "u\\*'", # small u, acute accent
1073 "Ucirc" => "U\\*^", # capital U, circumflex accent
1074 "ucirc" => "u\\*^", # small u, circumflex accent
1075 "Ugrave" => "U\\*`", # capital U, grave accent
1076 "ugrave" => "u\\*`", # small u, grave accent
1077 "Uuml" => "U\\*:", # capital U, dieresis or umlaut mark
1078 "uuml" => "u\\*:", # small u, dieresis or umlaut mark
1079 "Yacute" => "Y\\*'", # capital Y, acute accent
1080 "yacute" => "y\\*'", # small y, acute accent
1081 "yuml" => "y\\*:", # small y, dieresis or umlaut mark
1082);
1083}
cb1a09d0 1084
5d94fbed 1085!NO!SUBS!
4633a7c4
LW
1086
1087close OUT or die "Can't close $file: $!";
1088chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
1089exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';