csl 1.0.0.pre21 → 1.0.0.pre22
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/csl/style/number.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
module CSL
|
2
2
|
class Style
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
# Numbers are CSL rendering elements which output the number variable
|
5
|
+
# selected with the required variable attribute.
|
6
6
|
class Number < Node
|
7
7
|
attr_struct :variable, :form, :'text-case',
|
8
8
|
*Schema.attr(:affixes, :display, :font)
|
9
9
|
|
10
10
|
has_no_children
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
def has_variable?
|
13
|
+
attribute?(:variable)
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def variable
|
17
|
+
attributes[:variable]
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def has_form?
|
21
|
+
attribute?(:form)
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def form
|
25
|
+
attributes[:form]
|
26
|
+
end
|
27
27
|
|
28
28
|
# @return [Boolean] whether or not the number's format is set to
|
29
29
|
# :numeric; also returns true if the number's form attribute is not
|
@@ -34,7 +34,7 @@ module CSL
|
|
34
34
|
|
35
35
|
# @return [Boolean] whether or not the number's format is set to :ordinal
|
36
36
|
def ordinal?
|
37
|
-
|
37
|
+
has_form? && form.to_sym == :ordinal
|
38
38
|
end
|
39
39
|
|
40
40
|
# @return [Boolean] whether or not the number's format is set to :'long-ordinal'
|
data/lib/csl/style/text.rb
CHANGED
@@ -7,39 +7,39 @@ module CSL
|
|
7
7
|
|
8
8
|
has_no_children
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
10
|
+
def has_variable?
|
11
|
+
attribute?(:variable)
|
12
|
+
end
|
13
|
+
|
14
|
+
def variable
|
15
|
+
attributes[:variable]
|
16
|
+
end
|
17
|
+
|
18
|
+
def variable_options
|
19
|
+
attributes_for :form
|
20
|
+
end
|
21
|
+
|
22
|
+
def has_macro?
|
23
|
+
attribute?(:macro)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Macro, nil]
|
27
|
+
def macro
|
28
|
+
raise unless parent.respond_to?(:macros)
|
29
|
+
parent.macros[attributes[:macro]]
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_term?
|
33
|
+
attribute?(:term)
|
34
|
+
end
|
35
|
+
|
36
|
+
def has_value?
|
37
|
+
attribute?(:value)
|
38
|
+
end
|
39
|
+
|
40
|
+
def value
|
41
|
+
attributes[:value]
|
42
|
+
end
|
43
43
|
end
|
44
44
|
|
45
45
|
end
|
data/lib/csl/treelike.rb
CHANGED
@@ -6,7 +6,7 @@ module CSL
|
|
6
6
|
attr_reader :children
|
7
7
|
attr_writer :nodename
|
8
8
|
|
9
|
-
|
9
|
+
protected :parent=
|
10
10
|
|
11
11
|
def self.included(base)
|
12
12
|
base.extend(ClassMethods)
|
@@ -120,9 +120,9 @@ module CSL
|
|
120
120
|
end
|
121
121
|
|
122
122
|
# @return [Boolean] true if this node has no child nodes; false otherwise.
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
def empty?
|
124
|
+
children.empty?
|
125
|
+
end
|
126
126
|
|
127
127
|
# Unlinks the node and all its children from its parent node. Returns
|
128
128
|
# the old parent node or nil.
|
@@ -212,10 +212,10 @@ module CSL
|
|
212
212
|
|
213
213
|
|
214
214
|
# Add memoized methods. When processing citations, styles will
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
215
|
+
# typically remain stable; therefore cite processors may opt
|
216
|
+
# to use memoized versions of the following methods. These
|
217
|
+
# versions are marked with an exclamation mark as a reminder
|
218
|
+
# that the return values are cached and potentially outdated.
|
219
219
|
%w{ ancestors descendants siblings root depth }.each do |name|
|
220
220
|
ivar = "@#{name}"
|
221
221
|
define_method("#{name}!") do
|
@@ -261,17 +261,17 @@ module CSL
|
|
261
261
|
end
|
262
262
|
end
|
263
263
|
|
264
|
-
|
265
|
-
|
264
|
+
def constantize_nodename(name)
|
265
|
+
return constantize(name) if respond_to?(:constantize)
|
266
266
|
|
267
267
|
klass = name.to_s.capitalize.gsub(/(\w)-(\w)/) { [$1, $2.upcase].join }
|
268
268
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
269
|
+
if const_defined?(klass)
|
270
|
+
const_get(klass)
|
271
|
+
else
|
272
|
+
nil
|
273
|
+
end
|
274
|
+
end
|
275
275
|
|
276
276
|
|
277
277
|
private
|
@@ -315,9 +315,9 @@ module CSL
|
|
315
315
|
if klass
|
316
316
|
value = klass.new(value)
|
317
317
|
else
|
318
|
-
|
319
|
-
|
320
|
-
|
318
|
+
# try to force convert value
|
319
|
+
value = (value.is_a?(String) ? TextNode : Node).new(value)
|
320
|
+
value.nodename = name.to_s
|
321
321
|
end
|
322
322
|
|
323
323
|
rescue => e
|
data/lib/csl/version.rb
CHANGED
data/spec/csl/info_spec.rb
CHANGED
@@ -1,25 +1,50 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module CSL
|
4
|
-
|
4
|
+
|
5
5
|
describe Info do
|
6
|
-
|
6
|
+
|
7
7
|
it { should_not be_nil }
|
8
8
|
it { should_not have_children }
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
before { @info = Info.new }
|
11
|
+
|
12
12
|
describe '#nodename' do
|
13
13
|
it 'returns "info"' do
|
14
14
|
subject.nodename.should == 'info'
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
|
+
describe 'license' do
|
19
|
+
it { should_not have_rights }
|
20
|
+
it { should_not be_default_license }
|
21
|
+
|
22
|
+
it 'has no license by default' do
|
23
|
+
@info.license.should be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'setting a license adds a rights node' do
|
27
|
+
expect { @info.license = 'cc' }.to change { @info.has_rights? }
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'setting the default license creates the default rights node' do
|
31
|
+
@info.default_license!
|
32
|
+
@info.should have_rights
|
33
|
+
@info.should be_default_license
|
34
|
+
|
35
|
+
@info.rights.text = 'cc'
|
36
|
+
@info.should_not be_default_license
|
37
|
+
|
38
|
+
@info.default_license!
|
39
|
+
@info.should be_default_license
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
18
43
|
describe '#children' do
|
19
44
|
it 'returns a Info::Children instance' do
|
20
|
-
|
45
|
+
@info.children.should be_a(Info::Children)
|
21
46
|
end
|
22
|
-
|
47
|
+
|
23
48
|
it 'allows to set the id by array accessor' do
|
24
49
|
lambda { Info.new.children[:id] = 'foo' }.should_not raise_error
|
25
50
|
end
|
@@ -27,90 +52,90 @@ module CSL
|
|
27
52
|
|
28
53
|
describe '#category' do
|
29
54
|
it 'returns an empty list by default' do
|
30
|
-
|
55
|
+
@info.category.should be_empty
|
31
56
|
end
|
32
57
|
end
|
33
58
|
|
34
59
|
describe 'citation-format' do
|
35
60
|
it 'has no citation-format by default' do
|
36
|
-
|
61
|
+
@info.citation_format.should be_nil
|
37
62
|
end
|
38
|
-
|
63
|
+
|
39
64
|
it 'setting a citation-format creates a new category node' do
|
40
|
-
expect { info.citation_format = 'foo' }.to change { info.has_categories? }
|
65
|
+
expect { @info.citation_format = 'foo' }.to change { @info.has_categories? }
|
41
66
|
end
|
42
67
|
|
43
68
|
it 'setting a citation-format actually sets the citation-format' do
|
44
|
-
expect { info.citation_format = 'bar' }.to change { info.citation_format }.to(:bar)
|
69
|
+
expect { @info.citation_format = 'bar' }.to change { @info.citation_format }.to(:bar)
|
45
70
|
end
|
46
|
-
|
71
|
+
|
47
72
|
describe 'given a category node with the citation-attribute set' do
|
48
|
-
before
|
49
|
-
|
73
|
+
before { @info.add_child Info::Category.new(:'citation-format' => 'author') }
|
74
|
+
|
50
75
|
it 'has a citation format' do
|
51
|
-
info.citation_format.should == :author
|
76
|
+
@info.citation_format.should == :author
|
52
77
|
end
|
53
|
-
|
78
|
+
|
54
79
|
it 'setting a citation-format does not create a new category node' do
|
55
|
-
expect { info.citation_format = 'foo' }.not_to change { info.categories.length }
|
80
|
+
expect { @info.citation_format = 'foo' }.not_to change { @info.categories.length }
|
56
81
|
end
|
57
|
-
|
82
|
+
|
58
83
|
it 'setting a citation-format actually sets the citation-format' do
|
59
|
-
expect { info.citation_format = 'bar' }.to change { info.citation_format }.to(:bar)
|
84
|
+
expect { @info.citation_format = 'bar' }.to change { @info.citation_format }.to(:bar)
|
60
85
|
end
|
61
86
|
end
|
62
|
-
|
87
|
+
|
63
88
|
describe 'given a category node without the citation-attribute set' do
|
64
|
-
before
|
65
|
-
|
89
|
+
before { @info.add_child Info::Category.new(:field => 'literature') }
|
90
|
+
|
66
91
|
it 'has no citation-format by default' do
|
67
|
-
info.citation_format.should be_nil
|
92
|
+
@info.citation_format.should be_nil
|
68
93
|
end
|
69
94
|
|
70
95
|
it 'setting a citation-format creates a new category node' do
|
71
|
-
expect { info.citation_format = 'foo' }.to change { info.categories.length }.from(1).to(2)
|
96
|
+
expect { @info.citation_format = 'foo' }.to change { @info.categories.length }.from(1).to(2)
|
72
97
|
end
|
73
98
|
|
74
99
|
it 'setting a citation-format actually sets the citation-format' do
|
75
|
-
expect { info.citation_format = 'bar' }.to change { info.citation_format }.to(:bar)
|
100
|
+
expect { @info.citation_format = 'bar' }.to change { @info.citation_format }.to(:bar)
|
76
101
|
end
|
77
102
|
end
|
78
103
|
end
|
79
|
-
|
104
|
+
|
80
105
|
describe 'link accessors' do
|
81
106
|
it { should_not have_self_link }
|
82
107
|
it { should_not have_documentation_link }
|
83
108
|
it { should_not have_template_link }
|
84
|
-
|
109
|
+
|
85
110
|
it 'self_link is nil by default' do
|
86
|
-
|
111
|
+
@info.self_link.should be_nil
|
87
112
|
end
|
88
113
|
|
89
114
|
it 'returns nil if no suitable link is set' do
|
90
115
|
Info.new {|i| i.link = {:href => 'foo', :rel => 'documentation'} }.self_link.should be_nil
|
91
116
|
end
|
92
|
-
|
117
|
+
|
93
118
|
it 'returns the href value of the link if it is set' do
|
94
119
|
Info.new {|i| i.link = {:href => 'foo', :rel => 'self'} }.self_link.should == 'foo'
|
95
120
|
end
|
96
|
-
|
121
|
+
|
97
122
|
it 'setter changes the value of existing link' do
|
98
123
|
info = Info.new {|i| i.link = {:href => 'foo', :rel => 'self'} }
|
99
124
|
expect { info.self_link = 'bar' }.to change { info.self_link }.from('foo').to('bar')
|
100
125
|
end
|
101
126
|
|
102
127
|
it 'setter creates new link node if link did not exist' do
|
103
|
-
expect { info.self_link = 'bar' }.to change { info.has_self_link? }
|
104
|
-
info.links[0].should be_a(Info::Link)
|
128
|
+
expect { @info.self_link = 'bar' }.to change { @info.has_self_link? }
|
129
|
+
@info.links[0].should be_a(Info::Link)
|
105
130
|
end
|
106
|
-
|
131
|
+
|
107
132
|
end
|
108
|
-
|
133
|
+
|
109
134
|
describe '#to_xml' do
|
110
135
|
it 'returns an empty info element by default' do
|
111
136
|
subject.to_xml.should == '<info/>'
|
112
137
|
end
|
113
|
-
|
138
|
+
|
114
139
|
it 'prints the id if present' do
|
115
140
|
Info.new { |i| i.set_child_id 'apa' }.to_xml.should == '<info><id>apa</id></info>'
|
116
141
|
end
|
@@ -119,7 +144,7 @@ module CSL
|
|
119
144
|
Info.new { |i| i.category = {:'citation-format' => 'author'} }.to_xml.should == '<info><category citation-format="author"/></info>'
|
120
145
|
end
|
121
146
|
end
|
122
|
-
|
147
|
+
|
123
148
|
describe '#pretty_print' do
|
124
149
|
it 'returns an empty info element by default' do
|
125
150
|
subject.pretty_print.should == '<info/>'
|
@@ -129,19 +154,19 @@ module CSL
|
|
129
154
|
Info.new { |i| i.set_child_id 'apa' }.pretty_print.should == "<info>\n <id>apa</id>\n</info>"
|
130
155
|
end
|
131
156
|
end
|
132
|
-
|
157
|
+
|
133
158
|
describe '#tags' do
|
134
159
|
it 'returns a list with an empty info element by default' do
|
135
160
|
subject.tags.should == ['<info/>']
|
136
161
|
end
|
137
|
-
|
162
|
+
|
138
163
|
it 'returns a nested list if id is present' do
|
139
164
|
Info.new { |i| i.set_child_id 'apa' }.tags.should == ['<info>', ['<id>apa</id>'], '</info>']
|
140
165
|
end
|
141
|
-
|
166
|
+
|
142
167
|
end
|
143
168
|
end
|
144
|
-
|
169
|
+
|
145
170
|
describe Info::Author do
|
146
171
|
it { should_not be_nil }
|
147
172
|
|
@@ -156,7 +181,7 @@ module CSL
|
|
156
181
|
it 'returns nil by default' do
|
157
182
|
subject.name.should be nil
|
158
183
|
end
|
159
|
-
|
184
|
+
|
160
185
|
it 'returns the name if set' do
|
161
186
|
poe.name.to_s.should == 'E. A. Poe'
|
162
187
|
end
|
@@ -173,42 +198,42 @@ module CSL
|
|
173
198
|
poe.email.to_s.should == 'poe@baltimore.com'
|
174
199
|
end
|
175
200
|
end
|
176
|
-
|
201
|
+
|
177
202
|
describe '#to_xml' do
|
178
203
|
it 'returns an empty author by default' do
|
179
204
|
subject.to_xml.should == '<author/>'
|
180
205
|
end
|
181
|
-
|
206
|
+
|
182
207
|
it 'prints all children' do
|
183
208
|
poe.to_xml.should == '<author><name>E. A. Poe</name><email>poe@baltimore.com</email></author>'
|
184
|
-
end
|
209
|
+
end
|
185
210
|
end
|
186
|
-
|
211
|
+
|
187
212
|
end
|
188
|
-
|
213
|
+
|
189
214
|
describe Info::Contributor do
|
190
|
-
|
215
|
+
|
191
216
|
it { should_not be_nil }
|
192
|
-
|
217
|
+
|
193
218
|
let(:bruce) { Info::Contributor.new { |c| c.name = "Bruce D'Arcus" } }
|
194
|
-
|
219
|
+
|
195
220
|
describe '#name' do
|
196
221
|
it 'returns the name' do
|
197
222
|
bruce.name.to_s.should == "Bruce D'Arcus"
|
198
223
|
end
|
199
224
|
end
|
200
|
-
|
201
|
-
|
225
|
+
|
226
|
+
|
202
227
|
describe '#to_xml' do
|
203
228
|
it 'returns an empty contributor by default' do
|
204
229
|
subject.to_xml.should == '<contributor/>'
|
205
230
|
end
|
206
|
-
|
231
|
+
|
207
232
|
it 'prints the name tag if present' do
|
208
233
|
bruce.to_xml.should == "<contributor><name>Bruce D'Arcus</name></contributor>"
|
209
|
-
end
|
234
|
+
end
|
210
235
|
end
|
211
|
-
|
236
|
+
|
212
237
|
end
|
213
|
-
|
238
|
+
|
214
239
|
end
|