citeproc 1.0.0.pre10 → 1.0.0.pre11

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.
@@ -72,7 +72,7 @@ module CiteProc
72
72
  # The {DateParts} class encapsulates the year, month and day parts of a
73
73
  # date; it is used internally by {Date} variables and not supposed to
74
74
  # be used in an external context.
75
- class DateParts < Struct.new(:year, :month, :day)
75
+ DateParts = Struct.new(:year, :month, :day) do
76
76
  include Comparable
77
77
 
78
78
  def initialize(*arguments)
@@ -194,6 +194,9 @@ module CiteProc
194
194
  end
195
195
  end
196
196
 
197
+ #
198
+ # CiteProc::Date
199
+ #
197
200
 
198
201
  include Attributes
199
202
 
@@ -15,4 +15,5 @@ module CiteProc
15
15
 
16
16
  NotImplementedByEngine = Class.new(Error)
17
17
 
18
+ RenderingError = Class.new(Error)
18
19
  end
@@ -11,7 +11,7 @@ module CiteProc
11
11
 
12
12
  extend Forwardable
13
13
  include Comparable
14
-
14
+
15
15
  @fields = Hash.new { |h,k| h.fetch(k.to_sym, nil) }.merge({
16
16
  :date => %w{
17
17
  accessed container event-date issued original-date submitted
@@ -21,12 +21,12 @@ module CiteProc
21
21
  author collection-editor composer container-author recipient editor
22
22
  editorial-director illustrator interviewer original-author translator
23
23
  },
24
-
24
+
25
25
  :number => %w{
26
26
  chapter-number collection-number edition issue number number-of-pages
27
- number-of-volumes volume
27
+ number-of-volumes volume
28
28
  },
29
-
29
+
30
30
  :text => %w{
31
31
  abstract annote archive archive_location archive-place authority
32
32
  call-number citation-label citation-number collection-title
@@ -38,36 +38,36 @@ module CiteProc
38
38
  title title-short URL version year-suffix
39
39
  }
40
40
  })
41
-
41
+
42
42
  @fields.each_value { |v| v.map!(&:to_sym) }
43
-
43
+
44
44
  @types = Hash.new { |h,k| h.fetch(k.to_sym, nil) }.merge(
45
45
  Hash[*@fields.keys.map { |k| @fields[k].map { |n| [n,k] } }.flatten]
46
46
  ).freeze
47
-
47
+
48
48
  @fields[:name] = @fields[:names]
49
49
  @fields[:dates] = @fields[:date]
50
50
  @fields[:numbers] = @fields[:number]
51
-
51
+
52
52
  @fields[:all] = @fields[:any] =
53
53
  [:date,:names,:text,:number].reduce([]) { |s,a| s.concat(@fields[a]) }.sort
54
54
 
55
55
  @fields.freeze
56
56
 
57
57
  @markup = /<[^>]*>/.freeze
58
-
59
-
58
+
59
+
60
60
  class << self
61
-
61
+
62
62
  # @!attribute [r] fields
63
63
  # @return [{Symbol => Array<Symbol>}] mapping of variable types to
64
64
  # their respective field names
65
65
  attr_reader :fields
66
-
66
+
67
67
  # @!attribute [r] types
68
68
  # @return [{Symbol => Symbol}] mapping of field names to variable types
69
69
  attr_reader :types
70
-
70
+
71
71
  # @!attribute [r] factories
72
72
  # @return [{Symbol => Class}] mapping of field names to their respective
73
73
  # Variable classes
@@ -76,7 +76,7 @@ module CiteProc
76
76
  # @!attribute markup
77
77
  # @return [Regexp] pattern used to strip markup off values
78
78
  attr_accessor :markup
79
-
79
+
80
80
  # Creates a new {Variable} instance using the passed-in field name
81
81
  # to distinguish which {Variable} class to use as factory. This
82
82
  # method returns nil if the creation fails.
@@ -105,8 +105,8 @@ module CiteProc
105
105
  rescue
106
106
  nil
107
107
  end
108
-
109
-
108
+
109
+
110
110
  # Creates a new {Variable} instance using the passed-in field name
111
111
  # to distinguish which {Variable} class to use as factory.
112
112
  #
@@ -132,20 +132,20 @@ module CiteProc
132
132
 
133
133
  def_delegators :@value, :to_s,
134
134
  *::String.instance_methods(false).select {|m| m.to_s =~ /!$/ }
135
-
135
+
136
136
  def_delegators :to_s, :=~, :===,
137
137
  *::String.instance_methods(false).reject {|m| m.to_s =~ /^\W|!$|to_s/ }
