darkroom 0.0.9 → 0.0.10

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.
@@ -4,6 +4,7 @@ require('base64')
4
4
  require('digest')
5
5
  require('set')
6
6
 
7
+ require_relative('delegate')
7
8
  require_relative('errors/asset_error')
8
9
  require_relative('errors/asset_not_found_error')
9
10
  require_relative('errors/circular_reference_error')
@@ -12,9 +13,7 @@ require_relative('errors/processing_error')
12
13
  require_relative('errors/unrecognized_extension_error')
13
14
 
14
15
  class Darkroom
15
- ##
16
16
  # Represents an asset.
17
- #
18
17
  class Asset
19
18
  EXTENSION_REGEX = /(?=\.\w+)/.freeze
20
19
  DEFAULT_QUOTE = '\''
@@ -28,6 +27,8 @@ class Darkroom
28
27
  \k<quote>
29
28
  /x.freeze
30
29
 
30
+ BUILT_IN_PARSE_KINDS = [:import, :reference].freeze
31
+
31
32
  # First item of each set is used as default, so order is important.
32
33
  REFERENCE_FORMATS = {
33
34
  'path' => Set.new(%w[versioned unversioned]),
@@ -36,18 +37,16 @@ class Darkroom
36
37
 
37
38
  attr_reader(:errors, :path, :path_unversioned)
38
39
 
39
- ##
40
- # Creates a new instance.
41
- #
42
- # [file] Path of file on disk.
43
- # [path] Path this asset will be referenced by (e.g. /js/app.js).
44
- # [darkroom] Darkroom instance that the asset is a member of.
45
- # [prefix:] Prefix to apply to unversioned and versioned paths.
46
- # [entry:] Boolean indicating whether or not the asset is an entry point (i.e. accessible externally).
47
- # [minify:] Boolean specifying whether or not the asset should be minified when processed.
48
- # [intermediate:] Boolean indicating whether or not the asset exists solely to provide an intermediate
49
- # form (e.g. compiled) to another asset instance.
40
+ # Public: Create a new instance.
50
41
  #
42
+ # path - String path this asset will be referenced by (e.g. /js/app.js).
43
+ # file - String absolute path of file on disk.
44
+ # darkroom - Darkroom instance that the asset is a member of.
45
+ # prefix: - String prefix to apply to unversioned and versioned paths.
46
+ # entry: - Boolean specifying if the asset is an entry point (i.e. accessible externally).
47
+ # minify: - Boolean specifying if the asset should be minified when processed.
48
+ # intermediate: - Boolean specifying if the asset exists solely to provide an intermediate form (e.g.
49
+ # compiled) for another Asset instance.
51
50
  def initialize(path, file, darkroom, prefix: nil, entry: true, minify: false, intermediate: false)
52
51
  @path = path
53
52
  @dir = File.dirname(path)
@@ -65,7 +64,8 @@ class Darkroom
65
64
 
66
65
  if @delegate.compile_delegate && !intermediate
67
66
  @delegate = @delegate.compile_delegate
68
- @intermediate_asset = Asset.new(@path, @file, @darkroom,
67
+ @intermediate_asset = Asset.new(
68
+ @path, @file, @darkroom,
69
69
  prefix: @prefix,
70
70
  entry: false,
71
71
  minify: false,
@@ -77,12 +77,13 @@ class Darkroom
77
77
  clear
78
78
  end
79
79
 
80
- ##
81
- # Processes the asset if modified since the last run (see #modified? for how modification is
82
- # determined). File is read from disk, references are substituted (if supported), content is compiled
83
- # (if required), imports are prefixed to its content (if supported), and content is minified
84
- # (if supported and enabled and the asset is an entry point).
80
+ # Public: Process the asset if it's been modified since the last run (see #modified? for how
81
+ # modification is determined). The asset file is read from disk, references are substituted (if
82
+ # supported for the asset type), content is compiled (if required), imports are prefixed to the asset's
83
+ # own content (if supported), and content is minified (if supported and enabled and the asset is an
84
+ # entry point).
85
85
  #
86
+ # Returns nothing.
86
87
  def process
87
88
  return if ran?(:process)
88
89
 
@@ -90,97 +91,98 @@ class Darkroom
90
91
  content if entry?
91
92
  end
92
93
 
93
- ##
94
- # Returns the HTTP MIME type string.
94
+ # Public: Get the HTTP MIME type string for this asset.
95
95
  #
96
+ # Returns the String content type from the asset's Delegate.
96
97
  def content_type
97
98
  @delegate.content_type
98
99
  end
99
100
 
100
- ##
101
- # Returns boolean indicating whether or not the asset is binary.
101
+ # Public: Check if the asset's content is binary.
102
102
  #
103
+ # Returns the boolean result.
103
104
  def binary?
104
- return @is_binary if defined?(@is_binary)
105
+ return @binary if defined?(@binary)
105
106
 
106
107
  type, subtype = content_type.split('/')
107
108
 
108
- @is_binary = type != 'text' && !subtype.include?('json') && !subtype.include?('xml')
109
+ @binary = type != 'text' && !subtype.include?('json') && !subtype.include?('xml')
109
110
  end
110
111
 
111
- ##
112
- # Returns boolean indicating whether or not the asset is a font.
112
+ # Public: Check if the asset is a font.
113
113
  #
114
+ # Returns the boolean result.
114
115
  def font?
115
116
  defined?(@is_font) ? @is_font : (@is_font = content_type.start_with?('font/'))
116
117
  end
117
118
 
118
- ##
119
- # Returns boolean indicating whether or not the asset is an image.
119
+ # Public: Check if the asset is an image.
120
120
  #
121
+ # Returns the boolean result.
121
122
  def image?
122
123
  defined?(@is_image) ? @is_image : (@is_image = content_type.start_with?('image/'))
123
124
  end
124
125
 
125
- ##
126
- # Returns boolean indicating whether or not the asset is an entry point.
126
+ # Public: Check if the asset is an entry point.
127
127
  #
128
+ # Returns the boolean result.
128
129
  def entry?
129
130
  @entry
130
131
  end
131
132
 
132
- ##
133
- # Returns boolean indicating whether or not an error was encountered the last time the asset was
134
- # processed.
133
+ # Public: Check if one or more errors were encountered the last time the asset was processed.
135
134
  #
135
+ # Returns the boolean result.
136
136
  def error?
137
137
  @errors && !@errors.empty?
138
138
  end
139
139
 
140
- ##
141
- # Returns ProcessingError wrapper of all errors if any exist, or nil if there are none.
140
+ # Public: Get a single error wrapper object for all errors.
142
141
  #
142
+ # Returns a ProcessingError if one or more errors exit or nil otherwise.
143
143
  def error
144
144
  @error ||= error? ? ProcessingError.new(@errors) : nil
145
145
  end
146
146
 
147
- ##
148
- # Returns hash of content.
147
+ # Public: Get an MD5 hash of the asset's content.
149
148
  #
149
+ # Returns the String hash.
150
150
  def fingerprint
151
151
  content
152
152
 
153
153
  @fingerprint
154
154
  end
155
155
 
156
- ##
157
- # Returns versioned path.
156
+ # Public: Get the versioned path of the asset (includes the fingerprint).
158
157
  #
158
+ # Returns the String versioned path.
159
159
  def path_versioned
160
160
  content
161
161
 
162
162
  @path_versioned
163
163
  end
164
164
 
165
- ##
166
- # Returns appropriate HTTP headers.
165
+ # Public: Get the asset's HTTP headers.
167
166
  #
168
- # [versioned:] Uses Cache-Control header with max-age if +true+ and ETag header if +false+.
167
+ # versioned: - Boolean indicating if this is for the versioned or unversioned asset path. If true,
168
+ # a Cache-Control header with max-age is included; if false, an ETag header is used.
169
169
  #
170
+ # Returns a Hash of String HTTP header names and String values.
170
171
  def headers(versioned: true)
171
172
  {
172
173
  'Content-Type' => content_type,
173
174
  'Cache-Control' => ('public, max-age=31536000' if versioned),
174
- 'ETag' => ("\"#{fingerprint}\"" if !versioned),
175
+ 'ETag' => ("\"#{fingerprint}\"" unless versioned),
175
176
  }.compact!
176
177
  end
177
178
 
178
- ##
179
- # Returns subresource integrity string.
179
+ # Public: Get a subresource integrity string (SHA digest).
180
180
  #
181
- # [algorithm] Hash algorithm to use to generate the integrity string (one of +:sha256+, +:sha384+, or
182
- # +:sha512+).
181
+ # algorithm - Symbol hash algorithm name to use to generate the integrity string (must be one of
182
+ # :sha256, :sha384, :sha512).
183
183
  #
184
+ # Returns the String SHA digest.
185
+ # Raises RuntimeError if the request algorithm is not valid.
184
186
  def integrity(algorithm = :sha384)
185
187
  @integrity[algorithm] ||= "#{algorithm}-#{Base64.strict_encode64(
186
188
  case algorithm
@@ -192,11 +194,11 @@ class Darkroom
192
194
  )}".freeze
193
195
  end
194
196
 
195
- ##
196
- # Returns full asset content.
197
+ # Public: Get the full asset content, including imports and asset reference content substitutions.
197
198
  #
198
- # [minified:] Boolean indicating whether or not to return minified version if it is available.
199
+ # minified: - Boolean specifying if the minified version is desired.
199
200
  #
201
+ # Returns the String asset content, minified if requested (and the asset is minifiable).
200
202
  def content(minified: @minify)
201
203
  unless ran?(:content)
202
204
  compile
@@ -221,7 +223,7 @@ class Darkroom
221
223
  )
222
224
 
223
225
  @content = finalized if finalized.kind_of?(String)
224
- rescue => e
226
+ rescue StandardError => e
225
227
  @errors << e
226
228
  end
227
229
  end
@@ -233,7 +235,7 @@ class Darkroom
233
235
  path: @path,
234
236
  content: @content,
235
237
  )
236
- rescue => e
238
+ rescue StandardError => e
237
239
  @errors << e
238
240
  end
239
241
  end
@@ -247,31 +249,34 @@ class Darkroom
247
249
  @content_minified.freeze
248
250
  end
249
251
 
250
- ##
251
- # Returns high-level object info string.
252
+ # Public: Get a high-level object info string about this Asset instance.
252
253
  #
254
+ # Returns the String.
253
255
  def inspect
254
- "#<#{self.class} "\
255
- "@entry=#{@entry.inspect}, "\
256
- "@errors=#{@errors.inspect}, "\
257
- "@extension=#{@extension.inspect}, "\
258
- "@file=#{@file.inspect}, "\
259
- "@fingerprint=#{@fingerprint.inspect}, "\
260
- "@minify=#{@minify.inspect}, "\
261
- "@mtime=#{@mtime.inspect}, "\
262
- "@path=#{@path.inspect}, "\
263
- "@path_unversioned=#{@path_unversioned.inspect}, "\
264
- "@path_versioned=#{@path_versioned.inspect}, "\
265
- "@prefix=#{@prefix.inspect}"\
256
+ "#<#{self.class} " \
257
+ "@delegate=#{@delegate.inspect}, " \
258
+ "@dir=#{@dir.inspect}, " \
259
+ "@entry=#{@entry.inspect}, " \
260
+ "@errors=#{@errors.inspect}, " \
261
+ "@extension=#{@extension.inspect}, " \
262
+ "@file=#{@file.inspect}, " \
263
+ "@fingerprint=#{@fingerprint.inspect}, " \
264
+ "@minify=#{@minify.inspect}, " \
265
+ "@modified=#{@modified.inspect}, " \
266
+ "@mtime=#{@mtime.inspect}, " \
267
+ "@path=#{@path.inspect}, " \
268
+ "@path_unversioned=#{@path_unversioned.inspect}, " \
269
+ "@path_versioned=#{@path_versioned.inspect}, " \
270
+ "@prefix=#{@prefix.inspect}" \
266
271
  '>'
