X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FHTML%2FZoom%2FStreamBase.pm;h=1293458e8b5758d4bd59b4cc62fa10f86992e4f4;hb=bce7b3519da39ab703e46aa27e9a5b1a1791279a;hp=96edbf09ab8bb43e9c9d44c7909a2cfcb437fbdb;hpb=3cdbc13fadcd5e13e38f95f37529d2e9f1b50a51;p=catagits%2FHTML-Zoom.git diff --git a/lib/HTML/Zoom/StreamBase.pm b/lib/HTML/Zoom/StreamBase.pm index 96edbf0..1293458 100644 --- a/lib/HTML/Zoom/StreamBase.pm +++ b/lib/HTML/Zoom/StreamBase.pm @@ -1,58 +1,122 @@ package HTML::Zoom::StreamBase; -use strict; -use warnings FATAL => 'all'; +use strictures 1; +use HTML::Zoom::TransformBuilder; + +sub _zconfig { shift->{_zconfig} } sub peek { my ($self) = @_; if (exists $self->{_peeked}) { return ($self->{_peeked}); } - if (my ($peeked) = $self->next) { + if (my ($peeked) = $self->_next(1)) { return ($self->{_peeked} = $peeked); } return; } -sub flatten { - my $source_stream = shift; - require HTML::Zoom::CodeStream; - my $cur_stream; - HTML::Zoom::CodeStream->new({ - code => sub { - return unless $source_stream; - my $next; - until (($next) = ($cur_stream ? $cur_stream->next : ())) { -#::Dwarn $source_stream; - unless (($cur_stream) = $source_stream->next) { - undef $source_stream; return; - } - } -#::Dwarn $next; - return $next; +sub next { + my ($self) = @_; + + # peeked entry so return that + + if (exists $self->{_peeked}) { + if (my $peeked_from = delete $self->{_peeked_from}) { + $peeked_from->next; } + return (delete $self->{_peeked}); + } + + $self->_next; +} + + +sub flatten { + my $self = shift; + require HTML::Zoom::FlattenedStream; + HTML::Zoom::FlattenedStream->new({ + source => $self, + zconfig => $self->_zconfig }); } sub map { - my ($source_stream, $map_func) = @_; - require HTML::Zoom::CodeStream; - HTML::Zoom::CodeStream->new({ - code => sub { - return unless $source_stream; - # If we were aiming for a "true" perl-like map then we should - # elegantly handle the case where the map function returns 0 events - # and the case where it returns >1 - if you're reading this comment - # because you wanted it to do that, now would be the time to fix it :) - if (my ($next) = $source_stream->next) { - #### XXXX collapsing this into a return doesn't work. what the - #### flying fornication ... -- mst - my $mapped = do { local $_ = $next; $map_func->($next) }; - return $mapped; - } - undef $source_stream; return; - } + my ($self, $mapper) = @_; + require HTML::Zoom::MappedStream; + HTML::Zoom::MappedStream->new({ + source => $self, mapper => $mapper, zconfig => $self->_zconfig + }); +} + +sub with_filter { + my ($self, $selector, $filter) = @_; + my $match = $self->_parse_selector($selector); + $self->_zconfig->stream_utils->wrap_with_filter($self, $match, $filter); +} + +sub with_transform { + my ($self, $transform) = @_; + $transform->apply_to_stream($self); +} + +sub select { + my ($self, $selector) = @_; + return HTML::Zoom::TransformBuilder->new({ + zconfig => $self->_zconfig, + selector => $selector, + filters => [], + proto => $self, }); } +sub then { + my ($self) = @_; + # see notes in HTML/Zoom.pm for why this needs to be fixed + $self->select($self->transform->selector); +} + +sub apply { + my ($self, $code) = @_; + local $_ = $self; + $self->$code; +} + +sub apply_if { + my ($self, $predicate, $code) = @_; + if($predicate) { + local $_ = $self; + $self->$code; + } + else { + $self; + } +} + +sub to_html { + my ($self) = @_; + $self->_zconfig->producer->html_from_stream($self); +} + +sub AUTOLOAD { + my ($self, $selector, @args) = @_; + my $sel = $self->select($selector); + my $meth = our $AUTOLOAD; + $meth =~ s/.*:://; + if (ref($selector) eq 'HASH') { + my $ret = $self; + $ret = $ret->_do($_, $meth, @{$selector->{$_}}) for keys %$selector; + $ret; + } else { + $self->_do($selector, $meth, @args); + } +} + +sub _do { + my ($self, $selector, $meth, @args) = @_; + return $self->select($selector)->$meth(@args); +} + +sub DESTROY {} + 1;