jekyll 0.5.7 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of jekyll might be problematic. Click here for more details.
- data/History.txt +88 -31
- data/LICENSE +21 -0
- data/README.textile +1 -9
- data/Rakefile +119 -51
- data/bin/jekyll +26 -2
- data/cucumber.yml +1 -0
- data/features/create_sites.feature +28 -10
- data/features/post_data.feature +7 -7
- data/features/site_configuration.feature +41 -1
- data/features/step_definitions/jekyll_steps.rb +13 -4
- data/jekyll.gemspec +125 -143
- data/lib/jekyll.rb +40 -20
- data/lib/jekyll/albino.rb +5 -7
- data/lib/jekyll/converter.rb +50 -0
- data/lib/jekyll/converters/identity.rb +22 -0
- data/lib/jekyll/converters/markdown.rb +77 -0
- data/lib/jekyll/converters/textile.rb +33 -0
- data/lib/jekyll/convertible.rb +18 -24
- data/lib/jekyll/errors.rb +6 -0
- data/lib/jekyll/generator.rb +7 -0
- data/lib/jekyll/generators/pagination.rb +87 -0
- data/lib/jekyll/{converters → migrators}/csv.rb +0 -0
- data/lib/jekyll/{converters → migrators}/mephisto.rb +0 -0
- data/lib/jekyll/{converters → migrators}/mt.rb +0 -0
- data/lib/jekyll/{converters → migrators}/textpattern.rb +0 -0
- data/lib/jekyll/{converters → migrators}/typo.rb +0 -0
- data/lib/jekyll/{converters → migrators}/wordpress.rb +1 -0
- data/lib/jekyll/page.rb +28 -11
- data/lib/jekyll/plugin.rb +76 -0
- data/lib/jekyll/post.rb +10 -8
- data/lib/jekyll/site.rb +40 -88
- data/lib/jekyll/static_file.rb +52 -4
- data/lib/jekyll/tags/highlight.rb +20 -9
- data/test/helper.rb +6 -0
- data/test/source/_posts/2010-01-09-date-override.textile +2 -0
- data/test/source/_posts/2010-01-09-time-override.textile +2 -0
- data/test/source/_posts/2010-01-09-timezone-override.textile +7 -0
- data/test/source/_posts/2010-01-16-override-data.textile +4 -0
- data/test/source/sitemap.xml +27 -18
- data/test/test_configuration.rb +1 -1
- data/test/test_generated_site.rb +1 -1
- data/test/test_post.rb +63 -12
- data/test/test_site.rb +69 -7
- data/test/test_tags.rb +6 -14
- metadata +156 -52
- data/.gitignore +0 -6
- data/VERSION.yml +0 -5
- data/lib/jekyll/pager.rb +0 -45
@@ -4,15 +4,28 @@ module Jekyll
|
|
4
4
|
include Liquid::StandardFilters
|
5
5
|
|
6
6
|
# we need a language, but the linenos argument is optional.
|
7
|
-
SYNTAX = /(\w+)\s?(
|
7
|
+
SYNTAX = /(\w+)\s?([\w\s=]+)*/
|
8
8
|
|
9
9
|
def initialize(tag_name, markup, tokens)
|
10
10
|
super
|
11
11
|
if markup =~ SYNTAX
|
12
12
|
@lang = $1
|
13
13
|
if defined? $2
|
14
|
+
tmp_options = {}
|
15
|
+
$2.split.each do |opt|
|
16
|
+
key, value = opt.split('=')
|
17
|
+
if value.nil?
|
18
|
+
if key == 'linenos'
|
19
|
+
value = 'inline'
|
20
|
+
else
|
21
|
+
value = true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
tmp_options[key] = value
|
25
|
+
end
|
26
|
+
tmp_options = tmp_options.to_a.collect { |opt| opt.join('=') }
|
14
27
|
# additional options to pass to Albino.
|
15
|
-
@options = { 'O' => '
|
28
|
+
@options = { 'O' => tmp_options.join(',') }
|
16
29
|
else
|
17
30
|
@options = {}
|
18
31
|
end
|
@@ -23,19 +36,17 @@ module Jekyll
|
|
23
36
|
|
24
37
|
def render(context)
|
25
38
|
if context.registers[:site].pygments
|
26
|
-
render_pygments(context, super.
|
39
|
+
render_pygments(context, super.join)
|
27
40
|
else
|
28
|
-
render_codehighlighter(context, super.
|
41
|
+
render_codehighlighter(context, super.join)
|
29
42
|
end
|
30
43
|
end
|
31
44
|
|
32
45
|
def render_pygments(context, code)
|
33
46
|
output = add_code_tags(Albino.new(code, @lang).to_s(@options), @lang)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
return "<notextile>" + output + "</notextile>"
|
38
|
-
end
|
47
|
+
output = context["pygments_prefix"] + output if context["pygments_prefix"]
|
48
|
+
output = output + context["pygments_suffix"] if context["pygments_suffix"]
|
49
|
+
output
|
39
50
|
end
|
40
51
|
|
41
52
|
def render_codehighlighter(context, code)
|
data/test/helper.rb
CHANGED
@@ -3,6 +3,9 @@ gem 'RedCloth', '>= 4.2.1'
|
|
3
3
|
|
4
4
|
require File.join(File.dirname(__FILE__), *%w[.. lib jekyll])
|
5
5
|
|
6
|
+
require 'RedCloth'
|
7
|
+
require 'rdiscount'
|
8
|
+
|
6
9
|
require 'test/unit'
|
7
10
|
require 'redgreen'
|
8
11
|
require 'shoulda'
|
@@ -10,6 +13,9 @@ require 'rr'
|
|
10
13
|
|
11
14
|
include Jekyll
|
12
15
|
|
16
|
+
# Send STDERR into the void to suppress program output messages
|
17
|
+
STDERR.reopen(test(?e, '/dev/null') ? '/dev/null' : 'NUL:')
|
18
|
+
|
13
19
|
class Test::Unit::TestCase
|
14
20
|
include RR::Adapters::TestUnit
|
15
21
|
|
data/test/source/sitemap.xml
CHANGED
@@ -2,22 +2,31 @@
|
|
2
2
|
layout: nil
|
3
3
|
---
|
4
4
|
<?xml version="1.0" encoding="UTF-8"?>
|
5
|
-
<urlset
|
6
|
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
7
|
-
|
5
|
+
<urlset
|
6
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
7
|
+
|
8
8
|
<url>
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
9
|
+
<loc>http://example.com</loc>
|
10
|
+
<lastmod>{{ site.time | date: "%Y-%m-%d" }}</lastmod>
|
11
|
+
<changefreq>daily</changefreq>
|
12
|
+
<priority>1.0</priority>
|
13
|
+
</url>
|
14
|
+
|
15
|
+
{% for post in site.posts %}
|
16
|
+
<url>
|
17
|
+
<loc>http://example.com{{ post.url }}/</loc>
|
18
|
+
<lastmod>{{ post.date | date: "%Y-%m-%d" }}</lastmod>
|
19
|
+
<changefreq>monthly</changefreq>
|
20
|
+
<priority>0.2</priority>
|
21
|
+
</url>
|
22
|
+
{% endfor %}
|
23
|
+
|
24
|
+
{% for page in site.html_pages %}
|
25
|
+
<url>
|
26
|
+
<loc>http://example.com{{ page.url }}</loc>
|
27
|
+
<lastmod>{{ site.time | date: "%Y-%m-%d" }}</lastmod>
|
28
|
+
{% if page.changefreq %}<changefreq>{{ page.changefreq }}</changefreq>{% endif %}
|
29
|
+
{% if page.priority %}<priority>{{ page.priority }}</priority>{% endif %}
|
30
|
+
</url>
|
31
|
+
{% endfor %}
|
32
|
+
</urlset>
|
data/test/test_configuration.rb
CHANGED
data/test/test_generated_site.rb
CHANGED
data/test/test_post.rb
CHANGED
@@ -18,10 +18,10 @@ class TestPost < Test::Unit::TestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
should "ensure valid posts are valid" do
|
21
|
-
assert Post.valid?("2008-
|
22
|
-
assert Post.valid?("foo/bar/2008-
|
21
|
+
assert Post.valid?("2008-09-09-foo-bar.textile")
|
22
|
+
assert Post.valid?("foo/bar/2008-09-09-foo-bar.textile")
|
23
23
|
|
24
|
-
assert !Post.valid?("lol2008-
|
24
|
+
assert !Post.valid?("lol2008-09-09-foo-bar.textile")
|
25
25
|
assert !Post.valid?("blah")
|
26
26
|
end
|
27
27
|
|
@@ -31,7 +31,7 @@ class TestPost < Test::Unit::TestCase
|
|
31
31
|
@post.site = @site
|
32
32
|
|
33
33
|
@real_file = "2008-10-18-foo-bar.textile"
|
34
|
-
@fake_file = "2008-
|
34
|
+
@fake_file = "2008-09-09-foo-bar.textile"
|
35
35
|
@source = source_dir('_posts')
|
36
36
|
end
|
37
37
|
|
@@ -39,17 +39,17 @@ class TestPost < Test::Unit::TestCase
|
|
39
39
|
@post.categories = []
|
40
40
|
@post.process(@fake_file)
|
41
41
|
|
42
|
-
assert_equal Time.parse("2008-
|
42
|
+
assert_equal Time.parse("2008-09-09"), @post.date
|
43
43
|
assert_equal "foo-bar", @post.slug
|
44
44
|
assert_equal ".textile", @post.ext
|
45
|
-
assert_equal "/2008/
|
46
|
-
assert_equal "/2008/
|
45
|
+
assert_equal "/2008/09/09", @post.dir
|
46
|
+
assert_equal "/2008/09/09/foo-bar", @post.id
|
47
47
|
end
|
48
48
|
|
49
49
|
should "create url based on date and title" do
|
50
50
|
@post.categories = []
|
51
51
|
@post.process(@fake_file)
|
52
|
-
assert_equal "/2008/
|
52
|
+
assert_equal "/2008/09/09/foo-bar.html", @post.url
|
53
53
|
end
|
54
54
|
|
55
55
|
should "CGI escape urls" do
|
@@ -106,7 +106,7 @@ class TestPost < Test::Unit::TestCase
|
|
106
106
|
|
107
107
|
should "process the url correctly" do
|
108
108
|
assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
|
109
|
-
assert_equal "/2008/
|
109
|
+
assert_equal "/2008/09/09/foo-bar.html", @post.url
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
@@ -118,7 +118,7 @@ class TestPost < Test::Unit::TestCase
|
|
118
118
|
|
119
119
|
should "process the url correctly" do
|
120
120
|
assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
|
121
|
-
assert_equal "/beer/2008/
|
121
|
+
assert_equal "/beer/2008/09/09/foo-bar.html", @post.url
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
@@ -131,7 +131,7 @@ class TestPost < Test::Unit::TestCase
|
|
131
131
|
|
132
132
|
should "process the url correctly" do
|
133
133
|
assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
|
134
|
-
assert_equal "/beer/
|
134
|
+
assert_equal "/food/beer/2008/09/09/foo-bar.html", @post.url
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
@@ -155,7 +155,18 @@ class TestPost < Test::Unit::TestCase
|
|
155
155
|
|
156
156
|
should "process the url correctly" do
|
157
157
|
assert_equal "/:categories/:year/:month/:day/:title/", @post.template
|
158
|
-
assert_equal "/2008/
|
158
|
+
assert_equal "/2008/09/09/foo-bar/", @post.url
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "with custom date permalink" do
|
163
|
+
setup do
|
164
|
+
@post.site.permalink_style = '/:categories/:year/:i_month/:i_day/:title/'
|
165
|
+
@post.process(@fake_file)
|
166
|
+
end
|
167
|
+
|
168
|
+
should "process the url correctly" do
|
169
|
+
assert_equal "/2008/9/9/foo-bar/", @post.url
|
159
170
|
end
|
160
171
|
end
|
161
172
|
|
@@ -227,12 +238,37 @@ class TestPost < Test::Unit::TestCase
|
|
227
238
|
|
228
239
|
should "recognize date in yaml" do
|
229
240
|
post = setup_post("2010-01-09-date-override.textile")
|
241
|
+
do_render(post)
|
242
|
+
assert_equal Time, post.date.class
|
243
|
+
assert_equal Time, post.to_liquid["date"].class
|
230
244
|
assert_equal "/2010/01/10/date-override.html", post.url
|
245
|
+
assert_equal "<p>Post with a front matter date</p>\n<p>10 Jan 2010</p>", post.output
|
231
246
|
end
|
232
247
|
|
233
248
|
should "recognize time in yaml" do
|
234
249
|
post = setup_post("2010-01-09-time-override.textile")
|
250
|
+
do_render(post)
|
251
|
+
assert_equal Time, post.date.class
|
252
|
+
assert_equal Time, post.to_liquid["date"].class
|
235
253
|
assert_equal "/2010/01/10/time-override.html", post.url
|
254
|
+
assert_equal "<p>Post with a front matter time</p>\n<p>10 Jan 2010</p>", post.output
|
255
|
+
end
|
256
|
+
|
257
|
+
should "recognize time with timezone in yaml" do
|
258
|
+
post = setup_post("2010-01-09-timezone-override.textile")
|
259
|
+
do_render(post)
|
260
|
+
assert_equal Time, post.date.class
|
261
|
+
assert_equal Time, post.to_liquid["date"].class
|
262
|
+
assert_equal "/2010/01/10/timezone-override.html", post.url
|
263
|
+
assert_equal "<p>Post with a front matter time with timezone</p>\n<p>10 Jan 2010</p>", post.output
|
264
|
+
end
|
265
|
+
|
266
|
+
should "to_liquid prioritizes post attributes over data" do
|
267
|
+
post = setup_post("2010-01-16-override-data.textile")
|
268
|
+
assert_equal Array, post.tags.class
|
269
|
+
assert_equal Array, post.to_liquid["tags"].class
|
270
|
+
assert_equal Time, post.date.class
|
271
|
+
assert_equal Time, post.to_liquid["date"].class
|
236
272
|
end
|
237
273
|
|
238
274
|
should "recognize category in yaml" do
|
@@ -333,6 +369,21 @@ class TestPost < Test::Unit::TestCase
|
|
333
369
|
|
334
370
|
assert_equal "<<< <hr />\n<p>Tom Preston-Werner github.com/mojombo</p>\n\n<p>This <em>is</em> cool</p> >>>", post.output
|
335
371
|
end
|
372
|
+
|
373
|
+
should "render date specified in front matter properly" do
|
374
|
+
post = setup_post("2010-01-09-date-override.textile")
|
375
|
+
do_render(post)
|
376
|
+
|
377
|
+
assert_equal "<p>Post with a front matter date</p>\n<p>10 Jan 2010</p>", post.output
|
378
|
+
end
|
379
|
+
|
380
|
+
should "render time specified in front matter properly" do
|
381
|
+
post = setup_post("2010-01-09-time-override.textile")
|
382
|
+
do_render(post)
|
383
|
+
|
384
|
+
assert_equal "<p>Post with a front matter time</p>\n<p>10 Jan 2010</p>", post.output
|
385
|
+
end
|
386
|
+
|
336
387
|
end
|
337
388
|
end
|
338
389
|
|
data/test/test_site.rb
CHANGED
@@ -22,6 +22,7 @@ class TestSite < Test::Unit::TestCase
|
|
22
22
|
before_tags = @site.tags.length
|
23
23
|
before_pages = @site.pages.length
|
24
24
|
before_static_files = @site.static_files.length
|
25
|
+
before_time = @site.time
|
25
26
|
|
26
27
|
@site.process
|
27
28
|
assert_equal before_posts, @site.posts.length
|
@@ -30,6 +31,65 @@ class TestSite < Test::Unit::TestCase
|
|
30
31
|
assert_equal before_tags, @site.tags.length
|
31
32
|
assert_equal before_pages, @site.pages.length
|
32
33
|
assert_equal before_static_files, @site.static_files.length
|
34
|
+
assert before_time <= @site.time
|
35
|
+
end
|
36
|
+
|
37
|
+
should "write only modified static files" do
|
38
|
+
clear_dest
|
39
|
+
StaticFile.reset_cache
|
40
|
+
|
41
|
+
@site.process
|
42
|
+
some_static_file = @site.static_files[0].path
|
43
|
+
dest = File.expand_path(@site.static_files[0].destination(@site.dest))
|
44
|
+
mtime1 = File.stat(dest).mtime.to_i # first run must generate dest file
|
45
|
+
|
46
|
+
# need to sleep because filesystem timestamps have best resolution in seconds
|
47
|
+
sleep 1
|
48
|
+
@site.process
|
49
|
+
mtime2 = File.stat(dest).mtime.to_i
|
50
|
+
assert_equal mtime1, mtime2
|
51
|
+
|
52
|
+
# simulate file modification by user
|
53
|
+
FileUtils.touch some_static_file
|
54
|
+
|
55
|
+
sleep 1
|
56
|
+
@site.process
|
57
|
+
mtime3 = File.stat(dest).mtime.to_i
|
58
|
+
assert_not_equal mtime2, mtime3 # must be regenerated!
|
59
|
+
|
60
|
+
sleep 1
|
61
|
+
@site.process
|
62
|
+
mtime4 = File.stat(dest).mtime.to_i
|
63
|
+
assert_equal mtime3, mtime4 # no modifications, so must be the same
|
64
|
+
end
|
65
|
+
|
66
|
+
should "write static files if not modified but missing in destination" do
|
67
|
+
clear_dest
|
68
|
+
StaticFile.reset_cache
|
69
|
+
|
70
|
+
@site.process
|
71
|
+
some_static_file = @site.static_files[0].path
|
72
|
+
dest = File.expand_path(@site.static_files[0].destination(@site.dest))
|
73
|
+
mtime1 = File.stat(dest).mtime.to_i # first run must generate dest file
|
74
|
+
|
75
|
+
# need to sleep because filesystem timestamps have best resolution in seconds
|
76
|
+
sleep 1
|
77
|
+
@site.process
|
78
|
+
mtime2 = File.stat(dest).mtime.to_i
|
79
|
+
assert_equal mtime1, mtime2
|
80
|
+
|
81
|
+
# simulate destination file deletion
|
82
|
+
File.unlink dest
|
83
|
+
|
84
|
+
sleep 1
|
85
|
+
@site.process
|
86
|
+
mtime3 = File.stat(dest).mtime.to_i
|
87
|
+
assert_not_equal mtime2, mtime3 # must be regenerated and differ!
|
88
|
+
|
89
|
+
sleep 1
|
90
|
+
@site.process
|
91
|
+
mtime4 = File.stat(dest).mtime.to_i
|
92
|
+
assert_equal mtime3, mtime4 # no modifications, so must be the same
|
33
93
|
end
|
34
94
|
|
35
95
|
should "read layouts" do
|
@@ -73,18 +133,20 @@ class TestSite < Test::Unit::TestCase
|
|
73
133
|
end
|
74
134
|
|
75
135
|
context 'with an invalid markdown processor in the configuration' do
|
76
|
-
|
77
|
-
should 'give a meaningful error message' do
|
136
|
+
should 'not throw an error at initialization time' do
|
78
137
|
bad_processor = 'not a processor name'
|
79
|
-
|
138
|
+
assert_nothing_raised do
|
80
139
|
Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor }))
|
81
|
-
flunk 'Invalid markdown processors should cause a failure on site creation'
|
82
|
-
rescue RuntimeError => e
|
83
|
-
assert e.to_s =~ /invalid|bad/i
|
84
|
-
assert e.to_s =~ %r{#{bad_processor}}
|
85
140
|
end
|
86
141
|
end
|
87
142
|
|
143
|
+
should 'throw FatalException at process time' do
|
144
|
+
bad_processor = 'not a processor name'
|
145
|
+
s = Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor }))
|
146
|
+
assert_raise Jekyll::FatalException do
|
147
|
+
s.process
|
148
|
+
end
|
149
|
+
end
|
88
150
|
end
|
89
151
|
|
90
152
|
end
|
data/test/test_tags.rb
CHANGED
@@ -2,26 +2,18 @@ require File.dirname(__FILE__) + '/helper'
|
|
2
2
|
|
3
3
|
class TestTags < Test::Unit::TestCase
|
4
4
|
|
5
|
-
def create_post(content, override = {},
|
5
|
+
def create_post(content, override = {}, converter_class = Jekyll::MarkdownConverter)
|
6
6
|
stub(Jekyll).configuration do
|
7
7
|
Jekyll::DEFAULTS.merge({'pygments' => true}).merge(override)
|
8
8
|
end
|
9
9
|
site = Site.new(Jekyll.configuration)
|
10
10
|
info = { :filters => [Jekyll::Filters], :registers => { :site => site } }
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
else
|
15
|
-
payload = {"content_type" => "textile"}
|
16
|
-
end
|
11
|
+
@converter = site.converters.find { |c| c.class == converter_class }
|
12
|
+
payload = { "pygments_prefix" => @converter.pygments_prefix,
|
13
|
+
"pygments_suffix" => @converter.pygments_suffix }
|
17
14
|
|
18
15
|
@result = Liquid::Template.parse(content).render(payload, info)
|
19
|
-
|
20
|
-
if markdown
|
21
|
-
@result = site.markdown(@result)
|
22
|
-
else
|
23
|
-
@result = site.textile(@result)
|
24
|
-
end
|
16
|
+
@result = @converter.convert(@result)
|
25
17
|
end
|
26
18
|
|
27
19
|
def fill_post(code, override = {})
|
@@ -82,7 +74,7 @@ CONTENT
|
|
82
74
|
|
83
75
|
context "using Textile" do
|
84
76
|
setup do
|
85
|
-
create_post(@content, {},
|
77
|
+
create_post(@content, {}, Jekyll::TextileConverter)
|
86
78
|
end
|
87
79
|
|
88
80
|
# Broken in RedCloth 4.1.9
|