citeproc 1.0.0.pre12 → 1.0.0

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