csl 1.0.0.pre11 → 1.0.0.pre12
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.
- data/lib/csl/locale.rb +4 -2
- data/lib/csl/locale/term.rb +26 -14
- data/lib/csl/node.rb +8 -2
- data/lib/csl/version.rb +1 -1
- data/spec/csl/locale/term_spec.rb +33 -0
- data/spec/csl/node_spec.rb +72 -24
- metadata +3 -3
data/lib/csl/locale.rb
CHANGED
@@ -195,8 +195,10 @@ module CSL
|
|
195
195
|
self
|
196
196
|
end
|
197
197
|
|
198
|
-
|
199
|
-
|
198
|
+
# @return [String, nil] the term's translation
|
199
|
+
def translate(name, options = {})
|
200
|
+
term = terms.lookup name, options
|
201
|
+
term && term.to_s(options)
|
200
202
|
end
|
201
203
|
alias t translate
|
202
204
|
|
data/lib/csl/locale/term.rb
CHANGED
@@ -21,16 +21,20 @@ module CSL
|
|
21
21
|
|
22
22
|
alias each each_child
|
23
23
|
|
24
|
+
# @return [Term, nil] the first term that matches the query
|
24
25
|
def lookup(name, options = {})
|
25
26
|
options[:name] = name = name.to_s
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
registry[name].detect { |t| t.match?(
|
28
|
+
# specialize search conditions
|
29
|
+
conditions = options.select { |k,_| Term::Attributes.keys.include?(k.to_sym) }
|
30
|
+
|
31
|
+
term = registry[name].detect { |t| t.match?(conditions) }
|
32
|
+
return term unless term.nil? && conditions.delete(:'gender-form')
|
33
|
+
|
34
|
+
registry[name].detect { |t| t.match?(conditions) }
|
31
35
|
end
|
32
36
|
alias [] lookup
|
33
|
-
|
37
|
+
|
34
38
|
def ordinalize_modulo(number, divisor, options = {})
|
35
39
|
ordinal = ordinalize(number, options)
|
36
40
|
return unless ordinal && ordinal.match_modulo?(divisor)
|
@@ -39,21 +43,21 @@ module CSL
|
|
39
43
|
|
40
44
|
def ordinalize(number, options = {})
|
41
45
|
return unless has_ordinals?
|
42
|
-
|
46
|
+
|
43
47
|
if number == :default
|
44
48
|
options[:name] = 'ordinal'
|
45
49
|
else
|
46
50
|
options[:name] = 'ordinal-%02d' % number
|
47
51
|
end
|
48
|
-
|
52
|
+
|
49
53
|
if options[:form].to_s =~ /^long/i
|
50
54
|
options.delete :form
|
51
55
|
options[:name][0,0] = 'long-'
|
52
56
|
end
|
53
|
-
|
57
|
+
|
54
58
|
ordinal = ordinals[number].detect { |t| t.match?(options) }
|
55
59
|
return ordinal unless ordinal.nil? && options.delete(:'gender-form')
|
56
|
-
|
60
|
+
|
57
61
|
ordinals[number].detect { |t| t.match?(options) }
|
58
62
|
end
|
59
63
|
|
@@ -70,7 +74,7 @@ module CSL
|
|
70
74
|
def has_legacy_ordinals?
|
71
75
|
has_ordinals? && !ordinals.key?(:default)
|
72
76
|
end
|
73
|
-
|
77
|
+
|
74
78
|
def drop_ordinals
|
75
79
|
tmp = ordinals.values.flatten(1)
|
76
80
|
ordinals.clear
|
@@ -113,7 +117,7 @@ module CSL
|
|
113
117
|
registry[term[:name]].delete(term)
|
114
118
|
end
|
115
119
|
end
|
116
|
-
|
120
|
+
|
117
121
|
end
|
118
122
|
|
119
123
|
class Term < Node
|
@@ -162,15 +166,23 @@ module CSL
|
|
162
166
|
end
|
163
167
|
|
164
168
|
def gendered?
|
165
|
-
|
169
|
+
!attributes.gender.blank?
|
166
170
|
end
|
167
171
|
|
168
172
|
def neutral?
|
169
|
-
|
173
|
+
!gendered?
|
174
|
+
end
|
175
|
+
|
176
|
+
def short?
|
177
|
+
attribute?(:form) && attributes.form.to_s =~ /^short$/i
|
178
|
+
end
|
179
|
+
|
180
|
+
def long?
|
181
|
+
!short?
|
170
182
|
end
|
171
183
|
|
172
184
|
def textnode?
|
173
|
-
|
185
|
+
!text.blank?
|
174
186
|
end
|
175
187
|
|
176
188
|
def singularize
|
data/lib/csl/node.rb
CHANGED
@@ -183,7 +183,7 @@ module CSL
|
|
183
183
|
# Returns an array containing the attributes in self according
|
184
184
|
# to the given selector(s). The selectors may be either integer
|
185
185
|
# indices, ranges (functionality inherited from Struct) or
|
186
|
-
# symbols
|
186
|
+
# symbols identifying valid keys (similar to Hash#values_at).
|
187
187
|
#
|
188
188
|
# @example
|
189
189
|
# attributes.values_at(:family, :nick) #=> ['Matsumoto', 'Matz']
|
@@ -191,7 +191,13 @@ module CSL
|
|
191
191
|
# @see Struct#values_at
|
192
192
|
# @return [Array] the list of values
|
193
193
|
def values_at(*arguments)
|
194
|
-
|
194
|
+
arguments.flatten.inject([]) do |values, key|
|
195
|
+
if key.is_a?(Symbol)
|
196
|
+
values.push fetch(key)
|
197
|
+
else
|
198
|
+
values.concat super(key)
|
199
|
+
end
|
200
|
+
end
|
195
201
|
end
|
196
202
|
|
197
203
|
})
|
data/lib/csl/version.rb
CHANGED
@@ -36,8 +36,41 @@ module CSL
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
|
+
|
39
40
|
end
|
40
41
|
|
42
|
+
describe '#lookup' do
|
43
|
+
|
44
|
+
describe "given standard English terms" do
|
45
|
+
let(:en) do
|
46
|
+
Locale::Terms.parse <<-EOS
|
47
|
+
<terms>
|
48
|
+
<term name="page" form="short">
|
49
|
+
<single>p.</single>
|
50
|
+
<multiple>pp.</multiple>
|
51
|
+
</term>
|
52
|
+
<term name="page">
|
53
|
+
<single>page</single>
|
54
|
+
<multiple>pages</multiple>
|
55
|
+
</term>
|
56
|
+
</terms>
|
57
|
+
EOS
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns nil if there is no matching term' do
|
61
|
+
en.lookup(:foo).should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns the first matching form by default' do
|
65
|
+
en.lookup(:page).should be_short
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'ignores irrelevant options' do
|
69
|
+
en.lookup(:page, :plural => true).should_not be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
41
74
|
end
|
42
75
|
|
43
76
|
describe Locale::Term do
|
data/spec/csl/node_spec.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module CSL
|
4
|
-
|
4
|
+
|
5
5
|
describe Node do
|
6
6
|
|
7
7
|
it { should_not be nil }
|
8
8
|
it { should_not have_children }
|
9
9
|
it { should_not have_attributes }
|
10
|
-
|
10
|
+
|
11
11
|
describe 'given a FooBarNode with attributes :foo and :bar and a TestNode without defined attributes' do
|
12
12
|
before(:all) do
|
13
13
|
class FooBarNode < Node
|
@@ -16,15 +16,15 @@ module CSL
|
|
16
16
|
class TestNode < Node
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it 'creates FooBarNode::Attributes' do
|
21
21
|
FooBarNode.const_defined?(:Attributes).should be_true
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it 'does not create TestNode::Attributes' do
|
25
25
|
TestNode.const_defined?(:Attributes).should_not be_true
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it 'TestNode attributes are a regular Hash' do
|
29
29
|
TestNode.new.attributes.should be_a(Hash)
|
30
30
|
end
|
@@ -32,21 +32,65 @@ module CSL
|
|
32
32
|
it 'FooBarNode attributes are a Struct' do
|
33
33
|
FooBarNode.new.attributes.should be_a(Struct)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
describe '#match?' do
|
37
|
+
it 'matches an empty query' do
|
38
|
+
FooBarNode.new.match?({}).should be_true
|
39
|
+
FooBarNode.new(:foo => 'Foo').match?({}).should be_true
|
40
|
+
TestNode.new.match?({}).should be_true
|
41
|
+
TestNode.new(:foo => 'Foo').match?({}).should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns true for a matching query' do
|
45
|
+
FooBarNode.new(:foo => 'bar').match?(:foo => 'bar').should be_true
|
46
|
+
FooBarNode.new(:bar => 'b', :foo => 'f').match?(:foo => 'f', :bar => 'b').should be_true
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns false for non-matching query' do
|
50
|
+
FooBarNode.new.match?(:foo => 'bar').should be_false
|
51
|
+
FooBarNode.new(:foo => 'f').match?(:foo => 'f', :bar => 'b').should be_false
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns false if the query contains unknown attributes' do
|
55
|
+
FooBarNode.new(:foo => 'f').match?(:foo => 'f', :unknown => 'u').should be_false
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'matches irrespective of order' do
|
59
|
+
FooBarNode.new(:bar => 'b', :foo => 'f').match?(:foo => 'f', :bar => 'b').should be_true
|
60
|
+
FooBarNode.new(:foo => 'f', :bar => 'b').match?(:foo => 'f', :bar => 'b').should be_true
|
61
|
+
FooBarNode.new(:foo => 'f', :bar => 'b').match?(:bar => 'b', :foo => 'f').should be_true
|
62
|
+
FooBarNode.new(:bar => 'b', :foo => 'f').match?(:bar => 'b', :foo => 'f').should be_true
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'matches an empty query with the correct node name' do
|
66
|
+
FooBarNode.new.match?('foo-bar-node', {}).should be_true
|
67
|
+
FooBarNode.new(:foo => 'Foo').match?('foo-bar-node', {}).should be_true
|
68
|
+
TestNode.new.match?('test-node', {}).should be_true
|
69
|
+
TestNode.new(:foo => 'Foo').match?('test-node', {}).should be_true
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'does not match other node names' do
|
73
|
+
FooBarNode.new.match?(:name, {}).should_not be_true
|
74
|
+
FooBarNode.new(:foo => 'Foo').match?(:name, {}).should_not be_true
|
75
|
+
TestNode.new.match?(:name, {}).should_not be_true
|
76
|
+
TestNode.new(:foo => 'Foo').match?(:name, {}).should_not be_true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
36
80
|
describe '#attributes_for' do
|
37
81
|
it 'returns an empty hash when there no attributes are set' do
|
38
82
|
TestNode.new.attributes_for.should be_empty
|
39
83
|
TestNode.new.attributes_for(:x, :y).should be_empty
|
40
|
-
|
84
|
+
|
41
85
|
FooBarNode.new.attributes_for.should be_empty
|
42
86
|
FooBarNode.new.attributes_for(:x, :y).should be_empty
|
43
87
|
FooBarNode.new.attributes_for(:foo, :bar).should be_empty
|
44
88
|
end
|
45
|
-
|
89
|
+
|
46
90
|
it 'returns an empty hash when no attributes match the filter' do
|
47
91
|
TestNode.new(:foo => 'foo').attributes_for.should be_empty
|
48
92
|
TestNode.new(:foo => 'foo').attributes_for(:x, :y).should be_empty
|
49
|
-
|
93
|
+
|
50
94
|
FooBarNode.new(:foo => 'foo').attributes_for.should be_empty
|
51
95
|
FooBarNode.new(:foo => 'foo').attributes_for(:x, :y).should be_empty
|
52
96
|
end
|
@@ -56,33 +100,37 @@ module CSL
|
|
56
100
|
FooBarNode.new(:foo => 'foo', :bar => 'bar').attributes_for(:x, :foo).should == { :foo => 'foo' }
|
57
101
|
end
|
58
102
|
end
|
59
|
-
|
103
|
+
|
60
104
|
describe '#formatting_options' do
|
61
105
|
it 'returns an empty hash by default' do
|
62
106
|
TestNode.new.formatting_options.should be_empty
|
63
107
|
FooBarNode.new.formatting_options.should be_empty
|
64
108
|
end
|
65
|
-
|
109
|
+
|
66
110
|
it 'returns an empty hash if there are no formatting attributes' do
|
67
111
|
TestNode.new(:foo => 'foo', :bar => 'bar').formatting_options.should be_empty
|
68
112
|
FooBarNode.new(:foo => 'foo', :bar => 'bar').formatting_options.should be_empty
|
69
113
|
end
|
70
|
-
|
114
|
+
|
71
115
|
it "returns a hash of the node's formatting attributes" do
|
72
116
|
TestNode.new(:foo => 'foo', :'font-style' => 'italic').formatting_options.should == { :'font-style' => 'italic' }
|
73
117
|
end
|
74
118
|
end
|
75
|
-
|
119
|
+
|
76
120
|
describe '#values_at' do
|
77
121
|
it 'FooBarNode accepts attribute names' do
|
78
122
|
FooBarNode.new(:foo => 'Foo', :bar => 'Bar').values_at(:bar, :foo).should == %w{ Bar Foo }
|
123
|
+
FooBarNode.new(:foo => 'Foo').values_at(:bar, :foo).should == [nil, 'Foo']
|
124
|
+
FooBarNode.new(:foo => 'Foo').values_at(:unknown, :foo).should == [nil, 'Foo']
|
79
125
|
end
|
80
|
-
|
126
|
+
|
81
127
|
it 'TestNode accepts attribute names' do
|
82
128
|
TestNode.new(:foo => 'Foo', :bar => 'Bar').values_at(:bar, :foo).should == %w{ Bar Foo }
|
129
|
+
TestNode.new(:foo => 'Foo').values_at(:bar, :foo).should == [nil, 'Foo']
|
130
|
+
TestNode.new(:foo => 'Foo').values_at(:unknown, :foo).should == [nil, 'Foo']
|
83
131
|
end
|
84
132
|
end
|
85
|
-
|
133
|
+
|
86
134
|
describe '#to_a' do
|
87
135
|
it 'returns an empty list by default' do
|
88
136
|
Node.new.attributes.to_a.should == []
|
@@ -91,7 +139,7 @@ module CSL
|
|
91
139
|
it 'TestNode returns an empty list by default' do
|
92
140
|
TestNode.new.attributes.to_a.should == []
|
93
141
|
end
|
94
|
-
|
142
|
+
|
95
143
|
# it 'TestNode returns a list of all key/value pairs' do
|
96
144
|
# TestNode.new(:foo => 'Foo', :bar => 'Bar').attributes.to_a.map(&:last).sort.should == %w{ Bar Foo }
|
97
145
|
# end
|
@@ -99,12 +147,12 @@ module CSL
|
|
99
147
|
# it 'FooBarNode returns an empty list by default' do
|
100
148
|
# FooBarNode.new.attributes.to_a.should == []
|
101
149
|
# end
|
102
|
-
|
150
|
+
|
103
151
|
# it 'FooBarNode returns a list of all key/value pairs' do
|
104
152
|
# FooBarNode.new(:foo => 'Foo', :bar => 'Bar').attributes.to_a.map(&:last).sort.should == %w{ Bar Foo }
|
105
153
|
# end
|
106
154
|
end
|
107
|
-
|
155
|
+
|
108
156
|
describe 'attributes.keys' do
|
109
157
|
it 'returns all attribute names as symbols' do
|
110
158
|
TestNode.new.attributes.keys.should be_empty
|
@@ -115,28 +163,28 @@ module CSL
|
|
115
163
|
end
|
116
164
|
|
117
165
|
describe TextNode do
|
118
|
-
|
166
|
+
|
119
167
|
it { should_not be nil }
|
120
168
|
it { should_not have_children }
|
121
169
|
it { should_not have_attributes }
|
122
|
-
|
170
|
+
|
123
171
|
describe '.new' do
|
124
172
|
it 'accepts a hash of attributes' do
|
125
173
|
TextNode.new(:foo => 'bar').should have_attributes
|
126
174
|
end
|
127
|
-
|
175
|
+
|
128
176
|
it 'yields itself to the optional block' do
|
129
177
|
TextNode.new { |n| n.text = 'foo' }.text.should == 'foo'
|
130
178
|
end
|
131
|
-
|
179
|
+
|
132
180
|
it 'accepts hash and yields itself to the optional block' do
|
133
181
|
TextNode.new(:foo => 'bar') { |n| n.text = 'foo' }.to_xml.should == '<text-node foo="bar">foo</text-node>'
|
134
182
|
end
|
135
183
|
end
|
136
|
-
|
184
|
+
|
137
185
|
describe '#pretty_print' do
|
138
186
|
TextNode.new(:foo => 'bar') { |n| n.text = 'foo' }.pretty_print.should == '<text-node foo="bar">foo</text-node>'
|
139
187
|
end
|
140
188
|
end
|
141
|
-
|
189
|
+
|
142
190
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.pre12
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: namae
|
@@ -183,7 +183,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
183
|
version: '0'
|
184
184
|
segments:
|
185
185
|
- 0
|
186
|
-
hash:
|
186
|
+
hash: 1070711312713509519
|
187
187
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
188
|
none: false
|
189
189
|
requirements:
|