esvg 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5617c1952dc7fd76da427719eb2a7ddb5a8e7910
4
+ data.tar.gz: 7ab87e15d4af16d39aac5c53116e9f945719b09c
5
+ SHA512:
6
+ metadata.gz: f1fd6835394f4aad7832edf92997f79a89e2f3a2d9b4cf1f1aab4e2bad25ea088c5d4f8b93f35e250f2e447edd6fa3c0e649c6536149e58d72fa42df82ee283e
7
+ data.tar.gz: 94a0b8da7fc8e9314bcbecc1f0052f4dca9934214e8ea4a013400d73d24f44a03afdd300f6ff1d36ac6d013afd17a857355851bfcbd4de31534707b0937bc154
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ before_install: gem install bundler -v 1.10.3
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in esvg.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Brandon Mathis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,114 @@
1
+ # Esvg
2
+
3
+ Easily embed optimized SVGs in HTML or CSS. Use as a standalone tool or with Rails.
4
+
5
+ [![Gem Version](http://img.shields.io/gem/v/esvg.svg)](https://rubygems.org/gems/esvg)
6
+ [![License](http://img.shields.io/:license-mit-blue.svg)](http://imathis.mit-license.org)
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'esvg'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install esvg
23
+
24
+ ## Usage: Rails
25
+
26
+ Add SVG files to your `app/assets/svg_icons/` directory, then embed these SVGs in your application layout like this:
27
+
28
+ ```
29
+ <head>
30
+ ...
31
+ <%= embed_svgs %>
32
+ </head>
33
+ ```
34
+
35
+ To reference an SVG, use the `svg_icon` helper.
36
+
37
+ ```
38
+ # Syntax: svg_icon name, [options]
39
+
40
+ # Standard example
41
+ <%= svg_icon 'kitten' %>
42
+
43
+ # Output:
44
+ # <svg class="icon kitten-icon"><use xlink:href="#kitten-icon"/></svg>
45
+
46
+ # Add custom classnames
47
+ <%= svg_icon 'kitten', class: 'adorbs' %>
48
+
49
+ # Output:
50
+ # <svg class="icon kitten-icon adorbs"><use xlink:href="#kitten-icon"/></svg>
51
+
52
+ # Add title and desc tags for SVG accessibility.
53
+ <%= svg_icon 'kitten', title: "Mr. Snuggles", desc: "A graphic of a cat snuggling a ball of yarn" %>
54
+
55
+ # Output:
56
+ # <svg class="icon kitten-icon"><use xlink:href="#kitten-icon"/>
57
+ # <title>Mr. Snuggles</title>
58
+ # <desc>A graphic of a cat snuggling a ball of yarn</desc>
59
+ # </svg>
60
+ ```
61
+
62
+ ## Usage: stand-alone CLI
63
+
64
+ ```
65
+ # Syntax:
66
+ $ esvg PATH [options]
67
+
68
+ # Examples:
69
+ $ esvg # Read icons from current directory, write HTML to ./esvg.html
70
+ $ esvg icons --output embedded # Read icons from 'icons' directory, write HTML to embedded/esvg.html
71
+ $ esvg --stylesheet # Embed icons in Stylesheet and write to ./esvg.scss
72
+ $ esvg --config foo.yml # Read confguration from foo.yml
73
+ ```
74
+
75
+ ## Configuration: Rails
76
+
77
+ Esvg reads configuration from `config/esvg.yml` if used with Rails.
78
+
79
+ Options when used with Rails:
80
+
81
+ ```
82
+ path: app/assets/svg_icons # Where to find SVG icons
83
+ namespace: icon # Add to the filename when creating symbol ids
84
+ namespace_after: true # Add after the name, e.g. kitten-icon
85
+
86
+
87
+ stylesheet_embed: false # Embed as a stylesheet
88
+ font_size: 1em # Default size for SVGs (if embeded in stylesheets)
89
+ ```
90
+
91
+ ## Configuration: stand-alone CLI
92
+
93
+ If you're using esvg from the command line, configuration files are read from `./esvg.yml` or you can pass a path with the `--config` option to read the config file from elsewhere.
94
+
95
+ ```
96
+ path: . # Where to find SVG icons
97
+ namespace: icon # Add to the filename when creating symbol ids
98
+ namespace_after: true # Add after the name, e.g. kitten-icon
99
+
100
+
101
+ stylesheet_embed: false # Embed as a stylesheet
102
+ font_size: 1em # Default size for SVGs (if embeded in stylesheets)
103
+
104
+ output_path: . # Where to write output files
105
+ ```
106
+
107
+ ## Contributing
108
+
109
+ Bug reports and pull requests are welcome on GitHub at https://github.com/imathis/esvg. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
110
+
111
+ ## License
112
+
113
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
114
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "esvg"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'esvg/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "esvg"
8
+ spec.version = Esvg::VERSION
9
+ spec.authors = ["Brandon Mathis"]
10
+ spec.email = ["brandon@imathis.com"]
11
+
12
+ spec.summary = %q{Embed svgs in HTML or CSS}
13
+ spec.homepage = "https://github.com/imathis/esvg"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "svg_optimizer", "~> 0.0.2"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "pry-byebug"
26
+ end
@@ -0,0 +1,32 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
4
+
5
+ require 'optparse'
6
+ require 'esvg'
7
+
8
+ options = {}
9
+
10
+ OptionParser.new do |opts|
11
+ opts.on("-s", "--stylesheet", "Embed SVGs in Sass file") do
12
+ options[:stylesheet_embed] = true
13
+ end
14
+
15
+ opts.on("-c", "--config PATH", String, "Path to a config file (default: esvg.yml or config/esvg.yml)") do |path|
16
+ options[:config_file] = path
17
+ end
18
+
19
+ opts.on("-o", "--output PATH", String, "Where should SCSS/HTML files be written, (default: current directory)") do |path|
20
+ options[:output_path] = path
21
+ end
22
+ end.parse!
23
+
24
+ options[:path] = ARGV.shift
25
+
26
+ esvg = Esvg::SVG.new(options)
27
+
28
+ if options[:stylesheet_embed]
29
+ esvg.write_stylesheet
30
+ else
31
+ esvg.write_html
32
+ end
@@ -0,0 +1,51 @@
1
+ require "svg_optimizer"
2
+ require "fileutils"
3
+
4
+ require "esvg/version"
5
+ require "esvg/svg"
6
+
7
+ if defined?(Rails)
8
+ require "esvg/helpers"
9
+ require "esvg/railties"
10
+ end
11
+
12
+ module Esvg
13
+ extend self
14
+
15
+ def icons(options={})
16
+ @icons ||= SVG.new(options)
17
+
18
+ if rails? && ::Rails.env != 'production' && @icons.modified?
19
+ @icons.read_icons
20
+ end
21
+
22
+ @icons
23
+ end
24
+
25
+ def embed_svgs
26
+ icons.html.html_safe
27
+ end
28
+
29
+ def svg_icon(name, options={})
30
+ name = icons.icon_name(name)
31
+ %Q{<svg class="icon #{name} #{options[:class] || ""}"><use xlink:href="##{name}"/>#{title(options)}#{desc(options)}</svg>}.html_safe
32
+ end
33
+
34
+ def rails?
35
+ defined?(Rails)
36
+ end
37
+
38
+ private
39
+
40
+ def title(options)
41
+ if options[:title]
42
+ "<title>#{options[:title]}</title>"
43
+ end
44
+ end
45
+
46
+ def desc(options)
47
+ if options[:desc]
48
+ "<desc>#{options[:desc]}</desc>"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,9 @@
1
+ module Esvg::Helpers
2
+ def embed_svgs
3
+ Esvg.embed_svgs
4
+ end
5
+
6
+ def svg_icon(name, options={})
7
+ Esvg.svg_icon(name, options)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Esvg
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "my_gem.configure_view_controller" do |app|
4
+ ActiveSupport.on_load :action_view do
5
+ include Esvg::Helpers
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,168 @@
1
+ module Esvg
2
+ class SVG
3
+
4
+ attr_accessor :files
5
+
6
+ CONFIG = {
7
+ path: Dir.pwd,
8
+ namespace: 'icon',
9
+ namespace_after: true,
10
+ font_size: '1em',
11
+ stylesheet_embed: false,
12
+ output_path: Dir.pwd
13
+ }
14
+
15
+ CONFIG_RAILS = {
16
+ path: "app/assets/svg_icons",
17
+ css_path: "app/assets/stylesheets/_svg_icons.scss",
18
+ html_path: "app/views/shared/_svg_icons.html"
19
+ }
20
+
21
+ def initialize(options={})
22
+ config(options)
23
+
24
+ @mtime = File.mtime(config[:path])
25
+ read_icons
26
+ end
27
+
28
+ def modified?
29
+ @mtime != File.mtime(config[:path])
30
+ end
31
+
32
+ def read_icons
33
+ @files = {}
34
+
35
+ find_files.each do |f|
36
+ svg = File.read(f)
37
+ @files[File.basename(f, ".*")] = SvgOptimizer.optimize(svg)
38
+ end
39
+ end
40
+
41
+ def write_stylesheet
42
+ unless @files.empty?
43
+ FileUtils.mkdir_p(File.expand_path(File.dirname(config[:css_path])))
44
+
45
+ File.open(config[:css_path], 'w') do |io|
46
+ io.write(stylesheet)
47
+ end
48
+ end
49
+ end
50
+
51
+ def write_html
52
+ unless @files.empty?
53
+ FileUtils.mkdir_p(File.expand_path(File.dirname(config[:html_path])))
54
+
55
+ File.open(config[:html_path], 'w') do |io|
56
+ io.write(html)
57
+ end
58
+ end
59
+ end
60
+
61
+ def stylesheet
62
+ styles = []
63
+ preamble = %Q{%svg-icon {
64
+ clip: auto;
65
+ font-size: #{config[:font_size]};
66
+ background: {
67
+ size: auto 1em;
68
+ repeat: no-repeat;
69
+ position: center center;
70
+ }
71
+ display: inline-block;
72
+ overflow: hidden;
73
+ height: 1em;
74
+ width: 1em;
75
+ color: transparent;
76
+ vertical-align: middle;
77
+ }}
78
+ styles << preamble
79
+
80
+ files.each do |name, contents|
81
+ f = contents.gsub(/</, '%3C') # escape <
82
+ .gsub(/>/, '%3E') # escape >
83
+ .gsub(/#/, '%23') # escape #
84
+ .gsub(/\n/,'') # remove newlines
85
+ styles << ".#{icon_name(name)} { background-image: url('data:image/svg+xml;utf-8,#{f}'); @extend %svg-icon; }"
86
+ end
87
+ styles.join("\n")
88
+ end
89
+
90
+ def html
91
+ if @files.empty?
92
+ ''
93
+ else
94
+ svg = []
95
+ svg << %Q{<svg class="icon-symbols" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none">}
96
+ files.each do |name, contents|
97
+ svg << contents.gsub(/<svg.+?>/, %Q{<symbol id="#{icon_name(name)}" #{dimensions(contents)}>}) # convert svg to symbols
98
+ .gsub(/<\/svg/, '</symbol') # convert svg to symbols
99
+ .gsub(/style=['"].+?['"]/, '') # remove inline styles
100
+ .gsub(/\n/, '') # remove endlines
101
+ .gsub(/\s{2,}/, ' ') # remove whitespace
102
+ .gsub(/>\s+</, '><') # remove whitespace between tags
103
+ end
104
+ svg << %Q{</svg>}
105
+ svg.join("\n")
106
+ end
107
+ end
108
+
109
+ def config(options={})
110
+ @config ||= begin
111
+ paths = [options[:config_file], 'config/esvg.yml', 'esvg.yml'].compact
112
+
113
+ config = if path = paths.select{ |p| File.exist?(p)}.first
114
+ CONFIG.merge(symbolize_keys(YAML.load(File.read(path) || {}))).merge(options)
115
+ else
116
+ CONFIG.merge(options)
117
+ end
118
+
119
+ config.merge!(CONFIG_RAILS) if Esvg.rails?
120
+ config.merge(options)
121
+
122
+ config[:css_path] ||= File.join(config[:output_path], 'esvg.scss')
123
+ config[:html_path] ||= File.join(config[:output_path], 'esvg.html')
124
+ config.delete(:output_path)
125
+
126
+ config
127
+ end
128
+ end
129
+
130
+ def symbolize_keys(hash)
131
+ h = {}
132
+ hash.each {|k,v| h[k.to_sym] = v }
133
+ h
134
+ end
135
+
136
+ def dimensions(input)
137
+ dimensions = []
138
+ %w(viewBox).map do |dimension|
139
+ dimensions << input.scan(/<svg.+(#{dimension}=["'].+?["'])/).flatten.first
140
+ end
141
+ dimensions.compact.join(' ')
142
+ end
143
+
144
+ def icon_name(name)
145
+ if @files[name].nil?
146
+ raise "No icon named #{name} exists at #{config[:path]}"
147
+ end
148
+
149
+ name = dasherize(name)
150
+ if config[:namespace_after]
151
+ "#{name}-#{config[:namespace]}"
152
+ else
153
+ "#{config[:namespace]}-#{name}"
154
+ end
155
+ end
156
+
157
+ def dasherize(input)
158
+ input.gsub(/\W/, '-').gsub(/-{2,}/, '-')
159
+ end
160
+
161
+ def find_files
162
+ path = File.join(config[:path], '*.svg')
163
+
164
+ Dir[path].uniq
165
+ end
166
+
167
+ end
168
+ end
@@ -0,0 +1,3 @@
1
+ module Esvg
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: esvg
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Brandon Mathis
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-06-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: svg_optimizer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - brandon@imathis.com
72
+ executables:
73
+ - esvg
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".travis.yml"
79
+ - CODE_OF_CONDUCT.md
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - bin/console
85
+ - bin/setup
86
+ - esvg.gemspec
87
+ - exe/esvg
88
+ - lib/esvg.rb
89
+ - lib/esvg/helpers.rb
90
+ - lib/esvg/railties.rb
91
+ - lib/esvg/svg.rb
92
+ - lib/esvg/version.rb
93
+ homepage: https://github.com/imathis/esvg
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.4.7
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Embed svgs in HTML or CSS
117
+ test_files: []