csspress 0.0.3 → 0.0.4
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/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:
|