csspress 0.0.1

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,144 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # declaration.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
+ # Declaration represents a declaration in a style sheet rule.
11
+ # It is composed of a property and a value. The property must be
12
+ # valid.
13
+ #
14
+ # Declaration takes a string and populates itself.
15
+ #
16
+ # Example:
17
+ # d = declaration.new ( "border-color : blue" )
18
+ # puts d.property #=> "border-color"
19
+ # puts d.value #=> "blue"
20
+ #
21
+ class Declaration
22
+
23
+ # Declaration property
24
+ attr_reader :property
25
+ # Declaration value
26
+ attr_reader :value
27
+
28
+ # internal error for invalid property types
29
+ #
30
+ class PropertyError < StandardError
31
+ # do nothing - just creating a specific error
32
+ end
33
+
34
+ # Properties for CSS1 to CSS3
35
+ VALID_PROPERTIES = %w(
36
+ alignment-adjust alignment-baseline appearance azimuth background background-attachment background-break
37
+ background-clip background-color background-image background-origin background-position background-repeat
38
+ background-size baseline-shift binding bookmark-label bookmark-level bookmark-target border border-bottom
39
+ border-bottom-color border-bottom-left-radius border-bottom-right-radius border-bottom-style border-bottom-width
40
+ border-break border-collapse border-color border-image border-left border-left-color border-left-style
41
+ border-left-width border-length border-radius border-right border-right-color border-right-style border-right-width
42
+ border-spacing border-style border-top border-top-color border-top-left-radius border-top-right-radius border-top-style
43
+ border-top-width border-width bottom box-align box-direction box-flex box-flex-group box-lines box-orient box-pack
44
+ box-shadow box-sizing caption-side clear clip color color-profile column-break-after column-break-before column-count
45
+ column-fill column-gap column-rule column-rule-color column-rule-style column-rule-width column-span column-width columns
46
+ content counter-increment counter-reset crop cue cue-after cue-before cursor direction display dominant-baseline
47
+ drop-initial-after-adjust drop-initial-after-align drop-initial-before-adjust drop-initial-before-align
48
+ drop-initial-size drop-initial-value elevation empty-cells fit fit-position float float-offset font
49
+ font-effect font-emphasize font-emphasize-position font-emphasize-style font-family font-size font-size-adjust
50
+ font-smooth font-stretch font-style font-variant font-weight grid-columns grid-rows hanging-punctuation height
51
+ hyphenate-after hyphenate-before hyphenate-character hyphenate-lines hyphenate-resource hyphens icon image-orientation
52
+ image-resolution inline-box-align left letter-spacing line-height line-stacking line-stacking-ruby line-stacking-shift
53
+ line-stacking-strategy list-style list-style-image list-style-position list-style-type margin margin-bottom margin-left
54
+ margin-right margin-top mark mark-after mark-before marker-offset marks marquee-direction marquee-loop marquee-speed
55
+ marquee-style max-height max-width min-height min-width move-to nav-down nav-index nav-left nav-right nav-up opacity orphans
56
+ outline outline-color outline-offset outline-style outline-width overflow overflow-style overflow-x overflow-y padding
57
+ padding-bottom padding-left padding-right padding-top page page-break-after page-break-before page-break-inside page-policy
58
+ pause pause-after pause-before phonemes pitch pitch-range play-during position presentation-level punctuation-trim quotes
59
+ rendering-intent resize rest rest-after rest-before richness right rotation rotation-point ruby-align ruby-overhang ruby-position
60
+ ruby-span size speak speak-header speak-numeral speak-punctuation speech-rate stress string-set tab-side table-layout target
61
+ target-name target-new target-position text-align text-align-last text-decoration text-emphasis text-height text-indent
62
+ text-justify text-outline text-replace text-shadow text-transform text-wrap top unicode-bidi vertical-align visibility
63
+ voice-balance voice-duration voice-family voice-pitch voice-pitch-range voice-rate voice-stress voice-volume volume
64
+ white-space white-space-collapse widows width word-break word-spacing word-wrap z-index
65
+ )
66
+
67
+ ## Create a new Declaration from a string
68
+ # (The string should be valid CSS!)
69
+ #
70
+ def initialize(text)
71
+ dp = DeclarationParser.new(text)
72
+ @property = dp.property
73
+ @value = dp.value
74
+ end
75
+
76
+ # Print out the rule neatly
77
+ #
78
+ def to_s
79
+ "#{@property}:#{@value}"
80
+ end
81
+
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
+ end
@@ -0,0 +1,123 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # rule.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
+ # Rule represents a rule in a style sheet.
11
+ # An example of a rule would be:
12
+ # body { margin : 0; padding : 0 }
13
+ #
14
+ # The components of a rule are:
15
+ # name { declarations }
16
+ #
17
+ # All declarations of Rule can be accessed using the
18
+ # .each_declaration(){} method where each declaration
19
+ # is passed to the block as a Declaration object.
20
+ #
21
+ # Example:
22
+ # r = Rule.new ( "foo { margin: 0; padding: 0 }" )
23
+ # r.each_declaration do |dec|
24
+ # puts dec
25
+ # end
26
+ # puts r.name
27
+ #
28
+ class Rule
29
+
30
+ # name of the Rule
31
+ attr_reader :name
32
+ # declarations contained within Rule
33
+ attr_reader :declarations
34
+
35
+ # Create a new Rule from a string
36
+ # (The string should be a valid CSS rule!)
37
+ #
38
+ def initialize( string )
39
+ rp = RuleParser.new( string )
40
+ @name = rp.name
41
+ @declarations = rp.declarations
42
+ end
43
+
44
+ # Yeild all declarations for self
45
+ #
46
+ def each_declaration
47
+ @declarations.each do |declaration|
48
+ yield declaration
49
+ end
50
+ end
51
+
52
+ # Print out the rule neatly
53
+ #
54
+ def to_s
55
+ "#{@name}{#{@declarations.join(";")}}"
56
+ end
57
+
58
+ private
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
116
+ end
117
+ end
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
123
+ end
@@ -0,0 +1,243 @@
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
+ # StyleSheet is a container class for Rule objects which can be added
11
+ # individually using the .add() method. The Rule objects that StyleSheet
12
+ # contains can be accessed using the .each_rule(){} method which yields
13
+ # each Rule to the block.
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
+ # Example:
21
+ # ss = StyleSheet.new ( "foo.css" )
22
+ # tb = TemplateBuilder.new ( ss )
23
+ # puts tb.publish # output compressed version of ss
24
+ #
25
+ class StyleSheet
26
+
27
+ # rule objects
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)
38
+ @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
+ end
49
+
50
+ # Output a compressed version of self
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
+ #
69
+ def add(rule)
70
+ @rules << Rule.new(rule)
71
+ self
72
+ end
73
+
74
+ # Output self as String
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
+ #
86
+ def size
87
+ @rules.size
88
+ end
89
+
90
+ # Alias of size
91
+ #
92
+ def length
93
+ size
94
+ end
95
+
96
+ private
97
+
98
+ # This class is responsible for processing a CSS file
99
+ # and allows iteration over the rules contained within
100
+ # the file to add to a StyleSheet object.
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
216
+ 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
242
+ end
243
+ end