ngage 0.0.0

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 (109) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/exe/ngage +55 -0
  4. data/lib/ngage.rb +3 -0
  5. data/lib/ngage/jekyll.rb +204 -0
  6. data/lib/ngage/jekyll/cleaner.rb +111 -0
  7. data/lib/ngage/jekyll/collection.rb +235 -0
  8. data/lib/ngage/jekyll/command.rb +103 -0
  9. data/lib/ngage/jekyll/commands/build.rb +93 -0
  10. data/lib/ngage/jekyll/commands/clean.rb +45 -0
  11. data/lib/ngage/jekyll/commands/doctor.rb +173 -0
  12. data/lib/ngage/jekyll/commands/help.rb +34 -0
  13. data/lib/ngage/jekyll/commands/new.rb +157 -0
  14. data/lib/ngage/jekyll/commands/new_theme.rb +42 -0
  15. data/lib/ngage/jekyll/commands/serve.rb +354 -0
  16. data/lib/ngage/jekyll/commands/serve/live_reload_reactor.rb +122 -0
  17. data/lib/ngage/jekyll/commands/serve/livereload_assets/livereload.js +1183 -0
  18. data/lib/ngage/jekyll/commands/serve/servlet.rb +203 -0
  19. data/lib/ngage/jekyll/commands/serve/websockets.rb +81 -0
  20. data/lib/ngage/jekyll/configuration.rb +391 -0
  21. data/lib/ngage/jekyll/converter.rb +54 -0
  22. data/lib/ngage/jekyll/converters/identity.rb +41 -0
  23. data/lib/ngage/jekyll/converters/markdown.rb +116 -0
  24. data/lib/ngage/jekyll/converters/markdown/kramdown_parser.rb +122 -0
  25. data/lib/ngage/jekyll/converters/smartypants.rb +70 -0
  26. data/lib/ngage/jekyll/convertible.rb +253 -0
  27. data/lib/ngage/jekyll/deprecator.rb +50 -0
  28. data/lib/ngage/jekyll/document.rb +503 -0
  29. data/lib/ngage/jekyll/drops/collection_drop.rb +20 -0
  30. data/lib/ngage/jekyll/drops/document_drop.rb +69 -0
  31. data/lib/ngage/jekyll/drops/drop.rb +209 -0
  32. data/lib/ngage/jekyll/drops/excerpt_drop.rb +15 -0
  33. data/lib/ngage/jekyll/drops/jekyll_drop.rb +32 -0
  34. data/lib/ngage/jekyll/drops/site_drop.rb +56 -0
  35. data/lib/ngage/jekyll/drops/static_file_drop.rb +14 -0
  36. data/lib/ngage/jekyll/drops/unified_payload_drop.rb +26 -0
  37. data/lib/ngage/jekyll/drops/url_drop.rb +89 -0
  38. data/lib/ngage/jekyll/entry_filter.rb +127 -0
  39. data/lib/ngage/jekyll/errors.rb +20 -0
  40. data/lib/ngage/jekyll/excerpt.rb +180 -0
  41. data/lib/ngage/jekyll/external.rb +76 -0
  42. data/lib/ngage/jekyll/filters.rb +390 -0
  43. data/lib/ngage/jekyll/filters/date_filters.rb +110 -0
  44. data/lib/ngage/jekyll/filters/grouping_filters.rb +64 -0
  45. data/lib/ngage/jekyll/filters/url_filters.rb +68 -0
  46. data/lib/ngage/jekyll/frontmatter_defaults.rb +233 -0
  47. data/lib/ngage/jekyll/generator.rb +5 -0
  48. data/lib/ngage/jekyll/hooks.rb +106 -0
  49. data/lib/ngage/jekyll/layout.rb +62 -0
  50. data/lib/ngage/jekyll/liquid_extensions.rb +22 -0
  51. data/lib/ngage/jekyll/liquid_renderer.rb +63 -0
  52. data/lib/ngage/jekyll/liquid_renderer/file.rb +56 -0
  53. data/lib/ngage/jekyll/liquid_renderer/table.rb +98 -0
  54. data/lib/ngage/jekyll/log_adapter.rb +151 -0
  55. data/lib/ngage/jekyll/mime.types +825 -0
  56. data/lib/ngage/jekyll/page.rb +185 -0
  57. data/lib/ngage/jekyll/page_without_a_file.rb +14 -0
  58. data/lib/ngage/jekyll/plugin.rb +92 -0
  59. data/lib/ngage/jekyll/plugin_manager.rb +115 -0
  60. data/lib/ngage/jekyll/publisher.rb +23 -0
  61. data/lib/ngage/jekyll/reader.rb +154 -0
  62. data/lib/ngage/jekyll/readers/collection_reader.rb +22 -0
  63. data/lib/ngage/jekyll/readers/data_reader.rb +75 -0
  64. data/lib/ngage/jekyll/readers/layout_reader.rb +70 -0
  65. data/lib/ngage/jekyll/readers/page_reader.rb +25 -0
  66. data/lib/ngage/jekyll/readers/post_reader.rb +72 -0
  67. data/lib/ngage/jekyll/readers/static_file_reader.rb +25 -0
  68. data/lib/ngage/jekyll/readers/theme_assets_reader.rb +51 -0
  69. data/lib/ngage/jekyll/regenerator.rb +195 -0
  70. data/lib/ngage/jekyll/related_posts.rb +52 -0
  71. data/lib/ngage/jekyll/renderer.rb +266 -0
  72. data/lib/ngage/jekyll/site.rb +476 -0
  73. data/lib/ngage/jekyll/static_file.rb +169 -0
  74. data/lib/ngage/jekyll/stevenson.rb +60 -0
  75. data/lib/ngage/jekyll/tags/highlight.rb +108 -0
  76. data/lib/ngage/jekyll/tags/include.rb +226 -0
  77. data/lib/ngage/jekyll/tags/link.rb +40 -0
  78. data/lib/ngage/jekyll/tags/post_url.rb +104 -0
  79. data/lib/ngage/jekyll/theme.rb +73 -0
  80. data/lib/ngage/jekyll/theme_builder.rb +121 -0
  81. data/lib/ngage/jekyll/url.rb +160 -0
  82. data/lib/ngage/jekyll/utils.rb +370 -0
  83. data/lib/ngage/jekyll/utils/ansi.rb +57 -0
  84. data/lib/ngage/jekyll/utils/exec.rb +26 -0
  85. data/lib/ngage/jekyll/utils/internet.rb +37 -0
  86. data/lib/ngage/jekyll/utils/platforms.rb +82 -0
  87. data/lib/ngage/jekyll/utils/thread_event.rb +31 -0
  88. data/lib/ngage/jekyll/utils/win_tz.rb +75 -0
  89. data/lib/ngage/site_template/.gitignore +5 -0
  90. data/lib/ngage/site_template/404.html +25 -0
  91. data/lib/ngage/site_template/_config.yml +47 -0
  92. data/lib/ngage/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +29 -0
  93. data/lib/ngage/site_template/about.markdown +18 -0
  94. data/lib/ngage/site_template/index.markdown +6 -0
  95. data/lib/ngage/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
  96. data/lib/ngage/theme_template/Gemfile +4 -0
  97. data/lib/ngage/theme_template/LICENSE.txt.erb +21 -0
  98. data/lib/ngage/theme_template/README.md.erb +52 -0
  99. data/lib/ngage/theme_template/_layouts/default.html +1 -0
  100. data/lib/ngage/theme_template/_layouts/page.html +5 -0
  101. data/lib/ngage/theme_template/_layouts/post.html +5 -0
  102. data/lib/ngage/theme_template/example/_config.yml.erb +1 -0
  103. data/lib/ngage/theme_template/example/_post.md +12 -0
  104. data/lib/ngage/theme_template/example/index.html +14 -0
  105. data/lib/ngage/theme_template/example/style.scss +7 -0
  106. data/lib/ngage/theme_template/gitignore.erb +6 -0
  107. data/lib/ngage/theme_template/theme.gemspec.erb +19 -0
  108. data/lib/ngage/version.rb +5 -0
  109. metadata +328 -0
@@ -0,0 +1,203 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "webrick"
4
+
5
+ module Jekyll
6
+ module Commands
7
+ class Serve
8
+ # This class is used to determine if the Servlet should modify a served file
9
+ # to insert the LiveReload script tags
10
+ class SkipAnalyzer
11
+ BAD_USER_AGENTS = [%r!MSIE!].freeze
12
+
13
+ def self.skip_processing?(request, response, options)
14
+ new(request, response, options).skip_processing?
15
+ end
16
+
17
+ def initialize(request, response, options)
18
+ @options = options
19
+ @request = request
20
+ @response = response
21
+ end
22
+
23
+ def skip_processing?
24
+ !html? || chunked? || inline? || bad_browser?
25
+ end
26
+
27
+ def chunked?
28
+ @response["Transfer-Encoding"] == "chunked"
29
+ end
30
+
31
+ def inline?
32
+ @response["Content-Disposition"] =~ %r!^inline!
33
+ end
34
+
35
+ def bad_browser?
36
+ BAD_USER_AGENTS.any? { |pattern| @request["User-Agent"] =~ pattern }
37
+ end
38
+
39
+ def html?
40
+ @response["Content-Type"] =~ %r!text/html!
41
+ end
42
+ end
43
+
44
+ # This class inserts the LiveReload script tags into HTML as it is served
45
+ class BodyProcessor
46
+ HEAD_TAG_REGEX = %r!<head>|<head[^(er)][^<]*>!
47
+
48
+ attr_reader :content_length, :new_body, :livereload_added
49
+
50
+ def initialize(body, options)
51
+ @body = body
52
+ @options = options
53
+ @processed = false
54
+ end
55
+
56
+ def processed?
57
+ @processed
58
+ end
59
+
60
+ # rubocop:disable Metrics/MethodLength
61
+ def process!
62
+ @new_body = []
63
+ # @body will usually be a File object but Strings occur in rare cases
64
+ if @body.respond_to?(:each)
65
+ begin
66
+ @body.each { |line| @new_body << line.to_s }
67
+ ensure
68
+ @body.close
69
+ end
70
+ else
71
+ @new_body = @body.lines
72
+ end
73
+
74
+ @content_length = 0
75
+ @livereload_added = false
76
+
77
+ @new_body.each do |line|
78
+ if !@livereload_added && line["<head"]
79
+ line.gsub!(HEAD_TAG_REGEX) do |match|
80
+ %(#{match}#{template.result(binding)})
81
+ end
82
+
83
+ @livereload_added = true
84
+ end
85
+
86
+ @content_length += line.bytesize
87
+ @processed = true
88
+ end
89
+ @new_body = @new_body.join
90
+ end
91
+ # rubocop:enable Metrics/MethodLength
92
+
93
+ def template
94
+ # Unclear what "snipver" does. Doc at
95
+ # https://github.com/livereload/livereload-js states that the recommended
96
+ # setting is 1.
97
+
98
+ # Complicated JavaScript to ensure that livereload.js is loaded from the
99
+ # same origin as the page. Mostly useful for dealing with the browser's
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>
110
+ TEMPLATE
111
+ ERB.new(Jekyll::Utils.strip_heredoc(template))
112
+ end
113
+
114
+ def livereload_args
115
+ # XHTML standard requires ampersands to be encoded as entities when in
116
+ # attributes. See http://stackoverflow.com/a/2190292
117
+ src = ""
118
+ if @options["livereload_min_delay"]
119
+ src += "&amp;mindelay=#{@options["livereload_min_delay"]}"
120
+ end
121
+ if @options["livereload_max_delay"]
122
+ src += "&amp;maxdelay=#{@options["livereload_max_delay"]}"
123
+ end
124
+ src += "&amp;port=#{@options["livereload_port"]}" if @options["livereload_port"]
125
+ src
126
+ end
127
+ end
128
+
129
+ class Servlet < WEBrick::HTTPServlet::FileHandler
130
+ DEFAULTS = {
131
+ "Cache-Control" => "private, max-age=0, proxy-revalidate, " \
132
+ "no-store, no-cache, must-revalidate",
133
+ }.freeze
134
+
135
+ def initialize(server, root, callbacks)
136
+ # So we can access them easily.
137
+ @jekyll_opts = server.config[:JekyllOptions]
138
+ set_defaults
139
+ super
140
+ end
141
+
142
+ def search_index_file(req, res)
143
+ super ||
144
+ search_file(req, res, ".html") ||
145
+ search_file(req, res, ".xhtml")
146
+ end
147
+
148
+ # Add the ability to tap file.html the same way that Nginx does on our
149
+ # Docker images (or on GitHub Pages.) The difference is that we might end
150
+ # up with a different preference on which comes first.
151
+
152
+ def search_file(req, res, basename)
153
+ # /file.* > /file/index.html > /file.html
154
+ super ||
155
+ super(req, res, "#{basename}.html") ||
156
+ super(req, res, "#{basename}.xhtml")
157
+ end
158
+
159
+ # rubocop:disable Naming/MethodName
160
+ def do_GET(req, res)
161
+ rtn = super
162
+
163
+ if @jekyll_opts["livereload"]
164
+ return rtn if SkipAnalyzer.skip_processing?(req, res, @jekyll_opts)
165
+
166
+ processor = BodyProcessor.new(res.body, @jekyll_opts)
167
+ processor.process!
168
+ res.body = processor.new_body
169
+ res.content_length = processor.content_length.to_s
170
+
171
+ if processor.livereload_added
172
+ # Add a header to indicate that the page content has been modified
173
+ res["X-Rack-LiveReload"] = "1"
174
+ end
175
+ end
176
+
177
+ validate_and_ensure_charset(req, res)
178
+ res.header.merge!(@headers)
179
+ rtn
180
+ end
181
+ # rubocop:enable Naming/MethodName
182
+
183
+ private
184
+
185
+ def validate_and_ensure_charset(_req, res)
186
+ key = res.header.keys.grep(%r!content-type!i).first
187
+ typ = res.header[key]
188
+
189
+ unless typ =~ %r!;\s*charset=!
190
+ res.header[key] = "#{typ}; charset=#{@jekyll_opts["encoding"]}"
191
+ end
192
+ end
193
+
194
+ def set_defaults
195
+ hash_ = @jekyll_opts.fetch("webrick", {}).fetch("headers", {})
196
+ DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|
197
+ hash[key] = val unless hash.key?(key)
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "http/parser"
4
+
5
+ module Jekyll
6
+ module Commands
7
+ class Serve
8
+ # The LiveReload protocol requires the server to serve livereload.js over HTTP
9
+ # despite the fact that the protocol itself uses WebSockets. This custom connection
10
+ # class addresses the dual protocols that the server needs to understand.
11
+ class HttpAwareConnection < EventMachine::WebSocket::Connection
12
+ attr_reader :reload_body, :reload_size
13
+
14
+ def initialize(_opts)
15
+ # If EventMachine SSL support on Windows ever gets better, the code below will
16
+ # set up the reactor to handle SSL
17
+ #
18
+ # @ssl_enabled = opts["ssl_cert"] && opts["ssl_key"]
19
+ # if @ssl_enabled
20
+ # em_opts[:tls_options] = {
21
+ # :private_key_file => Jekyll.sanitized_path(opts["source"], opts["ssl_key"]),
22
+ # :cert_chain_file => Jekyll.sanitized_path(opts["source"], opts["ssl_cert"])
23
+ # }
24
+ # em_opts[:secure] = true
25
+ # end
26
+
27
+ # This is too noisy even for --verbose, but uncomment if you need it for
28
+ # a specific WebSockets issue. Adding ?LR-verbose=true onto the URL will
29
+ # enable logging on the client side.
30
+ # em_opts[:debug] = true
31
+
32
+ em_opts = {}
33
+ super(em_opts)
34
+
35
+ reload_file = File.join(Serve.singleton_class::LIVERELOAD_DIR, "livereload.js")
36
+
37
+ @reload_body = File.read(reload_file)
38
+ @reload_size = @reload_body.bytesize
39
+ end
40
+
41
+ # rubocop:disable Metrics/MethodLength
42
+ def dispatch(data)
43
+ parser = Http::Parser.new
44
+ parser << data
45
+
46
+ # WebSockets requests will have a Connection: Upgrade header
47
+ if parser.http_method != "GET" || parser.upgrade?
48
+ super
49
+ elsif parser.request_url =~ %r!^\/livereload.js!
50
+ headers = [
51
+ "HTTP/1.1 200 OK",
52
+ "Content-Type: application/javascript",
53
+ "Content-Length: #{reload_size}",
54
+ "",
55
+ "",
56
+ ].join("\r\n")
57
+ send_data(headers)
58
+
59
+ # stream_file_data would free us from keeping livereload.js in memory
60
+ # but JRuby blocks on that call and never returns
61
+ send_data(reload_body)
62
+ close_connection_after_writing
63
+ else
64
+ body = "This port only serves livereload.js over HTTP.\n"
65
+ headers = [
66
+ "HTTP/1.1 400 Bad Request",
67
+ "Content-Type: text/plain",
68
+ "Content-Length: #{body.bytesize}",
69
+ "",
70
+ "",
71
+ ].join("\r\n")
72
+ send_data(headers)
73
+ send_data(body)
74
+ close_connection_after_writing
75
+ end
76
+ end
77
+ # rubocop:enable Metrics/MethodLength
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,391 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class Configuration < Hash
5
+ # Default options. Overridden by values in _config.yml.
6
+ # Strings rather than symbols are used for compatibility with YAML.
7
+ DEFAULTS = Configuration[{
8
+ # Where things are
9
+ "source" => Dir.pwd,
10
+ "destination" => File.join(Dir.pwd, "_site"),
11
+ "collections_dir" => "",
12
+ "cache_dir" => ".jekyll-cache",
13
+ "plugins_dir" => "_plugins",
14
+ "layouts_dir" => "_layouts",
15
+ "data_dir" => "_data",
16
+ "includes_dir" => "_includes",
17
+ "collections" => {},
18
+
19
+ # Handling Reading
20
+ "safe" => false,
21
+ "include" => [".htaccess"],
22
+ "exclude" => %w(
23
+ Gemfile Gemfile.lock node_modules vendor/bundle/ vendor/cache/ vendor/gems/
24
+ vendor/ruby/
25
+ ),
26
+ "keep_files" => [".git", ".svn"],
27
+ "encoding" => "utf-8",
28
+ "markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
29
+ "strict_front_matter" => false,
30
+
31
+ # Filtering Content
32
+ "show_drafts" => nil,
33
+ "limit_posts" => 0,
34
+ "future" => false,
35
+ "unpublished" => false,
36
+
37
+ # Plugins
38
+ "whitelist" => [],
39
+ "plugins" => [],
40
+
41
+ # Conversion
42
+ "markdown" => "kramdown",
43
+ "highlighter" => "rouge",
44
+ "lsi" => false,
45
+ "excerpt_separator" => "\n\n",
46
+ "incremental" => false,
47
+
48
+ # Serving
49
+ "detach" => false, # default to not detaching the server
50
+ "port" => "4000",
51
+ "host" => "127.0.0.1",
52
+ "baseurl" => nil, # this mounts at /, i.e. no subdirectory
53
+ "show_dir_listing" => false,
54
+
55
+ # Output Configuration
56
+ "permalink" => "date",
57
+ "paginate_path" => "/page:num",
58
+ "timezone" => nil, # use the local timezone
59
+
60
+ "quiet" => false,
61
+ "verbose" => false,
62
+ "defaults" => [],
63
+
64
+ "liquid" => {
65
+ "error_mode" => "warn",
66
+ "strict_filters" => false,
67
+ "strict_variables" => false,
68
+ },
69
+
70
+ "kramdown" => {
71
+ "auto_ids" => true,
72
+ "toc_levels" => "1..6",
73
+ "entity_output" => "as_char",
74
+ "smart_quotes" => "lsquo,rsquo,ldquo,rdquo",
75
+ "input" => "GFM",
76
+ "hard_wrap" => false,
77
+ "footnote_nr" => 1,
78
+ "show_warnings" => false,
79
+ },
80
+ }.map { |k, v| [k, v.freeze] }].freeze
81
+
82
+ class << self
83
+ # Static: Produce a Configuration ready for use in a Site.
84
+ # It takes the input, fills in the defaults where values do not
85
+ # exist, and patches common issues including migrating options for
86
+ # backwards compatiblity. Except where a key or value is being fixed,
87
+ # the user configuration will override the defaults.
88
+ #
89
+ # user_config - a Hash or Configuration of overrides.
90
+ #
91
+ # Returns a Configuration filled with defaults and fixed for common
92
+ # problems and backwards-compatibility.
93
+ def from(user_config)
94
+ Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
95
+ .add_default_collections
96
+ end
97
+ end
98
+
99
+ # Public: Turn all keys into string
100
+ #
101
+ # Return a copy of the hash where all its keys are strings
102
+ def stringify_keys
103
+ reduce({}) { |hsh, (k, v)| hsh.merge(k.to_s => v) }
104
+ end
105
+
106
+ def get_config_value_with_override(config_key, override)
107
+ override[config_key] || self[config_key] || DEFAULTS[config_key]
108
+ end
109
+
110
+ # Public: Directory of the Jekyll source folder
111
+ #
112
+ # override - the command-line options hash
113
+ #
114
+ # Returns the path to the Jekyll source directory
115
+ def source(override)
116
+ get_config_value_with_override("source", override)
117
+ end
118
+
119
+ def quiet(override = {})
120
+ get_config_value_with_override("quiet", override)
121
+ end
122
+ alias_method :quiet?, :quiet
123
+
124
+ def verbose(override = {})
125
+ get_config_value_with_override("verbose", override)
126
+ end
127
+ alias_method :verbose?, :verbose
128
+
129
+ def safe_load_file(filename)
130
+ case File.extname(filename)
131
+ when %r!\.toml!i
132
+ Jekyll::External.require_with_graceful_fail("tomlrb") unless defined?(Tomlrb)
133
+ Tomlrb.load_file(filename)
134
+ when %r!\.ya?ml!i
135
+ SafeYAML.load_file(filename) || {}
136
+ else
137
+ raise ArgumentError, "No parser for '#{filename}' is available.
138
+ Use a .y(a)ml or .toml file instead."
139
+ end
140
+ end
141
+
142
+ # Public: Generate list of configuration files from the override
143
+ #
144
+ # override - the command-line options hash
145
+ #
146
+ # Returns an Array of config files
147
+ def config_files(override)
148
+ # Adjust verbosity quickly
149
+ Jekyll.logger.adjust_verbosity(
150
+ :quiet => quiet?(override),
151
+ :verbose => verbose?(override)
152
+ )
153
+
154
+ # Get configuration from <source>/_config.yml or <source>/<config_file>
155
+ config_files = override["config"]
156
+ if config_files.to_s.empty?
157
+ default = %w(yml yaml).find(-> { "yml" }) do |ext|
158
+ File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}"))
159
+ end
160
+ config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
161
+ @default_config_file = true
162
+ end
163
+ Array(config_files)
164
+ end
165
+
166
+ # Public: Read configuration and return merged Hash
167
+ #
168
+ # file - the path to the YAML file to be read in
169
+ #
170
+ # Returns this configuration, overridden by the values in the file
171
+ def read_config_file(file)
172
+ next_config = safe_load_file(file)
173
+ check_config_is_hash!(next_config, file)
174
+ Jekyll.logger.info "Configuration file:", file
175
+ next_config
176
+ rescue SystemCallError
177
+ if @default_config_file ||= nil
178
+ Jekyll.logger.warn "Configuration file:", "none"
179
+ {}
180
+ else
181
+ Jekyll.logger.error "Fatal:", "The configuration file '#{file}'
182
+ could not be found."
183
+ raise LoadError, "The Configuration file '#{file}' could not be found."
184
+ end
185
+ end
186
+
187
+ # Public: Read in a list of configuration files and merge with this hash
188
+ #
189
+ # files - the list of configuration file paths
190
+ #
191
+ # Returns the full configuration, with the defaults overridden by the values in the
192
+ # configuration files
193
+ def read_config_files(files)
194
+ configuration = clone
195
+
196
+ begin
197
+ files.each do |config_file|
198
+ next if config_file.nil? || config_file.empty?
199
+
200
+ new_config = read_config_file(config_file)
201
+ configuration = Utils.deep_merge_hashes(configuration, new_config)
202
+ end
203
+ rescue ArgumentError => err
204
+ Jekyll.logger.warn "WARNING:", "Error reading configuration. " \
205
+ "Using defaults (and options)."
206
+ warn err
207
+ end
208
+
209
+ configuration.backwards_compatibilize.add_default_collections
210
+ end
211
+
212
+ # Public: Split a CSV string into an array containing its values
213
+ #
214
+ # csv - the string of comma-separated values
215
+ #
216
+ # Returns an array of the values contained in the CSV
217
+ def csv_to_array(csv)
218
+ csv.split(",").map(&:strip)
219
+ end
220
+
221
+ # Public: Ensure the proper options are set in the configuration to allow for
222
+ # backwards-compatibility with Jekyll pre-1.0
223
+ #
224
+ # Returns the backwards-compatible configuration
225
+ def backwards_compatibilize
226
+ config = clone
227
+ # Provide backwards-compatibility
228
+ check_auto(config)
229
+ check_server(config)
230
+ check_plugins(config)
231
+
232
+ renamed_key "server_port", "port", config
233
+ renamed_key "gems", "plugins", config
234
+ renamed_key "layouts", "layouts_dir", config
235
+ renamed_key "data_source", "data_dir", config
236
+
237
+ check_pygments(config)
238
+ check_include_exclude(config)
239
+ check_coderay(config)
240
+ check_maruku(config)
241
+
242
+ config
243
+ end
244
+
245
+ # DEPRECATED.
246
+ def fix_common_issues
247
+ self
248
+ end
249
+
250
+ def add_default_collections
251
+ config = clone
252
+
253
+ # It defaults to `{}`, so this is only if someone sets it to null manually.
254
+ return config if config["collections"].nil?
255
+
256
+ # Ensure we have a hash.
257
+ if config["collections"].is_a?(Array)
258
+ config["collections"] = Hash[config["collections"].map { |c| [c, {}] }]
259
+ end
260
+
261
+ config["collections"] = Utils.deep_merge_hashes(
262
+ { "posts" => {} }, config["collections"]
263
+ ).tap do |collections|
264
+ collections["posts"]["output"] = true
265
+ if config["permalink"]
266
+ collections["posts"]["permalink"] ||= style_to_permalink(config["permalink"])
267
+ end
268
+ end
269
+
270
+ config
271
+ end
272
+
273
+ def renamed_key(old, new, config, _ = nil)
274
+ if config.key?(old)
275
+ Jekyll::Deprecator.deprecation_message "The '#{old}' configuration" \
276
+ " option has been renamed to '#{new}'. Please update your config" \
277
+ " file accordingly."
278
+ config[new] = config.delete(old)
279
+ end
280
+ end
281
+
282
+ private
283
+
284
+ def style_to_permalink(permalink_style)
285
+ case permalink_style.to_sym
286
+ when :pretty
287
+ "/:categories/:year/:month/:day/:title/"
288
+ when :none
289
+ "/:categories/:title:output_ext"
290
+ when :date
291
+ "/:categories/:year/:month/:day/:title:output_ext"
292
+ when :ordinal
293
+ "/:categories/:year/:y_day/:title:output_ext"
294
+ else
295
+ permalink_style.to_s
296
+ end
297
+ end
298
+
299
+ # Private: Checks if a given config is a hash
300
+ #
301
+ # extracted_config - the value to check
302
+ # file - the file from which the config was extracted
303
+ #
304
+ # Raises an ArgumentError if given config is not a hash
305
+ def check_config_is_hash!(extracted_config, file)
306
+ unless extracted_config.is_a?(Hash)
307
+ raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
308
+ end
309
+ end
310
+
311
+ def check_auto(config)
312
+ if config.key?("auto") || config.key?("watch")
313
+ Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" \
314
+ " be set from your configuration file(s). Use the" \
315
+ " --[no-]watch/-w command-line option instead."
316
+ config.delete("auto")
317
+ config.delete("watch")
318
+ end
319
+ end
320
+
321
+ def check_server(config)
322
+ if config.key?("server")
323
+ Jekyll::Deprecator.deprecation_message "The 'server' configuration option" \
324
+ " is no longer accepted. Use the 'jekyll serve'" \
325
+ " subcommand to serve your site with WEBrick."
326
+ config.delete("server")
327
+ end
328
+ end
329
+
330
+ def check_pygments(config)
331
+ if config.key?("pygments")
332
+ Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" \
333
+ " has been renamed to 'highlighter'. Please update your" \
334
+ " config file accordingly. The allowed values are 'rouge', " \
335
+ "'pygments' or null."
336
+
337
+ config["highlighter"] = "pygments" if config["pygments"]
338
+ config.delete("pygments")
339
+ end
340
+ end
341
+
342
+ def check_include_exclude(config)
343
+ %w(include exclude).each do |option|
344
+ if config[option].is_a?(String)
345
+ Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" \
346
+ " must now be specified as an array, but you specified" \
347
+ " a string. For now, we've treated the string you provided" \
348
+ " as a list of comma-separated values."
349
+ config[option] = csv_to_array(config[option])
350
+ end
351
+ config[option]&.map!(&:to_s)
352
+ end
353
+ end
354
+
355
+ def check_coderay(config)
356
+ if (config["kramdown"] || {}).key?("use_coderay")
357
+ Jekyll::Deprecator.deprecation_message "Please change 'use_coderay'" \
358
+ " to 'enable_coderay' in your configuration file."
359
+ config["kramdown"]["use_coderay"] = config["kramdown"].delete("enable_coderay")
360
+ end
361
+ end
362
+
363
+ def check_maruku(config)
364
+ if config.fetch("markdown", "kramdown").to_s.casecmp("maruku").zero?
365
+ Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " \
366
+ "Markdown processor, which has been removed as of 3.0.0. " \
367
+ "We recommend you switch to Kramdown. To do this, replace " \
368
+ "`markdown: maruku` with `markdown: kramdown` in your " \
369
+ "`_config.yml` file."
370
+ end
371
+ end
372
+
373
+ # Private: Checks if the `plugins` config is a String
374
+ #
375
+ # config - the config hash
376
+ #
377
+ # Raises a Jekyll::Errors::InvalidConfigurationError if the config `plugins`
378
+ # is a string
379
+ def check_plugins(config)
380
+ if config.key?("plugins") && config["plugins"].is_a?(String)
381
+ Jekyll.logger.error "Configuration Error:", "You specified the" \
382
+ " `plugins` config in your configuration file as a string, please" \
383
+ " use an array instead. If you wanted to set the directory of your" \
384
+ " plugins, use the config key `plugins_dir` instead."
385
+ raise Jekyll::Errors::InvalidConfigurationError,
386
+ "'plugins' should not be a string, but was: " \
387
+ "#{config["plugins"].inspect}. Use 'plugins_dir' instead."
388
+ end
389
+ end
390
+ end
391
+ end