citeproc 1.0.0.pre12 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.simplecov +4 -0
  3. data/AGPL +1 -1
  4. data/BSDL +2 -2
  5. data/Gemfile +39 -19
  6. data/README.md +123 -14
  7. data/Rakefile +22 -8
  8. data/cucumber.yml +1 -1
  9. data/features/step_definitions/processor.rb +59 -0
  10. data/features/support/env.rb +45 -2
  11. data/lib/citeproc.rb +8 -8
  12. data/lib/citeproc/abbreviate.rb +5 -4
  13. data/lib/citeproc/assets.rb +109 -109
  14. data/lib/citeproc/attributes.rb +11 -11
  15. data/lib/citeproc/bibliography.rb +107 -71
  16. data/lib/citeproc/citation_data.rb +175 -150
  17. data/lib/citeproc/compatibility.rb +5 -108
  18. data/lib/citeproc/date.rb +23 -12
  19. data/lib/citeproc/engine.rb +9 -4
  20. data/lib/citeproc/errors.rb +6 -6
  21. data/lib/citeproc/extensions.rb +66 -66
  22. data/lib/citeproc/item.rb +60 -2
  23. data/lib/citeproc/names.rb +103 -24
  24. data/lib/citeproc/number.rb +27 -8
  25. data/lib/citeproc/processor.rb +31 -41
  26. data/lib/citeproc/selector.rb +132 -126
  27. data/lib/citeproc/utilities.rb +6 -6
  28. data/lib/citeproc/variable.rb +5 -4
  29. data/lib/citeproc/version.rb +1 -1
  30. data/spec/citeproc/assets_spec.rb +17 -15
  31. data/spec/citeproc/bibliography_spec.rb +17 -17
  32. data/spec/citeproc/citation_data_spec.rb +90 -90
  33. data/spec/citeproc/engine_spec.rb +3 -4
  34. data/spec/citeproc/item_spec.rb +76 -68
  35. data/spec/citeproc/names_spec.rb +187 -148
  36. data/spec/citeproc/processor_spec.rb +119 -115
  37. data/spec/citeproc/selector_spec.rb +87 -78
  38. data/spec/citeproc/variable_spec.rb +30 -30
  39. data/spec/fixtures/locales/locales-en-US.xml +304 -0
  40. data/spec/spec_helper.rb +32 -1
  41. data/tasks/testsuite.rb +209 -0
  42. metadata +19 -87
  43. data/.gitignore +0 -6
  44. data/.travis.yml +0 -21
  45. data/citeproc.gemspec +0 -40
@@ -200,6 +200,7 @@ module CiteProc
200
200
 
201
201
  include Attributes
202
202
 
203
+
203
204
  alias attributes value
204
205
  protected :value, :attributes
205
206
 
@@ -214,7 +215,7 @@ module CiteProc
214
215
  require date_parser
215
216
  @parsers << ::Object.const_get(module_id)
216
217
  rescue LoadError
217
- warn "failed to load `#{date_parser}' gem"
218
+ # warn "failed to load `#{date_parser}' gem"
218
219
  end
219
220
  end
220
221
 
@@ -272,16 +273,15 @@ module CiteProc
272
273
  end
273
274
 
274
275
  alias now today
275
-
276
276
  end
277
277
 
278
278
 
279
- attr_predicates :circa, :season, :literal, :'date-parts'
280
-
281
279
  # Make Date behave like a regular Ruby Date
282
- def_delegators :to_ruby,
283
- *::Date.instance_methods(false).reject { |m| m.to_s =~ /^to_s$|^inspect$|start$|^\W|uncertain|season/ }
280
+ def_delegators :to_ruby, *::Date.instance_methods(false).reject { |m|
281
+ m.to_s =~ /^[\W_]|[!=_]$|^(to_s|inspect|dup|clone|change)$|^(marshal|season|year|month|day|certain|uncertain)/
282
+ }
284
283
 
284
+ attr_predicates :circa, :season, :literal, :'date-parts'
285
285
 
286
286
  def initialize(value = {})
287
287
  super
@@ -292,6 +292,14 @@ module CiteProc
292
292
  @value = other.value.deep_copy
293
293
  end
294
294
 
295
+ def marshal_dump
296
+ to_citeproc
297
+ end
298
+
299
+ def marshal_load(value)
300
+ replace(value)
301
+ end
302
+
295
303
  def merge(other)
296
304
  super
297
305
  convert_parts!
