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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +511 -89
  3. data/LICENSE +1 -1
  4. data/README.markdown +48 -27
  5. data/lib/blank_template/_config.yml +3 -0
  6. data/lib/blank_template/_layouts/default.html +12 -0
  7. data/lib/blank_template/_sass/base.scss +9 -0
  8. data/lib/blank_template/assets/css/main.scss +4 -0
  9. data/lib/blank_template/index.md +8 -0
  10. data/lib/jekyll/cache.rb +186 -0
  11. data/lib/jekyll/cleaner.rb +8 -7
  12. data/lib/jekyll/collection.rb +84 -11
  13. data/lib/jekyll/command.rb +33 -6
  14. data/lib/jekyll/commands/build.rb +8 -28
  15. data/lib/jekyll/commands/clean.rb +3 -2
  16. data/lib/jekyll/commands/doctor.rb +46 -35
  17. data/lib/jekyll/commands/help.rb +1 -1
  18. data/lib/jekyll/commands/new.rb +44 -50
  19. data/lib/jekyll/commands/new_theme.rb +27 -28
  20. data/lib/jekyll/commands/serve/live_reload_reactor.rb +9 -16
  21. data/lib/jekyll/commands/serve/servlet.rb +21 -22
  22. data/lib/jekyll/commands/serve/websockets.rb +1 -1
  23. data/lib/jekyll/commands/serve.rb +75 -97
  24. data/lib/jekyll/configuration.rb +66 -158
  25. data/lib/jekyll/converters/identity.rb +18 -0
  26. data/lib/jekyll/converters/markdown/kramdown_parser.rb +83 -33
  27. data/lib/jekyll/converters/markdown.rb +49 -40
  28. data/lib/jekyll/converters/smartypants.rb +34 -14
  29. data/lib/jekyll/convertible.rb +36 -34
  30. data/lib/jekyll/deprecator.rb +2 -4
  31. data/lib/jekyll/document.rb +107 -72
  32. data/lib/jekyll/drops/collection_drop.rb +3 -4
  33. data/lib/jekyll/drops/document_drop.rb +9 -3
  34. data/lib/jekyll/drops/drop.rb +115 -33
  35. data/lib/jekyll/drops/excerpt_drop.rb +8 -0
  36. data/lib/jekyll/drops/site_drop.rb +9 -8
  37. data/lib/jekyll/drops/static_file_drop.rb +4 -4
  38. data/lib/jekyll/drops/theme_drop.rb +39 -0
  39. data/lib/jekyll/drops/unified_payload_drop.rb +7 -2
  40. data/lib/jekyll/drops/url_drop.rb +55 -3
  41. data/lib/jekyll/entry_filter.rb +42 -51
  42. data/lib/jekyll/excerpt.rb +48 -38
  43. data/lib/jekyll/external.rb +20 -19
  44. data/lib/jekyll/filters/date_filters.rb +6 -3
  45. data/lib/jekyll/filters/grouping_filters.rb +1 -2
  46. data/lib/jekyll/filters/url_filters.rb +50 -15
  47. data/lib/jekyll/filters.rb +211 -50
  48. data/lib/jekyll/frontmatter_defaults.rb +45 -36
  49. data/lib/jekyll/hooks.rb +26 -26
  50. data/lib/jekyll/inclusion.rb +32 -0
  51. data/lib/jekyll/layout.rb +12 -19
  52. data/lib/jekyll/liquid_extensions.rb +0 -2
  53. data/lib/jekyll/liquid_renderer/file.rb +24 -3
  54. data/lib/jekyll/liquid_renderer/table.rb +26 -77
  55. data/lib/jekyll/liquid_renderer.rb +31 -16
  56. data/lib/jekyll/log_adapter.rb +5 -1
  57. data/lib/jekyll/page.rb +51 -23
  58. data/lib/jekyll/page_excerpt.rb +25 -0
  59. data/lib/jekyll/page_without_a_file.rb +0 -4
  60. data/lib/jekyll/path_manager.rb +74 -0
  61. data/lib/jekyll/plugin.rb +5 -11
  62. data/lib/jekyll/plugin_manager.rb +15 -5
  63. data/lib/jekyll/profiler.rb +51 -0
  64. data/lib/jekyll/reader.rb +65 -10
  65. data/lib/jekyll/readers/collection_reader.rb +1 -0
  66. data/lib/jekyll/readers/data_reader.rb +48 -10
  67. data/lib/jekyll/readers/layout_reader.rb +3 -12
  68. data/lib/jekyll/readers/page_reader.rb +5 -5
  69. data/lib/jekyll/readers/post_reader.rb +32 -19
  70. data/lib/jekyll/readers/static_file_reader.rb +4 -4
  71. data/lib/jekyll/readers/theme_assets_reader.rb +8 -5
  72. data/lib/jekyll/regenerator.rb +4 -12
  73. data/lib/jekyll/related_posts.rb +1 -1
  74. data/lib/jekyll/renderer.rb +34 -49
  75. data/lib/jekyll/site.rb +151 -58
  76. data/lib/jekyll/static_file.rb +64 -28
  77. data/lib/jekyll/stevenson.rb +4 -8
  78. data/lib/jekyll/tags/highlight.rb +44 -57
  79. data/lib/jekyll/tags/include.rb +114 -80
  80. data/lib/jekyll/tags/link.rb +12 -7
  81. data/lib/jekyll/tags/post_url.rb +33 -30
  82. data/lib/jekyll/theme.rb +20 -18
  83. data/lib/jekyll/theme_builder.rb +91 -89
  84. data/lib/jekyll/url.rb +18 -10
  85. data/lib/jekyll/utils/ansi.rb +2 -2
  86. data/lib/jekyll/utils/exec.rb +0 -1
  87. data/lib/jekyll/utils/internet.rb +2 -4
  88. data/lib/jekyll/utils/platforms.rb +37 -52
  89. data/lib/jekyll/utils/thread_event.rb +1 -5
  90. data/lib/jekyll/utils.rb +29 -28
  91. data/lib/jekyll/version.rb +1 -1
  92. data/lib/jekyll.rb +9 -14
  93. data/lib/site_template/.gitignore +2 -0
  94. data/lib/site_template/404.html +2 -1
  95. data/lib/site_template/_config.yml +17 -5
  96. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
  97. data/lib/theme_template/README.md.erb +1 -3
  98. data/lib/theme_template/gitignore.erb +1 -0
  99. data/lib/theme_template/theme.gemspec.erb +1 -4
  100. data/rubocop/jekyll/assert_equal_literal_actual.rb +150 -0
  101. data/rubocop/jekyll/no_p_allowed.rb +5 -6
  102. data/rubocop/jekyll/no_puts_allowed.rb +5 -6
  103. metadata +149 -37
  104. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
  105. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
  106. data/lib/jekyll/utils/rouge.rb +0 -22
  107. /data/lib/site_template/{about.md → about.markdown} +0 -0
  108. /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
- Jekyll::Commands::Build.process(options)
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:", "Skipping the initial build." \
34
- " This may result in an out-of-date site."
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
- "disabled when running server detached."
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
- (incremental ? "enabled" : "disabled. Enable with --incremental")
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
- watch_method = Jekyll::Watcher.method(:watch)
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
- "Custom configuration file"
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
- "Detected '_posts' directory outside custom `collections_dir`!"
53
+ "Detected '_posts' directory outside custom `collections_dir`!"
52
54
  Jekyll.logger.warn "",
53
- "Please move '#{posts_at_root}' into the custom directory at " \
54
- "'#{site.in_source_dir(site.config["collections_dir"])}'"
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
- " permalinks, which was removed in" \
62
- " Jekyll v3.0.0."
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
- urls = {}
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:", "The URL '#{url}' is the destination" \
76
- " for the following pages: #{paths.join(", ")}"
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 " " + <<-STR.strip.gsub(%r!\n\s+!, "\n ")
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 work arounds or you can work around it immediately
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
- " by case. On a case-insensitive file system one of the URLs" \
105
- " will be overwritten by the other: #{real_urls.join(", ")}"
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
- def collect_urls(urls, things, destination)
121
- things.each do |thing|
122
- dest = thing.destination(destination)
123
- if urls[dest]
124
- urls[dest] << thing.path
125
- else
126
- urls[dest] = [thing.path]
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
- urls
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
- Jekyll.logger.warn "Warning:", "You didn't set an URL in the config file, "\
142
- "you may encounter problems with some plugins."
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://git.io/vFfbx
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
- "check the value of `url` in your config file."
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
- Jekyll.logger.warn "Warning:", "Your site URL does not seem to be absolute, "\
160
- "check the value of `url` in your config file."
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
@@ -25,7 +25,7 @@ module Jekyll
25
25
 