138
138
 
139
-
139
+
140
140
  # Creates new Variable for the passed-in value
141
141
  def initialize(value = nil)
142
142
  replace(value)
143
143
  end
144
-
144
+
145
145
  def initialize_copy(other)
146
146
  @value = other.value.dup
147
147
  end
148
-
148
+
149
149
 
150
150
  # The replace method is typically called by the Variable's constructor. It
151
151
  # will try to set the Variable to the passed in value and should accept
@@ -182,8 +182,29 @@ module CiteProc
182
182
  Number.romanize(to_i)
183
183
  end
184
184
 
185
+ # Tokenizes the variable's value according to the rules of CSL number
186
+ # extraction. Note that this method returns an emtpy array unless
187
+ # the variable has numeric content.
188
+ #
189
+ # @see numeric?
190
+ #
191
+ # For numeric variables, this method normalizes delimiters and
192
+ # separators: numbers separated by a hyphen are stripped of intervening
193
+ # spaces ("2 - 4" becomes "2-4"). Numbers separated by a comma receive
194
+ # one space after the comma ("2,3" and "2 , 3" become "2, 3"), while
195
+ # numbers separated by an ampersand receive one space before and one
196
+ # after the ampsersand ("2&3" becomes "2 & 3").
197
+ #
198
+ # The array returned by this method contains all numbers and tokens
199
+ # as separate strings.
200
+ #
201
+ # @example
202
+ # Variable.new('2,3').tokenize #-> ['2', ', ', '3']
203
+ # Variable.new('2 - 4').tokenize #-> ['2', '-', '4']
204
+ #
185
205
  # @return [Array<String>] tokenizes the variable's value
186
206
  def tokenize
207
+ return [] unless numeric?
187
208
  numbers = to_s.dup
188
209
 
189
210
  numbers.gsub!(/\s*,\s*/, ', ')
@@ -192,6 +213,7 @@ module CiteProc
192
213
 
193
214
  numbers.split(/(\s*[,&-]\s*)/)
194
215
  end
216
+ alias extract_numbers tokenize
195
217
 
196
218
  # Tests whether the variable contains numeric content. Content is
197
219
  # considered numeric if it solely consists of numbers. Numbers may have
@@ -210,24 +232,24 @@ module CiteProc
210
232
  def to_i
211
233
  to_s =~ /([+-]?\d+)/ && $1.to_i || 0
212
234
  end
213
-
235
+
214
236
  # @return [Float] the first (!) numeric or floating point data contained
215
237
  # in the variable's value; zero if no numeric data is present
216
238
  def to_f
217
239
  to_s =~ /([+-]?\d[\d,\.]*)/ && $1.tr(',','.').to_f || 0.0
218
240
  end
219
-
241
+
220
242
  # @return [String] the variable's value stripped of markup
221
243
  def strip_markup
222
244
  gsub(Variable.markup, '')
223
245
  end
224
-
246
+
225
247
  # Strips markup off the variable's value.
226
248
  # @return [self]
227
249
  def strip_markup!
228
250
  gsub!(Variable.markup, '')
229
- end
230
-
251
+ end
252
+
231
253
  # Compares the variable with the passed-in value. If other responds
232
254
  # to {#strip_markup} the stripped strings will be compared; otherwise
233
255
  # both objects will be converted to and compared as strings.
@@ -249,7 +271,7 @@ module CiteProc
249
271
  # @!method to_s
250
272
  # @return [String] the variable's value as a string
251
273
  alias to_citeproc to_s
252
-
274
+
253
275
  # @return [String] a JSON string representation of the variable
254
276
  def to_json
255
277
  MultiJson.encode(to_citeproc)
@@ -259,7 +281,7 @@ module CiteProc
259
281
  def inspect
260
282
  "#<#{self.class.name} #{to_s.inspect}>"
261
283
  end
262
-
284
+
263
285
  end
264
286
 
265
287
  # A CiteProc Variable used for string values.
@@ -1,3 +1,3 @@
1
1
  module CiteProc
2
- VERSION = '1.0.0.pre10'.freeze
2
+ VERSION = '1.0.0.pre11'.freeze
3
3
  end
@@ -2,12 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  module CiteProc
4
4
  describe Date do
5
-
5
+
6
6
  class Date
7
7
  describe DateParts do
8
8
  it { should_not be_nil }
9
9
  it { should be_empty }
10
-
10
+
11
11
  describe 'sorting' do
12
12
  it 'treats [2003] as less than [2003,1]' do