@@ -330,7 +338,7 @@ module CiteProc
330
338
  DateParts.new(value.max)
331
339
  ]}
332
340
  when value.is_a?(String) && /^\s*\{/ =~ value
333
- return replace(MultiJson.decode(value, :symbolize_keys => true))
341
+ return replace(::JSON.parse(value, :symbolize_names => true))
334
342
  when value.respond_to?(:to_s)
335
343
  @value = Date.parse!(value.to_s).value
336
344
  else
@@ -340,9 +348,11 @@ module CiteProc
340
348
  self
341
349
  end
342
350
 
351
+ remove_method :date_parts
352
+
343
353
  # @return [Array<DateParts>]
344
354
  def date_parts
345
- @value[:'date-parts'] ||= []
355
+ value[:'date-parts'] ||= []
346
356
  end
347
357
 
348
358
  alias parts date_parts
@@ -442,14 +452,14 @@ module CiteProc
442
452
  # Marks the date as uncertain
443
453
  # @return [self]
444
454
  def uncertain!
445
- @value[:circa] = true
455
+ value[:circa] = true
446
456
  self
447
457
  end
448
458
 
449
459
  # Marks the date as a certain date
450
460
  # @return [self]
451
461
  def certain!
452
- @value[:circa] = false
462
+ value[:circa] = false
453
463
  self
454
464
  end
455
465
 
@@ -479,7 +489,7 @@ module CiteProc
479
489
 
480
490
  # @return [Hash] a hash representation of the date.
481
491
  def to_citeproc
482
- cp = @value.stringify_keys
492
+ cp = value.stringify_keys
483
493
 
484
494
  # Convert (or suppress empty) date-parts
485
495
  if parts.all?(&:empty?)
@@ -505,7 +515,8 @@ module CiteProc
505
515
 
506
516
  def <=>(other)
507
517
  case other
508
- when Date
518
+ when CiteProc::Date
519
+ return nil if season? || other.season?
509
520
  parts <=> other.parts
510
521
  when ::Date
511
522
  parts <=> [other]
@@ -25,7 +25,7 @@ module CiteProc
25
25
  def default
26
26
  @default ||= autodetect or warn 'no citeproc engine found'
27
27
  end
28
-
28
+
29
29
  # Returns the engine class for the given name or nil. If no suitable
30
30
  # class is found and a block is given, executes the block and returns
31
31
  # the result. The list of available engines will be passed to the block.
@@ -42,6 +42,8 @@ module CiteProc
42
42
 
43
43
  # Returns the best available engine class or nil.
44
44
  def autodetect(options = {})
45
+ load('citeproc-ruby') if subclasses.empty?
46
+
45
47
  subclasses.detect { |e|
46
48
  !options.has_key?(:engine) || e.name == options[:engine] and
47
49
  !options.has_key?(:name) || e.name == options[:name]
@@ -66,13 +68,12 @@ module CiteProc
66
68
 
67
69
  def priority
68
70
  @priority ||= 0
69
- end
71
+ end
70
72
  end
71
73
 
72
74
  attr_accessor :processor
73
75
 
74
- def_delegators :@processor, :options, :abbreviations, :style, :locale,
75
- :items, :language, :region, :abbreviate
76
+ def_delegators :@processor, :options, :abbreviate
76
77
 
77
78
  def initialize(processor = nil)
78
79
  @processor = processor
@@ -97,6 +98,10 @@ module CiteProc
97
98
  raise NotImplementedByEngine
98
99
  end
99
100
 
101
+ def render
102
+ raise NotImplementedByEngine
103
+ end
104
+
100
105
  def update_items
101
106
  raise NotImplementedByEngine
102
107
  end
@@ -6,14 +6,14 @@ module CiteProc
6
6
  def initialize(message, original = $!)
7
7
  @original = original
8
8
  super(message)
9
- end
9
+ end
10
10
  end
11
-
11
+
12
12
  ParseError = Class.new(Error)
13
-
13
+
14
14
  EngineError = Class.new(Error)
15
-
15
+
16
16
  NotImplementedByEngine = Class.new(Error)
17
-
17
+
18
18
  RenderingError = Class.new(Error)
19
- end
19
+ end
@@ -1,38 +1,38 @@
1
1
 
2
2
  module CiteProc
3
3
  module Extensions
4
-
5
- module Underscore
6
- def underscore(word)
7
- word = word.to_s.dup
8
- word.gsub!(/::/, '/')
9
- word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
10
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
11
- word.tr!('-', '_')
12
- word.downcase!
13
- word
14
- end
15
- end
16
-
4
+
5
+ module Underscore
6
+ def underscore(word)
7
+ word = word.to_s.dup
8
+ word.gsub!(/::/, '/')
9
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
10
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
11
+ word.tr!('-', '_')
12
+ word.downcase!
13
+ word
14
+ end
15
+ end
16
+
17
17
  module DeepCopy
18
18
  # See Matz, Flanagan: 'The Ruby Programming Language', p.83
19
19
  def deep_copy
20
20
  Marshal.load(Marshal.dump(self))
21
21
  end
22
22
  end
23
-
24
- module DeepFetch
23
+
24
+ module DeepFetch
25
25
  def deep_fetch(*arguments)
26
26
  arguments.reduce(self) { |s,a| s[a] } rescue nil
27
27
  end
28
-
28
+
29
29
  def [](*arguments)
30
30
  return super if arguments.length == 1
31
31
  deep_fetch(*arguments)
32
32
  end
33
-
33
+
34
34
  end
35
-
35
+
36
36
  # shamelessly copied from active_support
37
37
  module SymbolizeKeys
38
38
  def symbolize_keys
@@ -41,53 +41,53 @@ module CiteProc
41
41
  options
42
42
  end
43
43
  end
44
-
44
+
45
45
  def symbolize_keys!
46
46
  replace(symbolize_keys)
47
47
  end
48
48
 
49
49
  end
50
50
 
51
- module StringifyKeys
52
- def stringify_keys
53
- inject({}) do |options, (key, value)|
54
- options[(key.to_s rescue key) || key] = value
55
- options
56
- end
57
- end
58
-
59
- def stringify_keys!
60
- replace(symbolize_keys)
61
- end
62
- end
63
-
64
- module CompactJoin
65
- def compact_join(delimiter = ' ')
66
- reject { |t| t.nil? || (t.respond_to?(:empty?) && t.empty?) }.join(delimiter)
67
- end
68
- end
69
-
70
- # based and compatible to the active support version
71
- # module ToSentence
72
- # def to_sentence(options = {})
73
- # options = {
74
- # :words_connector => ", ",
75
- # :two_words_connector => " and ",
76
- # :last_word_connector => ", and "
77
- # }.merge!(options)
78
- #
79
- # case length
80
- # when 0
81
- # ""
82
- # when 1
83
- # self[0].to_s.dup
84
- # when 2
85
- # "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
86
- # else
87
- # "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
88
- # end
89
- # end
90
- # end
51
+ module StringifyKeys
52
+ def stringify_keys
53
+ inject({}) do |options, (key, value)|
54
+ options[(key.to_s rescue key) || key] = value
55
+ options
56
+ end
57
+ end
58
+
59
+ def stringify_keys!
60
+ replace(symbolize_keys)
61
+ end
62
+ end
63
+
64
+ module CompactJoin
65
+ def compact_join(delimiter = ' ')
66
+ reject { |t| t.nil? || (t.respond_to?(:empty?) && t.empty?) }.join(delimiter)
67
+ end
68
+ end
69
+
70
+ # based and compatible to the active support version
71
+ # module ToSentence
72
+ # def to_sentence(options = {})
73
+ # options = {
74
+ # :words_connector => ", ",
75
+ # :two_words_connector => " and ",
76
+ # :last_word_connector => ", and "
77
+ # }.merge!(options)
78
+ #
79
+ # case length
80
+ # when 0
81
+ # ""
82
+ # when 1
83
+ # self[0].to_s.dup
84
+ # when 2
85
+ # "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
86
+ # else
87
+ # "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
88
+ # end
89
+ # end
90
+ # end
91
91
 
92
92
  module AliasMethods
93
93
  private
@@ -101,10 +101,10 @@ module CiteProc
101
101
  end
102
102
 
103
103
  class Hash
104
- warn "citeproc: re-defining Hash#deep_copy, this may cause conflicts with other libraries" if method_defined?(:deep_copy)
104
+ warn "citeproc: re-defining Hash#deep_copy, this may cause conflicts with other libraries" if method_defined?(:deep_copy)
105
105
  include CiteProc::Extensions::DeepCopy
106
106
 
107
- warn "citeproc: re-defining Hash#deep_copy, this may cause conflicts with other libraries" if method_defined?(:deep_fetch)
107
+ warn "citeproc: re-defining Hash#deep_copy, this may cause conflicts with other libraries" if method_defined?(:deep_fetch)
108
108
  include CiteProc::Extensions::DeepFetch
109
109
 
110
110
  include CiteProc::Extensions::SymbolizeKeys unless method_defined?(:symbolize_keys)
@@ -112,15 +112,15 @@ class Hash
112
112
  end
113
113
 
114
114
  class Array
115
- include CiteProc::Extensions::CompactJoin
116
- # include CiteProc::Extensions::ToSentence unless method_defined?(:to_sentence)
117
-
118
- warn "citeproc: re-defining Array#deep_copy, this may cause conflicts with other libraries" if method_defined?(:deep_copy)
115
+ include CiteProc::Extensions::CompactJoin
116
+ # include CiteProc::Extensions::ToSentence unless method_defined?(:to_sentence)
117
+
118
+ warn "citeproc: re-defining Array#deep_copy, this may cause conflicts with other libraries" if method_defined?(:deep_copy)
119
119
  include CiteProc::Extensions::DeepCopy
120
120
  end
121
121
 
122
122
  class String
123
- include CiteProc::Extensions::Underscore unless method_defined?(:underscore)
123
+ include CiteProc::Extensions::Underscore unless method_defined?(:underscore)
124
124
  end
125
125
 
126
126
  # module Kernel
@@ -84,16 +84,37 @@ module CiteProc
84
84
  end
85
85
 
86
86
 
87
+ # Returns a CitationItem with a copy of this item
88
+ # attached as data.
89
+ #
90
+ # If given, number is added as the item's
91
+ # citation-number variable.
92
+ #
93
+ # @params [Fixnum] number the item's citation-number
94
+ # @returns [CitationItem] a citation item for this item
95
+ def cite(number = nil)
96
+ CitationItem.new :id => id do |c|
97
+ c.data = dup
98
+ c.data[:'citation-number'] = number unless number.nil?
99
+ end
100
+ end
101
+
87
102
  def observable_read_attribute(key)
88
103
  value = original_read_attribute(key)
104
+ return if suppressed?(key)
105
+ value
89
106
  ensure
90
107
  changed
91
108
  notify_observers :read, key, value
92
109
  end
93
110
 
94
111
  alias original_read_attribute read_attribute
112
+ alias unobservable_read_attribute read_attribute
113
+
95
114
  alias read_attribute observable_read_attribute
96
115
 
116
+ # Update [] alias!
117
+ alias [] read_attribute
97
118
 
98
119
  # @param name [Symbol] the name of the variable
99
120
  #
@@ -111,6 +132,20 @@ module CiteProc
111
132
  read_attribute name
112
133
  end
113
134
 
135
+ def language
136
+ unobservable_read_attribute(:language)
137
+ end
138
+
139
+ # An Item is interpreted as being English unless it has
140
+ # an attribute 'language' set to something other than 'en'.
141
+ #
142
+ # @return [Boolean] whether or not this is an English Item
143
+ def english?
144
+ lang = language
145
+ lang.nil? || lang == 'en'
146
+ end
147
+ alias en? english?
148
+
114
149
  # Calls a block once for each field in the item, passing the field's
115
150
  # name-value pair as parameters.
116
151
  #
@@ -133,7 +168,6 @@ module CiteProc
133
168
  to_enum
134
169
  end
135
170
  end
136
-
137
171
  alias each_pair each
138
172
 
139
173
  # Calls a block once for each field in the item, passing the field's
@@ -158,6 +192,30 @@ module CiteProc
158
192
  end
159
193
  end
160
194
 
195
+ def suppressed?(key)
196
+ suppressed.include?(key.to_s)
197
+ end
198
+
199
+ def suppress!(*keys)
200
+ keys.flatten.each do |key|
201
+ suppressed << key.to_s
202
+ end
203
+
204
+ suppressed.sort!
205
+ suppressed.uniq!
206
+
207
+ self
208
+ end
209
+
210
+ def suppressed
211
+ @suppressed ||= []
212
+ end
213
+
214
+ def ==(other)
215
+ return false unless other.is_a?(Item)
216
+ id == other.id
217
+ end
218
+
161
219
  def <=>(other)
162
220
  return nil unless other.is_a?(Attributes)
163
221
  eql?(other) ? 0 : length <=> other.length
@@ -210,4 +268,4 @@ module CiteProc
210
268
  end
211
269
  end
212
270
 
213
- end
271
+ end