File Coverage

blib/lib/Text/APL/Core.pm
Criterion Covered Total %
statement 82 82 100.0
branch 8 12 66.6
condition 5 15 33.3
subroutine 20 20 100.0
pod 0 1 0.0
total 115 130 88.4


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