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
@@ -30,9 +30,9 @@ module Jekyll
30
30
  end
31
31
 
32
32
  def render_pygments(context, code)
33
- if context["content_type"] == :markdown
33
+ if context["content_type"] == "markdown"
34
34
  return "\n" + Albino.new(code, @lang).to_s(@options) + "\n"
35
- elsif context["content_type"] == :textile
35
+ elsif context["content_type"] == "textile"
36
36
  return "<notextile>" + Albino.new(code, @lang).to_s(@options) + "</notextile>"
37
37
  else
38
38
  return Albino.new(code, @lang).to_s(@options)
data/lib/jekyll.rb CHANGED
@@ -16,6 +16,7 @@ require 'redcloth'
16
16
 
17
17
  # internal requires
18
18
  require 'jekyll/core_ext'
19
+ require 'jekyll/pager'
19
20
  require 'jekyll/site'
20
21
  require 'jekyll/convertible'
21
22
  require 'jekyll/custom_filters'
@@ -28,7 +29,7 @@ require 'jekyll/tags/include'
28
29
  require 'jekyll/albino'
29
30
 
30
31
  module Jekyll
31
- # Default options. Overriden by values in _config.yaml or command-line opts.
32
+ # Default options. Overriden by values in _config.yml or command-line opts.
32
33
  # (Strings rather symbols used for compatability with YAML)
33
34
  DEFAULTS = {
34
35
  'auto' => false,
@@ -63,15 +64,16 @@ module Jekyll
63
64
  # then, we need to know where to look for _config.yml
64
65
  source = override['source'] || Jekyll::DEFAULTS['source']
65
66
 
66
- # Get configuration from <source>/_config.yaml
67
- config = {}
67
+ # Get configuration from <source>/_config.yml
68
68
  config_file = File.join(source, '_config.yml')
69
69
  begin
70
70
  config = YAML.load_file(config_file)
71
- puts "Configuration from #{config_file}"
71
+ raise "Invalid configuration - #{config_file}" if !config.is_a?(Hash)
72
+ STDOUT.puts "Configuration from #{config_file}"
72
73
  rescue => err
73
- puts "WARNING: Could not read configuration. Using defaults (and options)."
74
- puts "\t" + err
74
+ STDERR.puts "WARNING: Could not read configuration. Using defaults (and options)."
75
+ STDERR.puts "\t" + err.to_s
76
+ config = {}
75
77
  end
76
78
 
77
79
  # Merge DEFAULTS < _config.yml < override
data/test/helper.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'rubygems'
2
+ gem 'RedCloth', '= 4.2.1'
3
+
1
4
  require File.join(File.dirname(__FILE__), *%w[.. lib jekyll])
2
5
 
3
6
  require 'test/unit'
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Hash #1
4
+ ---
5
+
6
+ Hashes are nice
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: A Tag
3
+ tag: code
4
+ ---
5
+
6
+ Whoa.
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: Some Tags
3
+ tags:
4
+ - food
5
+ - cooking
6
+ - pizza
7
+ ---
8
+
9
+ Awesome!
@@ -0,0 +1,3 @@
1
+ ---
2
+ ---
3
+ Empty YAML.
@@ -0,0 +1 @@
1
+ No YAML.
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: About
3
+ permalink: /about/
4
+ ---
5
+
6
+ About the site
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Contact Information
3
+ ---
4
+
5
+ Contact Information
@@ -0,0 +1,7 @@
1
+ ---
2
+ layout: post
3
+ title: "Test title"
4
+ tag: "Ruby"
5
+ ---
6
+
7
+ This is the content
@@ -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_filters.rb CHANGED
@@ -37,5 +37,13 @@ class TestFilters < Test::Unit::TestCase
37
37
  assert_equal "AT&amp;T", @filter.xml_escape("AT&T")
38
38
  assert_equal "&lt;code&gt;command &amp;lt;filename&amp;gt;&lt;/code&gt;", @filter.xml_escape("<code>command &lt;filename&gt;</code>")
39
39
  end
40
+
41
+ should "escape space as plus" do
42
+ assert_equal "my+things", @filter.cgi_escape("my things")
43
+ end
44
+
45
+ should "escape special characters" do
46
+ assert_equal "hey%21", @filter.cgi_escape("hey!")
47
+ end
40
48
  end
41
49
  end
@@ -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.content" do
21
- latest_post = Dir[source_dir('_posts', '*')].last
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
@@ -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
data/test/test_post.rb CHANGED
@@ -41,6 +41,8 @@ class TestPost < Test::Unit::TestCase
41
41
  assert_equal Time.parse("2008-10-19"), @post.date
42
42
  assert_equal "foo-bar", @post.slug
43
43
  assert_equal ".textile", @post.ext
44
+ assert_equal "/2008/10/19", @post.dir
45
+ assert_equal "/2008/10/19/foo-bar", @post.id
44
46
  end
45
47
 
46
48
  should "create url based on date and title" do
@@ -49,16 +51,114 @@ class TestPost < Test::Unit::TestCase
49
51
  assert_equal "/2008/10/19/foo-bar.html", @post.url
50
52
  end
51
53
 
52
- should "respect permalink" do
54
+ should "CGI escape urls" do
55
+ @post.categories = []
56
+ @post.process("2009-03-12-hash-#1.markdown")
57
+ assert_equal "/2009/03/12/hash-%231.html", @post.url
58
+ assert_equal "/2009/03/12/hash-#1", @post.id
59
+ end
60
+
61
+ should "respect permalink in yaml front matter" do
53
62
  file = "2008-12-03-permalinked-post.textile"
54
63
  @post.process(file)
55
64
  @post.read_yaml(@source, file)
56
65
 
57
66
  assert_equal "my_category/permalinked-post", @post.permalink
58
- assert_equal "my_category/", @post.dir
67
+ assert_equal "my_category", @post.dir
59
68
  assert_equal "my_category/permalinked-post", @post.url
60
69
  end
61
70
 
71
+ context "with CRLF linebreaks" do
72
+ setup do
73
+ @real_file = "2009-05-24-yaml-linebreak.markdown"
74
+ @source = source_dir('win/_posts')
75
+ end
76
+ should "read yaml front-matter" do
77
+ @post.read_yaml(@source, @real_file)
78
+
79
+ assert_equal({"title" => "Test title", "layout" => "post", "tag" => "Ruby"}, @post.data)
80
+ assert_equal "\r\nThis is the content", @post.content
81
+ end
82
+ end
83
+
84
+ context "with site wide permalink" do
85
+ setup do
86
+ @post.categories = []
87
+ end
88
+
89
+ context "with unspecified (date) style" do
90
+ setup do
91
+ @post.process(@fake_file)
92
+ end
93
+
94
+ should "process the url correctly" do
95
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
96
+ assert_equal "/2008/10/19/foo-bar.html", @post.url
97
+ end
98
+ end
99
+
100
+ context "with unspecified (date) style and a category" do
101
+ setup do
102
+ @post.categories << "beer"
103
+ @post.process(@fake_file)
104
+ end
105
+
106
+ should "process the url correctly" do
107
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
108
+ assert_equal "/beer/2008/10/19/foo-bar.html", @post.url
109
+ end
110
+ end
111
+
112
+ context "with unspecified (date) style and categories" do
113
+ setup do
114
+ @post.categories << "food"
115
+ @post.categories << "beer"
116
+ @post.process(@fake_file)
117
+ end
118
+
119
+ should "process the url correctly" do
120
+ assert_equal "/:categories/:year/:month/:day/:title.html", @post.template
121
+ assert_equal "/beer/food/2008/10/19/foo-bar.html", @post.url
122
+ end
123
+ end
124
+
125
+ context "with none style" do
126
+ setup do
127
+ @post.site.permalink_style = :none
128
+ @post.process(@fake_file)
129
+ end
130
+
131
+ should "process the url correctly" do
132
+ assert_equal "/:categories/:title.html", @post.template
133
+ assert_equal "/foo-bar.html", @post.url
134
+ end
135
+ end
136
+
137
+ context "with pretty style" do
138
+ setup do
139
+ @post.site.permalink_style = :pretty
140
+ @post.process(@fake_file)
141
+ end
142
+
143
+ should "process the url correctly" do
144
+ assert_equal "/:categories/:year/:month/:day/:title/", @post.template
145
+ assert_equal "/2008/10/19/foo-bar/", @post.url
146
+ end
147
+ end
148
+
149
+ context "with prefix style and no extension" do
150
+ setup do
151
+ @post.site.permalink_style = "/prefix/:title"
152
+ @post.process(@fake_file)
153
+ end
154
+
155
+ should "process the url correctly" do
156
+ assert_equal "/prefix/:title", @post.template
157
+ assert_equal "/prefix/foo-bar", @post.url
158
+ end
159
+ end
160
+ end
161
+
62
162
  should "read yaml front-matter" do
63
163
  @post.read_yaml(@source, @real_file)
64
164
 
@@ -75,6 +175,32 @@ class TestPost < Test::Unit::TestCase
75
175
  end
76
176
  end
77
177
 
178
+ context "when in a site" do
179
+ setup do
180
+ clear_dest
181
+ stub(Jekyll).configuration { Jekyll::DEFAULTS }
182
+ @site = Site.new(Jekyll.configuration)
183
+ @site.posts = [setup_post('2008-02-02-published.textile'),
184
+ setup_post('2009-01-27-categories.textile')]
185
+ end
186
+
187
+ should "have next post" do
188
+ assert_equal(@site.posts.last, @site.posts.first.next)
189
+ end
190
+
191
+ should "have previous post" do
192
+ assert_equal(@site.posts.first, @site.posts.last.previous)
193
+ end
194
+
195
+ should "not have previous post if first" do
196
+ assert_equal(nil, @site.posts.first.previous)
197
+ end
198
+
199
+ should "not have next post if last" do
200
+ assert_equal(nil, @site.posts.last.next)
201
+ end
202
+ end
203
+
78
204
  context "initializing posts" do
79
205
  should "publish when published yaml is no specified" do
80
206
  post = setup_post("2008-02-02-published.textile")
@@ -98,6 +224,28 @@ class TestPost < Test::Unit::TestCase
98
224
  assert post.categories.include?('baz')
99
225
  end
100
226
 
227
+ should "recognize tag in yaml" do
228
+ post = setup_post("2009-05-18-tag.textile")
229
+ assert post.tags.include?('code')
230
+ end
231
+
232
+ should "recognize tags in yaml" do
233
+ post = setup_post("2009-05-18-tags.textile")
234
+ assert post.tags.include?('food')
235
+ assert post.tags.include?('cooking')
236
+ assert post.tags.include?('pizza')
237
+ end
238
+
239
+ should "allow no yaml" do
240
+ post = setup_post("2009-06-22-no-yaml.textile")
241
+ assert_equal "No YAML.", post.content
242
+ end
243
+
244
+ should "allow empty yaml" do
245
+ post = setup_post("2009-06-22-empty-yaml.textile")
246
+ assert_equal "Empty YAML.", post.content
247
+ end
248
+
101
249
  context "rendering" do
102
250
  setup do
103
251
  clear_dest
@@ -118,6 +266,16 @@ class TestPost < Test::Unit::TestCase
118
266
  assert File.exists?(File.join(dest_dir, '2008', '10', '18', 'foo-bar.html'))
119
267
  end
120
268
 
269
+ should "write properly without html extension" do
270
+ post = setup_post("2008-10-18-foo-bar.textile")
271
+ post.site.permalink_style = ":title"
272
+ do_render(post)
273
+ post.write(dest_dir)
274
+
275
+ assert File.directory?(dest_dir)
276
+ assert File.exists?(File.join(dest_dir, 'foo-bar', 'index.html'))
277
+ end
278
+
121
279
  should "insert data" do
122
280
  post = setup_post("2008-11-21-complex.textile")
123
281
  do_render(post)
@@ -138,7 +296,6 @@ class TestPost < Test::Unit::TestCase
138
296
  should "generate categories and topics" do
139
297
  post = Post.new(@site, File.join(File.dirname(__FILE__), *%w[source]), 'foo', 'bar/2008-12-12-topical-post.textile')
140
298
  assert_equal ['foo'], post.categories
141
- assert_equal ['bar'], post.topics
142
299
  end
143
300
 
144
301
  end
data/test/test_site.rb CHANGED
@@ -9,6 +9,10 @@ class TestSite < Test::Unit::TestCase
9
9
  @site = Site.new(Jekyll.configuration)
10
10
  end
11
11
 
12
+ should "have an empty tag hash by default" do
13
+ assert_equal Hash.new, @site.tags
14
+ end
15
+
12
16
  should "reset data before processing" do
13
17
  clear_dest
14
18
  @site.process
@@ -38,7 +42,7 @@ class TestSite < Test::Unit::TestCase
38
42
  @site.process
39
43
 
40
44
  posts = Dir[source_dir("**", "_posts", "*")]
41
- categories = %w(bar baz category foo z_category publish_test).sort
45
+ categories = %w(bar baz category foo z_category publish_test win).sort
42
46
 
43
47
  assert_equal posts.size - 1, @site.posts.size
44
48
  assert_equal categories, @site.categories.keys.sort
@@ -53,5 +57,29 @@ class TestSite < Test::Unit::TestCase
53
57
  assert_equal %w[foo.markdown bar.markdown baz.markdown], @site.filter_entries(ent1)
54
58
  assert_equal ent2, @site.filter_entries(ent2)
55
59
  end
60
+
61
+ should "filter entries with exclude" do
62
+ excludes = %w[README TODO]
63
+ includes = %w[index.html site.css]
64
+
65
+ @site.exclude = excludes
66
+ assert_equal includes, @site.filter_entries(excludes + includes)
67
+ end
68
+
69
+ context 'with an invalid markdown processor in the configuration' do
70
+
71
+ should 'give a meaningful error message' do
72
+ bad_processor = 'not a processor name'
73
+ begin
74
+ Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor }))
75
+ flunk 'Invalid markdown processors should cause a failure on site creation'
76
+ rescue RuntimeError => e
77
+ assert e.to_s =~ /invalid|bad/i
78
+ assert e.to_s =~ %r{#{bad_processor}}
79
+ end
80
+ end
81
+
82
+ end
83
+
56
84
  end
57
85
  end