svgeez 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0c36326d5848bbca6e2cad29119a27e1c20b8f31
4
- data.tar.gz: 8d2e00d295b978f00321b649c9e3032b15aa671b
3
+ metadata.gz: 4b5e6d929efa9fcb5c48283aada61cf024d4bdb7
4
+ data.tar.gz: 86611eebed02b5c8980743bdfe17b6eb044835a6
5
5
  SHA512:
6
- metadata.gz: 44b7acb9b4d0949341df569e959f680ba4f1fe1ca5989d2cd04c1022d354b77550b3be8dcf7f758a37a8e929d01a73f85fc2d49b40f01eb4ac25f7ee3229197b
7
- data.tar.gz: d9211e89a0a1314cf89281780d4ee7a2f02a061eeb2aae34071d670f86e6112f615b4f2f3039dcaf2f94f3f33c1ec9f7f9759184c94a104ffea9264b619c3dc3
6
+ metadata.gz: c626b106b2cf43412576b9592543092c43451158a1a041dc9f14e26c3e0be844fe4598a670282e6cffdb02899e6158618185b654957f5b9e1d19141439f43ecf
7
+ data.tar.gz: f910a1fc6b3a7d4d355f9aef5586826032c1e1f6c24839510cb6cb9b9cfdafeeb1b6e9dade04e365490280c54f149c747b18a3fc265eed2e61f21678d1dc96f3
@@ -1,8 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.2.6
4
- - 2.3.3
5
- - 2.4.0
4
+ - 2.3.4
5
+ - 2.4.1
6
6
  before_install:
7
7
  - npm install -g svgo
8
8
  notifications:
@@ -11,7 +11,7 @@ I definitely appreciate your interest in (and help improving) svgeez. Thanks!
11
11
 
12
12
  ## Installation
13
13
 
14
- svgeez is written in [Ruby](https://www.ruby-lang.org/en/) (version 2.2.6) and development dependencies are managed using the [Bundler](http://bundler.io/) gem. [Travis CI builds](https://travis-ci.org/jgarber623/svgeez) are done using Ruby 2.2.6, 2.3.3, and 2.4.0.
14
+ svgeez is written in [Ruby](https://www.ruby-lang.org/en/) (version 2.2.6) and development dependencies are managed using the [Bundler](http://bundler.io/) gem. [Travis CI builds](https://travis-ci.org/jgarber623/svgeez) use Ruby 2.2.6, 2.3.4, and 2.4.1.
15
15
 
16
16
  I manage Ruby versions with [rbenv](https://github.com/rbenv/rbenv). I'd recommend you do the same or use a similar Ruby version manager ([chruby](https://github.com/postmodern/chruby/) or [RVM](https://rvm.io/) come to mind). Once you've installed Ruby 2.2.6 using your method of choice, install the project's gems by running:
17
17
 
data/README.md CHANGED
@@ -2,26 +2,27 @@
2
2
 
3
3
  **A Ruby gem for automatically generating an SVG sprite from a folder of SVG icons.**
4
4
 
5
- [![Gem Version](https://badge.fury.io/rb/svgeez.svg)](https://badge.fury.io/rb/svgeez)
6
- [![Build Status](https://travis-ci.org/jgarber623/svgeez.svg?branch=master)](https://travis-ci.org/jgarber623/svgeez)
7
- [![Code Climate](https://codeclimate.com/github/jgarber623/svgeez/badges/gpa.svg)](https://codeclimate.com/github/jgarber623/svgeez)
8
- [![Test Coverage](https://codeclimate.com/github/jgarber623/svgeez/badges/coverage.svg)](https://codeclimate.com/github/jgarber623/svgeez/coverage)
5
+ [![Gem Version](https://img.shields.io/gem/v/svgeez.svg?label=gem%20version)](https://rubygems.org/gems/svgeez)
6
+ [![Downloads](https://img.shields.io/gem/dt/svgeez.svg)](https://rubygems.org/gems/svgeez)
7
+ [![Build Status](https://img.shields.io/travis/jgarber623/svgeez/master.svg?label=build%20status)](https://travis-ci.org/jgarber623/svgeez)
8
+ [![Code Climate](https://img.shields.io/codeclimate/github/jgarber623/svgeez.svg)](https://codeclimate.com/github/jgarber623/svgeez)
9
+ [![Coverage](https://img.shields.io/codeclimate/coverage/github/jgarber623/svgeez.svg)](https://codeclimate.com/github/jgarber623/svgeez/coverage)
9
10
 
10
- If you're using an [SVG](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) icon system in your Web projects, svgeez can help speed up your workflow by automating the SVG sprite generation process. Simply run svgeez alongside your existing project (or integrate it into your current build system); add, edit, or delete SVG files from a folder; and marvel as svgeez generates a single SVG sprite file ready for inclusion in your user interface.
11
+ If you're using an [SVG](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) icon system in your Web projects, svgeez can help speed up your workflow by automating the SVG sprite generation process. Run svgeez alongside your existing project (or integrate it into your current build system); add, edit, or delete SVG files from a folder; and marvel as svgeez generates a single SVG sprite file ready for inclusion in your user interface.
11
12
 
12
13
  _For more on why SVG sprites are the bee's knees as far as icon systems go, give Chris Coyier's original post, [Icon System with SVG Sprites](https://css-tricks.com/svg-sprites-use-better-icon-fonts/), and his follow-up article, [SVG \`symbol\` a Good Choice for Icons](https://css-tricks.com/svg-symbol-good-choice-icons/) a read-through._
13
14
 
14
15
  ## Key Features
15
16
 
16
- - Provides a simple [CLI](https://en.wikipedia.org/wiki/Command-line_interface) for generating SVG sprite files.
17
- - Easily integrates with existing projects (e.g. alongside a Rails application using [Foreman](https://github.com/ddollar/foreman)).
17
+ - Provides a [CLI](https://en.wikipedia.org/wiki/Command-line_interface) for generating SVG sprite files.
18
+ - Integrates with existing projects (e.g. alongside a Rails application using [Foreman](https://github.com/ddollar/foreman)).
18
19
  - Optionally optimizes SVG files with [SVGO](https://github.com/svg/svgo/).
19
20
 
20
21
  ## Getting Started
21
22
 
22
23
  Before installing and using svgeez, you'll want to have Ruby 2.2.6 (or newer) installed on your computer. There are plenty of ways to go about this, but my preference is [rbenv](https://github.com/sstephenson/rbenv). If you're developing on a Mac and using [Homebrew](http://brew.sh/), installing rbenv is [super easy](https://github.com/sstephenson/rbenv#homebrew-on-mac-os-x).
23
24
 
24
- svgeez _might_ work with other versions of Ruby, but it's developed in 2.2.6.
25
+ svgeez _might_ work with other versions of Ruby, but it's developed in 2.2.6 and automatically tested against 2.3.4 and 2.4.1 by [Travis CI](https://travis-ci.org/jgarber623/svgeez).
25
26
 
26
27
  ## Installation
27
28
 
@@ -77,7 +78,13 @@ Tweaking the example from above:
77
78
  $ svgeez watch --source ~/Sites/sixtwothree.org/images/icons --destination ~/Sites/sixtwothree.org/images/icons.svg
78
79
  ```
79
80
 
80
- svgeez will remaing running, watching for new, removed, or updated SVG files in the provided source folder. As SVG files are added, deleted, or modified in the source folder, svgeez will keep pumping out updated SVG sprite files to the destination folder.
81
+ svgeez will remaing running, watching for new, removed, or updated SVG files in the provided source folder. As SVG files are added, deleted, or modified in the source folder, svgeez will pump out updated SVG sprite files to the destination folder.
82
+
83
+ ### Preparing SVG files for svgeez
84
+
85
+ svgeez works best with well-organized SVG files. If you're using tools like Sketch or Adobe Illustrator, your source SVG files _may_ contain unnecessary cruft like comments and editor-specific attributes. svgeez will do its best to work with source SVG files, but as a general rule it's good practice to make sure that the SVG files exported from your editor are as concise as possible.
86
+
87
+ The first section of Jayden Seric's post, [How to optimize SVG](http://jaydenseric.com/blog/how-to-optimize-svg), offers some helpful advice on optimizing SVGs prior to exporting from editing software.
81
88
 
82
89
  ### Optimizing generated files with SVGO
83
90
 
@@ -218,6 +225,7 @@ svgeez is written and maintained by [Jason Garber](https://github.com/jgarber623
218
225
  - [Brett Wilkins](https://github.com/bwilkins)
219
226
  - [danny](https://github.com/f96q)
220
227
  - [Denis Hovart](https://github.com/dhovart)
228
+ - [Desmond Sadler](https://github.com/dezman)
221
229
 
222
230
  ## License
223
231
 
@@ -2,12 +2,20 @@ require 'fileutils'
2
2
  require 'listen'
3
3
  require 'logger'
4
4
  require 'mkmf'
5
+ require 'securerandom'
5
6
 
6
7
  require 'svgeez/version'
8
+
7
9
  require 'svgeez/command'
8
10
  require 'svgeez/commands/build'
9
11
  require 'svgeez/commands/watch'
10
- require 'svgeez/sprite_builder'
12
+
13
+ require 'svgeez/builder'
14
+ require 'svgeez/destination'
15
+ require 'svgeez/optimizer'
16
+ require 'svgeez/source'
17
+ require 'svgeez/svg_element'
18
+ require 'svgeez/symbol_element'
11
19
 
12
20
  module Svgeez
13
21
  def self.logger
@@ -0,0 +1,54 @@
1
+ module Svgeez
2
+ class Builder
3
+ SOURCE_IS_DESTINATION_MESSAGE = "Setting `source` and `destination` to the same path isn't allowed!".freeze
4
+ NO_SVGS_IN_SOURCE_MESSAGE = 'No SVGs were found in `source` folder.'.freeze
5
+
6
+ def initialize(options = {})
7
+ @options = options
8
+ end
9
+
10
+ # rubocop:disable Metrics/AbcSize
11
+ def build
12
+ return Svgeez.logger.error(SOURCE_IS_DESTINATION_MESSAGE) if source_is_destination?
13
+ return Svgeez.logger.warn(NO_SVGS_IN_SOURCE_MESSAGE) if source_is_empty?
14
+
15
+ Svgeez.logger.info "Generating sprite at `#{destination.file_path}` from #{source.file_paths.length} SVG#{'s' if source.file_paths.length > 1}..."
16
+
17
+ # Make destination folder
18
+ FileUtils.mkdir_p(destination.folder_path)
19
+
20
+ # Write the file
21
+ File.open(destination.file_path, 'w') do |f|
22
+ f.write destination_file_contents
23
+ end
24
+
25
+ Svgeez.logger.info "Successfully generated sprite at `#{destination.file_path}`."
26
+ end
27
+ # rubocop:enable Metrics/AbcSize
28
+
29
+ def destination
30
+ @destination ||= Destination.new(@options)
31
+ end
32
+
33
+ def source
34
+ @source ||= Source.new(@options)
35
+ end
36
+
37
+ private
38
+
39
+ def destination_file_contents
40
+ file_contents = SvgElement.new(source, destination).build
41
+ file_contents = Optimizer.new.optimize(file_contents) if @options['svgo']
42
+
43
+ file_contents.insert(4, ' style="display: none;"')
44
+ end
45
+
46
+ def source_is_destination?
47
+ /\A#{source.folder_path}/ =~ destination.folder_path
48
+ end
49
+
50
+ def source_is_empty?
51
+ source.file_paths.empty?
52
+ end
53
+ end
54
+ end
@@ -9,13 +9,13 @@ module Svgeez
9
9
  add_build_options(c)
10
10
 
11
11
  c.action do |_, options|
12
- Svgeez::Commands::Build.process(options)
12
+ Build.process(options)
13
13
  end
14
14
  end
15
15
  end
16
16
 
17
17
  def self.process(options)
18
- Svgeez::SpriteBuilder.new(options).build
18
+ Svgeez::Builder.new(options).build
19
19
  end
20
20
  end
21
21
  end
@@ -9,20 +9,20 @@ module Svgeez
9
9
  add_build_options(c)
10
10
 
11
11
  c.action do |_, options|
12
- Svgeez::Commands::Build.process(options)
13
- Svgeez::Commands::Watch.process(options)
12
+ Build.process(options)
13
+ Watch.process(options)
14
14
  end
15
15
  end
16
16
  end
17
17
 
18
18
  def self.process(options)
19
- sprite_builder = Svgeez::SpriteBuilder.new(options)
19
+ builder = Svgeez::Builder.new(options)
20
20
 
21
- listener = Listen.to(sprite_builder.source, only: /\.svg\z/) do
22
- sprite_builder.build
21
+ listener = Listen.to(builder.source.folder_path, only: /\.svg\z/) do
22
+ builder.build
23
23
  end
24
24
 
25
- Svgeez.logger.info "Watching `#{sprite_builder.source}` for changes... Press ctrl-c to stop."
25
+ Svgeez.logger.info "Watching `#{builder.source.folder_path}` for changes... Press ctrl-c to stop."
26
26
 
27
27
  listener.start
28
28
  sleep
@@ -0,0 +1,41 @@
1
+ module Svgeez
2
+ class Destination
3
+ DEFAULT_DESTINATION_FILE_NAME = 'svgeez.svg'.freeze
4
+
5
+ def initialize(options = {})
6
+ @options = options
7
+ end
8
+
9
+ def file_id
10
+ @file_id ||= File.basename(file_name, '.svg').tr(' ', '-')
11
+ end
12
+
13
+ def file_name
14
+ @file_name ||=
15
+ if destination.end_with?('.svg')
16
+ File.split(destination)[1]
17
+ else
18
+ DEFAULT_DESTINATION_FILE_NAME
19
+ end
20
+ end
21
+
22
+ def file_path
23
+ @file_path ||= File.join(folder_path, file_name)
24
+ end
25
+
26
+ def folder_path
27
+ @folder_path ||=
28
+ if destination.end_with?('.svg')
29
+ File.split(destination)[0]
30
+ else
31
+ destination
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def destination
38
+ @destination ||= File.expand_path(@options.fetch('destination', "./#{DEFAULT_DESTINATION_FILE_NAME}"))
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ module Svgeez
2
+ class Optimizer
3
+ SVGO_NOT_INSTALLED = 'Unable to find `svgo` in your PATH. Continuing with standard sprite generation...'.freeze
4
+
5
+ def optimize(file_contents)
6
+ return Svgeez.logger.warn(SVGO_NOT_INSTALLED) unless installed?
7
+
8
+ `cat <<EOF | svgo --disable=cleanupIDs -i - -o -\n#{file_contents}\nEOF`
9
+ end
10
+
11
+ private
12
+
13
+ def installed?
14
+ @installed ||= find_executable0('svgo')
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module Svgeez
2
+ class Source
3
+ DEFAULT_INPUT_FOLDER_PATH = './_svgeez'.freeze
4
+
5
+ def initialize(options = {})
6
+ @options = options
7
+ end
8
+
9
+ def file_paths
10
+ Dir.glob(file_paths_pattern)
11
+ end
12
+
13
+ def folder_path
14
+ @folder_path ||= File.expand_path(@options.fetch('source', DEFAULT_INPUT_FOLDER_PATH))
15
+ end
16
+
17
+ private
18
+
19
+ def file_paths_pattern
20
+ @file_paths_pattern ||= File.join(folder_path, '*.svg')
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ module Svgeez
2
+ class SvgElement
3
+ def initialize(source, destination)
4
+ @source = source
5
+ @destination = destination
6
+ end
7
+
8
+ def build
9
+ %(<svg id="#{@destination.file_id}" version="1.1" xmlns="http://www.w3.org/2000/svg">#{element_contents}</svg>)
10
+ end
11
+
12
+ private
13
+
14
+ def element_contents
15
+ @source.file_paths.map { |file_path| SymbolElement.new(file_path, @destination.file_id).build }.join
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ module Svgeez
2
+ class SymbolElement
3
+ def initialize(file_path, file_id)
4
+ @file_path = file_path
5
+ @file_id = file_id
6
+ end
7
+
8
+ def build
9
+ IO.read(@file_path).match(%r{^<svg\s*?(?<attributes>.*?)>(?<content>.*?)</svg>}m) do |matches|
10
+ %(<symbol #{element_attributes(matches[:attributes]).sort.join(' ')}>#{element_contents(matches[:content])}</symbol>)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def element_attributes(attributes)
17
+ attrs = attributes.scan(/(?:viewBox|xmlns:.+?)=".*?"/m)
18
+
19
+ attrs << %(id="#{@file_id}-#{File.basename(@file_path, '.svg').gsub(/['"\s]/, '-')}")
20
+ end
21
+
22
+ def element_contents(content)
23
+ content.scan(/\sid="(.+?)"/).flatten.each do |value|
24
+ content.gsub!(/\s(id|xlink:href)="(#?#{value})"/m, %( \\1="\\2-#{SecureRandom.uuid}"))
25
+ end
26
+
27
+ content
28
+ end
29
+ end
30
+ end
@@ -1,3 +1,3 @@
1
1
  module Svgeez
2
- VERSION = '1.0.2'.freeze
2
+ VERSION = '1.0.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: svgeez
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Garber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-26 00:00:00.000000000 Z
11
+ date: 2017-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -131,10 +131,15 @@ files:
131
131
  - Rakefile
132
132
  - bin/svgeez
133
133
  - lib/svgeez.rb
134
+ - lib/svgeez/builder.rb
134
135
  - lib/svgeez/command.rb
135
136
  - lib/svgeez/commands/build.rb
136
137
  - lib/svgeez/commands/watch.rb
137
- - lib/svgeez/sprite_builder.rb
138
+ - lib/svgeez/destination.rb
139
+ - lib/svgeez/optimizer.rb
140
+ - lib/svgeez/source.rb
141
+ - lib/svgeez/svg_element.rb
142
+ - lib/svgeez/symbol_element.rb
138
143
  - lib/svgeez/version.rb
139
144
  - svgeez.gemspec
140
145
  homepage: https://github.com/jgarber623/svgeez
@@ -1,101 +0,0 @@
1
- module Svgeez
2
- class SpriteBuilder
3
- DEFAULT_DESTINATION_FILE_NAME = 'svgeez.svg'.freeze
4
-
5
- def initialize(options = {})
6
- @options = options
7
- end
8
-
9
- def build
10
- if source_is_destination?
11
- Svgeez.logger.error "Setting `source` and `destination` to the same path isn't allowed!"
12
- elsif source_file_paths.empty?
13
- Svgeez.logger.warn "No SVGs were found in `#{source}`."
14
- else
15
- Svgeez.logger.info "Generating sprite at `#{destination_file_path}` from #{source_file_paths.length} SVG#{'s' if source_file_paths.length > 1}..."
16
-
17
- # Make destination folder
18
- FileUtils.mkdir_p(destination_folder_path)
19
-
20
- # Write the file
21
- File.open(destination_file_path, 'w') do |f|
22
- f.write build_destination_file_contents
23
- end
24
-
25
- Svgeez.logger.info "Successfully generated sprite at `#{destination_file_path}`."
26
- end
27
- end
28
-
29
- def destination
30
- @destination ||= File.expand_path(@options.fetch('destination', "./#{DEFAULT_DESTINATION_FILE_NAME}"))
31
- end
32
-
33
- def source
34
- @source ||= File.expand_path(@options.fetch('source', './_svgeez'))
35
- end
36
-
37
- private
38
-
39
- def build_destination_file_contents
40
- destination_file_contents = "<svg>#{collect_source_files_contents.join}</svg>"
41
-
42
- if svgo_use?
43
- if svgo_installed?
44
- destination_file_contents = `cat <<EOF | svgo --disable=cleanupIDs -i - -o -\n#{destination_file_contents}\nEOF`
45
- else
46
- Svgeez.logger.warn 'Unable to find `svgo` in your PATH. Continuing with standard sprite generation...'
47
- end
48
- end
49
-
50
- destination_file_contents.insert(4, %( id="#{destination_file_id}" style="display: none;" version="1.1" xmlns="http://www.w3.org/2000/svg"))
51
- end
52
-
53
- def collect_source_files_contents
54
- source_file_paths.collect do |file_path|
55
- IO.read(file_path).match(%r{^<svg.*?(?<viewbox>viewBox=".*?").*?>(?<content>.*?)</svg>}m) do |matches|
56
- %(<symbol id="#{destination_file_id}-#{File.basename(file_path, '.svg').gsub(/['"\s]/, '-')}" #{matches[:viewbox]}>#{matches[:content]}</symbol>)
57
- end
58
- end
59
- end
60
-
61
- def destination_file_id
62
- @destination_file_id ||= File.basename(destination_file_name, '.svg').tr(' ', '-')
63
- end
64
-
65
- def destination_file_name
66
- if destination.end_with?('.svg')
67
- File.split(destination)[1]
68
- else
69
- DEFAULT_DESTINATION_FILE_NAME
70
- end
71
- end
72
-
73
- def destination_file_path
74
- @destination_file_path ||= File.join(destination_folder_path, destination_file_name)
75
- end
76
-
77
- def destination_folder_path
78
- if destination.end_with?('.svg')
79
- File.split(destination)[0]
80
- else
81
- destination
82
- end
83
- end
84
-
85
- def source_file_paths
86
- @source_file_paths ||= Dir.glob(File.join(source, '*.svg'))
87
- end
88
-
89
- def source_is_destination?
90
- /\A#{source}/ =~ destination_folder_path
91
- end
92
-
93
- def svgo_use?
94
- @svgo_use ||= @options['svgo']
95
- end
96
-
97
- def svgo_installed?
98
- @svgo_installed ||= find_executable0('svgo')
99
- end
100
- end
101
- end