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
It seems like
pod2usage()does not work correctly when extracting sections if there was a previous=begin textblock:This script outputs (notice missing spaces between words):
whereas the expected output would be something like:
I have looked briefly at the source to figure out why this happens. First, when you pass
-verbose => 99, combined with-sections => 'foo'topod2usage()it signals that you want to only print sectionfoo. Internally, a variableUSAGE_SKIPPINGis used to indicate when to skip a section.Pod::UsageusesPod::Textas a parent class (which usesPod::Simpleas parent class which usesPod::Simple::BlackBoxas a parent class). In order to implement extracting sections,Pod::Usageoverrides_handle_element_end()inPod::Text, see line 296 (and line 204 inPod::Text).If the variable
USAGE_SKIPPINGis set, it pops the current element off thePENDINGstack, see line 344. However, it seems the problem is that if there is a=begin textblock, it is handled twice. First at line 905 in_ponder_paragraph_buffer()inPod::Simple::BlackBoxthe method_ponder_begin()is called which turns the paragraph type intoforat line 1333 and later at line 1349 calls_handle_element_start()inPod::Text, which pushes the paragraph type onto thePENDINGstack only if there is a method calledcmd_for, see line 194. Since there is no method calledcmd_fortheforparagraph 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::Usagestill tries to pop aforparagraph 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 inPod::Textis no longer true which causes the observed behavior with missing spaces.The problem can be fixed by adding the
cmd_forsub manually like this:I am not sure if this is an issue with
Pod::Usageor withPod::Textand 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