csl 1.0.0.pre3 → 1.0.0.pre4

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.
@@ -1,91 +1,147 @@
1
1
  module CSL
2
-
2
+
3
3
  class Style < Node
4
4
  types << CSL::Info << CSL::Locale
5
-
5
+
6
6
  @default = :apa
7
7
 
8
8
  @root = File.expand_path('../../../vendor/styles', __FILE__).freeze
9
-
9
+
10
10
  @extension = '.csl'.freeze
11
11
  @prefix = ''
12
-
12
+
13
13
  class << self
14
14
  include Loader
15
-
15
+
16
16
  attr_accessor :default
17
17
 
18
18
  def parse(data)
19
19
  node = CSL.parse!(data, self)
20
-
20
+
21
21
  raise ParseError, "root node is not a style: #{node.inspect}" unless
22
22
  node.is_a?(self)
23
-
23
+
24
24
  node
25
- end
25
+ end
26
26
  end
27
-
27
+
28
28
  attr_defaults :version => Schema.version, :xmlns => Schema.namespace
29
-
29
+
30
30
  attr_struct :xmlns, :version, :class, :'default-locale',
31
31
  :'initialize-with-hyphen', :'page-range-format',
32
32
  :'demote-non-dropping-particle', *Schema.attr(:name, :names)
33
-
33
+
34
34
  attr_children :'style-options', :info, :locale, :macro,
35
35
  :citation, :bibliography
36
-
36
+
37
+ attr_reader :macros, :errors
38
+
37
39
  alias options style_options
38
40
  alias locales locale
39
-
41
+
42
+ alias has_macros? has_macro?
43
+
40
44
  def_delegators :info, :self_link, :self_link=, :has_self_link?,
41
45
  :template_link, :template_link=, :has_template_link?,
42
46
  :documentation_link, :documentation_link=, :has_documentation_link?,
43
- :title=, :id=
44
-
47
+ :independent_parent_link, :independent_parent_link=,
48
+ :has_independent_parent_link?, :title=, :id=, :has_title?, :has_id?,
49
+ :published_at, :updated_at
50
+
45
51
  def initialize(attributes = {})
46
- super(attributes, &nil)
47
- children[:locale], children[:macro] = [], []
48
-
52
+ super(attributes, &nil)
53
+ children[:locale], children[:macro], @macros, @errors = [], [], {}, []
54
+
49
55
  yield self if block_given?
50
56
  end
51
57
 
58
+ # @override
59
+ def added_child(node)
60
+ delegate = :"added_#{node.nodename}"
61
+ send delegate, node if respond_to?(delegate, true)
62
+ node
63
+ end
64
+
65
+ # @override
66
+ def deleted_child(node)
67
+ delegate = :"deleted_#{node.nodename}"
68
+ send delegate, node if respond_to?(delegate, true)
69
+ node
70
+ end
71
+
52
72
  def validate
53
- Schema.validate self
73
+ @errors = Schema.validate self
54
74
  end
55
-
75
+
56
76
  def valid?
57
77
  validate.empty?
58
78
  end
59
-
79
+
60
80
  def info
61
81
  children[:info] ||= Info.new
62
82
  end
63
-
83
+
64
84
  alias_child :metadata, :info
65
-
85
+
66
86
  # @return [String] the style's id
67
87
  def id
68
- return nil unless info.has_id?
88
+ return unless info.has_id?
69
89
  info.id.to_s
70
90
  end
71
-
91
+
72
92
  # @return [String] the style's title
73
93
  def title
74
- return nil unless info.has_title?
94
+ return unless info.has_title?
75
95
  info.title.to_s
76
96
  end
77
-
78
- # @return [Time] timestamp for the time set in info.updated
79
- def updated_at
80
- return nil unless info.has_updated?
81
- Time.parse(info.updated)
82
- end
97
+
98
+ alias has_template? has_template_link?
99
+
100
+ # @return [Style] the style's template
101
+ def template
102
+ return unless has_template?
103
+ load_related_style_from template_link
104
+ end
105
+
106
+ alias dependent? has_independent_parent_link?
107
+
108
+ def independent?
109
+ !dependent?
110
+ end
111
+
112
+ def independent_parent
113
+ return unless dependent?
114
+ load_related_style_from independent_parent_link
115
+ end
83
116
 
84
117
  private
85
-
118
+
86
119
  def preamble
87
120
  Schema.preamble.dup
88
- end
121
+ end
122
+
123
+ def load_related_style_from(uri)
124
+ # TODO try local first
125
+ Style.load(uri)
126
+ end
127
+
128
+ def added_macro(node)
129
+ unless node.attribute?(:name)
130
+ raise ValidationError,
131
+ "failed to register macro #{node.inspect}: name attribute missing"
132
+ end
133
+
134
+ if macros.key?(node[:name])
135
+ raise ValidationError,
136
+ "failed to register macro #{node.inspect}: duplicate name"
137
+ end
138
+
139
+ macros[node[:name]] = node
140
+ end
141
+
142
+ def deleted_macro(node)
143
+ macros.delete node[:name]
144
+ end
89
145
  end
90
-
146
+
91
147
  end
@@ -1,17 +1,17 @@
1
1
  module CSL
2
-
2
+
3
3
  module Treelike
4
-
4
+
5
5
  attr_accessor :parent
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)
13
13
  end
14
-
14
+
15
15
  # @return [String] the node's name.
16
16
  def nodename
17
17
  @nodename ||= self.class.name.split(/::/)[-1].gsub(/([[:lower:]])([[:upper:]])/, '\1-\2').downcase
@@ -25,12 +25,13 @@ module CSL
25
25
  enum_for :each_child
26
26
  end
27
27
  end
28
-
28
+
29
29
  def delete_children(*nodes)
30
30
  nodes.each do |node|
31
31
  delete_child node
32
32
  end
33
33
  end
34
+ alias delete delete_children
34
35
 
35
36
  # Deletes child nodes that are equal to the passed-in node. Returns all
36
37
  # deleted children. If no children were deleted, returns nil. If the
@@ -38,54 +39,52 @@ module CSL
38
39
  # deleted.
39
40
  def delete_child(child)
40
41
  deleted = children.delete child
41
-
42
+
42
43
  case
43
44
  when deleted.nil? && block_given?
44
45
  yield
45
46
  when deleted.nil?
46
47
  nil
47
48
  else
48
- [*deleted].each do |node|
49
- node.parent = nil
50
-
51
- deleted_child node
52
- node.deleted_from self
53
- end
54
-
49
+ deleted.parent = nil
50
+
51
+ deleted_child deleted
52
+ deleted.deleted_from self
53
+
55
54
  deleted
56
55
  end
57
56
  rescue => e
58
57
  # TODO rollback
59
58
  raise e
60
59
  end
61
-
60
+
62
61
  def add_children(*nodes)
63
62
  nodes.each do |node|
64
63
  add_child node
65
64
  end
66
65
  self
67
66
  end
68
-
67
+
69
68
  def add_child(node)
70
69
  node.unlink
71
-
70
+
72
71
  node.parent = self
73
72
  children << node
74
-
73
+
75
74
  added_child node
76
75
  node.added_to self
77
-
76
+
78
77
  node
79
78
  rescue => e
80
79
  # TODO rollback
81
80
  raise e
82
81
  end
83
-
82
+
84
83
  def <<(node)
85
84
  add_child node
86
85
  self
87
86
  end
88
-
87
+
89
88
  # Returns the first immediate child node whose nodename matches the
90
89
  # passed-in name/pattern and attribute conditions.
91
90
  #
@@ -99,7 +98,7 @@ module CSL
99
98
  end
100
99
  end
101
100
  alias > find_child
102
-
101
+
103
102
  # Returns all immediate child nodes whose nodename matches the passed-in
104
103
  # name/pattern and attribute conditions; returns an empty array if there
105
104
  # is no match.
@@ -124,20 +123,20 @@ module CSL
124
123
  def empty?
125
124
  children.empty?
126
125
  end
127
-
126
+
128
127
  # Unlinks the node and all its children from its parent node. Returns
129
128
  # the old parent node or nil.
130
129
  def unlink
131
130
  return nil if root?
132
-
131
+
133
132
  other = parent
134
133
  other.delete_child self
135
-
134
+
136
135
  self.parent = nil
137
136
 
138
137
  other
139
138
  end
140
-
139
+
141
140
  def each_sibling
142
141
  if block_given?
143
142
  unless root?
@@ -145,73 +144,73 @@ module CSL
145
144
  yield node unless node.equal?(self)
146
145
  end
147
146
  end
148
-
147
+
149
148
  self
150
149
  else
151
150
  enum_for :each_sibling
152
151
  end
153
152
  end
154
-
153
+
155
154
  def siblings
156
155
  @siblings = each_sibling.to_a
157
156
  end
158
-
157
+
159
158
  # Traverses the node's sub-tree in depth-first order.
160
159
  def each_descendant
161
160
  if block_given?
162
161
  each_child do |child|
