File Coverage

blib/lib/Lingua/DE/TypoGenerator.pm
Criterion Covered Total %
statement 24 98 24.4
branch 0 24 0.0
condition 0 3 0.0
subroutine 8 15 53.3
pod 0 2 0.0
total 32 142 22.5


line stmt bran cond sub pod time code
1             package Lingua::DE::TypoGenerator;
2              
3 1     1   20231 use strict;
  1         2  
  1         39  
4 1     1   5 use warnings;
  1         2  
  1         34  
5 1     1   4 use constant LDT_VCHARSETS => ( 'ISO-8859-1' ); #, 'ISO-8859-15', 'UTF-8' );
  1         6  
  1         82  
6 1     1   4 use constant LDT_DEFCHARSET => 'ISO-8859-1';
  1         1  
  1         54  
7 1     1   9 use constant LDT_KEYBOARDLAY => ( '1234567890', 'qwertzuiopü', 'asdfghjklöä', 'yxcvbnm' );
  1         1  
  1         45  
8 1     1   4 use vars qw($VERSION @ISA @EXPORT);
  1         2  
  1         98  
9             require 5.8.0;
10              
11             BEGIN {
12 1     1   2 $VERSION = '0.2';
13              
14 1     1   5 use Exporter;
  1         2  
  1         60  
15 1         16 @ISA = qw(Exporter);
16              
17 1         955 @EXPORT = qw(typos);
18             }
19              
20             sub new {
21 0     0 0   my $class = shift;
22 0           my %opt = @_;
23              
24 0           my $self = {
25             charset => $opt{'charset'},
26             };
27            
28             # Check charset
29 0           my $v_charset = 0;
30 0           foreach my $ccharset (LDT_VCHARSETS) {
31 0 0 0       if ($self->{'charset'} and $self->{'charset'} eq $ccharset) {
32 0           $v_charset = 1;
33             }
34             }
35 0 0         if (!$v_charset) { $self->{'charset'} = LDT_DEFCHARSET; }
  0            
36              
37             # Bless and return
38 0           return bless $self, $class;
39             }
40              
41             sub typos {
42 0     0 0   my $self;
43 0 0         if (@_ == 2) {
44 0           $self = shift;
45             }
46 0           my $word = shift;
47              
48             # Self init if required
49 0 0         if (!$self) {
50 0           $self = new('Lingua::DE::TypoGenerator');
51             }
52              
53 0           my @typos = ();
54              
55             # Forget characters
56 0           @typos = (@typos, $self->_typo_forgetchar($word));
57              
58             # Double characters
59 0           @typos = (@typos, $self->_typo_doublechar($word));
60              
61             # Twist characters
62 0           @typos = (@typos, $self->_typo_twistchars($word));
63              
64             # Miss keys
65 0           @typos = (@typos, $self->_typo_misskeys($word));
66              
67             # Sort unique
68 0           @typos = $self->_unique_array(@typos);
69              
70 0           return @typos;
71             }
72              
73             sub _typo_forgetchar {
74 0     0     my $self = shift;
75 0           my $word = shift;
76              
77 0           my @typos = ();
78              
79 0           for (my $i = 0; $i < length($word); $i++) {
80 0           push @typos, substr($word, 0, $i).substr($word, $i + 1);
81             }
82            
83 0           return @typos;
84             }
85              
86             sub _typo_doublechar {
87 0     0     my $self = shift;
88 0           my $word = shift;
89              
90 0           my @typos = ();
91              
92 0           for (my $i = 0; $i < length($word); $i++) {
93 0           push @typos, substr($word, 0, $i).substr($word, $i, 1).substr($word, $i);
94             }
95              
96 0           return @typos;
97             }
98              
99             sub _typo_twistchars {
100 0     0     my $self = shift;
101 0           my $word = shift;
102              
103 0           my @typos = ();
104              
105 0           for (my $i = 0; $i < length($word) - 1; $i++) {
106 0           my @c = split //, $word;
107 0           my $b = $c[$i];
108 0           $c[$i] = $c[$i + 1];
109 0           $c[$i + 1] = $b;
110 0 0         push @typos, join('', @c) unless $#c < 0;
111             }
112              
113 0           return @typos;
114             }
115              
116             sub _typo_misskeys {
117 0     0     my $self = shift;
118 0           my $word = shift;
119              
120 0           my @typos = ();
121 0           my @kblay = LDT_KEYBOARDLAY;
122              
123 0           for (my $i = 0; $i < length($word); $i++) {
124 0           my $c = substr($word, $i, 1);
125 0           my $kl = -1;
126 0           my $ki = -1;
127 0           KBLAYIT: for (my $j = 0; $j < scalar(@kblay); $j++) {
128 0           $ki = index($kblay[$j], $c);
129 0 0         if ($ki > -1) {
130 0           $kl = $j;
131 0           last KBLAYIT;
132             }
133             }
134 0 0         last if $kl == -1;
135 0 0         last if $ki == -1;
136 0           for (my $line = $kl - 1; $line <= $kl + 1; $line++) {
137 0 0         next if $line < 0;
138 0 0         next if $line > $#kblay;
139              
140 0           for (my $col = $ki - 1; $col <= $ki + 1; $col+=2) {
141 0 0         next if $col < 0;
142 0 0         next if $ki > length($kblay[$line]);
143              
144 0           push @typos, substr($word, 0, $i).substr($kblay[$line], $ki, 1).substr($word, $i + 1);
145             }
146             }
147             }
148              
149 0           return @typos;
150             }
151              
152             sub _unique_array {
153 0     0     my $self = shift;
154 0           my @in = @_;
155              
156 0           my %uq = ();
157 0           foreach my $e (@in) {
158 0           $uq{$e} = 1;
159             }
160              
161 0           return sort keys %uq;
162             }
163              
164             # Satisfy require
165             1;
166             __END__