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>
--------