163
- yield child
162
+ yield child
164
163
  child.each_descendant(&Proc.new)
165
164
  end
166
-
165
+
167
166
  self
168
167
  else
169
168
  enum_for :each_descendant
170
169
  end
171
170
  end
172
-
171
+
173
172
  # Returns all descendants of the node. See {#descendants!}
174
173
  # for a memoized version.
175
174
  def descendants
176
175
  @descendants = each_descendant.to_a
177
176
  end
178
-
177
+
179
178
  def each_ancestor
180
179
  if block_given?
181
180
  p = parent
182
-
181
+
183
182
  until p.nil?
184
183
  yield p
185
184
  p = p.parent
186
185
  end
187
-
186
+
188
187
  self
189
188
  else
190
189
  enum_for :each_ancestor
191
190
  end
192
191
  end
193
-
192
+
194
193
  # @returns this node's ancestors as an array
195
194
  def ancestors
196
195
  @ancestors = each_ancestor.to_a
197
196
  end
198
-
197
+
199
198
  # @return [Fixnum] the node's current depth in the tree
200
199
  def depth
201
200
  @depth = ancestors.length
202
201
  end
203
-
202
+
204
203
  # @return [Node] the root node
205
204
  def root
206
205
  @root = root? ? self : parent.root!
207
206
  end
208
-
207
+
209
208
  # @returns [Boolean] whether or not the node is the tree's root node
210
209
  def root?
211
210
  parent.nil?
212
211
  end
213
212
 
214
-
213
+
215
214
  # Add memoized methods. When processing citations, styles will
216
215
  # typically remain stable; therefore cite processors may opt
217
216
  # to use memoized versions of the following methods. These
@@ -223,34 +222,34 @@ module CSL
223
222
  instance_variable_get(ivar) || send(name)
224
223
  end
225
224
  end
226
-
225
+
227
226
  protected
228
-
227
+
229
228
  # @abstract
230
229
  # Called after the node was added to another node.
231
230
  def added_to(node)
232
231
  end
233
-
232
+
234
233
  # @abstract
235
234
  # Called when the node was deleted from an other node.
236
235
  def deleted_from(node)
237
236
  end
238
-
237
+
239
238
  private
240
-
239
+
241
240
  # @abstract
242
241
  # Called when the passed-in node was added to this node as a child.
243
242
  def added_child(node)
244
243
  end
245
-
244
+
246
245
  # @abstract
247
246
  # Called when the passed-in node was deleted from this node's child nodes.
248
247
  def deleted_child(node)
249
248
  end
250
-
249
+
251
250
 
252
251
  module ClassMethods
253
-
252
+
254
253
  # Returns a new instance of an Array or Struct to manage the Node's
255
254
  # children. This method is called automatically by the Node's
256
255
  # constructor.
@@ -261,27 +260,27 @@ module CSL
261
260
  []
262
261
  end
263
262
  end
264
-
263
+
265
264
  def constantize_nodename(name)
266
265
  return constantize(name) if respond_to?(:constantize)
267
-
266
+
268
267
  klass = name.to_s.capitalize.gsub(/(\w)-(\w)/) { [$1, $2.upcase].join }
269
-
268
+
270
269
  if const_defined?(klass)
271
- const_get(klass)
270
+ const_get(klass)
272
271
  else
273
272
  nil
274
273
  end
275
274
  end
276
-
277
-
275
+
276
+
278
277
  private
279
-
278
+
280
279
  def attr_child_names_for(name)
281
280
  reader = name.to_s.downcase.tr('-', '_')
282
281
  [name.to_sym, reader, "set_child_#{reader}", "has_#{reader}?"]
283
282
  end
284
-
283
+
285
284
  # Creates a Struct for the passed-in child node names that will be
286
285
  # used internally by the Node to manage its children. The Struct
287
286
  # will be automatically initialized and is used similarly to the
@@ -295,7 +294,7 @@ module CSL
295
294
  # method will try to coerce the passed-in value into the correct
296
295
  # node type automatically.
297
296
  def attr_children(*names)
298
-
297
+
299
298
  names.each do |name|
300
299
  name, reader, writer, predicate = attr_child_names_for(name)
301
300
 
@@ -312,7 +311,7 @@ module CSL
312
311
  define_method(writer) do |value|
313
312
  begin
314
313
  klass = self.class.constantize_nodename(name)
315
-
314
+
316
315
  if klass
317
316
  value = klass.new(value)
318
317
  else
@@ -320,7 +319,7 @@ module CSL
320
319
  value = (value.is_a?(String) ? TextNode : Node).new(value)
