Merge branch 'master' of git://github.com/mojombo/jekyll

This commit is contained in:
Alagu 2012-10-03 19:33:21 -07:00
commit 2726a5f27c
19 changed files with 195 additions and 42 deletions

4
.travis.yml Normal file
View File

@ -0,0 +1,4 @@
rvm:
- 1.9.3
- 1.9.2
- 1.8.7

View File

@ -4,10 +4,15 @@
* Add --default-mimetype option (#279)
* Allow setting of RedCloth options (#284)
* Add post_url Liquid tag for internal post linking (#369)
* Allow multiple plugin dirs to be specified (#438)
* Inline TOC token support for RDiscount (#333)
* Add the option to specify the paginated url format (#342)
* Bug Fixes
* Allow some special characters in highlight names
* URL escape category names in URL generation (#360)
* Fix error with limit_posts (#442)
* Properly select dotfile during directory scan (#363, #431, #377)
* Allow setting of Kramdown smart_quotes (#482)
== 0.11.2 / 2011-12-27
* Bug Fixes

View File

@ -50,10 +50,6 @@ task :default => [:test, :features]
require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
if `which pygmentize` == ''
puts "You must have Pygments installed to run the tests."
exit 1
end
test.libs << 'lib' << 'test'
test.pattern = 'test/**/test_*.rb'
test.verbose = true

View File

@ -117,6 +117,16 @@ opts = OptionParser.new do |opts|
end
end
opts.on("--paginate_path [PAGINATED_URL_FORMAT]", "Leave blank for /page<num>") do |paginate_path|
begin
options['paginate_path'] = paginate_path
raise ArgumentError if options['paginate_path'].nil?
rescue
puts 'You must specify a pagination url format'
exit 0
end
end
opts.on("--limit_posts [MAX_POSTS]", "Limit the number of posts to publish") do |limit_posts|
begin
options['limit_posts'] = limit_posts.to_i

View File

@ -104,3 +104,9 @@ Feature: Create sites
When I run jekyll
Then the _site directory should exist
And I should see "URL: /2020/01/31/entry2/" in "_site/index.html"
Scenario: Basic site with whitelisted dotfile
Given I have an ".htaccess" file that contains "SomeDirective"
When I run jekyll
Then the _site directory should exist
And I should see "SomeDirective" in "_site/.htaccess"

View File

@ -25,3 +25,30 @@ Feature: Site pagination
| 1 | 4 | 1 | 5 |
| 2 | 2 | 2 | 3 |
| 3 | 2 | 1 | 3 |
Scenario Outline: Setting a custom pagination path
Given I have a configuration file with:
| key | value |
| paginate | 1 |
| paginate_path | /blog/page-:num |
| permalink | /blog/:year/:month/:day/:title |
And I have a _layouts directory
And I have an "index.html" page that contains "{{ paginator.posts.size }}"
And I have a _posts directory
And I have the following post:
| title | date | layout | content |
| Wargames | 3/27/2009 | default | The only winning move is not to play. |
| Wargames2 | 4/27/2009 | default | The only winning move is not to play2. |
| Wargames3 | 5/27/2009 | default | The only winning move is not to play3. |
| Wargames4 | 6/27/2009 | default | The only winning move is not to play4. |
When I run jekyll
Then the _site/blog/page-<exist> directory should exist
And the "_site/blog/page-<exist>/index.html" file should exist
And I should see "<posts>" in "_site/blog/page-<exist>/index.html"
And the "_site/blog/page-<not_exist>/index.html" file should not exist
Examples:
| exist | posts | not_exist |
| 2 | 1 | 5 |
| 3 | 1 | 6 |
| 4 | 1 | 7 |

View File

@ -131,3 +131,36 @@ Feature: Site configuration
And the "_site/2009/04/05/bananas.html" file should exist
And the "_site/2009/04/01/oranges.html" file should exist
And the "_site/2009/03/27/apples.html" file should not exist
Scenario: Copy over normally excluded files when they are explicitly included
Given I have a ".gitignore" file that contains ".DS_Store"
And I have an ".htaccess" file that contains "SomeDirective"
And I have a configuration file with "include" set to:
| value |
| .gitignore |
| .foo |
When I run jekyll
Then the _site directory should exist
And I should see ".DS_Store" in "_site/.gitignore"
And the "_site/.htaccess" file should not exist
Scenario: Using a different layouts directory
Given I have a _theme directory
And I have a page theme that contains "Page Layout: {{ site.posts.size }} on {{ site.time | date: "%Y-%m-%d" }}"
And I have a post theme that contains "Post Layout: {{ content }}"
And I have an "index.html" page with layout "page" that contains "site index page"
And I have a configuration file with:
| key | value |
| time | 2010-01-01 |
| future | true |
| layouts | _theme |
And I have a _posts directory
And I have the following posts:
| title | date | layout | content |
| entry1 | 12/31/2007 | post | content for entry1. |
| entry2 | 01/31/2020 | post | content for entry2. |
When I run jekyll
Then the _site directory should exist
And I should see "Page Layout: 2 on 2010-01-01" in "_site/index.html"
And I should see "Post Layout: <p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
And I should see "Post Layout: <p>content for entry2.</p>" in "_site/2020/01/31/entry2.html"

View File

@ -39,6 +39,13 @@ Given /^I have a (.*) layout that contains "(.*)"$/ do |layout, text|
end
end
Given /^I have a (.*) theme that contains "(.*)"$/ do |layout, text|
File.open(File.join('_theme', layout + '.html'), 'w') do |f|
f.write(text)
f.close
end
end
Given /^I have an? (.*) directory$/ do |dir|
FileUtils.mkdir_p(dir)
end
@ -121,7 +128,7 @@ When /^I change "(.*)" to contain "(.*)"$/ do |file, text|
end
Then /^the (.*) directory should exist$/ do |dir|
assert File.directory?(dir)
assert File.directory?(dir), "The directory \"#{dir}\" does not exist"
end
Then /^I should see "(.*)" in "(.*)"$/ do |text, file|

View File

@ -26,8 +26,8 @@ Gem::Specification.new do |s|
s.add_runtime_dependency('classifier', "~> 1.3")
s.add_runtime_dependency('directory_watcher', "~> 1.1")
s.add_runtime_dependency('maruku', "~> 0.5")
s.add_runtime_dependency('kramdown', "~> 0.13")
s.add_runtime_dependency('albino', "~> 1.3")
s.add_runtime_dependency('kramdown', "~> 0.13.4")
s.add_runtime_dependency('pygments.rb', "~> 0.2.12")
s.add_development_dependency('rake', "~> 0.9")
s.add_development_dependency('rdoc', "~> 3.11")

View File

@ -24,7 +24,7 @@ require 'English'
# 3rd party
require 'liquid'
require 'maruku'
require 'albino'
require 'pygments'
# internal requires
require 'jekyll/core_ext'
@ -59,6 +59,7 @@ module Jekyll
'source' => Dir.pwd,
'destination' => File.join(Dir.pwd, '_site'),
'plugins' => File.join(Dir.pwd, '_plugins'),
'layouts' => '_layouts',
'future' => true,
'lsi' => false,
@ -66,6 +67,7 @@ module Jekyll
'markdown' => 'maruku',
'permalink' => 'date',
'include' => ['.htaccess'],
'paginate_path' => 'page:num',
'markdown_ext' => 'markdown,mkd,mkdn,md',
'textile_ext' => 'textile',
@ -88,6 +90,7 @@ module Jekyll
'footnote_nr' => 1,
'entity_output' => 'as_char',
'toc_levels' => '1..6',
'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
'use_coderay' => false,
'coderay' => {

View File

@ -97,6 +97,7 @@ module Jekyll
:footnote_nr => @config['kramdown']['footnote_nr'],
:entity_output => @config['kramdown']['entity_output'],
:toc_levels => @config['kramdown']['toc_levels'],
:smart_quotes => @config['kramdown']['smart_quotes'],
:coderay_wrap => @config['kramdown']['coderay']['coderay_wrap'],
:coderay_line_numbers => @config['kramdown']['coderay']['coderay_line_numbers'],
@ -111,11 +112,17 @@ module Jekyll
:auto_ids => @config['kramdown']['auto_ids'],
:footnote_nr => @config['kramdown']['footnote_nr'],
:entity_output => @config['kramdown']['entity_output'],
:toc_levels => @config['kramdown']['toc_levels']
:toc_levels => @config['kramdown']['toc_levels'],
:smart_quotes => @config['kramdown']['smart_quotes']
}).to_html
end
when 'rdiscount'
RDiscount.new(content, *@rdiscount_extensions).to_html
rd = RDiscount.new(content, *@rdiscount_extensions)
html = rd.to_html
if rd.generate_toc and html.include?(@config['rdiscount']['toc_token'])
html.gsub!(@config['rdiscount']['toc_token'], rd.toc_content)
end
html
when 'maruku'
Maruku.new(content).to_html
end

View File

@ -37,13 +37,19 @@ module Jekyll
if num_page > 1
newpage = Page.new(site, site.source, page.dir, page.name)
newpage.pager = pager
newpage.dir = File.join(page.dir, "page#{num_page}")
newpage.dir = File.join(page.dir, paginate_path(site, num_page))
site.pages << newpage
else
page.pager = pager
end
end
end
private
def paginate_path(site, num_page)
format = site.config['paginate_path']
format.sub(':num', num_page.to_s)
end
end
class Pager

View File

@ -18,7 +18,7 @@ module Jekyll
self.safe = config['safe']
self.source = File.expand_path(config['source'])
self.dest = File.expand_path(config['destination'])
self.plugins = File.expand_path(config['plugins'])
self.plugins = Array(config['plugins']).map { |d| File.expand_path(d) }
self.lsi = config['lsi']
self.pygments = config['pygments']
self.permalink_style = config['permalink'].to_sym
@ -73,10 +73,12 @@ module Jekyll
# If safe mode is off, load in any Ruby files under the plugins
# directory.
unless self.safe
Dir[File.join(self.plugins, "**/*.rb")].each do |f|
self.plugins.each do |plugins|
Dir[File.join(plugins, "**/*.rb")].each do |f|
require f
end
end
end
self.converters = Jekyll::Converter.subclasses.select do |c|
!self.safe || c.safe
@ -99,12 +101,12 @@ module Jekyll
self.read_directories
end
# Read all the files in <source>/<dir>/_layouts and create a new Layout
# object with each one.
# Read all the files in <source>/<layouts> and create a new Layout object
# with each one.
#
# Returns nothing.
def read_layouts(dir = '')
base = File.join(self.source, dir, "_layouts")
def read_layouts
base = File.join(self.source, self.config['layouts'])
return unless File.exists?(base)
entries = []
Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
@ -119,12 +121,12 @@ module Jekyll
# that will become part of the site according to the rules in
# filter_entries.
#
# dir - The String relative path of the directory to read.
# dir - The String relative path of the directory to read. Default: ''.
#
# Returns nothing.
def read_directories(dir = '')
base = File.join(self.source, dir)
entries = Dir.chdir(base) { filter_entries(Dir['*']) }
entries = Dir.chdir(base) { filter_entries(Dir.entries('.')) }
self.read_posts(dir)
@ -193,12 +195,13 @@ module Jekyll
#
# Returns nothing.
def render
payload = site_payload
self.posts.each do |post|
post.render(self.layouts, site_payload)
post.render(self.layouts, payload)
end
self.pages.each do |page|
page.render(self.layouts, site_payload)
page.render(self.layouts, payload)
end
self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a } }
@ -254,7 +257,7 @@ module Jekyll
end
end
# Constructs a Hash of Posts indexed by the specified Post attribute.
# Construct a Hash of Posts indexed by the specified Post attribute.
#
# post_attr - The String name of the Post attribute.
#
@ -304,7 +307,7 @@ module Jekyll
# or are excluded in the site configuration, unless they are web server
# files such as '.htaccess'.
#
# entries - The Array of file/directory entries to filter.
# entries - The Array of String file/directory entries to filter.
#
# Returns the Array of filtered entries.
def filter_entries(entries)

View File

@ -48,7 +48,13 @@ module Jekyll
end
def render_pygments(context, code)
output = add_code_tags(Albino.new(code, @lang).to_s(@options), @lang)
@options[:encoding] = 'utf-8'
output = add_code_tags(
Pygments.highlight(code, :lexer => @lang, :options => @options),
@lang
)
output = context["pygments_prefix"] + output if context["pygments_prefix"]
output = output + context["pygments_suffix"] if context["pygments_suffix"]
output

View File

@ -3,21 +3,31 @@ require 'helper'
class TestKramdown < Test::Unit::TestCase
context "kramdown" do
setup do
config = {
@config = {
'markdown' => 'kramdown',
'kramdown' => {
'auto_ids' => false,
'footnote_nr' => 1,
'entity_output' => 'as_char',
'toc_levels' => '1..6'
'toc_levels' => '1..6',
'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo'
}
}
@markdown = MarkdownConverter.new config
end
# http://kramdown.rubyforge.org/converter/html.html#options
should "pass kramdown options" do
assert_equal "<h1>Some Header</h1>", @markdown.convert('# Some Header #').strip
markdown = MarkdownConverter.new(@config)
assert_equal "<h1>Some Header</h1>", markdown.convert('# Some Header #').strip
end
should "convert quotes to smart quotes" do
markdown = MarkdownConverter.new(@config)
assert_equal "<p>&ldquo;Pit&rsquo;hy&rdquo;</p>", markdown.convert(%{"Pit'hy"}).strip
override = { 'kramdown' => { 'smart_quotes' => 'lsaquo,rsaquo,laquo,raquo' } }
markdown = MarkdownConverter.new(@config.deep_merge(override))
assert_equal "<p>&laquo;Pit&rsaquo;hy&raquo;</p>", markdown.convert(%{"Pit'hy"}).strip
end
end
end

View File

@ -5,8 +5,8 @@ class TestRdiscount < Test::Unit::TestCase
context "rdiscount" do
setup do
config = {
'rdiscount' => { 'extensions' => ['smart'] },
'markdown' => 'rdiscount'
'markdown' => 'rdiscount',
'rdiscount' => { 'extensions' => ['smart', 'generate_toc'], 'toc_token' => '{:toc}' }
}
@markdown = MarkdownConverter.new config
end
@ -14,5 +14,9 @@ class TestRdiscount < Test::Unit::TestCase
should "pass rdiscount extensions" do
assert_equal "<p>&ldquo;smart&rdquo;</p>", @markdown.convert('"smart"').strip
end
should "render toc" do
assert_equal "<h1 id=\"Header+1\">Header 1</h1>\n\n<h2 id=\"Header+2\">Header 2</h2>\n\n<p>\n <ul>\n <li><a href=\"#Header+1\">Header 1</a>\n <ul>\n <li><a href=\"#Header+2\">Header 2</a> </li>\n </ul>\n </li>\n </ul>\n\n</p>", @markdown.convert("# Header 1\n\n## Header 2\n\n{:toc}").strip
end
end
end

View File

@ -1,4 +1,4 @@
require File.dirname(__FILE__) + '/helper'
require 'helper'
class TestRedcarpet < Test::Unit::TestCase
context "redcarpet" do

View File

@ -1,6 +1,32 @@
require 'helper'
class TestSite < Test::Unit::TestCase
context "configuring sites" do
should "have an array for plugins by default" do
site = Site.new(Jekyll::DEFAULTS)
assert_equal [File.join(Dir.pwd, '_plugins')], site.plugins
end
should "have an array for plugins if passed as a string" do
site = Site.new(Jekyll::DEFAULTS.merge({'plugins' => '/tmp/plugins'}))
assert_equal ['/tmp/plugins'], site.plugins
end
should "have an array for plugins if passed as an array" do
site = Site.new(Jekyll::DEFAULTS.merge({'plugins' => ['/tmp/plugins', '/tmp/otherplugins']}))
assert_equal ['/tmp/plugins', '/tmp/otherplugins'], site.plugins
end
should "have an empty array for plugins if nothing is passed" do
site = Site.new(Jekyll::DEFAULTS.merge({'plugins' => []}))
assert_equal [], site.plugins
end
should "have an empty array for plugins if nil is passed" do
site = Site.new(Jekyll::DEFAULTS.merge({'plugins' => nil}))
assert_equal [], site.plugins
end
end
context "creating sites" do
setup do
stub(Jekyll).configuration do

View File

@ -6,7 +6,7 @@ class TestTags < Test::Unit::TestCase
def create_post(content, override = {}, converter_class = Jekyll::MarkdownConverter)
stub(Jekyll).configuration do
Jekyll::DEFAULTS.merge({'pygments' => true}).merge(override)
Jekyll::DEFAULTS.deep_merge({'pygments' => true}).deep_merge(override)
end
site = Site.new(Jekyll.configuration)