mofo 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/Manifest.txt +55 -0
- data/Rakefile +32 -0
- data/init.rb +2 -0
- data/lib/microformat.rb +39 -6
- data/lib/mofo/hentry.rb +4 -0
- data/site/index.html +382 -0
- data/site/mofo-logo.png +0 -0
- data/site/mootools.v1.00.js +2 -0
- data/site/style.css +159 -0
- data/test/base_url_test.rb +22 -0
- data/test/fixtures/corkd.html +1 -1
- data/test/hatom_test.rb +1 -1
- data/test/hreview_test.rb +4 -3
- data/test/include_pattern_test.rb +1 -1
- data/test/test_helper.rb +17 -6
- metadata +63 -115
- data/test/format_test.rb +0 -230
- data/vendor/testspec-0.3.0/ChangeLog +0 -177
- data/vendor/testspec-0.3.0/README +0 -289
- data/vendor/testspec-0.3.0/ROADMAP +0 -1
- data/vendor/testspec-0.3.0/Rakefile +0 -151
- data/vendor/testspec-0.3.0/SPECS +0 -108
- data/vendor/testspec-0.3.0/TODO +0 -2
- data/vendor/testspec-0.3.0/bin/specrb +0 -104
- data/vendor/testspec-0.3.0/doc/classes/Kernel.html +0 -140
- data/vendor/testspec-0.3.0/doc/classes/Object.html +0 -155
- data/vendor/testspec-0.3.0/doc/classes/Test/Spec.html +0 -128
- data/vendor/testspec-0.3.0/doc/classes/Test/Spec/CustomShould.html +0 -236
- data/vendor/testspec-0.3.0/doc/classes/Test/Spec/DefinitionError.html +0 -111
- data/vendor/testspec-0.3.0/doc/classes/Test/Spec/Should.html +0 -884
- data/vendor/testspec-0.3.0/doc/classes/Test/Spec/ShouldNot.html +0 -487
- data/vendor/testspec-0.3.0/doc/classes/Test/Spec/TestCase.html +0 -220
- data/vendor/testspec-0.3.0/doc/classes/Test/Spec/TestCase/ClassMethods.html +0 -318
- data/vendor/testspec-0.3.0/doc/classes/Test/Spec/TestCase/InstanceMethods.html +0 -195
- data/vendor/testspec-0.3.0/doc/classes/Test/Unit/UI/RDox/TestRunner.html +0 -222
- data/vendor/testspec-0.3.0/doc/classes/Test/Unit/UI/SpecDox/TestRunner.html +0 -476
- data/vendor/testspec-0.3.0/doc/created.rid +0 -1
- data/vendor/testspec-0.3.0/doc/files/README.html +0 -516
- data/vendor/testspec-0.3.0/doc/files/ROADMAP.html +0 -109
- data/vendor/testspec-0.3.0/doc/files/SPECS.html +0 -386
- data/vendor/testspec-0.3.0/doc/files/lib/test/spec/dox_rb.html +0 -108
- data/vendor/testspec-0.3.0/doc/files/lib/test/spec/rdox_rb.html +0 -108
- data/vendor/testspec-0.3.0/doc/files/lib/test/spec/should-output_rb.html +0 -115
- data/vendor/testspec-0.3.0/doc/files/lib/test/spec_rb.html +0 -123
- data/vendor/testspec-0.3.0/doc/fr_class_index.html +0 -38
- data/vendor/testspec-0.3.0/doc/fr_file_index.html +0 -33
- data/vendor/testspec-0.3.0/doc/fr_method_index.html +0 -102
- data/vendor/testspec-0.3.0/doc/index.html +0 -24
- data/vendor/testspec-0.3.0/doc/rdoc-style.css +0 -208
- data/vendor/testspec-0.3.0/examples/stack.rb +0 -38
- data/vendor/testspec-0.3.0/examples/stack_spec.rb +0 -119
- data/vendor/testspec-0.3.0/lib/test/spec.rb +0 -490
- data/vendor/testspec-0.3.0/lib/test/spec/dox.rb +0 -122
- data/vendor/testspec-0.3.0/lib/test/spec/rdox.rb +0 -25
- data/vendor/testspec-0.3.0/lib/test/spec/should-output.rb +0 -49
- data/vendor/testspec-0.3.0/test/spec_dox.rb +0 -39
- data/vendor/testspec-0.3.0/test/spec_flexmock.rb +0 -210
- data/vendor/testspec-0.3.0/test/spec_mocha.rb +0 -118
- data/vendor/testspec-0.3.0/test/spec_nestedcontexts.rb +0 -26
- data/vendor/testspec-0.3.0/test/spec_should-output.rb +0 -26
- data/vendor/testspec-0.3.0/test/spec_testspec.rb +0 -522
- data/vendor/testspec-0.3.0/test/spec_testspec_order.rb +0 -26
- data/vendor/testspec-0.3.0/test/test_testunit.rb +0 -21
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
= 0.2.3
|
2
|
+
- Moved to Echoe
|
3
|
+
- Added feature of figuring out the base URL for relative URLs
|
4
|
+
- Removed vendor/, now has test/spec 0.3 gem dependency
|
5
|
+
- Added after_find callbacks to run arbitrary code after a uformat is found
|
6
|
+
|
1
7
|
= 0.2.2
|
2
8
|
- Proper ISO8601 date handling and cleanup of String#coerce
|
3
9
|
|
data/Manifest.txt
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
./CHANGELOG
|
2
|
+
./init.rb
|
3
|
+
./lib/microformat/array.rb
|
4
|
+
./lib/microformat/simple.rb
|
5
|
+
./lib/microformat/string.rb
|
6
|
+
./lib/microformat/time.rb
|
7
|
+
./lib/microformat.rb
|
8
|
+
./lib/mofo/adr.rb
|
9
|
+
./lib/mofo/geo.rb
|
10
|
+
./lib/mofo/hcalendar.rb
|
11
|
+
./lib/mofo/hcard.rb
|
12
|
+
./lib/mofo/hentry.rb
|
13
|
+
./lib/mofo/hfeed.rb
|
14
|
+
./lib/mofo/hresume.rb
|
15
|
+
./lib/mofo/hreview.rb
|
16
|
+
./lib/mofo/rel_bookmark.rb
|
17
|
+
./lib/mofo/rel_tag.rb
|
18
|
+
./lib/mofo/xfn.rb
|
19
|
+
./lib/mofo/xoxo.rb
|
20
|
+
./lib/mofo.rb
|
21
|
+
./LICENSE
|
22
|
+
./Manifest.txt
|
23
|
+
./Rakefile
|
24
|
+
./README
|
25
|
+
./site/index.html
|
26
|
+
./site/mofo-logo.png
|
27
|
+
./site/mootools.v1.00.js
|
28
|
+
./site/style.css
|
29
|
+
./test/base_url_test.rb
|
30
|
+
./test/ext_test.rb
|
31
|
+
./test/fixtures/bob.html
|
32
|
+
./test/fixtures/chowhound.html
|
33
|
+
./test/fixtures/corkd.html
|
34
|
+
./test/fixtures/event_addr.html
|
35
|
+
./test/fixtures/events.html
|
36
|
+
./test/fixtures/fake.html
|
37
|
+
./test/fixtures/fauxtank.html
|
38
|
+
./test/fixtures/hatom.html
|
39
|
+
./test/fixtures/hresume.html
|
40
|
+
./test/fixtures/include_pattern_single_attribute.html
|
41
|
+
./test/fixtures/simple.html
|
42
|
+
./test/fixtures/stoneship.html
|
43
|
+
./test/fixtures/upcoming.html
|
44
|
+
./test/fixtures/upcoming_single.html
|
45
|
+
./test/fixtures/xfn.html
|
46
|
+
./test/hatom_test.rb
|
47
|
+
./test/hcalendar_test.rb
|
48
|
+
./test/hcard_test.rb
|
49
|
+
./test/hresume_test.rb
|
50
|
+
./test/hreview_test.rb
|
51
|
+
./test/include_pattern_test.rb
|
52
|
+
./test/reltag_test.rb
|
53
|
+
./test/test_helper.rb
|
54
|
+
./test/xfn_test.rb
|
55
|
+
./test/xoxo_test.rb
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
version = '0.2.3'
|
5
|
+
svn_repo = 'svn+ssh://chris@errtheblog.com/svn/projects/mofo'
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'echoe'
|
9
|
+
|
10
|
+
Echoe.new('mofo', version) do |p|
|
11
|
+
p.rubyforge_name = 'mofo'
|
12
|
+
p.summary = "mofo is a ruby microformat parser"
|
13
|
+
p.description = "mofo is a ruby microformat parser"
|
14
|
+
p.url = "http://mofo.rubyforge.org/"
|
15
|
+
p.author = 'Chris Wanstrath'
|
16
|
+
p.email = "chris@ozmm.org"
|
17
|
+
p.extra_deps << ['hpricot', '>=0.4.59']
|
18
|
+
p.test_globs = 'test/*_test.rb'
|
19
|
+
end
|
20
|
+
|
21
|
+
rescue LoadError => boom
|
22
|
+
puts "You are missing a dependency required for meta-operations on this gem."
|
23
|
+
puts "#{boom.to_s.capitalize}."
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Tag the current trunk with the current release version"
|
27
|
+
task :tag do
|
28
|
+
warn "WARNING: this will tag #{svn_repo}/trunk using the tag REL_#{version.gsub!('.','_')}"
|
29
|
+
warn "If you do not wish to continue, you have 5 seconds to cancel by pressing CTRL-C..."
|
30
|
+
5.times { |i| print "#{5-i} "; $stdout.flush; sleep 1 }
|
31
|
+
system %[svn copy #{svn_repo}/trunk #{svn_repo}/tags/REL_#{version} -m "Tagging the #{version} release"]
|
32
|
+
end
|
data/init.rb
ADDED
data/lib/microformat.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
%w(rubygems hpricot microformat/string microformat/array open-uri ostruct timeout).each { |f| require f }
|
2
|
-
gem 'hpricot', '>=
|
2
|
+
gem 'hpricot', '>=0.4.59'
|
3
3
|
|
4
4
|
class Microformat
|
5
5
|
module Base
|
@@ -10,6 +10,8 @@ class Microformat
|
|
10
10
|
target, @options = args
|
11
11
|
@options ||= target.is_a?(Hash) ? target : {}
|
12
12
|
[:first, :all].each { |key| target = @options[key] if @options[key] }
|
13
|
+
|
14
|
+
extract_base_url! target, @options
|
13
15
|
|
14
16
|
@doc = build_doc(@options[:text] ? @options : target)
|
15
17
|
|
@@ -49,9 +51,16 @@ class Microformat
|
|
49
51
|
##
|
50
52
|
# DSL Related
|
51
53
|
#
|
54
|
+
def after_find(&block)
|
55
|
+
@after_find_procs ||= Hash.new { |h,k| h[k] = [] }
|
56
|
+
@after_find_procs[name] << block if block_given?
|
57
|
+
@after_find_procs[name]
|
58
|
+
end
|
59
|
+
alias :after_finds :after_find
|
60
|
+
|
52
61
|
def inherited(klass)
|
53
|
-
klass.instance_variable_set(
|
54
|
-
klass.instance_variable_set(
|
62
|
+
klass.instance_variable_set(:@container, klass.name.downcase)
|
63
|
+
klass.instance_variable_set(:@attributes, Hash.new([]))
|
55
64
|
end
|
56
65
|
|
57
66
|
def collector
|
@@ -119,14 +128,31 @@ class Microformat
|
|
119
128
|
def build_class(microformat)
|
120
129
|
hash = build_hash(microformat)
|
121
130
|
class_eval { attr_reader *(hash.keys << :properties) }
|
131
|
+
|
122
132
|
klass = new
|
123
|
-
klass.instance_variable_set(
|
133
|
+
klass.instance_variable_set(:@properties, hash.keys.map { |i| i.to_s } )
|
134
|
+
|
124
135
|
hash.each do |key, value|
|
125
136
|
klass.instance_variable_set("@#{key}", prepare_value(value) )
|
126
137
|
end
|
138
|
+
|
139
|
+
after_find_callbacks! klass
|
140
|
+
|
127
141
|
klass
|
128
142
|
end
|
129
143
|
|
144
|
+
def after_find_callbacks!(object)
|
145
|
+
original_ivars = object.instance_variables.dup
|
146
|
+
|
147
|
+
after_finds.each do |block|
|
148
|
+
object.instance_eval &block
|
149
|
+
end
|
150
|
+
|
151
|
+
Array(object.instance_variables - original_ivars).each do |ivar|
|
152
|
+
object.properties << ivar.gsub('@','')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
130
156
|
def build_hash(doc, attributes = @attributes)
|
131
157
|
hash = {}
|
132
158
|
|
@@ -203,11 +229,12 @@ class Microformat
|
|
203
229
|
|
204
230
|
def parse_element(element, target = nil)
|
205
231
|
if target == :url
|
206
|
-
case element.name
|
232
|
+
url = case element.name
|
207
233
|
when 'img' then element['src']
|
208
234
|
when 'a' then element['href']
|
209
235
|
when 'object' then element['value']
|
210
236
|
end
|
237
|
+
url[/^http/] ? url : @base_url.to_s + url
|
211
238
|
elsif target.is_a? Array
|
212
239
|
target.inject(nil) do |found, klass|
|
213
240
|
klass = klass.respond_to?(:find) ? klass : nil
|
@@ -215,7 +242,7 @@ class Microformat
|
|
215
242
|
found || parse_element(element, klass)
|
216
243
|
end
|
217
244
|
elsif target.is_a? Class
|
218
|
-
target.find(:first => element)
|
245
|
+
target.find({:first => element}.merge(@options))
|
219
246
|
else
|
220
247
|
value = case element.name
|
221
248
|
when 'abbr' then element['title']
|
@@ -229,6 +256,12 @@ class Microformat
|
|
229
256
|
def prepare_value(value)
|
230
257
|
value.is_a?(Hash) ? OpenStruct.new(value) : value
|
231
258
|
end
|
259
|
+
|
260
|
+
def extract_base_url!(target, options)
|
261
|
+
@base_url = nil
|
262
|
+
@base_url ||= options[:base] || options[:url]
|
263
|
+
@base_url ||= target[/^(http:\/\/[^\/]+)/] if target.respond_to?(:scan)
|
264
|
+
end
|
232
265
|
end
|
233
266
|
|
234
267
|
def method_missing(method, *args, &block)
|
data/lib/mofo/hentry.rb
CHANGED
data/site/index.html
ADDED
@@ -0,0 +1,382 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
7
|
+
|
8
|
+
<title>mofo - a ruby microformat parser</title>
|
9
|
+
<link href="style.css" rel="stylesheet" type="text/css" />
|
10
|
+
<script type="text/javascript" src="mootools.v1.00.js"></script>
|
11
|
+
<script type="text/javascript">function sc(el) { new Fx.Scroll(window).toElement(el); }</script>
|
12
|
+
</head>
|
13
|
+
|
14
|
+
<body>
|
15
|
+
<div id="container">
|
16
|
+
<div id="header">
|
17
|
+
<img src="mofo-logo.png" alt="mofo!" />
|
18
|
+
<br /><hr />
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<div id="left">
|
22
|
+
<h3>mofo</h3>
|
23
|
+
|
24
|
+
<ul class="xoxo">
|
25
|
+
<li><a href="#" onclick="sc('get_started')">Get Started</a></li>
|
26
|
+
<li><a href="#" onclick="sc('microwhozit')">Microwhozit?</a></li>
|
27
|
+
<li><a href="#" onclick="sc('find')">Mofo#find</a></li>
|
28
|
+
<li><a href="#" onclick="sc('supported')">Supported Microformats</a></li>
|
29
|
+
<li><a href="#" onclick="sc('rails')">Ruby on Rails</a></li>
|
30
|
+
<li><a href="#" onclick="sc('touch')">Get in Touch</a></li>
|
31
|
+
</ul>
|
32
|
+
|
33
|
+
<h3>Points of Interest</h3>
|
34
|
+
|
35
|
+
<ul class="xoxo">
|
36
|
+
<li><a href="http://errtheblog.com/post/37">Me and uFormats</a></li>
|
37
|
+
<li><a href="http://microformats.org">Microformats HQ</a></li>
|
38
|
+
<li><a href="http://microformatique.com">Microformatique</a></li>
|
39
|
+
<li><a href="http://labnotes.org">Assaf Arkin</a></li>
|
40
|
+
<li><a href="http://allinthehead.com">Drew McClellan</a></li>
|
41
|
+
<li><a href="http://tantek.com">Tantek Çelik</a></li>
|
42
|
+
<li><a href="http://theryanking.com/blog">Ryan King</a></li>
|
43
|
+
</ul>
|
44
|
+
|
45
|
+
<h3>Other Parsers</h3>
|
46
|
+
|
47
|
+
<ul class="xoxo">
|
48
|
+
<li><a href="http://rubyforge.org/projects/scrapi">Scrapi</a> [ruby]</li>
|
49
|
+
<li><a href="http://rubyforge.org/projects/uformats">uFormats</a> [ruby]</li>
|
50
|
+
<li><a href="http://allinthehead.com/hkit">hKit</a> [php]</li>
|
51
|
+
<li><a href="http://www.danwebb.net/2007/2/9/sumo-a-generic-microformats-parser-for-javascript">Sumo</a> [js]</li>
|
52
|
+
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/4106">Operator</a> [firefox]</li>
|
53
|
+
</ul>
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<div id="main">
|
57
|
+
<h3 id="get_started">Get Started Immediately</h3>
|
58
|
+
<br/>
|
59
|
+
<pre>
|
60
|
+
$ sudo gem install mofo -y
|
61
|
+
... install mofo and hpricot dependency ...
|
62
|
+
$ irb -rubygems
|
63
|
+
>> require 'mofo'
|
64
|
+
=> true
|
65
|
+
>> fireball = HCard.find 'http://flickr.com/people/gruber/'
|
66
|
+
=> #<HCard:0x6db898 ...>
|
67
|
+
>> fireball.properties
|
68
|
+
=> ["fn", "logo", "url", "n", "adr", "title", "nickname"]
|
69
|
+
>> fireball.nickname
|
70
|
+
=> "gruber"
|
71
|
+
>> fireball.url
|
72
|
+
=> "http://daringfireball.net/"
|
73
|
+
>> fireball.n.family_name
|
74
|
+
=> "Gruber"
|
75
|
+
>> fireball.title
|
76
|
+
=> "Raconteur"
|
77
|
+
>> fireball.adr.locality
|
78
|
+
=> "Philadelphia"
|
79
|
+
>> fireball.logo
|
80
|
+
=> "http://static.flickr.com/9/buddyicons/44621776@N00.jpg?1117572751"
|
81
|
+
</pre>
|
82
|
+
|
83
|
+
<h3 id="microwhozit">Microwhozit?</h3>
|
84
|
+
|
85
|
+
<p>
|
86
|
+
Microformats are tiny little markup definitions built on top of, usually,
|
87
|
+
HTML or XHTML.
|
88
|
+
</p>
|
89
|
+
<p>
|
90
|
+
You have a blog. You have recent posts on your blog's index page. You have
|
91
|
+
an Atom feed. You have recent posts on your blog's Atom feed. See where I'm
|
92
|
+
going with this?
|
93
|
+
</p>
|
94
|
+
<p>
|
95
|
+
The hAtom microformat (or uformat) can be embedded in your existing HTML by
|
96
|
+
setting CSS classes with semantic meaning inside of your posts. A class to signify
|
97
|
+
a post is contained within this div, a class to signify the contents of this
|
98
|
+
h3 are the post's title, a class to signify the contents of this span is the
|
99
|
+
blog post's author, etc.
|
100
|
+
</p>
|
101
|
+
<p>
|
102
|
+
You can then use a microformat parser (like, say, mofo) to extract this information
|
103
|
+
as you would from an Atom feed. Hell, you can even convert hAtom to Atom. It's an
|
104
|
+
insta-feed! No extra code required!
|
105
|
+
</p>
|
106
|
+
<p>
|
107
|
+
You're already doing the work, you see. Microformats are everywhere. We just need
|
108
|
+
to set them free.
|
109
|
+
</p>
|
110
|
+
<p>
|
111
|
+
Check it:</p>
|
112
|
+
|
113
|
+
<pre>
|
114
|
+
<div class="post">
|
115
|
+
<h3>Megadeth Show Last Night</h3>
|
116
|
+
<span class="subtitle">Posted by Chris on June 4th</span>
|
117
|
+
<div class="content">Went to a show last night. Megadeth. It was alright.</div>
|
118
|
+
</div>
|
119
|
+
</pre>
|
120
|
+
|
121
|
+
<p>Right? Normal. Here's the same post marked up with hAtom:</p>
|
122
|
+
|
123
|
+
<pre>
|
124
|
+
<div class="post <strong>hentry</strong>">
|
125
|
+
<h3 class="<strong>entry-title</strong>">Megadeth Show Last Night</h3>
|
126
|
+
<span class="subtitle">Posted by <span class="<strong>author vcard fn</strong>">Chris</span> on
|
127
|
+
<abbr class="<strong>updated</strong>" title="2006-06-04T10:32:10Z">June 4th</abbr></span>
|
128
|
+
<div class="content <strong>entry-content</strong>">
|
129
|
+
Went to a show last night. Megadeth. It was alright.
|
130
|
+
</div>
|
131
|
+
</div>
|
132
|
+
</pre>
|
133
|
+
|
134
|
+
<p>
|
135
|
+
All I did was add the hentry, entry-title, and entry-content classes to existing containers. Then I
|
136
|
+
went ahead and wrapped the date in an <abbr> tag giving it a title in the microformat-standard way. Finally
|
137
|
+
I put a div around Chris signifying it as the author field of the hEntry and making it a valid hCard by
|
138
|
+
including the vcard and fn classes. It's really not all that hard. Did I mess it up? Maybe, but I'm sure I got
|
139
|
+
close. And I didn't even use a reference. Practice.
|
140
|
+
</p>
|
141
|
+
|
142
|
+
<p>
|
143
|
+
How'd we parse this, tho?
|
144
|
+
</p>
|
145
|
+
|
146
|
+
<pre>
|
147
|
+
$ irb -rubygems
|
148
|
+
>> require 'mofo'
|
149
|
+
=> true
|
150
|
+
>> post = HEntry.find 'http://milesofstyle.org/posts/351-megadeth-show-last-night'
|
151
|
+
=> #<HEntry:0x6db898 ... >
|
152
|
+
>> post.entry_title
|
153
|
+
=> "Megadeth Show Last Night"
|
154
|
+
>> post.properties
|
155
|
+
=> ["entry_content", "updated", "author", "entry_title"]
|
156
|
+
>> post.updated
|
157
|
+
=> Sun Jun 04 10:32:10 UTC 2006
|
158
|
+
>> post.updated.class
|
159
|
+
=> Time
|
160
|
+
>> post.author
|
161
|
+
=> #<HCard:0x6e7b98 @properties=["fn"], @fn="Chris">
|
162
|
+
>> post.author.fn
|
163
|
+
=> "Chris"
|
164
|
+
>> post.entry_content
|
165
|
+
=> "Went to a show last night. Megadeth. It was alright."
|
166
|
+
</pre>
|
167
|
+
<p>
|
168
|
+
That's, like, stupid easy. If HEntry.find gets back more than one hEntry, you'll get an array.
|
169
|
+
</p>
|
170
|
+
|
171
|
+
<h3 id="find">Mofo#find</h3>
|
172
|
+
|
173
|
+
<p>Everything revolves around the #find method. Sound familiar? Yeah.</p>
|
174
|
+
|
175
|
+
<pre>
|
176
|
+
>> Microformat.find "http://valid-url.com"
|
177
|
+
>> Microformat.find "/path/to/existing/file"
|
178
|
+
>> Microformat.find :text => "microformat text"
|
179
|
+
</pre>
|
180
|
+
|
181
|
+
<p>
|
182
|
+
Also, #find can be told explicitly to find all (returning an array on failure) or only find
|
183
|
+
the first (returning nil on failure).
|
184
|
+
</p>
|
185
|
+
|
186
|
+
<pre>
|
187
|
+
>> Microformat.find :all => "/existing/file"
|
188
|
+
=> [ array of microformat objects ]
|
189
|
+
>> Microformat.find :first => "/existing/file"
|
190
|
+
=> microformat object
|
191
|
+
>> Microformat.find "/existing/file"
|
192
|
+
=> either an array of objects or just one object
|
193
|
+
</pre>
|
194
|
+
|
195
|
+
<p>When parsing a string, use :all and :first go outside of :text.</p>
|
196
|
+
|
197
|
+
<pre>
|
198
|
+
>> Microformat.find :all => { :text => 'mfin text' }
|
199
|
+
</pre>
|
200
|
+
|
201
|
+
<p>
|
202
|
+
That's it.
|
203
|
+
</p>
|
204
|
+
|
205
|
+
<h3 id="supported">Supported Microformats</h3>
|
206
|
+
|
207
|
+
<p><strong>hCard</strong> - <a href="http://microformats.org/wiki/hcard">http://microformats.org/wiki/hcard</a></p>
|
208
|
+
<pre>
|
209
|
+
>> messina = HCard.find 'http://www.flickr.com/people/factoryjoe/'
|
210
|
+
=> #<HCard:0x125eb5c ...>
|
211
|
+
>> messina.properties
|
212
|
+
=> ["fn", "note", "logo", "url", "n", "adr", "title", "nickname"]
|
213
|
+
>> messina.title
|
214
|
+
=> "Citizen Provocateur, Open Source Ambassador"
|
215
|
+
>> messina.logo
|
216
|
+
=> "http://farm1.static.flickr.com/1/buddyicons/25419820@N00.jpg?1167346106"
|
217
|
+
>> messina.n
|
218
|
+
=> #<OpenStruct given_name="Chris", family_name="Messina">
|
219
|
+
>> messina.fn
|
220
|
+
=> "Chris Messina"
|
221
|
+
>> messina.url
|
222
|
+
=> "http://factoryjoe.com/blog"
|
223
|
+
>> messina.nickname
|
224
|
+
=> "factoryjoe"
|
225
|
+
</pre>
|
226
|
+
|
227
|
+
<p><strong>hCalendar</strong> - <a href="http://microformats.org/wiki/hcalendar">http://microformats.org/wiki/hcalendar</a></p>
|
228
|
+
<pre>
|
229
|
+
>> events = HCalendar.find 'http://upcoming.org'
|
230
|
+
=> [#<HCalendar:0x131d304 ...> ... ]
|
231
|
+
>> events.size
|
232
|
+
=> 17
|
233
|
+
>> events.first.properties
|
234
|
+
=> ["summary", "url", "location"]
|
235
|
+
>> events.first.location
|
236
|
+
=> "Neumo&#39;s, Seattle, WA"
|
237
|
+
>> events.first.summary
|
238
|
+
=> "Ratatat + 120 Days"
|
239
|
+
</pre>
|
240
|
+
|
241
|
+
<p><strong>hReview</strong> - <a href="http://microformats.org/wiki/hreview">http://microformats.org/wiki/hreview</a></p>
|
242
|
+
<pre>
|
243
|
+
>> wine = HReview.find 'http://corkd.com/wine/view/1772'
|
244
|
+
=> [#<HReview:0x156c3f8 ...> ...]
|
245
|
+
>> wine.size
|
246
|
+
=> 7
|
247
|
+
>> wine.first.properties
|
248
|
+
=> ["rating", "description", "item", "reviewer", "tags", "dtreviewed"]
|
249
|
+
>> wine.first.rating
|
250
|
+
=> 3
|
251
|
+
>> wine.first.tags
|
252
|
+
=> ["fresh", "lime", "pear"]
|
253
|
+
>> wine.first.dtreviewed
|
254
|
+
=> Fri Jun 02 00:00:00 -0700 2006
|
255
|
+
</pre>
|
256
|
+
|
257
|
+
<p><strong>hEntry</strong> - <a href="http://microformats.org/wiki/hatom">http://microformats.org/wiki/hatom</a></p>
|
258
|
+
<pre>
|
259
|
+
>> post = HEntry.find 'http://errtheblog.com'
|
260
|
+
=> #<HEntry:0x169309c ...>
|
261
|
+
>> post.properties
|
262
|
+
=> ["published", "entry_title", "author", "entry_content", "bookmark", "tags"]
|
263
|
+
>> post.author.class
|
264
|
+
=> HCard
|
265
|
+
>> post.author.fn
|
266
|
+
=> "Chris"
|
267
|
+
>> post.published
|
268
|
+
=> Mon Mar 26 09:21:00 UTC 2007
|
269
|
+
>> post.entry_content.length
|
270
|
+
=> 4737
|
271
|
+
</pre>
|
272
|
+
|
273
|
+
<p><strong>hResume</strong> - <a href="http://microformats.org/wiki/hresume">http://microformats.org/wiki/hresume</a></p>
|
274
|
+
<pre>
|
275
|
+
>> crunch = HResume.find 'http://www.linkedin.com/in/michaelarrington'
|
276
|
+
=> #<HResume:0x129d370 ...>
|
277
|
+
>> crunch.properties
|
278
|
+
=> ["summary", "education", "experience", "contact"]
|
279
|
+
>> crunch.experience.first.class
|
280
|
+
=> HCalendar
|
281
|
+
>> crunch.contact
|
282
|
+
=> #<HCard:0x36614 ...>
|
283
|
+
>> crunch.contact.title
|
284
|
+
=> "Editor - TechCrunch"
|
285
|
+
</pre>
|
286
|
+
|
287
|
+
<p><strong>XOXO</strong> - <a href="http://microformats.org/wiki/xoxo">http://microformats.org/wiki/xoxo</a></p>
|
288
|
+
<pre>
|
289
|
+
>> mofo = XOXO.find 'http://mofo.rubyforge.org', :class => true
|
290
|
+
=> [["Get Started", "Microwhozit?", "Mofo#find", ...]
|
291
|
+
>> mofo.first
|
292
|
+
=> ["Get Started", "Microwhozit?", "Mofo#find", "Supported Microformats", ...]
|
293
|
+
>> mofo[1]
|
294
|
+
=> ["Me and uFormats", "Microformats HQ", "Microformatique", "Assaf Arkin", ...]
|
295
|
+
>> mofo[1].first
|
296
|
+
=> "Me and uFormats"
|
297
|
+
>> mofo[1].first.class
|
298
|
+
=> XOXO::Label
|
299
|
+
>> mofo[1].first.url
|
300
|
+
=> "http://errtheblog.com/post/37"
|
301
|
+
</pre>
|
302
|
+
|
303
|
+
<p><strong>Geo</strong> - <a href="http://microformats.org/wiki/geo">http://microformats.org/wiki/geo</a></p>
|
304
|
+
<pre>
|
305
|
+
>> somewhere = Geo.find 'http://www.geograph.org.uk/photo/1234'
|
306
|
+
=> #<Geo:0x12337a4 ...>
|
307
|
+
>> somewhere.latitude
|
308
|
+
=> 54.05836
|
309
|
+
>> somewhere.longitude
|
310
|
+
=> -2.14662
|
311
|
+
</pre>
|
312
|
+
|
313
|
+
<p><strong>Adr</strong> - <a href="http://microformats.org/wiki/adr">http://microformats.org/wiki/adr</a></p>
|
314
|
+
<pre>
|
315
|
+
...coming soon...
|
316
|
+
</pre>
|
317
|
+
|
318
|
+
<p><strong>XFN</strong> - <a href="http://microformats.org/wiki/xfn">http://microformats.org/wiki/xfn</a></p>
|
319
|
+
<pre>
|
320
|
+
>> tons = XFN.find 'http://deliciouslymeta.com/projects/xfn/test_data.html'
|
321
|
+
=> #<XFN:0x157f200 ...>
|
322
|
+
>> tons.first
|
323
|
+
=> #<XFN::Link name="friend - contact", relation="contact", link="#contact">
|
324
|
+
>> tons.me_and_parent
|
325
|
+
=> #<XFN::Link name="me + parent", relation=["me", "parent"], link="#parent">
|
326
|
+
>> tons.me_and_parent.name
|
327
|
+
=> "me + parent
|
328
|
+
>> tons.neighbor
|
329
|
+
=> [#<XFN::Link ...> ...]
|
330
|
+
>> tons.neighbor.size
|
331
|
+
=> 5
|
332
|
+
>> tons.parent_and_kin.link
|
333
|
+
=> "#parent"
|
334
|
+
</pre>
|
335
|
+
|
336
|
+
|
337
|
+
<h3 id="rails">Ruby on Rails</h3>
|
338
|
+
|
339
|
+
<p>
|
340
|
+
mofo doubles as a Rails plugin. Just drop it into vendor/plugins and you are good to go, with all the
|
341
|
+
available microformat parsers loaded into your application.
|
342
|
+
|
343
|
+
mofo classes are YAML and Marshal approved, meaning you can cache them with memcached (or DRb) or store
|
344
|
+
them in a session.
|
345
|
+
</p>
|
346
|
+
|
347
|
+
<p>
|
348
|
+
Install with <a href="http://www.rubyinside.com/advent2006/12-piston.html">Piston</a>:
|
349
|
+
</p>
|
350
|
+
|
351
|
+
<pre>
|
352
|
+
$ piston import svn://errtheblog.com/svn/mofo/trunk vendor/plugins/mofo
|
353
|
+
</pre>
|
354
|
+
|
355
|
+
<p>
|
356
|
+
Install with SVN:
|
357
|
+
</p>
|
358
|
+
|
359
|
+
<pre>
|
360
|
+
$ ./script/plugin install -x svn://errtheblog.com/svn/mofo/trunk
|
361
|
+
</pre>
|
362
|
+
|
363
|
+
<h3 id="touch">Get in Touch</h3>
|
364
|
+
|
365
|
+
<ul>
|
366
|
+
<li>Me: chris[at]ozmm[dot]org (chris wanstrath)</li>
|
367
|
+
<li>Trac: <a href="http://require.errtheblog.com/mofo/browser">http://require.errtheblog.com/mofo/browser</a></li>
|
368
|
+
<li>SVN: svn://errtheblog.com/svn/mofo/trunk</li>
|
369
|
+
</ul>
|
370
|
+
</div>
|
371
|
+
|
372
|
+
<div id="footer">
|
373
|
+
<hr />
|
374
|
+
<p class="left">| <a href="http://jigsaw.w3.org/css-validator/">CSS</a> | <a href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a> |</p>
|
375
|
+
<p class="right">Designed by <a href="mailto:support@syndicateme.net">syndicateme.net</a>. Hosted by <a href="http://rubyforge.org">Rubyforge</a>. Birthed by <a href="http://errtheblog.com">Err</a>.</p>
|
376
|
+
<p> </p>
|
377
|
+
</div>
|
378
|
+
</div>
|
379
|
+
<script src="http://static.getclicky.com/4581.js" type="text/javascript"></script>
|
380
|
+
<noscript><p><img alt="Clicky" src="http://static.getclicky.com/4581ns.gif" /></p></noscript>
|
381
|
+
</body>
|
382
|
+
</html>
|