13
13
  DateParts.new(2003).should be < DateParts.new(2003,1)
@@ -32,46 +32,46 @@ module CiteProc
32
32
  it 'treats [-50] as less than [-50,12]' do
33
33
  DateParts.new(-50).should be < DateParts.new(-50,12)
34
34
  end
35
-
35
+
36
36
  it 'treats [1994,1,23] as less than today' do
37
37
  DateParts.new(1994,1,23).should be < ::Date.today
38
- end
38
+ end
39
39
  end
40
-
40
+
41
41
  describe '#dup' do
42
42
  let(:date) { DateParts.new(1991,8,22) }
43
-
43
+
44
44
  it 'creates a copy that contains the same parts' do
45
45
  date.dup.to_a.should == [1991,8,22]
46
46
  end
47
-
47
+
48
48
  it 'does not return self' do
49
49
  date.dup.should_not equal(date)
50
50
  date.dup.should == date
51
51
  end
52
52
  end
53
-
53
+
54
54
  describe '#update' do
55
55
  it 'accepts a hash' do
56
56
  DateParts.new.update(:month => 2, :year => 80).to_a.should == [80,2,nil]
57
57
  end
58
-
58
+
59
59
  it 'accepts an array' do
60
60
  DateParts.new.update([80,2]).to_a.should == [80,2,nil]
61
61
  end
62
62
  end
63
-
63
+
64
64
  describe '#strftime' do
65
65
  it 'formats the date parts according to the format string' do
66
66
  DateParts.new(1998,2,4).strftime('FOO %0m%0d%y').should == 'FOO 020498'
67
67
  end
68
68
  end
69
-
69
+
70
70
  describe 'to_citeproc' do
71
71
  it 'returns an empty list by default' do
72
72
  DateParts.new.to_citeproc.should == []
73
73
  end
74
-
74
+
75
75
  it 'returns a list with the year if only the year is set' do
76
76
  DateParts.new(2001).to_citeproc.should == [2001]
77
77
  end
@@ -80,37 +80,37 @@ module CiteProc
80
80
  DateParts.new(0,0).to_citeproc.should == [0,0]
81
81
  end
82
82
  end
83
-
83
+
84
84
  describe '#open?' do
85
85
  it 'returns false by default' do
86
86
  DateParts.new.should_not be_open
87
87
  end
88
-
88
+
89
89
  it 'returns false for [1999,8,24]' do
90
90
  DateParts.new(1999, 8, 24).should_not be_open
91
91
  end
92
-
92
+
93
93
  it 'returns true for [0]' do
94
94
  DateParts.new(0).should be_open
95
95
  end
96
96
  end
97
97
  end
98
98
  end
99
-
100
-
99
+
100
+
101
101
  let(:ad2k) { Date.create('date-parts' => [[2000]])}
102
102
  let(:may) { Date.create('date-parts' => [[2000, 5]])}
103
103
  let(:first_of_may) { Date.create('date-parts' => [[2000, 5, 1]])}
104
-
104
+
105
105
  let(:bc100) { Date.create('date-parts' => [[-100]]) }
106
106
  let(:bc50) { Date.create('date-parts' => [[-50]]) }
107
107
  let(:ad50) { Date.create('date-parts' => [[50]]) }
108
108
  let(:ad100) { Date.create('date-parts' => [[100]]) }
109
109
 
110
110
  it { should_not be nil }
111
-
111
+
112
112
  it { should_not be_numeric }
113
-
113
+
114
114
  describe '.new' do
115
115
  it 'accepts a hash as input' do
116
116
  Date.new(:literal => 'Summer').to_s.should == 'Summer'
@@ -119,19 +119,19 @@ module CiteProc
119
119
  it 'accepts a hash as input and converts date parts' do
120
120
  Date.new(:'date-parts' => [[2003,2]]).parts[0].should be_a(Date::DateParts)
121
121
  end
122
-
122
+
123
123
  it 'accepts a fixnum and treats it as the year' do
124
124
  Date.new(1666).year.should == 1666
125
125
  end
126
-
126
+
127
127
  it 'accepts a date' do
128
128
  Date.new(::Date.new(1980,4)).month.should == 4
129
129
  end
130
-
130
+
131
131
  it 'accepts a date and creates date parts' do
132
132
  Date.new(::Date.new(1980,4)).parts[0].to_citeproc.should == [1980,4,1]
133
133
  end
134
-
134
+
135
135
  it 'is empty by default' do
136
136
  Date.new.should be_empty
137
137
  end
@@ -163,7 +163,7 @@ module CiteProc
163
163
  it 'accepts inclusive date ranges' do
