# Pod::Man -- Convert POD data to formatted *roff input.
-# $Id: Man.pm,v 0.8 1999/10/07 09:39:37 eagle Exp $
+# $Id: Man.pm,v 1.15 2001/02/10 06:50:22 eagle Exp $
#
-# Copyright 1999 by Russ Allbery <rra@stanford.edu>
+# Copyright 1999, 2000, 2001 by Russ Allbery <rra@stanford.edu>
#
# This program is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
-# This module is intended to be a replacement for pod2man, and attempts to
-# match its output except for some specific circumstances where other
-# decisions seemed to produce better output. It uses Pod::Parser and is
-# designed to be very easy to subclass.
+# This module is intended to be a replacement for the pod2man script
+# distributed with versions of Perl prior to 5.6, and attempts to match its
+# output except for some specific circumstances where other decisions seemed
+# to produce better output. It uses Pod::Parser and is designed to be easy
+# to subclass.
+#
+# Perl core hackers, please note that this module is also separately
+# maintained outside of the Perl core as part of the podlators. Please send
+# me any patches at the address above in addition to sending them to the
+# standard Perl mailing lists.
############################################################################
# Modules and declarations
@ISA = qw(Pod::Parser);
-($VERSION = (split (' ', q$Revision: 0.8 $ ))[1]) =~ s/\.(\d)$/.0$1/;
+# Don't use the CVS revision as the version, since this module is also in
+# Perl core and too many things could munge CVS magic revision strings.
+# This number should ideally be the same as the CVS revision in podlators,
+# however.
+$VERSION = 1.15;
############################################################################
# The following is the static preamble which starts all *roff output we
# generate. It's completely static except for the font to use as a
-# fixed-width font, which is designed by @CFONT@. $PREAMBLE should
-# therefore be run through s/\@CFONT\@/<font>/g before output.
+# fixed-width font, which is designed by @CFONT@, and the left and right
+# quotes to use for C<> text, designated by @LQOUTE@ and @RQUOTE@.
+# $PREAMBLE should therefore be run through s/\@CFONT\@/<font>/g before
+# output.
$PREAMBLE = <<'----END OF PREAMBLE----';
.de Sh \" Subsection heading
.br
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
-. ds C` `
-. ds C' '
+. ds C` @LQUOTE@
+. ds C' @RQUOTE@
'br\}
.el\{\
. ds -- \|\(em\|
.if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
-. .
+..
. nr % 0
. rr F
.\}
.\}
.rm #[ #] #H #V #F C
----END OF PREAMBLE----
-
+#`# for cperl-mode
+
# This table is taken nearly verbatim from Tom Christiansen's pod2man. It
# assumes that the standard preamble has already been printed, since that's
# what defines all of the accent marks. Note that some of these are quoted
'lt' => '<', # left chevron, less-than
'gt' => '>', # right chevron, greater-than
'quot' => '"', # double quote
+ 'sol' => '/', # solidus (forward slash)
+ 'verbar' => '|', # vertical bar
'Aacute' => "A\\*'", # capital A, acute accent
'aacute' => "a\\*'", # small a, acute accent
############################################################################
# Protect leading quotes and periods against interpretation as commands.
-sub protect { local $_ = shift; s/^([.\'])/\\&$1/mg; $_ }
-
-# Given a command and a single argument that may or may not contain double
-# quotes, handle double-quote formatting for it. If there are no double
-# quotes, just return the command followed by the argument in double quotes.
-# If there are double quotes, use an if statement to test for nroff, and for
-# nroff output the command followed by the argument in double quotes with
-# embedded double quotes doubled. For other formatters, remap paired double
-# quotes to `` and ''.
-sub switchquotes {
- my $command = shift;
+# Also protect anything starting with a backslash, since it could expand
+# or hide something that *roff would interpret as a command. This is
+# overkill, but it's much simpler than trying to parse *roff here.
+sub protect {
local $_ = shift;
- my $extra = shift;
- s/\\\*\([LR]\"/\"/g;
- if (/\"/) {
- s/\"/\"\"/g;
- my $troff = $_;
- $troff =~ s/\"\"([^\"]*)\"\"/\`\`$1\'\'/g;
- s/\"/\"\"/g if $extra;
- $troff =~ s/\"/\"\"/g if $extra;
- $_ = qq("$_") . ($extra ? " $extra" : '');
- $troff = qq("$troff") . ($extra ? " $extra" : '');
- return ".if n $command $_\n.el $command $troff\n";
- } else {
- $_ = qq("$_") . ($extra ? " $extra" : '');
- return "$command $_\n";
- }
+ s/^([.\'\\])/\\&$1/mg;
+ $_;
}
# Translate a font string into an escape.
sub toescape { (length ($_[0]) > 1 ? '\f(' : '\f') . $_[0] }
-
+
############################################################################
# Initialization
############################################################################
for (qw/fixed fixedbold fixeditalic fixedbolditalic/) {
if (defined $$self{$_}) {
if (length ($$self{$_}) < 1 || length ($$self{$_}) > 2) {
- croak "roff font should be 1 or 2 chars, not `$$self{$_}'";
+ croak qq(roff font should be 1 or 2 chars,)
+ . qq( not "$$self{$_}");
}
} else {
$$self{$_} = '';
# We used to try first to get the version number from a local binary,
# but we shouldn't need that any more. Get the version from the running
- # Perl.
+ # Perl. Work a little magic to handle subversions correctly under both
+ # the pre-5.6 and the post-5.6 version numbering schemes.
if (!defined $$self{release}) {
- my ($version, $patch) = ($] =~ /^(.{5})(\d{2})?/);
- $$self{release} = "perl $version";
- $$self{release} .= ", patch $patch" if $patch;
+ my @version = ($] =~ /^(\d+)\.(\d{3})(\d{0,3})$/);
+ $version[2] ||= 0;
+ $version[2] *= 10 ** (3 - length $version[2]);
+ for (@version) { $_ += 0 }
+ $$self{release} = 'perl v' . join ('.', @version);
}
# Double quotes in things that will be quoted.
- for (qw/center date release/) { $$self{$_} =~ s/\"/\"\"/g }
+ for (qw/center date release/) {
+ $$self{$_} =~ s/\"/\"\"/g if $$self{$_};
+ }
+
+ # Figure out what quotes we'll be using for C<> text.
+ $$self{quotes} ||= '"';
+ if ($$self{quotes} eq 'none') {
+ $$self{LQUOTE} = $$self{RQUOTE} = '';
+ } elsif (length ($$self{quotes}) == 1) {
+ $$self{LQUOTE} = $$self{RQUOTE} = $$self{quotes};
+ } elsif ($$self{quotes} =~ /^(.)(.)$/
+ || $$self{quotes} =~ /^(..)(..)$/) {
+ $$self{LQUOTE} = $1;
+ $$self{RQUOTE} = $2;
+ } else {
+ croak qq(Invalid quote specification "$$self{quotes}");
+ }
+
+ # Double the first quote; note that this should not be s///g as two
+ # double quotes is represented in *roff as three double quotes, not
+ # four. Weird, I know.
+ $$self{LQUOTE} =~ s/\"/\"\"/;
+ $$self{RQUOTE} =~ s/\"/\"\"/;
$$self{INDENT} = 0; # Current indentation level.
$$self{INDENTS} = []; # Stack of indentations.
$$self{INDEX} = []; # Index keys waiting to be printed.
+ $$self{ITEMS} = 0; # The number of consecutive =items.
$self->SUPER::initialize;
}
-# For each document we process, output the preamble first. Note that the
-# fixed width font is a global default; once we interpolate it into the
-# PREAMBLE, it ain't ever changing. Maybe fix this later.
+# For each document we process, output the preamble first.
sub begin_pod {
my $self = shift;
my $name = $$self{name};
if (!defined $name) {
$name = $self->input_file;
- $section = 3 if (!$$self{section} && $name =~ /\.pm$/i);
- $name =~ s/\.p(od|[lm])$//i;
+ $section = 3 if (!$$self{section} && $name =~ /\.pm\z/i);
+ $name =~ s/\.p(od|[lm])\z//i;
if ($section =~ /^1/) {
require File::Basename;
$name = uc File::Basename::basename ($name);
# */lib/*perl* standard or site_perl module
# */*perl*/lib from -D prefix=/opt/perl
# */*perl*/ random module hierarchy
- # which works. Should be fixed to use File::Spec.
+ # which works. Should be fixed to use File::Spec. Also handle
+ # a leading lib/ since that's what ExtUtils::MakeMaker creates.
for ($name) {
s%//+%/%g;
- if ( s%^.*?/lib/[^/]*perl[^/]*/%%i
- or s%^.*?/[^/]*perl[^/]*/(?:lib/)?%%i) {
- s%^site(_perl)?/%%; # site and site_perl
- s%^(.*-$^O|$^O-.*)/%%o; # arch
- s%^\d+\.\d+%%; # version
+ if ( s%^.*?/lib/[^/]*perl[^/]*/%%si
+ or s%^.*?/[^/]*perl[^/]*/(?:lib/)?%%si) {
+ s%^site(_perl)?/%%s; # site and site_perl
+ s%^(.*-$^O|$^O-.*)/%%so; # arch
+ s%^\d+\.\d+%%s; # version
}
+ s%^lib/%%;
s%/%::%g;
}
}
}
+ # If $name contains spaces, quote it; this mostly comes up in the case
+ # of input from stdin.
+ $name = '"' . $name . '"' if ($name =~ /\s/);
+
# Modification date header. Try to use the modification time of our
# input.
if (!defined $$self{date}) {
my ($day, $month, $year) = (localtime $time)[3,4,5];
$month++;
$year += 1900;
- $$self{date} = join ('-', $year, $month, $day);
+ $$self{date} = sprintf ('%4d-%02d-%02d', $year, $month, $day);
}
# Now, print out the preamble and the title.
- $PREAMBLE =~ s/\@CFONT\@/$$self{fixed}/;
- chomp $PREAMBLE;
+ local $_ = $PREAMBLE;
+ s/\@CFONT\@/$$self{fixed}/;
+ s/\@LQUOTE\@/$$self{LQUOTE}/;
+ s/\@RQUOTE\@/$$self{RQUOTE}/;
+ chomp $_;
print { $self->output_handle } <<"----END OF HEADER----";
.\\" Automatically generated by Pod::Man version $VERSION
.\\" @{[ scalar localtime ]}
.\\"
.\\" Standard preamble:
.\\" ======================================================================
-$PREAMBLE
+$_
.\\" ======================================================================
.\\"
.IX Title "$name $section"
my $self = shift;
my $command = shift;
return if $command eq 'pod';
- return if ($$self{EXCLUDE} && $command ne 'end');
- $command = 'cmd_' . $command;
- $self->$command (@_);
+ return if ($$self{EXCLUDE} && $command ne 'end');
+ if ($self->can ('cmd_' . $command)) {
+ $command = 'cmd_' . $command;
+ $self->$command (@_);
+ } else {
+ my ($text, $line, $paragraph) = @_;
+ my $file;
+ ($file, $line) = $paragraph->file_line;
+ $text =~ s/\n+\z//;
+ $text = " $text" if ($text =~ /^\S/);
+ warn qq($file:$line: Unknown command paragraph "=$command$text"\n);
+ return;
+ }
}
# Called for a verbatim paragraph. Gets the paragraph, the line number, and
1 while s/^(.*?)(\t+)/$1 . ' ' x (length ($2) * 8 - length ($1) % 8)/me;
s/\\/\\e/g;
s/^(\s*\S)/'\&' . $1/gme;
- $self->makespace if $$self{NEEDSPACE};
+ $self->makespace;
$self->output (".Vb $lines\n$_.Ve\n");
$$self{NEEDSPACE} = 0;
}
# Perform a little magic to collapse multiple L<> references. We'll
# just rewrite the whole thing into actual text at this part, bypassing
# the whole internal sequence parsing thing.
- s{
+ my $text = shift;
+ $text =~ s{
(L< # A link of the form L</something>.
/
(
>
(
,?\s+(and\s+)? # Allow lots of them, conjuncted.
- L<
+ L<
/
( [:\w]+ ( \(\) )? )
>
)
} {
local $_ = $1;
- s{ L< / ([^>]+ ) } {$1}g;
+ s{ L< / ( [^>]+ ) > } {$1}xg;
my @items = split /(?:,?\s+(?:and\s+)?)/;
- my $string = "the ";
+ my $string = 'the ';
my $i;
for ($i = 0; $i < @items; $i++) {
$string .= $items[$i];
- $string .= ", " if @items > 2 && $i != $#items;
- $string .= " and " if ($i == $#items - 1);
+ $string .= ', ' if @items > 2 && $i != $#items;
+ $string .= ' ' if @items == 2 && $i == 2;
+ $string .= 'and ' if ($i == $#items - 1);
}
- $string .= " entries elsewhere in this document";
+ $string .= ' entries elsewhere in this document';
$string;
}gex;
# Parse the tree and output it. collapse knows about references to
# scalars as well as scalars and does the right thing with them.
- local $_ = $self->parse (@_);
- s/\n\s*$/\n/;
- $self->makespace if $$self{NEEDSPACE};
- $self->output (protect $self->mapfonts ($_));
+ $text = $self->parse ($text, @_);
+ $text =~ s/\n\s*$/\n/;
+ $self->makespace;
+ $self->output (protect $self->textmapfonts ($text));
$self->outindex;
$$self{NEEDSPACE} = 1;
}
# Zero-width characters.
if ($command eq 'Z') {
- my $v = '\&'; return bless \ $v, 'Pod::Man::String';
+ # Workaround to generate a blessable reference, needed by 5.005.
+ my $tmp = '\&';
+ return bless \ "$tmp", 'Pod::Man::String';
}
- # C<>, L<>, X<>, and E<> don't apply guesswork to their contents.
- local $_ = $self->collapse ($seq->parse_tree, $command =~ /^[CELX]$/);
+ # C<>, L<>, X<>, and E<> don't apply guesswork to their contents. C<>
+ # needs some additional special handling.
+ my $literal = ($command =~ /^[CELX]$/);
+ $literal++ if $command eq 'C';
+ local $_ = $self->collapse ($seq->parse_tree, $literal);
# Handle E<> escapes.
if ($command eq 'E') {
} elsif ($command eq 'I') {
return bless \ ('\f(IS' . $_ . '\f(IE'), 'Pod::Man::String';
} elsif ($command eq 'C') {
- s/-/\\-/g;
- s/__/_\\|_/g;
return bless \ ('\f(FS\*(C`' . $_ . "\\*(C'\\f(FE"),
'Pod::Man::String';
}
# Handle links.
if ($command eq 'L') {
- # XXX bug in lvalue subroutines prevents this from working
- #return bless \ ($self->buildlink ($_)), 'Pod::Man::String';
- my $v = $self->buildlink($_);
- return bless \$v, 'Pod::Man::String';
+ # A bug in lvalue subs in 5.6 requires the temporary variable.
+ my $tmp = $self->buildlink ($_);
+ return bless \ "$tmp", 'Pod::Man::String';
}
-
+
# Whitespace protection replaces whitespace with "\ ".
if ($command eq 'S') {
s/\s+/\\ /g;
local $_ = $self->parse (@_);
s/\s+$//;
s/\\s-?\d//g;
- $self->output (switchquotes ('.SH', $self->mapfonts ($_)));
+ s/\s*\n\s*/ /g;
+ if ($$self{ITEMS} > 1) {
+ $$self{ITEMS} = 0;
+ $self->output (".PD\n");
+ }
+ $self->output ($self->switchquotes ('.SH', $self->mapfonts ($_)));
$self->outindex (($_ eq 'NAME') ? () : ('Header', $_));
$$self{NEEDSPACE} = 0;
}
my $self = shift;
local $_ = $self->parse (@_);
s/\s+$//;
- $self->output (switchquotes ('.Sh', $self->mapfonts ($_)));
+ s/\s*\n\s*/ /g;
+ if ($$self{ITEMS} > 1) {
+ $$self{ITEMS} = 0;
+ $self->output (".PD\n");
+ }
+ $self->output ($self->switchquotes ('.Sh', $self->mapfonts ($_)));
$self->outindex ('Subsection', $_);
$$self{NEEDSPACE} = 0;
}
+# Third level heading.
+sub cmd_head3 {
+ my $self = shift;
+ local $_ = $self->parse (@_);
+ s/\s+$//;
+ s/\s*\n\s*/ /g;
+ if ($$self{ITEMS} > 1) {
+ $$self{ITEMS} = 0;
+ $self->output (".PD\n");
+ }
+ $self->makespace;
+ $self->output ($self->switchquotes ('.I', $self->mapfonts ($_)));
+ $self->outindex ('Subsection', $_);
+ $$self{NEEDSPACE} = 1;
+}
+
+# Fourth level heading.
+sub cmd_head4 {
+ my $self = shift;
+ local $_ = $self->parse (@_);
+ s/\s+$//;
+ s/\s*\n\s*/ /g;
+ if ($$self{ITEMS} > 1) {
+ $$self{ITEMS} = 0;
+ $self->output (".PD\n");
+ }
+ $self->makespace;
+ $self->output ($self->textmapfonts ($_) . "\n");
+ $self->outindex ('Subsection', $_);
+ $$self{NEEDSPACE} = 1;
+}
+
# Start a list. For indents after the first, wrap the outside indent in .RS
# so that hanging paragraph tags will be correct.
sub cmd_over {
# An individual list item. Emit an index entry for anything that's
# interesting, but don't emit index entries for things like bullets and
# numbers. rofficate bullets too while we're at it (so for nice output, use
-# * for your lists rather than o or . or - or some other thing).
+# * for your lists rather than o or . or - or some other thing). Newlines
+# in an item title are turned into spaces since *roff can't handle them
+# embedded.
sub cmd_item {
my $self = shift;
local $_ = $self->parse (@_);
s/\s+$//;
+ s/\s*\n\s*/ /g;
my $index;
if (/\w/ && !/^\w[.\)]\s*$/) {
$index = $_;
- $index =~ s/^\s*[-*+o.]?\s*//;
+ $index =~ s/^\s*[-*+o.]?(?:\s+|\Z)//;
}
s/^\*(\s|\Z)/\\\(bu$1/;
if ($$self{WEIRDINDENT}) {
$self->output (".RE\n");
$$self{WEIRDINDENT} = 0;
}
- $_ = $self->mapfonts ($_);
- $self->output (switchquotes ('.Ip', $_, $$self{INDENT}));
+ $_ = $self->textmapfonts ($_);
+ $self->output (".PD 0\n") if ($$self{ITEMS} == 1);
+ $self->output ($self->switchquotes ('.Ip', $_, $$self{INDENT}));
$self->outindex ($index ? ('Item', $index) : ());
$$self{NEEDSPACE} = 0;
+ $$self{ITEMS}++;
}
# Begin a block for a particular translator. Setting VERBATIM triggers
sub cmd_for {
my $self = shift;
local $_ = shift;
- my $line = shift;
return unless s/^(?:man|roff)\b[ \t]*\n?//;
$self->output ($_);
}
s/^\s+//;
s/\s+$//;
+ # If the argument looks like a URL, return it verbatim. This only
+ # handles URLs that use the server syntax.
+ if (m%^[a-z]+://\S+$%) { return $_ }
+
# Default to using the whole content of the link entry as a section
# name. Note that L<manpage/> forces a manpage interpretation, as does
# something looking like L<manpage(section)>. Do the same thing to
# At this point, we'll have embedded font codes of the form \f(<font>[SE]
# where <font> is one of B, I, or F. Turn those into the right font start
-# or end codes. B<someI<thing> else> should map to \fBsome\f(BIthing\fB
-# else\fR. The old pod2man didn't get this right; the second \fB was \fR,
-# so nested sequences didn't work right. We take care of this by using
-# variables as a combined pointer to our current font sequence, and set each
-# to the number of current nestings of start tags for that font. Use them
-# as a vector to look up what font sequence to use.
+# or end codes. The old pod2man didn't get B<someI<thing> else> right;
+# after I<> it switched back to normal text rather than bold. We take care
+# of this by using variables as a combined pointer to our current font
+# sequence, and set each to the number of current nestings of start tags for
+# that font. Use them as a vector to look up what font sequence to use.
+#
+# \fP changes to the previous font, but only one previous font is kept. We
+# don't know what the outside level font is; normally it's R, but if we're
+# inside a heading it could be something else. So arrange things so that
+# the outside font is always the "previous" font and end with \fP instead of
+# \fR. Idea from Zack Weinberg.
sub mapfonts {
my $self = shift;
local $_ = shift;
my ($fixed, $bold, $italic) = (0, 0, 0);
my %magic = (F => \$fixed, B => \$bold, I => \$italic);
+ my $last = '\fR';
+ s { \\f\((.)(.) } {
+ my $sequence = '';
+ my $f;
+ if ($last ne '\fR') { $sequence = '\fP' }
+ ${ $magic{$1} } += ($2 eq 'S') ? 1 : -1;
+ $f = $$self{FONTS}{($fixed && 1) . ($bold && 1) . ($italic && 1)};
+ if ($f eq $last) {
+ '';
+ } else {
+ if ($f ne '\fR') { $sequence .= $f }
+ $last = $f;
+ $sequence;
+ }
+ }gxe;
+ $_;
+}
+
+# Unfortunately, there is a bug in Solaris 2.6 nroff (not present in GNU
+# groff) where the sequence \fB\fP\f(CW\fP leaves the font set to B rather
+# than R, presumably because \f(CW doesn't actually do a font change. To
+# work around this, use a separate textmapfonts for text blocks where the
+# default font is always R and only use the smart mapfonts for headings.
+sub textmapfonts {
+ my $self = shift;
+ local $_ = shift;
+
+ my ($fixed, $bold, $italic) = (0, 0, 0);
+ my %magic = (F => \$fixed, B => \$bold, I => \$italic);
s { \\f\((.)(.) } {
${ $magic{$1} } += ($2 eq 'S') ? 1 : -1;
$$self{FONTS}{($fixed && 1) . ($bold && 1) . ($italic && 1)};
$self->parse_text ({ -expand_seq => 'sequence',
-expand_ptree => 'collapse' }, @_);
}
-
+
# Takes a parse tree and a flag saying whether or not to treat it as literal
# text (not call guesswork on it), and returns the concatenation of all of
# the text strings in that parse tree. If the literal flag isn't true,
# guesswork() will be called on all plain scalars in the parse tree.
-# Assumes that everything in the parse tree is either a scalar or a
-# reference to a scalar.
+# Otherwise, just escape backslashes in the normal case. If collapse is
+# being called on a C<> sequence, literal is set to 2, and we do some
+# additional cleanup. Assumes that everything in the parse tree is either a
+# scalar or a reference to a scalar.
sub collapse {
my ($self, $ptree, $literal) = @_;
if ($literal) {
$$_;
} else {
s/\\/\\e/g;
+ s/-/\\-/g if $literal > 1;
+ s/__/_\\|_/g if $literal > 1;
$_;
}
} $ptree->children);
( ^ | [\s\(\"\'\`\[\{<>] )
( [A-Z] [A-Z] [/A-Z+:\d_\$&-]* )
(?: (?= [\s>\}\]\)\'\".?!,;:] | -- ) | $ )
- } { $1 . '\s-1' . $2 . '\s0' . $3 }egx;
+ } { $1 . '\s-1' . $2 . '\s0' }egx;
# Turn PI into a pretty pi.
s{ (?: \\s-1 | \b ) PI (?: \\s0 | \b ) } {\\*\(PI}gx;
# Make vertical whitespace.
sub makespace {
my $self = shift;
- $self->output ($$self{INDENT} > 0 ? ".Sp\n" : ".PP\n");
+ $self->output (".PD\n") if ($$self{ITEMS} > 1);
+ $$self{ITEMS} = 0;
+ $self->output ($$self{INDENT} > 0 ? ".Sp\n" : ".PP\n")
+ if $$self{NEEDSPACE};
}
# Output any pending index entries, and optionally an index entry given as
# Output text to the output device.
sub output { print { $_[0]->output_handle } $_[1] }
+# Given a command and a single argument that may or may not contain double
+# quotes, handle double-quote formatting for it. If there are no double
+# quotes, just return the command followed by the argument in double quotes.
+# If there are double quotes, use an if statement to test for nroff, and for
+# nroff output the command followed by the argument in double quotes with
+# embedded double quotes doubled. For other formatters, remap paired double
+# quotes to LQUOTE and RQUOTE.
+sub switchquotes {
+ my $self = shift;
+ my $command = shift;
+ local $_ = shift;
+ my $extra = shift;
+ s/\\\*\([LR]\"/\"/g;
+
+ # We also have to deal with \*C` and \*C', which are used to add the
+ # quotes around C<> text, since they may expand to " and if they do this
+ # confuses the .SH macros and the like no end. Expand them ourselves.
+ # If $extra is set, we're dealing with =item, which in most nroff macro
+ # sets requires an extra level of quoting of double quotes.
+ my $c_is_quote = ($$self{LQUOTE} =~ /\"/) || ($$self{RQUOTE} =~ /\"/);
+ if (/\"/ || ($c_is_quote && /\\\*\(C[\'\`]/)) {
+ s/\"/\"\"/g;
+ my $troff = $_;
+ $troff =~ s/\"\"([^\"]*)\"\"/\`\`$1\'\'/g;
+ s/\\\*\(C\`/$$self{LQUOTE}/g;
+ s/\\\*\(C\'/$$self{RQUOTE}/g;
+ $troff =~ s/\\\*\(C[\'\`]//g;
+ s/\"/\"\"/g if $extra;
+ $troff =~ s/\"/\"\"/g if $extra;
+ $_ = qq("$_") . ($extra ? " $extra" : '');
+ $troff = qq("$troff") . ($extra ? " $extra" : '');
+ return ".if n $command $_\n.el $command $troff\n";
+ } else {
+ $_ = qq("$_") . ($extra ? " $extra" : '');
+ return "$command $_\n";
+ }
+}
+
__END__
.\" These are some extra bits of roff that I don't want to lose track of
preferred language for documenting Perl) into *roff input using the man
macro set. The resulting *roff code is suitable for display on a terminal
using nroff(1), normally via man(1), or printing using troff(1). It is
-conventionally invoked using the driver script B<pod2roff>, but it can also
+conventionally invoked using the driver script B<pod2man>, but it can also
be used directly.
As a derived class from Pod::Parser, Pod::Man supports the same methods and
(such as Solaris) have this font available as CX. Only matters for troff(1)
output.
+=item quotes
+
+Sets the quote marks used to surround CE<lt>> text. If the value is a
+single character, it is used as both the left and right quote; if it is two
+characters, the first character is used as the left quote and the second as
+the right quoted; and if it is four characters, the first two are used as
+the left quote and the second two as the right quote.
+
+This may also be set to the special value C<none>, in which case no quote
+marks are added around CE<lt>> text (but the font is still changed for troff
+output).
+
=item release
Set the centered footer. By default, this is the version of Perl you run
=over 4
-=item roff font should be 1 or 2 chars, not `%s'
+=item roff font should be 1 or 2 chars, not "%s"
(F) You specified a *roff font (using C<fixed>, C<fixedbold>, etc.) that
wasn't either one or two characters. Pod::Man doesn't support *roff fonts
unable to parse. You should never see this error message; it probably
indicates a bug in Pod::Man.
+=item Invalid quote specification "%s"
+
+(F) The quote specification given (the quotes option to the constructor) was
+invalid. A quote specification must be one, two, or four characters long.
+
+=item %s:%d: Unknown command paragraph "%s".
+
+(W) The POD source contained a non-standard command paragraph (something of
+the form C<=command args>) that Pod::Man didn't know about. It was ignored.
+
=item Unknown escape EE<lt>%sE<gt>
(W) The POD source contained an C<EE<lt>E<gt>> escape that Pod::Man didn't
(W) The POD source contained a non-standard interior sequence (something of
the form C<XE<lt>E<gt>>) that Pod::Man didn't know about. It was ignored.
+=item %s: Unknown command paragraph "%s" on line %d.
+
+(W) The POD source contained a non-standard command paragraph (something of
+the form C<=command args>) that Pod::Man didn't know about. It was ignored.
+
=item Unmatched =back
(W) Pod::Man encountered a C<=back> command that didn't correspond to an
Pod::Man is excessively slow.
-=head1 NOTES
-
-The intention is for this module and its driver script to eventually replace
-B<pod2man> in Perl core.
-
=head1 SEE ALSO
-L<Pod::Parser|Pod::Parser>, perlpod(1), pod2roff(1), nroff(1), troff(1),
+L<Pod::Parser|Pod::Parser>, perlpod(1), pod2man(1), nroff(1), troff(1),
man(1), man(7)
Ossanna, Joseph F., and Brian W. Kernighan. "Troff User's Manual,"
this writing, it's available at http://www.cs.bell-labs.com/cm/cs/cstr.html.
The man page documenting the man macro set may be man(5) instead of man(7)
-on your system. Also, please see pod2roff(1) for extensive documentation on
+on your system. Also, please see pod2man(1) for extensive documentation on
writing manual pages if you've not done it before and aren't familiar with
the conventions.