sprite-generator 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [Richard Huang (flyerhzm@gmail.com)]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # sprite-generator #
2
+
3
+ `sprite-generator` is a gem that helps generate css sprite images automagically. It's aim is to support all web frameworks (Merb/Rails/Sinatra), and have extensible output generator. By default, it supports CSS and SASS output (via mixins).
4
+
5
+ ## INSTALL ##
6
+
7
+ ### Install the `rmagick` gem ###
8
+
9
+ `sprite-generator` currently requires the rmagick gem. to install it, use
10
+
11
+ gem install rmagick
12
+
13
+ ### Install the `sprite-generator` gem ###
14
+
15
+ Install the `sprite-generator` gem from gemcutter
16
+
17
+ gem sources -a http://gemcutter.org
18
+ gem install sprite-generator
19
+
20
+ ## USAGE ##
21
+
22
+ if installed as a gem, at your root project folder you can just run
23
+
24
+ sprite
25
+
26
+ ### Intelligent Defaults ###
27
+
28
+ Without having to configure anything, `sprite-generator` will allow you to easily generate sprites based on a couple default folder settings we give you right off the bat.
29
+
30
+ For example, given you have the following setup:
31
+
32
+ public/
33
+ images/
34
+ sprites/
35
+ black-icons/
36
+ stop.png
37
+ go.png
38
+ back.png
39
+ forward.png
40
+
41
+ weather/
42
+ sunny.gif
43
+ rainy.gif
44
+ cloudy.gif
45
+
46
+ Running `sprite-generator` with no configuration file will generate the following new files:
47
+
48
+ public/
49
+ stylesheets/
50
+ sprites.css
51
+ images/
52
+ sprites/
53
+ black-icons.png
54
+ weather.png
55
+
56
+ Any folders within `public/images/sprites/` will get compressed into a merged image file at the same
57
+ location. Then `sprites.css` will get generated in the stylesheets folder with all the class definitions for
58
+ these files. Just add a link to `sprites.css` into your html <head> and you're ready to go!
59
+
60
+
61
+ ## CONFIGURATION ##
62
+
63
+ Configuration of `sprite-generator` is done via `config/sprite.yml`. It allows you to set sprite configuration options, and fine tune exactly which sprites get generated where.
64
+
65
+ * `config:` section defines all the global properties for sprite generation. Such as how it generates the styles, where it looks for images, where it writes it output file to, and what image file format it uses by default
66
+ - `style:` defines how the style rules are outputted. built in options are `css`, `sass`, and `sass_mixin`. (defaults to `css`)
67
+ - `style_output_path:` defines the file path where your style settings get written (defaults to `stylesheets/sprites`). the file extension not needed as it will be set based on the `style:` setting
68
+ - `image_output_path:` defines the folder path where the combined sprite images files are written (defaults to `images/sprites/`)
69
+ - `image_source_path:` defines the folder where source image files are read from (defaults to `images/`)
70
+ - `public_path:` defines the root folder where static assets live (defaults to `public/`)
71
+ - `sprites_class:` defines the class name that gets added to all sprite stylesheet rules (defaults to `sprites`)
72
+ - `default_format:` defines the default file image format of the generated files. (defaults to `png`)
73
+ - `default_spacing:` defines the default pixel spacing between sprites (defaults to 0)
74
+ - `class_separator:` used to generated the class name by separating the image name and sprite name (defaults to `-`)
75
+
76
+ * `images:` section provides an array of configurations which define which image files are built, and where they get their sprites from. each image setup provides the following config options:
77
+ - `name:` name of image (required)
78
+ - `sources:` defines a list of source image filenames to build the target image from (required). They are parsed by <code>Dir.glob</code>
79
+ - `align:` defines the composite gravity type, horizontal or vertical. (defaults to `vertical`)
80
+ - `spaced_by:` spacing (in pixels) between the combined images. (defaults to `0`)
81
+ - `format:` define what image file format gets created (optional, uses `default_format` setting if not set)
82
+
83
+ All image and style paths should be set relative to the public folder (which is configurable via public_path setting).
84
+
85
+ ### Sample Configuration `config/sprite.yml` ###
86
+
87
+ # defines the base configuration options (file paths, etc, default style, etc)
88
+
89
+ config:
90
+ style: css
91
+ style_output_path: stylesheets/sprites
92
+ image_output_path: images/sprites/
93
+ image_source_path: images/
94
+ public_path: public/
95
+ sprites_class: 'sprites'
96
+ class_separator: '-'
97
+ default_format: png
98
+ default_spacing: 50
99
+
100
+ # defines what sprite collections get created
101
+ images:
102
+
103
+ # creates a public/images/sprites/blue_stars.png image with 4 sprites in it
104
+ - name: blue_stars
105
+ format: png
106
+ align: horizontal
107
+ spaced_by: 50
108
+ sources:
109
+ - icons/blue-stars/small.png
110
+ - icons/blue-stars/medium.png
111
+ - icons/blue-stars/large.png
112
+ - icons/blue-stars/xlarge.png
113
+
114
+ # creates a public/images/sprites/green-stars.jpg image with
115
+ # all the gif files contained within /images/icons/green-stars/
116
+ - name: green_stars
117
+ format: png
118
+ align: vertical
119
+ spaced_by: 50
120
+ sources:
121
+ - icons/green-stars/*.gif
122
+
123
+ ### Style Settings ###
124
+
125
+ By default, it will use with `style: css` and generate the file at `public/stylesheets/sprites.css`
126
+
127
+ .sprites.blue-stars-small {
128
+ background: url('/images/icons/blue-stars/small.png') no-repeat 0px 0px;
129
+ width: 12px;
130
+ height: 6px;
131
+ }
132
+ .sprites.blue-stars-medium {
133
+ background: url('/images/icons/blue-stars/medium.png') no-repeat 0px 6px;
134
+ width: 30px;
135
+ height: 15px;
136
+ }
137
+ .sprites.blue-stars-large {
138
+ background: url('/images/icons/blue-stars/large.png') no-repeat 0px 21px;
139
+ width: 60px;
140
+ height: 30px;
141
+ }
142
+ .sprites.blue-stars-xlarge {
143
+ background: url('/images/icons/blue-stars/xlarge.png') no-repeat 0px 96px;
144
+ width: 100px;
145
+ height: 75px;
146
+ }
147
+
148
+ We also support mixin syntax via `style: sass_mixin`. If set, it will generate a SASS mixin which you can use in order to mix in these sprites anywhere within your SASS stylesheets. For this option, set `style_output_path:` to `stylesheets/sass/_sprites` in order to generate the sass mixin file at `stylesheets/sass/_sprites.sass`
149
+
150
+ @import "sass/mixins/sprites.sass"
151
+
152
+ // you can then use your sprite like this
153
+ .largebluestar
154
+ +sprite("blue-stars", "large")
155
+
156
+ .mysmallbluestar
157
+ +sprite("blue-stars", "small")
158
+
159
+ Additional style generators are very easy to add. We have one for `style: sass` and `style: sass_ext`. The `sass_ext` style is a work in progress, as it's attempting to write the sprite data to yml and use a dynamic sass extension to provide the mixin. Eventually, if it works, this will be the default for `sass_mixin`
160
+
161
+ ## Framework Integration?? ##
162
+
163
+ `sprite` is provided as a command line helper. Deep web framework integration is not implemented at this time, however it shouldn't be needed. Just generate your sprites on your dev machine by running the command line, check in the resulting sprite images and stylesheets to your source control, and deploy!
164
+
165
+ You can also easily script it out via capistrano. You could also run `sprite` on application start, or just about anywhere. Let me know what limitations you run into.
166
+
167
+ ## ABOUT `sprite` ##
168
+
169
+ `sprite-generator` is based on `sprite` gem by Jacques Crocker: [sprite](http://github.com/merbjedi/sprite)
170
+
171
+ `sprite` was originally based off of Richard Huang's excellent Rails plugin: [css_sprite](http://github.com/flyerhzm/css_sprite)
172
+
173
+ Since then it's been rebuilt (with some reuse of the image generation code) to be a general purpose ruby executable, with hooks for merb/rails/sinatra
174
+
175
+
176
+ ## LICENSE ##
177
+
178
+ Released under the MIT License
179
+
180
+ ## COPYRIGHT ##
181
+
182
+ Copyright (c) 2009 Gist
183
+
184
+ Original Codebase Copyright (c) 2009 [Richard Huang]
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+ require 'jeweler'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :spec
7
+
8
+ desc "Run all specs in spec directory"
9
+ Spec::Rake::SpecTask.new(:spec) do |t|
10
+ t.spec_files = FileList['spec/**/*_spec.rb']
11
+ end
12
+
13
+ Jeweler::Tasks.new do |gemspec|
14
+ gemspec.name = "sprite"
15
+ gemspec.summary = "generate your css sprites automagically"
16
+ gemspec.description = "sprite is a rails/merb plugin that generates sprites for css, sass"
17
+ gemspec.email = "merbjedi@gmail.com"
18
+ gemspec.homepage = "http://github.com/merbjedi/sprite"
19
+ gemspec.authors = ["Jacques Crocker"]
20
+ gemspec.files.exclude '.gitignore'
21
+
22
+ # removing test files and specs from the gem to save space
23
+ gemspec.files -= Dir.glob("spec/**/*")
24
+ gemspec.test_files = []
25
+ end
26
+ Jeweler::GemcutterTasks.new
27
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.6
data/bin/sprite ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # The compass command line utility
3
+
4
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'sprite'))
5
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'sprite', 'runner'))
6
+
7
+ command = Sprite::Runner.new(ARGV)
8
+ exit command.run!
data/lib/sprite.rb ADDED
@@ -0,0 +1,23 @@
1
+ module Sprite
2
+
3
+ # provides the root directory to use when reading and writing files
4
+ def self.root
5
+ @root ||= nil
6
+
7
+ # set the root to the framework setting (if not already set)
8
+ @root ||= begin
9
+ if defined?(Rails)
10
+ Rails.root
11
+ elsif defined?(Merb)
12
+ Merb.root
13
+ else
14
+ "."
15
+ end
16
+ end
17
+ @root
18
+ end
19
+ end
20
+
21
+ require 'sprite/builder'
22
+ require 'sprite/image_combiner'
23
+ require 'sprite/styles'
@@ -0,0 +1,198 @@
1
+ require 'fileutils'
2
+ module Sprite
3
+ class Builder
4
+ DEFAULT_CONFIG_PATH = 'config/sprite.yml'
5
+
6
+ attr_reader :config
7
+ attr_reader :images
8
+
9
+ def self.from_config(path = nil)
10
+ results = {}
11
+ config_path = File.join(Sprite.root, path || DEFAULT_CONFIG_PATH)
12
+
13
+ # read configuration
14
+ if File.exists?(config_path)
15
+ begin
16
+ results = File.open(config_path) {|f| YAML::load(f)} || {}
17
+ rescue => e
18
+ puts "Error reading sprite config: #{config_path}"
19
+ puts e.to_s
20
+ end
21
+ end
22
+
23
+ new(results["config"], results["images"])
24
+ end
25
+
26
+ def initialize(config = nil, images = nil)
27
+ @config = config || {}
28
+ set_config_defaults
29
+
30
+ @images = images || []
31
+ set_image_defaults
32
+ expand_image_paths
33
+
34
+ # initialize sprite files
35
+ @sprite_files = {}
36
+ end
37
+
38
+ def build
39
+ @sprite_files = {}
40
+
41
+ if images.size > 0
42
+ # create images
43
+ images.each do |image|
44
+ write_image(image)
45
+ end
46
+
47
+ if @sprite_files.values.length > 0
48
+ # write css
49
+ write_styles
50
+ end
51
+ end
52
+ end
53
+
54
+ protected
55
+ def write_image(image)
56
+ results = []
57
+ sources = image['sources'].to_a
58
+ return unless sources.length > 0
59
+
60
+ name = image['name']
61
+ format = image['format'] || config["default_format"]
62
+ spaced_by = image['spaced_by'] || config["default_spacing"] || 0
63
+
64
+ combiner = ImageCombiner.new
65
+
66
+ dest_image = combiner.get_image(sources.shift)
67
+ results << combiner.image_properties(dest_image).merge(:x => 0, :y => 0, :group => name)
68
+ sources.each do |source|
69
+ source_image = combiner.get_image(source)
70
+ if image['align'].to_s == 'horizontal'
71
+ x = dest_image.columns + spaced_by
72
+ y = 0
73
+ align = "horizontal"
74
+ else
75
+ x = 0
76
+ y = dest_image.rows + spaced_by
77
+ align = "vertical"
78
+ end
79
+ results << combiner.image_properties(source_image).merge(:x => -x, :y => -y, :group => name, :align => align)
80
+ dest_image = combiner.composite_images(dest_image, source_image, x, y)
81
+ end
82
+
83
+ # set up path
84
+ path = image_output_path(name, format)
85
+ FileUtils.mkdir_p(File.dirname(path))
86
+
87
+ # write sprite image file to disk
88
+ dest_image.write(path)
89
+ @sprite_files["#{name}.#{format}"] = results
90
+ end
91
+
92
+ def write_styles
93
+ style = Styles.get(config["style"]).new(self)
94
+
95
+ # use the absolute style output path to make sure we have the directory set up
96
+ path = style_output_path(style.extension, false)
97
+ FileUtils.mkdir_p(File.dirname(path))
98
+
99
+ # send the style the relative path
100
+ style.write(style_output_path(style.extension, true), @sprite_files)
101
+ end
102
+
103
+ # sets all the default values on the config
104
+ def set_config_defaults
105
+ @config['style'] ||= 'css'
106
+ @config['style_output_path'] ||= 'stylesheets/sprites'
107
+ @config['image_output_path'] ||= 'images/sprites/'
108
+ @config['image_source_path'] ||= 'images/'
109
+ @config['public_path'] ||= 'public/'
110
+ @config['default_format'] ||= 'png'
111
+ @config['class_separator'] ||= '-'
112
+ @config["sprites_class"] ||= 'sprites'
113
+ @config["default_spacing"] ||= 0
114
+ end
115
+
116
+ # if no image configs are detected, set some intelligent defaults
117
+ def set_image_defaults
118
+ return unless @images.size == 0
119
+
120
+ sprites_path = image_source_path("sprites")
121
+
122
+ if File.exists?(sprites_path)
123
+ Dir.glob(File.join(sprites_path, "*")) do |dir|
124
+ next unless File.directory?(dir)
125
+ source_name = File.basename(dir)
126
+
127
+ # default to finding all png, gif, jpg, and jpegs within the directory
128
+ images << {
129
+ "name" => source_name,
130
+ "sources" => [
131
+ File.join("sprites", source_name, "*.png"),
132
+ File.join("sprites", source_name, "*.gif"),
133
+ File.join("sprites", source_name, "*.jpg"),
134
+ File.join("sprites", source_name, "*.jpeg"),
135
+ ]
136
+ }
137
+ end
138
+ end
139
+ end
140
+
141
+ # expands out sources, taking the Glob paths and turning them into separate entries in the array
142
+ def expand_image_paths
143
+ # cycle through image sources and expand out globs
144
+ @images.each do |image|
145
+ # expand out all the globs
146
+ image['sources'] = image['sources'].to_a.map{ |source|
147
+ Dir.glob(image_source_path(source))
148
+ }.flatten.compact
149
+ end
150
+ end
151
+
152
+ # get the disk path for the style output file
153
+ def style_output_path(file_ext, relative = false)
154
+ path = config['style_output_path']
155
+ unless path.include?(".#{file_ext}")
156
+ path = "#{path}.#{file_ext}"
157
+ end
158
+ public_path(path, relative)
159
+ end
160
+
161
+ # get the disk path for a location within the image output folder
162
+ def image_output_path(name, format, relative = false)
163
+ path_parts = []
164
+ path_parts << chop_trailing_slash(config['image_output_path']) if path_present?(config['image_output_path'])
165
+ path_parts << "#{name}.#{format}"
166
+ public_path(File.join(*path_parts), relative)
167
+ end
168
+
169
+ # get the disk path for an image source file
170
+ def image_source_path(location, relative = false)
171
+ path_parts = []
172
+ path_parts << chop_trailing_slash(config["image_source_path"]) if path_present?(config['image_source_path'])
173
+ path_parts << location
174
+ public_path(File.join(*path_parts), relative)
175
+ end
176
+
177
+ # get the disk path for a location within the public folder (if set)
178
+ def public_path(location, relative = false)
179
+ path_parts = []
180
+ path_parts << Sprite.root unless relative
181
+ path_parts << chop_trailing_slash(config['public_path']) if path_present?(config['public_path'])
182
+ path_parts << location
183
+
184
+ File.join(*path_parts)
185
+ end
186
+
187
+ # chop off the trailing slash on a directory path (if it exists)
188
+ def chop_trailing_slash(path)
189
+ path = path[0...-1] if path[-1] == File::SEPARATOR
190
+ path
191
+ end
192
+
193
+ # check if the path is set
194
+ def path_present?(path)
195
+ path.to_s.strip != ""
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,33 @@
1
+ module Sprite
2
+ class ImageCombiner
3
+ def initialize
4
+ # avoid loading rmagick till the last possible moment
5
+ require 'RMagick'
6
+ end
7
+
8
+ def composite_images(dest_image, src_image, x, y)
9
+ width = [src_image.columns + x, dest_image.columns].max
10
+ height = [src_image.rows + y, dest_image.rows].max
11
+ image = Magick::Image.new(width, height)
12
+ image.opacity = Magick::MaxRGB
13
+
14
+ image.composite!(dest_image, 0, 0, Magick::OverCompositeOp)
15
+ image.composite!(src_image, x, y, Magick::OverCompositeOp)
16
+ image
17
+ end
18
+
19
+ # Image Utility Methods
20
+ def get_image(image_filename)
21
+ image = Magick::Image::read(image_filename).first
22
+ end
23
+
24
+ def image_properties(image)
25
+ {:name => File.basename(image.filename).split('.')[0], :width => image.columns, :height => image.rows}
26
+ end
27
+
28
+ # REMOVE RMAGICK AND USE IMAGEMAGICK FROM THE COMMAND LINE
29
+ # identify => find properties for an image
30
+ # composite => combine 2 images
31
+
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ module Sprite
2
+ class Runner
3
+
4
+ attr_accessor :options
5
+ def initialize(args)
6
+ self.options = set_options(args)
7
+ end
8
+
9
+ def set_options(args)
10
+ opts = {}
11
+ # TODO
12
+ # edit options with passed in args
13
+ opts
14
+ end
15
+
16
+ # run sprite creator
17
+ def run!
18
+ begin
19
+ Sprite::Builder.from_config(options[:path]).build
20
+ # rescue Exception => e
21
+ # # catch errors
22
+ # puts "ERROR"
23
+ # puts e
24
+ # return 1
25
+ end
26
+ 0
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,57 @@
1
+ module Sprite::Sass::Extensions
2
+ def sprite_background(group, image)
3
+ sprite = sprite_data(group, image)
4
+ if sprite
5
+ "url('#{sprite[:img]}') no-repeat #{sprite[:x]}px #{sprite[:y]}px"
6
+ else
7
+ ""
8
+ end
9
+ end
10
+
11
+ def sprite_width(group, image)
12
+ sprite = sprite_data(group, image)
13
+ if sprite
14
+ "#{sprite[:width]}px"
15
+ else
16
+ ""
17
+ end
18
+ end
19
+
20
+ def sprite_height(group, image)
21
+ sprite = sprite_data(group, image)
22
+ if sprite
23
+ "#{sprite[:height]}px"
24
+ else
25
+ ""
26
+ end
27
+ end
28
+
29
+ protected
30
+ def sprite_data(group, image)
31
+ unless @__sprite_data
32
+
33
+ # TODO: read template from !sprite_data
34
+ sprite_data_path = "public/sass/sprites.yml"
35
+
36
+ # figure out the site root
37
+ root = "./"
38
+
39
+ # read sprite data from yml
40
+ @__sprite_data = File.open(File.join(root, sprite_data_path)) { |yf| YAML::load( yf ) }
41
+ end
42
+
43
+ group_data = @__sprite_data[group.to_s]
44
+ if group_data
45
+ return group_data[image.to_s]
46
+ else
47
+ nil
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ if defined?(Sass)
54
+ module Sass::Script::Functions
55
+ include Sprite::Sass::Extensions
56
+ end
57
+ end
@@ -0,0 +1,20 @@
1
+ require 'sprite/styles/sass_generator'
2
+ require 'sprite/styles/css_generator'
3
+ require 'sprite/styles/sass_yml_generator'
4
+ require 'sprite/styles/sass_mixin_generator'
5
+
6
+ module Sprite::Styles
7
+ GENERATORS = {
8
+ "css" => "CssGenerator",
9
+ "sass" => "SassGenerator",
10
+ "sass_mixin" => "SassMixinGenerator",
11
+ "sass_yml" => "SassYmlGenerator"
12
+ }
13
+
14
+ def self.get(config)
15
+ const_get(GENERATORS[config])
16
+ rescue
17
+ CssGenerator
18
+ end
19
+
20
+ end
@@ -0,0 +1,33 @@
1
+ module Sprite
2
+ module Styles
3
+ # renders standard css style rules
4
+ class CssGenerator
5
+ def initialize(builder)
6
+ @builder = builder
7
+ end
8
+
9
+ def write(path, sprite_files)
10
+ # set up class_name to append to each rule
11
+ sprites_class = @builder.config['sprites_class'] ? ".#{@builder.config['sprites_class']}" : ""
12
+
13
+ # write styles to disk
14
+ File.open(File.join(Sprite.root, path), 'w') do |f|
15
+ # write stylesheet file to disk
16
+ sprite_files.each do |sprite_file, sprites|
17
+ sprites.each do |sprite|
18
+ f.puts "#{sprites_class}.#{sprite[:group]}#{@builder.config['class_separator']}#{sprite[:name]} {"
19
+ f.puts " background: url('/#{@builder.config['image_output_path']}#{sprite_file}') no-repeat #{sprite[:x]}px #{sprite[:y]}px;"
20
+ f.puts " width: #{sprite[:width]}px;"
21
+ f.puts " height: #{sprite[:height]}px;"
22
+ f.puts "}"
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def extension
29
+ "css"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ module Sprite
2
+ module Styles
3
+
4
+ # renders standard sass rules
5
+ class SassGenerator
6
+ def initialize(builder)
7
+ @builder = builder
8
+ end
9
+
10
+ def write(path, sprite_files)
11
+ @level = 0
12
+
13
+ File.open(File.join(Sprite.root, path), 'w') do |f|
14
+ if @builder.config['sprites_class']
15
+ f.puts ".#{@builder.config['sprites_class']}"
16
+ @level += 1
17
+ end
18
+
19
+ sprite_files.each do |sprite_file, sprites|
20
+ sprites.each do |sprite|
21
+ f.puts sass_line("&.#{sprite[:group]}#{@builder.config['class_separator']}#{sprite[:name]}")
22
+ @level += 1
23
+ f.puts sass_line("background: url('/#{@builder.config['image_output_path']}#{sprite_file}') no-repeat #{sprite[:x]}px #{sprite[:y]}px")
24
+ f.puts sass_line("width: #{sprite[:width]}px")
25
+ f.puts sass_line("height: #{sprite[:height]}px")
26
+ f.puts sass_line("")
27
+ @level -= 1
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # write sass output with correct tab spaces prepended
34
+ def sass_line(sass)
35
+ "#{' '*@level}#{sass}"
36
+ end
37
+
38
+ def extension
39
+ "sass"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ module Sprite
2
+ module Styles
3
+ # renders a yml file that is later parsed by a sass extension when generating the mixins
4
+ class SassMixinGenerator
5
+ def initialize(builder)
6
+ @builder = builder
7
+ end
8
+
9
+ def write(path, sprite_files)
10
+ # write the sass mixins to disk
11
+ File.open(File.join(Sprite.root, path), 'w') do |f|
12
+ add_else = false
13
+
14
+ f.puts "= sprite(!group_name, !image_name, !offset=0)"
15
+ sprite_files.each do |sprite_file, sprites|
16
+ sprites.each do |sprite|
17
+
18
+ f << " @"
19
+ if add_else
20
+ f << "else "
21
+ end
22
+ add_else = true
23
+ #{sprite[:x]}px #{sprite[:y]}px
24
+
25
+ if sprite[:align] == 'horizontal'
26
+ background_offset = "\#{#{sprite[:x]}+!offset}px #{sprite[:y]}px"
27
+ else
28
+ background_offset = "#{sprite[:x]}px \#{#{sprite[:y]}+!offset}px"
29
+ end
30
+
31
+ f.puts %{if !group_name == "#{sprite[:group]}" and !image_name == "#{sprite[:name]}"}
32
+ f.puts " background: url('/#{@builder.config['image_output_path']}#{sprite_file}') no-repeat #{background_offset}"
33
+ f.puts " width: #{sprite[:width]}px"
34
+ f.puts " height: #{sprite[:height]}px"
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def extension
41
+ "sass"
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,54 @@
1
+ require 'yaml'
2
+ module Sprite
3
+ module Styles
4
+ # renders a yml file that is later parsed by a sass extension when generating the mixins
5
+ class SassYmlGenerator
6
+ def initialize(builder)
7
+ @builder = builder
8
+ end
9
+
10
+ def write(path, sprite_files)
11
+ # build the yml file
12
+ config_location = write_config(path, sprite_files)
13
+
14
+ # write the sass mixins to disk
15
+ File.open(File.join(Sprite.root, path), 'w') do |f|
16
+ f.puts "!sprite_data = '#{config_location}'"
17
+ f.puts ""
18
+ f.puts "= sprite(!group_name, !image_name)"
19
+ f.puts " background= sprite_background(!group_name, !image_name)"
20
+ f.puts " width= sprite_width(!group_name, !image_name)"
21
+ f.puts " height= sprite_height(!group_name, !image_name)"
22
+ f.puts ""
23
+ end
24
+ end
25
+
26
+ # write the sprite configuration file (used by the yml extension)
27
+ def write_config(path, sprite_files)
28
+ # build a grouped hash with all the sprites in it
29
+ result = {}
30
+ sprite_files.each do |sprite_file, sprites|
31
+ sprites.each do |sprite|
32
+ if sprite[:group]
33
+ result[sprite[:group]] ||= {}
34
+ result[sprite[:group]][sprite[:name]] = sprite
35
+ end
36
+ end
37
+ end
38
+
39
+ # write the config yml to disk
40
+ config_path = path.gsub(".sass", ".yml")
41
+ File.open(File.join(Sprite.root, config_path), 'w') do |f|
42
+ YAML.dump(result, f)
43
+ end
44
+
45
+ config_path
46
+ end
47
+
48
+ def extension
49
+ "sass"
50
+ end
51
+
52
+ end
53
+ end
54
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'sprite'
2
+
@@ -0,0 +1,56 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{sprite-generator}
8
+ s.version = "0.1.7"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jacques Crocker", "Anton Styagun"]
12
+ s.date = %q{2009-11-27}
13
+ s.default_executable = %q{sprite}
14
+ s.description = %q{sprite-generator is a rails/merb plugin that generates sprites for css, sass}
15
+ s.email = %q{astyagun@gmail.com}
16
+ s.executables = ["sprite"]
17
+ s.extra_rdoc_files = [
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ "MIT-LICENSE",
22
+ "README.md",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "bin/sprite",
26
+ "lib/sprite.rb",
27
+ "lib/sprite/builder.rb",
28
+ "lib/sprite/image_combiner.rb",
29
+ "lib/sprite/runner.rb",
30
+ "lib/sprite/sass_extensions.rb",
31
+ "lib/sprite/styles.rb",
32
+ "lib/sprite/styles/css_generator.rb",
33
+ "lib/sprite/styles/sass_generator.rb",
34
+ "lib/sprite/styles/sass_mixin_generator.rb",
35
+ "lib/sprite/styles/sass_yml_generator.rb",
36
+ "rails/init.rb",
37
+ "sprite-generator.gemspec",
38
+ "tasks/sprite_tasks.rake"
39
+ ]
40
+ s.homepage = %q{http://github.com/iast/sprite}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.5}
44
+ s.summary = %q{generate your css sprites automagically}
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
+ else
52
+ end
53
+ else
54
+ end
55
+ end
56
+
@@ -0,0 +1,13 @@
1
+ require File.join(File.dirname(__FILE__), '../lib/sprite/sprite.rb')
2
+
3
+ namespace :sprite do
4
+ desc "build sprite images based on config/sprite.yml"
5
+ task :build do
6
+ Sprite.new.build
7
+ end
8
+
9
+ task :list => [:build] do
10
+ # TODO
11
+ # list all the currently configured sprites
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sprite-generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.7
5
+ platform: ruby
6
+ authors:
7
+ - Jacques Crocker
8
+ - Anton Styagun
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-11-27 00:00:00 +02:00
14
+ default_executable: sprite
15
+ dependencies: []
16
+
17
+ description: sprite-generator is a rails/merb plugin that generates sprites for css, sass
18
+ email: astyagun@gmail.com
19
+ executables:
20
+ - sprite
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - README.md
25
+ files:
26
+ - MIT-LICENSE
27
+ - README.md
28
+ - Rakefile
29
+ - VERSION
30
+ - bin/sprite
31
+ - lib/sprite.rb
32
+ - lib/sprite/builder.rb
33
+ - lib/sprite/image_combiner.rb
34
+ - lib/sprite/runner.rb
35
+ - lib/sprite/sass_extensions.rb
36
+ - lib/sprite/styles.rb
37
+ - lib/sprite/styles/css_generator.rb
38
+ - lib/sprite/styles/sass_generator.rb
39
+ - lib/sprite/styles/sass_mixin_generator.rb
40
+ - lib/sprite/styles/sass_yml_generator.rb
41
+ - rails/init.rb
42
+ - sprite-generator.gemspec
43
+ - tasks/sprite_tasks.rake
44
+ has_rdoc: true
45
+ homepage: http://github.com/iast/sprite
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --charset=UTF-8
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.3.5
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: generate your css sprites automagically
72
+ test_files: []
73
+