csl 1.0.0.pre21 → 1.0.0.pre22
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/.gitignore +2 -0
- data/.travis.yml +4 -3
- data/Gemfile +11 -4
- data/Rakefile +7 -0
- data/csl.gemspec +3 -7
- data/features/step_definitions/parser_steps.rb +3 -1
- data/lib/csl/compatibility.rb +33 -2
- data/lib/csl/errors.rb +5 -5
- data/lib/csl/extensions.rb +6 -6
- data/lib/csl/info.rb +55 -21
- data/lib/csl/loader.rb +14 -14
- data/lib/csl/locale.rb +41 -38
- data/lib/csl/locale/date.rb +18 -18
- data/lib/csl/locale/style_options.rb +7 -7
- data/lib/csl/locale/term.rb +12 -5
- data/lib/csl/node.rb +44 -42
- data/lib/csl/pretty_printer.rb +8 -8
- data/lib/csl/schema.rb +20 -7
- data/lib/csl/style.rb +15 -12
- data/lib/csl/style/choose.rb +15 -6
- data/lib/csl/style/label.rb +1 -3
- data/lib/csl/style/layout.rb +4 -4
- data/lib/csl/style/names.rb +5 -1
- data/lib/csl/style/number.rb +15 -15
- data/lib/csl/style/text.rb +33 -33
- data/lib/csl/treelike.rb +19 -19
- data/lib/csl/version.rb +1 -1
- data/spec/csl/info_spec.rb +82 -57
- data/spec/csl/locale/term_spec.rb +6 -0
- data/spec/csl/style/choose_spec.rb +24 -8
- data/spec/csl/style/label_spec.rb +2 -15
- data/spec/csl/style_spec.rb +34 -19
- data/spec/spec_helper.rb +7 -2
- metadata +9 -64
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d4cb72ec6f5e2c4a369fe2fb0a5a36df75da5df9
|
4
|
+
data.tar.gz: 4910056174f713025c28fd9a8136468fd785651a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 74f0b979d50b5348d4f6a2b1e33c373e53abee501f840e9926f949ad2f4fb77c9a9bb07dbd302caffdfa2dc3b729cf06ddf1fb67ca4f7eebfc9efa998cdc3d34
|
7
|
+
data.tar.gz: 6330e92fe3e39b5a4cb8b6fd365f2cfb5a95d425a8b74f046a02a83bd4580c4b9a9932e400c9e8491cc85e5a422ebcf542665a65c3b99e94b436615e2148bbde
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
language: ruby
|
2
2
|
bundler_args: --without debug extra
|
3
3
|
rvm:
|
4
|
+
- 2.0.0
|
4
5
|
- 1.9.2
|
5
6
|
- 1.9.3
|
6
7
|
- jruby-18mode
|
@@ -12,10 +13,10 @@ rvm:
|
|
12
13
|
notifications:
|
13
14
|
email:
|
14
15
|
recipients:
|
15
|
-
-
|
16
|
+
- sylvester@keil.or.at
|
16
17
|
on_success: change
|
17
18
|
on_failure: always
|
18
19
|
matrix:
|
19
20
|
allow_failures:
|
20
|
-
- rvm:
|
21
|
-
- rvm: rbx-19mode
|
21
|
+
- rvm: jruby-19mode
|
22
|
+
- rvm: rbx-19mode
|
data/Gemfile
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
gemspec
|
3
3
|
|
4
|
+
group :development, :test do
|
5
|
+
gem 'rake', '~>10.0'
|
6
|
+
gem 'rspec', '~>2.13'
|
7
|
+
gem 'cucumber', '~>1.2'
|
8
|
+
end
|
9
|
+
|
4
10
|
group :debug do
|
5
11
|
gem 'ruby-debug', :platforms => [:mri_18, :jruby]
|
6
12
|
gem 'debugger', :platforms => [:mri_19]
|
13
|
+
gem 'debugger2', :platforms => [:mri_20]
|
7
14
|
end
|
8
15
|
|
9
16
|
group :optional do
|
@@ -16,10 +23,10 @@ group :extra do
|
|
16
23
|
gem 'guard', '~>1.2'
|
17
24
|
gem 'guard-rspec', '~>1.1'
|
18
25
|
gem 'guard-cucumber', '~>1.2'
|
19
|
-
gem 'rb-fsevent', '~>0.9.1', :platforms => [:mri_19, :rbx]
|
26
|
+
gem 'rb-fsevent', '~>0.9.1', :platforms => [:mri_19, :mri_20, :rbx]
|
20
27
|
|
21
|
-
|
22
|
-
|
28
|
+
gem 'yard', '~>0.8', :platforms => [:mri_19, :mri_20]
|
29
|
+
gem 'redcarpet', '~>2.1', :platforms => [:mri_19, :mri_20]
|
23
30
|
end
|
24
31
|
|
25
32
|
# vim: syntax=ruby
|
data/Rakefile
CHANGED
data/csl.gemspec
CHANGED
@@ -14,9 +14,9 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.summary = 'A Ruby CSL parser and library'
|
15
15
|
s.description =
|
16
16
|
"""
|
17
|
-
A Ruby parser and library for the Citation Style Language (CSL),
|
18
|
-
XML-based language to describe the formatting of citations
|
19
|
-
bibliographies.
|
17
|
+
A Ruby parser and library for the Citation Style Language (CSL),
|
18
|
+
an open XML-based language to describe the formatting of citations
|
19
|
+
and bibliographies.
|
20
20
|
"""
|
21
21
|
|
22
22
|
s.license = 'AGPL'
|
@@ -24,10 +24,6 @@ Gem::Specification.new do |s|
|
|
24
24
|
|
25
25
|
s.add_dependency('namae', ['~>0.3'])
|
26
26
|
|
27
|
-
s.add_development_dependency('cucumber', ['~>1.1'])
|
28
|
-
s.add_development_dependency('rspec', ['~>2.7'])
|
29
|
-
s.add_development_dependency('rake', ['~>0.9'])
|
30
|
-
|
31
27
|
s.files = `git ls-files`.split("\n")
|
32
28
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
33
29
|
s.executables = []
|
@@ -4,7 +4,9 @@ When /^I parse the CSL string(?: in the (\w+) scope)?$/ do |scope, string|
|
|
4
4
|
end
|
5
5
|
|
6
6
|
Then /^(?:the )?(\w+[\?!]?) should be "([^"]*)"$/ do |name, expected|
|
7
|
-
@csl.send(name)
|
7
|
+
actual = @csl.send(name)
|
8
|
+
actual = !!actual if expected =~ /^true|false$/
|
9
|
+
actual.to_s.should == expected
|
8
10
|
end
|
9
11
|
|
10
12
|
Then /^the (\w+) (\w+) should be "([^"]*)"$/ do |outer, inner, expected|
|
data/lib/csl/compatibility.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
class Symbol
|
3
3
|
include Comparable
|
4
|
-
|
4
|
+
|
5
5
|
def <=>(other)
|
6
6
|
return unless other.kind_of? Symbol
|
7
7
|
to_s <=> other.to_s
|
@@ -20,4 +20,35 @@ end
|
|
20
20
|
|
21
21
|
class Struct
|
22
22
|
alias_method :__class__, :class
|
23
|
-
end unless Struct.instance_methods.include?(:__class__)
|
23
|
+
end unless Struct.instance_methods.include?(:__class__)
|
24
|
+
|
25
|
+
module CSL
|
26
|
+
module_function
|
27
|
+
|
28
|
+
if RUBY_VERSION < '1.9'
|
29
|
+
|
30
|
+
XML_ENTITY_SUBSTITUTION = Hash[*%w{
|
31
|
+
& & < < > > ' ' " "
|
32
|
+
}].freeze
|
33
|
+
|
34
|
+
def encode_xml_text(string)
|
35
|
+
string.gsub(/[&<>]/) { |match|
|
36
|
+
XML_ENTITY_SUBSTITUTION[match]
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def encode_xml_attr(string)
|
41
|
+
string.gsub(/[&<>'"]/) { |match|
|
42
|
+
XML_ENTITY_SUBSTITUTION[match]
|
43
|
+
}.inspect
|
44
|
+
end
|
45
|
+
else
|
46
|
+
def encode_xml_text(string)
|
47
|
+
string.encode(:xml => :text)
|
48
|
+
end
|
49
|
+
|
50
|
+
def encode_xml_attr(string)
|
51
|
+
string.encode(:xml => :attr)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/csl/errors.rb
CHANGED
@@ -5,14 +5,14 @@ module CSL
|
|
5
5
|
|
6
6
|
def initialize(message, original = $!)
|
7
7
|
@original = original
|
8
|
-
|
8
|
+
super(message)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
class ParseError < Error
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
class ValidationError < Error
|
16
|
+
end
|
17
17
|
|
18
18
|
end
|
data/lib/csl/extensions.rb
CHANGED
@@ -35,11 +35,11 @@ module CSL
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
module Nesting
|
39
|
+
def nesting
|
40
|
+
name.split(/::/).inject([]) { |ns, n| ns << (ns[-1] || Object).const_get(n) }
|
41
|
+
end
|
42
|
+
end
|
43
43
|
|
44
44
|
module Blank
|
45
45
|
def blank?
|
@@ -55,7 +55,7 @@ class Hash
|
|
55
55
|
end
|
56
56
|
|
57
57
|
class Module
|
58
|
-
|
58
|
+
include CSL::Extensions::Nesting
|
59
59
|
end
|
60
60
|
|
61
61
|
class Object
|
data/lib/csl/info.rb
CHANGED
@@ -37,7 +37,7 @@ module CSL
|
|
37
37
|
|
38
38
|
attr_children :title, :'title-short', :id, :issn, :eissn, :issnl,
|
39
39
|
:link, :author, :contributor, :translator, :category, :published,
|
40
|
-
|
40
|
+
:summary, :updated, :rights, :'link-dependent-style'
|
41
41
|
|
42
42
|
alias_child :contributors, :contributor
|
43
43
|
alias_child :authors, :author
|
@@ -96,6 +96,11 @@ module CSL
|
|
96
96
|
|
97
97
|
alias id= set_child_id
|
98
98
|
|
99
|
+
def self_link!
|
100
|
+
return unless has_id?
|
101
|
+
self.self_link = id
|
102
|
+
end
|
103
|
+
|
99
104
|
# @return [Time,nil] when the info node's parent was last updated
|
100
105
|
def updated_at
|
101
106
|
return unless has_updated?
|
@@ -108,9 +113,9 @@ module CSL
|
|
108
113
|
ts = timestamp.respond_to?(:xmlschema) ? timestamp.xmlschema : timestamp.to_s
|
109
114
|
|
110
115
|
if has_updated?
|
111
|
-
updated = Updated.new { |u| u.text = ts }
|
112
|
-
else
|
113
116
|
updated.text = ts
|
117
|
+
else
|
118
|
+
add_child Updated.new { |u| u.text = ts }
|
114
119
|
end
|
115
120
|
|
116
121
|
self
|
@@ -128,14 +133,43 @@ module CSL
|
|
128
133
|
ts = timestamp.respond_to?(:xmlschema) ? timestamp.xmlschema : timestamp.to_s
|
129
134
|
|
130
135
|
if has_published?
|
131
|
-
published = Published.new { |u| u.text = ts }
|
132
|
-
else
|
133
136
|
published.text = ts
|
137
|
+
else
|
138
|
+
add_child Published.new { |u| u.text = ts }
|
134
139
|
end
|
135
140
|
|
136
141
|
self
|
137
142
|
end
|
138
143
|
|
144
|
+
def license
|
145
|
+
return unless has_rights?
|
146
|
+
rights[:license] || rights.to_s
|
147
|
+
end
|
148
|
+
|
149
|
+
def license=(license)
|
150
|
+
if has_rights?
|
151
|
+
rights[:license] = license
|
152
|
+
else
|
153
|
+
add_child Rights.new(:license => license)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def default_license?
|
158
|
+
has_rights? && rights[:license] == Schema.default_license &&
|
159
|
+
rights.to_s == Schema.default_rights_string
|
160
|
+
end
|
161
|
+
|
162
|
+
def default_license!
|
163
|
+
if has_rights?
|
164
|
+
rights[:license] = Schema.default_license
|
165
|
+
rights.text = Schema.default_rights_string
|
166
|
+
else
|
167
|
+
add_child Rights.new(:license => Schema.default_license) { |r|
|
168
|
+
r.text = Schema.default_rights_string
|
169
|
+
}
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
139
173
|
# @return [Symbol] the parent style's citation format
|
140
174
|
def citation_format
|
141
175
|
return unless has_categories?
|
@@ -159,21 +193,21 @@ module CSL
|
|
159
193
|
|
160
194
|
class Contributor < Node
|
161
195
|
attr_children :name, :email, :uri
|
162
|
-
|
196
|
+
def_delegators :name, *Namae::Name.members
|
163
197
|
end
|
164
198
|
|
165
199
|
class Author < Node
|
166
200
|
attr_children :name, :email, :uri
|
167
|
-
|
201
|
+
def_delegators :name, *Namae::Name.members
|
168
202
|
end
|
169
203
|
|
170
204
|
class Translator < Node
|
171
205
|
attr_children :name, :email, :uri
|
172
|
-
|
206
|
+
def_delegators :name, *Namae::Name.members
|
173
207
|
end
|
174
208
|
|
175
209
|
class Link < Node
|
176
|
-
|
210
|
+
has_language
|
177
211
|
attr_struct :href, :rel
|
178
212
|
end
|
179
213
|
|
@@ -191,17 +225,17 @@ module CSL
|
|
191
225
|
|
192
226
|
class Name < TextNode
|
193
227
|
|
194
|
-
|
228
|
+
def_delegators :namae, *Namae::Name.members
|
195
229
|
|
196
|
-
|
230
|
+
private
|
197
231
|
|
198
|
-
|
199
|
-
|
200
|
-
|
232
|
+
def namae
|
233
|
+
@namae || namae!
|
234
|
+
end
|
201
235
|
|
202
|
-
|
203
|
-
|
204
|
-
|
236
|
+
def namae!
|
237
|
+
@namae = Namae::Name.parse to_s
|
238
|
+
end
|
205
239
|
end
|
206
240
|
|
207
241
|
class Email < TextNode
|
@@ -211,19 +245,19 @@ module CSL
|
|
211
245
|
end
|
212
246
|
|
213
247
|
class Title < TextNode
|
214
|
-
|
248
|
+
has_language
|
215
249
|
end
|
216
250
|
|
217
251
|
class TitleShort < TextNode
|
218
|
-
|
252
|
+
has_language
|
219
253
|
end
|
220
254
|
|
221
255
|
class Summary < TextNode
|
222
|
-
|
256
|
+
has_language
|
223
257
|
end
|
224
258
|
|
225
259
|
class Rights < TextNode
|
226
|
-
|
260
|
+
has_language
|
227
261
|
attr_struct :license
|
228
262
|
end
|
229
263
|
|
data/lib/csl/loader.rb
CHANGED
@@ -37,26 +37,26 @@ module CSL
|
|
37
37
|
|
38
38
|
input = input.to_s
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
case
|
41
|
+
when File.exists?(input)
|
42
|
+
location = input
|
43
|
+
when File.exists?(extend_name(input))
|
44
|
+
location = extend_name(input)
|
45
|
+
when File.exists?(extend_path(input))
|
46
|
+
location = extend_path(input)
|
47
|
+
else
|
48
|
+
location = input
|
49
|
+
end
|
50
50
|
|
51
|
-
|
51
|
+
Kernel.open(location, 'r:UTF-8') do |io|
|
52
52
|
data = io.read
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
parse(data)
|
57
57
|
|
58
|
-
|
59
|
-
|
58
|
+
rescue => e
|
59
|
+
raise ParseError, "failed to load #{input.inspect}: #{e.message}"
|
60
60
|
end
|
61
61
|
|
62
62
|
def list
|
data/lib/csl/locale.rb
CHANGED
@@ -72,12 +72,15 @@ module CSL
|
|
72
72
|
attr_reader :tag_pattern
|
73
73
|
end
|
74
74
|
|
75
|
-
attr_defaults :version => Schema.
|
76
|
-
|
75
|
+
attr_defaults :version => Schema.major_version,
|
76
|
+
:xmlns => Schema.namespace
|
77
|
+
|
78
|
+
show_default_attributes!
|
77
79
|
|
78
|
-
|
80
|
+
attr_struct :xmlns, :version
|
81
|
+
attr_children :info, :'style-options', :date, :terms
|
79
82
|
|
80
|
-
|
83
|
+
has_language
|
81
84
|
|
82
85
|
attr_accessor :region
|
83
86
|
|
@@ -165,7 +168,7 @@ module CSL
|
|
165
168
|
|
166
169
|
# @return [Boolean] whether or not the Locale's version is less than CSL-Ruby's default version
|
167
170
|
def legacy?
|
168
|
-
version < Schema.
|
171
|
+
version < Schema.major_version
|
169
172
|
end
|
170
173
|
|
171
174
|
# @example
|
@@ -178,18 +181,18 @@ module CSL
|
|
178
181
|
# region to the default region for the given language.
|
179
182
|
#
|
180
183
|
# @raise [ArgumentError] if the argument is no valid locale string.
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
184
|
+
# A valid locale string is based on the syntax of IETF language tags;
|
185
|
+
# it consists of either a language or region tag (or both), separated
|
186
|
+
# by a hyphen.
|
187
|
+
#
|
188
|
+
# @return [self]
|
186
189
|
def set(locale)
|
187
190
|
@language, @region = Locale.normalize(locale).split(/-/).map(&:to_sym)
|
188
191
|
self
|
189
192
|
end
|
190
193
|
|
191
194
|
# Sets the locale's language and region to nil.
|
192
|
-
|
195
|
+
# @return [self]
|
193
196
|
def clear
|
194
197
|
@language, @region = nil
|
195
198
|
self
|
@@ -238,12 +241,12 @@ module CSL
|
|
238
241
|
raise ArgumentError, "unable to ordinalize #{number}; integer expected" unless
|
239
242
|
number.respond_to?(:to_i)
|
240
243
|
|
241
|
-
number = number.to_i
|
244
|
+
number = number.to_i
|
242
245
|
ordinal = terms.ordinalize number, options
|
243
246
|
|
244
247
|
return number.to_s if ordinal.nil?
|
245
248
|
return ordinal.to_s(options) if ordinal.long_ordinal?
|
246
|
-
|
249
|
+
|
247
250
|
[number, ordinal.to_s(options)].join
|
248
251
|
end
|
249
252
|
|
@@ -301,20 +304,20 @@ module CSL
|
|
301
304
|
validate.empty?
|
302
305
|
end
|
303
306
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
307
|
+
# @return [Locale]
|
308
|
+
def merge(*others)
|
309
|
+
deep_copy.merge!(*others)
|
310
|
+
end
|
308
311
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
312
|
+
# @return [self]
|
313
|
+
def merge!(*others)
|
314
|
+
others.each do |other|
|
315
|
+
merge_options other
|
316
|
+
merge_dates other
|
317
|
+
end
|
315
318
|
|
316
|
-
|
317
|
-
|
319
|
+
self
|
320
|
+
end
|
318
321
|
|
319
322
|
|
320
323
|
# Locales are sorted first by language, then by region; sort order is
|
@@ -373,22 +376,22 @@ module CSL
|
|
373
376
|
Schema.preamble.dup
|
374
377
|
end
|
375
378
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
379
|
+
# @param other [Locale] an other locale whose options should be merged
|
380
|
+
# @return [self]
|
381
|
+
def merge_options(other)
|
382
|
+
return self unless other.has_options?
|
380
383
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
384
|
+
if has_options?
|
385
|
+
options.attributes.merge! other.options.attributes
|
386
|
+
else
|
387
|
+
add_child other.options.dup
|
388
|
+
end
|
386
389
|
|
387
|
-
|
388
|
-
|
390
|
+
self
|
391
|
+
end
|
389
392
|
|
390
|
-
|
391
|
-
|
393
|
+
# @param other [Locale] an other locale whose date nodes should be merged
|
394
|
+
# @return [self]
|
392
395
|
def merge_dates(other)
|
393
396
|
return self unless other.has_dates?
|
394
397
|
|