mofo 0.1.2 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,51 +2,49 @@ $:.unshift 'lib'
2
2
  require 'microformat'
3
3
 
4
4
  class XOXO < Microformat
5
- class << self
6
- PARENTS = %w[ol ul]
7
- CHILDREN = %w[li]
5
+ @@parents = %w[ol ul]
6
+ @@children = %w[li]
8
7
 
9
- xpath_build = proc { |element| element.map { |e| "/#{e}" } * ' | ' }
10
- CHILDREN_XPATH = xpath_build.call(CHILDREN)
11
- PARENTS_XPATH = xpath_build.call(PARENTS)
8
+ xpath_build = proc { |element| element.map { |e| "/#{e}" } * ' | ' }
9
+ @@children_xpath = xpath_build[@@children]
10
+ @@parents_xpath = xpath_build[@@parents]
12
11
 
13
- def find_first(doc)
14
- find_every(doc).first
15
- end
16
-
17
- def find_every(doc)
18
- tree = []
19
- doc.each do |child|
20
- tree << build_tree(child)
21
- end
22
- tree
23
- end
12
+ def self.find_first(doc)
13
+ find_every(doc).first
14
+ end
24
15
 
25
- def find_occurances(doc)
26
- @options[:class] ? doc/".xoxo" : doc.search(PARENTS_XPATH)
27
- end
16
+ def self.find_every(doc)
17
+ doc.map { |child| build_tree(child) }
18
+ end
28
19
 
29
- def build_tree(child)
30
- tree = []
31
- child.search(CHILDREN_XPATH) do |element|
32
- label, branch = nil, nil
33
- element.children.each do |inner|
34
- label ||= build_label(inner) unless inner.elem? && PARENTS.include?(inner.name)
35
- branch ||= build_tree(inner) if inner.elem? && PARENTS.include?(inner.name)
36
- end
37
- tree << (branch ? { label => branch } : label)
38
- end
39
- tree
40
- end
20
+ def self.find_occurences(doc)
21
+ @options[:class] ? doc/".xoxo" : doc.search(@@parents_xpath)
22
+ end
41
23
 
42
- def build_label(node)
43
- if node.elem?
44
- label = Label.new(node.innerHTML.strip)
45
- label.url = node['href'] if node.name == 'a'
46
- label
47
- elsif node.text? && !node.to_s.strip.empty?
48
- node.to_s.strip
24
+ def self.build_tree(child)
25
+ tree = []
26
+ child.search(@@children_xpath) do |element|
27
+ label, branch = nil, nil
28
+ element.children.each do |inner|
29
+ label ||= build_label(inner) unless container?(inner)
30
+ branch ||= build_tree(inner) if container?(inner)
49
31
  end
32
+ tree << (branch ? { label => branch } : label)
33
+ end
34
+ tree
35
+ end
36
+
37
+ def self.container?(el)
38
+ el.elem? && @@parents.include?(el.name)
39
+ end
40
+
41
+ def self.build_label(node)
42
+ if node.elem?
43
+ label = Label.new(node.innerHTML.strip)
44
+ label.url = node['href'] if node.name == 'a'
45
+ label
46
+ elsif node.text? && !node.to_s.strip.empty?
47
+ node.to_s.strip
50
48
  end
51
49
  end
