File Coverage

blib/lib/Pandoc/Selector.pm
Criterion Covered Total %
statement 36 37 97.3
branch 21 22 95.4
condition 3 3 100.0
subroutine 8 8 100.0
pod 0 2 0.0
total 68 72 94.4


line stmt bran cond sub pod time code
1             package Pandoc::Selector;
2 31     31   244 use strict;
  31         77  
  31         951  
3 31     31   191 use warnings;
  31         69  
  31         815  
4 31     31   649 use 5.010001;
  31         122  
5              
6 31     31   199 use Pandoc::Elements;
  31         66  
  31         1830  
7              
8             my $IDENTIFIER = qr{[\p{L}\p{N}_-]+};
9             my $NAME = qr{[A-Za-z]+};
10              
11             sub new {
12 173     173 0 501 my ($class, $selector) = @_;
13             # TODO: compile selector
14 173         770 bless { selector => $selector }, $class;
15             }
16              
17             sub match {
18 173     173 0 410 my ($self, $element) = @_;
19              
20 173         766 foreach my $selector ( split /\|/, $self->{selector} ) {
21 340 100       848 return 1 if _match_expression($selector, $element);
22             }
23              
24 90         523 return 0;
25             }
26              
27             sub _match_expression {
28 340     340   832 my ( $selector, $elem ) = @_;
29 340         1491 $selector =~ s/^\s+|\s+$//g;
30              
31             # name
32 340 100 100     3199 return 0
33             if $selector =~ s/^($NAME)\s*//i and lc($1) ne lc( $elem->name );
34 90 100       739 return 1 if $selector eq '';
35              
36             # type
37 17 100       79 if ( $selector =~ s/^:(document|block|inline|meta)\s*// ) {
38 6         26 my $method = "is_$1";
39 6 100       48 return 0 unless $elem->$method;
40 4 100       36 return 1 if $selector eq '';
41             }
42              
43             # TODO: :method (e.g. :url)
44              
45             # TODO: [:level=1]
46              
47             # TODO []
48              
49             # TODO [@]
50              
51             # id and/or classes
52 12 100       90 return 0 unless $elem->isa('Pandoc::Document::AttributesRole');
53 11         39 return _match_attributes($selector, $elem);
54             }
55              
56             # check #id and .class
57             sub _match_attributes {
58 11     11   88 my ( $selector, $elem ) = @_;
59              
60 11         53 $selector =~ s/^\s+|\s+$//g; # trim
61              
62 11         52 while ( $selector ne '' ) {
63 14 100       197 if ( $selector =~ s/^#($IDENTIFIER)\s*// ) {
    50          
64 4 100       413 return 0 unless $elem->id eq $1;
65             }
66             elsif ( $selector =~ s/^\.($IDENTIFIER)\s*// ) {
67 10 100       954 return 0 unless grep { $1 eq $_ } @{ $elem->attr->[1] };
  24         126  
  10         307  
68             }
69             else {
70 0         0 return 0;
71             }
72             }
73              
74 7         70 return 1;
75             }
76              
77             1;
78             __END__