motion-hpple 0.2.0

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,2 @@
1
+ .repl_history
2
+ build
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bubble-wrap.gemspec
4
+ gemspec
@@ -0,0 +1,50 @@
1
+ # Hpple motion
2
+
3
+ An XML/HTML parser for RubyMotion, with nokogiri style interface.
4
+
5
+ Based on [Hpple](https://github.com/topfunky/hpple) and some hacks.
6
+
7
+ WARNING: This is a quick hack that I'll use until we can use the real
8
+ nokorigi (or maybe something based on NSXMLDocument). It has not been heavily tested.
9
+
10
+ ## Install
11
+
12
+ Install motion-hpple:
13
+
14
+ gem install motion-hpple
15
+
16
+
17
+ Add following to your Rakefile:
18
+
19
+ ```ruby
20
+ $:.unshift("/Library/RubyMotion/lib")
21
+ require 'motion/project'
22
+ require 'motion-hpple'
23
+
24
+ Motion::Project::App.setup do |app|
25
+ app.name = 'MyApp'
26
+ end
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ``` ruby
32
+ html = "<html><body><h1>Hello</h1><div><p>Foo</p><p>Bar</p></div><p><a href=\"http://google.com\">google</a></p></body></html>"
33
+ parser = Hpple.HTML(html)
34
+
35
+ # Get content via #to_s, #to_html and #inner_html
36
+ h1 = parser.xpath("//h1").first
37
+ h1.tag # => "h1"
38
+ h1.to_s # => "Hello"
39
+ h1.to_html # => "<h1>Hello</h1>"
40
+
41
+ div = parser.xpath("//div").first
42
+ div.inner_html # => "<p>Foo</p><p>Bar</p>"
43
+
44
+ # Access attributes directly
45
+ link = parser.xpath("//a").first
46
+ link["href"] # => "http://google.com"
47
+ ```
48
+
49
+ For more example, check the spec.
50
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ class AppDelegate
2
+ def application(application, didFinishLaunchingWithOptions:launchOptions)
3
+ true
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ require "motion-hpple/version"
2
+
3
+ unless defined?(Motion::Project::Config)
4
+ raise "This file must be required within a RubyMotion project Rakefile."
5
+ end
6
+
7
+ Motion::Project::App.setup do |app|
8
+ Dir.glob(File.join(File.dirname(__FILE__), 'motion-hpple/*.rb')).each do |file|
9
+ app.files.unshift(file)
10
+ end
11
+ app.libs << '/usr/lib/libxml2.2.dylib'
12
+
13
+ hpple_vendor = File.expand_path(File.join(File.dirname(__FILE__), '../vendor/hpple'))
14
+ app.vendor_project(hpple_vendor, :static)
15
+ end
@@ -0,0 +1,74 @@
1
+ module Hpple
2
+ module_function
3
+
4
+ def XML(xml, encoding=NSUTF8StringEncoding)
5
+ if xml.is_a?(NSString)
6
+ xml = xml.dataUsingEncoding(encoding)
7
+ end
8
+ TFHpple.hppleWithXMLData(xml)
9
+ end
10
+
11
+ def HTML(html, encoding=NSUTF8StringEncoding)
12
+ if html.is_a?(NSString)
13
+ html = html.dataUsingEncoding(encoding)
14
+ end
15
+ TFHpple.hppleWithHTMLData(html)
16
+ end
17
+
18
+ end
19
+
20
+ class TFHpple
21
+ def xpath(query)
22
+ searchWithXPathQuery(query)
23
+ end
24
+ end
25
+
26
+ class TFHppleElement
27
+ def tag
28
+ self.tagName
29
+ end
30
+
31
+ def [](key)
32
+ self.objectForKey(key)
33
+ end
34
+
35
+ def text
36
+ self.inner_text
37
+ end
38
+
39
+ def inner_text
40
+ return self.content if self.content
41
+ return self.children.collect do |sub_node|
42
+ sub_node.inner_text
43
+ end.join("")
44
+ end
45
+
46
+ def inner_html
47
+ return self.children.map do |sub_node|
48
+ sub_node.to_html
49
+ end.join
50
+ end
51
+
52
+ # a hack to return html
53
+ def to_html
54
+ if self.content
55
+ self.content
56
+ else
57
+ tags_fragments = []
58
+ tags_fragments << "<#{self.tag}"
59
+ self.attributes.each do |key, value|
60
+ value = value.gsub('"', '&quot;')
61
+ tags_fragments << "#{key}=\"#{value}\""
62
+ end
63
+ tags_fragments.join(" ") + ">" + self.inner_html + "</#{self.tag}>"
64
+ end
65
+ end
66
+
67
+ def to_s
68
+ if self.content
69
+ self.content
70
+ else
71
+ self.inner_text
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module Hpple
2
+ VERSION = '0.2.0'
3
+ end
@@ -0,0 +1,16 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/motion-hpple/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Francis Chong"]
6
+ gem.email = ["francis@ignition.hk"]
7
+ gem.description = "A XML/HTML parser for RubyMotion, with nokogiri style interface."
8
+ gem.summary = "A XML/HTML parser for RubyMotion, with nokogiri style interface."
9
+ gem.homepage = "https://github.com/siuying/hpple-motion"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
+ gem.name = "motion-hpple"
14
+ gem.require_paths = ["lib"]
15
+ gem.version = Hpple::VERSION
16
+ end
@@ -0,0 +1,67 @@
1
+ describe "Application 'HppleMotion'" do
2
+ def xml
3
+ "<folder name='lib'><file name='libxml.dylib'></file><file name='libz.dylib'></file></folder>"
4
+ end
5
+
6
+ def html
7
+ %{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
8
+ <html><body><h1>Hello</h1><div><p>Foo</p><p>Bar</p></div><p><a href="http://google.com">google</a></p></body></html>"}
9
+ end
10
+
11
+ it "create xml and html parser" do
12
+ doc = Hpple.XML(xml)
13
+ doc.is_a?(TFHpple).should.be.true
14
+
15
+ doc = Hpple.HTML(html)
16
+ doc.is_a?(TFHpple).should.be.true
17
+ end
18
+
19
+ it "parse xml" do
20
+ doc = Hpple.XML(xml)
21
+ items = doc.xpath("/folder/file")
22
+ items.size.should == 2
23
+
24
+ items[0].tagName.should == "file"
25
+ items[1].tagName.should == "file"
26
+ items[0]["name"].should == "libxml.dylib"
27
+ items[1]["name"].should == "libz.dylib"
28
+ end
29
+
30
+ it "parse html" do
31
+ doc = Hpple.HTML(html)
32
+ h1_items = doc.xpath("//h1")
33
+ h1_items.size.should == 1
34
+ h1 = h1_items.first
35
+ h1.tag.should == "h1"
36
+
37
+ link = doc.xpath("//a").first
38
+ link["href"].should == "http://google.com"
39
+ end
40
+
41
+ it "should parse inner_text" do
42
+ doc = Hpple.HTML(html)
43
+ h1 = doc.xpath("//h1").first
44
+ h1.inner_text.should == "Hello"
45
+
46
+ div = doc.xpath("//div").first
47
+ div.inner_text.should == "FooBar"
48
+
49
+ p = doc.xpath("//div/p").first
50
+ p.inner_text.should == "Foo"
51
+
52
+ p = doc.xpath("//div/p").last
53
+ p.inner_text.should == "Bar"
54
+ end
55
+
56
+ it "should parse inner_html" do
57
+ doc = Hpple.HTML(html)
58
+ h1 = doc.xpath("//h1").first
59
+ h1.inner_html.should == "Hello"
60
+
61
+ div = doc.xpath("//div").first
62
+ div.inner_html.should == "<p>Foo</p><p>Bar</p>"
63
+
64
+ myhtml = doc.xpath("//html").first
65
+ myhtml.to_html.should == "<html><body><h1>Hello</h1><div><p>Foo</p><p>Bar</p></div><p><a href=\"http://google.com\">google</a></p></body></html>"
66
+ end
67
+ end
@@ -0,0 +1,54 @@
1
+ //
2
+ // TFHpple.h
3
+ // Hpple
4
+ //
5
+ // Created by Geoffrey Grosenbach on 1/31/09.
6
+ //
7
+ // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com
8
+ //
9
+ // MIT LICENSE
10
+ //
11
+ // Permission is hereby granted, free of charge, to any person obtaining
12
+ // a copy of this software and associated documentation files (the
13
+ // "Software"), to deal in the Software without restriction, including
14
+ // without limitation the rights to use, copy, modify, merge, publish,
15
+ // distribute, sublicense, and/or sell copies of the Software, and to
16
+ // permit persons to whom the Software is furnished to do so, subject to
17
+ // the following conditions:
18
+ //
19
+ // The above copyright notice and this permission notice shall be
20
+ // included in all copies or substantial portions of the Software.
21
+ //
22
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
+ // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
+ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
+
30
+
31
+ #import <Foundation/Foundation.h>
32
+
33
+ #import "TFHppleElement.h"
34
+
35
+ @interface TFHpple : NSObject {
36
+ @private
37
+ NSData * data;
38
+ BOOL isXML;
39
+ }
40
+
41
+ - (id) initWithData:(NSData *)theData isXML:(BOOL)isDataXML;
42
+ - (id) initWithXMLData:(NSData *)theData;
43
+ - (id) initWithHTMLData:(NSData *)theData;
44
+
45
+ + (TFHpple *) hppleWithData:(NSData *)theData isXML:(BOOL)isDataXML;
46
+ + (TFHpple *) hppleWithXMLData:(NSData *)theData;
47
+ + (TFHpple *) hppleWithHTMLData:(NSData *)theData;
48
+
49
+ - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS;
50
+ - (TFHppleElement *) peekAtSearchWithXPathQuery:(NSString *)xPathOrCSS;
51
+
52
+ @property (retain) NSData * data;
53
+
54
+ @end
@@ -0,0 +1,68 @@
1
+ //
2
+ // TFHppleElement.h
3
+ // Hpple
4
+ //
5
+ // Created by Geoffrey Grosenbach on 1/31/09.
6
+ //
7
+ // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com
8
+ //
9
+ // MIT LICENSE
10
+ //
11
+ // Permission is hereby granted, free of charge, to any person obtaining
12
+ // a copy of this software and associated documentation files (the
13
+ // "Software"), to deal in the Software without restriction, including
14
+ // without limitation the rights to use, copy, modify, merge, publish,
15
+ // distribute, sublicense, and/or sell copies of the Software, and to
16
+ // permit persons to whom the Software is furnished to do so, subject to
17
+ // the following conditions:
18
+ //
19
+ // The above copyright notice and this permission notice shall be
20
+ // included in all copies or substantial portions of the Software.
21
+ //
22
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
+ // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
+ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
+
30
+ #import <Foundation/Foundation.h>
31
+
32
+
33
+ @interface TFHppleElement : NSObject {
34
+ @private
35
+
36
+ NSDictionary * node;
37
+ TFHppleElement *parent;
38
+ }
39
+
40
+ - (id) initWithNode:(NSDictionary *) theNode;
41
+
42
+ + (TFHppleElement *) hppleElementWithNode:(NSDictionary *) theNode;
43
+
44
+ // Returns this tag's innerHTML content.
45
+ @property (nonatomic, readonly) NSString *content;
46
+
47
+ // Returns the name of the current tag, such as "h3".
48
+ @property (nonatomic, readonly) NSString *tagName;
49
+
50
+ // Returns tag attributes with name as key and content as value.
51
+ // href = 'http://peepcode.com'
52
+ // class = 'highlight'
53
+ @property (nonatomic, readonly) NSDictionary *attributes;
54
+
55
+ // Returns the children of a given node
56
+ @property (nonatomic, readonly) NSArray *children;
57
+
58
+ // Returns the first child of a given node
59
+ @property (nonatomic, readonly) TFHppleElement *firstChild;
60
+
61
+ // the parent of a node
62
+ @property (nonatomic, retain, readonly) TFHppleElement *parent;
63
+
64
+ // Provides easy access to the content of a specific attribute,
65
+ // such as 'href' or 'class'.
66
+ - (NSString *) objectForKey:(NSString *) theKey;
67
+
68
+ @end
@@ -0,0 +1,78 @@
1
+ <?xml version='1.0'?>
2
+ <signatures version='1.0'>
3
+ <class name='TFHpple'>
4
+ <method selector='data'>
5
+ <retval declared_type='NSData*' type='@'/>
6
+ </method>
7
+ <method selector='hppleWithData:isXML:' class_method='true'>
8
+ <arg name='theData' declared_type='NSData*' type='@' index='0'/>
9
+ <arg name='isDataXML' declared_type='BOOL' type='B' index='1'/>
10
+ <retval declared_type='TFHpple*' type='@'/>
11
+ </method>
12
+ <method selector='hppleWithHTMLData:' class_method='true'>
13
+ <arg name='theData' declared_type='NSData*' type='@' index='0'/>
14
+ <retval declared_type='TFHpple*' type='@'/>
15
+ </method>
16
+ <method selector='hppleWithXMLData:' class_method='true'>
17
+ <arg name='theData' declared_type='NSData*' type='@' index='0'/>
18
+ <retval declared_type='TFHpple*' type='@'/>
19
+ </method>
20
+ <method selector='initWithData:isXML:'>
21
+ <arg name='theData' declared_type='NSData*' type='@' index='0'/>
22
+ <arg name='isDataXML' declared_type='BOOL' type='B' index='1'/>
23
+ <retval declared_type='id' type='@'/>
24
+ </method>
25
+ <method selector='initWithHTMLData:'>
26
+ <arg name='theData' declared_type='NSData*' type='@' index='0'/>
27
+ <retval declared_type='id' type='@'/>
28
+ </method>
29
+ <method selector='initWithXMLData:'>
30
+ <arg name='theData' declared_type='NSData*' type='@' index='0'/>
31
+ <retval declared_type='id' type='@'/>
32
+ </method>
33
+ <method selector='peekAtSearchWithXPathQuery:'>
34
+ <arg name='xPathOrCSS' declared_type='NSString*' type='@' index='0'/>
35
+ <retval declared_type='TFHppleElement*' type='@'/>
36
+ </method>
37
+ <method selector='searchWithXPathQuery:'>
38
+ <arg name='xPathOrCSS' declared_type='NSString*' type='@' index='0'/>
39
+ <retval declared_type='NSArray*' type='@'/>
40
+ </method>
41
+ <method selector='setData:'>
42
+ <arg name='data' declared_type='NSData*' type='@' index='0'/>
43
+ <retval declared_type='void' type='v'/>
44
+ </method>
45
+ </class>
46
+ <class name='TFHppleElement'>
47
+ <method selector='attributes'>
48
+ <retval declared_type='NSDictionary*' type='@'/>
49
+ </method>
50
+ <method selector='children'>
51
+ <retval declared_type='NSArray*' type='@'/>
52
+ </method>
53
+ <method selector='content'>
54
+ <retval declared_type='NSString*' type='@'/>
55
+ </method>
56
+ <method selector='firstChild'>
57
+ <retval declared_type='TFHppleElement*' type='@'/>
58
+ </method>
59
+ <method selector='hppleElementWithNode:' class_method='true'>
60
+ <arg name='theNode' declared_type='NSDictionary*' type='@' index='0'/>
61
+ <retval declared_type='TFHppleElement*' type='@'/>
62
+ </method>
63
+ <method selector='initWithNode:'>
64
+ <arg name='theNode' declared_type='NSDictionary*' type='@' index='0'/>
65
+ <retval declared_type='id' type='@'/>
66
+ </method>
67
+ <method selector='objectForKey:'>
68
+ <arg name='theKey' declared_type='NSString*' type='@' index='0'/>
69
+ <retval declared_type='NSString*' type='@'/>
70
+ </method>
71
+ <method selector='parent'>
72
+ <retval declared_type='TFHppleElement*' type='@'/>
73
+ </method>
74
+ <method selector='tagName'>
75
+ <retval declared_type='NSString*' type='@'/>
76
+ </method>
77
+ </class>
78
+ </signatures>
Binary file
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motion-hpple
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Francis Chong
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-22 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A XML/HTML parser for RubyMotion, with nokogiri style interface.
15
+ email:
16
+ - francis@ignition.hk
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - README.md
24
+ - Rakefile
25
+ - app/app_delegate.rb
26
+ - lib/motion-hpple.rb
27
+ - lib/motion-hpple/hpple.rb
28
+ - lib/motion-hpple/version.rb
29
+ - motion-hpple.gemspec
30
+ - spec/hpple_spec.rb
31
+ - vendor/hpple/TFHpple.h
32
+ - vendor/hpple/TFHppleElement.h
33
+ - vendor/hpple/hpple.bridgesupport
34
+ - vendor/hpple/libHpple.a
35
+ homepage: https://github.com/siuying/hpple-motion
36
+ licenses: []
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 1.8.15
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: A XML/HTML parser for RubyMotion, with nokogiri style interface.
59
+ test_files:
60
+ - spec/hpple_spec.rb