jekyll 4.2.1 → 4.2.2
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 +350 -350
- data/LICENSE +21 -21
- data/README.markdown +86 -86
- data/exe/jekyll +57 -57
- data/lib/blank_template/_config.yml +3 -3
- data/lib/blank_template/_layouts/default.html +12 -12
- data/lib/blank_template/_sass/main.scss +9 -9
- data/lib/blank_template/assets/css/main.scss +4 -4
- data/lib/blank_template/index.md +8 -8
- data/lib/jekyll/cache.rb +190 -190
- data/lib/jekyll/cleaner.rb +111 -111
- data/lib/jekyll/collection.rb +309 -309
- data/lib/jekyll/command.rb +105 -105
- data/lib/jekyll/commands/build.rb +93 -93
- data/lib/jekyll/commands/clean.rb +45 -45
- data/lib/jekyll/commands/doctor.rb +177 -177
- data/lib/jekyll/commands/help.rb +34 -34
- data/lib/jekyll/commands/new.rb +172 -169
- data/lib/jekyll/commands/new_theme.rb +40 -40
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +122 -122
- data/lib/jekyll/commands/serve/livereload_assets/livereload.js +1183 -1183
- data/lib/jekyll/commands/serve/servlet.rb +202 -202
- data/lib/jekyll/commands/serve/websockets.rb +81 -81
- data/lib/jekyll/commands/serve.rb +362 -362
- data/lib/jekyll/configuration.rb +313 -313
- data/lib/jekyll/converter.rb +54 -54
- data/lib/jekyll/converters/identity.rb +41 -41
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +199 -199
- data/lib/jekyll/converters/markdown.rb +113 -113
- data/lib/jekyll/converters/smartypants.rb +70 -70
- data/lib/jekyll/convertible.rb +257 -257
- data/lib/jekyll/deprecator.rb +50 -50
- data/lib/jekyll/document.rb +544 -544
- data/lib/jekyll/drops/collection_drop.rb +20 -20
- data/lib/jekyll/drops/document_drop.rb +70 -70
- data/lib/jekyll/drops/drop.rb +293 -293
- data/lib/jekyll/drops/excerpt_drop.rb +19 -19
- data/lib/jekyll/drops/jekyll_drop.rb +32 -32
- data/lib/jekyll/drops/site_drop.rb +66 -66
- data/lib/jekyll/drops/static_file_drop.rb +14 -14
- data/lib/jekyll/drops/unified_payload_drop.rb +26 -26
- data/lib/jekyll/drops/url_drop.rb +140 -140
- data/lib/jekyll/entry_filter.rb +121 -121
- data/lib/jekyll/errors.rb +20 -20
- data/lib/jekyll/excerpt.rb +201 -201
- data/lib/jekyll/external.rb +79 -79
- data/lib/jekyll/filters/date_filters.rb +110 -110
- data/lib/jekyll/filters/grouping_filters.rb +64 -64
- data/lib/jekyll/filters/url_filters.rb +98 -98
- data/lib/jekyll/filters.rb +535 -535
- data/lib/jekyll/frontmatter_defaults.rb +240 -240
- data/lib/jekyll/generator.rb +5 -5
- data/lib/jekyll/hooks.rb +107 -107
- data/lib/jekyll/inclusion.rb +32 -32
- data/lib/jekyll/layout.rb +67 -67
- data/lib/jekyll/liquid_extensions.rb +22 -22
- data/lib/jekyll/liquid_renderer/file.rb +77 -77
- data/lib/jekyll/liquid_renderer/table.rb +55 -55
- data/lib/jekyll/liquid_renderer.rb +80 -80
- data/lib/jekyll/log_adapter.rb +151 -151
- data/lib/jekyll/mime.types +866 -866
- data/lib/jekyll/page.rb +217 -217
- data/lib/jekyll/page_excerpt.rb +25 -25
- data/lib/jekyll/page_without_a_file.rb +14 -14
- data/lib/jekyll/path_manager.rb +74 -74
- data/lib/jekyll/plugin.rb +92 -92
- data/lib/jekyll/plugin_manager.rb +115 -115
- data/lib/jekyll/profiler.rb +58 -58
- data/lib/jekyll/publisher.rb +23 -23
- data/lib/jekyll/reader.rb +192 -192
- data/lib/jekyll/readers/collection_reader.rb +23 -23
- data/lib/jekyll/readers/data_reader.rb +79 -79
- data/lib/jekyll/readers/layout_reader.rb +62 -62
- data/lib/jekyll/readers/page_reader.rb +25 -25
- data/lib/jekyll/readers/post_reader.rb +85 -85
- data/lib/jekyll/readers/static_file_reader.rb +25 -25
- data/lib/jekyll/readers/theme_assets_reader.rb +52 -52
- data/lib/jekyll/regenerator.rb +195 -195
- data/lib/jekyll/related_posts.rb +52 -52
- data/lib/jekyll/renderer.rb +265 -265
- data/lib/jekyll/site.rb +551 -551
- data/lib/jekyll/static_file.rb +208 -208
- data/lib/jekyll/stevenson.rb +60 -60
- data/lib/jekyll/tags/highlight.rb +110 -110
- data/lib/jekyll/tags/include.rb +275 -275
- data/lib/jekyll/tags/link.rb +42 -42
- data/lib/jekyll/tags/post_url.rb +106 -106
- data/lib/jekyll/theme.rb +86 -86
- data/lib/jekyll/theme_builder.rb +121 -121
- data/lib/jekyll/url.rb +167 -167
- data/lib/jekyll/utils/ansi.rb +57 -57
- data/lib/jekyll/utils/exec.rb +26 -26
- data/lib/jekyll/utils/internet.rb +37 -37
- data/lib/jekyll/utils/platforms.rb +67 -67
- data/lib/jekyll/utils/thread_event.rb +31 -31
- data/lib/jekyll/utils/win_tz.rb +75 -75
- data/lib/jekyll/utils.rb +367 -367
- data/lib/jekyll/version.rb +5 -5
- data/lib/jekyll.rb +195 -195
- data/lib/site_template/.gitignore +5 -5
- data/lib/site_template/404.html +25 -25
- data/lib/site_template/_config.yml +55 -55
- data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +29 -29
- data/lib/site_template/about.markdown +18 -18
- data/lib/site_template/index.markdown +6 -6
- data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -74
- data/lib/theme_template/Gemfile +4 -4
- data/lib/theme_template/LICENSE.txt.erb +21 -21
- data/lib/theme_template/README.md.erb +52 -52
- data/lib/theme_template/_layouts/default.html +1 -1
- data/lib/theme_template/_layouts/page.html +5 -5
- data/lib/theme_template/_layouts/post.html +5 -5
- data/lib/theme_template/example/_config.yml.erb +1 -1
- data/lib/theme_template/example/_post.md +12 -12
- data/lib/theme_template/example/index.html +14 -14
- data/lib/theme_template/example/style.scss +7 -7
- data/lib/theme_template/gitignore.erb +6 -6
- data/lib/theme_template/theme.gemspec.erb +16 -16
- data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -149
- data/rubocop/jekyll/no_p_allowed.rb +23 -23
- data/rubocop/jekyll/no_puts_allowed.rb +23 -23
- data/rubocop/jekyll.rb +5 -5
- metadata +3 -3
data/lib/jekyll/excerpt.rb
CHANGED
|
@@ -1,201 +1,201 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Jekyll
|
|
4
|
-
class Excerpt
|
|
5
|
-
extend Forwardable
|
|
6
|
-
|
|
7
|
-
attr_accessor :doc
|
|
8
|
-
attr_accessor :content, :ext
|
|
9
|
-
attr_writer :output
|
|
10
|
-
|
|
11
|
-
def_delegators :@doc,
|
|
12
|
-
:site, :name, :ext, :extname,
|
|
13
|
-
:collection, :related_posts, :type,
|
|
14
|
-
:coffeescript_file?, :yaml_file?,
|
|
15
|
-
:url, :next_doc, :previous_doc
|
|
16
|
-
|
|
17
|
-
private :coffeescript_file?, :yaml_file?
|
|
18
|
-
|
|
19
|
-
# Initialize this Excerpt instance.
|
|
20
|
-
#
|
|
21
|
-
# doc - The Document.
|
|
22
|
-
#
|
|
23
|
-
# Returns the new Excerpt.
|
|
24
|
-
def initialize(doc)
|
|
25
|
-
self.doc = doc
|
|
26
|
-
self.content = extract_excerpt(doc.content)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Fetch YAML front-matter data from related doc, without layout key
|
|
30
|
-
#
|
|
31
|
-
# Returns Hash of doc data
|
|
32
|
-
def data
|
|
33
|
-
@data ||= doc.data.dup
|
|
34
|
-
@data.delete("layout")
|
|
35
|
-
@data.delete("excerpt")
|
|
36
|
-
@data
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def trigger_hooks(*); end
|
|
40
|
-
|
|
41
|
-
# 'Path' of the excerpt.
|
|
42
|
-
#
|
|
43
|
-
# Returns the path for the doc this excerpt belongs to with #excerpt appended
|
|
44
|
-
def path
|
|
45
|
-
File.join(doc.path, "#excerpt")
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# 'Relative Path' of the excerpt.
|
|
49
|
-
#
|
|
50
|
-
# Returns the relative_path for the doc this excerpt belongs to with #excerpt appended
|
|
51
|
-
def relative_path
|
|
52
|
-
@relative_path ||= File.join(doc.relative_path, "#excerpt")
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Check if excerpt includes a string
|
|
56
|
-
#
|
|
57
|
-
# Returns true if the string passed in
|
|
58
|
-
def include?(something)
|
|
59
|
-
output&.include?(something) || content.include?(something)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# The UID for this doc (useful in feeds).
|
|
63
|
-
# e.g. /2008/11/05/my-awesome-doc
|
|
64
|
-
#
|
|
65
|
-
# Returns the String UID.
|
|
66
|
-
def id
|
|
67
|
-
"#{doc.id}#excerpt"
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def to_s
|
|
71
|
-
output || content
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def to_liquid
|
|
75
|
-
Jekyll::Drops::ExcerptDrop.new(self)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Returns the shorthand String identifier of this doc.
|
|
79
|
-
def inspect
|
|
80
|
-
"<#{self.class} id=#{id}>"
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def output
|
|
84
|
-
@output ||= Renderer.new(doc.site, self, site.site_payload).run
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def place_in_layout?
|
|
88
|
-
false
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def render_with_liquid?
|
|
92
|
-
return false if data["render_with_liquid"] == false
|
|
93
|
-
|
|
94
|
-
!(coffeescript_file? || yaml_file? || !Utils.has_liquid_construct?(content))
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
protected
|
|
98
|
-
|
|
99
|
-
# Internal: Extract excerpt from the content
|
|
100
|
-
#
|
|
101
|
-
# By default excerpt is your first paragraph of a doc: everything before
|
|
102
|
-
# the first two new lines:
|
|
103
|
-
#
|
|
104
|
-
# ---
|
|
105
|
-
# title: Example
|
|
106
|
-
# ---
|
|
107
|
-
#
|
|
108
|
-
# First paragraph with [link][1].
|
|
109
|
-
#
|
|
110
|
-
# Second paragraph.
|
|
111
|
-
#
|
|
112
|
-
# [1]: http://example.com/
|
|
113
|
-
#
|
|
114
|
-
# This is fairly good option for Markdown and Textile files. But might cause
|
|
115
|
-
# problems for HTML docs (which is quite unusual for Jekyll). If default
|
|
116
|
-
# excerpt delimiter is not good for you, you might want to set your own via
|
|
117
|
-
# configuration option `excerpt_separator`. For example, following is a good
|
|
118
|
-
# alternative for HTML docs:
|
|
119
|
-
#
|
|
120
|
-
# # file: _config.yml
|
|
121
|
-
# excerpt_separator: "<!-- more -->"
|
|
122
|
-
#
|
|
123
|
-
# Notice that all markdown-style link references will be appended to the
|
|
124
|
-
# excerpt. So the example doc above will have this excerpt source:
|
|
125
|
-
#
|
|
126
|
-
# First paragraph with [link][1].
|
|
127
|
-
#
|
|
128
|
-
# [1]: http://example.com/
|
|
129
|
-
#
|
|
130
|
-
# Excerpts are rendered same time as content is rendered.
|
|
131
|
-
#
|
|
132
|
-
# Returns excerpt String
|
|
133
|
-
|
|
134
|
-
LIQUID_TAG_REGEX = %r!{%-?\s*(\w+)\s*.*?-?%}!m.freeze
|
|
135
|
-
MKDWN_LINK_REF_REGEX = %r!^ {0,3}(?:(\[[^\]]+\])(:.+))$!.freeze
|
|
136
|
-
|
|
137
|
-
def extract_excerpt(doc_content)
|
|
138
|
-
head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
|
|
139
|
-
return head if tail.empty?
|
|
140
|
-
|
|
141
|
-
head = sanctify_liquid_tags(head) if head.include?("{%")
|
|
142
|
-
definitions = extract_markdown_link_reference_defintions(head, tail)
|
|
143
|
-
return head if definitions.empty?
|
|
144
|
-
|
|
145
|
-
head << "\n\n" << definitions.join("\n")
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
private
|
|
149
|
-
|
|
150
|
-
# append appropriate closing tag(s) (for each Liquid block), to the `head` if the
|
|
151
|
-
# partitioning resulted in leaving the closing tag somewhere in the `tail` partition.
|
|
152
|
-
def sanctify_liquid_tags(head)
|
|
153
|
-
modified = false
|
|
154
|
-
tag_names = head.scan(LIQUID_TAG_REGEX)
|
|
155
|
-
tag_names.flatten!
|
|
156
|
-
tag_names.reverse_each do |tag_name|
|
|
157
|
-
next unless liquid_block?(tag_name)
|
|
158
|
-
next if endtag_regex_stash(tag_name).match?(head)
|
|
159
|
-
|
|
160
|
-
modified = true
|
|
161
|
-
head << "\n{% end#{tag_name} %}"
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
print_build_warning if modified
|
|
165
|
-
head
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def extract_markdown_link_reference_defintions(head, tail)
|
|
169
|
-
[].tap do |definitions|
|
|
170
|
-
tail.scan(MKDWN_LINK_REF_REGEX).each do |segments|
|
|
171
|
-
definitions << segments.join if head.include?(segments[0])
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def endtag_regex_stash(tag_name)
|
|
177
|
-
@endtag_regex_stash ||= {}
|
|
178
|
-
@endtag_regex_stash[tag_name] ||= %r!{%-?\s*end#{tag_name}.*?\s*-?%}!m
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def liquid_block?(tag_name)
|
|
182
|
-
return false unless tag_name.is_a?(String)
|
|
183
|
-
return false unless Liquid::Template.tags[tag_name]
|
|
184
|
-
|
|
185
|
-
Liquid::Template.tags[tag_name].ancestors.include?(Liquid::Block)
|
|
186
|
-
rescue NoMethodError
|
|
187
|
-
Jekyll.logger.error "Error:",
|
|
188
|
-
"A Liquid tag in the excerpt of #{doc.relative_path} couldn't be parsed."
|
|
189
|
-
raise
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def print_build_warning
|
|
193
|
-
Jekyll.logger.warn "Warning:", "Excerpt modified in #{doc.relative_path}!"
|
|
194
|
-
Jekyll.logger.warn "", "Found a Liquid block containing the excerpt separator" \
|
|
195
|
-
" #{doc.excerpt_separator.inspect}. "
|
|
196
|
-
Jekyll.logger.warn "", "The block has been modified with the appropriate closing tag."
|
|
197
|
-
Jekyll.logger.warn "", "Feel free to define a custom excerpt or excerpt_separator in the"
|
|
198
|
-
Jekyll.logger.warn "", "document's Front Matter if the generated excerpt is unsatisfactory."
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class Excerpt
|
|
5
|
+
extend Forwardable
|
|
6
|
+
|
|
7
|
+
attr_accessor :doc
|
|
8
|
+
attr_accessor :content, :ext
|
|
9
|
+
attr_writer :output
|
|
10
|
+
|
|
11
|
+
def_delegators :@doc,
|
|
12
|
+
:site, :name, :ext, :extname,
|
|
13
|
+
:collection, :related_posts, :type,
|
|
14
|
+
:coffeescript_file?, :yaml_file?,
|
|
15
|
+
:url, :next_doc, :previous_doc
|
|
16
|
+
|
|
17
|
+
private :coffeescript_file?, :yaml_file?
|
|
18
|
+
|
|
19
|
+
# Initialize this Excerpt instance.
|
|
20
|
+
#
|
|
21
|
+
# doc - The Document.
|
|
22
|
+
#
|
|
23
|
+
# Returns the new Excerpt.
|
|
24
|
+
def initialize(doc)
|
|
25
|
+
self.doc = doc
|
|
26
|
+
self.content = extract_excerpt(doc.content)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Fetch YAML front-matter data from related doc, without layout key
|
|
30
|
+
#
|
|
31
|
+
# Returns Hash of doc data
|
|
32
|
+
def data
|
|
33
|
+
@data ||= doc.data.dup
|
|
34
|
+
@data.delete("layout")
|
|
35
|
+
@data.delete("excerpt")
|
|
36
|
+
@data
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def trigger_hooks(*); end
|
|
40
|
+
|
|
41
|
+
# 'Path' of the excerpt.
|
|
42
|
+
#
|
|
43
|
+
# Returns the path for the doc this excerpt belongs to with #excerpt appended
|
|
44
|
+
def path
|
|
45
|
+
File.join(doc.path, "#excerpt")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# 'Relative Path' of the excerpt.
|
|
49
|
+
#
|
|
50
|
+
# Returns the relative_path for the doc this excerpt belongs to with #excerpt appended
|
|
51
|
+
def relative_path
|
|
52
|
+
@relative_path ||= File.join(doc.relative_path, "#excerpt")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Check if excerpt includes a string
|
|
56
|
+
#
|
|
57
|
+
# Returns true if the string passed in
|
|
58
|
+
def include?(something)
|
|
59
|
+
output&.include?(something) || content.include?(something)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# The UID for this doc (useful in feeds).
|
|
63
|
+
# e.g. /2008/11/05/my-awesome-doc
|
|
64
|
+
#
|
|
65
|
+
# Returns the String UID.
|
|
66
|
+
def id
|
|
67
|
+
"#{doc.id}#excerpt"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def to_s
|
|
71
|
+
output || content
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def to_liquid
|
|
75
|
+
Jekyll::Drops::ExcerptDrop.new(self)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns the shorthand String identifier of this doc.
|
|
79
|
+
def inspect
|
|
80
|
+
"<#{self.class} id=#{id}>"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def output
|
|
84
|
+
@output ||= Renderer.new(doc.site, self, site.site_payload).run
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def place_in_layout?
|
|
88
|
+
false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def render_with_liquid?
|
|
92
|
+
return false if data["render_with_liquid"] == false
|
|
93
|
+
|
|
94
|
+
!(coffeescript_file? || yaml_file? || !Utils.has_liquid_construct?(content))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
protected
|
|
98
|
+
|
|
99
|
+
# Internal: Extract excerpt from the content
|
|
100
|
+
#
|
|
101
|
+
# By default excerpt is your first paragraph of a doc: everything before
|
|
102
|
+
# the first two new lines:
|
|
103
|
+
#
|
|
104
|
+
# ---
|
|
105
|
+
# title: Example
|
|
106
|
+
# ---
|
|
107
|
+
#
|
|
108
|
+
# First paragraph with [link][1].
|
|
109
|
+
#
|
|
110
|
+
# Second paragraph.
|
|
111
|
+
#
|
|
112
|
+
# [1]: http://example.com/
|
|
113
|
+
#
|
|
114
|
+
# This is fairly good option for Markdown and Textile files. But might cause
|
|
115
|
+
# problems for HTML docs (which is quite unusual for Jekyll). If default
|
|
116
|
+
# excerpt delimiter is not good for you, you might want to set your own via
|
|
117
|
+
# configuration option `excerpt_separator`. For example, following is a good
|
|
118
|
+
# alternative for HTML docs:
|
|
119
|
+
#
|
|
120
|
+
# # file: _config.yml
|
|
121
|
+
# excerpt_separator: "<!-- more -->"
|
|
122
|
+
#
|
|
123
|
+
# Notice that all markdown-style link references will be appended to the
|
|
124
|
+
# excerpt. So the example doc above will have this excerpt source:
|
|
125
|
+
#
|
|
126
|
+
# First paragraph with [link][1].
|
|
127
|
+
#
|
|
128
|
+
# [1]: http://example.com/
|
|
129
|
+
#
|
|
130
|
+
# Excerpts are rendered same time as content is rendered.
|
|
131
|
+
#
|
|
132
|
+
# Returns excerpt String
|
|
133
|
+
|
|
134
|
+
LIQUID_TAG_REGEX = %r!{%-?\s*(\w+)\s*.*?-?%}!m.freeze
|
|
135
|
+
MKDWN_LINK_REF_REGEX = %r!^ {0,3}(?:(\[[^\]]+\])(:.+))$!.freeze
|
|
136
|
+
|
|
137
|
+
def extract_excerpt(doc_content)
|
|
138
|
+
head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
|
|
139
|
+
return head if tail.empty?
|
|
140
|
+
|
|
141
|
+
head = sanctify_liquid_tags(head) if head.include?("{%")
|
|
142
|
+
definitions = extract_markdown_link_reference_defintions(head, tail)
|
|
143
|
+
return head if definitions.empty?
|
|
144
|
+
|
|
145
|
+
head << "\n\n" << definitions.join("\n")
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
private
|
|
149
|
+
|
|
150
|
+
# append appropriate closing tag(s) (for each Liquid block), to the `head` if the
|
|
151
|
+
# partitioning resulted in leaving the closing tag somewhere in the `tail` partition.
|
|
152
|
+
def sanctify_liquid_tags(head)
|
|
153
|
+
modified = false
|
|
154
|
+
tag_names = head.scan(LIQUID_TAG_REGEX)
|
|
155
|
+
tag_names.flatten!
|
|
156
|
+
tag_names.reverse_each do |tag_name|
|
|
157
|
+
next unless liquid_block?(tag_name)
|
|
158
|
+
next if endtag_regex_stash(tag_name).match?(head)
|
|
159
|
+
|
|
160
|
+
modified = true
|
|
161
|
+
head << "\n{% end#{tag_name} %}"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
print_build_warning if modified
|
|
165
|
+
head
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def extract_markdown_link_reference_defintions(head, tail)
|
|
169
|
+
[].tap do |definitions|
|
|
170
|
+
tail.scan(MKDWN_LINK_REF_REGEX).each do |segments|
|
|
171
|
+
definitions << segments.join if head.include?(segments[0])
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def endtag_regex_stash(tag_name)
|
|
177
|
+
@endtag_regex_stash ||= {}
|
|
178
|
+
@endtag_regex_stash[tag_name] ||= %r!{%-?\s*end#{tag_name}.*?\s*-?%}!m
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def liquid_block?(tag_name)
|
|
182
|
+
return false unless tag_name.is_a?(String)
|
|
183
|
+
return false unless Liquid::Template.tags[tag_name]
|
|
184
|
+
|
|
185
|
+
Liquid::Template.tags[tag_name].ancestors.include?(Liquid::Block)
|
|
186
|
+
rescue NoMethodError
|
|
187
|
+
Jekyll.logger.error "Error:",
|
|
188
|
+
"A Liquid tag in the excerpt of #{doc.relative_path} couldn't be parsed."
|
|
189
|
+
raise
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def print_build_warning
|
|
193
|
+
Jekyll.logger.warn "Warning:", "Excerpt modified in #{doc.relative_path}!"
|
|
194
|
+
Jekyll.logger.warn "", "Found a Liquid block containing the excerpt separator" \
|
|
195
|
+
" #{doc.excerpt_separator.inspect}. "
|
|
196
|
+
Jekyll.logger.warn "", "The block has been modified with the appropriate closing tag."
|
|
197
|
+
Jekyll.logger.warn "", "Feel free to define a custom excerpt or excerpt_separator in the"
|
|
198
|
+
Jekyll.logger.warn "", "document's Front Matter if the generated excerpt is unsatisfactory."
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
data/lib/jekyll/external.rb
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Jekyll
|
|
4
|
-
module External
|
|
5
|
-
class << self
|
|
6
|
-
#
|
|
7
|
-
# Gems that, if installed, should be loaded.
|
|
8
|
-
# Usually contain subcommands.
|
|
9
|
-
#
|
|
10
|
-
def blessed_gems
|
|
11
|
-
%w(
|
|
12
|
-
jekyll-compose
|
|
13
|
-
jekyll-docs
|
|
14
|
-
jekyll-import
|
|
15
|
-
)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
#
|
|
19
|
-
# Require a gem or file if it's present, otherwise silently fail.
|
|
20
|
-
#
|
|
21
|
-
# names - a string gem name or array of gem names
|
|
22
|
-
#
|
|
23
|
-
def require_if_present(names)
|
|
24
|
-
Array(names).each do |name|
|
|
25
|
-
begin
|
|
26
|
-
require name
|
|
27
|
-
rescue LoadError
|
|
28
|
-
Jekyll.logger.debug "Couldn't load #{name}. Skipping."
|
|
29
|
-
yield(name, version_constraint(name)) if block_given?
|
|
30
|
-
false
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
#
|
|
36
|
-
# The version constraint required to activate a given gem.
|
|
37
|
-
# Usually the gem version requirement is "> 0," because any version
|
|
38
|
-
# will do. In the case of jekyll-docs, however, we require the exact
|
|
39
|
-
# same version as Jekyll.
|
|
40
|
-
#
|
|
41
|
-
# Returns a String version constraint in a parseable form for
|
|
42
|
-
# RubyGems.
|
|
43
|
-
def version_constraint(gem_name)
|
|
44
|
-
return "= #{Jekyll::VERSION}" if gem_name.to_s.eql?("jekyll-docs")
|
|
45
|
-
|
|
46
|
-
"> 0"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
#
|
|
50
|
-
# Require a gem or gems. If it's not present, show a very nice error
|
|
51
|
-
# message that explains everything and is much more helpful than the
|
|
52
|
-
# normal LoadError.
|
|
53
|
-
#
|
|
54
|
-
# names - a string gem name or array of gem names
|
|
55
|
-
#
|
|
56
|
-
def require_with_graceful_fail(names)
|
|
57
|
-
Array(names).each do |name|
|
|
58
|
-
begin
|
|
59
|
-
Jekyll.logger.debug "Requiring:", name.to_s
|
|
60
|
-
require name
|
|
61
|
-
rescue LoadError => e
|
|
62
|
-
Jekyll.logger.error "Dependency Error:", <<~MSG
|
|
63
|
-
Yikes! It looks like you don't have #{name} or one of its dependencies installed.
|
|
64
|
-
In order to use Jekyll as currently configured, you'll need to install this gem.
|
|
65
|
-
|
|
66
|
-
If you've run Jekyll with `bundle exec`, ensure that you have included the #{name}
|
|
67
|
-
gem in your Gemfile as well.
|
|
68
|
-
|
|
69
|
-
The full error message from Ruby is: '#{e.message}'
|
|
70
|
-
|
|
71
|
-
If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/!
|
|
72
|
-
MSG
|
|
73
|
-
raise Jekyll::Errors::MissingDependencyException, name
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module External
|
|
5
|
+
class << self
|
|
6
|
+
#
|
|
7
|
+
# Gems that, if installed, should be loaded.
|
|
8
|
+
# Usually contain subcommands.
|
|
9
|
+
#
|
|
10
|
+
def blessed_gems
|
|
11
|
+
%w(
|
|
12
|
+
jekyll-compose
|
|
13
|
+
jekyll-docs
|
|
14
|
+
jekyll-import
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Require a gem or file if it's present, otherwise silently fail.
|
|
20
|
+
#
|
|
21
|
+
# names - a string gem name or array of gem names
|
|
22
|
+
#
|
|
23
|
+
def require_if_present(names)
|
|
24
|
+
Array(names).each do |name|
|
|
25
|
+
begin
|
|
26
|
+
require name
|
|
27
|
+
rescue LoadError
|
|
28
|
+
Jekyll.logger.debug "Couldn't load #{name}. Skipping."
|
|
29
|
+
yield(name, version_constraint(name)) if block_given?
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# The version constraint required to activate a given gem.
|
|
37
|
+
# Usually the gem version requirement is "> 0," because any version
|
|
38
|
+
# will do. In the case of jekyll-docs, however, we require the exact
|
|
39
|
+
# same version as Jekyll.
|
|
40
|
+
#
|
|
41
|
+
# Returns a String version constraint in a parseable form for
|
|
42
|
+
# RubyGems.
|
|
43
|
+
def version_constraint(gem_name)
|
|
44
|
+
return "= #{Jekyll::VERSION}" if gem_name.to_s.eql?("jekyll-docs")
|
|
45
|
+
|
|
46
|
+
"> 0"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#
|
|
50
|
+
# Require a gem or gems. If it's not present, show a very nice error
|
|
51
|
+
# message that explains everything and is much more helpful than the
|
|
52
|
+
# normal LoadError.
|
|
53
|
+
#
|
|
54
|
+
# names - a string gem name or array of gem names
|
|
55
|
+
#
|
|
56
|
+
def require_with_graceful_fail(names)
|
|
57
|
+
Array(names).each do |name|
|
|
58
|
+
begin
|
|
59
|
+
Jekyll.logger.debug "Requiring:", name.to_s
|
|
60
|
+
require name
|
|
61
|
+
rescue LoadError => e
|
|
62
|
+
Jekyll.logger.error "Dependency Error:", <<~MSG
|
|
63
|
+
Yikes! It looks like you don't have #{name} or one of its dependencies installed.
|
|
64
|
+
In order to use Jekyll as currently configured, you'll need to install this gem.
|
|
65
|
+
|
|
66
|
+
If you've run Jekyll with `bundle exec`, ensure that you have included the #{name}
|
|
67
|
+
gem in your Gemfile as well.
|
|
68
|
+
|
|
69
|
+
The full error message from Ruby is: '#{e.message}'
|
|
70
|
+
|
|
71
|
+
If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/!
|
|
72
|
+
MSG
|
|
73
|
+
raise Jekyll::Errors::MissingDependencyException, name
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|