string-direction 1.0.0 → 1.1.0
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 +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
|