267
272
  end
268
273
 
269
274
  protected
270
275
 
271
- ##
272
- # Returns true if the asset or any of its dependencies were modified since last processed, or if an
276
+ # Internal: Check if the asset or any of its dependencies were modified since last processed, or if an
273
277
  # error was recorded during the last processing run.
274
278
  #
279
+ # Returns the boolean result.
275
280
  def modified?
276
281
  @modified_key == @darkroom.process_key ? (return @modified) : @modified_key = @darkroom.process_key
277
282
 
@@ -289,9 +294,9 @@ class Darkroom
289
294
  end
290
295
  end
291
296
 
292
- ##
293
- # Clears content, dependencies, and errors so asset is ready for (re)processing.
297
+ # Internal: Clear content, dependencies, and errors so asset is ready for (re)processing.
294
298
  #
299
+ # Returns nothing.
295
300
  def clear
296
301
  return if ran?(:clear)
297
302
 
@@ -315,9 +320,9 @@ class Darkroom
315
320
  @errors = []
316
321
  end
317
322
 
318
- ##
319
- # Reads the asset file into memory.
323
+ # Internal: Read the asset file into memory.
320
324
  #
325
+ # Returns nothing.
321
326
  def read
322
327
  return if ran?(:read)
323
328
 
@@ -336,9 +341,9 @@ class Darkroom
336
341
  end