26
26
  def invalid_command(prog, cmd)
27
27
  Jekyll.logger.error "Error:",
28
- "Hmm... we don't know what the '#{cmd}' command is."
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
@@ -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
- "try again with `--force` to proceed and overwrite any files."
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(_layouts _posts _drafts))
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
- <<-RUBY
66
- source "https://rubygems.org"
67
-
68
- # Hello! This is where you manage which Jekyll version is used to run.
69
- # When you want to use a different version, change it below, save the
70
- # file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
71
- #
72
- # bundle exec jekyll serve
73
- #
74
- # This will help ensure the proper Jekyll version is running.
75
- # Happy Jekylling!
76
- gem "jekyll", "~> #{Jekyll::VERSION}"
77
-
78
- # This is the default theme for new Jekyll sites. You may change this to anything you like.
79
- gem "minima", "~> 2.0"
80
-
81
- # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
82
- # uncomment the line below. To upgrade, run `bundle update github-pages`.
83
- # gem "github-pages", group: :jekyll_plugins
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
- # Performance-booster for watching directories on Windows
98
- gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
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
- # kramdown v2 ships without the gfm parser by default. If you're using
101
- # kramdown v1, comment out this line.
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.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
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.open(File.expand_path("Gemfile", new_blog_path), "w") do |f|
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
- class Jekyll::Commands::NewTheme < Jekyll::Command
6
- class << self
7
- def init_with_program(prog)
8
- prog.command(:"new-theme") do |c|
9
- c.syntax "new-theme NAME"
10
- c.description "Creates a new Jekyll theme scaffold"
11
- c.option "code_of_conduct", \
12
- "-c", "--code-of-conduct", \
13
- "Include a Code of Conduct. (defaults to false)"
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
- c.action do |args, opts|
16
- Jekyll::Commands::NewTheme.process(args, opts)
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
- # rubocop:disable Metrics/AbcSize
22
- def process(args, opts)
23
- if !args || args.empty?
24
- raise Jekyll::Errors::InvalidThemeName, "You must specify a theme name."
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
- new_theme_name = args.join("_")
28
- theme = Jekyll::ThemeBuilder.new(new_theme_name, opts)
29
- if theme.path.exist?
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
- theme.create!
34
- Jekyll.logger.info "Your new Jekyll theme, #{theme.name.cyan}," \
35
- " is ready for you in #{theme.path.to_s.cyan}!"
36
- Jekyll.logger.info "For help getting started, read #{theme.path}/README.md."
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
- "http://#{opts["host"]}:#{opts["livereload_port"]}"
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
- "Run with --trace for more information."
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"] =~ %r!^inline!
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"] =~ pattern }
36
+ BAD_USER_AGENTS.any? { |pattern| pattern.match?(@request["User-Agent"]) }
37
37
  end
38
38
 
39
39
  def html?
40
- @response["Content-Type"] =~ %r!text/html!
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 = <<-TEMPLATE
102
- <script>
103
- document.write(
104
- '<script src="http://' +
105
- (location.host || 'localhost').split(':')[0] +
106
- ':<%=@options["livereload_port"] %>/livereload.js?snipver=1<%= livereload_args %>"' +
107
- '></' +
108
- 'script>');
109
- </script>
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 += "&amp;maxdelay=#{@options["livereload_max_delay"]}"
123
122
  end
124
- if @options["livereload_port"]
125
- src += "&amp;port=#{@options["livereload_port"]}"
126
- end
123
+ src += "&amp;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
- "no-store, no-cache, must-revalidate",
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 || search_file(req, res, ".html")
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 || super(req, res, "#{basename}.html")
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 =~ %r!^\/livereload.js!
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",