csspress 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +6 -0
- data/PostInstall.txt +1 -1
- data/README.txt +3 -3
- data/bin/css +22 -30
- data/lib/csspress.rb +1 -0
- data/lib/csspress/declaration.rb +9 -82
- data/lib/csspress/rule.rb +25 -82
- data/lib/csspress/style_sheet.rb +25 -209
- data/lib/csspress/style_sheet_parser.rb +287 -0
- data/lib/csspress/template_builder.rb +5 -18
- data/lib/csspress/version.rb +1 -1
- data/spec/csspress_spec.rb +4 -2
- data/spec/declaration_spec.rb +29 -0
- data/spec/rule_spec.rb +50 -0
- data/spec/style_sheet_parser_spec.rb +14 -0
- data/spec/style_sheet_spec.rb +57 -0
- data/spec/template_builder_spec.rb +37 -0
- metadata +9 -3
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -11,6 +11,7 @@ lib/csspress.rb
|
|
11
11
|
lib/csspress/declaration.rb
|
12
12
|
lib/csspress/rule.rb
|
13
13
|
lib/csspress/style_sheet.rb
|
14
|
+
lib/csspress/style_sheet_parser.rb
|
14
15
|
lib/csspress/template_builder.rb
|
15
16
|
lib/csspress/version.rb
|
16
17
|
lib/templates/default.csst
|
@@ -20,8 +21,13 @@ script/generate
|
|
20
21
|
script/txt2html
|
21
22
|
setup.rb
|
22
23
|
spec/csspress_spec.rb
|
24
|
+
spec/declaration_spec.rb
|
25
|
+
spec/rule_spec.rb
|
23
26
|
spec/spec.opts
|
24
27
|
spec/spec_helper.rb
|
28
|
+
spec/style_sheet_spec.rb
|
29
|
+
spec/style_sheet_parser_spec.rb
|
30
|
+
spec/template_builder_spec.rb
|
25
31
|
tasks/custom.rake
|
26
32
|
tasks/deployment.rake
|
27
33
|
tasks/environment.rake
|
data/PostInstall.txt
CHANGED
data/README.txt
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
=
|
1
|
+
= CSSpress
|
2
2
|
|
3
3
|
Project Page:
|
4
|
-
- http://csspress.
|
4
|
+
- http://www.csspress.net
|
5
5
|
RubyForge Page:
|
6
6
|
- http://rubyforge.org/projects/csspress/
|
7
7
|
|
8
8
|
== DESCRIPTION:
|
9
9
|
|
10
|
-
Press out only the juice worth serving from
|
10
|
+
Press out only the juice worth serving from your CSS files (and optimize it a little while your at it).
|
11
11
|
|
12
12
|
When you are building a website, a well formatted and clearly commented CSS file can make it really easy
|
13
13
|
for developers to see what is going on and build beautiful pages. All of this extra stuff however needs to be downloaded by a end user who is never going to read it, but has to wait for it.
|
data/bin/css
CHANGED
@@ -29,11 +29,9 @@
|
|
29
29
|
# == Options
|
30
30
|
# -h, --help Displays help message
|
31
31
|
# -s, --stats Output compression information
|
32
|
-
# -v, --version Display the version
|
33
|
-
#
|
34
|
-
# == Author
|
35
|
-
# David Madden
|
32
|
+
# -v, --version Display the version
|
36
33
|
#
|
34
|
+
|
37
35
|
require 'optparse' # for parsing cmd line options
|
38
36
|
require 'rdoc/usage' # for outputing rdoc to terminal
|
39
37
|
require 'ostruct' # useful in cmd line option usage
|
@@ -139,32 +137,26 @@ class App #:nodoc: all
|
|
139
137
|
# and output that file to pressed_filename.css
|
140
138
|
#
|
141
139
|
def process_command
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
out.close
|
163
|
-
rescue Declaration::PropertyError => e
|
164
|
-
puts e
|
165
|
-
rescue IOError => e
|
166
|
-
puts e
|
167
|
-
end
|
140
|
+
file_in = @arguments[0]
|
141
|
+
# Get the dir
|
142
|
+
path = File.dirname(file_in)
|
143
|
+
# Get the file name
|
144
|
+
name = File.basename(file_in)
|
145
|
+
|
146
|
+
# Create name for tar file
|
147
|
+
file_out = path <<"/csspress-" << name
|
148
|
+
|
149
|
+
# Do the compression stuff
|
150
|
+
ssp = StyleSheetParser.new( file_in )
|
151
|
+
ss = ssp.style_sheet
|
152
|
+
tb = TemplateBuilder.new( ss )
|
153
|
+
|
154
|
+
# Change working dir to files dir
|
155
|
+
#Dir.chdir(path)
|
156
|
+
|
157
|
+
out = File.new( file_out, "w" )
|
158
|
+
out.write(tb.publish)
|
159
|
+
out.close
|
168
160
|
output_stats(file_in, file_out) if @options.stats
|
169
161
|
#process_standard_input # [Optional]
|
170
162
|
end
|
data/lib/csspress.rb
CHANGED
data/lib/csspress/declaration.rb
CHANGED
@@ -11,24 +11,18 @@
|
|
11
11
|
# It is composed of a property and a value. The property must be
|
12
12
|
# valid.
|
13
13
|
#
|
14
|
-
# Declaration takes a string and populates itself.
|
15
14
|
#
|
16
15
|
# Example:
|
17
|
-
# d = declaration.new ( "border-color
|
16
|
+
# d = declaration.new ( "border-color", "blue" )
|
18
17
|
# puts d.property #=> "border-color"
|
19
18
|
# puts d.value #=> "blue"
|
20
19
|
#
|
21
20
|
class Declaration
|
22
21
|
|
23
|
-
|
24
|
-
attr_reader :property
|
25
|
-
# Declaration value
|
26
|
-
attr_reader :value
|
22
|
+
attr_reader :property, :value
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
class PropertyError < StandardError
|
31
|
-
# do nothing - just creating a specific error
|
24
|
+
class PropertyError < StandardError #:nodoc:
|
25
|
+
# do nothing - just creating an error for internal use
|
32
26
|
end
|
33
27
|
|
34
28
|
# Properties for CSS1 to CSS3
|
@@ -64,81 +58,14 @@ class Declaration
|
|
64
58
|
white-space white-space-collapse widows width word-break word-spacing word-wrap z-index
|
65
59
|
)
|
66
60
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
dp = DeclarationParser.new(text)
|
72
|
-
@property = dp.property
|
73
|
-
@value = dp.value
|
61
|
+
def initialize(property, value)
|
62
|
+
raise PropertyError unless VALID_PROPERTIES.include?(property)
|
63
|
+
@property = property
|
64
|
+
@value = value
|
74
65
|
end
|
75
66
|
|
76
|
-
# Print out the rule neatly
|
77
|
-
#
|
78
67
|
def to_s
|
79
|
-
|
68
|
+
"#{@property}:#{@value}"
|
80
69
|
end
|
81
70
|
|
82
|
-
private
|
83
|
-
|
84
|
-
# This class parses the text entered and makes the
|
85
|
-
# property and value available to the Declaration that
|
86
|
-
# initialised it.
|
87
|
-
#
|
88
|
-
class DeclarationParser #:nodoc:
|
89
|
-
attr_reader :property, :value
|
90
|
-
|
91
|
-
def initialize(raw_data)
|
92
|
-
@raw_data = raw_data
|
93
|
-
@property = ""
|
94
|
-
@value = ""
|
95
|
-
parse
|
96
|
-
end
|
97
|
-
|
98
|
-
private
|
99
|
-
|
100
|
-
# Call methods to parse @raw_data and
|
101
|
-
# extract the property and name.
|
102
|
-
#
|
103
|
-
# Raise an error if the property found
|
104
|
-
# is invalid.
|
105
|
-
#
|
106
|
-
def parse
|
107
|
-
@property = get_property
|
108
|
-
raise PropertyError, "Invalid property type found: #{@property}" unless VALID_PROPERTIES.include? @property
|
109
|
-
@value = get_value
|
110
|
-
end
|
111
|
-
|
112
|
-
# Get the property from @raw_data
|
113
|
-
#---
|
114
|
-
# The property is the part of @raw_data
|
115
|
-
# before the ':' character.
|
116
|
-
#+++
|
117
|
-
#
|
118
|
-
def get_property
|
119
|
-
@raw_data.slice(0, @raw_data.index(":")).strip
|
120
|
-
end
|
121
|
-
|
122
|
-
# Get the value from @raw_data
|
123
|
-
#---
|
124
|
-
# The value is the part of @raw_data
|
125
|
-
# after the ':' character.
|
126
|
-
#+++
|
127
|
-
#
|
128
|
-
def get_value
|
129
|
-
@raw_data.slice(@raw_data.index(":")+1..@raw_data.size-1).strip
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
if __FILE__ == $0
|
137
|
-
begin
|
138
|
-
d = Declaration.new("backgrond-color: sdfds")
|
139
|
-
puts d.property
|
140
|
-
puts d.value
|
141
|
-
rescue PropertyError => e
|
142
|
-
puts e.message
|
143
|
-
end
|
144
71
|
end
|
data/lib/csspress/rule.rb
CHANGED
@@ -12,112 +12,55 @@
|
|
12
12
|
# body { margin : 0; padding : 0 }
|
13
13
|
#
|
14
14
|
# The components of a rule are:
|
15
|
-
# name {
|
15
|
+
# name { declaration block }
|
16
16
|
#
|
17
17
|
# All declarations of Rule can be accessed using the
|
18
18
|
# .each_declaration(){} method where each declaration
|
19
|
-
# is passed to the block
|
19
|
+
# is passed to the block.
|
20
20
|
#
|
21
21
|
# Example:
|
22
|
-
# r = Rule.new ( "
|
22
|
+
# r = Rule.new ( "my rule" )
|
23
|
+
# r.add(Declaration.new("margin", "1px"))
|
23
24
|
# r.each_declaration do |dec|
|
24
25
|
# puts dec
|
25
26
|
# end
|
26
27
|
# puts r.name
|
27
|
-
#
|
28
|
+
#
|
28
29
|
class Rule
|
29
30
|
|
30
|
-
# name of the Rule
|
31
31
|
attr_reader :name
|
32
|
-
# declarations contained within Rule
|
33
|
-
attr_reader :declarations
|
34
32
|
|
35
|
-
# Create a new Rule
|
36
|
-
#
|
33
|
+
# Create a new Rule with name
|
34
|
+
#
|
35
|
+
def initialize(name)
|
36
|
+
@name = name
|
37
|
+
@declaration_block = []
|
38
|
+
end
|
39
|
+
|
40
|
+
# add a Declaration to the rule's declaration block
|
37
41
|
#
|
38
|
-
def
|
39
|
-
|
40
|
-
@
|
41
|
-
@declarations = rp.declarations
|
42
|
+
def add(declaration)
|
43
|
+
raise ArgumentError unless declaration.instance_of?(Declaration)
|
44
|
+
@declaration_block << declaration
|
42
45
|
end
|
43
46
|
|
44
|
-
#
|
47
|
+
# iterate through the declarations in the declaration block and pass
|
48
|
+
# each one to the block
|
45
49
|
#
|
46
50
|
def each_declaration
|
47
|
-
@
|
51
|
+
@declaration_block.each do |declaration|
|
48
52
|
yield declaration
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
52
|
-
#
|
56
|
+
# Return all declarations for the rule in an array
|
53
57
|
#
|
54
|
-
def
|
55
|
-
|
58
|
+
def declaration_block
|
59
|
+
@declaration_block.dup
|
56
60
|
end
|
57
61
|
|
58
|
-
|
59
|
-
|
60
|
-
# This class parses the text entered and makes the
|
61
|
-
# name and declarations available to the Rule that
|
62
|
-
# initialised it.
|
63
|
-
#
|
64
|
-
class RuleParser #:nodoc:
|
65
|
-
|
66
|
-
attr_reader :name, :declarations
|
67
|
-
|
68
|
-
# Create a new RuleParser and parse raw_data
|
69
|
-
#
|
70
|
-
def initialize( raw_data )
|
71
|
-
@raw_data = raw_data
|
72
|
-
@name = ""
|
73
|
-
@declarations = []
|
74
|
-
parse
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
# Calls the methods needed to retrieve the
|
80
|
-
# information from @raw_data
|
81
|
-
#
|
82
|
-
def parse
|
83
|
-
@name = get_rule_name
|
84
|
-
@declarations = get_declarations
|
85
|
-
end
|
86
|
-
|
87
|
-
# Get the name of the rule from @raw_data
|
88
|
-
#---
|
89
|
-
# Simply a case of cutting the front off the
|
90
|
-
# @raw data string up to the first '{' and
|
91
|
-
# remove any white space
|
92
|
-
# +++
|
93
|
-
#
|
94
|
-
def get_rule_name
|
95
|
-
@raw_data.slice(0, @raw_data.index("{")).strip
|
96
|
-
end
|
97
|
-
|
98
|
-
# Get an array of declartaions for the Rule.
|
99
|
-
#---
|
100
|
-
# Get the part of @raw_data between '{'..'}'
|
101
|
-
# This is all of the declaration text.
|
102
|
-
# Declarations are delimeted by ';' so
|
103
|
-
# the string is split on the semi-colon and
|
104
|
-
# a new Declaration object is created for each
|
105
|
-
# one.
|
106
|
-
#+++
|
107
|
-
#
|
108
|
-
def get_declarations
|
109
|
-
tmp = []
|
110
|
-
raw = @raw_data.slice(@raw_data.index("{")+1..@raw_data.index("}")-1).strip
|
111
|
-
raw.split(";").each do |line|
|
112
|
-
tmp << Declaration.new(line.strip)
|
113
|
-
end
|
114
|
-
tmp
|
115
|
-
end
|
62
|
+
def to_s
|
63
|
+
"#{@name}{#{@declaration_block.join(";")}}"
|
116
64
|
end
|
117
|
-
|
118
|
-
|
119
|
-
if __FILE__ == $0
|
120
|
-
r = Rule.new("this is a test { background-color: sdfds; color:adlkasdj}")
|
121
|
-
puts r.name
|
122
|
-
puts r.declarations
|
65
|
+
|
123
66
|
end
|
data/lib/csspress/style_sheet.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/local/bin/ruby -w
|
2
2
|
|
3
|
-
#
|
3
|
+
# style_sheet_parser.rb
|
4
4
|
#
|
5
5
|
# Created by David Madden on 2008-05-14.
|
6
6
|
# Copyright 2008 David Madden. All rights reserved.
|
@@ -12,232 +12,48 @@
|
|
12
12
|
# contains can be accessed using the .each_rule(){} method which yields
|
13
13
|
# each Rule to the block.
|
14
14
|
#
|
15
|
-
# StyleSheet can also accept a CSS file as a paramiter to .new or using the
|
16
|
-
# .load() method. This file is then converted into Rule objects and they are
|
17
|
-
# added to StyleSheet. A compressed version of StyleSheet can be output using
|
18
|
-
# a TemplateBuilder object and passing it StyleSheet as a parameter.
|
19
|
-
#
|
20
15
|
# Example:
|
21
|
-
# ss = StyleSheet.new
|
16
|
+
# ss = StyleSheet.new
|
17
|
+
# ss.add( Rule.new("A Rule") )
|
22
18
|
# tb = TemplateBuilder.new ( ss )
|
23
19
|
# puts tb.publish # output compressed version of ss
|
24
|
-
#
|
20
|
+
#
|
25
21
|
class StyleSheet
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
# TODO: remove this and only allow access through each_rule.
|
30
|
-
# +++
|
31
|
-
attr_reader :rules
|
32
|
-
|
33
|
-
# Creates a new StyleSheet object. Can also accept a file name
|
34
|
-
# and parse the contents to initalize the StyleSheet with the file's
|
35
|
-
# contents.
|
36
|
-
#
|
37
|
-
def initialize(file=nil)
|
23
|
+
def initialize
|
24
|
+
# Store style rules in order
|
38
25
|
@rules = []
|
39
|
-
load file unless file.nil?
|
40
|
-
end
|
41
|
-
|
42
|
-
# Yeild each style rule in self
|
43
|
-
#
|
44
|
-
def each_rule
|
45
|
-
@rules.each do |rule|
|
46
|
-
yield rule
|
47
|
-
end
|
48
26
|
end
|
49
27
|
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#def compress
|
53
|
-
# out = ""
|
54
|
-
# self.each_style do |rule|
|
55
|
-
# out << rule.compress
|
56
|
-
# end
|
57
|
-
# out
|
58
|
-
#end
|
59
|
-
|
60
|
-
# Load a CSS file into self
|
61
|
-
#
|
62
|
-
def load(file)
|
63
|
-
ssp = StyleSheetParser.new(file)
|
64
|
-
ssp.each { |rule| add(rule) }
|
65
|
-
end
|
66
|
-
|
67
|
-
# Add a rule to self
|
68
|
-
#
|
28
|
+
# Add rule to StyleSheet
|
29
|
+
# Raises ArgumentError rule is not a Rule
|
69
30
|
def add(rule)
|
70
|
-
|
71
|
-
|
31
|
+
raise ArgumentError unless rule.instance_of?(Rule)
|
32
|
+
@rules << rule
|
33
|
+
@self
|
72
34
|
end
|
73
35
|
|
74
|
-
#
|
75
|
-
#
|
76
|
-
def to_s
|
77
|
-
out = ""
|
78
|
-
self.each_rule do |rule|
|
79
|
-
out << "#{rule}\n"
|
80
|
-
end
|
81
|
-
out
|
82
|
-
end
|
83
|
-
|
84
|
-
# Number of Rules in Self
|
85
|
-
#
|
36
|
+
# The number of rules in self
|
86
37
|
def size
|
87
38
|
@rules.size
|
88
39
|
end
|
89
40
|
|
90
|
-
#
|
91
|
-
#
|
92
|
-
def
|
93
|
-
|
41
|
+
# Iterate through all rules in self and yield them
|
42
|
+
# to a block
|
43
|
+
def each_rule
|
44
|
+
@rules.each {|r| yield r }
|
94
45
|
end
|
95
46
|
|
96
|
-
|
47
|
+
# Return an array of all rules in self
|
48
|
+
def rules
|
49
|
+
@rules.dup
|
50
|
+
end
|
97
51
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
# Due to the flexible nature of CSS syntax most of the
|
103
|
-
# work performed by the parser is envolved in normalizing
|
104
|
-
# the text into an array of style rules with the
|
105
|
-
# comments striped out.
|
106
|
-
#
|
107
|
-
# This parser uses patern matching and string manupulation
|
108
|
-
# rather than analysing the file byte, by byte. This may or
|
109
|
-
# may not be proved to be a good thing.
|
110
|
-
#
|
111
|
-
# At present all '@import' statements with in the CSS file are
|
112
|
-
# ignored!
|
113
|
-
#
|
114
|
-
# A file is processed as follows:
|
115
|
-
# 1. The file is read into an array (@raw_data)
|
116
|
-
# 2. White space is removed from the beginnig and end of each field in the @raw_data
|
117
|
-
# 3. Comments are sepatated into there own array fields as they could be mixed into style code
|
118
|
-
# 4. All fields with comments and empty fields are removed from @raw_data
|
119
|
-
# 5. All style rules are put in their own array field
|
120
|
-
# 6. Each field has any white space removed
|
121
|
-
# Data clean!
|
122
|
-
#
|
123
|
-
# Only the file in gerneral is parsed. Parsing of Rules and Declarations
|
124
|
-
# is handled by them internaly.
|
125
|
-
#++
|
126
|
-
#
|
127
|
-
class StyleSheetParser #:nodoc:
|
128
|
-
attr_reader :lines
|
129
|
-
|
130
|
-
# Creates new StyleSheetParser to parse the file
|
131
|
-
# file_name
|
132
|
-
#
|
133
|
-
def initialize( file_name )
|
134
|
-
@file = file_name
|
135
|
-
@raw_data = []
|
136
|
-
parse
|
137
|
-
end
|
138
|
-
|
139
|
-
# Yield each rule in the parsed file
|
140
|
-
#
|
141
|
-
def each
|
142
|
-
@raw_data.each do |rule|
|
143
|
-
yield rule
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
private
|
148
|
-
|
149
|
-
# Controls the processing of the data by calling
|
150
|
-
# a number of private functions.
|
151
|
-
#
|
152
|
-
# The order of the method calls is important and
|
153
|
-
# the successful removal of comments depends
|
154
|
-
# upon it!
|
155
|
-
#
|
156
|
-
def parse
|
157
|
-
get_lines
|
158
|
-
remove_white_space
|
159
|
-
separate_comments
|
160
|
-
delete_comments_and_blank_lines
|
161
|
-
separate_rules
|
162
|
-
remove_white_space
|
163
|
-
end
|
164
|
-
|
165
|
-
# Read in all lines of @file to @raw_data.
|
166
|
-
# Will raise an error if there is any problem with
|
167
|
-
# accessing the file.
|
168
|
-
#
|
169
|
-
def get_lines
|
170
|
-
begin
|
171
|
-
f = File.open( @file, 'r' )
|
172
|
-
@raw_data = f.readlines
|
173
|
-
rescue
|
174
|
-
raise IOError, "Could not process file: #{@file}"
|
175
|
-
ensure
|
176
|
-
f.close unless f.nil?
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
# This removes white space from the beginning
|
181
|
-
# and end of every field in the @raw_data array,
|
182
|
-
# as well as removing runs of space characters.
|
183
|
-
#
|
184
|
-
def remove_white_space
|
185
|
-
@raw_data.each do |line|
|
186
|
-
line.strip! # remove white space from line beginnig and end
|
187
|
-
line.squeeze!( " " ) # remove runs of spaces
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
# Put a linebreak before and after every comment
|
192
|
-
# in @raw_data
|
193
|
-
#
|
194
|
-
def separate_comments
|
195
|
-
tmp = @raw_data.join(" ") # convert to string
|
196
|
-
tmp.gsub!( '/*', "\n/*" ) # add new line before comment
|
197
|
-
tmp.gsub!( '*/', "*/\n" ) # add new line after comment
|
198
|
-
@raw_data = tmp.split( "\n" ) # convert to array
|
199
|
-
end
|
200
|
-
|
201
|
-
# Remove comments and blank lines from @raw_data.
|
202
|
-
#
|
203
|
-
# This method currently also removes import stetments.
|
204
|
-
# TODO: move import handleing to separate method.
|
205
|
-
#
|
206
|
-
def delete_comments_and_blank_lines
|
207
|
-
tmp = []
|
208
|
-
@raw_data.each do |line|
|
209
|
-
line.strip! # remove any white space
|
210
|
-
next if line.length < 1 # ignore blank line
|
211
|
-
next if line =~ /\/\*/ # ignore comments
|
212
|
-
next if line =~ /import/ # ignore imports specially
|
213
|
-
tmp << line
|
214
|
-
end
|
215
|
-
@raw_data = tmp
|
52
|
+
def to_s
|
53
|
+
out = ""
|
54
|
+
@rules.each do |rule|
|
55
|
+
out << rule.to_s
|
216
56
|
end
|
217
|
-
|
218
|
-
# Add a new line character after every style rule
|
219
|
-
# in @raw_data
|
220
|
-
#
|
221
|
-
def separate_rules
|
222
|
-
tmp = @raw_data.join( " " ) # convert to string
|
223
|
-
tmp.gsub!( '}', "}\n" ) # add a new line after every style rule
|
224
|
-
@raw_data = tmp.split( "\n" ) # convert to array
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
|
230
|
-
if __FILE__ == $0
|
231
|
-
begin
|
232
|
-
ss = StyleSheet.new( "../test_data/style.css" )
|
233
|
-
#ss.load( "../test_data/style.css" )
|
234
|
-
tb = TemplateBuilder.new(ss)
|
235
|
-
puts tb.publish
|
236
|
-
rescue Declaration::PropertyError => e
|
237
|
-
puts e
|
238
|
-
rescue IOError => e
|
239
|
-
puts e
|
240
|
-
rescue Error => e
|
241
|
-
puts e
|
57
|
+
out
|
242
58
|
end
|
243
59
|
end
|
@@ -0,0 +1,287 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# style_sheet.rb
|
4
|
+
#
|
5
|
+
# Created by David Madden on 2008-05-14.
|
6
|
+
# Copyright 2008 David Madden. All rights reserved.
|
7
|
+
#
|
8
|
+
# This is Free Software. See LICENSE for details.
|
9
|
+
|
10
|
+
# This class is responsible for processing a CSS file.
|
11
|
+
# It creates a StyleSheet object from the content of the file.
|
12
|
+
# The StyleSheet can be obtained using the style_sheet() method.
|
13
|
+
#
|
14
|
+
# Example:
|
15
|
+
# ssp = StyleSheetParser("foo.css")
|
16
|
+
# stylesheet = ssp.style_sheet
|
17
|
+
# puts stylesheet
|
18
|
+
#
|
19
|
+
#--
|
20
|
+
# Due to the flexible nature of CSS syntax most of the
|
21
|
+
# work performed by the parser is envolved in normalizing
|
22
|
+
# the text into an array of style rules with the
|
23
|
+
# comments striped out.
|
24
|
+
#
|
25
|
+
# This parser uses patern matching and string manupulation
|
26
|
+
# rather than analysing the file byte, by byte. This may or
|
27
|
+
# may not be proved to be a good thing.
|
28
|
+
#
|
29
|
+
# At present all '@import' statements with in the CSS file are
|
30
|
+
# ignored!
|
31
|
+
#
|
32
|
+
# A file is processed as follows:
|
33
|
+
# 1. The file is read into an array (@raw_data)
|
34
|
+
# 2. White space is removed from the beginnig and end of each field in the @raw_data
|
35
|
+
# 3. Comments are sepatated into there own array fields as they could be mixed into style code
|
36
|
+
# 4. All fields with comments and empty fields are removed from @raw_data
|
37
|
+
# 5. All style rules are put in their own array field
|
38
|
+
# 6. Each field has any white space removed
|
39
|
+
# 7. A style sheet object is populated with the parsed rules
|
40
|
+
# Data clean!
|
41
|
+
#
|
42
|
+
# Only the file in gerneral is parsed. Parsing of Rules and Declarations
|
43
|
+
# is handled by internaly by nested classes. StyleSheet parser breaks a
|
44
|
+
# file down into indevidule rules. It then uses a RuleParse object to parse
|
45
|
+
# each of these rules. The rule parser then breaks up the rule into a name and
|
46
|
+
# declaration block. It the uses a Declaration Parser on each declaration.
|
47
|
+
#++
|
48
|
+
#
|
49
|
+
class StyleSheetParser
|
50
|
+
|
51
|
+
# Creates new StyleSheetParser to parse the file
|
52
|
+
# file
|
53
|
+
#
|
54
|
+
def initialize( file )
|
55
|
+
@file = file
|
56
|
+
@raw_data = []
|
57
|
+
@style_sheet = nil
|
58
|
+
parse
|
59
|
+
end
|
60
|
+
|
61
|
+
# Get parsed style sheet
|
62
|
+
#
|
63
|
+
def style_sheet
|
64
|
+
@style_sheet.dup
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# Yield each rule in the parsed file
|
70
|
+
#
|
71
|
+
def each
|
72
|
+
@raw_data.each do |rule|
|
73
|
+
yield rule
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Controls the processing of the data by calling
|
78
|
+
# a number of private functions.
|
79
|
+
#
|
80
|
+
# The order of the method calls is important and
|
81
|
+
# the successful removal of comments depends
|
82
|
+
# upon it!
|
83
|
+
#
|
84
|
+
def parse
|
85
|
+
get_lines
|
86
|
+
remove_white_space
|
87
|
+
separate_comments
|
88
|
+
delete_comments_and_blank_lines
|
89
|
+
separate_rules
|
90
|
+
remove_white_space
|
91
|
+
populate_style_sheet
|
92
|
+
end
|
93
|
+
|
94
|
+
# Read in all lines of @file to @raw_data.
|
95
|
+
# Will raise an error if there is any problem with
|
96
|
+
# accessing the file.
|
97
|
+
#
|
98
|
+
def get_lines
|
99
|
+
begin
|
100
|
+
f = File.open( @file, 'r' )
|
101
|
+
@raw_data = f.readlines
|
102
|
+
rescue
|
103
|
+
raise IOError, "Could not process file: #{@file}"
|
104
|
+
ensure
|
105
|
+
f.close unless f.nil?
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# This removes white space from the beginning
|
110
|
+
# and end of every field in the @raw_data array,
|
111
|
+
# as well as removing runs of space characters.
|
112
|
+
#
|
113
|
+
def remove_white_space
|
114
|
+
@raw_data.each do |line|
|
115
|
+
line.strip! # remove white space from line beginnig and end
|
116
|
+
line.squeeze!( " " ) # remove runs of spaces
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Put a linebreak before and after every comment
|
121
|
+
# in @raw_data
|
122
|
+
#
|
123
|
+
def separate_comments
|
124
|
+
tmp = @raw_data.join(" ") # convert to string
|
125
|
+
tmp.gsub!( '/*', "\n/*" ) # add new line before comment
|
126
|
+
tmp.gsub!( '*/', "*/\n" ) # add new line after comment
|
127
|
+
@raw_data = tmp.split( "\n" ) # convert to array
|
128
|
+
end
|
129
|
+
|
130
|
+
# Remove comments and blank lines from @raw_data.
|
131
|
+
#
|
132
|
+
# This method currently also removes import stetments.
|
133
|
+
# TODO: move import handleing to separate method.
|
134
|
+
#
|
135
|
+
def delete_comments_and_blank_lines
|
136
|
+
tmp = []
|
137
|
+
@raw_data.each do |line|
|
138
|
+
line.strip! # remove any white space
|
139
|
+
next if line.length < 1 # ignore blank line
|
140
|
+
next if line =~ /\/\*/ # ignore comments
|
141
|
+
next if line =~ /import/ # ignore imports specially
|
142
|
+
tmp << line
|
143
|
+
end
|
144
|
+
@raw_data = tmp
|
145
|
+
end
|
146
|
+
|
147
|
+
# Add a new line character after every style rule
|
148
|
+
# in @raw_data
|
149
|
+
#
|
150
|
+
def separate_rules
|
151
|
+
tmp = @raw_data.join( " " ) # convert to string
|
152
|
+
tmp.gsub!( '}', "}\n" ) # add a new line after every style rule
|
153
|
+
@raw_data = tmp.split( "\n" ) # convert to array
|
154
|
+
end
|
155
|
+
|
156
|
+
def populate_style_sheet
|
157
|
+
tmp = StyleSheet.new
|
158
|
+
each do |rule|
|
159
|
+
begin
|
160
|
+
rp = RuleParser.new(rule)
|
161
|
+
tmp.add(rp.rule)
|
162
|
+
rescue PropertyError
|
163
|
+
puts "An invalid property was detected: #{rule}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
@style_sheet = tmp
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
# This class parses the text entered and makes the
|
171
|
+
# name and declarations available to the Rule that
|
172
|
+
# initialised it.
|
173
|
+
#
|
174
|
+
class RuleParser #:nodoc:
|
175
|
+
attr_reader :rule
|
176
|
+
|
177
|
+
# Create a new RuleParser and parse raw_data
|
178
|
+
#
|
179
|
+
def initialize( raw_data )
|
180
|
+
@rule = nil
|
181
|
+
@raw_data = raw_data
|
182
|
+
@name = ""
|
183
|
+
@declarations = []
|
184
|
+
parse
|
185
|
+
end
|
186
|
+
|
187
|
+
private
|
188
|
+
|
189
|
+
# Calls the methods needed to retrieve the
|
190
|
+
# information from @raw_data
|
191
|
+
#
|
192
|
+
def parse
|
193
|
+
@name = get_rule_name
|
194
|
+
@declarations = get_declarations
|
195
|
+
@rule = Rule.new(@name)
|
196
|
+
@declarations.each {|dec| @rule.add(dec)}
|
197
|
+
end
|
198
|
+
|
199
|
+
# Get the name of the rule from @raw_data
|
200
|
+
#---
|
201
|
+
# Simply a case of cutting the front off the
|
202
|
+
# @raw data string up to the first '{' and
|
203
|
+
# remove any white space
|
204
|
+
# +++
|
205
|
+
#
|
206
|
+
def get_rule_name
|
207
|
+
@raw_data.slice(0, @raw_data.index("{")).strip
|
208
|
+
end
|
209
|
+
|
210
|
+
# Get an array of declartaions for the Rule.
|
211
|
+
#---
|
212
|
+
# Get the part of @raw_data between '{'..'}'
|
213
|
+
# This is all of the declaration text.
|
214
|
+
# Declarations are delimeted by ';' so
|
215
|
+
# the string is split on the semi-colon and
|
216
|
+
# a new Declaration object is created for each
|
217
|
+
# one.
|
218
|
+
#+++
|
219
|
+
#
|
220
|
+
def get_declarations
|
221
|
+
tmp = []
|
222
|
+
raw = @raw_data.slice(@raw_data.index("{")+1..@raw_data.index("}")-1).strip
|
223
|
+
raw.split(";").each do |line|
|
224
|
+
dp = DeclarationParser.new(line.strip)
|
225
|
+
tmp << dp.declaration
|
226
|
+
end
|
227
|
+
tmp
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# This class parses the text entered and makes the
|
232
|
+
# property and value available to the Declaration that
|
233
|
+
# initialised it.
|
234
|
+
#
|
235
|
+
class DeclarationParser #:nodoc:
|
236
|
+
attr_reader :declaration
|
237
|
+
|
238
|
+
def initialize(raw_data)
|
239
|
+
@declaration = nil
|
240
|
+
@raw_data = raw_data
|
241
|
+
@property = ""
|
242
|
+
@value = ""
|
243
|
+
parse
|
244
|
+
end
|
245
|
+
|
246
|
+
private
|
247
|
+
|
248
|
+
# Call methods to parse @raw_data and
|
249
|
+
# extract the property and name.
|
250
|
+
#
|
251
|
+
# Raise an error if the property found
|
252
|
+
# is invalid.
|
253
|
+
#
|
254
|
+
def parse
|
255
|
+
@property = get_property
|
256
|
+
@value = get_value
|
257
|
+
@declaration = Declaration.new(@property, @value)
|
258
|
+
end
|
259
|
+
|
260
|
+
# Get the property from @raw_data
|
261
|
+
#---
|
262
|
+
# The property is the part of @raw_data
|
263
|
+
# before the ':' character.
|
264
|
+
#+++
|
265
|
+
#
|
266
|
+
def get_property
|
267
|
+
@raw_data.slice(0, @raw_data.index(":")).strip
|
268
|
+
end
|
269
|
+
|
270
|
+
# Get the value from @raw_data
|
271
|
+
#---
|
272
|
+
# The value is the part of @raw_data
|
273
|
+
# after the ':' character.
|
274
|
+
#+++
|
275
|
+
#
|
276
|
+
def get_value
|
277
|
+
@raw_data.slice(@raw_data.index(":")+1..@raw_data.size-1).strip
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
|
284
|
+
if __FILE__ == $0
|
285
|
+
ssp = StyleSheetParser.new("../../test/style.css")
|
286
|
+
puts ssp.style_sheet
|
287
|
+
end
|
@@ -29,15 +29,16 @@ require 'erb'
|
|
29
29
|
class TemplateBuilder
|
30
30
|
|
31
31
|
# Style sheet to publish
|
32
|
-
attr_reader :style_sheet
|
32
|
+
attr_reader :style_sheet, :template
|
33
33
|
TEMPLATE_DIR = "/../templates/"
|
34
|
-
DEFAULT = "default.csst"
|
34
|
+
DEFAULT = "/../templates/default.csst"
|
35
35
|
# Create a new TemplateBuilder for style_sheet using
|
36
36
|
# template.
|
37
37
|
#
|
38
38
|
def initialize( style_sheet, template=DEFAULT )
|
39
|
+
raise ArgumentError unless style_sheet.instance_of?(StyleSheet)
|
39
40
|
@style_sheet = style_sheet
|
40
|
-
@template =
|
41
|
+
@template = template
|
41
42
|
end
|
42
43
|
|
43
44
|
|
@@ -47,7 +48,7 @@ class TemplateBuilder
|
|
47
48
|
#
|
48
49
|
def publish
|
49
50
|
begin
|
50
|
-
template = File.read(@template)
|
51
|
+
template = File.read(File.dirname(__FILE__) + @template)
|
51
52
|
engin = ERB.new(template)
|
52
53
|
t = engin.result(binding())
|
53
54
|
# Chomp the trailing newline
|
@@ -56,18 +57,4 @@ class TemplateBuilder
|
|
56
57
|
raise IOError, "Could not use requested template file: #{@template}"
|
57
58
|
end
|
58
59
|
end
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
if __FILE__ == $0
|
63
|
-
|
64
|
-
require "style_sheet"
|
65
|
-
|
66
|
-
ss = StyleSheet.new
|
67
|
-
ss.load( "../test_data/style.css" )
|
68
|
-
tb = TemplateBuilder.new(ss, "../templates/style_sheet.cssplate")
|
69
|
-
# out = File.new("../test_data/compressed_style.css", "w")
|
70
|
-
# out.write(tb.publish)
|
71
|
-
# out.close
|
72
|
-
puts tb.publish
|
73
60
|
end
|
data/lib/csspress/version.rb
CHANGED
data/spec/csspress_spec.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe Declaration do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@dec = Declaration.new("margin", "0")
|
7
|
+
end
|
8
|
+
|
9
|
+
# is everything connected?
|
10
|
+
it "should exist" do
|
11
|
+
@dec.should_not be_nil
|
12
|
+
@dec.should be_an_instance_of(Declaration)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have a property and be readable" do
|
16
|
+
@dec.property.should_not be_nil
|
17
|
+
@dec.property.should == "margin"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have a value and be readable" do
|
21
|
+
@dec.value.should_not be_nil
|
22
|
+
@dec.value.should == "0"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should raise a property error if property is not valid" do
|
26
|
+
lambda { dec = Declaration.new("foo", "10") }.should raise_error(Declaration::PropertyError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/spec/rule_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe Rule do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@rule = Rule.new("Test Rule")
|
7
|
+
@decs = [Declaration.new("border", "1px"),Declaration.new("margin", "1px"),Declaration.new("width","2px")]
|
8
|
+
end
|
9
|
+
|
10
|
+
# is everything connected?
|
11
|
+
it "should exist" do
|
12
|
+
@rule.should_not be_nil
|
13
|
+
@rule.should be_an_instance_of(Rule)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have a name" do
|
17
|
+
@rule.name.should_not be_nil
|
18
|
+
@rule.name.should == "Test Rule"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should allow declarations to be added" do
|
22
|
+
@rule.add(Declaration.new("height","2px"))
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should only allow declarations to be added" do
|
26
|
+
lambda { @rule.add("foo") }.should raise_error(ArgumentError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow iteration of the declarations" do
|
30
|
+
@decs.each {|dec| @rule.add(dec)}
|
31
|
+
output = []
|
32
|
+
@rule.each_declaration {|dec| output << dec}
|
33
|
+
@decs.should == output
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should preserve the order of declarations" do
|
37
|
+
@decs.each {|dec| @rule.add(dec) }
|
38
|
+
out = @rule.declaration_block
|
39
|
+
@decs.each_with_index do |dec, index|
|
40
|
+
dec.should == out[index]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should retun declaration block as an array of declarations" do
|
45
|
+
@decs.each {|dec| @rule.add(dec) }
|
46
|
+
@decs.should eql(@rule.declaration_block)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe StyleSheetParser do
|
4
|
+
|
5
|
+
it "should accept a file" do
|
6
|
+
ssp = StyleSheetParser.new("test/style.css")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should produce a style sheet" do
|
10
|
+
ssp = StyleSheetParser.new("test/style.css")
|
11
|
+
ss = ssp.style_sheet
|
12
|
+
ss.should be_instance_of(StyleSheet)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe StyleSheet do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@style_sheet = StyleSheet.new
|
7
|
+
@rules = [Rule.new("Test1"), Rule.new("Test2"), Rule.new("Test3")]
|
8
|
+
@rule = Rule.new("test")
|
9
|
+
end
|
10
|
+
|
11
|
+
# is everything connected?
|
12
|
+
it "should exist" do
|
13
|
+
@style_sheet.should_not be_nil
|
14
|
+
@style_sheet.should be_an_instance_of(StyleSheet)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be empty when created" do
|
18
|
+
@style_sheet.size.should == 0
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should know how many rules it contains" do
|
22
|
+
total = 5
|
23
|
+
1.upto(total) do |i|
|
24
|
+
@style_sheet.add(@rule)
|
25
|
+
end
|
26
|
+
@style_sheet.size.should == total
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should accept rule objects" do
|
30
|
+
@style_sheet.add(@rule)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should only allow rules to be added" do
|
34
|
+
lambda { @style_sheet.add("foo") }.should raise_error(ArgumentError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should yield all rules to a block" do
|
38
|
+
@rules.each {|rule| @style_sheet.add(rule) }
|
39
|
+
output = []
|
40
|
+
@style_sheet.each_rule {|rule| output << rule }
|
41
|
+
output.should == @rules
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return all rules as an array" do
|
45
|
+
@rules.each {|rule| @style_sheet.add(rule) }
|
46
|
+
@rules.should eql(@style_sheet.rules)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should preserve the order rules are added in" do
|
50
|
+
@rules.each {|rule| @style_sheet.add(rule) }
|
51
|
+
out = @style_sheet.rules
|
52
|
+
@rules.each_with_index do |rule, index|
|
53
|
+
rule.should == out[index]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe TemplateBuilder do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@ss = StyleSheet.new
|
7
|
+
r = Rule.new("foo")
|
8
|
+
r.add(Declaration.new("margin", "0px"))
|
9
|
+
@ss.add(r)
|
10
|
+
end
|
11
|
+
it "should accept a StyleSheet" do
|
12
|
+
TemplateBuilder.new(StyleSheet.new)
|
13
|
+
end
|
14
|
+
it "should raise an argument error if it is not a stylesheet" do
|
15
|
+
lambda { TemplateBuilder.new("foo") }.should raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
it "should generate a string" do
|
18
|
+
tb = TemplateBuilder.new(@ss)
|
19
|
+
str = tb.publish
|
20
|
+
str.should be_an_instance_of(String)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have a default template" do
|
24
|
+
TemplateBuilder::DEFAULT.should_not be_nil
|
25
|
+
TemplateBuilder::DEFAULT.should be_an_instance_of(String)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should accept a custom template to build" do
|
29
|
+
tb = TemplateBuilder.new(@ss, "A/test/file")
|
30
|
+
tb.template.should == "A/test/file"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should raise a IOError if the template file it not valid" do
|
34
|
+
lambda { tb = TemplateBuilder.new(@ss, "A/test/file"); tb.publish }.should raise_error(IOError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csspress
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Madden
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-05-
|
12
|
+
date: 2008-05-20 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- lib/csspress/declaration.rb
|
42
42
|
- lib/csspress/rule.rb
|
43
43
|
- lib/csspress/style_sheet.rb
|
44
|
+
- lib/csspress/style_sheet_parser.rb
|
44
45
|
- lib/csspress/template_builder.rb
|
45
46
|
- lib/csspress/version.rb
|
46
47
|
- lib/templates/default.csst
|
@@ -50,8 +51,13 @@ files:
|
|
50
51
|
- script/txt2html
|
51
52
|
- setup.rb
|
52
53
|
- spec/csspress_spec.rb
|
54
|
+
- spec/declaration_spec.rb
|
55
|
+
- spec/rule_spec.rb
|
53
56
|
- spec/spec.opts
|
54
57
|
- spec/spec_helper.rb
|
58
|
+
- spec/style_sheet_spec.rb
|
59
|
+
- spec/style_sheet_parser_spec.rb
|
60
|
+
- spec/template_builder_spec.rb
|
55
61
|
- tasks/custom.rake
|
56
62
|
- tasks/deployment.rake
|
57
63
|
- tasks/environment.rake
|
@@ -65,7 +71,7 @@ has_rdoc: true
|
|
65
71
|
homepage: http://csspress.rubyforge.org
|
66
72
|
post_install_message: |+
|
67
73
|
|
68
|
-
For more information on csspress, see http://csspress.
|
74
|
+
For more information on csspress, see http://www.csspress.net
|
69
75
|
|
70
76
|
|
71
77
|
To get cracking straight away:
|