esvg 4.1.6 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/esvg/svg.rb CHANGED
@@ -1,731 +1,83 @@
1
- require 'yaml'
2
- require 'json'
3
1
  require 'zlib'
4
2
  require 'digest'
5
3
 
6
4
  module Esvg
7
- class SVG
8
- attr_accessor :svgs, :last_read, :svg_symbols
5
+ class Svg
6
+ include Esvg::Utils
9
7
 
10
- CONFIG = {
11
- filename: 'svgs',
12
- class: 'svg-symbol',
13
- namespace: 'svg',
14
- core: true,
15
- namespace_before: true,
16
- optimize: false,
17
- gzip: false,
18
- fingerprint: true,
19
- throttle_read: 4,
20
- flatten: [],
21
- alias: {}
22
- }
8
+ attr_reader :asset, :vesion, :name
23
9
 
24
- CONFIG_RAILS = {
25
- source: "app/assets/svgs",
26
- assets: "app/assets/javascripts",
27
- build: "public/javascripts",
28
- temp: "tmp"
29
- }
30
-
31
- def initialize(options={})
32
- config(options)
33
-
34
- @modules = {}
35
- @last_read = nil
36
-
37
- read_cache
38
- read_files
10
+ def initialize(name, symbols, config={})
11
+ @name = name
12
+ @config = config
13
+ @symbols = symbols
14
+ @asset = File.basename(name).start_with?('_')
15
+ @version = @config[:version] || Digest::MD5.hexdigest(symbols.map(&:mtime).join)
39
16
  end
40
17
 
41
- def config(options={})
42
- @config ||= begin
43
- paths = [options[:config_file], 'config/esvg.yml', 'esvg.yml'].compact
44
-
45
- config = CONFIG.dup
46
-
47
- if Esvg.rails? || options[:rails]
48
- config.merge!(CONFIG_RAILS)
49
- end
50
-
51
- if path = paths.select{ |p| File.exist?(p)}.first
52
- config.merge!(symbolize_keys(YAML.load(File.read(path) || {})))
53
- end
54
-
55
- config.merge!(options)
56
-
57
- config[:filename] = File.basename(config[:filename], '.*')
58
-
59
- config[:pwd] = File.expand_path Dir.pwd
60
- config[:source] = File.expand_path config[:source] || config[:pwd]
61
- config[:build] = File.expand_path config[:build] || config[:pwd]
62
- config[:assets] = File.expand_path config[:assets] || config[:pwd]
63
-
64
- config[:temp] = config[:pwd] if config[:temp].nil?
65
- config[:temp] = File.expand_path File.join(config[:temp], '.esvg-cache')
66
-
67
- config[:aliases] = load_aliases(config[:alias])
68
- config[:flatten] = [config[:flatten]].flatten.map { |dir| File.join(dir, '/') }.join('|')
69
-
70
- config
71
- end
18
+ def embed
19
+ %Q{if (!document.querySelector('#esvg-#{id}')) {
20
+ document.querySelector('body').insertAdjacentHTML('afterbegin', '#{svg}')
21
+ }}
72
22
  end
73
23
 
74
- def read_files
75
- if !@last_read.nil? && (Time.now.to_i - @last_read) < config[:throttle_read]
76
- return
77
- end
78
-
79
- # Get a list of svg files and modification times
80
- #
81
- find_files
82
-
83
- @last_read = Time.now.to_i
84
-
85
- puts "Read #{svgs.size} files from #{config[:source]}" if config[:print]
86
-
87
- if svgs.empty? && config[:print]
88
- puts "No svgs found at #{config[:source]}"
89
- end
24
+ def named?(names=[])
25
+ [names].flatten.map {
26
+ |n| dasherize(n)
27
+ }.include? dasherize(@name)
90
28
  end
91
29
 
92
- def find_files
93
- files = Dir[File.join(config[:source], '**/*.svg')].uniq.sort
94
- @svg_symbols = {}
95
-
96
- # Remove deleted files from svg cache
97
- (svgs.keys - file_keys(files)).each { |f| svgs.delete(f) }
98
-
99
- dirs = {}
100
-
101
- files.each do |path|
102
- mtime = File.mtime(path).to_i
103
- key = file_key path
104
- dkey = dir_key path
105
-
106
- # Use cache if possible
107
- if svgs[key].nil? || svgs[key][:last_modified] != mtime
108
- svgs[key] = process_file(path, mtime)
109
- end
110
-
111
- # Name may have changed due to flatten config
112
- svgs[key][:name] = file_name(path)
113
- svgs[key][:attr][:name] = id(svgs[key][:name])
114
-
115
- dirs[dkey] ||= {}
116
- (dirs[dkey][:files] ||= []) << key
117
-
118
- if dirs[dkey][:last_modified].nil? || dirs[dkey][:last_modified] < mtime
119
- dirs[dkey][:last_modified] = mtime
120
- end
121
- end
122
-
123
- dirs = sort(dirs)
124
-
125
- dirs.each do |dir, data|
126
-
127
- # overwrite cache if
128
- if svg_symbols[dir].nil? || # No cache for this dir yet
129
- svg_symbols[dir][:last_modified] != data[:last_modified] || # New or updated file
130
- svg_symbols[dir][:files] != data[:files] # Changed files
131
-
132
- attributes = data[:files].map { |f| svgs[f][:attr] }
133
- mtimes = data[:files].map { |f| svgs[f][:last_modified] }.join
134
-
135
- svg_symbols[dir] = data.merge({
136
- name: dir,
137
- asset: File.basename(dir).start_with?('_'),
138
- version: config[:version] || Digest::MD5.hexdigest(mtimes)
139
- })
140
-
141
- svg_symbols[dir][:path] = write_path(dir)
142
- end
143
- end
144
-
145
- @svg_symbols = sort(@svg_symbols)
146
- @svgs = sort(@svgs)
147
- end
148
-
149
- def read_cache
150
- @svgs = YAML.load(read_tmp '.svgs') || {}
151
- end
152
-
153
- def write_cache
154
- return if production?
155
-
156
- write_tmp '.svgs', sort(@svgs).to_yaml
157
- end
158
-
159
- def sort(hash)
160
- sorted = {}
161
- hash.sort.each do |h|
162
- sorted[h.first] = h.last
163
- end
164
- sorted
165
- end
166
-
167
- def embed_script(key=nil)
168
- if script = js(key)
169
- "<script>#{script}</script>"
30
+ def id
31
+ if @name == '.'
32
+ 'symbols'
170
33
  else
171
- ''
34
+ dasherize "#{@config[:prefix]}-#{name_key}"
172
35
  end
173
36
  end
174
37
 
175
- def build_paths(keys=nil)
176
- build_files(keys).map { |s| File.basename(s[:path]) }
177
- end
178
-
179
- def build_files(keys=nil)
180
- valid_keys(keys).reject do |k|
181
- svg_symbols[k][:asset]
182
- end.map { |k| svg_symbols[k] }
183
- end
184
-
185
- def asset_files(keys=nil)
186
- valid_keys(keys).select do |k|
187
- svg_symbols[k][:asset]
188
- end.map { |k| svg_symbols[k] }
189
- end
38
+ def path
39
+ @path ||= begin
40
+ name = name_key
190
41
 
191
- def process_file(path, mtime)
192
- content = File.read(path)
193
- id = id(file_key(path))
194
- size_attr = dimensions(content)
42
+ if name.start_with?('_') # Is it an asset?
43
+ File.join @config[:assets], "#{name}.js"
44
+ else # or a build file?
195
45
 
