TODO: non-alphabetic (.) support
authorMischa POSLAWSKY <perl@shiar.org>
Thu, 12 Nov 2009 22:24:12 +0000 (23:24 +0100)
committerMischa POSLAWSKY <perl@shiar.org>
Fri, 13 Nov 2009 01:09:50 +0000 (02:09 +0100)
lib/List/Index.pm
t/20-links.t

index 3663c2459422638225058204dbc9854f667f315f..dca0d1f3970b83ffad665fc385ea2ed00b8bd778 100644 (file)
@@ -78,6 +78,7 @@ sub rangematch {
        my ($link) = @_;
        my ($s1, $s2) = $link =~ /([^-]*) - ([^-]*)/x
                or return qr/^\Q$link/i;
+       $s1 =~ s/\.$//;
        my @allow;
 
        if (length $s1) {
@@ -88,9 +89,12 @@ sub rangematch {
                my $prefix = '';
                my $char;
                for my $i (0 .. length($s1) - 1) {
+                       my $lasti = $i == length($s1) - 1;
                        $char = substr $s1, $i, 1;
                        my $next = $char;
-                       $next = chr( ord($char) + 1 ) if length $s1 > $i + 1;
+                       # do not include prefix character in final range
+                       $next = chr( ord($char) + 1 ) unless $lasti;
+
                        my $last = 'z';
                        next if $next gt $last;
                        if (length $s2 > $i) {
@@ -101,10 +105,23 @@ sub rangematch {
                                        next if $next gt $last;
                                }
                        }
+
+                       if ($char eq '.') {
+                               if ($last eq 'z') {
+#                                      push @allow, $prefix if $i and $lasti;
+#                                      next;
+                               }
+#                              if ($last eq 'z') {
+#                                      push @allow, $prefix if $i and $lasti;
+#                                      next;
+#                              }
+                               $next = 'a';
+                       }
+
                        push @allow, $prefix."[$next-$last]";
                }
                continue {
-                       $prefix .= $char;
+                       $prefix .= $char eq '.' ? '[^a-z]' : $char;
                }
        }
 
@@ -120,11 +137,16 @@ sub rangematch {
                                        next if $c1 le $char;
                                }
                        }
-                       push @allow, $prefix."(?![$char-$last])"
+
+                       if ($char eq '.') {
+                               next if $i < length($s2) - 1;
+                       }
+
+                       push @allow, $prefix.'(?!['.($char eq '.' ? 'a' : $char)."-$last])"
                                if $i or $s1 eq '';
                }
                continue {
-                       $prefix .= $char;
+                       $prefix .= $char eq '.' ? '[^a-z]' : $char;
                }
 
                push @allow, $prefix
index 1ae7d4a4a27c0b1137d84e8119e8c223b8d81a22..68432052cb842ef699a1f2de8e11e6cc5efef92c 100644 (file)
@@ -2,7 +2,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 30;
+use Test::More tests => 47;
 use Test::NoWarnings;
 use Data::Dump 'pp';
 
@@ -45,6 +45,30 @@ my @RANGETESTS = (
        ['xxx-qqq' => undef],
        ['xxx-q'   => undef],
        ['qqq-qc'  => undef],
+
+       # non-alphabetic offset
+       [  '.-'    =>          ''],
+       ['...-'    => '(?:[a-z]|[^a-z][a-z])'],
+       [ '.q-'    => '(?:[a-z]|[^a-z][q-z])'],
+       [ '.q-.'   =>          '[^a-z][q-z]'],
+       # limit
+       ['.q.-q'   => '(?:[a-q]|[^a-z][q-z])'],
+       ['..z-q'   => '(?:[a-q]|[^a-z][a-z]|[^a-z][^a-z][z-z])'],
+       ['.q.-z'   => '(?:[a-z]|[^a-z][q-z])'],
+       ['.q.-zz'  => '(?:[a-y]|[^a-z][q-z]|'        .       'z(?![z-z])|zz)'],
+       ['.q..-zz' => '(?:[a-y]|[^a-z][r-z]|[^a-z]q' . '[a-z]|z(?![z-z])|zz)'],
+       # non-alpha limit
+       ['.q.-z.'  => '(?:[a-y]|[^a-z][q-z]|'        .       'z(?![a-z]))'],
+       [ '..-.'   =>                                '(?:[^a-z](?![a-z]))'],
+       [  '.-.'   =>                                         '(?![a-z])'],
+       [   '-.'   =>                                         '(?![a-z])'],
+       [   '-...' =>                                         '(?![a-z])(?!.[a-z])(?!..[a-z])'],
+       [   '-q.'  =>                           '(?:(?![q-z])|q(?![a-z]))'],
+       [   '-q..' =>                           '(?:(?![q-z])|q(?![a-z])(?!.[a-z]))'],
+#      [ '..-...' =>                                '(?:[^a-z](?![a-z])|[^a-z][^a-z](?![a-z]))'],
+#      [  '.-...' =>                                                   '[^a-z][^a-z](?![a-z])'],
+       #
+       [  'a-.'   => undef],
 );
 
 for (@RANGETESTS) {