csses 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ == 1.0.0 / 2008-01-03
2
+
3
+ * 1 major enhancement
4
+ * Initial release as a gem!
@@ -0,0 +1,22 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/csses.rb
6
+ lib/csses_helpers.rb
7
+ rails_generators/csses/USAGE
8
+ rails_generators/csses/csses_generator.rb
9
+ rails_generators/csses/templates/application.css.erb
10
+ tasks/annotations.rake
11
+ tasks/doc.rake
12
+ tasks/gem.rake
13
+ tasks/manifest.rake
14
+ tasks/rubyforge.rake
15
+ tasks/setup.rb
16
+ tasks/spec.rake
17
+ tasks/test.rake
18
+ test/test_csses.rb
19
+ test/test_csses_helpers.rb
20
+ test/test_site/test_no_parens.html.erb
21
+ test/test_site/test_unless.html.erb
22
+ test/test_site/view.html.erb
@@ -0,0 +1,74 @@
1
+ csses
2
+ by Chris Shea
3
+ http://ruby.tie-rack.org/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Generate a clean CSS file based on your Rails view and helpers.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * All HTML elements handled
12
+ * Most Rails HTML helper methods handled
13
+ * Probably not perfect, but does a lot you would rather not have to
14
+ * Doesn't update the generated CSS, but soon it will
15
+
16
+ == SYNOPSIS:
17
+ In your RAILS_ROOT, run <tt>script/generate css</tt>
18
+
19
+ And it takes this:
20
+ <h1 id="pomp">The Grand Demonstration</h1>
21
+ <p class="wing">Super Mario Bros. 3 reference</p>
22
+ <%= image_tag('joy.png', :class => 'happy') %>
23
+ <%= link_to('Read', {:action => :read, :id => 4}, {:id => 'four'}) %>
24
+ <!-- and it works for form tags too -->
25
+
26
+ and makes this:
27
+ a {}
28
+ a:visited {}
29
+ a:hover {}
30
+ a:active {}
31
+ a#four {}
32
+ a#four:visited {}
33
+ a#four:hover {}
34
+ a#four:active {}
35
+ h1 {}
36
+ h1#pomp {}
37
+ img {}
38
+ img.happy {}
39
+ p {}
40
+ p.wing {}
41
+
42
+ == REQUIREMENTS:
43
+
44
+ * Rails 2.x
45
+ * HTML, raw or generated, in your views and helpers
46
+
47
+ == INSTALL:
48
+
49
+ * sudo gem install csses
50
+
51
+ == LICENSE:
52
+
53
+ (The MIT License)
54
+
55
+ Copyright (c) 2008 Christopher Shea
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining
58
+ a copy of this software and associated documentation files (the
59
+ 'Software'), to deal in the Software without restriction, including
60
+ without limitation the rights to use, copy, modify, merge, publish,
61
+ distribute, sublicense, and/or sell copies of the Software, and to
62
+ permit persons to whom the Software is furnished to do so, subject to
63
+ the following conditions:
64
+
65
+ The above copyright notice and this permission notice shall be
66
+ included in all copies or substantial portions of the Software.
67
+
68
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
69
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
70
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
71
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
72
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
73
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
74
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,23 @@
1
+ # Look in the tasks/setup.rb file for the various options that can be
2
+ # configured in this Rakefile. The .rake files in the tasks directory
3
+ # are where the options are used.
4
+
5
+ load 'tasks/setup.rb'
6
+
7
+ ensure_in_path 'lib'
8
+ require 'csses'
9
+
10
+ task :default => 'spec:run'
11
+
12
+ PROJ.name = 'csses'
13
+ PROJ.summary = 'Generate a CSS slate for your Rails applications'
14
+ PROJ.authors = 'Chris Shea'
15
+ PROJ.email = 'chris@ruby.tie-rack.org'
16
+ PROJ.url = 'http://csses.rubyforge.org'
17
+ PROJ.description = paragraphs_of('README.txt', 1).join("\n\n")
18
+ PROJ.changes = paragraphs_of('History.txt', 0..1).join("\n\n")
19
+ PROJ.rubyforge_name = 'csses'
20
+
21
+ PROJ.spec_opts << '--color'
22
+
23
+ # EOF
@@ -0,0 +1,68 @@
1
+ # Ah... CSSes...
2
+
3
+ require 'csses_helpers'
4
+
5
+ # The CSSes class takes some files, figures out what HTML is referenced
6
+ # or generated in them, and puts those all into an array called elements.
7
+ class CSSes
8
+ VERSION = '1.0.0'
9
+
10
+ UNFASHIONABLE_ELEMENTS = %w(html head meta title)
11
+ RAILS_HELPERS = { /\blink_to\w*\b/ => 'a',
12
+ /\bimage_tag\b/ => 'img',
13
+ /\blabel\b/ => 'label',
14
+ /\bform(?:_(?:for|tag))\b/ => 'form',
15
+ /\btext_area(?:_tag)?\b/ => 'textarea',
16
+ /\btext_field(?:_tag)?\b/ => 'input',
17
+ /\bcheck_box_tag\b/ => 'input',
18
+ /\bfield_set_tag\b/ => 'fieldset',
19
+ /\bfile_field_tag\b/ => 'input',
20
+ /\bimage_submit_tag\b/ => 'input',
21
+ /\bpassword_field_tag\b/ => 'input',
22
+ /\bradio_button_tag\b/ => 'input',
23
+ /\bselect_tag\b/ => 'select',
24
+ /\bsubmit_tag\b/ => 'input' }
25
+ RAILS_HTML_ID_OR_CLASS = /(?::(id|class))\s*=>\s*['"](\w+)['"]/
26
+
27
+ attr_reader :elements
28
+
29
+ # Give it a list of files as an array (not splatted), get back, well,
30
+ # a CSS object, but one with an array of CSS elements as an attribute.
31
+ def initialize(files)
32
+ @elements = []
33
+ files.each do |file|
34
+ source = File.read(file)
35
+ @elements << source.scan(/<(\w+)/)
36
+ source.scan(/<(\w+)\s+[^>]*(class|id)="(\w+)"/).each do |elem|
37
+ @elements << "#{elem[0]}#{css_sym_for_attribute(elem[1])}#{elem[2]}"
38
+ end
39
+ RAILS_HELPERS.each do |regex, tag|
40
+ source.scan(/#{regex}.*/).each do |line|
41
+ if line.match(RAILS_HTML_ID_OR_CLASS)
42
+ @elements << "#{tag}#{css_sym_for_attribute($1)}#{$2}"
43
+ end
44
+ @elements << tag
45
+ end
46
+ end
47
+ end
48
+
49
+ @elements.flatten!
50
+ @elements.uniq!
51
+ @elements.sort!
52
+ @elements -= UNFASHIONABLE_ELEMENTS
53
+
54
+ apply_pseudo_classes!
55
+ end
56
+
57
+ private
58
+
59
+ # Generates the typical pseudo-classes for anchors (visited, hover, active).
60
+ def apply_pseudo_classes!
61
+ @elements.each_with_index do |e, i|
62
+ if e.match(/\Aa(?:[#\.]\w+)?/)
63
+ @elements[i] = [e, "#{e}:visited", "#{e}:hover", "#{e}:active"]
64
+ end
65
+ end
66
+ @elements.flatten!
67
+ end
68
+ end
@@ -0,0 +1,15 @@
1
+ # Assuming there will be more than one method here one day,
2
+ # this file is called csses_helpers.rb.
3
+
4
+ # You know how CSS selectors use the octothorpe for IDs
5
+ # and the dot for classes? This translates that.
6
+ def css_sym_for_attribute(attribute)
7
+ case attribute
8
+ when 'id'
9
+ '#'
10
+ when 'class'
11
+ '.'
12
+ else
13
+ raise ArgumentError
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Generates public/stylesheets/application.css based on the appearance
3
+ of html elements in your views and helpers.
4
+
5
+ Example:
6
+ ./script/generate css
7
+
8
+ This will create:
9
+ public/stylesheets/application.css
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + '../../lib')
2
+
3
+ require 'csses'
4
+ class CssesGenerator < Rails::Generator::Base
5
+ attr_reader :css
6
+
7
+ def initialize(*args)
8
+ super
9
+ files_to_scan = Dir.glob('app/views/**/*.erb') + Dir.glob('app/helpers/*.rb')
10
+ @css = CSSes.new(files_to_scan)
11
+ end
12
+
13
+ def manifest
14
+ record do |m|
15
+ m.directory "public/stylesheets"
16
+ m.template 'application.css.erb', 'public/stylesheets/application.css'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,4 @@
1
+ <% css.elements.each do |element| -%>
2
+ <%= element %> {}
3
+
4
+ <% end -%>
@@ -0,0 +1,30 @@
1
+ # $Id$
2
+
3
+ if HAVE_BONES
4
+
5
+ desc "Enumerate all annotations"
6
+ task :notes do
7
+ Bones::AnnotationExtractor.enumerate(
8
+ PROJ, "OPTIMIZE|FIXME|TODO", :tag => true)
9
+ end
10
+
11
+ namespace :notes do
12
+ desc "Enumerate all OPTIMIZE annotations"
13
+ task :optimize do
14
+ Bones::AnnotationExtractor.enumerate(PROJ, "OPTIMIZE")
15
+ end
16
+
17
+ desc "Enumerate all FIXME annotations"
18
+ task :fixme do
19
+ Bones::AnnotationExtractor.enumerate(PROJ, "FIXME")
20
+ end
21
+
22
+ desc "Enumerate all TODO annotations"
23
+ task :todo do
24
+ Bones::AnnotationExtractor.enumerate(PROJ, "TODO")
25
+ end
26
+ end
27
+
28
+ end # if HAVE_BONES
29
+
30
+ # EOF
@@ -0,0 +1,49 @@
1
+ # $Id$
2
+
3
+ require 'rake/rdoctask'
4
+
5
+ namespace :doc do
6
+
7
+ desc 'Generate RDoc documentation'
8
+ Rake::RDocTask.new do |rd|
9
+ rd.main = PROJ.rdoc_main
10
+ rd.options << '-d' if !WIN32 and `which dot` =~ %r/\/dot/
11
+ rd.rdoc_dir = PROJ.rdoc_dir
12
+
13
+ incl = Regexp.new(PROJ.rdoc_include.join('|'))
14
+ excl = Regexp.new(PROJ.rdoc_exclude.join('|'))
15
+ files = PROJ.files.find_all do |fn|
16
+ case fn
17
+ when excl; false
18
+ when incl; true
19
+ else false end
20
+ end
21
+ rd.rdoc_files.push(*files)
22
+
23
+ title = "#{PROJ.name}-#{PROJ.version} Documentation"
24
+ title = "#{PROJ.rubyforge_name}'s " + title if PROJ.rubyforge_name != title
25
+
26
+ rd.options << "-t #{title}"
27
+ end
28
+
29
+ desc 'Generate ri locally for testing'
30
+ task :ri => :clobber_ri do
31
+ sh "#{RDOC} --ri -o ri ."
32
+ end
33
+
34
+ desc 'Remove ri products'
35
+ task :clobber_ri do
36
+ rm_r 'ri' rescue nil
37
+ end
38
+
39
+ end # namespace :doc
40
+
41
+ desc 'Alias to doc:rdoc'
42
+ task :doc => 'doc:rdoc'
43
+
44
+ desc 'Remove all build products'
45
+ task :clobber => %w(doc:clobber_rdoc doc:clobber_ri)
46
+
47
+ remove_desc_for_task %w(doc:clobber_rdoc doc:clobber_ri)
48
+
49
+ # EOF
@@ -0,0 +1,89 @@
1
+ # $Id$
2
+
3
+ require 'rake/gempackagetask'
4
+
5
+ namespace :gem do
6
+
7
+ PROJ.spec = Gem::Specification.new do |s|
8
+ s.name = PROJ.name
9
+ s.version = PROJ.version
10
+ s.summary = PROJ.summary
11
+ s.authors = Array(PROJ.authors)
12
+ s.email = PROJ.email
13
+ s.homepage = Array(PROJ.url).first
14
+ s.rubyforge_project = PROJ.rubyforge_name
15
+
16
+ s.description = PROJ.description
17
+
18
+ PROJ.dependencies.each do |dep|
19
+ s.add_dependency(*dep)
20
+ end
21
+
22
+ s.files = PROJ.files
23
+ s.executables = PROJ.executables.map {|fn| File.basename(fn)}
24
+ s.extensions = PROJ.files.grep %r/extconf\.rb$/
25
+
26
+ s.bindir = 'bin'
27
+ dirs = Dir["{#{PROJ.libs.join(',')}}"]
28
+ s.require_paths = dirs unless dirs.empty?
29
+
30
+ incl = Regexp.new(PROJ.rdoc_include.join('|'))
31
+ excl = PROJ.rdoc_exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
32
+ excl = Regexp.new(excl.join('|'))
33
+ rdoc_files = PROJ.files.find_all do |fn|
34
+ case fn
35
+ when excl; false
36
+ when incl; true
37
+ else false end
38
+ end
39
+ s.rdoc_options = PROJ.rdoc_opts + ['--main', PROJ.rdoc_main]
40
+ s.extra_rdoc_files = rdoc_files
41
+ s.has_rdoc = true
42
+
43
+ if test ?f, PROJ.test_file
44
+ s.test_file = PROJ.test_file
45
+ else
46
+ s.test_files = PROJ.tests.to_a
47
+ end
48
+
49
+ # Do any extra stuff the user wants
50
+ # spec_extras.each do |msg, val|
51
+ # case val
52
+ # when Proc
53
+ # val.call(s.send(msg))
54
+ # else
55
+ # s.send "#{msg}=", val
56
+ # end
57
+ # end
58
+ end
59
+
60
+ desc 'Show information about the gem'
61
+ task :debug do
62
+ puts PROJ.spec.to_ruby
63
+ end
64
+
65
+ Rake::GemPackageTask.new(PROJ.spec) do |pkg|
66
+ pkg.need_tar = PROJ.need_tar
67
+ pkg.need_zip = PROJ.need_zip
68
+ end
69
+
70
+ desc 'Install the gem'
71
+ task :install => [:clobber, :package] do
72
+ sh "#{SUDO} #{GEM} install pkg/#{PROJ.spec.file_name}"
73
+ end
74
+
75
+ desc 'Uninstall the gem'
76
+ task :uninstall do
77
+ sh "#{SUDO} #{GEM} uninstall -v '#{PROJ.version}' #{PROJ.name}"
78
+ end
79
+
80
+ end # namespace :gem
81
+
82
+ desc 'Alias to gem:package'
83
+ task :gem => 'gem:package'
84
+
85
+ task :clobber => 'gem:clobber_package'
86
+
87
+ remove_desc_for_task %w(gem:clobber_package)
88
+
89
+ # EOF
@@ -0,0 +1,41 @@
1
+ # $Id$
2
+
3
+ require 'find'
4
+
5
+ namespace :manifest do
6
+
7
+ desc 'Verify the manifest'
8
+ task :check do
9
+ fn = 'Manifest.tmp'
10
+ files = []
11
+ exclude = Regexp.new(PROJ.exclude.join('|'))
12
+ Find.find '.' do |path|
13
+ path.sub! %r/^(\.\/|\/)/o, ''
14
+ next unless test ?f, path
15
+ next if path =~ exclude
16
+ files << path
17
+ end
18
+
19
+ File.open(fn, 'w') {|fp| fp.puts files.sort}
20
+ system "#{DIFF} -du Manifest.txt #{fn}"
21
+ rm fn rescue nil
22
+ end
23
+
24
+ desc 'Create a new manifest'
25
+ task :create do
26
+ fn = 'Manifest.txt'
27
+ files = []
28
+ exclude = Regexp.new(PROJ.exclude.join('|'))
29
+ Find.find '.' do |path|
30
+ path.sub! %r/^(\.\/|\/)/o, ''
31
+ next unless test ?f, path
32
+ next if path =~ exclude
33
+ files << path
34
+ end
35
+
36
+ files << fn unless test ?f, fn
37
+ File.open(fn, 'w') {|fp| fp.puts files.sort}
38
+ end
39
+ end
40
+
41
+ # EOF
@@ -0,0 +1,57 @@
1
+ # $Id$
2
+
3
+ if PROJ.rubyforge_name && HAVE_RUBYFORGE
4
+
5
+ require 'rubyforge'
6
+ require 'rake/contrib/sshpublisher'
7
+
8
+ namespace :gem do
9
+ desc 'Package and upload to RubyForge'
10
+ task :release => [:clobber, :package] do |t|
11
+ v = ENV['VERSION'] or abort 'Must supply VERSION=x.y.z'
12
+ abort "Versions don't match #{v} vs #{PROJ.version}" if v != PROJ.version
13
+ pkg = "pkg/#{PROJ.spec.full_name}"
14
+
15
+ if $DEBUG then
16
+ puts "release_id = rf.add_release #{PROJ.rubyforge_name.inspect}, #{PROJ.name.inspect}, #{PROJ.version.inspect}, \"#{pkg}.tgz\""
17
+ puts "rf.add_file #{PROJ.rubyforge_name.inspect}, #{PROJ.name.inspect}, release_id, \"#{pkg}.gem\""
18
+ end
19
+
20
+ rf = RubyForge.new
21
+ puts 'Logging in'
22
+ rf.login
23
+
24
+ c = rf.userconfig
25
+ c['release_notes'] = PROJ.description if PROJ.description
26
+ c['release_changes'] = PROJ.changes if PROJ.changes
27
+ c['preformatted'] = true
28
+
29
+ files = [(PROJ.need_tar ? "#{pkg}.tgz" : nil),
30
+ (PROJ.need_zip ? "#{pkg}.zip" : nil),
31
+ "#{pkg}.gem"].compact
32
+
33
+ puts "Releasing #{PROJ.name} v. #{PROJ.version}"
34
+ rf.add_release PROJ.rubyforge_name, PROJ.name, PROJ.version, *files
35
+ end
36
+ end # namespace :gem
37
+
38
+
39
+ namespace :doc do
40
+ desc "Publish RDoc to RubyForge"
41
+ task :release => %w(doc:clobber_rdoc doc:rdoc) do
42
+ config = YAML.load(
43
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
44
+ )
45
+
46
+ host = "#{config['username']}@rubyforge.org"
47
+ remote_dir = "/var/www/gforge-projects/#{PROJ.rubyforge_name}/"
48
+ remote_dir << PROJ.rdoc_remote_dir || PROJ.name
49
+ local_dir = PROJ.rdoc_dir
50
+
51
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
52
+ end
53
+ end # namespace :doc
54
+
55
+ end # if HAVE_RUBYFORGE
56
+
57
+ # EOF
@@ -0,0 +1,144 @@
1
+ # $Id$
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'fileutils'
6
+ require 'ostruct'
7
+
8
+ PROJ = OpenStruct.new
9
+
10
+ PROJ.name = nil
11
+ PROJ.summary = nil
12
+ PROJ.description = nil
13
+ PROJ.changes = nil
14
+ PROJ.authors = nil
15
+ PROJ.email = nil
16
+ PROJ.url = nil
17
+ PROJ.version = ENV['VERSION'] || '0.0.0'
18
+ PROJ.rubyforge_name = nil
19
+ PROJ.exclude = %w(tmp$ bak$ ~$ CVS \.svn ^pkg ^doc)
20
+
21
+ # Rspec
22
+ PROJ.specs = FileList['spec/**/*_spec.rb']
23
+ PROJ.spec_opts = []
24
+
25
+ # Test::Unit
26
+ PROJ.tests = FileList['test/**/test_*.rb']
27
+ PROJ.test_file = 'test/all.rb'
28
+ PROJ.test_opts = []
29
+
30
+ # Rcov
31
+ PROJ.rcov_opts = ['--sort', 'coverage', '-T']
32
+
33
+ # Rdoc
34
+ PROJ.rdoc_opts = []
35
+ PROJ.rdoc_include = %w(^lib ^bin ^ext txt$)
36
+ PROJ.rdoc_exclude = %w(extconf\.rb$ ^Manifest\.txt$)
37
+ PROJ.rdoc_main = 'README.txt'
38
+ PROJ.rdoc_dir = 'doc'
39
+ PROJ.rdoc_remote_dir = nil
40
+
41
+ # Extensions
42
+ PROJ.extensions = FileList['ext/**/extconf.rb']
43
+ PROJ.ruby_opts = %w(-w)
44
+ PROJ.libs = []
45
+ %w(lib ext).each {|dir| PROJ.libs << dir if test ?d, dir}
46
+
47
+ # Gem Packaging
48
+ PROJ.files =
49
+ if test ?f, 'Manifest.txt'
50
+ files = File.readlines('Manifest.txt').map {|fn| fn.chomp.strip}
51
+ files.delete ''
52
+ files
53
+ else [] end
54
+ PROJ.executables = PROJ.files.find_all {|fn| fn =~ %r/^bin/}
55
+ PROJ.dependencies = []
56
+ PROJ.need_tar = true
57
+ PROJ.need_zip = false
58
+
59
+ # File Annotations
60
+ PROJ.annotation_exclude = []
61
+ PROJ.annotation_extensions = %w(.txt .rb .erb) << ''
62
+
63
+ # Load the other rake files in the tasks folder
64
+ Dir.glob('tasks/*.rake').sort.each {|fn| import fn}
65
+
66
+ # Setup some constants
67
+ WIN32 = %r/win32/ =~ RUBY_PLATFORM unless defined? WIN32
68
+
69
+ DEV_NULL = WIN32 ? 'NUL:' : '/dev/null'
70
+
71
+ def quiet( &block )
72
+ io = [STDOUT.dup, STDERR.dup]
73
+ STDOUT.reopen DEV_NULL
74
+ STDERR.reopen DEV_NULL
75
+ block.call
76
+ ensure
77
+ STDOUT.reopen io.first
78
+ STDERR.reopen io.last
79
+ end
80
+
81
+ DIFF = if WIN32 then 'diff.exe'
82
+ else
83
+ if quiet {system "gdiff", __FILE__, __FILE__} then 'gdiff'
84
+ else 'diff' end
85
+ end unless defined? DIFF
86
+
87
+ SUDO = if WIN32 then ''
88
+ else
89
+ if quiet {system 'which sudo'} then 'sudo'
90
+ else '' end
91
+ end
92
+
93
+ RCOV = WIN32 ? 'rcov.cmd' : 'rcov'
94
+ GEM = WIN32 ? 'gem.cmd' : 'gem'
95
+
96
+ %w(rcov spec/rake/spectask rubyforge bones).each do |lib|
97
+ begin
98
+ require lib
99
+ Object.instance_eval {const_set "HAVE_#{lib.tr('/','_').upcase}", true}
100
+ rescue LoadError
101
+ Object.instance_eval {const_set "HAVE_#{lib.tr('/','_').upcase}", false}
102
+ end
103
+ end
104
+
105
+ # Reads a file at +path+ and spits out an array of the +paragraphs+
106
+ # specified.
107
+ #
108
+ # changes = paragraphs_of('History.txt', 0..1).join("\n\n")
109
+ # summary, *description = paragraphs_of('README.txt', 3, 3..8)
110
+ #
111
+ def paragraphs_of(path, *paragraphs)
112
+ File.read(path).delete("\r").split(/\n\n+/).values_at(*paragraphs)
113
+ end
114
+
115
+ # Adds the given gem _name_ to the current project's dependency list. An
116
+ # optional gem _version_ can be given. If omitted, the newest gem version
117
+ # will be used.
118
+ #
119
+ def depend_on( name, version = nil )
120
+ spec = Gem.source_index.find_name(name).last
121
+ version = spec.version.to_s if version.nil? and !spec.nil?
122
+
123
+ PROJ.dependencies << (version.nil? ? [name] : [name, ">= #{version}"])
124
+ end
125
+
126
+ # Adds the given _path_ to the include path if it is not already there
127
+ #
128
+ def ensure_in_path( path )
129
+ path = File.expand_path(path)
130
+ $:.unshift(path) if test(?d, path) and not $:.include?(path)
131
+ end
132
+
133
+ # Find a rake task using the task name and remove any description text. This
134
+ # will prevent the task from being displayed in the list of available tasks.
135
+ #
136
+ def remove_desc_for_task( names )
137
+ Array(names).each do |task_name|
138
+ task = Rake.application.tasks.find {|t| t.name == task_name}
139
+ next if task.nil?
140
+ task.instance_variable_set :@comment, nil
141
+ end
142
+ end
143
+
144
+ # EOF
@@ -0,0 +1,40 @@
1
+ # $Id$
2
+
3
+ if HAVE_SPEC_RAKE_SPECTASK
4
+
5
+ namespace :spec do
6
+
7
+ desc 'Run all specs with basic output'
8
+ Spec::Rake::SpecTask.new(:run) do |t|
9
+ t.spec_opts = PROJ.spec_opts
10
+ t.spec_files = PROJ.specs
11
+ end
12
+
13
+ desc 'Run all specs with text output'
14
+ Spec::Rake::SpecTask.new(:specdoc) do |t|
15
+ t.spec_opts = PROJ.spec_opts + ['--format', 'specdoc']
16
+ t.spec_files = PROJ.specs
17
+ end
18
+
19
+ if HAVE_RCOV
20
+ desc 'Run all specs with RCov'
21
+ Spec::Rake::SpecTask.new(:rcov) do |t|
22
+ t.spec_opts = PROJ.spec_opts
23
+ t.spec_files = PROJ.specs
24
+ t.rcov = true
25
+ t.rcov_opts = PROJ.rcov_opts + ['--exclude', 'spec']
26
+ end
27
+ end
28
+
29
+ end # namespace :spec
30
+
31
+ desc 'Alias to spec:run'
32
+ task :spec => 'spec:run'
33
+
34
+ task :clobber => 'spec:clobber_rcov' if HAVE_RCOV
35
+
36
+ remove_desc_for_task %w(spec:clobber_rcov)
37
+
38
+ end # if HAVE_SPEC_RAKE_SPECTASK
39
+
40
+ # EOF
@@ -0,0 +1,40 @@
1
+ # $Id$
2
+
3
+ require 'rake/testtask'
4
+
5
+ namespace :test do
6
+
7
+ Rake::TestTask.new(:run) do |t|
8
+ t.libs = PROJ.libs
9
+ t.test_files = if test ?f, PROJ.test_file then [PROJ.test_file]
10
+ else PROJ.tests end
11
+ t.ruby_opts += PROJ.ruby_opts
12
+ t.ruby_opts += PROJ.test_opts
13
+ end
14
+
15
+ if HAVE_RCOV
16
+ desc 'Run rcov on the unit tests'
17
+ task :rcov => :clobber_rcov do
18
+ opts = PROJ.rcov_opts.join(' ')
19
+ files = if test ?f, PROJ.test_file then [PROJ.test_file]
20
+ else PROJ.tests end
21
+ files = files.join(' ')
22
+ sh "#{RCOV} #{files} #{opts}"
23
+ end
24
+
25
+ desc 'Remove rcov products'
26
+ task :clobber_rcov do
27
+ rm_r 'coverage' rescue nil
28
+ end
29
+ end
30
+
31
+ end # namespace :test
32
+
33
+ desc 'Alias to test:run'
34
+ task :test => 'test:run'
35
+
36
+ task :clobber => 'test:clobber_rcov' if HAVE_RCOV
37
+
38
+ remove_desc_for_task %w(test:clobber_rcov)
39
+
40
+ # EOF
@@ -0,0 +1,108 @@
1
+ require 'test/unit'
2
+ require 'lib/csses'
3
+
4
+ module Test::Unit::Assertions
5
+ def assert_include(item, obj, message = nil)
6
+ assert_respond_to obj, :include?
7
+ message ||= "#{obj.inspect}\ndoes not include\n#{item.inspect}."
8
+ assert_block message do obj.include? item end
9
+ end
10
+
11
+ def deny_include(item, obj, message = nil)
12
+ assert_respond_to obj, :include?
13
+ message ||= "#{obj.inspect} includes #{item.inspect}."
14
+ assert_block message do !obj.include? item end
15
+ end
16
+
17
+ # Thanks ZenTest!
18
+ end
19
+
20
+ class CSSesTest < Test::Unit::TestCase
21
+
22
+ def setup
23
+ files = Dir.glob('test/test_site/*')
24
+ @css = CSSes.new(files)
25
+ @css_unless = CSSes.new(['test/test_site/test_unless.html.erb'])
26
+ @css_without_parens = CSSes.new(['test/test_site/test_no_parens.html.erb'])
27
+ @css_without_anything = CSSes.new([])
28
+ end
29
+
30
+ def test_000_no_unfashionable_elements
31
+ CSSes::UNFASHIONABLE_ELEMENTS.each do |not_allowed|
32
+ deny_include(not_allowed, @css.elements)
33
+ end
34
+ end
35
+
36
+ def test_001_h1
37
+ assert_include('h1', @css.elements)
38
+ end
39
+
40
+ def test_002_h1_with_id
41
+ assert_include('h1#h1_id', @css.elements, 'CSS should include entries for ids')
42
+ end
43
+
44
+ def test_003_h1_with_class
45
+ assert_include('h1.h1_class', @css.elements, 'CSS should include entries for classes')
46
+ end
47
+
48
+ def test_004_link_to
49
+ assert_include('a', @css.elements, 'CSS should know that link_to makes anchors')
50
+ end
51
+
52
+ def test_005_link_to_without_parens
53
+ assert_include('a', @css_without_parens.elements, 'CSS should handle parenthesis-less helper calls')
54
+ end
55
+
56
+ def test_006_link_to_unless
57
+ assert_include('a', @css_unless.elements, 'CSS should know that link_to_unless makes anchors')
58
+ end
59
+
60
+ def test_007_anchor_pseudo_class_visited
61
+ assert_include('a:visited', @css.elements, 'CSS should create the visited pseudo-class for anchors')
62
+ end
63
+
64
+ def test_008_anchor_pseudo_class_hover
65
+ assert_include('a:hover', @css.elements, 'CSS should create the hover pseudo-class for anchors')
66
+ end
67
+
68
+ def test_009_anchor_pseudo_class_active
69
+ assert_include('a:active', @css.elements, 'CSS should create the active pseudo-class for anchors')
70
+ end
71
+
72
+ def test_010_anchor_pseudo_class_with_id
73
+ assert_include('a#a_id:visited', @css.elements, 'CSS should handle ids with pseudoclasses')
74
+ end
75
+
76
+ def test_011_anchor_pseudo_class_with_class
77
+ assert_include('a.a_class:hover', @css.elements, 'CSS should handle classes with pseudoclasses')
78
+ end
79
+
80
+ def test_012_image_tag
81
+ assert_include('img', @css.elements, 'CSS should know that image_tag makes img tags')
82
+ end
83
+
84
+ def test_013_image_tag_with_id
85
+ assert_include('img#img_id', @css.elements, 'CSS should handle image_tags with ids')
86
+ end
87
+
88
+ def test_014_image_tag_with_class
89
+ assert_include('img.img_class', @css.elements, 'CSS should handle image_tags with classes')
90
+ end
91
+
92
+ def test_015_link_to_with_id
93
+ assert_include('a#link_to_id', @css.elements, 'CSS should handle link_to with ids')
94
+ end
95
+
96
+ def test_016_link_to_with_class
97
+ assert_include('a.link_to_class', @css.elements, 'CSS should handle link_to with classes')
98
+ end
99
+
100
+ def test_017_link_to_with_rails_id_not_html_id
101
+ deny_include('a#not_an_html_id', @css.elements, "CSS shouldn't fall for rails ids in link_to calls")
102
+ end
103
+
104
+ def test_018_form_helpers
105
+ assert_include('label#label_id', @css.elements, 'CSS should handle labels')
106
+ end
107
+
108
+ end
@@ -0,0 +1,13 @@
1
+ class TestCSSesHelpers < Test::Unit::TestCase
2
+ def test_001_css_sym_for_attribute_with_class
3
+ assert_equal('.', css_sym_for_attribute('class'))
4
+ end
5
+
6
+ def test_002_css_sym_for_attribute_with_id
7
+ assert_equal('#', css_sym_for_attribute('id'))
8
+ end
9
+
10
+ def test_003_css_sym_for_attribute_on_junk
11
+ assert_raise(ArgumentError) { css_sym_for_attribute('junk') }
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ <%= link_to 'No parens', 'http://www.google.com' %>
@@ -0,0 +1 @@
1
+ <%= link_to_unless(false, 'Test link_to_unless', 'http://example.com') %>
@@ -0,0 +1,23 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
4
+ <title>Test View</title>
5
+ </head>
6
+ <body id="view.html">
7
+ <h1>Heading</h1>
8
+ <h1 id="h1_id">Heading with ID</h1>
9
+ <h1 class="h1_class">Heading with class</h1>
10
+
11
+ <%= link_to('Test link_to', 'http://example.com') %>
12
+
13
+ <a href="http://soveryverymuchclass" class="a_class">Test classes with pseudoclasses</a>
14
+ <a href="http://ihaveatotallycoolidentity" id="a_id">Test ids with pseudoclasses</a>
15
+ <%= image_tag('portrait_of_the_artist.gif') %>
16
+ <%= image_tag('baltimore_orioles.jpg', :class => 'img_class') %>
17
+ <%= image_tag('sideways_pony.png', :id => 'img_id') %>
18
+ <%= link_to('Test link_to with id', {:controller => 'test'}, {:id => 'link_to_id'}) %>
19
+ <%= link_to('Test link_to with class', {:action => 'test'}, {:class => 'link_to_class'}) %>
20
+ <%= link_to('Test link_to with resource id, no html id', :action => 'test', :id => not_an_html_id) %>
21
+
22
+ <%= label(:test, :test_title, 'A Test Title', :id => 'label_id') %>
23
+ </body>
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csses
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Chris Shea
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-01-03 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: "== DESCRIPTION: Generate a clean CSS file based on your Rails view and helpers."
17
+ email: chris@ruby.tie-rack.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - History.txt
24
+ - README.txt
25
+ files:
26
+ - History.txt
27
+ - Manifest.txt
28
+ - README.txt
29
+ - Rakefile
30
+ - lib/csses.rb
31
+ - lib/csses_helpers.rb
32
+ - rails_generators/csses/USAGE
33
+ - rails_generators/csses/csses_generator.rb
34
+ - rails_generators/csses/templates/application.css.erb
35
+ - tasks/annotations.rake
36
+ - tasks/doc.rake
37
+ - tasks/gem.rake
38
+ - tasks/manifest.rake
39
+ - tasks/rubyforge.rake
40
+ - tasks/setup.rb
41
+ - tasks/spec.rake
42
+ - tasks/test.rake
43
+ - test/test_csses.rb
44
+ - test/test_csses_helpers.rb
45
+ - test/test_site/test_no_parens.html.erb
46
+ - test/test_site/test_unless.html.erb
47
+ - test/test_site/view.html.erb
48
+ has_rdoc: true
49
+ homepage: http://csses.rubyforge.org
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --main
53
+ - README.txt
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project: csses
71
+ rubygems_version: 1.0.1
72
+ signing_key:
73
+ specification_version: 2
74
+ summary: Generate a CSS slate for your Rails applications
75
+ test_files:
76
+ - test/test_csses.rb
77
+ - test/test_csses_helpers.rb