sixones-jekyll 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
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