package HTML::FormFu::OutputProcessor::StripWhitespace; use Moose; extends 'HTML::FormFu::OutputProcessor'; use HTML::FormFu::Constants qw( $EMPTY_STR ); use HTML::TokeParser::Simple; use List::MoreUtils qw( any ); has collapse_tags => ( is => 'rw', default => sub { [ qw( fieldset form hr legend optgroup option table td th tr ) ] }, lazy => 1, traits => ['Chained'], ); has collapse_consecutive_tags => ( is => 'rw', default => sub { [ qw( span div ) ] }, lazy => 1, traits => ['Chained'], ); sub process { my ( $self, $input ) = @_; my $parser = HTML::TokeParser::Simple->new( \$input ); my @tokens; while ( my $token = $parser->get_token ) { push @tokens, $token; } my $iter = HTML::FormFu::OutputProcessor::StripWhitespace::_iter->new(@tokens); my @collapse = @{ $self->collapse_tags }; my @consecutive = @{ $self->collapse_consecutive_tags }; my $output = $EMPTY_STR; while ( defined( my $token = $iter->next ) ) { if ( $token->is_start_tag ) { my $tag = $token->get_tag; my $prev_tag = $iter->prev_tag_name; if ( any { $tag eq $_ } @collapse ) { # strip \s from before us $output =~ s/ \s+ \z //x; } elsif ( defined $prev_tag ) { # strip \s between for my $consec (@consecutive) { if ( $tag eq $consec && $tag eq $prev_tag ) { $output =~ s/ \s+ \z //x; } } } } elsif ( $token->is_end_tag ) { my $tag = $token->get_tag; my $prev_tag = $iter->prev_tag_name; if ( any { $tag eq $_ } @collapse ) { # strip \s from before us $output =~ s/ \s+ \z //x; } elsif ( defined $prev_tag ) { # strip \s between for my $consec (@consecutive) { if ( $tag eq $consec && $tag eq $prev_tag ) { $output =~ s/ \s+ \z //x; } } } } my $prev_tag = $iter->prev_tag_name; if ( defined $prev_tag && any { $prev_tag eq $_ } @collapse ) { $output =~ s/ \s+ \z //x; my $part = $token->as_is; $part =~ s/ ^ \s+ //x; $output .= $part; } else { $output .= $token->as_is; } } return $output; } __PACKAGE__->meta->make_immutable; package HTML::FormFu::OutputProcessor::StripWhitespace::_iter; use Moose; sub new { my ( $class, @tags ) = @_; my %self = ( tags => \@tags, i => 0, ); return bless \%self, $class; } sub next { my ($self) = @_; return $self->{tags}[ $self->{i}++ ]; } sub prev_tag_name { my ($self) = @_; my $i = $self->{i} - 2; while ( $i >= 0 ) { if ( $self->{tags}[$i]->is_tag ) { return if !$self->{tags}[$i]->is_tag; return $self->{tags}[$i]->get_tag; } --$i; } } __PACKAGE__->meta->make_immutable( inline_constructor => 0 ); 1; __END__ =head1 NAME HTML::FormFu::OutputProcessor::StripWhitespace - Strip shitespace from HTML output =head1 SYNOPSIS --- output_processors: - StripWhitespace =head1 METHODS =head2 collapse_tags =head2 collapse_consecutive_tags =head1 SEE ALSO Is a sub-class of, and inherits methods from L L =head1 AUTHOR Carl Franks C =head1 LICENSE This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut