tumblargh 0.1.0

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.
Files changed (59) hide show
  1. data/.gitignore +2 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +15 -0
  4. data/Gemfile.lock +52 -0
  5. data/LICENSE +20 -0
  6. data/README.md +84 -0
  7. data/Rakefile +43 -0
  8. data/VERSION +1 -0
  9. data/examples/confg.ru +18 -0
  10. data/examples/middleman_config.rb +7 -0
  11. data/lib/middleman/features/tumblargh.rb +41 -0
  12. data/lib/rack/tumblargh.rb +51 -0
  13. data/lib/tumblargh.rb +60 -0
  14. data/lib/tumblargh/api.rb +60 -0
  15. data/lib/tumblargh/grammar.rb +560 -0
  16. data/lib/tumblargh/grammar.treetop +42 -0
  17. data/lib/tumblargh/node.rb +14 -0
  18. data/lib/tumblargh/node/base.rb +21 -0
  19. data/lib/tumblargh/node/block.rb +31 -0
  20. data/lib/tumblargh/node/block_end.rb +9 -0
  21. data/lib/tumblargh/node/block_start.rb +22 -0
  22. data/lib/tumblargh/node/literal.rb +9 -0
  23. data/lib/tumblargh/node/root.rb +17 -0
  24. data/lib/tumblargh/node/tag.rb +33 -0
  25. data/lib/tumblargh/parser.rb +96 -0
  26. data/lib/tumblargh/renderer.rb +316 -0
  27. data/lib/tumblargh/renderer/base.rb +64 -0
  28. data/lib/tumblargh/renderer/blocks/answer.rb +22 -0
  29. data/lib/tumblargh/renderer/blocks/audio.rb +70 -0
  30. data/lib/tumblargh/renderer/blocks/base.rb +35 -0
  31. data/lib/tumblargh/renderer/blocks/dates.rb +62 -0
  32. data/lib/tumblargh/renderer/blocks/navigation.rb +65 -0
  33. data/lib/tumblargh/renderer/blocks/notes.rb +68 -0
  34. data/lib/tumblargh/renderer/blocks/posts.rb +50 -0
  35. data/lib/tumblargh/renderer/blocks/reblogs.rb +50 -0
  36. data/lib/tumblargh/renderer/blocks/tags.rb +37 -0
  37. data/lib/tumblargh/renderer/document.rb +70 -0
  38. data/lib/tumblargh/renderer/literal.rb +9 -0
  39. data/lib/tumblargh/renderer/tag.rb +37 -0
  40. data/lib/tumblargh/resource.rb +12 -0
  41. data/lib/tumblargh/resource/base.rb +39 -0
  42. data/lib/tumblargh/resource/blog.rb +49 -0
  43. data/lib/tumblargh/resource/note.rb +8 -0
  44. data/lib/tumblargh/resource/post.rb +63 -0
  45. data/lib/tumblargh/resource/tag.rb +8 -0
  46. data/lib/tumblargh/resource/user.rb +8 -0
  47. data/spec/api_spec.rb +1 -0
  48. data/spec/fixtures/data/staff.tumblr.com-2012-05-06/posts.json +1203 -0
  49. data/spec/fixtures/themes/fluid.html +1138 -0
  50. data/spec/fixtures/themes/solstice.html +392 -0
  51. data/spec/parser_spec.rb +159 -0
  52. data/spec/renderer/blocks/posts_spec.rb +17 -0
  53. data/spec/renderer/document_spec.rb +57 -0
  54. data/spec/resource/post_spec.rb +38 -0
  55. data/spec/resource_spec.rb +23 -0
  56. data/spec/spec_helper.rb +24 -0
  57. data/spec/tumblargh_spec.rb +50 -0
  58. data/tumblargh.gemspec +120 -0
  59. metadata +237 -0
@@ -0,0 +1,392 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+
7
+ <!--
8
+ _| _|_| _| _| _|_|_|_|
9
+ _| _| _| _| _| _|
10
+ _| _|_|_|_| _|_| _|_|_|
11
+ _| _| _| _| _| _| _|
12
+ _|_|_|_| _| _| _| _| _|_|_|_|
13
+
14
+ _|_|_|_| _|_| _| _| _|
15
+ _| _| _| _| _| _| _|
16
+ _|_|_|_| _|_|_|_| _| _| _|
17
+ _| _| _| _| _| _|
18
+ _| _| _| _|_| _|_|_|_|
19
+
20
+ SOLSTICE THEME http://solsticetheme.tumblr.com
21
+ by JAKE PAUL http://jakepaul.tumblr.com
22
+
23
+ -->
24
+
25
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
26
+ <meta name="viewport" content="width=850,maximum-scale=1.0" />
27
+ <meta name="description" content="{MetaDescription}" />
28
+
29
+ <title>{Title}{block:PostSummary} &mdash; {PostSummary}{/block:PostSummary}{block:SearchPage} &mdash; Search: {SearchQuery}{/block:SearchPage}</title>
30
+ <link rel="shortcut icon" href="{Favicon}" />
31
+ <link rel="alternate" type="application/rss+xml" href="{RSS}" />
32
+
33
+ <meta name="image:Background" content="" />
34
+ <meta name="if:Show people I follow" content="1"/>
35
+ <meta name="if:Show my portrait photo" content="1"/>
36
+ <meta name="if:Show via links with reblogged posts" content="1">
37
+ <meta name="if:Use classic paging" content="0"/>
38
+ <meta name="if:Hide Disqus comment count if zero" content="0">
39
+ <meta name="text:Disqus Shortname" content="" />
40
+ <meta name="text:Google Analytics ID" content="" />
41
+
42
+ <link rel="stylesheet" type="text/css" media="screen" href="http://static.tumblr.com/pvdmavg/pTrkuzeoc/reset.css" />
43
+ <link rel="stylesheet" type="text/css" media="screen" href="http://static.tumblr.com/pvdmavg/S3Xkv0xy6/fancybox-tumblr.css" />
44
+ <link rel="stylesheet" type="text/css" media="screen" href="http://static.tumblr.com/pvdmavg/KCnldy6xv/screen.css" />
45
+ <style type="text/css">
46
+ body {
47
+ {block:IfNotBackgroundImage}
48
+ background: #14171f url(http://static.tumblr.com/pvdmavg/Pfykuzdki/h1_bg.png) repeat left top;
49
+ {/block:IfNotBackgroundImage}
50
+ {block:IfBackgroundImage}
51
+ background: #0e1112 url('{image:Background}') repeat fixed left top;
52
+ {/block:IfBackgroundImage}
53
+ }
54
+ #page_outer {
55
+ {block:IfNotBackgroundImage}
56
+ background: url(http://static.tumblr.com/pvdmavg/HHOkuzdlf/h1_bg_top.png) repeat-x left top;
57
+ {/block:IfNotBackgroundImage}
58
+ }
59
+ #header h1 {
60
+ {block:IfNotBackgroundImage}
61
+ text-shadow: #0e1112 1px 1px 1px;
62
+ -webkit-text-stroke:1px transparent;
63
+ {/block:IfNotBackgroundImage}
64
+ }
65
+ #pages {
66
+ display: none;
67
+ {block:HasPages}display: block;{/block:HasPages}
68
+ {block:AskEnabled}display: block;{/block:AskEnabled}
69
+ {block:SubmissionsEnabled}display: block;{/block:SubmissionsEnabled}
70
+ }
71
+ .notice .tag:before { content:'“'; }
72
+ .notice .tag:after { content:'”'; }
73
+ {CustomCSS}
74
+ </style>
75
+
76
+ <script type="text/javascript" src="http://static.tumblr.com/pvdmavg/k5dkuzkft/jquery-1.3.2.min.js"></script>
77
+ <script type="text/javascript" src="http://static.tumblr.com/pvdmavg/v8Vkv0xxe/jquery.fancybox-1.2.6.pack.js"></script>
78
+ <script type="text/javascript" src="http://static.tumblr.com/pvdmavg/Xbsldy6x0/solstice.js"></script>
79
+ <script type="text/javascript">
80
+ {block:IfUseClassicPaging}
81
+ ajax_loader = false;
82
+ {/block:IfUseClassicPaging}
83
+ {block:IfNotUseClassicPaging}
84
+ ajax_loader = true;
85
+ {/block:IfNotUseClassicPaging}
86
+ {block:IfDisqusShortname}
87
+ disqus_shortname = "{text:Disqus Shortname}";
88
+ disqus_iframe_css = "http://static.tumblr.com/pvdmavg/OGLl0q9ii/iframe.css";
89
+ {/block:IfDisqusShortname}
90
+ {block:IfHideDisqusCommentCountIfZero}
91
+ hide_zero = true
92
+ {/block:IfHideDisqusCommentCountIfZero}
93
+ {block:IfNotHideDisqusCommentCountIfZero}
94
+ hide_zero = false
95
+ {/block:IfNotHideDisqusCommentCountIfZero}
96
+ </script>
97
+
98
+ </head>
99
+
100
+ <body>
101
+ <div id="page_outer">
102
+ <div id="page_inner">
103
+ <div id="header">
104
+ <h1><a href="/">{Title}</a></h1>
105
+ </div>
106
+ <div id="container_outer">
107
+ <div id="container_inner">
108
+ <div id="posts_outer"{block:PermalinkPage} class="permalink"{/block:PermalinkPage}>
109
+
110
+ {block:TagPage}
111
+ <h2 class="notice">{lang:Posts tagged Tag 2}</h2>
112
+ {/block:TagPage}
113
+
114
+ {block:SearchResults}
115
+ <h2 class="notice">{lang:Search results for SearchQuery}</h2>
116
+ {/block:SearchResults}
117
+
118
+ {block:NoSearchResults}
119
+ <h2 class="notice">{lang:No results found}</h2>
120
+ {/block:NoSearchResults}
121
+
122
+ <div id="posts_inner">
123
+ <!-- posts-start -->
124
+ {block:Posts}
125
+ {block:Text}
126
+ <div class="post text">
127
+ {block:Date}
128
+ <div class="info">
129
+ <a href="{Permalink}" class="type">{lang:Text}</a>
130
+ {block:IndexPage}{block:NoteCount}<a href="{Permalink}#notes" class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}{/block:IndexPage}
131
+ </div>
132
+ {/block:Date}
133
+ {block:IndexPage}<div class="date"><span></span>{lang:Posted TimeAgo}</div>{/block:IndexPage}
134
+ <div class="content{block:Date} narrow{/block:Date}">
135
+ {block:Title}<h3 class="title">{Title}</h3>{/block:Title}
136
+ {body}
137
+ <div class="details">{block:IfShowViaLinksWithRebloggedPosts}{block:RebloggedFrom}<a href="{ReblogParentURL}" title="{ReblogParentTitle}" class="reblog">via {ReblogParentName}</a>{/block:RebloggedFrom}{/block:IfShowViaLinksWithRebloggedPosts}{block:Date}{block:IfDisqusShortname}<a href="{Permalink}#disqus_thread" class="disqus">{lang:View comments}</a>{/block:IfDisqusShortname}{/block:Date}</div>
138
+ </div>
139
+ </div>
140
+ {/block:Text}
141
+
142
+ {block:Answer}
143
+ <div class="post answer">
144
+ <div class="info">
145
+ <a href="{Permalink}" class="type">{lang:Answer}</a>
146
+ {block:IndexPage}{block:NoteCount}<a href="{Permalink}#notes" class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}{/block:IndexPage}
147
+ </div>
148
+ {block:IndexPage}<div class="date"><span></span>{lang:Posted TimeAgo}</div>{/block:IndexPage}
149
+ <div class="content">
150
+ <div class="question">{Question}</div>
151
+ <div class="asker"><img src="{AskerPortraitURL-16}" width="16" height="16" class="avatar"><span>{lang:Asker asked}</span></div>
152
+ <div class="answer">{Answer}</div>
153
+ <div class="details">{block:IfShowViaLinksWithRebloggedPosts}{block:RebloggedFrom}<a href="{ReblogParentURL}" title="{ReblogParentTitle}" class="reblog">via {ReblogParentName}</a>{/block:RebloggedFrom}{/block:IfShowViaLinksWithRebloggedPosts}{block:Date}{block:IfDisqusShortname}<a href="{Permalink}#disqus_thread" class="disqus">{lang:View comments}</a>{/block:IfDisqusShortname}{/block:Date}</div>
154
+ </div>
155
+ </div>
156
+ {/block:Answer}
157
+
158
+ {block:Photo}
159
+ <div class="post photo">
160
+ <div class="info">
161
+ <a href="{Permalink}" class="type">{lang:Photo}</a>
162
+ {block:IndexPage}{block:NoteCount}<a href="{Permalink}#notes" class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}{/block:IndexPage}
163
+ </div>
164
+ {block:IndexPage}<div class="date"><span></span>{lang:Posted TimeAgo}</div>{/block:IndexPage}
165
+ <div class="content">
166
+ <div class="image">
167
+ {LinkOpenTag}<img src="{PhotoURL-500}" alt="{PhotoAlt}">{LinkCloseTag}
168
+ {block:HighRes}<a href="{PhotoURL-HighRes}?.jpg" class="zoom">{lang:Zoom}</a>{/block:HighRes}
169
+ </div>
170
+ {block:Caption}
171
+ <div class="description">
172
+ {Caption}
173
+ </div>
174
+ {/block:Caption}
175
+ <div class="details">{block:IfShowViaLinksWithRebloggedPosts}{block:RebloggedFrom}<a href="{ReblogParentURL}" title="{ReblogParentTitle}" class="reblog">via {ReblogParentName}</a>{/block:RebloggedFrom}{/block:IfShowViaLinksWithRebloggedPosts}{block:Date}{block:IfDisqusShortname}<a href="{Permalink}#disqus_thread" class="disqus">{lang:View comments}</a>{/block:IfDisqusShortname}{/block:Date}</div>
176
+ </div>
177
+ </div>
178
+ {/block:Photo}
179
+
180
+ {block:Quote}
181
+ <div class="post quote">
182
+ <div class="info">
183
+ <a href="{Permalink}" class="type">{lang:Quote}</a>
184
+ {block:IndexPage}{block:NoteCount}<a href="{Permalink}#notes" class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}{/block:IndexPage}
185
+ </div>
186
+ {block:IndexPage}<div class="date"><span></span>{lang:Posted TimeAgo}</div>{/block:IndexPage}
187
+ <div class="content">
188
+ <div class="quoted">{Quote}</div>
189
+ {block:Source}<div class="description">{Source}</div>{/block:Source}
190
+ <div class="details">{block:IfShowViaLinksWithRebloggedPosts}{block:RebloggedFrom}<a href="{ReblogParentURL}" title="{ReblogParentTitle}" class="reblog">via {ReblogParentName}</a>{/block:RebloggedFrom}{/block:IfShowViaLinksWithRebloggedPosts}{block:Date}{block:IfDisqusShortname}<a href="{Permalink}#disqus_thread" class="disqus">{lang:View comments}</a>{/block:IfDisqusShortname}{/block:Date}</div>
191
+ </div>
192
+ </div>
193
+ {/block:Quote}
194
+
195
+ {block:Link}
196
+ <div class="post link">
197
+ <div class="info">
198
+ <a href="{Permalink}" class="type">{lang:Link}</a>
199
+ {block:IndexPage}{block:NoteCount}<a href="{Permalink}#notes" class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}{/block:IndexPage}
200
+ </div>
201
+ {block:IndexPage}<div class="date"><span></span>{lang:Posted TimeAgo}</div>{/block:IndexPage}
202
+ <div class="content">
203
+ <h3 class="title"><a href="{URL}" {Target}>{Name}</a></h3>
204
+ {block:Description}
205
+ <div class="description">
206
+ {Description}
207
+ </div>
208
+ {/block:Description}
209
+ <div class="details">{block:IfShowViaLinksWithRebloggedPosts}{block:RebloggedFrom}<a href="{ReblogParentURL}" title="{ReblogParentTitle}" class="reblog">via {ReblogParentName}</a>{/block:RebloggedFrom}{/block:IfShowViaLinksWithRebloggedPosts}{block:Date}{block:IfDisqusShortname}<a href="{Permalink}#disqus_thread" class="disqus">{lang:View comments}</a>{/block:IfDisqusShortname}{/block:Date}</div>
210
+ </div>
211
+ </div>
212
+ {/block:Link}
213
+
214
+ {block:Chat}
215
+ <div class="post chat">
216
+ <div class="info">
217
+ <a href="{Permalink}" class="type">{lang:Chat}</a>
218
+ {block:IndexPage}{block:NoteCount}<a href="{Permalink}#notes" class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}{/block:IndexPage}
219
+ </div>
220
+ {block:IndexPage}<div class="date"><span></span>{lang:Posted TimeAgo}</div>{/block:IndexPage}
221
+ <div class="content">
222
+ {block:Title}<h3 class="title">{Title}</h3>{/block:Title}
223
+ <ol class="lines">
224
+ {block:Lines}
225
+ <li class="{Alt} user_{UserNumber}">
226
+ {block:Label}<strong>{Label}</strong>{/block:Label} {Line}
227
+ </li>
228
+ {/block:Lines}
229
+ </ol>
230
+ <div class="details">{block:IfShowViaLinksWithRebloggedPosts}{block:RebloggedFrom}<a href="{ReblogParentURL}" title="{ReblogParentTitle}" class="reblog">via {ReblogParentName}</a>{/block:RebloggedFrom}{/block:IfShowViaLinksWithRebloggedPosts}{block:Date}{block:IfDisqusShortname}<a href="{Permalink}#disqus_thread" class="disqus">{lang:View comments}</a>{/block:IfDisqusShortname}{/block:Date}</div>
231
+ </div>
232
+ </div>
233
+ {/block:Chat}
234
+
235
+ {block:Audio}
236
+ <div class="post audio">
237
+ <div class="info">
238
+ <a href="{Permalink}" class="type">{lang:Audio}</a>
239
+ {block:IndexPage}{block:NoteCount}<a href="{Permalink}#notes" class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}{/block:IndexPage}
240
+ </div>
241
+ {block:IndexPage}<div class="date"><span></span>{lang:Posted TimeAgo}</div>{/block:IndexPage}
242
+ <div class="content">
243
+ {block:AlbumArt}<div class="cover"><img src="{AlbumArtURL}" width="160"></div>{/block:AlbumArt}
244
+ <div class="player_wrap{block:AlbumArt} inline{/block:AlbumArt}">
245
+ <div class="player">{AudioPlayerBlack}</div>
246
+ {block:Artist}<div class="metadata">{Artist}{block:TrackName} &ndash; {TrackName}{/block:TrackName}</div>{/block:Artist}
247
+ </div>
248
+ {block:Caption}
249
+ <div class="description">{Caption}</div>
250
+ {/block:Caption}
251
+ <div class="details">{block:IfShowViaLinksWithRebloggedPosts}{block:RebloggedFrom}<a href="{ReblogParentURL}" title="{ReblogParentTitle}" class="reblog">via {ReblogParentName}</a>{/block:RebloggedFrom}{/block:IfShowViaLinksWithRebloggedPosts}{block:Date}{block:IfDisqusShortname}<a href="{Permalink}#disqus_thread" class="disqus">{lang:View comments}</a>{/block:IfDisqusShortname}{/block:Date}</div>
252
+ </div>
253
+ </div>
254
+ {/block:Audio}
255
+
256
+ {block:Video}
257
+ <div class="post video">
258
+ <div class="info">
259
+ <a href="{Permalink}" class="type">{lang:Video}</a>
260
+ {block:IndexPage}{block:NoteCount}<a href="{Permalink}#notes" class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}{/block:IndexPage}
261
+ </div>
262
+ {block:IndexPage}<div class="date"><span></span>{lang:Posted TimeAgo}</div>{/block:IndexPage}
263
+ <div class="content">
264
+ <div class="embed">{Video-500}</div>
265
+ {block:Caption}
266
+ <div class="description">{Caption}</div>
267
+ {/block:Caption}
268
+ <div class="details">{block:IfShowViaLinksWithRebloggedPosts}{block:RebloggedFrom}<a href="{ReblogParentURL}" title="{ReblogParentTitle}" class="reblog">via {ReblogParentName}</a>{/block:RebloggedFrom}{/block:IfShowViaLinksWithRebloggedPosts}{block:Date}{block:IfDisqusShortname}<a href="{Permalink}#disqus_thread" class="disqus">{lang:View comments}</a>{/block:IfDisqusShortname}{/block:Date}</div>
269
+ </div>
270
+ </div>
271
+ {/block:Video}
272
+
273
+ {block:PermalinkPage}
274
+ {block:Date}
275
+ <div class="meta">{lang:Posted on DayOfWeek Month DayOfMonth Year}. {block:HasTags}{lang:Tagged with}: {block:Tags}<a href="{TagURL}">{Tag}</a>{/block:Tags}{/block:HasTags}</div>
276
+ {/block:Date}
277
+ {/block:PermalinkPage}
278
+
279
+ {block:PostNotes}
280
+ <div class="post noted">
281
+ <div class="info">
282
+ {block:NoteCount}<a class="notes">{NoteCount}<br/>{lang:Notes}</a>{/block:NoteCount}
283
+ </div>
284
+ <div class="content">
285
+ {PostNotes}
286
+ </div>
287
+ </div>
288
+ {/block:PostNotes}
289
+
290
+ {block:Permalink}
291
+ {block:Date}
292
+ {block:IfDisqusShortname}
293
+ <div class="post commented">
294
+ <div id="disqus_thread"></div>
295
+ <link rel="stylesheet" href="http://static.tumblr.com/pvdmavg/3Egl0q9t8/disqus.css" type="text/css" media="screen">
296
+ <script type="text/javascript" src="http://disqus.com/forums/{text:Disqus Shortname}/embed.js"></script>
297
+ <noscript><a href="http://{text:Disqus Shortname}.disqus.com/?url=ref">{lang:View the discussion thread}</a></noscript>
298
+ <p class="attribution">{lang:Comments powered by Disqus}</p>
299
+ </div>
300
+ {/block:IfDisqusShortname}
301
+ {/block:Date}
302
+ {/block:Permalink}
303
+
304
+ {/block:Posts}
305
+ <div style="clear:both"></div>
306
+ <!-- posts-end -->
307
+ </div><!--/posts_inner-->
308
+ {block:Pagination}
309
+ <div id="pagination">
310
+ <div id="endless">
311
+ <a id="more"><span class="spinner"><img src="http://static.tumblr.com/pvdmavg/h58kv1dih/spinner.gif"></span><span class="label">{lang:More}</span></a>
312
+ <div id="hidden"><span class="startpage">{CurrentPage}</span><span class="totalpages">{TotalPages}</span></div>
313
+ </div>
314
+ <div id="classic">
315
+ {block:NextPage}<a href="{NextPage}" id="older">{lang:Older posts}</a>{/block:NextPage}
316
+ {block:PreviousPage}<a href="{PreviousPage}" id="newer">{lang:Newer posts}</a>{/block:PreviousPage}
317
+ </div>
318
+ </div>
319
+ {/block:Pagination}
320
+ </div><!--/posts_outer-->
321
+ <div id="sidebar">
322
+ {block:Description}
323
+ <div class="section" id="about">
324
+ {block:IfShowMyPortraitPhoto}
325
+ <img src="{PortraitURL-64}" title="{Title}" alt="{Title}" class="picture">
326
+ {/block:IfShowMyPortraitPhoto}{Description}
327
+ </div>
328
+ {/block:Description}
329
+ <div class="section" id="pages">
330
+ {block:HasPages}{block:Pages}<a href="{URL}">{Label}</a>{/block:Pages}{/block:HasPages}
331
+ {block:AskEnabled}<a href="/ask">{AskLabel}</a>{/block:AskEnabled}
332
+ {block:SubmissionsEnabled}<a href="/submit">{SubmitLabel}</a>{/block:SubmissionsEnabled}
333
+ </div>
334
+ {block:IndexPage}
335
+ <div class="section" id="tumblr">
336
+ <form action="/search" method="get" id="search">
337
+ <input type="text" name="q" id="query" value="{SearchQuery}"/>
338
+ <input type="submit" value="" id="submit"/>
339
+ </form>
340
+ <a href="/archive" class="archive">{lang:Archive}</a>
341
+ <a href="{RSS}" class="rss">{lang:Subscribe}</a>
342
+ </div>
343
+ {block:Twitter}
344
+ <div class="section" id="twitter">
345
+ <h4 class="title">{lang:Tweets}</h4>
346
+ <ul id="tweets"></ul>
347
+ <a href="http://twitter.com/{TwitterUsername}" id="follow">{lang:Follow me}</a>
348
+ </div>
349
+ {/block:Twitter}
350
+ {block:IfShowPeopleIFollow}
351
+ {block:Following}
352
+ <div class="section" id="following">
353
+ <h4 class="title">{lang:Following}</h4>
354
+ <ul class="following">
355
+ {block:Followed}
356
+ <li><a href="{FollowedURL}" title="{FollowedTitle}">{FollowedName}</a></li>
357
+ {/block:Followed}
358
+ </ul>
359
+ </div>
360
+ {/block:Following}
361
+ {/block:IfShowPeopleIFollow}
362
+ {/block:IndexPage}
363
+ {block:PermalinkPagination}
364
+ <div class="section" id="permalink">
365
+ {block:PreviousPost}<a href="{PreviousPost}" class="previous">{lang:Previous}</a>{/block:PreviousPost}
366
+ {block:NextPost}<a href="{NextPost}" class="next">{lang:Next}</a>{/block:NextPost}
367
+ </div>
368
+ {/block:PermalinkPagination}
369
+ </div><!--/sidebar-->
370
+ </div><!--/container_inner-->
371
+ <div id="container_close"></div>
372
+ </div><!--/container_outer-->
373
+ <div style="clear:both"></div>
374
+ </div><!--/page_inner-->
375
+ </div><!--/page_outer-->
376
+ {block:Twitter}
377
+ <script type="text/javascript" src="/tweets.js"></script>
378
+ {/block:Twitter}
379
+ {block:IfGoogleAnalyticsID}
380
+ <script type="text/javascript">
381
+ var _gaq = _gaq || [];
382
+ _gaq.push(['_setAccount', '{text:Google Analytics ID}']);
383
+ _gaq.push(['_trackPageview']);
384
+ (function() {
385
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
386
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
387
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
388
+ })();
389
+ </script>
390
+ {/block:IfGoogleAnalyticsID}
391
+ </body>
392
+ </html>
@@ -0,0 +1,159 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe Tumblargh::Parser do
5
+
6
+ before do
7
+ @parser = Tumblargh::Parser.new
8
+ end
9
+
10
+ it "should exist" do
11
+ defined?(Tumblargh::Parser).should be_true
12
+ end
13
+
14
+ describe "given invalid input" do
15
+
16
+ it "should throw an error if there is an unclosed block" do
17
+ @parser.html = <<-eos
18
+ {block:Text}
19
+ {block:Title}<h1>{Title}</h1>{block:Title}
20
+ <p>{Body}</p>
21
+ {/block:text}
22
+ eos
23
+
24
+ lambda { @parser.tree }.should raise_error Tumblargh::ParserError
25
+ end
26
+
27
+ end
28
+
29
+ describe "given something that kinda looks like a tag but isn't" do
30
+
31
+ before do
32
+ @parser.html = "<div>{CustomCSS</div>"
33
+ end
34
+
35
+ it "should NOT throw an error if there is a malformed tag" do
36
+ lambda { @parser.tree }.should_not raise_error Tumblargh::ParserError
37
+ end
38
+
39
+ it "should generate the following tree" do
40
+ @parser.tree.should == [[:Literal, "<div>"], [:Literal, "{"], [:Literal, "CustomCSS</div>"]]
41
+ end
42
+
43
+ end
44
+
45
+ describe "when given a bunch of css" do
46
+
47
+ before do
48
+ @input = <<-eos
49
+ .container{*zoom:1;margin:auto;width:960px;max-width:100%;position:relative}.container:after{content:"";display:table;clear:both}.dot-sprite,#clients .nav .dots li,#clients .nav .dots li.active,#fullscreen_nav .nav .dots li,#fullscreen_nav .nav .dots li.active{background:url('../images/dot-sa49b299bc4.png') no-repeat}body.index{min-width:1000px}body.fullscreen{overflow-x:hidden}#clients{height:461px;overflow:visible;background:#fff url('../images/homepage-clients-bg.png') repeat-x 0 0px}#clients .frame{width:958px;height:448px;margin:0 auto;position:relative;-moz-border-radius:7px;-webkit-border-radius:7px;-o-border-radius:7px;-ms-border-radius:7px;-khtml-border-radius:7px;border-radius:7px;-moz-box-shadow:#000 0px 1px 2px;-webkit-box-shadow:#000 0px 1px 2px;-o-box-shadow:#000 0px 1px 2px;box-shadow:#000 0px 1px 2px;background:#262626}
50
+
51
+ #title a{
52
+ text-decoration:none;
53
+ color:#fff;
54
+ font-weight:bold;
55
+ text-shadow: #fff 0px 1px 0px;
56
+ padding:0;
57
+ display:block;
58
+ }
59
+
60
+ #title b {height:93px;
61
+ width:36px;
62
+ position: absolute;
63
+ top:0px;
64
+ }
65
+
66
+ #title b.left {
67
+ background: url(http://static.tumblr.com/xsp9wak/Shikloi1h/background-title.png) top left;
68
+ left:-36px; }
69
+
70
+ #title b.right {right:-36px;}
71
+ eos
72
+
73
+ @parser.html = @input
74
+ end
75
+
76
+ it "should NOT throw an error" do
77
+ lambda { @parser.tree }.should_not raise_error Tumblargh::ParserError
78
+ end
79
+
80
+ it "its output should match its input" do
81
+ @parser.to_s.should eql @input
82
+ end
83
+
84
+ end
85
+
86
+
87
+ describe "given a simple partial" do
88
+
89
+ before do
90
+ @parser.html = <<-eos
91
+ {block:Text}
92
+ {block:Title}<h1>{Title}</h1>{/block:Title}
93
+ <p>{Body}</p>
94
+ {/block:text}
95
+ eos
96
+ end
97
+
98
+ it "should not contain any custom appearance options" do
99
+ @parser.options.empty?.should be_true
100
+ end
101
+
102
+ it "should contain the following tree" do
103
+ expected = [
104
+ [:Literal, " "],
105
+ [:Block, "Text",
106
+ [:Block, "Title",
107
+ [:Literal, "<h1>"],
108
+ [:Tag, "Title"],
109
+ [:Literal, "</h1>"]
110
+ ],
111
+ [:Literal, "<p>"],
112
+ [:Tag, "Body"],
113
+ [:Literal, "</p>\n "]
114
+ ]
115
+ ]
116
+
117
+ # Yes, Array.== Array is a deep value based comparison
118
+ @parser.tree.should == expected
119
+ end
120
+
121
+ end
122
+
123
+ describe "given jake's solstice theme" do
124
+
125
+ before do
126
+ @parser.html = open(File.join(FIXTURE_PATH, 'themes', 'solstice.html')).read
127
+ end
128
+
129
+ it "should contain the correct appearance options" do
130
+ @parser.options.should == {
131
+ "image" => {
132
+ "background" => ""
133
+ },
134
+ "if" => {
135
+ "showpeopleifollow" => true,
136
+ "showmyportraitphoto" => true,
137
+ "showvialinkswithrebloggedposts" => true,
138
+ "useclassicpaging" => false,
139
+ "hidedisquscommentcountifzero" => false
140
+ },
141
+ "text" => {
142
+ "disqusshortname" => "",
143
+ "googleanalyticsid" => ""
144
+ }
145
+ }
146
+ end
147
+
148
+ it "should contain exacty one 'posts' block" do
149
+ nodes = @parser.tree
150
+ matches = nodes.select do |n|
151
+ n[0] == :Block && n[1] == "Posts"
152
+ end
153
+
154
+ matches.size.should eql 1
155
+ end
156
+
157
+ end
158
+
159
+ end