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