jekyll 0.5.1 → 0.5.3

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.

@@ -1,4 +1,24 @@
1
- == 0.5.1
1
+ == 0.5.3 / 2009-07-14
2
+ * Bug Fixes
3
+ * Solving the permalink bug where non-html files wouldn't work [github.com/jeffrydegrande]
4
+
5
+ == 0.5.2 / 2009-06-24
6
+ * Enhancements
7
+ * Added --paginate option to the executable along with a paginator object for the payload [github.com/calavera]
8
+ * Upgraded RedCloth to 4.2.1, which makes <notextile> tags work once again.
9
+ * Configuration options set in config.yml are now available through the site payload [github.com/vilcans]
10
+ * Posts can now have an empty YAML front matter or none at all [github.com/bahuvrihi]
11
+ * Bug Fixes
12
+ * Fixing Ruby 1.9 issue that requires to_s on the err object [github.com/Chrononaut]
13
+ * Fixes for pagination and ordering posts on the same day [github.com/ujh]
14
+ * Made pages respect permalinks style and permalinks in yml front matter [github.com/eugenebolshakov]
15
+ * Index.html file should always have index.html permalink [github.com/eugenebolshakov]
16
+ * Added trailing slash to pretty permalink style so Apache is happy [github.com/eugenebolshakov]
17
+ * Bad markdown processor in config fails sooner and with better message [github.com/gcnovus]
18
+ * Allow CRLFs in yaml frontmatter [github.com/juretta]
19
+ * Added Date#xmlschema for Ruby versions < 1.9
20
+
21
+ == 0.5.1 / 2009-05-06
2
22
  * Major Enhancements
3
23
  * Next/previous posts in site payload [github.com/pantulis, github.com/tomo]
4
24
  * Permalink templating system
@@ -10,6 +10,7 @@ h2. Getting Started
10
10
  * Read up about its "Usage":http://wiki.github.com/mojombo/jekyll/usage and "Configuration":http://wiki.github.com/mojombo/jekyll/configuration
11
11
  * Take a gander at some existing "Sites":http://wiki.github.com/mojombo/jekyll/sites
12
12
  * Fork and "Contribute":http://wiki.github.com/mojombo/jekyll/contribute your own modifications
13
+ * Have questions? Post them on the "Mailing List":http://groups.google.com/group/jekyll-rb
13
14
 
14
15
  h2. Diving In
15
16
 
@@ -21,7 +22,7 @@ h2. Diving In
21
22
 
22
23
  h2. Dependencies
23
24
 
24
- * RedCloth 4.1.0: Textile support. This version obeys <notextile> tags. The latest version will still work, but tests will fail.
25
+ * RedCloth: Textile support
25
26
  * Liquid: Templating system
26
27
  * Classifier: Generating related posts
27
28
  * Maruku: Default markdown engine
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ begin
15
15
  s.rubyforge_project = "jekyll"
16
16
  s.files.exclude 'test/dest'
17
17
  s.test_files.exclude 'test/dest'
18
- s.add_dependency('RedCloth', '= 4.1.0')
18
+ s.add_dependency('RedCloth', '>= 4.2.1')
19
19
  s.add_dependency('liquid', '>= 1.9.0')
20
20
  s.add_dependency('classifier', '>= 1.3.1')
21
21
  s.add_dependency('maruku', '>= 0.5.9')
@@ -81,7 +81,7 @@ begin
81
81
  require 'cucumber/rake/task'
82
82
 
83
83
  Cucumber::Rake::Task.new(:features) do |t|
84
- t.cucumber_opts = "--format pretty"
84
+ t.cucumber_opts = "--format progress"
85
85
  end
86
86
  rescue LoadError
87
87
  desc 'Cucumber rake task not available'
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 5
4
- :patch: 1
4
+ :patch: 3
data/bin/jekyll CHANGED
@@ -51,6 +51,16 @@ opts = OptionParser.new do |opts|
51
51
  opts.on("--permalink [TYPE]", "Use 'date' (default) for YYYY/MM/DD") do |style|
52
52
  options['permalink'] = style unless style.nil?
53
53
  end
54
+
55
+ opts.on("--paginate [POSTS_PER_PAGE]", "Paginate a blog's posts") do |per_page|
56
+ begin
57
+ options['paginate'] = per_page.to_i
58
+ raise ArgumentError if options['paginate'] == 0
59
+ rescue
60
+ puts 'you must specify a number of posts by page bigger than 0'
61
+ exit 0
62
+ end
63
+ end
54
64
 
55
65
  opts.on("--version", "Display current version") do
56
66
  puts "Jekyll " + Jekyll.version
@@ -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/layout'
@@ -62,14 +63,15 @@ module Jekyll
62
63
  source = override['source'] || Jekyll::DEFAULTS['source']
63
64
 
64
65
  # Get configuration from <source>/_config.yml
65
- config = {}
66
66
  config_file = File.join(source, '_config.yml')
67
67
  begin
68
68
  config = YAML.load_file(config_file)
69
- puts "Configuration from #{config_file}"
69
+ raise "Invalid configuration - #{config_file}" if !config.is_a?(Hash)
70
+ STDOUT.puts "Configuration from #{config_file}"
70
71
  rescue => err
