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 30     30   355 use strict;
  30         77  
  30         1032  
3 30     30   186 use warnings;
  30         76  
  30         828  
4 30     30   777 use 5.010001;
  30         123  
5              
6 30     30   181 use Pandoc::Elements;
  30         69  
  30         2001  
7              
8             my $IDENTIFIER = qr{[\p{L}\p{N}_-]+};
9             my $NAME = qr{[A-Za-z]+};
10              
11             sub new {
12 169     169 0 396 my ($class, $selector) = @_;
13             # TODO: compile selector
14 169         628 bless { selector => $selector }, $class;
15             }
16              
17             sub match {
18 169     169 0 369 my ($self, $element) = @_;
19              
20 169         647 foreach my $selector ( split /\|/, $self->{selector} ) {
21 332 100       639 return 1 if _match_expression($selector, $element);
22             }
23              
24 88         411 return 0;
25             }
26              
27             sub _match_expression {
28 332     332   593 my ( $selector, $elem ) = @_;
29 332         1175 $selector =~ s/^\s+|\s+$//g;
30              
31             # name
32 332 100 100     2746 return 0
33             if $selector =~ s/^($NAME)\s*//i and lc($1) ne lc( $elem->name );
34 88 100       584 return 1 if $selector eq '';
35              
36             # type
37 17 100       59 if ( $selector =~ s/^:(document|block|inline|meta)\s*// ) {
38 6         17 my $method = "is_$1";
39 6 100       32 return 0 unless $elem->$method;
40 4 100       24 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       67 return 0 unless $elem->isa('Pandoc::Document::AttributesRole');
53 11         27 return _match_attributes($selector, $elem);
54             }
55              
56             # check #id and .class
57             sub _match_attributes {
58 11     11   20 my ( $selector, $elem ) = @_;
59              
60 11         27 $selector =~ s/^\s+|\s+$//g; # trim
61              
62 11         27 while ( $selector ne '' ) {
63 14 100       141 if ( $selector =~ s/^#($IDENTIFIER)\s*// ) {
    50          
64 4 100       370 return 0 unless $elem->id eq $1;
65             }
66             elsif ( $selector =~ s/^\.($IDENTIFIER)\s*// ) {
67 10 100       826 return 0 unless grep { $1 eq $_ } @{ $elem->attr->[1] };
  24         100  
  10         235  
68             }
69             else {
70 0         0 return 0;
71             }
72             }
73              
74 7         99 return 1;
75             }
76              
77             1;
78             __END__