sixones-jekyll 0.5.1 → 0.5.2

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 (45) hide show
  1. data/.gitignore +6 -0
  2. data/History.txt +28 -0
  3. data/README.textile +25 -529
  4. data/Rakefile +2 -2
  5. data/VERSION.yml +1 -1
  6. data/bin/jekyll +12 -2
  7. data/features/create_sites.feature +46 -0
  8. data/features/embed_filters.feature +60 -0
  9. data/features/pagination.feature +40 -0
  10. data/features/permalinks.feature +63 -0
  11. data/features/post_data.feature +153 -0
  12. data/features/site_configuration.feature +63 -0
  13. data/features/site_data.feature +82 -0
  14. data/features/step_definitions/jekyll_steps.rb +136 -0
  15. data/features/support/env.rb +16 -0
  16. data/jekyll.gemspec +134 -0
  17. data/lib/jekyll/albino.rb +4 -2
  18. data/lib/jekyll/convertible.rb +6 -4
  19. data/lib/jekyll/core_ext.rb +9 -1
  20. data/lib/jekyll/filters.rb +5 -1
  21. data/lib/jekyll/page.rb +58 -13
  22. data/lib/jekyll/pager.rb +45 -0
  23. data/lib/jekyll/post.rb +76 -30
  24. data/lib/jekyll/site.rb +44 -16
  25. data/lib/jekyll/tags/highlight.rb +2 -2
  26. data/lib/jekyll.rb +8 -6
  27. data/test/helper.rb +3 -0
  28. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  29. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  30. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  31. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  32. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  33. data/test/source/about.html +6 -0
  34. data/test/source/contacts.html +5 -0
  35. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  36. data/test/test_configuration.rb +29 -0
  37. data/test/test_filters.rb +8 -0
  38. data/test/test_generated_site.rb +7 -5
  39. data/test/test_page.rb +87 -0
  40. data/test/test_pager.rb +47 -0
  41. data/test/test_post.rb +160 -3
  42. data/test/test_site.rb +29 -1
  43. data/test/test_tags.rb +97 -16
  44. metadata +31 -6
  45. data/lib/jekyll/custom_filters.rb +0 -25
