string-direction 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +38 -8
- data/lib/string-direction/configuration.rb +6 -0
- data/lib/string-direction/detector.rb +15 -3
- data/lib/string-direction/strategies/characters_strategy.rb +4 -4
- data/lib/string-direction/strategies/marks_strategy.rb +2 -2
- data/lib/string-direction/string_methods.rb +5 -1
- data/lib/string-direction/version.rb +1 -1
- data/spec/string-direction/configuration_spec.rb +6 -0
- data/spec/string-direction/string_methods_spec.rb +43 -17
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4012023bbe9a099ec7e4bc0c0c366e79df36b194
|
4
|
+
data.tar.gz: 8ad5696dafb160dff2310054f77e1504ee7a4cfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efc912ae089c7ea5b7002797f935543619c18bc7c8ea12db133ff9cff49e0c8f40af69213710c1df03db4e4ca2b6cd8f15eb0741449070f1dd93162ccdc2c976
|
7
|
+
data.tar.gz: 228e529c260071ea4d8b21e89556a91b7780fab5d803a673807d636cf29e22fb1412e80a42a9b5c7e916a8f81001f70d0c0bd6d261ba1415cc1c837713fffc54
|
data/README.md
CHANGED
@@ -31,11 +31,19 @@ String.send(:include, StringDirection::StringMethods)
|
|
31
31
|
|
32
32
|
`string-direction` uses different strategies in order to try to detect the direction of a string. The detector uses them once at a time and returns the result once one of them succeeds, aborting any further analysis.
|
33
33
|
|
34
|
-
|
34
|
+
Strategies are passed to the detector during its initialization:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
detector = StringDirection::Detector.new(:foo, :bar)
|
38
|
+
```
|
39
|
+
|
40
|
+
In the above example, classes `StringDirection::FooStrategy` and `StringDirection::BarStrategy` have to be in the load path.
|
41
|
+
|
42
|
+
Two strategies are natively integrated: `marks` and `characters`. They are used, in that order, as default strategies if no arguments are given to the detector.
|
35
43
|
|
36
44
|
### marks
|
37
45
|
|
38
|
-
Looks for the presence of direction
|
46
|
+
Looks for the presence of Unicode direction marks: [left-to-right](http://en.wikipedia.org/wiki/Left-to-right_mark) (\u200e) or [right-to-left](http://en.wikipedia.org/wiki/Right-to-left_mark) (\u200f).
|
39
47
|
|
40
48
|
```ruby
|
41
49
|
detector = StringDirection::Detector.new(:marks)
|
@@ -44,6 +52,8 @@ detector.direction("\u200eالعربية") #=> "ltr"
|
|
44
52
|
detector.direction("\u200fEnglish") #=> "rtl"
|
45
53
|
```
|
46
54
|
|
55
|
+
`marks` strategy can not only analyze a string but everything responding to `to_s`.
|
56
|
+
|
47
57
|
### characters
|
48
58
|
|
49
59
|
Looks for the presence of right-to-left characters in the scripts used in the string.
|
@@ -71,8 +81,8 @@ You can change these defaults:
|
|
71
81
|
```ruby
|
72
82
|
detector.direction('ᚪᚫᚬᚭᚮᚯ') #=> 'ltr'
|
73
83
|
|
74
|
-
StringDirection.
|
75
|
-
|
84
|
+
StringDirection.configure do |config|
|
85
|
+
config.rtl_scripts << 'Runic'
|
76
86
|
end
|
77
87
|
|
78
88
|
detector.direction('ᚪᚫᚬᚭᚮᚯ') #=> 'rtl'
|
@@ -90,12 +100,14 @@ This can be useful, mainly, for scripts that have both left-to-right and right-t
|
|
90
100
|
|
91
101
|
Keep in mind than only [scripts recognized by Ruby regular expressions](http://www.ruby-doc.org/core-1.9.3/Regexp.html#label-Character+Properties) are allowed.
|
92
102
|
|
103
|
+
`characters` strategy can not only analyze a string but everything responding to `to_s`.
|
104
|
+
|
93
105
|
### Custom Strategies
|
94
106
|
|
95
|
-
You can define your custom strategies. To do so, you just have to define a class inside `StringDirection` module with a name ending with `Strategy`. This class has to respond to an instance method `run` which takes the string as argument. You can inherit from `StringDirection::Strategy` to have convenient methods `ltr`, `rtl` and `bidi`.
|
107
|
+
You can define your custom strategies. To do so, you just have to define a class inside `StringDirection` module with a name ending with `Strategy`. This class has to respond to an instance method `run` which takes the string as argument. You can inherit from `StringDirection::Strategy` to have convenient methods `ltr`, `rtl` and `bidi` which return expected result. If the strategy doesn't know the direction, it must return `nil`.
|
96
108
|
|
97
109
|
```ruby
|
98
|
-
class StringDirection::AlwaysLtrStrategy
|
110
|
+
class StringDirection::AlwaysLtrStrategy < StringDirection::Strategy
|
99
111
|
def run(string)
|
100
112
|
ltr
|
101
113
|
end
|
@@ -110,8 +122,26 @@ detector.direction('العربية') #=> 'ltr'
|
|
110
122
|
`marks` and `characters` are default strategies, but you can change them:
|
111
123
|
|
112
124
|
```ruby
|
113
|
-
StringDirection.
|
114
|
-
|
125
|
+
StringDirection.configure do |config|
|
126
|
+
config.default_strategies = [:custom, :marks, :always_ltr]
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
## Monkey patching String
|
131
|
+
|
132
|
+
If you desire, you can monkey patch `String`:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
String.send(:include, StringDirection::StringMethods)
|
136
|
+
|
137
|
+
'english'.direction #=> 'ltr'
|
138
|
+
```
|
139
|
+
|
140
|
+
In that case, strategies configured in `string_method_strategies` are used:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
StringDirection.configure do |config|
|
144
|
+
config.string_methods_strategies = [:marks, :characters]
|
115
145
|
end
|
116
146
|
```
|
117
147
|
|
@@ -11,10 +11,16 @@ module StringDirection
|
|
11
11
|
# @return [Array]
|
12
12
|
attr_accessor :default_strategies
|
13
13
|
|
14
|
+
# Strategies, in order, that {StringMethods} uses. Values are symbols with a matching class expected. For example, `:marks` expects a class `StringDirection::MarksStrategy` to exist. Defaults to `:marks` and `:characters`.
|
15
|
+
#
|
16
|
+
# @return [Array]
|
17
|
+
attr_accessor :string_methods_strategies
|
18
|
+
|
14
19
|
# Initialize defaults
|
15
20
|
def initialize
|
16
21
|
self.rtl_scripts = %w(Arabic Hebrew Nko Kharoshthi Phoenician Syriac Thaana Tifinagh)
|
17
22
|
self.default_strategies = [:marks, :characters]
|
23
|
+
self.string_methods_strategies = [:marks, :characters]
|
18
24
|
end
|
19
25
|
end
|
20
26
|
end
|
@@ -32,7 +32,7 @@ module StringDirection
|
|
32
32
|
# @param string [String] The string to inspect
|
33
33
|
# @return [Boolean]
|
34
34
|
def ltr?(string)
|
35
|
-
direction(string) ==
|
35
|
+
direction(string) == ltr
|
36
36
|
end
|
37
37
|
|
38
38
|
# Returns whether string is right-to-left or not
|
@@ -40,7 +40,7 @@ module StringDirection
|
|
40
40
|
# @param string [String] The string to inspect
|
41
41
|
# @return [Boolean]
|
42
42
|
def rtl?(string)
|
43
|
-
direction(string) ==
|
43
|
+
direction(string) == rtl
|
44
44
|
end
|
45
45
|
|
46
46
|
# Returns whether string is bidirectional or not
|
@@ -48,7 +48,7 @@ module StringDirection
|
|
48
48
|
# @param string [String] The string to inspect
|
49
49
|
# @return [Boolean]
|
50
50
|
def bidi?(string)
|
51
|
-
direction(string) ==
|
51
|
+
direction(string) == bidi
|
52
52
|
end
|
53
53
|
|
54
54
|
private
|
@@ -68,5 +68,17 @@ module StringDirection
|
|
68
68
|
base_name = strategy.to_s.split('_').map(&:capitalize).join
|
69
69
|
"StringDirection::#{base_name}Strategy"
|
70
70
|
end
|
71
|
+
|
72
|
+
def ltr
|
73
|
+
StringDirection::LTR
|
74
|
+
end
|
75
|
+
|
76
|
+
def rtl
|
77
|
+
StringDirection::RTL
|
78
|
+
end
|
79
|
+
|
80
|
+
def bidi
|
81
|
+
StringDirection::BIDI
|
82
|
+
end
|
71
83
|
end
|
72
84
|
end
|
@@ -22,15 +22,15 @@ module StringDirection
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def rtl_characters?(string)
|
25
|
-
string.match(/[#{
|
25
|
+
string.match(/[#{join_rtl_for_regex}]/)
|
26
26
|
end
|
27
27
|
|
28
28
|
def ltr_characters?(string)
|
29
|
-
string.gsub(CHAR_IGNORE_REGEX, '').match(/[^#{
|
29
|
+
string.gsub(CHAR_IGNORE_REGEX, '').match(/[^#{join_rtl_for_regex}]/)
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
33
|
-
|
32
|
+
def join_rtl_for_regex
|
33
|
+
rtl_scripts.map { |script| '\p{' + script + '}' }.join
|
34
34
|
end
|
35
35
|
|
36
36
|
def rtl_scripts
|
@@ -25,11 +25,11 @@ module StringDirection
|
|
25
25
|
private
|
26
26
|
|
27
27
|
def ltr_mark?(string)
|
28
|
-
string.include?(LTR_MARK)
|
28
|
+
string.include?(LTR_MARK)
|
29
29
|
end
|
30
30
|
|
31
31
|
def rtl_mark?(string)
|
32
|
-
string.include?(RTL_MARK)
|
32
|
+
string.include?(RTL_MARK)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -25,7 +25,11 @@ module StringDirection
|
|
25
25
|
private
|
26
26
|
|
27
27
|
def string_direction_detector
|
28
|
-
@string_direction_detector ||= StringDirection::Detector.new
|
28
|
+
@string_direction_detector ||= StringDirection::Detector.new(*string_direction_strategies)
|
29
|
+
end
|
30
|
+
|
31
|
+
def string_direction_strategies
|
32
|
+
StringDirection.configuration.string_methods_strategies
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
@@ -12,4 +12,10 @@ describe StringDirection::Configuration do
|
|
12
12
|
expect(subject.default_strategies).to eq([:marks, :characters])
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
describe '#string_methods_strategies' do
|
17
|
+
it 'defaults to an array with :marks and :characters' do
|
18
|
+
expect(subject.string_methods_strategies).to eq([:marks, :characters])
|
19
|
+
end
|
20
|
+
end
|
15
21
|
end
|
@@ -3,31 +3,57 @@ require 'spec_helper'
|
|
3
3
|
describe StringDirection::StringMethods do
|
4
4
|
subject { 'abc' }
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
context 'in any case' do
|
7
|
+
before :each do
|
8
|
+
String.send(:include, StringDirection::StringMethods)
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
describe '#direction' do
|
12
|
+
it 'returns string direction' do
|
13
|
+
expect(subject.direction).to eq(StringDirection::LTR)
|
14
|
+
end
|
13
15
|
end
|
14
|
-
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
describe '#ltr?' do
|
18
|
+
it 'returns whether string direction is left-to-right' do
|
19
|
+
expect(subject.ltr?).to eq(true)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#rtl?' do
|
24
|
+
it 'returns whether string direction is right-to-left' do
|
25
|
+
expect(subject.rtl?).to eq(false)
|
26
|
+
end
|
19
27
|
end
|
20
|
-
end
|
21
28
|
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
describe '#bidi?' do
|
30
|
+
it 'returns whether string direction is bidirectional' do
|
31
|
+
expect(subject.bidi?).to eq(false)
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
28
|
-
|
29
|
-
|
30
|
-
|
36
|
+
context 'when StringDirection.configuration.string_methods_strategies is changed' do
|
37
|
+
before :each do
|
38
|
+
class StringDirection::AlwaysRtlStrategy < StringDirection::Strategy
|
39
|
+
def run(string)
|
40
|
+
rtl
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
StringDirection.configure do |config|
|
45
|
+
config.string_methods_strategies = [:always_rtl]
|
46
|
+
end
|
47
|
+
|
48
|
+
String.send(:include, StringDirection::StringMethods)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'uses that configured strategies' do
|
52
|
+
expect('abc'.direction).to eq('rtl')
|
53
|
+
end
|
54
|
+
|
55
|
+
after :each do
|
56
|
+
StringDirection.reset_configuration
|
31
57
|
end
|
32
58
|
end
|
33
59
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: string-direction
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Busqué
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yard
|