337
342
  end
338
343
 
339
- ##
340
- # Parses own content to build list of imports and references.
344
+ # Internal: Parse the asset's own content to build the lists of imports and references.
341
345
  #
346
+ # Returns nothing.
342
347
  def parse
343
348
  return if ran?(:parse)
344
349
 
@@ -349,7 +354,7 @@ class Darkroom
349
354
  match = Regexp.last_match
350
355
  asset = nil
351
356
 
352
- if kind == :import || kind == :reference
357
+ if BUILT_IN_PARSE_KINDS.include?(kind)
353
358
  path = File.expand_path(match[:path], @dir)
354
359
  asset = @darkroom.manifest(path)
355
360
 
@@ -362,18 +367,18 @@ class Darkroom
362
367
  end
363
368
  end
364
369
 
365
- ##
366
- # Returns direct dependencies (ones explicitly specified in the asset's own content.)
370
+ # Internal: Get direct dependencies (ones explicitly specified in the asset's own content).
367
371
  #
372
+ # Returns an Array of Asset objects.
368
373
  def own_dependencies
369
374
  parse
370
375
 
371
376
  @own_dependencies
372
377
  end
373
378
 
374
- ##
375
- # Returns all dependencies (including dependencies of dependencies).
379
+ # Internal: Get all dependencies (including dependencies of dependencies).
376
380
  #
381
+ # Returns an Array of Asset objects.
377
382
  def dependencies
378
383
  unless ran?(:dependencies)
379
384
  parse
@@ -383,18 +388,18 @@ class Darkroom
383
388
  @dependencies
384
389
  end
385
390
 
386
- ##
387
- # Returns direct imports (ones explicitly specified in the asset's own content.)
391
+ # Internal: Get direct imports (ones explicitly specified in the asset's own content).
388
392
  #
393
+ # Returns an Array of Asset objects.
389
394
  def own_imports
390
395
  parse
391
396
 
392
397
  @own_imports
393
398
  end
394
399
 
395
- ##
396
- # Returns all imports (including imports of imports).
400
+ # Internal: Get all imports (including imports of imports).
397
401
  #
402
+ # Returns an Array of Asset objects.
398
403
  def imports
399
404
  unless ran?(:imports)
400
405
  parse
@@ -404,18 +409,18 @@ class Darkroom
404
409
  @imports
405
410
  end
406
411
 
407
- ##
408
- # Performs import and reference substitutions based on parse matches.
412
+ # Internal: Perform import and reference substitutions based on parse matches.
409
413
  #
414
+ # Returns nothing.
410
415
  def substitute
411
416
  return if ran?(:substitute)
412
417
 
413
418
  parse
414
419
  substitutions = []
415
420
 
416
- @parse_matches.sort_by! { |_, match, __| match.begin(0) }.each do |kind, match, asset|
417
- format = nil
421
+ @parse_matches.sort_by! { |_kind, match, _asset| match.begin(0) }
418
422
 
423
+ @parse_matches.each do |kind, match, asset|
419
424
  handler = @delegate.handler(kind)
420
425
  handler_args = {
421
426
  parse_data: @parse_data,
@@ -423,24 +428,29 @@ class Darkroom
423
428
  }
424
429
  handler_args[:asset] = asset if asset
425
430
 
426
- if !asset && (kind == :import || kind == :reference)
427
- add_parse_error(match, AssetNotFoundError)
431
+ if !asset && BUILT_IN_PARSE_KINDS.include?(kind)
432
+ add_parse_error(:not_found, match)
428
433
  next
429
434
  elsif kind == :reference
435
+ entity = match[:entity]
430
436
  format = match[:format]
431
- format = REFERENCE_FORMATS[match[:entity]].first if format.nil? || format == ''
437
+
438
+ allowed_formats = REFERENCE_FORMATS[entity]
439
+ format = allowed_formats&.first if format.nil? || format == ''
432
440
 
433
441
  handler_args[:format] = format
434
442
 
435
443
  if asset.dependencies.include?(self)
436
- add_parse_error(match, CircularReferenceError)
444
+ add_parse_error(:circular_reference, match)
445
+ next
446
+ elsif allowed_formats.nil?
447
+ add_parse_error(:unrecognized_reference_entity, match)
437
448
  next
