Decl
view release on metacpan or search on metacpan
lib/Decl/Template.pm view on Meta::CPAN
sub new {
my ($class, %values) = @_;
my $self = bless \%values, $class;
#TODO: 'brackets' split
$self->{left} = '\[\[' unless $self->{left};
$self->{right} = '\]\]' unless $self->{right};
$self->{leftp} = $self->{left};
$self->{leftp} =~ s/\\//g;
$self->{rightp} = $self->{right};
$self->{rightp} =~ s/\\//g;
$self->{valuator} = \&default_valuator unless $self->{valuator};
$self->{leave_misses} = 1 unless defined $self->{leave_misses};
$self->{spanners} = {} unless $self->{spanners};
$self->{spanners}->{with} = \&do_with unless defined $self->{spanners}->{with};
$self->{spanners}->{if} = \&do_if unless defined $self->{spanners}->{if};
$self->{spanners}->{repeat} = \&do_repeat unless defined $self->{spanners}->{repeat};
$self;
}
=head2 default_valuator
Given a value environment (by default, a hashref) and the name of a value, a valuator finds the value.
If nothing else is specified, the hashref valuator is used. In the Decl context, a node will generally
be used and the node's own valuation function is used as the valuator.
=cut
sub default_valuator {
my ($name, $env) = @_;
$$env{$name};
}
=head2 prepare_varname
Given a variable specification, prepare it for use as a lookup key.
=cut
sub prepare_varname {
my ($name) = @_;
$name =~ s/\n */ /sg;
$name =~ s/^ *//g;
$name =~ s/ *$//g;
$name;
}
=head2 parse_spanning_command
Given a spanning command string, parse out the initial word (the command) and leave the arguments (the rest). Drop the . or +.
=cut
sub parse_spanning_command {
my $piece = shift;
$piece =~ s/^[+\.] *//;
split m[ +], $piece, 2;
}
=head2 handle_spanning_command
Given a parsed spanning command and the value object and valuator function to be used, express the command. This is really just
a dispatcher for a command table.
=cut
sub handle_spanning_command {
my ($self, $command, $values, $valuator) = @_;
my $c = $self->{spanners}->{$$command[0]};
return $c->($self, $command, $values, $valuator) if $c;
return ''; # TODO: consider better error handling. As always.
}
=head2 register_spanning_command ($name, $closure)
Here's how you register a spanning command. Just name it and provide a closure for it, and you're good to go.
=cut
sub register_spanning_command {
my ($self, $name, $sub) = @_;
$self->{spanners}->{$name} = $sub;
}
=head2 do_with, do_if, do_repeat, express_repeat
These are our three default spanning commands. More can be added to the table.
The C<express_repeat> does the heavy lifting in expressing the list template and can be recycled in other forms of list template.
=cut
sub do_with {
my ($self, $command, $values, $valuator) = @_;
my $with = do_lookup($$command[1], $values, $valuator);
$self->express_parsed ($$command[2], $with, \&default_valuator);
}
sub do_if {
my ($self, $command, $values, $valuator) = @_;
my $test = do_lookup ($$command[1], $values, $valuator);
if ($test) {
return $self->express_parsed ($$command[2], $values, $valuator);
}
my @alternatives = @{$$command[3]};
foreach my $check (@alternatives) {
if ($$check[0] eq 'elif') {
$test = do_lookup ($$check[1], $values, $valuator);
if ($test) {
return $self->express_parsed ($$check[2], $values, $valuator);
}
}
if ($$check[0] eq 'else') {
( run in 2.047 seconds using v1.01-cache-2.11-cpan-71847e10f99 )