turkish_support 0.3.0 → 1.0.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.hound.yml +3 -0
- data/.rubocop.yml +7 -0
- data/README.md +173 -41
- data/Rakefile +3 -3
- data/lib/turkish_support.rb +6 -6
- data/lib/turkish_support/array_methods.rb +5 -1
- data/lib/turkish_support/constants.rb +47 -14
- data/lib/turkish_support/helpers.rb +112 -0
- data/lib/turkish_support/string_methods.rb +33 -21
- data/lib/turkish_support/version.rb +1 -1
- data/spec/helpers_spec.rb +264 -0
- data/spec/turkish_support_spec.rb +482 -122
- data/turkish_support.gemspec +15 -14
- metadata +13 -9
- data/lib/turkish_support/destructives.rb +0 -17
- data/lib/turkish_support/string_helpers.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fca374a0e22cae4752a98bc96a26b64d99e57612
|
4
|
+
data.tar.gz: 5ff3bac0eb61748ec55b9de97f6fed195f15222a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1682d709edeeb141dc55ff93b9243298ae32892d8fe8e5beeabcc4a9b6d9c4800686a9f2a7d8899e52409e557843fd7dc9c37b89d4a072704314c388372809e7
|
7
|
+
data.tar.gz: a90302ff8136ee2ad490f6746cf1043c1fe61a58e750944fe8c5a21c333a4c8b0cab194f8fc6c637b10cfa3710ce9ea338aac4500ce2491bfdcb6d47ff40d16f
|
data/.gitignore
CHANGED
data/.hound.yml
ADDED
data/.rubocop.yml
ADDED
data/README.md
CHANGED
@@ -4,16 +4,41 @@
|
|
4
4
|
[![Build Status](https://travis-ci.org/sbagdat/turkish_support.svg?branch=master)](https://travis-ci.org/sbagdat/turkish_support)
|
5
5
|
[![Gitter chat](https://badges.gitter.im/sbagdat/turkish_support.png)](https://gitter.im/sbagdat/turkish_support)
|
6
6
|
|
7
|
-
Turkish character support for
|
8
|
-
`String#downcase`, `String#capitalize`, `String#swapcase`, `String#casecmp`, `String#match`, `Array#sort`, and their destructive versions like `Array#sort!` or `String#capitalize!`. It also gives you some bonus methods like `String#titleize`.
|
7
|
+
Turkish character support for core ruby methods. This gem provides support nearly all `String` methods, such as `String#upcase`, `String#downcase`, `String#match`, `String#gsub`. It also provides support for `Array#sort`and some bonus methods like `String#titleize`.
|
9
8
|
|
10
9
|
## Requirements
|
11
10
|
|
12
11
|
* Ruby >= 2.0.0
|
13
12
|
* Rails >= 4.0.0
|
14
13
|
|
15
|
-
__Notice:__ TurkishSupport uses refinements instead of monkey patching. Refinements come with Ruby 2.0.0 as a new feature
|
16
|
-
|
14
|
+
__Notice:__ TurkishSupport uses refinements instead of monkey patching. ~~Refinements come with Ruby 2.0.0 as a new feature and also, it is an experimental feature for now. If you want to more information about refinements, you can see the doc at [http://www.ruby-doc.org/core-2.0.0/doc/syntax/refinements_rdoc.html](http://www.ruby-doc.org/core-2.0.0/doc/syntax/refinements_rdoc.html)~~ *Refinements are not an experimental feature, it is a core feature now.*
|
15
|
+
|
16
|
+
* [Installation](#installation)
|
17
|
+
* [Usage](#usage)
|
18
|
+
* [Using with ruby](#using-with-ruby)
|
19
|
+
* [Using with ruby on rails](#using-with-ruby-on-rails)
|
20
|
+
* [Using Core Methods](#using-core-methods)
|
21
|
+
* [String Methods](#string-methods)
|
22
|
+
* [#[] and #[]=](-and-)
|
23
|
+
* [#=~](#-equal-tilda)
|
24
|
+
* [capitalize](#capitalize-and-capitalize)
|
25
|
+
* [casecmp](#casecmp)
|
26
|
+
* [downcase](#downcase-and-downcase)
|
27
|
+
* [gsub](#gsub-and-gsub)
|
28
|
+
* [index](#index)
|
29
|
+
* [match](#match)
|
30
|
+
* [partition](#partition)
|
31
|
+
* [rpartition](#rpartition)
|
32
|
+
* [rindex](#rpartition)
|
33
|
+
* [scan](#scan)
|
34
|
+
* [slice](#slice-and-slice)
|
35
|
+
* [split](#split)
|
36
|
+
* [sub](#sub-and-sub)
|
37
|
+
* [swapcase](#swapcase-and-swapcase)
|
38
|
+
* [titleize](#titleize-and-titleize)
|
39
|
+
* [upcase](#upcase-and-upcase)
|
40
|
+
* [Array Methods](#array-methods)
|
41
|
+
* [sort](sort-and-sort)
|
17
42
|
|
18
43
|
## Installation
|
19
44
|
|
@@ -29,7 +54,7 @@ Or install it yourself as:
|
|
29
54
|
|
30
55
|
$ gem install turkish_support
|
31
56
|
|
32
|
-
## Usage
|
57
|
+
## Usage
|
33
58
|
|
34
59
|
After the installation of the gem, you should follow these steps.
|
35
60
|
|
@@ -59,99 +84,206 @@ class Test
|
|
59
84
|
end
|
60
85
|
end
|
61
86
|
|
62
|
-
Test.new.up_me('içel')
|
87
|
+
Test.new.up_me('içel') # => "İÇEL"
|
63
88
|
```
|
64
89
|
|
65
90
|
### Using with rails
|
66
91
|
|
67
92
|
__Note:__ You don't need to require, because it is already required by the rails.
|
68
93
|
|
69
|
-
*
|
94
|
+
* You must add `using TurkishSupport` line to the top of the scope.
|
70
95
|
|
71
96
|
```ruby
|
72
97
|
using TurkishSupport
|
73
98
|
|
74
|
-
class SampleModel
|
99
|
+
class SampleModel < ActiveRecord::Base
|
75
100
|
...
|
76
101
|
end
|
77
102
|
```
|
78
103
|
|
79
|
-
|
104
|
+
* If you want to use TurkishSupport with a custom class or a module that is not inherited from any rails tie, you must add `using TurkishSupport` line to the class or module.
|
80
105
|
|
81
|
-
|
106
|
+
```ruby
|
107
|
+
class CustomClass
|
108
|
+
using TurkishSupport
|
109
|
+
|
110
|
+
...
|
111
|
+
end
|
112
|
+
```
|
82
113
|
|
83
|
-
|
114
|
+
### Using Core Methods
|
115
|
+
|
116
|
+
If you want to use original set of the core methods in the same scope, you can use `Object#public_send`:
|
84
117
|
|
85
118
|
```ruby
|
86
119
|
str = 'Bağcılar'
|
120
|
+
str.public_send(:upcase) # => "BAğCıLAR"
|
121
|
+
```
|
87
122
|
|
88
|
-
|
89
|
-
str #=> "Bağcılar"
|
123
|
+
## String Methods
|
90
124
|
|
91
|
-
|
92
|
-
|
125
|
+
### [] and []=
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
'Türkiye Cumhuriyeti'[/\w+/] # => "Türkiye"
|
129
|
+
'Çetin'[/[a-ğ]+/i] # => "Çe"
|
93
130
|
```
|
94
131
|
|
95
|
-
|
132
|
+
### =~ (equal-tilda)
|
96
133
|
|
97
134
|
```ruby
|
98
|
-
|
99
|
-
str.downcase #=> "ismail"
|
135
|
+
'Bağlarbaşı Çarşı Kalabalık' =~ (/[s-ü]+/i) # => 8
|
100
136
|
```
|
101
137
|
|
102
|
-
|
138
|
+
### capitalize and capitalize!
|
103
139
|
|
104
140
|
```ruby
|
105
141
|
str = 'türkÇE desteĞİ'
|
106
|
-
|
142
|
+
|
143
|
+
str.capitalize # => "Türkçe desteği"
|
144
|
+
str.capitalize! # => "Türkçe desteği"
|
107
145
|
```
|
108
146
|
|
109
|
-
|
147
|
+
### casecmp
|
148
|
+
|
110
149
|
```ruby
|
111
|
-
'
|
150
|
+
'sıtKI'.casecmp('SITkı') # => 0
|
112
151
|
```
|
113
152
|
|
114
|
-
|
153
|
+
### downcase and downcase!
|
154
|
+
|
115
155
|
```ruby
|
116
|
-
'
|
156
|
+
str = 'İSMAİL'
|
157
|
+
|
158
|
+
str.downcase # => "ismail"
|
159
|
+
str.downcase! # => "ismail"
|
117
160
|
```
|
118
161
|
|
119
|
-
|
162
|
+
### gsub and gsub!
|
120
163
|
|
121
164
|
```ruby
|
122
|
-
|
123
|
-
'Aşağı Ayrancı'.match(/^\w+\s\w+$/) #=> #<MatchData "Aşağı Ayrancı">
|
124
|
-
'aüvvağğ öövvaağ'.match(/^[a-z]+\s[a-z]+$/) #=> #<MatchData "aüvvağğ öövvaağ">
|
125
|
-
'BAĞCIlar'.match(/[A-Z]+/) #=> #<MatchData "BAĞCI">
|
126
|
-
'Aşağı Ayrancı'.match(/\W+/) #=> #<MatchData "">
|
165
|
+
'ağapaşaağa'.gsub(/[a-h]+/, 'bey')
|
127
166
|
```
|
128
167
|
|
129
|
-
|
168
|
+
### index
|
130
169
|
|
131
170
|
```ruby
|
132
|
-
|
133
|
-
|
171
|
+
'?ç-!+*/-ğüı'.index(/\w+/) # => 1
|
172
|
+
'?ç-!+*/-ğüı'.index(/[a-z]+/, 2) # => 8
|
173
|
+
```
|
174
|
+
|
175
|
+
### match
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
'Aşağı'.match(/\w+/)
|
179
|
+
# => #<MatchData "Aşağı">
|
180
|
+
|
181
|
+
'Aşağı Ayrancı'.match(/^\w+\s\w+$/)
|
182
|
+
# => #<MatchData "Aşağı Ayrancı">
|
183
|
+
|
184
|
+
'aüvvağğ öövvaağ'.match(/^[a-z]+\s[a-z]+$/)
|
185
|
+
# => #<MatchData "aüvvağğ öövvaağ">
|
186
|
+
|
187
|
+
'BAĞCIlar'.match(/[A-Z]+/)
|
188
|
+
# => #<MatchData "BAĞCI">
|
189
|
+
|
190
|
+
'Aşağı Ayrancı'.match(/\W+/)
|
191
|
+
# => #<MatchData "">
|
192
|
+
```
|
193
|
+
|
194
|
+
### partition
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
'Bağlarbaşı Çarşı'.partition(/\W+/) # => ["Bağlarbaşı", " ", "Çarşı"]
|
198
|
+
```
|
199
|
+
|
200
|
+
### rpartition
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
'Bağlarbaşı Çarşı Kalabalık'.rpartition(/\W+/)
|
204
|
+
# => ["Bağlarbaşı Çarşı", " ", "Kalabalık"]
|
205
|
+
```
|
206
|
+
|
207
|
+
### rindex
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
'şç-!+*/-ğüı'.rindex(/\w+/, 7) # => 1
|
134
211
|
```
|
135
212
|
|
136
|
-
|
213
|
+
### scan
|
137
214
|
|
138
|
-
|
215
|
+
```ruby
|
216
|
+
'Bağlarbaşı Çarşı Kalabalık'.scan(/[a-z]+/i)
|
217
|
+
# => ["Bağlarbaşı", "Çarşı", "Kalabalık"]
|
218
|
+
```
|
219
|
+
|
220
|
+
|
221
|
+
### slice and slice!
|
139
222
|
|
140
223
|
```ruby
|
141
|
-
'
|
224
|
+
'Duayen'.slice(/[^h-ö]+/) # => "Duaye"
|
225
|
+
```
|
226
|
+
|
227
|
+
### split
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
'Bağlarbaşı Çarşı Kalabalık'.split(/\W+/)
|
231
|
+
# => ["Bağlarbaşı", "Çarşı", "Kalabalık"]
|
232
|
+
|
233
|
+
'Bağlarbaşı Çarşı Kalabalık'.split(/[ç-ş]+/)
|
234
|
+
# => ["Ba", "a", "ba", " Ça", " Ka", "aba"]
|
235
|
+
```
|
236
|
+
|
237
|
+
### sub and sub!
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
'ağapaşaağa'.sub(/[a-h]+/, 'bey') # => "beypaşaağa"
|
241
|
+
```
|
242
|
+
|
243
|
+
### swapcase and swapcase!
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
'TuğÇE'.swapcase # => "tUĞçe"
|
247
|
+
'TuğÇE'.swapcase! # => "tUĞçe"
|
248
|
+
```
|
249
|
+
|
250
|
+
### titleize and titleize!
|
251
|
+
|
252
|
+
*These methods are not core methods of ruby, but they are accepted as useful in most situations.*
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
'türkÇE desteĞİ'.titleize # => "Türkçe Desteği"
|
256
|
+
'türkÇE desteĞİ'.titleize! # => "Türkçe Desteği"
|
142
257
|
|
143
258
|
# Parenthesis, quotes, etc. support
|
144
|
-
"rUBY roCkS... (really! 'tRUSt' ME)".titleize
|
259
|
+
"rUBY roCkS... (really! 'tRUSt' ME)".titleize
|
260
|
+
# => "Ruby Rocks... (Really! 'Trust' Me)"
|
145
261
|
|
146
|
-
# If you don't want to capitalize conjuctions,
|
147
|
-
|
262
|
+
# If you don't want to capitalize conjuctions,
|
263
|
+
# simply pass a false value as parameter
|
264
|
+
"kerem VE aslı VeYa leyla İlE mecnun".titleize(false)
|
265
|
+
# => "Kerem ve Aslı veya Leyla ile Mecnun"
|
148
266
|
```
|
149
267
|
|
150
|
-
|
268
|
+
### upcase and upcase!
|
151
269
|
|
152
270
|
```ruby
|
153
271
|
str = 'Bağcılar'
|
154
|
-
|
272
|
+
|
273
|
+
str.upcase # => "BAĞCILAR"
|
274
|
+
str # => "Bağcılar"
|
275
|
+
|
276
|
+
str.upcase! # => "BAĞCILAR"
|
277
|
+
str # => "BAĞCILAR"
|
278
|
+
```
|
279
|
+
|
280
|
+
## Array Methods
|
281
|
+
|
282
|
+
### sort and sort!
|
283
|
+
|
284
|
+
```ruby
|
285
|
+
%w(iki üç dört ılık iğne iyne).sort
|
286
|
+
# => ["dört", "ılık", "iğne", "iki", "iyne", "üç"]
|
155
287
|
```
|
156
288
|
|
157
289
|
## Contributing
|
data/Rakefile
CHANGED
data/lib/turkish_support.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
|
5
|
-
require
|
6
|
-
require
|
1
|
+
require 'turkish_support/version'
|
2
|
+
require 'turkish_support/constants'
|
3
|
+
require 'turkish_support/helpers'
|
4
|
+
|
5
|
+
require 'turkish_support/string_methods'
|
6
|
+
require 'turkish_support/array_methods'
|
7
7
|
|
8
8
|
module TurkishSupport
|
9
9
|
end
|
@@ -3,11 +3,15 @@ module TurkishSupport
|
|
3
3
|
def sort
|
4
4
|
sort_by do |item|
|
5
5
|
if item.is_a?(String)
|
6
|
-
item.chars.map { |ch|
|
6
|
+
item.chars.map { |ch| ALPHABET.index(ch) }
|
7
7
|
else
|
8
8
|
super
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
def sort!
|
14
|
+
replace(sort)
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
@@ -1,21 +1,54 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module TurkishSupportHelpers
|
2
|
+
ALPHA = {
|
3
|
+
lower: 'abcçdefgğhıijklmnoöpqrsştuüvwxyz',
|
4
|
+
upper: 'ABCÇDEFGĞHIİJKLMNOÖPQRSŞTUÜVWXYZ',
|
5
|
+
tr_lower: 'çğıiöşü',
|
6
|
+
tr_upper: 'ÇĞIİÖŞÜ'
|
7
|
+
}
|
8
8
|
|
9
|
-
|
10
|
-
DESTRUCTIVE_ARRAY_METHODS = %i(sort)
|
9
|
+
ALPHABET = ALPHA[:upper] + ALPHA[:lower]
|
11
10
|
|
12
|
-
|
11
|
+
META_CHARS = {
|
13
12
|
'\w' => '[\p{Latin}\d_]',
|
14
|
-
'\W' => '[^\p{Latin}\d_]'
|
15
|
-
'a-z' => DOWNCASED_ALPHABET,
|
16
|
-
'A-Z' => UPCASED_ALPHABET
|
13
|
+
'\W' => '[^\p{Latin}\d_]'
|
17
14
|
}
|
18
15
|
|
16
|
+
# Regexp required methods
|
17
|
+
RE_RE_METHS = %i(
|
18
|
+
match
|
19
|
+
scan
|
20
|
+
)
|
21
|
+
|
22
|
+
# Regexp optional methods
|
23
|
+
RE_OP_METHS = %i(
|
24
|
+
[]
|
25
|
+
[]=
|
26
|
+
=~
|
27
|
+
index
|
28
|
+
rindex
|
29
|
+
partition
|
30
|
+
rpartition
|
31
|
+
slice
|
32
|
+
slice!
|
33
|
+
split
|
34
|
+
sub
|
35
|
+
sub!
|
36
|
+
gsub
|
37
|
+
gsub!
|
38
|
+
)
|
39
|
+
|
40
|
+
CASE_RELATED_METHS = %i(
|
41
|
+
downcase
|
42
|
+
downcase!
|
43
|
+
upcase
|
44
|
+
upcase!
|
45
|
+
capitalize
|
46
|
+
capitalize!
|
47
|
+
)
|
48
|
+
|
49
|
+
RANGE_REGEXP = /\[[^\]]*?([#{ALPHABET}]-[#{ALPHABET}])[^\[]*?\]/
|
50
|
+
|
19
51
|
CONJUCTIONS = %w(ve ile veya)
|
20
|
-
|
52
|
+
|
53
|
+
SPECIAL_CHARS = %q{("'}
|
21
54
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module TurkishSupportHelpers
|
2
|
+
def translate_regexp(pattern) # rubocop:disable Metrics/AbcSize
|
3
|
+
Regexp.new(pattern) unless pattern.is_a? Regexp
|
4
|
+
re, options = pattern.source, pattern.options
|
5
|
+
|
6
|
+
while re.match(RANGE_REGEXP)
|
7
|
+
re.scan(RANGE_REGEXP).flatten.compact.each do |matching|
|
8
|
+
re.gsub! matching, translate_range(matching, pattern.casefold?)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
META_CHARS.each { |k, v| re.gsub!(k, v) }
|
13
|
+
Regexp.new(re.force_encoding('UTF-8'), Regexp::FIXEDENCODING | options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def translate_range(range_as_string, casefold = false)
|
17
|
+
return '' unless range_as_string
|
18
|
+
|
19
|
+
range_as_string.gsub!(/\[\]/, '')
|
20
|
+
first, last = range_as_string.split('-')
|
21
|
+
|
22
|
+
expand_range(first, last, casefold)
|
23
|
+
end
|
24
|
+
|
25
|
+
def prepare_for(meth, string)
|
26
|
+
valid_meths = %i(upcase downcase capitalize)
|
27
|
+
unless valid_meths.include?(meth) && string.is_a?(String)
|
28
|
+
fail ArgumentError, 'Invalid arguments for method `prepare_for`!'
|
29
|
+
end
|
30
|
+
|
31
|
+
method("prepare_for_#{meth}").call(string)
|
32
|
+
end
|
33
|
+
|
34
|
+
def tr_char?(ch)
|
35
|
+
tr_lower?(ch) || tr_upper?(ch)
|
36
|
+
end
|
37
|
+
|
38
|
+
def tr_lower?(ch)
|
39
|
+
ALPHA[:tr_lower].include? ch
|
40
|
+
end
|
41
|
+
|
42
|
+
def tr_upper?(ch)
|
43
|
+
ALPHA[:tr_upper].include? ch
|
44
|
+
end
|
45
|
+
|
46
|
+
def conjuction?(string)
|
47
|
+
CONJUCTIONS.include? string
|
48
|
+
end
|
49
|
+
|
50
|
+
def start_with_a_special_char?(string)
|
51
|
+
string =~ /^[#{SPECIAL_CHARS}]/
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def prepare_for_upcase(string)
|
57
|
+
string.tr(ALPHA[:tr_lower], ALPHA[:tr_upper])
|
58
|
+
end
|
59
|
+
|
60
|
+
def prepare_for_downcase(string)
|
61
|
+
string.tr(ALPHA[:tr_upper], ALPHA[:tr_lower])
|
62
|
+
end
|
63
|
+
|
64
|
+
def prepare_for_capitalize(string)
|
65
|
+
[
|
66
|
+
prepare_for(:upcase, string.chr).upcase,
|
67
|
+
prepare_for(:downcase, self[1..-1]).downcase
|
68
|
+
].join
|
69
|
+
end
|
70
|
+
|
71
|
+
def expand_range(first, last, casefold)
|
72
|
+
if lower.include?(first) && lower.include?(last)
|
73
|
+
downcase_range(first, last, casefold)
|
74
|
+
elsif upper.include?(first) && upper.include?(last)
|
75
|
+
upcase_range(first, last, casefold)
|
76
|
+
else
|
77
|
+
fail ArgumentError, 'Invalid regexp range arguments!'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def downcase_range(first, last, casefold)
|
82
|
+
lower(first, last) +
|
83
|
+
(lower_opposite(first, last) if casefold).to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
def upcase_range(first, last, casefold)
|
87
|
+
upper(first, last) +
|
88
|
+
(upper_opposite(first, last) if casefold).to_s
|
89
|
+
end
|
90
|
+
|
91
|
+
def lower(first = nil, last = nil)
|
92
|
+
return ALPHA[:lower] if first.nil? || last.nil?
|
93
|
+
ALPHA[:lower][ALPHA[:lower].index(first)..ALPHA[:lower].index(last)]
|
94
|
+
end
|
95
|
+
|
96
|
+
def lower_opposite(first, last)
|
97
|
+
upper[lower.index(first)..lower.index(last)].delete("^#{ALPHA[:tr_upper]}")
|
98
|
+
end
|
99
|
+
|
100
|
+
def upper(first = nil, last = nil)
|
101
|
+
return ALPHA[:upper] if first.nil? || last.nil?
|
102
|
+
ALPHA[:upper][ALPHA[:upper].index(first)..ALPHA[:upper].index(last)]
|
103
|
+
end
|
104
|
+
|
105
|
+
def upper_opposite(first, last)
|
106
|
+
lower[upper.index(first)..upper.index(last)].delete("^#{ALPHA[:tr_lower]}")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
module TurkishSupport
|
111
|
+
include TurkishSupportHelpers
|
112
|
+
end
|