71
- puts "WARNING: Could not read configuration. Using defaults (and options)."
72
- puts "\t" + err
72
+ STDERR.puts "WARNING: Could not read configuration. Using defaults (and options)."
73
+ STDERR.puts "\t" + err.to_s
74
+ config = {}
73
75
  end
74
76
 
75
77
  # Merge DEFAULTS < _config.yml < override
@@ -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
@@ -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 ||= (ext == '.html') ? template.gsub(':name', basename) : "/#{name}"
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.ext == '.html' && 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
@@ -18,7 +18,7 @@ module Jekyll
18
18
  name =~ MATCHER
19
19
  end
20
20
 
21
- attr_accessor :site, :date, :slug, :ext, :topics, :published, :data, :content, :output
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" => self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '),
209
- "url" => self.url,
210
- "date" => self.date,
211
- "id" => self.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" => self.next,
215
- "previous" => self.previous,
216
- "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)
217
225
  end
218
226
 
219
227
  def inspect
@@ -1,8 +1,8 @@
1
1
  module Jekyll
2
2
 
3
3
  class Site
4
- attr_accessor :config, :layouts, :posts, :categories, :exclude
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
@@ -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] = Array.new }
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 { |cats| cats.sort! { |a, b| b <=> a} }
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
@@ -172,11 +177,14 @@ module Jekyll
172
177
  directories.delete('_posts')
173
178
  read_posts(dir)
174
179
  end
180
+
175
181
  [directories, files].each do |entries|
176
182
  entries.each do |f|
177
183
  if File.directory?(File.join(base, f))
178
184
  next if self.dest.sub(/\/$/, '') == File.join(base, f)
179
185
  transform_pages(File.join(dir, f))
186
+ elsif Pager.pagination_enabled?(self.config, f)
187
+ paginate_posts(f, dir)
180
188
  else
181
189
  first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
182
190
 
@@ -211,15 +219,13 @@ module Jekyll
211
219
  #
212
220
  # Returns {"site" => {"time" => <Time>,
213
221
  # "posts" => [<Post>],
214
- # "categories" => [<Post>],
215
- # "topics" => [<Post>] }}
222
+ # "categories" => [<Post>]}
216
223
  def site_payload
217
- {"site" => {
218
- "time" => Time.now,
219
- "posts" => self.posts.sort { |a,b| b <=> a },
220
- "categories" => post_attr_hash('categories'),
221
- "topics" => post_attr_hash('topics')
222
- }}
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')})}
223
229
  end
224
230
 
225
231
  # Filter out any files/directories that are hidden or backup files (start
@@ -233,5 +239,28 @@ module Jekyll
233
239
  end
234
240
  end
235
241
  end
242
+
243
+ # Paginates the blog's posts. Renders the index.html file into paginated directories, ie: page2, page3...
244
+ # and adds more wite-wide data
245
+ #
246
+ # {"paginator" => { "page" => <Number>,
247
+ # "per_page" => <Number>,
248
+ # "posts" => [<Post>],
249
+ # "total_posts" => <Number>,
250
+ # "total_pages" => <Number>,
251
+ # "previous_page" => <Number>,
252
+ # "next_page" => <Number> }}
253
+ def paginate_posts(file, dir)
254
+ all_posts = self.posts.sort { |a,b| b <=> a }
255
+ pages = Pager.calculate_pages(all_posts, self.config['paginate'].to_i)
256
+ pages += 1
257
+ (1..pages).each do |num_page|
258
+ pager = Pager.new(self.config, num_page, all_posts, pages)
259
+ page = Page.new(self, self.source, dir, file)
260
+ page.render(self.layouts, site_payload.merge({'paginator' => pager.to_hash}))
261
+ suffix = "page#{num_page}" if num_page > 1
262
+ page.write(self.dest, suffix)
263
+ end
264
+ end
236
265
  end
237
266
  end
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- gem 'RedCloth', '= 4.1.0'
2
+ gem 'RedCloth', '= 4.2.1'
3
3
 
4
4
  require File.join(File.dirname(__FILE__), *%w[.. lib jekyll])
5
5
 
@@ -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,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,23 @@
1
+ ---
2
+ layout: nil
3
+ ---
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
+
8
+ <url>
9
+ <loc>http://example.com</loc>
10
+ <lastmod>{{ site.time | date_to_xmlschema }}</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>{{ site.time }}</lastmod>
19
+ <changefreq>monthly</changefreq>
20
+ <priority>0.2</priority>
21
+ </url>
22
+ {% endfor %}
23
+ </urlset>
@@ -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
@@ -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', '*')].sort.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
@@ -0,0 +1,98 @@
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
+ should "write properly with extension different from html" do
85
+ page = setup_page("sitemap.xml")
86
+ page.site.permalink_style = :pretty
87
+ do_render(page)
88
+ page.write(dest_dir)
89
+
90
+ assert_equal("/sitemap.xml", page.url)
91
+ assert_nil(page.url[/\.html$/])
92
+ assert File.directory?(dest_dir)
93
+ assert File.exists?(File.join(dest_dir,'sitemap.xml'))
94
+ end
95
+ end
96
+
97
+ end
98
+ 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
@@ -25,7 +25,6 @@ class TestPost < Test::Unit::TestCase
25
25
  assert !Post.valid?("blah")