164
164
  Date.new(::Date.new(2009) .. ::Date.new(2011)).end_date.year.should == 2011
165
165
  end
166
-
166
+
167
167
  it 'accepts EDTF date strings' do
168
168
  Date.new('2009?-03-19').should be_uncertain
169
169
  end
@@ -172,27 +172,27 @@ module CiteProc
172
172
  Date.new('2009-03-19/2010-11-21').parts.map(&:to_citeproc).should == [[2009,3,19],[2010,11,21]]
173
173
  end
174
174
  end
175
-
175
+
176
176
  describe '.parse' do
177
177
  it 'returns nil by default' do
178
178
  Date.parse('').should be nil
179
179
  Date.parse(nil).should be nil
180
180
  end
181
-
181
+
182
182
  it 'parses date strings' do
183
183
  Date.parse('2004-10-26').year.should == 2004
184
184
  end
185
185
  end
186
-
186
+
187
187
  describe '.create' do
188
188
  it 'should accept parameters and return a new instance' do
189
189
  Date.create('date-parts' => [[2001, 1]]).year.should == 2001
190
190
  end
191
191
  end
192
-
192
+
193
193
  describe '#dup' do
194
194
  let(:date) { Date.new([1991,8]) }
195
-
195
+
196
196
  it 'creates a copy that contains the same parts' do
197
197
  date.dup.parts.map(&:to_citeproc).should == [[1991,8]]
198
198
  end
@@ -201,30 +201,30 @@ module CiteProc
201
201
  date.dup.should_not be_uncertain
202
202
  date.uncertain!.dup.should be_uncertain
203
203
  end
204
-
204
+
205
205
  it 'makes a deep copy of attributes' do
206
206
  expect { date.dup.uncertain! }.not_to change { date.uncertain? }
207
207
  end
208
-
208
+
209
209
  it 'makes a deep copy of date parts' do
210
210
  expect { date.dup.parts[0].update(:year => 2012) }.not_to change { date.year }
211
211
  end
212
-
212
+
213
213
  it 'does not return self' do
214
214
  date.dup.should_not equal(date)
215
215
  date.dup.should == date
216
216
  end
217
217
  end
218
-
219
- describe 'literal dates' do
218
+
219
+ describe 'literal dates' do
220
220
  it 'is not literal by default' do
221
221
  Date.new.should_not be_literal
222
222
  end
223
-
223
+
224
224
  it 'is literal if it contains only a literal field' do
225
225
  Date.create(:literal => 'foo').should be_literal
226
226
  end
227
-
227
+
228
228
  it 'is literal if it contains a literal field' do
229
229
  Date.create('date-parts' => [[2000]], :literal => 'foo').should be_literal
230
230
  end
@@ -234,22 +234,22 @@ module CiteProc
234
234
  it 'is no season by default' do
235
235
  Date.new.should_not be_season
236
236
  end
237
-
237
+
238
238
  it 'is a season if contains only a season field' do
239
239
  Date.new(:season => 'Winter').should be_season
240
240
  end
241
241
 
242
242
  it 'is a season if contains a season field' do
243
243
  Date.new(:'date-parts' => [[2001]], :season => 'Winter').should be_season
244
- end
244
+ end
245
245
  end
246
-
246
+
247
247
  describe 'uncertain dates' do
248
248
  it 'are uncertain' do
249
249
  Date.new({ 'date-parts' => [[-225]], 'circa' => '1' }).should be_uncertain
250
250
  Date.new { |d| d.parts = [[-225]]; d.uncertain! }.should_not be_certain
251
251
  end
252
-
252
+
253
253
  describe '#(un)certain!' do
254
254
  it 'returns self' do
255
255
  ad2k.uncertain!.should equal(ad2k)
@@ -257,16 +257,16 @@ module CiteProc
257
257
  end
258
258
  end
259
259
  end
260
-
260
+
261
261
  describe 'sorting' do
262
262
  it 'dates with more date-parts will come after those with fewer parts' do
263
263
  (ad2k < may && may < first_of_may).should be true
264
264
  end
265
-
265
+
266
266
  it 'negative years are sorted inversely' do
267
267
  [ad50, bc100, bc50, ad100].sort.map(&:year).should == [-100, -50, 50, 100]
268
268
  end
269
-
269
+
270
270
  it 'can be compared to dates' do
271
271
  ad50.should be < ::Date.new(50,2)
272
272
  ad50.should be > ::Date.new(49)
@@ -277,7 +277,7 @@ module CiteProc
277
277
  it 'returns nil by default' do
