monad 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CONTRIBUTING.markdown +91 -0
- data/Gemfile +1 -1
- data/History.markdown +772 -0
- data/{README.md → README.markdown} +5 -2
- data/Rakefile +163 -1
- data/bin/monad +86 -30
- data/features/create_sites.feature +54 -25
- data/features/data.feature +65 -0
- data/features/data_sources.feature +10 -10
- data/features/drafts.feature +5 -5
- data/features/embed_filters.feature +10 -10
- data/features/include_tag.feature +48 -0
- data/features/markdown.feature +5 -5
- data/features/pagination.feature +38 -10
- data/features/permalinks.feature +31 -11
- data/features/post_data.feature +41 -41
- data/features/post_excerpts.feature +50 -0
- data/features/site_configuration.feature +47 -26
- data/features/site_data.feature +30 -24
- data/features/step_definitions/{monad_steps.rb → jekyll_steps.rb} +66 -52
- data/features/support/env.rb +27 -8
- data/lib/jekyll.rb +99 -0
- data/lib/jekyll/cleaner.rb +73 -0
- data/lib/{monad → jekyll}/command.rb +6 -6
- data/lib/{monad → jekyll}/commands/build.rb +9 -9
- data/lib/jekyll/commands/doctor.rb +67 -0
- data/lib/jekyll/commands/new.rb +67 -0
- data/lib/jekyll/commands/serve.rb +65 -0
- data/lib/{monad → jekyll}/configuration.rb +60 -18
- data/lib/{monad → jekyll}/converter.rb +1 -1
- data/lib/{monad → jekyll}/converters/identity.rb +1 -1
- data/lib/{monad → jekyll}/converters/markdown.rb +2 -2
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +29 -0
- data/lib/{monad → jekyll}/converters/markdown/maruku_parser.rb +12 -8
- data/lib/{monad → jekyll}/converters/markdown/rdiscount_parser.rb +4 -2
- data/lib/{monad → jekyll}/converters/markdown/redcarpet_parser.rb +1 -1
- data/lib/{monad → jekyll}/converters/textile.rb +1 -1
- data/lib/{monad → jekyll}/convertible.rb +39 -17
- data/lib/{monad → jekyll}/core_ext.rb +22 -4
- data/lib/jekyll/deprecator.rb +36 -0
- data/lib/{monad → jekyll}/draft.rb +1 -1
- data/lib/{monad → jekyll}/drivers/json_driver.rb +1 -1
- data/lib/{monad → jekyll}/drivers/yaml_driver.rb +1 -1
- data/lib/{monad → jekyll}/errors.rb +1 -1
- data/lib/jekyll/excerpt.rb +113 -0
- data/lib/{monad → jekyll}/filters.rb +16 -6
- data/lib/{monad → jekyll}/generator.rb +1 -1
- data/lib/jekyll/generators/pagination.rb +214 -0
- data/lib/{monad → jekyll}/layout.rb +4 -1
- data/lib/{monad → jekyll}/mime.types +0 -0
- data/lib/{monad → jekyll}/page.rb +36 -39
- data/lib/{monad → jekyll}/plugin.rb +1 -1
- data/lib/{monad → jekyll}/post.rb +58 -123
- data/lib/jekyll/related_posts.rb +59 -0
- data/lib/{monad → jekyll}/site.rb +120 -123
- data/lib/{monad → jekyll}/static_file.rb +1 -1
- data/lib/jekyll/stevenson.rb +89 -0
- data/lib/jekyll/tags/gist.rb +48 -0
- data/lib/{monad → jekyll}/tags/highlight.rb +3 -3
- data/lib/jekyll/tags/include.rb +135 -0
- data/lib/{monad → jekyll}/tags/post_url.rb +8 -6
- data/lib/jekyll/url.rb +67 -0
- data/lib/monad.rb +36 -27
- data/lib/site_template/_config.yml +2 -1
- data/lib/site_template/_layouts/default.html +21 -23
- data/lib/site_template/_layouts/post.html +1 -1
- data/lib/site_template/_posts/{0000-00-00-welcome-to-monad.markdown.erb → 0000-00-00-welcome-to-jekyll.markdown.erb} +6 -6
- data/lib/site_template/css/main.css +22 -27
- data/lib/site_template/index.html +2 -2
- data/monad.gemspec +153 -52
- data/site/.gitignore +4 -0
- data/site/CNAME +1 -0
- data/site/README +1 -0
- data/site/_config.yml +6 -0
- data/site/_includes/analytics.html +32 -0
- data/site/_includes/docs_contents.html +16 -0
- data/site/_includes/docs_contents_mobile.html +23 -0
- data/site/_includes/docs_option.html +11 -0
- data/site/_includes/docs_ul.html +20 -0
- data/site/_includes/footer.html +15 -0
- data/site/_includes/header.html +18 -0
- data/site/_includes/news_contents.html +23 -0
- data/site/_includes/news_contents_mobile.html +11 -0
- data/site/_includes/news_item.html +24 -0
- data/site/_includes/primary-nav-items.html +14 -0
- data/site/_includes/section_nav.html +22 -0
- data/site/_includes/top.html +17 -0
- data/site/_layouts/default.html +12 -0
- data/site/_layouts/docs.html +23 -0
- data/site/_layouts/news.html +19 -0
- data/site/_layouts/news_item.html +27 -0
- data/site/_posts/2013-05-06-jekyll-1-0-0-released.markdown +23 -0
- data/site/_posts/2013-05-08-jekyll-1-0-1-released.markdown +27 -0
- data/site/_posts/2013-05-12-jekyll-1-0-2-released.markdown +28 -0
- data/site/_posts/2013-06-07-jekyll-1-0-3-released.markdown +25 -0
- data/site/_posts/2013-07-14-jekyll-1-1-0-released.markdown +27 -0
- data/site/_posts/2013-07-24-jekyll-1-1-1-released.markdown +31 -0
- data/site/_posts/2013-07-25-jekyll-1-0-4-released.markdown +20 -0
- data/site/_posts/2013-07-25-jekyll-1-1-2-released.markdown +20 -0
- data/site/_posts/2013-09-06-jekyll-1-2-0-released.markdown +23 -0
- data/site/_posts/2013-09-14-jekyll-1-2-1-released.markdown +19 -0
- data/site/css/gridism.css +110 -0
- data/site/css/normalize.css +1 -0
- data/site/css/pygments.css +70 -0
- data/site/css/style.css +946 -0
- data/site/docs/configuration.md +373 -0
- data/site/docs/contributing.md +128 -0
- data/site/docs/datafiles.md +63 -0
- data/site/docs/deployment-methods.md +109 -0
- data/site/docs/drafts.md +20 -0
- data/site/docs/extras.md +56 -0
- data/site/docs/frontmatter.md +180 -0
- data/site/docs/github-pages.md +91 -0
- data/site/docs/heroku.md +9 -0
- data/site/docs/history.md +722 -0
- data/site/docs/index.md +52 -0
- data/site/docs/installation.md +76 -0
- data/site/docs/migrations.md +257 -0
- data/site/docs/pages.md +86 -0
- data/site/docs/pagination.md +211 -0
- data/site/docs/permalinks.md +180 -0
- data/site/docs/plugins.md +508 -0
- data/site/docs/posts.md +181 -0
- data/site/docs/quickstart.md +32 -0
- data/site/docs/resources.md +46 -0
- data/site/docs/sites.md +29 -0
- data/site/docs/structure.md +190 -0
- data/site/docs/templates.md +319 -0
- data/site/docs/troubleshooting.md +150 -0
- data/site/docs/upgrading.md +146 -0
- data/site/docs/usage.md +63 -0
- data/site/docs/variables.md +322 -0
- data/site/favicon.png +0 -0
- data/site/feed.xml +36 -0
- data/site/freenode.txt +1 -0
- data/site/img/article-footer.png +0 -0
- data/site/img/footer-arrow.png +0 -0
- data/site/img/footer-logo.png +0 -0
- data/site/img/logo-2x.png +0 -0
- data/site/img/octojekyll.png +0 -0
- data/site/img/tube.png +0 -0
- data/site/img/tube1x.png +0 -0
- data/site/index.html +90 -0
- data/site/js/modernizr-2.5.3.min.js +4 -0
- data/site/news/index.html +10 -0
- data/site/news/releases/index.html +10 -0
- data/test/helper.rb +6 -3
- data/test/source/+/foo.md +7 -0
- data/test/source/_data/languages.yml +2 -0
- data/test/source/_data/members.yaml +7 -0
- data/test/source/_data/products.yml +4 -0
- data/test/source/_includes/params.html +7 -0
- data/test/source/_layouts/default.html +1 -1
- data/test/source/_layouts/post/simple.html +1 -0
- data/test/source/_plugins/dummy.rb +1 -1
- data/test/source/_posts/2013-01-02-post-excerpt.markdown +1 -1
- data/test/source/_posts/2013-07-22-post-excerpt-with-layout.markdown +23 -0
- data/test/source/_posts/2013-08-01-mkdn-extension.mkdn +0 -0
- data/test/source/deal.with.dots.html +1 -1
- data/test/source/products.yml +4 -0
- data/test/test_configuration.rb +46 -11
- data/test/test_convertible.rb +2 -2
- data/test/test_excerpt.rb +78 -0
- data/test/test_filters.rb +4 -4
- data/test/test_generated_site.rb +13 -13
- data/test/test_json_driver.rb +9 -9
- data/test/test_kramdown.rb +32 -5
- data/test/test_new_command.rb +8 -8
- data/test/test_page.rb +12 -3
- data/test/test_pager.rb +34 -33
- data/test/test_post.rb +34 -26
- data/test/test_redcloth.rb +3 -3
- data/test/test_related_posts.rb +47 -0
- data/test/test_site.rb +102 -44
- data/test/test_tags.rb +168 -23
- data/test/test_url.rb +28 -0
- data/test/test_yaml_driver.rb +6 -6
- metadata +215 -137
- data/lib/monad/commands/doctor.rb +0 -29
- data/lib/monad/commands/new.rb +0 -50
- data/lib/monad/commands/serve.rb +0 -33
- data/lib/monad/converters/markdown/kramdown_parser.rb +0 -44
- data/lib/monad/deprecator.rb +0 -32
- data/lib/monad/generators/pagination.rb +0 -143
- data/lib/monad/logger.rb +0 -54
- data/lib/monad/tags/gist.rb +0 -30
- data/lib/monad/tags/include.rb +0 -37
data/features/support/env.rb
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
if RUBY_VERSION > '1.9'
|
|
2
|
+
require 'coveralls'
|
|
3
|
+
Coveralls.wear_merged!
|
|
4
|
+
end
|
|
5
|
+
|
|
1
6
|
require 'fileutils'
|
|
2
7
|
require 'rr'
|
|
3
8
|
require 'test/unit'
|
|
9
|
+
require 'time'
|
|
4
10
|
|
|
5
|
-
|
|
6
|
-
include Test::Unit::Assertions
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
TEST_DIR = File.join('/', 'tmp', 'monad')
|
|
11
|
+
TEST_DIR = File.join('/', 'tmp', 'jekyll')
|
|
10
12
|
JEKYLL_PATH = File.join(File.dirname(__FILE__), '..', '..', 'bin', 'monad')
|
|
11
13
|
|
|
12
|
-
def
|
|
14
|
+
def run_jekyll(opts = {})
|
|
13
15
|
command = JEKYLL_PATH.clone
|
|
14
16
|
command << " build"
|
|
15
17
|
command << " --drafts" if opts[:drafts]
|
|
@@ -17,8 +19,25 @@ def run_monad(opts = {})
|
|
|
17
19
|
system command
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
+
def call_jekyll_new(opts = {})
|
|
23
|
+
command = JEKYLL_PATH.clone
|
|
24
|
+
command << " new"
|
|
25
|
+
command << " #{opts[:path]}" if opts[:path]
|
|
26
|
+
command << " --blank" if opts[:blank]
|
|
27
|
+
command << " >> /dev/null 2>&1" if opts[:debug].nil?
|
|
28
|
+
system command
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def slug(title)
|
|
32
|
+
title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def location(folder, direction)
|
|
36
|
+
if folder
|
|
37
|
+
before = folder if direction == "in"
|
|
38
|
+
after = folder if direction == "under"
|
|
39
|
+
end
|
|
40
|
+
[before || '.', after || '.']
|
|
22
41
|
end
|
|
23
42
|
|
|
24
43
|
# work around "invalid option: --format" cucumber bug (see #296)
|
data/lib/jekyll.rb
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
|
2
|
+
|
|
3
|
+
# Require all of the Ruby files in the given directory.
|
|
4
|
+
#
|
|
5
|
+
# path - The String relative path from here to the directory.
|
|
6
|
+
#
|
|
7
|
+
# Returns nothing.
|
|
8
|
+
def require_all(path)
|
|
9
|
+
glob = File.join(File.dirname(__FILE__), path, '*.rb')
|
|
10
|
+
Dir[glob].each do |f|
|
|
11
|
+
require f
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# rubygems
|
|
16
|
+
require 'rubygems'
|
|
17
|
+
|
|
18
|
+
# stdlib
|
|
19
|
+
require 'fileutils'
|
|
20
|
+
require 'time'
|
|
21
|
+
require 'safe_yaml'
|
|
22
|
+
require 'English'
|
|
23
|
+
require 'pathname'
|
|
24
|
+
|
|
25
|
+
# 3rd party
|
|
26
|
+
require 'liquid'
|
|
27
|
+
require 'maruku'
|
|
28
|
+
require 'colorator'
|
|
29
|
+
|
|
30
|
+
# internal requires
|
|
31
|
+
require 'jekyll/core_ext'
|
|
32
|
+
require 'jekyll/stevenson'
|
|
33
|
+
require 'jekyll/deprecator'
|
|
34
|
+
require 'jekyll/configuration'
|
|
35
|
+
require 'jekyll/site'
|
|
36
|
+
require 'jekyll/convertible'
|
|
37
|
+
require 'jekyll/url'
|
|
38
|
+
require 'jekyll/layout'
|
|
39
|
+
require 'jekyll/page'
|
|
40
|
+
require 'jekyll/post'
|
|
41
|
+
require 'jekyll/excerpt'
|
|
42
|
+
require 'jekyll/draft'
|
|
43
|
+
require 'jekyll/filters'
|
|
44
|
+
require 'jekyll/static_file'
|
|
45
|
+
require 'jekyll/errors'
|
|
46
|
+
require 'jekyll/related_posts'
|
|
47
|
+
require 'jekyll/cleaner'
|
|
48
|
+
|
|
49
|
+
# extensions
|
|
50
|
+
require 'jekyll/plugin'
|
|
51
|
+
require 'jekyll/converter'
|
|
52
|
+
require 'jekyll/generator'
|
|
53
|
+
require 'jekyll/command'
|
|
54
|
+
|
|
55
|
+
require_all 'jekyll/commands'
|
|
56
|
+
require_all 'jekyll/converters'
|
|
57
|
+
require_all 'jekyll/converters/markdown'
|
|
58
|
+
require_all 'jekyll/generators'
|
|
59
|
+
require_all 'jekyll/tags'
|
|
60
|
+
require_all 'jekyll/drivers'
|
|
61
|
+
|
|
62
|
+
SafeYAML::OPTIONS[:suppress_warnings] = true
|
|
63
|
+
|
|
64
|
+
module Jekyll
|
|
65
|
+
VERSION = '1.2.1'
|
|
66
|
+
|
|
67
|
+
# Public: Generate a Jekyll configuration Hash by merging the default
|
|
68
|
+
# options with anything in _config.yml, and adding the given options on top.
|
|
69
|
+
#
|
|
70
|
+
# override - A Hash of config directives that override any options in both
|
|
71
|
+
# the defaults and the config file. See Jekyll::Configuration::DEFAULTS for a
|
|
72
|
+
# list of option names and their defaults.
|
|
73
|
+
#
|
|
74
|
+
# Returns the final configuration Hash.
|
|
75
|
+
def self.configuration(override)
|
|
76
|
+
config = Configuration[Configuration::DEFAULTS]
|
|
77
|
+
override = Configuration[override].stringify_keys
|
|
78
|
+
config = config.read_config_files(config.config_files(override))
|
|
79
|
+
|
|
80
|
+
# Merge DEFAULTS < _config.yml < override
|
|
81
|
+
config = config.deep_merge(override).stringify_keys
|
|
82
|
+
set_timezone(config['timezone']) if config['timezone']
|
|
83
|
+
|
|
84
|
+
config
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Static: Set the TZ environment variable to use the timezone specified
|
|
88
|
+
#
|
|
89
|
+
# timezone - the IANA Time Zone
|
|
90
|
+
#
|
|
91
|
+
# Returns nothing
|
|
92
|
+
def self.set_timezone(timezone)
|
|
93
|
+
ENV['TZ'] = timezone
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.logger
|
|
97
|
+
@logger ||= Stevenson.new
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class Site
|
|
5
|
+
# Handles the cleanup of a site's destination before it is built.
|
|
6
|
+
class Cleaner
|
|
7
|
+
def initialize(site)
|
|
8
|
+
@site = site
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Cleans up the site's destination directory
|
|
12
|
+
def cleanup!
|
|
13
|
+
FileUtils.rm_rf(obsolete_files)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
# Private: The list of files and directories to be deleted during cleanup process
|
|
19
|
+
#
|
|
20
|
+
# Returns an Array of the file and directory paths
|
|
21
|
+
def obsolete_files
|
|
22
|
+
(existing_files - new_files - new_dirs + replaced_files).to_a
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Private: The list of existing files, apart from those included in keep_files and hidden files.
|
|
26
|
+
#
|
|
27
|
+
# Returns a Set with the file paths
|
|
28
|
+
def existing_files
|
|
29
|
+
files = Set.new
|
|
30
|
+
Dir.glob(File.join(@site.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
|
|
31
|
+
files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
|
|
32
|
+
end
|
|
33
|
+
files
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Private: The list of files to be created when site is built.
|
|
37
|
+
#
|
|
38
|
+
# Returns a Set with the file paths
|
|
39
|
+
def new_files
|
|
40
|
+
files = Set.new
|
|
41
|
+
@site.each_site_file { |item| files << item.destination(@site.dest) }
|
|
42
|
+
files
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Private: The list of directories to be created when site is built.
|
|
46
|
+
# These are the parent directories of the files in #new_files.
|
|
47
|
+
#
|
|
48
|
+
# Returns a Set with the directory paths
|
|
49
|
+
def new_dirs
|
|
50
|
+
new_files.map { |file| File.dirname(file) }.to_set
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Private: The list of existing files that will be replaced by a directory during build
|
|
54
|
+
#
|
|
55
|
+
# Returns a Set with the file paths
|
|
56
|
+
def replaced_files
|
|
57
|
+
new_dirs.select { |dir| File.file?(dir) }.to_set
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Private: Creates a regular expression from the config's keep_files array
|
|
61
|
+
#
|
|
62
|
+
# Examples
|
|
63
|
+
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
|
64
|
+
#
|
|
65
|
+
# Returns the regular expression
|
|
66
|
+
def keep_file_regex
|
|
67
|
+
or_list = @site.keep_files.join("|")
|
|
68
|
+
pattern = "\/(#{or_list.gsub(".", "\.")})"
|
|
69
|
+
Regexp.new pattern
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module
|
|
1
|
+
module Jekyll
|
|
2
2
|
class Command
|
|
3
3
|
def self.globs(source, destination)
|
|
4
4
|
Dir.chdir(source) do
|
|
@@ -11,16 +11,16 @@ module Monad
|
|
|
11
11
|
|
|
12
12
|
# Static: Run Site#process and catch errors
|
|
13
13
|
#
|
|
14
|
-
# site - the
|
|
14
|
+
# site - the Jekyll::Site object
|
|
15
15
|
#
|
|
16
16
|
# Returns nothing
|
|
17
17
|
def self.process_site(site)
|
|
18
18
|
site.process
|
|
19
|
-
rescue
|
|
19
|
+
rescue Jekyll::FatalException => e
|
|
20
20
|
puts
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
Jekyll.logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:"
|
|
22
|
+
Jekyll.logger.error "", "------------------------------------"
|
|
23
|
+
Jekyll.logger.error "", e.message
|
|
24
24
|
exit(1)
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
module
|
|
1
|
+
module Jekyll
|
|
2
2
|
module Commands
|
|
3
3
|
class Build < Command
|
|
4
4
|
def self.process(options)
|
|
5
|
-
site =
|
|
5
|
+
site = Jekyll::Site.new(options)
|
|
6
6
|
|
|
7
7
|
self.build(site, options)
|
|
8
8
|
self.watch(site, options) if options['watch']
|
|
@@ -10,23 +10,23 @@ module Monad
|
|
|
10
10
|
|
|
11
11
|
# Private: Build the site from source into destination.
|
|
12
12
|
#
|
|
13
|
-
# site - A
|
|
13
|
+
# site - A Jekyll::Site instance
|
|
14
14
|
# options - A Hash of options passed to the command
|
|
15
15
|
#
|
|
16
16
|
# Returns nothing.
|
|
17
17
|
def self.build(site, options)
|
|
18
18
|
source = options['source']
|
|
19
19
|
destination = options['destination']
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
print
|
|
20
|
+
Jekyll.logger.info "Source:", source
|
|
21
|
+
Jekyll.logger.info "Destination:", destination
|
|
22
|
+
print Jekyll.logger.formatted_topic "Generating..."
|
|
23
23
|
self.process_site(site)
|
|
24
24
|
puts "done."
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
# Private: Watch for file changes and rebuild the site.
|
|
28
28
|
#
|
|
29
|
-
# site - A
|
|
29
|
+
# site - A Jekyll::Site instance
|
|
30
30
|
# options - A Hash of options passed to the command
|
|
31
31
|
#
|
|
32
32
|
# Returns nothing.
|
|
@@ -36,14 +36,14 @@ module Monad
|
|
|
36
36
|
source = options['source']
|
|
37
37
|
destination = options['destination']
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Jekyll.logger.info "Auto-regeneration:", "enabled"
|
|
40
40
|
|
|
41
41
|
dw = DirectoryWatcher.new(source, :glob => self.globs(source, destination), :pre_load => true)
|
|
42
42
|
dw.interval = 1
|
|
43
43
|
|
|
44
44
|
dw.add_observer do |*args|
|
|
45
45
|
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
|
46
|
-
print
|
|
46
|
+
print Jekyll.logger.formatted_topic("Regenerating:") + "#{args.size} files at #{t} "
|
|
47
47
|
self.process_site(site)
|
|
48
48
|
puts "...done."
|
|
49
49
|
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Jekyll
|
|
2
|
+
module Commands
|
|
3
|
+
class Doctor < Command
|
|
4
|
+
class << self
|
|
5
|
+
def process(options)
|
|
6
|
+
site = Jekyll::Site.new(options)
|
|
7
|
+
site.read
|
|
8
|
+
|
|
9
|
+
if healthy?(site)
|
|
10
|
+
Jekyll.logger.info "Your test results", "are in. Everything looks fine."
|
|
11
|
+
else
|
|
12
|
+
abort
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def healthy?(site)
|
|
17
|
+
[
|
|
18
|
+
!deprecated_relative_permalinks(site),
|
|
19
|
+
!conflicting_urls(site)
|
|
20
|
+
].all?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def deprecated_relative_permalinks(site)
|
|
24
|
+
contains_deprecated_pages = false
|
|
25
|
+
site.pages.each do |page|
|
|
26
|
+
if page.uses_relative_permalinks
|
|
27
|
+
Jekyll.logger.warn "Deprecation:", "'#{page.path}' uses relative" +
|
|
28
|
+
" permalinks which will be deprecated in" +
|
|
29
|
+
" Jekyll v1.2 and beyond."
|
|
30
|
+
contains_deprecated_pages = true
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
contains_deprecated_pages
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def conflicting_urls(site)
|
|
37
|
+
conflicting_urls = false
|
|
38
|
+
urls = {}
|
|
39
|
+
urls = collect_urls(urls, site.pages, site.dest)
|
|
40
|
+
urls = collect_urls(urls, site.posts, site.dest)
|
|
41
|
+
urls.each do |url, paths|
|
|
42
|
+
if paths.size > 1
|
|
43
|
+
conflicting_urls = true
|
|
44
|
+
Jekyll.logger.warn "Conflict:", "The URL '#{url}' is the destination" +
|
|
45
|
+
" for the following pages: #{paths.join(", ")}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
conflicting_urls
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def collect_urls(urls, things, destination)
|
|
54
|
+
things.each do |thing|
|
|
55
|
+
dest = thing.destination(destination)
|
|
56
|
+
if urls[dest]
|
|
57
|
+
urls[dest] << thing.path
|
|
58
|
+
else
|
|
59
|
+
urls[dest] = [thing.path]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
urls
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module Commands
|
|
5
|
+
class New < Command
|
|
6
|
+
def self.process(args, options = {})
|
|
7
|
+
raise ArgumentError.new('You must specify a path.') if args.empty?
|
|
8
|
+
|
|
9
|
+
new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
|
|
10
|
+
FileUtils.mkdir_p new_blog_path
|
|
11
|
+
if preserve_source_location?(new_blog_path, options)
|
|
12
|
+
Jekyll.logger.error "Conflict:", "#{new_blog_path} exists and is not empty."
|
|
13
|
+
exit(1)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
if options[:blank]
|
|
17
|
+
create_blank_site new_blog_path
|
|
18
|
+
else
|
|
19
|
+
create_sample_files new_blog_path
|
|
20
|
+
|
|
21
|
+
File.open(File.expand_path(self.initialized_post_name, new_blog_path), "w") do |f|
|
|
22
|
+
f.write(self.scaffold_post_content)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
puts "New jekyll site installed in #{new_blog_path}."
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.create_blank_site(path)
|
|
30
|
+
Dir.chdir(path) do
|
|
31
|
+
FileUtils.mkdir(%w(_layouts _posts _drafts))
|
|
32
|
+
FileUtils.touch("index.html")
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.scaffold_post_content
|
|
37
|
+
ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Internal: Gets the filename of the sample post to be created
|
|
41
|
+
#
|
|
42
|
+
# Returns the filename of the sample post, as a String
|
|
43
|
+
def self.initialized_post_name
|
|
44
|
+
"_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def self.preserve_source_location?(path, options)
|
|
50
|
+
!options[:force] && !Dir["#{path}/**/*"].empty?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.create_sample_files(path)
|
|
54
|
+
FileUtils.cp_r site_template + '/.', path
|
|
55
|
+
FileUtils.rm File.expand_path(scaffold_path, path)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.site_template
|
|
59
|
+
File.expand_path("../../site_template", File.dirname(__FILE__))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.scaffold_path
|
|
63
|
+
"_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
module Jekyll
|
|
3
|
+
module Commands
|
|
4
|
+
class Serve < Command
|
|
5
|
+
def self.process(options)
|
|
6
|
+
require 'webrick'
|
|
7
|
+
include WEBrick
|
|
8
|
+
|
|
9
|
+
destination = options['destination']
|
|
10
|
+
|
|
11
|
+
FileUtils.mkdir_p(destination)
|
|
12
|
+
|
|
13
|
+
# recreate NondisclosureName under utf-8 circumstance
|
|
14
|
+
fh_option = WEBrick::Config::FileHandler
|
|
15
|
+
fh_option[:NondisclosureName] = ['.ht*','~*']
|
|
16
|
+
|
|
17
|
+
s = HTTPServer.new(webrick_options(options))
|
|
18
|
+
|
|
19
|
+
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
|
|
20
|
+
|
|
21
|
+
Jekyll.logger.info "Server address:", "http://#{s.config[:BindAddress]}:#{s.config[:Port]}"
|
|
22
|
+
|
|
23
|
+
if options['detach'] # detach the server
|
|
24
|
+
pid = Process.fork { s.start }
|
|
25
|
+
Process.detach(pid)
|
|
26
|
+
Jekyll.logger.info "Server detatched with pid '#{pid}'.", "Run `kill -9 #{pid}' to stop the server."
|
|
27
|
+
else # create a new server thread, then join it with current terminal
|
|
28
|
+
t = Thread.new { s.start }
|
|
29
|
+
trap("INT") { s.shutdown }
|
|
30
|
+
t.join()
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.webrick_options(config)
|
|
35
|
+
opts = {
|
|
36
|
+
:Port => config['port'],
|
|
37
|
+
:BindAddress => config['host'],
|
|
38
|
+
:MimeTypes => self.mime_types,
|
|
39
|
+
:DoNotReverseLookup => true,
|
|
40
|
+
:StartCallback => start_callback(config['detach'])
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if !config['verbose']
|
|
44
|
+
opts.merge!({
|
|
45
|
+
:AccessLog => [],
|
|
46
|
+
:Logger => Log::new([], Log::WARN)
|
|
47
|
+
})
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
opts
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.start_callback(detached)
|
|
54
|
+
unless detached
|
|
55
|
+
Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.mime_types
|
|
60
|
+
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
|
61
|
+
WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|