data/jekyll.gemspec ADDED
@@ -0,0 +1,134 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{jekyll}
5
+ s.version = "0.5.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Tom Preston-Werner"]
9
+ s.date = %q{2009-06-24}
10
+ s.default_executable = %q{jekyll}
11
+ s.description = %q{Jekyll is a simple, blog aware, static site generator.}
12
+ s.email = %q{tom@mojombo.com}
13
+ s.executables = ["jekyll"]
14
+ s.extra_rdoc_files = [
15
+ "README.textile"
16
+ ]
17
+ s.files = [
18
+ ".gitignore",
19
+ "History.txt",
20
+ "README.textile",
21
+ "Rakefile",
22
+ "VERSION.yml",
23
+ "bin/jekyll",
24
+ "features/create_sites.feature",
25
+ "features/embed_filters.feature",
26
+ "features/pagination.feature",
27
+ "features/permalinks.feature",
28
+ "features/post_data.feature",
29
+ "features/site_configuration.feature",
30
+ "features/site_data.feature",
31
+ "features/step_definitions/jekyll_steps.rb",
32
+ "features/support/env.rb",
33
+ "jekyll.gemspec",
34
+ "lib/jekyll.rb",
35
+ "lib/jekyll/albino.rb",
36
+ "lib/jekyll/converters/csv.rb",
37
+ "lib/jekyll/converters/mephisto.rb",
38
+ "lib/jekyll/converters/mt.rb",
39
+ "lib/jekyll/converters/textpattern.rb",
40
+ "lib/jekyll/converters/typo.rb",
41
+ "lib/jekyll/converters/wordpress.rb",
42
+ "lib/jekyll/convertible.rb",
43
+ "lib/jekyll/core_ext.rb",
44
+ "lib/jekyll/filters.rb",
45
+ "lib/jekyll/layout.rb",
46
+ "lib/jekyll/page.rb",
47
+ "lib/jekyll/pager.rb",
48
+ "lib/jekyll/post.rb",
49
+ "lib/jekyll/site.rb",
50
+ "lib/jekyll/tags/highlight.rb",
51
+ "lib/jekyll/tags/include.rb",
52
+ "test/helper.rb",
53
+ "test/source/_includes/sig.markdown",
54
+ "test/source/_layouts/default.html",
55
+ "test/source/_layouts/simple.html",
56
+ "test/source/_posts/2008-02-02-not-published.textile",
57
+ "test/source/_posts/2008-02-02-published.textile",
58
+ "test/source/_posts/2008-10-18-foo-bar.textile",
59
+ "test/source/_posts/2008-11-21-complex.textile",
60
+ "test/source/_posts/2008-12-03-permalinked-post.textile",
61
+ "test/source/_posts/2008-12-13-include.markdown",
62
+ "test/source/_posts/2009-01-27-array-categories.textile",
63
+ "test/source/_posts/2009-01-27-categories.textile",
64
+ "test/source/_posts/2009-01-27-category.textile",
65
+ "test/source/_posts/2009-03-12-hash-#1.markdown",
66
+ "test/source/_posts/2009-05-18-tag.textile",
67
+ "test/source/_posts/2009-05-18-tags.textile",
68
+ "test/source/_posts/2009-06-22-empty-yaml.textile",
69
+ "test/source/_posts/2009-06-22-no-yaml.textile",
70
+ "test/source/about.html",
71
+ "test/source/category/_posts/2008-9-23-categories.textile",
72
+ "test/source/contacts.html",
73
+ "test/source/css/screen.css",
74
+ "test/source/foo/_posts/bar/2008-12-12-topical-post.textile",
75
+ "test/source/index.html",
76
+ "test/source/win/_posts/2009-05-24-yaml-linebreak.markdown",
77
+ "test/source/z_category/_posts/2008-9-23-categories.textile",
78
+ "test/suite.rb",
79
+ "test/test_configuration.rb",
80
+ "test/test_filters.rb",
81
+ "test/test_generated_site.rb",
82
+ "test/test_page.rb",
83
+ "test/test_pager.rb",
84
+ "test/test_post.rb",
85
+ "test/test_site.rb",
86
+ "test/test_tags.rb"
87
+ ]
88
+ s.homepage = %q{http://github.com/mojombo/jekyll}
89
+ s.rdoc_options = ["--charset=UTF-8"]
90
+ s.require_paths = ["lib"]
91
+ s.rubyforge_project = %q{jekyll}
92
+ s.rubygems_version = %q{1.3.4}
93
+ s.summary = %q{Jekyll is a simple, blog aware, static site generator.}
94
+ s.test_files = [
95
+ "test/helper.rb",
96
+ "test/suite.rb",
97
+ "test/test_configuration.rb",
98
+ "test/test_filters.rb",
99
+ "test/test_generated_site.rb",
100
+ "test/test_page.rb",
101
+ "test/test_pager.rb",
102
+ "test/test_post.rb",
103
+ "test/test_site.rb",
104
+ "test/test_tags.rb"
105
+ ]
106
+
107
+ if s.respond_to? :specification_version then
108
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
109
+ s.specification_version = 3
110
+
111
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
112
+ s.add_runtime_dependency(%q<RedCloth>, [">= 4.2.1"])
113
+ s.add_runtime_dependency(%q<liquid>, [">= 1.9.0"])
114
+ s.add_runtime_dependency(%q<classifier>, [">= 1.3.1"])
115
+ s.add_runtime_dependency(%q<maruku>, [">= 0.5.9"])
116
+ s.add_runtime_dependency(%q<directory_watcher>, [">= 1.1.1"])
117
+ s.add_runtime_dependency(%q<open4>, [">= 0.9.6"])
118
+ else
119
+ s.add_dependency(%q<RedCloth>, [">= 4.2.1"])
120
+ s.add_dependency(%q<liquid>, [">= 1.9.0"])
121
+ s.add_dependency(%q<classifier>, [">= 1.3.1"])
122
+ s.add_dependency(%q<maruku>, [">= 0.5.9"])
123
+ s.add_dependency(%q<directory_watcher>, [">= 1.1.1"])
124
+ s.add_dependency(%q<open4>, [">= 0.9.6"])
125
+ end
126
+ else
127
+ s.add_dependency(%q<RedCloth>, [">= 4.2.1"])
128
+ s.add_dependency(%q<liquid>, [">= 1.9.0"])
129
+ s.add_dependency(%q<classifier>, [">= 1.3.1"])
130
+ s.add_dependency(%q<maruku>, [">= 0.5.9"])
131
+ s.add_dependency(%q<directory_watcher>, [">= 1.1.1"])
132
+ s.add_dependency(%q<open4>, [">= 0.9.6"])
133
+ end
134
+ end
data/lib/jekyll/albino.rb CHANGED
@@ -56,7 +56,7 @@ class Albino
56
56
 
57
57
  def initialize(target, lexer = :text, format = :html)
58
58
  @target = File.exists?(target) ? File.read(target) : target rescue target
59
- @options = { :l => lexer, :f => format }
59
+ @options = { :l => lexer, :f => format, :O => 'encoding=utf-8' }
60
60
  end
61
61
 
62
62
  def execute(command)
@@ -71,7 +71,9 @@ class Albino
71
71
  end
72
72
 
73
73
  def colorize(options = {})
74
- execute @@bin + convert_options(options)
74
+ html = execute(@@bin + convert_options(options))
75
+ # Work around an RDiscount bug: http://gist.github.com/97682
76
+ html.to_s.sub(%r{</pre></div>\Z}, "</pre>\n</div>")
75
77
  end
76
78
  alias_method :to_s, :colorize
77
79
 
@@ -17,12 +17,14 @@ module Jekyll
17
17
  # Returns nothing
18
18
  def read_yaml(base, name)
19
19
  self.content = File.read(File.join(base, name))
20
-
21
- if self.content =~ /^(---\s*\n.*?)\n---\s*\n/m
22
- self.content = self.content[($1.size + 5)..-1]
23
-
20
+
21
+ if self.content =~ /^(---\s*\n.*?\n?)(---.*?\n)/m
22
+ self.content = self.content[($1.size + $2.size)..-1]
23
+
24
24
  self.data = YAML.load($1)
25
25
  end
26
+
27
+ self.data ||= {}
26
28
  end
27
29
 
28
30
  # Transform the contents based on the file extension.
@@ -19,4 +19,12 @@ class Hash
19
19
 
20
20
  target
21
21
  end
22
- end
22
+ end
23
+
24
+ # Thanks, ActiveSupport!
25
+ class Date
26
+ # Converts datetime to an appropriate format for use in XML
27
+ def xmlschema
28
+ strftime("%Y-%m-%dT%H:%M:%S%Z")
29
+ end if RUBY_VERSION < '1.9'
30
+ end
@@ -18,7 +18,11 @@ module Jekyll
18
18
  end
19
19
 
20
20
  def xml_escape(input)
21
- input.gsub("&", "&amp;").gsub("<", "&lt;").gsub(">", "&gt;")
21
+ CGI.escapeHTML(input)
22
+ end
23
+
24
+ def cgi_escape(input)
25
+ CGI::escape(input)
22
26
  end
23
27
 
24
28
  def number_of_words(input)
data/lib/jekyll/page.rb CHANGED
@@ -4,7 +4,7 @@ module Jekyll
4
4
  include Convertible
5
5
 
6
6
  attr_accessor :site
7
- attr_accessor :ext
7
+ attr_accessor :name, :ext, :basename
8
8
  attr_accessor :data, :content, :output
9
9
 
10
10
  # Initialize a new Page.
@@ -17,14 +17,47 @@ module Jekyll
17
17
  def initialize(site, base, dir, name)
18
18
  @site = site
19
19
  @base = base
20
- @dir = dir
20
+ @dir = dir
21
21
  @name = name
22
22
 
23
- self.data = {}
24
-
25
23
  self.process(name)
26
24
  self.read_yaml(File.join(base, dir), name)
27
- #self.transform
25
+ end
26
+
27
+ # The generated directory into which the page will be placed
28
+ # upon generation. This is derived from the permalink or, if
29
+ # permalink is absent, set to '/'
30
+ #
31
+ # Returns <String>
32
+ def dir
33
+ url[-1, 1] == '/' ? url : File.dirname(url)
34
+ end
35
+
36
+ # The full path and filename of the post.
37
+ # Defined in the YAML of the post body
38
+ # (Optional)
39
+ #
40
+ # Returns <String>
41
+ def permalink
42
+ self.data && self.data['permalink']
43
+ end
44
+
45
+ def template
46
+ if self.site.permalink_style == :pretty && !index?
47
+ "/:name/"
48
+ else
49
+ "/:name.html"
50
+ end
51
+ end
52
+
53
+ # The generated relative url of this page
54
+ # e.g. /about.html
55
+ #
56
+ # Returns <String>
57
+ def url
58
+ return permalink if permalink
59
+
60
+ @url ||= template.gsub(':name', basename)
28
61
  end
29
62
 
30
63
  # Extract information from the page filename
@@ -33,6 +66,7 @@ module Jekyll
33
66
  # Returns nothing
34
67
  def process(name)
35
68
  self.ext = File.extname(name)
69
+ self.basename = name.split('.')[0..-2].first
36
70
  end
37
71
 
38
72
  # Add any necessary layouts to this post
@@ -46,22 +80,33 @@ module Jekyll
46
80
  end
47
81
 
48
82
  # Write the generated page file to the destination directory.
49
- # +dest+ is the String path to the destination dir
83
+ # +dest_prefix+ is the String path to the destination dir
84
+ # +dest_suffix+ is a suffix path to the destination dir
50
85
  #
51
86
  # Returns nothing
52
- def write(dest)
53
- FileUtils.mkdir_p(File.join(dest, @dir))
87
+ def write(dest_prefix, dest_suffix = nil)
88
+ dest = File.join(dest_prefix, @dir)
89
+ dest = File.join(dest, dest_suffix) if dest_suffix
90
+ FileUtils.mkdir_p(dest)
54
91
 
55
- name = @name
56
- if self.ext != ""
57
- name = @name.split(".")[0..-2].join('.') + self.ext
92
+ # The url needs to be unescaped in order to preserve the correct filename
93
+ path = File.join(dest, CGI.unescape(self.url))
94
+ if self.url[/\.html$/].nil?
95
+ FileUtils.mkdir_p(path)
96
+ path = File.join(path, "index.html")
58
97
  end
59
98
 
60
- path = File.join(dest, @dir, name)
61
99
  File.open(path, 'w') do |f|
62
100
  f.write(self.output)
63
101
  end
64
102
  end
103
+
104
+ private
105
+
106
+ def index?
107
+ basename == 'index'
108
+ end
109
+
65
110
  end
66
111
 
67
- end
112
+ end
@@ -0,0 +1,45 @@
1
+ module Jekyll
2
+ class Pager
3
+ attr_reader :page, :per_page, :posts, :total_posts, :total_pages, :previous_page, :next_page
4
+
5
+ def self.calculate_pages(all_posts, per_page)
6
+ num_pages = all_posts.size / per_page.to_i
7
+ num_pages.abs + 1 if all_posts.size % per_page.to_i != 0
8
+ num_pages
9
+ end
10
+
11
+ def self.pagination_enabled?(config, file)
12
+ file == 'index.html' && !config['paginate'].nil?
13
+ end
14
+
15
+ def initialize(config, page, all_posts, num_pages = nil)
16
+ @page = page
17
+ @per_page = config['paginate'].to_i
18
+ @total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page)
19
+
20
+ if @page > @total_pages
21
+ raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}"
22
+ end
23
+
24
+ init = (@page - 1) * @per_page
25
+ offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1)
26
+
27
+ @total_posts = all_posts.size
28
+ @posts = all_posts[init..offset]
29
+ @previous_page = @page != 1 ? @page - 1 : nil
30
+ @next_page = @page != @total_pages ? @page + 1 : nil
31
+ end
32
+
33
+ def to_hash
34
+ {
35
+ 'page' => page,
36
+ 'per_page' => per_page,
37
+ 'posts' => posts,
38
+ 'total_posts' => total_posts,
39
+ 'total_pages' => total_pages,
40
+ 'previous_page' => previous_page,
41
+ 'next_page' => next_page
42
+ }
43
+ end
44
+ end
45
+ end
data/lib/jekyll/post.rb CHANGED
@@ -18,9 +18,12 @@ module Jekyll
18
18
  name =~ MATCHER
19
19
  end
20
20
 
21
- attr_accessor :site
22
- attr_accessor :date, :slug, :ext, :categories, :topics, :published
23
- attr_accessor :data, :content, :output
21
+ attr_accessor :site, :date, :slug, :ext, :published, :data, :content, :output, :tags
22
+ attr_writer :categories
23
+
24
+ def categories
25
+ @categories ||= []
26
+ end
24
27
 
25
28
  # Initialize this Post instance.
26
29
  # +site+ is the Site
@@ -35,10 +38,6 @@ module Jekyll
35
38
  @name = name
36
39
 
37
40
  self.categories = dir.split('/').reject { |x| x.empty? }
38
-
39
- parts = name.split('/')
40
- self.topics = parts.size > 1 ? parts[0..-2] : []
41
-
42
41
  self.process(name)
43
42
  self.read_yaml(@base, name)
44
43
 
@@ -48,6 +47,14 @@ module Jekyll
48
47
  self.published = true
49
48
  end
50
49
 
50
+ if self.data.has_key?("tag")
51
+ self.tags = [self.data["tag"]]
52
+ elsif self.data.has_key?("tags")
53
+ self.tags = self.data['tags']
54
+ else
55
+ self.tags = []
56
+ end
57
+
51
58
  if self.categories.empty?
