Merge branch 'master' into issue-653

This commit is contained in:
Matt Rogers 2013-01-16 21:52:32 -06:00
commit f460a6cf71
43 changed files with 714 additions and 503 deletions

View File

@ -1,4 +1,6 @@
language: ruby
rvm:
- 1.9.3
- 1.9.2
- 1.8.7
script: bundle exec rake

45
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,45 @@
Contribute
==========
So you've got an awesome idea to throw into Jekyll. Great! Please keep the following in mind:
* **Contributions will not be accepted without tests.**
* If you're creating a small fix or patch to an existing feature, just a simple test will do. Please stay in the confines of the current test suite and use [Shoulda](http://github.com/thoughtbot/shoulda/tree/master) and [RR](http://github.com/btakita/rr/tree/master).
* If it's a brand new feature, make sure to create a new [Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps where appropriate. Also, whipping up some documentation in your fork's wiki would be appreciated, and once merged it will be transferred over to the main wiki.
Test Dependencies
-----------------
To run the test suite and build the gem you'll need to install Jekyll's dependencies. Jekyll uses Bundler, so a quick run of the bundle command and you're all set!
$ bundle
Before you start, run the tests and make sure that they pass (to confirm your environment is configured properly):
$ rake test
$ rake features
Workflow
--------
Here's the most direct way to get your work merged into the project:
* Fork the project
* Clone down your fork ( `git clone git://github.com/<username>/jekyll.git` )
* Create a topic branch to contain your change ( `git checkout -b my_awesome_feature` )
* Hack away, add tests. Not necessarily in that order.
* Make sure everything still passes by running `rake`
* If necessary, rebase your commits into logical chunks, without errors
* Push the branch up ( `git push origin my_awesome_feature` )
* Create an issue with a description and link to your branch
Gotchas
-------
* If you want to bump the gem version, please put that in a separate commit. This way, the maintainers can control when the gem gets released.
* Try to keep your patch(es) based from the latest commit on mojombo/jekyll. The easier it is to apply your work, the less work the maintainers have to do, which is always a good thing.
* Please don't tag your GitHub issue with [fix], [feature], etc. The maintainers actively read the issues and will label it once they come across it.
Finally...
----------
Thanks! Hacking on Jekyll should be fun, and if for some reason it's a pain to do let us know so we can fix it.

View File

