sprite 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -24,31 +24,12 @@ Install the `sprite` gem from gemcutter
24
24
  gem sources -a http://gemcutter.org
25
25
  gem install sprite
26
26
 
27
- ### if using Merb ###
28
-
29
- With Merb 1.1 and Bundler, just add the line `gem 'sprite'` your ./Gemfile and then run `gem bundle`
30
-
31
- ### if using Rails ###
32
-
33
- add to environment.rb
34
-
35
- config.gem "sprite"
36
-
37
- or install as a plugin
38
-
39
- script/plugin install git://github.com/gistinc/sprite.git
40
-
41
27
  ## USAGE ##
42
28
 
43
29
  if installed as a gem, at your root project folder you can just run
44
30
 
45
31
  sprite
46
32
 
47
- if you would rather not install the gem, you can also use it with rake
48
-
49
- rake sprite:build
50
-
51
-
52
33
  ### Intelligent Defaults ###
53
34
 
54
35
  Without having to configure anything, `sprite` will allow you to easily generate sprites based on a couple default folder settings we give you right off the bat.
@@ -177,6 +158,13 @@ We also support mixin syntax via `style: sass_mixin`. If set, sprite will only g
177
158
 
178
159
  .mysmallbluestar
179
160
  +sprite("blue-stars", "small")
