monad 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.markdown +91 -0
  3. data/Gemfile +1 -1
  4. data/History.markdown +772 -0
  5. data/{README.md → README.markdown} +5 -2
  6. data/Rakefile +163 -1
  7. data/bin/monad +86 -30
  8. data/features/create_sites.feature +54 -25
  9. data/features/data.feature +65 -0
  10. data/features/data_sources.feature +10 -10
  11. data/features/drafts.feature +5 -5
  12. data/features/embed_filters.feature +10 -10
  13. data/features/include_tag.feature +48 -0
  14. data/features/markdown.feature +5 -5
  15. data/features/pagination.feature +38 -10
  16. data/features/permalinks.feature +31 -11
  17. data/features/post_data.feature +41 -41
  18. data/features/post_excerpts.feature +50 -0
  19. data/features/site_configuration.feature +47 -26
  20. data/features/site_data.feature +30 -24
  21. data/features/step_definitions/{monad_steps.rb → jekyll_steps.rb} +66 -52
  22. data/features/support/env.rb +27 -8
  23. data/lib/jekyll.rb +99 -0
  24. data/lib/jekyll/cleaner.rb +73 -0
  25. data/lib/{monad → jekyll}/command.rb +6 -6
  26. data/lib/{monad → jekyll}/commands/build.rb +9 -9
  27. data/lib/jekyll/commands/doctor.rb +67 -0
  28. data/lib/jekyll/commands/new.rb +67 -0
  29. data/lib/jekyll/commands/serve.rb +65 -0
  30. data/lib/{monad → jekyll}/configuration.rb +60 -18
  31. data/lib/{monad → jekyll}/converter.rb +1 -1
  32. data/lib/{monad → jekyll}/converters/identity.rb +1 -1
  33. data/lib/{monad → jekyll}/converters/markdown.rb +2 -2
  34. data/lib/jekyll/converters/markdown/kramdown_parser.rb +29 -0
  35. data/lib/{monad → jekyll}/converters/markdown/maruku_parser.rb +12 -8
  36. data/lib/{monad → jekyll}/converters/markdown/rdiscount_parser.rb +4 -2
  37. data/lib/{monad → jekyll}/converters/markdown/redcarpet_parser.rb +1 -1
  38. data/lib/{monad → jekyll}/converters/textile.rb +1 -1
  39. data/lib/{monad → jekyll}/convertible.rb +39 -17
  40. data/lib/{monad → jekyll}/core_ext.rb +22 -4
  41. data/lib/jekyll/deprecator.rb +36 -0
  42. data/lib/{monad → jekyll}/draft.rb +1 -1
  43. data/lib/{monad → jekyll}/drivers/json_driver.rb +1 -1
  44. data/lib/{monad → jekyll}/drivers/yaml_driver.rb +1 -1
  45. data/lib/{monad → jekyll}/errors.rb +1 -1
  46. data/lib/jekyll/excerpt.rb +113 -0
  47. data/lib/{monad → jekyll}/filters.rb +16 -6
  48. data/lib/{monad → jekyll}/generator.rb +1 -1
  49. data/lib/jekyll/generators/pagination.rb +214 -0
  50. data/lib/{monad → jekyll}/layout.rb +4 -1
  51. data/lib/{monad → jekyll}/mime.types +0 -0
  52. data/lib/{monad → jekyll}/page.rb +36 -39
  53. data/lib/{monad → jekyll}/plugin.rb +1 -1
  54. data/lib/{monad → jekyll}/post.rb +58 -123
  55. data/lib/jekyll/related_posts.rb +59 -0
  56. data/lib/{monad → jekyll}/site.rb +120 -123
  57. data/lib/{monad → jekyll}/static_file.rb +1 -1
  58. data/lib/jekyll/stevenson.rb +89 -0
  59. data/lib/jekyll/tags/gist.rb +48 -0
  60. data/lib/{monad → jekyll}/tags/highlight.rb +3 -3
  61. data/lib/jekyll/tags/include.rb +135 -0
  62. data/lib/{monad → jekyll}/tags/post_url.rb +8 -6
  63. data/lib/jekyll/url.rb +67 -0
  64. data/lib/monad.rb +36 -27
  65. data/lib/site_template/_config.yml +2 -1
  66. data/lib/site_template/_layouts/default.html +21 -23
  67. data/lib/site_template/_layouts/post.html +1 -1
  68. data/lib/site_template/_posts/{0000-00-00-welcome-to-monad.markdown.erb → 0000-00-00-welcome-to-jekyll.markdown.erb} +6 -6
  69. data/lib/site_template/css/main.css +22 -27
  70. data/lib/site_template/index.html +2 -2
  71. data/monad.gemspec +153 -52
  72. data/site/.gitignore +4 -0
  73. data/site/CNAME +1 -0
  74. data/site/README +1 -0
  75. data/site/_config.yml +6 -0
  76. data/site/_includes/analytics.html +32 -0
  77. data/site/_includes/docs_contents.html +16 -0
  78. data/site/_includes/docs_contents_mobile.html +23 -0
  79. data/site/_includes/docs_option.html +11 -0
  80. data/site/_includes/docs_ul.html +20 -0
  81. data/site/_includes/footer.html +15 -0
  82. data/site/_includes/header.html +18 -0
  83. data/site/_includes/news_contents.html +23 -0
  84. data/site/_includes/news_contents_mobile.html +11 -0
  85. data/site/_includes/news_item.html +24 -0
  86. data/site/_includes/primary-nav-items.html +14 -0
  87. data/site/_includes/section_nav.html +22 -0
  88. data/site/_includes/top.html +17 -0
  89. data/site/_layouts/default.html +12 -0
  90. data/site/_layouts/docs.html +23 -0
  91. data/site/_layouts/news.html +19 -0
  92. data/site/_layouts/news_item.html +27 -0
  93. data/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown +23 -0
  94. data/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown +27 -0
  95. data/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown +28 -0
  96. data/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown +25 -0
  97. data/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown +27 -0
  98. data/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown +31 -0
  99. data/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown +20 -0
  100. data/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown +20 -0
  101. data/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown +23 -0
  102. data/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown +19 -0
  103. data/site/css/gridism.css +110 -0
  104. data/site/css/normalize.css +1 -0
  105. data/site/css/pygments.css +70 -0
  106. data/site/css/style.css +946 -0
  107. data/site/docs/configuration.md +373 -0
  108. data/site/docs/contributing.md +128 -0
  109. data/site/docs/datafiles.md +63 -0
  110. data/site/docs/deployment-methods.md +109 -0
  111. data/site/docs/drafts.md +20 -0
  112. data/site/docs/extras.md +56 -0
  113. data/site/docs/frontmatter.md +180 -0
  114. data/site/docs/github-pages.md +91 -0
  115. data/site/docs/heroku.md +9 -0
  116. data/site/docs/history.md +722 -0
  117. data/site/docs/index.md +52 -0
  118. data/site/docs/installation.md +76 -0
  119. data/site/docs/migrations.md +257 -0
  120. data/site/docs/pages.md +86 -0
  121. data/site/docs/pagination.md +211 -0
  122. data/site/docs/permalinks.md +180 -0
  123. data/site/docs/plugins.md +508 -0
  124. data/site/docs/posts.md +181 -0
  125. data/site/docs/quickstart.md +32 -0
  126. data/site/docs/resources.md +46 -0
  127. data/site/docs/sites.md +29 -0
  128. data/site/docs/structure.md +190 -0
  129. data/site/docs/templates.md +319 -0
  130. data/site/docs/troubleshooting.md +150 -0
  131. data/site/docs/upgrading.md +146 -0
  132. data/site/docs/usage.md +63 -0
  133. data/site/docs/variables.md +322 -0
  134. data/site/favicon.png +0 -0
  135. data/site/feed.xml +36 -0
  136. data/site/freenode.txt +1 -0
  137. data/site/img/article-footer.png +0 -0
  138. data/site/img/footer-arrow.png +0 -0
  139. data/site/img/footer-logo.png +0 -0
  140. data/site/img/logo-2x.png +0 -0
  141. data/site/img/octojekyll.png +0 -0
  142. data/site/img/tube.png +0 -0
  143. data/site/img/tube1x.png +0 -0
  144. data/site/index.html +90 -0
  145. data/site/js/modernizr-2.5.3.min.js +4 -0
  146. data/site/news/index.html +10 -0
  147. data/site/news/releases/index.html +10 -0
  148. data/test/helper.rb +6 -3
  149. data/test/source/+/foo.md +7 -0
  150. data/test/source/_data/languages.yml +2 -0
  151. data/test/source/_data/members.yaml +7 -0
  152. data/test/source/_data/products.yml +4 -0
  153. data/test/source/_includes/params.html +7 -0
  154. data/test/source/_layouts/default.html +1 -1
  155. data/test/source/_layouts/post/simple.html +1 -0
  156. data/test/source/_plugins/dummy.rb +1 -1
  157. data/test/source/_posts/2013-01-02-post-excerpt.markdown +1 -1
  158. data/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown +23 -0
  159. data/test/source/_posts/2013-08-01-mkdn-extension.mkdn +0 -0
  160. data/test/source/deal.with.dots.html +1 -1
  161. data/test/source/products.yml +4 -0
  162. data/test/test_configuration.rb +46 -11
  163. data/test/test_convertible.rb +2 -2
  164. data/test/test_excerpt.rb +78 -0
  165. data/test/test_filters.rb +4 -4
  166. data/test/test_generated_site.rb +13 -13
  167. data/test/test_json_driver.rb +9 -9
  168. data/test/test_kramdown.rb +32 -5
  169. data/test/test_new_command.rb +8 -8
  170. data/test/test_page.rb +12 -3
  171. data/test/test_pager.rb +34 -33
  172. data/test/test_post.rb +34 -26
  173. data/test/test_redcloth.rb +3 -3
  174. data/test/test_related_posts.rb +47 -0
  175. data/test/test_site.rb +102 -44
  176. data/test/test_tags.rb +168 -23
  177. data/test/test_url.rb +28 -0
  178. data/test/test_yaml_driver.rb +6 -6
  179. metadata +215 -137
  180. data/lib/monad/commands/doctor.rb +0 -29
  181. data/lib/monad/commands/new.rb +0 -50
  182. data/lib/monad/commands/serve.rb +0 -33
  183. data/lib/monad/converters/markdown/kramdown_parser.rb +0 -44
  184. data/lib/monad/deprecator.rb +0 -32
  185. data/lib/monad/generators/pagination.rb +0 -143
  186. data/lib/monad/logger.rb +0 -54
  187. data/lib/monad/tags/gist.rb +0 -30
  188. data/lib/monad/tags/include.rb +0 -37
@@ -1,10 +1,13 @@
1
- module Monad
1
+ module Jekyll
2
2
  class Layout
3
3
  include Convertible
4
4
 
5
5
  # Gets the Site object.
6
6
  attr_reader :site
7
7
 
8
+ # Gets the name of this layout.
9
+ attr_reader :name
10
+
8
11
  # Gets/Sets the extension of this layout.
9
12
  attr_accessor :ext
10
13
 
File without changes
@@ -1,4 +1,4 @@
1
- module Monad
1
+ module Jekyll
2
2
  class Page
3
3
  include Convertible
4
4
 
@@ -7,6 +7,13 @@ module Monad
7
7
  attr_accessor :name, :ext, :basename
8
8
  attr_accessor :data, :content, :output
9
9
 
10
+ # Attributes for Liquid templates
11
+ ATTRIBUTES_FOR_LIQUID = %w[
12
+ url
13
+ content
14
+ path
15
+ ]
16
+
10
17
  # Initialize a new Page.
11
18
  #
12
19
  # site - The Site object.
@@ -37,7 +44,12 @@ module Monad
37
44
  #
38
45
  # Returns the String permalink or nil if none has been set.
39
46
  def permalink
40
- self.data && self.data['permalink']
47
+ return nil if self.data.nil? || self.data['permalink'].nil?
48
+ if site.config['relative_permalinks']
49
+ File.join(@dir, self.data['permalink'])
50
+ else
51
+ self.data['permalink']
52
+ end
41
53
  end
42
54
 
43
55
  # The template of the permalink.
@@ -61,29 +73,21 @@ module Monad
61
73
  #
62
74
  # Returns the String url.
63
75
  def url
64
- return @url if @url
65
-
66
- url = if permalink
67
- if site.config['relative_permalinks']
68
- File.join(@dir, permalink)
69
- else
70
- permalink
71
- end
72
- else
73
- {
74
- "path" => @dir,
75
- "basename" => self.basename,
76
- "output_ext" => self.output_ext,
77
- }.inject(template) { |result, token|
78
- result.gsub(/:#{token.first}/, token.last)
79
- }.gsub(/\/\//, "/")
80
- end
76
+ @url ||= URL.new({
77
+ :template => template,
78
+ :placeholders => url_placeholders,
79
+ :permalink => permalink
80
+ }).to_s
81
+ end
81
82
 
82
- # sanitize url
83
- @url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
84
- @url += "/" if url =~ /\/$/
85
- @url.gsub!(/\A([^\/])/, '/\1')
86
- @url
83
+ # Returns a hash of URL placeholder names (as symbols) mapping to the
84
+ # desired placeholder replacements. For details see "url.rb"
85
+ def url_placeholders
86
+ {
87
+ :path => @dir,
88
+ :basename => self.basename,
89
+ :output_ext => self.output_ext
90
+ }
87
91
  end
88
92
 
89
93
  # Extract information from the page filename.
@@ -111,21 +115,16 @@ module Monad
111
115
  do_layout(payload, layouts)
112
116
  end
113
117
 
114
- # Convert this Page's data to a Hash suitable for use by Liquid.
115
- #
116
- # Returns the Hash representation of this Page.
117
- def to_liquid
118
- self.data.deep_merge({
119
- "url" => self.url,
120
- "content" => self.content,
121
- "path" => self.data['path'] || path })
122
- end
123
-
124
118
  # The path to the source file
125
119
  #
126
120
  # Returns the path to the source file
127
121
  def path
128
- File.join(@dir, @name).sub(/\A\//, '')
122
+ self.data.fetch('path', self.relative_path.sub(/\A\//, ''))
123
+ end
124
+
125
+ # The path to the page source file, relative to the site source
126
+ def relative_path
127
+ File.join(@dir, @name)
129
128
  end
130
129
 
131
130
  # Obtain destination path.
@@ -134,16 +133,14 @@ module Monad
134
133
  #
135
134
  # Returns the destination file path String.
136
135
  def destination(dest)
137
- # The url needs to be unescaped in order to preserve the correct
138
- # filename.
139
- path = File.join(dest, CGI.unescape(self.url))
136
+ path = File.join(dest, self.url)
140
137
  path = File.join(path, "index.html") if self.url =~ /\/$/
141
138
  path
142
139
  end
143
140
 
144
141
  # Returns the object as a debug String.
145
142
  def inspect
146
- "#<Monad:Page @name=#{self.name.inspect}>"
143
+ "#<Jekyll:Page @name=#{self.name.inspect}>"
147
144
  end
148
145
 
149
146
  # Returns the Boolean of whether this Page is HTML or not.
@@ -1,4 +1,4 @@
1
- module Monad
1
+ module Jekyll
2
2
  class Plugin
3
3
  PRIORITIES = { :lowest => -100,
4
4
  :low => -10,
@@ -1,17 +1,12 @@
1
- module Monad
1
+ module Jekyll
2
2
  class Post
3
3
  include Comparable
4
4
  include Convertible
5
5
 
6
- class << self
7
- attr_accessor :lsi
8
- end
9
-
10
6
  # Valid post name regex.
11
7
  MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
12
8
 
13
- # Attributes for Liquid templates
14
- ATTRIBUTES_FOR_LIQUID = %w[
9
+ EXCERPT_ATTRIBUTES_FOR_LIQUID = %w[
15
10
  title
16
11
  url
17
12
  date
@@ -20,9 +15,13 @@ module Monad
20
15
  next
21
16
  previous
22
17
  tags
18
+ path
19
+ ]
20
+
21
+ # Attributes for Liquid templates
22
+ ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID + %w[
23
23
  content
24
24
  excerpt
25
- path
26
25
  ]
27
26
 
28
27
  # Post name validator. Post filenames must be like:
@@ -106,18 +105,19 @@ module Monad
106
105
  #
107
106
  # Returns excerpt string.
108
107
  def excerpt
109
- if self.data.has_key? 'excerpt'
110
- self.data['excerpt']
111
- else
112
- self.extracted_excerpt
113
- end
108
+ self.data.fetch('excerpt', self.extracted_excerpt.to_s)
114
109
  end
115
110
 
116
111
  # Public: the Post title, from the YAML Front-Matter or from the slug
117
112
  #
118
113
  # Returns the post title
119
114
  def title
120
- self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' ')
115
+ self.data.fetch("title", self.titleized_slug)
116
+ end
117
+
118
+ # Turns the post slug into a suitable title
119
+ def titleized_slug
120
+ self.slug.split('-').select {|w| w.capitalize! || w }.join(' ')
121
121
  end
122
122
 
123
123
  # Public: the path to the post relative to the site source,
@@ -127,7 +127,12 @@ module Monad
127
127
  #
128
128
  # Returns the path to the file relative to the site source
129
129
  def path
130
- self.data['path'] || File.join(@dir, '_posts', @name).sub(/\A\//, '')
130
+ self.data.fetch('path', self.relative_path.sub(/\A\//, ''))
131
+ end
132
+
133
+ # The path to the post source file, relative to the site source
134
+ def relative_path
135
+ File.join(@dir, '_posts', @name)
131
136
  end
132
137
 
133
138
  # Compares Post objects. First compares the Post date. If the dates are
@@ -158,14 +163,6 @@ module Monad
158
163
  raise FatalException.new("Post #{name} does not have a valid date.")
159
164
  end
160
165
 
161
- # Transform the contents and excerpt based on the content type.
162
- #
163
- # Returns nothing.
164
- def transform
165
- super
166
- self.extracted_excerpt = converter.convert(self.extracted_excerpt)
167
- end
168
-
169
166
  # The generated directory into which the post will be placed
170
167
  # upon generation. This is derived from the permalink or, if
171
168
  # permalink is absent, set to the default date
@@ -200,36 +197,31 @@ module Monad
200
197
  end
201
198
 
202
199
  # The generated relative url of this post.
203
- # e.g. /2008/11/05/my-awesome-post.html
204
200
  #
205
- # Returns the String URL.
201
+ # Returns the String url.
206
202
  def url
207
- return @url if @url
208
-
209
- url = if permalink
210
- permalink
211
- else
212
- {
213
- "year" => date.strftime("%Y"),
214
- "month" => date.strftime("%m"),
215
- "day" => date.strftime("%d"),
216
- "title" => CGI.escape(slug),
217
- "i_day" => date.strftime("%d").to_i.to_s,
218
- "i_month" => date.strftime("%m").to_i.to_s,
219
- "categories" => categories.map { |c| URI.escape(c.to_s) }.join('/'),
220
- "short_month" => date.strftime("%b"),
221
- "y_day" => date.strftime("%j"),
222
- "output_ext" => self.output_ext
223
- }.inject(template) { |result, token|
224
- result.gsub(/:#{Regexp.escape token.first}/, token.last)
225
- }.gsub(/\/\//, "/")
226
- end
203
+ @url ||= URL.new({
204
+ :template => template,
205
+ :placeholders => url_placeholders,
206
+ :permalink => permalink
207
+ }).to_s
208
+ end
227
209
 
228
- # sanitize url
229
- @url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
230
- @url += "/" if url =~ /\/$/
231
- @url.gsub!(/\A([^\/])/, '/\1')
232
- @url
210
+ # Returns a hash of URL placeholder names (as symbols) mapping to the
211
+ # desired placeholder replacements. For details see "url.rb"
212
+ def url_placeholders
213
+ {
214
+ :year => date.strftime("%Y"),
215
+ :month => date.strftime("%m"),
216
+ :day => date.strftime("%d"),
217
+ :title => CGI.escape(slug),
218
+ :i_day => date.strftime("%d").to_i.to_s,
219
+ :i_month => date.strftime("%m").to_i.to_s,
220
+ :categories => (categories || []).map { |c| URI.escape(c.to_s) }.join('/'),
221
+ :short_month => date.strftime("%b"),
222
+ :y_day => date.strftime("%j"),
223
+ :output_ext => self.output_ext
224
+ }
233
225
  end
234
226
 
235
227
  # The UID for this post (useful in feeds).
@@ -244,29 +236,7 @@ module Monad
244
236
  #
245
237
  # Returns an Array of related Posts.
246
238
  def related_posts(posts)
247
- return [] unless posts.size > 1
248
-
249
- if self.site.lsi
250
- build_index
251
-
252
- related = self.class.lsi.find_related(self.content, 11)
253
- related - [self]
254
- else
255
- (posts - [self])[0..9]
256
- end
257
- end
258
-
259
- def build_index
260
- self.class.lsi ||= begin
261
- puts "Starting the classifier..."
262
- lsi = Classifier::LSI.new(:auto_rebuild => false)
263
- $stdout.print(" Populating LSI... "); $stdout.flush
264
- self.site.posts.each { |x| $stdout.print("."); $stdout.flush; lsi.add_item(x) }
265
- $stdout.print("\n Rebuilding LSI index... ")
266
- lsi.build_index
267
- puts ""
268
- lsi
269
- end
239
+ Jekyll::RelatedPosts.new(self).build
270
240
  end
271
241
 
272
242
  # Add any necessary layouts to this post.
@@ -279,10 +249,14 @@ module Monad
279
249
  # construct payload
280
250
  payload = {
281
251
  "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
282
- "page" => self.to_liquid
252
+ "page" => self.to_liquid(EXCERPT_ATTRIBUTES_FOR_LIQUID)
283
253
  }.deep_merge(site_payload)
284
254
 
285
- do_layout(payload, layouts)
255
+ if generate_excerpt?
256
+ self.extracted_excerpt.do_layout(payload, {})
257
+ end
258
+
259
+ do_layout(payload.merge({"page" => self.to_liquid}), layouts)
286
260
  end
287
261
 
288
262
  # Obtain destination path.
@@ -293,20 +267,10 @@ module Monad
293
267
  def destination(dest)
294
268
  # The url needs to be unescaped in order to preserve the correct filename
295
269
  path = File.join(dest, CGI.unescape(self.url))
296
- path = File.join(path, "index.html") if template[/\.html$/].nil?
270
+ path = File.join(path, "index.html") if path[/\.html$/].nil?
297
271
  path
298
272
  end
299
273
 
300
- # Convert this post into a Hash for use in Liquid templates.
301
- #
302
- # Returns the representative Hash.
303
- def to_liquid
304
- further_data = Hash[ATTRIBUTES_FOR_LIQUID.map { |attribute|
305
- [attribute, send(attribute)]
306
- }]
307
- data.deep_merge(further_data)
308
- end
309
-
310
274
  # Returns the shorthand String identifier of this Post.
311
275
  def inspect
312
276
  "<Post: #{self.id}>"
@@ -333,45 +297,16 @@ module Monad
333
297
 
334
298
  protected
335
299
 
336
- # Internal: Extract excerpt from the content
337
- #
338
- # By default excerpt is your first paragraph of a post: everything before
339
- # the first two new lines:
340
- #
341
- # ---
342
- # title: Example
343
- # ---
344
- #
345
- # First paragraph with [link][1].
346
- #
347
- # Second paragraph.
348
- #
349
- # [1]: http://example.com/
350
- #
351
- # This is fairly good option for Markdown and Textile files. But might cause
352
- # problems for HTML posts (which is quite unusual for Monad). If default
353
- # excerpt delimiter is not good for you, you might want to set your own via
354
- # configuration option `excerpt_separator`. For example, following is a good
355
- # alternative for HTML posts:
356
- #
357
- # # file: _config.yml
358
- # excerpt_separator: "<!-- more -->"
359
- #
360
- # Notice that all markdown-style link references will be appended to the
361
- # excerpt. So the example post above will have this excerpt source:
362
- #
363
- # First paragraph with [link][1].
364
- #
365
- # [1]: http://example.com/
366
- #
367
- # Excerpts are rendered same time as content is rendered.
368
- #
369
- # Returns excerpt String
370
300
  def extract_excerpt
371
- separator = self.site.config['excerpt_separator']
372
- head, _, tail = self.content.partition(separator)
301
+ if generate_excerpt?
302
+ Jekyll::Excerpt.new(self)
303
+ else
304
+ ""
305
+ end
306
+ end
373
307
 
374
- "" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
308
+ def generate_excerpt?
309
+ !(site.config['excerpt_separator'].to_s.empty?)
375
310
  end
376
311
  end
377
312
  end
@@ -0,0 +1,59 @@
1
+ module Jekyll
2
+ class RelatedPosts
3
+
4
+ class << self
5
+ attr_accessor :lsi
6
+ end
7
+
8
+ attr_reader :post, :site
9
+
10
+ def initialize(post)
11
+ @post = post
12
+ @site = post.site
13
+ require 'classifier' if site.lsi
14
+ end
15
+
16
+ def build
17
+ return [] unless self.site.posts.size > 1
18
+
19
+ if self.site.lsi
20
+ build_index
21
+ lsi_related_posts
22
+ else
23
+ most_recent_posts
24
+ end
25
+ end
26
+
27
+
28
+ def build_index
29
+ self.class.lsi ||= begin
30
+ lsi = Classifier::LSI.new(:auto_rebuild => false)
31
+ display("Populating LSI...")
32
+
33
+ self.site.posts.each do |x|
34
+ lsi.add_item(x)
35
+ end
36
+
37
+ display("Rebuilding index...")
38
+ lsi.build_index
39
+ display("")
40
+ lsi
41
+ end
42
+ end
43
+
44
+ def lsi_related_posts
45
+ self.class.lsi.find_related(post.content, 11) - [self.post]
46
+ end
47
+
48
+ def most_recent_posts
49
+ recent_posts = self.site.posts.reverse - [self.post]
50
+ recent_posts.first(10)
51
+ end
52
+
53
+ def display(output)
54
+ $stdout.print("\n")
55
+ $stdout.print(Jekyll.logger.formatted_topic(output))
56
+ $stdout.flush
57
+ end
58
+ end
59
+ end