css_primer 0.1 → 0.2
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.
- data/CHANGELOG +6 -0
- data/README +7 -2
- data/bin/css_primer +3 -6
- data/css_primer.gemspec +16 -16
- data/lib/css_primer.rb +216 -0
- metadata +5 -6
- data/lib/classes/CSSPrimer.rb +0 -149
- data/lib/modules/GenericApplication.rb +0 -16
- data/lib/modules/IOHelper.rb +0 -39
data/CHANGELOG
CHANGED
data/README
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
CSSPrimer takes in a markup file and generates a css file of all the extracted ids and classes.
|
2
2
|
|
3
|
+
http://rubygems.org/gems/css_primer
|
4
|
+
|
3
5
|
== Terminal usage
|
4
6
|
As a ruby gem:
|
5
7
|
css_primer -h
|
@@ -8,8 +10,8 @@ CSSPrimer takes in a markup file and generates a css file of all the extracted i
|
|
8
10
|
ruby bin/css_primer -h
|
9
11
|
|
10
12
|
== Using Examples
|
11
|
-
|
12
|
-
|
13
|
+
ruby bin/css_primer --in examples/test.html
|
14
|
+
ruby bin/css_primer --in examples/test.xml --out some_styles.css
|
13
15
|
|
14
16
|
== Dependencies
|
15
17
|
Core Lib
|
@@ -22,6 +24,9 @@ CSSPrimer takes in a markup file and generates a css file of all the extracted i
|
|
22
24
|
|
23
25
|
spec tests/css_primer.rspec
|
24
26
|
|
27
|
+
== Bugs
|
28
|
+
- classes/ids on the same line are randomly sorted in when writing rules in order
|
29
|
+
|
25
30
|
== Author
|
26
31
|
Copyright 2010 Brent Lintner
|
27
32
|
|
data/bin/css_primer
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
$:.unshift(
|
2
|
+
LIB = File.join(File.dirname(__FILE__), %w(.. lib))
|
3
|
+
$:.unshift(LIB) if File.exists?(LIB) unless $:.member?(LIB)
|
4
4
|
|
5
5
|
require 'optparse'
|
6
6
|
require 'ostruct'
|
7
|
-
require 'fileutils'
|
8
7
|
|
9
|
-
require "#{
|
10
|
-
require "#{lib}/modules/IOHelper"
|
11
|
-
require "#{lib}/classes/CSSPrimer"
|
8
|
+
require "#{LIB}/css_primer"
|
12
9
|
|
13
10
|
CSSPrimer.new(ARGV).prime!
|
14
11
|
|
data/css_primer.gemspec
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
s.platform = Gem::Platform::RUBY
|
4
|
+
s.name = 'css_primer'
|
5
|
+
s.version = '0.2'
|
6
|
+
s.summary = 'CSS Primer for markup files'
|
7
|
+
s.description = 'Takes in a markup file (html/xml) and creates a CSS file with a reference to classes/ids.'
|
8
8
|
|
9
|
-
|
9
|
+
s.required_ruby_version = '>= 1.8.6'
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
s.author = 'Brent Lintner'
|
12
|
+
s.email = 'brent.lintner@gmail.com'
|
13
|
+
s.homepage = 'http://github.com/brentlintner/css_primer'
|
14
14
|
|
15
|
-
|
15
|
+
s.files = Dir['bin/*', 'css_primer.gemspec', 'CHANGELOG', 'README', 'lib/*'].to_a
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
s.has_rdoc = true
|
18
|
+
s.extra_rdoc_files = %w( README )
|
19
|
+
s.rdoc_options.concat ['--main', 'README']
|
20
|
+
|
21
|
+
s.executables = ["css_primer"]
|
22
|
+
s.require_path = "lib"
|
20
23
|
|
21
|
-
s.executables = ["css_primer"]
|
22
|
-
s.require_path = "lib"
|
23
|
-
|
24
24
|
end
|
25
25
|
|
26
26
|
|
data/lib/css_primer.rb
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
HELP = <<TEXT
|
4
|
+
|
5
|
+
== CSS::Primer
|
6
|
+
Takes in a markup file (html/xml) and creates a CSS file with a reference to classes/ids.
|
7
|
+
|
8
|
+
== Usage
|
9
|
+
css_primer [options] --in FILE_TO_PRIME [--out] CSS_OUTPUT_FILE
|
10
|
+
|
11
|
+
== Options
|
12
|
+
-h, --help Displays help message
|
13
|
+
-q, --quiet Output as little as possible, overrides verbose
|
14
|
+
-V, --verbose Verbose output
|
15
|
+
-i, --in Markup file to parse
|
16
|
+
-o, --out (optional) CSS file to save out to
|
17
|
+
-s, --sort (optional) Sorts ids/classes alphabetically when set else by the order of parsing
|
18
|
+
|
19
|
+
TEXT
|
20
|
+
|
21
|
+
class CSSPrimer
|
22
|
+
|
23
|
+
class MarkupFileError < StandardError ; end
|
24
|
+
|
25
|
+
attr_accessor :markup_file, :css_file
|
26
|
+
|
27
|
+
def initialize(argv)
|
28
|
+
|
29
|
+
@config = OpenStruct.new
|
30
|
+
@config.HELP = HELP
|
31
|
+
@config.DEFAULT_CSS_FILE_OUT = "primed_styles.css"
|
32
|
+
|
33
|
+
@argv = argv
|
34
|
+
|
35
|
+
@options = OpenStruct.new
|
36
|
+
@options.verbose = false
|
37
|
+
@options.quiet = false
|
38
|
+
@options.sort = false
|
39
|
+
|
40
|
+
@attributes = []
|
41
|
+
|
42
|
+
@markup_file = ""
|
43
|
+
@css_file = self.config("DEFAULT_CSS_FILE_OUT")
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def prime!
|
48
|
+
|
49
|
+
if self.parsed_options?
|
50
|
+
|
51
|
+
begin
|
52
|
+
|
53
|
+
self.log("Time to pwn...\n")
|
54
|
+
|
55
|
+
# TODO: clean up regex, not tight enough (i.e. will match against inner text and javascript strings if present)
|
56
|
+
parser = Proc.new { |full_path|
|
57
|
+
|
58
|
+
self.log("\nOpening up #{full_path}\n") if @options.verbose
|
59
|
+
|
60
|
+
self.read_in_file(full_path) do |line|
|
61
|
+
|
62
|
+
line.scan(/class="((\s|\w|\-)*)"/) do |class_attribute|
|
63
|
+
class_attribute[0].split(" ").each do |class_name|
|
64
|
+
@attributes << [class_name, "."]
|
65
|
+
self.log("Found class => #{class_name}") if @options.verbose
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
line.scan(/id="((\w|\-)*)"/) do |id_attribute|
|
70
|
+
@attributes << [id_attribute[0], "#"]
|
71
|
+
self.log("Found id => #{id_attribute[0]}") if @options.verbose
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
}
|
77
|
+
|
78
|
+
if File.directory?(@markup_file)
|
79
|
+
self.recurse_directories(@markup_file) do |full_path|
|
80
|
+
parser.call(full_path) if full_path =~ /\.(html|xml)$/
|
81
|
+
end
|
82
|
+
else
|
83
|
+
parser.call(@markup_file)
|
84
|
+
end
|
85
|
+
|
86
|
+
# TODO: do win or *nix line breaks
|
87
|
+
buffer_array = @attributes.uniq
|
88
|
+
buffer_array.sort! if @options.sort
|
89
|
+
|
90
|
+
self.save(buffer_array.inject("") { |buffer, item| buffer << "#{item[1]}#{item[0]} {\n\n}\n\n" }, @css_file)
|
91
|
+
|
92
|
+
puts "\nSaved to #{@css_file}\n\nLet's Roll!"
|
93
|
+
|
94
|
+
rescue Exception => e
|
95
|
+
self.handle_exception(e)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
|
104
|
+
def config(struct)
|
105
|
+
@config.send(struct)
|
106
|
+
end
|
107
|
+
|
108
|
+
def generate_docs
|
109
|
+
begin
|
110
|
+
Kernel.exec "rdoc1.8 -U -S -N -o 'rdoc' --main CSSPrimer"
|
111
|
+
rescue Exception => e
|
112
|
+
self.handle_exception(e)
|
113
|
+
ensure
|
114
|
+
Kernel.exit!(0)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def parsed_options?
|
119
|
+
|
120
|
+
opts = OptionParser.new
|
121
|
+
|
122
|
+
opts.on('-v', '--version') { self.log("0.1") ; exit!(0) }
|
123
|
+
opts.on('-h', '--help') { self.log(self.config("HELP")) ; exit!(0) }
|
124
|
+
opts.on('-V', '--verbose') { @options.verbose = true }
|
125
|
+
opts.on('-q', '--quiet') { @options.quiet = true }
|
126
|
+
opts.on('-r', '--rdoc') { self.generate_docs }
|
127
|
+
opts.on('-s', '--sort') { @options.sort = true }
|
128
|
+
|
129
|
+
opts.on('-i', '--in MARKUPFILE') do |markup_file|
|
130
|
+
@markup_file = markup_file
|
131
|
+
end
|
132
|
+
|
133
|
+
opts.on('-o', '--out [CSSFILE]') do |css_file|
|
134
|
+
@css_file = css_file
|
135
|
+
end
|
136
|
+
|
137
|
+
begin
|
138
|
+
|
139
|
+
opts.parse!(@argv)
|
140
|
+
|
141
|
+
rescue Exception => e
|
142
|
+
self.handle_exception(e)
|
143
|
+
exit!(0)
|
144
|
+
end
|
145
|
+
|
146
|
+
self.process_options
|
147
|
+
|
148
|
+
true
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
def process_options
|
153
|
+
@options.verbose = false if @options.quiet
|
154
|
+
raise MarkupFileError, "No input markup file specified." if !File.exists?(@markup_file)
|
155
|
+
end
|
156
|
+
|
157
|
+
def recurse_directories(directory, limit=10, &block)
|
158
|
+
|
159
|
+
raise StandardError, "You should use a block eh!" if !block_given?
|
160
|
+
raise StandardError, "Recursive limit reached!" if limit <= 0
|
161
|
+
|
162
|
+
Dir.foreach(directory) do |directory_item|
|
163
|
+
full_path = "#{directory}/#{directory_item}"
|
164
|
+
|
165
|
+
if directory_item != "." && directory_item != ".."
|
166
|
+
if File.directory?(full_path)
|
167
|
+
self.log("\nNavigating into #{full_path}") if @options.verbose
|
168
|
+
recurse_directories(full_path, limit - 1, &block)
|
169
|
+
else
|
170
|
+
yield(full_path)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
# helpers
|
179
|
+
def log(msg)
|
180
|
+
puts msg.to_s
|
181
|
+
end
|
182
|
+
|
183
|
+
def handle_exception(e)
|
184
|
+
msg = e.message
|
185
|
+
|
186
|
+
msg = e.exception.to_s+" :: "+msg if e.message.to_s != e.exception.to_s
|
187
|
+
|
188
|
+
self.log "\nHANDLED EXCEPTION --> #{e.class.to_s}\n\nMESSAGE --> #{msg}"
|
189
|
+
self.log "\nBACKTRACE\n\n#{e.backtrace.join("\n")}\n\n"
|
190
|
+
end
|
191
|
+
|
192
|
+
def read_in_file(full_path, &block)
|
193
|
+
data = ""
|
194
|
+
|
195
|
+
if !File.directory?(full_path)
|
196
|
+
IO.foreach full_path do |line|
|
197
|
+
data += block_given? ? yield(line) : line
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
data
|
202
|
+
end
|
203
|
+
|
204
|
+
def save(lines, file_to_write)
|
205
|
+
File.open(file_to_write, "w") do |file|
|
206
|
+
file.syswrite lines
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def append(lines, file_to_append)
|
211
|
+
File.open(file_to_append, "a") do |file|
|
212
|
+
file.syswrite lines
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
metadata
CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
version: "0.
|
7
|
+
- 2
|
8
|
+
version: "0.2"
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- Brent Lintner
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2010-06-
|
16
|
+
date: 2010-06-26 00:00:00 -04:00
|
17
17
|
default_executable:
|
18
18
|
dependencies: []
|
19
19
|
|
@@ -26,12 +26,11 @@ extensions: []
|
|
26
26
|
extra_rdoc_files:
|
27
27
|
- README
|
28
28
|
files:
|
29
|
+
- bin/css_primer
|
29
30
|
- css_primer.gemspec
|
30
31
|
- CHANGELOG
|
31
32
|
- README
|
32
|
-
- lib/
|
33
|
-
- lib/modules/IOHelper.rb
|
34
|
-
- lib/modules/GenericApplication.rb
|
33
|
+
- lib/css_primer.rb
|
35
34
|
has_rdoc: true
|
36
35
|
homepage: http://github.com/brentlintner/css_primer
|
37
36
|
licenses: []
|
data/lib/classes/CSSPrimer.rb
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
HELP = <<TEXT
|
4
|
-
|
5
|
-
== CSS::Primer
|
6
|
-
Takes in a markup file (html/xml) and creates a CSS file with a reference to classes/ids.
|
7
|
-
|
8
|
-
== Usage
|
9
|
-
css_primer [options] --in FILE_TO_PRIME [--out] CSS_OUTPUT_FILE
|
10
|
-
|
11
|
-
== Options
|
12
|
-
-h, --help Displays help message
|
13
|
-
-q, --quiet Output as little as possible, overrides verbose
|
14
|
-
-V, --verbose Verbose output
|
15
|
-
-i, --in Markup file to parse
|
16
|
-
-o, --out CSS file to save out to (optional)
|
17
|
-
|
18
|
-
TEXT
|
19
|
-
|
20
|
-
class CSSPrimer
|
21
|
-
|
22
|
-
include GenericApplication
|
23
|
-
include IOHelper
|
24
|
-
|
25
|
-
class MarkupFileError < StandardError ; end
|
26
|
-
|
27
|
-
attr_accessor :markup_file, :css_file
|
28
|
-
|
29
|
-
def initialize(argv)
|
30
|
-
|
31
|
-
@config = OpenStruct.new
|
32
|
-
@config.HELP = HELP
|
33
|
-
|
34
|
-
@config.DEFAULT_CSS_FILE_OUT = "primed_styles.css"
|
35
|
-
|
36
|
-
@argv = argv
|
37
|
-
|
38
|
-
@options = OpenStruct.new
|
39
|
-
@options.verbose = false
|
40
|
-
@options.quiet = false
|
41
|
-
|
42
|
-
@my_ids, @my_classes = [], []
|
43
|
-
|
44
|
-
@markup_file = ""
|
45
|
-
@css_file = self.config("DEFAULT_CSS_FILE_OUT")
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
def config(struct)
|
50
|
-
@config.send(struct)
|
51
|
-
end
|
52
|
-
|
53
|
-
def prime!
|
54
|
-
|
55
|
-
if self.parsed_options?
|
56
|
-
|
57
|
-
begin
|
58
|
-
|
59
|
-
self.log("what up! lets do some priming\nopening up #{@markup_file}\n") if @options.verbose
|
60
|
-
|
61
|
-
buffer = ""
|
62
|
-
|
63
|
-
# TODO: clean up
|
64
|
-
self.read_in_file(@markup_file).scan(/(id="\S+"|class="\S+")/) do |w|
|
65
|
-
|
66
|
-
w[0].scan(/"\S+"/) do |rule_attribute|
|
67
|
-
|
68
|
-
css_type = (w[0] =~ /^id=/) ? "#" : "."
|
69
|
-
|
70
|
-
rule_attribute.gsub!(/"/,"")
|
71
|
-
|
72
|
-
if css_type == "#"
|
73
|
-
@my_ids.push [rule_attribute, css_type]
|
74
|
-
else
|
75
|
-
@my_classes.push [rule_attribute, css_type]
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
@my_ids.uniq.sort.concat(@my_classes.uniq.sort).each do |arr|
|
83
|
-
buffer += "#{arr[1]}#{arr[0]}{\n\n}\n\n"
|
84
|
-
end
|
85
|
-
|
86
|
-
self.save(buffer, @css_file)
|
87
|
-
|
88
|
-
puts "saved to #{@css_file}\n\nLet's Roll!" if @options.verbose
|
89
|
-
|
90
|
-
rescue Exception => e
|
91
|
-
self.handle_exception(e)
|
92
|
-
end
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
protected
|
99
|
-
|
100
|
-
def generate_docs
|
101
|
-
begin
|
102
|
-
Kernel.exec "rdoc1.8 -U -S -N -o 'rdoc' --main CSSPrimer"
|
103
|
-
rescue Exception => e
|
104
|
-
self.handle_exception(e)
|
105
|
-
ensure
|
106
|
-
Kernel.exit!
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def parsed_options?
|
111
|
-
|
112
|
-
opts = OptionParser.new
|
113
|
-
|
114
|
-
opts.on('-v', '--version') { self.log("0.1") ; exit!(0) }
|
115
|
-
opts.on('-h', '--help') { self.log(self.config("HELP")) ; exit!(0) }
|
116
|
-
opts.on('-V', '--verbose') { @options.verbose = true }
|
117
|
-
opts.on('-q', '--quiet') { @options.quiet = true }
|
118
|
-
opts.on('-r', '--rdoc') { self.generate_docs }
|
119
|
-
|
120
|
-
opts.on('-i', '--in MARKUPFILE') do |markup_file|
|
121
|
-
@markup_file = markup_file
|
122
|
-
end
|
123
|
-
|
124
|
-
opts.on('-o', '--out [CSSFILE]') do |css_file|
|
125
|
-
@css_file = css_file
|
126
|
-
end
|
127
|
-
|
128
|
-
begin
|
129
|
-
|
130
|
-
opts.parse!(@argv)
|
131
|
-
|
132
|
-
rescue Exception => e
|
133
|
-
self.handle_exception(e)
|
134
|
-
exit!(0)
|
135
|
-
end
|
136
|
-
|
137
|
-
self.process_options
|
138
|
-
|
139
|
-
true
|
140
|
-
|
141
|
-
end
|
142
|
-
|
143
|
-
def process_options
|
144
|
-
@options.verbose = false if @options.quiet
|
145
|
-
|
146
|
-
raise MarkupFileError, "No input markup file specified." if !File.exists?(@markup_file)
|
147
|
-
end
|
148
|
-
|
149
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module GenericApplication
|
2
|
-
|
3
|
-
def log(msg)
|
4
|
-
puts msg.to_s
|
5
|
-
end
|
6
|
-
|
7
|
-
def handle_exception(e, verbose=false)
|
8
|
-
msg = e.message
|
9
|
-
|
10
|
-
msg = e.exception.to_s+" :: "+msg if e.message.to_s != e.exception.to_s
|
11
|
-
|
12
|
-
self.log "\nHANDLED EXCEPTION --> #{e.class.to_s}\n\nMESSAGE --> #{msg}" if verbose
|
13
|
-
self.log "\nBACKTRACE\n\n#{e.backtrace.join("\n")}\n\n" if verbose
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
data/lib/modules/IOHelper.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
module IOHelper
|
2
|
-
|
3
|
-
def read_in_file(full_path, &block)
|
4
|
-
data = ""
|
5
|
-
|
6
|
-
if !File.directory?(full_path)
|
7
|
-
IO.foreach full_path do |line|
|
8
|
-
data += block_given? ? yield(line) : line
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
data
|
13
|
-
end
|
14
|
-
|
15
|
-
def copy_full_dir(orig, target)
|
16
|
-
FileUtils.cp_r(orig, target)
|
17
|
-
end
|
18
|
-
|
19
|
-
def delete_full_dir(directory)
|
20
|
-
FileUtils.rm_r(directory)
|
21
|
-
end
|
22
|
-
|
23
|
-
def delete_full_dir_contents(directory)
|
24
|
-
FileUtils.rm_r(Dir.glob("#{directory}*"))
|
25
|
-
end
|
26
|
-
|
27
|
-
def save(lines, file_to_write)
|
28
|
-
File.open(file_to_write, "w") do |file|
|
29
|
-
file.syswrite lines
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def append(lines, file_to_append)
|
34
|
-
File.open(file_to_append, "a") do |file|
|
35
|
-
file.syswrite lines
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|