PerfectlyNormal-jekyll 0.5.1 → 0.5.3

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.
@@ -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