mofo 0.2.2 → 0.2.3
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.
- 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>
|