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   205 use strict;
  31         59  
  31         839  
3 31     31   210 use warnings;
  31         55  
  31         670  
4 31     31   676 use 5.010001;
  31         99  
5              
6 31     31   151 use Pandoc::Elements;
  31         53  
  31         1661  
7              
8             my $IDENTIFIER = qr{[\p{L}\p{N}_-]+};
9             my $NAME = qr{[A-Za-z]+};
10              
11             sub new {
12 176     176 0 365 my ($class, $selector) = @_;
13             # TODO: compile selector
14 176         640 bless { selector => $selector }, $class;
15             }
16              
17             sub match {
18 176     176 0 302 my ($self, $element) = @_;
19              
20 176         543 foreach my $selector ( split /\|/, $self->{selector} ) {
21 343 100       611 return 1 if _match_expression($selector, $element);
22             }
23              
24 92         406 return 0;
25             }
26              
27             sub _match_expression {
28 343     343   732 my ( $selector, $elem ) = @_;
29 343         1077 $selector =~ s/^\s+|\s+$//g;
30              
31             # name
32 343 100 100     2975 return 0
33             if $selector =~ s/^($NAME)\s*//i and lc($1) ne lc( $elem->name );
34 91 100       497 return 1 if $selector eq '';
35              
36             # type
37 17 100       58 if ( $selector =~ s/^:(document|block|inline|meta)\s*// ) {
38 6         17 my $method = "is_$1";
39 6 100       35 return 0 unless $elem->$method;
40 4 100       29 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       70 return 0 unless $elem->isa('Pandoc::Document::AttributesRole');
53 11         28 return _match_attributes($selector, $elem);
54             }
55              
56             # check #id and .class
57             sub _match_attributes {
58 11     11   28 my ( $selector, $elem ) = @_;
59              
60 11         34 $selector =~ s/^\s+|\s+$//g; # trim
61              
62 11         27 while ( $selector ne '' ) {
63 14 100       151 if ( $selector =~ s/^#($IDENTIFIER)\s*// ) {
    50          
64 4 100       335 return 0 unless $elem->id eq $1;
65             }
66             elsif ( $selector =~ s/^\.($IDENTIFIER)\s*// ) {
67 10 100       787 return 0 unless grep { $1 eq $_ } @{ $elem->attr->[1] };
  24         91  
  10         239  
68             }
69             else {
70 0         0 return 0;
71             }
72             }
73              
74 7         53 return 1;
75             }
76              
77             1;
78             __END__