middleman-scavenger 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +19 -0
- data/README.md +75 -0
- data/Rakefile +14 -0
- data/assets/javascripts/middleman-scavenger.js.erb +15 -0
- data/features/support/env.rb +4 -0
- data/lib/middleman-scavenger.rb +60 -0
- data/lib/middleman_extension.rb +1 -0
- data/lib/svg_processor.rb +45 -0
- data/middleman-scavenger.gemspec +25 -0
- metadata +85 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c5f987b216ce954d071a8ead7860438bad4b07a0
|
4
|
+
data.tar.gz: 013256a957db369fde7469699762506ce7ec3140
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 90ec031a8f5aadec70917fc66d454f2719c738d60b8299f7914c608298922e698eaef36c97505115327681af8694c86ae8f7528bea01d1a683bfd1937e938683
|
7
|
+
data.tar.gz: 2d87d48755fcf3c078e36653c9c7447a43bfdea05843d63d983b1b52c33dbc08d16510cce0088a9eaf00cbdc3f23d5bf2128c8e2be0b55cc24ed4f105b0efa80
|
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# If you do not have OpenSSL installed, update
|
2
|
+
# the following line to use "http://" instead
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
# Specify your gem's dependencies in middleman-scavenger.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem "rake"
|
10
|
+
gem "rdoc"
|
11
|
+
gem "yard"
|
12
|
+
end
|
13
|
+
|
14
|
+
group :test do
|
15
|
+
gem "cucumber"
|
16
|
+
gem "fivemat"
|
17
|
+
gem "aruba"
|
18
|
+
gem "rspec"
|
19
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Middleman-scavenger
|
2
|
+
|
3
|
+
A Middleman extension for creating svg sprite sheets. It's usable in modern (IE9+) browsers, uses `<symbol>` to include the svg:s, and can optionally inline the SVG images for speed. If you need legacy browser support it combines well with [svg4everybody](https://github.com/jonathantneal/svg4everybody).
|
4
|
+
|
5
|
+
|
6
|
+
## Installation and quick start
|
7
|
+
|
8
|
+
- Put the SVG:s you want to include in `source/images/svg`.
|
9
|
+
- Add `gem "middleman-scavenger"` to your gemfile and run `bundle install`
|
10
|
+
- Add `activate :middleman_scavenger` to your config.rb file
|
11
|
+
- Add `//= require middleman-scavenger` to your all.js file
|
12
|
+
|
13
|
+
Done! Now you can include your SVG images with the `svg` helper:
|
14
|
+
```ruby
|
15
|
+
<%= svg "my-image", class: "my-image-class" %>
|
16
|
+
```
|
17
|
+
|
18
|
+
|
19
|
+
## Configuration
|
20
|
+
|
21
|
+
If you don't like the default settings, you can change them at activation time. These are the three available configuration directives:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
activate :middleman_scavenger do |config|
|
25
|
+
config.path = "./source/my-svg-directory/"
|
26
|
+
config.prefix = "icon-"
|
27
|
+
config.sprite_path = "another-directory/my-sprite.svg"
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
- `path` sets the directory where Middleman-scavenger looks for SVG files. Every time an SVG is added, removed, or changed, Middleman-scavenger will rebuild a sprite sheet from all the files it finds there
|
32
|
+
- `prefix` sets an optional prefix for symbol ids. By default, when Middleman-scavenger finds an svg called `my-svg.svg` it will set the symbol id to the filename, so you can do `<%= svg "my-svg" %>`. If you prefer, you can set a prefix to use something like `<%= svg "icon-my-svg" %>` instead
|
33
|
+
- `sprite_path` will change the path and filename for the static file that Middleman-scavenger writes to disk.
|
34
|
+
|
35
|
+
## Helpers
|
36
|
+
|
37
|
+
### Displaying images from the sprite
|
38
|
+
|
39
|
+
Use `<%= svg "my-image" %>` to display an image from the sprite. Middleman-scavenger will insert an `svg` element for you that references an image inside the sprite sheet. You can append HTML attributes to that SVG element with an options hash, like this: `<%= svg "my-image", class: "my-image-class", width: 200, height: 100 %>`.
|
40
|
+
|
41
|
+
### Inlining
|
42
|
+
|
43
|
+
If you include the JS file, Middleman-scavenger will XHR load the sprite sheet and insert it into the DOM. If you prefer to inline the SVG document instead of loading it asynchronously, don't add the javascript file and use the `<%= inline_svg_sprite %>` helper instead. It will insert a hidden SVG, then you can use the `<%= svg %>` helper as usual.
|
44
|
+
|
45
|
+
|
46
|
+
### Sprite path
|
47
|
+
|
48
|
+
If you want to reference the sprite directly, you can use `scavenger_sprite_path`. It uses the built-in asset_path helper and is safe even when the `asset_hash` directive is activated.
|
49
|
+
|
50
|
+
|
51
|
+
## How it works
|
52
|
+
|
53
|
+
Middleman-scavenger uses an SVG processor based on [Nokogiri](http://www.nokogiri.org) to load and parse the SVG images in the folder into a sprite sheet, each image in its own `<symbol>` with its own viewBox. The sprite sheet is cached in memory and written to disk, so it can be asynchronously loaded or quickly inlined into the document. Whenever an SVG is added, removed, or changed in development mode Middleman-scavenger will make a new in-memory and on-disk version. The rebuild process fires at build time as well.
|
54
|
+
|
55
|
+
The bundled javascript will asynchronously load the SVG sprite sheet as text and insert it at the top of the body. This makes it possible to control the SVG sprites via CSS. An externally referenced SVG will create a shadow DOM boundary that is impossible to cross, but inserting the sprite sheet into the document removes that obstacle and makes for easy transitions and hover states.
|
56
|
+
|
57
|
+
|
58
|
+
## Gotchas
|
59
|
+
|
60
|
+
### Sizing
|
61
|
+
|
62
|
+
SVG sizing is always a little difficult, and even more so with sprite sheets. Middleman-scavenger uses [Nokogiri](http://www.nokogiri.org) to parse the SVG images and put them in `<symbol>` elements, so each image can have its own viewBox. That way, they will scale as expected when given width or height parameters. Including an SVG without sizing information will constrain it to the dimensions of the element it was included in, so it's advisable to add `width:` or `height:` or a styled CSS selector to the `svg` helper.
|
63
|
+
|
64
|
+
|
65
|
+
### FONI
|
66
|
+
|
67
|
+
Since default behavior is to asynchronously load the sprite sheet, you may experience a "flash of no images" while the script is fetching your SVGs. Depending on your application, this may or may not be acceptable. The solution is to inline the sprite as described under the "Inlining" section above, but beware - if you have a lot of SVG:s it will bloat the size of each page since the inlined sprite sheet won't be cached between pages.
|
68
|
+
|
69
|
+
|
70
|
+
## Who made this?
|
71
|
+
|
72
|
+
I'm [Johan Halse](https://www.twitter.com/hejsna) and I work at [Varvet](https://www.varvet.se). We do Ruby and Javascript and we're super friendly. You should totally hire us!
|
73
|
+
|
74
|
+
## License
|
75
|
+
[MIT](http://johanhalse.mit-license.org)
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'cucumber/rake/task'
|
5
|
+
|
6
|
+
Cucumber::Rake::Task.new(:cucumber, 'Run features that should pass') do |t|
|
7
|
+
t.cucumber_opts = "--color --tags ~@wip --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}"
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rake/clean'
|
11
|
+
|
12
|
+
task test: ['cucumber']
|
13
|
+
|
14
|
+
task default: :test
|
@@ -0,0 +1,15 @@
|
|
1
|
+
(function() {
|
2
|
+
function requestListener () {
|
3
|
+
document.body.insertAdjacentHTML('afterbegin', this.responseText);
|
4
|
+
document.body.children[0].style.display = 'none';
|
5
|
+
}
|
6
|
+
|
7
|
+
function requestSprite() {
|
8
|
+
var oReq = new XMLHttpRequest();
|
9
|
+
oReq.addEventListener('load', requestListener);
|
10
|
+
oReq.open('GET', '<%= image_path svg_sprite_path %>');
|
11
|
+
oReq.send();
|
12
|
+
}
|
13
|
+
|
14
|
+
requestSprite();
|
15
|
+
})();
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Require core library
|
2
|
+
require 'middleman-core'
|
3
|
+
|
4
|
+
# Extension namespace
|
5
|
+
class MiddlemanScavenger < ::Middleman::Extension
|
6
|
+
option :path, "./source/images/svg", "Directory containing SVG files"
|
7
|
+
option :prefix, "", "Optional prefix for icon names"
|
8
|
+
option :sprite_path, "sprite.svg", "Static file to write svg spritesheet to"
|
9
|
+
|
10
|
+
def initialize(app, options_hash={}, &block)
|
11
|
+
super
|
12
|
+
|
13
|
+
require "svg_processor"
|
14
|
+
|
15
|
+
processor_instance = SVGProcessor.new(options.path, options.prefix, options.sprite_path)
|
16
|
+
processor_instance.rebuild
|
17
|
+
app.set :svg_processor, processor_instance
|
18
|
+
app.set :svg_sprite_path, options.sprite_path
|
19
|
+
|
20
|
+
app.ready do
|
21
|
+
files.changed do |file|
|
22
|
+
if File.extname(file) == ".svg"
|
23
|
+
svg_processor.rebuild
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
files.deleted do |file|
|
28
|
+
if File.extname(file) == ".svg"
|
29
|
+
svg_processor.rebuild
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
helpers do
|
36
|
+
def scavenger_sprite_path
|
37
|
+
image_path svg_sprite_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def inline_svg_sprite
|
41
|
+
"<svg style=\"display:none;\">#{svg_processor.to_s}</svg>"
|
42
|
+
end
|
43
|
+
|
44
|
+
def svg(name, options=nil)
|
45
|
+
if defined?(options)
|
46
|
+
attrs = options.map {|k,v| "#{k}=\"#{v}\"" }.join(" ")
|
47
|
+
"<svg #{attrs}><use xlink:href=\"##{name}\" /></svg>"
|
48
|
+
else
|
49
|
+
"<svg><use xlink:href=\"##{name}\" /></svg>"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Register extensions which can be activated
|
56
|
+
# Make sure we have the version of Middleman we expect
|
57
|
+
# Name param may be omited, it will default to underscored
|
58
|
+
# version of class name
|
59
|
+
|
60
|
+
MiddlemanScavenger.register(:middleman_scavenger)
|
@@ -0,0 +1 @@
|
|
1
|
+
require "middleman-scavenger"
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class SVGProcessor
|
2
|
+
require "nokogiri"
|
3
|
+
|
4
|
+
def initialize(path, prefix, sprite_path)
|
5
|
+
@path = path
|
6
|
+
@prefix = prefix
|
7
|
+
@sprite_path = sprite_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def rebuild
|
11
|
+
@svgs = Dir["#{@path}/*"].map { |file| get_svg(file) }
|
12
|
+
puts "rebuilding: #{@svgs.length} svgs found"
|
13
|
+
@symbols = @svgs.map { |svg| convert_to_symbol(svg) }
|
14
|
+
|
15
|
+
@symbol_string = @symbols.join("\n")
|
16
|
+
|
17
|
+
if @sprite_path != nil
|
18
|
+
File.write("./source/images/#{@sprite_path}", "<svg xmlns=\"http://www.w3.org/2000/svg\">#{@symbol_string}</svg>")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
@symbol_string
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def get_svg(file)
|
29
|
+
f = File.open(file)
|
30
|
+
doc = Nokogiri::XML(f)
|
31
|
+
f.close
|
32
|
+
|
33
|
+
{
|
34
|
+
filename: File.basename(file, ".svg"),
|
35
|
+
xml: doc
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def convert_to_symbol(svg)
|
40
|
+
svg[:xml].xpath('//@id').remove
|
41
|
+
g = svg[:xml].at_css("g")
|
42
|
+
viewbox_size = svg[:xml].xpath("//@viewBox").first.value
|
43
|
+
"<symbol viewBox=\"#{viewbox_size}\" id=\"#{@prefix}#{svg[:filename]}\">#{g.to_s}</symbol>"
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "middleman-scavenger"
|
6
|
+
s.version = "1.0.0"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Johan Halse"]
|
9
|
+
s.email = ["johan.halse@varvet.com"]
|
10
|
+
s.license = "MIT"
|
11
|
+
s.homepage = "https://github.com/varvet/middleman-scavenger"
|
12
|
+
s.summary = %q{A middleman extension for automatically creating SVG sprite sheets}
|
13
|
+
s.description = %q{Discovers and compiles SVG files into a sprite sheet that can be used for icons and such.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
# The version of middleman-core your extension depends on
|
21
|
+
s.add_runtime_dependency("middleman-core", [">= 3.3.12"])
|
22
|
+
|
23
|
+
# Additional dependencies
|
24
|
+
s.add_runtime_dependency("nokogiri", "~> 1.6")
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: middleman-scavenger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Johan Halse
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: middleman-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.3.12
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.3.12
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: nokogiri
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
description: Discovers and compiles SVG files into a sprite sheet that can be used
|
42
|
+
for icons and such.
|
43
|
+
email:
|
44
|
+
- johan.halse@varvet.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- Gemfile
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- assets/javascripts/middleman-scavenger.js.erb
|
54
|
+
- features/support/env.rb
|
55
|
+
- lib/middleman-scavenger.rb
|
56
|
+
- lib/middleman_extension.rb
|
57
|
+
- lib/svg_processor.rb
|
58
|
+
- middleman-scavenger.gemspec
|
59
|
+
homepage: https://github.com/varvet/middleman-scavenger
|
60
|
+
licenses:
|
61
|
+
- MIT
|
62
|
+
metadata: {}
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 2.4.5
|
80
|
+
signing_key:
|
81
|
+
specification_version: 4
|
82
|
+
summary: A middleman extension for automatically creating SVG sprite sheets
|
83
|
+
test_files:
|
84
|
+
- features/support/env.rb
|
85
|
+
has_rdoc:
|