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.
- 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
@@ -1,219 +1,244 @@
|
|
1
1
|
module CiteProc
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
# A {CitationItem} consititues the main input elements to CiteProc's
|
4
|
+
# processing methods. In order to be processed correctly, an item must
|
5
|
+
# have a valid {#id} attribute used to retrieve the correpsonding {Item}
|
6
|
+
# containing the actual bibliographic data.
|
7
|
+
class CitationItem
|
8
|
+
|
9
|
+
extend Forwardable
|
10
|
+
include Attributes
|
11
|
+
include Comparable
|
12
|
+
|
13
|
+
@labels = [
|
14
|
+
:book, :chapter, :column, :figure, :folio, :issue, :line, :note, :opus,
|
15
|
+
:page, :paragraph, :part, :section, :'sub-verbo', :verse, :volume
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_reader :labels
|
20
|
+
end
|
10
21
|
|
11
|
-
|
12
|
-
|
13
|
-
:page, :paragraph, :part, :section, :'sub-verbo', :verse, :volume
|
14
|
-
].freeze
|
22
|
+
# @!attribute id
|
23
|
+
# @return [Symbol,String] the id of the corresponding resource
|
15
24
|
|
16
|
-
|
17
|
-
|
18
|
-
|
25
|
+
# @!attribute locator
|
26
|
+
# @return [String] a string identifying a page number or similar to mark
|
27
|
+
# a location or range within the resource
|
19
28
|
|
20
|
-
|
21
|
-
|
29
|
+
# @!attribute label
|
30
|
+
# Labels indicate whether the current locator is to a page, a chapter,
|
31
|
+
# or other subdivision of the target resource. Valid labels are defined
|
32
|
+
# by {.labels}.
|
33
|
+
# @return [Symbol,String] the label type
|
22
34
|
|
23
|
-
|
24
|
-
|
25
|
-
|
35
|
+
# @!attribute suppress_author
|
36
|
+
# @return [Boolean] whether or not author names will not be included
|
37
|
+
# in the citation output for this cite
|
26
38
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
39
|
+
# @!attribute author_only
|
40
|
+
# This optional parameter provides a means for certain demanding styles
|
41
|
+
# that require the processor output to be divided between the main text
|
42
|
+
# and a footnote.
|
43
|
+
# @return [Boolean] whether or not only the author name will be included
|
44
|
+
# in the citation output for this cite
|
32
45
|
|
33
|
-
|
34
|
-
|
35
|
-
# in the citation output for this cite
|
46
|
+
# @!attribute prefix
|
47
|
+
# @return [String] a string to print before cites produced for this item
|
36
48
|
|
37
|
-
|
38
|
-
|
39
|
-
# that require the processor output to be divided between the main text
|
40
|
-
# and a footnote.
|
41
|
-
# @return [Boolean] whether or not only the author name will be included
|
42
|
-
# in the citation output for this cite
|
49
|
+
# @!attribute suffix
|
50
|
+
# @return [String] a string to print after cites produced for this item
|
43
51
|
|
44
|
-
|
45
|
-
|
52
|
+
attr_predicates :id, :locator, :page, :label, :'suppress-author',
|
53
|
+
:'author-only', :prefix, :suffix
|
46
54
|
|
47
|
-
|
48
|
-
|
55
|
+
# Attributes added by processor
|
56
|
+
attr_predicates :sortkeys, :postion, :'first-reference-note-number',
|
57
|
+
:'near-note', :unsorted
|
49
58
|
|
50
|
-
|
51
|
-
:'author-only', :prefix, :suffix
|
59
|
+
attr_accessor :data
|
52
60
|
|
53
|
-
|
54
|
-
|
55
|
-
:'near-note', :unsorted
|
61
|
+
def_delegators :@data, :suppressed?, :suppress!,
|
62
|
+
:language, :english?, :en?
|
56
63
|
|
57
|
-
|
64
|
+
def initialize(attributes = nil)
|
65
|
+
merge(attributes)
|
66
|
+
yield self if block_given?
|
67
|
+
end
|
58
68
|
|
59
|
-
|
60
|
-
|
61
|
-
|
69
|
+
def initialize_copy(other)
|
70
|
+
@attributes = other.attributes.deep_copy
|
71
|
+
end
|
62
72
|
|
63
|
-
|
64
|
-
|
65
|
-
|
73
|
+
def <=>(other)
|
74
|
+
return unless other.respond_to?(:data)
|
75
|
+
data <=> other.data
|
76
|
+
end
|
66
77
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
78
|
+
# @return [String] a human-readable representation of the citation item
|
79
|
+
def inspect
|
80
|
+
"#<CiteProc::CitationItem #{[id, locator].compact.map(&:inspect).join(', ')}>"
|
81
|
+
end
|
71
82
|
|
72
|
-
|
83
|
+
end
|
73
84
|
|
74
85
|
|
75
86
|
|
76
87
|
|
77
|
-
|
88
|
+
class CitationData
|
78
89
|
|
79
|
-
|
80
|
-
|
90
|
+
extend Forwardable
|
91
|
+
include Enumerable
|
81
92
|
|
82
|
-
|
83
|
-
|
84
|
-
|
93
|
+
@defaults = {
|
94
|
+
:footnote => 0
|
95
|
+
}.freeze
|
85
96
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
97
|
+
@rb2cp = {
|
98
|
+
:id => 'citationID',
|
99
|
+
:items => 'citationItems',
|
100
|
+
:sorted_items => 'sortedItems',
|
101
|
+
:footnote => 'noteIndex',
|
102
|
+
:options => 'properties'
|
103
|
+
}
|
93
104
|
|
94
|
-
|
95
|
-
|
105
|
+
@cp2rb = @rb2cp.invert.freeze
|
106
|
+
@rb2cp.freeze
|
96
107
|
|
97
|
-
|
98
|
-
|
99
|
-
|
108
|
+
class << self
|
109
|
+
attr_reader :defaults, :cp2rb, :rb2cp
|
110
|
+
end
|
100
111
|
|
101
|
-
|
112
|
+
attr_accessor :id
|
102
113
|
|
103
|
-
|
114
|
+
attr_reader :items, :options, :sorted_items
|
104
115
|
|
105
|
-
|
116
|
+
alias properties options
|
106
117
|
|
107
|
-
|
118
|
+
def_delegators :@items, :length, :empty?, :[]
|
108
119
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
120
|
+
# Some delegators should return self
|
121
|
+
[:push, :<<, :unshift, :concat].each do |m|
|
122
|
+
define_method(m) do |*arguments|
|
123
|
+
names.send(m, *arguments)
|
124
|
+
self
|
125
|
+
end
|
126
|
+
end
|
116
127
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
128
|
+
def initialize(attributes = nil, options = {})
|
129
|
+
@options = CitationData.defaults.merge(options)
|
130
|
+
@items, @sorted_items = [], []
|
131
|
+
merge(attributes)
|
132
|
+
end
|
122
133
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
134
|
+
def initialize_copy(other)
|
135
|
+
@options = other.options.dup
|
136
|
+
@items = other.items.map(&:dup)
|
137
|
+
@sorted_items = other.items.map(&:dup)
|
138
|
+
@id = other.id.dup if other.processed?
|
139
|
+
end
|
129
140
|
|
130
141
|
def merge(other)
|
131
142
|
return self if other.nil?
|
132
143
|
|
133
144
|
case other
|
134
145
|
when String, /^\s*\{/
|
135
|
-
other =
|
146
|
+
other = JSON.parse(other, :symbolize_names => true)
|
136
147
|
when Hash
|
137
|
-
|
138
|
-
|
139
|
-
|
148
|
+
# do nothing
|
149
|
+
when Array
|
150
|
+
other = { :items => other }
|
140
151
|
when Attributes
|
141
152
|
other = other.to_hash
|
142
|
-
|
143
|
-
|
153
|
+
else
|
154
|
+
raise ParseError, "failed to merge citation data and #{other.inspect}"
|
144
155
|
end
|
145
156
|
|
146
|
-
|
157
|
+
other = convert_from_citeproc(other)
|
147
158
|
|
148
|
-
|
149
|
-
|
159
|
+
items.concat(Array(other.delete(:items)).map { |i| CitationItem.create!(i) })
|
160
|
+
sorted_items.concat(Array(other.delete(:sorted_items)))
|
150
161
|
|
151
|
-
|
152
|
-
|
162
|
+
properties = other.delete(:options)
|
163
|
+
options.merge!(convert_from_citeproc(Hash[properties])) unless properties.nil?
|
153
164
|
|
154
|
-
|
165
|
+
@id = other[:id] if other.has_key?(:id)
|
155
166
|
|
156
167
|
self
|
157
168
|
end
|
158
169
|
|
159
|
-
|
170
|
+
alias update merge
|
160
171
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
172
|
+
def each
|
173
|
+
if block_given?
|
174
|
+
if sorted?
|
175
|
+
sorted_items.each(&Proc.new)
|
176
|
+
else
|
177
|
+
items.each(&Proc.new)
|
178
|
+
end
|
169
179
|
|
170
|
-
|
171
|
-
|
172
|
-
|
180
|
+
self
|
181
|
+
else
|
182
|
+
to_enum
|
183
|
+
end
|
184
|
+
end
|
173
185
|
|
174
|
-
|
175
|
-
|
176
|
-
|
186
|
+
def processed?
|
187
|
+
!!id
|
188
|
+
end
|
177
189
|
|
178
|
-
|
179
|
-
|
180
|
-
|
190
|
+
def sorted?
|
191
|
+
!sorted_items.empty?
|
192
|
+
end
|
181
193
|
|
182
|
-
|
183
|
-
|
194
|
+
def sort!(&block)
|
195
|
+
@sorted_items = items.sort(&block)
|
196
|
+
self
|
197
|
+
end
|
184
198
|
|
185
|
-
|
186
|
-
|
199
|
+
def index
|
200
|
+
options[:footnote]
|
201
|
+
end
|
187
202
|
|
188
|
-
|
203
|
+
def footnote?
|
204
|
+
options[:footnote] > 0
|
205
|
+
end
|
189
206
|
|
190
|
-
|
191
|
-
|
207
|
+
def to_citeproc
|
208
|
+
cp = {}
|
192
209
|
|
193
|
-
|
194
|
-
|
195
|
-
end
|
210
|
+
cp[CitationData.rb2cp[:items]] = items.map(&:to_citeproc)
|
211
|
+
cp[CitationData.rb2cp[:options]] = { CitationData.rb2cp[:footnote] => index }
|
196
212
|
|
197
|
-
|
213
|
+
cp[CitationData.rb2cp[:id]] = id if processed?
|
198
214
|
|
199
|
-
|
200
|
-
|
201
|
-
"#<CiteProc::CitationData items=[#{length}]>"
|
202
|
-
end
|
215
|
+
cp
|
216
|
+
end
|
203
217
|
|
204
|
-
|
218
|
+
def to_json
|
219
|
+
::JSON.dump(to_citeproc)
|
220
|
+
end
|
205
221
|
|
206
|
-
|
207
|
-
hash = hash.symbolize_keys
|
222
|
+
alias to_s to_json
|
208
223
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
224
|
+
# @return [String] a human-readable representation of the citation data
|
225
|
+
def inspect
|
226
|
+
"#<CiteProc::CitationData items=[#{length}]>"
|
227
|
+
end
|
228
|
+
|
229
|
+
private
|
230
|
+
|
231
|
+
def convert_from_citeproc(hash)
|
232
|
+
hash = hash.symbolize_keys
|
213
233
|
|
214
|
-
|
215
|
-
|
234
|
+
CitationData.cp2rb.each do |cp, rb|
|
235
|
+
cp = cp.to_sym
|
236
|
+
hash[rb] = hash.delete(cp) if hash.has_key?(cp)
|
237
|
+
end
|
238
|
+
|
239
|
+
hash
|
240
|
+
end
|
216
241
|
|
217
|
-
|
242
|
+
end
|
218
243
|
|
219
|
-
end
|
244
|
+
end
|
@@ -1,91 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
unless Symbol.is_a?(Comparable)
|
4
|
-
class Symbol
|
5
|
-
include Comparable
|
6
|
-
|
7
|
-
def =~(pattern)
|
8
|
-
to_s =~ pattern
|
9
|
-
end
|
10
|
-
|
11
|
-
def <=>(other)
|
12
|
-
return nil unless other.is_a?(Symbol)
|
13
|
-
to_s <=> other.to_s
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
if RUBY_VERSION < '1.9'
|
21
|
-
require 'enumerator'
|
22
|
-
|
23
|
-
$KCODE = 'u'
|
24
|
-
require 'jcode'
|
25
|
-
|
26
|
-
module CiteProc
|
27
|
-
|
28
|
-
def to_unicode(string)
|
29
|
-
string.gsub(/\\?u([\da-f]{4})/i) { |m| [$1.to_i(16)].pack('U') }
|
30
|
-
end
|
31
|
-
|
32
|
-
def ruby_18
|
33
|
-
yield
|
34
|
-
end
|
35
|
-
|
36
|
-
def ruby_19
|
37
|
-
false
|
38
|
-
end
|
39
|
-
|
40
|
-
begin
|
41
|
-
require 'oniguruma'
|
42
|
-
|
43
|
-
def oniguruma
|
44
|
-
Oniguruma::ORegexp.new(yield, :syntax => Oniguruma::SYNTAX_JAVA, :encoding => Oniguruma::ENCODING_UTF8)
|
45
|
-
end
|
46
|
-
|
47
|
-
def oniguruma?
|
48
|
-
true
|
49
|
-
end
|
50
|
-
rescue LoadError
|
51
|
-
def oniguruma
|
52
|
-
false
|
53
|
-
end
|
54
|
-
alias oniguruma? oniguruma
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Remove the 'id' and 'type' methods in Ruby 1.8
|
59
|
-
class Object
|
60
|
-
undef_method :id
|
61
|
-
undef_method :type
|
62
|
-
end
|
63
|
-
|
64
|
-
else
|
65
|
-
|
66
|
-
module CiteProc
|
67
|
-
def to_unicode(string)
|
68
|
-
string
|
69
|
-
end
|
70
|
-
|
71
|
-
def ruby_18
|
72
|
-
false
|
73
|
-
end
|
74
|
-
|
75
|
-
def ruby_19
|
76
|
-
yield
|
77
|
-
end
|
78
|
-
|
79
|
-
def oniguruma
|
80
|
-
Regexp.new(yield)
|
81
|
-
end
|
82
|
-
|
83
|
-
def oniguruma?
|
84
|
-
true
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
3
|
#
|
90
4
|
# Robust unicode upcase/downcase
|
91
5
|
#
|
@@ -94,13 +8,9 @@ if RUBY_PLATFORM =~ /java/i
|
|
94
8
|
require 'java'
|
95
9
|
|
96
10
|
puts java.lang.System.getProperty('file.encoding')
|
97
|
-
|
11
|
+
|
98
12
|
module CiteProc
|
99
|
-
|
100
|
-
def jruby
|
101
|
-
yield
|
102
|
-
end
|
103
|
-
|
13
|
+
|
104
14
|
def upcase(string)
|
105
15
|
java.lang.String.new(string).to_upper_case(java.util.Locale::ENGLISH).to_s
|
106
16
|
end
|
@@ -108,23 +18,11 @@ if RUBY_PLATFORM =~ /java/i
|
|
108
18
|
def downcase(string)
|
109
19
|
java.lang.String.new(string).to_lower_case(java.util.Locale::ENGLISH).to_s
|
110
20
|
end
|
111
|
-
|
112
|
-
# def oniguruma
|
113
|
-
# Regexp.new(yield)
|
114
|
-
# end
|
115
|
-
#
|
116
|
-
# def oniguruma?
|
117
|
-
# true
|
118
|
-
# end
|
119
21
|
end
|
120
22
|
|
121
23
|
else
|
122
24
|
|
123
|
-
module CiteProc
|
124
|
-
|
125
|
-
def jruby
|
126
|
-
false
|
127
|
-
end
|
25
|
+
module CiteProc
|
128
26
|
|
129
27
|
begin
|
130
28
|
require 'unicode'
|
@@ -157,7 +55,7 @@ else
|
|
157
55
|
|
158
56
|
def downcase(string)
|
159
57
|
ActiveSupport::Multibyte::Chars.new(string).downcase.to_s
|
160
|
-
end
|
58
|
+
end
|
161
59
|
rescue LoadError
|
162
60
|
|
163
61
|
def upcase(string)
|
@@ -174,6 +72,5 @@ else
|
|
174
72
|
end
|
175
73
|
|
176
74
|
module CiteProc
|
177
|
-
module_function :
|
178
|
-
:to_unicode, :upcase, :downcase
|
75
|
+
module_function :upcase, :downcase
|
179
76
|
end
|