summaryrefslogtreecommitdiff
path: root/cpan/podlators
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2022-12-06 22:40:57 +0000
committerJames E Keenan <jkeenan@cpan.org>2022-12-09 10:43:28 -0500
commit20616d517ad4726a85ee27750db6e24443343601 (patch)
tree81ce700b789f108c04517c90af38b78338fe86ae /cpan/podlators
parent85900e28cc250e1c4603f11073b77d0c6b5cff46 (diff)
downloadperl-20616d517ad4726a85ee27750db6e24443343601.tar.gz
Update podlators to CPAN version 5.00
5.00 - 2022-11-25: Changes Drop support for Perl 5.8. The minimum required version is Perl 5.10. The default output encoding of Pod::Man on non-EBCDIC systems is now UTF-8. The utf8 option (-u or --utf8 to pod2man) is now ignored, since it is the default. See the ENCODING section of its documentation for testing results and further discussion. (#68741) Pod::Man now supports an encoding option (-e or --encoding to pod2man), to change the output encoding to any encoding recognized by Encode, or the special values groff or roff. Setting it to roff requests the old behavior of using character substitutions and *roff escapes to generate ASCII-only output (the default prior to this version). Pod::Man now supports the groff output encoding, which replaces all non-ASCII characters with \[uNNNN] escapes. This escape was not supported by the originally *roff implementation, but it is supported by groff and mandoc and allows proper representation of Unicode characters. This output format has no known advantages in portability over UTF-8 on non-EBCDIC systems. It is the default output format on EBCDIC systems, and when the Encode module is not available. (#73804) Pod::Man no longer does guesswork transformations that only affected troff output. Formatting manual pages with troff is exceptionally rare, and this magic caused constant maintenance issues. This means "--" is no longer changed to an em-dash, strings of capital letters aren't made a bit smaller, no attempt is made to change double quotes to paired quotes, and no special formatting is done for C++. (#132007) Guesswork (formatting rules based on heuristics intended for Perl documentation) can now be disabled or selectively enabled in Pod::Man with the guesswork option (--guessword to pod2man). (#143668) Pod::Text now supports an encoding option (-e or --encoding to pod2text) to force the output encoding, similar to Pod::Man. The utf8 option (-u or --utf8 to pod2text) is still supported and is equivalent to setting encoding to UTF-8. Pod::Text now defaults to UTF-8 encoding if it sees a non-ASCII character on a non-EBCDIC system and the input encoding is not specified. This should fix rendering of E<> escapes of non-ASCII characters in POD files that don't specify an input encoding, at the cost of assuming UTF-8 output. Pod::Text also now commits to an encoding the first time it outputs a non-ASCII character and sticks with that encoding for the rest of the file, even if the detected or declared input encoding changes. (#102631) Stop using a PerlIO encoding layer for Pod::Text output and instead use Encode. If a PerlIO encoding layer is already set, trust it and do no encoding. This fixes encoding problems with output to a string. Add a coding tag comment to the start of Pod::Man output if the output encoding is not ASCII. groff's preconv program and FreeBSD's mandoc will use this line to determine the input encoding. Pod::Man now supports a language option (--language to pod2man) that adds groff language configuration commands to the start of the output. This is required for proper line breaking of Japanese and Chinese text when the manual page is not installed in a language-specific directory so that the man program knows to add that configuration automatically. Unfortunately, the commands added when this option is used are groff-specific. Thanks to zynldyx for the bug report and suggested fix. Pod::Man now converts Unicode zero-width spaces (U+200B) to the *roff escape \:, which indicates a line break point without a space or hyphen. (Unfortunately, groff does not honor U+200B itself as a line break point.) This escape is not part of the language defined in CSTR this escape won't cause problems. (Debian Bug#941980) Pod::Man and Pod::Text now correctly honor S<> wrapping L<> with an anchor and URL, and make the space between the anchor and URL nonbreaking. (#143768) Clear the current font before changing fonts in all Pod::Man output, not just headings. groff 1.22.4 does not clear bold or italic when seeing \f(CW font change, which meant bold and italic were extending farther than they should without this change. (#143667) Honor the quotes, lquote, and rquote configuration parameters to Pod::Man for C<> text inside the special NAME section. (#143967) Pod::Man suppresses quote marks around some additional cases of Perl code in C<> where the intent had been to suppress the quotes but there were various bugs in the matching regular expressions. This primarily affects method calls and negative numbers. Avoid non-standard *roff escape in the troff accent mark definition for an acute accent. \h"..." was used instead of \h'...' as seen in the other accent mark definitions. This error appears to have existed since the first version of Pod::Man. Thanks, Paul Evans. (GitHub #14) Document that nroff adds two spaces after each sentence when reflowing, and therefore if you want formatted Pod::Man output to consistently have one space after each sentence, you will have to avoid ending a sentence at the end of a line in the middle of a paragraph. Committer: Adjust Porting/Maintainers.pl and Porting/sync-with-cpan to reflect upstream acceptance of customizations in core distribution.
Diffstat (limited to 'cpan/podlators')
-rw-r--r--cpan/podlators/Makefile.PL6
-rw-r--r--cpan/podlators/docs/docknot.yaml144
-rw-r--r--cpan/podlators/lib/Pod/Man.pm1328
-rw-r--r--cpan/podlators/lib/Pod/ParseLink.pm12
-rw-r--r--cpan/podlators/lib/Pod/Text.pm492
-rw-r--r--cpan/podlators/lib/Pod/Text/Color.pm30
-rw-r--r--cpan/podlators/lib/Pod/Text/Overstrike.pm27
-rw-r--r--cpan/podlators/lib/Pod/Text/Termcap.pm42
-rw-r--r--cpan/podlators/scripts/pod2man.PL383
-rw-r--r--cpan/podlators/scripts/pod2text.PL199
-rw-r--r--cpan/podlators/t/data/basic.man50
-rw-r--r--cpan/podlators/t/data/man/encoding.groff87
-rw-r--r--cpan/podlators/t/data/man/encoding.pod30
-rw-r--r--cpan/podlators/t/data/man/encoding.roff149
-rw-r--r--cpan/podlators/t/data/man/encoding.utf888
-rw-r--r--cpan/podlators/t/data/perl.conf2
-rw-r--r--cpan/podlators/t/data/regenerate-data108
-rw-r--r--cpan/podlators/t/data/snippets/README.md (renamed from cpan/podlators/t/data/snippets/README)16
-rw-r--r--cpan/podlators/t/data/snippets/man/agrave3
-rw-r--r--cpan/podlators/t/data/snippets/man/cpp6
-rw-r--r--cpan/podlators/t/data/snippets/man/dollar-magic8
-rw-r--r--cpan/podlators/t/data/snippets/man/eth3
-rw-r--r--cpan/podlators/t/data/snippets/man/fixed-font2
-rw-r--r--cpan/podlators/t/data/snippets/man/fixed-font-in-item16
-rw-r--r--cpan/podlators/t/data/snippets/man/guesswork24
-rw-r--r--cpan/podlators/t/data/snippets/man/guesswork-all27
-rw-r--r--cpan/podlators/t/data/snippets/man/guesswork-no-quoting57
-rw-r--r--cpan/podlators/t/data/snippets/man/guesswork-none27
-rw-r--r--cpan/podlators/t/data/snippets/man/guesswork-partial27
-rw-r--r--cpan/podlators/t/data/snippets/man/guesswork-quoting54
-rw-r--r--cpan/podlators/t/data/snippets/man/hyphen-in-s2
-rw-r--r--cpan/podlators/t/data/snippets/man/iso-8859-113
-rw-r--r--cpan/podlators/t/data/snippets/man/iso-8859-1-error-die30
-rw-r--r--cpan/podlators/t/data/snippets/man/iso-8859-1-error-pod29
-rw-r--r--cpan/podlators/t/data/snippets/man/iso-8859-1-roff31
-rw-r--r--cpan/podlators/t/data/snippets/man/language19
-rw-r--r--cpan/podlators/t/data/snippets/man/link-to-url2
-rw-r--r--cpan/podlators/t/data/snippets/man/naive14
-rw-r--r--cpan/podlators/t/data/snippets/man/naive-groff17
-rw-r--r--cpan/podlators/t/data/snippets/man/name-guesswork10
-rw-r--r--cpan/podlators/t/data/snippets/man/name-quotes15
-rw-r--r--cpan/podlators/t/data/snippets/man/name-quotes-none14
-rw-r--r--cpan/podlators/t/data/snippets/man/non-ascii3
-rw-r--r--cpan/podlators/t/data/snippets/man/nonbreaking-space-l28
-rw-r--r--cpan/podlators/t/data/snippets/man/paired-quotes20
-rw-r--r--cpan/podlators/t/data/snippets/man/small-caps-magic12
-rw-r--r--cpan/podlators/t/data/snippets/man/true-false2
-rw-r--r--cpan/podlators/t/data/snippets/man/uppercase-license48
-rw-r--r--cpan/podlators/t/data/snippets/man/utf8-nonbreaking4
-rw-r--r--cpan/podlators/t/data/snippets/man/zero-width-space10
-rw-r--r--cpan/podlators/t/data/snippets/text/iso-8859-1-error-die29
-rw-r--r--cpan/podlators/t/data/snippets/text/iso-8859-1-error-pod29
-rw-r--r--cpan/podlators/t/data/snippets/text/iso-8859-1-utf828
-rw-r--r--cpan/podlators/t/data/snippets/text/naive13
-rw-r--r--cpan/podlators/t/data/snippets/text/name-quotes14
-rw-r--r--cpan/podlators/t/data/snippets/text/name-quotes-none14
-rw-r--r--cpan/podlators/t/data/snippets/text/non-latin30
-rw-r--r--cpan/podlators/t/data/snippets/text/nonbreaking-space-l27
-rw-r--r--cpan/podlators/t/docs/changes.t47
-rw-r--r--cpan/podlators/t/docs/pod-spelling.t13
-rw-r--r--cpan/podlators/t/docs/pod.t13
-rw-r--r--cpan/podlators/t/docs/spdx-license.t35
-rw-r--r--cpan/podlators/t/docs/synopsis.t4
-rw-r--r--cpan/podlators/t/general/basic.t20
-rw-r--r--cpan/podlators/t/lib/Test/Podlators.pm84
-rw-r--r--cpan/podlators/t/lib/Test/RRA.pm28
-rw-r--r--cpan/podlators/t/lib/Test/RRA/Config.pm22
-rw-r--r--cpan/podlators/t/lib/Test/RRA/ModuleVersion.pm20
-rw-r--r--cpan/podlators/t/man/empty.t6
-rw-r--r--cpan/podlators/t/man/encoding.t81
-rw-r--r--cpan/podlators/t/man/iso-8859-1.t38
-rw-r--r--cpan/podlators/t/man/no-encode.t79
-rw-r--r--cpan/podlators/t/man/snippets.t22
-rw-r--r--cpan/podlators/t/man/utf8-io.t4
-rw-r--r--cpan/podlators/t/style/minimum-version.t4
-rw-r--r--cpan/podlators/t/style/module-version.t14
-rw-r--r--cpan/podlators/t/style/obsolete-strings.t6
-rw-r--r--cpan/podlators/t/style/strict.t6
-rw-r--r--cpan/podlators/t/text/invalid.t5
-rw-r--r--cpan/podlators/t/text/iso-8859-1.t33
-rw-r--r--cpan/podlators/t/text/snippets.t7
-rw-r--r--cpan/podlators/t/text/utf8-io.t4
82 files changed, 3332 insertions, 1217 deletions
diff --git a/cpan/podlators/Makefile.PL b/cpan/podlators/Makefile.PL
index ff76df5f9f..93fcd4f9d9 100644
--- a/cpan/podlators/Makefile.PL
+++ b/cpan/podlators/Makefile.PL
@@ -4,7 +4,7 @@
# which only supports that build method, and because it is a dependency of
# other build systems like Module::Build.
#
-# Copyright 1999-2001, 2008, 2010, 2012, 2014-2016, 2018-2019
+# Copyright 1999-2001, 2008, 2010, 2012, 2014-2016, 2018-2019, 2022
# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
@@ -30,7 +30,7 @@ sub dist_version {
open(my $fh, '<', File::Spec->catfile('lib', 'Pod', 'Man.pm'))
or die "$0: cannot open lib/Pod/Man.pm: $!\n";
while (defined(my $line = <$fh>)) {
- if ($line =~ m{ \A \$VERSION \s+ = \s+ '([^\']+)' }xms) {
+ if ($line =~ m{ \A (?:our \s+)? \$VERSION \s+ = \s+ '([^\']+)' }xms) {
close($fh) or die "$0: cannot close lib/Pod/Man.pm\n";
return $1;
}
@@ -89,7 +89,7 @@ my %metadata = (
LICENSE => 'perl_5',
EXE_FILES => [scripts('pod2text', 'pod2man')],
VERSION_FROM => 'lib/Pod/Man.pm',
- MIN_PERL_VERSION => '5.008',
+ MIN_PERL_VERSION => '5.010',
# Use *.PL files to generate the driver scripts so that we get the correct
# invocation of Perl on non-UNIX platforms.
diff --git a/cpan/podlators/docs/docknot.yaml b/cpan/podlators/docs/docknot.yaml
new file mode 100644
index 0000000000..4dcb50e2da
--- /dev/null
+++ b/cpan/podlators/docs/docknot.yaml
@@ -0,0 +1,144 @@
+# Package metadata for podlators.
+#
+# This file contains configuration for DocKnot used to generate
+# documentation files (like README.md) and web pages. Other documentation
+# in this package is generated automatically from these files as part of
+# the release process. For more information, see DocKnot's documentation.
+#
+# DocKnot is available from <https://www.eyrie.org/~eagle/software/docknot/>.
+#
+# Copyright 1999-2010, 2012-2022 Russ Allbery <rra@cpan.org>
+#
+# SPDX-License-Identifier: MIT
+
+format: v1
+
+name: podlators
+maintainer: Russ Allbery <rra@cpan.org>
+version: '5.00'
+synopsis: format POD source into various output formats
+
+license:
+ name: Perl
+copyrights:
+ - holder: Russ Allbery <rra@cpan.org>
+ years: 1999-2010, 2012-2022
+
+build:
+ type: ExtUtils::MakeMaker
+distribution:
+ cpan: podlators
+ section: perl
+ tarname: podlators
+ version: podlators
+support:
+ email: rra@cpan.org
+ github: rra/podlators
+ web: https://www.eyrie.org/~eagle/software/podlators/
+vcs:
+ browse: https://git.eyrie.org/?p=perl/podlators.git
+ github: rra/podlators
+ openhub: https://www.openhub.net/p/podlators
+ status:
+ workflow: build
+ type: Git
+ url: https://git.eyrie.org/git/perl/podlators.git
+
+quote:
+ author: Robert Fripp
+ text: |
+ We move from making unnecessary efforts, the exertions of force, to making
+ necessary efforts: the direction of effortlessness. In this the prime
+ maxim is: honor necessity, honor sufficiency.
+ work: '"The Road to Graceland"'
+docs:
+ api:
+ - name: pod-man
+ title: Pod::Man
+ - name: pod-text
+ title: Pod::Text
+ - name: pod-text-color
+ title: Pod::Text::Color
+ - name: pod-text-overstrike
+ title: Pod::Text::Overstrike
+ - name: pod-text-termcap
+ title: Pod::Text::Termcap
+ developer:
+ - name: todo
+ title: To-do list
+ user:
+ - name: perlpodstyle
+ title: POD style guide
+ - name: pod2man
+ title: pod2man documentation
+ - name: pod2text
+ title: pod2text documentation
+ - name: thanks
+ title: Thanks and credits
+
+blurb: |
+ podlators contains Pod::Man and Pod::Text modules which convert POD input to
+ *roff source output, suitable for man pages, or plain text. It also
+ includes several subclasses of Pod::Text for formatted output to terminals
+ with various capabilities. It is the source package for the Pod::Man and
+ Pod::Text modules included with Perl.
+
+description: |
+ POD is the Plain Old Documentation format, the documentation language used
+ for all of Perl's documentation. I learned it to document Perl modules,
+ started using it for Perl scripts as well, and discovered it was the most
+ convenient way I've found to write program documentation. It's extremely
+ simple, well-designed for writing Unix manual pages (and I'm a
+ traditionalist who thinks that any program should have a regular manual
+ page), and easily readable in the raw format by humans.
+
+ The translators into text and nroff (for manual pages) included in the Perl
+ distribution had various bugs, however, and used their own ad hoc parsers,
+ so when I started running into those bugs and when a new generic parser
+ (Pod::Parser) was written, I decided to rewrite the two translators that I
+ use the most and fix the bugs that were bothering me. This package is the
+ result.
+
+ podlators contains two main modules, Pod::Man and Pod::Text. The former
+ converts POD into nroff/troff source and the latter into plain text (with
+ various options controlling some of the formatting). There are also several
+ subclasses of Pod::Text for generating slightly formatted text using color
+ or other terminal control escapes, and a general utility module,
+ Pod::ParseLink, for parsing the POD `L<>` formatting sequences. Also
+ included in this package are the `pod2text` and `pod2man` driver scripts.
+
+ Both Pod::Text and Pod::Man provide a variety of options for fine-tuning
+ their output. Pod::Man also tries to massage input text where appropriate
+ to produce better output when run through nroff or troff, such as
+ distinguishing between different types of hyphens.
+
+ As of Perl 5.6.0, my implementation was included in Perl core, and each
+ release of Perl will have the at-the-time most current version of podlators
+ included. You therefore only need to install this package yourself if you
+ need a newer version than came with Perl (to get some bug fixes, for
+ example).
+
+requirements: |
+ This module requires Perl 5.10 or later.
+
+ The troff/nroff generated by Pod::Man should be compatible with any troff or
+ nroff implementation with the `-man` macro set, including mandoc. It is
+ primarily tested by me under GNU groff, but Perl users send bug reports for
+ a wide variety of implementations and Pod::Man is used to generate all of
+ Perl's own manual pages, so hopefully most of the bugs have been weeded out.
+
+test:
+ lancaster: true
+ suffix: |
+ The following additional Perl modules will be used by the test suite if
+ present:
+
+ * Test::CPAN::Changes (part of CPAN-Changes)
+ * Test::MinimumVersion
+ * Test::Pod
+ * Test::Spelling
+ * Test::Strict
+ * Test::Synopsis
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
diff --git a/cpan/podlators/lib/Pod/Man.pm b/cpan/podlators/lib/Pod/Man.pm
index d7c029357a..57be69f600 100644
--- a/cpan/podlators/lib/Pod/Man.pm
+++ b/cpan/podlators/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.00';
+
+# 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
@@ -57,9 +54,9 @@ 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 +72,84 @@ 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
+##############################################################################
+
+# 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 +163,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 +181,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;
}
@@ -183,7 +276,7 @@ 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{$_};
+ 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");
}
@@ -192,19 +285,19 @@ sub init_fonts {
# 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}) };
+ '100' => toescape ($self->{opt_fixed}),
+ '101' => toescape ($self->{opt_fixeditalic}),
+ '110' => toescape ($self->{opt_fixedbold}),
+ '111' => toescape ($self->{opt_fixedbolditalic}) };
}
# Initialize the quotes that we'll be using for C<> text. This requires some
@@ -215,25 +308,27 @@ 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
@@ -254,16 +349,13 @@ 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};
+ $self->{opt_center} //= 'User Contributed Perl Documentation';
+ $self->{opt_release} //= 'perl v' . $version;
+ $self->{opt_indent} //= 4;
# Double quotes in things that will be quoted.
for (qw/center release/) {
- $$self{$_} =~ s/\"/\"\"/g if $$self{$_};
+ $self->{"opt_$_"} =~ s/\"/\"\"/g if $self->{"opt_$_"};
}
}
@@ -289,7 +381,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 +399,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 +406,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 +417,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 +427,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 +443,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 +461,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 +509,47 @@ 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}) {
+ my $lquote = $$self{LQUOTE} eq '""' ? '"' : $$self{LQUOTE};
+ my $rquote = $$self{RQUOTE} eq '""' ? '"' : $$self{RQUOTE};
+ return $lquote . $_ . $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 +558,9 @@ 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 or
+# textmapfonts.
#
# 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 +568,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 +578,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 +589,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 +610,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 +634,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 $_;
}
@@ -608,9 +664,9 @@ sub mapfonts {
my ($fixed, $bold, $italic) = (0, 0, 0);
my %magic = (F => \$fixed, B => \$bold, I => \$italic);
my $last = '\fR';
- $text =~ s<
+ $text =~ s{
\\f\((.)(.)
- > <
+ }{
my $sequence = '';
my $f;
if ($last ne '\fR') { $sequence = '\fP' }
@@ -623,25 +679,46 @@ sub mapfonts {
$last = $f;
$sequence;
}
- >gxe;
+ }gxe;
return $text;
}
# 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.
+# around this, use a separate textmapfonts for text blocks that uses \fR
+# instead of \fP.
+#
+# Originally, this function was much simpler 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 default before each font change.
sub textmapfonts {
my ($self, $text) = @_;
my ($fixed, $bold, $italic) = (0, 0, 0);
my %magic = (F => \$fixed, B => \$bold, I => \$italic);
- $text =~ s<
+ my $last = '\fR';
+ $text =~ s{
\\f\((.)(.)
- > <
+ }{
+ my $sequence = q{};
+ if ($last ne '\fR') { $sequence = '\fR' }
${ $magic{$1} } += ($2 eq 'S') ? 1 : -1;
- $$self{FONTS}{ ($fixed && 1) . ($bold && 1) . ($italic && 1) };
- >gxe;
+ my $f = $$self{FONTS}{ ($fixed && 1) . ($bold && 1) . ($italic && 1) };
+ if ($f eq $last) {
+ '';
+ } else {
+ if ($f ne '\fR') { $sequence .= $f }
+ $last = $f;
+ $sequence;
+ }
+ }gxe;
+
+ # 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;
+
return $text;
}
@@ -761,10 +838,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 +866,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 +894,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 +927,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 +935,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,7 +1068,7 @@ 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";
@@ -1000,7 +1087,7 @@ sub preamble {
$date =~ s/\"/\"\"/g;
# Substitute into the preamble the configuration options.
- $preamble =~ s/\@CFONT\@/$$self{fixed}/;
+ $preamble =~ s/\@CFONT\@/$self->{opt_fixed}/;
$preamble =~ s/\@LQUOTE\@/$$self{LQUOTE}/;
$preamble =~ s/\@RQUOTE\@/$$self{RQUOTE}/;
chomp $preamble;
@@ -1008,7 +1095,24 @@ sub preamble {
# Get the version information.
my $version = $self->version_report;
- # Finally output everything.
+ # 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 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});
+ }
+ }
+
+ # Output the majority of the preamble.
$self->output (<<"----END OF HEADER----");
.\\" Automatically generated by $version
.\\"
@@ -1018,13 +1122,18 @@ $preamble
.\\" ========================================================================
.\\"
.IX Title "$index"
-.TH $name $section "$date" "$$self{release}" "$$self{center}"
+.TH $name $section "$date" "$self->{opt_release}" "$self->{opt_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 +1158,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
@@ -1136,9 +1240,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;
}
@@ -1203,6 +1304,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 +1332,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 +1353,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 +1385,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 +1423,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
@@ -1448,48 +1552,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 +1575,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 +1614,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 +1644,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 +1691,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 +1723,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 +1921,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 +1950,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 +1965,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
-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.
+=back
+
+=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');
+
+Be aware that the output in that variable will already be encoded in UTF-8.
+
+=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)
-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.
+Read the POD source from INPUT, format it, and output the results to OUTPUT.
-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.
+parse_from_filehandle() is provided for backward compatibility with older
+versions of Pod::Man. parse_from_file() should be used instead.
-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().
+=item parse_lines(LINES[, ...[, undef]])
-See L<Pod::Simple> for more specific details on the methods available to
-all derived parsers.
+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 +2252,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 +2283,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.
+
+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.
-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 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.
-Pod::Man is excessively slow.
+=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
-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.
+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.
-When and whether to use small caps is somewhat tricky, and Pod::Man doesn't
-necessarily get it right.
+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:
-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.
+ =pod
+
+ One sentence.
+ Another sentence.
+
+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.
+
+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 +2389,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/cpan/podlators/lib/Pod/ParseLink.pm b/cpan/podlators/lib/Pod/ParseLink.pm
index 273c95847a..c4220a8d65 100644
--- a/cpan/podlators/lib/Pod/ParseLink.pm
+++ b/cpan/podlators/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.00';
##############################################################################
# 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/cpan/podlators/lib/Pod/Text.pm b/cpan/podlators/lib/Pod/Text.pm
index 56e6e78a86..85b4e53c51 100644
--- a/cpan/podlators/lib/Pod/Text.pm
+++ b/cpan/podlators/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.00';
# 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} ||= '"';
@@ -272,9 +275,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 +285,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 +347,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 +402,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 +606,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.
@@ -766,7 +791,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 +810,152 @@ 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
+
+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)
-new() can take options, in the form of key/value pairs, that control the
-behavior of the parser. The currently recognized options are:
+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 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 +963,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
-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.
+=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)
-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.
+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.
-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_from_file(INPUT, OUTPUT)
-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().
+=item parse_from_filehandle(FH, OUTPUT)
-See L<Pod::Simple> for more specific details on the methods available to
-all derived parsers.
+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 FUNCTIONS
+
+Pod::Text exports one function for backward compatibility with older versions.
+This function is deprecated; instead, use the object-oriented interface
+described above.
+
+=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().
+
+If C<-a> is given as an initial argument, pass the C<alt> option to the
+Pod::Text constructor. This enables alternative formatting.
+
+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 +1122,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/cpan/podlators/lib/Pod/Text/Color.pm b/cpan/podlators/lib/Pod/Text/Color.pm
index 5d47c5ecb3..b340c5030c 100644
--- a/cpan/podlators/lib/Pod/Text/Color.pm
+++ b/cpan/podlators/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.00';
##############################################################################
# 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/cpan/podlators/lib/Pod/Text/Overstrike.pm b/cpan/podlators/lib/Pod/Text/Overstrike.pm
index 53bc6afef2..a06f46feb6 100644
--- a/cpan/podlators/lib/Pod/Text/Overstrike.pm
+++ b/cpan/podlators/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.00';
##############################################################################
# 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/cpan/podlators/lib/Pod/Text/Termcap.pm b/cpan/podlators/lib/Pod/Text/Termcap.pm
index be218f0bf0..1a13a8e1b6 100644
--- a/cpan/podlators/lib/Pod/Text/Termcap.pm
+++ b/cpan/podlators/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.00';
##############################################################################
# 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/cpan/podlators/scripts/pod2man.PL b/cpan/podlators/scripts/pod2man.PL
index d6e685d201..5b89980c75 100644
--- a/cpan/podlators/scripts/pod2man.PL
+++ b/cpan/podlators/scripts/pod2man.PL
@@ -38,7 +38,7 @@ print "Extracting $file (with variable substitutions)\n";
print {$out} <<"PREAMBLE" or die "Cannot write to $file: $!\n";
$Config{startperl}
eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
- if \$running_under_some_shell;
+ if 0; # ^ Run only under a shell
PREAMBLE
# In the following, Perl variables are not expanded during extraction.
@@ -72,11 +72,11 @@ my $stdin;
# allowing short forms as well. --lax is currently ignored.
my %options;
Getopt::Long::config ('bundling_override');
-GetOptions (\%options, 'center|c=s', 'date|d=s', 'errors=s', 'fixed=s',
- 'fixedbold=s', 'fixeditalic=s', 'fixedbolditalic=s', 'help|h',
- 'lax|l', 'lquote=s', 'name|n=s', 'nourls', 'official|o',
- 'quotes|q=s', 'release|r=s', 'rquote=s', 'section|s=s', 'stderr',
- 'verbose|v', 'utf8|u')
+GetOptions (\%options, 'center|c=s', 'date|d=s', 'encoding|e=s', 'errors=s',
+ 'fixed=s', 'fixedbold=s', 'fixeditalic=s', 'fixedbolditalic=s',
+ 'guesswork=s', 'help|h', 'lax|l', 'language=s', 'lquote=s',
+ 'name|n=s', 'nourls', 'official|o', 'quotes|q=s', 'release|r=s',
+ 'rquote=s', 'section|s=s', 'stderr', 'verbose|v', 'utf8|u')
or exit 1;
pod2usage (0) if $options{help};
@@ -128,7 +128,7 @@ __END__
=for stopwords
en em --stderr stderr --utf8 UTF-8 overdo markup MT-LEVEL Allbery Solaris URL
troff troff-specific formatters uppercased Christiansen --nourls UTC prepend
-lquote rquote
+lquote rquote unrepresentable mandoc manref EBCDIC
=head1 NAME
@@ -136,10 +136,12 @@ pod2man - Convert POD data to formatted *roff input
=head1 SYNOPSIS
-pod2man [B<--center>=I<string>] [B<--date>=I<string>] [B<--errors>=I<style>]
- [B<--fixed>=I<font>] [B<--fixedbold>=I<font>] [B<--fixeditalic>=I<font>]
- [B<--fixedbolditalic>=I<font>] [B<--name>=I<name>] [B<--nourls>]
- [B<--official>] [B<--release>=I<version>] [B<--section>=I<manext>]
+pod2man [B<--center>=I<string>] [B<--date>=I<string>]
+ [B<--encoding>=I<encoding>] [B<--errors>=I<style>] [B<--fixed>=I<font>]
+ [B<--fixedbold>=I<font>] [B<--fixeditalic>=I<font>]
+ [B<--fixedbolditalic>=I<font>] [B<--guesswork>=I<rule>[,I<rule>...]
+ [B<--name>=I<name>] [B<--nourls>] [B<--official>]
+ [B<--release>=I<version>] [B<--section>=I<manext>]
[B<--quotes>=I<quotes>] [B<--lquote>=I<quote>] [B<--rquote>=I<quote>]
[B<--stderr>] [B<--utf8>] [B<--verbose>] [I<input> [I<output>] ...]
@@ -147,107 +149,208 @@ pod2man B<--help>
=head1 DESCRIPTION
-B<pod2man> is a front-end for Pod::Man, using it to generate *roff input
-from POD source. The resulting *roff code is suitable for display on a
-terminal using nroff(1), normally via man(1), or printing using troff(1).
-
-I<input> is the file to read for POD source (the POD can be embedded in
-code). If I<input> isn't given, it defaults to C<STDIN>. I<output>, if
-given, is the file to which to write the formatted output. If I<output>
-isn't given, the formatted output is written to C<STDOUT>. Several POD
-files can be processed in the same B<pod2man> invocation (saving module
-load and compile times) by providing multiple pairs of I<input> and
-I<output> files on the command line.
-
-B<--section>, B<--release>, B<--center>, B<--date>, and B<--official> can
-be used to set the headers and footers to use; if not given, Pod::Man will
-assume various defaults. See below or L<Pod::Man> for details.
-
-B<pod2man> assumes that your *roff formatters have a fixed-width font
-named C<CW>. If yours is called something else (like C<CR>), use
-B<--fixed> 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, and therefore pod2man also
-takes care of formatting func(), func(n), 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," and
-takes care of several other troff-specific tweaks. See L<Pod::Man> for
-complete information.
+B<pod2man> is a wrapper script around the L<Pod::Man> module, using it to
+generate *roff input from POD source. The resulting *roff code is suitable
+for display on a terminal using L<nroff(1)>, normally via L<man(1)>, or
+printing using L<troff(1)>.
+
+By default (on non-EBCDIC systems), B<pod2man> outputs UTF-8 manual pages.
+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, use C<--encoding=roff>
+(the default in earlier Pod::Man versions). See the B<--encoding> option and
+L<Pod::Man/ENCODING> for more details.
+
+I<input> is the file to read for POD source (the POD can be embedded in code).
+If I<input> isn't given, it defaults to C<STDIN>. I<output>, if given, is the
+file to which to write the formatted output. If I<output> isn't given, the
+formatted output is written to C<STDOUT>. Several POD files can be processed
+in the same B<pod2man> invocation (saving module load and compile times) by
+providing multiple pairs of I<input> and I<output> files on the command line.
+
+B<--section>, B<--release>, B<--center>, B<--date>, and B<--official> can be
+used to set the headers and footers to use. If not given, Pod::Man will
+assume various defaults. See below for details.
=head1 OPTIONS
+Each option is annotated with the version of podlators in which that option
+was added with its current meaning.
+
=over 4
=item B<-c> I<string>, B<--center>=I<string>
-Sets the centered page header for the C<.TH> macro to I<string>. The
-default is "User Contributed Perl Documentation", but also see
-B<--official> below.
+[1.00] Sets the centered page header for the C<.TH> macro to I<string>. The
+default is C<User Contributed Perl Documentation>, but also see B<--official>
+below.
=item B<-d> I<string>, B<--date>=I<string>
-Set the left-hand footer string for the C<.TH> macro to I<string>. By
-default, the modification date of the input file will be used, or the
-current date if input comes from C<STDIN>, and will be based on UTC (so
-that the output will be reproducible regardless of local time zone).
+[4.00] Set the left-hand footer string for the C<.TH> macro to I<string>. By
+default, the first of POD_MAN_DATE, SOURCE_DATE_EPOCH, the modification date
+of the input file, or the current date (if input comes from C<STDIN>) will be
+used, and the date will be in UTC. See L<Pod::Man/CLASS METHODS> for more
+details.
+
+=item B<-e> I<encoding>, B<--encoding>=I<encoding>
+
+[5.00] Specifies the encoding of the output. I<encoding> must be an encoding
+recognized by the L<Encode> module (see L<Encode::Supported>). 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 B<--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> (see below), 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 I<encoding> is set to the special value C<roff>, B<pod2man> 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 B<pod2man> 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. Its use is discouraged.
+
+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 B<--errors>=I<style>
-Set the error handling style. 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.5.0] Set the error handling style. 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<die>.
=item B<--fixed>=I<font>
-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 troff(1)
+[1.0] 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.
=item B<--fixedbold>=I<font>
-Bold version of the fixed-width font. Defaults to C<CB>. Only matters
-for troff(1) output.
+[1.0] Bold version of the fixed-width font. Defaults to C<CB>. Only matters
+for B<troff> output.
=item B<--fixeditalic>=I<font>
-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 troff(1) output.
+[1.0] 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 B<--fixedbolditalic>=I<font>
-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 troff(1) output.
+[1.0] 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 B<--guesswork>=I<rule>[,I<rule>...]
+
+[5.00] By default, B<pod2man> 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 rule C<all> enables all guesswork. This is also the default for
+backward compatibility reasons. The special rule 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 man 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 B<-h>, B<--help>
-Print out usage information.
+[1.00] Print out usage information.
=item B<-l>, B<--lax>
-No longer used. B<pod2man> used to check its input for validity as a
+[1.00] No longer used. B<pod2man> used to check its input for validity as a
manual page, but this should now be done by L<podchecker(1)> instead.
Accepted for backward compatibility; this option no longer does anything.
+=item B<--language>=I<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).
+
+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 man page is installed
+into the normal man page directory, such as F</usr/share/man>.
+
+On many systems, this will be done automatically if the man page is installed
+into a language-specific man 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 B<--lquote>=I<quote>
=item B<--rquote>=I<quote>
-Sets the quote marks used to surround CE<lt>> text. B<--lquote> sets the
-left quote mark and B<--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. B<--lquote> sets
+the left quote mark and B<--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 B<--quotes> option, which can be used to set both quotes at once.
If both B<--quotes> and one of the other options is set, B<--lquote> or
@@ -255,19 +358,19 @@ B<--rquote> overrides B<--quotes>.
=item B<-n> I<name>, B<--name>=I<name>
-Set the name of the manual page for the C<.TH> macro to I<name>. 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 to I<name>.
+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.
Although one does not have to follow this convention, be aware that the
-convention for UNIX man pages for commands is for the man page title to be
-in all-uppercase, even if the command isn't.
+convention for UNIX manual pages is for the title to be in all-uppercase, even
+if the command isn't. (Perl modules traditionally use mixed case for the
+manual page title, however.)
-This option is probably not useful when converting multiple POD files at
-once.
+This option is probably not useful when converting multiple POD files at once.
When converting POD source from standard input, the name will be set to
C<STDIN> if this option is not provided. Providing this option is strongly
@@ -275,8 +378,8 @@ recommended to set a meaningful manual page name.
=item B<--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.5.0] 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/>
@@ -290,19 +393,19 @@ cluttered output in cases where the URLs are not particularly important.
=item B<-o>, B<--official>
-Set the default header to indicate that this page is part of the standard
-Perl release, if B<--center> is not also given.
+[1.00] Set the default header to indicate that this page is part of the
+standard Perl release, if B<--center> is not also given.
=item B<-q> I<quotes>, B<--quotes>=I<quotes>
-Sets the quote marks used to surround CE<lt>> text to I<quotes>. If
-I<quotes> 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 to I<quotes>. If
+I<quotes> 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.
-I<quotes> may also be set to the special value C<none>, in which case no
-quote marks are added around CE<lt>> text (but the font is still changed for
-troff output).
+I<quotes> may also be set to the special value C<none>, in which case no quote
+marks are added around CE<lt>> text (but the font is still changed for troff
+output).
Also see the B<--lquote> and B<--rquote> options, which can be used to set the
left and right quotes independently. If both B<--quotes> and one of the other
@@ -310,76 +413,57 @@ options is set, B<--lquote> or B<--rquote> overrides B<--quotes>.
=item B<-r> I<version>, B<--release>=I<version>
-Set the centered footer for the C<.TH> macro to I<version>. By default,
-this is set to the version of Perl you run B<pod2man> under. Setting this
-to the empty string will cause some *roff implementations to use the
+[1.00] Set the centered footer for the C<.TH> macro to I<version>. By
+default, this is set to the version of Perl you run B<pod2man> 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 B<--release> to the last modified date and B<--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 B<--release> to
+the last modified date and B<--date> to the version number.
=item B<-s> I<string>, B<--section>=I<string>
-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.
+By default, section 1 will be used unless the file ends in C<.pm>, in which
+case section 3 will be selected.
=item B<--stderr>
-By default, B<pod2man> dies if any errors are detected in the POD input.
-If B<--stderr> is given and no B<--errors> flag is present, errors are
-sent to standard error, but B<pod2man> does not abort. This is equivalent
-to C<--errors=stderr> and is supported for backward compatibility.
+[2.1.3] By default, B<pod2man> dies if any errors are detected in the POD
+input. If B<--stderr> is given and no B<--errors> flag is present, errors are
+sent to standard error, but B<pod2man> does not abort. This is equivalent to
+C<--errors=stderr> and is supported for backward compatibility.
=item B<-u>, B<--utf8>
-By default, B<pod2man> 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>.
-
-This option says to instead output literal UTF-8 characters. 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 warn, which by default results in a B<pod2man> failure.
-Use the C<=encoding> command to declare the encoding. See L<perlpod(1)>
-for more information.
+[2.1.0] This option used to tell B<pod2man> to produce UTF-8 output. Since
+this is now the default as of version 5.00, it is ignored and does nothing.
=item B<-v>, B<--verbose>
-Print out the name of each output file as it is being generated.
+[1.11] Print out the name of each output file as it is being generated.
=back
=head1 EXIT STATUS
-As long as all documents processed result in some output, even if that
-output includes errata (a C<POD ERRORS> section generated with
-C<--errors=pod>), B<pod2man> will exit with status 0. If any of the
-documents being processed do not result in an output document, B<pod2man>
-will exit with status 1. If there are syntax errors in a POD document
-being processed and the error handling style is set to the default of
-C<die>, B<pod2man> will abort immediately with exit status 255.
+As long as all documents processed result in some output, even if that output
+includes errata (a C<POD ERRORS> section generated with C<--errors=pod>),
+B<pod2man> will exit with status 0. If any of the documents being processed
+do not result in an output document, B<pod2man> will exit with status 1. If
+there are syntax errors in a POD document being processed and the error
+handling style is set to the default of C<die>, B<pod2man> will abort
+immediately with exit status 255.
=head1 DIAGNOSTICS
@@ -402,22 +486,17 @@ To get index entries on C<STDERR>, turn on the F register, as in:
troff -man -rF1 perl.1
-The indexing merely outputs messages via C<.tm> for each major page,
-section, subsection, item, and any C<XE<lt>E<gt>> directives. See
-L<Pod::Man> for more details.
-
-=head1 BUGS
-
-Lots of this documentation is duplicated from L<Pod::Man>.
+The indexing merely outputs messages via C<.tm> for each major page, section,
+subsection, item, and any C<XE<lt>E<gt>> directives.
=head1 AUTHOR
-Russ Allbery <rra@cpan.org>, based I<very> heavily on the original
-B<pod2man> by Larry Wall and Tom Christiansen.
+Russ Allbery <rra@cpan.org>, based on the original B<pod2man> by Larry Wall
+and Tom Christiansen.
=head1 COPYRIGHT AND LICENSE
-Copyright 1999-2001, 2004, 2006, 2008, 2010, 2012-2019 Russ Allbery
+Copyright 1999-2001, 2004, 2006, 2008, 2010, 2012-2019, 2022 Russ Allbery
<rra@cpan.org>
This program is free software; you may redistribute it and/or modify it
diff --git a/cpan/podlators/scripts/pod2text.PL b/cpan/podlators/scripts/pod2text.PL
index be06960ad7..073f0725eb 100644
--- a/cpan/podlators/scripts/pod2text.PL
+++ b/cpan/podlators/scripts/pod2text.PL
@@ -38,7 +38,7 @@ print "Extracting $file (with variable substitutions)\n";
print {$out} <<"PREAMBLE" or die "Cannot write to $file: $!\n";
$Config{startperl}
eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
- if \$running_under_some_shell;
+ if 0; # ^ Run only under a shell
PREAMBLE
# In the following, Perl variables are not expanded during extraction.
@@ -81,10 +81,10 @@ my $stdin;
# Parse our options. Use the same names as Pod::Text for simplicity.
my %options;
Getopt::Long::config ('bundling');
-GetOptions (\%options, 'alt|a', 'code', 'color|c', 'errors=s', 'help|h',
- 'indent|i=i', 'loose|l', 'margin|left-margin|m=i', 'nourls',
- 'overstrike|o', 'quotes|q=s', 'sentence|s', 'stderr', 'termcap|t',
- 'utf8|u', 'width|w=i')
+GetOptions (\%options, 'alt|a', 'code', 'color|c', 'encoding|e=s', 'errors=s',
+ 'help|h', 'indent|i=i', 'loose|l', 'margin|left-margin|m=i',
+ 'nourls', 'overstrike|o', 'quotes|q=s', 'sentence|s', 'stderr',
+ 'termcap|t', 'utf8|u', 'width|w=i')
or exit 1;
pod2usage (1) if $options{help};
@@ -133,7 +133,7 @@ __END__
=for stopwords
-aclostu --alt --stderr Allbery --overstrike overstrike --termcap --utf8
-UTF-8 subclasses --nourls
+UTF-8 subclasses --nourls EBCDIC unrepresentable
=head1 NAME
@@ -141,82 +141,109 @@ pod2text - Convert POD data to formatted ASCII text
=head1 SYNOPSIS
-pod2text [B<-aclostu>] [B<--code>] [B<--errors>=I<style>] [B<-i> I<indent>]
- S<[B<-q> I<quotes>]> [B<--nourls>] [B<--stderr>] S<[B<-w> I<width>]>
- [I<input> [I<output> ...]]
+pod2text [B<-aclostu>] [B<--code>] S<[B<-e> I<encoding>]>
+ [B<--errors>=I<style>] [B<-i> I<indent>] S<[B<-q> I<quotes>]>
+ [B<--nourls>] [B<--stderr>] S<[B<-w> I<width>]> [I<input> [I<output> ...]]
pod2text B<-h>
=head1 DESCRIPTION
-B<pod2text> is a front-end for Pod::Text and its subclasses. It uses them
-to generate formatted ASCII text from POD source. It can optionally use
-either termcap sequences or ANSI color escape sequences to format the text.
+B<pod2text> is a wrapper script around the L<Pod::Text> and its subclasses.
+It uses them to generate formatted text from POD source. It can optionally
+use either termcap sequences or ANSI color escape sequences to format the
+text.
-I<input> is the file to read for POD source (the POD can be embedded in
-code). If I<input> isn't given, it defaults to C<STDIN>. I<output>, if
-given, is the file to which to write the formatted output. If I<output>
-isn't given, the formatted output is written to C<STDOUT>. Several POD
-files can be processed in the same B<pod2text> invocation (saving module
-load and compile times) by providing multiple pairs of I<input> and
-I<output> files on the command line.
+I<input> is the file to read for POD source (the POD can be embedded in code).
+If I<input> isn't given, it defaults to C<STDIN>. I<output>, if given, is the
+file to which to write the formatted output. If I<output> isn't given, the
+formatted output is written to C<STDOUT>. Several POD files can be processed
+in the same B<pod2text> invocation (saving module load and compile times) by
+providing multiple pairs of I<input> and I<output> files on the command line.
+
+By default, the output encoding is the same as the encoding of the input file,
+or UTF-8 if that encoding is not set (except on EBCDIC systems). See the
+B<-e> option to explicitly set the output encoding and L<Pod::Text/Encoding>
+for more discussion.
=head1 OPTIONS
+Each option is annotated with the version of podlators in which that option
+was added with its current meaning.
+
=over 4
=item B<-a>, B<--alt>
-Use 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.
+[1.00] Use 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.
=item B<--code>
-Include any non-POD text from the input file in the output as well. Useful
-for viewing code documented with POD blocks with the POD rendered and the
-code left intact.
+[1.11] Include any non-POD text from the input file in the output as well.
+Useful for viewing code documented with POD blocks with the POD rendered and
+the code left intact.
=item B<-c>, B<--color>
-Format the output with ANSI color escape sequences. Using this option
+[1.00] Format the output with ANSI color escape sequences. Using this option
requires that Term::ANSIColor be installed on your system.
+=item B<-e> I<encoding>, B<--encoding>=I<encoding>
+
+[5.00] Specifies the encoding of the output. I<encoding> 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<?>).
+
+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 B<--errors>=I<style>
-Set the error handling style. 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.5.0] Set the error handling style. 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<die>.
=item B<-i> I<indent>, B<--indent=>I<indent>
-Set the number of spaces to indent regular text, and the default indentation
-for C<=over> blocks. Defaults to 4 spaces if this option isn't given.
+[1.00] Set the number of spaces to indent regular text, and the default
+indentation for C<=over> blocks. Defaults to 4 spaces if this option isn't
+given.
=item B<-h>, B<--help>
-Print out usage information and exit.
+[1.00] Print out usage information and exit.
=item B<-l>, B<--loose>
-Print a blank line after a C<=head1> heading. Normally, no blank line is
-printed after C<=head1>, although one is still printed after C<=head2>,
-because this is the expected formatting for manual pages; if you're
-formatting arbitrary text documents, using this option is recommended.
+[1.00] Print a blank line after a C<=head1> heading. Normally, no blank line
+is printed after C<=head1>, although one is still printed after C<=head2>,
+because this is the expected formatting for manual pages; if you're formatting
+arbitrary text documents, using this option is recommended.
=item B<-m> I<width>, B<--left-margin>=I<width>, B<--margin>=I<width>
-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 B<-i> option.
+[1.24] 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 B<-i> option.
=item B<--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.5.0] 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/>
@@ -225,80 +252,71 @@ is formatted as:
foo <http://example.com/>
This flag, if given, 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.
+example would be formatted as just C<foo>. This can produce less cluttered
+output in cases where the URLs are not particularly important.
=item B<-o>, B<--overstrike>
-Format the output with overstrike printing. Bold text is rendered as
+[1.06] Format the output with overstrike printing. Bold text is rendered as
character, backspace, character. Italics and file names are rendered as
-underscore, backspace, character. Many pagers, such as B<less>, know how
-to convert this to bold or underlined text.
+underscore, backspace, character. Many pagers, such as B<less>, know how to
+convert this to bold or underlined text.
=item B<-q> I<quotes>, B<--quotes>=I<quotes>
-Sets the quote marks used to surround CE<lt>> text to I<quotes>. If
-I<quotes> 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 to I<quotes>. If
+I<quotes> 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.
-I<quotes> may also be set to the special value C<none>, in which case no
-quote marks are added around CE<lt>> text.
+I<quotes> may also be set to the special value C<none>, in which case no quote
+marks are added around CE<lt>> text.
=item B<-s>, B<--sentence>
-Assume each sentence ends with two spaces and try to preserve that spacing.
-Without this option, all consecutive whitespace in non-verbatim paragraphs
-is compressed into a single space.
+[1.00] Assume each sentence ends with two spaces and try to preserve that
+spacing. Without this option, all consecutive whitespace in non-verbatim
+paragraphs is compressed into a single space.
=item B<--stderr>
-By default, B<pod2text> dies if any errors are detected in the POD input.
-If B<--stderr> is given and no B<--errors> flag is present, errors are
-sent to standard error, but B<pod2text> does not abort. This is
-equivalent to C<--errors=stderr> and is supported for backward
-compatibility.
+[2.1.3] By default, B<pod2text> dies if any errors are detected in the POD
+input. If B<--stderr> is given and no B<--errors> flag is present, errors are
+sent to standard error, but B<pod2text> does not abort. This is equivalent to
+C<--errors=stderr> and is supported for backward compatibility.
=item B<-t>, B<--termcap>
-Try to determine the width of the screen and the bold and underline
+[1.00] Try to determine the width of the screen and the bold and underline
sequences for the terminal from termcap, and use that information in
formatting the output. Output will be wrapped at two columns less than the
width of your terminal device. Using this option requires that your system
have a termcap file somewhere where Term::Cap can find it and requires that
-your system support termios. With this option, the output of B<pod2text>
-will contain terminal control sequences for your current terminal type.
+your system support termios. With this option, the output of B<pod2text> will
+contain terminal control sequences for your current terminal type.
=item B<-u>, B<--utf8>
-By default, B<pod2text> tries to use the same output encoding as its input
-encoding (to be backward-compatible with older versions). This option
-says to instead force the output encoding 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 warn, which by default results in a
-B<pod2text> failure. Use the C<=encoding> command to declare the
-encoding. See L<perlpod(1)> for more information.
+[2.2.0] Set the output encoding to UTF-8. This is equivalent to
+C<--encoding=UTF-8> and is supported for backward compatibility.
=item B<-w>, B<--width=>I<width>, B<->I<width>
-The column at which to wrap text on the right-hand side. Defaults to 76,
-unless B<-t> is given, in which case it's two columns less than the width of
-your terminal device.
+[1.00] The column at which to wrap text on the right-hand side. Defaults to
+76, unless B<-t> is given, in which case it's two columns less than the width
+of your terminal device.
=back
=head1 EXIT STATUS
-As long as all documents processed result in some output, even if that
-output includes errata (a C<POD ERRORS> section generated with
-C<--errors=pod>), B<pod2text> will exit with status 0. If any of the
-documents being processed do not result in an output document, B<pod2text>
-will exit with status 1. If there are syntax errors in a POD document
-being processed and the error handling style is set to the default of
-C<die>, B<pod2text> will abort immediately with exit status 255.
+As long as all documents processed result in some output, even if that output
+includes errata (a C<POD ERRORS> section generated with C<--errors=pod>),
+B<pod2text> will exit with status 0. If any of the documents being processed
+do not result in an output document, B<pod2text> will exit with status 1. If
+there are syntax errors in a POD document being processed and the error
+handling style is set to the default of C<die>, B<pod2text> will abort
+immediately with exit status 255.
=head1 DIAGNOSTICS
@@ -310,8 +328,7 @@ produce the following diagnostics:
=item -c (--color) requires Term::ANSIColor be installed
-(F) B<-c> or B<--color> were given, but Term::ANSIColor could not be
-loaded.
+(F) B<-c> or B<--color> were given, but Term::ANSIColor could not be loaded.
=item Unknown option: %s
@@ -328,8 +345,8 @@ command-line options.
=item COLUMNS
-If B<-t> is given, B<pod2text> will take the current width of your screen
-from this environment variable, if available. It overrides terminal width
+If B<-t> is given, B<pod2text> will take the current width of your screen from
+this environment variable, if available. It overrides terminal width
information in TERMCAP.
=item TERMCAP
@@ -346,7 +363,7 @@ Russ Allbery <rra@cpan.org>.
=head1 COPYRIGHT AND LICENSE
-Copyright 1999-2001, 2004, 2006, 2008, 2010, 2012-2019 Russ Allbery
+Copyright 1999-2001, 2004, 2006, 2008, 2010, 2012-2019, 2022 Russ Allbery
<rra@cpan.org>
This program is free software; you may redistribute it and/or modify it
@@ -354,8 +371,8 @@ under the same terms as Perl itself.
=head1 SEE ALSO
-L<Pod::Text>, L<Pod::Text::Color>, L<Pod::Text::Overstrike>,
-L<Pod::Text::Termcap>, L<Pod::Simple>, L<perlpod(1)>
+L<Encode::Supported>, L<Pod::Text>, L<Pod::Text::Color>,
+L<Pod::Text::Overstrike>, L<Pod::Text::Termcap>, L<Pod::Simple>, L<perlpod(1)>
The current version of this script 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/cpan/podlators/t/data/basic.man b/cpan/podlators/t/data/basic.man
index e2fe97805e..f65b9b5f9d 100644
--- a/cpan/podlators/t/data/basic.man
+++ b/cpan/podlators/t/data/basic.man
@@ -6,10 +6,10 @@ Try a few different levels of headings, with embedded formatting codes and
other interesting bits.
.ie n .SH "This ""is"" a ""level 1"" heading"
.el .SH "This \f(CWis\fP a ``level 1'' heading"
-.IX Header "This is a level 1 heading"
+.IX Header "This is a ""level 1"" heading"
.SS "``Level'' ""2 \fIheading\fP"
.IX Subsection "``Level'' ""2 heading"
-\fILevel 3 \f(BIheading \f(BIwith \f(CB\*(C`weird \f(CBstuff "" (double quote)\f(CB\*(C'\f(BI\f(BI\fI\fR
+\fILevel 3 \fR\f(BIheading with \fR\f(CB\*(C`weird stuff "" (double quote)\*(C'\fR
.IX Subsection "Level 3 heading with weird stuff """" (double quote)"
.PP
Level "4 \f(CW\*(C`heading\*(C'\fR
@@ -18,13 +18,13 @@ Level "4 \f(CW\*(C`heading\*(C'\fR
Now try again with \fBintermixed\fR \fItext\fR.
.ie n .SH "This ""is"" a ""level 1"" heading"
.el .SH "This \f(CWis\fP a ``level 1'' heading"
-.IX Header "This is a level 1 heading"
+.IX Header "This is a ""level 1"" heading"
Text.
.SS "``Level'' 2 \fIheading\fP"
.IX Subsection "``Level'' 2 heading"
Text.
.PP
-\fILevel 3 \f(BIheading \f(BIwith \f(CB\*(C`weird \f(CBstuff\f(CB\*(C'\f(BI\f(BI\fI\fR
+\fILevel 3 \fR\f(BIheading with \fR\f(CB\*(C`weird stuff\*(C'\fR
.IX Subsection "Level 3 heading with weird stuff"
.PP
Text.
@@ -37,15 +37,15 @@ Text.
.IX Header "LINKS"
These are all taken from the Pod::Parser tests.
.PP
-Try out \fI\s-1LOTS\s0\fR of different ways of specifying references:
+Try out \fILOTS\fR of different ways of specifying references:
.PP
-Reference the \*(L"section\*(R" in manpage
+Reference the "section" in manpage
.PP
-Reference the \*(L"section\*(R" in \*(L"manpage\*(R"
+Reference the "section" in "manpage"
.PP
-Reference the \*(L"section\*(R" in manpage
+Reference the "section" in manpage
.PP
-Now try it using the new \*(L"|\*(R" stuff ...
+Now try it using the new "|" stuff ...
.PP
Reference the thistext|
.PP
@@ -65,23 +65,23 @@ foo
.PP
foo
.PP
-\&\*(L"bar\*(R" in foo
+"bar" in foo
.PP
-\&\*(L"baz boo\*(R" in foo
+"baz boo" in foo
.PP
-\&\*(L"bar\*(R"
+"bar"
.PP
-\&\*(L"baz boo\*(R"
+"baz boo"
.PP
-\&\*(L"baz boo\*(R"
+"baz boo"
.PP
-\&\*(L"baz boo\*(R" in foo bar
+"baz boo" in foo bar
.PP
-\&\*(L"boo var baz\*(R"
+"boo var baz"
.PP
-\&\*(L"bar baz\*(R"
+"bar baz"
.PP
-\&\*(L"boo\*(R", \*(L"bar\*(R", and \*(L"baz\*(R"
+"boo", "bar", and "baz"
.PP
foobar
.PP
@@ -89,7 +89,7 @@ Testing \fIitalics\fR
.PP
"\fIItalic\fR text" in foo
.PP
-"Section \f(CW\*(C`with\*(C'\fR \fI\f(BIother\fI markup\fR" in foo|bar
+"Section \f(CW\*(C`with\*(C'\fR \fR\f(BIother\fR\fI markup\fR" in foo|bar
.SH "OVER AND ITEMS"
.IX Header "OVER AND ITEMS"
Taken from Pod::Parser tests, this is a test to ensure that multiline
@@ -137,7 +137,7 @@ Now some additional weirdness of our own. Make sure that multiple tags
for one paragraph are properly compacted.
.ie n .IP """foo""" 4
.el .IP "``foo''" 4
-.IX Item "foo"
+.IX Item """foo"""
.PD 0
.IP "\fBbar\fR" 4
.IX Item "bar"
@@ -155,7 +155,7 @@ few lines).
.Sp
Let's also make it multiple paragraphs to be sure that works.
.PP
-Test use of =over without =item as a block \*(L"quote\*(R" or block paragraph.
+Test use of =over without =item as a block "quote" or block paragraph.
.Sp
.RS 4
This should be indented four spaces but otherwise formatted the same as
@@ -202,7 +202,7 @@ Second item.
.IX Header "FORMATTING CODES"
Another test taken from Pod::Parser.
.PP
-This is a test to see if I can do not only \f(CW$self\fR and \f(CW\*(C`method()\*(C'\fR, but
+This is a test to see if I can do not only \f(CW$self\fR and \f(CWmethod()\fR, but
also \f(CW\*(C`$self\->method()\*(C'\fR and \f(CW\*(C`$self\->{FIELDNAME}\*(C'\fR and
\&\f(CW\*(C`$Foo <=> $Bar\*(C'\fR without resorting to escape sequences. If
I want to refer to the right-shift operator I can do something
@@ -221,14 +221,14 @@ Don't forget \f(CW\*(C`$self\->method()\->{FIELDNAME} = {FOO=>BAR}\*(C'\fR.
And make sure that \f(CW0\fR works too!
.PP
Now, if I use << or >> as my delimiters, then I have to use whitespace.
-So things like \f(CW\*(C`<$self\-\*(C'\fR\fBmethod()\fR>> and \f(CW\*(C`<$self\-\*(C'\fR{\s-1FIELDNAME\s0}>> won't end
+So things like \f(CW\*(C`<$self\-\*(C'\fR\fBmethod()\fR>> and \f(CW\*(C`<$self\-\*(C'\fR{FIELDNAME}>> won't end
up doing what you might expect since the first > will still terminate
the first < seen.
.PP
Lets make sure these work for empty ones too, like \f(CW\*(C`\*(C'\fR and \f(CW\*(C`>>\*(C'\fR
(just to be obnoxious)
.PP
-The statement: \f(CW\*(C`This is dog kind\*(Aqs \f(CIfinest\f(CW hour!\*(C'\fR is a parody of a
+The statement: \f(CW\*(C`This is dog kind\*(Aqs \fR\f(CIfinest\fR\f(CW hour!\*(C'\fR is a parody of a
quotation from Winston Churchill.
.PP
The following tests are added to those:
@@ -326,4 +326,4 @@ permitted in any medium without royalty provided the copyright notice and
this notice are preserved. This file is offered as-is, without any
warranty.
.PP
-SPDX-License-Identifier: \s-1FSFAP\s0
+SPDX-License-Identifier: FSFAP
diff --git a/cpan/podlators/t/data/man/encoding.groff b/cpan/podlators/t/data/man/encoding.groff
new file mode 100644
index 0000000000..1eba828104
--- /dev/null
+++ b/cpan/podlators/t/data/man/encoding.groff
@@ -0,0 +1,87 @@
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "ENCODING 1"
+.TH ENCODING 1 "2022-09-25" "testing" "podlators"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "ENCODING TESTS"
+.IX Header "ENCODING TESTS"
+This POD source is intended to test encoding behavior with different
+pod2man encoding options. The resulting *roff output files can be copied
+to various systems to test with the local nroff or man implementations.
+.PP
+ISO 8859\-1 character: na\[u00EF]ve
+.PP
+ISO 8859\-1 escape: na\[u00EF]ve, na\[u00EF]ve
+.PP
+Combining accent: nai\[u0308]ve
+.PP
+SMP plane character: \[u1F600]
+.PP
+Non-breaking space: foo\ bar, foo\ bar
+.PP
+Soft hyphen: fac\%tory
+.SH "LICENSE"
+.IX Header "LICENSE"
+Copyright 2022 Russ Allbery <rra@cpan.org>
+.PP
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and
+this notice are preserved. This file is offered as-is, without any
+warranty.
+.PP
+SPDX-License-Identifier: FSFAP
diff --git a/cpan/podlators/t/data/man/encoding.pod b/cpan/podlators/t/data/man/encoding.pod
new file mode 100644
index 0000000000..e8b46b2114
--- /dev/null
+++ b/cpan/podlators/t/data/man/encoding.pod
@@ -0,0 +1,30 @@
+=encoding utf-8
+
+=head1 ENCODING TESTS
+
+This POD source is intended to test encoding behavior with different
+pod2man encoding options. The resulting *roff output files can be copied
+to various systems to test with the local nroff or man implementations.
+
+ISO 8859-1 character: naïve
+
+ISO 8859-1 escape: naE<iuml>ve, naE<0xEF>ve
+
+Combining accent: naïve
+
+SMP plane character: 😀
+
+Non-breaking space: foo bar, S<foo bar>
+
+Soft hyphen: fac­tory
+
+=head1 LICENSE
+
+Copyright 2022 Russ Allbery <rra@cpan.org>
+
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and
+this notice are preserved. This file is offered as-is, without any
+warranty.
+
+SPDX-License-Identifier: FSFAP
diff --git a/cpan/podlators/t/data/man/encoding.roff b/cpan/podlators/t/data/man/encoding.roff
new file mode 100644
index 0000000000..7b4e6621a8
--- /dev/null
+++ b/cpan/podlators/t/data/man/encoding.roff
@@ -0,0 +1,149 @@
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. 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*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "ENCODING 1"
+.TH ENCODING 1 "2022-09-25" "testing" "podlators"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "ENCODING TESTS"
+.IX Header "ENCODING TESTS"
+This POD source is intended to test encoding behavior with different
+pod2man encoding options. The resulting *roff output files can be copied
+to various systems to test with the local nroff or man implementations.
+.PP
+ISO 8859\-1 character: nai\*:ve
+.PP
+ISO 8859\-1 escape: nai\*:ve, nai\*:ve
+.PP
+Combining accent: naiXve
+.PP
+SMP plane character: X
+.PP
+Non-breaking space: foo\ bar, foo\ bar
+.PP
+Soft hyphen: fac\%tory
+.SH "LICENSE"
+.IX Header "LICENSE"
+Copyright 2022 Russ Allbery <rra@cpan.org>
+.PP
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and
+this notice are preserved. This file is offered as-is, without any
+warranty.
+.PP
+SPDX-License-Identifier: FSFAP
diff --git a/cpan/podlators/t/data/man/encoding.utf8 b/cpan/podlators/t/data/man/encoding.utf8
new file mode 100644
index 0000000000..b74c2e8804
--- /dev/null
+++ b/cpan/podlators/t/data/man/encoding.utf8
@@ -0,0 +1,88 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "ENCODING 1"
+.TH ENCODING 1 "2022-09-25" "testing" "podlators"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "ENCODING TESTS"
+.IX Header "ENCODING TESTS"
+This POD source is intended to test encoding behavior with different
+pod2man encoding options. The resulting *roff output files can be copied
+to various systems to test with the local nroff or man implementations.
+.PP
+ISO 8859\-1 character: naïve
+.PP
+ISO 8859\-1 escape: naïve, naïve
+.PP
+Combining accent: naïve
+.PP
+SMP plane character: 😀
+.PP
+Non-breaking space: foo\ bar, foo\ bar
+.PP
+Soft hyphen: fac\%tory
+.SH "LICENSE"
+.IX Header "LICENSE"
+Copyright 2022 Russ Allbery <rra@cpan.org>
+.PP
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and
+this notice are preserved. This file is offered as-is, without any
+warranty.
+.PP
+SPDX-License-Identifier: FSFAP
diff --git a/cpan/podlators/t/data/perl.conf b/cpan/podlators/t/data/perl.conf
index ca0556858b..7fc4db8673 100644
--- a/cpan/podlators/t/data/perl.conf
+++ b/cpan/podlators/t/data/perl.conf
@@ -1,7 +1,7 @@
# Configuration for Perl tests. -*- perl -*-
# Default minimum version requirement.
-$MINIMUM_VERSION = '5.008';
+$MINIMUM_VERSION = '5.010';
# File must end with this line.
1;
diff --git a/cpan/podlators/t/data/regenerate-data b/cpan/podlators/t/data/regenerate-data
new file mode 100644
index 0000000000..d118afbc63
--- /dev/null
+++ b/cpan/podlators/t/data/regenerate-data
@@ -0,0 +1,108 @@
+#!/usr/bin/perl
+#
+# Development helper program to regenerate test data.
+#
+# The snippet tests are designed to keep the output fairly stable, but there
+# are a few tests that use complete output with some customization. This
+# helper program regenerates those files using the local installation of
+# podlators. The output can then be reviewed with normal Git tools.
+#
+# Copyright 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.
+#
+# SPDX-License-Identifier: GPL-1.0-or-later OR Artistic-1.0-Perl
+
+use 5.008;
+use strict;
+use warnings;
+
+use lib 'blib/lib';
+
+use File::Spec;
+use Pod::Man;
+use Pod::Text;
+use Pod::Text::Color;
+use Pod::Text::Overstrike;
+use Pod::Text::Termcap;
+
+# Hard-code configuration for Term::Cap to get predictable results.
+#<<<
+local $ENV{COLUMNS} = 80;
+local $ENV{TERM} = 'xterm';
+local $ENV{TERMPATH} = File::Spec->catfile('t', 'data', 'termcap');
+local $ENV{TERMCAP} = 'xterm:co=#80:do=^J:md=\\E[1m:us=\\E[4m:me=\\E[m';
+#>>>
+
+# Map of translators to the file containing the formatted output for the
+# general/basic.t test.
+#<<<
+my %output = (
+ 'Pod::Man' => File::Spec->catfile('t', 'data', 'basic.man'),
+ 'Pod::Text' => File::Spec->catfile('t', 'data', 'basic.txt'),
+ 'Pod::Text::Color' => File::Spec->catfile('t', 'data', 'basic.clr'),
+ 'Pod::Text::Overstrike' => File::Spec->catfile('t', 'data', 'basic.ovr'),
+ 'Pod::Text::Termcap' => File::Spec->catfile('t', 'data', 'basic.cap'),
+);
+#>>>
+
+# Regenerate those output files.
+my $input = File::Spec->catfile('t', 'data', 'basic.pod');
+for my $module (keys(%output)) {
+ my $parser = $module->new();
+
+ # Run the formatting module.
+ my $output;
+ $parser->output_string(\$output);
+ $parser->parse_file($input);
+
+ # If the test module is Pod::Man, strip off the header. This test does
+ # not attempt to compare it, since it contains version numbers that
+ # change.
+ if ($module eq 'Pod::Man') {
+ $output =~ s{ \A .* \n [.]nh \n }{}xms;
+ }
+
+ # Overwrite the output.
+ open(my $fh, '>', $output{$module})
+ or die "cannot create $output{$module}: $!\n";
+ print {$fh} $output
+ or die "cannot write to $output{$module}: $!\n";
+ close($fh)
+ or die "cannot write to $output{$module}: $!\n";
+}
+
+# Now switch to the files for the man/encoding.t test.
+$input = File::Spec->catfile('t', 'data', 'man', 'encoding.pod');
+#<<<
+%output = (
+ groff => File::Spec->catfile('t', 'data', 'man', 'encoding.groff'),
+ roff => File::Spec->catfile('t', 'data', 'man', 'encoding.roff'),
+ utf8 => File::Spec->catfile('t', 'data', 'man', 'encoding.utf8'),
+);
+#>>>
+
+# For each encoding, load the input, generate the output, and check that the
+# output matches.
+for my $encoding (keys(%output)) {
+ my $parser = Pod::Man->new(
+ encoding => $encoding,
+ center => 'podlators',
+ release => 'testing',
+ );
+ my $output;
+ $parser->output_string(\$output);
+ $parser->parse_file($input);
+
+ # Strip off the version line.
+ $output =~ s{ ^ [^\n]+ Automatically [ ] generated [ ] by [^\n]+ \n }{}xms;
+
+ # Overwrite the output.
+ open(my $fh, '>', $output{$encoding})
+ or die "cannot create $output{$encoding}: $!\n";
+ print {$fh} $output
+ or die "cannot write to $output{$encoding}: $!\n";
+ close($fh)
+ or die "cannot write to $output{$encoding}: $!\n";
+}
diff --git a/cpan/podlators/t/data/snippets/README b/cpan/podlators/t/data/snippets/README.md
index 342959585b..92ccc64c56 100644
--- a/cpan/podlators/t/data/snippets/README
+++ b/cpan/podlators/t/data/snippets/README.md
@@ -1,15 +1,18 @@
+# Test snippets
+
The files in this directory are used by the test suite to exercise various
behavior of Pod::Man or Pod::Text. They use a pseudo-ini-file syntax with
free-form sections, normally an input and an output section and possibly
others.
-Sections start with the section type in []. The contents are normally
-just free-form. The exception is an [options] section, where the contents
-are key/value pairs, where the key is separated from the value with
-whitespace.
+Sections start with the section type in `[]`. The contents are normally
+free-form text. The exception is an `[options]` section, where the
+contents are key/value pairs, where the key is separated from the value
+with whitespace.
Valid sections are:
+```
[name]
The name of this test for status reporting
@@ -30,14 +33,15 @@ Valid sections are:
[exception]
The text of an exception (with the file and line number information
stripped) thrown by running some formatter on the input.
+```
Files are organized into subdirectories named after the formatter, namely
man (Pod::Man), text (Pod::Text), color (Pod::Text::Color), overstrike
(Pod::Text::Overstrike), and termcap (Pod::Text::Termcap).
------
+## Copyright and license
-Copyright 2015, 2018 Russ Allbery <rra@cpan.org>
+Copyright 2015, 2018, 2022 Russ Allbery <rra@cpan.org>
Copying and distribution of this file, with or without modification, are
permitted in any medium without royalty provided the copyright notice and
diff --git a/cpan/podlators/t/data/snippets/man/agrave b/cpan/podlators/t/data/snippets/man/agrave
index c1ec02655a..134087ff21 100644
--- a/cpan/podlators/t/data/snippets/man/agrave
+++ b/cpan/podlators/t/data/snippets/man/agrave
@@ -1,6 +1,9 @@
[name]
E<agrave>
+[options]
+encoding roff
+
[input]
=head1 agrave
diff --git a/cpan/podlators/t/data/snippets/man/cpp b/cpan/podlators/t/data/snippets/man/cpp
index 177aeeeb89..8b3e7f9454 100644
--- a/cpan/podlators/t/data/snippets/man/cpp
+++ b/cpan/podlators/t/data/snippets/man/cpp
@@ -15,6 +15,6 @@ Other mentions of C++.
[output]
.SH "NAME"
gcc \- GNU project C and C++ compiler
-.SH "\*(C+ NOTES"
-.IX Header " NOTES"
-Other mentions of \*(C+.
+.SH "C++ NOTES"
+.IX Header "C++ NOTES"
+Other mentions of C++.
diff --git a/cpan/podlators/t/data/snippets/man/dollar-magic b/cpan/podlators/t/data/snippets/man/dollar-magic
index 2634732971..d5546eac5b 100644
--- a/cpan/podlators/t/data/snippets/man/dollar-magic
+++ b/cpan/podlators/t/data/snippets/man/dollar-magic
@@ -17,8 +17,8 @@ price is $100."
.IX Header "MAGIC MONEY"
These should be identical.
.PP
-Bippity boppity boo \*(L"The
-price is \f(CW$100\fR.\*(R"
+Bippity boppity boo "The
+price is \f(CW$100\fR."
.PP
-Bippity boppity boo \*(L"The
-price is \f(CW$100\fR.\*(R"
+Bippity boppity boo "The
+price is \f(CW$100\fR."
diff --git a/cpan/podlators/t/data/snippets/man/eth b/cpan/podlators/t/data/snippets/man/eth
index 6583ccb1fd..835b45b909 100644
--- a/cpan/podlators/t/data/snippets/man/eth
+++ b/cpan/podlators/t/data/snippets/man/eth
@@ -1,6 +1,9 @@
[name]
E<eth>
+[options]
+encoding roff
+
[input]
=pod
diff --git a/cpan/podlators/t/data/snippets/man/fixed-font b/cpan/podlators/t/data/snippets/man/fixed-font
index f0b8524e71..19b8aaf26a 100644
--- a/cpan/podlators/t/data/snippets/man/fixed-font
+++ b/cpan/podlators/t/data/snippets/man/fixed-font
@@ -15,4 +15,4 @@ C<foo B<bar I<baz>> I<bay>>
[output]
.SH "FIXED FONTS"
.IX Header "FIXED FONTS"
-\&\f(CR\*(C`foo \f(CYbar \f(CXbaz\f(CY\f(CR \f(CWbay\f(CR\*(C'\fR
+\&\f(CR\*(C`foo \fR\f(CYbar \fR\f(CXbaz\fR\f(CR \fR\f(CWbay\fR\f(CR\*(C'\fR
diff --git a/cpan/podlators/t/data/snippets/man/fixed-font-in-item b/cpan/podlators/t/data/snippets/man/fixed-font-in-item
index e096fd4cd6..55e52353df 100644
--- a/cpan/podlators/t/data/snippets/man/fixed-font-in-item
+++ b/cpan/podlators/t/data/snippets/man/fixed-font-in-item
@@ -4,8 +4,8 @@ Fixed-width font in item
[input]
=head1 Fixed-width Fonts in =item
-The nroff portion should not use fixed-width fonts. In podlators 4.06 and
-earlier, italic was terminated with \f(CW, which didn't properly stop italic.
+In podlators 4.06 and earlier, italic was terminated with \f(CW, which
+didn't properly stop italic.
=over 2
@@ -18,12 +18,12 @@ earlier, italic was terminated with \f(CW, which didn't properly stop italic.
[output]
.SH "Fixed-width Fonts in =item"
.IX Header "Fixed-width Fonts in =item"
-The nroff portion should not use fixed-width fonts. In podlators 4.06 and
-earlier, italic was terminated with \ef(\s-1CW,\s0 which didn't properly stop italic.
-.ie n .IP """tar \fIoption\fP... [\fIname\fP]...""" 2
-.el .IP "\f(CWtar \f(CIoption\f(CW... [\f(CIname\f(CW]...\fR" 2
+In podlators 4.06 and earlier, italic was terminated with \ef(CW, which
+didn't properly stop italic.
+.ie n .IP """tar \f(CIoption\fR... [\f(CIname\fR]...""" 2
+.el .IP "\f(CWtar \fR\f(CIoption\fR\f(CW... [\fR\f(CIname\fR\f(CW]...\fR" 2
.IX Item "tar option... [name]..."
.PD 0
-.ie n .IP """tar \fIletter\fP... [\fIargument\fP]... [\fIoption\fP]... [\fIname\fP]...""" 2
-.el .IP "\f(CWtar \f(CIletter\f(CW... [\f(CIargument\f(CW]... [\f(CIoption\f(CW]... [\f(CIname\f(CW]...\fR" 2
+.ie n .IP """tar \f(CIletter\fR... [\f(CIargument\fR]... [\f(CIoption\fR]... [\f(CIname\fR]...""" 2
+.el .IP "\f(CWtar \fR\f(CIletter\fR\f(CW... [\fR\f(CIargument\fR\f(CW]... [\fR\f(CIoption\fR\f(CW]... [\fR\f(CIname\fR\f(CW]...\fR" 2
.IX Item "tar letter... [argument]... [option]... [name]..."
diff --git a/cpan/podlators/t/data/snippets/man/guesswork b/cpan/podlators/t/data/snippets/man/guesswork
new file mode 100644
index 0000000000..11d5b72184
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/guesswork
@@ -0,0 +1,24 @@
+[name]
+Non-quoting guesswork applied by default
+
+[input]
+=head1 GUESSWORK
+
+The hyphens-in-compound-words shouldn't be escaped, but e-mail should be.
+
+Function: foo(), bar::baz(), _private::_stuff()
+
+Manpage: foo(1), Pod::Man(3perl), git-rebase(1)
+
+Variables: $foo, @bar::baz, %Pod::Blah
+
+[output]
+.SH "GUESSWORK"
+.IX Header "GUESSWORK"
+The hyphens-in-compound-words shouldn't be escaped, but e\-mail should be.
+.PP
+Function: \fBfoo()\fR, \fBbar::baz()\fR, \fB_private::_stuff()\fR
+.PP
+Manpage: \fBfoo\fR\|(1), \fBPod::Man\fR\|(3perl), \fBgit\-rebase\fR\|(1)
+.PP
+Variables: \f(CW$foo\fR, \f(CW@bar::baz\fR, \f(CW%Pod::Blah\fR
diff --git a/cpan/podlators/t/data/snippets/man/guesswork-all b/cpan/podlators/t/data/snippets/man/guesswork-all
new file mode 100644
index 0000000000..789dbd96a6
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/guesswork-all
@@ -0,0 +1,27 @@
+[name]
+Guesswork with all
+
+[options]
+guesswork all
+
+[input]
+=head1 GUESSWORK
+
+The hyphens-in-compound-words shouldn't be escaped, but e-mail should be.
+
+Function: foo(), bar::baz(), _private::_stuff()
+
+Manpage: foo(1), Pod::Man(3perl), git-rebase(1)
+
+Variables: $foo, @bar::baz, %Pod::Blah
+
+[output]
+.SH "GUESSWORK"
+.IX Header "GUESSWORK"
+The hyphens-in-compound-words shouldn't be escaped, but e\-mail should be.
+.PP
+Function: \fBfoo()\fR, \fBbar::baz()\fR, \fB_private::_stuff()\fR
+.PP
+Manpage: \fBfoo\fR\|(1), \fBPod::Man\fR\|(3perl), \fBgit\-rebase\fR\|(1)
+.PP
+Variables: \f(CW$foo\fR, \f(CW@bar::baz\fR, \f(CW%Pod::Blah\fR
diff --git a/cpan/podlators/t/data/snippets/man/guesswork-no-quoting b/cpan/podlators/t/data/snippets/man/guesswork-no-quoting
new file mode 100644
index 0000000000..c3793e3086
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/guesswork-no-quoting
@@ -0,0 +1,57 @@
+[name]
+Disable quoting guesswork
+
+[options]
+guesswork none
+
+[input]
+=head1 QUOTING
+
+Suppress quotes:
+C<"foo">,
+C<'foo'>,
+C<`foo`>,
+C<`foo'>,
+
+All these should now be quoted:
+C<$#f>,
+C<$foo[4]>,
+C<$foo{bar}>,
+C<%foo>,
+C<@foo>,
+C<&foo>,
+C<*foo>,
+C<< $foo->("bar") >>,
+C<&foo::baz("bar")>,
+C<&foo()>,
+C<foo( "bar" )>,
+C<-1000>,
+C<132.123>,
+C<5e-7>,
+C<0xdeadbeef>
+
+[output]
+.SH "QUOTING"
+.IX Header "QUOTING"
+Suppress quotes:
+\&\f(CW"foo"\fR,
+\&\f(CW\*(Aqfoo\*(Aq\fR,
+\&\f(CW\`foo\`\fR,
+\&\f(CW\`foo\*(Aq\fR,
+.PP
+All these should now be quoted:
+\&\f(CW\*(C`$#f\*(C'\fR,
+\&\f(CW\*(C`$foo[4]\*(C'\fR,
+\&\f(CW\*(C`$foo{bar}\*(C'\fR,
+\&\f(CW\*(C`%foo\*(C'\fR,
+\&\f(CW\*(C`@foo\*(C'\fR,
+\&\f(CW\*(C`&foo\*(C'\fR,
+\&\f(CW\*(C`*foo\*(C'\fR,
+\&\f(CW\*(C`$foo\->("bar")\*(C'\fR,
+\&\f(CW\*(C`&foo::baz("bar")\*(C'\fR,
+\&\f(CW\*(C`&foo()\*(C'\fR,
+\&\f(CW\*(C`foo( "bar" )\*(C'\fR,
+\&\f(CW\*(C`\-1000\*(C'\fR,
+\&\f(CW\*(C`132.123\*(C'\fR,
+\&\f(CW\*(C`5e\-7\*(C'\fR,
+\&\f(CW\*(C`0xdeadbeef\*(C'\fR
diff --git a/cpan/podlators/t/data/snippets/man/guesswork-none b/cpan/podlators/t/data/snippets/man/guesswork-none
new file mode 100644
index 0000000000..ff615e5680
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/guesswork-none
@@ -0,0 +1,27 @@
+[name]
+Non-quoting guesswork disabled
+
+[options]
+guesswork none
+
+[input]
+=head1 GUESSWORK
+
+The hyphens-in-compound-words shouldn't be escaped, but e-mail should be.
+
+Function: foo(), bar::baz(), _private::_stuff()
+
+Manpage: foo(1), Pod::Man(3perl), git-rebase(1)
+
+Variables: $foo, @bar::baz, %Pod::Blah
+
+[output]
+.SH "GUESSWORK"
+.IX Header "GUESSWORK"
+The hyphens-in-compound-words shouldn't be escaped, but e\-mail should be.
+.PP
+Function: foo(), bar::baz(), _private::_stuff()
+.PP
+Manpage: foo(1), Pod::Man(3perl), git\-rebase(1)
+.PP
+Variables: $foo, @bar::baz, %Pod::Blah
diff --git a/cpan/podlators/t/data/snippets/man/guesswork-partial b/cpan/podlators/t/data/snippets/man/guesswork-partial
new file mode 100644
index 0000000000..19a8cb6b8b
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/guesswork-partial
@@ -0,0 +1,27 @@
+[name]
+Some guesswork configured
+
+[options]
+guesswork functions,variables
+
+[input]
+=head1 GUESSWORK
+
+The hyphens-in-compound-words shouldn't be escaped, but e-mail should be.
+
+Function: foo(), bar::baz(), _private::_stuff()
+
+Manpage: foo(1), Pod::Man(3perl), git-rebase(1)
+
+Variables: $foo, @bar::baz, %Pod::Blah
+
+[output]
+.SH "GUESSWORK"
+.IX Header "GUESSWORK"
+The hyphens-in-compound-words shouldn't be escaped, but e\-mail should be.
+.PP
+Function: \fBfoo()\fR, \fBbar::baz()\fR, \fB_private::_stuff()\fR
+.PP
+Manpage: foo(1), Pod::Man(3perl), git\-rebase(1)
+.PP
+Variables: \f(CW$foo\fR, \f(CW@bar::baz\fR, \f(CW%Pod::Blah\fR
diff --git a/cpan/podlators/t/data/snippets/man/guesswork-quoting b/cpan/podlators/t/data/snippets/man/guesswork-quoting
new file mode 100644
index 0000000000..d452fe388b
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/guesswork-quoting
@@ -0,0 +1,54 @@
+[name]
+Quoting guesswork applied by default
+
+[input]
+=head1 QUOTING
+
+Suppress quotes:
+C<"foo">,
+C<'foo'>,
+C<`foo`>,
+C<`foo'>,
+C<$^F>,
+C<$">,
+C<$#f>,
+C<$foo[4]>,
+C<$foo{bar}>,
+C<%foo>,
+C<@foo>,
+C<&foo>,
+C<*foo>,
+C<< $foo->("bar") >>,
+C<&foo::baz("bar")>,
+C<&foo()>,
+C<foo( "bar" )>,
+C<-1000>,
+C<132.123>,
+C<5e-7>,
+C<0xdeadbeef>
+
+[output]
+.SH "QUOTING"
+.IX Header "QUOTING"
+Suppress quotes:
+\&\f(CW"foo"\fR,
+\&\f(CW\*(Aqfoo\*(Aq\fR,
+\&\f(CW\`foo\`\fR,
+\&\f(CW\`foo\*(Aq\fR,
+\&\f(CW$^F\fR,
+\&\f(CW$"\fR,
+\&\f(CW$#f\fR,
+\&\f(CW$foo[4]\fR,
+\&\f(CW$foo{bar}\fR,
+\&\f(CW%foo\fR,
+\&\f(CW@foo\fR,
+\&\f(CW&foo\fR,
+\&\f(CW*foo\fR,
+\&\f(CW$foo\->("bar")\fR,
+\&\f(CW&foo::baz("bar")\fR,
+\&\f(CW&foo()\fR,
+\&\f(CWfoo( "bar" )\fR,
+\&\f(CW\-1000\fR,
+\&\f(CW132.123\fR,
+\&\f(CW5e\-7\fR,
+\&\f(CW0xdeadbeef\fR
diff --git a/cpan/podlators/t/data/snippets/man/hyphen-in-s b/cpan/podlators/t/data/snippets/man/hyphen-in-s
index dbadd44a5f..754ae167f1 100644
--- a/cpan/podlators/t/data/snippets/man/hyphen-in-s
+++ b/cpan/podlators/t/data/snippets/man/hyphen-in-s
@@ -10,5 +10,5 @@ $-0.13 should have a real hyphen.
[output]
.SH "Hyphen in S<>"
.IX Header "Hyphen in S<>"
-Don't transform\ even-this\ hyphen. This \*(L"one's-fine!\*(R", as well. However,
+Don't transform\ even-this\ hyphen. This "one's-fine!", as well. However,
$\-0.13 should have a real hyphen.
diff --git a/cpan/podlators/t/data/snippets/man/iso-8859-1 b/cpan/podlators/t/data/snippets/man/iso-8859-1
index 6486e7741e..d2816cdeb0 100644
--- a/cpan/podlators/t/data/snippets/man/iso-8859-1
+++ b/cpan/podlators/t/data/snippets/man/iso-8859-1
@@ -1,6 +1,9 @@
[name]
ISO-8859-1 encoding
+[options]
+encoding iso-8859-1
+
[input]
=encoding iso-8859-1
@@ -17,12 +20,12 @@ Older versions didn't convert Beyoncé in verbatim.
[output]
.SH "ACCENTS"
.IX Header "ACCENTS"
-Beyonce\*'! Beyonce\*'! Beyonce\*'!!
+Beyoncé! Beyoncé! Beyoncé!!
.PP
.Vb 3
-\& Beyonce\*'! Beyonce\*'!
-\& Beyonce\*'! Beyonce\*'!
-\& Beyonce\*'! Beyonce\*'!
+\& Beyoncé! Beyoncé!
+\& Beyoncé! Beyoncé!
+\& Beyoncé! Beyoncé!
.Ve
.PP
-Older versions didn't convert Beyonce\*' in verbatim.
+Older versions didn't convert Beyoncé in verbatim.
diff --git a/cpan/podlators/t/data/snippets/man/iso-8859-1-error-die b/cpan/podlators/t/data/snippets/man/iso-8859-1-error-die
new file mode 100644
index 0000000000..b89abaf936
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/iso-8859-1-error-die
@@ -0,0 +1,30 @@
+[name]
+ISO-8859-1 encoding with invalid character (die)
+
+[options]
+errors die
+encoding iso-8859-1
+
+[input]
+=encoding UTF-8
+
+=head1 INVALID
+
+This character cannot be represented in ISO-8859-1, so should produce an
+error.
+
+☺
+
+[output]
+.SH "INVALID"
+.IX Header "INVALID"
+This character cannot be represented in ISO\-8859\-1, so should produce an
+error.
+.PP
+?
+
+[errors]
+Pod input around line 8: "\x{38790}" does not map to iso-8859-1
+
+[exception]
+POD document had syntax errors
diff --git a/cpan/podlators/t/data/snippets/man/iso-8859-1-error-pod b/cpan/podlators/t/data/snippets/man/iso-8859-1-error-pod
new file mode 100644
index 0000000000..29950e09c7
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/iso-8859-1-error-pod
@@ -0,0 +1,29 @@
+[name]
+ISO-8859-1 encoding with invalid character
+
+[options]
+encoding iso-8859-1
+
+[input]
+=encoding UTF-8
+
+=head1 INVALID
+
+This character cannot be represented in ISO-8859-1, so should produce an
+error.
+
+☺
+
+[output]
+.SH "INVALID"
+.IX Header "INVALID"
+This character cannot be represented in ISO\-8859\-1, so should produce an
+error.
+.PP
+?
+.SH "POD ERRORS"
+.IX Header "POD ERRORS"
+Hey! \fBThe above document had some coding errors, which are explained below:\fR
+.IP "Around line 8:" 4
+.IX Item "Around line 8:"
+"\ex{38790}" does not map to iso\-8859\-1
diff --git a/cpan/podlators/t/data/snippets/man/iso-8859-1-roff b/cpan/podlators/t/data/snippets/man/iso-8859-1-roff
new file mode 100644
index 0000000000..8dd2acba5c
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/iso-8859-1-roff
@@ -0,0 +1,31 @@
+[name]
+ISO-8859-1 encoding with *roff output
+
+[options]
+encoding roff
+
+[input]
+=encoding iso-8859-1
+
+=head1 ACCENTS
+
+Beyoncé! Beyoncé! Beyoncé!!
+
+ Beyoncé! Beyoncé!
+ Beyoncé! Beyoncé!
+ Beyoncé! Beyoncé!
+
+Older versions didn't convert Beyoncé in verbatim.
+
+[output]
+.SH "ACCENTS"
+.IX Header "ACCENTS"
+Beyonce\*'! Beyonce\*'! Beyonce\*'!!
+.PP
+.Vb 3
+\& Beyonce\*'! Beyonce\*'!
+\& Beyonce\*'! Beyonce\*'!
+\& Beyonce\*'! Beyonce\*'!
+.Ve
+.PP
+Older versions didn't convert Beyonce\*' in verbatim.
diff --git a/cpan/podlators/t/data/snippets/man/language b/cpan/podlators/t/data/snippets/man/language
new file mode 100644
index 0000000000..3d39941c51
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/language
@@ -0,0 +1,19 @@
+[name]
+Hyphenation language
+
+[options]
+language ja
+
+[input]
+=encoding utf-8
+
+=head1 JAPANESE
+
+Perl 自身㯠Unicode ã§å‹•ä½œã—ã¾ã™ã€‚Perl スクリプト内ã®æ–‡å­—列リテラルや正è¦è¡¨ç¾ã¯ Unicode ã‚’å‰æã¨ã—ã¦ã„ã¾ã™ã€‚ãã—ã¦å…¥å‡ºåŠ›ã®ãŸã‚ã«ã¯ã€ã“ã‚Œã¾ã§ä½¿ã‚ã‚Œã¦ããŸã•ã¾ã–ã¾ãªæ–‡å­—コードã«å¯¾å¿œã™ã‚‹ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã€ã€Œ Encode ã€ãŒæ¨™æº–装備ã•ã‚Œã¦ãŠã‚Šã€Unicode ã¨ã“れらã®æ–‡å­—コードã®ç›¸äº’変æ›ã‚‚ç°¡å˜ã«è¡Œãˆã‚‹ã‚ˆã†ã«ãªã£ã¦ã„ã¾ã™ã€‚
+
+[output]
+.mso ja.tmac
+.hla ja
+.SH "JAPANESE"
+.IX Header "JAPANESE"
+Perl 自身㯠Unicode ã§å‹•ä½œã—ã¾ã™ã€‚Perl スクリプト内ã®æ–‡å­—列リテラルや正è¦è¡¨ç¾ã¯ Unicode ã‚’å‰æã¨ã—ã¦ã„ã¾ã™ã€‚ãã—ã¦å…¥å‡ºåŠ›ã®ãŸã‚ã«ã¯ã€ã“ã‚Œã¾ã§ä½¿ã‚ã‚Œã¦ããŸã•ã¾ã–ã¾ãªæ–‡å­—コードã«å¯¾å¿œã™ã‚‹ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã€ã€Œ Encode ã€ãŒæ¨™æº–装備ã•ã‚Œã¦ãŠã‚Šã€Unicode ã¨ã“れらã®æ–‡å­—コードã®ç›¸äº’変æ›ã‚‚ç°¡å˜ã«è¡Œãˆã‚‹ã‚ˆã†ã«ãªã£ã¦ã„ã¾ã™ã€‚
diff --git a/cpan/podlators/t/data/snippets/man/link-to-url b/cpan/podlators/t/data/snippets/man/link-to-url
index 7f81e3c7f8..e8b08a1247 100644
--- a/cpan/podlators/t/data/snippets/man/link-to-url
+++ b/cpan/podlators/t/data/snippets/man/link-to-url
@@ -16,7 +16,7 @@ L<[perl #12345]|https://rt.cpan.org/12345>
[output]
.SH "LINK TO URL"
.IX Header "LINK TO URL"
-This is a link <http://www.example.com/> to a \s-1URL.\s0
+This is a link <http://www.example.com/> to a URL.
.PP
The newest version of this document is also available on the World Wide Web at
<http://pod.tst.eu/http://cvs.schmorp.de/rxvt\-unicode/doc/rxvt.7.pod>.
diff --git a/cpan/podlators/t/data/snippets/man/naive b/cpan/podlators/t/data/snippets/man/naive
new file mode 100644
index 0000000000..e36b8b4fde
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/naive
@@ -0,0 +1,14 @@
+[name]
+Handling of E<> Unicode escape
+
+[input]
+=head1 perlfaq4 SNIPPET
+
+The trick to this problem is avoiding accidental autovivification. If
+you want to check three keys deep, you might naE<0xEF>vely try this:
+
+[output]
+.SH "perlfaq4 SNIPPET"
+.IX Header "perlfaq4 SNIPPET"
+The trick to this problem is avoiding accidental autovivification. If
+you want to check three keys deep, you might naïvely try this:
diff --git a/cpan/podlators/t/data/snippets/man/naive-groff b/cpan/podlators/t/data/snippets/man/naive-groff
new file mode 100644
index 0000000000..d169412981
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/naive-groff
@@ -0,0 +1,17 @@
+[name]
+Handling of E<> Unicode escape
+
+[options]
+encoding groff
+
+[input]
+=head1 perlfaq4 SNIPPET
+
+The trick to this problem is avoiding accidental autovivification. If
+you want to check three keys deep, you might naE<0xEF>vely try this:
+
+[output]
+.SH "perlfaq4 SNIPPET"
+.IX Header "perlfaq4 SNIPPET"
+The trick to this problem is avoiding accidental autovivification. If
+you want to check three keys deep, you might na\[u00EF]vely try this:
diff --git a/cpan/podlators/t/data/snippets/man/name-guesswork b/cpan/podlators/t/data/snippets/man/name-guesswork
index 6eecd9a36e..7626aeff2d 100644
--- a/cpan/podlators/t/data/snippets/man/name-guesswork
+++ b/cpan/podlators/t/data/snippets/man/name-guesswork
@@ -4,15 +4,15 @@ No guesswork in NAME
[input]
=head1 NAME
-"Stuff" (no guesswork)
+function() - man(1) $variable
=head2 THINGS
-Oboy, is this C++ "fun" yet! (guesswork)
+function() - man(1) $variable
[output]
.SH "NAME"
-"Stuff" (no guesswork)
-.SS "\s-1THINGS\s0"
+function() \- man(1) $variable
+.SS "THINGS"
.IX Subsection "THINGS"
-Oboy, is this \*(C+ \*(L"fun\*(R" yet! (guesswork)
+\&\fBfunction()\fR \- \fBman\fR\|(1) \f(CW$variable\fR
diff --git a/cpan/podlators/t/data/snippets/man/name-quotes b/cpan/podlators/t/data/snippets/man/name-quotes
new file mode 100644
index 0000000000..0b547f82b4
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/name-quotes
@@ -0,0 +1,15 @@
+[name]
+Honor quote settings in NAME
+
+[options]
+lquote '
+rquote '
+
+[input]
+=head1 NAME
+
+C</etc/blah> - config file for I<blah(1)>
+
+[output]
+.SH "NAME"
+\&'/etc/blah' \- config file for blah(1)
diff --git a/cpan/podlators/t/data/snippets/man/name-quotes-none b/cpan/podlators/t/data/snippets/man/name-quotes-none
new file mode 100644
index 0000000000..3e362f0b0c
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/name-quotes-none
@@ -0,0 +1,14 @@
+[name]
+Honor quote settings in NAME
+
+[options]
+quotes none
+
+[input]
+=head1 NAME
+
+C</etc/blah> - config file for I<blah(1)>
+
+[output]
+.SH "NAME"
+/etc/blah \- config file for blah(1)
diff --git a/cpan/podlators/t/data/snippets/man/non-ascii b/cpan/podlators/t/data/snippets/man/non-ascii
index 739690f9ac..f45d2cc793 100644
--- a/cpan/podlators/t/data/snippets/man/non-ascii
+++ b/cpan/podlators/t/data/snippets/man/non-ascii
@@ -1,6 +1,9 @@
[name]
Non-ASCII character
+[options]
+encoding roff
+
[input]
=head1 YEN
diff --git a/cpan/podlators/t/data/snippets/man/nonbreaking-space-l b/cpan/podlators/t/data/snippets/man/nonbreaking-space-l
new file mode 100644
index 0000000000..8908df347c
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/nonbreaking-space-l
@@ -0,0 +1,28 @@
+[name]
+S<> wrapping L<>
+
+[input]
+=head1 URLS
+
+SZ<><> wrapping LZ<><> should make the space between the anchor and URL
+non-breaking and thus keep them together.
+
+L<perl> L<Net::DNS> L<Net::DNS::RR> L<Net::DNS::SEC>
+S<L<RFC2535|https://tools.ietf.org/html/rfc2535>>
+S<L<RFC2536|https://tools.ietf.org/html/rfc2536>>
+S<L<RFC2931|https://tools.ietf.org/html/rfc2931>>
+S<L<RFC3110|https://tools.ietf.org/html/rfc3110>>
+S<L<RFC4034|https://tools.ietf.org/html/rfc4034>>
+
+[output]
+.SH "URLS"
+.IX Header "URLS"
+S<> wrapping L<> should make the space between the anchor and URL
+non-breaking and thus keep them together.
+.PP
+perl Net::DNS Net::DNS::RR Net::DNS::SEC
+RFC2535\ <https://tools.ietf.org/html/rfc2535>
+RFC2536\ <https://tools.ietf.org/html/rfc2536>
+RFC2931\ <https://tools.ietf.org/html/rfc2931>
+RFC3110\ <https://tools.ietf.org/html/rfc3110>
+RFC4034\ <https://tools.ietf.org/html/rfc4034>
diff --git a/cpan/podlators/t/data/snippets/man/paired-quotes b/cpan/podlators/t/data/snippets/man/paired-quotes
deleted file mode 100644
index f81ed8a2a4..0000000000
--- a/cpan/podlators/t/data/snippets/man/paired-quotes
+++ /dev/null
@@ -1,20 +0,0 @@
-[name]
-Paired quotes
-
-[input]
-=head1 SEQS
-
-"=over ... Z<>=back"
-
-"SE<lt>...E<gt>"
-
-The quotes should be converted in the above to paired quotes.
-
-[output]
-.SH "SEQS"
-.IX Header "SEQS"
-\&\*(L"=over ... =back\*(R"
-.PP
-\&\*(L"S<...>\*(R"
-.PP
-The quotes should be converted in the above to paired quotes.
diff --git a/cpan/podlators/t/data/snippets/man/small-caps-magic b/cpan/podlators/t/data/snippets/man/small-caps-magic
deleted file mode 100644
index bb5fea6c07..0000000000
--- a/cpan/podlators/t/data/snippets/man/small-caps-magic
+++ /dev/null
@@ -1,12 +0,0 @@
-[name]
-Small caps and unbreakable magic
-
-[input]
-=head1 SE<lt>E<gt> MAGIC
-
-Magic should be applied S<RISC OS> to that.
-
-[output]
-.SH "S<> MAGIC"
-.IX Header "S<> MAGIC"
-Magic should be applied \s-1RISC\s0\ \s-1OS\s0 to that.
diff --git a/cpan/podlators/t/data/snippets/man/true-false b/cpan/podlators/t/data/snippets/man/true-false
index 6f0e4e0f3c..6671cca1de 100644
--- a/cpan/podlators/t/data/snippets/man/true-false
+++ b/cpan/podlators/t/data/snippets/man/true-false
@@ -11,6 +11,6 @@ code and got it wrong.
[output]
.SH "TRUE (1)"
.IX Header "TRUE (1)"
-podlators prior to 4.08 misrendered \s-1TRUE\s0 (1) and \s-1FALSE\s0 (0) with escaped nroff
+podlators prior to 4.08 misrendered TRUE (1) and FALSE (0) with escaped nroff
in the output because it tried to apply both small caps and man page reference
code and got it wrong.
diff --git a/cpan/podlators/t/data/snippets/man/uppercase-license b/cpan/podlators/t/data/snippets/man/uppercase-license
deleted file mode 100644
index f49baa3318..0000000000
--- a/cpan/podlators/t/data/snippets/man/uppercase-license
+++ /dev/null
@@ -1,48 +0,0 @@
-[name]
-Uppercase license text
-
-[input]
-=head1 Uppercase License
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-SPDX-License-Identifier: MIT
-
-[output]
-.SH "Uppercase License"
-.IX Header "Uppercase License"
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the \*(L"Software\*(R"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-.PP
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-.PP
-\&\s-1THE SOFTWARE IS PROVIDED \*(L"AS IS\*(R", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\s0
-.PP
-SPDX-License-Identifier: \s-1MIT\s0
diff --git a/cpan/podlators/t/data/snippets/man/utf8-nonbreaking b/cpan/podlators/t/data/snippets/man/utf8-nonbreaking
index 8198a77ece..378397ddc0 100644
--- a/cpan/podlators/t/data/snippets/man/utf8-nonbreaking
+++ b/cpan/podlators/t/data/snippets/man/utf8-nonbreaking
@@ -2,7 +2,7 @@
UTF-8 non-breaking space
[options]
-utf8 1
+encoding utf-8
[input]
=encoding utf-8
@@ -14,4 +14,4 @@ This is S<non-breaking output>.
[output]
.SH "S<> output with UTF\-8"
.IX Header "S<> output with UTF-8"
-This is non-breaking output.
+This is non-breaking\ output.
diff --git a/cpan/podlators/t/data/snippets/man/zero-width-space b/cpan/podlators/t/data/snippets/man/zero-width-space
new file mode 100644
index 0000000000..3911f9c4e2
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/man/zero-width-space
@@ -0,0 +1,10 @@
+[name]
+Zero-width spaces
+
+[input]
+=pod
+
+B<DEF:>I<E<lt>vnameE<gt>>=I<E<lt>rrdfileE<gt>>:I<E<lt>ds-nameE<gt>>:I<E<lt>CFE<gt>>[:step=I<E<lt>stepE<gt>>][:start=I<E<lt>timeE<gt>>]E<0x200B>[:end=I<E<lt>timeE<gt>>]E<0x200B>[:reduce=I<E<lt>B<CF>E<gt>>]E<0x200B>[:daemon=I<E<lt>addressE<gt>>]
+
+[output]
+\&\fBDEF:\fR\fI<vname>\fR=\fI<rrdfile>\fR:\fI<ds\-name>\fR:\fI<CF>\fR[:step=\fI<step>\fR][:start=\fI<time>\fR]\:[:end=\fI<time>\fR]\:[:reduce=\fI<\fR\f(BICF\fR\fI>\fR]\:[:daemon=\fI<address>\fR]
diff --git a/cpan/podlators/t/data/snippets/text/iso-8859-1-error-die b/cpan/podlators/t/data/snippets/text/iso-8859-1-error-die
new file mode 100644
index 0000000000..18f189a8cc
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/iso-8859-1-error-die
@@ -0,0 +1,29 @@
+[name]
+ISO-8859-1 encoding
+
+[options]
+errors die
+encoding iso-8859-1
+
+[input]
+=encoding UTF-8
+
+=head1 INVALID
+
+This character cannot be represented in ISO-8859-1, so should produce an
+error.
+
+☺
+
+[output]
+INVALID
+ This character cannot be represented in ISO-8859-1, so should produce an
+ error.
+
+ ?
+
+[errors]
+Pod input around line 8: "\x{38790}" does not map to iso-8859-1
+
+[exception]
+POD document had syntax errors
diff --git a/cpan/podlators/t/data/snippets/text/iso-8859-1-error-pod b/cpan/podlators/t/data/snippets/text/iso-8859-1-error-pod
new file mode 100644
index 0000000000..c623342e37
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/iso-8859-1-error-pod
@@ -0,0 +1,29 @@
+[name]
+ISO-8859-1 encoding
+
+[options]
+encoding iso-8859-1
+
+[input]
+=encoding UTF-8
+
+=head1 INVALID
+
+This character cannot be represented in ISO-8859-1, so should produce an
+error.
+
+☺
+
+[output]
+INVALID
+ This character cannot be represented in ISO-8859-1, so should produce an
+ error.
+
+ ?
+
+POD ERRORS
+ Hey! The above document had some coding errors, which are explained
+ below:
+
+ Around line 8:
+ "\x{38790}" does not map to iso-8859-1
diff --git a/cpan/podlators/t/data/snippets/text/iso-8859-1-utf8 b/cpan/podlators/t/data/snippets/text/iso-8859-1-utf8
new file mode 100644
index 0000000000..4f14a92fa8
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/iso-8859-1-utf8
@@ -0,0 +1,28 @@
+[name]
+ISO-8859-1 encoding
+
+[options]
+encoding utf-8
+
+[input]
+=encoding iso-8859-1
+
+=head1 ACCENTS
+
+Beyoncé! Beyoncé! Beyoncé!!
+
+ Beyoncé! Beyoncé!
+ Beyoncé! Beyoncé!
+ Beyoncé! Beyoncé!
+
+Older versions didn't convert Beyoncé in verbatim.
+
+[output]
+ACCENTS
+ Beyoncé! Beyoncé! Beyoncé!!
+
+ Beyoncé! Beyoncé!
+ Beyoncé! Beyoncé!
+ Beyoncé! Beyoncé!
+
+ Older versions didn't convert Beyoncé in verbatim.
diff --git a/cpan/podlators/t/data/snippets/text/naive b/cpan/podlators/t/data/snippets/text/naive
new file mode 100644
index 0000000000..28a4630901
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/naive
@@ -0,0 +1,13 @@
+[name]
+Handling of E<> Unicode escape
+
+[input]
+=head1 perlfaq4 SNIPPET
+
+The trick to this problem is avoiding accidental autovivification. If
+you want to check three keys deep, you might naE<0xEF>vely try this:
+
+[output]
+perlfaq4 SNIPPET
+ The trick to this problem is avoiding accidental autovivification. If
+ you want to check three keys deep, you might naïvely try this:
diff --git a/cpan/podlators/t/data/snippets/text/name-quotes b/cpan/podlators/t/data/snippets/text/name-quotes
new file mode 100644
index 0000000000..3a45fc8b63
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/name-quotes
@@ -0,0 +1,14 @@
+[name]
+Honor quote settings in NAME
+
+[options]
+quotes ''
+
+[input]
+=head1 NAME
+
+C</etc/blah> - config file for I<blah(1)>
+
+[output]
+NAME
+ '/etc/blah' - config file for *blah(1)*
diff --git a/cpan/podlators/t/data/snippets/text/name-quotes-none b/cpan/podlators/t/data/snippets/text/name-quotes-none
new file mode 100644
index 0000000000..2911571a8f
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/name-quotes-none
@@ -0,0 +1,14 @@
+[name]
+Honor quote settings in NAME
+
+[options]
+quotes none
+
+[input]
+=head1 NAME
+
+C</etc/blah> - config file for I<blah(1)>
+
+[output]
+NAME
+ /etc/blah - config file for *blah(1)*
diff --git a/cpan/podlators/t/data/snippets/text/non-latin b/cpan/podlators/t/data/snippets/text/non-latin
new file mode 100644
index 0000000000..a20ae8cf8a
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/non-latin
@@ -0,0 +1,30 @@
+[name]
+E<> escapes outside of ISO 8859-1 range
+
+[input]
+=head1 BACKGROUND
+
+Taken from an older version of ack (see podlators bug #102631), this was
+seen in an input file with no =encoding and characers outside of the ISO
+8859-1 range.
+
+=head1 ACKNOWLEDGEMENTS
+
+...
+SE<eacute>bastien FeugE<egrave>re,
+RaE<uacute>l GundE<iacute>n,
+RaE<aacute>l GundE<aacute>n,
+GE<aacute>bor SzabE<oacute>,
+E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason,
+Ask BjE<oslash>rn Hansen,
+Slaven ReziE<0x107>,
+
+[output]
+BACKGROUND
+ Taken from an older version of ack (see podlators bug #102631), this was
+ seen in an input file with no =encoding and characers outside of the ISO
+ 8859-1 range.
+
+ACKNOWLEDGEMENTS
+ ... Sébastien Feugère, Raúl Gundín, Raál Gundán, Gábor Szabó, Ævar
+ Arnfjörð Bjarmason, Ask Bjørn Hansen, Slaven Rezić,
diff --git a/cpan/podlators/t/data/snippets/text/nonbreaking-space-l b/cpan/podlators/t/data/snippets/text/nonbreaking-space-l
new file mode 100644
index 0000000000..18bb60f3ee
--- /dev/null
+++ b/cpan/podlators/t/data/snippets/text/nonbreaking-space-l
@@ -0,0 +1,27 @@
+[name]
+S<> wrapping L<>
+
+[input]
+=head1 URLS
+
+SZ<><> wrapping LZ<><> should make the space between the anchor and URL
+non-breaking and thus keep them together.
+
+L<perl> L<Net::DNS> L<Net::DNS::RR> L<Net::DNS::SEC>
+S<L<RFC2535|https://tools.ietf.org/html/rfc2535>>
+S<L<RFC2536|https://tools.ietf.org/html/rfc2536>>
+S<L<RFC2931|https://tools.ietf.org/html/rfc2931>>
+S<L<RFC3110|https://tools.ietf.org/html/rfc3110>>
+S<L<RFC4034|https://tools.ietf.org/html/rfc4034>>
+
+[output]
+URLS
+ S<> wrapping L<> should make the space between the anchor and URL
+ non-breaking and thus keep them together.
+
+ perl Net::DNS Net::DNS::RR Net::DNS::SEC
+ RFC2535 <https://tools.ietf.org/html/rfc2535>
+ RFC2536 <https://tools.ietf.org/html/rfc2536>
+ RFC2931 <https://tools.ietf.org/html/rfc2931>
+ RFC3110 <https://tools.ietf.org/html/rfc3110>
+ RFC4034 <https://tools.ietf.org/html/rfc4034>
diff --git a/cpan/podlators/t/docs/changes.t b/cpan/podlators/t/docs/changes.t
new file mode 100644
index 0000000000..94b800066c
--- /dev/null
+++ b/cpan/podlators/t/docs/changes.t
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+#
+# Check Changes file for compliance with CPAN::Changes::Spec.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Copyright 2021 Russ Allbery <eagle@eyrie.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+# SPDX-License-Identifier: MIT
+
+use 5.010;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::RRA qw(skip_unless_automated use_prereq);
+
+use Test::More;
+
+# Skip this test for normal user installs.
+skip_unless_automated('Changes format tests');
+
+# Load prerequisite modules.
+use_prereq('Test::CPAN::Changes');
+
+# Run the tests.
+changes_ok();
diff --git a/cpan/podlators/t/docs/pod-spelling.t b/cpan/podlators/t/docs/pod-spelling.t
index 819aa69331..497dce31b8 100644
--- a/cpan/podlators/t/docs/pod-spelling.t
+++ b/cpan/podlators/t/docs/pod-spelling.t
@@ -6,7 +6,7 @@
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2019 Russ Allbery <eagle@eyrie.org>
+# Copyright 2019, 2021 Russ Allbery <eagle@eyrie.org>
# Copyright 2013-2014
# The Board of Trustees of the Leland Stanford Junior University
#
@@ -30,7 +30,7 @@
#
# SPDX-License-Identifier: MIT
-use 5.008;
+use 5.010;
use strict;
use warnings;
@@ -47,13 +47,16 @@ skip_unless_author('Spelling tests');
# Load prerequisite modules.
use_prereq('Test::Spelling');
-# Check all POD in the Perl distribution. Add the examples directory if it
-# exists. Also add any files in usr/bin or usr/sbin, which are widely used in
-# Stanford-internal packages.
+# Check all POD in the Perl distribution. Add the examples and t/lib
+# directories if they exist. Also add any files in usr/bin or usr/sbin, which
+# are widely used in Stanford-internal packages.
my @files = all_pod_files();
if (-d 'examples') {
push(@files, all_pod_files('examples'));
}
+if (-d File::Spec->catfile('t', 'lib')) {
+ push(@files, all_pod_files(File::Spec->catfile('t', 'lib')));
+}
for my $dir (qw(usr/bin usr/sbin)) {
if (-d $dir) {
push(@files, glob("$dir/*"));
diff --git a/cpan/podlators/t/docs/pod.t b/cpan/podlators/t/docs/pod.t
index e7d0231660..85974d82c3 100644
--- a/cpan/podlators/t/docs/pod.t
+++ b/cpan/podlators/t/docs/pod.t
@@ -6,7 +6,7 @@
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2019 Russ Allbery <eagle@eyrie.org>
+# Copyright 2019, 2021 Russ Allbery <eagle@eyrie.org>
# Copyright 2012-2014
# The Board of Trustees of the Leland Stanford Junior University
#
@@ -30,7 +30,7 @@
#
# SPDX-License-Identifier: MIT
-use 5.008;
+use 5.010;
use strict;
use warnings;
@@ -46,13 +46,16 @@ skip_unless_automated('POD syntax tests');
# Load prerequisite modules.
use_prereq('Test::Pod');
-# Check all POD in the Perl distribution. Add the examples directory if it
-# exists. Also add any files in usr/bin or usr/sbin, which are widely used in
-# Stanford-internal packages.
+# Check all POD in the Perl distribution. Add the examples and t/lib
+# directories if they exist. Also add any files in usr/bin or usr/sbin,
+# which are widely used in Stanford-internal packages.
my @files = all_pod_files();
if (-d 'examples') {
push(@files, all_pod_files('examples'));
}
+if (-d File::Spec->catfile('t', 'lib')) {
+ push(@files, all_pod_files(File::Spec->catfile('t', 'lib')));
+}
for my $dir (qw(usr/bin usr/sbin)) {
if (-d $dir) {
push(@files, glob("$dir/*"));
diff --git a/cpan/podlators/t/docs/spdx-license.t b/cpan/podlators/t/docs/spdx-license.t
index 5b34cab493..15ee7e0553 100644
--- a/cpan/podlators/t/docs/spdx-license.t
+++ b/cpan/podlators/t/docs/spdx-license.t
@@ -9,7 +9,7 @@
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Copyright 2018-2019 Russ Allbery <eagle@eyrie.org>
+# Copyright 2018-2021 Russ Allbery <eagle@eyrie.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@@ -31,7 +31,7 @@
#
# SPDX-License-Identifier: MIT
-use 5.008;
+use 5.010;
use strict;
use warnings;
@@ -45,8 +45,9 @@ use Test::More;
# File name (the file without any directory component) and path patterns to
# skip for this check.
## no critic (RegularExpressions::ProhibitFixedStringMatches)
+#<<<
my @IGNORE = (
- qr{ \A Build ( [.] (?!PL) .* )? \z }ixms, # Generated file from Build.PL
+ qr{ \A Build ( [.] (?!PL) .* )? \z }ixms, # Generated file from Build.PL
qr{ \A LICENSE \z }xms, # Generated file, no license itself
qr{ \A (Changes|NEWS|THANKS) \z }xms, # Package license should be fine
qr{ \A TODO \z }xms, # Package license should be fine
@@ -55,20 +56,24 @@ my @IGNORE = (
qr{ \A (MY)? META [.] .* }xms, # Generated file, no license itself
qr{ [.] output \z }xms, # Test data
qr{ pod2htm . [.] tmp \z }xms, # Windows pod2html output
+ qr{ ~ \z }xms, # Backup files
);
my @IGNORE_PATHS = (
- qr{ \A [.] / [.] git/ }xms, # Version control files
- qr{ \A [.] /_build/ }xms, # Module::Build metadata
- qr{ \A [.] /blib/ }xms, # Perl build system artifacts
- qr{ \A [.] /cover_db/ }xms, # Artifacts from coverage testing
- qr{ \A [.] /debian/ }xms, # Found in debian/* branches
- qr{ \A [.] /docs/metadata/ }xms, # Package license should be fine
- qr{ \A [.] /README ( [.] .* )? \z }xms, # Package license should be fine
- qr{ \A [.] /share/ }xms, # Package license should be fine
- qr{ \A [.] /t/data .* /metadata/ }xms, # Test metadata
- qr{ \A [.] /t/data .* /output/ }xms, # Test output
- qr{ \A [.] /t/data .* [.] json \z }xms, # Test metadata
+ qr{ \A [.] / [.] git/ }xms, # Version control files
+ qr{ \A [.] / [.] pc/ }xms, # quilt metadata files
+ qr{ \A [.] /_build/ }xms, # Module::Build metadata
+ qr{ \A [.] /blib/ }xms, # Perl build system artifacts
+ qr{ \A [.] /cover_db/ }xms, # Artifacts from coverage testing
+ qr{ \A [.] /debian/ }xms, # Found in debian/* branches
+ qr{ \A [.] /docs/metadata/ }xms, # Package license should be fine
+ qr{ \A [.] /README ( [.] .* )? \z }xms, # Package license should be fine
+ qr{ \A [.] /share/ }xms, # Package license should be fine
+ qr{ \A [.] /t/data/generate/ }xms, # Test metadata
+ qr{ \A [.] /t/data/spin/ }xms, # Test metadata
+ qr{ \A [.] /t/data/update/ }xms, # Test output
+ qr{ \A [.] /t/data .* [.] json \z }xms, # Test metadata
);
+#>>>
## use critic
# Only run this test during automated testing, since failure doesn't indicate
@@ -82,7 +87,7 @@ skip_unless_automated('SPDX identifier tests');
# Returns: undef
sub check_file {
my $filename = $_;
- my $path = $File::Find::name;
+ my $path = $File::Find::name;
# Ignore files in the whitelist and binary files.
for my $pattern (@IGNORE) {
diff --git a/cpan/podlators/t/docs/synopsis.t b/cpan/podlators/t/docs/synopsis.t
index 1a2fbf1af2..b19b4dd3de 100644
--- a/cpan/podlators/t/docs/synopsis.t
+++ b/cpan/podlators/t/docs/synopsis.t
@@ -6,7 +6,7 @@
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2019 Russ Allbery <eagle@eyrie.org>
+# Copyright 2019, 2021 Russ Allbery <eagle@eyrie.org>
# Copyright 2013-2014
# The Board of Trustees of the Leland Stanford Junior University
#
@@ -30,7 +30,7 @@
#
# SPDX-License-Identifier: MIT
-use 5.008;
+use 5.010;
use strict;
use warnings;
diff --git a/cpan/podlators/t/general/basic.t b/cpan/podlators/t/general/basic.t
index 0feb6a6ed2..a0c84e9d3a 100644
--- a/cpan/podlators/t/general/basic.t
+++ b/cpan/podlators/t/general/basic.t
@@ -12,7 +12,7 @@
# the machinery to run small POD snippets through the specific formatter being
# tested should probably be used instead.
#
-# Copyright 2001-2002, 2004, 2006, 2009, 2012, 2014-2015, 2018-2019
+# Copyright 2001-2002, 2004, 2006, 2009, 2012, 2014-2015, 2018-2019, 2022
# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
@@ -43,27 +43,31 @@ BEGIN {
local $| = 1;
# Hard-code configuration for Term::Cap to get predictable results.
+#<<<
local $ENV{COLUMNS} = 80;
local $ENV{TERM} = 'xterm';
local $ENV{TERMPATH} = File::Spec->catfile('t', 'data', 'termcap');
local $ENV{TERMCAP} = 'xterm:co=#80:do=^J:md=\\E[1m:us=\\E[4m:me=\\E[m';
+#>>>
# Find the source of the test file.
-my $INPUT = File::Spec->catfile('t', 'data', 'basic.pod');
+my $input = File::Spec->catfile('t', 'data', 'basic.pod');
# Map of translators to the file containing the formatted output to compare
# against.
-my %OUTPUT = (
+#<<<
+my %output = (
'Pod::Man' => File::Spec->catfile('t', 'data', 'basic.man'),
'Pod::Text' => File::Spec->catfile('t', 'data', 'basic.txt'),
'Pod::Text::Color' => File::Spec->catfile('t', 'data', 'basic.clr'),
'Pod::Text::Overstrike' => File::Spec->catfile('t', 'data', 'basic.ovr'),
'Pod::Text::Termcap' => File::Spec->catfile('t', 'data', 'basic.cap'),
);
+#>>>
# Walk through teach of the modules and format the sample file, checking to
# ensure the results match the pre-generated file.
-for my $module (sort keys %OUTPUT) {
+for my $module (sort keys %output) {
my $parser = $module->new();
isa_ok($parser, $module, 'parser object');
@@ -71,7 +75,7 @@ for my $module (sort keys %OUTPUT) {
# instead of a file.
my $got;
$parser->output_string(\$got);
- $parser->parse_file($INPUT);
+ $parser->parse_file($input);
# If the test module is Pod::Man, strip off the header. This test does
# not attempt to compare it, since it contains version numbers that
@@ -81,15 +85,15 @@ for my $module (sort keys %OUTPUT) {
}
# Try to convert on EBCDIC boxes so that the test still works.
- if (ord "A" == 193 && $module eq 'Pod::Text::Termcap') {
+ if (ord('A') == 193 && $module eq 'Pod::Text::Termcap') {
$got =~ tr{\033}{\047};
}
# Check the output. If it doesn't match, save the erroneous output in a
# file for later inspection.
- my $expected = slurp($OUTPUT{$module});
+ my $expected = slurp($output{$module});
if (!ok($got eq $expected, "$module output is correct")) {
- my ($suffix) = ($OUTPUT{$module} =~ m{ [.] ([^.]+) \z }xms);
+ my ($suffix) = ($output{$module} =~ m{ [.] ([^.]+) \z }xms);
my $tmpdir = File::Spec->catdir('t', 'tmp');
if (!-d $tmpdir) {
mkdir($tmpdir, 0777);
diff --git a/cpan/podlators/t/lib/Test/Podlators.pm b/cpan/podlators/t/lib/Test/Podlators.pm
index 9254f26468..fa4a8bf931 100644
--- a/cpan/podlators/t/lib/Test/Podlators.pm
+++ b/cpan/podlators/t/lib/Test/Podlators.pm
@@ -280,8 +280,7 @@ sub test_snippet {
$got =~ s{ \n\s+ \z }{\n}xms;
# Check the output, errors, and any exception.
- my $expected = decode($encoding, $data_ref->{output});
- is($got, $expected, "$data_ref->{name}: output");
+ is($got, $data_ref->{output}, "$data_ref->{name}: output");
if ($data_ref->{errors} || $stderr) {
is($stderr, $data_ref->{errors} || q{}, "$data_ref->{name}: errors");
}
@@ -304,7 +303,9 @@ sub test_snippet {
# $snippet - Path to the snippet file defining the test
# $options_ref - Hash of options with the following keys:
# encoding - Expect the snippet to be in this non-standard encoding
-# perlio_utf8 - Set to 1 to set a PerlIO UTF-8 encoding on the output file
+# perlio_utf8 - Set to 1 to set PerlIO UTF-8 encoding on the output file
+# perlio_iso - Set to 1 to set PerlIO ISO 8859-1 encoding on the output file
+# output - Expect the output to be in this non-standard encoding
sub test_snippet_with_io {
my ($class, $snippet, $options_ref) = @_;
my $data_ref = read_snippet($snippet);
@@ -316,6 +317,19 @@ sub test_snippet_with_io {
}
$encoding ||= 'UTF-8';
+ # Determine the encoding to expect for the actual output.
+ my $outencoding;
+ if (defined($options_ref)) {
+ $outencoding = $options_ref->{output};
+ }
+ $outencoding ||= 'UTF-8';
+
+ # Additional test output based on whether we're using PerlIO.
+ my $perlio = q{};
+ if ($options_ref->{perlio_utf8} || $options_ref->{perlio_iso}) {
+ $perlio = ' (PerlIO)';
+ }
+
# Create the formatter object.
my $parser = $class->new(%{ $data_ref->{options} }, name => 'TEST');
isa_ok($parser, $class, 'Parser object');
@@ -342,20 +356,40 @@ sub test_snippet_with_io {
## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
eval 'binmode($output, ":encoding(utf-8)")';
## use critic
+ } elsif ($options_ref->{perlio_iso}) {
+ ## no critic (BuiltinFunctions::ProhibitStringyEval)
+ ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
+ eval 'binmode($output, ":encoding(iso-8859-1)")';
+ ## use critic
}
# Parse the input file into the output file.
$parser->parse_from_file($input_file, $output);
close($output) or BAIL_OUT("cannot flush output to $output_file: $!");
- # Read back in the results. For Pod::Man, also ensure that we didn't
- # output the accent definitions if we wrote UTF-8 output.
+ # Read back in the results. For Pod::Man, also check the coding line, and
+ # ensure that we didn't output the accent definitions if we wrote UTF-8
+ # output.
open(my $results, '<', $output_file)
or BAIL_OUT("cannot open $output_file: $!");
my ($line, $saw_accents);
if ($class eq 'Pod::Man') {
+ $line = <$results>;
+ my $coding = lc($outencoding);
+ if ($outencoding eq 'ascii') {
+ unlike(
+ $line, qr{ mode: [ ] troff }xms,
+ "$data_ref->{name}: no preconv coding line$perlio"
+ );
+ } else {
+ is(
+ $line,
+ qq{.\\\" -*- mode: troff; coding: $coding -*-\n},
+ "$data_ref->{name}: preconv coding line$perlio"
+ );
+ }
while (defined($line = <$results>)) {
- $line = decode('UTF-8', $line);
+ $line = decode($outencoding, $line);
if ($line =~ m{ Accent [ ] mark [ ] definitions }xms) {
$saw_accents = 1;
}
@@ -363,7 +397,7 @@ sub test_snippet_with_io {
}
}
my $saw = do { local $/ = undef; <$results> };
- $saw = decode('UTF-8', $saw);
+ $saw = decode($outencoding, $saw);
$saw =~ s{ \n\s+ \z }{\n}xms;
close($results) or BAIL_OUT("cannot close output file: $!");
@@ -371,11 +405,10 @@ sub test_snippet_with_io {
unlink($input_file, $output_file);
# Check the accent definitions and the output.
- my $perlio = $options_ref->{perlio_utf8} ? ' (PerlIO)' : q{};
if ($class eq 'Pod::Man') {
is(
$saw_accents,
- $data_ref->{options}{utf8} ? undef : 1,
+ ($data_ref->{options}{encoding} || q{}) eq 'roff' ? 1 : undef,
"$data_ref->{name}: accent definitions$perlio"
);
}
@@ -513,11 +546,34 @@ the output portion of the snippet.
The same as test_snippet(), except, rather than parsing the input into a
string buffer, this function uses real, temporary input and output files.
-This can be used to test I/O layer handling and proper encoding.
+This can be used to test I/O layer handling and proper encoding. It also
+does additional tests for the preamble to the *roff output.
+
+OPTIONS, if present, is a reference to a hash of options chosen from the
+following:
+
+=over 4
+
+=item encoding
+
+The encoding to expect from the snippet file. Default if not specified is
+UTF-8.
+
+=item output
+
+The encoding to expect from the output. Default if not specified is UTF-8.
-OPTIONS, if present, is a reference to a hash of options. Currently, only one
-key is supported: C<perlio_utf8>, which, if set to true, will set a PerlIO
-UTF-8 encoding layer on the output file before writing to it.
+=item perlio_iso
+
+If set to true, set a PerlIO ISO-8859-1 encoding layer on the output file
+before writing to it.
+
+=item perlio_utf8
+
+If set to true, set a PerlIO UTF-8 encoding layer on the output file before
+writing to it.
+
+=back
=back
@@ -527,7 +583,7 @@ Russ Allbery <rra@cpan.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2015-2016, 2018-2020 Russ Allbery <rra@cpan.org>
+Copyright 2015-2016, 2018-2020, 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/cpan/podlators/t/lib/Test/RRA.pm b/cpan/podlators/t/lib/Test/RRA.pm
index 1d5e4db23d..a66ef4d43d 100644
--- a/cpan/podlators/t/lib/Test/RRA.pm
+++ b/cpan/podlators/t/lib/Test/RRA.pm
@@ -10,7 +10,7 @@
package Test::RRA;
-use 5.008;
+use 5.010;
use base qw(Exporter);
use strict;
use warnings;
@@ -46,13 +46,13 @@ our (@EXPORT_OK, $VERSION);
# consistency is good).
BEGIN {
@EXPORT_OK = qw(
- is_file_contents skip_unless_author skip_unless_automated use_prereq
+ is_file_contents skip_unless_author skip_unless_automated use_prereq
);
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '8.01';
+ $VERSION = '10.03';
}
# Compare a string to the contents of a file, similar to the standard is()
@@ -83,11 +83,11 @@ sub is_file_contents {
eval {
require IPC::System::Simple;
- my $tmp = File::Temp->new();
+ my $tmp = File::Temp->new();
my $tmpname = $tmp->filename;
print {$tmp} $got or BAIL_OUT("Cannot write to $tmpname: $!\n");
my @command = ('diff', '-u', $expected, $tmpname);
- my $diff = IPC::System::Simple::capturex([0 .. 1], @command);
+ my $diff = IPC::System::Simple::capturex([0 .. 1], @command);
diag($diff);
};
if ($@) {
@@ -165,15 +165,15 @@ sub use_prereq {
## no critic (ValuesAndExpressions::ProhibitImplicitNewlines)
my ($result, $error, $sigdie);
{
- local $@ = undef;
- local $! = undef;
+ local $@ = undef;
+ local $! = undef;
local $SIG{__DIE__} = undef;
$result = eval qq{
package $package;
use $module $version \@imports;
1;
};
- $error = $@;
+ $error = $@;
$sigdie = $SIG{__DIE__} || undef;
}
@@ -196,7 +196,7 @@ __END__
=for stopwords
Allbery Allbery's DESC bareword sublicense MERCHANTABILITY NONINFRINGEMENT
-rra-c-util CPAN
+rra-c-util CPAN diff
=head1 NAME
@@ -238,6 +238,14 @@ should be explicitly imported.
=over 4
+=item is_file_contents(GOT, EXPECTED, MESSAGE)
+
+Check a string against the contents of a file, showing the differences if any
+using diff (if IPC::System::Simple and diff are available). GOT is the output
+the test received. EXPECTED is the path to a file containing the expected
+output (not the output itself). MESSAGE is a message to display alongside the
+test results.
+
=item skip_unless_author(DESC)
Checks whether AUTHOR_TESTING is set in the environment and skips the whole
@@ -275,7 +283,7 @@ Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2016, 2018-2019 Russ Allbery <eagle@eyrie.org>
+Copyright 2016, 2018-2019, 2021 Russ Allbery <eagle@eyrie.org>
Copyright 2013-2014 The Board of Trustees of the Leland Stanford Junior
University
diff --git a/cpan/podlators/t/lib/Test/RRA/Config.pm b/cpan/podlators/t/lib/Test/RRA/Config.pm
index 80a1573941..3c44442f11 100644
--- a/cpan/podlators/t/lib/Test/RRA/Config.pm
+++ b/cpan/podlators/t/lib/Test/RRA/Config.pm
@@ -9,7 +9,7 @@
package Test::RRA::Config;
-use 5.008;
+use 5.010;
use base qw(Exporter);
use strict;
use warnings;
@@ -24,15 +24,15 @@ our (@EXPORT_OK, $VERSION);
# consistency is good).
BEGIN {
@EXPORT_OK = qw(
- $COVERAGE_LEVEL @COVERAGE_SKIP_TESTS @CRITIC_IGNORE $LIBRARY_PATH
- $MINIMUM_VERSION %MINIMUM_VERSION @MODULE_VERSION_IGNORE
- @POD_COVERAGE_EXCLUDE @STRICT_IGNORE @STRICT_PREREQ
+ $COVERAGE_LEVEL @COVERAGE_SKIP_TESTS @CRITIC_IGNORE $LIBRARY_PATH
+ $MINIMUM_VERSION %MINIMUM_VERSION @MODULE_VERSION_IGNORE
+ @POD_COVERAGE_EXCLUDE @STRICT_IGNORE @STRICT_PREREQ
);
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '8.01';
+ $VERSION = '10.03';
}
# If C_TAP_BUILD or C_TAP_SOURCE are set in the environment, look for
@@ -58,7 +58,7 @@ our $COVERAGE_LEVEL = 100;
our @COVERAGE_SKIP_TESTS;
our @CRITIC_IGNORE;
our $LIBRARY_PATH;
-our $MINIMUM_VERSION = '5.008';
+our $MINIMUM_VERSION = '5.010';
our %MINIMUM_VERSION;
our @MODULE_VERSION_IGNORE;
our @POD_COVERAGE_EXCLUDE;
@@ -121,9 +121,9 @@ this setting.
=item @CRITIC_IGNORE
-Additional directories to ignore when doing recursive perlcritic testing. The
-contents of this directory must be either top-level directory names or
-directory names starting with F<tests/>.
+Additional files or directories to ignore when doing recursive perlcritic
+testing. To ignore files that will be installed, the path should start with
+F<blib>.
=item $LIBRARY_PATH
@@ -135,7 +135,7 @@ that Perl scripts can pass a syntax check.
=item $MINIMUM_VERSION
Default minimum version requirement for included Perl scripts. If not given,
-defaults to 5.008.
+defaults to 5.010.
=item %MINIMUM_VERSION
@@ -183,7 +183,7 @@ Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2015-2016, 2019 Russ Allbery <eagle@eyrie.org>
+Copyright 2015-2016, 2019, 2021 Russ Allbery <eagle@eyrie.org>
Copyright 2013-2014 The Board of Trustees of the Leland Stanford Junior
University
diff --git a/cpan/podlators/t/lib/Test/RRA/ModuleVersion.pm b/cpan/podlators/t/lib/Test/RRA/ModuleVersion.pm
index fc8bfbc8de..db75829422 100644
--- a/cpan/podlators/t/lib/Test/RRA/ModuleVersion.pm
+++ b/cpan/podlators/t/lib/Test/RRA/ModuleVersion.pm
@@ -8,7 +8,7 @@
package Test::RRA::ModuleVersion;
-use 5.008;
+use 5.010;
use base qw(Exporter);
use strict;
use warnings;
@@ -29,7 +29,7 @@ BEGIN {
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '8.01';
+ $VERSION = '10.03';
}
# A regular expression matching the version string for a module using the
@@ -103,9 +103,7 @@ sub _module_version {
my ($file) = @_;
open(my $data, q{<}, $file) or die "$0: cannot open $file: $!\n";
while (defined(my $line = <$data>)) {
- if ( $line =~ $REGEX_VERSION_PACKAGE
- || $line =~ $REGEX_VERSION_OLD)
- {
+ if ($line =~ $REGEX_VERSION_PACKAGE || $line =~ $REGEX_VERSION_OLD) {
my ($prefix, $version, $suffix) = ($1, $2, $3);
close($data) or die "$0: error reading from $file: $!\n";
return $version;
@@ -135,13 +133,13 @@ sub _update_module_version {
}
# Scan for the version and replace it.
- open(my $in, q{<}, $file) or die "$0: cannot open $file: $!\n";
+ open(my $in, q{<}, $file) or die "$0: cannot open $file: $!\n";
open(my $out, q{>}, "$file.new")
or die "$0: cannot create $file.new: $!\n";
SCAN:
while (defined(my $line = <$in>)) {
- if ( $line =~ s{ $REGEX_VERSION_PACKAGE }{$1$version$3}xms
- || $line =~ s{ $REGEX_VERSION_OLD }{$1$old_version$3}xms)
+ if ($line =~ s{ $REGEX_VERSION_PACKAGE }{$1$version$3}xms
+ || $line =~ s{ $REGEX_VERSION_OLD }{$1$old_version$3}xms)
{
print {$out} $line or die "$0: cannot write to $file.new: $!\n";
last SCAN;
@@ -151,8 +149,8 @@ sub _update_module_version {
# Copy the rest of the input file to the output file.
print {$out} <$in> or die "$0: cannot write to $file.new: $!\n";
- close($out) or die "$0: cannot flush $file.new: $!\n";
- close($in) or die "$0: error reading from $file: $!\n";
+ close($out) or die "$0: cannot flush $file.new: $!\n";
+ close($in) or die "$0: error reading from $file: $!\n";
# All done. Rename the new file over top of the old file.
rename("$file.new", $file)
@@ -265,7 +263,7 @@ Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2016, 2018-2019 Russ Allbery <eagle@eyrie.org>
+Copyright 2016, 2018-2020, 2022 Russ Allbery <eagle@eyrie.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/cpan/podlators/t/man/empty.t b/cpan/podlators/t/man/empty.t
index c38254e583..9e243afc41 100644
--- a/cpan/podlators/t/man/empty.t
+++ b/cpan/podlators/t/man/empty.t
@@ -2,7 +2,7 @@
#
# Test Pod::Man with a document that produces only errors.
#
-# Copyright 2013, 2016, 2018-2019 Russ Allbery <rra@cpan.org>
+# Copyright 2013, 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.
@@ -31,12 +31,10 @@ local $SIG{__WARN__} = sub { croak($_[0]) };
# Try a POD document where the only command is invalid. Make sure it succeeds
# and doesn't throw an exception.
-## no critic (ValuesAndExpressions::ProhibitEscapedCharacters)
-my $invalid_char = chr utf8::unicode_to_native(0xa0);
+my $invalid_char = chr(utf8::unicode_to_native(0xa0));
ok(eval { $parser->parse_string_document("=$invalid_char") },
'Parsed invalid document');
is($@, q{}, '...with no errors');
-## use critic
# With recent Pod::Simple, there will be a POD ERRORS section. With older
# versions of Pod::Simple, we have to skip the test since it doesn't trigger
diff --git a/cpan/podlators/t/man/encoding.t b/cpan/podlators/t/man/encoding.t
new file mode 100644
index 0000000000..3b658bff5e
--- /dev/null
+++ b/cpan/podlators/t/man/encoding.t
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+#
+# Encoding tests for Pod::Man.
+#
+# This test uses a single test file with UTF-8 characters and escapes and
+# processes it with different encoding configurations for Pod::Man, comparing
+# it with pre-generated and hand-checked output files.
+#
+# The primary purpose of these test files is for portability testing on
+# different operating systems, but this test ensures that they remain accurate
+# for any changes to Pod::Man. It doubles as a test that the preamble is
+# emitted correctly.
+#
+# Copyright 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.
+#
+# SPDX-License-Identifier: GPL-1.0-or-later OR Artistic-1.0-Perl
+
+use 5.008;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use File::Spec;
+use Test::More tests => 4;
+use Test::Podlators qw(slurp);
+
+BEGIN {
+ use_ok('Pod::Man');
+}
+
+# Force the timestamp on the input file since it will otherwise depend on the
+# checkout.
+local $ENV{SOURCE_DATE_EPOCH} = 1664146047;
+
+# Get the path to the input and output files.
+my $input = File::Spec->catfile('t', 'data', 'man', 'encoding.pod');
+#<<<
+my %output = (
+ groff => File::Spec->catfile('t', 'data', 'man', 'encoding.groff'),
+ roff => File::Spec->catfile('t', 'data', 'man', 'encoding.roff'),
+ utf8 => File::Spec->catfile('t', 'data', 'man', 'encoding.utf8'),
+);
+#>>>
+
+# For each encoding, load the input, generate the output, and check that the
+# output matches.
+for my $encoding (sort(keys(%output))) {
+ my $parser = Pod::Man->new(
+ encoding => $encoding,
+ center => 'podlators',
+ release => 'testing',
+ );
+ my $got;
+ $parser->output_string(\$got);
+ $parser->parse_file($input);
+
+ # Strip off the version line.
+ $got =~ s{ ^ [^\n]+ Automatically [ ] generated [ ] by [^\n]+ \n }{}xms;
+
+ # Check the output. If it doesn't match, save the erroneous output in a
+ # file for later inspection.
+ my $expected = slurp($output{$encoding});
+ if (!ok($got eq $expected, "encoding.pod output with $encoding")) {
+ my $tmpdir = File::Spec->catdir('t', 'tmp');
+ if (!-d $tmpdir) {
+ mkdir($tmpdir, 0777);
+ }
+ my $outfile = File::Spec->catfile('t', 'tmp', "encoding$$.$encoding");
+ open(my $output, '>', $outfile)
+ or BAIL_OUT("cannot create $outfile for failed output: $!");
+ print {$output} $got
+ or BAIL_OUT("cannot write failed output to $outfile: $!");
+ close($output)
+ or BAIL_OUT("cannot write failed output to $outfile: $!");
+ diag("Non-matching output left in $outfile");
+ }
+}
diff --git a/cpan/podlators/t/man/iso-8859-1.t b/cpan/podlators/t/man/iso-8859-1.t
index 2b2106f14f..336cd38ad4 100644
--- a/cpan/podlators/t/man/iso-8859-1.t
+++ b/cpan/podlators/t/man/iso-8859-1.t
@@ -2,7 +2,7 @@
#
# Test Pod::Man ISO-8859-1 handling
#
-# Copyright 2016, 2019 Russ Allbery <rra@cpan.org>
+# Copyright 2016, 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.
@@ -15,13 +15,41 @@ use warnings;
use lib 't/lib';
-use Test::More tests => 3;
-use Test::Podlators qw(test_snippet);
+use Test::More tests => 19;
+use Test::Podlators qw(test_snippet test_snippet_with_io);
# Load the module.
BEGIN {
use_ok('Pod::Man');
}
-# Test the snippet with the proper encoding.
-test_snippet('Pod::Man', 'man/iso-8859-1');
+# Test the snippet with the old-school roff encoding. Use _with_io to check
+# that we correctly add the accents preamble.
+test_snippet_with_io('Pod::Man', 'man/iso-8859-1-roff', { output => 'ascii' });
+
+# Test error handling when there are characters that cannot be represented in
+# the output character set.
+test_snippet('Pod::Man', 'man/iso-8859-1-error-die');
+test_snippet('Pod::Man', 'man/iso-8859-1-error-pod');
+
+# Force ISO 8859-1 on all relevant file handles. Hide this in a string eval
+# so that older versions of Perl don't croak and minimum-version tests still
+# pass.
+#
+## no critic (BuiltinFunctions::ProhibitStringyEval)
+## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
+eval 'binmode(\*STDOUT, ":encoding(iso-8859-1)")';
+my $builder = Test::More->builder;
+eval 'binmode($builder->output, ":encoding(iso-8859-1)")';
+eval 'binmode($builder->failure_output, ":encoding(iso-8859-1)")';
+## use critic
+
+# Test the snippet with ISO 8859-1 output, with and without PerlIO layers.
+test_snippet_with_io(
+ 'Pod::Man', 'man/iso-8859-1',
+ { encoding => 'iso-8859-1', output => 'iso-latin-1' }
+);
+test_snippet_with_io(
+ 'Pod::Man', 'man/iso-8859-1',
+ { encoding => 'iso-8859-1', perlio_iso => 1, output => 'iso-latin-1' }
+);
diff --git a/cpan/podlators/t/man/no-encode.t b/cpan/podlators/t/man/no-encode.t
index 209509fb1b..0a807e2581 100644
--- a/cpan/podlators/t/man/no-encode.t
+++ b/cpan/podlators/t/man/no-encode.t
@@ -1,9 +1,9 @@
#!/usr/bin/perl
#
-# Test for graceful degradation to non-utf8 output without Encode module.
+# Test for graceful degradation to non-UTF-8 output without Encode module.
#
# Copyright 2016 Niko Tyni <ntyni@iki.fi>
-# Copyright 2016, 2018-2019 Russ Allbery <rra@cpan.org>
+# Copyright 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.
@@ -14,7 +14,7 @@ use 5.008;
use strict;
use warnings;
-use Test::More tests => 5;
+use Test::More tests => 8;
# Remove the record of the Encode module being loaded if it already was (it
# may have been loaded before the test suite runs), and then make it
@@ -38,41 +38,70 @@ BEGIN {
# Ensure we don't get warnings by throwing an exception if we see any. This
# is overridden below when we enable utf8 and do expect a warning.
-local $SIG{__WARN__} = sub { die join("\n",
- "No warnings expected; instead got:",
- @_);
- };
-# First, check that everything works properly when utf8 isn't set. We expect
-# to get accent-mangled ASCII output. Don't use Test::Podlators, since it
-# wants to import Encode.
-#
-## no critic (ValuesAndExpressions::ProhibitEscapedCharacters)
-my $pod = "=encoding latin1\n\n=head1 NAME\n\nBeyonc"
- . chr(utf8::unicode_to_native(0xE9))
- . "!";
-my $parser = Pod::Man->new(utf8 => 0, name => 'test');
+local $SIG{__WARN__} = sub {
+ my @warnings = @_;
+ die join("\n", "No warnings expected; instead got:", @warnings);
+};
+
+# First, check that everything works properly if an encoding of roff is set.
+# We expect to get accent-mangled ASCII output. Don't use Test::Podlators,
+# since it wants to import Encode.
+my $invalid_char = chr(utf8::unicode_to_native(0xE9));
+my $pod = "=encoding latin1\n\n=head1 NAME\n\nBeyonc${invalid_char}!";
+my $parser = Pod::Man->new(name => 'test', encoding => 'roff');
my $output;
$parser->output_string(\$output);
$parser->parse_string_document($pod);
like(
$output,
qr{ Beyonce\\[*]\' }xms,
- 'Works without Encode for non-utf8 output'
+ 'Works without Encode for roff encoding'
);
-# Now, try with the utf8 option set. We should then get a warning that we're
-# falling back to non-utf8 output.
+# Likewise for an encoding of groff.
+$parser = Pod::Man->new(name => 'test', encoding => 'groff');
+my $output_groff = q{};
+$parser->output_string(\$output_groff);
+$parser->parse_string_document($pod);
+like(
+ $output_groff,
+ qr{ Beyonc\\\[u00E9\] }xms,
+ 'Works without Encode for groff encoding'
+);
+
+# The default output format is UTF-8, so it should produce an error message
+# and then degrade to groff.
+{
+ local $SIG{__WARN__} = sub {
+ like(
+ $_[0],
+ qr{ falling [ ] back [ ] to [ ] groff [ ] escapes }xms,
+ 'Pod::Man warns with no Encode module'
+ );
+ };
+ $parser = Pod::Man->new(name => 'test');
+}
+$output = q{};
+$parser->output_string(\$output);
+$parser->parse_string_document($pod);
+is($output, $output_groff, 'Degraded gracefull to groff output');
+
+# Now try with an explicit output encoding, which should produce an error
+# message and then degrade to groff.
{
local $SIG{__WARN__} = sub {
like(
$_[0],
- qr{ falling [ ] back [ ] to [ ] non-utf8 }xms,
- 'Pod::Man warns on utf8 option with no Encode module'
+ qr{ falling [ ] back [ ] to [ ] groff [ ] escapes }xms,
+ 'Pod::Man warns with no Encode module'
);
};
- $parser = Pod::Man->new(utf8 => 1, name => 'test');
+ $parser = Pod::Man->new(name => 'test', encoding => 'iso-8859-1');
}
-my $output_fallback;
-$parser->output_string(\$output_fallback);
+$output = q{};
+$parser->output_string(\$output);
$parser->parse_string_document($pod);
-is($output_fallback, $output, 'Degraded gracefully to non-utf8 output');
+is(
+ $output, $output_groff,
+ 'Explicit degraded gracefully to groff output'
+);
diff --git a/cpan/podlators/t/man/snippets.t b/cpan/podlators/t/man/snippets.t
index 7e0ad3808f..8b7ad2f471 100644
--- a/cpan/podlators/t/man/snippets.t
+++ b/cpan/podlators/t/man/snippets.t
@@ -2,7 +2,7 @@
#
# Test Pod::Man behavior with various snippets.
#
-# Copyright 2002, 2004, 2006, 2008-2009, 2012-2013, 2015-2016, 2018-2019
+# Copyright 2002, 2004, 2006, 2008-2009, 2012-2013, 2015-2016, 2018-2020, 2022
# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
@@ -16,7 +16,7 @@ use warnings;
use lib 't/lib';
-use Test::More tests => 93;
+use Test::More tests => 113;
use Test::Podlators qw(test_snippet);
# Load the module.
@@ -27,14 +27,16 @@ BEGIN {
# List of snippets run by this test.
my @snippets = qw(
agrave backslash-man-ref bullet-after-nonbullet bullets c-in-header
- c-in-name dollar-magic error-die error-none error-normal
- error-pod error-stderr error-stderr-opt eth fixed-font fixed-font-in-item
- for-blocks hyphen-in-s item-fonts link-quoting link-to-url long-quote
- lquote-and-quote lquote-rquote markup-in-name multiline-x name-guesswork
- nested-lists newlines-in-c non-ascii not-bullet not-numbers nourls
- paired-quotes periods quote-escaping rquote-none small-caps-magic
- soft-hyphens trailing-space true-false uppercase-license x-whitespace
- x-whitespace-entry
+ c-in-name dollar-magic error-die error-none error-normal error-pod
+ error-stderr error-stderr-opt eth fixed-font fixed-font-in-item for-blocks
+ guesswork guesswork-all guesswork-no-quoting guesswork-none
+ guesswork-partial guesswork-quoting hyphen-in-s item-fonts language
+ link-quoting link-to-url long-quote lquote-and-quote lquote-rquote
+ markup-in-name multiline-x naive naive-groff name-guesswork name-quotes
+ name-quotes-none nested-lists newlines-in-c non-ascii nonbreaking-space-l
+ not-bullet not-numbers nourls periods quote-escaping rquote-none
+ soft-hyphens trailing-space true-false x-whitespace x-whitespace-entry
+ zero-width-space
);
# Run all the tests.
diff --git a/cpan/podlators/t/man/utf8-io.t b/cpan/podlators/t/man/utf8-io.t
index 76e21b98f0..a3a401f16e 100644
--- a/cpan/podlators/t/man/utf8-io.t
+++ b/cpan/podlators/t/man/utf8-io.t
@@ -2,7 +2,7 @@
#
# Test Pod::Man UTF-8 handling, with and without PerlIO.
#
-# Copyright 2002, 2004, 2006, 2008-2010, 2012, 2014-2015, 2018-2020
+# Copyright 2002, 2004, 2006, 2008-2010, 2012, 2014-2015, 2018-2020, 2022
# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
@@ -16,7 +16,7 @@ use warnings;
use lib 't/lib';
-use Test::More tests => 13;
+use Test::More tests => 17;
use Test::Podlators qw(test_snippet_with_io);
# Load the module.
diff --git a/cpan/podlators/t/style/minimum-version.t b/cpan/podlators/t/style/minimum-version.t
index 861367de4a..6a5aa8917c 100644
--- a/cpan/podlators/t/style/minimum-version.t
+++ b/cpan/podlators/t/style/minimum-version.t
@@ -6,7 +6,7 @@
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2019 Russ Allbery <eagle@eyrie.org>
+# Copyright 2019, 2021 Russ Allbery <eagle@eyrie.org>
# Copyright 2013-2014
# The Board of Trustees of the Leland Stanford Junior University
#
@@ -30,7 +30,7 @@
#
# SPDX-License-Identifier: MIT
-use 5.008;
+use 5.010;
use strict;
use warnings;
diff --git a/cpan/podlators/t/style/module-version.t b/cpan/podlators/t/style/module-version.t
index 035b596de5..2601f81058 100644
--- a/cpan/podlators/t/style/module-version.t
+++ b/cpan/podlators/t/style/module-version.t
@@ -11,7 +11,7 @@
#
# SPDX-License-Identifier: MIT
-use 5.008;
+use 5.010;
use strict;
use warnings;
@@ -42,9 +42,9 @@ if (@ARGV) {
# Throws: Text exception if MYMETA.json is not found or doesn't contain a
# version
sub dist_version {
- my $json = JSON::PP->new->utf8(1);
+ my $json = JSON::PP->new->utf8(1);
my $metadata = $json->decode(scalar(slurp('MYMETA.json')));
- my $version = $metadata->{version};
+ my $version = $metadata->{version};
if (!defined($version)) {
die "$0: cannot find version number in MYMETA.json\n";
}
@@ -81,9 +81,9 @@ B<module-version.t> [B<--update>]
=head1 REQUIREMENTS
-Perl 5.6.0 or later, the Perl6::Slurp module, and the JSON::PP Perl module,
-both of which are available from CPAN. JSON::PP is also included in Perl core
-in Perl 5.14 and later.
+Perl 5.8 or later, the Perl6::Slurp module, and the JSON::PP Perl module, both
+of which are available from CPAN. JSON::PP is also included in Perl core in
+Perl 5.14 and later.
=head1 DESCRIPTION
@@ -121,7 +121,7 @@ Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2014-2016, 2019 Russ Allbery <eagle@eyrie.org>
+Copyright 2014-2016, 2019-2021 Russ Allbery <eagle@eyrie.org>
Copyright 2013-2014 The Board of Trustees of the Leland Stanford Junior
University
diff --git a/cpan/podlators/t/style/obsolete-strings.t b/cpan/podlators/t/style/obsolete-strings.t
index fca5a80f30..cd028de6a7 100644
--- a/cpan/podlators/t/style/obsolete-strings.t
+++ b/cpan/podlators/t/style/obsolete-strings.t
@@ -9,7 +9,7 @@
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Copyright 2016, 2018-2019 Russ Allbery <eagle@eyrie.org>
+# Copyright 2016, 2018-2021 Russ Allbery <eagle@eyrie.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@@ -31,7 +31,7 @@
#
# SPDX-License-Identifier: MIT
-use 5.008;
+use 5.010;
use strict;
use warnings;
@@ -48,7 +48,7 @@ my @BAD_STRINGS = qw(rra@stanford.edu RRA_MAINTAINER_TESTS);
# File or directory names to always skip.
my %SKIP = map { $_ => 1 } qw(
- .git Changes _build blib cover_db obsolete-strings.t
+ .git .pc Changes _build blib changelog cover_db obsolete-strings.t
);
# Only run this test during automated testing, since failure doesn't indicate
diff --git a/cpan/podlators/t/style/strict.t b/cpan/podlators/t/style/strict.t
index a87c1fabca..a2f5b990e1 100644
--- a/cpan/podlators/t/style/strict.t
+++ b/cpan/podlators/t/style/strict.t
@@ -6,7 +6,7 @@
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2016, 2018-2019 Russ Allbery <eagle@eyrie.org>
+# Copyright 2016, 2018-2021 Russ Allbery <eagle@eyrie.org>
# Copyright 2013-2014
# The Board of Trustees of the Leland Stanford Junior University
#
@@ -30,7 +30,7 @@
#
# SPDX-License-Identifier: MIT
-use 5.008;
+use 5.010;
use strict;
use warnings;
@@ -59,7 +59,7 @@ my %EXCLUDE = map { $_ => 1 } qw(.git blib);
# Returns: 1 if it should be checked, undef otherwise.
sub should_check {
my ($file) = @_;
- return if $EXCLUDE{$file};
+ return if $EXCLUDE{$file};
return 1 if -d $file;
return 1 if $file =~ m{ [.] PL \z }xms;
return;
diff --git a/cpan/podlators/t/text/invalid.t b/cpan/podlators/t/text/invalid.t
index a9666e2501..0b34221ed5 100644
--- a/cpan/podlators/t/text/invalid.t
+++ b/cpan/podlators/t/text/invalid.t
@@ -6,7 +6,7 @@
# section, which previously led to internal errors because state variables
# weren't properly initialized. See CPAN RT #88724.
#
-# Copyright 2013, 2018, 2020 Russ Allbery <rra@cpan.org>
+# Copyright 2013, 2018, 2020, 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.
@@ -54,8 +54,7 @@ sub check_document {
}
# Document whose only content is an invalid command.
-## no critic (ValuesAndExpressions::ProhibitEscapedCharacters)
-my $invalid_char = chr utf8::unicode_to_native(0xa0);
+my $invalid_char = chr(utf8::unicode_to_native(0xa0));
check_document("=$invalid_char", 'invalid command');
# Document containing only a =cut.
diff --git a/cpan/podlators/t/text/iso-8859-1.t b/cpan/podlators/t/text/iso-8859-1.t
index 889d553bd8..b27604a7a9 100644
--- a/cpan/podlators/t/text/iso-8859-1.t
+++ b/cpan/podlators/t/text/iso-8859-1.t
@@ -2,7 +2,7 @@
#
# Test Pod::Text ISO-8859-1 handling
#
-# Copyright 2016, 2019 Russ Allbery <rra@cpan.org>
+# Copyright 2016, 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.
@@ -15,8 +15,8 @@ use warnings;
use lib 't/lib';
-use Test::More tests => 3;
-use Test::Podlators qw(test_snippet);
+use Test::More tests => 13;
+use Test::Podlators qw(test_snippet test_snippet_with_io);
# Load the module.
BEGIN {
@@ -25,3 +25,30 @@ BEGIN {
# Test the snippet with the proper encoding.
test_snippet('Pod::Text', 'text/iso-8859-1', { encoding => 'iso-8859-1' });
+
+# Test error handling when there are characters that cannot be represented in
+# the output character set.
+test_snippet('Pod::Text', 'text/iso-8859-1-error-die');
+test_snippet('Pod::Text', 'text/iso-8859-1-error-pod');
+
+# Force ISO 8859-1 on all relevant file handles. Hide this in a string eval
+# so that older versions of Perl don't croak and minimum-version tests still
+# pass.
+#
+## no critic (BuiltinFunctions::ProhibitStringyEval)
+## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
+eval 'binmode(\*STDOUT, ":encoding(iso-8859-1)")';
+my $builder = Test::More->builder;
+eval 'binmode($builder->output, ":encoding(iso-8859-1)")';
+eval 'binmode($builder->failure_output, ":encoding(iso-8859-1)")';
+## use critic
+
+# Test the snippet with ISO 8859-1 output with a PerlIO layer.
+test_snippet_with_io(
+ 'Pod::Text', 'text/iso-8859-1',
+ { encoding => 'iso-8859-1', output => 'iso-8859-1', perlio_iso => 1 }
+);
+
+# Test the snippet with ISO 8859-1 input but an encoding forcing output to
+# UTF-8.
+test_snippet('Pod::Text', 'text/iso-8859-1-utf8');
diff --git a/cpan/podlators/t/text/snippets.t b/cpan/podlators/t/text/snippets.t
index 7667de794e..8fe6d90779 100644
--- a/cpan/podlators/t/text/snippets.t
+++ b/cpan/podlators/t/text/snippets.t
@@ -2,7 +2,7 @@
#
# Test Pod::Text behavior with various snippets.
#
-# Copyright 2002, 2004, 2006-2009, 2012, 2018-2020
+# Copyright 2002, 2004, 2006-2009, 2012, 2018-2020, 2022
# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
@@ -16,7 +16,7 @@ use warnings;
use lib 't/lib';
-use Test::More tests => 53;
+use Test::More tests => 63;
use Test::Podlators qw(test_snippet);
# Load the module.
@@ -28,7 +28,8 @@ BEGIN {
my @snippets = qw(
alt c-with-spaces code cpp empty error-die error-none error-normal error-pod
error-stderr error-stderr-opt for late-encoding link-rt link-url margin
- nonbreaking-space nourls periods quotes-opt s-whitespace sentence-spacing
+ naive name-quotes name-quotes-none non-latin nonbreaking-space
+ nonbreaking-space-l nourls periods quotes-opt s-whitespace sentence-spacing
utf8 verbatim
);
diff --git a/cpan/podlators/t/text/utf8-io.t b/cpan/podlators/t/text/utf8-io.t
index 2e59c41700..44fb0afd43 100644
--- a/cpan/podlators/t/text/utf8-io.t
+++ b/cpan/podlators/t/text/utf8-io.t
@@ -2,7 +2,7 @@
#
# Test Pod::Text UTF-8 handling, with and without PerlIO.
#
-# Copyright 2002, 2004, 2006-2010, 2012, 2014, 2018, 2020
+# Copyright 2002, 2004, 2006-2010, 2012, 2014, 2018, 2020, 2022
# Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
@@ -45,4 +45,4 @@ for my $snippet (qw(late-encoding s-whitespace utf8)) {
test_snippet_with_io('Pod::Text', 'text/utf8-iso',
{ encoding => 'iso-8859-1' });
test_snippet_with_io('Pod::Text', 'text/utf8-iso',
- { encoding => 'iso-8859-1', perlio_utf8 => 1 });
+ { encoding => 'iso-8859-1', perlio_utf8 => 1, output => 'utf-8' });