52
59
  if self.data.has_key?('category')
53
60
  self.categories << self.data['category']
@@ -63,11 +70,15 @@ module Jekyll
63
70
  end
64
71
  end
65
72
 
66
- # Spaceship is based on Post#date
73
+ # Spaceship is based on Post#date, slug
67
74
  #
68
75
  # Returns -1, 0, 1
69
76
  def <=>(other)
70
- self.date <=> other.date
77
+ cmp = self.date <=> other.date
78
+ if 0 == cmp
79
+ cmp = self.slug <=> other.slug
80
+ end
81
+ return cmp
71
82
  end
72
83
 
73
84
  # Extract information from the post filename
@@ -88,16 +99,7 @@ module Jekyll
88
99
  #
89
100
  # Returns <String>
90
101
  def dir
91
- if permalink
92
- permalink.to_s.split("/")[0..-2].join("/") + '/'
93
- else
94
- prefix = self.categories.empty? ? '' : '/' + self.categories.join('/')
95
- if [:date, :pretty].include?(self.site.permalink_style)
96
- prefix + date.strftime("/%Y/%m/%d/")
97
- else
98
- prefix + '/'
99
- end
100
- end
102
+ File.dirname(url)
101
103
  end
102
104
 
103
105
  # The full path and filename of the post.
