Merge remote-tracking branch 'mojombo/master' into responsify

This commit is contained in:
Coby Chapple 2013-04-04 15:11:23 +01:00
commit 8354ef1960
41 changed files with 1081 additions and 1666 deletions

View File

@ -4,3 +4,8 @@ rvm:
- 1.9.2 - 1.9.2
- 1.8.7 - 1.8.7
script: bundle exec rake script: bundle exec rake
notifications:
irc: "irc.freenode.org#jekyll"
email:
on_success: never
on_failure: never

View File

@ -1,13 +1,17 @@
== HEAD == HEAD
* Major Enhancements * Major Enhancements
* Add `jekyll new` subcommand: generate a jekyll scaffold (#764)
* Refactored jekyll commands into subcommands: build, serve, and migrate. (#690) * Refactored jekyll commands into subcommands: build, serve, and migrate. (#690)
* Removed importers/migrators from main project, migrated to jekyll-import sub-gem (#793) * Removed importers/migrators from main project, migrated to jekyll-import sub-gem (#793)
* Added ability to render drafts in _drafts folder via command line (#833) * Added ability to render drafts in _drafts folder via command line (#833)
* Minor Enhancements * Minor Enhancements
* Load in Apache MIME Types on `jekyll serve` (#847) * Expose site.baseurl to Liquid templates (#869)
* Adds excerpt attribute to posts which contains first paragraph of content (#837)
* Accept custom configuration file via CLI (#863)
* Load in GitHub Pages MIME Types on `jekyll serve` (#847, #871)
* Improve debugability of error message for a malformed highlight tag (#785) * Improve debugability of error message for a malformed highlight tag (#785)
* Allow symlinked files in unsafe mode (#824) * Allow symlinked files in unsafe mode (#824)
* Add 'gist' liquid tag to core (#822) * Add 'gist' Liquid tag to core (#822, #861)
* New format of Jekyll output (#795) * New format of Jekyll output (#795)
* Reinstate --limit_posts and --future switches (#788) * Reinstate --limit_posts and --future switches (#788)
* Remove ambiguity from command descriptions (#815) * Remove ambiguity from command descriptions (#815)
@ -26,6 +30,14 @@
* Add source and destination directory protection (#535) * Add source and destination directory protection (#535)
* Better YAML error message (#718) * Better YAML error message (#718)
* Bug Fixes * Bug Fixes
* Fix symlinked static files not being correctly built in unsafe mode (#909)
* Fix integration with directory_watcher 1.4.x (#916)
* Accepting strings as arguments to jekyll-import command (#910)
* Force usage of older directory_watcher gem as 1.5 is broken (#883)
* Ensure all Post categories are downcase (#842, #872)
* Force encoding of the rdiscount TOC to UTF8 to avoid conversion errors (#555)
* Patch for multibyte URI problem with jekyll serve (#723)
* Order plugin execution by priority (#864)
* Fixed Page#dir and Page#url for edge cases (#536) * Fixed Page#dir and Page#url for edge cases (#536)
* Fix broken post_url with posts with a time in their YAML Front-Matter (#831) * Fix broken post_url with posts with a time in their YAML Front-Matter (#831)
* Look for plugins under the source directory (#654) * Look for plugins under the source directory (#654)
@ -34,7 +46,7 @@
* Force Categories to be Strings (#767) * Force Categories to be Strings (#767)
* Safe YAML plugin to prevent vulnerability (#777) * Safe YAML plugin to prevent vulnerability (#777)
* Add SVG support to Jekyll/WEBrick. (#407, #406) * Add SVG support to Jekyll/WEBrick. (#407, #406)
* Prevent custom destination from causing continuous regen on watch (#528, #820) * Prevent custom destination from causing continuous regen on watch (#528, #820, #862)
* Site Enhancements * Site Enhancements
* Bring site into master branch with better preview/deploy (#709) * Bring site into master branch with better preview/deploy (#709)
* Redesigned site (#583) * Redesigned site (#583)
@ -49,6 +61,14 @@
of greater than 1.9 (#771) of greater than 1.9 (#771)
* Switch to Simplecov for coverage report (#765) * Switch to Simplecov for coverage report (#765)
== 0.12.1 / 2013-02-19
* Minor Enhancements
* Update Kramdown version to 0.14.1 (#744)
* Test Enhancements
* Update Rake version to 10.0.3 (#744)
* Update Shoulda version to 3.3.2 (#744)
* Update Redcarpet version to 2.2.2 (#744)
== 0.12.0 / 2012-12-22 == 0.12.0 / 2012-12-22
* Minor Enhancements * Minor Enhancements
* Add ability to explicitly specify included files (#261) * Add ability to explicitly specify included files (#261)

View File

@ -1,6 +1,7 @@
h1. Jekyll h1. Jekyll
!https://travis-ci.org/mojombo/jekyll.png?branch=master!:https://travis-ci.org/mojombo/jekyll !https://travis-ci.org/mojombo/jekyll.png?branch=master!:https://travis-ci.org/mojombo/jekyll
"!https://codeclimate.com/github/mojombo/jekyll.png!":https://codeclimate.com/github/mojombo/jekyll
By Tom Preston-Werner, Nick Quaranto, and many awesome contributors! By Tom Preston-Werner, Nick Quaranto, and many awesome contributors!

View File

@ -1,4 +1,5 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
STDOUT.sync = true
$:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib }) $:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
@ -30,10 +31,20 @@ def normalize_options(options)
options options
end end
command :new do |c|
c.syntax = 'jekyll new PATH'
c.description = 'Creates a new Jekyll site scaffold in PATH'
c.action do |args, options|
Jekyll::Commands::New.process(args)
end
end
command :build do |c| command :build do |c|
c.syntax = 'jekyll build [options]' c.syntax = 'jekyll build [options]'
c.description = 'Build your site' c.description = 'Build your site'
c.option '--config [CONFIG_FILE]', 'Custom configuration file'
c.option '--future', 'Publishes posts with a future date' c.option '--future', 'Publishes posts with a future date'
c.option '--limit_posts MAX_POSTS', 'Limits the number of posts to parse and publish' c.option '--limit_posts MAX_POSTS', 'Limits the number of posts to parse and publish'
c.option '-w', '--watch', 'Watch for changes and rebuild' c.option '-w', '--watch', 'Watch for changes and rebuild'
@ -52,6 +63,7 @@ command :serve do |c|
c.syntax = 'jekyll serve [options]' c.syntax = 'jekyll serve [options]'
c.description = 'Serve your site locally' c.description = 'Serve your site locally'
c.option '--config [CONFIG_FILE]', 'Custom configuration file'
c.option '--future', 'Publishes posts with a future date' c.option '--future', 'Publishes posts with a future date'
c.option '--limit_posts MAX_POSTS', 'Limits the number of posts to parse and publish' c.option '--limit_posts MAX_POSTS', 'Limits the number of posts to parse and publish'
c.option '-w', '--watch', 'Watch for changes and rebuild' c.option '-w', '--watch', 'Watch for changes and rebuild'
@ -80,12 +92,12 @@ command :import do |c|
c.syntax = 'jekyll import <platform> [options]' c.syntax = 'jekyll import <platform> [options]'
c.description = 'Import your old blog to Jekyll' c.description = 'Import your old blog to Jekyll'
c.option '--source', 'Source file or URL to migrate from' c.option '--source STRING', 'Source file or URL to migrate from'
c.option '--file', 'File to migrate from' c.option '--file STRING', 'File to migrate from'
c.option '--dbname', 'Database name to migrate from' c.option '--dbname STRING', 'Database name to migrate from'
c.option '--user', 'Username to use when migrating' c.option '--user STRING', 'Username to use when migrating'
c.option '--pass', 'Password to use when migrating' c.option '--pass STRING', 'Password to use when migrating'
c.option '--host', 'Host address to use when migrating' c.option '--host STRING', 'Host address to use when migrating'
c.action do |args, options| c.action do |args, options|
begin begin

View File

@ -94,6 +94,41 @@ Feature: Post data
Then the _site directory should exist Then the _site directory should exist
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html" And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when categories are in folders with mixed case
Given I have a scifi directory
And I have a scifi/Movies directory
And I have a scifi/Movies/_posts directory
And I have a _layouts directory
And I have the following post in "scifi/Movies":
| title | date | layout | content |
| Star Wars | 3/27/2009 | simple | Luke, I am your father. |
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
When I run jekyll
Then the _site directory should exist
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when category is in YAML
Given I have a _posts directory
And I have a _layouts directory
And I have the following post:
| title | date | layout | category | content |
| Star Wars | 3/27/2009 | simple | movies | Luke, I am your father. |
And I have a simple layout that contains "Post category: {{ page.categories }}"
When I run jekyll
Then the _site directory should exist
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when category is in YAML and is mixed-case
Given I have a _posts directory
And I have a _layouts directory
And I have the following post:
| title | date | layout | category | content |
| Star Wars | 3/27/2009 | simple | Movies | Luke, I am your father. |
And I have a simple layout that contains "Post category: {{ page.categories }}"
When I run jekyll
Then the _site directory should exist
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when category is in YAML Scenario: Use post.categories variable when category is in YAML
Given I have a _posts directory Given I have a _posts directory
And I have a _layouts directory And I have a _layouts directory
@ -105,16 +140,18 @@ Feature: Post data
Then the _site directory should exist Then the _site directory should exist
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html" And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
Scenario: Use post.categories variable when categories are in YAML Scenario: Use post.categories variable when categories are in YAML with mixed case
Given I have a _posts directory Given I have a _posts directory
And I have a _layouts directory And I have a _layouts directory
And I have the following post: And I have the following posts:
| title | date | layout | categories | content | | title | date | layout | categories | content |
| Star Wars | 3/27/2009 | simple | ['scifi', 'movies'] | Luke, I am your father. | | Star Wars | 3/27/2009 | simple | ['scifi', 'Movies'] | Luke, I am your father. |
| Star Trek | 3/17/2013 | simple | ['SciFi', 'movies'] | Jean Luc, I am your father. |
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}" And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
When I run jekyll When I run jekyll
Then the _site directory should exist Then the _site directory should exist
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html" And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2013/03/17/star-trek.html"
Scenario: Disable a post from being published Scenario: Disable a post from being published
Given I have a _posts directory Given I have a _posts directory

View File

@ -3,7 +3,7 @@ Feature: Site configuration
I want to be able to configure jekyll I want to be able to configure jekyll
In order to make setting up a site easier In order to make setting up a site easier
Scenario: Change destination directory Scenario: Change source directory
Given I have a blank site in "_sourcedir" Given I have a blank site in "_sourcedir"
And I have an "_sourcedir/index.html" file that contains "Changing source directory" And I have an "_sourcedir/index.html" file that contains "Changing source directory"
And I have a configuration file with "source" set to "_sourcedir" And I have a configuration file with "source" set to "_sourcedir"

View File

@ -4,9 +4,9 @@ Gem::Specification.new do |s|
s.rubygems_version = '1.3.5' s.rubygems_version = '1.3.5'
s.name = 'jekyll' s.name = 'jekyll'
s.version = '1.0.0.beta1' s.version = '1.0.0.beta2'
s.license = 'MIT' s.license = 'MIT'
s.date = '2013-03-14' s.date = '2013-03-19'
s.rubyforge_project = 'jekyll' s.rubyforge_project = 'jekyll'
s.summary = "A simple, blog aware, static site generator." s.summary = "A simple, blog aware, static site generator."
@ -25,7 +25,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency('liquid', "~> 2.3") s.add_runtime_dependency('liquid', "~> 2.3")
s.add_runtime_dependency('classifier', "~> 1.3") s.add_runtime_dependency('classifier', "~> 1.3")
s.add_runtime_dependency('directory_watcher', "~> 1.1") s.add_runtime_dependency('directory_watcher', "~> 1.4.1")
s.add_runtime_dependency('maruku', "~> 0.5") s.add_runtime_dependency('maruku', "~> 0.5")
s.add_runtime_dependency('kramdown', "~> 0.14") s.add_runtime_dependency('kramdown', "~> 0.14")
s.add_runtime_dependency('pygments.rb', "~> 0.3.2") s.add_runtime_dependency('pygments.rb', "~> 0.3.2")
@ -70,6 +70,7 @@ Gem::Specification.new do |s|
lib/jekyll.rb lib/jekyll.rb
lib/jekyll/command.rb lib/jekyll/command.rb
lib/jekyll/commands/build.rb lib/jekyll/commands/build.rb
lib/jekyll/commands/new.rb
lib/jekyll/commands/serve.rb lib/jekyll/commands/serve.rb
lib/jekyll/converter.rb lib/jekyll/converter.rb
lib/jekyll/converters/identity.rb lib/jekyll/converters/identity.rb
@ -93,6 +94,15 @@ Gem::Specification.new do |s|
lib/jekyll/tags/highlight.rb lib/jekyll/tags/highlight.rb
lib/jekyll/tags/include.rb lib/jekyll/tags/include.rb
lib/jekyll/tags/post_url.rb lib/jekyll/tags/post_url.rb
lib/site_template/_config.yml
lib/site_template/_layouts/default.html
lib/site_template/_layouts/post.html
lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb
lib/site_template/css/screen.css
lib/site_template/css/syntax.css
lib/site_template/images/.gitkeep
lib/site_template/images/rss.png
lib/site_template/index.html
script/bootstrap script/bootstrap
site/.gitignore site/.gitignore
site/CNAME site/CNAME
@ -153,6 +163,7 @@ Gem::Specification.new do |s|
test/source/_includes/sig.markdown test/source/_includes/sig.markdown
test/source/_layouts/default.html test/source/_layouts/default.html
test/source/_layouts/simple.html test/source/_layouts/simple.html
test/source/_plugins/dummy.rb
test/source/_posts/2008-02-02-not-published.textile test/source/_posts/2008-02-02-not-published.textile
test/source/_posts/2008-02-02-published.textile test/source/_posts/2008-02-02-published.textile
test/source/_posts/2008-10-18-foo-bar.textile test/source/_posts/2008-10-18-foo-bar.textile
@ -178,6 +189,7 @@ Gem::Specification.new do |s|
test/source/_posts/2010-01-16-override-data.textile test/source/_posts/2010-01-16-override-data.textile
test/source/_posts/2011-04-12-md-extension.md test/source/_posts/2011-04-12-md-extension.md
test/source/_posts/2011-04-12-text-extension.text test/source/_posts/2011-04-12-text-extension.text
test/source/_posts/2013-01-02-post-excerpt.markdown
test/source/_posts/2013-01-12-nil-layout.textile test/source/_posts/2013-01-12-nil-layout.textile
test/source/_posts/2013-01-12-no-layout.textile test/source/_posts/2013-01-12-no-layout.textile
test/source/about.html test/source/about.html
@ -193,12 +205,14 @@ Gem::Specification.new do |s|
test/source/win/_posts/2009-05-24-yaml-linebreak.markdown test/source/win/_posts/2009-05-24-yaml-linebreak.markdown
test/source/z_category/_posts/2008-9-23-categories.textile test/source/z_category/_posts/2008-9-23-categories.textile
test/suite.rb test/suite.rb
test/test_command.rb
test/test_configuration.rb test/test_configuration.rb
test/test_convertible.rb test/test_convertible.rb
test/test_core_ext.rb test/test_core_ext.rb
test/test_filters.rb test/test_filters.rb
test/test_generated_site.rb test/test_generated_site.rb
test/test_kramdown.rb test/test_kramdown.rb
test/test_new_command.rb
test/test_page.rb test/test_page.rb
test/test_pager.rb test/test_pager.rb
test/test_post.rb test/test_post.rb

View File

@ -52,7 +52,7 @@ require_all 'jekyll/tags'
SafeYAML::OPTIONS[:suppress_warnings] = true SafeYAML::OPTIONS[:suppress_warnings] = true
module Jekyll module Jekyll
VERSION = '1.0.0.beta1' VERSION = '1.0.0.beta2'
# Default options. Overriden by values in _config.yml. # Default options. Overriden by values in _config.yml.
# Strings rather than symbols are used for compatability with YAML. # Strings rather than symbols are used for compatability with YAML.
@ -64,16 +64,19 @@ module Jekyll
'keep_files' => ['.git','.svn'], 'keep_files' => ['.git','.svn'],
'future' => true, # remove and make true just default 'future' => true, # remove and make true just default
'pygments' => false, # remove and make true just default 'pygments' => true, # remove and make true just default
'markdown' => 'maruku', # no longer a command option 'markdown' => 'maruku',
'permalink' => 'date', # no longer a command option 'permalink' => 'date',
'include' => ['.htaccess'], # no longer a command option 'baseurl' => '',
'paginate_path' => 'page:num', # no longer a command option 'include' => ['.htaccess'],
'paginate_path' => 'page:num',
'markdown_ext' => 'markdown,mkd,mkdn,md', 'markdown_ext' => 'markdown,mkd,mkdn,md',
'textile_ext' => 'textile', 'textile_ext' => 'textile',
'excerpt_separator' => "\n\n",
'maruku' => { 'maruku' => {
'use_tex' => false, 'use_tex' => false,
'use_divs' => false, 'use_divs' => false,
@ -129,8 +132,10 @@ module Jekyll
# then, we need to know where to look for _config.yml # then, we need to know where to look for _config.yml
source = override['source'] || Jekyll::DEFAULTS['source'] source = override['source'] || Jekyll::DEFAULTS['source']
# Get configuration from <source>/_config.yml # Get configuration from <source>/_config.yml or <source>/<config_file>
config_file = File.join(source, '_config.yml') config_file = override.delete('config')
config_file = File.join(source, "_config.yml") if config_file.to_s.empty?
begin begin
config = YAML.safe_load_file(config_file) config = YAML.safe_load_file(config_file)
raise "Configuration file: (INVALID) #{config_file}" if !config.is_a?(Hash) raise "Configuration file: (INVALID) #{config_file}" if !config.is_a?(Hash)

View File

@ -3,7 +3,7 @@ module Jekyll
def self.globs(source, destination) def self.globs(source, destination)
Dir.chdir(source) do Dir.chdir(source) do
dirs = Dir['*'].select { |x| File.directory?(x) } dirs = Dir['*'].select { |x| File.directory?(x) }
dirs -= [destination] dirs -= [destination, File.expand_path(destination), File.basename(destination)]
dirs = dirs.map { |x| "#{x}/**/*" } dirs = dirs.map { |x| "#{x}/**/*" }
dirs += ['*'] dirs += ['*']
end end

View File

@ -4,14 +4,8 @@ module Jekyll
def self.process(options) def self.process(options)
site = Jekyll::Site.new(options) site = Jekyll::Site.new(options)
source = options['source'] self.build(site, options)
destination = options['destination'] self.watch(site, options) if options['watch']
if options['watch']
self.watch(site, options)
else
self.build(site, options)
end
end end
# Private: Build the site from source into destination. # Private: Build the site from source into destination.
@ -50,18 +44,23 @@ module Jekyll
source = options['source'] source = options['source']
destination = options['destination'] destination = options['destination']
puts " Source: #{source}"
puts " Destination: #{destination}"
puts " Auto-regeneration: enabled" puts " Auto-regeneration: enabled"
dw = DirectoryWatcher.new(source) dw = DirectoryWatcher.new(source, :glob => self.globs(source, destination), :pre_load => true)
dw.interval = 1 dw.interval = 1
dw.glob = self.globs(source, destination)
dw.add_observer do |*args| dw.add_observer do |*args|
t = Time.now.strftime("%Y-%m-%d %H:%M:%S") t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
print " Regenerating: #{args.size} files at #{t} " print " Regenerating: #{args.size} files at #{t} "
site.process begin
site.process
rescue Jekyll::FatalException => e
puts
puts "ERROR: YOUR SITE COULD NOT BE BUILT:"
puts "------------------------------------"
puts e.message
exit(1)
end
puts "...done." puts "...done."
end end

View File

@ -0,0 +1,46 @@
require 'erb'
module Jekyll
module Commands
class New < Command
def self.process(args)
raise ArgumentError.new('You must specify a path.') if args.empty?
new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
FileUtils.mkdir_p new_blog_path
create_sample_files new_blog_path
File.open(File.expand_path(self.initialized_post_name, new_blog_path), "w") do |f|
f.write(self.scaffold_post_content(site_template))
end
puts "New jekyll site installed in #{new_blog_path}."
end
def self.scaffold_post_content(template_site)
ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
end
# Internal: Gets the filename of the sample post to be created
#
# Returns the filename of the sample post, as a String
def self.initialized_post_name
"_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
end
private
def self.create_sample_files(path)
FileUtils.cp_r site_template + '/.', path
FileUtils.rm File.expand_path(scaffold_path, path)
end
def self.site_template
File.expand_path("../../site_template", File.dirname(__FILE__))
end
def self.scaffold_path
"_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
end
end
end
end

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
module Jekyll module Jekyll
module Commands module Commands
class Serve < Command class Serve < Command
@ -12,13 +13,17 @@ module Jekyll
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__)) mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
mime_types = WEBrick::HTTPUtils::load_mime_types(mime_types_file) mime_types = WEBrick::HTTPUtils::load_mime_types(mime_types_file)
# recreate NondisclosureName under utf-8 circumstance
fh_option = WEBrick::Config::FileHandler
fh_option[:NondisclosureName] = ['.ht*','~*']
s = HTTPServer.new( s = HTTPServer.new(
:Port => options['port'], :Port => options['port'],
:BindAddress => options['host'], :BindAddress => options['host'],
:MimeTypes => mime_types :MimeTypes => mime_types
) )
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination) s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
t = Thread.new { s.start } t = Thread.new { s.start }
trap("INT") { s.shutdown } trap("INT") { s.shutdown }
t.join() t.join()

View File

@ -137,7 +137,7 @@ module Jekyll
rd = RDiscount.new(content, *@rdiscount_extensions) rd = RDiscount.new(content, *@rdiscount_extensions)
html = rd.to_html html = rd.to_html
if rd.generate_toc and html.include?(@config['rdiscount']['toc_token']) if rd.generate_toc and html.include?(@config['rdiscount']['toc_token'])
html.gsub!(@config['rdiscount']['toc_token'], rd.toc_content) html.gsub!(@config['rdiscount']['toc_token'], rd.toc_content.force_encoding('utf-8'))
end end
html html
when 'maruku' when 'maruku'

View File

@ -58,3 +58,11 @@ module Enumerable
any? { |exp| File.fnmatch?(exp, e) } any? { |exp| File.fnmatch?(exp, e) }
end end
end end
if RUBY_VERSION < "1.9"
class String
def force_encoding(enc)
self
end
end
end

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ module Jekyll
end end
attr_accessor :site attr_accessor :site
attr_accessor :data, :content, :output, :ext attr_accessor :data, :excerpt, :content, :output, :ext
attr_accessor :date, :slug, :published, :tags, :categories attr_accessor :date, :slug, :published, :tags, :categories
attr_reader :name attr_reader :name
@ -36,7 +36,7 @@ module Jekyll
@base = self.containing_dir(source, dir) @base = self.containing_dir(source, dir)
@name = name @name = name
self.categories = dir.split('/').reject { |x| x.empty? } self.categories = dir.downcase.split('/').reject { |x| x.empty? }
self.process(name) self.process(name)
begin begin
self.read_yaml(@base, name) self.read_yaml(@base, name)
@ -60,8 +60,11 @@ module Jekyll
self.tags = self.data.pluralized_array("tag", "tags") self.tags = self.data.pluralized_array("tag", "tags")
if self.categories.empty? if self.categories.empty?
self.categories = self.data.pluralized_array('category', 'categories') self.categories = self.data.pluralized_array('category', 'categories').map {|c| c.downcase}
end end
self.tags.flatten!
self.categories.flatten!
end end
# Get the full path to the directory containing the post files # Get the full path to the directory containing the post files
@ -77,8 +80,8 @@ module Jekyll
# Returns nothing. # Returns nothing.
def read_yaml(base, name) def read_yaml(base, name)
super(base, name) super(base, name)
self.excerpt = self.extract_excerpt
self.data['layout'] = 'post' unless self.data.has_key?('layout') self.data['layout'] = 'post' unless self.data.has_key?('layout')
self.data
end end
# Compares Post objects. First compares the Post date. If the dates are # Compares Post objects. First compares the Post date. If the dates are
@ -109,6 +112,14 @@ module Jekyll
raise FatalException.new("Post #{name} does not have a valid date.") raise FatalException.new("Post #{name} does not have a valid date.")
end end
# Transform the contents and excerpt based on the content type.
#
# Returns nothing.
def transform
super
self.excerpt = converter.convert(self.excerpt)
end
# The generated directory into which the post will be placed # The generated directory into which the post will be placed
# upon generation. This is derived from the permalink or, if # upon generation. This is derived from the permalink or, if
# permalink is absent, set to the default date # permalink is absent, set to the default date
@ -257,7 +268,8 @@ module Jekyll
"next" => self.next, "next" => self.next,
"previous" => self.previous, "previous" => self.previous,
"tags" => self.tags, "tags" => self.tags,
"content" => self.content }) "content" => self.content,
"excerpt" => self.excerpt })
end end
# Returns the shorthand String identifier of this Post. # Returns the shorthand String identifier of this Post.
@ -283,5 +295,48 @@ module Jekyll
nil nil
end end
end end
protected
# Internal: Extract excerpt from the content
#
# By default excerpt is your first paragraph of a post: everything before
# the first two new lines:
#
# ---
# title: Example
# ---
#
# First paragraph with [link][1].
#
# Second paragraph.
#
# [1]: http://example.com/
#
# This is fairly good option for Markdown and Textile files. But might cause
# problems for HTML posts (which is quite unusual for Jekyll). If default
# excerpt delimiter is not good for you, you might want to set your own via
# configuration option `excerpt_separator`. For example, following is a good
# alternative for HTML posts:
#
# # file: _config.yml
# excerpt_separator: "<!-- more -->"
#
# Notice that all markdown-style link references will be appended to the
# excerpt. So the example post above will have this excerpt source:
#
# First paragraph with [link][1].
#
# [1]: http://example.com/
#
# Excerpts are rendered same time as content is rendered.
#
# Returns excerpt String
def extract_excerpt
separator = self.site.config['excerpt_separator']
head, _, tail = self.content.partition(separator)
"" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
end
end end
end end

View File

@ -5,7 +5,7 @@ module Jekyll
attr_accessor :config, :layouts, :posts, :pages, :static_files, attr_accessor :config, :layouts, :posts, :pages, :static_files,
:categories, :exclude, :include, :source, :dest, :lsi, :pygments, :categories, :exclude, :include, :source, :dest, :lsi, :pygments,
:permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts, :permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts,
:show_drafts, :keep_files :show_drafts, :keep_files, :baseurl
attr_accessor :converters, :generators attr_accessor :converters, :generators
@ -21,6 +21,7 @@ module Jekyll
self.plugins = plugins_path self.plugins = plugins_path
self.lsi = config['lsi'] self.lsi = config['lsi']
self.pygments = config['pygments'] self.pygments = config['pygments']
self.baseurl = config['baseurl']
self.permalink_style = config['permalink'].to_sym self.permalink_style = config['permalink'].to_sym
self.exclude = config['exclude'] || [] self.exclude = config['exclude'] || []
self.include = config['include'] || [] self.include = config['include'] || []
@ -88,17 +89,8 @@ module Jekyll
end end
end end
self.converters = Jekyll::Converter.subclasses.select do |c| self.converters = instantiate_subclasses(Jekyll::Converter)
!self.safe || c.safe self.generators = instantiate_subclasses(Jekyll::Generator)
end.map do |c|
c.new(self.config)
end
self.generators = Jekyll::Generator.subclasses.select do |c|
!self.safe || c.safe
end.map do |c|
c.new(self.config)
end
end end
# Internal: Setup the plugin search path # Internal: Setup the plugin search path
@ -167,7 +159,7 @@ module Jekyll
if File.directory?(f_abs) if File.directory?(f_abs)
next if self.dest.sub(/\/$/, '') == f_abs next if self.dest.sub(/\/$/, '') == f_abs
read_directories(f_rel) read_directories(f_rel)
elsif !File.symlink?(f_abs) else
first3 = File.open(f_abs) { |fd| fd.read(3) } first3 = File.open(f_abs) { |fd| fd.read(3) }
if first3 == "---" if first3 == "---"
# file appears to have a YAML header so process it as a page # file appears to have a YAML header so process it as a page
@ -388,6 +380,21 @@ module Jekyll
end end
end end
# Create array of instances of the subclasses of the class or module
# passed in as argument.
#
# klass - class or module containing the subclasses which should be
# instantiated
#
# Returns array of instances of subclasses of parameter
def instantiate_subclasses(klass)
klass.subclasses.select do |c|
!self.safe || c.safe
end.sort.map do |c|
c.new(self.config)
end
end
# Read the entries from a particular directory for processing # Read the entries from a particular directory for processing
# #
# dir - The String relative path of the directory to read # dir - The String relative path of the directory to read

View File

@ -2,16 +2,27 @@
# #
# Example: # Example:
# {% gist 1234567 %} # {% gist 1234567 %}
# {% gist 1234567 file.rb %}
module Jekyll module Jekyll
class GistTag < Liquid::Tag class GistTag < Liquid::Tag
def initialize(tag_name, gist, tokens) def render(context)
super if tag_contents = @markup.strip.match(/\A(\d+) ?(\S*)\Z/)
@gist = gist.strip gist_id, filename = tag_contents[1].strip, tag_contents[2].strip
gist_script_tag(gist_id, filename)
else
"Error parsing gist id"
end
end end
def render(context) private
"<script src=\"https://gist.github.com/#{@gist}.js\"> </script>"
def gist_script_tag(gist_id, filename=nil)
if filename.empty?
"<script src=\"https://gist.github.com/#{gist_id}.js\"> </script>"
else
"<script src=\"https://gist.github.com/#{gist_id}.js?file=#{filename}\"> </script>"
end
end end
end end
end end

View File

@ -0,0 +1,2 @@
markdown: rdiscount
pygments: true

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>{{ page.title }}</title>
<!-- syntax highlighting CSS -->
<link rel="stylesheet" href="/css/syntax.css" type="text/css" />
<!-- Homepage CSS -->
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen, projection" />
</head>
<body>
<div class="site">
<div class="title">
<a href="/">Your Name</a>
<a class="extra" href="/">home</a>
</div>
{{ content }}
<div class="footer">
<div class="contact">
<p>
Your Name<br />
What You Are<br />
your@email.com
</p>
</div>
<div class="contact">
<p>
<a href="http://github.com/yourusername/">github.com/yourusername</a><br />
<a href="http://twitter.com/yourusername/">twitter.com/yourusername</a><br />
</p>
</div>
</div>
</div>
<a href="http://github.com/yourusername"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub" /></a>
</body>
</html>

View File

@ -0,0 +1,6 @@
---
layout: default
---
<div id="post">
{{ content }}
</div>

View File

@ -0,0 +1,24 @@
---
layout: post
title: "Welcome to Jekyll!"
date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S') %>
categories: jekyll update
---
You'll find this post in your `_posts` directory - edit this post and re-build (or run with the `-w` switch) to see your changes!
To add new posts, simply add a file in the `_posts` directory that follows the convention: YYYY-MM-DD-name-of-post.ext.
Jekyll also offers powerful support for code snippets:
{% highlight ruby %}
def print_hi(name)
puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
{% endhighlight %}
Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll's GitHub repo][jekyll-gh].
[jekyll-gh]: https://github.com/mojombo/jekyll
[jekyll]: http://jekyllrb.com

View File

@ -0,0 +1,189 @@
/*****************************************************************************/
/*
/* Common
/*
/*****************************************************************************/
/* Global Reset */
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
background-color: white;
font: 13.34px helvetica, arial, clean, sans-serif;
*font-size: small;
text-align: center;
}
h1, h2, h3, h4, h5, h6 {
font-size: 100%;
}
h1 {
margin-bottom: 1em;
}
p {
margin: 1em 0;
}
a {
color: #00a;
}
a:hover {
color: black;
}
a:visited {
color: #a0a;
}
table {
font-size: inherit;
font: 100%;
}
/*****************************************************************************/
/*
/* Home
/*
/*****************************************************************************/
ul.posts {
list-style-type: none;
margin-bottom: 2em;
}
ul.posts li {
line-height: 1.75em;
}
ul.posts span {
color: #aaa;
font-family: Monaco, "Courier New", monospace;
font-size: 80%;
}
/*****************************************************************************/
/*
/* Site
/*
/*****************************************************************************/
.site {
font-size: 110%;
text-align: justify;
width: 42em;
margin: 3em auto 2em auto;
line-height: 1.5em;
}
.title {
color: #a00;
font-weight: bold;
margin-bottom: 2em;
}
.site .title a {
color: #a00;
text-decoration: none;
}
.site .title a:hover {
color: black;
}
.site .title a.extra {
color: #aaa;
text-decoration: none;
margin-left: 1em;
}
.site .title a.extra:hover {
color: black;
}
.site .meta {
color: #aaa;
}
.site .footer {
font-size: 80%;
color: #666;
border-top: 4px solid #eee;
margin-top: 2em;
overflow: hidden;
}
.site .footer .contact {
float: left;
margin-right: 3em;
}
.site .footer .contact a {
color: #8085C1;
}
.site .footer .rss {
margin-top: 1.1em;
margin-right: -.2em;
float: right;
}
.site .footer .rss img {
border: 0;
}
/*****************************************************************************/
/*
/* Posts
/*
/*****************************************************************************/
#post {
}
/* standard */
#post pre {
border: 1px solid #ddd;
background-color: #eef;
padding: 0 .4em;
}
#post ul,
#post ol {
margin-left: 1.35em;
}
#post code {
border: 1px solid #ddd;
background-color: #eef;
font-size: 85%;
padding: 0 .2em;
}
#post pre code {
border: none;
}
/* terminal */
#post pre.terminal {
border: 1px solid black;
background-color: #333;
color: white;
}
#post pre.terminal code {
background-color: #333;
}

View File

@ -0,0 +1,60 @@
.highlight { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -0,0 +1,13 @@
---
layout: default
title: Your New Jekyll Site
---
<div id="home">
<h1>Blog Posts</h1>
<ul class="posts">
{% for post in site.posts %}
<li><span>{{ post.date | date_to_string }}</span> &raquo; <a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</div>

View File

@ -22,6 +22,11 @@ paginate: 5
The number should be the maximum number of posts youd like to be displayed per-page in the generated site. The number should be the maximum number of posts youd like to be displayed per-page in the generated site.
<div class="note info">
<h5>Pagination does not support tags or categories</h5>
<p>Pagination pages through every post in the <code>posts</code> variable regardless of variables defined in the YAML Front Matter of each. It does not currently allow paging over groups of posts linked by a common tag or category.</p>
</div>
## Render the paginated posts ## Render the paginated posts
The next thing you need to do is to actually display your posts in a list using the `paginator` variable that will now be available to you. Youll probably want to do this in one of the main pages of your site. Heres one example of a simple way of rendering paginated posts in a HTML file: The next thing you need to do is to actually display your posts in a list using the `paginator` variable that will now be available to you. Youll probably want to do this in one of the main pages of your site. Heres one example of a simple way of rendering paginated posts in a HTML file:

View File

@ -28,17 +28,27 @@ class Test::Unit::TestCase
include RR::Adapters::TestUnit include RR::Adapters::TestUnit
def dest_dir(*subdirs) def dest_dir(*subdirs)
File.join(File.dirname(__FILE__), 'dest', *subdirs) test_dir('dest', *subdirs)
end end
def source_dir(*subdirs) def source_dir(*subdirs)
File.join(File.dirname(__FILE__), 'source', *subdirs) test_dir('source', *subdirs)
end end
def clear_dest def clear_dest
FileUtils.rm_rf(dest_dir) FileUtils.rm_rf(dest_dir)
end end
def test_dir(*subdirs)
File.join(File.dirname(__FILE__), *subdirs)
end
def directory_with_contents(path)
FileUtils.rm_rf(path)
FileUtils.mkdir(path)
File.open("#{path}/index.html", "w"){ |f| f.write("I was previously generated.") }
end
def capture_stdout def capture_stdout
$old_stdout = $stdout $old_stdout = $stdout
$stdout = StringIO.new $stdout = StringIO.new

View File

@ -0,0 +1,8 @@
module Jekyll
class Dummy < Generator
priority :high
def generate(site)
end
end
end

View File

@ -0,0 +1,14 @@
---
layout: ~
title: Post Excerpt
---
First paragraph with [link ref][link].
Second paragraph
---
Third paragraph
[link]: http://www.jekyllrb.com/

View File

@ -0,0 +1 @@
../css

View File

@ -0,0 +1 @@
../index.html

View File

@ -8,4 +8,4 @@ require 'test/unit'
tests = Dir[File.expand_path("#{File.dirname(__FILE__)}/test_*.rb")] tests = Dir[File.expand_path("#{File.dirname(__FILE__)}/test_*.rb")]
tests.each do |file| tests.each do |file|
require file require file
end end

39
test/test_command.rb Normal file
View File

@ -0,0 +1,39 @@
require 'helper'
class TestCommand < Test::Unit::TestCase
context "when calling .globs" do
context "when non-default dest & source dirs" do
setup do
@source = source_dir
@dest = dest_dir
directory_with_contents(@dest)
@globs = Command.globs(@source, @dest)
end
should "return an array without the destination dir" do
assert @globs.is_a?(Array)
assert !@globs.include?(@dest)
end
teardown do
clear_dest
end
end
context "when using default dest dir" do
setup do
@source = test_dir
@dest = test_dir('_site')
directory_with_contents(@dest)
@globs = Command.globs(@source, @dest)
end
should "return an array without the destination dir" do
assert @globs.is_a?(Array)
assert !@globs.include?(@dest)
@globs.each do |glob|
assert !glob.include?(File.basename(@dest))
end
end
teardown do
FileUtils.rm_r(@dest)
end
end
end
end

View File

@ -25,4 +25,31 @@ class TestConfiguration < Test::Unit::TestCase
assert_equal Jekyll::DEFAULTS, Jekyll.configuration({}) assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
end end
end end
context "loading config from external file" do
setup do
@paths = {
:default => File.join(Dir.pwd, '_config.yml'),
:other => File.join(Dir.pwd, '_config.live.yml'),
:empty => ""
}
end
should "load default config if no config_file is set" do
mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
mock($stdout).puts("Configuration file: #{@paths[:default]}")
assert_equal Jekyll::DEFAULTS, Jekyll.configuration({})
end
should "load different config if specified" do
mock(YAML).safe_load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
mock($stdout).puts("Configuration file: #{@paths[:other]}")
assert_equal Jekyll::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => @paths[:other] })
end
should "load default config if path passed is empty" do
mock(YAML).safe_load_file(@paths[:default]) { Hash.new }
mock($stdout).puts("Configuration file: #{@paths[:default]}")
assert_equal Jekyll::DEFAULTS, Jekyll.configuration({ "config" => @paths[:empty] })
end
end
end end

View File

@ -14,7 +14,7 @@ class TestGeneratedSite < Test::Unit::TestCase
end end
should "ensure post count is as expected" do should "ensure post count is as expected" do
assert_equal 30, @site.posts.size assert_equal 31, @site.posts.size
end end
should "insert site.posts into the index" do should "insert site.posts into the index" do

104
test/test_new_command.rb Normal file
View File

@ -0,0 +1,104 @@
require 'helper'
require 'jekyll/commands/new'
class TestNewCommand < Test::Unit::TestCase
def dir_contents(path)
Dir["#{path}/**/*"].each do |file|
file.gsub! path, ''
end
end
def site_template
File.expand_path("../lib/site_template", File.dirname(__FILE__))
end
context 'when args contains a path' do
setup do
@path = 'new-site'
@args = [@path]
@full_path = File.expand_path(@path, Dir.pwd)
end
teardown do
FileUtils.rm_r @full_path
end
should 'create a new directory' do
assert !File.exists?(@full_path)
capture_stdout { Jekyll::Commands::New.process(@args) }
assert File.exists?(@full_path)
end
should 'display a success message' do
output = capture_stdout { Jekyll::Commands::New.process(@args) }
success_message = "New jekyll site installed in #{@full_path}.\n"
assert_equal success_message, output
end
should 'copy the static files in site template to the new directory' do
static_template_files = dir_contents(site_template).reject do |f|
File.extname(f) == '.erb'
end
capture_stdout { Jekyll::Commands::New.process(@args) }
new_site_files = dir_contents(@full_path).reject do |f|
File.extname(f) == '.markdown'
end
assert_same_elements static_template_files, new_site_files
end
should 'process any ERB files' do
erb_template_files = dir_contents(site_template).select do |f|
File.extname(f) == '.erb'
end
stubbed_date = '2013-01-01'
stub.instance_of(Time).strftime { stubbed_date }
erb_template_files.each do |f|
f.chomp! '.erb'
f.gsub! '0000-00-00', stubbed_date
end
capture_stdout { Jekyll::Commands::New.process(@args) }
new_site_files = dir_contents(@full_path).select do |f|
erb_template_files.include? f
end
assert_same_elements erb_template_files, new_site_files
end
end
context 'when multiple args are given' do
setup do
@site_name_with_spaces = 'new site name'
@multiple_args = @site_name_with_spaces.split
end
teardown do
FileUtils.rm_r File.expand_path(@site_name_with_spaces, Dir.pwd)
end
should 'create a new directory' do
assert !File.exists?(@site_name_with_spaces)
capture_stdout { Jekyll::Commands::New.process(@multiple_args) }
assert File.exists?(@site_name_with_spaces)
end
end
context 'when no args are given' do
setup do
@empty_args = []
end
should 'raise an ArgumentError' do
exception = assert_raise ArgumentError do
Jekyll::Commands::New.process(@empty_args)
end
assert_equal 'You must specify a path.', exception.message
end
end
end

View File

@ -252,6 +252,52 @@ class TestPost < Test::Unit::TestCase
assert_equal "<h1>{{ page.title }}</h1>\n<p>Best <strong>post</strong> ever</p>", @post.content assert_equal "<h1>{{ page.title }}</h1>\n<p>Best <strong>post</strong> ever</p>", @post.content
end end
context "#excerpt" do
setup do
file = "2013-01-02-post-excerpt.markdown"
@post.process(file)
@post.read_yaml(@source, file)
@post.transform
end
should "return first paragraph by default" do
assert @post.excerpt.include?("First paragraph"), "contains first paragraph"
assert !@post.excerpt.include?("Second paragraph"), "does not contains second paragraph"
assert !@post.excerpt.include?("Third paragraph"), "does not contains third paragraph"
end
should "correctly resolve link references" do
assert @post.excerpt.include?("www.jekyllrb.com"), "contains referenced link URL"
end
should "return rendered HTML" do
assert_equal "<p>First paragraph with <a href='http://www.jekyllrb.com/'>link ref</a>.</p>",
@post.excerpt
end
context "with excerpt_separator setting" do
setup do
file = "2013-01-02-post-excerpt.markdown"
@post.site.config['excerpt_separator'] = "\n---\n"
@post.process(file)
@post.read_yaml(@source, file)
@post.transform
end
should "respect given separator" do
assert @post.excerpt.include?("First paragraph"), "contains first paragraph"
assert @post.excerpt.include?("Second paragraph"), "contains second paragraph"
assert !@post.excerpt.include?("Third paragraph"), "does not contains third paragraph"
end
should "replace separator with new-lines" do
assert !@post.excerpt.include?("---"), "does not contains separator"
end
end
end
end end
context "when in a site" do context "when in a site" do

View File

@ -32,6 +32,15 @@ class TestSite < Test::Unit::TestCase
assert_equal [], site.plugins assert_equal [], site.plugins
end end
should "expose default baseurl" do
site = Site.new(Jekyll::DEFAULTS)
assert_equal Jekyll::DEFAULTS['baseurl'], site.baseurl
end
should "expose baseurl passed in from config" do
site = Site.new(Jekyll::DEFAULTS.merge({'baseurl' => '/blog'}))
assert_equal '/blog', site.baseurl
end
end end
context "creating sites" do context "creating sites" do
setup do setup do
@ -45,6 +54,21 @@ class TestSite < Test::Unit::TestCase
assert_equal Hash.new, @site.tags assert_equal Hash.new, @site.tags
end end
should "give site with parsed pages and posts to generators" do
@site.reset
@site.read
class MyGenerator < Generator
def generate(site)
site.pages.dup.each do |page|
raise "#{page} isn't a page" unless page.is_a?(Page)
raise "#{page} doesn't respond to :name" unless page.respond_to?(:name)
end
end
end
@site.generate
assert_not_equal 0, @site.pages.size
end
should "reset data before processing" do should "reset data before processing" do
clear_dest clear_dest
@site.process @site.process
@ -124,6 +148,11 @@ class TestSite < Test::Unit::TestCase
assert_equal mtime3, mtime4 # no modifications, so must be the same assert_equal mtime3, mtime4 # no modifications, so must be the same
end end
should "setup plugins in priority order" do
assert_equal @site.converters.sort_by(&:class).map{|c|c.class.priority}, @site.converters.map{|c|c.class.priority}
assert_equal @site.generators.sort_by(&:class).map{|g|g.class.priority}, @site.generators.map{|g|g.class.priority}
end
should "read layouts" do should "read layouts" do
@site.read_layouts @site.read_layouts
assert_equal ["default", "simple"].sort, @site.layouts.keys.sort assert_equal ["default", "simple"].sort, @site.layouts.keys.sort
@ -188,6 +217,28 @@ class TestSite < Test::Unit::TestCase
assert_equal files, @site.filter_entries(files) assert_equal files, @site.filter_entries(files)
end end
should "not include symlinks in safe mode" do
stub(Jekyll).configuration do
Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'safe' => true})
end
site = Site.new(Jekyll.configuration)
site.read_directories("symlink-test")
assert_equal [], site.pages
assert_equal [], site.static_files
end
should "include symlinks in unsafe mode" do
stub(Jekyll).configuration do
Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'safe' => false})
end
site = Site.new(Jekyll.configuration)
site.read_directories("symlink-test")
assert_not_equal [], site.pages
assert_not_equal [], site.static_files
end
context 'error handling' do context 'error handling' do
should "raise if destination is included in source" do should "raise if destination is included in source" do
stub(Jekyll).configuration do stub(Jekyll).configuration do

View File

@ -170,7 +170,7 @@ CONTENT
assert_match %r{<em>FINISH HIM</em>}, @result assert_match %r{<em>FINISH HIM</em>}, @result
end end
end end
context "using Redcarpet" do context "using Redcarpet" do
setup do setup do
create_post(@content, 'markdown' => 'redcarpet') create_post(@content, 'markdown' => 'redcarpet')
@ -203,22 +203,78 @@ CONTENT
assert_match %r{/2008/11/21/complex/}, @result assert_match %r{/2008/11/21/complex/}, @result
end end
end end
context "simple gist inclusion" do context "gist tag" do
setup do context "simple" do
@gist = 358471 setup do
content = <<CONTENT @gist = 358471
content = <<CONTENT
--- ---
title: My Cool Gist title: My Cool Gist
--- ---
{% gist #{@gist} %} {% gist #{@gist} %}
CONTENT CONTENT
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true}) create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
end
should "write script tag" do
assert_match "<script src='https://gist.github.com/#{@gist}.js'>\s</script>", @result
end
end end
should "write script tag" do context "with specific file" do
assert_match %r{<script src='https://gist.github.com/#{@gist}.js'>\s</script>}, @result setup do
@gist = 358471
@filename = 'somefile.rb'
content = <<CONTENT
---
title: My Cool Gist
---
{% gist #{@gist} #{@filename} %}
CONTENT
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
end
should "write script tag with specific file in gist" do
assert_match "<script src='https://gist.github.com/#{@gist}.js?file=#{@filename}'>\s</script>", @result
end
end
context "with blank gist id" do
setup do
content = <<CONTENT
---
title: My Cool Gist
---
{% gist %}
CONTENT
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
end
should "output error message" do
assert_match "Error parsing gist id", @result
end
end
context "with invalid gist id" do
setup do
invalid_gist = 'invalid'
content = <<CONTENT
---
title: My Cool Gist
---
{% gist #{invalid_gist} %}
CONTENT
create_post(content, {'permalink' => 'pretty', 'source' => source_dir, 'destination' => dest_dir, 'read_posts' => true})
end
should "output error message" do
assert_match "Error parsing gist id", @result
end
end end
end end
end end