278
278
  Date.new.start_date.should be_nil
279
279
  end
280
-
280
+
281
281
  it 'returns a ruby date when date-parts are set' do
282
282
  Date.new(1999).start_date.year.should == 1999
283
283
  end
@@ -287,16 +287,16 @@ module CiteProc
287
287
  it 'returns nil by default' do
288
288
  Date.new.end_date.should be_nil
289
289
  end
290
-
290
+
291
291
  it 'returns nil when there is a single date-parts set' do
292
292
  Date.new(1312).end_date.should be_nil
293
293
  end
294
-
294
+
295
295
  it 'returns a ruby date when date-parts are a closed range' do
296
296
  Date.new(1999..2000).end_date.year.should == 2000
297
297
  end
298
298
  end
299
-
299
+
300
300
  describe '#-@' do
301
301
  it 'inverts the year' do
302
302
  (-ad50).should == bc50
@@ -310,7 +310,7 @@ module CiteProc
310
310
  end
311
311
 
312
312
  describe 'b.c. and a.d.' do
313
-
313
+
314
314
  it 'the year 993 is a.d.' do
315
315
  Date.new(993).should be_ad
316
316
  end
@@ -338,11 +338,11 @@ module CiteProc
338
338
  it 'the year -33 is b.c.' do
339
339
  Date.new(-33).should be_bc
340
340
  end
341
-
341
+
342
342
  it 'today is not a.d.' do
343
343
  Date.today.should_not be_ad
344
344
  end
345
-
345
+
346
346
  it 'today is not b.c.' do
347
347
  Date.today.should_not be_bc
348
348
  end
@@ -350,22 +350,22 @@ module CiteProc
350
350
  it 'the year 2000 is not a.d.' do
351
351
  ad2k.should_not be_ad
352
352
  end
353
-
353
+
354
354
  end
355
-
355
+
356
356
  describe '#empty?' do
357
357
  it 'returns true by default' do
358
358
  Date.new.should be_empty
359
359
  end
360
-
360
+
361
361
  it 'returns true when it contains no date parts' do
362
362
  Date.new({}).should be_empty
363
363
  end
364
-
364
+
365
365
  it 'returns false for today' do
366
366
  Date.today.should_not be_empty
367
367
  end
368
-
368
+
369
369
  it 'returns false for literal dates' do
370
370
  Date.new(:literal => 'foo').should_not be_empty
371
371
  end
@@ -374,8 +374,8 @@ module CiteProc
374
374
  Date.new(:season => 'Summer').should_not be_empty
375
375
  end
376
376
  end
377
-
378
- describe '#to_json' do
377
+
378
+ describe '#to_json' do
379
379
  it 'supports simple parts' do
380
380
  Date.new(%w{2000 1 15}).to_json.should == '{"date-parts":[[2000,1,15]]}'
381
381
  end
@@ -387,7 +387,7 @@ module CiteProc
387
387
  it 'supports integer parts' do
388
388
  Date.new([2000, 1, 15]).to_json.should == '{"date-parts":[[2000,1,15]]}'
389
389
  end
390
-
390
+
391
391
  it 'supports mixed parts' do
392
392
  Date.new(['2000', 1, '15']).to_json.should == '{"date-parts":[[2000,1,15]]}'
393
393
  end
@@ -399,7 +399,7 @@ module CiteProc
399
399
  it 'treats seasons as a strings' do
400
400
  Date.create({:season => '1', 'date-parts' => [[1950]]}).to_json.should =~ /"season":"1"/
401
401
  end
402
-
402
+
403
403
  it 'supports seasons' do
404
404
  Date.create({:season => 'Trinity', 'date-parts' => [[1975]]}).to_json.should =~ /"season":"Trinity"/
405
405
  end
@@ -415,7 +415,7 @@ module CiteProc
415
415
  it 'supports closed ranges' do
416
416
  Date.new([[2000,11],[2000,12]]).to_json.should == '{"date-parts":[[2000,11],[2000,12]]}'
417
417
  end
418
-
418
+
419
419
  it 'supports open ranges' do
420
420
  Date.new([[2000,11],[0,0]]).to_json.should == '{"date-parts":[[2000,11],[0,0]]}'
421
421
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: citeproc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre10
4
+ version: 1.0.0.pre11
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -162,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
162
  version: '0'
163
163
  segments:
164
164
  - 0
165
- hash: -3211648624536269637
165
+ hash: 1049133668296705127
166
166
  required_rubygems_version: !ruby/object:Gem::Requirement
167
167
  none: false
168
168
  requirements: