csl 1.0.0.pre15 → 1.0.0.pre16

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.
@@ -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: