jekyll 3.9.3 → 4.4.1
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 +4 -4
- data/.rubocop.yml +511 -89
- data/LICENSE +1 -1
- data/README.markdown +48 -27
- data/lib/blank_template/_config.yml +3 -0
- data/lib/blank_template/_layouts/default.html +12 -0
- data/lib/blank_template/_sass/base.scss +9 -0
- data/lib/blank_template/assets/css/main.scss +4 -0
- data/lib/blank_template/index.md +8 -0
- data/lib/jekyll/cache.rb +186 -0
- data/lib/jekyll/cleaner.rb +8 -7
- data/lib/jekyll/collection.rb +84 -11
- data/lib/jekyll/command.rb +33 -6
- data/lib/jekyll/commands/build.rb +8 -28
- data/lib/jekyll/commands/clean.rb +3 -2
- data/lib/jekyll/commands/doctor.rb +46 -35
- data/lib/jekyll/commands/help.rb +1 -1
- data/lib/jekyll/commands/new.rb +44 -50
- data/lib/jekyll/commands/new_theme.rb +27 -28
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +9 -16
- data/lib/jekyll/commands/serve/servlet.rb +21 -22
- data/lib/jekyll/commands/serve/websockets.rb +1 -1
- data/lib/jekyll/commands/serve.rb +75 -97
- data/lib/jekyll/configuration.rb +66 -158
- data/lib/jekyll/converters/identity.rb +18 -0
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +83 -33
- data/lib/jekyll/converters/markdown.rb +49 -40
- data/lib/jekyll/converters/smartypants.rb +34 -14
- data/lib/jekyll/convertible.rb +36 -34
- data/lib/jekyll/deprecator.rb +2 -4
- data/lib/jekyll/document.rb +107 -72
- data/lib/jekyll/drops/collection_drop.rb +3 -4
- data/lib/jekyll/drops/document_drop.rb +9 -3
- data/lib/jekyll/drops/drop.rb +115 -33
- data/lib/jekyll/drops/excerpt_drop.rb +8 -0
- data/lib/jekyll/drops/site_drop.rb +9 -8
- data/lib/jekyll/drops/static_file_drop.rb +4 -4
- data/lib/jekyll/drops/theme_drop.rb +39 -0
- data/lib/jekyll/drops/unified_payload_drop.rb +7 -2
- data/lib/jekyll/drops/url_drop.rb +55 -3
- data/lib/jekyll/entry_filter.rb +42 -51
- data/lib/jekyll/excerpt.rb +48 -38
- data/lib/jekyll/external.rb +20 -19
- data/lib/jekyll/filters/date_filters.rb +6 -3
- data/lib/jekyll/filters/grouping_filters.rb +1 -2
- data/lib/jekyll/filters/url_filters.rb +50 -15
- data/lib/jekyll/filters.rb +211 -50
- data/lib/jekyll/frontmatter_defaults.rb +45 -36
- data/lib/jekyll/hooks.rb +26 -26
- data/lib/jekyll/inclusion.rb +32 -0
- data/lib/jekyll/layout.rb +12 -19
- data/lib/jekyll/liquid_extensions.rb +0 -2
- data/lib/jekyll/liquid_renderer/file.rb +24 -3
- data/lib/jekyll/liquid_renderer/table.rb +26 -77
- data/lib/jekyll/liquid_renderer.rb +31 -16
- data/lib/jekyll/log_adapter.rb +5 -1
- data/lib/jekyll/page.rb +51 -23
- data/lib/jekyll/page_excerpt.rb +25 -0
- data/lib/jekyll/page_without_a_file.rb +0 -4
- data/lib/jekyll/path_manager.rb +74 -0
- data/lib/jekyll/plugin.rb +5 -11
- data/lib/jekyll/plugin_manager.rb +15 -5
- data/lib/jekyll/profiler.rb +51 -0
- data/lib/jekyll/reader.rb +65 -10
- data/lib/jekyll/readers/collection_reader.rb +1 -0
- data/lib/jekyll/readers/data_reader.rb +48 -10
- data/lib/jekyll/readers/layout_reader.rb +3 -12
- data/lib/jekyll/readers/page_reader.rb +5 -5
- data/lib/jekyll/readers/post_reader.rb +32 -19
- data/lib/jekyll/readers/static_file_reader.rb +4 -4
- data/lib/jekyll/readers/theme_assets_reader.rb +8 -5
- data/lib/jekyll/regenerator.rb +4 -12
- data/lib/jekyll/related_posts.rb +1 -1
- data/lib/jekyll/renderer.rb +34 -49
- data/lib/jekyll/site.rb +151 -58
- data/lib/jekyll/static_file.rb +64 -28
- data/lib/jekyll/stevenson.rb +4 -8
- data/lib/jekyll/tags/highlight.rb +44 -57
- data/lib/jekyll/tags/include.rb +114 -80
- data/lib/jekyll/tags/link.rb +12 -7
- data/lib/jekyll/tags/post_url.rb +33 -30
- data/lib/jekyll/theme.rb +20 -18
- data/lib/jekyll/theme_builder.rb +91 -89
- data/lib/jekyll/url.rb +18 -10
- data/lib/jekyll/utils/ansi.rb +2 -2
- data/lib/jekyll/utils/exec.rb +0 -1
- data/lib/jekyll/utils/internet.rb +2 -4
- data/lib/jekyll/utils/platforms.rb +37 -52
- data/lib/jekyll/utils/thread_event.rb +1 -5
- data/lib/jekyll/utils.rb +29 -28
- data/lib/jekyll/version.rb +1 -1
- data/lib/jekyll.rb +9 -14
- data/lib/site_template/.gitignore +2 -0
- data/lib/site_template/404.html +2 -1
- data/lib/site_template/_config.yml +17 -5
- data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
- data/lib/theme_template/README.md.erb +1 -3
- data/lib/theme_template/gitignore.erb +1 -0
- data/lib/theme_template/theme.gemspec.erb +1 -4
- data/rubocop/jekyll/assert_equal_literal_actual.rb +150 -0
- data/rubocop/jekyll/no_p_allowed.rb +5 -6
- data/rubocop/jekyll/no_puts_allowed.rb +5 -6
- metadata +149 -37
- data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
- data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
- data/lib/jekyll/utils/rouge.rb +0 -22
- /data/lib/site_template/{about.md → about.markdown} +0 -0
- /data/lib/site_template/{index.md → index.markdown} +0 -0
|
@@ -15,7 +15,7 @@ module Jekyll
|
|
|
15
15
|
|
|
16
16
|
c.action do |_, options|
|
|
17
17
|
options["serving"] = false
|
|
18
|
-
|
|
18
|
+
process_with_graceful_fail(c, options, self)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -30,15 +30,15 @@ module Jekyll
|
|
|
30
30
|
site = Jekyll::Site.new(options)
|
|
31
31
|
|
|
32
32
|
if options.fetch("skip_initial_build", false)
|
|
33
|
-
Jekyll.logger.warn "Build Warning:",
|
|
34
|
-
|
|
33
|
+
Jekyll.logger.warn "Build Warning:",
|
|
34
|
+
"Skipping the initial build. This may result in an out-of-date site."
|
|
35
35
|
else
|
|
36
36
|
build(site, options)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
if options.fetch("detach", false)
|
|
40
40
|
Jekyll.logger.info "Auto-regeneration:",
|
|
41
|
-
|
|
41
|
+
"disabled when running server detached."
|
|
42
42
|
elsif options.fetch("watch", false)
|
|
43
43
|
watch(site, options)
|
|
44
44
|
else
|
|
@@ -54,13 +54,13 @@ module Jekyll
|
|
|
54
54
|
# Returns nothing.
|
|
55
55
|
def build(site, options)
|
|
56
56
|
t = Time.now
|
|
57
|
-
source = options["source"]
|
|
58
|
-
destination = options["destination"]
|
|
57
|
+
source = File.expand_path(options["source"])
|
|
58
|
+
destination = File.expand_path(options["destination"])
|
|
59
59
|
incremental = options["incremental"]
|
|
60
60
|
Jekyll.logger.info "Source:", source
|
|
61
61
|
Jekyll.logger.info "Destination:", destination
|
|
62
62
|
Jekyll.logger.info "Incremental build:",
|
|
63
|
-
|
|
63
|
+
(incremental ? "enabled" : "disabled. Enable with --incremental")
|
|
64
64
|
Jekyll.logger.info "Generating..."
|
|
65
65
|
process_site(site)
|
|
66
66
|
Jekyll.logger.info "", "done in #{(Time.now - t).round(3)} seconds."
|
|
@@ -73,28 +73,8 @@ module Jekyll
|
|
|
73
73
|
#
|
|
74
74
|
# Returns nothing.
|
|
75
75
|
def watch(site, options)
|
|
76
|
-
# Warn Windows users that they might need to upgrade.
|
|
77
|
-
if Utils::Platforms.bash_on_windows?
|
|
78
|
-
Jekyll.logger.warn "",
|
|
79
|
-
"Auto-regeneration may not work on some Windows versions."
|
|
80
|
-
Jekyll.logger.warn "",
|
|
81
|
-
"Please see: https://github.com/Microsoft/BashOnWindows/issues/216"
|
|
82
|
-
Jekyll.logger.warn "",
|
|
83
|
-
"If it does not work, please upgrade Bash on Windows or "\
|
|
84
|
-
"run Jekyll with --no-watch."
|
|
85
|
-
end
|
|
86
|
-
|
|
87
76
|
External.require_with_graceful_fail "jekyll-watch"
|
|
88
|
-
|
|
89
|
-
if watch_method.parameters.size == 1
|
|
90
|
-
watch_method.call(
|
|
91
|
-
options
|
|
92
|
-
)
|
|
93
|
-
else
|
|
94
|
-
watch_method.call(
|
|
95
|
-
options, site
|
|
96
|
-
)
|
|
97
|
-
end
|
|
77
|
+
Jekyll::Watcher.watch(options, site)
|
|
98
78
|
end
|
|
99
79
|
end
|
|
100
80
|
end
|
|
@@ -7,8 +7,7 @@ module Jekyll
|
|
|
7
7
|
def init_with_program(prog)
|
|
8
8
|
prog.command(:clean) do |c|
|
|
9
9
|
c.syntax "clean [subcommand]"
|
|
10
|
-
c.description "Clean the site "
|
|
11
|
-
"(removes site output and metadata file) without building."
|
|
10
|
+
c.description "Clean the site (removes site output and metadata file) without building."
|
|
12
11
|
|
|
13
12
|
add_build_options(c)
|
|
14
13
|
|
|
@@ -22,10 +21,12 @@ module Jekyll
|
|
|
22
21
|
options = configuration_from_options(options)
|
|
23
22
|
destination = options["destination"]
|
|
24
23
|
metadata_file = File.join(options["source"], ".jekyll-metadata")
|
|
24
|
+
cache_dir = File.join(options["source"], options["cache_dir"])
|
|
25
25
|
sass_cache = ".sass-cache"
|
|
26
26
|
|
|
27
27
|
remove(destination, :checker_func => :directory?)
|
|
28
28
|
remove(metadata_file, :checker_func => :file?)
|
|
29
|
+
remove(cache_dir, :checker_func => :directory?)
|
|
29
30
|
remove(sass_cache, :checker_func => :directory?)
|
|
30
31
|
end
|
|
31
32
|
|
|
@@ -11,7 +11,7 @@ module Jekyll
|
|
|
11
11
|
c.alias(:hyde)
|
|
12
12
|
|
|
13
13
|
c.option "config", "--config CONFIG_FILE[,CONFIG_FILE2,...]", Array,
|
|
14
|
-
|
|
14
|
+
"Custom configuration file"
|
|
15
15
|
|
|
16
16
|
c.action do |_, options|
|
|
17
17
|
Jekyll::Commands::Doctor.process(options)
|
|
@@ -45,46 +45,50 @@ module Jekyll
|
|
|
45
45
|
|
|
46
46
|
def properly_gathered_posts?(site)
|
|
47
47
|
return true if site.config["collections_dir"].empty?
|
|
48
|
+
|
|
48
49
|
posts_at_root = site.in_source_dir("_posts")
|
|
49
50
|
return true unless File.directory?(posts_at_root)
|
|
51
|
+
|
|
50
52
|
Jekyll.logger.warn "Warning:",
|
|
51
|
-
|
|
53
|
+
"Detected '_posts' directory outside custom `collections_dir`!"
|
|
52
54
|
Jekyll.logger.warn "",
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
"Please move '#{posts_at_root}' into the custom directory at " \
|
|
56
|
+
"'#{site.in_source_dir(site.config["collections_dir"])}'"
|
|
55
57
|
false
|
|
56
58
|
end
|
|
57
59
|
|
|
58
60
|
def deprecated_relative_permalinks(site)
|
|
59
61
|
if site.config["relative_permalinks"]
|
|
60
|
-
Jekyll::Deprecator.deprecation_message "Your site still uses relative" \
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return true
|
|
62
|
+
Jekyll::Deprecator.deprecation_message "Your site still uses relative permalinks, " \
|
|
63
|
+
"which was removed in Jekyll v3.0.0."
|
|
64
|
+
true
|
|
64
65
|
end
|
|
65
66
|
end
|
|
66
67
|
|
|
67
68
|
def conflicting_urls(site)
|
|
68
69
|
conflicting_urls = false
|
|
69
|
-
|
|
70
|
-
urls = collect_urls(urls, site.pages, site.dest)
|
|
71
|
-
urls = collect_urls(urls, site.posts.docs, site.dest)
|
|
72
|
-
urls.each do |url, paths|
|
|
70
|
+
destination_map(site).each do |dest, paths|
|
|
73
71
|
next unless paths.size > 1
|
|
72
|
+
|
|
74
73
|
conflicting_urls = true
|
|
75
|
-
Jekyll.logger.warn "Conflict:",
|
|
76
|
-
|
|
74
|
+
Jekyll.logger.warn "Conflict:",
|
|
75
|
+
"The following destination is shared by multiple files."
|
|
76
|
+
Jekyll.logger.warn "", "The written file may end up with unexpected contents."
|
|
77
|
+
Jekyll.logger.warn "", dest.to_s.cyan
|
|
78
|
+
paths.each { |path| Jekyll.logger.warn "", " - #{path}" }
|
|
79
|
+
Jekyll.logger.warn ""
|
|
77
80
|
end
|
|
78
81
|
conflicting_urls
|
|
79
82
|
end
|
|
80
83
|
|
|
81
84
|
def fsnotify_buggy?(_site)
|
|
82
85
|
return true unless Utils::Platforms.osx?
|
|
86
|
+
|
|
83
87
|
if Dir.pwd != `pwd`.strip
|
|
84
|
-
Jekyll.logger.error
|
|
88
|
+
Jekyll.logger.error <<~STR
|
|
85
89
|
We have detected that there might be trouble using fsevent on your
|
|
86
90
|
operating system, you can read https://github.com/thibaudgg/rb-fsevent/wiki/no-fsevents-fired-(OSX-bug)
|
|
87
|
-
for possible
|
|
91
|
+
for possible workarounds or you can work around it immediately
|
|
88
92
|
with `--force-polling`.
|
|
89
93
|
STR
|
|
90
94
|
|
|
@@ -99,10 +103,11 @@ module Jekyll
|
|
|
99
103
|
urls = case_insensitive_urls(site.pages + site.docs_to_write, site.dest)
|
|
100
104
|
urls.each_value do |real_urls|
|
|
101
105
|
next unless real_urls.uniq.size > 1
|
|
106
|
+
|
|
102
107
|
urls_only_differ_by_case = true
|
|
103
|
-
Jekyll.logger.warn "Warning:", "The following URLs only differ" \
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
Jekyll.logger.warn "Warning:", "The following URLs only differ by case. On a " \
|
|
109
|
+
"case-insensitive file system one of the URLs will be " \
|
|
110
|
+
"overwritten by the other: #{real_urls.join(", ")}"
|
|
106
111
|
end
|
|
107
112
|
urls_only_differ_by_case
|
|
108
113
|
end
|
|
@@ -117,16 +122,20 @@ module Jekyll
|
|
|
117
122
|
end
|
|
118
123
|
|
|
119
124
|
private
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
|
|
126
|
+
def destination_map(site)
|
|
127
|
+
{}.tap do |result|
|
|
128
|
+
site.each_site_file do |thing|
|
|
129
|
+
next if allow_used_permalink?(thing)
|
|
130
|
+
|
|
131
|
+
dest_path = thing.destination(site.dest)
|
|
132
|
+
(result[dest_path] ||= []) << thing.path
|
|
127
133
|
end
|
|
128
134
|
end
|
|
129
|
-
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def allow_used_permalink?(item)
|
|
138
|
+
defined?(JekyllRedirectFrom) && item.is_a?(JekyllRedirectFrom::RedirectPage)
|
|
130
139
|
end
|
|
131
140
|
|
|
132
141
|
def case_insensitive_urls(things, destination)
|
|
@@ -138,8 +147,9 @@ module Jekyll
|
|
|
138
147
|
|
|
139
148
|
def url_exists?(url)
|
|
140
149
|
return true unless url.nil? || url.empty?
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
|
|
151
|
+
Jekyll.logger.warn "Warning:", "You didn't set an URL in the config file, you may " \
|
|
152
|
+
"encounter problems with some plugins."
|
|
143
153
|
false
|
|
144
154
|
end
|
|
145
155
|
|
|
@@ -147,17 +157,18 @@ module Jekyll
|
|
|
147
157
|
Addressable::URI.parse(url)
|
|
148
158
|
true
|
|
149
159
|
# Addressable::URI#parse only raises a TypeError
|
|
150
|
-
# https://
|
|
160
|
+
# https://github.com/sporkmonger/addressable/blob/0a0e96acb17225f9b1c9cab0bad332b448934c9a/lib/addressable/uri.rb#L103
|
|
151
161
|
rescue TypeError
|
|
152
|
-
Jekyll.logger.warn "Warning:", "The site URL does not seem to be valid, "\
|
|
153
|
-
|
|
162
|
+
Jekyll.logger.warn "Warning:", "The site URL does not seem to be valid, " \
|
|
163
|
+
"check the value of `url` in your config file."
|
|
154
164
|
false
|
|
155
165
|
end
|
|
156
166
|
|
|
157
167
|
def url_absolute(url)
|
|
158
|
-
return true if Addressable::URI.parse(url).absolute?
|
|
159
|
-
|
|
160
|
-
|
|
168
|
+
return true if url.is_a?(String) && Addressable::URI.parse(url).absolute?
|
|
169
|
+
|
|
170
|
+
Jekyll.logger.warn "Warning:", "Your site URL does not seem to be absolute, " \
|
|
171
|
+
"check the value of `url` in your config file."
|
|
161
172
|
false
|
|
162
173
|
end
|
|
163
174
|
end
|
data/lib/jekyll/commands/help.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Jekyll
|
|
|
25
25
|
|
|
26
26
|
def invalid_command(prog, cmd)
|
|
27
27
|
Jekyll.logger.error "Error:",
|
|
28
|
-
|
|
28
|
+
"Hmm... we don't know what the '#{cmd}' command is."
|
|
29
29
|
Jekyll.logger.info "Valid commands:", prog.commands.keys.join(", ")
|
|
30
30
|
end
|
|
31
31
|
end
|
data/lib/jekyll/commands/new.rb
CHANGED
|
@@ -28,8 +28,8 @@ module Jekyll
|
|
|
28
28
|
FileUtils.mkdir_p new_blog_path
|
|
29
29
|
if preserve_source_location?(new_blog_path, options)
|
|
30
30
|
Jekyll.logger.error "Conflict:", "#{new_blog_path} exists and is not empty."
|
|
31
|
-
Jekyll.logger.abort_with "", "Ensure #{new_blog_path} is empty or else " \
|
|
32
|
-
|
|
31
|
+
Jekyll.logger.abort_with "", "Ensure #{new_blog_path} is empty or else try again " \
|
|
32
|
+
"with `--force` to proceed and overwrite any files."
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
if options["blank"]
|
|
@@ -41,10 +41,16 @@ module Jekyll
|
|
|
41
41
|
after_install(new_blog_path, options)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def blank_template
|
|
45
|
+
File.expand_path("../../blank_template", __dir__)
|
|
46
|
+
end
|
|
47
|
+
|
|
44
48
|
def create_blank_site(path)
|
|
49
|
+
FileUtils.cp_r blank_template + "/.", path
|
|
50
|
+
FileUtils.chmod_R "u+w", path
|
|
51
|
+
|
|
45
52
|
Dir.chdir(path) do
|
|
46
|
-
FileUtils.mkdir(%w(
|
|
47
|
-
FileUtils.touch("index.html")
|
|
53
|
+
FileUtils.mkdir(%w(_data _drafts _includes _posts))
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
56
|
|
|
@@ -62,61 +68,49 @@ module Jekyll
|
|
|
62
68
|
private
|
|
63
69
|
|
|
64
70
|
def gemfile_contents
|
|
65
|
-
|
|
66
|
-
source "https://rubygems.org"
|
|
67
|
-
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
#
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
# If you
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# If you have any plugins, put them here!
|
|
86
|
-
group :jekyll_plugins do
|
|
87
|
-
gem "jekyll-feed", "~> 0.6"
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
|
91
|
-
# and associated library.
|
|
92
|
-
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
|
93
|
-
gem "tzinfo", ">= 1", "< 3"
|
|
94
|
-
gem "tzinfo-data"
|
|
95
|
-
end
|
|
71
|
+
<<~RUBY
|
|
72
|
+
source "https://rubygems.org"
|
|
73
|
+
# Hello! This is where you manage which Jekyll version is used to run.
|
|
74
|
+
# When you want to use a different version, change it below, save the
|
|
75
|
+
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
|
76
|
+
#
|
|
77
|
+
# bundle exec jekyll serve
|
|
78
|
+
#
|
|
79
|
+
# This will help ensure the proper Jekyll version is running.
|
|
80
|
+
# Happy Jekylling!
|
|
81
|
+
gem "jekyll", "~> #{Jekyll::VERSION}"
|
|
82
|
+
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
|
83
|
+
gem "minima", "~> 2.5"
|
|
84
|
+
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
|
85
|
+
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
|
86
|
+
# gem "github-pages", group: :jekyll_plugins
|
|
87
|
+
# If you have any plugins, put them here!
|
|
88
|
+
group :jekyll_plugins do
|
|
89
|
+
gem "jekyll-feed", "~> 0.12"
|
|
90
|
+
end
|
|
96
91
|
|
|
97
|
-
#
|
|
98
|
-
|
|
92
|
+
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
|
93
|
+
# and associated library.
|
|
94
|
+
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
|
95
|
+
gem "tzinfo", ">= 1", "< 3"
|
|
96
|
+
gem "tzinfo-data"
|
|
97
|
+
end
|
|
99
98
|
|
|
100
|
-
#
|
|
101
|
-
|
|
102
|
-
gem "kramdown-parser-gfm"
|
|
99
|
+
# Performance-booster for watching directories on Windows
|
|
100
|
+
gem "wdm", "~> 0.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
|
103
101
|
|
|
104
|
-
# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
|
|
105
|
-
# do not have a Java counterpart.
|
|
106
|
-
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
|
|
107
|
-
RUBY
|
|
102
|
+
# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
|
|
103
|
+
# do not have a Java counterpart.
|
|
104
|
+
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
|
|
105
|
+
RUBY
|
|
108
106
|
end
|
|
109
107
|
|
|
110
108
|
def create_site(new_blog_path)
|
|
111
109
|
create_sample_files new_blog_path
|
|
112
110
|
|
|
113
|
-
File.
|
|
114
|
-
f.write(scaffold_post_content)
|
|
115
|
-
end
|
|
111
|
+
File.write(File.expand_path(initialized_post_name, new_blog_path), scaffold_post_content)
|
|
116
112
|
|
|
117
|
-
File.
|
|
118
|
-
f.write(gemfile_contents)
|
|
119
|
-
end
|
|
113
|
+
File.write(File.expand_path("Gemfile", new_blog_path), gemfile_contents)
|
|
120
114
|
end
|
|
121
115
|
|
|
122
116
|
def preserve_source_location?(path, options)
|
|
@@ -2,39 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
require "erb"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
module Jekyll
|
|
6
|
+
module Commands
|
|
7
|
+
class NewTheme < Jekyll::Command
|
|
8
|
+
class << self
|
|
9
|
+
def init_with_program(prog)
|
|
10
|
+
prog.command(:"new-theme") do |c|
|
|
11
|
+
c.syntax "new-theme NAME"
|
|
12
|
+
c.description "Creates a new Jekyll theme scaffold"
|
|
13
|
+
c.option "code_of_conduct", "-c", "--code-of-conduct",
|
|
14
|
+
"Include a Code of Conduct. (defaults to false)"
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
c.action do |args, opts|
|
|
17
|
+
Jekyll::Commands::NewTheme.process(args, opts)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
17
20
|
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
end
|
|
22
|
+
def process(args, opts)
|
|
23
|
+
if !args || args.empty?
|
|
24
|
+
raise Jekyll::Errors::InvalidThemeName, "You must specify a theme name."
|
|
25
|
+
end
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Jekyll.logger.abort_with "Conflict:", "#{theme.path} already exists."
|
|
31
|
-
end
|
|
27
|
+
new_theme_name = args.join("_")
|
|
28
|
+
theme = Jekyll::ThemeBuilder.new(new_theme_name, opts)
|
|
29
|
+
Jekyll.logger.abort_with "Conflict:", "#{theme.path} already exists." if theme.path.exist?
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
theme.create!
|
|
32
|
+
Jekyll.logger.info "Your new Jekyll theme, #{theme.name.cyan}, " \
|
|
33
|
+
"is ready for you in #{theme.path.to_s.cyan}!"
|
|
34
|
+
Jekyll.logger.info "For help getting started, read #{theme.path}/README.md."
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
37
|
end
|
|
38
|
-
# rubocop:enable Metrics/AbcSize
|
|
39
38
|
end
|
|
40
39
|
end
|
|
@@ -8,9 +8,7 @@ module Jekyll
|
|
|
8
8
|
module Commands
|
|
9
9
|
class Serve
|
|
10
10
|
class LiveReloadReactor
|
|
11
|
-
attr_reader :started_event
|
|
12
|
-
attr_reader :stopped_event
|
|
13
|
-
attr_reader :thread
|
|
11
|
+
attr_reader :started_event, :stopped_event, :thread
|
|
14
12
|
|
|
15
13
|
def initialize
|
|
16
14
|
@websockets = []
|
|
@@ -58,7 +56,7 @@ module Jekyll
|
|
|
58
56
|
EM.add_shutdown_hook { @stopped_event.set }
|
|
59
57
|
|
|
60
58
|
Jekyll.logger.info "LiveReload address:",
|
|
61
|
-
|
|
59
|
+
"http://#{opts["host"]}:#{opts["livereload_port"]}"
|
|
62
60
|
end
|
|
63
61
|
end
|
|
64
62
|
@thread.abort_on_exception = true
|
|
@@ -68,19 +66,19 @@ module Jekyll
|
|
|
68
66
|
# http://feedback.livereload.com/knowledgebase/articles/86174-livereload-protocol
|
|
69
67
|
def reload(pages)
|
|
70
68
|
pages.each do |p|
|
|
71
|
-
json_message = JSON.dump(
|
|
69
|
+
json_message = JSON.dump(
|
|
72
70
|
:command => "reload",
|
|
73
71
|
:path => p.url,
|
|
74
|
-
:liveCSS => true
|
|
75
|
-
|
|
72
|
+
:liveCSS => true
|
|
73
|
+
)
|
|
76
74
|
|
|
77
|
-
Jekyll.logger.debug "LiveReload:", "Reloading #{p.url}"
|
|
78
|
-
Jekyll.logger.debug "", json_message
|
|
75
|
+
Jekyll.logger.debug "LiveReload:", "Reloading URL #{p.url.inspect}"
|
|
79
76
|
@websockets.each { |ws| ws.send(json_message) }
|
|
80
77
|
end
|
|
81
78
|
end
|
|
82
79
|
|
|
83
80
|
private
|
|
81
|
+
|
|
84
82
|
def connect(websocket, handshake)
|
|
85
83
|
@connections_count += 1
|
|
86
84
|
if @connections_count == 1
|
|
@@ -99,25 +97,20 @@ module Jekyll
|
|
|
99
97
|
@websockets << websocket
|
|
100
98
|
end
|
|
101
99
|
|
|
102
|
-
private
|
|
103
100
|
def disconnect(websocket)
|
|
104
101
|
@websockets.delete(websocket)
|
|
105
102
|
end
|
|
106
103
|
|
|
107
|
-
private
|
|
108
104
|
def print_message(json_message)
|
|
109
105
|
msg = JSON.parse(json_message)
|
|
110
106
|
# Not sure what the 'url' command even does in LiveReload. The spec is silent
|
|
111
107
|
# on its purpose.
|
|
112
|
-
if msg["command"] == "url"
|
|
113
|
-
Jekyll.logger.info "LiveReload:", "Browser URL: #{msg["url"]}"
|
|
114
|
-
end
|
|
108
|
+
Jekyll.logger.info "LiveReload:", "Browser URL: #{msg["url"]}" if msg["command"] == "url"
|
|
115
109
|
end
|
|
116
110
|
|
|
117
|
-
private
|
|
118
111
|
def log_error(error)
|
|
119
112
|
Jekyll.logger.error "LiveReload experienced an error. " \
|
|
120
|
-
|
|
113
|
+
"Run with --trace for more information."
|
|
121
114
|
raise error
|
|
122
115
|
end
|
|
123
116
|
end
|
|
@@ -29,21 +29,21 @@ module Jekyll
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def inline?
|
|
32
|
-
@response["Content-Disposition"]
|
|
32
|
+
@response["Content-Disposition"].to_s.start_with?("inline")
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def bad_browser?
|
|
36
|
-
BAD_USER_AGENTS.any? { |pattern| @request["User-Agent"]
|
|
36
|
+
BAD_USER_AGENTS.any? { |pattern| pattern.match?(@request["User-Agent"]) }
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def html?
|
|
40
|
-
@response["Content-Type"]
|
|
40
|
+
@response["Content-Type"].to_s.include?("text/html")
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# This class inserts the LiveReload script tags into HTML as it is served
|
|
45
45
|
class BodyProcessor
|
|
46
|
-
HEAD_TAG_REGEX = %r!<head>|<head[^(er)][^<]
|
|
46
|
+
HEAD_TAG_REGEX = %r!<head>|<head[^(er)][^<]*>!.freeze
|
|
47
47
|
|
|
48
48
|
attr_reader :content_length, :new_body, :livereload_added
|
|
49
49
|
|
|
@@ -98,17 +98,16 @@ module Jekyll
|
|
|
98
98
|
# Complicated JavaScript to ensure that livereload.js is loaded from the
|
|
99
99
|
# same origin as the page. Mostly useful for dealing with the browser's
|
|
100
100
|
# distinction between 'localhost' and 127.0.0.1
|
|
101
|
-
template
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
@template ||= ERB.new(<<~TEMPLATE)
|
|
102
|
+
<script>
|
|
103
|
+
document.write(
|
|
104
|
+
'<script src="' + location.protocol + '//' +
|
|
105
|
+
(location.host || 'localhost').split(':')[0] +
|
|
106
|
+
':<%=@options["livereload_port"] %>/livereload.js?snipver=1<%= livereload_args %>"' +
|
|
107
|
+
'></' +
|
|
108
|
+
'script>');
|
|
109
|
+
</script>
|
|
110
110
|
TEMPLATE
|
|
111
|
-
ERB.new(Jekyll::Utils.strip_heredoc(template))
|
|
112
111
|
end
|
|
113
112
|
|
|
114
113
|
def livereload_args
|
|
@@ -121,9 +120,7 @@ module Jekyll
|
|
|
121
120
|
if @options["livereload_max_delay"]
|
|
122
121
|
src += "&maxdelay=#{@options["livereload_max_delay"]}"
|
|
123
122
|
end
|
|
124
|
-
if @options["livereload_port"]
|
|
125
|
-
src += "&port=#{@options["livereload_port"]}"
|
|
126
|
-
end
|
|
123
|
+
src += "&port=#{@options["livereload_port"]}" if @options["livereload_port"]
|
|
127
124
|
src
|
|
128
125
|
end
|
|
129
126
|
end
|
|
@@ -131,7 +128,7 @@ module Jekyll
|
|
|
131
128
|
class Servlet < WEBrick::HTTPServlet::FileHandler
|
|
132
129
|
DEFAULTS = {
|
|
133
130
|
"Cache-Control" => "private, max-age=0, proxy-revalidate, " \
|
|
134
|
-
|
|
131
|
+
"no-store, no-cache, must-revalidate",
|
|
135
132
|
}.freeze
|
|
136
133
|
|
|
137
134
|
def initialize(server, root, callbacks)
|
|
@@ -143,7 +140,9 @@ module Jekyll
|
|
|
143
140
|
end
|
|
144
141
|
|
|
145
142
|
def search_index_file(req, res)
|
|
146
|
-
super ||
|
|
143
|
+
super ||
|
|
144
|
+
search_file(req, res, ".html") ||
|
|
145
|
+
search_file(req, res, ".xhtml")
|
|
147
146
|
end
|
|
148
147
|
|
|
149
148
|
# Add the ability to tap file.html the same way that Nginx does on our
|
|
@@ -152,7 +151,9 @@ module Jekyll
|
|
|
152
151
|
|
|
153
152
|
def search_file(req, res, basename)
|
|
154
153
|
# /file.* > /file/index.html > /file.html
|
|
155
|
-
super ||
|
|
154
|
+
super ||
|
|
155
|
+
super(req, res, "#{basename}.html") ||
|
|
156
|
+
super(req, res, "#{basename}.xhtml")
|
|
156
157
|
end
|
|
157
158
|
|
|
158
159
|
# rubocop:disable Naming/MethodName
|
|
@@ -181,7 +182,6 @@ module Jekyll
|
|
|
181
182
|
|
|
182
183
|
private
|
|
183
184
|
|
|
184
|
-
#
|
|
185
185
|
# Inject charset based on Jekyll config only if our mime-types database contains
|
|
186
186
|
# the charset metadata.
|
|
187
187
|
#
|
|
@@ -194,7 +194,6 @@ module Jekyll
|
|
|
194
194
|
res.header["content-type"] = "#{typ}; charset=#{@jekyll_opts["encoding"]}"
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
#
|
|
198
197
|
def set_defaults
|
|
199
198
|
hash_ = @jekyll_opts.fetch("webrick", {}).fetch("headers", {})
|
|
200
199
|
DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|
|
|
@@ -46,7 +46,7 @@ module Jekyll
|
|
|
46
46
|
# WebSockets requests will have a Connection: Upgrade header
|
|
47
47
|
if parser.http_method != "GET" || parser.upgrade?
|
|
48
48
|
super
|
|
49
|
-
elsif parser.request_url
|
|
49
|
+
elsif parser.request_url.start_with?("/livereload.js")
|
|
50
50
|
headers = [
|
|
51
51
|
"HTTP/1.1 200 OK",
|
|
52
52
|
"Content-Type: application/javascript",
|