motion-hpple 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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