File Coverage

blib/lib/Acme/ButFirst.pm
Criterion Covered Total %
statement 13 13 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 18 100.0


line stmt bran cond sub pod time code
1             package Acme::ButFirst;
2              
3 2     2   33363 use 5.006;
  2         7  
  2         85  
4 2     2   11 use strict;
  2         4  
  2         93  
5 2     2   11 use warnings;
  2         7  
  2         74  
6              
7 2     2   2908 use Filter::Simple;
  2         136838  
  2         15  
8              
9             our $VERSION = '1.00';
10              
11             # Yes, this is a recursive regexp. ;)
12              
13             my $block;
14              
15             $block = qr{
16             { # An open-curly
17             (?:
18             (?> [^{}]+ ) # Non-curlies no backtracking.
19             |
20             (??{ $block }) # An embedded block
21             )*
22             } # Close-curly
23             }x;
24              
25             sub _butfirstify {
26              
27             # Continue to re-write our code until no more butfirst
28             # sections exist.
29              
30             # We enclose each pair of blocks transposed inside their
31             # own block. This allows chained but-firsts and
32             # butfirst modifiers on loops to work 'correctly'.
33              
34 2     2   18793 1 while s{ ($block) \s* but \s* first \s* ($block) }
35             {{$2\n$1}}gxs;
36              
37             };
38              
39             # We have to use 'executable' rather than code, as Filter::Simple
40             # sometimes thinks that 'but \s* first' is a bareword string.
41             #
42             # The downside of this is that we may modify some *real* strings
43             # as well as code.
44              
45              
46             FILTER_ONLY executable => \&_butfirstify;
47              
48             1;
49             __END__