@@ -109,13 +111,35 @@ module Jekyll
109
111
  self.data && self.data['permalink']
110
112
  end
111
113
 
114
+ def template
115
+ case self.site.permalink_style
116
+ when :pretty
117
+ "/:categories/:year/:month/:day/:title/"
118
+ when :none
119
+ "/:categories/:title.html"
120
+ when :date
121
+ "/:categories/:year/:month/:day/:title.html"
122
+ else
123
+ self.site.permalink_style.to_s
124
+ end
125
+ end
126
+
112
127
  # The generated relative url of this post
113
128
  # e.g. /2008/11/05/my-awesome-post.html
114
129
  #
115
130
  # Returns <String>
116
131
  def url
117
- ext = self.site.permalink_style == :pretty ? '' : '.html'
118
- permalink || self.id + ext
132
+ return permalink if permalink
133
+
134
+ @url ||= {
135
+ "year" => date.strftime("%Y"),
136
+ "month" => date.strftime("%m"),
137
+ "day" => date.strftime("%d"),
138
+ "title" => CGI.escape(slug),
139
+ "categories" => categories.sort.join('/')
140
+ }.inject(template) { |result, token|
141
+ result.gsub(/:#{token.first}/, token.last)
142
+ }.gsub(/\/\//, "/")
119
143
  end
120
144
 
121
145
  # The UID for this post (useful in feeds)
@@ -123,7 +147,7 @@ module Jekyll
123
147
  #
124
148
  # Returns <String>
125
149
  def id
126
- self.dir + self.slug
150
+ File.join(self.dir, self.slug)
127
151
  end
128
152
 
129
153
  # Calculate related posts.
@@ -172,9 +196,10 @@ module Jekyll
172
196
  def write(dest)
173
197
  FileUtils.mkdir_p(File.join(dest, dir))
174
198
 
175
- path = File.join(dest, self.url)
199
+ # The url needs to be unescaped in order to preserve the correct filename
200
+ path = File.join(dest, CGI.unescape(self.url))
176
201
 
177
- if self.site.permalink_style == :pretty
202
+ if template[/\.html$/].nil?
178
203
  FileUtils.mkdir_p(path)
179
204
  path = File.join(path, "index.html")
180
205
  end
@@ -188,18 +213,39 @@ module Jekyll
188
213
  #
189
214
  # Returns <Hash>
190
215
  def to_liquid
191
- { "title" => self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '),
192
- "url" => self.url,
193
- "date" => self.date,
194
- "id" => self.id,
195
- "topics" => self.topics,
216
+ { "title" => self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '),
217
+ "url" => self.url,
218
+ "date" => self.date,
219
+ "id" => self.id,
196
220
  "categories" => self.categories,
197
- "content" => self.content }.deep_merge(self.data)
221
+ "next" => self.next,
222
+ "previous" => self.previous,
223
+ "tags" => self.tags,
224
+ "content" => self.content }.deep_merge(self.data)
198
225
  end
199
226
 
200
227
  def inspect
201
228
  "<Post: #{self.id}>"
202
229
  end
230
+
231
+ def next
232
+ pos = self.site.posts.index(self)
233
+
234
+ if pos && pos < self.site.posts.length-1
235
+ self.site.posts[pos+1]
236
+ else
237
+ nil
238
+ end
239
+ end
240
+
241
+ def previous
242
+ pos = self.site.posts.index(self)
243
+ if pos && pos > 0
244
+ self.site.posts[pos-1]
245
+ else
246
+ nil
247
+ end
248
+ end
203
249
  end
204
250
 
205
251
  end
data/lib/jekyll/site.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Jekyll
2
2
 
3
3
  class Site
4
- attr_accessor :config, :layouts, :posts, :categories
5
- attr_accessor :source, :dest, :lsi, :pygments, :permalink_style
4
+ attr_accessor :config, :layouts, :posts, :categories, :exclude,
5
+ :source, :dest, :lsi, :pygments, :permalink_style, :tags
6
6
 
7
7
  # Initialize the site
8
8
  # +config+ is a Hash containing site configurations details
@@ -16,6 +16,7 @@ module Jekyll
16
16
  self.lsi = config['lsi']
17
17
  self.pygments = config['pygments']
18
18
  self.permalink_style = config['permalink'].to_sym
19
+ self.exclude = config['exclude'] || []
19
20
 
20
21
  self.reset
21
22
  self.setup
@@ -24,7 +25,8 @@ module Jekyll
24
25
  def reset
25
26
  self.layouts = {}
26
27
  self.posts = []
27
- self.categories = Hash.new { |hash, key| hash[key] = Array.new }
28
+ self.categories = Hash.new { |hash, key| hash[key] = [] }
29
+ self.tags = Hash.new { |hash, key| hash[key] = [] }
28
30
  end
29
31
 
30
32
  def setup
@@ -41,7 +43,6 @@ module Jekyll
41
43
  RDiscount.new(content).to_html
42
44
  end
43
45
 
44
- puts 'Using rdiscount for Markdown'
45
46
  rescue LoadError
46
47
  puts 'You must have the rdiscount gem installed first'
47
48
  end
@@ -76,6 +77,8 @@ module Jekyll
76
77
  rescue LoadError
77
78
  puts "The maruku gem is required for markdown support!"
78
79
  end
80
+ else
81
+ raise "Invalid Markdown processor: '#{self.config['markdown']}' -- did you mean 'maruku' or 'rdiscount'?"
79
82
  end
80
83
 
81
84
  if self.config['custom_filters']
@@ -140,17 +143,20 @@ module Jekyll
140
143
  if post.published
141
144
  self.posts << post
142
145
  post.categories.each { |c| self.categories[c] << post }
146
+ post.tags.each { |c| self.tags[c] << post }
143
147
  end
144
148
  end
145
149
  end
146
150
 
151
+ self.posts.sort!
152
+
147
153
  # second pass renders each post now that full site payload is available
148
154
  self.posts.each do |post|
149
155
  post.render(self.layouts, site_payload)
150
156
  end
151
157
 
152
- self.posts.sort!
153
- self.categories.values.map { |cats| cats.sort! { |a, b| b <=> a} }
158
+ self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a} }
159
+ self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a} }
154
160
  rescue Errno::ENOENT => e