26
26
  end
27
27
 
28
-
29
28
  context "processing posts" do
30
29
  setup do
31
30
  @post = Post.allocate
@@ -69,6 +68,19 @@ class TestPost < Test::Unit::TestCase
69
68
  assert_equal "my_category/permalinked-post", @post.url
70
69
  end
71
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
+
72
84
  context "with site wide permalink" do
73
85
  setup do
74
86
  @post.categories = []
@@ -129,8 +141,8 @@ class TestPost < Test::Unit::TestCase
129
141
  end
130
142
 
131
143
  should "process the url correctly" do
132
- assert_equal "/:categories/:year/:month/:day/:title", @post.template
133
- assert_equal "/2008/10/19/foo-bar", @post.url
144
+ assert_equal "/:categories/:year/:month/:day/:title/", @post.template
145
+ assert_equal "/2008/10/19/foo-bar/", @post.url
134
146
  end
135
147
  end
136
148
 
@@ -212,6 +224,28 @@ class TestPost < Test::Unit::TestCase
212
224
  assert post.categories.include?('baz')
213
225
  end
214
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
+
215
249
  context "rendering" do
216
250
  setup do
217
251
  clear_dest
@@ -262,7 +296,6 @@ class TestPost < Test::Unit::TestCase
262
296
  should "generate categories and topics" do
263
297
  post = Post.new(@site, File.join(File.dirname(__FILE__), *%w[source]), 'foo', 'bar/2008-12-12-topical-post.textile')
264
298
  assert_equal ['foo'], post.categories
265
- assert_equal ['bar'], post.topics
266
299
  end
267
300
 
268
301
  end
@@ -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
@@ -61,5 +65,21 @@ class TestSite < Test::Unit::TestCase
61
65
  @site.exclude = excludes
62
66
  assert_equal includes, @site.filter_entries(excludes + includes)
63
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
+
64
84
  end
65
85
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Preston-Werner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-06 00:00:00 -04:00
12
+ date: 2009-07-14 00:00:00 -07:00
13
13
  default_executable: jekyll
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -18,9 +18,9 @@ dependencies:
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - "="
21
+ - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 4.1.0
23
+ version: 4.2.1
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: liquid
@@ -99,6 +99,7 @@ files:
99
99
  - lib/jekyll/filters.rb
100
100
  - lib/jekyll/layout.rb
101
101
  - lib/jekyll/page.rb
102
+ - lib/jekyll/pager.rb
102
103
  - lib/jekyll/post.rb
103
104
  - lib/jekyll/site.rb
104
105
  - lib/jekyll/tags/highlight.rb
@@ -117,14 +118,25 @@ files:
117
118
  - test/source/_posts/2009-01-27-categories.textile
118
119
  - test/source/_posts/2009-01-27-category.textile
119
120
  - test/source/_posts/2009-03-12-hash-#1.markdown
121
+ - test/source/_posts/2009-05-18-tag.textile
122
+ - test/source/_posts/2009-05-18-tags.textile
123
+ - test/source/_posts/2009-06-22-empty-yaml.textile
124
+ - test/source/_posts/2009-06-22-no-yaml.textile
125
+ - test/source/about.html
120
126
  - test/source/category/_posts/2008-9-23-categories.textile
127
+ - test/source/contacts.html
121
128
  - test/source/css/screen.css
122
129
  - test/source/foo/_posts/bar/2008-12-12-topical-post.textile
123
130
  - test/source/index.html
131
+ - test/source/sitemap.xml
132
+ - test/source/win/_posts/2009-05-24-yaml-linebreak.markdown
124
133
  - test/source/z_category/_posts/2008-9-23-categories.textile
125
134
  - test/suite.rb
135
+ - test/test_configuration.rb
126
136
  - test/test_filters.rb
127
137
  - test/test_generated_site.rb
138
+ - test/test_page.rb
139
+ - test/test_pager.rb
128
140
  - test/test_post.rb
129
141
  - test/test_site.rb
130
142
  - test/test_tags.rb
@@ -154,13 +166,16 @@ requirements: []
154
166
  rubyforge_project: jekyll
155
167
  rubygems_version: 1.3.5
156
168
  signing_key:
157
- specification_version: 2
169
+ specification_version: 3
158
170
  summary: Jekyll is a simple, blog aware, static site generator.
159
171
  test_files:
160
- - test/helper.rb
172
+ - test/test_page.rb
173
+ - test/test_post.rb
174
+ - test/test_pager.rb
175
+ - test/test_configuration.rb
176
+ - test/test_tags.rb
177
+ - test/test_generated_site.rb
161
178
  - test/suite.rb
162
179
  - test/test_filters.rb
163
- - test/test_generated_site.rb
164
- - test/test_post.rb
180
+ - test/helper.rb
165
181
  - test/test_site.rb
166
- - test/test_tags.rb