321
320
  value.nodename = name.to_s
322
321
  end
323
-
322
+
324
323
  rescue => e
325
324
  raise ArgumentError, "failed to convert #{value.inspect} to node: #{e.message}"
326
325
  end unless value.respond_to?(:nodename)
@@ -328,20 +327,20 @@ module CSL
328
327
  children << value
329
328
  value
330
329
  end
331
-
330
+
332
331
  alias_method :"#{reader}=", writer unless method_defined?(:"#{reader}=")
333
332
  end
334
333
  end
335
-
334
+
336
335
  const_set(:Children, Struct.new(*names) {
337
-
336
+
338
337
  # 1.8 Compatibility
339
338
  @keys = members.map(&:to_sym).freeze
340
-
339
+
341
340
  class << self
342
341
  attr_reader :keys
343
342
  end
344
-
343
+
345
344
  def initialize(attrs = {})
346
345
  super(*attrs.symbolize_keys.values_at(*keys))
347
346
  end
@@ -351,9 +350,9 @@ module CSL
351
350
  def keys
352
351
  __class__.keys
353
352
  end
354
-
353
+
355
354
  alias original_each each
356
-
355
+
357
356
  def count
358
357
  values.reject { |c| c.nil? || c.empty? }.length
359
358
  end
@@ -373,11 +372,11 @@ module CSL
373
372
  to_enum
374
373
  end
375
374
  end
376
-
375
+
377
376
  def empty?
378
377
  all?(&:nil?)
379
378
  end
380
-
379
+
381
380
  # Adds the node as a child node. Raises ValidationError if none
382
381
  # of the Struct members matches the node's name. If there is
383
382
  # already a node set with this node name, the node will be pushed
@@ -386,7 +385,7 @@ module CSL
386
385
  unless node.respond_to?(:nodename) && keys.include?(node.nodename.to_sym)
387
386
  raise ValidationError, "not allowed to add #{node.inspect} to #{inspect}"
388
387
  end
389
-
388
+
390
389
  current = self[node.nodename]
391
390
  case current
392
391
  when Array
@@ -396,19 +395,19 @@ module CSL
396
395
  else
397
396
  self[node.nodename] = [current, node]
398
397
  end
399
-
398
+
400
399
  self
401
400
  end
402
-
401
+
403
402
  alias << push
404
-
403
+
405
404
  # Delete items from self that are equal to node. If any items are
406
405
  # found, returns the deleted items. If the items is not found,
407
406
  # returns nil. If the optional code block is given, returns the
408
407
  # result og block if the item is not found.
409
408
  def delete(node)
410
409
  return nil unless node.respond_to?(:nodename)
411
-
410
+
412
411
  deleted = resolve(node.nodename)
413
412
  if deleted.kind_of?(Array)
414
413
  deleted = deleted.delete(node)
@@ -419,30 +418,30 @@ module CSL
419
418
  deleted = nil
420
419
  end
421
420
  end
422
-
421
+
423
422
  if deleted.nil? && block_given?
424
423
  yield
425
424
  else
426
425
  deleted
427
426
  end
428
427
  end
429
-
428
+
430
429
  def fetch(name, default = nil)
431
- if block_given?
430
+ if block_given?
432
431
  resolve(name) || yield(key)
433
432
  else
434
433
  resolve(name) || default
435
434
  end
436
435
  end
437
-
436
+
438
437
  private
439
-
438
+
440
439
  def resolve(nodename)
441
440
  keys.include?(nodename.to_sym) && send(nodename)
442
441
  end
443
442
  })
444
443
  end
445
-
444
+
446
445
  def alias_child(new_name, old_name)
447
446
  attr_child_names_for(new_name).zip(attr_child_names_for(old_name)).each do |nn, on|
448
447
  alias_method nn, on if method_defined?(on)
@@ -450,7 +449,7 @@ module CSL
450
449
  end
451
450
 
452
451
  # Turns the node into a leaf-node.
453
- def has_no_children
452
+ def has_no_children
454
453
  undef_method :add_child
455
454
  undef_method :added_child
456
455
  undef_method :add_children
@@ -459,9 +458,9 @@ module CSL
459
458
  undef_method :delete_child
460
459
  undef_method :deleted_child
461
460
  undef_method :delete_children
462
-
461
+
463
462
  private :children
464
-
463
+
465
464
  define_method(:has_children?) do
466
465
  false
467
466
  end
@@ -471,8 +470,8 @@ module CSL
471
470
  end
472
471
 
473
472
  end
474
-
473
+
475
474
  end
476
-
475
+
477
476
  end
478
477
  end