package main; use Smart::Comments; { my @elements; @elements = (Element::PlainText->new(' *** Sample sites ***'), Element::URI->new('http://1.com/3rd'), Element::URI->new('http://3.com/2nd/'), Element::URI->new('http://2.com/1st/')); { ### not sorted, not filtered: my $page = Page->new(@elements); print $page->out(); } print "\n--------\n"; { ### sorted: my $page = Page->new(Element::Container::Sort->new(@elements)); print $page->out(); } print "\n--------\n"; { ### link list: my $page = Page->new(Element::Container::Filter->new(@elements)); print $page->out(); } print "\n--------\n"; { ### link list sorted by label: my $page = Page->new(Element::Container::Sort->new(Element::Container::Filter->new(@elements))); print $page->out(); } print "\n--------\n"; } package Page; sub new { my $class = shift; bless { element => [@_] }, $class; } sub contents { my $self = shift; map { $_->contents() } @{$self->{element}}; } sub out { my $self = shift; join "\n", map { $_->out() } $self->contents(); } sub raw { my $self = shift; join '', map { $_->raw() } $self->contents(); } package Element::Container::Sort; sub new { my $class = shift; bless { element => [@_] }, $class; } sub contents { my $self = shift; my @r; foreach (@{$self->{element}}){ push @r, $_->contents(); } sort { $a->raw() cmp $b->raw() } @r; } sub out { my $self = shift; map { $_->out() } $self->contents(); } sub raw { my $self = shift; join '', map { $_->raw() } $self->contents(); } package Element::Container::Filter; sub new { my $class = shift; bless { element => [@_] }, $class; } sub contents { my $self = shift; my @r; foreach (@{$self->{element}}){ push @r, map { $_->label() =~ m%http://[^/]*/([^/]*)%; ref($_)->new($_->uri(), $1); } grep { $_->can('label') } $_->contents(); } @r; } sub out { my $self = shift; map { $_->out() } $self->contents(); } sub raw { my $self = shift; join '', map { $_->raw() } $self->contents(); } package Element::URI; sub new { my $class = shift; my($uri, $label) = @_; $label = $label ? $label : $uri; bless { uri => $uri, label => $label }, $class; } sub contents { $_[0]; } sub out { my $self = shift; '<a href="'.$self->{uri}.'">'.$self->{label}.'</a>'; } sub raw { my $self = shift; $self->{label}; } sub uri { my $self = shift; $self->{uri}; } sub label { my $self = shift; $self->{label}; } package Element::PlainText; sub new { my $class = shift; bless { text => $_[0] }, $class; } sub contents { $_[0]; } sub out { $_[0]->{text}; } sub raw { $_[0]->{text}; }
### not sorted, not filtered: *** Sample sites *** <a href="http://1.com/3rd">http://1.com/3rd</a> <a href="http://3.com/2nd/">http://3.com/2nd/</a> <a href="http://2.com/1st/">http://2.com/1st/</a> -------- ### sorted: *** Sample sites *** <a href="http://1.com/3rd">http://1.com/3rd</a> <a href="http://2.com/1st/">http://2.com/1st/</a> <a href="http://3.com/2nd/">http://3.com/2nd/</a> -------- ### link list: <a href="http://1.com/3rd">3rd</a> <a href="http://3.com/2nd/">2nd</a> <a href="http://2.com/1st/">1st</a> -------- ### link list sorted by label: <a href="http://2.com/1st/">1st</a> <a href="http://3.com/2nd/">2nd</a> <a href="http://1.com/3rd">3rd</a> --------