@ -1,5 +1,13 @@
== HEAD
* Major Enhancements
* Refactored jekyll commands into subcommands: build, serve, and migrate. (#690)
* Minor Enhancements
* Massively accelerate LSI performance (#664)
* Truncate post slugs when importing from Tumblr (#496)
* Add glob support to include, exclude option (#743)
* Layout of Page or Post defaults to 'page' or 'post', respectively (#580)
* "Keep files" feature (#685)
* Output full path & name for files that don't parse (#745)
* Add source and destination directory protection (#535)
* Better YAML error message (#718)
* Bug Fixes

View File

@ -1,5 +1,7 @@
h1. Jekyll
!https://travis-ci.org/mojombo/jekyll.png?branch=master!:https://travis-ci.org/mojombo/jekyll
By Tom Preston-Werner, Nick Quaranto, and many awesome contributors!
Jekyll is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind "GitHub Pages":http://pages.github.com, which you can use to host your project's page or blog right here from GitHub.

View File

@ -131,7 +131,7 @@ namespace :site do
# Generate the site in server mode.
puts "Running Jekyll..."
Dir.chdir("site") do
sh "#{File.expand_path('bin/jekyll', File.dirname(__FILE__))} --server"
sh "#{File.expand_path('bin/jekyll', File.dirname(__FILE__))} serve --watch"
end
end

View File

@ -1,299 +1,70 @@
#!/usr/bin/env ruby
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
$:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
help = <<HELP
Jekyll is a blog-aware, static site generator.
Basic Command Line Usage:
jekyll # . -> ./_site
jekyll <path to write generated site> # . -> <path>
jekyll <path to source> <path to write generated site> # <path> -> <path>
jekyll import <importer name> <options> # imports posts using named import script
Configuration is read from '<source>/_config.yml' but can be overriden
using the following options:
HELP
require 'optparse'
require 'commander/import'
require 'jekyll'
program :name, 'jekyll'
program :version, Jekyll::VERSION
program :description, 'Jekyll is a blog-aware, static site generator in Ruby'
exec = {}
options = {}
opts = OptionParser.new do |opts|
opts.banner = help
default_command :help
opts.on("--file [PATH]", "File to import from") do |import_file|
options['file'] = import_file
end
opts.on("--dbname [TEXT]", "DB to import from") do |import_dbname|
options['dbname'] = import_dbname
end
opts.on("--user [TEXT]", "Username to use when importing") do |import_user|
options['user'] = import_user
end
opts.on("--pass [TEXT]", "Password to use when importing") do |import_pass|
options['pass'] = import_pass
end
opts.on("--host [HOST ADDRESS]", "Host to import from") do |import_host|
options['host'] = import_host
end
opts.on("--site [SITE NAME]", "Site to import from") do |import_site|
options['site'] = import_site
end
global_option '-s', '--source [DIR]', 'Source directory (defaults to ./)'
global_option '-d', '--destination [DIR]', 'Destination directory (defaults to ./_site)'
global_option '--safe', 'Safe mode (defaults to false)'
global_option '--plugins', 'Plugins directory (defaults to ./_plugins)'
global_option '--layouts', 'Layouts directory (defaults to ./_layouts)'
opts.on("--[no-]safe", "Safe mode (default unsafe)") do |safe|
options['safe'] = safe
end
command :build do |c|
c.syntax = 'jekyll build [options]'
c.description = 'Build your site with the option of auto-renegeration'
opts.on("--[no-]auto", "Auto-regenerate") do |auto|
options['auto'] = auto
end
c.option '-w', '--watch', 'Watch for changes and rebuild'
c.option '--lsi', 'Use LSI for improved related posts'
opts.on("--server [PORT]", "Start web server (default port 4000)") do |port|
options['server'] = true
options['server_port'] = port unless port.nil?
end
opts.on("--no-server", "Do not start a web server") do |part|
options['server'] = false
end
opts.on("--base-url [BASE_URL]", "Serve website from a given base URL (default '/'") do |baseurl|
options['baseurl'] = baseurl
end
opts.on("--default-mimetype [MT]", "Mimetype to use when no file extension (if --server)") do |mt|
options['default-mimetype'] = mt
end
opts.on("--[no-]lsi", "Use LSI for better related posts") do |lsi|
options['lsi'] = lsi
end
opts.on("--[no-]pygments", "Use pygments to highlight code") do |pygments|
options['pygments'] = pygments
end
opts.on("--rdiscount", "Use rdiscount gem for Markdown") do
options['markdown'] = 'rdiscount'
end
opts.on("--redcarpet", "Use redcarpet gem for Markdown") do
options['markdown'] = 'redcarpet'
end
opts.on("--kramdown", "Use kramdown gem for Markdown") do
options['markdown'] = 'kramdown'
end
opts.on("--time [TIME]", "Time to generate the site for") do |time|
options['time'] = Time.parse(time)
end
opts.on("--[no-]future", "Render future dated posts") do |future|
options['future'] = future
end
opts.on("--permalink [TYPE]", "Use 'date' (default) for YYYY/MM/DD") do |style|
options['permalink'] = style unless style.nil?
end
opts.on("--paginate [POSTS_PER_PAGE]", "Paginate a blog's posts") do |per_page|
begin
options['paginate'] = per_page.to_i
raise ArgumentError if options['paginate'] == 0
rescue
puts 'you must specify a number of posts by page bigger than 0'
exit 0
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
raise ArgumentError if options['limit_posts'] < 1
rescue
puts 'you must specify a number of posts by page bigger than 0'
exit 0
end
end
opts.on("--url [URL]", "Set custom site.url") do |url|
options['url'] = url
end
opts.on("--version", "Display current version") do
puts "Jekyll " + Jekyll::VERSION
exit 0
c.action do |args, options|
options.defaults :serving => false
options = Jekyll.configuration(options.__hash__)
Jekyll::BuildCommand.process(options)
end
end
# Read command line options into `options` hash
opts.parse!
command :serve do |c|
c.syntax = 'jekyll serve [options]'
c.description = 'Serve your site locally with the option of auto-regeneration'
c.option '-w', '--watch', 'Watch for changes and rebuild'
c.option '--lsi', 'Use LSI for improved related posts'
# Check for import stuff
if ARGV.size > 0
if ARGV[0] == 'import'
migrator = ARGV[1]
c.option '-p', '--port [PORT]', 'Port to listen on'
c.option '-h', '--host [HOST]', 'Host to bind to'
c.option '-b', '--baseurl [URL]', 'Base URL'
if migrator.nil?
puts "Invalid options. Run `jekyll --help` for assistance."
exit(1)
else
migrator = migrator.downcase
end
c.action do |args, options|
options.default :port => '4000',
:host => '0.0.0.0',
:baseurl => '/',
:serving => true
cmd_options = []
['file', 'dbname', 'user', 'pass', 'host', 'site'].each do |p|
cmd_options << "\"#{options[p]}\"" unless options[p].nil?
end
# It's import time
puts "Importing..."
# Ideally, this shouldn't be necessary. Maybe parse the actual
# src files for the migrator name?
migrators = {
:posterous => 'Posterous',
:wordpressdotcom => 'WordpressDotCom',
:wordpress => 'WordPress',
:csv => 'CSV',
:drupal => 'Drupal',
:enki => 'Enki',
:mephisto => 'Mephisto',
:mt => 'MT',
:textpattern => 'TextPattern',
:tumblr => 'Tumblr',
:typo => 'Typo'
}
app_root = File.join(File.dirname(__FILE__), '..')
require "#{app_root}/lib/jekyll/migrators/#{migrator}"
if Jekyll.const_defined?(migrators[migrator.to_sym])
migrator_class = Jekyll.const_get(migrators[migrator.to_sym])
migrator_class.process(*cmd_options)
else
puts "Invalid migrator. Run `jekyll --help` for assistance."
exit(1)
end
exit(0)
options = Jekyll.configuration(options.__hash__)
Jekyll::BuildCommand.process(options)
Jekyll::ServeCommand.process(options)
end
end
command :import do |c|
c.syntax = 'jekyll import <platform> [options]'
c.description = 'Import your old blog to Jekyll'
c.option '--file', 'File to migrate from'
c.option '--dbname', 'Database name to migrate from'
c.option '--user', 'Username to use when migrating'
c.option '--pass', 'Password to use when migrating'
c.option '--host', 'Host address to use when migrating'
# Get source and destination from command line
case ARGV.size
when 0
when 1
options['destination'] = ARGV[0]
when 2
options['source'] = ARGV[0]
options['destination'] = ARGV[1]
else
puts "Invalid options. Run `jekyll --help` for assistance."
exit(1)
end
options = Jekyll.configuration(options)
# Get source and destination directories (possibly set by config file)
source = options['source']
destination = options['destination']
# Files to watch
def globs(source, destination)
Dir.chdir(source) do
dirs = Dir['*'].select { |x| File.directory?(x) }
dirs -= [destination]
dirs = dirs.map { |x| "#{x}/**/*" }
dirs += ['*']
c.action do |args, options|
Jekyll::MigrateCommand.process(args.first, options)
end
end
# Create the Site
site = Jekyll::Site.new(options)
# Run the directory watcher for auto-generation, if required
if options['auto']
require 'directory_watcher'
puts "Auto-regenerating enabled: #{source} -> #{destination}"
dw = DirectoryWatcher.new(source)
dw.interval = 1
dw.glob = globs(source, destination)
dw.add_observer do |*args|
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
puts "[#{t}] regeneration: #{args.size} files changed"
site.process
end
dw.start
unless options['server']
loop { sleep 1000 }
end
else
puts "Building site: #{source} -> #{destination}"
begin
site.process
rescue Jekyll::FatalException => e
puts
puts "ERROR: YOUR SITE COULD NOT BE BUILT:"
puts "------------------------------------"
puts e.message
exit(1)
end
puts "Successfully generated site: #{source} -> #{destination}"
end
# Run the server on the specified port, if required
if options['server']
require 'webrick'
include WEBrick
FileUtils.mkdir_p(destination)
mime_types = WEBrick::HTTPUtils::DefaultMimeTypes
mime_types.store 'js', 'application/javascript'
if options['default-mimetype']
mime_types.store(nil, options['default-mimetype'])
end
s = HTTPServer.new(
:Port => options['server_port'],
:MimeTypes => mime_types
)
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination)
t = Thread.new {
s.start
}
trap("INT") { s.shutdown }
t.join()
end

View File

@ -1 +1,2 @@
default: --format progress
default: --format progress
html_report: --format progress --format html --out=features_report.html

View File

@ -22,7 +22,7 @@ Feature: Site configuration
Given I have an "Rakefile" file that contains "I want to be excluded"
And I have an "README" file that contains "I want to be excluded"
And I have an "index.html" file that contains "I want to be included"
And I have a configuration file with "exclude" set to "Rakefile", "README"
And I have a configuration file with "exclude" set to "['Rakefile', 'README']"
When I run jekyll
Then I should see "I want to be included" in "_site/index.html"
And the "_site/Rakefile" file should not exist

View File

@ -11,6 +11,7 @@ JEKYLL_PATH = File.join(ENV['PWD'], 'bin', 'jekyll')
def run_jekyll(opts = {})
command = JEKYLL_PATH
command << " build"
command << " >> /dev/null 2>&1" if opts[:debug].nil?
system command
end

View File

@ -29,6 +29,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency('maruku', "~> 0.5")
s.add_runtime_dependency('kramdown', "~> 0.13.4")
s.add_runtime_dependency('pygments.rb', "~> 0.3.2")
s.add_runtime_dependency('commander', "~> 4.1.3")
s.add_development_dependency('rake', "~> 0.9")
s.add_development_dependency('rdoc', "~> 3.11")
@ -43,6 +44,8 @@ Gem::Specification.new do |s|
# = MANIFEST =
s.files = %w[
.travis.yml
CONTRIBUTING.md
Gemfile
History.txt
LICENSE
@ -62,6 +65,10 @@ Gem::Specification.new do |s|
features/support/env.rb
jekyll.gemspec
lib/jekyll.rb
lib/jekyll/command.rb
lib/jekyll/commands/build.rb
lib/jekyll/commands/migrate.rb
lib/jekyll/commands/serve.rb
lib/jekyll/converter.rb
lib/jekyll/converters/identity.rb
lib/jekyll/converters/markdown.rb
@ -96,6 +103,8 @@ Gem::Specification.new do |s|
lib/jekyll/tags/include.rb
lib/jekyll/tags/post_url.rb
test/fixtures/broken_front_matter1.erb
test/fixtures/broken_front_matter2.erb
test/fixtures/broken_front_matter3.erb
test/fixtures/front_matter.erb
test/helper.rb
test/source/.htaccess

View File

@ -41,6 +41,9 @@ require 'jekyll/errors'
require 'jekyll/plugin'
require 'jekyll/converter'
require 'jekyll/generator'
require 'jekyll/command'
require_all 'jekyll/commands'
require_all 'jekyll/converters'
require_all 'jekyll/generators'
require_all 'jekyll/tags'
@ -48,26 +51,22 @@ require_all 'jekyll/tags'
module Jekyll
VERSION = '0.12.0'
# Default options. Overriden by values in _config.yml or command-line opts.
# Default options. Overriden by values in _config.yml.
# Strings rather than symbols are used for compatability with YAML.
DEFAULTS = {
'safe' => false,
'auto' => false,
'server' => false,
'server_port' => 4000,
'source' => Dir.pwd,
'destination' => File.join(Dir.pwd, '_site'),
'plugins' => '_plugins',
'layouts' => '_layouts',
'keep_files' => ['.git','.svn'],
'future' => true,
'lsi' => false,
'pygments' => false,
'markdown' => 'maruku',
'permalink' => 'date',
'include' => ['.htaccess'],
'paginate_path' => 'page:num',
'future' => true, # remove and make true just default
'pygments' => false, # remove and make true just default
'markdown' => 'maruku', # no longer a command option
'permalink' => 'date', # no longer a command option
'include' => ['.htaccess'], # no longer a command option
'paginate_path' => 'page:num', # no longer a command option
'markdown_ext' => 'markdown,mkd,mkdn,md',
'textile_ext' => 'textile',
@ -120,6 +119,9 @@ module Jekyll
#
# Returns the final configuration Hash.
def self.configuration(override)
# Convert any symbol keys to strings and remove the old key/values
override = override.reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
# _config.yml may override default source location, but until
# then, we need to know where to look for _config.yml
source = override['source'] || Jekyll::DEFAULTS['source']

14
lib/jekyll/command.rb Normal file
View File

@ -0,0 +1,14 @@
module Jekyll
class Command
def self.globs(source)
Dir.chdir(source) do
dirs = Dir['*'].select { |x| File.directory?(x) }
dirs -= ['_site']
dirs = dirs.map { |x| "#{x}/**/*" }
dirs += ['*']
end
end
end
end

View File

@ -0,0 +1,76 @@
module Jekyll
class BuildCommand < Command
def self.process(options)
site = Jekyll::Site.new(options)
source = options['source']
destination = options['destination']
if options['watch']
self.watch(site, options)
else
self.build(site, options)
end
end
# Private: Build the site from source into destination.
#
# site - A Jekyll::Site instance
# options - A Hash of options passed to the command
#
# Returns nothing.
def self.build(site, options)
source = options['source']
destination = options['destination']
puts "Building site: #{source} -> #{destination}"
begin
site.process
rescue Jekyll::FatalException => e
puts
puts "ERROR: YOUR SITE COULD NOT BE BUILT:"
puts "------------------------------------"
puts e.message
exit(1)
end
puts "Successfully generated site: #{source} -> #{destination}"
end
# Private: Watch for file changes and rebuild the site.
#
# site - A Jekyll::Site instance
# options - A Hash of options passed to the command
#
# Returns nothing.
def self.watch(site, options)
require 'directory_watcher'
source = options['source']
destination = options['destination']
puts "Auto-Regenerating enabled: #{source} -> #{destination}"
dw = DirectoryWatcher.new(source)
dw.interval = 1
dw.glob = self.globs(source)
dw.add_observer do |*args|
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
puts "[#{t}] regeneration: #{args.size} files changed"
site.process
end
dw.start
unless options['serving']
trap("INT") do
puts "Stopping auto-regeneration..."
exit 0
end
loop { sleep 1000 }
end
end
end
end

View File

@ -0,0 +1,47 @@
module Jekyll
class MigrateCommand < Command
MIGRATORS = {
:csv => 'CSV',
:drupal => 'Drupal',
:enki => 'Enki',
:mephisto => 'Mephisto',
:mt => 'MT',
:posterous => 'Posterous',
:textpattern => 'TextPattern',
:tumblr => 'Tumblr',
:typo => 'Typo',
:wordpressdotcom => 'WordpressDotCom',
:wordpress => 'WordPress'
}
def self.process(migrator, options)
abort 'missing argument. Please specify a migrator' if migrator.nil?
migrator = migrator.downcase
cmd_options = []
[ :file, :dbname, :user, :pass, :host, :site ].each do |p|
cmd_options << "\"#{options[p]}\"" unless options[p].nil?
end
if MIGRATORS.keys.include?(migrator)
app_root = File.expand_path(
File.join(File.dirname(__FILE__), '..', '..', '..')
)
require "#{app_root}/lib/jekyll/migrators/#{migrator}"
if Jekyll.const_defiend?(MIGRATORS[migrator.to_sym])
puts 'Importing...'
migrator_class = Jekyll.const_get(MIGRATORS[migrator.to_sym])
migrator_class.process(*cmd_options)
exit 0
end
end
abort 'invalid migrator. Please specify a valid migrator'
end
end
end

View File

@ -0,0 +1,28 @@
module Jekyll
class ServeCommand < Command
def self.process(options)
require 'webrick'
include WEBrick
destination = options['destination']
FileUtils.mkdir_p(destination)
mime_types = WEBrick::HTTPUtils::DefaultMimeTypes
mime_types.store 'js', 'application/javascript'
s = HTTPServer.new(
:Port => options['port'],
:BindAddress => options['host'],
:MimeTypes => mime_types
)
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination)
t = Thread.new { s.start }
trap("INT") { s.shutdown }
t.join()
end
end
end

View File

@ -33,9 +33,9 @@ module Jekyll
self.data = YAML.load($1)
end
rescue => e
puts "Error reading file #{name}: #{e.message}"
puts "Error reading file #{File.join(base, name)}: #{e.message}"
rescue SyntaxError => e
puts "YAML Exception reading #{name}: #{e.message}"
puts "YAML Exception reading #{File.join(base, name)}: #{e.message}"
end
self.data ||= {}

View File

@ -50,3 +50,11 @@ class Date
strftime("%Y-%m-%dT%H:%M:%S%Z")
end if RUBY_VERSION < '1.9'
end
module Enumerable
# Returns true if path matches against any glob pattern.
# Look for more detail about glob pattern in method File::fnmatch.
def glob_include?(e)
any? { |exp| File.fnmatch?(exp, e) }
end
end

View File

@ -1,14 +1,11 @@
require 'rubygems'
require 'jekyll'
require 'fileutils'
require 'net/https'
require 'open-uri'
require 'net/http'
require 'uri'
require "json"
# ruby -r './lib/jekyll/migrators/posterous.rb' -e 'Jekyll::Posterous.process(email, pass, api_token, blog, tags_key)'
# You can find your api token in posterous api page - http://posterous.com/api . Click on any of the 'view token' links to see your token.
# blog is optional, by default it is the primary one
# ruby -r './lib/jekyll/migrators/posterous.rb' -e 'Jekyll::Posterous.process(email, pass, api_key, blog)'
module Jekyll
module Posterous
@ -17,9 +14,6 @@ module Jekyll
raise ArgumentError, 'Stuck in a redirect loop. Please double check your email and password' if limit == 0
response = nil
puts uri_str
puts '-------'
Net::HTTP.start('posterous.com') do |http|
req = Net::HTTP::Get.new(uri_str)
req.basic_auth @email, @pass
@ -29,50 +23,36 @@ module Jekyll
case response
when Net::HTTPSuccess then response
when Net::HTTPRedirection then fetch(response['location'], limit - 1)
when Net::HTTPForbidden then
retry_after = response.to_hash['retry-after'][0]
puts "We have been told to try again after #{retry_after} seconds"
sleep(retry_after.to_i + 1)
fetch(uri_str, limit - 1)
else response.error!
end
end
def self.process(email, pass, api_token, blog = 'primary', tags_key = 'categories')
def self.process(email, pass, api_token, blog = 'primary')
@email, @pass, @api_token = email, pass, api_token
FileUtils.mkdir_p "_posts"
posts = JSON.parse(self.fetch("/api/2/sites/#{blog}/posts?api_token=#{@api_token}").body)
posts = JSON.parse(self.fetch("/api/v2/users/me/sites/#{blog}/posts?api_token=#{@api_token}").body)
page = 1
while posts.any?
posts.each do |post|
title = post["title"]
slug = title.gsub(/[^[:alnum:]]+/, '-').gsub(/^-+|-+$/, '').downcase
posterous_slug = post["slug"]
slug = title.gsub(/[^[:alnum:]]+/, '-').downcase
date = Date.parse(post["display_date"])
content = post["body_html"]
published = !post["is_private"]
name = "%02d-%02d-%02d-%s.html" % [date.year, date.month, date.day, slug]
tags = []
post["tags"].each do |tag|
tags.push(tag["name"])
end
# Get the relevant fields as a hash, delete empty fields and convert
# to YAML for the header
data = {
'layout' => 'post',
'title' => title.to_s,
'published' => published,
tags_key => tags,
'posterous_url' => post["full_url"],
'posterous_slug' => posterous_slug
'published' => published
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
# Write out the data and content to file
File.open("_posts/#{name}", "w") do |f|
puts name
f.puts data
f.puts "---"
f.puts content
@ -80,7 +60,7 @@ module Jekyll
end
page += 1
posts = JSON.parse(self.fetch("/api/2/sites/#{blog}/posts?api_token=#{@api_token}&page=#{page}").body)
posts = JSON.parse(self.fetch("/api/v2/users/me/sites/#{blog}/posts?api_token=#{@api_token}&page=#{page}").body)
end
end
end

View File

@ -34,6 +34,7 @@ module Jekyll
post[:content] = html_to_markdown post[:content]
post[:content] = add_syntax_highlights post[:content] if add_highlights
end
post[:name] = truncate_post_name post[:name] if post[:name].size > 255
File.open("_posts/tumblr/#{post[:name]}", "w") do |f|
f.puts post[:header].to_yaml + "---\n" + post[:content]
end
@ -42,6 +43,11 @@ module Jekyll
private
def self.truncate_post_name name
post = name.match(/^(.+)\.(.+)$/).captures
post[0][0..(-1 - post[1].size)] + post[1].size
end
# Converts each type of Tumblr post to a hash with all required
# data for Jekyll.
def self.post_to_hash(post, format)

View File

@ -24,6 +24,18 @@ module Jekyll
self.read_yaml(File.join(base, dir), name)
end
# Read the YAML frontmatter.
#
# base - The String path to the dir containing the file.
# name - The String filename of the file.
#
# Returns nothing.
def read_yaml(base, name)
super(base, name)
self.data['layout'] = 'page' unless self.data.has_key?('layout')
self.data
end
# The generated directory into which the page will be placed
# upon generation. This is derived from the permalink or, if
# permalink is absent, we be '/'

View File

@ -66,6 +66,18 @@ module Jekyll
end
end
# Read the YAML frontmatter.
#
# base - The String path to the dir containing the file.
# name - The String filename of the file.
#
# Returns nothing.
def read_yaml(base, name)
super(base, name)
self.data['layout'] = 'post' unless self.data.has_key?('layout')
self.data
end
# Compares Post objects. First compares the Post date. If the dates are
# equal, it compares the Post slugs.
#
@ -171,9 +183,12 @@ module Jekyll
if self.site.lsi
self.class.lsi ||= begin
puts "Running the classifier... this could take a while."
lsi = Classifier::LSI.new
puts "Starting the classifier..."
lsi = Classifier::LSI.new(:auto_rebuild => false)
$stdout.print(" Populating LSI... ");$stdout.flush
posts.each { |x| $stdout.print(".");$stdout.flush;lsi.add_item(x) }
$stdout.print("\n Rebuilding LSI index... ")
lsi.build_index
puts ""
lsi
end

View File

@ -5,7 +5,8 @@ module Jekyll
class Site
attr_accessor :config, :layouts, :posts, :pages, :static_files,
: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,
:keep_files
attr_accessor :converters, :generators
@ -26,6 +27,7 @@ module Jekyll
self.include = config['include'] || []
self.future = config['future']
self.limit_posts = config['limit_posts'] || nil
self.keep_files = config['keep_files'] || []
self.reset
self.setup
@ -234,8 +236,12 @@ module Jekyll
def cleanup
# all files and directories in destination, including hidden ones
dest_files = Set.new
Dir.glob(File.join(self.dest, "**", "*")) do |file|
dest_files << file
Dir.glob(File.join(self.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
if self.keep_files.length > 0
dest_files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
else
dest_files << file unless file =~ /\/\.{1,2}$/
end
end
# files to be written
@ -256,10 +262,21 @@ module Jekyll
files.merge(dirs)
obsolete_files = dest_files - files
FileUtils.rm_rf(obsolete_files.to_a)
end
# Private: creates a regular expression from the keep_files array
#
# Examples
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
#
# Returns the regular expression
def keep_file_regex
or_list = self.keep_files.join("|")
pattern = "\/(#{or_list.gsub(".", "\.")})"
Regexp.new pattern
end
# Write static files, pages, and posts.
#
# Returns nothing.
@ -330,10 +347,10 @@ module Jekyll
# Returns the Array of filtered entries.
def filter_entries(entries)
entries.reject do |e|
unless self.include.include?(e)
unless self.include.glob_include?(e)
['.', '_', '#'].include?(e[0..0]) ||
e[-1..-1] == '~' ||
self.exclude.include?(e) ||
self.exclude.glob_include?(e) ||
File.symlink?(e)
end
end

View File

@ -15,8 +15,8 @@ module Jekyll
super
if markup.strip =~ SYNTAX
@lang = $1
@options = {}
if defined?($2) && $2 != ''
tmp_options = {}
$2.split.each do |opt|
key, value = opt.split('=')
if value.nil?
@ -26,13 +26,8 @@ module Jekyll
value = true
end
end
tmp_options[key] = value
@options[key] = value
end
tmp_options = tmp_options.to_a.sort.collect { |opt| opt.join('=') }
# additional options to pass to Albino
@options = { 'O' => tmp_options.join(',') }
else
@options = {}
end
else
raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")

View File

@ -71,6 +71,9 @@
<li class="{% if page.title == "Troubleshooting" %}current{% endif %}">
<a href="{{ site.url }}/docs/troubleshooting">Troubleshooting</a>
</li>
<li class="{% if page.title == "Sites using Jekyll" %}current{% endif %}">
<a href="{{ site.url }}/docs/sites">Sites using Jekyll</a>
</li>
<li class="{% if page.title == "Resources" %}current{% endif %}">
<a href="{{ site.url }}/docs/resources">Resources</a>
</li>

View File

@ -9,6 +9,8 @@ Jekyll allows you to concoct your sites in any way you can dream up, and its
## Configuration Settings
### Global Configuration
The table below lists the available settings for Jekyll, and the various <code class="option">options</code> (specifed in the configuration file) and <code class="flag">flags</code> (specified on the command-line) that control them.
<table>
@ -19,6 +21,26 @@ The table below lists the available settings for Jekyll, and the various <code c
</tr>
</thead>
<tbody>
<tr class='setting'>
<td>
<p class='name'><strong>Site Source</strong></p>
<p class='description'>Changes the directory where Jekyll will look to transform files</p>
</td>
<td class="align-center">
<p><code class="option">source: [string]</code></p>
<p><code class="flag">--source [source]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Site Destination</strong></p>
<p class='description'>Changes the directory where Jekyll will write files to</p>
</td>
<td class="align-center">
<p><code class="option">destination: [string]</code></p>
<p><code class="flag">--destination</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Safe</strong></p>
@ -29,140 +51,6 @@ The table below lists the available settings for Jekyll, and the various <code c
<p><code class="flag">--safe</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Regeneration</strong></p>
<p class='description'>Enables or disables Jekyll from recreating the site when files are modified.</p>
</td>
<td class="align-center">
<p><code class="option">auto: [boolean]</code></p>
<p><code class="flag">--auto</code></p>
<p><code class="flag">--no-auto</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Local Server</strong></p>
<p class='description'>Fires up a server that will host your <code>_site</code> directory</p>
</td>
<td class="align-center">
<p><code class="option">server: [boolean]</code></p>
<p><code class="flag">--server</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Local Server Port</strong></p>
<p class='description'>Changes the port that the Jekyll server will run on</p>
</td>
<td class="align-center">
<p><code class="option">server_port: [integer]</code></p>
<p><code class="flag">--server [port]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Base URL</strong></p>
<p class='description'>Serve website from a given base URL</p>
</td>
<td class="align-center">
<p><code class="option">baseurl: [BASE_URL]</code></p>
<p><code class="flag">--base-url [url]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>URL</strong></p>
<p class='description'>Sets <code>site.url</code>, useful for environment switching</p>
</td>
<td class="align-center">
<p><code class="option">url: [URL]</code></p>
<p><code class="flag">--url [URL]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Site Destination</strong></p>
<p class="description">Changes the directory where Jekyll will write files to</p>
</td>
<td class='align-center'>
<p><code class="option">destination: [dir]</code></p>
<p><code class="flag">jekyll [dest]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Site Source</strong></p>
<p class="description">Changes the directory where Jekyll will look to transform files</p>
</td>
<td class='align-center'>
<p><code class="option">source: [dir]</code></p>
<p><code class="flag">jekyll [source] [dest]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Markdown</strong></p>
<p class="description">Uses RDiscount or <code>[engine]</code> instead of Maruku.</p>
</td>
<td class='align-center'>
<p><code class="option">markdown: [engine]</code></p>
<p><code class="flag">--rdiscount</code></p>
<p><code class="flag">--kramdown</code></p>
<p><code class="flag">--redcarpet</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Pygments</strong></p>
<p class="description">Enables highlight tag with Pygments.</p>
</td>
<td class='align-center'>
<p><code class="option">pygments: [boolean]</code></p>
<p><code class="flag">--pygments</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Future</strong></p>
<p class="description">Publishes posts with a future date</p>
</td>
<td class='align-center'>
<p><code class="option">future: [boolean]</code></p>
<p><code class="flag">--no-future</code></p>
<p><code class="flag">--future</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>LSI</strong></p>
<p class="description">Produces an index for related posts.</p>
</td>
<td class='align-center'>
<p><code class="option">lsi: [boolean]</code></p>
<p><code class="flag">--lsi</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Permalink</strong></p>
<p class="description">Controls the URLs that posts are generated with. Please refer to the <a href="../permalinks">Permalinks</a> page for more info.</p>
</td>
<td class='align-center'>
<p><code class="option">permalink: [style]</code></p>
<p><code class="flag">--permalink=[style]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Pagination</strong></p>
<p class="description">Splits your posts up over multiple subdirectories called "page2", "page3", ... "pageN"</p>
</td>
<td class='align-center'>
<p><code class="option">paginate: [per_page]</code></p>
<p><code class="flag">--paginate [per_page]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Exclude</strong></p>
@ -181,6 +69,98 @@ The table below lists the available settings for Jekyll, and the various <code c
<p><code class="option">include: [dir1, file1, dir2]</code></p>
</td>
</tr>
</tbody>
</table>
### Build Command Options
<table>
<thead>
<tr>
<th>Setting</th>
<th><span class="option">Options</span> and <span class="flag">Flags</span></th>
</tr>
</thead>
<tbody>
<tr class='setting'>
<td>
<p class='name'><strong>Regeneration</strong></p>
<p class='description'>Enables auto-regeneration of the site when files are modified. Off by default.</p>
</td>
<td class="align-center">
<p><code class="flag">--watch</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>URL</strong></p>
<p class='description'>Sets <code>site.url</code>, useful for environment switching</p>
</td>
<td class="align-center">
<p><code class="option">url: [URL]</code></p>
<p><code class="flag">--url [URL]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Markdown</strong></p>
<p class="description">Uses RDiscount or <code>[engine]</code> instead of Maruku.</p>
</td>
<td class='align-center'>
<p><code class="option">markdown: [engine]</code></p>
<p><code class="flag">--markdown [rdiscount|kramdown|redcarpet]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Pygments</strong></p>
<p class="description">Enables highlight tag with Pygments.</p>
</td>
<td class='align-center'>
<p><code class="option">pygments: [boolean]</code></p>
<p><code class="flag">--pygments</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Future</strong></p>
<p class="description">Publishes posts with a future date</p>
</td>
<td class='align-center'>
<p><code class="option">future: [boolean]</code></p>
<p><code class="flag">--future</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>LSI</strong></p>
<p class="description">Produces an index for related posts.</p>
</td>
<td class='align-center'>
<p><code class="option">lsi: [boolean]</code></p>
<p><code class="flag">--lsi</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Permalink</strong></p>
<p class="description">Controls the URLs that posts are generated with. Please refer to the <a href="../permalinks">Permalinks</a> page for more info.</p>
</td>
<td class='align-center'>
<p><code class="option">permalink: [style]</code></p>
<p><code class="flag">--permalink [style]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Pagination</strong></p>
<p class="description">Splits your posts up over multiple subdirectories called "page2", "page3", ... "pageN"</p>
</td>
<td class='align-center'>
<p><code class="option">paginate: [per_page]</code></p>
<p><code class="flag">--paginate [per_page]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Limit Posts</strong></p>
@ -188,10 +168,56 @@ The table below lists the available settings for Jekyll, and the various <code c
</td>
<td class='align-center'>
<p><code class="option">limit_posts: [max_posts]</code></p>
<p><code class="flag">--limit_posts=[max_posts]</code></p>
<p><code class="flag">--limit_posts [max_posts]</code></p>
</td>
</tr>
</tbody>
</table>
### Serve Command Options
In addition to the options below, the `serve` sub-command can accept any of the options
for the `build` sub-command, which are then applied to the site build which occurs right
before your site is served.
<table>
<thead>
<tr>
<th>Setting</th>
<th><span class="option">Options</span> and <span class="flag">Flags</span></th>
</tr>
</thead>
<tbody>
<tr class='setting'>
<td>
<p class='name'><strong>Local Server Port</strong></p>
<p class='description'>Changes the port that the Jekyll server will run on</p>
</td>
<td class="align-center">
<p><code class="option">port: [integer]</code></p>
<p><code class="flag">--port [port]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Local Server Hostname</strong></p>
<p class='description'>Changes the hostname that the Jekyll server will run on</p>
</td>
<td class="align-center">
<p><code class="option">host: [string]</code></p>
<p><code class="flag">--host [hostname]</code></p>
</td>
</tr>
<tr class='setting'>
<td>
<p class='name'><strong>Base URL</strong></p>
<p class='description'>Serve website from a given base URL</p>
</td>
<td class="align-center">
<p><code class="option">baseurl: [BASE_URL]</code></p>
<p><code class="flag">--baseurl [url]</code></p>
</td>
</tr>
</tbody>
</table>
@ -206,9 +232,10 @@ Jekyll runs with the following configuration options by default. Unless alternat
{% highlight yaml %}
safe: false
auto: false
watch: false
server: false
server_port: 4000
host: 0.0.0.0
port: 4000
baseurl: /
url: http://localhost:4000

View File

@ -53,7 +53,7 @@ TMP_GIT_CLONE=$HOME/tmp/myrepo
PUBLIC_WWW=/var/www/myrepo
git clone $GIT_REPO $TMP_GIT_CLONE
jekyll --no-auto $TMP_GIT_CLONE $PUBLIC_WWW
jekyll build $TMP_GIT_CLONE $PUBLIC_WWW
rm -Rf $TMP_GIT_CLONE
exit
{% endhighlight %}

View File

@ -91,7 +91,7 @@ sudo gem install rdiscount
And then run Jekyll with the following option:
{% highlight bash %}
jekyll --rdiscount
jekyll build --markdown rdiscount
{% endhighlight %}
Or, specify RDiscount as the markdown engine in your `_config.yml` file to have Jekyll run with that option by default (so you dont have to specify the flag every time).

View File

@ -19,7 +19,7 @@ For the impatient, here's how to get Jekyll up and running.
~ $ mkdir -p my/new/site
~ $ cd my/new/site
~ $ vim index.html
~/my/new/site $ jekyll --server
~/my/new/site $ jekyll serve
# => Now browse to http://localhost:4000
{% endhighlight %}

View File

@ -0,0 +1,28 @@
---
layout: docs
title: Sites using Jekyll
prev_section: troubleshooting
next_section: resources
---
Its interesting to see what designs and features others have come up
with. Below are some Jekyll-powered blogs which were hand-picked for
learning purposes.
- [Tom Preston-Werner](http://tom.preston-werner.com/)
([source](http://github.com/mojombo/mojombo.github.com))
- [Nick Quaranto](http://quaran.to/)
([source](https://github.com/qrush/qrush.github.com))
- [Roger Chapman](http://rogchap.com/)
([source](https://github.com/rogchap/rogchap.github.com))
- [GitHub Official Teaching Materials](http://teach.github.com)
([source](https://github.com/github/teach.github.com))
- [Rasmus Andersson](http://rsms.me/)
([source](https://github.com/rsms/rsms.github.com))
- [Scott Chacon](http://schacon.github.com)
([source](https://github.com/schacon/schacon.github.com))
If you would like to explore more examples, you can find a list of sites
and their sources on the ["Sites" page in the Jekyll wiki][jekyll-sites].
[jekyll-sites]: https://github.com/mojombo/jekyll/wiki/Sites

View File

@ -88,7 +88,7 @@ An overview of what each of these does:
<p>Other Files/Folders</p>
</td>
<td>
<p>Every other directory and file except for those listed above—such as <code>css</code> and <code>images</code> folders, <code>favicon.ico</code> files, and so forth—will be transferred over verbatim to the generated site. There's plenty of sites already using Jekyll if you're curious as to how they're laid out.</p>
<p>Every other directory and file except for those listed above—such as <code>css</code> and <code>images</code> folders, <code>favicon.ico</code> files, and so forth—will be transferred over verbatim to the generated site. There's plenty of <a href="../sites">sites already using Jekyll</a> if you're curious as to how they're laid out.</p>
</td>
</tr>
</tbody>

View File

@ -50,7 +50,7 @@ On Debian or Ubuntu, you may need to add /var/lib/gems/1.8/bin/ to your path in
## Base-URL Problems
If you are using base-url option like `jekyll --server --base-url '/blog'` then make sure that you access the site at `http://localhost:4000/blog/index.html`. Just accessing `http://localhost:4000/blog` will not work.
If you are using base-url option like `jekyll serve --baseurl '/blog'` then make sure that you access the site at `http://localhost:4000/blog/index.html`. Just accessing `http://localhost:4000/blog` will not work.
## Configuration problems

View File

@ -8,28 +8,31 @@ next_section: structure
The Jekyll gem makes a `jekyll` executable available to you in your Terminal window. You can use this command in a number of ways:
{% highlight bash %}
jekyll
jekyll build
#=> The current folder will get generated into ./_site
jekyll <destination>
jekyll build --destination <destination>
#=> The current folder will get generated into <destination>
jekyll <source> <destination>
jekyll build --source <source> --destination <destination>
#=> The <source> folder will get generated into <destination>
jekyll build --watch
#=> The current folder will get generated into ./_site,
# and watch for changes and regenerate automatically.
{% endhighlight %}
Jekyll also comes with a built-in development server that will allow you to preview what the generated site will look like in your browser locally.
{% highlight bash %}
jekyll --server
jekyll serve
#=> A development server will run at http://localhost:4000/
jekyll --server --auto
jekyll serve --watch
#=> As above, but watch for changes and regenerate automatically too.
{% endhighlight %}
These are just some of the many [configuration options](../configuration) available. All configuration options can either be specified as flags on the command line, or alternatively (and more commonly) they can be specified in a `_config.yml` file at the root of the source directory. Jekyll will automatically configuration options from this file when run, so placing the following two lines in the configuration file will mean that running `jekyll` would be equivalent to running `jekyll --server --auto`:
These are just some of the many [configuration options](../configuration) available. All configuration options can either be specified as flags on the command line, or alternatively (and more commonly) they can be specified in a `_config.yml` file at the root of the source directory. Jekyll will automatically configuration options from this file when run, so placing the following one line in the configuration file will mean that running `jekyll build` or `jekyll serve` would be equivalent to running `jekyll [build|serve] --source _source --destination _deploy`:
{% highlight yaml %}
auto: true
server: true
source: _source
destination: _deploy
{% endhighlight %}
For more about the possible configuration options, see the [configuration](../configuration) page.

View File

@ -68,7 +68,7 @@ Jekyll traverses your site looking for files to process. Any files with [YAML Fr
</tr>
<tr>
<td><p><code>site.[CONFIGURATION_DATA]</code></p></td>
<td><p>All variables set in your <code>_config.yml</code> are available through the <code>site</code> variable. For example, if you have <code>url: http://mysite.com</code> in your configuration file, then in your posts and pages it can be accessed using <code>{{ "{{ site.url " }}}}</code>. Jekyll does not parse changes to <code>_config.yml</code> in <code>auto</code> mode, you have to restart Jekyll to see changes to variables.</p></td>
<td><p>All variables set in your <code>_config.yml</code> are available through the <code>site</code> variable. For example, if you have <code>url: http://mysite.com</code> in your configuration file, then in your posts and pages it can be accessed using <code>{{ "{{ site.url " }}}}</code>. Jekyll does not parse changes to <code>_config.yml</code> in <code>watch</code> mode, you have to restart Jekyll to see changes to variables.</p></td>
</tr>
</tbody>
</table>

View File

@ -16,19 +16,19 @@ overview: true
<p>
No more databases, comment moderation, or pesky updates to install—just <em>your content</em>.
</p>
<a href="https://github.com/mojombo/jekyll/wiki/Usage" class="">How Jekyll works &rarr;</a>
<a href="{% post_url 2012-07-01-usage %}" class="">How Jekyll works &rarr;</a>
</div>
<div class="grid4">
<h2>Static</h2>
<p><a href="http://daringfireball.net/projects/markdown/">Markdown</a> (or <a href="http://textile.sitemonks.com/">Textile</a>), <a href="http://liquidmarkup.org/">Liquid</a>, HTML <span class="amp">&amp;</span> CSS go in. Static sites come out ready for deployment.</p>
<a href="https://github.com/mojombo/jekyll/wiki/Template-Data" class="">Jekyll template guide &rarr;</a>
<a href="{% post_url 2012-07-01-templates %}" class="">Jekyll template guide &rarr;</a>
</div>
<div class="grid4">
<h2>Blog-aware</h2>
<p>
Permalinks, categories, pages, posts, and custom layouts are all first-class citizens here.
</p>
<a href="https://github.com/mojombo/jekyll/wiki/Blog-Migrations" class="">Migrate your blog &rarr;</a>
<a href="{% post_url 2012-07-01-migrations %}" class="">Migrate your blog &rarr;</a>
</div>
<div class="clear"></div>
</div>
@ -54,7 +54,7 @@ overview: true
<p class="line">
<span class="path">~/my/awesome/site</span>
<span class="prompt">$</span>
<span class="command">jekyll --server</span>
<span class="command">jekyll serve</span>
</p>
<p class="line">
<span class="output"># => Now browse to http://localhost:4000</span>

View File

@ -0,0 +1,6 @@
---
layout: nil
title: No layout
---
This post has no layout.

View File

@ -0,0 +1,5 @@
---
title: I have no layout
---
This post will be rendered with the "post" layout.

View File

@ -20,20 +20,24 @@ class TestConvertible < Test::Unit::TestCase
end
should "not parse if there is syntax error in front-matter" do
name = 'broken_front_matter2.erb'
out = capture_stdout do
ret = @convertible.read_yaml(@base, 'broken_front_matter2.erb')
ret = @convertible.read_yaml(@base, name)
assert_equal({}, ret)
end
assert_match(/YAML Exception|syntax error/, out)
assert_match(/#{File.join(@base, name)}/, out)
end
if RUBY_VERSION >= '1.9.2'
should "not parse if there is encoding error in file" do
name = 'broken_front_matter3.erb'
out = capture_stdout do
ret = @convertible.read_yaml(@base, 'broken_front_matter3.erb')
ret = @convertible.read_yaml(@base, name)
assert_equal({}, ret)
end
assert_match(/invalid byte sequence in UTF-8/, out)
assert_match(/#{File.join(@base, name)}/, out)
end
end
end

View File

@ -63,4 +63,26 @@ class TestCoreExt < Test::Unit::TestCase
end
end
context "enumerable" do
context "glob_include?" do
should "return false with no glob patterns" do
assert ![].glob_include?("a.txt")
end
should "return false with all not match path" do
data = ["a*", "b?"]
assert !data.glob_include?("ca.txt")
assert !data.glob_include?("ba.txt")
end
should "return true with match path" do
data = ["a*", "b?", "**/a*"]
assert data.glob_include?("a.txt")
assert data.glob_include?("ba")
assert data.glob_include?("c/a/a.txt")
assert data.glob_include?("c/a/b/a.txt")
end
end
end
end

View File

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

View File

@ -66,6 +66,26 @@ class TestPage < Test::Unit::TestCase
assert_equal "/about/", @page.dir
end
end
context "with unspecified layout" do
setup do
@page = setup_page('contacts.html')
end
should "default to 'post' layout" do
assert_equal "page", @page.data["layout"]
end
end
context "with specified layout of nil" do
setup do
@page = setup_page('sitemap.xml')
end
should "layout of nil is respected" do
assert_equal "nil", @page.data["layout"]
end
end
context "rendering" do
setup do

View File

@ -95,7 +95,7 @@ class TestPost < Test::Unit::TestCase
should "consume the embedded dashes" do
@post.read_yaml(@source, @real_file)
assert_equal({"title" => "Foo --- Bar"}, @post.data)
assert_equal({"title" => "Foo --- Bar", "layout" => "post"}, @post.data)
assert_equal "Triple the fun!", @post.content
end
end
@ -128,6 +128,30 @@ class TestPost < Test::Unit::TestCase
end
end
context "with unspecified layout" do
setup do
file = '2013-01-12-no-layout.textile'
@post = setup_post(file)
@post.process(file)
end
should "default to 'post' layout" do
assert_equal "post", @post.data["layout"]
end
end
context "with specified layout of nil" do
setup do
file = '2013-01-12-nil-layout.textile'
@post = setup_post(file)
@post.process(file)
end
should "layout of nil is respected" do
assert_equal "nil", @post.data["layout"]
end
end
context "with unspecified (date) style and categories" do
setup do
@post.categories << "food"

View File

@ -155,13 +155,13 @@ class TestSite < Test::Unit::TestCase
excludes = %w[README TODO]
files = %w[index.html site.css .htaccess]
@site.exclude = excludes
assert_equal files, @site.filter_entries(excludes + files)
@site.exclude = excludes + ["exclude*"]
assert_equal files, @site.filter_entries(excludes + files + ["excludeA"])
end
should "not filter entries within include" do
includes = %w[_index.html .htaccess]
files = %w[index.html _index.html .htaccess]
includes = %w[_index.html .htaccess include*]
files = %w[index.html _index.html .htaccess includeA]
@site.include = includes
assert_equal files, @site.filter_entries(files)
@ -201,12 +201,22 @@ class TestSite < Test::Unit::TestCase
File.open(dest_dir('qux/obsolete.html'), 'w')
# empty directory
FileUtils.mkdir(dest_dir('quux'))
FileUtils.mkdir(dest_dir('.git'))
FileUtils.mkdir(dest_dir('.svn'))
FileUtils.mkdir(dest_dir('.hg'))
# single file in repository
File.open(dest_dir('.git/HEAD'), 'w')
File.open(dest_dir('.svn/HEAD'), 'w')
File.open(dest_dir('.hg/HEAD'), 'w')
end
teardown do
FileUtils.rm_f(dest_dir('obsolete.html'))
FileUtils.rm_rf(dest_dir('qux'))
FileUtils.rm_f(dest_dir('quux'))
FileUtils.rm_rf(dest_dir('.git'))
FileUtils.rm_rf(dest_dir('.svn'))
FileUtils.rm_rf(dest_dir('.hg'))
end
should 'remove orphaned files in destination' do
@ -214,8 +224,23 @@ class TestSite < Test::Unit::TestCase
assert !File.exist?(dest_dir('obsolete.html'))
assert !File.exist?(dest_dir('qux'))
assert !File.exist?(dest_dir('quux'))
assert File.exist?(dest_dir('.git'))
assert File.exist?(dest_dir('.git/HEAD'))
end
should 'remove orphaned files in destination - keep_files .svn' do
config = Jekyll::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'keep_files' => ['.svn']})
@site = Site.new(config)
@site.process
assert !File.exist?(dest_dir('.htpasswd'))
assert !File.exist?(dest_dir('obsolete.html'))
assert !File.exist?(dest_dir('qux'))
assert !File.exist?(dest_dir('quux'))
assert !File.exist?(dest_dir('.git'))
assert !File.exist?(dest_dir('.git/HEAD'))
assert File.exist?(dest_dir('.svn'))
assert File.exist?(dest_dir('.svn/HEAD'))
end
end
context 'with an invalid markdown processor in the configuration' do

View File

@ -32,6 +32,7 @@ title: This is a test
This document results in a markdown error with maruku
{% highlight text %}#{code}{% endhighlight %}
{% highlight text linenos %}#{code}{% endhighlight %}
CONTENT
create_post(content, override)
end
@ -58,16 +59,16 @@ CONTENT
assert_equal({}, tag.instance_variable_get(:@options))
tag = Jekyll::HighlightBlock.new('highlight', 'ruby linenos ', ["test", "{% endhighlight %}", "\n"])
assert_equal({'O' => "linenos=inline"}, tag.instance_variable_get(:@options))
assert_equal({ 'linenos' => 'inline' }, tag.instance_variable_get(:@options))
tag = Jekyll::HighlightBlock.new('highlight', 'ruby linenos=table ', ["test", "{% endhighlight %}", "\n"])
assert_equal({'O' => "linenos=table"}, tag.instance_variable_get(:@options))
assert_equal({ 'linenos' => 'table' }, tag.instance_variable_get(:@options))
tag = Jekyll::HighlightBlock.new('highlight', 'ruby linenos=table nowrap', ["test", "{% endhighlight %}", "\n"])
assert_equal({'O' => "linenos=table,nowrap=true"}, tag.instance_variable_get(:@options))
assert_equal({ 'linenos' => 'table', 'nowrap' => true }, tag.instance_variable_get(:@options))
tag = Jekyll::HighlightBlock.new('highlight', 'ruby linenos=table cssclass=hl', ["test", "{% endhighlight %}", "\n"])
assert_equal({'O' => "cssclass=hl,linenos=table"}, tag.instance_variable_get(:@options))
assert_equal({ 'cssclass' => 'hl', 'linenos' => 'table' }, tag.instance_variable_get(:@options))
end
end
@ -80,9 +81,13 @@ CONTENT
assert_no_match /markdown\-html\-error/, @result
end
should "render markdown with pygments line handling" do
should "render markdown with pygments" do
assert_match %{<pre><code class='text'>test\n</code></pre>}, @result
end
should "render markdown with pygments with line numbers" do
assert_match %{<pre><code class='text'><span class='lineno'>1</span> test\n</code></pre>}, @result
end
end
context "post content has highlight with file reference" do