Pod-Eventual-Reconstruct/lib/Pod/Eventual/Reconstruct/LazyCut.pm
use 5.006;
use strict;
use warnings;
package Pod::Eventual::Reconstruct::LazyCut;
# ABSTRACT: A Subclass of Pod::Eventual::Reconstruct that emits less =cut's
our $VERSION = '1.000002';
our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
use Moo qw( extends has around );
use Carp qw(carp);
use Data::Dump qw(pp);
extends 'Pod::Eventual::Reconstruct';
has 'inpod' => (
is => ro =>,
writer => 'set_inpod',
clearer => 'clear_inpod',
predicate => 'is_inpod',
lazy => 1,
builder => sub { undef },
);
around write_command => sub {
my ( $orig, $self, $event ) = @_;
if ( $event->{type} ne 'command' ) {
return $self->$orig($event);
}
if ( $event->{command} ne 'cut' ) {
my $result = $self->$orig($event);
$self->set_inpod(1);
return $result;
}
if ( $self->is_inpod ) {
my $result = $self->$orig($event);
$self->clear_inpod();
return $result;
}
# Skipping a cut
return $self;
};
around write_text => sub {
my ( $orig, $self, $event ) = @_;
if ( $event->{type} ne 'text' ) {
return $self->$orig($event);
}
if ( not $self->is_inpod ) {
return $self->write_text_outside_pod( $orig, $event );
}
return $self->$orig($event);
};
around write_nonpod => sub {
my ( $orig, $self, $event ) = @_;
if ( $event->{type} ne 'nonpod' ) {
return $self->$orig($event);
}
if ( $self->is_inpod ) {
return $self->write_nonpod_inside_pod( $orig, $event );
}
return $self->$orig($event);
};
no Moo;
sub write_text_outside_pod {
my ( $self, $orig, $event ) = @_;
carp 'POD Text element outside POD ' . pp($event);
return $self->$orig($event);
}
sub write_nonpod_inside_pod {
my ( $self, $orig, $event ) = @_;
carp 'NONPOD element inside POD ' . pp($event);
return $self->$orig($event);
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Pod::Eventual::Reconstruct::LazyCut - A Subclass of Pod::Eventual::Reconstruct that emits less =cut's
=head1 VERSION
version 1.000002
=head1 SYNOPSIS
If you're blindly filtering POD in an Eventual manner, sometimes removing elements
may change the semantics.
For instance, in
codehere
=begin foo
=end foo
=cut
codehere
That C<=cut> is an "End of POD Marker".
However, if you simply remove the elements before the C<=cut>, the semantics change:
codehere
=cut
codehere
Here, C<=cut> marks a "Start of POD" and the second C<codehere> is deemed "in the POD".
This module attempts to keep the document "consistent" by not emitting C<=cut> unless a preceding C<=command> is seen in the output.
Additionally, this module will warn if elements are posted to it in ways that are likely to cause errors, for instance:
=over 4
=item * A POD Text element outside a POD region
=item * A Non-POD element inside a POD region
=back
The specific behavior occurred when hitting these errors can be customized via sub-classing,
and overriding L</write_text_outside_pod> and L</write_nonpod_inside_pod>
=head1 METHODS
=head2 C<set_inpod>
=head2 C<clear_inpod>
=head2 C<is_inpod>
=head2 write_text_outside_pod
Is called when a C<text> event is seen but we don't appear to be inside a C<POD> region.
$recon->write_text_outside_pod( $orig_method, $event );
Default implementation warns via C<Carp> and then emits the element anyway, via
$self->$orig_method( $event )
=head2 write_nonpod_inside_pod
Is called when a C<nonpod> event is seen but we appear to be inside a C<POD> region.
$recon->write_nonpod_inside_pod( $orig_method, $event );
Default implementation warns via C<Carp> and then emits the element anyway, via
$self->$orig_method( $event )
=head1 ATTRIBUTES
=head2 C<inpod>
=begin MetaPOD::JSON v1.0.0
{
"namespace":"Pod::Eventual::Reconstruct::LazyCut",
"inherits":"Pod::Eventual::Reconstruct"
}
=end MetaPOD::JSON
=head1 AUTHOR
Kent Fredric <kentnl@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2017 by Kent Fredric <kentfredric@gmail.com>.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut