codeslinger-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.
- data/.gitignore +6 -0
- data/History.txt +17 -1
- data/README.textile +2 -1
- data/Rakefile +2 -2
- data/VERSION.yml +1 -1
- data/features/create_sites.feature +46 -0
- data/features/embed_filters.feature +60 -0
- data/features/pagination.feature +40 -0
- data/features/permalinks.feature +63 -0
- data/features/post_data.feature +153 -0
- data/features/site_configuration.feature +63 -0
- data/features/site_data.feature +82 -0
- data/features/step_definitions/jekyll_steps.rb +136 -0
- data/features/support/env.rb +16 -0
- data/jekyll.gemspec +134 -0
- data/lib/jekyll.rb +5 -4
- data/lib/jekyll/convertible.rb +6 -4
- data/lib/jekyll/core_ext.rb +9 -1
- data/lib/jekyll/page.rb +52 -10
- data/lib/jekyll/pager.rb +45 -0
- data/lib/jekyll/post.rb +24 -16
- data/lib/jekyll/site.rb +17 -16
- data/test/helper.rb +1 -1
- data/test/source/_posts/2009-05-18-tag.textile +6 -0
- data/test/source/_posts/2009-05-18-tags.textile +9 -0
- data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
- data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
- data/test/source/about.html +6 -0
- data/test/source/contacts.html +5 -0
- data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
- data/test/test_configuration.rb +29 -0
- data/test/test_generated_site.rb +7 -5
- data/test/test_page.rb +87 -0
- data/test/test_pager.rb +47 -0
- data/test/test_post.rb +37 -4
- data/test/test_site.rb +21 -1
- metadata +31 -6
data/lib/jekyll/pager.rb
ADDED
@@ -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,7 +18,7 @@ module Jekyll
|
|
18
18
|
name =~ MATCHER
|
19
19
|
end
|
20
20
|
|
21
|
-
attr_accessor :site, :date, :slug, :ext, :
|
21
|
+
attr_accessor :site, :date, :slug, :ext, :published, :data, :content, :output, :tags
|
22
22
|
attr_writer :categories
|
23
23
|
|
24
24
|
def categories
|
@@ -38,10 +38,6 @@ module Jekyll
|
|
38
38
|
@name = name
|
39
39
|
|
40
40
|
self.categories = dir.split('/').reject { |x| x.empty? }
|
41
|
-
|
42
|
-
parts = name.split('/')
|
43
|
-
self.topics = parts.size > 1 ? parts[0..-2] : []
|
44
|
-
|
45
41
|
self.process(name)
|
46
42
|
self.read_yaml(@base, name)
|
47
43
|
|
@@ -51,6 +47,14 @@ module Jekyll
|
|
51
47
|
self.published = true
|
52
48
|
end
|
53
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
|
+
|
54
58
|
if self.categories.empty?
|
55
59
|
if self.data.has_key?('category')
|
56
60
|
self.categories << self.data['category']
|
@@ -66,11 +70,15 @@ module Jekyll
|
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
69
|
-
# Spaceship is based on Post#date
|
73
|
+
# Spaceship is based on Post#date, slug
|
70
74
|
#
|
71
75
|
# Returns -1, 0, 1
|
72
76
|
def <=>(other)
|
73
|
-
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
|
74
82
|
end
|
75
83
|
|
76
84
|
# Extract information from the post filename
|
@@ -106,7 +114,7 @@ module Jekyll
|
|
106
114
|
def template
|
107
115
|
case self.site.permalink_style
|
108
116
|
when :pretty
|
109
|
-
"/:categories/:year/:month/:day/:title"
|
117
|
+
"/:categories/:year/:month/:day/:title/"
|
110
118
|
when :none
|
111
119
|
"/:categories/:title.html"
|
112
120
|
when :date
|
@@ -205,15 +213,15 @@ module Jekyll
|
|
205
213
|
#
|
206
214
|
# Returns <Hash>
|
207
215
|
def to_liquid
|
208
|
-
{ "title"
|
209
|
-
"url"
|
210
|
-
"date"
|
211
|
-
"id"
|
212
|
-
"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,
|
213
220
|
"categories" => self.categories,
|
214
|
-
"next"
|
215
|
-
"previous"
|
216
|
-
"
|
221
|
+
"next" => self.next,
|
222
|
+
"previous" => self.previous,
|
223
|
+
"tags" => self.tags,
|
224
|
+
"content" => self.content }.deep_merge(self.data)
|
217
225
|
end
|
218
226
|
|
219
227
|
def inspect
|
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, :exclude
|
5
|
-
|
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
|
@@ -25,7 +25,8 @@ module Jekyll
|
|
25
25
|
def reset
|
26
26
|
self.layouts = {}
|
27
27
|
self.posts = []
|
28
|
-
self.categories = Hash.new { |hash, key| hash[key] =
|
28
|
+
self.categories = Hash.new { |hash, key| hash[key] = [] }
|
29
|
+
self.tags = Hash.new { |hash, key| hash[key] = [] }
|
29
30
|
end
|
30
31
|
|
31
32
|
def setup
|
@@ -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
|
end
|
81
84
|
|
@@ -126,6 +129,7 @@ module Jekyll
|
|
126
129
|
if post.published
|
127
130
|
self.posts << post
|
128
131
|
post.categories.each { |c| self.categories[c] << post }
|
132
|
+
post.tags.each { |c| self.tags[c] << post }
|
129
133
|
end
|
130
134
|
end
|
131
135
|
end
|
@@ -137,7 +141,8 @@ module Jekyll
|
|
137
141
|
post.render(self.layouts, site_payload)
|
138
142
|
end
|
139
143
|
|
140
|
-
self.categories.values.map { |
|
144
|
+
self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a} }
|
145
|
+
self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a} }
|
141
146
|
rescue Errno::ENOENT => e
|
142
147
|
# ignore missing layout dir
|
143
148
|
end
|
@@ -214,15 +219,13 @@ module Jekyll
|
|
214
219
|
#
|
215
220
|
# Returns {"site" => {"time" => <Time>,
|
216
221
|
# "posts" => [<Post>],
|
217
|
-
# "categories" => [<Post>]
|
218
|
-
# "topics" => [<Post>] }}
|
222
|
+
# "categories" => [<Post>]}
|
219
223
|
def site_payload
|
220
|
-
{"site" => {
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
}}
|
224
|
+
{"site" => self.config.merge({
|
225
|
+
"time" => Time.now,
|
226
|
+
"posts" => self.posts.sort { |a,b| b <=> a },
|
227
|
+
"categories" => post_attr_hash('categories'),
|
228
|
+
"tags" => post_attr_hash('tags')})}
|
226
229
|
end
|
227
230
|
|
228
231
|
# Filter out any files/directories that are hidden or backup files (start
|
@@ -249,13 +252,11 @@ module Jekyll
|
|
249
252
|
# "next_page" => <Number> }}
|
250
253
|
def paginate_posts(file, dir)
|
251
254
|
all_posts = self.posts.sort { |a,b| b <=> a }
|
252
|
-
page = Page.new(self, self.source, dir, file)
|
253
|
-
|
254
255
|
pages = Pager.calculate_pages(all_posts, self.config['paginate'].to_i)
|
255
|
-
|
256
|
+
pages += 1
|
256
257
|
(1..pages).each do |num_page|
|
257
258
|
pager = Pager.new(self.config, num_page, all_posts, pages)
|
258
|
-
|
259
|
+
page = Page.new(self, self.source, dir, file)
|
259
260
|
page.render(self.layouts, site_payload.merge({'paginator' => pager.to_hash}))
|
260
261
|
suffix = "page#{num_page}" if num_page > 1
|
261
262
|
page.write(self.dest, suffix)
|
data/test/helper.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
No YAML.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestConfiguration < Test::Unit::TestCase
|
4
|
+
context "loading configuration" do
|
5
|
+
setup do
|
6
|
+
@path = './_config.yml'
|
7
|
+
end
|
8
|
+
|
9
|
+
should "fire warning with no _config.yml" do
|
10
|
+
mock(YAML).load_file(@path) { raise "No such file or directory - #{@path}" }
|
11
|
+
mock(STDERR).puts("WARNING: Could not read configuration. Using defaults (and options).")
|
12
|
+
mock(STDERR).puts("\tNo such file or directory - #{@path}")
|
13
|
+
assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
|
14
|
+
end
|
15
|
+
|
16
|
+
should "load configuration as hash" do
|
17
|
+
mock(YAML).load_file(@path) { Hash.new }
|
18
|
+
mock(STDOUT).puts("Configuration from #{@path}")
|
19
|
+
assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
|
20
|
+
end
|
21
|
+
|
22
|
+
should "fire warning with bad config" do
|
23
|
+
mock(YAML).load_file(@path) { Array.new }
|
24
|
+
mock(STDERR).puts("WARNING: Could not read configuration. Using defaults (and options).")
|
25
|
+
mock(STDERR).puts("\tInvalid configuration - #{@path}")
|
26
|
+
assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/test_generated_site.rb
CHANGED
@@ -17,11 +17,8 @@ class TestGeneratedSite < Test::Unit::TestCase
|
|
17
17
|
assert @index.include?("#{@site.posts.size} Posts")
|
18
18
|
end
|
19
19
|
|
20
|
-
should "render post
|
21
|
-
|
22
|
-
post = Post.new(@site, source_dir, '', File.basename(latest_post))
|
23
|
-
post.transform
|
24
|
-
assert @index.include?(post.content)
|
20
|
+
should "render latest post's content" do
|
21
|
+
assert @index.include?(@site.posts.last.content)
|
25
22
|
end
|
26
23
|
|
27
24
|
should "hide unpublished posts" do
|
@@ -34,5 +31,10 @@ class TestGeneratedSite < Test::Unit::TestCase
|
|
34
31
|
should "not copy _posts directory" do
|
35
32
|
assert !File.exist?(dest_dir('_posts'))
|
36
33
|
end
|
34
|
+
|
35
|
+
should "process other static files and generate correct permalinks" do
|
36
|
+
assert File.exists?(dest_dir('/about/index.html'))
|
37
|
+
assert File.exists?(dest_dir('/contacts.html'))
|
38
|
+
end
|
37
39
|
end
|
38
40
|
end
|
data/test/test_page.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestPage < Test::Unit::TestCase
|
4
|
+
def setup_page(file)
|
5
|
+
@page = Page.new(@site, source_dir, '', file)
|
6
|
+
end
|
7
|
+
|
8
|
+
def do_render(page)
|
9
|
+
layouts = { "default" => Layout.new(@site, source_dir('_layouts'), "simple.html")}
|
10
|
+
page.render(layouts, {"site" => {"posts" => []}})
|
11
|
+
end
|
12
|
+
|
13
|
+
context "A Page" do
|
14
|
+
setup do
|
15
|
+
clear_dest
|
16
|
+
stub(Jekyll).configuration { Jekyll::DEFAULTS }
|
17
|
+
@site = Site.new(Jekyll.configuration)
|
18
|
+
end
|
19
|
+
|
20
|
+
context "processing pages" do
|
21
|
+
should "create url based on filename" do
|
22
|
+
@page = setup_page('contacts.html')
|
23
|
+
assert_equal "/contacts.html", @page.url
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with pretty url style" do
|
27
|
+
setup do
|
28
|
+
@site.permalink_style = :pretty
|
29
|
+
end
|
30
|
+
|
31
|
+
should "return dir correctly" do
|
32
|
+
@page = setup_page('contacts.html')
|
33
|
+
assert_equal '/contacts/', @page.dir
|
34
|
+
end
|
35
|
+
|
36
|
+
should "return dir correctly for index page" do
|
37
|
+
@page = setup_page('index.html')
|
38
|
+
assert_equal '/', @page.dir
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with any other url style" do
|
43
|
+
should "return dir correctly" do
|
44
|
+
@site.permalink_style = nil
|
45
|
+
@page = setup_page('contacts.html')
|
46
|
+
assert_equal '/', @page.dir
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
should "respect permalink in yaml front matter" do
|
51
|
+
file = "about.html"
|
52
|
+
@page = setup_page(file)
|
53
|
+
|
54
|
+
assert_equal "/about/", @page.permalink
|
55
|
+
assert_equal @page.permalink, @page.url
|
56
|
+
assert_equal "/about/", @page.dir
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "rendering" do
|
61
|
+
setup do
|
62
|
+
clear_dest
|
63
|
+
end
|
64
|
+
|
65
|
+
should "write properly" do
|
66
|
+
page = setup_page('contacts.html')
|
67
|
+
do_render(page)
|
68
|
+
page.write(dest_dir)
|
69
|
+
|
70
|
+
assert File.directory?(dest_dir)
|
71
|
+
assert File.exists?(File.join(dest_dir, 'contacts.html'))
|
72
|
+
end
|
73
|
+
|
74
|
+
should "write properly without html extension" do
|
75
|
+
page = setup_page('contacts.html')
|
76
|
+
page.site.permalink_style = :pretty
|
77
|
+
do_render(page)
|
78
|
+
page.write(dest_dir)
|
79
|
+
|
80
|
+
assert File.directory?(dest_dir)
|
81
|
+
assert File.exists?(File.join(dest_dir, 'contacts', 'index.html'))
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/test/test_pager.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestPager < Test::Unit::TestCase
|
4
|
+
context "pagination enabled" do
|
5
|
+
setup do
|
6
|
+
stub(Jekyll).configuration do
|
7
|
+
Jekyll::DEFAULTS.merge({
|
8
|
+
'source' => source_dir,
|
9
|
+
'destination' => dest_dir,
|
10
|
+
'paginate' => 2
|
11
|
+
})
|
12
|
+
end
|
13
|
+
|
14
|
+
@config = Jekyll.configuration
|
15
|
+
@site = Site.new(@config)
|
16
|
+
@posts = @site.read_posts('')
|
17
|
+
end
|
18
|
+
|
19
|
+
should "calculate number of pages" do
|
20
|
+
assert_equal(2, Pager.calculate_pages(@posts, @config['paginate']))
|
21
|
+
end
|
22
|
+
|
23
|
+
should "create first pager" do
|
24
|
+
pager = Pager.new(@config, 1, @posts)
|
25
|
+
assert_equal(@config['paginate'].to_i, pager.posts.size)
|
26
|
+
assert_equal(2, pager.total_pages)
|
27
|
+
assert_nil(pager.previous_page)
|
28
|
+
assert_equal(2, pager.next_page)
|
29
|
+
end
|
30
|
+
|
31
|
+
should "create second pager" do
|
32
|
+
pager = Pager.new(@config, 2, @posts)
|
33
|
+
assert_equal(@posts.size - @config['paginate'].to_i, pager.posts.size)
|
34
|
+
assert_equal(2, pager.total_pages)
|
35
|
+
assert_equal(1, pager.previous_page)
|
36
|
+
assert_nil(pager.next_page)
|
37
|
+
end
|
38
|
+
|
39
|
+
should "not create third pager" do
|
40
|
+
assert_raise(RuntimeError) { Pager.new(@config, 3, @posts) }
|
41
|
+
end
|
42
|
+
|
43
|
+
should "report that pagination is enabled" do
|
44
|
+
assert Pager.pagination_enabled?(@config, 'index.html')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|