jekyll 3.8.7 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +71 -62
- data/LICENSE +1 -1
- data/README.markdown +46 -17
- data/lib/blank_template/_config.yml +3 -0
- data/lib/blank_template/_layouts/default.html +12 -0
- data/lib/blank_template/_sass/main.scss +9 -0
- data/lib/blank_template/assets/css/main.scss +4 -0
- data/lib/blank_template/index.md +8 -0
- data/lib/jekyll.rb +10 -1
- data/lib/jekyll/cache.rb +190 -0
- data/lib/jekyll/cleaner.rb +5 -4
- data/lib/jekyll/collection.rb +82 -10
- data/lib/jekyll/command.rb +33 -6
- data/lib/jekyll/commands/build.rb +11 -20
- data/lib/jekyll/commands/clean.rb +2 -0
- data/lib/jekyll/commands/doctor.rb +15 -8
- data/lib/jekyll/commands/help.rb +1 -1
- data/lib/jekyll/commands/new.rb +37 -35
- data/lib/jekyll/commands/new_theme.rb +30 -28
- data/lib/jekyll/commands/serve.rb +55 -81
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
- data/lib/jekyll/commands/serve/servlet.rb +22 -25
- data/lib/jekyll/commands/serve/websockets.rb +1 -1
- data/lib/jekyll/configuration.rb +61 -149
- data/lib/jekyll/converters/identity.rb +18 -0
- data/lib/jekyll/converters/markdown.rb +49 -40
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +84 -11
- data/lib/jekyll/converters/smartypants.rb +34 -14
- data/lib/jekyll/convertible.rb +30 -31
- data/lib/jekyll/deprecator.rb +1 -3
- data/lib/jekyll/document.rb +89 -61
- data/lib/jekyll/drops/collection_drop.rb +2 -3
- data/lib/jekyll/drops/document_drop.rb +14 -1
- data/lib/jekyll/drops/drop.rb +17 -14
- data/lib/jekyll/drops/excerpt_drop.rb +4 -0
- data/lib/jekyll/drops/page_drop.rb +18 -0
- data/lib/jekyll/drops/site_drop.rb +6 -5
- data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
- data/lib/jekyll/drops/url_drop.rb +53 -1
- data/lib/jekyll/entry_filter.rb +42 -45
- data/lib/jekyll/excerpt.rb +45 -34
- data/lib/jekyll/external.rb +10 -5
- data/lib/jekyll/filters.rb +200 -40
- 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 +46 -14
- data/lib/jekyll/frontmatter_defaults.rb +46 -35
- data/lib/jekyll/hooks.rb +4 -8
- data/lib/jekyll/inclusion.rb +32 -0
- data/lib/jekyll/liquid_extensions.rb +0 -2
- data/lib/jekyll/liquid_renderer.rb +31 -16
- data/lib/jekyll/liquid_renderer/file.rb +24 -3
- data/lib/jekyll/liquid_renderer/table.rb +36 -77
- data/lib/jekyll/log_adapter.rb +5 -1
- data/lib/jekyll/mime.types +53 -11
- data/lib/jekyll/page.rb +54 -12
- data/lib/jekyll/page_excerpt.rb +26 -0
- data/lib/jekyll/page_without_a_file.rb +0 -4
- data/lib/jekyll/path_manager.rb +31 -0
- data/lib/jekyll/plugin.rb +5 -11
- data/lib/jekyll/plugin_manager.rb +2 -0
- data/lib/jekyll/profiler.rb +58 -0
- data/lib/jekyll/reader.rb +42 -9
- data/lib/jekyll/readers/collection_reader.rb +1 -0
- data/lib/jekyll/readers/data_reader.rb +8 -9
- 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 +31 -18
- 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/renderer.rb +23 -40
- data/lib/jekyll/site.rb +91 -38
- data/lib/jekyll/static_file.rb +62 -21
- data/lib/jekyll/stevenson.rb +2 -3
- data/lib/jekyll/tags/highlight.rb +19 -51
- data/lib/jekyll/tags/include.rb +82 -42
- data/lib/jekyll/tags/link.rb +11 -7
- data/lib/jekyll/tags/post_url.rb +25 -21
- data/lib/jekyll/theme.rb +16 -18
- data/lib/jekyll/theme_builder.rb +91 -89
- data/lib/jekyll/url.rb +10 -5
- data/lib/jekyll/utils.rb +18 -21
- data/lib/jekyll/utils/ansi.rb +1 -1
- data/lib/jekyll/utils/exec.rb +0 -1
- data/lib/jekyll/utils/internet.rb +2 -4
- data/lib/jekyll/utils/platforms.rb +8 -8
- data/lib/jekyll/utils/thread_event.rb +1 -5
- data/lib/jekyll/utils/win_tz.rb +2 -2
- data/lib/jekyll/version.rb +1 -1
- data/lib/site_template/.gitignore +2 -0
- data/lib/site_template/404.html +1 -0
- 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/site_template/{about.md → about.markdown} +0 -0
- data/lib/site_template/{index.md → index.markdown} +0 -0
- 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 +149 -0
- metadata +69 -31
- 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
@@ -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",
|
data/lib/jekyll/configuration.rb
CHANGED
@@ -4,11 +4,12 @@ module Jekyll
|
|
4
4
|
class Configuration < Hash
|
5
5
|
# Default options. Overridden by values in _config.yml.
|
6
6
|
# Strings rather than symbols are used for compatibility with YAML.
|
7
|
-
DEFAULTS =
|
7
|
+
DEFAULTS = {
|
8
8
|
# Where things are
|
9
9
|
"source" => Dir.pwd,
|
10
10
|
"destination" => File.join(Dir.pwd, "_site"),
|
11
11
|
"collections_dir" => "",
|
12
|
+
"cache_dir" => ".jekyll-cache",
|
12
13
|
"plugins_dir" => "_plugins",
|
13
14
|
"layouts_dir" => "_layouts",
|
14
15
|
"data_dir" => "_data",
|
@@ -18,10 +19,7 @@ module Jekyll
|
|
18
19
|
# Handling Reading
|
19
20
|
"safe" => false,
|
20
21
|
"include" => [".htaccess"],
|
21
|
-
"exclude" =>
|
22
|
-
Gemfile Gemfile.lock node_modules vendor/bundle/ vendor/cache/ vendor/gems/
|
23
|
-
vendor/ruby/
|
24
|
-
),
|
22
|
+
"exclude" => [],
|
25
23
|
"keep_files" => [".git", ".svn"],
|
26
24
|
"encoding" => "utf-8",
|
27
25
|
"markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
|
@@ -66,40 +64,29 @@ module Jekyll
|
|
66
64
|
"strict_variables" => false,
|
67
65
|
},
|
68
66
|
|
69
|
-
"rdiscount" => {
|
70
|
-
"extensions" => [],
|
71
|
-
},
|
72
|
-
|
73
|
-
"redcarpet" => {
|
74
|
-
"extensions" => [],
|
75
|
-
},
|
76
|
-
|
77
67
|
"kramdown" => {
|
78
68
|
"auto_ids" => true,
|
79
|
-
"toc_levels" =>
|
69
|
+
"toc_levels" => (1..6).to_a,
|
80
70
|
"entity_output" => "as_char",
|
81
71
|
"smart_quotes" => "lsquo,rsquo,ldquo,rdquo",
|
82
72
|
"input" => "GFM",
|
83
73
|
"hard_wrap" => false,
|
74
|
+
"guess_lang" => true,
|
84
75
|
"footnote_nr" => 1,
|
85
76
|
"show_warnings" => false,
|
86
77
|
},
|
87
|
-
}.
|
78
|
+
}.each_with_object(Configuration.new) { |(k, v), hsh| hsh[k] = v.freeze }.freeze
|
88
79
|
|
89
80
|
class << self
|
90
81
|
# Static: Produce a Configuration ready for use in a Site.
|
91
|
-
# It takes the input, fills in the defaults where values do not
|
92
|
-
# exist, and patches common issues including migrating options for
|
93
|
-
# backwards compatiblity. Except where a key or value is being fixed,
|
94
|
-
# the user configuration will override the defaults.
|
82
|
+
# It takes the input, fills in the defaults where values do not exist.
|
95
83
|
#
|
96
84
|
# user_config - a Hash or Configuration of overrides.
|
97
85
|
#
|
98
|
-
# Returns a Configuration filled with defaults
|
99
|
-
# problems and backwards-compatibility.
|
86
|
+
# Returns a Configuration filled with defaults.
|
100
87
|
def from(user_config)
|
101
88
|
Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
|
102
|
-
.add_default_collections
|
89
|
+
.add_default_collections.add_default_excludes
|
103
90
|
end
|
104
91
|
end
|
105
92
|
|
@@ -107,7 +94,7 @@ module Jekyll
|
|
107
94
|
#
|
108
95
|
# Return a copy of the hash where all its keys are strings
|
109
96
|
def stringify_keys
|
110
|
-
|
97
|
+
each_with_object({}) { |(k, v), hsh| hsh[k.to_s] = v }
|
111
98
|
end
|
112
99
|
|
113
100
|
def get_config_value_with_override(config_key, override)
|
@@ -141,8 +128,8 @@ module Jekyll
|
|
141
128
|
when %r!\.ya?ml!i
|
142
129
|
SafeYAML.load_file(filename) || {}
|
143
130
|
else
|
144
|
-
raise ArgumentError,
|
145
|
-
|
131
|
+
raise ArgumentError,
|
132
|
+
"No parser for '#{filename}' is available. Use a .y(a)ml or .toml file instead."
|
146
133
|
end
|
147
134
|
end
|
148
135
|
|
@@ -161,7 +148,7 @@ module Jekyll
|
|
161
148
|
# Get configuration from <source>/_config.yml or <source>/<config_file>
|
162
149
|
config_files = override["config"]
|
163
150
|
if config_files.to_s.empty?
|
164
|
-
default = %w(yml yaml).find(-> { "yml" }) do |ext|
|
151
|
+
default = %w(yml yaml toml).find(-> { "yml" }) do |ext|
|
165
152
|
File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}"))
|
166
153
|
end
|
167
154
|
config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
|
@@ -176,8 +163,13 @@ module Jekyll
|
|
176
163
|
#
|
177
164
|
# Returns this configuration, overridden by the values in the file
|
178
165
|
def read_config_file(file)
|
166
|
+
file = File.expand_path(file)
|
179
167
|
next_config = safe_load_file(file)
|
180
|
-
|
168
|
+
|
169
|
+
unless next_config.is_a?(Hash)
|
170
|
+
raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
|
171
|
+
end
|
172
|
+
|
181
173
|
Jekyll.logger.info "Configuration file:", file
|
182
174
|
next_config
|
183
175
|
rescue SystemCallError
|
@@ -185,8 +177,7 @@ module Jekyll
|
|
185
177
|
Jekyll.logger.warn "Configuration file:", "none"
|
186
178
|
{}
|
187
179
|
else
|
188
|
-
Jekyll.logger.error "Fatal:", "The configuration file '#{file}'
|
189
|
-
could not be found."
|
180
|
+
Jekyll.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
|
190
181
|
raise LoadError, "The Configuration file '#{file}' could not be found."
|
191
182
|
end
|
192
183
|
end
|
@@ -203,16 +194,16 @@ module Jekyll
|
|
203
194
|
begin
|
204
195
|
files.each do |config_file|
|
205
196
|
next if config_file.nil? || config_file.empty?
|
197
|
+
|
206
198
|
new_config = read_config_file(config_file)
|
207
199
|
configuration = Utils.deep_merge_hashes(configuration, new_config)
|
208
200
|
end
|
209
|
-
rescue ArgumentError =>
|
210
|
-
Jekyll.logger.warn "WARNING:", "Error reading configuration. "
|
211
|
-
|
212
|
-
warn err
|
201
|
+
rescue ArgumentError => e
|
202
|
+
Jekyll.logger.warn "WARNING:", "Error reading configuration. Using defaults (and options)."
|
203
|
+
warn e
|
213
204
|
end
|
214
205
|
|
215
|
-
configuration.
|
206
|
+
configuration.validate.add_default_collections
|
216
207
|
end
|
217
208
|
|
218
209
|
# Public: Split a CSV string into an array containing its values
|
@@ -224,35 +215,18 @@ module Jekyll
|
|
224
215
|
csv.split(",").map(&:strip)
|
225
216
|
end
|
226
217
|
|
227
|
-
# Public: Ensure the proper options are set in the configuration
|
228
|
-
# backwards-compatibility with Jekyll pre-1.0
|
218
|
+
# Public: Ensure the proper options are set in the configuration
|
229
219
|
#
|
230
|
-
# Returns the
|
231
|
-
def
|
220
|
+
# Returns the configuration Hash
|
221
|
+
def validate
|
232
222
|
config = clone
|
233
|
-
# Provide backwards-compatibility
|
234
|
-
check_auto(config)
|
235
|
-
check_server(config)
|
236
|
-
check_plugins(config)
|
237
|
-
|
238
|
-
renamed_key "server_port", "port", config
|
239
|
-
renamed_key "gems", "plugins", config
|
240
|
-
renamed_key "layouts", "layouts_dir", config
|
241
|
-
renamed_key "data_source", "data_dir", config
|
242
223
|
|
243
|
-
|
224
|
+
check_plugins(config)
|
244
225
|
check_include_exclude(config)
|
245
|
-
check_coderay(config)
|
246
|
-
check_maruku(config)
|
247
226
|
|
248
227
|
config
|
249
228
|
end
|
250
229
|
|
251
|
-
# DEPRECATED.
|
252
|
-
def fix_common_issues
|
253
|
-
self
|
254
|
-
end
|
255
|
-
|
256
230
|
def add_default_collections
|
257
231
|
config = clone
|
258
232
|
|
@@ -261,7 +235,9 @@ module Jekyll
|
|
261
235
|
|
262
236
|
# Ensure we have a hash.
|
263
237
|
if config["collections"].is_a?(Array)
|
264
|
-
config["collections"] =
|
238
|
+
config["collections"] = config["collections"].each_with_object({}) do |collection, hash|
|
239
|
+
hash[collection] = {}
|
240
|
+
end
|
265
241
|
end
|
266
242
|
|
267
243
|
config["collections"] = Utils.deep_merge_hashes(
|
@@ -276,16 +252,23 @@ module Jekyll
|
|
276
252
|
config
|
277
253
|
end
|
278
254
|
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
255
|
+
DEFAULT_EXCLUDES = %w(
|
256
|
+
.sass-cache .jekyll-cache
|
257
|
+
gemfiles Gemfile Gemfile.lock
|
258
|
+
node_modules
|
259
|
+
vendor/bundle/ vendor/cache/ vendor/gems/ vendor/ruby/
|
260
|
+
).freeze
|
261
|
+
|
262
|
+
def add_default_excludes
|
263
|
+
config = clone
|
264
|
+
return config if config["exclude"].nil?
|
265
|
+
|
266
|
+
config["exclude"].concat(DEFAULT_EXCLUDES).uniq!
|
267
|
+
config
|
286
268
|
end
|
287
269
|
|
288
270
|
private
|
271
|
+
|
289
272
|
def style_to_permalink(permalink_style)
|
290
273
|
case permalink_style.to_sym
|
291
274
|
when :pretty
|
@@ -296,89 +279,20 @@ module Jekyll
|
|
296
279
|
"/:categories/:year/:month/:day/:title:output_ext"
|
297
280
|
when :ordinal
|
298
281
|
"/:categories/:year/:y_day/:title:output_ext"
|
282
|
+
when :weekdate
|
283
|
+
"/:categories/:year/W:week/:short_day/:title:output_ext"
|
299
284
|
else
|
300
285
|
permalink_style.to_s
|
301
286
|
end
|
302
287
|
end
|
303
288
|
|
304
|
-
# Private: Checks if a given config is a hash
|
305
|
-
#
|
306
|
-
# extracted_config - the value to check
|
307
|
-
# file - the file from which the config was extracted
|
308
|
-
#
|
309
|
-
# Raises an ArgumentError if given config is not a hash
|
310
|
-
private
|
311
|
-
def check_config_is_hash!(extracted_config, file)
|
312
|
-
unless extracted_config.is_a?(Hash)
|
313
|
-
raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
private
|
318
|
-
def check_auto(config)
|
319
|
-
if config.key?("auto") || config.key?("watch")
|
320
|
-
Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" \
|
321
|
-
" be set from your configuration file(s). Use the" \
|
322
|
-
" --[no-]watch/-w command-line option instead."
|
323
|
-
config.delete("auto")
|
324
|
-
config.delete("watch")
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
private
|
329
|
-
def check_server(config)
|
330
|
-
if config.key?("server")
|
331
|
-
Jekyll::Deprecator.deprecation_message "The 'server' configuration option" \
|
332
|
-
" is no longer accepted. Use the 'jekyll serve'" \
|
333
|
-
" subcommand to serve your site with WEBrick."
|
334
|
-
config.delete("server")
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
private
|
339
|
-
def check_pygments(config)
|
340
|
-
if config.key?("pygments")
|
341
|
-
Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" \
|
342
|
-
" has been renamed to 'highlighter'. Please update your" \
|
343
|
-
" config file accordingly. The allowed values are 'rouge', " \
|
344
|
-
"'pygments' or null."
|
345
|
-
|
346
|
-
config["highlighter"] = "pygments" if config["pygments"]
|
347
|
-
config.delete("pygments")
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
private
|
352
289
|
def check_include_exclude(config)
|
353
290
|
%w(include exclude).each do |option|
|
354
|
-
|
355
|
-
|
356
|
-
" must now be specified as an array, but you specified" \
|
357
|
-
" a string. For now, we've treated the string you provided" \
|
358
|
-
" as a list of comma-separated values."
|
359
|
-
config[option] = csv_to_array(config[option])
|
360
|
-
end
|
361
|
-
config[option].map!(&:to_s) if config[option]
|
362
|
-
end
|
363
|
-
end
|
291
|
+
next unless config.key?(option)
|
292
|
+
next if config[option].is_a?(Array)
|
364
293
|
|
365
|
-
|
366
|
-
|
367
|
-
if (config["kramdown"] || {}).key?("use_coderay")
|
368
|
-
Jekyll::Deprecator.deprecation_message "Please change 'use_coderay'" \
|
369
|
-
" to 'enable_coderay' in your configuration file."
|
370
|
-
config["kramdown"]["use_coderay"] = config["kramdown"].delete("enable_coderay")
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
private
|
375
|
-
def check_maruku(config)
|
376
|
-
if config.fetch("markdown", "kramdown").to_s.casecmp("maruku").zero?
|
377
|
-
Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " \
|
378
|
-
"Markdown processor, which has been removed as of 3.0.0. " \
|
379
|
-
"We recommend you switch to Kramdown. To do this, replace " \
|
380
|
-
"`markdown: maruku` with `markdown: kramdown` in your " \
|
381
|
-
"`_config.yml` file."
|
294
|
+
raise Jekyll::Errors::InvalidConfigurationError,
|
295
|
+
"'#{option}' should be set as an array, but was: #{config[option].inspect}."
|
382
296
|
end
|
383
297
|
end
|
384
298
|
|
@@ -387,18 +301,16 @@ module Jekyll
|
|
387
301
|
# config - the config hash
|
388
302
|
#
|
389
303
|
# Raises a Jekyll::Errors::InvalidConfigurationError if the config `plugins`
|
390
|
-
# is
|
391
|
-
private
|
304
|
+
# is not an Array.
|
392
305
|
def check_plugins(config)
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
end
|
306
|
+
return unless config.key?("plugins")
|
307
|
+
return if config["plugins"].is_a?(Array)
|
308
|
+
|
309
|
+
Jekyll.logger.error "'plugins' should be set as an array of gem-names, but was: " \
|
310
|
+
"#{config["plugins"].inspect}. Use 'plugins_dir' instead to set the directory " \
|
311
|
+
"for your non-gemified Ruby plugins."
|
312
|
+
raise Jekyll::Errors::InvalidConfigurationError,
|
313
|
+
"'plugins' should be set as an array, but was: #{config["plugins"].inspect}."
|
402
314
|
end
|
403
315
|
end
|
404
316
|
end
|
@@ -2,19 +2,37 @@
|
|
2
2
|
|
3
3
|
module Jekyll
|
4
4
|
module Converters
|
5
|
+
# Identity converter. Returns same content as given.
|
6
|
+
# For more info on converters see https://jekyllrb.com/docs/plugins/converters/
|
5
7
|
class Identity < Converter
|
6
8
|
safe true
|
7
9
|
|
8
10
|
priority :lowest
|
9
11
|
|
12
|
+
# Public: Does the given extension match this converter's list of acceptable extensions?
|
13
|
+
# Takes one argument: the file's extension (including the dot).
|
14
|
+
#
|
15
|
+
# _ext - The String extension to check (not relevant here)
|
16
|
+
#
|
17
|
+
# Returns true since it always matches.
|
10
18
|
def matches(_ext)
|
11
19
|
true
|
12
20
|
end
|
13
21
|
|
22
|
+
# Public: The extension to be given to the output file (including the dot).
|
23
|
+
#
|
24
|
+
# ext - The String extension or original file.
|
25
|
+
#
|
26
|
+
# Returns The String output file extension.
|
14
27
|
def output_ext(ext)
|
15
28
|
ext
|
16
29
|
end
|
17
30
|
|
31
|
+
# Logic to do the content conversion.
|
32
|
+
#
|
33
|
+
# content - String content of file (without front matter).
|
34
|
+
#
|
35
|
+
# Returns a String of the converted content.
|
18
36
|
def convert(content)
|
19
37
|
content
|
20
38
|
end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Jekyll
|
4
4
|
module Converters
|
5
|
+
# Markdown converter.
|
6
|
+
# For more info on converters see https://jekyllrb.com/docs/plugins/converters/
|
5
7
|
class Markdown < Converter
|
6
8
|
highlighter_prefix "\n"
|
7
9
|
highlighter_suffix "\n"
|
@@ -9,80 +11,91 @@ module Jekyll
|
|
9
11
|
|
10
12
|
def setup
|
11
13
|
return if @setup ||= false
|
14
|
+
|
12
15
|
unless (@parser = get_processor)
|
13
|
-
Jekyll.logger.error "Invalid Markdown processor given:", @config["markdown"]
|
14
16
|
if @config["safe"]
|
15
|
-
Jekyll.logger.
|
17
|
+
Jekyll.logger.warn "Build Warning:", "Custom processors are not loaded in safe mode"
|
16
18
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
)
|
21
|
-
|
19
|
+
|
20
|
+
Jekyll.logger.error "Markdown processor:",
|
21
|
+
"#{@config["markdown"].inspect} is not a valid Markdown processor."
|
22
|
+
Jekyll.logger.error "", "Available processors are: #{valid_processors.join(", ")}"
|
23
|
+
Jekyll.logger.error ""
|
24
|
+
raise Errors::FatalException, "Invalid Markdown processor given: #{@config["markdown"]}"
|
22
25
|
end
|
23
26
|
|
27
|
+
@cache = Jekyll::Cache.new("Jekyll::Converters::Markdown")
|
24
28
|
@setup = true
|
25
29
|
end
|
26
30
|
|
27
|
-
#
|
31
|
+
# RuboCop does not allow reader methods to have names starting with `get_`
|
28
32
|
# To ensure compatibility, this check has been disabled on this method
|
29
33
|
#
|
30
34
|
# rubocop:disable Naming/AccessorMethodName
|
31
35
|
def get_processor
|
32
36
|
case @config["markdown"].downcase
|
33
|
-
when "
|
34
|
-
when "kramdown" then return KramdownParser.new(@config)
|
35
|
-
when "rdiscount" then return RDiscountParser.new(@config)
|
37
|
+
when "kramdown" then KramdownParser.new(@config)
|
36
38
|
else
|
37
39
|
custom_processor
|
38
40
|
end
|
39
41
|
end
|
40
42
|
# rubocop:enable Naming/AccessorMethodName
|
41
43
|
|
42
|
-
# Public: Provides you with a list of processors
|
43
|
-
#
|
44
|
-
#
|
45
|
-
|
44
|
+
# Public: Provides you with a list of processors comprised of the ones we support internally
|
45
|
+
# and the ones that you have provided to us (if they're whitelisted for use in safe mode).
|
46
|
+
#
|
47
|
+
# Returns an array of symbols.
|
46
48
|
def valid_processors
|
47
|
-
|
49
|
+
[:kramdown] + third_party_processors
|
48
50
|
end
|
49
51
|
|
50
52
|
# Public: A list of processors that you provide via plugins.
|
51
|
-
#
|
52
|
-
#
|
53
|
-
|
53
|
+
#
|
54
|
+
# Returns an array of symbols
|
54
55
|
def third_party_processors
|
55
|
-
self.class.constants -
|
56
|
-
%w(KramdownParser RDiscountParser RedcarpetParser PRIORITIES).map(
|
57
|
-
&:to_sym
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
def extname_list
|
62
|
-
@extname_list ||= @config["markdown_ext"].split(",").map do |e|
|
63
|
-
".#{e.downcase}"
|
64
|
-
end
|
56
|
+
self.class.constants - [:KramdownParser, :PRIORITIES]
|
65
57
|
end
|
66
58
|
|
59
|
+
# Does the given extension match this converter's list of acceptable extensions?
|
60
|
+
# Takes one argument: the file's extension (including the dot).
|
61
|
+
#
|
62
|
+
# ext - The String extension to check.
|
63
|
+
#
|
64
|
+
# Returns true if it matches, false otherwise.
|
67
65
|
def matches(ext)
|
68
66
|
extname_list.include?(ext.downcase)
|
69
67
|
end
|
70
68
|
|
69
|
+
# Public: The extension to be given to the output file (including the dot).
|
70
|
+
#
|
71
|
+
# ext - The String extension or original file.
|
72
|
+
#
|
73
|
+
# Returns The String output file extension.
|
71
74
|
def output_ext(_ext)
|
72
75
|
".html"
|
73
76
|
end
|
74
77
|
|
78
|
+
# Logic to do the content conversion.
|
79
|
+
#
|
80
|
+
# content - String content of file (without front matter).
|
81
|
+
#
|
82
|
+
# Returns a String of the converted content.
|
75
83
|
def convert(content)
|
76
84
|
setup
|
77
|
-
@
|
85
|
+
@cache.getset(content) do
|
86
|
+
@parser.convert(content)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def extname_list
|
91
|
+
@extname_list ||= @config["markdown_ext"].split(",").map! { |e| ".#{e.downcase}" }
|
78
92
|
end
|
79
93
|
|
80
94
|
private
|
95
|
+
|
81
96
|
def custom_processor
|
82
97
|
converter_name = @config["markdown"]
|
83
|
-
if custom_class_allowed?(converter_name)
|
84
|
-
self.class.const_get(converter_name).new(@config)
|
85
|
-
end
|
98
|
+
self.class.const_get(converter_name).new(@config) if custom_class_allowed?(converter_name)
|
86
99
|
end
|
87
100
|
|
88
101
|
# Private: Determine whether a class name is an allowed custom
|
@@ -90,14 +103,10 @@ module Jekyll
|
|
90
103
|
#
|
91
104
|
# parser_name - the name of the parser class
|
92
105
|
#
|
93
|
-
# Returns true if the parser name contains only alphanumeric
|
94
|
-
#
|
95
|
-
|
96
|
-
private
|
106
|
+
# Returns true if the parser name contains only alphanumeric characters and is defined
|
107
|
+
# within Jekyll::Converters::Markdown
|
97
108
|
def custom_class_allowed?(parser_name)
|
98
|
-
parser_name !~ %r![^A-Za-z0-9_]! && self.class.constants.include?(
|
99
|
-
parser_name.to_sym
|
100
|
-
)
|
109
|
+
parser_name !~ %r![^A-Za-z0-9_]! && self.class.constants.include?(parser_name.to_sym)
|
101
110
|
end
|
102
111
|
end
|
103
112
|
end
|