blackboard 3.1.6 → 3.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +132 -0
  3. data/exe/jekyll +55 -0
  4. data/lib/jekyll.rb +179 -0
  5. data/lib/jekyll/cleaner.rb +105 -0
  6. data/lib/jekyll/collection.rb +205 -0
  7. data/lib/jekyll/command.rb +65 -0
  8. data/lib/jekyll/commands/build.rb +77 -0
  9. data/lib/jekyll/commands/clean.rb +42 -0
  10. data/lib/jekyll/commands/doctor.rb +114 -0
  11. data/lib/jekyll/commands/help.rb +31 -0
  12. data/lib/jekyll/commands/new.rb +82 -0
  13. data/lib/jekyll/commands/serve.rb +205 -0
  14. data/lib/jekyll/commands/serve/servlet.rb +61 -0
  15. data/lib/jekyll/configuration.rb +348 -0
  16. data/lib/jekyll/converter.rb +48 -0
  17. data/lib/jekyll/converters/identity.rb +21 -0
  18. data/lib/jekyll/converters/markdown.rb +92 -0
  19. data/lib/jekyll/converters/markdown/kramdown_parser.rb +117 -0
  20. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +33 -0
  21. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +102 -0
  22. data/lib/jekyll/converters/smartypants.rb +34 -0
  23. data/lib/jekyll/convertible.rb +300 -0
  24. data/lib/jekyll/deprecator.rb +46 -0
  25. data/lib/jekyll/document.rb +447 -0
  26. data/lib/jekyll/drops/collection_drop.rb +22 -0
  27. data/lib/jekyll/drops/document_drop.rb +60 -0
  28. data/lib/jekyll/drops/drop.rb +200 -0
  29. data/lib/jekyll/drops/excerpt_drop.rb +15 -0
  30. data/lib/jekyll/drops/jekyll_drop.rb +33 -0
  31. data/lib/jekyll/drops/site_drop.rb +38 -0
  32. data/lib/jekyll/drops/unified_payload_drop.rb +25 -0
  33. data/lib/jekyll/drops/url_drop.rb +83 -0
  34. data/lib/jekyll/entry_filter.rb +72 -0
  35. data/lib/jekyll/errors.rb +10 -0
  36. data/lib/jekyll/excerpt.rb +124 -0
  37. data/lib/jekyll/external.rb +59 -0
  38. data/lib/jekyll/filters.rb +367 -0
  39. data/lib/jekyll/frontmatter_defaults.rb +188 -0
  40. data/lib/jekyll/generator.rb +3 -0
  41. data/lib/jekyll/hooks.rb +101 -0
  42. data/lib/jekyll/layout.rb +49 -0
  43. data/lib/jekyll/liquid_extensions.rb +22 -0
  44. data/lib/jekyll/liquid_renderer.rb +39 -0
  45. data/lib/jekyll/liquid_renderer/file.rb +50 -0
  46. data/lib/jekyll/liquid_renderer/table.rb +94 -0
  47. data/lib/jekyll/log_adapter.rb +115 -0
  48. data/lib/jekyll/mime.types +800 -0
  49. data/lib/jekyll/page.rb +180 -0
  50. data/lib/jekyll/plugin.rb +96 -0
  51. data/lib/jekyll/plugin_manager.rb +95 -0
  52. data/lib/jekyll/publisher.rb +21 -0
  53. data/lib/jekyll/reader.rb +126 -0
  54. data/lib/jekyll/readers/collection_reader.rb +20 -0
  55. data/lib/jekyll/readers/data_reader.rb +69 -0
  56. data/lib/jekyll/readers/layout_reader.rb +53 -0
  57. data/lib/jekyll/readers/page_reader.rb +21 -0
  58. data/lib/jekyll/readers/post_reader.rb +62 -0
  59. data/lib/jekyll/readers/static_file_reader.rb +21 -0
  60. data/lib/jekyll/regenerator.rb +175 -0
  61. data/lib/jekyll/related_posts.rb +56 -0
  62. data/lib/jekyll/renderer.rb +194 -0
  63. data/lib/jekyll/site.rb +392 -0
  64. data/lib/jekyll/static_file.rb +141 -0
  65. data/lib/jekyll/stevenson.rb +58 -0
  66. data/lib/jekyll/tags/highlight.rb +122 -0
  67. data/lib/jekyll/tags/include.rb +190 -0
  68. data/lib/jekyll/tags/post_url.rb +88 -0
  69. data/lib/jekyll/url.rb +136 -0
  70. data/lib/jekyll/utils.rb +300 -0
  71. data/lib/jekyll/utils/ansi.rb +59 -0
  72. data/lib/jekyll/utils/platforms.rb +30 -0
  73. data/lib/jekyll/version.rb +3 -0
  74. data/lib/site_template/.gitignore +3 -0
  75. data/lib/site_template/_config.yml +24 -0
  76. data/lib/site_template/_includes/footer.html +38 -0
  77. data/lib/site_template/_includes/head.html +12 -0
  78. data/lib/site_template/_includes/header.html +27 -0
  79. data/lib/site_template/_includes/icon-github.html +1 -0
  80. data/lib/site_template/_includes/icon-github.svg +1 -0
  81. data/lib/site_template/_includes/icon-twitter.html +1 -0
  82. data/lib/site_template/_includes/icon-twitter.svg +1 -0
  83. data/lib/site_template/_layouts/default.html +20 -0
  84. data/lib/site_template/_layouts/page.html +14 -0
  85. data/lib/site_template/_layouts/post.html +15 -0
  86. data/lib/site_template/_pages/about.md +15 -0
  87. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +25 -0
  88. data/lib/site_template/_sass/_base.scss +206 -0
  89. data/lib/site_template/_sass/_layout.scss +242 -0
  90. data/lib/site_template/_sass/_syntax-highlighting.scss +71 -0
  91. data/lib/site_template/css/main.scss +53 -0
  92. data/lib/site_template/feed.xml +30 -0
  93. data/lib/site_template/index.html +23 -0
  94. data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
  95. data/lib/theme_template/Gemfile +2 -0
  96. data/lib/theme_template/LICENSE.txt.erb +21 -0
  97. data/lib/theme_template/README.md.erb +46 -0
  98. data/lib/theme_template/Rakefile.erb +74 -0
  99. data/lib/theme_template/_layouts/default.html +1 -0
  100. data/lib/theme_template/_layouts/page.html +5 -0
  101. data/lib/theme_template/_layouts/post.html +5 -0
  102. data/lib/theme_template/example/_config.yml.erb +1 -0
  103. data/lib/theme_template/example/_post.md +12 -0
  104. data/lib/theme_template/example/index.html +14 -0
  105. data/lib/theme_template/example/style.scss +7 -0
  106. data/lib/theme_template/gitignore.erb +4 -0
  107. data/lib/theme_template/theme.gemspec.erb +22 -0
  108. metadata +109 -2
@@ -0,0 +1,31 @@
1
+ module Jekyll
2
+ module Commands
3
+ class Help < Command
4
+ class << self
5
+ def init_with_program(prog)
6
+ prog.command(:help) do |c|
7
+ c.syntax 'help [subcommand]'
8
+ c.description 'Show the help message, optionally for a given subcommand.'
9
+
10
+ c.action do |args, _|
11
+ cmd = (args.first || "").to_sym
12
+ if args.empty?
13
+ puts prog
14
+ elsif prog.has_command? cmd
15
+ puts prog.commands[cmd]
16
+ else
17
+ invalid_command(prog, cmd)
18
+ abort
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ def invalid_command(prog, cmd)
25
+ Jekyll.logger.error "Error:", "Hmm... we don't know what the '#{cmd}' command is."
26
+ Jekyll.logger.info "Valid commands:", prog.commands.keys.join(", ")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,82 @@
1
+ require 'erb'
2
+
3
+ module Jekyll
4
+ module Commands
5
+ class New < Command
6
+ class << self
7
+ def init_with_program(prog)
8
+ prog.command(:new) do |c|
9
+ c.syntax 'new PATH'
10
+ c.description 'Creates a new Jekyll site scaffold in PATH'
11
+
12
+ c.option 'force', '--force', 'Force creation even if PATH already exists'
13
+ c.option 'blank', '--blank', 'Creates scaffolding but with empty files'
14
+
15
+ c.action do |args, options|
16
+ Jekyll::Commands::New.process(args, options)
17
+ end
18
+ end
19
+ end
20
+
21
+ def process(args, options = {})
22
+ raise ArgumentError.new('You must specify a path.') if args.empty?
23
+
24
+ new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
25
+ FileUtils.mkdir_p new_blog_path
26
+ if preserve_source_location?(new_blog_path, options)
27
+ Jekyll.logger.abort_with "Conflict:", "#{new_blog_path} exists and is not empty."
28
+ end
29
+
30
+ if options["blank"]
31
+ create_blank_site new_blog_path
32
+ else
33
+ create_sample_files new_blog_path
34
+
35
+ File.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
36
+ f.write(scaffold_post_content)
37
+ end
38
+ end
39
+
40
+ Jekyll.logger.info "New jekyll site installed in #{new_blog_path}."
41
+ end
42
+
43
+ def create_blank_site(path)
44
+ Dir.chdir(path) do
45
+ FileUtils.mkdir(%w(_layouts _posts _drafts))
46
+ FileUtils.touch("index.html")
47
+ end
48
+ end
49
+
50
+ def scaffold_post_content
51
+ ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
52
+ end
53
+
54
+ # Internal: Gets the filename of the sample post to be created
55
+ #
56
+ # Returns the filename of the sample post, as a String
57
+ def initialized_post_name
58
+ "_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
59
+ end
60
+
61
+ private
62
+
63
+ def preserve_source_location?(path, options)
64
+ !options["force"] && !Dir["#{path}/**/*"].empty?
65
+ end
66
+
67
+ def create_sample_files(path)
68
+ FileUtils.cp_r site_template + '/.', path
69
+ FileUtils.rm File.expand_path(scaffold_path, path)
70
+ end
71
+
72
+ def site_template
73
+ File.expand_path("../../site_template", File.dirname(__FILE__))
74
+ end
75
+
76
+ def scaffold_path
77
+ "_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,205 @@
1
+ module Jekyll
2
+ module Commands
3
+ class Serve < Command
4
+ class << self
5
+ COMMAND_OPTIONS = {
6
+ "ssl_cert" => ["--ssl-cert [CERT]", "X.509 (SSL) certificate."],
7
+ "host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
8
+ "open_url" => ["-o", "--open-url", "Launch your browser with your site."],
9
+ "detach" => ["-B", "--detach", "Run the server in the background (detach)"],
10
+ "ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
11
+ "port" => ["-P", "--port [PORT]", "Port to listen on"],
12
+ "baseurl" => ["-b", "--baseurl [URL]", "Base URL"],
13
+ "skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
14
+ "Skips the initial site build which occurs before the server is started."]
15
+ }
16
+
17
+ #
18
+
19
+ def init_with_program(prog)
20
+ prog.command(:serve) do |cmd|
21
+ cmd.description "Serve your site locally"
22
+ cmd.syntax "serve [options]"
23
+ cmd.alias :server
24
+ cmd.alias :s
25
+
26
+ add_build_options(cmd)
27
+ COMMAND_OPTIONS.each do |key, val|
28
+ cmd.option key, *val
29
+ end
30
+
31
+ cmd.action do |_, opts|
32
+ opts["serving"] = true
33
+ opts["watch" ] = true unless opts.key?("watch")
34
+ Build.process(opts)
35
+ Serve.process(opts)
36
+ end
37
+ end
38
+ end
39
+
40
+ #
41
+
42
+ def process(opts)
43
+ opts = configuration_from_options(opts)
44
+ destination = opts["destination"]
45
+ setup(destination)
46
+
47
+ server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
48
+ server.mount(opts["baseurl"], Servlet, destination, file_handler_opts)
49
+ Jekyll.logger.info "Server address:", server_address(server, opts)
50
+ launch_browser server, opts if opts["open_url"]
51
+ boot_or_detach server, opts
52
+ end
53
+
54
+ # Do a base pre-setup of WEBRick so that everything is in place
55
+ # when we get ready to party, checking for an setting up an error page
56
+ # and making sure our destination exists.
57
+
58
+ private
59
+ def setup(destination)
60
+ require_relative "serve/servlet"
61
+
62
+ FileUtils.mkdir_p(destination)
63
+ if File.exist?(File.join(destination, "404.html"))
64
+ WEBrick::HTTPResponse.class_eval do
65
+ def create_error_page
66
+ @header["Content-Type"] = "text/html; charset=UTF-8"
67
+ @body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ #
74
+
75
+ private
76
+ def webrick_opts(opts)
77
+ opts = {
78
+ :JekyllOptions => opts,
79
+ :DoNotReverseLookup => true,
80
+ :MimeTypes => mime_types,
81
+ :DocumentRoot => opts["destination"],
82
+ :StartCallback => start_callback(opts["detach"]),
83
+ :BindAddress => opts["host"],
84
+ :Port => opts["port"],
85
+ :DirectoryIndex => %W(
86
+ index.htm
87
+ index.html
88
+ index.rhtml
89
+ index.cgi
90
+ index.xml
91
+ )
92
+ }
93
+
94
+ enable_ssl(opts)
95
+ enable_logging(opts)
96
+ opts
97
+ end
98
+
99
+ # Recreate NondisclosureName under utf-8 circumstance
100
+
101
+ private
102
+ def file_handler_opts
103
+ WEBrick::Config::FileHandler.merge({
104
+ :FancyIndexing => true,
105
+ :NondisclosureName => [
106
+ '.ht*', '~*'
107
+ ]
108
+ })
109
+ end
110
+
111
+ #
112
+
113
+ private
114
+ def server_address(server, opts)
115
+ "%{prefix}://%{address}:%{port}%{baseurl}" % {
116
+ :prefix => server.config[:SSLEnable] ? "https" : "http",
117
+ :baseurl => opts["baseurl"] ? "#{opts["baseurl"]}/" : "",
118
+ :address => server.config[:BindAddress],
119
+ :port => server.config[:Port]
120
+ }
121
+ end
122
+
123
+ #
124
+
125
+ private
126
+ def launch_browser(server, opts)
127
+ command =
128
+ if Utils::Platforms.windows?
129
+ "start"
130
+ elsif Utils::Platforms.osx?
131
+ "open"
132
+ else
133
+ "xdg-open"
134
+ end
135
+ system command, server_address(server, opts)
136
+ end
137
+
138
+ # Keep in our area with a thread or detach the server as requested
139
+ # by the user. This method determines what we do based on what you
140
+ # ask us to do.
141
+
142
+ private
143
+ def boot_or_detach(server, opts)
144
+ if opts["detach"]
145
+ pid = Process.fork do
146
+ server.start
147
+ end
148
+
149
+ Process.detach(pid)
150
+ Jekyll.logger.info "Server detached with pid '#{pid}'.", \
151
+ "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
152
+ else
153
+ t = Thread.new { server.start }
154
+ trap("INT") { server.shutdown }
155
+ t.join
156
+ end
157
+ end
158
+
159
+ # Make the stack verbose if the user requests it.
160
+
161
+ private
162
+ def enable_logging(opts)
163
+ opts[:AccessLog] = []
164
+ level = WEBrick::Log.const_get(opts[:JekyllOptions]["verbose"] ? :DEBUG : :WARN)
165
+ opts[:Logger] = WEBrick::Log.new($stdout, level)
166
+ end
167
+
168
+ # Add SSL to the stack if the user triggers --enable-ssl and they
169
+ # provide both types of certificates commonly needed. Raise if they
170
+ # forget to add one of the certificates.
171
+
172
+ private
173
+ def enable_ssl(opts)
174
+ return if !opts[:JekyllOptions]["ssl_cert"] && !opts[:JekyllOptions]["ssl_key"]
175
+ if !opts[:JekyllOptions]["ssl_cert"] || !opts[:JekyllOptions]["ssl_key"]
176
+ raise RuntimeError, "--ssl-cert or --ssl-key missing."
177
+ end
178
+
179
+ require "openssl"
180
+ require "webrick/https"
181
+ source_key = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_key" ])
182
+ source_certificate = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_cert"])
183
+ opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read(source_certificate))
184
+ opts[:SSLPrivateKey ] = OpenSSL::PKey::RSA.new(File.read(source_key))
185
+ opts[:SSLEnable] = true
186
+ end
187
+
188
+ private
189
+ def start_callback(detached)
190
+ unless detached
191
+ proc do
192
+ Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
193
+ end
194
+ end
195
+ end
196
+
197
+ private
198
+ def mime_types
199
+ file = File.expand_path('../mime.types', File.dirname(__FILE__))
200
+ WEBrick::HTTPUtils.load_mime_types(file)
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,61 @@
1
+ require "webrick"
2
+
3
+ module Jekyll
4
+ module Commands
5
+ class Serve
6
+ class Servlet < WEBrick::HTTPServlet::FileHandler
7
+ DEFAULTS = {
8
+ "Cache-Control" => "private, max-age=0, proxy-revalidate, " \
9
+ "no-store, no-cache, must-revalidate"
10
+ }
11
+
12
+ def initialize(server, root, callbacks)
13
+ # So we can access them easily.
14
+ @jekyll_opts = server.config[:JekyllOptions]
15
+ set_defaults
16
+ super
17
+ end
18
+
19
+ # Add the ability to tap file.html the same way that Nginx does on our
20
+ # Docker images (or on GitHub Pages.) The difference is that we might end
21
+ # up with a different preference on which comes first.
22
+
23
+ def search_file(req, res, basename)
24
+ # /file.* > /file/index.html > /file.html
25
+ super || super(req, res, "#{basename}.html")
26
+ end
27
+
28
+ #
29
+
30
+ def do_GET(req, res)
31
+ rtn = super
32
+ validate_and_ensure_charset(req, res)
33
+ res.header.merge!(@headers)
34
+ rtn
35
+ end
36
+
37
+ #
38
+
39
+ private
40
+ def validate_and_ensure_charset(_req, res)
41
+ key = res.header.keys.grep(/content-type/i).first
42
+ typ = res.header[key]
43
+
44
+ unless typ =~ /;\s*charset=/
45
+ res.header[key] = "#{typ}; charset=#{@jekyll_opts["encoding"]}"
46
+ end
47
+ end
48
+
49
+ #
50
+
51
+ private
52
+ def set_defaults
53
+ hash_ = @jekyll_opts.fetch("webrick", {}).fetch("headers", {})
54
+ DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|
55
+ hash[key] = val unless hash.key?(key)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,348 @@
1
+ # encoding: UTF-8
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
+ 'plugins_dir' => '_plugins',
12
+ 'layouts_dir' => '_layouts',
13
+ 'data_dir' => '_data',
14
+ 'includes_dir' => '_includes',
15
+ 'collections' => {},
16
+
17
+ # Handling Reading
18
+ 'safe' => false,
19
+ 'include' => ['.htaccess'],
20
+ 'exclude' => [],
21
+ 'keep_files' => ['.git', '.svn'],
22
+ 'encoding' => 'utf-8',
23
+ 'markdown_ext' => 'markdown,mkdown,mkdn,mkd,md',
24
+
25
+ # Filtering Content
26
+ 'show_drafts' => nil,
27
+ 'limit_posts' => 0,
28
+ 'future' => false,
29
+ 'unpublished' => false,
30
+
31
+ # Plugins
32
+ 'whitelist' => [],
33
+ 'gems' => [],
34
+
35
+ # Conversion
36
+ 'markdown' => 'kramdown',
37
+ 'highlighter' => 'rouge',
38
+ 'lsi' => false,
39
+ 'excerpt_separator' => "\n\n",
40
+ 'incremental' => false,
41
+
42
+ # Serving
43
+ 'detach' => false, # default to not detaching the server
44
+ 'port' => '4000',
45
+ 'host' => '127.0.0.1',
46
+ 'baseurl' => '',
47
+
48
+ # Output Configuration
49
+ 'permalink' => 'date',
50
+ 'paginate_path' => '/page:num',
51
+ 'timezone' => nil, # use the local timezone
52
+
53
+ 'quiet' => false,
54
+ 'verbose' => false,
55
+ 'defaults' => [],
56
+
57
+ 'rdiscount' => {
58
+ 'extensions' => []
59
+ },
60
+
61
+ 'redcarpet' => {
62
+ 'extensions' => []
63
+ },
64
+
65
+ 'kramdown' => {
66
+ 'auto_ids' => true,
67
+ 'toc_levels' => '1..6',
68
+ 'entity_output' => 'as_char',
69
+ 'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
70
+ 'input' => "GFM",
71
+ 'hard_wrap' => false,
72
+ 'footnote_nr' => 1
73
+ }
74
+ }.map { |k, v| [k, v.freeze] }].freeze
75
+
76
+ class << self
77
+ # Static: Produce a Configuration ready for use in a Site.
78
+ # It takes the input, fills in the defaults where values do not
79
+ # exist, and patches common issues including migrating options for
80
+ # backwards compatiblity. Except where a key or value is being fixed,
81
+ # the user configuration will override the defaults.
82
+ #
83
+ # user_config - a Hash or Configuration of overrides.
84
+ #
85
+ # Returns a Configuration filled with defaults and fixed for common
86
+ # problems and backwards-compatibility.
87
+ def from(user_config)
88
+ Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys).
89
+ fix_common_issues.add_default_collections
90
+ end
91
+ end
92
+
93
+ # Public: Turn all keys into string
94
+ #
95
+ # Return a copy of the hash where all its keys are strings
96
+ def stringify_keys
97
+ reduce({}) { |hsh, (k, v)| hsh.merge(k.to_s => v) }
98
+ end
99
+
100
+ def get_config_value_with_override(config_key, override)
101
+ override[config_key] || self[config_key] || DEFAULTS[config_key]
102
+ end
103
+
104
+ # Public: Directory of the Jekyll source folder
105
+ #
106
+ # override - the command-line options hash
107
+ #
108
+ # Returns the path to the Jekyll source directory
109
+ def source(override)
110
+ get_config_value_with_override('source', override)
111
+ end
112
+
113
+ def quiet(override = {})
114
+ get_config_value_with_override('quiet', override)
115
+ end
116
+ alias_method :quiet?, :quiet
117
+
118
+ def verbose(override = {})
119
+ get_config_value_with_override('verbose', override)
120
+ end
121
+ alias_method :verbose?, :verbose
122
+
123
+ def safe_load_file(filename)
124
+ case File.extname(filename)
125
+ when /\.toml/i
126
+ Jekyll::External.require_with_graceful_fail('toml') unless defined?(TOML)
127
+ TOML.load_file(filename)
128
+ when /\.ya?ml/i
129
+ SafeYAML.load_file(filename) || {}
130
+ else
131
+ raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
132
+ end
133
+ end
134
+
135
+ # Public: Generate list of configuration files from the override
136
+ #
137
+ # override - the command-line options hash
138
+ #
139
+ # Returns an Array of config files
140
+ def config_files(override)
141
+ # Adjust verbosity quickly
142
+ Jekyll.logger.adjust_verbosity(:quiet => quiet?(override), :verbose => verbose?(override))
143
+
144
+ # Get configuration from <source>/_config.yml or <source>/<config_file>
145
+ config_files = override.delete('config')
146
+ if config_files.to_s.empty?
147
+ default = %w(yml yaml).find(-> { 'yml' }) do |ext|
148
+ File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}"))
149
+ end
150
+ config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
151
+ @default_config_file = true
152
+ end
153
+ config_files = [config_files] unless config_files.is_a? Array
154
+ config_files
155
+ end
156
+
157
+ # Public: Read configuration and return merged Hash
158
+ #
159
+ # file - the path to the YAML file to be read in
160
+ #
161
+ # Returns this configuration, overridden by the values in the file
162
+ def read_config_file(file)
163
+ next_config = safe_load_file(file)
164
+ check_config_is_hash!(next_config, file)
165
+ Jekyll.logger.info "Configuration file:", file
166
+ next_config
167
+ rescue SystemCallError
168
+ if @default_config_file
169
+ Jekyll.logger.warn "Configuration file:", "none"
170
+ {}
171
+ else
172
+ Jekyll.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
173
+ raise LoadError, "The Configuration file '#{file}' could not be found."
174
+ end
175
+ end
176
+
177
+ # Public: Read in a list of configuration files and merge with this hash
178
+ #
179
+ # files - the list of configuration file paths
180
+ #
181
+ # Returns the full configuration, with the defaults overridden by the values in the
182
+ # configuration files
183
+ def read_config_files(files)
184
+ configuration = clone
185
+
186
+ begin
187
+ files.each do |config_file|
188
+ next if config_file.nil? or config_file.empty?
189
+ new_config = read_config_file(config_file)
190
+ configuration = Utils.deep_merge_hashes(configuration, new_config)
191
+ end
192
+ rescue ArgumentError => err
193
+ Jekyll.logger.warn "WARNING:", "Error reading configuration. " \
194
+ "Using defaults (and options)."
195
+ $stderr.puts "#{err}"
196
+ end
197
+
198
+ configuration.fix_common_issues.backwards_compatibilize.add_default_collections
199
+ end
200
+
201
+ # Public: Split a CSV string into an array containing its values
202
+ #
203
+ # csv - the string of comma-separated values
204
+ #
205
+ # Returns an array of the values contained in the CSV
206
+ def csv_to_array(csv)
207
+ csv.split(",").map(&:strip)
208
+ end
209
+
210
+ # Public: Ensure the proper options are set in the configuration to allow for
211
+ # backwards-compatibility with Jekyll pre-1.0
212
+ #
213
+ # Returns the backwards-compatible configuration
214
+ def backwards_compatibilize
215
+ config = clone
216
+ # Provide backwards-compatibility
217
+ if config.key?('auto') || config.key?('watch')
218
+ Jekyll::Deprecator.deprecation_message "Auto-regeneration can no longer" \
219
+ " be set from your configuration file(s). Use the"\
220
+ " --[no-]watch/-w command-line option instead."
221
+ config.delete('auto')
222
+ config.delete('watch')
223
+ end
224
+
225
+ if config.key? 'server'
226
+ Jekyll::Deprecator.deprecation_message "The 'server' configuration option" \
227
+ " is no longer accepted. Use the 'jekyll serve'" \
228
+ " subcommand to serve your site with WEBrick."
229
+ config.delete('server')
230
+ end
231
+
232
+ renamed_key 'server_port', 'port', config
233
+ renamed_key 'plugins', 'plugins_dir', config
234
+ renamed_key 'layouts', 'layouts_dir', config
235
+ renamed_key 'data_source', 'data_dir', config
236
+
237
+ if config.key? 'pygments'
238
+ Jekyll::Deprecator.deprecation_message "The 'pygments' configuration option" \
239
+ " has been renamed to 'highlighter'. Please update your" \
240
+ " config file accordingly. The allowed values are 'rouge', " \
241
+ "'pygments' or null."
242
+
243
+ config['highlighter'] = 'pygments' if config['pygments']
244
+ config.delete('pygments')
245
+ end
246
+
247
+ %w(include exclude).each do |option|
248
+ if config[option].is_a?(String)
249
+ Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" \
250
+ " must now be specified as an array, but you specified" \
251
+ " a string. For now, we've treated the string you provided" \
252
+ " as a list of comma-separated values."
253
+ config[option] = csv_to_array(config[option])
254
+ end
255
+ config[option].map!(&:to_s) if config[option]
256
+ end
257
+
258
+ if (config['kramdown'] || {}).key?('use_coderay')
259
+ Jekyll::Deprecator.deprecation_message "Please change 'use_coderay'" \
260
+ " to 'enable_coderay' in your configuration file."
261
+ config['kramdown']['use_coderay'] = config['kramdown'].delete('enable_coderay')
262
+ end
263
+
264
+ if config.fetch('markdown', 'kramdown').to_s.downcase.eql?("maruku")
265
+ Jekyll.logger.abort_with "Error:", "You're using the 'maruku' " \
266
+ "Markdown processor, which has been removed as of 3.0.0. " \
267
+ "We recommend you switch to Kramdown. To do this, replace " \
268
+ "`markdown: maruku` with `markdown: kramdown` in your " \
269
+ "`_config.yml` file."
270
+ end
271
+
272
+ config
273
+ end
274
+
275
+ def fix_common_issues
276
+ config = clone
277
+
278
+ if config.key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
279
+ Jekyll.logger.warn "Config Warning:", "The `paginate` key must be a" \
280
+ " positive integer or nil. It's currently set to '#{config['paginate'].inspect}'."
281
+ config['paginate'] = nil
282
+ end
283
+
284
+ config
285
+ end
286
+
287
+ def add_default_collections
288
+ config = clone
289
+
290
+ # It defaults to `{}`, so this is only if someone sets it to null manually.
291
+ return config if config['collections'].nil?
292
+
293
+ # Ensure we have a hash.
294
+ if config['collections'].is_a?(Array)
295
+ config['collections'] = Hash[config['collections'].map { |c| [c, {}] }]
296
+ end
297
+
298
+ config['collections'] = Utils.deep_merge_hashes(
299
+ { 'posts' => {} }, config['collections']
300
+ ).tap do |collections|
301
+ collections['posts']['output'] = true
302
+ if config['permalink']
303
+ collections['posts']['permalink'] ||= style_to_permalink(config['permalink'])
304
+ end
305
+ end
306
+
307
+ config
308
+ end
309
+
310
+ def renamed_key(old, new, config, _ = nil)
311
+ if config.key?(old)
312
+ Jekyll::Deprecator.deprecation_message "The '#{old}' configuration" \
313
+ "option has been renamed to '#{new}'. Please update your config " \
314
+ "file accordingly."
315
+ config[new] = config.delete(old)
316
+ end
317
+ end
318
+
319
+ private
320
+
321
+ def style_to_permalink(permalink_style)
322
+ case permalink_style.to_sym
323
+ when :pretty
324
+ "/:categories/:year/:month/:day/:title/"
325
+ when :none
326
+ "/:categories/:title:output_ext"
327
+ when :date
328
+ "/:categories/:year/:month/:day/:title:output_ext"
329
+ when :ordinal
330
+ "/:categories/:year/:y_day/:title:output_ext"
331
+ else
332
+ permalink_style.to_s
333
+ end
334
+ end
335
+
336
+ # Private: Checks if a given config is a hash
337
+ #
338
+ # extracted_config - the value to check
339
+ # file - the file from which the config was extracted
340
+ #
341
+ # Raises an ArgumentError if given config is not a hash
342
+ def check_config_is_hash!(extracted_config, file)
343
+ unless extracted_config.is_a?(Hash)
344
+ raise ArgumentError.new("Configuration file: (INVALID) #{file}".yellow)
345
+ end
346
+ end
347
+ end
348
+ end