File Coverage

blib/lib/XML/Grammar/Fiction/FromProto/Parser/QnD.pm
Criterion Covered Total %
statement 18 58 31.0
branch 0 10 0.0
condition 0 9 0.0
subroutine 6 14 42.8
pod n/a
total 24 91 26.3


line stmt bran cond sub pod time code
1             package XML::Grammar::Fiction::FromProto::Parser::QnD;
2              
3 1     1   45999 use strict;
  1         2  
  1         23  
4 1     1   5 use warnings;
  1         1  
  1         21  
5              
6 1     1   230 use MooX 'late';
  1         8889  
  1         5  
7              
8             extends("XML::Grammar::FictionBase::FromProto::Parser::XmlIterator");
9              
10 1     1   24749 use XML::Grammar::Fiction::Struct::Tag;
  1         3  
  1         42  
11 1     1   281 use XML::Grammar::Fiction::Err;
  1         2  
  1         26  
12 1     1   272 use XML::Grammar::FictionBase::Event;
  1         3  
  1         571  
13              
14              
15             our $VERSION = 'v0.14.12';
16              
17             sub _non_tag_text_unit_consume_regex {
18 0     0     return qr{(?:[\<]|^\n?$)}ms;
19             }
20              
21             sub _generate_non_tag_text_event
22             {
23 0     0     my $self = shift;
24              
25 0           my $is_para = $self->at_line_start;
26              
27 0           my $status = $self->_parse_non_tag_text_unit();
28              
29 0 0         if (!defined($status))
30             {
31 0           return;
32             }
33              
34 0           my $elem = $status->{'elem'};
35 0           my $is_para_end = $status->{'para_end'};
36              
37 0           my $in_para = $self->_in_para();
38 0 0 0       if ($is_para && !$in_para)
39             {
40 0           $self->_enqueue_event(
41             XML::Grammar::FictionBase::Event->new(
42             { type => "open", tag => "para", }
43             ),
44             );
45 0           $in_para = 1;
46             }
47              
48 0 0         if (my ($rest) = $elem->get_text() =~ m{\A\+(.*)}ms)
49             {
50 0 0         if ( length($rest) )
51             {
52 0           $self->throw_text_error(
53             'XML::Grammar::Fiction::Err::Parse::ParaOpenPlusNotFollowedByTag',
54             "Got a paragraph opening plus sign not followed by a tag.",
55             );
56             }
57             # Else - do nothing - just ignore the + sign before the
58             # style tag.
59             }
60             else
61             {
62 0           $self->_enqueue_event(
63             XML::Grammar::FictionBase::Event->new(
64             {type => "elem", elem => $elem}
65             )
66             );
67             }
68              
69 0 0 0       if ($is_para_end && $in_para)
70             {
71 0           $self->_enqueue_event(
72             XML::Grammar::FictionBase::Event->new(
73             { type => "close", tag => "para" }
74             )
75             );
76 0           $in_para = 0;
77             }
78              
79 0           return;
80             }
81              
82             before '_generate_text_unit_events' => sub {
83             my $self = shift;
84              
85             $self->skip_multiline_space();
86              
87             return;
88             };
89              
90             sub _calc_open_para
91             {
92 0     0     my $self = shift;
93              
94             return
95 0           XML::Grammar::Fiction::Struct::Tag::Para->new(
96             name => "p",
97             is_standalone => 0,
98             line => $self->line_num(),
99             attrs => [],
100             children => [],
101             );
102             }
103              
104             sub _handle_open_para
105             {
106 0     0     my ($self, $event) = @_;
107              
108 0           $self->_push_tag($self->_calc_open_para());
109              
110 0           $self->_in_para(1);
111              
112 0           return;
113             }
114              
115             sub _handle_close_para
116             {
117 0     0     my ($self, $event) = @_;
118              
119 0           my $open = $self->_pop_tag;
120              
121 0           my $new_elem =
122             $self->_new_para(
123             $open->detach_children(),
124             );
125              
126 0           $self->_add_to_top_tag($new_elem);
127              
128 0           $self->_in_para(0);
129              
130 0           return;
131             }
132              
133             sub _list_valid_tag_events
134             {
135 0     0     return [qw(para)];
136             }
137              
138             before '_handle_close_tag' => sub {
139             my $self = shift;
140              
141             $self->skip_space();
142             };
143              
144             sub _look_ahead_for_tag
145             {
146 0     0     my $self = shift;
147              
148 0           my $l = $self->curr_line_copy();
149              
150 0           my $is_tag_cond = ($$l =~ m{\G<}cg);
151 0   0       my $is_close = $is_tag_cond && ($$l =~ m{\G/}cg);
152              
153 0           return ($is_tag_cond, $is_close);
154             }
155              
156             sub _main_loop_iter_body_prelude
157             {
158 0     0     my $self = shift;
159              
160             # $self->skip_space();
161              
162 0           return 1;
163             }
164              
165             before '_parse_all' => sub {
166             my $self = shift;
167              
168             $self->skip_space();
169              
170             return;
171             };
172              
173              
174             1;
175              
176             __END__