csl 1.0.1 → 1.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f920dbb7c10c61a8b61e466240c5f16869363df0
4
- data.tar.gz: b6f70a565ce53bc5b707ebe554718e3982dbe1cc
3
+ metadata.gz: b4f4e2dd15fcca560abf0a5d5527097bf02d95ba
4
+ data.tar.gz: f8aa36164f892d1b45c86dc23d4f360d0c3c03c0
5
5
  SHA512:
6
- metadata.gz: 1a1e39250f3363a65f49a1b10fac9b7d1d564a267296bbc8433de4e0d9bc21b2b8909513954fe4ce55514f971b189600f4519298850ab4e5cc9cf17c0f1aa86d
7
- data.tar.gz: 5dc8b7ce0f7bc79178c4f123e5b4bb375ad07a4bee53e2ab3bbb379a9f830d4077fa6132bb9747bd73d05ea175172df7e8e94984d05d7640ae5b057fd42d521e
6
+ metadata.gz: aad6d6d7102be615407a550b3cfbb7aeca23a5c3aff00b2d896b512f66325ee9fcb5fd61482976b63b91adc07eb03317648d609812f15df9fa244b17f4492200
7
+ data.tar.gz: 691ec4b1b95f4d01e8cfa41f7ec60e49986eac63436313d6cea1122e0c46bb9f839fefc147d06aab21c4e83e7f1ce5da0e1c48b222a9205c51f9796869afbd9e
data/.gitignore CHANGED
@@ -6,6 +6,7 @@ Gemfile.lock
6
6
  /.yardoc
7
7
  /.rbx
8
8
  *.rbc
9
+ *.swp
9
10
  *.gem
10
11
  .ruby-version
11
12
  .rvm
@@ -357,7 +357,11 @@ module CSL
357
357
 
358
358
  def tags
359
359
  if textnode?
360
- ["<#{[nodename, *attribute_assignments].join(' ')}>", text, "</#{nodename}>"]
360
+ [
361
+ "<#{[nodename, *attribute_assignments].join(' ')}>",
362
+ CSL.encode_xml_text(text),
363
+ "</#{nodename}>"
364
+ ]
361
365
  else
362
366
  super
363
367
  end
@@ -417,4 +421,4 @@ module CSL
417
421
 
418
422
  TextNode.types << Term
419
423
  end
420
- end
424
+ end
@@ -293,6 +293,15 @@ module CSL
293
293
  attributes.fetch(name, false)
294
294
  end
295
295
 
296
+ # @param [[String]] names list of attribute names
297
+ # @return [Boolean] true if the node contains attributes for all
298
+ # passed-in names; false otherwise.
299
+ def attributes?(*names)
300
+ names.flatten(1).all? do |name|
301
+ attribute?(name)
302
+ end
303
+ end
304
+
296
305
  # Returns true if the node contains any attributes (ignores nil values);
297
306
  # false otherwise.
298
307
  def has_attributes?
@@ -541,4 +550,4 @@ module CSL
541
550
 
542
551
  end
543
552
 
544
- end
553
+ end
@@ -110,7 +110,12 @@ module CSL
110
110
 
