html_css_decorator 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,39 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # jeweler generated
12
+ pkg
13
+
14
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
15
+ #
16
+ # * Create a file at ~/.gitignore
17
+ # * Include files you want ignored
18
+ # * Run: git config --global core.excludesfile ~/.gitignore
19
+ #
20
+ # After doing this, these files will be ignored in all your git projects,
21
+ # saving you from having to 'pollute' every project you touch with them
22
+ #
23
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
24
+ #
25
+ # For MacOS:
26
+ #
27
+ #.DS_Store
28
+ #
29
+ # For TextMate
30
+ #*.tmproj
31
+ #tmtags
32
+ #
33
+ # For emacs:
34
+ #*~
35
+ #\#*
36
+ #.\#*
37
+ #
38
+ # For vim:
39
+ #*.swp
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Kristian Mandrup
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ = html_css_decorator
2
+
3
+ Populates a Nokogiri HTML document with CSS information on nodes where CSS styles apply. The CSS information is the resulting CSS styles which would apply for the
4
+ given element if it was shown in a browser. The tool should correctly use specification rules as defined by W3C. The tool uses my own extension of 'Css_parser' by Alex Dunae.
5
+ The Css_parser used is version 1.1.2, available from my github@kristianmandrup account.
6
+
7
+ == Note on Patches/Pull Requests
8
+
9
+ * Fork the project.
10
+ * Make your feature addition or bug fix.
11
+ * Add tests for it. This is important so I don't break it in a
12
+ future version unintentionally.
13
+ * Commit, do not mess with rakefile, version, or history.
14
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
15
+ * Send me a pull request. Bonus points for topic branches.
16
+
17
+ == Copyright
18
+
19
+ Copyright (c) 2010 Kristian Mandrup. See LICENSE for details.
@@ -0,0 +1,46 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "html_css_decorator"
8
+ gem.summary = %Q{Decorate your Nokogiri HTML model with CSS information}
9
+ gem.description = %Q{Decorate your Nokogiri HTML model with CSS information as it would apply in the browser}
10
+ gem.email = "kmandrup@gmail.com"
11
+ gem.homepage = "http://github.com/kristianmandrup/html_css_decorator"
12
+ gem.authors = ["Kristian Mandrup"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_dependency "css_parser_master", ">=1.2.4"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ # require 'spec/rake/spectask'
23
+ # Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ # spec.libs << 'lib' << 'spec'
25
+ # spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ # end
27
+ #
28
+ # Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ # spec.libs << 'lib' << 'spec'
30
+ # spec.pattern = 'spec/**/*_spec.rb'
31
+ # spec.rcov = true
32
+ # end
33
+ #
34
+ # task :spec => :check_dependencies
35
+ #
36
+ # task :default => :spec
37
+ #
38
+ # require 'rake/rdoctask'
39
+ # Rake::RDocTask.new do |rdoc|
40
+ # version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+ #
42
+ # rdoc.rdoc_dir = 'rdoc'
43
+ # rdoc.title = "html_css_decorator #{version}"
44
+ # rdoc.rdoc_files.include('README*')
45
+ # rdoc.rdoc_files.include('lib/**/*.rb')
46
+ # end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
@@ -0,0 +1,62 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{html_css_decorator}
8
+ s.version = "0.1.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kristian Mandrup"]
12
+ s.date = %q{2010-05-27}
13
+ s.description = %q{Decorate your Nokogiri HTML model with CSS information as it would apply in the browser}
14
+ s.email = %q{kmandrup@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "html_css_decorator.gemspec",
27
+ "lib/css_model.rb",
28
+ "lib/html_css_decorator.rb",
29
+ "spec/fixtures/my.css",
30
+ "spec/fixtures/other.css",
31
+ "spec/fixtures/test.html",
32
+ "spec/html_css_decorator_spec.rb",
33
+ "spec/spec.opts",
34
+ "spec/spec_helper.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/kristianmandrup/html_css_decorator}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.7}
40
+ s.summary = %q{Decorate your Nokogiri HTML model with CSS information}
41
+ s.test_files = [
42
+ "spec/html_css_decorator_spec.rb",
43
+ "spec/spec_helper.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
52
+ s.add_runtime_dependency(%q<css_parser_master>, [">= 1.2.4"])
53
+ else
54
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
55
+ s.add_dependency(%q<css_parser_master>, [">= 1.2.4"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
59
+ s.add_dependency(%q<css_parser_master>, [">= 1.2.4"])
60
+ end
61
+ end
62
+
@@ -0,0 +1,44 @@
1
+ module CSS
2
+ module Model
3
+
4
+ def self.apply_to(doc, options = {})
5
+ doc.decorators(Nokogiri::XML::Element) << ::CSS::Element
6
+ doc.decorate!
7
+ doc.extend(::CSS::Model)
8
+ doc.css_path options[:css_path] if options[:css_path]
9
+ doc.apply_css!(options)
10
+ doc
11
+ end
12
+
13
+ attr_writer :css_path
14
+
15
+ def css_path(path = nil)
16
+ return @css_path if !path
17
+ @css_path = path
18
+ self
19
+ end
20
+
21
+ def apply_css!(options = {})
22
+ cp = CssParserMaster::Parser.new
23
+
24
+ self.xpath('//link[@rel = "stylesheet"]').each do |stylesheet|
25
+ file_name = css_path + stylesheet['href']
26
+ puts "load stylesheet: #{file_name}" if options[:verbose]
27
+ cp.load_file!(file_name)
28
+ end
29
+
30
+ cp.each_selector do |sel|
31
+ self.css(sel.selector).each do |elem|
32
+ elem.add_rule! sel.to_text
33
+ end
34
+
35
+ end
36
+
37
+ self.css('*').each do |elem|
38
+ elem.merge_declarations!
39
+ elem.merge_style!
40
+ end
41
+ self
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,62 @@
1
+ require 'nokogiri'
2
+ require 'css_parser_master'
3
+ require 'css_model'
4
+ require 'yaml'
5
+
6
+ module CSS
7
+ module Element
8
+ attr_accessor :parser
9
+ attr_accessor :ruleset
10
+ attr_accessor :rules
11
+ attr_accessor :declarations
12
+
13
+ def add_rule!(rule)
14
+ @parser ||= CssParserMaster::Parser.new
15
+ @declarations = {}
16
+
17
+ parser.add_block! rule
18
+ end
19
+
20
+ def add_declaration!(declaration)
21
+ return if !declaration
22
+ @declarations ||= {}
23
+ dec = declaration.kind_of?(Array) ? declaration[1] : declaration
24
+ declarations[dec.property] = dec
25
+ end
26
+ alias_method :[]=, :add_declaration!
27
+
28
+ def merge_declarations(selector)
29
+ @order = 0
30
+
31
+ selector.each_declaration do |decl|
32
+ add_declaration!(decl)
33
+ end
34
+ end
35
+
36
+ def merge_style!
37
+ style = attribute('style')
38
+ if style
39
+ s = style.to_s + ';'
40
+ selector = CssParserMaster::Selector.new(name, s, 99999)
41
+ merge_declarations(selector)
42
+ end
43
+ end
44
+
45
+ # merge declarations by specificity
46
+ def merge_declarations!
47
+ !parser and return
48
+
49
+ @order = 0
50
+ @declarations ||= {}
51
+
52
+ parser.selector_declarations do |sel, decl|
53
+ add_declaration!(decl)
54
+ end
55
+ end
56
+
57
+ def duplicate?(decl)
58
+ declarations.select{|d| d.property == decl.property}.empty?
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,9 @@
1
+ div {
2
+ color: black;
3
+ font-weight: bold;
4
+ }
5
+
6
+ div#content {
7
+ color: green;
8
+ }
9
+
@@ -0,0 +1,7 @@
1
+ p {
2
+ color: blue;
3
+ }
4
+
5
+ div + p {
6
+ color: red;
7
+ }
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
5
+ <head>
6
+ <title>Test</title>
7
+ <link rel="stylesheet" href="my.css" type="text/css" media="screen" title="no title" charset="utf-8">
8
+ <link rel="stylesheet" href="other.css" type="text/css" media="screen" title="no title" charset="utf-8">
9
+ </head>
10
+ <body>
11
+ <div id="content">Hello World</div>
12
+ <div class="header">My header</div>
13
+ <p>Go for it</p>
14
+ <table style="color:blue">
15
+ <tr>
16
+ <td style="font-weight:bold"></td>
17
+ </tr>
18
+ </table>
19
+ </body>
20
+ </html>
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "HtmlCssDecorator" do
4
+ it "works" do
5
+ doc = Nokogiri::HTML(File.open 'fixtures/test.html')
6
+ doc = CSS::Model.apply_to(doc, :css_path => File.dirname(__FILE__) + "/fixtures/")
7
+
8
+ doc.css('*').each do |elem|
9
+ puts show(elem) if elem.declarations
10
+ end
11
+ end
12
+ end
13
+
14
+ def show(elem)
15
+ s = "Tag: #{elem.name}\n"
16
+ return s if !elem.declarations
17
+ elem.declarations.each do |decl|
18
+ s += decl[1].to_text
19
+ end
20
+ s
21
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,4 @@
1
+ require 'rspec'
2
+ require 'rspec/autorun'
3
+ require 'html_css_decorator'
4
+
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: html_css_decorator
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 2
9
+ version: 0.1.2
10
+ platform: ruby
11
+ authors:
12
+ - Kristian Mandrup
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-27 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 2
31
+ - 9
32
+ version: 1.2.9
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: css_parser_master
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 1
45
+ - 2
46
+ - 4
47
+ version: 1.2.4
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ description: Decorate your Nokogiri HTML model with CSS information as it would apply in the browser
51
+ email: kmandrup@gmail.com
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files:
57
+ - LICENSE
58
+ - README.rdoc
59
+ files:
60
+ - .document
61
+ - .gitignore
62
+ - LICENSE
63
+ - README.rdoc
64
+ - Rakefile
65
+ - VERSION
66
+ - html_css_decorator.gemspec
67
+ - lib/css_model.rb
68
+ - lib/html_css_decorator.rb
69
+ - spec/fixtures/my.css
70
+ - spec/fixtures/other.css
71
+ - spec/fixtures/test.html
72
+ - spec/html_css_decorator_spec.rb
73
+ - spec/spec.opts
74
+ - spec/spec_helper.rb
75
+ has_rdoc: true
76
+ homepage: http://github.com/kristianmandrup/html_css_decorator
77
+ licenses: []
78
+
79
+ post_install_message:
80
+ rdoc_options:
81
+ - --charset=UTF-8
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ requirements: []
101
+
102
+ rubyforge_project:
103
+ rubygems_version: 1.3.7
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Decorate your Nokogiri HTML model with CSS information
107
+ test_files:
108
+ - spec/html_css_decorator_spec.rb
109
+ - spec/spec_helper.rb