196
- {
197
- path: path,
198
- use: %Q{<use xlink:href="##{id}"/>},
199
- last_modified: mtime,
200
- attr: { id: id }.merge(size_attr),
201
- content: content
202
- }
203
- end
204
-
205
- def use(file, options={})
206
- if svg = find_svg(file, options[:fallback])
207
-
208
- if options[:color]
209
- options[:style] ||= ''
210
- options[:style] += "color:#{options[:color]};#{options[:style]}"
211
- end
212
-
213
- attr = {
214
- fill: options[:fill],
215
- style: options[:style],
216
- viewBox: svg[:attr][:viewBox],
217
- class: [config[:class], id(svg[:name]), options[:class]].compact.join(' ')
218
- }
219
-
220
- # If user doesn't pass a size or set scale: true
221
- if !(options[:width] || options[:height] || options[:scale])
222
-
223
- # default to svg dimensions
224
- attr[:width] = svg[:attr][:width]
225
- attr[:height] = svg[:attr][:height]
226
- else
227
-
228
- # Add sizes (nil options will be stripped)
229
- attr[:width] = options[:width]
230
- attr[:height] = options[:height]
231
- end
232
-
233
- use = %Q{<svg #{attributes(attr)}>#{svg[:use]}#{title(options)}#{desc(options)}#{options[:content]||''}</svg>}
234
-
235
- if Esvg.rails?
236
- use.html_safe
237
- else
238
- use
239
- end
240
- else
241
- if production?
242
- return ''
243
- else
244
- raise "no svg named '#{get_alias(file)}' exists at #{config[:source]}"
245
- end
246
- end
247
- end
248
-
249
- alias :svg_icon :use
250
-
251
- def dimensions(input)
252
- viewbox = input.scan(/<svg.+(viewBox=["'](.+?)["'])/).flatten.last
253
- if viewbox
254
- coords = viewbox.split(' ')
255
-
256
- {
257
- viewBox: viewbox,
258
- width: coords[2].to_i - coords[0].to_i,
259
- height: coords[3].to_i - coords[1].to_i
260
- }
261
- else
262
- {}
263
- end
264
- end
265
-
266
- def attributes(hash)
267
- att = []
268
- hash.each do |key, value|
269
- att << %Q{#{key}="#{value}"} unless value.nil?
270
- end
271
- att.join(' ')
272
- end
273
-
274
- def exist?(name, fallback=nil)
275
- !find_svg(name, fallback).nil?
276
- end
277
-
278
- def find_svg(name, fallback=nil)
279
- name = get_alias dasherize(name)
280
-
281
- if svg = svgs.values.find { |v| v[:name] == name }
282
- svg
283
- elsif fallback
284
- find_svg(fallback)
285
- end
286
- end
287
-
288
- alias_method :exists?, :exist?
289
-
290
- def id(name)
291
- name = name_key(name)
292
- if config[:namespace_before]
293
- dasherize "#{config[:namespace]}-#{name}"
294
- else
295
- dasherize "#{name}-#{config[:namespace]}"
296
- end
297
- end
298
-
299
- def dasherize(input)
300
- input.gsub(/[\W,_]/, '-').sub(/^-/,'').gsub(/-{2,}/, '-')
301
- end
302
-
303
- def title(options)
304
- if options[:title]
305
- "<title>#{options[:title]}</title>"
306
- else
307
- ''
308
- end
309
- end
310
-
311
- def desc(options)
312
- if options[:desc]
313
- "<desc>#{options[:desc]}</desc>"
314
- else
315
- ''
316
- end
317
- end
318
-
319
- def version(key)
320
- svg_symbols[key][:version]
321
- end
322
-
323
- def build
324
- paths = write_files svg_symbols.values
325
-
326
- if config[:core]
327
- path = File.join config[:assets], "_esvg.js"
328
- write_file(path, js_core)
329
- paths << path
330
- end
331
-
332
- paths
333
- end
334
-
335
- def write_files(files)
336
- paths = []
337
-
338
- files.each do |file|
339
- content = js(file[:name])
340
-
341
- write_file(file[:path], content)
342
- puts "Writing #{file[:path]}" if config[:print]
343
- paths << file[:path]
344
-
345
- if !file[:asset] && gz = compress(file[:path])
346
- puts "Writing #{gz}" if config[:print]
347
- paths << gz
348
- end
349
- end
350
-
351
- write_cache
352
-
353
- paths
354
- end
355
-
356
- def symbols(keys)
357
- symbols = valid_keys(keys).map { |key|
358
- # Build on demand
359
- build_symbols(svg_symbols[key][:files])
360
- }.join.gsub(/\n/,'')
361
-
362
- %Q{<svg id="esvg-#{key_id(keys)}" version="1.1" style="height:0;position:absolute">#{symbols}</svg>}
363
- end
364
-
365
- def build_symbols(files)
366
- files.map { |file|
367
- if svgs[file][:optimized_at].nil? || svgs[file][:optimized_at] < svgs[file][:last_modified]
368
- svgs[file][:optimized_content] = optimize(svgs[file])
369
- end
370
- svgs[file][:optimized_content]
371
- }.join.gsub(/\n/,'')
372
- end
373
-
374
- def js(key)
375
- keys = valid_keys(key)
376
- return if keys.empty?
377
-
378
- script key_id(keys), symbols(keys).gsub('/n','').gsub("'"){"\\'"}
379
- end
380
-
381
- def script(id, symbols)
382
- %Q{(function(){
383
-
384
- function embed() {
385
- if (!document.querySelector('#esvg-#{id}')) {
386
- document.querySelector('body').insertAdjacentHTML('afterbegin', '#{symbols}')
387
- }
388
- }
389
-
390
- // If DOM is already ready, embed SVGs
391
- if (document.readyState == 'interactive') { embed() }
392
-
393
- // Handle Turbolinks page change events
394
- if ( window.Turbolinks ) {
395
- document.addEventListener("turbolinks:load", function(event) { embed() })
396
- }
397
-
398
- // Handle standard DOM ready events
399
- document.addEventListener("DOMContentLoaded", function(event) { embed() })
400
- })()}
401
- end
402
-
403
- def js_core
404
- %Q{(function(){
405
- var names
406
-
407
- function attr( source, name ){
408
- if (typeof source == 'object')
409
- return name+'="'+source.getAttribute(name)+'" '
410
- else
411
- return name+'="'+source+'" ' }
412
-
413
- function dasherize( input ) {
414
- return input.replace(/[\\W,_]/g, '-').replace(/-{2,}/g, '-')
415
- }
416
-
417
- function svgName( name ) {
418
- #{if config[:namespace_before]
419
- %Q{return "#{config[:namespace]}-"+dasherize( name )}
420
- else
421
- %Q{return dasherize( name )+"-#{config[:namespace]}"}
422
- end}
423
- }
424
-
425
- function use( name, options ) {
426
- options = options || {}
427
- var id = dasherize( svgName( name ) )
428
- var symbol = svgs()[id]
429
-
430
- if ( symbol ) {
431
- var svg = document.createRange().createContextualFragment( '<svg><use xlink:href="#'+id+'"/></svg>' ).firstChild;
432
- svg.setAttribute( 'class', '#{config[:class]} '+id+' '+( options.classname || '' ).trim() )
433
- svg.setAttribute( 'viewBox', symbol.getAttribute( 'viewBox' ) )
434
-
435
- if ( !( options.width || options.height || options.scale ) ) {
436
-
437
- svg.setAttribute('width', symbol.getAttribute('width'))
438
- svg.setAttribute('height', symbol.getAttribute('height'))
439
-
440
- } else {
441
-
442
- if ( options.width ) svg.setAttribute( 'width', options.width )
443
- if ( options.height ) svg.setAttribute( 'height', options.height )
444
- }
445
-
446
- return svg
447
- } else {
448
- console.error('Cannot find "'+name+'" svg symbol. Ensure that svg scripts are loaded')
449
- }
450
- }
451
-
452
- function svgs(){
453
- if ( !names ) {
454
- names = {}
455
- for( var symbol of document.querySelectorAll( 'svg[id^=esvg] symbol' ) ) {
456
- names[symbol.getAttribute('name')] = symbol
457
- }
458
- }
459
- return names
460
- }
461
-
462
- var esvg = {
463
- svgs: svgs,
464
- use: use
465
- }
466
-
467
- // Handle Turbolinks page change events
468
- if ( window.Turbolinks ) {
469
- document.addEventListener( "turbolinks:load", function( event ) { names = null; esvg.svgs() })
470
- }
471
-
472
- if( typeof( module ) != 'undefined' ) { module.exports = esvg }
473
- else window.esvg = esvg
474
-
475
- })()}
476
- end
477
-
478
- private
479
-
480
- def file_key(path)
481
- dasherize sub_path(path).sub('.svg','')
482
- end
483
-
484
- def dir_key(path)
485
- dir = File.dirname(flatten_path(path))
486
-
487
- # Flattened paths which should be treated as assets will use '_' as their dir key
488
- # - flatten: _foo - _foo/icon.svg will have a dirkey of _
489
- # - filename: _icons - treats all root or flattened files as assets
490
- if dir == '.' && ( sub_path(path).start_with?('_') || config[:filename].start_with?('_') )
491
- '_'
492
- else
493
- dir
494
- end
495
- end
496
-
497
- def file_name(path)
498
- dasherize flatten_path(path).sub('.svg','')
499
- end
500
-
501
- def sub_path(path)
502
- path.sub("#{config[:source]}/",'')
503
- end
504
-
505
- def flatten_path(path)
506
- sub_path(path).sub(Regexp.new(config[:flatten]), '')
507
- end
508
-
509
- def file_keys(paths)
510
- paths.flatten.map { |p| file_key(p) }
511
- end
512
-
513
- def name_key(key)
514
- if key == '_' # Root level asset file
515
- "_#{config[:filename]}".sub(/_+/, '_')
516
- elsif key == '.' # Root level build file
517
- config[:filename]
518
- else
519
- "#{key}"
520
- end
521
- end
522
-
523
- def write_path(key)
524
- name = name_key(key)
525
-
526
- if name.start_with?('_') # Is it an asset?
527
- File.join config[:assets], "#{name}.js"
528
- else # or a build file?
529
-
530
- # User doesn't want a fingerprinted build file and hasn't set a version
531
- if !config[:fingerprint] && !config[:version]
532
- File.join config[:build], "#{name}.js"
533
- else
534
- File.join config[:build], "#{name}-#{version(key)}.js"
535
- end
536
- end
537
- end
538
-
539
- def svgo?
540
- !!(config[:optimize] && svgo_cmd)
541
- end
542
-
543
- def optimize(svg)
544
- svg[:optimized_content] = pre_optimize svg[:content]
545
- svg[:optimized_content] = sub_def_ids svg
546
-
547
- if svgo?
548
- response = Open3.capture3(%Q{#{} --disable=removeUselessDefs -s '#{svg[:content]}' -o -})
549
- svg[:optimized_content] = response[0] if response[2].success?
550
- end
551
-
552
- svg[:optimized_at] = Time.now.to_i
553
- svg[:optimized_content] = post_optimize svg
554
- end
555
-
556
- def pre_optimize(svg)
557
- reg = %w(xmlns xmlns:xlink xml:space version).map { |m| "#{m}=\".+?\"" }.join('|')
558
- svg.gsub(Regexp.new(reg), '') # Remove unwanted attributes
559
- .gsub(/<?.+\?>/,'').gsub(/<!.+?>/,'') # Get rid of doctypes and comments
560
- .gsub(/style="([^"]*?)fill:(.+?);/m, 'fill="\2" style="\1') # Make fill a property instead of a style
561
- .gsub(/style="([^"]*?)fill-opacity:(.+?);/m, 'fill-opacity="\2" style="\1') # Move fill-opacity a property instead of a style
562
- .gsub(/\n/, '') # Remove endlines
563
- .gsub(/\s{2,}/, ' ') # Remove whitespace
564
- .gsub(/>\s+</, '><') # Remove whitespace between tags
565
- .gsub(/\s?fill="(#0{3,6}|black|rgba?\(0,0,0\))"/,'') # Strip black fill
566
- end
567
-
568
- def post_optimize(svg)
569
- svg[:optimized_content] = set_attributes(svg)
570
- .gsub(/<\/svg/,'</symbol') # Replace svgs with symbols
571
- .gsub(/class="def-/,'id="def-') # Replace <def> classes with ids (classes are generated in sub_def_ids)
572
- .gsub(/\w+=""/,'') # Remove empty attributes
573
- end
574
-
575
- def set_attributes(svg)
576
- svg[:attr].keys.each { |key| svg[:optimized_content].sub!(/ #{key}=".+?"/,'') }
577
- svg[:optimized_content].sub(/<svg/, "<symbol #{attributes(svg[:attr])}")
578
- end
579
-
580
- def svgo_cmd
581
- find_node_module('svgo')
582
- end
583
-
584
- # Scans <def> blocks for IDs
585
- # If urls(#id) are used, ensure these IDs are unique to this file
586
- # Only replace IDs if urls exist to avoid replacing defs
587
- # used in other svg files
588
- #
589
- def sub_def_ids(svg)
590
- content = svg[:optimized_content]
591
- name = svg[:attr][:id]
592
-
593
- return content unless !!content.match(/<defs>/)
594
-
595
- content.scan(/<defs>.+<\/defs>/m).flatten.each do |defs|
596
- defs.scan(/id="(.+?)"/).flatten.uniq.each_with_index do |id, index|
597
-
598
- if content.match(/url\(##{id}\)/)
599
- new_id = "def-#{name}-#{index}"
600
-
601
- content = content.gsub(/id="#{id}"/, %Q{class="#{new_id}"})
602
- .gsub(/url\(##{id}\)/, "url(##{new_id})" )
46
+ # User doesn't want a fingerprinted build file and hasn't set a version
47
+ if !@config[:fingerprint] && !@config[:version]
48
+ File.join @config[:build], "#{name}.js"
603
49
  else
604
- content = content.gsub(/id="#{id}"/, %Q{class="#{id}"})
50
+ File.join @config[:build], "#{name}-#{@version}.js"
605
51
  end
606
52
  end
607
53
  end
608
-
609
- content
610
- end
611
-
612
- def compress(file)
613
- return if !config[:gzip]
614
-
615
- mtime = File.mtime(file)
616
- gz_file = "#{file}.gz"
617
-
618
- return if (File.exist?(gz_file) && File.mtime(gz_file) >= mtime)
619
-
620
- File.open(gz_file, "wb") do |dest|
621
- gz = ::Zlib::GzipWriter.new(dest, Zlib::BEST_COMPRESSION)
622
- gz.mtime = mtime.to_i
623
- IO.copy_stream(open(file), gz)
624
- gz.close
625
- end
626
-
627
- File.utime(mtime, mtime, gz_file)
628
-
629
- gz_file
630
- end
631
-
632
- def write_tmp(name, content)
633
- path = File.join(config[:temp], name)
634
- FileUtils.mkdir_p(File.dirname(path))
635
- write_file path, content
636
- path
637
- end
638
-
639
- def read_tmp(name)
640
- path = File.join(config[:temp], name)
641
- if File.exist? path
642
- File.read path
643
- else
644
- ''
645
- end
646
- end
647
-
648
- def log_path(path)
649
- File.expand_path(path).sub(config[:pwd], '').sub(/^\//,'')
650
- end
651
-
652
- def write_file(path, contents)
653
- FileUtils.mkdir_p(File.expand_path(File.dirname(path)))
654
- File.open(path, 'w') do |io|
655
- io.write(contents)
656
- end
657
- end
658
-
659
- def key_id(keys)
660
- keys.map do |key|
661
- (key == '.') ? 'symbols' : id(key)
662
- end.join('-')
663
- end
664
-
665
- # Determine if an NPM module is installed by checking paths with `npm bin`
666
- # Returns path to binary if installed
667
- def find_node_module(cmd)
668
- require 'open3'
669
-
670
- return @modules[cmd] unless @modules[cmd].nil?
671
-
672
- @modules[cmd] = begin
673
- local = "$(npm bin)/#{cmd}"
674
- global = "$(npm -g bin)/#{cmd}"
675
-
676
- if Open3.capture3(local)[2].success?
677
- local
678
- elsif Open3.capture3(global)[2].success?
679
- global
680
- else
681
- false
682
- end
683
- end
684
54
  end
685
55
 
686
- def symbolize_keys(hash)
687
- h = {}
688
- hash.each {|k,v| h[k.to_sym] = v }
689
- h
690
- end
56
+ private
691
57
 
692
- # Return non-empty key names for groups of svgs
693
- def valid_keys(keys)
694
- if keys.nil? || keys.empty?
695
- svg_symbols.keys
58
+ def name_key
59
+ if @name == '_' # Root level asset file
60
+ "_#{@config[:filename]}".sub(/_+/, '_')
61
+ elsif @name == '.' # Root level build file
62
+ @config[:filename]
696
63
  else
697
- keys = [keys].flatten.map { |k| dasherize k }
698
- svg_symbols.keys.select { |k| keys.include? dasherize(k) }
64
+ @name
699
65
  end
700
66
  end
701
67
 
702
- # Load aliases from configuration.
703
- # returns a hash of aliasees mapped to a name.
704
- # Converts configuration YAML:
705
- # alias:
706
- # foo: bar
707
- # baz: zip, zop
708
- # To output:
709
- # { :bar => "foo", :zip => "baz", :zop => "baz" }
710
- #
711
- def load_aliases(aliases)
712
- a = {}
713
- aliases.each do |name,alternates|
714
- alternates.split(',').each do |val|
715
- a[dasherize(val.strip).to_sym] = dasherize(name.to_s)
716
- end
717
- end
718
- a
68
+ def optimize
69
+ @symbols.map(&:optimize).join.gsub("\n",'')
719
70
  end
720
71
 
721
- def get_alias(name)
722
- config[:aliases][dasherize(name).to_sym] || name
72
+ def svg
73
+ attr = {
74
+ "data-symbol-class": @config[:class],
75
+ "data-prefix": @config[:prefix],
76
+ "version": "1.1",
77
+ "style": "height:0;position:absolute"
78
+ }
79
+ %Q{<svg id="esvg-#{id}" #{attributes(attr)}>#{optimize}</svg>}
723
80
  end
724
81
 
725
- def production?
726
- config[:produciton] || if Esvg.rails?
727
- Rails.env.production?
728
- end
729
- end
730
82
  end
731
83
  end