csspool 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.1.0
2
+
3
+ * Birthday!
4
+
data/Manifest.txt ADDED
@@ -0,0 +1,32 @@
1
+ CHANGELOG.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/css/sac.rb
6
+ lib/css/sac/attribute_condition.rb
7
+ lib/css/sac/condition.rb
8
+ lib/css/sac/document_handler.rb
9
+ lib/css/sac/error_handler.rb
10
+ lib/css/sac/generated_property_parser.rb
11
+ lib/css/sac/lexeme.rb
12
+ lib/css/sac/lexical_unit.rb
13
+ lib/css/sac/parse_exception.rb
14
+ lib/css/sac/parser.rb
15
+ lib/css/sac/property_parser.rb
16
+ lib/css/sac/selectors.rb
17
+ lib/css/sac/token.rb
18
+ lib/css/sac/tokenizer.rb
19
+ lib/parser.y
20
+ lib/property_parser.y
21
+ lib/property_parser.y.erb
22
+ test/helper.rb
23
+ test/test_all.rb
24
+ test/test_lexeme.rb
25
+ test/test_lexical_unit.rb
26
+ test/test_parse_error.rb
27
+ test/test_parser.rb
28
+ test/test_property_parser.rb
29
+ test/test_selector_as_string.rb
30
+ test/test_selector_parser.rb
31
+ test/test_token.rb
32
+ test/test_tokenizer.rb
data/README.txt ADDED
@@ -0,0 +1,71 @@
1
+ = CSSpool
2
+
3
+ http://csspool.rubyforge.org/
4
+
5
+ == Description
6
+
7
+ CSSpool (pronounced "cesspool") is a validating SAC parser for CSS. The parser
8
+ calls methods on a document handler depending on what it has found. CSSPool
9
+ currently only supports CSS 2.1. CSSPool will not yield invalid properties or
10
+ selectors.
11
+
12
+ == Dependencies
13
+
14
+ Building CSSpool requires:
15
+
16
+ - RACC (not just the runtime)
17
+ (http://i.loveruby.net/en/projects/racc)
18
+
19
+ - rubygems, hoe, flexmock
20
+
21
+ == Example
22
+
23
+ This example prints out all properties from a particular CSS file.
24
+
25
+ class DH < CSS::SAC::DocumentHandler
26
+ def start_selector(selectors)
27
+ puts selectors.map { |x| x.to_css }.join(', ')
28
+ end
29
+
30
+ def property(name, value, important)
31
+ puts "#{name} #{value.join(', ')} #{important}"
32
+ end
33
+ end
34
+
35
+ token = CSS::SAC::Parser.new(DH.new)
36
+ token.parse(File.read(ARGV[0]))
37
+
38
+ See CSS::SAC::DocumentHandler for callbacks to implement.
39
+
40
+ See SAC[http://www.w3.org/Style/CSS/SAC/] for more information on SAC.
41
+
42
+ == Authors
43
+
44
+ * Aaron Patterson[http://tenderlovemaking.com/] <aaronp@rubyforge.com>
45
+ * John Barnette
46
+
47
+ == LICENSE
48
+
49
+ (The MIT License)
50
+
51
+ Copyright (c) 2007 Aaron Patterson, John Barnette
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining
54
+ a copy of this software and associated documentation files (the
55
+ 'Software'), to deal in the Software without restriction, including
56
+ without limitation the rights to use, copy, modify, merge, publish,
57
+ distribute, sublicense, and/or sell copies of the Software, and to
58
+ permit persons to whom the Software is furnished to do so, subject to
59
+ the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be
62
+ included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
65
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
66
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
67
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
68
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
69
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
70
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
71
+
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'erb'
3
+ require 'hoe'
4
+
5
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "lib")
6
+
7
+ GENERATED_PARSER = "lib/css/sac/generated_parser.rb"
8
+ GENERATED_PROPERTY_PARSER = "lib/css/sac/generated_property_parser.rb"
9
+
10
+ Hoe.new('csspool', '0.1.0') do |p|
11
+ p.rubyforge_name = 'csspool'
12
+ p.author = 'Aaron Patterson'
13
+ p.email = 'aaronp@rubyforge.org'
14
+ p.summary = "Parses CSS"
15
+ p.description = p.paragraphs_of('README.txt', 3).join("\n\n")
16
+ p.url = p.paragraphs_of('README.txt', 1).first.strip
17
+ p.changes = p.paragraphs_of('CHANGELOG.txt', 0..2).join("\n\n")
18
+ p.clean_globs = [GENERATED_PARSER]
19
+ end
20
+
21
+ class Array
22
+ def permutations
23
+ return [self] if size < 2
24
+ perm = []
25
+ each { |e| (self - [e]).permutations.each { |p| perm << ([e] + p) } }
26
+ perm
27
+ end
28
+
29
+ def permute_all_combinations
30
+ list = []
31
+ permutations.each do |perm|
32
+ while perm.length > 0
33
+ list << perm.dup
34
+ perm.shift
35
+ end
36
+ end
37
+ list.uniq.sort_by { |x| x.length }.reverse
38
+ end
39
+ end
40
+
41
+ file GENERATED_PARSER => "lib/parser.y" do |t|
42
+ sh "racc -o #{t.name} #{t.prerequisites.first}"
43
+ end
44
+
45
+ file GENERATED_PROPERTY_PARSER => "lib/property_parser.y.erb" do |t|
46
+ template = ERB.new(File.open(t.prerequisites.first, 'rb') { |x| x.read })
47
+ File.open("lib/property_parser.y", 'wb') { |f|
48
+ f.write template.result(binding)
49
+ }
50
+ sh "racc -o #{t.name} lib/property_parser.y"
51
+ end
52
+
53
+ task :parser => [GENERATED_PARSER, GENERATED_PROPERTY_PARSER]
54
+
55
+ # make sure the parser's up-to-date when we test
56
+ Rake::Task[:test].prerequisites << :parser
@@ -0,0 +1,78 @@
1
+ module CSS
2
+ module SAC
3
+ class AttributeCondition < Condition
4
+ attr_accessor :local_name, :value, :specified
5
+ alias :specified? :specified
6
+
7
+ class << self
8
+ def pseudo_class_condition(pseudo_class)
9
+ self.new do |condition|
10
+ condition.condition_type = :SAC_PSEUDO_CLASS_CONDITION
11
+ condition.value = pseudo_class
12
+ end
13
+ end
14
+
15
+ def attribute_id(id_value)
16
+ self.new do |condition|
17
+ condition.condition_type = :SAC_ID_CONDITION
18
+ condition.specified = true
19
+ condition.value = id_value
20
+ end
21
+ end
22
+
23
+ def class_condition(class_name)
24
+ self.new do |condition|
25
+ condition.condition_type = :SAC_CLASS_CONDITION
26
+ condition.specified = true
27
+ condition.value = class_name
28
+ end
29
+ end
30
+
31
+ def attribute_condition(attribute, conditions)
32
+ self.new do |condition|
33
+ if attribute
34
+ condition.condition_type = :SAC_ATTRIBUTE_CONDITION
35
+ condition.local_name = attribute
36
+ end
37
+
38
+ if conditions
39
+ condition.condition_type =
40
+ case conditions.first
41
+ when '~='
42
+ :SAC_ONE_OF_ATTRIBUTE_CONDITION
43
+ when '|='
44
+ :SAC_BEGIN_HYPHEN_ATTRIBUTE_CONDITION
45
+ when '='
46
+ :SAC_ATTRIBUTE_CONDITION
47
+ end
48
+ condition.value = conditions.last
49
+ condition.specified = true
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def initialize(attribute = nil, conditions = nil)
56
+ @specified = false
57
+ @local_name = nil
58
+ @value = nil
59
+ yield self if block_given?
60
+ end
61
+
62
+ def to_css
63
+ case condition_type
64
+ when :SAC_ONE_OF_ATTRIBUTE_CONDITION
65
+ "[#{local_name}~=#{value}]"
66
+ when :SAC_BEGIN_HYPHEN_ATTRIBUTE_CONDITION
67
+ "[#{local_name}|=#{value}]"
68
+ when :SAC_ATTRIBUTE_CONDITION
69
+ "[#{local_name}=#{value}]"
70
+ when :SAC_CLASS_CONDITION
71
+ ".#{value}"
72
+ when :SAC_ID_CONDITION
73
+ "#{value}"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,21 @@
1
+ module CSS
2
+ module SAC
3
+ class Condition
4
+ attr_accessor :condition_type
5
+ end
6
+
7
+ class CombinatorCondition < Condition
8
+ attr_accessor :first_condition, :second_condition
9
+
10
+ def initialize(first, second, type = :SAC_AND_CONDITION)
11
+ @first_condition = first
12
+ @second_condition = second
13
+ @condition_type = type
14
+ end
15
+
16
+ def to_css
17
+ "#{first_condition.to_css}#{second_condition.to_css}"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,67 @@
1
+ module CSS
2
+ module SAC
3
+ class CSS::SAC::DocumentHandler
4
+ def initialize
5
+ end
6
+
7
+ # Receive notification of the beginning of a style sheet.
8
+ def start_document(input_source)
9
+ end
10
+
11
+ # Receive notification of the end of a style sheet.
12
+ def end_document(input_source)
13
+ end
14
+
15
+ # Receive notification of a comment
16
+ def comment(text)
17
+ end
18
+
19
+ # Receive notification of an unknown at rule not supported by this parser.
20
+ def ignorable_at_rule(at_rule)
21
+ end
22
+
23
+ def namespace_declaration(prefix, uri)
24
+ end
25
+
26
+ # Called on an import statement
27
+ def import_style(uri, media, default_namespace_uri = nil)
28
+ end
29
+
30
+ # Notification of the start of a media statement
31
+ def start_media(media)
32
+ end
33
+
34
+ # Notification of the end of a media statement
35
+ def end_media(media)
36
+ end
37
+
38
+ # Notification of the start of a page statement
39
+ def start_page(name = nil, pseudo_page = nil)
40
+ end
41
+
42
+ # Notification of the end of a page statement
43
+ def end_page(name = nil, pseudo_page = nil)
44
+ end
45
+
46
+ # Notification of the beginning of a font face statement.
47
+ def start_font_face
48
+ end
49
+
50
+ # Notification of the end of a font face statement.
51
+ def end_font_face
52
+ end
53
+
54
+ # Notification of the beginning of a rule statement.
55
+ def start_selector(selectors)
56
+ end
57
+
58
+ # Notification of the end of a rule statement.
59
+ def end_selector(selectors)
60
+ end
61
+
62
+ # Notification of a declaration.
63
+ def property(name, value, important)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,14 @@
1
+ module CSS
2
+ module SAC
3
+ class ErrorHandler
4
+ def error(exception)
5
+ end
6
+
7
+ def fatal_error(exception)
8
+ end
9
+
10
+ def warning_error(exception)
11
+ end
12
+ end
13
+ end
14
+ end