File Coverage

blib/lib/Text/APL/Core.pm
Criterion Covered Total %
statement 84 84 100.0
branch 8 12 66.6
condition 5 15 33.3
subroutine 20 20 100.0
pod 0 1 0.0
total 117 132 88.6


line stmt bran cond sub pod time code
1             package Text::APL::Core;
2              
3 2     2   14 use strict;
  2         4  
  2         55  
4 2     2   11 use warnings;
  2         3  
  2         50  
5              
6 2     2   9 use base 'Text::APL::Base';
  2         5  
  2         847  
7              
8             our $VERSION = '0.09';
9              
10 2     2   728 use Text::APL::Compiler;
  2         5  
  2         53  
11 2     2   762 use Text::APL::Context;
  2         5  
  2         52  
12 2     2   747 use Text::APL::Parser;
  2         4  
  2         53  
13 2     2   835 use Text::APL::Reader;
  2         6  
  2         49  
14 2     2   751 use Text::APL::Translator;
  2         4  
  2         52  
15 2     2   776 use Text::APL::Writer;
  2         4  
  2         1414  
16              
17             sub _BUILD {
18 20     20   30 my $self = shift;
19              
20 20   33     99 $self->{parser} ||= Text::APL::Parser->new;
21 20   33     93 $self->{translator} ||= Text::APL::Translator->new;
22 20   33     83 $self->{compiler} ||= Text::APL::Compiler->new;
23 20   33     44 $self->{reader} ||= Text::APL::Reader->new;
24 20   33     66 $self->{writer} ||= Text::APL::Writer->new;
25             }
26              
27             sub render {
28 22     22 0 100 my $self = shift;
29 22         66 my (%params) = @_;
30              
31 22         39 my $return = '';
32              
33             my $writer =
34             $self->{writer}
35 22 50       79 ->build(exists $params{output} ? $params{output} : \$return);
36              
37             my $context = Text::APL::Context->new(
38             helpers => $params{helpers},
39             vars => $params{vars},
40             name => $params{name}
41 22         104 );
42 22     7   115 $context->add_helper(__print => sub { $writer->(@_) });
  7         20  
43             $context->add_helper(
44             __print_escaped => sub {
45 18     18   38 my ($input) = @_;
46              
47 18 50       39 return $writer->('') unless defined $input;
48              
49 18         37 for ($input) { s/&/&/g; s//>/g; s/"/"/g; s/'/'/g }
  18         41  
  18         33  
  18         33  
  18         28  
  18         32  
50              
51 18         44 $writer->($input);
52             }
53 22         95 );
54              
55             $self->_process(
56             $params{input},
57             $context,
58             sub {
59 21     21   38 my $self = shift;
60 21         50 my ($sub_ref) = @_;
61              
62 21         556 $sub_ref->($context);
63              
64 21         50 $writer->();
65             }
66 22         98 );
67              
68 21 50       436 return exists $params{output} ? $self : $return;
69             }
70              
71             sub _process {
72 20     20   31 my $self = shift;
73 20         37 my ($input, $context, $cb) = @_;
74              
75             $self->_parse(
76             $input => sub {
77 20     20   28 my $self = shift;
78 20         34 my ($tape) = @_;
79              
80 20         48 my $code = $self->_translate($tape);
81              
82 20         47 my $sub_ref = $self->_compile($code, $context);
83              
84 19         58 $cb->($self, $sub_ref);
85             }
86 20         69 );
87             }
88              
89             sub _parse {
90 20     20   29 my $self = shift;
91 20         37 my ($input, $cb) = @_;
92              
93 20         34 my $parser = $self->{parser};
94              
95 20         48 my $reader = $self->{reader}->build($input);
96              
97 20         31 my $tape = [];
98             my $reader_cb = sub {
99 40     40   84 my ($chunk) = @_;
100              
101 40 100       74 if (!defined $chunk) {
102 20         43 my $leftover = $parser->parse();
103 20 50       67 push @$tape, @$leftover if $leftover;
104              
105 20         42 $cb->($self, $tape);
106             }
107             else {
108 20         46 my $subtape = $parser->parse($chunk);
109 20 100       80 push @$tape, @$subtape if @$subtape;
110             }
111 20         61 };
112              
113 20         51 $reader->($reader_cb, $input);
114             }
115              
116             sub _translate {
117 20     20   25 my $self = shift;
118 20         29 my ($tape) = @_;
119              
120 20         57 return $self->{translator}->translate($tape);
121             }
122              
123             sub _compile {
124 21     21   33 my $self = shift;
125 21         38 my ($code, $context) = @_;
126              
127 21         58 return $self->{compiler}->compile($code, $context);
128             }
129              
130             1;
131             __END__