438
- elsif !REFERENCE_FORMATS[match[:entity]].include?(format)
439
- formats = REFERENCE_FORMATS[match[:entity]].join("', '")
440
- add_parse_error(match, "Invalid reference format '#{format}' (must be one of '#{formats}')")
449
+ elsif !allowed_formats.include?(format)
450
+ add_parse_error(:unrecognized_reference_format, match)
441
451
  next
442
- elsif match[:entity] == 'content' && format != 'base64' && asset.binary?
443
- add_parse_error(match, 'Base64 encoding is required for binary assets')
452
+ elsif entity == 'content' && format != 'base64' && asset.binary?
453
+ add_parse_error(:format_not_base64, match)
444
454
  next
445
455
  end
446
456
  end
@@ -449,10 +459,10 @@ class Darkroom
449
459
  substitution, start, finish = handler&.call(**handler_args)
450
460
 
451
461
  min_start, max_finish = match.offset(0)
452
- start ||= (!format || format == 'displace') ? min_start : match.begin(:quoted)
453
- finish ||= (!format || format == 'displace') ? max_finish : match.end(:quoted)
454
- start = [[start, min_start].max, max_finish].min
455
- finish = [[finish, max_finish].min, min_start].max
462
+ start ||= !format || format == 'displace' ? min_start : match.begin(:quoted)
463
+ finish ||= !format || format == 'displace' ? max_finish : match.end(:quoted)
464
+ start = start.clamp(min_start, max_finish)
465
+ finish = finish.clamp(min_start, max_finish)
456
466
 
457
467
  if kind == :reference
458
468
  case "#{match[:entity]}-#{format}"
@@ -477,7 +487,7 @@ class Darkroom
477
487
  nil
478
488
  end
479
489
 
480
- add_parse_error(match, error) if error
490
+ add_parse_error(error, match) if error
481
491
  end
482
492
 
483
493
  substitutions.reverse_each do |content, start, finish|
@@ -485,9 +495,9 @@ class Darkroom
485
495
  end
486
496
  end
487
497
 
488
- ##
489
- # Compiles the asset if compilation is supported for the asset's type.
498
+ # Internal: Compile the asset if compilation is supported for the asset's type.
490
499
  #
500
+ # Returns nothing.
491
501
  def compile
492
502
  return if ran?(:compile)
493
503
 
@@ -501,16 +511,16 @@ class Darkroom
501
511
  )
502
512
 
503
513
  @own_content = compiled if compiled.kind_of?(String)
504
- rescue => e
514
+ rescue StandardError => e
505
515
  @errors << e
506
516
  ensure
507
517
  @own_content.freeze
508
518
  end
509
519
  end
510
520
 
511
- ##
512
- # Returns the processed content of the asset without dependencies concatenated.
521
+ # Internal: Get the processed content of the asset without dependencies concatenated.
513
522
  #
523
+ # Returns the String result.
514
524
  def own_content
515
525
  compile
516
526
 
@@ -519,37 +529,35 @@ class Darkroom
519
529
 
520
530
  private
521
531
 
522
- ##
523
- # Requires any libraries necessary for compiling and minifying the asset based on its type. Raises a
524
- # MissingLibraryError if library cannot be loaded.
532
+ # Internal: Require any libraries necessary for compiling, finalizing, and minifying the asset based on
533
+ # its type.
525
534
  #
526
- # Darkroom does not explicitly depend on any libraries necessary for asset compilation or minification,
527
- # since not every app will use every kind of asset or use minification. It is instead up to each app
528
- # using Darkroom to specify any needed compilation and minification libraries as direct dependencies
529
- # (e.g. specify +gem('terser')+ in the app's Gemfile if JavaScript minification is desired).
535
+ # Darkroom does not explicitly depend on any libraries necessary for asset compilation, finalization, or
536
+ # minification. This is because not every app will use every kind of asset or use minification. It is
537
+ # instead up to each app using Darkroom to specify any needed libraries as direct dependencies (e.g. add
538
+ # gem('terser') to the app's Gemfile if JavaScript minification is desired).
530
539
  #
540
+ # Returns nothing.
541
+ # Raises MissingLibraryError if a library cannot be loaded.
531
542
  def require_libs
