Perl 的 pod2usage 函数不正确地处理格式化代码

Perl's pod2usage function is incorrectly handling formatting codes

首先,我使用 Ubuntu 20.04 和 Perl v5.30.0;但是,我 运行 在将 macOS High Sierra 与 Perl v5.32.1 结合使用时遇到了同样的问题,因此它不限于一个平台。

我开始使用 Perl 的 Pod::Usage 模块通过调用 pod2usage 来记录我的代码。我很高兴有一些东西可以处理手册页的格式,但是当我注意到 B<text>I<text> 等格式代码在输出手册页中没有正确呈现时,我感到很沮丧。下面是我的终端 window.

的屏幕截图

正如我在说明部分所说,我希望有粗体文本,然后是普通文本,然后是斜体文本。前两组出现在相同的字体中,而斜体部分出现在星号之间以模拟不同的字体。我脚本的源代码如下。

#!/usr/bin/env perl

use strict;
use warnings;
# NOTE: un-commenting the following line produces the "Undefined
#       subroutine" error described below in the post. Otherwise this
#       code executes, though it does not produce the desired output.
# BEGIN { $Pod::Usage::Formatter = "Pod::Perldoc::ToMan"; }

use Getopt::Long qw(GetOptions);
use Pod::Usage qw(pod2usage);

my $man  = 0;
my $help = 0;

GetOptions("help|h" => $help, "man" => $man) || pod2usage(2);
pod2usage(1) if ($help);
pod2usage(-verbose => 2) if ($man);

__END__

=pod

=head1 NAME

Sample POD.

=head1 SYNOPSIS

This is a simple test to see if Perl is correctly formatting POD.

=head1 DESCRIPTION

B<This text should be bold>, this text should be normal,
I<and this text should be italicized>.

=cut

我尝试使用以下代码行更改 POD 格式化程序,我直接从 Pod::Usage page 中获取这些代码,但没有成功。

BEGIN { $Pod::Usage::Formatter = 'Pod::Text::Termcap'; }
use Pod::Usage qw(pod2usage);

经过几个兔子洞,我从命令行调用 perldoc 来读取 POD,然后我将格式化程序更改为 Pod::Perldoc::ToMan,首先使用 -oman,然后通过-M 标志;我通过阅读 perldoc 联机帮助页了解到这些。这产生了预期的结果——虽然斜体文本显示为带下划线,但我接受它。

perldoc -t -oman test.pl
perldoc -t -MPod::Perldoc::ToMan test.pl

认为这可能会解决我的脚本中的问题,我将格式化程序从 "Pod::Text::Termcap" 更改为 "Pod::Perldoc::ToMan",但是这导致了以下意外错误。

Undefined subroutine &main::pod2usage called at test.pl line 16.

我希望 pod2usage 的输出看起来像第二个屏幕截图中显示的那样 — 即使我无法正确呈现斜体。我该怎么做,是否需要更改 POD 格式化程序?

编辑:这是出现在我的文件中的代码,直接从 xclip.

的输出中复制
#!/usr/bin/env perl

use strict;
use warnings;

BEGIN { $Pod::Usage::Formatter = "Pod::Perldoc::ToMan"; }

use Getopt::Long qw(GetOptions);
use Pod::Usage qw(pod2usage);

my $man  = 0;
my $help = 0;

GetOptions("help|h" => $help, "man" => $man) || pod2usage(2);
pod2usage(1) if ($help);
pod2usage(-verbose => 2) if ($man);

__END__

=pod

=head1 NAME

Sample POD.

=head1 SYNOPSIS

This is a simple test to see if Perl is correctly formatting POD.

=head1 DESCRIPTION

B<This text should be bold>, this text should be normal,
I<and this text should be italicized>.

=cut

运行 没有标志的脚本产生零退出状态,没有错误。但是,使用以下标志执行会导致上述 Undefined subroutine 错误。同样,此输出是使用 xclip.

直接从终端收集的
$ perl test.pl -help
Undefined subroutine &main::pod2usage called at test.pl line 15.
$ perl test.pl -man
Undefined subroutine &main::pod2usage called at test.pl line 16.

首先,Pod::Text::Termcap 工作正常。

“用法”是粗体,我加了下划线的I<foo>


其次,您使用的是 perldoc 插件而不是 pod 格式化程序。您应该使用 Pod::Man 而不是 Pod::Perldoc::ToMan.

(Pod::Man 导致与 Pod::Perldoc::ToMan 相同的错误。我将在下面提供解释和解决方法。)

当然,这会生成一个手册页,除非您使用类似以下内容之一调用 nroff,否则它是完全不可读的:

man <( perl a.pl --help )     # Requires bash
perl a.pl --help | nroff -man

不过,文本完全丢失了。

所以这是不行的。坚持 Pod::Text::Termcap.


但是至于你的问题,Pod::Usage.

中有一个错误

大多数导出符号的模块都使用 Exporter。这就是 Pod::Usage 用于导出 pod2usage.

的内容

Exporter有两种使用方式:

  1. 从中继承。

    use Exporter;
    our @EXPORT = qw( pod2usage );
    our @ISA = qw( Exporter );
    
  2. 从中导入 import

    use Exporter qw( import );
    our @EXPORT = qw( pod2usage );
    

这就是 Pod::Usage 的作用:

use Exporter;
our @EXPORT = qw( pod2usage );
our @ISA = $Pod::Usage::Formatter;

如果格式化程序继承自 Exporter(例如 Pod::Text),则此方法有效,但如果格式化程序不继承,则失败。 Pod::Man.

就是这种情况

但是有解决方法。

BEGIN { $Pod::Usage::Formatter = 'Pod::Man'; }
package Pod::Usage { use Exporter qw( import ); }
use Pod::Usage qw( pod2usage );

我已经提交了 ticket


最后,您可能注意到我在上面使用了 --help。您可能会问 --man,您使用 perldoc 而不是 Pod::Usage 的格式化程序。所以玩 Pod::Usage 的格式化程序对 --man 绝对没有影响。不过,-perldocopt 应该可以带您到达您想去的地方。