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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3b1088be5dda40f1dc4e4eb6fbb7d38db262f00
4
- data.tar.gz: 9c43ab7aae842e4afb6dc9e816a62d856b0741e6
3
+ metadata.gz: fca374a0e22cae4752a98bc96a26b64d99e57612
4
+ data.tar.gz: 5ff3bac0eb61748ec55b9de97f6fed195f15222a
5
5
  SHA512:
6
- metadata.gz: 2163bef027f543a1e6b19ffd321f6be0f1b6a758191503672e454ab149451a6270fb1a7fc74974b76090ac7f055699aa7681a14b52f7498193bce811168b1589
7
- data.tar.gz: 28bbd4b4e070ccc06359d3e6aa6eacfef69cd4c7b808ecf8221f0f33667f3bda4e3cbd4f2e97a35457988cb85274192417c8eba87791d25e04023a4cade80345
6
+ metadata.gz: 1682d709edeeb141dc55ff93b9243298ae32892d8fe8e5beeabcc4a9b6d9c4800686a9f2a7d8899e52409e557843fd7dc9c37b89d4a072704314c388372809e7
7
+ data.tar.gz: a90302ff8136ee2ad490f6746cf1043c1fe61a58e750944fe8c5a21c333a4c8b0cab194f8fc6c637b10cfa3710ce9ea338aac4500ce2491bfdcb6d47ff40d16f
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ todo.txt
data/.hound.yml ADDED
@@ -0,0 +1,3 @@
1
+ ruby:
2
+ enabled: true
3
+ config_file: .rubocop.yml
data/.rubocop.yml ADDED
@@ -0,0 +1,7 @@
1
+ StringLiterals:
2
+ EnforcedStyle: single_quotes
3
+ Documentation:
4
+ Enabled: false
5
+ DotPosition:
6
+ EnforcedStyle: leading
7
+ Enabled: true
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 some core ruby methods. This gem provide support for those methods: `String#upcase`,
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
- 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)
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 Instructions
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') #=> "İÇ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
- * In rails you must add `using TurkishSupport` line to the top of the scope, __not inside of any class or module__.
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
- ## Examples
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
- Within the file that you added `using TurkishSupport` line; you can use the core methods like below:
106
+ ```ruby
107
+ class CustomClass
108
+ using TurkishSupport
109
+
110
+ ...
111
+ end
112
+ ```
82
113
 
83
- __String#upcase__ and __String#upcase!__
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
- str.upcase #=> "BAĞCILAR"
89
- str #=> "Bağcılar"
123
+ ## String Methods
90
124
 
91
- str.upcase! #=> "BAĞCILAR"
92
- str #=> "BAĞCILAR"
125
+ ### [] and []=
126
+
127
+ ```ruby
128
+ 'Türkiye Cumhuriyeti'[/\w+/] # => "Türkiye"
129
+ 'Çetin'[/[a-ğ]+/i] # => "Çe"
93
130
  ```
94
131
 
95
- __String#downcase__ and __String#downcase!__
132
+ ### =~ (equal-tilda)
96
133
 
97
134
  ```ruby
98
- str = 'İSMAİL'
99
- str.downcase #=> "ismail"
135
+ 'Bağlarbaşı Çarşı Kalabalık' =~ (/[s-ü]+/i) # => 8
100
136
  ```
101
137
 
102
- __String#capitalize__ and __String#capitalize!__
138
+ ### capitalize and capitalize!
103
139
 
104
140
  ```ruby
105
141
  str = 'türkÇE desteĞİ'
106
- str.capitalize #=> "Türkçe desteği"
142
+
143
+ str.capitalize # => "Türkçe desteği"
144
+ str.capitalize! # => "Türkçe desteği"
107
145
  ```
108
146
 
109
- __String#swapcase__ and __String#swapcase!__
147
+ ### casecmp
148
+
110
149
  ```ruby
111
- 'TuğÇE'.swapcase #=> "tUĞçe"
150
+ 'sıtKI'.casecmp('SITkı') # => 0
112
151
  ```
113
152
 
114
- __String#casecmp__
153
+ ### downcase and downcase!
154
+
115
155
  ```ruby
116
- 'sıtKI'.casecmp('SITkı') #=> 0
156
+ str = 'İSMAİL'
157
+
158
+ str.downcase # => "ismail"
159
+ str.downcase! # => "ismail"
117
160
  ```
118
161
 
119
- __String#match__
162
+ ### gsub and gsub!
120
163
 
121
164
  ```ruby
122
- 'Aşağı'.match(/\w+/) #=> #<MatchData "Aşağı">
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
- __Array#sort__ and __Array#sort!__
168
+ ### index
130
169
 
131
170
  ```ruby
132
- %w(iki üç dört ılık iğne iyne).sort
133
- #=> ["dört", "ılık", "iğne", "iki", "iyne", "üç"]
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
- __String#titleize__ and __String#titleize!__
213
+ ### scan
137
214
 
138
- These methods are not core methods of ruby, but they are accepted as useful in most situations.
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
- 'türkÇE desteĞİ'.titleize #=> "Türkçe Desteği"
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 #=> "Ruby Rocks... (Really! 'Trust' Me)"
259
+ "rUBY roCkS... (really! 'tRUSt' ME)".titleize
260
+ # => "Ruby Rocks... (Really! 'Trust' Me)"
145
261
 
146
- # If you don't want to capitalize conjuctions, simply pass a false value as a parameter
147
- "kerem VE aslı VeYa leyla İlE mecnun".titleize(false) #=> "Kerem ve Aslı veya Leyla ile Mecnun"
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
- __Important Note:__ If you also want to use original set of the core methods in the same scope, you can use `send` method like this:
268
+ ### upcase and upcase!
151
269
 
152
270
  ```ruby
153
271
  str = 'Bağcılar'
154
- str.send(:upcase) #=> "BAğCıLAR"
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
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
@@ -1,9 +1,9 @@
1
- require "turkish_support/version"
2
- require "turkish_support/constants"
3
- require "turkish_support/string_helpers"
4
- require "turkish_support/string_methods"
5
- require "turkish_support/array_methods"
6
- require "turkish_support/destructives"
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| ORDERED_CHARS.index(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 TurkishSupport
2
- DOWNCASED_ALPHABET = 'abcçdefgğhıijklmnoöpqrsştuüvwxyz'
3
- UPCASED_ALPHABET = 'ABCÇDEFGĞHIİJKLMNOÖPQRSŞTUÜVWXYZ'
4
-
5
- UNSUPPORTED_DOWNCASE_CHARS = 'çğıiöşü'
6
- UNSUPPORTED_UPCASE_CHARS = 'ÇĞIİÖŞÜ'
7
- ORDERED_CHARS = UPCASED_ALPHABET + DOWNCASED_ALPHABET
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
- DESTRUCTIVE_STRING_METHODS = %i(swapcase titleize)
10
- DESTRUCTIVE_ARRAY_METHODS = %i(sort)
9
+ ALPHABET = ALPHA[:upper] + ALPHA[:lower]
11
10
 
12
- MATCH_TRANSFORMATIONS = {
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
- SPECIAL_CHARS = %(\("')
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