cssdryer2 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ === 0.1 / 2009-04-17
2
+
3
+ * Initial version
data/Manifest.txt ADDED
@@ -0,0 +1,18 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ USAGE.markdown
6
+ generators/css_dryer/css_dryer_generator.rb
7
+ generators/css_dryer/templates/css_dryer_2.rake
8
+ lib/css_dryer_2.rb
9
+ lib/css_dryer_2/files_handler.rb
10
+ lib/css_dryer_2/ncss_handler.rb
11
+ lib/css_dryer_2/processor.rb
12
+ lib/css_dryer_2/stylesheets_helper.rb
13
+ spec/example.ncss
14
+ spec/lib/css_dryer_test.rb
15
+ spec/lib/files_handler_spec.rb
16
+ spec/lib/ncss_handler_spec.rb
17
+ spec/spec.opts
18
+ spec/spec_helper.rb
data/README.txt ADDED
@@ -0,0 +1,95 @@
1
+ == DESCRIPTION:
2
+
3
+ This gem is based on Rails plugin 'css_dryer': http://github.com/airblade/css_dryer.
4
+ Unlike 'css_dryer', this one doesn't create any controllers and views.
5
+ Instead, it acts more like SASS, but uses css_dryer parser (which allows you to use completely
6
+ conventional css-syntax and write one-line css rules).
7
+
8
+ * Read 'install' section to find out how to use it with Rails or any other Ruby appplication.
9
+ * Read USAGE.markdown file to learn about css_dryer parser (copypasted from css_dryer README).
10
+
11
+ == REQUIREMENTS:
12
+
13
+ * ActiveResource gem
14
+
15
+ == INSTALL:
16
+
17
+ 1)
18
+
19
+ sudo gem install css_dryer_2
20
+
21
+ if from GitHub:
22
+
23
+ sudo gem sources -a http://gems.github.com
24
+ sudo gem install snitko-css_dryer_2
25
+
26
+ 2) If you're planning to use it with rails application, then
27
+ go to rails application folder and run 'script/generate css_dryer'.
28
+ This will generate neccessary rake tasks.
29
+
30
+ 3) Put this is config/environments/development.rb:
31
+
32
+ require 'css_dryer_2'
33
+
34
+ 4) In dev environment, to generate css on any changes in .ncss files, put this in ApplicationController:
35
+
36
+ before_filter :ncss
37
+ def ncss
38
+ CssDryer2::FilesHandler.new(:settings => :rails).run if RAILS_ENV == 'development'
39
+ end
40
+
41
+ You can also set custom directories for files, instead of using rails shortcut option:
42
+
43
+ CssDryer2::FilesHandler.new(
44
+ :source_path => 'my_css_dir/ncss',
45
+ :compile_path => 'my_css_dir',
46
+ :tmp_path => '/tmp',
47
+ :force_compile => true
48
+ )
49
+
50
+
51
+ 5) While rails application to production, run rake task:
52
+
53
+ rake ncss:compile
54
+
55
+ 6) Now put your .ncss files in your 'public/stylesheets/ncss/' dir.
56
+ The compiler will put generated css files in 'public/stylesheets/' dir.
57
+
58
+
59
+ == HOW IT WORKS:
60
+
61
+ When you fire 'run' method, CssDryer2::FileHandler object checks if the .ncss files
62
+ changed (it stores their SHA1 in tmp dir). If they did, it recompiles them.
63
+
64
+ For Rails application it assumes that you store your .ncss files in 'public/stylesheets/ncss',
65
+ and it compiles .css files in 'public/stylesheets'.
66
+ You might want to add 'public/stylesheets/*.css' into your '.gitignore' file
67
+
68
+ You can force reompile by providing the run method with':force_recompile => true' argument.
69
+ You can also recompile at any time by running 'rake ncss:compile'
70
+
71
+
72
+ == LICENSE:
73
+
74
+ (The MIT License)
75
+
76
+ Copyright (c) 2009
77
+
78
+ Permission is hereby granted, free of charge, to any person obtaining
79
+ a copy of this software and associated documentation files (the
80
+ 'Software'), to deal in the Software without restriction, including
81
+ without limitation the rights to use, copy, modify, merge, publish,
82
+ distribute, sublicense, and/or sell copies of the Software, and to
83
+ permit persons to whom the Software is furnished to do so, subject to
84
+ the following conditions:
85
+
86
+ The above copyright notice and this permission notice shall be
87
+ included in all copies or substantial portions of the Software.
88
+
89
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
90
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
91
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
92
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
93
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
94
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
95
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require File.dirname(__FILE__) + '/lib/css_dryer_2'
4
+
5
+ def generate_gemspec(options = {})
6
+ files = list_files.map { |i| "\"#{i}\"" }
7
+ test_files = list_testfiles.map { |i| "\"#{i}\"" }
8
+ gemspec = File.read('gemspec.template')
9
+ gemspec.sub!('$files', "[#{files.join(', ')}]")
10
+ gemspec.sub!('$test_files', "[#{test_files.join(', ')}]")
11
+ return "Gem::Specification.new do |s|\n" + gemspec + "\nend" if options[:in_block]
12
+ gemspec
13
+ end
14
+
15
+ def list_files
16
+ files = FileList["{lib}/**/*", "{generators}/**/*"]
17
+ end
18
+ def list_testfiles
19
+ test_files = FileList["spec/**/*"]
20
+ end
21
+
22
+ spec = eval(generate_gemspec(:in_block => true))
23
+
24
+ Hoe.new('cssdryer2', '0.1') do |s|
25
+ s.rubyforge_name = 'cssdryer2'
26
+ s.developer('Roman Snitko', 'roman@snitko.ru')
27
+ end
28
+
29
+ Rake::GemPackageTask.new(spec) do |pkg|
30
+ pkg.need_tar = true
31
+ File.open('css_dryer_2.gemspec', 'w') { |f| f.puts generate_gemspec }
32
+ end
33
+
34
+ task :generate_gemspec do
35
+ File.open('css_dryer_2.gemspec', 'w') { |f| f.puts generate_gemspec }
36
+ `cd #{File.dirname(__FILE__)} && rake check_manifest | patch`
37
+ end
data/USAGE.markdown ADDED
@@ -0,0 +1,190 @@
1
+ This is a copypaste of README from http://github.com/airblade/css_dryer
2
+
3
+ # CssDryer -- Eliminate Repetition In Your Stylesheets
4
+ ## Introduction
5
+
6
+ Cascading style sheets (CSS) are wonderful but repetitive. [Repetition is bad](http://en.wikipedia.org/wiki/Don't_repeat_yourself), so CssDryer lets you write CSS without repeating yourself. And you don't need to learn any new syntax.
7
+
8
+ There are two sources of repetition in CSS:
9
+
10
+ * nested selectors
11
+ * lack of variables
12
+
13
+ Nested selectors lead to CSS like this:
14
+
15
+ div { font-family: Verdana; }
16
+ div#content { background-color: green; }
17
+ div#content p { color: red; }
18
+
19
+ Note the triple repetition of `div` and the double repetition of `#content`.
20
+
21
+ The lack of variables leads to CSS like this:
22
+
23
+ .sidebar { border: 1px solid #fefefe; }
24
+ .content { color: #fefefe; }
25
+
26
+ Note the repeated colour `#fefefe`.
27
+
28
+ CssDryer eliminates both of these. The examples above become:
29
+
30
+ <% dark_grey = '#fefefe' %>
31
+
32
+ div {
33
+ font-family: Verdana;
34
+ #content {
35
+ background-color: green;
36
+ p { color: red; }
37
+ }
38
+ }
39
+
40
+ .sidebar { border: 1 px solid <%= dark_grey %>; }
41
+ .content { color: <%= dark_grey %>; }
42
+
43
+ Note, though, that `@media` blocks are preserved. For example:
44
+
45
+ @media screen, projection {
46
+ div {font-size:100%;}
47
+ }
48
+
49
+ is left unchanged.
50
+
51
+ The original whitespace is preserved as much as possible.
52
+
53
+
54
+ ## Which Selectors Are Supported?
55
+
56
+ CssDryer handles all [CSS 2.1 selectors](http://www.w3.org/TR/CSS21/selector.html): nested descendant, child, adjacent, class, pseudo-class, attribute and id selectors.
57
+
58
+ Multiple comma separated selectors are also supported.
59
+
60
+
61
+ ## Comments
62
+
63
+ Comments on nested selectors do not get 'flattened' or de-nested with their selector. For example comment B will be left inside the html selector below:
64
+
65
+ Before:
66
+
67
+ /* Comment A */
68
+ html {
69
+ /* Comment B */
70
+ p {
71
+ color: blue;
72
+ }
73
+ }
74
+
75
+ After:
76
+
77
+ /* Comment A */
78
+ html {
79
+ /* Comment B */
80
+ }
81
+ html p {
82
+ color: blue;
83
+ }
84
+
85
+ This is suboptimal but I hope not too inconvenient.
86
+
87
+ Please also note that commas in comments will sometimes be replaced with a space. This is due to a shameful hack in the code that handles comma-separated selectors.
88
+
89
+
90
+ ## Partials
91
+
92
+ You may use partial nested stylesheets as you would with normal templates. For example, assuming your controller(s) set the @user variable and a User has a background colour (red):
93
+
94
+ app/views/stylesheets/site.css.ncss:
95
+
96
+ body {
97
+ color: blue;
98
+ <%= render :partial => 'content', :locals => {:background => @user.background} %>
99
+ }
100
+
101
+ app/views/stylesheets/_content.css.ncss:
102
+
103
+ div#content {
104
+ background: <%= background %>;
105
+ margin: 10px;
106
+ }
107
+
108
+ And all this would render to `site.css`:
109
+
110
+ body {
111
+ color: blue;
112
+ }
113
+ body div#content {
114
+ background: red;
115
+ margin: 10px;
116
+ }
117
+
118
+
119
+ ## Remember the helper
120
+
121
+ Browser hacks are an ugly necessity in any non-trivial stylesheet. They clutter up your stylesheet without actually adding anything. They make you sad.
122
+
123
+ So encapsulate them in the StylesheetsHelper instead. Separate your lovely CSS from the decidely unlovely hacks. For example:
124
+
125
+ app/views/stylesheets/site.css.ncss:
126
+
127
+ <% ie7 do %>
128
+ #sidebar {
129
+ padding: 4px;
130
+ }
131
+ <% end %>
132
+
133
+ This renders to `site.css`:
134
+
135
+ *+html #sidebar {
136
+ padding: 4px;
137
+ }
138
+
139
+ In this example the hacky selector, `*+html`, isn't too bad. However some hacks are pretty long-winded, and soon you'll thank yourself for moving them out of your nested stylesheet.
140
+
141
+ You don't have to limit yourself to browser hacks. Consider self-clearing: to make an element clear itself requires 13 lines of CSS, in 3 selector blocks, by my count. To make a second element clear itself, you need to add the element's selector to each of those three blocks. It's fiddly. And your stylesheet gets harder and harder to understand.
142
+
143
+ We can do better:
144
+
145
+ <%= self_clear 'div.foo', 'div.bar', 'baz' %>
146
+
147
+ Self-clear as many elements as you like in one easy line.
148
+
149
+ ## Alternatives
150
+
151
+ * [RCSS][1]: ERB, server-side constants, server-side classes and command line execution. No nesting as such, though server-side classes offer a form of inheritance.
152
+
153
+ * [DCSS][2] (written up [here][3]): server-side constants, different syntax. Descendant selectors only.
154
+
155
+ * [Styleaby][4] creates CSS with Ruby syntax. "An experimental, unauthorized mashup of Scott Barron's stillborn Builder::CSS templates and Why The Lucky Stiff's Markaby templates."
156
+
157
+ * [Dirt Simple .rcss Templates][5] by Josh Susser. No nesting, just variables.
158
+
159
+ [1]: http://rubyforge.org/projects/rcss
160
+ [2]: http://rubyforge.org/projects/dcss
161
+ [3]: http://myles.id.au/2006/11/20/introducing-dcss/
162
+ [4]: http://topfunky.net/svn/plugins/styleaby/README
163
+ [5]: http://blog.hasmanythrough.com/2006/3/23/dirt-simple-rcss-templates
164
+
165
+
166
+ ## Credits
167
+
168
+ The idea came from John Nunemaker on [Rails Tips][6]. John beta-tested the code, provided a test case for @media blocks and suggested the controller's body. Thanks John!
169
+
170
+ The caching code is based on [Topfunky's][7].
171
+
172
+ Changing the controller's name to `stylesheets`, thus allowing one to use Rails' `stylesheet_link_tag` helper, occurred to me while reading Josh Susser's [Dirt Simple .rcss Templates][5]. Once I noticed it, I realised everybody was using a `StylesheetsController`. Doh!
173
+
174
+ [6]: http://railstips.org/2006/12/7/styleaby-css-plugin/
175
+ [7]: http://topfunky.net/svn/plugins/styleaby/lib/stylesheets_controller.rb
176
+
177
+
178
+ ## Author
179
+
180
+ [Andrew Stewart][8], [AirBlade Software Ltd][9].
181
+
182
+ [8]: mailto:boss@airbladesoftware.com
183
+ [9]: http://airbladesoftware.com
184
+
185
+
186
+ ## Licence
187
+
188
+ CssDryer is available under the MIT licence. See MIT-LICENCE for the details.
189
+
190
+ Copyright (c) 2006-2008 Andrew Stewart
@@ -0,0 +1,16 @@
1
+ require 'rbconfig'
2
+
3
+ class CssDryerGenerator < Rails::Generator::Base
4
+
5
+ def initialize(runtime_args, runtime_options = {})
6
+ Dir.mkdir('lib/tasks') unless File.directory?('lib/tasks')
7
+ super
8
+ end
9
+
10
+ def manifest
11
+ record do |m|
12
+ m.file "css_dryer_2.rake", "lib/tasks/css_dryer_2.rake"
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,10 @@
1
+ require 'css_dryer_2'
2
+
3
+ namespace(:ncss) do
4
+
5
+ desc "compile ncss files into css"
6
+ task :compile do
7
+ CssDryer2::FilesHandler.new(:force_compile => true, :settings => :rails).run
8
+ end
9
+
10
+ end
@@ -0,0 +1,63 @@
1
+ require 'digest'
2
+
3
+ module CssDryer2
4
+ # This module is included in rake task or
5
+ # anywhere (for example ApplicationController of Rails app)
6
+ # you need to choose when and which files are compiled.
7
+ class FilesHandler
8
+
9
+ attr_accessor :source_path, :compile_path, :tmp_path, :force_compile
10
+
11
+ def initialize(params = {})
12
+
13
+ @force_compile = false
14
+
15
+ if params[:settings] == :rails
16
+ @source_path = "#{RAILS_ROOT}/public/stylesheets/ncss"
17
+ @compile_path = "#{RAILS_ROOT}/public/stylesheets"
18
+ @tmp_path = "#{RAILS_ROOT}/tmp"
19
+ end
20
+
21
+ @source_path = params[:source_path] if params[:source_path]
22
+ @compile_path = params[:compile_path] if params[:compile_path]
23
+ @tmp_path ||= params[:tmp_path] || Dir.tmpdir + '/css_dryer_2_gem/tmp'
24
+
25
+
26
+ unless @source_path or @compile_path or @tmp_path
27
+ raise "You have to set source_path, compile_path and tmp_path"
28
+ end
29
+
30
+ FileUtils.mkdir_p(@tmp_path + '/css_dryer_2') unless File.exist?(@tmp_path + '/css_dryer_2')
31
+ end
32
+
33
+ def run(params = {})
34
+ files = Dir.new(@source_path + '/').entries
35
+ files.delete_if { |f| !File.file?(@source_path + "/#{f}") or !(f =~ /.ncss$/) }
36
+ files.each { |f| prepare_file(f, params[:force_compile] || @force_compile) }
37
+ end
38
+
39
+ def self.configure
40
+ yield(self)
41
+ end
42
+
43
+ private
44
+
45
+ def prepare_file(file, force_compile)
46
+
47
+ ncss = File.read(@source_path + "/#{file}")
48
+ hashed_content = Digest::SHA1.hexdigest(ncss)
49
+
50
+ # Check if the file has been updated since the last run
51
+ if File.exist?(@tmp_path + "/css_dryer_2/#{file}")
52
+ prev_hashed_content = File.read(@tmp_path + "/css_dryer_2/#{file}")
53
+ return if prev_hashed_content == hashed_content and !@force_compile
54
+ end
55
+
56
+ ncss = File.read(@source_path + "/#{file}")
57
+ css = CssDryer2::NcssHandler.new.compile(ncss)
58
+ File.open(@compile_path + "/#{file.sub(/.ncss$/, '.css')}", 'w') { |f| f.write(css) }
59
+ File.open(@tmp_path + "/css_dryer_2/#{file}", 'w') { |f| f.write(hashed_content) }
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,19 @@
1
+ # Handler for DRY stylesheets which can be registered with Rails
2
+ # as a new templating system.
3
+ #
4
+ # DRY stylesheets are piped through ERB and then CssDryer#process.
5
+ module CssDryer2
6
+
7
+ class NcssHandler
8
+ include CssDryer::Processor
9
+ # In case user doesn't have helper or hasn't run generator yet.
10
+ include StylesheetsHelper rescue nil
11
+
12
+ def compile(template)
13
+ output_buffer = String.new
14
+ erb_compiled_template = ERB.new(template, nil, nil, "@output_buffer").result(binding)
15
+ process(erb_compiled_template)
16
+ end
17
+ end
18
+
19
+ end