html2markdown 0.0.2 → 0.0.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/Gemfile CHANGED
@@ -5,6 +5,8 @@ group :development, :test do
5
5
  # Testing infrastructure
6
6
  gem 'guard'
7
7
  gem 'guard-rspec'
8
+ gem 'vcr'
9
+ gem 'webmock'
8
10
 
9
11
  end
10
12
 
data/Readme.md CHANGED
@@ -1,11 +1,30 @@
1
- ### Yet Another Html to Markdown ruby lib
1
+ ### Simple html to Markdown ruby gem
2
2
  We love markdown, cause it is friendly to edit.
3
- So we want everything to be markdown
3
+ So we want everything to be **markdown**
4
4
 
5
- ### spec is our promise
5
+ ### RSpec is our promise
6
6
  ```ruby
7
7
  p = HTMLPage.new :contents => '<strong>haha</strong>'
8
8
  p.markdown.should == '**haha**'
9
9
  p.contents = '<strong>hehe</strong>'
10
10
  p.markdown!.should == '**hehe**'
11
+
12
+ # you can also define your own node parse
13
+ p.strong do |node,contents|
14
+ "strong text : **#{contents}**"
15
+ end
16
+ p.markdown!.should be_include('strong text')
17
+ ```
18
+
19
+ ### Installation
20
+ * gem
21
+
22
+ ```ruby
23
+ gem install html2markdown
24
+ ```
25
+
26
+ * Rails Gemfile
27
+
28
+ ```ruby
29
+ gem 'html2markdown'
11
30
  ```
@@ -0,0 +1,545 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://www.kickstarter.com/projects/1397300529/railsapp
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Ruby
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Server:
20
+ - nginx/1.0.11
21
+ Date:
22
+ - Wed, 28 Mar 2012 23:06:46 GMT
23
+ Content-Type:
24
+ - text/html; charset=utf-8
25
+ Connection:
26
+ - keep-alive
27
+ Status:
28
+ - 200 OK
29
+ Etag:
30
+ - ! '"75da5432903c1b163d600fcf81fa65b1"'
31
+ Set-Cookie:
32
+ - _ksr_session=BAh7ByIPc2Vzc2lvbl9pZCIlNjhlZGU3NGE3NDQxMWNlMmY4ZDc2NTgyYjk4M2Q1N2QiEF9jc3JmX3Rva2VuIjFLSnV1a1c0RWhLbG12cmQwaVpKVjl1b1VLNHdoSW4rSmJ1Y2J3RmpIMUFjPQ%3D%3D--31eac2c89ed04e369b81ef4dd247fbae2098517e;
33
+ path=/
34
+ - abid=BAgiFTk5NDA2OWM4OTY1Y2NhZjI%3D--512e3e9f12894311c8dc10fcb05d3e14f539265c;
35
+ path=/; expires=Sun, 28-Mar-2032 23:06:46 GMT
36
+ - last_page=http%3A%2F%2Fwww.kickstarter.com%2Fprojects%2F1397300529%2Frailsapp;
37
+ path=/; expires=Wed, 28-Mar-2012 23:36:46 GMT
38
+ - request_time=Wed%2C+28+Mar+2012+23%3A06%3A46+-0000; path=/
39
+ Content-Length:
40
+ - '42056'
41
+ Cache-Control:
42
+ - max-age=0, private, must-revalidate
43
+ X-Runtime:
44
+ - '0.139642'
45
+ X-Ua-Compatible:
46
+ - IE=Edge,chrome=1
47
+ body:
48
+ encoding: ASCII-8BIT
49
+ string: ! "<!DOCTYPE html>\n<html class=\"projects_show no-js fontface \" lang=\"en\"
50
+ xml:lang=\"en\" xmlns:fb=\"http://www.facebook.com/2008/fbml\" xmlns=\"http://www.w3.org/1999/xhtml\">\n<head><script
51
+ type=\"text/javascript\">var NREUMQ=NREUMQ||[];NREUMQ.push([\"mark\",\"firstbyte\",new
52
+ Date().getTime()]);</script><title>rails.app by Yehuda Katz &mdash; Kickstarter</title><!--[if
53
+ lt IE 9]>\n <script src=\"http://html5shim.googlecode.com/svn/trunk/html5.js\"
54
+ type=\"text/javascript\"></script>\n<![endif]-->\n\n\n<meta content=\"text/html;
55
+ charset=utf-8\" http-equiv=\"Content-Type\">\n<meta content=\"telephone=no\"
56
+ name=\"format-detection\">\n<link href=\"/fonts/fonts.css\" media=\"screen\"
57
+ rel=\"stylesheet\" type=\"text/css\">\n<link href=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/assets/project_page.css\"
58
+ media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n<!--[if lte IE 7]>\n
59
+ \ <link href=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/stylesheets/compass/library/ie.css\"
60
+ media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n<![endif]-->\n\n<link
61
+ href=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/favicon.png\"
62
+ rel=\"icon\" type=\"image/png\">\n<link href=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/apple-touch-icon-precomposed.png\"
63
+ rel=\"apple-touch-icon-precomposed\" type=\"image/png\">\n<link href=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/apple-touch-icon-ipad-precomposed.png\"
64
+ rel=\"apple-touch-icon-precomposed\" sizes=\"72x72\" type=\"image/png\">\n<link
65
+ href=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/apple-touch-icon-iphone4-precomposed.png\"
66
+ rel=\"apple-touch-icon-precomposed\" sizes=\"114x114\" type=\"image/png\">\n<link
67
+ href=\"http://www.kickstarter.com/services/oembed?url=http%3A%2F%2Fwww.kickstarter.com%2Fprojects%2F1397300529%2Frailsapp\"
68
+ rel=\"alternate\" title=\"rails.app Script Tag oEmbed\" type=\"application/json+oembed\">\n<link
69
+ rel=\"alternate\" type=\"application/atom+xml\" title=\"rails.app : Kickstarter\"
70
+ href=\"http://www.kickstarter.com/projects/1397300529/railsapp/posts.atom\"
71
+ />\n<meta name=\"description\" content=\"Yehuda Katz is raising funds for
72
+ rails.app on Kickstarter! \n\n Let's make Rails on OS X easy again!\n\n&quot;Install
73
+ this .app. Good job, you now have a working Rails install!&quot;\"/>\n<meta
74
+ property=\"fb:app_id\" content=\"69103156693\"/>\n<meta property=\"og:type\"
75
+ content=\"kickstarter:project\"/>\n<meta property=\"kickstarter:location:longitude\"
76
+ content=\"-122.419\"/>\n<meta property=\"og:image\" content=\"http://s3.amazonaws.com/ksr/projects/82738/photo-full.jpg?1331014996\"/>\n<meta
77
+ property=\"og:site_name\" content=\"Kickstarter\"/>\n<meta name=\"title\"
78
+ content=\"Kickstarter &gt;&gt; rails.app by Yehuda Katz\"/>\n<meta property=\"kickstarter:location:latitude\"
79
+ content=\"37.7749\"/>\n<meta property=\"og:title\" content=\"rails.app\"/>\n<meta
80
+ property=\"og:description\" content=\"Let's make Rails on OS X easy again!\n\n&quot;Install
81
+ this .app. Good job, you now have a working Rails install!&quot;\"/>\n<meta
82
+ property=\"og:url\" content=\"http://www.kickstarter.com/projects/1397300529/railsapp\"/>\n<meta
83
+ name=\"csrf-param\" content=\"authenticity_token\"/>\n<meta name=\"csrf-token\"
84
+ content=\"KJuukW4EhKlmvrd0iZJV9uoUK4whIn+JbucbwFjH1Ac=\"/>\n<link href=\"http://kck.st/HfUVql\"
85
+ rel=\"shorturl\">\n<link href=\"http://www.kickstarter.com/projects/1397300529/railsapp\"
86
+ rel=\"canonical\">\n<link href=\"http://s3.amazonaws.com/ksr/projects/82738/photo-med.jpg?1331014996\"
87
+ rel=\"image_src\">\n\n<script>\n //<![CDATA[\n var _sf_startpt=(new Date()).getTime();\n
88
+ \ docElement = this.document.documentElement;\n docElement.className=docElement.className.replace(/\\bno-js\\b/,'')
89
+ + 'js';\n //]]>\n</script>\n<script>\n //<![CDATA[\n function timeRemaining(epochTime){\n
90
+ \ \n var diff = epochTime - ((new Date()).getTime() / 1000);\n var
91
+ num_unit = (diff < 60 && [Math.max(diff, 0), 'seconds']) ||\n ((diff/=60)
92
+ < 60 && [diff, 'minutes']) ||\n ((diff/=60) < 72 && [diff, 'hours'])
93
+ ||\n [diff/=24, 'days'];\n \n // Round down\n num_unit[0]
94
+ = Math.floor(num_unit[0]);\n // Singularize unit\n if (num_unit[0]
95
+ == 1) { num_unit[1] = num_unit[1].replace(/s$/,\"\"); }\n \n return
96
+ num_unit;\n };\n //]]>\n</script>\n</head>\n\n<body class=\"project projects\"
97
+ id=\"projects_show\">\n<div class=\"jGrowl center\" id=\"growl_section\"></div>\n<div
98
+ id=\"learn-more-wrap\">\n<div class=\"container\" id=\"learn-more\">\n<p>\n<span
99
+ class=\"icon-whaaat\"></span>\n<strong>What is Kickstarter?</strong>\nWe’re
100
+ the world's largest funding platform for creative projects.\n<a href=\"#\"
101
+ class=\"link_to_learn-more-dialog\">Learn more!</a>\n</p>\n</div>\n</div>\n<div
102
+ id=\"header-wrap\">\n<div class=\"container\" id=\"header\">\n<h1 id=\"logo\"><a
103
+ href=\"/\"><span>Kickstarter</span></a></h1>\n<ul id=\"menu-main\">\n<li id=\"menu-main-discover\"><a
104
+ href=\"/discover\"><strong>Discover</strong> <span>great projects</span></a></li>\n<li
105
+ id=\"menu-main-fund\"><a href=\"/start\"><strong>Start</strong> <span>your
106
+ project</span></a></li>\n</ul>\n<form accept-charset=\"UTF-8\" action=\"/projects/search\"
107
+ class=\"search\" method=\"get\"><div style=\"margin:0;padding:0;display:inline\"><input
108
+ name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /></div>\n<div class=\"field
109
+ search\">\n<span class=\"icon-search\"></span>\n<span class=\"icon-search-clear\"></span>\n<input
110
+ class=\"input-search header text\" data-tracker-name=\"Header Live Search\"
111
+ id=\"term\" name=\"term\" type=\"text\" />\n<span class=\"icon-search-nipple\"></span>\n</div>\n</form>\n\n<ul
112
+ id=\"menu-sub\">\n<li id=\"menu-sub-blog\"><a href=\"/blog\">Blog</a></li>\n<li
113
+ id=\"menu-sub-help\"><a href=\"/help\">Help</a></li>\n<li><a href=\"https://www.kickstarter.com/signup\">Sign
114
+ up</a></li>\n<li><a href=\"https://www.kickstarter.com/login\">Log in</a></li>\n</ul>\n</div>\n</div>\n<div
115
+ id=\"search_results-wrap\">\n<div id=\"search_results-shadow\">\n<div id=\"search_results-inner_wrap\">\n<div
116
+ class=\"container\" id=\"search_results\">\n<a class=\"close\"><span class=\"icon-x\"></span>\nClose</a>\n<h2
117
+ class=\"header\"></h2>\n<div id=\"search_results_panel\"></div>\n<p class=\"footer\"></p>\n<a
118
+ class=\"prev arrow\">\n<span class=\"icon-search-left\"></span>\n<strong>Previous</strong>\n</a>\n<a
119
+ class=\"next arrow\">\n<span class=\"icon-search-right\"></span>\n<strong>Next</strong>\n</a>\n</div>\n</div>\n</div>\n</div>\n\n\n\n\n\n<div
120
+ id=\"running-board-wrap\">\n<div class=\"container\" id=\"running-board\">\n<div
121
+ id=\"project-header\">\n<div class=\"NS-project_-running_board\">\n<div id=\"headrow\">\n<h1
122
+ id=\"name\"><a href=\"/projects/1397300529/railsapp\">rails.app</a></h1>\n<p>\n<span
123
+ data-project-category=\"Technology\" id=\"project_category\">\nAn\n<a href=\"/discover/categories/Open%20Software?ref=project\">Open
124
+ Software</a>\n</span>\nproject\nin\n<a href=\"/discover/cities/san-francisco-ca?ref=project\">San
125
+ Francisco, CA</a>\nby\n<a href=\"/profile/1397300529\" id=\"byline\">Yehuda
126
+ Katz</a>\n·\n<a href=\"/projects/1397300529/railsapp/messages/new?message[to]=1397300529\"
127
+ class=\"send-message remote_modal_dialog\" data-modal-title=\"Send a Message
128
+ to Yehuda Katz\">send message</a>\n</p>\n</div>\n\n<ul id=\"widgets\">\n<li
129
+ class=\"ajax-container\" id=\"following-widget\">\n<div id=\"follow-tip\">\n<p>Don't
130
+ want to forget? We'll remind you by email 48 hours before funding ends.</p>\n<span
131
+ class=\"nipple\"></span>\n</div>\n<div id=\"follow\">\n<a href=\"/projects/1397300529/railsapp/follow\"
132
+ class=\"button-remind-me\" data-ksrjson=\"true\">Remind Me</a>\n</div>\n\n</li>\n</ul>\n<ul
133
+ class=\"menu-tabs\" id=\"running-board-nav\">\n<li>\n<a href=\"/projects/1397300529/railsapp\"
134
+ class=\"current\" id=\"home\">Project Home</a>\n</li>\n<li>\n<a href=\"/projects/1397300529/railsapp/posts\"
135
+ id=\"updates\">Updates <span class='count'>0</span></a>\n</li>\n<li>\n<a href=\"/projects/1397300529/railsapp/backers\"
136
+ id=\"backers\">Backers <span class='count'>147</span></a>\n</li>\n<li>\n<a
137
+ href=\"/projects/1397300529/railsapp/comments\" id=\"comments\">Comments <span
138
+ class='count'>3</span></a>\n</li>\n</ul>\n</div>\n\n</div>\n</div>\n</div>\n<div
139
+ id=\"content-wrap\">\n<div class=\"container\" id=\"content\">\n\n<div class=\"NS-projects-content\">\n<div
140
+ id=\"leftcol\">\n\n<div id=\"video-section\">\n<img alt=\"Photo-full\" src=\"http://s3.amazonaws.com/ksr/projects/82738/photo-full.jpg?1331014996\"
141
+ />\n</div>\n<div class=\"share-box-wrap\">\n<table class=\"share-box\">\n<tbody>\n<tr>\n<td
142
+ class=\"facebook first\">\n<fb:like data-tracker-name=\"Facebook\" font=\"lucida
143
+ grande\" href=\"http://www.kickstarter.com/projects/1397300529/railsapp\"
144
+ show_faces=\"false\" width=\"251\"></fb:like>\n</td>\n<td class=\"twitter\">\n<a
145
+ class=\"twitter-share-button\" data-count=\"none\" data-tracker-name=\"Twitter\"
146
+ data-url=\"http://kck.st/HfUVql\" data-via=\"kickstarter\" href=\"http://twitter.com/share\"></a>\n</td>\n<td
147
+ class=\"embed\">\n<a href=\"/projects/1397300529/railsapp/widget\" class=\"button-action
148
+ remote_modal_dialog\" data-modal-title=\"Embed a widget on your site\" data-tracker-name=\"Embed\"><span
149
+ class='icon-embed'></span>Embed</a>\n</td>\n<td class=\"short-link\">\n<input
150
+ class=\"text\" id=\"share_a_link\" name=\"share_a_link\" type=\"text\" value=\"http://kck.st/HfUVql\"
151
+ />\n<div class=\"copy_button\">\n<a href=\"\" class=\"copy-button zeroclipboard\"
152
+ data-text=\"http://kck.st/HfUVql\" data-tracker-name=\"Copy Link\">Copy</a>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n\n<div
153
+ data-project-state=\"live\" id=\"about\">\n<h3 class=\"dotty\">About this
154
+ project<div class=\"clear\"></div></h3><p><b>Let's make Rails on OS X easy
155
+ again!</b></p><p>Getting started with Rails on OS X has gotten hard. When
156
+ I started working with Rails in 2005, a beginner could get up and running
157
+ by downloading and running Locomotive. Locomotive made good on the implicit
158
+ promise of the original <a href=\"http://media.rubyonrails.org/video/rails-0-5.mov\"
159
+ target=\"_blank\">Get Excited screencast</a>: within minutes, you too can
160
+ feel the power of Ruby on Rails.</p><p>By the time I became a member of the
161
+ Rails core team and began work on Rails 3, Locomotive was abandonware. Since
162
+ OS X shipped with Ruby 1.8, it seemed like a simple `gem install` would do
163
+ the trick. And for many people, it did.</p><p>Since then, the Ruby ecosystem
164
+ has become increasingly sophisticated, making tools like bundler and rvm (or
165
+ rbenv, if that's your thing) a part of the standard workflow. And as those
166
+ tools increasingly became part of the toolchain for experienced developers,
167
+ we lost track of the complexity of setting up the standard Ruby toolchain.</p><p>Even
168
+ more frustrating, every piece of the toolchain has multiple options, meaning
169
+ that new developers are faced with needing to choose between rvm and rbenv,
170
+ Ruby 1.8 and Ruby 1.9, etc.</p><p>For experienced developers, these hurdles
171
+ may not seem particularly large, but they frequently chase away enthusiastic
172
+ newcomers at exactly the wrong time.</p><p><b>Enough is enough. </b>We need
173
+ a way to get up and running with Rails that is as conventional and pleasant
174
+ as Rails itself.</p><p><b>I have a track record of delivering OSS projects.
175
+ </b>For the past five years, I have worked on a number of popular open source
176
+ projects. I am probably most well-known for my work on Rails following its
177
+ merge with Merb, where I was the maintainer.</p><p>My goals for Rails 3 were
178
+ to bring Merb's ethic of modularity and extensibility to Rails, and Rails
179
+ 3 shipped with a stable plugin API that has paved the way for a richer extension
180
+ ecosystem. Jose Valim's book, <a href=\"http://pragprog.com/book/jvrails/crafting-rails-applications\"
181
+ target=\"_blank\">Crafting Rails Applications</a>, illustrates the power of
182
+ many of these extensions.</p><p>When I began work on Rails 3, the Rails ecosystem
183
+ desperately needed a stable foundation for long-term extensions. Today, the
184
+ Rails ecosystem desperately needs to get back to basics and make the experience
185
+ of starting fresh exciting again.</p><p>I have the track record and skills
186
+ to deliver a polished, maintainable solution that can become part of the Rails
187
+ project. Please help me get this done.</p><h1>Deliverables</h1><p>Many of
188
+ the necessary components for rails.app already exist in some form. <b>I do
189
+ not want to duplicate existing efforts</b>, where those efforts already solve
190
+ some part of the larger problem. I will deliver a project that lives in the
191
+ `rails` organization on GitHub, can be maintained by the Rails team and shipped
192
+ as part of the official releases.</p><p>My plan is to deliver a `.app` that
193
+ can be downloaded and dragged to the user's `/Applications` folder. At first,
194
+ the application will have two facilities:</p><ul>\n<li>Install Rails into
195
+ the system: This will install a working copy of Ruby, Rubygems, Rails and
196
+ all necessary gems into the user's system, available from the Terminal. It
197
+ may also install rvm and other common system tools, depending on the feedback
198
+ I get from the community as I develop this project.</li>\n<li>Open a Terminal
199
+ with a working Rails environment: This will leave all necessary resources
200
+ in the `.app` file or `Application Support`, but open a terminal window with
201
+ the `$PATH` and other variables set up.</li>\n</ul><p>The second option will
202
+ be the preferred option for new users, as it will be a more controlled environment
203
+ with fewer opportunities for something to go wrong. This will not be a toy
204
+ Ruby. It will be a full-fledged Ruby environment running in an isolated sandbox. <b>My
205
+ goal is for this mode to be something I personally would use</b>.</p><p>Over
206
+ time, I imagine that the community would add additional features, such as
207
+ the ability to start and stop the server, generate files, run migrations,
208
+ etc. but these are not part of the initial release goals.</p><p>The finished
209
+ project will also include several facilities to help with long-term maintenance:</p><ul>\n<li>It
210
+ will prompt the user to accept patch-level updates to Ruby or Rails without
211
+ requiring a new download of the entire package.</li>\n<li>Each `.app` will
212
+ be a self-contained environment for a given version of Ruby and Rails, so
213
+ multiple copies can live side-by-side for users who want to work with, for
214
+ example, Rails 3.1 and Rails 3.2 for different projects.</li>\n<li>The release
215
+ of a new version of the `.app` will be fully scripted, working off of release
216
+ tags of the Rails repository. At the very *most* a single rake task will build
217
+ and deploy new versions and make those versions available to the `.app`'s
218
+ updater.</li>\n<li>It will be easy to build a nightly build server for people
219
+ who want to live on the edge.</li>\n</ul><p>If time permits, I also would
220
+ like the framework for building this self-contained `.app` to be useful for
221
+ other projects (such as Compass/Sass) that have a desire to ship self-contained
222
+ environments for working with Ruby-based tools.</p>\n</div>\n<div class=\"NS-projects-faqs\"
223
+ id=\"project-faqs\">\n<h3 class=\"dotty hidden\">\nFAQ\n</h3>\n<ul class=\"faqs\">\n\n</ul>\n<div
224
+ class=\"faq-ask-box\">\n<a href=\"/projects/1397300529/railsapp/messages/new?message[to]=1397300529&amp;mode=FAQ\"
225
+ class=\"remote_modal_dialog button-neutral\" data-modal-title=\"Ask a question
226
+ about rails.app\">Ask a question</a>\n<p>\n<strong>Have a question?</strong>\nIf
227
+ the info above doesn't help, you can ask the project creator directly.\n</p>\n</div>\n</div>\n\n<div
228
+ id=\"report-issue-wrap\">\n<a href=\"/projects/1397300529/railsapp/report/new\"
229
+ class=\"remote_modal_dialog\" data-modal-title=\"Report this project to Kickstarter\"
230
+ id=\"report-issue-link\">Report this project to Kickstarter</a>\n</div>\n</div>\n<div
231
+ class=\"NS-projects-rightcol\" id=\"rightcol\">\n<div class=\"NS-projects-ecom\"
232
+ id=\"moneyraised\">\n<h5>\n<div class=\"num\">147</div>\nBackers\n</h5>\n<h5>\n<div
233
+ class=\"num\">$4,580</div>\npledged of $25,000 goal\n</h5>\n<h5 class=\"ksr_page_timer\"
234
+ data-end_time=\"Sat, 12 May 2012 16:53:15 -0400\">\n<div class=\"num\">&nbsp;</div>\n<span
235
+ class=\"text\">&nbsp;</span>\n</h5>\n<div id=\"banner\">\nThis project will
236
+ only be funded if at least $25,000 is pledged by Saturday May 12, 4:53pm
237
+ EDT.\n</div>\n<div id=\"pledge-wrap\">\n<a href=\"/projects/1397300529/railsapp/pledge/new?clicked_reward=false&amp;logged_in=false&amp;p=0&amp;v=n\"
238
+ class=\"button roundsmall\" id=\"button-back-this-proj\" title=\"Back This
239
+ Project\">Back This Project <small>$1 minimum pledge</small></a>\n</div>\n</div>\n\n<div
240
+ class=\"NS-projects-rightcol-rewards clickable\" id=\"what-you-get\">\n<div
241
+ class=\"NS-projects-reward clickable\">\n<h3>\n<a href=\"/projects/1397300529/railsapp/pledge/new?backing[amount]=10.0&amp;backing[backer_reward_id]=477812&amp;clicked_reward=true&amp;logged_in=false\">Pledge
242
+ $10 or more</a>\n<span>Pledge $10 or more</span>\n</h3>\n<div class=\"backers-limits\">\n<span
243
+ class=\"icon-backer-tag\"></span>\n<span class=\"num-backers\">\n29 Backers\n</span>\n</div>\n<div
244
+ class=\"desc\">\n<p>Receive a handwritten thank you for sponsoring this project.</p>\n</div>\n<div
245
+ class=\"delivery-date\">\n<strong>Estimated Delivery:</strong>\nJun 2012\n</div>\n</div>\n<div
246
+ class=\"NS-projects-reward clickable\">\n<h3>\n<a href=\"/projects/1397300529/railsapp/pledge/new?backing[amount]=25.0&amp;backing[backer_reward_id]=477813&amp;clicked_reward=true&amp;logged_in=false\">Pledge
247
+ $25 or more</a>\n<span>Pledge $25 or more</span>\n</h3>\n<div class=\"backers-limits\">\n<span
248
+ class=\"icon-backer-tag\"></span>\n<span class=\"num-backers\">\n61 Backers\n</span>\n</div>\n<div
249
+ class=\"desc\">\n<p>The previous rewards, plus receive a first-edition backers-only
250
+ sticker so you can show your support. My laptop is graced with an &quot;I'm
251
+ committed&quot; sticker that the Rubinius project gave me for my early contributions--this
252
+ is your chance to spruce up any of your belongings in desperate need of a
253
+ stickering.</p>\n</div>\n<div class=\"delivery-date\">\n<strong>Estimated
254
+ Delivery:</strong>\nJul 2012\n</div>\n</div>\n<div class=\"NS-projects-reward
255
+ clickable\">\n<h3>\n<a href=\"/projects/1397300529/railsapp/pledge/new?backing[amount]=100.0&amp;backing[backer_reward_id]=477814&amp;clicked_reward=true&amp;logged_in=false\">Pledge
256
+ $100 or more</a>\n<span>Pledge $100 or more</span>\n</h3>\n<div class=\"backers-limits\">\n<span
257
+ class=\"icon-backer-tag\"></span>\n<span class=\"num-backers\">\n21 Backers\n</span>\n</div>\n<div
258
+ class=\"desc\">\n<p>The previous rewards, plus access to the internal list
259
+ for the project, where I'll be soliciting feedback about how to nail this.
260
+ Great open source projects rarely come from the ideas of just one person,
261
+ and your input will guarantee that Rails 4 is as great for beginners as it
262
+ is for experienced developers.</p>\n</div>\n<div class=\"delivery-date\">\n<strong>Estimated
263
+ Delivery:</strong>\nMay 2012\n</div>\n</div>\n<div class=\"NS-projects-reward
264
+ clickable\">\n<h3>\n<a href=\"/projects/1397300529/railsapp/pledge/new?backing[amount]=1000.0&amp;backing[backer_reward_id]=477815&amp;clicked_reward=true&amp;logged_in=false\">Pledge
265
+ $1,000 or more</a>\n<span>Pledge $1,000 or more</span>\n</h3>\n<div class=\"backers-limits\">\n<span
266
+ class=\"icon-backer-tag\"></span>\n<span class=\"num-backers\">\n0 Backers\n</span>\n<span
267
+ class=\"limited\">\n&bull; Limited Reward\n(10 of 10 remaining)\n</span>\n</div>\n<div
268
+ class=\"desc\">\n<p>The previous rewards, plus recognition on the project's
269
+ website as a backer. If the price is a bit too steep personally, this is a
270
+ good opportunity to ask your company to contribute to a good cause.</p>\n</div>\n<div
271
+ class=\"delivery-date\">\n<strong>Estimated Delivery:</strong>\nJul 2012\n</div>\n</div>\n<div
272
+ class=\"NS-projects-reward clickable\">\n<h3>\n<a href=\"/projects/1397300529/railsapp/pledge/new?backing[amount]=10000.0&amp;backing[backer_reward_id]=550490&amp;clicked_reward=true&amp;logged_in=false\">Pledge
273
+ $10,000 or more</a>\n<span>Pledge $10,000 or more</span>\n</h3>\n<div class=\"backers-limits\">\n<span
274
+ class=\"icon-backer-tag\"></span>\n<span class=\"num-backers\">\n0 Backers\n</span>\n<span
275
+ class=\"limited\">\n&bull; Limited Reward\n(2 of 2 remaining)\n</span>\n</div>\n<div
276
+ class=\"desc\">\n<p>The previous rewards, plus recognition on the project's
277
+ website as a sponsor. This recognition will appear above the fold on the front
278
+ page for at least one year. If you or your company is building a product that
279
+ appeals to new developers, this is a great way to get some visibility, and
280
+ give back to the community :D\n\nPing me. Let's talk about how we can both
281
+ get the most out of this.</p>\n</div>\n<div class=\"delivery-date\">\n<strong>Estimated
282
+ Delivery:</strong>\nJul 2012\n</div>\n</div>\n\n</div>\n\n<div class=\"NS-projects-rightcol-projectby\"
283
+ id=\"project-by\">\n<h3 class=\"dotty\">Project By<div class=\"clear\"></div></h3><div
284
+ id=\"avatar\">\n<a href=\"/profile/1397300529\"><img alt=\"Fb_profile_picture.large\"
285
+ class=\"avatar-large\" height=\"220\" src=\"http://s3.amazonaws.com/ksr/avatars/441663/fb_profile_picture.large.jpg?1301941659\"
286
+ width=\"220\" /></a>\n</div>\n<div id=\"creator-details\">\n<h3><a href=\"/profile/1397300529\">Yehuda
287
+ Katz</a></h3>\n<p class=\"last-login\">\nLast Login\n03/28/12\n</p>\n<ul>\n<li
288
+ class=\"location\">\n<a href=\"/discover/cities/san-francisco-ca\"><span class='icon'></span>San
289
+ Francisco, CA</a>\n</li>\n<li class=\"backed\">\n<a href=\"/profiles/1397300529/projects/backed\"
290
+ class=\"more-button remote_modal_dialog\" data-modal-title=\"Projects backed
291
+ by Yehuda Katz\"><span class='icon'></span>Backed 2 projects</a>\n</li>\n<li
292
+ class=\"contactme\">\n<a href=\"/projects/1397300529/railsapp/messages/new?message[to]=1397300529\"
293
+ class=\"remote_modal_dialog\" data-modal-title=\"Send A Message to Yehuda
294
+ Katz\"><span class='icon'></span>Send Message</a>\n</li>\n</ul>\n</div>\n<div
295
+ id=\"facebook-connect\">\n<div class=\"icon\"></div>\n<p>Connected\nas\n<a
296
+ href=\"http://facebook.com/16200017\" class=\"popup\" target=\"_blank\">Yehuda
297
+ Katz</a>\n(400&nbsp;friends)\n</p>\n</div>\n<div id=\"biography\">\n<p>I have
298
+ a history of working on hard open source projects and delivering on them.</p>\n\n<p>Since
299
+ 2008, I worked on the Merb project, helped lead the Rails 3 effort, and am
300
+ currently bringing convention over configuration to the browser with Ember.js.</p>\n</div>\n<ol
301
+ id=\"sites\">\n<li>\n<a href=\"http://www.yehudakatz.com\" class=\"popup\"
302
+ rel=\"nofollow\" target=\"_blank\">yehudakatz.com</a>\n</li>\n<li>\n<a href=\"http://github.com/wycats\"
303
+ class=\"popup\" rel=\"nofollow\" target=\"_blank\">github.com</a>\n</li>\n<li>\n<a
304
+ href=\"http://twitter.com/wycats\" class=\"popup\" rel=\"nofollow\" target=\"_blank\">twitter.com</a>\n</li>\n</ol>\n</div>\n\n</div>\n\n</div>\n\n\n</div>\n</div>\n<div
305
+ id=\"project_bar\">\n<div class=\"this_project_id\" style=\"display: none;\">82738</div>\n<div
306
+ class=\"container\">\n<img alt=\"Project_bar_shadow\" class=\"shadow\" src=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/images/projects/project_bar_shadow.png\"
307
+ />\n<div class=\"window\">\n<ol class=\"projects\">\n<li class=\"page\">\n<ol></ol>\n</li>\n</ol>\n</div>\n<a
308
+ href=\"#\" class=\"prev arrow enabled\"><div class=\"icon-project-bar-left\"></div>\n</a><a
309
+ href=\"#\" class=\"next arrow enabled\"><div class=\"icon-project-bar-right\"></div>\n</a></div>\n</div>\n\n\n\n\n<div
310
+ id=\"mega-footer-wrap\">\n<div id=\"mega-footer-shadow\">\n<div class=\"container\"
311
+ id=\"mega-footer\">\n<div id=\"mega-discover\">\n<h5>Browse Categories</h5>\n<ul
312
+ class=\"list-footer-categories list-0\">\n<li><a href=\"/discover/categories/art?ref=footer\">Art</a></li>\n<li><a
313
+ href=\"/discover/categories/comics?ref=footer\">Comics</a></li>\n<li><a href=\"/discover/categories/dance?ref=footer\">Dance</a></li>\n<li><a
314
+ href=\"/discover/categories/design?ref=footer\">Design</a></li>\n<li><a href=\"/discover/categories/fashion?ref=footer\">Fashion</a></li>\n<li><a
315
+ href=\"/discover/categories/film%20&amp;%20video?ref=footer\">Film &amp; Video</a></li>\n<li><a
316
+ href=\"/discover/categories/food?ref=footer\">Food</a></li>\n</ul>\n<ul class=\"list-footer-categories
317
+ list-1\">\n<li><a href=\"/discover/categories/games?ref=footer\">Games</a></li>\n<li><a
318
+ href=\"/discover/categories/music?ref=footer\">Music</a></li>\n<li><a href=\"/discover/categories/photography?ref=footer\">Photography</a></li>\n<li><a
319
+ href=\"/discover/categories/publishing?ref=footer\">Publishing</a></li>\n<li><a
320
+ href=\"/discover/categories/technology?ref=footer\">Technology</a></li>\n<li><a
321
+ href=\"/discover/categories/theater?ref=footer\">Theater</a></li>\n</ul>\n</div>\n<div
322
+ id=\"mega-join-like\">\n<form accept-charset=\"UTF-8\" action=\"/newsletters/signup\"
323
+ class=\"overlabels\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input
324
+ name=\"utf8\" type=\"hidden\" value=\"&#x2713;\" /><input name=\"authenticity_token\"
325
+ type=\"hidden\" value=\"KJuukW4EhKlmvrd0iZJV9uoUK4whIn+JbucbwFjH1Ac=\" /></div>\n<h5>Kickstarter's
326
+ weekly newsletter</h5>\n<p>Get awesome projects delivered to your inbox each
327
+ week.</p>\n<textarea class=\"hide textarea\" id=\"comment\" name=\"comment\"></textarea>\n<div
328
+ class=\"field newsletter\">\n<label class=\"overlabel overlabel-newsletter\">Your
329
+ email address...</label>\n<input class=\"text\" id=\"email\" name=\"email\"
330
+ type=\"text\" />\n</div>\n<input class=\"button-positive submit\" id=\"user_submit\"
331
+ name=\"commit\" type=\"submit\" value=\"Join newsletter\" />\n</form>\n\n<h5>Kickstarter
332
+ on Facebook</h5>\n<fb:like href=\"http://facebook.com/kickstarter\" show_faces=\"true\"
333
+ width=\"330\"></fb:like>\n</div>\n<div id=\"mega-connect\">\n<h5>Connect with
334
+ Kickstarter</h5>\n<ul id=\"list-footer-connect\">\n<li><a href=\"http://twitter.com/kickstarter\"
335
+ id=\"footer-twitter\"><span class='icon-footer-twitter'></span>Follow on Twitter</a></li>\n<li><a
336
+ href=\"/blog\" id=\"footer-blog\"><span class='icon-footer-blog'></span>Read
337
+ our blog</a></li>\n<li><a href=\"/team?ref=footer\" id=\"footer-team\"><span
338
+ class='icon-footer-team'></span>Meet the team</a></li>\n<li><a href=\"/jobs?ref=footer\"
339
+ id=\"footer-jobs\"><span class='icon-footer-jobs'></span>Work with us</a></li>\n</ul>\n<span
340
+ class=\"scissors icon-scissors-1\"></span>\n</div>\n</div>\n</div>\n</div>\n<div
341
+ id=\"footer-wrap\">\n<div class=\"container\" id=\"footer\">\n<div id=\"etc\">\n<ul>\n<li><a
342
+ href=\"/help?ref=footer\">Help</a></li>\n<li><a href=\"/help/guidelines?ref=footer\">Guidelines</a></li>\n<li><a
343
+ href=\"/terms-of-use?ref=footer\">Terms of Use</a></li>\n<li><a href=\"/privacy?ref=footer\">Privacy
344
+ Policy</a></li>\n<li class=\"last\"><a href=\"http://kickstarter.zendesk.com/home\"
345
+ id=\"\" onclick=\"Zenbox.render(); return false;\">Contact</a></li>\n</ul>\n</div>\n<div
346
+ id=\"legal\">\n&copy;\n2012\nKickstarter, Inc.\n</div>\n</div>\n</div>\n\n<script>\n
347
+ \ //<![CDATA[\n var gaJsHost = ((\"https:\" == document.location.protocol)
348
+ ? \"https://ssl.\" : \"http://www.\");\n document.write(unescape(\"%3Cscript
349
+ src='\" + gaJsHost + \"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E\"));\n
350
+ \ var analytics_vars = { google_analytics_id : \"UA-7621056-1\", logged_in
351
+ : \"false\", verifying_backing : \"false\" }\n //]]>\n</script>\n\n\n<script>\n
352
+ \ //<![CDATA[\n _qoptions={qacct:\"p-34IbSpw2K94Sg\"};\n //]]>\n</script>\n<script
353
+ src=\"http://edge.quantserve.com/quant.js\" type=\"text/javascript\"></script>\n<noscript><img
354
+ alt=\"Quantcast\" border=\"0\" height=\"1\" src=\"http://pixel.quantserve.com/pixel/p-34IbSpw2K94Sg.gif\"
355
+ style=\"display:none\" width=\"1\" /></noscript>\n\n<script>\n //<![CDATA[\n
356
+ \ var _sf_async_config={uid:5536,domain:\"kickstarter.com\"};\n (function(){\n
357
+ \ function loadChartbeat() {\n window._sf_endpt=(new Date()).getTime();\n
358
+ \ var e = document.createElement('script');\n e.setAttribute('language',
359
+ 'javascript');\n e.setAttribute('type', 'text/javascript');\n e.setAttribute('src',\n
360
+ \ ((\"https:\" == document.location.protocol) ? \"https://a248.e.akamai.net/chartbeat.download.akamai.com/102508/\"
361
+ : \"http://static.chartbeat.com/\") +\n \"js/chartbeat.js\");\n
362
+ \ document.body.appendChild(e);\n }\n var oldonload = window.onload;\n
363
+ \ window.onload = (typeof window.onload != 'function') ?\n loadChartbeat
364
+ : function() { oldonload(); loadChartbeat(); };\n })();\n //]]>\n</script>\n\n<div
365
+ class=\"modal_dialog\" id=\"learn-more-dialog\" style=\"display: none;\">\n<div
366
+ class=\"modal_dialog_ie6_background\"></div>\n<div class=\"modal_dialog_outer\">\n<div
367
+ class=\"modal_dialog_sizer\">\n<div class=\"modal_dialog_inner\">\n<div class=\"modal_dialog_content\">\n<div
368
+ class=\"modal_dialog_head\"><h4><span>What is Kickstarter?</span></h4><a class=\"modal_dialog_close\"
369
+ href=\"#\"><span class=\"icon-x\">Close</span></a></div>\n<div class=\"modal_dialog_body\">\n<div
370
+ id=\"learn-more\">\n<p><strong>Kickstarter is the world's largest funding
371
+ platform for creative projects.</strong> Every week, tens of thousands of
372
+ amazing people pledge millions of dollars to projects from the worlds of <span
373
+ class='category-1'>music</span>, <span class='category-2'>film</span>, <span
374
+ class='category-3'>art</span>, <span class='category-4'>technology</span>,
375
+ <span class='category-5'>design</span>, <span class='category-6'>food</span>,
376
+ <span class='category-7'>publishing</span> and other creative fields.</p>\n<p>\n<strong>A
377
+ new form of commerce and patronage.</strong>\nThis is not about investment
378
+ or lending. Project creators keep 100% ownership and control over their work.
379
+ Instead, they offer products and experiences that are unique to each project.\n</p>\n<p>\n<strong>All
380
+ or nothing funding.</strong>\nOn Kickstarter, a project must reach its funding
381
+ goal before time runs out or no money changes hands. Why? It protects everyone
382
+ involved. Creators aren’t expected to develop their project without necessary
383
+ funds, and it allows anyone to test concepts without risk.\n</p>\n<p>\n<strong>Each
384
+ and every project is the independent creation of someone like you.</strong>\nProjects
385
+ are big and small, serious and whimsical, traditional and experimental. They’re
386
+ inspiring, entertaining and unbelievably diverse. We hope you agree... Welcome
387
+ to Kickstarter!\n</p>\n<p><a href=\"#\" class=\"modal_dialog_close\">Thanks!
388
+ All done.</a></p>\n</div>\n\n</div>\n</div>\n</div>\n<span class=\"modal_dialog_ie_hack\"></span>\n</div>\n</div>\n</div>\n\n<script
389
+ src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js\" type=\"text/javascript\"></script>\n<script>\n
390
+ \ //<![CDATA[\n (function () {\n function PageClock(settings){\n this.local_start_time
391
+ = new Date();\n this.settings = {\n cookie_name : 'request_time'\n
392
+ \ };\n for (var k in settings) {\n this.settings[k]
393
+ = settings[k];\n }\n this.get_remote_offset();\n }\n \n
394
+ \ PageClock.prototype.get_remote_offset = function () {\n // try
395
+ to get remote time from cookie\n this.cookie_value = this.read_cookie();\n
396
+ \ var remote_start_time = new Date( this.cookie_value );\n \n if
397
+ (!this.cookie_value || remote_start_time.toString() === 'Invalid Date') {\n
398
+ \ // try to get the offset from the local_offset cookie, if present\n
399
+ \ // this situation arises when the back button is clicked\n this.remote_offset
400
+ = this.read_cookie('local_offset');\n if (this.remote_offset) {\n
401
+ \ this.remote_offset = parseInt(this.remote_offset, 10);\n }\n
402
+ \ } else {\n this.remote_offset = remote_start_time - this.local_start_time;\n
403
+ \ }\n \n if (typeof this.remote_offset !== 'undefined') {\n
404
+ \ document.cookie = 'local_offset=' + this.remote_offset + '; path=/';\n
405
+ \ this.is_set = true;\n } else {\n this.is_set = false;\n
406
+ \ }\n };\n \n PageClock.prototype.time_units = [\n ['milliseconds',
407
+ 1],\n ['seconds', 1000],\n ['minutes', 1000 * 60],\n ['hours',
408
+ \ 1000 * 60 * 60],\n ['days', 1000 * 60 * 60 * 24]\n ];\n
409
+ \ \n PageClock.prototype.get_units_in_interval = function(unit_name,
410
+ time) {\n var method_name = unit_name.replace(/^\\w/, function(l) {\n
411
+ \ return 'get' + l.toUpperCase();\n });\n return time[method_name]();\n
412
+ \ };\n \n PageClock.prototype.milliseconds_in_day = function(time)
413
+ {\n if (typeof time === 'undefined') {\n time = new Date();\n
414
+ \ }\n var milliseconds = 0;\n for (var i=this.time_units.length
415
+ - 2; i >= 0; i--) {\n milliseconds += this.get_units_in_interval(this.time_units[i][0],
416
+ time) * this.time_units[i][1];\n }\n return milliseconds;\n
417
+ \ };\n \n PageClock.prototype.milliseconds_in_interval = function(unit_length,
418
+ time) {\n return this.milliseconds_in_day(time) % unit_length;\n };\n
419
+ \ \n PageClock.prototype.milliseconds_to_next_interval = function(unit_length,
420
+ time) {\n return unit_length - this.milliseconds_in_interval(unit_length,
421
+ time);\n };\n \n PageClock.prototype.pluralize = function(unit,
422
+ num) {\n if (num === 1) {\n unit = unit.replace(/s$/, '');\n
423
+ \ }\n return unit;\n };\n \n \n PageClock.prototype.read_cookie
424
+ = function(cookie_name){\n var\n ca = window.document.cookie.split(';'),\n
425
+ \ cookie_string = (cookie_name || this.settings.cookie_name) + '=';\n
426
+ \ for (var i=0;i < ca.length;i++) {\n var c = ca[i];\n while
427
+ (c.charAt(0)==' ') {\n c = c.substring(1,c.length);\n }\n
428
+ \ if (c.indexOf(cookie_string) == 0) {\n var encoded_string
429
+ = c.substring(cookie_string.length,c.length);\n return decodeURIComponent(encoded_string).replace(/\\+/g,
430
+ ' ');\n }\n }\n return null;\n };\n \n PageClock.prototype.destroy_cookie
431
+ = function() {\n var expires = new Date();\n expires.setTime(expires.getTime()
432
+ - 1 * 24 * 60 * 60 * 1000);\n window.document.cookie = this.settings.cookie_name
433
+ + \"=; expires=\" + expires.toGMTString() + \"; path=/\";\n };\n \n
434
+ \ PageClock.prototype.get_remote_time = function() {\n var\n time
435
+ = new Date(),\n remote_milliseconds = time.getTime() + this.remote_offset;\n
436
+ \ time = time.setTime(remote_milliseconds);\n return time;\n
437
+ \ };\n \n window.ksr_page_clock = new PageClock();\n })();\n
438
+ \ \n (function(){\n // simple_find( selector [, context_element]
439
+ )\n // selector: a string in the form [tag_name].class_name : must include
440
+ a dot-prefixed css class\n var simple_find = function(selector, context)
441
+ {\n var\n root = context || window.document.body,\n parts
442
+ = selector.split('.'),\n class_name = parts[parts.length - 1],\n
443
+ \ tag_name = (parts.length > 1 && parts[0]) ? parts[0] : '*';\n \n
444
+ \ if (window.document.getElementsByClassName) {\n return root.getElementsByClassName(class_name);\n
445
+ \ }\n \n if (root.querySelectorAll) {\n tag_name
446
+ = tag_name || '';\n return root.querySelectorAll(selector);\n }\n
447
+ \ \n // lame, fall back\n var\n much_elements = root.getElementsByTagName(tag_name),\n
448
+ \ elements = [];\n for (var i = 0, much_element; much_element
449
+ = much_elements[i]; i++) {\n if (this.hasClass(much_element, class_name))
450
+ {\n elements.push(much_element);\n }\n }\n return
451
+ elements;\n }\n \n // TODO: decouple this class from the DOM\n
452
+ \ function ProjectTimer(element, clock, options) {\n this.options
453
+ = {\n unit_base : {\n 'seconds' : 119,\n 'minutes'
454
+ : 119,\n 'hours' : 72,\n 'days' : 0\n },\n
455
+ \ end_phrase : (element.getAttribute('data-word') || 'to go'),\n count_down
456
+ : false\n };\n for (k in options) {\n this.options[k]
457
+ = options[k];\n }\n this.clock = clock;\n this.time_units
458
+ = this.clock.time_units.slice(1);\n this.element = element;\n if
459
+ (this.clock.is_set) {\n this.attach();\n }\n };\n \n
460
+ \ ProjectTimer.prototype.get_remaining_time = function() {\n var
461
+ time = this.remote_end_time - this.clock.get_remote_time();\n if (time
462
+ < 0) {\n time = 0;\n }\n return time;\n };\n \n
463
+ \ ProjectTimer.prototype.get_current_unit = function() {\n var
464
+ unit;\n for (var i=0; i < this.time_units.length; i++) {\n unit
465
+ = this.time_units[i];\n if (this.get_remaining_time() <= this.options.unit_base[unit[0]]
466
+ * unit[1]) {\n break;\n }\n }\n return unit;\n
467
+ \ };\n \n ProjectTimer.prototype.update_element = function() {\n
468
+ \ var\n unit = this.get_current_unit(),\n number_of_units
469
+ = Math.floor(this.get_remaining_time() / unit[1]);\n if (isNaN(number_of_units))
470
+ { return; }\n this.number_element.innerHTML = number_of_units;\n this.text_element.innerHTML
471
+ = this.clock.pluralize(unit[0], number_of_units) + ' ' + this.options.end_phrase;\n
472
+ \ };\n \n ProjectTimer.prototype.valid = function() {\n return
473
+ !!(this.number_element && this.text_element);\n };\n \n ProjectTimer.prototype.attach
474
+ = function() {\n function count() {\n timer.update_element();\n
475
+ \ if (timer.options.count_down && timer.get_remaining_time() > 0)
476
+ {\n var unit = timer.get_current_unit();\n this.timeout
477
+ = window.setTimeout(count, timer.clock.milliseconds_to_next_interval(unit[1]));\n
478
+ \ }\n }\n var timer = this;\n this.remote_end_time_string
479
+ = this.element.getAttribute('data-end_time');\n this.remote_end_time
480
+ = new Date(this.remote_end_time_string);\n this.number_element = simple_find('.num',
481
+ this.element)[0],\n this.text_element = simple_find('.text', this.element)[0],\n
482
+ \ this.element.ksr_page_timer = true;\n if (this.valid()) {\n
483
+ \ count();\n }\n };\n \n ProjectTimer.prototype.cancel
484
+ = function () {\n if (this.timeout) {\n clearTimeout(this.timeout);\n
485
+ \ }\n };\n \n function TimerFinder() {\n this.elements
486
+ = [];\n this.attach();\n }\n \n TimerFinder.prototype.loading
487
+ = true;\n \n TimerFinder.prototype.stop_finding = function() {\n this.attach_timers();\n
488
+ \ this.loading = false;\n \n if ( document.addEventListener
489
+ ) {\n document.removeEventListener( \"DOMContentLoaded\", this.stop_finding,
490
+ false );\n } else if ( document.attachEvent ) {\n if ( document.readyState
491
+ === \"complete\" ) {\n document.detachEvent( \"onreadystatechange\",
492
+ this.stop_finding );\n }\n }\n };\n \n TimerFinder.prototype.bind_ready
493
+ = function() {\n var\n that = this,\n stop_finding
494
+ = function () {\n that.stop_finding.call(that);\n };\n
495
+ \ \n // lifted from jQuery's .ready() method:\n // Mozilla,
496
+ Opera and webkit nightlies currently support this event\n if ( document.addEventListener
497
+ ) {\n // Use the handy event callback\n document.addEventListener(
498
+ \"DOMContentLoaded\", stop_finding, false );\n \n // A fallback
499
+ to window.onload, that will always work\n window.addEventListener(
500
+ \"load\", stop_finding, false );\n \n // If IE event model is used\n
501
+ \ } else if ( document.attachEvent ) {\n // ensure firing before
502
+ onload,\n // maybe late but safe also for iframes\n document.attachEvent(
503
+ \"onreadystatechange\", stop_finding );\n \n // A fallback to
504
+ window.onload, that will always work\n window.attachEvent( \"onload\",
505
+ stop_finding );\n }\n };\n \n TimerFinder.prototype.attach_timers
506
+ = function () {\n var elements = simple_find('div.ksr_page_timer');\n
507
+ \ for (var i=0; i < elements.length; i++) {\n if (!elements[i].ksr_page_timer)
508
+ {\n new ProjectTimer(elements[i], window.ksr_page_clock);\n this.elements.push(elements[i]);\n
509
+ \ }\n }\n };\n \n TimerFinder.prototype.attach
510
+ = function() {\n var that = this;\n function poll_for_timers()
511
+ {\n that.attach_timers();\n if (that.loading) {\n window.setTimeout(that.attach_timers,
512
+ 200);\n }\n }\n this.bind_ready();\n poll_for_timers();\n
513
+ \ };\n \n window.ProjectTimer = ProjectTimer;\n \n new
514
+ TimerFinder();\n })();\n //]]>\n</script>\n\n<script src=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/assets/jwplayer.js\"
515
+ type=\"text/javascript\"></script>\n<script src=\"http://d297h9he240fqh.cloudfront.net/cache-e1f3b9f54/assets/project_page.js\"
516
+ type=\"text/javascript\"></script>\n<style type=\"text/css\" media=\"screen,
517
+ projection\">@import url(http://asset0.zendesk.com/external/zenbox/v2.1/zenbox.css);</style><script
518
+ type=\"text/javascript\" src=\"http://asset0.zendesk.com/external/zenbox/v2.1/zenbox.js\"></script><script
519
+ type=\"text/javascript\">\n//<![CDATA[\n if (typeof(Zenbox) !== \"undefined\")
520
+ {\n Zenbox.init({\n dropboxID: \"20012797\",\n tabID:
521
+ \"support\",\n hide_tab: true,\n url: \"kickstarter.zendesk.com\"\n
522
+ \ });\n }\n\n//]]>\n</script>\n<script src=\"http://platform.twitter.com/widgets.js\"
523
+ type=\"text/javascript\"></script>\n\n\n\n<div id=\"fb-root\"></div>\n<script>\n
524
+ \ //<![CDATA[\n var channelUrl = window.location.protocol + \"//\" + window.location.host
525
+ + \"/channel.html\";\n \n window.fbAsyncInit = function() {\n FB.init({\n
526
+ \ appId: '69103156693',\n channelUrl: channelUrl,\n status:
527
+ true, // check login status\n cookie: true, // enable cookies
528
+ to allow the server to access the session\n xfbml: true, // parse
529
+ XFBML\n logging: false // turn off logging\n });\n \n $(document).trigger('fb:loaded');\n
530
+ \ \n var logout_from_fb = false;\n \n FB.Event.subscribe('auth.statusChange',
531
+ function(response) {\n if (logout_from_fb) {\n FB.logout(function()
532
+ {\n logout_from_fb = false;\n });\n } else if (response.authResponse
533
+ && true && true && true && !FB.usingButton) {\n $.get(\"http://www.kickstarter.com/fb/connect/verify?then=http%3A%2F%2Fwww.kickstarter.com%2Fprojects%2F1397300529%2Frailsapp\",
534
+ {'fbsr': response.authResponse.signedRequest}, function() {});\n }\n
535
+ \ });\n \n };\n \n \n // Load the SDK Asynchronously\n
536
+ \ (function(d){\n var js, id = 'facebook-jssdk'; if (d.getElementById(id))
537
+ {return;}\n js = d.createElement('script'); js.id = id; js.async = true;\n
538
+ \ js.src = \"//connect.facebook.net/en_US/all.js\";\n d.getElementsByTagName('head')[0].appendChild(js);\n
539
+ \ }(document));\n //]]>\n</script>\n\n\n<script type=\"text/javascript\">if
540
+ (!NREUMQ.f) { NREUMQ.f=function() {\nNREUMQ.push([\"load\",new Date().getTime()]);\nvar
541
+ e=document.createElement(\"script\");\ne.type=\"text/javascript\";e.async=true;e.src=\"https://d1ros97qkrwjf5.cloudfront.net/30/eum/rum.js\";\ndocument.body.appendChild(e);\nif(NREUMQ.a)NREUMQ.a();\n};\nNREUMQ.a=window.onload;window.onload=NREUMQ.f;\n};\nNREUMQ.push([\"nrfj\",\"beacon-1.newrelic.com\",\"b04b883ad2\",11086,\"cFteRUULX1wHFhtIEFxeVVJDFxxDCgtD\",0.0,120,new
542
+ Date().getTime(),\"\",\"\",\"\",\"\",\"\"])</script></body>\n</html>\n"
543
+ http_version: !!null
544
+ recorded_at: Wed, 28 Mar 2012 23:06:47 GMT
545
+ recorded_with: VCR 2.0.0
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
6
6
  gem.email = ["mike.d.1984@gmail.com"]
7
7
  gem.description = %q{simple and flexible html to markdown converter}
8
8
  gem.summary = %q{simple and flexible html to markdown converter}
9
- gem.homepage = ""
9
+ gem.homepage = "https://github.com/29decibel/html2markdown"
10
10
 
11
11
  gem.add_dependency 'nokogiri'
12
12
 
@@ -38,6 +38,8 @@ module HTML2Markdown
38
38
  # default parse
39
39
  case node.name.downcase
40
40
  when 'i'
41
+ when 'script'
42
+ when 'style'
41
43
  when 'li'
42
44
  result << "*#{contents}\n"
43
45
  when 'blockquote'
@@ -20,7 +20,7 @@ class HTMLPage
20
20
  end
21
21
 
22
22
  def markdown!
23
- to_markdown(contents)
23
+ @markdown = to_markdown(contents)
24
24
  end
25
25
 
26
26
  end
@@ -1,3 +1,3 @@
1
1
  module HTML2Markdown
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -4,12 +4,15 @@ require_relative '../../lib/html2markdown'
4
4
 
5
5
  describe HTMLPage do
6
6
 
7
- # it "should have url and contents property" do
8
- # url = 'http://bbs.qyer.com/viewthread.php?tid=503325&extra=page%3D1'
9
- # page = HTMLPage.new :url => url
10
- # page.contents.should_not be_nil
11
- # page.url.should == url
12
- # end
7
+ it "should fetch contents of url" do
8
+ url = 'http://www.kickstarter.com/projects/1397300529/railsapp'
9
+ VCR.use_cassette 'html_page' do
10
+ page = HTMLPage.new :url => url
11
+ page.contents.should_not be_nil
12
+ page.url.should == url
13
+ page.markdown.length.should > 0
14
+ end
15
+ end
13
16
 
14
17
  it "can convert to markdow format" do
15
18
  contents = <<-CON
@@ -72,7 +75,6 @@ NEXT!<br>
72
75
  end
73
76
  markdown = page.to_markdown page.contents
74
77
  markdown.length.should > 0
75
- puts markdown
76
78
  end
77
79
 
78
80
  it "should have markdown method" do
@@ -81,4 +83,13 @@ NEXT!<br>
81
83
  p.contents = '<strong>hehe</strong>'
82
84
  p.markdown!.should == '**hehe**'
83
85
  end
86
+
87
+ it "can have custom node parse block" do
88
+ p = HTMLPage.new :contents => '<strong>haha</strong>'
89
+ p.strong do |node,contents|
90
+ "strong text : **#{contents}**"
91
+ end
92
+ p.markdown!.should be_include('strong text')
93
+ end
94
+
84
95
  end
@@ -4,6 +4,9 @@ rescue LoadError
4
4
  puts 'Although not required, bundler is recommended for running the tests.'
5
5
  end
6
6
 
7
+ require 'vcr'
8
+
9
+ # configuration for rspec
7
10
  RSpec.configure do |config|
8
11
  config.mock_with :rspec
9
12
  config.color_enabled = true
@@ -19,4 +22,10 @@ RSpec.configure do |config|
19
22
  end
20
23
  end
21
24
 
22
- require 'html2markdown'
25
+ # configuration for vcr
26
+ VCR.configure do |c|
27
+ c.cassette_library_dir = 'fixtures/vcr_cassettes'
28
+ c.hook_into :webmock # or :fakeweb
29
+ end
30
+
31
+ require_relative '../lib/html2markdown'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html2markdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-03-28 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &2158826900 !ruby/object:Gem::Requirement
16
+ requirement: &2155739160 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2158826900
24
+ version_requirements: *2155739160
25
25
  description: simple and flexible html to markdown converter
26
26
  email:
27
27
  - mike.d.1984@gmail.com
@@ -33,15 +33,16 @@ files:
33
33
  - Gemfile
34
34
  - Rakefile
35
35
  - Readme.md
36
+ - fixtures/vcr_cassettes/html_page.yml
36
37
  - html2markdown.gemspec
37
38
  - lib/html2markdown.rb
38
39
  - lib/html2markdown/converter.rb
39
40
  - lib/html2markdown/exceptions.rb
40
41
  - lib/html2markdown/html_page.rb
41
42
  - lib/html2markdown/version.rb
42
- - spec/cases/converter_spec.rb
43
+ - spec/cases/html_page_spec.rb
43
44
  - spec/spec_helper.rb
44
- homepage: ''
45
+ homepage: https://github.com/29decibel/html2markdown
45
46
  licenses: []
46
47
  post_install_message:
47
48
  rdoc_options: []
@@ -66,5 +67,5 @@ signing_key:
66
67
  specification_version: 3
67
68
  summary: simple and flexible html to markdown converter
68
69
  test_files:
69
- - spec/cases/converter_spec.rb
70
+ - spec/cases/html_page_spec.rb
70
71
  - spec/spec_helper.rb