turkish_support 0.3.0 → 1.0.0.pre.alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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