111
111
  @validators = {
112
112
  :nokogiri => lambda { |schema, style|
113
- schema.validate(Nokogiri::XML(style)).map { |e| [e.line, e.message] }
113
+ begin
114
+ schema.validate(Nokogiri::XML(style, nil, nil, Nokogiri::XML::ParseOptions::PEDANTIC)).
115
+ map { |e| [e.line, e.message] }
116
+ rescue
117
+ [[0, $!.message]]
118
+ end
114
119
  },
115
120
 
116
121
  :default => lambda { |schema, style|
@@ -217,4 +222,4 @@ module CSL
217
222
  end
218
223
 
219
224
  end
220
- end
225
+ end
@@ -35,6 +35,10 @@ module CSL
35
35
 
36
36
  attr_struct :form, *Schema.attr(:name, :affixes, :font, :delimiter)
37
37
 
38
+ attr_defaults :form => 'long', :delimiter => ', ',
39
+ :'delimiter-precedes-last' => 'contextual', :initialize => true,
40
+ :'sort-separator' => ', '
41
+
38
42
  attr_children :'name-part'
39
43
 
40
44
  alias parts name_part
@@ -46,6 +50,163 @@ module CSL
46
50
  yield self if block_given?
47
51
  end
48
52
 
53
+
54
+ def initialize?
55
+ attributes[:initialize].to_s !~ /^false$/i
56
+ end
57
+
58
+ def et_al
59
+ parent && parent.et_al
60
+ end
61
+
62
+ # @param names [#to_i, Enumerable] the list of names (or its length)
63
+ # @return [Boolean] whether or not the should be truncate
64
+ def truncate?(names, subsequent = false)
65
+ names = names.length if names.respond_to?(:length)
66
+ limit = truncate_when(subsequent)
67
+
68
+ !limit.zero? && names.to_i >= limit
69
+ end
70
+
71
+ # @param [Enumerable] names
72
+ # @return [Array] the truncated list of names
73
+ def truncate(names, subsequent = false)
74
+ limit = truncate_at(subsequent)
75
+
76
+ return names if limit.zero?
77
+ names.take limit
78
+ end
79
+
80
+ def truncate_when(subsequent = false)
81
+ if subsequent && attribute?(:'et-al-subsequent-min')
82
+ attribute[:'et-al-subsequent-min'].to_i
83
+ else
84
+ attribute[:'et-al-min'].to_i
85
+ end
86
+ end
87
+
88
+ def truncate_at(subsequent = false)
89
+ if subsequent && attribute?(:'et-al-subsequent-use-first')
90
+ attribute[:'et-al-subsequent-use-first'].to_i
91
+ else
92
+ attribute[:'et-al-use-first'].to_i
93
+ end
94
+ end
95
+
96
+ # @return [String] the delimiter between family and given names
97
+ # in sort order
98
+ def sort_separator
99
+ attributes[:'sort-separator'].to_s
100
+ end
101
+
102
+ # @return [String] the delimiter between names
103
+ def delimiter
104
+ attributes[:delimiter].to_s
105
+ end
106
+
107
+ def name_as_sort_order?
108
+ attribute?(:'name-as-sort-order')
109
+ end
110
+
111
+ def name_as_sort_order
112
+ attributes[:'name-as-sort-order'].to_s
113
+ end
114
+
115
+ alias sort_order name_as_sort_order
116
+
117
+ def first_name_as_sort_order?
118
+ attributes[:'name-as-sort-order'].to_s =~ /^first$/i
119
+ end
120
+
121
+ def all_names_as_sort_order?
122
+ attributes[:'name-as-sort-order'].to_s =~ /^all$/i
123
+ end
124
+
125
+
126
+ # @param names [#to_i, Enumerable] the list of names (or its length)
127
+ # @return [Boolean] whether or not the delimiter will be inserted between
128
+ # the penultimate and the last name
129
+ def delimiter_precedes_last?(names)
130
+ names = names.length if names.respond_to?(:length)
131
+
132
+ case
133
+ when !attribute?(:and)
134
+ true
135
+ when delimiter_never_precedes_last?
136
+ false
137
+ when delimiter_always_precedes_last?
138
+ true
139
+ when delimiter_precedeces_last_after_inverted_name?
140
+ if name_as_sort_order?
141
+ all_names_as_sort_order? || names.to_i == 2
142
+ else
143
+ false
144
+ end
145
+
146
+ else
147
+ names.to_i > 2
148
+ end
149
+ end
150
+
151
+ # @return [Boolean] whether or not the should always be inserted between
152
+ # the penultimate and the last name
153
+ def delimiter_always_precedes_last?
154
+ !!(attributes[:'delimiter-precedes-last'].to_s =~ /^always$/i)
155
+ end
156
+
157
+ # Set the :'delimiter-precedes-last' attribute to 'always'.
158
+ # @return [self] self
159
+ def delimiter_always_precedes_last!
160
+ attributes[:'delimiter-precedes-last'] = 'always'
161
+ self
162
+ end
163
+
164
+ alias delimiter_precedes_last! delimiter_always_precedes_last!
165
+
166
+
167
+ # @return [Boolean] whether or not the should never be inserted between
168
+ # the penultimate and the last name
169
+ def delimiter_never_precedes_last?
170
+ !!(attributes[:'delimiter-precedes-last'].to_s =~ /^never$/i)
171
+ end
172
+
173
+ # Set the :'delimiter-precedes-last' attribute to 'never'
174
+ # @return [self] self
175
+ def delimiter_never_precedes_last!
176
+ attributes[:'delimiter-precedes-last'] = 'never'
177
+ self
178
+ end
179
+
180
+ # @return [Boolean] whether or not the should be inserted between the
181
+ # penultimate and the last name depending on the number of names
182
+ def delimiter_contextually_precedes_last?
183
+ !!(attributes[:'delimiter-precedes-last'].to_s =~ /^contextual/i)
184
+ end
185
+
186
+ # Set the :'delimiter-precedes-last' attribute to 'contextual'
187
+ # @return [self] self
188
+ def delimiter_contextually_precedes_last!
189
+ attributes[:'delimiter-precedes-last'] = 'contextual'
190
+ self
191
+ end
192
+
193
+ def delimiter_precedes_last_after_inverted_name?
194
+ !!(attributes[:'delimiter-precedes-last'].to_s =~ /^after-inverted-name/i)
195
+ end
196
+
197
+ def delimiter_precedes_last_after_inverted_name!
198
+ attributes[:'delimiter-precedes-last'] = 'after-inverted-name'
199
+ self
200
+ end
201
+
202
+ def ellipsis?
203
+ attributes[:'et-al-use-last'].to_s =~ /^true$/
204
+ end
205
+
206
+ def connector
207
+ c = attributes[:and]
208
+ c == 'symbol' ? '&' : c
209
+ end
49
210
  end
50
211
 
51
212
  class NamePart < Node
@@ -56,6 +217,8 @@ module CSL
56
217
  class EtAl < Node
57
218
  has_no_children
58
219
  attr_struct :term, *Schema.attr(:affixes, :font)
220
+
221
+ attr_defaults :term => 'et-al'
59
222
  end
60
223
 
61
224
  class Substitute < Node
@@ -1,3 +1,3 @@
1
1
  module CSL
2
- VERSION = '1.0.1'.freeze
3
- end
2
+ VERSION = '1.0.2'.freeze
3
+ end
@@ -96,9 +96,16 @@ module CSL
96
96
  it 'accepts and validates a style instance' do
97
97
  Schema.validate(Style.load(:apa)).should == []
98
98
  end
99
+
100
+ it 'does not accept invalid xml markup' do
101
+ Schema.validate(%Q{
102
+ <style xmlns="http://purl.org/net/xbiblio/csl" class="note" version="1.0">
103
+ </stle>
104
+ })[0][0].should == 0 # error on line 0 -> parse error
105
+ end
99
106
 
100
107
  # TODO fix nokogiri/jing validation
101
108
  end unless RUBY_PLATFORM =~ /java/i
102
109
 
103
110
  end
104
- end
111
+ end
@@ -2,22 +2,35 @@ require 'spec_helper'
2
2
 
3
3
  module CSL
4
4
  describe Style::Names do
5
-
5
+
6
6
  end
7
7
 
8
8
  describe Style::Name do
9
-
9
+
10
+ it { should be_delimiter_contextually_precedes_last }
11
+
12
+ [:never, :always, :contextually].each do |setting|
13
+ setter = "delimiter_#{setting}_precedes_last!"
14
+ predicate = "delimiter_#{setting}_precedes_last?"
15
+
16
+ describe "##{setter}" do
17
+ it 'sets the delimiter precedes last option accordingly' do
18
+ subject.send(setter).send(predicate).should == true
19
+ end
20
+ end
21
+ end
22
+
10
23
  end
11
24
 
12
25
  describe Style::NamePart do
13
-
26
+
14
27
  end
15
28
 
16
29
  describe Style::EtAl do
17
-
30
+
18
31
  end
19
32
 
20
33
  describe Style::Substitute do
21
-
34
+
22
35
  end
23
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvester Keil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-27 00:00:00.000000000 Z
11
+ date: 2013-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: namae