csl 1.0.0.pre15 → 1.0.0.pre16

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,17 +21,36 @@ module CSL
21
21
 
22
22
  alias each each_child
23
23
 
24
- # @return [Term, nil] the first term that matches the query
24
+ # If a style uses a term in a form that is undefined, there is a
25
+ # fallback to other forms: "verb-short" first falls back to "verb",
26
+ # "symbol" first falls back to "short", and "verb" and "short" both
27
+ # fall back to "long". If no form fallback is available, nil is
28
+ # returned instead.
29
+ #
30
+ # @return [Term, nil] the term that matches the query
25
31
  def lookup(name, options = {})
26
32
  options = Term.specialize(options)
33
+
27
34
  options[:name] = name = name.to_s
35
+ options[:form] = 'long' unless options.key?(:form)
36
+
37
+ # NB: currently only ordinals support gender-forms
38
+ options.delete(:'gender-form')
39
+
40
+ candidates = registry[name]
41
+ return if candidates.empty?
28
42
 
29
- # TODO default to long form
43
+ # loop terminates when a matching term is found or
44
+ # when there are no more form fallbacks left
45
+ while true do
46
+ term = candidates.detect { |t| t.match?(options) }
47
+ return term unless term.nil?
30
48
 
31
- term = registry[name].detect { |t| t.match?(options) }
32
- return term unless term.nil? && options.delete(:'gender-form')
49
+ fallback = Term.form_fallbacks[options[:form].to_s]
50
+ return if fallback == options[:form]
33
51
 
34
- registry[name].detect { |t| t.match?(options) }
52
+ options[:form] = fallback
53
+ end
35
54
  end
36
55
  alias [] lookup
37
56
 
@@ -175,11 +194,24 @@ module CSL
175
194
  attr_struct :name, :form, :gender, :'gender-form', :match
176
195
  attr_children :single, :multiple
177
196
 
197
+ attr_defaults :form => 'long'
198
+
178
199
  attr_accessor :text
179
200
 
180
201
  def_delegators :attributes, :hash, :eql?, :name, :form, :gender
181
202
 
203
+ @form_fallbacks = {
204
+ 'long' => 'long',
205
+ 'verb' => 'long',
206
+ 'short' => 'long',
207
+ 'verb-short' => 'verb',
208
+ 'symbol' => 'short'
209
+ }.freeze
210
+
182
211
  class << self
212
+
213
+ attr_reader :form_fallbacks
214
+
183
215
  def specialize(options)
184
216
  options = options.select do |k,v|
185
217
  !v.nil? && Term::Attributes.keys.include?(k.to_sym)
@@ -243,7 +275,7 @@ module CSL
243
275
  return :default if attributes.name == 'ordinal'
244
276
  attributes.name[/\d+/].to_i
245
277
  end
246
-
278
+
247
279
  def gendered?
248
280
  !attributes.gender.blank?
249
281
  end
@@ -256,8 +288,21 @@ module CSL
256
288
  attribute?(:form) && attributes.form.to_s =~ /^short$/i
257
289
  end
258
290
 
291
+ def verb?
292
+ attribute?(:form) && attributes.form.to_s =~ /^verb$/i
293
+ end
294
+
295
+ def verb_short?
296
+ attribute?(:form) && attributes.form.to_s =~ /^verb-short$/i
297
+ end
298
+
299
+ def symbol?
300
+ attribute?(:form) && attributes.form.to_s =~ /^symbol$/i
301
+ end
302
+
259
303
  def long?
260
- !short?
304
+ return true unless attribute?(:form)
305
+ attributes.form.to_s =~ /^long$/i
261
306
  end
262
307
 
263
308
  def textnode?
@@ -28,6 +28,18 @@ module CSL
28
28
  @default_attributes ||= {}
29
29
  end
30
30
 
31
+ def hide_default_attributes?
32
+ @hide_default_attributes ||= true
33
+ end
34
+
35
+ def hide_default_attributes!
36
+ @hide_default_attributes = true
37
+ end
38
+
39
+ def show_default_attributes!
40
+ @hide_default_attributes = false
41
+ end
42
+
31
43
  def constantize(name)
