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,11 +1,9 @@
1
- require 'set'
2
-
3
- module Monad
1
+ module Jekyll
4
2
  class Site
5
3
  attr_accessor :config, :layouts, :posts, :pages, :static_files,
6
4
  :categories, :exclude, :include, :source, :dest, :lsi, :pygments,
7
5
  :permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts,
8
- :show_drafts, :keep_files, :baseurl, :data_sources
6
+ :show_drafts, :keep_files, :baseurl, :data, :data_sources, :file_read_opts
9
7
 
10
8
  attr_accessor :converters, :generators
11
9
 
@@ -15,20 +13,17 @@ module Monad
15
13
  def initialize(config)
16
14
  self.config = config.clone
17
15
 
18
- self.safe = config['safe']
16
+ %w[safe lsi pygments baseurl exclude include future show_drafts limit_posts keep_files].each do |opt|
17
+ self.send("#{opt}=", config[opt])
18
+ end
19
+
19
20
  self.source = File.expand_path(config['source'])
20
21
  self.dest = File.expand_path(config['destination'])
21
22
  self.plugins = plugins_path
22
- self.lsi = config['lsi']
23
- self.pygments = config['pygments']
24
- self.baseurl = config['baseurl']
25
23
  self.permalink_style = config['permalink'].to_sym
26
- self.exclude = config['exclude']
27
- self.include = config['include']
28
- self.future = config['future']
29
- self.show_drafts = config['show_drafts']
30
- self.limit_posts = config['limit_posts']
31
- self.keep_files = config['keep_files']
24
+
25
+ self.file_read_opts = {}
26
+ self.file_read_opts[:encoding] = config['encoding'] if config['encoding']
32
27
 
33
28
  self.reset
34
29
  self.setup
@@ -61,6 +56,7 @@ module Monad
61
56
  self.static_files = []
62
57
  self.categories = Hash.new { |hash, key| hash[key] = [] }
63
58
  self.tags = Hash.new { |hash, key| hash[key] = [] }
59
+ self.data = {}
64
60
  self.data_sources = {}
65
61
 
66
62
  if self.limit_posts < 0
@@ -72,13 +68,7 @@ module Monad
72
68
  #
73
69
  # Returns nothing.
74
70
  def setup
75
- require 'classifier' if self.lsi
76
-
77
- # Check that the destination dir isn't the source dir or a directory
78
- # parent to the source dir.
79
- if self.source =~ /^#{self.dest}/
80
- raise FatalException.new "Destination directory cannot be or contain the Source directory."
81
- end
71
+ ensure_not_in_dest
82
72
 
83
73
  # If safe mode is off, load in any Ruby files under the plugins
84
74
  # directory.
@@ -90,15 +80,26 @@ module Monad
90
80
  end
91
81
  end
92
82
 
93
- self.converters = instantiate_subclasses(Monad::Converter)
94
- self.generators = instantiate_subclasses(Monad::Generator)
83
+ self.converters = instantiate_subclasses(Jekyll::Converter)
84
+ self.generators = instantiate_subclasses(Jekyll::Generator)
85
+ end
86
+
87
+ # Check that the destination dir isn't the source dir or a directory
88
+ # parent to the source dir.
89
+ def ensure_not_in_dest
90
+ dest = Pathname.new(self.dest)
91
+ Pathname.new(self.source).ascend do |path|
92
+ if path == dest
93
+ raise FatalException.new "Destination directory cannot be or contain the Source directory."
94
+ end
95
+ end
95
96
  end
96
97
 
97
98
  # Internal: Setup the plugin search path
98
99
  #
99
100
  # Returns an Array of plugin search paths
100
101
  def plugins_path