52
50
 
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+ require 'microformat/string'
3
+ require 'microformat/array'
4
+
5
+ context "A string should be coercable into" do
6
+ specify "an integer" do
7
+ "2".coerce.should.equal 2
8
+ end
9
+
10
+ specify "a float" do
11
+ "4.0".coerce.should.equal 4.0
12
+ end
13
+
14
+ specify "a datetime" do
15
+ "1985-03-13".coerce.should.equal Time.parse("1985-03-13")
16
+ end
17
+
18
+ specify "a boolean" do
19
+ "true".coerce.should.be true
20
+ "false".coerce.should.be false
21
+ end
22
+ end
23
+
24
+ context "A string with HTML" do
25
+ specify "should be able to remove the HTML" do
26
+ string = %[<ol> <li><a href="http://diveintomark.org/xml/blink.xml" type="application/rss+xml">dive into mark b-links</a></li> <li><a href="http://www.thauvin.net/blog/xml.jsp?format=rdf" type="application/rss+xml">Eric&#39;s Weblog</a></li> <li><a href="http://intertwingly.net/blog/index.rss2" type="application/rss+xml">Sam Ruby</a></li> <li><a href="http://diveintomark.org/xml/atom.xml" type="application/atom+xml">dive into mark</a></li> <li><a href="http://www.decafbad.com/blog/index.rss" type="application/rss+xml">0xDECAFBAD</a></li> </ol>]
27
+ string.strip_html.strip.should.equal "dive into mark b-links Eric&#39;s Weblog Sam Ruby dive into mark 0xDECAFBAD"
28
+ end
29
+ end
30
+
31
+ context "An array sent first_or_self" do
32
+ setup do
33
+ @array = %w[one two]
34
+ end
35
+
36
+ specify "should return itself if it has more than one element" do
37
+ @array.first_or_self.should.be @array
38
+ end
39
+
40
+ specify "should return its first element if it has only one element" do
41
+ @array.pop
42
+ @array.first_or_self.should.be.an.instance_of String
43
+ end
44
+ end
@@ -0,0 +1,26 @@
1
+ <!-- Taken from upcoming.org and slimmed down -->
2
+ <div id="event" class="vevent">
3
+ <h1><span class="name summary">Bruce Cockburn</span></h1>
4
+
5
+ <div class="date"><abbr class="dtstart" title="20070313T200000">Tuesday, March 13, 2007</abbr></div>
6
+ <div class="time">8:00 PM</div> <!-- /.time -->
7
+
8
+ <br />
9
+ <div class="small">Where</div>
10
+
11
+ <div class="venue location">
12
+
13
+ <div class="address adr">
14
+ <span class="street-address">3210 Burton SE</span><br />
15
+ <span class="locality">Grand Rapids</span>, <span class="region">Michigan</span> <span class="postal-code"></span>
16
+ </div>
17
+
18
+ <span class="geo" style="display: none">
19
+ <span class="latitude">42.9268</span>,
20
+ <span class="longitude">-85.5888</span>
21
+ </span>
22
+
23
+ </div> <!-- /.venue -->
24
+
25
+ <div class="description">Fine Arts Center<br />$8 w/ Calvin ID, $20 public<br /></div>
26
+ </div>
@@ -0,0 +1,409 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
3
+ <head>
4
+ <title>LinkedIn: Scott Bedard</title>
5
+ <link rel="shortcut icon" type="image/ico" href="/favicon.ico" />
6
+ <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
7
+ <meta name="description" content="Scott Bedard's professional profile on LinkedIn. LinkedIn is a networking tool that helps users like Scott Bedard discover inside connections to recommended job candidates, industry experts and business partners." />
8
+ <link rel="stylesheet" type="text/css" href="/css/public-profile/default.css" media="screen,projection,print" />
9
+ <link rel="stylesheet" type="text/css" href="/css/public-profile/screen.css" media="screen,projection" />
10
+ <link rel="stylesheet" type="text/css" href="/css/public-profile/print.css" media="print" />
11
+ <script type="text/javascript" src="/js/showhide.js"></script>
12
+ <script type="text/javascript" src="/js/public_profile.js"></script>
13
+ <script type="text/javascript" src="/js/scripts.js"></script>
14
+ </head>
15
+ <body id="www-linkedin-com" class="public-profile">
16
+ <div class="hresume">
17
+ <div id="masthead" class="vcard contact">
18
+ <div id="nameplate">
19
+ <h1 id="name"><span class="fn n"> <span class="given-name">Scott</span> <span class="family-name">Bedard</span> </span></h1>
20
+ <p class="headline title"><strong>VP, Product Integration at Yahoo!</strong></p>
21
+ <div class="adr">
22
+ <p class="locality">
23
+ San Francisco Bay Area
24
+ </p>
25
+ </div>
26
+ </div>
27
+ <div id="overview">
28
+ <dl>
29
+ <dt>Current</dt>
30
+ <dd>
31
+ <ul class="current">
32
+ <li>
33
+
34
+
35
+
36
+ VP, Product Integration at Yahoo! </li>
37
+ </ul>
38
+ </dd>
39
+ <dt>Past</dt>
40
+ <dd>
41
+ <ul>
42
+ <li>
43
+
44
+
45
+
46
+ VP of Engineering at CNET Networks </li>
47
+ <li>
48
+
49
+
50
+
51
+
52
+ Founder
53
+ at eRankings, Inc
54
+ (Self-employed)
55
+
56
+ </li>
57
+ <li>
58
+
59
+
60
+
61
+ Senior Software Engineer at Channelinx Inc </li>
62
+ </ul>
63
+ <div class="showhide-block" id="morepast">
64
+ <ul>
65
+ </ul>
66
+ <p class="seeall showhide-link"><a href="#" id="morepast-hide">see less...</a></p>
67
+ </div>
68
+ </dd>
69
+ <dt>Education</dt>
70
+ <dd>
71
+ <ul>
72
+ <li>
73
+
74
+ Fitchburg State College
75
+
76
+ </li>
77
+ </ul>
78
+ </dd>
79
+ <dt class="recommended">Recommended</dt>
80
+ <dd class="recommended">
81
+ <img src="/img/icon/endorse/icon_endorse_2_35x24.gif" width="35" height="24" alt="Scott has 6 recommendations" title="Scott has 6 recommendations" /> <strong class="r2">6</strong> people have recommended Scott </dd>
82
+ <dt class="connections">Connections</dt>
83
+ <dd class="connections">
84
+ <img src="/img/icon/conx/icon_conx_16_24x24.gif" width="24" height="24" alt="" />
85
+ <strong>
86
+ 212
87
+ </strong> connections
88
+ </dd>
89
+ <dt>Industry</dt>
90
+ <dd>
91
+ Internet
92
+ </dd>
93
+ <dt>Websites</dt>
94
+ <dd>
95
+ <ul>
96
+ <li>
97
+ <a href="http://www.gamespot.com" class="url" rel="me" target="_blank">
98
+ My Website
99
+ </a> </li>
100
+ <li>
101
+ <a href="http://www.tv.com" class="url" rel="me" target="_blank">
102
+ My Website
103
+ </a> </li>
104
+ <li>
105
+ <a href="http://www.mp3.com" class="url" rel="me" target="_blank">
106
+ My Website
107
+ </a> </li>
108
+ </ul>
109
+ </dd>
110
+ </dl>
111
+ </div>
112
+ </div>
113
+ <hr />
114
+ <script type="text/javascript">
115
+ <!--
116
+ if (window.addEventListener || window.attachEvent)
117
+ { showHide.init(); }
118
+ // -->
119
+ </script>
120
+ <div id="summary">
121
+ <h2>Scott Bedard&#8217;s Summary</h2>
122
+ <p class="summary">
123
+ Responsible for working with all business units at Yahoo to better integrate all of their services with each other.
124
+ </p>
125
+ <h3>Scott Bedard&#8217;s Specialties:</h3>
126
+ <p class="skills">
127
+ product development, engineering, managment, team building from scratch.
128
+ </p>
129
+ </div>
130
+ <hr />
131
+ <div id="experience">
132
+ <h2>Scott Bedard&#8217;s Experience</h2>
133
+ <ul class="vcalendar">
134
+
135
+
136
+
137
+ <li class="experience vevent vcard"> <a href="#name" class="include"></a>
138
+
139
+ <h3 class="title">VP, Product Integration</h3>
140
+ <h4 class="org summary">Yahoo!</h4>
141
+
142
+ <p class="organization-details">(Public Company; 10,001 or more employees; yhoo; Internet industry)</p>
143
+ <p class="period">
144
+
145
+ <abbr class="dtstart" title="2007-02-01">February 2007</abbr>
146
+ &mdash; <abbr class="dtstamp" title="2007-03-21">Present</abbr>
147
+
148
+ <abbr class="duration" title="P2M">(2 months)</abbr>
149
+
150
+
151
+ </p>
152
+
153
+ <p class="description">Working with other business units to integrate their technologies with each other.</p>
154
+
155
+ </li>
156
+
157
+
158
+ <li class="experience vevent vcard"> <a href="#name" class="include"></a>
159
+
160
+ <h3 class="title">VP of Engineering</h3>
161
+ <h4 class="org summary">CNET Networks</h4>
162
+
163
+ <p class="organization-details">(Public Company; 1001-5000 employees; cnet; Internet industry)</p>
164
+ <p class="period">
165
+
166
+ <abbr class="dtstart" title="2003-05-01">May 2003</abbr>
167
+ &mdash; <abbr class="dtend" title="2007-02-01">February 2007</abbr>
168
+
169
+ <abbr class="duration" title="P3Y10M">(3 years 10 months)</abbr>
170
+
171
+
172
+ </p>
173
+
174
+ <p class="description">Worked my ass off at a bunch of start-ups. Finally got tired of working so hard for others, so I started my own website. It started taking off, so I sold it to CNET and came along with it. Built up the CNET Entertainment division from one site to the current portfolio of GameSpot, GameFAQs, Game Rankings, Metacritic, TV,com, MP3.com and FilmSpot.com.</p>
175
+
176
+ </li>
177
+
178
+
179
+ <li class="experience vevent vcard"> <a href="#name" class="include"></a>
180
+
181
+ <h3 class="title">Founder</h3>
182
+ <h4 class="org summary">eRankings, Inc
183
+ (Self-employed)</h4>
184
+
185
+
186
+ <p class="organization-details">(Self-Employed; 1-10 employees; Internet industry)</p>
187
+ <p class="period">
188
+
189
+ <abbr class="dtstart" title="2001-05-01">May 2001</abbr>
190
+ &mdash; <abbr class="dtend" title="2003-05-01">May 2003</abbr>
191
+
192
+ <abbr class="duration" title="P2Y1M">(2 years 1 month)</abbr>
193
+
194
+
195
+ </p>
196
+
197
+ <p class="description">Started Game Rankings.com and eventually sold out to the Man at CNET.</p>
198
+
199
+ </li>
200
+
201
+
202
+ <li class="experience vevent vcard"> <a href="#name" class="include"></a>
203
+
204
+ <h3 class="title">Senior Software Engineer</h3>
205
+ <h4 class="org summary">Channelinx Inc</h4>
206
+
207
+ <p class="organization-details">(Privately Held; 51-200 employees; Internet industry)</p>
208
+ <p class="period">
209
+
210
+ <abbr class="dtstart" title="2000-04-01">April 2000</abbr>
211
+ &mdash; <abbr class="dtend" title="2002-03-01">March 2002</abbr>
212
+
213
+ <abbr class="duration" title="P2Y">(2 years)</abbr>
214
+
215
+
216
+ </p>
217
+
218
+ <p class="description">Code Monkey at an internet start-up....BIG mistake!</p>
219
+
220
+ </li> </ul>
221
+ </div>
222
+ <hr />
223
+ <div id="education">
224
+ <h2>Scott Bedard&#8217;s Education</h2>
225
+ <ul class="vcalendar">
226
+
227
+
228
+
229
+
230
+ <li class="education vevent vcard">
231
+ <h3 class="summary fn org">
232
+
233
+ Fitchburg State College
234
+
235
+ </h3>
236
+ <div class="description">
237
+ <p>
238
+ <span class="degree">None</span>, <span class="major">Communications</span>,
239
+
240
+ <span name="startDate"><abbr class="dtstart" title="1986-01-01">1986</abbr></span> &mdash; <span name="endDate"><abbr class="dtend" title="1987-12-31">1987</abbr></span>
241
+
242
+ </p>
243
+
244
+
245
+ <dl class="activities-societies">
246
+ <dt>Activities and Societies:</dt>
247
+ <dd>TV Productions</dd>
248
+ </dl>
249
+
250
+ </div>
251
+ </li>
252
+ </ul>
253
+ </div>
254
+ <hr />
255
+ <div id="additional-information">
256
+ <h2>Additional Information</h2>
257
+ <h3>Scott Bedard&#8217;s Websites:</h3>
258
+ <ul class="websites">
259
+ <li>
260
+ <a href="http://www.gamespot.com" rel="me" target="_blank">
261
+ My Website
262
+ </a> </li>
263
+ <li>
264
+ <a href="http://www.tv.com" rel="me" target="_blank">
265
+ My Website
266
+ </a> </li>
267
+ <li>
268
+ <a href="http://www.mp3.com" rel="me" target="_blank">
269
+ My Website
270
+ </a> </li>
271
+ </ul>
272
+ <h3>Scott Bedard&#8217;s Interests:</h3>
273
+ <p class="interests">YouTube!</p>
274
+ </div>
275
+ <hr />
276
+ <div id="contact-settings">
277
+ <h2>Scott Bedard&#8217;s Contact Settings</h2>
278
+ <h3>Interested In:</h3>
279
+ <ul>
280
+ <li>
281
+ job inquiries
282
+ </li>
283
+ <li>
284
+ getting back in touch
285
+ </li>
286
+ </ul>
287
+ </div>
288
+ <hr />
289
+ <div class="viewfull">
290
+ <h2>View the full profile of <strong>Scott Bedard</strong></h2>
291
+ <ul>
292
+ <li>See who you and <strong>Scott Bedard</strong> know in common</li>
293
+ <li>Get introduced to <strong>Scott Bedard</strong></li>
294
+ <li>Contact <strong>Scott Bedard</strong> directly</li>
295
+ </ul>
296
+ <a href="http://www.linkedin.com/ppl/webprofile?action=vmi&id=4159007&authToken=9j0W&authType=name&trk=ppro_viewmore" ><img src="/img/btn/btn_view_full_profile_144x34.gif" width="144" height="34" alt="View Scott Bedard's Full Profile" /></a>
297
+ </div>
298
+ <div id="control" class="infobar">
299
+ <div class="actions">
300
+ <div class="buttonbox">
301
+ <div class="buttonbox-in">
302
+ <a href="http://www.linkedin.com/ppl/webprofile?action=ctu&id=4159007&authToken=9j0W&authType=name&trk=ppro_getintr" ><img src="/img/btn/btn_getintroduced_122x26.gif" width="122" height="26" alt="Get Introduced" /></a>
303
+ &nbsp;
304
+ <a href="http://www.linkedin.com/ppl/webprofile?action=ctu&id=4159007&authToken=9j0W&authType=name&trk=ppro_cntdir" ><img src="/img/btn/btn_contactdirectly_inmail_131x26.gif" width="131" height="26" alt="Contact Directly" /></a>
305
+ </div>
306
+ </div>
307
+ </div>
308
+ <div class="powered">
309
+ <div class="powered-in">
310
+ <h3><a href="http://www.linkedin.com/home?trk=ppro_pbli" ><img src="/img/hdr/hdr_poweredby_249x23.gif" width="249" height="23" alt="Public profile powered by LinkedIn" /></a></h3>
311
+ <p>Create a public profile: <strong>
312
+ <a href="http://www.linkedin.com/ppl/webprofile?action=gwp&id=4159007&authToken=9j0W&authType=name&trk=ppro_geturl" >Sign In</a>
313
+ </strong> or <strong>
314
+ <a href="https://www.linkedin.com/secure/register?trk=ppro_joinnow" >Join Now</a>
315
+ </strong></p>
316
+ </div>
317
+ </div>
318
+ <div class="rndbox" id="readmore">
319
+ <div class="rndbox-in">
320
+ <h3>View Scott&#8217;s full profile:</h3>
321
+ <ul>
322
+ <li>See who you and <strong>Scott Bedard</strong> know in common</li>
323
+ <li>Get introduced to <strong>Scott Bedard</strong></li>
324
+ <li>Contact <strong>Scott Bedard</strong> directly</li>
325
+ </ul>
326
+ <p class="btn">
327
+ <a href="http://www.linkedin.com/ppl/webprofile?action=vmi&id=4159007&authToken=9j0W&authType=name&trk=ppro_viewmore" ><img src="/img/btn/btn_view_full_profile_144x34.gif" width="144" height="34" alt="View Scott Bedard's Full Profile" /></a>
328
+ </p>
329
+ </div>
330
+ </div>
331
+ <div class="rndbox" id="search">
332
+ <div class="rndbox-in">
333
+ <h3><img src="/img/hdr/hdr_name_search_122x15.gif" width="122" height="15" alt="Name Search" /></h3>
334
+ <p><strong>Search for people you know</strong> from over 9 million professionals already on LinkedIn.</p>
335
+ <form name="searchForm" action="/pub/dir/" method="get">
336
+ <p class="field"><span class="lbl">
337
+ <label for="first">First Name</label>
338
+ <br />
339
+ </span>
340
+ <input type="text" name="first" id="first" />
341
+ &nbsp;&nbsp;<span class="lbl"><br />
342
+ <label for="last">Last Name</label>
343
+ <br />
344
+ </span>
345
+ <input type="text" name="last" id="last" />
346
+ </p>
347
+ <p class="example">
348
+ <input type="image" name="search" src="/img/btn/btn_search_61x20.gif" value="" />
349
+ (example: <strong>
350
+ <a href="/pub/dir/Scott/Bedard?trk=ppro_find_others" >Scott Bedard</a> </strong>)
351
+ </p>
352
+ </form>
353
+ </div>
354
+ </div>
355
+ <script type="text/javascript">
356
+ <!--
357
+ if (window.addEventListener || window.attachEvent)
358
+ { fancyLabels.init('search'); }
359
+ // -->
360
+ </script>
361
+ <script type="text/javascript">
362
+ var dbl_page = 'public_profile';
363
+ </script>
364
+
365
+
366
+ <!-- DO NOT change order of tags -->
367
+
368
+ <script type="text/javascript">
369
+ var _leo_profile = null;
370
+ var google_keywords = null;
371
+ </script>
372
+
373
+ <script type="text/javascript" src="/js/adproxy.js"></script>
374
+
375
+ <script type="text/javascript">
376
+ <!--
377
+ var google_ad_client = 'pub-2283433109277150';
378
+
379
+ var google_ad_width = 300;
380
+ var google_ad_height = 250;
381
+ var google_ad_format = "300x250_as";
382
+ var google_ad_channel = "";
383
+ var google_color_border = "FFFFFF";
384
+ var google_color_bg = "FFFFFF";
385
+ var google_color_link = "0000FF";
386
+ var google_color_url = "008000";
387
+ var google_color_text = "000000";
388
+ // -->
389
+ </script>
390
+
391
+ <script type="text/javascript" src="/js/google.js"></script>
392
+
393
+ <script type="text/javascript">
394
+ var dbl_tile = '3';
395
+ var dbl_sz = '300x250';
396
+ </script>
397
+ <script type="text/javascript" src="/js/doubleclick.js"></script> </div>
398
+ </div>
399
+ <hr />
400
+
401
+ <div id="footer" class="guest">
402
+ <ul>
403
+ <li class="first"><a href="http://www.linkedin.com/static?key=company_info" >About LinkedIn</a></li>
404
+ <li><a href="http://www.linkedin.com/static?key=customer_service" >Customer Service/<abbr title="Frequently Asked Questions">FAQ</abbr></a></li>
405
+ <li class="last"><a href="http://www.linkedin.com/static?key=contact_feedback" >Send Us Feedback</a></li>
406
+ </ul>
407
+ <p>All content Copyright &copy; 2003-7, LinkedIn Corporation</p>
408
+ </div></body>
409
+ </html>