161
+
162
+
163
+ ## Framework Integration?? ##
164
+
165
+ `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!
166
+
167
+ 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.
180
168
 
181
169
  ## ABOUT `sprite` ##
182
170
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
@@ -5,7 +5,6 @@ module Sprite
5
5
 
6
6
  attr_reader :config
7
7
  attr_reader :images
8
- attr_reader :output
9
8
 
10
9
  def self.from_config(path = nil)
11
10
  results = {}
@@ -32,37 +31,40 @@ module Sprite
32
31
  set_image_defaults
33
32
  expand_image_paths
34
33
 
35
- # initialize output
36
- @output = {}
34
+ # initialize sprite files
35
+ @sprite_files = {}
37
36
  end
38
37
 
39
38
  def build
40
- @output = {}
39
+ @sprite_files = {}
41
40
 
42
41
  if images.size > 0
43
42
  # create images
44
43
  images.each do |image|
45
- output_image(image)
44
+ write_image(image)
46
45
  end
47
46
 
48
- # write css
49
- output_file
47
+ if @sprite_files.values.length > 0
48
+ # write css
49
+ write_styles
50
+ end
50
51
  end
51
52
  end
52
53
 
53
54
  protected
54
- def output_image(image)
55
+ def write_image(image)
55
56
  results = []
56
57
  sources = image['sources'].to_a
57
58
  return unless sources.length > 0
58
59
 
59
60
  name = image['name']
61
+ format = image['format'] || config["default_format"]
60
62
  spaced_by = image['spaced_by'] || 0
61
63
 
62
64
  combiner = ImageCombiner.new
63
65
 
64
66
  dest_image = combiner.get_image(sources.shift)
65
- results << combiner.image_properties(dest_image).merge(:x => 0, :y => 0)
67
+ results << combiner.image_properties(dest_image).merge(:x => 0, :y => 0, :group => name)
66
68
  sources.each do |source|
67
69
  source_image = combiner.get_image(source)
68
70
  if image['align'].to_s == 'horizontal'
@@ -77,75 +79,31 @@ module Sprite
77
79
  end
78
80
 
79
81
  # set up path
80
- path = image_output_path(name, image['format'] || config["default_format"])
82
+ path = image_output_path(name, format)
81
83
  FileUtils.mkdir_p(File.dirname(path))
82
84
 
83
85
  # write sprite image file to disk
84
86
  dest_image.write(path)
85
- @output[name] = results
86
- end
87
-
88
- def output_file
89
- # set up path
90
- path = style_output_path("css")
91
- FileUtils.mkdir_p(File.dirname(path))
92
-
93
- # set up class_name to append to each rule
94
- sprites_class = config['sprites_class'] ? ".#{config['sprites_class']}" : ""
95
-
96
- # write stylesheet file to disk
97
- File.open(path, 'w') do |f|
98
- @output.each do |dest, results|
99
- results.each do |result|
100
- f.puts "#{sprites_class}.#{result[:group]}#{config['class_separator']}#{result[:name]} {"
101
- f.puts " background: url('/#{config['image_output_path']}#{dest}') no-repeat #{result[:x]}px #{result[:y]}px;"
102
- f.puts " width: #{result[:width]}px;"
103
- f.puts " height: #{result[:height]}px;"
104
- f.puts "}"
105
- end
106
- end
107
- end
108
- end
109
-
110
- # get the disk path for the style output file
111
- def style_output_path(file_ext)
112
- path = config['style_output_path']
113
- unless path.include?(".#{file_ext}")
114
- path = "#{path}.#{file_ext}"
115
- end
116
- public_path(path)
87
+ @sprite_files["#{name}.#{format}"] = results
117
88
  end
118
89
 
119
- # get the disk path for a location within the image output folder
120
- def image_output_path(name, format)
121
- path_parts = []
122
- path_parts << chop_trailing_slash(config['image_output_path'])
123
- path_parts << "#{name}.#{format}"
124
- public_path(File.join(*path_parts))
125
- end
126
-
127
- # get the disk path for a location within the public folder (if set)
128
- def public_path(location)
129
- path_parts = []
130
- path_parts << Sprite.root
131
- path_parts << chop_trailing_slash(config['public_path']) if config['public_path'] and config['public_path'].length > 0
132
- path_parts << location
90
+ def write_styles
91
+ style = Styles.get(config["style"]).new(self)
133
92
 
134
- File.join(*path_parts)
135
- end
136
-
137
- # chop off the trailing slash on a directory path (if it exists)
138
- def chop_trailing_slash(path)
139
- path = path[0...-1] if path[-1] == File::SEPARATOR
140
- path
93
+ # use the absolute style output path to make sure we have the directory set up
94
+ path = style_output_path(style.extension, false)
95
+ FileUtils.mkdir_p(File.dirname(path))
96
+
97
+ # send the style the relative path
98
+ style.write(style_output_path(style.extension, true), @sprite_files)
141
99
  end
142
100
 
143
101
  # sets all the default values on the config
144
102
  def set_config_defaults
145
103
  @config['style'] ||= 'css'
146
- @config['style_output_path'] ||= 'stylesheets/sprites'
104
+ @config['style_output_path'] ||= 'stylesheets/sprites'
147
105
  @config['image_output_path'] ||= 'images/sprites/'
148
- @config['image_source_path'] ||= 'images/'
106
+ @config['image_source_path'] ||= 'images/'
149
107
  @config['public_path'] ||= 'public/'
150
108
  @config['default_format'] ||= 'png'
151
109
  @config['class_separator'] ||= '-'
@@ -156,7 +114,7 @@ module Sprite
156
114
  def set_image_defaults
157
115
  return unless @images.size == 0
158
116
 
159
- sprites_path = File.join(Sprite.root, config['public_path'], config['image_source_path'], "sprites")
117
+ sprites_path = image_source_path("sprites")
160
118
 
161
119
  if File.exists?(sprites_path)
162
120
  Dir.glob(File.join(sprites_path, "*")) do |dir|
@@ -175,7 +133,6 @@ module Sprite
175
133
  }
176
134
  end
177
135
  end
178
-
179
136
  end
180
137
 
181
138
  # expands out sources, taking the Glob paths and turning them into separate entries in the array
@@ -184,10 +141,55 @@ module Sprite
184
141
  @images.each do |image|
185
142
  # expand out all the globs
186
143
  image['sources'] = image['sources'].to_a.map{ |source|
187
- Dir.glob(File.join(Sprite.root, config['public_path'], @config['image_source_path'], source))
144
+ Dir.glob(image_source_path(source))
188
145
  }.flatten.compact
189
146
  end
190
147
  end
191
148
 
149
+ # get the disk path for the style output file
150
+ def style_output_path(file_ext, relative = false)
151
+ path = config['style_output_path']
152
+ unless path.include?(".#{file_ext}")
153
+ path = "#{path}.#{file_ext}"
154
+ end
155
+ public_path(path, relative)
156
+ end
157
+
158
+ # get the disk path for a location within the image output folder
159
+ def image_output_path(name, format, relative = false)
160
+ path_parts = []
161
+ path_parts << chop_trailing_slash(config['image_output_path']) if path_present?(config['image_output_path'])
162
+ path_parts << "#{name}.#{format}"
163
+ public_path(File.join(*path_parts), relative)
164
+ end
165
+
166
+ # get the disk path for an image source file
167
+ def image_source_path(location, relative = false)
168
+ path_parts = []
169
+ path_parts << chop_trailing_slash(config["image_source_path"]) if path_present?(config['image_source_path'])
170
+ path_parts << location
171
+ public_path(File.join(*path_parts), relative)
172
+ end
173
+
174
+ # get the disk path for a location within the public folder (if set)
175
+ def public_path(location, relative = false)
176
+ path_parts = []
177
+ path_parts << Sprite.root unless relative
178
+ path_parts << chop_trailing_slash(config['public_path']) if path_present?(config['public_path'])
179
+ path_parts << location
180
+
181
+ File.join(*path_parts)
182
+ end
183
+
184
+ # chop off the trailing slash on a directory path (if it exists)
185
+ def chop_trailing_slash(path)
186
+ path = path[0...-1] if path[-1] == File::SEPARATOR
187
+ path
188
+ end
189
+
190
+ # check if the path is set
191
+ def path_present?(path)
192
+ path.to_s.strip != ""
193
+ end
192
194
  end
193
195
  end
@@ -16,7 +16,6 @@ module Sprite
16
16
  image
17
17
  end
18
18
 
19
-
20
19
  # Image Utility Methods
21
20
  def get_image(image_filename)
22
21
  image = Magick::Image::read(image_filename).first
@@ -25,6 +24,10 @@ module Sprite
25
24
  def image_properties(image)
26
25
  {:name => File.basename(image.filename).split('.')[0], :width => image.columns, :height => image.rows}
27
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
28
31
 
29
32
  end
30
33
  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,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,39 @@
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 SassIfGenerator
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)"
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
+
24
+ f.puts %{if !group_name == "#{sprite[:group]}" and !image_name == "#{sprite[:name]}"}
25
+ f.puts " background: url('/#{@builder.config['image_output_path']}#{sprite_file}') no-repeat #{sprite[:x]}px #{sprite[:y]}px"
26
+ f.puts " width: #{sprite[:width]}px"
27
+ f.puts " height: #{sprite[:height]}px"
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ def extension
34
+ "sass"
35
+ end
36
+
37
+ end
38
+ end
39
+ 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 SassMixinGenerator
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
@@ -0,0 +1,20 @@
1
+ require 'sprite/styles/sass_generator'
2
+ require 'sprite/styles/css_generator'
3
+ require 'sprite/styles/sass_mixin_generator'
4
+ require 'sprite/styles/sass_if_generator'
5
+
6
+ module Sprite::Styles
7
+ GENERATORS = {
8
+ "css" => "CssGenerator",
9
+ "sass" => "SassGenerator",
10
+ "sass_mixin" => "SassMixinGenerator",
11
+ "sass_if" => "SassIfGenerator"
12
+ }
13
+
14
+ def self.get(config)
15
+ const_get(GENERATORS[config])
16
+ rescue
17
+ CssGenerator
18
+ end
19
+
20
+ end
data/lib/sprite.rb CHANGED
@@ -20,3 +20,4 @@ end
20
20
 
21
21
  require 'sprite/builder'
22
22
  require 'sprite/image_combiner'
23
+ require 'sprite/styles'
data/sprite.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sprite}
8
- s.version = "0.1.2"
8
+ s.version = "0.1.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jacques Crocker", "Richard Huang"]
12
- s.date = %q{2009-11-17}
12
+ s.date = %q{2009-11-18}
13
13
  s.default_executable = %q{sprite}
14
14
  s.description = %q{sprite is a rails/merb plugin that generates sprites for css, sass}
15
15
  s.email = %q{merbjedi@gmail.com}
@@ -27,6 +27,12 @@ Gem::Specification.new do |s|
27
27
  "lib/sprite/builder.rb",
28
28
  "lib/sprite/image_combiner.rb",
29
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_if_generator.rb",
35
+ "lib/sprite/styles/sass_mixin_generator.rb",
30
36
  "rails/init.rb",
31
37
  "sprite.gemspec",
32
38
  "tasks/sprite_tasks.rake"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sprite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacques Crocker
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-11-17 00:00:00 -08:00
13
+ date: 2009-11-18 00:00:00 -08:00
14
14
  default_executable: sprite
15
15
  dependencies: []
16
16
 
@@ -32,6 +32,12 @@ files:
32
32
  - lib/sprite/builder.rb
33
33
  - lib/sprite/image_combiner.rb
34
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_if_generator.rb
40
+ - lib/sprite/styles/sass_mixin_generator.rb
35
41
  - rails/init.rb
36
42
  - sprite.gemspec
37
43
  - tasks/sprite_tasks.rake