nokogiri-styles 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nokogiri-stykes.gemspec
4
+ gemspec
@@ -0,0 +1,25 @@
1
+ Copyright © 2012, Readmore
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ * Neither the name of Readmore nor the
13
+ names of its contributors may be used to endorse or promote products
14
+ derived from this software without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL READMORE BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,55 @@
1
+ # nokogiri-styles
2
+
3
+ NokgiriStyles lets you decompose inline CSS styling (the style attribute) in
4
+ HTML elements so you don’t have to bother with regexes and such.
5
+
6
+ ## Usage
7
+
8
+ require 'nokogiri'
9
+ require 'nokogiri-styles'
10
+
11
+ # ...
12
+
13
+ # Get styles
14
+ node['style'] # => 'width: 400px; color: blue'
15
+ node.styles['width'] # => '400px'
16
+ node.styles['color'] # => 'blue'
17
+
18
+ # Update styles
19
+ style = node.styles
20
+ style['width'] = '500px'
21
+ style['height'] = '300px'
22
+ style['color'] = nil
23
+ node.styles = style
24
+ node['style'] # => 'width: 500xp; height: 300px'
25
+
26
+ # Modify classes
27
+ node['class'] # => 'foo bar'
28
+ node.classes # => ['foo', 'bar']
29
+ node.classes = ['foo']
30
+ node['class'] # => 'foo'
31
+
32
+ Note that the `style` attribute is only updated when assigning `.styles`,
33
+ simply doing `node.styles['color'] = 'red'` does not work. Patches welcome.
34
+
35
+ ## Installation
36
+
37
+ Add this line to your application's Gemfile:
38
+
39
+ gem 'nokogiri-styles'
40
+
41
+ And then execute:
42
+
43
+ $ bundle
44
+
45
+ Or install it yourself as:
46
+
47
+ $ gem install nokogiri-styles
48
+
49
+ ## Contributing
50
+
51
+ 1. Fork it
52
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
53
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
54
+ 4. Push to the branch (`git push origin my-new-feature`)
55
+ 5. Create new Pull Request
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+
7
+ Rake::TestTask.new(:test) do |test|
8
+ test.libs << 'lib' << 'test'
9
+ test.pattern = 'test/{functional,unit}/test_*.rb'
10
+ end
@@ -0,0 +1,8 @@
1
+ require 'nokogiri-styles/version'
2
+ require 'nokogiri-styles/node_styles'
3
+
4
+ module Nokogiri::XML
5
+ class Node
6
+ include NokogiriStyles::NodeStyles
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ require 'nokogiri-styles/propset'
2
+
3
+ module NokogiriStyles
4
+ module NodeStyles
5
+ def styles
6
+ return NokogiriStyles::Propset.new(self['style'])
7
+ end
8
+
9
+ def styles=(value)
10
+ self['style'] = value.to_s
11
+ end
12
+
13
+ def classes
14
+ return self['class'].split(' ')
15
+ end
16
+
17
+ def classes=(value)
18
+ self['class'] = value.join(' ')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,59 @@
1
+ module NokogiriStyles
2
+ class Propset
3
+ def initialize(style_string)
4
+ @properties = parse_properties(style_string)
5
+ @mapping = make_mapping(@properties)
6
+ end
7
+
8
+ def to_s
9
+ @properties.
10
+ map { |p| [p[:key], p[:value]].join(': ') }.
11
+ join('; ')
12
+ end
13
+
14
+ def [](key)
15
+ property = @mapping[key]
16
+ property.nil? ? nil : property[:value]
17
+ end
18
+
19
+ def []=(key, val)
20
+ return self.delete(key) if val.nil?
21
+ property = @mapping[key]
22
+ if property.nil?
23
+ property = {:key => key}
24
+ @properties << property
25
+ @mapping[key] = property
26
+ end
27
+ @mapping[key][:value] = val
28
+ end
29
+
30
+ def delete(key)
31
+ @mapping.delete(key)
32
+ @properties.reject! { |p| p[:key] == key }
33
+ end
34
+
35
+ private
36
+ def parse_property(property_string)
37
+ parts = property_string.split(':', 2)
38
+ return nil if parts.nil?
39
+ return nil if parts.length != 2
40
+ return nil if parts.any? { |s| s.nil? }
41
+ {:key => parts[0].strip, :value => parts[1].strip}
42
+ end
43
+
44
+ def parse_properties(style_string)
45
+ style_string.
46
+ split(';').
47
+ reject { |s| s.strip.empty? }.
48
+ map { |s| parse_property(s) }.
49
+ reject { |s| s.nil? }
50
+ end
51
+
52
+ def make_mapping(properties)
53
+ properties.reduce({}) do |accum, property|
54
+ accum[property[:key]] = property
55
+ accum
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module NokogiriStyles
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,53 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/nokogiri-styles/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ['Sijmen Mulder']
6
+ gem.email = ['sijmen@readmo.re']
7
+ gem.summary = %q{Basic inline CSS reading and editing for Nokogiri}
8
+ gem.homepage = ''
9
+
10
+ gem.description = <<-EOF
11
+ NokgiriStyles lets you decompose inline CSS styling (the style attribute) in
12
+ HTML elements so you don’t have to bother with regexes and such.
13
+
14
+ Usage:
15
+
16
+ require 'nokogiri'
17
+ require 'nokogiri-styles'
18
+
19
+ # ...
20
+
21
+ # Get styles
22
+ node['style'] # => 'width: 400px; color: blue'
23
+ node.styles['width'] # => '400px'
24
+ node.styles['color'] # => 'blue'
25
+
26
+ # Update styles
27
+ style = node.styles
28
+ style['width'] = '500px'
29
+ style['height'] = '300px'
30
+ style['color'] = nil
31
+ node.styles = style
32
+ node['style'] # => 'width: 500xp; height: 300px'
33
+
34
+ # Modify classes
35
+ node['class'] # => 'foo bar'
36
+ node.classes # => ['foo', 'bar']
37
+ node.classes = ['foo']
38
+ node['class'] # => 'foo'
39
+
40
+ Note that the `style` attribute is only updated when assigning `.styles`,
41
+ simply doing `node.styles['color'] = 'red'` does not work. Patches welcome.
42
+ EOF
43
+
44
+ gem.files = `git ls-files`.split($\)
45
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
46
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
47
+ gem.name = 'nokogiri-styles'
48
+ gem.require_paths = ['lib']
49
+ gem.version = NokogiriStyles::VERSION
50
+
51
+ gem.add_dependency('nokogiri')
52
+ gem.add_development_dependency('test-unit', '2.4.8')
53
+ end
@@ -0,0 +1,36 @@
1
+ require 'test/unit'
2
+ require 'nokogiri-styles/node_styles'
3
+ require 'nokogiri-styles/propset'
4
+
5
+ class MockNode < Hash
6
+ include NokogiriStyles::NodeStyles
7
+ end
8
+
9
+ class MockStyles < String
10
+ end
11
+
12
+ class TestNodeStyles < Test::Unit::TestCase
13
+ def test_classes
14
+ node = MockNode.new
15
+ node['class'] = 'foo bar'
16
+ assert_equal(%w(foo bar), node.classes)
17
+ end
18
+
19
+ def test_set_classes
20
+ node = MockNode.new
21
+ node.classes = %w(foo bar)
22
+ assert_equal('foo bar', node['class'])
23
+ end
24
+
25
+ def test_styles
26
+ node = MockNode.new
27
+ node['style'] = 'width: 2px; height: 4px'
28
+ assert_equal(node.styles.class, NokogiriStyles::Propset)
29
+ end
30
+
31
+ def test_set_styles
32
+ node = MockNode.new
33
+ node.styles = MockStyles.new('width: 2px; height: 4px')
34
+ assert_equal('width: 2px; height: 4px', node['style'])
35
+ end
36
+ end
@@ -0,0 +1,51 @@
1
+ require 'test/unit'
2
+ require 'nokogiri-styles/propset'
3
+
4
+ include NokogiriStyles
5
+
6
+ class TestPropset < Test::Unit::TestCase
7
+ def test_getters
8
+ propset = Propset.new('width: 2px; height: 4px; ')
9
+ assert_equal('2px', propset['width'])
10
+ assert_equal('4px', propset['height'])
11
+ end
12
+
13
+ def test_delete
14
+ propset = Propset.new('width: 2px; height: 4px; height: 3px')
15
+ propset.delete('height')
16
+ propset['width'] = nil
17
+ assert_equal(nil, propset['height'])
18
+ assert_equal(nil, propset['width'])
19
+ end
20
+
21
+ def test_setters
22
+ propset = Propset.new('width: 2px; height: 4px')
23
+ propset['width'] = nil
24
+ propset['height'] = '5px'
25
+ propset['top'] = '1px'
26
+ assert_equal(nil, propset['width'])
27
+ assert_equal('5px', propset['height'])
28
+ assert_equal('1px', propset['top'])
29
+ end
30
+
31
+ def test_duplicate_property
32
+ propset = Propset.new('width: 2px; height: 4px; width: 3px')
33
+ assert_equal('4px', propset['height'])
34
+ assert_equal('3px', propset['width'])
35
+ propset['width'] = '2px'
36
+ assert_equal('2px', propset['width'])
37
+ end
38
+
39
+ def test_to_s
40
+ propset = Propset.new('width: 2px; height: 4px; width: 3px; ')
41
+ propset['height'] = nil
42
+ propset['top'] = '1px'
43
+ propset['width'] = '5px'
44
+ assert_equal('width: 2px; width: 5px; top: 1px', propset.to_s)
45
+ end
46
+
47
+ def test_invalid_property
48
+ propset = Propset.new('width: 2px; height 4px')
49
+ assert_equal('2px', propset['width'])
50
+ end
51
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nokogiri-styles
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sijmen Mulder
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: test-unit
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '='
36
+ - !ruby/object:Gem::Version
37
+ version: 2.4.8
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.4.8
46
+ description: ! " NokgiriStyles lets you decompose inline CSS styling (the style
47
+ attribute) in\n HTML elements so you don’t have to bother with regexes and such.\n\n
48
+ \ Usage:\n \n require 'nokogiri'\n require 'nokogiri-styles'\n\n
49
+ \ # ...\n \n # Get styles\n node['style'] # => 'width:
50
+ 400px; color: blue'\n node.styles['width'] # => '400px'\n node.styles['color']
51
+ \ # => 'blue'\n \n # Update styles\n style = node.styles\n style['width']
52
+ \ = '500px'\n style['height'] = '300px'\n style['color'] = nil\n
53
+ \ node.styles = style\n node['style'] # => 'width: 500xp; height:
54
+ 300px'\n\n # Modify classes\n node['class'] # => 'foo bar'\n
55
+ \ node.classes # => ['foo', 'bar']\n node.classes = ['foo']\n
56
+ \ node['class'] # => 'foo'\n\n Note that the `style` attribute
57
+ is only updated when assigning `.styles`,\n simply doing `node.styles['color']
58
+ = 'red'` does not work. Patches welcome.\n"
59
+ email:
60
+ - sijmen@readmo.re
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - LICENSE.md
68
+ - README.md
69
+ - Rakefile
70
+ - lib/nokogiri-styles.rb
71
+ - lib/nokogiri-styles/node_styles.rb
72
+ - lib/nokogiri-styles/propset.rb
73
+ - lib/nokogiri-styles/version.rb
74
+ - nokogiri-styles.gemspec
75
+ - test/unit/test_node_styles.rb
76
+ - test/unit/test_propset.rb
77
+ homepage: ''
78
+ licenses: []
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 1.8.24
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Basic inline CSS reading and editing for Nokogiri
101
+ test_files:
102
+ - test/unit/test_node_styles.rb
103
+ - test/unit/test_propset.rb