32
44
  pattern = /:#{name.to_s.tr('-', '')}$/i
33
45
  klass = types.detect { |t| t.matches?(pattern) }
@@ -106,7 +118,7 @@ module CSL
106
118
  end
107
119
 
108
120
  def attr_defaults(attributes)
109
- @default_attributes = attributes
121
+ default_attributes.merge! attributes
110
122
  end
111
123
 
112
124
  # Creates a new Struct for the passed-in attributes. Node instances
@@ -234,6 +246,12 @@ module CSL
234
246
  copy
235
247
  end
236
248
 
249
+ # @return [Boolean] whether or not the node has default attributes
250
+ def has_default_attributes?
251
+ !default_attributes.empty?
252
+ end
253
+ alias has_defaults? has_default_attributes?
254
+
237
255
  # Iterates through the Node's attributes
238
256
  def each
239
257
  if block_given?
@@ -245,6 +263,30 @@ module CSL
245
263
  end
246
264
  alias each_pair each
247
265
 
266
+ # @param name [#to_sym] the name of the attribute
267
+ # @return [Boolean] whether or not key is set to the default value
268
+ def default_attribute?(name)
269
+ defaults = self.class.default_attributes
270
+ name, value = name.to_sym, attributes.fetch(name)
271
+
272
+ return false unless !value.nil? || defaults.key?(name)
273
+ defaults[name] == value
274
+ end
275
+
276
+ # @return [Hash] the attributes currently set to their default values
277
+ def default_attributes
278
+ attributes.to_hash.select do |name, _|
279
+ default_attribute?(name)
280
+ end
281
+ end
282
+
283
+ # @return [Hash] the attributes currently not set to their default values
284
+ def custom_attributes
285
+ attributes.to_hash.reject do |name, _|
286
+ default_attribute?(name)
287
+ end
288
+ end
289
+
248
290
  # Returns true if the node contains an attribute with the passed-in name;
249
291
  # false otherwise.
250
292
  def attribute?(name)
@@ -410,7 +452,8 @@ module CSL
410
452
  private
411
453
 
412
454
  def attribute_assignments
