PerfectlyNormal-jekyll 0.5.1 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -63,14 +63,15 @@ module Jekyll
63
63
  source = override['source'] || Jekyll::DEFAULTS['source']
64
64
 
65
65
  # Get configuration from <source>/_config.yml
66
- config = {}
67
66
  config_file = File.join(source, '_config.yml')
68
67
  begin
69
68
  config = YAML.load_file(config_file)
70
- puts "Configuration from #{config_file}"
69
+ raise "Invalid configuration - #{config_file}" if !config.is_a?(Hash)
70
+ STDOUT.puts "Configuration from #{config_file}"
71
71
  rescue => err
72
- puts "WARNING: Could not read configuration. Using defaults (and options)."
73
- puts "\t" + err
72
+ STDERR.puts "WARNING: Could not read configuration. Using defaults (and options)."
73
+ STDERR.puts "\t" + err.to_s
74
+ config = {}
74
75
  end
75
76
 
76
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
@@ -55,16 +89,24 @@ module Jekyll
55
89
  dest = File.join(dest, dest_suffix) if dest_suffix
56
90
  FileUtils.mkdir_p(dest)
57
91
 
58
- name = @name
59
- if self.ext != ""
60
- 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")
61
97
  end
62
98
 
63
- path = File.join(dest, name)
64
99
  File.open(path, 'w') do |f|
65
100
  f.write(self.output)
66
101
  end
67
102
  end
103
+
104
+ private
105
+
106
+ def index?
107
+ basename == 'index'
108
+ end
109
+
68
110
  end
69
111
 
70
- end
112
+ end
@@ -0,0 +1,46 @@
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
+ res = (file.to_s =~ /index.html/ && !config['paginate'].nil?)
13
+ res
14
+ end
15
+
16
+ def initialize(config, page, all_posts, num_pages = nil)
17
+ @page = page
18
+ @per_page = config['paginate'].to_i
19
+ @total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page)
20
+
21
+ if @page > @total_pages
22
+ raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}"
23
+ end
24
+
25
+ init = (@page - 1) * @per_page
26
+ offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1)
27
+
28
+ @total_posts = all_posts.size
29
+ @posts = all_posts[init..offset]
30
+ @previous_page = @page != 1 ? @page - 1 : nil
31
+ @next_page = @page != @total_pages ? @page + 1 : nil
32
+ end
33
+
34
+ def to_hash
35
+ {
36
+ 'page' => page,
37
+ 'per_page' => per_page,
38
+ 'posts' => posts,
39
+ 'total_posts' => total_posts,
40
+ 'total_pages' => total_pages,
41
+ 'previous_page' => previous_page,
42
+ 'next_page' => next_page
43
+ }
44
+ end
45
+ end
46
+ 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
@@ -128,7 +136,7 @@ module Jekyll
128
136
  "month" => date.strftime("%m"),
129
137
  "day" => date.strftime("%d"),
130
138
  "title" => CGI.escape(slug),
131
- "categories" => categories.sort.join('/')
139
+ "categories" => categories.join('/')
132
140
  }.inject(template) { |result, token|
133
141
  result.gsub(/:#{token.first}/, token.last)
134
142
  }.gsub(/\/\//, "/")
@@ -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
@@ -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
- "time" => Time.now,
222
- "posts" => self.posts.sort { |a,b| b <=> a },
223
- "categories" => post_attr_hash('categories'),
224
- "topics" => post_attr_hash('topics')
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)
@@ -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: PerfectlyNormal-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 -07: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.9
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,18 +118,29 @@ 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
131
- has_rdoc: true
143
+ has_rdoc: false
132
144
  homepage: http://github.com/mojombo/jekyll
133
145
  post_install_message:
134
146
  rdoc_options:
@@ -152,13 +164,16 @@ requirements: []
152
164
  rubyforge_project: jekyll
153
165
  rubygems_version: 1.2.0
154
166
  signing_key:
155
- specification_version: 2
167
+ specification_version: 3
156
168
  summary: Jekyll is a simple, blog aware, static site generator.
157
169
  test_files:
158
- - test/helper.rb
170
+ - test/test_page.rb
171
+ - test/test_post.rb
172
+ - test/test_pager.rb
173
+ - test/test_configuration.rb
174
+ - test/test_tags.rb
175
+ - test/test_generated_site.rb
159
176
  - test/suite.rb
160
177
  - test/test_filters.rb
161
- - test/test_generated_site.rb
162
- - test/test_post.rb
178
+ - test/helper.rb
163
179
  - test/test_site.rb
164
- - test/test_tags.rb