532
- begin
533
- require(@delegate.compile_lib) if @delegate.compile_lib
534
- rescue LoadError
535
- compile_load_error = true
536
- end
543
+ Delegate::LIB_REQUIRES.each do |need|
544
+ next if need == :minify && !@minify
537
545
 
538
- begin
539
- require(@delegate.minify_lib) if @delegate.minify_lib && @minify
540
- rescue LoadError
541
- minify_load_error = true
546
+ begin
547
+ lib = @delegate.send(:"#{need}_lib")
548
+ require(lib) if lib
549
+ rescue LoadError
550
+ raise(MissingLibraryError.new(lib, need, @extension), cause: nil)
551
+ end
542
552
  end
543
-
544
- raise(MissingLibraryError.new(@delegate.compile_lib, 'compile', @extension)) if compile_load_error
545
- raise(MissingLibraryError.new(@delegate.minify_lib, 'minify', @extension)) if minify_load_error
546
553
  end
547
554
 
548
- ##
549
- # Returns boolean indicating if a method has already been run during the current round of processing.
555
+ # Internal: Check if a method has already been run during the current round of processing and mark it as
556
+ # having been run if not.
550
557
  #
551
- # [name] Name of the method.
558
+ # name - Symbol name of the method.
552
559
  #
560
+ # Returns the boolean result.
553
561
  def ran?(name)
554
562
  modified?
555
563
 
@@ -561,11 +569,11 @@ class Darkroom
561
569
  end
562
570
  end
563
571
 
564
- ##
565
- # Utility method used by #dependencies and #imports to recursively build arrays.
572
+ # Internal: Recursively build an array of Asset objects (used by #dependencies and #imports).
566
573
  #
567
- # [name] Name of the array to accumulate (:dependencies or :imports).
574
+ # name - Symbol name of the array to accumulate (:dependencies or :imports).
568
575
  #
576
+ # Returns an Array of Asset objects.
569
577
  def accumulate(name)
570
578
  done = Set.new
571
579
  assets = [self]
@@ -583,28 +591,42 @@ class Darkroom
583
591
  assets
584
592
  end
585
593
 
586
- ##
587
- # Utility method to create a parse error of the appropriate class and append it to the errors array.
588
- #
589
- # [match] MatchData object for where the parse error occurred.
590
- # [error] Error class or message.
591
- #
592
- def add_parse_error(match, error)
593
- klass = error
594
- args = []
595
-
596
- if error == AssetNotFoundError
597
- klass = UnrecognizedExtensionError unless Darkroom.delegate(File.extname(match[:path]))
598
- args << match[:path]
594
+ # Internal: Create a parse error of the appropriate class and append it to the errors array.
595
+ #
596
+ # error - Symbol error type or String error message.
597
+ # match - MatchData object for where the parse error occurred.
598
+ #
599
+ # Returns nothing.
600
+ # Raises RuntimeError if error is not a String or recognized Symbol error name.
601
+ def add_parse_error(error, match)
602
+ klass = AssetError
603
+ args = [match[0].strip]
604
+
605
+ case error
606
+ when :not_found
607
+ path = match[:path]
608
+ delegate = Darkroom.delegate(File.extname(path)) if path
609
+ klass = delegate ? AssetNotFoundError : UnrecognizedExtensionError
610
+ args.clear << path
611
+ when :circular_reference
612
+ klass = CircularReferenceError
613
+ when :unrecognized_reference_entity
614
+ entity = match[:entity].nil? ? 'nil' : "'#{match[:entity]}'"
615
+ allowed = "'#{Asset::REFERENCE_FORMATS.keys.join("', '")}'"
616
+ message = "Invalid reference entity #{entity} (must be one of #{allowed})"
617
+ when :unrecognized_reference_format
618
+ entity = match[:entity]
619
+ format = match[:format].nil? ? 'nil' : "'#{match[:format]}'"
620
+ allowed = "'#{Asset::REFERENCE_FORMATS[entity].join("', '")}'"
621
+ message = "Invalid reference format #{format} (must be one of #{allowed})"
622
+ when :format_not_base64
623
+ message = 'Base64 encoding is required for binary assets'
599
624
  else
600
- if error.kind_of?(String)
601
- klass = AssetError
602
- args << error
603
- end
604
-
605
- args << match[0].strip
625
+ message = error.to_s
606
626
  end
607
627
 
628
+ args.unshift(message) if message
629
+
608
630
  @errors << klass.new(*args, @path, @own_content[0..match.begin(:path)].count("\n") + 1)
609
631
  end
610
632
  end