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.
- checksums.yaml +7 -0
- data/.simplecov +4 -0
- data/AGPL +1 -1
- data/BSDL +2 -2
- data/Gemfile +39 -19
- data/README.md +123 -14
- data/Rakefile +22 -8
- data/cucumber.yml +1 -1
- data/features/step_definitions/processor.rb +59 -0
- data/features/support/env.rb +45 -2
- data/lib/citeproc.rb +8 -8
- data/lib/citeproc/abbreviate.rb +5 -4
- data/lib/citeproc/assets.rb +109 -109
- data/lib/citeproc/attributes.rb +11 -11
- data/lib/citeproc/bibliography.rb +107 -71
- data/lib/citeproc/citation_data.rb +175 -150
- data/lib/citeproc/compatibility.rb +5 -108
- data/lib/citeproc/date.rb +23 -12
- data/lib/citeproc/engine.rb +9 -4
- data/lib/citeproc/errors.rb +6 -6
- data/lib/citeproc/extensions.rb +66 -66
- data/lib/citeproc/item.rb +60 -2
- data/lib/citeproc/names.rb +103 -24
- data/lib/citeproc/number.rb +27 -8
- data/lib/citeproc/processor.rb +31 -41
- data/lib/citeproc/selector.rb +132 -126
- data/lib/citeproc/utilities.rb +6 -6
- data/lib/citeproc/variable.rb +5 -4
- data/lib/citeproc/version.rb +1 -1
- data/spec/citeproc/assets_spec.rb +17 -15
- data/spec/citeproc/bibliography_spec.rb +17 -17
- data/spec/citeproc/citation_data_spec.rb +90 -90
- data/spec/citeproc/engine_spec.rb +3 -4
- data/spec/citeproc/item_spec.rb +76 -68
- data/spec/citeproc/names_spec.rb +187 -148
- data/spec/citeproc/processor_spec.rb +119 -115
- data/spec/citeproc/selector_spec.rb +87 -78
- data/spec/citeproc/variable_spec.rb +30 -30
- data/spec/fixtures/locales/locales-en-US.xml +304 -0
- data/spec/spec_helper.rb +32 -1
- data/tasks/testsuite.rb +209 -0
- metadata +19 -87
- data/.gitignore +0 -6
- data/.travis.yml +0 -21
- data/citeproc.gemspec +0 -40
data/lib/citeproc/date.rb
CHANGED
@@ -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
|
-
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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]
|
data/lib/citeproc/engine.rb
CHANGED
@@ -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, :
|
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
|
data/lib/citeproc/errors.rb
CHANGED
@@ -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
|
data/lib/citeproc/extensions.rb
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
|
2
2
|
module CiteProc
|
3
3
|
module Extensions
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
123
|
+
include CiteProc::Extensions::Underscore unless method_defined?(:underscore)
|
124
124
|
end
|
125
125
|
|
126
126
|
# module Kernel
|
data/lib/citeproc/item.rb
CHANGED
@@ -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
|