monad 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.
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