413
- each_pair.map { |name, value|
455
+ a = self.class.hide_default_attributes? ? custom_attributes : attributes
456
+ a.map { |name, value|
414
457
  value.nil? ? nil : [name, value.to_s.inspect].join('=')
415
458
  }.compact
416
459
  end
@@ -22,6 +22,8 @@ module CSL
22
22
 
23
23
  attr_defaults :version => Schema.version, :xmlns => Schema.namespace
24
24
 
25
+ show_default_attributes!
26
+
25
27
  attr_struct :xmlns, :version, :class, :'default-locale',
26
28
  :'initialize-with-hyphen', :'page-range-format',
27
29
  :'demote-non-dropping-particle', *Schema.attr(:name, :names)
@@ -72,8 +72,9 @@ module CSL
72
72
  end
73
73
  alias name_label? names_label?
74
74
 
75
+ # @return [String] the term name for the label's variable
75
76
  def term
76
- Label.terms[variable]
77
+ Label.terms[variable.to_s]
77
78
  end
78
79
  end
79
80
 
@@ -1,6 +1,8 @@
1
1
  module CSL
2
2
  class Style
3
3
 
4
+ # Numbers are CSL rendering elements which output the number variable
5
+ # selected with the required variable attribute.
4
6
  class Number < Node
5
7
  attr_struct :variable, :form, :'text-case',
6
8
  *Schema.attr(:affixes, :display, :font)
@@ -33,10 +33,6 @@ module CSL
33
33
  attribute?(:term)
34
34
  end
35
35
 
36
- def term_options
37
- attributes_for :term, :plural, :form
38
- end
39
-
40
36
  def has_value?
41
37
  attribute?(:value)
42
38
  end
@@ -1,3 +1,3 @@
1
1
  module CSL
2
- VERSION = '1.0.0.pre15'.freeze
2
+ VERSION = '1.0.0.pre16'.freeze
3
3
  end
@@ -11,7 +11,7 @@ module CSL
11
11
 
12
12
  describe '#to_xml' do
13
13
  it 'returns <style-options punctuation-in-quote="false"/> by default' do
14
- subject.to_xml.should =~ /<style-options [^\/>]+\/>/
14
+ subject.to_xml.should =~ /<style-options\/>/
15
15
  end
16
16
  end
17
17
 
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  module CSL
@@ -53,18 +54,54 @@ module CSL
53
54
  <single>page</single>
54
55
  <multiple>pages</multiple>
55
56
  </term>
57
+ <term name="section">
58
+ <single>section</single>
59
+ <multiple>sections</multiple>
60
+ </term>
61
+ <term name="section" form="short">sec.</term>
62
+ <term name="section" form="symbol">
63
+ <single>§</single>
64
+ <multiple>§§</multiple>
65
+ </term>
66
+ <term name="editor">
67
+ <single>editor</single>
68
+ <multiple>editors</multiple>
69
+ </term>
70
+ <term name="editor" form="short">
71
+ <single>ed.</single>
72
+ <multiple>eds.</multiple>
73
+ </term>
74
+ <term name="editor" form="verb">edited by</term>
75
+ <term name="editor" form="verb-short">ed.</term>
56
76
  </terms>
57
77
  EOS
58
78
  end
59
-
79
+
60
80
  it 'returns nil if there is no matching term' do
61
81
  en.lookup(:foo).should be_nil
62
82
  end
63
83
 
64
- it 'returns the first matching form by default' do
65
- en.lookup(:page).should be_short
84
+ it 'returns the long form by default' do
85
+ en.lookup(:page).should be_long
66
86
  end
67
-
87
+
88
+ it 'returns the term in the passed-in form if available' do
89
+ en.lookup(:section, :form => 'long').should be_long
90
+ en.lookup(:section, :form => 'short').should be_short
91
+ en.lookup(:section, :form => 'symbol').should be_symbol
92
+
93
+ en.lookup(:editor).should be_long
94
+ en.lookup(:editor, :form => 'long').should be_long
95
+ en.lookup(:editor, :form => 'verb').should be_verb
96
+ en.lookup(:editor, :form => 'verb-short').should be_verb_short
97
+ end
98
+
99
+ it 'returns the right fallback form if the passed-in form is not available' do
100
+ en.lookup(:page, :form => 'verb').should be_long
101
+ en.lookup(:page, :form => 'verb-short').should be_long
102
+ en.lookup(:page, :form => 'symbol').should be_short
103
+ end
104
+
68
105
  it 'ignores irrelevant options' do
69
106
  en.lookup(:page, :plural => true).should_not be_nil
70
107
  end
@@ -78,9 +115,10 @@ module CSL
78
115
  it { should_not be_nil }
79
116
 
80
117
  it { should_not be_gendered }
81
-
82
118
  it { should be_neutral }
83
119
 
120
+ it { should be_long }
121
+
84
122
  it { should_not be_ordinal }
85
123
  it { should_not be_short_ordinal }
86
124
  it { should_not be_long_ordinal }
@@ -149,7 +187,7 @@ module CSL
149
187
 
150
188
  describe 'attributes#to_a' do
151
189
  it 'returns an array of all attribute values of underlying struct' do
152
- f.attributes.to_a.should == ['edition', nil, 'feminine', nil, nil]
190
+ f.attributes.to_a.should == ['edition', 'long', 'feminine', nil, nil]
153
191
  end
154
192
  end
155
193
  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.pre15
4
+ version: 1.0.0.pre16
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: 2013-01-18 00:00:00.000000000 Z
12
+ date: 2013-01-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: namae
@@ -182,7 +182,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
182
  version: '0'
183
183
  segments:
184
184
  - 0
185
- hash: 3229480668265481885
185
+ hash: -3642197188366485862
186
186
  required_rubygems_version: !ruby/object:Gem::Requirement
187
187
  none: false
188
188
  requirements: