package Template::Flute::Specification::Scoped; use strict; use warnings; use Template::Flute::Specification; use Config::Scoped; =head1 NAME Template::Flute::Specification::Scoped - Config::Scoped Specification Parser =head1 SYNOPSIS $scoped = new Template::Flute::Specification::Scoped; $spec = $scoped->parse_file($specification_file); $spec = $scoped->parse($specification_text); =head1 CONSTRUCTOR =head2 new Create a Template::Flute::Specification::Scoped object. =cut # Constructor sub new { my ($class, $self); my (%params); $class = shift; %params = @_; $self = \%params; bless ($self, $class); } =head1 METHODS =head2 parse [ STRING | SCALARREF ] Parses text from STRING or SCALARREF and returns L object in case of success. =cut sub parse { my ($self, $text) = @_; my ($scoped, $config); # create Config::Scoped parser and parse text $scoped = new Config::Scoped; if (ref($text) eq 'SCALAR') { $config = $scoped->parse(text => $$text); } else { $config = $scoped->parse(text => $text); } $self->{spec} = $self->create_specification($config); return $self->{spec}; } =head2 parse_file FILENAME Parses text from file FILENAME and returns L object in case of success. =cut sub parse_file { my ($self, $file) = @_; my ($scoped, $config, $key, $value, %list); # create Config::Scoped parser and parse file $scoped = new Config::Scoped(file => $file); $config = $scoped->parse(); $self->{spec} = $self->create_specification($config); return $self->{spec}; } =head2 create_specification [ HASHREF ] Takes a L hash reference and returns a L object. Mostly used for parse and parse_file methods. =cut sub create_specification { my ($self, $config) = @_; my ($spec, $scoped, $key, $value, %list, $encoding); # specification object $spec = new Template::Flute::Specification; if ($encoding = $config->{specification}->{encoding}) { $spec->encoding($encoding); } # lists while (($key, $value) = each %{$config->{list}}) { $value->{name} = $key; $list{$key} = $value; } # adding list tokens: params, separators, inputs and filters my ($list); for my $cname (qw/param input filter separator/) { while (($key, $value) = each %{$config->{$cname}}) { $list = delete $value->{list}; $value->{name} = $key; if ($list) { if (exists $list{$list}) { push @{$list{$list}->{$cname}}, {%$value}; } else { die "List missing for $cname $key."; } } else { die "No list assigned to $cname $key."; } } } # adding other tokens: values and i18n for my $cname (qw/value i18n/) { while (($key, $value) = each %{$config->{$cname}}) { $value->{name} = $key; if ($cname eq 'value') { $spec->value_add({value => $value}); } elsif ($cname eq 'i18n') { $spec->i18n_add({i18n => $value}); } } } while (($key, $value) = each %{$config->{list}}) { $spec->list_add({list => $value, param => $value->{param}, separator => $value->{separator}, input => $value->{input}, filter => $value->{filter}, }); } return $spec; } =head2 error Returns last error. =cut sub error { my ($self) = @_; if (@{$self->{errors}}) { return $self->{errors}->[0]->{error}; } } sub _add_error { my ($self, @args) = @_; my (%error); %error = @args; unshift (@{$self->{errors}}, \%error); } =head1 AUTHOR Stefan Hornburg (Racke), =head1 LICENSE AND COPYRIGHT Copyright 2010-2014 Stefan Hornburg (Racke) . This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License. See http://dev.perl.org/licenses/ for more information. =cut 1;