polymer 1.0.0.beta.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +8 -0
- data/History.md +126 -0
- data/LICENSE +28 -0
- data/README.md +229 -0
- data/Rakefile +186 -0
- data/bin/polymer +10 -0
- data/lib/polymer/cache.rb +106 -0
- data/lib/polymer/cli.rb +340 -0
- data/lib/polymer/core_ext.rb +78 -0
- data/lib/polymer/css_generator.rb +32 -0
- data/lib/polymer/deviant_finder.rb +76 -0
- data/lib/polymer/dsl.rb +283 -0
- data/lib/polymer/man/polymer-bond.1 +60 -0
- data/lib/polymer/man/polymer-bond.1.txt +66 -0
- data/lib/polymer/man/polymer-init.1 +33 -0
- data/lib/polymer/man/polymer-init.1.txt +42 -0
- data/lib/polymer/man/polymer-optimise.1 +23 -0
- data/lib/polymer/man/polymer-optimise.1.txt +25 -0
- data/lib/polymer/man/polymer-position.1 +39 -0
- data/lib/polymer/man/polymer-position.1.txt +42 -0
- data/lib/polymer/man/polymer.1 +50 -0
- data/lib/polymer/man/polymer.1.txt +60 -0
- data/lib/polymer/man/polymer.5 +130 -0
- data/lib/polymer/man/polymer.5.txt +145 -0
- data/lib/polymer/optimisation.rb +130 -0
- data/lib/polymer/project.rb +164 -0
- data/lib/polymer/sass_generator.rb +38 -0
- data/lib/polymer/source.rb +55 -0
- data/lib/polymer/sprite.rb +130 -0
- data/lib/polymer/templates/polymer.tt +28 -0
- data/lib/polymer/templates/sass_mixins.erb +29 -0
- data/lib/polymer/templates/sources/one/book.png +0 -0
- data/lib/polymer/templates/sources/one/box-label.png +0 -0
- data/lib/polymer/templates/sources/one/calculator.png +0 -0
- data/lib/polymer/templates/sources/one/calendar-month.png +0 -0
- data/lib/polymer/templates/sources/one/camera.png +0 -0
- data/lib/polymer/templates/sources/one/eraser.png +0 -0
- data/lib/polymer/templates/sources/two/inbox-image.png +0 -0
- data/lib/polymer/templates/sources/two/magnet.png +0 -0
- data/lib/polymer/templates/sources/two/newspaper.png +0 -0
- data/lib/polymer/templates/sources/two/television.png +0 -0
- data/lib/polymer/templates/sources/two/wand-hat.png +0 -0
- data/lib/polymer/templates/sources/two/wooden-box-label.png +0 -0
- data/lib/polymer/version.rb +4 -0
- data/lib/polymer.rb +49 -0
- data/polymer.gemspec +94 -0
- metadata +206 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
POLYMER(1) Polymer Manual POLYMER(1)
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
NAME
|
6
|
+
polymer - Image spriting for web applications
|
7
|
+
|
8
|
+
SYNOPSIS
|
9
|
+
polymer [--no-colour] COMMAND [ARGUMENTS]
|
10
|
+
|
11
|
+
DESCRIPTION
|
12
|
+
Polymer is a tool for creating sprite images which combine many smaller
|
13
|
+
sources into a single larger image. Spriting allows you to reduce the
|
14
|
+
number of HTTP requests required to load a web page, and as such can
|
15
|
+
result in reduced load times.
|
16
|
+
|
17
|
+
Polymer also creates the necessary CSS to position the sprite within an
|
18
|
+
HTML element so that only the desired source appears. Those writing
|
19
|
+
their website or application in Ruby can make use of Polymer's Sass
|
20
|
+
builder which creates a Sass mixin, further simplifying the use of your
|
21
|
+
sprites.
|
22
|
+
|
23
|
+
In order to reduce the amount of data transferred to clients loading
|
24
|
+
your pages, Polymer optimises the sprites it generates using PNGOUT,
|
25
|
+
OptiPNG, and PNGCrush.
|
26
|
+
|
27
|
+
OPTIONS
|
28
|
+
--no-colour
|
29
|
+
Disables the use of colour in output. This option is also avail-
|
30
|
+
able as --no-color.
|
31
|
+
|
32
|
+
COMMANDS
|
33
|
+
polymer init(1) polymer-init.1.html
|
34
|
+
Creates a new Polymer project in the current directory.
|
35
|
+
|
36
|
+
polymer bond(1) polymer-bond.1.html
|
37
|
+
Creates the sprites specified by your .polymer or polymer.rb
|
38
|
+
file, optimises the images, and creates any requested CSS or
|
39
|
+
Sass files.
|
40
|
+
|
41
|
+
polymer optimise(1) polymer-optimise.1.html
|
42
|
+
Given paths to PNG files as arguments, optimises them to reduce
|
43
|
+
the filesize as much as possible without compromising quality.
|
44
|
+
Also available as polymer optimize.
|
45
|
+
|
46
|
+
polymer position(1) polymer-position.1.html
|
47
|
+
Shows the position of a source within a sprite, and provides CSS
|
48
|
+
which you can use in your own stylesheets.
|
49
|
+
|
50
|
+
Detailed documentation for each of Polymer's commands can be viewed
|
51
|
+
with the polymer help command. For example, to view the documentation
|
52
|
+
for the bond command, run polymer help bond.
|
53
|
+
|
54
|
+
SEE ALSO
|
55
|
+
polymer(5) (polymer help .polymer) provides a description of the .poly-
|
56
|
+
mer configuration file format.
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
POLYMER 1.0.0.BETA.3 September 2010 POLYMER(1)
|
@@ -0,0 +1,130 @@
|
|
1
|
+
.\" generated with Ronn/v0.7.3
|
2
|
+
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
|
+
.ad l
|
4
|
+
.
|
5
|
+
.TH "\.POLYMER" "5" "September 2010" "POLYMER 1.0.0.BETA.3" "Polymer Manual"
|
6
|
+
.
|
7
|
+
.SH "NAME"
|
8
|
+
\fB\.polymer\fR \- a format for describing image sprites and their sources
|
9
|
+
.
|
10
|
+
.SH "DESCRIPTION"
|
11
|
+
A \fB\.polymer\fR file describes the image sprites used in a Polymer project, and the source images which are used to create those sprites\.
|
12
|
+
.
|
13
|
+
.P
|
14
|
+
Placing a \fB\.polymer\fR file in the root directory of your project will allow the Polymer application to automate generation and optimisation of your sprite images\. In a Ruby project the \fB\.polymer\fR file should be in the same directory as your \fBRakefile\fR\.
|
15
|
+
.
|
16
|
+
.P
|
17
|
+
On systems where files beginning with a "\." are tricky to work with (e\.g\. Windows), you may instead use \fBpolymer\.rb\fR instead of \fB\.polymer\fR\.
|
18
|
+
.
|
19
|
+
.P
|
20
|
+
A \fB\.polymer\fR can be generated by running \fBpolymer init\fR\.
|
21
|
+
.
|
22
|
+
.SH "SYNTAX"
|
23
|
+
The \fB\.polymer\fR file is, at it\'s heart, a Ruby file and thus any valid Ruby code may be used in it\. This may seem intimidating to those who have never used Ruby, but the \fB\.polymer\fR syntax is very simple, and fairly self\-explanatory (the irony of saying that, then writing a man page, is not lost on me\.\.\.)\.
|
24
|
+
.
|
25
|
+
.SH "GLOBAL SETTINGS"
|
26
|
+
Global options are prefixed with "config\." and followed by the value you wish to set\. These settings are OPTIONAL, and Polymer will use it\'s own defaults if you choose not to define them\.
|
27
|
+
.
|
28
|
+
.TP
|
29
|
+
\fBconfig\.sass\fR "\fIstring\fR" or \fIfalse\fR
|
30
|
+
The path, relative to the \fB\.polymer\fR file, at which you want the Sass mixin file to be written\. You may also set this to \fIfalse\fR in order to disable generation of Sass files\. Default: "public/stylesheets/sass"
|
31
|
+
.
|
32
|
+
.TP
|
33
|
+
\fBconfig\.css\fR "\fIstring\fR" or \fIfalse\fR
|
34
|
+
The path, relative to the \fB\.polymer\fR file, at which you want the CSS file to be written\. You may also set this to \fIfalse\fR in order to disable generation of CSS files\. Default: false
|
35
|
+
.
|
36
|
+
.TP
|
37
|
+
\fBconfig\.url\fR "\fIstring\fR"
|
38
|
+
In order for stylesheets to link to the generated sprites, they must be able to create a URL for each sprite\. Typically this URL should be relative to the web root and prefixed with a "/", otherwise browsers will interpret the URL as being relative to the stylesheet\. The \fBurl\fR option accepts a ":filename" segment which Polymer will change to each sprite\'s filename (including the extension)\. Default: "/images/:filename"
|
39
|
+
.
|
40
|
+
.TP
|
41
|
+
\fBconfig\.padding\fR \fInumber\fR
|
42
|
+
Polymer stacks each source image on top of one another, with transparent padding being used to ensure that one source does not bleed into another when used as the background for an HTML element\. The \fBpadding\fR option sets the number of pixels to be used to separate each source, and may be set to 0 if no padding is desired\. Default: 20\.
|
43
|
+
.
|
44
|
+
.TP
|
45
|
+
\fBconfig\.cache\fR "\fIstring\fR" or \fIfalse\fR
|
46
|
+
Since optimising sprites can take some time, Polymer maintains a cache of each sprite, only generating and optimising those which have changed\. This cache is typically stored in your project root as "\.polymer\-cache"\. You may specify an alternate path here, or provide \fIfalse\fR if you want to disable the cache entirely (not recommended)\.
|
47
|
+
.
|
48
|
+
.SH "DEFINING SPRITES"
|
49
|
+
Sprites are defined using the \fIsprite\fR keyword (which is also aliased as \fIsprites\fR)\. The simplest way of defining a sprite is:
|
50
|
+
.
|
51
|
+
.IP "" 4
|
52
|
+
.
|
53
|
+
.nf
|
54
|
+
|
55
|
+
sprite "path/to/sources/*" => "path/to/sprite\.png"
|
56
|
+
.
|
57
|
+
.fi
|
58
|
+
.
|
59
|
+
.IP "" 0
|
60
|
+
.
|
61
|
+
.P
|
62
|
+
Both of the paths in the above example are relative to the \fB\.polymer\fR file\. In this case, we are telling Polymer to take source files from the "path/to/sources" directory, and composite them together in a sprite to be saved at "path/to/sprite\.png"\.
|
63
|
+
.
|
64
|
+
.P
|
65
|
+
If your source directory contains non\-images, you may need to be more specific:
|
66
|
+
.
|
67
|
+
.IP "" 4
|
68
|
+
.
|
69
|
+
.nf
|
70
|
+
|
71
|
+
sprite "path/to/sources/*\.{png,gif,jpg}" => "path/to/sprite\.png"
|
72
|
+
.
|
73
|
+
.fi
|
74
|
+
.
|
75
|
+
.IP "" 0
|
76
|
+
.
|
77
|
+
.P
|
78
|
+
Sprite definitions may contain a \fB:name\fR segment which Polymer will use to match any sub\-directory:
|
79
|
+
.
|
80
|
+
.IP "" 4
|
81
|
+
.
|
82
|
+
.nf
|
83
|
+
|
84
|
+
sprites "sources/:name/*" => "sprites/:name\.png"
|
85
|
+
.
|
86
|
+
.fi
|
87
|
+
.
|
88
|
+
.IP "" 0
|
89
|
+
.
|
90
|
+
.P
|
91
|
+
In this case, Polymer will look inside the "sources/" directory for sub\-directories\. The contents of sub\-directory will be used to create individual sprites where the final sprite name is the same as the directory name\. For example, given the following directory structure\.\.\.
|
92
|
+
.
|
93
|
+
.IP "" 4
|
94
|
+
.
|
95
|
+
.nf
|
96
|
+
|
97
|
+
sources/
|
98
|
+
one/
|
99
|
+
book\.png
|
100
|
+
calculator\.png
|
101
|
+
two/
|
102
|
+
magnet\.png
|
103
|
+
television\.png
|
104
|
+
.
|
105
|
+
.fi
|
106
|
+
.
|
107
|
+
.IP "" 0
|
108
|
+
.
|
109
|
+
.P
|
110
|
+
\&\.\.\. Polymer will create two sprites in the "sprites/" directory: one\.png will contain "book" and "calculator", while two\.png will contain "magnet" and "television"\.
|
111
|
+
.
|
112
|
+
.P
|
113
|
+
There may be cases where you need to customise an individual sprite and you don\'t want to change the global setting; \fBsprite\fR allows you to specify any of the global settings with the exception of "sass" and "css" like so:
|
114
|
+
.
|
115
|
+
.IP "" 4
|
116
|
+
.
|
117
|
+
.nf
|
118
|
+
|
119
|
+
sprite "path/to/sources/*" => "path/to/sprite\.png",
|
120
|
+
:padding => 50, :url => "/elsewhere/:filename"
|
121
|
+
.
|
122
|
+
.fi
|
123
|
+
.
|
124
|
+
.IP "" 0
|
125
|
+
.
|
126
|
+
.P
|
127
|
+
Each configuration option is prefixed with a colon rather than "config\.", is separated from the value with " => ", and all but the final option should be followed with a comma\.
|
128
|
+
.
|
129
|
+
.SH "SEE ALSO"
|
130
|
+
polymer(1), polymer\-init(1)
|
@@ -0,0 +1,145 @@
|
|
1
|
+
.POLYMER(5) Polymer Manual .POLYMER(5)
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
NAME
|
6
|
+
.polymer - a format for describing image sprites and their sources
|
7
|
+
|
8
|
+
DESCRIPTION
|
9
|
+
A .polymer file describes the image sprites used in a Polymer project,
|
10
|
+
and the source images which are used to create those sprites.
|
11
|
+
|
12
|
+
Placing a .polymer file in the root directory of your project will
|
13
|
+
allow the Polymer application to automate generation and optimisation
|
14
|
+
of your sprite images. In a Ruby project the .polymer file should be in
|
15
|
+
the same directory as your Rakefile.
|
16
|
+
|
17
|
+
On systems where files beginning with a "." are tricky to work with
|
18
|
+
(e.g. Windows), you may instead use polymer.rb instead of .polymer.
|
19
|
+
|
20
|
+
A .polymer can be generated by running polymer init.
|
21
|
+
|
22
|
+
SYNTAX
|
23
|
+
The .polymer file is, at it's heart, a Ruby file and thus any valid
|
24
|
+
Ruby code may be used in it. This may seem intimidating to those who
|
25
|
+
have never used Ruby, but the .polymer syntax is very simple, and
|
26
|
+
fairly self-explanatory (the irony of saying that, then writing a man
|
27
|
+
page, is not lost on me...).
|
28
|
+
|
29
|
+
GLOBAL SETTINGS
|
30
|
+
Global options are prefixed with "config." and followed by the value
|
31
|
+
you wish to set. These settings are OPTIONAL, and Polymer will use it's
|
32
|
+
own defaults if you choose not to define them.
|
33
|
+
|
34
|
+
config.sass "string" or false
|
35
|
+
The path, relative to the .polymer file, at which you want the
|
36
|
+
Sass mixin file to be written. You may also set this to false in
|
37
|
+
order to disable generation of Sass files. Default: "pub-
|
38
|
+
lic/stylesheets/sass"
|
39
|
+
|
40
|
+
config.css "string" or false
|
41
|
+
The path, relative to the .polymer file, at which you want the
|
42
|
+
CSS file to be written. You may also set this to false in order
|
43
|
+
to disable generation of CSS files. Default: false
|
44
|
+
|
45
|
+
config.url "string"
|
46
|
+
In order for stylesheets to link to the generated sprites, they
|
47
|
+
must be able to create a URL for each sprite. Typically this URL
|
48
|
+
should be relative to the web root and prefixed with a "/", oth-
|
49
|
+
erwise browsers will interpret the URL as being relative to the
|
50
|
+
stylesheet. The url option accepts a ":filename" segment which
|
51
|
+
Polymer will change to each sprite's filename (including the
|
52
|
+
extension). Default: "/images/:filename"
|
53
|
+
|
54
|
+
config.padding number
|
55
|
+
Polymer stacks each source image on top of one another, with
|
56
|
+
transparent padding being used to ensure that one source does
|
57
|
+
not bleed into another when used as the background for an HTML
|
58
|
+
element. The padding option sets the number of pixels to be used
|
59
|
+
to separate each source, and may be set to 0 if no padding is
|
60
|
+
desired. Default: 20.
|
61
|
+
|
62
|
+
config.cache "string" or false
|
63
|
+
Since optimising sprites can take some time, Polymer maintains a
|
64
|
+
cache of each sprite, only generating and optimising those which
|
65
|
+
have changed. This cache is typically stored in your project
|
66
|
+
root as ".polymer-cache". You may specify an alternate path
|
67
|
+
here, or provide false if you want to disable the cache entirely
|
68
|
+
(not recommended).
|
69
|
+
|
70
|
+
DEFINING SPRITES
|
71
|
+
Sprites are defined using the sprite keyword (which is also aliased as
|
72
|
+
sprites). The simplest way of defining a sprite is:
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
sprite "path/to/sources/*" => "path/to/sprite.png"
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
Both of the paths in the above example are relative to the .polymer
|
81
|
+
file. In this case, we are telling Polymer to take source files from
|
82
|
+
the "path/to/sources" directory, and composite them together in a
|
83
|
+
sprite to be saved at "path/to/sprite.png".
|
84
|
+
|
85
|
+
If your source directory contains non-images, you may need to be more
|
86
|
+
specific:
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
sprite "path/to/sources/*.{png,gif,jpg}" => "path/to/sprite.png"
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
Sprite definitions may contain a :name segment which Polymer will use
|
95
|
+
to match any sub-directory:
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
sprites "sources/:name/*" => "sprites/:name.png"
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
In this case, Polymer will look inside the "sources/" directory for
|
104
|
+
sub-directories. The contents of sub-directory will be used to create
|
105
|
+
individual sprites where the final sprite name is the same as the
|
106
|
+
directory name. For example, given the following directory structure...
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
sources/
|
111
|
+
one/
|
112
|
+
book.png
|
113
|
+
calculator.png
|
114
|
+
two/
|
115
|
+
magnet.png
|
116
|
+
television.png
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
... Polymer will create two sprites in the "sprites/" directory:
|
121
|
+
one.png will contain "book" and "calculator", while two.png will con-
|
122
|
+
tain "magnet" and "television".
|
123
|
+
|
124
|
+
There may be cases where you need to customise an individual sprite and
|
125
|
+
you don't want to change the global setting; sprite allows you to spec-
|
126
|
+
ify any of the global settings with the exception of "sass" and "css"
|
127
|
+
like so:
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
sprite "path/to/sources/*" => "path/to/sprite.png",
|
132
|
+
:padding => 50, :url => "/elsewhere/:filename"
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
Each configuration option is prefixed with a colon rather than "con-
|
137
|
+
fig.", is separated from the value with " => ", and all but the final
|
138
|
+
option should be followed with a comma.
|
139
|
+
|
140
|
+
SEE ALSO
|
141
|
+
polymer(1), polymer-init(1)
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
POLYMER 1.0.0.BETA.3 September 2010 .POLYMER(5)
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Polymer
|
2
|
+
# Contains support for PNGOUT, OptiPNG, and PNGCrush.
|
3
|
+
module Optimisation
|
4
|
+
|
5
|
+
# Returns an array of optimisers supported on the current system.
|
6
|
+
#
|
7
|
+
# @return [Array<Polymer::Optimisation::Optimiser>]
|
8
|
+
#
|
9
|
+
def self.optimisers
|
10
|
+
@optimisers ||=
|
11
|
+
[PNGOut, OptiPNG, PNGCrush].select { |o| o.supported? }.map(&:new)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Given a path to a file, runs all of the available optimisers until
|
15
|
+
# either:
|
16
|
+
#
|
17
|
+
# 1. No further optimisations could be found.
|
18
|
+
# 2. Each optimiser has been run three times.
|
19
|
+
#
|
20
|
+
# @param [Pathname] path
|
21
|
+
# Path to the file to be optimised.
|
22
|
+
#
|
23
|
+
# @return [Integer, false]
|
24
|
+
# Returns the number of bytes by which the filesize was reduced.
|
25
|
+
# @return [false]
|
26
|
+
# Returns false if the current machine has no optimisers available.
|
27
|
+
#
|
28
|
+
def self.optimise_file(path)
|
29
|
+
return false if optimisers.empty?
|
30
|
+
|
31
|
+
reduction = 0
|
32
|
+
skip = []
|
33
|
+
|
34
|
+
3.times do |i|
|
35
|
+
before_iteration = reduction
|
36
|
+
|
37
|
+
optimisers.each do |optimiser|
|
38
|
+
next if skip.include?(optimiser)
|
39
|
+
|
40
|
+
if (opt_reduction = optimiser.run(path)) > 0
|
41
|
+
reduction += opt_reduction
|
42
|
+
else
|
43
|
+
# This optimiser can't find any more savings, don't run
|
44
|
+
# it again.
|
45
|
+
skip << optimiser
|
46
|
+
end
|
47
|
+
end # optimisers.each
|
48
|
+
|
49
|
+
# If the iteration found no savings, return immediately rather than
|
50
|
+
# running them again.
|
51
|
+
return reduction if before_iteration >= reduction
|
52
|
+
end # 3.times
|
53
|
+
|
54
|
+
reduction
|
55
|
+
end
|
56
|
+
|
57
|
+
# A base optimiser class.
|
58
|
+
class Optimiser
|
59
|
+
COMMAND = ''
|
60
|
+
|
61
|
+
# Runs the optimiser on a file once. Running again may yield further
|
62
|
+
# reductions in file size.
|
63
|
+
#
|
64
|
+
# @param [Pathname] path
|
65
|
+
# Path to the file to be optimised.
|
66
|
+
#
|
67
|
+
# @return [Integer]
|
68
|
+
# Returns the number of bytes by which the filesize was reduced.
|
69
|
+
#
|
70
|
+
# @see [Polymer::Optimisation.optimise_file]
|
71
|
+
#
|
72
|
+
def run(path)
|
73
|
+
before_size = path.size
|
74
|
+
`#{self.class::COMMAND.gsub(/\[PATH\]/, path.to_s)}`
|
75
|
+
before_size - path.size
|
76
|
+
end
|
77
|
+
|
78
|
+
# Tests if the optimiser is supported on the current system.
|
79
|
+
#
|
80
|
+
# @return [Boolean]
|
81
|
+
#
|
82
|
+
def self.supported?
|
83
|
+
unless defined?(@supported)
|
84
|
+
stdout = `which #{self::COMMAND.split(' ', 2).first}`
|
85
|
+
@supported = $?.exitstatus.zero? && stdout !~ /not found/
|
86
|
+
end
|
87
|
+
|
88
|
+
@supported
|
89
|
+
end
|
90
|
+
end # Optimiser
|
91
|
+
|
92
|
+
# An optimiser which uses PNGOUT. pngout may also be called
|
93
|
+
# "pngout-darwin" if installed using MacPorts.
|
94
|
+
class PNGOutDefault < Optimiser
|
95
|
+
COMMAND = 'pngout [PATH] [PATH] -s0 -k0 -y'
|
96
|
+
end
|
97
|
+
|
98
|
+
# MacPorts installs a pngout-darwin binary.
|
99
|
+
class PNGOutDarwin < PNGOutDefault
|
100
|
+
COMMAND = 'pngout-darwin [PATH] [PATH] -s0 -k0 -y'
|
101
|
+
end
|
102
|
+
|
103
|
+
# An optimiser which uses OptiPNG.
|
104
|
+
class OptiPNG < Optimiser
|
105
|
+
COMMAND = 'optipng [PATH]'
|
106
|
+
end # OptiPNG
|
107
|
+
|
108
|
+
# An optimiser which uses PNGCrush.
|
109
|
+
class PNGCrush < Optimiser
|
110
|
+
COMMAND = 'pngcrush -brute -e .png.tmp [PATH]'
|
111
|
+
|
112
|
+
# PNGCrush doesn't overwrite existing files. Instead the -e (extension)
|
113
|
+
# option is used to write to a temporary file, which is them moved over
|
114
|
+
# the new file.
|
115
|
+
def run(path)
|
116
|
+
super
|
117
|
+
FileUtils.rm(path)
|
118
|
+
FileUtils.mv(path.to_s + '.tmp', path)
|
119
|
+
end
|
120
|
+
end # PNGCrush
|
121
|
+
|
122
|
+
# Which PNGOUT should we use?
|
123
|
+
if not PNGOutDefault.supported? and PNGOutDarwin.supported?
|
124
|
+
PNGOut = PNGOutDarwin
|
125
|
+
else
|
126
|
+
PNGOut = PNGOutDefault
|
127
|
+
end
|
128
|
+
|
129
|
+
end # Optimisation
|
130
|
+
end # Polymer
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module Polymer
|
2
|
+
# Represents a directory in which it is expected that there be a
|
3
|
+
# configuration file, and source images.
|
4
|
+
#
|
5
|
+
# The Project class exists mostly to make CLI tasks simpler; if you're using
|
6
|
+
# Polymer within your own library, you may prefer to create Sprite instances
|
7
|
+
# without using a Project.
|
8
|
+
#
|
9
|
+
class Project
|
10
|
+
|
11
|
+
# Defaults used by DSL when the user doesn't provide explicit values.
|
12
|
+
DEFAULTS = {
|
13
|
+
:sass => 'public/stylesheets/sass',
|
14
|
+
:url => "/images/:name.png",
|
15
|
+
:cache => '.polymer-cache',
|
16
|
+
:css => false,
|
17
|
+
:padding => 20
|
18
|
+
}
|
19
|
+
|
20
|
+
# Returns the path to the project root directory.
|
21
|
+
#
|
22
|
+
# @return [Pathname]
|
23
|
+
#
|
24
|
+
attr_reader :root
|
25
|
+
|
26
|
+
# @return [Pathname, false]
|
27
|
+
# The path to the Sass mixin file.
|
28
|
+
# @return [false]
|
29
|
+
# False if Sass has been disabled.
|
30
|
+
#
|
31
|
+
attr_reader :sass
|
32
|
+
|
33
|
+
# @return [Pathname, false]
|
34
|
+
# The path to the CSS file.
|
35
|
+
# @return [false]
|
36
|
+
# False if CSS generation has been disabled.
|
37
|
+
#
|
38
|
+
attr_reader :css
|
39
|
+
|
40
|
+
# An array containing all of the sprites in the project.
|
41
|
+
#
|
42
|
+
# @return [Array<Polymer::Sprite>]
|
43
|
+
#
|
44
|
+
attr_reader :sprites
|
45
|
+
|
46
|
+
# Creates a new Project.
|
47
|
+
#
|
48
|
+
# Note that +new+ does not validation of the given paths or options; it
|
49
|
+
# expects them to be correct. You're probably better using +DSL.build+.
|
50
|
+
#
|
51
|
+
# @param [Pathname] root_path
|
52
|
+
# Path to the root of the Polymer project. The .polymer config should
|
53
|
+
# reside in this directory.
|
54
|
+
# @param [Array<Polymer::Sprite>] sprites
|
55
|
+
# An array of sprites which belong to the project.
|
56
|
+
# @param [Hash] options
|
57
|
+
# Extra options for customising the behaviour of the Project.
|
58
|
+
#
|
59
|
+
# @option options [String, false] :css (false)
|
60
|
+
# Sets the path -- relative to +root_path+ -- at which the CSS
|
61
|
+
# file should be saved. Setting +:css+ to false will disable
|
62
|
+
# generation of CSS stylesheets.
|
63
|
+
# @option options [String, false] :sass (false)
|
64
|
+
# Sets the path -- relative to +root_path+ -- at which the Sass
|
65
|
+
# mixin file should be saved. Setting +:sass+ to false will
|
66
|
+
# disable generation of the mixin file.
|
67
|
+
#
|
68
|
+
def initialize(root_path, sprites, options = {})
|
69
|
+
@root = root_path
|
70
|
+
@sprites = sprites
|
71
|
+
|
72
|
+
@sass = extract_path :sass, options
|
73
|
+
@css = extract_path :css, options
|
74
|
+
@cachefile = extract_path :cache, options
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the sprite whose name is +name+.
|
78
|
+
#
|
79
|
+
# @param [String] name
|
80
|
+
# The name of the sprite to be retrieved.
|
81
|
+
#
|
82
|
+
# @return [Polymer::Sprite] The sprite.
|
83
|
+
# @return [nil] If no such sprite exists.
|
84
|
+
#
|
85
|
+
def sprite(name)
|
86
|
+
sprites.detect { |sprite| sprite.name == name }
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns if the cache should be used.
|
90
|
+
#
|
91
|
+
# @return [true] If the cache should be used by CLI.
|
92
|
+
# @return [false] If the cache is disabled and should not be used.
|
93
|
+
#
|
94
|
+
def use_cache?
|
95
|
+
!! @cachefile
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns a Cache instance for this project.
|
99
|
+
#
|
100
|
+
# @return [Polymer::Cache]
|
101
|
+
#
|
102
|
+
def cache
|
103
|
+
@cache ||= Polymer::Cache.new(@cachefile)
|
104
|
+
end
|
105
|
+
|
106
|
+
private # ================================================================
|
107
|
+
|
108
|
+
# Extracts a path, typically specified in the DSL, and converts it to
|
109
|
+
# an absolute Pathname (by appending it on to +@root+).
|
110
|
+
#
|
111
|
+
# @param [Symbol] key
|
112
|
+
# The option key in which the value is expected.
|
113
|
+
# @param [Hash] options
|
114
|
+
# The options hash passed to #initialize.
|
115
|
+
#
|
116
|
+
# @return [Pathname]
|
117
|
+
# Returns the path appended to +@root+.
|
118
|
+
# @return [false, nil]
|
119
|
+
# When the option value was not a string.
|
120
|
+
#
|
121
|
+
def extract_path(key, options)
|
122
|
+
value = options.fetch(key, DEFAULTS[key])
|
123
|
+
value.is_a?(String) ? @root + value : value
|
124
|
+
end
|
125
|
+
|
126
|
+
# === Class Methods ======================================================
|
127
|
+
|
128
|
+
# Given a path to a directory, +find_config+ attempts to locate a
|
129
|
+
# suitable configuration file by looking for a ".polymer" or "polymer.rb"
|
130
|
+
# file. If no such file is found in the given directory, it ascends the
|
131
|
+
# directory structure until one is found, or it runs out of parent
|
132
|
+
# directories to check.
|
133
|
+
#
|
134
|
+
# If given a path to a file, +find_config+ assumes that this file is the
|
135
|
+
# config, and simply returns it as a Pathname.
|
136
|
+
#
|
137
|
+
# @param [Pathname, String] path
|
138
|
+
# The path to the directory or configuration file.
|
139
|
+
#
|
140
|
+
# @return [Pathname]
|
141
|
+
# The path to the found configuration.
|
142
|
+
#
|
143
|
+
# @raise [Polymer::MissingProject]
|
144
|
+
# Raised when +find_config+ could not find a suitable configuration
|
145
|
+
# file.
|
146
|
+
#
|
147
|
+
def self.find_config(path)
|
148
|
+
path, config_path = Pathname.new(path).expand_path, nil
|
149
|
+
return path if path.file?
|
150
|
+
|
151
|
+
path.ascend do |directory|
|
152
|
+
if (dot_polymer = directory + '.polymer').file?
|
153
|
+
return dot_polymer
|
154
|
+
elsif (polymer_rb = directory + 'polymer.rb').file?
|
155
|
+
return polymer_rb
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
raise MissingProject,
|
160
|
+
"Polymer couldn't find a configuration file at `#{path.to_s}'"
|
161
|
+
end
|
162
|
+
|
163
|
+
end # Project
|
164
|
+
end # Polymer
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Polymer
|
2
|
+
class SassGenerator
|
3
|
+
|
4
|
+
TEMPLATE = Pathname.new(__FILE__).dirname + 'templates/sass_mixins.erb'
|
5
|
+
|
6
|
+
# Given a project, generates a Sass mixin stylesheet which can can be
|
7
|
+
# included into your own Sass stylesheets.
|
8
|
+
#
|
9
|
+
# @param [Polymer::Project] project
|
10
|
+
# The project instance for which to generate a Sass stylesheet.
|
11
|
+
#
|
12
|
+
# @return [true]
|
13
|
+
# Returned when the stylesheet was generated and saved to the location
|
14
|
+
# specified by +project.sass+.
|
15
|
+
# @return [false]
|
16
|
+
# Returned when +project.sass+ evaluates to false, disabling generation
|
17
|
+
# of the Sass mixin file.
|
18
|
+
#
|
19
|
+
def self.generate(project)
|
20
|
+
return false unless project.sass
|
21
|
+
|
22
|
+
if project.sass.to_s[-5..-1] == '.sass'
|
23
|
+
project.sass.dirname.mkpath
|
24
|
+
save_to = project.sass
|
25
|
+
else
|
26
|
+
project.sass.mkpath
|
27
|
+
save_to = project.sass + '_polymer.sass'
|
28
|
+
end
|
29
|
+
|
30
|
+
File.open(save_to, 'w') do |file|
|
31
|
+
file.puts ERB.new(File.read(TEMPLATE), nil, '<>').result(binding)
|
32
|
+
end
|
33
|
+
|
34
|
+
true
|
35
|
+
end # self.generate
|
36
|
+
|
37
|
+
end # SassGenerator
|
38
|
+
end # Polymer
|