summaryrefslogtreecommitdiff
path: root/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-03-15 03:06:35 +0000
committerNorbert Preining <norbert@preining.info>2024-03-15 03:06:35 +0000
commit12679ab7d3c2a210f4123163671b532b8b55d5f9 (patch)
tree0060d13467186ad977f4e73488ee20dd6c0017ab /systems/texlive/tlnet/tlpkg/tlperl/lib/Pod
parent62170822e034fdd3f81de7274835d0d3b0467100 (diff)
CTAN sync 202403150306
Diffstat (limited to 'systems/texlive/tlnet/tlpkg/tlperl/lib/Pod')
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Checker.pm7
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Functions.pm12
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html.pm820
-rwxr-xr-xsystems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html/Util.pm282
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Man.pm1576
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/ParseLink.pm12
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple.pm4
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/BlackBox.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Checker.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Debug.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsText.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsXML.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTML.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTMLBatch.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/LinkSection.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Methody.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Progress.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParser.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserEndToken.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserStartToken.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserTextToken.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserToken.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/RTF.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Search.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/SimpleTree.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Text.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TextContent.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TiedOutFH.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Transcode.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeDumb.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeSmart.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XHTML.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XMLOutStream.pm2
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text.pm561
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Color.pm30
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Overstrike.pm27
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Termcap.pm42
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Usage.pm2
38 files changed, 2094 insertions, 1333 deletions
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Checker.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Checker.pm
index bee20d0bfa..1dfb58b128 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Checker.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Checker.pm
@@ -10,7 +10,7 @@ package Pod::Checker;
use strict;
use warnings;
-our $VERSION = '1.74'; ## Current version of this package
+our $VERSION = '1.75'; ## Current version of this package
=head1 NAME
@@ -1112,7 +1112,10 @@ sub new {
$self->{'-line'} ||= $caller->{'_line'};
$self->{'-type'} ||= $simple_link->{'type'};
-
+ # preserve raw link text for additional checks
+ $self->{'-raw-link-text'} = (exists $simple_link->{'raw'})
+ ? "$simple_link->{'raw'}"
+ : "";
# Force stringification of page and node. (This expands any E<>.)
$self->{'-page'} = exists $simple_link->{'to'} ? "$simple_link->{'to'}" : "";
$self->{'-node'} = exists $simple_link->{'section'} ? "$simple_link->{'section'}" : "";
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Functions.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Functions.pm
index f4e2a9464c..727c7fd0d4 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Functions.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Functions.pm
@@ -54,11 +54,10 @@ L<perlfunc/"Perl Functions by Category"> section.
=cut
-our $VERSION = '1.13';
+our $VERSION = '1.14';
-require Exporter;
+use Exporter 'import';
-our @ISA = qw(Exporter);
our @EXPORT = qw(%Kinds %Type %Flavor %Type_Description @Type_Order);
our(%Kinds, %Type, %Flavor, %Type_Description, @Type_Order);
@@ -142,6 +141,7 @@ chop String remove the last character from a string
chown File change the ownership on a list of files
chr String get character this number represents
chroot File make directory new root for path lookups
+class Namespace Objects declare a separate global namespace that is an object class
close I/O close file (or pipe or socket) handle
closedir I/O close directory handle
connect Socket connect to a remote socket
@@ -171,6 +171,7 @@ exit Flow terminate this program
exp Math raise I<e> to a power
fc String return casefolded version of a string
fcntl File file control system call
+field Namespace Objects declare a field variable of the current class
__FILE__ Flow the name of the current source file
fileno I/O return file descriptor from filehandle
flock I/O lock an entire file with an advisory lock
@@ -229,6 +230,7 @@ log Math retrieve the natural logarithm for a number
lstat File stat a symbolic link
m// Regexp match a string with a regular expression pattern
map LIST apply a change to a list to get back a new list with the changes
+method Flow Objects declare a method of a class
mkdir File create a directory
msgctl SysV SysV IPC message control operations
msgget SysV get SysV IPC message queue
@@ -332,14 +334,14 @@ times Process Time return elapsed time for self and child processes
tr/// String transliterate a string
truncate I/O shorten a file
uc String return upper-case version of a string
-ucfirst String return a string with just the next letter in upper case
+ucfirst String return a string with the first letter in upper case
umask File set file creation mode mask
undef Misc remove a variable or function definition
unlink File remove one link to a file
unpack Binary LIST convert binary structure into normal perl variables
unshift ARRAY prepend more elements to the beginning of a list
untie Objects break a tie binding to a variable
-use Modules Namespace Objects load in a module at compile time and import its namespace
+use Modules Namespace Objects enable Perl language features and declare required version
utime File set a file's last access and modify times
values ARRAY HASH return a list of the values in a hash
vec Binary test or set particular bits in a string
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html.pm
index ba0ab0b39a..7c568f9e91 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html.pm
@@ -1,22 +1,27 @@
package Pod::Html;
use strict;
-require Exporter;
+use Exporter 'import';
-our $VERSION = 1.27;
-our @ISA = qw(Exporter);
-our @EXPORT = qw(pod2html htmlify);
-our @EXPORT_OK = qw(anchorify relativize_url);
+our $VERSION = 1.34;
+$VERSION = eval $VERSION;
+our @EXPORT = qw(pod2html);
-use Carp;
use Config;
use Cwd;
use File::Basename;
use File::Spec;
-use File::Spec::Unix;
-use Getopt::Long;
use Pod::Simple::Search;
use Pod::Simple::SimpleTree ();
-use Text::Tabs;
+use Pod::Html::Util qw(
+ html_escape
+ process_command_line
+ trim_leading_whitespace
+ unixify
+ usage
+ htmlify
+ anchorify
+ relativize_url
+);
use locale; # make \w work right in non-ASCII lands
=head1 NAME
@@ -189,20 +194,26 @@ Display progress messages. By default, they won't be displayed.
=back
-=head2 htmlify
+=head2 Formerly Exported Auxiliary Functions
- htmlify($heading);
+Prior to perl-5.36, the following three functions were exported by
+F<Pod::Html>, either by default or on request:
+
+=over 4
-Converts a pod section specification to a suitable section specification
-for HTML. Note that we keep spaces and special characters except
-C<", ?> (Netscape problem) and the hyphen (writer's problem...).
+=item * C<htmlify()> (by default)
-=head2 anchorify
+=item * C<anchorify()> (upon request)
+
+=item * C<relativize_url()> (upon request)
+
+=back
- anchorify(@heading);
+The definition and documentation of these functions have been moved to
+F<Pod::Html::Util>, viewable via C<perldoc Pod::Html::Util>.
-Similar to C<htmlify()>, but turns non-alphanumerics into underscores. Note
-that C<anchorify()> is not exported by default.
+Beginning with perl-5.38 these functions must be explicitly imported from
+F<Pod::Html::Util>. Please modify your code as needed.
=head1 ENVIRONMENT
@@ -224,386 +235,234 @@ This program is distributed under the Artistic License.
=cut
-# This sub duplicates the guts of Pod::Simple::FromTree. We could have
-# used that module, except that it would have been a non-core dependency.
-sub feed_tree_to_parser {
- my($parser, $tree) = @_;
- if(ref($tree) eq "") {
- $parser->_handle_text($tree);
- } elsif(!($tree->[0] eq "X" && $parser->nix_X_codes)) {
- $parser->_handle_element_start($tree->[0], $tree->[1]);
- feed_tree_to_parser($parser, $_) foreach @{$tree}[2..$#$tree];
- $parser->_handle_element_end($tree->[0]);
- }
-}
-
-my $Cachedir;
-my $Dircache;
-my($Htmlroot, $Htmldir, $Htmlfile, $Htmlfileurl);
-my($Podfile, @Podpath, $Podroot);
-my $Poderrors;
-my $Css;
-
-my $Recurse;
-my $Quiet;
-my $Verbose;
-my $Doindex;
-
-my $Backlink;
-
-my($Title, $Header);
-
-my %Pages = (); # associative array used to find the location
- # of pages referenced by L<> links.
-
-my $Curdir = File::Spec->curdir;
-
-sub init_globals {
- $Cachedir = "."; # The directory to which directory caches
- # will be written.
-
- $Dircache = "pod2htmd.tmp";
-
- $Htmlroot = "/"; # http-server base directory from which all
- # relative paths in $podpath stem.
- $Htmldir = ""; # The directory to which the html pages
- # will (eventually) be written.
- $Htmlfile = ""; # write to stdout by default
- $Htmlfileurl = ""; # The url that other files would use to
- # refer to this file. This is only used
- # to make relative urls that point to
- # other files.
-
- $Poderrors = 1;
- $Podfile = ""; # read from stdin by default
- @Podpath = (); # list of directories containing library pods.
- $Podroot = $Curdir; # filesystem base directory from which all
- # relative paths in $podpath stem.
- $Css = ''; # Cascading style sheet
- $Recurse = 1; # recurse on subdirectories in $podpath.
- $Quiet = 0; # not quiet by default
- $Verbose = 0; # not verbose by default
- $Doindex = 1; # non-zero if we should generate an index
- $Backlink = 0; # no backlinks added by default
- $Header = 0; # produce block header/footer
- $Title = undef; # title to give the pod(s)
+sub new {
+ my $class = shift;
+ return bless {}, $class;
}
sub pod2html {
local(@ARGV) = @_;
local $_;
- init_globals();
- parse_command_line();
+ my $self = Pod::Html->new();
+ $self->init_globals();
- # prevent '//' in urls
- $Htmlroot = "" if $Htmlroot eq "/";
- $Htmldir =~ s#/\z##;
+ my $opts = process_command_line;
+ $self->process_options($opts);
- if ( $Htmlroot eq ''
- && defined( $Htmldir )
- && $Htmldir ne ''
- && substr( $Htmlfile, 0, length( $Htmldir ) ) eq $Htmldir
- ) {
- # Set the 'base' url for this file, so that we can use it
- # as the location from which to calculate relative links
- # to other files. If this is '', then absolute links will
- # be used throughout.
- #$Htmlfileurl = "$Htmldir/" . substr( $Htmlfile, length( $Htmldir ) + 1);
- # Is the above not just "$Htmlfileurl = $Htmlfile"?
- $Htmlfileurl = Pod::Html::_unixify($Htmlfile);
-
- }
+ $self->refine_globals();
# load or generate/cache %Pages
- unless (get_cache($Dircache, \@Podpath, $Podroot, $Recurse)) {
+ unless ($self->get_cache()) {
# generate %Pages
- my $pwd = getcwd();
- chdir($Podroot) ||
- die "$0: error changing to directory $Podroot: $!\n";
-
- # find all pod modules/pages in podpath, store in %Pages
- # - callback used to remove Podroot and extension from each file
- # - laborious to allow '.' in dirnames (e.g., /usr/share/perl/5.14.1)
- Pod::Simple::Search->new->inc(0)->verbose($Verbose)->laborious(1)
- ->callback(\&_save_page)->recurse($Recurse)->survey(@Podpath);
-
- chdir($pwd) || die "$0: error changing to directory $pwd: $!\n";
-
- # cache the directory list for later use
- warn "caching directories for later use\n" if $Verbose;
- open my $cache, '>', $Dircache
- or die "$0: error open $Dircache for writing: $!\n";
-
- print $cache join(":", @Podpath) . "\n$Podroot\n";
- my $_updirs_only = ($Podroot =~ /\.\./) && !($Podroot =~ /[^\.\\\/]/);
- foreach my $key (keys %Pages) {
- if($_updirs_only) {
- my $_dirlevel = $Podroot;
- while($_dirlevel =~ /\.\./) {
- $_dirlevel =~ s/\.\.//;
- # Assume $Pages{$key} has '/' separators (html dir separators).
- $Pages{$key} =~ s/^[\w\s\-\.]+\///;
- }
- }
- print $cache "$key $Pages{$key}\n";
- }
-
- close $cache or die "error closing $Dircache: $!";
+ #%Pages = $self->generate_cache(\%Pages);
+ $self->generate_cache($self->{Pages});
}
-
- my $input;
- unless (@ARGV && $ARGV[0]) {
- if ($Podfile and $Podfile ne '-') {
- $input = $Podfile;
- } else {
- $input = '-'; # XXX: make a test case for this
- }
- } else {
- $Podfile = $ARGV[0];
- $input = *ARGV;
- }
-
- # set options for input parser
- my $parser = Pod::Simple::SimpleTree->new;
- # Normalize whitespace indenting
- $parser->strip_verbatim_indent(\&trim_leading_whitespace);
-
- $parser->codes_in_verbatim(0);
- $parser->accept_targets(qw(html HTML));
- $parser->no_errata_section(!$Poderrors); # note the inverse
-
- warn "Converting input file $Podfile\n" if $Verbose;
- my $podtree = $parser->parse_file($input)->root;
-
- unless(defined $Title) {
- if($podtree->[0] eq "Document" && ref($podtree->[2]) eq "ARRAY" &&
- $podtree->[2]->[0] eq "head1" && @{$podtree->[2]} == 3 &&
- ref($podtree->[2]->[2]) eq "" && $podtree->[2]->[2] eq "NAME" &&
- ref($podtree->[3]) eq "ARRAY" && $podtree->[3]->[0] eq "Para" &&
- @{$podtree->[3]} >= 3 &&
- !(grep { ref($_) ne "" }
- @{$podtree->[3]}[2..$#{$podtree->[3]}]) &&
- (@$podtree == 4 ||
- (ref($podtree->[4]) eq "ARRAY" &&
- $podtree->[4]->[0] eq "head1"))) {
- $Title = join("", @{$podtree->[3]}[2..$#{$podtree->[3]}]);
- }
- }
-
- $Title //= "";
- $Title = html_escape($Title);
+ my $input = $self->identify_input();
+ my $podtree = $self->parse_input_for_podtree($input);
+ $self->set_Title_from_podtree($podtree);
# set options for the HTML generator
- $parser = Pod::Simple::XHTML::LocalPodLinks->new();
+ my $parser = Pod::Simple::XHTML::LocalPodLinks->new();
$parser->codes_in_verbatim(0);
$parser->anchor_items(1); # the old Pod::Html always did
- $parser->backlink($Backlink); # linkify =head1 directives
- $parser->force_title($Title);
- $parser->htmldir($Htmldir);
- $parser->htmlfileurl($Htmlfileurl);
- $parser->htmlroot($Htmlroot);
- $parser->index($Doindex);
- $parser->output_string(\my $output); # written to file later
- $parser->pages(\%Pages);
- $parser->quiet($Quiet);
- $parser->verbose($Verbose);
+ $parser->backlink($self->{Backlink}); # linkify =head1 directives
+ $parser->force_title($self->{Title});
+ $parser->htmldir($self->{Htmldir});
+ $parser->htmlfileurl($self->{Htmlfileurl});
+ $parser->htmlroot($self->{Htmlroot});
+ $parser->index($self->{Doindex});
+ $parser->output_string(\$self->{output}); # written to file later
+ #$parser->pages(\%Pages);
+ $parser->pages($self->{Pages});
+ $parser->quiet($self->{Quiet});
+ $parser->verbose($self->{Verbose});
+
+ $parser = $self->refine_parser($parser);
+ $self->feed_tree_to_parser($parser, $podtree);
+ $self->write_file();
+}
- # We need to add this ourselves because we use our own header, not
- # ::XHTML's header. We need to set $parser->backlink to linkify
- # the =head1 directives
- my $bodyid = $Backlink ? ' id="_podtop_"' : '';
+sub init_globals {
+ my $self = shift;
+ $self->{Cachedir} = "."; # The directory to which directory caches
+ # will be written.
+
+ $self->{Dircache} = "pod2htmd.tmp";
+
+ $self->{Htmlroot} = "/"; # http-server base directory from which all
+ # relative paths in $podpath stem.
+ $self->{Htmldir} = ""; # The directory to which the html pages
+ # will (eventually) be written.
+ $self->{Htmlfile} = ""; # write to stdout by default
+ $self->{Htmlfileurl} = ""; # The url that other files would use to
+ # refer to this file. This is only used
+ # to make relative urls that point to
+ # other files.
+
+ $self->{Poderrors} = 1;
+ $self->{Podfile} = ""; # read from stdin by default
+ $self->{Podpath} = []; # list of directories containing library pods.
+ $self->{Podroot} = $self->{Curdir} = File::Spec->curdir;
+ # filesystem base directory from which all
+ # relative paths in $podpath stem.
+ $self->{Css} = ''; # Cascading style sheet
+ $self->{Recurse} = 1; # recurse on subdirectories in $podpath.
+ $self->{Quiet} = 0; # not quiet by default
+ $self->{Verbose} = 0; # not verbose by default
+ $self->{Doindex} = 1; # non-zero if we should generate an index
+ $self->{Backlink} = 0; # no backlinks added by default
+ $self->{Header} = 0; # produce block header/footer
+ $self->{Title} = undef; # title to give the pod(s)
+ $self->{Saved_Cache_Key} = '';
+ $self->{Pages} = {};
+ return $self;
+}
- my $csslink = '';
- my $tdstyle = ' style="background-color: #cccccc; color: #000"';
+sub process_options {
+ my ($self, $opts) = @_;
+
+ $self->{Podpath} = (defined $opts->{podpath})
+ ? [ split(":", $opts->{podpath}) ]
+ : [];
+
+ $self->{Backlink} = $opts->{backlink} if defined $opts->{backlink};
+ $self->{Cachedir} = unixify($opts->{cachedir}) if defined $opts->{cachedir};
+ $self->{Css} = $opts->{css} if defined $opts->{css};
+ $self->{Header} = $opts->{header} if defined $opts->{header};
+ $self->{Htmldir} = unixify($opts->{htmldir}) if defined $opts->{htmldir};
+ $self->{Htmlroot} = unixify($opts->{htmlroot}) if defined $opts->{htmlroot};
+ $self->{Doindex} = $opts->{index} if defined $opts->{index};
+ $self->{Podfile} = unixify($opts->{infile}) if defined $opts->{infile};
+ $self->{Htmlfile} = unixify($opts->{outfile}) if defined $opts->{outfile};
+ $self->{Poderrors} = $opts->{poderrors} if defined $opts->{poderrors};
+ $self->{Podroot} = unixify($opts->{podroot}) if defined $opts->{podroot};
+ $self->{Quiet} = $opts->{quiet} if defined $opts->{quiet};
+ $self->{Recurse} = $opts->{recurse} if defined $opts->{recurse};
+ $self->{Title} = $opts->{title} if defined $opts->{title};
+ $self->{Verbose} = $opts->{verbose} if defined $opts->{verbose};
- if ($Css) {
- $csslink = qq(\n<link rel="stylesheet" href="$Css" type="text/css" />);
- $csslink =~ s,\\,/,g;
- $csslink =~ s,(/.):,$1|,;
- $tdstyle= '';
+ warn "Flushing directory caches\n"
+ if $opts->{verbose} && defined $opts->{flush};
+ $self->{Dircache} = "$self->{Cachedir}/pod2htmd.tmp";
+ if (defined $opts->{flush}) {
+ 1 while unlink($self->{Dircache});
}
+ return $self;
+}
- # header/footer block
- my $block = $Header ? <<END_OF_BLOCK : '';
-<table border="0" width="100%" cellspacing="0" cellpadding="3">
-<tr><td class="_podblock_"$tdstyle valign="middle">
-<big><strong><span class="_podblock_">&nbsp;$Title</span></strong></big>
-</td></tr>
-</table>
-END_OF_BLOCK
-
- # create own header/footer because of --header
- $parser->html_header(<<"HTMLHEAD");
-<?xml version="1.0" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title>$Title</title>$csslink
-<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-<link rev="made" href="mailto:$Config{perladmin}" />
-</head>
-
-<body$bodyid>
-$block
-HTMLHEAD
-
- $parser->html_footer(<<"HTMLFOOT");
-$block
-</body>
-
-</html>
-HTMLFOOT
+sub refine_globals {
+ my $self = shift;
- feed_tree_to_parser($parser, $podtree);
+ # prevent '//' in urls
+ $self->{Htmlroot} = "" if $self->{Htmlroot} eq "/";
+ $self->{Htmldir} =~ s#/\z##;
- # Write output to file
- $Htmlfile = "-" unless $Htmlfile; # stdout
- my $fhout;
- if($Htmlfile and $Htmlfile ne '-') {
- open $fhout, ">", $Htmlfile
- or die "$0: cannot open $Htmlfile file for output: $!\n";
- } else {
- open $fhout, ">-";
+ if ( $self->{Htmlroot} eq ''
+ && defined( $self->{Htmldir} )
+ && $self->{Htmldir} ne ''
+ && substr( $self->{Htmlfile}, 0, length( $self->{Htmldir} ) ) eq $self->{Htmldir}
+ ) {
+ # Set the 'base' url for this file, so that we can use it
+ # as the location from which to calculate relative links
+ # to other files. If this is '', then absolute links will
+ # be used throughout.
+ #$self->{Htmlfileurl} = "$self->{Htmldir}/" . substr( $self->{Htmlfile}, length( $self->{Htmldir} ) + 1);
+ # Is the above not just "$self->{Htmlfileurl} = $self->{Htmlfile}"?
+ $self->{Htmlfileurl} = unixify($self->{Htmlfile});
}
- binmode $fhout, ":utf8";
- print $fhout $output;
- close $fhout or die "Failed to close $Htmlfile: $!";
- chmod 0644, $Htmlfile unless $Htmlfile eq '-';
+ return $self;
}
-##############################################################################
-
-sub usage {
- my $podfile = shift;
- warn "$0: $podfile: @_\n" if @_;
- die <<END_OF_USAGE;
-Usage: $0 --help --htmldir=<name> --htmlroot=<URL>
- --infile=<name> --outfile=<name>
- --podpath=<name>:...:<name> --podroot=<name>
- --cachedir=<name> --flush --recurse --norecurse
- --quiet --noquiet --verbose --noverbose
- --index --noindex --backlink --nobacklink
- --header --noheader --poderrors --nopoderrors
- --css=<URL> --title=<name>
-
- --[no]backlink - turn =head1 directives into links pointing to the top of
- the page (off by default).
- --cachedir - directory for the directory cache files.
- --css - stylesheet URL
- --flush - flushes the directory cache.
- --[no]header - produce block header/footer (default is no headers).
- --help - prints this message.
- --htmldir - directory for resulting HTML files.
- --htmlroot - http-server base directory from which all relative paths
- in podpath stem (default is /).
- --[no]index - generate an index at the top of the resulting html
- (default behaviour).
- --infile - filename for the pod to convert (input taken from stdin
- by default).
- --outfile - filename for the resulting html file (output sent to
- stdout by default).
- --[no]poderrors - include a POD ERRORS section in the output if there were
- any POD errors in the input (default behavior).
- --podpath - colon-separated list of directories containing library
- pods (empty by default).
- --podroot - filesystem base directory from which all relative paths
- in podpath stem (default is .).
- --[no]quiet - suppress some benign warning messages (default is off).
- --[no]recurse - recurse on those subdirectories listed in podpath
- (default behaviour).
- --title - title that will appear in resulting html file.
- --[no]verbose - self-explanatory (off by default).
-
-END_OF_USAGE
+sub generate_cache {
+ my $self = shift;
+ my $pwd = getcwd();
+ chdir($self->{Podroot}) ||
+ die "$0: error changing to directory $self->{Podroot}: $!\n";
+
+ # find all pod modules/pages in podpath, store in %Pages
+ # - inc(0): do not prepend directories in @INC to search list;
+ # limit search to those in @{$self->{Podpath}}
+ # - verbose: report (via 'warn') what search is doing
+ # - laborious: to allow '.' in dirnames (e.g., /usr/share/perl/5.14.1)
+ # - recurse: go into subdirectories
+ # - survey: search for POD files in PodPath
+ my ($name2path, $path2name) =
+ Pod::Simple::Search->new->inc(0)->verbose($self->{Verbose})->laborious(1)
+ ->recurse($self->{Recurse})->survey(@{$self->{Podpath}});
+ # remove Podroot and extension from each file
+ for my $k (keys %{$name2path}) {
+ $self->{Pages}{$k} = _transform($self, $name2path->{$k});
+ }
+ chdir($pwd) || die "$0: error changing to directory $pwd: $!\n";
+
+ # cache the directory list for later use
+ warn "caching directories for later use\n" if $self->{Verbose};
+ open my $cache, '>', $self->{Dircache}
+ or die "$0: error open $self->{Dircache} for writing: $!\n";
+
+ print $cache join(":", @{$self->{Podpath}}) . "\n$self->{Podroot}\n";
+ my $_updirs_only = ($self->{Podroot} =~ /\.\./) && !($self->{Podroot} =~ /[^\.\\\/]/);
+ foreach my $key (keys %{$self->{Pages}}) {
+ if($_updirs_only) {
+ my $_dirlevel = $self->{Podroot};
+ while($_dirlevel =~ /\.\./) {
+ $_dirlevel =~ s/\.\.//;
+ # Assume $Pagesref->{$key} has '/' separators (html dir separators).
+ $self->{Pages}->{$key} =~ s/^[\w\s\-\.]+\///;
+ }
+ }
+ print $cache "$key $self->{Pages}->{$key}\n";
+ }
+ close $cache or die "error closing $self->{Dircache}: $!";
}
-sub parse_command_line {
- my ($opt_backlink,$opt_cachedir,$opt_css,$opt_flush,$opt_header,
- $opt_help,$opt_htmldir,$opt_htmlroot,$opt_index,$opt_infile,
- $opt_outfile,$opt_poderrors,$opt_podpath,$opt_podroot,
- $opt_quiet,$opt_recurse,$opt_title,$opt_verbose);
-
- unshift @ARGV, split ' ', $Config{pod2html} if $Config{pod2html};
- my $result = GetOptions(
- 'backlink!' => \$opt_backlink,
- 'cachedir=s' => \$opt_cachedir,
- 'css=s' => \$opt_css,
- 'flush' => \$opt_flush,
- 'help' => \$opt_help,
- 'header!' => \$opt_header,
- 'htmldir=s' => \$opt_htmldir,
- 'htmlroot=s' => \$opt_htmlroot,
- 'index!' => \$opt_index,
- 'infile=s' => \$opt_infile,
- 'outfile=s' => \$opt_outfile,
- 'poderrors!' => \$opt_poderrors,
- 'podpath=s' => \$opt_podpath,
- 'podroot=s' => \$opt_podroot,
- 'quiet!' => \$opt_quiet,
- 'recurse!' => \$opt_recurse,
- 'title=s' => \$opt_title,
- 'verbose!' => \$opt_verbose,
- );
- usage("-", "invalid parameters") if not $result;
-
- usage("-") if defined $opt_help; # see if the user asked for help
- $opt_help = ""; # just to make -w shut-up.
-
- @Podpath = split(":", $opt_podpath) if defined $opt_podpath;
-
- $Backlink = $opt_backlink if defined $opt_backlink;
- $Cachedir = _unixify($opt_cachedir) if defined $opt_cachedir;
- $Css = $opt_css if defined $opt_css;
- $Header = $opt_header if defined $opt_header;
- $Htmldir = _unixify($opt_htmldir) if defined $opt_htmldir;
- $Htmlroot = _unixify($opt_htmlroot) if defined $opt_htmlroot;
- $Doindex = $opt_index if defined $opt_index;
- $Podfile = _unixify($opt_infile) if defined $opt_infile;
- $Htmlfile = _unixify($opt_outfile) if defined $opt_outfile;
- $Poderrors = $opt_poderrors if defined $opt_poderrors;
- $Podroot = _unixify($opt_podroot) if defined $opt_podroot;
- $Quiet = $opt_quiet if defined $opt_quiet;
- $Recurse = $opt_recurse if defined $opt_recurse;
- $Title = $opt_title if defined $opt_title;
- $Verbose = $opt_verbose if defined $opt_verbose;
+sub _transform {
+ my ($self, $v) = @_;
+ $v = $self->{Podroot} eq File::Spec->curdir
+ ? File::Spec->abs2rel($v)
+ : File::Spec->abs2rel($v,
+ File::Spec->canonpath($self->{Podroot}));
- warn "Flushing directory caches\n"
- if $opt_verbose && defined $opt_flush;
- $Dircache = "$Cachedir/pod2htmd.tmp";
- if (defined $opt_flush) {
- 1 while unlink($Dircache);
- }
-}
+ # Convert path to unix style path
+ $v = unixify($v);
-my $Saved_Cache_Key;
+ my ($file, $dir) = fileparse($v, qr/\.[^.]*/); # strip .ext
+ return $dir.$file;
+}
sub get_cache {
- my($dircache, $podpath, $podroot, $recurse) = @_;
+ my $self = shift;
# A first-level cache:
# Don't bother reading the cache files if they still apply
# and haven't changed since we last read them.
- my $this_cache_key = cache_key($dircache, $podpath, $podroot, $recurse);
- return 1 if $Saved_Cache_Key and $this_cache_key eq $Saved_Cache_Key;
- $Saved_Cache_Key = $this_cache_key;
+ my $this_cache_key = $self->cache_key();
+ return 1 if $self->{Saved_Cache_Key} and $this_cache_key eq $self->{Saved_Cache_Key};
+ $self->{Saved_Cache_Key} = $this_cache_key;
# load the cache of %Pages if possible. $tests will be
# non-zero if successful.
my $tests = 0;
- if (-f $dircache) {
- warn "scanning for directory cache\n" if $Verbose;
- $tests = load_cache($dircache, $podpath, $podroot);
+ if (-f $self->{Dircache}) {
+ warn "scanning for directory cache\n" if $self->{Verbose};
+ $tests = $self->load_cache();
}
return $tests;
}
sub cache_key {
- my($dircache, $podpath, $podroot, $recurse) = @_;
- return join('!',$dircache,$recurse,@$podpath,$podroot,stat($dircache));
+ my $self = shift;
+ return join('!',
+ $self->{Dircache},
+ $self->{Recurse},
+ @{$self->{Podpath}},
+ $self->{Podroot},
+ stat($self->{Dircache}),
+ );
}
#
@@ -611,24 +470,24 @@ sub cache_key {
# cache of %Pages. if so, it loads them and returns a non-zero value.
#
sub load_cache {
- my($dircache, $podpath, $podroot) = @_;
+ my $self = shift;
my $tests = 0;
local $_;
- warn "scanning for directory cache\n" if $Verbose;
- open(my $cachefh, '<', $dircache) ||
- die "$0: error opening $dircache for reading: $!\n";
+ warn "scanning for directory cache\n" if $self->{Verbose};
+ open(my $cachefh, '<', $self->{Dircache}) ||
+ die "$0: error opening $self->{Dircache} for reading: $!\n";
$/ = "\n";
# is it the same podpath?
$_ = <$cachefh>;
chomp($_);
- $tests++ if (join(":", @$podpath) eq $_);
+ $tests++ if (join(":", @{$self->{Podpath}}) eq $_);
# is it the same podroot?
$_ = <$cachefh>;
chomp($_);
- $tests++ if ($podroot eq $_);
+ $tests++ if ($self->{Podroot} eq $_);
# load the cache if its good
if ($tests != 2) {
@@ -636,96 +495,147 @@ sub load_cache {
return 0;
}
- warn "loading directory cache\n" if $Verbose;
+ warn "loading directory cache\n" if $self->{Verbose};
while (<$cachefh>) {
/(.*?) (.*)$/;
- $Pages{$1} = $2;
+ $self->{Pages}->{$1} = $2;
}
close($cachefh);
return 1;
}
-
-#
-# html_escape: make text safe for HTML
-#
-sub html_escape {
- my $rest = $_[0];
- $rest =~ s/&/&amp;/g;
- $rest =~ s/</&lt;/g;
- $rest =~ s/>/&gt;/g;
- $rest =~ s/"/&quot;/g;
- $rest =~ s/([[:^print:]])/sprintf("&#x%x;", ord($1))/aeg;
- return $rest;
+sub identify_input {
+ my $self = shift;
+ my $input;
+ unless (@ARGV && $ARGV[0]) {
+ if ($self->{Podfile} and $self->{Podfile} ne '-') {
+ $input = $self->{Podfile};
+ } else {
+ $input = '-'; # XXX: make a test case for this
+ }
+ } else {
+ $self->{Podfile} = $ARGV[0];
+ $input = *ARGV;
+ }
+ return $input;
}
-#
-# htmlify - converts a pod section specification to a suitable section
-# specification for HTML. We adopt the mechanism used by the formatter
-# that we use.
-#
-sub htmlify {
- my( $heading) = @_;
- return Pod::Simple::XHTML->can("idify")->(undef, $heading, 1);
+sub parse_input_for_podtree {
+ my ($self, $input) = @_;
+ # set options for input parser
+ my $input_parser = Pod::Simple::SimpleTree->new;
+ # Normalize whitespace indenting
+ $input_parser->strip_verbatim_indent(\&trim_leading_whitespace);
+
+ $input_parser->codes_in_verbatim(0);
+ $input_parser->accept_targets(qw(html HTML));
+ $input_parser->no_errata_section(!$self->{Poderrors}); # note the inverse
+
+ warn "Converting input file $self->{Podfile}\n" if $self->{Verbose};
+ my $podtree = $input_parser->parse_file($input)->root;
+ return $podtree;
}
-#
-# similar to htmlify, but turns non-alphanumerics into underscores
-#
-sub anchorify {
- my ($anchor) = @_;
- $anchor = htmlify($anchor);
- $anchor =~ s/\W/_/g;
- return $anchor;
+sub set_Title_from_podtree {
+ my ($self, $podtree) = @_;
+ unless(defined $self->{Title}) {
+ if($podtree->[0] eq "Document" && ref($podtree->[2]) eq "ARRAY" &&
+ $podtree->[2]->[0] eq "head1" && @{$podtree->[2]} == 3 &&
+ ref($podtree->[2]->[2]) eq "" && $podtree->[2]->[2] eq "NAME" &&
+ ref($podtree->[3]) eq "ARRAY" && $podtree->[3]->[0] eq "Para" &&
+ @{$podtree->[3]} >= 3 &&
+ !(grep { ref($_) ne "" }
+ @{$podtree->[3]}[2..$#{$podtree->[3]}]) &&
+ (@$podtree == 4 ||
+ (ref($podtree->[4]) eq "ARRAY" &&
+ $podtree->[4]->[0] eq "head1"))) {
+ $self->{Title} = join("", @{$podtree->[3]}[2..$#{$podtree->[3]}]);
+ }
+ }
+
+ $self->{Title} //= "";
+ $self->{Title} = html_escape($self->{Title});
+ return $self;
}
-#
-# store POD files in %Pages
-#
-sub _save_page {
- my ($modspec, $modname) = @_;
+sub refine_parser {
+ my ($self, $parser) = @_;
+ # We need to add this ourselves because we use our own header, not
+ # ::XHTML's header. We need to set $parser->backlink to linkify
+ # the =head1 directives
+ my $bodyid = $self->{Backlink} ? ' id="_podtop_"' : '';
- # Remove Podroot from path
- $modspec = $Podroot eq File::Spec->curdir
- ? File::Spec->abs2rel($modspec)
- : File::Spec->abs2rel($modspec,
- File::Spec->canonpath($Podroot));
+ my $csslink = '';
+ my $tdstyle = ' style="background-color: #cccccc; color: #000"';
- # Convert path to unix style path
- $modspec = Pod::Html::_unixify($modspec);
+ if ($self->{Css}) {
+ $csslink = qq(\n<link rel="stylesheet" href="$self->{Css}" type="text/css" />);
+ $csslink =~ s,\\,/,g;
+ $csslink =~ s,(/.):,$1|,;
+ $tdstyle= '';
+ }
+
+ # header/footer block
+ my $block = $self->{Header} ? <<END_OF_BLOCK : '';
+<table border="0" width="100%" cellspacing="0" cellpadding="3">
+<tr><td class="_podblock_"$tdstyle valign="middle">
+<big><strong><span class="_podblock_">&nbsp;$self->{Title}</span></strong></big>
+</td></tr>
+</table>
+END_OF_BLOCK
+
+ # create own header/footer because of --header
+ $parser->html_header(<<"HTMLHEAD");
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>$self->{Title}</title>$csslink
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:$Config{perladmin}" />
+</head>
+
+<body$bodyid>
+$block
+HTMLHEAD
+
+ $parser->html_footer(<<"HTMLFOOT");
+$block
+</body>
- my ($file, $dir) = fileparse($modspec, qr/\.[^.]*/); # strip .ext
- $Pages{$modname} = $dir.$file;
+</html>
+HTMLFOOT
+ return $parser;
}
-sub _unixify {
- my $full_path = shift;
- return '' unless $full_path;
- return $full_path if $full_path eq '/';
-
- my ($vol, $dirs, $file) = File::Spec->splitpath($full_path);
- my @dirs = $dirs eq File::Spec->curdir()
- ? (File::Spec::Unix->curdir())
- : File::Spec->splitdir($dirs);
- if (defined($vol) && $vol) {
- $vol =~ s/:$// if $^O eq 'VMS';
- $vol = uc $vol if $^O eq 'MSWin32';
-
- if( $dirs[0] ) {
- unshift @dirs, $vol;
- }
- else {
- $dirs[0] = $vol;
- }
+# This sub duplicates the guts of Pod::Simple::FromTree. We could have
+# used that module, except that it would have been a non-core dependency.
+sub feed_tree_to_parser {
+ my($self, $parser, $tree) = @_;
+ if(ref($tree) eq "") {
+ $parser->_handle_text($tree);
+ } elsif(!($tree->[0] eq "X" && $parser->nix_X_codes)) {
+ $parser->_handle_element_start($tree->[0], $tree->[1]);
+ $self->feed_tree_to_parser($parser, $_) foreach @{$tree}[2..$#$tree];
+ $parser->_handle_element_end($tree->[0]);
}
- unshift @dirs, '' if File::Spec->file_name_is_absolute($full_path);
- return $file unless scalar(@dirs);
- $full_path = File::Spec::Unix->catfile(File::Spec::Unix->catdir(@dirs),
- $file);
- $full_path =~ s|^\/|| if $^O eq 'MSWin32'; # C:/foo works, /C:/foo doesn't
- $full_path =~ s/\^\././g if $^O eq 'VMS'; # unescape dots
- return $full_path;
+}
+
+sub write_file {
+ my $self = shift;
+ $self->{Htmlfile} = "-" unless $self->{Htmlfile}; # stdout
+ my $fhout;
+ if($self->{Htmlfile} and $self->{Htmlfile} ne '-') {
+ open $fhout, ">", $self->{Htmlfile}
+ or die "$0: cannot open $self->{Htmlfile} file for output: $!\n";
+ } else {
+ open $fhout, ">-";
+ }
+ binmode $fhout, ":utf8";
+ print $fhout $self->{output};
+ close $fhout or die "Failed to close $self->{Htmlfile}: $!";
+ chmod 0644, $self->{Htmlfile} unless $self->{Htmlfile} eq '-';
}
package Pod::Simple::XHTML::LocalPodLinks;
@@ -795,15 +705,15 @@ sub resolve_pod_page_link {
$path = $self->pages->{$to};
}
- my $url = File::Spec::Unix->catfile(Pod::Html::_unixify($self->htmlroot),
+ my $url = File::Spec::Unix->catfile(Pod::Html::Util::unixify($self->htmlroot),
$path);
if ($self->htmlfileurl ne '') {
# then $self->htmlroot eq '' (by definition of htmlfileurl) so
# $self->htmldir needs to be prepended to link to get the absolute path
# that will be relativized
- $url = Pod::Html::relativize_url(
- File::Spec::Unix->catdir(Pod::Html::_unixify($self->htmldir), $url),
+ $url = Pod::Html::Util::relativize_url(
+ File::Spec::Unix->catdir(Pod::Html::Util::unixify($self->htmldir), $url),
$self->htmlfileurl # already unixified
);
}
@@ -811,56 +721,4 @@ sub resolve_pod_page_link {
return $url . ".html$section";
}
-package Pod::Html;
-
-#
-# relativize_url - convert an absolute URL to one relative to a base URL.
-# Assumes both end in a filename.
-#
-sub relativize_url {
- my ($dest, $source) = @_;
-
- # Remove each file from its path
- my ($dest_volume, $dest_directory, $dest_file) =
- File::Spec::Unix->splitpath( $dest );
- $dest = File::Spec::Unix->catpath( $dest_volume, $dest_directory, '' );
-
- my ($source_volume, $source_directory, $source_file) =
- File::Spec::Unix->splitpath( $source );
- $source = File::Spec::Unix->catpath( $source_volume, $source_directory, '' );
-
- my $rel_path = '';
- if ($dest ne '') {
- $rel_path = File::Spec::Unix->abs2rel( $dest, $source );
- }
-
- if ($rel_path ne '' && substr( $rel_path, -1 ) ne '/') {
- $rel_path .= "/$dest_file";
- } else {
- $rel_path .= "$dest_file";
- }
-
- return $rel_path;
-}
-
-# Remove any level of indentation (spaces or tabs) from each code block consistently
-# Adapted from: https://metacpan.org/source/HAARG/MetaCPAN-Pod-XHTML-0.002001/lib/Pod/Simple/Role/StripVerbatimIndent.pm
-sub trim_leading_whitespace {
- my ($para) = @_;
-
- # Start by converting tabs to spaces
- @$para = Text::Tabs::expand(@$para);
-
- # Find the line with the least amount of indent, as that's our "base"
- my @indent_levels = (sort(map { $_ =~ /^( *)./mg } @$para));
- my $indent = $indent_levels[0] || "";
-
- # Remove the "base" amount of indent from each line
- foreach (@$para) {
- $_ =~ s/^\Q$indent//mg;
- }
-
- return;
-}
-
1;
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html/Util.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html/Util.pm
new file mode 100755
index 0000000000..88452d4d4e
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Html/Util.pm
@@ -0,0 +1,282 @@
+package Pod::Html::Util;
+use strict;
+use Exporter 'import';
+
+our $VERSION = 1.34; # Please keep in synch with lib/Pod/Html.pm
+$VERSION = eval $VERSION;
+our @EXPORT_OK = qw(
+ anchorify
+ html_escape
+ htmlify
+ process_command_line
+ relativize_url
+ trim_leading_whitespace
+ unixify
+ usage
+);
+
+use Config;
+use File::Spec;
+use File::Spec::Unix;
+use Getopt::Long;
+use Pod::Simple::XHTML;
+use Text::Tabs;
+use locale; # make \w work right in non-ASCII lands
+
+=head1 NAME
+
+Pod::Html::Util - helper functions for Pod-Html
+
+=head1 SUBROUTINES
+
+B<Note:> While these functions are importable on request from
+F<Pod::Html::Util>, they are specifically intended for use within (a) the
+F<Pod-Html> distribution (modules and test programs) shipped as part of the
+Perl 5 core and (b) other parts of the core such as the F<installhtml>
+program. These functions may be modified or relocated within the core
+distribution -- or removed entirely therefrom -- as the core's needs evolve.
+Hence, you should not rely on these functions in situations other than those
+just described.
+
+=cut
+
+=head2 C<process_command_line()>
+
+Process command-line switches (options). Returns a reference to a hash. Will
+provide usage message if C<--help> switch is present or if parameters are
+invalid.
+
+Calling this subroutine may modify C<@ARGV>.
+
+=cut
+
+sub process_command_line {
+ my %opts = map { $_ => undef } (qw|
+ backlink cachedir css flush
+ header help htmldir htmlroot
+ index infile outfile poderrors
+ podpath podroot quiet recurse
+ title verbose
+ |);
+ unshift @ARGV, split ' ', $Config{pod2html} if $Config{pod2html};
+ my $result = GetOptions(\%opts,
+ 'backlink!',
+ 'cachedir=s',
+ 'css=s',
+ 'flush',
+ 'help',
+ 'header!',
+ 'htmldir=s',
+ 'htmlroot=s',
+ 'index!',
+ 'infile=s',
+ 'outfile=s',
+ 'poderrors!',
+ 'podpath=s',
+ 'podroot=s',
+ 'quiet!',
+ 'recurse!',
+ 'title=s',
+ 'verbose!',
+ );
+ usage("-", "invalid parameters") if not $result;
+ usage("-") if defined $opts{help}; # see if the user asked for help
+ $opts{help} = ""; # just to make -w shut-up.
+ return \%opts;
+}
+
+=head2 C<usage()>
+
+Display customary Pod::Html usage information on STDERR.
+
+=cut
+
+sub usage {
+ my $podfile = shift;
+ warn "$0: $podfile: @_\n" if @_;
+ die <<END_OF_USAGE;
+Usage: $0 --help --htmldir=<name> --htmlroot=<URL>
+ --infile=<name> --outfile=<name>
+ --podpath=<name>:...:<name> --podroot=<name>
+ --cachedir=<name> --flush --recurse --norecurse
+ --quiet --noquiet --verbose --noverbose
+ --index --noindex --backlink --nobacklink
+ --header --noheader --poderrors --nopoderrors
+ --css=<URL> --title=<name>
+
+ --[no]backlink - turn =head1 directives into links pointing to the top of
+ the page (off by default).
+ --cachedir - directory for the directory cache files.
+ --css - stylesheet URL
+ --flush - flushes the directory cache.
+ --[no]header - produce block header/footer (default is no headers).
+ --help - prints this message.
+ --htmldir - directory for resulting HTML files.
+ --htmlroot - http-server base directory from which all relative paths
+ in podpath stem (default is /).
+ --[no]index - generate an index at the top of the resulting html
+ (default behaviour).
+ --infile - filename for the pod to convert (input taken from stdin
+ by default).
+ --outfile - filename for the resulting html file (output sent to
+ stdout by default).
+ --[no]poderrors - include a POD ERRORS section in the output if there were
+ any POD errors in the input (default behavior).
+ --podpath - colon-separated list of directories containing library
+ pods (empty by default).
+ --podroot - filesystem base directory from which all relative paths
+ in podpath stem (default is .).
+ --[no]quiet - suppress some benign warning messages (default is off).
+ --[no]recurse - recurse on those subdirectories listed in podpath
+ (default behaviour).
+ --title - title that will appear in resulting html file.
+ --[no]verbose - self-explanatory (off by default).
+
+END_OF_USAGE
+
+}
+
+=head2 C<unixify()>
+
+Ensure that F<Pod::Html>'s internals and tests handle paths consistently
+across Unix, Windows and VMS.
+
+=cut
+
+sub unixify {
+ my $full_path = shift;
+ return '' unless $full_path;
+ return $full_path if $full_path eq '/';
+
+ my ($vol, $dirs, $file) = File::Spec->splitpath($full_path);
+ my @dirs = $dirs eq File::Spec->curdir()
+ ? (File::Spec::Unix->curdir())
+ : File::Spec->splitdir($dirs);
+ if (defined($vol) && $vol) {
+ $vol =~ s/:$// if $^O eq 'VMS';
+ $vol = uc $vol if $^O eq 'MSWin32';
+
+ if( $dirs[0] ) {
+ unshift @dirs, $vol;
+ }
+ else {
+ $dirs[0] = $vol;
+ }
+ }
+ unshift @dirs, '' if File::Spec->file_name_is_absolute($full_path);
+ return $file unless scalar(@dirs);
+ $full_path = File::Spec::Unix->catfile(File::Spec::Unix->catdir(@dirs),
+ $file);
+ $full_path =~ s|^\/|| if $^O eq 'MSWin32'; # C:/foo works, /C:/foo doesn't
+ $full_path =~ s/\^\././g if $^O eq 'VMS'; # unescape dots
+ return $full_path;
+}
+
+=head2 C<relativize_url()>
+
+Convert an absolute URL to one relative to a base URL.
+Assumes both end in a filename.
+
+=cut
+
+sub relativize_url {
+ my ($dest, $source) = @_;
+
+ # Remove each file from its path
+ my ($dest_volume, $dest_directory, $dest_file) =
+ File::Spec::Unix->splitpath( $dest );
+ $dest = File::Spec::Unix->catpath( $dest_volume, $dest_directory, '' );
+
+ my ($source_volume, $source_directory, $source_file) =
+ File::Spec::Unix->splitpath( $source );
+ $source = File::Spec::Unix->catpath( $source_volume, $source_directory, '' );
+
+ my $rel_path = '';
+ if ($dest ne '') {
+ $rel_path = File::Spec::Unix->abs2rel( $dest, $source );
+ }
+
+ if ($rel_path ne '' && substr( $rel_path, -1 ) ne '/') {
+ $rel_path .= "/$dest_file";
+ } else {
+ $rel_path .= "$dest_file";
+ }
+
+ return $rel_path;
+}
+
+=head2 C<html_escape()>
+
+Make text safe for HTML.
+
+=cut
+
+sub html_escape {
+ my $rest = $_[0];
+ $rest =~ s/&/&amp;/g;
+ $rest =~ s/</&lt;/g;
+ $rest =~ s/>/&gt;/g;
+ $rest =~ s/"/&quot;/g;
+ $rest =~ s/([[:^print:]])/sprintf("&#x%x;", ord($1))/aeg;
+ return $rest;
+}
+
+=head2 C<htmlify()>
+
+ htmlify($heading);
+
+Converts a pod section specification to a suitable section specification
+for HTML. Note that we keep spaces and special characters except
+C<", ?> (Netscape problem) and the hyphen (writer's problem...).
+
+=cut
+
+sub htmlify {
+ my( $heading) = @_;
+ return Pod::Simple::XHTML->can("idify")->(undef, $heading, 1);
+}
+
+=head2 C<anchorify()>
+
+ anchorify(@heading);
+
+Similar to C<htmlify()>, but turns non-alphanumerics into underscores. Note
+that C<anchorify()> is not exported by default.
+
+=cut
+
+sub anchorify {
+ my ($anchor) = @_;
+ $anchor = htmlify($anchor);
+ $anchor =~ s/\W/_/g;
+ return $anchor;
+}
+
+=head2 C<trim_leading_whitespace()>
+
+Remove any level of indentation (spaces or tabs) from each code block
+consistently. Adapted from:
+https://metacpan.org/source/HAARG/MetaCPAN-Pod-XHTML-0.002001/lib/Pod/Simple/Role/StripVerbatimIndent.pm
+
+=cut
+
+sub trim_leading_whitespace {
+ my ($para) = @_;
+
+ # Start by converting tabs to spaces
+ @$para = Text::Tabs::expand(@$para);
+
+ # Find the line with the least amount of indent, as that's our "base"
+ my @indent_levels = (sort(map { $_ =~ /^( *)./mg } @$para));
+ my $indent = $indent_levels[0] || "";
+
+ # Remove the "base" amount of indent from each line
+ foreach (@$para) {
+ $_ =~ s/^\Q$indent//mg;
+ }
+
+ return;
+}
+
+1;
+
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Man.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Man.pm
index d7c029357a..5ed95bbc90 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Man.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Man.pm
@@ -14,36 +14,33 @@
package Pod::Man;
-use 5.008;
+use 5.010;
use strict;
use warnings;
-use subs qw(makespace);
-use vars qw(@ISA %ESCAPES $PREAMBLE $VERSION);
-
use Carp qw(carp croak);
use Pod::Simple ();
# Conditionally import Encode and set $HAS_ENCODE if it is available. This is
# required to support building as part of Perl core, since podlators is built
# before Encode is.
-our $HAS_ENCODE;
+my $HAS_ENCODE;
BEGIN {
$HAS_ENCODE = eval { require Encode };
}
-@ISA = qw(Pod::Simple);
-
-$VERSION = '4.14';
-
-# Set the debugging level. If someone has inserted a debug function into this
-# class already, use that. Otherwise, use any Pod::Simple debug function
-# that's defined, and failing that, define a debug level of 10.
-BEGIN {
- my $parent = defined (&Pod::Simple::DEBUG) ? \&Pod::Simple::DEBUG : undef;
- unless (defined &DEBUG) {
- *DEBUG = $parent || sub () { 10 };
- }
+our @ISA = qw(Pod::Simple);
+our $VERSION = '5.01';
+
+# Ensure that $Pod::Simple::nbsp and $Pod::Simple::shy are available. Code
+# taken from Pod::Simple 3.32, but was only added in 3.30.
+my ($NBSP, $SHY);
+if ($Pod::Simple::VERSION ge 3.30) {
+ $NBSP = $Pod::Simple::nbsp;
+ $SHY = $Pod::Simple::shy;
+} else {
+ $NBSP = chr utf8::unicode_to_native(0xA0);
+ $SHY = chr utf8::unicode_to_native(0xAD);
}
# Import the ASCII constant from Pod::Simple. This is true iff we're in an
@@ -51,15 +48,12 @@ BEGIN {
# generally only false for EBCDIC.
BEGIN { *ASCII = \&Pod::Simple::ASCII }
-# Pretty-print a data structure. Only used for debugging.
-BEGIN { *pretty = \&Pod::Simple::pretty }
-
# Formatting instructions for various types of blocks. cleanup makes hyphens
# hard, adds spaces between consecutive underscores, and escapes backslashes.
# convert translates characters into escapes. guesswork means to apply the
-# transformations done by the guesswork sub. literal says to protect literal
-# quotes from being turned into UTF-8 quotes. By default, all transformations
-# are on except literal, but some elements override.
+# transformations done by the guesswork sub (if enabled). literal says to
+# protect literal quotes from being turned into UTF-8 quotes. By default, all
+# transformations are on except literal, but some elements override.
#
# DEFAULT specifies the default settings. All other elements should list only
# those settings that they are overriding. Data indicates =for roff blocks,
@@ -75,6 +69,98 @@ my %FORMATTING = (
X => { cleanup => 0, guesswork => 0 },
);
+# Try to map an encoding as understood by Perl Encode to an encoding
+# understood by groff's preconv. Encode doesn't care about hyphens or
+# capitalization, but preconv does. The key is the canonicalized Encode
+# encoding, and the value is something preconv might understand.
+#
+# FreeBSD mandoc only understands utf-8 and iso-latin-1 as of 2022-09-24.
+# groff preconv prefers iso-8859-1, but also understands iso-latin-1, so
+# convert ISO-8859-1 to iso-latin-1 for FreeBSD.
+my %ENCODINGS = (
+ ascii => 'us-ascii',
+ big5 => 'big5',
+ big5eten => 'big5',
+ cp950 => 'big5',
+ cp1047 => 'cp1047',
+ euccn => 'gb2312',
+ eucjp => 'euc-jp',
+ euckr => 'euc-kr',
+ gb2312 => 'gb2312',
+ gb2312raw => 'gb2312',
+ iso88591 => 'iso-latin-1',
+ iso88592 => 'iso-8859-2',
+ iso88595 => 'iso-8859-5',
+ iso88597 => 'iso-8859-7',
+ iso88599 => 'iso-8859-9',
+ iso885913 => 'iso-8859-13',
+ iso885915 => 'iso-8859-15',
+ koi8r => 'koi8-r',
+ latin1 => 'iso-8859-1',
+ usascii => 'us-ascii',
+ utf8 => 'utf-8',
+ utf16 => 'utf-16',
+ utf16be => 'utf-16be',
+ utf16le => 'utf-16le',
+);
+
+##############################################################################
+# Translation tables
+##############################################################################
+
+# The following table is adapted from Tom Christiansen's pod2man. It is only
+# used with roff output. It assumes that the standard preamble has already
+# been printed, since that's what defines all of the accent marks. We really
+# want to do something better than this when *roff actually supports other
+# character sets itself, since these results are pretty poor.
+#
+# This only works in an ASCII world. What to do in a non-ASCII world is very
+# unclear, so we just output what we get and hope for the best.
+my %ESCAPES;
+@ESCAPES{0xA0 .. 0xFF} = (
+ $NBSP, undef, undef, undef, undef, undef, undef, undef,
+ undef, undef, undef, undef, undef, $SHY, undef, undef,
+
+ undef, undef, undef, undef, undef, undef, undef, undef,
+ undef, undef, undef, undef, undef, undef, undef, undef,
+
+ "A\\*`", "A\\*'", "A\\*^", "A\\*~", "A\\*:", "A\\*o", "\\*(Ae", "C\\*,",
+ "E\\*`", "E\\*'", "E\\*^", "E\\*:", "I\\*`", "I\\*'", "I\\*^", "I\\*:",
+
+ "\\*(D-", "N\\*~", "O\\*`", "O\\*'", "O\\*^", "O\\*~", "O\\*:", undef,
+ "O\\*/", "U\\*`", "U\\*'", "U\\*^", "U\\*:", "Y\\*'", "\\*(Th", "\\*8",
+
+ "a\\*`", "a\\*'", "a\\*^", "a\\*~", "a\\*:", "a\\*o", "\\*(ae", "c\\*,",
+ "e\\*`", "e\\*'", "e\\*^", "e\\*:", "i\\*`", "i\\*'", "i\\*^", "i\\*:",
+
+ "\\*(d-", "n\\*~", "o\\*`", "o\\*'", "o\\*^", "o\\*~", "o\\*:", undef,
+ "o\\*/" , "u\\*`", "u\\*'", "u\\*^", "u\\*:", "y\\*'", "\\*(th", "y\\*:",
+) if ASCII;
+
+##############################################################################
+# Utility functions
+##############################################################################
+
+# Quote an argument to a macro.
+#
+# $arg - Intended argument to the macro
+#
+# Returns: $arg suitably escaped and quoted
+sub _quote_macro_argument {
+ my ($arg) = @_;
+ if (length($arg) > 0 && $arg !~ m{ [\s\"] }xms) {
+ return $arg;
+ }
+ $arg =~ s{ \" }{""}xmsg;
+ return qq("$arg");
+}
+
+# Returns whether the given encoding needs a call to Encode::encode.
+sub _needs_encode {
+ my ($encoding) = @_;
+ return $encoding ne 'roff' && $encoding ne 'groff';
+}
+
##############################################################################
# Object initialization
##############################################################################
@@ -88,9 +174,6 @@ sub new {
my $class = shift;
my $self = $class->SUPER::new;
- # Tell Pod::Simple not to handle S<> by automatically inserting &nbsp;.
- $self->nbsp_for_S (1);
-
# Tell Pod::Simple to keep whitespace whenever possible.
if (my $preserve_whitespace = $self->can ('preserve_whitespace')) {
$self->$preserve_whitespace (1);
@@ -109,63 +192,84 @@ sub new {
# to put them in our object as hash keys and values. This could cause
# problems if we ever clash with Pod::Simple's own internal class
# variables.
- %$self = (%$self, @_);
+ my %opts = @_;
+ my @opts = map { ("opt_$_", $opts{$_}) } keys %opts;
+ %$self = (%$self, @opts);
+
+ # Pod::Simple uses encoding internally, so we need to store it as
+ # ENCODING. Set the default to UTF-8 if not specified.
+ #
+ # Degrade to the old roff encoding if Encode is not available.
+ #
+ # Suppress the warning message when PERL_CORE is set, indicating this is
+ # running as part of the core Perl build. Perl builds podlators (and all
+ # pure Perl modules) before Encode and other XS modules, so Encode won't
+ # yet be available. Rely on the Perl core build to generate man pages
+ # later, after all the modules are available, so that UTF-8 handling will
+ # be correct.
+ my %options = @_;
+ if (defined $self->{opt_encoding}) {
+ $$self{ENCODING} = $self->{opt_encoding};
+ } elsif (ASCII) {
+ $$self{ENCODING} = 'UTF-8';
+ } else {
+ $$self{ENCODING} = 'groff';
+ }
+ if (_needs_encode($$self{ENCODING}) && !$HAS_ENCODE) {
+ if (!$ENV{PERL_CORE}) {
+ carp ('encoding requested but Encode module not available,'
+ . ' falling back to groff escapes');
+ }
+ $$self{ENCODING} = 'groff';
+ }
# Send errors to stderr if requested.
- if ($$self{stderr} and not $$self{errors}) {
- $$self{errors} = 'stderr';
+ if ($self->{opt_stderr} and not $self->{opt_errors}) {
+ $self->{opt_errors} = 'stderr';
}
- delete $$self{stderr};
+ delete $self->{opt_stderr};
# Validate the errors parameter and act on it.
- if (not defined $$self{errors}) {
- $$self{errors} = 'pod';
- }
- if ($$self{errors} eq 'stderr' || $$self{errors} eq 'die') {
+ $self->{opt_errors} //= 'pod';
+ if ($self->{opt_errors} eq 'stderr' || $self->{opt_errors} eq 'die') {
$self->no_errata_section (1);
$self->complain_stderr (1);
- if ($$self{errors} eq 'die') {
- $$self{complain_die} = 1;
+ if ($self->{opt_errors} eq 'die') {
+ $self->{complain_die} = 1;
}
- } elsif ($$self{errors} eq 'pod') {
+ } elsif ($self->{opt_errors} eq 'pod') {
$self->no_errata_section (0);
$self->complain_stderr (0);
- } elsif ($$self{errors} eq 'none') {
+ } elsif ($self->{opt_errors} eq 'none') {
$self->no_errata_section (1);
$self->no_whining (1);
} else {
- croak (qq(Invalid errors setting: "$$self{errors}"));
- }
- delete $$self{errors};
-
- # Degrade back to non-utf8 if Encode is not available.
- #
- # Suppress the warning message when PERL_CORE is set, indicating this is
- # running as part of the core Perl build. Perl builds podlators (and all
- # pure Perl modules) before Encode and other XS modules, so Encode won't
- # yet be available. Rely on the Perl core build to generate man pages
- # later, after all the modules are available, so that UTF-8 handling will
- # be correct.
- if ($$self{utf8} and !$HAS_ENCODE) {
- if (!$ENV{PERL_CORE}) {
- carp ('utf8 mode requested but Encode module not available,'
- . ' falling back to non-utf8');
- }
- delete $$self{utf8};
+ croak (qq(Invalid errors setting: "$self->{opt_errors}"));
}
+ delete $self->{opt_errors};
# Initialize various other internal constants based on our arguments.
$self->init_fonts;
$self->init_quotes;
$self->init_page;
- # For right now, default to turning on all of the magic.
- $$self{MAGIC_CPP} = 1;
- $$self{MAGIC_EMDASH} = 1;
- $$self{MAGIC_FUNC} = 1;
- $$self{MAGIC_MANREF} = 1;
- $$self{MAGIC_SMALLCAPS} = 1;
- $$self{MAGIC_VARS} = 1;
+ # Configure guesswork based on options.
+ my $guesswork = $self->{opt_guesswork} || q{};
+ my %guesswork = map { $_ => 1 } split(m{,}xms, $guesswork);
+ if (!%guesswork || $guesswork{all}) {
+ #<<<
+ $$self{GUESSWORK} = {
+ functions => 1,
+ manref => 1,
+ quoting => 1,
+ variables => 1,
+ };
+ #>>>
+ } elsif ($guesswork{none}) {
+ $$self{GUESSWORK} = {};
+ } else {
+ $$self{GUESSWORK} = {%guesswork};
+ }
return $self;
}
@@ -182,29 +286,41 @@ sub init_fonts {
# Figure out the fixed-width font. If user-supplied, make sure that they
# are the right length.
- for (qw/fixed fixedbold fixeditalic fixedbolditalic/) {
- my $font = $$self{$_};
- if (defined ($font) && (length ($font) < 1 || length ($font) > 2)) {
- croak qq(roff font should be 1 or 2 chars, not "$font");
+ for (qw(fixed fixedbold fixeditalic fixedbolditalic)) {
+ my $font = $self->{"opt_$_"};
+ if (defined($font) && (length($font) < 1 || length($font) > 2)) {
+ croak(qq(roff font should be 1 or 2 chars, not "$font"));
}
}
# Set the default fonts. We can't be sure portably across different
# implementations what fixed bold-italic may be called (if it's even
# available), so default to just bold.
- $$self{fixed} ||= 'CW';
- $$self{fixedbold} ||= 'CB';
- $$self{fixeditalic} ||= 'CI';
- $$self{fixedbolditalic} ||= 'CB';
+ #<<<
+ $self->{opt_fixed} ||= 'CW';
+ $self->{opt_fixedbold} ||= 'CB';
+ $self->{opt_fixeditalic} ||= 'CI';
+ $self->{opt_fixedbolditalic} ||= 'CB';
+ #>>>
# Set up a table of font escapes. First number is fixed-width, second is
# bold, third is italic.
- $$self{FONTS} = { '000' => '\fR', '001' => '\fI',
- '010' => '\fB', '011' => '\f(BI',
- '100' => toescape ($$self{fixed}),
- '101' => toescape ($$self{fixeditalic}),
- '110' => toescape ($$self{fixedbold}),
- '111' => toescape ($$self{fixedbolditalic}) };
+ $self->{FONTS} = {
+ '000' => '\fR',
+ '001' => '\fI',
+ '010' => '\fB',
+ '011' => '\f(BI',
+ '100' => toescape($self->{opt_fixed}),
+ '101' => toescape($self->{opt_fixeditalic}),
+ '110' => toescape($self->{opt_fixedbold}),
+ '111' => toescape($self->{opt_fixedbolditalic}),
+ };
+
+ # Precalculate a regex that matches all fixed-width fonts, which will be
+ # used later by switchquotes.
+ my @fixedpat = map { quotemeta($self->{FONTS}{$_}) } qw(100 101 110 111);
+ my $fixedpat = join('|', @fixedpat);
+ $self->{FIXEDPAT} = qr{ $fixedpat }xms;
}
# Initialize the quotes that we'll be using for C<> text. This requires some
@@ -215,32 +331,28 @@ sub init_quotes {
my ($self) = (@_);
# Handle the quotes option first, which sets both quotes at once.
- $$self{quotes} ||= '"';
- if ($$self{quotes} eq 'none') {
+ $self->{opt_quotes} ||= '"';
+ if ($self->{opt_quotes} eq 'none') {
$$self{LQUOTE} = $$self{RQUOTE} = '';
- } elsif (length ($$self{quotes}) == 1) {
- $$self{LQUOTE} = $$self{RQUOTE} = $$self{quotes};
- } elsif (length ($$self{quotes}) % 2 == 0) {
- my $length = length ($$self{quotes}) / 2;
- $$self{LQUOTE} = substr ($$self{quotes}, 0, $length);
- $$self{RQUOTE} = substr ($$self{quotes}, $length);
+ } elsif (length ($self->{opt_quotes}) == 1) {
+ $$self{LQUOTE} = $$self{RQUOTE} = $self->{opt_quotes};
+ } elsif (length ($self->{opt_quotes}) % 2 == 0) {
+ my $length = length ($self->{opt_quotes}) / 2;
+ $$self{LQUOTE} = substr ($self->{opt_quotes}, 0, $length);
+ $$self{RQUOTE} = substr ($self->{opt_quotes}, $length);
} else {
- croak(qq(Invalid quote specification "$$self{quotes}"))
+ croak(qq(Invalid quote specification "$self->{opt_quotes}"))
}
# Now handle the lquote and rquote options.
- if (defined $$self{lquote}) {
- $$self{LQUOTE} = $$self{lquote} eq 'none' ? q{} : $$self{lquote};
+ if (defined($self->{opt_lquote})) {
+ $self->{opt_lquote} = q{} if $self->{opt_lquote} eq 'none';
+ $$self{LQUOTE} = $self->{opt_lquote};
}
- if (defined $$self{rquote}) {
- $$self{RQUOTE} = $$self{rquote} eq 'none' ? q{} : $$self{rquote};
+ if (defined $self->{opt_rquote}) {
+ $self->{opt_rquote} = q{} if $self->{opt_rquote} eq 'none';
+ $$self{RQUOTE} = $self->{opt_rquote};
}
-
- # 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/\"/\"\"/;
}
# Initialize the page title information and indentation from our arguments.
@@ -254,17 +366,9 @@ sub init_page {
# Set the defaults for page titles and indentation if the user didn't
# override anything.
- $$self{center} = 'User Contributed Perl Documentation'
- unless defined $$self{center};
- $$self{release} = 'perl v' . $version
- unless defined $$self{release};
- $$self{indent} = 4
- unless defined $$self{indent};
-
- # Double quotes in things that will be quoted.
- for (qw/center release/) {
- $$self{$_} =~ s/\"/\"\"/g if $$self{$_};
- }
+ $self->{opt_center} //= 'User Contributed Perl Documentation';
+ $self->{opt_release} //= 'perl v' . $version;
+ $self->{opt_indent} //= 4;
}
##############################################################################
@@ -289,7 +393,6 @@ sub init_page {
# according to the current formatting instructions as we do.
sub _handle_text {
my ($self, $text) = @_;
- DEBUG > 3 and print "== $text\n";
my $tag = $$self{PENDING}[-1];
$$tag[2] .= $self->format_text ($$tag[1], $text);
}
@@ -308,7 +411,6 @@ sub method_for_element {
# text and nested elements. Otherwise, if start_element is defined, call it.
sub _handle_element_start {
my ($self, $element, $attrs) = @_;
- DEBUG > 3 and print "++ $element (<", join ('> <', %$attrs), ">)\n";
my $method = $self->method_for_element ($element);
# If we have a command handler, we need to accumulate the contents of the
@@ -316,7 +418,6 @@ sub _handle_element_start {
# <Para> and the formatting codes so that IN_NAME isn't still set for the
# first heading after the NAME heading.
if ($self->can ("cmd_$method")) {
- DEBUG > 2 and print "<$element> starts saving a tag\n";
$$self{IN_NAME} = 0 if ($element ne 'Para' && length ($element) > 1);
# How we're going to format embedded text blocks depends on the tag
@@ -328,11 +429,8 @@ sub _handle_element_start {
%{ $FORMATTING{$element} || {} },
};
push (@{ $$self{PENDING} }, [ $attrs, $formatting, '' ]);
- DEBUG > 4 and print "Pending: [", pretty ($$self{PENDING}), "]\n";
} elsif (my $start_method = $self->can ("start_$method")) {
$self->$start_method ($attrs, '');
- } else {
- DEBUG > 2 and print "No $method start method, skipping\n";
}
}
@@ -341,16 +439,12 @@ sub _handle_element_start {
# an end_ method for the element, call that.
sub _handle_element_end {
my ($self, $element) = @_;
- DEBUG > 3 and print "-- $element\n";
my $method = $self->method_for_element ($element);
# If we have a command handler, pull off the pending text and pass it to
# the handler along with the saved attribute hash.
if (my $cmd_method = $self->can ("cmd_$method")) {
- DEBUG > 2 and print "</$element> stops saving a tag\n";
my $tag = pop @{ $$self{PENDING} };
- DEBUG > 4 and print "Popped: [", pretty ($tag), "]\n";
- DEBUG > 4 and print "Pending: [", pretty ($$self{PENDING}), "]\n";
my $text = $self->$cmd_method ($$tag[0], $$tag[2]);
if (defined $text) {
if (@{ $$self{PENDING} } > 1) {
@@ -361,8 +455,6 @@ sub _handle_element_end {
}
} elsif (my $end_method = $self->can ("end_$method")) {
$self->$end_method ();
- } else {
- DEBUG > 2 and print "No $method end method, skipping\n";
}
}
@@ -381,31 +473,40 @@ sub format_text {
my $literal = $$options{literal};
# Cleanup just tidies up a few things, telling *roff that the hyphens are
- # hard, putting a bit of space between consecutive underscores, and
- # escaping backslashes. Be careful not to mangle our character
- # translations by doing this before processing character translation.
+ # hard, putting a bit of space between consecutive underscores, escaping
+ # backslashes, and converting zero-width spaces to zero-width break
+ # points.
if ($cleanup) {
$text =~ s/\\/\\e/g;
$text =~ s/-/\\-/g;
$text =~ s/_(?=_)/_\\|/g;
+ $text =~ s/\x{200B}/\\:/g;
}
- # Normally we do character translation, but we won't even do that in
- # <Data> blocks or if UTF-8 output is desired.
- if ($convert && !$$self{utf8} && ASCII) {
- $text =~ s/([^\x00-\x7F])/$ESCAPES{ord ($1)} || "X"/eg;
+ # Except in <Data> blocks, if groff or roff encoding is requested and
+ # we're in an ASCII environment, do the encoding. For EBCDIC, we just
+ # write what we get and hope for the best. Leave non-breaking spaces and
+ # soft hyphens alone; we'll convert those at the last minute.
+ if ($convert) {
+ if (ASCII) {
+ if ($$self{ENCODING} eq 'groff') {
+ $text =~ s{ ([^\x00-\x7F\xA0\xAD]) }{
+ '\\[u' . sprintf('%04X', ord($1)) . ']'
+ }xmsge;
+ } elsif ($$self{ENCODING} eq 'roff') {
+ $text =~ s/([^\x00-\x7F\xA0\xAD])/$ESCAPES{ord ($1)} || "X"/eg;
+ }
+ }
}
# Ensure that *roff doesn't convert literal quotes to UTF-8 single quotes,
- # but don't mess up our accept escapes.
+ # but don't mess up accent escapes.
if ($literal) {
$text =~ s/(?<!\\\*)\'/\\*\(Aq/g;
$text =~ s/(?<!\\\*)\`/\\\`/g;
}
- # If guesswork is asked for, do that. This involves more substantial
- # formatting based on various heuristics that may only be appropriate for
- # particular documents.
+ # If guesswork is is viable for this block, do that.
if ($guesswork) {
$text = $self->guesswork ($text);
}
@@ -420,31 +521,45 @@ sub quote_literal {
my $self = shift;
local $_ = shift;
+ # If in NAME section, just return an ASCII quoted string to avoid
+ # confusing tools like whatis.
+ if ($$self{IN_NAME}) {
+ return $self->{LQUOTE} . $_ . $self->{RQUOTE};
+ }
+
# A regex that matches the portion of a variable reference that's the
# array or hash index, separated out just because we want to use it in
# several places in the following regex.
- my $index = '(?: \[.*\] | \{.*\} )?';
-
- # If in NAME section, just return an ASCII quoted string to avoid
- # confusing tools like whatis.
- return qq{"$_"} if $$self{IN_NAME};
+ my $index = '(?: \[[^]]+\] | \{[^}]+\} )?';
# Check for things that we don't want to quote, and if we find any of
# them, return the string with just a font change and no quoting.
+ #
+ # Traditionally, Pod::Man has not quoted Perl variables, functions,
+ # numbers, or hex constants, but this is not always desirable. Make this
+ # optional on the quoting guesswork flag.
+ my $extra = qr{(?!)}xms; # never matches
+ if ($$self{GUESSWORK}{quoting}) {
+ $extra = qr{
+ \$+ [\#^]? \S $index # special ($^F, $")
+ | [\$\@%&*]+ \#? [:\'\w]+ $index # plain var or func
+ | [\$\@%&*]* [:\'\w]+
+ (?: \\-> )? \(\s*[^\s,\)]*\s*\) # 0/1-arg func call
+ | (?: [+] || \\- )? ( \d[\d.]* | \.\d+ )
+ (?: [eE] (?: [+] || \\- )? \d+ )? # a number
+ | 0x [a-fA-F\d]+ # a hex constant
+ }xms;
+ }
m{
^\s*
(?:
- ( [\'\`\"] ) .* \1 # already quoted
- | \\\*\(Aq .* \\\*\(Aq # quoted and escaped
- | \\?\` .* ( \' | \\\*\(Aq ) # `quoted'
- | \$+ [\#^]? \S $index # special ($^Foo, $")
- | [\$\@%&*]+ \#? [:\'\w]+ $index # plain var or func
- | [\$\@%&*]* [:\'\w]+ (?: -> )? \(\s*[^\s,]\s*\) # 0/1-arg func call
- | [-+]? ( \d[\d.]* | \.\d+ ) (?: [eE][-+]?\d+ )? # a number
- | 0x [a-fA-F\d]+ # a hex constant
+ ( [\'\"] ) .* \1 # already quoted
+ | \\\*\(Aq .* \\\*\(Aq # quoted and escaped
+ | \\?\` .* ( \' | \\?\` | \\\*\(Aq ) # `quoted' or `quoted`
+ | $extra
)
\s*\z
- }xso and return '\f(FS' . $_ . '\f(FE';
+ }xms and return '\f(FS' . $_ . '\f(FE';
# If we didn't return, go ahead and quote the text.
return '\f(FS\*(C`' . $_ . "\\*(C'\\f(FE";
@@ -453,10 +568,8 @@ sub quote_literal {
# Takes a text block to perform guesswork on. Returns the text block with
# formatting codes added. This is the code that marks up various Perl
# constructs and things commonly used in man pages without requiring the user
-# to add any explicit markup, and is applied to all non-literal text. We're
-# guaranteed that the text we're applying guesswork to does not contain any
-# *roff formatting codes. Note that the inserted font sequences must be
-# treated later with mapfonts or textmapfonts.
+# to add any explicit markup, and is applied to all non-literal text. Note
+# that the inserted font sequences must be treated later with mapfonts.
#
# This method is very fragile, both in the regular expressions it uses and in
# the ordering of those modifications. Care and testing is required when
@@ -464,7 +577,6 @@ sub quote_literal {
sub guesswork {
my $self = shift;
local $_ = shift;
- DEBUG > 5 and print " Guesswork called on [$_]\n";
# By the time we reach this point, all hyphens will be escaped by adding a
# backslash. We want to undo that escaping if they're part of regular
@@ -475,9 +587,9 @@ sub guesswork {
# Note that this is not user-controllable; we pretty much have to do this
# transformation or *roff will mangle the output in unacceptable ways.
s{
- ( (?:\G|^|\s) [\(\"]* [a-zA-Z] ) ( \\- )?
+ ( (?:\G|^|\s|$NBSP) [\(\"]* [a-zA-Z] ) ( \\- )?
( (?: [a-zA-Z\']+ \\-)+ )
- ( [a-zA-Z\']+ ) (?= [\)\".?!,;:]* (?:\s|\Z|\\\ ) )
+ ( [a-zA-Z\']+ ) (?= [\)\".?!,;:]* (?:\s|$NBSP|\Z|\\\ ) )
\b
} {
my ($prefix, $hyphen, $main, $suffix) = ($1, $2, $3, $4);
@@ -486,52 +598,17 @@ sub guesswork {
$prefix . $hyphen . $main . $suffix;
}egx;
- # Translate "--" into a real em-dash if it's used like one. This means
- # that it's either surrounded by whitespace, it follows a regular word, or
- # it occurs between two regular words.
- if ($$self{MAGIC_EMDASH}) {
- s{ (\s) \\-\\- (\s) } { $1 . '\*(--' . $2 }egx;
- s{ (\b[a-zA-Z]+) \\-\\- (\s|\Z|[a-zA-Z]+\b) } { $1 . '\*(--' . $2 }egx;
- }
-
- # Make words in all-caps a little bit smaller; they look better that way.
- # However, we don't want to change Perl code (like @ARGV), nor do we want
- # to fix the MIME in MIME-Version since it looks weird with the
- # full-height V.
- #
- # We change only a string of all caps (2) either at the beginning of the
- # line or following regular punctuation (like quotes) or whitespace (1),
- # and followed by either similar punctuation, an em-dash, or the end of
- # the line (3).
- #
- # Allow the text we're changing to small caps to include double quotes,
- # commas, newlines, and periods as long as it doesn't otherwise interrupt
- # the string of small caps and still fits the criteria. This lets us turn
- # entire warranty disclaimers in man page output into small caps.
- if ($$self{MAGIC_SMALLCAPS}) {
- s{
- ( ^ | [\s\(\"\'\`\[\{<>] | \\[ ] ) # (1)
- ( [A-Z] [A-Z] (?: \s? [/A-Z+:\d_\$&] | \\- | \s? [.,\"] )* ) # (2)
- (?= [\s>\}\]\(\)\'\".?!,;] | \\*\(-- | \\[ ] | $ ) # (3)
- } {
- $1 . '\s-1' . $2 . '\s0'
- }egx;
- }
-
- # Note that from this point forward, we have to adjust for \s-1 and \s-0
- # strings inserted around things that we've made small-caps if later
- # transforms should work on those strings.
-
# Embolden functions in the form func(), including functions that are in
- # all capitals, but don't embolden if there's anything between the parens.
+ # all capitals, but don't embolden if there's anything inside the parens.
# The function must start with an alphabetic character or underscore and
# then consist of word characters or colons.
- if ($$self{MAGIC_FUNC}) {
+ if ($$self{GUESSWORK}{functions}) {
s{
- ( \b | \\s-1 )
- ( [A-Za-z_] ([:\w] | \\s-?[01])+ \(\) )
+ (?<! \\ )
+ \b
+ ( [A-Za-z_] [:\w]+ \(\) )
} {
- $1 . '\f(BS' . $2 . '\f(BE'
+ '\f(BS' . $1 . '\f(BE'
}egx;
}
@@ -542,21 +619,21 @@ sub guesswork {
# configuration file man pages), or colons, and n is a single digit,
# optionally followed by some number of lowercase letters. Note that this
# does not recognize man page references like perl(l) or socket(3SOCKET).
- if ($$self{MAGIC_MANREF}) {
+ if ($$self{GUESSWORK}{manref}) {
s{
- ( \b | \\s-1 )
- (?<! \\ ) # rule out \s0(1)
- ( [A-Za-z_] (?:[.:\w] | \\- | \\s-?[01])+ )
+ \b
+ (?<! \\ ) # rule out \e0(1)
+ ( [A-Za-z_] (?:[.:\w] | \\-)+ )
( \( \d [a-z]* \) )
} {
- $1 . '\f(BS' . $2 . '\f(BE\|' . $3
+ '\f(BS' . $1 . '\f(BE\|' . $2
}egx;
}
# Convert simple Perl variable references to a fixed-width font. Be
# careful not to convert functions, though; there are too many subtleties
# with them to want to perform this transformation.
- if ($$self{MAGIC_VARS}) {
+ if ($$self{GUESSWORK}{variables}) {
s{
( ^ | \s+ )
( [\$\@%] [\w:]+ )
@@ -566,19 +643,7 @@ sub guesswork {
}egx;
}
- # Fix up double quotes. Unfortunately, we miss this transformation if the
- # quoted text contains any code with formatting codes and there's not much
- # we can effectively do about that, which makes it somewhat unclear if
- # this is really a good idea.
- s{ \" ([^\"]+) \" } { '\*(L"' . $1 . '\*(R"' }egx;
-
- # Make C++ into \*(C+, which is a squinched version.
- if ($$self{MAGIC_CPP}) {
- s{ \b C\+\+ } {\\*\(C+}gx;
- }
-
# Done.
- DEBUG > 5 and print " Guesswork returning [$_]\n";
return $_;
}
@@ -592,111 +657,106 @@ sub guesswork {
# the right start and end codes.
#
# We add this level of complexity because the old pod2man didn't get code like
-# B<someI<thing> else> right; after I<> it switched back to normal text rather
-# than bold. We take care of this by using variables that state whether bold,
-# italic, or fixed are turned on as a combined pointer to our current font
-# sequence, and set each to the number of current nestings of start tags for
-# that font.
+# B<< someI<thing> else>> right. After I<> it switched back to normal text
+# rather than bold. We take care of this by using variables that state
+# whether bold, italic, or fixed are turned on as a combined pointer to our
+# current font sequence, and set each to the number of current nestings of
+# start tags for that font.
+#
+# The base font must be either \fP or \fR. \fP changes to the previous font,
+# but only one previous font is kept. 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. Because of this, we prefer to use
+# \fR where possible.
+#
+# Unfortunately, this isn't possible for arguments to heading macros, since
+# there we don't know what the outside level font is. In that case, arrange
+# things so that the outside font is always the "previous" font and end with
+# \fP instead of \fR. Idea from Zack Weinberg.
#
-# \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.
+# This function used to be much simpler outside of macro arguments because it
+# went directly from \fB to \f(CW and relied on \f(CW clearing bold since it
+# wasn't \f(CB. Unfortunately, while this works for mandoc, this is not how
+# groff works; \fBfoo\f(CWbar still prints bar in bold. Therefore, we force
+# the font back to the base font before each font change.
sub mapfonts {
- my ($self, $text) = @_;
+ my ($self, $text, $base) = @_;
+
+ # The closure used to process each font escape, expected to be called from
+ # the right-hand side of an s/// expression.
my ($fixed, $bold, $italic) = (0, 0, 0);
my %magic = (F => \$fixed, B => \$bold, I => \$italic);
my $last = '\fR';
- $text =~ 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;
+ my $process = sub {
+ my ($style, $start_stop) = @_;
+ my $sequence = ($last ne '\fR') ? $base : q{};
+ ${ $magic{$style} } += ($start_stop eq 'S') ? 1 : -1;
+ my $f = $self->{FONTS}{($fixed && 1) . ($bold && 1) . ($italic && 1)};
+ return q{} if ($f eq $last);
+ if ($f ne '\fR') {
+ $sequence .= $f;
}
- >gxe;
- return $text;
-}
+ $last = $f;
+ return $sequence;
+ };
+
+ # Now, do the actual work.
+ $text =~ s{ \\f\((.)(.) }{$process->($1, $2)}xmsge;
+
+ # We can do a bit of cleanup by collapsing sequences like \fR\fB\fR\fI
+ # into just \fI.
+ $text =~ s{ (?: \\fR )? (?: \\f (.|\(..) \\fR )+ }{\\fR}xms;
-# 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, $text) = @_;
- my ($fixed, $bold, $italic) = (0, 0, 0);
- my %magic = (F => \$fixed, B => \$bold, I => \$italic);
- $text =~ s<
- \\f\((.)(.)
- > <
- ${ $magic{$1} } += ($2 eq 'S') ? 1 : -1;
- $$self{FONTS}{ ($fixed && 1) . ($bold && 1) . ($italic && 1) };
- >gxe;
return $text;
}
# 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.
+# quotes and fixed-width text, handle double-quote formatting for it. If
+# there is no fixed-width text, just return the command followed by the
+# argument with proper quoting. If there is fixed-width text, work around a
+# Solaris nroff bug with fixed-width fonts by converting fixed-width to
+# regular fonts (nroff sees no difference).
sub switchquotes {
my ($self, $command, $text, $extra) = @_;
- $text =~ 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.
- # Also separate troff from nroff if there are any fixed-width fonts in use
- # to work around problems with Solaris nroff.
- my $c_is_quote = ($$self{LQUOTE} =~ /\"/) || ($$self{RQUOTE} =~ /\"/);
- my $fixedpat = join '|', @{ $$self{FONTS} }{'100', '101', '110', '111'};
- $fixedpat =~ s/\\/\\\\/g;
- $fixedpat =~ s/\(/\\\(/g;
- if ($text =~ m/\"/ || $text =~ m/$fixedpat/) {
- $text =~ s/\"/\"\"/g;
+
+ # Separate troff from nroff if there are any fixed-width fonts in use to
+ # work around problems with Solaris nroff.
+ if ($text =~ $self->{FIXEDPAT}) {
my $nroff = $text;
my $troff = $text;
- $troff =~ s/\"\"([^\"]*)\"\"/\`\`$1\'\'/g;
- if ($c_is_quote and $text =~ m/\\\*\(C[\'\`]/) {
- $nroff =~ s/\\\*\(C\`/$$self{LQUOTE}/g;
- $nroff =~ s/\\\*\(C\'/$$self{RQUOTE}/g;
- $troff =~ s/\\\*\(C[\'\`]//g;
- }
- $nroff = qq("$nroff") . ($extra ? " $extra" : '');
- $troff = qq("$troff") . ($extra ? " $extra" : '');
# Work around the Solaris nroff bug where \f(CW\fP leaves the font set
# to Roman rather than the actual previous font when used in headings.
# troff output may still be broken, but at least we can fix nroff by
# just switching the font changes to the non-fixed versions.
- my $font_end = "(?:\\f[PR]|\Q$$self{FONTS}{100}\E)";
- $nroff =~ s/\Q$$self{FONTS}{100}\E(.*?)\\f([PR])/$1/g;
- $nroff =~ s/\Q$$self{FONTS}{101}\E(.*?)$font_end/\\fI$1\\fP/g;
- $nroff =~ s/\Q$$self{FONTS}{110}\E(.*?)$font_end/\\fB$1\\fP/g;
- $nroff =~ s/\Q$$self{FONTS}{111}\E(.*?)$font_end/\\f\(BI$1\\fP/g;
+ my $font_end = qr{ (?: \\f[PR] | \Q$self->{FONTS}{100}\E ) }xms;
+ $nroff =~ s{\Q$self->{FONTS}{100}\E(.*?)\\f([PR])}{$1}xmsg;
+ $nroff =~ s{\Q$self->{FONTS}{101}\E}{\\fI}xmsg;
+ $nroff =~ s{\Q$self->{FONTS}{110}\E}{\\fB}xmsg;
+ $nroff =~ s{\Q$self->{FONTS}{111}\E}{\\f\(BI}xmsg;
+
+ # We 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.
+ my $c_is_quote = index("$self->{LQUOTE}$self->{RQUOTE}", qq(\")) != -1;
+ if ($c_is_quote && $text =~ m{ \\[*]\(C[\'\`] }xms) {
+ $nroff =~ s{ \\[*]\(C\` }{$self->{LQUOTE}}xmsg;
+ $nroff =~ s{ \\[*]\(C\' }{$self->{RQUOTE}}xmsg;
+ $troff =~ s{ \\[*]\(C[\'\`] }{}xmsg;
+ }
# Now finally output the command. Bother with .ie only if the nroff
# and troff output aren't the same.
+ $nroff = _quote_macro_argument($nroff) . ($extra ? " $extra" : '');
+ $troff = _quote_macro_argument($troff) . ($extra ? " $extra" : '');
if ($nroff ne $troff) {
return ".ie n $command $nroff\n.el $command $troff\n";
} else {
return "$command $nroff\n";
}
} else {
- $text = qq("$text") . ($extra ? " $extra" : '');
+ $text = _quote_macro_argument($text) . ($extra ? " $extra" : '');
return "$command $text\n";
}
}
@@ -761,10 +821,22 @@ sub outindex {
# Output some text, without any additional changes.
sub output {
my ($self, @text) = @_;
- if ($$self{ENCODE}) {
- print { $$self{output_fh} } Encode::encode ('UTF-8', join ('', @text));
+ my $text = join('', @text);
+ $text =~ s{$NBSP}{\\ }g;
+ $text =~ s{$SHY}{\\%}g;
+
+ if ($$self{ENCODE} && _needs_encode($$self{ENCODING})) {
+ my $check = sub {
+ my ($char) = @_;
+ my $display = '"\x{' . hex($char) . '}"';
+ my $error = "$display does not map to $$self{ENCODING}";
+ $self->whine ($self->line_count(), $error);
+ return Encode::encode ($$self{ENCODING}, chr($char));
+ };
+ my $output = Encode::encode ($$self{ENCODING}, $text, $check);
+ print { $$self{output_fh} } $output;
} else {
- print { $$self{output_fh} } @text;
+ print { $$self{output_fh} } $text;
}
}
@@ -777,21 +849,20 @@ sub output {
sub start_document {
my ($self, $attrs) = @_;
if ($$attrs{contentless} && !$$self{ALWAYS_EMIT_SOMETHING}) {
- DEBUG and print "Document is contentless\n";
$$self{CONTENTLESS} = 1;
} else {
delete $$self{CONTENTLESS};
}
- # When UTF-8 output is set, check whether our output file handle already
- # has a PerlIO encoding layer set. If it does not, we'll need to encode
- # our output before printing it (handled in the output() sub). Wrap the
- # check in an eval to handle versions of Perl without PerlIO.
+ # When an encoding is requested, check whether our output file handle
+ # already has a PerlIO encoding layer set. If it does not, we'll need to
+ # encode our output before printing it (handled in the output() sub).
+ # Wrap the check in an eval to handle versions of Perl without PerlIO.
#
# PerlIO::get_layers still requires its argument be a glob, so coerce the
# file handle to a glob.
$$self{ENCODE} = 0;
- if ($$self{utf8}) {
+ if ($$self{ENCODING}) {
$$self{ENCODE} = 1;
eval {
my @options = (output => 1, details => 1);
@@ -806,15 +877,15 @@ sub start_document {
# document was content-free.
if (!$$self{CONTENTLESS}) {
my ($name, $section);
- if (defined $$self{name}) {
- $name = $$self{name};
- $section = $$self{section} || 1;
+ if (defined $self->{opt_name}) {
+ $name = $self->{opt_name};
+ $section = $self->{opt_section} || 1;
} else {
($name, $section) = $self->devise_title;
}
- my $date = defined($$self{date}) ? $$self{date} : $self->devise_date;
+ my $date = $self->{opt_date} // $self->devise_date();
$self->preamble ($name, $section, $date)
- unless $self->bare_output or DEBUG > 9;
+ unless $self->bare_output;
}
# Initialize a few per-document variables.
@@ -839,7 +910,6 @@ sub end_document {
}
return if $self->bare_output;
return if ($$self{CONTENTLESS} && !$$self{ALWAYS_EMIT_SOMETHING});
- $self->output (q(.\" [End document]) . "\n") if DEBUG;
}
# Try to figure out the name and section from the file name and return them as
@@ -848,8 +918,8 @@ sub end_document {
sub devise_title {
my ($self) = @_;
my $name = $self->source_filename || '';
- my $section = $$self{section} || 1;
- $section = 3 if (!$$self{section} && $name =~ /\.pm\z/i);
+ my $section = $self->{opt_section} || 1;
+ $section = 3 if (!$self->{opt_section} && $name =~ /\.pm\z/i);
$name =~ s/\.p(od|[lm])\z//i;
# If Pod::Parser gave us an IO::File reference as the source file name,
@@ -981,34 +1051,53 @@ sub devise_date {
# module, but this order is correct for both Solaris and Linux.
sub preamble {
my ($self, $name, $section, $date) = @_;
- my $preamble = $self->preamble_template (!$$self{utf8});
+ my $preamble = $self->preamble_template();
- # Build the index line and make sure that it will be syntactically valid.
- my $index = "$name $section";
- $index =~ s/\"/\"\"/g;
-
- # If name or section contain spaces, quote them (section really never
- # should, but we may as well be cautious).
- for ($name, $section) {
- if (/\s/) {
- s/\"/\"\"/g;
- $_ = '"' . $_ . '"';
+ # groff's preconv script will use this line to correctly determine the
+ # input encoding if the encoding is one of the ones it recognizes. It
+ # must be the first or second line.
+ #
+ # If the output encoding is some version of Unicode, we could also add a
+ # Unicode Byte Order Mark to the start of the file, but the BOM is now
+ # deprecated and I am concerned that may break a *roff implementation that
+ # might otherwise cope with Unicode. Revisit this if someone files a bug
+ # report about it.
+ if (_needs_encode($$self{ENCODING})) {
+ my $normalized = lc($$self{ENCODING});
+ $normalized =~ s{-}{}g;
+ my $coding = $ENCODINGS{$normalized} || lc($$self{ENCODING});
+ if ($coding ne 'us-ascii') {
+ $self->output(qq{.\\\" -*- mode: troff; coding: $coding -*-\n});
}
}
- # Double quotes in date, since it will be quoted.
- $date =~ s/\"/\"\"/g;
-
- # Substitute into the preamble the configuration options.
- $preamble =~ s/\@CFONT\@/$$self{fixed}/;
- $preamble =~ s/\@LQUOTE\@/$$self{LQUOTE}/;
- $preamble =~ s/\@RQUOTE\@/$$self{RQUOTE}/;
- chomp $preamble;
+ # Substitute into the preamble the configuration options. Because it's
+ # used as the argument to defining a string, any leading double quote (but
+ # no other double quotes) in LQUOTE and RQUOTE has to be doubled.
+ $preamble =~ s{ [@] CFONT [@] }{$self->{opt_fixed}}xms;
+ my $lquote = $self->{LQUOTE};
+ my $rquote = $self->{RQUOTE};
+ $lquote =~ s{ \A \" }{""}xms;
+ $rquote =~ s{ \A \" }{""}xms;
+ $preamble =~ s{ [@] LQUOTE [@] }{$lquote}xms;
+ $preamble =~ s{ [@] RQUOTE [@] }{$rquote}xms;
+ chomp($preamble);
# Get the version information.
- my $version = $self->version_report;
+ my $version = $self->version_report();
- # Finally output everything.
+ # Build the index line and make sure that it will be syntactically valid.
+ my $index = _quote_macro_argument("$name $section");
+
+ # Quote the arguments to the .TH macro. (Section should never require
+ # this, but we may as well be cautious.)
+ $name = _quote_macro_argument($name);
+ $section = _quote_macro_argument($section);
+ $date = _quote_macro_argument($date);
+ my $center = _quote_macro_argument($self->{opt_center});
+ my $release = _quote_macro_argument($self->{opt_release});
+
+ # Output the majority of the preamble.
$self->output (<<"----END OF HEADER----");
.\\" Automatically generated by $version
.\\"
@@ -1017,14 +1106,19 @@ sub preamble {
$preamble
.\\" ========================================================================
.\\"
-.IX Title "$index"
-.TH $name $section "$date" "$$self{release}" "$$self{center}"
+.IX Title $index
+.TH $name $section $date $release $center
.\\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\\" way too many mistakes in technical documents.
.if n .ad l
.nh
----END OF HEADER----
- $self->output (".\\\" [End of preamble]\n") if DEBUG;
+
+ # If the language was specified, output the language configuration.
+ if ($self->{opt_language}) {
+ $self->output(".mso $self->{opt_language}.tmac\n");
+ $self->output(".hla $self->{opt_language}\n");
+ }
}
##############################################################################
@@ -1049,11 +1143,6 @@ sub cmd_para {
$$self{SHIFTWAIT} = 0;
}
- # Add the line number for debugging, but not in the NAME section just in
- # case the comment would confuse apropos.
- $self->output (".\\\" [At source line $line]\n")
- if defined ($line) && DEBUG && !$$self{IN_NAME};
-
# Force exactly one newline at the end and strip unwanted trailing
# whitespace at the end, but leave "\ " backslashed space from an S< > at
# the end of a line. Reverse the text first, to avoid having to scan the
@@ -1063,8 +1152,8 @@ sub cmd_para {
$text = reverse $text;
# Output the paragraph.
- $self->output ($self->protect ($self->textmapfonts ($text)));
- $self->outindex;
+ $self->output($self->protect($self->mapfonts($text, '\fR')));
+ $self->outindex();
$$self{NEEDSPACE} = 1;
return '';
}
@@ -1076,45 +1165,44 @@ sub cmd_verbatim {
my ($self, $attrs, $text) = @_;
# Ignore an empty verbatim paragraph.
- return unless $text =~ /\S/;
+ return if $text !~ m{ \S }xms;
# Force exactly one newline at the end and strip unwanted trailing
- # whitespace at the end. Reverse the text first, to avoid having to scan
- # the entire paragraph.
- $text = reverse $text;
- $text =~ s/\A\s*/\n/;
- $text = reverse $text;
+ # whitespace at the end.
+ $text =~ s{ \s* \z }{\n}xms;
# Get a count of the number of lines before the first blank line, which
# we'll pass to .Vb as its parameter. This tells *roff to keep that many
# lines together. We don't want to tell *roff to keep huge blocks
# together.
- my @lines = split (/\n/, $text);
+ my @lines = split (m{ \n }xms, $text);
my $unbroken = 0;
- for (@lines) {
- last if /^\s*$/;
+ for my $line (@lines) {
+ last if $line =~ m{ \A \s* \z }xms;
$unbroken++;
}
- $unbroken = 10 if ($unbroken > 12 && !$$self{MAGIC_VNOPAGEBREAK_LIMIT});
+ if ($unbroken > 12) {
+ $unbroken = 10;
+ }
- # Prepend a null token to each line.
- $text =~ s/^/\\&/gm;
+ # Prepend a null token to each line to preserve indentation.
+ $text =~ s{ ^ }{\\&}xmsg;
# Output the results.
- $self->makespace;
- $self->output (".Vb $unbroken\n$text.Ve\n");
+ $self->makespace();
+ $self->output(".Vb $unbroken\n$text.Ve\n");
$$self{NEEDSPACE} = 1;
- return '';
+ return q{};
}
# Handle literal text (produced by =for and similar constructs). Just output
# it with the minimum of changes.
sub cmd_data {
my ($self, $attrs, $text) = @_;
- $text =~ s/^\n+//;
- $text =~ s/\n{0,2}$/\n/;
- $self->output ($text);
- return '';
+ $text =~ s{ \A \n+ }{}xms;
+ $text =~ s{ \n{0,2} \z }{\n}xms;
+ $self->output($text);
+ return q{};
}
##############################################################################
@@ -1136,9 +1224,6 @@ sub heading_common {
$self->output (".PD\n");
}
- # Output the current source line.
- $self->output ( ".\\\" [At source line $line]\n" )
- if defined ($line) && DEBUG;
return $text;
}
@@ -1151,7 +1236,7 @@ sub cmd_head1 {
$text =~ s/\\s-?\d//g;
$text = $self->heading_common ($text, $$attrs{start_line});
my $isname = ($text eq 'NAME' || $text =~ /\(NAME\)/);
- $self->output ($self->switchquotes ('.SH', $self->mapfonts ($text)));
+ $self->output($self->switchquotes('.SH', $self->mapfonts($text, '\fP')));
$self->outindex ('Header', $text) unless $isname;
$$self{NEEDSPACE} = 0;
$$self{IN_NAME} = $isname;
@@ -1162,7 +1247,7 @@ sub cmd_head1 {
sub cmd_head2 {
my ($self, $attrs, $text) = @_;
$text = $self->heading_common ($text, $$attrs{start_line});
- $self->output ($self->switchquotes ('.SS', $self->mapfonts ($text)));
+ $self->output($self->switchquotes('.SS', $self->mapfonts($text, '\fP')));
$self->outindex ('Subsection', $text);
$$self{NEEDSPACE} = 0;
return '';
@@ -1174,7 +1259,7 @@ sub cmd_head3 {
my ($self, $attrs, $text) = @_;
$text = $self->heading_common ($text, $$attrs{start_line});
$self->makespace;
- $self->output ($self->textmapfonts ('\f(IS' . $text . '\f(IE') . "\n");
+ $self->output($self->mapfonts('\f(IS' . $text . '\f(IE', '\fR') . "\n");
$self->outindex ('Subsection', $text);
$$self{NEEDSPACE} = 1;
return '';
@@ -1186,7 +1271,7 @@ sub cmd_head4 {
my ($self, $attrs, $text) = @_;
$text = $self->heading_common ($text, $$attrs{start_line});
$self->makespace;
- $self->output ($self->textmapfonts ($text) . "\n");
+ $self->output($self->mapfonts($text, '\fR') . "\n");
$self->outindex ('Subsection', $text);
$$self{NEEDSPACE} = 1;
return '';
@@ -1203,6 +1288,13 @@ sub cmd_i { return $_[0]->{IN_NAME} ? $_[2] : '\f(IS' . $_[2] . '\f(IE' }
sub cmd_f { return $_[0]->{IN_NAME} ? $_[2] : '\f(IS' . $_[2] . '\f(IE' }
sub cmd_c { return $_[0]->quote_literal ($_[2]) }
+# Convert all internal whitespace to $NBSP.
+sub cmd_s {
+ my ($self, $attrs, $text) = @_;
+ $text =~ s{ \s }{$NBSP}xmsg;
+ return $text;
+}
+
# Index entries are just added to the pending entries.
sub cmd_x {
my ($self, $attrs, $text) = @_;
@@ -1224,7 +1316,7 @@ sub cmd_l {
}
if (not defined ($to) or $to eq $text) {
return "<$text>";
- } elsif ($$self{nourls}) {
+ } elsif ($self->{opt_nourls}) {
return $text;
} else {
return "$text <$$attrs{to}>";
@@ -1245,12 +1337,10 @@ sub over_common_start {
my ($self, $type, $attrs) = @_;
my $line = $$attrs{start_line};
my $indent = $$attrs{indent};
- DEBUG > 3 and print " Starting =over $type (line $line, indent ",
- ($indent || '?'), "\n";
# Find the indentation level.
unless (defined ($indent) && $indent =~ /^[-+]?\d{1,4}\s*$/) {
- $indent = $$self{indent};
+ $indent = $self->{opt_indent};
}
# If we've gotten multiple indentations in a row, we need to emit the
@@ -1279,7 +1369,6 @@ sub over_common_start {
# .RE and then a new .RS to unconfuse *roff.
sub over_common_end {
my ($self) = @_;
- DEBUG > 3 and print " Ending =over\n";
$$self{INDENT} = pop @{ $$self{INDENTS} };
pop @{ $$self{ITEMTYPES} };
@@ -1318,7 +1407,6 @@ sub end_over_block { $_[0]->over_common_end }
sub item_common {
my ($self, $type, $attrs, $text) = @_;
my $line = $$attrs{start_line};
- DEBUG > 3 and print " $type item (line $line): $text\n";
# Clean up the text. We want to end up with two variables, one ($text)
# which contains any body text after taking out the item portion, and
@@ -1350,8 +1438,8 @@ sub item_common {
$self->output (".PD 0\n") if ($$self{ITEMS} == 1);
# Now, output the item tag itself.
- $item = $self->textmapfonts ($item);
- $self->output ($self->switchquotes ('.IP', $item, $$self{INDENT}));
+ $item = $self->mapfonts($item, '\fR');
+ $self->output($self->switchquotes('.IP', $item, $$self{INDENT}));
$$self{NEEDSPACE} = 0;
$$self{ITEMS}++;
$$self{SHIFTWAIT} = 0;
@@ -1360,7 +1448,7 @@ sub item_common {
if ($text) {
$text =~ s/\s*$/\n/;
$self->makespace;
- $self->output ($self->protect ($self->textmapfonts ($text)));
+ $self->output($self->protect($self->mapfonts($text, '\fR')));
$$self{NEEDSPACE} = 1;
}
$self->outindex ($index ? ('Item', $index) : ());
@@ -1448,48 +1536,15 @@ sub parse_string_document {
}
##############################################################################
-# Translation tables
-##############################################################################
-
-# The following table is adapted 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. We really want to do something better than
-# this when *roff actually supports other character sets itself, since these
-# results are pretty poor.
-#
-# This only works in an ASCII world. What to do in a non-ASCII world is very
-# unclear -- hopefully we can assume UTF-8 and just leave well enough alone.
-@ESCAPES{0xA0 .. 0xFF} = (
- "\\ ", undef, undef, undef, undef, undef, undef, undef,
- undef, undef, undef, undef, undef, "\\%", undef, undef,
-
- undef, undef, undef, undef, undef, undef, undef, undef,
- undef, undef, undef, undef, undef, undef, undef, undef,
-
- "A\\*`", "A\\*'", "A\\*^", "A\\*~", "A\\*:", "A\\*o", "\\*(Ae", "C\\*,",
- "E\\*`", "E\\*'", "E\\*^", "E\\*:", "I\\*`", "I\\*'", "I\\*^", "I\\*:",
-
- "\\*(D-", "N\\*~", "O\\*`", "O\\*'", "O\\*^", "O\\*~", "O\\*:", undef,
- "O\\*/", "U\\*`", "U\\*'", "U\\*^", "U\\*:", "Y\\*'", "\\*(Th", "\\*8",
-
- "a\\*`", "a\\*'", "a\\*^", "a\\*~", "a\\*:", "a\\*o", "\\*(ae", "c\\*,",
- "e\\*`", "e\\*'", "e\\*^", "e\\*:", "i\\*`", "i\\*'", "i\\*^", "i\\*:",
-
- "\\*(d-", "n\\*~", "o\\*`", "o\\*'", "o\\*^", "o\\*~", "o\\*:", undef,
- "o\\*/" , "u\\*`", "u\\*'", "u\\*^", "u\\*:", "y\\*'", "\\*(th", "y\\*:",
-) if ASCII;
-
-##############################################################################
# Premable
##############################################################################
-# The following is the static preamble which starts all *roff output we
-# generate. Most is static except for the font to use as a fixed-width font,
-# which is designed by @CFONT@, and the left and right quotes to use for C<>
-# text, designated by @LQOUTE@ and @RQUOTE@. However, the second part, which
-# defines the accent marks, is only used if $escapes is set to true.
+# The preamble which starts all *roff output we generate. Most is static
+# except for the font to use as a fixed-width font (designed by @CFONT@), and
+# the left and right quotes to use for C<> text (designated by @LQOUTE@ and
+# @RQUOTE@). Accent marks are only defined if the output encoding is roff.
sub preamble_template {
- my ($self, $accents) = @_;
+ my ($self) = @_;
my $preamble = <<'----END OF PREAMBLE----';
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
@@ -1504,29 +1559,12 @@ sub preamble_template {
.ft R
.fi
..
-.\" Set up some character translations and predefined strings. \*(-- will
-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
-.\" double quote, and \*(R" will give a right double quote. \*(C+ will
-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
-.\" nothing in troff, for use with C<>.
-.tr \(*W-
-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
-. ds -- \(*W-
-. ds PI pi
-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
-. ds L" ""
-. ds R" ""
. ds C` @LQUOTE@
. ds C' @RQUOTE@
'br\}
.el\{\
-. ds -- \|\(em\|
-. ds PI \(*p
-. ds L" ``
-. ds R" ''
. ds C`
. ds C'
'br\}
@@ -1560,7 +1598,7 @@ sub preamble_template {
----END OF PREAMBLE----
#'# for cperl-mode
- if ($accents) {
+ if ($$self{ENCODING} eq 'roff') {
$preamble .= <<'----END OF PREAMBLE----'
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
@@ -1590,7 +1628,7 @@ sub preamble_template {
. ds /
.\}
.if t \{\
-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h'|\\n:u'
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
@@ -1637,10 +1675,13 @@ sub preamble_template {
1;
__END__
+=encoding UTF-8
+
=for stopwords
en em ALLCAPS teeny fixedbold fixeditalic fixedbolditalic stderr utf8 UTF-8
Allbery Sean Burke Ossanna Solaris formatters troff uppercased Christiansen
-nourls parsers Kernighan lquote rquote
+nourls parsers Kernighan lquote rquote unrepresentable mandoc NetBSD PostScript
+SMP macOS EBCDIC fallbacks manref reflowed reflowing FH overridable
=head1 NAME
@@ -1666,100 +1707,197 @@ using L<nroff(1)>, normally via L<man(1)>, or printing using L<troff(1)>.
It is conventionally invoked using the driver script B<pod2man>, but it can
also be used directly.
-As a derived class from Pod::Simple, Pod::Man supports the same methods and
-interfaces. See L<Pod::Simple> for all the details.
-
-new() can take options, in the form of key/value pairs that control the
-behavior of the parser. See below for details.
-
-If no options are given, Pod::Man uses the name of the input file with any
-trailing C<.pod>, C<.pm>, or C<.pl> stripped as the man page title, to
-section 1 unless the file ended in C<.pm> in which case it defaults to
-section 3, to a centered title of "User Contributed Perl Documentation", to
-a centered footer of the Perl version it is run with, and to a left-hand
-footer of the modification date of its input (or the current date if given
-C<STDIN> for input).
-
-Pod::Man assumes that your *roff formatters have a fixed-width font named
-C<CW>. If yours is called something else (like C<CR>), use the C<fixed>
-option to specify it. This generally only matters for troff output for
-printing. Similarly, you can set the fonts used for bold, italic, and
-bold italic fixed-width output.
-
-Besides the obvious pod conversions, Pod::Man also takes care of
-formatting func(), func(3), and simple variable references like $foo or
-@bar so you don't have to use code escapes for them; complex expressions
-like C<$fred{'stuff'}> will still need to be escaped, though. It also
-translates dashes that aren't used as hyphens into en dashes, makes long
-dashes--like this--into proper em dashes, fixes "paired quotes," makes C++
-look right, puts a little space between double underscores, makes ALLCAPS
-a teeny bit smaller in B<troff>, and escapes stuff that *roff treats as
-special so that you don't have to.
-
-The recognized options to new() are as follows. All options take a single
-argument.
+By default (on non-EBCDIC systems), Pod::Man outputs UTF-8. Its output should
+work with the B<man> program on systems that use B<groff> (most Linux
+distributions) or B<mandoc> (most BSD variants), but may result in mangled
+output on older UNIX systems. To choose a different, possibly more
+backward-compatible output mangling on such systems, set the C<encoding>
+option to C<roff> (the default in earlier Pod::Man versions). See the
+C<encoding> option and L</ENCODING> for more details.
+
+See L</COMPATIBILTY> for the versions of Pod::Man with significant
+backward-incompatible changes (other than constructor options, whose versions
+are documented below), and the versions of Perl that included them.
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item new(ARGS)
+
+Create a new Pod::Man object. ARGS should be a list of key/value pairs, where
+the keys are chosen from the following. Each option is annotated with the
+version of Pod::Man in which that option was added with its current meaning.
=over 4
=item center
-Sets the centered page header for the C<.TH> macro. The default, if this
-option is not specified, is "User Contributed Perl Documentation".
+[1.00] Sets the centered page header for the C<.TH> macro. The default, if
+this option is not specified, is C<User Contributed Perl Documentation>.
=item date
-Sets the left-hand footer for the C<.TH> macro. If this option is not set,
-the contents of the environment variable POD_MAN_DATE, if set, will be used.
-Failing that, the value of SOURCE_DATE_EPOCH, the modification date of the
-input file, or the current time if stat() can't find that file (which will be
-the case if the input is from C<STDIN>) will be used. If obtained from the
-file modification date or the current time, the date will be formatted as
-C<YYYY-MM-DD> and will be based on UTC (so that the output will be
-reproducible regardless of local time zone).
+[4.00] Sets the left-hand footer for the C<.TH> macro. If this option is not
+set, the contents of the environment variable POD_MAN_DATE, if set, will be
+used. Failing that, the value of SOURCE_DATE_EPOCH, the modification date of
+the input file, or the current time if stat() can't find that file (which will
+be the case if the input is from C<STDIN>) will be used. If taken from any
+source other than POD_MAN_DATE (which is used verbatim), the date will be
+formatted as C<YYYY-MM-DD> and will be based on UTC (so that the output will
+be reproducible regardless of local time zone).
+
+=item encoding
+
+[5.00] Specifies the encoding of the output. The value must be an encoding
+recognized by the L<Encode> module (see L<Encode::Supported>), or the special
+values C<roff> or C<groff>. The default on non-EBCDIC systems is UTF-8.
+
+If the output contains characters that cannot be represented in this encoding,
+that is an error that will be reported as configured by the C<errors> option.
+If error handling is other than C<die>, the unrepresentable character will be
+replaced with the Encode substitution character (normally C<?>).
+
+If the C<encoding> option is set to the special value C<groff> (the default on
+EBCDIC systems), or if the Encode module is not available and the encoding is
+set to anything other than C<roff>, Pod::Man will translate all non-ASCII
+characters to C<\[uNNNN]> Unicode escapes. These are not traditionally part
+of the *roff language, but are supported by B<groff> and B<mandoc> and thus by
+the majority of manual page processors in use today.
+
+If the C<encoding> option is set to the special value C<roff>, Pod::Man will
+do its historic transformation of (some) ISO 8859-1 characters into *roff
+escapes that may be adequate in troff and may be readable (if ugly) in nroff.
+This was the default behavior of versions of Pod::Man before 5.00. With this
+encoding, all other non-ASCII characters will be replaced with C<X>. It may
+be required for very old troff and nroff implementations that do not support
+UTF-8, but its representation of any non-ASCII character is very poor and
+often specific to European languages.
+
+If the output file handle has a PerlIO encoding layer set, setting C<encoding>
+to anything other than C<groff> or C<roff> will be ignored and no encoding
+will be done by Pod::Man. It will instead rely on the encoding layer to make
+whatever output encoding transformations are desired.
+
+WARNING: The input encoding of the POD source is independent from the output
+encoding, and setting this option does not affect the interpretation of the
+POD input. Unless your POD source is US-ASCII, its encoding should be
+declared with the C<=encoding> command in the source. If this is not done,
+Pod::Simple will will attempt to guess the encoding and may be successful if
+it's Latin-1 or UTF-8, but it will produce warnings. See L<perlpod(1)> for
+more information.
=item errors
-How to report errors. C<die> says to throw an exception on any POD
-formatting error. C<stderr> says to report errors on standard error, but
-not to throw an exception. C<pod> says to include a POD ERRORS section
-in the resulting documentation summarizing the errors. C<none> ignores
-POD errors entirely, as much as possible.
+[2.27] How to report errors. C<die> says to throw an exception on any POD
+formatting error. C<stderr> says to report errors on standard error, but not
+to throw an exception. C<pod> says to include a POD ERRORS section in the
+resulting documentation summarizing the errors. C<none> ignores POD errors
+entirely, as much as possible.
The default is C<pod>.
=item fixed
-The fixed-width font to use for verbatim text and code. Defaults to
-C<CW>. Some systems may want C<CR> instead. Only matters for B<troff>
-output.
+[1.00] The fixed-width font to use for verbatim text and code. Defaults to
+C<CW>. Some systems prefer C<CR> instead. Only matters for B<troff> output.
=item fixedbold
-Bold version of the fixed-width font. Defaults to C<CB>. Only matters
+[1.00] Bold version of the fixed-width font. Defaults to C<CB>. Only matters
for B<troff> output.
=item fixeditalic
-Italic version of the fixed-width font (actually, something of a misnomer,
-since most fixed-width fonts only have an oblique version, not an italic
-version). Defaults to C<CI>. Only matters for B<troff> output.
+[1.00] Italic version of the fixed-width font (something of a misnomer, since
+most fixed-width fonts only have an oblique version, not an italic version).
+Defaults to C<CI>. Only matters for B<troff> output.
=item fixedbolditalic
-Bold italic (probably actually oblique) version of the fixed-width font.
-Pod::Man doesn't assume you have this, and defaults to C<CB>. Some
-systems (such as Solaris) have this font available as C<CX>. Only matters
-for B<troff> output.
+[1.00] Bold italic (in theory, probably oblique in practice) version of the
+fixed-width font. Pod::Man doesn't assume you have this, and defaults to
+C<CB>. Some systems (such as Solaris) have this font available as C<CX>.
+Only matters for B<troff> output.
+
+=item guesswork
+
+[5.00] By default, Pod::Man applies some default formatting rules based on
+guesswork and regular expressions that are intended to make writing Perl
+documentation easier and require less explicit markup. These rules may not
+always be appropriate, particularly for documentation that isn't about Perl.
+This option allows turning all or some of it off.
+
+The special value C<all> enables all guesswork. This is also the default for
+backward compatibility reasons. The special value C<none> disables all
+guesswork. Otherwise, the value of this option should be a comma-separated
+list of one or more of the following keywords:
+
+=over 4
+
+=item functions
+
+Convert function references like C<foo()> to bold even if they have no markup.
+The function name accepts valid Perl characters for function names (including
+C<:>), and the trailing parentheses must be present and empty.
+
+=item manref
+
+Make the first part (before the parentheses) of manual page references like
+C<foo(1)> bold even if they have no markup. The section must be a single
+number optionally followed by lowercase letters.
+
+=item quoting
+
+If no guesswork is enabled, any text enclosed in CZ<><> is surrounded by
+double quotes in nroff (terminal) output unless the contents are already
+quoted. When this guesswork is enabled, quote marks will also be suppressed
+for Perl variables, function names, function calls, numbers, and hex
+constants.
+
+=item variables
+
+Convert Perl variable names to a fixed-width font even if they have no markup.
+This transformation will only be apparent in troff output, or some other
+output format (unlike nroff terminal output) that supports fixed-width fonts.
+
+=back
+
+Any unknown guesswork name is silently ignored (for potential future
+compatibility), so be careful about spelling.
+
+=item language
+
+[5.00] Add commands telling B<groff> that the input file is in the given
+language. The value of this setting must be a language abbreviation for which
+B<groff> provides supplemental configuration, such as C<ja> (for Japanese) or
+C<zh> (for Chinese).
+
+Specifically, this adds:
+
+ .mso <language>.tmac
+ .hla <language>
+
+to the start of the file, which configure correct line breaking for the
+specified language. Without these commands, groff may not know how to add
+proper line breaks for Chinese and Japanese text if the manual page is
+installed into the normal manual page directory, such as F</usr/share/man>.
+
+On many systems, this will be done automatically if the manual page is
+installed into a language-specific manual page directory, such as
+F</usr/share/man/zh_CN>. In that case, this option is not required.
+
+Unfortunately, the commands added with this option are specific to B<groff>
+and will not work with other B<troff> and B<nroff> implementations.
=item lquote
=item rquote
-Sets the quote marks used to surround CE<lt>> text. C<lquote> sets the
-left quote mark and C<rquote> sets the right quote mark. Either may also
-be set to the special value C<none>, in which case no quote mark is added
-on that side of CE<lt>> text (but the font is still changed for troff
-output).
+[4.08] Sets the quote marks used to surround CE<lt>> text. C<lquote> sets the
+left quote mark and C<rquote> sets the right quote mark. Either may also be
+set to the special value C<none>, in which case no quote mark is added on that
+side of CE<lt>> text (but the font is still changed for troff output).
Also see the C<quotes> option, which can be used to set both quotes at once.
If both C<quotes> and one of the other options is set, C<lquote> or C<rquote>
@@ -1767,21 +1905,21 @@ overrides C<quotes>.
=item name
-Set the name of the manual page for the C<.TH> macro. Without this
-option, the manual name is set to the uppercased base name of the file
-being converted unless the manual section is 3, in which case the path is
-parsed to see if it is a Perl module path. If it is, a path like
-C<.../lib/Pod/Man.pm> is converted into a name like C<Pod::Man>. This
-option, if given, overrides any automatic determination of the name.
+[4.08] Set the name of the manual page for the C<.TH> macro. Without this
+option, the manual name is set to the uppercased base name of the file being
+converted unless the manual section is 3, in which case the path is parsed to
+see if it is a Perl module path. If it is, a path like C<.../lib/Pod/Man.pm>
+is converted into a name like C<Pod::Man>. This option, if given, overrides
+any automatic determination of the name.
If generating a manual page from standard input, the name will be set to
-C<STDIN> if this option is not provided. Providing this option is strongly
-recommended to set a meaningful manual page name.
+C<STDIN> if this option is not provided. In this case, providing this option
+is strongly recommended to set a meaningful manual page name.
=item nourls
-Normally, LZ<><> formatting codes with a URL but anchor text are formatted
-to show both the anchor text and the URL. In other words:
+[2.27] Normally, LZ<><> formatting codes with a URL but anchor text are
+formatted to show both the anchor text and the URL. In other words:
L<foo|http://example.com/>
@@ -1796,10 +1934,10 @@ important.
=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. Otherwise,
-it is split in half, and the first half of the string is used as the left
-quote and the second is used as the right quote.
+[4.00] 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. Otherwise, it
+is split in half, and the first half of the string is used as the left quote
+and the second is used 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
@@ -1811,82 +1949,258 @@ options is set, C<lquote> or C<rquote> overrides C<quotes>.
=item release
-Set the centered footer for the C<.TH> macro. By default, this is set to
-the version of Perl you run Pod::Man under. Setting this to the empty
-string will cause some *roff implementations to use the system default
-value.
+[1.00] Set the centered footer for the C<.TH> macro. By default, this is set
+to the version of Perl you run Pod::Man under. Setting this to the empty
+string will cause some *roff implementations to use the system default value.
-Note that some system C<an> macro sets assume that the centered footer
-will be a modification date and will prepend something like "Last
-modified: ". If this is the case for your target system, you may want to
-set C<release> to the last modified date and C<date> to the version
-number.
+Note that some system C<an> macro sets assume that the centered footer will be
+a modification date and will prepend something like C<Last modified: >. If
+this is the case for your target system, you may want to set C<release> to the
+last modified date and C<date> to the version number.
=item section
-Set the section for the C<.TH> macro. The standard section numbering
-convention is to use 1 for user commands, 2 for system calls, 3 for
-functions, 4 for devices, 5 for file formats, 6 for games, 7 for
-miscellaneous information, and 8 for administrator commands. There is a lot
-of variation here, however; some systems (like Solaris) use 4 for file
-formats, 5 for miscellaneous information, and 7 for devices. Still others
-use 1m instead of 8, or some mix of both. About the only section numbers
-that are reliably consistent are 1, 2, and 3.
+[1.00] Set the section for the C<.TH> macro. The standard section numbering
+convention is to use 1 for user commands, 2 for system calls, 3 for functions,
+4 for devices, 5 for file formats, 6 for games, 7 for miscellaneous
+information, and 8 for administrator commands. There is a lot of variation
+here, however; some systems (like Solaris) use 4 for file formats, 5 for
+miscellaneous information, and 7 for devices. Still others use 1m instead of
+8, or some mix of both. About the only section numbers that are reliably
+consistent are 1, 2, and 3.
By default, section 1 will be used unless the file ends in C<.pm> in which
case section 3 will be selected.
=item stderr
-Send error messages about invalid POD to standard error instead of
-appending a POD ERRORS section to the generated *roff output. This is
-equivalent to setting C<errors> to C<stderr> if C<errors> is not already
-set. It is supported for backward compatibility.
+[2.19] If set to a true value, send error messages about invalid POD to
+standard error instead of appending a POD ERRORS section to the generated
+*roff output. This is equivalent to setting C<errors> to C<stderr> if
+C<errors> is not already set.
+
+This option is for backward compatibility with Pod::Man versions that did not
+support C<errors>. Normally, the C<errors> option should be used instead.
=item utf8
-By default, Pod::Man produces the most conservative possible *roff output
-to try to ensure that it will work with as many different *roff
-implementations as possible. Many *roff implementations cannot handle
-non-ASCII characters, so this means all non-ASCII characters are converted
-either to a *roff escape sequence that tries to create a properly accented
-character (at least for troff output) or to C<X>.
-
-If this option is set, Pod::Man will instead output UTF-8. If your *roff
-implementation can handle it, this is the best output format to use and
-avoids corruption of documents containing non-ASCII characters. However,
-be warned that *roff source with literal UTF-8 characters is not supported
-by many implementations and may even result in segfaults and other bad
-behavior.
-
-Be aware that, when using this option, the input encoding of your POD
-source should be properly declared unless it's US-ASCII. Pod::Simple will
-attempt to guess the encoding and may be successful if it's Latin-1 or
-UTF-8, but it will produce warnings. Use the C<=encoding> command to
-declare the encoding. See L<perlpod(1)> for more information.
+[2.21] This option used to set the output encoding to UTF-8. Since this is
+now the default, it is ignored and does nothing.
+
+=back
=back
-The standard Pod::Simple method parse_file() takes one argument naming the
-POD file to read from. By default, the output is sent to C<STDOUT>, but
-this can be changed with the output_fh() method.
+=head1 INSTANCE METHODS
+
+As a derived class from Pod::Simple, Pod::Man supports the same methods and
+interfaces. See L<Pod::Simple> for all the details. This section summarizes
+the most-frequently-used methods and the ones added by Pod::Man.
+
+=over 4
+
+=item output_fh(FH)
+
+Direct the output from parse_file(), parse_lines(), or parse_string_document()
+to the file handle FH instead of C<STDOUT>.
+
+=item output_string(REF)
+
+Direct the output from parse_file(), parse_lines(), or parse_string_document()
+to the scalar variable pointed to by REF, rather than C<STDOUT>. For example:
+
+ my $man = Pod::Man->new();
+ my $output;
+ $man->output_string(\$output);
+ $man->parse_file('/some/input/file');
-The standard Pod::Simple method parse_from_file() takes up to two
-arguments, the first being the input file to read POD from and the second
-being the file to write the formatted output to.
+Be aware that the output in that variable will already be encoded in UTF-8.
-You can also call parse_lines() to parse an array of lines or
-parse_string_document() to parse a document already in memory. As with
-parse_file(), parse_lines() and parse_string_document() default to sending
-their output to C<STDOUT> unless changed with the output_fh() method. Be
-aware that parse_lines() and parse_string_document() both expect raw bytes,
-not decoded characters.
+=item parse_file(PATH)
-To put the output from any parse method into a string instead of a file
-handle, call the output_string() method instead of output_fh().
+Read the POD source from PATH and format it. By default, the output is sent
+to C<STDOUT>, but this can be changed with the output_fh() or output_string()
+methods.
-See L<Pod::Simple> for more specific details on the methods available to
-all derived parsers.
+=item parse_from_file(INPUT, OUTPUT)
+
+=item parse_from_filehandle(FH, OUTPUT)
+
+Read the POD source from INPUT, format it, and output the results to OUTPUT.
+
+parse_from_filehandle() is provided for backward compatibility with older
+versions of Pod::Man. parse_from_file() should be used instead.
+
+=item parse_lines(LINES[, ...[, undef]])
+
+Parse the provided lines as POD source, writing the output to either C<STDOUT>
+or the file handle set with the output_fh() or output_string() methods. This
+method can be called repeatedly to provide more input lines. An explicit
+C<undef> should be passed to indicate the end of input.
+
+This method expects raw bytes, not decoded characters.
+
+=item parse_string_document(INPUT)
+
+Parse the provided scalar variable as POD source, writing the output to either
+C<STDOUT> or the file handle set with the output_fh() or output_string()
+methods.
+
+This method expects raw bytes, not decoded characters.
+
+=back
+
+=head1 ENCODING
+
+As of Pod::Man 5.00, the default output encoding for Pod::Man is UTF-8. This
+should work correctly on any modern system that uses either B<groff> (most
+Linux distributions) or B<mandoc> (Alpine Linux and most BSD variants,
+including macOS).
+
+The user will probably have to use a UTF-8 locale to see correct output. This
+may be done by default; if not, set the LANG or LC_CTYPE environment variables
+to an appropriate local. The locale C<C.UTF-8> is available on most systems
+if one wants correct output without changing the other things locales affect,
+such as collation.
+
+The backward-compatible output format used in Pod::Man versions before 5.00 is
+available by setting the C<encoding> option to C<roff>. This may produce
+marginally nicer results on older UNIX versions that do not use B<groff> or
+B<mandoc>, but none of the available options will correctly render Unicode
+characters on those systems.
+
+Below are some additional details about how this choice was made and some
+discussion of alternatives.
+
+=head2 History
+
+The default output encoding for Pod::Man has been a long-standing problem.
+B<troff> and B<nroff> predate Unicode by a significant margin, and their
+implementations for many UNIX systems reflect that legacy. It's common for
+Unicode to not be supported in any form.
+
+Because of this, versions of Pod::Man prior to 5.00 maintained the highly
+conservative output of the original pod2man, which output pure ASCII with
+complex macros to simulate common western European accented characters when
+processed with troff. The nroff output was awkward and sometimes incorrect,
+and characters not used in western European scripts were replaced with C<X>.
+This choice maximized backwards compatibility with B<man> and
+B<nroff>/B<troff> implementations at the cost of incorrect rendering of many
+POD documents, particularly those containing people's names.
+
+The modern implementations, B<groff> (used in most Linux distributions) and
+B<mandoc> (used by most BSD variants), do now support Unicode. Other UNIX
+systems often do not, but they're now a tiny minority of the systems people
+use on a daily basis. It's increasingly common (for very good reasons) to use
+Unicode characters for POD documents rather than using ASCII conversions of
+people's names or avoiding non-English text, making the limitations in the old
+output format more apparent.
+
+Four options have been proposed to fix this:
+
+=over 2
+
+=item *
+
+Optionally support UTF-8 output but don't change the default. This is the
+approach taken since Pod::Man 2.1.0, which added the C<utf8> option. Some
+Pod::Man users use this option for better output on platforms known to support
+Unicode, but since the defaults have not changed, people continued to
+encounter (and file bug reports about) the poor default rendering.
+
+=item *
+
+Convert characters to troff C<\(xx> escapes. This requires maintaining a
+large translation table and addresses only a tiny part of the problem, since
+many Unicode characters have no standard troff name. B<groff> has the largest
+list, but if one is willing to assume B<groff> is the formatter, the next
+option is better.
+
+=item *
+
+Convert characters to groff C<\[uNNNN]> escapes. This is implemented as the
+C<groff> encoding for those who want to use it, and is supported by both
+B<groff> and B<mandoc>. However, it is no better than UTF-8 output for
+portability to other implementations. See L</Testing results> for more
+details.
+
+=item *
+
+Change the default output format to UTF-8 and ask those who want maximum
+backward compatibility to explicitly select the old encoding. This fixes the
+issue for most users at the cost of backwards compatibility. While the
+rendering of non-ASCII characters is different on older systems that don't
+support UTF-8, it's not always worse than the old output.
+
+=back
+
+Pod::Man 5.00 and later makes the last choice. This arguably produces worse
+output when manual pages are formatted with B<troff> into PostScript or PDF,
+but doing this is rare and normally manual, so the encoding can be changed in
+those cases. The older output encoding is available by setting C<encoding> to
+C<roff>.
+
+=head2 Testing results
+
+Here is the results of testing C<encoding> values of C<utf-8> and C<groff> on
+various operating systems. The testing methodology was to create F<man/man1>
+in the current directory, copy F<encoding.utf8> or F<encoding.groff> from the
+podlators 5.00 distribution to F<man/man1/encoding.1>, and then run:
+
+ LANG=C.UTF-8 MANPATH=$(pwd)/man man 1 encoding
+
+If the locale is not explicitly set to one that includes UTF-8, the Unicode
+characters were usually converted to ASCII (by, for example, dropping an
+accent) or deleted or replaced with C<< <?> >> if there was no conversion.
+
+Tested on 2022-09-25. Many thanks to the GCC Compile Farm project for access
+to testing hosts.
+
+ OS UTF-8 groff
+ ------------------ ------- -------
+ AIX 7.1 no [1] no [2]
+ Alpine 3.15.0 yes yes
+ CentOS 7.9 yes yes
+ Debian 7 yes yes
+ FreeBSD 13.0 yes yes
+ NetBSD 9.2 yes yes
+ OpenBSD 7.1 yes yes
+ openSUSE Leap 15.4 yes yes
+ Solaris 10 yes no [2]
+ Solaris 11 no [3] no [3]
+
+I did not have access to a macOS system for testing, but since it uses
+B<mandoc>, it's behavior is probably the same as the BSD hosts.
+
+Notes:
+
+=over 4
+
+=item [1]
+
+Unicode characters were converted to one or two random ASCII characters
+unrelated to the original character.
+
+=item [2]
+
+Unicode characters were shown as the body of the groff escape rather than the
+indicated character (in other words, text like C<[u00EF]>).
+
+=item [3]
+
+Unicode characters were deleted entirely, as if they weren't there. Using
+C<nroff -man> instead of B<man> to format the page showed the same results as
+Solaris 10. Using C<groff -k -man -Tutf8> to format the page produced the
+correct output.
+
+=back
+
+PostScript and PDF output using groff on a Debian 12 system do not support
+combining accent marks or SMP characters due to a lack of support in the
+default output font.
+
+Testing on additional platforms is welcome. Please let the author know if you
+have additional results.
=head1 DIAGNOSTICS
@@ -1922,9 +2236,9 @@ option was set to C<die>.
=item PERL_CORE
-If set and Encode is not available, silently fall back to non-UTF-8 mode
-without complaining to standard error. This environment variable is set
-during Perl core builds, which build Encode after podlators. Encode is
+If set and Encode is not available, silently fall back to an encoding of
+C<groff> without complaining to standard error. This environment variable is
+set during Perl core builds, which build Encode after podlators. Encode is
expected to not (yet) be available in that case.
=item POD_MAN_DATE
@@ -1953,65 +2267,104 @@ reliable if this variable overrode the timestamp of the input file.)
=back
-=head1 BUGS
+=head1 COMPATIBILITY
-Encoding handling assumes that PerlIO is available and does not work
-properly if it isn't. The C<utf8> option is therefore not supported
-unless Perl is built with PerlIO support.
+Pod::Man 1.02 (based on L<Pod::Parser>) was the first version included with
+Perl, in Perl 5.6.0.
-There is currently no way to turn off the guesswork that tries to format
-unmarked text appropriately, and sometimes it isn't wanted (particularly
-when using POD to document something other than Perl). Most of the work
-toward fixing this has now been done, however, and all that's still needed
-is a user interface.
+The current API based on L<Pod::Simple> was added in Pod::Man 2.00. Pod::Man
+2.04 was included in Perl 5.9.3, the first version of Perl to incorporate
+those changes. This is the first version that correctly supports all modern
+POD syntax. The parse_from_filehandle() method was re-added for backward
+compatibility in Pod::Man 2.09, included in Perl 5.9.4.
-The NAME section should be recognized specially and index entries emitted
-for everything in that section. This would have to be deferred until the
-next section, since extraneous things in NAME tends to confuse various man
-page processors. Currently, no index entries are emitted for anything in
-NAME.
+Support for anchor text in LZ<><> links of type URL was added in Pod::Man
+2.23, included in Perl 5.11.5.
-Pod::Man doesn't handle font names longer than two characters. Neither do
-most B<troff> implementations, but GNU troff does as an extension. It would
-be nice to support as an option for those who want to use it.
+parse_lines(), parse_string_document(), and parse_file() set a default output
+file handle of C<STDOUT> if one was not already set as of Pod::Man 2.28,
+included in Perl 5.19.5.
+
+Support for SOURCE_DATE_EPOCH and POD_MAN_DATE was added in Pod::Man 4.00,
+included in Perl 5.23.7, and generated dates were changed to use UTC instead
+of the local time zone. This is also the first release that aligned the
+module version and the version of the podlators distribution. All modules
+included in podlators, and the podlators distribution itself, share the same
+version number from this point forward.
-The preamble added to each output file is rather verbose, and most of it
-is only necessary in the presence of non-ASCII characters. It would
-ideally be nice if all of those definitions were only output if needed,
-perhaps on the fly as the characters are used.
+Pod::Man 4.10, included in Perl 5.27.8, changed the formatting for manual page
+references and function names to bold instead of italic, following the current
+Linux manual page standard.
-Pod::Man is excessively slow.
+Pod::Man 5.00 changed the default output encoding to UTF-8, overridable with
+the new C<encoding> option. It also fixed problems with bold or italic
+extending too far when used with CZ<><> escapes, and began converting Unicode
+zero-width spaces (U+200B) to the C<\:> *roff escape. It also dropped
+attempts to add subtle formatting corrections in the output that would only be
+visible when typeset with B<troff>, which had previously been a significant
+source of bugs.
+
+=head1 BUGS
+
+There are numerous bugs and language-specific assumptions in the nroff
+fallbacks for accented characters in the C<roff> encoding. Since the point of
+this encoding is backward compatibility with the output from earlier versions
+of Pod::Man, and it is deprecated except when necessary to support old
+systems, those bugs are unlikely to ever be fixed.
+
+Pod::Man doesn't handle font names longer than two characters. Neither do
+most B<troff> implementations, but groff does as an extension. It would be
+nice to support as an option for those who want to use it.
=head1 CAVEATS
-If Pod::Man is given the C<utf8> option, the encoding of its output file
-handle will be forced to UTF-8 if possible, overriding any existing
-encoding. This will be done even if the file handle is not created by
-Pod::Man and was passed in from outside. This maintains consistency
-regardless of PERL_UNICODE and other settings.
+=head2 Sentence spacing
+
+Pod::Man copies the input spacing verbatim to the output *roff document. This
+means your output will be affected by how B<nroff> generally handles sentence
+spacing.
+
+B<nroff> dates from an era in which it was standard to use two spaces after
+sentences, and will always add two spaces after a line-ending period (or
+similar punctuation) when reflowing text. For example, the following input:
+
+ =pod
-The handling of hyphens and em dashes is somewhat fragile, and one may get
-the wrong one under some circumstances. This should only matter for
-B<troff> output.
+ One sentence.
+ Another sentence.
-When and whether to use small caps is somewhat tricky, and Pod::Man doesn't
-necessarily get it right.
+will result in two spaces after the period when the text is reflowed. If you
+use two spaces after sentences anyway, this will be consistent, although you
+will have to be careful to not end a line with an abbreviation such as C<e.g.>
+or C<Ms.>. Output will also be consistent if you use the *roff style guide
+(and L<XKCD 1285|https://xkcd.com/1285/>) recommendation of putting a line
+break after each sentence, although that will consistently produce two spaces
+after each sentence, which may not be what you want.
-Converting neutral double quotes to properly matched double quotes doesn't
-work unless there are no formatting codes between the quote marks. This
-only matters for troff output.
+If you prefer one space after sentences (which is the more modern style), you
+will unfortunately need to ensure that no line in the middle of a paragraph
+ends in a period or similar sentence-ending paragraph. Otherwise, B<nroff>
+will add a two spaces after that sentence when reflowing, and your output
+document will have inconsistent spacing.
+
+=head2 Hyphens
+
+The handling of hyphens versus dashes is somewhat fragile, and one may get a
+the wrong one under some circumstances. This will normally only matter for
+line breaking and possibly for troff output.
=head1 AUTHOR
-Russ Allbery <rra@cpan.org>, based I<very> heavily on the original B<pod2man>
-by Tom Christiansen <tchrist@mox.perl.com>. The modifications to work with
-Pod::Simple instead of Pod::Parser were originally contributed by Sean Burke
-<sburke@cpan.org> (but I've since hacked them beyond recognition and all bugs
-are mine).
+Written by Russ Allbery <rra@cpan.org>, based on the original B<pod2man> by
+Tom Christiansen <tchrist@mox.perl.com>.
+
+The modifications to work with Pod::Simple instead of Pod::Parser were
+contributed by Sean Burke <sburke@cpan.org>, but I've since hacked them beyond
+recognition and all bugs are mine.
=head1 COPYRIGHT AND LICENSE
-Copyright 1999-2010, 2012-2019 Russ Allbery <rra@cpan.org>
+Copyright 1999-2010, 2012-2020, 2022 Russ Allbery <rra@cpan.org>
Substantial contributions by Sean Burke <sburke@cpan.org>.
@@ -2020,18 +2373,19 @@ under the same terms as Perl itself.
=head1 SEE ALSO
-L<Pod::Simple>, L<perlpod(1)>, L<pod2man(1)>, L<nroff(1)>, L<troff(1)>,
-L<man(1)>, L<man(7)>
+L<Encode::Supported>, L<Pod::Simple>, L<perlpod(1)>, L<pod2man(1)>,
+L<nroff(1)>, L<troff(1)>, L<man(1)>, L<man(7)>
Ossanna, Joseph F., and Brian W. Kernighan. "Troff User's Manual,"
Computing Science Technical Report No. 54, AT&T Bell Laboratories. This is
the best documentation of standard B<nroff> and B<troff>. At the time of
this writing, it's available at L<http://www.troff.org/54.pdf>.
-The man page documenting the man macro set may be L<man(5)> instead of
-L<man(7)> on your system. Also, please see L<pod2man(1)> for extensive
-documentation on writing manual pages if you've not done it before and
-aren't familiar with the conventions.
+The manual page documenting the man macro set may be L<man(5)> instead of
+L<man(7)> on your system.
+
+See L<perlpodstyle(1)> for documentation on writing manual pages in POD if
+you've not done it before and aren't familiar with the conventions.
The current version of this module is always available from its web site at
L<https://www.eyrie.org/~eagle/software/podlators/>. It is also part of the
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/ParseLink.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/ParseLink.pm
index 273c95847a..83bc3f7565 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/ParseLink.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/ParseLink.pm
@@ -13,17 +13,15 @@
package Pod::ParseLink;
-use 5.008;
+use 5.010;
use strict;
use warnings;
-use vars qw(@EXPORT @ISA $VERSION);
-
use Exporter;
-@ISA = qw(Exporter);
-@EXPORT = qw(parselink);
-$VERSION = '4.14';
+our @ISA = qw(Exporter);
+our @EXPORT = qw(parselink);
+our $VERSION = '5.01';
##############################################################################
# Implementation
@@ -171,7 +169,7 @@ Russ Allbery <rra@cpan.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2001, 2008, 2009, 2014, 2018-2019 Russ Allbery <rra@cpan.org>
+Copyright 2001, 2008, 2009, 2014, 2018-2019, 2022 Russ Allbery <rra@cpan.org>
This program is free software; you may redistribute it and/or modify it
under the same terms as Perl itself.
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple.pm
index f2544d0ef1..ee89c0a489 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple.pm
@@ -8,6 +8,7 @@ use integer;
use Pod::Escapes 1.04 ();
use Pod::Simple::LinkSection ();
use Pod::Simple::BlackBox ();
+use Pod::Simple::TiedOutFH;
#use utf8;
use vars qw(
@@ -18,7 +19,7 @@ use vars qw(
);
@ISA = ('Pod::Simple::BlackBox');
-$VERSION = '3.42';
+$VERSION = '3.43';
@Known_formatting_codes = qw(I B C L E F S X Z);
%Known_formatting_codes = map(($_=>1), @Known_formatting_codes);
@@ -202,7 +203,6 @@ sub output_string {
my $this = shift;
return $this->{'output_string'} unless @_; # GET.
- require Pod::Simple::TiedOutFH;
my $x = (defined($_[0]) and ref($_[0])) ? $_[0] : \( $_[0] );
$$x = '' unless defined $$x;
DEBUG > 4 and print STDERR "# Output string set to $x ($$x)\n";
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/BlackBox.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/BlackBox.pm
index 03dede7c34..7c0d9aa469 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/BlackBox.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/BlackBox.pm
@@ -22,7 +22,7 @@ use integer; # vroom!
use strict;
use Carp ();
use vars qw($VERSION );
-$VERSION = '3.42';
+$VERSION = '3.43';
#use constant DEBUG => 7;
sub my_qr ($$) {
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Checker.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Checker.pm
index 65f4d54243..3b22a3d6cd 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Checker.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Checker.pm
@@ -9,7 +9,7 @@ use Carp ();
use Pod::Simple::Methody ();
use Pod::Simple ();
use vars qw( @ISA $VERSION );
-$VERSION = '3.42';
+$VERSION = '3.43';
@ISA = ('Pod::Simple::Methody');
BEGIN { *DEBUG = defined(&Pod::Simple::DEBUG)
? \&Pod::Simple::DEBUG
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Debug.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Debug.pm
index 6b9aa327c0..7f51efa9dc 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Debug.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Debug.pm
@@ -2,7 +2,7 @@ require 5;
package Pod::Simple::Debug;
use strict;
use vars qw($VERSION );
-$VERSION = '3.42';
+$VERSION = '3.43';
sub import {
my($value,$variable);
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsText.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsText.pm
index a22603043b..dfcee5d2b4 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsText.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsText.pm
@@ -1,7 +1,7 @@
require 5;
package Pod::Simple::DumpAsText;
-$VERSION = '3.42';
+$VERSION = '3.43';
use Pod::Simple ();
BEGIN {@ISA = ('Pod::Simple')}
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsXML.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsXML.pm
index 024e4b7b81..c5e719cdf8 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsXML.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/DumpAsXML.pm
@@ -1,7 +1,7 @@
require 5;
package Pod::Simple::DumpAsXML;
-$VERSION = '3.42';
+$VERSION = '3.43';
use Pod::Simple ();
BEGIN {@ISA = ('Pod::Simple')}
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTML.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTML.pm
index f930a51217..cebf5702a8 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTML.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTML.pm
@@ -9,7 +9,7 @@ use vars qw(
$Doctype_decl $Content_decl
);
@ISA = ('Pod::Simple::PullParser');
-$VERSION = '3.42';
+$VERSION = '3.43';
BEGIN {
if(defined &DEBUG) { } # no-op
elsif( defined &Pod::Simple::DEBUG ) { *DEBUG = \&Pod::Simple::DEBUG }
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTMLBatch.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTMLBatch.pm
index 6a06173f47..cd33a4c97c 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTMLBatch.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/HTMLBatch.pm
@@ -5,7 +5,7 @@ use strict;
use vars qw( $VERSION $HTML_RENDER_CLASS $HTML_EXTENSION
$CSS $JAVASCRIPT $SLEEPY $SEARCH_CLASS @ISA
);
-$VERSION = '3.42';
+$VERSION = '3.43';
@ISA = (); # Yup, we're NOT a subclass of Pod::Simple::HTML!
# TODO: nocontents stylesheets. Strike some of the color variations?
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/LinkSection.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/LinkSection.pm
index a6898caec4..c14dabcea2 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/LinkSection.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/LinkSection.pm
@@ -6,7 +6,7 @@ package Pod::Simple::LinkSection;
use strict;
use Pod::Simple::BlackBox;
use vars qw($VERSION );
-$VERSION = '3.42';
+$VERSION = '3.43';
use overload( # So it'll stringify nice
'""' => \&Pod::Simple::BlackBox::stringify_lol,
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Methody.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Methody.pm
index 45e26cf463..cc096facbb 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Methody.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Methody.pm
@@ -4,7 +4,7 @@ package Pod::Simple::Methody;
use strict;
use Pod::Simple ();
use vars qw(@ISA $VERSION);
-$VERSION = '3.42';
+$VERSION = '3.43';
@ISA = ('Pod::Simple');
# Yes, we could use named variables, but I want this to be impose
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Progress.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Progress.pm
index 77de9ae86f..d1eaba2d6f 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Progress.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Progress.pm
@@ -1,7 +1,7 @@
require 5;
package Pod::Simple::Progress;
-$VERSION = '3.42';
+$VERSION = '3.43';
use strict;
# Objects of this class are used for noting progress of an
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParser.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParser.pm
index 57aad9ac08..8c00592fba 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParser.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParser.pm
@@ -1,6 +1,6 @@
require 5;
package Pod::Simple::PullParser;
-$VERSION = '3.42';
+$VERSION = '3.43';
use Pod::Simple ();
BEGIN {@ISA = ('Pod::Simple')}
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserEndToken.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserEndToken.pm
index dbff3df249..2d656e088f 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserEndToken.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserEndToken.pm
@@ -5,7 +5,7 @@ use Pod::Simple::PullParserToken ();
use strict;
use vars qw(@ISA $VERSION);
@ISA = ('Pod::Simple::PullParserToken');
-$VERSION = '3.42';
+$VERSION = '3.43';
sub new { # Class->new(tagname);
my $class = shift;
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserStartToken.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserStartToken.pm
index 1ab33cc6e0..5e1bf71ed9 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserStartToken.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserStartToken.pm
@@ -5,7 +5,7 @@ use Pod::Simple::PullParserToken ();
use strict;
use vars qw(@ISA $VERSION);
@ISA = ('Pod::Simple::PullParserToken');
-$VERSION = '3.42';
+$VERSION = '3.43';
sub new { # Class->new(tagname, optional_attrhash);
my $class = shift;
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserTextToken.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserTextToken.pm
index cdce959db4..159839952e 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserTextToken.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserTextToken.pm
@@ -5,7 +5,7 @@ use Pod::Simple::PullParserToken ();
use strict;
use vars qw(@ISA $VERSION);
@ISA = ('Pod::Simple::PullParserToken');
-$VERSION = '3.42';
+$VERSION = '3.43';
sub new { # Class->new(text);
my $class = shift;
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserToken.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserToken.pm
index 63a2dabe6f..48cece540f 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserToken.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/PullParserToken.pm
@@ -3,7 +3,7 @@ require 5;
package Pod::Simple::PullParserToken;
# Base class for tokens gotten from Pod::Simple::PullParser's $parser->get_token
@ISA = ();
-$VERSION = '3.42';
+$VERSION = '3.43';
use strict;
sub new { # Class->new('type', stuff...); ## Overridden in derived classes anyway
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/RTF.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/RTF.pm
index 10e05c5d0a..793a8b2a49 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/RTF.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/RTF.pm
@@ -8,7 +8,7 @@ package Pod::Simple::RTF;
use strict;
use vars qw($VERSION @ISA %Escape $WRAP %Tagmap);
-$VERSION = '3.42';
+$VERSION = '3.43';
use Pod::Simple::PullParser ();
BEGIN {@ISA = ('Pod::Simple::PullParser')}
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Search.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Search.pm
index ad610654c9..6462549492 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Search.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Search.pm
@@ -3,7 +3,7 @@ package Pod::Simple::Search;
use strict;
use vars qw($VERSION $MAX_VERSION_WITHIN $SLEEPY);
-$VERSION = '3.42'; ## Current version of this package
+$VERSION = '3.43'; ## Current version of this package
BEGIN { *DEBUG = sub () {0} unless defined &DEBUG; } # set DEBUG level
use Carp ();
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/SimpleTree.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/SimpleTree.pm
index 38a2704f87..15f457baaf 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/SimpleTree.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/SimpleTree.pm
@@ -5,7 +5,7 @@ use strict;
use Carp ();
use Pod::Simple ();
use vars qw( $ATTR_PAD @ISA $VERSION $SORT_ATTRS);
-$VERSION = '3.42';
+$VERSION = '3.43';
BEGIN {
@ISA = ('Pod::Simple');
*DEBUG = \&Pod::Simple::DEBUG unless defined &DEBUG;
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Text.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Text.pm
index 2f0254ec37..f44987f4e4 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Text.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Text.pm
@@ -6,7 +6,7 @@ use Carp ();
use Pod::Simple::Methody ();
use Pod::Simple ();
use vars qw( @ISA $VERSION $FREAKYMODE);
-$VERSION = '3.42';
+$VERSION = '3.43';
@ISA = ('Pod::Simple::Methody');
BEGIN { *DEBUG = defined(&Pod::Simple::DEBUG)
? \&Pod::Simple::DEBUG
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TextContent.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TextContent.pm
index ccbf424221..9c2932e37d 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TextContent.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TextContent.pm
@@ -6,7 +6,7 @@ use strict;
use Carp ();
use Pod::Simple ();
use vars qw( @ISA $VERSION );
-$VERSION = '3.42';
+$VERSION = '3.43';
@ISA = ('Pod::Simple');
sub new {
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TiedOutFH.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TiedOutFH.pm
index cbf58b3706..af5e745a30 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TiedOutFH.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TiedOutFH.pm
@@ -4,7 +4,7 @@ package Pod::Simple::TiedOutFH;
use Symbol ('gensym');
use Carp ();
use vars qw($VERSION );
-$VERSION = '3.42';
+$VERSION = '3.43';
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Transcode.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Transcode.pm
index bdb7181af6..fef5d17d45 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Transcode.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/Transcode.pm
@@ -3,7 +3,7 @@ require 5;
package Pod::Simple::Transcode;
use strict;
use vars qw($VERSION @ISA);
-$VERSION = '3.42';
+$VERSION = '3.43';
BEGIN {
if(defined &DEBUG) {;} # Okay
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeDumb.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeDumb.pm
index 96e6a54410..776b067645 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeDumb.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeDumb.pm
@@ -5,7 +5,7 @@ require 5;
package Pod::Simple::TranscodeDumb;
use strict;
use vars qw($VERSION %Supported);
-$VERSION = '3.42';
+$VERSION = '3.43';
# This module basically pretends it knows how to transcode, except
# only for null-transcodings! We use this when Encode isn't
# available.
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeSmart.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeSmart.pm
index 3f3224f917..f46d1f9d05 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeSmart.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/TranscodeSmart.pm
@@ -9,7 +9,7 @@ use strict;
use Pod::Simple;
require Encode;
use vars qw($VERSION );
-$VERSION = '3.42';
+$VERSION = '3.43';
sub is_dumb {0}
sub is_smart {1}
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XHTML.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XHTML.pm
index 9049ce755f..e8d7e11127 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XHTML.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XHTML.pm
@@ -45,7 +45,7 @@ declare the output character set as UTF-8 before parsing, like so:
package Pod::Simple::XHTML;
use strict;
use vars qw( $VERSION @ISA $HAS_HTML_ENTITIES );
-$VERSION = '3.42';
+$VERSION = '3.43';
use Pod::Simple::Methody ();
@ISA = ('Pod::Simple::Methody');
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XMLOutStream.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XMLOutStream.pm
index a891a3341f..74d8c16b7b 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XMLOutStream.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Simple/XMLOutStream.pm
@@ -5,7 +5,7 @@ use strict;
use Carp ();
use Pod::Simple ();
use vars qw( $ATTR_PAD @ISA $VERSION $SORT_ATTRS);
-$VERSION = '3.42';
+$VERSION = '3.43';
BEGIN {
@ISA = ('Pod::Simple');
*DEBUG = \&Pod::Simple::DEBUG unless defined &DEBUG;
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text.pm
index 56e6e78a86..83a7ce22a8 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text.pm
@@ -14,23 +14,20 @@
package Pod::Text;
-use 5.008;
+use 5.010;
use strict;
use warnings;
-use vars qw(@ISA @EXPORT %ESCAPES $VERSION);
-
use Carp qw(carp croak);
use Encode qw(encode);
use Exporter ();
use Pod::Simple ();
-@ISA = qw(Pod::Simple Exporter);
+our @ISA = qw(Pod::Simple Exporter);
+our $VERSION = '5.01';
# We have to export pod2text for backward compatibility.
-@EXPORT = qw(pod2text);
-
-$VERSION = '4.14';
+our @EXPORT = qw(pod2text);
# Ensure that $Pod::Simple::nbsp and $Pod::Simple::shy are available. Code
# taken from Pod::Simple 3.32, but was only added in 3.30.
@@ -43,6 +40,11 @@ if ($Pod::Simple::VERSION ge 3.30) {
$SHY = chr utf8::unicode_to_native(0xAD);
}
+# Import the ASCII constant from Pod::Simple. This is true iff we're in an
+# ASCII-based universe (including such things as ISO 8859-1 and UTF-8), and is
+# generally only false for EBCDIC.
+BEGIN { *ASCII = \&Pod::Simple::ASCII }
+
##############################################################################
# Initialization
##############################################################################
@@ -64,9 +66,6 @@ sub new {
my $class = shift;
my $self = $class->SUPER::new;
- # Tell Pod::Simple to handle S<> by automatically inserting &nbsp;.
- $self->nbsp_for_S (1);
-
# Tell Pod::Simple to keep whitespace whenever possible.
if ($self->can ('preserve_whitespace')) {
$self->preserve_whitespace (1);
@@ -89,16 +88,20 @@ sub new {
my @opts = map { ("opt_$_", $opts{$_}) } keys %opts;
%$self = (%$self, @opts);
- # Send errors to stderr if requested.
+ # Backwards-compatibility support for the stderr option.
if ($$self{opt_stderr} and not $$self{opt_errors}) {
$$self{opt_errors} = 'stderr';
}
delete $$self{opt_stderr};
- # Validate the errors parameter and act on it.
- if (not defined $$self{opt_errors}) {
- $$self{opt_errors} = 'pod';
+ # Backwards-compatibility support for the utf8 option.
+ if ($$self{opt_utf8} && !$$self{opt_encoding}) {
+ $$self{opt_encoding} = 'UTF-8';
}
+ delete $$self{opt_utf8};
+
+ # Validate the errors parameter and act on it.
+ $$self{opt_errors} //= 'pod';
if ($$self{opt_errors} eq 'stderr' || $$self{opt_errors} eq 'die') {
$self->no_errata_section (1);
$self->complain_stderr (1);
@@ -117,12 +120,12 @@ sub new {
delete $$self{errors};
# Initialize various things from our parameters.
- $$self{opt_alt} = 0 unless defined $$self{opt_alt};
- $$self{opt_indent} = 4 unless defined $$self{opt_indent};
- $$self{opt_margin} = 0 unless defined $$self{opt_margin};
- $$self{opt_loose} = 0 unless defined $$self{opt_loose};
- $$self{opt_sentence} = 0 unless defined $$self{opt_sentence};
- $$self{opt_width} = 76 unless defined $$self{opt_width};
+ $$self{opt_alt} //= 0;
+ $$self{opt_indent} //= 4;
+ $$self{opt_margin} //= 0;
+ $$self{opt_loose} //= 0;
+ $$self{opt_sentence} //= 0;
+ $$self{opt_width} //= 76;
# Figure out what quotes we'll be using for C<> text.
$$self{opt_quotes} ||= '"';
@@ -138,6 +141,17 @@ sub new {
croak qq(Invalid quote specification "$$self{opt_quotes}");
}
+ # Configure guesswork based on options.
+ my $guesswork = $self->{opt_guesswork} || q{};
+ my %guesswork = map { $_ => 1 } split(m{,}xms, $guesswork);
+ if (!%guesswork || $guesswork{all}) {
+ $$self{GUESSWORK} = {quoting => 1};
+ } elsif ($guesswork{none}) {
+ $$self{GUESSWORK} = {};
+ } else {
+ $$self{GUESSWORK} = {%guesswork};
+ }
+
# If requested, do something with the non-POD text.
$self->code_handler (\&handle_code) if $$self{opt_code};
@@ -272,9 +286,7 @@ sub reformat {
}
# Output text to the output device. Replace non-breaking spaces with spaces
-# and soft hyphens with nothing, and then try to fix the output encoding if
-# necessary to match the input encoding unless UTF-8 output is forced. This
-# preserves the traditional pass-through behavior of Pod::Text.
+# and soft hyphens with nothing, and then determine the output encoding.
sub output {
my ($self, @text) = @_;
my $text = join ('', @text);
@@ -284,15 +296,39 @@ sub output {
if ($SHY) {
$text =~ s/$SHY//g;
}
- unless ($$self{opt_utf8}) {
- my $encoding = $$self{encoding} || '';
- if ($encoding && $encoding ne $$self{ENCODING}) {
- $$self{ENCODING} = $encoding;
- eval { binmode ($$self{output_fh}, ":encoding($encoding)") };
- }
- }
+
+ # The logic used here is described in the POD documentation. Prefer the
+ # configured encoding, then the pass-through option of using the same
+ # encoding as the input, and then UTF-8, but commit to an encoding for the
+ # document.
+ #
+ # ENCODE says whether to encode or not and is turned off if there is a
+ # PerlIO encoding layer (in start_document). ENCODING is the encoding
+ # that we previously committed to and is cleared at the start of each
+ # document.
if ($$self{ENCODE}) {
- print { $$self{output_fh} } encode ('UTF-8', $text);
+ my $encoding = $$self{ENCODING};
+ if (!$encoding) {
+ $encoding = $self->encoding();
+ if (!$encoding && ASCII && $text =~ /[^\x00-\x7F]/) {
+ $encoding = 'UTF-8';
+ }
+ if ($encoding) {
+ $$self{ENCODING} = $encoding;
+ }
+ }
+ if ($encoding) {
+ my $check = sub {
+ my ($char) = @_;
+ my $display = '"\x{' . hex($char) . '}"';
+ my $error = "$display does not map to $$self{ENCODING}";
+ $self->whine ($self->line_count(), $error);
+ return Encode::encode ($$self{ENCODING}, chr($char));
+ };
+ print { $$self{output_fh} } encode ($encoding, $text, $check);
+ } else {
+ print { $$self{output_fh} } $text;
+ }
} else {
print { $$self{output_fh} } $text;
}
@@ -322,24 +358,18 @@ sub start_document {
$$self{MARGIN} = $margin; # Default left margin.
$$self{PENDING} = [[]]; # Pending output.
- # We have to redo encoding handling for each document.
- $$self{ENCODING} = '';
-
- # When UTF-8 output is set, check whether our output file handle already
- # has a PerlIO encoding layer set. If it does not, we'll need to encode
- # our output before printing it (handled in the output() sub).
- $$self{ENCODE} = 0;
- if ($$self{opt_utf8}) {
- $$self{ENCODE} = 1;
- eval {
- my @options = (output => 1, details => 1);
- my $flag = (PerlIO::get_layers ($$self{output_fh}, @options))[-1];
- if ($flag && ($flag & PerlIO::F_UTF8 ())) {
- $$self{ENCODE} = 0;
- $$self{ENCODING} = 'UTF-8';
- }
- };
- }
+ # We have to redo encoding handling for each document. Check whether the
+ # output file handle already has a PerlIO encoding layer set and, if so,
+ # disable encoding.
+ $$self{ENCODE} = 1;
+ eval {
+ my @options = (output => 1, details => 1);
+ my $flag = (PerlIO::get_layers ($$self{output_fh}, @options))[-1];
+ if ($flag && ($flag & PerlIO::F_UTF8 ())) {
+ $$self{ENCODE} = 0;
+ }
+ };
+ $$self{ENCODING} = $$self{opt_encoding};
return '';
}
@@ -383,8 +413,7 @@ sub item {
# Calculate the indentation and margin. $fits is set to true if the tag
# will fit into the margin of the paragraph given our indentation level.
- my $indent = $$self{INDENTS}[-1];
- $indent = $$self{opt_indent} unless defined $indent;
+ my $indent = $$self{INDENTS}[-1] // $$self{opt_indent};
my $margin = ' ' x $$self{opt_margin};
my $tag_length = length ($self->strip_format ($tag));
my $fits = ($$self{MARGIN} - $indent >= $tag_length + 1);
@@ -588,6 +617,13 @@ sub cmd_f { return $_[0]{alt} ? "\"$_[2]\"" : $_[2] }
sub cmd_i { return '*' . $_[2] . '*' }
sub cmd_x { return '' }
+# Convert all internal whitespace to $NBSP.
+sub cmd_s {
+ my ($self, $attrs, $text) = @_;
+ $text =~ s{ \s }{$NBSP}xmsg;
+ return $text;
+}
+
# Apply a whole bunch of messy heuristics to not quote things that don't
# benefit from being quoted. These originally come from Barrie Slaymaker and
# largely duplicate code in Pod::Man.
@@ -597,23 +633,35 @@ sub cmd_c {
# A regex that matches the portion of a variable reference that's the
# array or hash index, separated out just because we want to use it in
# several places in the following regex.
- my $index = '(?: \[.*\] | \{.*\} )?';
+ my $index = '(?: \[[^]]+\] | \{[^}]+\} )?';
# Check for things that we don't want to quote, and if we find any of
# them, return the string with just a font change and no quoting.
+ #
+ # Traditionally, Pod::Text has not quoted Perl variables, functions,
+ # numbers, or hex constants, but this is not always desirable. Make this
+ # optional on the quoting guesswork flag.
+ my $extra = qr{(?!)}xms; # never matches
+ if ($$self{GUESSWORK}{quoting}) {
+ $extra = qr{
+ \$+ [\#^]? \S $index # special ($^F, $")
+ | [\$\@%&*]+ \#? [:\'\w]+ $index # plain var or func
+ | [\$\@%&*]* [:\'\w]+
+ (?: -> )? \(\s*[^\s,\)]*\s*\) # 0/1-arg func call
+ | [+-]? ( \d[\d.]* | \.\d+ )
+ (?: [eE][+-]?\d+ )? # a number
+ | 0x [a-fA-F\d]+ # a hex constant
+ }xms;
+ }
$text =~ m{
^\s*
(?:
- ( [\'\`\"] ) .* \1 # already quoted
- | \` .* \' # `quoted'
- | \$+ [\#^]? \S $index # special ($^Foo, $")
- | [\$\@%&*]+ \#? [:\'\w]+ $index # plain var or func
- | [\$\@%&*]* [:\'\w]+ (?: -> )? \(\s*[^\s,]\s*\) # 0/1-arg func call
- | [+-]? ( \d[\d.]* | \.\d+ ) (?: [eE][+-]?\d+ )? # a number
- | 0x [a-fA-F\d]+ # a hex constant
+ ( [\'\`\"] ) .* \1 # already quoted
+ | \` .* \' # `quoted'
+ | $extra
)
\s*\z
- }xo && return $text;
+ }xms and return $text;
# If we didn't return, go ahead and quote the text.
return $$self{opt_alt}
@@ -766,7 +814,7 @@ __END__
=for stopwords
alt stderr Allbery Sean Burke's Christiansen UTF-8 pre-Unicode utf8 nourls
-parsers
+parsers EBCDIC autodetecting superset unrepresentable FH NNN
=head1 NAME
@@ -785,67 +833,180 @@ Pod::Text - Convert POD data to formatted text
=head1 DESCRIPTION
-Pod::Text is a module that can convert documentation in the POD format
-(the preferred language for documenting Perl) into formatted text. It
-uses no special formatting controls or codes whatsoever, and its output is
-therefore suitable for nearly any device.
+Pod::Text is a module that can convert documentation in the POD format (the
+preferred language for documenting Perl) into formatted text. It uses no
+special formatting controls or codes, and its output is therefore suitable for
+nearly any device.
-As a derived class from Pod::Simple, Pod::Text supports the same methods and
-interfaces. See L<Pod::Simple> for all the details; briefly, one creates a
-new parser with C<< Pod::Text->new() >> and then normally calls parse_file().
+=head2 Encoding
-new() can take options, in the form of key/value pairs, that control the
-behavior of the parser. The currently recognized options are:
+Pod::Text uses the following logic to choose an output encoding, in order:
+
+=over 4
+
+=item 1.
+
+If a PerlIO encoding layer is set on the output file handle, do not do any
+output encoding and will instead rely on the PerlIO encoding layer.
+
+=item 2.
+
+If the C<encoding> or C<utf8> options are set, use the output encoding
+specified by those options.
+
+=item 3.
+
+If the input encoding of the POD source file was explicitly specified (using
+C<=encoding>) or automatically detected by Pod::Simple, use that as the output
+encoding as well.
+
+=item 4.
+
+Otherwise, if running on a non-EBCDIC system, use UTF-8 as the output
+encoding. Since this is a superset of ASCII, this will result in ASCII output
+unless the POD input contains non-ASCII characters without declaring or
+autodetecting an encoding (usually via EZ<><> escapes).
+
+=item 5.
+
+Otherwise, for EBCDIC systems, output without doing any encoding and hope
+this works.
+
+=back
+
+One caveat: Pod::Text has to commit to an output encoding the first time it
+outputs a non-ASCII character, and then has to stick with it for consistency.
+However, C<=encoding> commands don't have to be at the beginning of a POD
+document. If someone uses a non-ASCII character early in a document with an
+escape, such as EZ<><0xEF>, and then puts C<=encoding iso-8859-1> later,
+ideally Pod::Text would follow rule 3 and output the entire document as ISO
+8859-1. Instead, it will commit to UTF-8 following rule 4 as soon as it sees
+that escape, and then stick with that encoding for the rest of the document.
+
+Unfortunately, there's no universally good choice for an output encoding.
+Each choice will be incorrect in some circumstances. This approach was chosen
+primarily for backwards compatibility. Callers should consider forcing the
+output encoding via C<encoding> if they have any knowledge about what encoding
+the user may expect.
+
+In particular, consider importing the L<Encode::Locale> module, if available,
+and setting C<encoding> to C<locale> to use an output encoding appropriate to
+the user's locale. But be aware that if the user is not using locales or is
+using a locale of C<C>, Encode::Locale will set the output encoding to
+US-ASCII. This will cause all non-ASCII characters will be replaced with C<?>
+and produce a flurry of warnings about unsupported characters, which may or
+may not be what you want.
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item new(ARGS)
+
+Create a new Pod::Text object. ARGS should be a list of key/value pairs,
+where the keys are chosen from the following. Each option is annotated with
+the version of Pod::Text in which that option was added with its current
+meaning.
=over 4
=item alt
-If set to a true value, selects an alternate output format that, among other
-things, uses a different heading style and marks C<=item> entries with a
+[2.00] If set to a true value, selects an alternate output format that, among
+other things, uses a different heading style and marks C<=item> entries with a
colon in the left margin. Defaults to false.
=item code
-If set to a true value, the non-POD parts of the input file will be included
-in the output. Useful for viewing code documented with POD blocks with the
-POD rendered and the code left intact.
+[2.13] If set to a true value, the non-POD parts of the input file will be
+included in the output. Useful for viewing code documented with POD blocks
+with the POD rendered and the code left intact.
+
+=item encoding
+
+[5.00] Specifies the encoding of the output. The value must be an encoding
+recognized by the L<Encode> module (see L<Encode::Supported>). If the output
+contains characters that cannot be represented in this encoding, that is an
+error that will be reported as configured by the C<errors> option. If error
+handling is other than C<die>, the unrepresentable character will be replaced
+with the Encode substitution character (normally C<?>).
+
+If the output file handle has a PerlIO encoding layer set, this parameter will
+be ignored and no encoding will be done by Pod::Man. It will instead rely on
+the encoding layer to make whatever output encoding transformations are
+desired.
+
+WARNING: The input encoding of the POD source is independent from the output
+encoding, and setting this option does not affect the interpretation of the
+POD input. Unless your POD source is US-ASCII, its encoding should be
+declared with the C<=encoding> command in the source, as near to the top of
+the file as possible. If this is not done, Pod::Simple will will attempt to
+guess the encoding and may be successful if it's Latin-1 or UTF-8, but it will
+produce warnings. See L<perlpod(1)> for more information.
=item errors
-How to report errors. C<die> says to throw an exception on any POD
-formatting error. C<stderr> says to report errors on standard error, but
-not to throw an exception. C<pod> says to include a POD ERRORS section
-in the resulting documentation summarizing the errors. C<none> ignores
-POD errors entirely, as much as possible.
+[3.17] How to report errors. C<die> says to throw an exception on any POD
+formatting error. C<stderr> says to report errors on standard error, but not
+to throw an exception. C<pod> says to include a POD ERRORS section in the
+resulting documentation summarizing the errors. C<none> ignores POD errors
+entirely, as much as possible.
The default is C<pod>.
+=item guesswork
+
+[5.01] By default, Pod::Text applies some default formatting rules based on
+guesswork and regular expressions that are intended to make writing Perl
+documentation easier and require less explicit markup. These rules may not
+always be appropriate, particularly for documentation that isn't about Perl.
+This option allows turning all or some of it off.
+
+The special value C<all> enables all guesswork. This is also the default for
+backward compatibility reasons. The special value C<none> disables all
+guesswork. Otherwise, the value of this option should be a comma-separated
+list of one or more of the following keywords:
+
+=over 4
+
+=item quoting
+
+If no guesswork is enabled, any text enclosed in CZ<><> is surrounded by
+double quotes in nroff (terminal) output unless the contents are already
+quoted. When this guesswork is enabled, quote marks will also be suppressed
+for Perl variables, function names, function calls, numbers, and hex
+constants.
+
+=back
+
+Any unknown guesswork name is silently ignored (for potential future
+compatibility), so be careful about spelling.
+
=item indent
-The number of spaces to indent regular text, and the default indentation for
-C<=over> blocks. Defaults to 4.
+[2.00] The number of spaces to indent regular text, and the default
+indentation for C<=over> blocks. Defaults to 4.
=item loose
-If set to a true value, a blank line is printed after a C<=head1> heading.
-If set to false (the default), no blank line is printed after C<=head1>,
-although one is still printed after C<=head2>. This is the default because
-it's the expected formatting for manual pages; if you're formatting
+[2.00] If set to a true value, a blank line is printed after a C<=head1>
+heading. If set to false (the default), no blank line is printed after
+C<=head1>, although one is still printed after C<=head2>. This is the default
+because it's the expected formatting for manual pages; if you're formatting
arbitrary text documents, setting this to true may result in more pleasing
output.
=item margin
-The width of the left margin in spaces. Defaults to 0. This is the margin
-for all text, including headings, not the amount by which regular text is
-indented; for the latter, see the I<indent> option. To set the right
+[2.21] The width of the left margin in spaces. Defaults to 0. This is the
+margin for all text, including headings, not the amount by which regular text
+is indented; for the latter, see the I<indent> option. To set the right
margin, see the I<width> option.
=item nourls
-Normally, LZ<><> formatting codes with a URL but anchor text are formatted
-to show both the anchor text and the URL. In other words:
+[3.17] Normally, LZ<><> formatting codes with a URL but anchor text are
+formatted to show both the anchor text and the URL. In other words:
L<foo|http://example.com/>
@@ -853,74 +1014,131 @@ is formatted as:
foo <http://example.com/>
-This option, if set to a true value, suppresses the URL when anchor text
-is given, so this example would be formatted as just C<foo>. This can
-produce less cluttered output in cases where the URLs are not particularly
-important.
+This option, if set to a true value, suppresses the URL when anchor text is
+given, so this example would be formatted as just C<foo>. This can produce
+less cluttered output in cases where the URLs are not particularly important.
=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. Otherwise,
-it is split in half, and the first half of the string is used as the left
-quote and the second is used as the right quote.
+[4.00] 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. Otherwise, it
+is split in half, and the first half of the string is used as the left quote
+and the second is used 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.
=item sentence
-If set to a true value, Pod::Text will assume that each sentence ends in two
-spaces, and will try to preserve that spacing. If set to false, all
-consecutive whitespace in non-verbatim paragraphs is compressed into a
-single space. Defaults to false.
+[3.00] If set to a true value, Pod::Text will assume that each sentence ends
+in two spaces, and will try to preserve that spacing. If set to false, all
+consecutive whitespace in non-verbatim paragraphs is compressed into a single
+space. Defaults to false.
=item stderr
-Send error messages about invalid POD to standard error instead of
-appending a POD ERRORS section to the generated output. This is
-equivalent to setting C<errors> to C<stderr> if C<errors> is not already
-set. It is supported for backward compatibility.
+[3.10] Send error messages about invalid POD to standard error instead of
+appending a POD ERRORS section to the generated output. This is equivalent to
+setting C<errors> to C<stderr> if C<errors> is not already set. It is
+supported for backward compatibility.
=item utf8
-By default, Pod::Text uses the same output encoding as the input encoding
-of the POD source (provided that Perl was built with PerlIO; otherwise, it
-doesn't encode its output). If this option is given, the output encoding
-is forced to UTF-8.
-
-Be aware that, when using this option, the input encoding of your POD
-source should be properly declared unless it's US-ASCII. Pod::Simple will
-attempt to guess the encoding and may be successful if it's Latin-1 or
-UTF-8, but it will produce warnings. Use the C<=encoding> command to
-declare the encoding. See L<perlpod(1)> for more information.
+[3.12] If this option is set to a true value, the output encoding is set to
+UTF-8. This is equivalent to setting C<encoding> to C<UTF-8> if C<encoding>
+is not already set. It is supported for backward compatibility.
=item width
-The column at which to wrap text on the right-hand side. Defaults to 76.
+[2.00] The column at which to wrap text on the right-hand side. Defaults to
+76.
+
+=back
+
+=back
+
+=head1 INSTANCE METHODS
+
+As a derived class from Pod::Simple, Pod::Text supports the same methods and
+interfaces. See L<Pod::Simple> for all the details. This section summarizes
+the most-frequently-used methods and the ones added by Pod::Text.
+
+=over 4
+
+=item output_fh(FH)
+
+Direct the output from parse_file(), parse_lines(), or parse_string_document()
+to the file handle FH instead of C<STDOUT>.
+
+=item output_string(REF)
+
+Direct the output from parse_file(), parse_lines(), or parse_string_document()
+to the scalar variable pointed to by REF, rather than C<STDOUT>. For example:
+
+ my $man = Pod::Man->new();
+ my $output;
+ $man->output_string(\$output);
+ $man->parse_file('/some/input/file');
+
+Be aware that the output in that variable will already be encoded (see
+L</Encoding>).
+
+=item parse_file(PATH)
+
+Read the POD source from PATH and format it. By default, the output is sent
+to C<STDOUT>, but this can be changed with the output_fh() or output_string()
+methods.
+
+=item parse_from_file(INPUT, OUTPUT)
+
+=item parse_from_filehandle(FH, OUTPUT)
+
+Read the POD source from INPUT, format it, and output the results to OUTPUT.
+
+parse_from_filehandle() is provided for backward compatibility with older
+versions of Pod::Man. parse_from_file() should be used instead.
+
+=item parse_lines(LINES[, ...[, undef]])
+
+Parse the provided lines as POD source, writing the output to either C<STDOUT>
+or the file handle set with the output_fh() or output_string() methods. This
+method can be called repeatedly to provide more input lines. An explicit
+C<undef> should be passed to indicate the end of input.
+
+This method expects raw bytes, not decoded characters.
+
+=item parse_string_document(INPUT)
+
+Parse the provided scalar variable as POD source, writing the output to either
+C<STDOUT> or the file handle set with the output_fh() or output_string()
+methods.
+
+This method expects raw bytes, not decoded characters.
=back
-The standard Pod::Simple method parse_file() takes one argument naming the
-POD file to read from. By default, the output is sent to C<STDOUT>, but
-this can be changed with the output_fh() method.
+=head1 FUNCTIONS
-The standard Pod::Simple method parse_from_file() takes up to two
-arguments, the first being the input file to read POD from and the second
-being the file to write the formatted output to.
+Pod::Text exports one function for backward compatibility with older versions.
+This function is deprecated; instead, use the object-oriented interface
+described above.
-You can also call parse_lines() to parse an array of lines or
-parse_string_document() to parse a document already in memory. As with
-parse_file(), parse_lines() and parse_string_document() default to sending
-their output to C<STDOUT> unless changed with the output_fh() method. Be
-aware that parse_lines() and parse_string_document() both expect raw bytes,
-not decoded characters.
+=over 4
+
+=item pod2text([[-a,] [-NNN,]] INPUT[, OUTPUT])
+
+Convert the POD source from INPUT to text and write it to OUTPUT. If OUTPUT
+is not given, defaults to C<STDOUT>. INPUT can be any expression supported as
+the second argument to two-argument open().
-To put the output from any parse method into a string instead of a file
-handle, call the output_string() method instead of output_fh().
+If C<-a> is given as an initial argument, pass the C<alt> option to the
+Pod::Text constructor. This enables alternative formatting.
-See L<Pod::Simple> for more specific details on the methods available to
-all derived parsers.
+If C<-NNN> is given as an initial argument, pass the C<width> option to the
+Pod::Text constructor with the number C<NNN> as its argument. This sets the
+wrap line width to NNN.
+
+=back
=head1 DIAGNOSTICS
@@ -955,61 +1173,66 @@ option was set to C<die>.
=back
-=head1 BUGS
+=head1 COMPATIBILITY
-Encoding handling assumes that PerlIO is available and does not work
-properly if it isn't. The C<utf8> option is therefore not supported
-unless Perl is built with PerlIO support.
+Pod::Text 2.03 (based on L<Pod::Parser>) was the first version of this module
+included with Perl, in Perl 5.6.0. Earlier versions of Perl had a different
+Pod::Text module, with a different API.
-=head1 CAVEATS
+The current API based on L<Pod::Simple> was added in Pod::Text 3.00.
+Pod::Text 3.01 was included in Perl 5.9.3, the first version of Perl to
+incorporate those changes. This is the first version that correctly supports
+all modern POD syntax. The parse_from_filehandle() method was re-added for
+backward compatibility in Pod::Text 3.07, included in Perl 5.9.4.
-If Pod::Text is given the C<utf8> option, the encoding of its output file
-handle will be forced to UTF-8 if possible, overriding any existing
-encoding. This will be done even if the file handle is not created by
-Pod::Text and was passed in from outside. This maintains consistency
-regardless of PERL_UNICODE and other settings.
+Pod::Text 3.12, included in Perl 5.10.1, first implemented the current
+practice of attempting to match the default output encoding with the input
+encoding of the POD source, unless overridden by the C<utf8> option or (added
+later) the C<encoding> option.
-If the C<utf8> option is not given, the encoding of its output file handle
-will be forced to the detected encoding of the input POD, which preserves
-whatever the input text is. This ensures backward compatibility with
-earlier, pre-Unicode versions of this module, without large numbers of
-Perl warnings.
+Support for anchor text in LZ<><> links of type URL was added in Pod::Text
+3.14, included in Perl 5.11.5.
-This is not ideal, but it seems to be the best compromise. If it doesn't
-work for you, please let me know the details of how it broke.
+parse_lines(), parse_string_document(), and parse_file() set a default output
+file handle of C<STDOUT> if one was not already set as of Pod::Text 3.18,
+included in Perl 5.19.5.
-=head1 NOTES
+Pod::Text 4.00, included in Perl 5.23.7, aligned the module version and the
+version of the podlators distribution. All modules included in podlators, and
+the podlators distribution itself, share the same version number from this
+point forward.
-This is a replacement for an earlier Pod::Text module written by Tom
-Christiansen. It has a revamped interface, since it now uses Pod::Simple,
-but an interface roughly compatible with the old Pod::Text::pod2text()
-function is still available. Please change to the new calling convention,
-though.
+Pod::Text 4.09, included in Perl 5.25.7, fixed a serious bug on EBCDIC
+systems, present in all versions back to 3.00, that would cause opening
+brackets to disappear.
-The original Pod::Text contained code to do formatting via termcap
-sequences, although it wasn't turned on by default and it was problematic to
-get it to work at all. This rewrite doesn't even try to do that, but a
-subclass of it does. Look for L<Pod::Text::Termcap>.
+Pod::Text 5.00 now defaults, on non-EBCDIC systems, to UTF-8 encoding if it
+sees a non-ASCII character in the input and the input encoding is not
+specified. It also commits to an encoding with the first non-ASCII character
+and does not change the output encoding if the input encoding changes. The
+L<Encode> module is now used for all output encoding rather than PerlIO
+layers, which fixes earlier problems with output to scalars.
=head1 AUTHOR
-Russ Allbery <rra@cpan.org>, based I<very> heavily on the original
-Pod::Text by Tom Christiansen <tchrist@mox.perl.com> and its conversion to
-Pod::Parser by Brad Appleton <bradapp@enteract.com>. Sean Burke's initial
-conversion of Pod::Man to use Pod::Simple provided much-needed guidance on
-how to use Pod::Simple.
+Russ Allbery <rra@cpan.org>, based I<very> heavily on the original Pod::Text
+by Tom Christiansen <tchrist@mox.perl.com> and its conversion to Pod::Parser
+by Brad Appleton <bradapp@enteract.com>. Sean Burke's initial conversion of
+Pod::Man to use Pod::Simple provided much-needed guidance on how to use
+Pod::Simple.
=head1 COPYRIGHT AND LICENSE
-Copyright 1999-2002, 2004, 2006, 2008-2009, 2012-2016, 2018-2019 Russ Allbery
-<rra@cpan.org>
+Copyright 1999-2002, 2004, 2006, 2008-2009, 2012-2016, 2018-2019, 2022 Russ
+Allbery <rra@cpan.org>
This program is free software; you may redistribute it and/or modify it
under the same terms as Perl itself.
=head1 SEE ALSO
-L<Pod::Simple>, L<Pod::Text::Termcap>, L<perlpod(1)>, L<pod2text(1)>
+L<Encode::Locale>, L<Encode::Supproted>, L<Pod::Simple>,
+L<Pod::Text::Termcap>, L<perlpod(1)>, L<pod2text(1)>
The current version of this module is always available from its web site at
L<https://www.eyrie.org/~eagle/software/podlators/>. It is also part of the
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Color.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Color.pm
index 5d47c5ecb3..2d656d6a3d 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Color.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Color.pm
@@ -12,18 +12,15 @@
package Pod::Text::Color;
-use 5.008;
+use 5.010;
use strict;
use warnings;
use Pod::Text ();
use Term::ANSIColor qw(color colored);
-use vars qw(@ISA $VERSION);
-
-@ISA = qw(Pod::Text);
-
-$VERSION = '4.14';
+our @ISA = qw(Pod::Text);
+our $VERSION = '5.01';
##############################################################################
# Overrides
@@ -170,11 +167,22 @@ options.
Term::ANSIColor is used to get colors and therefore must be installed to use
this module.
-=head1 BUGS
+=head1 COMPATIBILITY
+
+Pod::Text::Color 0.05 (based on L<Pod::Parser>) was the first version of this
+module included with Perl, in Perl 5.6.0.
+
+The current API based on L<Pod::Simple> was added in Pod::Text::Color 2.00.
+Pod::Text::Color 2.01 was included in Perl 5.9.3, the first version of Perl to
+incorporate those changes.
+
+Several problems with wrapping and line length were fixed as recently as
+Pod::Text::Color 4.11, included in Perl 5.29.1.
-This is just a basic proof of concept. It should be seriously expanded to
-support configurable coloration via options passed to the constructor, and
-B<pod2text> should be taught about those.
+This module inherits its API and most behavior from Pod::Text, so the details
+in L<Pod::Text/COMPATIBILITY> also apply. Pod::Text and Pod::Text::Color have
+had the same module version since 4.00, included in Perl 5.23.7. (They
+unfortunately diverge in confusing ways prior to that.)
=head1 AUTHOR
@@ -182,7 +190,7 @@ Russ Allbery <rra@cpan.org>.
=head1 COPYRIGHT AND LICENSE
-Copyright 1999, 2001, 2004, 2006, 2008, 2009, 2018-2019 Russ Allbery
+Copyright 1999, 2001, 2004, 2006, 2008, 2009, 2018-2019, 2022 Russ Allbery
<rra@cpan.org>
This program is free software; you may redistribute it and/or modify it
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Overstrike.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Overstrike.pm
index 53bc6afef2..3135c8863c 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Overstrike.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Overstrike.pm
@@ -19,17 +19,14 @@
package Pod::Text::Overstrike;
-use 5.008;
+use 5.010;
use strict;
use warnings;
-use vars qw(@ISA $VERSION);
-
use Pod::Text ();
-@ISA = qw(Pod::Text);
-
-$VERSION = '4.14';
+our @ISA = qw(Pod::Text);
+our $VERSION = '5.01';
##############################################################################
# Overrides
@@ -176,6 +173,22 @@ Currently, the outermost formatting instruction wins, so for example
underlined text inside a region of bold text is displayed as simply bold.
There may be some better approach possible.
+=head1 COMPATIBILITY
+
+Pod::Text::Overstrike 1.01 (based on L<Pod::Parser>) was the first version of
+this module included with Perl, in Perl 5.6.1.
+
+The current API based on L<Pod::Simple> was added in Pod::Text::Overstrike
+2.00, included in Perl 5.9.3.
+
+Several problems with wrapping and line length were fixed as recently as
+Pod::Text::Overstrike 2.04, included in Perl 5.11.5.
+
+This module inherits its API and most behavior from Pod::Text, so the details
+in L<Pod::Text/COMPATIBILITY> also apply. Pod::Text and Pod::Text::Overstrike
+have had the same module version since 4.00, included in Perl 5.23.7. (They
+unfortunately diverge in confusing ways prior to that.)
+
=head1 AUTHOR
Originally written by Joe Smith <Joe.Smith@inwap.com>, using the framework
@@ -185,7 +198,7 @@ created by Russ Allbery <rra@cpan.org>. Subsequently updated by Russ Allbery.
Copyright 2000 by Joe Smith <Joe.Smith@inwap.com>
-Copyright 2001, 2004, 2008, 2014, 2018-2019 by Russ Allbery <rra@cpan.org>
+Copyright 2001, 2004, 2008, 2014, 2018-2019, 2022 by Russ Allbery <rra@cpan.org>
This program is free software; you may redistribute it and/or modify it
under the same terms as Perl itself.
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Termcap.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Termcap.pm
index be218f0bf0..d4b74874d8 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Termcap.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Text/Termcap.pm
@@ -12,7 +12,7 @@
package Pod::Text::Termcap;
-use 5.008;
+use 5.010;
use strict;
use warnings;
@@ -20,11 +20,8 @@ use Pod::Text ();
use POSIX ();
use Term::Cap;
-use vars qw(@ISA $VERSION);
-
-@ISA = qw(Pod::Text);
-
-$VERSION = '4.14';
+our @ISA = qw(Pod::Text);
+our $VERSION = '5.01';
##############################################################################
# Overrides
@@ -204,13 +201,13 @@ sub wrap {
1;
__END__
+=for stopwords
+ECMA-48 VT100 Allbery Solaris TERMPATH unformatted
+
=head1 NAME
Pod::Text::Termcap - Convert POD data to ASCII text with format escapes
-=for stopwords
-ECMA-48 VT100 Allbery Solaris TERMPATH
-
=head1 SYNOPSIS
use Pod::Text::Termcap;
@@ -235,14 +232,37 @@ and how to override that behavior if necessary. If unable to find control
strings for bold and underscore formatting, that formatting is skipped,
resulting in the same output as Pod::Text.
+=head1 COMPATIBILITY
+
+Pod::Text::Termcap 0.04 (based on L<Pod::Parser>) was the first version of
+this module included with Perl, in Perl 5.6.0.
+
+The current API based on L<Pod::Simple> was added in Pod::Text::Termcap 2.00.
+Pod::Text::Termcap 2.01 was included in Perl 5.9.3, the first version of Perl
+to incorporate those changes.
+
+Several problems with wrapping and line length were fixed as recently as
+Pod::Text::Termcap 4.11, included in Perl 5.29.1.
+
+Pod::Text::Termcap 4.13 stopped setting the TERMPATH environment variable
+during module load. It also stopped falling back on VT100 escape sequences if
+Term::Cap was not able to find usable escape sequences, instead producing
+unformatted output for better results on dumb terminals. The next version to
+be incorporated into Perl, 4.14, was included in Perl 5.31.8.
+
+This module inherits its API and most behavior from Pod::Text, so the details
+in L<Pod::Text/COMPATIBILITY> also apply. Pod::Text and Pod::Text::Termcap
+have had the same module version since 4.00, included in Perl 5.23.7. (They
+unfortunately diverge in confusing ways prior to that.)
+
=head1 AUTHOR
Russ Allbery <rra@cpan.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 1999, 2001-2002, 2004, 2006, 2008-2009, 2014-2015, 2018-2019 Russ
-Allbery <rra@cpan.org>
+Copyright 1999, 2001-2002, 2004, 2006, 2008-2009, 2014-2015, 2018-2019, 2022
+Russ Allbery <rra@cpan.org>
This program is free software; you may redistribute it and/or modify it
under the same terms as Perl itself.
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Usage.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Usage.pm
index c290f2baf1..0ed3a60315 100644
--- a/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Usage.pm
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Pod/Usage.pm
@@ -18,7 +18,7 @@ use Config;
use Exporter;
use File::Spec;
-our $VERSION = '2.01';
+our $VERSION = '2.03';
our @EXPORT = qw(&pod2usage);
our @ISA;