101
- if (config['plugins'] == Monad::Configuration::DEFAULTS['plugins'])
102
+ if (config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
102
103
  [File.join(self.source, config['plugins'])]
103
104
  else
104
105
  Array(config['plugins']).map { |d| File.expand_path(d) }
@@ -111,6 +112,7 @@ module Monad
111
112
  def read
112
113
  self.read_layouts
113
114
  self.read_directories
115
+ self.read_data(config['data_source'])
114
116
  self.load_data_sources
115
117
  end
116
118
 
@@ -122,7 +124,7 @@ module Monad
122
124
  base = File.join(self.source, self.config['layouts'])
123
125
  return unless File.exists?(base)
124
126
  entries = []
125
- Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
127
+ Dir.chdir(base) { entries = filter_entries(Dir['**/*.*']) }
126
128
 
127
129
  entries.each do |f|
128
130
  name = f.split(".")[0..-2].join(".")
@@ -142,34 +144,19 @@ module Monad
142
144
  entries = Dir.chdir(base) { filter_entries(Dir.entries('.')) }
143
145
 
144
146
  self.read_posts(dir)
145
-
146
- if self.show_drafts
147
- self.read_drafts(dir)
148
- end
149
-
147
+ self.read_drafts(dir) if self.show_drafts
150
148
  self.posts.sort!
151
-
152
- # limit the posts if :limit_posts option is set
153
- if limit_posts > 0
154
- limit = self.posts.length < limit_posts ? self.posts.length : limit_posts
155
- self.posts = self.posts[-limit, limit]
156
- end
149
+ limit_posts! if limit_posts > 0 # limit the posts if :limit_posts option is set
157
150
 
158
151
  entries.each do |f|
159
152
  f_abs = File.join(base, f)
160
- f_rel = File.join(dir, f)
161
153
  if File.directory?(f_abs)
162
- next if self.dest.sub(/\/$/, '') == f_abs
163
- read_directories(f_rel)
154
+ f_rel = File.join(dir, f)
155
+ read_directories(f_rel) unless self.dest.sub(/\/$/, '') == f_abs
156
+ elsif has_yaml_header?(f_abs)
157
+ pages << Page.new(self, self.source, dir, f)
164
158
  else
165
- first3 = File.open(f_abs) { |fd| fd.read(3) }
166
- if first3 == "---"
167
- # file appears to have a YAML header so process it as a page
168
- pages << Page.new(self, self.source, dir, f)
169
- else
170
- # otherwise treat it as a static file
171
- static_files << StaticFile.new(self, self.source, dir, f)
172
- end
159
+ static_files << StaticFile.new(self, self.source, dir, f)
173
160
  end
174
161
  end
175
162
  end
@@ -214,6 +201,42 @@ module Monad
214
201
  end
215
202
  end
216
203
 
204
+ # Read and parse all yaml files under <source>/<dir>
205
+ #
206
+ # Returns nothing
207
+ def read_data(dir)
208
+ base = File.join(self.source, dir)
209
+ return unless File.directory?(base) && (!self.safe || !File.symlink?(base))
210
+
211
+ entries = Dir.chdir(base) { Dir['*.{yaml,yml}'] }
212
+ entries.delete_if { |e| File.directory?(File.join(base, e)) }
213
+
214
+ entries.each do |entry|
215
+ path = File.join(self.source, dir, entry)
216
+ next if File.symlink?(path) && self.safe
217
+
218
+ key = sanitize_filename(File.basename(entry, '.*'))
219
+ self.data[key] = YAML.safe_load_file(path)
220
+ end
221
+ end
222
+
223
+ # Load external data sources to @data_sources
224
+ #
225
+ # Returns nothing
226
+ def load_data_sources
227
+ self.config['data_sources'] && self.config['data_sources'].each do |data_source_config|
228
+ if data_source_config['name'] !~ /^\w+$/
229
+ raise FatalException.new "Bad data source name: #{data_source_config['name']}. Only letters or digits allowed in data source name."
230
+ end
231
+
232
+ # create driver
233
+ driver_name = data_source_config['type'].split('_').collect!{ |w| w.capitalize }.join + 'Driver'
234
+ driver = Jekyll::Drivers.const_get(driver_name).new(data_source_config)
235
+
236
+ @data_sources[data_source_config['name']] = driver.load
237
+ end
238
+ end
239
+
217
240
  # Run each of the Generators.
218
241
  #
219
242
  # Returns nothing.
@@ -227,14 +250,11 @@ module Monad
227
250
  #
228
251
  # Returns nothing.
229
252
  def render
230
- payload = site_payload
231
- self.posts.each do |post|
232
- post.render(self.layouts, payload)
233
- end
253
+ relative_permalinks_deprecation_method
234
254
 
235
- self.pages.each do |page|
236
- relative_permalinks_deprecation_method if page.uses_relative_permalinks
237
- page.render(self.layouts, payload)
255
+ payload = site_payload
256
+ [self.posts, self.pages].flatten.each do |page_or_post|
257
+ page_or_post.render(self.layouts, payload)
238
258
  end
239
259
 
240
260
  self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a } }
@@ -247,62 +267,14 @@ module Monad
247
267
  #
248
268
  # Returns nothing.
249
269
  def cleanup