155
161
  # ignore missing layout dir
156
162
  end
@@ -185,11 +191,14 @@ module Jekyll
185
191
  directories.delete('_posts')
186
192
  read_posts(dir)
187
193
  end
194
+
188
195
  [directories, files].each do |entries|
189
196
  entries.each do |f|
190
197
  if File.directory?(File.join(base, f))
191
198
  next if self.dest.sub(/\/$/, '') == File.join(base, f)
192
199
  transform_pages(File.join(dir, f))
200
+ elsif Pager.pagination_enabled?(self.config, f)
201
+ paginate_posts(f, dir)
193
202
  else
194
203
  first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
195
204
 
@@ -224,15 +233,13 @@ module Jekyll
224
233
  #
225
234
  # Returns {"site" => {"time" => <Time>,
226
235
  # "posts" => [<Post>],
227
- # "categories" => [<Post>],
228
- # "topics" => [<Post>] }}
236
+ # "categories" => [<Post>]}
229
237
  def site_payload
230
- {"site" => {
231
- "time" => Time.now,
232
- "posts" => self.posts.sort { |a,b| b <=> a },
233
- "categories" => post_attr_hash('categories'),
234
- "topics" => post_attr_hash('topics')
235
- }}
238
+ {"site" => self.config.merge({
239
+ "time" => Time.now,
240
+ "posts" => self.posts.sort { |a,b| b <=> a },
241
+ "categories" => post_attr_hash('categories'),
242
+ "tags" => post_attr_hash('tags')})}
236
243
  end
