| 1 | # Pod::Man -- Convert POD data to formatted *roff input.
|
|---|
| 2 | # $Id: Man.pm,v 1.37 2003/03/30 22:34:11 eagle Exp $
|
|---|
| 3 | #
|
|---|
| 4 | # Copyright 1999, 2000, 2001, 2002, 2003 by Russ Allbery <[email protected]>
|
|---|
| 5 | #
|
|---|
| 6 | # This program is free software; you may redistribute it and/or modify it
|
|---|
| 7 | # under the same terms as Perl itself.
|
|---|
| 8 | #
|
|---|
| 9 | # This module translates POD documentation into *roff markup using the man
|
|---|
| 10 | # macro set, and is intended for converting POD documents written as Unix
|
|---|
| 11 | # manual pages to manual pages that can be read by the man(1) command. It is
|
|---|
| 12 | # a replacement for the pod2man command distributed with versions of Perl
|
|---|
| 13 | # prior to 5.6.
|
|---|
| 14 | #
|
|---|
| 15 | # Perl core hackers, please note that this module is also separately
|
|---|
| 16 | # maintained outside of the Perl core as part of the podlators. Please send
|
|---|
| 17 | # me any patches at the address above in addition to sending them to the
|
|---|
| 18 | # standard Perl mailing lists.
|
|---|
| 19 |
|
|---|
| 20 | ##############################################################################
|
|---|
| 21 | # Modules and declarations
|
|---|
| 22 | ##############################################################################
|
|---|
| 23 |
|
|---|
| 24 | package Pod::Man;
|
|---|
| 25 |
|
|---|
| 26 | require 5.005;
|
|---|
| 27 |
|
|---|
| 28 | use Carp qw(carp croak);
|
|---|
| 29 | use Pod::ParseLink qw(parselink);
|
|---|
| 30 | use Pod::Parser ();
|
|---|
| 31 |
|
|---|
| 32 | use strict;
|
|---|
| 33 | use subs qw(makespace);
|
|---|
| 34 | use vars qw(@ISA %ESCAPES $PREAMBLE $VERSION);
|
|---|
| 35 |
|
|---|
| 36 | @ISA = qw(Pod::Parser);
|
|---|
| 37 |
|
|---|
| 38 | # Don't use the CVS revision as the version, since this module is also in Perl
|
|---|
| 39 | # core and too many things could munge CVS magic revision strings. This
|
|---|
| 40 | # number should ideally be the same as the CVS revision in podlators, however.
|
|---|
| 41 | $VERSION = 1.37;
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 | ##############################################################################
|
|---|
| 45 | # Preamble and *roff output tables
|
|---|
| 46 | ##############################################################################
|
|---|
| 47 |
|
|---|
| 48 | # The following is the static preamble which starts all *roff output we
|
|---|
| 49 | # generate. It's completely static except for the font to use as a
|
|---|
| 50 | # fixed-width font, which is designed by @CFONT@, and the left and right
|
|---|
| 51 | # quotes to use for C<> text, designated by @LQOUTE@ and @RQUOTE@. $PREAMBLE
|
|---|
| 52 | # should therefore be run through s/\@CFONT\@/<font>/g before output.
|
|---|
| 53 | $PREAMBLE = <<'----END OF PREAMBLE----';
|
|---|
| 54 | .de Sh \" Subsection heading
|
|---|
| 55 | .br
|
|---|
| 56 | .if t .Sp
|
|---|
| 57 | .ne 5
|
|---|
| 58 | .PP
|
|---|
| 59 | \fB\\$1\fR
|
|---|
| 60 | .PP
|
|---|
| 61 | ..
|
|---|
| 62 | .de Sp \" Vertical space (when we can't use .PP)
|
|---|
| 63 | .if t .sp .5v
|
|---|
| 64 | .if n .sp
|
|---|
| 65 | ..
|
|---|
| 66 | .de Vb \" Begin verbatim text
|
|---|
| 67 | .ft @CFONT@
|
|---|
| 68 | .nf
|
|---|
| 69 | .ne \\$1
|
|---|
| 70 | ..
|
|---|
| 71 | .de Ve \" End verbatim text
|
|---|
| 72 | .ft R
|
|---|
| 73 | .fi
|
|---|
| 74 | ..
|
|---|
| 75 | .\" Set up some character translations and predefined strings. \*(-- will
|
|---|
| 76 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
|---|
| 77 | .\" double quote, and \*(R" will give a right double quote. | will give a
|
|---|
| 78 | .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to
|
|---|
| 79 | .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C'
|
|---|
| 80 | .\" expand to `' in nroff, nothing in troff, for use with C<>.
|
|---|
| 81 | .tr \(*W-|\(bv\*(Tr
|
|---|
| 82 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
|---|
| 83 | .ie n \{\
|
|---|
| 84 | . ds -- \(*W-
|
|---|
| 85 | . ds PI pi
|
|---|
| 86 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
|---|
| 87 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
|---|
| 88 | . ds L" ""
|
|---|
| 89 | . ds R" ""
|
|---|
| 90 | . ds C` @LQUOTE@
|
|---|
| 91 | . ds C' @RQUOTE@
|
|---|
| 92 | 'br\}
|
|---|
| 93 | .el\{\
|
|---|
| 94 | . ds -- \|\(em\|
|
|---|
| 95 | . ds PI \(*p
|
|---|
| 96 | . ds L" ``
|
|---|
| 97 | . ds R" ''
|
|---|
| 98 | 'br\}
|
|---|
| 99 | .\"
|
|---|
| 100 | .\" If the F register is turned on, we'll generate index entries on stderr for
|
|---|
| 101 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
|
|---|
| 102 | .\" entries marked with X<> in POD. Of course, you'll have to process the
|
|---|
| 103 | .\" output yourself in some meaningful fashion.
|
|---|
| 104 | .if \nF \{\
|
|---|
| 105 | . de IX
|
|---|
| 106 | . tm Index:\\$1\t\\n%\t"\\$2"
|
|---|
| 107 | ..
|
|---|
| 108 | . nr % 0
|
|---|
| 109 | . rr F
|
|---|
| 110 | .\}
|
|---|
| 111 | .\"
|
|---|
| 112 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
|---|
| 113 | .\" way too many mistakes in technical documents.
|
|---|
| 114 | .hy 0
|
|---|
| 115 | .if n .na
|
|---|
| 116 | .\"
|
|---|
| 117 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
|---|
| 118 | .\" Fear. Run. Save yourself. No user-serviceable parts.
|
|---|
| 119 | . \" fudge factors for nroff and troff
|
|---|
| 120 | .if n \{\
|
|---|
| 121 | . ds #H 0
|
|---|
| 122 | . ds #V .8m
|
|---|
| 123 | . ds #F .3m
|
|---|
| 124 | . ds #[ \f1
|
|---|
| 125 | . ds #] \fP
|
|---|
| 126 | .\}
|
|---|
| 127 | .if t \{\
|
|---|
| 128 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
|---|
| 129 | . ds #V .6m
|
|---|
| 130 | . ds #F 0
|
|---|
| 131 | . ds #[ \&
|
|---|
| 132 | . ds #] \&
|
|---|
| 133 | .\}
|
|---|
| 134 | . \" simple accents for nroff and troff
|
|---|
| 135 | .if n \{\
|
|---|
| 136 | . ds ' \&
|
|---|
| 137 | . ds ` \&
|
|---|
| 138 | . ds ^ \&
|
|---|
| 139 | . ds , \&
|
|---|
| 140 | . ds ~ ~
|
|---|
| 141 | . ds /
|
|---|
| 142 | .\}
|
|---|
| 143 | .if t \{\
|
|---|
| 144 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
|---|
| 145 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
|---|
| 146 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
|---|
| 147 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
|---|
| 148 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
|---|
| 149 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
|---|
| 150 | .\}
|
|---|
| 151 | . \" troff and (daisy-wheel) nroff accents
|
|---|
| 152 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
|---|
| 153 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
|---|
| 154 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
|---|
| 155 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
|---|
| 156 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
|---|
| 157 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
|---|
| 158 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
|---|
| 159 | .ds ae a\h'-(\w'a'u*4/10)'e
|
|---|
| 160 | .ds Ae A\h'-(\w'A'u*4/10)'E
|
|---|
| 161 | . \" corrections for vroff
|
|---|
| 162 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
|---|
| 163 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
|---|
| 164 | . \" for low resolution devices (crt and lpr)
|
|---|
| 165 | .if \n(.H>23 .if \n(.V>19 \
|
|---|
| 166 | \{\
|
|---|
| 167 | . ds : e
|
|---|
| 168 | . ds 8 ss
|
|---|
| 169 | . ds o a
|
|---|
| 170 | . ds d- d\h'-1'\(ga
|
|---|
| 171 | . ds D- D\h'-1'\(hy
|
|---|
| 172 | . ds th \o'bp'
|
|---|
| 173 | . ds Th \o'LP'
|
|---|
| 174 | . ds ae ae
|
|---|
| 175 | . ds Ae AE
|
|---|
| 176 | .\}
|
|---|
| 177 | .rm #[ #] #H #V #F C
|
|---|
| 178 | ----END OF PREAMBLE----
|
|---|
| 179 | #`# for cperl-mode
|
|---|
| 180 |
|
|---|
| 181 | # This table is taken nearly verbatim from Tom Christiansen's pod2man. It
|
|---|
| 182 | # assumes that the standard preamble has already been printed, since that's
|
|---|
| 183 | # what defines all of the accent marks. Note that some of these are quoted
|
|---|
| 184 | # with double quotes since they contain embedded single quotes, so use \\
|
|---|
| 185 | # uniformly for backslash for readability.
|
|---|
| 186 | %ESCAPES = (
|
|---|
| 187 | 'amp' => '&', # ampersand
|
|---|
| 188 | 'apos' => "'", # apostrophe
|
|---|
| 189 | 'lt' => '<', # left chevron, less-than
|
|---|
| 190 | 'gt' => '>', # right chevron, greater-than
|
|---|
| 191 | 'quot' => '"', # double quote
|
|---|
| 192 | 'sol' => '/', # solidus (forward slash)
|
|---|
| 193 | 'verbar' => '|', # vertical bar
|
|---|
| 194 |
|
|---|
| 195 | 'Aacute' => "A\\*'", # capital A, acute accent
|
|---|
| 196 | 'aacute' => "a\\*'", # small a, acute accent
|
|---|
| 197 | 'Acirc' => 'A\\*^', # capital A, circumflex accent
|
|---|
| 198 | 'acirc' => 'a\\*^', # small a, circumflex accent
|
|---|
| 199 | 'AElig' => '\*(AE', # capital AE diphthong (ligature)
|
|---|
| 200 | 'aelig' => '\*(ae', # small ae diphthong (ligature)
|
|---|
| 201 | 'Agrave' => "A\\*`", # capital A, grave accent
|
|---|
| 202 | 'agrave' => "A\\*`", # small a, grave accent
|
|---|
| 203 | 'Aring' => 'A\\*o', # capital A, ring
|
|---|
| 204 | 'aring' => 'a\\*o', # small a, ring
|
|---|
| 205 | 'Atilde' => 'A\\*~', # capital A, tilde
|
|---|
| 206 | 'atilde' => 'a\\*~', # small a, tilde
|
|---|
| 207 | 'Auml' => 'A\\*:', # capital A, dieresis or umlaut mark
|
|---|
| 208 | 'auml' => 'a\\*:', # small a, dieresis or umlaut mark
|
|---|
| 209 | 'Ccedil' => 'C\\*,', # capital C, cedilla
|
|---|
| 210 | 'ccedil' => 'c\\*,', # small c, cedilla
|
|---|
| 211 | 'Eacute' => "E\\*'", # capital E, acute accent
|
|---|
| 212 | 'eacute' => "e\\*'", # small e, acute accent
|
|---|
| 213 | 'Ecirc' => 'E\\*^', # capital E, circumflex accent
|
|---|
| 214 | 'ecirc' => 'e\\*^', # small e, circumflex accent
|
|---|
| 215 | 'Egrave' => 'E\\*`', # capital E, grave accent
|
|---|
| 216 | 'egrave' => 'e\\*`', # small e, grave accent
|
|---|
| 217 | 'ETH' => '\\*(D-', # capital Eth, Icelandic
|
|---|
| 218 | 'eth' => '\\*(d-', # small eth, Icelandic
|
|---|
| 219 | 'Euml' => 'E\\*:', # capital E, dieresis or umlaut mark
|
|---|
| 220 | 'euml' => 'e\\*:', # small e, dieresis or umlaut mark
|
|---|
| 221 | 'Iacute' => "I\\*'", # capital I, acute accent
|
|---|
| 222 | 'iacute' => "i\\*'", # small i, acute accent
|
|---|
| 223 | 'Icirc' => 'I\\*^', # capital I, circumflex accent
|
|---|
| 224 | 'icirc' => 'i\\*^', # small i, circumflex accent
|
|---|
| 225 | 'Igrave' => 'I\\*`', # capital I, grave accent
|
|---|
| 226 | 'igrave' => 'i\\*`', # small i, grave accent
|
|---|
| 227 | 'Iuml' => 'I\\*:', # capital I, dieresis or umlaut mark
|
|---|
| 228 | 'iuml' => 'i\\*:', # small i, dieresis or umlaut mark
|
|---|
| 229 | 'Ntilde' => 'N\*~', # capital N, tilde
|
|---|
| 230 | 'ntilde' => 'n\*~', # small n, tilde
|
|---|
| 231 | 'Oacute' => "O\\*'", # capital O, acute accent
|
|---|
| 232 | 'oacute' => "o\\*'", # small o, acute accent
|
|---|
| 233 | 'Ocirc' => 'O\\*^', # capital O, circumflex accent
|
|---|
| 234 | 'ocirc' => 'o\\*^', # small o, circumflex accent
|
|---|
| 235 | 'Ograve' => 'O\\*`', # capital O, grave accent
|
|---|
| 236 | 'ograve' => 'o\\*`', # small o, grave accent
|
|---|
| 237 | 'Oslash' => 'O\\*/', # capital O, slash
|
|---|
| 238 | 'oslash' => 'o\\*/', # small o, slash
|
|---|
| 239 | 'Otilde' => 'O\\*~', # capital O, tilde
|
|---|
| 240 | 'otilde' => 'o\\*~', # small o, tilde
|
|---|
| 241 | 'Ouml' => 'O\\*:', # capital O, dieresis or umlaut mark
|
|---|
| 242 | 'ouml' => 'o\\*:', # small o, dieresis or umlaut mark
|
|---|
| 243 | 'szlig' => '\*8', # small sharp s, German (sz ligature)
|
|---|
| 244 | 'THORN' => '\\*(Th', # capital THORN, Icelandic
|
|---|
| 245 | 'thorn' => '\\*(th', # small thorn, Icelandic
|
|---|
| 246 | 'Uacute' => "U\\*'", # capital U, acute accent
|
|---|
| 247 | 'uacute' => "u\\*'", # small u, acute accent
|
|---|
| 248 | 'Ucirc' => 'U\\*^', # capital U, circumflex accent
|
|---|
| 249 | 'ucirc' => 'u\\*^', # small u, circumflex accent
|
|---|
| 250 | 'Ugrave' => 'U\\*`', # capital U, grave accent
|
|---|
| 251 | 'ugrave' => 'u\\*`', # small u, grave accent
|
|---|
| 252 | 'Uuml' => 'U\\*:', # capital U, dieresis or umlaut mark
|
|---|
| 253 | 'uuml' => 'u\\*:', # small u, dieresis or umlaut mark
|
|---|
| 254 | 'Yacute' => "Y\\*'", # capital Y, acute accent
|
|---|
| 255 | 'yacute' => "y\\*'", # small y, acute accent
|
|---|
| 256 | 'yuml' => 'y\\*:', # small y, dieresis or umlaut mark
|
|---|
| 257 |
|
|---|
| 258 | 'nbsp' => '\\ ', # non-breaking space
|
|---|
| 259 | 'shy' => '', # soft (discretionary) hyphen
|
|---|
| 260 | );
|
|---|
| 261 |
|
|---|
| 262 |
|
|---|
| 263 | ##############################################################################
|
|---|
| 264 | # Static helper functions
|
|---|
| 265 | ##############################################################################
|
|---|
| 266 |
|
|---|
| 267 | # Protect leading quotes and periods against interpretation as commands. Also
|
|---|
| 268 | # protect anything starting with a backslash, since it could expand or hide
|
|---|
| 269 | # something that *roff would interpret as a command. This is overkill, but
|
|---|
| 270 | # it's much simpler than trying to parse *roff here.
|
|---|
| 271 | sub protect {
|
|---|
| 272 | local $_ = shift;
|
|---|
| 273 | s/^([.\'\\])/\\&$1/mg;
|
|---|
| 274 | $_;
|
|---|
| 275 | }
|
|---|
| 276 |
|
|---|
| 277 | # Translate a font string into an escape.
|
|---|
| 278 | sub toescape { (length ($_[0]) > 1 ? '\f(' : '\f') . $_[0] }
|
|---|
| 279 |
|
|---|
| 280 |
|
|---|
| 281 | ##############################################################################
|
|---|
| 282 | # Initialization
|
|---|
| 283 | ##############################################################################
|
|---|
| 284 |
|
|---|
| 285 | # Initialize the object. Here, we also process any additional options passed
|
|---|
| 286 | # to the constructor or set up defaults if none were given. center is the
|
|---|
| 287 | # centered title, release is the version number, and date is the date for the
|
|---|
| 288 | # documentation. Note that we can't know what file name we're processing due
|
|---|
| 289 | # to the architecture of Pod::Parser, so that *has* to either be passed to the
|
|---|
| 290 | # constructor or set separately with Pod::Man::name().
|
|---|
| 291 | sub initialize {
|
|---|
| 292 | my $self = shift;
|
|---|
| 293 |
|
|---|
| 294 | # Figure out the fixed-width font. If user-supplied, make sure that they
|
|---|
| 295 | # are the right length.
|
|---|
| 296 | for (qw/fixed fixedbold fixeditalic fixedbolditalic/) {
|
|---|
| 297 | if (defined $$self{$_}) {
|
|---|
| 298 | if (length ($$self{$_}) < 1 || length ($$self{$_}) > 2) {
|
|---|
| 299 | croak qq(roff font should be 1 or 2 chars,)
|
|---|
| 300 | . qq( not "$$self{$_}");
|
|---|
| 301 | }
|
|---|
| 302 | } else {
|
|---|
| 303 | $$self{$_} = '';
|
|---|
| 304 | }
|
|---|
| 305 | }
|
|---|
| 306 |
|
|---|
| 307 | # Set the default fonts. We can't be sure what fixed bold-italic is going
|
|---|
| 308 | # to be called, so default to just bold.
|
|---|
| 309 | $$self{fixed} ||= 'CW';
|
|---|
| 310 | $$self{fixedbold} ||= 'CB';
|
|---|
| 311 | $$self{fixeditalic} ||= 'CI';
|
|---|
| 312 | $$self{fixedbolditalic} ||= 'CB';
|
|---|
| 313 |
|
|---|
| 314 | # Set up a table of font escapes. First number is fixed-width, second is
|
|---|
| 315 | # bold, third is italic.
|
|---|
| 316 | $$self{FONTS} = { '000' => '\fR', '001' => '\fI',
|
|---|
| 317 | '010' => '\fB', '011' => '\f(BI',
|
|---|
| 318 | '100' => toescape ($$self{fixed}),
|
|---|
| 319 | '101' => toescape ($$self{fixeditalic}),
|
|---|
| 320 | '110' => toescape ($$self{fixedbold}),
|
|---|
| 321 | '111' => toescape ($$self{fixedbolditalic})};
|
|---|
| 322 |
|
|---|
| 323 | # Extra stuff for page titles.
|
|---|
| 324 | $$self{center} = 'User Contributed Perl Documentation'
|
|---|
| 325 | unless defined $$self{center};
|
|---|
| 326 | $$self{indent} = 4 unless defined $$self{indent};
|
|---|
| 327 |
|
|---|
| 328 | # We used to try first to get the version number from a local binary, but
|
|---|
| 329 | # we shouldn't need that any more. Get the version from the running Perl.
|
|---|
| 330 | # Work a little magic to handle subversions correctly under both the
|
|---|
| 331 | # pre-5.6 and the post-5.6 version numbering schemes.
|
|---|
| 332 | if (!defined $$self{release}) {
|
|---|
| 333 | my @version = ($] =~ /^(\d+)\.(\d{3})(\d{0,3})$/);
|
|---|
| 334 | $version[2] ||= 0;
|
|---|
| 335 | $version[2] *= 10 ** (3 - length $version[2]);
|
|---|
| 336 | for (@version) { $_ += 0 }
|
|---|
| 337 | $$self{release} = 'perl v' . join ('.', @version);
|
|---|
| 338 | }
|
|---|
| 339 |
|
|---|
| 340 | # Double quotes in things that will be quoted.
|
|---|
| 341 | for (qw/center date release/) {
|
|---|
| 342 | $$self{$_} =~ s/\"/\"\"/g if $$self{$_};
|
|---|
| 343 | }
|
|---|
| 344 |
|
|---|
| 345 | # Figure out what quotes we'll be using for C<> text.
|
|---|
| 346 | $$self{quotes} ||= '"';
|
|---|
| 347 | if ($$self{quotes} eq 'none') {
|
|---|
| 348 | $$self{LQUOTE} = $$self{RQUOTE} = '';
|
|---|
| 349 | } elsif (length ($$self{quotes}) == 1) {
|
|---|
| 350 | $$self{LQUOTE} = $$self{RQUOTE} = $$self{quotes};
|
|---|
| 351 | } elsif ($$self{quotes} =~ /^(.)(.)$/
|
|---|
| 352 | || $$self{quotes} =~ /^(..)(..)$/) {
|
|---|
| 353 | $$self{LQUOTE} = $1;
|
|---|
| 354 | $$self{RQUOTE} = $2;
|
|---|
| 355 | } else {
|
|---|
| 356 | croak qq(Invalid quote specification "$$self{quotes}");
|
|---|
| 357 | }
|
|---|
| 358 |
|
|---|
| 359 | # Double the first quote; note that this should not be s///g as two double
|
|---|
| 360 | # quotes is represented in *roff as three double quotes, not four. Weird,
|
|---|
| 361 | # I know.
|
|---|
| 362 | $$self{LQUOTE} =~ s/\"/\"\"/;
|
|---|
| 363 | $$self{RQUOTE} =~ s/\"/\"\"/;
|
|---|
| 364 |
|
|---|
| 365 | $self->SUPER::initialize;
|
|---|
| 366 | }
|
|---|
| 367 |
|
|---|
| 368 | # For each document we process, output the preamble first.
|
|---|
| 369 | sub begin_pod {
|
|---|
| 370 | my $self = shift;
|
|---|
| 371 |
|
|---|
| 372 | # Try to figure out the name and section from the file name.
|
|---|
| 373 | my $section = $$self{section} || 1;
|
|---|
| 374 | my $name = $$self{name};
|
|---|
| 375 | if (!defined $name) {
|
|---|
| 376 | $name = $self->input_file;
|
|---|
| 377 | $section = 3 if (!$$self{section} && $name =~ /\.pm\z/i);
|
|---|
| 378 | $name =~ s/\.p(od|[lm])\z//i;
|
|---|
| 379 | if ($section !~ /^3/) {
|
|---|
| 380 | require File::Basename;
|
|---|
| 381 | $name = uc File::Basename::basename ($name);
|
|---|
| 382 | } else {
|
|---|
| 383 | # Assume that we're dealing with a module. We want to figure out
|
|---|
| 384 | # the full module name from the path to the file, but we don't
|
|---|
| 385 | # want to include too much of the path into the module name. Lose
|
|---|
| 386 | # everything up to the first of:
|
|---|
| 387 | #
|
|---|
| 388 | # */lib/*perl*/ standard or site_perl module
|
|---|
| 389 | # */*perl*/lib/ from -Dprefix=/opt/perl
|
|---|
| 390 | # */*perl*/ random module hierarchy
|
|---|
| 391 | #
|
|---|
| 392 | # which works. Also strip off a leading site or site_perl
|
|---|
| 393 | # component, any OS-specific component, and any version number
|
|---|
| 394 | # component, and strip off an initial component of "lib" or
|
|---|
| 395 | # "blib/lib" since that's what ExtUtils::MakeMaker creates.
|
|---|
| 396 | # splitdir requires at least File::Spec 0.8.
|
|---|
| 397 | require File::Spec;
|
|---|
| 398 | my ($volume, $dirs, $file) = File::Spec->splitpath ($name);
|
|---|
| 399 | my @dirs = File::Spec->splitdir ($dirs);
|
|---|
| 400 | my $cut = 0;
|
|---|
| 401 | my $i;
|
|---|
| 402 | for ($i = 0; $i < scalar @dirs; $i++) {
|
|---|
| 403 | if ($dirs[$i] eq 'lib' && $dirs[$i + 1] =~ /perl/) {
|
|---|
| 404 | $cut = $i + 2;
|
|---|
| 405 | last;
|
|---|
| 406 | } elsif ($dirs[$i] =~ /perl/) {
|
|---|
| 407 | $cut = $i + 1;
|
|---|
| 408 | $cut++ if $dirs[$i + 1] eq 'lib';
|
|---|
| 409 | last;
|
|---|
| 410 | }
|
|---|
| 411 | }
|
|---|
| 412 | if ($cut > 0) {
|
|---|
| 413 | splice (@dirs, 0, $cut);
|
|---|
| 414 | shift @dirs if ($dirs[0] =~ /^site(_perl)?$/);
|
|---|
| 415 | shift @dirs if ($dirs[0] =~ /^[\d.]+$/);
|
|---|
| 416 | shift @dirs if ($dirs[0] =~ /^(.*-$^O|$^O-.*|$^O)$/);
|
|---|
| 417 | }
|
|---|
| 418 | shift @dirs if $dirs[0] eq 'lib';
|
|---|
| 419 | splice (@dirs, 0, 2) if ($dirs[0] eq 'blib' && $dirs[1] eq 'lib');
|
|---|
| 420 |
|
|---|
| 421 | # Remove empty directories when building the module name; they
|
|---|
| 422 | # occur too easily on Unix by doubling slashes.
|
|---|
| 423 | $name = join ('::', (grep { $_ ? $_ : () } @dirs), $file);
|
|---|
| 424 | }
|
|---|
| 425 | }
|
|---|
| 426 |
|
|---|
| 427 | # If $name contains spaces, quote it; this mostly comes up in the case of
|
|---|
| 428 | # input from stdin.
|
|---|
| 429 | $name = '"' . $name . '"' if ($name =~ /\s/);
|
|---|
| 430 |
|
|---|
| 431 | # Modification date header. Try to use the modification time of our
|
|---|
| 432 | # input.
|
|---|
| 433 | if (!defined $$self{date}) {
|
|---|
| 434 | my $time = (stat $self->input_file)[9] || time;
|
|---|
| 435 | my ($day, $month, $year) = (localtime $time)[3,4,5];
|
|---|
| 436 | $month++;
|
|---|
| 437 | $year += 1900;
|
|---|
| 438 | $$self{date} = sprintf ('%4d-%02d-%02d', $year, $month, $day);
|
|---|
| 439 | }
|
|---|
| 440 |
|
|---|
| 441 | # Now, print out the preamble and the title. The meaning of the arguments
|
|---|
| 442 | # to .TH unfortunately vary by system; some systems consider the fourth
|
|---|
| 443 | # argument to be a "source" and others use it as a version number.
|
|---|
| 444 | # Generally it's just presented as the left-side footer, though, so it
|
|---|
| 445 | # doesn't matter too much if a particular system gives it another
|
|---|
| 446 | # interpretation.
|
|---|
| 447 | #
|
|---|
| 448 | # The order of date and release used to be reversed in older versions of
|
|---|
| 449 | # this module, but this order is correct for both Solaris and Linux.
|
|---|
| 450 | local $_ = $PREAMBLE;
|
|---|
| 451 | s/\@CFONT\@/$$self{fixed}/;
|
|---|
| 452 | s/\@LQUOTE\@/$$self{LQUOTE}/;
|
|---|
| 453 | s/\@RQUOTE\@/$$self{RQUOTE}/;
|
|---|
| 454 | chomp $_;
|
|---|
| 455 | my $pversion = $Pod::Parser::VERSION;
|
|---|
| 456 | print { $self->output_handle } <<"----END OF HEADER----";
|
|---|
| 457 | .\\" Automatically generated by Pod::Man v$VERSION, Pod::Parser v$pversion
|
|---|
| 458 | .\\"
|
|---|
| 459 | .\\" Standard preamble:
|
|---|
| 460 | .\\" ========================================================================
|
|---|
| 461 | $_
|
|---|
| 462 | .\\" ========================================================================
|
|---|
| 463 | .\\"
|
|---|
| 464 | .IX Title "$name $section"
|
|---|
| 465 | .TH $name $section "$$self{date}" "$$self{release}" "$$self{center}"
|
|---|
| 466 | ----END OF HEADER----
|
|---|
| 467 |
|
|---|
| 468 | # Initialize a few per-file variables.
|
|---|
| 469 | $$self{INDENT} = 0; # Current indentation level.
|
|---|
| 470 | $$self{INDENTS} = []; # Stack of indentations.
|
|---|
| 471 | $$self{INDEX} = []; # Index keys waiting to be printed.
|
|---|
| 472 | $$self{IN_NAME} = 0; # Whether processing the NAME section.
|
|---|
| 473 | $$self{ITEMS} = 0; # The number of consecutive =items.
|
|---|
| 474 | $$self{ITEMTYPES} = []; # Stack of =item types, one per list.
|
|---|
| 475 | $$self{SHIFTWAIT} = 0; # Whether there is a shift waiting.
|
|---|
| 476 | $$self{SHIFTS} = []; # Stack of .RS shifts.
|
|---|
| 477 | }
|
|---|
| 478 |
|
|---|
| 479 |
|
|---|
| 480 | ##############################################################################
|
|---|
| 481 | # Core overrides
|
|---|
| 482 | ##############################################################################
|
|---|
| 483 |
|
|---|
| 484 | # Called for each command paragraph. Gets the command, the associated
|
|---|
| 485 | # paragraph, the line number, and a Pod::Paragraph object. Just dispatches
|
|---|
| 486 | # the command to a method named the same as the command. =cut is handled
|
|---|
| 487 | # internally by Pod::Parser.
|
|---|
| 488 | sub command {
|
|---|
| 489 | my $self = shift;
|
|---|
| 490 | my $command = shift;
|
|---|
| 491 | return if $command eq 'pod';
|
|---|
| 492 | return if ($$self{EXCLUDE} && $command ne 'end');
|
|---|
| 493 | if ($self->can ('cmd_' . $command)) {
|
|---|
| 494 | $command = 'cmd_' . $command;
|
|---|
| 495 | $self->$command (@_);
|
|---|
| 496 | } else {
|
|---|
| 497 | my ($text, $line, $paragraph) = @_;
|
|---|
| 498 | my $file;
|
|---|
| 499 | ($file, $line) = $paragraph->file_line;
|
|---|
| 500 | $text =~ s/\n+\z//;
|
|---|
| 501 | $text = " $text" if ($text =~ /^\S/);
|
|---|
| 502 | warn qq($file:$line: Unknown command paragraph "=$command$text"\n);
|
|---|
| 503 | return;
|
|---|
| 504 | }
|
|---|
| 505 | }
|
|---|
| 506 |
|
|---|
| 507 | # Called for a verbatim paragraph. Gets the paragraph, the line number, and a
|
|---|
| 508 | # Pod::Paragraph object. Rofficate backslashes, untabify, put a zero-width
|
|---|
| 509 | # character at the beginning of each line to protect against commands, and
|
|---|
| 510 | # wrap in .Vb/.Ve.
|
|---|
| 511 | sub verbatim {
|
|---|
| 512 | my $self = shift;
|
|---|
| 513 | return if $$self{EXCLUDE};
|
|---|
| 514 | local $_ = shift;
|
|---|
| 515 | return if /^\s+$/;
|
|---|
| 516 | s/\s+$/\n/;
|
|---|
| 517 | my $lines = tr/\n/\n/;
|
|---|
| 518 | 1 while s/^(.*?)(\t+)/$1 . ' ' x (length ($2) * 8 - length ($1) % 8)/me;
|
|---|
| 519 | s/\\/\\e/g;
|
|---|
| 520 | s/^(\s*\S)/'\&' . $1/gme;
|
|---|
| 521 | $self->makespace;
|
|---|
| 522 | $self->output (".Vb $lines\n$_.Ve\n");
|
|---|
| 523 | $$self{NEEDSPACE} = 1;
|
|---|
| 524 | }
|
|---|
| 525 |
|
|---|
| 526 | # Called for a regular text block. Gets the paragraph, the line number, and a
|
|---|
| 527 | # Pod::Paragraph object. Perform interpolation and output the results.
|
|---|
| 528 | sub textblock {
|
|---|
| 529 | my $self = shift;
|
|---|
| 530 | return if $$self{EXCLUDE};
|
|---|
| 531 | $self->output ($_[0]), return if $$self{VERBATIM};
|
|---|
| 532 |
|
|---|
| 533 | # Parse the tree. collapse knows about references to scalars as well as
|
|---|
| 534 | # scalars and does the right thing with them. Tidy up any trailing
|
|---|
| 535 | # whitespace.
|
|---|
| 536 | my $text = shift;
|
|---|
| 537 | $text = $self->parse ($text, @_);
|
|---|
| 538 | $text =~ s/\n\s*$/\n/;
|
|---|
| 539 |
|
|---|
| 540 | # Output the paragraph. We also have to handle =over without =item. If
|
|---|
| 541 | # there's an =over without =item, SHIFTWAIT will be set, and we need to
|
|---|
| 542 | # handle creation of the indent here. Add the shift to SHIFTS so that it
|
|---|
| 543 | # will be cleaned up on =back.
|
|---|
| 544 | $self->makespace;
|
|---|
| 545 | if ($$self{SHIFTWAIT}) {
|
|---|
| 546 | $self->output (".RS $$self{INDENT}\n");
|
|---|
| 547 | push (@{ $$self{SHIFTS} }, $$self{INDENT});
|
|---|
| 548 | $$self{SHIFTWAIT} = 0;
|
|---|
| 549 | }
|
|---|
| 550 | $self->output (protect $self->textmapfonts ($text));
|
|---|
| 551 | $self->outindex;
|
|---|
| 552 | $$self{NEEDSPACE} = 1;
|
|---|
| 553 | }
|
|---|
| 554 |
|
|---|
| 555 | # Called for a formatting code. Takes a Pod::InteriorSequence object and
|
|---|
| 556 | # returns a reference to a scalar. This scalar is the final formatted text.
|
|---|
| 557 | # It's returned as a reference to an array so that other formatting codes
|
|---|
| 558 | # above us know that the text has already been processed.
|
|---|
| 559 | sub sequence {
|
|---|
| 560 | my ($self, $seq) = @_;
|
|---|
| 561 | my $command = $seq->cmd_name;
|
|---|
| 562 |
|
|---|
| 563 | # We have to defer processing of the inside of an L<> formatting code. If
|
|---|
| 564 | # this code is nested inside an L<> code, return the literal raw text of
|
|---|
| 565 | # it.
|
|---|
| 566 | my $parent = $seq->nested;
|
|---|
| 567 | while (defined $parent) {
|
|---|
| 568 | return $seq->raw_text if ($parent->cmd_name eq 'L');
|
|---|
| 569 | $parent = $parent->nested;
|
|---|
| 570 | }
|
|---|
| 571 |
|
|---|
| 572 | # Zero-width characters.
|
|---|
| 573 | return [ '\&' ] if ($command eq 'Z');
|
|---|
| 574 |
|
|---|
| 575 | # C<>, L<>, X<>, and E<> don't apply guesswork to their contents. C<>
|
|---|
| 576 | # needs some additional special handling.
|
|---|
| 577 | my $literal = ($command =~ /^[CELX]$/);
|
|---|
| 578 | local $_ = $self->collapse ($seq->parse_tree, $literal, $command eq 'C');
|
|---|
| 579 |
|
|---|
| 580 | # Handle E<> escapes. Numeric escapes that match one of the supported ISO
|
|---|
| 581 | # 8859-1 characters don't work at present.
|
|---|
| 582 | if ($command eq 'E') {
|
|---|
| 583 | if (/^\d+$/) {
|
|---|
| 584 | return [ chr ($_) ];
|
|---|
| 585 | } elsif (exists $ESCAPES{$_}) {
|
|---|
| 586 | return [ $ESCAPES{$_} ];
|
|---|
| 587 | } else {
|
|---|
| 588 | my ($file, $line) = $seq->file_line;
|
|---|
| 589 | warn "$file:$line: Unknown escape E<$_>\n";
|
|---|
| 590 | return [ "E<$_>" ];
|
|---|
| 591 | }
|
|---|
| 592 | }
|
|---|
| 593 |
|
|---|
| 594 | # For all the other codes, empty content produces no output.
|
|---|
| 595 | return '' if $_ eq '';
|
|---|
| 596 |
|
|---|
| 597 | # Handle simple formatting codes.
|
|---|
| 598 | if ($command eq 'B') {
|
|---|
| 599 | return [ '\f(BS' . $_ . '\f(BE' ];
|
|---|
| 600 | } elsif ($command eq 'F' || $command eq 'I') {
|
|---|
| 601 | return [ '\f(IS' . $_ . '\f(IE' ];
|
|---|
| 602 | } elsif ($command eq 'C') {
|
|---|
| 603 | return [ $self->quote_literal ($_) ];
|
|---|
| 604 | }
|
|---|
| 605 |
|
|---|
| 606 | # Handle links.
|
|---|
| 607 | if ($command eq 'L') {
|
|---|
| 608 | my ($text, $type) = (parselink ($_))[1,4];
|
|---|
| 609 | return '' unless $text;
|
|---|
| 610 | my ($file, $line) = $seq->file_line;
|
|---|
| 611 | $text = $self->parse ($text, $line);
|
|---|
| 612 | $text = '<' . $text . '>' if $type eq 'url';
|
|---|
| 613 | return [ $text ];
|
|---|
| 614 | }
|
|---|
| 615 |
|
|---|
| 616 | # Whitespace protection replaces whitespace with "\ ".
|
|---|
| 617 | if ($command eq 'S') {
|
|---|
| 618 | s/\s+/\\ /g;
|
|---|
| 619 | return [ $_ ];
|
|---|
| 620 | }
|
|---|
| 621 |
|
|---|
| 622 | # Add an index entry to the list of ones waiting to be output.
|
|---|
| 623 | if ($command eq 'X') {
|
|---|
| 624 | push (@{ $$self{INDEX} }, $_);
|
|---|
| 625 | return '';
|
|---|
| 626 | }
|
|---|
| 627 |
|
|---|
| 628 | # Anything else is unknown.
|
|---|
| 629 | my ($file, $line) = $seq->file_line;
|
|---|
| 630 | warn "$file:$line: Unknown formatting code $command<$_>\n";
|
|---|
| 631 | }
|
|---|
| 632 |
|
|---|
| 633 |
|
|---|
| 634 | ##############################################################################
|
|---|
| 635 | # Command paragraphs
|
|---|
| 636 | ##############################################################################
|
|---|
| 637 |
|
|---|
| 638 | # All command paragraphs take the paragraph and the line number.
|
|---|
| 639 |
|
|---|
| 640 | # First level heading. We can't output .IX in the NAME section due to a bug
|
|---|
| 641 | # in some versions of catman, so don't output a .IX for that section. .SH
|
|---|
| 642 | # already uses small caps, so remove \s1 and \s-1. Maintain IN_NAME as
|
|---|
| 643 | # appropriate, but don't leave it set while calling parse() so as to not
|
|---|
| 644 | # override guesswork on section headings after NAME.
|
|---|
| 645 | sub cmd_head1 {
|
|---|
| 646 | my $self = shift;
|
|---|
| 647 | $$self{IN_NAME} = 0;
|
|---|
| 648 | local $_ = $self->parse (@_);
|
|---|
| 649 | s/\s+$//;
|
|---|
| 650 | s/\\s-?\d//g;
|
|---|
| 651 | s/\s*\n\s*/ /g;
|
|---|
| 652 | if ($$self{ITEMS} > 1) {
|
|---|
| 653 | $$self{ITEMS} = 0;
|
|---|
| 654 | $self->output (".PD\n");
|
|---|
| 655 | }
|
|---|
| 656 | $self->output ($self->switchquotes ('.SH', $self->mapfonts ($_)));
|
|---|
| 657 | $self->outindex (($_ eq 'NAME') ? () : ('Header', $_));
|
|---|
| 658 | $$self{NEEDSPACE} = 0;
|
|---|
| 659 | $$self{IN_NAME} = ($_ eq 'NAME');
|
|---|
| 660 | }
|
|---|
| 661 |
|
|---|
| 662 | # Second level heading.
|
|---|
| 663 | sub cmd_head2 {
|
|---|
| 664 | my $self = shift;
|
|---|
| 665 | local $_ = $self->parse (@_);
|
|---|
| 666 | s/\s+$//;
|
|---|
| 667 | s/\s*\n\s*/ /g;
|
|---|
| 668 | if ($$self{ITEMS} > 1) {
|
|---|
| 669 | $$self{ITEMS} = 0;
|
|---|
| 670 | $self->output (".PD\n");
|
|---|
| 671 | }
|
|---|
| 672 | $self->output ($self->switchquotes ('.Sh', $self->mapfonts ($_)));
|
|---|
| 673 | $self->outindex ('Subsection', $_);
|
|---|
| 674 | $$self{NEEDSPACE} = 0;
|
|---|
| 675 | }
|
|---|
| 676 |
|
|---|
| 677 | # Third level heading.
|
|---|
| 678 | sub cmd_head3 {
|
|---|
| 679 | my $self = shift;
|
|---|
| 680 | local $_ = $self->parse (@_);
|
|---|
| 681 | s/\s+$//;
|
|---|
| 682 | s/\s*\n\s*/ /g;
|
|---|
| 683 | if ($$self{ITEMS} > 1) {
|
|---|
| 684 | $$self{ITEMS} = 0;
|
|---|
| 685 | $self->output (".PD\n");
|
|---|
| 686 | }
|
|---|
| 687 | $self->makespace;
|
|---|
| 688 | $self->output ($self->textmapfonts ('\f(IS' . $_ . '\f(IE') . "\n");
|
|---|
| 689 | $self->outindex ('Subsection', $_);
|
|---|
| 690 | $$self{NEEDSPACE} = 1;
|
|---|
| 691 | }
|
|---|
| 692 |
|
|---|
| 693 | # Fourth level heading.
|
|---|
| 694 | sub cmd_head4 {
|
|---|
| 695 | my $self = shift;
|
|---|
| 696 | local $_ = $self->parse (@_);
|
|---|
| 697 | s/\s+$//;
|
|---|
| 698 | s/\s*\n\s*/ /g;
|
|---|
| 699 | if ($$self{ITEMS} > 1) {
|
|---|
| 700 | $$self{ITEMS} = 0;
|
|---|
| 701 | $self->output (".PD\n");
|
|---|
| 702 | }
|
|---|
| 703 | $self->makespace;
|
|---|
| 704 | $self->output ($self->textmapfonts ($_) . "\n");
|
|---|
| 705 | $self->outindex ('Subsection', $_);
|
|---|
| 706 | $$self{NEEDSPACE} = 1;
|
|---|
| 707 | }
|
|---|
| 708 |
|
|---|
| 709 | # Start a list. For indents after the first, wrap the outside indent in .RS
|
|---|
| 710 | # so that hanging paragraph tags will be correct.
|
|---|
| 711 | sub cmd_over {
|
|---|
| 712 | my $self = shift;
|
|---|
| 713 | local $_ = shift;
|
|---|
| 714 | unless (/^[-+]?\d+\s+$/) { $_ = $$self{indent} }
|
|---|
| 715 | if (@{ $$self{SHIFTS} } < @{ $$self{INDENTS} }) {
|
|---|
| 716 | $self->output (".RS $$self{INDENT}\n");
|
|---|
| 717 | push (@{ $$self{SHIFTS} }, $$self{INDENT});
|
|---|
| 718 | }
|
|---|
| 719 | push (@{ $$self{INDENTS} }, $$self{INDENT});
|
|---|
| 720 | push (@{ $$self{ITEMTYPES} }, 'unknown');
|
|---|
| 721 | $$self{INDENT} = ($_ + 0);
|
|---|
| 722 | $$self{SHIFTWAIT} = 1;
|
|---|
| 723 | }
|
|---|
| 724 |
|
|---|
| 725 | # End a list. If we've closed an embedded indent, we've mangled the hanging
|
|---|
| 726 | # paragraph indent, so temporarily replace it with .RS and set WEIRDINDENT.
|
|---|
| 727 | # We'll close that .RS at the next =back or =item.
|
|---|
| 728 | sub cmd_back {
|
|---|
| 729 | my $self = shift;
|
|---|
| 730 | $$self{INDENT} = pop @{ $$self{INDENTS} };
|
|---|
| 731 | if (defined $$self{INDENT}) {
|
|---|
| 732 | pop @{ $$self{ITEMTYPES} };
|
|---|
| 733 | } else {
|
|---|
| 734 | my ($file, $line, $paragraph) = @_;
|
|---|
| 735 | ($file, $line) = $paragraph->file_line;
|
|---|
| 736 | warn "$file:$line: Unmatched =back\n";
|
|---|
| 737 | $$self{INDENT} = 0;
|
|---|
| 738 | }
|
|---|
| 739 | if (@{ $$self{SHIFTS} } > @{ $$self{INDENTS} }) {
|
|---|
| 740 | $self->output (".RE\n");
|
|---|
| 741 | pop @{ $$self{SHIFTS} };
|
|---|
| 742 | }
|
|---|
| 743 | if (@{ $$self{INDENTS} } > 0) {
|
|---|
| 744 | $self->output (".RE\n");
|
|---|
| 745 | $self->output (".RS $$self{INDENT}\n");
|
|---|
| 746 | }
|
|---|
| 747 | $$self{NEEDSPACE} = 1;
|
|---|
| 748 | $$self{SHIFTWAIT} = 0;
|
|---|
| 749 | }
|
|---|
| 750 |
|
|---|
| 751 | # An individual list item. Emit an index entry for anything that's
|
|---|
| 752 | # interesting, but don't emit index entries for things like bullets and
|
|---|
| 753 | # numbers. rofficate bullets too while we're at it (so for nice output, use *
|
|---|
| 754 | # for your lists rather than o or . or - or some other thing). Newlines in an
|
|---|
| 755 | # item title are turned into spaces since *roff can't handle them embedded.
|
|---|
| 756 | sub cmd_item {
|
|---|
| 757 | my $self = shift;
|
|---|
| 758 | local $_ = $self->parse (@_);
|
|---|
| 759 | s/\s+$//;
|
|---|
| 760 | s/\s*\n\s*/ /g;
|
|---|
| 761 | my $index;
|
|---|
| 762 | if (/\w/ && !/^\w[.\)]\s*$/) {
|
|---|
| 763 | $index = $_;
|
|---|
| 764 | $index =~ s/^\s*[-*+o.]?(?:\s+|\Z)//;
|
|---|
| 765 | }
|
|---|
| 766 | $_ = '*' unless length ($_) > 0;
|
|---|
| 767 | my $type = $$self{ITEMTYPES}[0];
|
|---|
| 768 | unless (defined $type) {
|
|---|
| 769 | my ($file, $line, $paragraph) = @_;
|
|---|
| 770 | ($file, $line) = $paragraph->file_line;
|
|---|
| 771 | $type = 'unknown';
|
|---|
| 772 | }
|
|---|
| 773 | if ($type eq 'unknown') {
|
|---|
| 774 | $type = /^\*\s*\Z/ ? 'bullet' : 'text';
|
|---|
| 775 | $$self{ITEMTYPES}[0] = $type if $$self{ITEMTYPES}[0];
|
|---|
| 776 | }
|
|---|
| 777 | s/^\*\s*\Z/\\\(bu/ if $type eq 'bullet';
|
|---|
| 778 | if (@{ $$self{SHIFTS} } == @{ $$self{INDENTS} }) {
|
|---|
| 779 | $self->output (".RE\n");
|
|---|
| 780 | pop @{ $$self{SHIFTS} };
|
|---|
| 781 | }
|
|---|
| 782 | $_ = $self->textmapfonts ($_);
|
|---|
| 783 | $self->output (".PD 0\n") if ($$self{ITEMS} == 1);
|
|---|
| 784 | $self->output ($self->switchquotes ('.IP', $_, $$self{INDENT}));
|
|---|
| 785 | $self->outindex ($index ? ('Item', $index) : ());
|
|---|
| 786 | $$self{NEEDSPACE} = 0;
|
|---|
| 787 | $$self{ITEMS}++;
|
|---|
| 788 | $$self{SHIFTWAIT} = 0;
|
|---|
| 789 | }
|
|---|
| 790 |
|
|---|
| 791 | # Begin a block for a particular translator. Setting VERBATIM triggers
|
|---|
| 792 | # special handling in textblock().
|
|---|
| 793 | sub cmd_begin {
|
|---|
| 794 | my $self = shift;
|
|---|
| 795 | local $_ = shift;
|
|---|
| 796 | my ($kind) = /^(\S+)/ or return;
|
|---|
| 797 | if ($kind eq 'man' || $kind eq 'roff') {
|
|---|
| 798 | $$self{VERBATIM} = 1;
|
|---|
| 799 | } else {
|
|---|
| 800 | $$self{EXCLUDE} = 1;
|
|---|
| 801 | }
|
|---|
| 802 | }
|
|---|
| 803 |
|
|---|
| 804 | # End a block for a particular translator. We assume that all =begin/=end
|
|---|
| 805 | # pairs are properly closed.
|
|---|
| 806 | sub cmd_end {
|
|---|
| 807 | my $self = shift;
|
|---|
| 808 | $$self{EXCLUDE} = 0;
|
|---|
| 809 | $$self{VERBATIM} = 0;
|
|---|
| 810 | }
|
|---|
| 811 |
|
|---|
| 812 | # One paragraph for a particular translator. Ignore it unless it's intended
|
|---|
| 813 | # for man or roff, in which case we output it verbatim.
|
|---|
| 814 | sub cmd_for {
|
|---|
| 815 | my $self = shift;
|
|---|
| 816 | local $_ = shift;
|
|---|
| 817 | return unless s/^(?:man|roff)\b[ \t]*\n?//;
|
|---|
| 818 | $self->output ($_);
|
|---|
| 819 | }
|
|---|
| 820 |
|
|---|
| 821 |
|
|---|
| 822 | ##############################################################################
|
|---|
| 823 | # Escaping and fontification
|
|---|
| 824 | ##############################################################################
|
|---|
| 825 |
|
|---|
| 826 | # At this point, we'll have embedded font codes of the form \f(<font>[SE]
|
|---|
| 827 | # where <font> is one of B, I, or F. Turn those into the right font start or
|
|---|
| 828 | # end codes. The old pod2man didn't get B<someI<thing> else> right; after I<>
|
|---|
| 829 | # it switched back to normal text rather than bold. We take care of this by
|
|---|
| 830 | # using variables as a combined pointer to our current font sequence, and set
|
|---|
| 831 | # each to the number of current nestings of start tags for that font. Use
|
|---|
| 832 | # them as a vector to look up what font sequence to use.
|
|---|
| 833 | #
|
|---|
| 834 | # \fP changes to the previous font, but only one previous font is kept. We
|
|---|
| 835 | # don't know what the outside level font is; normally it's R, but if we're
|
|---|
| 836 | # inside a heading it could be something else. So arrange things so that the
|
|---|
| 837 | # outside font is always the "previous" font and end with \fP instead of \fR.
|
|---|
| 838 | # Idea from Zack Weinberg.
|
|---|
| 839 | sub mapfonts {
|
|---|
| 840 | my $self = shift;
|
|---|
| 841 | local $_ = shift;
|
|---|
| 842 |
|
|---|
| 843 | my ($fixed, $bold, $italic) = (0, 0, 0);
|
|---|
| 844 | my %magic = (F => \$fixed, B => \$bold, I => \$italic);
|
|---|
| 845 | my $last = '\fR';
|
|---|
| 846 | s { \\f\((.)(.) } {
|
|---|
| 847 | my $sequence = '';
|
|---|
| 848 | my $f;
|
|---|
| 849 | if ($last ne '\fR') { $sequence = '\fP' }
|
|---|
| 850 | ${ $magic{$1} } += ($2 eq 'S') ? 1 : -1;
|
|---|
| 851 | $f = $$self{FONTS}{($fixed && 1) . ($bold && 1) . ($italic && 1)};
|
|---|
| 852 | if ($f eq $last) {
|
|---|
| 853 | '';
|
|---|
| 854 | } else {
|
|---|
| 855 | if ($f ne '\fR') { $sequence .= $f }
|
|---|
| 856 | $last = $f;
|
|---|
| 857 | $sequence;
|
|---|
| 858 | }
|
|---|
| 859 | }gxe;
|
|---|
| 860 | $_;
|
|---|
| 861 | }
|
|---|
| 862 |
|
|---|
| 863 | # Unfortunately, there is a bug in Solaris 2.6 nroff (not present in GNU
|
|---|
| 864 | # groff) where the sequence \fB\fP\f(CW\fP leaves the font set to B rather
|
|---|
| 865 | # than R, presumably because \f(CW doesn't actually do a font change. To work
|
|---|
| 866 | # around this, use a separate textmapfonts for text blocks where the default
|
|---|
| 867 | # font is always R and only use the smart mapfonts for headings.
|
|---|
| 868 | sub textmapfonts {
|
|---|
| 869 | my $self = shift;
|
|---|
| 870 | local $_ = shift;
|
|---|
| 871 |
|
|---|
| 872 | my ($fixed, $bold, $italic) = (0, 0, 0);
|
|---|
| 873 | my %magic = (F => \$fixed, B => \$bold, I => \$italic);
|
|---|
| 874 | s { \\f\((.)(.) } {
|
|---|
| 875 | ${ $magic{$1} } += ($2 eq 'S') ? 1 : -1;
|
|---|
| 876 | $$self{FONTS}{($fixed && 1) . ($bold && 1) . ($italic && 1)};
|
|---|
| 877 | }gxe;
|
|---|
| 878 | $_;
|
|---|
| 879 | }
|
|---|
| 880 |
|
|---|
| 881 |
|
|---|
| 882 | ##############################################################################
|
|---|
| 883 | # *roff-specific parsing and magic
|
|---|
| 884 | ##############################################################################
|
|---|
| 885 |
|
|---|
| 886 | # Called instead of parse_text, calls parse_text with the right flags.
|
|---|
| 887 | sub parse {
|
|---|
| 888 | my $self = shift;
|
|---|
| 889 | $self->parse_text ({ -expand_seq => 'sequence',
|
|---|
| 890 | -expand_ptree => 'collapse' }, @_);
|
|---|
| 891 | }
|
|---|
| 892 |
|
|---|
| 893 | # Takes a parse tree, a flag saying whether or not to treat it as literal text
|
|---|
| 894 | # (not call guesswork on it), and a flag saying whether or not to clean some
|
|---|
| 895 | # things up for *roff, and returns the concatenation of all of the text
|
|---|
| 896 | # strings in that parse tree. If the literal flag isn't true, guesswork()
|
|---|
| 897 | # will be called on all plain scalars in the parse tree. Otherwise, if
|
|---|
| 898 | # collapse is being called on a C<> code, $cleanup should be set to true and
|
|---|
| 899 | # some additional cleanup will be done. Assumes that everything in the parse
|
|---|
| 900 | # tree is either a scalar or a reference to a scalar.
|
|---|
| 901 | sub collapse {
|
|---|
| 902 | my ($self, $ptree, $literal, $cleanup) = @_;
|
|---|
| 903 |
|
|---|
| 904 | # If we're processing the NAME section, don't do normal guesswork. This
|
|---|
| 905 | # is because NAME lines are often extracted by utilities like catman that
|
|---|
| 906 | # require plain text and don't understand *roff markup. We still need to
|
|---|
| 907 | # escape backslashes and hyphens for *roff (and catman expects \- instead
|
|---|
| 908 | # of -).
|
|---|
| 909 | if ($$self{IN_NAME}) {
|
|---|
| 910 | $literal = 1;
|
|---|
| 911 | $cleanup = 1;
|
|---|
| 912 | }
|
|---|
| 913 |
|
|---|
| 914 | # Do the collapse of the parse tree as described above.
|
|---|
| 915 | return join ('', map {
|
|---|
| 916 | if (ref $_) {
|
|---|
| 917 | join ('', @$_);
|
|---|
| 918 | } elsif ($literal) {
|
|---|
| 919 | if ($cleanup) {
|
|---|
| 920 | s/\\/\\e/g;
|
|---|
| 921 | s/-/\\-/g;
|
|---|
| 922 | s/__/_\\|_/g;
|
|---|
| 923 | }
|
|---|
| 924 | $_;
|
|---|
| 925 | } else {
|
|---|
| 926 | $self->guesswork ($_);
|
|---|
| 927 | }
|
|---|
| 928 | } $ptree->children);
|
|---|
| 929 | }
|
|---|
| 930 |
|
|---|
| 931 | # Takes a text block to perform guesswork on; this is guaranteed not to
|
|---|
| 932 | # contain any formatting codes. Returns the text block with remapping done.
|
|---|
| 933 | sub guesswork {
|
|---|
| 934 | my $self = shift;
|
|---|
| 935 | local $_ = shift;
|
|---|
| 936 |
|
|---|
| 937 | # rofficate backslashes.
|
|---|
| 938 | s/\\/\\e/g;
|
|---|
| 939 |
|
|---|
| 940 | # Ensure double underbars have a tiny space between them.
|
|---|
| 941 | s/__/_\\|_/g;
|
|---|
| 942 |
|
|---|
| 943 | # Leave hyphens only if they're part of regular words and there is only
|
|---|
| 944 | # one dash at a time. Leave a dash after the first character as a regular
|
|---|
| 945 | # non-breaking dash, but don't let it mark the rest of the word invalid
|
|---|
| 946 | # for hyphenation.
|
|---|
| 947 | s/-/\\-/g;
|
|---|
| 948 | s{
|
|---|
| 949 | ( (?:\G|^|\s) [a-zA-Z] ) ( \\- )?
|
|---|
| 950 | ( (?: [a-zA-Z]+ \\-)+ )
|
|---|
| 951 | ( [a-zA-Z]+ ) (?=\s|\Z)
|
|---|
| 952 | \b
|
|---|
| 953 | } {
|
|---|
| 954 | my ($prefix, $hyphen, $main, $suffix) = ($1, $2, $3, $4);
|
|---|
| 955 | $hyphen ||= '';
|
|---|
| 956 | $main =~ s/\\-/-/g;
|
|---|
| 957 | $prefix . $hyphen . $main . $suffix;
|
|---|
| 958 | }egx;
|
|---|
| 959 |
|
|---|
| 960 | # Translate -- into a real em dash if it's used like one.
|
|---|
| 961 | s{ (\s) \\-\\- (\s) } { $1 . '\*(--' . $2 }egx;
|
|---|
| 962 | s{ (\b[a-zA-Z]+) \\-\\- (\s|\Z|[a-zA-Z]+\b) } { $1 . '\*(--' . $2 }egx;
|
|---|
| 963 |
|
|---|
| 964 | # Make all caps a little smaller. Be careful here, since we don't want to
|
|---|
| 965 | # make @ARGV into small caps, nor do we want to fix the MIME in
|
|---|
| 966 | # MIME-Version, since it looks weird with the full-height V.
|
|---|
| 967 | s{
|
|---|
| 968 | ( ^ | [\s\(\"\'\`\[\{<>] )
|
|---|
| 969 | ( [A-Z] [A-Z] (?: [/A-Z+:\d_\$&] | \\- )* )
|
|---|
| 970 | (?= [\s>\}\]\(\)\'\".?!,;] | \\*\(-- | $ )
|
|---|
| 971 | } { $1 . '\s-1' . $2 . '\s0' }egx;
|
|---|
| 972 |
|
|---|
| 973 | # Italize functions in the form func().
|
|---|
| 974 | s{
|
|---|
| 975 | ( \b | \\s-1 )
|
|---|
| 976 | (
|
|---|
| 977 | [A-Za-z_] ([:\w]|\\s-?[01])+ \(\)
|
|---|
| 978 | )
|
|---|
| 979 | } { $1 . '\f(IS' . $2 . '\f(IE' }egx;
|
|---|
| 980 |
|
|---|
| 981 | # func(n) is a reference to a manual page. Make it \fIfunc\fR\|(n).
|
|---|
| 982 | s{
|
|---|
| 983 | ( \b | \\s-1 )
|
|---|
| 984 | ( [A-Za-z_] (?:[.:\w]|\\-|\\s-?[01])+ )
|
|---|
| 985 | (
|
|---|
| 986 | \( \d [a-z]* \)
|
|---|
| 987 | )
|
|---|
| 988 | } { $1 . '\f(IS' . $2 . '\f(IE\|' . $3 }egx;
|
|---|
| 989 |
|
|---|
| 990 | # Convert simple Perl variable references to a fixed-width font.
|
|---|
| 991 | s{
|
|---|
| 992 | ( \s+ )
|
|---|
| 993 | ( [\$\@%] [\w:]+ )
|
|---|
| 994 | (?! \( )
|
|---|
| 995 | } { $1 . '\f(FS' . $2 . '\f(FE'}egx;
|
|---|
| 996 |
|
|---|
| 997 | # Fix up double quotes.
|
|---|
| 998 | s{ \" ([^\"]+) \" } { '\*(L"' . $1 . '\*(R"' }egx;
|
|---|
| 999 |
|
|---|
| 1000 | # Make C++ into \*(C+, which is a squinched version.
|
|---|
| 1001 | s{ \b C\+\+ } {\\*\(C+}gx;
|
|---|
| 1002 |
|
|---|
| 1003 | # All done.
|
|---|
| 1004 | $_;
|
|---|
| 1005 | }
|
|---|
| 1006 |
|
|---|
| 1007 | # Handles C<> text, deciding whether to put \*C` around it or not. This is a
|
|---|
| 1008 | # whole bunch of messy heuristics to try to avoid overquoting, originally from
|
|---|
| 1009 | # Barrie Slaymaker. This largely duplicates similar code in Pod::Text.
|
|---|
| 1010 | sub quote_literal {
|
|---|
| 1011 | my $self = shift;
|
|---|
| 1012 | local $_ = shift;
|
|---|
| 1013 |
|
|---|
| 1014 | # A regex that matches the portion of a variable reference that's the
|
|---|
| 1015 | # array or hash index, separated out just because we want to use it in
|
|---|
| 1016 | # several places in the following regex.
|
|---|
| 1017 | my $index = '(?: \[.*\] | \{.*\} )?';
|
|---|
| 1018 |
|
|---|
| 1019 | # Check for things that we don't want to quote, and if we find any of
|
|---|
| 1020 | # them, return the string with just a font change and no quoting.
|
|---|
| 1021 | m{
|
|---|
| 1022 | ^\s*
|
|---|
| 1023 | (?:
|
|---|
| 1024 | ( [\'\`\"] ) .* \1 # already quoted
|
|---|
| 1025 | | \` .* \' # `quoted'
|
|---|
| 1026 | | \$+ [\#^]? \S $index # special ($^Foo, $")
|
|---|
| 1027 | | [\$\@%&*]+ \#? [:\'\w]+ $index # plain var or func
|
|---|
| 1028 | | [\$\@%&*]* [:\'\w]+ (?: -> )? \(\s*[^\s,]\s*\) # 0/1-arg func call
|
|---|
| 1029 | | [+-]? ( \d[\d.]* | \.\d+ ) (?: [eE][+-]?\d+ )? # a number
|
|---|
| 1030 | | 0x [a-fA-F\d]+ # a hex constant
|
|---|
| 1031 | )
|
|---|
| 1032 | \s*\z
|
|---|
| 1033 | }xo && return '\f(FS' . $_ . '\f(FE';
|
|---|
| 1034 |
|
|---|
| 1035 | # If we didn't return, go ahead and quote the text.
|
|---|
| 1036 | return '\f(FS\*(C`' . $_ . "\\*(C'\\f(FE";
|
|---|
| 1037 | }
|
|---|
| 1038 |
|
|---|
| 1039 |
|
|---|
| 1040 | ##############################################################################
|
|---|
| 1041 | # Output formatting
|
|---|
| 1042 | ##############################################################################
|
|---|
| 1043 |
|
|---|
| 1044 | # Make vertical whitespace.
|
|---|
| 1045 | sub makespace {
|
|---|
| 1046 | my $self = shift;
|
|---|
| 1047 | $self->output (".PD\n") if ($$self{ITEMS} > 1);
|
|---|
| 1048 | $$self{ITEMS} = 0;
|
|---|
| 1049 | $self->output ($$self{INDENT} > 0 ? ".Sp\n" : ".PP\n")
|
|---|
| 1050 | if $$self{NEEDSPACE};
|
|---|
| 1051 | }
|
|---|
| 1052 |
|
|---|
| 1053 | # Output any pending index entries, and optionally an index entry given as an
|
|---|
| 1054 | # argument. Support multiple index entries in X<> separated by slashes, and
|
|---|
| 1055 | # strip special escapes from index entries.
|
|---|
| 1056 | sub outindex {
|
|---|
| 1057 | my ($self, $section, $index) = @_;
|
|---|
| 1058 | my @entries = map { split m%\s*/\s*% } @{ $$self{INDEX} };
|
|---|
| 1059 | return unless ($section || @entries);
|
|---|
| 1060 | $$self{INDEX} = [];
|
|---|
| 1061 | my @output;
|
|---|
| 1062 | if (@entries) {
|
|---|
| 1063 | push (@output, [ 'Xref', join (' ', @entries) ]);
|
|---|
| 1064 | }
|
|---|
| 1065 | if ($section) {
|
|---|
| 1066 | $index =~ s/\\-/-/g;
|
|---|
| 1067 | $index =~ s/\\(?:s-?\d|.\(..|.)//g;
|
|---|
| 1068 | push (@output, [ $section, $index ]);
|
|---|
| 1069 | }
|
|---|
| 1070 | for (@output) {
|
|---|
| 1071 | my ($type, $entry) = @$_;
|
|---|
| 1072 | $entry =~ s/\"/\"\"/g;
|
|---|
| 1073 | $self->output (".IX $type " . '"' . $entry . '"' . "\n");
|
|---|
| 1074 | }
|
|---|
| 1075 | }
|
|---|
| 1076 |
|
|---|
| 1077 | # Output text to the output device.
|
|---|
| 1078 | sub output { print { $_[0]->output_handle } $_[1] }
|
|---|
| 1079 |
|
|---|
| 1080 | # Given a command and a single argument that may or may not contain double
|
|---|
| 1081 | # quotes, handle double-quote formatting for it. If there are no double
|
|---|
| 1082 | # quotes, just return the command followed by the argument in double quotes.
|
|---|
| 1083 | # If there are double quotes, use an if statement to test for nroff, and for
|
|---|
| 1084 | # nroff output the command followed by the argument in double quotes with
|
|---|
| 1085 | # embedded double quotes doubled. For other formatters, remap paired double
|
|---|
| 1086 | # quotes to LQUOTE and RQUOTE.
|
|---|
| 1087 | sub switchquotes {
|
|---|
| 1088 | my $self = shift;
|
|---|
| 1089 | my $command = shift;
|
|---|
| 1090 | local $_ = shift;
|
|---|
| 1091 | my $extra = shift;
|
|---|
| 1092 | s/\\\*\([LR]\"/\"/g;
|
|---|
| 1093 |
|
|---|
| 1094 | # We also have to deal with \*C` and \*C', which are used to add the
|
|---|
| 1095 | # quotes around C<> text, since they may expand to " and if they do this
|
|---|
| 1096 | # confuses the .SH macros and the like no end. Expand them ourselves.
|
|---|
| 1097 | # Also separate troff from nroff if there are any fixed-width fonts in use
|
|---|
| 1098 | # to work around problems with Solaris nroff.
|
|---|
| 1099 | my $c_is_quote = ($$self{LQUOTE} =~ /\"/) || ($$self{RQUOTE} =~ /\"/);
|
|---|
| 1100 | my $fixedpat = join ('|', @{ $$self{FONTS} }{'100', '101', '110', '111'});
|
|---|
| 1101 | $fixedpat =~ s/\\/\\\\/g;
|
|---|
| 1102 | $fixedpat =~ s/\(/\\\(/g;
|
|---|
| 1103 | if (/\"/ || /$fixedpat/) {
|
|---|
| 1104 | s/\"/\"\"/g;
|
|---|
| 1105 | my $nroff = $_;
|
|---|
| 1106 | my $troff = $_;
|
|---|
| 1107 | $troff =~ s/\"\"([^\"]*)\"\"/\`\`$1\'\'/g;
|
|---|
| 1108 | if ($c_is_quote && /\\\*\(C[\'\`]/) {
|
|---|
| 1109 | $nroff =~ s/\\\*\(C\`/$$self{LQUOTE}/g;
|
|---|
| 1110 | $nroff =~ s/\\\*\(C\'/$$self{RQUOTE}/g;
|
|---|
| 1111 | $troff =~ s/\\\*\(C[\'\`]//g;
|
|---|
| 1112 | }
|
|---|
| 1113 | $nroff = qq("$nroff") . ($extra ? " $extra" : '');
|
|---|
| 1114 | $troff = qq("$troff") . ($extra ? " $extra" : '');
|
|---|
| 1115 |
|
|---|
| 1116 | # Work around the Solaris nroff bug where \f(CW\fP leaves the font set
|
|---|
| 1117 | # to Roman rather than the actual previous font when used in headings.
|
|---|
| 1118 | # troff output may still be broken, but at least we can fix nroff by
|
|---|
| 1119 | # just switching the font changes to the non-fixed versions.
|
|---|
| 1120 | $nroff =~ s/\Q$$self{FONTS}{100}\E(.*)\\f[PR]/$1/g;
|
|---|
| 1121 | $nroff =~ s/\Q$$self{FONTS}{101}\E(.*)\\f([PR])/\\fI$1\\f$2/g;
|
|---|
| 1122 | $nroff =~ s/\Q$$self{FONTS}{110}\E(.*)\\f([PR])/\\fB$1\\f$2/g;
|
|---|
| 1123 | $nroff =~ s/\Q$$self{FONTS}{111}\E(.*)\\f([PR])/\\f\(BI$1\\f$2/g;
|
|---|
| 1124 |
|
|---|
| 1125 | # Now finally output the command. Only bother with .ie if the nroff
|
|---|
| 1126 | # and troff output isn't the same.
|
|---|
| 1127 | if ($nroff ne $troff) {
|
|---|
| 1128 | return ".ie n $command $nroff\n.el $command $troff\n";
|
|---|
| 1129 | } else {
|
|---|
| 1130 | return "$command $nroff\n";
|
|---|
| 1131 | }
|
|---|
| 1132 | } else {
|
|---|
| 1133 | $_ = qq("$_") . ($extra ? " $extra" : '');
|
|---|
| 1134 | return "$command $_\n";
|
|---|
| 1135 | }
|
|---|
| 1136 | }
|
|---|
| 1137 |
|
|---|
| 1138 | ##############################################################################
|
|---|
| 1139 | # Module return value and documentation
|
|---|
| 1140 | ##############################################################################
|
|---|
| 1141 |
|
|---|
| 1142 | 1;
|
|---|
| 1143 | __END__
|
|---|
| 1144 |
|
|---|
| 1145 | =head1 NAME
|
|---|
| 1146 |
|
|---|
| 1147 | Pod::Man - Convert POD data to formatted *roff input
|
|---|
| 1148 |
|
|---|
| 1149 | =head1 SYNOPSIS
|
|---|
| 1150 |
|
|---|
| 1151 | use Pod::Man;
|
|---|
| 1152 | my $parser = Pod::Man->new (release => $VERSION, section => 8);
|
|---|
| 1153 |
|
|---|
| 1154 | # Read POD from STDIN and write to STDOUT.
|
|---|
| 1155 | $parser->parse_from_filehandle;
|
|---|
| 1156 |
|
|---|
| 1157 | # Read POD from file.pod and write to file.1.
|
|---|
| 1158 | $parser->parse_from_file ('file.pod', 'file.1');
|
|---|
| 1159 |
|
|---|
| 1160 | =head1 DESCRIPTION
|
|---|
| 1161 |
|
|---|
| 1162 | Pod::Man is a module to convert documentation in the POD format (the
|
|---|
| 1163 | preferred language for documenting Perl) into *roff input using the man
|
|---|
| 1164 | macro set. The resulting *roff code is suitable for display on a terminal
|
|---|
| 1165 | using L<nroff(1)>, normally via L<man(1)>, or printing using L<troff(1)>.
|
|---|
| 1166 | It is conventionally invoked using the driver script B<pod2man>, but it can
|
|---|
| 1167 | also be used directly.
|
|---|
| 1168 |
|
|---|
| 1169 | As a derived class from Pod::Parser, Pod::Man supports the same methods and
|
|---|
| 1170 | interfaces. See L<Pod::Parser> for all the details; briefly, one creates a
|
|---|
| 1171 | new parser with C<< Pod::Man->new() >> and then calls either
|
|---|
| 1172 | parse_from_filehandle() or parse_from_file().
|
|---|
| 1173 |
|
|---|
| 1174 | new() can take options, in the form of key/value pairs that control the
|
|---|
| 1175 | behavior of the parser. See below for details.
|
|---|
| 1176 |
|
|---|
| 1177 | If no options are given, Pod::Man uses the name of the input file with any
|
|---|
| 1178 | trailing C<.pod>, C<.pm>, or C<.pl> stripped as the man page title, to
|
|---|
| 1179 | section 1 unless the file ended in C<.pm> in which case it defaults to
|
|---|
| 1180 | section 3, to a centered title of "User Contributed Perl Documentation", to
|
|---|
| 1181 | a centered footer of the Perl version it is run with, and to a left-hand
|
|---|
| 1182 | footer of the modification date of its input (or the current date if given
|
|---|
| 1183 | STDIN for input).
|
|---|
| 1184 |
|
|---|
| 1185 | Pod::Man assumes that your *roff formatters have a fixed-width font named
|
|---|
| 1186 | CW. If yours is called something else (like CR), use the C<fixed> option to
|
|---|
| 1187 | specify it. This generally only matters for troff output for printing.
|
|---|
| 1188 | Similarly, you can set the fonts used for bold, italic, and bold italic
|
|---|
| 1189 | fixed-width output.
|
|---|
| 1190 |
|
|---|
| 1191 | Besides the obvious pod conversions, Pod::Man also takes care of formatting
|
|---|
| 1192 | func(), func(3), and simple variable references like $foo or @bar so you
|
|---|
| 1193 | don't have to use code escapes for them; complex expressions like
|
|---|
| 1194 | C<$fred{'stuff'}> will still need to be escaped, though. It also translates
|
|---|
| 1195 | dashes that aren't used as hyphens into en dashes, makes long dashes--like
|
|---|
| 1196 | this--into proper em dashes, fixes "paired quotes," makes C++ look right,
|
|---|
| 1197 | puts a little space between double underbars, makes ALLCAPS a teeny bit
|
|---|
| 1198 | smaller in B<troff>, and escapes stuff that *roff treats as special so that
|
|---|
| 1199 | you don't have to.
|
|---|
| 1200 |
|
|---|
| 1201 | The recognized options to new() are as follows. All options take a single
|
|---|
| 1202 | argument.
|
|---|
| 1203 |
|
|---|
| 1204 | =over 4
|
|---|
| 1205 |
|
|---|
| 1206 | =item center
|
|---|
| 1207 |
|
|---|
| 1208 | Sets the centered page header to use instead of "User Contributed Perl
|
|---|
| 1209 | Documentation".
|
|---|
| 1210 |
|
|---|
| 1211 | =item date
|
|---|
| 1212 |
|
|---|
| 1213 | Sets the left-hand footer. By default, the modification date of the input
|
|---|
| 1214 | file will be used, or the current date if stat() can't find that file (the
|
|---|
| 1215 | case if the input is from STDIN), and the date will be formatted as
|
|---|
| 1216 | YYYY-MM-DD.
|
|---|
| 1217 |
|
|---|
| 1218 | =item fixed
|
|---|
| 1219 |
|
|---|
| 1220 | The fixed-width font to use for vertabim text and code. Defaults to CW.
|
|---|
| 1221 | Some systems may want CR instead. Only matters for B<troff> output.
|
|---|
| 1222 |
|
|---|
| 1223 | =item fixedbold
|
|---|
| 1224 |
|
|---|
| 1225 | Bold version of the fixed-width font. Defaults to CB. Only matters for
|
|---|
| 1226 | B<troff> output.
|
|---|
| 1227 |
|
|---|
| 1228 | =item fixeditalic
|
|---|
| 1229 |
|
|---|
| 1230 | Italic version of the fixed-width font (actually, something of a misnomer,
|
|---|
| 1231 | since most fixed-width fonts only have an oblique version, not an italic
|
|---|
| 1232 | version). Defaults to CI. Only matters for B<troff> output.
|
|---|
| 1233 |
|
|---|
| 1234 | =item fixedbolditalic
|
|---|
| 1235 |
|
|---|
| 1236 | Bold italic (probably actually oblique) version of the fixed-width font.
|
|---|
| 1237 | Pod::Man doesn't assume you have this, and defaults to CB. Some systems
|
|---|
| 1238 | (such as Solaris) have this font available as CX. Only matters for B<troff>
|
|---|
| 1239 | output.
|
|---|
| 1240 |
|
|---|
| 1241 | =item name
|
|---|
| 1242 |
|
|---|
| 1243 | Set the name of the manual page. Without this option, the manual name is
|
|---|
| 1244 | set to the uppercased base name of the file being converted unless the
|
|---|
| 1245 | manual section is 3, in which case the path is parsed to see if it is a Perl
|
|---|
| 1246 | module path. If it is, a path like C<.../lib/Pod/Man.pm> is converted into
|
|---|
| 1247 | a name like C<Pod::Man>. This option, if given, overrides any automatic
|
|---|
| 1248 | determination of the name.
|
|---|
| 1249 |
|
|---|
| 1250 | =item quotes
|
|---|
| 1251 |
|
|---|
| 1252 | Sets the quote marks used to surround CE<lt>> text. If the value is a
|
|---|
| 1253 | single character, it is used as both the left and right quote; if it is two
|
|---|
| 1254 | characters, the first character is used as the left quote and the second as
|
|---|
| 1255 | the right quoted; and if it is four characters, the first two are used as
|
|---|
| 1256 | the left quote and the second two as the right quote.
|
|---|
| 1257 |
|
|---|
| 1258 | This may also be set to the special value C<none>, in which case no quote
|
|---|
| 1259 | marks are added around CE<lt>> text (but the font is still changed for troff
|
|---|
| 1260 | output).
|
|---|
| 1261 |
|
|---|
| 1262 | =item release
|
|---|
| 1263 |
|
|---|
| 1264 | Set the centered footer. By default, this is the version of Perl you run
|
|---|
| 1265 | Pod::Man under. Note that some system an macro sets assume that the
|
|---|
| 1266 | centered footer will be a modification date and will prepend something like
|
|---|
| 1267 | "Last modified: "; if this is the case, you may want to set C<release> to
|
|---|
| 1268 | the last modified date and C<date> to the version number.
|
|---|
| 1269 |
|
|---|
| 1270 | =item section
|
|---|
| 1271 |
|
|---|
| 1272 | Set the section for the C<.TH> macro. The standard section numbering
|
|---|
| 1273 | convention is to use 1 for user commands, 2 for system calls, 3 for
|
|---|
| 1274 | functions, 4 for devices, 5 for file formats, 6 for games, 7 for
|
|---|
| 1275 | miscellaneous information, and 8 for administrator commands. There is a lot
|
|---|
| 1276 | of variation here, however; some systems (like Solaris) use 4 for file
|
|---|
| 1277 | formats, 5 for miscellaneous information, and 7 for devices. Still others
|
|---|
| 1278 | use 1m instead of 8, or some mix of both. About the only section numbers
|
|---|
| 1279 | that are reliably consistent are 1, 2, and 3.
|
|---|
| 1280 |
|
|---|
| 1281 | By default, section 1 will be used unless the file ends in .pm in which case
|
|---|
| 1282 | section 3 will be selected.
|
|---|
| 1283 |
|
|---|
| 1284 | =back
|
|---|
| 1285 |
|
|---|
| 1286 | The standard Pod::Parser method parse_from_filehandle() takes up to two
|
|---|
| 1287 | arguments, the first being the file handle to read POD from and the second
|
|---|
| 1288 | being the file handle to write the formatted output to. The first defaults
|
|---|
| 1289 | to STDIN if not given, and the second defaults to STDOUT. The method
|
|---|
| 1290 | parse_from_file() is almost identical, except that its two arguments are the
|
|---|
| 1291 | input and output disk files instead. See L<Pod::Parser> for the specific
|
|---|
| 1292 | details.
|
|---|
| 1293 |
|
|---|
| 1294 | =head1 DIAGNOSTICS
|
|---|
| 1295 |
|
|---|
| 1296 | =over 4
|
|---|
| 1297 |
|
|---|
| 1298 | =item roff font should be 1 or 2 chars, not "%s"
|
|---|
| 1299 |
|
|---|
| 1300 | (F) You specified a *roff font (using C<fixed>, C<fixedbold>, etc.) that
|
|---|
| 1301 | wasn't either one or two characters. Pod::Man doesn't support *roff fonts
|
|---|
| 1302 | longer than two characters, although some *roff extensions do (the canonical
|
|---|
| 1303 | versions of B<nroff> and B<troff> don't either).
|
|---|
| 1304 |
|
|---|
| 1305 | =item Invalid link %s
|
|---|
| 1306 |
|
|---|
| 1307 | (W) The POD source contained a C<LE<lt>E<gt>> formatting code that
|
|---|
| 1308 | Pod::Man was unable to parse. You should never see this error message; it
|
|---|
| 1309 | probably indicates a bug in Pod::Man.
|
|---|
| 1310 |
|
|---|
| 1311 | =item Invalid quote specification "%s"
|
|---|
| 1312 |
|
|---|
| 1313 | (F) The quote specification given (the quotes option to the constructor) was
|
|---|
| 1314 | invalid. A quote specification must be one, two, or four characters long.
|
|---|
| 1315 |
|
|---|
| 1316 | =item %s:%d: Unknown command paragraph "%s".
|
|---|
| 1317 |
|
|---|
| 1318 | (W) The POD source contained a non-standard command paragraph (something of
|
|---|
| 1319 | the form C<=command args>) that Pod::Man didn't know about. It was ignored.
|
|---|
| 1320 |
|
|---|
| 1321 | =item %s:%d: Unknown escape EE<lt>%sE<gt>
|
|---|
| 1322 |
|
|---|
| 1323 | (W) The POD source contained an C<EE<lt>E<gt>> escape that Pod::Man didn't
|
|---|
| 1324 | know about. C<EE<lt>%sE<gt>> was printed verbatim in the output.
|
|---|
| 1325 |
|
|---|
| 1326 | =item %s:%d: Unknown formatting code %s
|
|---|
| 1327 |
|
|---|
| 1328 | (W) The POD source contained a non-standard formatting code (something of
|
|---|
| 1329 | the form C<XE<lt>E<gt>>) that Pod::Man didn't know about. It was ignored.
|
|---|
| 1330 |
|
|---|
| 1331 | =item %s:%d: Unmatched =back
|
|---|
| 1332 |
|
|---|
| 1333 | (W) Pod::Man encountered a C<=back> command that didn't correspond to an
|
|---|
| 1334 | C<=over> command.
|
|---|
| 1335 |
|
|---|
| 1336 | =back
|
|---|
| 1337 |
|
|---|
| 1338 | =head1 BUGS
|
|---|
| 1339 |
|
|---|
| 1340 | Eight-bit input data isn't handled at all well at present. The correct
|
|---|
| 1341 | approach would be to map EE<lt>E<gt> escapes to the appropriate UTF-8
|
|---|
| 1342 | characters and then do a translation pass on the output according to the
|
|---|
| 1343 | user-specified output character set. Unfortunately, we can't send eight-bit
|
|---|
| 1344 | data directly to the output unless the user says this is okay, since some
|
|---|
| 1345 | vendor *roff implementations can't handle eight-bit data. If the *roff
|
|---|
| 1346 | implementation can, however, that's far superior to the current hacked
|
|---|
| 1347 | characters that only work under troff.
|
|---|
| 1348 |
|
|---|
| 1349 | There is currently no way to turn off the guesswork that tries to format
|
|---|
| 1350 | unmarked text appropriately, and sometimes it isn't wanted (particularly
|
|---|
| 1351 | when using POD to document something other than Perl).
|
|---|
| 1352 |
|
|---|
| 1353 | The NAME section should be recognized specially and index entries emitted
|
|---|
| 1354 | for everything in that section. This would have to be deferred until the
|
|---|
| 1355 | next section, since extraneous things in NAME tends to confuse various man
|
|---|
| 1356 | page processors.
|
|---|
| 1357 |
|
|---|
| 1358 | Pod::Man doesn't handle font names longer than two characters. Neither do
|
|---|
| 1359 | most B<troff> implementations, but GNU troff does as an extension. It would
|
|---|
| 1360 | be nice to support as an option for those who want to use it.
|
|---|
| 1361 |
|
|---|
| 1362 | The preamble added to each output file is rather verbose, and most of it is
|
|---|
| 1363 | only necessary in the presence of EE<lt>E<gt> escapes for non-ASCII
|
|---|
| 1364 | characters. It would ideally be nice if all of those definitions were only
|
|---|
| 1365 | output if needed, perhaps on the fly as the characters are used.
|
|---|
| 1366 |
|
|---|
| 1367 | Pod::Man is excessively slow.
|
|---|
| 1368 |
|
|---|
| 1369 | =head1 CAVEATS
|
|---|
| 1370 |
|
|---|
| 1371 | The handling of hyphens and em dashes is somewhat fragile, and one may get
|
|---|
| 1372 | the wrong one under some circumstances. This should only matter for
|
|---|
| 1373 | B<troff> output.
|
|---|
| 1374 |
|
|---|
| 1375 | When and whether to use small caps is somewhat tricky, and Pod::Man doesn't
|
|---|
| 1376 | necessarily get it right.
|
|---|
| 1377 |
|
|---|
| 1378 | =head1 SEE ALSO
|
|---|
| 1379 |
|
|---|
| 1380 | L<Pod::Parser>, L<perlpod(1)>, L<pod2man(1)>, L<nroff(1)>, L<troff(1)>,
|
|---|
| 1381 | L<man(1)>, L<man(7)>
|
|---|
| 1382 |
|
|---|
| 1383 | Ossanna, Joseph F., and Brian W. Kernighan. "Troff User's Manual,"
|
|---|
| 1384 | Computing Science Technical Report No. 54, AT&T Bell Laboratories. This is
|
|---|
| 1385 | the best documentation of standard B<nroff> and B<troff>. At the time of
|
|---|
| 1386 | this writing, it's available at
|
|---|
| 1387 | L<http://www.cs.bell-labs.com/cm/cs/cstr.html>.
|
|---|
| 1388 |
|
|---|
| 1389 | The man page documenting the man macro set may be L<man(5)> instead of
|
|---|
| 1390 | L<man(7)> on your system. Also, please see L<pod2man(1)> for extensive
|
|---|
| 1391 | documentation on writing manual pages if you've not done it before and
|
|---|
| 1392 | aren't familiar with the conventions.
|
|---|
| 1393 |
|
|---|
| 1394 | The current version of this module is always available from its web site at
|
|---|
| 1395 | L<http://www.eyrie.org/~eagle/software/podlators/>. It is also part of the
|
|---|
| 1396 | Perl core distribution as of 5.6.0.
|
|---|
| 1397 |
|
|---|
| 1398 | =head1 AUTHOR
|
|---|
| 1399 |
|
|---|
| 1400 | Russ Allbery <[email protected]>, based I<very> heavily on the original
|
|---|
| 1401 | B<pod2man> by Tom Christiansen <[email protected]>.
|
|---|
| 1402 |
|
|---|
| 1403 | =head1 COPYRIGHT AND LICENSE
|
|---|
| 1404 |
|
|---|
| 1405 | Copyright 1999, 2000, 2001, 2002, 2003 by Russ Allbery <[email protected]>.
|
|---|
| 1406 |
|
|---|
| 1407 | This program is free software; you may redistribute it and/or modify it
|
|---|
| 1408 | under the same terms as Perl itself.
|
|---|
| 1409 |
|
|---|
| 1410 | =cut
|
|---|