250
- # all files and directories in destination, including hidden ones
251
- dest_files = Set.new
252
- Dir.glob(File.join(self.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
253
- if self.keep_files.length > 0
254
- dest_files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
255
- else
256
- dest_files << file unless file =~ /\/\.{1,2}$/
257
- end
258
- end
259
-
260
- # files to be written
261
- files = Set.new
262
- self.posts.each do |post|
263
- files << post.destination(self.dest)
264
- end
265
- self.pages.each do |page|
266
- files << page.destination(self.dest)
267
- end
268
- self.static_files.each do |sf|
269
- files << sf.destination(self.dest)
270
- end
271
-
272
- # adding files' parent directories
273
- dirs = Set.new
274
- files.each { |file| dirs << File.dirname(file) }
275
- files.merge(dirs)
276
-
277
- obsolete_files = dest_files - files
278
- FileUtils.rm_rf(obsolete_files.to_a)
279
- end
280
-
281
- # Private: creates a regular expression from the keep_files array
282
- #
283
- # Examples
284
- # ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
285
- #
286
- # Returns the regular expression
287
- def keep_file_regex
288
- or_list = self.keep_files.join("|")
289
- pattern = "\/(#{or_list.gsub(".", "\.")})"
290
- Regexp.new pattern
270
+ site_cleaner.cleanup!
291
271
  end
292
272
 
293
273
  # Write static files, pages, and posts.
294
274
  #
295
275
  # Returns nothing.
296
276
  def write
297
- self.posts.each do |post|
298
- post.write(self.dest)
299
- end
300
- self.pages.each do |page|
301
- page.write(self.dest)
302
- end
303
- self.static_files.each do |sf|
304
- sf.write(self.dest)
305
- end
277
+ each_site_file { |item| item.write(self.dest) }
306
278
  end
307
279
 
308
280
  # Construct a Hash of Posts indexed by the specified Post attribute.
@@ -327,6 +299,14 @@ module Monad
327
299
  hash
328
300
  end
329
301
 
302
+ # Prepare site data for site payload. The method maintains backward compatibility
303
+ # if the key 'data' is already used in _config.yml.
304
+ #
305
+ # Returns the Hash to be hooked to site.data.
306
+ def site_data
307
+ self.config['data'] || self.data
308
+ end
309
+
330
310
  # The Hash payload containing site-wide data.
331
311
  #
332
312
  # Returns the Hash: { "site" => data } where data is a Hash with keys:
@@ -341,13 +321,15 @@ module Monad
341
321
  # "tags" - The Hash of tag values and Posts.
342
322
  # See Site#post_attr_hash for type info.
343
323
  def site_payload
344
- {"site" => self.data_sources.merge(self.config).merge({
324
+ {"jekyll" => { "version" => Jekyll::VERSION },
325
+ "site" => self.data_sources.merge(self.config).merge({
345
326
  "time" => self.time,
346
327
  "posts" => self.posts.sort { |a, b| b <=> a },
347
328
  "pages" => self.pages,
348
329
  "html_pages" => self.pages.reject { |page| !page.html? },
349
330
  "categories" => post_attr_hash('categories'),
350
- "tags" => post_attr_hash('tags')})}
331
+ "tags" => post_attr_hash('tags'),
332
+ "data" => site_data})}
351
333
  end
352
334
 
353
335
  # Filter out any files/directories that are hidden or backup files (start
@@ -423,33 +405,48 @@ module Monad
423
405
  end
424
406
 
425
407
  def relative_permalinks_deprecation_method
426
- if config['relative_permalinks'] && !@deprecated_relative_permalinks
408
+ if config['relative_permalinks'] && has_relative_page?
427
409
  $stderr.puts # Places newline after "Generating..."
428
- Monad::Logger.warn "Deprecation:", "Starting in 1.1, permalinks for pages" +
410
+ Jekyll.logger.warn "Deprecation:", "Starting in 1.1, permalinks for pages" +
429
411
  " in subfolders must be relative to the" +
430
412
  " site source directory, not the parent" +
431
- " directory. Check http://monadrb.com/docs/upgrading/"+
413
+ " directory. Check http://jekyllrb.com/docs/upgrading/"+
432
414
  " for more info."
433
- $stderr.print Monad::Logger.formatted_topic("") + "..." # for "done."
434
- @deprecated_relative_permalinks = true
415
+ $stderr.print Jekyll.logger.formatted_topic("") + "..." # for "done."
435
416
  end
436
417
  end
437
418
 
438
- # Load external data sources to @data_sources
439
- #
440
- # Returns nothing
441
- def load_data_sources
442
- self.config['data_sources'] && self.config['data_sources'].each do |data_source_config|
443
- if data_source_config['name'] !~ /^\w+$/
444
- raise FatalException.new "Bad data source name: #{data_source_config['name']}. Only letters or digits allowed in data source name."
419
+ def each_site_file
420
+ %w(posts pages static_files).each do |type|
421
+ self.send(type).each do |item|
422
+ yield item
445
423
  end
424
+ end
425
+ end
446
426
 
447
- # create driver
448
- driver_name = data_source_config['type'].split('_').collect!{ |w| w.capitalize }.join + 'Driver'
449
- driver = Monad::Drivers.const_get(driver_name).new(data_source_config)
427
+ private
450
428
 
451
- @data_sources[data_source_config['name']] = driver.load
452
- end
429
+ def has_relative_page?
430
+ self.pages.any? { |page| page.uses_relative_permalinks }
431
+ end
432
+
433
+ def has_yaml_header?(file)
434
+ "---" == File.open(file) { |fd| fd.read(3) }
435
+ end
436
+
437
+ def limit_posts!
438
+ limit = self.posts.length < limit_posts ? self.posts.length : limit_posts
439
+ self.posts = self.posts[-limit, limit]
440
+ end
441
+
442
+ def site_cleaner
443
+ @site_cleaner ||= Cleaner.new(self)
444
+ end
445
+
446
+ def sanitize_filename(name)
447
+ name = name.gsub(/[^\w\s_-]+/, '')
448
+ name = name.gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
449
+ name = name.gsub(/\s+/, '_')
453
450
  end
454
451
  end
455
452
  end
@@ -1,4 +1,4 @@
1
- module Monad
1
+ module Jekyll
2
2
  class StaticFile
3
3
  # The cache of last modification times [path] -> mtime.
4
4
  @@mtimes = Hash.new
@@ -0,0 +1,89 @@
1
+ module Jekyll
2
+ class Stevenson
3
+ attr_accessor :log_level
4
+
5
+ DEBUG = 0
6
+ INFO = 1
7
+ WARN = 2
8
+ ERROR = 3
9
+
10
+ # Public: Create a new instance of Stevenson, Jekyll's logger
11
+ #
12
+ # level - (optional, integer) the log level
13
+ #
14
+ # Returns nothing
15
+ def initialize(level = INFO)
16
+ @log_level = level
17
+ end
18
+
19
+ # Public: Print a jekyll debug message to stdout
20
+ #
21
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
22
+ # message - the message detail
23
+ #
24
+ # Returns nothing
25
+ def debug(topic, message = nil)
26
+ $stdout.puts(message(topic, message)) if log_level <= DEBUG
27
+ end
28
+
29
+ # Public: Print a jekyll message to stdout
30
+ #
31
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
32
+ # message - the message detail
33
+ #
34
+ # Returns nothing
35
+ def info(topic, message = nil)
36
+ $stdout.puts(message(topic, message)) if log_level <= INFO
37
+ end
38
+
39
+ # Public: Print a jekyll message to stderr
40
+ #
41
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
42
+ # message - the message detail
43
+ #
44
+ # Returns nothing
45
+ def warn(topic, message = nil)
46
+ $stderr.puts(message(topic, message).yellow) if log_level <= WARN
47
+ end
48
+
49
+ # Public: Print a jekyll error message to stderr
50
+ #
51
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
52
+ # message - the message detail
53
+ #
54
+ # Returns nothing
55
+ def error(topic, message = nil)
56
+ $stderr.puts(message(topic, message).red) if log_level <= ERROR
57
+ end
58
+
59
+ # Public: Print a Jekyll error message to stderr and immediately abort the process
60
+ #
61
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
62
+ # message - the message detail (can be omitted)
63
+ #
64
+ # Returns nothing
65
+ def abort_with(topic, message = nil)
66
+ error(topic, message)
67
+ abort
68
+ end
69
+
70
+ # Public: Build a Jekyll topic method
71
+ #
72
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
73
+ # message - the message detail
74
+ #
75
+ # Returns the formatted message
76
+ def message(topic, message)
77
+ formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ')
78
+ end
79
+
80
+ # Public: Format the topic
81
+ #
82
+ # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
83
+ #
84
+ # Returns the formatted topic statement
85
+ def formatted_topic(topic)
86
+ "#{topic} ".rjust(20)
87
+ end
88
+ end
89
+ end