C0 code coverage information
Generated on Thu Mar 20 19:37:19 +0100 2008 with rcov 0.8.0
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # == About
2 #
3 # Rainpress is a compressor for CSS. It's written in ruby, but should not be
4 # limited to ruby projects.
5 #
6 # Rainpress does not apply common compression algorithms like gzip, it removes
7 # unnecessary characters and replaces some attributes with a shorter equivalent
8 # name.
9 #
10 # Copyright:: Copyright (c) 2007-2008 Uwe L. Korn
11 #
12 # == License
13 #
14 # Copyright (c) 2007-2008 Uwe L. Korn
15 #
16 # Permission is hereby granted, free of charge, to any person obtaining a copy
17 # of this software and associated documentation files (the "Software"), to deal
18 # in the Software without restriction, including without limitation the rights
19 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 # copies of the Software, and to permit persons to whom the Software is
21 # furnished to do so, subject to the following conditions:
22 #
23 # The above copyright notice and this permission notice shall be included in
24 # all copies or substantial portions of the Software.
25 #
26 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32 # THE SOFTWARE.
33 #
34 # Remark(not part of the license text): This is a MIT-style license
35 #
36 # == Links
37 #
38 # * {Rainpress Website}[http://rainpress.xhochy.com/]
39 # * {SVN repository}[http://code.google.com/p/rainpress/source]
40 # * {Bugtracker}[https://bugs.launchpad.net/rainpress/]
41 # * {Wiki}[http://code.google.com/p/rainpress/w/list]
42 # * {Translations}[https://translations.launchpad.net/rainpress/]
43 # * {XhochY Weblog (for Announcements about Rainpress)}[http://xhochy.org/en/]
44 # * {Mailinglist}[http://groups.google.com/group/xy-oss-projects-discussion]
45 # * {Continous Integration Builds and Tests}[http://cruisecontrol-rb.xhochy.com/builds/rainpress]
46 # * {Freshmeat Record}[http://freshmeat.net/projects/rainpress]
47 # * {Ohloh listing}[http://www.ohloh.net/projects/12620/]
48 module Rainpress
49
50 # == Information
51 #
52 # This is the main class of Rainpress, create an instance of it to compress
53 # your CSS-styles.
54 #
55 # Author:: Uwe L. Korn <uwelk@xhochy.org>
56 #
57 # == Simple Usage
58 #
59 # packer = Rainpress::Packer.new
60 # compressed_style = packer.compress(style)
61 class Packer
62
63 # Use always this functions if you want to compress your CSS-style
64 #
65 # <b>Options:</b>
66 #
67 # * <tt>:preserveComments</tt> - if set to true, comments will not be
68 # removed
69 # * <tt>:preserveNewline</tt> - if set to true, newlines will not be removed
70 # * <tt>:preserveSpaces</tt> - if set to true, spaces will not be removed
71 # * <tt>:preserveColors</tt> - if set to true, colors will not be modified
72 # * <tt>:skipMisc</tt> - if set to true, miscellaneous compression parts
73 # will be skipped
74 def compress(style, options = {})
75 # remove comments
76 style = remove_comments(style) unless options[:preserveComments]
77
78 # remove newlines
79 style = remove_newlines(style) unless options[:preserveNewlines]
80
81 # remove unneeded spaces
82 style = remove_spaces(style) unless options[:preserveSpaces]
83
84 # replace colours with shorter names
85 style = shorten_colors(style) unless options[:preserveColors]
86
87 # make all other things
88 style = do_misc(style) unless options[:skipMisc]
89
90 style
91 end
92
93 # Remove all comments out of the CSS-Document
94 #
95 # Only /* text */ comments are supported.
96 # Attention: If you are doing css hacks for IE using the comment tricks,
97 # they will be removed using this function. Please consider for IE css style
98 # corrections the usage of conditionals comments in your (X)HTML document.
99 def remove_comments(script)
100 input = script
101 script = ''
102
103 while input.length > 0 do
104 pos = input.index("/*");
105
106 # No more comments
107 if pos == nil
108 script += input
109 input = '';
110 else # Comment beginning at pos
111 script += input[0..(pos-1)] if pos > 0 # only append text if there is some
112 input = input[(pos+2)..-1]
113 # Comment ending at pos
114 pos = input.index("*/")
115 input = input[(pos+2)..-1]
116 end
117 end
118
119 # return
120 script
121 end
122
123 # Remove all newline characters
124 #
125 # We take care of Windows(\r\n), Unix(\n) and Mac(\r) newlines.
126 def remove_newlines(script)
127 script.gsub(/\n|\r/,'')
128 end
129
130 # Remove unneeded spaces
131 #
132 # 1. Turn mutiple spaces into a single
133 # 2. Remove spaces around ;:{},
134 # 3. Remove tabs
135 def remove_spaces(script)
136 script = script.gsub(/(\s(\s)+)/, ' ')
137 script = script.gsub(/\s*;\s*/,';')
138 script = script.gsub(/\s*:\s*/,':')
139 script = script.gsub(/\s*\{\s*/,'{')
140 script = script.gsub(/\s*\}\s*/,'}')
141 script = script.gsub(/\s*,\s*/,',')
142 script.gsub("\t",'');
143 end
144
145 # Replace color values with their shorter equivalent
146 #
147 # 1. Turn rgb(,,)-colors into #-values
148 # 2. Shorten #AABBCC down to #ABC
149 # 3. Replace names with their shorter hex-equivalent
150 # * white -> #fff
151 # * black -> #000
152 # 4. Replace #-values with their shorter name
153 # * #f00 -> red
154 def shorten_colors(style)
155 # rgb(50,101,152) to #326598
156 style = style.gsub(/rgb\s*\(\s*([0-9,\s]+)\s*\)/) do |match|
157 out = '#'
158 $1.split(',').each do |num|
159 if num.to_i < 16
160 out += '0'
161 end
162 out += num.to_i.to_s(16) # convert to hex
163 end
164 out
165 end
166 # Convert #AABBCC to #ABC, keep if preceed by a '='
167 style = style.gsub(/([^\"'=\s])(\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/) do |match|
168 out = match
169 if ($3.downcase == $4.downcase) and ($5.downcase == $6.downcase) and ($7.downcase == $8.downcase)
170 out = $1 + '#' + $3.downcase + $5.downcase + $7.downcase
171 end
172 out
173 end
174
175 # At the moment we assume that colours only appear before ';' or '}' and
176 # after a ':', if there could be an occurence of a color before or after
177 # an other character, submit either a bug report or, better, a patch that
178 # enables Rainpress to take care of this.
179
180 # shorten several names to numbers
181 ## shorten white -> #fff
182 style = style.gsub(/:[\s]*white[\s]*;/, ':#fff;')
183 style = style.gsub(/:[\s]*white[\s]*\}/, ':#fff}')
184 ## shorten black -> #000
185 style = style.gsub(/:[\s]*black[\s]*;/, ':#000;')
186 style = style.gsub(/:[\s]*black[\s]*\}/, ':#000}')
187 # shotern several numbers to names
188 ## shorten #f00 or #ff0000 -> red
189 style = style.gsub(/:[\s]*#([fF]00|[fF]{2}0000);/, ':red;')
190 style = style.gsub(/:[\s]*#([fF]00|[fF]{2}0000)\}/, ':red}')
191
192 style
193 end
194
195 # Do miscellaneous compression methods on the style.
196 def do_misc(script)
197 # Replace 0(pt,px,em,%) with 0 but only when preceded by : or a white-space
198 script = script.gsub(/([\s:]+)(0)(px|em|%|in|cm|mm|pc|pt|ex)/) do |match|
199 match.gsub(/(px|em|%|in|cm|mm|pc|pt|ex)/,'')
200 end
201 # Replace :0 0 0 0(;|}) with :0(;|})
202 script = script.gsub(':0 0 0 0;', ':0;')
203 script = script.gsub(':0 0 0 0}', ':0}')
204 # Replace :0 0 0(;|}) with :0(;|})
205 script = script.gsub(':0 0 0;', ':0;')
206 script = script.gsub(':0 0 0}', ':0}')
207 # Replace :0 0(;|}) with :0(;|})
208 script = script.gsub(':0 0}', ':0}')
209 script = script.gsub(':0 0;', ':0;')
210 # Replace background-position:0; with background-position:0 0;
211 script = script.gsub('background-position:0;', 'background-position:0 0;');
212 # Replace 0.6 to .6, but only when preceded by : or a white-space
213 script = script.gsub(/[:\s]0+\.(\d+)/) do |match|
214 match.sub('0', '') # only first '0' !!
215 end
216 # Replace multiple ';' with a single ';'
217 script = script.gsub(/[;]+/, ';')
218 # Replace ;} with }
219 script = script.gsub(';}', '}')
220 # Replace background-color: with background:
221 script = script.gsub('background-color:', 'background:')
222 # Replace font-weight:normal; with 400
223 script = script.gsub(/font-weight[\s]*:[\s]*normal[\s]*;/,'font-weight:400;')
224 script = script.gsub(/font-weight[\s]*:[\s]*normal[\s]*\}/,'font-weight:400}')
225 script = script.gsub(/font[\s]*:[\s]*normal[\s;\}]*/) do |match|
226 match.sub('normal', '400')
227 end
228 # Replace font-weight:bold; with 700
229 script = script.gsub(/font-weight[\s]*:[\s]*bold[\s]*;/,'font-weight:700;')
230 script = script.gsub(/font-weight[\s]*:[\s]*bold[\s]*\}/,'font-weight:700}')
231 script = script.gsub(/font[\s]*:[\s]*bold[\s;\}]*/) do |match|
232 match.sub('bold', '700')
233 end
234
235 script
236 end
237
238 end
239
240 end
Generated using the rcov code coverage analysis tool for Ruby version 0.8.0.