237
244
 
238
245
  # Filter out any files/directories that are hidden or backup files (start
@@ -242,11 +249,32 @@ module Jekyll
242
249
  def filter_entries(entries)
243
250
  entries = entries.reject do |e|
244
251
  unless ['_posts', '.htaccess'].include?(e)
245
- # Reject backup/hidden
246
- ['.', '_', '#'].include?(e[0..0]) or e[-1..-1] == '~'
252
+ ['.', '_', '#'].include?(e[0..0]) || e[-1..-1] == '~' || self.exclude.include?(e)
247
253
  end
248
254
  end
249
255
  end
250
256
 
257
+ # Paginates the blog's posts. Renders the index.html file into paginated directories, ie: page2, page3...
258
+ # and adds more wite-wide data
259
+ #
260
+ # {"paginator" => { "page" => <Number>,
261
+ # "per_page" => <Number>,
262
+ # "posts" => [<Post>],
263
+ # "total_posts" => <Number>,
264
+ # "total_pages" => <Number>,
265
+ # "previous_page" => <Number>,
266
+ # "next_page" => <Number> }}
267
+ def paginate_posts(file, dir)
268
+ all_posts = self.posts.sort { |a,b| b <=> a }
269
+ pages = Pager.calculate_pages(all_posts, self.config['paginate'].to_i)
270
+ pages += 1
271
+ (1..pages).each do |num_page|
272
+ pager = Pager.new(self.config, num_page, all_posts, pages)
273
+ page = Page.new(self, self.source, dir, file)
274
+ page.render(self.layouts, site_payload.merge({'paginator' => pager.to_hash}))
275
+ suffix = "page#{num_page}" if num_page > 1
276
+ page.write(self.dest, suffix)
277
+ end
278
+ end
251
279
  end
252
280
  end