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/url.rb
CHANGED
|
@@ -1,167 +1,167 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
|
4
|
-
#
|
|
5
|
-
# Examples
|
|
6
|
-
#
|
|
7
|
-
# URL.new({
|
|
8
|
-
# :template => /:categories/:title.html",
|
|
9
|
-
# :placeholders => {:categories => "ruby", :title => "something"}
|
|
10
|
-
# }).to_s
|
|
11
|
-
#
|
|
12
|
-
module Jekyll
|
|
13
|
-
class URL
|
|
14
|
-
# options - One of :permalink or :template must be supplied.
|
|
15
|
-
# :template - The String used as template for URL generation,
|
|
16
|
-
# for example "/:path/:basename:output_ext", where
|
|
17
|
-
# a placeholder is prefixed with a colon.
|
|
18
|
-
# :placeholders - A hash containing the placeholders which will be
|
|
19
|
-
# replaced when used inside the template. E.g.
|
|
20
|
-
# { "year" => Time.now.strftime("%Y") } would replace
|
|
21
|
-
# the placeholder ":year" with the current year.
|
|
22
|
-
# :permalink - If supplied, no URL will be generated from the
|
|
23
|
-
# template. Instead, the given permalink will be
|
|
24
|
-
# used as URL.
|
|
25
|
-
def initialize(options)
|
|
26
|
-
@template = options[:template]
|
|
27
|
-
@placeholders = options[:placeholders] || {}
|
|
28
|
-
@permalink = options[:permalink]
|
|
29
|
-
|
|
30
|
-
if (@template || @permalink).nil?
|
|
31
|
-
raise ArgumentError, "One of :template or :permalink must be supplied."
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# The generated relative URL of the resource
|
|
36
|
-
#
|
|
37
|
-
# Returns the String URL
|
|
38
|
-
def to_s
|
|
39
|
-
sanitize_url(generated_permalink || generated_url)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Generates a URL from the permalink
|
|
43
|
-
#
|
|
44
|
-
# Returns the _unsanitized String URL
|
|
45
|
-
def generated_permalink
|
|
46
|
-
(@generated_permalink ||= generate_url(@permalink)) if @permalink
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Generates a URL from the template
|
|
50
|
-
#
|
|
51
|
-
# Returns the unsanitized String URL
|
|
52
|
-
def generated_url
|
|
53
|
-
@generated_url ||= generate_url(@template)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Internal: Generate the URL by replacing all placeholders with their
|
|
57
|
-
# respective values in the given template
|
|
58
|
-
#
|
|
59
|
-
# Returns the unsanitized String URL
|
|
60
|
-
def generate_url(template)
|
|
61
|
-
if @placeholders.is_a? Drops::UrlDrop
|
|
62
|
-
generate_url_from_drop(template)
|
|
63
|
-
else
|
|
64
|
-
generate_url_from_hash(template)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def generate_url_from_hash(template)
|
|
69
|
-
@placeholders.inject(template) do |result, token|
|
|
70
|
-
break result if result.index(":").nil?
|
|
71
|
-
|
|
72
|
-
if token.last.nil?
|
|
73
|
-
# Remove leading "/" to avoid generating urls with `//`
|
|
74
|
-
result.gsub("/:#{token.first}", "")
|
|
75
|
-
else
|
|
76
|
-
result.gsub(":#{token.first}", self.class.escape_path(token.last))
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# We include underscores in keys to allow for 'i_month' and so forth.
|
|
82
|
-
# This poses a problem for keys which are followed by an underscore
|
|
83
|
-
# but the underscore is not part of the key, e.g. '/:month_:day'.
|
|
84
|
-
# That should be :month and :day, but our key extraction regexp isn't
|
|
85
|
-
# smart enough to know that so we have to make it an explicit
|
|
86
|
-
# possibility.
|
|
87
|
-
def possible_keys(key)
|
|
88
|
-
if key.end_with?("_")
|
|
89
|
-
[key, key.chomp("_")]
|
|
90
|
-
else
|
|
91
|
-
[key]
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def generate_url_from_drop(template)
|
|
96
|
-
template.gsub(%r!:([a-z_]+)!) do |match|
|
|
97
|
-
name = Regexp.last_match(1)
|
|
98
|
-
pool = name.end_with?("_") ? [name, name.chomp!("_")] : [name]
|
|
99
|
-
|
|
100
|
-
winner = pool.find { |key| @placeholders.key?(key) }
|
|
101
|
-
if winner.nil?
|
|
102
|
-
raise NoMethodError,
|
|
103
|
-
"The URL template doesn't have #{pool.join(" or ")} keys. "\
|
|
104
|
-
"Check your permalink template!"
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
value = @placeholders[winner]
|
|
108
|
-
value = "" if value.nil?
|
|
109
|
-
replacement = self.class.escape_path(value)
|
|
110
|
-
|
|
111
|
-
match.sub!(":#{winner}", replacement)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# Returns a sanitized String URL, stripping "../../" and multiples of "/",
|
|
116
|
-
# as well as the beginning "/" so we can enforce and ensure it.
|
|
117
|
-
def sanitize_url(str)
|
|
118
|
-
"/#{str}".gsub("..", "/").tap do |result|
|
|
119
|
-
result.gsub!("./", "")
|
|
120
|
-
result.squeeze!("/")
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Escapes a path to be a valid URL path segment
|
|
125
|
-
#
|
|
126
|
-
# path - The path to be escaped.
|
|
127
|
-
#
|
|
128
|
-
# Examples:
|
|
129
|
-
#
|
|
130
|
-
# URL.escape_path("/a b")
|
|
131
|
-
# # => "/a%20b"
|
|
132
|
-
#
|
|
133
|
-
# Returns the escaped path.
|
|
134
|
-
def self.escape_path(path)
|
|
135
|
-
return path if path.empty? || %r!^[a-zA-Z0-9./-]+$!.match?(path)
|
|
136
|
-
|
|
137
|
-
# Because URI.escape doesn't escape "?", "[" and "]" by default,
|
|
138
|
-
# specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
|
|
139
|
-
#
|
|
140
|
-
# URI path segment is defined in RFC 3986 as follows:
|
|
141
|
-
# segment = *pchar
|
|
142
|
-
# pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
143
|
-
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
144
|
-
# pct-encoded = "%" HEXDIG HEXDIG
|
|
145
|
-
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
|
146
|
-
# / "*" / "+" / "," / ";" / "="
|
|
147
|
-
Addressable::URI.encode(path).encode("utf-8").sub("#", "%23")
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
# Unescapes a URL path segment
|
|
151
|
-
#
|
|
152
|
-
# path - The path to be unescaped.
|
|
153
|
-
#
|
|
154
|
-
# Examples:
|
|
155
|
-
#
|
|
156
|
-
# URL.unescape_path("/a%20b")
|
|
157
|
-
# # => "/a b"
|
|
158
|
-
#
|
|
159
|
-
# Returns the unescaped path.
|
|
160
|
-
def self.unescape_path(path)
|
|
161
|
-
path = path.encode("utf-8")
|
|
162
|
-
return path unless path.include?("%")
|
|
163
|
-
|
|
164
|
-
Addressable::URI.unencode(path)
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
|
4
|
+
#
|
|
5
|
+
# Examples
|
|
6
|
+
#
|
|
7
|
+
# URL.new({
|
|
8
|
+
# :template => /:categories/:title.html",
|
|
9
|
+
# :placeholders => {:categories => "ruby", :title => "something"}
|
|
10
|
+
# }).to_s
|
|
11
|
+
#
|
|
12
|
+
module Jekyll
|
|
13
|
+
class URL
|
|
14
|
+
# options - One of :permalink or :template must be supplied.
|
|
15
|
+
# :template - The String used as template for URL generation,
|
|
16
|
+
# for example "/:path/:basename:output_ext", where
|
|
17
|
+
# a placeholder is prefixed with a colon.
|
|
18
|
+
# :placeholders - A hash containing the placeholders which will be
|
|
19
|
+
# replaced when used inside the template. E.g.
|
|
20
|
+
# { "year" => Time.now.strftime("%Y") } would replace
|
|
21
|
+
# the placeholder ":year" with the current year.
|
|
22
|
+
# :permalink - If supplied, no URL will be generated from the
|
|
23
|
+
# template. Instead, the given permalink will be
|
|
24
|
+
# used as URL.
|
|
25
|
+
def initialize(options)
|
|
26
|
+
@template = options[:template]
|
|
27
|
+
@placeholders = options[:placeholders] || {}
|
|
28
|
+
@permalink = options[:permalink]
|
|
29
|
+
|
|
30
|
+
if (@template || @permalink).nil?
|
|
31
|
+
raise ArgumentError, "One of :template or :permalink must be supplied."
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# The generated relative URL of the resource
|
|
36
|
+
#
|
|
37
|
+
# Returns the String URL
|
|
38
|
+
def to_s
|
|
39
|
+
sanitize_url(generated_permalink || generated_url)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Generates a URL from the permalink
|
|
43
|
+
#
|
|
44
|
+
# Returns the _unsanitized String URL
|
|
45
|
+
def generated_permalink
|
|
46
|
+
(@generated_permalink ||= generate_url(@permalink)) if @permalink
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Generates a URL from the template
|
|
50
|
+
#
|
|
51
|
+
# Returns the unsanitized String URL
|
|
52
|
+
def generated_url
|
|
53
|
+
@generated_url ||= generate_url(@template)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Internal: Generate the URL by replacing all placeholders with their
|
|
57
|
+
# respective values in the given template
|
|
58
|
+
#
|
|
59
|
+
# Returns the unsanitized String URL
|
|
60
|
+
def generate_url(template)
|
|
61
|
+
if @placeholders.is_a? Drops::UrlDrop
|
|
62
|
+
generate_url_from_drop(template)
|
|
63
|
+
else
|
|
64
|
+
generate_url_from_hash(template)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def generate_url_from_hash(template)
|
|
69
|
+
@placeholders.inject(template) do |result, token|
|
|
70
|
+
break result if result.index(":").nil?
|
|
71
|
+
|
|
72
|
+
if token.last.nil?
|
|
73
|
+
# Remove leading "/" to avoid generating urls with `//`
|
|
74
|
+
result.gsub("/:#{token.first}", "")
|
|
75
|
+
else
|
|
76
|
+
result.gsub(":#{token.first}", self.class.escape_path(token.last))
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# We include underscores in keys to allow for 'i_month' and so forth.
|
|
82
|
+
# This poses a problem for keys which are followed by an underscore
|
|
83
|
+
# but the underscore is not part of the key, e.g. '/:month_:day'.
|
|
84
|
+
# That should be :month and :day, but our key extraction regexp isn't
|
|
85
|
+
# smart enough to know that so we have to make it an explicit
|
|
86
|
+
# possibility.
|
|
87
|
+
def possible_keys(key)
|
|
88
|
+
if key.end_with?("_")
|
|
89
|
+
[key, key.chomp("_")]
|
|
90
|
+
else
|
|
91
|
+
[key]
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def generate_url_from_drop(template)
|
|
96
|
+
template.gsub(%r!:([a-z_]+)!) do |match|
|
|
97
|
+
name = Regexp.last_match(1)
|
|
98
|
+
pool = name.end_with?("_") ? [name, name.chomp!("_")] : [name]
|
|
99
|
+
|
|
100
|
+
winner = pool.find { |key| @placeholders.key?(key) }
|
|
101
|
+
if winner.nil?
|
|
102
|
+
raise NoMethodError,
|
|
103
|
+
"The URL template doesn't have #{pool.join(" or ")} keys. "\
|
|
104
|
+
"Check your permalink template!"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
value = @placeholders[winner]
|
|
108
|
+
value = "" if value.nil?
|
|
109
|
+
replacement = self.class.escape_path(value)
|
|
110
|
+
|
|
111
|
+
match.sub!(":#{winner}", replacement)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Returns a sanitized String URL, stripping "../../" and multiples of "/",
|
|
116
|
+
# as well as the beginning "/" so we can enforce and ensure it.
|
|
117
|
+
def sanitize_url(str)
|
|
118
|
+
"/#{str}".gsub("..", "/").tap do |result|
|
|
119
|
+
result.gsub!("./", "")
|
|
120
|
+
result.squeeze!("/")
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Escapes a path to be a valid URL path segment
|
|
125
|
+
#
|
|
126
|
+
# path - The path to be escaped.
|
|
127
|
+
#
|
|
128
|
+
# Examples:
|
|
129
|
+
#
|
|
130
|
+
# URL.escape_path("/a b")
|
|
131
|
+
# # => "/a%20b"
|
|
132
|
+
#
|
|
133
|
+
# Returns the escaped path.
|
|
134
|
+
def self.escape_path(path)
|
|
135
|
+
return path if path.empty? || %r!^[a-zA-Z0-9./-]+$!.match?(path)
|
|
136
|
+
|
|
137
|
+
# Because URI.escape doesn't escape "?", "[" and "]" by default,
|
|
138
|
+
# specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
|
|
139
|
+
#
|
|
140
|
+
# URI path segment is defined in RFC 3986 as follows:
|
|
141
|
+
# segment = *pchar
|
|
142
|
+
# pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
143
|
+
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
144
|
+
# pct-encoded = "%" HEXDIG HEXDIG
|
|
145
|
+
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
|
146
|
+
# / "*" / "+" / "," / ";" / "="
|
|
147
|
+
Addressable::URI.encode(path).encode("utf-8").sub("#", "%23")
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Unescapes a URL path segment
|
|
151
|
+
#
|
|
152
|
+
# path - The path to be unescaped.
|
|
153
|
+
#
|
|
154
|
+
# Examples:
|
|
155
|
+
#
|
|
156
|
+
# URL.unescape_path("/a%20b")
|
|
157
|
+
# # => "/a b"
|
|
158
|
+
#
|
|
159
|
+
# Returns the unescaped path.
|
|
160
|
+
def self.unescape_path(path)
|
|
161
|
+
path = path.encode("utf-8")
|
|
162
|
+
return path unless path.include?("%")
|
|
163
|
+
|
|
164
|
+
Addressable::URI.unencode(path)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
data/lib/jekyll/utils/ansi.rb
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
# Frozen-string-literal: true
|
|
2
|
-
|
|
3
|
-
module Jekyll
|
|
4
|
-
module Utils
|
|
5
|
-
module Ansi
|
|
6
|
-
extend self
|
|
7
|
-
|
|
8
|
-
ESCAPE = format("%c", 27)
|
|
9
|
-
MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix.freeze
|
|
10
|
-
COLORS = {
|
|
11
|
-
:red => 31,
|
|
12
|
-
:green => 32,
|
|
13
|
-
:black => 30,
|
|
14
|
-
:magenta => 35,
|
|
15
|
-
:yellow => 33,
|
|
16
|
-
:white => 37,
|
|
17
|
-
:blue => 34,
|
|
18
|
-
:cyan => 36,
|
|
19
|
-
}.freeze
|
|
20
|
-
|
|
21
|
-
# Strip ANSI from the current string. It also strips cursor stuff,
|
|
22
|
-
# well some of it, and it also strips some other stuff that a lot of
|
|
23
|
-
# the other ANSI strippers don't.
|
|
24
|
-
|
|
25
|
-
def strip(str)
|
|
26
|
-
str.gsub MATCH, ""
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
def has?(str)
|
|
32
|
-
!!(str =~ MATCH)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Reset the color back to the default color so that you do not leak any
|
|
36
|
-
# colors when you move onto the next line. This is probably normally
|
|
37
|
-
# used as part of a wrapper so that we don't leak colors.
|
|
38
|
-
|
|
39
|
-
def reset(str = "")
|
|
40
|
-
@ansi_reset ||= format("%c[0m", 27)
|
|
41
|
-
"#{@ansi_reset}#{str}"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# SEE: `self::COLORS` for a list of methods. They are mostly
|
|
45
|
-
# standard base colors supported by pretty much any xterm-color, we do
|
|
46
|
-
# not need more than the base colors so we do not include them.
|
|
47
|
-
# Actually... if I'm honest we don't even need most of the
|
|
48
|
-
# base colors.
|
|
49
|
-
|
|
50
|
-
COLORS.each do |color, num|
|
|
51
|
-
define_method color do |str|
|
|
52
|
-
"#{format("%c", 27)}[#{num}m#{str}#{reset}"
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
1
|
+
# Frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module Utils
|
|
5
|
+
module Ansi
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
ESCAPE = format("%c", 27)
|
|
9
|
+
MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix.freeze
|
|
10
|
+
COLORS = {
|
|
11
|
+
:red => 31,
|
|
12
|
+
:green => 32,
|
|
13
|
+
:black => 30,
|
|
14
|
+
:magenta => 35,
|
|
15
|
+
:yellow => 33,
|
|
16
|
+
:white => 37,
|
|
17
|
+
:blue => 34,
|
|
18
|
+
:cyan => 36,
|
|
19
|
+
}.freeze
|
|
20
|
+
|
|
21
|
+
# Strip ANSI from the current string. It also strips cursor stuff,
|
|
22
|
+
# well some of it, and it also strips some other stuff that a lot of
|
|
23
|
+
# the other ANSI strippers don't.
|
|
24
|
+
|
|
25
|
+
def strip(str)
|
|
26
|
+
str.gsub MATCH, ""
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
|
|
31
|
+
def has?(str)
|
|
32
|
+
!!(str =~ MATCH)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Reset the color back to the default color so that you do not leak any
|
|
36
|
+
# colors when you move onto the next line. This is probably normally
|
|
37
|
+
# used as part of a wrapper so that we don't leak colors.
|
|
38
|
+
|
|
39
|
+
def reset(str = "")
|
|
40
|
+
@ansi_reset ||= format("%c[0m", 27)
|
|
41
|
+
"#{@ansi_reset}#{str}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# SEE: `self::COLORS` for a list of methods. They are mostly
|
|
45
|
+
# standard base colors supported by pretty much any xterm-color, we do
|
|
46
|
+
# not need more than the base colors so we do not include them.
|
|
47
|
+
# Actually... if I'm honest we don't even need most of the
|
|
48
|
+
# base colors.
|
|
49
|
+
|
|
50
|
+
COLORS.each do |color, num|
|
|
51
|
+
define_method color do |str|
|
|
52
|
+
"#{format("%c", 27)}[#{num}m#{str}#{reset}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/jekyll/utils/exec.rb
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "open3"
|
|
4
|
-
|
|
5
|
-
module Jekyll
|
|
6
|
-
module Utils
|
|
7
|
-
module Exec
|
|
8
|
-
extend self
|
|
9
|
-
|
|
10
|
-
# Runs a program in a sub-shell.
|
|
11
|
-
#
|
|
12
|
-
# *args - a list of strings containing the program name and arguments
|
|
13
|
-
#
|
|
14
|
-
# Returns a Process::Status and a String of output in an array in
|
|
15
|
-
# that order.
|
|
16
|
-
def run(*args)
|
|
17
|
-
stdin, stdout, stderr, process = Open3.popen3(*args)
|
|
18
|
-
out = stdout.read.strip
|
|
19
|
-
err = stderr.read.strip
|
|
20
|
-
|
|
21
|
-
[stdin, stdout, stderr].each(&:close)
|
|
22
|
-
[process.value, out + err]
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "open3"
|
|
4
|
+
|
|
5
|
+
module Jekyll
|
|
6
|
+
module Utils
|
|
7
|
+
module Exec
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
# Runs a program in a sub-shell.
|
|
11
|
+
#
|
|
12
|
+
# *args - a list of strings containing the program name and arguments
|
|
13
|
+
#
|
|
14
|
+
# Returns a Process::Status and a String of output in an array in
|
|
15
|
+
# that order.
|
|
16
|
+
def run(*args)
|
|
17
|
+
stdin, stdout, stderr, process = Open3.popen3(*args)
|
|
18
|
+
out = stdout.read.strip
|
|
19
|
+
err = stderr.read.strip
|
|
20
|
+
|
|
21
|
+
[stdin, stdout, stderr].each(&:close)
|
|
22
|
+
[process.value, out + err]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Jekyll
|
|
4
|
-
module Utils
|
|
5
|
-
module Internet
|
|
6
|
-
# Public: Determine whether the present device has a connection to
|
|
7
|
-
# the Internet. This allows plugin writers which require the outside
|
|
8
|
-
# world to have a neat fallback mechanism for offline building.
|
|
9
|
-
#
|
|
10
|
-
# Example:
|
|
11
|
-
# if Internet.connected?
|
|
12
|
-
# Typhoeus.get("https://pages.github.com/versions.json")
|
|
13
|
-
# else
|
|
14
|
-
# Jekyll.logger.warn "Warning:", "Version check has been disabled."
|
|
15
|
-
# Jekyll.logger.warn "", "Connect to the Internet to enable it."
|
|
16
|
-
# nil
|
|
17
|
-
# end
|
|
18
|
-
#
|
|
19
|
-
# Returns true if a DNS call can successfully be made, or false if not.
|
|
20
|
-
|
|
21
|
-
module_function
|
|
22
|
-
|
|
23
|
-
def connected?
|
|
24
|
-
!dns("example.com").nil?
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def dns(domain)
|
|
28
|
-
require "resolv"
|
|
29
|
-
Resolv::DNS.open do |resolver|
|
|
30
|
-
resolver.getaddress(domain)
|
|
31
|
-
end
|
|
32
|
-
rescue Resolv::ResolvError, Resolv::ResolvTimeout
|
|
33
|
-
nil
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module Utils
|
|
5
|
+
module Internet
|
|
6
|
+
# Public: Determine whether the present device has a connection to
|
|
7
|
+
# the Internet. This allows plugin writers which require the outside
|
|
8
|
+
# world to have a neat fallback mechanism for offline building.
|
|
9
|
+
#
|
|
10
|
+
# Example:
|
|
11
|
+
# if Internet.connected?
|
|
12
|
+
# Typhoeus.get("https://pages.github.com/versions.json")
|
|
13
|
+
# else
|
|
14
|
+
# Jekyll.logger.warn "Warning:", "Version check has been disabled."
|
|
15
|
+
# Jekyll.logger.warn "", "Connect to the Internet to enable it."
|
|
16
|
+
# nil
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# Returns true if a DNS call can successfully be made, or false if not.
|
|
20
|
+
|
|
21
|
+
module_function
|
|
22
|
+
|
|
23
|
+
def connected?
|
|
24
|
+
!dns("example.com").nil?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def dns(domain)
|
|
28
|
+
require "resolv"
|
|
29
|
+
Resolv::DNS.open do |resolver|
|
|
30
|
+
resolver.getaddress(domain)
|
|
31
|
+
end
|
|
32
|
+
rescue Resolv::ResolvError, Resolv::ResolvTimeout
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|