Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with output when extracting sections and there was a previous =begin text block #18

Open
hakonhagland opened this issue Aug 3, 2021 · 0 comments

Comments

@hakonhagland
Copy link

hakonhagland commented Aug 3, 2021

It seems like pod2usage() does not work correctly when extracting sections if there was a previous =begin text block:

use strict;
use warnings;
use Pod::Usage;

pod2usage(-verbose => 99, -sections => 'Two');

=head1 One

=begin text

For non-Latex only.

=end text

=head1 Two

C<Formatting> all I<messed> up!

This script outputs (notice missing spaces between words):

Two:
"Formatting2"allmessed     up!

whereas the expected output would be something like:

Two:
    "Formatting2" all messed up!

I have looked briefly at the source to figure out why this happens. First, when you pass -verbose => 99, combined with -sections => 'foo' to pod2usage() it signals that you want to only print section foo. Internally, a variable USAGE_SKIPPING is used to indicate when to skip a section. Pod::Usage uses Pod::Text as a parent class (which uses Pod::Simple as parent class which uses Pod::Simple::BlackBox as a parent class). In order to implement extracting sections, Pod::Usage overrides _handle_element_end() in Pod::Text, see line 296 (and line 204 in Pod::Text).

If the variable USAGE_SKIPPING is set, it pops the current element off the PENDING stack, see line 344. However, it seems the problem is that if there is a =begin text block, it is handled twice. First at line 905 in _ponder_paragraph_buffer() in Pod::Simple::BlackBox the method _ponder_begin() is called which turns the paragraph type into for at line 1333 and later at line 1349 calls _handle_element_start() in Pod::Text, which pushes the paragraph type onto the PENDING stack only if there is a method called cmd_for, see line 194. Since there is no method called cmd_for the for paragraph type is not pushed onto the PENDING stack.. and later when _ponder_end() is called at line 908 which calls _handle_element_end() (line 1417), Pod::Usage still tries to pop a for paragraph from the PENDING stack, but since there is no such item it instead pops a wrong item off the stack. Now the stack size is one less than it should be and this propagates to all parsing following this point. In particular the check at line 215 in Pod::Text is no longer true which causes the observed behavior with missing spaces.

The problem can be fixed by adding the cmd_for sub manually like this:

use strict;
use warnings;
use Pod::Usage;
{
    no warnings 'once';
    *Pod::Usage::cmd_for = sub { };  # <-- Quick Fix: add cmd_for sub manually
}
pod2usage(-verbose => 99, -sections => 'Two');

I am not sure if this is an issue with Pod::Usage or with Pod::Text and should be fixed there instead?
I can submit a pull request here if you think it should be fixed here.

See also this question on stackoverflow.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant