middleman-scavenger 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: c5f987b216ce954d071a8ead7860438bad4b07a0
4
+ data.tar.gz: 013256a957db369fde7469699762506ce7ec3140
5
+ SHA512:
6
+ metadata.gz: 90ec031a8f5aadec70917fc66d454f2719c738d60b8299f7914c608298922e698eaef36c97505115327681af8694c86ae8f7528bea01d1a683bfd1937e938683
7
+ data.tar.gz: 2d87d48755fcf3c078e36653c9c7447a43bfdea05843d63d983b1b52c33dbc08d16510cce0088a9eaf00cbdc3f23d5bf2128c8e2be0b55cc24ed4f105b0efa80
@@ -0,0 +1,5 @@
1
+ # Ignore bundler lock file
2
+ /Gemfile.lock
3
+
4
+ # Ignore pkg folder
5
+ /pkg
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
@@ -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)
@@ -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,4 @@
1
+ PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
2
+ require "middleman-core"
3
+ require "middleman-core/step_definitions"
4
+ require File.join(PROJECT_ROOT_PATH, "lib", "middleman-scavenger")
@@ -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: